slopwaresystems 0.9.4 → 0.9.6
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/index.js +1 -1
- package/dist/main.js +138 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -146,7 +146,7 @@ function fetchLaunchCandidate(launcher2) {
|
|
|
146
146
|
var path = fileURLToPath(import.meta.url);
|
|
147
147
|
var launcher = {
|
|
148
148
|
path,
|
|
149
|
-
bundledVersion: "0.9.
|
|
149
|
+
bundledVersion: "0.9.6",
|
|
150
150
|
bundledMain: fileURLToPath(new URL("./main.js", import.meta.url)),
|
|
151
151
|
installed: isInstalledLauncherPath(path)
|
|
152
152
|
};
|
package/dist/main.js
CHANGED
|
@@ -26542,7 +26542,7 @@ var TaskEventRecord = external_exports.object({
|
|
|
26542
26542
|
});
|
|
26543
26543
|
|
|
26544
26544
|
// ../contract/src/work/cli-release.ts
|
|
26545
|
-
var CLI_RELEASE = "0.9.
|
|
26545
|
+
var CLI_RELEASE = "0.9.6";
|
|
26546
26546
|
var CLI_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
26547
26547
|
var CLI_VERSION_MAX = 64;
|
|
26548
26548
|
function parseCliVersion(version2) {
|
|
@@ -28760,6 +28760,25 @@ function persistRememberedConversation(cwd, conversation) {
|
|
|
28760
28760
|
const directory = `${buildConversationPath(cwd)}.d`;
|
|
28761
28761
|
persistLocalState(join3(directory, `${generateLocalStateKey(cwd, conversation.id)}.json`), JSON.stringify(conversation));
|
|
28762
28762
|
}
|
|
28763
|
+
var buildRelayConversationPath = (relay) => join3(buildSessionsDir(), `relay-${relay.relayPid}-${relay.harnessPid}.conversation.json`);
|
|
28764
|
+
function persistRelayConversation(relay, conversation) {
|
|
28765
|
+
try {
|
|
28766
|
+
persistLocalState(buildRelayConversationPath(relay), JSON.stringify(conversation));
|
|
28767
|
+
} catch {
|
|
28768
|
+
}
|
|
28769
|
+
}
|
|
28770
|
+
function fetchRelayConversation(relay) {
|
|
28771
|
+
try {
|
|
28772
|
+
const parsed = JSON.parse(readFileSync4(buildRelayConversationPath(relay), "utf8"));
|
|
28773
|
+
const harness = AgentHarness.safeParse(parsed.harness);
|
|
28774
|
+
return typeof parsed.id === "string" && parsed.id && harness.success ? { id: parsed.id, harness: harness.data } : null;
|
|
28775
|
+
} catch {
|
|
28776
|
+
return null;
|
|
28777
|
+
}
|
|
28778
|
+
}
|
|
28779
|
+
function deleteRelayConversation(relay) {
|
|
28780
|
+
rmSync4(buildRelayConversationPath(relay), { force: true });
|
|
28781
|
+
}
|
|
28763
28782
|
function fetchRememberedConversation(cwd, notBefore, harness) {
|
|
28764
28783
|
const path3 = buildConversationPath(cwd);
|
|
28765
28784
|
const candidates = [];
|
|
@@ -29378,6 +29397,24 @@ function isMainChatThread(roots, threadId) {
|
|
|
29378
29397
|
const head = fetchFileHead(path3, HEAD_BYTES);
|
|
29379
29398
|
return head === "" ? true : isMainChatRollout(head.split("\n")[0] ?? "");
|
|
29380
29399
|
}
|
|
29400
|
+
function parseCodexThreadFromToolCallMeta(meta3) {
|
|
29401
|
+
const turn = meta3["x-codex-turn-metadata"];
|
|
29402
|
+
if (typeof turn !== "object" || turn === null || Array.isArray(turn)) return null;
|
|
29403
|
+
const thread = turn.thread_id ?? meta3.threadId;
|
|
29404
|
+
return typeof thread === "string" && thread.trim() ? thread.trim() : null;
|
|
29405
|
+
}
|
|
29406
|
+
var PARENT_THREAD_HOPS = 8;
|
|
29407
|
+
function fetchCodexChatThreadId(roots, threadId) {
|
|
29408
|
+
let current = threadId;
|
|
29409
|
+
for (let hop = 0; hop < PARENT_THREAD_HOPS; hop += 1) {
|
|
29410
|
+
const path3 = fetchCodexRolloutPath(roots, current);
|
|
29411
|
+
const line = path3 ? fetchFileHead(path3, HEAD_BYTES).split("\n")[0] ?? "" : "";
|
|
29412
|
+
const parent = /"parent_thread_id"\s*:\s*"([^"]+)"/.exec(line)?.[1];
|
|
29413
|
+
if (!parent || parent === current) return current;
|
|
29414
|
+
current = parent;
|
|
29415
|
+
}
|
|
29416
|
+
return current;
|
|
29417
|
+
}
|
|
29381
29418
|
function fetchCodexRolloutPath(roots, threadId) {
|
|
29382
29419
|
const suffix = `-${threadId}.jsonl`;
|
|
29383
29420
|
let best = null;
|
|
@@ -29451,15 +29488,14 @@ function fetchKnownConversation(cwd) {
|
|
|
29451
29488
|
if (remembered?.harness === "codex" && isMainChatThread(fetchCodexHomes().map((home) => join9(home, "sessions")), remembered.id)) return remembered;
|
|
29452
29489
|
return remembered?.harness === "codex" ? null : remembered;
|
|
29453
29490
|
}
|
|
29454
|
-
function resolveAgentIdentity(cwd, fallback = "process") {
|
|
29455
|
-
const conversation = fetchKnownConversation(cwd);
|
|
29491
|
+
function resolveAgentIdentity(cwd, fallback = "process", conversation = fetchKnownConversation(cwd)) {
|
|
29456
29492
|
const repo = fetchRepo();
|
|
29457
29493
|
return {
|
|
29458
29494
|
conversation: conversation?.id ?? (fallback === "process" ? processConversation : `dir:${resolve4(cwd)}`),
|
|
29459
29495
|
harness: conversation?.harness ?? null,
|
|
29460
29496
|
directory: repo ? basename3(repo.worktree) : basename3(cwd),
|
|
29461
29497
|
branch: fetchCurrentBranch(cwd),
|
|
29462
|
-
cliVersion: "0.9.
|
|
29498
|
+
cliVersion: "0.9.6"
|
|
29463
29499
|
};
|
|
29464
29500
|
}
|
|
29465
29501
|
|
|
@@ -29924,6 +29960,9 @@ linked to ${link.projectKey} ${link.projectName} (${link.baseUrl})`
|
|
|
29924
29960
|
});
|
|
29925
29961
|
}
|
|
29926
29962
|
|
|
29963
|
+
// src/commands/mcp.ts
|
|
29964
|
+
import { join as join26 } from "path";
|
|
29965
|
+
|
|
29927
29966
|
// src/platform/mcp.ts
|
|
29928
29967
|
import { createInterface } from "readline";
|
|
29929
29968
|
|
|
@@ -30008,6 +30047,7 @@ function buildMcpRequestHandler(tools, info, sendJsonRpcMessage, options2 = {})
|
|
|
30008
30047
|
const output2 = new McpOutput();
|
|
30009
30048
|
let text;
|
|
30010
30049
|
try {
|
|
30050
|
+
options2.onToolCall?.(isRecord(params._meta) ? params._meta : {});
|
|
30011
30051
|
const suppliedArguments = params.arguments ?? {};
|
|
30012
30052
|
const args2 = tool.parseInput ? tool.parseInput(suppliedArguments) : suppliedArguments;
|
|
30013
30053
|
text = output2.formatResult(await tool.run(args2, output2));
|
|
@@ -30123,7 +30163,7 @@ function buildUpdateNotice() {
|
|
|
30123
30163
|
}
|
|
30124
30164
|
function resolveLatestCliVersion() {
|
|
30125
30165
|
const deprecated = fetchDeprecatedVersions();
|
|
30126
|
-
return sortCliVersions([CLI_RELEASE, "0.9.
|
|
30166
|
+
return sortCliVersions([CLI_RELEASE, "0.9.6", fetchUpdateStatus().latest ?? CLI_RELEASE]).filter((version2) => !deprecated.has(version2)).at(-1) ?? CLI_RELEASE;
|
|
30127
30167
|
}
|
|
30128
30168
|
function formatAgentCliVersion(version2, latest = resolveLatestCliVersion()) {
|
|
30129
30169
|
const label = version2 ? `slop ${version2}` : "an older slop";
|
|
@@ -30559,7 +30599,7 @@ async function updateInstalledCliFromRegistry(launcher, options2) {
|
|
|
30559
30599
|
const running = fetchLaunchCandidate(launcher).version;
|
|
30560
30600
|
const action = running === previous ? "current" : isNewerVersion(running, previous) ? "updated" : "rolled-back";
|
|
30561
30601
|
const latest = resolveNewestOfferedRelease(index);
|
|
30562
|
-
deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.
|
|
30602
|
+
deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.6"]));
|
|
30563
30603
|
persistUpdateStatus({ checkedAt: now(), latest, failures: 0, lastError: null });
|
|
30564
30604
|
return { action, running, previous, latest };
|
|
30565
30605
|
} catch (error62) {
|
|
@@ -31366,7 +31406,7 @@ function watchLaunchTarget(onChange) {
|
|
|
31366
31406
|
}
|
|
31367
31407
|
function runMcpRelay() {
|
|
31368
31408
|
const launcher = readLauncherInfo();
|
|
31369
|
-
const own2 = { version: "0.9.
|
|
31409
|
+
const own2 = { version: "0.9.6", main: fileURLToPath(import.meta.url), downloaded: false };
|
|
31370
31410
|
const relay = new McpRelay({
|
|
31371
31411
|
input: process.stdin,
|
|
31372
31412
|
output: process.stdout,
|
|
@@ -31807,7 +31847,7 @@ async function waitForMessage(api, projectId, taskKey, options2 = {}) {
|
|
|
31807
31847
|
setTimeout(() => resolve6(outcome), 50);
|
|
31808
31848
|
};
|
|
31809
31849
|
const held = new HeldSession(api, projectId, taskKey, {
|
|
31810
|
-
claim: () => options2.claim ?? { harness: null, directory: null, branch: null, cliVersion: "0.9.
|
|
31850
|
+
claim: () => options2.claim ?? { harness: null, directory: null, branch: null, cliVersion: "0.9.6" },
|
|
31811
31851
|
reconnect: false,
|
|
31812
31852
|
onHello: options2.onHello,
|
|
31813
31853
|
onEnd: () => finishWait({ kind: "ended" }),
|
|
@@ -32118,7 +32158,6 @@ var WORKER_FRESH_MS = 12e4;
|
|
|
32118
32158
|
var WORKER_GONE_MS = 3e5;
|
|
32119
32159
|
var READ_CAP = 256 * 1024;
|
|
32120
32160
|
var CARRY_CAP = 64 * 1024;
|
|
32121
|
-
var CHILD_SCAN_CAP = 40;
|
|
32122
32161
|
var DISCOVER_EVERY_MS = 1e4;
|
|
32123
32162
|
var TAIL_EVERY_MS = 1e3;
|
|
32124
32163
|
var truncate = (text, cap) => text.length <= cap ? text : `${text.slice(0, cap - 1)}\u2026`;
|
|
@@ -32252,7 +32291,33 @@ function parseModelFromCodexLine(line) {
|
|
|
32252
32291
|
if (entry.type !== "turn_context" || typeof model !== "string" || !model.trim()) return null;
|
|
32253
32292
|
return truncate(model.trim(), MODEL_MAX);
|
|
32254
32293
|
}
|
|
32255
|
-
|
|
32294
|
+
function parseTurnStateFromClaudeLine(line) {
|
|
32295
|
+
if (!line.includes('"assistant"') && !line.includes('"user"')) return null;
|
|
32296
|
+
let entry;
|
|
32297
|
+
try {
|
|
32298
|
+
entry = JSON.parse(line);
|
|
32299
|
+
} catch {
|
|
32300
|
+
return null;
|
|
32301
|
+
}
|
|
32302
|
+
if (entry.type === "user") return "working";
|
|
32303
|
+
if (entry.type !== "assistant") return null;
|
|
32304
|
+
const stop = entry.message?.stop_reason;
|
|
32305
|
+
return stop === "end_turn" || stop === "stop_sequence" ? "finished" : "working";
|
|
32306
|
+
}
|
|
32307
|
+
function parseTurnStateFromCodexLine(line) {
|
|
32308
|
+
if (!line.includes('"event_msg"') && !line.includes('"response_item"') && !line.includes('"turn_context"')) return null;
|
|
32309
|
+
let entry;
|
|
32310
|
+
try {
|
|
32311
|
+
entry = JSON.parse(line);
|
|
32312
|
+
} catch {
|
|
32313
|
+
return null;
|
|
32314
|
+
}
|
|
32315
|
+
if (entry.type === "response_item" || entry.type === "turn_context") return "working";
|
|
32316
|
+
if (entry.type !== "event_msg") return null;
|
|
32317
|
+
if (entry.payload?.type === "task_complete" || entry.payload?.type === "turn_aborted") return "finished";
|
|
32318
|
+
return entry.payload?.type === "task_started" ? "working" : null;
|
|
32319
|
+
}
|
|
32320
|
+
var resolveLineParsers = (harness) => harness === "codex" ? { parseToolCall: parseToolCallFromCodexLine, parseModel: parseModelFromCodexLine, parseTurnState: parseTurnStateFromCodexLine } : { parseToolCall: parseToolCallFromClaudeLine, parseModel: parseModelFromClaudeLine, parseTurnState: parseTurnStateFromClaudeLine };
|
|
32256
32321
|
var fetchFileSize = (path3) => {
|
|
32257
32322
|
try {
|
|
32258
32323
|
return statSync7(path3).size;
|
|
@@ -32307,6 +32372,14 @@ function fetchModelFromFileTail(path3, parseModel) {
|
|
|
32307
32372
|
}
|
|
32308
32373
|
return null;
|
|
32309
32374
|
}
|
|
32375
|
+
function fetchTurnStateFromFileTail(path3, parseTurnState) {
|
|
32376
|
+
const lines2 = new FileTail(path3, "start").fetchNewLines();
|
|
32377
|
+
for (let index = lines2.length - 1; index >= 0; index -= 1) {
|
|
32378
|
+
const state = parseTurnState(lines2[index]);
|
|
32379
|
+
if (state) return state;
|
|
32380
|
+
}
|
|
32381
|
+
return "working";
|
|
32382
|
+
}
|
|
32310
32383
|
var fetchChangedAt = (path3) => {
|
|
32311
32384
|
try {
|
|
32312
32385
|
return statSync7(path3).mtimeMs;
|
|
@@ -32382,7 +32455,7 @@ function parseCodexWorkerLabel(head) {
|
|
|
32382
32455
|
return parts.length ? truncate(parts.join(" \u2014 "), WORKER_LABEL_MAX) : null;
|
|
32383
32456
|
}
|
|
32384
32457
|
function findCodexChildRollouts(roots, parentThreadId, changedAfter) {
|
|
32385
|
-
const rollouts =
|
|
32458
|
+
const rollouts = /* @__PURE__ */ new Map();
|
|
32386
32459
|
const findRolloutsInDirectory = (directory, depth) => {
|
|
32387
32460
|
let entries;
|
|
32388
32461
|
try {
|
|
@@ -32400,12 +32473,13 @@ function findCodexChildRollouts(roots, parentThreadId, changedAfter) {
|
|
|
32400
32473
|
if (!ref || ref === parentThreadId) continue;
|
|
32401
32474
|
const changedAt = fetchChangedAt(path3);
|
|
32402
32475
|
if (changedAt < changedAfter) continue;
|
|
32403
|
-
rollouts.
|
|
32476
|
+
if (!rollouts.has(ref)) rollouts.set(ref, { path: path3, ref, changedAt });
|
|
32404
32477
|
}
|
|
32405
32478
|
};
|
|
32406
32479
|
for (const root of roots) findRolloutsInDirectory(root, 0);
|
|
32407
32480
|
const found = [];
|
|
32408
|
-
for (const rollout of rollouts.sort((a, b) => b.changedAt - a.changedAt)
|
|
32481
|
+
for (const rollout of [...rollouts.values()].sort((a, b) => b.changedAt - a.changedAt)) {
|
|
32482
|
+
if (found.length >= WORKERS_PER_SESSION) break;
|
|
32409
32483
|
const head = fetchFileHead(rollout.path, HEAD_BYTES).split("\n")[0] ?? "";
|
|
32410
32484
|
if (!head.includes('"session_meta"') || isCodexHelperRollout(head)) continue;
|
|
32411
32485
|
if (!new RegExp(`"parent_thread_id"\\s*:\\s*"${parentThreadId}"`).test(head)) continue;
|
|
@@ -32497,7 +32571,10 @@ var HarnessActivity = class {
|
|
|
32497
32571
|
for (const file2 of found) {
|
|
32498
32572
|
const known = this.workers.get(file2.ref);
|
|
32499
32573
|
if (known) Object.assign(known, { label: file2.label, directory: file2.directory, branch: file2.branch, changedAt: file2.changedAt });
|
|
32500
|
-
else
|
|
32574
|
+
else {
|
|
32575
|
+
const tail = new FileTail(file2.path, "end");
|
|
32576
|
+
this.workers.set(file2.ref, { ...file2, since: new Date(file2.changedAt).toISOString(), model: fetchModelFromFileTail(file2.path, this.parsers.parseModel), doing: null, finished: fetchTurnStateFromFileTail(file2.path, this.parsers.parseTurnState) === "finished", tail });
|
|
32577
|
+
}
|
|
32501
32578
|
}
|
|
32502
32579
|
const live = new Set(found.map((file2) => file2.ref));
|
|
32503
32580
|
for (const ref of [...this.workers.keys()]) if (!live.has(ref)) this.workers.delete(ref);
|
|
@@ -32522,35 +32599,39 @@ var HarnessActivity = class {
|
|
|
32522
32599
|
}
|
|
32523
32600
|
return [];
|
|
32524
32601
|
}
|
|
32525
|
-
/** The newest tool call and
|
|
32602
|
+
/** The newest tool call, model and turn state in everything that has been written since the last read. */
|
|
32526
32603
|
read() {
|
|
32527
|
-
const { parseToolCall, parseModel } = this.parsers;
|
|
32528
|
-
const
|
|
32604
|
+
const { parseToolCall, parseModel, parseTurnState } = this.parsers;
|
|
32605
|
+
const fetchNewestCallModelAndTurnState = (tail) => {
|
|
32529
32606
|
let call = null;
|
|
32530
32607
|
let model = null;
|
|
32608
|
+
let turn = null;
|
|
32531
32609
|
for (const line of tail.fetchNewLines()) {
|
|
32532
32610
|
call = parseToolCall(line) ?? call;
|
|
32533
32611
|
model = parseModel(line) ?? model;
|
|
32612
|
+
turn = parseTurnState(line) ?? turn;
|
|
32534
32613
|
}
|
|
32535
|
-
return { call, model };
|
|
32614
|
+
return { call, model, turn };
|
|
32536
32615
|
};
|
|
32537
32616
|
if (this.own) {
|
|
32538
|
-
const { call, model } =
|
|
32617
|
+
const { call, model } = fetchNewestCallModelAndTurnState(this.own);
|
|
32539
32618
|
this.doing = call ?? this.doing;
|
|
32540
32619
|
this.model = model ?? this.model;
|
|
32541
32620
|
}
|
|
32542
32621
|
for (const worker of this.workers.values()) {
|
|
32543
|
-
const { call, model } =
|
|
32622
|
+
const { call, model, turn } = fetchNewestCallModelAndTurnState(worker.tail);
|
|
32544
32623
|
worker.doing = call ?? worker.doing;
|
|
32545
32624
|
worker.model = model ?? worker.model;
|
|
32625
|
+
if (turn) worker.finished = turn === "finished";
|
|
32546
32626
|
}
|
|
32547
32627
|
}
|
|
32548
32628
|
/**
|
|
32549
|
-
* Every worker, oldest first, so the roster changes only when one starts or finishes and never
|
|
32550
|
-
*
|
|
32629
|
+
* Every worker still working, oldest first, so the roster changes only when one starts or finishes and never
|
|
32630
|
+
* because one got busy. One whose turn has ended leaves at once, not when its records have gone quiet. The
|
|
32631
|
+
* contract's guard is far past what a harness runs; past it, the oldest are the ones listed.
|
|
32551
32632
|
*/
|
|
32552
32633
|
buildRoster() {
|
|
32553
|
-
return [...this.workers.values()].sort((a, b) => a.since.localeCompare(b.since) || a.ref.localeCompare(b.ref)).slice(0, WORKERS_PER_SESSION).map((worker) => ({ ref: worker.ref, label: worker.label, directory: worker.directory, branch: worker.branch, model: worker.model, since: worker.since }));
|
|
32634
|
+
return [...this.workers.values()].filter((worker) => !worker.finished).sort((a, b) => a.since.localeCompare(b.since) || a.ref.localeCompare(b.ref)).slice(0, WORKERS_PER_SESSION).map((worker) => ({ ref: worker.ref, label: worker.label, directory: worker.directory, branch: worker.branch, model: worker.model, since: worker.since }));
|
|
32554
32635
|
}
|
|
32555
32636
|
/** Quiet for a while: still listed, because it is probably thinking, but saying nothing about what it is doing. */
|
|
32556
32637
|
buildWorkerLines(roster, now) {
|
|
@@ -35445,7 +35526,7 @@ var SplatRendererConnection = class {
|
|
|
35445
35526
|
try {
|
|
35446
35527
|
let path3;
|
|
35447
35528
|
try {
|
|
35448
|
-
const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.
|
|
35529
|
+
const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.6", onlyMe: this.options.onlyMe ?? false, agent: this.options.agent ?? null, capabilities: ["workspaces"] });
|
|
35449
35530
|
path3 = ticket.path;
|
|
35450
35531
|
} catch (error62) {
|
|
35451
35532
|
if (error62 instanceof CliError && ["unauthenticated", "not_found", "forbidden", "bad_request"].includes(error62.code)) {
|
|
@@ -37479,17 +37560,17 @@ function hasHarnessSetup() {
|
|
|
37479
37560
|
function syncMachineSetupAfterUpdate() {
|
|
37480
37561
|
const nothing = { skills: [], retired: [], reinstalling: false };
|
|
37481
37562
|
try {
|
|
37482
|
-
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.
|
|
37563
|
+
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.6") return nothing;
|
|
37483
37564
|
const lock = claimFileLock(buildMachineSetupLockDirectory(), { staleAfterMs: 6e4 });
|
|
37484
37565
|
if (!lock) return nothing;
|
|
37485
37566
|
try {
|
|
37486
37567
|
const state = fetchMachineSetupState();
|
|
37487
|
-
if (state?.version === "0.9.
|
|
37568
|
+
if (state?.version === "0.9.6") return nothing;
|
|
37488
37569
|
const skills = hasInstalledSkills() ? installSkills() : [];
|
|
37489
37570
|
const shipped = Object.keys(SKILLS);
|
|
37490
37571
|
const retired = deleteRetiredSkills((state?.skills ?? []).filter((name) => !shipped.includes(name)));
|
|
37491
37572
|
const setupRevision = state?.setupRevision ?? (hasHarnessSetup() ? UNRECORDED_SETUP_REVISION : null);
|
|
37492
|
-
persistMachineSetupState({ version: "0.9.
|
|
37573
|
+
persistMachineSetupState({ version: "0.9.6", setupRevision, skills: hasInstalledSkills() ? shipped : [] });
|
|
37493
37574
|
const reinstalling = setupRevision !== null && setupRevision < SETUP_REVISION && runMcpInstallInBackground();
|
|
37494
37575
|
return { skills, retired, reinstalling };
|
|
37495
37576
|
} finally {
|
|
@@ -37656,7 +37737,7 @@ async function trustCodexHooks(codexHome) {
|
|
|
37656
37737
|
const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
|
|
37657
37738
|
`);
|
|
37658
37739
|
try {
|
|
37659
|
-
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.
|
|
37740
|
+
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.6" }, capabilities: { experimentalApi: true } });
|
|
37660
37741
|
sendNotification("initialized", {});
|
|
37661
37742
|
const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
|
|
37662
37743
|
const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
|
|
@@ -37689,18 +37770,34 @@ function registerMcpInstallCommand(mcp) {
|
|
|
37689
37770
|
}
|
|
37690
37771
|
|
|
37691
37772
|
// src/commands/mcp.ts
|
|
37692
|
-
function buildTools(lifecycle) {
|
|
37693
|
-
if (isNonInteractiveHarness()) return { tools: [], startPresence: () => void 0, releaseSessions: () => void 0 };
|
|
37773
|
+
function buildTools(lifecycle, relay) {
|
|
37774
|
+
if (isNonInteractiveHarness()) return { tools: [], startPresence: () => void 0, releaseSessions: () => void 0, observeToolCall: () => void 0 };
|
|
37694
37775
|
let api = null;
|
|
37695
37776
|
const requireApi = () => api ??= buildAuthedApiClient();
|
|
37696
37777
|
let identity = null;
|
|
37778
|
+
let called = relay ? fetchRelayConversation(relay) : null;
|
|
37779
|
+
const observeToolCall = (meta3) => {
|
|
37780
|
+
if (called) return;
|
|
37781
|
+
const thread = parseCodexThreadFromToolCallMeta(meta3);
|
|
37782
|
+
if (!thread) return;
|
|
37783
|
+
called = { id: fetchCodexChatThreadId(fetchCodexHomes().map((home) => join26(home, "sessions")), thread), harness: "codex" };
|
|
37784
|
+
if (relay) persistRelayConversation(relay, called);
|
|
37785
|
+
};
|
|
37786
|
+
const fetchOwnConversation = () => called ?? fetchKnownConversation(process.cwd());
|
|
37697
37787
|
let stopped = false;
|
|
37698
37788
|
const projects = /* @__PURE__ */ new Map();
|
|
37699
37789
|
const requireProjectTools = (project) => {
|
|
37700
37790
|
if (stopped) throw new Error("The MCP server is stopping");
|
|
37701
37791
|
let context2 = projects.get(project.id);
|
|
37702
37792
|
if (!context2) {
|
|
37703
|
-
|
|
37793
|
+
if (!identity) {
|
|
37794
|
+
const conversation = fetchOwnConversation();
|
|
37795
|
+
identity = resolveAgentIdentity(process.cwd(), "process", conversation);
|
|
37796
|
+
if (relay && conversation && !called) {
|
|
37797
|
+
called = conversation;
|
|
37798
|
+
persistRelayConversation(relay, conversation);
|
|
37799
|
+
}
|
|
37800
|
+
}
|
|
37704
37801
|
context2 = createProjectTools(buildAuthedApiClient(), project, identity);
|
|
37705
37802
|
projects.set(project.id, context2);
|
|
37706
37803
|
}
|
|
@@ -37719,8 +37816,9 @@ function buildTools(lifecycle) {
|
|
|
37719
37816
|
if (presenceStarted) return;
|
|
37720
37817
|
presenceStarted = true;
|
|
37721
37818
|
void (async () => {
|
|
37722
|
-
for (let waited = 0; waited < 1e4 && !
|
|
37819
|
+
for (let waited = 0; waited < 1e4 && !fetchOwnConversation() && !stopped; waited += 250) await new Promise((resolve6) => setTimeout(resolve6, 250));
|
|
37723
37820
|
if (stopped) return;
|
|
37821
|
+
if (!identity && !fetchOwnConversation() && resolveParentHarness() === "codex") return;
|
|
37724
37822
|
await requireProjectTools(await resolveProject(requireApi())).start();
|
|
37725
37823
|
})().catch(() => void 0);
|
|
37726
37824
|
};
|
|
@@ -37728,6 +37826,7 @@ function buildTools(lifecycle) {
|
|
|
37728
37826
|
if (stopped) return;
|
|
37729
37827
|
stopped = true;
|
|
37730
37828
|
for (const context2 of projects.values()) context2.stop(reason);
|
|
37829
|
+
if (relay && reason === "released") deleteRelayConversation(relay);
|
|
37731
37830
|
};
|
|
37732
37831
|
let exiting = false;
|
|
37733
37832
|
const endSessionAndExit = (reason) => {
|
|
@@ -37739,7 +37838,7 @@ function buildTools(lifecycle) {
|
|
|
37739
37838
|
process.stdin.once("end", () => endSessionAndExit(lifecycle.onInputEnd));
|
|
37740
37839
|
process.stdin.once("close", () => endSessionAndExit(lifecycle.onInputEnd));
|
|
37741
37840
|
for (const signal of ["SIGTERM", "SIGHUP", "SIGINT"]) process.once(signal, () => endSessionAndExit("released"));
|
|
37742
|
-
return { tools: createProjectGroupedTools(runHandlerByName), startPresence, releaseSessions };
|
|
37841
|
+
return { tools: createProjectGroupedTools(runHandlerByName), startPresence, releaseSessions, observeToolCall };
|
|
37743
37842
|
}
|
|
37744
37843
|
function attachUpdateNoticeToTools(list) {
|
|
37745
37844
|
return list.map((tool) => ({
|
|
@@ -37754,10 +37853,12 @@ ${notice}` : result;
|
|
|
37754
37853
|
}));
|
|
37755
37854
|
}
|
|
37756
37855
|
function serveBoardTools(version2) {
|
|
37757
|
-
const
|
|
37856
|
+
const relay = drainRelayChildContextFromEnvironment();
|
|
37857
|
+
const underRelay = relay !== null;
|
|
37758
37858
|
const lifecycle = { onInputEnd: underRelay ? "orphaned" : "released" };
|
|
37759
|
-
const { tools, startPresence, releaseSessions } = buildTools(lifecycle);
|
|
37859
|
+
const { tools, startPresence, releaseSessions, observeToolCall } = buildTools(lifecycle, relay);
|
|
37760
37860
|
serveMcp(attachUpdateNoticeToTools(tools), { name: "slop", version: version2 }, {
|
|
37861
|
+
onToolCall: observeToolCall,
|
|
37761
37862
|
onNotification: (method) => {
|
|
37762
37863
|
if (method === RELAY_START_NOTIFICATION) startPresence();
|
|
37763
37864
|
else if (method === RELAY_HANDOVER_NOTIFICATION) {
|
|
@@ -37921,7 +38022,7 @@ var options = optionEnd < 0 ? args : args.slice(0, optionEnd);
|
|
|
37921
38022
|
updateJsonMode(options.includes("--json"));
|
|
37922
38023
|
syncMachineSetupAfterUpdate();
|
|
37923
38024
|
if (!options.includes("--background") && !options.includes("--child")) scheduleBackgroundUpdate();
|
|
37924
|
-
var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.9.
|
|
38025
|
+
var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.9.6").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
|
|
37925
38026
|
outputError: (message, write) => {
|
|
37926
38027
|
if (!isJsonMode()) write(message);
|
|
37927
38028
|
},
|
|
@@ -37938,7 +38039,7 @@ var sessionCommand = registerSessionCommands(program2);
|
|
|
37938
38039
|
registerThreadCommands(program2, taskCommand);
|
|
37939
38040
|
registerOperationCommands(program2, taskCommand, sessionCommand);
|
|
37940
38041
|
registerSplatCommands(program2);
|
|
37941
|
-
registerMcpCommands(program2, "0.9.
|
|
38042
|
+
registerMcpCommands(program2, "0.9.6");
|
|
37942
38043
|
registerGuideCommand(program2);
|
|
37943
38044
|
registerSkillCommands(program2);
|
|
37944
38045
|
registerUpdateCommand(program2);
|