Install ink@7.0.2 + react@19.2.6. Add JSX/react-jsx support to
packages/tui tsconfig. Create ink-bridge.tsx: LegacyComponentView wraps
existing Component objects as React nodes, startInkRenderer drives the
Ink render loop around any legacy Component tree.
Exports startInkRenderer from @singularity-forge/tui public API.
All 78 existing tui tests pass; 3 new ink-bridge tests added.
This is the infrastructure step for migrating components one-by-one from
the custom differential renderer to native Ink React components, without
breaking interactive mode.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove vestigial experimentalDecorators/emitDecoratorMetadata from all
package tsconfigs (no actual decorators in source — flags were from
pi-mono vendor copy)
- Add @typescript/native-preview for 8-10x faster type checking (measured
4.6x on this repo: tsc 6.5s vs tsgo 1.4s)
- Fix tsconfig.extensions.json: remove baseUrl (removed in tsgo/TS7) and
use relative paths in paths mappings — compatible with both tsc and tsgo
- Add typecheck/typecheck:extensions scripts using tsgo
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add scripts/check-circular-deps.mjs using madge; npm run check:circular
and check:circular:ext scan src/ and the SF extension respectively
- findMilestoneIds() is now DB-first: reads from milestones table when DB is
open so stale/duplicate filesystem dirs (M001/ and M001-6377a4/) are never
returned; falls back to fs scan only during early bootstrap
- milestone-id-utils.js was a stale duplicate; replaced with re-exports from
canonical milestone-ids.js
- metrics-central.js: guard null/undefined counter/gauge/histogram values
with ?? 0 to prevent NOT NULL constraint failure on metrics.value
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- engines.node: >=24.15.0 across all 23 package.json (root + 8
workspace + studio + web + pkg + vscode-extension + 11 SF
extension manifests)
- CI workflows pinned to node-version: '24.15' (16 sites)
- Dockerfile -> node:24.15-slim
- .nvmrc / .node-version -> 24.15.0
- Refactored worktree-cli.ts and headless-query.ts to use
import.meta.filename instead of fileURLToPath(import.meta.url)
- exec.ts simplified with AbortSignal.any + spawn signal/killSignal
- Picks up Crush's biome.json + AGENTS.md doc cleanup in same pass
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add vitest.config.ts with forks pool, v8 coverage, and package aliases.
Run migrate-to-vitest.mjs to replace `from "node:test"` imports with
`from 'vitest'` across 749 test files, converting mock.fn→vi.fn and
mock.timers→vi fake timers where needed.
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- package.json: add 'typecheck' script (build:pi + tsc --noEmit) so pi-ai
and pi-coding-agent typecheck under the same command surface SF uses.
- anthropic-shared.ts: replace 'as any' casts with proper Anthropic SDK
types (ServerToolUseBlockParam, WebSearchToolResultBlockParam,
CacheControlEphemeral). The cache_control variant is documented inline
so the cast is auditable.
- openai-completions.ts: drop the 'as any' on stream_options — the type
system can verify the assignment now.
- openai-codex-responses.ts, package-manager.ts, skills.ts: annotate the
three remaining empty catches with one-line WHY comments (best-effort
cleanup, malformed ignore files, partial directory traversal). Empty
catch with no rationale is an SF012 anti-pattern; with rationale it is
a deliberate fallback.
- oauth/github-copilot.ts, oauth/openai-codex.ts: add UPSTREAM AUDIT
blocks documenting why these hand-rolled OAuth flows stay hand-rolled
rather than delegating to @octokit/auth-oauth-device or @openai/codex.
AbortSignal coverage and provider-specific surface area are the gating
concerns; re-audit triggers are named.
The wrapper imposed CPUQuota=200% / MemoryMax=4G via a transient scope
unit, which requires polkit interactive auth and silently failed on
non-TTY hosts (the script then exit-0'd without running tests). The
limits were a guard against the heavy test:coverage runner's worker
saturation, but test:sf-light already runs in-process with
--max-old-space-size=2048 and --test-timeout=30000 — the systemd
governor was overkill for this lighter target and incompatible with
headless / non-laptop environments.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Milestone-end workflow that compares declared product intent (VISION.md,
RUNBOOKS.md, etc.) against actual code/test/deploy/docs evidence and
emits structured gaps with severity. Soft gates — adds follow-up slices
but doesn't hard-block merge.
Slim port (4 new files + 1 registration) — extracts only the audit
feature itself, not bunker's parallel rewrite of dispatch/prompts/
benchmark-selector that came with it in commit 2aa785475.
Created:
- prompts/product-audit.md — prompt verbatim, gsd_*→sf_* and .gsd→.sf
- tools/product-audit-tool.ts — slim file-write implementation,
atomicWriteAsync to .sf/active/{mid}/
PRODUCT-AUDIT.{json,md}; no DB deps
- bootstrap/product-audit-tool.ts — pi-coding-agent tool registration,
TypeBox schema for sf_product_audit
- workflow-templates/product-audit.md — workflow template
Modified:
- bootstrap/register-extension.ts — 2 lines: import + add to nonCriticalRegistrations
- workflow-templates/registry.json — registry entry
- package.json — version 2.75.0 → 2.75.1
Verdict logic (no-gaps | gaps-found | contract-underspecified) is the
load-bearing innovation: contract-underspecified forces the auditor to
flag unverifiable docs as a real gap rather than rubber-stamping
no-gaps when the product contract is silent.
Out of scope: phase enum changes, dispatch hookup. Wire-up to the phase
machine is a follow-up; the prompt + tool + template stand alone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit captures uncommitted modifications that accumulated in the
working tree across multiple in-progress workstreams. It is a snapshot
to clear the deck before sf v3 work begins; individual workstreams
should land separately on top of this.
Notable additions:
- trace-collector.ts, traces.ts, src/tests/trace-export.test.ts —
trace export plumbing
- biome.json — Biome linter configuration
- .gitignore — exclude native/npm/**/*.node compiled binaries
The bulk of the diff is across src/resources/extensions/sf/ (301 files)
and src/resources/extensions/sf/tests/ (277 files), reflecting the
ongoing sf extension work. Specific feature commits should follow this
snapshot rather than being archaeology'd out of it.
The 76MB native/npm/linux-x64-gnu/forge_engine.node compiled binary
was left out of the commit — it's now gitignored and built locally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous override (gaxios: 7.1.4) was set in 5c64f991b to silence a
glob@10 deprecation warning. That choice is incompatible with
@google/gemini-cli-core's dependency graph: googleapis-common@7.2.0
does `require("gaxios/build/src/common")` — a deep internal path that
gaxios 6.x exposed but 7.x tightened out of its exports field.
Swapping to ^6.7.1 restores cli-core's runtime: a probe using the
installed cli-core + the user's cached ~/.gemini/oauth_creds.json now
successfully reaches https://cloudcode-pa.googleapis.com/v1internal:
streamGenerateContent and gets a real response from gemini-2.5-flash.
The glob deprecation the previous override fixed is cosmetic and
doesn't block anything. Live cli-core functionality trumps npm warning
noise.
Unblocks task #3: replacing the handwritten fetch() transport in
pi-ai/src/providers/google-gemini-cli.ts with CodeAssistServer calls.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>