shennian 0.2.88 → 0.2.90

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.
Files changed (143) hide show
  1. package/dist/assets/wechat-channel/macos/manifest.json +22 -0
  2. package/dist/assets/wechat-channel/macos/shennian-wechat-channel-helper +0 -0
  3. package/dist/bin/shennian.js +1 -1
  4. package/dist/publish-build-manifest.json +548 -0
  5. package/dist/scripts/wechat-rpa-confirmation.mjs +5 -97
  6. package/dist/src/agent-env.js +4 -105
  7. package/dist/src/agents/adapter.d.ts +6 -0
  8. package/dist/src/agents/adapter.js +1 -19
  9. package/dist/src/agents/claude.js +8 -305
  10. package/dist/src/agents/codex-control.d.ts +35 -0
  11. package/dist/src/agents/codex-control.js +2 -0
  12. package/dist/src/agents/codex-utils.js +7 -200
  13. package/dist/src/agents/codex.d.ts +8 -0
  14. package/dist/src/agents/codex.js +15 -863
  15. package/dist/src/agents/command-spec.js +2 -413
  16. package/dist/src/agents/config-status.js +1 -226
  17. package/dist/src/agents/cursor.js +1 -249
  18. package/dist/src/agents/custom.js +4 -271
  19. package/dist/src/agents/detect.js +1 -56
  20. package/dist/src/agents/external-channel-instructions.js +10 -94
  21. package/dist/src/agents/gemini.js +1 -173
  22. package/dist/src/agents/manager.js +13 -157
  23. package/dist/src/agents/model-registry/cache.js +1 -37
  24. package/dist/src/agents/model-registry/discovery.js +2 -187
  25. package/dist/src/agents/model-registry/parsers.js +4 -447
  26. package/dist/src/agents/model-registry/runner.js +1 -30
  27. package/dist/src/agents/model-registry/service.js +1 -78
  28. package/dist/src/agents/model-registry/types.js +1 -8
  29. package/dist/src/agents/model-registry.js +1 -18
  30. package/dist/src/agents/openclaw.js +2 -275
  31. package/dist/src/agents/opencode.js +1 -231
  32. package/dist/src/agents/pi-context.js +12 -217
  33. package/dist/src/agents/pi.js +14 -723
  34. package/dist/src/agents/platform-instructions.js +9 -54
  35. package/dist/src/channels/base.d.ts +4 -1
  36. package/dist/src/channels/base.js +1 -3
  37. package/dist/src/channels/registry.js +1 -30
  38. package/dist/src/channels/reply-split.js +10 -89
  39. package/dist/src/channels/runtime.d.ts +1 -0
  40. package/dist/src/channels/runtime.js +5 -533
  41. package/dist/src/channels/secret-registry.d.ts +1 -0
  42. package/dist/src/channels/secret-registry.js +1 -46
  43. package/dist/src/channels/websocket.js +8 -378
  44. package/dist/src/channels/wechat-channel/anchor.d.ts +10 -0
  45. package/dist/src/channels/wechat-channel/anchor.js +1 -0
  46. package/dist/src/channels/wechat-channel/client.d.ts +74 -0
  47. package/dist/src/channels/wechat-channel/client.js +1 -0
  48. package/dist/src/channels/wechat-channel/cooldown.d.ts +15 -0
  49. package/dist/src/channels/wechat-channel/cooldown.js +1 -0
  50. package/dist/src/channels/wechat-channel/fingerprint.d.ts +28 -0
  51. package/dist/src/channels/wechat-channel/fingerprint.js +1 -0
  52. package/dist/src/channels/wechat-channel/helper-assets.d.ts +37 -0
  53. package/dist/src/channels/wechat-channel/helper-assets.js +1 -0
  54. package/dist/src/channels/wechat-channel/helper-client.d.ts +25 -0
  55. package/dist/src/channels/wechat-channel/helper-client.js +3 -0
  56. package/dist/src/channels/wechat-channel/helper-protocol.d.ts +84 -0
  57. package/dist/src/channels/wechat-channel/helper-protocol.js +1 -0
  58. package/dist/src/channels/wechat-channel/index.d.ts +17 -0
  59. package/dist/src/channels/wechat-channel/index.js +1 -0
  60. package/dist/src/channels/wechat-channel/ledger.d.ts +33 -0
  61. package/dist/src/channels/wechat-channel/ledger.js +1 -0
  62. package/dist/src/channels/wechat-channel/media-resolver.d.ts +32 -0
  63. package/dist/src/channels/wechat-channel/media-resolver.js +1 -0
  64. package/dist/src/channels/wechat-channel/message-key.d.ts +19 -0
  65. package/dist/src/channels/wechat-channel/message-key.js +1 -0
  66. package/dist/src/channels/wechat-channel/observer.d.ts +64 -0
  67. package/dist/src/channels/wechat-channel/observer.js +1 -0
  68. package/dist/src/channels/wechat-channel/outbound-ledger.d.ts +69 -0
  69. package/dist/src/channels/wechat-channel/outbound-ledger.js +2 -0
  70. package/dist/src/channels/wechat-channel/outbound-sender.d.ts +26 -0
  71. package/dist/src/channels/wechat-channel/outbound-sender.js +1 -0
  72. package/dist/src/channels/wechat-channel/preflight.d.ts +37 -0
  73. package/dist/src/channels/wechat-channel/preflight.js +1 -0
  74. package/dist/src/channels/wechat-channel/runner.d.ts +34 -0
  75. package/dist/src/channels/wechat-channel/runner.js +1 -0
  76. package/dist/src/channels/wechat-channel/runtime.d.ts +45 -0
  77. package/dist/src/channels/wechat-channel/runtime.js +1 -0
  78. package/dist/src/channels/wechat-channel/scheduler.d.ts +35 -0
  79. package/dist/src/channels/wechat-channel/scheduler.js +1 -0
  80. package/dist/src/channels/wechat-rpa/macos-flow.js +1 -96
  81. package/dist/src/channels/wechat-rpa/macos.js +6 -48
  82. package/dist/src/channels/wechat-rpa/normalizer.js +7 -127
  83. package/dist/src/channels/wechat-rpa.d.ts +21 -0
  84. package/dist/src/channels/wechat-rpa.js +6 -1022
  85. package/dist/src/channels/wecom.js +4 -357
  86. package/dist/src/commands/agent.js +6 -131
  87. package/dist/src/commands/daemon-windows.js +8 -48
  88. package/dist/src/commands/daemon.js +19 -1013
  89. package/dist/src/commands/external-attachments.js +1 -51
  90. package/dist/src/commands/external.js +1 -137
  91. package/dist/src/commands/manager.js +2 -389
  92. package/dist/src/commands/pair-qr.js +1 -6
  93. package/dist/src/commands/pair.js +9 -287
  94. package/dist/src/commands/tools.js +1 -34
  95. package/dist/src/commands/upgrade.js +1 -198
  96. package/dist/src/config/index.js +1 -35
  97. package/dist/src/daemon-log.js +6 -58
  98. package/dist/src/env-path.js +1 -64
  99. package/dist/src/fs/boundary.js +1 -126
  100. package/dist/src/fs/handler.js +1 -130
  101. package/dist/src/fs/security.js +1 -32
  102. package/dist/src/fs/text-decoder.d.ts +10 -0
  103. package/dist/src/fs/text-decoder.js +1 -0
  104. package/dist/src/index.js +2 -404
  105. package/dist/src/log-reporter.js +1 -16
  106. package/dist/src/manager/prompt.js +29 -34
  107. package/dist/src/manager/registry.js +2 -269
  108. package/dist/src/manager/runtime.js +19 -1003
  109. package/dist/src/native-fusion/config.js +1 -5
  110. package/dist/src/native-fusion/opencode-parser.js +3 -123
  111. package/dist/src/native-fusion/parser-common.js +8 -264
  112. package/dist/src/native-fusion/parsers.js +8 -729
  113. package/dist/src/native-fusion/service.d.ts +10 -0
  114. package/dist/src/native-fusion/service.js +2 -198
  115. package/dist/src/native-fusion/state.js +1 -22
  116. package/dist/src/native-fusion/types.js +1 -1
  117. package/dist/src/region.js +1 -88
  118. package/dist/src/relay/client.js +1 -343
  119. package/dist/src/session/archive-zip.js +1 -220
  120. package/dist/src/session/handlers/agent-config.js +1 -150
  121. package/dist/src/session/handlers/agents.js +1 -55
  122. package/dist/src/session/handlers/chat.js +2 -733
  123. package/dist/src/session/handlers/control.js +1 -55
  124. package/dist/src/session/handlers/fs.js +1 -747
  125. package/dist/src/session/handlers/session-refresh.js +1 -35
  126. package/dist/src/session/handlers/skills.js +1 -121
  127. package/dist/src/session/handlers/title.js +1 -60
  128. package/dist/src/session/handlers/tool-detail.d.ts +3 -0
  129. package/dist/src/session/handlers/tool-detail.js +1 -0
  130. package/dist/src/session/manager.d.ts +3 -0
  131. package/dist/src/session/manager.js +1 -261
  132. package/dist/src/session/projection.js +1 -54
  133. package/dist/src/session/queue.js +4 -317
  134. package/dist/src/session/remote-attachments.js +1 -72
  135. package/dist/src/session/store.js +3 -109
  136. package/dist/src/session/types.d.ts +4 -0
  137. package/dist/src/session/types.js +1 -4
  138. package/dist/src/skills/registry.js +15 -148
  139. package/dist/src/skills/setup.js +1 -101
  140. package/dist/src/tools/markdown-to-pdf.js +10 -346
  141. package/dist/src/upgrade/engine.js +3 -347
  142. package/package.json +3 -2
  143. package/dist/scripts/wechat-rpa-download-candidates.mjs +0 -105
