@oatelauser/crosschat 1.3.1 → 1.3.3
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/CHANGELOG.md +37 -0
- package/README.md +169 -16
- package/dist/cli.js +19 -5
- package/dist/cli.js.map +1 -1
- package/dist/codex/rollout-meta.js +26 -0
- package/dist/codex/rollout-meta.js.map +1 -1
- package/dist/commands/send.js +100 -11
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/status.js +38 -10
- package/dist/commands/status.js.map +1 -1
- package/dist/envelope.js +2 -1
- package/dist/envelope.js.map +1 -1
- package/dist/federation.js +242 -0
- package/dist/federation.js.map +1 -0
- package/dist/platform/machine-id.js +38 -0
- package/dist/platform/machine-id.js.map +1 -0
- package/dist/ref.js +188 -7
- package/dist/ref.js.map +1 -1
- package/dist/send-log.js +39 -1
- package/dist/send-log.js.map +1 -1
- package/package.json +1 -1
- package/skills/crosschat/SKILL.md +4 -0
package/dist/commands/send.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { hostname as osHostname } from 'node:os';
|
|
2
3
|
import { MultichatError } from '../errors.js';
|
|
3
4
|
import { checkAndRecord, rateKey } from '../rate-limit.js';
|
|
4
5
|
import { mailboxFileFor, outboxCount, park } from '../outbox.js';
|
|
5
6
|
import { endpointOfIdentity, identityKey, identityMatchesEndpoint, resolveCallerIdentity, } from '../identity.js';
|
|
6
7
|
import { resolveTargetByName } from '../resolve.js';
|
|
7
8
|
import { composeEnvelope } from '../envelope.js';
|
|
9
|
+
import { decodeOriginIdentity, isSameMachine, runViaSend } from '../federation.js';
|
|
8
10
|
import { continueConversation, continueFromRef, recordConversation } from '../conversations.js';
|
|
9
11
|
import { decodeRef, encodeRef, newConversationRef, nextTurnRef, } from '../ref.js';
|
|
10
12
|
/** Hard body limit (ticket 004): 16KiB, enforced synchronously, never truncated. */
|
|
@@ -16,8 +18,49 @@ export async function runSend(args, deps) {
|
|
|
16
18
|
if (size > MAX_BODY_BYTES) {
|
|
17
19
|
throw new MultichatError('MESSAGE_TOO_LARGE', `Body is ${size} bytes; the limit is ${MAX_BODY_BYTES}. Write the content to a file and send the path instead.`);
|
|
18
20
|
}
|
|
21
|
+
// Federation (008 B2, design §5 C): a cross-machine --conversation ref names
|
|
22
|
+
// the remote machine in its endpoints — fill a missing --via from it so a
|
|
23
|
+
// hand-typed reply without the flag still routes (the envelope's copy
|
|
24
|
+
// already carries it; this is typo insurance). Undecodable refs fall
|
|
25
|
+
// through to the normal path's error.
|
|
26
|
+
// B11 fix: only the CALLER'S COUNTERPART may become the via target. The
|
|
27
|
+
// previous form scanned both endpoints and picked the first non-local one —
|
|
28
|
+
// on a cross-machine reply the sender's own endpoint lives on the OTHER
|
|
29
|
+
// machine, so the remote leg auto-filled a via back to the sender's machine
|
|
30
|
+
// and the two machines bounced the send at each other over ssh until the
|
|
31
|
+
// 120s timeout, with zero output at either end.
|
|
32
|
+
if (args.via === undefined && args.conversation !== undefined) {
|
|
33
|
+
const here = deps.hostname?.() ?? osHostname();
|
|
34
|
+
const localMid = deps.machineId?.();
|
|
35
|
+
try {
|
|
36
|
+
const ref = decodeRef(args.conversation);
|
|
37
|
+
const envScan = deps.listClaudeSessions();
|
|
38
|
+
const envCaller = resolveCallerIdentity(deps.env, envScan);
|
|
39
|
+
const caller = envCaller.p === 'human' && args.origin !== undefined
|
|
40
|
+
? decodeOriginIdentity(args.origin)
|
|
41
|
+
: envCaller;
|
|
42
|
+
const remote = [ref.f, ref.t].find((ep) => !identityMatchesEndpoint(caller, ep) &&
|
|
43
|
+
ep.p !== 'human' && ep.m !== undefined && !isSameMachine(ep.mid, ep.m, localMid, here));
|
|
44
|
+
if (remote !== undefined)
|
|
45
|
+
args = { ...args, via: `ssh:${remote.m}` };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// invalid ref: the main path reports it
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Federation (008/B1): everything via lives behind this early branch — the
|
|
52
|
+
// 16K check above applies to cross-machine sends too (D6), and the local
|
|
53
|
+
// path below stays byte-identical when --via is absent (D9).
|
|
54
|
+
if (args.via !== undefined) {
|
|
55
|
+
return runViaSend(args, body, deps);
|
|
56
|
+
}
|
|
19
57
|
const scan = deps.listClaudeSessions();
|
|
20
|
-
const
|
|
58
|
+
const envCaller = resolveCallerIdentity(deps.env, scan);
|
|
59
|
+
// Federation (008 D5): an ssh shell has no agent env, so the remote caller
|
|
60
|
+
// would collapse to human (unreplyable). --origin — injected by the sending
|
|
61
|
+
// machine's CLI — is the identity fallback; a real env identity always wins.
|
|
62
|
+
const origin = envCaller.p === 'human' && args.origin !== undefined ? decodeOriginIdentity(args.origin) : undefined;
|
|
63
|
+
const caller = origin ?? envCaller;
|
|
21
64
|
let target;
|
|
22
65
|
let newRef;
|
|
23
66
|
let turn;
|
|
@@ -26,7 +69,8 @@ export async function runSend(args, deps) {
|
|
|
26
69
|
const asFrom = identityMatchesEndpoint(caller, ref.f);
|
|
27
70
|
const asTo = identityMatchesEndpoint(caller, ref.t);
|
|
28
71
|
if (!asFrom && !asTo) {
|
|
29
|
-
throw new MultichatError('CALLER_NOT_IN_CONVERSATION', `Caller (${identityKey(caller)}) is not an endpoint of this conversation
|
|
72
|
+
throw new MultichatError('CALLER_NOT_IN_CONVERSATION', `Caller (${identityKey(caller)}) is not an endpoint of this conversation. ` +
|
|
73
|
+
'手里的 ref 可能抄漏或已过期——改用 --to <名字> 自动接续该端对最新对话。');
|
|
30
74
|
}
|
|
31
75
|
target = asFrom ? ref.t : ref.f;
|
|
32
76
|
if (target.p === 'human') {
|
|
@@ -71,6 +115,50 @@ export async function runSend(args, deps) {
|
|
|
71
115
|
newRef = continued.ref;
|
|
72
116
|
turn = continued.turn;
|
|
73
117
|
}
|
|
118
|
+
// Federation (008 B2 + B10): a remote-origin send (ssh shell + --origin)
|
|
119
|
+
// stamps both endpoints with their machines — m (hostname) routes the return
|
|
120
|
+
// --via, mid (machine-id) decides "same machine" so hostname collisions
|
|
121
|
+
// cannot fake a local conversation. Local sends stamp nothing (no m = local).
|
|
122
|
+
const here = deps.hostname?.() ?? osHostname();
|
|
123
|
+
const localMid = deps.machineId?.();
|
|
124
|
+
if (origin !== undefined) {
|
|
125
|
+
const fIsCaller = identityMatchesEndpoint(caller, newRef.f);
|
|
126
|
+
const stamp = (ep, m, mid) => ep.p === 'human' ? ep : { ...ep, m, ...(mid === undefined ? {} : { mid }) };
|
|
127
|
+
newRef = {
|
|
128
|
+
...newRef,
|
|
129
|
+
f: stamp(newRef.f, fIsCaller ? origin.host : here, fIsCaller ? origin.mid : localMid),
|
|
130
|
+
t: stamp(newRef.t, fIsCaller ? here : origin.host, fIsCaller ? localMid : origin.mid),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// The reply-hint's --via points at the machine of the endpoint reading this
|
|
134
|
+
// envelope would reply to — the sender's own endpoint (D5: no --to needed).
|
|
135
|
+
const senderEp = identityMatchesEndpoint(caller, newRef.f) ? newRef.f : newRef.t;
|
|
136
|
+
const viaHost = senderEp.p !== 'human' && senderEp.m !== undefined && !isSameMachine(senderEp.mid, senderEp.m, localMid, here)
|
|
137
|
+
? senderEp.m
|
|
138
|
+
: undefined;
|
|
139
|
+
// B10 collision warning: the ssh peer's hostname equals ours but its
|
|
140
|
+
// machine-id differs — routing is still correct (per-machine ssh alias
|
|
141
|
+
// namespaces resolve it), the name ambiguity is worth telling the human.
|
|
142
|
+
const collision = origin !== undefined &&
|
|
143
|
+
origin.host === here &&
|
|
144
|
+
origin.mid !== undefined &&
|
|
145
|
+
localMid !== undefined &&
|
|
146
|
+
origin.mid !== localMid
|
|
147
|
+
? `⚠ 两台机器同名 (${here}):已按跨机路由(machine-id 不同)。建议改名避免混淆。`
|
|
148
|
+
: undefined;
|
|
149
|
+
const finish = (out) => {
|
|
150
|
+
if (collision === undefined)
|
|
151
|
+
return out;
|
|
152
|
+
if (args.json === true) {
|
|
153
|
+
try {
|
|
154
|
+
return JSON.stringify({ ...JSON.parse(out), warning: collision });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return `${out}\n${collision}`;
|
|
161
|
+
};
|
|
74
162
|
const replyRef = encodeRef(newRef);
|
|
75
163
|
const fromName = displayName(caller);
|
|
76
164
|
/** Every exit path logs who sent what to whom (B14, +from in B16, +fromName in B21). */
|
|
@@ -81,11 +169,12 @@ export async function runSend(args, deps) {
|
|
|
81
169
|
const claudeSession = scan.sessions.find((session) => session.sessionId === target.id);
|
|
82
170
|
if (claudeSession === undefined) {
|
|
83
171
|
throw new MultichatError('TARGET_NOT_FOUND', `Claude session ${target.id} is not currently routable (process exited or unregistered). ` +
|
|
84
|
-
'
|
|
172
|
+
'对端会话可能已重启——改用 --to <名字> 自动接续该端对最新对话(--to 同名即续,无需换名)。' +
|
|
173
|
+
'status 只列本机会话;跨机对端用 ssh <对端> crosschat status 查。');
|
|
85
174
|
}
|
|
86
175
|
checkAndRecord(deps.rateDir, rateKey(identityKey(caller), `claude:${target.id}`), deps.now());
|
|
87
176
|
const toName = claudeSession.name ?? shortId('claude', claudeSession.sessionId);
|
|
88
|
-
const content = composeEnvelope({ fromName, toName, turn, ref: replyRef, body });
|
|
177
|
+
const content = composeEnvelope({ fromName, toName, turn, ref: replyRef, body, viaHost });
|
|
89
178
|
try {
|
|
90
179
|
await deps.deliverClaude({ pid: claudeSession.pid, messagingSocketPath: claudeSession.messagingSocketPath }, content);
|
|
91
180
|
}
|
|
@@ -96,14 +185,14 @@ export async function runSend(args, deps) {
|
|
|
96
185
|
logNow({ to: toName, target: `claude:${target.id}`, status: 'delivered', turn, replyRef });
|
|
97
186
|
if (deps.conversationStateFile !== undefined)
|
|
98
187
|
recordConversation(deps.conversationStateFile, newRef, deps.now());
|
|
99
|
-
return formatDelivery(args.json === true, toName, turn, replyRef, false);
|
|
188
|
+
return finish(formatDelivery(args.json === true, toName, turn, replyRef, false));
|
|
100
189
|
}
|
|
101
190
|
// Codex delivers by threadId; a missing thread surfaces as a codex adapter error.
|
|
102
191
|
checkAndRecord(deps.rateDir, rateKey(identityKey(caller), `codex:${target.id}`), deps.now());
|
|
103
192
|
const threads = await deps.listCodexThreads();
|
|
104
193
|
const threadName = threads.find((thread) => thread.id === target.id)?.name;
|
|
105
194
|
const toName = threadName ?? shortId('codex', target.id);
|
|
106
|
-
const content = composeEnvelope({ fromName, toName, turn, ref: replyRef, body });
|
|
195
|
+
const content = composeEnvelope({ fromName, toName, turn, ref: replyRef, body, viaHost });
|
|
107
196
|
const parkNow = () => {
|
|
108
197
|
park(deps.outboxDir, target.id, { envelope: content, toName, callerKey: identityKey(caller) }, deps.now());
|
|
109
198
|
deps.spawnWatchdog?.();
|
|
@@ -116,7 +205,7 @@ export async function runSend(args, deps) {
|
|
|
116
205
|
const queuedBefore = outboxCount(deps.outboxDir, target.id);
|
|
117
206
|
if (queuedBefore > 0) {
|
|
118
207
|
const queue = parkNow();
|
|
119
|
-
return formatParked(args.json === true, toName, turn, replyRef, queue, mailboxPath);
|
|
208
|
+
return finish(formatParked(args.json === true, toName, turn, replyRef, queue, mailboxPath));
|
|
120
209
|
}
|
|
121
210
|
try {
|
|
122
211
|
const delivered = await deps.deliverCodex(target.id, content);
|
|
@@ -129,12 +218,12 @@ export async function runSend(args, deps) {
|
|
|
129
218
|
if (deps.conversationStateFile !== undefined)
|
|
130
219
|
recordConversation(deps.conversationStateFile, newRef, deps.now());
|
|
131
220
|
if (queued) {
|
|
132
|
-
return `${out}\n已入对方服务端队列,本轮结束即处理;终态可查 crosschat status --conversations
|
|
221
|
+
return finish(`${out}\n已入对方服务端队列,本轮结束即处理;终态可查 crosschat status --conversations`);
|
|
133
222
|
}
|
|
134
223
|
if (receipt === 'unconfirmed') {
|
|
135
|
-
return `${out}\n回执: 暂未在对方会话记录中确认(可能仍在落盘);稍后查 send-log.jsonl 或重跑 status
|
|
224
|
+
return finish(`${out}\n回执: 暂未在对方会话记录中确认(可能仍在落盘);稍后查 send-log.jsonl 或重跑 status`);
|
|
136
225
|
}
|
|
137
|
-
return out;
|
|
226
|
+
return finish(out);
|
|
138
227
|
}
|
|
139
228
|
catch (err) {
|
|
140
229
|
// Busy/locked = definitively not delivered (deliver.ts polls before giving
|
|
@@ -145,7 +234,7 @@ export async function runSend(args, deps) {
|
|
|
145
234
|
logNow({ to: toName, target: `codex:${target.id}`, status: 'parked', turn, replyRef });
|
|
146
235
|
if (deps.conversationStateFile !== undefined)
|
|
147
236
|
recordConversation(deps.conversationStateFile, newRef, deps.now());
|
|
148
|
-
return formatParked(args.json === true, toName, turn, replyRef, queue, mailboxPath);
|
|
237
|
+
return finish(formatParked(args.json === true, toName, turn, replyRef, queue, mailboxPath));
|
|
149
238
|
}
|
|
150
239
|
logNow({ to: toName, target: `codex:${target.id}`, status: 'failed', code: errorCode(err), turn, replyRef });
|
|
151
240
|
throw err;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/status.js
CHANGED
|
@@ -33,6 +33,7 @@ export async function runStatus(deps, json, conversations = false) {
|
|
|
33
33
|
? `${err.code}: ${err.message}`
|
|
34
34
|
: `INTERNAL: ${err instanceof Error ? err.message : String(err)}`;
|
|
35
35
|
}
|
|
36
|
+
const held = deps.listWriterLocks?.() ?? new Set();
|
|
36
37
|
if (json) {
|
|
37
38
|
return JSON.stringify({
|
|
38
39
|
claude: scan.sessions.map((session) => ({
|
|
@@ -44,14 +45,29 @@ export async function runStatus(deps, json, conversations = false) {
|
|
|
44
45
|
})),
|
|
45
46
|
codex: threads === undefined
|
|
46
47
|
? { error: codexError }
|
|
47
|
-
:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
: [
|
|
49
|
+
...threads.map((thread) => ({
|
|
50
|
+
name: thread.name,
|
|
51
|
+
status: thread.status,
|
|
52
|
+
id: thread.id.slice(0, 8),
|
|
53
|
+
cwd: thread.meta?.cwd ?? null,
|
|
54
|
+
createdAt: thread.meta?.createdAt ?? null,
|
|
55
|
+
originator: thread.meta?.originator ?? null,
|
|
56
|
+
// 006: only present when the writer is held — no locks, no field.
|
|
57
|
+
...(held.has(thread.id) ? { held: true } : {}),
|
|
58
|
+
})),
|
|
59
|
+
// Locked threads that never made it into thread/list (fresh TUI
|
|
60
|
+
// tab, no rollout yet) still deserve a row.
|
|
61
|
+
...unlistedLocks(held, threads).map((id) => ({
|
|
62
|
+
name: null,
|
|
63
|
+
status: 'not_listed',
|
|
64
|
+
id: id.slice(0, 8),
|
|
65
|
+
cwd: null,
|
|
66
|
+
createdAt: null,
|
|
67
|
+
originator: null,
|
|
68
|
+
held: true,
|
|
69
|
+
})),
|
|
70
|
+
],
|
|
55
71
|
});
|
|
56
72
|
}
|
|
57
73
|
const lines = ['claude:'];
|
|
@@ -63,7 +79,7 @@ export async function runStatus(deps, json, conversations = false) {
|
|
|
63
79
|
lines.push('codex:');
|
|
64
80
|
if (codexError !== undefined)
|
|
65
81
|
lines.push(` unavailable (${codexError})`);
|
|
66
|
-
else if ((threads ?? []).length === 0)
|
|
82
|
+
else if ((threads ?? []).length === 0 && held.size === 0)
|
|
67
83
|
lines.push(' (none)');
|
|
68
84
|
else {
|
|
69
85
|
for (const thread of threads ?? []) {
|
|
@@ -71,11 +87,23 @@ export async function runStatus(deps, json, conversations = false) {
|
|
|
71
87
|
const dir = formatCwdShort(thread.meta?.cwd).padEnd(20);
|
|
72
88
|
const created = formatCreatedAt(thread.meta?.createdAt).padEnd(11);
|
|
73
89
|
const originator = (thread.meta?.originator ?? '-').padEnd(16);
|
|
74
|
-
|
|
90
|
+
const marker = held.has(thread.id) ? ' TUI占用' : '';
|
|
91
|
+
lines.push(` ${name} ${dir} ${created} ${originator} ${thread.id.slice(0, 8)} ${thread.status}${marker}`);
|
|
92
|
+
}
|
|
93
|
+
// 006: locked but absent from thread/list (fresh TUI tab, no rollout).
|
|
94
|
+
for (const id of unlistedLocks(held, threads)) {
|
|
95
|
+
lines.push(` ${'-'.padEnd(24)} ${'-'.padEnd(20)} ${'-'.padEnd(11)} ${'-'.padEnd(16)} ${id.slice(0, 8)} 未列入 TUI占用`);
|
|
75
96
|
}
|
|
76
97
|
}
|
|
77
98
|
return lines.join('\n');
|
|
78
99
|
}
|
|
100
|
+
/** Locks whose thread id is not in the thread/list result (empty when listing failed). */
|
|
101
|
+
function unlistedLocks(held, threads) {
|
|
102
|
+
if (threads === undefined)
|
|
103
|
+
return [];
|
|
104
|
+
const listed = new Set(threads.map((thread) => thread.id));
|
|
105
|
+
return [...held].filter((id) => !listed.has(id));
|
|
106
|
+
}
|
|
79
107
|
/** `status --conversations`: per-pair rows (direction, freshness, turn, last status, receipt, parked). */
|
|
80
108
|
async function conversationsView(deps, json) {
|
|
81
109
|
const rows = deps.listConversations?.() ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/envelope.js
CHANGED
|
@@ -24,9 +24,10 @@ export function composeEnvelope(input) {
|
|
|
24
24
|
const fromName = shortened ? codepoints.slice(0, FROM_NAME_MAX_CODEPOINTS).join('') : input.fromName;
|
|
25
25
|
const aliasAttr = shortened ? ` from-alias="${escapeAttr(input.fromName)}"` : '';
|
|
26
26
|
const body = neutralizeReservedTags(input.body);
|
|
27
|
+
const via = input.viaHost === undefined ? '' : ` --via ssh:${input.viaHost}`;
|
|
27
28
|
return (`<cross-session-message from-name="${escapeAttr(fromName)}" turn="${input.turn}"${aliasAttr}>\n` +
|
|
28
29
|
`<crosschat-reply-hint conversation="${input.ref}" reply-as="${escapeAttr(input.toName)}">` +
|
|
29
|
-
`回复请运行: crosschat send --conversation ${input.ref} --body "<你的回复>"</crosschat-reply-hint>\n` +
|
|
30
|
+
`回复请运行: crosschat send${via} --conversation ${input.ref} --body "<你的回复>"</crosschat-reply-hint>\n` +
|
|
30
31
|
`新话题或对话已推进时: crosschat send --to <名字> --body "..."(--to 自动接续该端对最近对话);超 16KiB 请写文件后只发路径\n` +
|
|
31
32
|
`${body}\n` +
|
|
32
33
|
`</cross-session-message>`);
|
package/dist/envelope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,4FAA4F,CAAC;
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,4FAA4F,CAAC;AAqB1H,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,GAAG,wBAAwB,CAAC;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IACrG,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,MAAM,IAAI,GAAG,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7E,OAAO,CACL,qCAAqC,UAAU,CAAC,QAAQ,CAAC,WAAW,KAAK,CAAC,IAAI,IAAI,SAAS,KAAK;QAChG,uCAAuC,KAAK,CAAC,GAAG,eAAe,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;QAC3F,wBAAwB,GAAG,mBAAmB,KAAK,CAAC,GAAG,2CAA2C;QAClG,yFAAyF;QACzF,GAAG,IAAI,IAAI;QACX,0BAA0B,CAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { hostname as osHostname } from 'node:os';
|
|
3
|
+
import { Buffer } from 'node:buffer';
|
|
4
|
+
import { MultichatError } from './errors.js';
|
|
5
|
+
import { recordConversation } from './conversations.js';
|
|
6
|
+
import { decodeRef } from './ref.js';
|
|
7
|
+
import { identityKey, resolveCallerIdentity, } from './identity.js';
|
|
8
|
+
export function parseViaValue(value) {
|
|
9
|
+
const idx = value.indexOf(':');
|
|
10
|
+
const usage = new MultichatError('USAGE', `--via expects <transport>:<host>, e.g. ssh:build01(host 为 ~/.ssh/config 里的 Host 别名)`);
|
|
11
|
+
if (idx <= 0)
|
|
12
|
+
throw usage;
|
|
13
|
+
const transport = value.slice(0, idx);
|
|
14
|
+
const host = value.slice(idx + 1);
|
|
15
|
+
if (transport !== 'ssh') {
|
|
16
|
+
const note = transport === 'tcp' || transport === 'broker'
|
|
17
|
+
? `${transport}: 传输二期支持,当前仅 ssh`
|
|
18
|
+
: `未知传输 ${transport},当前仅支持 ssh:`;
|
|
19
|
+
throw new MultichatError('USAGE', `--via ${note}`);
|
|
20
|
+
}
|
|
21
|
+
// Injection guard (design §2): the host reaches the ssh command line, so it
|
|
22
|
+
// is limited to alias-safe characters — spaces and cmd metachars are out.
|
|
23
|
+
if (!/^[A-Za-z0-9._-]+$/.test(host)) {
|
|
24
|
+
throw new MultichatError('USAGE', `--via ssh: host 别名仅限字母/数字/./_/-(防命令行注入),收到: ${host}`);
|
|
25
|
+
}
|
|
26
|
+
return { transport: 'ssh', host };
|
|
27
|
+
}
|
|
28
|
+
/** Values that will become part of the remote command line (design §2 whitelist). */
|
|
29
|
+
export function validateRemoteFlagValues(args) {
|
|
30
|
+
if (args.to !== undefined) {
|
|
31
|
+
// No whitespace, no cmd/PowerShell metachars, no leading dash. Names with
|
|
32
|
+
// spaces stay single-machine; cross-machine addressing uses id8/ref.
|
|
33
|
+
if (/[\s&|<>^%"']/.test(args.to) || args.to.startsWith('-')) {
|
|
34
|
+
throw new MultichatError('USAGE', `跨机 --to 值不能含空格或特殊字符(${args.to})——请改用 id8 或 --conversation 寻址`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (args.conversation !== undefined && !/^mc[12]_[A-Za-z0-9_-]+$/.test(args.conversation)) {
|
|
38
|
+
throw new MultichatError('USAGE', `跨机 --conversation 值非法: ${args.conversation}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `<p>/<full id>[/<display name>]@<hostname>[:<mid-b64u>]`, base64url-whole.
|
|
43
|
+
* The FULL id is what makes the origin endpoint routable in refs (B2.1);
|
|
44
|
+
* the display name is optional and may contain spaces/unicode/@/'/' (F1 —
|
|
45
|
+
* never parsed beyond its slot). The optional mid (B10 machine-id) rides
|
|
46
|
+
* along so the receiving side can tell same-hostname machines apart —
|
|
47
|
+
* hostnames never contain ':' so the tail split is unambiguous.
|
|
48
|
+
*/
|
|
49
|
+
export function encodeOrigin(identity, host, mid) {
|
|
50
|
+
const who = identity.p === 'claude'
|
|
51
|
+
? identity.name === undefined
|
|
52
|
+
? `claude/${identity.id}`
|
|
53
|
+
: `claude/${identity.id}/${identity.name}`
|
|
54
|
+
: identity.p === 'codex'
|
|
55
|
+
? `codex/${identity.id}`
|
|
56
|
+
: 'human';
|
|
57
|
+
const tail = mid === undefined ? host : `${host}:${Buffer.from(mid, 'utf8').toString('base64url')}`;
|
|
58
|
+
return Buffer.from(`${who}@${tail}`, 'utf8').toString('base64url');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* B10 same-machine rule: when both machine-ids are known they decide (unique
|
|
62
|
+
* per install — hostname collisions cannot fake a match); otherwise fall back
|
|
63
|
+
* to hostname equality (the pre-B10 semantics, still correct when mids are
|
|
64
|
+
* unreadable on either side).
|
|
65
|
+
*/
|
|
66
|
+
export function isSameMachine(epMid, epHost, localMid, localHost) {
|
|
67
|
+
if (epMid !== undefined && localMid !== undefined)
|
|
68
|
+
return epMid === localMid;
|
|
69
|
+
return epHost === localHost;
|
|
70
|
+
}
|
|
71
|
+
/** Remote-side identity fallback for ssh shells without agent env (design D5). */
|
|
72
|
+
export function decodeOriginIdentity(encoded) {
|
|
73
|
+
let text;
|
|
74
|
+
try {
|
|
75
|
+
text = Buffer.from(encoded, 'base64url').toString('utf8');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw new MultichatError('USAGE', '--origin 不是合法的 base64url');
|
|
79
|
+
}
|
|
80
|
+
const at = text.lastIndexOf('@');
|
|
81
|
+
if (at <= 0)
|
|
82
|
+
throw new MultichatError('USAGE', `--origin 格式非法: ${text}`);
|
|
83
|
+
const head = text.slice(0, at);
|
|
84
|
+
const tail = text.slice(at + 1);
|
|
85
|
+
const colon = tail.lastIndexOf(':');
|
|
86
|
+
const host = colon === -1 ? tail : tail.slice(0, colon);
|
|
87
|
+
const mid = colon === -1 ? undefined : Buffer.from(tail.slice(colon + 1), 'base64url').toString('utf8');
|
|
88
|
+
if (host === '' || mid === '')
|
|
89
|
+
throw new MultichatError('USAGE', `--origin 格式非法: ${text}`);
|
|
90
|
+
const slash = head.indexOf('/');
|
|
91
|
+
if (slash <= 0) {
|
|
92
|
+
if (head === 'human')
|
|
93
|
+
return mid === undefined ? { p: 'human', host } : { p: 'human', host, mid };
|
|
94
|
+
throw new MultichatError('USAGE', `--origin 格式非法: ${text}`);
|
|
95
|
+
}
|
|
96
|
+
const p = head.slice(0, slash);
|
|
97
|
+
const rest = head.slice(slash + 1);
|
|
98
|
+
// First '/' after the endpoint type separates the full id from the optional
|
|
99
|
+
// display name; a name may itself contain '/' (B2.1 spec). Ids are
|
|
100
|
+
// hex/uuid-ish and never contain '/'.
|
|
101
|
+
const nameSlash = rest.indexOf('/');
|
|
102
|
+
const id = nameSlash === -1 ? rest : rest.slice(0, nameSlash);
|
|
103
|
+
const name = nameSlash === -1 ? undefined : rest.slice(nameSlash + 1);
|
|
104
|
+
if (id === '' || name === '')
|
|
105
|
+
throw new MultichatError('USAGE', `--origin 格式非法: ${text}`);
|
|
106
|
+
const midField = mid === undefined ? {} : { mid };
|
|
107
|
+
if (p === 'claude')
|
|
108
|
+
return name === undefined ? { p: 'claude', id, host, ...midField } : { p: 'claude', id, name, host, ...midField };
|
|
109
|
+
if (p === 'codex')
|
|
110
|
+
return { p: 'codex', id, host, ...midField };
|
|
111
|
+
throw new MultichatError('USAGE', `--origin 端点类型非法: ${p}`);
|
|
112
|
+
}
|
|
113
|
+
/** The exact remote command (fixed face, design D2 — configurable = injectable). */
|
|
114
|
+
export function buildSshArgv(host, args, originB64) {
|
|
115
|
+
const target = args.to !== undefined
|
|
116
|
+
? ['--to', args.to]
|
|
117
|
+
: ['--conversation', args.conversation];
|
|
118
|
+
return [
|
|
119
|
+
'ssh',
|
|
120
|
+
host,
|
|
121
|
+
'-o',
|
|
122
|
+
'BatchMode=yes', // F2: any interactive prompt becomes a fast failure, not a 120s hang
|
|
123
|
+
'-o',
|
|
124
|
+
'ConnectTimeout=10',
|
|
125
|
+
'crosschat',
|
|
126
|
+
'send',
|
|
127
|
+
...target,
|
|
128
|
+
'--json',
|
|
129
|
+
'--origin',
|
|
130
|
+
originB64,
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
/** Real transport: spawn ssh, feed the body on stdin, close it (EOF), cap output. */
|
|
134
|
+
export function defaultSshExec(argv, input, timeoutMs) {
|
|
135
|
+
return new Promise((resolve) => {
|
|
136
|
+
const child = spawn(argv[0], argv.slice(1), { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
137
|
+
let stdout = '';
|
|
138
|
+
let stderr = '';
|
|
139
|
+
let timedOut = false;
|
|
140
|
+
const cap = (prev, chunk) => (prev.length > 262_144 ? prev : prev + chunk.toString('utf8'));
|
|
141
|
+
child.stdout.on('data', (chunk) => { stdout = cap(stdout, chunk); });
|
|
142
|
+
child.stderr.on('data', (chunk) => { stderr = cap(stderr, chunk); });
|
|
143
|
+
const timer = setTimeout(() => {
|
|
144
|
+
timedOut = true;
|
|
145
|
+
child.kill();
|
|
146
|
+
}, timeoutMs);
|
|
147
|
+
child.on('error', (err) => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
resolve({ code: null, stdout, stderr: `${stderr}${err.message}`, timedOut });
|
|
150
|
+
});
|
|
151
|
+
child.on('close', (code) => {
|
|
152
|
+
clearTimeout(timer);
|
|
153
|
+
resolve({ code, stdout, stderr, timedOut });
|
|
154
|
+
});
|
|
155
|
+
child.stdin.on('error', () => { });
|
|
156
|
+
child.stdin.end(input, 'utf8');
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/** Entry point of the via branch — everything federation lives behind this (D9). */
|
|
160
|
+
export async function runViaSend(args, body, deps) {
|
|
161
|
+
const { host } = parseViaValue(args.via);
|
|
162
|
+
validateRemoteFlagValues(args);
|
|
163
|
+
const scan = deps.listClaudeSessions();
|
|
164
|
+
const caller = resolveCallerIdentity(deps.env, scan);
|
|
165
|
+
const origin = encodeOrigin(caller, deps.hostname?.() ?? osHostname(), deps.machineId?.());
|
|
166
|
+
const argv = buildSshArgv(host, args, origin);
|
|
167
|
+
const envTimeout = Number(deps.env.CROSSCHAT_SSH_TIMEOUT_MS);
|
|
168
|
+
const timeoutMs = Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : 120_000;
|
|
169
|
+
const fromName = originDisplayName(caller);
|
|
170
|
+
const logNow = (fields) => {
|
|
171
|
+
deps.appendLog?.({ ...fields, ts: new Date(deps.now()).toISOString() });
|
|
172
|
+
};
|
|
173
|
+
const res = await (deps.sshExec ?? defaultSshExec)(argv, body, timeoutMs);
|
|
174
|
+
if (res.timedOut || res.code === null) {
|
|
175
|
+
logNow({ from: identityKey(caller), fromName, to: `${args.to ?? args.conversation}@${host}`, target: `via:${host}`, status: 'failed', code: 'SSH_TRANSPORT_TIMEOUT' });
|
|
176
|
+
throw new MultichatError('SSH_TRANSPORT_TIMEOUT', `本地等待 ${Math.round(timeoutMs / 1000)}s 超时,远端状态不明——勿盲目重发(可能与首次投递叠加)。先在对端查 send-log 或 status --conversations 核实后再决定。`);
|
|
177
|
+
}
|
|
178
|
+
if (res.code === 255) {
|
|
179
|
+
logNow({ from: identityKey(caller), fromName, to: `${args.to ?? args.conversation}@${host}`, target: `via:${host}`, status: 'failed', code: 'SSH_TRANSPORT_FAILED' });
|
|
180
|
+
throw new MultichatError('SSH_TRANSPORT_FAILED', `ssh 无法到达 ${host}(不通/密钥/known_hosts)。自证: ssh ${host} crosschat --version(顺带核对版本);检查 ~/.ssh/config 与网络。`);
|
|
181
|
+
}
|
|
182
|
+
if (res.code !== 0) {
|
|
183
|
+
// Remote business error: rethrow the SAME code so self-correction guidance
|
|
184
|
+
// (MESSAGE_TOO_LARGE etc.) stays verbatim (D3); prefix marks the hop.
|
|
185
|
+
const m = res.stderr.match(/crosschat: ([A-Z_]+): (.+)/);
|
|
186
|
+
const err = m !== null
|
|
187
|
+
? new MultichatError(m[1], `[via ${host}] ${m[2]}`)
|
|
188
|
+
: new MultichatError('REMOTE_FAILED', `[via ${host}] 远端异常退出(${res.code}): ${res.stderr.slice(-400)}`);
|
|
189
|
+
logNow({ from: identityKey(caller), fromName, to: `${args.to ?? args.conversation}@${host}`, target: `via:${host}`, status: 'failed', code: err.code });
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
let receipt;
|
|
193
|
+
try {
|
|
194
|
+
receipt = JSON.parse(res.stdout.trim());
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
logNow({ from: identityKey(caller), fromName, to: `${args.to ?? args.conversation}@${host}`, target: `via:${host}`, status: 'failed', code: 'REMOTE_FAILED' });
|
|
198
|
+
throw new MultichatError('REMOTE_FAILED', `[via ${host}] 远端回执不是 JSON: ${res.stdout.slice(0, 200)}`);
|
|
199
|
+
}
|
|
200
|
+
const displayTo = `${receipt.to}@${host}`;
|
|
201
|
+
logNow({
|
|
202
|
+
from: identityKey(caller),
|
|
203
|
+
fromName,
|
|
204
|
+
to: displayTo,
|
|
205
|
+
target: `via:${host}`,
|
|
206
|
+
status: receipt.status,
|
|
207
|
+
turn: receipt.turn,
|
|
208
|
+
replyRef: receipt.replyRef,
|
|
209
|
+
});
|
|
210
|
+
// Own-side pair continuity: the remote issued the ref, recording it locally
|
|
211
|
+
// makes the cross-machine pair show up in `status --conversations` (patch B).
|
|
212
|
+
if (deps.conversationStateFile !== undefined) {
|
|
213
|
+
try {
|
|
214
|
+
recordConversation(deps.conversationStateFile, decodeRef(receipt.replyRef), deps.now());
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// a non-decodable ref must never fail the already-delivered send
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (args.json === true) {
|
|
221
|
+
return JSON.stringify({ ...receipt, via: `ssh:${host}` });
|
|
222
|
+
}
|
|
223
|
+
if (receipt.status === 'parked') {
|
|
224
|
+
return [
|
|
225
|
+
`已寄存给 ${displayTo}(对方忙,未送达)。队列共 ${receipt.queue ?? 1} 条,看门狗每 0.5–5 分钟自动重试,无需手动 status。`,
|
|
226
|
+
`人工随时可读滞留内容: ${receipt.mailbox ?? ''}(位于 ${host})`,
|
|
227
|
+
`reply-ref: ${receipt.replyRef}`,
|
|
228
|
+
].join('\n');
|
|
229
|
+
}
|
|
230
|
+
if (receipt.status === 'queued') {
|
|
231
|
+
return `queued to ${displayTo} (turn ${receipt.turn}; 对方正忙,已入队,本轮结束即处理)\nreply-ref: ${receipt.replyRef}`;
|
|
232
|
+
}
|
|
233
|
+
return `delivered to ${displayTo} (turn ${receipt.turn})\nreply-ref: ${receipt.replyRef}`;
|
|
234
|
+
}
|
|
235
|
+
function originDisplayName(identity) {
|
|
236
|
+
if (identity.p === 'claude')
|
|
237
|
+
return identity.name ?? `claude/${identity.id.slice(0, 8)}`;
|
|
238
|
+
if (identity.p === 'codex')
|
|
239
|
+
return `codex/${identity.id.slice(0, 8)}`;
|
|
240
|
+
return 'human';
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=federation.js.map
|