Refactor SDK-first architecture seams (#3316)

* refactor: tighten sdk-first architecture seams

Refs #3312

* refactor: finish state document seam cleanup

Refs #3312

* test: harden minimal install cleanup assertion

* ci: support sdk-scoped package lock

* fix(3316): restore root package-lock.json and align changeset pr ref

Reverts dec57a83 ("ci: support sdk-scoped package lock") and restores
the root package-lock.json that c249d34d deleted. The deletion was the
wrong direction:

- The root package.json declares its own runtime and dev deps
  (@anthropic-ai/claude-agent-sdk, ws, c8). Without a root lockfile,
  `npm install --no-package-lock` resolves whatever satisfies semver at
  install time — CI today and CI in six months can install different
  transitive trees, defeating reproducibility.
- The lockfile has been part of every release on this repo (long
  history on main); removing it loses the npm audit / Dependabot
  target without compensating benefit.
- The CI workaround pattern (cache-dependency-path: sdk/package-lock.json
  + `npm install --no-package-lock`) papered over the symptom rather
  than fix the cause.

Also fix the changeset pr: from 3312 (issue) to 3316 (PR). CONTEXT.md
flags this exact failure mode as a recurring CodeRabbit finding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: address coderabbit review findings

* fix: close remaining coderabbit threads

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-05-09 14:21:42 -04:00
committed by GitHub
parent 2e87c60afc
commit 26dcdb1ad0
34 changed files with 1693 additions and 738 deletions

View File

@@ -155,8 +155,36 @@ describe('stateJson', () => {
expect(progress.completed_plans).toBe(4);
// Phase 09 complete (3/3), phase 10 incomplete (1/3), phase 11 incomplete (0/1)
expect(progress.completed_phases).toBe(1);
// 4/7 = 57%
expect(progress.percent).toBe(57);
// min(plan fraction 4/7, phase fraction 1/3) = 33%
expect(progress.percent).toBe(33);
});
it('preserves wider curated progress when disk scan only sees a realized subset', async () => {
const stateContent = `---
gsd_state_version: 1.0
milestone: v3.0
milestone_name: SDK-First Migration
status: executing
progress:
total_phases: 12
completed_phases: 6
total_plans: 22
completed_plans: 22
percent: 50
---
${STATE_BODY}`;
await writeFile(join(tmpDir, '.planning', 'STATE.md'), stateContent);
const result = await stateJson([], tmpDir);
const data = result.data as Record<string, unknown>;
const progress = data.progress as Record<string, unknown>;
expect(progress.total_phases).toBe(12);
expect(progress.completed_phases).toBe(6);
expect(progress.total_plans).toBe(22);
expect(progress.completed_plans).toBe(22);
expect(progress.percent).toBe(50);
});
it('preserves stopped_at from existing frontmatter', async () => {
@@ -232,8 +260,8 @@ Progress: [░░░░░░░░░░] 0%
const data = result.data as Record<string, unknown>;
const progress = data.progress as Record<string, unknown>;
// Disk should override the body's 0%
expect(progress.percent).toBe(57);
// Disk should override the body's 0%; phase fraction caps plan-only progress.
expect(progress.percent).toBe(33);
});
});