@peakflo/agent-harness 0.2.9-rc.3 → 0.2.9-rc.5

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.
@@ -47,31 +47,23 @@ export declare const CLAUDE_SDK_PACKAGE = "@anthropic-ai/claude-agent-sdk";
47
47
  * runner. Fixed sentences, like every other reason in the report.
48
48
  */
49
49
  export declare const NOT_RUNNABLE_REASONS: {
50
- readonly claudeSdkMissing: "The Claude Agent SDK is not installed. Run `npm install -g @anthropic-ai/claude-agent-sdk` on this machine.";
50
+ readonly claudeSdkMissing: "The Claude Agent SDK that ships with this runner could not be loaded. Reinstall the runner.";
51
51
  readonly sandbox: "A cloud sandbox runs Pi only.";
52
52
  };
53
53
  /**
54
- * Directories to look for the SDK in, besides this package's own
55
- * `node_modules`.
54
+ * Where the SDK is, or null.
56
55
  *
57
- * WHY IT IS NOT SIMPLY A DEPENDENCY. In 20x the SDK ships inside the app. Here
58
- * that would add its platform package — about 190 MB, a copy of the Claude
59
- * binary — to EVERY install of the runner, the cloud sandbox included, for a
60
- * harness most installs never use. The adapter already points the SDK at the
61
- * `claude` the user installed, so only the SDK's own JavaScript is needed, and
62
- * a machine that wants Claude Code installs it once, globally.
63
- */
64
- export declare function claudeSdkSearchRoots(env?: NodeJS.ProcessEnv, execPath?: string): string[];
65
- /**
66
- * Where the SDK can be loaded from, or null. Synchronous and cheap (a few
67
- * file reads), so it can be asked on every capability report.
56
+ * THE SDK IS A DEPENDENCY OF THIS PACKAGE, as it is of the 20x app: installing
57
+ * the runner installs it, and nothing else has to be done on the machine. So
58
+ * it is looked for in one place, this package's own dependency tree.
59
+ *
60
+ * Null is still possible and still handled, because "declared" is not
61
+ * "present": an install that was interrupted, pruned, or made with
62
+ * dependencies left out has no SDK. Claude Code is then reported as not
63
+ * runnable, with a reason, instead of being routed a turn it must fail.
68
64
  *
69
- * `ownTree` is this package's own resolution, replaced in tests — this
70
- * repository has the SDK as a dev dependency, so "not installed" could not be
71
- * tested otherwise.
65
+ * `ownTree` is replaced in tests, which could not otherwise see "missing".
72
66
  */
73
- export declare function resolveClaudeSdk(roots?: readonly string[], ownTree?: () => string): string | null;
74
- /** Import the SDK from wherever `resolveClaudeSdk` finds it. Throws when absent. */
75
- export declare function importClaudeSdk(): Promise<unknown>;
67
+ export declare function resolveClaudeSdk(ownTree?: () => string): string | null;
76
68
  /** Whether this runner can build an adapter for a vendor backend right now. */
77
69
  export declare function vendorBackendBlocker(backend: string, runtime: string): string | null;
@@ -25,14 +25,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.NOT_RUNNABLE_REASONS = exports.CLAUDE_SDK_PACKAGE = exports.VENDOR_BACKENDS = void 0;
26
26
  exports.isVendorBackend = isVendorBackend;
27
27
  exports.vendorModelId = vendorModelId;
28
- exports.claudeSdkSearchRoots = claudeSdkSearchRoots;
29
28
  exports.resolveClaudeSdk = resolveClaudeSdk;
30
- exports.importClaudeSdk = importClaudeSdk;
31
29
  exports.vendorBackendBlocker = vendorBackendBlocker;
32
- const node_fs_1 = require("node:fs");
33
30
  const node_module_1 = require("node:module");
34
- const node_path_1 = require("node:path");
35
- const node_url_1 = require("node:url");
36
31
  exports.VENDOR_BACKENDS = ['codex', 'claude-code', 'cursor'];
