@warpgogol/forge 5.2.4 → 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 +32 -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 +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 +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 +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 +60 -31
- 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 -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 +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.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/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 +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 +74 -33
- 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 +6 -4
- 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 +54 -54
- 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
|
@@ -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
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Unit tests for alignMarkdownTable + parseMarkdownTable (RFC-1154):
|
|
4
|
+
prettier-normal emission, separator dash-padding, escaped-pipe literals,
|
|
5
|
+
idempotency, and a regression guard over forge emission surfaces.</purpose>
|
|
6
|
+
</MODULE_CONTRACT>
|
|
7
|
+
<CHANGE_SUMMARY>
|
|
8
|
+
<item>RFC-1154: initial table-emitter tests + compact-separator regression guard.</item>
|
|
9
|
+
</CHANGE_SUMMARY>
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { test, expect } from "vitest";
|
|
13
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { alignMarkdownTable, parseMarkdownTable } from "../utils/markdown-table.ts";
|
|
16
|
+
|
|
17
|
+
test("aligns cells and pads separator with dashes to column width", () => {
|
|
18
|
+
const out = alignMarkdownTable(
|
|
19
|
+
["Name", "Value"],
|
|
20
|
+
[
|
|
21
|
+
["long-name-here", "x"],
|
|
22
|
+
["a", "b"],
|
|
23
|
+
],
|
|
24
|
+
);
|
|
25
|
+
expect(out).toBe(
|
|
26
|
+
[
|
|
27
|
+
"| Name | Value |",
|
|
28
|
+
"| -------------- | ----- |",
|
|
29
|
+
"| long-name-here | x |",
|
|
30
|
+
"| a | b |",
|
|
31
|
+
].join("\n"),
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("minimum column width is 3 even for short cells", () => {
|
|
36
|
+
const out = alignMarkdownTable(["a", "b"], [["1", "2"]]);
|
|
37
|
+
expect(out).toBe("| a | b |\n| --- | --- |\n| 1 | 2 |");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("escaped pipe inside a cell is a literal, not a delimiter", () => {
|
|
41
|
+
const out = alignMarkdownTable(["Pattern", "Meaning"], [["a \\| b", "or"]]);
|
|
42
|
+
const lines = out.split("\n");
|
|
43
|
+
expect(lines[0]).toBe("| Pattern | Meaning |");
|
|
44
|
+
expect(lines[1]).toBe("| ------- | ------- |");
|
|
45
|
+
expect(lines[2]).toBe("| a \\| b | or |");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("rows shorter or longer than headers extend the column set", () => {
|
|
49
|
+
const out = alignMarkdownTable(["A"], [["x", "extra"]]);
|
|
50
|
+
expect(out.split("\n")[0]).toBe("| A | |");
|
|
51
|
+
expect(out.split("\n")[2]).toBe("| x | extra |");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("empty input emits empty string", () => {
|
|
55
|
+
expect(alignMarkdownTable([], [])).toBe("");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("AC-5: re-aligning emitted output is byte-identical", () => {
|
|
59
|
+
const once = alignMarkdownTable(
|
|
60
|
+
["Name", "Category", "Concerns"],
|
|
61
|
+
[
|
|
62
|
+
["fo-idea", "fo", "classification"],
|
|
63
|
+
["wg-mission", "wg", "lifecycle"],
|
|
64
|
+
],
|
|
65
|
+
);
|
|
66
|
+
const parsed = parseMarkdownTable(once);
|
|
67
|
+
expect(parsed).not.toBeNull();
|
|
68
|
+
const twice = alignMarkdownTable(parsed!.headers, parsed!.rows);
|
|
69
|
+
expect(twice, "align(parse(emit)) must be byte-stable — check separator width math").toBe(once);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("parseMarkdownTable returns null for non-table input", () => {
|
|
73
|
+
expect(parseMarkdownTable("just prose\nno table here")).toBeNull();
|
|
74
|
+
expect(parseMarkdownTable("| a |\nno separator")).toBeNull();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("parseMarkdownTable splits on unescaped pipes only", () => {
|
|
78
|
+
const parsed = parseMarkdownTable("| a \\| b | c |\n| --- | --- |\n| 1 | 2 |");
|
|
79
|
+
expect(parsed).not.toBeNull();
|
|
80
|
+
expect(parsed!.headers).toEqual(["a \\| b", "c"]);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("regression guard: no forge emitter emits a compact '| --- |' separator", () => {
|
|
84
|
+
const srcDir = join(import.meta.dirname, "..");
|
|
85
|
+
const offenders: string[] = [];
|
|
86
|
+
const walk = (dir: string) => {
|
|
87
|
+
for (const entry of readdirSync(dir)) {
|
|
88
|
+
const full = join(dir, entry);
|
|
89
|
+
if (statSync(full).isDirectory()) {
|
|
90
|
+
if (entry === "tests" || entry === "__tests__") continue;
|
|
91
|
+
walk(full);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (!entry.endsWith(".ts")) continue;
|
|
95
|
+
const content = readFileSync(full, "utf8");
|
|
96
|
+
// Flag compact separator literals — all tables must route through
|
|
97
|
+
// alignMarkdownTable. The aligner itself lives in utils/markdown-table.ts.
|
|
98
|
+
if (full.endsWith("markdown-table.ts")) continue;
|
|
99
|
+
if (/\| -{2,} \|/.test(content)) offenders.push(full);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
walk(srcDir);
|
|
103
|
+
expect(
|
|
104
|
+
offenders,
|
|
105
|
+
"compact '| --- |' table literals found — route through alignMarkdownTable",
|
|
106
|
+
).toEqual([]);
|
|
107
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Unit tests for the RFC-1154 managed .prettierignore block:
|
|
4
|
+
root-only prettier detection, delimited-block reconcile preserving operator
|
|
5
|
+
content, marker-driven skill entries, and the skipped contract for
|
|
6
|
+
prettier-free consumers.</purpose>
|
|
7
|
+
</MODULE_CONTRACT>
|
|
8
|
+
<CHANGE_SUMMARY>
|
|
9
|
+
<item>RFC-1154: initial prettierignore plan/apply tests.</item>
|
|
10
|
+
</CHANGE_SUMMARY>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { test, expect, beforeEach, afterEach } from "vitest";
|
|
14
|
+
import { mkdtemp, rm, writeFile, mkdir, readFile } from "node:fs/promises";
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import {
|
|
19
|
+
planPrettierignore,
|
|
20
|
+
applyPrettierignore,
|
|
21
|
+
reconcilePrettierignoreContent,
|
|
22
|
+
PRETTIERIGNORE_BLOCK_BEGIN,
|
|
23
|
+
PRETTIERIGNORE_BLOCK_END,
|
|
24
|
+
} from "../onboarding/prettierignore.ts";
|
|
25
|
+
import { SKILL_MARKER_FILE } from "../onboarding/skill-markers.ts";
|
|
26
|
+
|
|
27
|
+
let tmpDir: string;
|
|
28
|
+
|
|
29
|
+
beforeEach(async () => {
|
|
30
|
+
tmpDir = await mkdtemp(join(tmpdir(), "prettierignore-"));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(async () => {
|
|
34
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
async function withPrettier(root: string): Promise<void> {
|
|
38
|
+
await writeFile(join(root, ".prettierrc"), "{}\n");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
test("detects prettier via root .prettierrc", async () => {
|
|
42
|
+
await withPrettier(tmpDir);
|
|
43
|
+
const plan = await planPrettierignore(tmpDir);
|
|
44
|
+
expect(plan.applies).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("detects prettier via package.json prettier key", async () => {
|
|
48
|
+
await writeFile(join(tmpDir, "package.json"), JSON.stringify({ prettier: {} }));
|
|
49
|
+
const plan = await planPrettierignore(tmpDir);
|
|
50
|
+
expect(plan.applies).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("detects prettier via prettier devDependency", async () => {
|
|
54
|
+
await writeFile(
|
|
55
|
+
join(tmpDir, "package.json"),
|
|
56
|
+
JSON.stringify({ devDependencies: { prettier: "^3" } }),
|
|
57
|
+
);
|
|
58
|
+
const plan = await planPrettierignore(tmpDir);
|
|
59
|
+
expect(plan.applies).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("detects prettier via existing .prettierignore alone", async () => {
|
|
63
|
+
await writeFile(join(tmpDir, ".prettierignore"), "dist/\n");
|
|
64
|
+
const plan = await planPrettierignore(tmpDir);
|
|
65
|
+
expect(plan.applies).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("AC-4: no prettier markers — plan does not apply, apply writes nothing", async () => {
|
|
69
|
+
const plan = await planPrettierignore(tmpDir);
|
|
70
|
+
expect(plan.applies).toBe(false);
|
|
71
|
+
const result = await applyPrettierignore(tmpDir, plan);
|
|
72
|
+
expect(result).toBe("skipped");
|
|
73
|
+
expect(existsSync(join(tmpDir, ".prettierignore"))).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("AC-2: block contains generated.yaml glob, sessions, metrics, queues entries", async () => {
|
|
77
|
+
await withPrettier(tmpDir);
|
|
78
|
+
const plan = await planPrettierignore(tmpDir);
|
|
79
|
+
const result = await applyPrettierignore(tmpDir, plan);
|
|
80
|
+
expect(result).toBe("written");
|
|
81
|
+
const content = await readFile(join(tmpDir, ".prettierignore"), "utf8");
|
|
82
|
+
expect(content).toContain(PRETTIERIGNORE_BLOCK_BEGIN);
|
|
83
|
+
expect(content).toContain("**/*.generated.yaml");
|
|
84
|
+
expect(content).toContain("docs/sessions/");
|
|
85
|
+
expect(content).toContain("docs/metrics/");
|
|
86
|
+
expect(content).toContain("docs/queues/session-*.yaml");
|
|
87
|
+
expect(content).toContain(PRETTIERIGNORE_BLOCK_END);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("skill entries enumerate only marker-carrying dirs (AC-9)", async () => {
|
|
91
|
+
await withPrettier(tmpDir);
|
|
92
|
+
const skillsDir = join(tmpDir, ".agents", "skills");
|
|
93
|
+
await mkdir(join(skillsDir, "fo-idea"), { recursive: true });
|
|
94
|
+
await writeFile(join(skillsDir, "fo-idea", SKILL_MARKER_FILE), '{"files":["SKILL.md"]}');
|
|
95
|
+
await mkdir(join(skillsDir, "my-own-skill"), { recursive: true }); // unmarked — consumer-owned
|
|
96
|
+
|
|
97
|
+
const plan = await planPrettierignore(tmpDir);
|
|
98
|
+
expect(plan.entries).toContain(".agents/skills/fo-idea/");
|
|
99
|
+
expect(plan.entries).not.toContain(".agents/skills/my-own-skill/");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("reconcile preserves operator content outside the block", async () => {
|
|
103
|
+
const existing = `dist/\nnode_modules/\n${PRETTIERIGNORE_BLOCK_BEGIN}\nold-entry/\n${PRETTIERIGNORE_BLOCK_END}\ncustom/\n`;
|
|
104
|
+
const { next, changed } = reconcilePrettierignoreContent(existing, ["a/", "b/"]);
|
|
105
|
+
expect(changed).toBe("updated");
|
|
106
|
+
expect(next).toContain("dist/\nnode_modules/\n");
|
|
107
|
+
expect(next).toContain("custom/\n");
|
|
108
|
+
expect(next).not.toContain("old-entry/");
|
|
109
|
+
expect(next).toContain("a/\nb/");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("unbalanced markers treat the file as operator-owned and append a fresh block", async () => {
|
|
113
|
+
const existing = `dist/\n${PRETTIERIGNORE_BLOCK_BEGIN}\nstray/\n`; // no END marker
|
|
114
|
+
const { next, changed } = reconcilePrettierignoreContent(existing, ["x/"]);
|
|
115
|
+
expect(changed).toBe("updated");
|
|
116
|
+
expect(next).toContain("dist/\n");
|
|
117
|
+
// Original content preserved verbatim — forge does not merge into a
|
|
118
|
+
// corrupted region; a fresh block is appended.
|
|
119
|
+
expect(next.indexOf(PRETTIERIGNORE_BLOCK_BEGIN)).toBeLessThan(
|
|
120
|
+
next.lastIndexOf(PRETTIERIGNORE_BLOCK_BEGIN),
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("repeated apply is idempotent", async () => {
|
|
125
|
+
await withPrettier(tmpDir);
|
|
126
|
+
await writeFile(join(tmpDir, ".prettierignore"), "dist/\n");
|
|
127
|
+
const plan = await planPrettierignore(tmpDir);
|
|
128
|
+
const first = await applyPrettierignore(tmpDir, plan);
|
|
129
|
+
expect(first).toBe("updated");
|
|
130
|
+
const second = await applyPrettierignore(tmpDir, await planPrettierignore(tmpDir));
|
|
131
|
+
expect(second, "second apply must be unchanged — check reconcile block boundaries").toBe(
|
|
132
|
+
"unchanged",
|
|
133
|
+
);
|
|
134
|
+
});
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>CI gate: every forge/pack skill source must be fully propagated to
|
|
4
|
+
`.agents/skills/` (IDE discovery copy written by forge.init/forge.upgrade).
|
|
5
|
+
SKILL.md syncs verbatim; declared knowledge files follow the append-only
|
|
6
|
+
syncKnowledgeFile contract — in the canonical repo a resync must be a no-op,
|
|
7
|
+
otherwise source and copy have drifted apart.</purpose>
|
|
8
|
+
<non-goals>
|
|
9
|
+
<item>Do not validate skill content/schema — forge.skill.validate owns that.</item>
|
|
10
|
+
<item>Do not flag unmarked dirs — a missing .forge-managed marker means
|
|
11
|
+
consumer-owned (RFC-1154), e.g. `_shared/`.</item>
|
|
12
|
+
</non-goals>
|
|
13
|
+
<KEY_DECISIONS>
|
|
14
|
+
<item>planKnowledgeSync is reused so the gate encodes the exact merge
|
|
15
|
+
semantics of the syncer — only "unchanged" is a pass; "merged" (source has
|
|
16
|
+
entries the copy lacks), "copied" (copy missing), and "skipped"
|
|
17
|
+
(non-mergeable divergence = hand-edited copy) all fail.</item>
|
|
18
|
+
<item>Runs on the real repo — this is a drift gate, not a fixture test.</item>
|
|
19
|
+
</KEY_DECISIONS>
|
|
20
|
+
<CHANGE_SUMMARY>
|
|
21
|
+
<item>Initial version — covers FORGE_SKILLS, declared pack skills
|
|
22
|
+
(discoverPackSkills), and the shared-knowledge layer.</item>
|
|
23
|
+
</CHANGE_SUMMARY>
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import fs from "node:fs";
|
|
27
|
+
import path from "node:path";
|
|
28
|
+
import { describe, expect, it } from "vitest";
|
|
29
|
+
|
|
30
|
+
import { loadForgeConfig } from "../config/forge-config.ts";
|
|
31
|
+
import { planKnowledgeSync } from "../knowledge/index.ts";
|
|
32
|
+
import { FORGE_SKILLS, discoverPackSkills } from "../registry.ts";
|
|
33
|
+
|
|
34
|
+
const forgeRoot = path.resolve(import.meta.dirname, "../..");
|
|
35
|
+
const workspaceRoot = path.resolve(import.meta.dirname, "../../../..");
|
|
36
|
+
|
|
37
|
+
interface SkillSource {
|
|
38
|
+
name: string;
|
|
39
|
+
srcDir: string;
|
|
40
|
+
knowledge: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function collectSkillSources(): SkillSource[] {
|
|
44
|
+
const sources: SkillSource[] = [];
|
|
45
|
+
for (const skill of FORGE_SKILLS) {
|
|
46
|
+
sources.push({
|
|
47
|
+
name: skill.name,
|
|
48
|
+
srcDir: path.dirname(path.join(forgeRoot, skill.path)),
|
|
49
|
+
knowledge: skill.knowledge ?? [],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const config = loadForgeConfig(workspaceRoot);
|
|
53
|
+
for (const skill of discoverPackSkills(workspaceRoot, config)) {
|
|
54
|
+
sources.push({
|
|
55
|
+
name: skill.name,
|
|
56
|
+
srcDir: path.dirname(path.join(workspaceRoot, skill.dir, skill.path)),
|
|
57
|
+
knowledge: skill.knowledge ?? [],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return sources;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Skipped in the standalone package repo — the gate needs a forge-managed
|
|
64
|
+
// workspace root (forge.yaml + synced skillsDir), which only exists for the
|
|
65
|
+
// monorepo and consumer projects, not for the published forge source tree.
|
|
66
|
+
const hasForgeWorkspace = fs.existsSync(path.join(workspaceRoot, "forge.yaml"));
|
|
67
|
+
describe.runIf(hasForgeWorkspace)(
|
|
68
|
+
".agents/skills sync gate (forge.init/forge.upgrade parity)",
|
|
69
|
+
() => {
|
|
70
|
+
// describe callbacks still run during collection even when runIf is false,
|
|
71
|
+
// so initializers must tolerate the absent forge.yaml themselves.
|
|
72
|
+
const config = hasForgeWorkspace ? loadForgeConfig(workspaceRoot) : null;
|
|
73
|
+
const skillsDir = config ? path.join(workspaceRoot, config.paths.skillsDir) : "";
|
|
74
|
+
const sources = config ? collectSkillSources() : [];
|
|
75
|
+
|
|
76
|
+
it("every forge + pack skill has a synced copy in .agents/skills/", () => {
|
|
77
|
+
const missing = sources
|
|
78
|
+
.filter((s) => !fs.existsSync(path.join(skillsDir, s.name, "SKILL.md")))
|
|
79
|
+
.map((s) => `${s.name} (src ${path.relative(workspaceRoot, s.srcDir)})`);
|
|
80
|
+
expect(
|
|
81
|
+
missing,
|
|
82
|
+
`skills never synced — run \`forge init\`/\`forge upgrade\` to populate ${path.relative(workspaceRoot, skillsDir)}`,
|
|
83
|
+
).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("SKILL.md copies are byte-identical to their sources", () => {
|
|
87
|
+
const drifted: string[] = [];
|
|
88
|
+
for (const s of sources) {
|
|
89
|
+
const src = path.join(s.srcDir, "SKILL.md");
|
|
90
|
+
const dest = path.join(skillsDir, s.name, "SKILL.md");
|
|
91
|
+
if (!fs.existsSync(dest)) continue; // reported by the presence test
|
|
92
|
+
if (fs.readFileSync(src, "utf8") !== fs.readFileSync(dest, "utf8")) {
|
|
93
|
+
drifted.push(s.name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
expect(
|
|
97
|
+
drifted,
|
|
98
|
+
"SKILL.md drift — edit the pack source and re-sync, never edit .agents/skills/ directly",
|
|
99
|
+
).toEqual([]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("declared knowledge files are in sync (append-only merge would be a no-op)", () => {
|
|
103
|
+
const stale: string[] = [];
|
|
104
|
+
for (const s of sources) {
|
|
105
|
+
for (const kf of s.knowledge) {
|
|
106
|
+
const src = path.join(s.srcDir, kf);
|
|
107
|
+
const dest = path.join(skillsDir, s.name, kf);
|
|
108
|
+
if (!fs.existsSync(src)) {
|
|
109
|
+
stale.push(`${s.name}/${kf} — declared but missing in source`);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (!fs.existsSync(dest)) {
|
|
113
|
+
stale.push(`${s.name}/${kf} — missing in .agents/skills (run forge upgrade)`);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const plan = planKnowledgeSync(src, dest);
|
|
117
|
+
if (plan.action === "merged") {
|
|
118
|
+
stale.push(`${s.name}/${kf} — source has entries the copy lacks`);
|
|
119
|
+
} else if (plan.action === "skipped") {
|
|
120
|
+
stale.push(`${s.name}/${kf} — copy diverged non-mergeably (hand-edited .agents copy)`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
expect(stale).toEqual([]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("undeclared aux files in the copy still match their sources", () => {
|
|
128
|
+
// The syncer writes SKILL.md + declared knowledge files only. Aux files
|
|
129
|
+
// (references, templates, placeholder dirs) that exist in BOTH trees are
|
|
130
|
+
// hand-copied and silently diverge — a same-named pair must stay identical,
|
|
131
|
+
// and a copy-only orphan can never resync.
|
|
132
|
+
const flagged: string[] = [];
|
|
133
|
+
for (const s of sources) {
|
|
134
|
+
const destDir = path.join(skillsDir, s.name);
|
|
135
|
+
if (!fs.existsSync(destDir)) continue;
|
|
136
|
+
const declared = new Set(["SKILL.md", ".forge-managed", ...s.knowledge]);
|
|
137
|
+
for (const entry of fs.readdirSync(destDir)) {
|
|
138
|
+
if (declared.has(entry)) continue;
|
|
139
|
+
const srcEntry = path.join(s.srcDir, entry);
|
|
140
|
+
const destEntry = path.join(destDir, entry);
|
|
141
|
+
if (fs.statSync(destEntry).isDirectory()) {
|
|
142
|
+
if (!fs.existsSync(srcEntry))
|
|
143
|
+
flagged.push(`${s.name}/${entry}/ — dir absent in source`);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (!fs.existsSync(srcEntry)) {
|
|
147
|
+
flagged.push(`${s.name}/${entry} — absent in source, copy can never resync`);
|
|
148
|
+
} else if (fs.readFileSync(srcEntry, "utf8") !== fs.readFileSync(destEntry, "utf8")) {
|
|
149
|
+
flagged.push(`${s.name}/${entry} — diverged from source`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
expect(
|
|
154
|
+
flagged,
|
|
155
|
+
"aux-file drift — declare aux files via `knowledge:` in SKILL.md or keep copies identical to source",
|
|
156
|
+
).toEqual([]);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("shared-knowledge layer is synced", () => {
|
|
160
|
+
const src = path.join(forgeRoot, "skills", "shared", "knowledge", "learned-principles.md");
|
|
161
|
+
const dest = path.join(skillsDir, "shared-knowledge", "learned-principles.md");
|
|
162
|
+
if (!fs.existsSync(src)) return; // layer absent — nothing to gate
|
|
163
|
+
expect(fs.existsSync(dest), "shared-knowledge/learned-principles.md not synced").toBe(true);
|
|
164
|
+
const plan = planKnowledgeSync(src, dest);
|
|
165
|
+
expect(plan.action, `shared-knowledge drift (sync action: ${plan.action})`).toBe("unchanged");
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
);
|