slopwaresystems 0.9.4 → 0.9.5
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 +75 -22
- 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.5",
|
|
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.5";
|
|
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.5"
|
|
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.5", 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.5"]));
|
|
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.5", 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.5" },
|
|
31811
31851
|
reconnect: false,
|
|
31812
31852
|
onHello: options2.onHello,
|
|
31813
31853
|
onEnd: () => finishWait({ kind: "ended" }),
|
|
@@ -35445,7 +35485,7 @@ var SplatRendererConnection = class {
|
|
|
35445
35485
|
try {
|
|
35446
35486
|
let path3;
|
|
35447
35487
|
try {
|
|
35448
|
-
const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.
|
|
35488
|
+
const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.5", onlyMe: this.options.onlyMe ?? false, agent: this.options.agent ?? null, capabilities: ["workspaces"] });
|
|
35449
35489
|
path3 = ticket.path;
|
|
35450
35490
|
} catch (error62) {
|
|
35451
35491
|
if (error62 instanceof CliError && ["unauthenticated", "not_found", "forbidden", "bad_request"].includes(error62.code)) {
|
|
@@ -37479,17 +37519,17 @@ function hasHarnessSetup() {
|
|
|
37479
37519
|
function syncMachineSetupAfterUpdate() {
|
|
37480
37520
|
const nothing = { skills: [], retired: [], reinstalling: false };
|
|
37481
37521
|
try {
|
|
37482
|
-
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.
|
|
37522
|
+
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.5") return nothing;
|
|
37483
37523
|
const lock = claimFileLock(buildMachineSetupLockDirectory(), { staleAfterMs: 6e4 });
|
|
37484
37524
|
if (!lock) return nothing;
|
|
37485
37525
|
try {
|
|
37486
37526
|
const state = fetchMachineSetupState();
|
|
37487
|
-
if (state?.version === "0.9.
|
|
37527
|
+
if (state?.version === "0.9.5") return nothing;
|
|
37488
37528
|
const skills = hasInstalledSkills() ? installSkills() : [];
|
|
37489
37529
|
const shipped = Object.keys(SKILLS);
|
|
37490
37530
|
const retired = deleteRetiredSkills((state?.skills ?? []).filter((name) => !shipped.includes(name)));
|
|
37491
37531
|
const setupRevision = state?.setupRevision ?? (hasHarnessSetup() ? UNRECORDED_SETUP_REVISION : null);
|
|
37492
|
-
persistMachineSetupState({ version: "0.9.
|
|
37532
|
+
persistMachineSetupState({ version: "0.9.5", setupRevision, skills: hasInstalledSkills() ? shipped : [] });
|
|
37493
37533
|
const reinstalling = setupRevision !== null && setupRevision < SETUP_REVISION && runMcpInstallInBackground();
|
|
37494
37534
|
return { skills, retired, reinstalling };
|
|
37495
37535
|
} finally {
|
|
@@ -37656,7 +37696,7 @@ async function trustCodexHooks(codexHome) {
|
|
|
37656
37696
|
const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
|
|
37657
37697
|
`);
|
|
37658
37698
|
try {
|
|
37659
|
-
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.
|
|
37699
|
+
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.5" }, capabilities: { experimentalApi: true } });
|
|
37660
37700
|
sendNotification("initialized", {});
|
|
37661
37701
|
const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
|
|
37662
37702
|
const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
|
|
@@ -37689,18 +37729,27 @@ function registerMcpInstallCommand(mcp) {
|
|
|
37689
37729
|
}
|
|
37690
37730
|
|
|
37691
37731
|
// src/commands/mcp.ts
|
|
37692
|
-
function buildTools(lifecycle) {
|
|
37693
|
-
if (isNonInteractiveHarness()) return { tools: [], startPresence: () => void 0, releaseSessions: () => void 0 };
|
|
37732
|
+
function buildTools(lifecycle, relay) {
|
|
37733
|
+
if (isNonInteractiveHarness()) return { tools: [], startPresence: () => void 0, releaseSessions: () => void 0, observeToolCall: () => void 0 };
|
|
37694
37734
|
let api = null;
|
|
37695
37735
|
const requireApi = () => api ??= buildAuthedApiClient();
|
|
37696
37736
|
let identity = null;
|
|
37737
|
+
let called = relay ? fetchRelayConversation(relay) : null;
|
|
37738
|
+
const observeToolCall = (meta3) => {
|
|
37739
|
+
if (called) return;
|
|
37740
|
+
const thread = parseCodexThreadFromToolCallMeta(meta3);
|
|
37741
|
+
if (!thread) return;
|
|
37742
|
+
called = { id: fetchCodexChatThreadId(fetchCodexHomes().map((home) => join26(home, "sessions")), thread), harness: "codex" };
|
|
37743
|
+
if (relay) persistRelayConversation(relay, called);
|
|
37744
|
+
};
|
|
37745
|
+
const fetchOwnConversation = () => called ?? fetchKnownConversation(process.cwd());
|
|
37697
37746
|
let stopped = false;
|
|
37698
37747
|
const projects = /* @__PURE__ */ new Map();
|
|
37699
37748
|
const requireProjectTools = (project) => {
|
|
37700
37749
|
if (stopped) throw new Error("The MCP server is stopping");
|
|
37701
37750
|
let context2 = projects.get(project.id);
|
|
37702
37751
|
if (!context2) {
|
|
37703
|
-
identity ??= resolveAgentIdentity(process.cwd());
|
|
37752
|
+
identity ??= resolveAgentIdentity(process.cwd(), "process", fetchOwnConversation());
|
|
37704
37753
|
context2 = createProjectTools(buildAuthedApiClient(), project, identity);
|
|
37705
37754
|
projects.set(project.id, context2);
|
|
37706
37755
|
}
|
|
@@ -37719,8 +37768,9 @@ function buildTools(lifecycle) {
|
|
|
37719
37768
|
if (presenceStarted) return;
|
|
37720
37769
|
presenceStarted = true;
|
|
37721
37770
|
void (async () => {
|
|
37722
|
-
for (let waited = 0; waited < 1e4 && !
|
|
37771
|
+
for (let waited = 0; waited < 1e4 && !fetchOwnConversation() && !stopped; waited += 250) await new Promise((resolve6) => setTimeout(resolve6, 250));
|
|
37723
37772
|
if (stopped) return;
|
|
37773
|
+
if (!identity && !fetchOwnConversation() && resolveParentHarness() === "codex") return;
|
|
37724
37774
|
await requireProjectTools(await resolveProject(requireApi())).start();
|
|
37725
37775
|
})().catch(() => void 0);
|
|
37726
37776
|
};
|
|
@@ -37728,6 +37778,7 @@ function buildTools(lifecycle) {
|
|
|
37728
37778
|
if (stopped) return;
|
|
37729
37779
|
stopped = true;
|
|
37730
37780
|
for (const context2 of projects.values()) context2.stop(reason);
|
|
37781
|
+
if (relay && reason === "released") deleteRelayConversation(relay);
|
|
37731
37782
|
};
|
|
37732
37783
|
let exiting = false;
|
|
37733
37784
|
const endSessionAndExit = (reason) => {
|
|
@@ -37739,7 +37790,7 @@ function buildTools(lifecycle) {
|
|
|
37739
37790
|
process.stdin.once("end", () => endSessionAndExit(lifecycle.onInputEnd));
|
|
37740
37791
|
process.stdin.once("close", () => endSessionAndExit(lifecycle.onInputEnd));
|
|
37741
37792
|
for (const signal of ["SIGTERM", "SIGHUP", "SIGINT"]) process.once(signal, () => endSessionAndExit("released"));
|
|
37742
|
-
return { tools: createProjectGroupedTools(runHandlerByName), startPresence, releaseSessions };
|
|
37793
|
+
return { tools: createProjectGroupedTools(runHandlerByName), startPresence, releaseSessions, observeToolCall };
|
|
37743
37794
|
}
|
|
37744
37795
|
function attachUpdateNoticeToTools(list) {
|
|
37745
37796
|
return list.map((tool) => ({
|
|
@@ -37754,10 +37805,12 @@ ${notice}` : result;
|
|
|
37754
37805
|
}));
|
|
37755
37806
|
}
|
|
37756
37807
|
function serveBoardTools(version2) {
|
|
37757
|
-
const
|
|
37808
|
+
const relay = drainRelayChildContextFromEnvironment();
|
|
37809
|
+
const underRelay = relay !== null;
|
|
37758
37810
|
const lifecycle = { onInputEnd: underRelay ? "orphaned" : "released" };
|
|
37759
|
-
const { tools, startPresence, releaseSessions } = buildTools(lifecycle);
|
|
37811
|
+
const { tools, startPresence, releaseSessions, observeToolCall } = buildTools(lifecycle, relay);
|
|
37760
37812
|
serveMcp(attachUpdateNoticeToTools(tools), { name: "slop", version: version2 }, {
|
|
37813
|
+
onToolCall: observeToolCall,
|
|
37761
37814
|
onNotification: (method) => {
|
|
37762
37815
|
if (method === RELAY_START_NOTIFICATION) startPresence();
|
|
37763
37816
|
else if (method === RELAY_HANDOVER_NOTIFICATION) {
|
|
@@ -37921,7 +37974,7 @@ var options = optionEnd < 0 ? args : args.slice(0, optionEnd);
|
|
|
37921
37974
|
updateJsonMode(options.includes("--json"));
|
|
37922
37975
|
syncMachineSetupAfterUpdate();
|
|
37923
37976
|
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.
|
|
37977
|
+
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.5").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
|
|
37925
37978
|
outputError: (message, write) => {
|
|
37926
37979
|
if (!isJsonMode()) write(message);
|
|
37927
37980
|
},
|
|
@@ -37938,7 +37991,7 @@ var sessionCommand = registerSessionCommands(program2);
|
|
|
37938
37991
|
registerThreadCommands(program2, taskCommand);
|
|
37939
37992
|
registerOperationCommands(program2, taskCommand, sessionCommand);
|
|
37940
37993
|
registerSplatCommands(program2);
|
|
37941
|
-
registerMcpCommands(program2, "0.9.
|
|
37994
|
+
registerMcpCommands(program2, "0.9.5");
|
|
37942
37995
|
registerGuideCommand(program2);
|
|
37943
37996
|
registerSkillCommands(program2);
|
|
37944
37997
|
registerUpdateCommand(program2);
|