@deftai/directive 0.107.0 → 0.109.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/dispatch.d.ts +1 -1
- package/dist/dispatch.js +87 -51
- package/dist/doctor.js +6 -0
- package/dist/occupancy-grant.d.ts +18 -0
- package/dist/occupancy-grant.js +120 -0
- package/dist/occupancy-heartbeat.d.ts +8 -0
- package/dist/occupancy-heartbeat.js +62 -0
- package/dist/occupancy-release.d.ts +1 -0
- package/dist/occupancy-release.js +26 -2
- package/dist/occupancy-steal.d.ts +1 -0
- package/dist/occupancy-steal.js +32 -4
- package/dist/render-cli/prd-render-cli.js +6 -10
- package/dist/session-ready.d.ts +2 -0
- package/dist/session-ready.js +37 -5
- package/dist/session-start.d.ts +2 -0
- package/dist/session-start.js +39 -6
- package/dist/toolchain-check.d.ts +1 -0
- package/dist/toolchain-check.js +41 -2
- package/dist/verify-orphan-active.d.ts +2 -0
- package/dist/verify-orphan-active.js +30 -0
- package/dist/verify-pr-closeout-attestable.d.ts +14 -0
- package/dist/verify-pr-closeout-attestable.js +96 -0
- package/dist/verify-source-cli/verify-closing-keywords.d.ts +35 -0
- package/dist/verify-source-cli/verify-closing-keywords.js +139 -0
- package/dist/verify-source-cli/verify-consumer-hard-stops.d.ts +16 -0
- package/dist/verify-source-cli/verify-consumer-hard-stops.js +99 -0
- package/dist/verify-source-cli/verify-deposit-closure.d.ts +12 -0
- package/dist/verify-source-cli/verify-deposit-closure.js +52 -0
- package/dist/verify-source-cli/verify-semantic-single-source.d.ts +11 -0
- package/dist/verify-source-cli/verify-semantic-single-source.js +49 -0
- package/dist/verify-subagent-alive.js +5 -1
- package/package.json +3 -3
package/dist/dispatch.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ 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", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "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", "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-telemetry-coverage", "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-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-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"];
|
|
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", "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-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", "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-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", "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-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-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
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). */
|
package/dist/dispatch.js
CHANGED
|
@@ -8,12 +8,11 @@ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, readSync
|
|
|
8
8
|
import { homedir, tmpdir } from "node:os";
|
|
9
9
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
10
|
import { engineInfo, userConfig } from "@deftai/directive-core";
|
|
11
|
-
import { assertWriteTargetSafe } from "@deftai/directive-core/dist/fs/projection-containment.js";
|
|
12
11
|
import { parseInitArgv, runInitDepositCli } from "@deftai/directive-core/init-deposit";
|
|
13
12
|
import { appendAuditLog, disclosureLine, migrateLegacyPolicyKey, PLAN_POLICY_KEY, POLICY_AUDIT_NOOP_STDOUT, policyColonInvocation, policySetInvocation, projectDefinitionPath, resolvePolicy, resolveWipCap, setPolicy, stampChangedToken, } from "@deftai/directive-core/policy";
|
|
14
13
|
import { defaultWhich } from "@deftai/directive-core/scm";
|
|
15
14
|
import { KNOWN_SUBAGENT_BACKEND_IDS, probeSubagentBackends, resolveSwarmSubagentBackend, } from "@deftai/directive-core/swarm";
|
|
16
|
-
import {
|
|
15
|
+
import { withProjectDefinitionMutation, } from "@deftai/directive-core/vbrief-build";
|
|
17
16
|
const HANDLER_KEYS = [
|
|
18
17
|
"run",
|
|
19
18
|
"main",
|
|
@@ -76,6 +75,8 @@ export const CLI_MODULE_VERBS = [
|
|
|
76
75
|
"session-ready",
|
|
77
76
|
"occupancy-steal",
|
|
78
77
|
"occupancy-release",
|
|
78
|
+
"occupancy-heartbeat",
|
|
79
|
+
"occupancy-grant",
|
|
79
80
|
"plan-sequence",
|
|
80
81
|
"slice",
|
|
81
82
|
"subagent-monitor",
|
|
@@ -122,7 +123,11 @@ export const CLI_MODULE_VERBS = [
|
|
|
122
123
|
"verify-contained-writes",
|
|
123
124
|
"verify-telemetry-coverage",
|
|
124
125
|
"verify-content-manifest",
|
|
126
|
+
"verify-deposit-closure",
|
|
127
|
+
"verify-consumer-hard-stops",
|
|
128
|
+
"verify-closing-keywords",
|
|
125
129
|
"verify-skill-external-fetch-gate",
|
|
130
|
+
"verify-semantic-single-source",
|
|
126
131
|
"verify-contract-drift",
|
|
127
132
|
"verify-cursor-tier1",
|
|
128
133
|
"verify-openclaw-tier1",
|
|
@@ -142,6 +147,7 @@ export const CLI_MODULE_VERBS = [
|
|
|
142
147
|
"verify-tools",
|
|
143
148
|
"verify-wip-cap",
|
|
144
149
|
"verify-orphan-active",
|
|
150
|
+
"verify-pr-closeout-attestable",
|
|
145
151
|
"verify-lifecycle-visible",
|
|
146
152
|
"verify-completed-tracked",
|
|
147
153
|
"verify-completed-write-guard",
|
|
@@ -287,6 +293,7 @@ export const VERB_ALIASES = {
|
|
|
287
293
|
"verify:vbrief-conformance": "vbrief-validate",
|
|
288
294
|
"verify:wip-cap": "verify-wip-cap",
|
|
289
295
|
"verify:orphan-active": "verify-orphan-active",
|
|
296
|
+
"verify:pr-closeout-attestable": "verify-pr-closeout-attestable",
|
|
290
297
|
"verify:lifecycle-visible": "verify-lifecycle-visible",
|
|
291
298
|
"verify:completed-tracked": "verify-completed-tracked",
|
|
292
299
|
"verify:completed-write-guard": "verify-completed-write-guard",
|
|
@@ -330,7 +337,11 @@ export const VERB_ALIASES = {
|
|
|
330
337
|
"verify:contained-writes": "verify-contained-writes",
|
|
331
338
|
"verify:telemetry-coverage": "verify-telemetry-coverage",
|
|
332
339
|
"verify:content-manifest": "verify-content-manifest",
|
|
340
|
+
"verify:deposit-closure": "verify-deposit-closure",
|
|
341
|
+
"verify:consumer-hard-stops": "verify-consumer-hard-stops",
|
|
342
|
+
"verify:closing-keywords": "verify-closing-keywords",
|
|
333
343
|
"verify:skill-external-fetch-gate": "verify-skill-external-fetch-gate",
|
|
344
|
+
"verify:semantic-single-source": "verify-semantic-single-source",
|
|
334
345
|
"verify:contract-drift": "verify-contract-drift",
|
|
335
346
|
"verify:cursor-tier1": "verify-cursor-tier1",
|
|
336
347
|
"verify:openclaw-tier1": "verify-openclaw-tier1",
|
|
@@ -369,6 +380,8 @@ export const VERB_ALIASES = {
|
|
|
369
380
|
"session:ready": "session-ready",
|
|
370
381
|
"occupancy:steal": "occupancy-steal",
|
|
371
382
|
"occupancy:release": "occupancy-release",
|
|
383
|
+
"occupancy:heartbeat": "occupancy-heartbeat",
|
|
384
|
+
"occupancy:grant": "occupancy-grant",
|
|
372
385
|
"session:end": "occupancy-release",
|
|
373
386
|
...FRESHNESS_COLON_ALIASES,
|
|
374
387
|
"lifecycle:event": "lifecycle-event",
|
|
@@ -408,7 +421,11 @@ const SUBDIR_CLI_STEMS = {
|
|
|
408
421
|
"verify-contained-writes": "verify-source-cli/verify-contained-writes",
|
|
409
422
|
"verify-telemetry-coverage": "verify-source-cli/verify-telemetry-coverage",
|
|
410
423
|
"verify-content-manifest": "verify-source-cli/verify-content-manifest",
|
|
424
|
+
"verify-deposit-closure": "verify-source-cli/verify-deposit-closure",
|
|
425
|
+
"verify-consumer-hard-stops": "verify-source-cli/verify-consumer-hard-stops",
|
|
426
|
+
"verify-closing-keywords": "verify-source-cli/verify-closing-keywords",
|
|
411
427
|
"verify-skill-external-fetch-gate": "verify-source-cli/verify-skill-external-fetch-gate",
|
|
428
|
+
"verify-semantic-single-source": "verify-source-cli/verify-semantic-single-source",
|
|
412
429
|
"verify-contract-drift": "verify-source-cli/verify-contract-drift",
|
|
413
430
|
"verify-cursor-tier1": "verify-source-cli/verify-cursor-tier1",
|
|
414
431
|
"verify-openclaw-tier1": "verify-source-cli/verify-openclaw-tier1",
|
|
@@ -2104,25 +2121,26 @@ function parsePolicySetArgs(argv) {
|
|
|
2104
2121
|
}
|
|
2105
2122
|
return args;
|
|
2106
2123
|
}
|
|
2107
|
-
/**
|
|
2108
|
-
|
|
2109
|
-
|
|
2124
|
+
/**
|
|
2125
|
+
* Load PROJECT-DEFINITION for an in-place typed-field write (mirrors the
|
|
2126
|
+
* .setdefault chain). Reads the artifact the mutation lock captured (#3796) so
|
|
2127
|
+
* these CLI writers can no longer resolve, read, and write a PROJECT-DEFINITION
|
|
2128
|
+
* outside the shared mutation lock.
|
|
2129
|
+
*/
|
|
2130
|
+
function loadProjectDefinitionForWrite(mutation) {
|
|
2131
|
+
const path = mutation.artifactPath;
|
|
2110
2132
|
if (!existsSync(path)) {
|
|
2111
|
-
throw new PolicySetError(`PROJECT-DEFINITION not found at ${
|
|
2133
|
+
throw new PolicySetError(`PROJECT-DEFINITION not found at ${mutation.artifactLabel}`, "not-found");
|
|
2112
2134
|
}
|
|
2113
|
-
let
|
|
2135
|
+
let data;
|
|
2114
2136
|
try {
|
|
2115
|
-
|
|
2137
|
+
// The shared loader rejects unreadable, malformed, and non-object top-level
|
|
2138
|
+
// payloads; every one of those is a config error for the CLI writers.
|
|
2139
|
+
data = mutation.load();
|
|
2116
2140
|
}
|
|
2117
2141
|
catch (err) {
|
|
2118
|
-
throw new PolicySetError(
|
|
2142
|
+
throw new PolicySetError(err instanceof Error ? err.message : String(err), "config");
|
|
2119
2143
|
}
|
|
2120
|
-
// JSON.parse can yield a non-object top level (null / array / scalar) without
|
|
2121
|
-
// throwing; reject it before the .plan/.policy property chain dereferences it.
|
|
2122
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
2123
|
-
throw new PolicySetError(`PROJECT-DEFINITION at ${path} is not a JSON object`, "config");
|
|
2124
|
-
}
|
|
2125
|
-
const data = parsed;
|
|
2126
2144
|
let plan = data.plan;
|
|
2127
2145
|
if (plan === undefined) {
|
|
2128
2146
|
plan = {};
|
|
@@ -2141,45 +2159,47 @@ function loadProjectDefinitionForWrite(projectRoot) {
|
|
|
2141
2159
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
2142
2160
|
throw new PolicySetError("plan.policy is not an object", "config");
|
|
2143
2161
|
}
|
|
2144
|
-
return {
|
|
2162
|
+
return { data, policyBlock: policy, legacyMigrated };
|
|
2145
2163
|
}
|
|
2146
2164
|
/** Write plan.policy.wipCap in place + append the audit row (mirrors set_wip_cap). */
|
|
2147
2165
|
function writeWipCap(projectRoot, cap, actor, note) {
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2166
|
+
return withProjectDefinitionMutation(projectRoot, (mutation) => {
|
|
2167
|
+
const { data, policyBlock, legacyMigrated } = loadProjectDefinitionForWrite(mutation);
|
|
2168
|
+
const previous = policyBlock.wipCap;
|
|
2169
|
+
policyBlock.wipCap = cap;
|
|
2170
|
+
const changed = previous !== cap || legacyMigrated;
|
|
2171
|
+
const parts = [`actor=${actor}`, `wipCap=${cap}`, `previous=${pyRepr(previous)}`];
|
|
2172
|
+
if (note)
|
|
2173
|
+
parts.push(`note=${sanitizeNote(note)}`);
|
|
2174
|
+
const auditEntry = stampChangedToken(parts.join(" "), changed);
|
|
2175
|
+
if (changed) {
|
|
2176
|
+
mutation.persist(data);
|
|
2177
|
+
}
|
|
2178
|
+
appendAuditLog(projectRoot, auditEntry, changed);
|
|
2179
|
+
return { changed, auditEntry };
|
|
2180
|
+
});
|
|
2162
2181
|
}
|
|
2163
2182
|
/** Write plan.policy.swarmSubagentBackend in place + append the audit row. */
|
|
2164
2183
|
function writeSubagentBackend(projectRoot, backendId, actor, note) {
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2184
|
+
return withProjectDefinitionMutation(projectRoot, (mutation) => {
|
|
2185
|
+
const { data, policyBlock, legacyMigrated } = loadProjectDefinitionForWrite(mutation);
|
|
2186
|
+
const previous = policyBlock.swarmSubagentBackend;
|
|
2187
|
+
policyBlock.swarmSubagentBackend = backendId;
|
|
2188
|
+
const changed = previous !== backendId || legacyMigrated;
|
|
2189
|
+
const parts = [
|
|
2190
|
+
`actor=${actor}`,
|
|
2191
|
+
`swarmSubagentBackend=${backendId}`,
|
|
2192
|
+
`previous=${pyRepr(previous)}`,
|
|
2193
|
+
];
|
|
2194
|
+
if (note)
|
|
2195
|
+
parts.push(`note=${sanitizeNote(note)}`);
|
|
2196
|
+
const auditEntry = stampChangedToken(parts.join(" "), changed);
|
|
2197
|
+
if (changed) {
|
|
2198
|
+
mutation.persist(data);
|
|
2199
|
+
}
|
|
2200
|
+
appendAuditLog(projectRoot, auditEntry, changed);
|
|
2201
|
+
return { changed, auditEntry };
|
|
2202
|
+
});
|
|
2183
2203
|
}
|
|
2184
2204
|
/** Serialise the probe output for `subagent-backends --format json`. */
|
|
2185
2205
|
function subagentBackendsToJson(backends) {
|
|
@@ -2617,19 +2637,30 @@ const CURATED_HELP_GROUPS = [
|
|
|
2617
2637
|
{
|
|
2618
2638
|
title: "Session & ritual",
|
|
2619
2639
|
commands: [
|
|
2620
|
-
{
|
|
2640
|
+
{
|
|
2641
|
+
name: "session:start",
|
|
2642
|
+
summary: "Claim occupancy and record ritual state for one session owner",
|
|
2643
|
+
},
|
|
2621
2644
|
{
|
|
2622
2645
|
name: "session:ready",
|
|
2623
2646
|
summary: "One-shot recovery to gated write-ready (session + ritual + cache)",
|
|
2624
2647
|
},
|
|
2625
2648
|
{
|
|
2626
2649
|
name: "occupancy:steal",
|
|
2627
|
-
summary: "
|
|
2650
|
+
summary: "Replace only the live lease; use session:start --steal to align ritual",
|
|
2628
2651
|
},
|
|
2629
2652
|
{
|
|
2630
2653
|
name: "occupancy:release",
|
|
2631
2654
|
summary: "Release this worktree occupancy lease (owner live, or expired residue)",
|
|
2632
2655
|
},
|
|
2656
|
+
{
|
|
2657
|
+
name: "occupancy:heartbeat",
|
|
2658
|
+
summary: "Refresh your own live lease during long quiet stretches (never claims)",
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
name: "occupancy:grant",
|
|
2662
|
+
summary: "Admit a dispatched child to your lease for writes (--revoke withdraws)",
|
|
2663
|
+
},
|
|
2633
2664
|
{
|
|
2634
2665
|
name: "session:end",
|
|
2635
2666
|
summary: "End this mutation session by releasing occupancy (same as occupancy:release)",
|
|
@@ -2795,6 +2826,9 @@ export async function dispatch(argv, io = defaultIo()) {
|
|
|
2795
2826
|
const planSequenceSubcommand = verb !== undefined ? PLAN_SEQUENCE_ALIAS_SUBCOMMANDS[verb] : undefined;
|
|
2796
2827
|
const productSignalSubcommand = verb !== undefined ? PRODUCT_SIGNAL_ALIAS_SUBCOMMANDS[verb] : undefined;
|
|
2797
2828
|
const freshnessSubcommand = verb !== undefined ? FRESHNESS_ALIAS_SUBCOMMANDS[verb] : undefined;
|
|
2829
|
+
const vbriefValidateSubcommand = verb === "verify:vbrief-conformance" && canonical === "vbrief-validate"
|
|
2830
|
+
? "conformance"
|
|
2831
|
+
: undefined;
|
|
2798
2832
|
const handlerArgv = canonical === "framework-commands" && verb !== undefined && verb !== canonical
|
|
2799
2833
|
? [verb, ...rest]
|
|
2800
2834
|
: triageSubcommand !== undefined && canonical === "triage-actions"
|
|
@@ -2811,7 +2845,9 @@ export async function dispatch(argv, io = defaultIo()) {
|
|
|
2811
2845
|
? [productSignalSubcommand, ...rest]
|
|
2812
2846
|
: freshnessSubcommand !== undefined && canonical === "freshness-report"
|
|
2813
2847
|
? [freshnessSubcommand, ...rest]
|
|
2814
|
-
:
|
|
2848
|
+
: vbriefValidateSubcommand !== undefined
|
|
2849
|
+
? [vbriefValidateSubcommand, ...rest]
|
|
2850
|
+
: rest;
|
|
2815
2851
|
return await invokeHandler(handler, handlerArgv);
|
|
2816
2852
|
}
|
|
2817
2853
|
catch (err) {
|
package/dist/doctor.js
CHANGED
|
@@ -6,6 +6,7 @@ import { resolveContentPackageRoot } from "@deftai/directive-core/dist/content-r
|
|
|
6
6
|
import { parseDoctorFlags } from "@deftai/directive-core/dist/doctor/flags.js";
|
|
7
7
|
import { cmdDoctor } from "@deftai/directive-core/dist/doctor/main.js";
|
|
8
8
|
import { findPackageAbsentDepositPathsSync } from "@deftai/directive-core/dist/init-deposit/hygiene.js";
|
|
9
|
+
import { evaluateInstalledDepositClosure, renderDeclaredDepositClosureLine, } from "@deftai/directive-core/dist/validate-content/deposit-required.js";
|
|
9
10
|
import { renderPrecutoverLine } from "@deftai/directive-core/dist/vbrief-validate/precutover.js";
|
|
10
11
|
import { renderStaleHeaderLine, renderXbriefMigrationLine, } from "@deftai/directive-core/xbrief-migrate";
|
|
11
12
|
/** Compare `.deft/core/` against `@deftai/directive-content` (#2804). */
|
|
@@ -56,9 +57,14 @@ export function run(argv) {
|
|
|
56
57
|
process.stdout.write(`${renderXbriefMigrationLine(projectRoot)}\n`);
|
|
57
58
|
process.stdout.write(`${renderStaleHeaderLine(projectRoot)}\n`);
|
|
58
59
|
process.stdout.write(`${renderDepositFileSetHygieneLine(projectRoot, depositResult)}\n`);
|
|
60
|
+
const closure = evaluateInstalledDepositClosure(projectRoot);
|
|
61
|
+
process.stdout.write(`${renderDeclaredDepositClosureLine(closure)}\n`);
|
|
59
62
|
if (flags.full && !depositResult.skipped && depositResult.absent.length > 0) {
|
|
60
63
|
depositHygieneExit = 1;
|
|
61
64
|
}
|
|
65
|
+
if (flags.full && !closure.skipped && (closure.missing.length > 0 || closure.error !== null)) {
|
|
66
|
+
depositHygieneExit = 1;
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
69
|
const doctorExit = cmdDoctor(argv);
|
|
64
70
|
return Math.max(depositHygieneExit, doctorExit);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type OccupancyJoinProtocol } from "@deftai/directive-core/session";
|
|
3
|
+
export interface GrantArgs {
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
childSessionId?: string;
|
|
7
|
+
role?: string;
|
|
8
|
+
worktree?: string;
|
|
9
|
+
ttlMinutes?: number;
|
|
10
|
+
host?: string;
|
|
11
|
+
address?: string;
|
|
12
|
+
joinProtocol?: OccupancyJoinProtocol;
|
|
13
|
+
revoke: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function parseArgs(argv: readonly string[]): GrantArgs;
|
|
17
|
+
export declare function run(argv: readonly string[]): number;
|
|
18
|
+
//# sourceMappingURL=occupancy-grant.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { grantOccupancyMembership, OCCUPANCY_JOIN_PROTOCOLS, revokeOccupancyMembership, } from "@deftai/directive-core/session";
|
|
4
|
+
const VALUE_FLAGS = [
|
|
5
|
+
"--project-root",
|
|
6
|
+
"--session-id",
|
|
7
|
+
"--child-session-id",
|
|
8
|
+
"--role",
|
|
9
|
+
"--worktree",
|
|
10
|
+
"--ttl-minutes",
|
|
11
|
+
"--host",
|
|
12
|
+
"--address",
|
|
13
|
+
"--join-protocol",
|
|
14
|
+
];
|
|
15
|
+
function readValue(argv, index, flag) {
|
|
16
|
+
const arg = argv[index] ?? "";
|
|
17
|
+
const inline = `${flag}=`;
|
|
18
|
+
const raw = arg.startsWith(inline) ? arg.slice(inline.length) : argv[index + 1];
|
|
19
|
+
if (raw === undefined || raw.startsWith("--")) {
|
|
20
|
+
return { error: `argument ${flag}: expected one argument` };
|
|
21
|
+
}
|
|
22
|
+
const value = raw.trim();
|
|
23
|
+
if (value.length === 0) {
|
|
24
|
+
return { error: `argument ${flag}: expected a non-empty value` };
|
|
25
|
+
}
|
|
26
|
+
return { value, next: arg.startsWith(inline) ? index : index + 1 };
|
|
27
|
+
}
|
|
28
|
+
export function parseArgs(argv) {
|
|
29
|
+
const parsed = { projectRoot: ".", revoke: false };
|
|
30
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
31
|
+
const arg = argv[i] ?? "";
|
|
32
|
+
if (arg === "--revoke")
|
|
33
|
+
continue;
|
|
34
|
+
const flag = VALUE_FLAGS.find((name) => arg === name || arg.startsWith(`${name}=`));
|
|
35
|
+
if (flag === undefined) {
|
|
36
|
+
return {
|
|
37
|
+
...parsed,
|
|
38
|
+
revoke: argv.includes("--revoke"),
|
|
39
|
+
error: `unrecognized argument: ${arg}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const read = readValue(argv, i, flag);
|
|
43
|
+
if ("error" in read)
|
|
44
|
+
return { ...parsed, revoke: argv.includes("--revoke"), error: read.error };
|
|
45
|
+
i = read.next;
|
|
46
|
+
switch (flag) {
|
|
47
|
+
case "--project-root":
|
|
48
|
+
parsed.projectRoot = read.value;
|
|
49
|
+
break;
|
|
50
|
+
case "--session-id":
|
|
51
|
+
parsed.sessionId = read.value;
|
|
52
|
+
break;
|
|
53
|
+
case "--child-session-id":
|
|
54
|
+
parsed.childSessionId = read.value;
|
|
55
|
+
break;
|
|
56
|
+
case "--role":
|
|
57
|
+
parsed.role = read.value;
|
|
58
|
+
break;
|
|
59
|
+
case "--worktree":
|
|
60
|
+
parsed.worktree = read.value;
|
|
61
|
+
break;
|
|
62
|
+
case "--host":
|
|
63
|
+
parsed.host = read.value;
|
|
64
|
+
break;
|
|
65
|
+
case "--address":
|
|
66
|
+
parsed.address = read.value;
|
|
67
|
+
break;
|
|
68
|
+
case "--ttl-minutes": {
|
|
69
|
+
const minutes = Number(read.value);
|
|
70
|
+
if (!Number.isFinite(minutes) || minutes <= 0) {
|
|
71
|
+
return {
|
|
72
|
+
...parsed,
|
|
73
|
+
revoke: argv.includes("--revoke"),
|
|
74
|
+
error: "argument --ttl-minutes: expected a positive number of minutes",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
parsed.ttlMinutes = minutes;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "--join-protocol": {
|
|
81
|
+
if (!OCCUPANCY_JOIN_PROTOCOLS.includes(read.value)) {
|
|
82
|
+
return {
|
|
83
|
+
...parsed,
|
|
84
|
+
revoke: argv.includes("--revoke"),
|
|
85
|
+
error: `argument --join-protocol: expected one of ${OCCUPANCY_JOIN_PROTOCOLS.join(", ")}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
parsed.joinProtocol = read.value;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { ...parsed, revoke: argv.includes("--revoke") };
|
|
94
|
+
}
|
|
95
|
+
export function run(argv) {
|
|
96
|
+
const args = parseArgs(argv);
|
|
97
|
+
if (args.error !== undefined) {
|
|
98
|
+
process.stderr.write(`occupancy:grant: ${args.error}\n`);
|
|
99
|
+
return 2;
|
|
100
|
+
}
|
|
101
|
+
const projectRoot = resolve(args.projectRoot);
|
|
102
|
+
const input = {
|
|
103
|
+
sessionId: args.sessionId,
|
|
104
|
+
childSessionId: args.childSessionId,
|
|
105
|
+
role: args.role,
|
|
106
|
+
worktreePath: args.worktree,
|
|
107
|
+
ttlMs: args.ttlMinutes === undefined ? undefined : args.ttlMinutes * 60 * 1000,
|
|
108
|
+
host: args.host,
|
|
109
|
+
address: args.address,
|
|
110
|
+
joinProtocol: args.joinProtocol,
|
|
111
|
+
env: process.env,
|
|
112
|
+
};
|
|
113
|
+
const result = args.revoke
|
|
114
|
+
? revokeOccupancyMembership(projectRoot, input)
|
|
115
|
+
: grantOccupancyMembership(projectRoot, input);
|
|
116
|
+
const sink = result.code === 0 ? process.stdout : process.stderr;
|
|
117
|
+
sink.write(`${result.message}\n`);
|
|
118
|
+
return result.code;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=occupancy-grant.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare function parseArgs(argv: readonly string[]): {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
error?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function run(argv: readonly string[]): number;
|
|
8
|
+
//# sourceMappingURL=occupancy-heartbeat.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { heartbeatOccupancy } from "@deftai/directive-core/session";
|
|
4
|
+
export function parseArgs(argv) {
|
|
5
|
+
const parsed = { projectRoot: "." };
|
|
6
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
7
|
+
const arg = argv[i];
|
|
8
|
+
if (arg === "--project-root") {
|
|
9
|
+
const value = argv[i + 1];
|
|
10
|
+
if (value === undefined || value.startsWith("--")) {
|
|
11
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
12
|
+
}
|
|
13
|
+
parsed.projectRoot = value;
|
|
14
|
+
i += 1;
|
|
15
|
+
}
|
|
16
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
17
|
+
const value = arg.slice("--project-root=".length);
|
|
18
|
+
if (value.length === 0 || value.startsWith("--")) {
|
|
19
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
20
|
+
}
|
|
21
|
+
parsed.projectRoot = value;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === "--session-id") {
|
|
24
|
+
const value = argv[i + 1];
|
|
25
|
+
if (value === undefined || value.startsWith("--")) {
|
|
26
|
+
return { ...parsed, error: "argument --session-id: expected one argument" };
|
|
27
|
+
}
|
|
28
|
+
const sessionId = value.trim();
|
|
29
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
30
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
31
|
+
}
|
|
32
|
+
parsed.sessionId = sessionId;
|
|
33
|
+
i += 1;
|
|
34
|
+
}
|
|
35
|
+
else if (arg?.startsWith("--session-id=")) {
|
|
36
|
+
const sessionId = arg.slice("--session-id=".length).trim();
|
|
37
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
38
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
39
|
+
}
|
|
40
|
+
parsed.sessionId = sessionId;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
export function run(argv) {
|
|
49
|
+
const args = parseArgs(argv);
|
|
50
|
+
if (args.error !== undefined) {
|
|
51
|
+
process.stderr.write(`occupancy:heartbeat: ${args.error}\n`);
|
|
52
|
+
return 2;
|
|
53
|
+
}
|
|
54
|
+
const result = heartbeatOccupancy(resolve(args.projectRoot), {
|
|
55
|
+
sessionId: args.sessionId,
|
|
56
|
+
env: process.env,
|
|
57
|
+
});
|
|
58
|
+
const sink = result.code === 0 ? process.stdout : process.stderr;
|
|
59
|
+
sink.write(`${result.message}\n`);
|
|
60
|
+
return result.code;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=occupancy-heartbeat.js.map
|
|
@@ -7,14 +7,37 @@ export function parseArgs(argv) {
|
|
|
7
7
|
const arg = argv[i];
|
|
8
8
|
if (arg === "--project-root") {
|
|
9
9
|
const value = argv[i + 1];
|
|
10
|
-
if (value === undefined) {
|
|
10
|
+
if (value === undefined || value.startsWith("--")) {
|
|
11
11
|
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
12
12
|
}
|
|
13
13
|
parsed.projectRoot = value;
|
|
14
14
|
i += 1;
|
|
15
15
|
}
|
|
16
16
|
else if (arg?.startsWith("--project-root=")) {
|
|
17
|
-
|
|
17
|
+
const value = arg.slice("--project-root=".length);
|
|
18
|
+
if (value.length === 0 || value.startsWith("--")) {
|
|
19
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
20
|
+
}
|
|
21
|
+
parsed.projectRoot = value;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === "--session-id") {
|
|
24
|
+
const value = argv[i + 1];
|
|
25
|
+
if (value === undefined || value.startsWith("--")) {
|
|
26
|
+
return { ...parsed, error: "argument --session-id: expected one argument" };
|
|
27
|
+
}
|
|
28
|
+
const sessionId = value.trim();
|
|
29
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
30
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
31
|
+
}
|
|
32
|
+
parsed.sessionId = sessionId;
|
|
33
|
+
i += 1;
|
|
34
|
+
}
|
|
35
|
+
else if (arg?.startsWith("--session-id=")) {
|
|
36
|
+
const sessionId = arg.slice("--session-id=".length).trim();
|
|
37
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
38
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
39
|
+
}
|
|
40
|
+
parsed.sessionId = sessionId;
|
|
18
41
|
}
|
|
19
42
|
else {
|
|
20
43
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
@@ -29,6 +52,7 @@ export function run(argv) {
|
|
|
29
52
|
return 2;
|
|
30
53
|
}
|
|
31
54
|
const result = releaseOccupancy(resolve(args.projectRoot), {
|
|
55
|
+
sessionId: args.sessionId,
|
|
32
56
|
env: process.env,
|
|
33
57
|
});
|
|
34
58
|
const sink = result.code === 0 ? process.stdout : process.stderr;
|
package/dist/occupancy-steal.js
CHANGED
|
@@ -10,25 +10,52 @@ export function parseArgs(argv) {
|
|
|
10
10
|
}
|
|
11
11
|
else if (arg === "--occupant") {
|
|
12
12
|
const value = argv[i + 1];
|
|
13
|
-
if (value === undefined) {
|
|
13
|
+
if (value === undefined || value.startsWith("--")) {
|
|
14
14
|
return { ...parsed, error: "argument --occupant: expected one argument" };
|
|
15
15
|
}
|
|
16
16
|
parsed.occupant = value;
|
|
17
17
|
i += 1;
|
|
18
18
|
}
|
|
19
19
|
else if (arg?.startsWith("--occupant=")) {
|
|
20
|
-
|
|
20
|
+
const value = arg.slice("--occupant=".length);
|
|
21
|
+
if (value.length === 0 || value.startsWith("--")) {
|
|
22
|
+
return { ...parsed, error: "argument --occupant: expected one argument" };
|
|
23
|
+
}
|
|
24
|
+
parsed.occupant = value;
|
|
21
25
|
}
|
|
22
26
|
else if (arg === "--project-root") {
|
|
23
27
|
const value = argv[i + 1];
|
|
24
|
-
if (value === undefined) {
|
|
28
|
+
if (value === undefined || value.startsWith("--")) {
|
|
25
29
|
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
26
30
|
}
|
|
27
31
|
parsed.projectRoot = value;
|
|
28
32
|
i += 1;
|
|
29
33
|
}
|
|
30
34
|
else if (arg?.startsWith("--project-root=")) {
|
|
31
|
-
|
|
35
|
+
const value = arg.slice("--project-root=".length);
|
|
36
|
+
if (value.length === 0 || value.startsWith("--")) {
|
|
37
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
38
|
+
}
|
|
39
|
+
parsed.projectRoot = value;
|
|
40
|
+
}
|
|
41
|
+
else if (arg === "--session-id") {
|
|
42
|
+
const value = argv[i + 1];
|
|
43
|
+
if (value === undefined || value.startsWith("--")) {
|
|
44
|
+
return { ...parsed, error: "argument --session-id: expected one argument" };
|
|
45
|
+
}
|
|
46
|
+
const sessionId = value.trim();
|
|
47
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
48
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
49
|
+
}
|
|
50
|
+
parsed.sessionId = sessionId;
|
|
51
|
+
i += 1;
|
|
52
|
+
}
|
|
53
|
+
else if (arg?.startsWith("--session-id=")) {
|
|
54
|
+
const sessionId = arg.slice("--session-id=".length).trim();
|
|
55
|
+
if (sessionId.length === 0 || sessionId.startsWith("--")) {
|
|
56
|
+
return { ...parsed, error: "argument --session-id: expected a non-empty value" };
|
|
57
|
+
}
|
|
58
|
+
parsed.sessionId = sessionId;
|
|
32
59
|
}
|
|
33
60
|
else {
|
|
34
61
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
@@ -43,6 +70,7 @@ export function run(argv) {
|
|
|
43
70
|
return 2;
|
|
44
71
|
}
|
|
45
72
|
const result = stealOccupancy(resolve(args.projectRoot), {
|
|
73
|
+
sessionId: args.sessionId,
|
|
46
74
|
confirm: args.confirm,
|
|
47
75
|
occupant: args.occupant ?? undefined,
|
|
48
76
|
env: process.env,
|