@event4u/agent-config 10.4.0 → 12.0.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +73 -182
- package/dist/agent-src/commands/agent-handoff.md +0 -1
- package/dist/agent-src/commands/agent-status.md +0 -1
- package/dist/agent-src/commands/agents/audit.md +0 -1
- package/dist/agent-src/commands/agents/init.md +0 -1
- package/dist/agent-src/commands/agents/optimize.md +0 -1
- package/dist/agent-src/commands/agents/user/accept.md +0 -1
- package/dist/agent-src/commands/agents/user/delete.md +0 -1
- package/dist/agent-src/commands/agents/user/init.md +0 -1
- package/dist/agent-src/commands/agents/user/review.md +0 -1
- package/dist/agent-src/commands/agents/user/show.md +0 -1
- package/dist/agent-src/commands/agents/user/update.md +0 -1
- package/dist/agent-src/commands/agents/user.md +0 -1
- package/dist/agent-src/commands/agents.md +0 -1
- package/dist/agent-src/commands/analytics/prune.md +0 -1
- package/dist/agent-src/commands/analytics/show.md +0 -1
- package/dist/agent-src/commands/analytics.md +0 -1
- package/dist/agent-src/commands/analyze/conformance.md +0 -1
- package/dist/agent-src/commands/analyze/decision.md +0 -1
- package/dist/agent-src/commands/analyze/inbox.md +0 -1
- package/dist/agent-src/commands/analyze/incident.md +0 -1
- package/dist/agent-src/commands/analyze/near-miss.md +0 -1
- package/dist/agent-src/commands/analyze/postmortem.md +0 -1
- package/dist/agent-src/commands/analyze/premortem.md +0 -1
- package/dist/agent-src/commands/analyze/reference-repo.md +0 -1
- package/dist/agent-src/commands/analyze.md +0 -1
- package/dist/agent-src/commands/brand/identity.md +0 -1
- package/dist/agent-src/commands/brand/review.md +0 -1
- package/dist/agent-src/commands/brand/strategy.md +0 -1
- package/dist/agent-src/commands/brand/tokens.md +0 -1
- package/dist/agent-src/commands/brand/voice.md +0 -1
- package/dist/agent-src/commands/brand.md +0 -1
- package/dist/agent-src/commands/bug/fix.md +0 -1
- package/dist/agent-src/commands/bug/investigate.md +0 -1
- package/dist/agent-src/commands/bug.md +0 -1
- package/dist/agent-src/commands/challenge-me/vision.md +0 -1
- package/dist/agent-src/commands/challenge-me/with-docs.md +0 -1
- package/dist/agent-src/commands/challenge-me.md +0 -1
- package/dist/agent-src/commands/chat-history/import.md +0 -1
- package/dist/agent-src/commands/chat-history.md +0 -1
- package/dist/agent-src/commands/check-current-md.md +0 -1
- package/dist/agent-src/commands/commit/in-chunks.md +0 -1
- package/dist/agent-src/commands/commit.md +0 -1
- package/dist/agent-src/commands/condense.md +0 -1
- package/dist/agent-src/commands/context/create.md +0 -1
- package/dist/agent-src/commands/context/refactor.md +0 -1
- package/dist/agent-src/commands/context.md +0 -1
- package/dist/agent-src/commands/contribution-precheck.md +0 -1
- package/dist/agent-src/commands/cost/profile.md +0 -1
- package/dist/agent-src/commands/cost/report.md +0 -1
- package/dist/agent-src/commands/cost.md +0 -1
- package/dist/agent-src/commands/council/analysis.md +0 -1
- package/dist/agent-src/commands/council/debate.md +13 -5
- package/dist/agent-src/commands/council/default.md +26 -12
- package/dist/agent-src/commands/council/design.md +0 -1
- package/dist/agent-src/commands/council/optimize.md +0 -1
- package/dist/agent-src/commands/council/pr.md +0 -1
- package/dist/agent-src/commands/council.md +1 -2
- package/dist/agent-src/commands/design-system/capture.md +0 -1
- package/dist/agent-src/commands/design-system/generate.md +23 -2
- package/dist/agent-src/commands/design-system/import.md +0 -1
- package/dist/agent-src/commands/design-system.md +0 -1
- package/dist/agent-src/commands/estimate-ticket.md +0 -1
- package/dist/agent-src/commands/explain-run.md +0 -1
- package/dist/agent-src/commands/feature/dev.md +0 -1
- package/dist/agent-src/commands/feature/explore.md +0 -1
- package/dist/agent-src/commands/feature/plan.md +0 -1
- package/dist/agent-src/commands/feature/refactor.md +0 -1
- package/dist/agent-src/commands/feature/roadmap.md +0 -1
- package/dist/agent-src/commands/feature.md +0 -1
- package/dist/agent-src/commands/fix/ci.md +0 -1
- package/dist/agent-src/commands/fix/comments.md +0 -1
- package/dist/agent-src/commands/fix/portability.md +0 -1
- package/dist/agent-src/commands/fix/pr-comments-loop.md +0 -1
- package/dist/agent-src/commands/fix/pr-comments.md +0 -1
- package/dist/agent-src/commands/fix/quality.md +0 -1
- package/dist/agent-src/commands/fix/refs.md +0 -1
- package/dist/agent-src/commands/fix/route.md +0 -1
- package/dist/agent-src/commands/fix/seeder.md +0 -1
- package/dist/agent-src/commands/fix.md +0 -1
- package/dist/agent-src/commands/ghostwriter/delete.md +0 -1
- package/dist/agent-src/commands/ghostwriter/fetch.md +0 -1
- package/dist/agent-src/commands/ghostwriter/list.md +0 -1
- package/dist/agent-src/commands/ghostwriter/show.md +0 -1
- package/dist/agent-src/commands/ghostwriter/write.md +0 -1
- package/dist/agent-src/commands/ghostwriter.md +0 -1
- package/dist/agent-src/commands/grill-me.md +0 -1
- package/dist/agent-src/commands/humanize.md +0 -1
- package/dist/agent-src/commands/image/analyse.md +0 -1
- package/dist/agent-src/commands/image/create.md +0 -1
- package/dist/agent-src/commands/image/verify.md +0 -1
- package/dist/agent-src/commands/image.md +0 -1
- package/dist/agent-src/commands/implement-ticket.md +0 -1
- package/dist/agent-src/commands/jira-ticket.md +0 -1
- package/dist/agent-src/commands/judge/on-diff.md +0 -1
- package/dist/agent-src/commands/judge/solo.md +0 -1
- package/dist/agent-src/commands/judge/steps.md +0 -1
- package/dist/agent-src/commands/judge.md +0 -1
- package/dist/agent-src/commands/knowledge/cross-repo.md +0 -1
- package/dist/agent-src/commands/knowledge/forget.md +0 -1
- package/dist/agent-src/commands/knowledge/ingest.md +0 -1
- package/dist/agent-src/commands/knowledge/list.md +0 -1
- package/dist/agent-src/commands/knowledge.md +0 -1
- package/dist/agent-src/commands/memory/add.md +0 -1
- package/dist/agent-src/commands/memory/learn-low-impact.md +0 -1
- package/dist/agent-src/commands/memory/load.md +0 -1
- package/dist/agent-src/commands/memory/mine-session.md +0 -1
- package/dist/agent-src/commands/memory/promote.md +0 -1
- package/dist/agent-src/commands/memory/propose.md +0 -1
- package/dist/agent-src/commands/memory.md +0 -1
- package/dist/agent-src/commands/mission/upgrade.md +0 -1
- package/dist/agent-src/commands/mode.md +0 -1
- package/dist/agent-src/commands/module/create.md +0 -1
- package/dist/agent-src/commands/module/explore.md +0 -1
- package/dist/agent-src/commands/module.md +0 -1
- package/dist/agent-src/commands/optimize/agents-dir.md +0 -1
- package/dist/agent-src/commands/optimize/augmentignore.md +0 -1
- package/dist/agent-src/commands/optimize/deep.md +0 -1
- package/dist/agent-src/commands/optimize/project.md +0 -1
- package/dist/agent-src/commands/optimize/prompt.md +0 -1
- package/dist/agent-src/commands/optimize/rtk.md +0 -1
- package/dist/agent-src/commands/optimize/skills.md +0 -1
- package/dist/agent-src/commands/optimize.md +0 -1
- package/dist/agent-src/commands/orchestrate.md +0 -1
- package/dist/agent-src/commands/override/create.md +0 -1
- package/dist/agent-src/commands/override/manage.md +0 -1
- package/dist/agent-src/commands/override.md +0 -1
- package/dist/agent-src/commands/package/reset.md +0 -1
- package/dist/agent-src/commands/package/test.md +0 -1
- package/dist/agent-src/commands/package.md +0 -1
- package/dist/agent-src/commands/post-as/ghostwriter.md +0 -1
- package/dist/agent-src/commands/post-as/me.md +0 -1
- package/dist/agent-src/commands/post-as.md +0 -1
- package/dist/agent-src/commands/pr/create/description-only.md +0 -1
- package/dist/agent-src/commands/pr/create.md +67 -28
- package/dist/agent-src/commands/prediction-pool.md +0 -1
- package/dist/agent-src/commands/prepare-for-review.md +0 -1
- package/dist/agent-src/commands/profile/activate.md +0 -1
- package/dist/agent-src/commands/profile/deactivate.md +0 -1
- package/dist/agent-src/commands/profile/show.md +0 -1
- package/dist/agent-src/commands/profile.md +0 -1
- package/dist/agent-src/commands/project/analyze.md +0 -1
- package/dist/agent-src/commands/project/health.md +0 -1
- package/dist/agent-src/commands/project.md +0 -1
- package/dist/agent-src/commands/refine-ticket.md +0 -1
- package/dist/agent-src/commands/research/deep.md +0 -1
- package/dist/agent-src/commands/research/report.md +0 -1
- package/dist/agent-src/commands/research.md +0 -1
- package/dist/agent-src/commands/review/changes.md +0 -1
- package/dist/agent-src/commands/review/routing.md +0 -1
- package/dist/agent-src/commands/review.md +0 -1
- package/dist/agent-src/commands/roadmap/ai-council.md +0 -1
- package/dist/agent-src/commands/roadmap/create.md +0 -1
- package/dist/agent-src/commands/roadmap/materialize.md +0 -1
- package/dist/agent-src/commands/roadmap/next.md +0 -1
- package/dist/agent-src/commands/roadmap/process-full.md +0 -1
- package/dist/agent-src/commands/roadmap/process-phase.md +0 -1
- package/dist/agent-src/commands/roadmap/process-step.md +0 -1
- package/dist/agent-src/commands/roadmap.md +0 -1
- package/dist/agent-src/commands/rule-compliance-audit.md +0 -1
- package/dist/agent-src/commands/security-audit-config.md +0 -1
- package/dist/agent-src/commands/skill/preview.md +0 -1
- package/dist/agent-src/commands/skill.md +0 -1
- package/dist/agent-src/commands/skills/discover.md +0 -1
- package/dist/agent-src/commands/skills.md +0 -1
- package/dist/agent-src/commands/sync/agent-settings.md +0 -1
- package/dist/agent-src/commands/sync/gitignore/fix.md +0 -1
- package/dist/agent-src/commands/sync/gitignore.md +0 -1
- package/dist/agent-src/commands/sync.md +0 -1
- package/dist/agent-src/commands/tdd/green.md +0 -1
- package/dist/agent-src/commands/tdd/red.md +0 -1
- package/dist/agent-src/commands/tdd/refactor.md +0 -1
- package/dist/agent-src/commands/tdd.md +0 -1
- package/dist/agent-src/commands/team/adversarial.md +0 -1
- package/dist/agent-src/commands/team/delegate.md +0 -1
- package/dist/agent-src/commands/team/review.md +0 -1
- package/dist/agent-src/commands/team/status.md +0 -1
- package/dist/agent-src/commands/team-knowledge/bootstrap.md +0 -1
- package/dist/agent-src/commands/team-knowledge/consolidate.md +0 -1
- package/dist/agent-src/commands/team-knowledge.md +0 -1
- package/dist/agent-src/commands/team.md +0 -1
- package/dist/agent-src/commands/tests/create.md +0 -1
- package/dist/agent-src/commands/tests/e2e-heal.md +0 -1
- package/dist/agent-src/commands/tests/e2e-plan.md +0 -1
- package/dist/agent-src/commands/tests/execute.md +0 -1
- package/dist/agent-src/commands/tests.md +0 -1
- package/dist/agent-src/commands/threat-model.md +0 -1
- package/dist/agent-src/commands/update-form-request-messages.md +0 -1
- package/dist/agent-src/commands/upstream-contribute.md +0 -1
- package/dist/agent-src/commands/video/from-script.md +0 -1
- package/dist/agent-src/commands/video/from-song.md +0 -1
- package/dist/agent-src/commands/video/scene.md +0 -1
- package/dist/agent-src/commands/video/stitch.md +0 -1
- package/dist/agent-src/commands/video/storyboard.md +0 -1
- package/dist/agent-src/commands/video.md +0 -1
- package/dist/agent-src/commands/work.md +0 -1
- package/dist/agent-src/commands/worktree/cleanup.md +0 -1
- package/dist/agent-src/commands/worktree/create.md +5 -4
- package/dist/agent-src/commands/worktree/status.md +0 -1
- package/dist/agent-src/commands/worktree/verify.md +0 -1
- package/dist/agent-src/commands/worktree.md +0 -1
- package/dist/agent-src/rules/settings-ask-protocol.md +14 -9
- package/dist/agent-src/skills/ai-council/SKILL.md +24 -6
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +12 -1
- package/dist/agent-src/skills/corpus-grounding/scripts/decision_engine.ts +215 -7
- package/dist/agent-src/skills/corpus-grounding/scripts/ground.ts +39 -1
- package/dist/agent-src/skills/design-intelligence/ATTRIBUTION.md +19 -2
- package/dist/agent-src/skills/design-intelligence/data/manifest.json +36 -1
- package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -0
- package/dist/agent-src/skills/docx-authoring/SKILL.md +1 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +17 -3
- package/dist/agent-src/skills/pdf-tools/SKILL.md +1 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +35 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +9 -6
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +25 -21
- package/dist/agent-src/templates/agent-settings.md +0 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/commands/commands.candidates.test.js +1 -1
- package/dist/cli/commands/commands.candidates.test.js.map +1 -1
- package/dist/cli/commands/commands.js +9 -15
- package/dist/cli/commands/commands.js.map +1 -1
- package/dist/cli/commands/profiles.test.js +7 -7
- package/dist/cli/commands/profiles.test.js.map +1 -1
- package/dist/cli/discovery/loadManifest.js.map +1 -1
- package/dist/cli/main.js +2 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli-delegate/{chunk-BV3WR67D.js → chunk-55WZN5VF.js} +3 -6
- package/dist/cli-delegate/{chunk-X3VOARZD.js → chunk-L565YFXH.js} +3 -3
- package/dist/cli-delegate/{chunk-JMQZ7MM5.js → chunk-MNWRDMR5.js} +1 -1
- package/dist/cli-delegate/{chunk-IR3IVRVC.js → chunk-NLP54U3J.js} +2 -1
- package/dist/cli-delegate/{chunk-FV34EGEX.js → chunk-NN4KW4HZ.js} +1 -1
- package/dist/cli-delegate/{chunk-6ENSXSBW.js → chunk-PPQO4NGR.js} +1 -1
- package/dist/cli-delegate/{chunk-6LOPHJLD.js → chunk-RYNADUFG.js} +1 -1
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +16 -4
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +1 -1
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +216 -415
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +2 -2
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +3 -3
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +3 -3
- package/dist/hooks/dispatch.js +68 -14
- package/dist/install/install.mjs +5 -7
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +48 -6
- package/dist/scripts/_lib/agent_settings.js +8 -0
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -4
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/ui/assets/{index-5fXOHoVh.js → index-B0aMJnuz.js} +2 -2
- package/dist/ui/assets/{index-5fXOHoVh.js.map → index-B0aMJnuz.js.map} +1 -1
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -0
- package/docs/contracts/settings-classes.md +53 -9
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +49 -18
- package/src/config/gate-coverage.yml +13 -3
- package/src/config/gate-violation-baselines.json +4 -4
- package/src/config/pack-size-budget.json +3 -2
- package/src/scripts/_dispatch.bash +42 -5
- package/src/scripts/_lib/agent_settings.ts +8 -0
- package/src/scripts/audit_command_surface.ts +21 -15
- package/src/scripts/build_catalog_index.ts +1 -1
- package/src/scripts/build_discovery_manifest.ts +30 -34
- package/src/scripts/check_branch_freshness.ts +393 -12
- package/src/scripts/external_sources_denylist.json +7 -2
- package/src/scripts/gen_discovery_baseline.ts +3 -3
- package/src/scripts/hook_manifest.yaml +20 -0
- package/src/scripts/hooks/subagent_ledger_hook.ts +17 -4
- package/src/scripts/lint_command_tiers.ts +29 -75
- package/src/scripts/lint_originality.ts +101 -14
- package/src/scripts/schemas/command.schema.json +4 -9
- package/src/scripts/schemas/skill.schema.json +10 -1
- package/src/scripts/session_register_hook.ts +120 -10
- package/src/scripts/skill_linter.ts +82 -2
- package/src/scripts/worktree_cleanup_check.ts +111 -7
- package/src/server/schemas/settings.ts +3 -6
|
@@ -254,6 +254,42 @@ const EXTERNAL_EXECUTION_HANDLERS = new Set(['shell', 'php', 'node']);
|
|
|
254
254
|
* span lines and accept a bare key whose value sits somewhere below it.
|
|
255
255
|
*/
|
|
256
256
|
const RUNTIME_REQUIRES_BLOCK_PATTERN = /^runtime_requires:[ \t]*(\{.*)?$/m;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The deprecated free-text `compatibility:` key and its structured successor
|
|
260
|
+
* `harness_compat:`, both top-level. Anchored at column 0 so a `compatibility:`
|
|
261
|
+
* nested inside another block (or the word inside a quoted description) is not
|
|
262
|
+
* read as the frontmatter key — the same reason the neighbouring patterns above
|
|
263
|
+
* use `^` rather than a bare substring test. A value is required after the colon
|
|
264
|
+
* so a bare key with the value on the next line is not counted as a declaration.
|
|
265
|
+
*/
|
|
266
|
+
const COMPATIBILITY_KEY_PATTERN = /^compatibility:[ \t]*\S/m;
|
|
267
|
+
const HARNESS_COMPAT_KEY_PATTERN = /^harness_compat:[ \t]*\S/m;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* `safety_mode: strict` is a claim made in the frontmatter about a skill whose
|
|
271
|
+
* execution path may mutate something. Nothing checked that the body honours it,
|
|
272
|
+
* so the claim could be pure metadata. These patterns recognise the two shapes
|
|
273
|
+
* the action-reference split allows (`skill-writing` § Action-reference split):
|
|
274
|
+
* an inline precondition that gates the write, or a deferral of the write-path
|
|
275
|
+
* steps into the skill's own `references/`.
|
|
276
|
+
*
|
|
277
|
+
* Deliberately a warning over a phrase list rather than an error over a required
|
|
278
|
+
* section: a skill that gates its write path some third way is doing the right
|
|
279
|
+
* thing, and a hard gate over a corpus of one strict skill would be a gate that
|
|
280
|
+
* mostly cannot fail — the defect class `road-to-skill-ecosystem-gate-integrity`
|
|
281
|
+
* exists to remove.
|
|
282
|
+
*/
|
|
283
|
+
const STRICT_WRITE_GATE_PATTERNS = [
|
|
284
|
+
/--dry-run/i,
|
|
285
|
+
/\bnever silent[- ]run/i,
|
|
286
|
+
/\bpropose,? never\b/i,
|
|
287
|
+
/\bconfirms? before\b/i,
|
|
288
|
+
/\bexplicit (?:user )?confirmation\b/i,
|
|
289
|
+
/\basks? (?:the user )?(?:first|before)\b/i,
|
|
290
|
+
];
|
|
291
|
+
const SKILL_REFERENCE_DEFERRAL_PATTERN = /\]\(\.{0,2}\/?references\//;
|
|
292
|
+
|
|
257
293
|
const VALID_EXECUTION_FIELDS = new Set([
|
|
258
294
|
'type',
|
|
259
295
|
'handler',
|
|
@@ -1295,7 +1331,7 @@ function lint_wing4_boundaries(text: string): Issue[] {
|
|
|
1295
1331
|
* for an optional parameter — a future caller that forgets it gets a confident
|
|
1296
1332
|
* error about a declaration it never looked for.
|
|
1297
1333
|
*/
|
|
1298
|
-
function lint_execution_metadata(execution: ExecutionBlock, frontmatter: string): Issue[] {
|
|
1334
|
+
function lint_execution_metadata(execution: ExecutionBlock, frontmatter: string, body = ''): Issue[] {
|
|
1299
1335
|
const issues: Issue[] = [];
|
|
1300
1336
|
|
|
1301
1337
|
const execType = execution.type;
|
|
@@ -1370,6 +1406,29 @@ function lint_execution_metadata(execution: ExecutionBlock, frontmatter: string)
|
|
|
1370
1406
|
);
|
|
1371
1407
|
}
|
|
1372
1408
|
|
|
1409
|
+
// road-to-skill-ecosystem-executable-payloads Phase 5 — the action-reference
|
|
1410
|
+
// split. A strict-mode skill either gates its write path inline, or says it
|
|
1411
|
+
// does not define the mutating workflow and defers those steps to its own
|
|
1412
|
+
// `references/` behind a precondition. Neither present → the strict claim is
|
|
1413
|
+
// frontmatter only, and the body reads like an ordinary skill.
|
|
1414
|
+
if (
|
|
1415
|
+
safetyMode === 'strict' &&
|
|
1416
|
+
body !== '' &&
|
|
1417
|
+
!STRICT_WRITE_GATE_PATTERNS.some((p) => p.test(body)) &&
|
|
1418
|
+
!SKILL_REFERENCE_DEFERRAL_PATTERN.test(body)
|
|
1419
|
+
) {
|
|
1420
|
+
issues.push(
|
|
1421
|
+
new Issue(
|
|
1422
|
+
'warning',
|
|
1423
|
+
'strict_mode_missing_write_gate',
|
|
1424
|
+
"execution.safety_mode is 'strict' but the body names no precondition on the write " +
|
|
1425
|
+
'path and defers no write-path steps to the skill\'s references/ — state the gate ' +
|
|
1426
|
+
'inline (propose-then-confirm, --dry-run) or defer it, per skill-writing ' +
|
|
1427
|
+
'§ Action-reference split',
|
|
1428
|
+
),
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1373
1432
|
const timeout = execution.timeout_seconds;
|
|
1374
1433
|
if (timeout !== undefined) {
|
|
1375
1434
|
if (typeof timeout !== 'number' || !Number.isInteger(timeout) || timeout <= 0) {
|
|
@@ -1583,9 +1642,30 @@ export function lint_skill(p: string, text: string, absPath: string | null = nul
|
|
|
1583
1642
|
}
|
|
1584
1643
|
}
|
|
1585
1644
|
|
|
1645
|
+
// `compatibility:` is deprecated in favour of the structured
|
|
1646
|
+
// `harness_compat:` (schema, 2026-08-14). The field is NOT removed — the
|
|
1647
|
+
// schema still accepts it and both existing users still carry it — so this
|
|
1648
|
+
// is a warning, not an error: its job is to stop NEW adoption during the
|
|
1649
|
+
// window, which is the only thing a deprecation notice with no gate cannot
|
|
1650
|
+
// do. Regex, not a YAML parse, to match the file's existing convention.
|
|
1651
|
+
if (
|
|
1652
|
+
COMPATIBILITY_KEY_PATTERN.test(frontmatter) &&
|
|
1653
|
+
!HARNESS_COMPAT_KEY_PATTERN.test(frontmatter)
|
|
1654
|
+
) {
|
|
1655
|
+
issues.push(
|
|
1656
|
+
new Issue(
|
|
1657
|
+
'warning',
|
|
1658
|
+
'deprecated_compatibility_field',
|
|
1659
|
+
"Frontmatter declares the deprecated free-text 'compatibility:' without the structured " +
|
|
1660
|
+
"'harness_compat:' that supersedes it — add harness_compat (see skill.schema.json and " +
|
|
1661
|
+
'docs/MIGRATION.md § Scheduled deprecations); compatibility stays accepted until removal',
|
|
1662
|
+
),
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1586
1666
|
const execution = parseExecutionBlock(frontmatter);
|
|
1587
1667
|
if (execution !== null) {
|
|
1588
|
-
issues.push(...lint_execution_metadata(execution, frontmatter));
|
|
1668
|
+
issues.push(...lint_execution_metadata(execution, frontmatter, text.replace(FRONTMATTER_PATTERN, '')));
|
|
1589
1669
|
}
|
|
1590
1670
|
|
|
1591
1671
|
const tierMatch = TIER_PATTERN.exec(frontmatter);
|
|
@@ -34,6 +34,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
34
34
|
import * as fs from 'node:fs';
|
|
35
35
|
import * as path from 'node:path';
|
|
36
36
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
37
|
+
import { read_live_records, register_dir } from './_lib/session_register.js';
|
|
37
38
|
|
|
38
39
|
export interface CheckResult {
|
|
39
40
|
allowed: boolean;
|
|
@@ -304,8 +305,20 @@ function isAncestor(repoPath: string, branch: string, trunk: string): boolean {
|
|
|
304
305
|
}
|
|
305
306
|
}
|
|
306
307
|
|
|
307
|
-
|
|
308
|
-
|
|
308
|
+
/**
|
|
309
|
+
* `basePath` MUST be the main worktree, never the invoking repo path.
|
|
310
|
+
*
|
|
311
|
+
* Measured 2026-08-13, and the failure is total rather than partial: called with
|
|
312
|
+
* a linked worktree as the base, every sibling worktree resolves to `..` and the
|
|
313
|
+
* safe set collapses to empty. Same binary, same repo, same minute — from inside
|
|
314
|
+
* `.claude/worktrees/<branch>`: 304 registered, safe 0, 278 "non-standard"; from
|
|
315
|
+
* the main checkout: safe 181, 81 non-standard. A maintainer who ran the
|
|
316
|
+
* inventory from a worktree would read "nothing to clean" and conclude the
|
|
317
|
+
* estate was fine, which is the worst shape a cleanup tool can fail in — it
|
|
318
|
+
* fails silently, and toward inaction.
|
|
319
|
+
*/
|
|
320
|
+
export function isStandardLocation(basePath: string, worktreePath: string): boolean {
|
|
321
|
+
const rel = path.relative(canonical(basePath), canonical(worktreePath));
|
|
309
322
|
if (rel.startsWith('..') || path.isAbsolute(rel)) return false;
|
|
310
323
|
return STANDARD_WORKTREE_DIRS.some(
|
|
311
324
|
(dir) => rel === dir || rel.startsWith(`${dir}${path.sep}`),
|
|
@@ -348,16 +361,70 @@ function lastGitActivity(worktreePath: string): Date | null {
|
|
|
348
361
|
* Classify every worktree. `now` is injectable so the live-window boundary is
|
|
349
362
|
* testable rather than wall-clock dependent.
|
|
350
363
|
*/
|
|
351
|
-
|
|
364
|
+
/**
|
|
365
|
+
* Two conditions the `safe` predicate does NOT carry by default, both off unless
|
|
366
|
+
* asked for. They exist because an approval can be stricter than the tool, and
|
|
367
|
+
* silently removing under the looser predicate is the substitution such an
|
|
368
|
+
* approval is written to prevent.
|
|
369
|
+
*
|
|
370
|
+
* `minAgeDays` is a floor on git inactivity, layered ON TOP of the 48-hour live
|
|
371
|
+
* window rather than replacing it: 48h answers "is someone in it right now", a
|
|
372
|
+
* 60-day floor answers "is this abandoned". Different questions.
|
|
373
|
+
*
|
|
374
|
+
* `excludeLiveSessions` reads the session register — real records with a real
|
|
375
|
+
* `worktree` path and a real TTL — instead of inferring occupancy from file
|
|
376
|
+
* mtime, which this module's own header already rules out as a liveness signal.
|
|
377
|
+
*/
|
|
378
|
+
export interface InventoryOptions {
|
|
379
|
+
now?: Date;
|
|
380
|
+
minAgeDays?: number | null;
|
|
381
|
+
excludeLiveSessions?: boolean;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function buildInventory(
|
|
385
|
+
repoPath: string,
|
|
386
|
+
nowOrOptions: Date | InventoryOptions = new Date(),
|
|
387
|
+
): Inventory {
|
|
388
|
+
const opts: InventoryOptions =
|
|
389
|
+
nowOrOptions instanceof Date ? { now: nowOrOptions } : nowOrOptions;
|
|
390
|
+
const now = opts.now ?? new Date();
|
|
391
|
+
const minAgeDays = opts.minAgeDays ?? null;
|
|
392
|
+
const ageCutoff = minAgeDays === null ? null : now.getTime() - minAgeDays * 86400 * 1000;
|
|
393
|
+
return buildInventoryInner(repoPath, now, ageCutoff, minAgeDays, opts.excludeLiveSessions === true);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function buildInventoryInner(
|
|
397
|
+
repoPath: string,
|
|
398
|
+
nowArg: Date,
|
|
399
|
+
ageCutoff: number | null,
|
|
400
|
+
minAgeDays: number | null,
|
|
401
|
+
excludeLiveSessions: boolean,
|
|
402
|
+
): Inventory {
|
|
403
|
+
const now = nowArg;
|
|
352
404
|
const trunk = resolveTrunk(repoPath);
|
|
353
405
|
const entries = listWorktrees(repoPath);
|
|
354
406
|
const mainPath = canonical(entries.length > 0 ? entries[0]!.path : repoPath);
|
|
355
407
|
const liveCutoff = now.getTime() - LIVE_WINDOW_HOURS * 3600 * 1000;
|
|
356
408
|
|
|
409
|
+
// Registered session worktrees, canonicalised so the comparison survives a
|
|
410
|
+
// symlinked checkout root the same way every other path here does. Empty set
|
|
411
|
+
// when the option is off, when no register directory exists (the normal
|
|
412
|
+
// state before any session registers), or when every record has expired.
|
|
413
|
+
const sessionPaths = new Set<string>();
|
|
414
|
+
if (excludeLiveSessions) {
|
|
415
|
+
const dir = register_dir(mainPath);
|
|
416
|
+
if (dir !== null) {
|
|
417
|
+
for (const rec of read_live_records(dir, { now })) {
|
|
418
|
+
sessionPaths.add(canonical(rec.worktree));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
357
423
|
const rows: InventoryRow[] = entries.map((e) => {
|
|
358
424
|
const resolved = canonical(e.path);
|
|
359
425
|
const isMain = resolved === mainPath;
|
|
360
|
-
|
|
426
|
+
// `mainPath`, NOT `repoPath` — see isStandardLocation's contract.
|
|
427
|
+
const standardLocation = isMain ? true : isStandardLocation(mainPath, resolved);
|
|
361
428
|
const reasons: string[] = [];
|
|
362
429
|
|
|
363
430
|
if (!fs.existsSync(resolved)) {
|
|
@@ -389,6 +456,20 @@ export function buildInventory(repoPath: string, now: Date = new Date()): Invent
|
|
|
389
456
|
if (e.branch === null) {
|
|
390
457
|
reasons.push('detached HEAD — no branch to judge reachability for');
|
|
391
458
|
}
|
|
459
|
+
if (sessionPaths.has(resolved)) {
|
|
460
|
+
reasons.push('a live agent session is registered in this worktree');
|
|
461
|
+
}
|
|
462
|
+
if (ageCutoff !== null && (activity === null || activity.getTime() >= ageCutoff)) {
|
|
463
|
+
// `activity === null` disqualifies rather than passes: an unreadable
|
|
464
|
+
// git-dir mtime is absence of evidence, and under an explicit
|
|
465
|
+
// minimum-age floor that has to read as "cannot show it is old
|
|
466
|
+
// enough", never as "old enough".
|
|
467
|
+
reasons.push(
|
|
468
|
+
activity === null
|
|
469
|
+
? `git activity unreadable — cannot prove ${minAgeDays}+ days of inactivity`
|
|
470
|
+
: `git activity within the last ${minAgeDays} days`,
|
|
471
|
+
);
|
|
472
|
+
}
|
|
392
473
|
if (!standardLocation) {
|
|
393
474
|
reasons.push('non-standard location — outside the conventional worktree roots');
|
|
394
475
|
}
|
|
@@ -465,7 +546,7 @@ export function removalPlan(inv: Inventory): string[] {
|
|
|
465
546
|
function usage(): never {
|
|
466
547
|
process.stderr.write(
|
|
467
548
|
'usage: worktree_cleanup_check check <worktree-path> | scope-overlap [repo-path] | ' +
|
|
468
|
-
'inventory [repo-path] [--json|--plan]\n',
|
|
549
|
+
'inventory [repo-path] [--json|--plan] [--min-age-days=N] [--exclude-live-sessions]\n',
|
|
469
550
|
);
|
|
470
551
|
process.exit(2);
|
|
471
552
|
}
|
|
@@ -509,9 +590,32 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
|
509
590
|
const rest = argv.slice(1);
|
|
510
591
|
const flags = rest.filter((a) => a.startsWith('--'));
|
|
511
592
|
const positional = rest.filter((a) => !a.startsWith('--'));
|
|
512
|
-
|
|
593
|
+
const KNOWN = ['--json', '--plan', '--exclude-live-sessions'];
|
|
594
|
+
const ageFlag = flags.find((f) => f.startsWith('--min-age-days='));
|
|
595
|
+
if (
|
|
596
|
+
positional.length > 1 ||
|
|
597
|
+
flags.some((f) => !KNOWN.includes(f) && !f.startsWith('--min-age-days='))
|
|
598
|
+
) {
|
|
599
|
+
usage();
|
|
600
|
+
}
|
|
601
|
+
let minAgeDays: number | null = null;
|
|
602
|
+
if (ageFlag !== undefined) {
|
|
603
|
+
const raw = ageFlag.slice('--min-age-days='.length);
|
|
604
|
+
const n = Number(raw);
|
|
605
|
+
// Refuse rather than silently fall back to null: a typo'd floor that
|
|
606
|
+
// reads as "no floor" would widen the safe set at exactly the moment
|
|
607
|
+
// the caller asked to narrow it.
|
|
608
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) {
|
|
609
|
+
process.stderr.write(`--min-age-days needs a non-negative integer, got '${raw}'\n`);
|
|
610
|
+
return 2;
|
|
611
|
+
}
|
|
612
|
+
minAgeDays = n;
|
|
613
|
+
}
|
|
513
614
|
const repo = path.resolve(positional[0] ?? '.');
|
|
514
|
-
const inv = buildInventory(repo
|
|
615
|
+
const inv = buildInventory(repo, {
|
|
616
|
+
minAgeDays,
|
|
617
|
+
excludeLiveSessions: flags.includes('--exclude-live-sessions'),
|
|
618
|
+
});
|
|
515
619
|
|
|
516
620
|
if (flags.includes('--json')) {
|
|
517
621
|
process.stdout.write(`${JSON.stringify(inv, null, 2)}\n`);
|
|
@@ -23,7 +23,6 @@ const accessStyle = z.enum(['getters_setters', 'get_attribute', 'magic_propertie
|
|
|
23
23
|
const chatFreq = z.enum(['per_turn', 'per_phase', 'per_tool']);
|
|
24
24
|
const qualityCadence = z.enum(['end_of_roadmap', 'per_phase', 'per_step']);
|
|
25
25
|
const regenCadence = z.enum(['per_step', 'every_5_steps', 'phase_boundary']);
|
|
26
|
-
const worktreeMode = z.enum(['off', 'on', 'ask']);
|
|
27
26
|
const fidelityMode = z.enum(['strict', 'structural', 'hard-floor']);
|
|
28
27
|
const crossSourceMode = z.enum(['on', 'auto', 'off']);
|
|
29
28
|
const richSkillsMode = z.enum(['on', 'ask', 'off']);
|
|
@@ -351,11 +350,9 @@ export const settingsSchema = z.object({
|
|
|
351
350
|
'Opt-in adversarial-verification-council mode (subagent-orchestration Mode 9, ADR-122). off (default) = never runs; ask = offer it on an explicit high-risk change; on = auto-run on high-risk changes. Advisory only — a panel of distinct-model skeptics red-teams a real change for defect FINDING coverage and NEVER auto-gates it (Hard Floor). Stays default-off until the adversarial-council-finding-coverage claim is backed.',
|
|
352
351
|
),
|
|
353
352
|
}),
|
|
354
|
-
worktrees
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
),
|
|
358
|
-
}),
|
|
353
|
+
// `worktrees.mode` was DELETED (ADR-229). Worktree creation is
|
|
354
|
+
// instruction-only and hardcoded; there is nothing left to configure. A
|
|
355
|
+
// leftover key is ignored with one deprecation line via REMOVED_KEYS.
|
|
359
356
|
ai_team: z.object({
|
|
360
357
|
model: z.string().default('auto').describe(
|
|
361
358
|
"Model handed to the codex CLI. 'auto' (default) = pass no --model flag so the CLI's own default applies — tracks the subscription's current strongest model instead of pinning a stale ID. Any other value passes through verbatim as `--model <value>`.",
|