slopwaresystems 0.4.15 → 0.4.16
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 +231 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27144,7 +27144,7 @@ function persistRememberedConversation(cwd, conversation) {
|
|
|
27144
27144
|
const directory = `${buildConversationPath(cwd)}.d`;
|
|
27145
27145
|
persistLocalState(join3(directory, `${generateLocalStateKey(cwd, conversation.id)}.json`), JSON.stringify(conversation));
|
|
27146
27146
|
}
|
|
27147
|
-
function fetchRememberedConversation(cwd, notBefore) {
|
|
27147
|
+
function fetchRememberedConversation(cwd, notBefore, harness) {
|
|
27148
27148
|
const path2 = buildConversationPath(cwd);
|
|
27149
27149
|
const candidates = [];
|
|
27150
27150
|
let paths;
|
|
@@ -27158,12 +27158,13 @@ function fetchRememberedConversation(cwd, notBefore) {
|
|
|
27158
27158
|
try {
|
|
27159
27159
|
if (statSync(candidate).mtimeMs < notBefore) continue;
|
|
27160
27160
|
const parsed = JSON.parse(readFileSync3(candidate, "utf8"));
|
|
27161
|
-
const
|
|
27162
|
-
if (typeof parsed.id === "string" && parsed.id &&
|
|
27161
|
+
const wrote = AgentHarness.safeParse(parsed.harness ?? "other");
|
|
27162
|
+
if (typeof parsed.id === "string" && parsed.id && wrote.success) candidates.push({ id: parsed.id, harness: wrote.data });
|
|
27163
27163
|
} catch {
|
|
27164
27164
|
}
|
|
27165
27165
|
}
|
|
27166
|
-
const
|
|
27166
|
+
const mine = harness ? candidates.filter((candidate) => candidate.harness === harness) : candidates;
|
|
27167
|
+
const distinct = [...new Map((mine.length ? mine : candidates).map((candidate) => [candidate.id, candidate])).values()];
|
|
27167
27168
|
return distinct.length === 1 ? distinct[0] : null;
|
|
27168
27169
|
}
|
|
27169
27170
|
|
|
@@ -27497,6 +27498,109 @@ function wakeCodexOverWs(text, threadId, endpoint) {
|
|
|
27497
27498
|
});
|
|
27498
27499
|
});
|
|
27499
27500
|
}
|
|
27501
|
+
var CURSOR_TURN_CAP_MS = 6e5;
|
|
27502
|
+
var CURSOR_LOAD_WITHIN_MS = 3e4;
|
|
27503
|
+
function wakeCursor(text, chatId, cwd, options = {}) {
|
|
27504
|
+
const binary = options.binary ?? "cursor-agent";
|
|
27505
|
+
return wakeCursorOverAcp(text, chatId, cwd, binary).then((woken) => woken || resumeCursorChat(text, chatId, cwd, binary));
|
|
27506
|
+
}
|
|
27507
|
+
function wakeCursorOverAcp(text, chatId, cwd, binary) {
|
|
27508
|
+
return new Promise((resolve6) => {
|
|
27509
|
+
let child;
|
|
27510
|
+
try {
|
|
27511
|
+
child = spawn(binary, ["acp"], { cwd, stdio: ["pipe", "pipe", "ignore"] });
|
|
27512
|
+
} catch {
|
|
27513
|
+
resolve6(false);
|
|
27514
|
+
return;
|
|
27515
|
+
}
|
|
27516
|
+
let settled = false;
|
|
27517
|
+
let nextId = 1;
|
|
27518
|
+
let buffer = "";
|
|
27519
|
+
const finishWake = (woken, keepRunning = false) => {
|
|
27520
|
+
if (settled) return;
|
|
27521
|
+
settled = true;
|
|
27522
|
+
clearTimeout(loadTimer);
|
|
27523
|
+
if (!keepRunning) child.kill();
|
|
27524
|
+
else setTimeout(() => child.kill(), CURSOR_TURN_CAP_MS).unref?.();
|
|
27525
|
+
resolve6(woken);
|
|
27526
|
+
};
|
|
27527
|
+
const loadTimer = setTimeout(() => finishWake(false), CURSOR_LOAD_WITHIN_MS);
|
|
27528
|
+
const send = (message) => {
|
|
27529
|
+
try {
|
|
27530
|
+
child.stdin?.write(`${JSON.stringify(message)}
|
|
27531
|
+
`);
|
|
27532
|
+
} catch {
|
|
27533
|
+
finishWake(false);
|
|
27534
|
+
}
|
|
27535
|
+
};
|
|
27536
|
+
const call = (method, params) => {
|
|
27537
|
+
const id = nextId++;
|
|
27538
|
+
send({ jsonrpc: "2.0", id, method, params });
|
|
27539
|
+
return id;
|
|
27540
|
+
};
|
|
27541
|
+
const initializeId = call("initialize", { protocolVersion: 1, clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false }, clientInfo: { name: "slop", version: "0.4.16" } });
|
|
27542
|
+
let loadId = 0;
|
|
27543
|
+
let promptId = 0;
|
|
27544
|
+
child.on("error", () => finishWake(false));
|
|
27545
|
+
child.on("exit", () => finishWake(false));
|
|
27546
|
+
child.stdout?.on("data", (chunk) => {
|
|
27547
|
+
buffer += chunk.toString("utf8");
|
|
27548
|
+
let index;
|
|
27549
|
+
while ((index = buffer.indexOf("\n")) >= 0) {
|
|
27550
|
+
const line = buffer.slice(0, index);
|
|
27551
|
+
buffer = buffer.slice(index + 1);
|
|
27552
|
+
if (!line.trim()) continue;
|
|
27553
|
+
let message;
|
|
27554
|
+
try {
|
|
27555
|
+
message = JSON.parse(line);
|
|
27556
|
+
} catch {
|
|
27557
|
+
continue;
|
|
27558
|
+
}
|
|
27559
|
+
if (message.id !== void 0 && message.method === "session/request_permission") {
|
|
27560
|
+
const options = message.params?.options ?? [];
|
|
27561
|
+
const allow = options.find((option) => option.kind === "allow_once") ?? options.find((option) => /allow|accept/i.test(option.optionId ?? "")) ?? options[0];
|
|
27562
|
+
send({ jsonrpc: "2.0", id: message.id, result: { outcome: { outcome: "selected", optionId: allow?.optionId ?? "allow" } } });
|
|
27563
|
+
continue;
|
|
27564
|
+
}
|
|
27565
|
+
if (message.id !== void 0 && message.method) {
|
|
27566
|
+
send({ jsonrpc: "2.0", id: message.id, result: {} });
|
|
27567
|
+
continue;
|
|
27568
|
+
}
|
|
27569
|
+
if (message.id === initializeId) {
|
|
27570
|
+
if (message.error) finishWake(false);
|
|
27571
|
+
else loadId = call("session/load", { sessionId: chatId, cwd, mcpServers: [] });
|
|
27572
|
+
continue;
|
|
27573
|
+
}
|
|
27574
|
+
if (message.id === loadId && loadId !== 0) {
|
|
27575
|
+
if (message.error) finishWake(false);
|
|
27576
|
+
else promptId = call("session/prompt", { sessionId: chatId, prompt: [{ type: "text", text }] });
|
|
27577
|
+
continue;
|
|
27578
|
+
}
|
|
27579
|
+
if (promptId !== 0 && (message.id === promptId || message.method === "session/update")) finishWake(true, true);
|
|
27580
|
+
}
|
|
27581
|
+
});
|
|
27582
|
+
});
|
|
27583
|
+
}
|
|
27584
|
+
function resumeCursorChat(text, chatId, cwd, binary) {
|
|
27585
|
+
return new Promise((resolve6) => {
|
|
27586
|
+
let child;
|
|
27587
|
+
try {
|
|
27588
|
+
child = spawn(binary, ["--resume", chatId, "-p", text, "--output-format", "text"], { cwd, stdio: ["ignore", "ignore", "ignore"] });
|
|
27589
|
+
} catch {
|
|
27590
|
+
resolve6(false);
|
|
27591
|
+
return;
|
|
27592
|
+
}
|
|
27593
|
+
const timer = setTimeout(() => resolve6(true), 5e3);
|
|
27594
|
+
child.on("error", () => {
|
|
27595
|
+
clearTimeout(timer);
|
|
27596
|
+
resolve6(false);
|
|
27597
|
+
});
|
|
27598
|
+
child.on("exit", (code) => {
|
|
27599
|
+
clearTimeout(timer);
|
|
27600
|
+
resolve6(code === 0);
|
|
27601
|
+
});
|
|
27602
|
+
});
|
|
27603
|
+
}
|
|
27500
27604
|
|
|
27501
27605
|
// src/platform/harness.ts
|
|
27502
27606
|
var AgentHarnessValues = AgentHarness.options;
|
|
@@ -27648,6 +27752,31 @@ function resolveCodexBinary() {
|
|
|
27648
27752
|
}
|
|
27649
27753
|
return "codex";
|
|
27650
27754
|
}
|
|
27755
|
+
function resolveParentHarness() {
|
|
27756
|
+
return parseHarnessFromCommand(fetchParentCommand());
|
|
27757
|
+
}
|
|
27758
|
+
var RETRY_ACP_AFTER_MS = 5e3;
|
|
27759
|
+
var acpSession = null;
|
|
27760
|
+
function fetchCursorAcpSessionByCwd(cwd, binary = "cursor-agent") {
|
|
27761
|
+
if (acpSession && (acpSession.id !== null || Date.now() - acpSession.at < RETRY_ACP_AFTER_MS)) return acpSession.id;
|
|
27762
|
+
acpSession = { id: null, at: Date.now() };
|
|
27763
|
+
const said = [
|
|
27764
|
+
{ jsonrpc: "2.0", id: 1, method: "initialize", params: { protocolVersion: 1, clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false }, clientInfo: { name: "slop", version: "0.4.16" } } },
|
|
27765
|
+
{ jsonrpc: "2.0", id: 2, method: "session/list", params: {} }
|
|
27766
|
+
];
|
|
27767
|
+
try {
|
|
27768
|
+
const answered = execFileSync3(binary, ["acp"], { input: `${said.map((message) => JSON.stringify(message)).join("\n")}
|
|
27769
|
+
`, encoding: "utf8", timeout: 15e3, stdio: ["pipe", "pipe", "ignore"], cwd });
|
|
27770
|
+
for (const line of answered.split("\n")) {
|
|
27771
|
+
if (!line.includes('"sessions"')) continue;
|
|
27772
|
+
const listed = JSON.parse(line).result?.sessions ?? [];
|
|
27773
|
+
const here = listed.filter((session) => typeof session.sessionId === "string" && typeof session.cwd === "string" && isSamePath(session.cwd, cwd));
|
|
27774
|
+
if (here.length === 1) acpSession = { id: here[0].sessionId, at: Date.now() };
|
|
27775
|
+
}
|
|
27776
|
+
} catch {
|
|
27777
|
+
}
|
|
27778
|
+
return acpSession.id;
|
|
27779
|
+
}
|
|
27651
27780
|
function fetchHarnessConversation(cwd) {
|
|
27652
27781
|
const explicit = process.env.SLOP_CONVERSATION_ID?.trim();
|
|
27653
27782
|
if (explicit) return { id: explicit, harness: AgentHarnessValues.includes(process.env.SLOP_HARNESS) ? process.env.SLOP_HARNESS : "other" };
|
|
@@ -27671,9 +27800,13 @@ var startedAt = Date.now();
|
|
|
27671
27800
|
function fetchKnownConversation(cwd) {
|
|
27672
27801
|
const own2 = fetchHarnessConversation(cwd);
|
|
27673
27802
|
if (own2) return own2;
|
|
27674
|
-
const remembered = fetchRememberedConversation(cwd, startedAt - 12e4);
|
|
27803
|
+
const remembered = fetchRememberedConversation(cwd, startedAt - 12e4, resolveParentHarness());
|
|
27675
27804
|
if (remembered?.harness === "codex" && isMainChatThread(fetchCodexHomes().map((home) => join8(home, "sessions")), remembered.id)) return remembered;
|
|
27676
|
-
|
|
27805
|
+
const known = remembered?.harness === "codex" ? null : remembered;
|
|
27806
|
+
if (known) return known;
|
|
27807
|
+
if (resolveParentHarness() !== "cursor") return null;
|
|
27808
|
+
const acp = fetchCursorAcpSessionByCwd(cwd);
|
|
27809
|
+
return acp ? { id: acp, harness: "cursor" } : null;
|
|
27677
27810
|
}
|
|
27678
27811
|
function resolveAgentIdentity(cwd, fallback = "process") {
|
|
27679
27812
|
const conversation = fetchKnownConversation(cwd);
|
|
@@ -28877,6 +29010,67 @@ function parseToolCallFromCodexLine(line) {
|
|
|
28877
29010
|
if (payload.type === "local_shell_call") return formatToolCallLine("shell", payload.action);
|
|
28878
29011
|
return null;
|
|
28879
29012
|
}
|
|
29013
|
+
function parseCursorTaskFromLine(line) {
|
|
29014
|
+
if (!line.includes("CallDynamicTool") || !line.includes('"Task"')) return null;
|
|
29015
|
+
let entry;
|
|
29016
|
+
try {
|
|
29017
|
+
entry = JSON.parse(line);
|
|
29018
|
+
} catch {
|
|
29019
|
+
return null;
|
|
29020
|
+
}
|
|
29021
|
+
const content = entry.message?.content;
|
|
29022
|
+
if (!Array.isArray(content)) return null;
|
|
29023
|
+
for (const block of content) {
|
|
29024
|
+
if (!block || typeof block !== "object") continue;
|
|
29025
|
+
const { type, name, input: input2 } = block;
|
|
29026
|
+
if (type !== "tool_use" || name !== "CallDynamicTool" || input2?.toolName !== "Task") continue;
|
|
29027
|
+
const asked = input2.arguments ?? {};
|
|
29028
|
+
const prompt = typeof asked.prompt === "string" ? asked.prompt : null;
|
|
29029
|
+
if (!prompt) continue;
|
|
29030
|
+
const label = [asked.subagent_type, asked.description].filter((part) => typeof part === "string" && part.trim() !== "").join(" \u2014 ");
|
|
29031
|
+
return { label: truncate(label || "subagent", WORKER_LABEL_MAX), prompt };
|
|
29032
|
+
}
|
|
29033
|
+
return null;
|
|
29034
|
+
}
|
|
29035
|
+
function parseCursorUserQuery(line) {
|
|
29036
|
+
let entry;
|
|
29037
|
+
try {
|
|
29038
|
+
entry = JSON.parse(line);
|
|
29039
|
+
} catch {
|
|
29040
|
+
return null;
|
|
29041
|
+
}
|
|
29042
|
+
const content = entry.message?.content;
|
|
29043
|
+
if (entry.role !== "user" || !Array.isArray(content)) return null;
|
|
29044
|
+
for (const block of content) {
|
|
29045
|
+
const text = block?.text;
|
|
29046
|
+
if (typeof text !== "string") continue;
|
|
29047
|
+
const asked = /<user_query>\s*([\s\S]*?)\s*<\/user_query>/.exec(text);
|
|
29048
|
+
if (asked?.[1]) return asked[1];
|
|
29049
|
+
}
|
|
29050
|
+
return null;
|
|
29051
|
+
}
|
|
29052
|
+
function findCursorWorkerFiles(transcriptPath, conversation, changedAfter, asked) {
|
|
29053
|
+
if (asked.length === 0) return [];
|
|
29054
|
+
const directory = dirname7(dirname7(transcriptPath));
|
|
29055
|
+
let chats;
|
|
29056
|
+
try {
|
|
29057
|
+
chats = readdirSync7(directory);
|
|
29058
|
+
} catch {
|
|
29059
|
+
return [];
|
|
29060
|
+
}
|
|
29061
|
+
const found = [];
|
|
29062
|
+
for (const chat of chats) {
|
|
29063
|
+
if (chat === conversation) continue;
|
|
29064
|
+
const path2 = join14(directory, chat, `${chat}.jsonl`);
|
|
29065
|
+
const changedAt = fetchChangedAt(path2);
|
|
29066
|
+
if (changedAt < changedAfter) continue;
|
|
29067
|
+
const query = parseCursorUserQuery(fetchFileHead(path2, 16 * 1024).split("\n")[0] ?? "");
|
|
29068
|
+
const task = query === null ? void 0 : asked.find((candidate) => candidate.prompt === query);
|
|
29069
|
+
if (!task) continue;
|
|
29070
|
+
found.push({ ref: chat, label: task.label, path: path2, directory: null, branch: null, changedAt });
|
|
29071
|
+
}
|
|
29072
|
+
return found.sort((a, b) => b.changedAt - a.changedAt);
|
|
29073
|
+
}
|
|
28880
29074
|
var fetchFileSize = (path2) => {
|
|
28881
29075
|
try {
|
|
28882
29076
|
return statSync4(path2).size;
|
|
@@ -29045,6 +29239,7 @@ function findCodexChildRollouts(roots, parentThreadId, changedAfter) {
|
|
|
29045
29239
|
}
|
|
29046
29240
|
return found;
|
|
29047
29241
|
}
|
|
29242
|
+
var ASKED_CAP = 16;
|
|
29048
29243
|
var HarnessActivity = class {
|
|
29049
29244
|
constructor(conversation, onReport) {
|
|
29050
29245
|
this.conversation = conversation;
|
|
@@ -29053,6 +29248,8 @@ var HarnessActivity = class {
|
|
|
29053
29248
|
conversation;
|
|
29054
29249
|
onReport;
|
|
29055
29250
|
workers = /* @__PURE__ */ new Map();
|
|
29251
|
+
/** What this chat has asked a subagent to do, which is how a Cursor chat's children are claimed. */
|
|
29252
|
+
asked = [];
|
|
29056
29253
|
own = null;
|
|
29057
29254
|
doing = null;
|
|
29058
29255
|
watched = false;
|
|
@@ -29070,10 +29267,7 @@ var HarnessActivity = class {
|
|
|
29070
29267
|
setWatched(on) {
|
|
29071
29268
|
if (on === this.watched) return;
|
|
29072
29269
|
this.watched = on;
|
|
29073
|
-
if (on)
|
|
29074
|
-
this.own = this.own && new FileTail(this.own.path);
|
|
29075
|
-
for (const worker of this.workers.values()) worker.tail = new FileTail(worker.path);
|
|
29076
|
-
}
|
|
29270
|
+
if (on) this.doing = null;
|
|
29077
29271
|
this.tick();
|
|
29078
29272
|
}
|
|
29079
29273
|
/** Say it again: the room forgets a session's activity when its socket drops, and only the agent can refill it. */
|
|
@@ -29089,6 +29283,10 @@ var HarnessActivity = class {
|
|
|
29089
29283
|
tick() {
|
|
29090
29284
|
if (this.stopped) return;
|
|
29091
29285
|
const now = Date.now();
|
|
29286
|
+
try {
|
|
29287
|
+
this.read();
|
|
29288
|
+
} catch {
|
|
29289
|
+
}
|
|
29092
29290
|
if (now - this.discoveredAt >= DISCOVER_EVERY_MS) {
|
|
29093
29291
|
this.discoveredAt = now;
|
|
29094
29292
|
try {
|
|
@@ -29096,12 +29294,6 @@ var HarnessActivity = class {
|
|
|
29096
29294
|
} catch {
|
|
29097
29295
|
}
|
|
29098
29296
|
}
|
|
29099
|
-
if (this.watched) {
|
|
29100
|
-
try {
|
|
29101
|
-
this.read();
|
|
29102
|
-
} catch {
|
|
29103
|
-
}
|
|
29104
|
-
}
|
|
29105
29297
|
const activity = this.build();
|
|
29106
29298
|
const said = JSON.stringify(activity);
|
|
29107
29299
|
if (said === this.reported) return;
|
|
@@ -29128,7 +29320,7 @@ var HarnessActivity = class {
|
|
|
29128
29320
|
if (this.conversation.harness === "cursor") {
|
|
29129
29321
|
const transcript = findCursorTranscriptPath(fetchCursorHomes(), this.conversation.id);
|
|
29130
29322
|
this.own ??= transcript ? new FileTail(transcript, "end") : null;
|
|
29131
|
-
return [];
|
|
29323
|
+
return transcript ? findCursorWorkerFiles(transcript, this.conversation.id, changedAfter, this.asked) : [];
|
|
29132
29324
|
}
|
|
29133
29325
|
if (this.conversation.harness === "codex") {
|
|
29134
29326
|
const roots = fetchCodexHomes().map((home) => join14(home, "sessions"));
|
|
@@ -29146,7 +29338,18 @@ var HarnessActivity = class {
|
|
|
29146
29338
|
for (const line of tail.fetchNewLines()) newest = parse3(line) ?? newest;
|
|
29147
29339
|
return newest;
|
|
29148
29340
|
};
|
|
29149
|
-
if (this.own)
|
|
29341
|
+
if (this.own) {
|
|
29342
|
+
let newest = null;
|
|
29343
|
+
for (const line of this.own.fetchNewLines()) {
|
|
29344
|
+
newest = parse3(line) ?? newest;
|
|
29345
|
+
const task = this.conversation.harness === "cursor" ? parseCursorTaskFromLine(line) : null;
|
|
29346
|
+
if (task) {
|
|
29347
|
+
this.asked.push(task);
|
|
29348
|
+
while (this.asked.length > ASKED_CAP) this.asked.shift();
|
|
29349
|
+
}
|
|
29350
|
+
}
|
|
29351
|
+
this.doing = newest ?? this.doing;
|
|
29352
|
+
}
|
|
29150
29353
|
for (const worker of this.workers.values()) worker.doing = findNewestCall(worker.tail) ?? worker.doing;
|
|
29151
29354
|
}
|
|
29152
29355
|
build() {
|
|
@@ -29708,7 +29911,7 @@ function createProjectTools(api, project, identity) {
|
|
|
29708
29911
|
if (waking || stopped) return;
|
|
29709
29912
|
waking = true;
|
|
29710
29913
|
const text = `Messages are waiting for you on Slopware Tasks in project ${project.key}. Use session check with project ${project.id} to read them, then act or reply only if it changes something. Do not acknowledge.`;
|
|
29711
|
-
const wake = identity.harness === "codex" && identity.conversation ? wakeCodex(text, identity.conversation, { binary: resolveCodexBinary(), codexHome: resolveOwnHarnessHome("CODEX_HOME") }) : identity.harness === "claude" ? wakeHarness(text, void 0, identity.conversation) : Promise.resolve(false);
|
|
29914
|
+
const wake = identity.harness === "codex" && identity.conversation ? wakeCodex(text, identity.conversation, { binary: resolveCodexBinary(), codexHome: resolveOwnHarnessHome("CODEX_HOME") }) : identity.harness === "claude" ? wakeHarness(text, void 0, identity.conversation) : identity.harness === "cursor" && identity.conversation ? wakeCursor(text, identity.conversation, process.cwd()) : Promise.resolve(false);
|
|
29712
29915
|
void wake.catch(() => false).finally(() => {
|
|
29713
29916
|
waking = false;
|
|
29714
29917
|
});
|
|
@@ -30269,7 +30472,7 @@ async function trustCodexHooks(codexHome) {
|
|
|
30269
30472
|
const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
|
|
30270
30473
|
`);
|
|
30271
30474
|
try {
|
|
30272
|
-
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.4.
|
|
30475
|
+
await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.4.16" }, capabilities: { experimentalApi: true } });
|
|
30273
30476
|
sendNotification("initialized", {});
|
|
30274
30477
|
const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
|
|
30275
30478
|
const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
|
|
@@ -30285,7 +30488,8 @@ async function trustCodexHooks(codexHome) {
|
|
|
30285
30488
|
server.kill();
|
|
30286
30489
|
}
|
|
30287
30490
|
}
|
|
30288
|
-
async function parseHookInput(
|
|
30491
|
+
async function parseHookInput(installedAs, remember = true) {
|
|
30492
|
+
const harness = resolveParentHarness() ?? installedAs;
|
|
30289
30493
|
const input2 = await new Promise((resolve6) => {
|
|
30290
30494
|
let data = "";
|
|
30291
30495
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
@@ -30302,7 +30506,7 @@ async function parseHookInput(harness, remember = true) {
|
|
|
30302
30506
|
}
|
|
30303
30507
|
const ownThread = harness !== "codex" || !conversation || isMainChatThread(fetchCodexHomes().map((home) => join16(home, "sessions")), conversation);
|
|
30304
30508
|
if (remember && conversation && ownThread && !isNonInteractiveHarness()) persistRememberedConversation(cwd, { id: conversation, harness: harness ?? "other" });
|
|
30305
|
-
return { cwd, conversation };
|
|
30509
|
+
return { cwd, conversation, harness };
|
|
30306
30510
|
}
|
|
30307
30511
|
async function runPromptHook(harness) {
|
|
30308
30512
|
await parseHookInput(harness);
|
|
@@ -30310,11 +30514,11 @@ async function runPromptHook(harness) {
|
|
|
30310
30514
|
async function runToolHook(harness) {
|
|
30311
30515
|
await parseHookInput(harness, false);
|
|
30312
30516
|
}
|
|
30313
|
-
async function runStartHook(
|
|
30517
|
+
async function runStartHook(installedAs) {
|
|
30314
30518
|
if (isNonInteractiveHarness()) return;
|
|
30315
|
-
const { conversation } = await parseHookInput(
|
|
30519
|
+
const { conversation, harness } = await parseHookInput(installedAs);
|
|
30316
30520
|
if (!conversation) return;
|
|
30317
|
-
const carried = harness === "codex" ? " (no wait tool on Codex; a reply becomes your next turn)" : harness === "cursor" ? " (
|
|
30521
|
+
const carried = harness === "codex" ? " (no wait tool on Codex; a reply becomes your next turn)" : harness === "cursor" ? " (no wait tool on Cursor; a message for you arrives as a new turn in this chat)" : "";
|
|
30318
30522
|
const text = `On Slopware Tasks you are ${generateAgentName(conversation)}: that is how people and other agents address you (session who lists everyone). Messages between agents are letters, read when the other side gets to them: write once, reply only when it changes something, never wait for a reply${carried}.`;
|
|
30319
30523
|
process.stdout.write(`${JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: text }, additional_context: text })}
|
|
30320
30524
|
`);
|
|
@@ -30556,13 +30760,13 @@ ${written.map((path2) => ` ${path2}`).join("\n")}`);
|
|
|
30556
30760
|
}
|
|
30557
30761
|
|
|
30558
30762
|
// src/index.ts
|
|
30559
|
-
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.4.
|
|
30763
|
+
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.4.16").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").hook("preAction", (_, action) => updateJsonMode(Boolean(action.optsWithGlobals().json))).showHelpAfterError("(run with --help for usage)");
|
|
30560
30764
|
registerAuthCommands(program2);
|
|
30561
30765
|
registerProjectCommands(program2);
|
|
30562
30766
|
var taskCommand = registerTaskCommands(program2);
|
|
30563
30767
|
registerSessionCommands(program2);
|
|
30564
30768
|
registerThreadCommands(program2, taskCommand);
|
|
30565
|
-
registerMcpCommands(program2, "0.4.
|
|
30769
|
+
registerMcpCommands(program2, "0.4.16");
|
|
30566
30770
|
registerGuideCommand(program2);
|
|
30567
30771
|
registerSkillCommands(program2);
|
|
30568
30772
|
program2.parseAsync().catch(exitWithError);
|