sparkecoder 0.1.126 → 0.1.127
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.js +52 -3
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +118 -17
- package/dist/cli.js.map +1 -1
- package/dist/index.js +118 -17
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +118 -17
- package/dist/server/index.js.map +1 -1
- package/dist/skills/default/slack-messaging.md +268 -0
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
- package/src/skills/default/slack-messaging.md +268 -0
- 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/_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.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- 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/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- 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.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- 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/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_ssgManifest.js +0 -0
- /package/web/.next/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_buildManifest.js +0 -0
- /package/web/.next/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{BSOUN7vf8epF685UYalET → l63ZK5juWEj8lzzuVVSpx}/_ssgManifest.js +0 -0
package/dist/server/index.js
CHANGED
|
@@ -4239,8 +4239,10 @@ async function loadAgentsMd(agentsMdPath) {
|
|
|
4239
4239
|
}
|
|
4240
4240
|
async function loadSkillContent(skillName, directories) {
|
|
4241
4241
|
const allSkills = await loadAllSkills(directories);
|
|
4242
|
+
const normalize2 = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
4243
|
+
const wanted = normalize2(skillName);
|
|
4242
4244
|
const skill = allSkills.find(
|
|
4243
|
-
(s) => s.name
|
|
4245
|
+
(s) => normalize2(s.name) === wanted || normalize2(basename(s.filePath, extname4(s.filePath))) === wanted
|
|
4244
4246
|
);
|
|
4245
4247
|
if (!skill) {
|
|
4246
4248
|
return null;
|
|
@@ -7038,7 +7040,7 @@ Every user-message you see is tagged at the front with a channel pill describing
|
|
|
7038
7040
|
Pill formats:
|
|
7039
7041
|
|
|
7040
7042
|
- \`[WEB] ...\` \u2014 typed in the web dashboard. Your assistant text streams back automatically. No tool call needed.
|
|
7041
|
-
- \`[SLACK channel=C0123 thread=1700000000.001 user=U0123] ...\` \u2014 a Slack mention or DM. To reply: \`messenger({action:'post', channel:'slack', to:'C0123', threadTs:'1700000000.001', text:'...'})\`. **Always set \`threadTs\`** so the reply lands in the same thread.
|
|
7043
|
+
- \`[SLACK channel=C0123 thread=1700000000.001 user=Ryan Trattner <@U0123> (ryan@example.com)] ...\` \u2014 a Slack mention or DM. To reply: \`messenger({action:'post', channel:'slack', to:'C0123', threadTs:'1700000000.001', text:'...'})\`. **Always set \`threadTs\`** so the reply lands in the same thread. The \`user=\` field is enriched in-place: when the bot has the right scopes you get \`<Name> <@U_ID> (email)\`; if scopes are missing you may see just the raw id \u2014 that's not an error, just less context. Any \`<@U\u2026>\` mentions inside the message text are similarly normalized to \`<Name> <@U_ID>\` so you can immediately tell who's being addressed.
|
|
7042
7044
|
- \`[SYSTEM worker.completed worker-name] ...\` \u2014 a worker you spawned finished. Look back at the conversation: where did the request originate?
|
|
7043
7045
|
- If the original request was \`[WEB]\`, a normal text reply is enough (the user is watching).
|
|
7044
7046
|
- If it was \`[SLACK ...]\`, post the result to that Slack thread via \`messenger\`.
|
|
@@ -7058,6 +7060,48 @@ If \`messenger({action:'post', ...})\` returns \`{ok:false, error:'...'}\` (e.g.
|
|
|
7058
7060
|
**Never silently swallow a delivery failure.**
|
|
7059
7061
|
</delivery_failures>
|
|
7060
7062
|
|
|
7063
|
+
<reaching_specific_people>
|
|
7064
|
+
|
|
7065
|
+
When a request needs a *specific human's attention* (e.g. "ask Ryan to review this", "let Sarah know the deploy is done", "wait for Charlie's OK before merging") \u2014 don't just reply into thin air, actually surface it to that person. Two mechanisms, in order of preference:
|
|
7066
|
+
|
|
7067
|
+
**1. @-ping them in a Slack channel they're already in (the cheap path)**
|
|
7068
|
+
|
|
7069
|
+
If you know the person's Slack user id and the conversation has a relevant channel/thread, include a literal mention token in the message text. Slack renders \`<@U0123>\` as a clickable @-mention and pushes a notification to that user.
|
|
7070
|
+
|
|
7071
|
+
\`\`\`
|
|
7072
|
+
messenger({
|
|
7073
|
+
action: 'post', channel: 'slack',
|
|
7074
|
+
to: 'C0B5CESSBGD', threadTs: '1700000000.001',
|
|
7075
|
+
text: '<@U05C6RWBDPC> heads up \u2014 the deploy hit a flaky test, can you check?'
|
|
7076
|
+
})
|
|
7077
|
+
\`\`\`
|
|
7078
|
+
|
|
7079
|
+
You already have the user id from inbound \`[SLACK ... user=U0123]\` pills. If multiple people are involved in a thread, you've seen their ids in the recent messages \u2014 use those. **The mention must be wrapped in \`<@...>\` \u2014 bare \`@username\` does NOT notify.**
|
|
7080
|
+
|
|
7081
|
+
**2. DM them directly (when channel context is missing OR you only know their email)**
|
|
7082
|
+
|
|
7083
|
+
For "DM Alice" / "shoot Bob a note" / pinging someone not in the current thread, use the **\`slack-messaging\` skill** \u2014 load it first with \`load_skill slack-messaging\`. It documents the lookup recipe (\`users.lookupByEmail\` \u2192 user id \u2192 \`messenger\` with the user id as \`to\`). Slack auto-opens the DM; no extra step.
|
|
7084
|
+
|
|
7085
|
+
Quick form (when you've already loaded the skill earlier in the turn): look up the user id by email via the Slack API, then \`messenger({action:'post', channel:'slack', to:'<U_ID>', text:'...'})\`. No \`threadTs\` for DMs \u2014 they're standalone.
|
|
7086
|
+
|
|
7087
|
+
**When to use which**
|
|
7088
|
+
|
|
7089
|
+
| Situation | Use |
|
|
7090
|
+
|---|---|
|
|
7091
|
+
| Inbound Slack thread + you know the user is in it | ping with \`<@U\u2026>\` in the existing thread |
|
|
7092
|
+
| Need them but they're not in this channel/thread | DM (skill) |
|
|
7093
|
+
| Have only their email, not their id | DM (skill \u2014 it looks up the id) |
|
|
7094
|
+
| Need a broadcast-style heads-up | ping in their team's channel |
|
|
7095
|
+
| Sensitive / 1:1 conversation | always DM, never ping in a shared channel |
|
|
7096
|
+
|
|
7097
|
+
**Don'ts**
|
|
7098
|
+
|
|
7099
|
+
- Don't @-mention everyone in a channel ("FYI" pings \u2014 leave that to humans).
|
|
7100
|
+
- Don't ping AND DM the same person for the same thing \u2014 pick one.
|
|
7101
|
+
- Don't fabricate user ids or emails. If you don't know how to reach them, ask the requester ("which Sarah?") instead of guessing.
|
|
7102
|
+
- Don't ping in a thread the person hasn't shown up in unless the asker explicitly named them \u2014 surprise pings are annoying.
|
|
7103
|
+
</reaching_specific_people>
|
|
7104
|
+
|
|
7061
7105
|
<hard_rules>
|
|
7062
7106
|
|
|
7063
7107
|
- Avoid direct workspace work. Do not directly edit product code, run builds, or perform substantive implementation yourself; spawn workers for that.
|
|
@@ -7978,7 +8022,12 @@ function load() {
|
|
|
7978
8022
|
const now = Date.now();
|
|
7979
8023
|
for (const [id, e] of Object.entries(parsed.users || {})) {
|
|
7980
8024
|
if (e && typeof e.expiresAt === "number" && e.expiresAt > now) {
|
|
7981
|
-
userMap.set(id, {
|
|
8025
|
+
userMap.set(id, {
|
|
8026
|
+
name: e.name ?? null,
|
|
8027
|
+
realName: e.realName ?? null,
|
|
8028
|
+
email: e.email ?? null,
|
|
8029
|
+
expiresAt: e.expiresAt
|
|
8030
|
+
});
|
|
7982
8031
|
}
|
|
7983
8032
|
}
|
|
7984
8033
|
for (const [key2, e] of Object.entries(parsed.threads || {})) {
|
|
@@ -8173,7 +8222,7 @@ function getSlackAllowlistPolicy() {
|
|
|
8173
8222
|
return { allowedUsers: [], allowedChannels: [], allowDmsFromAnyone: true };
|
|
8174
8223
|
}
|
|
8175
8224
|
}
|
|
8176
|
-
async function
|
|
8225
|
+
async function fetchSlackUserInfo(userId) {
|
|
8177
8226
|
const token = getSlackBotToken();
|
|
8178
8227
|
if (!token) return null;
|
|
8179
8228
|
try {
|
|
@@ -8187,31 +8236,45 @@ async function fetchSlackUserName(userId) {
|
|
|
8187
8236
|
}
|
|
8188
8237
|
const profile = data.user?.profile || {};
|
|
8189
8238
|
const name = profile.display_name_normalized || profile.display_name || profile.real_name_normalized || profile.real_name || data.user?.real_name || data.user?.name || null;
|
|
8190
|
-
|
|
8239
|
+
const realName = profile.real_name_normalized || profile.real_name || data.user?.real_name || null;
|
|
8240
|
+
const email = profile.email || null;
|
|
8241
|
+
return {
|
|
8242
|
+
name: name ? String(name) : null,
|
|
8243
|
+
realName: realName ? String(realName) : null,
|
|
8244
|
+
email: email ? String(email) : null
|
|
8245
|
+
};
|
|
8191
8246
|
} catch (err) {
|
|
8192
8247
|
console.warn(`[slack] users.info(${userId}) error:`, err?.message || err);
|
|
8193
8248
|
return null;
|
|
8194
8249
|
}
|
|
8195
8250
|
}
|
|
8196
|
-
async function
|
|
8251
|
+
async function resolveSlackUserInfo(userId) {
|
|
8197
8252
|
if (!userId) return null;
|
|
8198
8253
|
const now = Date.now();
|
|
8199
8254
|
const hit = getCachedUserName(userId);
|
|
8200
|
-
if (hit && hit.expiresAt > now)
|
|
8255
|
+
if (hit && hit.expiresAt > now) {
|
|
8256
|
+
return { name: hit.name, realName: hit.realName ?? null, email: hit.email ?? null };
|
|
8257
|
+
}
|
|
8201
8258
|
const inflight = userInflight.get(userId);
|
|
8202
8259
|
if (inflight) return inflight;
|
|
8203
8260
|
const p = (async () => {
|
|
8204
|
-
const
|
|
8261
|
+
const info = await fetchSlackUserInfo(userId);
|
|
8205
8262
|
setCachedUserName(userId, {
|
|
8206
|
-
name,
|
|
8207
|
-
|
|
8263
|
+
name: info?.name ?? null,
|
|
8264
|
+
realName: info?.realName ?? null,
|
|
8265
|
+
email: info?.email ?? null,
|
|
8266
|
+
expiresAt: now + (info?.name ? USER_TTL_MS : USER_FAIL_TTL_MS)
|
|
8208
8267
|
});
|
|
8209
8268
|
userInflight.delete(userId);
|
|
8210
|
-
return
|
|
8269
|
+
return info;
|
|
8211
8270
|
})();
|
|
8212
8271
|
userInflight.set(userId, p);
|
|
8213
8272
|
return p;
|
|
8214
8273
|
}
|
|
8274
|
+
async function resolveSlackUserName(userId) {
|
|
8275
|
+
const info = await resolveSlackUserInfo(userId);
|
|
8276
|
+
return info?.name ?? null;
|
|
8277
|
+
}
|
|
8215
8278
|
async function normalizeSlackMentions(text) {
|
|
8216
8279
|
if (!text) return text;
|
|
8217
8280
|
const userMentionRe = /<@([UW][A-Z0-9]+)(?:\|([^>]+))?>/g;
|
|
@@ -8444,6 +8507,13 @@ var init_slack = __esm({
|
|
|
8444
8507
|
});
|
|
8445
8508
|
|
|
8446
8509
|
// src/integrations/channels/system.ts
|
|
8510
|
+
var system_exports = {};
|
|
8511
|
+
__export(system_exports, {
|
|
8512
|
+
systemChannel: () => systemChannel,
|
|
8513
|
+
workerCompletedEvent: () => workerCompletedEvent,
|
|
8514
|
+
workerFailedEvent: () => workerFailedEvent,
|
|
8515
|
+
workerQuestionEvent: () => workerQuestionEvent
|
|
8516
|
+
});
|
|
8447
8517
|
function workerCompletedEvent(workerId, workerName, summary) {
|
|
8448
8518
|
const ref = { channel: "system", kind: "worker.completed", workerId, workerName };
|
|
8449
8519
|
return {
|
|
@@ -9431,6 +9501,14 @@ var init_pending_input = __esm({
|
|
|
9431
9501
|
});
|
|
9432
9502
|
|
|
9433
9503
|
// src/orchestrator/inbox.ts
|
|
9504
|
+
var inbox_exports = {};
|
|
9505
|
+
__export(inbox_exports, {
|
|
9506
|
+
clearInbox: () => clearInbox,
|
|
9507
|
+
flush: () => flush,
|
|
9508
|
+
peekInbox: () => peekInbox,
|
|
9509
|
+
pushToInbox: () => pushToInbox,
|
|
9510
|
+
setFlushHandler: () => setFlushHandler
|
|
9511
|
+
});
|
|
9434
9512
|
function setFlushHandler(fn) {
|
|
9435
9513
|
flushHandler = fn;
|
|
9436
9514
|
}
|
|
@@ -9476,6 +9554,18 @@ async function flush(sessionId) {
|
|
|
9476
9554
|
console.error("[orchestrator-inbox] flush handler threw:", err?.message || err);
|
|
9477
9555
|
}
|
|
9478
9556
|
}
|
|
9557
|
+
function peekInbox(sessionId) {
|
|
9558
|
+
return inboxes.get(sessionId)?.pending.slice() ?? [];
|
|
9559
|
+
}
|
|
9560
|
+
function clearInbox(sessionId) {
|
|
9561
|
+
const e = inboxes.get(sessionId);
|
|
9562
|
+
if (!e) return;
|
|
9563
|
+
if (e.timer) {
|
|
9564
|
+
clearTimeout(e.timer);
|
|
9565
|
+
e.timer = void 0;
|
|
9566
|
+
}
|
|
9567
|
+
e.pending.length = 0;
|
|
9568
|
+
}
|
|
9479
9569
|
var inboxes, FLUSH_DEBOUNCE_MS, flushHandler;
|
|
9480
9570
|
var init_inbox = __esm({
|
|
9481
9571
|
"src/orchestrator/inbox.ts"() {
|
|
@@ -14119,6 +14209,18 @@ tasks.post(
|
|
|
14119
14209
|
data: { status: "failed", error: errorMsg }
|
|
14120
14210
|
});
|
|
14121
14211
|
}
|
|
14212
|
+
if (body.orchestratorSessionId) {
|
|
14213
|
+
try {
|
|
14214
|
+
const { pushToInbox: pushToInbox2 } = await Promise.resolve().then(() => (init_inbox(), inbox_exports));
|
|
14215
|
+
const { workerFailedEvent: workerFailedEvent2 } = await Promise.resolve().then(() => (init_system(), system_exports));
|
|
14216
|
+
pushToInbox2(
|
|
14217
|
+
body.orchestratorSessionId,
|
|
14218
|
+
workerFailedEvent2(taskId, body.name || "worker", `(uncaught) ${errorMsg}`)
|
|
14219
|
+
);
|
|
14220
|
+
} catch (notifyErr) {
|
|
14221
|
+
console.error(`[TASK] failed to notify orchestrator of crash:`, notifyErr?.message || notifyErr);
|
|
14222
|
+
}
|
|
14223
|
+
}
|
|
14122
14224
|
}
|
|
14123
14225
|
} finally {
|
|
14124
14226
|
await writeSSE("[DONE]");
|
|
@@ -14368,12 +14470,11 @@ slack.post("/events", async (c) => {
|
|
|
14368
14470
|
if (orchestratorId) {
|
|
14369
14471
|
inbound.content = await normalizeSlackMentions(inbound.content);
|
|
14370
14472
|
if (ev.user) {
|
|
14371
|
-
const
|
|
14372
|
-
if (
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
);
|
|
14473
|
+
const info = await resolveSlackUserInfo(ev.user);
|
|
14474
|
+
if (info?.name) {
|
|
14475
|
+
const emailSuffix = info.email ? ` (${info.email})` : "";
|
|
14476
|
+
const enriched = `user=${info.name} <@${ev.user}>${emailSuffix}`;
|
|
14477
|
+
inbound.content = inbound.content.replace(`user=${ev.user}`, () => enriched);
|
|
14377
14478
|
}
|
|
14378
14479
|
}
|
|
14379
14480
|
pushToInbox(orchestratorId, inbound);
|