@sagentlab/navarch-runtime 0.1.33 → 0.1.34
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/adapters/index.cjs +9 -1
- package/dist/adapters/pi.cjs +321 -0
- package/dist/redact.cjs +5 -1
- package/package.json +1 -1
package/dist/adapters/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runOpenCodeAdapter = exports.openCodeAdapter = exports.runGeminiAdapter = exports.geminiAdapter = exports.runCodexAdapter = exports.codexAdapter = exports.runClaudeCodeAdapter = exports.claudeCodeAdapter = void 0;
|
|
3
|
+
exports.runPiAdapter = exports.piAdapter = exports.runOpenCodeAdapter = exports.openCodeAdapter = exports.runGeminiAdapter = exports.geminiAdapter = exports.runCodexAdapter = exports.codexAdapter = exports.runClaudeCodeAdapter = exports.claudeCodeAdapter = void 0;
|
|
4
4
|
exports.selectAdapter = selectAdapter;
|
|
5
5
|
const claude_cjs_1 = require("./claude.cjs");
|
|
6
6
|
Object.defineProperty(exports, "claudeCodeAdapter", { enumerable: true, get: function () { return claude_cjs_1.claudeCodeAdapter; } });
|
|
@@ -14,6 +14,9 @@ Object.defineProperty(exports, "runGeminiAdapter", { enumerable: true, get: func
|
|
|
14
14
|
const opencode_cjs_1 = require("./opencode.cjs");
|
|
15
15
|
Object.defineProperty(exports, "openCodeAdapter", { enumerable: true, get: function () { return opencode_cjs_1.openCodeAdapter; } });
|
|
16
16
|
Object.defineProperty(exports, "runOpenCodeAdapter", { enumerable: true, get: function () { return opencode_cjs_1.runOpenCodeAdapter; } });
|
|
17
|
+
const pi_cjs_1 = require("./pi.cjs");
|
|
18
|
+
Object.defineProperty(exports, "piAdapter", { enumerable: true, get: function () { return pi_cjs_1.piAdapter; } });
|
|
19
|
+
Object.defineProperty(exports, "runPiAdapter", { enumerable: true, get: function () { return pi_cjs_1.runPiAdapter; } });
|
|
17
20
|
/**
|
|
18
21
|
* Picks the AgentAdapter (adapters/types.cts) session.cts should run a
|
|
19
22
|
* session with, keyed off config.cts's `agentType` (NAVARCH_AGENT). This is
|
|
@@ -31,6 +34,11 @@ function selectAdapter(agentType) {
|
|
|
31
34
|
return opencode_cjs_1.openCodeAdapter;
|
|
32
35
|
case "claude-code":
|
|
33
36
|
return claude_cjs_1.claudeCodeAdapter;
|
|
37
|
+
case "pi":
|
|
38
|
+
// Managed hosted runtime (#885): reachable only on a managed runner
|
|
39
|
+
// executing a `runtime: "pi"` claim — config.cts never produces "pi"
|
|
40
|
+
// from NAVARCH_AGENT, so a BYO machine cannot select it locally.
|
|
41
|
+
return pi_cjs_1.piAdapter;
|
|
34
42
|
default: {
|
|
35
43
|
// Exhaustiveness guard: config.cts only ever produces the values
|
|
36
44
|
// above, but fall back to Claude Code rather than throwing if this
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.piAdapter = exports.DEFAULT_HOSTED_PI_MODEL = exports.HOSTED_PI_MODELS = exports.DEEPSEEK_API_KEY_ENV = exports.PI_PROVIDER_NAME = void 0;
|
|
7
|
+
exports.resolveHostedPiModel = resolveHostedPiModel;
|
|
8
|
+
exports.buildPiProviderConfig = buildPiProviderConfig;
|
|
9
|
+
exports.parsePiJsonEvents = parsePiJsonEvents;
|
|
10
|
+
exports.runPiAdapter = runPiAdapter;
|
|
11
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
14
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
/**
|
|
16
|
+
* Headless Pi coding-agent adapter (#885) — the process-side twin of the
|
|
17
|
+
* Cloudflare hosted executor (worker/hosted-pi/lifecycle.ts). It invokes
|
|
18
|
+
* `pi --mode json -p <prompt>` against DeepSeek V4 through a generated
|
|
19
|
+
* OpenAI-compatible custom-provider config and normalizes the JSON event
|
|
20
|
+
* stream into the common AdapterResult boundary.
|
|
21
|
+
*
|
|
22
|
+
* Hosted Pi is control-plane provisioned (docs/navarch/runtime-adapter-contract.md
|
|
23
|
+
* — "Hosted Pi is not a fifth AgentAdapter" for BYO workers): config.cts
|
|
24
|
+
* never selects this adapter from NAVARCH_AGENT, and dispatch never returns
|
|
25
|
+
* `runtime: "pi"` to a BYO machine. This module exists so the managed runner
|
|
26
|
+
* has the same normalized process boundary as every other CLI, with one
|
|
27
|
+
* shared parsing/provider-config contract.
|
|
28
|
+
*
|
|
29
|
+
* Secret hygiene: the generated models.json references the DeepSeek key ONLY
|
|
30
|
+
* as a `$DEEPSEEK_API_KEY` environment interpolation (Pi expands it from the
|
|
31
|
+
* child environment at load time). The literal key never appears in argv, in
|
|
32
|
+
* the config file, or in any file that survives cleanup. A missing
|
|
33
|
+
* DEEPSEEK_API_KEY in the session environment is a hard configuration
|
|
34
|
+
* failure — the adapter refuses to launch rather than fall back to an
|
|
35
|
+
* ambient credential.
|
|
36
|
+
*
|
|
37
|
+
* MCP: Pi has no MCP client, so `mcpConfigPath` is a documented unsupported
|
|
38
|
+
* control for this adapter (contract: "document an unsupported control
|
|
39
|
+
* instead of inventing one"); platform MCP tools are unavailable to hosted
|
|
40
|
+
* Pi sessions.
|
|
41
|
+
*/
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Provider config — MIRROR of worker/hosted-pi/provider-config.ts. Both
|
|
44
|
+
// sides must keep the same provider name, env reference, and model ids.
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
exports.PI_PROVIDER_NAME = "deepseek";
|
|
47
|
+
exports.DEEPSEEK_API_KEY_ENV = "DEEPSEEK_API_KEY";
|
|
48
|
+
exports.HOSTED_PI_MODELS = ["deepseek-v4-flash", "deepseek-v4-pro"];
|
|
49
|
+
exports.DEFAULT_HOSTED_PI_MODEL = "deepseek-v4-flash";
|
|
50
|
+
function resolveHostedPiModel(configured) {
|
|
51
|
+
const trimmed = (configured ?? "").trim();
|
|
52
|
+
const bare = trimmed.startsWith(`${exports.PI_PROVIDER_NAME}/`)
|
|
53
|
+
? trimmed.slice(exports.PI_PROVIDER_NAME.length + 1)
|
|
54
|
+
: trimmed;
|
|
55
|
+
return exports.HOSTED_PI_MODELS.includes(bare)
|
|
56
|
+
? bare
|
|
57
|
+
: exports.DEFAULT_HOSTED_PI_MODEL;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Pi custom-provider models.json. Cost figures mirror the OFF-PEAK DeepSeek
|
|
61
|
+
* prices from lib/navarch/hosted-credits.ts and only drive Pi's local cost
|
|
62
|
+
* display; billing authority is the control plane's immutable price
|
|
63
|
+
* snapshot, never this file.
|
|
64
|
+
*/
|
|
65
|
+
function buildPiProviderConfig() {
|
|
66
|
+
const models = [
|
|
67
|
+
{
|
|
68
|
+
id: "deepseek-v4-flash",
|
|
69
|
+
name: "DeepSeek V4 Flash",
|
|
70
|
+
reasoning: true,
|
|
71
|
+
input: ["text"],
|
|
72
|
+
cost: { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0.22 },
|
|
73
|
+
contextWindow: 128_000,
|
|
74
|
+
maxTokens: 16_384,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "deepseek-v4-pro",
|
|
78
|
+
name: "DeepSeek V4 Pro",
|
|
79
|
+
reasoning: true,
|
|
80
|
+
input: ["text"],
|
|
81
|
+
cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0.66 },
|
|
82
|
+
contextWindow: 128_000,
|
|
83
|
+
maxTokens: 16_384,
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
return `${JSON.stringify({
|
|
87
|
+
providers: {
|
|
88
|
+
[exports.PI_PROVIDER_NAME]: {
|
|
89
|
+
baseUrl: "https://api.deepseek.com",
|
|
90
|
+
api: "openai-completions",
|
|
91
|
+
apiKey: `$${exports.DEEPSEEK_API_KEY_ENV}`,
|
|
92
|
+
models,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
}, null, 2)}\n`;
|
|
96
|
+
}
|
|
97
|
+
function tokenCount(value) {
|
|
98
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
99
|
+
? Math.floor(value)
|
|
100
|
+
: undefined;
|
|
101
|
+
}
|
|
102
|
+
function usdAmount(value) {
|
|
103
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
104
|
+
}
|
|
105
|
+
function extractText(content) {
|
|
106
|
+
if (typeof content === "string")
|
|
107
|
+
return content;
|
|
108
|
+
if (!Array.isArray(content))
|
|
109
|
+
return "";
|
|
110
|
+
return content
|
|
111
|
+
.map((block) => {
|
|
112
|
+
if (typeof block === "string")
|
|
113
|
+
return block;
|
|
114
|
+
if (block &&
|
|
115
|
+
typeof block === "object" &&
|
|
116
|
+
block.type === "text" &&
|
|
117
|
+
typeof block.text === "string") {
|
|
118
|
+
return block.text;
|
|
119
|
+
}
|
|
120
|
+
return "";
|
|
121
|
+
})
|
|
122
|
+
.filter(Boolean)
|
|
123
|
+
.join("\n");
|
|
124
|
+
}
|
|
125
|
+
function parsePiJsonEvents(stdout) {
|
|
126
|
+
const events = [];
|
|
127
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
128
|
+
const trimmed = line.trim();
|
|
129
|
+
if (!trimmed.startsWith("{"))
|
|
130
|
+
continue;
|
|
131
|
+
try {
|
|
132
|
+
const parsed = JSON.parse(trimmed);
|
|
133
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
134
|
+
events.push(parsed);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Unknown lines remain available in the raw transcript.
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return events;
|
|
142
|
+
}
|
|
143
|
+
function attachPiOutput(result) {
|
|
144
|
+
const events = parsePiJsonEvents(result.stdout);
|
|
145
|
+
if (events.length === 0)
|
|
146
|
+
return result;
|
|
147
|
+
let cacheHit = 0;
|
|
148
|
+
let cacheMiss = 0;
|
|
149
|
+
let output = 0;
|
|
150
|
+
let costUsd;
|
|
151
|
+
let sawUsage = false;
|
|
152
|
+
let reportText = "";
|
|
153
|
+
for (const event of events) {
|
|
154
|
+
const message = event.message;
|
|
155
|
+
if (event.type !== "message_end" || !message || message.role !== "assistant")
|
|
156
|
+
continue;
|
|
157
|
+
const text = extractText(message.content);
|
|
158
|
+
if (text.trim())
|
|
159
|
+
reportText = text.trim();
|
|
160
|
+
const usage = message.usage;
|
|
161
|
+
if (usage && typeof usage === "object") {
|
|
162
|
+
const input = tokenCount(usage.input);
|
|
163
|
+
const read = tokenCount(usage.cacheRead);
|
|
164
|
+
const write = tokenCount(usage.cacheWrite);
|
|
165
|
+
const out = tokenCount(usage.output);
|
|
166
|
+
if (input !== undefined || read !== undefined || write !== undefined || out !== undefined) {
|
|
167
|
+
sawUsage = true;
|
|
168
|
+
cacheHit += read ?? 0;
|
|
169
|
+
// DeepSeek bills cache writes at the miss rate; cache-miss input is
|
|
170
|
+
// regular input plus cache writes (docs/navarch/hosted-prepaid-credits.md).
|
|
171
|
+
cacheMiss += (input ?? 0) + (write ?? 0);
|
|
172
|
+
output += out ?? 0;
|
|
173
|
+
const total = usage.cost ? usdAmount(usage.cost.total) : undefined;
|
|
174
|
+
if (total !== undefined)
|
|
175
|
+
costUsd = (costUsd ?? 0) + total;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
...result,
|
|
181
|
+
...(sawUsage
|
|
182
|
+
? {
|
|
183
|
+
// AdapterResult semantics: tokensIn folds every input category
|
|
184
|
+
// together and cacheHitTokensIn is its cache-read component.
|
|
185
|
+
tokensIn: cacheHit + cacheMiss,
|
|
186
|
+
tokensOut: output,
|
|
187
|
+
cacheHitTokensIn: cacheHit,
|
|
188
|
+
}
|
|
189
|
+
: {}),
|
|
190
|
+
...(costUsd !== undefined ? { costUsd } : {}),
|
|
191
|
+
...(reportText ? { reportText } : {}),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Invocation
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
const CONTAINER_PI_DIR = "/tmp/navarch-pi-agent";
|
|
198
|
+
function hasArg(args, ...flags) {
|
|
199
|
+
return args.some((arg) => flags.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));
|
|
200
|
+
}
|
|
201
|
+
async function runPiAdapter(options) {
|
|
202
|
+
if (!options.env[exports.DEEPSEEK_API_KEY_ENV]) {
|
|
203
|
+
// Fail closed: launching without the referenced managed credential would
|
|
204
|
+
// let Pi fall back to ambient/operator auth outside the session boundary.
|
|
205
|
+
throw new Error(`pi adapter: ${exports.DEEPSEEK_API_KEY_ENV} is missing from the session environment; ` +
|
|
206
|
+
"the managed provider credential must be injected by the hosted runner");
|
|
207
|
+
}
|
|
208
|
+
const args = ["--mode", "json"];
|
|
209
|
+
if (!hasArg(options.extraArgs, "--no-session")) {
|
|
210
|
+
// Ephemeral by default: session persistence would leave conversation
|
|
211
|
+
// files (which may quote repository content) behind after cleanup.
|
|
212
|
+
args.push("--no-session");
|
|
213
|
+
}
|
|
214
|
+
args.push(...options.extraArgs);
|
|
215
|
+
const model = resolveHostedPiModel(options.model);
|
|
216
|
+
args.push("--model", `${exports.PI_PROVIDER_NAME}/${model}`);
|
|
217
|
+
if (options.reasoningEffort) {
|
|
218
|
+
// Pi's --thinking accepts off|minimal|low|medium|high|xhigh|max; the
|
|
219
|
+
// resolved efforts are a subset, so they map directly.
|
|
220
|
+
args.push("--thinking", options.reasoningEffort);
|
|
221
|
+
}
|
|
222
|
+
args.push("-p", options.prompt);
|
|
223
|
+
const raw = options.dockerExec
|
|
224
|
+
? await runViaDocker(options, args)
|
|
225
|
+
: await runOnHost(options, args);
|
|
226
|
+
return attachPiOutput(raw);
|
|
227
|
+
}
|
|
228
|
+
async function runOnHost(options, args) {
|
|
229
|
+
// Isolated agent dir so the generated provider config never touches (or
|
|
230
|
+
// reads) an operator's ~/.pi configuration/credentials.
|
|
231
|
+
const agentDir = await node_fs_1.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), "navarch-pi-agent-"));
|
|
232
|
+
await node_fs_1.promises.writeFile(node_path_1.default.join(agentDir, "models.json"), buildPiProviderConfig(), { mode: 0o600 });
|
|
233
|
+
const env = { ...options.env, PI_CODING_AGENT_DIR: agentDir };
|
|
234
|
+
try {
|
|
235
|
+
return await new Promise((resolve) => {
|
|
236
|
+
let stdout = "";
|
|
237
|
+
let stderr = "";
|
|
238
|
+
let timedOut = false;
|
|
239
|
+
let killedByLeaseLoss = false;
|
|
240
|
+
const child = (0, node_child_process_1.spawn)(options.bin, args, {
|
|
241
|
+
cwd: options.cwd,
|
|
242
|
+
env: { ...process.env, ...env },
|
|
243
|
+
});
|
|
244
|
+
child.stdin?.end();
|
|
245
|
+
const timer = setTimeout(() => {
|
|
246
|
+
timedOut = true;
|
|
247
|
+
child.kill("SIGKILL");
|
|
248
|
+
}, options.timeoutMs);
|
|
249
|
+
const onAbort = () => {
|
|
250
|
+
killedByLeaseLoss = true;
|
|
251
|
+
child.kill("SIGKILL");
|
|
252
|
+
};
|
|
253
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
254
|
+
child.stdout.on("data", (data) => {
|
|
255
|
+
stdout += data.toString();
|
|
256
|
+
});
|
|
257
|
+
child.stderr.on("data", (data) => {
|
|
258
|
+
stderr += data.toString();
|
|
259
|
+
});
|
|
260
|
+
child.on("error", (err) => {
|
|
261
|
+
clearTimeout(timer);
|
|
262
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
263
|
+
stderr += `\n${String(err)}`;
|
|
264
|
+
resolve({ exitCode: null, timedOut, killedByLeaseLoss, stdout, stderr });
|
|
265
|
+
});
|
|
266
|
+
child.on("close", (code) => {
|
|
267
|
+
clearTimeout(timer);
|
|
268
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
269
|
+
resolve({ exitCode: code, timedOut, killedByLeaseLoss, stdout, stderr });
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
await node_fs_1.promises.rm(agentDir, { recursive: true, force: true }).catch(() => undefined);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function runViaDocker(options, args) {
|
|
278
|
+
const { containerName, runner } = options.dockerExec;
|
|
279
|
+
// The provider config carries no secret values (only the $DEEPSEEK_API_KEY
|
|
280
|
+
// env reference), so materializing it through the container shell is safe.
|
|
281
|
+
const command = `[ -f /tmp/session.env ] && . /tmp/session.env; cd repo 2>/dev/null; ` +
|
|
282
|
+
`mkdir -p ${CONTAINER_PI_DIR} && cat > ${CONTAINER_PI_DIR}/models.json <<'NAVARCH_PI_EOF'\n` +
|
|
283
|
+
`${buildPiProviderConfig()}NAVARCH_PI_EOF\n` +
|
|
284
|
+
`PI_CODING_AGENT_DIR=${CONTAINER_PI_DIR} ${[options.bin, ...args].map(shellQuote).join(" ")}`;
|
|
285
|
+
let killedByLeaseLoss = false;
|
|
286
|
+
const onAbort = () => {
|
|
287
|
+
killedByLeaseLoss = true;
|
|
288
|
+
runner.run("docker", ["kill", containerName]).catch(() => undefined);
|
|
289
|
+
};
|
|
290
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
291
|
+
try {
|
|
292
|
+
const forwardedEnv = Object.keys(options.env).flatMap((name) => ["--env", name]);
|
|
293
|
+
const result = await runner.run("docker", ["exec", ...forwardedEnv, containerName, "sh", "-c", command], { timeoutMs: options.timeoutMs, env: { ...process.env, ...options.env } });
|
|
294
|
+
return {
|
|
295
|
+
exitCode: result.code,
|
|
296
|
+
timedOut: false,
|
|
297
|
+
killedByLeaseLoss,
|
|
298
|
+
stdout: result.stdout,
|
|
299
|
+
stderr: result.stderr,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
return {
|
|
304
|
+
exitCode: null,
|
|
305
|
+
timedOut: false,
|
|
306
|
+
killedByLeaseLoss,
|
|
307
|
+
stdout: "",
|
|
308
|
+
stderr: String(err),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function shellQuote(value) {
|
|
316
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
317
|
+
}
|
|
318
|
+
exports.piAdapter = {
|
|
319
|
+
agentType: "pi",
|
|
320
|
+
run: runPiAdapter,
|
|
321
|
+
};
|
package/dist/redact.cjs
CHANGED
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.SecretRegistry = void 0;
|
|
9
9
|
exports.redactText = redactText;
|
|
10
|
+
// Keep in sync with lib/navarch/redaction.ts's SECRET_SHAPE_PATTERNS — the
|
|
11
|
+
// hosted Pi executor (worker/hosted-pi) shares these shapes for its own
|
|
12
|
+
// transcript/progress scrubbing.
|
|
10
13
|
const SECRET_PATTERNS = [
|
|
11
14
|
/gh[pousr]_[A-Za-z0-9]{20,}/g, // GitHub PAT / OAuth / user-to-server / refresh tokens
|
|
12
15
|
/github_pat_[A-Za-z0-9_]{20,}/g, // GitHub fine-grained PAT
|
|
13
|
-
/sk-[A-Za-z0-9-]{20,}/g, //
|
|
16
|
+
/sk-[A-Za-z0-9-]{20,}/g, // OpenAI-compatible secret keys, incl. DeepSeek `sk-…` (hosted Pi provider)
|
|
17
|
+
/\/\/[^/\s:@]+:[^/\s@]+@/g, // basic-auth userinfo in URLs (e.g. x-access-token:…@github.com clones)
|
|
14
18
|
/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]+?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,
|
|
15
19
|
];
|
|
16
20
|
const REDACTED = "[REDACTED]";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sagentlab/navarch-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "Navarch machine-side session manager: claims delivery tasks and runs them through Claude Code, Codex, Gemini, or OpenCode.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|