@deftai/directive-core 0.108.0 → 0.109.1
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/cache/operations.js +1 -1
- package/dist/check/gate-lists.d.ts +14 -0
- package/dist/check/gate-lists.js +26 -3
- package/dist/check/session-completed-ac.d.ts +1 -1
- package/dist/check/session-completed-ac.js +1 -1
- package/dist/consumer-check-contract/evaluate.d.ts +47 -0
- package/dist/consumer-check-contract/evaluate.js +181 -15
- package/dist/delivery-attempt/evaluate.d.ts +9 -1
- package/dist/delivery-attempt/evaluate.js +69 -0
- package/dist/delivery-attempt/index.d.ts +1 -1
- package/dist/delivery-attempt/index.js +1 -1
- package/dist/deposit/live-procedure-exclusions.d.ts +18 -0
- package/dist/deposit/live-procedure-exclusions.js +110 -0
- package/dist/deposit/live-procedure-targets.d.ts +45 -0
- package/dist/deposit/live-procedure-targets.js +274 -0
- package/dist/deposit/python-free.d.ts +6 -0
- package/dist/deposit/python-free.js +15 -0
- package/dist/deposit/rewrite-deposit-links.d.ts +42 -0
- package/dist/deposit/rewrite-deposit-links.js +148 -0
- package/dist/deposit/run-stage-content-pack.d.ts +2 -0
- package/dist/deposit/run-stage-content-pack.js +3 -0
- package/dist/deposit/stage-content-pack.d.ts +17 -0
- package/dist/deposit/stage-content-pack.js +91 -0
- package/dist/design-critique/citation-grammar.d.ts +7 -0
- package/dist/design-critique/citation-grammar.js +1 -1
- package/dist/design-critique/completed-arc-record.d.ts +8 -1
- package/dist/design-critique/completed-arc-record.js +98 -14
- package/dist/hooks/classify/host-session-identity.d.ts +25 -12
- package/dist/hooks/classify/host-session-identity.js +64 -49
- package/dist/hooks/classify/index.d.ts +2 -2
- package/dist/hooks/classify/index.js +2 -2
- package/dist/hooks/classify/paths.d.ts +2 -0
- package/dist/hooks/classify/paths.js +8 -4
- package/dist/hooks/classify/stdin.js +69 -3
- package/dist/hooks/dest-form.d.ts +20 -1
- package/dist/hooks/dest-form.js +158 -21
- package/dist/hooks/dispatcher.d.ts +22 -2
- package/dist/hooks/dispatcher.js +338 -66
- package/dist/hooks/fixtures/cases.d.ts +6 -0
- package/dist/hooks/fixtures/cases.js +53 -0
- package/dist/hooks/git-destructive-log.d.ts +32 -0
- package/dist/hooks/git-destructive-log.js +46 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/owner-liveness.d.ts +92 -0
- package/dist/hooks/owner-liveness.js +103 -0
- package/dist/hooks/shell-write-targets.d.ts +10 -0
- package/dist/hooks/shell-write-targets.js +274 -0
- package/dist/hooks/tools.d.ts +49 -2
- package/dist/hooks/tools.js +96 -1
- package/dist/init-deposit/agent-hooks.d.ts +10 -0
- package/dist/init-deposit/agent-hooks.js +39 -0
- package/dist/init-deposit/gitignore.d.ts +7 -0
- package/dist/init-deposit/gitignore.js +24 -0
- package/dist/init-deposit/host-tool-coverage.d.ts +53 -0
- package/dist/init-deposit/host-tool-coverage.js +150 -0
- package/dist/init-deposit/index.d.ts +1 -0
- package/dist/init-deposit/index.js +1 -0
- package/dist/init-deposit/init-deposit.js +3 -0
- package/dist/init-deposit/refresh.js +7 -0
- package/dist/init-deposit/runtime-writers.d.ts +14 -0
- package/dist/init-deposit/runtime-writers.js +33 -0
- package/dist/intake/issue-ingest.d.ts +6 -1
- package/dist/intake/issue-ingest.js +21 -2
- package/dist/intake/reconcile-issues.js +13 -13
- package/dist/lifecycle/brief-envelope.d.ts +25 -0
- package/dist/lifecycle/brief-envelope.js +42 -0
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/literal-acceptance/evaluate.js +14 -5
- package/dist/literal-acceptance/index.d.ts +1 -1
- package/dist/literal-acceptance/index.js +1 -1
- package/dist/literal-acceptance/run.d.ts +2 -0
- package/dist/literal-acceptance/run.js +19 -1
- package/dist/orchestration/subagent-monitor.d.ts +6 -0
- package/dist/orchestration/subagent-monitor.js +23 -1
- package/dist/orphan-active/candidate-scope.d.ts +53 -0
- package/dist/orphan-active/candidate-scope.js +157 -0
- package/dist/orphan-active/evaluate.d.ts +27 -0
- package/dist/orphan-active/evaluate.js +63 -6
- package/dist/orphan-active/index.d.ts +1 -0
- package/dist/orphan-active/index.js +1 -0
- package/dist/policy/merge-approval-head.js +7 -6
- package/dist/pr-closing-keywords/gh.js +32 -9
- package/dist/pr-closing-keywords/main.d.ts +1 -0
- package/dist/pr-closing-keywords/main.js +68 -3
- package/dist/pr-closing-keywords/types.d.ts +2 -0
- package/dist/pr-merge-readiness/gh.js +32 -9
- package/dist/pr-protected-issues/gh.js +36 -9
- package/dist/pr-wait-mergeable/wrappers.js +3 -3
- package/dist/product-first-done-gate/evaluate.js +6 -2
- package/dist/product-first-done-gate/types.js +2 -0
- package/dist/release/consumer-hard-stops.d.ts +48 -0
- package/dist/release/consumer-hard-stops.js +140 -0
- package/dist/release/consumer-readiness-disclosure.d.ts +18 -0
- package/dist/release/consumer-readiness-disclosure.js +51 -0
- package/dist/release/index.d.ts +2 -0
- package/dist/release/index.js +2 -0
- package/dist/release/pipeline.js +55 -0
- package/dist/release/run-consumer-readiness.d.ts +15 -0
- package/dist/release/run-consumer-readiness.js +24 -0
- package/dist/release/types.d.ts +6 -0
- package/dist/review-monitor/github-lease.js +4 -3
- package/dist/run-summary/types.d.ts +2 -2
- package/dist/scm/build-command.d.ts +2 -2
- package/dist/scm/build-command.js +2 -2
- package/dist/scm/call-shape.d.ts +25 -0
- package/dist/scm/call-shape.js +59 -0
- package/dist/scm/call.d.ts +7 -4
- package/dist/scm/call.js +41 -11
- package/dist/scm/gh-rest.d.ts +25 -12
- package/dist/scm/gh-rest.js +65 -15
- package/dist/scm/index.d.ts +2 -0
- package/dist/scm/index.js +2 -0
- package/dist/scm/spawn-status.d.ts +33 -0
- package/dist/scm/spawn-status.js +53 -0
- package/dist/scope/acceptance-evidence.d.ts +1 -1
- package/dist/scope/transition.js +4 -14
- package/dist/session/ac-pass-banking.d.ts +2 -2
- package/dist/session/ac-pass-banking.js +2 -2
- package/dist/session/child-occupancy.d.ts +72 -0
- package/dist/session/child-occupancy.js +209 -0
- package/dist/session/host-session-owner.d.ts +93 -0
- package/dist/session/host-session-owner.js +148 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/occupancy.d.ts +107 -2
- package/dist/session/occupancy.js +272 -34
- package/dist/session/verify-ac-session-cache.d.ts +2 -2
- package/dist/session/verify-ac-session-cache.js +2 -2
- package/dist/swarm/complete-cohort.js +2 -0
- package/dist/swarm/pre-dispatch.js +2 -0
- package/dist/swarm/subagent-status-dir.d.ts +2 -1
- package/dist/swarm/subagent-status-dir.js +11 -2
- package/dist/swarm/worktrees.js +2 -0
- package/dist/triage/evaluate/worktrees.js +153 -6
- package/dist/umbrella-current-shape/index.d.ts +51 -3
- package/dist/umbrella-current-shape/index.js +106 -18
- package/dist/validate-content/deposit-required.d.ts +39 -0
- package/dist/validate-content/deposit-required.js +147 -0
- package/dist/validate-content/index.d.ts +1 -0
- package/dist/validate-content/index.js +1 -0
- package/dist/validate-content/validate-links.d.ts +2 -3
- package/dist/validate-content/validate-links.js +29 -2
- package/dist/vbrief-activate/activate.d.ts +7 -2
- package/dist/vbrief-activate/activate.js +26 -13
- package/dist/verify-ac/evaluate.d.ts +9 -0
- package/dist/verify-ac/evaluate.js +32 -9
- package/dist/verify-env/agent-hooks.d.ts +6 -1
- package/dist/verify-env/agent-hooks.js +28 -2
- package/dist/verify-source/deposit-closure.d.ts +23 -0
- package/dist/verify-source/deposit-closure.js +162 -0
- package/dist/verify-source/index.d.ts +2 -0
- package/dist/verify-source/index.js +2 -0
- package/dist/verify-source/semantic-single-source.d.ts +36 -0
- package/dist/verify-source/semantic-single-source.js +349 -0
- package/package.json +3 -3
package/dist/scm/call.js
CHANGED
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { resolveCaptureFailureStderr, SUBPROCESS_MAX_BUFFER } from "../subprocess/max-buffer.js";
|
|
3
|
-
import {
|
|
3
|
+
import { defaultWhich } from "./binary.js";
|
|
4
|
+
import { classifyScmArgv, resolveBinaryForRole } from "./call-shape.js";
|
|
4
5
|
import { SUPPORTED_CALL_SOURCES } from "./constants.js";
|
|
5
6
|
import { pyRepr } from "./py-format.js";
|
|
7
|
+
import { formatScmSpawnDiagnostic, isAvailabilitySpawnFailure } from "./spawn-status.js";
|
|
6
8
|
/**
|
|
7
9
|
* Source-aware SCM invocation -- partial down-payment on #445 / #935 Workstream 6.
|
|
8
10
|
* Mirrors `scripts/scm.py::call`.
|
|
9
11
|
*
|
|
10
|
-
* Binary absence still throws ScmStubError via
|
|
11
|
-
* diagnostic. Full auth readiness is enforced at SCM CLI entry points
|
|
12
|
+
* Binary absence still throws ScmStubError via resolveBinaryForRole with the
|
|
13
|
+
* #2275 diagnostic. Full auth readiness is enforced at SCM CLI entry points
|
|
12
14
|
* (`scm/main`, issue-ingest, reconcile-issues) via requireScmReady — not on
|
|
13
15
|
* every call() — so unit tests that inject binary/seams stay hermetic.
|
|
16
|
+
*
|
|
17
|
+
* Call-shape selection (#3737): ghx only for single-path GET. An explicit
|
|
18
|
+
* `binary` override skips selection and spawn-failure fallback.
|
|
14
19
|
*/
|
|
15
20
|
export function call(source, verb, args = null, options = {}) {
|
|
16
21
|
if (!SUPPORTED_CALL_SOURCES.includes(source)) {
|
|
17
22
|
throw new Error(`source=${pyRepr(source)} not yet supported; ` +
|
|
18
23
|
"see #445 / #935 Workstream 6 for the abstraction.");
|
|
19
24
|
}
|
|
20
|
-
const
|
|
21
|
-
const
|
|
25
|
+
const whichFn = options.whichFn ?? defaultWhich;
|
|
26
|
+
const role = classifyScmArgv(verb, args ?? []);
|
|
27
|
+
const explicitBinary = options.binary;
|
|
28
|
+
let resolved = explicitBinary ?? resolveBinaryForRole(role, whichFn);
|
|
29
|
+
const extra = args ?? [];
|
|
22
30
|
const captureOutput = options.captureOutput ?? true;
|
|
23
31
|
const timeoutMs = options.timeout !== undefined ? Math.round(options.timeout * 1000) : undefined;
|
|
24
|
-
const
|
|
32
|
+
const spawnOnce = (bin) => spawnSync(bin, [verb, ...extra], {
|
|
25
33
|
cwd: options.cwd,
|
|
26
34
|
env: options.env ?? process.env,
|
|
27
35
|
input: options.input,
|
|
@@ -30,14 +38,36 @@ export function call(source, verb, args = null, options = {}) {
|
|
|
30
38
|
maxBuffer: SUBPROCESS_MAX_BUFFER,
|
|
31
39
|
stdio: captureOutput ? ["pipe", "pipe", "pipe"] : "inherit",
|
|
32
40
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
let result = spawnOnce(resolved);
|
|
42
|
+
if (explicitBinary === undefined &&
|
|
43
|
+
role === "cached-get" &&
|
|
44
|
+
resolved === "ghx" &&
|
|
45
|
+
isAvailabilitySpawnFailure({
|
|
46
|
+
status: result.status,
|
|
47
|
+
error: result.error,
|
|
48
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
49
|
+
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
50
|
+
}) &&
|
|
51
|
+
whichFn("gh") !== null) {
|
|
52
|
+
resolved = "gh";
|
|
53
|
+
result = spawnOnce(resolved);
|
|
54
|
+
}
|
|
55
|
+
const argv = [resolved, verb, ...extra];
|
|
56
|
+
const captured = typeof result.stderr === "string" ? result.stderr : "";
|
|
57
|
+
let stderr = resolveCaptureFailureStderr({
|
|
58
|
+
captured,
|
|
38
59
|
status: result.status,
|
|
39
60
|
message: result.error?.message,
|
|
40
61
|
});
|
|
62
|
+
if (isAvailabilitySpawnFailure({
|
|
63
|
+
status: result.status,
|
|
64
|
+
error: result.error,
|
|
65
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
66
|
+
stderr: captured,
|
|
67
|
+
}) &&
|
|
68
|
+
stderr.trim().length === 0) {
|
|
69
|
+
stderr = formatScmSpawnDiagnostic(resolved, result.status, stderr, result.error);
|
|
70
|
+
}
|
|
41
71
|
if (options.check && result.status !== 0) {
|
|
42
72
|
const error = new Error(stderr || `Process exited with code ${result.status}`);
|
|
43
73
|
throw error;
|
package/dist/scm/gh-rest.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type SpawnSyncOptions } from "node:child_process";
|
|
2
|
+
import { type WhichFn } from "./binary.js";
|
|
2
3
|
export declare const DEFAULT_TIMEOUT_S = 60;
|
|
3
4
|
/** Raised when the `"owner/repo"` argument is malformed. */
|
|
4
5
|
export declare class InvalidRepoError extends Error {
|
|
@@ -11,35 +12,47 @@ export declare class GhRestError extends Error {
|
|
|
11
12
|
readonly endpoint: string;
|
|
12
13
|
readonly payload: Record<string, unknown> | null;
|
|
13
14
|
readonly hint: string;
|
|
15
|
+
readonly binary: string;
|
|
14
16
|
constructor(options: {
|
|
15
17
|
stderr: string;
|
|
16
18
|
exitCode: number;
|
|
17
19
|
endpoint: string;
|
|
18
20
|
payload: Record<string, unknown> | null;
|
|
19
21
|
hint?: string;
|
|
22
|
+
binary?: string;
|
|
20
23
|
});
|
|
21
24
|
}
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
export type GhSpawnResult = {
|
|
26
|
+
readonly status: number | null;
|
|
27
|
+
readonly stdout?: string | Buffer | null;
|
|
28
|
+
readonly stderr?: string | Buffer | null;
|
|
29
|
+
readonly error?: {
|
|
30
|
+
readonly message?: string;
|
|
31
|
+
readonly code?: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export type GhSpawnFn = (command: string, args: readonly string[], options: SpawnSyncOptions) => GhSpawnResult;
|
|
35
|
+
export type GhApiProcess = {
|
|
26
36
|
returncode: number;
|
|
27
37
|
stdout: string;
|
|
28
38
|
stderr: string;
|
|
39
|
+
binary?: string;
|
|
29
40
|
};
|
|
41
|
+
export type RunGhApiFn = (args: readonly string[], options?: {
|
|
42
|
+
timeout?: number;
|
|
43
|
+
whichFn?: WhichFn;
|
|
44
|
+
spawnFn?: GhSpawnFn;
|
|
45
|
+
}) => GhApiProcess;
|
|
30
46
|
/** Single subprocess seam invoked by every helper. */
|
|
31
47
|
export declare function runGhApi(args: readonly string[], options?: {
|
|
32
48
|
timeout?: number;
|
|
33
|
-
whichFn?:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
stdout: string;
|
|
37
|
-
stderr: string;
|
|
38
|
-
};
|
|
49
|
+
whichFn?: WhichFn;
|
|
50
|
+
spawnFn?: GhSpawnFn;
|
|
51
|
+
}): GhApiProcess;
|
|
39
52
|
export declare function splitRepo(repo: string): [string, string];
|
|
40
53
|
export interface GhRestSeams {
|
|
41
54
|
readonly runGhApiFn?: RunGhApiFn;
|
|
42
|
-
readonly whichFn?:
|
|
55
|
+
readonly whichFn?: WhichFn;
|
|
43
56
|
}
|
|
44
57
|
/** `GET /repos/{owner}/{repo}/issues/{n}` -- read a single issue. */
|
|
45
58
|
export declare function restIssueView(repo: string, n: number, seams?: GhRestSeams): Record<string, unknown>;
|
package/dist/scm/gh-rest.js
CHANGED
|
@@ -3,8 +3,10 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { SUBPROCESS_MAX_BUFFER } from "../subprocess/max-buffer.js";
|
|
6
|
-
import {
|
|
6
|
+
import { defaultWhich } from "./binary.js";
|
|
7
|
+
import { classifyScmArgv, resolveBinaryForRole } from "./call-shape.js";
|
|
7
8
|
import { pyRepr } from "./py-format.js";
|
|
9
|
+
import { classifySpawnStatus, formatScmSpawnDiagnostic, isAvailabilitySpawnFailure, } from "./spawn-status.js";
|
|
8
10
|
export const DEFAULT_TIMEOUT_S = 60;
|
|
9
11
|
/** Raised when the `"owner/repo"` argument is malformed. */
|
|
10
12
|
export class InvalidRepoError extends Error {
|
|
@@ -23,10 +25,16 @@ export class GhRestError extends Error {
|
|
|
23
25
|
endpoint;
|
|
24
26
|
payload;
|
|
25
27
|
hint;
|
|
28
|
+
binary;
|
|
26
29
|
constructor(options) {
|
|
27
30
|
const hint = options.hint ?? "";
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const binary = options.binary ?? "gh";
|
|
32
|
+
const statusClass = classifySpawnStatus(options.exitCode);
|
|
33
|
+
let msg = `${binary} api failed: endpoint=${pyRepr(options.endpoint)} ` + `exit=${options.exitCode}`;
|
|
34
|
+
if (statusClass !== `exit ${options.exitCode}`) {
|
|
35
|
+
msg += ` (${statusClass})`;
|
|
36
|
+
}
|
|
37
|
+
msg += ` stderr=${pyRepr(options.stderr)}`;
|
|
30
38
|
if (hint.length > 0) {
|
|
31
39
|
msg += `; hint: ${hint}`;
|
|
32
40
|
}
|
|
@@ -37,30 +45,70 @@ export class GhRestError extends Error {
|
|
|
37
45
|
this.endpoint = options.endpoint;
|
|
38
46
|
this.payload = options.payload;
|
|
39
47
|
this.hint = hint;
|
|
48
|
+
this.binary = binary;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function defaultGhSpawn(command, args, options) {
|
|
52
|
+
return spawnSync(command, [...args], options);
|
|
53
|
+
}
|
|
54
|
+
function finalizeGhApiResult(binary, result) {
|
|
55
|
+
const rawStderr = typeof result.stderr === "string" ? result.stderr : "";
|
|
56
|
+
let stderr = rawStderr;
|
|
57
|
+
if (result.status === null && result.error && stderr.trim().length === 0) {
|
|
58
|
+
stderr = result.error.message ?? "";
|
|
40
59
|
}
|
|
60
|
+
if (isAvailabilitySpawnFailure({
|
|
61
|
+
status: result.status,
|
|
62
|
+
error: result.error,
|
|
63
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
64
|
+
stderr: rawStderr,
|
|
65
|
+
}) &&
|
|
66
|
+
stderr.trim().length === 0) {
|
|
67
|
+
stderr = formatScmSpawnDiagnostic(binary, result.status, stderr, result.error);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
returncode: result.status ?? 1,
|
|
71
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
72
|
+
stderr,
|
|
73
|
+
binary,
|
|
74
|
+
rawStderr,
|
|
75
|
+
rawStatus: result.status,
|
|
76
|
+
error: result.error,
|
|
77
|
+
};
|
|
41
78
|
}
|
|
42
79
|
/** Single subprocess seam invoked by every helper. */
|
|
43
80
|
export function runGhApi(args, options = {}) {
|
|
44
|
-
const
|
|
81
|
+
const whichFn = options.whichFn ?? defaultWhich;
|
|
82
|
+
const spawnFn = options.spawnFn ?? defaultGhSpawn;
|
|
83
|
+
const role = classifyScmArgv("api", args);
|
|
84
|
+
let binary = resolveBinaryForRole(role, whichFn);
|
|
45
85
|
const timeoutMs = options.timeout !== undefined ? Math.round(options.timeout * 1000) : DEFAULT_TIMEOUT_S * 1000;
|
|
46
|
-
const
|
|
86
|
+
const spawnOpts = {
|
|
47
87
|
encoding: "utf8",
|
|
48
88
|
timeout: timeoutMs,
|
|
49
89
|
env: process.env,
|
|
50
90
|
maxBuffer: SUBPROCESS_MAX_BUFFER,
|
|
51
91
|
stdio: ["ignore", "pipe", "pipe"],
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
92
|
+
};
|
|
93
|
+
const spawnOnce = (bin) => finalizeGhApiResult(bin, spawnFn(bin, ["api", ...args], spawnOpts));
|
|
94
|
+
let first = spawnOnce(binary);
|
|
95
|
+
if (role === "cached-get" &&
|
|
96
|
+
binary === "ghx" &&
|
|
97
|
+
isAvailabilitySpawnFailure({
|
|
98
|
+
status: first.rawStatus,
|
|
99
|
+
error: first.error,
|
|
100
|
+
stdout: first.stdout,
|
|
101
|
+
stderr: first.rawStderr,
|
|
102
|
+
}) &&
|
|
103
|
+
whichFn("gh") !== null) {
|
|
104
|
+
binary = "gh";
|
|
105
|
+
first = spawnOnce(binary);
|
|
59
106
|
}
|
|
60
107
|
return {
|
|
61
|
-
returncode:
|
|
62
|
-
stdout:
|
|
63
|
-
stderr,
|
|
108
|
+
returncode: first.returncode,
|
|
109
|
+
stdout: first.stdout,
|
|
110
|
+
stderr: first.stderr,
|
|
111
|
+
binary,
|
|
64
112
|
};
|
|
65
113
|
}
|
|
66
114
|
export function splitRepo(repo) {
|
|
@@ -83,6 +131,7 @@ function execApi(args, options) {
|
|
|
83
131
|
endpoint: options.endpoint,
|
|
84
132
|
payload: options.payload,
|
|
85
133
|
hint: options.hint ?? "",
|
|
134
|
+
binary: result.binary ?? "gh",
|
|
86
135
|
});
|
|
87
136
|
}
|
|
88
137
|
const stdout = result.stdout.trim();
|
|
@@ -393,6 +442,7 @@ export function restIssueListOpenInventory(repo, seams = {}) {
|
|
|
393
442
|
endpoint,
|
|
394
443
|
payload: null,
|
|
395
444
|
hint: "verify gh auth and core REST quota; open-issue inventory must be complete",
|
|
445
|
+
binary: result.binary ?? "gh",
|
|
396
446
|
});
|
|
397
447
|
}
|
|
398
448
|
const stdout = result.stdout.trim();
|
package/dist/scm/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./argv.js";
|
|
|
2
2
|
export * from "./binary.js";
|
|
3
3
|
export * from "./build-command.js";
|
|
4
4
|
export * from "./call.js";
|
|
5
|
+
export * from "./call-shape.js";
|
|
5
6
|
export * from "./constants.js";
|
|
6
7
|
export * from "./design-critique-chip.js";
|
|
7
8
|
export * from "./errors.js";
|
|
@@ -10,4 +11,5 @@ export * from "./main.js";
|
|
|
10
11
|
export * from "./py-format.js";
|
|
11
12
|
export * from "./readiness.js";
|
|
12
13
|
export * from "./rest-dispatch.js";
|
|
14
|
+
export * from "./spawn-status.js";
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/scm/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./argv.js";
|
|
|
2
2
|
export * from "./binary.js";
|
|
3
3
|
export * from "./build-command.js";
|
|
4
4
|
export * from "./call.js";
|
|
5
|
+
export * from "./call-shape.js";
|
|
5
6
|
export * from "./constants.js";
|
|
6
7
|
export * from "./design-critique-chip.js";
|
|
7
8
|
export * from "./errors.js";
|
|
@@ -10,4 +11,5 @@ export * from "./main.js";
|
|
|
10
11
|
export * from "./py-format.js";
|
|
11
12
|
export * from "./readiness.js";
|
|
12
13
|
export * from "./rest-dispatch.js";
|
|
14
|
+
export * from "./spawn-status.js";
|
|
13
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { WhichFn } from "./binary.js";
|
|
2
|
+
import type { ScmBinaryRole } from "./call-shape.js";
|
|
3
|
+
/** Windows NTSTATUS STATUS_DLL_INIT_FAILED (#3737). Unsigned and signed 32-bit. */
|
|
4
|
+
export declare const STATUS_DLL_INIT_FAILED = 3221225794;
|
|
5
|
+
export declare function unsignedExitStatus(status: number): number;
|
|
6
|
+
export declare function classifySpawnStatus(status: number | null | undefined, error?: {
|
|
7
|
+
readonly message?: string;
|
|
8
|
+
readonly code?: string;
|
|
9
|
+
}): string;
|
|
10
|
+
export declare function isAvailabilitySpawnFailure(result: {
|
|
11
|
+
readonly status: number | null | undefined;
|
|
12
|
+
readonly error?: {
|
|
13
|
+
readonly message?: string;
|
|
14
|
+
readonly code?: string;
|
|
15
|
+
};
|
|
16
|
+
readonly stdout?: string;
|
|
17
|
+
readonly stderr?: string;
|
|
18
|
+
}): boolean;
|
|
19
|
+
export declare function formatScmSpawnDiagnostic(binary: string, status: number | null | undefined, stderr: string, error?: {
|
|
20
|
+
readonly message?: string;
|
|
21
|
+
readonly code?: string;
|
|
22
|
+
}): string;
|
|
23
|
+
/** Return `gh` when a cached-get ghx spawn failed and live gh is on PATH. */
|
|
24
|
+
export declare function ghxSpawnFallbackBinary(role: ScmBinaryRole, invoked: string, whichFn: WhichFn, failure: {
|
|
25
|
+
readonly status: number | null | undefined;
|
|
26
|
+
readonly error?: {
|
|
27
|
+
readonly message?: string;
|
|
28
|
+
readonly code?: string;
|
|
29
|
+
};
|
|
30
|
+
readonly stdout?: string;
|
|
31
|
+
readonly stderr?: string;
|
|
32
|
+
}): string | null;
|
|
33
|
+
//# sourceMappingURL=spawn-status.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Windows NTSTATUS STATUS_DLL_INIT_FAILED (#3737). Unsigned and signed 32-bit. */
|
|
2
|
+
export const STATUS_DLL_INIT_FAILED = 0xc0000142;
|
|
3
|
+
const STATUS_DLL_INIT_FAILED_SIGNED = -1073741502;
|
|
4
|
+
export function unsignedExitStatus(status) {
|
|
5
|
+
return status >>> 0;
|
|
6
|
+
}
|
|
7
|
+
export function classifySpawnStatus(status, error) {
|
|
8
|
+
if (typeof status !== "number") {
|
|
9
|
+
if (typeof error?.code === "string" && error.code.length > 0) {
|
|
10
|
+
return error.code;
|
|
11
|
+
}
|
|
12
|
+
if (typeof error?.message === "string" && error.message.trim().length > 0) {
|
|
13
|
+
return error.message.trim();
|
|
14
|
+
}
|
|
15
|
+
return "spawn-failed";
|
|
16
|
+
}
|
|
17
|
+
const unsigned = unsignedExitStatus(status);
|
|
18
|
+
if (unsigned === STATUS_DLL_INIT_FAILED || status === STATUS_DLL_INIT_FAILED_SIGNED) {
|
|
19
|
+
return "0xC0000142 STATUS_DLL_INIT_FAILED";
|
|
20
|
+
}
|
|
21
|
+
if (unsigned >= 0xc0000000) {
|
|
22
|
+
return `0x${unsigned.toString(16).toUpperCase()}`;
|
|
23
|
+
}
|
|
24
|
+
return `exit ${status}`;
|
|
25
|
+
}
|
|
26
|
+
export function isAvailabilitySpawnFailure(result) {
|
|
27
|
+
if (result.error !== undefined) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (typeof result.status !== "number") {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
const unsigned = unsignedExitStatus(result.status);
|
|
34
|
+
const emptyOut = (result.stdout ?? "").trim().length === 0 && (result.stderr ?? "").trim().length === 0;
|
|
35
|
+
return (emptyOut &&
|
|
36
|
+
(unsigned === STATUS_DLL_INIT_FAILED || result.status === STATUS_DLL_INIT_FAILED_SIGNED));
|
|
37
|
+
}
|
|
38
|
+
export function formatScmSpawnDiagnostic(binary, status, stderr, error) {
|
|
39
|
+
const cls = classifySpawnStatus(status, error);
|
|
40
|
+
const err = stderr.trim();
|
|
41
|
+
if (err.length > 0) {
|
|
42
|
+
return `${binary} failed (${cls}): ${err}`;
|
|
43
|
+
}
|
|
44
|
+
return `${binary} failed (${cls}); stderr empty`;
|
|
45
|
+
}
|
|
46
|
+
/** Return `gh` when a cached-get ghx spawn failed and live gh is on PATH. */
|
|
47
|
+
export function ghxSpawnFallbackBinary(role, invoked, whichFn, failure) {
|
|
48
|
+
if (role !== "cached-get" || invoked !== "ghx" || whichFn("gh") === null) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return isAvailabilitySpawnFailure(failure) ? "gh" : null;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=spawn-status.js.map
|
|
@@ -58,7 +58,7 @@ export interface AcceptanceEvidenceGateResult {
|
|
|
58
58
|
readonly message: string;
|
|
59
59
|
readonly reports: readonly CriterionAcceptanceReport[];
|
|
60
60
|
/** How the #3357 walk obtained AC (#3387). */
|
|
61
|
-
readonly servedFrom?: "bank" | "cache" | "executed";
|
|
61
|
+
readonly servedFrom?: "bank" | "cache" | "executed" | "refused";
|
|
62
62
|
/** Which acceptance check decided the walk (#3497). Undefined when no walk ran. */
|
|
63
63
|
readonly predicate?: AcceptancePredicate;
|
|
64
64
|
}
|
package/dist/scope/transition.js
CHANGED
|
@@ -5,6 +5,7 @@ import { InstrumentedVbriefCrud, persistCrudMetrics } from "../eval/crud-telemet
|
|
|
5
5
|
import { assertProjectionContained, ProjectionContainmentError, } from "../fs/projection-containment.js";
|
|
6
6
|
import { applyClauseDerivationToPlan, maybeEmitAcceptanceStampFromChange, } from "../intake/clause-derivation.js";
|
|
7
7
|
import { hasArtifactSuffix } from "../layout/resolve.js";
|
|
8
|
+
import { stampExistingEnvelopes } from "../lifecycle/brief-envelope.js";
|
|
8
9
|
import { evaluateCompletedPlanConsistency } from "../lifecycle/completed-consistency.js";
|
|
9
10
|
import { evaluateLiteralAcceptanceFromPlan } from "../literal-acceptance/index.js";
|
|
10
11
|
import { evaluateAcceptanceActivateGate } from "./acceptance-activate-gate.js";
|
|
@@ -45,18 +46,6 @@ function advanceNonTerminalOwnItems(items, targetStatus) {
|
|
|
45
46
|
advanceNonTerminalOwnItems(obj.items, targetStatus);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Refresh the document envelope `updated` stamp to match `plan.updated`.
|
|
50
|
-
* Stamps whichever of xBRIEFInfo (v0.8) / vBRIEFInfo (v0.6) is present — never creates one (#2862 / #2346).
|
|
51
|
-
*/
|
|
52
|
-
function stampEnvelopeUpdated(data, nowIso) {
|
|
53
|
-
for (const key of ["xBRIEFInfo", "vBRIEFInfo"]) {
|
|
54
|
-
const env = data[key];
|
|
55
|
-
if (typeof env === "object" && env !== null && !Array.isArray(env)) {
|
|
56
|
-
env.updated = nowIso;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
49
|
export function runTransition(action, filePath, now = new Date(), options = {}) {
|
|
61
50
|
if (!(action in TRANSITIONS)) {
|
|
62
51
|
const valid = Object.keys(TRANSITIONS).sort().join(", ");
|
|
@@ -255,7 +244,8 @@ export function runTransition(action, filePath, now = new Date(), options = {})
|
|
|
255
244
|
planObj.status = targetStatus;
|
|
256
245
|
planObj.updated = nowIso;
|
|
257
246
|
// Keep the envelope clock aligned with plan.updated on every mutating transition (#2862).
|
|
258
|
-
|
|
247
|
+
// Stamps whichever envelope is present, never creates one (#3933 / #2346).
|
|
248
|
+
stampExistingEnvelopes(data, nowIso);
|
|
259
249
|
// Reconcile the completing brief's own plan.items (mirrors #1527 / #2566 registry sync) (#2862).
|
|
260
250
|
// On complete, items only reach here when #3240 evidence/disposition gate passed.
|
|
261
251
|
if (OWN_ITEMS_RECONCILE_ACTIONS.has(act)) {
|
|
@@ -412,7 +402,7 @@ function restampCompletedBrief(args) {
|
|
|
412
402
|
}
|
|
413
403
|
planObj.status = "completed";
|
|
414
404
|
planObj.updated = nowIso;
|
|
415
|
-
|
|
405
|
+
stampExistingEnvelopes(data, nowIso);
|
|
416
406
|
stampCompletionMetadata(planObj, projectRoot, nowIso, {
|
|
417
407
|
completedSessionId: resolveCompletionSessionId(projectRoot),
|
|
418
408
|
});
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { type AcPassBankingConfig } from "../policy/ac-pass-banking.js";
|
|
14
14
|
import type { HardEffortBudget, VerificationDepthPolicy } from "./effort-budget.js";
|
|
15
|
-
/** Durable bank ledger directory (
|
|
16
|
-
export declare const AC_PASS_BANK_DIR = ".deft/ac-pass-banks";
|
|
15
|
+
/** Durable bank ledger directory (under already-ignored `.deft/cache/`). */
|
|
16
|
+
export declare const AC_PASS_BANK_DIR = ".deft/cache/ac-pass-banks";
|
|
17
17
|
export declare const AC_PASS_BANK_SCHEMA_VERSION: 1;
|
|
18
18
|
/** Env path for optional JSONL run summary (#3282). Unset = silent. */
|
|
19
19
|
export declare const ENV_RUN_SUMMARY_PATH = "DEFT_RUN_SUMMARY_PATH";
|
|
@@ -18,8 +18,8 @@ import { DEFAULT_SURPLUS_THRESHOLD, resolveAcPassBanking, } from "../policy/ac-p
|
|
|
18
18
|
import { RunSummaryEmitter } from "../run-summary/emit.js";
|
|
19
19
|
import { detectHardEffortBudget, formatDeepeningSkippedNote, recommendVerificationDepth, } from "./effort-budget.js";
|
|
20
20
|
import { gitHead } from "./git.js";
|
|
21
|
-
/** Durable bank ledger directory (
|
|
22
|
-
export const AC_PASS_BANK_DIR = ".deft/ac-pass-banks";
|
|
21
|
+
/** Durable bank ledger directory (under already-ignored `.deft/cache/`). */
|
|
22
|
+
export const AC_PASS_BANK_DIR = ".deft/cache/ac-pass-banks";
|
|
23
23
|
export const AC_PASS_BANK_SCHEMA_VERSION = 1;
|
|
24
24
|
/** Env path for optional JSONL run summary (#3282). Unset = silent. */
|
|
25
25
|
export const ENV_RUN_SUMMARY_PATH = "DEFT_RUN_SUMMARY_PATH";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch-recorded child occupancy leases (#3999).
|
|
3
|
+
*
|
|
4
|
+
* A parent records the child's occupancy owner and the exact worktree root at
|
|
5
|
+
* dispatch in `.deft/child-occupancy/` — lease-gated, not `.deft-scratch/**`.
|
|
6
|
+
* The orchestration terminal transition already carries agent_id / parent_id /
|
|
7
|
+
* phase; this store is the missing occupancy-owner datum. Release reuses
|
|
8
|
+
* `releaseOccupancy` under the occupancy lock and only fires when the recorded
|
|
9
|
+
* child is still the current owner of the recorded tree.
|
|
10
|
+
*
|
|
11
|
+
* Per identity-source kind: `host-env` children are strangers and strand —
|
|
12
|
+
* that is the defect. `payload` parents share one id with their children, so
|
|
13
|
+
* the same transition is a no-op; auto-release would drop a live parent lease
|
|
14
|
+
* mid-flight. Swarm close-out of the launcher's occupancy_session_id is not
|
|
15
|
+
* the precedent and is not copied here.
|
|
16
|
+
*/
|
|
17
|
+
import type { LockDeps } from "../slice/lock.js";
|
|
18
|
+
import { type OccupancyDecision } from "./occupancy.js";
|
|
19
|
+
export declare const CHILD_OCCUPANCY_SCHEMA_VERSION = 1;
|
|
20
|
+
export declare const CHILD_OCCUPANCY_DIR: readonly [".deft", "child-occupancy"];
|
|
21
|
+
export declare const CHILD_OCCUPANCY_IDENTITY_SOURCE_KINDS: readonly ["host-env", "payload"];
|
|
22
|
+
export type ChildOccupancyIdentitySourceKind = (typeof CHILD_OCCUPANCY_IDENTITY_SOURCE_KINDS)[number];
|
|
23
|
+
export interface ChildOccupancyRecord {
|
|
24
|
+
readonly schemaVersion: number;
|
|
25
|
+
readonly agentId: string;
|
|
26
|
+
readonly parentId: string;
|
|
27
|
+
readonly occupancyOwner: string;
|
|
28
|
+
readonly worktreePath: string;
|
|
29
|
+
readonly identitySourceKind: ChildOccupancyIdentitySourceKind;
|
|
30
|
+
}
|
|
31
|
+
export interface ChildOccupancyDispatchInput {
|
|
32
|
+
readonly agentId: string;
|
|
33
|
+
readonly parentId: string;
|
|
34
|
+
readonly occupancyOwner: string;
|
|
35
|
+
readonly worktreePath: string;
|
|
36
|
+
readonly identitySourceKind: ChildOccupancyIdentitySourceKind;
|
|
37
|
+
}
|
|
38
|
+
export type ChildOccupancyReleaseReason = "released" | "already-free" | "owner-changed" | "payload-skip" | "missing-record" | "denied";
|
|
39
|
+
export interface ChildOccupancyReleaseResult {
|
|
40
|
+
readonly reason: ChildOccupancyReleaseReason;
|
|
41
|
+
readonly record: ChildOccupancyRecord | null;
|
|
42
|
+
readonly occupancy: OccupancyDecision | null;
|
|
43
|
+
}
|
|
44
|
+
/** Filename-safe agent id; the payload keeps the original. */
|
|
45
|
+
export declare function childOccupancyFileSegment(agentId: string): string;
|
|
46
|
+
export declare function childOccupancyRelpath(agentId: string): string[];
|
|
47
|
+
export declare function childOccupancyPath(storeRoot: string, agentId: string): string;
|
|
48
|
+
export declare function childOccupancyIdentitySourceKind(host: string): ChildOccupancyIdentitySourceKind | null;
|
|
49
|
+
export declare function readChildOccupancyLease(storeRoot: string, agentId: string): ChildOccupancyRecord | null;
|
|
50
|
+
/**
|
|
51
|
+
* Parent-only write at dispatch. Workers cannot author this store: `.deft/` is
|
|
52
|
+
* not assist-scratch, so a mutation write is occupancy-gated and an assist
|
|
53
|
+
* writer does not get the scratch carve-out.
|
|
54
|
+
*/
|
|
55
|
+
export declare function recordChildOccupancyLease(storeRoot: string, input: ChildOccupancyDispatchInput): ChildOccupancyRecord;
|
|
56
|
+
/**
|
|
57
|
+
* Compare-and-release under the occupancy lock. Caller identity is the id the
|
|
58
|
+
* parent recorded at dispatch — not the occupant currently named in the lease
|
|
59
|
+
* file, and not a field on a worker-authored heartbeat.
|
|
60
|
+
*/
|
|
61
|
+
export declare function releaseChildOccupancyOnTerminal(storeRoot: string, input: {
|
|
62
|
+
readonly agentId: string;
|
|
63
|
+
readonly now?: Date;
|
|
64
|
+
readonly lockDeps?: LockDeps;
|
|
65
|
+
}): ChildOccupancyReleaseResult;
|
|
66
|
+
/**
|
|
67
|
+
* Worktree guesses for a heartbeat file. Canonical layout is
|
|
68
|
+
* `<worktree>/.deft-scratch/subagent-status/<agent>.json`; cwd is the fallback
|
|
69
|
+
* when the scratch dir was passed as a custom path.
|
|
70
|
+
*/
|
|
71
|
+
export declare function worktreeCandidatesForHeartbeat(heartbeatPath: string, cwd: string): readonly string[];
|
|
72
|
+
//# sourceMappingURL=child-occupancy.d.ts.map
|