@claudexor/core 1.0.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/adapter.d.ts +56 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +8 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/browser-mcp.d.ts +18 -0
  8. package/dist/browser-mcp.d.ts.map +1 -0
  9. package/dist/browser-mcp.js +32 -0
  10. package/dist/browser-mcp.js.map +1 -0
  11. package/dist/capabilities.d.ts +4 -0
  12. package/dist/capabilities.d.ts.map +1 -0
  13. package/dist/capabilities.js +8 -0
  14. package/dist/capabilities.js.map +1 -0
  15. package/dist/conformance.d.ts +25 -0
  16. package/dist/conformance.d.ts.map +1 -0
  17. package/dist/conformance.js +60 -0
  18. package/dist/conformance.js.map +1 -0
  19. package/dist/diff.d.ts +71 -0
  20. package/dist/diff.d.ts.map +1 -0
  21. package/dist/diff.js +325 -0
  22. package/dist/diff.js.map +1 -0
  23. package/dist/doctor.d.ts +7 -0
  24. package/dist/doctor.d.ts.map +1 -0
  25. package/dist/doctor.js +75 -0
  26. package/dist/doctor.js.map +1 -0
  27. package/dist/effort.d.ts +18 -0
  28. package/dist/effort.d.ts.map +1 -0
  29. package/dist/effort.js +49 -0
  30. package/dist/effort.js.map +1 -0
  31. package/dist/env-scope.d.ts +38 -0
  32. package/dist/env-scope.d.ts.map +1 -0
  33. package/dist/env-scope.js +139 -0
  34. package/dist/env-scope.js.map +1 -0
  35. package/dist/errors.d.ts +16 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +17 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/inactivity.d.ts +31 -0
  40. package/dist/inactivity.d.ts.map +1 -0
  41. package/dist/inactivity.js +77 -0
  42. package/dist/inactivity.js.map +1 -0
  43. package/dist/index.d.ts +16 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +16 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/model.d.ts +23 -0
  48. package/dist/model.d.ts.map +1 -0
  49. package/dist/model.js +21 -0
  50. package/dist/model.js.map +1 -0
  51. package/dist/proc.d.ts +68 -0
  52. package/dist/proc.d.ts.map +1 -0
  53. package/dist/proc.js +283 -0
  54. package/dist/proc.js.map +1 -0
  55. package/dist/process-registry.d.ts +8 -0
  56. package/dist/process-registry.d.ts.map +1 -0
  57. package/dist/process-registry.js +20 -0
  58. package/dist/process-registry.js.map +1 -0
  59. package/dist/runloop.d.ts +35 -0
  60. package/dist/runloop.d.ts.map +1 -0
  61. package/dist/runloop.js +156 -0
  62. package/dist/runloop.js.map +1 -0
  63. package/dist/runtime-env.d.ts +16 -0
  64. package/dist/runtime-env.d.ts.map +1 -0
  65. package/dist/runtime-env.js +51 -0
  66. package/dist/runtime-env.js.map +1 -0
  67. package/package.json +40 -0
