@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
|
@@ -15,7 +15,7 @@ workspace type (app, service, package) by content markers.</purpose>
|
|
|
15
15
|
</CHANGE_SUMMARY>
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import fs from "
|
|
18
|
+
import * as fs from "../utils/sync-fs.ts";
|
|
19
19
|
import path from "node:path";
|
|
20
20
|
import { hasGeneratedMarker } from "../utils/index.ts";
|
|
21
21
|
import type { ProfileWorkspaceType } from "../profiles/profile-schema.ts";
|
|
@@ -116,10 +116,7 @@ describe("deriveQueueItemStatus — derivation matrix (RFC-1140)", () => {
|
|
|
116
116
|
|
|
117
117
|
test("audit file only → in-progress/enhance", async () => {
|
|
118
118
|
await writeRfc("RFC-1107", "status: draft\n");
|
|
119
|
-
await fs.writeFile(
|
|
120
|
-
path.join(tmpDir, "docs/audits/audit-rfc-1107-test.md"),
|
|
121
|
-
"# audit\n",
|
|
122
|
-
);
|
|
119
|
+
await fs.writeFile(path.join(tmpDir, "docs/audits/audit-rfc-1107-test.md"), "# audit\n");
|
|
123
120
|
const r = await deriveQueueItemStatus(tmpDir, "RFC-1107");
|
|
124
121
|
expect(r?.status).toBe("in-progress");
|
|
125
122
|
expect(r?.pipelineStep).toBe("enhance");
|
package/src/pipeline-status.ts
CHANGED
|
@@ -25,8 +25,9 @@ Add pipeline-status.test.ts (derivation matrix, order, next selection, ADR, skip
|
|
|
25
25
|
</CHANGE_SUMMARY>
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
import fs from "node:fs/promises";
|
|
29
28
|
import path from "node:path";
|
|
29
|
+
import type { WorkspaceIO } from "./types.ts";
|
|
30
|
+
import { resolveIo } from "./utils/io.ts";
|
|
30
31
|
import YAML from "yaml";
|
|
31
32
|
|
|
32
33
|
// ---------------------------------------------------------------------------
|
|
@@ -75,10 +76,12 @@ export function parseFrontmatter(source: string): ParsedDocument {
|
|
|
75
76
|
export async function findAuditFile(
|
|
76
77
|
workspaceRoot: string,
|
|
77
78
|
docId: string,
|
|
79
|
+
io?: WorkspaceIO,
|
|
78
80
|
): Promise<string | undefined> {
|
|
81
|
+
const fio = resolveIo(io);
|
|
79
82
|
const auditsDir = path.join(workspaceRoot, "docs/audits");
|
|
80
83
|
try {
|
|
81
|
-
const entries = await
|
|
84
|
+
const entries = (await fio.readdir(auditsDir)).map((e) => e.name);
|
|
82
85
|
const prefix = `audit-${docId.toLowerCase()}`;
|
|
83
86
|
const match = entries.find((e) => e.toLowerCase().startsWith(prefix) && e.endsWith(".md"));
|
|
84
87
|
return match ? path.join("docs/audits", match) : undefined;
|
|
@@ -90,10 +93,12 @@ export async function findAuditFile(
|
|
|
90
93
|
export async function findPlanFile(
|
|
91
94
|
workspaceRoot: string,
|
|
92
95
|
docId: string,
|
|
96
|
+
io?: WorkspaceIO,
|
|
93
97
|
): Promise<string | undefined> {
|
|
98
|
+
const fio = resolveIo(io);
|
|
94
99
|
const plansDir = path.join(workspaceRoot, "docs/plans");
|
|
95
100
|
try {
|
|
96
|
-
const entries = await
|
|
101
|
+
const entries = (await fio.readdir(plansDir)).map((e) => e.name);
|
|
97
102
|
const prefix = `plan-${docId.toLowerCase()}`;
|
|
98
103
|
const match = entries.find((e) => e.toLowerCase().startsWith(prefix) && e.endsWith(".md"));
|
|
99
104
|
return match ? path.join("docs/plans", match) : undefined;
|
|
@@ -122,20 +127,26 @@ async function scanForDocument(
|
|
|
122
127
|
dirPath: string,
|
|
123
128
|
relativePrefix: string,
|
|
124
129
|
idLower: string,
|
|
130
|
+
io: WorkspaceIO,
|
|
125
131
|
): Promise<string | undefined> {
|
|
126
132
|
let entries;
|
|
127
133
|
try {
|
|
128
|
-
entries = await
|
|
134
|
+
entries = await io.readdir(dirPath);
|
|
129
135
|
} catch {
|
|
130
136
|
return undefined;
|
|
131
137
|
}
|
|
132
138
|
for (const entry of entries) {
|
|
133
139
|
const relativePath = relativePrefix ? `${relativePrefix}/${entry.name}` : entry.name;
|
|
134
|
-
if (entry.isDirectory
|
|
135
|
-
const found = await scanForDocument(
|
|
140
|
+
if (entry.isDirectory) {
|
|
141
|
+
const found = await scanForDocument(
|
|
142
|
+
path.join(dirPath, entry.name),
|
|
143
|
+
relativePath,
|
|
144
|
+
idLower,
|
|
145
|
+
io,
|
|
146
|
+
);
|
|
136
147
|
if (found) return found;
|
|
137
148
|
} else if (
|
|
138
|
-
entry.isFile
|
|
149
|
+
entry.isFile &&
|
|
139
150
|
entry.name.endsWith(".md") &&
|
|
140
151
|
entry.name.toLowerCase().startsWith(idLower)
|
|
141
152
|
) {
|
|
@@ -153,19 +164,21 @@ async function scanForDocument(
|
|
|
153
164
|
export async function resolveDocument(
|
|
154
165
|
workspaceRoot: string,
|
|
155
166
|
docId: string,
|
|
167
|
+
io?: WorkspaceIO,
|
|
156
168
|
): Promise<ResolvedDocument | undefined> {
|
|
169
|
+
const fio = resolveIo(io);
|
|
157
170
|
const idMatch = DOC_ID_PATTERN.exec(docId.trim());
|
|
158
171
|
if (!idMatch) return undefined;
|
|
159
172
|
const kind: QueueDocumentKind = idMatch[1]!.toUpperCase() === "ADR" ? "adr" : "rfc";
|
|
160
173
|
const baseDir = kind === "adr" ? "docs/adrs" : "docs/rfcs";
|
|
161
174
|
const idLower = docId.toLowerCase();
|
|
162
175
|
|
|
163
|
-
const found = await scanForDocument(path.join(workspaceRoot, baseDir), "", idLower);
|
|
176
|
+
const found = await scanForDocument(path.join(workspaceRoot, baseDir), "", idLower, fio);
|
|
164
177
|
if (!found) return undefined;
|
|
165
178
|
|
|
166
179
|
let source: string;
|
|
167
180
|
try {
|
|
168
|
-
source = await
|
|
181
|
+
source = await fio.readFile(path.join(workspaceRoot, baseDir, found));
|
|
169
182
|
} catch {
|
|
170
183
|
return undefined;
|
|
171
184
|
}
|
|
@@ -242,8 +255,10 @@ export interface QueueItemReport {
|
|
|
242
255
|
export async function deriveQueueItemStatus(
|
|
243
256
|
workspaceRoot: string,
|
|
244
257
|
docId: string,
|
|
258
|
+
io?: WorkspaceIO,
|
|
245
259
|
): Promise<QueueItemReport | undefined> {
|
|
246
|
-
const
|
|
260
|
+
const fio = resolveIo(io);
|
|
261
|
+
const doc = await resolveDocument(workspaceRoot, docId, fio);
|
|
247
262
|
if (!doc) return undefined;
|
|
248
263
|
|
|
249
264
|
const fm = doc.frontmatter;
|
|
@@ -268,8 +283,8 @@ export async function deriveQueueItemStatus(
|
|
|
268
283
|
}
|
|
269
284
|
|
|
270
285
|
const enhancedAt = fm["enhancedAt"] ? String(fm["enhancedAt"]) : undefined;
|
|
271
|
-
const auditFile = await findAuditFile(workspaceRoot, doc.id);
|
|
272
|
-
const planFile = await findPlanFile(workspaceRoot, doc.id);
|
|
286
|
+
const auditFile = await findAuditFile(workspaceRoot, doc.id, fio);
|
|
287
|
+
const planFile = await findPlanFile(workspaceRoot, doc.id, fio);
|
|
273
288
|
|
|
274
289
|
const stages = computeRfcPipelineStages({
|
|
275
290
|
status,
|
|
@@ -306,10 +321,12 @@ export interface QueueReport {
|
|
|
306
321
|
export async function deriveQueueReport(
|
|
307
322
|
workspaceRoot: string,
|
|
308
323
|
itemIds: string[],
|
|
324
|
+
io?: WorkspaceIO,
|
|
309
325
|
): Promise<QueueReport> {
|
|
326
|
+
const fio = resolveIo(io);
|
|
310
327
|
const items: QueueItemReport[] = [];
|
|
311
328
|
for (const id of itemIds) {
|
|
312
|
-
const report = await deriveQueueItemStatus(workspaceRoot, id);
|
|
329
|
+
const report = await deriveQueueItemStatus(workspaceRoot, id, fio);
|
|
313
330
|
// Unresolvable ids are reported by the manifest validator; the resolver
|
|
314
331
|
// skips them here so a partial report stays usable.
|
|
315
332
|
if (report) items.push(report);
|
|
@@ -20,7 +20,7 @@ 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 { z } from "zod";
|
|
26
26
|
import { parse as parseYaml } from "yaml";
|
package/src/registry.ts
CHANGED
|
@@ -19,7 +19,7 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
|
|
|
19
19
|
</CHANGE_SUMMARY>
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import fs from "
|
|
22
|
+
import * as fs from "./utils/sync-fs.ts";
|
|
23
23
|
import path from "node:path";
|
|
24
24
|
import { parse as parseYaml } from "yaml";
|
|
25
25
|
import type { ForgeConfig } from "./config/forge-config.ts";
|
|
@@ -38,7 +38,7 @@ export interface ForgeSkillEntry {
|
|
|
38
38
|
dependsOn: string[];
|
|
39
39
|
path: string;
|
|
40
40
|
knowledge?: string[];
|
|
41
|
-
|
|
41
|
+
triggerPhrases?: string[];
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
@@ -191,9 +191,9 @@ function discoverForgeSkills(skillsRoot: string): ForgeSkillEntry[] {
|
|
|
191
191
|
),
|
|
192
192
|
}
|
|
193
193
|
: {}),
|
|
194
|
-
...(Array.isArray(fm["
|
|
194
|
+
...(Array.isArray(fm["triggerPhrases"])
|
|
195
195
|
? {
|
|
196
|
-
|
|
196
|
+
triggerPhrases: (fm["triggerPhrases"] as unknown[]).filter(
|
|
197
197
|
(v): v is string => typeof v === "string",
|
|
198
198
|
),
|
|
199
199
|
}
|
package/src/skill-schema.ts
CHANGED
|
@@ -31,7 +31,10 @@ export const skillFrontmatterSchema = z.object({
|
|
|
31
31
|
})
|
|
32
32
|
.optional(),
|
|
33
33
|
knowledge: z.array(z.string()).optional(),
|
|
34
|
-
triggers
|
|
34
|
+
// Named triggerPhrases, not triggers — agent-IDE skill loaders (Devin CLI,
|
|
35
|
+
// Windsurf) reserve `triggers` for invocation modes (user/model); a list of
|
|
36
|
+
// phrases parses to zero valid modes and the skill is dropped entirely.
|
|
37
|
+
triggerPhrases: z.array(z.string().min(5).max(100)).max(5).optional(),
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
export type SkillFrontmatter = z.infer<typeof skillFrontmatterSchema>;
|
|
@@ -36,17 +36,13 @@ describe("validateAcceptanceShape — test probe", () => {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
it("rejects a test probe missing file", () => {
|
|
39
|
-
const issues = validateAcceptanceShape([
|
|
40
|
-
{ probe: "test", expect: { exitCode: 0 } },
|
|
41
|
-
]);
|
|
39
|
+
const issues = validateAcceptanceShape([{ probe: "test", expect: { exitCode: 0 } }]);
|
|
42
40
|
expect(issues).toHaveLength(1);
|
|
43
41
|
expect(issues[0].message).toContain('requires a string "file"');
|
|
44
42
|
});
|
|
45
43
|
|
|
46
44
|
it("rejects a test probe missing expect.exitCode", () => {
|
|
47
|
-
const issues = validateAcceptanceShape([
|
|
48
|
-
{ probe: "test", file: "src/test.ts" },
|
|
49
|
-
]);
|
|
45
|
+
const issues = validateAcceptanceShape([{ probe: "test", file: "src/test.ts" }]);
|
|
50
46
|
expect(issues).toHaveLength(1);
|
|
51
47
|
expect(issues[0].message).toContain("requires expect: { exitCode");
|
|
52
48
|
});
|
|
@@ -108,9 +104,7 @@ describe("validateAcceptanceShape — existing probe kinds (regression)", () =>
|
|
|
108
104
|
});
|
|
109
105
|
|
|
110
106
|
it("accepts well-formed file-exists probe", () => {
|
|
111
|
-
const issues = validateAcceptanceShape([
|
|
112
|
-
{ probe: "file-exists", path: "src/index.ts" },
|
|
113
|
-
]);
|
|
107
|
+
const issues = validateAcceptanceShape([{ probe: "file-exists", path: "src/index.ts" }]);
|
|
114
108
|
expect(issues).toEqual([]);
|
|
115
109
|
});
|
|
116
110
|
|
|
@@ -122,16 +116,12 @@ describe("validateAcceptanceShape — existing probe kinds (regression)", () =>
|
|
|
122
116
|
});
|
|
123
117
|
|
|
124
118
|
it("accepts well-formed command-registered probe", () => {
|
|
125
|
-
const issues = validateAcceptanceShape([
|
|
126
|
-
{ probe: "command-registered", name: "rfc.validate" },
|
|
127
|
-
]);
|
|
119
|
+
const issues = validateAcceptanceShape([{ probe: "command-registered", name: "rfc.validate" }]);
|
|
128
120
|
expect(issues).toEqual([]);
|
|
129
121
|
});
|
|
130
122
|
|
|
131
123
|
it("accepts well-formed page probe", () => {
|
|
132
|
-
const issues = validateAcceptanceShape([
|
|
133
|
-
{ probe: "page", path: "/about" },
|
|
134
|
-
]);
|
|
124
|
+
const issues = validateAcceptanceShape([{ probe: "page", path: "/about" }]);
|
|
135
125
|
expect(issues).toEqual([]);
|
|
136
126
|
});
|
|
137
127
|
});
|
|
@@ -10,7 +10,7 @@ routing table, conditional extended layer, markers, and idempotency (RFC-0548, R
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { test, expect, beforeEach, afterEach } from "vitest";
|
|
13
|
-
import { mkdtemp, rm, writeFile, mkdir, readFile } from "node:fs/promises";
|
|
13
|
+
import { mkdtemp, rm, writeFile, mkdir, readFile, symlink } from "node:fs/promises";
|
|
14
14
|
import { existsSync } from "node:fs";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { join } from "node:path";
|
|
@@ -102,11 +102,33 @@ test("agents-generate includes intent-to-skill routing table", async () => {
|
|
|
102
102
|
|
|
103
103
|
const agentsMd = await readFile(join(tempDir, "AGENTS.md"), "utf8");
|
|
104
104
|
expect(agentsMd).toContain("### Intent-to-skill routing");
|
|
105
|
-
|
|
105
|
+
// RFC-1154: header cells are padded to column width — match via regex
|
|
106
|
+
expect(agentsMd).toMatch(/\| Operator says something like +\| Skill +\|/);
|
|
106
107
|
// Should contain at least one skill name from the registry
|
|
107
108
|
expect(agentsMd).toContain("fo-");
|
|
108
109
|
});
|
|
109
110
|
|
|
111
|
+
test("agents-generate populates routing table rows in consumer layout (no packages/forge)", async () => {
|
|
112
|
+
await makeForgeYaml(tempDir);
|
|
113
|
+
// Consumer install: the package lives under node_modules — skills ship inside
|
|
114
|
+
// it. A symlinked node_modules/@warpgogol/forge mimics the npm layout.
|
|
115
|
+
const consumerPkg = join(tempDir, "node_modules", "@warpgogol", "forge");
|
|
116
|
+
await mkdir(join(consumerPkg, ".."), { recursive: true });
|
|
117
|
+
await symlink(FORGE_ROOT, consumerPkg, "junction");
|
|
118
|
+
|
|
119
|
+
// forgeRoot undefined → extraction must resolve via the consumer layout.
|
|
120
|
+
const result = await runAgentsGenerate(
|
|
121
|
+
{ argv: [], flags: {} },
|
|
122
|
+
{ ...makeContext(tempDir), forgeRoot: undefined },
|
|
123
|
+
);
|
|
124
|
+
expect(result.exitCode).toBe(0);
|
|
125
|
+
|
|
126
|
+
const agentsMd = await readFile(join(tempDir, "AGENTS.md"), "utf8");
|
|
127
|
+
// A quoted trigger phrase appears only in routing-table rows — the Skills
|
|
128
|
+
// table contains bare skill names, so this probes extraction end-to-end.
|
|
129
|
+
expect(agentsMd).toContain('"show RFC and ADR status"');
|
|
130
|
+
});
|
|
131
|
+
|
|
110
132
|
test("agents-generate includes fixed policy text sections", async () => {
|
|
111
133
|
await makeForgeYaml(tempDir);
|
|
112
134
|
const result = await runAgentsGenerate({ argv: [], flags: {} }, makeContext(tempDir));
|
|
@@ -427,9 +449,10 @@ test("agents-generate nested renders entry points from exports map", async () =>
|
|
|
427
449
|
|
|
428
450
|
const nested = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
|
|
429
451
|
expect(nested).toContain("## Entry points");
|
|
430
|
-
|
|
431
|
-
expect(nested).
|
|
432
|
-
expect(nested).
|
|
452
|
+
// RFC-1154: cells are padded to column width — match via regex
|
|
453
|
+
expect(nested).toMatch(/\| `@test\/my-pkg` +\| `\.\/src\/index\.ts` +\|/);
|
|
454
|
+
expect(nested).toMatch(/\| `@test\/my-pkg\/port` +\| `\.\/src\/port\.ts` +\|/);
|
|
455
|
+
expect(nested).toMatch(/\| `@test\/my-pkg\/client` +\| `\.\/src\/client\.ts` +\|/);
|
|
433
456
|
});
|
|
434
457
|
|
|
435
458
|
test("agents-generate nested separates workspace and external dependencies", async () => {
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Unit tests for src/cli-flags.ts — schema-driven argv-to-flags
|
|
4
|
+
resolution for the standalone forge CLI (strict KERNEL-FLAG-01/02/03 and
|
|
5
|
+
KERNEL-ARG-01 diagnostics, legacy heuristic path for schema-less commands).</purpose>
|
|
6
|
+
<non-goals>
|
|
7
|
+
<item>Do not test bin/cli.ts dispatch — these tests cover pure functions only.</item>
|
|
8
|
+
</non-goals>
|
|
9
|
+
</MODULE_CONTRACT>
|
|
10
|
+
<CHANGE_SUMMARY>
|
|
11
|
+
<item>Initial cli-flags resolution tests — covers the `forge rfc.validate --id` crash regression (value-less declared string flag must produce KERNEL-FLAG-02, not a boolean).</item>
|
|
12
|
+
</CHANGE_SUMMARY>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { describe, expect, test } from "vitest";
|
|
16
|
+
import { parseCliArgs, resolveCliFlags } from "../cli-flags.ts";
|
|
17
|
+
import type { ForgeCommandDefinition, ForgeFlagSpec } from "../types.ts";
|
|
18
|
+
|
|
19
|
+
function command(flags?: Record<string, ForgeFlagSpec>): ForgeCommandDefinition {
|
|
20
|
+
return {
|
|
21
|
+
name: "test.command",
|
|
22
|
+
description: "test command",
|
|
23
|
+
scope: "workspace",
|
|
24
|
+
flags,
|
|
25
|
+
execute: () => {},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const errorRuleIds = (diagnostics: { ruleId: string; severity: string }[]) =>
|
|
30
|
+
diagnostics.filter((d) => d.severity === "error").map((d) => d.ruleId);
|
|
31
|
+
|
|
32
|
+
describe("resolveCliFlags — strict (schema-carrying) path", () => {
|
|
33
|
+
const rfcValidate = command({
|
|
34
|
+
id: { kind: "string", description: "Target a single RFC by id." },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("value-less declared string flag errors with KERNEL-FLAG-02 instead of becoming `true`", () => {
|
|
38
|
+
const { flags, diagnostics } = resolveCliFlags(["--id"], rfcValidate);
|
|
39
|
+
expect(flags["id"]).toBeUndefined();
|
|
40
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
|
|
41
|
+
expect(diagnostics[0]!.message).toContain('Flag "--id"');
|
|
42
|
+
expect(diagnostics[0]!.message).toContain('"test.command"');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("value-less declared string flag before another flag still errors", () => {
|
|
46
|
+
const { flags, diagnostics } = resolveCliFlags(["--id", "--json"], rfcValidate);
|
|
47
|
+
expect(flags["id"]).toBeUndefined();
|
|
48
|
+
expect(flags["json"]).toBe(true);
|
|
49
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("--id <value> and --id=<value> resolve to the string", () => {
|
|
53
|
+
for (const argv of [["--id", "RFC-0609"], ["--id=RFC-0609"]]) {
|
|
54
|
+
const { flags, diagnostics } = resolveCliFlags(argv, rfcValidate);
|
|
55
|
+
expect(flags["id"]).toBe("RFC-0609");
|
|
56
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("repeated single-value string flag errors instead of promoting to an array", () => {
|
|
61
|
+
const { flags, diagnostics } = resolveCliFlags(["--id", "RFC-1", "--id", "RFC-2"], rfcValidate);
|
|
62
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
|
|
63
|
+
expect(diagnostics[0]!.message).toContain("single value");
|
|
64
|
+
expect(flags["id"]).toEqual(["RFC-1", "RFC-2"]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("unknown flag errors with KERNEL-FLAG-01 listing valid flags", () => {
|
|
68
|
+
const { diagnostics } = resolveCliFlags(["--idd"], rfcValidate);
|
|
69
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-01"]);
|
|
70
|
+
expect(diagnostics[0]!.message).toContain("id");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("unknown flag followed by a bare token also flags the token as positional", () => {
|
|
74
|
+
const { diagnostics } = resolveCliFlags(["--idd", "RFC-1"], rfcValidate);
|
|
75
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-01", "KERNEL-ARG-01"]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("required flag missing errors with KERNEL-FLAG-03", () => {
|
|
79
|
+
const cmd = command({
|
|
80
|
+
name: { kind: "string", required: true, description: "Required name." },
|
|
81
|
+
});
|
|
82
|
+
const { diagnostics } = resolveCliFlags([], cmd);
|
|
83
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-03"]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("declared default applies when flag absent", () => {
|
|
87
|
+
const cmd = command({
|
|
88
|
+
mode: { kind: "string", default: "all", description: "Mode." },
|
|
89
|
+
});
|
|
90
|
+
const { flags, diagnostics } = resolveCliFlags([], cmd);
|
|
91
|
+
expect(flags["mode"]).toBe("all");
|
|
92
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("positional token errors with KERNEL-ARG-01", () => {
|
|
96
|
+
const { diagnostics } = resolveCliFlags(["RFC-0609"], rfcValidate);
|
|
97
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("tokens after -- are positional errors", () => {
|
|
101
|
+
const { diagnostics } = resolveCliFlags(["--id", "RFC-1", "--", "extra"], rfcValidate);
|
|
102
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("universal flags accepted on commands with empty schema", () => {
|
|
106
|
+
const { flags, diagnostics } = resolveCliFlags(
|
|
107
|
+
["--json", "--dry-run", "--help", "--site", "x"],
|
|
108
|
+
command({}),
|
|
109
|
+
);
|
|
110
|
+
expect(flags["json"]).toBe(true);
|
|
111
|
+
expect(flags["dry-run"]).toBe(true);
|
|
112
|
+
expect(flags["help"]).toBe(true);
|
|
113
|
+
expect(flags["site"]).toBe("x");
|
|
114
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("universal boolean does not swallow the next flag's token", () => {
|
|
118
|
+
const cmd = command({ fix: { kind: "boolean", description: "Fix." } });
|
|
119
|
+
const { flags, diagnostics } = resolveCliFlags(["--json", "--fix"], cmd);
|
|
120
|
+
expect(flags["json"]).toBe(true);
|
|
121
|
+
expect(flags["fix"]).toBe(true);
|
|
122
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("--flag=false on a declared boolean resolves to false", () => {
|
|
126
|
+
const cmd = command({ fix: { kind: "boolean", description: "Fix." } });
|
|
127
|
+
const { flags, diagnostics } = resolveCliFlags(["--fix=false"], cmd);
|
|
128
|
+
expect(flags["fix"]).toBe(false);
|
|
129
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("string[] flag collects repeated values", () => {
|
|
133
|
+
const cmd = command({
|
|
134
|
+
files: { kind: "string[]", description: "Files." },
|
|
135
|
+
});
|
|
136
|
+
const { flags, diagnostics } = resolveCliFlags(["--files", "a", "--files", "b"], cmd);
|
|
137
|
+
expect(flags["files"]).toEqual(["a", "b"]);
|
|
138
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe("resolveCliFlags — legacy (schema-less) path", () => {
|
|
143
|
+
const schemaLess = command(undefined);
|
|
144
|
+
|
|
145
|
+
test("unknown flags still parse heuristically", () => {
|
|
146
|
+
const { flags, diagnostics } = resolveCliFlags(["--anything", "v"], schemaLess);
|
|
147
|
+
expect(flags["anything"]).toBe("v");
|
|
148
|
+
expect(errorRuleIds(diagnostics)).toEqual([]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("known boolean switches do not consume the next token", () => {
|
|
152
|
+
const { flags } = resolveCliFlags(["--json", "v"], schemaLess);
|
|
153
|
+
expect(flags["json"]).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("positional token errors with KERNEL-ARG-01", () => {
|
|
157
|
+
const { diagnostics } = resolveCliFlags(["positional"], schemaLess);
|
|
158
|
+
expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe("parseCliArgs", () => {
|
|
163
|
+
test("--key=value and --key value forms both resolve", () => {
|
|
164
|
+
const { flags } = parseCliArgs(["--a=1", "--b", "2", "--json"]);
|
|
165
|
+
expect(flags["a"]).toBe("1");
|
|
166
|
+
expect(flags["b"]).toBe("2");
|
|
167
|
+
expect(flags["json"]).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -41,11 +41,15 @@ describe("contract-registry (RFC-0943)", () => {
|
|
|
41
41
|
|
|
42
42
|
describe("fileMatchesGlobs", () => {
|
|
43
43
|
test("matches a simple glob pattern", () => {
|
|
44
|
-
expect(fileMatchesGlobs("packages/my-pack/src/index.ts", ["packages/my-pack/**/*.ts"])).toBe(
|
|
44
|
+
expect(fileMatchesGlobs("packages/my-pack/src/index.ts", ["packages/my-pack/**/*.ts"])).toBe(
|
|
45
|
+
true,
|
|
46
|
+
);
|
|
45
47
|
});
|
|
46
48
|
|
|
47
49
|
test("does not match when glob does not match", () => {
|
|
48
|
-
expect(
|
|
50
|
+
expect(
|
|
51
|
+
fileMatchesGlobs("packages/other-pack/src/index.ts", ["packages/my-pack/**/*.ts"]),
|
|
52
|
+
).toBe(false);
|
|
49
53
|
});
|
|
50
54
|
|
|
51
55
|
test("matches any of multiple globs", () => {
|
|
@@ -58,7 +62,9 @@ describe("contract-registry (RFC-0943)", () => {
|
|
|
58
62
|
});
|
|
59
63
|
|
|
60
64
|
test("handles dot files with dot option", () => {
|
|
61
|
-
expect(fileMatchesGlobs("packages/my-pack/.env.example", ["packages/**/*.example"])).toBe(
|
|
65
|
+
expect(fileMatchesGlobs("packages/my-pack/.env.example", ["packages/**/*.example"])).toBe(
|
|
66
|
+
true,
|
|
67
|
+
);
|
|
62
68
|
});
|
|
63
69
|
});
|
|
64
70
|
|
|
@@ -86,7 +92,7 @@ describe("contract-registry (RFC-0943)", () => {
|
|
|
86
92
|
const packDir = join(ws, "my-pack");
|
|
87
93
|
writeManifest(
|
|
88
94
|
packDir,
|
|
89
|
-
|
|
95
|
+
'id: my-pack\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: api-contract\n requiredFor:\n - "packages/my-pack/**/*.ts"\n requiredTags:\n - name: endpoints\n minWords: 5\n',
|
|
90
96
|
);
|
|
91
97
|
|
|
92
98
|
const config: ForgeConfig = {
|
|
@@ -111,11 +117,11 @@ describe("contract-registry (RFC-0943)", () => {
|
|
|
111
117
|
try {
|
|
112
118
|
writeManifest(
|
|
113
119
|
join(ws, "pack-a"),
|
|
114
|
-
|
|
120
|
+
'id: pack-a\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - "packages/**/*.ts"\n',
|
|
115
121
|
);
|
|
116
122
|
writeManifest(
|
|
117
123
|
join(ws, "pack-b"),
|
|
118
|
-
|
|
124
|
+
'id: pack-b\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - "services/**/*.ts"\n',
|
|
119
125
|
);
|
|
120
126
|
|
|
121
127
|
const config: ForgeConfig = {
|
|
@@ -83,10 +83,7 @@ test("doctor --fix regenerates stale nested AGENTS.md and subsequent run passes"
|
|
|
83
83
|
expect(fixEntry).toBeDefined();
|
|
84
84
|
expect(fixEntry!.action).toBe("fixed");
|
|
85
85
|
|
|
86
|
-
const regenerated = await readFile(
|
|
87
|
-
join(tempDir, "packages", "my-pkg", "AGENTS.md"),
|
|
88
|
-
"utf8",
|
|
89
|
-
);
|
|
86
|
+
const regenerated = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
|
|
90
87
|
expect(regenerated).toContain("`@test/my-pkg` — Agent Guide");
|
|
91
88
|
expect(regenerated).not.toContain("Old content");
|
|
92
89
|
|
|
@@ -9,10 +9,13 @@ workspace discovery exclusions via bindings.workspaces.skipDirs (RFC-1150).</pur
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { test, expect, beforeEach, afterEach } from "vitest";
|
|
12
|
-
import { mkdtemp, rm, mkdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { mkdtemp, rm, mkdir, writeFile, appendFile } from "node:fs/promises";
|
|
13
13
|
import { tmpdir } from "node:os";
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
import { runDoctor } from "../onboarding/doctor.ts";
|
|
16
|
+
import { generateNestedAgentsMd } from "../onboarding/nested-agents-generate.ts";
|
|
17
|
+
import { buildGeneratedHeader } from "../utils/index.ts";
|
|
18
|
+
import { loadForgeConfig } from "../config/forge-config.ts";
|
|
16
19
|
import type { ForgeCommandInput, ForgeRuntimeContext } from "../types.ts";
|
|
17
20
|
|
|
18
21
|
let tempDir: string;
|
|
@@ -106,3 +109,52 @@ test("nested-AGENTS.md check reports artifact dir as missing without skipDirs",
|
|
|
106
109
|
expect(check).toBeDefined();
|
|
107
110
|
expect(check!.message).toContain("builds");
|
|
108
111
|
});
|
|
112
|
+
|
|
113
|
+
// RFC-1153: boundary-aware staleness -----------------------------------------
|
|
114
|
+
|
|
115
|
+
test("AC-8: custom content below the forge:custom boundary reports in-sync, not stale", async () => {
|
|
116
|
+
await writeFile(join(tempDir, "forge.yaml"), forgeYaml([]), "utf8");
|
|
117
|
+
await mkdir(join(tempDir, "packages", "pkg"), { recursive: true });
|
|
118
|
+
await writeFile(join(tempDir, "packages", "pkg", "package.json"), '{"name":"pkg"}', "utf8");
|
|
119
|
+
|
|
120
|
+
const config = loadForgeConfig(tempDir);
|
|
121
|
+
await generateNestedAgentsMd(tempDir, config, false);
|
|
122
|
+
|
|
123
|
+
// Operator appends a custom section below the marker
|
|
124
|
+
await appendFile(
|
|
125
|
+
join(tempDir, "packages", "pkg", "AGENTS.md"),
|
|
126
|
+
"\n## Custom rules\n\n- workspace-specific note\n",
|
|
127
|
+
"utf8",
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const input: ForgeCommandInput = { argv: [], flags: {} };
|
|
131
|
+
const result = await runDoctor(input, makeContext());
|
|
132
|
+
|
|
133
|
+
const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
|
|
134
|
+
expect(check).toBeDefined();
|
|
135
|
+
expect(
|
|
136
|
+
check!.message,
|
|
137
|
+
"Below-boundary divergence must not count as stale — merge(expected, actual) compares only the head",
|
|
138
|
+
).not.toContain("stale");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("AC-6: divergent file without a resolvable boundary reports unmapped-customization", async () => {
|
|
142
|
+
await writeFile(join(tempDir, "forge.yaml"), forgeYaml([]), "utf8");
|
|
143
|
+
await mkdir(join(tempDir, "packages", "legacy"), { recursive: true });
|
|
144
|
+
await writeFile(join(tempDir, "packages", "legacy", "package.json"), '{"name":"legacy"}', "utf8");
|
|
145
|
+
// Marker-bearing (isGenerated) file that diverges and lacks footer/forge:custom
|
|
146
|
+
await writeFile(
|
|
147
|
+
join(tempDir, "packages", "legacy", "AGENTS.md"),
|
|
148
|
+
`${buildGeneratedHeader({ filePath: "AGENTS.md", ownerCommand: "forge.agents.generate", editable: true })}\n# Hand-maintained\n\ndivergent body\n`,
|
|
149
|
+
"utf8",
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const input: ForgeCommandInput = { argv: [], flags: {} };
|
|
153
|
+
const result = await runDoctor(input, makeContext());
|
|
154
|
+
|
|
155
|
+
const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
|
|
156
|
+
expect(check).toBeDefined();
|
|
157
|
+
expect(check!.status).toBe("warn");
|
|
158
|
+
expect(check!.message).toContain("unmapped-customization");
|
|
159
|
+
expect(check!.message).not.toContain("stale");
|
|
160
|
+
});
|