37
32
  function isVendorBackend(name) {
38
33
  return exports.VENDOR_BACKENDS.includes(name);
@@ -65,94 +60,30 @@ exports.CLAUDE_SDK_PACKAGE = '@anthropic-ai/claude-agent-sdk';
65
60
  * runner. Fixed sentences, like every other reason in the report.
66
61
  */
67
62
  exports.NOT_RUNNABLE_REASONS = {
68
- claudeSdkMissing: 'The Claude Agent SDK is not installed. Run `npm install -g @anthropic-ai/claude-agent-sdk` on this machine.',
63
+ claudeSdkMissing: 'The Claude Agent SDK that ships with this runner could not be loaded. Reinstall the runner.',
69
64
  sandbox: 'A cloud sandbox runs Pi only.'
70
65
  };
71
66
  /**
72
- * Directories to look for the SDK in, besides this package's own
73
- * `node_modules`.
67
+ * Where the SDK is, or null.
74
68
  *
75
- * WHY IT IS NOT SIMPLY A DEPENDENCY. In 20x the SDK ships inside the app. Here
76
- * that would add its platform package — about 190 MB, a copy of the Claude
77
- * binary — to EVERY install of the runner, the cloud sandbox included, for a
78
- * harness most installs never use. The adapter already points the SDK at the
79
- * `claude` the user installed, so only the SDK's own JavaScript is needed, and
80
- * a machine that wants Claude Code installs it once, globally.
81
- */
82
- function claudeSdkSearchRoots(env = process.env, execPath = process.execPath) {
83
- const roots = [
84
- env.PF_CLAUDE_AGENT_SDK_DIR,
85
- // `npm install -g` beside the running node: <prefix>/lib/node_modules
86
- (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.dirname)(execPath)), 'lib', 'node_modules'),
87
- // Windows: <prefix>\node_modules
88
- (0, node_path_1.join)((0, node_path_1.dirname)(execPath), 'node_modules'),
89
- '/opt/homebrew/lib/node_modules',
90
- '/usr/local/lib/node_modules'
91
- ];
92
- return [...new Set(roots.filter((root) => Boolean(root)))];
93
- }
94
- /** The file a package directory loads as, read from its own package.json. */
95
- function packageEntry(directory) {
96
- try {
97
- const manifest = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(directory, 'package.json'), 'utf8'));
98
- const root = manifest.exports && typeof manifest.exports === 'object'
99
- ? (manifest.exports['.'] ??
100
- manifest.exports)
101
- : manifest.exports;
102
- const fromExports = typeof root === 'string'
103
- ? root
104
- : root && typeof root === 'object'
105
- ? (root.import ??
106
- root.default)
107
- : undefined;
108
- const entry = [
109
- fromExports,
110
- manifest.module,
111
- manifest.main,
112
- 'index.js'
113
- ].find((candidate) => typeof candidate === 'string');
114
- const file = entry ? (0, node_path_1.join)(directory, entry) : null;
115
- return file && (0, node_fs_1.existsSync)(file) ? file : null;
116
- }
117
- catch {
118
- return null;
119
- }
120
- }
121
- /**
122
- * Where the SDK can be loaded from, or null. Synchronous and cheap (a few
123
- * file reads), so it can be asked on every capability report.
69
+ * THE SDK IS A DEPENDENCY OF THIS PACKAGE, as it is of the 20x app: installing
70
+ * the runner installs it, and nothing else has to be done on the machine. So
71
+ * it is looked for in one place, this package's own dependency tree.
72
+ *
73
+ * Null is still possible and still handled, because "declared" is not
74
+ * "present": an install that was interrupted, pruned, or made with
75
+ * dependencies left out has no SDK. Claude Code is then reported as not
76
+ * runnable, with a reason, instead of being routed a turn it must fail.
124
77
  *
125
- * `ownTree` is this package's own resolution, replaced in tests — this
126
- * repository has the SDK as a dev dependency, so "not installed" could not be
127
- * tested otherwise.
78
+ * `ownTree` is replaced in tests, which could not otherwise see "missing".
128
79
  */
129
- function resolveClaudeSdk(roots = claudeSdkSearchRoots(), ownTree = () => (0, node_module_1.createRequire)(__filename).resolve(exports.CLAUDE_SDK_PACKAGE)) {
80
+ function resolveClaudeSdk(ownTree = () => (0, node_module_1.createRequire)(__filename).resolve(exports.CLAUDE_SDK_PACKAGE)) {
130
81
  try {
131
82
  return ownTree();
132
83
  }
133
84
  catch {
134
- // Not in this package's own tree.
135
- }
136
- for (const root of roots) {
137
- const entry = packageEntry((0, node_path_1.join)(root, exports.CLAUDE_SDK_PACKAGE));
138
- if (entry)
139
- return entry;
140
- }
141
- return null;
142
- }
143
- /** Import the SDK from wherever `resolveClaudeSdk` finds it. Throws when absent. */
144
- async function importClaudeSdk() {
145
- const resolved = resolveClaudeSdk();
146
- if (!resolved) {
147
- throw new Error(exports.NOT_RUNNABLE_REASONS.claudeSdkMissing);
85
+ return null;
148
86
  }
149
- /*
150
- * `new Function` keeps this a REAL dynamic import in the compiled CommonJS
151
- * output. Written as `import(x)`, TypeScript turns it into `require(x)`,
152
- * and the SDK is an ES module that `require` cannot load on every Node.
153
- */
154
- const dynamicImport = new Function('specifier', 'return import(specifier)');
155
- return dynamicImport((0, node_url_1.pathToFileURL)(resolved).href);
156
87
  }
157
88
  /** Whether this runner can build an adapter for a vendor backend right now. */
158
89
  function vendorBackendBlocker(backend, runtime) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peakflo/agent-harness",
3
- "version": "0.2.9-rc.3",
3
+ "version": "0.2.9-rc.5",
4
4
  "description": "Headless Peakflo coding-agent harness. One codebase, three hosting modes: a Daytona cloud sandbox, a customer VM, and the 20x desktop.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -29,7 +29,6 @@
29
29
  "test": "jest"
30
30
  },
31
31
  "devDependencies": {
32
- "@anthropic-ai/claude-agent-sdk": "^0.3.195",
33
32
  "@opencode-ai/sdk": "^1.15.13",
34
33
  "@types/node": "^22.10.0",
35
34
  "tsx": "^4.19.3",
@@ -37,6 +36,7 @@
37
36
  "undici": "^7.21.0"
38
37
  },
39
38
  "dependencies": {
39
+ "@anthropic-ai/claude-agent-sdk": "0.3.258",
40
40
  "@modelcontextprotocol/client": "2.0.0",
41
41
  "@peculiar/x509": "^2.1.0",
42
42
  "reflect-metadata": "^0.2.2"