@deftai/directive 0.98.1 → 0.100.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/dist/cli-router/route-argv.js +1 -0
- package/dist/dispatch.d.ts +2 -2
- package/dist/dispatch.js +23 -0
- package/dist/policy.d.ts +6 -1
- package/dist/policy.js +83 -11
- package/dist/session-start.d.ts +17 -0
- package/dist/session-start.js +212 -1
- package/dist/verify-completed-tracked.d.ts +15 -0
- package/dist/verify-completed-tracked.js +88 -0
- package/dist/verify-literal-ac.d.ts +14 -0
- package/dist/verify-literal-ac.js +161 -0
- package/dist/verify-story-ready.js +1 -0
- package/package.json +3 -3
|
@@ -83,6 +83,7 @@ export const SUBCOMMAND_ROUTES = {
|
|
|
83
83
|
"policy:allow-direct-commits": ["policy", "allow-direct-commits"],
|
|
84
84
|
"policy:allow-bot-merge": ["policy", "allow-bot-merge"],
|
|
85
85
|
"policy:enable-value-feedback": ["policy", "enable-value-feedback"],
|
|
86
|
+
"policy:set-ceremony-dial": ["policy", "set-ceremony-dial"],
|
|
86
87
|
"policy:coverage-check-resume-preset": ["policy", "coverage-check-resume-preset"],
|
|
87
88
|
"policy:coverage-check-resume-dismiss": ["policy", "coverage-check-resume-dismiss"],
|
|
88
89
|
"policy:coverage-check-resume-later": ["policy", "coverage-check-resume-later"],
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -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", "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", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "scope-record-approved-scope", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "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", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "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-content-manifest", "verify-skill-external-fetch-gate", "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", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "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", "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", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "scope-lifecycle", "scope-record-approved-scope", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "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", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "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-content-manifest", "verify-skill-external-fetch-gate", "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", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-completed-tracked", "verify-literal-ac", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "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-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", "roadmap-render", "rule-map", "spec-render", "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"];
|
|
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-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", "roadmap-render", "rule-map", "spec-render", "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"];
|
|
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). */
|
package/dist/dispatch.js
CHANGED
|
@@ -137,6 +137,8 @@ export const CLI_MODULE_VERBS = [
|
|
|
137
137
|
"verify-tools",
|
|
138
138
|
"verify-wip-cap",
|
|
139
139
|
"verify-orphan-active",
|
|
140
|
+
"verify-completed-tracked",
|
|
141
|
+
"verify-literal-ac",
|
|
140
142
|
"verify-agents-md-budget",
|
|
141
143
|
"verify-agents-md-advisory",
|
|
142
144
|
"verify-eval-health-relocation",
|
|
@@ -159,6 +161,7 @@ export const CORE_MODULE_VERBS = [
|
|
|
159
161
|
"swarm-launch",
|
|
160
162
|
"swarm-complete-cohort",
|
|
161
163
|
"swarm-finalize-cohort",
|
|
164
|
+
"swarm-pre-dispatch",
|
|
162
165
|
"swarm-readiness",
|
|
163
166
|
"swarm-routing-verify",
|
|
164
167
|
"swarm-routing-set",
|
|
@@ -191,6 +194,8 @@ export const CORE_MODULE_VERBS = [
|
|
|
191
194
|
"value-readback",
|
|
192
195
|
"product-signal",
|
|
193
196
|
"freshness-report",
|
|
197
|
+
"decision-write",
|
|
198
|
+
"decision-list",
|
|
194
199
|
];
|
|
195
200
|
/** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
|
|
196
201
|
export const TRIAGE_ACTION_ALIAS_SUBCOMMANDS = {
|
|
@@ -211,6 +216,7 @@ export const POLICY_ACTION_ALIAS_SUBCOMMANDS = {
|
|
|
211
216
|
"policy:allow-direct-commits": "allow-direct-commits",
|
|
212
217
|
"policy:allow-bot-merge": "allow-bot-merge",
|
|
213
218
|
"policy:enable-value-feedback": "enable-value-feedback",
|
|
219
|
+
"policy:set-ceremony-dial": "set-ceremony-dial",
|
|
214
220
|
"policy:clear-value-feedback": "clear-value-feedback",
|
|
215
221
|
"policy:coverage-check-resume-preset": "coverage-check-resume-preset",
|
|
216
222
|
"policy:coverage-check-resume-dismiss": "coverage-check-resume-dismiss",
|
|
@@ -275,6 +281,9 @@ export const VERB_ALIASES = {
|
|
|
275
281
|
"verify:vbrief-conformance": "vbrief-validate",
|
|
276
282
|
"verify:wip-cap": "verify-wip-cap",
|
|
277
283
|
"verify:orphan-active": "verify-orphan-active",
|
|
284
|
+
"verify:completed-tracked": "verify-completed-tracked",
|
|
285
|
+
"verify:literal-ac": "verify-literal-ac",
|
|
286
|
+
"verify:literal-acceptance": "verify-literal-ac",
|
|
278
287
|
"verify:agents-md-budget": "verify-agents-md-budget",
|
|
279
288
|
"verify:agents-md-advisory": "verify-agents-md-advisory",
|
|
280
289
|
"verify:eval-health-relocation": "verify-eval-health-relocation",
|
|
@@ -360,6 +369,8 @@ export const VERB_ALIASES = {
|
|
|
360
369
|
"feedback:file": "feedback-file",
|
|
361
370
|
"value:show": "value-readback",
|
|
362
371
|
"triage:metrics": "value-readback",
|
|
372
|
+
"decision:write": "decision-write",
|
|
373
|
+
"decision:list": "decision-list",
|
|
363
374
|
"eval:run": "eval-run",
|
|
364
375
|
"eval:triggers": "eval-triggers",
|
|
365
376
|
"eval:report": "eval-report",
|
|
@@ -2340,6 +2351,10 @@ async function loadCoreModuleHandler(verb, io) {
|
|
|
2340
2351
|
const { finalizeCohortMain } = await import("@deftai/directive-core/dist/swarm/finalize-cohort-cli.js");
|
|
2341
2352
|
return finalizeCohortMain;
|
|
2342
2353
|
}
|
|
2354
|
+
case "swarm-pre-dispatch": {
|
|
2355
|
+
const { preDispatchMain } = await import("@deftai/directive-core/dist/swarm/pre-dispatch-cli.js");
|
|
2356
|
+
return preDispatchMain;
|
|
2357
|
+
}
|
|
2343
2358
|
case "swarm-readiness": {
|
|
2344
2359
|
const { readinessMain } = await import("@deftai/directive-core/dist/swarm/readiness-cli.js");
|
|
2345
2360
|
return readinessMain;
|
|
@@ -2470,6 +2485,14 @@ async function loadCoreModuleHandler(verb, io) {
|
|
|
2470
2485
|
const { mainEntry } = await import("@deftai/directive-core/dist/freshness/cli.js");
|
|
2471
2486
|
return mainEntry;
|
|
2472
2487
|
}
|
|
2488
|
+
case "decision-write": {
|
|
2489
|
+
const { writeMainEntry } = await import("@deftai/directive-core/dist/decision/index.js");
|
|
2490
|
+
return writeMainEntry;
|
|
2491
|
+
}
|
|
2492
|
+
case "decision-list": {
|
|
2493
|
+
const { listMainEntry } = await import("@deftai/directive-core/dist/decision/index.js");
|
|
2494
|
+
return listMainEntry;
|
|
2495
|
+
}
|
|
2473
2496
|
default:
|
|
2474
2497
|
throw new Error(`unknown core verb: ${verb}`);
|
|
2475
2498
|
}
|
package/dist/policy.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type CeremonyDepth } from "@deftai/directive-core/policy";
|
|
2
3
|
interface ShowArgs {
|
|
3
4
|
format: "text" | "json";
|
|
4
5
|
changedOnly: boolean;
|
|
@@ -7,7 +8,7 @@ interface ShowArgs {
|
|
|
7
8
|
error?: string;
|
|
8
9
|
}
|
|
9
10
|
interface SetArgs {
|
|
10
|
-
cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "coverage-check-resume-preset" | "coverage-check-resume-dismiss" | "coverage-check-resume-later" | "disable-directive" | "enable-directive" | "resolve";
|
|
11
|
+
cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "coverage-check-resume-preset" | "coverage-check-resume-dismiss" | "coverage-check-resume-later" | "disable-directive" | "enable-directive" | "resolve";
|
|
11
12
|
confirm: boolean;
|
|
12
13
|
actor: string;
|
|
13
14
|
note: string;
|
|
@@ -18,6 +19,10 @@ interface SetArgs {
|
|
|
18
19
|
/** Strict | hatch-aware for coverage-check-resume-preset; reason for dismiss. */
|
|
19
20
|
preset?: string;
|
|
20
21
|
reason?: string;
|
|
22
|
+
/** #3214 ceremony dial override depth for set-ceremony-dial. */
|
|
23
|
+
ceremonyOverride?: CeremonyDepth | null;
|
|
24
|
+
/** #3214 ceremony dial enabled flag for set-ceremony-dial. */
|
|
25
|
+
ceremonyEnabled?: boolean;
|
|
21
26
|
error?: string;
|
|
22
27
|
}
|
|
23
28
|
/** Parse policy:show flags (mirrors _policy_show_cli.py). */
|
package/dist/policy.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { resolve as pathResolve, relative } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { ALLOW_BOT_MERGE_CAPABILITY_COST, applyHatchAwareCoverageCheckResumePreset, applyLaterCoverageCheckResumeSkip, applyStrictCoverageCheckResumePreset, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disclosureLine, dismissCoverageCheckResume, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, setPolicy, setRequireHumanMerge, } from "@deftai/directive-core/policy";
|
|
9
|
+
import { ALLOW_BOT_MERGE_CAPABILITY_COST, applyHatchAwareCoverageCheckResumePreset, applyLaterCoverageCheckResumeSkip, applyStrictCoverageCheckResumePreset, CEREMONY_DEPTHS, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disclosureLine, dismissCoverageCheckResume, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, setCeremonyDial, setPolicy, setRequireHumanMerge, } from "@deftai/directive-core/policy";
|
|
10
10
|
const CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure -- enabling direct commits to the default " +
|
|
11
11
|
"branch turns OFF the deft branch-protection policy.\n" +
|
|
12
12
|
" \u2022 Pre-commit + pre-push hooks will no longer block default-branch " +
|
|
@@ -114,7 +114,7 @@ export function parseShowArgs(argv) {
|
|
|
114
114
|
/** Parse argv for the policy CLI (show + set subcommands). */
|
|
115
115
|
export function parseArgs(argv) {
|
|
116
116
|
if (argv.length === 0) {
|
|
117
|
-
const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-bot-merge|enable-value-feedback|clear-value-feedback|coverage-check-resume-preset|coverage-check-resume-dismiss|coverage-check-resume-later|disable-directive|enable-directive|resolve] ...";
|
|
117
|
+
const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|coverage-check-resume-preset|coverage-check-resume-dismiss|coverage-check-resume-later|disable-directive|enable-directive|resolve] ...";
|
|
118
118
|
return makeSetError(usage);
|
|
119
119
|
}
|
|
120
120
|
const cmd = argv[0];
|
|
@@ -151,6 +151,7 @@ export function parseArgs(argv) {
|
|
|
151
151
|
cmd === "allow-bot-merge" ||
|
|
152
152
|
cmd === "enable-value-feedback" ||
|
|
153
153
|
cmd === "clear-value-feedback" ||
|
|
154
|
+
cmd === "set-ceremony-dial" ||
|
|
154
155
|
cmd === "coverage-check-resume-preset" ||
|
|
155
156
|
cmd === "coverage-check-resume-dismiss" ||
|
|
156
157
|
cmd === "coverage-check-resume-later" ||
|
|
@@ -167,19 +168,23 @@ export function parseArgs(argv) {
|
|
|
167
168
|
? policyColonInvocation("enable-value-feedback")
|
|
168
169
|
: cmd === "clear-value-feedback"
|
|
169
170
|
? policyColonInvocation("clear-value-feedback")
|
|
170
|
-
: cmd === "
|
|
171
|
-
? policyColonInvocation("
|
|
172
|
-
: cmd === "coverage-check-resume-
|
|
173
|
-
? policyColonInvocation("coverage-check-resume-
|
|
174
|
-
: cmd === "coverage-check-resume-
|
|
175
|
-
? policyColonInvocation("coverage-check-resume-
|
|
176
|
-
: cmd === "
|
|
177
|
-
? policyColonInvocation("
|
|
178
|
-
:
|
|
171
|
+
: cmd === "set-ceremony-dial"
|
|
172
|
+
? policyColonInvocation("set-ceremony-dial")
|
|
173
|
+
: cmd === "coverage-check-resume-preset"
|
|
174
|
+
? policyColonInvocation("coverage-check-resume-preset")
|
|
175
|
+
: cmd === "coverage-check-resume-dismiss"
|
|
176
|
+
? policyColonInvocation("coverage-check-resume-dismiss")
|
|
177
|
+
: cmd === "coverage-check-resume-later"
|
|
178
|
+
? policyColonInvocation("coverage-check-resume-later")
|
|
179
|
+
: cmd === "disable-directive"
|
|
180
|
+
? policyColonInvocation("disable-directive")
|
|
181
|
+
: policyColonInvocation("enable-directive");
|
|
179
182
|
let note = "";
|
|
180
183
|
let projectRoot = ".";
|
|
181
184
|
let preset = "";
|
|
182
185
|
let reason = "";
|
|
186
|
+
let ceremonyOverride;
|
|
187
|
+
let ceremonyEnabled;
|
|
183
188
|
for (let i = 1; i < argv.length; i += 1) {
|
|
184
189
|
const arg = argv[i];
|
|
185
190
|
if (arg === "--confirm") {
|
|
@@ -239,6 +244,50 @@ export function parseArgs(argv) {
|
|
|
239
244
|
(arg === "strict" || arg === "hatch-aware")) {
|
|
240
245
|
preset = arg;
|
|
241
246
|
}
|
|
247
|
+
else if (cmd === "set-ceremony-dial" && (arg === "--override" || arg === "--depth")) {
|
|
248
|
+
const v = argv[i + 1];
|
|
249
|
+
if (v === undefined) {
|
|
250
|
+
return makeSetError(`argument ${arg}: expected one argument (minimal|rapid|standard|elevated|null)`);
|
|
251
|
+
}
|
|
252
|
+
if (v === "null" || v === "none" || v === "clear") {
|
|
253
|
+
ceremonyOverride = null;
|
|
254
|
+
}
|
|
255
|
+
else if (CEREMONY_DEPTHS.includes(v)) {
|
|
256
|
+
ceremonyOverride = v;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
return makeSetError(`argument ${arg}: expected minimal|rapid|standard|elevated|null, got ${JSON.stringify(v)}`);
|
|
260
|
+
}
|
|
261
|
+
i += 1;
|
|
262
|
+
}
|
|
263
|
+
else if (cmd === "set-ceremony-dial" &&
|
|
264
|
+
(arg?.startsWith("--override=") || arg?.startsWith("--depth="))) {
|
|
265
|
+
const v = arg.slice(arg.indexOf("=") + 1);
|
|
266
|
+
if (v === "null" || v === "none" || v === "clear") {
|
|
267
|
+
ceremonyOverride = null;
|
|
268
|
+
}
|
|
269
|
+
else if (CEREMONY_DEPTHS.includes(v)) {
|
|
270
|
+
ceremonyOverride = v;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
return makeSetError(`argument --override: expected minimal|rapid|standard|elevated|null, got ${JSON.stringify(v)}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else if (cmd === "set-ceremony-dial" && arg === "--enabled") {
|
|
277
|
+
const v = argv[i + 1];
|
|
278
|
+
if (v === undefined || (v !== "true" && v !== "false")) {
|
|
279
|
+
return makeSetError("argument --enabled: expected true|false");
|
|
280
|
+
}
|
|
281
|
+
ceremonyEnabled = v === "true";
|
|
282
|
+
i += 1;
|
|
283
|
+
}
|
|
284
|
+
else if (cmd === "set-ceremony-dial" && arg?.startsWith("--enabled=")) {
|
|
285
|
+
const v = arg.slice("--enabled=".length);
|
|
286
|
+
if (v !== "true" && v !== "false") {
|
|
287
|
+
return makeSetError("argument --enabled: expected true|false");
|
|
288
|
+
}
|
|
289
|
+
ceremonyEnabled = v === "true";
|
|
290
|
+
}
|
|
242
291
|
else {
|
|
243
292
|
return makeSetError(`unrecognized argument: ${arg}`);
|
|
244
293
|
}
|
|
@@ -254,6 +303,8 @@ export function parseArgs(argv) {
|
|
|
254
303
|
field: null,
|
|
255
304
|
preset,
|
|
256
305
|
reason,
|
|
306
|
+
ceremonyOverride,
|
|
307
|
+
ceremonyEnabled,
|
|
257
308
|
};
|
|
258
309
|
}
|
|
259
310
|
return makeSetError(`unknown subcommand: ${cmd}`);
|
|
@@ -493,6 +544,9 @@ export function run(argv) {
|
|
|
493
544
|
if (args.cmd === "clear-value-feedback") {
|
|
494
545
|
return runClearValueFeedback(args);
|
|
495
546
|
}
|
|
547
|
+
if (args.cmd === "set-ceremony-dial") {
|
|
548
|
+
return runSetCeremonyDial(args);
|
|
549
|
+
}
|
|
496
550
|
if (args.cmd === "coverage-check-resume-preset") {
|
|
497
551
|
return runCoverageCheckResumePreset(args);
|
|
498
552
|
}
|
|
@@ -546,6 +600,24 @@ function runCoverageCheckResumeLater() {
|
|
|
546
600
|
process.stdout.write(result.stdout);
|
|
547
601
|
return result.exitCode;
|
|
548
602
|
}
|
|
603
|
+
/** Persist plan.policy.ceremonyDial override/enabled (#3214). */
|
|
604
|
+
function runSetCeremonyDial(args) {
|
|
605
|
+
const root = pathResolve(args.projectRoot);
|
|
606
|
+
if (args.ceremonyOverride === undefined && args.ceremonyEnabled === undefined) {
|
|
607
|
+
process.stdout.write("usage: policy set-ceremony-dial -- --confirm [--override minimal|rapid|standard|elevated|null] [--enabled true|false] [--project-root PATH]\n" +
|
|
608
|
+
` Inspect: ${policyColonInvocation("show", " --field=ceremonyDial")}\n`);
|
|
609
|
+
return 1;
|
|
610
|
+
}
|
|
611
|
+
const result = setCeremonyDial(root, {
|
|
612
|
+
confirm: args.confirm,
|
|
613
|
+
actor: args.actor,
|
|
614
|
+
note: args.note,
|
|
615
|
+
...(args.ceremonyOverride !== undefined ? { override: args.ceremonyOverride } : {}),
|
|
616
|
+
...(args.ceremonyEnabled !== undefined ? { enabled: args.ceremonyEnabled } : {}),
|
|
617
|
+
});
|
|
618
|
+
process.stdout.write(result.stdout);
|
|
619
|
+
return result.exitCode;
|
|
620
|
+
}
|
|
549
621
|
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
550
622
|
process.exit(run(process.argv.slice(2)));
|
|
551
623
|
}
|
package/dist/session-start.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type CeremonyDepth, type CeremonyDialInputs } from "@deftai/directive-core/policy";
|
|
2
3
|
import { type SessionCeremonyTier } from "@deftai/directive-core/session";
|
|
3
4
|
export interface ParsedSessionStartArgs {
|
|
4
5
|
projectRoot: string;
|
|
@@ -10,6 +11,22 @@ export interface ParsedSessionStartArgs {
|
|
|
10
11
|
withNetwork: boolean;
|
|
11
12
|
/** #2992: cold (full) vs rearm (clock/HEAD refresh without fat path). */
|
|
12
13
|
ceremonyTier: SessionCeremonyTier;
|
|
14
|
+
/** #3214: optional dial inputs for ritual-depth selection. */
|
|
15
|
+
ceremonyDialInputs: CeremonyDialInputs;
|
|
16
|
+
/**
|
|
17
|
+
* #3214: force depth for this session only (does not persist policy).
|
|
18
|
+
* Applied as resolve inputs via a one-shot config override in run().
|
|
19
|
+
*/
|
|
20
|
+
ceremonyDepthOverride: CeremonyDepth | null;
|
|
21
|
+
/**
|
|
22
|
+
* #3266: host/CLI effort-budget cap fields for bank-the-pass guidance.
|
|
23
|
+
* Merged with DEFT_HOST_EFFORT_BUDGET JSON when present.
|
|
24
|
+
*/
|
|
25
|
+
effortBudgetHost: {
|
|
26
|
+
maxTurns?: number;
|
|
27
|
+
maxBudget?: number;
|
|
28
|
+
hardBudget?: boolean;
|
|
29
|
+
};
|
|
13
30
|
error?: string;
|
|
14
31
|
}
|
|
15
32
|
/** Parse session:start CLI args, mirroring scripts/session_start.py. */
|
package/dist/session-start.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
4
|
+
import { CEREMONY_DEPTHS, normalizeCeremonyModelTier, normalizeCeremonyProjectShape, normalizeCeremonyTaskSize, selectCeremonyDepth, } from "@deftai/directive-core/policy";
|
|
5
|
+
import { COLD_CEREMONY_TIER, parseDeferrals, READ_ONLY_POSTURE, REARM_CEREMONY_TIER, resolveProductionHostEffortDescriptor, ritualStatePath, runSessionStart, SESSION_CEREMONY_TIERS, } from "@deftai/directive-core/session";
|
|
6
|
+
function parseCeremonyDepth(raw) {
|
|
7
|
+
const value = raw.trim().toLowerCase();
|
|
8
|
+
if (CEREMONY_DEPTHS.includes(value)) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
5
13
|
function parseCeremonyTier(raw) {
|
|
6
14
|
const value = raw.trim().toLowerCase();
|
|
7
15
|
if (SESSION_CEREMONY_TIERS.includes(value)) {
|
|
@@ -19,7 +27,11 @@ export function parseArgs(argv) {
|
|
|
19
27
|
readOnly: false,
|
|
20
28
|
withNetwork: false,
|
|
21
29
|
ceremonyTier: COLD_CEREMONY_TIER,
|
|
30
|
+
ceremonyDialInputs: {},
|
|
31
|
+
ceremonyDepthOverride: null,
|
|
32
|
+
effortBudgetHost: {},
|
|
22
33
|
};
|
|
34
|
+
const dialInputs = {};
|
|
23
35
|
for (let i = 0; i < argv.length; i += 1) {
|
|
24
36
|
const arg = argv[i];
|
|
25
37
|
if (arg === "--json") {
|
|
@@ -86,10 +98,185 @@ export function parseArgs(argv) {
|
|
|
86
98
|
else if (arg?.startsWith("--defer=")) {
|
|
87
99
|
parsed.deferValues.push(arg.slice("--defer=".length));
|
|
88
100
|
}
|
|
101
|
+
else if (arg === "--task-size" || arg === "--ceremony-task-size") {
|
|
102
|
+
const value = argv[i + 1];
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
return { ...parsed, error: `argument ${arg}: expected one argument (S|M|L|XL)` };
|
|
105
|
+
}
|
|
106
|
+
const size = normalizeCeremonyTaskSize(value);
|
|
107
|
+
if (size === null) {
|
|
108
|
+
return {
|
|
109
|
+
...parsed,
|
|
110
|
+
error: `argument ${arg}: expected S|M|L|XL (or small|medium|large), got ${JSON.stringify(value)}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
dialInputs.taskSize = size;
|
|
114
|
+
i += 1;
|
|
115
|
+
}
|
|
116
|
+
else if (arg?.startsWith("--task-size=") || arg?.startsWith("--ceremony-task-size=")) {
|
|
117
|
+
const value = arg.slice(arg.indexOf("=") + 1);
|
|
118
|
+
const size = normalizeCeremonyTaskSize(value);
|
|
119
|
+
if (size === null) {
|
|
120
|
+
return {
|
|
121
|
+
...parsed,
|
|
122
|
+
error: `argument --task-size: expected S|M|L|XL, got ${JSON.stringify(value)}`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
dialInputs.taskSize = size;
|
|
126
|
+
}
|
|
127
|
+
else if (arg === "--model-tier" || arg === "--ceremony-model-tier") {
|
|
128
|
+
const value = argv[i + 1];
|
|
129
|
+
if (value === undefined) {
|
|
130
|
+
return {
|
|
131
|
+
...parsed,
|
|
132
|
+
error: `argument ${arg}: expected one argument (frontier|mid|low)`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const tier = normalizeCeremonyModelTier(value);
|
|
136
|
+
if (tier === null) {
|
|
137
|
+
return {
|
|
138
|
+
...parsed,
|
|
139
|
+
error: `argument ${arg}: expected frontier|mid|low, got ${JSON.stringify(value)}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
dialInputs.modelTier = tier;
|
|
143
|
+
i += 1;
|
|
144
|
+
}
|
|
145
|
+
else if (arg?.startsWith("--model-tier=") || arg?.startsWith("--ceremony-model-tier=")) {
|
|
146
|
+
const value = arg.slice(arg.indexOf("=") + 1);
|
|
147
|
+
const tier = normalizeCeremonyModelTier(value);
|
|
148
|
+
if (tier === null) {
|
|
149
|
+
return {
|
|
150
|
+
...parsed,
|
|
151
|
+
error: `argument --model-tier: expected frontier|mid|low, got ${JSON.stringify(value)}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
dialInputs.modelTier = tier;
|
|
155
|
+
}
|
|
156
|
+
else if (arg === "--project-shape" || arg === "--ceremony-project-shape") {
|
|
157
|
+
const value = argv[i + 1];
|
|
158
|
+
if (value === undefined) {
|
|
159
|
+
return {
|
|
160
|
+
...parsed,
|
|
161
|
+
error: `argument ${arg}: expected one argument (project|non-project)`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const shape = normalizeCeremonyProjectShape(value);
|
|
165
|
+
if (shape === null) {
|
|
166
|
+
return {
|
|
167
|
+
...parsed,
|
|
168
|
+
error: `argument ${arg}: expected project|non-project, got ${JSON.stringify(value)}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
dialInputs.projectShape = shape;
|
|
172
|
+
i += 1;
|
|
173
|
+
}
|
|
174
|
+
else if (arg?.startsWith("--project-shape=") ||
|
|
175
|
+
arg?.startsWith("--ceremony-project-shape=")) {
|
|
176
|
+
const value = arg.slice(arg.indexOf("=") + 1);
|
|
177
|
+
const shape = normalizeCeremonyProjectShape(value);
|
|
178
|
+
if (shape === null) {
|
|
179
|
+
return {
|
|
180
|
+
...parsed,
|
|
181
|
+
error: `argument --project-shape: expected project|non-project, got ${JSON.stringify(value)}`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
dialInputs.projectShape = shape;
|
|
185
|
+
}
|
|
186
|
+
else if (arg === "--ceremony-depth") {
|
|
187
|
+
const value = argv[i + 1];
|
|
188
|
+
if (value === undefined) {
|
|
189
|
+
return {
|
|
190
|
+
...parsed,
|
|
191
|
+
error: "argument --ceremony-depth: expected one argument (minimal|rapid|standard|elevated)",
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const depth = parseCeremonyDepth(value);
|
|
195
|
+
if (depth === null) {
|
|
196
|
+
return {
|
|
197
|
+
...parsed,
|
|
198
|
+
error: `argument --ceremony-depth: expected minimal|rapid|standard|elevated, got ${JSON.stringify(value)}`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
parsed.ceremonyDepthOverride = depth;
|
|
202
|
+
i += 1;
|
|
203
|
+
}
|
|
204
|
+
else if (arg?.startsWith("--ceremony-depth=")) {
|
|
205
|
+
const value = arg.slice("--ceremony-depth=".length);
|
|
206
|
+
const depth = parseCeremonyDepth(value);
|
|
207
|
+
if (depth === null) {
|
|
208
|
+
return {
|
|
209
|
+
...parsed,
|
|
210
|
+
error: `argument --ceremony-depth: expected minimal|rapid|standard|elevated, got ${JSON.stringify(value)}`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
parsed.ceremonyDepthOverride = depth;
|
|
214
|
+
}
|
|
215
|
+
else if (arg === "--max-turns") {
|
|
216
|
+
// #3266: harness hard turn budget for bank-the-pass guidance
|
|
217
|
+
const value = argv[i + 1];
|
|
218
|
+
if (value === undefined) {
|
|
219
|
+
return { ...parsed, error: "argument --max-turns: expected one argument" };
|
|
220
|
+
}
|
|
221
|
+
const n = Number(value);
|
|
222
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
223
|
+
return {
|
|
224
|
+
...parsed,
|
|
225
|
+
error: `argument --max-turns: expected non-negative number, got ${JSON.stringify(value)}`,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
parsed.effortBudgetHost.maxTurns = n;
|
|
229
|
+
i += 1;
|
|
230
|
+
}
|
|
231
|
+
else if (arg?.startsWith("--max-turns=")) {
|
|
232
|
+
const value = arg.slice("--max-turns=".length);
|
|
233
|
+
const n = Number(value);
|
|
234
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
235
|
+
return {
|
|
236
|
+
...parsed,
|
|
237
|
+
error: `argument --max-turns: expected non-negative number, got ${JSON.stringify(value)}`,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
parsed.effortBudgetHost.maxTurns = n;
|
|
241
|
+
}
|
|
242
|
+
else if (arg === "--max-budget") {
|
|
243
|
+
const value = argv[i + 1];
|
|
244
|
+
if (value === undefined) {
|
|
245
|
+
return { ...parsed, error: "argument --max-budget: expected one argument" };
|
|
246
|
+
}
|
|
247
|
+
const n = Number(value);
|
|
248
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
249
|
+
return {
|
|
250
|
+
...parsed,
|
|
251
|
+
error: `argument --max-budget: expected non-negative number, got ${JSON.stringify(value)}`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
parsed.effortBudgetHost.maxBudget = n;
|
|
255
|
+
i += 1;
|
|
256
|
+
}
|
|
257
|
+
else if (arg?.startsWith("--max-budget=")) {
|
|
258
|
+
const value = arg.slice("--max-budget=".length);
|
|
259
|
+
const n = Number(value);
|
|
260
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
261
|
+
return {
|
|
262
|
+
...parsed,
|
|
263
|
+
error: `argument --max-budget: expected non-negative number, got ${JSON.stringify(value)}`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
parsed.effortBudgetHost.maxBudget = n;
|
|
267
|
+
}
|
|
268
|
+
else if (arg === "--hard-budget") {
|
|
269
|
+
parsed.effortBudgetHost.hardBudget = true;
|
|
270
|
+
}
|
|
89
271
|
else {
|
|
90
272
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
91
273
|
}
|
|
92
274
|
}
|
|
275
|
+
parsed.ceremonyDialInputs = {
|
|
276
|
+
taskSize: dialInputs.taskSize ?? null,
|
|
277
|
+
modelTier: dialInputs.modelTier ?? null,
|
|
278
|
+
projectShape: dialInputs.projectShape ?? null,
|
|
279
|
+
};
|
|
93
280
|
return parsed;
|
|
94
281
|
}
|
|
95
282
|
/** Native session:start handler (#2032 — replaces framework-commands Python bridge). */
|
|
@@ -117,14 +304,38 @@ export function run(argv) {
|
|
|
117
304
|
}
|
|
118
305
|
return true;
|
|
119
306
|
});
|
|
307
|
+
// #3266: production host adapter — native harness env + DEFT_HOST_EFFORT_BUDGET + CLI flags.
|
|
308
|
+
const hostDescriptor = {
|
|
309
|
+
...resolveProductionHostEffortDescriptor(process.env),
|
|
310
|
+
};
|
|
311
|
+
if (args.effortBudgetHost.maxTurns !== undefined) {
|
|
312
|
+
hostDescriptor.maxTurns = args.effortBudgetHost.maxTurns;
|
|
313
|
+
}
|
|
314
|
+
if (args.effortBudgetHost.maxBudget !== undefined) {
|
|
315
|
+
hostDescriptor.maxBudget = args.effortBudgetHost.maxBudget;
|
|
316
|
+
}
|
|
317
|
+
if (args.effortBudgetHost.hardBudget === true) {
|
|
318
|
+
hostDescriptor.hardBudget = true;
|
|
319
|
+
}
|
|
120
320
|
let result;
|
|
121
321
|
try {
|
|
322
|
+
// #3214: --ceremony-depth forces this session only (not persisted to policy).
|
|
122
323
|
result = runSessionStart(projectRoot, {
|
|
123
324
|
deferrals,
|
|
124
325
|
writeHistory: !args.noHistory,
|
|
125
326
|
posture: args.readOnly ? READ_ONLY_POSTURE : undefined,
|
|
126
327
|
allowOptionalNetwork: args.withNetwork ? true : undefined,
|
|
127
328
|
ceremonyTier: args.ceremonyTier,
|
|
329
|
+
ceremonyDialInputs: args.ceremonyDialInputs,
|
|
330
|
+
effortBudgetSeams: { hostDescriptor, environ: process.env },
|
|
331
|
+
...(args.ceremonyDepthOverride !== null
|
|
332
|
+
? {
|
|
333
|
+
ceremonyDial: selectCeremonyDepth({
|
|
334
|
+
config: { enabled: true, override: args.ceremonyDepthOverride },
|
|
335
|
+
inputs: args.ceremonyDialInputs,
|
|
336
|
+
}),
|
|
337
|
+
}
|
|
338
|
+
: {}),
|
|
128
339
|
});
|
|
129
340
|
}
|
|
130
341
|
finally {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface ParsedArgs {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
repo: string | null;
|
|
5
|
+
tip: string | null;
|
|
6
|
+
quiet: boolean;
|
|
7
|
+
skipGh: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Parse verify-completed-tracked CLI args (#3264). */
|
|
11
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
12
|
+
/** Run the gate and return the process exit code. */
|
|
13
|
+
export declare function run(argv: string[]): number;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=verify-completed-tracked.d.ts.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { evaluateCompletedTracked } from "@deftai/directive-core/lifecycle";
|
|
5
|
+
/** Parse verify-completed-tracked CLI args (#3264). */
|
|
6
|
+
export function parseArgs(argv) {
|
|
7
|
+
const parsed = {
|
|
8
|
+
projectRoot: ".",
|
|
9
|
+
repo: null,
|
|
10
|
+
tip: null,
|
|
11
|
+
quiet: false,
|
|
12
|
+
skipGh: false,
|
|
13
|
+
};
|
|
14
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
15
|
+
const arg = argv[i];
|
|
16
|
+
if (arg === "--quiet") {
|
|
17
|
+
parsed.quiet = true;
|
|
18
|
+
}
|
|
19
|
+
else if (arg === "--skip-gh") {
|
|
20
|
+
parsed.skipGh = true;
|
|
21
|
+
}
|
|
22
|
+
else if (arg === "--project-root") {
|
|
23
|
+
const value = argv[i + 1];
|
|
24
|
+
if (value === undefined) {
|
|
25
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
26
|
+
}
|
|
27
|
+
parsed.projectRoot = value;
|
|
28
|
+
i += 1;
|
|
29
|
+
}
|
|
30
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
31
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
32
|
+
}
|
|
33
|
+
else if (arg === "--repo") {
|
|
34
|
+
const value = argv[i + 1];
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
return { ...parsed, error: "argument --repo: expected one argument" };
|
|
37
|
+
}
|
|
38
|
+
parsed.repo = value;
|
|
39
|
+
i += 1;
|
|
40
|
+
}
|
|
41
|
+
else if (arg?.startsWith("--repo=")) {
|
|
42
|
+
parsed.repo = arg.slice("--repo=".length);
|
|
43
|
+
}
|
|
44
|
+
else if (arg === "--tip") {
|
|
45
|
+
const value = argv[i + 1];
|
|
46
|
+
if (value === undefined) {
|
|
47
|
+
return { ...parsed, error: "argument --tip: expected one argument" };
|
|
48
|
+
}
|
|
49
|
+
parsed.tip = value;
|
|
50
|
+
i += 1;
|
|
51
|
+
}
|
|
52
|
+
else if (arg?.startsWith("--tip=")) {
|
|
53
|
+
parsed.tip = arg.slice("--tip=".length);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
/** Run the gate and return the process exit code. */
|
|
62
|
+
export function run(argv) {
|
|
63
|
+
const args = parseArgs(argv);
|
|
64
|
+
if (args.error !== undefined) {
|
|
65
|
+
process.stderr.write(`verify_completed_tracked: ${args.error}\n`);
|
|
66
|
+
return 2;
|
|
67
|
+
}
|
|
68
|
+
const projectRoot = resolve(args.projectRoot);
|
|
69
|
+
const result = evaluateCompletedTracked(projectRoot, {
|
|
70
|
+
quiet: args.quiet,
|
|
71
|
+
repo: args.repo,
|
|
72
|
+
tip: args.tip,
|
|
73
|
+
skipGh: args.skipGh,
|
|
74
|
+
});
|
|
75
|
+
if (result.message.length > 0) {
|
|
76
|
+
if (result.stream === "stdout") {
|
|
77
|
+
process.stdout.write(`${result.message}\n`);
|
|
78
|
+
}
|
|
79
|
+
else if (result.stream === "stderr") {
|
|
80
|
+
process.stderr.write(`${result.message}\n`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return result.code;
|
|
84
|
+
}
|
|
85
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
86
|
+
process.exit(run(process.argv.slice(2)));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=verify-completed-tracked.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface ParsedArgs {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
xbriefPath: string | null;
|
|
5
|
+
quiet: boolean;
|
|
6
|
+
captureOnly: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Parse verify-literal-ac CLI args. */
|
|
10
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
11
|
+
/** Run the gate and return the process exit code. */
|
|
12
|
+
export declare function run(argv: string[]): number;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=verify-literal-ac.d.ts.map
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI: task verify:literal-ac — run stored literal acceptance commands verbatim (#3267).
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { evaluateLiteralAcceptanceFromPath, formatRejectedLedger, resolveLiteralAcceptanceDetailed, } from "@deftai/directive-core/literal-acceptance";
|
|
9
|
+
/** Parse verify-literal-ac CLI args. */
|
|
10
|
+
export function parseArgs(argv) {
|
|
11
|
+
const parsed = {
|
|
12
|
+
projectRoot: ".",
|
|
13
|
+
xbriefPath: null,
|
|
14
|
+
quiet: false,
|
|
15
|
+
captureOnly: false,
|
|
16
|
+
};
|
|
17
|
+
const positionals = [];
|
|
18
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
+
const arg = argv[i];
|
|
20
|
+
if (arg === "--quiet") {
|
|
21
|
+
parsed.quiet = true;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === "--capture-only") {
|
|
24
|
+
parsed.captureOnly = true;
|
|
25
|
+
}
|
|
26
|
+
else if (arg === "--project-root") {
|
|
27
|
+
const value = argv[i + 1];
|
|
28
|
+
if (value === undefined) {
|
|
29
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
30
|
+
}
|
|
31
|
+
parsed.projectRoot = value;
|
|
32
|
+
i += 1;
|
|
33
|
+
}
|
|
34
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
35
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
36
|
+
}
|
|
37
|
+
else if (arg === "--xbrief" || arg === "--vbrief") {
|
|
38
|
+
const value = argv[i + 1];
|
|
39
|
+
if (value === undefined) {
|
|
40
|
+
return { ...parsed, error: `argument ${arg}: expected one argument` };
|
|
41
|
+
}
|
|
42
|
+
parsed.xbriefPath = value;
|
|
43
|
+
i += 1;
|
|
44
|
+
}
|
|
45
|
+
else if (arg?.startsWith("--xbrief=") || arg?.startsWith("--vbrief=")) {
|
|
46
|
+
parsed.xbriefPath = arg.slice(arg.indexOf("=") + 1);
|
|
47
|
+
}
|
|
48
|
+
else if (arg?.startsWith("-")) {
|
|
49
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
50
|
+
}
|
|
51
|
+
else if (arg !== undefined) {
|
|
52
|
+
positionals.push(arg);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (parsed.xbriefPath === null && positionals.length > 0) {
|
|
56
|
+
parsed.xbriefPath = positionals[0] ?? null;
|
|
57
|
+
}
|
|
58
|
+
return parsed;
|
|
59
|
+
}
|
|
60
|
+
function findActiveXbrief(projectRoot) {
|
|
61
|
+
for (const dirName of ["xbrief", "vbrief"]) {
|
|
62
|
+
const active = join(projectRoot, dirName, "active");
|
|
63
|
+
if (!existsSync(active))
|
|
64
|
+
continue;
|
|
65
|
+
let names = [];
|
|
66
|
+
try {
|
|
67
|
+
names = readdirSync(active).filter((n) => n.endsWith(".xbrief.json") || n.endsWith(".vbrief.json"));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (names.length === 1) {
|
|
73
|
+
return join(active, names[0]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
function asRecord(value) {
|
|
79
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/** Run the gate and return the process exit code. */
|
|
85
|
+
export function run(argv) {
|
|
86
|
+
const args = parseArgs(argv);
|
|
87
|
+
if (args.error !== undefined) {
|
|
88
|
+
process.stderr.write(`verify_literal_ac: ${args.error}\n`);
|
|
89
|
+
return 2;
|
|
90
|
+
}
|
|
91
|
+
const projectRoot = resolve(args.projectRoot);
|
|
92
|
+
let xbriefPath = args.xbriefPath !== null ? resolve(projectRoot, args.xbriefPath) : null;
|
|
93
|
+
if (xbriefPath === null) {
|
|
94
|
+
xbriefPath = findActiveXbrief(projectRoot);
|
|
95
|
+
}
|
|
96
|
+
if (xbriefPath === null) {
|
|
97
|
+
process.stderr.write("verify_literal_ac: pass an xBRIEF path or ensure exactly one artifact in xbrief/active/\n" +
|
|
98
|
+
" Usage: task verify:literal-ac -- <path-to-active.xbrief.json>\n" +
|
|
99
|
+
" Refs #3267 literal acceptance-command verification\n");
|
|
100
|
+
return 2;
|
|
101
|
+
}
|
|
102
|
+
if (args.captureOnly) {
|
|
103
|
+
try {
|
|
104
|
+
const data = asRecord(JSON.parse(readFileSync(xbriefPath, "utf8")));
|
|
105
|
+
if (data === null) {
|
|
106
|
+
process.stderr.write("verify_literal_ac: xBRIEF top-level is not an object\n");
|
|
107
|
+
return 2;
|
|
108
|
+
}
|
|
109
|
+
const plan = asRecord(data.plan);
|
|
110
|
+
if (plan === null) {
|
|
111
|
+
process.stderr.write("verify_literal_ac: xBRIEF missing plan object\n");
|
|
112
|
+
return 2;
|
|
113
|
+
}
|
|
114
|
+
const resolved = resolveLiteralAcceptanceDetailed(plan, { captureFromNarratives: true });
|
|
115
|
+
const payload = {
|
|
116
|
+
xbrief: xbriefPath,
|
|
117
|
+
count: resolved.commands.length,
|
|
118
|
+
rejected_count: resolved.rejected.length,
|
|
119
|
+
commands: resolved.commands.map((c) => ({
|
|
120
|
+
command: c.command,
|
|
121
|
+
source: c.source,
|
|
122
|
+
sourceSpan: c.sourceSpan ?? null,
|
|
123
|
+
cwd: c.cwd ?? null,
|
|
124
|
+
expectedExitCode: c.expectedExitCode ?? 0,
|
|
125
|
+
})),
|
|
126
|
+
rejected: resolved.rejected.map((r) => ({
|
|
127
|
+
command: r.command,
|
|
128
|
+
reason: r.reason,
|
|
129
|
+
sourceSpan: r.sourceSpan ?? null,
|
|
130
|
+
})),
|
|
131
|
+
};
|
|
132
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
133
|
+
if (resolved.rejected.length > 0) {
|
|
134
|
+
process.stderr.write(`${formatRejectedLedger(resolved.rejected)}\n`);
|
|
135
|
+
}
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
140
|
+
process.stderr.write(`verify_literal_ac: ${msg}\n`);
|
|
141
|
+
return 2;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const result = evaluateLiteralAcceptanceFromPath(xbriefPath, {
|
|
145
|
+
projectRoot,
|
|
146
|
+
quiet: args.quiet,
|
|
147
|
+
});
|
|
148
|
+
if (result.message.length > 0) {
|
|
149
|
+
if (result.ok) {
|
|
150
|
+
process.stdout.write(`${result.message}\n`);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
process.stderr.write(`${result.message}\n`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return result.code;
|
|
157
|
+
}
|
|
158
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
159
|
+
process.exit(run(process.argv.slice(2)));
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=verify-literal-ac.js.map
|
|
@@ -148,6 +148,7 @@ export function run(argv) {
|
|
|
148
148
|
allocationContext: allocationContextText,
|
|
149
149
|
allowDirty: args.allowDirty,
|
|
150
150
|
parsed,
|
|
151
|
+
projectRoot,
|
|
151
152
|
});
|
|
152
153
|
if (result.exitCode === 0 && !args.skipRouting) {
|
|
153
154
|
const provider = resolveDispatchProvider(process.env);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.100.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/",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"provenance": true
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@deftai/directive-core": "^0.
|
|
38
|
-
"@deftai/directive-content": "^0.
|
|
37
|
+
"@deftai/directive-core": "^0.100.0",
|
|
38
|
+
"@deftai/directive-content": "^0.100.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b"
|