@deftai/directive 0.123.0 → 0.125.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.
@@ -16,6 +16,14 @@ export declare const PR_VERB_MAP: Readonly<Record<string, string>>;
16
16
  export declare const VERIFY_VERB_MAP: Readonly<Record<string, string>>;
17
17
  /** Namespace handlers that require a subcommand token after the handler stem. */
18
18
  export declare const SUBCOMMAND_ROUTES: Readonly<Record<string, readonly [string, string]>>;
19
+ /** Eight scm:body:* dual-invoke names (#5521); keep in sync with SUBCOMMAND_ROUTES above. */
20
+ export declare const SCM_BODY_COLON_VERBS: readonly ["scm:body:issue:create", "scm:body:issue:edit", "scm:body:issue:fetch", "scm:body:issue:lint", "scm:body:comment:create", "scm:body:comment:edit", "scm:body:pr:edit", "scm:body:pr:lint"];
21
+ /**
22
+ * Colon forms handled by explicit `routeNamespaceVerb` branches (not SUBCOMMAND_ROUTES /
23
+ * PR_VERB_MAP / VERIFY_VERB_MAP / SCOPE_LIFECYCLE_VERBS). Scraped by rule-to-verb parity
24
+ * so valid citations like `deft framework:doctor` pass (#5521).
25
+ */
26
+ export declare const ROUTER_BRANCH_COLON_VERBS: readonly ["framework:doctor", "agents:refresh", "scope:demote", "scope:decompose", "scope:undo", "scope:record-approved-scope", "scope:record-observable-scope", "scope:record-intent-constraint", "scm:issue:design-critique-chip", "scm:issue:design-critique-stale-ready", "scm:issue:work-claim", "issue:ingest", "issue:emit", "issue:sync-from-xbrief"];
19
27
  export type RouteKind = "dispatch" | "stub";