@@ -1,12 +1,4 @@
1
- // @arch docs/architecture/cli/agent-adapters.md#平台输出规范
2
- // @test src/__tests__/platform-instructions.test.ts
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { createHash } from 'node:crypto';
6
- import { resolveShennianPath } from '../config/index.js';
7
- import { buildExternalChannelInstructions } from './external-channel-instructions.js';
8
- import { buildInstalledSkillInstructions } from '../skills/registry.js';
9
- export const PLATFORM_OUTPUT_INSTRUCTIONS = `## Shennian Output Instructions
1
+ import s from"node:fs";import a from"node:path";import{createHash as c}from"node:crypto";import{resolveShennianPath as l}from"../config/index.js";import{buildExternalChannelInstructions as u}from"./external-channel-instructions.js";import{buildInstalledSkillInstructions as f}from"../skills/registry.js";const h=`## Shennian Output Instructions
10
2
 
11
3
  When you mention a local file that the user may want to open in Shennian, format it as a Markdown link using the exact local path:
12
4
 
@@ -14,48 +6,11 @@ When you mention a local file that the user may want to open in Shennian, format
14
6
  - Use [filename.ext](<relative/path/to/filename.ext>) for paths relative to the current working directory.
15
7
  - Do not use file:// URLs for local files.
