sparkecoder 0.1.110 → 0.1.112
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/agent/index.d.ts +3 -3
- package/dist/agent/index.js +10 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +261 -88
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-Biy5JTop.d.ts → index-Bi8Ek02A.d.ts} +104 -104
- package/dist/index.d.ts +5 -5
- package/dist/index.js +261 -88
- package/dist/index.js.map +1 -1
- package/dist/{schema-CYSKJZ3m.d.ts → schema-ecQSnCMz.d.ts} +3 -3
- package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
- package/dist/server/index.js +261 -88
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__6097da17._.js +3 -3
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_app_(main)_page_tsx_5ac4794b._.js +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_app_(main)_settings_page_tsx_eb320e07._.js +1 -31
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/.next/static/chunks/{ae4bb24474ff1ed0.js → a189cacf6d83cf0b.js} +5 -5
- package/web/.next/standalone/web/.next/static/chunks/bef6931fdd8428c8.js +1 -0
- package/web/.next/standalone/web/.next/static/chunks/c1f73b3fa4353c31.css +1 -0
- package/web/.next/standalone/web/.next/static/chunks/c5dd884b71007965.js +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/{ae4bb24474ff1ed0.js → a189cacf6d83cf0b.js} +5 -5
- package/web/.next/standalone/web/.next/static/static/chunks/bef6931fdd8428c8.js +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/c1f73b3fa4353c31.css +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/c5dd884b71007965.js +1 -0
- package/web/.next/standalone/web/package-lock.json +7 -7
- package/web/.next/standalone/web/src/app/(main)/page.tsx +36 -2
- package/web/.next/standalone/web/src/app/(main)/settings/page.tsx +76 -35
- package/web/.next/standalone/web/src/components/chat-interface.tsx +34 -0
- package/web/.next/static/chunks/{ae4bb24474ff1ed0.js → a189cacf6d83cf0b.js} +5 -5
- package/web/.next/static/chunks/bef6931fdd8428c8.js +1 -0
- package/web/.next/static/chunks/c1f73b3fa4353c31.css +1 -0
- package/web/.next/static/chunks/c5dd884b71007965.js +1 -0
- package/web/.next/standalone/web/.next/static/chunks/344be859c2c8600b.css +0 -1
- package/web/.next/standalone/web/.next/static/chunks/b038e0ff462bfe45.js +0 -31
- package/web/.next/standalone/web/.next/static/chunks/f5fe518b79d1bf41.js +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/344be859c2c8600b.css +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/b038e0ff462bfe45.js +0 -31
- package/web/.next/standalone/web/.next/static/static/chunks/f5fe518b79d1bf41.js +0 -1
- package/web/.next/static/chunks/344be859c2c8600b.css +0 -1
- package/web/.next/static/chunks/b038e0ff462bfe45.js +0 -31
- package/web/.next/static/chunks/f5fe518b79d1bf41.js +0 -1
- /package/web/.next/standalone/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → static/x3G1ePtJHSb_uWa9Qs8dN}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → static/x3G1ePtJHSb_uWa9Qs8dN}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → static/x3G1ePtJHSb_uWa9Qs8dN}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{static/TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_ssgManifest.js +0 -0
- /package/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_buildManifest.js +0 -0
- /package/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{TSXbqtKMFeFa6H3GGMd86 → x3G1ePtJHSb_uWa9Qs8dN}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -1340,9 +1340,10 @@ function createDefaultConfig() {
|
|
|
1340
1340
|
}
|
|
1341
1341
|
function loadStoredAuthKey() {
|
|
1342
1342
|
const locations = [
|
|
1343
|
+
process.env.SPARKECODER_AUTH_KEY_PATH,
|
|
1343
1344
|
join(process.cwd(), ".sparkecoder", AUTH_KEY_FILE),
|
|
1344
1345
|
join(getAppDataDirectory(), AUTH_KEY_FILE)
|
|
1345
|
-
];
|
|
1346
|
+
].filter((p) => !!p);
|
|
1346
1347
|
for (const keysPath of locations) {
|
|
1347
1348
|
if (!existsSync(keysPath)) continue;
|
|
1348
1349
|
try {
|
|
@@ -1361,15 +1362,44 @@ function saveAuthKey(authKey3, userId) {
|
|
|
1361
1362
|
userId
|
|
1362
1363
|
};
|
|
1363
1364
|
const json = JSON.stringify(data, null, 2);
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1365
|
+
const targets = [];
|
|
1366
|
+
if (process.env.SPARKECODER_AUTH_KEY_PATH) {
|
|
1367
|
+
targets.push({
|
|
1368
|
+
label: "SPARKECODER_AUTH_KEY_PATH",
|
|
1369
|
+
path: process.env.SPARKECODER_AUTH_KEY_PATH
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1366
1372
|
try {
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1373
|
+
const appDir = ensureAppDataDirectory();
|
|
1374
|
+
targets.push({ label: "app-data", path: join(appDir, AUTH_KEY_FILE) });
|
|
1375
|
+
} catch (err) {
|
|
1376
|
+
console.warn(`[auth-key] could not ensure app data dir: ${err?.message ?? err}`);
|
|
1377
|
+
}
|
|
1378
|
+
targets.push({
|
|
1379
|
+
label: "workspace",
|
|
1380
|
+
path: join(process.cwd(), ".sparkecoder", AUTH_KEY_FILE)
|
|
1381
|
+
});
|
|
1382
|
+
const successes = [];
|
|
1383
|
+
const failures = [];
|
|
1384
|
+
for (const { label, path } of targets) {
|
|
1385
|
+
try {
|
|
1386
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
1387
|
+
writeFileSync(path, json, { mode: 384 });
|
|
1388
|
+
successes.push(`${label}:${path}`);
|
|
1389
|
+
} catch (err) {
|
|
1390
|
+
failures.push({ label, path, error: err?.message ?? String(err) });
|
|
1370
1391
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1392
|
+
}
|
|
1393
|
+
if (successes.length === 0) {
|
|
1394
|
+
const detail = failures.map((f) => `${f.label} (${f.path}): ${f.error}`).join("; ");
|
|
1395
|
+
throw new Error(`Failed to persist auth-key.json to any location. ${detail}`);
|
|
1396
|
+
}
|
|
1397
|
+
if (failures.length > 0) {
|
|
1398
|
+
console.warn(
|
|
1399
|
+
`[auth-key] wrote to ${successes.length}/${targets.length} locations. Success: ${successes.join(", ")}. Failed: ${failures.map((f) => `${f.label} (${f.path}): ${f.error}`).join("; ")}`
|
|
1400
|
+
);
|
|
1401
|
+
} else if (process.env.SPARKECODER_VERBOSE_CONFIG) {
|
|
1402
|
+
console.log(`[auth-key] saved to: ${successes.join(", ")}`);
|
|
1373
1403
|
}
|
|
1374
1404
|
}
|
|
1375
1405
|
function getStoredAuthKeyInfo() {
|
|
@@ -9033,15 +9063,30 @@ var init_client3 = __esm({
|
|
|
9033
9063
|
});
|
|
9034
9064
|
|
|
9035
9065
|
// src/integrations/channels/slack.ts
|
|
9066
|
+
function threadKey(channel, threadTs) {
|
|
9067
|
+
return `${channel}\u241F${threadTs}`;
|
|
9068
|
+
}
|
|
9069
|
+
function markThreadOwned(channel, threadTs) {
|
|
9070
|
+
ownedThreads.add(threadKey(channel, threadTs));
|
|
9071
|
+
}
|
|
9072
|
+
function isThreadOwned(channel, threadTs) {
|
|
9073
|
+
return ownedThreads.has(threadKey(channel, threadTs));
|
|
9074
|
+
}
|
|
9036
9075
|
function stripMention(text) {
|
|
9037
9076
|
return String(text || "").replace(/<@[^>]+>/g, "").trim();
|
|
9038
9077
|
}
|
|
9039
9078
|
function slackEventToInboundResult(event) {
|
|
9040
9079
|
if (!event) return { event: null, dropReason: "empty_text" };
|
|
9041
|
-
if (event.bot_id
|
|
9080
|
+
if (event.bot_id) return { event: null, dropReason: "bot_message" };
|
|
9081
|
+
if (event.type === "message" && event.subtype && IGNORED_MESSAGE_SUBTYPES.has(event.subtype)) {
|
|
9082
|
+
return { event: null, dropReason: "bot_message" };
|
|
9083
|
+
}
|
|
9042
9084
|
const isDm = event.type === "message" && event.channel_type === "im";
|
|
9043
|
-
|
|
9044
|
-
|
|
9085
|
+
const isThreadReply = event.type === "message" && !isDm && typeof event.thread_ts === "string" && event.thread_ts !== event.ts;
|
|
9086
|
+
if (event.type !== "app_mention" && !isDm && !isThreadReply) {
|
|
9087
|
+
return { event: null, dropReason: "unsupported_type" };
|
|
9088
|
+
}
|
|
9089
|
+
const text = event.type === "app_mention" ? stripMention(event.text) : (event.text ?? "").trim();
|
|
9045
9090
|
if (!text) return { event: null, dropReason: "empty_text" };
|
|
9046
9091
|
const policy = getSlackAllowlistPolicy();
|
|
9047
9092
|
const userAllowlistActive = policy.allowedUsers.length > 0;
|
|
@@ -9076,11 +9121,12 @@ function slackEventToInboundResult(event) {
|
|
|
9076
9121
|
}
|
|
9077
9122
|
};
|
|
9078
9123
|
}
|
|
9079
|
-
var slackChannel;
|
|
9124
|
+
var ownedThreads, slackChannel, IGNORED_MESSAGE_SUBTYPES;
|
|
9080
9125
|
var init_slack = __esm({
|
|
9081
9126
|
"src/integrations/channels/slack.ts"() {
|
|
9082
9127
|
"use strict";
|
|
9083
9128
|
init_client3();
|
|
9129
|
+
ownedThreads = /* @__PURE__ */ new Set();
|
|
9084
9130
|
slackChannel = {
|
|
9085
9131
|
id: "slack",
|
|
9086
9132
|
canSend: () => isSlackConfigured(),
|
|
@@ -9094,6 +9140,9 @@ var init_slack = __esm({
|
|
|
9094
9140
|
threadTs: r.threadTs
|
|
9095
9141
|
});
|
|
9096
9142
|
if (!result.ok) throw new Error(`slack post failed: ${result.error}`);
|
|
9143
|
+
if (r.slackChannel && r.threadTs) {
|
|
9144
|
+
markThreadOwned(r.slackChannel, r.threadTs);
|
|
9145
|
+
}
|
|
9097
9146
|
},
|
|
9098
9147
|
displayLabel(ref) {
|
|
9099
9148
|
const r = ref;
|
|
@@ -9104,6 +9153,29 @@ var init_slack = __esm({
|
|
|
9104
9153
|
return parts.join(" ");
|
|
9105
9154
|
}
|
|
9106
9155
|
};
|
|
9156
|
+
IGNORED_MESSAGE_SUBTYPES = /* @__PURE__ */ new Set([
|
|
9157
|
+
"bot_message",
|
|
9158
|
+
"message_changed",
|
|
9159
|
+
"message_deleted",
|
|
9160
|
+
"channel_join",
|
|
9161
|
+
"channel_leave",
|
|
9162
|
+
"channel_topic",
|
|
9163
|
+
"channel_purpose",
|
|
9164
|
+
"channel_name",
|
|
9165
|
+
"channel_archive",
|
|
9166
|
+
"channel_unarchive",
|
|
9167
|
+
"pinned_item",
|
|
9168
|
+
"unpinned_item",
|
|
9169
|
+
"thread_broadcast",
|
|
9170
|
+
// also-broadcast-to-channel replies; the regular thread reply already fires
|
|
9171
|
+
"message_replied",
|
|
9172
|
+
// legacy parent-thread bump
|
|
9173
|
+
"file_share",
|
|
9174
|
+
// we'd handle these later; for now skip to avoid double-handling
|
|
9175
|
+
"reply_broadcast",
|
|
9176
|
+
"tombstone",
|
|
9177
|
+
"huddle_thread"
|
|
9178
|
+
]);
|
|
9107
9179
|
}
|
|
9108
9180
|
});
|
|
9109
9181
|
|
|
@@ -11405,6 +11477,81 @@ var init_session_lock = __esm({
|
|
|
11405
11477
|
}
|
|
11406
11478
|
});
|
|
11407
11479
|
|
|
11480
|
+
// src/orchestrator/daemon.ts
|
|
11481
|
+
var daemon_exports = {};
|
|
11482
|
+
__export(daemon_exports, {
|
|
11483
|
+
startOrchestratorDaemon: () => startOrchestratorDaemon,
|
|
11484
|
+
subscribeToDaemonOutput: () => subscribeToDaemonOutput
|
|
11485
|
+
});
|
|
11486
|
+
function subscribeToDaemonOutput(sessionId, fn) {
|
|
11487
|
+
let set = listeners.get(sessionId);
|
|
11488
|
+
if (!set) {
|
|
11489
|
+
set = /* @__PURE__ */ new Set();
|
|
11490
|
+
listeners.set(sessionId, set);
|
|
11491
|
+
}
|
|
11492
|
+
set.add(fn);
|
|
11493
|
+
return () => {
|
|
11494
|
+
const s = listeners.get(sessionId);
|
|
11495
|
+
if (!s) return;
|
|
11496
|
+
s.delete(fn);
|
|
11497
|
+
if (s.size === 0) listeners.delete(sessionId);
|
|
11498
|
+
};
|
|
11499
|
+
}
|
|
11500
|
+
function broadcast(out) {
|
|
11501
|
+
const set = listeners.get(out.sessionId);
|
|
11502
|
+
if (!set) return;
|
|
11503
|
+
for (const fn of set) {
|
|
11504
|
+
try {
|
|
11505
|
+
fn(out);
|
|
11506
|
+
} catch (err) {
|
|
11507
|
+
console.error("[daemon] listener threw:", err?.message || err);
|
|
11508
|
+
}
|
|
11509
|
+
}
|
|
11510
|
+
}
|
|
11511
|
+
function startOrchestratorDaemon() {
|
|
11512
|
+
setFlushHandler(async (sessionId, events) => {
|
|
11513
|
+
await runDaemonTurn(sessionId, events);
|
|
11514
|
+
});
|
|
11515
|
+
}
|
|
11516
|
+
async function runDaemonTurn(sessionId, events) {
|
|
11517
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
11518
|
+
const session = await sessionQueries.getById(sessionId).catch(() => void 0);
|
|
11519
|
+
if (!session) {
|
|
11520
|
+
console.warn(`[daemon] flush for unknown session ${sessionId}; dropping ${events.length} event(s)`);
|
|
11521
|
+
return;
|
|
11522
|
+
}
|
|
11523
|
+
const prompt = events.map((e) => e.content).join("\n\n");
|
|
11524
|
+
let text = "";
|
|
11525
|
+
let error;
|
|
11526
|
+
await withSessionLock(sessionId, async () => {
|
|
11527
|
+
try {
|
|
11528
|
+
const agent = await Agent.create({ sessionId });
|
|
11529
|
+
const result = await agent.stream({ prompt });
|
|
11530
|
+
for await (const part of result.stream.fullStream) {
|
|
11531
|
+
if (part.type === "text-delta") text += part.text || "";
|
|
11532
|
+
}
|
|
11533
|
+
await result.saveResponseMessages();
|
|
11534
|
+
} catch (err) {
|
|
11535
|
+
error = err?.message || String(err);
|
|
11536
|
+
console.error(`[daemon] turn failed for ${sessionId}:`, error);
|
|
11537
|
+
}
|
|
11538
|
+
});
|
|
11539
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
11540
|
+
const trimmed = text.trim();
|
|
11541
|
+
broadcast({ sessionId, text: trimmed, triggeredBy: events, startedAt, finishedAt, error });
|
|
11542
|
+
}
|
|
11543
|
+
var listeners;
|
|
11544
|
+
var init_daemon = __esm({
|
|
11545
|
+
"src/orchestrator/daemon.ts"() {
|
|
11546
|
+
"use strict";
|
|
11547
|
+
init_agent();
|
|
11548
|
+
init_session_lock();
|
|
11549
|
+
init_db();
|
|
11550
|
+
init_inbox();
|
|
11551
|
+
listeners = /* @__PURE__ */ new Map();
|
|
11552
|
+
}
|
|
11553
|
+
});
|
|
11554
|
+
|
|
11408
11555
|
// src/tasks/boot-recovery.ts
|
|
11409
11556
|
var boot_recovery_exports = {};
|
|
11410
11557
|
__export(boot_recovery_exports, {
|
|
@@ -11492,81 +11639,6 @@ var init_ensure_orchestrator = __esm({
|
|
|
11492
11639
|
}
|
|
11493
11640
|
});
|
|
11494
11641
|
|
|
11495
|
-
// src/orchestrator/daemon.ts
|
|
11496
|
-
var daemon_exports = {};
|
|
11497
|
-
__export(daemon_exports, {
|
|
11498
|
-
startOrchestratorDaemon: () => startOrchestratorDaemon,
|
|
11499
|
-
subscribeToDaemonOutput: () => subscribeToDaemonOutput
|
|
11500
|
-
});
|
|
11501
|
-
function subscribeToDaemonOutput(sessionId, fn) {
|
|
11502
|
-
let set = listeners.get(sessionId);
|
|
11503
|
-
if (!set) {
|
|
11504
|
-
set = /* @__PURE__ */ new Set();
|
|
11505
|
-
listeners.set(sessionId, set);
|
|
11506
|
-
}
|
|
11507
|
-
set.add(fn);
|
|
11508
|
-
return () => {
|
|
11509
|
-
const s = listeners.get(sessionId);
|
|
11510
|
-
if (!s) return;
|
|
11511
|
-
s.delete(fn);
|
|
11512
|
-
if (s.size === 0) listeners.delete(sessionId);
|
|
11513
|
-
};
|
|
11514
|
-
}
|
|
11515
|
-
function broadcast(out) {
|
|
11516
|
-
const set = listeners.get(out.sessionId);
|
|
11517
|
-
if (!set) return;
|
|
11518
|
-
for (const fn of set) {
|
|
11519
|
-
try {
|
|
11520
|
-
fn(out);
|
|
11521
|
-
} catch (err) {
|
|
11522
|
-
console.error("[daemon] listener threw:", err?.message || err);
|
|
11523
|
-
}
|
|
11524
|
-
}
|
|
11525
|
-
}
|
|
11526
|
-
function startOrchestratorDaemon() {
|
|
11527
|
-
setFlushHandler(async (sessionId, events) => {
|
|
11528
|
-
await runDaemonTurn(sessionId, events);
|
|
11529
|
-
});
|
|
11530
|
-
}
|
|
11531
|
-
async function runDaemonTurn(sessionId, events) {
|
|
11532
|
-
const startedAt = /* @__PURE__ */ new Date();
|
|
11533
|
-
const session = await sessionQueries.getById(sessionId).catch(() => void 0);
|
|
11534
|
-
if (!session) {
|
|
11535
|
-
console.warn(`[daemon] flush for unknown session ${sessionId}; dropping ${events.length} event(s)`);
|
|
11536
|
-
return;
|
|
11537
|
-
}
|
|
11538
|
-
const prompt = events.map((e) => e.content).join("\n\n");
|
|
11539
|
-
let text = "";
|
|
11540
|
-
let error;
|
|
11541
|
-
await withSessionLock(sessionId, async () => {
|
|
11542
|
-
try {
|
|
11543
|
-
const agent = await Agent.create({ sessionId });
|
|
11544
|
-
const result = await agent.stream({ prompt });
|
|
11545
|
-
for await (const part of result.stream.fullStream) {
|
|
11546
|
-
if (part.type === "text-delta") text += part.text || "";
|
|
11547
|
-
}
|
|
11548
|
-
await result.saveResponseMessages();
|
|
11549
|
-
} catch (err) {
|
|
11550
|
-
error = err?.message || String(err);
|
|
11551
|
-
console.error(`[daemon] turn failed for ${sessionId}:`, error);
|
|
11552
|
-
}
|
|
11553
|
-
});
|
|
11554
|
-
const finishedAt = /* @__PURE__ */ new Date();
|
|
11555
|
-
const trimmed = text.trim();
|
|
11556
|
-
broadcast({ sessionId, text: trimmed, triggeredBy: events, startedAt, finishedAt, error });
|
|
11557
|
-
}
|
|
11558
|
-
var listeners;
|
|
11559
|
-
var init_daemon = __esm({
|
|
11560
|
-
"src/orchestrator/daemon.ts"() {
|
|
11561
|
-
"use strict";
|
|
11562
|
-
init_agent();
|
|
11563
|
-
init_session_lock();
|
|
11564
|
-
init_db();
|
|
11565
|
-
init_inbox();
|
|
11566
|
-
listeners = /* @__PURE__ */ new Map();
|
|
11567
|
-
}
|
|
11568
|
-
});
|
|
11569
|
-
|
|
11570
11642
|
// src/tasks/scheduler.ts
|
|
11571
11643
|
var scheduler_exports = {};
|
|
11572
11644
|
__export(scheduler_exports, {
|
|
@@ -11781,6 +11853,7 @@ function deriveAgentStatus(input) {
|
|
|
11781
11853
|
|
|
11782
11854
|
// src/server/routes/sessions.ts
|
|
11783
11855
|
init_pending_input();
|
|
11856
|
+
init_daemon();
|
|
11784
11857
|
|
|
11785
11858
|
// src/server/devtools-store.ts
|
|
11786
11859
|
var devtoolsContextStore = /* @__PURE__ */ new Map();
|
|
@@ -11923,6 +11996,63 @@ sessions2.post(
|
|
|
11923
11996
|
}, 201);
|
|
11924
11997
|
}
|
|
11925
11998
|
);
|
|
11999
|
+
sessions2.get("/:id/updates", async (c) => {
|
|
12000
|
+
const id = c.req.param("id");
|
|
12001
|
+
const session = await sessionQueries.getById(id);
|
|
12002
|
+
if (!session) return c.json({ error: "Session not found" }, 404);
|
|
12003
|
+
const stream = new ReadableStream({
|
|
12004
|
+
start(controller) {
|
|
12005
|
+
const encoder = new TextEncoder();
|
|
12006
|
+
const send = (data) => {
|
|
12007
|
+
try {
|
|
12008
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}
|
|
12009
|
+
|
|
12010
|
+
`));
|
|
12011
|
+
} catch {
|
|
12012
|
+
}
|
|
12013
|
+
};
|
|
12014
|
+
send({ type: "ready", sessionId: id });
|
|
12015
|
+
const unsubscribe = subscribeToDaemonOutput(id, (output) => {
|
|
12016
|
+
send({
|
|
12017
|
+
type: "turn-complete",
|
|
12018
|
+
sessionId: id,
|
|
12019
|
+
finishedAt: output.finishedAt.toISOString(),
|
|
12020
|
+
triggeredBy: output.triggeredBy.map((e) => e.content?.slice(0, 80)),
|
|
12021
|
+
error: output.error ?? null
|
|
12022
|
+
});
|
|
12023
|
+
});
|
|
12024
|
+
let cleaned = false;
|
|
12025
|
+
const cleanup2 = () => {
|
|
12026
|
+
if (cleaned) return;
|
|
12027
|
+
cleaned = true;
|
|
12028
|
+
clearInterval(keepalive);
|
|
12029
|
+
unsubscribe();
|
|
12030
|
+
try {
|
|
12031
|
+
controller.close();
|
|
12032
|
+
} catch {
|
|
12033
|
+
}
|
|
12034
|
+
};
|
|
12035
|
+
const keepalive = setInterval(() => {
|
|
12036
|
+
try {
|
|
12037
|
+
controller.enqueue(encoder.encode(`: keepalive
|
|
12038
|
+
|
|
12039
|
+
`));
|
|
12040
|
+
} catch {
|
|
12041
|
+
cleanup2();
|
|
12042
|
+
}
|
|
12043
|
+
}, 25e3);
|
|
12044
|
+
c.req.raw.signal?.addEventListener("abort", cleanup2);
|
|
12045
|
+
}
|
|
12046
|
+
});
|
|
12047
|
+
return new Response(stream, {
|
|
12048
|
+
headers: {
|
|
12049
|
+
"Content-Type": "text/event-stream",
|
|
12050
|
+
"Cache-Control": "no-cache",
|
|
12051
|
+
Connection: "keep-alive",
|
|
12052
|
+
"X-Accel-Buffering": "no"
|
|
12053
|
+
}
|
|
12054
|
+
});
|
|
12055
|
+
});
|
|
11926
12056
|
sessions2.get("/:id", async (c) => {
|
|
11927
12057
|
const id = c.req.param("id");
|
|
11928
12058
|
const session = await sessionQueries.getById(id);
|
|
@@ -14670,6 +14800,19 @@ function verifySlackSignature(opts) {
|
|
|
14670
14800
|
init_client3();
|
|
14671
14801
|
init_slack();
|
|
14672
14802
|
init_inbox();
|
|
14803
|
+
var recentlyHandled = /* @__PURE__ */ new Map();
|
|
14804
|
+
var MAX_RECENT = 1e3;
|
|
14805
|
+
function alreadyHandled(channel, ts) {
|
|
14806
|
+
if (!channel || !ts) return false;
|
|
14807
|
+
const key2 = `${channel}\u241F${ts}`;
|
|
14808
|
+
if (recentlyHandled.has(key2)) return true;
|
|
14809
|
+
recentlyHandled.set(key2, Date.now());
|
|
14810
|
+
if (recentlyHandled.size > MAX_RECENT) {
|
|
14811
|
+
const oldest = recentlyHandled.keys().next().value;
|
|
14812
|
+
if (oldest) recentlyHandled.delete(oldest);
|
|
14813
|
+
}
|
|
14814
|
+
return false;
|
|
14815
|
+
}
|
|
14673
14816
|
var slack = new Hono6();
|
|
14674
14817
|
slack.post("/events", async (c) => {
|
|
14675
14818
|
const signingSecret = getSlackSigningSecret();
|
|
@@ -14695,8 +14838,26 @@ slack.post("/events", async (c) => {
|
|
|
14695
14838
|
return c.json({ challenge: payload.challenge });
|
|
14696
14839
|
}
|
|
14697
14840
|
if (payload?.type === "event_callback" && payload?.event) {
|
|
14698
|
-
const
|
|
14841
|
+
const ev = payload.event;
|
|
14842
|
+
if (alreadyHandled(ev.channel, ev.ts)) {
|
|
14843
|
+
return c.json({ ok: true });
|
|
14844
|
+
}
|
|
14845
|
+
const { event: inbound, dropReason } = slackEventToInboundResult(ev);
|
|
14699
14846
|
if (inbound) {
|
|
14847
|
+
const isThreadReply = ev.type === "message" && ev.channel_type !== "im" && typeof ev.thread_ts === "string" && ev.thread_ts !== ev.ts;
|
|
14848
|
+
if (isThreadReply) {
|
|
14849
|
+
const ours = isThreadOwned(ev.channel, ev.thread_ts) || await threadBelongsToUs(ev.channel, ev.thread_ts);
|
|
14850
|
+
if (!ours) {
|
|
14851
|
+
console.log(`[slack] dropping thread reply in unknown thread: channel=${ev.channel} thread=${ev.thread_ts}`);
|
|
14852
|
+
return c.json({ ok: true });
|
|
14853
|
+
}
|
|
14854
|
+
}
|
|
14855
|
+
if (ev.type === "app_mention" && ev.channel && (ev.thread_ts || ev.ts)) {
|
|
14856
|
+
markThreadOwned(ev.channel, ev.thread_ts || ev.ts);
|
|
14857
|
+
}
|
|
14858
|
+
if (ev.type === "message" && ev.channel_type === "im" && ev.channel && (ev.thread_ts || ev.ts)) {
|
|
14859
|
+
markThreadOwned(ev.channel, ev.thread_ts || ev.ts);
|
|
14860
|
+
}
|
|
14700
14861
|
const orchestratorId = await findOrCreateOrchestratorId();
|
|
14701
14862
|
if (orchestratorId) {
|
|
14702
14863
|
pushToInbox(orchestratorId, inbound);
|
|
@@ -14713,6 +14874,18 @@ slack.post("/events", async (c) => {
|
|
|
14713
14874
|
}
|
|
14714
14875
|
return c.json({ ok: true });
|
|
14715
14876
|
});
|
|
14877
|
+
async function threadBelongsToUs(channel, threadTs) {
|
|
14878
|
+
try {
|
|
14879
|
+
const sessions3 = await sessionQueries.list(500, 0);
|
|
14880
|
+
return sessions3.some((s) => {
|
|
14881
|
+
const slack2 = s.config?.slack;
|
|
14882
|
+
return slack2?.channel === channel && slack2?.threadTs === threadTs;
|
|
14883
|
+
});
|
|
14884
|
+
} catch (err) {
|
|
14885
|
+
console.warn("[slack] threadBelongsToUs lookup failed:", err?.message ?? err);
|
|
14886
|
+
return false;
|
|
14887
|
+
}
|
|
14888
|
+
}
|
|
14716
14889
|
async function findOrCreateOrchestratorId() {
|
|
14717
14890
|
try {
|
|
14718
14891
|
const all = await sessionQueries.list(500, 0);
|