shennian 0.3.63 → 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 +78 -63
- 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-files.d.ts +2 -0
- package/dist/src/native-fusion/codex-files.js +1 -0
- package/dist/src/native-fusion/codex-parser.d.ts +1 -2
- package/dist/src/native-fusion/codex-parser.js +3 -5
- package/dist/src/native-fusion/codex-user-input.d.ts +11 -0
- package/dist/src/native-fusion/codex-user-input.js +5 -0
- 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,13 +301,23 @@
|
|
|
301
301
|
},
|
|
302
302
|
{
|
|
303
303
|
"file": "src/manager/runtime.js",
|
|
304
|
-
"beforeBytes":
|
|
305
|
-
"afterBytes":
|
|
304
|
+
"beforeBytes": 72214,
|
|
305
|
+
"afterBytes": 36669
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"file": "src/native-fusion/codex-files.js",
|
|
309
|
+
"beforeBytes": 2623,
|
|
310
|
+
"afterBytes": 1339
|
|
306
311
|
},
|
|
307
312
|
{
|
|
308
313
|
"file": "src/native-fusion/codex-parser.js",
|
|
309
|
-
"beforeBytes":
|
|
310
|
-
"afterBytes":
|
|
314
|
+
"beforeBytes": 28748,
|
|
315
|
+
"afterBytes": 11925
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"file": "src/native-fusion/codex-user-input.js",
|
|
319
|
+
"beforeBytes": 4098,
|
|
320
|
+
"afterBytes": 1925
|
|
311
321
|
},
|
|
312
322
|
{
|
|
313
323
|
"file": "src/native-fusion/config.js",
|
|
@@ -316,13 +326,13 @@
|
|
|
316
326
|
},
|
|
317
327
|
{
|
|
318
328
|
"file": "src/native-fusion/file-watcher.js",
|
|
319
|
-
"beforeBytes":
|
|
320
|
-
"afterBytes":
|
|
329
|
+
"beforeBytes": 7353,
|
|
330
|
+
"afterBytes": 3024
|
|
321
331
|
},
|
|
322
332
|
{
|
|
323
333
|
"file": "src/native-fusion/local-repository.js",
|
|
324
|
-
"beforeBytes":
|
|
325
|
-
"afterBytes":
|
|
334
|
+
"beforeBytes": 25241,
|
|
335
|
+
"afterBytes": 12409
|
|
326
336
|
},
|
|
327
337
|
{
|
|
328
338
|
"file": "src/native-fusion/native-source-deletions.js",
|
|
@@ -336,28 +346,28 @@
|
|
|
336
346
|
},
|
|
337
347
|
{
|
|
338
348
|
"file": "src/native-fusion/parser-common.js",
|
|
339
|
-
"beforeBytes":
|
|
340
|
-
"afterBytes":
|
|
349
|
+
"beforeBytes": 8685,
|
|
350
|
+
"afterBytes": 3912
|
|
341
351
|
},
|
|
342
352
|
{
|
|
343
353
|
"file": "src/native-fusion/parsers.js",
|
|
344
|
-
"beforeBytes":
|
|
345
|
-
"afterBytes":
|
|
354
|
+
"beforeBytes": 5850,
|
|
355
|
+
"afterBytes": 3235
|
|
346
356
|
},
|
|
347
357
|
{
|
|
348
358
|
"file": "src/native-fusion/service.js",
|
|
349
|
-
"beforeBytes":
|
|
350
|
-
"afterBytes":
|
|
359
|
+
"beforeBytes": 29648,
|
|
360
|
+
"afterBytes": 13788
|
|
351
361
|
},
|
|
352
362
|
{
|
|
353
363
|
"file": "src/native-fusion/session-header.js",
|
|
354
|
-
"beforeBytes":
|
|
364
|
+
"beforeBytes": 4294,
|
|
355
365
|
"afterBytes": 1996
|
|
356
366
|
},
|
|
357
367
|
{
|
|
358
368
|
"file": "src/native-fusion/state.js",
|
|
359
|
-
"beforeBytes":
|
|
360
|
-
"afterBytes":
|
|
369
|
+
"beforeBytes": 4112,
|
|
370
|
+
"afterBytes": 2111
|
|
361
371
|
},
|
|
362
372
|
{
|
|
363
373
|
"file": "src/native-fusion/types.js",
|
|
@@ -365,24 +375,29 @@
|
|
|
365
375
|
"afterBytes": 60
|
|
366
376
|
},
|
|
367
377
|
{
|
|
368
|
-
"file": "src/personal-sync/
|
|
369
|
-
"beforeBytes":
|
|
370
|
-
"afterBytes":
|
|
378
|
+
"file": "src/personal-sync/epoch.js",
|
|
379
|
+
"beforeBytes": 8116,
|
|
380
|
+
"afterBytes": 3955
|
|
371
381
|
},
|
|
372
382
|
{
|
|
373
383
|
"file": "src/personal-sync/identity.js",
|
|
374
|
-
"beforeBytes":
|
|
375
|
-
"afterBytes":
|
|
384
|
+
"beforeBytes": 2427,
|
|
385
|
+
"afterBytes": 1324
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"file": "src/personal-sync/machine-authority.js",
|
|
389
|
+
"beforeBytes": 1835,
|
|
390
|
+
"afterBytes": 1127
|
|
376
391
|
},
|
|
377
392
|
{
|
|
378
393
|
"file": "src/personal-sync/metrics.js",
|
|
379
|
-
"beforeBytes":
|
|
380
|
-
"afterBytes":
|
|
394
|
+
"beforeBytes": 2258,
|
|
395
|
+
"afterBytes": 1391
|
|
381
396
|
},
|
|
382
397
|
{
|
|
383
398
|
"file": "src/personal-sync/paths.js",
|
|
384
|
-
"beforeBytes":
|
|
385
|
-
"afterBytes":
|
|
399
|
+
"beforeBytes": 910,
|
|
400
|
+
"afterBytes": 479
|
|
386
401
|
},
|
|
387
402
|
{
|
|
388
403
|
"file": "src/region.js",
|
|
@@ -391,8 +406,8 @@
|
|
|
391
406
|
},
|
|
392
407
|
{
|
|
393
408
|
"file": "src/relay/client.js",
|
|
394
|
-
"beforeBytes":
|
|
395
|
-
"afterBytes":
|
|
409
|
+
"beforeBytes": 14515,
|
|
410
|
+
"afterBytes": 7173
|
|
396
411
|
},
|
|
397
412
|
{
|
|
398
413
|
"file": "src/room/activation-audit.js",
|
|
@@ -506,13 +521,13 @@
|
|
|
506
521
|
},
|
|
507
522
|
{
|
|
508
523
|
"file": "src/session/canonical-store.js",
|
|
509
|
-
"beforeBytes":
|
|
510
|
-
"afterBytes":
|
|
524
|
+
"beforeBytes": 31550,
|
|
525
|
+
"afterBytes": 15208
|
|
511
526
|
},
|
|
512
527
|
{
|
|
513
528
|
"file": "src/session/deletion-sync-state.js",
|
|
514
|
-
"beforeBytes":
|
|
515
|
-
"afterBytes":
|
|
529
|
+
"beforeBytes": 5030,
|
|
530
|
+
"afterBytes": 2897
|
|
516
531
|
},
|
|
517
532
|
{
|
|
518
533
|
"file": "src/session/handlers/agent-capabilities.js",
|
|
@@ -531,8 +546,8 @@
|
|
|
531
546
|
},
|
|
532
547
|
{
|
|
533
548
|
"file": "src/session/handlers/chat.js",
|
|
534
|
-
"beforeBytes":
|
|
535
|
-
"afterBytes":
|
|
549
|
+
"beforeBytes": 35022,
|
|
550
|
+
"afterBytes": 14909
|
|
536
551
|
},
|
|
537
552
|
{
|
|
538
553
|
"file": "src/session/handlers/control.js",
|
|
@@ -541,13 +556,13 @@
|
|
|
541
556
|
},
|
|
542
557
|
{
|
|
543
558
|
"file": "src/session/handlers/fs.js",
|
|
544
|
-
"beforeBytes":
|
|
545
|
-
"afterBytes":
|
|
559
|
+
"beforeBytes": 21924,
|
|
560
|
+
"afterBytes": 10383
|
|
546
561
|
},
|
|
547
562
|
{
|
|
548
563
|
"file": "src/session/handlers/message-status.js",
|
|
549
|
-
"beforeBytes":
|
|
550
|
-
"afterBytes":
|
|
564
|
+
"beforeBytes": 676,
|
|
565
|
+
"afterBytes": 392
|
|
551
566
|
},
|
|
552
567
|
{
|
|
553
568
|
"file": "src/session/handlers/room-managed.js",
|
|
@@ -561,33 +576,33 @@
|
|
|
561
576
|
},
|
|
562
577
|
{
|
|
563
578
|
"file": "src/session/handlers/title.js",
|
|
564
|
-
"beforeBytes":
|
|
565
|
-
"afterBytes":
|
|
579
|
+
"beforeBytes": 3128,
|
|
580
|
+
"afterBytes": 1668
|
|
566
581
|
},
|
|
567
582
|
{
|
|
568
583
|
"file": "src/session/handlers/tool-detail.js",
|
|
569
|
-
"beforeBytes":
|
|
570
|
-
"afterBytes":
|
|
584
|
+
"beforeBytes": 6399,
|
|
585
|
+
"afterBytes": 3357
|
|
571
586
|
},
|
|
572
587
|
{
|
|
573
588
|
"file": "src/session/handlers/voice-window.js",
|
|
574
|
-
"beforeBytes":
|
|
575
|
-
"afterBytes":
|
|
589
|
+
"beforeBytes": 2556,
|
|
590
|
+
"afterBytes": 1252
|
|
576
591
|
},
|
|
577
592
|
{
|
|
578
593
|
"file": "src/session/history-subscriptions.js",
|
|
579
|
-
"beforeBytes":
|
|
580
|
-
"afterBytes":
|
|
594
|
+
"beforeBytes": 8639,
|
|
595
|
+
"afterBytes": 4283
|
|
581
596
|
},
|
|
582
597
|
{
|
|
583
598
|
"file": "src/session/index-publisher.js",
|
|
584
|
-
"beforeBytes":
|
|
585
|
-
"afterBytes":
|
|
599
|
+
"beforeBytes": 7582,
|
|
600
|
+
"afterBytes": 3747
|
|
586
601
|
},
|
|
587
602
|
{
|
|
588
603
|
"file": "src/session/manager.js",
|
|
589
|
-
"beforeBytes":
|
|
590
|
-
"afterBytes":
|
|
604
|
+
"beforeBytes": 27929,
|
|
605
|
+
"afterBytes": 14336
|
|
591
606
|
},
|
|
592
607
|
{
|
|
593
608
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -596,8 +611,8 @@
|
|
|
596
611
|
},
|
|
597
612
|
{
|
|
598
613
|
"file": "src/session/native-session-lifecycle.js",
|
|
599
|
-
"beforeBytes":
|
|
600
|
-
"afterBytes":
|
|
614
|
+
"beforeBytes": 14160,
|
|
615
|
+
"afterBytes": 6446
|
|
601
616
|
},
|
|
602
617
|
{
|
|
603
618
|
"file": "src/session/projection.js",
|
|
@@ -606,13 +621,13 @@
|
|
|
606
621
|
},
|
|
607
622
|
{
|
|
608
623
|
"file": "src/session/queue.js",
|
|
609
|
-
"beforeBytes":
|
|
610
|
-
"afterBytes":
|
|
624
|
+
"beforeBytes": 19312,
|
|
625
|
+
"afterBytes": 8831
|
|
611
626
|
},
|
|
612
627
|
{
|
|
613
628
|
"file": "src/session/store.js",
|
|
614
|
-
"beforeBytes":
|
|
615
|
-
"afterBytes":
|
|
629
|
+
"beforeBytes": 25840,
|
|
630
|
+
"afterBytes": 13364
|
|
616
631
|
},
|
|
617
632
|
{
|
|
618
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();
|