16
8
  - Do not put user-openable file paths only inside code blocks.
17
- - Keep normal http:// and https:// links unchanged.`;
18
- function readProjectAgentsMd(workDir) {
19
- const agentsPath = path.join(workDir, 'AGENTS.md');
20
- try {
21
- return fs.readFileSync(agentsPath, 'utf8').trim();
22
- }
23
- catch {
24
- return '';
25
- }
26
- }
27
- export function buildPlatformInstructions(workDir, externalChannel, sessionId) {
28
- const projectInstructions = readProjectAgentsMd(workDir);
29
- const channelInstructions = buildExternalChannelInstructions(externalChannel, path.resolve(workDir), sessionId);
30
- const skillInstructions = buildInstalledSkillInstructions();
31
- const sections = [
32
- '# Shennian Agent Instructions',
33
- projectInstructions
34
- ? `## Project Instructions\n\n${projectInstructions}`
35
- : '',
36
- PLATFORM_OUTPUT_INSTRUCTIONS,
37
- skillInstructions,
38
- channelInstructions
39
- ? `## External Message Channel Instructions\n\n${channelInstructions}`
40
- : '',
41
- ].filter(Boolean);
42
- return `${sections.join('\n\n')}\n`;
43
- }
44
- export function ensurePlatformInstructionsFile(workDir, externalChannel, sessionId) {
45
- const key = createHash('sha256')
46
- .update(`${path.resolve(workDir)}:${sessionId ?? ''}:${JSON.stringify(externalChannel ?? null)}`)
47
- .digest('hex')
48
- .slice(0, 16);
49
- const filePath = resolveShennianPath('runtime', 'agent-instructions', `${key}.md`);
50
- const content = buildPlatformInstructions(workDir, externalChannel, sessionId);
51
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
52
- try {
53
- if (fs.readFileSync(filePath, 'utf8') === content)
54
- return filePath;
55
- }
56
- catch {
57
- // Write the generated instruction file below.
58
- }
59
- fs.writeFileSync(filePath, content);
60
- return filePath;
61
- }
9
+ - Keep normal http:// and https:// links unchanged.`;function m(n){const e=a.join(n,"AGENTS.md");try{return s.readFileSync(e,"utf8").trim()}catch{return""}}function p(n,e,o){const r=m(n),t=u(e,a.resolve(n),o),i=f();return`${["# Shennian Agent Instructions",r?`## Project Instructions
10
+
11
+ ${r}`:"",h,i,t?`## External Message Channel Instructions
12
+
13
+ ${t}`:""].filter(Boolean).join(`
14
+
15
+ `)}
16
+ `}function b(n,e,o){const r=c("sha256").update(`${a.resolve(n)}:${o??""}:${JSON.stringify(e??null)}`).digest("hex").slice(0,16),t=l("runtime","agent-instructions",`${r}.md`),i=p(n,e,o);s.mkdirSync(a.dirname(t),{recursive:!0});try{if(s.readFileSync(t,"utf8")===i)return t}catch{}return s.writeFileSync(t,i),t}export{h as PLATFORM_OUTPUT_INSTRUCTIONS,p as buildPlatformInstructions,b as ensurePlatformInstructionsFile};
@@ -1,5 +1,5 @@
1
1
  import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
