@warpgogol/forge 5.2.4 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.uk.md +8 -8
- package/bin/cli.ts +25 -33
- package/dist/bin/cli.js +21 -32
- package/dist/bin/cli.js.map +1 -1
- package/dist/os/adr/adr.module.d.ts.map +1 -1
- package/dist/os/adr/adr.module.js +8 -3
- package/dist/os/adr/adr.module.js.map +1 -1
- package/dist/os/adr/frontmatter-io.js +5 -5
- package/dist/os/adr/frontmatter-io.js.map +1 -1
- package/dist/os/adr/handlers/archive.d.ts.map +1 -1
- package/dist/os/adr/handlers/archive.js +10 -4
- package/dist/os/adr/handlers/archive.js.map +1 -1
- package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/adr/handlers/implement-stamp.js +10 -10
- package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
- package/dist/os/adr/handlers/list-create.js +5 -5
- package/dist/os/adr/handlers/list-create.js.map +1 -1
- package/dist/os/adr/handlers/validate.js +1 -1
- package/dist/os/adr/handlers/validate.js.map +1 -1
- package/dist/os/audit/audit.module.js +3 -3
- package/dist/os/audit/audit.module.js.map +1 -1
- package/dist/os/audit/frontmatter-io.js +5 -5
- package/dist/os/audit/frontmatter-io.js.map +1 -1
- package/dist/os/audit/handlers/archive.d.ts.map +1 -1
- package/dist/os/audit/handlers/archive.js +10 -4
- package/dist/os/audit/handlers/archive.js.map +1 -1
- package/dist/os/compass/compass.module.d.ts.map +1 -1
- package/dist/os/compass/compass.module.js +17 -1
- package/dist/os/compass/compass.module.js.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.js +12 -5
- package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.js +3 -2
- package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.js +6 -4
- package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory.js +10 -8
- package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
- package/dist/os/compass/handlers/compass-migrate-handler.js +1 -1
- package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-migrate.js +6 -3
- package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
- package/dist/os/compass/handlers/git-revision.d.ts.map +1 -1
- package/dist/os/compass/handlers/git-revision.js +9 -6
- package/dist/os/compass/handlers/git-revision.js.map +1 -1
- package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
- package/dist/os/compass/handlers/resolve-scan-root.js.map +1 -1
- package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
- package/dist/os/compass/handlers/summary-record.js +8 -4
- package/dist/os/compass/handlers/summary-record.js.map +1 -1
- package/dist/os/core/core.module.d.ts.map +1 -1
- package/dist/os/core/core.module.js +43 -4
- package/dist/os/core/core.module.js.map +1 -1
- package/dist/os/core/handlers/assets-helpers.d.ts.map +1 -1
- package/dist/os/core/handlers/assets-helpers.js +6 -3
- package/dist/os/core/handlers/assets-helpers.js.map +1 -1
- package/dist/os/core/handlers/build.js +1 -1
- package/dist/os/core/handlers/build.js.map +1 -1
- package/dist/os/core/handlers/determinism-check.d.ts.map +1 -1
- package/dist/os/core/handlers/determinism-check.js +10 -6
- package/dist/os/core/handlers/determinism-check.js.map +1 -1
- package/dist/os/core/handlers/dev.js +1 -1
- package/dist/os/core/handlers/dev.js.map +1 -1
- package/dist/os/core/handlers/file-size-lint.d.ts.map +1 -1
- package/dist/os/core/handlers/file-size-lint.js +11 -7
- package/dist/os/core/handlers/file-size-lint.js.map +1 -1
- package/dist/os/core/handlers/forge-autonomy-validate.d.ts.map +1 -1
- package/dist/os/core/handlers/forge-autonomy-validate.js +9 -5
- package/dist/os/core/handlers/forge-autonomy-validate.js.map +1 -1
- package/dist/os/core/handlers/knowledge-compact.js +1 -1
- package/dist/os/core/handlers/knowledge-compact.js.map +1 -1
- package/dist/os/core/handlers/package-health.js +1 -1
- package/dist/os/core/handlers/package-health.js.map +1 -1
- package/dist/os/core/handlers/pinned-check.js +2 -2
- package/dist/os/core/handlers/pinned-check.js.map +1 -1
- package/dist/os/core/handlers/pinned-init.d.ts.map +1 -1
- package/dist/os/core/handlers/pinned-init.js +9 -8
- package/dist/os/core/handlers/pinned-init.js.map +1 -1
- package/dist/os/core/handlers/pinned-validate.js +3 -3
- package/dist/os/core/handlers/pinned-validate.js.map +1 -1
- package/dist/os/core/handlers/profile-resolve.js +1 -1
- package/dist/os/core/handlers/profile-resolve.js.map +1 -1
- package/dist/os/core/handlers/public-surface.js +1 -1
- package/dist/os/core/handlers/public-surface.js.map +1 -1
- package/dist/os/core/handlers/release-prepare.d.ts.map +1 -1
- package/dist/os/core/handlers/release-prepare.js +10 -6
- package/dist/os/core/handlers/release-prepare.js.map +1 -1
- package/dist/os/core/handlers/release-publish.js +6 -6
- package/dist/os/core/handlers/release-publish.js.map +1 -1
- package/dist/os/core/handlers/validate.js +1 -1
- package/dist/os/core/handlers/validate.js.map +1 -1
- package/dist/os/exploration/exploration.module.d.ts.map +1 -1
- package/dist/os/exploration/exploration.module.js +1 -0
- package/dist/os/exploration/exploration.module.js.map +1 -1
- package/dist/os/exploration/frontmatter-io.js +4 -4
- package/dist/os/exploration/frontmatter-io.js.map +1 -1
- package/dist/os/exploration/handlers/archive.js +3 -3
- package/dist/os/exploration/handlers/archive.js.map +1 -1
- package/dist/os/mission/handlers/archive.d.ts.map +1 -1
- package/dist/os/mission/handlers/archive.js +44 -23
- package/dist/os/mission/handlers/archive.js.map +1 -1
- package/dist/os/mission/mission.module.js +3 -3
- package/dist/os/mission/mission.module.js.map +1 -1
- package/dist/os/naming/naming-convention.d.ts.map +1 -1
- package/dist/os/naming/naming-convention.js +7 -3
- package/dist/os/naming/naming-convention.js.map +1 -1
- package/dist/os/naming/naming.module.d.ts.map +1 -1
- package/dist/os/naming/naming.module.js +4 -3
- package/dist/os/naming/naming.module.js.map +1 -1
- package/dist/os/notes/notes.module.d.ts.map +1 -1
- package/dist/os/notes/notes.module.js +6 -3
- package/dist/os/notes/notes.module.js.map +1 -1
- package/dist/os/plan/frontmatter-io.js +5 -5
- package/dist/os/plan/frontmatter-io.js.map +1 -1
- package/dist/os/plan/handlers/archive.d.ts.map +1 -1
- package/dist/os/plan/handlers/archive.js +10 -4
- package/dist/os/plan/handlers/archive.js.map +1 -1
- package/dist/os/plan/plan.module.js +3 -3
- package/dist/os/plan/plan.module.js.map +1 -1
- package/dist/os/plugin/plugin.module.d.ts.map +1 -1
- package/dist/os/plugin/plugin.module.js +6 -3
- package/dist/os/plugin/plugin.module.js.map +1 -1
- package/dist/os/program/discovery.js +2 -2
- package/dist/os/program/discovery.js.map +1 -1
- package/dist/os/program/handlers/complete.js +1 -1
- package/dist/os/program/handlers/complete.js.map +1 -1
- package/dist/os/program/handlers/lease.js +1 -1
- package/dist/os/program/handlers/lease.js.map +1 -1
- package/dist/os/program/handlers/seal.js +1 -1
- package/dist/os/program/handlers/seal.js.map +1 -1
- package/dist/os/program/lease.js +1 -1
- package/dist/os/program/lease.js.map +1 -1
- package/dist/os/program/program.module.d.ts.map +1 -1
- package/dist/os/program/program.module.js +9 -3
- package/dist/os/program/program.module.js.map +1 -1
- package/dist/os/queue/index.js +1 -1
- package/dist/os/queue/manifest.d.ts.map +1 -1
- package/dist/os/queue/manifest.js +4 -8
- package/dist/os/queue/manifest.js.map +1 -1
- package/dist/os/rfc/acceptance.d.ts.map +1 -1
- package/dist/os/rfc/acceptance.js +10 -6
- package/dist/os/rfc/acceptance.js.map +1 -1
- package/dist/os/rfc/decision-log.d.ts.map +1 -1
- package/dist/os/rfc/decision-log.js +4 -3
- package/dist/os/rfc/decision-log.js.map +1 -1
- package/dist/os/rfc/dna-trace.d.ts.map +1 -1
- package/dist/os/rfc/dna-trace.js +7 -2
- package/dist/os/rfc/dna-trace.js.map +1 -1
- package/dist/os/rfc/frontmatter-io.js +5 -5
- package/dist/os/rfc/frontmatter-io.js.map +1 -1
- package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
- package/dist/os/rfc/handlers/archive.js +11 -5
- package/dist/os/rfc/handlers/archive.js.map +1 -1
- package/dist/os/rfc/handlers/check.d.ts.map +1 -1
- package/dist/os/rfc/handlers/check.js +6 -3
- package/dist/os/rfc/handlers/check.js.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.js +11 -10
- package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
- package/dist/os/rfc/handlers/index-graph.js +3 -3
- package/dist/os/rfc/handlers/index-graph.js.map +1 -1
- package/dist/os/rfc/handlers/lifecycle.d.ts.map +1 -1
- package/dist/os/rfc/handlers/lifecycle.js +6 -2
- package/dist/os/rfc/handlers/lifecycle.js.map +1 -1
- package/dist/os/rfc/handlers/list-create.d.ts.map +1 -1
- package/dist/os/rfc/handlers/list-create.js +7 -6
- package/dist/os/rfc/handlers/list-create.js.map +1 -1
- package/dist/os/rfc/handlers/shared.js +3 -3
- package/dist/os/rfc/handlers/shared.js.map +1 -1
- package/dist/os/rfc/handlers/supersede-propose.d.ts.map +1 -1
- package/dist/os/rfc/handlers/supersede-propose.js +7 -3
- package/dist/os/rfc/handlers/supersede-propose.js.map +1 -1
- package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
- package/dist/os/rfc/handlers/validate-rules.js +8 -5
- package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
- package/dist/os/rfc/handlers/validate.d.ts.map +1 -1
- package/dist/os/rfc/handlers/validate.js +6 -1
- package/dist/os/rfc/handlers/validate.js.map +1 -1
- package/dist/os/rfc/rfc.module.d.ts.map +1 -1
- package/dist/os/rfc/rfc.module.js +44 -4
- package/dist/os/rfc/rfc.module.js.map +1 -1
- package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
- package/dist/os/rfc/verification-evidence.js +9 -5
- package/dist/os/rfc/verification-evidence.js.map +1 -1
- package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
- package/dist/os/rfc/verification-refresh.js +4 -3
- package/dist/os/rfc/verification-refresh.js.map +1 -1
- package/dist/os/session/frontmatter-io.js +12 -12
- package/dist/os/session/frontmatter-io.js.map +1 -1
- package/dist/os/session/handlers/archive.d.ts.map +1 -1
- package/dist/os/session/handlers/archive.js +10 -4
- package/dist/os/session/handlers/archive.js.map +1 -1
- package/dist/os/session/handlers/metrics-aggregate.d.ts.map +1 -1
- package/dist/os/session/handlers/metrics-aggregate.js +9 -5
- package/dist/os/session/handlers/metrics-aggregate.js.map +1 -1
- package/dist/os/session/handlers/metrics-rfc.d.ts.map +1 -1
- package/dist/os/session/handlers/metrics-rfc.js +11 -8
- package/dist/os/session/handlers/metrics-rfc.js.map +1 -1
- package/dist/os/session/handlers/metrics-session.d.ts.map +1 -1
- package/dist/os/session/handlers/metrics-session.js +6 -3
- package/dist/os/session/handlers/metrics-session.js.map +1 -1
- package/dist/os/session/handlers/save.d.ts.map +1 -1
- package/dist/os/session/handlers/save.js +14 -8
- package/dist/os/session/handlers/save.js.map +1 -1
- package/dist/os/session/session.module.d.ts.map +1 -1
- package/dist/os/session/session.module.js +6 -0
- package/dist/os/session/session.module.js.map +1 -1
- package/dist/os/spec/live-spec-list.js +4 -4
- package/dist/os/spec/live-spec-list.js.map +1 -1
- package/dist/os/spec/live-spec-merge.js +5 -5
- package/dist/os/spec/live-spec-merge.js.map +1 -1
- package/dist/os/spec/live-spec-show.js +3 -3
- package/dist/os/spec/live-spec-show.js.map +1 -1
- package/dist/os/spec/live-spec-validate.js +4 -4
- package/dist/os/spec/live-spec-validate.js.map +1 -1
- package/dist/os/spec/spec-materialize.js +9 -9
- package/dist/os/spec/spec-materialize.js.map +1 -1
- package/dist/os/spec/spec-status.js +9 -9
- package/dist/os/spec/spec-status.js.map +1 -1
- package/dist/os/spec/spec-validate.js +7 -7
- package/dist/os/spec/spec-validate.js.map +1 -1
- package/dist/os/spec/spec.module.d.ts.map +1 -1
- package/dist/os/spec/spec.module.js +8 -0
- package/dist/os/spec/spec.module.js.map +1 -1
- package/dist/os/werkstatt/handlers/lock.js +16 -16
- package/dist/os/werkstatt/handlers/lock.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js +3 -3
- package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +3 -2
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
- package/dist/os/werkstatt/handlers/workspace-deps.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/workspace-deps.js +0 -1
- package/dist/os/werkstatt/handlers/workspace-deps.js.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.js +6 -2
- package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
- package/dist/os/workflow/handlers.d.ts.map +1 -1
- package/dist/os/workflow/handlers.js +8 -5
- package/dist/os/workflow/handlers.js.map +1 -1
- package/dist/os/workflow/workflow.module.d.ts.map +1 -1
- package/dist/os/workflow/workflow.module.js +6 -3
- package/dist/os/workflow/workflow.module.js.map +1 -1
- package/dist/src/cli-flags.d.ts +28 -0
- package/dist/src/cli-flags.d.ts.map +1 -0
- package/dist/src/cli-flags.js +232 -0
- package/dist/src/cli-flags.js.map +1 -0
- package/dist/src/compass/contract-registry.js +1 -1
- package/dist/src/compass/contract-registry.js.map +1 -1
- package/dist/src/config/forge-config.d.ts +1 -1
- package/dist/src/config/forge-config.js +1 -1
- package/dist/src/config/forge-config.js.map +1 -1
- package/dist/src/knowledge/budgets.js +1 -1
- package/dist/src/knowledge/budgets.js.map +1 -1
- package/dist/src/knowledge/compact.js +1 -1
- package/dist/src/knowledge/compact.js.map +1 -1
- package/dist/src/knowledge/parse.js +1 -1
- package/dist/src/knowledge/parse.js.map +1 -1
- package/dist/src/knowledge/sync.d.ts.map +1 -1
- package/dist/src/knowledge/sync.js +3 -5
- package/dist/src/knowledge/sync.js.map +1 -1
- package/dist/src/migration-adapters/git-utils.js +2 -2
- package/dist/src/migration-adapters/git-utils.js.map +1 -1
- package/dist/src/migration-adapters/ignored-files.js +2 -2
- package/dist/src/migration-adapters/ignored-files.js.map +1 -1
- package/dist/src/migration-adapters/node-typescript-pnpm/index.js +1 -1
- package/dist/src/migration-adapters/node-typescript-pnpm/index.js.map +1 -1
- package/dist/src/migration-adapters/phaser-pnpm/index.js +1 -1
- package/dist/src/migration-adapters/phaser-pnpm/index.js.map +1 -1
- package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
- package/dist/src/onboarding/agents-generate.js +76 -34
- package/dist/src/onboarding/agents-generate.js.map +1 -1
- package/dist/src/onboarding/create.d.ts.map +1 -1
- package/dist/src/onboarding/create.js +10 -10
- package/dist/src/onboarding/create.js.map +1 -1
- package/dist/src/onboarding/doctor.d.ts.map +1 -1
- package/dist/src/onboarding/doctor.js +68 -59
- package/dist/src/onboarding/doctor.js.map +1 -1
- package/dist/src/onboarding/init.d.ts.map +1 -1
- package/dist/src/onboarding/init.js +30 -1
- package/dist/src/onboarding/init.js.map +1 -1
- package/dist/src/onboarding/invariant-engine.js +1 -1
- package/dist/src/onboarding/invariant-engine.js.map +1 -1
- package/dist/src/onboarding/memory-compact.d.ts.map +1 -1
- package/dist/src/onboarding/memory-compact.js +5 -4
- package/dist/src/onboarding/memory-compact.js.map +1 -1
- package/dist/src/onboarding/memory-scaffold.js +1 -1
- package/dist/src/onboarding/memory-scaffold.js.map +1 -1
- package/dist/src/onboarding/nested-agents-generate.d.ts +4 -1
- package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
- package/dist/src/onboarding/nested-agents-generate.js +34 -5
- package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
- package/dist/src/onboarding/nested-agents-templates.d.ts.map +1 -1
- package/dist/src/onboarding/nested-agents-templates.js +8 -12
- package/dist/src/onboarding/nested-agents-templates.js.map +1 -1
- package/dist/src/onboarding/npm-token-check.js +2 -2
- package/dist/src/onboarding/npm-token-check.js.map +1 -1
- package/dist/src/onboarding/prettierignore.d.ts +29 -0
- package/dist/src/onboarding/prettierignore.d.ts.map +1 -0
- package/dist/src/onboarding/prettierignore.js +231 -0
- package/dist/src/onboarding/prettierignore.js.map +1 -0
- package/dist/src/onboarding/profile-validate.d.ts.map +1 -1
- package/dist/src/onboarding/profile-validate.js +5 -4
- package/dist/src/onboarding/profile-validate.js.map +1 -1
- package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
- package/dist/src/onboarding/scaffold-project.js +35 -27
- package/dist/src/onboarding/scaffold-project.js.map +1 -1
- package/dist/src/onboarding/scaffold.js +1 -1
- package/dist/src/onboarding/scaffold.js.map +1 -1
- package/dist/src/onboarding/skill-markers.d.ts +27 -0
- package/dist/src/onboarding/skill-markers.d.ts.map +1 -0
- package/dist/src/onboarding/skill-markers.js +131 -0
- package/dist/src/onboarding/skill-markers.js.map +1 -0
- package/dist/src/onboarding/upgrade.d.ts +10 -0
- package/dist/src/onboarding/upgrade.d.ts.map +1 -1
- package/dist/src/onboarding/upgrade.js +215 -74
- package/dist/src/onboarding/upgrade.js.map +1 -1
- package/dist/src/onboarding/workspace-discovery.js +1 -1
- package/dist/src/onboarding/workspace-discovery.js.map +1 -1
- package/dist/src/pipeline-status.d.ts +6 -5
- package/dist/src/pipeline-status.d.ts.map +1 -1
- package/dist/src/pipeline-status.js +24 -19
- package/dist/src/pipeline-status.js.map +1 -1
- package/dist/src/profiles/stack-profile.js +1 -1
- package/dist/src/profiles/stack-profile.js.map +1 -1
- package/dist/src/registry.d.ts +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +3 -3
- package/dist/src/registry.js.map +1 -1
- package/dist/src/skill-schema.d.ts +1 -1
- package/dist/src/skill-schema.d.ts.map +1 -1
- package/dist/src/skill-schema.js +4 -1
- package/dist/src/skill-schema.js.map +1 -1
- package/dist/src/types.d.ts +116 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/editable-region.d.ts +46 -0
- package/dist/src/utils/editable-region.d.ts.map +1 -0
- package/dist/src/utils/editable-region.js +125 -0
- package/dist/src/utils/editable-region.js.map +1 -0
- package/dist/src/utils/fs-idempotent.d.ts +2 -1
- package/dist/src/utils/fs-idempotent.d.ts.map +1 -1
- package/dist/src/utils/fs-idempotent.js +11 -7
- package/dist/src/utils/fs-idempotent.js.map +1 -1
- package/dist/src/utils/generated-marker.d.ts +17 -0
- package/dist/src/utils/generated-marker.d.ts.map +1 -1
- package/dist/src/utils/generated-marker.js +29 -1
- package/dist/src/utils/generated-marker.js.map +1 -1
- package/dist/src/utils/index.d.ts +3 -1
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +3 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/io.d.ts +9 -0
- package/dist/src/utils/io.d.ts.map +1 -0
- package/dist/src/utils/io.js +130 -0
- package/dist/src/utils/io.js.map +1 -0
- package/dist/src/utils/markdown-table.d.ts +21 -0
- package/dist/src/utils/markdown-table.d.ts.map +1 -0
- package/dist/src/utils/markdown-table.js +116 -0
- package/dist/src/utils/markdown-table.js.map +1 -0
- package/dist/src/utils/sync-fs.d.ts +5 -0
- package/dist/src/utils/sync-fs.d.ts.map +1 -0
- package/dist/src/utils/sync-fs.js +26 -0
- package/dist/src/utils/sync-fs.js.map +1 -0
- package/dist/src/validators/note-frontmatter-validate.js +1 -1
- package/dist/src/validators/note-frontmatter-validate.js.map +1 -1
- package/dist/src/validators/note-link-validate.js +1 -1
- package/dist/src/validators/note-link-validate.js.map +1 -1
- package/dist/src/validators/note-orphan-detect.js +1 -1
- package/dist/src/validators/note-orphan-detect.js.map +1 -1
- package/dist/src/validators/port-validate.js +1 -1
- package/dist/src/validators/port-validate.js.map +1 -1
- package/dist/src/validators/skill-validate.d.ts.map +1 -1
- package/dist/src/validators/skill-validate.js +34 -13
- package/dist/src/validators/skill-validate.js.map +1 -1
- package/os/adr/adr.module.ts +136 -132
- package/os/adr/frontmatter-io.ts +5 -5
- package/os/adr/handlers/archive.ts +8 -4
- package/os/adr/handlers/implement-stamp.ts +14 -10
- package/os/adr/handlers/list-create.ts +5 -5
- package/os/adr/handlers/validate.ts +1 -1
- package/os/audit/audit.module.ts +33 -34
- package/os/audit/frontmatter-io.ts +5 -5
- package/os/audit/handlers/archive.ts +8 -4
- package/os/compass/compass.module.ts +17 -1
- package/os/compass/handlers/compass-audit-handler.ts +13 -5
- package/os/compass/handlers/compass-change-summary-handler.ts +4 -2
- package/os/compass/handlers/compass-inventory-handler.ts +7 -4
- package/os/compass/handlers/compass-inventory.ts +11 -8
- package/os/compass/handlers/compass-migrate-handler.ts +1 -1
- package/os/compass/handlers/compass-migrate.ts +7 -3
- package/os/compass/handlers/git-revision.ts +11 -6
- package/os/compass/handlers/resolve-scan-root.ts +1 -1
- package/os/compass/handlers/summary-record.ts +10 -4
- package/os/compass/handlers/tests/compass-audit-plan.test.ts +2 -1
- package/os/core/core.module.ts +43 -4
- package/os/core/handlers/assets-helpers.ts +7 -3
- package/os/core/handlers/build.ts +1 -1
- package/os/core/handlers/determinism-check.ts +12 -6
- package/os/core/handlers/dev.ts +1 -1
- package/os/core/handlers/file-size-lint.ts +16 -9
- package/os/core/handlers/forge-autonomy-validate.ts +10 -5
- package/os/core/handlers/knowledge-compact.ts +1 -1
- package/os/core/handlers/package-health.ts +1 -1
- package/os/core/handlers/pinned-check.ts +2 -2
- package/os/core/handlers/pinned-init.ts +9 -8
- package/os/core/handlers/pinned-validate.ts +3 -3
- package/os/core/handlers/profile-resolve.ts +1 -1
- package/os/core/handlers/public-surface.ts +1 -1
- package/os/core/handlers/release-prepare.ts +11 -6
- package/os/core/handlers/release-publish.ts +6 -6
- package/os/core/handlers/validate.ts +1 -1
- package/os/exploration/exploration.module.ts +1 -0
- package/os/exploration/frontmatter-io.ts +4 -4
- package/os/exploration/handlers/archive.ts +3 -3
- package/os/mission/handlers/archive.test.ts +38 -1
- package/os/mission/handlers/archive.ts +54 -23
- package/os/mission/mission.module.ts +38 -39
- package/os/naming/naming-convention.ts +9 -3
- package/os/naming/naming.module.ts +25 -25
- package/os/notes/notes.module.ts +87 -85
- package/os/plan/frontmatter-io.ts +5 -5
- package/os/plan/handlers/archive.ts +8 -4
- package/os/plan/plan.module.ts +33 -34
- package/os/plugin/plugin.module.ts +8 -6
- package/os/program/discovery.ts +2 -2
- package/os/program/handlers/complete.ts +1 -1
- package/os/program/handlers/lease.ts +1 -1
- package/os/program/handlers/seal.ts +1 -1
- package/os/program/lease.ts +1 -1
- package/os/program/program.module.ts +198 -193
- package/os/queue/index.ts +1 -1
- package/os/queue/manifest.ts +10 -9
- package/os/queue/queue-validate.test.ts +6 -15
- package/os/rfc/acceptance.ts +12 -6
- package/os/rfc/decision-log.ts +4 -3
- package/os/rfc/dna-trace.ts +8 -2
- package/os/rfc/frontmatter-io.ts +5 -5
- package/os/rfc/handlers/archive.ts +9 -5
- package/os/rfc/handlers/check.ts +5 -3
- package/os/rfc/handlers/implement-stamp.ts +15 -10
- package/os/rfc/handlers/index-graph.ts +3 -3
- package/os/rfc/handlers/lifecycle.ts +7 -2
- package/os/rfc/handlers/list-create.ts +7 -6
- package/os/rfc/handlers/shared.ts +3 -3
- package/os/rfc/handlers/supersede-propose.ts +8 -3
- package/os/rfc/handlers/validate-rules-rfc1006.test.ts +18 -6
- package/os/rfc/handlers/validate-rules.ts +10 -5
- package/os/rfc/handlers/validate.test.ts +71 -0
- package/os/rfc/handlers/validate.ts +6 -1
- package/os/rfc/rfc-create-concurrent.test.ts +11 -3
- package/os/rfc/rfc.module.ts +413 -374
- package/os/rfc/verification-evidence.ts +11 -5
- package/os/rfc/verification-refresh.ts +4 -3
- package/os/session/frontmatter-io.ts +14 -14
- package/os/session/handlers/archive.ts +8 -4
- package/os/session/handlers/metrics-aggregate.ts +34 -13
- package/os/session/handlers/metrics-rfc.ts +13 -8
- package/os/session/handlers/metrics-session.ts +7 -3
- package/os/session/handlers/save.ts +12 -8
- package/os/session/session.module.ts +6 -0
- package/os/spec/live-spec-list.ts +4 -4
- package/os/spec/live-spec-merge.ts +5 -5
- package/os/spec/live-spec-show.ts +3 -3
- package/os/spec/live-spec-validate.ts +4 -4
- package/os/spec/spec-materialize.ts +9 -9
- package/os/spec/spec-status.ts +9 -9
- package/os/spec/spec-validate.ts +7 -7
- package/os/spec/spec.module.ts +8 -0
- package/os/werkstatt/handlers/lock.ts +16 -16
- package/os/werkstatt/handlers/werkstatt-lock-recover.ts +3 -3
- package/os/werkstatt/handlers/werkstatt-operation-validate.ts +4 -2
- package/os/werkstatt/handlers/workspace-deps.ts +0 -1
- package/os/werkstatt/werkstatt.module.ts +8 -5
- package/os/workflow/handlers.ts +7 -5
- package/os/workflow/workflow.module.ts +45 -44
- package/package.json +1 -1
- package/profiles/forge-shell.yaml +1 -1
- package/profiles/godot-game.yaml +1 -1
- package/profiles/knowledge.yaml +1 -1
- package/profiles/phaser-game.yaml +1 -1
- package/profiles/site-workshop.yaml +1 -1
- package/profiles/typescript.yaml +1 -1
- package/skills/fo/fo-add-tests/SKILL.md +2 -2
- package/skills/fo/fo-architecture/SKILL.md +2 -2
- package/skills/fo/fo-compass-annotate/SKILL.md +2 -2
- package/skills/fo/fo-design-summit/SKILL.md +2 -2
- package/skills/fo/fo-doc-audit/SKILL.md +2 -2
- package/skills/fo/fo-explore/SKILL.md +2 -2
- package/skills/fo/fo-extract-dna/SKILL.md +2 -2
- package/skills/fo/fo-fix/SKILL.md +2 -2
- package/skills/fo/fo-handoff/SKILL.md +2 -2
- package/skills/fo/fo-harvest/SKILL.md +2 -2
- package/skills/fo/fo-idea/SKILL.md +2 -2
- package/skills/fo/fo-idea-audit/SKILL.md +2 -2
- package/skills/fo/fo-idea-create-adr/SKILL.md +3 -3
- package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -3
- package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
- package/skills/fo/fo-idea-i-just-want-to-see-the-plan/SKILL.md +2 -2
- package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +1 -1
- package/skills/fo/fo-idea-implement/SKILL.md +2 -2
- package/skills/fo/fo-idea-plan/SKILL.md +2 -2
- package/skills/fo/fo-idea-status/SKILL.md +2 -2
- package/skills/fo/fo-knowledge-distill/SKILL.md +2 -2
- package/skills/fo/fo-memory-sync/SKILL.md +2 -2
- package/skills/fo/fo-qa/SKILL.md +2 -2
- package/skills/fo/fo-review/SKILL.md +2 -2
- package/skills/fo/fo-session-retro/SKILL.md +2 -2
- package/skills/fo/fo-session-save/SKILL.md +2 -2
- package/skills/fo/fo-spec-ingest/SKILL.md +2 -2
- package/skills/fo/fo-step-commit/SKILL.md +1 -1
- package/skills/fo/fo-triage/SKILL.md +2 -2
- package/skills/meta/forge-bootstrap/SKILL.md +1 -1
- package/skills/meta/port-to-forge/SKILL.md +1 -1
- package/skills/meta/skill-create/SKILL.md +1 -1
- package/skills/shared/grilling/SKILL.md +1 -1
- package/skills/shared/grilling/learned-principles.archive.md +17 -0
- package/skills/shared/grilling/learned-principles.md +0 -1
- package/skills/shared/knowledge/learned-principles.md +6 -0
- package/skills/shared/my-preferences/SKILL.md +1 -1
- package/skills/shared/windows-ai-tooling/SKILL.md +1 -1
- package/skills/shared/writing-great-skills/SKILL.md +1 -1
- package/src/cli-flags.ts +285 -0
- package/src/compass/contract-registry.ts +1 -1
- package/src/config/forge-config.ts +1 -1
- package/src/knowledge/__tests__/sync.test.ts +2 -7
- package/src/knowledge/budgets.ts +1 -1
- package/src/knowledge/compact.ts +1 -1
- package/src/knowledge/parse.ts +1 -1
- package/src/knowledge/sync.ts +3 -5
- package/src/migration-adapters/git-utils.ts +2 -2
- package/src/migration-adapters/ignored-files.ts +2 -2
- package/src/migration-adapters/node-typescript-pnpm/index.ts +1 -1
- package/src/migration-adapters/phaser-pnpm/index.ts +1 -1
- package/src/onboarding/agents-generate.ts +92 -36
- package/src/onboarding/create.ts +10 -10
- package/src/onboarding/doctor.ts +70 -55
- package/src/onboarding/init.ts +38 -1
- package/src/onboarding/invariant-engine.ts +1 -1
- package/src/onboarding/memory-compact.ts +5 -4
- package/src/onboarding/memory-scaffold.ts +1 -1
- package/src/onboarding/nested-agents-generate.ts +45 -4
- package/src/onboarding/nested-agents-templates.ts +19 -13
- package/src/onboarding/npm-token-check.ts +2 -2
- package/src/onboarding/prettierignore.ts +263 -0
- package/src/onboarding/profile-validate.ts +5 -4
- package/src/onboarding/scaffold-project.ts +38 -27
- package/src/onboarding/scaffold.ts +1 -1
- package/src/onboarding/skill-markers.ts +162 -0
- package/src/onboarding/templates/behavioral-layer-core.md +2 -4
- package/src/onboarding/upgrade.ts +285 -89
- package/src/onboarding/workspace-discovery.ts +1 -1
- package/src/pipeline-status.test.ts +1 -4
- package/src/pipeline-status.ts +30 -13
- package/src/profiles/stack-profile.ts +1 -1
- package/src/registry.ts +4 -4
- package/src/skill-schema.ts +4 -1
- package/src/tests/acceptance-probe-kinds.test.ts +5 -15
- package/src/tests/agents-generate.test.ts +28 -5
- package/src/tests/cli-flags.test.ts +169 -0
- package/src/tests/contract-registry.test.ts +12 -6
- package/src/tests/doctor-fix.test.ts +1 -4
- package/src/tests/doctor-nested-agents.test.ts +53 -1
- package/src/tests/editable-generated-region.test.ts +231 -0
- package/src/tests/file-size-lint.test.ts +8 -12
- package/src/tests/fixtures/agents-generate-business-before.txt +85 -56
- package/src/tests/markdown-table.test.ts +107 -0
- package/src/tests/prettierignore-manage.test.ts +134 -0
- package/src/tests/skill-agents-sync.test.ts +168 -0
- package/src/tests/skill-sync-marker.test.ts +134 -0
- package/src/tests/skill-validate.test.ts +12 -5
- package/src/tests/upgrade.test.ts +87 -41
- package/src/types.ts +123 -0
- package/src/utils/editable-region.ts +156 -0
- package/src/utils/fs-idempotent.ts +12 -6
- package/src/utils/generated-marker.ts +36 -2
- package/src/utils/index.ts +17 -0
- package/src/utils/io.ts +143 -0
- package/src/utils/markdown-table.ts +121 -0
- package/src/utils/sync-fs.ts +43 -0
- package/src/validators/note-frontmatter-validate.ts +1 -1
- package/src/validators/note-link-validate.ts +1 -1
- package/src/validators/note-orphan-detect.ts +1 -1
- package/src/validators/port-validate.ts +1 -1
- package/src/validators/skill-validate.ts +38 -13
- package/AGENTS.md +0 -502
package/src/onboarding/doctor.ts
CHANGED
|
@@ -21,8 +21,10 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
|
|
|
21
21
|
</CHANGE_SUMMARY>
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
24
|
+
import type { WorkspaceIO } from "../types.ts";
|
|
25
|
+
import { resolveIo } from "../utils/io.ts";
|
|
26
|
+
import { hasEditableGeneratedMarker, mergeEditableGenerated } from "../utils/index.ts";
|
|
27
|
+
import { readFileSync, existsSync } from "../utils/sync-fs.ts";
|
|
26
28
|
import { join, relative, dirname, resolve } from "node:path";
|
|
27
29
|
import { parse as parseYaml } from "yaml";
|
|
28
30
|
import { forgePluginManifestSchema } from "../plugin/forge-plugin-manifest.ts";
|
|
@@ -52,8 +54,8 @@ import { compactMemoryMd } from "./memory-compact.ts";
|
|
|
52
54
|
import { checkInvariants } from "./invariant-engine.ts";
|
|
53
55
|
import type { InvariantViolation } from "./invariant-engine.ts";
|
|
54
56
|
import { checkNpmToken, workshopNeedsWarpgogolToken } from "./npm-token-check.ts";
|
|
55
|
-
import { execSync } from "
|
|
56
|
-
import fs from "
|
|
57
|
+
import { execSync } from "../utils/sync-fs.ts";
|
|
58
|
+
import * as fs from "../utils/sync-fs.ts";
|
|
57
59
|
import type { ProfilePrerequisite } from "../profiles/profile-schema.ts";
|
|
58
60
|
|
|
59
61
|
interface DoctorFixResult {
|
|
@@ -87,13 +89,8 @@ interface BindingNotice {
|
|
|
87
89
|
suggestion: string;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
async function pathExists(target: string): Promise<boolean> {
|
|
91
|
-
|
|
92
|
-
await stat(target);
|
|
93
|
-
return true;
|
|
94
|
-
} catch {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
92
|
+
async function pathExists(target: string, io: WorkspaceIO): Promise<boolean> {
|
|
93
|
+
return io.exists(target);
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
const FORBIDDEN_IMPORT_PATTERN =
|
|
@@ -102,19 +99,20 @@ const FORBIDDEN_IMPORT_PATTERN =
|
|
|
102
99
|
async function scanForForbiddenImports(
|
|
103
100
|
dir: string,
|
|
104
101
|
workspaceRoot: string,
|
|
102
|
+
io: WorkspaceIO,
|
|
105
103
|
): Promise<ForbiddenImport[]> {
|
|
106
104
|
const violations: ForbiddenImport[] = [];
|
|
107
|
-
const entries = await readdir(dir
|
|
105
|
+
const entries = await io.readdir(dir).catch(() => []);
|
|
108
106
|
|
|
109
107
|
for (const entry of entries) {
|
|
110
108
|
const fullPath = join(dir, entry.name);
|
|
111
109
|
|
|
112
|
-
if (entry.isDirectory
|
|
110
|
+
if (entry.isDirectory) {
|
|
113
111
|
if (entry.name === "node_modules" || entry.name === "tests") continue;
|
|
114
|
-
const sub = await scanForForbiddenImports(fullPath, workspaceRoot);
|
|
112
|
+
const sub = await scanForForbiddenImports(fullPath, workspaceRoot, io);
|
|
115
113
|
violations.push(...sub);
|
|
116
114
|
} else if (entry.name.endsWith(".ts")) {
|
|
117
|
-
const content = await readFile(fullPath
|
|
115
|
+
const content = await io.readFile(fullPath).catch(() => "");
|
|
118
116
|
let match: RegExpExecArray | null;
|
|
119
117
|
const pattern = new RegExp(FORBIDDEN_IMPORT_PATTERN.source, "g");
|
|
120
118
|
while ((match = pattern.exec(content)) !== null) {
|
|
@@ -151,7 +149,7 @@ const BINDING_COMMAND_KEYS = [
|
|
|
151
149
|
"commands.sessionSave",
|
|
152
150
|
];
|
|
153
151
|
|
|
154
|
-
async function validateBindings(workspaceRoot: string): Promise<BindingValidation> {
|
|
152
|
+
async function validateBindings(workspaceRoot: string, io: WorkspaceIO): Promise<BindingValidation> {
|
|
155
153
|
const result: BindingValidation = { resolved: [], absent: [], invalid: [], notices: [] };
|
|
156
154
|
|
|
157
155
|
let config;
|
|
@@ -170,7 +168,7 @@ async function validateBindings(workspaceRoot: string): Promise<BindingValidatio
|
|
|
170
168
|
if (value === null) {
|
|
171
169
|
result.absent.push(key);
|
|
172
170
|
} else if (typeof value === "string") {
|
|
173
|
-
const exists = await pathExists(join(workspaceRoot, value));
|
|
171
|
+
const exists = await pathExists(join(workspaceRoot, value), io);
|
|
174
172
|
if (exists) {
|
|
175
173
|
result.resolved.push(key);
|
|
176
174
|
} else {
|
|
@@ -182,7 +180,7 @@ async function validateBindings(workspaceRoot: string): Promise<BindingValidatio
|
|
|
182
180
|
const compassDocs = resolveBinding(config, "paths.compassDocs");
|
|
183
181
|
if (Array.isArray(compassDocs) && compassDocs.length > 0) {
|
|
184
182
|
for (const docPath of compassDocs) {
|
|
185
|
-
const exists = await pathExists(join(workspaceRoot, docPath));
|
|
183
|
+
const exists = await pathExists(join(workspaceRoot, docPath), io);
|
|
186
184
|
if (exists) {
|
|
187
185
|
result.resolved.push(`paths.compassDocs[${docPath}]`);
|
|
188
186
|
} else {
|
|
@@ -226,6 +224,7 @@ async function validateBindings(workspaceRoot: string): Promise<BindingValidatio
|
|
|
226
224
|
async function checkStaleKnowledgeFiles(
|
|
227
225
|
workspaceRoot: string,
|
|
228
226
|
forgeRoot: string,
|
|
227
|
+
io: WorkspaceIO,
|
|
229
228
|
): Promise<DoctorCheck> {
|
|
230
229
|
const stale: string[] = [];
|
|
231
230
|
|
|
@@ -247,8 +246,8 @@ async function checkStaleKnowledgeFiles(
|
|
|
247
246
|
const srcPath = join(skillSrcDir, kf);
|
|
248
247
|
const destPath = join(agentsSkillsDir, skill.name, kf);
|
|
249
248
|
|
|
250
|
-
const srcExists = await pathExists(srcPath);
|
|
251
|
-
const destExists = await pathExists(destPath);
|
|
249
|
+
const srcExists = await pathExists(srcPath, io);
|
|
250
|
+
const destExists = await pathExists(destPath, io);
|
|
252
251
|
|
|
253
252
|
if (srcExists && destExists) {
|
|
254
253
|
// Append-only contract: local copies legitimately accumulate entries.
|
|
@@ -279,8 +278,8 @@ async function checkStaleKnowledgeFiles(
|
|
|
279
278
|
const srcPath = join(skillSrcDir, kf);
|
|
280
279
|
const destPath = join(agentsSkillsDir, skill.name, kf);
|
|
281
280
|
|
|
282
|
-
const srcExists = await pathExists(srcPath);
|
|
283
|
-
const destExists = await pathExists(destPath);
|
|
281
|
+
const srcExists = await pathExists(srcPath, io);
|
|
282
|
+
const destExists = await pathExists(destPath, io);
|
|
284
283
|
|
|
285
284
|
if (srcExists && destExists) {
|
|
286
285
|
const plan = planKnowledgeSync(srcPath, destPath);
|
|
@@ -642,7 +641,7 @@ function checkSharedKnowledgeFile(
|
|
|
642
641
|
// Independent version packages diagnostics (RFC-0704)
|
|
643
642
|
// ---------------------------------------------------------------------------
|
|
644
643
|
|
|
645
|
-
async function checkIndependentVersionPackages(workspaceRoot: string): Promise<DoctorCheck> {
|
|
644
|
+
async function checkIndependentVersionPackages(workspaceRoot: string, io: WorkspaceIO): Promise<DoctorCheck> {
|
|
646
645
|
let config;
|
|
647
646
|
try {
|
|
648
647
|
config = loadForgeConfig(workspaceRoot);
|
|
@@ -658,8 +657,8 @@ async function checkIndependentVersionPackages(workspaceRoot: string): Promise<D
|
|
|
658
657
|
let validCount = 0;
|
|
659
658
|
|
|
660
659
|
for (const pkgPath of config.independentVersionPackages) {
|
|
661
|
-
const dirExists = await pathExists(join(workspaceRoot, pkgPath));
|
|
662
|
-
const pkgJsonExists = await pathExists(join(workspaceRoot, pkgPath, "package.json"));
|
|
660
|
+
const dirExists = await pathExists(join(workspaceRoot, pkgPath), io);
|
|
661
|
+
const pkgJsonExists = await pathExists(join(workspaceRoot, pkgPath, "package.json"), io);
|
|
663
662
|
if (!dirExists) {
|
|
664
663
|
issues.push(`path '${pkgPath}' does not exist`);
|
|
665
664
|
} else if (!pkgJsonExists) {
|
|
@@ -688,7 +687,7 @@ async function checkIndependentVersionPackages(workspaceRoot: string): Promise<D
|
|
|
688
687
|
// Pack skill diagnostics (RFC-0539)
|
|
689
688
|
// ---------------------------------------------------------------------------
|
|
690
689
|
|
|
691
|
-
async function checkPackSkills(workspaceRoot: string): Promise<DoctorCheck> {
|
|
690
|
+
async function checkPackSkills(workspaceRoot: string, io: WorkspaceIO): Promise<DoctorCheck> {
|
|
692
691
|
let config;
|
|
693
692
|
try {
|
|
694
693
|
config = loadForgeConfig(workspaceRoot);
|
|
@@ -720,7 +719,7 @@ async function checkPackSkills(workspaceRoot: string): Promise<DoctorCheck> {
|
|
|
720
719
|
}
|
|
721
720
|
dirs.add(pack.dir);
|
|
722
721
|
|
|
723
|
-
const packDirExists = await pathExists(join(workspaceRoot, pack.dir));
|
|
722
|
+
const packDirExists = await pathExists(join(workspaceRoot, pack.dir), io);
|
|
724
723
|
if (!packDirExists) {
|
|
725
724
|
issues.push(`pack dir '${pack.dir}' does not exist`);
|
|
726
725
|
}
|
|
@@ -739,12 +738,12 @@ async function checkPackSkills(workspaceRoot: string): Promise<DoctorCheck> {
|
|
|
739
738
|
const srcPath = join(workspaceRoot, skill.dir, skill.path);
|
|
740
739
|
const destPath = join(agentsSkillsDir, skill.name, "SKILL.md");
|
|
741
740
|
|
|
742
|
-
const srcExists = await pathExists(srcPath);
|
|
743
|
-
const destExists = await pathExists(destPath);
|
|
741
|
+
const srcExists = await pathExists(srcPath, io);
|
|
742
|
+
const destExists = await pathExists(destPath, io);
|
|
744
743
|
|
|
745
744
|
if (srcExists && destExists) {
|
|
746
|
-
const srcContent = await readFile(srcPath
|
|
747
|
-
const destContent = await readFile(destPath
|
|
745
|
+
const srcContent = await io.readFile(srcPath).catch(() => "");
|
|
746
|
+
const destContent = await io.readFile(destPath).catch(() => "");
|
|
748
747
|
if (srcContent !== destContent) {
|
|
749
748
|
issues.push(`stale copy of '${skill.name}'`);
|
|
750
749
|
}
|
|
@@ -767,7 +766,7 @@ async function checkPackSkills(workspaceRoot: string): Promise<DoctorCheck> {
|
|
|
767
766
|
// Pack manifest diagnostics (RFC-0941)
|
|
768
767
|
// ---------------------------------------------------------------------------
|
|
769
768
|
|
|
770
|
-
async function checkPackManifests(workspaceRoot: string): Promise<DoctorCheck> {
|
|
769
|
+
async function checkPackManifests(workspaceRoot: string, _io: WorkspaceIO): Promise<DoctorCheck> {
|
|
771
770
|
let config;
|
|
772
771
|
try {
|
|
773
772
|
config = loadForgeConfig(workspaceRoot);
|
|
@@ -820,7 +819,8 @@ async function checkPackManifests(workspaceRoot: string): Promise<DoctorCheck> {
|
|
|
820
819
|
|
|
821
820
|
async function checkNestedAgentsMd(
|
|
822
821
|
workspaceRoot: string,
|
|
823
|
-
workspaceTypes
|
|
822
|
+
workspaceTypes: ProfileWorkspaceType[] | undefined,
|
|
823
|
+
io: WorkspaceIO,
|
|
824
824
|
): Promise<DoctorCheck> {
|
|
825
825
|
let config;
|
|
826
826
|
try {
|
|
@@ -851,6 +851,7 @@ async function checkNestedAgentsMd(
|
|
|
851
851
|
let missing = 0;
|
|
852
852
|
let stale = 0;
|
|
853
853
|
let handwritten = 0;
|
|
854
|
+
let unmapped = 0;
|
|
854
855
|
|
|
855
856
|
for (const ws of workspaces) {
|
|
856
857
|
if (!ws.hasAgentsMd) {
|
|
@@ -863,7 +864,7 @@ async function checkNestedAgentsMd(
|
|
|
863
864
|
handwritten++;
|
|
864
865
|
const suggestions: string[] = [];
|
|
865
866
|
try {
|
|
866
|
-
const content = await readFile(join(workspaceRoot, ws.path, "AGENTS.md")
|
|
867
|
+
const content = await io.readFile(join(workspaceRoot, ws.path, "AGENTS.md"));
|
|
867
868
|
if (!content.includes("AGENTS.md")) {
|
|
868
869
|
suggestions.push("reference root AGENTS.md");
|
|
869
870
|
}
|
|
@@ -885,8 +886,19 @@ async function checkNestedAgentsMd(
|
|
|
885
886
|
const terminology = resolveAllTerminology(config, profile);
|
|
886
887
|
const wsType = workspaceTypes?.find((wt) => wt.id === ws.type);
|
|
887
888
|
const expected = selectNestedTemplate(wsType, profile, terminology, fallback);
|
|
888
|
-
const actual = await readFile(join(workspaceRoot, ws.path, "AGENTS.md")
|
|
889
|
-
|
|
889
|
+
const actual = await io.readFile(join(workspaceRoot, ws.path, "AGENTS.md"));
|
|
890
|
+
// RFC-1153: boundary-aware staleness — merge(expected, actual) compares
|
|
891
|
+
// only the generated head; content below the forge:custom boundary (or
|
|
892
|
+
// the canonical footer fallback) is preserved, not drift. Files bearing
|
|
893
|
+
// the restrictive GENERATED marker are generator-owned (RFC-0081) — any
|
|
894
|
+
// divergence is plain staleness, never unmapped-customization.
|
|
895
|
+
const merged = mergeEditableGenerated(expected, actual, `${ws.path}/AGENTS.md`);
|
|
896
|
+
if (merged === null && hasEditableGeneratedMarker(actual)) {
|
|
897
|
+
unmapped++;
|
|
898
|
+
issues.push(
|
|
899
|
+
`${ws.path}/AGENTS.md has custom content but no resolvable boundary — add <!-- forge:custom --> manually`,
|
|
900
|
+
);
|
|
901
|
+
} else if (merged === null || merged !== actual.replace(/\r\n/g, "\n")) {
|
|
890
902
|
stale++;
|
|
891
903
|
issues.push(`${ws.path}/AGENTS.md stale — run 'forge agents generate'`);
|
|
892
904
|
}
|
|
@@ -906,11 +918,12 @@ async function checkNestedAgentsMd(
|
|
|
906
918
|
const parts: string[] = [];
|
|
907
919
|
if (missing > 0) parts.push(`${missing} missing`);
|
|
908
920
|
if (stale > 0) parts.push(`${stale} stale`);
|
|
921
|
+
if (unmapped > 0) parts.push(`${unmapped} unmapped-customization`);
|
|
909
922
|
if (handwritten > 0) parts.push(`${handwritten} hand-written`);
|
|
910
923
|
|
|
911
924
|
return {
|
|
912
925
|
name: "nested-AGENTS.md",
|
|
913
|
-
status: stale > 0 ? "warn" : "pass",
|
|
926
|
+
status: stale > 0 || unmapped > 0 ? "warn" : "pass",
|
|
914
927
|
message: `${parts.join(", ")} — ${issues.slice(0, 3).join("; ")}${issues.length > 3 ? ` (+${issues.length - 3} more)` : ""}`,
|
|
915
928
|
};
|
|
916
929
|
}
|
|
@@ -1222,12 +1235,13 @@ export async function runDoctor(
|
|
|
1222
1235
|
context: ForgeRuntimeContext,
|
|
1223
1236
|
): Promise<ForgeCommandResult<{ command: string; checks: DoctorCheck[]; allPass: boolean; forbiddenImports: ForbiddenImport[]; bindings: BindingValidation; domain?: DomainReport; fixes?: DoctorFixResult[] }>> {
|
|
1224
1237
|
const { workspaceRoot, logger, outputFormat, dryRun } = context;
|
|
1238
|
+
const fio = resolveIo(context.io);
|
|
1225
1239
|
const strict = input.flags["strict"] === true;
|
|
1226
1240
|
const fix = input.flags["fix"] === true;
|
|
1227
1241
|
const checks: DoctorCheck[] = [];
|
|
1228
1242
|
|
|
1229
1243
|
// Check forge.yaml
|
|
1230
|
-
const forgeYamlExists = await pathExists(join(workspaceRoot, "forge.yaml"));
|
|
1244
|
+
const forgeYamlExists = await pathExists(join(workspaceRoot, "forge.yaml"), fio);
|
|
1231
1245
|
checks.push({
|
|
1232
1246
|
name: "forge.yaml",
|
|
1233
1247
|
status: forgeYamlExists ? "pass" : "warn",
|
|
@@ -1237,7 +1251,7 @@ export async function runDoctor(
|
|
|
1237
1251
|
});
|
|
1238
1252
|
|
|
1239
1253
|
// Check AGENTS.md
|
|
1240
|
-
const agentsMdExists = await pathExists(join(workspaceRoot, "AGENTS.md"));
|
|
1254
|
+
const agentsMdExists = await pathExists(join(workspaceRoot, "AGENTS.md"), fio);
|
|
1241
1255
|
checks.push({
|
|
1242
1256
|
name: "AGENTS.md",
|
|
1243
1257
|
status: agentsMdExists ? "pass" : "warn",
|
|
@@ -1247,7 +1261,7 @@ export async function runDoctor(
|
|
|
1247
1261
|
});
|
|
1248
1262
|
|
|
1249
1263
|
// Check PREFERENCES.md
|
|
1250
|
-
const preferencesExists = await pathExists(join(workspaceRoot, "PREFERENCES.md"));
|
|
1264
|
+
const preferencesExists = await pathExists(join(workspaceRoot, "PREFERENCES.md"), fio);
|
|
1251
1265
|
checks.push({
|
|
1252
1266
|
name: "PREFERENCES.md",
|
|
1253
1267
|
status: preferencesExists ? "pass" : "warn",
|
|
@@ -1257,7 +1271,7 @@ export async function runDoctor(
|
|
|
1257
1271
|
});
|
|
1258
1272
|
|
|
1259
1273
|
// Check .agents/skills/
|
|
1260
|
-
const skillsDirExists = await pathExists(join(workspaceRoot, ".agents", "skills"));
|
|
1274
|
+
const skillsDirExists = await pathExists(join(workspaceRoot, ".agents", "skills"), fio);
|
|
1261
1275
|
checks.push({
|
|
1262
1276
|
name: ".agents/skills/",
|
|
1263
1277
|
status: skillsDirExists ? "pass" : "fail",
|
|
@@ -1267,7 +1281,7 @@ export async function runDoctor(
|
|
|
1267
1281
|
});
|
|
1268
1282
|
|
|
1269
1283
|
// Check docs/rfcs/
|
|
1270
|
-
const rfcsDirExists = await pathExists(join(workspaceRoot, "docs", "rfcs"));
|
|
1284
|
+
const rfcsDirExists = await pathExists(join(workspaceRoot, "docs", "rfcs"), fio);
|
|
1271
1285
|
checks.push({
|
|
1272
1286
|
name: "docs/rfcs/",
|
|
1273
1287
|
status: rfcsDirExists ? "pass" : "warn",
|
|
@@ -1277,7 +1291,7 @@ export async function runDoctor(
|
|
|
1277
1291
|
});
|
|
1278
1292
|
|
|
1279
1293
|
// Check docs/adrs/
|
|
1280
|
-
const adrsDirExists = await pathExists(join(workspaceRoot, "docs", "adrs"));
|
|
1294
|
+
const adrsDirExists = await pathExists(join(workspaceRoot, "docs", "adrs"), fio);
|
|
1281
1295
|
checks.push({
|
|
1282
1296
|
name: "docs/adrs/",
|
|
1283
1297
|
status: adrsDirExists ? "pass" : "warn",
|
|
@@ -1386,7 +1400,7 @@ export async function runDoctor(
|
|
|
1386
1400
|
: `${invalidProfiles.length} profile(s) invalid (advisory): ${invalidProfiles.map((p) => p.id).join(", ")}`,
|
|
1387
1401
|
});
|
|
1388
1402
|
|
|
1389
|
-
const forbiddenImports = await scanForForbiddenImports(forgeRoot, workspaceRoot);
|
|
1403
|
+
const forbiddenImports = await scanForForbiddenImports(forgeRoot, workspaceRoot, fio);
|
|
1390
1404
|
checks.push({
|
|
1391
1405
|
name: "autonomy-guard",
|
|
1392
1406
|
status: forbiddenImports.length === 0 ? "pass" : "fail",
|
|
@@ -1397,7 +1411,7 @@ export async function runDoctor(
|
|
|
1397
1411
|
});
|
|
1398
1412
|
|
|
1399
1413
|
// Check bindings contract (RFC-0393)
|
|
1400
|
-
const bindingsResult = await validateBindings(workspaceRoot);
|
|
1414
|
+
const bindingsResult = await validateBindings(workspaceRoot, fio);
|
|
1401
1415
|
checks.push({
|
|
1402
1416
|
name: "bindings",
|
|
1403
1417
|
status: bindingsResult.invalid.length === 0 ? "pass" : "fail",
|
|
@@ -1408,7 +1422,7 @@ export async function runDoctor(
|
|
|
1408
1422
|
});
|
|
1409
1423
|
|
|
1410
1424
|
// Check stale knowledge files (RFC-0524, RFC-0539)
|
|
1411
|
-
const staleCheck = await checkStaleKnowledgeFiles(workspaceRoot, forgeRoot);
|
|
1425
|
+
const staleCheck = await checkStaleKnowledgeFiles(workspaceRoot, forgeRoot, fio);
|
|
1412
1426
|
checks.push(staleCheck);
|
|
1413
1427
|
|
|
1414
1428
|
// RFC-0660: Check legacy sections in knowledge files
|
|
@@ -1434,15 +1448,15 @@ export async function runDoctor(
|
|
|
1434
1448
|
checks.push(checkDistFreshness(forgeRoot));
|
|
1435
1449
|
|
|
1436
1450
|
// RFC-0539: Check pack skills — stale/missing copies and config validation
|
|
1437
|
-
const packCheck = await checkPackSkills(workspaceRoot);
|
|
1451
|
+
const packCheck = await checkPackSkills(workspaceRoot, fio);
|
|
1438
1452
|
checks.push(packCheck);
|
|
1439
1453
|
|
|
1440
1454
|
// RFC-0941: Check pack manifests — forge.plugin.yaml existence and validity
|
|
1441
|
-
const packManifestCheck = await checkPackManifests(workspaceRoot);
|
|
1455
|
+
const packManifestCheck = await checkPackManifests(workspaceRoot, fio);
|
|
1442
1456
|
checks.push(packManifestCheck);
|
|
1443
1457
|
|
|
1444
1458
|
// RFC-0704: Check independent version packages — paths must exist and contain package.json
|
|
1445
|
-
const independentCheck = await checkIndependentVersionPackages(workspaceRoot);
|
|
1459
|
+
const independentCheck = await checkIndependentVersionPackages(workspaceRoot, fio);
|
|
1446
1460
|
checks.push(independentCheck);
|
|
1447
1461
|
|
|
1448
1462
|
// RFC-0611: Check nested AGENTS.md — missing, stale, hand-written
|
|
@@ -1470,7 +1484,7 @@ export async function runDoctor(
|
|
|
1470
1484
|
} catch {
|
|
1471
1485
|
// profiles not loadable
|
|
1472
1486
|
}
|
|
1473
|
-
const nestedCheck = await checkNestedAgentsMd(workspaceRoot, wsTypes);
|
|
1487
|
+
const nestedCheck = await checkNestedAgentsMd(workspaceRoot, wsTypes, fio);
|
|
1474
1488
|
checks.push(nestedCheck);
|
|
1475
1489
|
}
|
|
1476
1490
|
|
|
@@ -1492,7 +1506,7 @@ export async function runDoctor(
|
|
|
1492
1506
|
if (fix) {
|
|
1493
1507
|
for (const check of finalChecks) {
|
|
1494
1508
|
if (check.status === "pass") continue;
|
|
1495
|
-
fixes.push(await applyDoctorRemediation(check, workspaceRoot, wsTypes, dryRun === true));
|
|
1509
|
+
fixes.push(await applyDoctorRemediation(check, workspaceRoot, wsTypes, dryRun === true, fio));
|
|
1496
1510
|
}
|
|
1497
1511
|
}
|
|
1498
1512
|
|
|
@@ -1571,12 +1585,13 @@ async function applyDoctorRemediation(
|
|
|
1571
1585
|
workspaceRoot: string,
|
|
1572
1586
|
workspaceTypes: ProfileWorkspaceType[] | undefined,
|
|
1573
1587
|
dryRun: boolean,
|
|
1588
|
+
io: WorkspaceIO,
|
|
1574
1589
|
): Promise<DoctorFixResult> {
|
|
1575
1590
|
switch (check.name) {
|
|
1576
1591
|
case "nested-AGENTS.md": {
|
|
1577
1592
|
try {
|
|
1578
1593
|
const config = loadForgeConfig(workspaceRoot);
|
|
1579
|
-
const res = await generateNestedAgentsMd(workspaceRoot, config, dryRun, workspaceTypes);
|
|
1594
|
+
const res = await generateNestedAgentsMd(workspaceRoot, config, dryRun, workspaceTypes, io);
|
|
1580
1595
|
return {
|
|
1581
1596
|
check: check.name,
|
|
1582
1597
|
action: res.generated.length > 0 ? "fixed" : "skipped",
|
|
@@ -1589,10 +1604,10 @@ async function applyDoctorRemediation(
|
|
|
1589
1604
|
case "memory-layer": {
|
|
1590
1605
|
try {
|
|
1591
1606
|
const memoryPath = join(workspaceRoot, ".agents", "memory", "MEMORY.md");
|
|
1592
|
-
if (!
|
|
1607
|
+
if (!(await io.exists(memoryPath))) {
|
|
1593
1608
|
return { check: check.name, action: "skipped", detail: "MEMORY.md absent" };
|
|
1594
1609
|
}
|
|
1595
|
-
const content =
|
|
1610
|
+
const content = await io.readFile(memoryPath);
|
|
1596
1611
|
const budget = resolveMemoryBudget(workspaceRoot);
|
|
1597
1612
|
const { lines, removedLines, fitsBudget } = compactMemoryMd(content, budget);
|
|
1598
1613
|
if (!fitsBudget) {
|
|
@@ -1606,7 +1621,7 @@ async function applyDoctorRemediation(
|
|
|
1606
1621
|
return { check: check.name, action: "skipped", detail: "within budget" };
|
|
1607
1622
|
}
|
|
1608
1623
|
if (!dryRun) {
|
|
1609
|
-
|
|
1624
|
+
await io.writeFile(memoryPath, lines.join("\n"));
|
|
1610
1625
|
}
|
|
1611
1626
|
return {
|
|
1612
1627
|
check: check.name,
|
package/src/onboarding/init.ts
CHANGED
|
@@ -20,11 +20,13 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
|
|
|
20
20
|
</CHANGE_SUMMARY>
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import fs from "
|
|
23
|
+
import * as fs from "../utils/sync-fs.ts";
|
|
24
24
|
import path from "node:path";
|
|
25
25
|
import { stringify as stringifyYaml, parse as parseYaml } from "yaml";
|
|
26
26
|
import { FORGE_SKILLS, discoverPackSkills } from "../registry.ts";
|
|
27
27
|
import { syncKnowledgeFile } from "../knowledge/index.ts";
|
|
28
|
+
import { writeSkillMarkerSync } from "./skill-markers.ts";
|
|
29
|
+
import { planPrettierignoreSync, applyPrettierignoreSync } from "./prettierignore.ts";
|
|
28
30
|
import { defaultForgeConfig, loadForgeConfig, resolveForgeRoot, type ForgeConfig } from "../config/forge-config.ts";
|
|
29
31
|
import { listStackProfiles, detectStack } from "../profiles/stack-profile.ts";
|
|
30
32
|
|
|
@@ -280,6 +282,11 @@ export function runInit(
|
|
|
280
282
|
fs.writeFileSync(destPath, content, "utf8");
|
|
281
283
|
created.push(`${config.paths.skillsDir}/${skillName}/SKILL.md`);
|
|
282
284
|
|
|
285
|
+
// RFC-1154: marker manifest lists SKILL.md + knowledge files whose content
|
|
286
|
+
// is purely forge's (copied/unchanged); merged/skipped files carry consumer
|
|
287
|
+
// entries and stay out of the manifest so prune never deletes them.
|
|
288
|
+
const markerFiles = ["SKILL.md"];
|
|
289
|
+
|
|
283
290
|
// RFC-0524: sync declared knowledge files
|
|
284
291
|
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
285
292
|
if (fmMatch) {
|
|
@@ -298,6 +305,9 @@ export function runInit(
|
|
|
298
305
|
if (syncResult.action === "copied" || syncResult.action === "merged") {
|
|
299
306
|
created.push(`${config.paths.skillsDir}/${skillName}/${kf}`);
|
|
300
307
|
}
|
|
308
|
+
if (syncResult.action === "copied" || syncResult.action === "unchanged") {
|
|
309
|
+
markerFiles.push(kf);
|
|
310
|
+
}
|
|
301
311
|
} else {
|
|
302
312
|
errors.push(`Knowledge file '${kf}' declared in ${skillName} but not found in source`);
|
|
303
313
|
}
|
|
@@ -307,6 +317,7 @@ export function runInit(
|
|
|
307
317
|
// Frontmatter parse error — SKILL-01 will catch this in validation
|
|
308
318
|
}
|
|
309
319
|
}
|
|
320
|
+
writeSkillMarkerSync(destDir, markerFiles);
|
|
310
321
|
}
|
|
311
322
|
|
|
312
323
|
// RFC-0539: Copy declared pack skills to .agents/skills/<name>/ for IDE discovery
|
|
@@ -352,6 +363,9 @@ export function runInit(
|
|
|
352
363
|
fs.writeFileSync(destPath, content, "utf8");
|
|
353
364
|
created.push(`${config.paths.skillsDir}/${skillName}/SKILL.md`);
|
|
354
365
|
|
|
366
|
+
// RFC-1154: same marker rule as forge skills.
|
|
367
|
+
const markerFiles = ["SKILL.md"];
|
|
368
|
+
|
|
355
369
|
// RFC-0524: sync declared knowledge files for pack skills
|
|
356
370
|
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
357
371
|
if (fmMatch) {
|
|
@@ -370,6 +384,9 @@ export function runInit(
|
|
|
370
384
|
if (syncResult.action === "copied" || syncResult.action === "merged") {
|
|
371
385
|
created.push(`${config.paths.skillsDir}/${skillName}/${kf}`);
|
|
372
386
|
}
|
|
387
|
+
if (syncResult.action === "copied" || syncResult.action === "unchanged") {
|
|
388
|
+
markerFiles.push(kf);
|
|
389
|
+
}
|
|
373
390
|
} else {
|
|
374
391
|
errors.push(`Knowledge file '${kf}' declared in ${skillName} but not found in source`);
|
|
375
392
|
}
|
|
@@ -379,6 +396,7 @@ export function runInit(
|
|
|
379
396
|
// Frontmatter parse error — SKILL-01 will catch this in validation
|
|
380
397
|
}
|
|
381
398
|
}
|
|
399
|
+
writeSkillMarkerSync(destDir, markerFiles);
|
|
382
400
|
}
|
|
383
401
|
|
|
384
402
|
// RFC-0663: Sync shared knowledge layer to .agents/skills/shared-knowledge/
|
|
@@ -391,6 +409,25 @@ export function runInit(
|
|
|
391
409
|
if (syncResult.action === "copied" || syncResult.action === "merged") {
|
|
392
410
|
created.push(`${config.paths.skillsDir}/shared-knowledge/learned-principles.md`);
|
|
393
411
|
}
|
|
412
|
+
// RFC-1154: marker lists the file only when its content is purely forge's.
|
|
413
|
+
writeSkillMarkerSync(
|
|
414
|
+
sharedKnowledgeDestDir,
|
|
415
|
+
syncResult.action === "copied" || syncResult.action === "unchanged"
|
|
416
|
+
? ["learned-principles.md"]
|
|
417
|
+
: [],
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// RFC-1154: reconcile the forge-managed .prettierignore block (prettier
|
|
422
|
+
// consumers only; additive + idempotent, no-op otherwise). Non-fatal —
|
|
423
|
+
// a prettierignore write failure must not fail init.
|
|
424
|
+
try {
|
|
425
|
+
applyPrettierignoreSync(
|
|
426
|
+
workspaceRoot,
|
|
427
|
+
planPrettierignoreSync(workspaceRoot, config.paths.skillsDir),
|
|
428
|
+
);
|
|
429
|
+
} catch (err) {
|
|
430
|
+
errors.push(`.prettierignore reconcile failed: ${(err as Error).message}`);
|
|
394
431
|
}
|
|
395
432
|
|
|
396
433
|
// 4. Create docs directories from config paths
|
|
@@ -20,7 +20,7 @@ Sweep batch 4: 73 Compass headers on headerless engine files (certification, com
|
|
|
20
20
|
</CHANGE_SUMMARY>
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import fs from "
|
|
23
|
+
import * as fs from "../utils/sync-fs.ts";
|
|
24
24
|
import path from "node:path";
|
|
25
25
|
import { parse as parseYaml } from "yaml";
|
|
26
26
|
import type { StackProfile } from "../profiles/stack-profile.ts";
|
|
@@ -14,7 +14,7 @@ Invoked standalone and by forge doctor --fix for the memory-layer check (RFC-115
|
|
|
14
14
|
</CHANGE_SUMMARY>
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import { resolveIo } from "../utils/io.ts";
|
|
18
18
|
import path from "node:path";
|
|
19
19
|
import type { ForgeCommandInput, ForgeCommandResult, ForgeRuntimeContext } from "../types.ts";
|
|
20
20
|
import { resolveMemoryBudget } from "./memory-scaffold.ts";
|
|
@@ -100,6 +100,7 @@ export async function runMemoryCompact(
|
|
|
100
100
|
context: ForgeRuntimeContext,
|
|
101
101
|
): Promise<ForgeCommandResult<MemoryCompactResult>> {
|
|
102
102
|
const { workspaceRoot, logger, outputFormat, dryRun } = context;
|
|
103
|
+
const fio = resolveIo(context.io);
|
|
103
104
|
const memoryPath = path.join(workspaceRoot, MEMORY_MD_PATH);
|
|
104
105
|
const budget = resolveMemoryBudget(workspaceRoot);
|
|
105
106
|
|
|
@@ -116,7 +117,7 @@ export async function runMemoryCompact(
|
|
|
116
117
|
summary: `forge.memory.compact: failed — ${msg}`,
|
|
117
118
|
});
|
|
118
119
|
|
|
119
|
-
if (!
|
|
120
|
+
if (!(await fio.exists(memoryPath))) {
|
|
120
121
|
return {
|
|
121
122
|
data: {
|
|
122
123
|
command: "forge.memory.compact",
|
|
@@ -131,7 +132,7 @@ export async function runMemoryCompact(
|
|
|
131
132
|
};
|
|
132
133
|
}
|
|
133
134
|
|
|
134
|
-
const content =
|
|
135
|
+
const content = await fio.readFile(memoryPath);
|
|
135
136
|
if (content.length <= budget) {
|
|
136
137
|
return {
|
|
137
138
|
data: {
|
|
@@ -158,7 +159,7 @@ export async function runMemoryCompact(
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
if (!dryRun) {
|
|
161
|
-
|
|
162
|
+
await fio.writeFile(memoryPath, lines.join("\n"));
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
if (outputFormat === "pretty") {
|
|
@@ -23,19 +23,29 @@ Sweep batch 4: 73 Compass headers on headerless engine files (certification, com
|
|
|
23
23
|
</CHANGE_SUMMARY>
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import fs from "
|
|
26
|
+
import * as fs from "../utils/sync-fs.ts";
|
|
27
27
|
import path from "node:path";
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
canonicalFooterOf,
|
|
30
|
+
hasEditableGeneratedMarker,
|
|
31
|
+
mergeEditableGenerated,
|
|
32
|
+
splitEditableGenerated,
|
|
33
|
+
writeFileIfChanged,
|
|
34
|
+
} from "../utils/index.ts";
|
|
35
|
+
import { resolveIo } from "../utils/io.ts";
|
|
29
36
|
import { discoverWorkspaces } from "./workspace-discovery.ts";
|
|
30
37
|
import { buildNestedAgentsMd, selectNestedTemplate, type PackageInfo } from "./nested-agents-templates.ts";
|
|
31
38
|
import type { ForgeConfig } from "../config/forge-config.ts";
|
|
32
39
|
import type { ProfileWorkspaceType } from "../profiles/profile-schema.ts";
|
|
33
40
|
import type { StackProfile } from "../profiles/stack-profile.ts";
|
|
41
|
+
import type { WorkspaceIO } from "../types.ts";
|
|
34
42
|
import { resolveAllTerminology } from "../profiles/terminology-utils.ts";
|
|
35
43
|
|
|
36
44
|
export interface NestedGenerateResult {
|
|
37
45
|
generated: string[];
|
|
38
46
|
skipped: string[];
|
|
47
|
+
/** RFC-1153: files merged with a carried custom tail below the boundary. */
|
|
48
|
+
preserved: string[];
|
|
39
49
|
renderedFiles: { [relPath: string]: string };
|
|
40
50
|
workspaceTypeMap?: { [relPath: string]: string };
|
|
41
51
|
}
|
|
@@ -55,6 +65,7 @@ export async function generateNestedAgentsMd(
|
|
|
55
65
|
config: ForgeConfig,
|
|
56
66
|
dryRun: boolean,
|
|
57
67
|
workspaceTypes?: ProfileWorkspaceType[],
|
|
68
|
+
io?: WorkspaceIO,
|
|
58
69
|
): Promise<NestedGenerateResult> {
|
|
59
70
|
const workspaces = discoverWorkspaces(
|
|
60
71
|
workspaceRoot,
|
|
@@ -63,7 +74,9 @@ export async function generateNestedAgentsMd(
|
|
|
63
74
|
);
|
|
64
75
|
const generated: string[] = [];
|
|
65
76
|
const skipped: string[] = [];
|
|
77
|
+
const preserved: string[] = [];
|
|
66
78
|
const renderedFiles: { [relPath: string]: string } = {};
|
|
79
|
+
const fio = resolveIo(io);
|
|
67
80
|
const workspaceTypeMap: { [relPath: string]: string } = {};
|
|
68
81
|
|
|
69
82
|
// RFC-0643: resolve terminology from config + profile for nested template substitution
|
|
@@ -90,12 +103,40 @@ export async function generateNestedAgentsMd(
|
|
|
90
103
|
continue;
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
|
|
106
|
+
// RFC-1153: merge instead of overwrite — the `forge:custom` boundary marks
|
|
107
|
+
// the split between the generator-owned head and the preserved custom tail.
|
|
108
|
+
let existing: string | null = null;
|
|
109
|
+
if (ws.hasAgentsMd) {
|
|
110
|
+
try {
|
|
111
|
+
existing = await fio.readFile(agentsMdPath);
|
|
112
|
+
} catch {
|
|
113
|
+
// Unreadable — treat as absent; merge will emit a fresh file.
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
let merged = mergeEditableGenerated(content, existing, relPath);
|
|
117
|
+
if (merged === null && existing !== null && !hasEditableGeneratedMarker(existing)) {
|
|
118
|
+
// RFC-0081/RFC-1153: restrictive-marker file is fully generator-owned —
|
|
119
|
+
// upgrade it to the editable boundary contract (fresh render + marker).
|
|
120
|
+
merged = mergeEditableGenerated(content, null, relPath);
|
|
121
|
+
}
|
|
122
|
+
if (merged === null) {
|
|
123
|
+
skipped.push(`${relPath} (unmapped-customization)`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await writeFileIfChanged(agentsMdPath, merged, fio);
|
|
94
128
|
generated.push(relPath);
|
|
95
129
|
workspaceTypeMap[relPath] = ws.type;
|
|
130
|
+
const footer = canonicalFooterOf(content);
|
|
131
|
+
if (
|
|
132
|
+
existing !== null &&
|
|
133
|
+
splitEditableGenerated(existing, relPath, footer ?? undefined).customTail !== null
|
|
134
|
+
) {
|
|
135
|
+
preserved.push(relPath);
|
|
136
|
+
}
|
|
96
137
|
}
|
|
97
138
|
|
|
98
|
-
return { generated, skipped, renderedFiles, workspaceTypeMap };
|
|
139
|
+
return { generated, skipped, preserved, renderedFiles, workspaceTypeMap };
|
|
99
140
|
}
|
|
100
141
|
|
|
101
142
|
export { discoverWorkspaces, type WorkspaceDir, type WorkspaceType } from "./workspace-discovery.ts";
|