@warpgogol/forge 5.2.3 → 5.3.0
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/AGENTS.md +34 -2
- package/README.md +1 -1
- package/README.uk.md +8 -8
- package/bin/cli.ts +1 -0
- package/dist/bin/cli.js +1 -0
- 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 -9
- 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 +57 -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 +22 -19
- 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/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/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/compass/contract-registry.js +1 -1
- package/dist/src/compass/contract-registry.js.map +1 -1
- package/dist/src/config/forge-config.d.ts +10 -1
- package/dist/src/config/forge-config.d.ts.map +1 -1
- package/dist/src/config/forge-config.js +8 -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 +2 -0
- package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
- package/dist/src/onboarding/agents-generate.js +73 -48
- 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 +6 -0
- package/dist/src/onboarding/doctor.d.ts.map +1 -1
- package/dist/src/onboarding/doctor.js +179 -61
- 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 +22 -0
- package/dist/src/onboarding/memory-compact.d.ts.map +1 -0
- package/dist/src/onboarding/memory-compact.js +148 -0
- package/dist/src/onboarding/memory-compact.js.map +1 -0
- package/dist/src/onboarding/memory-scaffold.d.ts +1 -0
- package/dist/src/onboarding/memory-scaffold.d.ts.map +1 -1
- package/dist/src/onboarding/memory-scaffold.js +2 -2
- 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 +35 -6
- 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.d.ts +1 -1
- package/dist/src/onboarding/workspace-discovery.d.ts.map +1 -1
- package/dist/src/onboarding/workspace-discovery.js +15 -3
- 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/docs/reference/forge-yaml.md +12 -0
- 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 -9
- 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 +58 -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.ts +27 -19
- 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/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/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 +3 -0
- package/profiles/godot-game.yaml +3 -0
- package/profiles/phaser-game.yaml +3 -0
- package/profiles/site-workshop.yaml +567 -564
- 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/compass/contract-registry.ts +1 -1
- package/src/config/forge-config.ts +12 -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 +91 -50
- package/src/onboarding/create.ts +10 -10
- package/src/onboarding/doctor.ts +199 -59
- package/src/onboarding/init.ts +38 -1
- package/src/onboarding/invariant-engine.ts +1 -1
- package/src/onboarding/memory-compact.ts +189 -0
- package/src/onboarding/memory-scaffold.ts +2 -2
- package/src/onboarding/nested-agents-generate.ts +50 -5
- 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 +16 -2
- 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 +32 -7
- package/src/tests/contract-registry.test.ts +12 -6
- package/src/tests/doctor-dist-freshness.test.ts +110 -0
- package/src/tests/doctor-fix.test.ts +142 -0
- package/src/tests/doctor-nested-agents.test.ts +160 -0
- 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 +54 -54
- package/src/tests/markdown-table.test.ts +107 -0
- package/src/tests/memory-compact.test.ts +143 -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/tests/workspace-discovery.test.ts +28 -0
- 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
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Unit tests for the nested-AGENTS.md doctor check — consumer-declared
|
|
4
|
+
workspace discovery exclusions via bindings.workspaces.skipDirs (RFC-1150).</purpose>
|
|
5
|
+
</MODULE_CONTRACT>
|
|
6
|
+
<CHANGE_SUMMARY>
|
|
7
|
+
<item>RFC-1150: initial nested-AGENTS.md skipDirs tests.</item>
|
|
8
|
+
</CHANGE_SUMMARY>
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { test, expect, beforeEach, afterEach } from "vitest";
|
|
12
|
+
import { mkdtemp, rm, mkdir, writeFile, appendFile } from "node:fs/promises";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
import { join } from "node:path";
|
|
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";
|
|
19
|
+
import type { ForgeCommandInput, ForgeRuntimeContext } from "../types.ts";
|
|
20
|
+
|
|
21
|
+
let tempDir: string;
|
|
22
|
+
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
tempDir = await mkdtemp(join(tmpdir(), "doctor-nested-test-"));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(async () => {
|
|
28
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function makeContext(): ForgeRuntimeContext {
|
|
32
|
+
return {
|
|
33
|
+
workspaceRoot: tempDir,
|
|
34
|
+
logger: {
|
|
35
|
+
section: () => {},
|
|
36
|
+
success: () => {},
|
|
37
|
+
warn: () => {},
|
|
38
|
+
error: () => {},
|
|
39
|
+
info: () => {},
|
|
40
|
+
},
|
|
41
|
+
dryRun: false,
|
|
42
|
+
outputFormat: "json",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function forgeYaml(skipDirs: string[]): string {
|
|
47
|
+
const skip = skipDirs.length > 0 ? `\n workspaces:\n skipDirs: [${skipDirs.join(", ")}]` : "";
|
|
48
|
+
return `schema: "forge/config@1"
|
|
49
|
+
project:
|
|
50
|
+
name: test-project
|
|
51
|
+
stack: []
|
|
52
|
+
packageManager: pnpm
|
|
53
|
+
paths:
|
|
54
|
+
rfcsDir: docs/rfcs
|
|
55
|
+
adrsDir: docs/adrs
|
|
56
|
+
plansDir: docs/plans
|
|
57
|
+
auditsDir: docs/audits
|
|
58
|
+
specsDir: docs/specs
|
|
59
|
+
skillsDir: .agents/skills
|
|
60
|
+
sessionsDir: docs/sessions
|
|
61
|
+
bindings:
|
|
62
|
+
schema: forge/bindings@1
|
|
63
|
+
commands:
|
|
64
|
+
validateRfc: null
|
|
65
|
+
validateAdr: null
|
|
66
|
+
implementStamp: null
|
|
67
|
+
typecheck: null
|
|
68
|
+
test: null
|
|
69
|
+
scopedBuild: null
|
|
70
|
+
specValidate: null
|
|
71
|
+
sessionSave: null
|
|
72
|
+
paths:
|
|
73
|
+
invariantsFile: null
|
|
74
|
+
compassDocs: []
|
|
75
|
+
reviewsDir: null
|
|
76
|
+
handoffsDir: null
|
|
77
|
+
sessionsDir: null${skip}
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
test("nested-AGENTS.md check excludes dirs declared in workspaces.skipDirs", async () => {
|
|
82
|
+
await writeFile(join(tempDir, "forge.yaml"), forgeYaml(["builds"]), "utf8");
|
|
83
|
+
// Artifact dir that would otherwise be discovered as a workspace
|
|
84
|
+
await mkdir(join(tempDir, "builds", "out"), { recursive: true });
|
|
85
|
+
await writeFile(join(tempDir, "builds", "out", "package.json"), "{}");
|
|
86
|
+
// Real workspace without AGENTS.md — must still be reported missing
|
|
87
|
+
await mkdir(join(tempDir, "packages", "real-pkg"), { recursive: true });
|
|
88
|
+
await writeFile(join(tempDir, "packages", "real-pkg", "package.json"), "{}");
|
|
89
|
+
|
|
90
|
+
const input: ForgeCommandInput = { argv: [], flags: {} };
|
|
91
|
+
const result = await runDoctor(input, makeContext());
|
|
92
|
+
|
|
93
|
+
const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
|
|
94
|
+
expect(check).toBeDefined();
|
|
95
|
+
// missing-only reports pass (warn requires stale>0) — assert on message
|
|
96
|
+
expect(check!.message).toContain("packages/real-pkg");
|
|
97
|
+
expect(check!.message).not.toContain("builds");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("nested-AGENTS.md check reports artifact dir as missing without skipDirs", async () => {
|
|
101
|
+
await writeFile(join(tempDir, "forge.yaml"), forgeYaml([]), "utf8");
|
|
102
|
+
await mkdir(join(tempDir, "builds", "out"), { recursive: true });
|
|
103
|
+
await writeFile(join(tempDir, "builds", "out", "package.json"), "{}");
|
|
104
|
+
|
|
105
|
+
const input: ForgeCommandInput = { argv: [], flags: {} };
|
|
106
|
+
const result = await runDoctor(input, makeContext());
|
|
107
|
+
|
|
108
|
+
const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
|
|
109
|
+
expect(check).toBeDefined();
|
|
110
|
+
expect(check!.message).toContain("builds");
|
|
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
|
+
});
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Unit tests for the RFC-1153 preservation boundary — splitEditableGenerated
|
|
4
|
+
and mergeEditableGenerated (forge:custom marker + canonical-footer fallback),
|
|
5
|
+
plus an integration pass through generateNestedAgentsMd on a temp workspace.</purpose>
|
|
6
|
+
</MODULE_CONTRACT>
|
|
7
|
+
<CHANGE_SUMMARY>
|
|
8
|
+
<item>RFC-1153: initial boundary merge tests — marker, footer fallback, fail-closed, comment styles, CRLF, integration.</item>
|
|
9
|
+
</CHANGE_SUMMARY>
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { test, expect, beforeEach, afterEach } from "vitest";
|
|
13
|
+
import { mkdtemp, mkdir, rm, writeFile, readFile, appendFile } from "node:fs/promises";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import {
|
|
17
|
+
splitEditableGenerated,
|
|
18
|
+
mergeEditableGenerated,
|
|
19
|
+
canonicalFooterOf,
|
|
20
|
+
} from "../utils/editable-region.ts";
|
|
21
|
+
import {
|
|
22
|
+
CUSTOM_BOUNDARY_HINTS,
|
|
23
|
+
CUSTOM_BOUNDARY_MARKERS,
|
|
24
|
+
buildGeneratedHeader,
|
|
25
|
+
} from "../utils/generated-marker.ts";
|
|
26
|
+
import { generateNestedAgentsMd } from "../onboarding/nested-agents-generate.ts";
|
|
27
|
+
import { loadForgeConfig } from "../config/forge-config.ts";
|
|
28
|
+
|
|
29
|
+
const MD = "AGENTS.md";
|
|
30
|
+
const MD_MARKER = CUSTOM_BOUNDARY_MARKERS["block-html"]; // <!-- forge:custom -->
|
|
31
|
+
const MD_HINT = CUSTOM_BOUNDARY_HINTS["block-html"];
|
|
32
|
+
|
|
33
|
+
const FOOTER = "See the root `AGENTS.md` for project-wide rules, skills, and capabilities.";
|
|
34
|
+
|
|
35
|
+
function render(body: string): string {
|
|
36
|
+
return `${buildGeneratedHeader({ filePath: MD, ownerCommand: "forge.agents.generate", editable: true })}\n${body}\n\n${FOOTER}\n`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
test("AC-1: content below the forge:custom marker is preserved byte-identical", () => {
|
|
40
|
+
const tail = "\n## Workspace rules\n\n- always run pnpm test first\n- custom note\n";
|
|
41
|
+
const existing = `${render("old body v1")}${MD_MARKER}\n${MD_HINT}\n${tail}`;
|
|
42
|
+
const merged = mergeEditableGenerated(render("fresh body v2"), existing, MD);
|
|
43
|
+
expect(merged).not.toBeNull();
|
|
44
|
+
// Fresh head regenerated, tail below the marker verbatim
|
|
45
|
+
expect(merged).toContain("fresh body v2");
|
|
46
|
+
expect(merged).not.toContain("old body v1");
|
|
47
|
+
expect(
|
|
48
|
+
merged!.endsWith(tail.trimStart() === tail ? tail : `\n${tail}`) || merged!.includes(tail),
|
|
49
|
+
).toBe(true);
|
|
50
|
+
expect(merged).toContain(MD_MARKER);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("marker line itself belongs to the generated head — operator-placed marker also merges", () => {
|
|
54
|
+
const tail = "everything below survives\n";
|
|
55
|
+
const existing = `hand-tuned intro\n${MD_MARKER}\n${tail}`;
|
|
56
|
+
const merged = mergeEditableGenerated(render("body"), existing, MD);
|
|
57
|
+
expect(merged).toBe(`${render("body")}${MD_MARKER}\n${MD_HINT}\n${tail}`);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("AC-2: footer fallback preserves text below the canonical template footer", () => {
|
|
61
|
+
const tail = "\noperator-appended rules\n";
|
|
62
|
+
const existing = `${render("stale body")}${tail}`; // marker-less, ends with footer + tail
|
|
63
|
+
const merged = mergeEditableGenerated(render("new body"), existing, MD);
|
|
64
|
+
expect(merged).not.toBeNull();
|
|
65
|
+
expect(merged!.endsWith(tail)).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("AC-3: footer-fallback merge introduces the forge:custom marker as the new boundary", () => {
|
|
69
|
+
const existing = `${render("body")}\ncustom tail\n`;
|
|
70
|
+
const merged = mergeEditableGenerated(render("body"), existing, MD);
|
|
71
|
+
expect(merged).toContain(MD_MARKER);
|
|
72
|
+
expect(merged).toContain(MD_HINT);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("AC-5: footer-less marker-less divergent content returns null — caller must skip", () => {
|
|
76
|
+
const existing = `${buildGeneratedHeader({ filePath: MD, ownerCommand: "forge.agents.generate", editable: true })}\n# Custom\n\ntotally divergent, no footer\n`;
|
|
77
|
+
expect(mergeEditableGenerated(render("body"), existing, MD)).toBeNull();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("identical content is a clean regeneration — marker appended for future runs", () => {
|
|
81
|
+
const r = render("body");
|
|
82
|
+
const merged = mergeEditableGenerated(r, r, MD);
|
|
83
|
+
expect(merged).toBe(`${r}${MD_MARKER}\n${MD_HINT}\n`);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("new file (existing null) gains the boundary marker and hint", () => {
|
|
87
|
+
const merged = mergeEditableGenerated(render("body"), null, MD);
|
|
88
|
+
expect(merged).toBe(`${render("body")}${MD_MARKER}\n${MD_HINT}\n`);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("AC-4: boundary marker is emitted in the comment style of the target file", () => {
|
|
92
|
+
for (const [file, style] of [
|
|
93
|
+
["AGENTS.md", "block-html"],
|
|
94
|
+
["config.ts", "line-slash"],
|
|
95
|
+
["data.yaml", "line-hash"],
|
|
96
|
+
["styles.css", "block-css"],
|
|
97
|
+
] as const) {
|
|
98
|
+
const merged = mergeEditableGenerated("content\n", null, file);
|
|
99
|
+
expect(merged, `marker for ${file} must use ${style} comment syntax`).toContain(
|
|
100
|
+
CUSTOM_BOUNDARY_MARKERS[style],
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("CRLF input normalizes to LF and still resolves the marker boundary", () => {
|
|
106
|
+
const tail = "preserved tail\n";
|
|
107
|
+
const existing = `a\r\nb\r\n${MD_MARKER}\r\n${tail}`;
|
|
108
|
+
const merged = mergeEditableGenerated("fresh\n", existing, MD);
|
|
109
|
+
expect(merged).toBe(`fresh\n${MD_MARKER}\n${MD_HINT}\n${tail}`);
|
|
110
|
+
expect(merged).not.toContain("\r\n");
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("mid-file marker freezes everything below the first occurrence", () => {
|
|
114
|
+
const tail = "mid doc\nfrozen rules\n";
|
|
115
|
+
const existing = `intro\n${MD_MARKER}\n${tail}`;
|
|
116
|
+
const merged = mergeEditableGenerated(render("body"), existing, MD);
|
|
117
|
+
expect(merged!.endsWith(tail)).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("forge:custom token in prose is treated as a boundary (first occurrence wins)", () => {
|
|
121
|
+
const existing = `notes on the forge:custom feature\nkept anyway\n`;
|
|
122
|
+
const split = splitEditableGenerated(existing, MD);
|
|
123
|
+
expect(split.boundary).toBe("marker");
|
|
124
|
+
expect(split.customTail).toBe("kept anyway\n");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("boundary none: split returns whole content as head", () => {
|
|
128
|
+
const split = splitEditableGenerated("plain\nfile\n", MD, FOOTER);
|
|
129
|
+
expect(split.boundary).toBe("none");
|
|
130
|
+
expect(split.customTail).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("canonicalFooterOf returns the last non-empty line", () => {
|
|
134
|
+
expect(canonicalFooterOf("a\nb\n\n\n")).toBe("b");
|
|
135
|
+
expect(canonicalFooterOf("x\n")).toBe("x");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// --- Integration through the real write path -----------------------------
|
|
139
|
+
|
|
140
|
+
let tempDir: string;
|
|
141
|
+
|
|
142
|
+
beforeEach(async () => {
|
|
143
|
+
tempDir = await mkdtemp(join(tmpdir(), "editable-region-it-"));
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
afterEach(async () => {
|
|
147
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const FORGE_YAML = `schema: "forge/config@1"
|
|
151
|
+
project:
|
|
152
|
+
name: test-project
|
|
153
|
+
stack: []
|
|
154
|
+
packageManager: pnpm
|
|
155
|
+
paths:
|
|
156
|
+
rfcsDir: docs/rfcs
|
|
157
|
+
adrsDir: docs/adrs
|
|
158
|
+
plansDir: docs/plans
|
|
159
|
+
auditsDir: docs/audits
|
|
160
|
+
specsDir: docs/specs
|
|
161
|
+
skillsDir: .agents/skills
|
|
162
|
+
sessionsDir: docs/sessions
|
|
163
|
+
bindings:
|
|
164
|
+
schema: forge/bindings@1
|
|
165
|
+
commands:
|
|
166
|
+
validateRfc: null
|
|
167
|
+
validateAdr: null
|
|
168
|
+
implementStamp: null
|
|
169
|
+
typecheck: null
|
|
170
|
+
test: null
|
|
171
|
+
scopedBuild: null
|
|
172
|
+
specValidate: null
|
|
173
|
+
sessionSave: null
|
|
174
|
+
paths:
|
|
175
|
+
invariantsFile: null
|
|
176
|
+
compassDocs: []
|
|
177
|
+
reviewsDir: null
|
|
178
|
+
handoffsDir: null
|
|
179
|
+
sessionsDir: null
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
test("generateNestedAgentsMd regenerates the head and preserves the custom tail", async () => {
|
|
183
|
+
await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
|
|
184
|
+
await mkdir(join(tempDir, "packages", "pkg"), { recursive: true });
|
|
185
|
+
await writeFile(join(tempDir, "packages", "pkg", "package.json"), '{"name":"pkg"}', "utf8");
|
|
186
|
+
|
|
187
|
+
const config = loadForgeConfig(tempDir);
|
|
188
|
+
|
|
189
|
+
// First run — fresh file gains the marker + hint
|
|
190
|
+
const first = await generateNestedAgentsMd(tempDir, config, false);
|
|
191
|
+
expect(first.generated).toContain(join("packages", "pkg", "AGENTS.md"));
|
|
192
|
+
const agentsPath = join(tempDir, "packages", "pkg", "AGENTS.md");
|
|
193
|
+
const initial = await readFile(agentsPath, "utf8");
|
|
194
|
+
expect(initial).toContain(MD_MARKER);
|
|
195
|
+
expect(initial).toContain(MD_HINT);
|
|
196
|
+
|
|
197
|
+
// Operator appends a custom section below the boundary
|
|
198
|
+
await appendFile(agentsPath, "\n## Workspace rules\n\n- never touch dist/\n", "utf8");
|
|
199
|
+
|
|
200
|
+
// Second run — head regenerated, tail preserved verbatim
|
|
201
|
+
const second = await generateNestedAgentsMd(tempDir, config, false);
|
|
202
|
+
expect(second.preserved).toContain(join("packages", "pkg", "AGENTS.md"));
|
|
203
|
+
const merged = await readFile(agentsPath, "utf8");
|
|
204
|
+
expect(merged).toContain("## Workspace rules");
|
|
205
|
+
expect(merged).toContain("- never touch dist/");
|
|
206
|
+
// Boundary sits between generated head and custom tail
|
|
207
|
+
expect(merged.indexOf(MD_MARKER)).toBeLessThan(merged.indexOf("## Workspace rules"));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("generateNestedAgentsMd skips a divergent file without a resolvable boundary", async () => {
|
|
211
|
+
await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
|
|
212
|
+
await mkdir(join(tempDir, "packages", "legacy"), { recursive: true });
|
|
213
|
+
await writeFile(join(tempDir, "packages", "legacy", "package.json"), '{"name":"legacy"}', "utf8");
|
|
214
|
+
// Marker-bearing (isGenerated) file whose body diverges and lacks the footer
|
|
215
|
+
await writeFile(
|
|
216
|
+
join(tempDir, "packages", "legacy", "AGENTS.md"),
|
|
217
|
+
`${buildGeneratedHeader({ filePath: "AGENTS.md", ownerCommand: "forge.agents.generate", editable: true })}\n# Hand-maintained\n\ndivergent body\n`,
|
|
218
|
+
"utf8",
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const config = loadForgeConfig(tempDir);
|
|
222
|
+
const result = await generateNestedAgentsMd(tempDir, config, false);
|
|
223
|
+
const skippedEntry = result.skipped.find((s) => s.includes("legacy"));
|
|
224
|
+
expect(
|
|
225
|
+
skippedEntry,
|
|
226
|
+
"Divergent file without forge:custom/footer boundary must be skipped as unmapped-customization",
|
|
227
|
+
).toContain("unmapped-customization");
|
|
228
|
+
// File untouched
|
|
229
|
+
const content = await readFile(join(tempDir, "packages", "legacy", "AGENTS.md"), "utf8");
|
|
230
|
+
expect(content).toContain("divergent body");
|
|
231
|
+
});
|
|
@@ -31,7 +31,10 @@ function mockContext(workspaceRoot: string): ForgeRuntimeContext {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function input(flags: Record<string, unknown> = {}): {
|
|
34
|
+
function input(flags: Record<string, unknown> = {}): {
|
|
35
|
+
argv: string[];
|
|
36
|
+
flags: Record<string, unknown>;
|
|
37
|
+
} {
|
|
35
38
|
return { argv: [], flags };
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -108,16 +111,10 @@ describe("runFileSizeLint (RFC-1088, command-level)", () => {
|
|
|
108
111
|
const big = Array.from({ length: 700 }, (_, i) => `const x${i} = ${i};`).join("\n");
|
|
109
112
|
await writeFile(join(tempDir, "packages", "some-pkg", "src", "big.ts"), big, "utf8");
|
|
110
113
|
|
|
111
|
-
const result = await runFileSizeLint(
|
|
112
|
-
input({ "write-baseline": true }),
|
|
113
|
-
mockContext(tempDir),
|
|
114
|
-
);
|
|
114
|
+
const result = await runFileSizeLint(input({ "write-baseline": true }), mockContext(tempDir));
|
|
115
115
|
expect(result.exitCode ?? 0).toBe(0);
|
|
116
116
|
|
|
117
|
-
const baselineRaw = await readFile(
|
|
118
|
-
join(tempDir, "file-size-lint.baseline.yaml"),
|
|
119
|
-
"utf8",
|
|
120
|
-
);
|
|
117
|
+
const baselineRaw = await readFile(join(tempDir, "file-size-lint.baseline.yaml"), "utf8");
|
|
121
118
|
expect(baselineRaw).toContain("schemaVersion");
|
|
122
119
|
expect(baselineRaw).toContain("threshold: 600");
|
|
123
120
|
expect(baselineRaw).toContain("big.ts");
|
|
@@ -155,9 +152,8 @@ describe("runFileSizeLint (RFC-1088, command-level)", () => {
|
|
|
155
152
|
const result = await runFileSizeLint(input(), mockContext(tempDir));
|
|
156
153
|
expect(result.exitCode ?? 0).toBe(0);
|
|
157
154
|
|
|
158
|
-
const diagnostics = (
|
|
159
|
-
|
|
160
|
-
).diagnostics;
|
|
155
|
+
const diagnostics = (result.data as { diagnostics: Array<{ ruleId: string; message: string }> })
|
|
156
|
+
.diagnostics;
|
|
161
157
|
const hit = diagnostics.find((d) => d.ruleId === "SIZE-01");
|
|
162
158
|
expect(hit).toBeDefined();
|
|
163
159
|
expect(hit!.message).toContain("grew from the baselined 700 to 800");
|
|
@@ -35,76 +35,76 @@
|
|
|
35
35
|
|
|
36
36
|
## Skills
|
|
37
37
|
|
|
38
|
-
| Name
|
|
39
|
-
|
|
|
40
|
-
| fo-add-tests
|
|
41
|
-
| fo-architecture
|
|
42
|
-
| fo-compass-annotate
|
|
43
|
-
| fo-design-summit
|
|
44
|
-
| fo-doc-audit
|
|
45
|
-
| fo-explore
|
|
46
|
-
| fo-extract-dna
|
|
47
|
-
| fo-fix
|
|
48
|
-
| fo-handoff
|
|
49
|
-
| fo-harvest
|
|
50
|
-
| fo-idea
|
|
51
|
-
| fo-idea-audit
|
|
52
|
-
| fo-idea-create-adr
|
|
53
|
-
| fo-idea-create-rfc
|
|
54
|
-
| fo-idea-enhance
|
|
55
|
-
| fo-idea-i-just-want-to-see-the-plan
|
|
56
|
-
| fo-idea-i-just-want-to-see-the-result | fo
|
|
57
|
-
| fo-idea-implement
|
|
58
|
-
| fo-idea-plan
|
|
59
|
-
| fo-idea-status
|
|
60
|
-
| fo-knowledge-distill
|
|
61
|
-
| fo-memory-sync
|
|
62
|
-
| fo-qa
|
|
63
|
-
| fo-review
|
|
64
|
-
| fo-session-retro
|
|
65
|
-
| fo-session-save
|
|
66
|
-
| fo-spec-ingest
|
|
67
|
-
| fo-step-commit
|
|
68
|
-
| fo-triage
|
|
69
|
-
| forge-bootstrap
|
|
70
|
-
| grilling
|
|
71
|
-
| my-preferences
|
|
72
|
-
| port-to-forge
|
|
73
|
-
| skill-create
|
|
74
|
-
| windows-ai-tooling
|
|
75
|
-
| writing-great-skills
|
|
38
|
+
| Name | Category | Invocation | Concerns |
|
|
39
|
+
| ------------------------------------- | -------- | ---------- | ---------------- |
|
|
40
|
+
| fo-add-tests | fo | user | code-mutation |
|
|
41
|
+
| fo-architecture | fo | user | document-only |
|
|
42
|
+
| fo-compass-annotate | fo | user | content-mutation |
|
|
43
|
+
| fo-design-summit | fo | user | document-only |
|
|
44
|
+
| fo-doc-audit | fo | user | document-only |
|
|
45
|
+
| fo-explore | fo | user | document-only |
|
|
46
|
+
| fo-extract-dna | fo | user | document-only |
|
|
47
|
+
| fo-fix | fo | user | code-mutation |
|
|
48
|
+
| fo-handoff | fo | user | document-only |
|
|
49
|
+
| fo-harvest | fo | user | code-mutation |
|
|
50
|
+
| fo-idea | fo | user | document-only |
|
|
51
|
+
| fo-idea-audit | fo | user | read-only |
|
|
52
|
+
| fo-idea-create-adr | fo | user | document-only |
|
|
53
|
+
| fo-idea-create-rfc | fo | user | document-only |
|
|
54
|
+
| fo-idea-enhance | fo | user | document-only |
|
|
55
|
+
| fo-idea-i-just-want-to-see-the-plan | fo | user | document-only |
|
|
56
|
+
| fo-idea-i-just-want-to-see-the-result | fo | user | code-mutation |
|
|
57
|
+
| fo-idea-implement | fo | user | code-mutation |
|
|
58
|
+
| fo-idea-plan | fo | user | document-only |
|
|
59
|
+
| fo-idea-status | fo | user | read-only |
|
|
60
|
+
| fo-knowledge-distill | fo | user | document-only |
|
|
61
|
+
| fo-memory-sync | fo | user | content-mutation |
|
|
62
|
+
| fo-qa | fo | user | document-only |
|
|
63
|
+
| fo-review | fo | user | read-only |
|
|
64
|
+
| fo-session-retro | fo | user | document-only |
|
|
65
|
+
| fo-session-save | fo | user | document-only |
|
|
66
|
+
| fo-spec-ingest | fo | user | document-only |
|
|
67
|
+
| fo-step-commit | fo | model | code-mutation |
|
|
68
|
+
| fo-triage | fo | user | document-only |
|
|
69
|
+
| forge-bootstrap | meta | user | content-mutation |
|
|
70
|
+
| grilling | shared | user | read-only |
|
|
71
|
+
| my-preferences | shared | user | document-only |
|
|
72
|
+
| port-to-forge | meta | user | code-mutation |
|
|
73
|
+
| skill-create | meta | user | document-only |
|
|
74
|
+
| windows-ai-tooling | shared | user | code-mutation |
|
|
75
|
+
| writing-great-skills | shared | user | read-only |
|
|
76
76
|
|
|
77
77
|
## Capabilities
|
|
78
78
|
|
|
79
79
|
Bindings resolved from `forge.yaml`:
|
|
80
80
|
|
|
81
|
-
| Key
|
|
82
|
-
|
|
|
83
|
-
| commands.validateRfc
|
|
84
|
-
| commands.validateAdr
|
|
85
|
-
| commands.typecheck
|
|
86
|
-
| commands.test
|
|
87
|
-
| commands.scopedBuild
|
|
81
|
+
| Key | Status | Value |
|
|
82
|
+
| --------------------- | -------- | ------------------------------- |
|
|
83
|
+
| commands.validateRfc | resolved | `pnpm exec forge rfc.validate` |
|
|
84
|
+
| commands.validateAdr | resolved | `pnpm exec forge adr.validate` |
|
|
85
|
+
| commands.typecheck | absent | — |
|
|
86
|
+
| commands.test | absent | — |
|
|
87
|
+
| commands.scopedBuild | absent | — |
|
|
88
88
|
| commands.specValidate | resolved | `pnpm exec forge spec.validate` |
|
|
89
|
-
| commands.sessionSave
|
|
90
|
-
| paths.invariantsFile
|
|
91
|
-
| paths.reviewsDir
|
|
92
|
-
| paths.handoffsDir
|
|
93
|
-
| paths.sessionsDir
|
|
94
|
-
| paths.compassDocs
|
|
89
|
+
| commands.sessionSave | resolved | `pnpm exec forge session.save` |
|
|
90
|
+
| paths.invariantsFile | resolved | `docs/architecture-dna.md` |
|
|
91
|
+
| paths.reviewsDir | resolved | `docs/reviews` |
|
|
92
|
+
| paths.handoffsDir | resolved | `docs/handoffs` |
|
|
93
|
+
| paths.sessionsDir | resolved | `docs/sessions` |
|
|
94
|
+
| paths.compassDocs | resolved | `docs/requirements.xml` |
|
|
95
95
|
|
|
96
96
|
<!-- forge:begin behavioral-layer -->
|
|
97
97
|
|
|
98
98
|
## Behavioral layer
|
|
99
99
|
|
|
100
|
-
This section defines the agent's core behavioral contract. It is generated from skill `
|
|
100
|
+
This section defines the agent's core behavioral contract. It is generated from skill `triggerPhrases` and fixed policy text. The agent MUST follow these behaviors in every session.
|
|
101
101
|
|
|
102
102
|
### Intent-to-skill routing
|
|
103
103
|
|
|
104
|
-
When the operator expresses an intent in natural language, the agent routes to the matching skill. The routing table is generated from `
|
|
104
|
+
When the operator expresses an intent in natural language, the agent routes to the matching skill. The routing table is generated from `triggerPhrases` fields in skill frontmatter.
|
|
105
105
|
|
|
106
106
|
| Operator says something like | Skill |
|
|
107
|
-
|
|
|
107
|
+
| ---------------------------- | ----- |
|
|
108
108
|
|
|
109
109
|
The agent uses judgment to calibrate routing — minor edits (typo fixes, small CSS changes) do not require skill invocation, while significant changes (new features, architectural decisions) do.
|
|
110
110
|
|