@@ -0,0 +1,139 @@
1
+ import { harnessRuntimeEnv } from "./runtime-env.js";
2
+ /**
3
+ * Declarative env-scrub SSOT for harness children.
4
+ *
5
+ * Previously each adapter hand-rolled a partial denylist: codex scrubbed only
6
+ * OpenAI vars, claude only Anthropic/AWS/Google, cursor only its base-URL. The
7
+ * result was a cross-provider credential LEAK — a codex child inherited the
8
+ * user's `ANTHROPIC_API_KEY`, a claude child inherited `OPENAI_API_KEY`, etc.
9
+ *
10
+ * The contract is now uniform: scrub EVERY known provider credential / redirect
11
+ * env var from a harness child, then have the adapter re-add ONLY the single
12
+ * variable its chosen auth route legitimately needs (after the scrub). Base-URL
13
+ * redirects are always scrubbed so a redirect can never exfiltrate a seeded
14
+ * credential.
15
+ */
16
+ export const PROVIDER_SECRET_ENV = [
17
+ // OpenAI / Codex
18
+ "OPENAI_API_KEY",
19
+ "OPENAI_ORG",
20
+ "OPENAI_ORG_ID",
21
+ "OPENAI_PROJECT",
22
+ "OPENAI_PROJECT_ID",
23
+ "OPENAI_BASE_URL",
24
+ "CODEX_API_KEY",
25
+ "CLAUDEXOR_CODEX_API_KEY",
26
+ // Anthropic / Claude
27
+ "ANTHROPIC_API_KEY",
28
+ "ANTHROPIC_AUTH_TOKEN",
29
+ "ANTHROPIC_BASE_URL",
30
+ "CLAUDE_API_KEY",
31
+ "CLAUDE_CODE_OAUTH_TOKEN",
32
+ "CLAUDE_CODE_USE_BEDROCK",
33
+ "CLAUDE_CODE_USE_VERTEX",
34
+ "ANTHROPIC_BEDROCK_BASE_URL",
35
+ "ANTHROPIC_VERTEX_PROJECT_ID",
36
+ "CLAUDEXOR_ANTHROPIC_API_KEY",
37
+ // Cloud provider creds reachable by Bedrock/Vertex routing
38
+ "AWS_ACCESS_KEY_ID",
39
+ "AWS_SECRET_ACCESS_KEY",
40
+ "AWS_SESSION_TOKEN",
41
+ "AWS_PROFILE",
42
+ "GOOGLE_APPLICATION_CREDENTIALS",
43
+ // Google / Gemini, xAI, OpenRouter, Cursor, OpenCode
44
+ "GEMINI_API_KEY",
45
+ "GOOGLE_API_KEY",
46
+ "XAI_API_KEY",
47
+ "OPENROUTER_API_KEY",
48
+ "OPENROUTER_BASE_URL",
49
+ "CURSOR_API_KEY",
50
+ "CLAUDEXOR_CURSOR_API_KEY",
51
+ "CURSOR_API_URL",
52
+ "OPENCODE_API_KEY",
53
+ // Raw OpenAI-compatible API harness
54
+ "CLAUDEXOR_RAWAPI_KEY",
55
+ "CLAUDEXOR_RAWAPI_BASE_URL",
56
+ // Other providers harness CLIs can read (third-party routers / clouds)
57
+ "GROQ_API_KEY",
58
+ "MISTRAL_API_KEY",
59
+ "DEEPSEEK_API_KEY",
60
+ "OPENAI_API_BASE",
61
+ ];
62
+ /**
63
+ * Build an env patch (`{VAR: null}`) that scrubs every provider secret EXCEPT the
64
+ * ones in `keep` (the vars the adapter's chosen route legitimately uses, which it
65
+ * sets explicitly afterward). Apply this AFTER spreading `spec.env`.
66
+ */
67
+ export function providerScrubEnv(keep = []) {
68
+ const keepSet = new Set(keep);
69
+ const out = {};
70
+ for (const name of PROVIDER_SECRET_ENV) {
71
+ if (!keepSet.has(name))
72
+ out[name] = null;
73
+ }
74
+ return out;
75
+ }
76
+ /**
77
+ * Minimal env an interactive CLI genuinely needs to run (locale, terminal, temp,
78
+ * and PATH to find its own binary + tools). Everything else is dropped under
79
+ * `env_inheritance: "clean"` — agent env isolation. Exact var values still come
80
+ * from the parent; only the KEY SET is restricted. Provider secrets are NOT in
81
+ * the allowlist (defense-in-depth on top of providerScrubEnv), and the adapter
82
+ * re-adds its single chosen credential explicitly afterward.
83
+ */
84
+ export const CLEAN_ENV_ALLOWLIST = [
85
+ "PATH",
86
+ "HOME",
87
+ "USER",
88
+ "LOGNAME",
89
+ "SHELL",
90
+ "TERM",
91
+ "TMPDIR",
92
+ "TZ",
93
+ "LANG",
94
+ "LC_ALL",
95
+ "LC_CTYPE",
96
+ "LANGUAGE",
97
+ // Node/runtime discovery the spawned CLI may itself need to locate a runtime.
98
+ "NODE_PATH",
99
+ "NVM_DIR",
100
+ "XDG_CONFIG_HOME",
101
+ "XDG_CACHE_HOME",
102
+ "XDG_DATA_HOME",
103
+ "SYSTEMROOT", // Windows CLIs fail to start without it
104
+ // Proxy + TLS trust: NOT provider secrets, but a harness behind a corporate
105
+ // proxy / custom CA loses egress and TLS trust without them — `clean` must keep
106
+ // the network path working. (Both cases: curl/openssl read lower, Node reads upper.)
107
+ "HTTP_PROXY",
108
+ "HTTPS_PROXY",
109
+ "ALL_PROXY",
110
+ "NO_PROXY",
111
+ "http_proxy",
112
+ "https_proxy",
113
+ "all_proxy",
114
+ "no_proxy",
115
+ "NODE_EXTRA_CA_CERTS",
116
+ "SSL_CERT_FILE",
117
+ "SSL_CERT_DIR",
118
+ "REQUESTS_CA_BUNDLE",
119
+ "CURL_CA_BUNDLE",
120
+ ];
121
+ /**
122
+ * Build the base child env for a given inheritance mode. `mirror_native` copies
123
+ * the parent env (the native CLIs' default); `clean` copies only the minimal
124
+ * allowlist (agent isolation). The adapter's `spec.env` overrides + the
125
+ * providerScrubEnv patch are applied ON TOP of this by the spawn layer.
126
+ */
127
+ export function composeBaseEnv(inheritance, source = process.env) {
128
+ const normalizedSource = harnessRuntimeEnv(source);
129
+ if (inheritance !== "clean")
130
+ return normalizedSource;
131
+ const out = {};
132
+ for (const key of CLEAN_ENV_ALLOWLIST) {
133
+ const value = normalizedSource[key];
134
+ if (value !== undefined)
135
+ out[key] = value;
136
+ }
137
+ return out;
138
+ }
139
+ //# sourceMappingURL=env-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-scope.js","sourceRoot":"","sources":["../src/env-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,iBAAiB;IACjB,gBAAgB;IAChB,YAAY;IACZ,eAAe;IACf,gBAAgB;IAChB,mBAAmB;IACnB,iBAAiB;IACjB,eAAe;IACf,yBAAyB;IACzB,qBAAqB;IACrB,mBAAmB;IACnB,sBAAsB;IACtB,oBAAoB;IACpB,gBAAgB;IAChB,yBAAyB;IACzB,yBAAyB;IACzB,wBAAwB;IACxB,4BAA4B;IAC5B,6BAA6B;IAC7B,6BAA6B;IAC7B,2DAA2D;IAC3D,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,aAAa;IACb,gCAAgC;IAChC,qDAAqD;IACrD,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,oBAAoB;IACpB,qBAAqB;IACrB,gBAAgB;IAChB,0BAA0B;IAC1B,gBAAgB;IAChB,kBAAkB;IAClB,oCAAoC;IACpC,sBAAsB;IACtB,2BAA2B;IAC3B,uEAAuE;IACvE,cAAc;IACd,iBAAiB;IACjB,kBAAkB;IAClB,iBAAiB;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA0B,EAAE;IAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,MAAM;IACN,MAAM;IACN,MAAM;IACN,SAAS;IACT,OAAO;IACP,MAAM;IACN,QAAQ;IACR,IAAI;IACJ,MAAM;IACN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,8EAA8E;IAC9E,WAAW;IACX,SAAS;IACT,iBAAiB;IACjB,gBAAgB;IAChB,eAAe;IACf,YAAY,EAAE,wCAAwC;IACtD,4EAA4E;IAC5E,gFAAgF;IAChF,qFAAqF;IACrF,YAAY;IACZ,aAAa;IACb,WAAW;IACX,UAAU;IACV,YAAY;IACZ,aAAa;IACb,WAAW;IACX,UAAU;IACV,qBAAqB;IACrB,eAAe;IACf,cAAc;IACd,oBAAoB;IACpB,gBAAgB;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAsC,EACtC,SAA4B,OAAO,CAAC,GAAG;IAEvC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,WAAW,KAAK,OAAO;QAAE,OAAO,gBAAgB,CAAC;IACrD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Typed error hierarchy. We fail loudly: boundaries add context, preserve the
3
+ * original cause, and never swallow-and-continue.
4
+ */
5
+ export declare class ClaudexorError extends Error {
6
+ constructor(message: string, options?: {
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ export declare class HarnessUnavailableError extends ClaudexorError {
11
+ }
12
+ export declare class ContextOverflowError extends ClaudexorError {
13
+ }
14
+ export declare class WorkspaceError extends ClaudexorError {
15
+ }
16
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,uBAAwB,SAAQ,cAAc;CAAG;AAC9D,qBAAa,oBAAqB,SAAQ,cAAc;CAAG;AAC3D,qBAAa,cAAe,SAAQ,cAAc;CAAG"}
package/dist/errors.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Typed error hierarchy. We fail loudly: boundaries add context, preserve the
3
+ * original cause, and never swallow-and-continue.
4
+ */
5
+ export class ClaudexorError extends Error {
6
+ constructor(message, options) {
7
+ super(message, options);
8
+ this.name = this.constructor.name;
9
+ }
10
+ }
11
+ export class HarnessUnavailableError extends ClaudexorError {
12
+ }
13
+ export class ContextOverflowError extends ClaudexorError {
14
+ }
15
+ export class WorkspaceError extends ClaudexorError {
16
+ }
17
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,cAAc;CAAG;AAC9D,MAAM,OAAO,oBAAqB,SAAQ,cAAc;CAAG;AAC3D,MAAM,OAAO,cAAe,SAAQ,cAAc;CAAG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Inactivity watchdog for harness event streams: a wedged vendor CLI
3
+ * that stops emitting events would otherwise park the run in `running`
4
+ * forever — only reviewers had a timeout. The combinator pumps the source
5
+ * iterator and re-arms a timer on EVERY event; when the window elapses with
6
+ * no event, `onTimeout` fires exactly once (the caller aborts its per-attempt
7
+ * controller, which kills the process group through the existing abort
8
+ * plumbing) and the pump stops waiting for the source.
9
+ *
10
+ * This is an INACTIVITY window, not a wall-clock cap: long runs are fine as
11
+ * long as they keep talking. Distinct from cancellation by construction —
12
+ * the caller decides what the timeout means (typed harness_timeout failure),
13
+ * and a user cancel still routes through the run signal.
14
+ */
15
+ export declare class HarnessInactivityTimeoutError extends Error {
16
+ readonly timeoutMs: number;
17
+ constructor(timeoutMs: number);
18
+ }
19
+ export declare function withInactivityWatchdog<T>(source: AsyncIterable<T>, opts: {
20
+ timeoutMs: number;
21
+ /** Called once when the window elapses; abort the stream here. */
22
+ onTimeout: () => void;
23
+ /**
24
+ * Legitimate-silence probe. When the window elapses while this returns
25
+ * true (e.g. a question is awaiting the USER's answer), the watchdog
26
+ * RE-ARMS instead of firing — waiting on a human is not a wedged harness,
27
+ * and the interaction channel enforces its own answer-wait budget.
28
+ */
29
+ isSuspended?: () => boolean;
30
+ }): AsyncIterable<T>;
31
+ //# sourceMappingURL=inactivity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inactivity.d.ts","sourceRoot":"","sources":["../src/inactivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAQvC;AAED,wBAAuB,sBAAsB,CAAC,CAAC,EAC7C,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B,GACA,aAAa,CAAC,CAAC,CAAC,CA8ClB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Inactivity watchdog for harness event streams: a wedged vendor CLI
3
+ * that stops emitting events would otherwise park the run in `running`
4
+ * forever — only reviewers had a timeout. The combinator pumps the source
5
+ * iterator and re-arms a timer on EVERY event; when the window elapses with
6
+ * no event, `onTimeout` fires exactly once (the caller aborts its per-attempt
7
+ * controller, which kills the process group through the existing abort
8
+ * plumbing) and the pump stops waiting for the source.
9
+ *
10
+ * This is an INACTIVITY window, not a wall-clock cap: long runs are fine as
11
+ * long as they keep talking. Distinct from cancellation by construction —
12
+ * the caller decides what the timeout means (typed harness_timeout failure),
13
+ * and a user cancel still routes through the run signal.
14
+ */
15
+ export class HarnessInactivityTimeoutError extends Error {
16
+ timeoutMs;
17
+ constructor(timeoutMs) {
18
+ super(`harness produced no events for ${timeoutMs}ms (inactivity watchdog); ` +
19
+ `the stream was aborted and the process group killed. Raise ` +
20
+ `runtime.harness_inactivity_timeout_ms if this workload is legitimately silent.`);
21
+ this.timeoutMs = timeoutMs;
22
+ this.name = "HarnessInactivityTimeoutError";
23
+ }
24
+ }
25
+ export async function* withInactivityWatchdog(source, opts) {
26
+ const iterator = source[Symbol.asyncIterator]();
27
+ let timer = null;
28
+ let timedOut = false;
29
+ let wake = null;
30
+ const arm = () => {
31
+ if (timer)
32
+ clearTimeout(timer);
33
+ timer = setTimeout(() => {
34
+ if (opts.isSuspended?.()) {
35
+ arm();
36
+ return;
37
+ }
38
+ timedOut = true;
39
+ opts.onTimeout();
40
+ wake?.();
41
+ }, Math.max(1, opts.timeoutMs));
42
+ // Deliberately NOT unref'd: a wedged in-process stream can leave nothing
43
+ // else on the event loop, and an unref'd watchdog would let node exit 0
44
+ // mid-run instead of firing the timeout.
45
+ };
46
+ try {
47
+ arm();
48
+ for (;;) {
49
+ // Race the next event against the watchdog firing: after onTimeout()
50
+ // aborts the child, the source SHOULD end on its own, but a stuck
51
+ // iterator must not keep the run parked — the sentinel wakes the pump.
52
+ const next = await Promise.race([
53
+ iterator.next(),
54
+ new Promise((resolve) => {
55
+ wake = () => resolve("timeout");
56
+ if (timedOut)
57
+ resolve("timeout");
58
+ }),
59
+ ]);
60
+ if (next === "timeout" || timedOut) {
61
+ throw new HarnessInactivityTimeoutError(opts.timeoutMs);
62
+ }
63
+ if (next.done)
64
+ return;
65
+ arm();
66
+ yield next.value;
67
+ }
68
+ }
69
+ finally {
70
+ if (timer)
71
+ clearTimeout(timer);
72
+ // Release a source still mid-iteration (also triggers spawnProcess's
73
+ // finally -> requestCancel when the caller exits the loop early).
74
+ void iterator.return?.(undefined);
75
+ }
76
+ }
77
+ //# sourceMappingURL=inactivity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inactivity.js","sourceRoot":"","sources":["../src/inactivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IACjC;IAArB,YAAqB,SAAiB;QACpC,KAAK,CACH,kCAAkC,SAAS,4BAA4B;YACrE,6DAA6D;YAC7D,gFAAgF,CACnF,CAAC;QALiB,cAAS,GAAT,SAAS,CAAQ;QAMpC,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,sBAAsB,CAC3C,MAAwB,EACxB,IAWC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;IAChD,IAAI,KAAK,GAAyC,IAAI,CAAC;IACvD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,IAAI,GAAwB,IAAI,CAAC;IACrC,MAAM,GAAG,GAAG,GAAS,EAAE;QACrB,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;gBACzB,GAAG,EAAE,CAAC;gBACN,OAAO;YACT,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,EAAE,EAAE,CAAC;QACX,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAChC,yEAAyE;QACzE,wEAAwE;QACxE,yCAAyC;IAC3C,CAAC,CAAC;IACF,IAAI,CAAC;QACH,GAAG,EAAE,CAAC;QACN,SAAS,CAAC;YACR,qEAAqE;YACrE,kEAAkE;YAClE,uEAAuE;YACvE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAC9B,QAAQ,CAAC,IAAI,EAAE;gBACf,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,EAAE;oBACjC,IAAI,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAChC,IAAI,QAAQ;wBAAE,OAAO,CAAC,SAAS,CAAC,CAAC;gBACnC,CAAC,CAAC;aACH,CAAC,CAAC;YACH,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,6BAA6B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO;YACtB,GAAG,EAAE,CAAC;YACN,MAAM,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,qEAAqE;QACrE,kEAAkE;QAClE,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,SAAkB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ export * from "./errors.js";
2
+ export * from "./adapter.js";
3
+ export * from "./effort.js";
4
+ export * from "./model.js";
5
+ export * from "./proc.js";
6
+ export * from "./runloop.js";
7
+ export * from "./inactivity.js";
8
+ export * from "./process-registry.js";
9
+ export * from "./diff.js";
10
+ export * from "./conformance.js";
11
+ export * from "./capabilities.js";
12
+ export * from "./doctor.js";
13
+ export * from "./env-scope.js";
14
+ export * from "./runtime-env.js";
15
+ export * from "./browser-mcp.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ export * from "./errors.js";
2
+ export * from "./adapter.js";
3
+ export * from "./effort.js";
4
+ export * from "./model.js";
5
+ export * from "./proc.js";
6
+ export * from "./runloop.js";
7
+ export * from "./inactivity.js";
8
+ export * from "./process-registry.js";
9
+ export * from "./diff.js";
10
+ export * from "./conformance.js";
11
+ export * from "./capabilities.js";
12
+ export * from "./doctor.js";
13
+ export * from "./env-scope.js";
14
+ export * from "./runtime-env.js";
15
+ export * from "./browser-mcp.js";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Validate a requested/configured model id against a harness's model truth
3
+ * source — the model analog of the effort normalizer (`normalizeEffort`).
4
+ * Data-driven: the caller supplies the truth list (live `models()` inventory
5
+ * or manifest `known_models`); this never hardcodes a model list in logic.
6
+ *
7
+ * STRICT semantics (locked owner decision, INV-104): there is no "warn and pass through".
8
+ * - no model requested (null/empty) → ok (the harness default is used).
9
+ * - truth list empty → rejected: the harness cannot verify models, so an
10
+ * EXPLICIT model is refused with actionable text instead of being forwarded
11
+ * to the vendor CLI to die as an opaque native error.
12
+ * - requested ∈ list → ok.
13
+ * - requested ∉ list → rejected, naming the truth source and the list.
14
+ */
15
+ export type ModelCheckStatus = "ok" | "rejected";
16
+ export interface ModelCheck {
17
+ status: ModelCheckStatus;
18
+ message: string | null;
19
+ }
20
+ /** Where the truth list came from; used to phrase actionable refusals. */
21
+ export type ModelTruthSource = "api" | "manifest";
22
+ export declare function validateModel(requested: string | null | undefined, known: readonly string[], source?: ModelTruthSource): ModelCheck;
23
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,UAAU,CAAC;AACjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,UAAU,CAAC;AAElD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,GAAE,gBAA6B,GACpC,UAAU,CAkBZ"}
package/dist/model.js ADDED
@@ -0,0 +1,21 @@
1
+ export function validateModel(requested, known, source = "manifest") {
2
+ const model = typeof requested === "string" ? requested.trim() : "";
3
+ if (!model)
4
+ return { status: "ok", message: null };
5
+ if (known.length === 0) {
6
+ return {
7
+ status: "rejected",
8
+ message: `this harness cannot verify models (no ${source === "api" ? "live model inventory" : "manifest known_models"}); ` +
9
+ `use the harness default (omit the model) or add known_models to the manifest`,
10
+ };
11
+ }
12
+ if (known.includes(model))
13
+ return { status: "ok", message: null };
14
+ const shown = known.slice(0, 80).join(", ");
15
+ const suffix = known.length > 80 ? `, ... (${known.length} total)` : "";
16
+ return {
17
+ status: "rejected",
18
+ message: `model "${model}" is not in the harness's ${source === "api" ? "live model inventory" : "manifest known-model list"} (${shown}${suffix})`,
19
+ };
20
+ }
21
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,aAAa,CAC3B,SAAoC,EACpC,KAAwB,EACxB,SAA2B,UAAU;IAErC,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,OAAO,EACL,yCAAyC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,uBAAuB,KAAK;gBACjH,8EAA8E;SACjF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,UAAU,KAAK,6BAA6B,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,2BAA2B,KAAK,KAAK,GAAG,MAAM,GAAG;KACnJ,CAAC;AACJ,CAAC"}
package/dist/proc.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ export interface SpawnOptions {
2
+ cwd?: string;
3
+ env?: Record<string, string | null | undefined>;
4
+ /**
5
+ * Base env composition for the child: `mirror_native` (default) inherits the
6
+ * parent env; `clean` starts from a minimal allowlist (agent env isolation).
7
+ * `env` patches + scrub are applied on top either way.
8
+ */
9
+ inheritEnv?: "mirror_native" | "clean";
10
+ input?: string;
11
+ timeoutMs?: number;
12
+ /** Signal sent when the consumer closes the stream before process exit. */
13
+ cancelSignal?: NodeJS.Signals;
14
+ /** Hard-kill delay after cancelSignal when the child ignores cooperative stop. */
15
+ cancelKillDelayMs?: number;
16
+ /** Runtime abort signal for active daemon/orchestrator cancellation. */
17
+ abortSignal?: AbortSignal;
18
+ /**
19
+ * Keep stdin open after writing `input` (bidirectional protocols such as
20
+ * Claude's stream-json control channel). The caller receives a writer via
21
+ * `onSpawn` and OWNS closing it; the child usually exits on stdin EOF.
22
+ */
23
+ keepStdinOpen?: boolean;
24
+ /** Called once after spawn with a live stdin handle (see keepStdinOpen). */
25
+ onSpawn?: (io: ChildStdin) => void;
26
+ }
27
+ /** Minimal live stdin handle for bidirectional CLI protocols. */
28
+ export interface ChildStdin {
29
+ /** Write one line/frame; errors are swallowed (exit carries the outcome). */
30
+ write(data: string): void;
31
+ /** Close stdin (EOF) — the cooperative way to end a streaming session. */
32
+ end(): void;
33
+ }
34
+ export type ProcEvent = {
35
+ type: "stdout";
36
+ line: string;
37
+ } | {
38
+ type: "stderr";
39
+ line: string;
40
+ } | {
41
+ type: "exit";
42
+ code: number | null;
43
+ signal: NodeJS.Signals | null;
44
+ };
45
+ /**
46
+ * Spawn a process and stream stdout/stderr lines as they arrive, ending with an
47
+ * `exit` event. Throws (rejects the iterator) if the binary cannot be spawned
48
+ * (e.g. ENOENT) so callers can detect an unavailable harness.
49
+ */
50
+ export declare function spawnProcess(cmd: string, args: string[], opts?: SpawnOptions): AsyncGenerator<ProcEvent>;
51
+ export interface CaptureResult {
52
+ code: number | null;
53
+ signal: NodeJS.Signals | null;
54
+ stdout: string;
55
+ stderr: string;
56
+ }
57
+ /** Run a process to completion, capturing stdout/stderr. Throws on spawn error. */
58
+ export declare function runCapture(cmd: string, args: string[], opts?: SpawnOptions): Promise<CaptureResult>;
59
+ /**
60
+ * BYTE-FAITHFUL capture: `runCapture` rides readline, which splits
61
+ * on lone `\r` too and rejoins with `\n` — destroying CR bytes in CRLF file
62
+ * content and fabricating trailing newlines. Diff-carrying git output MUST
63
+ * come through here, or `final/patch.diff` is corrupted at the source and
64
+ * fails `git apply` downstream. Raw buffers, no line splitting, no
65
+ * fabrication; the same spawn machinery (process group, abort, timeout).
66
+ */
67
+ export declare function runCaptureRaw(cmd: string, args: string[], opts?: SpawnOptions): Promise<CaptureResult>;
68
+ //# sourceMappingURL=proc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proc.d.ts","sourceRoot":"","sources":["../src/proc.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAChD;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC9B,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,IAAI,CAAC;CACpC;AAED,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,GAAG,IAAI,IAAI,CAAC;CACb;AAED,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC;AAEzE;;;;GAIG;AACH,wBAAuB,YAAY,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,YAAiB,GACtB,cAAc,CAAC,SAAS,CAAC,CAkJ3B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,aAAa,CAAC,CAcxB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,aAAa,CAAC,CA0ExB"}