- export type ExternalChannelRuntimeStatus = Pick<ExternalChannelSessionStatus, 'wechatRpaRuntimeState' | 'wechatRpaLastRunAt' | 'wechatRpaLastMessageAt' | 'wechatRpaLastInterruptedAt' | 'wechatRpaPendingReplyCount' | 'wechatRpaLastError' | 'wechatRpaLastRunId' | 'wechatRpaLastTracePath' | 'wechatRpaLastTraceSummary' | 'wechatRpaRecentTaskSummaries'>;
2
+ export type ExternalChannelRuntimeStatus = Pick<ExternalChannelSessionStatus, 'wechatRpaRuntimeState' | 'wechatRpaLastRunAt' | 'wechatRpaLastMessageAt' | 'wechatRpaLastInterruptedAt' | 'wechatRpaPendingReplyCount' | 'wechatRpaLastError' | 'wechatRpaLastRunId' | 'wechatRpaLastTracePath' | 'wechatRpaLastTraceSummary' | 'wechatRpaRecentTaskSummaries' | 'wechatRpaPreflightChecks' | 'wechatRpaServerDecisionAvailable' | 'wechatRpaPrivacyConsentAccepted'>;
3
3
  export type ExternalChannelType = 'wecom' | 'websocket' | 'wechat-rpa';
