@sideboard-ai/core 0.1.135 → 0.1.136
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/{agents-O3AJMI2Y.js → agents-ELWR7A2T.js} +3 -3
- package/dist/{agents-RTQFF7PY.js → agents-QNTTLMG2.js} +3 -3
- package/dist/{chunk-RDULVW3E.js → chunk-4XKUHP6G.js} +1 -1
- package/dist/{chunk-N62K3KXX.js → chunk-CYM5DCHI.js} +38 -4
- package/dist/{chunk-XUEI4GCF.js → chunk-GSKRGF7B.js} +284 -3
- package/dist/{chunk-57GIFU3X.js → chunk-IFZ4MOTN.js} +2 -2
- package/dist/{chunk-KBBXNS2V.js → chunk-JPBRMUM6.js} +8 -4
- package/dist/{chunk-2ESCEK2Q.js → chunk-K5YT5GX2.js} +242 -3
- package/dist/{chunk-LOKXPQ4U.js → chunk-MDCKV2NF.js} +1 -1
- package/dist/{chunk-XIKEUCNC.js → chunk-TIGKDMIA.js} +139 -266
- package/dist/{chunk-K7EX47QG.js → chunk-TQ4S5AGJ.js} +2 -2
- package/dist/{chunk-Z5LYMW7M.js → chunk-WS5LFFU3.js} +135 -217
- package/dist/{coordinator-prompt-Y737IIFR.js → coordinator-prompt-2OWSUAUR.js} +1 -1
- package/dist/{coordinator-prompt-FYMWE33S.js → coordinator-prompt-IPL4Z6SL.js} +1 -1
- package/dist/{global-workspace-6KH6BSKL.js → global-workspace-JDUCUL7S.js} +2 -2
- package/dist/{global-workspace-ZFKNLBZA.js → global-workspace-NIKZAKOO.js} +2 -2
- package/dist/index.cjs +828 -615
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +38 -17
- package/dist/mcp/run-stdio.cjs +657 -485
- package/dist/mcp/run-stdio.js +20 -9
- package/dist/{orchestrator-3YDPPZHZ.js → orchestrator-6I47JMU2.js} +5 -5
- package/dist/{orchestrator-2BRAPJ47.js → orchestrator-KK3CUW37.js} +5 -5
- package/dist/{workspaces-3RRF3LVF.js → workspaces-5EWNNALF.js} +3 -3
- package/dist/{workspaces-AYI5DHK4.js → workspaces-KZA3TCEE.js} +3 -3
- package/package.json +1 -1
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
ensureGlobalCoordinatorCwd
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TQ4S5AGJ.js";
|
|
6
6
|
import {
|
|
7
7
|
allocateTeamName,
|
|
8
8
|
takenSlugsFromThread,
|
|
9
9
|
teamSlugFromName
|
|
10
10
|
} from "./chunk-QAV3HGVS.js";
|
|
11
|
+
import {
|
|
12
|
+
ATTACHMENTS_DIR,
|
|
13
|
+
attachmentsGitignoreBody
|
|
14
|
+
} from "./chunk-B3SJXYIJ.js";
|
|
11
15
|
import {
|
|
12
16
|
createEmptyThread,
|
|
13
17
|
listThreads,
|
|
@@ -44,6 +48,233 @@ var CLOUD_COORDINATOR_TIMEOUT_REPLY = [
|
|
|
44
48
|
"What do you want me to do? (retry later, wait, force-stop, rephrase, or cancel)"
|
|
45
49
|
].join(" ");
|
|
46
50
|
|
|
51
|
+
// src/composer/stage-files.ts
|
|
52
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
53
|
+
import { basename, extname, join } from "path";
|
|
54
|
+
import { randomUUID } from "crypto";
|
|
55
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
56
|
+
"png",
|
|
57
|
+
"jpg",
|
|
58
|
+
"jpeg",
|
|
59
|
+
"gif",
|
|
60
|
+
"webp",
|
|
61
|
+
"svg",
|
|
62
|
+
"bmp",
|
|
63
|
+
"ico"
|
|
64
|
+
]);
|
|
65
|
+
var IMAGE_MIME_BY_EXT = {
|
|
66
|
+
png: "image/png",
|
|
67
|
+
jpg: "image/jpeg",
|
|
68
|
+
jpeg: "image/jpeg",
|
|
69
|
+
gif: "image/gif",
|
|
70
|
+
webp: "image/webp",
|
|
71
|
+
svg: "image/svg+xml",
|
|
72
|
+
bmp: "image/bmp",
|
|
73
|
+
ico: "image/x-icon"
|
|
74
|
+
};
|
|
75
|
+
var MAX_INLINE_BYTES = 4e5;
|
|
76
|
+
var MAX_PREVIEW_BYTES = 5e6;
|
|
77
|
+
function fileExtension(filePath) {
|
|
78
|
+
const base = basename(filePath).toLowerCase();
|
|
79
|
+
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
80
|
+
}
|
|
81
|
+
function isImageFilePath(filePath) {
|
|
82
|
+
return IMAGE_EXTENSIONS.has(fileExtension(filePath));
|
|
83
|
+
}
|
|
84
|
+
function imageMimeType(filePath) {
|
|
85
|
+
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
86
|
+
}
|
|
87
|
+
function ensureAttachmentsDir(worktreePath) {
|
|
88
|
+
const dir = join(worktreePath, ATTACHMENTS_DIR);
|
|
89
|
+
mkdirSync(dir, { recursive: true });
|
|
90
|
+
const gi = join(dir, ".gitignore");
|
|
91
|
+
if (!existsSync(gi)) {
|
|
92
|
+
writeFileSync(gi, attachmentsGitignoreBody(), "utf8");
|
|
93
|
+
}
|
|
94
|
+
return dir;
|
|
95
|
+
}
|
|
96
|
+
function uniqueAttachmentName(dir, originalName) {
|
|
97
|
+
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
98
|
+
if (!existsSync(join(dir, safe))) return safe;
|
|
99
|
+
const ext = extname(safe);
|
|
100
|
+
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
101
|
+
for (let i = 1; i < 1e4; i++) {
|
|
102
|
+
const candidate = `${stem}-${i}${ext}`;
|
|
103
|
+
if (!existsSync(join(dir, candidate))) return candidate;
|
|
104
|
+
}
|
|
105
|
+
return `${stem}-${randomUUID()}${ext}`;
|
|
106
|
+
}
|
|
107
|
+
function previewDataUrlFromBuf(filePath, buf) {
|
|
108
|
+
if (!isImageFilePath(filePath)) return void 0;
|
|
109
|
+
if (buf.length > MAX_PREVIEW_BYTES) return void 0;
|
|
110
|
+
return `data:${imageMimeType(filePath)};base64,${buf.toString("base64")}`;
|
|
111
|
+
}
|
|
112
|
+
function attachmentFromBuffer(name, buf, opts) {
|
|
113
|
+
const previewDataUrl = previewDataUrlFromBuf(name, buf);
|
|
114
|
+
if (isImageFilePath(name)) {
|
|
115
|
+
const pathHint = opts.path ? `\`${opts.path}\`` : opts.sourceLabel || name;
|
|
116
|
+
return {
|
|
117
|
+
id: randomUUID(),
|
|
118
|
+
name,
|
|
119
|
+
kind: "file",
|
|
120
|
+
path: opts.path,
|
|
121
|
+
previewDataUrl,
|
|
122
|
+
content: [
|
|
123
|
+
`Image attached: ${pathHint}`,
|
|
124
|
+
opts.path ? `Use the Read tool on \`${opts.path}\` to view this image.` : "The image is shown in the composer; copy it into the worktree if you need to inspect pixels."
|
|
125
|
+
].join("\n")
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (buf.length > MAX_INLINE_BYTES) {
|
|
129
|
+
return {
|
|
130
|
+
id: randomUUID(),
|
|
131
|
+
name,
|
|
132
|
+
kind: "file",
|
|
133
|
+
path: opts.path,
|
|
134
|
+
content: opts.path ? `(file too large to attach inline: \`${opts.path}\`, ${buf.length} bytes \u2014 use the Read tool)` : `(file too large to attach inline: ${opts.sourceLabel || name}, ${buf.length} bytes)`
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (buf.includes(0)) {
|
|
138
|
+
return {
|
|
139
|
+
id: randomUUID(),
|
|
140
|
+
name,
|
|
141
|
+
kind: "file",
|
|
142
|
+
path: opts.path,
|
|
143
|
+
content: opts.path ? `(binary file at \`${opts.path}\` \u2014 use tools to inspect)` : `(binary file attached by path only: ${opts.sourceLabel || name})`
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
id: randomUUID(),
|
|
148
|
+
name,
|
|
149
|
+
kind: "file",
|
|
150
|
+
path: opts.path,
|
|
151
|
+
content: buf.toString("utf8")
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
155
|
+
if (absolutePaths.length === 0) return [];
|
|
156
|
+
const dir = ensureAttachmentsDir(worktreePath);
|
|
157
|
+
const out = [];
|
|
158
|
+
for (const abs of absolutePaths) {
|
|
159
|
+
const originalName = basename(abs);
|
|
160
|
+
try {
|
|
161
|
+
const st = statSync(abs);
|
|
162
|
+
if (!st.isFile()) continue;
|
|
163
|
+
const name = uniqueAttachmentName(dir, originalName);
|
|
164
|
+
const destAbs = join(dir, name);
|
|
165
|
+
copyFileSync(abs, destAbs);
|
|
166
|
+
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
167
|
+
const buf = readFileSync(destAbs);
|
|
168
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
169
|
+
} catch (err) {
|
|
170
|
+
out.push({
|
|
171
|
+
id: randomUUID(),
|
|
172
|
+
name: originalName,
|
|
173
|
+
kind: "file",
|
|
174
|
+
content: `(could not attach ${abs}: ${err instanceof Error ? err.message : String(err)})`
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
181
|
+
if (buffers.length === 0) return [];
|
|
182
|
+
const dir = ensureAttachmentsDir(worktreePath);
|
|
183
|
+
const out = [];
|
|
184
|
+
for (const item of buffers) {
|
|
185
|
+
const originalName = (item.name || "file").replace(/[/\\]/g, "_") || "file";
|
|
186
|
+
try {
|
|
187
|
+
const buf = Buffer.from(item.dataBase64, "base64");
|
|
188
|
+
const name = uniqueAttachmentName(dir, originalName);
|
|
189
|
+
const destAbs = join(dir, name);
|
|
190
|
+
writeFileSync(destAbs, buf);
|
|
191
|
+
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
192
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
193
|
+
} catch (err) {
|
|
194
|
+
out.push({
|
|
195
|
+
id: randomUUID(),
|
|
196
|
+
name: originalName,
|
|
197
|
+
kind: "file",
|
|
198
|
+
content: `(could not attach ${originalName}: ${err instanceof Error ? err.message : String(err)})`
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
function isWorktreeRelativePath(p) {
|
|
205
|
+
if (!p || p.includes("..")) return false;
|
|
206
|
+
if (p.startsWith("/")) return false;
|
|
207
|
+
if (/^[A-Za-z]:[\\/]/.test(p)) return false;
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
function dataUrlToBase64(url) {
|
|
211
|
+
if (!url) return null;
|
|
212
|
+
const m = /^data:[^;]+;base64,(.+)$/s.exec(url);
|
|
213
|
+
return m?.[1] ?? null;
|
|
214
|
+
}
|
|
215
|
+
var IMAGE_HINT_RE = /^Image attached:/;
|
|
216
|
+
var PLACEHOLDER_CONTENT_RE = /^\((could not |file too large|binary file|not a file|invalid path)/;
|
|
217
|
+
function persistPendingFileAttachments(worktreePath, attachments) {
|
|
218
|
+
if (attachments.length === 0) return attachments;
|
|
219
|
+
const keep = [];
|
|
220
|
+
const buffers = [];
|
|
221
|
+
for (const att of attachments) {
|
|
222
|
+
if (att.kind !== "file") {
|
|
223
|
+
keep.push(att);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (att.path && isWorktreeRelativePath(att.path)) {
|
|
227
|
+
keep.push(att);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const fromPreview = dataUrlToBase64(att.previewDataUrl);
|
|
231
|
+
if (fromPreview) {
|
|
232
|
+
buffers.push({ name: att.name, dataBase64: fromPreview });
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (att.content && !IMAGE_HINT_RE.test(att.content) && !PLACEHOLDER_CONTENT_RE.test(att.content)) {
|
|
236
|
+
buffers.push({
|
|
237
|
+
name: att.name,
|
|
238
|
+
dataBase64: Buffer.from(att.content, "utf8").toString("base64")
|
|
239
|
+
});
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
keep.push(att);
|
|
243
|
+
}
|
|
244
|
+
if (buffers.length === 0) return attachments;
|
|
245
|
+
return [...keep, ...stageBuffersAsAttachments(worktreePath, buffers)];
|
|
246
|
+
}
|
|
247
|
+
function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
248
|
+
const out = [];
|
|
249
|
+
for (const rel of relativePaths) {
|
|
250
|
+
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
251
|
+
out.push({
|
|
252
|
+
id: randomUUID(),
|
|
253
|
+
name: basename(rel) || "file",
|
|
254
|
+
kind: "file",
|
|
255
|
+
content: `(invalid path: ${rel})`
|
|
256
|
+
});
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const name = basename(rel);
|
|
260
|
+
try {
|
|
261
|
+
const abs = join(worktreePath, rel);
|
|
262
|
+
const st = statSync(abs);
|
|
263
|
+
if (!st.isFile()) continue;
|
|
264
|
+
const buf = readFileSync(abs);
|
|
265
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
266
|
+
} catch (err) {
|
|
267
|
+
out.push({
|
|
268
|
+
id: randomUUID(),
|
|
269
|
+
name,
|
|
270
|
+
kind: "file",
|
|
271
|
+
content: `(could not read ${rel}: ${err instanceof Error ? err.message : String(err)})`
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return out;
|
|
276
|
+
}
|
|
277
|
+
|
|
47
278
|
// src/agents/orchestrator-capable.ts
|
|
48
279
|
var ORCHESTRATOR_AGENT_KINDS = [
|
|
49
280
|
"claude",
|
|
@@ -139,6 +370,7 @@ function createGlobalChat(opts) {
|
|
|
139
370
|
fast: opts.fast
|
|
140
371
|
});
|
|
141
372
|
const agent = assertOrchestratorCapableAgent(resolved.agent);
|
|
373
|
+
const worktreePath = globalAgentCwd();
|
|
142
374
|
const thread = createEmptyThread({
|
|
143
375
|
title,
|
|
144
376
|
// Stick nicknames the same way chat tabs do (avoid later sync overwrites).
|
|
@@ -146,7 +378,7 @@ function createGlobalChat(opts) {
|
|
|
146
378
|
sourceType: "orchestration",
|
|
147
379
|
sourceRef,
|
|
148
380
|
branchName: "global",
|
|
149
|
-
worktreePath
|
|
381
|
+
worktreePath,
|
|
150
382
|
repoPath: GLOBAL_WORKSPACE_ID,
|
|
151
383
|
agent,
|
|
152
384
|
autonomy: opts.autonomy ?? "default",
|
|
@@ -154,7 +386,10 @@ function createGlobalChat(opts) {
|
|
|
154
386
|
effort: resolved.effort,
|
|
155
387
|
fast: resolved.fast,
|
|
156
388
|
planMode: Boolean(opts.planMode),
|
|
157
|
-
attachments:
|
|
389
|
+
attachments: persistPendingFileAttachments(
|
|
390
|
+
worktreePath,
|
|
391
|
+
opts.attachments ?? []
|
|
392
|
+
),
|
|
158
393
|
parentThreadId: opts.parentThreadId ?? null,
|
|
159
394
|
status: "idle"
|
|
160
395
|
});
|
|
@@ -276,6 +511,10 @@ function ensureCloudCoordinator(agent) {
|
|
|
276
511
|
}
|
|
277
512
|
|
|
278
513
|
export {
|
|
514
|
+
stageAbsolutePathsAsAttachments,
|
|
515
|
+
stageBuffersAsAttachments,
|
|
516
|
+
persistPendingFileAttachments,
|
|
517
|
+
attachmentsFromWorktreePaths,
|
|
279
518
|
ORCHESTRATOR_AGENT_KINDS,
|
|
280
519
|
isOrchestratorCapableAgent,
|
|
281
520
|
assertOrchestratorCapableAgent,
|