20
28
  export interface RoutedArgv {
21
29
  kind: RouteKind;
@@ -118,11 +118,52 @@ export const SUBCOMMAND_ROUTES = {
118
118
  "github-body:comment-edit": ["github-body", "comment-edit"],
119
119
  "github-body:pr-edit": ["github-body", "pr-edit"],
120
120
  "github-body:pr-lint": ["github-body", "pr-lint"],
121
+ // #5521: pinned AGENTS scm:body:* colon aliases → github-body engine (argv inserts subcommand)
122
+ "scm:body:issue:create": ["github-body", "issue-create"],
123
+ "scm:body:issue:edit": ["github-body", "issue-edit"],
124
+ "scm:body:issue:fetch": ["github-body", "issue-fetch"],
125
+ "scm:body:issue:lint": ["github-body", "issue-lint"],
126
+ "scm:body:comment:create": ["github-body", "comment-create"],
127
+ "scm:body:comment:edit": ["github-body", "comment-edit"],
128
+ "scm:body:pr:edit": ["github-body", "pr-edit"],
129
+ "scm:body:pr:lint": ["github-body", "pr-lint"],
121
130
  "plan-sequence:set": ["plan-sequence", "set"],
122
131
  "plan-sequence:current": ["plan-sequence", "current"],
123
132
  "plan-sequence:clear": ["plan-sequence", "clear"],
124
133
  "plan-sequence:advance": ["plan-sequence", "advance"],
125
134
  };
135
+ /** Eight scm:body:* dual-invoke names (#5521); keep in sync with SUBCOMMAND_ROUTES above. */
136
+ export const SCM_BODY_COLON_VERBS = [
137
+ "scm:body:issue:create",
138
+ "scm:body:issue:edit",
139
+ "scm:body:issue:fetch",
140
+ "scm:body:issue:lint",
141
+ "scm:body:comment:create",
142
+ "scm:body:comment:edit",
143
+ "scm:body:pr:edit",
144
+ "scm:body:pr:lint",
145
+ ];
146
+ /**
147
+ * Colon forms handled by explicit `routeNamespaceVerb` branches (not SUBCOMMAND_ROUTES /
148
+ * PR_VERB_MAP / VERIFY_VERB_MAP / SCOPE_LIFECYCLE_VERBS). Scraped by rule-to-verb parity
149
+ * so valid citations like `deft framework:doctor` pass (#5521).
150
+ */
151
+ export const ROUTER_BRANCH_COLON_VERBS = [
152
+ "framework:doctor",
153
+ "agents:refresh",
154
+ "scope:demote",
155
+ "scope:decompose",
156
+ "scope:undo",
157
+ "scope:record-approved-scope",
158
+ "scope:record-observable-scope",
159
+ "scope:record-intent-constraint",
160
+ "scm:issue:design-critique-chip",
161
+ "scm:issue:design-critique-stale-ready",
162
+ "scm:issue:work-claim",
163
+ "issue:ingest",
164
+ "issue:emit",
165
+ "issue:sync-from-xbrief",
166
+ ];
126
167
  function isMetaVerb(token) {
127
168
  return token === "--help" || token === "-h" || token === "--version" || token === "-V";
128
169
  }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ export declare const DESIGN_CRITIQUE_SPEND_RESOLVE_HELP = "design-critique:spend-resolve \u2014 record spend-recommend then resolve (#5466)\n\nUsage:\n deft design-critique:spend-resolve --utterance <text> --recommend N=1|N\u22653 [--project-root PATH] [--session-id ID] [--json]\n deft design-critique:spend-resolve --open-gate [--utterance <text>] [--project-root PATH] [--session-id ID]\n deft design-critique:spend-resolve --clear [--project-root PATH] [--session-id ID]\n deft design-critique:spend-resolve --utterance <text> --unclosable-recommend [--project-root PATH] [--session-id ID]\n\nOptions:\n --utterance TEXT Operator chat utterance (required except --open-gate/--clear)\n --recommend N=1|N\u22653 Closed Dual-stop recommendation (required on bare arc)\n --unclosable-recommend Parent-declared unclosable recommend; permit lawful ask\n --open-gate Open deny-default session-scoped arc-spend-state at arc start\n --clear Clear session arc-spend-state when the arc ends or is abandoned\n --session-id ID Session that owns arc-spend-state (default: DEFT_SESSION_ID / env)\n --project-root PATH Project root for arc-spend-state scratch (default: cwd)\n --json Emit structured result\n\nExit codes:\n 0 Resolved / gate opened / cleared\n 1 Refused (missing/invalid recommend, ambiguous, or unclosable ask path)\n 2 Config / usage error\n";
3
+ export interface DesignCritiqueSpendResolveArgs {
4
+ utterance: string | null;
5
+ recommend: string | null;
6
+ projectRoot: string;
7
+ sessionId: string | null;
8
+ emitJson: boolean;
9
+ help: boolean;
10
+ openGate: boolean;
11
+ clear: boolean;
12
+ unclosableRecommend: boolean;
13
+ error?: string;
14
+ }
15
+ export declare function parseDesignCritiqueSpendResolveArgs(argv: readonly string[]): DesignCritiqueSpendResolveArgs;
16
+ export declare function run(argv: readonly string[]): number;
17
+ export declare function main(argv: readonly string[]): number;
18
+ //# sourceMappingURL=design-critique-spend-resolve.d.ts.map
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * design-critique:spend-resolve — callable spend front door (#5466 Prefer-A).
4
+ * Records closed spend-recommend: + resolved spend:/spend-ask: via
5
+ * parseOperatorSpend / evaluateSpendRecord. Bare arc requires --recommend;
6
+ * never asks; never defaults N=1. Does not copy run-posture missing-token
7
+ * auto-resolve onto spend.
8
+ */
9
+ import { resolve } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ import { clearArcSpendState, openArcSpendGate, resolveDesignCritiqueSpend, } from "@deftai/directive-core/dist/design-critique/spend.js";
12
+ export const DESIGN_CRITIQUE_SPEND_RESOLVE_HELP = `design-critique:spend-resolve — record spend-recommend then resolve (#5466)
13
+
14
+ Usage:
15
+ deft design-critique:spend-resolve --utterance <text> --recommend N=1|N≥3 [--project-root PATH] [--session-id ID] [--json]
16
+ deft design-critique:spend-resolve --open-gate [--utterance <text>] [--project-root PATH] [--session-id ID]
17
+ deft design-critique:spend-resolve --clear [--project-root PATH] [--session-id ID]
18
+ deft design-critique:spend-resolve --utterance <text> --unclosable-recommend [--project-root PATH] [--session-id ID]
19
+
20
+ Options:
21
+ --utterance TEXT Operator chat utterance (required except --open-gate/--clear)
22
+ --recommend N=1|N≥3 Closed Dual-stop recommendation (required on bare arc)
23
+ --unclosable-recommend Parent-declared unclosable recommend; permit lawful ask
24
+ --open-gate Open deny-default session-scoped arc-spend-state at arc start
25
+ --clear Clear session arc-spend-state when the arc ends or is abandoned
26
+ --session-id ID Session that owns arc-spend-state (default: DEFT_SESSION_ID / env)
27
+ --project-root PATH Project root for arc-spend-state scratch (default: cwd)
28
+ --json Emit structured result
29
+
30
+ Exit codes:
31
+ 0 Resolved / gate opened / cleared
32
+ 1 Refused (missing/invalid recommend, ambiguous, or unclosable ask path)
33
+ 2 Config / usage error
34
+ `;
35
+ export function parseDesignCritiqueSpendResolveArgs(argv) {
36
+ const acc = {
37
+ utterance: null,
38
+ recommend: null,
39
+ projectRoot: ".",
40
+ sessionId: null,
41
+ emitJson: false,
42
+ help: false,
43
+ openGate: false,
44
+ clear: false,
45
+ unclosableRecommend: false,
46
+ };
47
+ for (let i = 0; i < argv.length; i += 1) {
48
+ const arg = argv[i];
49
+ // Accept a lone go-task / deft separator so documented `-- --utterance` forms work.
50
+ if (arg === "--") {
51
+ continue;
52
+ }
53
+ if (arg === "--help" || arg === "-h") {
54
+ return { ...acc, help: true };
55
+ }
56
+ if (arg === "--json") {
57
+ acc.emitJson = true;
58
+ continue;
59
+ }
60
+ if (arg === "--open-gate") {
61
+ acc.openGate = true;
62
+ continue;
63
+ }
64
+ if (arg === "--clear") {
65
+ acc.clear = true;
66
+ continue;
67
+ }
68
+ if (arg === "--unclosable-recommend") {
69
+ acc.unclosableRecommend = true;
70
+ continue;
71
+ }
72
+ if (arg === "--utterance") {
73
+ const value = argv[i + 1];
74
+ if (value === undefined) {
75
+ return { ...acc, error: "argument --utterance: expected one argument" };
76
+ }
77
+ acc.utterance = value;
78
+ i += 1;
79
+ continue;
80
+ }
81
+ if (arg?.startsWith("--utterance=")) {
82
+ acc.utterance = arg.slice("--utterance=".length);
83
+ continue;
84
+ }
85
+ if (arg === "--recommend") {
86
+ const value = argv[i + 1];
87
+ if (value === undefined) {
88
+ return { ...acc, error: "argument --recommend: expected one argument" };
89
+ }
90
+ acc.recommend = value;
91
+ i += 1;
92
+ continue;
93
+ }
94
+ if (arg?.startsWith("--recommend=")) {
95
+ acc.recommend = arg.slice("--recommend=".length);
96
+ continue;
97
+ }
98
+ if (arg === "--session-id") {
99
+ const value = argv[i + 1];
100
+ if (value === undefined || value.startsWith("--")) {
101
+ return { ...acc, error: "argument --session-id: expected one argument" };
102
+ }
103
+ acc.sessionId = value;
104
+ i += 1;
105
+ continue;
106
+ }
107
+ if (arg?.startsWith("--session-id=")) {
108
+ acc.sessionId = arg.slice("--session-id=".length);
109
+ continue;
110
+ }
111
+ if (arg === "--project-root") {
112
+ const value = argv[i + 1];
113
+ if (value === undefined) {
114
+ return { ...acc, error: "argument --project-root: expected one argument" };
115
+ }
116
+ acc.projectRoot = value;
117
+ i += 1;
118
+ continue;
119
+ }
120
+ if (arg?.startsWith("--project-root=")) {
121
+ acc.projectRoot = arg.slice("--project-root=".length);
122
+ continue;
123
+ }
124
+ return { ...acc, error: `unknown argument: ${arg}` };
125
+ }
126
+ return acc;
127
+ }
128
+ export function run(argv) {
129
+ const args = parseDesignCritiqueSpendResolveArgs(argv);
130
+ if (args.help) {
131
+ process.stdout.write(`${DESIGN_CRITIQUE_SPEND_RESOLVE_HELP}\n`);
132
+ return 0;
133
+ }
134
+ if (args.error !== undefined) {
135
+ process.stderr.write(`design-critique:spend-resolve: ${args.error}\n`);
136
+ return 2;
137
+ }
138
+ const projectRoot = resolve(args.projectRoot);
139
+ const sessionId = args.sessionId;
140
+ if (args.clear) {
141
+ const removed = clearArcSpendState(projectRoot, { sessionId });
142
+ if (args.emitJson) {
143
+ process.stdout.write(`${JSON.stringify({ ok: true, cleared: removed }, null, 2)}\n`);
144
+ }
145
+ else {
146
+ process.stdout.write(removed
147
+ ? "design-critique:spend-resolve: cleared arc-spend-state\n"
148
+ : "design-critique:spend-resolve: no arc-spend-state to clear\n");
149
+ }
150
+ return 0;
151
+ }
152
+ if (args.openGate) {
153
+ const state = openArcSpendGate(projectRoot, { utterance: args.utterance, sessionId });
154
+ if (args.emitJson) {
155
+ process.stdout.write(`${JSON.stringify({ ok: true, opened: true, state }, null, 2)}\n`);
156
+ }
157
+ else {
158
+ process.stdout.write("design-critique:spend-resolve: opened arc spend gate (ask denied until --recommend or lawful ask)\n");
159
+ }
160
+ return 0;
161
+ }
162
+ if (args.utterance === null || args.utterance.trim().length === 0) {
163
+ process.stderr.write("design-critique:spend-resolve: --utterance is required\n" +
164
+ "Remediation: deft design-critique:spend-resolve --utterance <text> --recommend N=1|N≥3\n");
165
+ return 2;
166
+ }
167
+ const result = resolveDesignCritiqueSpend({
168
+ utterance: args.utterance,
169
+ recommendRaw: args.recommend,
170
+ unclosableRecommend: args.unclosableRecommend,
171
+ projectRoot,
172
+ sessionId,
173
+ });
174
+ if (args.emitJson) {
175
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
176
+ }
177
+ else if (result.ok) {
178
+ process.stdout.write(`${result.lines.join("\n")}\n`);
179
+ }
180
+ else {
181
+ process.stderr.write(`${result.message}\n`);
182
+ }
183
+ return result.ok ? 0 : 1;
184
+ }
185
+ export function main(argv) {
186
+ return run(argv);
187
+ }
188
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
189
+ process.exit(run(process.argv.slice(2)));
190
+ }
191
+ //# sourceMappingURL=design-critique-spend-resolve.js.map
@@ -10,9 +10,9 @@ export interface DispatchIo {
10
10
  writeErr: (text: string) => void;
11
11
  }
12
12
  /** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
13
- export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "ownership-doctor", "ownership-fix", "verify-ownership", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "pre-pr-run", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-presentation-coverage", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "verify-spec-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-cohort-review-monitors", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "subagent-pre-cancel", "subagent-steer-write", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-consumer-header-placeholder", "verify-agents-md-advisory", "verify-persisted-planning-narratives", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-presentation-ceiling", "verify-intent-constraint", "verify-durable-effect-acquisition", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
13
+ export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "ownership-doctor", "ownership-fix", "verify-ownership", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "pre-pr-run", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-presentation-coverage", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "verify-spec-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-cohort-review-monitors", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "subagent-pre-cancel", "subagent-steer-write", "design-critique-spend-resolve", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-consumer-header-placeholder", "verify-agents-md-advisory", "verify-persisted-planning-narratives", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-presentation-ceiling", "verify-intent-constraint", "verify-durable-effect-acquisition", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
14
14
  /** Core-only CLI entrypoints without a packages/cli wrapper. */
15
- export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-reconstruct", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "migrate-clause-ids", "migrate-confidence"];
15
+ export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-reconstruct", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "migrate-clause-ids", "migrate-confidence", "rule-to-verb-parity"];
16
16
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
17
17
  export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
18
18
  /** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
@@ -177,12 +177,13 @@ export declare function printCommandsList(io?: DispatchIo): void;
177
177
  * (#2172). Preserves the init/update/doctor first-run guidance from #2273.
178
178
  */
179
179
  export declare function printHelp(io?: DispatchIo): void;
180
+ export type UnknownColonHintContext = "framework" | "include-only" | "no-taskfile" | "unknown";
180
181
  /**
181
- * Unknown-colon-verb remediation (#3439 / #2652).
182
- * Agent-facing spelling is `deft <verb>` (works on consumer CLI and source).
183
- * Bare `task <verb>` is not consumer-runnable on include-only Taskfiles.
182
+ * Unknown-colon-verb remediation (#3439 / #2652 / #5521).
183
+ * Never re-suggest the failing `deft <verb>` spelling. Prefer Taskfile
184
+ * dual-invoke forms when known; demote hyphen stems; no `task --list` shell-out.
184
185
  */
185
- export declare function unknownColonVerbHint(verb: string): string;
186
+ export declare function unknownColonVerbHint(verb: string, context?: UnknownColonHintContext): string;
186
187
  /** Dispatch argv to a registered verb; returns the handler exit code. */
187
188
  export declare function dispatch(argv: string[], io?: DispatchIo): Promise<number>;
188
189
  /** Test seam: reset lazy handler cache between cases. */
package/dist/dispatch.js CHANGED
@@ -161,6 +161,7 @@ export const CLI_MODULE_VERBS = [
161
161
  "verify-subagent-steer",
162
162
  "subagent-pre-cancel",
163
163
  "subagent-steer-write",
164
+ "design-critique-spend-resolve",
164
165
  "review-monitor-register",
165
166
  "review-monitor-release",
166
167
  "verify-tools",
@@ -244,6 +245,7 @@ export const CORE_MODULE_VERBS = [
244
245
  "docs-impact",
245
246
  "migrate-clause-ids",
246
247
  "migrate-confidence",
248
+ "rule-to-verb-parity",
247
249
  ];
248
250
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
249
251
  export const TRIAGE_ACTION_ALIAS_SUBCOMMANDS = {
@@ -378,6 +380,7 @@ export const VERB_ALIASES = {
378
380
  "verify:subagent-steer": "verify-subagent-steer",
379
381
  "subagent:pre-cancel": "subagent-pre-cancel",
380
382
  "subagent:steer": "subagent-steer-write",
383
+ "design-critique:spend-resolve": "design-critique-spend-resolve",
381
384
  "agent:monitor": "subagent-monitor",
382
385
  "review-monitor:register": "review-monitor-register",
383
386
  "review-monitor:release": "review-monitor-release",
@@ -389,6 +392,7 @@ export const VERB_ALIASES = {
389
392
  "validate:links": "validate-links",
390
393
  "verify:rule-ownership": "rule-ownership-lint",
391
394
  "rule:ownership-lint": "rule-ownership-lint",
395
+ "verify:rule-to-verb-parity": "rule-to-verb-parity",
392
396
  "verify:biome-config": "verify-biome-config",
393
397
  "verify:contained-writes": "verify-contained-writes",
394
398
  "verify:telemetry-coverage": "verify-telemetry-coverage",
@@ -2467,6 +2471,10 @@ async function loadCoreModuleHandler(verb, io) {
2467
2471
  const { mainEntry } = await import("@deftai/directive-core/dist/intake/github-body-cli.js");
2468
2472
  return mainEntry;
2469
2473
  }
2474
+ case "rule-to-verb-parity": {
2475
+ const { mainEntry } = await import("@deftai/directive-core/dist/check/rule-to-verb-parity.js");
2476
+ return mainEntry;
2477
+ }
2470
2478
  case "issue-emit": {
2471
2479
  const { mainEntry } = await import("@deftai/directive-core/dist/intake/issue-emit-cli.js");
2472
2480
  return mainEntry;
@@ -2727,6 +2735,21 @@ const SCOPE_COMMAND_NAMES = [
2727
2735
  "scope:record-observable-scope",
2728
2736
  "scope:record-intent-constraint",
2729
2737
  ];
2738
+ /**
2739
+ * Static dual-invoke set for scm:body:* (#5521). Mirror of
2740
+ * packages/cli/src/cli-router/route-argv.ts SCM_BODY_COLON_VERBS — kept here
2741
+ * so dispatch does not import route-argv (route-argv already imports dispatch).
2742
+ */
2743
+ const SCM_BODY_DUAL_INVOKE_VERBS = new Set([
2744
+ "scm:body:issue:create",
2745
+ "scm:body:issue:edit",
2746
+ "scm:body:issue:fetch",
2747
+ "scm:body:issue:lint",
2748
+ "scm:body:comment:create",
2749
+ "scm:body:comment:edit",
2750
+ "scm:body:pr:edit",
2751
+ "scm:body:pr:lint",
2752
+ ]);
2730
2753
  /**
2731
2754
  * Deduplicated command names for `directive commands`, preferring colon-style
2732
2755
  * task verbs over dash-style canonical stems when both exist (#2172).
@@ -2740,6 +2763,7 @@ export function preferredCommandNames() {
2740
2763
  ...TOP_LEVEL_COMMAND_NAMES,
2741
2764
  ...SCOPE_COMMAND_NAMES,
2742
2765
  ...aliasKeys,
2766
+ ...SCM_BODY_DUAL_INVOKE_VERBS,
2743
2767
  ...unaliasedCanonicals,
2744
2768
  ]),
2745
2769
  ].sort();
@@ -2908,20 +2932,54 @@ async function invokeHandler(handler, argv) {
2908
2932
  }
2909
2933
  const PLAN_SEQUENCE_VERBS = "set|current|clear|advance";
2910
2934
  /**
2911
- * Unknown-colon-verb remediation (#3439 / #2652).
2912
- * Agent-facing spelling is `deft <verb>` (works on consumer CLI and source).
2913
- * Bare `task <verb>` is not consumer-runnable on include-only Taskfiles.
2935
+ * Unknown-colon-verb remediation (#3439 / #2652 / #5521).
2936
+ * Never re-suggest the failing `deft <verb>` spelling. Prefer Taskfile
2937
+ * dual-invoke forms when known; demote hyphen stems; no `task --list` shell-out.
2914
2938
  */
2915
- export function unknownColonVerbHint(verb) {
2939
+ export function unknownColonVerbHint(verb, context = "unknown") {
2916
2940
  if (verb.startsWith("plan-sequence:") && !(verb in PLAN_SEQUENCE_ALIAS_SUBCOMMANDS)) {
2917
2941
  return (`hint: plan-sequence verbs are ${PLAN_SEQUENCE_VERBS} ` +
2918
2942
  `(e.g. \`deft plan-sequence:current\`). '${verb}' is not a verb. ` +
2919
2943
  `Do not run bare \`task ${verb}\` -- consumer include-only Taskfiles cannot resolve it.\n`);
2920
2944
  }
2921
2945
  const hyphen = verb.replaceAll(":", "-");
2922
- return (`hint: try \`deft ${verb}\` (CLI) or \`task deft:${verb}\` (consumer Taskfile). ` +
2923
- `Bare \`task ${verb}\` does not exist on include-only deposits. ` +
2924
- `Hyphen stem: ${hyphen}.\n`);
2946
+ const hyphenNote = `Hyphen stem \`${hyphen}\` is not primary recovery.`;
2947
+ const listing = "List registered CLI verbs with `deft commands`.";
2948
+ if (SCM_BODY_DUAL_INVOKE_VERBS.has(verb)) {
2949
+ if (context === "include-only") {
2950
+ return (`hint: try \`task deft:${verb}\` (consumer include Taskfile). ` +
2951
+ `Bare \`task ${verb}\` is framework-only. ${hyphenNote} ${listing}\n`);
2952
+ }
2953
+ if (context === "no-taskfile") {
2954
+ return (`hint: Taskfile recovery is unavailable here. ` +
2955
+ `On a framework checkout with go-task: \`task ${verb}\`; ` +
2956
+ `on an include-only deposit: \`task deft:${verb}\`. ${hyphenNote} ${listing}\n`);
2957
+ }
2958
+ if (context === "framework") {
2959
+ return (`hint: try \`task ${verb}\` (framework Taskfile) or \`task deft:${verb}\` (consumer include). ` +
2960
+ `${hyphenNote} ${listing}\n`);
2961
+ }
2962
+ return (`hint: if go-task is available, try \`task ${verb}\` (framework) or ` +
2963
+ `\`task deft:${verb}\` (consumer include) — Taskfile recovery is conditional. ` +
2964
+ `${hyphenNote} ${listing}\n`);
2965
+ }
2966
+ if (context === "include-only") {
2967
+ return (`hint: do not retry the same \`deft ${verb}\` spelling. ` +
2968
+ `If a Taskfile task exists, try \`task deft:${verb}\` (include-only). ` +
2969
+ `${hyphenNote} ${listing}\n`);
2970
+ }
2971
+ if (context === "no-taskfile") {
2972
+ return (`hint: do not retry the same \`deft ${verb}\` spelling. ` +
2973
+ `Taskfile recovery is unavailable here. ${hyphenNote} ${listing}\n`);
2974
+ }
2975
+ if (context === "framework") {
2976
+ return (`hint: do not retry the same \`deft ${verb}\` spelling. ` +
2977
+ `If a Taskfile task exists, try \`task ${verb}\` (framework) or \`task deft:${verb}\` (include). ` +
2978
+ `${hyphenNote} ${listing}\n`);
2979
+ }
2980
+ return (`hint: do not retry the same \`deft ${verb}\` spelling. ` +
2981
+ `If a Taskfile task exists, try \`task ${verb}\` (framework) or \`task deft:${verb}\` (include) — ` +
2982
+ `Taskfile recovery is conditional. ${hyphenNote} ${listing}\n`);
2925
2983
  }
2926
2984
  function versionBanner() {
2927
2985
  return `${identityBanner()}\n`;
@@ -7,6 +7,8 @@ interface ParsedArgs {
7
7
  quiet?: boolean;
8
8
  error?: string;
9
9
  }
10
+ /** Typed-only deliveryBranch union for CLI-seeded DEFAULT_BRANCHES (#5520). */
11
+ export declare function enrichBranchesWithTypedDelivery(projectRoot: string | undefined, branches: ReadonlySet<string>): Set<string>;
10
12
  export declare function parseArgs(argv: string[]): ParsedArgs;
11
13
  export declare function run(argv: string[]): number | Promise<number>;
12
14
  export {};
@@ -13,7 +13,19 @@
13
13
  */
14
14
  import { createInterface } from "node:readline";
15
15
  import { fileURLToPath } from "node:url";
16
+ import { resolveDeliveryBranch } from "@deftai/directive-core/policy";
16
17
  import { DEFAULT_BRANCHES, evaluateCommand, evaluatePrePush, parsePrePushStdin, runSelfTest, } from "@deftai/directive-core/preflight";
18
+ /** Typed-only deliveryBranch union for CLI-seeded DEFAULT_BRANCHES (#5520). */
19
+ export function enrichBranchesWithTypedDelivery(projectRoot, branches) {
20
+ const next = new Set(branches);
21
+ if (projectRoot === undefined || projectRoot.length === 0)
22
+ return next;
23
+ const delivery = resolveDeliveryBranch(projectRoot);
24
+ if (delivery.source === "typed" && delivery.error === null && delivery.branch.trim().length > 0) {
25
+ next.add(delivery.branch);
26
+ }
27
+ return next;
28
+ }
17
29
  export function parseArgs(argv) {
18
30
  const parsed = { defaultBranches: new Set(DEFAULT_BRANCHES) };
19
31
  for (let i = 0; i < argv.length; i++) {
@@ -66,7 +78,8 @@ export function run(argv) {
66
78
  return 2;
67
79
  }
68
80
  const quiet = args.quiet ?? false;
69
- const branches = args.defaultBranches ?? new Set(DEFAULT_BRANCHES);
81
+ // CLI seeds DEFAULT_BRANCHES; union typed delivery when --project-root is set (#5520).
82
+ const branches = enrichBranchesWithTypedDelivery(args.projectRoot, args.defaultBranches ?? new Set(DEFAULT_BRANCHES));
70
83
  if (args.mode === "self-test") {
71
84
  const [code, msg] = runSelfTest();
72
85
  if (code === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.123.0",
3
+ "version": "0.125.0",
4
4
  "description": "Directive CLI — npm install path for the Deft Directive framework.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://deftai.github.io/directive/",
@@ -35,8 +35,8 @@
35
35
  "provenance": true
36
36
  },
37
37
  "dependencies": {
38
- "@deftai/directive-core": "^0.123.0",
39
- "@deftai/directive-content": "^0.123.0"
38
+ "@deftai/directive-core": "^0.125.0",
39
+ "@deftai/directive-content": "^0.125.0"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -b",