sessionpipe-conformance 0.12.0 → 0.13.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/cli.js +77 -27
- package/dist/cli.js.map +4 -4
- package/dist/index.js +77 -27
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// sessionpipe-conformance 0.
|
|
2
|
+
// sessionpipe-conformance 0.13.0 · Apache-2.0 · https://sessionpipe.org
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
5
|
import { readdirSync as readdirSync5, realpathSync as realpathSync2, statSync as statSync5 } from "node:fs";
|
|
@@ -168,7 +168,14 @@ ${m.text}`;
|
|
|
168
168
|
continue;
|
|
169
169
|
}
|
|
170
170
|
if (cur) turns.push(cur);
|
|
171
|
-
cur = {
|
|
171
|
+
cur = {
|
|
172
|
+
user: m.text,
|
|
173
|
+
assistant: "",
|
|
174
|
+
at: m.at,
|
|
175
|
+
startLine: m.line,
|
|
176
|
+
endLine: m.line,
|
|
177
|
+
...m.injected ? { injected: true } : {}
|
|
178
|
+
};
|
|
172
179
|
} else {
|
|
173
180
|
if (!cur) cur = { user: "", assistant: "", at: m.at, startLine: m.line, endLine: m.line };
|
|
174
181
|
cur.assistant += (cur.assistant ? "\n\n" : "") + m.text;
|
|
@@ -178,10 +185,17 @@ ${m.text}`;
|
|
|
178
185
|
if (cur?.assistant) turns.push(cur);
|
|
179
186
|
const line = cur && !cur.assistant ? cur.startLine : endLine;
|
|
180
187
|
const out = {
|
|
181
|
-
turns: turns.map((t) => ({
|
|
188
|
+
turns: turns.map((t) => ({
|
|
189
|
+
user: t.user,
|
|
190
|
+
assistant: t.assistant,
|
|
191
|
+
at: t.at,
|
|
192
|
+
endLine: t.endLine,
|
|
193
|
+
...t.injected ? { injected: true } : {}
|
|
194
|
+
})),
|
|
182
195
|
line
|
|
183
196
|
};
|
|
184
|
-
if (cur && !cur.assistant && cur.user)
|
|
197
|
+
if (cur && !cur.assistant && cur.user)
|
|
198
|
+
out.open = { user: cur.user, at: cur.at, ...cur.injected ? { injected: true } : {} };
|
|
185
199
|
return out;
|
|
186
200
|
}
|
|
187
201
|
var isInjected = (text) => /^<[a-z_-]+(?:\s[^>]*)?>/i.test(text) && /<\/[a-z_-]+>\s*$/i.test(text) || /^<!--\s/.test(text) || /^<command-/.test(text);
|
|
@@ -204,27 +218,51 @@ var textParts = (c, kinds) => {
|
|
|
204
218
|
(b) => b && typeof b === "object" && kinds.includes(b.type ?? "") && typeof b.text === "string"
|
|
205
219
|
).map((b) => b.text).join("\n");
|
|
206
220
|
};
|
|
221
|
+
var SPOKEN = /* @__PURE__ */ new Set(["human", "peer"]);
|
|
222
|
+
var PEER_INTRO = /sent a message[^\n]*:$/;
|
|
223
|
+
var PEER_OUTRO = "\n\nThis came from another ";
|
|
224
|
+
var ENVELOPE = /^<cross-session-message\b[^>]*>\n([\s\S]*)\n<\/cross-session-message>$/;
|
|
225
|
+
function peerAsk(origin, text) {
|
|
226
|
+
const body = origin?.body;
|
|
227
|
+
let t = typeof body === "string" && body.trim() ? body : text;
|
|
228
|
+
if (t !== body) {
|
|
229
|
+
const nl = t.indexOf("\n");
|
|
230
|
+
if (nl > 0 && PEER_INTRO.test(t.slice(0, nl))) t = t.slice(nl + 1);
|
|
231
|
+
const outro = t.indexOf(PEER_OUTRO);
|
|
232
|
+
if (outro > 0) t = t.slice(0, outro);
|
|
233
|
+
}
|
|
234
|
+
return (ENVELOPE.exec(t.trim())?.[1] ?? t).trim();
|
|
235
|
+
}
|
|
207
236
|
var queuedPrompt = (a) => {
|
|
208
237
|
if (!a || typeof a !== "object") return "";
|
|
209
238
|
const q = a;
|
|
210
239
|
if (q.type !== "queued_command" || (q.commandMode ?? "prompt") !== "prompt") return "";
|
|
211
|
-
|
|
212
|
-
|
|
240
|
+
const kind = q.origin?.kind ?? "human";
|
|
241
|
+
if (!SPOKEN.has(kind)) return "";
|
|
242
|
+
const text = textParts(q.prompt, ["text"]).trim();
|
|
243
|
+
return kind === "peer" ? peerAsk(q.origin, text) : text;
|
|
213
244
|
};
|
|
245
|
+
var channelText = (text) => /^<channel\b[^>]*>([\s\S]*)<\/channel>$/.exec(text)?.[1]?.trim() ?? "";
|
|
214
246
|
function readClaude(lines, from) {
|
|
215
247
|
const msgs = [];
|
|
216
248
|
for (let i = from; i < lines.length; i++) {
|
|
217
249
|
const j = lines[i] ? parse(lines[i]) : null;
|
|
218
250
|
if (!j || j.isSidechain) continue;
|
|
219
251
|
const origin = j.origin;
|
|
220
|
-
|
|
221
|
-
|
|
252
|
+
const channel = j.type === "user" && origin?.kind === "channel";
|
|
253
|
+
const peer = origin?.kind === "peer";
|
|
254
|
+
if (j.type === "user" && (j.isCompactSummary || j.repeatsCompactSummary)) continue;
|
|
255
|
+
if (j.type === "user" && !channel && !peer && (j.isMeta || origin?.kind && origin.kind !== "human")) continue;
|
|
222
256
|
const at = Date.parse(String(j.timestamp ?? "")) || Date.now();
|
|
223
257
|
const c = j.message?.content;
|
|
224
|
-
if (
|
|
225
|
-
const text = textParts(c, ["text"]).trim();
|
|
258
|
+
if (channel) {
|
|
259
|
+
const text = channelText(textParts(c, ["text"]).trim());
|
|
260
|
+
if (text) msgs.push({ role: "user", text, at, line: i, injected: true });
|
|
261
|
+
} else if (j.type === "user") {
|
|
262
|
+
const raw = textParts(c, ["text"]).trim();
|
|
263
|
+
const text = peer ? peerAsk(origin, raw) : raw;
|
|
226
264
|
if (!text || isInjected(text)) continue;
|
|
227
|
-
msgs.push({ role: "user", text, at, line: i });
|
|
265
|
+
msgs.push({ role: "user", text, at, line: i, ...peer ? { injected: true } : {} });
|
|
228
266
|
} else if (j.type === "assistant" && Array.isArray(c)) {
|
|
229
267
|
const text = textParts(c, ["text"]).trim();
|
|
230
268
|
if (text) msgs.push({ role: "assistant", text, at, line: i });
|
|
@@ -1140,6 +1178,34 @@ async function claudeAiTitle(bridge, token) {
|
|
|
1140
1178
|
// ../core/src/adapters/headless.ts
|
|
1141
1179
|
import { accessSync, constants, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
1142
1180
|
import path4 from "node:path";
|
|
1181
|
+
|
|
1182
|
+
// ../core/src/launched-by.ts
|
|
1183
|
+
var LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
1184
|
+
var DELEGATED_BY_ENV = "SESSIONPIPE_ASKED_BY";
|
|
1185
|
+
var SESSION_REF = /^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/;
|
|
1186
|
+
function refIn(env, name) {
|
|
1187
|
+
const v = env[name]?.trim();
|
|
1188
|
+
return v && SESSION_REF.test(v) ? v : void 0;
|
|
1189
|
+
}
|
|
1190
|
+
function launchedBy(env) {
|
|
1191
|
+
return refIn(env, LAUNCHED_BY_ENV);
|
|
1192
|
+
}
|
|
1193
|
+
function delegatedBy(env) {
|
|
1194
|
+
return refIn(env, DELEGATED_BY_ENV);
|
|
1195
|
+
}
|
|
1196
|
+
function readHook(adapter, input) {
|
|
1197
|
+
const r = adapter.fromHook(input);
|
|
1198
|
+
if (r && !r.session.parent_id) {
|
|
1199
|
+
const self = `${adapter.name}:${r.session.id}`;
|
|
1200
|
+
const launcher = launchedBy(input.env);
|
|
1201
|
+
if (launcher && launcher !== self) r.session.launched_by = launcher;
|
|
1202
|
+
const asker = delegatedBy(input.env);
|
|
1203
|
+
if (asker && asker !== self) r.session.delegated_by = asker;
|
|
1204
|
+
}
|
|
1205
|
+
return r;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// ../core/src/adapters/headless.ts
|
|
1143
1209
|
var JOB_TIMEOUT_MS = 30 * 6e4;
|
|
1144
1210
|
var OUT_CAP = 1024 * 1024;
|
|
1145
1211
|
function isExe(p) {
|
|
@@ -2591,22 +2657,6 @@ function prune5(o) {
|
|
|
2591
2657
|
var ADAPTERS = [claudeCode, codex, geminiCli, antigravity, devin];
|
|
2592
2658
|
var adapterByName = (name) => ADAPTERS.find((a) => a.name === name);
|
|
2593
2659
|
|
|
2594
|
-
// ../core/src/launched-by.ts
|
|
2595
|
-
var LAUNCHED_BY_ENV = "SESSIONPIPE_LAUNCHED_BY";
|
|
2596
|
-
var LAUNCHED_BY = /^[a-z][a-z0-9-]{0,39}:[A-Za-z0-9._:-]{1,128}$/;
|
|
2597
|
-
function launchedBy(env) {
|
|
2598
|
-
const v = env[LAUNCHED_BY_ENV]?.trim();
|
|
2599
|
-
return v && LAUNCHED_BY.test(v) ? v : void 0;
|
|
2600
|
-
}
|
|
2601
|
-
function readHook(adapter, input) {
|
|
2602
|
-
const r = adapter.fromHook(input);
|
|
2603
|
-
if (r && !r.session.parent_id) {
|
|
2604
|
-
const launcher = launchedBy(input.env);
|
|
2605
|
-
if (launcher && launcher !== `${adapter.name}:${r.session.id}`) r.session.launched_by = launcher;
|
|
2606
|
-
}
|
|
2607
|
-
return r;
|
|
2608
|
-
}
|
|
2609
|
-
|
|
2610
2660
|
// src/index.ts
|
|
2611
2661
|
function matches(expect, got, pathStr = "") {
|
|
2612
2662
|
if (expect === "*") return null;
|