@supen-ai/cli 0.1.11 → 0.1.13
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/README.md +7 -1
- package/daemon/dist/core/coding-cli-status-cache.d.ts +19 -0
- package/daemon/dist/core/coding-cli-status-cache.d.ts.map +1 -0
- package/daemon/dist/core/coding-cli-status-cache.js +122 -0
- package/daemon/dist/core/coding-cli-status-cache.js.map +1 -0
- package/daemon/dist/core/gateway-config.d.ts.map +1 -1
- package/daemon/dist/core/gateway-config.js +3 -0
- package/daemon/dist/core/gateway-config.js.map +1 -1
- package/daemon/dist/http/routes/system.d.ts.map +1 -1
- package/daemon/dist/http/routes/system.js +225 -17
- package/daemon/dist/http/routes/system.js.map +1 -1
- package/daemon/package.json +83 -0
- package/dist/computer.js +31 -11
- package/dist/computer.js.map +1 -1
- package/dist/doctor.js +294 -14
- package/dist/doctor.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ curl -fsSL https://app.supen.ai/install.sh | /bin/sh -s -- --claim '<one-time-cl
|
|
|
73
73
|
`https://hub.supen.ai`. The legacy `--gateway-url` flag remains supported for
|
|
74
74
|
existing scripts. The hosted installer downloads a private Node 22.22.0
|
|
75
75
|
runtime into `~/.supen` when the system Node is too old, then uses
|
|
76
|
-
`@supen-ai/cli@0.1.
|
|
76
|
+
`@supen-ai/cli@0.1.13` with the `host` runtime to configure Codex app-server
|
|
77
77
|
transport and start the daemon as a user service with the existing Codex login
|
|
78
78
|
on that machine.
|
|
79
79
|
|
|
@@ -84,10 +84,16 @@ package and restart the user service without repeating enrollment.
|
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
86
|
supen doctor
|
|
87
|
+
supen doctor --fix
|
|
87
88
|
supen doctor list
|
|
88
89
|
supen doctor run
|
|
90
|
+
supen doctor run --fix
|
|
89
91
|
```
|
|
90
92
|
|
|
93
|
+
`supen doctor` reports setup issues without changing the machine. `supen doctor --fix`
|
|
94
|
+
also applies supported repairs, including canonicalizing the Hub URL, creating
|
|
95
|
+
local Supen directories, and reinstalling/restarting the host daemon service.
|
|
96
|
+
|
|
91
97
|
### Models
|
|
92
98
|
|
|
93
99
|
```bash
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type CodingCliStatusCacheMeta = {
|
|
2
|
+
cached_at: string;
|
|
3
|
+
stale: boolean;
|
|
4
|
+
refreshing: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type CodingCliStatusPayload = Record<string, unknown>;
|
|
7
|
+
type CodingCliStatusBuilder = () => CodingCliStatusPayload;
|
|
8
|
+
export declare function refreshCodingCliStatusCache(reason?: string): Promise<void>;
|
|
9
|
+
export declare function startCodingCliStatusCache(options: {
|
|
10
|
+
build: CodingCliStatusBuilder;
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
refreshOnStart?: boolean;
|
|
13
|
+
}): void;
|
|
14
|
+
export declare function stopCodingCliStatusCache(): void;
|
|
15
|
+
export declare function getCodingCliStatusResponse(options?: {
|
|
16
|
+
force?: boolean;
|
|
17
|
+
}): CodingCliStatusPayload;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=coding-cli-status-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding-cli-status-cache.d.ts","sourceRoot":"","sources":["../../src/core/coding-cli-status-cache.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAO7D,KAAK,sBAAsB,GAAG,MAAM,sBAAsB,CAAC;AAwE3D,wBAAgB,2BAA2B,CAAC,MAAM,SAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5E;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAeP;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAO/C;AAED,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,sBAAsB,CAmBzB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { SUPEN_HOME } from './config.js';
|
|
4
|
+
import { logger } from './logger.js';
|
|
5
|
+
const DEFAULT_REFRESH_INTERVAL_MS = 5 * 60 * 1000;
|
|
6
|
+
let builder = null;
|
|
7
|
+
let refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS;
|
|
8
|
+
let memory = null;
|
|
9
|
+
let refreshTimer = null;
|
|
10
|
+
let refreshInFlight = null;
|
|
11
|
+
let started = false;
|
|
12
|
+
function getDiskCachePath() {
|
|
13
|
+
return path.join(SUPEN_HOME, 'cache', 'coding-cli-status.json');
|
|
14
|
+
}
|
|
15
|
+
function loadFromDisk() {
|
|
16
|
+
const diskCachePath = getDiskCachePath();
|
|
17
|
+
try {
|
|
18
|
+
const raw = fs.readFileSync(diskCachePath, 'utf8');
|
|
19
|
+
const parsed = JSON.parse(raw);
|
|
20
|
+
if (parsed
|
|
21
|
+
&& typeof parsed.fetchedAt === 'number'
|
|
22
|
+
&& parsed.payload
|
|
23
|
+
&& typeof parsed.payload === 'object') {
|
|
24
|
+
return {
|
|
25
|
+
fetchedAt: parsed.fetchedAt,
|
|
26
|
+
payload: parsed.payload,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Missing or invalid cache file is normal on first run.
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function saveToDisk(record) {
|
|
36
|
+
const diskCachePath = getDiskCachePath();
|
|
37
|
+
try {
|
|
38
|
+
fs.mkdirSync(path.dirname(diskCachePath), { recursive: true });
|
|
39
|
+
fs.writeFileSync(diskCachePath, JSON.stringify(record));
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
logger.warn({ err: err instanceof Error ? err.message : String(err) }, 'Failed to persist coding CLI status cache');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function attachMeta(payload, meta) {
|
|
46
|
+
return { ...payload, cache: meta };
|
|
47
|
+
}
|
|
48
|
+
function buildMeta(record, refreshing) {
|
|
49
|
+
return {
|
|
50
|
+
cached_at: new Date(record.fetchedAt).toISOString(),
|
|
51
|
+
stale: Date.now() - record.fetchedAt > refreshIntervalMs,
|
|
52
|
+
refreshing,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function storeFreshPayload(payload) {
|
|
56
|
+
const record = { fetchedAt: Date.now(), payload };
|
|
57
|
+
memory = record;
|
|
58
|
+
saveToDisk(record);
|
|
59
|
+
return record;
|
|
60
|
+
}
|
|
61
|
+
export function refreshCodingCliStatusCache(reason = 'manual') {
|
|
62
|
+
if (!builder)
|
|
63
|
+
return Promise.resolve();
|
|
64
|
+
if (refreshInFlight)
|
|
65
|
+
return refreshInFlight;
|
|
66
|
+
refreshInFlight = (async () => {
|
|
67
|
+
try {
|
|
68
|
+
storeFreshPayload(builder());
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
logger.warn({
|
|
72
|
+
err: err instanceof Error ? err.message : String(err),
|
|
73
|
+
reason,
|
|
74
|
+
}, 'Failed to refresh coding CLI status cache');
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
refreshInFlight = null;
|
|
78
|
+
}
|
|
79
|
+
})();
|
|
80
|
+
return refreshInFlight;
|
|
81
|
+
}
|
|
82
|
+
export function startCodingCliStatusCache(options) {
|
|
83
|
+
if (started)
|
|
84
|
+
return;
|
|
85
|
+
started = true;
|
|
86
|
+
builder = options.build;
|
|
87
|
+
refreshIntervalMs = options.intervalMs ?? DEFAULT_REFRESH_INTERVAL_MS;
|
|
88
|
+
memory = loadFromDisk();
|
|
89
|
+
if (options.refreshOnStart !== false) {
|
|
90
|
+
void refreshCodingCliStatusCache('startup');
|
|
91
|
+
}
|
|
92
|
+
refreshTimer = setInterval(() => {
|
|
93
|
+
void refreshCodingCliStatusCache('interval');
|
|
94
|
+
}, refreshIntervalMs);
|
|
95
|
+
refreshTimer.unref?.();
|
|
96
|
+
}
|
|
97
|
+
export function stopCodingCliStatusCache() {
|
|
98
|
+
if (refreshTimer) {
|
|
99
|
+
clearInterval(refreshTimer);
|
|
100
|
+
refreshTimer = null;
|
|
101
|
+
}
|
|
102
|
+
started = false;
|
|
103
|
+
refreshInFlight = null;
|
|
104
|
+
}
|
|
105
|
+
export function getCodingCliStatusResponse(options) {
|
|
106
|
+
if (!builder) {
|
|
107
|
+
throw new Error('Coding CLI status cache has not been started');
|
|
108
|
+
}
|
|
109
|
+
if (options?.force) {
|
|
110
|
+
const record = storeFreshPayload(builder());
|
|
111
|
+
return attachMeta(record.payload, buildMeta(record, false));
|
|
112
|
+
}
|
|
113
|
+
if (memory) {
|
|
114
|
+
if (!refreshInFlight && Date.now() - memory.fetchedAt > refreshIntervalMs) {
|
|
115
|
+
void refreshCodingCliStatusCache('stale-read');
|
|
116
|
+
}
|
|
117
|
+
return attachMeta(memory.payload, buildMeta(memory, Boolean(refreshInFlight)));
|
|
118
|
+
}
|
|
119
|
+
const record = storeFreshPayload(builder());
|
|
120
|
+
return attachMeta(record.payload, buildMeta(record, false));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=coding-cli-status-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding-cli-status-cache.js","sourceRoot":"","sources":["../../src/core/coding-cli-status-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-config.d.ts","sourceRoot":"","sources":["../../src/core/gateway-config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAC7D,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"gateway-config.d.ts","sourceRoot":"","sources":["../../src/core/gateway-config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAC7D,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB7D;AAED,wBAAgB,iBAAiB,IAAI,aAAa,CAuCjD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAiC9D"}
|
|
@@ -24,6 +24,9 @@ export function normalizeGatewayUplinkUrl(raw) {
|
|
|
24
24
|
if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {
|
|
25
25
|
throw new Error(`Invalid gateway_url protocol: ${url.protocol}. Expected ws: or wss:.`);
|
|
26
26
|
}
|
|
27
|
+
if (url.hostname === 'gateway.supen.ai' || url.hostname === 'supen-gateway.onrender.com') {
|
|
28
|
+
url.hostname = 'hub.supen.ai';
|
|
29
|
+
}
|
|
27
30
|
return url.toString().replace(/\/+$/, '');
|
|
28
31
|
}
|
|
29
32
|
export function readGatewayConfig() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-config.js","sourceRoot":"","sources":["../../src/core/gateway-config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gateway-config.js","sourceRoot":"","sources":["../../src/core/gateway-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/http/routes/system.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/http/routes/system.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AA+M1B,KAAK,sBAAsB,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,yBAAyB,EAAE,CAAC;CAC3C,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAuVF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAoC,GAC3C,MAAM,EAAE,CAuBV;AAuxBD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAgC,EACrC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0anD;AA0+BD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA+8BlB"}
|
|
@@ -11,12 +11,14 @@ import { readCodexSubscription } from '../../core/codex-subscription.js';
|
|
|
11
11
|
import { buildHubSnapshotForSpace } from '../../core/hub-snapshot.js';
|
|
12
12
|
import { readEnrollmentState, createEnrollmentToken, verifyEnrollmentToken, setTrustState } from '../../core/enrollment.js';
|
|
13
13
|
import { collectOsTelemetryFields } from '../../core/os-info.js';
|
|
14
|
+
import { getCodingCliStatusResponse, startCodingCliStatusCache, } from '../../core/coding-cli-status-cache.js';
|
|
14
15
|
import { getGatewayInstance, getLlmToken } from '../../core/gateway.js';
|
|
15
16
|
import { normalizeGatewayUplinkUrl, readGatewayConfig, writeGatewayConfig, } from '../../core/gateway-config.js';
|
|
16
17
|
import { ensureSession, getAllAgents, getDailyUsage, getGlobalUsage, getSessionsForAgent, getSessionUiEvents, updateSessionBackendDriverId, updateSessionSdkId, } from '../../core/store.js';
|
|
17
18
|
import { listMcpEnvKeys, listMcpServers } from '../../mcp/default-servers.js';
|
|
18
19
|
import { getMcpEnvOverrides, updateMcpEnvOverrides } from '../../mcp/settings.js';
|
|
19
20
|
import { getMcpManager } from '../../mcp/index.js';
|
|
21
|
+
import { logger } from '../../core/logger.js';
|
|
20
22
|
import { buildDaemonOpenApiSpec } from '../../channels/http-routes.js';
|
|
21
23
|
import { writeJson, writeProtocolError, readJsonBody } from '../response.js';
|
|
22
24
|
import { listRecentThreadEventsAfter, readThreadEventLogHead, } from '../../core/thread-event-log.js';
|
|
@@ -39,6 +41,10 @@ const MIRRORED_THREAD_STREAM_REPLAY_MAX_BYTES = 8 * 1024 * 1024;
|
|
|
39
41
|
const MIRRORED_THREAD_RUNNING_LEASE_MS = 30 * 60 * 1000;
|
|
40
42
|
const MIRRORED_THREAD_HISTORY_CHUNK_BYTES = 1024 * 1024;
|
|
41
43
|
const require = createRequire(import.meta.url);
|
|
44
|
+
const HOST_DAEMON_INSTALL_DIR = path.join(SUPEN_HOME, 'daemon');
|
|
45
|
+
const HOST_DAEMON_CLI_PACKAGE_ROOT = path.join(HOST_DAEMON_INSTALL_DIR, 'node_modules', '@supen-ai', 'cli');
|
|
46
|
+
const HOST_DAEMON_BIN_PATH = path.join(HOST_DAEMON_CLI_PACKAGE_ROOT, 'daemon', 'scripts', 'supen-daemon.js');
|
|
47
|
+
const HOST_DAEMON_PACKAGE_SPEC = '@supen-ai/cli';
|
|
42
48
|
function readSqliteRows(dbPath, query) {
|
|
43
49
|
try {
|
|
44
50
|
const { DatabaseSync } = require('node:sqlite');
|
|
@@ -1692,7 +1698,7 @@ function threadStreamChunkForEvent(event) {
|
|
|
1692
1698
|
!Array.isArray(event.raw_payload) &&
|
|
1693
1699
|
typeof event.raw_payload.type === 'string' &&
|
|
1694
1700
|
String(event.raw_payload.type).trim()) {
|
|
1695
|
-
return event.raw_payload;
|
|
1701
|
+
return normalizeStoredCodexThreadChunk(event.raw_payload);
|
|
1696
1702
|
}
|
|
1697
1703
|
return {
|
|
1698
1704
|
type: 'data-codex-event',
|
|
@@ -1702,6 +1708,28 @@ function threadStreamChunkForEvent(event) {
|
|
|
1702
1708
|
},
|
|
1703
1709
|
};
|
|
1704
1710
|
}
|
|
1711
|
+
function normalizeStoredCodexThreadChunk(chunk) {
|
|
1712
|
+
if (chunk.type !== 'data-supen-event')
|
|
1713
|
+
return chunk;
|
|
1714
|
+
const data = chunk.data && typeof chunk.data === 'object' && !Array.isArray(chunk.data)
|
|
1715
|
+
? chunk.data
|
|
1716
|
+
: {};
|
|
1717
|
+
const raw = data.raw && typeof data.raw === 'object' && !Array.isArray(data.raw)
|
|
1718
|
+
? data.raw
|
|
1719
|
+
: {};
|
|
1720
|
+
return {
|
|
1721
|
+
...chunk,
|
|
1722
|
+
type: 'data-codex-event',
|
|
1723
|
+
data: {
|
|
1724
|
+
...data,
|
|
1725
|
+
eventType: typeof data.eventType === 'string' && data.eventType.trim()
|
|
1726
|
+
? data.eventType
|
|
1727
|
+
: typeof raw.method === 'string' && raw.method.trim()
|
|
1728
|
+
? raw.method
|
|
1729
|
+
: 'codex-event',
|
|
1730
|
+
},
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1705
1733
|
function buildMcpSettingsResponse() {
|
|
1706
1734
|
const overrides = getMcpEnvOverrides();
|
|
1707
1735
|
const runtimeEnv = { ...process.env };
|
|
@@ -1822,6 +1850,122 @@ function detectGlobalNpmRoot() {
|
|
|
1822
1850
|
return root;
|
|
1823
1851
|
}
|
|
1824
1852
|
}
|
|
1853
|
+
function findPackageRootFrom(startPath, expectedName) {
|
|
1854
|
+
if (!startPath)
|
|
1855
|
+
return null;
|
|
1856
|
+
let current = fs.existsSync(startPath) && fs.statSync(startPath).isDirectory()
|
|
1857
|
+
? startPath
|
|
1858
|
+
: path.dirname(startPath);
|
|
1859
|
+
for (let i = 0; i < 8; i += 1) {
|
|
1860
|
+
const packageJsonPath = path.join(current, 'package.json');
|
|
1861
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1862
|
+
try {
|
|
1863
|
+
const parsed = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
1864
|
+
if (parsed.name === expectedName)
|
|
1865
|
+
return current;
|
|
1866
|
+
}
|
|
1867
|
+
catch {
|
|
1868
|
+
return null;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
const next = path.dirname(current);
|
|
1872
|
+
if (next === current)
|
|
1873
|
+
break;
|
|
1874
|
+
current = next;
|
|
1875
|
+
}
|
|
1876
|
+
return null;
|
|
1877
|
+
}
|
|
1878
|
+
function readPackageVersion(packageRoot) {
|
|
1879
|
+
if (!packageRoot)
|
|
1880
|
+
return null;
|
|
1881
|
+
try {
|
|
1882
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
1883
|
+
return typeof parsed.version === 'string' ? parsed.version : null;
|
|
1884
|
+
}
|
|
1885
|
+
catch {
|
|
1886
|
+
return null;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
function detectDaemonPackageStatus() {
|
|
1890
|
+
const envVersion = process.env.SUPEN_DAEMON_VERSION || process.env.npm_package_version || null;
|
|
1891
|
+
let packageRoot = null;
|
|
1892
|
+
try {
|
|
1893
|
+
packageRoot = findPackageRootFrom(require.resolve('@supen-ai/daemon'), '@supen-ai/daemon');
|
|
1894
|
+
}
|
|
1895
|
+
catch {
|
|
1896
|
+
packageRoot = null;
|
|
1897
|
+
}
|
|
1898
|
+
if (!packageRoot) {
|
|
1899
|
+
for (const candidate of [process.argv[1], process.cwd(), path.resolve(process.cwd(), 'apps/daemon')]) {
|
|
1900
|
+
packageRoot = findPackageRootFrom(candidate || null, '@supen-ai/daemon');
|
|
1901
|
+
if (packageRoot)
|
|
1902
|
+
break;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
let cliPackageRoot = null;
|
|
1906
|
+
try {
|
|
1907
|
+
if (fs.existsSync(path.join(HOST_DAEMON_CLI_PACKAGE_ROOT, 'package.json'))) {
|
|
1908
|
+
cliPackageRoot = fs.realpathSync(HOST_DAEMON_CLI_PACKAGE_ROOT);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
catch {
|
|
1912
|
+
cliPackageRoot = null;
|
|
1913
|
+
}
|
|
1914
|
+
if (!cliPackageRoot) {
|
|
1915
|
+
cliPackageRoot = findPackageRootFrom(process.argv[1] || null, '@supen-ai/cli');
|
|
1916
|
+
}
|
|
1917
|
+
const bundledDaemonRoot = cliPackageRoot
|
|
1918
|
+
? path.join(cliPackageRoot, 'daemon')
|
|
1919
|
+
: null;
|
|
1920
|
+
const bundledDaemonVersion = readPackageVersion(bundledDaemonRoot);
|
|
1921
|
+
const packageVersion = readPackageVersion(packageRoot);
|
|
1922
|
+
const npmRoot = detectGlobalNpmRoot();
|
|
1923
|
+
const realPackageRoot = packageRoot ? fs.realpathSync(packageRoot) : null;
|
|
1924
|
+
const realCliPackageRoot = cliPackageRoot ? fs.realpathSync(cliPackageRoot) : null;
|
|
1925
|
+
const installSource = realCliPackageRoot && realCliPackageRoot.startsWith(`${HOST_DAEMON_INSTALL_DIR}${path.sep}`)
|
|
1926
|
+
? 'supen-cli-bundle'
|
|
1927
|
+
: realPackageRoot && npmRoot && realPackageRoot.startsWith(`${npmRoot}${path.sep}@supen-ai${path.sep}daemon`)
|
|
1928
|
+
? 'npm-global'
|
|
1929
|
+
: packageRoot
|
|
1930
|
+
? 'local-package'
|
|
1931
|
+
: null;
|
|
1932
|
+
return {
|
|
1933
|
+
version: envVersion || bundledDaemonVersion || packageVersion,
|
|
1934
|
+
package_root: packageRoot || bundledDaemonRoot,
|
|
1935
|
+
install_source: installSource,
|
|
1936
|
+
update_supported: installSource === 'supen-cli-bundle' || installSource === 'npm-global',
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
function restartManagedHostDaemon() {
|
|
1940
|
+
if (process.platform === 'linux') {
|
|
1941
|
+
const result = spawnSync('systemctl', ['--user', 'restart', 'supen-daemon.service'], {
|
|
1942
|
+
encoding: 'utf8',
|
|
1943
|
+
timeout: 10_000,
|
|
1944
|
+
});
|
|
1945
|
+
if (result.status === 0)
|
|
1946
|
+
return { method: 'systemd', attempted: true };
|
|
1947
|
+
}
|
|
1948
|
+
if (process.platform === 'darwin') {
|
|
1949
|
+
const uid = typeof process.getuid === 'function' ? process.getuid() : Number(process.env.UID || 0);
|
|
1950
|
+
const result = spawnSync('launchctl', ['kickstart', '-k', `gui/${uid}/ai.supen.daemon`], {
|
|
1951
|
+
encoding: 'utf8',
|
|
1952
|
+
timeout: 10_000,
|
|
1953
|
+
});
|
|
1954
|
+
if (result.status === 0)
|
|
1955
|
+
return { method: 'launchd', attempted: true };
|
|
1956
|
+
}
|
|
1957
|
+
if (fs.existsSync(HOST_DAEMON_BIN_PATH)) {
|
|
1958
|
+
const child = spawn(process.execPath, [HOST_DAEMON_BIN_PATH], {
|
|
1959
|
+
detached: true,
|
|
1960
|
+
stdio: 'ignore',
|
|
1961
|
+
env: process.env,
|
|
1962
|
+
});
|
|
1963
|
+
child.unref();
|
|
1964
|
+
setTimeout(() => process.exit(0), 250);
|
|
1965
|
+
return { method: 'detached-node', attempted: true };
|
|
1966
|
+
}
|
|
1967
|
+
return { method: 'none', attempted: false };
|
|
1968
|
+
}
|
|
1825
1969
|
function inferCliInstallSource(name, executablePath, resolvedPath) {
|
|
1826
1970
|
if (!executablePath && !resolvedPath)
|
|
1827
1971
|
return { install_source: null, update_supported: false };
|
|
@@ -1877,11 +2021,14 @@ function detectCliInstalled(name) {
|
|
|
1877
2021
|
encoding: 'utf8',
|
|
1878
2022
|
timeout: 5000,
|
|
1879
2023
|
});
|
|
1880
|
-
const output =
|
|
2024
|
+
const output = versionCmd.status === 0
|
|
2025
|
+
? trimLogNoise(`${versionCmd.stdout || ''}\n${versionCmd.stderr || ''}`) || ''
|
|
2026
|
+
: '';
|
|
2027
|
+
const semver = output.match(/\b\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?\b/)?.[0] || null;
|
|
1881
2028
|
const source = inferCliInstallSource(name, executablePath, resolvedPath);
|
|
1882
2029
|
return {
|
|
1883
2030
|
installed: true,
|
|
1884
|
-
version:
|
|
2031
|
+
version: semver || (output && !output.includes('\n') ? output : null),
|
|
1885
2032
|
path: executablePath,
|
|
1886
2033
|
resolved_path: resolvedPath,
|
|
1887
2034
|
...source,
|
|
@@ -1894,14 +2041,27 @@ function detectCodexAuthStatus(installed) {
|
|
|
1894
2041
|
encoding: 'utf8',
|
|
1895
2042
|
timeout: 8000,
|
|
1896
2043
|
});
|
|
1897
|
-
const
|
|
2044
|
+
const lines = `${result.stdout || ''}\n${result.stderr || ''}`
|
|
1898
2045
|
.split(/\r?\n/g)
|
|
1899
2046
|
.map((line) => trimLogNoise(line))
|
|
1900
|
-
.filter(Boolean)
|
|
1901
|
-
|
|
2047
|
+
.filter(Boolean);
|
|
2048
|
+
const text = lines.join('\n');
|
|
1902
2049
|
const authenticated = /logged in/i.test(text) && !/not logged in/i.test(text);
|
|
1903
|
-
const
|
|
1904
|
-
|
|
2050
|
+
const email = text.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i)?.[0] || null;
|
|
2051
|
+
const accountLine = lines.find((line) => /logged in as|account|email|user/i.test(line) && !line.startsWith('file://')) || null;
|
|
2052
|
+
const summary = authenticated
|
|
2053
|
+
? email || accountLine || 'Authenticated'
|
|
2054
|
+
: null;
|
|
2055
|
+
let accountId = null;
|
|
2056
|
+
try {
|
|
2057
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(resolveCodexHome(), 'auth.json'), 'utf8'));
|
|
2058
|
+
const tokens = parsed.tokens && typeof parsed.tokens === 'object' ? parsed.tokens : {};
|
|
2059
|
+
accountId = typeof tokens.account_id === 'string' && tokens.account_id.trim() ? tokens.account_id.trim() : null;
|
|
2060
|
+
}
|
|
2061
|
+
catch {
|
|
2062
|
+
accountId = null;
|
|
2063
|
+
}
|
|
2064
|
+
return { authenticated, summary, account_id: accountId };
|
|
1905
2065
|
}
|
|
1906
2066
|
function readCodexDefaultModel() {
|
|
1907
2067
|
const codexHome = resolveCodexHome();
|
|
@@ -2117,6 +2277,15 @@ function readCodingCliStatusPayload() {
|
|
|
2117
2277
|
codex_connect: codexConnectSnapshot(),
|
|
2118
2278
|
};
|
|
2119
2279
|
}
|
|
2280
|
+
function readCachedCodingCliStatusPayload(options) {
|
|
2281
|
+
startCodingCliStatusCache({
|
|
2282
|
+
build: () => ({
|
|
2283
|
+
...readCodingCliStatusPayload(),
|
|
2284
|
+
daemon: detectDaemonPackageStatus(),
|
|
2285
|
+
}),
|
|
2286
|
+
});
|
|
2287
|
+
return getCodingCliStatusResponse(options);
|
|
2288
|
+
}
|
|
2120
2289
|
function readRuntimeModelStatusPayload() {
|
|
2121
2290
|
const selected_cli = process.env.SUPEN_CODING_CLI || readConfigSummary().coding_cli || 'codex';
|
|
2122
2291
|
const codexTransport = normalizeCodexTransport(process.env.SUPEN_CODEX_TRANSPORT) ||
|
|
@@ -2437,7 +2606,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2437
2606
|
return true;
|
|
2438
2607
|
}
|
|
2439
2608
|
if (pathname === '/api/computers/{computer_id}/apps' && method === 'GET') {
|
|
2440
|
-
writeJson(res, 200,
|
|
2609
|
+
writeJson(res, 200, readCachedCodingCliStatusPayload());
|
|
2441
2610
|
return true;
|
|
2442
2611
|
}
|
|
2443
2612
|
if (pathname === '/api/computers/{computer_id}/runtime-models' && method === 'GET') {
|
|
@@ -2477,7 +2646,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2477
2646
|
writeJson(res, 200, {
|
|
2478
2647
|
ok: true,
|
|
2479
2648
|
...result,
|
|
2480
|
-
status:
|
|
2649
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2481
2650
|
});
|
|
2482
2651
|
}
|
|
2483
2652
|
catch (err) {
|
|
@@ -2497,7 +2666,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2497
2666
|
writeJson(res, 200, {
|
|
2498
2667
|
ok: true,
|
|
2499
2668
|
...result,
|
|
2500
|
-
status:
|
|
2669
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2501
2670
|
});
|
|
2502
2671
|
}
|
|
2503
2672
|
catch (err) {
|
|
@@ -2535,7 +2704,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2535
2704
|
writeJson(res, 200, {
|
|
2536
2705
|
ok: true,
|
|
2537
2706
|
cli,
|
|
2538
|
-
status:
|
|
2707
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2539
2708
|
});
|
|
2540
2709
|
}
|
|
2541
2710
|
catch (err) {
|
|
@@ -2543,6 +2712,43 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2543
2712
|
}
|
|
2544
2713
|
return true;
|
|
2545
2714
|
}
|
|
2715
|
+
if (pathname === '/api/computers/{computer_id}/daemon/update' && method === 'POST') {
|
|
2716
|
+
try {
|
|
2717
|
+
const current = detectDaemonPackageStatus();
|
|
2718
|
+
if (!current.update_supported) {
|
|
2719
|
+
writeProtocolError(res, 400, 'validation_error', 'daemon_update_not_supported', `Supen daemon is installed via ${current.install_source || current.package_root || 'an unknown source'}; update it with that installer on this computer.`);
|
|
2720
|
+
return true;
|
|
2721
|
+
}
|
|
2722
|
+
fs.mkdirSync(HOST_DAEMON_INSTALL_DIR, { recursive: true });
|
|
2723
|
+
const result = spawnSync('npm', ['install', '--prefix', HOST_DAEMON_INSTALL_DIR, HOST_DAEMON_PACKAGE_SPEC], {
|
|
2724
|
+
encoding: 'utf8',
|
|
2725
|
+
timeout: 120_000,
|
|
2726
|
+
});
|
|
2727
|
+
if (result.status !== 0) {
|
|
2728
|
+
const output = `${result.stdout || ''}\n${result.stderr || ''}`.trim() || 'Failed to update Supen daemon';
|
|
2729
|
+
writeProtocolError(res, 500, 'install_error', 'daemon_update_failed', output);
|
|
2730
|
+
return true;
|
|
2731
|
+
}
|
|
2732
|
+
writeJson(res, 200, {
|
|
2733
|
+
ok: true,
|
|
2734
|
+
daemon: detectDaemonPackageStatus(),
|
|
2735
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2736
|
+
restart: { scheduled: true },
|
|
2737
|
+
});
|
|
2738
|
+
setTimeout(() => {
|
|
2739
|
+
try {
|
|
2740
|
+
restartManagedHostDaemon();
|
|
2741
|
+
}
|
|
2742
|
+
catch (err) {
|
|
2743
|
+
logger.error({ err }, 'Failed to restart Supen daemon after update');
|
|
2744
|
+
}
|
|
2745
|
+
}, 250);
|
|
2746
|
+
}
|
|
2747
|
+
catch (err) {
|
|
2748
|
+
writeProtocolError(res, 500, 'install_error', 'daemon_update_failed', err?.message || 'Failed to update Supen daemon');
|
|
2749
|
+
}
|
|
2750
|
+
return true;
|
|
2751
|
+
}
|
|
2546
2752
|
const spaceAppConnectMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/apps\/([^/]+)\/connect$/);
|
|
2547
2753
|
if (spaceAppConnectMatch && method === 'POST') {
|
|
2548
2754
|
const cli = normalizeCliName(decodeURIComponent(spaceAppConnectMatch[1] || '').trim());
|
|
@@ -2550,7 +2756,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2550
2756
|
writeProtocolError(res, 400, 'validation_error', 'connect_not_supported', 'Only codex supports connect flow at the moment');
|
|
2551
2757
|
return true;
|
|
2552
2758
|
}
|
|
2553
|
-
const status =
|
|
2759
|
+
const status = readCachedCodingCliStatusPayload();
|
|
2554
2760
|
const codex = status.clis.find((entry) => entry.name === 'codex');
|
|
2555
2761
|
if (!codex?.installed) {
|
|
2556
2762
|
writeProtocolError(res, 400, 'validation_error', 'codex_not_installed', 'codex CLI is not installed');
|
|
@@ -2559,7 +2765,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2559
2765
|
writeJson(res, 200, {
|
|
2560
2766
|
ok: true,
|
|
2561
2767
|
codex_connect: startCodexConnectFlow(),
|
|
2562
|
-
status:
|
|
2768
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2563
2769
|
});
|
|
2564
2770
|
return true;
|
|
2565
2771
|
}
|
|
@@ -2572,7 +2778,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2572
2778
|
writeJson(res, 200, {
|
|
2573
2779
|
ok: true,
|
|
2574
2780
|
codex_connect: cancelCodexConnectFlow(),
|
|
2575
|
-
status:
|
|
2781
|
+
status: readCachedCodingCliStatusPayload({ force: true }),
|
|
2576
2782
|
});
|
|
2577
2783
|
return true;
|
|
2578
2784
|
}
|
|
@@ -2592,7 +2798,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2592
2798
|
writeProtocolError(res, 500, 'auth_error', 'codex_logout_failed', output);
|
|
2593
2799
|
return true;
|
|
2594
2800
|
}
|
|
2595
|
-
writeJson(res, 200, { ok: true, status:
|
|
2801
|
+
writeJson(res, 200, { ok: true, status: readCachedCodingCliStatusPayload({ force: true }) });
|
|
2596
2802
|
return true;
|
|
2597
2803
|
}
|
|
2598
2804
|
if (pathname === '/api/computers/{computer_id}/env' && method === 'PUT') {
|
|
@@ -2826,10 +3032,12 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
|
|
|
2826
3032
|
}
|
|
2827
3033
|
if (pathname === '/api/computers/{computer_id}' && method === 'GET') {
|
|
2828
3034
|
const enroll = readEnrollmentState(DAEMON_HOSTNAME || undefined);
|
|
3035
|
+
const daemon = detectDaemonPackageStatus();
|
|
2829
3036
|
writeJson(res, 200, {
|
|
2830
3037
|
daemon_id: enroll.daemon_id,
|
|
2831
3038
|
hostname: os.hostname(),
|
|
2832
|
-
version:
|
|
3039
|
+
version: daemon.version,
|
|
3040
|
+
daemon,
|
|
2833
3041
|
runtime: {
|
|
2834
3042
|
node: process.version,
|
|
2835
3043
|
platform: process.platform,
|