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/index.js
CHANGED
|
@@ -4256,8 +4256,10 @@ async function loadAgentsMd(agentsMdPath) {
|
|
|
4256
4256
|
}
|
|
4257
4257
|
async function loadSkillContent(skillName, directories) {
|
|
4258
4258
|
const allSkills = await loadAllSkills(directories);
|
|
4259
|
+
const normalize2 = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
4260
|
+
const wanted = normalize2(skillName);
|
|
4259
4261
|
const skill = allSkills.find(
|
|
4260
|
-
(s) => s.name
|
|
4262
|
+
(s) => normalize2(s.name) === wanted || normalize2(basename(s.filePath, extname4(s.filePath))) === wanted
|
|
4261
4263
|
);
|
|
4262
4264
|
if (!skill) {
|
|
4263
4265
|
return null;
|
|
@@ -7055,7 +7057,7 @@ Every user-message you see is tagged at the front with a channel pill describing
|
|
|
7055
7057
|
Pill formats:
|
|
7056
7058
|
|
|
7057
7059
|
- \`[WEB] ...\` \u2014 typed in the web dashboard. Your assistant text streams back automatically. No tool call needed.
|
|
7058
|
-
- \`[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.
|
|
7060
|
+
- \`[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.
|
|
7059
7061
|
- \`[SYSTEM worker.completed worker-name] ...\` \u2014 a worker you spawned finished. Look back at the conversation: where did the request originate?
|
|
7060
7062
|
- If the original request was \`[WEB]\`, a normal text reply is enough (the user is watching).
|
|
7061
7063
|
- If it was \`[SLACK ...]\`, post the result to that Slack thread via \`messenger\`.
|
|
@@ -7075,6 +7077,48 @@ If \`messenger({action:'post', ...})\` returns \`{ok:false, error:'...'}\` (e.g.
|
|
|
7075
7077
|
**Never silently swallow a delivery failure.**
|
|
7076
7078
|
</delivery_failures>
|
|
7077
7079
|
|
|
7080
|
+
<reaching_specific_people>
|
|
7081
|
+
|
|
7082
|
+
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:
|
|
7083
|
+
|
|
7084
|
+
**1. @-ping them in a Slack channel they're already in (the cheap path)**
|
|
7085
|
+
|
|
7086
|
+
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.
|
|
7087
|
+
|
|
7088
|
+
\`\`\`
|
|
7089
|
+
messenger({
|
|
7090
|
+
action: 'post', channel: 'slack',
|
|
7091
|
+
to: 'C0B5CESSBGD', threadTs: '1700000000.001',
|
|
7092
|
+
text: '<@U05C6RWBDPC> heads up \u2014 the deploy hit a flaky test, can you check?'
|
|
7093
|
+
})
|
|
7094
|
+
\`\`\`
|
|
7095
|
+
|
|
7096
|
+
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.**
|
|
7097
|
+
|
|
7098
|
+
**2. DM them directly (when channel context is missing OR you only know their email)**
|
|
7099
|
+
|
|
7100
|
+
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.
|
|
7101
|
+
|
|
7102
|
+
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.
|
|
7103
|
+
|
|
7104
|
+
**When to use which**
|
|
7105
|
+
|
|
7106
|
+
| Situation | Use |
|
|
7107
|
+
|---|---|
|
|
7108
|
+
| Inbound Slack thread + you know the user is in it | ping with \`<@U\u2026>\` in the existing thread |
|
|
7109
|
+
| Need them but they're not in this channel/thread | DM (skill) |
|
|
7110
|
+
| Have only their email, not their id | DM (skill \u2014 it looks up the id) |
|
|
7111
|
+
| Need a broadcast-style heads-up | ping in their team's channel |
|
|
7112
|
+
| Sensitive / 1:1 conversation | always DM, never ping in a shared channel |
|
|
7113
|
+
|
|
7114
|
+
**Don'ts**
|
|
7115
|
+
|
|
7116
|
+
- Don't @-mention everyone in a channel ("FYI" pings \u2014 leave that to humans).
|
|
7117
|
+
- Don't ping AND DM the same person for the same thing \u2014 pick one.
|
|
7118
|
+
- Don't fabricate user ids or emails. If you don't know how to reach them, ask the requester ("which Sarah?") instead of guessing.
|
|
7119
|
+
- Don't ping in a thread the person hasn't shown up in unless the asker explicitly named them \u2014 surprise pings are annoying.
|
|
7120
|
+
</reaching_specific_people>
|
|
7121
|
+
|
|
7078
7122
|
<hard_rules>
|
|
7079
7123
|
|
|
7080
7124
|
- Avoid direct workspace work. Do not directly edit product code, run builds, or perform substantive implementation yourself; spawn workers for that.
|
|
@@ -7995,7 +8039,12 @@ function load() {
|
|
|
7995
8039
|
const now = Date.now();
|
|
7996
8040
|
for (const [id, e] of Object.entries(parsed.users || {})) {
|
|
7997
8041
|
if (e && typeof e.expiresAt === "number" && e.expiresAt > now) {
|
|
7998
|
-
userMap.set(id, {
|
|
8042
|
+
userMap.set(id, {
|
|
8043
|
+
name: e.name ?? null,
|
|
8044
|
+
realName: e.realName ?? null,
|
|
8045
|
+
email: e.email ?? null,
|
|
8046
|
+
expiresAt: e.expiresAt
|
|
8047
|
+
});
|
|
7999
8048
|
}
|
|
8000
8049
|
}
|
|
8001
8050
|
for (const [key2, e] of Object.entries(parsed.threads || {})) {
|
|
@@ -8190,7 +8239,7 @@ function getSlackAllowlistPolicy() {
|
|
|
8190
8239
|
return { allowedUsers: [], allowedChannels: [], allowDmsFromAnyone: true };
|
|
8191
8240
|
}
|
|
8192
8241
|
}
|
|
8193
|
-
async function
|
|
8242
|
+
async function fetchSlackUserInfo(userId) {
|
|
8194
8243
|
const token = getSlackBotToken();
|
|
8195
8244
|
if (!token) return null;
|
|
8196
8245
|
try {
|
|
@@ -8204,31 +8253,45 @@ async function fetchSlackUserName(userId) {
|
|
|
8204
8253
|
}
|
|
8205
8254
|
const profile = data.user?.profile || {};
|
|
8206
8255
|
const name = profile.display_name_normalized || profile.display_name || profile.real_name_normalized || profile.real_name || data.user?.real_name || data.user?.name || null;
|
|
8207
|
-
|
|
8256
|
+
const realName = profile.real_name_normalized || profile.real_name || data.user?.real_name || null;
|
|
8257
|
+
const email = profile.email || null;
|
|
8258
|
+
return {
|
|
8259
|
+
name: name ? String(name) : null,
|
|
8260
|
+
realName: realName ? String(realName) : null,
|
|
8261
|
+
email: email ? String(email) : null
|
|
8262
|
+
};
|
|
8208
8263
|
} catch (err) {
|
|
8209
8264
|
console.warn(`[slack] users.info(${userId}) error:`, err?.message || err);
|
|
8210
8265
|
return null;
|
|
8211
8266
|
}
|
|
8212
8267
|
}
|
|
8213
|
-
async function
|
|
8268
|
+
async function resolveSlackUserInfo(userId) {
|
|
8214
8269
|
if (!userId) return null;
|
|
8215
8270
|
const now = Date.now();
|
|
8216
8271
|
const hit = getCachedUserName(userId);
|
|
8217
|
-
if (hit && hit.expiresAt > now)
|
|
8272
|
+
if (hit && hit.expiresAt > now) {
|
|
8273
|
+
return { name: hit.name, realName: hit.realName ?? null, email: hit.email ?? null };
|
|
8274
|
+
}
|
|
8218
8275
|
const inflight = userInflight.get(userId);
|
|
8219
8276
|
if (inflight) return inflight;
|
|
8220
8277
|
const p = (async () => {
|
|
8221
|
-
const
|
|
8278
|
+
const info = await fetchSlackUserInfo(userId);
|
|
8222
8279
|
setCachedUserName(userId, {
|
|
8223
|
-
name,
|
|
8224
|
-
|
|
8280
|
+
name: info?.name ?? null,
|
|
8281
|
+
realName: info?.realName ?? null,
|
|
8282
|
+
email: info?.email ?? null,
|
|
8283
|
+
expiresAt: now + (info?.name ? USER_TTL_MS : USER_FAIL_TTL_MS)
|
|
8225
8284
|
});
|
|
8226
8285
|
userInflight.delete(userId);
|
|
8227
|
-
return
|
|
8286
|
+
return info;
|
|
8228
8287
|
})();
|
|
8229
8288
|
userInflight.set(userId, p);
|
|
8230
8289
|
return p;
|
|
8231
8290
|
}
|
|
8291
|
+
async function resolveSlackUserName(userId) {
|
|
8292
|
+
const info = await resolveSlackUserInfo(userId);
|
|
8293
|
+
return info?.name ?? null;
|
|
8294
|
+
}
|
|
8232
8295
|
async function normalizeSlackMentions(text) {
|
|
8233
8296
|
if (!text) return text;
|
|
8234
8297
|
const userMentionRe = /<@([UW][A-Z0-9]+)(?:\|([^>]+))?>/g;
|
|
@@ -8461,6 +8524,13 @@ var init_slack = __esm({
|
|
|
8461
8524
|
});
|
|
8462
8525
|
|
|
8463
8526
|
// src/integrations/channels/system.ts
|
|
8527
|
+
var system_exports = {};
|
|
8528
|
+
__export(system_exports, {
|
|
8529
|
+
systemChannel: () => systemChannel,
|
|
8530
|
+
workerCompletedEvent: () => workerCompletedEvent,
|
|
8531
|
+
workerFailedEvent: () => workerFailedEvent,
|
|
8532
|
+
workerQuestionEvent: () => workerQuestionEvent
|
|
8533
|
+
});
|
|
8464
8534
|
function workerCompletedEvent(workerId, workerName, summary) {
|
|
8465
8535
|
const ref = { channel: "system", kind: "worker.completed", workerId, workerName };
|
|
8466
8536
|
return {
|
|
@@ -9448,6 +9518,14 @@ var init_pending_input = __esm({
|
|
|
9448
9518
|
});
|
|
9449
9519
|
|
|
9450
9520
|
// src/orchestrator/inbox.ts
|
|
9521
|
+
var inbox_exports = {};
|
|
9522
|
+
__export(inbox_exports, {
|
|
9523
|
+
clearInbox: () => clearInbox,
|
|
9524
|
+
flush: () => flush,
|
|
9525
|
+
peekInbox: () => peekInbox,
|
|
9526
|
+
pushToInbox: () => pushToInbox,
|
|
9527
|
+
setFlushHandler: () => setFlushHandler
|
|
9528
|
+
});
|
|
9451
9529
|
function setFlushHandler(fn) {
|
|
9452
9530
|
flushHandler = fn;
|
|
9453
9531
|
}
|
|
@@ -9493,6 +9571,18 @@ async function flush(sessionId) {
|
|
|
9493
9571
|
console.error("[orchestrator-inbox] flush handler threw:", err?.message || err);
|
|
9494
9572
|
}
|
|
9495
9573
|
}
|
|
9574
|
+
function peekInbox(sessionId) {
|
|
9575
|
+
return inboxes.get(sessionId)?.pending.slice() ?? [];
|
|
9576
|
+
}
|
|
9577
|
+
function clearInbox(sessionId) {
|
|
9578
|
+
const e = inboxes.get(sessionId);
|
|
9579
|
+
if (!e) return;
|
|
9580
|
+
if (e.timer) {
|
|
9581
|
+
clearTimeout(e.timer);
|
|
9582
|
+
e.timer = void 0;
|
|
9583
|
+
}
|
|
9584
|
+
e.pending.length = 0;
|
|
9585
|
+
}
|
|
9496
9586
|
var inboxes, FLUSH_DEBOUNCE_MS, flushHandler;
|
|
9497
9587
|
var init_inbox = __esm({
|
|
9498
9588
|
"src/orchestrator/inbox.ts"() {
|
|
@@ -14139,6 +14229,18 @@ tasks.post(
|
|
|
14139
14229
|
data: { status: "failed", error: errorMsg }
|
|
14140
14230
|
});
|
|
14141
14231
|
}
|
|
14232
|
+
if (body.orchestratorSessionId) {
|
|
14233
|
+
try {
|
|
14234
|
+
const { pushToInbox: pushToInbox2 } = await Promise.resolve().then(() => (init_inbox(), inbox_exports));
|
|
14235
|
+
const { workerFailedEvent: workerFailedEvent2 } = await Promise.resolve().then(() => (init_system(), system_exports));
|
|
14236
|
+
pushToInbox2(
|
|
14237
|
+
body.orchestratorSessionId,
|
|
14238
|
+
workerFailedEvent2(taskId, body.name || "worker", `(uncaught) ${errorMsg}`)
|
|
14239
|
+
);
|
|
14240
|
+
} catch (notifyErr) {
|
|
14241
|
+
console.error(`[TASK] failed to notify orchestrator of crash:`, notifyErr?.message || notifyErr);
|
|
14242
|
+
}
|
|
14243
|
+
}
|
|
14142
14244
|
}
|
|
14143
14245
|
} finally {
|
|
14144
14246
|
await writeSSE("[DONE]");
|
|
@@ -14388,12 +14490,11 @@ slack.post("/events", async (c) => {
|
|
|
14388
14490
|
if (orchestratorId) {
|
|
14389
14491
|
inbound.content = await normalizeSlackMentions(inbound.content);
|
|
14390
14492
|
if (ev.user) {
|
|
14391
|
-
const
|
|
14392
|
-
if (
|
|
14393
|
-
|
|
14394
|
-
|
|
14395
|
-
|
|
14396
|
-
);
|
|
14493
|
+
const info = await resolveSlackUserInfo(ev.user);
|
|
14494
|
+
if (info?.name) {
|
|
14495
|
+
const emailSuffix = info.email ? ` (${info.email})` : "";
|
|
14496
|
+
const enriched = `user=${info.name} <@${ev.user}>${emailSuffix}`;
|
|
14497
|
+
inbound.content = inbound.content.replace(`user=${ev.user}`, () => enriched);
|
|
14397
14498
|
}
|
|
14398
14499
|
}
|
|
14399
14500
|
pushToInbox(orchestratorId, inbound);
|