@deftai/directive 0.104.0 → 0.105.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.
@@ -2,11 +2,20 @@
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { evaluate } from "@deftai/directive-core/orphan-active";
5
+ function parseIssueNumber(raw) {
6
+ const trimmed = raw.startsWith("#") ? raw.slice(1) : raw;
7
+ if (!/^\d+$/.test(trimmed)) {
8
+ return null;
9
+ }
10
+ const value = Number(trimmed);
11
+ return Number.isInteger(value) && value > 0 ? value : null;
12
+ }
5
13
  /** Parse verify-orphan-active CLI args. */
6
14
  export function parseArgs(argv) {
7
15
  const parsed = {
8
16
  projectRoot: ".",
9
17
  repo: null,
18
+ issue: null,
10
19
  quiet: false,
11
20
  skipGh: false,
12
21
  };
@@ -40,6 +49,26 @@ export function parseArgs(argv) {
40
49
  else if (arg?.startsWith("--repo=")) {
41
50
  parsed.repo = arg.slice("--repo=".length);
42
51
  }
52
+ else if (arg === "--issue") {
53
+ const value = argv[i + 1];
54
+ if (value === undefined) {
55
+ return { ...parsed, error: "argument --issue: expected one argument" };
56
+ }
57
+ const issue = parseIssueNumber(value);
58
+ if (issue === null) {
59
+ return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
60
+ }
61
+ parsed.issue = issue;
62
+ i += 1;
63
+ }
64
+ else if (arg?.startsWith("--issue=")) {
65
+ const value = arg.slice("--issue=".length);
66
+ const issue = parseIssueNumber(value);
67
+ if (issue === null) {
68
+ return { ...parsed, error: `argument --issue: expected a positive integer, got ${value}` };
69
+ }
70
+ parsed.issue = issue;
71
+ }
43
72
  else {
44
73
  return { ...parsed, error: `unrecognized argument: ${arg}` };
45
74
  }
@@ -58,6 +87,7 @@ export function run(argv) {
58
87
  quiet: args.quiet,
59
88
  repo: args.repo,
60
89
  skipGh: args.skipGh,
90
+ issue: args.issue,
61
91
  });
62
92
  if (result.message.length > 0) {
63
93
  if (result.stream === "stdout") {
@@ -1,5 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { type DirectivePosture } from "@deftai/directive-core/session";
2
+ import { type DirectivePosture, type VerifyResult } from "@deftai/directive-core/session";
3
+ export interface VerifySessionRitualRunDeps {
4
+ readonly verifySessionRitual?: (projectRoot: string, options: {
5
+ tier: "quick" | "gated";
6
+ posture?: DirectivePosture;
7
+ }) => VerifyResult;
8
+ }
3
9
  interface ParsedArgs {
4
10
  projectRoot: string;
5
11
  tier: "quick" | "gated";
@@ -9,7 +15,9 @@ interface ParsedArgs {
9
15
  }
10
16
  /** Parse verify-session-ritual CLI args, mirroring scripts/verify_session_ritual.py. */
11
17
  export declare function parseArgs(argv: string[]): ParsedArgs;
18
+ /** True when the ritual failure is the gated cache_fresh step (#3506 / #3507). */
19
+ export declare function isCacheFreshFailureMessage(message: string): boolean;
12
20
  /** Run the gate and return the process exit code. */
13
- export declare function run(argv: string[]): number;
21
+ export declare function run(argv: string[], deps?: VerifySessionRitualRunDeps): number;
14
22
  export {};
15
23
  //# sourceMappingURL=verify-session-ritual.d.ts.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { emitBypassWarning, emitVerifyJson, verifySessionRitual, } from "@deftai/directive-core/session";
4
+ import { emitBypassWarning, emitVerifyJson, formatCacheFreshDeferSoftPath, formatRitualRecoveryInstruction, verifySessionRitual, } from "@deftai/directive-core/session";
5
5
  function parsePosture(value) {
6
6
  if (value === "read-only")
7
7
  return "read-only";
@@ -86,15 +86,20 @@ export function parseArgs(argv) {
86
86
  }
87
87
  return parsed;
88
88
  }
89
+ /** True when the ritual failure is the gated cache_fresh step (#3506 / #3507). */
90
+ export function isCacheFreshFailureMessage(message) {
91
+ return message.includes("cache_fresh") || message.includes("cache-fresh");
92
+ }
89
93
  /** Run the gate and return the process exit code. */
90
- export function run(argv) {
94
+ export function run(argv, deps = {}) {
91
95
  const args = parseArgs(argv);
92
96
  if (args.error !== undefined) {
93
97
  process.stderr.write(`verify_session_ritual: ${args.error}\n`);
94
98
  return 2;
95
99
  }
96
100
  const projectRoot = resolve(args.projectRoot);
97
- const result = verifySessionRitual(projectRoot, {
101
+ const verify = deps.verifySessionRitual ?? verifySessionRitual;
102
+ const result = verify(projectRoot, {
98
103
  tier: args.tier,
99
104
  posture: args.posture ?? undefined,
100
105
  });
@@ -108,6 +113,14 @@ export function run(argv) {
108
113
  process.stdout.write(`${result.message}\n`);
109
114
  }
110
115
  }
116
+ else if (result.code === 1) {
117
+ const recovery = formatRitualRecoveryInstruction(result.recoveryTier ?? "cold");
118
+ const lines = [result.message, recovery];
119
+ if (isCacheFreshFailureMessage(result.message)) {
120
+ lines.push(formatCacheFreshDeferSoftPath());
121
+ }
122
+ process.stderr.write(`${lines.join("\n")}\n`);
123
+ }
111
124
  else {
112
125
  process.stderr.write(`${result.message}\n`);
113
126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.104.0",
3
+ "version": "0.105.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.104.0",
38
- "@deftai/directive-content": "^0.104.0"
37
+ "@deftai/directive-core": "^0.105.0",
38
+ "@deftai/directive-content": "^0.105.0"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b"