@lannguyensi/harness 0.10.1 → 0.12.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/CHANGELOG.md +160 -7
- package/README.md +99 -58
- package/dist/cli/apply/apply.js +19 -3
- package/dist/cli/apply/apply.js.map +1 -1
- package/dist/cli/approve/understanding.d.ts +8 -0
- package/dist/cli/approve/understanding.js +154 -15
- package/dist/cli/approve/understanding.js.map +1 -1
- package/dist/cli/audit.d.ts +8 -0
- package/dist/cli/audit.js +2 -2
- package/dist/cli/audit.js.map +1 -1
- package/dist/cli/doctor/codex.d.ts +6 -1
- package/dist/cli/doctor/codex.js +10 -6
- package/dist/cli/doctor/codex.js.map +1 -1
- package/dist/cli/doctor/format.js +7 -1
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.js +62 -5
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +15 -0
- package/dist/cli/dry-run.js +9 -3
- package/dist/cli/dry-run.js.map +1 -1
- package/dist/cli/explain.d.ts +8 -0
- package/dist/cli/explain.js +6 -4
- package/dist/cli/explain.js.map +1 -1
- package/dist/cli/gate/disable.d.ts +42 -0
- package/dist/cli/gate/disable.js +199 -0
- package/dist/cli/gate/disable.js.map +1 -0
- package/dist/cli/gate/enable.d.ts +33 -0
- package/dist/cli/gate/enable.js +127 -0
- package/dist/cli/gate/enable.js.map +1 -0
- package/dist/cli/gate/snapshot.d.ts +65 -0
- package/dist/cli/gate/snapshot.js +119 -0
- package/dist/cli/gate/snapshot.js.map +1 -0
- package/dist/cli/index.js +141 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/dependencies.js +17 -7
- package/dist/cli/init/dependencies.js.map +1 -1
- package/dist/cli/init/templates.d.ts +1 -1
- package/dist/cli/init/templates.js +14 -5
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/pack/hook-pre-tool-use.d.ts +2 -0
- package/dist/cli/pack/hook-pre-tool-use.js +34 -2
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
- package/dist/cli/policy/intercept.d.ts +7 -1
- package/dist/cli/policy/intercept.js +28 -6
- package/dist/cli/policy/intercept.js.map +1 -1
- package/dist/cli/session-start/index.d.ts +75 -0
- package/dist/cli/session-start/index.js +232 -0
- package/dist/cli/session-start/index.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +27 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +32 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +16 -1
- package/dist/policy-packs/builtin/understanding-before-execution.js +35 -7
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
- package/dist/policy-packs/expand.d.ts +3 -1
- package/dist/policy-packs/expand.js +2 -2
- package/dist/policy-packs/expand.js.map +1 -1
- package/dist/policy-packs/index.d.ts +1 -1
- package/dist/policy-packs/index.js.map +1 -1
- package/dist/policy-packs/registry.d.ts +2 -1
- package/dist/policy-packs/registry.js +2 -2
- package/dist/policy-packs/registry.js.map +1 -1
- package/dist/runtime/git-context.d.ts +16 -0
- package/dist/runtime/git-context.js +97 -0
- package/dist/runtime/git-context.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pending-approval.d.ts +31 -0
- package/dist/runtime/pending-approval.js +80 -0
- package/dist/runtime/pending-approval.js.map +1 -0
- package/dist/runtime/session-id.d.ts +40 -1
- package/dist/runtime/session-id.js +99 -8
- package/dist/runtime/session-id.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy-packs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy-packs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GAGf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,cAAc,EACd,eAAe,EACf,SAAS,EACT,YAAY,GAEb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAmD,MAAM,aAAa,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PolicyPack } from "../schema/index.js";
|
|
2
|
+
import { type ResolvePackOptions } from "./builtin/understanding-before-execution.js";
|
|
2
3
|
import { type Runtime } from "./runtime.js";
|
|
3
4
|
import type { PackContribution } from "./types.js";
|
|
4
5
|
export declare const KNOWN_BUILTIN_PACKS: readonly ["understanding-before-execution"];
|
|
@@ -8,4 +9,4 @@ export interface ResolveBuiltinResult {
|
|
|
8
9
|
contribution: PackContribution;
|
|
9
10
|
warnings: string[];
|
|
10
11
|
}
|
|
11
|
-
export declare function resolveBuiltin(pack: PolicyPack, runtime?: Runtime): ResolveBuiltinResult | null;
|
|
12
|
+
export declare function resolveBuiltin(pack: PolicyPack, runtime?: Runtime, opts?: ResolvePackOptions): ResolveBuiltinResult | null;
|
|
@@ -9,12 +9,12 @@ export const KNOWN_BUILTIN_PACKS = [UNDERSTANDING_BEFORE_EXECUTION];
|
|
|
9
9
|
export function isBuiltinPackName(name) {
|
|
10
10
|
return KNOWN_BUILTIN_PACKS.includes(name);
|
|
11
11
|
}
|
|
12
|
-
export function resolveBuiltin(pack, runtime = DEFAULT_RUNTIME) {
|
|
12
|
+
export function resolveBuiltin(pack, runtime = DEFAULT_RUNTIME, opts = {}) {
|
|
13
13
|
if (!isBuiltinPackName(pack.name))
|
|
14
14
|
return null;
|
|
15
15
|
switch (pack.name) {
|
|
16
16
|
case UNDERSTANDING_BEFORE_EXECUTION:
|
|
17
|
-
return resolveUnderstandingBeforeExecution(pack, runtime);
|
|
17
|
+
return resolveUnderstandingBeforeExecution(pack, runtime, opts);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/policy-packs/registry.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AAGnE,OAAO,EACL,SAAS,IAAI,8BAA8B,EAC3C,OAAO,IAAI,mCAAmC,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/policy-packs/registry.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AAGnE,OAAO,EACL,SAAS,IAAI,8BAA8B,EAC3C,OAAO,IAAI,mCAAmC,GAE/C,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,eAAe,EAAgB,MAAM,cAAc,CAAC;AAG7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,8BAA8B,CAAU,CAAC;AAG7E,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAQ,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAOD,MAAM,UAAU,cAAc,CAC5B,IAAgB,EAChB,UAAmB,eAAe,EAClC,OAA2B,EAAE;IAE7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,QAAQ,IAAI,CAAC,IAAuB,EAAE,CAAC;QACrC,KAAK,8BAA8B;YACjC,OAAO,mCAAmC,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GitRepoContext {
|
|
2
|
+
/** Basename of the work-tree root, or "" when `cwd` is not in a repo. */
|
|
3
|
+
repo: string;
|
|
4
|
+
/**
|
|
5
|
+
* Current branch name, or "" when not in a repo or HEAD is detached
|
|
6
|
+
* (a raw SHA — there is no branch to name).
|
|
7
|
+
*/
|
|
8
|
+
branch: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Resolve `{ repo, branch }` for a working directory. Returns empty
|
|
12
|
+
* strings (never throws) when `cwd` is not inside a git work tree, or
|
|
13
|
+
* when any individual lookup fails — callers treat "" as "unknown" and
|
|
14
|
+
* fall through to their own behaviour.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveGitContext(cwd: string): GitRepoContext;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Resolves the `REPO` and `BRANCH` policy builtins from a working
|
|
2
|
+
// directory.
|
|
3
|
+
//
|
|
4
|
+
// The intercept engine exposes `${REPO}` / `${BRANCH}` as `ledger_tag`
|
|
5
|
+
// template builtins, but they were only ever populated from the
|
|
6
|
+
// `HARNESS_REPO` / `HARNESS_BRANCH` env vars — which nothing sets — so
|
|
7
|
+
// every `preflight:${REPO}` tag collapsed to the literal `preflight:`.
|
|
8
|
+
// That silently degraded the founding-incident policies to one global
|
|
9
|
+
// tag: a preflight done in repo A satisfied the gate in repo B.
|
|
10
|
+
//
|
|
11
|
+
// This module derives both values from the filesystem, not a `git`
|
|
12
|
+
// subprocess: the intercept hook runs on every Bash / Edit / Write
|
|
13
|
+
// tool call, so the resolution must stay cheap. A bounded walk up the
|
|
14
|
+
// directory tree to find `.git`, plus one small `HEAD` read, is
|
|
15
|
+
// microseconds and spawns no process.
|
|
16
|
+
//
|
|
17
|
+
// It is a deliberate approximation of `git rev-parse`: it reads the
|
|
18
|
+
// work tree's basename and `.git/HEAD` directly and does NOT consult
|
|
19
|
+
// `GIT_DIR` / `GIT_WORK_TREE` / `core.worktree`. For namespacing a
|
|
20
|
+
// ledger tag, the on-disk layout is the right (and more stable)
|
|
21
|
+
// signal; those exotic overrides are out of scope.
|
|
22
|
+
import * as fs from "node:fs";
|
|
23
|
+
import * as path from "node:path";
|
|
24
|
+
const EMPTY = { repo: "", branch: "" };
|
|
25
|
+
// A `.git` *file* (linked worktree / submodule) points at the real git
|
|
26
|
+
// dir: `gitdir: <path>`.
|
|
27
|
+
const GITDIR_RE = /^gitdir:\s*(.+)$/;
|
|
28
|
+
// `.git/HEAD` on a branch: `ref: refs/heads/<branch>`. A detached HEAD
|
|
29
|
+
// holds a raw SHA instead and matches nothing here.
|
|
30
|
+
const HEAD_REF_RE = /^ref:\s*refs\/heads\/(.+)$/;
|
|
31
|
+
/**
|
|
32
|
+
* Walk up from `startDir` looking for a `.git` entry. Handles both the
|
|
33
|
+
* common `.git` directory and the `.git` *file* form used by linked
|
|
34
|
+
* worktrees and submodules. The walk is bounded so a pathologically
|
|
35
|
+
* deep cwd cannot spin.
|
|
36
|
+
*/
|
|
37
|
+
function findGitEntry(startDir) {
|
|
38
|
+
let dir = path.resolve(startDir);
|
|
39
|
+
for (let depth = 0; depth < 128; depth++) {
|
|
40
|
+
const dotGit = path.join(dir, ".git");
|
|
41
|
+
let stat;
|
|
42
|
+
try {
|
|
43
|
+
stat = fs.statSync(dotGit);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
stat = undefined;
|
|
47
|
+
}
|
|
48
|
+
if (stat?.isDirectory()) {
|
|
49
|
+
return { worktreeRoot: dir, gitDir: dotGit };
|
|
50
|
+
}
|
|
51
|
+
if (stat?.isFile()) {
|
|
52
|
+
let gitDir = "";
|
|
53
|
+
try {
|
|
54
|
+
const match = GITDIR_RE.exec(fs.readFileSync(dotGit, "utf8").trim());
|
|
55
|
+
if (match)
|
|
56
|
+
gitDir = path.resolve(dir, match[1].trim());
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
/* unreadable `.git` file — leave gitDir empty, repo still resolves */
|
|
60
|
+
}
|
|
61
|
+
return { worktreeRoot: dir, gitDir };
|
|
62
|
+
}
|
|
63
|
+
const parent = path.dirname(dir);
|
|
64
|
+
if (parent === dir)
|
|
65
|
+
return null; // hit the filesystem root
|
|
66
|
+
dir = parent;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve `{ repo, branch }` for a working directory. Returns empty
|
|
72
|
+
* strings (never throws) when `cwd` is not inside a git work tree, or
|
|
73
|
+
* when any individual lookup fails — callers treat "" as "unknown" and
|
|
74
|
+
* fall through to their own behaviour.
|
|
75
|
+
*/
|
|
76
|
+
export function resolveGitContext(cwd) {
|
|
77
|
+
if (typeof cwd !== "string" || cwd.length === 0)
|
|
78
|
+
return EMPTY;
|
|
79
|
+
const entry = findGitEntry(cwd);
|
|
80
|
+
if (!entry)
|
|
81
|
+
return EMPTY;
|
|
82
|
+
const repo = path.basename(entry.worktreeRoot);
|
|
83
|
+
let branch = "";
|
|
84
|
+
if (entry.gitDir) {
|
|
85
|
+
try {
|
|
86
|
+
const head = fs.readFileSync(path.join(entry.gitDir, "HEAD"), "utf8").trim();
|
|
87
|
+
const match = HEAD_REF_RE.exec(head);
|
|
88
|
+
if (match)
|
|
89
|
+
branch = match[1].trim();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
/* unreadable HEAD — branch stays "" */
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { repo, branch };
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=git-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-context.js","sourceRoot":"","sources":["../../src/runtime/git-context.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { intercept, type ClaudeDenyJson, type InterceptOptions, type InterceptResult, type LedgerClient, type PolicyDecision, type PolicyOutcome, type ToolEvent, } from "./intercept.js";
|
|
2
2
|
export { recordPolicyDecision, payloadFromDecision, encodeLedgerContent, decodeLedgerContent, decisionSortKey, type LedgerRecordOptions, type PolicyDecisionPayload, } from "./ledger-record.js";
|
|
3
3
|
export { resolveSessionId } from "./session-id.js";
|
|
4
|
+
export { resolveGitContext, type GitRepoContext } from "./git-context.js";
|
|
4
5
|
export { addLedgerFact, type AddLedgerFactOptions, type AddLedgerFactResult, } from "./ledger-add.js";
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { intercept, } from "./intercept.js";
|
|
2
2
|
export { recordPolicyDecision, payloadFromDecision, encodeLedgerContent, decodeLedgerContent, decisionSortKey, } from "./ledger-record.js";
|
|
3
3
|
export { resolveSessionId } from "./session-id.js";
|
|
4
|
+
export { resolveGitContext } from "./git-context.js";
|
|
4
5
|
export { addLedgerFact, } from "./ledger-add.js";
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,GAQV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EACL,aAAa,GAGd,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,GAQV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAuB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,aAAa,GAGd,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const GENERATED_DIRNAME = "harness.generated";
|
|
2
|
+
export declare const PENDING_APPROVAL_BASENAME = ".pending-approval";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve `harness.generated/` the way `harness apply` does: a sibling of
|
|
5
|
+
* the manifest, unless an explicit `homeDir` override is in play (tests,
|
|
6
|
+
* non-default home).
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveGeneratedDir(opts: {
|
|
9
|
+
homeDir?: string;
|
|
10
|
+
manifestPath: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function pendingApprovalPath(generatedDir: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Producer: stage `sessionId` for a later `harness approve`. `atomicWriteFile`
|
|
15
|
+
* creates `generatedDir` if missing, so a hand-wired hook with no prior
|
|
16
|
+
* apply still benefits. Callers treat this as best-effort — a write
|
|
17
|
+
* failure must never escalate a gate block into a thrown hook error.
|
|
18
|
+
*/
|
|
19
|
+
export declare function writePendingApproval(generatedDir: string, sessionId: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Consumer: read the staged session id, or null when the file is absent,
|
|
22
|
+
* empty, whitespace-only, or unreadable. Trims the trailing newline the
|
|
23
|
+
* producer writes plus any surrounding whitespace.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readPendingApproval(generatedDir: string): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Consumer: drop the staging file once its id has been consumed, so a
|
|
28
|
+
* later arg-less `harness approve` cannot revive a stale session id.
|
|
29
|
+
* Best-effort — a missing file counts as success.
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearPendingApproval(generatedDir: string): void;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Task 33abc147 — `.pending-approval` session-id staging file.
|
|
2
|
+
//
|
|
3
|
+
// The understanding-gate PreToolUse hook knows the running session's
|
|
4
|
+
// exact `session_id` (it arrives on the hook event's stdin). `harness
|
|
5
|
+
// approve`, run from the operator's `!`-shell, does NOT: $CLAUDE_SESSION_ID
|
|
6
|
+
// is unset in that shell, and guessing the id from the newest project
|
|
7
|
+
// transcript is a heuristic that breaks on subagent / parallel-session
|
|
8
|
+
// transcripts (the approve error message warns about exactly that).
|
|
9
|
+
//
|
|
10
|
+
// So the producer hands the id off instead of making the consumer guess:
|
|
11
|
+
// on every block / ask the gate hook writes the `session_id` to
|
|
12
|
+
// `<generatedDir>/.pending-approval`, and `harness approve` reads it when
|
|
13
|
+
// no `--session` flag and no `$CLAUDE_SESSION_ID` are given. Deterministic,
|
|
14
|
+
// not a guess.
|
|
15
|
+
//
|
|
16
|
+
// `harness apply` only writes its own known files into harness.generated/
|
|
17
|
+
// (it never wipes the directory), so the staging file survives applies.
|
|
18
|
+
// `harness approve` deletes it after a successful resolve so a later
|
|
19
|
+
// arg-less invocation cannot revive a stale session id.
|
|
20
|
+
import * as fs from "node:fs";
|
|
21
|
+
import * as path from "node:path";
|
|
22
|
+
import { atomicWriteFile } from "../io/atomic-write.js";
|
|
23
|
+
// Mirrors `GENERATED_DIRNAME` in cli/apply/apply.ts — also independently
|
|
24
|
+
// duplicated in cli/pack/remove.ts and cli/diff/since-apply.ts. The
|
|
25
|
+
// constant has no single home yet; consolidating the four copies is a
|
|
26
|
+
// separate cleanup.
|
|
27
|
+
export const GENERATED_DIRNAME = "harness.generated";
|
|
28
|
+
export const PENDING_APPROVAL_BASENAME = ".pending-approval";
|
|
29
|
+
/**
|
|
30
|
+
* Resolve `harness.generated/` the way `harness apply` does: a sibling of
|
|
31
|
+
* the manifest, unless an explicit `homeDir` override is in play (tests,
|
|
32
|
+
* non-default home).
|
|
33
|
+
*/
|
|
34
|
+
export function resolveGeneratedDir(opts) {
|
|
35
|
+
if (opts.homeDir !== undefined)
|
|
36
|
+
return path.join(opts.homeDir, GENERATED_DIRNAME);
|
|
37
|
+
return path.join(path.dirname(opts.manifestPath), GENERATED_DIRNAME);
|
|
38
|
+
}
|
|
39
|
+
export function pendingApprovalPath(generatedDir) {
|
|
40
|
+
return path.join(generatedDir, PENDING_APPROVAL_BASENAME);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Producer: stage `sessionId` for a later `harness approve`. `atomicWriteFile`
|
|
44
|
+
* creates `generatedDir` if missing, so a hand-wired hook with no prior
|
|
45
|
+
* apply still benefits. Callers treat this as best-effort — a write
|
|
46
|
+
* failure must never escalate a gate block into a thrown hook error.
|
|
47
|
+
*/
|
|
48
|
+
export function writePendingApproval(generatedDir, sessionId) {
|
|
49
|
+
atomicWriteFile(pendingApprovalPath(generatedDir), `${sessionId}\n`);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Consumer: read the staged session id, or null when the file is absent,
|
|
53
|
+
* empty, whitespace-only, or unreadable. Trims the trailing newline the
|
|
54
|
+
* producer writes plus any surrounding whitespace.
|
|
55
|
+
*/
|
|
56
|
+
export function readPendingApproval(generatedDir) {
|
|
57
|
+
let raw;
|
|
58
|
+
try {
|
|
59
|
+
raw = fs.readFileSync(pendingApprovalPath(generatedDir), "utf8");
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const trimmed = raw.trim();
|
|
65
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Consumer: drop the staging file once its id has been consumed, so a
|
|
69
|
+
* later arg-less `harness approve` cannot revive a stale session id.
|
|
70
|
+
* Best-effort — a missing file counts as success.
|
|
71
|
+
*/
|
|
72
|
+
export function clearPendingApproval(generatedDir) {
|
|
73
|
+
try {
|
|
74
|
+
fs.rmSync(pendingApprovalPath(generatedDir));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
/* already gone (or never written) — nothing to clean up */
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=pending-approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-approval.js","sourceRoot":"","sources":["../../src/runtime/pending-approval.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,4EAA4E;AAC5E,sEAAsE;AACtE,uEAAuE;AACvE,oEAAoE;AACpE,EAAE;AACF,yEAAyE;AACzE,gEAAgE;AAChE,0EAA0E;AAC1E,4EAA4E;AAC5E,eAAe;AACf,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,qEAAqE;AACrE,wDAAwD;AAExD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,yEAAyE;AACzE,oEAAoE;AACpE,sEAAsE;AACtE,oBAAoB;AACpB,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,MAAM,CAAC,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAGnC;IACC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAoB,EAAE,SAAiB;IAC1E,eAAe,CAAC,mBAAmB,CAAC,YAAY,CAAC,EAAE,GAAG,SAAS,IAAI,CAAC,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAoB;IACvD,IAAI,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve the active grounding session id.
|
|
2
|
+
* Resolve the active grounding session id (WRITE path).
|
|
3
3
|
*
|
|
4
4
|
* Empty strings are treated as "not provided" — both for the explicit
|
|
5
5
|
* argument and for the env var, since `--session ''` from a forgetful
|
|
@@ -8,3 +8,42 @@
|
|
|
8
8
|
* empty session.
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveSessionId(explicit?: string): string;
|
|
11
|
+
export interface DiscoverSessionOptions {
|
|
12
|
+
/** Override the Claude Code projects root (tests). */
|
|
13
|
+
projectsRoot?: string;
|
|
14
|
+
/** Override `$HOME` used to derive the projects root (tests). */
|
|
15
|
+
homeDir?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Discover the current Claude Code session id from the most recently
|
|
19
|
+
* modified transcript JSONL under `~/.claude/projects/<project>/`.
|
|
20
|
+
*
|
|
21
|
+
* Claude Code appends to the active session's transcript live, so the
|
|
22
|
+
* newest-mtime `<uuid>.jsonl` across all project dirs is the running
|
|
23
|
+
* session. Returns `null` when the projects root is absent or holds no
|
|
24
|
+
* transcript files — callers fall through to their own default.
|
|
25
|
+
*/
|
|
26
|
+
export declare function discoverNewestSessionId(opts?: DiscoverSessionOptions): string | null;
|
|
27
|
+
export interface ResolveReadSessionOptions extends DiscoverSessionOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Test seam — override the transcript-discovery tier wholesale. The
|
|
30
|
+
* default scans the real `~/.claude/projects` via
|
|
31
|
+
* `discoverNewestSessionId`.
|
|
32
|
+
*/
|
|
33
|
+
discover?: (opts: DiscoverSessionOptions) => string | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the session id for the READ path (`audit`,
|
|
37
|
+
* `explain --trace/--last`).
|
|
38
|
+
*
|
|
39
|
+
* Precedence:
|
|
40
|
+
* 1. explicit value (the `--session` flag)
|
|
41
|
+
* 2. `$CLAUDE_SESSION_ID` env
|
|
42
|
+
* 3. newest Claude Code transcript (the live session)
|
|
43
|
+
* 4. literal `"default"`
|
|
44
|
+
*
|
|
45
|
+
* The WRITE path keeps `resolveSessionId`: it always has
|
|
46
|
+
* `event.session_id`, so it never reaches the discovery tier, and a
|
|
47
|
+
* per-hook-event filesystem scan would be wasteful.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveReadSessionId(explicit?: string, opts?: ResolveReadSessionOptions): string;
|
|
@@ -9,16 +9,28 @@
|
|
|
9
9
|
// audit/trace even though the writes had landed correctly under the
|
|
10
10
|
// real UUID.
|
|
11
11
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// 3. literal `"default"`
|
|
18
|
-
//
|
|
12
|
+
// `resolveSessionId` lifts the precedence chain into one place for the
|
|
13
|
+
// WRITE path (`policy intercept`), which always carries a concrete
|
|
14
|
+
// `event.session_id`:
|
|
15
|
+
// 1. explicit value (the runtime's `event.session_id`)
|
|
16
|
+
// 2. `$CLAUDE_SESSION_ID` env
|
|
17
|
+
// 3. literal `"default"`
|
|
18
|
+
//
|
|
19
|
+
// The READ path (`audit`, `explain --trace/--last`) needs more. The
|
|
20
|
+
// Phase 5 #2 fix assumed `$CLAUDE_SESSION_ID` is exported into the
|
|
21
|
+
// session's shell environment — it is not (Claude Code does not put it
|
|
22
|
+
// in the Bash tool env), so tier 2 is inert in practice and the readers
|
|
23
|
+
// still fell through to `"default"`. `resolveReadSessionId` adds a
|
|
24
|
+
// transcript-discovery tier: when no explicit id and no env, it reads
|
|
25
|
+
// the active session id off the newest Claude Code transcript JSONL.
|
|
26
|
+
// That is the programmatic form of the heuristic `harness approve`'s
|
|
27
|
+
// own help text recommends to humans.
|
|
28
|
+
import * as fs from "node:fs";
|
|
29
|
+
import * as os from "node:os";
|
|
30
|
+
import * as path from "node:path";
|
|
19
31
|
const FALLBACK = "default";
|
|
20
32
|
/**
|
|
21
|
-
* Resolve the active grounding session id.
|
|
33
|
+
* Resolve the active grounding session id (WRITE path).
|
|
22
34
|
*
|
|
23
35
|
* Empty strings are treated as "not provided" — both for the explicit
|
|
24
36
|
* argument and for the env var, since `--session ''` from a forgetful
|
|
@@ -34,4 +46,83 @@ export function resolveSessionId(explicit) {
|
|
|
34
46
|
return env;
|
|
35
47
|
return FALLBACK;
|
|
36
48
|
}
|
|
49
|
+
// Claude Code names each session's transcript `<uuid>.jsonl`. Anchored
|
|
50
|
+
// so sibling files (memory dirs, `.pending-approval`, etc.) are ignored.
|
|
51
|
+
const SESSION_TRANSCRIPT_RE = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
|
|
52
|
+
/**
|
|
53
|
+
* Discover the current Claude Code session id from the most recently
|
|
54
|
+
* modified transcript JSONL under `~/.claude/projects/<project>/`.
|
|
55
|
+
*
|
|
56
|
+
* Claude Code appends to the active session's transcript live, so the
|
|
57
|
+
* newest-mtime `<uuid>.jsonl` across all project dirs is the running
|
|
58
|
+
* session. Returns `null` when the projects root is absent or holds no
|
|
59
|
+
* transcript files — callers fall through to their own default.
|
|
60
|
+
*/
|
|
61
|
+
export function discoverNewestSessionId(opts = {}) {
|
|
62
|
+
const projectsRoot = opts.projectsRoot ??
|
|
63
|
+
path.join(opts.homeDir ?? os.homedir(), ".claude", "projects");
|
|
64
|
+
let projectDirs;
|
|
65
|
+
try {
|
|
66
|
+
projectDirs = fs.readdirSync(projectsRoot);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
let newest = null;
|
|
72
|
+
for (const dir of projectDirs) {
|
|
73
|
+
const projectPath = path.join(projectsRoot, dir);
|
|
74
|
+
let files;
|
|
75
|
+
try {
|
|
76
|
+
files = fs.readdirSync(projectPath);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
continue; // not a directory, or unreadable — skip
|
|
80
|
+
}
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
const match = SESSION_TRANSCRIPT_RE.exec(file);
|
|
83
|
+
if (!match)
|
|
84
|
+
continue;
|
|
85
|
+
let mtimeMs;
|
|
86
|
+
try {
|
|
87
|
+
mtimeMs = fs.statSync(path.join(projectPath, file)).mtimeMs;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (newest === null || mtimeMs > newest.mtimeMs) {
|
|
93
|
+
newest = { id: match[1], mtimeMs };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return newest === null ? null : newest.id;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolve the session id for the READ path (`audit`,
|
|
101
|
+
* `explain --trace/--last`).
|
|
102
|
+
*
|
|
103
|
+
* Precedence:
|
|
104
|
+
* 1. explicit value (the `--session` flag)
|
|
105
|
+
* 2. `$CLAUDE_SESSION_ID` env
|
|
106
|
+
* 3. newest Claude Code transcript (the live session)
|
|
107
|
+
* 4. literal `"default"`
|
|
108
|
+
*
|
|
109
|
+
* The WRITE path keeps `resolveSessionId`: it always has
|
|
110
|
+
* `event.session_id`, so it never reaches the discovery tier, and a
|
|
111
|
+
* per-hook-event filesystem scan would be wasteful.
|
|
112
|
+
*/
|
|
113
|
+
export function resolveReadSessionId(explicit, opts = {}) {
|
|
114
|
+
if (typeof explicit === "string" && explicit.length > 0)
|
|
115
|
+
return explicit;
|
|
116
|
+
const env = process.env.CLAUDE_SESSION_ID;
|
|
117
|
+
if (typeof env === "string" && env.length > 0)
|
|
118
|
+
return env;
|
|
119
|
+
const discover = opts.discover ?? discoverNewestSessionId;
|
|
120
|
+
const discovered = discover({
|
|
121
|
+
...(opts.projectsRoot !== undefined && { projectsRoot: opts.projectsRoot }),
|
|
122
|
+
...(opts.homeDir !== undefined && { homeDir: opts.homeDir }),
|
|
123
|
+
});
|
|
124
|
+
if (typeof discovered === "string" && discovered.length > 0)
|
|
125
|
+
return discovered;
|
|
126
|
+
return FALLBACK;
|
|
127
|
+
}
|
|
37
128
|
//# sourceMappingURL=session-id.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-id.js","sourceRoot":"","sources":["../../src/runtime/session-id.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,uEAAuE;AACvE,iEAAiE;AACjE,qEAAqE;AACrE,8DAA8D;AAC9D,wEAAwE;AACxE,iEAAiE;AACjE,oEAAoE;AACpE,aAAa;AACb,EAAE;AACF,yDAAyD;AACzD,
|
|
1
|
+
{"version":3,"file":"session-id.js","sourceRoot":"","sources":["../../src/runtime/session-id.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lannguyensi/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Declarative control plane for agent harnesses — one YAML for grounding, tools, memory, and hooks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/LanNguyenSi/harness",
|