@lannguyensi/harness 0.30.0 → 0.31.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +8 -2
  3. package/dist/cli/doctor/format.js +4 -0
  4. package/dist/cli/doctor/format.js.map +1 -1
  5. package/dist/cli/index.js +27 -0
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/pack/hook-branch-protection.js +2 -1
  8. package/dist/cli/pack/hook-branch-protection.js.map +1 -1
  9. package/dist/cli/pack/hook-codex-pre-tool-use.js +4 -3
  10. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
  11. package/dist/cli/pack/hook-codex-stop.js +1 -0
  12. package/dist/cli/pack/hook-codex-stop.js.map +1 -1
  13. package/dist/cli/pack/hook-post-tool-use.js +1 -0
  14. package/dist/cli/pack/hook-post-tool-use.js.map +1 -1
  15. package/dist/cli/pack/hook-pre-tool-use.js +3 -2
  16. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  17. package/dist/cli/pack/hook-runtime-reality.d.ts +50 -0
  18. package/dist/cli/pack/hook-runtime-reality.js +160 -0
  19. package/dist/cli/pack/hook-runtime-reality.js.map +1 -0
  20. package/dist/cli/pack/hook-stay-in-scope.d.ts +58 -0
  21. package/dist/cli/pack/hook-stay-in-scope.js +315 -0
  22. package/dist/cli/pack/hook-stay-in-scope.js.map +1 -0
  23. package/dist/cli/pause/index.d.ts +17 -3
  24. package/dist/cli/pause/index.js +30 -6
  25. package/dist/cli/pause/index.js.map +1 -1
  26. package/dist/cli/policy/intercept.js +56 -3
  27. package/dist/cli/policy/intercept.js.map +1 -1
  28. package/dist/cli/session-start/branch-check.js +4 -2
  29. package/dist/cli/session-start/branch-check.js.map +1 -1
  30. package/dist/cli/session-start/index.js +4 -2
  31. package/dist/cli/session-start/index.js.map +1 -1
  32. package/dist/policy-packs/builtin/understanding-before-execution.js +26 -0
  33. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  34. package/dist/runtime/bash-prefix-parse.d.ts +13 -0
  35. package/dist/runtime/bash-prefix-parse.js +172 -0
  36. package/dist/runtime/bash-prefix-parse.js.map +1 -0
  37. package/dist/runtime/risk-classifier.js +64 -0
  38. package/dist/runtime/risk-classifier.js.map +1 -1
  39. package/dist/runtime/session-id.d.ts +4 -3
  40. package/dist/runtime/session-id.js +17 -5
  41. package/dist/runtime/session-id.js.map +1 -1
  42. package/package.json +3 -1
  43. package/scripts/runtime-reality-docker-probe.mjs +71 -0
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ // Docker probe for the runtime-reality PreToolUse hook.
3
+ //
4
+ // Contract (see `harness pack hook runtime-reality`): print a JSON array
5
+ // of ActualProcessState `{ name, running, startup_mode, port }` on stdout,
6
+ // one entry per running/known container. The hook spawns this via
7
+ // RUNTIME_REALITY_PROBE_CMD, parses stdout, and compares it against the
8
+ // keyword's expectations file. A non-zero exit or non-JSON output is
9
+ // treated by the hook as "probe failed" (fail-open unless
10
+ // RUNTIME_REALITY_PROBE_FAIL_BLOCK=1) — so this script must either emit a
11
+ // valid array or exit non-zero, never print partial garbage.
12
+ //
13
+ // Host-coupling lives here on purpose: the agent-grounding package stays
14
+ // probe-agnostic; this is the harness-side concrete probe. Copy/adapt it
15
+ // for systemd or pm2 hosts.
16
+
17
+ import { execFileSync } from "node:child_process";
18
+
19
+ /** Pull the first published host port out of a `docker ps` Ports string,
20
+ * e.g. "0.0.0.0:3001->3001/tcp, :::3001->3001/tcp" -> 3001. Returns
21
+ * undefined when the container publishes no host port. */
22
+ function firstHostPort(ports) {
23
+ if (typeof ports !== "string") return undefined;
24
+ const m = ports.match(/:(\d+)->/);
25
+ if (!m) return undefined;
26
+ const n = Number.parseInt(m[1], 10);
27
+ return Number.isFinite(n) ? n : undefined;
28
+ }
29
+
30
+ function main() {
31
+ let raw;
32
+ try {
33
+ raw = execFileSync("docker", ["ps", "--format", "{{json .}}"], {
34
+ encoding: "utf8",
35
+ timeout: 8000,
36
+ maxBuffer: 4 * 1024 * 1024,
37
+ });
38
+ } catch (err) {
39
+ process.stderr.write(`docker-probe: docker ps failed: ${String(err)}\n`);
40
+ process.exit(1);
41
+ }
42
+
43
+ const states = [];
44
+ for (const line of raw.split("\n")) {
45
+ const trimmed = line.trim();
46
+ if (!trimmed) continue;
47
+ let row;
48
+ try {
49
+ row = JSON.parse(trimmed);
50
+ } catch {
51
+ // A single malformed line shouldn't sink the whole probe; skip it.
52
+ continue;
53
+ }
54
+ // `docker ps` may join multiple names with commas; the first is the
55
+ // canonical container name expectations are written against.
56
+ const name = String(row.Names ?? "").split(",")[0].trim();
57
+ if (!name) continue;
58
+ const state = {
59
+ name,
60
+ running: row.State === "running",
61
+ startup_mode: "docker",
62
+ };
63
+ const port = firstHostPort(row.Ports);
64
+ if (port !== undefined) state.port = port;
65
+ states.push(state);
66
+ }
67
+
68
+ process.stdout.write(JSON.stringify(states) + "\n");
69
+ }
70
+
71
+ main();