slopwaresystems 0.5.0 → 0.6.0
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 +64 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26478,7 +26478,7 @@ var TaskEventRecord = external_exports.object({
|
|
|
26478
26478
|
|
|
26479
26479
|
// ../contract/src/work/sessions.ts
|
|
26480
26480
|
var AgentHarness = external_exports.enum(["claude", "codex", "cursor", "other"]);
|
|
26481
|
-
var WORKERS_PER_SESSION =
|
|
26481
|
+
var WORKERS_PER_SESSION = 200;
|
|
26482
26482
|
var WORKER_LABEL_MAX = 80;
|
|
26483
26483
|
var DOING_MAX = 120;
|
|
26484
26484
|
var SessionWorker = external_exports.object({
|
|
@@ -26490,6 +26490,13 @@ var SessionWorker = external_exports.object({
|
|
|
26490
26490
|
doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
|
|
26491
26491
|
since: Timestamp
|
|
26492
26492
|
});
|
|
26493
|
+
var SessionWorkerEntry = SessionWorker.omit({ doing: true });
|
|
26494
|
+
var SessionWorkerLine = external_exports.object({ ref: SessionWorker.shape.ref, doing: SessionWorker.shape.doing });
|
|
26495
|
+
var SessionRoster = external_exports.object({ workers: external_exports.array(SessionWorkerEntry).max(WORKERS_PER_SESSION) });
|
|
26496
|
+
var SessionDoing = external_exports.object({
|
|
26497
|
+
doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
|
|
26498
|
+
lines: external_exports.array(SessionWorkerLine).max(WORKERS_PER_SESSION).default([])
|
|
26499
|
+
});
|
|
26493
26500
|
var SessionActivity = external_exports.object({
|
|
26494
26501
|
doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
|
|
26495
26502
|
workers: external_exports.array(SessionWorker).max(WORKERS_PER_SESSION).default([])
|
|
@@ -26543,12 +26550,18 @@ var SessionPush = external_exports.discriminatedUnion("type", [
|
|
|
26543
26550
|
external_exports.object({ type: external_exports.literal("reachable"), on: external_exports.boolean() }),
|
|
26544
26551
|
/** Whether anyone is looking at this project's board. Off, an agent stops saying what it is doing. */
|
|
26545
26552
|
external_exports.object({ type: external_exports.literal("watched"), on: external_exports.boolean() }),
|
|
26546
|
-
/** To board watchers:
|
|
26547
|
-
|
|
26553
|
+
/** To board watchers: one agent's workers now, replacing the ones before. Carries its own payload; nothing to refetch. */
|
|
26554
|
+
SessionRoster.extend({ type: external_exports.literal("workers"), session: Id }),
|
|
26555
|
+
/** To board watchers: what one agent is doing now, and the lines of its workers that changed. Nothing to refetch. */
|
|
26556
|
+
SessionDoing.extend({ type: external_exports.literal("doing"), session: Id }),
|
|
26548
26557
|
/** To board watchers: something in the project changed; refetch. */
|
|
26549
26558
|
external_exports.object({ type: external_exports.literal("changed"), scope: external_exports.string() })
|
|
26550
26559
|
]);
|
|
26551
|
-
var SessionUp = external_exports.discriminatedUnion("type", [
|
|
26560
|
+
var SessionUp = external_exports.discriminatedUnion("type", [
|
|
26561
|
+
SessionRoster.extend({ type: external_exports.literal("workers") }),
|
|
26562
|
+
SessionDoing.extend({ type: external_exports.literal("doing") }),
|
|
26563
|
+
SessionActivity.extend({ type: external_exports.literal("activity") })
|
|
26564
|
+
]);
|
|
26552
26565
|
var SessionMessagesInput = external_exports.object({ cursor: external_exports.coerce.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional() });
|
|
26553
26566
|
var SessionMessages = external_exports.object({
|
|
26554
26567
|
cursor: external_exports.number().int().nonnegative(),
|
|
@@ -29141,8 +29154,6 @@ var HeldSession = class {
|
|
|
29141
29154
|
delivered = /* @__PURE__ */ new Set();
|
|
29142
29155
|
/** A Worker older than this CLI refuses what it does not know. One refusal is enough: stop saying it. */
|
|
29143
29156
|
upstreamRefused = false;
|
|
29144
|
-
/** Whether this socket has been told anything about what the agent is doing; a new socket knows nothing again. */
|
|
29145
|
-
toldThisSocket = false;
|
|
29146
29157
|
identity;
|
|
29147
29158
|
session = null;
|
|
29148
29159
|
/**
|
|
@@ -29205,7 +29216,6 @@ var HeldSession = class {
|
|
|
29205
29216
|
return;
|
|
29206
29217
|
}
|
|
29207
29218
|
greeted = true;
|
|
29208
|
-
this.toldThisSocket = false;
|
|
29209
29219
|
this.api.sessionId = push.session.id;
|
|
29210
29220
|
this.session = push.session;
|
|
29211
29221
|
this.taskKey = push.session.taskKey;
|
|
@@ -29288,16 +29298,16 @@ var HeldSession = class {
|
|
|
29288
29298
|
}
|
|
29289
29299
|
}
|
|
29290
29300
|
/**
|
|
29291
|
-
* Says
|
|
29292
|
-
* true now, and the
|
|
29301
|
+
* Says who this agent's workers are, or what it and they are doing. Dropped when the socket is not up: the room
|
|
29302
|
+
* holds only what is true now, and the reporter says it all again after the next hello. The reporter says only what
|
|
29303
|
+
* changed, so an agent with no subagents that nobody is watching sends nothing at all, which is most agents most of
|
|
29304
|
+
* the time. The only thing this client ever sends but a ping.
|
|
29293
29305
|
*/
|
|
29294
|
-
reportActivity(
|
|
29306
|
+
reportActivity(message) {
|
|
29295
29307
|
const socket = this.socket;
|
|
29296
29308
|
if (this.stopped || this.upstreamRefused || !this.session || !socket || socket.readyState !== WebSocket.OPEN) return;
|
|
29297
|
-
if (!this.toldThisSocket && activity.doing === null && activity.workers.length === 0) return;
|
|
29298
29309
|
try {
|
|
29299
|
-
socket.send(JSON.stringify(
|
|
29300
|
-
this.toldThisSocket = true;
|
|
29310
|
+
socket.send(JSON.stringify(message));
|
|
29301
29311
|
} catch {
|
|
29302
29312
|
}
|
|
29303
29313
|
}
|
|
@@ -29687,7 +29697,10 @@ var HarnessActivity = class {
|
|
|
29687
29697
|
watched = false;
|
|
29688
29698
|
discoveredAt = 0;
|
|
29689
29699
|
timer = null;
|
|
29690
|
-
|
|
29700
|
+
/** What the room knows: the roster it was last told, what this agent is doing, and each worker's line. */
|
|
29701
|
+
toldRoster = "[]";
|
|
29702
|
+
toldDoing = null;
|
|
29703
|
+
toldLines = /* @__PURE__ */ new Map();
|
|
29691
29704
|
stopped = false;
|
|
29692
29705
|
start() {
|
|
29693
29706
|
if (this.timer || this.stopped) return;
|
|
@@ -29702,9 +29715,11 @@ var HarnessActivity = class {
|
|
|
29702
29715
|
if (on) this.doing = null;
|
|
29703
29716
|
this.tick();
|
|
29704
29717
|
}
|
|
29705
|
-
/** Say it again:
|
|
29718
|
+
/** Say it again: a new socket starts knowing nothing, and only the agent can refill it. */
|
|
29706
29719
|
repeat() {
|
|
29707
|
-
this.
|
|
29720
|
+
this.toldRoster = "[]";
|
|
29721
|
+
this.toldDoing = null;
|
|
29722
|
+
this.toldLines.clear();
|
|
29708
29723
|
this.tick();
|
|
29709
29724
|
}
|
|
29710
29725
|
stop() {
|
|
@@ -29726,11 +29741,20 @@ var HarnessActivity = class {
|
|
|
29726
29741
|
} catch {
|
|
29727
29742
|
}
|
|
29728
29743
|
}
|
|
29729
|
-
const
|
|
29730
|
-
const said = JSON.stringify(
|
|
29731
|
-
if (said
|
|
29732
|
-
|
|
29733
|
-
|
|
29744
|
+
const roster = this.buildRoster();
|
|
29745
|
+
const said = JSON.stringify(roster);
|
|
29746
|
+
if (said !== this.toldRoster) {
|
|
29747
|
+
this.toldRoster = said;
|
|
29748
|
+
const refs = new Set(roster.map((worker) => worker.ref));
|
|
29749
|
+
for (const ref of [...this.toldLines.keys()]) if (!refs.has(ref)) this.toldLines.delete(ref);
|
|
29750
|
+
this.onReport({ type: "workers", workers: roster });
|
|
29751
|
+
}
|
|
29752
|
+
const doing = this.watched ? this.doing : null;
|
|
29753
|
+
const changed = this.buildWorkerLines(roster, now).filter((line) => (this.toldLines.get(line.ref) ?? null) !== line.doing);
|
|
29754
|
+
if (changed.length === 0 && doing === this.toldDoing) return;
|
|
29755
|
+
this.toldDoing = doing;
|
|
29756
|
+
for (const line of changed) this.toldLines.set(line.ref, line.doing);
|
|
29757
|
+
this.onReport({ type: "doing", doing, lines: changed });
|
|
29734
29758
|
}
|
|
29735
29759
|
/** Which files to read: this chat's own, and one per worker still working. */
|
|
29736
29760
|
discover(now) {
|
|
@@ -29772,10 +29796,19 @@ var HarnessActivity = class {
|
|
|
29772
29796
|
}
|
|
29773
29797
|
for (const worker of this.workers.values()) worker.doing = findNewestCall(worker.tail) ?? worker.doing;
|
|
29774
29798
|
}
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
|
|
29799
|
+
/**
|
|
29800
|
+
* Every worker, oldest first, so the roster changes only when one starts or finishes and never because one got
|
|
29801
|
+
* busy. The contract's guard is far past what a harness runs; past it, the oldest are the ones listed.
|
|
29802
|
+
*/
|
|
29803
|
+
buildRoster() {
|
|
29804
|
+
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, since: worker.since }));
|
|
29805
|
+
}
|
|
29806
|
+
/** Quiet for a while: still listed, because it is probably thinking, but saying nothing about what it is doing. */
|
|
29807
|
+
buildWorkerLines(roster, now) {
|
|
29808
|
+
return roster.map(({ ref }) => {
|
|
29809
|
+
const worker = this.workers.get(ref);
|
|
29810
|
+
return { ref, doing: this.watched && now - worker.changedAt < WORKER_FRESH_MS ? worker.doing : null };
|
|
29811
|
+
});
|
|
29779
29812
|
}
|
|
29780
29813
|
};
|
|
29781
29814
|
|
|
@@ -31088,11 +31121,7 @@ function createProjectTools(api, project, identity) {
|
|
|
31088
31121
|
const requireOwnSession = () => {
|
|
31089
31122
|
if (!canHoldOwnSession()) throw new Error(SPAWNED_BY_ANOTHER_AGENT);
|
|
31090
31123
|
};
|
|
31091
|
-
|
|
31092
|
-
const activity = new HarnessActivity({ id: identity.conversation, harness: identity.harness }, (report) => {
|
|
31093
|
-
told = report;
|
|
31094
|
-
held?.reportActivity(report);
|
|
31095
|
-
});
|
|
31124
|
+
const activity = new HarnessActivity({ id: identity.conversation, harness: identity.harness }, (report) => held?.reportActivity(report));
|
|
31096
31125
|
let waking = false;
|
|
31097
31126
|
const wakeOwnHarness = () => {
|
|
31098
31127
|
if (waking || stopped) return;
|
|
@@ -31126,10 +31155,8 @@ function createProjectTools(api, project, identity) {
|
|
|
31126
31155
|
onMessage: wakeOwnHarness,
|
|
31127
31156
|
claim: resolveOwnAgentIdentity,
|
|
31128
31157
|
onReconnect: () => recovery.sync(),
|
|
31129
|
-
//
|
|
31130
|
-
onHello: () =>
|
|
31131
|
-
if (told) held?.reportActivity(told);
|
|
31132
|
-
},
|
|
31158
|
+
// A new socket starts knowing nothing about the workers: whatever is true is said again on it.
|
|
31159
|
+
onHello: () => activity.repeat(),
|
|
31133
31160
|
onWatched: (on) => activity.setWatched(on)
|
|
31134
31161
|
});
|
|
31135
31162
|
activity.start();
|
|
@@ -32259,7 +32286,7 @@ async function trustCodexHooks(codexHome) {
|
|
|
32259
32286
|
const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
|
|
32260
32287
|
`);
|
|
32261
32288
|
try {
|
|
32262
|
-
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.
|
|
32289
|
+
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.6.0" }, capabilities: { experimentalApi: true } });
|
|
32263
32290
|
sendNotification("initialized", {});
|
|
32264
32291
|
const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
|
|
32265
32292
|
const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
|
|
@@ -32460,7 +32487,7 @@ ${written.map((path3) => ` ${path3}`).join("\n")}`);
|
|
|
32460
32487
|
var args = process.argv.slice(2);
|
|
32461
32488
|
var optionEnd = args.indexOf("--");
|
|
32462
32489
|
updateJsonMode((optionEnd < 0 ? args : args.slice(0, optionEnd)).includes("--json"));
|
|
32463
|
-
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.
|
|
32490
|
+
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.6.0").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
|
|
32464
32491
|
outputError: (message, write) => {
|
|
32465
32492
|
if (!isJsonMode()) write(message);
|
|
32466
32493
|
},
|
|
@@ -32476,7 +32503,7 @@ var taskCommand = registerTaskCommands(program2);
|
|
|
32476
32503
|
var sessionCommand = registerSessionCommands(program2);
|
|
32477
32504
|
registerThreadCommands(program2, taskCommand);
|
|
32478
32505
|
registerOperationCommands(program2, taskCommand, sessionCommand);
|
|
32479
|
-
registerMcpCommands(program2, "0.
|
|
32506
|
+
registerMcpCommands(program2, "0.6.0");
|
|
32480
32507
|
registerGuideCommand(program2);
|
|
32481
32508
|
registerSkillCommands(program2);
|
|
32482
32509
|
program2.parseAsync().catch(exitWithError);
|