@deftai/directive 0.119.11 → 0.119.12

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.
@@ -1,7 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ /**
3
+ * First-class abandoned-lease recovery (#4667). Live actor is session_id in
4
+ * .deft/occupancy.json; bare session:end with empty identity refuses; TTL
5
+ * claim-over and deny-embedded copy-paste remain. host:none / address:none
6
+ * are unset metadata, not the lock cause. Does not reopen anonymous live
7
+ * auto-release (#3954).
8
+ */
9
+ export declare const ABANDONED_OCCUPANCY_LEASE_RECOVERY: string;
10
+ export declare function formatOccupancyReleaseHelp(): string;
2
11
  export declare function parseArgs(argv: readonly string[]): {
3
12
  projectRoot: string;
4
13
  sessionId?: string;
14
+ help?: boolean;
5
15
  error?: string;
6
16
  };
7
17
  export declare function run(argv: readonly string[]): number;
@@ -2,11 +2,38 @@
2
2
  import { resolve } from "node:path";
3
3
  import { releaseOccupancy } from "@deftai/directive-core/session";
4
4
  import { occupancyUnrecognizedArgument } from "./occupancy-unrecognized.js";
5
+ /**
6
+ * First-class abandoned-lease recovery (#4667). Live actor is session_id in
7
+ * .deft/occupancy.json; bare session:end with empty identity refuses; TTL
8
+ * claim-over and deny-embedded copy-paste remain. host:none / address:none
9
+ * are unset metadata, not the lock cause. Does not reopen anonymous live
10
+ * auto-release (#3954).
11
+ */
12
+ export const ABANDONED_OCCUPANCY_LEASE_RECOVERY = "Abandoned live occupancy lease: bare session:end / occupancy:release without a presented " +
13
+ "session identity refuses while the lease is live. Immediate recovery: " +
14
+ "occupancy:release --session-id=<id from .deft/occupancy.json> " +
15
+ "(read session_id from that file). Or wait for TTL claim-over. " +
16
+ "host:none / address:none are ordinary unset metadata, not the lock cause.";
17
+ export function formatOccupancyReleaseHelp() {
18
+ return [
19
+ "Usage: deft occupancy:release [--project-root <path>] [--session-id <id>]",
20
+ "",
21
+ "Release this worktree occupancy lease (owner live, or expired residue).",
22
+ "",
23
+ ABANDONED_OCCUPANCY_LEASE_RECOVERY,
24
+ "",
25
+ ].join("\n");
26
+ }
5
27
  export function parseArgs(argv) {
6
- const parsed = { projectRoot: "." };
28
+ const parsed = {
29
+ projectRoot: ".",
30
+ };
7
31
  for (let i = 0; i < argv.length; i += 1) {
8
32
  const arg = argv[i];
9
- if (arg === "--project-root") {
33
+ if (arg === "--help" || arg === "-h") {
34
+ parsed.help = true;
35
+ }
36
+ else if (arg === "--project-root") {
10
37
  const value = argv[i + 1];
11
38
  if (value === undefined || value.startsWith("--")) {
12
39
  return { ...parsed, error: "argument --project-root: expected one argument" };
@@ -52,6 +79,10 @@ export function run(argv) {
52
79
  process.stderr.write(`occupancy:release: ${args.error}\n`);
53
80
  return 2;
54
81
  }
82
+ if (args.help === true) {
83
+ process.stdout.write(formatOccupancyReleaseHelp());
84
+ return 0;
85
+ }
55
86
  const result = releaseOccupancy(resolve(args.projectRoot), {
56
87
  sessionId: args.sessionId,
57
88
  env: process.env,
package/dist/verify-ac.js CHANGED
@@ -12,7 +12,7 @@ import { join, resolve } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { resolveSessionCompletedVerifyAcTarget } from "@deftai/directive-core/check";
14
14
  import { formatRejectedLedger, resolveLiteralAcceptanceDetailed, } from "@deftai/directive-core/literal-acceptance";
15
- import { emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, readAdmittedSourceDigest, readAdmittedSourceSentences, readPlanAcceptance, resolveAcceptanceGateProfile, } from "@deftai/directive-core/product-first-done-gate";
15
+ import { emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, readAdmittedSourceDigest, readAdmittedSourceSentences, readPlanAcceptance, resolveAcceptanceGateProfile, resolveSoftMissingAcTargets, } from "@deftai/directive-core/product-first-done-gate";
16
16
  /** Parse verify:ac CLI args. */
17
17
  export function parseArgs(argv) {
18
18
  const parsed = {
@@ -277,18 +277,44 @@ export function run(argv) {
277
277
  paths = [found.path];
278
278
  }
279
279
  else if (found.kind === "many") {
280
- // Greptile #3284: multi-active must verify EVERY active scope, not skip.
281
- if (args.softMissingXbrief || args.captureOnly) {
280
+ // #4285: soft-missing selects via DEFT_ACTIVE_SCOPE / explicit path
281
+ // (or fail closed). ALL-paths soft-missing is not the #3284 product bar.
282
+ // --capture-only still lists every active artifact (inventory, not run).
283
+ if (args.captureOnly) {
282
284
  paths = [...found.paths];
283
285
  if (!args.quiet) {
284
- process.stdout.write(`verify:ac multi-active (#3284): evaluating ${paths.length} scopes in ${found.dir}\n`);
286
+ process.stdout.write(`verify:ac capture-only multi-active: listing ${paths.length} scopes in ${found.dir}\n`);
287
+ }
288
+ }
289
+ else if (args.softMissingXbrief) {
290
+ const selected = resolveSoftMissingAcTargets(projectRoot, {
291
+ env: process.env,
292
+ scannedPaths: found.paths,
293
+ });
294
+ if (selected.kind === "one") {
295
+ paths = [selected.path];
296
+ if (!args.quiet) {
297
+ process.stdout.write(`verify:ac soft-missing multi-active (#4285): selected ${selected.path}\n`);
298
+ }
299
+ }
300
+ else {
301
+ process.stderr.write(`${selected.kind === "need-pin" ? selected.message : "verify_ac: multi-active soft-missing needs a pin"}\n` +
302
+ " Usage: task verify:ac -- <path-to-active.xbrief.json>\n" +
303
+ ` Or set DEFT_ACTIVE_SCOPE to the dispatched story under ${found.dir}\n` +
304
+ " Refs #4285 / #3284 product-first done-gate\n");
305
+ emitVerifyAcTerminalOutcome({
306
+ projectRoot,
307
+ env: process.env,
308
+ outcome: "config-error",
309
+ });
310
+ return 1;
285
311
  }
286
312
  }
287
313
  else {
288
314
  process.stderr.write(`verify_ac: ${found.paths.length} active scopes in ${found.dir}.\n` +
289
- " Pass an explicit path, or use check composition (--soft-missing-xbrief) to evaluate all.\n" +
315
+ " Pass an explicit path, or set DEFT_ACTIVE_SCOPE with check composition (--soft-missing-xbrief).\n" +
290
316
  " Usage: task verify:ac -- <path-to-active.xbrief.json>\n" +
291
- " Refs #3284 product-first done-gate\n");
317
+ " Refs #4285 / #3284 product-first done-gate\n");
292
318
  emitVerifyAcTerminalOutcome({
293
319
  projectRoot,
294
320
  env: process.env,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.119.11",
3
+ "version": "0.119.12",
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.119.11",
39
- "@deftai/directive-content": "^0.119.11"
38
+ "@deftai/directive-core": "^0.119.12",
39
+ "@deftai/directive-content": "^0.119.12"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -b",