slopwaresystems 0.9.5 → 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 +77 -29
- 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) {
|
|
@@ -29495,7 +29495,7 @@ function resolveAgentIdentity(cwd, fallback = "process", conversation = fetchKno
|
|
|
29495
29495
|
harness: conversation?.harness ?? null,
|
|
29496
29496
|
directory: repo ? basename3(repo.worktree) : basename3(cwd),
|
|
29497
29497
|
branch: fetchCurrentBranch(cwd),
|
|
29498
|
-
cliVersion: "0.9.
|
|
29498
|
+
cliVersion: "0.9.6"
|
|
29499
29499
|
};
|
|
29500
29500
|
}
|
|
29501
29501
|
|
|
@@ -30163,7 +30163,7 @@ function buildUpdateNotice() {
|
|
|
30163
30163
|
}
|
|
30164
30164
|
function resolveLatestCliVersion() {
|
|
30165
30165
|
const deprecated = fetchDeprecatedVersions();
|
|
30166
|
-
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;
|
|
30167
30167
|
}
|
|
30168
30168
|
function formatAgentCliVersion(version2, latest = resolveLatestCliVersion()) {
|
|
30169
30169
|
const label = version2 ? `slop ${version2}` : "an older slop";
|
|
@@ -30599,7 +30599,7 @@ async function updateInstalledCliFromRegistry(launcher, options2) {
|
|
|
30599
30599
|
const running = fetchLaunchCandidate(launcher).version;
|
|
30600
30600
|
const action = running === previous ? "current" : isNewerVersion(running, previous) ? "updated" : "rolled-back";
|
|
30601
30601
|
const latest = resolveNewestOfferedRelease(index);
|
|
30602
|
-
deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.
|
|
30602
|
+
deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.6"]));
|
|
30603
30603
|
persistUpdateStatus({ checkedAt: now(), latest, failures: 0, lastError: null });
|
|
30604
30604
|
return { action, running, previous, latest };
|
|
30605
30605
|
} catch (error62) {
|
|
@@ -31406,7 +31406,7 @@ function watchLaunchTarget(onChange) {
|
|
|
31406
31406
|
}
|
|
31407
31407
|
function runMcpRelay() {
|
|
31408
31408
|
const launcher = readLauncherInfo();
|
|
31409
|
-
const own2 = { version: "0.9.
|
|
31409
|
+
const own2 = { version: "0.9.6", main: fileURLToPath(import.meta.url), downloaded: false };
|
|
31410
31410
|
const relay = new McpRelay({
|
|
31411
31411
|
input: process.stdin,
|
|
31412
31412
|
output: process.stdout,
|
|
@@ -31847,7 +31847,7 @@ async function waitForMessage(api, projectId, taskKey, options2 = {}) {
|
|
|
31847
31847
|
setTimeout(() => resolve6(outcome), 50);
|
|
31848
31848
|
};
|
|
31849
31849
|
const held = new HeldSession(api, projectId, taskKey, {
|
|
31850
|
-
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" },
|
|
31851
31851
|
reconnect: false,
|
|
31852
31852
|
onHello: options2.onHello,
|
|
31853
31853
|
onEnd: () => finishWait({ kind: "ended" }),
|
|
@@ -32158,7 +32158,6 @@ var WORKER_FRESH_MS = 12e4;
|
|
|
32158
32158
|
var WORKER_GONE_MS = 3e5;
|
|
32159
32159
|
var READ_CAP = 256 * 1024;
|
|
32160
32160
|
var CARRY_CAP = 64 * 1024;
|
|
32161
|
-
var CHILD_SCAN_CAP = 40;
|
|
32162
32161
|
var DISCOVER_EVERY_MS = 1e4;
|
|
32163
32162
|
var TAIL_EVERY_MS = 1e3;
|
|
32164
32163
|
var truncate = (text, cap) => text.length <= cap ? text : `${text.slice(0, cap - 1)}\u2026`;
|
|
@@ -32292,7 +32291,33 @@ function parseModelFromCodexLine(line) {
|
|
|
32292
32291
|
if (entry.type !== "turn_context" || typeof model !== "string" || !model.trim()) return null;
|
|
32293
32292
|
return truncate(model.trim(), MODEL_MAX);
|
|
32294
32293
|
}
|
|
32295
|
-
|
|
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 };
|
|
32296
32321
|
var fetchFileSize = (path3) => {
|
|
32297
32322
|
try {
|
|
32298
32323
|
return statSync7(path3).size;
|
|
@@ -32347,6 +32372,14 @@ function fetchModelFromFileTail(path3, parseModel) {
|
|
|
32347
32372
|
}
|
|
32348
32373
|
return null;
|
|
32349
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
|
+
}
|
|
32350
32383
|
var fetchChangedAt = (path3) => {
|
|
32351
32384
|
try {
|
|
32352
32385
|
return statSync7(path3).mtimeMs;
|
|
@@ -32422,7 +32455,7 @@ function parseCodexWorkerLabel(head) {
|
|
|
32422
32455
|
return parts.length ? truncate(parts.join(" \u2014 "), WORKER_LABEL_MAX) : null;
|
|
32423
32456
|
}
|
|
32424
32457
|
function findCodexChildRollouts(roots, parentThreadId, changedAfter) {
|
|
32425
|
-
const rollouts =
|
|
32458
|
+
const rollouts = /* @__PURE__ */ new Map();
|
|
32426
32459
|
const findRolloutsInDirectory = (directory, depth) => {
|
|
32427
32460
|
let entries;
|
|
32428
32461
|
try {
|
|
@@ -32440,12 +32473,13 @@ function findCodexChildRollouts(roots, parentThreadId, changedAfter) {
|
|
|
32440
32473
|
if (!ref || ref === parentThreadId) continue;
|
|
32441
32474
|
const changedAt = fetchChangedAt(path3);
|
|
32442
32475
|
if (changedAt < changedAfter) continue;
|
|
32443
|
-
rollouts.
|
|
32476
|
+
if (!rollouts.has(ref)) rollouts.set(ref, { path: path3, ref, changedAt });
|
|
32444
32477
|
}
|
|
32445
32478
|
};
|
|
32446
32479
|
for (const root of roots) findRolloutsInDirectory(root, 0);
|
|
32447
32480
|
const found = [];
|
|
32448
|
-
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;
|
|
32449
32483
|
const head = fetchFileHead(rollout.path, HEAD_BYTES).split("\n")[0] ?? "";
|
|
32450
32484
|
if (!head.includes('"session_meta"') || isCodexHelperRollout(head)) continue;
|
|
32451
32485
|
if (!new RegExp(`"parent_thread_id"\\s*:\\s*"${parentThreadId}"`).test(head)) continue;
|
|
@@ -32537,7 +32571,10 @@ var HarnessActivity = class {
|
|
|
32537
32571
|
for (const file2 of found) {
|
|
32538
32572
|
const known = this.workers.get(file2.ref);
|
|
32539
32573
|
if (known) Object.assign(known, { label: file2.label, directory: file2.directory, branch: file2.branch, changedAt: file2.changedAt });
|
|
32540
|
-
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
|
+
}
|
|
32541
32578
|
}
|
|
32542
32579
|
const live = new Set(found.map((file2) => file2.ref));
|
|
32543
32580
|
for (const ref of [...this.workers.keys()]) if (!live.has(ref)) this.workers.delete(ref);
|
|
@@ -32562,35 +32599,39 @@ var HarnessActivity = class {
|
|
|
32562
32599
|
}
|
|
32563
32600
|
return [];
|
|
32564
32601
|
}
|
|
32565
|
-
/** The newest tool call and
|
|
32602
|
+
/** The newest tool call, model and turn state in everything that has been written since the last read. */
|
|
32566
32603
|
read() {
|
|
32567
|
-
const { parseToolCall, parseModel } = this.parsers;
|
|
32568
|
-
const
|
|
32604
|
+
const { parseToolCall, parseModel, parseTurnState } = this.parsers;
|
|
32605
|
+
const fetchNewestCallModelAndTurnState = (tail) => {
|
|
32569
32606
|
let call = null;
|
|
32570
32607
|
let model = null;
|
|
32608
|
+
let turn = null;
|
|
32571
32609
|
for (const line of tail.fetchNewLines()) {
|
|
32572
32610
|
call = parseToolCall(line) ?? call;
|
|
32573
32611
|
model = parseModel(line) ?? model;
|
|
32612
|
+
turn = parseTurnState(line) ?? turn;
|
|
32574
32613
|
}
|
|
32575
|
-
return { call, model };
|
|
32614
|
+
return { call, model, turn };
|
|
32576
32615
|
};
|
|
32577
32616
|
if (this.own) {
|
|
32578
|
-
const { call, model } =
|
|
32617
|
+
const { call, model } = fetchNewestCallModelAndTurnState(this.own);
|
|
32579
32618
|
this.doing = call ?? this.doing;
|
|
32580
32619
|
this.model = model ?? this.model;
|
|
32581
32620
|
}
|
|
32582
32621
|
for (const worker of this.workers.values()) {
|
|
32583
|
-
const { call, model } =
|
|
32622
|
+
const { call, model, turn } = fetchNewestCallModelAndTurnState(worker.tail);
|
|
32584
32623
|
worker.doing = call ?? worker.doing;
|
|
32585
32624
|
worker.model = model ?? worker.model;
|
|
32625
|
+
if (turn) worker.finished = turn === "finished";
|
|
32586
32626
|
}
|
|
32587
32627
|
}
|
|
32588
32628
|
/**
|
|
32589
|
-
* Every worker, oldest first, so the roster changes only when one starts or finishes and never
|
|
32590
|
-
*
|
|
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.
|
|
32591
32632
|
*/
|
|
32592
32633
|
buildRoster() {
|
|
32593
|
-
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 }));
|
|
32594
32635
|
}
|
|
32595
32636
|
/** Quiet for a while: still listed, because it is probably thinking, but saying nothing about what it is doing. */
|
|
32596
32637
|
buildWorkerLines(roster, now) {
|
|
@@ -35485,7 +35526,7 @@ var SplatRendererConnection = class {
|
|
|
35485
35526
|
try {
|
|
35486
35527
|
let path3;
|
|
35487
35528
|
try {
|
|
35488
|
-
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"] });
|
|
35489
35530
|
path3 = ticket.path;
|
|
35490
35531
|
} catch (error62) {
|
|
35491
35532
|
if (error62 instanceof CliError && ["unauthenticated", "not_found", "forbidden", "bad_request"].includes(error62.code)) {
|
|
@@ -37519,17 +37560,17 @@ function hasHarnessSetup() {
|
|
|
37519
37560
|
function syncMachineSetupAfterUpdate() {
|
|
37520
37561
|
const nothing = { skills: [], retired: [], reinstalling: false };
|
|
37521
37562
|
try {
|
|
37522
|
-
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.
|
|
37563
|
+
if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.6") return nothing;
|
|
37523
37564
|
const lock = claimFileLock(buildMachineSetupLockDirectory(), { staleAfterMs: 6e4 });
|
|
37524
37565
|
if (!lock) return nothing;
|
|
37525
37566
|
try {
|
|
37526
37567
|
const state = fetchMachineSetupState();
|
|
37527
|
-
if (state?.version === "0.9.
|
|
37568
|
+
if (state?.version === "0.9.6") return nothing;
|
|
37528
37569
|
const skills = hasInstalledSkills() ? installSkills() : [];
|
|
37529
37570
|
const shipped = Object.keys(SKILLS);
|
|
37530
37571
|
const retired = deleteRetiredSkills((state?.skills ?? []).filter((name) => !shipped.includes(name)));
|
|
37531
37572
|
const setupRevision = state?.setupRevision ?? (hasHarnessSetup() ? UNRECORDED_SETUP_REVISION : null);
|
|
37532
|
-
persistMachineSetupState({ version: "0.9.
|
|
37573
|
+
persistMachineSetupState({ version: "0.9.6", setupRevision, skills: hasInstalledSkills() ? shipped : [] });
|
|
37533
37574
|
const reinstalling = setupRevision !== null && setupRevision < SETUP_REVISION && runMcpInstallInBackground();
|
|
37534
37575
|
return { skills, retired, reinstalling };
|
|
37535
37576
|
} finally {
|
|
@@ -37696,7 +37737,7 @@ async function trustCodexHooks(codexHome) {
|
|
|
37696
37737
|
const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
|
|
37697
37738
|
`);
|
|
37698
37739
|
try {
|
|
37699
|
-
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.
|
|
37740
|
+
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.6" }, capabilities: { experimentalApi: true } });
|
|
37700
37741
|
sendNotification("initialized", {});
|
|
37701
37742
|
const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
|
|
37702
37743
|
const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
|
|
@@ -37749,7 +37790,14 @@ function buildTools(lifecycle, relay) {
|
|
|
37749
37790
|
if (stopped) throw new Error("The MCP server is stopping");
|
|
37750
37791
|
let context2 = projects.get(project.id);
|
|
37751
37792
|
if (!context2) {
|
|
37752
|
-
|
|
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
|
+
}
|
|
37753
37801
|
context2 = createProjectTools(buildAuthedApiClient(), project, identity);
|
|
37754
37802
|
projects.set(project.id, context2);
|
|
37755
37803
|
}
|
|
@@ -37974,7 +38022,7 @@ var options = optionEnd < 0 ? args : args.slice(0, optionEnd);
|
|
|
37974
38022
|
updateJsonMode(options.includes("--json"));
|
|
37975
38023
|
syncMachineSetupAfterUpdate();
|
|
37976
38024
|
if (!options.includes("--background") && !options.includes("--child")) scheduleBackgroundUpdate();
|
|
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.
|
|
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({
|
|
37978
38026
|
outputError: (message, write) => {
|
|
37979
38027
|
if (!isJsonMode()) write(message);
|
|
37980
38028
|
},
|
|
@@ -37991,7 +38039,7 @@ var sessionCommand = registerSessionCommands(program2);
|
|
|
37991
38039
|
registerThreadCommands(program2, taskCommand);
|
|
37992
38040
|
registerOperationCommands(program2, taskCommand, sessionCommand);
|
|
37993
38041
|
registerSplatCommands(program2);
|
|
37994
|
-
registerMcpCommands(program2, "0.9.
|
|
38042
|
+
registerMcpCommands(program2, "0.9.6");
|
|
37995
38043
|
registerGuideCommand(program2);
|
|
37996
38044
|
registerSkillCommands(program2);
|
|
37997
38045
|
registerUpdateCommand(program2);
|