svamp-cli 0.2.323 → 0.2.324
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/{adminCommands-Bmgpks9U.mjs → adminCommands-CHE1wq5m.mjs} +1 -1
- package/dist/{agentCommands-CjbndvZ2.mjs → agentCommands-D7CV6DKL.mjs} +5 -5
- package/dist/{auth-7A9m78i5.mjs → auth-BfimMIpL.mjs} +1 -1
- package/dist/{cli-C3GwCq0z.mjs → cli-Dv0vM2P7.mjs} +82 -77
- package/dist/cli.mjs +2 -2
- package/dist/{commands-LMbH3V-v.mjs → commands-4hjEGB-I.mjs} +11 -11
- package/dist/{commands-DLQwUjpD.mjs → commands-BA4LVlQW.mjs} +2 -2
- package/dist/{commands-CZLE29kn.mjs → commands-BQ7UFowe.mjs} +3 -3
- package/dist/{commands-BARTdhcw.mjs → commands-CQK2nD3o.mjs} +7 -4
- package/dist/{commands-DVvR4X4G.mjs → commands-CdbvHh2p.mjs} +2 -2
- package/dist/{commands-CygFvR0a.mjs → commands-CuyCq5eZ.mjs} +3 -3
- package/dist/{commands-C8im5Q2J.mjs → commands-GRfwAHgR.mjs} +17 -5
- package/dist/{commands-gQM3K8Yf.mjs → commands-jaaQooYW.mjs} +1 -1
- package/dist/{fleet-C68s3qVt.mjs → fleet-CSh3MUcM.mjs} +3 -3
- package/dist/{headlessCli-0_H-JwW2.mjs → headlessCli-Zl5Yu4CL.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notifyCommands-r0r8eyxA.mjs → notifyCommands-BQZXhfLt.mjs} +1 -1
- package/dist/{package-BGIfEYpX.mjs → package-DgboZg2o.mjs} +2 -2
- package/dist/{pinnedClaudeCode-C8CmQv3y.mjs → pinnedClaudeCode-8SZDu7O-.mjs} +1 -1
- package/dist/{rpc-BosOiRY-.mjs → rpc-BIzMNjqC.mjs} +1 -1
- package/dist/{rpc-DP4CiR0g.mjs → rpc-C1KIoUyz.mjs} +1 -1
- package/dist/{run-BiwqH1hw.mjs → run-CEp9YpUZ.mjs} +334 -53
- package/dist/{run-DAo9Lw4D.mjs → run-DKAROgSg.mjs} +1 -1
- package/dist/{scheduler-BN9GuvGN.mjs → scheduler-DIYulmdV.mjs} +1 -1
- package/dist/{serveCommands-C_E-RAiL.mjs → serveCommands-Bq5Cw3mE.mjs} +10 -10
- package/dist/{sideband-L0YNMJhj.mjs → sideband-C83128hf.mjs} +1 -1
- package/package.json +2 -2
- package/dist/supervisorLock-DmfzJx7B.mjs +0 -159
|
@@ -9,7 +9,7 @@ import { execFile, execSync, spawn, exec as exec$1 } from 'child_process';
|
|
|
9
9
|
import * as crypto from 'crypto';
|
|
10
10
|
import { randomUUID, createHash } from 'crypto';
|
|
11
11
|
import { randomUUID as randomUUID$1, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
12
|
-
import { existsSync, readFileSync, mkdirSync as mkdirSync$1, writeFileSync as writeFileSync$1, chmodSync as chmodSync$1, rmSync as rmSync$1, cpSync, statSync, realpathSync, readdirSync, renameSync, appendFileSync, openSync, readSync, closeSync, unlinkSync as unlinkSync$1 } from 'node:fs';
|
|
12
|
+
import { existsSync, readFileSync, mkdirSync as mkdirSync$1, writeFileSync as writeFileSync$1, chmodSync as chmodSync$1, rmSync as rmSync$1, cpSync, statSync, realpathSync, readdirSync, renameSync, appendFileSync, openSync, readSync, closeSync, unlinkSync as unlinkSync$1, writeSync } from 'node:fs';
|
|
13
13
|
import { exec, spawn as spawn$1, execSync as execSync$1, execFile as execFile$1, execFileSync } from 'node:child_process';
|
|
14
14
|
import { promisify } from 'util';
|
|
15
15
|
import * as http from 'http';
|
|
@@ -3811,7 +3811,7 @@ a{color:#0969da;text-decoration:none;font-weight:500}a:hover{text-decoration:und
|
|
|
3811
3811
|
const normRel = this.toSessionRelative(rootDir, m[2] || "");
|
|
3812
3812
|
if (method === "GET" || method === "HEAD") {
|
|
3813
3813
|
if (url.searchParams.get("list") === "1") {
|
|
3814
|
-
const lex =
|
|
3814
|
+
const lex = this.resolveContainedPath(rootDir, normRel);
|
|
3815
3815
|
if (!lex) {
|
|
3816
3816
|
deny(403, "Forbidden");
|
|
3817
3817
|
return;
|
|
@@ -4414,6 +4414,29 @@ var serveManager = /*#__PURE__*/Object.freeze({
|
|
|
4414
4414
|
sanitizeMountForRole: sanitizeMountForRole
|
|
4415
4415
|
});
|
|
4416
4416
|
|
|
4417
|
+
const EXEC_MAX_BUFFER = 16 * 1024 * 1024;
|
|
4418
|
+
function execFailureOutcome(err, stdout, stderr) {
|
|
4419
|
+
const e = err || {};
|
|
4420
|
+
const rawCode = e.code;
|
|
4421
|
+
const enobufs = rawCode === "ENOBUFS";
|
|
4422
|
+
const timedOut = rawCode === "ETIMEDOUT" || e.killed === true && !!e.signal;
|
|
4423
|
+
let exitCode;
|
|
4424
|
+
if (typeof rawCode === "number") exitCode = rawCode;
|
|
4425
|
+
else if (timedOut) exitCode = 124;
|
|
4426
|
+
else exitCode = 1;
|
|
4427
|
+
const base = stderr || e.message || "";
|
|
4428
|
+
let text = base;
|
|
4429
|
+
if (enobufs) {
|
|
4430
|
+
text = `output exceeded the ${Math.round(EXEC_MAX_BUFFER / (1024 * 1024))} MB buffer and was truncated (the command may have completed): ${base}`;
|
|
4431
|
+
} else if (timedOut) {
|
|
4432
|
+
text = `command timed out and was killed (it may have partially completed): ${base}`;
|
|
4433
|
+
}
|
|
4434
|
+
return { success: false, stdout: stdout || "", stderr: text, exitCode };
|
|
4435
|
+
}
|
|
4436
|
+
function execSuccessOutcome(stdout, stderr) {
|
|
4437
|
+
return { success: true, stdout: stdout || "", stderr: stderr || "", exitCode: 0 };
|
|
4438
|
+
}
|
|
4439
|
+
|
|
4417
4440
|
const EXAMPLE_HYPHA_PROXY_URL = "https://proxy.hypha.aicell.io";
|
|
4418
4441
|
const MODE_KEY = "SVAMP_CLAUDE_PROXY";
|
|
4419
4442
|
const HYPHA_PROXY_URL_KEY = "SVAMP_HYPHA_PROXY_URL";
|
|
@@ -4844,6 +4867,13 @@ function stripV1(url) {
|
|
|
4844
4867
|
}
|
|
4845
4868
|
return trimmed;
|
|
4846
4869
|
}
|
|
4870
|
+
function promptCacheTtlEnv(env, subscription) {
|
|
4871
|
+
if (env.FORCE_PROMPT_CACHING_5M) return void 0;
|
|
4872
|
+
if (!subscription) {
|
|
4873
|
+
return env.ENABLE_PROMPT_CACHING_1H === "1" ? "1" : void 0;
|
|
4874
|
+
}
|
|
4875
|
+
return env.ENABLE_PROMPT_CACHING_1H === "0" ? void 0 : "1";
|
|
4876
|
+
}
|
|
4847
4877
|
function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
4848
4878
|
switch (account.method) {
|
|
4849
4879
|
case "anthropic-api-key":
|
|
@@ -4852,7 +4882,9 @@ function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
|
4852
4882
|
claudeEnv: {
|
|
4853
4883
|
ANTHROPIC_API_KEY: account.secret,
|
|
4854
4884
|
ANTHROPIC_BASE_URL: account.baseUrl ? stripV1(account.baseUrl) : void 0,
|
|
4855
|
-
CLAUDE_CODE_OAUTH_TOKEN: void 0
|
|
4885
|
+
CLAUDE_CODE_OAUTH_TOKEN: void 0,
|
|
4886
|
+
// #0986: metered first-party key — the 1h TTL costs 2.0x per cache write.
|
|
4887
|
+
ENABLE_PROMPT_CACHING_1H: promptCacheTtlEnv(env, false)
|
|
4856
4888
|
},
|
|
4857
4889
|
describe: `anthropic API key (${account.label})`
|
|
4858
4890
|
};
|
|
@@ -4863,7 +4895,9 @@ function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
|
4863
4895
|
claudeEnv: {
|
|
4864
4896
|
ANTHROPIC_BASE_URL: url,
|
|
4865
4897
|
ANTHROPIC_API_KEY: account.secret,
|
|
4866
|
-
CLAUDE_CODE_OAUTH_TOKEN: void 0
|
|
4898
|
+
CLAUDE_CODE_OAUTH_TOKEN: void 0,
|
|
4899
|
+
// #0986: an arbitrary gateway's billing model is unknown — opt-in only.
|
|
4900
|
+
ENABLE_PROMPT_CACHING_1H: promptCacheTtlEnv(env, false)
|
|
4867
4901
|
},
|
|
4868
4902
|
describe: `anthropic gateway ${url} (${account.label})`
|
|
4869
4903
|
};
|
|
@@ -4880,7 +4914,7 @@ function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
|
4880
4914
|
ANTHROPIC_API_KEY: token,
|
|
4881
4915
|
CLAUDE_CODE_OAUTH_TOKEN: void 0,
|
|
4882
4916
|
// #0203: subscription backend qualifies for the free 1h prompt-cache TTL.
|
|
4883
|
-
ENABLE_PROMPT_CACHING_1H: env
|
|
4917
|
+
ENABLE_PROMPT_CACHING_1H: promptCacheTtlEnv(env, true)
|
|
4884
4918
|
},
|
|
4885
4919
|
describe: `hypha proxy ${url} (${account.label})`
|
|
4886
4920
|
};
|
|
@@ -4891,7 +4925,9 @@ function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
|
4891
4925
|
claudeEnv: {
|
|
4892
4926
|
CLAUDE_CODE_OAUTH_TOKEN: account.secret,
|
|
4893
4927
|
ANTHROPIC_BASE_URL: void 0,
|
|
4894
|
-
ANTHROPIC_API_KEY: void 0
|
|
4928
|
+
ANTHROPIC_API_KEY: void 0,
|
|
4929
|
+
// #0986: subscription token — free 1h TTL.
|
|
4930
|
+
ENABLE_PROMPT_CACHING_1H: promptCacheTtlEnv(env, true)
|
|
4895
4931
|
},
|
|
4896
4932
|
describe: `claude subscription token (${account.label})`
|
|
4897
4933
|
};
|
|
@@ -4901,7 +4937,9 @@ function resolveAccountEnv(account, env = process.env, svampHome) {
|
|
|
4901
4937
|
claudeEnv: {
|
|
4902
4938
|
CLAUDE_CODE_OAUTH_TOKEN: account.accessToken,
|
|
4903
4939
|
ANTHROPIC_BASE_URL: void 0,
|
|
4904
|
-
ANTHROPIC_API_KEY: void 0
|
|
4940
|
+
ANTHROPIC_API_KEY: void 0,
|
|
4941
|
+
// #0986: subscription OAuth — free 1h TTL.
|
|
4942
|
+
ENABLE_PROMPT_CACHING_1H: promptCacheTtlEnv(env, true)
|
|
4905
4943
|
},
|
|
4906
4944
|
describe: `claude subscription oauth (${account.label})`
|
|
4907
4945
|
};
|
|
@@ -5521,10 +5559,16 @@ const genKey = () => "ck_" + randomBytes(18).toString("base64url");
|
|
|
5521
5559
|
const DEFAULT_TEMPLATE = `<inbound-message from="\${sender.name}" sender-type="\${sender.kind}" verified="\${sender.verified}" channel="\${channel.name}" call-id="\${call.id}" at="\${now}">
|
|
5522
5560
|
\${body.message}
|
|
5523
5561
|
</inbound-message>`;
|
|
5562
|
+
const CHANNEL_ID_RE = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
5563
|
+
function isValidChannelId(id) {
|
|
5564
|
+
return typeof id === "string" && CHANNEL_ID_RE.test(id) && id !== "." && id !== "..";
|
|
5565
|
+
}
|
|
5524
5566
|
function validateChannel(c) {
|
|
5525
5567
|
const errs = [];
|
|
5526
5568
|
if (!c || typeof c !== "object") return ["channel must be an object"];
|
|
5527
5569
|
if (!c.name) errs.push("name required");
|
|
5570
|
+
if (c.id !== void 0 && !isValidChannelId(c.id))
|
|
5571
|
+
errs.push("id must match [A-Za-z0-9_.-]{1,64} (no path separators)");
|
|
5528
5572
|
const m = c.identity?.mode;
|
|
5529
5573
|
if (!["per-key", "caller-supplied", "fixed"].includes(m)) errs.push("identity.mode must be per-key|caller-supplied|fixed");
|
|
5530
5574
|
if (m === "fixed" && !c.identity.fixed?.name) errs.push("identity.fixed.name required for fixed mode");
|
|
@@ -5591,10 +5635,14 @@ class ChannelStore {
|
|
|
5591
5635
|
} catch {
|
|
5592
5636
|
}
|
|
5593
5637
|
}
|
|
5638
|
+
// #0982: reject a traversing/oversized id at the path boundary itself, so no
|
|
5639
|
+
// caller (RPC, HTTP, CLI) can reach outside this.dir regardless of its own checks.
|
|
5594
5640
|
_path(id) {
|
|
5641
|
+
if (!isValidChannelId(id)) throw new Error(`invalid channel id: ${String(id).slice(0, 64)}`);
|
|
5595
5642
|
return join$1(this.dir, `${id}.json`);
|
|
5596
5643
|
}
|
|
5597
5644
|
_lock(id) {
|
|
5645
|
+
if (!isValidChannelId(id)) throw new Error(`invalid channel id: ${String(id).slice(0, 64)}`);
|
|
5598
5646
|
return join$1(this.dir, `${id}.json.lock`);
|
|
5599
5647
|
}
|
|
5600
5648
|
// #0679: the actual validate + atomic write, WITHOUT the lock, so a locked RMW mutator can
|
|
@@ -6463,6 +6511,15 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
6463
6511
|
serveCallerTrusted(context),
|
|
6464
6512
|
process.env.SVAMP_OWNER_EMAIL
|
|
6465
6513
|
);
|
|
6514
|
+
const assertMayReplaceMount = (sm, name, context) => {
|
|
6515
|
+
const existingMount = sm.getMount(name);
|
|
6516
|
+
if (!existingMount || serveCallerTrusted(context)) return;
|
|
6517
|
+
const callerEmail = (context?.user?.email || "").toLowerCase();
|
|
6518
|
+
const mountOwner = (existingMount.ownerEmail || "").toLowerCase();
|
|
6519
|
+
if (!callerEmail || !mountOwner || callerEmail !== mountOwner) {
|
|
6520
|
+
throw new Error(`Not authorized to replace mount '${name}' (owned by another user)`);
|
|
6521
|
+
}
|
|
6522
|
+
};
|
|
6466
6523
|
let lastInboundRpcAt = Date.now();
|
|
6467
6524
|
const trackInbound = () => {
|
|
6468
6525
|
lastInboundRpcAt = Date.now();
|
|
@@ -6603,6 +6660,21 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
6603
6660
|
}
|
|
6604
6661
|
return result;
|
|
6605
6662
|
},
|
|
6663
|
+
/**
|
|
6664
|
+
* #0970: list ARCHIVED (stopped-but-persisted) sessions.
|
|
6665
|
+
*
|
|
6666
|
+
* Kept as its own method rather than a flag on listSessions so no existing caller's
|
|
6667
|
+
* view silently gains stopped rows. Machine-level `view` only: an archived session has
|
|
6668
|
+
* no live RPC handler, so the per-session sharing check listSessions falls back to
|
|
6669
|
+
* cannot run — rather than guess, this returns nothing to a caller without machine
|
|
6670
|
+
* access. That is the conservative direction (a session-shared user simply keeps
|
|
6671
|
+
* today's behaviour).
|
|
6672
|
+
*/
|
|
6673
|
+
listArchivedSessions: async (context) => {
|
|
6674
|
+
trackInbound();
|
|
6675
|
+
authorizeRequest(context, currentMetadata.sharing, "view");
|
|
6676
|
+
return handlers.getArchivedSessions?.() || [];
|
|
6677
|
+
},
|
|
6606
6678
|
/**
|
|
6607
6679
|
* Get summary info for all sessions (metadata, agent state, activity).
|
|
6608
6680
|
* Replaces the need to discover and query N individual session services.
|
|
@@ -7080,14 +7152,9 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
7080
7152
|
const { exec } = await import('child_process');
|
|
7081
7153
|
const { homedir } = await import('os');
|
|
7082
7154
|
return new Promise((resolve) => {
|
|
7083
|
-
exec(command, { cwd: cwd || homedir(), timeout: 3e4, maxBuffer:
|
|
7084
|
-
if (err)
|
|
7085
|
-
|
|
7086
|
-
const errText = enobufs ? `output exceeded the 16 MB buffer and was truncated (the command may have completed): ${stderr || err.message}` : stderr || err.message;
|
|
7087
|
-
resolve({ success: false, stdout: stdout || "", stderr: errText, exitCode: err.code ?? 1 });
|
|
7088
|
-
} else {
|
|
7089
|
-
resolve({ success: true, stdout, stderr: stderr || "", exitCode: 0 });
|
|
7090
|
-
}
|
|
7155
|
+
exec(command, { cwd: cwd || homedir(), timeout: 3e4, maxBuffer: EXEC_MAX_BUFFER }, (err, stdout, stderr) => {
|
|
7156
|
+
if (err) resolve(execFailureOutcome(err, stdout, stderr));
|
|
7157
|
+
else resolve(execSuccessOutcome(stdout, stderr));
|
|
7091
7158
|
});
|
|
7092
7159
|
});
|
|
7093
7160
|
},
|
|
@@ -7632,6 +7699,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
7632
7699
|
if (params.sessionId && !serveCallerTrusted(context)) {
|
|
7633
7700
|
await authorizeSessionAccess(params.sessionId, "admin", context);
|
|
7634
7701
|
}
|
|
7702
|
+
assertMayReplaceMount(sm, params.name, context);
|
|
7635
7703
|
const ownerEmail2 = resolveMountOwnerEmailFor(params.ownerEmail, context);
|
|
7636
7704
|
const access = params.access || "owner";
|
|
7637
7705
|
return sm.addMount(params.name, params.directory, params.sessionId, access, ownerEmail2);
|
|
@@ -7652,14 +7720,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
7652
7720
|
if (params.sessionId && !serveCallerTrusted(context)) {
|
|
7653
7721
|
await authorizeSessionAccess(params.sessionId, "admin", context);
|
|
7654
7722
|
}
|
|
7655
|
-
|
|
7656
|
-
if (existingMount && !serveCallerTrusted(context)) {
|
|
7657
|
-
const callerEmail = (context?.user?.email || "").toLowerCase();
|
|
7658
|
-
const mountOwner = (existingMount.ownerEmail || "").toLowerCase();
|
|
7659
|
-
if (!callerEmail || !mountOwner || callerEmail !== mountOwner) {
|
|
7660
|
-
throw new Error(`Not authorized to replace mount '${params.name}' (owned by another user)`);
|
|
7661
|
-
}
|
|
7662
|
-
}
|
|
7723
|
+
assertMayReplaceMount(sm, params.name, context);
|
|
7663
7724
|
const ownerEmail2 = resolveMountOwnerEmailFor(params.ownerEmail, context);
|
|
7664
7725
|
const access = params.access ?? "owner";
|
|
7665
7726
|
return sm.applyMount({
|
|
@@ -8030,7 +8091,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
8030
8091
|
}
|
|
8031
8092
|
const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
|
|
8032
8093
|
const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
|
|
8033
|
-
const { toolsForRole } = await import('./sideband-
|
|
8094
|
+
const { toolsForRole } = await import('./sideband-C83128hf.mjs');
|
|
8034
8095
|
const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
|
|
8035
8096
|
return fmt(r2);
|
|
8036
8097
|
}
|
|
@@ -8135,7 +8196,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
8135
8196
|
return { ok: false, call_id: callId, status: "busy", error: "channel is busy (too many concurrent requests) \u2014 retry shortly" };
|
|
8136
8197
|
}
|
|
8137
8198
|
const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
|
|
8138
|
-
const { queryCore } = await import('./commands-
|
|
8199
|
+
const { queryCore } = await import('./commands-GRfwAHgR.mjs');
|
|
8139
8200
|
const timeout = c.reply?.timeout_sec || 120;
|
|
8140
8201
|
let result;
|
|
8141
8202
|
try {
|
|
@@ -10242,7 +10303,7 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
10242
10303
|
return { ok: result.status === "completed", call_id: callId, correlationId: callId, status: result.status, reply: result.reply, tool_calls: result.toolCalls, error: result.error };
|
|
10243
10304
|
}
|
|
10244
10305
|
if (c.action?.kind === "loop") return { error: "loop channels are served by the channel server, not channelSend" };
|
|
10245
|
-
if (params.no_reply && c.action?.kind === "message") {
|
|
10306
|
+
if (params.no_reply && c.action?.kind === "message" && r.sender.verified) {
|
|
10246
10307
|
const envelope = renderMessage(c, { sender: r.sender, body: { message: params.message }, callId });
|
|
10247
10308
|
const wire = JSON.stringify({ role: "user", content: { type: "text", text: envelope } });
|
|
10248
10309
|
await deliverUserMessageCore(wire, params.localId || callId, void 0, true);
|
|
@@ -17851,6 +17912,197 @@ function shouldForceReconnect(consecutiveHeartbeatFailures) {
|
|
|
17851
17912
|
return consecutiveHeartbeatFailures === 2 || consecutiveHeartbeatFailures % 3 === 0;
|
|
17852
17913
|
}
|
|
17853
17914
|
|
|
17915
|
+
function acquireSupervisorLock(pidFile, pid = process.pid) {
|
|
17916
|
+
try {
|
|
17917
|
+
const fd = openSync(pidFile, "wx");
|
|
17918
|
+
try {
|
|
17919
|
+
writeSync(fd, String(pid));
|
|
17920
|
+
} finally {
|
|
17921
|
+
closeSync(fd);
|
|
17922
|
+
}
|
|
17923
|
+
return { acquired: true };
|
|
17924
|
+
} catch (err) {
|
|
17925
|
+
if (err?.code !== "EEXIST") throw err;
|
|
17926
|
+
}
|
|
17927
|
+
let existingPid = 0;
|
|
17928
|
+
try {
|
|
17929
|
+
existingPid = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
17930
|
+
} catch {
|
|
17931
|
+
}
|
|
17932
|
+
if (!existingPid || Number.isNaN(existingPid) || existingPid <= 0) {
|
|
17933
|
+
try {
|
|
17934
|
+
unlinkSync$1(pidFile);
|
|
17935
|
+
} catch {
|
|
17936
|
+
}
|
|
17937
|
+
return { acquired: false, staleCleaned: true };
|
|
17938
|
+
}
|
|
17939
|
+
if (isPidAlive(existingPid)) {
|
|
17940
|
+
return { acquired: false, heldBy: existingPid };
|
|
17941
|
+
}
|
|
17942
|
+
try {
|
|
17943
|
+
unlinkSync$1(pidFile);
|
|
17944
|
+
} catch {
|
|
17945
|
+
}
|
|
17946
|
+
return { acquired: false, staleCleaned: true };
|
|
17947
|
+
}
|
|
17948
|
+
function acquireSupervisorLockWithRetry(pidFile, pid = process.pid) {
|
|
17949
|
+
let result = acquireSupervisorLock(pidFile, pid);
|
|
17950
|
+
if (!result.acquired && result.staleCleaned) {
|
|
17951
|
+
result = acquireSupervisorLock(pidFile, pid);
|
|
17952
|
+
}
|
|
17953
|
+
return { acquired: result.acquired, heldBy: result.heldBy };
|
|
17954
|
+
}
|
|
17955
|
+
function releaseSupervisorLock(pidFile, pid = process.pid) {
|
|
17956
|
+
try {
|
|
17957
|
+
if (!existsSync(pidFile)) return;
|
|
17958
|
+
const content = parseInt(readFileSync(pidFile, "utf-8").trim(), 10);
|
|
17959
|
+
if (content === pid) unlinkSync$1(pidFile);
|
|
17960
|
+
} catch {
|
|
17961
|
+
}
|
|
17962
|
+
}
|
|
17963
|
+
function isPidAlive(pid) {
|
|
17964
|
+
if (!pid || Number.isNaN(pid) || pid <= 0) return false;
|
|
17965
|
+
try {
|
|
17966
|
+
process.kill(pid, 0);
|
|
17967
|
+
return true;
|
|
17968
|
+
} catch (err) {
|
|
17969
|
+
return err?.code === "EPERM";
|
|
17970
|
+
}
|
|
17971
|
+
}
|
|
17972
|
+
function isSupervisorPid(pid) {
|
|
17973
|
+
if (!pid || Number.isNaN(pid) || pid <= 0) return false;
|
|
17974
|
+
if (process.platform === "win32") return null;
|
|
17975
|
+
try {
|
|
17976
|
+
const out = execFileSync("ps", ["-o", "command=", "-p", String(pid)], {
|
|
17977
|
+
encoding: "utf-8",
|
|
17978
|
+
timeout: 5e3,
|
|
17979
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
17980
|
+
}).trim();
|
|
17981
|
+
if (!out) return false;
|
|
17982
|
+
return /daemon\s+start-supervised/.test(out);
|
|
17983
|
+
} catch {
|
|
17984
|
+
return null;
|
|
17985
|
+
}
|
|
17986
|
+
}
|
|
17987
|
+
function shouldSignalSupervisor(opts) {
|
|
17988
|
+
const { pid, alive, isSupervisor } = opts;
|
|
17989
|
+
if (!pid || Number.isNaN(pid) || pid <= 0) return false;
|
|
17990
|
+
if (!alive) return false;
|
|
17991
|
+
if (isSupervisor === false) return false;
|
|
17992
|
+
return true;
|
|
17993
|
+
}
|
|
17994
|
+
function findOrphanedSyncPids(currentSupervisorPid = process.pid) {
|
|
17995
|
+
if (process.platform === "win32") return [];
|
|
17996
|
+
const pids = [];
|
|
17997
|
+
try {
|
|
17998
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
17999
|
+
const pgrepArgs = uid !== void 0 ? ["-u", String(uid), "-af", "svamp daemon start-sync"] : ["-af", "svamp daemon start-sync"];
|
|
18000
|
+
const output = execFileSync("pgrep", pgrepArgs, {
|
|
18001
|
+
encoding: "utf-8",
|
|
18002
|
+
timeout: 5e3
|
|
18003
|
+
});
|
|
18004
|
+
for (const line of output.split("\n")) {
|
|
18005
|
+
const trimmed = line.trim();
|
|
18006
|
+
if (!trimmed) continue;
|
|
18007
|
+
const match = trimmed.match(/^(\d+)\s/);
|
|
18008
|
+
if (!match) continue;
|
|
18009
|
+
const pid = parseInt(match[1], 10);
|
|
18010
|
+
if (Number.isNaN(pid) || pid <= 0) continue;
|
|
18011
|
+
if (pid === process.pid) continue;
|
|
18012
|
+
const ppid = getPpid(pid);
|
|
18013
|
+
if (ppid === currentSupervisorPid) continue;
|
|
18014
|
+
pids.push(pid);
|
|
18015
|
+
}
|
|
18016
|
+
} catch (err) {
|
|
18017
|
+
if (err?.status !== 1) ;
|
|
18018
|
+
}
|
|
18019
|
+
return pids;
|
|
18020
|
+
}
|
|
18021
|
+
function getPpid(pid) {
|
|
18022
|
+
if (process.platform === "win32") return 0;
|
|
18023
|
+
try {
|
|
18024
|
+
const out = execFileSync("ps", ["-o", "ppid=", "-p", String(pid)], {
|
|
18025
|
+
encoding: "utf-8",
|
|
18026
|
+
timeout: 2e3
|
|
18027
|
+
}).trim();
|
|
18028
|
+
const ppid = parseInt(out, 10);
|
|
18029
|
+
return Number.isNaN(ppid) ? 0 : ppid;
|
|
18030
|
+
} catch {
|
|
18031
|
+
return 0;
|
|
18032
|
+
}
|
|
18033
|
+
}
|
|
18034
|
+
async function killOrphanedSyncs(pids, opts = {}) {
|
|
18035
|
+
if (pids.length === 0) return;
|
|
18036
|
+
const log = opts.log || (() => {
|
|
18037
|
+
});
|
|
18038
|
+
const gracePeriodMs = opts.gracePeriodMs ?? 3e3;
|
|
18039
|
+
log(`Killing ${pids.length} orphan sync daemon(s): ${pids.join(", ")}`);
|
|
18040
|
+
for (const pid of pids) {
|
|
18041
|
+
try {
|
|
18042
|
+
process.kill(pid, "SIGTERM");
|
|
18043
|
+
} catch {
|
|
18044
|
+
}
|
|
18045
|
+
}
|
|
18046
|
+
const pollStep = 100;
|
|
18047
|
+
const steps = Math.max(1, Math.ceil(gracePeriodMs / pollStep));
|
|
18048
|
+
for (let i = 0; i < steps; i++) {
|
|
18049
|
+
await new Promise((r) => setTimeout(r, pollStep));
|
|
18050
|
+
if (pids.every((p) => !isPidAlive(p))) {
|
|
18051
|
+
log("All orphan daemons exited cleanly");
|
|
18052
|
+
return;
|
|
18053
|
+
}
|
|
18054
|
+
}
|
|
18055
|
+
const survivors = pids.filter(isPidAlive);
|
|
18056
|
+
if (survivors.length > 0) {
|
|
18057
|
+
log(`Force-killing survivors: ${survivors.join(", ")}`);
|
|
18058
|
+
for (const pid of survivors) {
|
|
18059
|
+
try {
|
|
18060
|
+
process.kill(pid, "SIGKILL");
|
|
18061
|
+
} catch {
|
|
18062
|
+
}
|
|
18063
|
+
}
|
|
18064
|
+
}
|
|
18065
|
+
}
|
|
18066
|
+
function watchParentLiveness(opts) {
|
|
18067
|
+
if (process.env.SVAMP_SUPERVISED !== "1") {
|
|
18068
|
+
return () => {
|
|
18069
|
+
};
|
|
18070
|
+
}
|
|
18071
|
+
const supervisorPid = process.ppid;
|
|
18072
|
+
if (!supervisorPid || supervisorPid === 1) {
|
|
18073
|
+
return () => {
|
|
18074
|
+
};
|
|
18075
|
+
}
|
|
18076
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
18077
|
+
let fired = false;
|
|
18078
|
+
const timer = setInterval(() => {
|
|
18079
|
+
if (fired) return;
|
|
18080
|
+
if (!isPidAlive(supervisorPid)) {
|
|
18081
|
+
fired = true;
|
|
18082
|
+
clearInterval(timer);
|
|
18083
|
+
opts.onParentDeath();
|
|
18084
|
+
}
|
|
18085
|
+
}, intervalMs);
|
|
18086
|
+
timer.unref?.();
|
|
18087
|
+
return () => {
|
|
18088
|
+
clearInterval(timer);
|
|
18089
|
+
};
|
|
18090
|
+
}
|
|
18091
|
+
|
|
18092
|
+
var supervisorLock = /*#__PURE__*/Object.freeze({
|
|
18093
|
+
__proto__: null,
|
|
18094
|
+
acquireSupervisorLock: acquireSupervisorLock,
|
|
18095
|
+
acquireSupervisorLockWithRetry: acquireSupervisorLockWithRetry,
|
|
18096
|
+
findOrphanedSyncPids: findOrphanedSyncPids,
|
|
18097
|
+
getPpid: getPpid,
|
|
18098
|
+
isPidAlive: isPidAlive,
|
|
18099
|
+
isSupervisorPid: isSupervisorPid,
|
|
18100
|
+
killOrphanedSyncs: killOrphanedSyncs,
|
|
18101
|
+
releaseSupervisorLock: releaseSupervisorLock,
|
|
18102
|
+
shouldSignalSupervisor: shouldSignalSupervisor,
|
|
18103
|
+
watchParentLiveness: watchParentLiveness
|
|
18104
|
+
});
|
|
18105
|
+
|
|
17854
18106
|
const SVAMP_HOME$1 = process.env.SVAMP_HOME || join$1(os.homedir(), ".svamp");
|
|
17855
18107
|
function generateHookSettings(portOrOptions = {}) {
|
|
17856
18108
|
const opts = typeof portOrOptions === "number" ? { sessionStartPort: portOrOptions } : portOrOptions;
|
|
@@ -18811,7 +19063,9 @@ function spawnHeadlessEvaluator(prompt, opts) {
|
|
|
18811
19063
|
const evalArgs = [
|
|
18812
19064
|
"--print",
|
|
18813
19065
|
prompt,
|
|
18814
|
-
// Read-only reviewer (
|
|
19066
|
+
// Read-only reviewer (#0995: NOT the retired .claude/agents/loop-evaluator.md subagent —
|
|
19067
|
+
// this is a separate `claude --print` process whose prompt buildEvaluatorPrompt owns,
|
|
19068
|
+
// which is what keeps the #0189 independence invariant): it inspects real repo
|
|
18815
19069
|
// state but must not mutate the working tree it's judging. The allowedTools whitelist
|
|
18816
19070
|
// already excludes mutation tools; --disallowedTools is belt-and-suspenders. Kept to
|
|
18817
19071
|
// Write/Edit only — MultiEdit/NotebookEdit aren't known tool names on some claude builds
|
|
@@ -19337,6 +19591,26 @@ function clearSessionArchivedFlag(sessionId) {
|
|
|
19337
19591
|
return null;
|
|
19338
19592
|
}
|
|
19339
19593
|
}
|
|
19594
|
+
function loadArchivedSessionInfos(isLive) {
|
|
19595
|
+
const out = [];
|
|
19596
|
+
const index = loadSessionIndex();
|
|
19597
|
+
for (const [sessionId, entry] of Object.entries(index)) {
|
|
19598
|
+
if (isLive(sessionId)) continue;
|
|
19599
|
+
try {
|
|
19600
|
+
const data = JSON.parse(readFileSync$1(getSessionFilePath(entry.directory, sessionId), "utf-8"));
|
|
19601
|
+
if (!data?.sessionId) continue;
|
|
19602
|
+
out.push({
|
|
19603
|
+
sessionId: data.sessionId,
|
|
19604
|
+
startedBy: data.startedBy || "unknown",
|
|
19605
|
+
directory: data.directory || entry.directory,
|
|
19606
|
+
active: false,
|
|
19607
|
+
metadata: data.metadata
|
|
19608
|
+
});
|
|
19609
|
+
} catch {
|
|
19610
|
+
}
|
|
19611
|
+
}
|
|
19612
|
+
return out;
|
|
19613
|
+
}
|
|
19340
19614
|
function loadPersistedSessions() {
|
|
19341
19615
|
const sessions = [];
|
|
19342
19616
|
const index = loadSessionIndex();
|
|
@@ -19487,7 +19761,7 @@ async function startDaemon(options) {
|
|
|
19487
19761
|
process.on("SIGINT", () => requestShutdown("os-signal"));
|
|
19488
19762
|
process.on("SIGTERM", () => requestShutdown("os-signal"));
|
|
19489
19763
|
process.on("SIGUSR1", () => requestShutdown("os-signal-cleanup"));
|
|
19490
|
-
const { watchParentLiveness } = await
|
|
19764
|
+
const { watchParentLiveness } = await Promise.resolve().then(function () { return supervisorLock; });
|
|
19491
19765
|
const cancelParentWatchdog = watchParentLiveness({
|
|
19492
19766
|
intervalMs: 5e3,
|
|
19493
19767
|
onParentDeath: () => {
|
|
@@ -19680,7 +19954,7 @@ async function startDaemon(options) {
|
|
|
19680
19954
|
try {
|
|
19681
19955
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
19682
19956
|
if (!dir) return;
|
|
19683
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
19957
|
+
const { reconcileServiceLinks } = await import('./agentCommands-D7CV6DKL.mjs');
|
|
19684
19958
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
19685
19959
|
const config = readSvampConfig(configPath);
|
|
19686
19960
|
const entries = Array.from(urls.entries());
|
|
@@ -19702,7 +19976,7 @@ async function startDaemon(options) {
|
|
|
19702
19976
|
try {
|
|
19703
19977
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
19704
19978
|
if (!dir) return;
|
|
19705
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
19979
|
+
const { reconcileServiceLinks } = await import('./agentCommands-D7CV6DKL.mjs');
|
|
19706
19980
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
19707
19981
|
const config = readSvampConfig(configPath);
|
|
19708
19982
|
const incoming = [{
|
|
@@ -19723,7 +19997,7 @@ async function startDaemon(options) {
|
|
|
19723
19997
|
try {
|
|
19724
19998
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
19725
19999
|
if (!dir) return;
|
|
19726
|
-
const { dropServiceLinks } = await import('./agentCommands-
|
|
20000
|
+
const { dropServiceLinks } = await import('./agentCommands-D7CV6DKL.mjs');
|
|
19727
20001
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
19728
20002
|
const config = readSvampConfig(configPath);
|
|
19729
20003
|
if (dropServiceLinks(config, "serve", mountName)) {
|
|
@@ -19766,7 +20040,7 @@ async function startDaemon(options) {
|
|
|
19766
20040
|
ensureAutoInstalledCommands(logger);
|
|
19767
20041
|
(async () => {
|
|
19768
20042
|
try {
|
|
19769
|
-
const { beginClaudeVersionReconcile } = await import('./pinnedClaudeCode-
|
|
20043
|
+
const { beginClaudeVersionReconcile } = await import('./pinnedClaudeCode-8SZDu7O-.mjs');
|
|
19770
20044
|
beginClaudeVersionReconcile((msg) => logger.log(msg));
|
|
19771
20045
|
} catch (e) {
|
|
19772
20046
|
logger.log(`[claude-version] check failed: ${e?.message || e}`);
|
|
@@ -22086,21 +22360,18 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
22086
22360
|
logger.log(`[Session ${sessionId}] Bash: ${command} (cwd: ${cwd || directory}, timeout: ${execTimeout}ms)`);
|
|
22087
22361
|
const { exec: exec2 } = await import('child_process');
|
|
22088
22362
|
return new Promise((resolve2) => {
|
|
22089
|
-
exec2(command, { cwd: cwd || directory, timeout: execTimeout, maxBuffer:
|
|
22090
|
-
if (err)
|
|
22091
|
-
|
|
22092
|
-
} else {
|
|
22093
|
-
resolve2({ success: true, stdout, stderr: stderr || "", exitCode: 0 });
|
|
22094
|
-
}
|
|
22363
|
+
exec2(command, { cwd: cwd || directory, timeout: execTimeout, maxBuffer: EXEC_MAX_BUFFER }, (err, stdout, stderr) => {
|
|
22364
|
+
if (err) resolve2(execFailureOutcome(err, stdout, stderr));
|
|
22365
|
+
else resolve2(execSuccessOutcome(stdout, stderr));
|
|
22095
22366
|
});
|
|
22096
22367
|
});
|
|
22097
22368
|
},
|
|
22098
22369
|
onIssue: async (params) => {
|
|
22099
|
-
const { issueRpc } = await import('./rpc-
|
|
22370
|
+
const { issueRpc } = await import('./rpc-BIzMNjqC.mjs');
|
|
22100
22371
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
22101
22372
|
},
|
|
22102
22373
|
onWorkflow: async (params) => {
|
|
22103
|
-
const { workflowRpc } = await import('./rpc-
|
|
22374
|
+
const { workflowRpc } = await import('./rpc-C1KIoUyz.mjs');
|
|
22104
22375
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
22105
22376
|
},
|
|
22106
22377
|
onRipgrep: async (args, cwd) => {
|
|
@@ -22797,21 +23068,18 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
22797
23068
|
const execTimeout = timeout || 12e4;
|
|
22798
23069
|
const { exec: exec2 } = await import('child_process');
|
|
22799
23070
|
return new Promise((resolve2) => {
|
|
22800
|
-
exec2(command, { cwd: cwd || directory, timeout: execTimeout, maxBuffer:
|
|
22801
|
-
if (err)
|
|
22802
|
-
|
|
22803
|
-
} else {
|
|
22804
|
-
resolve2({ success: true, stdout, stderr: stderr || "", exitCode: 0 });
|
|
22805
|
-
}
|
|
23071
|
+
exec2(command, { cwd: cwd || directory, timeout: execTimeout, maxBuffer: EXEC_MAX_BUFFER }, (err, stdout, stderr) => {
|
|
23072
|
+
if (err) resolve2(execFailureOutcome(err, stdout, stderr));
|
|
23073
|
+
else resolve2(execSuccessOutcome(stdout, stderr));
|
|
22806
23074
|
});
|
|
22807
23075
|
});
|
|
22808
23076
|
},
|
|
22809
23077
|
onIssue: async (params) => {
|
|
22810
|
-
const { issueRpc } = await import('./rpc-
|
|
23078
|
+
const { issueRpc } = await import('./rpc-BIzMNjqC.mjs');
|
|
22811
23079
|
return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
22812
23080
|
},
|
|
22813
23081
|
onWorkflow: async (params) => {
|
|
22814
|
-
const { workflowRpc } = await import('./rpc-
|
|
23082
|
+
const { workflowRpc } = await import('./rpc-C1KIoUyz.mjs');
|
|
22815
23083
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
22816
23084
|
},
|
|
22817
23085
|
onRipgrep: async (args, cwd) => {
|
|
@@ -23640,6 +23908,11 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
23640
23908
|
logger.log("Shutdown requested via hypha-app (ignored \u2014 daemon never self-terminates)");
|
|
23641
23909
|
},
|
|
23642
23910
|
getTrackedSessions: getCurrentChildren,
|
|
23911
|
+
// #0970: archived (stopped-but-persisted) sessions, so CLI id resolution can find them.
|
|
23912
|
+
getArchivedSessions: () => {
|
|
23913
|
+
const live = new Set(getCurrentChildren().map((c) => c.sessionId));
|
|
23914
|
+
return loadArchivedSessionInfos((id) => live.has(id));
|
|
23915
|
+
},
|
|
23643
23916
|
getSessionRPCHandlers: (sessionId) => {
|
|
23644
23917
|
for (const [, session] of pidToTrackedSession) {
|
|
23645
23918
|
if (session.svampSessionId === sessionId && !session.stopped && session.sessionRPCHandlers) {
|
|
@@ -23863,7 +24136,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
23863
24136
|
}
|
|
23864
24137
|
if (persistedSessions.length > 0) {
|
|
23865
24138
|
try {
|
|
23866
|
-
const { awaitClaudeVersionReady } = await import('./pinnedClaudeCode-
|
|
24139
|
+
const { awaitClaudeVersionReady } = await import('./pinnedClaudeCode-8SZDu7O-.mjs');
|
|
23867
24140
|
await awaitClaudeVersionReady();
|
|
23868
24141
|
} catch {
|
|
23869
24142
|
}
|
|
@@ -23964,8 +24237,16 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
23964
24237
|
const supPidFile = join(SVAMP_HOME, "supervisor.pid");
|
|
23965
24238
|
const supPid = existsSync$1(supPidFile) ? parseInt(readFileSync$1(supPidFile, "utf-8").trim(), 10) : NaN;
|
|
23966
24239
|
if (supPid && !isNaN(supPid)) {
|
|
23967
|
-
|
|
23968
|
-
|
|
24240
|
+
const ok = shouldSignalSupervisor({
|
|
24241
|
+
pid: supPid,
|
|
24242
|
+
alive: isPidAlive(supPid),
|
|
24243
|
+
isSupervisor: isSupervisorPid(supPid)
|
|
24244
|
+
});
|
|
24245
|
+
if (ok) {
|
|
24246
|
+
process.kill(supPid, "SIGUSR2");
|
|
24247
|
+
return;
|
|
24248
|
+
}
|
|
24249
|
+
logger.log(`[graceful-restart] supervisor.pid ${supPid} is stale or not a supervisor \u2014 not signalling`);
|
|
23969
24250
|
}
|
|
23970
24251
|
} catch {
|
|
23971
24252
|
}
|
|
@@ -24112,7 +24393,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
24112
24393
|
const PING_TIMEOUT_MS = 15e3;
|
|
24113
24394
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
24114
24395
|
const RECONNECT_JITTER_MS = 2500;
|
|
24115
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
24396
|
+
const { WorkflowScheduler } = await import('./scheduler-DIYulmdV.mjs');
|
|
24116
24397
|
const workflowProjectRoots = () => {
|
|
24117
24398
|
const dirs = /* @__PURE__ */ new Set();
|
|
24118
24399
|
for (const s of pidToTrackedSession.values()) {
|
|
@@ -24745,4 +25026,4 @@ var run = /*#__PURE__*/Object.freeze({
|
|
|
24745
25026
|
writeStopMarker: writeStopMarker
|
|
24746
25027
|
});
|
|
24747
25028
|
|
|
24748
|
-
export { listSkillFiles as $, saveWorkflow as A, rawWorkflow as B, listWorkflows as C, isWorkflowEnabled as D, workflowSchedules as E, inZone as F, cronMatches as G, summarize as H, workflowSteps as I, parseJwtEmail as J, computeCollectionConfigUpdate as K, SYSTEM_COLLECTION_CONFIG as L, loadMachineContext as M, buildMachineInstructions as N, machineToolsForRole as O, buildMachineTools as P, parseFrontmatter as Q, READ_ONLY_TOOLS as R, SharingNotificationSync as S, getSkillsServer as T, getSkillsWorkspaceName as U, getSkillsCollectionName as V, fetchWithTimeout as W, searchSkills as X, SKILLS_DIR as Y, getSkillInfo as Z, downloadSkillFile as _, createSessionStore as a, resolveModel as a0, formatHandle as a1, normalizeAllowedUser as a2, loadSecurityContextConfig as a3, resolveSecurityContext as a4, buildSecurityContextFromFlags as a5, mergeSecurityContexts as a6, buildSessionShareUrl as a7, computeOutboundHop as a8, registerAwaitingReply as a9, kimiSetup as aA, api as aB,
|
|
25029
|
+
export { listSkillFiles as $, saveWorkflow as A, rawWorkflow as B, listWorkflows as C, isWorkflowEnabled as D, workflowSchedules as E, inZone as F, cronMatches as G, summarize as H, workflowSteps as I, parseJwtEmail as J, computeCollectionConfigUpdate as K, SYSTEM_COLLECTION_CONFIG as L, loadMachineContext as M, buildMachineInstructions as N, machineToolsForRole as O, buildMachineTools as P, parseFrontmatter as Q, READ_ONLY_TOOLS as R, SharingNotificationSync as S, getSkillsServer as T, getSkillsWorkspaceName as U, getSkillsCollectionName as V, fetchWithTimeout as W, searchSkills as X, SKILLS_DIR as Y, getSkillInfo as Z, downloadSkillFile as _, createSessionStore as a, resolveModel as a0, formatHandle as a1, normalizeAllowedUser as a2, loadSecurityContextConfig as a3, resolveSecurityContext as a4, buildSecurityContextFromFlags as a5, mergeSecurityContexts as a6, buildSessionShareUrl as a7, computeOutboundHop as a8, registerAwaitingReply as a9, kimiSetup as aA, api as aB, supervisorLock as aC, run as aD, buildMachineShareUrl as aa, parseHandle as ab, handleMatchesMetadata as ac, PINNED_CODEX_VERSION as ad, clearStopMarker as ae, stopMarkerExists as af, withFileLock as ag, describeMisconfiguration as ah, buildMachineDeps as ai, applyClaudeProxyEnv as aj, composeSessionId as ak, generateFriendlyName as al, generateHookSettings as am, instanceConfig as an, frpc as ao, staticFileServer as ap, claudeAuth as aq, codexProvider as ar, projectInfo as as, DefaultTransport$1 as at, acpBackend as au, acpAgentConfig as av, codexAppServerBackend as aw, GeminiTransport$1 as ax, KimiTransport$1 as ay, kimiProvider as az, stopDaemon as b, connectToHypha as c, daemonStatus as d, shortId as e, resolveProjectRoot as f, getHyphaServerUrl$1 as g, getIssue as h, resumeIssue as i, addComment as j, addIssue as k, listIssues as l, isPendingIssue as m, searchIssues as n, isVisibleTo as o, pauseIssue as p, getRun as q, registerMachineService as r, startDaemon as s, listRuns as t, updateIssue as u, getWorkflow as v, runWorkflow as w, setWorkflowEnabled as x, removeWorkflow as y, validateWorkflowName as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { aj as applyClaudeProxyEnv, ak as composeSessionId, al as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, am as generateHookSettings } from './run-
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { aj as applyClaudeProxyEnv, ak as composeSessionId, al as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, am as generateHookSettings } from './run-CEp9YpUZ.mjs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import { existsSync, readFileSync, watch } from 'node:fs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as resolveProjectRoot, C as listWorkflows, D as isWorkflowEnabled, E as workflowSchedules, F as inZone, w as runWorkflow, G as cronMatches } from './run-
|
|
1
|
+
import { f as resolveProjectRoot, C as listWorkflows, D as isWorkflowEnabled, E as workflowSchedules, F as inZone, w as runWorkflow, G as cronMatches } from './run-CEp9YpUZ.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|