@ai-matrx/coding-sessions 0.1.85 → 0.1.87
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/CHANGELOG.md +12 -0
- package/dist/engine/index.cjs +184 -49
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +1 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.js +183 -50
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/worker.js +5 -3
- package/dist/engine/worker.js.map +1 -1
- package/dist/{index-DEPwyr2j.d.cts → index-CDeDKQHe.d.cts} +37 -5
- package/dist/{index-DEPwyr2j.d.ts → index-CDeDKQHe.d.ts} +37 -5
- package/dist/index.cjs +18 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +176 -25
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +29 -2
- package/dist/react/index.d.ts +29 -2
- package/dist/react/index.js +224 -62
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +182 -50
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +2 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +183 -51
- package/dist/server/index.js.map +1 -1
- package/dist/ui/assets/{index-DSWoryQZ.js → index-crORYlzR.js} +1 -2
- package/dist/ui/assets/index-eqe0sxR4.css +2 -0
- package/dist/ui/index.html +2 -2
- package/package.json +3 -3
- package/dist/ui/assets/index-Gp2bMDtx.css +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ai-matrx/coding-sessions
|
|
2
2
|
|
|
3
|
+
## 0.1.87
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/coding-sessions/v0.1.86..npm/coding-sessions/v0.1.87 -- apps/shared/coding-sessions`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.1.86
|
|
10
|
+
|
|
11
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
12
|
+
`git diff npm/coding-sessions/v0.1.85..npm/coding-sessions/v0.1.86 -- apps/shared/coding-sessions`).
|
|
13
|
+
No source changes intended and no consumer action required.
|
|
14
|
+
|
|
3
15
|
## 0.1.85
|
|
4
16
|
|
|
5
17
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
package/dist/engine/index.cjs
CHANGED
|
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/engine/index.ts
|
|
31
31
|
var engine_exports = {};
|
|
32
32
|
__export(engine_exports, {
|
|
33
|
+
DEFAULT_SERVER_URL: () => DEFAULT_SERVER_URL,
|
|
34
|
+
DEFAULT_SUPABASE_URL: () => DEFAULT_SUPABASE_URL,
|
|
33
35
|
EFFORT_LEVELS: () => EFFORT_LEVELS,
|
|
34
36
|
PreferenceStore: () => PreferenceStore,
|
|
35
37
|
RAW_TRANSCRIPT_MAX_BYTES: () => RAW_TRANSCRIPT_MAX_BYTES,
|
|
@@ -162,8 +164,25 @@ function createAiMatrxRawBackupSink(options) {
|
|
|
162
164
|
// src/engine/agent-attach.ts
|
|
163
165
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
164
166
|
var import_node_path = __toESM(require("path"), 1);
|
|
167
|
+
|
|
168
|
+
// src/normalize/agent-block.ts
|
|
169
|
+
var AGENT_BLOCK_MARKER = "<ai_matrx_agent ";
|
|
170
|
+
function stripAgentBlock(text) {
|
|
171
|
+
const removed = text.match(/^<ai_matrx_agent_removed>[\s\S]*?<\/ai_matrx_agent_removed>\s*/);
|
|
172
|
+
if (removed) return text.slice(removed[0].length);
|
|
173
|
+
if (!text.startsWith(AGENT_BLOCK_MARKER)) return text;
|
|
174
|
+
const end = text.indexOf("</ai_matrx_agent>");
|
|
175
|
+
if (end < 0) return text;
|
|
176
|
+
let rest = text.slice(end + "</ai_matrx_agent>".length);
|
|
177
|
+
const skills = rest.match(/^\s*<skills_instructions>[\s\S]*?<\/skills_instructions>/);
|
|
178
|
+
if (skills) rest = rest.slice(skills[0].length);
|
|
179
|
+
return rest.replace(/^\s+/, "");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/engine/agent-attach.ts
|
|
165
183
|
var AGENT_MCP_SERVER_NAME = "matrx-agent";
|
|
166
184
|
var AGENT_PLUGIN_NAME = "matrx-agent";
|
|
185
|
+
var CODEX_REPLACEMENT_CLAUSE = "If a later message in this chat begins with an <ai_matrx_agent> block, that block replaces these AI Matrx agent instructions from then on; an <ai_matrx_agent_removed> block withdraws them.";
|
|
167
186
|
function escapeAttr(value) {
|
|
168
187
|
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
169
188
|
}
|
|
@@ -212,6 +231,20 @@ function renderCodexSkillsList(bundle, skillsRoot) {
|
|
|
212
231
|
];
|
|
213
232
|
return lines.join("\n");
|
|
214
233
|
}
|
|
234
|
+
function renderFallbackBlock(bundle, skillsRoot, options = {}) {
|
|
235
|
+
const skills = renderCodexSkillsList(bundle, skillsRoot);
|
|
236
|
+
const lead = options.replaces ? `These instructions REPLACE the earlier AI Matrx agent "${options.replaces}" from this message on. Where they differ from anything said before \u2014 including how earlier replies ended \u2014 follow these.` : "The instructions below are your AI Matrx agent for this chat from now on; they replace any AI Matrx agent instructions given earlier.";
|
|
237
|
+
const body = renderAgentInstructions(bundle).trim().replace(/^(<ai_matrx_agent [^>]*>)/, `$1
|
|
238
|
+
|
|
239
|
+
${lead}`);
|
|
240
|
+
return skills ? `${body}
|
|
241
|
+
|
|
242
|
+
${skills}
|
|
243
|
+
|
|
244
|
+
` : `${body}
|
|
245
|
+
|
|
246
|
+
`;
|
|
247
|
+
}
|
|
215
248
|
function tomlString(value) {
|
|
216
249
|
const scalar = value.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
217
250
|
return JSON.stringify(scalar).replace(/\u007f/g, "\\u007f");
|
|
@@ -272,10 +305,16 @@ async function writeAgentAttachment(dir, bundle, options) {
|
|
|
272
305
|
pluginDir,
|
|
273
306
|
mcpConfigFile,
|
|
274
307
|
mcpUrl,
|
|
275
|
-
// Same order as Claude's: the skills list first, the agent's words last
|
|
276
|
-
|
|
308
|
+
// Same order as Claude's: the skills list first, the agent's words last —
|
|
309
|
+
// then the one sentence that lets a later block replace them. Codex ranks
|
|
310
|
+
// developer instructions above a user message, so without this permission
|
|
311
|
+
// a mid-chat switch or update is ignored (measured live: the v2 block was
|
|
312
|
+
// delivered and Codex kept ending with v1's line).
|
|
313
|
+
codexInstructions: `${skillsList ? `${skillsList}
|
|
277
314
|
|
|
278
|
-
|
|
315
|
+
` : ""}${instructions}
|
|
316
|
+
${CODEX_REPLACEMENT_CLAUSE}
|
|
317
|
+
`
|
|
279
318
|
};
|
|
280
319
|
}
|
|
281
320
|
function agentArgsFor(provider, attachment, options) {
|
|
@@ -327,9 +366,29 @@ function sessionAgentRecord(bundle, options) {
|
|
|
327
366
|
name: bundle.name,
|
|
328
367
|
definitionHash: bundle.definition_hash,
|
|
329
368
|
loaded,
|
|
330
|
-
unavailable
|
|
369
|
+
unavailable,
|
|
370
|
+
skills: bundle.skills.map((skill) => skill.label),
|
|
371
|
+
tools: options.toolsServed ? bundle.tools.map((tool) => tool.canonical_name) : [],
|
|
372
|
+
...options.variables ? { variables: options.variables } : {}
|
|
331
373
|
};
|
|
332
374
|
}
|
|
375
|
+
var AGENT_REMOVED_BLOCK = "<ai_matrx_agent_removed>The AI Matrx agent instructions given earlier in this chat no longer apply \u2014 including any rule about how replies end. Answer normally from this message on.</ai_matrx_agent_removed>\n\n";
|
|
376
|
+
async function codexCompactionDroppedAgent(rolloutFile, sinceIso) {
|
|
377
|
+
const text = await import_promises2.default.readFile(rolloutFile, "utf8").catch(() => "");
|
|
378
|
+
if (!text.includes('"type":"compacted"')) return false;
|
|
379
|
+
let latest = null;
|
|
380
|
+
for (const line of text.split("\n")) {
|
|
381
|
+
if (!line.includes('"type":"compacted"')) continue;
|
|
382
|
+
try {
|
|
383
|
+
const entry = JSON.parse(line);
|
|
384
|
+
if (entry.type === "compacted") latest = entry;
|
|
385
|
+
} catch {
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (!latest) return false;
|
|
389
|
+
if (sinceIso && latest.timestamp && latest.timestamp <= sinceIso) return false;
|
|
390
|
+
return !JSON.stringify(latest.payload?.replacement_history ?? "").includes(AGENT_BLOCK_MARKER.trim());
|
|
391
|
+
}
|
|
333
392
|
|
|
334
393
|
// src/engine/agents.ts
|
|
335
394
|
var import_node_crypto2 = require("crypto");
|
|
@@ -337,6 +396,7 @@ var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
|
337
396
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
338
397
|
var DEFAULT_SERVER_URL = "https://server.app.matrxserver.com";
|
|
339
398
|
var DEFAULT_SUPABASE_URL = "https://db.matrxserver.com";
|
|
399
|
+
var DEFAULT_SUPABASE_KEY = "sb_publishable_scm0jzEJiFUB5ItiqOx5Fg_8BOjB6oA";
|
|
340
400
|
var AGENT_CATALOG_RPCS = /* @__PURE__ */ new Set([
|
|
341
401
|
"agx_get_list_full",
|
|
342
402
|
"agx_search",
|
|
@@ -354,6 +414,10 @@ var agentsClient = async () => {
|
|
|
354
414
|
]);
|
|
355
415
|
return { ...matrx, ...portable, ...mcp };
|
|
356
416
|
};
|
|
417
|
+
function sortedValues(values) {
|
|
418
|
+
return Object.keys(values).sort().map((key) => [key, values[key]]);
|
|
419
|
+
}
|
|
420
|
+
var BUNDLE_CACHE_MS = 24 * 60 * 60 * 1e3;
|
|
357
421
|
var SIGNED_OUT_AGENT_MESSAGE = "Sign in to AI Matrx to use your agents.";
|
|
358
422
|
function userIdOf(credential) {
|
|
359
423
|
if (!credential || credential.kind !== "user") return null;
|
|
@@ -370,21 +434,26 @@ function createAgentConnection(options, dataDir) {
|
|
|
370
434
|
const credentials = options?.credentials ?? null;
|
|
371
435
|
const serverUrl = (options?.serverUrl ?? DEFAULT_SERVER_URL).replace(/\/+$/, "");
|
|
372
436
|
const supabaseUrl = (options?.supabaseUrl ?? DEFAULT_SUPABASE_URL).replace(/\/+$/, "");
|
|
373
|
-
const supabaseKey = options?.supabaseKey ?? null;
|
|
437
|
+
const supabaseKey = options?.supabaseKey ?? (options?.supabaseUrl ? null : DEFAULT_SUPABASE_KEY);
|
|
374
438
|
const root = import_node_path2.default.join(dataDir, "agents");
|
|
375
439
|
let mcpBaseUrl = null;
|
|
376
440
|
const handlers = /* @__PURE__ */ new Map();
|
|
377
441
|
const secretToSession = /* @__PURE__ */ new Map();
|
|
378
|
-
const organizationId = () => {
|
|
379
|
-
const raw = typeof options?.organizationId === "function" ? options.organizationId() : options?.organizationId;
|
|
442
|
+
const organizationId = async () => {
|
|
443
|
+
const raw = typeof options?.organizationId === "function" ? await options.organizationId() : options?.organizationId;
|
|
380
444
|
return raw && raw.trim() ? raw.trim() : null;
|
|
381
445
|
};
|
|
382
|
-
const transport = async () =>
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
446
|
+
const transport = async () => {
|
|
447
|
+
const org = await organizationId();
|
|
448
|
+
return (await agentsClient()).createMatrxTransport({
|
|
449
|
+
baseUrl: serverUrl,
|
|
450
|
+
...credentials ? { credentials } : {},
|
|
451
|
+
...org ? { organizationId: org } : {},
|
|
452
|
+
source: "codingSessionsAgents"
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
const cacheDir = import_node_path2.default.join(dataDir, "agents", ".bundles");
|
|
456
|
+
const cacheKey = (definitionHash, selection, surface) => (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify([definitionHash, sortedValues(selection.variables ?? {}), surface])).digest("hex");
|
|
388
457
|
const credential = async () => credentials ? credentials.get() : null;
|
|
389
458
|
const requireSignedIn = async () => {
|
|
390
459
|
if (!await credential()) throw new Error(SIGNED_OUT_AGENT_MESSAGE);
|
|
@@ -420,7 +489,7 @@ function createAgentConnection(options, dataDir) {
|
|
|
420
489
|
configured: credentials !== null && supabaseKey !== null,
|
|
421
490
|
signedIn: userId !== null,
|
|
422
491
|
userId,
|
|
423
|
-
organizationId: organizationId()
|
|
492
|
+
organizationId: await organizationId().catch(() => null)
|
|
424
493
|
};
|
|
425
494
|
},
|
|
426
495
|
async catalogRpc(request) {
|
|
@@ -467,27 +536,39 @@ function createAgentConnection(options, dataDir) {
|
|
|
467
536
|
},
|
|
468
537
|
async details(agentId) {
|
|
469
538
|
await requireSignedIn();
|
|
470
|
-
const
|
|
471
|
-
const [bundle, versions] = await Promise.all([
|
|
472
|
-
fetchPortableAgent(await transport(), { agentId }),
|
|
473
|
-
fetchPortableAgentVersions(await transport(), agentId).catch(() => [])
|
|
474
|
-
]);
|
|
539
|
+
const summary = await (await agentsClient()).fetchPortableAgentSummary(await transport(), agentId);
|
|
475
540
|
return {
|
|
476
|
-
agentId:
|
|
477
|
-
name:
|
|
478
|
-
variables:
|
|
479
|
-
versions: versions.map((v) => ({ id: v.id, versionNumber: v.version_number, changedAt: v.changed_at }))
|
|
480
|
-
latestVersionNumber:
|
|
541
|
+
agentId: summary.agent_id,
|
|
542
|
+
name: summary.name,
|
|
543
|
+
variables: summary.variables,
|
|
544
|
+
versions: summary.versions.map((v) => ({ id: v.id, versionNumber: v.version_number, changedAt: v.changed_at })),
|
|
545
|
+
latestVersionNumber: summary.version_number,
|
|
546
|
+
latestVersionId: summary.version_id
|
|
481
547
|
};
|
|
482
548
|
},
|
|
483
549
|
async loadBundle(selection) {
|
|
484
550
|
await requireSignedIn();
|
|
485
|
-
const
|
|
486
|
-
|
|
551
|
+
const client = await agentsClient();
|
|
552
|
+
const summary = await client.fetchPortableAgentSummary(await transport(), selection.agentId);
|
|
553
|
+
const versionId = selection.versionId ?? summary.version_id;
|
|
554
|
+
const definitionHash = versionId ? summary.versions.find((v) => v.id === versionId)?.definition_hash ?? null : summary.definition_hash;
|
|
555
|
+
const surface = "matrx-user/code-editor";
|
|
556
|
+
const file = definitionHash ? import_node_path2.default.join(cacheDir, `${cacheKey(definitionHash, selection, surface)}.json`) : null;
|
|
557
|
+
if (file) {
|
|
558
|
+
const cached = await import_promises3.default.readFile(file, "utf8").then((text) => JSON.parse(text)).catch(() => null);
|
|
559
|
+
const fresh = await import_promises3.default.stat(file).then((st) => Date.now() - st.mtimeMs < BUNDLE_CACHE_MS).catch(() => false);
|
|
560
|
+
if (cached && fresh && cached.definition_hash === definitionHash) return cached;
|
|
561
|
+
}
|
|
562
|
+
const bundle = await client.fetchPortableAgent(
|
|
487
563
|
await transport(),
|
|
488
|
-
|
|
489
|
-
{ variables: selection.variables ?? {} }
|
|
564
|
+
versionId ? { versionId } : { agentId: selection.agentId },
|
|
565
|
+
{ variables: selection.variables ?? {}, surface }
|
|
490
566
|
);
|
|
567
|
+
if (file && bundle.definition_hash === definitionHash) {
|
|
568
|
+
await import_promises3.default.mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
569
|
+
await import_promises3.default.writeFile(file, JSON.stringify(bundle), { mode: 384 });
|
|
570
|
+
}
|
|
571
|
+
return bundle;
|
|
491
572
|
},
|
|
492
573
|
async saveSessionBundle(sessionId, bundle) {
|
|
493
574
|
await import_promises3.default.mkdir(sessionDir(sessionId), { recursive: true, mode: 448 });
|
|
@@ -623,7 +704,7 @@ function createClaudeNormalizer() {
|
|
|
623
704
|
if (typeof content === "string") {
|
|
624
705
|
if (isSyntheticClaudeUserText(content) || content.trim().length === 0) return [];
|
|
625
706
|
userCounter += 1;
|
|
626
|
-
return [{ kind: "user", id: str(entry.uuid) ?? `user-${userCounter}`, text: content, at }];
|
|
707
|
+
return [{ kind: "user", id: str(entry.uuid) ?? `user-${userCounter}`, text: stripAgentBlock(content), at }];
|
|
627
708
|
}
|
|
628
709
|
if (!Array.isArray(content)) return [];
|
|
629
710
|
const items = [];
|
|
@@ -647,7 +728,7 @@ function createClaudeNormalizer() {
|
|
|
647
728
|
items.unshift({
|
|
648
729
|
kind: "user",
|
|
649
730
|
id: str(entry.uuid) ?? `user-${userCounter}`,
|
|
650
|
-
text: typed.join("\n\n"),
|
|
731
|
+
text: stripAgentBlock(typed.join("\n\n")),
|
|
651
732
|
at
|
|
652
733
|
});
|
|
653
734
|
}
|
|
@@ -902,7 +983,7 @@ function rolloutItem(item, fallbackId, at) {
|
|
|
902
983
|
const id = str2(item.id) ?? fallbackId;
|
|
903
984
|
switch (item.type) {
|
|
904
985
|
case "UserMessage": {
|
|
905
|
-
const text = stripCodexInjectedContext(itemText(item.content));
|
|
986
|
+
const text = stripCodexInjectedContext(stripAgentBlock(itemText(item.content)));
|
|
906
987
|
return text.trim() ? [{ kind: "user", id, text, at }] : [];
|
|
907
988
|
}
|
|
908
989
|
case "AgentMessage": {
|
|
@@ -985,7 +1066,7 @@ function createCodexRolloutNormalizer() {
|
|
|
985
1066
|
return rolloutItem(payload.item, fallbackId, at);
|
|
986
1067
|
}
|
|
987
1068
|
if (payload.type === "user_message" && !appItems) {
|
|
988
|
-
const text = stripCodexInjectedContext(str2(payload.message) ?? "");
|
|
1069
|
+
const text = stripCodexInjectedContext(stripAgentBlock(str2(payload.message) ?? ""));
|
|
989
1070
|
return text.trim() ? [{ kind: "user", id: fallbackId, text, at }] : [];
|
|
990
1071
|
}
|
|
991
1072
|
return [];
|
|
@@ -2463,6 +2544,12 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2463
2544
|
if (file) fileOffset = (await import_promises8.default.stat(file).catch(() => null))?.size ?? null;
|
|
2464
2545
|
}
|
|
2465
2546
|
let agentArgs = [];
|
|
2547
|
+
let cliPrompt = prompt;
|
|
2548
|
+
let delivered = null;
|
|
2549
|
+
if (!session.agent && session.agentRemovedDue) {
|
|
2550
|
+
cliPrompt = `${AGENT_REMOVED_BLOCK}${prompt}`;
|
|
2551
|
+
delivered = { agentRemovedDue: false };
|
|
2552
|
+
}
|
|
2466
2553
|
if (session.agent) {
|
|
2467
2554
|
const bundle = await agents.readSessionBundle(session.id);
|
|
2468
2555
|
if (!bundle) {
|
|
@@ -2480,6 +2567,10 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2480
2567
|
mcpUrl: await agents.mcpUrlFor(session.id)
|
|
2481
2568
|
});
|
|
2482
2569
|
agentArgs = agentArgsFor(provider, attachment, { resuming: session.providerSessionId !== null });
|
|
2570
|
+
if (session.agent.blockDue) {
|
|
2571
|
+
cliPrompt = `${renderFallbackBlock(bundle, import_node_path9.default.join(attachment.dir, "skills"), { replaces: session.agent.replaces })}${prompt}`;
|
|
2572
|
+
}
|
|
2573
|
+
delivered = { agent: { ...session.agent, blockDue: false, deliveredAt: run.startedAt } };
|
|
2483
2574
|
}
|
|
2484
2575
|
const child = forkWorker();
|
|
2485
2576
|
const liveRun = {
|
|
@@ -2495,6 +2586,10 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2495
2586
|
};
|
|
2496
2587
|
live.set(runId, liveRun);
|
|
2497
2588
|
emitItem(liveRun, { kind: "user", id: `run-${runId}`, text: prompt, at: run.startedAt });
|
|
2589
|
+
if (delivered) {
|
|
2590
|
+
const current = index.session(session.id);
|
|
2591
|
+
if (current) saveSession({ ...current, ...delivered });
|
|
2592
|
+
}
|
|
2498
2593
|
const splitter = createLineSplitter();
|
|
2499
2594
|
const claude = provider === "claude" ? createClaudeNormalizer() : null;
|
|
2500
2595
|
const codex = provider === "codex" ? createCodexStreamNormalizer(runId.slice(0, 8)) : null;
|
|
@@ -2533,6 +2628,7 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2533
2628
|
}
|
|
2534
2629
|
}
|
|
2535
2630
|
void pruneDriverScratch();
|
|
2631
|
+
if (provider === "codex" && final.status === "completed") void checkCompaction(session.id);
|
|
2536
2632
|
};
|
|
2537
2633
|
let settled = false;
|
|
2538
2634
|
child.on("message", (raw) => {
|
|
@@ -2647,7 +2743,7 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2647
2743
|
provider,
|
|
2648
2744
|
runId,
|
|
2649
2745
|
cwd: session.cwd,
|
|
2650
|
-
prompt,
|
|
2746
|
+
prompt: cliPrompt,
|
|
2651
2747
|
model,
|
|
2652
2748
|
effort: session.effort ?? null,
|
|
2653
2749
|
resumeSessionId: session.providerSessionId,
|
|
@@ -2658,6 +2754,29 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2658
2754
|
});
|
|
2659
2755
|
return run;
|
|
2660
2756
|
}
|
|
2757
|
+
async function checkCompaction(sessionId) {
|
|
2758
|
+
const session = index.session(sessionId);
|
|
2759
|
+
if (!session?.agent || session.agent.blockDue || !session.providerSessionId) return;
|
|
2760
|
+
const file = await findSessionFile("codex", session.providerSessionId, homes);
|
|
2761
|
+
if (!file || !await codexCompactionDroppedAgent(file, session.agent.deliveredAt ?? null)) return;
|
|
2762
|
+
const current = index.session(sessionId);
|
|
2763
|
+
if (current?.agent) {
|
|
2764
|
+
saveSession({ ...current, agent: { ...current.agent, blockDue: true } });
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
async function attachAgent(sessionId, selection, options2) {
|
|
2768
|
+
const bundle = await agents.loadBundle(selection);
|
|
2769
|
+
await agents.saveSessionBundle(sessionId, bundle);
|
|
2770
|
+
return {
|
|
2771
|
+
...sessionAgentRecord(bundle, {
|
|
2772
|
+
toolsServed: await agents.mcpUrlFor(sessionId) !== null,
|
|
2773
|
+
variables: selection.variables ?? {}
|
|
2774
|
+
}),
|
|
2775
|
+
blockDue: options2.blockDue,
|
|
2776
|
+
deliveredAt: null,
|
|
2777
|
+
replaces: options2.replaces ?? null
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2661
2780
|
function killGroup(liveRun) {
|
|
2662
2781
|
const target = liveRun.pgid;
|
|
2663
2782
|
if (target === null) return;
|
|
@@ -2914,7 +3033,6 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2914
3033
|
const prompt = input.prompt.trim();
|
|
2915
3034
|
if (!prompt) throw new Error("Type what you want done before starting.");
|
|
2916
3035
|
const cwd = await assertFolder(input.cwd);
|
|
2917
|
-
const bundle = input.agent ? await agents.loadBundle(input.agent) : null;
|
|
2918
3036
|
const draft = newSession({
|
|
2919
3037
|
provider: input.provider,
|
|
2920
3038
|
cwd,
|
|
@@ -2924,28 +3042,43 @@ async function createCodingSessionsEngine(options = {}) {
|
|
|
2924
3042
|
origin: "started",
|
|
2925
3043
|
providerSessionId: null
|
|
2926
3044
|
});
|
|
2927
|
-
if (
|
|
2928
|
-
await agents.saveSessionBundle(draft.id, bundle);
|
|
2929
|
-
draft.agent = sessionAgentRecord(bundle, { toolsServed: await agents.mcpUrlFor(draft.id) !== null });
|
|
2930
|
-
}
|
|
3045
|
+
if (input.agent) draft.agent = await attachAgent(draft.id, input.agent, { blockDue: false });
|
|
2931
3046
|
const session = saveSession(draft);
|
|
2932
3047
|
const run = await startRun(session, prompt);
|
|
2933
3048
|
return { session: index.session(session.id) ?? session, run, queued: false };
|
|
2934
3049
|
},
|
|
2935
3050
|
async takeover(input) {
|
|
2936
3051
|
const existing = index.session(input.providerSessionId);
|
|
2937
|
-
if (existing)
|
|
3052
|
+
if (existing) {
|
|
3053
|
+
if (!input.agent) return existing;
|
|
3054
|
+
return engine.setAgent(existing.id, input.agent);
|
|
3055
|
+
}
|
|
2938
3056
|
const cwd = await assertFolder(input.cwd);
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
);
|
|
3057
|
+
const draft = newSession({
|
|
3058
|
+
provider: input.provider,
|
|
3059
|
+
cwd,
|
|
3060
|
+
title: input.title?.trim() || "Taken-over chat",
|
|
3061
|
+
model: null,
|
|
3062
|
+
origin: "takeover",
|
|
3063
|
+
providerSessionId: input.providerSessionId
|
|
3064
|
+
});
|
|
3065
|
+
if (input.agent) draft.agent = await attachAgent(draft.id, input.agent, { blockDue: input.provider === "codex" });
|
|
3066
|
+
return saveSession(draft);
|
|
3067
|
+
},
|
|
3068
|
+
async setAgent(sessionId, selection) {
|
|
3069
|
+
const session = index.session(String(sessionId ?? ""));
|
|
3070
|
+
if (!session) throw new Error("This session is not in the list anymore.");
|
|
3071
|
+
if (!selection) {
|
|
3072
|
+
const told = session.agent?.deliveredAt != null;
|
|
3073
|
+
return saveSession({ ...session, agent: null, agentRemovedDue: told });
|
|
3074
|
+
}
|
|
3075
|
+
const previous = session.agent && session.agent.deliveredAt != null ? session.agent : null;
|
|
3076
|
+
const started = session.providerSessionId !== null;
|
|
3077
|
+
const agent = await attachAgent(session.id, selection, {
|
|
3078
|
+
blockDue: started,
|
|
3079
|
+
replaces: previous ? `${previous.name}${previous.versionNumber !== null ? ` v${previous.versionNumber}` : ""}` : null
|
|
3080
|
+
});
|
|
3081
|
+
return saveSession({ ...session, agent, agentRemovedDue: false });
|
|
2949
3082
|
},
|
|
2950
3083
|
async send(sessionId, rawPrompt) {
|
|
2951
3084
|
const prompt = rawPrompt.trim();
|
|
@@ -3061,6 +3194,8 @@ function openFolderIn(folder, target) {
|
|
|
3061
3194
|
}
|
|
3062
3195
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3063
3196
|
0 && (module.exports = {
|
|
3197
|
+
DEFAULT_SERVER_URL,
|
|
3198
|
+
DEFAULT_SUPABASE_URL,
|
|
3064
3199
|
EFFORT_LEVELS,
|
|
3065
3200
|
PreferenceStore,
|
|
3066
3201
|
RAW_TRANSCRIPT_MAX_BYTES,
|