svamp-cli 0.2.182 → 0.2.183
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/{agentCommands-Cf9VhA8Q.mjs → agentCommands-CDRs-TTe.mjs} +5 -5
- package/dist/{auth-CL9Qjhq6.mjs → auth-BwjvUcKt.mjs} +1 -1
- package/dist/cli.mjs +60 -60
- package/dist/{commands-HXmFkc9h.mjs → commands-Bv7vbi-z.mjs} +1 -1
- package/dist/{commands-f-gIOx_m.mjs → commands-C2mXJNwA.mjs} +20 -3
- package/dist/{commands-CM0JkQlm.mjs → commands-D4hGdv1B.mjs} +5 -5
- package/dist/{commands-D8uYJqvJ.mjs → commands-DQ_kpWqH.mjs} +1 -1
- package/dist/{commands-B_P2D4A3.mjs → commands-D_wD9qIr.mjs} +2 -2
- package/dist/{commands-BUg7EHp0.mjs → commands-ix9L1jaQ.mjs} +1 -1
- package/dist/{commands-Dxr3C5Y4.mjs → commands-pMwoqGpe.mjs} +2 -2
- package/dist/{fleet-wmEx5X-B.mjs → fleet-B4hfyHp4.mjs} +1 -1
- package/dist/{frpc-Clge8vu4.mjs → frpc-BzkAtKLy.mjs} +1 -1
- package/dist/{headlessCli-Bb3_TKKD.mjs → headlessCli-ohRvD7CT.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{package-C35XarmI.mjs → package-CcFzcCql.mjs} +1 -1
- package/dist/{rpc-oZAY4e3e.mjs → rpc-BwqRLir7.mjs} +1 -1
- package/dist/{rpc-BnH7Ljou.mjs → rpc-degyMl0V.mjs} +8 -2
- package/dist/{run-C_2jxzE5.mjs → run-68xel1pO.mjs} +168 -96
- package/dist/{run-CFgCIth9.mjs → run-B2aWNd0R.mjs} +1 -1
- package/dist/{scheduler-CYu4tzBf.mjs → scheduler-D0FGGxti.mjs} +3 -2
- package/dist/{serveCommands-CRntd5Tp.mjs → serveCommands-Bo2xZPIZ.mjs} +5 -5
- package/dist/{serveManager-CvlOyKBf.mjs → serveManager-BKbhWnMy.mjs} +2 -2
- package/dist/{sideband-Bqe-7HxJ.mjs → sideband-B1jzlbuf.mjs} +1 -1
- package/dist/{store-BPL__e4D.mjs → store-D-fJ9ANL.mjs} +17 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
import fs__default from 'fs';
|
|
3
3
|
import { resolve, join, relative } from 'path';
|
|
4
|
-
import { C as parseFrontmatter, D as getSkillsServer, E as getSkillsWorkspaceName, F as getSkillsCollectionName, G as fetchWithTimeout, H as searchSkills, I as SKILLS_DIR, J as getSkillInfo, K as downloadSkillFile, L as listSkillFiles } from './run-
|
|
4
|
+
import { C as parseFrontmatter, D as getSkillsServer, E as getSkillsWorkspaceName, F as getSkillsCollectionName, G as fetchWithTimeout, H as searchSkills, I as SKILLS_DIR, J as getSkillInfo, K as downloadSkillFile, L as listSkillFiles } from './run-68xel1pO.mjs';
|
|
5
5
|
import 'fs/promises';
|
|
6
6
|
import 'url';
|
|
7
7
|
import 'child_process';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
|
-
import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-
|
|
2
|
+
import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-DQ_kpWqH.mjs';
|
|
3
3
|
import { execSync } from 'node:child_process';
|
|
4
|
-
import { u as updateIssue, o as addComment, p as addIssue, x as shortId } from './run-
|
|
4
|
+
import { u as updateIssue, o as addComment, p as addIssue, x as shortId } from './run-68xel1pO.mjs';
|
|
5
5
|
import 'node:path';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'os';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import { c as connectToHypha } from './run-
|
|
4
|
+
import { c as connectToHypha } from './run-68xel1pO.mjs';
|
|
5
5
|
import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-HydRNEt7.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
@@ -4,7 +4,7 @@ import { mkdirSync, writeFileSync, unlinkSync, existsSync, chmodSync, readFileSy
|
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import { homedir, platform, arch } from 'os';
|
|
6
6
|
import { randomUUID, createHash } from 'crypto';
|
|
7
|
-
import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-
|
|
7
|
+
import { h as getFrpsSubdomainHost, i as getFrpsServerPort, j as getFrpsServerAddr } from './run-68xel1pO.mjs';
|
|
8
8
|
import 'fs/promises';
|
|
9
9
|
import 'url';
|
|
10
10
|
import 'node:crypto';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as resolveModel, _ as describeMisconfiguration, $ as buildMachineDeps } from './run-
|
|
2
|
-
import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-
|
|
1
|
+
import { M as resolveModel, _ as describeMisconfiguration, $ as buildMachineDeps } from './run-68xel1pO.mjs';
|
|
2
|
+
import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-B1jzlbuf.mjs';
|
|
3
3
|
import { WebSocket } from 'ws';
|
|
4
4
|
import { execSync, spawn } from 'child_process';
|
|
5
5
|
import 'os';
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-
|
|
1
|
+
export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-68xel1pO.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as resolveProjectRoot, u as updateIssue, n as getIssue, o as addComment, p as addIssue, q as listIssues, t as searchIssues } from './run-
|
|
1
|
+
import { m as resolveProjectRoot, u as updateIssue, n as getIssue, o as addComment, p as addIssue, q as listIssues, t as searchIssues } from './run-68xel1pO.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { m as resolveProjectRoot } from './run-
|
|
3
|
-
import { g as getWorkflow, w as workflowSteps, r as removeWorkflow,
|
|
2
|
+
import { m as resolveProjectRoot } from './run-68xel1pO.mjs';
|
|
3
|
+
import { g as getWorkflow, w as workflowSteps, s as setWorkflowEnabled, r as removeWorkflow, a as saveWorkflow, b as rawWorkflow, l as listWorkflows } from './store-D-fJ9ANL.mjs';
|
|
4
4
|
import 'os';
|
|
5
5
|
import 'fs/promises';
|
|
6
6
|
import 'fs';
|
|
@@ -53,6 +53,12 @@ function workflowRpc(cwd, params) {
|
|
|
53
53
|
}
|
|
54
54
|
case "remove":
|
|
55
55
|
return { removed: removeWorkflow(root, String(params.name)) };
|
|
56
|
+
case "enable":
|
|
57
|
+
case "disable": {
|
|
58
|
+
const wf = setWorkflowEnabled(root, String(params.name), op === "enable");
|
|
59
|
+
if (!wf) throw new Error(`Workflow not found: ${params.name}`);
|
|
60
|
+
return wf;
|
|
61
|
+
}
|
|
56
62
|
case "run": {
|
|
57
63
|
const wf = getWorkflow(root, String(params.name));
|
|
58
64
|
if (!wf) throw new Error(`Workflow not found: ${params.name}`);
|
|
@@ -89,7 +89,10 @@ function setOwnerWorkspace(ws) {
|
|
|
89
89
|
ownerWorkspace = ws || void 0;
|
|
90
90
|
}
|
|
91
91
|
function isSameOwnerWorkspace(context) {
|
|
92
|
-
|
|
92
|
+
const ws = context?.ws;
|
|
93
|
+
if (!ownerWorkspace || ownerWorkspace === "*") return false;
|
|
94
|
+
if (!ws || ws === "*") return false;
|
|
95
|
+
return ws === ownerWorkspace;
|
|
93
96
|
}
|
|
94
97
|
function resolveRoleLevel(sharing, userEmail) {
|
|
95
98
|
let level = -1;
|
|
@@ -2712,7 +2715,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
2712
2715
|
const tunnels = handlers.tunnels;
|
|
2713
2716
|
if (!tunnels) throw new Error("Tunnel management not available");
|
|
2714
2717
|
if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
|
|
2715
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
2718
|
+
const { FrpcTunnel } = await import('./frpc-BzkAtKLy.mjs');
|
|
2716
2719
|
const tunnel = new FrpcTunnel({
|
|
2717
2720
|
name: params.name,
|
|
2718
2721
|
ports: params.ports,
|
|
@@ -3159,7 +3162,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
3159
3162
|
}
|
|
3160
3163
|
const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
|
|
3161
3164
|
const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
|
|
3162
|
-
const { toolsForRole } = await import('./sideband-
|
|
3165
|
+
const { toolsForRole } = await import('./sideband-B1jzlbuf.mjs');
|
|
3163
3166
|
const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
|
|
3164
3167
|
return fmt(r2);
|
|
3165
3168
|
}
|
|
@@ -3258,7 +3261,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
|
|
|
3258
3261
|
if (r.error || !r.sender) return { error: r.error || "unauthorized" };
|
|
3259
3262
|
const callId = "call_" + Math.random().toString(16).slice(2, 12);
|
|
3260
3263
|
const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
|
|
3261
|
-
const { queryCore } = await import('./commands-
|
|
3264
|
+
const { queryCore } = await import('./commands-DQ_kpWqH.mjs');
|
|
3262
3265
|
const timeout = c.reply?.timeout_sec || 120;
|
|
3263
3266
|
let result;
|
|
3264
3267
|
try {
|
|
@@ -3528,6 +3531,35 @@ function applyInboxClear(inbox, opts) {
|
|
|
3528
3531
|
return { kept, removed: inbox.length - kept.length };
|
|
3529
3532
|
}
|
|
3530
3533
|
|
|
3534
|
+
function envInt(name, fallback) {
|
|
3535
|
+
const raw = process.env[name];
|
|
3536
|
+
if (raw === void 0 || raw === "") return fallback;
|
|
3537
|
+
const n = parseInt(raw, 10);
|
|
3538
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
3539
|
+
}
|
|
3540
|
+
function getRateLimitRetryConfig() {
|
|
3541
|
+
return {
|
|
3542
|
+
maxRetries: envInt("SVAMP_RATELIMIT_MAX_RETRIES", 10),
|
|
3543
|
+
baseMs: envInt("SVAMP_RATELIMIT_BASE_MS", 5e3),
|
|
3544
|
+
capMs: envInt("SVAMP_RATELIMIT_CAP_MS", 12e4)
|
|
3545
|
+
};
|
|
3546
|
+
}
|
|
3547
|
+
function computeRetryDelayMs(attempt, cfg = getRateLimitRetryConfig(), rng = Math.random) {
|
|
3548
|
+
const a = Math.max(0, Math.floor(attempt));
|
|
3549
|
+
const expo = Math.min(a, 30);
|
|
3550
|
+
const nominal = Math.min(cfg.capMs, cfg.baseMs * Math.pow(2, expo));
|
|
3551
|
+
const half = nominal / 2;
|
|
3552
|
+
return Math.round(half + rng() * half);
|
|
3553
|
+
}
|
|
3554
|
+
function isRetryableRateLimit(text, apiErrorStatus) {
|
|
3555
|
+
const t = (text || "").toLowerCase();
|
|
3556
|
+
const hardLimit = t.includes("quota") || t.includes("credit") || t.includes("balance") || t.includes("billing") || t.includes("payment") || t.includes("subscription") || t.includes("1m-context") || t.includes("1m context") || t.includes("insufficient") || t.includes("usage limit") && !t.includes("not your usage limit");
|
|
3557
|
+
if (hardLimit) return false;
|
|
3558
|
+
const authIssue = t.includes("unauthorized") || t.includes("invalid api key") || t.includes("authentication") || t.includes("forbidden");
|
|
3559
|
+
if (authIssue) return false;
|
|
3560
|
+
return apiErrorStatus === 429 || apiErrorStatus === 529 || apiErrorStatus === 503 || /\b(429|529|503)\b/.test(t) || t.includes("temporarily limiting") || t.includes("not your usage limit") || t.includes("overloaded") || t.includes("overload") || t.includes("too many requests") || t.includes("server is busy") || t.includes("rate limit") || t.includes("rate-limit") || t.includes("rate limited");
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3531
3563
|
const PARTICIPANTS_CHANNEL_ID = "sys-participants";
|
|
3532
3564
|
function channelPublicView(c) {
|
|
3533
3565
|
return { id: c.id, name: c.name, description: c.description, identity: { mode: c.identity?.mode }, action: c.action?.kind, bind: c.bind };
|
|
@@ -3858,7 +3890,7 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
3858
3890
|
}
|
|
3859
3891
|
};
|
|
3860
3892
|
ensureParticipantsChannel(initialMetadata.sharing);
|
|
3861
|
-
const
|
|
3893
|
+
const forkClaudeOnce = async (prompt, claudeSessionId, cwd, maxTurns, timeoutMs) => {
|
|
3862
3894
|
const { spawn } = await import('child_process');
|
|
3863
3895
|
return new Promise((resolve) => {
|
|
3864
3896
|
const child = spawn("claude", [
|
|
@@ -3895,14 +3927,37 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
|
|
|
3895
3927
|
}
|
|
3896
3928
|
try {
|
|
3897
3929
|
const result = JSON.parse(stdout);
|
|
3930
|
+
if (result && result.is_error) {
|
|
3931
|
+
resolve({ success: false, error: String(result.result || result.error || stderr || "error") });
|
|
3932
|
+
return;
|
|
3933
|
+
}
|
|
3898
3934
|
resolve({ success: true, text: result.result || result.text || stdout });
|
|
3899
3935
|
} catch {
|
|
3936
|
+
if (code !== 0) {
|
|
3937
|
+
resolve({ success: false, error: stderr || stdout.trim() || `claude exited with code ${code}` });
|
|
3938
|
+
return;
|
|
3939
|
+
}
|
|
3900
3940
|
resolve({ success: true, text: stdout.trim() });
|
|
3901
3941
|
}
|
|
3902
3942
|
});
|
|
3903
3943
|
child.on("error", (err) => resolve({ success: false, error: err.message }));
|
|
3904
3944
|
});
|
|
3905
3945
|
};
|
|
3946
|
+
const forkClaudePrint = async (prompt, claudeSessionId, cwd, maxTurns = 6, timeoutMs = 6e4) => {
|
|
3947
|
+
const cfg2 = getRateLimitRetryConfig();
|
|
3948
|
+
let last = { success: false, error: "" };
|
|
3949
|
+
for (let attempt = 0; ; attempt++) {
|
|
3950
|
+
last = await forkClaudeOnce(prompt, claudeSessionId, cwd, maxTurns, timeoutMs);
|
|
3951
|
+
if (last.success) return last;
|
|
3952
|
+
if (!isRetryableRateLimit(last.error || "") || attempt >= cfg2.maxRetries) return last;
|
|
3953
|
+
const delay = computeRetryDelayMs(attempt, cfg2);
|
|
3954
|
+
try {
|
|
3955
|
+
console.error(`[btw] rate-limited \u2014 holding ${Math.round(delay / 1e3)}s then retrying (attempt ${attempt + 1}/${cfg2.maxRetries})`);
|
|
3956
|
+
} catch {
|
|
3957
|
+
}
|
|
3958
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
3959
|
+
}
|
|
3960
|
+
};
|
|
3906
3961
|
const performEdit = async (target, newText) => {
|
|
3907
3962
|
if (!callbacks.onEditTranscript) return { success: false, message: "Editing history is not supported for this session." };
|
|
3908
3963
|
const info = editableInfo(target);
|
|
@@ -10214,35 +10269,6 @@ function resolveContextWindow(opts) {
|
|
|
10214
10269
|
return candidate;
|
|
10215
10270
|
}
|
|
10216
10271
|
|
|
10217
|
-
function envInt(name, fallback) {
|
|
10218
|
-
const raw = process.env[name];
|
|
10219
|
-
if (raw === void 0 || raw === "") return fallback;
|
|
10220
|
-
const n = parseInt(raw, 10);
|
|
10221
|
-
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
10222
|
-
}
|
|
10223
|
-
function getRateLimitRetryConfig() {
|
|
10224
|
-
return {
|
|
10225
|
-
maxRetries: envInt("SVAMP_RATELIMIT_MAX_RETRIES", 10),
|
|
10226
|
-
baseMs: envInt("SVAMP_RATELIMIT_BASE_MS", 5e3),
|
|
10227
|
-
capMs: envInt("SVAMP_RATELIMIT_CAP_MS", 12e4)
|
|
10228
|
-
};
|
|
10229
|
-
}
|
|
10230
|
-
function computeRetryDelayMs(attempt, cfg = getRateLimitRetryConfig(), rng = Math.random) {
|
|
10231
|
-
const a = Math.max(0, Math.floor(attempt));
|
|
10232
|
-
const expo = Math.min(a, 30);
|
|
10233
|
-
const nominal = Math.min(cfg.capMs, cfg.baseMs * Math.pow(2, expo));
|
|
10234
|
-
const half = nominal / 2;
|
|
10235
|
-
return Math.round(half + rng() * half);
|
|
10236
|
-
}
|
|
10237
|
-
function isRetryableRateLimit(text, apiErrorStatus) {
|
|
10238
|
-
const t = (text || "").toLowerCase();
|
|
10239
|
-
const hardLimit = t.includes("quota") || t.includes("credit") || t.includes("balance") || t.includes("billing") || t.includes("payment") || t.includes("subscription") || t.includes("1m-context") || t.includes("1m context") || t.includes("insufficient") || t.includes("usage limit") && !t.includes("not your usage limit");
|
|
10240
|
-
if (hardLimit) return false;
|
|
10241
|
-
const authIssue = t.includes("unauthorized") || t.includes("invalid api key") || t.includes("authentication") || t.includes("forbidden");
|
|
10242
|
-
if (authIssue) return false;
|
|
10243
|
-
return apiErrorStatus === 429 || apiErrorStatus === 529 || apiErrorStatus === 503 || /\b(429|529|503)\b/.test(t) || t.includes("temporarily limiting") || t.includes("not your usage limit") || t.includes("overloaded") || t.includes("overload") || t.includes("too many requests") || t.includes("server is busy") || t.includes("rate limit") || t.includes("rate-limit") || t.includes("rate limited");
|
|
10244
|
-
}
|
|
10245
|
-
|
|
10246
10272
|
const SVAMP_HOME$1 = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
|
|
10247
10273
|
function generateHookSettings(portOrOptions = {}) {
|
|
10248
10274
|
const opts = typeof portOrOptions === "number" ? { sessionStartPort: portOrOptions } : portOrOptions;
|
|
@@ -11581,7 +11607,7 @@ async function startDaemon(options) {
|
|
|
11581
11607
|
saveExposedTunnels(list);
|
|
11582
11608
|
}
|
|
11583
11609
|
async function createExposedTunnel(spec) {
|
|
11584
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
11610
|
+
const { FrpcTunnel } = await import('./frpc-BzkAtKLy.mjs');
|
|
11585
11611
|
const tunnel = new FrpcTunnel({
|
|
11586
11612
|
name: spec.name,
|
|
11587
11613
|
ports: spec.ports,
|
|
@@ -11601,7 +11627,7 @@ async function startDaemon(options) {
|
|
|
11601
11627
|
return tunnel;
|
|
11602
11628
|
}
|
|
11603
11629
|
const tunnelRecreateState = /* @__PURE__ */ new Map();
|
|
11604
|
-
const { ServeManager } = await import('./serveManager-
|
|
11630
|
+
const { ServeManager } = await import('./serveManager-BKbhWnMy.mjs');
|
|
11605
11631
|
const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
|
|
11606
11632
|
ensureAutoInstalledSkills(logger).catch(() => {
|
|
11607
11633
|
});
|
|
@@ -12955,73 +12981,119 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
12955
12981
|
return;
|
|
12956
12982
|
}
|
|
12957
12983
|
if (msgMeta?.btw && claudeResumeId) {
|
|
12984
|
+
const btwResumeId = claudeResumeId;
|
|
12958
12985
|
logger.log(`[Session ${sessionId}] /btw side-channel: "${text.substring(0, 80)}..."`);
|
|
12959
12986
|
sessionService.pushMessage(
|
|
12960
12987
|
{ type: "message", message: `/btw ${text}`, level: "btw-question" },
|
|
12961
12988
|
"event"
|
|
12962
12989
|
);
|
|
12963
12990
|
signalProcessing(true);
|
|
12964
|
-
const
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
|
|
12979
|
-
|
|
12980
|
-
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
12991
|
+
const runBtwOnce = () => new Promise((resolve2, reject) => {
|
|
12992
|
+
const btwArgs = [
|
|
12993
|
+
"--print",
|
|
12994
|
+
text,
|
|
12995
|
+
"--resume",
|
|
12996
|
+
btwResumeId,
|
|
12997
|
+
"--fork-session",
|
|
12998
|
+
"--no-session-persistence",
|
|
12999
|
+
// /btw is non-interactive; without bypass the forked Claude
|
|
13000
|
+
// pauses on tool prompts and the user sees a hanging side-channel.
|
|
13001
|
+
"--permission-mode",
|
|
13002
|
+
"bypassPermissions",
|
|
13003
|
+
"--output-format",
|
|
13004
|
+
"stream-json",
|
|
13005
|
+
"--verbose"
|
|
13006
|
+
];
|
|
13007
|
+
const btwProcess = spawn$1("claude", btwArgs, {
|
|
13008
|
+
cwd: directory,
|
|
13009
|
+
env: { ...process.env },
|
|
13010
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
13011
|
+
});
|
|
13012
|
+
let btwResult = "";
|
|
13013
|
+
let btwBuffer = "";
|
|
13014
|
+
let btwStderr = "";
|
|
13015
|
+
let settled = false;
|
|
13016
|
+
btwProcess.stderr?.on("data", (chunk) => {
|
|
13017
|
+
btwStderr += chunk.toString();
|
|
13018
|
+
});
|
|
13019
|
+
btwProcess.stdout.on("data", (chunk) => {
|
|
13020
|
+
btwBuffer += chunk.toString();
|
|
13021
|
+
let newlineIdx;
|
|
13022
|
+
while ((newlineIdx = btwBuffer.indexOf("\n")) !== -1) {
|
|
13023
|
+
const line = btwBuffer.substring(0, newlineIdx);
|
|
13024
|
+
btwBuffer = btwBuffer.substring(newlineIdx + 1);
|
|
13025
|
+
if (!line.trim()) continue;
|
|
13026
|
+
try {
|
|
13027
|
+
const msg = JSON.parse(line);
|
|
13028
|
+
if (msg.type === "assistant" && msg.message?.content) {
|
|
13029
|
+
for (const block of msg.message.content) {
|
|
13030
|
+
if (block.type === "text" && block.text) {
|
|
13031
|
+
btwResult += block.text;
|
|
13032
|
+
}
|
|
13033
|
+
}
|
|
13034
|
+
} else if (msg.type === "result") {
|
|
13035
|
+
if (settled) continue;
|
|
13036
|
+
settled = true;
|
|
13037
|
+
if (msg.is_error) {
|
|
13038
|
+
const err = new Error(String(msg.result || "error"));
|
|
13039
|
+
err.retryable = isRetryableRateLimit(String(msg.result || ""), msg.api_error_status);
|
|
13040
|
+
reject(err);
|
|
13041
|
+
} else {
|
|
13042
|
+
resolve2(btwResult || msg.result || "(no response)");
|
|
13000
13043
|
}
|
|
13001
13044
|
}
|
|
13002
|
-
}
|
|
13003
|
-
const finalText = btwResult || msg.result || "(no response)";
|
|
13004
|
-
sessionService.pushMessage(
|
|
13005
|
-
{ type: "message", message: finalText, level: "btw-answer" },
|
|
13006
|
-
"event"
|
|
13007
|
-
);
|
|
13008
|
-
signalProcessing(false);
|
|
13009
|
-
sessionService.sendSessionEnd();
|
|
13010
|
-
logger.log(`[Session ${sessionId}] /btw complete (${finalText.length} chars)`);
|
|
13045
|
+
} catch {
|
|
13011
13046
|
}
|
|
13012
|
-
} catch {
|
|
13013
13047
|
}
|
|
13014
|
-
}
|
|
13048
|
+
});
|
|
13049
|
+
btwProcess.on("exit", (code) => {
|
|
13050
|
+
if (settled) return;
|
|
13051
|
+
settled = true;
|
|
13052
|
+
if (code === 0) {
|
|
13053
|
+
resolve2(btwResult || "(no response)");
|
|
13054
|
+
return;
|
|
13055
|
+
}
|
|
13056
|
+
const detail = btwStderr.trim() || btwResult.trim();
|
|
13057
|
+
const err = new Error(detail || `claude exited with code ${code}`);
|
|
13058
|
+
err.retryable = isRetryableRateLimit(detail || "");
|
|
13059
|
+
reject(err);
|
|
13060
|
+
});
|
|
13061
|
+
btwProcess.on("error", (e) => {
|
|
13062
|
+
if (settled) return;
|
|
13063
|
+
settled = true;
|
|
13064
|
+
const err = new Error(e.message);
|
|
13065
|
+
err.retryable = false;
|
|
13066
|
+
reject(err);
|
|
13067
|
+
});
|
|
13015
13068
|
});
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13069
|
+
(async () => {
|
|
13070
|
+
let lastErr = null;
|
|
13071
|
+
for (let attempt = 0; ; attempt++) {
|
|
13072
|
+
try {
|
|
13073
|
+
const finalText = await runBtwOnce();
|
|
13074
|
+
sessionService.pushMessage(
|
|
13075
|
+
{ type: "message", message: finalText, level: "btw-answer" },
|
|
13076
|
+
"event"
|
|
13077
|
+
);
|
|
13078
|
+
logger.log(`[Session ${sessionId}] /btw complete (${finalText.length} chars)`);
|
|
13079
|
+
return;
|
|
13080
|
+
} catch (e) {
|
|
13081
|
+
lastErr = e;
|
|
13082
|
+
if (!e?.retryable || attempt >= RATELIMIT_CFG.maxRetries) break;
|
|
13083
|
+
const delayMs = computeRetryDelayMs(attempt, RATELIMIT_CFG);
|
|
13084
|
+
logger.log(`[Session ${sessionId}] /btw rate-limited \u2014 holding ${Math.round(delayMs / 1e3)}s then retrying (attempt ${attempt + 1}/${RATELIMIT_CFG.maxRetries})`);
|
|
13085
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
13086
|
+
}
|
|
13024
13087
|
}
|
|
13088
|
+
const detail = (lastErr?.message || "unknown error").toString().slice(0, 500);
|
|
13089
|
+
sessionService.pushMessage(
|
|
13090
|
+
{ type: "message", message: `/btw failed: ${detail}`, level: "error" },
|
|
13091
|
+
"event"
|
|
13092
|
+
);
|
|
13093
|
+
logger.log(`[Session ${sessionId}] /btw failed: ${detail}`);
|
|
13094
|
+
})().finally(() => {
|
|
13095
|
+
signalProcessing(false);
|
|
13096
|
+
sessionService.sendSessionEnd();
|
|
13025
13097
|
});
|
|
13026
13098
|
return;
|
|
13027
13099
|
}
|
|
@@ -13392,11 +13464,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
13392
13464
|
});
|
|
13393
13465
|
},
|
|
13394
13466
|
onIssue: async (params) => {
|
|
13395
|
-
const { issueRpc } = await import('./rpc-
|
|
13467
|
+
const { issueRpc } = await import('./rpc-BwqRLir7.mjs');
|
|
13396
13468
|
return issueRpc(params?.cwd || directory, params || {});
|
|
13397
13469
|
},
|
|
13398
13470
|
onWorkflow: async (params) => {
|
|
13399
|
-
const { workflowRpc } = await import('./rpc-
|
|
13471
|
+
const { workflowRpc } = await import('./rpc-degyMl0V.mjs');
|
|
13400
13472
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
13401
13473
|
},
|
|
13402
13474
|
onRipgrep: async (args, cwd) => {
|
|
@@ -13902,11 +13974,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
13902
13974
|
});
|
|
13903
13975
|
},
|
|
13904
13976
|
onIssue: async (params) => {
|
|
13905
|
-
const { issueRpc } = await import('./rpc-
|
|
13977
|
+
const { issueRpc } = await import('./rpc-BwqRLir7.mjs');
|
|
13906
13978
|
return issueRpc(params?.cwd || directory, params || {});
|
|
13907
13979
|
},
|
|
13908
13980
|
onWorkflow: async (params) => {
|
|
13909
|
-
const { workflowRpc } = await import('./rpc-
|
|
13981
|
+
const { workflowRpc } = await import('./rpc-degyMl0V.mjs');
|
|
13910
13982
|
return workflowRpc(params?.cwd || directory, params || {});
|
|
13911
13983
|
},
|
|
13912
13984
|
onRipgrep: async (args, cwd) => {
|
|
@@ -14659,7 +14731,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
14659
14731
|
const PING_TIMEOUT_MS = 15e3;
|
|
14660
14732
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
14661
14733
|
const RECONNECT_JITTER_MS = 2500;
|
|
14662
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
14734
|
+
const { WorkflowScheduler } = await import('./scheduler-D0FGGxti.mjs');
|
|
14663
14735
|
const workflowScheduler = new WorkflowScheduler({
|
|
14664
14736
|
projectRoots: () => {
|
|
14665
14737
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { a0 as composeSessionId, a1 as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, a2 as generateHookSettings } from './run-
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { a0 as composeSessionId, a1 as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, a2 as generateHookSettings } from './run-68xel1pO.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,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { m as resolveProjectRoot, v as cronMatches } from './run-
|
|
3
|
-
import { l as listWorkflows,
|
|
2
|
+
import { m as resolveProjectRoot, v as cronMatches } from './run-68xel1pO.mjs';
|
|
3
|
+
import { l as listWorkflows, i as isWorkflowEnabled, c as workflowCrons, w as workflowSteps } from './store-D-fJ9ANL.mjs';
|
|
4
4
|
import 'os';
|
|
5
5
|
import 'fs/promises';
|
|
6
6
|
import 'fs';
|
|
@@ -73,6 +73,7 @@ class WorkflowScheduler {
|
|
|
73
73
|
continue;
|
|
74
74
|
}
|
|
75
75
|
for (const wf of workflows) {
|
|
76
|
+
if (!isWorkflowEnabled(wf)) continue;
|
|
76
77
|
const crons = workflowCrons(wf);
|
|
77
78
|
if (!crons.length) continue;
|
|
78
79
|
if (crons.some((c) => cronMatchesSafe(c, now))) {
|
|
@@ -54,7 +54,7 @@ async function handleServeCommand() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
async function serveAdd(args, machineId) {
|
|
57
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
57
|
+
const { connectAndGetMachine } = await import('./commands-DQ_kpWqH.mjs');
|
|
58
58
|
const pos = positionalArgs(args);
|
|
59
59
|
const name = pos[0];
|
|
60
60
|
if (!name) {
|
|
@@ -93,7 +93,7 @@ async function serveAdd(args, machineId) {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
async function serveApply(args, machineId) {
|
|
96
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
96
|
+
const { connectAndGetMachine } = await import('./commands-DQ_kpWqH.mjs');
|
|
97
97
|
const fs = await import('fs');
|
|
98
98
|
const yaml = await import('yaml');
|
|
99
99
|
const file = positionalArgs(args)[0];
|
|
@@ -182,7 +182,7 @@ async function serveApply(args, machineId) {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
async function serveRemove(args, machineId) {
|
|
185
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
185
|
+
const { connectAndGetMachine } = await import('./commands-DQ_kpWqH.mjs');
|
|
186
186
|
const pos = positionalArgs(args);
|
|
187
187
|
const name = pos[0];
|
|
188
188
|
if (!name) {
|
|
@@ -202,7 +202,7 @@ async function serveRemove(args, machineId) {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
async function serveList(args, machineId) {
|
|
205
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
205
|
+
const { connectAndGetMachine } = await import('./commands-DQ_kpWqH.mjs');
|
|
206
206
|
const all = hasFlag(args, "--all", "-a");
|
|
207
207
|
const json = hasFlag(args, "--json");
|
|
208
208
|
const sessionId = getFlag(args, "--session");
|
|
@@ -235,7 +235,7 @@ async function serveList(args, machineId) {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
async function serveInfo(machineId) {
|
|
238
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
238
|
+
const { connectAndGetMachine } = await import('./commands-DQ_kpWqH.mjs');
|
|
239
239
|
const { machine, server } = await connectAndGetMachine(machineId);
|
|
240
240
|
try {
|
|
241
241
|
const info = await machine.serveInfo();
|
|
@@ -4,7 +4,7 @@ import * as fs from 'fs';
|
|
|
4
4
|
import * as http from 'http';
|
|
5
5
|
import * as net from 'net';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
-
import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-
|
|
7
|
+
import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-68xel1pO.mjs';
|
|
8
8
|
import 'os';
|
|
9
9
|
import 'fs/promises';
|
|
10
10
|
import 'url';
|
|
@@ -733,7 +733,7 @@ class ServeManager {
|
|
|
733
733
|
const mount = this.mounts.get(mountName);
|
|
734
734
|
const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, buildLinkSubdomain(subdomainSafe, mount.linkToken)]]) : void 0;
|
|
735
735
|
try {
|
|
736
|
-
const { FrpcTunnel } = await import('./frpc-
|
|
736
|
+
const { FrpcTunnel } = await import('./frpc-BzkAtKLy.mjs');
|
|
737
737
|
let tunnel;
|
|
738
738
|
tunnel = new FrpcTunnel({
|
|
739
739
|
name: tunnelName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as READ_ONLY_TOOLS, y as loadMachineContext, z as buildMachineInstructions, A as machineToolsForRole, B as buildMachineTools } from './run-
|
|
1
|
+
import { R as READ_ONLY_TOOLS, y as loadMachineContext, z as buildMachineInstructions, A as machineToolsForRole, B as buildMachineTools } from './run-68xel1pO.mjs';
|
|
2
2
|
import 'node:child_process';
|
|
3
3
|
import 'os';
|
|
4
4
|
import 'fs/promises';
|
|
@@ -2,6 +2,9 @@ import { existsSync, unlinkSync, readFileSync, readdirSync, mkdirSync, writeFile
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { parse, stringify } from 'yaml';
|
|
4
4
|
|
|
5
|
+
function isWorkflowEnabled(wf) {
|
|
6
|
+
return wf.enabled !== false;
|
|
7
|
+
}
|
|
5
8
|
function workflowSteps(wf) {
|
|
6
9
|
return Object.values(wf.jobs || {}).flatMap((j) => j?.steps || []);
|
|
7
10
|
}
|
|
@@ -54,7 +57,9 @@ function parseWorkflow(content) {
|
|
|
54
57
|
name: String(o.name),
|
|
55
58
|
on: normalizeOn(o.on),
|
|
56
59
|
jobs: normalizeJobs(o.jobs),
|
|
57
|
-
session: o.session ?? null
|
|
60
|
+
session: o.session ?? null,
|
|
61
|
+
// Only `enabled: false` disables; anything else (absent/true) is active.
|
|
62
|
+
...o.enabled === false ? { enabled: false } : {}
|
|
58
63
|
};
|
|
59
64
|
} catch {
|
|
60
65
|
return null;
|
|
@@ -63,6 +68,7 @@ function parseWorkflow(content) {
|
|
|
63
68
|
function serializeWorkflow(wf) {
|
|
64
69
|
const clean = { name: wf.name };
|
|
65
70
|
if (wf.session) clean.session = wf.session;
|
|
71
|
+
if (wf.enabled === false) clean.enabled = false;
|
|
66
72
|
const on = {};
|
|
67
73
|
if (wf.on?.schedule?.length) on.schedule = wf.on.schedule.map((s) => ({ cron: s.cron }));
|
|
68
74
|
if (wf.on?.workflow_dispatch) on.workflow_dispatch = {};
|
|
@@ -111,6 +117,15 @@ function saveWorkflow(projectRoot, wf) {
|
|
|
111
117
|
writeFileSync(tmp, serializeWorkflow(wf));
|
|
112
118
|
renameSync(tmp, path);
|
|
113
119
|
}
|
|
120
|
+
function setWorkflowEnabled(projectRoot, name, enabled) {
|
|
121
|
+
const wf = getWorkflow(projectRoot, name);
|
|
122
|
+
if (!wf) return null;
|
|
123
|
+
const next = { ...wf };
|
|
124
|
+
if (enabled) delete next.enabled;
|
|
125
|
+
else next.enabled = false;
|
|
126
|
+
saveWorkflow(projectRoot, next);
|
|
127
|
+
return next;
|
|
128
|
+
}
|
|
114
129
|
function removeWorkflow(projectRoot, name) {
|
|
115
130
|
const p = workflowPath(projectRoot, name);
|
|
116
131
|
if (!existsSync(p)) return false;
|
|
@@ -122,4 +137,4 @@ function removeWorkflow(projectRoot, name) {
|
|
|
122
137
|
}
|
|
123
138
|
}
|
|
124
139
|
|
|
125
|
-
export {
|
|
140
|
+
export { saveWorkflow as a, rawWorkflow as b, workflowCrons as c, getWorkflow as g, isWorkflowEnabled as i, listWorkflows as l, removeWorkflow as r, setWorkflowEnabled as s, workflowSteps as w };
|