shennian 0.2.0 → 0.2.5
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/bin/shennian.d.ts +0 -1
- package/dist/bin/shennian.js +0 -1
- package/dist/src/agents/adapter.d.ts +0 -1
- package/dist/src/agents/adapter.js +0 -1
- package/dist/src/agents/claude.d.ts +1 -1
- package/dist/src/agents/claude.js +12 -6
- package/dist/src/agents/codex.d.ts +18 -1
- package/dist/src/agents/codex.js +372 -13
- package/dist/src/agents/command-spec.d.ts +28 -3
- package/dist/src/agents/command-spec.js +251 -10
- package/dist/src/agents/cursor.d.ts +0 -1
- package/dist/src/agents/cursor.js +2 -4
- package/dist/src/agents/custom.d.ts +0 -6
- package/dist/src/agents/custom.js +4 -40
- package/dist/src/agents/detect.d.ts +0 -1
- package/dist/src/agents/detect.js +0 -1
- package/dist/src/agents/gemini.d.ts +0 -1
- package/dist/src/agents/gemini.js +7 -3
- package/dist/src/agents/model-registry/cache.d.ts +0 -1
- package/dist/src/agents/model-registry/cache.js +0 -1
- package/dist/src/agents/model-registry/discovery.d.ts +0 -1
- package/dist/src/agents/model-registry/discovery.js +90 -48
- package/dist/src/agents/model-registry/parsers.d.ts +4 -1
- package/dist/src/agents/model-registry/parsers.js +168 -1
- package/dist/src/agents/model-registry/runner.d.ts +2 -7
- package/dist/src/agents/model-registry/runner.js +3 -134
- package/dist/src/agents/model-registry/service.d.ts +0 -1
- package/dist/src/agents/model-registry/service.js +12 -10
- package/dist/src/agents/model-registry/types.d.ts +0 -1
- package/dist/src/agents/model-registry/types.js +0 -1
- package/dist/src/agents/model-registry.d.ts +3 -2
- package/dist/src/agents/model-registry.js +3 -2
- package/dist/src/agents/openclaw.d.ts +0 -1
- package/dist/src/agents/openclaw.js +13 -4
- package/dist/src/agents/pi.d.ts +0 -1
- package/dist/src/agents/pi.js +0 -1
- package/dist/src/commands/agent.d.ts +0 -1
- package/dist/src/commands/agent.js +2 -33
- package/dist/src/commands/daemon.d.ts +6 -1
- package/dist/src/commands/daemon.js +153 -18
- package/dist/src/commands/pair-qr.d.ts +0 -1
- package/dist/src/commands/pair-qr.js +0 -1
- package/dist/src/commands/pair.d.ts +0 -1
- package/dist/src/commands/pair.js +0 -1
- package/dist/src/commands/upgrade.d.ts +0 -1
- package/dist/src/commands/upgrade.js +0 -1
- package/dist/src/config/index.d.ts +0 -1
- package/dist/src/config/index.js +0 -1
- package/dist/src/fs/handler.d.ts +0 -1
- package/dist/src/fs/handler.js +18 -1
- package/dist/src/fs/security.d.ts +0 -1
- package/dist/src/fs/security.js +5 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +36 -8
- package/dist/src/log-reporter.d.ts +0 -1
- package/dist/src/log-reporter.js +2 -20
- package/dist/src/native-fusion/parsers.d.ts +0 -1
- package/dist/src/native-fusion/parsers.js +407 -44
- package/dist/src/native-fusion/service.d.ts +0 -1
- package/dist/src/native-fusion/service.js +16 -10
- package/dist/src/native-fusion/state.d.ts +0 -1
- package/dist/src/native-fusion/state.js +0 -1
- package/dist/src/native-fusion/types.d.ts +0 -1
- package/dist/src/native-fusion/types.js +0 -1
- package/dist/src/region.d.ts +0 -1
- package/dist/src/region.js +0 -1
- package/dist/src/relay/client.d.ts +11 -2
- package/dist/src/relay/client.js +22 -4
- package/dist/src/session/handlers/agents.d.ts +0 -1
- package/dist/src/session/handlers/agents.js +0 -1
- package/dist/src/session/handlers/chat.d.ts +0 -1
- package/dist/src/session/handlers/chat.js +49 -8
- package/dist/src/session/handlers/control.d.ts +0 -1
- package/dist/src/session/handlers/control.js +0 -1
- package/dist/src/session/handlers/fs.d.ts +0 -1
- package/dist/src/session/handlers/fs.js +37 -3
- package/dist/src/session/manager.d.ts +1 -1
- package/dist/src/session/manager.js +23 -4
- package/dist/src/session/store.d.ts +0 -1
- package/dist/src/session/store.js +0 -1
- package/dist/src/session/types.d.ts +6 -1
- package/dist/src/session/types.js +0 -1
- package/dist/src/upgrade/engine.d.ts +0 -1
- package/dist/src/upgrade/engine.js +0 -1
- package/package.json +3 -2
- package/dist/bin/shennian.d.ts.map +0 -1
- package/dist/bin/shennian.js.map +0 -1
- package/dist/src/__experiments__/probe-debug.d.ts +0 -2
- package/dist/src/__experiments__/probe-debug.d.ts.map +0 -1
- package/dist/src/__experiments__/probe-debug.js +0 -66
- package/dist/src/__experiments__/probe-debug.js.map +0 -1
- package/dist/src/__experiments__/probe-final-benchmark.d.ts +0 -3
- package/dist/src/__experiments__/probe-final-benchmark.d.ts.map +0 -1
- package/dist/src/__experiments__/probe-final-benchmark.js +0 -234
- package/dist/src/__experiments__/probe-final-benchmark.js.map +0 -1
- package/dist/src/__experiments__/probe-models-final.d.ts +0 -19
- package/dist/src/__experiments__/probe-models-final.d.ts.map +0 -1
- package/dist/src/__experiments__/probe-models-final.js +0 -250
- package/dist/src/__experiments__/probe-models-final.js.map +0 -1
- package/dist/src/__experiments__/probe-models.d.ts +0 -7
- package/dist/src/__experiments__/probe-models.d.ts.map +0 -1
- package/dist/src/__experiments__/probe-models.js +0 -251
- package/dist/src/__experiments__/probe-models.js.map +0 -1
- package/dist/src/__tests__/agents-e2e.d.ts +0 -21
- package/dist/src/__tests__/agents-e2e.d.ts.map +0 -1
- package/dist/src/__tests__/agents-e2e.js +0 -146
- package/dist/src/__tests__/agents-e2e.js.map +0 -1
- package/dist/src/__tests__/claude-adapter.test.d.ts +0 -2
- package/dist/src/__tests__/claude-adapter.test.d.ts.map +0 -1
- package/dist/src/__tests__/claude-adapter.test.js +0 -75
- package/dist/src/__tests__/claude-adapter.test.js.map +0 -1
- package/dist/src/__tests__/codex-adapter.test.d.ts +0 -2
- package/dist/src/__tests__/codex-adapter.test.d.ts.map +0 -1
- package/dist/src/__tests__/codex-adapter.test.js +0 -224
- package/dist/src/__tests__/codex-adapter.test.js.map +0 -1
- package/dist/src/__tests__/config.test.d.ts +0 -2
- package/dist/src/__tests__/config.test.d.ts.map +0 -1
- package/dist/src/__tests__/config.test.js +0 -60
- package/dist/src/__tests__/config.test.js.map +0 -1
- package/dist/src/__tests__/cursor-adapter.test.d.ts +0 -2
- package/dist/src/__tests__/cursor-adapter.test.d.ts.map +0 -1
- package/dist/src/__tests__/cursor-adapter.test.js +0 -69
- package/dist/src/__tests__/cursor-adapter.test.js.map +0 -1
- package/dist/src/__tests__/custom-agent-flow.test.d.ts +0 -2
- package/dist/src/__tests__/custom-agent-flow.test.d.ts.map +0 -1
- package/dist/src/__tests__/custom-agent-flow.test.js +0 -244
- package/dist/src/__tests__/custom-agent-flow.test.js.map +0 -1
- package/dist/src/__tests__/daemon-autostart.test.d.ts +0 -2
- package/dist/src/__tests__/daemon-autostart.test.d.ts.map +0 -1
- package/dist/src/__tests__/daemon-autostart.test.js +0 -60
- package/dist/src/__tests__/daemon-autostart.test.js.map +0 -1
- package/dist/src/__tests__/e2e-relay.d.ts +0 -19
- package/dist/src/__tests__/e2e-relay.d.ts.map +0 -1
- package/dist/src/__tests__/e2e-relay.js +0 -256
- package/dist/src/__tests__/e2e-relay.js.map +0 -1
- package/dist/src/__tests__/model-discovery.test.d.ts +0 -2
- package/dist/src/__tests__/model-discovery.test.d.ts.map +0 -1
- package/dist/src/__tests__/model-discovery.test.js +0 -47
- package/dist/src/__tests__/model-discovery.test.js.map +0 -1
- package/dist/src/__tests__/model-switching.test.d.ts +0 -2
- package/dist/src/__tests__/model-switching.test.d.ts.map +0 -1
- package/dist/src/__tests__/model-switching.test.js +0 -253
- package/dist/src/__tests__/model-switching.test.js.map +0 -1
- package/dist/src/__tests__/native-fusion-parsers.test.d.ts +0 -2
- package/dist/src/__tests__/native-fusion-parsers.test.d.ts.map +0 -1
- package/dist/src/__tests__/native-fusion-parsers.test.js +0 -216
- package/dist/src/__tests__/native-fusion-parsers.test.js.map +0 -1
- package/dist/src/__tests__/native-fusion-service.test.d.ts +0 -2
- package/dist/src/__tests__/native-fusion-service.test.d.ts.map +0 -1
- package/dist/src/__tests__/native-fusion-service.test.js +0 -157
- package/dist/src/__tests__/native-fusion-service.test.js.map +0 -1
- package/dist/src/__tests__/native-session-sync.test.d.ts +0 -2
- package/dist/src/__tests__/native-session-sync.test.d.ts.map +0 -1
- package/dist/src/__tests__/native-session-sync.test.js +0 -198
- package/dist/src/__tests__/native-session-sync.test.js.map +0 -1
- package/dist/src/__tests__/pair-qr.test.d.ts +0 -2
- package/dist/src/__tests__/pair-qr.test.d.ts.map +0 -1
- package/dist/src/__tests__/pair-qr.test.js +0 -13
- package/dist/src/__tests__/pair-qr.test.js.map +0 -1
- package/dist/src/__tests__/pi-context.test.d.ts +0 -2
- package/dist/src/__tests__/pi-context.test.d.ts.map +0 -1
- package/dist/src/__tests__/pi-context.test.js +0 -261
- package/dist/src/__tests__/pi-context.test.js.map +0 -1
- package/dist/src/__tests__/session-manager.test.d.ts +0 -2
- package/dist/src/__tests__/session-manager.test.d.ts.map +0 -1
- package/dist/src/__tests__/session-manager.test.js +0 -592
- package/dist/src/__tests__/session-manager.test.js.map +0 -1
- package/dist/src/__tests__/session-store.test.d.ts +0 -2
- package/dist/src/__tests__/session-store.test.d.ts.map +0 -1
- package/dist/src/__tests__/session-store.test.js +0 -106
- package/dist/src/__tests__/session-store.test.js.map +0 -1
- package/dist/src/agents/adapter.d.ts.map +0 -1
- package/dist/src/agents/adapter.js.map +0 -1
- package/dist/src/agents/claude.d.ts.map +0 -1
- package/dist/src/agents/claude.js.map +0 -1
- package/dist/src/agents/codex.d.ts.map +0 -1
- package/dist/src/agents/codex.js.map +0 -1
- package/dist/src/agents/command-spec.d.ts.map +0 -1
- package/dist/src/agents/command-spec.js.map +0 -1
- package/dist/src/agents/cursor.d.ts.map +0 -1
- package/dist/src/agents/cursor.js.map +0 -1
- package/dist/src/agents/custom.d.ts.map +0 -1
- package/dist/src/agents/custom.js.map +0 -1
- package/dist/src/agents/detect.d.ts.map +0 -1
- package/dist/src/agents/detect.js.map +0 -1
- package/dist/src/agents/gemini.d.ts.map +0 -1
- package/dist/src/agents/gemini.js.map +0 -1
- package/dist/src/agents/model-registry/cache.d.ts.map +0 -1
- package/dist/src/agents/model-registry/cache.js.map +0 -1
- package/dist/src/agents/model-registry/discovery.d.ts.map +0 -1
- package/dist/src/agents/model-registry/discovery.js.map +0 -1
- package/dist/src/agents/model-registry/parsers.d.ts.map +0 -1
- package/dist/src/agents/model-registry/parsers.js.map +0 -1
- package/dist/src/agents/model-registry/runner.d.ts.map +0 -1
- package/dist/src/agents/model-registry/runner.js.map +0 -1
- package/dist/src/agents/model-registry/service.d.ts.map +0 -1
- package/dist/src/agents/model-registry/service.js.map +0 -1
- package/dist/src/agents/model-registry/types.d.ts.map +0 -1
- package/dist/src/agents/model-registry/types.js.map +0 -1
- package/dist/src/agents/model-registry.d.ts.map +0 -1
- package/dist/src/agents/model-registry.js.map +0 -1
- package/dist/src/agents/openclaw.d.ts.map +0 -1
- package/dist/src/agents/openclaw.js.map +0 -1
- package/dist/src/agents/pi.d.ts.map +0 -1
- package/dist/src/agents/pi.js.map +0 -1
- package/dist/src/commands/agent.d.ts.map +0 -1
- package/dist/src/commands/agent.js.map +0 -1
- package/dist/src/commands/daemon.d.ts.map +0 -1
- package/dist/src/commands/daemon.js.map +0 -1
- package/dist/src/commands/pair-qr.d.ts.map +0 -1
- package/dist/src/commands/pair-qr.js.map +0 -1
- package/dist/src/commands/pair.d.ts.map +0 -1
- package/dist/src/commands/pair.js.map +0 -1
- package/dist/src/commands/upgrade.d.ts.map +0 -1
- package/dist/src/commands/upgrade.js.map +0 -1
- package/dist/src/config/index.d.ts.map +0 -1
- package/dist/src/config/index.js.map +0 -1
- package/dist/src/fs/handler.d.ts.map +0 -1
- package/dist/src/fs/handler.js.map +0 -1
- package/dist/src/fs/multimodal.d.ts +0 -5
- package/dist/src/fs/multimodal.d.ts.map +0 -1
- package/dist/src/fs/multimodal.js +0 -39
- package/dist/src/fs/multimodal.js.map +0 -1
- package/dist/src/fs/security.d.ts.map +0 -1
- package/dist/src/fs/security.js.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/log-reporter.d.ts.map +0 -1
- package/dist/src/log-reporter.js.map +0 -1
- package/dist/src/native-fusion/parsers.d.ts.map +0 -1
- package/dist/src/native-fusion/parsers.js.map +0 -1
- package/dist/src/native-fusion/service.d.ts.map +0 -1
- package/dist/src/native-fusion/service.js.map +0 -1
- package/dist/src/native-fusion/state.d.ts.map +0 -1
- package/dist/src/native-fusion/state.js.map +0 -1
- package/dist/src/native-fusion/types.d.ts.map +0 -1
- package/dist/src/native-fusion/types.js.map +0 -1
- package/dist/src/native-sync/discover.d.ts +0 -6
- package/dist/src/native-sync/discover.d.ts.map +0 -1
- package/dist/src/native-sync/discover.js +0 -69
- package/dist/src/native-sync/discover.js.map +0 -1
- package/dist/src/native-sync/parsers.d.ts +0 -3
- package/dist/src/native-sync/parsers.d.ts.map +0 -1
- package/dist/src/native-sync/parsers.js +0 -373
- package/dist/src/native-sync/parsers.js.map +0 -1
- package/dist/src/native-sync/service.d.ts +0 -16
- package/dist/src/native-sync/service.d.ts.map +0 -1
- package/dist/src/native-sync/service.js +0 -95
- package/dist/src/native-sync/service.js.map +0 -1
- package/dist/src/native-sync/state.d.ts +0 -6
- package/dist/src/native-sync/state.d.ts.map +0 -1
- package/dist/src/native-sync/state.js +0 -34
- package/dist/src/native-sync/state.js.map +0 -1
- package/dist/src/native-sync/types.d.ts +0 -23
- package/dist/src/native-sync/types.d.ts.map +0 -1
- package/dist/src/native-sync/types.js +0 -4
- package/dist/src/native-sync/types.js.map +0 -1
- package/dist/src/region.d.ts.map +0 -1
- package/dist/src/region.js.map +0 -1
- package/dist/src/relay/client.d.ts.map +0 -1
- package/dist/src/relay/client.js.map +0 -1
- package/dist/src/session/handlers/agents.d.ts.map +0 -1
- package/dist/src/session/handlers/agents.js.map +0 -1
- package/dist/src/session/handlers/chat.d.ts.map +0 -1
- package/dist/src/session/handlers/chat.js.map +0 -1
- package/dist/src/session/handlers/control.d.ts.map +0 -1
- package/dist/src/session/handlers/control.js.map +0 -1
- package/dist/src/session/handlers/fs.d.ts.map +0 -1
- package/dist/src/session/handlers/fs.js.map +0 -1
- package/dist/src/session/handlers/queue.d.ts +0 -4
- package/dist/src/session/handlers/queue.d.ts.map +0 -1
- package/dist/src/session/handlers/queue.js +0 -66
- package/dist/src/session/handlers/queue.js.map +0 -1
- package/dist/src/session/manager.d.ts.map +0 -1
- package/dist/src/session/manager.js.map +0 -1
- package/dist/src/session/store.d.ts.map +0 -1
- package/dist/src/session/store.js.map +0 -1
- package/dist/src/session/types.d.ts.map +0 -1
- package/dist/src/session/types.js.map +0 -1
- package/dist/src/upgrade/engine.d.ts.map +0 -1
- package/dist/src/upgrade/engine.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -28,7 +28,7 @@ export function isEphemeralCliPath(candidate) {
|
|
|
28
28
|
normalized.startsWith(tmp.endsWith('/') ? tmp : `${tmp}/`));
|
|
29
29
|
}
|
|
30
30
|
export function resolveServiceLaunchSpec(input) {
|
|
31
|
-
if (!isEphemeralCliPath(input.scriptPath)) {
|
|
31
|
+
if (fs.existsSync(input.scriptPath) && !isEphemeralCliPath(input.scriptPath)) {
|
|
32
32
|
return {
|
|
33
33
|
command: input.nodeExec,
|
|
34
34
|
args: [input.scriptPath, 'start'],
|
|
@@ -79,8 +79,10 @@ function isRunning(pid) {
|
|
|
79
79
|
const LAUNCHD_LABEL = 'com.shennian.agent';
|
|
80
80
|
const LAUNCHD_PLIST = path.join(os.homedir(), 'Library/LaunchAgents', `${LAUNCHD_LABEL}.plist`);
|
|
81
81
|
const WINDOWS_STARTUP_DIR = path.join(os.homedir(), 'AppData', 'Roaming', 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup');
|
|
82
|
-
const WINDOWS_STARTUP_VBS = path.join(WINDOWS_STARTUP_DIR, 'ShennianAgent.vbs');
|
|
83
82
|
const WINDOWS_STARTUP_CMD = resolveShennianPath('autostart.cmd');
|
|
83
|
+
const WINDOWS_LAUNCHER_VBS = resolveShennianPath('autostart.vbs');
|
|
84
|
+
const WINDOWS_TASK_XML = resolveShennianPath('autostart.xml');
|
|
85
|
+
const WINDOWS_STARTUP_VBS = path.join(WINDOWS_STARTUP_DIR, 'ShennianAgent.vbs');
|
|
84
86
|
function findCommandPath(binary) {
|
|
85
87
|
const command = getPlatform() === 'win32' ? `where ${binary}` : `command -v ${binary}`;
|
|
86
88
|
try {
|
|
@@ -130,12 +132,20 @@ function quoteCmdArg(text) {
|
|
|
130
132
|
function escapeVbsString(text) {
|
|
131
133
|
return text.replace(/"/g, '""');
|
|
132
134
|
}
|
|
135
|
+
function escapeXmlValue(text) {
|
|
136
|
+
return escapeXml(text);
|
|
137
|
+
}
|
|
138
|
+
function isWindowsCmdScript(filePath) {
|
|
139
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
140
|
+
return ext === '.cmd' || ext === '.bat';
|
|
141
|
+
}
|
|
133
142
|
export function buildWindowsLauncherCommand(spec, logFile) {
|
|
134
143
|
const commandLine = [spec.command, ...spec.args].map(quoteCmdArg).join(' ');
|
|
144
|
+
const invocation = isWindowsCmdScript(spec.command) ? `call ${commandLine}` : commandLine;
|
|
135
145
|
return [
|
|
136
146
|
'@echo off',
|
|
137
147
|
'setlocal',
|
|
138
|
-
`${
|
|
148
|
+
`${invocation} >> ${quoteCmdArg(logFile)} 2>&1`,
|
|
139
149
|
'',
|
|
140
150
|
].join('\r\n');
|
|
141
151
|
}
|
|
@@ -146,6 +156,66 @@ export function buildWindowsStartupVbs(cmdPath) {
|
|
|
146
156
|
'',
|
|
147
157
|
].join('\r\n');
|
|
148
158
|
}
|
|
159
|
+
export function buildWindowsScheduledTaskXml(input) {
|
|
160
|
+
const joinedArgs = input.arguments.join(' ');
|
|
161
|
+
return `<?xml version="1.0" encoding="UTF-16"?>
|
|
162
|
+
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
163
|
+
<RegistrationInfo>
|
|
164
|
+
<Description>Shennian Agent Daemon</Description>
|
|
165
|
+
</RegistrationInfo>
|
|
166
|
+
<Triggers>
|
|
167
|
+
<LogonTrigger>
|
|
168
|
+
<Enabled>true</Enabled>
|
|
169
|
+
<UserId>${escapeXmlValue(input.userId)}</UserId>
|
|
170
|
+
</LogonTrigger>
|
|
171
|
+
<EventTrigger>
|
|
172
|
+
<Enabled>true</Enabled>
|
|
173
|
+
<Subscription><![CDATA[
|
|
174
|
+
<QueryList>
|
|
175
|
+
<Query Id="0" Path="System">
|
|
176
|
+
<Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Power-Troubleshooter'] and EventID=1]]</Select>
|
|
177
|
+
</Query>
|
|
178
|
+
</QueryList>]]></Subscription>
|
|
179
|
+
</EventTrigger>
|
|
180
|
+
</Triggers>
|
|
181
|
+
<Principals>
|
|
182
|
+
<Principal id="Author">
|
|
183
|
+
<UserId>${escapeXmlValue(input.userId)}</UserId>
|
|
184
|
+
<LogonType>InteractiveToken</LogonType>
|
|
185
|
+
<RunLevel>LeastPrivilege</RunLevel>
|
|
186
|
+
</Principal>
|
|
187
|
+
</Principals>
|
|
188
|
+
<Settings>
|
|
189
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
190
|
+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
191
|
+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
192
|
+
<AllowHardTerminate>true</AllowHardTerminate>
|
|
193
|
+
<StartWhenAvailable>true</StartWhenAvailable>
|
|
194
|
+
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
|
195
|
+
<IdleSettings>
|
|
196
|
+
<StopOnIdleEnd>false</StopOnIdleEnd>
|
|
197
|
+
<RestartOnIdle>false</RestartOnIdle>
|
|
198
|
+
</IdleSettings>
|
|
199
|
+
<AllowStartOnDemand>true</AllowStartOnDemand>
|
|
200
|
+
<Enabled>true</Enabled>
|
|
201
|
+
<Hidden>true</Hidden>
|
|
202
|
+
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
203
|
+
<WakeToRun>false</WakeToRun>
|
|
204
|
+
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
205
|
+
<Priority>7</Priority>
|
|
206
|
+
<RestartOnFailure>
|
|
207
|
+
<Interval>PT1M</Interval>
|
|
208
|
+
<Count>3</Count>
|
|
209
|
+
</RestartOnFailure>
|
|
210
|
+
</Settings>
|
|
211
|
+
<Actions Context="Author">
|
|
212
|
+
<Exec>
|
|
213
|
+
<Command>${escapeXmlValue(input.command)}</Command>
|
|
214
|
+
<Arguments>${escapeXmlValue(joinedArgs)}</Arguments>
|
|
215
|
+
</Exec>
|
|
216
|
+
</Actions>
|
|
217
|
+
</Task>`;
|
|
218
|
+
}
|
|
149
219
|
function removeLegacyWindowsTask() {
|
|
150
220
|
try {
|
|
151
221
|
execSync(`schtasks /delete /tn "${WINDOWS_TASK_NAME}" /f`, { stdio: 'pipe' });
|
|
@@ -154,10 +224,64 @@ function removeLegacyWindowsTask() {
|
|
|
154
224
|
// Ignore missing legacy Task Scheduler entries during migration.
|
|
155
225
|
}
|
|
156
226
|
}
|
|
157
|
-
function
|
|
227
|
+
function removeLegacyWindowsStartupFiles() {
|
|
228
|
+
try {
|
|
229
|
+
fs.unlinkSync(WINDOWS_STARTUP_VBS);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// Legacy Startup entry may already be absent.
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function getWindowsTaskUserId() {
|
|
236
|
+
const domain = process.env.USERDOMAIN?.trim();
|
|
237
|
+
const computer = process.env.COMPUTERNAME?.trim();
|
|
238
|
+
const username = process.env.USERNAME?.trim() || os.userInfo().username;
|
|
239
|
+
if (domain && domain.toUpperCase() !== 'WORKGROUP')
|
|
240
|
+
return `${domain}\\${username}`;
|
|
241
|
+
if (computer)
|
|
242
|
+
return `${computer}\\${username}`;
|
|
243
|
+
return username;
|
|
244
|
+
}
|
|
245
|
+
function buildDetachedLaunchSpec(spec) {
|
|
246
|
+
if (getPlatform() === 'win32' && isWindowsCmdScript(spec.command)) {
|
|
247
|
+
const commandLine = [spec.command, ...spec.args].map(quoteCmdArg).join(' ');
|
|
248
|
+
return {
|
|
249
|
+
command: process.env.ComSpec || 'cmd.exe',
|
|
250
|
+
args: ['/d', '/s', '/c', `"${commandLine}"`],
|
|
251
|
+
windowsVerbatimArguments: true,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
command: spec.command,
|
|
256
|
+
args: spec.args,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function installWindowsScheduledTask() {
|
|
260
|
+
const launch = resolveCurrentServiceLaunchSpec();
|
|
261
|
+
fs.writeFileSync(WINDOWS_STARTUP_CMD, buildWindowsLauncherCommand(launch, LOG_FILE));
|
|
262
|
+
fs.writeFileSync(WINDOWS_LAUNCHER_VBS, buildWindowsStartupVbs(WINDOWS_STARTUP_CMD));
|
|
263
|
+
removeLegacyWindowsStartupFiles();
|
|
264
|
+
removeLegacyWindowsTask();
|
|
265
|
+
const taskXml = buildWindowsScheduledTaskXml({
|
|
266
|
+
userId: getWindowsTaskUserId(),
|
|
267
|
+
command: path.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'wscript.exe'),
|
|
268
|
+
arguments: [quoteCmdArg(WINDOWS_LAUNCHER_VBS)],
|
|
269
|
+
});
|
|
270
|
+
fs.writeFileSync(WINDOWS_TASK_XML, taskXml, 'utf8');
|
|
271
|
+
try {
|
|
272
|
+
execSync(`schtasks /create /tn "${WINDOWS_TASK_NAME}" /xml "${WINDOWS_TASK_XML}" /f`, { stdio: 'pipe' });
|
|
273
|
+
execSync(`schtasks /run /tn "${WINDOWS_TASK_NAME}"`, { stdio: 'pipe' });
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
export function captureEnvForService() {
|
|
158
281
|
const keep = [
|
|
159
282
|
'PATH', 'HOME', 'USER', 'LOGNAME', 'SHELL', 'TMPDIR', 'LANG',
|
|
160
283
|
'LC_ALL', 'LC_CTYPE', 'SSH_AUTH_SOCK', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME',
|
|
284
|
+
'TEMP', 'TMP',
|
|
161
285
|
'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN', 'ANTHROPIC_BASE_URL',
|
|
162
286
|
'OPENAI_API_KEY', 'OPENAI_BASE_URL',
|
|
163
287
|
'GEMINI_API_KEY', 'GOOGLE_API_KEY',
|
|
@@ -170,7 +294,15 @@ function captureEnvForService() {
|
|
|
170
294
|
env.HOME ??= os.homedir();
|
|
171
295
|
env.PATH ??= '/usr/local/bin:/usr/bin:/bin';
|
|
172
296
|
env.USER ??= os.userInfo().username;
|
|
173
|
-
|
|
297
|
+
if (getPlatform() === 'win32') {
|
|
298
|
+
const tempDir = process.env.TEMP || process.env.TMP || os.tmpdir();
|
|
299
|
+
env.TMPDIR ??= tempDir;
|
|
300
|
+
env.TEMP ??= tempDir;
|
|
301
|
+
env.TMP ??= tempDir;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
env.TMPDIR ??= '/tmp';
|
|
305
|
+
}
|
|
174
306
|
return env;
|
|
175
307
|
}
|
|
176
308
|
function buildPlist() {
|
|
@@ -255,10 +387,12 @@ export function startDaemonProcess() {
|
|
|
255
387
|
return;
|
|
256
388
|
}
|
|
257
389
|
const logFd = fs.openSync(LOG_FILE, 'a');
|
|
258
|
-
const
|
|
390
|
+
const launch = buildDetachedLaunchSpec(resolveCurrentServiceLaunchSpec());
|
|
391
|
+
const child = spawn(launch.command, launch.args, {
|
|
259
392
|
detached: true,
|
|
260
393
|
stdio: ['ignore', logFd, logFd],
|
|
261
394
|
env: process.env,
|
|
395
|
+
...(launch.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
|
|
262
396
|
});
|
|
263
397
|
child.unref();
|
|
264
398
|
fs.closeSync(logFd);
|
|
@@ -320,12 +454,7 @@ export function installService() {
|
|
|
320
454
|
return false; // systemd enable doesn't start immediately; caller should startDaemonProcess
|
|
321
455
|
}
|
|
322
456
|
case 'win32': {
|
|
323
|
-
|
|
324
|
-
fs.mkdirSync(WINDOWS_STARTUP_DIR, { recursive: true });
|
|
325
|
-
fs.writeFileSync(WINDOWS_STARTUP_CMD, buildWindowsLauncherCommand(launch, LOG_FILE));
|
|
326
|
-
fs.writeFileSync(WINDOWS_STARTUP_VBS, buildWindowsStartupVbs(WINDOWS_STARTUP_CMD));
|
|
327
|
-
removeLegacyWindowsTask();
|
|
328
|
-
return false; // Startup folder launches on logon; caller should startDaemonProcess now
|
|
457
|
+
return installWindowsScheduledTask();
|
|
329
458
|
}
|
|
330
459
|
}
|
|
331
460
|
}
|
|
@@ -435,18 +564,25 @@ function daemonUninstall() {
|
|
|
435
564
|
case 'win32': {
|
|
436
565
|
removeLegacyWindowsTask();
|
|
437
566
|
try {
|
|
438
|
-
fs.unlinkSync(
|
|
567
|
+
fs.unlinkSync(WINDOWS_STARTUP_CMD);
|
|
439
568
|
}
|
|
440
569
|
catch {
|
|
441
|
-
//
|
|
570
|
+
// Launcher script may already be removed.
|
|
442
571
|
}
|
|
443
572
|
try {
|
|
444
|
-
fs.unlinkSync(
|
|
573
|
+
fs.unlinkSync(WINDOWS_LAUNCHER_VBS);
|
|
445
574
|
}
|
|
446
575
|
catch {
|
|
447
|
-
// Launcher
|
|
576
|
+
// Launcher vbs may already be removed.
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
fs.unlinkSync(WINDOWS_TASK_XML);
|
|
580
|
+
}
|
|
581
|
+
catch {
|
|
582
|
+
// Task xml may already be removed.
|
|
448
583
|
}
|
|
449
|
-
|
|
584
|
+
removeLegacyWindowsStartupFiles();
|
|
585
|
+
console.log(chalk.green('✓ Auto-start uninstalled (Task Scheduler)'));
|
|
450
586
|
break;
|
|
451
587
|
}
|
|
452
588
|
}
|
|
@@ -474,4 +610,3 @@ export function registerDaemonCommand(program) {
|
|
|
474
610
|
.description('Uninstall auto-start service')
|
|
475
611
|
.action(daemonUninstall);
|
|
476
612
|
}
|
|
477
|
-
//# sourceMappingURL=daemon.js.map
|
|
@@ -6,4 +6,3 @@ export declare function runPairFlow(opts: {
|
|
|
6
6
|
}): Promise<void>;
|
|
7
7
|
export declare function runSmartStart(serverUrl: string | undefined, machineName: string): Promise<void>;
|
|
8
8
|
export declare function registerPairCommand(program: Command): void;
|
|
9
|
-
//# sourceMappingURL=pair.d.ts.map
|
|
@@ -3,4 +3,3 @@ import type { CliRelayClient } from '../relay/client.js';
|
|
|
3
3
|
export declare function registerUpgradeCommand(program: Command): void;
|
|
4
4
|
export declare function handleUpgradeStart(client: CliRelayClient, reqId: string, targetVersion?: string): Promise<void>;
|
|
5
5
|
export declare function handleUpgradeStatus(client: CliRelayClient, reqId: string): Promise<void>;
|
|
6
|
-
//# sourceMappingURL=upgrade.d.ts.map
|
package/dist/src/config/index.js
CHANGED
package/dist/src/fs/handler.d.ts
CHANGED
package/dist/src/fs/handler.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { normalizePath, isPathSafe } from './security.js';
|
|
5
|
+
const FILE_SYSTEM_ROOTS_PATH = '__roots__';
|
|
4
6
|
const MAX_READ_SIZE = 100 * 1024;
|
|
5
7
|
const MAX_TRANSFER_SIZE = 20 * 1024 * 1024;
|
|
6
8
|
const CHUNK_SIZE = 64 * 1024;
|
|
@@ -8,7 +10,23 @@ const RATE_LIMIT_BYTES_PER_SEC = 5 * 1024 * 1024;
|
|
|
8
10
|
function sleep(ms) {
|
|
9
11
|
return new Promise((r) => setTimeout(r, ms));
|
|
10
12
|
}
|
|
13
|
+
function listFileSystemRoots() {
|
|
14
|
+
if (os.platform() === 'win32') {
|
|
15
|
+
const entries = [];
|
|
16
|
+
for (let code = 65; code <= 90; code += 1) {
|
|
17
|
+
const drive = `${String.fromCharCode(code)}:\\`;
|
|
18
|
+
if (!fs.existsSync(drive))
|
|
19
|
+
continue;
|
|
20
|
+
entries.push({ name: drive, path: drive, isDir: true });
|
|
21
|
+
}
|
|
22
|
+
return { entries };
|
|
23
|
+
}
|
|
24
|
+
return { entries: [{ name: '/', path: '/', isDir: true }] };
|
|
25
|
+
}
|
|
11
26
|
export function handleFsLs(reqPath) {
|
|
27
|
+
if (reqPath === FILE_SYSTEM_ROOTS_PATH) {
|
|
28
|
+
return listFileSystemRoots();
|
|
29
|
+
}
|
|
12
30
|
const normalized = normalizePath(reqPath);
|
|
13
31
|
if (!isPathSafe(normalized)) {
|
|
14
32
|
return { error: `Access denied: ${reqPath}` };
|
|
@@ -110,4 +128,3 @@ export function handleFsUploadChunk(targetPath, chunk) {
|
|
|
110
128
|
const flag = chunk.seq === 0 ? 'w' : 'a';
|
|
111
129
|
fs.writeFileSync(targetPath, buf, { flag });
|
|
112
130
|
}
|
|
113
|
-
//# sourceMappingURL=handler.js.map
|
package/dist/src/fs/security.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import os from 'node:os';
|
|
3
|
+
const FILE_SYSTEM_ROOTS_PATH = '__roots__';
|
|
3
4
|
const ALLOWED_ROOTS = [os.homedir()];
|
|
4
5
|
const BLOCKED_PATTERNS = [
|
|
5
6
|
/\.\./, // directory traversal
|
|
@@ -10,12 +11,16 @@ const BLOCKED_PATTERNS = [
|
|
|
10
11
|
/\/\.env\./,
|
|
11
12
|
];
|
|
12
13
|
export function normalizePath(inputPath) {
|
|
14
|
+
if (inputPath === FILE_SYSTEM_ROOTS_PATH)
|
|
15
|
+
return inputPath;
|
|
13
16
|
const expanded = inputPath.startsWith('~')
|
|
14
17
|
? path.join(os.homedir(), inputPath.slice(1))
|
|
15
18
|
: inputPath;
|
|
16
19
|
return path.resolve(expanded);
|
|
17
20
|
}
|
|
18
21
|
export function isPathSafe(normalizedPath) {
|
|
22
|
+
if (normalizedPath === FILE_SYSTEM_ROOTS_PATH)
|
|
23
|
+
return true;
|
|
19
24
|
const withinAllowed = ALLOWED_ROOTS.some((root) => normalizedPath === root || normalizedPath.startsWith(root + path.sep));
|
|
20
25
|
if (!withinAllowed)
|
|
21
26
|
return false;
|
|
@@ -25,4 +30,3 @@ export function isPathSafe(normalizedPath) {
|
|
|
25
30
|
}
|
|
26
31
|
return true;
|
|
27
32
|
}
|
|
28
|
-
//# sourceMappingURL=security.js.map
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -23,6 +23,19 @@ const PID_FILE = resolveShennianPath('daemon.pid');
|
|
|
23
23
|
function httpToWs(url) {
|
|
24
24
|
return url.replace(/^https:\/\//, 'wss://').replace(/^http:\/\//, 'ws://');
|
|
25
25
|
}
|
|
26
|
+
function formatDisconnectInfo(info) {
|
|
27
|
+
const parts = [
|
|
28
|
+
`trigger=${info.trigger ?? 'unknown'}`,
|
|
29
|
+
`phase=${info.phase}`,
|
|
30
|
+
`code=${info.code ?? 'unknown'}`,
|
|
31
|
+
`attempt=${info.reconnectAttempt}`,
|
|
32
|
+
];
|
|
33
|
+
if (info.reason)
|
|
34
|
+
parts.push(`reason=${info.reason}`);
|
|
35
|
+
if (info.error)
|
|
36
|
+
parts.push(`error=${info.error}`);
|
|
37
|
+
return parts.join(' ');
|
|
38
|
+
}
|
|
26
39
|
const program = new Command();
|
|
27
40
|
program
|
|
28
41
|
.name('shennian')
|
|
@@ -59,10 +72,13 @@ program
|
|
|
59
72
|
const oldPid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
60
73
|
if (oldPid && oldPid !== process.pid) {
|
|
61
74
|
try {
|
|
62
|
-
process.kill(oldPid,
|
|
75
|
+
process.kill(oldPid, 0);
|
|
76
|
+
console.log(`[${new Date().toISOString()}] daemon already running (PID ${oldPid}), skipping duplicate start`);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Stale pid; continue booting and overwrite it below.
|
|
63
81
|
}
|
|
64
|
-
catch { /* noop */ }
|
|
65
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
catch { /* noop */ }
|
|
@@ -143,9 +159,20 @@ program
|
|
|
143
159
|
void scheduleAutoUpgrade(client, config.autoUpgrade ?? 'patch');
|
|
144
160
|
nativeFusion?.handleConnected();
|
|
145
161
|
},
|
|
146
|
-
onDisconnected: () => {
|
|
147
|
-
console.log(`[${new Date().toISOString()}] ⚠ Disconnected, reconnecting
|
|
148
|
-
reportLog({
|
|
162
|
+
onDisconnected: (info) => {
|
|
163
|
+
console.log(`[${new Date().toISOString()}] ⚠ Disconnected, reconnecting... ${formatDisconnectInfo(info)}`);
|
|
164
|
+
reportLog({
|
|
165
|
+
level: 'warn',
|
|
166
|
+
wsEvent: 'daemon.disconnected',
|
|
167
|
+
metadata: {
|
|
168
|
+
code: info.code,
|
|
169
|
+
reason: info.reason,
|
|
170
|
+
error: info.error,
|
|
171
|
+
phase: info.phase,
|
|
172
|
+
trigger: info.trigger,
|
|
173
|
+
reconnectAttempt: info.reconnectAttempt,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
149
176
|
},
|
|
150
177
|
onReq: (req) => {
|
|
151
178
|
console.log(`[${new Date().toISOString()}] [req] ${req.method}`);
|
|
@@ -153,7 +180,9 @@ program
|
|
|
153
180
|
void sessionManager.handleReq(req);
|
|
154
181
|
},
|
|
155
182
|
});
|
|
156
|
-
nativeFusion =
|
|
183
|
+
nativeFusion = process.env.SHENNIAN_NATIVE_FUSION_DISABLED === '1'
|
|
184
|
+
? null
|
|
185
|
+
: new NativeSessionFusionService(client);
|
|
157
186
|
const sessionManager = new SessionManager(client, nativeFusion);
|
|
158
187
|
fs.mkdirSync(SHENNIAN_DIR, { recursive: true });
|
|
159
188
|
fs.writeFileSync(PID_FILE, String(process.pid));
|
|
@@ -246,4 +275,3 @@ async function scheduleAutoUpgrade(client, policy) {
|
|
|
246
275
|
// Use a dummy reqId since this is self-triggered
|
|
247
276
|
await handleUpgradeStart(client, 'auto-upgrade', latest);
|
|
248
277
|
}
|
|
249
|
-
//# sourceMappingURL=index.js.map
|
package/dist/src/log-reporter.js
CHANGED
|
@@ -11,24 +11,6 @@ export function generateTraceId() {
|
|
|
11
11
|
export function reportLog(entry) {
|
|
12
12
|
if (!_serverUrl || !_machineId)
|
|
13
13
|
return;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
machineId: _machineId,
|
|
17
|
-
source: 'cli',
|
|
18
|
-
type: entry.type ?? 'internal',
|
|
19
|
-
level: entry.level,
|
|
20
|
-
wsEvent: entry.wsEvent,
|
|
21
|
-
wsDirection: entry.wsDirection,
|
|
22
|
-
sessionId: entry.sessionId,
|
|
23
|
-
errorMessage: entry.errorMessage,
|
|
24
|
-
errorStack: entry.errorStack,
|
|
25
|
-
durationMs: entry.durationMs,
|
|
26
|
-
metadata: entry.metadata,
|
|
27
|
-
};
|
|
28
|
-
fetch(`${_serverUrl}/log`, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: { 'Content-Type': 'application/json' },
|
|
31
|
-
body: JSON.stringify(body),
|
|
32
|
-
}).catch(() => { });
|
|
14
|
+
// Remote DB log reporting is intentionally disabled; keep the API for callers.
|
|
15
|
+
void entry;
|
|
33
16
|
}
|
|
34
|
-
//# sourceMappingURL=log-reporter.js.map
|