shennian 0.3.85 → 0.3.86

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 (99) hide show
  1. package/dist/bin/shennian.js +1 -1
  2. package/dist/publish-build-manifest.json +28 -28
  3. package/dist/src/agents/adapter.js +19 -1
  4. package/dist/src/agents/claude-managed-permissions.js +248 -1
  5. package/dist/src/agents/claude.js +393 -8
  6. package/dist/src/agents/codex-managed-permissions.js +294 -1
  7. package/dist/src/agents/codex-managed-room-tools.js +249 -1
  8. package/dist/src/agents/codex-utils.js +200 -7
  9. package/dist/src/agents/codex.js +1352 -17
  10. package/dist/src/agents/config-status.js +226 -1
  11. package/dist/src/agents/cursor-managed-permissions.js +299 -2
  12. package/dist/src/agents/cursor.js +314 -1
  13. package/dist/src/agents/custom.js +418 -4
  14. package/dist/src/agents/external-channel-instructions.js +94 -11
  15. package/dist/src/agents/gemini.js +180 -1
  16. package/dist/src/agents/manager.d.ts +2 -0
  17. package/dist/src/agents/manager.js +250 -18
  18. package/dist/src/agents/model-registry/cache.js +37 -1
  19. package/dist/src/agents/model-registry/discovery.js +188 -2
  20. package/dist/src/agents/model-registry/parsers.js +521 -4
  21. package/dist/src/agents/model-registry/runner.js +30 -1
  22. package/dist/src/agents/model-registry/service.js +115 -1
  23. package/dist/src/agents/model-registry/types.js +8 -1
  24. package/dist/src/agents/model-registry.js +19 -1
  25. package/dist/src/agents/native-capabilities.js +237 -1
  26. package/dist/src/agents/openclaw.js +293 -2
  27. package/dist/src/agents/opencode-managed-permissions.js +187 -2
  28. package/dist/src/agents/opencode.js +298 -1
  29. package/dist/src/agents/platform-instructions.js +46 -17
  30. package/dist/src/agents/runtime-compatibility.js +44 -1
  31. package/dist/src/agents/workbuddy-managed-permissions.js +329 -2
  32. package/dist/src/agents/workbuddy.js +444 -3
  33. package/dist/src/commands/room.js +2 -2
  34. package/dist/src/fs/boundary.js +185 -1
  35. package/dist/src/fs/handler.js +130 -1
  36. package/dist/src/fs/security.js +32 -1
  37. package/dist/src/fs/text-decoder.js +110 -1
  38. package/dist/src/index.js +587 -3
  39. package/dist/src/manager/prompt.js +34 -29
  40. package/dist/src/manager/registry.js +317 -1
  41. package/dist/src/manager/retired-external-channel-compat.js +40 -1
  42. package/dist/src/manager/runtime.d.ts +4 -0
  43. package/dist/src/manager/runtime.js +1514 -23
  44. package/dist/src/native-fusion/codex-parser.js +660 -4
  45. package/dist/src/native-fusion/codex-user-input.js +102 -5
  46. package/dist/src/native-fusion/config.js +5 -1
  47. package/dist/src/native-fusion/file-watcher.js +191 -1
  48. package/dist/src/native-fusion/local-repository.js +569 -2
  49. package/dist/src/native-fusion/opencode-parser.js +130 -3
  50. package/dist/src/native-fusion/parsers.js +140 -3
  51. package/dist/src/native-fusion/service.js +739 -2
  52. package/dist/src/native-fusion/session-header.js +101 -2
  53. package/dist/src/native-fusion/state.js +104 -2
  54. package/dist/src/native-fusion/types.js +1 -1
  55. package/dist/src/personal-sync/machine-authority.js +34 -1
  56. package/dist/src/room/activation-audit.js +45 -2
  57. package/dist/src/room/activation-policy.js +30 -1
  58. package/dist/src/room/activation-service.d.ts +1 -0
  59. package/dist/src/room/activation-service.js +408 -8
  60. package/dist/src/room/invite-bootstrap.js +156 -1
  61. package/dist/src/room/managed-context.d.ts +1 -1
  62. package/dist/src/room/managed-context.js +1 -1
  63. package/dist/src/room/managed-prompt-composer.d.ts +1 -1
  64. package/dist/src/room/managed-prompt-composer.js +6 -5
  65. package/dist/src/room/managed-room-binding.js +167 -1
  66. package/dist/src/room/managed-room-ipc.d.ts +2 -2
  67. package/dist/src/room/managed-room-ipc.js +2 -2
  68. package/dist/src/room/mirror-sync-service.js +183 -1
  69. package/dist/src/room/room-action-client.d.ts +11 -0
  70. package/dist/src/room/room-action-client.js +1 -1
  71. package/dist/src/room/room-binding-client.d.ts +1 -0
  72. package/dist/src/room/room-binding-client.js +151 -1
  73. package/dist/src/security/managed-agent-policy.d.ts +3 -2
  74. package/dist/src/security/managed-agent-policy.js +1 -1
  75. package/dist/src/session/archive-zip.js +220 -1
  76. package/dist/src/session/deletion-sync-state.js +136 -2
  77. package/dist/src/session/handlers/agent-capabilities.js +14 -1
  78. package/dist/src/session/handlers/agent-config.js +150 -1
  79. package/dist/src/session/handlers/agents.js +55 -1
  80. package/dist/src/session/handlers/chat.d.ts +1 -1
  81. package/dist/src/session/handlers/chat.js +1030 -2
  82. package/dist/src/session/handlers/control.js +61 -1
  83. package/dist/src/session/handlers/fs.js +594 -1
  84. package/dist/src/session/handlers/message-status.js +15 -1
  85. package/dist/src/session/handlers/remote-access.js +43 -1
  86. package/dist/src/session/handlers/room-managed.js +101 -1
  87. package/dist/src/session/handlers/session-refresh.js +35 -1
  88. package/dist/src/session/handlers/title.js +79 -1
  89. package/dist/src/session/handlers/tool-detail.js +149 -1
  90. package/dist/src/session/handlers/voice-window.js +62 -1
  91. package/dist/src/session/history-subscriptions.js +470 -1
  92. package/dist/src/session/manager.js +658 -1
  93. package/dist/src/session/native-cleanup-outbox.js +287 -2
  94. package/dist/src/session/native-session-lifecycle.js +327 -6
  95. package/dist/src/session/queue.d.ts +5 -0
  96. package/dist/src/session/queue.js +8 -8
  97. package/dist/src/upgrade/scheduler.js +126 -1
  98. package/node_modules/@shennian/wire/dist/agent-workspace.js +1 -1
  99. package/package.json +1 -1
