shennian 0.3.64 → 0.3.65
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/publish-build-manifest.json +70 -65
- package/dist/src/agents/adapter.d.ts +5 -1
- package/dist/src/agents/claude.d.ts +3 -2
- package/dist/src/agents/claude.js +6 -6
- package/dist/src/agents/workbuddy.d.ts +3 -2
- package/dist/src/agents/workbuddy.js +2 -2
- package/dist/src/index.js +3 -3
- package/dist/src/manager/runtime.js +8 -8
- package/dist/src/native-fusion/codex-parser.js +3 -3
- package/dist/src/native-fusion/codex-user-input.d.ts +9 -0
- package/dist/src/native-fusion/codex-user-input.js +4 -2
- package/dist/src/native-fusion/file-watcher.d.ts +13 -5
- package/dist/src/native-fusion/file-watcher.js +1 -1
- package/dist/src/native-fusion/local-repository.d.ts +2 -0
- package/dist/src/native-fusion/local-repository.js +2 -2
- package/dist/src/native-fusion/parser-common.d.ts +1 -0
- package/dist/src/native-fusion/parser-common.js +4 -4
- package/dist/src/native-fusion/parsers.d.ts +1 -0
- package/dist/src/native-fusion/parsers.js +2 -2
- package/dist/src/native-fusion/service.d.ts +3 -0
- package/dist/src/native-fusion/service.js +2 -2
- package/dist/src/native-fusion/state.js +2 -2
- package/dist/src/native-fusion/types.d.ts +4 -0
- package/dist/src/personal-sync/epoch.d.ts +17 -0
- package/dist/src/personal-sync/epoch.js +2 -0
- package/dist/src/personal-sync/identity.js +2 -2
- package/dist/src/personal-sync/machine-authority.d.ts +11 -0
- package/dist/src/personal-sync/machine-authority.js +1 -0
- package/dist/src/personal-sync/metrics.d.ts +7 -1
- package/dist/src/personal-sync/metrics.js +1 -1
- package/dist/src/personal-sync/paths.d.ts +2 -5
- package/dist/src/personal-sync/paths.js +1 -1
- package/dist/src/relay/client.d.ts +8 -2
- package/dist/src/relay/client.js +1 -1
- package/dist/src/session/attachment-transfer-store.d.ts +10 -3
- package/dist/src/session/canonical-store.d.ts +2 -0
- package/dist/src/session/canonical-store.js +5 -5
- package/dist/src/session/deletion-sync-state.d.ts +18 -0
- package/dist/src/session/deletion-sync-state.js +2 -2
- package/dist/src/session/handlers/chat.js +2 -2
- package/dist/src/session/handlers/fs.js +1 -1
- package/dist/src/session/handlers/message-status.js +1 -1
- package/dist/src/session/handlers/title.js +1 -1
- package/dist/src/session/handlers/tool-detail.js +1 -1
- package/dist/src/session/handlers/voice-window.js +1 -1
- package/dist/src/session/history-subscriptions.js +1 -1
- package/dist/src/session/index-publisher.d.ts +2 -2
- package/dist/src/session/index-publisher.js +1 -1
- package/dist/src/session/manager.d.ts +1 -0
- package/dist/src/session/manager.js +1 -1
- package/dist/src/session/native-session-lifecycle.js +4 -4
- package/dist/src/session/queue.d.ts +1 -0
- package/dist/src/session/queue.js +4 -4
- package/dist/src/session/store.d.ts +16 -0
- package/dist/src/session/store.js +2 -2
- package/node_modules/@shennian/wire/dist/frames.d.ts +3 -0
- package/node_modules/@shennian/wire/dist/fs.d.ts +16 -6
- package/node_modules/@shennian/wire/dist/machine.d.ts +2 -0
- package/node_modules/@shennian/wire/dist/message-payload.js +2 -0
- package/node_modules/@shennian/wire/dist/session-sync.d.ts +76 -33
- package/node_modules/@shennian/wire/dist/session-sync.js +50 -2
- package/node_modules/@shennian/wire/dist/session.d.ts +20 -10
- package/node_modules/@shennian/wire/dist/tool-detail.d.ts +3 -2
- package/node_modules/@shennian/wire/package.json +1 -1
- package/package.json +1 -1
- package/dist/src/personal-sync/account-namespace.d.ts +0 -6
- package/dist/src/personal-sync/account-namespace.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 131,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"file": "src/agents/claude.js",
|
|
24
|
-
"beforeBytes":
|
|
25
|
-
"afterBytes":
|
|
24
|
+
"beforeBytes": 12169,
|
|
25
|
+
"afterBytes": 6313
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"file": "src/agents/codex-utils.js",
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
"file": "src/agents/workbuddy.js",
|
|
139
|
-
"beforeBytes":
|
|
140
|
-
"afterBytes":
|
|
139
|
+
"beforeBytes": 14475,
|
|
140
|
+
"afterBytes": 7299
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
"file": "src/commands/daemon-process.js",
|
|
@@ -276,8 +276,8 @@
|
|
|
276
276
|
},
|
|
277
277
|
{
|
|
278
278
|
"file": "src/index.js",
|
|
279
|
-
"beforeBytes":
|
|
280
|
-
"afterBytes":
|
|
279
|
+
"beforeBytes": 24052,
|
|
280
|
+
"afterBytes": 12458
|
|
281
281
|
},
|
|
282
282
|
{
|
|
283
283
|
"file": "src/log-reporter.js",
|
|
@@ -301,8 +301,8 @@
|
|
|
301
301
|
},
|
|
302
302
|
{
|
|
303
303
|
"file": "src/manager/runtime.js",
|
|
304
|
-
"beforeBytes":
|
|
305
|
-
"afterBytes":
|
|
304
|
+
"beforeBytes": 72214,
|
|
305
|
+
"afterBytes": 36669
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
"file": "src/native-fusion/codex-files.js",
|
|
@@ -311,13 +311,13 @@
|
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"file": "src/native-fusion/codex-parser.js",
|
|
314
|
-
"beforeBytes":
|
|
315
|
-
"afterBytes":
|
|
314
|
+
"beforeBytes": 28748,
|
|
315
|
+
"afterBytes": 11925
|
|
316
316
|
},
|
|
317
317
|
{
|
|
318
318
|
"file": "src/native-fusion/codex-user-input.js",
|
|
319
|
-
"beforeBytes":
|
|
320
|
-
"afterBytes":
|
|
319
|
+
"beforeBytes": 4098,
|
|
320
|
+
"afterBytes": 1925
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
323
|
"file": "src/native-fusion/config.js",
|
|
@@ -326,13 +326,13 @@
|
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
328
|
"file": "src/native-fusion/file-watcher.js",
|
|
329
|
-
"beforeBytes":
|
|
330
|
-
"afterBytes":
|
|
329
|
+
"beforeBytes": 7353,
|
|
330
|
+
"afterBytes": 3024
|
|
331
331
|
},
|
|
332
332
|
{
|
|
333
333
|
"file": "src/native-fusion/local-repository.js",
|
|
334
|
-
"beforeBytes":
|
|
335
|
-
"afterBytes":
|
|
334
|
+
"beforeBytes": 25241,
|
|
335
|
+
"afterBytes": 12409
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
338
|
"file": "src/native-fusion/native-source-deletions.js",
|
|
@@ -346,28 +346,28 @@
|
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"file": "src/native-fusion/parser-common.js",
|
|
349
|
-
"beforeBytes":
|
|
350
|
-
"afterBytes":
|
|
349
|
+
"beforeBytes": 8685,
|
|
350
|
+
"afterBytes": 3912
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
"file": "src/native-fusion/parsers.js",
|
|
354
|
-
"beforeBytes":
|
|
355
|
-
"afterBytes":
|
|
354
|
+
"beforeBytes": 5850,
|
|
355
|
+
"afterBytes": 3235
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"file": "src/native-fusion/service.js",
|
|
359
|
-
"beforeBytes":
|
|
360
|
-
"afterBytes":
|
|
359
|
+
"beforeBytes": 29648,
|
|
360
|
+
"afterBytes": 13788
|
|
361
361
|
},
|
|
362
362
|
{
|
|
363
363
|
"file": "src/native-fusion/session-header.js",
|
|
364
|
-
"beforeBytes":
|
|
364
|
+
"beforeBytes": 4294,
|
|
365
365
|
"afterBytes": 1996
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"file": "src/native-fusion/state.js",
|
|
369
|
-
"beforeBytes":
|
|
370
|
-
"afterBytes":
|
|
369
|
+
"beforeBytes": 4112,
|
|
370
|
+
"afterBytes": 2111
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"file": "src/native-fusion/types.js",
|
|
@@ -375,24 +375,29 @@
|
|
|
375
375
|
"afterBytes": 60
|
|
376
376
|
},
|
|
377
377
|
{
|
|
378
|
-
"file": "src/personal-sync/
|
|
379
|
-
"beforeBytes":
|
|
380
|
-
"afterBytes":
|
|
378
|
+
"file": "src/personal-sync/epoch.js",
|
|
379
|
+
"beforeBytes": 8116,
|
|
380
|
+
"afterBytes": 3955
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
"file": "src/personal-sync/identity.js",
|
|
384
|
-
"beforeBytes":
|
|
385
|
-
"afterBytes":
|
|
384
|
+
"beforeBytes": 2427,
|
|
385
|
+
"afterBytes": 1324
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"file": "src/personal-sync/machine-authority.js",
|
|
389
|
+
"beforeBytes": 1835,
|
|
390
|
+
"afterBytes": 1127
|
|
386
391
|
},
|
|
387
392
|
{
|
|
388
393
|
"file": "src/personal-sync/metrics.js",
|
|
389
|
-
"beforeBytes":
|
|
390
|
-
"afterBytes":
|
|
394
|
+
"beforeBytes": 2258,
|
|
395
|
+
"afterBytes": 1391
|
|
391
396
|
},
|
|
392
397
|
{
|
|
393
398
|
"file": "src/personal-sync/paths.js",
|
|
394
|
-
"beforeBytes":
|
|
395
|
-
"afterBytes":
|
|
399
|
+
"beforeBytes": 910,
|
|
400
|
+
"afterBytes": 479
|
|
396
401
|
},
|
|
397
402
|
{
|
|
398
403
|
"file": "src/region.js",
|
|
@@ -401,8 +406,8 @@
|
|
|
401
406
|
},
|
|
402
407
|
{
|
|
403
408
|
"file": "src/relay/client.js",
|
|
404
|
-
"beforeBytes":
|
|
405
|
-
"afterBytes":
|
|
409
|
+
"beforeBytes": 14515,
|
|
410
|
+
"afterBytes": 7173
|
|
406
411
|
},
|
|
407
412
|
{
|
|
408
413
|
"file": "src/room/activation-audit.js",
|
|
@@ -516,13 +521,13 @@
|
|
|
516
521
|
},
|
|
517
522
|
{
|
|
518
523
|
"file": "src/session/canonical-store.js",
|
|
519
|
-
"beforeBytes":
|
|
520
|
-
"afterBytes":
|
|
524
|
+
"beforeBytes": 31550,
|
|
525
|
+
"afterBytes": 15208
|
|
521
526
|
},
|
|
522
527
|
{
|
|
523
528
|
"file": "src/session/deletion-sync-state.js",
|
|
524
|
-
"beforeBytes":
|
|
525
|
-
"afterBytes":
|
|
529
|
+
"beforeBytes": 5030,
|
|
530
|
+
"afterBytes": 2897
|
|
526
531
|
},
|
|
527
532
|
{
|
|
528
533
|
"file": "src/session/handlers/agent-capabilities.js",
|
|
@@ -541,8 +546,8 @@
|
|
|
541
546
|
},
|
|
542
547
|
{
|
|
543
548
|
"file": "src/session/handlers/chat.js",
|
|
544
|
-
"beforeBytes":
|
|
545
|
-
"afterBytes":
|
|
549
|
+
"beforeBytes": 35022,
|
|
550
|
+
"afterBytes": 14909
|
|
546
551
|
},
|
|
547
552
|
{
|
|
548
553
|
"file": "src/session/handlers/control.js",
|
|
@@ -551,13 +556,13 @@
|
|
|
551
556
|
},
|
|
552
557
|
{
|
|
553
558
|
"file": "src/session/handlers/fs.js",
|
|
554
|
-
"beforeBytes":
|
|
555
|
-
"afterBytes":
|
|
559
|
+
"beforeBytes": 21924,
|
|
560
|
+
"afterBytes": 10383
|
|
556
561
|
},
|
|
557
562
|
{
|
|
558
563
|
"file": "src/session/handlers/message-status.js",
|
|
559
|
-
"beforeBytes":
|
|
560
|
-
"afterBytes":
|
|
564
|
+
"beforeBytes": 676,
|
|
565
|
+
"afterBytes": 392
|
|
561
566
|
},
|
|
562
567
|
{
|
|
563
568
|
"file": "src/session/handlers/room-managed.js",
|
|
@@ -571,33 +576,33 @@
|
|
|
571
576
|
},
|
|
572
577
|
{
|
|
573
578
|
"file": "src/session/handlers/title.js",
|
|
574
|
-
"beforeBytes":
|
|
575
|
-
"afterBytes":
|
|
579
|
+
"beforeBytes": 3128,
|
|
580
|
+
"afterBytes": 1668
|
|
576
581
|
},
|
|
577
582
|
{
|
|
578
583
|
"file": "src/session/handlers/tool-detail.js",
|
|
579
|
-
"beforeBytes":
|
|
580
|
-
"afterBytes":
|
|
584
|
+
"beforeBytes": 6399,
|
|
585
|
+
"afterBytes": 3357
|
|
581
586
|
},
|
|
582
587
|
{
|
|
583
588
|
"file": "src/session/handlers/voice-window.js",
|
|
584
|
-
"beforeBytes":
|
|
585
|
-
"afterBytes":
|
|
589
|
+
"beforeBytes": 2556,
|
|
590
|
+
"afterBytes": 1252
|
|
586
591
|
},
|
|
587
592
|
{
|
|
588
593
|
"file": "src/session/history-subscriptions.js",
|
|
589
|
-
"beforeBytes":
|
|
590
|
-
"afterBytes":
|
|
594
|
+
"beforeBytes": 8639,
|
|
595
|
+
"afterBytes": 4283
|
|
591
596
|
},
|
|
592
597
|
{
|
|
593
598
|
"file": "src/session/index-publisher.js",
|
|
594
|
-
"beforeBytes":
|
|
595
|
-
"afterBytes":
|
|
599
|
+
"beforeBytes": 7582,
|
|
600
|
+
"afterBytes": 3747
|
|
596
601
|
},
|
|
597
602
|
{
|
|
598
603
|
"file": "src/session/manager.js",
|
|
599
|
-
"beforeBytes":
|
|
600
|
-
"afterBytes":
|
|
604
|
+
"beforeBytes": 27929,
|
|
605
|
+
"afterBytes": 14336
|
|
601
606
|
},
|
|
602
607
|
{
|
|
603
608
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -606,8 +611,8 @@
|
|
|
606
611
|
},
|
|
607
612
|
{
|
|
608
613
|
"file": "src/session/native-session-lifecycle.js",
|
|
609
|
-
"beforeBytes":
|
|
610
|
-
"afterBytes":
|
|
614
|
+
"beforeBytes": 14160,
|
|
615
|
+
"afterBytes": 6446
|
|
611
616
|
},
|
|
612
617
|
{
|
|
613
618
|
"file": "src/session/projection.js",
|
|
@@ -616,13 +621,13 @@
|
|
|
616
621
|
},
|
|
617
622
|
{
|
|
618
623
|
"file": "src/session/queue.js",
|
|
619
|
-
"beforeBytes":
|
|
620
|
-
"afterBytes":
|
|
624
|
+
"beforeBytes": 19312,
|
|
625
|
+
"afterBytes": 8831
|
|
621
626
|
},
|
|
622
627
|
{
|
|
623
628
|
"file": "src/session/store.js",
|
|
624
|
-
"beforeBytes":
|
|
625
|
-
"afterBytes":
|
|
629
|
+
"beforeBytes": 25840,
|
|
630
|
+
"afterBytes": 13364
|
|
626
631
|
},
|
|
627
632
|
{
|
|
628
633
|
"file": "src/session/tool-detail-store.js",
|
|
@@ -33,6 +33,10 @@ export type AgentSendResult = {
|
|
|
33
33
|
export type AgentSendContext = {
|
|
34
34
|
source: 'room_activation';
|
|
35
35
|
};
|
|
36
|
+
export type AgentStartOptions = {
|
|
37
|
+
/** Test-only callers can disable provider-native history persistence. */
|
|
38
|
+
persistNativeSession?: boolean;
|
|
39
|
+
};
|
|
36
40
|
export interface AgentAdapterEvents {
|
|
37
41
|
agentEvent: [event: AgentEvent];
|
|
38
42
|
error: [error: Error];
|
|
@@ -51,7 +55,7 @@ export declare abstract class AgentAdapter extends EventEmitter<AgentAdapterEven
|
|
|
51
55
|
canStop?: boolean;
|
|
52
56
|
}>;
|
|
53
57
|
setTitle?(agentSessionId: string, title: string, workDir?: string): Promise<void>;
|
|
54
|
-
abstract start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
58
|
+
abstract start(sessionId: string, workDir: string, agentSessionId?: string | null, options?: AgentStartOptions): Promise<void>;
|
|
55
59
|
abstract send(text: string, modelId?: string, reasoningEffort?: string, attachments?: ChatAttachmentMeta[], systemPrompt?: string | null, context?: AgentSendContext): Promise<void | AgentSendResult>;
|
|
56
60
|
abstract resume(agentSessionId: string): Promise<void>;
|
|
57
61
|
abstract stop(): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentAdapter } from './adapter.js';
|
|
1
|
+
import { AgentAdapter, type AgentStartOptions } from './adapter.js';
|
|
2
2
|
import type { ChatAttachmentMeta, ExternalChannelSessionStatus } from '@shennian/wire';
|
|
3
3
|
export declare function normalizeClaudeModelId(modelId?: string | null): string;
|
|
4
4
|
export declare function normalizeClaudeReasoningEffort(reasoningEffort?: string | null): string | undefined;
|
|
@@ -16,6 +16,7 @@ export declare class ClaudeAdapter extends AgentAdapter {
|
|
|
16
16
|
private runId;
|
|
17
17
|
private hasEmittedText;
|
|
18
18
|
private terminalState;
|
|
19
|
+
private persistNativeSession;
|
|
19
20
|
constructor(options?: {
|
|
20
21
|
systemPrompt?: string;
|
|
21
22
|
hidden?: boolean;
|
|
@@ -28,7 +29,7 @@ export declare class ClaudeAdapter extends AgentAdapter {
|
|
|
28
29
|
externalChannel?: ExternalChannelSessionStatus | null;
|
|
29
30
|
env?: NodeJS.ProcessEnv;
|
|
30
31
|
}): void;
|
|
31
|
-
start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
32
|
+
start(sessionId: string, workDir: string, agentSessionId?: string | null, options?: AgentStartOptions): Promise<void>;
|
|
32
33
|
send(text: string, modelId?: string, reasoningEffort?: string, _attachments?: ChatAttachmentMeta[], agentSystemPrompt?: string | null): Promise<void>;
|
|
33
34
|
resume(agentSessionId: string): Promise<void>;
|
|
34
35
|
stop(): Promise<void>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{createInterface as f}from"node:readline";import{randomUUID as
|
|
2
|
-
${
|
|
3
|
-
`)){const
|
|
4
|
-
`})}}),s.on("close",n=>{this.process===s&&(this.process=null,this.handleProcessClose(n,u))}),s.on("error",n=>{this.process===s&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",n))})}handleStreamEvent(
|
|
1
|
+
import{createInterface as f}from"node:readline";import{randomUUID as d}from"node:crypto";import{AgentAdapter as g,registerAgent as S}from"./adapter.js";import{resolveBuiltinCommand as p,spawnAgentCommand as I,spawnResolvedCommandSync as E}from"./command-spec.js";import{buildAgentProcessEnv as m}from"../agent-env.js";import{buildPlatformInstructions as c}from"./platform-instructions.js";function x(i){return i?.trim()||"default"}const y=new Set(["low","medium","high","xhigh","max"]),o=new Map;function v(i){const e=i?.trim();if(e){if(y.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function R(){o.clear()}function w(i){const e=i.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function C(){const i=p("claude");if(!i)return!1;const e=`${i.kind}:${i.path}:${i.command}:${i.args.join("\0")}`;if(o.has(e))return o.get(e)??!1;try{const t=E(i,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:m()}),s=`${t.stdout??""}
|
|
2
|
+
${t.stderr??""}`,a=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return o.set(e,a),a}catch{return o.set(e,!1),!1}}class k extends g{options;type="claude";process=null;agentSessionId=null;sessionId=null;workDir=null;seq=0;runId="";hasEmittedText=!1;terminalState="open";persistNativeSession=!0;constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{}}async start(e,t,s,a){this.sessionId=e,this.workDir=t,this.seq=0,this.persistNativeSession=a?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,a,u){await this.killProcess(),this.runId=d(),this.resetRunState();const n=["-p",e,"--output-format","stream-json","--verbose"];this.persistNativeSession||n.push("--no-session-persistence");const r=this.options.systemPrompt??c(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,u);r&&n.push("--append-system-prompt",r),this.options.hidden&&n.push("--name","Shennian Manager Substrate"),process.getuid?.()!==0&&n.push("--dangerously-skip-permissions"),n.push("--model",x(t));const l=v(s);l&&C()&&n.push("--effort",l),this.agentSessionId&&n.push("--resume",this.agentSessionId),this.spawnAndParse(n)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=d(),this.resetRunState();const t=["--resume",e,"--output-format","stream-json","--verbose"],s=this.options.systemPrompt??c(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0);s&&t.push("--append-system-prompt",s),this.options.hidden&&t.push("--name","Shennian Manager Substrate"),process.getuid?.()!==0&&t.push("--dangerously-skip-permissions"),this.spawnAndParse(t)}async stop(){await this.killProcess()}spawnAndParse(e){const t=p("claude");if(!t){this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?'));return}const s=I(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:m(this.extraEnv)});this.process=s,f({input:s.stdout}).on("line",n=>{if(n.trim())try{const r=JSON.parse(n);this.handleStreamEvent(r)}catch{}});let u="";s.stderr?.on("data",n=>{const r=n.toString();if(u+=r,this.terminalState==="open")for(const l of r.split(`
|
|
3
|
+
`)){const h=l.trim();w(h)&&this.emitEvent({state:"delta",text:h+`
|
|
4
|
+
`})}}),s.on("close",n=>{this.process===s&&(this.process=null,this.handleProcessClose(n,u))}),s.on("error",n=>{this.process===s&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",n))})}handleStreamEvent(e){if(e.type==="system"&&e.subtype==="init"&&e.session_id){this.agentSessionId=e.session_id,this.emitEvent({state:"start",agentSessionId:this.agentSessionId});return}if(e.type==="system"&&e.subtype==="api_retry"&&e.error==="authentication_failed"){this.emitErrorIfOpen({state:"error",message:'Claude authentication failed. Run "claude auth login" and retry.'});return}if(e.type==="assistant"){if(e.message?.content){for(const t of e.message.content)if(t.type==="text"&&t.text){const s=this.hasEmittedText?`
|
|
5
5
|
|
|
6
|
-
`:"";this.emitEvent({state:"delta",text:s+
|
|
6
|
+
`:"";this.emitEvent({state:"delta",text:s+t.text}),this.hasEmittedText=!0}else t.type==="thinking"&&t.thinking?this.emitEvent({state:"delta",text:t.thinking,thinking:!0}):t.type==="tool_use"&&this.emitEvent({state:"tool-call",name:t.name,args:t.input});return}if(e.subtype==="text"&&e.text){const t=this.hasEmittedText?`
|
|
7
7
|
|
|
8
|
-
`:"";this.emitEvent({state:"delta",text:e
|
|
8
|
+
`:"";this.emitEvent({state:"delta",text:t+e.text}),this.hasEmittedText=!0}else e.subtype==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.subtype==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});return}if(e.type==="result")if(e.subtype==="tool_result"){const t=typeof e.content=="string"?e.content:JSON.stringify(e.content);this.emitEvent({state:"tool-result",name:e.name,result:t})}else if(e.subtype==="success"){e.session_id&&(this.agentSessionId=e.session_id);const t=e.usage??e.message?.usage;this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0,usage:t?{inputTokens:t.input_tokens,outputTokens:t.output_tokens}:void 0})}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error"})}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}emitFinalIfOpen(e){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent(e))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent(e))}resetRunState(){this.seq=0,this.hasEmittedText=!1,this.terminalState="open"}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}))}}S("claude",()=>new k);export{k as ClaudeAdapter,x as normalizeClaudeModelId,v as normalizeClaudeReasoningEffort,R as resetClaudeCapabilityCacheForTests,w as shouldForwardClaudeStderrLine,C as supportsClaudeReasoningEffort};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ChildProcess } from 'node:child_process';
|
|
2
2
|
import type { ChatAttachmentMeta, ExternalChannelSessionStatus, SessionRunPhase } from '@shennian/wire';
|
|
3
|
-
import { AgentAdapter, type AgentSendContext } from './adapter.js';
|
|
3
|
+
import { AgentAdapter, type AgentSendContext, type AgentStartOptions } from './adapter.js';
|
|
4
4
|
export declare function normalizeWorkBuddyModelId(modelId?: string | null): string | undefined;
|
|
5
5
|
export declare function normalizeWorkBuddyReasoningEffort(value?: string | null): string | undefined;
|
|
6
6
|
export declare function workBuddySystemPromptArgs(systemPrompt: string | null, platform: NodeJS.Platform, promptFile?: string): string[];
|
|
@@ -16,6 +16,7 @@ export declare class WorkBuddyAdapter extends AgentAdapter {
|
|
|
16
16
|
private terminalState;
|
|
17
17
|
private hasEmittedText;
|
|
18
18
|
private runPhase;
|
|
19
|
+
private persistNativeSession;
|
|
19
20
|
private externalChannel;
|
|
20
21
|
private shennianSessionId;
|
|
21
22
|
private extraEnv;
|
|
@@ -24,7 +25,7 @@ export declare class WorkBuddyAdapter extends AgentAdapter {
|
|
|
24
25
|
externalChannel?: ExternalChannelSessionStatus | null;
|
|
25
26
|
env?: NodeJS.ProcessEnv;
|
|
26
27
|
}): void;
|
|
27
|
-
start(_sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
28
|
+
start(_sessionId: string, workDir: string, agentSessionId?: string | null, options?: AgentStartOptions): Promise<void>;
|
|
28
29
|
send(text: string, modelId?: string, reasoningEffort?: string, _attachments?: ChatAttachmentMeta[], agentSystemPrompt?: string | null, context?: AgentSendContext): Promise<void>;
|
|
29
30
|
resume(agentSessionId: string): Promise<void>;
|
|
30
31
|
stop(): Promise<void>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{spawnSync as g}from"node:child_process";import{createInterface as y}from"node:readline";import{randomUUID as
|
|
1
|
+
import{spawnSync as g}from"node:child_process";import{createInterface as y}from"node:readline";import{randomUUID as S}from"node:crypto";import w from"node:path";import{AgentAdapter as k,registerAgent as I}from"./adapter.js";import{resolveBuiltinCommand as x,spawnAgentCommand as E}from"./command-spec.js";import{buildAgentProcessEnv as _}from"../agent-env.js";import{buildPlatformInstructions as B,ensurePlatformInstructionsFile as P}from"./platform-instructions.js";import{resolveWindowsSystemRoot as T}from"../windows-shell.js";const W=new Set(["minimal","low","medium","high","xhigh","max"]);function C(s){const t=s?.trim();return t&&t!=="auto"?t:void 0}function A(s){const t=s?.trim();if(t){if(W.has(t))return t;throw new Error(`Unsupported WorkBuddy reasoning effort "${t}". Supported values: minimal, low, medium, high, xhigh, max.`)}}function O(s,t,e){if(!s)return[];if(t==="win32"){if(!e)throw new Error("WorkBuddy system prompt file is required on Windows.");return["--system-prompt-file",e]}return["--append-system-prompt",s]}function q(s){const t=s.split(/\n\n(?=<[^>\n]+>\n)/);return(t[t.length-1]??s).replace(/^\[群消息\][ \t]+<[^>\n]+>\n/,"").replace(/^\[群消息\]\n?/,"").replace(/^<[^>\n]+>\n/,"").trim()}function p(s,t=process.platform,e=R){t==="win32"&&s.pid&&e(s.pid)||s.kill("SIGTERM")}function R(s){const t=w.win32.join(T(),"System32","taskkill.exe");return g(t,["/pid",String(s),"/T","/F"],{stdio:"ignore",windowsHide:!0,timeout:5e3}).status===0}class D extends k{type="workbuddy";process=null;agentSessionId=null;workDir=null;seq=0;runId="";terminalState="open";hasEmittedText=!1;runPhase=null;persistNativeSession=!0;externalChannel=null;shennianSessionId=null;extraEnv={};configure(t){this.shennianSessionId=t.sessionId??null,this.externalChannel=t.externalChannel??null,this.extraEnv=t.env??{}}async start(t,e,n,r){this.workDir=e,this.seq=0,this.persistNativeSession=r?.persistNativeSession!==!1,n&&(this.agentSessionId=n)}async send(t,e,n,r,a,i){await this.killProcess(),this.runId=S(),this.resetRunState();const u=i?.source==="room_activation",o=["-p",u?q(t):t,"--output-format","stream-json","--verbose","--permission-mode","bypassPermissions","--setting-sources","user,project,local"];this.persistNativeSession||o.push("--no-session-persistence");const d=C(e);d&&o.push("--model",d),o.push("--tools","default"),u&&o.push("--max-turns","8");const h=this.shennianSessionId?.startsWith("room-managed-")&&!this.agentSessionId&&!u?null:B(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,a);if(h){const c=process.platform==="win32"?P(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,a):void 0;o.push(...O(h,process.platform,c))}const m=A(n);m&&o.push("--effort",m),this.agentSessionId&&o.push("--resume",this.agentSessionId),this.spawnAndParse(o)}async resume(t){await this.killProcess(),this.agentSessionId=t,this.resetRunState()}async stop(){await this.killProcess()}async getStatus(){return{active:this.process!=null&&this.terminalState==="open",runId:this.runId||null,runPhase:this.runPhase,canStop:this.process!=null&&this.terminalState==="open"}}spawnAndParse(t){const e=x("workbuddy");if(!e){this.emit("error",new Error("WorkBuddy was not found. Install WorkBuddy Desktop or the CodeBuddy CLI, then retry."));return}const n=E(e,t,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:_(this.extraEnv)});this.process=n,y({input:n.stdout}).on("line",i=>{if(i.trim())try{this.handleStreamEvent(JSON.parse(i))}catch{}});let a="";n.stderr?.on("data",i=>{a=`${a}${i.toString()}`.slice(-8e3)}),n.on("close",i=>{this.process===n&&(this.process=null,this.runPhase=null,this.handleProcessClose(i,a))}),n.on("error",i=>{if(this.process!==n)return;this.process=null,this.runPhase=null;const u=i.code==="ENOENT";this.emitErrorIfOpen({state:"error",message:u?"WorkBuddy was not found. Install WorkBuddy Desktop or the CodeBuddy CLI, then retry.":l(i.message)})})}handleStreamEvent(t){if(t.type==="system"&&t.subtype==="init"&&t.session_id){this.agentSessionId=t.session_id,this.runPhase="thinking",this.emitEvent({state:"start",agentSessionId:t.session_id});return}if(t.type==="control_request"&&t.request?.subtype==="can_use_tool"){this.runPhase="waiting_approval",this.emitEvent({state:"approval-pending",name:t.request.tool_name,args:t.request.input,approval:{title:`WorkBuddy \u8BF7\u6C42\u4F7F\u7528 ${t.request.tool_name||"\u5DE5\u5177"}`,source:"workbuddy",actionHint:"\u8BF7\u5728 WorkBuddy \u6216\u795E\u5FF5\u4E2D\u786E\u8BA4\u540E\u7EE7\u7EED\u3002"}});return}if(t.type==="assistant"){const n=t.message?.content;if(n?.length)for(const r of n)this.handleContentBlock(r);else t.text&&this.emitText(t.text,!!t.thinking);return}if(t.type!=="result")return;if(t.subtype==="tool_result"){this.runPhase="tool_running",this.emitEvent({state:"tool-result",name:t.name,result:f(t.content)});return}if(t.subtype==="error"||t.error){this.emitErrorIfOpen({state:"error",message:l(t.error||t.result||"WorkBuddy failed.")});return}!this.hasEmittedText&&t.result&&this.emitText(t.result,!1),t.session_id&&(this.agentSessionId=t.session_id);const e=t.usage??t.message?.usage;this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0,usage:e?{inputTokens:e.input_tokens??0,outputTokens:e.output_tokens??0}:void 0})}handleContentBlock(t){t.type==="text"&&t.text?this.emitText(t.text,!1):t.type==="thinking"&&t.thinking?this.emitText(t.thinking,!0):t.type==="tool_use"?(this.runPhase="tool_running",this.emitEvent({state:"tool-call",name:t.name,args:t.input})):t.type==="tool_result"&&this.emitEvent({state:"tool-result",name:t.name,result:f(t.content)})}emitText(t,e){this.runPhase=e?"thinking":"streaming_text";const n=!e&&this.hasEmittedText?`
|
|
2
2
|
|
|
3
|
-
`:"";this.emitEvent({state:"delta",text:n+t,thinking:e||void 0}),e||(this.hasEmittedText=!0)}handleProcessClose(t,e){if(t!==0&&t!==null){this.emitErrorIfOpen({state:"error",message:l(e)||`WorkBuddy exited with code ${t}.`});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}emitFinalIfOpen(t){this.terminalState==="open"&&(this.terminalState="final",this.runPhase=null,this.emitEvent(t))}emitErrorIfOpen(t){this.terminalState==="open"&&(this.terminalState="error",this.runPhase=null,this.emitEvent(t))}emitEvent(t){this.emit("agentEvent",{...t,runId:this.runId,seq:this.seq++})}resetRunState(){this.seq=0,this.terminalState="open",this.hasEmittedText=!1,this.runPhase=null}async killProcess(){const t=this.process;t&&(this.process=null,this.runPhase=null,p(t),await new Promise(e=>{let n=!1;const
|
|
3
|
+
`:"";this.emitEvent({state:"delta",text:n+t,thinking:e||void 0}),e||(this.hasEmittedText=!0)}handleProcessClose(t,e){if(t!==0&&t!==null){this.emitErrorIfOpen({state:"error",message:l(e)||`WorkBuddy exited with code ${t}.`});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}emitFinalIfOpen(t){this.terminalState==="open"&&(this.terminalState="final",this.runPhase=null,this.emitEvent(t))}emitErrorIfOpen(t){this.terminalState==="open"&&(this.terminalState="error",this.runPhase=null,this.emitEvent(t))}emitEvent(t){this.emit("agentEvent",{...t,runId:this.runId,seq:this.seq++})}resetRunState(){this.seq=0,this.terminalState="open",this.hasEmittedText=!1,this.runPhase=null}async killProcess(){const t=this.process;t&&(this.process=null,this.runPhase=null,p(t),await new Promise(e=>{let n=!1;const r=()=>{n||(n=!0,e())};t.once("close",r),setTimeout(()=>{p(t),r()},3e3).unref?.()}))}}function f(s){if(typeof s=="string")return s;try{return JSON.stringify(s)}catch{return"[unserializable WorkBuddy tool result]"}}function l(s){return s.replace(/(Authorization\s*:\s*)Bearer\s+[A-Za-z0-9._~+/-]+/gi,"$1Bearer [redacted]").replace(/(api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|connector[-_ ]?token)(\s*[:=]\s*)[^\s,;]+/gi,"$1$2[redacted]").trim().slice(0,2e3)}I("workbuddy",()=>new D);export{D as WorkBuddyAdapter,C as normalizeWorkBuddyModelId,A as normalizeWorkBuddyReasoningEffort,l as sanitizeWorkBuddyError,p as terminateWorkBuddyProcess,q as workBuddyRoomActivationText,O as workBuddySystemPromptArgs};
|
package/dist/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Command as te}from"commander";import
|
|
2
|
-
`),process.exitCode=1}function
|
|
3
|
-
Disconnecting...`)),
|
|
1
|
+
import{Command as te}from"commander";import w from"chalk";import re from"node:os";import b from"node:fs";import{loadConfig as d,saveConfig as ie,getConfigPath as se,getShennianDir as ae,resolveShennianPath as J,normalizeAutoUpgradePolicy as ce}from"./config/index.js";import{CliRelayClient as me}from"./relay/client.js";import{registerPairCommand as le,runSmartStart as de}from"./commands/pair.js";import{clearDaemonPidIfOwner as z,createDaemonInstanceId as pe,clearDaemonLauncher as j,findRunningDaemonProcessIds as ge,isRemoteAccessDisabled as ue,isIsolatedDaemonE2eInstance as he,registerDaemonCommand as fe,writeDaemonPid as K,writeDaemonLauncher as W}from"./commands/daemon.js";import{registerRuntimeCommand as Se}from"./commands/runtime.js";import{registerManagerCommand as ve}from"./commands/manager.js";import{registerUpgradeCommand as we}from"./commands/upgrade.js";import{registerToolsCommand as Ie}from"./commands/tools.js";import{registerIntegrationCommand as ye}from"./commands/integration.js";import{registerRoomCommand as Re}from"./commands/room.js";import{SessionManager as Ce}from"./session/manager.js";import{SERVERS as P,regionToUrl as ke,urlToRegion as De}from"./region.js";import{getCurrentVersion as Y,handleStartupCrashCheck as Ee}from"./upgrade/engine.js";import{AutoUpgradeScheduler as Te}from"./upgrade/scheduler.js";import{detectAgents as Ae}from"./agents/detect.js";import{augmentProcessPath as Q}from"./env-path.js";Q();const q=Y();import{getCachedAgentInfos as Ue,resolveAgentInfos as Oe}from"./agents/model-registry.js";import{initCliLogReporter as $e,reportLog as I}from"./log-reporter.js";import{isNativeFusionEnabled as Ne}from"./native-fusion/config.js";import{NativeSessionFusionService as be}from"./native-fusion/service.js";import{startDaemonLogRetention as Pe}from"./daemon-log.js";import{startDaemonIpcServer as _e}from"./daemon-ipc/server.js";import{RoomSessionRegistry as Me}from"./room/session-registry.js";import{HttpRoomBindingClient as Le}from"./room/room-binding-client.js";import{TrustedManagedRoomBinder as xe}from"./room/managed-room-binding.js";import{RoomHostSessionObservationStore as Ve}from"./room/host-session-observations.js";import{RoomMirrorSyncService as Be}from"./room/mirror-sync-service.js";import{RoomActivationService as He}from"./room/activation-service.js";import{RoomActivationAudit as Ge}from"./room/activation-audit.js";import{RoomAttachmentCache as Fe}from"./room/attachment-cache.js";import{RoomAttachmentUploader as Je}from"./room/attachment-upload.js";import{ManagedRoomContextAuthority as ze}from"./room/managed-context.js";import{createManagedRoomIpcHandlers as je}from"./room/managed-room-ipc.js";import{SESSION_SYNC_PROTOCOL_VERSION as Ke,SESSION_SYNC_REQUIRED_CAPABILITIES as We}from"@shennian/wire";import{getDaemonInstallationId as Ye}from"./session/store.js";import{synchronizeMachinePersonalAuthority as Qe}from"./personal-sync/machine-authority.js";import{getPersonalSyncLocalMetrics as qe}from"./personal-sync/metrics.js";import{CLI_SESSION_SYNC_DATA_EPOCH as Xe,ensurePersonalDataEpoch as Ze}from"./personal-sync/epoch.js";import{DeletionSyncRetryWaitError as eo,DeletionSyncTerminalError as oo}from"./session/deletion-sync-state.js";const X=ae(),no=J("daemon.pid");function to(){try{const o=b.readFileSync(no,"utf-8").trim();if(o.startsWith("{")){const i=JSON.parse(o),c=Number(i.pid);return Number.isInteger(c)&&c>0?c:null}const n=parseInt(o,10);return Number.isInteger(n)&&n>0?n:null}catch{return null}}function ro(o){return o.replace(/^https:\/\//,"wss://").replace(/^http:\/\//,"ws://")}function _(){process.stdout.write(`${JSON.stringify({ok:!1,error:"integration_command_retired",message:"Room MCP and Hooks were retired. Use the Shennian Skill and CLI.",nextAction:{type:"open_install_guide",url:"https://shennian.net/install.md"}})}
|
|
2
|
+
`),process.exitCode=1}function io(o){const n=[`trigger=${o.trigger??"unknown"}`,`phase=${o.phase}`,`code=${o.code??"unknown"}`,`attempt=${o.reconnectAttempt}`];return o.reason&&n.push(`reason=${o.reason}`),o.error&&n.push(`error=${o.error}`),n.join(" ")}async function Z(o,n=5e3){const i=Date.now();for(;Date.now()-i<n;){try{process.kill(o,0)}catch{return!0}await new Promise(c=>setTimeout(c,100))}try{return process.kill(o,0),!1}catch{return!0}}const t=new te;t.name("shennian").description("Shennian \u2014 AI Agent Control Plane").version(q),t.enablePositionalOptions(),ye(t),Re(t),t.option("--api <url>","Server URL override").option("--name <name>","Machine name",re.hostname()).action(async o=>{const n=d(),i=o.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??n.serverUrl??void 0;await de(i,o.name)}),t.command("run-service",{hidden:!0}).description("(internal) Connect to relay server, called by the background service").option("--api <url>","Server URL override").action(async o=>{const n=J("env.json");try{const e=JSON.parse(b.readFileSync(n,"utf-8"));for(const[s,r]of Object.entries(e))process.env[s]||(process.env[s]=r);Q()}catch{}const i=Pe();ue()&&(console.log(`[${new Date().toISOString()}] remote access disabled, service start skipped`),clearInterval(i),process.exit(0));const c=!!(process.env.INVOCATION_ID||process.env.JOURNAL_STREAM||process.env.SHENNIAN_DESKTOP_SERVER_URL),M=async(e,s)=>{console.log(`[${new Date().toISOString()}] ${s} (PID ${e})`),process.kill(e,"SIGTERM"),await Z(e)||(process.kill(e,"SIGKILL"),await Z(e,2e3))};try{const e=to();if(e&&e!==process.pid)try{process.kill(e,0),c?await M(e,"managed start taking over from existing daemon"):(console.log(`[${new Date().toISOString()}] daemon already running (PID ${e}), skipping duplicate start`),process.exit(0))}catch{}}catch{}const U=he(process.env,X)?[]:ge(process.pid);if(U.length>0)if(c)for(const e of U)try{await M(e,"managed start taking over from orphan daemon")}catch{}else console.log(`[${new Date().toISOString()}] daemon already running (PID ${U[0]}), skipping duplicate start`),process.exit(0);const l=pe();K(process.pid,l,{version:q}),W(process.pid,void 0,l),process.on("exit",()=>{z(process.pid,l),j(l)}),await Ee()&&(console.log(`[${new Date().toISOString()}] Rolled back to previous version, restarting...`),process.exit(0));try{Ze()}catch(e){console.error(`[personal-sync] data epoch initialization failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}const a=d(),g=o.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??a.serverUrl??P.cn.url,p=Y(),O=Ae(),h=O.map(e=>e.type),$=Ue(O),y=new Me,R=new Ve,L=new ze(y),f=new Le(g),oe=new Fe({actionClient:f}),ne=new Je({actionClient:f});let x=null;const C=await _e({handlers:{"personal.sync.metrics":()=>qe(),...je({authority:L,actionClient:f,attachmentCache:oe,attachmentUploader:ne,observations:R,getMachineCredentials:()=>({machineToken:d().machineToken})})}});let V=!1;const k=()=>{V||(V=!0,C.close().finally(()=>process.exit(0)))};if(process.once("SIGINT",k),process.once("SIGTERM",k),!a.machineToken){console.error('Shennian CLI is not paired. Run "shennian pair --browser" or "shennian pair --token" first.'),await C.close(),process.exitCode=1;return}process.removeListener("SIGINT",k),process.removeListener("SIGTERM",k);const B=`${ro(g)}/relay/machine`,N=a.machineToken;if(!N)return;try{await Qe({serverUrl:g,machineToken:N,machineId:a.machineId})}catch(e){console.error(`[personal-sync] machine authority verification failed: ${e instanceof Error?e.message:String(e)}`),await C.close(),process.exitCode=1;return}a.machineId&&$e(g,a.machineId),console.log(`[${new Date().toISOString()}] Connecting to ${B}... (v${p}) agents: ${h.join(",")}`),I({level:"info",wsEvent:"daemon.start",metadata:{version:p,agents:h}});let D=null,E=null,T=0;const H=ce(a.autoUpgrade),m=new me({serverUrl:B,machineToken:N,cliVersion:p,agentList:h,autoUpgradePolicy:H,sessionSyncProtocolVersion:Ke,sessionSyncCapabilities:We,daemonInstallationId:Ye(),dataEpoch:Xe,onConnected:()=>{console.log(`[${new Date().toISOString()}] \u2713 Connected`),I({level:"info",wsEvent:"daemon.connected"}),$.some(r=>r.models.length>0)&&m.sendEvent({type:"event",event:"machine.agents",payload:{agentList:h,agents:$}}),Oe(O,{serverUrl:a.serverUrl??g,authToken:a.machineToken??a.accessToken}).then(r=>{JSON.stringify(r)!==JSON.stringify($)&&m.sendEvent({type:"event",event:"machine.agents",payload:{agentList:h,agents:r}})}).catch(()=>{}),import("./upgrade/engine.js").then(({readUpgradeAttempt:r,clearUpgradeAttempt:S})=>{const v=r();S(),v&&(console.log(`[${new Date().toISOString()}] [upgrade] Reporting success: ${v.from} \u2192 ${v.to}`),m.sendEvent({type:"event",event:"upgrade",payload:{state:"success",machineId:"self",from:v.from,to:v.to}}))}).catch(()=>{}),A.start(),E?.start();const e=++T,s=async()=>{try{await u.synchronizeSessionDeletions(),e===T&&m.getState()==="connected"&&D?.handleConnected()}catch(r){if(console.error("[session.deletions] startup catch-up failed",r),e===T&&m.getState()==="connected"){if(r instanceof oo)return;const S=r instanceof eo?Math.max(1e3,r.retryAfterMs):5e3;setTimeout(()=>{s()},S).unref?.()}}};s()},onDisconnected:e=>{T+=1,E?.stop(),console.log(`[${new Date().toISOString()}] \u26A0 Disconnected, reconnecting... ${io(e)}`),I({level:"warn",wsEvent:"daemon.disconnected",metadata:{code:e.code,reason:e.reason,error:e.error,phase:e.phase,trigger:e.trigger,reconnectAttempt:e.reconnectAttempt}})},onReq:e=>{console.log(`[${new Date().toISOString()}] [req] ${e.method}`),I({level:"info",type:"ws",wsEvent:e.method,wsDirection:"in",traceId:e.traceId}),u.handleReq(e)}});D=Ne()?new be(m):null,E=new Be({registry:y,observations:R,actionClient:f,getMachineCredentials:()=>({machineToken:d().machineToken}),onMessages:async(e,s,r,S)=>{await x?.processMessages(e,s,r,S)}});const A=new Te({currentVersion:p,machineId:a.machineId??"unknown-machine",serverUrl:a.serverUrl??g,getIdleState:()=>u.getUpgradeIdleState(),startUpgrade:async e=>{const{handleUpgradeStart:s}=await import("./commands/upgrade.js");await s(m,"auto-upgrade",e,{currentVersion:p})}});A.setPolicy(H);const u=new Ce(m,D,p,A,new xe({registry:y,observations:R,bindingClient:f,getMachineCredentials:()=>{const e=d();return{machineId:e.machineId,machineToken:e.machineToken}},hostProcessIdentity:()=>`daemon:${l}`}));x=new He({registry:y,observations:R,activate:e=>u.activateRoomSession(e),issueManagedRoomContext:e=>{const s=d().machineToken;if(!s)throw new Error("machine_not_authorized");return L.issue({registryKey:e,machineCredential:s})},abort:e=>u.abortRoomSession(e),audit:new Ge}),b.mkdirSync(X,{recursive:!0}),K(process.pid,l,{version:p}),W(process.pid,void 0,l),m.connect(),process.stdin.resume();let G=!1;const F=async()=>{if(!G){G=!0,console.log(w.gray(`
|
|
3
|
+
Disconnecting...`)),I({level:"info",wsEvent:"daemon.stop"}),clearInterval(i);try{await u.cleanup(),A.stop(),D?.stop(),E?.stop(),m.disconnect(),await C.close(),z(process.pid,l),j(l)}finally{process.exit(0)}}};process.on("SIGINT",()=>{F()}),process.on("SIGTERM",()=>{F()})}),t.command("workbuddy-session-hook",{hidden:!0}).description("(retired) WorkBuddy Room Hook").allowUnknownOption(!0).action(()=>_()),t.command("room-session-hook",{hidden:!0}).description("(internal) Authorize the official Room tool for one trusted Agent Session").argument("<runtime>","Trusted runtime adapter").allowUnknownOption(!0).action(()=>_()),t.command("room-tool-server",{hidden:!0}).description("(internal) Run the official Shennian Room MCP tool").allowUnknownOption(!0).action(()=>_());const ee=t.command("config").description("View or modify configuration");ee.command("show",{isDefault:!0}).description("Show current configuration").action(()=>{console.log(`Config file: ${se()}`);const n={...d()};if(n.machineToken&&(n.machineToken=n.machineToken.slice(0,12)+"..."),n.serverUrl){const i=De(n.serverUrl);console.log(`Region: ${i} (${P[i].label})`)}console.log(JSON.stringify(n,null,2))}),ee.command("set").description("Update a config value").argument("<key>",'Config key (e.g. "server")').argument("<value>",'Config value (e.g. "cn" or "global")').action((o,n)=>{const i=d();if(o==="server"){n!=="cn"&&n!=="global"&&(console.error(w.red('\u2717 Value must be "cn" or "global"')),process.exit(1));const c=n;i.serverUrl=ke(c),ie(i),console.log(w.green(`\u2713 Server set to ${P[c].label}`)),console.log(w.yellow(" Restart the background service for this to take effect: shennian stop && shennian start"));return}console.error(w.red(`\u2717 Unknown config key: ${o}. Supported: server`)),process.exit(1)}),le(t),fe(t),Se(t),ve(t),we(t),Ie(t),t.parse();
|