4
4
  export type ExternalChannelConfig = {
5
5
  id: string;
@@ -51,6 +51,9 @@ export type ExternalChannelView = {
51
51
  wechatRpaLastTracePath?: string | null;
52
52
  wechatRpaLastTraceSummary?: string | null;
53
53
  wechatRpaRecentTaskSummaries?: ExternalChannelSessionStatus['wechatRpaRecentTaskSummaries'];
54
+ wechatRpaPreflightChecks?: ExternalChannelSessionStatus['wechatRpaPreflightChecks'];
55
+ wechatRpaServerDecisionAvailable?: boolean | null;
56
+ wechatRpaPrivacyConsentAccepted?: boolean | null;
54
57
  };
55
58
  export type ExternalMessageEvent = {
56
59
  type: 'external.message';
@@ -1,3 +1 @@
1
- // @arch docs/features/manager-agent.md
2
- // @test src/__tests__/manager-runtime.test.ts
3
- export {};
1
+
@@ -1,30 +1 @@
1
- // @arch docs/features/manager-agent.md
2
- // @test src/__tests__/manager-runtime.test.ts
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { resolveShennianPath } from '../config/index.js';
6
- const CHANNELS_PATH = resolveShennianPath('channels.json');
7
- export class ChannelConfigRegistry {
8
- list() {
9
- try {
10
- const parsed = JSON.parse(fs.readFileSync(CHANNELS_PATH, 'utf-8'));
11
- return parsed.channels ?? [];
12
- }
13
- catch {
14
- return [];
15
- }
16
- }
17
- get(channelId) {
18
- return this.list().find((channel) => channel.id === channelId);
19
- }
20
- upsert(config) {
21
- const channels = this.list().filter((channel) => channel.id !== config.id);
22
- channels.push(config);
23
- fs.mkdirSync(path.dirname(CHANNELS_PATH), { recursive: true });
24
- fs.writeFileSync(CHANNELS_PATH, JSON.stringify({ channels }, null, 2));
25
- }
26
- replaceAll(channels) {
27
- fs.mkdirSync(path.dirname(CHANNELS_PATH), { recursive: true });
28
- fs.writeFileSync(CHANNELS_PATH, JSON.stringify({ channels }, null, 2));
29
- }
30
- }
1
+ import e from"node:fs";import t from"node:path";import{resolveShennianPath as l}from"../config/index.js";const i=l("channels.json");class d{list(){try{return JSON.parse(e.readFileSync(i,"utf-8")).channels??[]}catch{return[]}}get(r){return this.list().find(n=>n.id===r)}upsert(r){const n=this.list().filter(s=>s.id!==r.id);n.push(r),e.mkdirSync(t.dirname(i),{recursive:!0}),e.writeFileSync(i,JSON.stringify({channels:n},null,2))}replaceAll(r){e.mkdirSync(t.dirname(i),{recursive:!0}),e.writeFileSync(i,JSON.stringify({channels:r},null,2))}}export{d as ChannelConfigRegistry};
@@ -1,89 +1,10 @@
1
- // @arch docs/features/manager-agent.md
2
- // @test src/__tests__/external-reply-split.test.ts
3
- const MAX_REPLY_CHARS = 500;
4
- const TARGET_REPLY_CHARS = 360;
5
- const MAX_REPLY_PARTS = 6;
6
- function visualLength(text) {
7
- return Array.from(text).length;
8
- }
9
- function sliceVisual(text, maxLength) {
10
- return Array.from(text).slice(0, maxLength).join('');
11
- }
12
- function normalizeReplyText(text) {
13
- return text
14
- .replace(/\r\n/g, '\n')
15
- .replace(/[ \t]+\n/g, '\n')
16
- .replace(/\n[ \t]+/g, '\n')
17
- .trim();
18
- }
19
- function splitLongParagraph(paragraph) {
20
- const pieces = [];
21
- const sentences = paragraph
22
- .split(/(?<=[。!?!?;;])\s*/)
23
- .map((part) => part.trim())
24
- .filter(Boolean);
25
- const units = sentences.length > 1 ? sentences : Array.from(paragraph);
26
- let current = '';
27
- for (const unit of units) {
28
- const next = current ? `${current}${sentences.length > 1 ? '' : ''}${unit}` : unit;
29
- if (current && visualLength(next) > TARGET_REPLY_CHARS) {
30
- pieces.push(current);
31
- current = unit;
32
- }
33
- else {
34
- current = next;
35
- }
36
- }
37
- if (current)
38
- pieces.push(current);
39
- return pieces.flatMap((piece) => {
40
- if (visualLength(piece) <= MAX_REPLY_CHARS)
41
- return [piece];
42
- const chars = Array.from(piece);
43
- const chunks = [];
44
- for (let i = 0; i < chars.length; i += TARGET_REPLY_CHARS) {
45
- chunks.push(chars.slice(i, i + TARGET_REPLY_CHARS).join('').trim());
46
- }
47
- return chunks.filter(Boolean);
48
- });
49
- }
50
- function capReplyParts(chunks) {
51
- if (chunks.length <= MAX_REPLY_PARTS)
52
- return chunks;
53
- const head = chunks.slice(0, MAX_REPLY_PARTS - 1);
54
- const tail = chunks.slice(MAX_REPLY_PARTS - 1).join('\n\n');
55
- const tailText = visualLength(tail) > MAX_REPLY_CHARS
56
- ? `${sliceVisual(tail, MAX_REPLY_CHARS - 1)}…`
57
- : tail;
58
- return [...head, tailText].filter(Boolean);
59
- }
60
- export function splitExternalReplyText(text) {
61
- const normalized = normalizeReplyText(text);
62
- if (!normalized)
63
- return [];
64
- if (visualLength(normalized) <= MAX_REPLY_CHARS && !normalized.includes('\n\n'))
65
- return [normalized];
66
- const paragraphs = normalized
67
- .split(/\n{2,}/)
68
- .map((part) => part.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim())
69
- .filter(Boolean);
70
- if (paragraphs.length > 1 && visualLength(normalized) > TARGET_REPLY_CHARS) {
71
- return capReplyParts(paragraphs.flatMap(splitLongParagraph));
72
- }
73
- const sourceParts = paragraphs.length > 1 ? paragraphs : [normalized.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim()];
74
- const chunks = [];
75
- let current = '';
76
- for (const part of sourceParts.flatMap(splitLongParagraph)) {
77
- const next = current ? `${current}\n\n${part}` : part;
78
- if (current && visualLength(next) > MAX_REPLY_CHARS) {
79
- chunks.push(current);
80
- current = part;
81
- }
82
- else {
83
- current = next;
84
- }
85
- }
86
- if (current)
87
- chunks.push(current);
88
- return capReplyParts(chunks);
89
- }
1
+ const _=500,p=360,P=6;function s(t){return Array.from(t).length}function f(t,e){return Array.from(t).slice(0,e).join("")}function u(t){return t.replace(/\r\n/g,`
2
+ `).replace(/[ \t]+\n/g,`
3
+ `).replace(/\n[ \t]+/g,`
4
+ `).trim()}function R(t){const e=[],r=t.split(/(?<=[。!?!?;;])\s*/).map(n=>n.trim()).filter(Boolean),i=r.length>1?r:Array.from(t);let l="";for(const n of i){const o=l?`${l}${r.length>1,""}${n}`:n;l&&s(o)>360?(e.push(l),l=n):l=o}return l&&e.push(l),e.flatMap(n=>{if(s(n)<=500)return[n];const o=Array.from(n),c=[];for(let a=0;a<o.length;a+=360)c.push(o.slice(a,a+360).join("").trim());return c.filter(Boolean)})}function A(t){if(t.length<=6)return t;const e=t.slice(0,5),r=t.slice(5).join(`
5
+
6
+ `),i=s(r)>500?`${f(r,499)}\u2026`:r;return[...e,i].filter(Boolean)}function E(t){const e=u(t);if(!e)return[];if(s(e)<=500&&!e.includes(`
7
+
8
+ `))return[e];const r=e.split(/\n{2,}/).map(o=>o.replace(/\n/g," ").replace(/\s+/g," ").trim()).filter(Boolean);if(r.length>1&&s(e)>360)return A(r.flatMap(R));const i=r.length>1?r:[e.replace(/\n/g," ").replace(/\s+/g," ").trim()],l=[];let n="";for(const o of i.flatMap(R)){const c=n?`${n}
9
+
10
+ ${o}`:o;n&&s(c)>500?(l.push(n),n=o):n=c}return n&&l.push(n),A(l)}export{E as splitExternalReplyText};
@@ -100,6 +100,7 @@ export declare class ChannelRuntime {
100
100
  downloadAttachments?: boolean;
101
101
  downloadAttachmentsDir?: string;
102
102
  selfNickname?: string;
103
+ privacyConsentAccepted?: boolean;
103
104
  flowScriptPath?: string;
104
105
  }): Promise<ExternalChannelView>;
105
106
  }