@@ -1,2 +1,188 @@
1
- import{createInterface as m}from"node:readline";import{resolveBuiltinCommand as c,spawnResolvedCommand as v}from"../command-spec.js";import{fallbackClaudeAliasModels as M,discoverClaudeAliasModelsFromEnv as w,fallbackCodexModels as y,fallbackWorkBuddyModels as C,fallbackGeminiModels as h,parseCodexAppServerModels as g,parseCursorModels as E,parseOpenCodeModels as k}from"./parsers.js";import{runResolvedCommand as f}from"./runner.js";import{DISCOVERY_WORKDIR as b}from"./types.js";import{buildAgentProcessEnv as x,readLatestUserEnv as O}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as R}from"../codex-utils.js";function l(e,r,o,i,a,n){return e.stdin?new Promise((t,s)=>{const u=setTimeout(()=>{r.delete(o),s(new Error(`codex app-server request timed out: ${i}`))},n);r.set(o,{resolve:t,reject:s,timer:u}),e.stdin.write(`${JSON.stringify({id:o,method:i,params:a})}
2
- `,p=>{p&&(clearTimeout(u),r.delete(o),s(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function A(e){const r=v(e,["app-server","--listen","stdio://"],{cwd:b,stdio:["pipe","pipe","pipe"],env:x({NO_COLOR:"1"})}),o=new Map;let i=1;m({input:r.stdout}).on("line",n=>{if(!n.trim())return;let t;try{t=JSON.parse(n)}catch{return}if(t.id==null)return;const s=o.get(t.id);s&&(clearTimeout(s.timer),o.delete(t.id),t.error?s.reject(new Error(t.error.message||`codex app-server error ${t.error.code??""}`.trim())):s.resolve(t.result))});try{await l(r,o,i++,"initialize",{clientInfo:R,capabilities:{experimentalApi:!0}},1e4);const[n,t]=await Promise.all([l(r,o,i++,"model/list",{},15e3),l(r,o,i++,"config/read",{},15e3).catch(()=>null)]),s=typeof t=="object"&&t!==null&&"config"in t?t.config:void 0;return g({...typeof n=="object"&&n!==null?n:{},config:s})}finally{for(const[n,t]of o)clearTimeout(t.timer),t.reject(new Error("codex app-server stopped")),o.delete(n);r.kill("SIGTERM"),setTimeout(()=>r.kill("SIGKILL"),1e3).unref()}}async function S(){const e=c("cursor");if(!e)return[];const r=await f(e,["--list-models"]);return E(r.stdout)}async function I(){const e=c("opencode");if(!e)return[];const r=await f(e,["models"]);return k(r.stdout)}async function P(){if(!c("claude"))return[];const e=w(O());return e.length>0?e:M()}async function T(){const e=c("codex");if(!e)return[];const r=await A(e).catch(()=>[]);return r.length>0?r:y()}async function _(){return c("gemini")?h():[]}const d=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],D=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function L(e){if(!e.serverUrl||!e.authToken)return d;try{const r=await fetch(`${e.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${e.authToken}`}});if(!r.ok)return d;const o=await r.json(),i=(o.models??[]).map(a=>({id:a.id,name:a.name?.trim()||a.id,provider:a.provider,isDefault:a.id===o.default}));return i.length>0?i:d}catch{return d}}async function $(e,r){switch(e){case"claude":return P();case"codex":return T();case"workbuddy":return c("workbuddy")?C():[];case"gemini":return _();case"cursor":return S();case"openclaw":return[];case"opencode":return I();case"pi":return L(r);case"manager":return D}}async function V(e,r){return e.type.startsWith("custom:")?e.models??[]:$(e.type,r)}export{V as discoverModelsForAgent};
1
+ // @arch docs/architecture/cli/model-discovery.md
2
+ // @test src/__tests__/model-switching.test.ts
3
+ import { createInterface } from 'node:readline';
4
+ import { resolveBuiltinCommand, spawnResolvedCommand } from '../command-spec.js';
5
+ import { fallbackClaudeAliasModels, discoverClaudeAliasModelsFromEnv, fallbackCodexModels, fallbackWorkBuddyModels, fallbackGeminiModels, parseCodexAppServerModels, parseCursorModels, parseOpenCodeModels, } from './parsers.js';
6
+ import { runResolvedCommand } from './runner.js';
7
+ import { DISCOVERY_WORKDIR } from './types.js';
8
+ import { buildAgentProcessEnv, readLatestUserEnv } from '../../agent-env.js';
9
+ import { CODEX_APP_SERVER_CLIENT_INFO } from '../codex-utils.js';
10
+ function sendAppServerRpc(proc, pending, id, method, params, timeoutMs) {
11
+ if (!proc.stdin)
12
+ return Promise.reject(new Error('codex app-server stdin unavailable'));
13
+ return new Promise((resolve, reject) => {
14
+ const timer = setTimeout(() => {
15
+ pending.delete(id);
16
+ reject(new Error(`codex app-server request timed out: ${method}`));
17
+ }, timeoutMs);
18
+ pending.set(id, { resolve, reject, timer });
19
+ proc.stdin.write(`${JSON.stringify({ id, method, params })}\n`, (error) => {
20
+ if (!error)
21
+ return;
22
+ clearTimeout(timer);
23
+ pending.delete(id);
24
+ reject(error);
25
+ });
26
+ });
27
+ }
28
+ async function discoverCodexModelsViaAppServer(spec) {
29
+ const proc = spawnResolvedCommand(spec, ['app-server', '--listen', 'stdio://'], {
30
+ cwd: DISCOVERY_WORKDIR,
31
+ stdio: ['pipe', 'pipe', 'pipe'],
32
+ env: buildAgentProcessEnv({ NO_COLOR: '1' }),
33
+ });
34
+ const pending = new Map();
35
+ let seq = 1;
36
+ const rl = createInterface({ input: proc.stdout });
37
+ rl.on('line', (line) => {
38
+ if (!line.trim())
39
+ return;
40
+ let msg;
41
+ try {
42
+ msg = JSON.parse(line);
43
+ }
44
+ catch {
45
+ return;
46
+ }
47
+ if (msg.id == null)
48
+ return;
49
+ const request = pending.get(msg.id);
50
+ if (!request)
51
+ return;
52
+ clearTimeout(request.timer);
53
+ pending.delete(msg.id);
54
+ if (msg.error) {
55
+ request.reject(new Error(msg.error.message || `codex app-server error ${msg.error.code ?? ''}`.trim()));
56
+ }
57
+ else {
58
+ request.resolve(msg.result);
59
+ }
60
+ });
61
+ try {
62
+ await sendAppServerRpc(proc, pending, seq++, 'initialize', {
63
+ clientInfo: CODEX_APP_SERVER_CLIENT_INFO,
64
+ capabilities: { experimentalApi: true },
65
+ }, 10_000);
66
+ const [modelList, configRead] = await Promise.all([
67
+ sendAppServerRpc(proc, pending, seq++, 'model/list', {}, 15_000),
68
+ sendAppServerRpc(proc, pending, seq++, 'config/read', {}, 15_000).catch(() => null),
69
+ ]);
70
+ const config = typeof configRead === 'object' && configRead !== null && 'config' in configRead
71
+ ? configRead.config
72
+ : undefined;
73
+ return parseCodexAppServerModels({
74
+ ...(typeof modelList === 'object' && modelList !== null ? modelList : {}),
75
+ config,
76
+ });
77
+ }
78
+ finally {
79
+ for (const [id, request] of pending) {
80
+ clearTimeout(request.timer);
81
+ request.reject(new Error('codex app-server stopped'));
82
+ pending.delete(id);
83
+ }
84
+ proc.kill('SIGTERM');
85
+ setTimeout(() => proc.kill('SIGKILL'), 1000).unref();
86
+ }
87
+ }
88
+ async function discoverCursorModels() {
89
+ const spec = resolveBuiltinCommand('cursor');
90
+ if (!spec)
91
+ return [];
92
+ const result = await runResolvedCommand(spec, ['--list-models']);
93
+ return parseCursorModels(result.stdout);
94
+ }
95
+ // OpenClaw support is intentionally disabled.
96
+ // async function discoverOpenClawModels(): Promise<ModelInfo[]> {
97
+ // const spec = resolveBuiltinCommand('openclaw')
98
+ // if (!spec) return []
99
+ // const result = await runResolvedCommand(spec, ['models', 'list', '--json'])
100
+ // return parseOpenClawModels(result.stdout)
101
+ // }
102
+ async function discoverOpenCodeModels() {
103
+ const spec = resolveBuiltinCommand('opencode');
104
+ if (!spec)
105
+ return [];
106
+ const result = await runResolvedCommand(spec, ['models']);
107
+ return parseOpenCodeModels(result.stdout);
108
+ }
109
+ async function discoverClaudeModels() {
110
+ if (!resolveBuiltinCommand('claude'))
111
+ return [];
112
+ const shellEnvModels = discoverClaudeAliasModelsFromEnv(readLatestUserEnv());
113
+ if (shellEnvModels.length > 0)
114
+ return shellEnvModels;
115
+ return fallbackClaudeAliasModels();
116
+ }
117
+ async function discoverCodexModels() {
118
+ const spec = resolveBuiltinCommand('codex');
119
+ if (!spec)
120
+ return [];
121
+ const appServerModels = await discoverCodexModelsViaAppServer(spec).catch(() => []);
122
+ return appServerModels.length > 0 ? appServerModels : fallbackCodexModels();
123
+ }
124
+ async function discoverGeminiModels() {
125
+ if (!resolveBuiltinCommand('gemini'))
126
+ return [];
127
+ return fallbackGeminiModels();
128
+ }
129
+ const fallbackPiModels = [
130
+ { id: 'qwen3.6-plus', name: 'Qwen 3.6 Plus', provider: 'dashscope', isDefault: true },
131
+ ];
132
+ const managerModels = [
133
+ { id: 'codex', name: 'Codex', provider: 'shennian', isDefault: true },
134
+ { id: 'claude', name: 'Claude Code', provider: 'shennian' },
135
+ ];
136
+ async function discoverPiModels(context) {
137
+ if (!context.serverUrl || !context.authToken)
138
+ return fallbackPiModels;
139
+ try {
140
+ const response = await fetch(`${context.serverUrl.replace(/\/$/, '')}/api/models`, {
141
+ headers: {
142
+ Authorization: `Bearer ${context.authToken}`,
143
+ },
144
+ });
145
+ if (!response.ok)
146
+ return fallbackPiModels;
147
+ const data = (await response.json());
148
+ const models = (data.models ?? []).map((model) => ({
149
+ id: model.id,
150
+ name: model.name?.trim() || model.id,
151
+ provider: model.provider,
152
+ isDefault: model.id === data.default,
153
+ }));
154
+ return models.length > 0 ? models : fallbackPiModels;
155
+ }
156
+ catch {
157
+ return fallbackPiModels;
158
+ }
159
+ }
160
+ async function discoverBuiltinModels(type, context) {
161
+ switch (type) {
162
+ case 'claude':
163
+ return discoverClaudeModels();
164
+ case 'codex':
165
+ return discoverCodexModels();
166
+ case 'workbuddy':
167
+ return resolveBuiltinCommand('workbuddy') ? fallbackWorkBuddyModels() : [];
168
+ case 'gemini':
169
+ return discoverGeminiModels();
170
+ case 'cursor':
171
+ return discoverCursorModels();
172
+ case 'openclaw':
173
+ // OpenClaw support is intentionally disabled.
174
+ return [];
175
+ case 'opencode':
176
+ return discoverOpenCodeModels();
177
+ case 'pi':
178
+ return discoverPiModels(context);
179
+ case 'manager':
180
+ return managerModels;
181
+ }
182
+ }
183
+ export async function discoverModelsForAgent(agent, context) {
184
+ if (agent.type.startsWith('custom:')) {
185
+ return agent.models ?? [];
186
+ }
187
+ return discoverBuiltinModels(agent.type, context);
188
+ }