@stigmer/cli 3.12.9 → 3.14.0-dev.20260910084630
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/auth/login.d.ts.map +1 -1
- package/auth/login.js +30 -5
- package/auth/login.js.map +1 -1
- package/auth/token.d.ts +10 -5
- package/auth/token.d.ts.map +1 -1
- package/auth/token.js +30 -21
- package/auth/token.js.map +1 -1
- package/commands/apikey/index.d.ts.map +1 -1
- package/commands/apikey/index.js +11 -5
- package/commands/apikey/index.js.map +1 -1
- package/commands/auth/index.d.ts.map +1 -1
- package/commands/auth/index.js +19 -8
- package/commands/auth/index.js.map +1 -1
- package/commands/config/backend.d.ts.map +1 -1
- package/commands/config/backend.js +134 -12
- package/commands/config/backend.js.map +1 -1
- package/commands/connect.d.ts.map +1 -1
- package/commands/connect.js +6 -3
- package/commands/connect.js.map +1 -1
- package/commands/share.d.ts.map +1 -1
- package/commands/share.js +8 -6
- package/commands/share.js.map +1 -1
- package/commands/up.d.ts.map +1 -1
- package/commands/up.js +22 -6
- package/commands/up.js.map +1 -1
- package/config/config.d.ts +56 -7
- package/config/config.d.ts.map +1 -1
- package/config/config.js +115 -16
- package/config/config.js.map +1 -1
- package/config/index.d.ts +1 -1
- package/config/index.d.ts.map +1 -1
- package/config/index.js +1 -1
- package/config/index.js.map +1 -1
- package/config/keys.d.ts +1 -1
- package/config/keys.d.ts.map +1 -1
- package/config/keys.js +29 -6
- package/config/keys.js.map +1 -1
- package/config/resolve.d.ts +32 -21
- package/config/resolve.d.ts.map +1 -1
- package/config/resolve.js +80 -39
- package/config/resolve.js.map +1 -1
- package/local/constants.d.ts +8 -3
- package/local/constants.d.ts.map +1 -1
- package/local/constants.js +8 -3
- package/local/constants.js.map +1 -1
- package/local/daemon/components.d.ts.map +1 -1
- package/local/daemon/components.js +4 -2
- package/local/daemon/components.js.map +1 -1
- package/local/daemon/env.d.ts +16 -3
- package/local/daemon/env.d.ts.map +1 -1
- package/local/daemon/env.js +16 -3
- package/local/daemon/env.js.map +1 -1
- package/local/daemon/launch.d.ts.map +1 -1
- package/local/daemon/launch.js +5 -4
- package/local/daemon/launch.js.map +1 -1
- package/local/daemon/process.d.ts.map +1 -1
- package/local/daemon/process.js +8 -5
- package/local/daemon/process.js.map +1 -1
- package/local/runtime/index.d.ts +2 -2
- package/local/runtime/index.d.ts.map +1 -1
- package/local/runtime/index.js +4 -2
- package/local/runtime/index.js.map +1 -1
- package/local/runtime/node.d.ts +8 -0
- package/local/runtime/node.d.ts.map +1 -1
- package/local/runtime/node.js +74 -23
- package/local/runtime/node.js.map +1 -1
- package/local/runtime/runner.d.ts +2 -1
- package/local/runtime/runner.d.ts.map +1 -1
- package/local/runtime/runner.js +4 -31
- package/local/runtime/runner.js.map +1 -1
- package/local/runtime/runtimes-install.d.ts +13 -0
- package/local/runtime/runtimes-install.d.ts.map +1 -0
- package/local/runtime/runtimes-install.js +60 -0
- package/local/runtime/runtimes-install.js.map +1 -0
- package/local/runtime/server.d.ts +26 -30
- package/local/runtime/server.d.ts.map +1 -1
- package/local/runtime/server.js +106 -108
- package/local/runtime/server.js.map +1 -1
- package/local/seedpack/content.d.ts +3 -3
- package/local/seedpack/content.d.ts.map +1 -1
- package/local/seedpack/content.js +19 -13
- package/local/seedpack/content.js.map +1 -1
- package/local/status.d.ts.map +1 -1
- package/local/status.js +4 -2
- package/local/status.js.map +1 -1
- package/local/webconsole/index.d.ts +2 -3
- package/local/webconsole/index.d.ts.map +1 -1
- package/local/webconsole/index.js +24 -10
- package/local/webconsole/index.js.map +1 -1
- package/package.json +5 -5
- package/resources/connect/connect.d.ts +4 -3
- package/resources/connect/connect.d.ts.map +1 -1
- package/resources/connect/connect.js +17 -5
- package/resources/connect/connect.js.map +1 -1
- package/resources/connect/oauth.d.ts +5 -2
- package/resources/connect/oauth.d.ts.map +1 -1
- package/resources/connect/oauth.js +5 -4
- package/resources/connect/oauth.js.map +1 -1
- package/src/auth/login.ts +54 -9
- package/src/auth/token.test.ts +69 -13
- package/src/auth/token.ts +46 -22
- package/src/client/client.test.ts +10 -2
- package/src/commands/apikey/index.ts +42 -11
- package/src/commands/auth/index.ts +52 -14
- package/src/commands/config/backend.test.ts +122 -0
- package/src/commands/config/backend.ts +195 -14
- package/src/commands/connect.test.ts +22 -4
- package/src/commands/connect.ts +37 -13
- package/src/commands/share.ts +36 -16
- package/src/commands/up.ts +24 -6
- package/src/config/config.test.ts +62 -6
- package/src/config/config.ts +165 -24
- package/src/config/index.ts +6 -0
- package/src/config/keys.test.ts +27 -4
- package/src/config/keys.ts +46 -9
- package/src/config/resolve.test.ts +135 -34
- package/src/config/resolve.ts +88 -38
- package/src/local/constants.ts +8 -4
- package/src/local/daemon/components.test.ts +9 -1
- package/src/local/daemon/components.ts +4 -2
- package/src/local/daemon/daemon.integration.test.ts +1 -1
- package/src/local/daemon/env.test.ts +15 -4
- package/src/local/daemon/env.ts +33 -5
- package/src/local/daemon/launch.ts +5 -4
- package/src/local/daemon/process.ts +7 -4
- package/src/local/runtime/index.ts +6 -5
- package/src/local/runtime/node.ts +99 -23
- package/src/local/runtime/runner.ts +5 -36
- package/src/local/runtime/runtime.test.ts +58 -14
- package/src/local/runtime/runtimes-install.test.ts +56 -0
- package/src/local/runtime/runtimes-install.ts +72 -0
- package/src/local/runtime/server.test.ts +178 -114
- package/src/local/runtime/server.ts +149 -129
- package/src/local/seedpack/content.ts +52 -21
- package/src/local/status.ts +4 -2
- package/src/local/webconsole/index.ts +27 -10
- package/src/resources/connect/connect.integration.test.ts +79 -26
- package/src/resources/connect/connect.ts +72 -19
- package/src/resources/connect/oauth.test.ts +38 -12
- package/src/resources/connect/oauth.ts +27 -11
- package/src/resources/share.test.ts +2 -2
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
// Resolution and on-demand acquisition of the
|
|
1
|
+
// Resolution and on-demand acquisition of the stigmer server — the
|
|
2
|
+
// TypeScript implementation serving since the DD-006 cutover (D4 #24; the Go
|
|
3
|
+
// binary ladder that backed rollback retired with #25).
|
|
2
4
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// with the Temporal downloader (`../artifact.ts`); the one deliberate difference
|
|
8
|
-
// is the checksum step — this is our own executable, and DD-003 makes integrity
|
|
9
|
-
// non-negotiable.
|
|
5
|
+
// The server is launched exactly like the runner: a compiled `node main.js`,
|
|
6
|
+
// never `tsx src/main.ts` (the workers bundle Temporal workflows on boot in
|
|
7
|
+
// dev shape, and the slim artifact ships pre-built bundles — either way the
|
|
8
|
+
// entry must be compiled; see the server package's workflow-source.ts).
|
|
10
9
|
//
|
|
11
|
-
// Resolution order (
|
|
12
|
-
// 1.
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
10
|
+
// Resolution order (the D2 §6 switch semantics):
|
|
11
|
+
// 1. STIGMER_SERVER_DIR — an explicit server package dir (dist/main.js
|
|
12
|
+
// required), the STIGMER_RUNNER_DIR mirror.
|
|
13
|
+
// 2. The repo-tree server package (dev; build required).
|
|
14
|
+
// 3. The published `@stigmer/server-slim`, installed on demand into
|
|
15
|
+
// ~/.stigmer/runtimes/<version>/ alongside the runner's package — one
|
|
16
|
+
// CJS main.js, pre-built workflow bundles, and the per-platform
|
|
17
|
+
// Temporal native bridge selected by npm via optionalDependencies.
|
|
18
18
|
|
|
19
19
|
import { existsSync } from "node:fs";
|
|
20
20
|
import { homedir } from "node:os";
|
|
@@ -22,148 +22,168 @@ import { dirname, join } from "node:path";
|
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
23
|
import { CliExitError } from "../../errors/cli-exit-error.js";
|
|
24
24
|
import { ExitCode } from "../../errors/exit-codes.js";
|
|
25
|
+
import { log } from "../../logger.js";
|
|
25
26
|
import { VERSION } from "../../version.js";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const SUPPORTED_PLATFORMS = new Set(["darwin-arm64", "darwin-amd64", "linux-amd64"]);
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Find an already-present `stigmer-server` binary, or null. Pure: never
|
|
41
|
-
* downloads. `home` is injectable for tests.
|
|
42
|
-
*/
|
|
43
|
-
export function resolveServerBinary(home: string = homedir()): string | null {
|
|
44
|
-
for (const candidate of serverCandidates(home)) {
|
|
45
|
-
if (existsSync(candidate)) return candidate;
|
|
46
|
-
}
|
|
47
|
-
return which(SERVER_BINARY);
|
|
48
|
-
}
|
|
27
|
+
import { runtimesDir } from "../paths.js";
|
|
28
|
+
import type { ServerLaunch } from "../daemon/env.js";
|
|
29
|
+
import { resolveServerNode } from "./node.js";
|
|
30
|
+
import {
|
|
31
|
+
ensureRuntimesRoot,
|
|
32
|
+
isAcquirableRelease,
|
|
33
|
+
npmInstallIntoRuntimes,
|
|
34
|
+
type NpmInstall,
|
|
35
|
+
} from "./runtimes-install.js";
|
|
36
|
+
|
|
37
|
+
const SLIM_PACKAGE = "@stigmer/server-slim";
|
|
49
38
|
|
|
50
39
|
export interface EnsureServerOptions {
|
|
51
40
|
home?: string;
|
|
52
|
-
/** Release version
|
|
41
|
+
/** Release version of the slim server to acquire (defaults to the CLI version). */
|
|
53
42
|
version?: string;
|
|
54
|
-
/**
|
|
55
|
-
|
|
43
|
+
/** Node resolver (injectable for tests). */
|
|
44
|
+
node?: () => string;
|
|
45
|
+
/** npm install implementation (injectable for tests). */
|
|
46
|
+
install?: NpmInstall;
|
|
56
47
|
}
|
|
57
48
|
|
|
58
49
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* platform).
|
|
50
|
+
* Resolve what the daemon launches as `stigmer-server`: the explicit
|
|
51
|
+
* STIGMER_SERVER_DIR override, then the repo tree, then acquiring the
|
|
52
|
+
* published slim package. Throws actionable guidance on a missing build, an
|
|
53
|
+
* invalid override, or a non-release CLI build with nothing local.
|
|
64
54
|
*/
|
|
65
|
-
export
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
const version = opts.version ?? VERSION;
|
|
71
|
-
if (!isDownloadableRelease(version)) {
|
|
72
|
-
throw notFoundError();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const binPath = join(binDir(home), SERVER_BINARY);
|
|
76
|
-
await downloadServerBinary({ version, binPath, fetchImpl: opts.fetchImpl });
|
|
77
|
-
return binPath;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export interface ServerDownloadTarget {
|
|
81
|
-
/** Release version, e.g. "0.5.0" or "0.5.0-rc.1" (with or without a leading "v"). */
|
|
82
|
-
version: string;
|
|
83
|
-
/** Absolute path to write the extracted `stigmer-server` binary to. */
|
|
84
|
-
binPath: string;
|
|
85
|
-
/** Node platform (defaults to process.platform). */
|
|
86
|
-
platform?: NodeJS.Platform;
|
|
87
|
-
/** Node arch (defaults to process.arch). */
|
|
88
|
-
arch?: string;
|
|
89
|
-
/** Override the fetch implementation (tests). */
|
|
90
|
-
fetchImpl?: typeof fetch;
|
|
55
|
+
export function ensureServer(opts: EnsureServerOptions = {}): ServerLaunch {
|
|
56
|
+
const node = opts.node ?? resolveServerNode;
|
|
57
|
+
const local = resolveServerTs(node);
|
|
58
|
+
if (local !== null) return local;
|
|
59
|
+
return acquireServer({ ...opts, node });
|
|
91
60
|
}
|
|
92
61
|
|
|
93
62
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
63
|
+
* Resolve a repo-tree TS server (dev) or an explicit STIGMER_SERVER_DIR, or
|
|
64
|
+
* null when neither is present (the caller then acquires the slim package).
|
|
65
|
+
* Throws when an override is set but invalid, or when a found server is not
|
|
66
|
+
* built — both are actionable user-facing conditions, not a reason to
|
|
67
|
+
* silently download. `node` is injectable for tests.
|
|
97
68
|
*/
|
|
98
|
-
export
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
|
|
69
|
+
export function resolveServerTs(
|
|
70
|
+
node: () => string = resolveServerNode,
|
|
71
|
+
): ServerLaunch | null {
|
|
72
|
+
const override = process.env.STIGMER_SERVER_DIR;
|
|
73
|
+
if (override !== undefined && override !== "") {
|
|
74
|
+
if (!hasPackageJson(override)) {
|
|
75
|
+
throw new CliExitError(
|
|
76
|
+
`STIGMER_SERVER_DIR is not a server package: ${override}`,
|
|
77
|
+
ExitCode.General,
|
|
78
|
+
[
|
|
79
|
+
"Point STIGMER_SERVER_DIR at the @stigmer/server package directory (the one with package.json).",
|
|
80
|
+
],
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return resolveBuiltServer(override, node);
|
|
104
84
|
}
|
|
105
85
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
checksumUrl: `${url}.sha256`,
|
|
113
|
-
entryName: SERVER_BINARY,
|
|
114
|
-
binPath: target.binPath,
|
|
115
|
-
label: SERVER_BINARY,
|
|
116
|
-
fetchImpl: target.fetchImpl,
|
|
117
|
-
});
|
|
86
|
+
const root = repoRoot();
|
|
87
|
+
if (root !== null) {
|
|
88
|
+
const candidate = join(root, "backend", "services", "stigmer-server");
|
|
89
|
+
if (hasPackageJson(candidate)) return resolveBuiltServer(candidate, node);
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
118
92
|
}
|
|
119
93
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Acquire the published `@stigmer/server-slim@<version>` into
|
|
96
|
+
* ~/.stigmer/runtimes/<version>/ (idempotent: reuses a prior install; shares
|
|
97
|
+
* the install root with the runner's package) and resolve its `main.js`
|
|
98
|
+
* entry. The version is pinned to the CLI's own version so the server's
|
|
99
|
+
* protos and behavior stay in lockstep with the CLI and the runner.
|
|
100
|
+
*/
|
|
101
|
+
export function acquireServer(opts: EnsureServerOptions = {}): ServerLaunch {
|
|
102
|
+
const home = opts.home ?? homedir();
|
|
103
|
+
const version = opts.version ?? VERSION;
|
|
104
|
+
if (!isAcquirableRelease(version)) {
|
|
105
|
+
throw new CliExitError(
|
|
106
|
+
`cannot acquire ${SLIM_PACKAGE} for a non-release build (${version})`,
|
|
107
|
+
ExitCode.General,
|
|
108
|
+
[
|
|
109
|
+
"Run from the repo with a built server (make build-server), or set",
|
|
110
|
+
"STIGMER_SERVER_DIR to a built server package.",
|
|
111
|
+
"On-demand acquisition is only available for published releases.",
|
|
112
|
+
],
|
|
113
|
+
);
|
|
114
|
+
}
|
|
124
115
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
116
|
+
// Probe the Node capability BEFORE the download: a user on an FTS5-less
|
|
117
|
+
// Node must not fetch the full slim artifact only to be rejected after.
|
|
118
|
+
const node = opts.node ?? resolveServerNode;
|
|
119
|
+
const nodeBin = node();
|
|
120
|
+
const installDir = join(runtimesDir(home), version);
|
|
121
|
+
const entryPath = join(
|
|
122
|
+
installDir,
|
|
123
|
+
"node_modules",
|
|
124
|
+
"@stigmer",
|
|
125
|
+
"server-slim",
|
|
126
|
+
"main.js",
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (!existsSync(entryPath)) {
|
|
130
|
+
log.info(`acquiring ${SLIM_PACKAGE}`, { version, dir: installDir });
|
|
131
|
+
ensureRuntimesRoot(installDir);
|
|
132
|
+
const install = opts.install ?? npmInstallIntoRuntimes;
|
|
133
|
+
install(installDir, `${SLIM_PACKAGE}@${version}`);
|
|
134
|
+
}
|
|
131
135
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
if (!existsSync(entryPath)) {
|
|
137
|
+
throw new CliExitError(
|
|
138
|
+
`${SLIM_PACKAGE} install did not produce ${entryPath}`,
|
|
139
|
+
ExitCode.General,
|
|
140
|
+
[
|
|
141
|
+
"The install may have skipped the platform-native package for this OS/arch.",
|
|
142
|
+
`Remove ${installDir} and retry, or set STIGMER_SERVER_DIR to a built server.`,
|
|
143
|
+
],
|
|
144
|
+
);
|
|
145
|
+
}
|
|
138
146
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
return {
|
|
148
|
+
nodeBin,
|
|
149
|
+
entryPath,
|
|
150
|
+
appDir: dirname(entryPath),
|
|
151
|
+
};
|
|
143
152
|
}
|
|
144
153
|
|
|
145
|
-
function
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
function resolveBuiltServer(appDir: string, node: () => string): ServerLaunch {
|
|
155
|
+
const entryPath = join(appDir, "dist", "main.js");
|
|
156
|
+
if (!existsSync(entryPath)) {
|
|
157
|
+
throw new CliExitError(
|
|
158
|
+
`TS server not built: ${entryPath} is missing`,
|
|
159
|
+
ExitCode.General,
|
|
160
|
+
[
|
|
161
|
+
"Build it with: make build-server",
|
|
162
|
+
"The server must be compiled — it cannot run from source via tsx (its",
|
|
163
|
+
"Temporal workers bundle workflow code from the compiled dist).",
|
|
164
|
+
"STIGMER_SERVER_DIR expects the source package (dist/main.js); to run an",
|
|
165
|
+
"acquired @stigmer/server-slim install, unset it — the CLI resolves that",
|
|
166
|
+
"shape itself.",
|
|
167
|
+
],
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
return { nodeBin: node(), entryPath, appDir };
|
|
151
171
|
}
|
|
152
172
|
|
|
153
|
-
function
|
|
154
|
-
return
|
|
155
|
-
"`stigmer up` needs a stigmer-server release asset, which is published for",
|
|
156
|
-
"macOS (arm64/amd64) and Linux (amd64) only.",
|
|
157
|
-
"Point STIGMER_SERVER_BIN at a server binary you built yourself to proceed.",
|
|
158
|
-
]);
|
|
173
|
+
function hasPackageJson(dir: string): boolean {
|
|
174
|
+
return existsSync(join(dir, "package.json"));
|
|
159
175
|
}
|
|
160
176
|
|
|
161
|
-
// Walk up from this module to
|
|
162
|
-
// `bin/stigmer-server` in a dev checkout). Returns null outside a checkout.
|
|
177
|
+
// Walk up from this module to a repo root containing the TS server package.
|
|
163
178
|
function repoRoot(): string | null {
|
|
164
179
|
let dir = dirname(fileURLToPath(import.meta.url));
|
|
165
|
-
for (let i = 0; i <
|
|
166
|
-
if (
|
|
180
|
+
for (let i = 0; i < 10; i += 1) {
|
|
181
|
+
if (
|
|
182
|
+
existsSync(
|
|
183
|
+
join(dir, "backend", "services", "stigmer-server", "package.json"),
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
return dir;
|
|
167
187
|
const parent = dirname(dir);
|
|
168
188
|
if (parent === dir) break;
|
|
169
189
|
dir = parent;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Resolution and on-demand acquisition of the seedpack content.
|
|
2
2
|
//
|
|
3
3
|
// The seedpack (system agents, skills, MCP servers, workflows under the
|
|
4
|
-
// "stigmer" org) is the
|
|
4
|
+
// "stigmer" org) is the system content every backend is bootstrapped with.
|
|
5
5
|
// A lean `npx @stigmer/cli` must not carry ~300 content files (DD-002), so the
|
|
6
6
|
// content ships as `@stigmer/seedpack` and is acquired on demand — the same
|
|
7
7
|
// pattern as `@stigmer/runner-slim` and the managed Temporal binary.
|
|
@@ -12,14 +12,22 @@
|
|
|
12
12
|
// ~/.stigmer/runtimes/<version>/ and read from
|
|
13
13
|
// node_modules/@stigmer/seedpack.
|
|
14
14
|
//
|
|
15
|
-
// The content-hash and extract logic mirror `@stigmer/seedpack` exactly
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
15
|
+
// The content-hash and extract logic mirror `@stigmer/seedpack` exactly; the CLI
|
|
16
|
+
// reimplements them over a resolved directory so it stays decoupled from the
|
|
17
|
+
// package in the lean install (where the package is not a dependency, only an
|
|
18
|
+
// on-demand artifact). `seedpack/src/index.ts` is the one definition both follow.
|
|
19
19
|
|
|
20
20
|
import { execFileSync } from "node:child_process";
|
|
21
21
|
import { createHash } from "node:crypto";
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
cpSync,
|
|
24
|
+
existsSync,
|
|
25
|
+
mkdirSync,
|
|
26
|
+
readdirSync,
|
|
27
|
+
readFileSync,
|
|
28
|
+
statSync,
|
|
29
|
+
writeFileSync,
|
|
30
|
+
} from "node:fs";
|
|
23
31
|
import { homedir } from "node:os";
|
|
24
32
|
import { dirname, join, posix, relative, sep } from "node:path";
|
|
25
33
|
import { fileURLToPath } from "node:url";
|
|
@@ -33,9 +41,9 @@ const SEEDPACK_PACKAGE = "@stigmer/seedpack";
|
|
|
33
41
|
|
|
34
42
|
/**
|
|
35
43
|
* The canonical seedpack entries, in apply-safe order. Kept in sync with
|
|
36
|
-
* `SEEDPACK_ENTRIES` in `@stigmer/seedpack`
|
|
37
|
-
*
|
|
38
|
-
*
|
|
44
|
+
* `SEEDPACK_ENTRIES` in `@stigmer/seedpack` (`seedpack/src/index.ts`, the one
|
|
45
|
+
* definition) — `tools/`, `icons/`, and `canary/` (CI canary metadata, not a
|
|
46
|
+
* resource) are deliberately excluded so the content set (and thus the
|
|
39
47
|
* idempotency hash) is identical across delivery paths.
|
|
40
48
|
*/
|
|
41
49
|
export const SEEDPACK_ENTRIES = [
|
|
@@ -70,7 +78,9 @@ export interface ResolveSeedpackOptions {
|
|
|
70
78
|
* on-demand-acquired `@stigmer/seedpack` package. Throws actionable guidance when
|
|
71
79
|
* acquisition is not possible (non-release build, or a failed/incomplete install).
|
|
72
80
|
*/
|
|
73
|
-
export function resolveSeedpackContent(
|
|
81
|
+
export function resolveSeedpackContent(
|
|
82
|
+
opts: ResolveSeedpackOptions = {},
|
|
83
|
+
): SeedpackContent {
|
|
74
84
|
const repo = repoSeedpackDir();
|
|
75
85
|
if (repo !== null) return { dir: repo, source: "repo" };
|
|
76
86
|
return { dir: acquireSeedpack(opts), source: "package" };
|
|
@@ -86,10 +96,14 @@ export function acquireSeedpack(opts: ResolveSeedpackOptions = {}): string {
|
|
|
86
96
|
const home = opts.home ?? homedir();
|
|
87
97
|
const version = opts.version ?? VERSION;
|
|
88
98
|
if (!isAcquirableRelease(version)) {
|
|
89
|
-
throw new CliExitError(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
throw new CliExitError(
|
|
100
|
+
`cannot acquire ${SEEDPACK_PACKAGE} for a non-release build (${version})`,
|
|
101
|
+
ExitCode.General,
|
|
102
|
+
[
|
|
103
|
+
"Run from the repo (the seedpack/ tree is used directly in dev).",
|
|
104
|
+
"On-demand acquisition is only available for published releases.",
|
|
105
|
+
],
|
|
106
|
+
);
|
|
93
107
|
}
|
|
94
108
|
|
|
95
109
|
const installDir = join(runtimesDir(home), version);
|
|
@@ -103,16 +117,21 @@ export function acquireSeedpack(opts: ResolveSeedpackOptions = {}): string {
|
|
|
103
117
|
// additive and non-pruning, so this prefix is safely shared with the runner.
|
|
104
118
|
const rootPkg = join(installDir, "package.json");
|
|
105
119
|
if (!existsSync(rootPkg)) {
|
|
106
|
-
writeFileSync(
|
|
120
|
+
writeFileSync(
|
|
121
|
+
rootPkg,
|
|
122
|
+
`${JSON.stringify({ name: "stigmer-runtime", private: true, version: "0.0.0" }, null, 2)}\n`,
|
|
123
|
+
);
|
|
107
124
|
}
|
|
108
125
|
const install = opts.install ?? installSeedpack;
|
|
109
126
|
install(installDir, `${SEEDPACK_PACKAGE}@${version}`);
|
|
110
127
|
}
|
|
111
128
|
|
|
112
129
|
if (!existsSync(marker)) {
|
|
113
|
-
throw new CliExitError(
|
|
114
|
-
|
|
115
|
-
|
|
130
|
+
throw new CliExitError(
|
|
131
|
+
`${SEEDPACK_PACKAGE} install did not produce ${marker}`,
|
|
132
|
+
ExitCode.General,
|
|
133
|
+
[`Remove ${installDir} and retry.`],
|
|
134
|
+
);
|
|
116
135
|
}
|
|
117
136
|
return pkgDir;
|
|
118
137
|
}
|
|
@@ -121,9 +140,21 @@ export function acquireSeedpack(opts: ResolveSeedpackOptions = {}): string {
|
|
|
121
140
|
// the user sees the one-time download progress.
|
|
122
141
|
function installSeedpack(installDir: string, spec: string): void {
|
|
123
142
|
try {
|
|
124
|
-
execFileSync(
|
|
125
|
-
|
|
126
|
-
|
|
143
|
+
execFileSync(
|
|
144
|
+
"npm",
|
|
145
|
+
[
|
|
146
|
+
"install",
|
|
147
|
+
spec,
|
|
148
|
+
"--prefix",
|
|
149
|
+
installDir,
|
|
150
|
+
"--omit=dev",
|
|
151
|
+
"--no-audit",
|
|
152
|
+
"--no-fund",
|
|
153
|
+
],
|
|
154
|
+
{
|
|
155
|
+
stdio: "inherit",
|
|
156
|
+
},
|
|
157
|
+
);
|
|
127
158
|
} catch (err) {
|
|
128
159
|
throw new CliExitError(`failed to install ${spec}`, ExitCode.General, [
|
|
129
160
|
`Command: npm install ${spec} --prefix ${installDir}`,
|
package/src/local/status.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { join } from "node:path";
|
|
|
12
12
|
import { load as loadConfig } from "../config/config.js";
|
|
13
13
|
import { configPath } from "../config/paths.js";
|
|
14
14
|
import { CommandResult } from "../output/command-result.js";
|
|
15
|
-
import { SERVER_PORT, TEMPORAL_UI_PORT
|
|
15
|
+
import { SERVER_PORT, TEMPORAL_UI_PORT } from "./constants.js";
|
|
16
16
|
import { resolveApiKey, resolveProvider } from "./llm-config.js";
|
|
17
17
|
import { tcpConnects } from "./net/tcp.js";
|
|
18
18
|
import { dataDir } from "./paths.js";
|
|
@@ -144,7 +144,9 @@ function addWebUiSection(result: CommandResult, health: HealthState): void {
|
|
|
144
144
|
if (!temporalRunning && !webRunning) return;
|
|
145
145
|
|
|
146
146
|
const section = result.addSection("Web UI");
|
|
147
|
-
|
|
147
|
+
// The console shares the server's unified port (DD-012) — same origin as
|
|
148
|
+
// the API, served by the server itself.
|
|
149
|
+
if (webRunning) section.field("Console", `http://localhost:${SERVER_PORT}`);
|
|
148
150
|
if (temporalRunning) section.field("Temporal", `http://localhost:${TEMPORAL_UI_PORT}`);
|
|
149
151
|
}
|
|
150
152
|
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Web-console availability against the server's unified port.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
// :
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
3
|
+
// Since DD-012 (oss sub-project console-serving) the SERVER serves the
|
|
4
|
+
// console: the static export ships inside @stigmer/server-slim and the
|
|
5
|
+
// unified port's lane 4 serves it, synthesizing /config.json in-process.
|
|
6
|
+
// The CLI therefore PROBES rather than serves — /config.json answers 200
|
|
7
|
+
// exactly when a console export is bundled with the running server (a
|
|
8
|
+
// dev-tree server without the export falls through to the RPC adapter's
|
|
9
|
+
// 404), so the daemon's component state reports what a browser would
|
|
10
|
+
// actually find. The Go-era embedded console (go:embed on :8234) and the
|
|
11
|
+
// T05/T06 stub this file used to be are both retired by that design.
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
import { SERVER_PORT } from "../constants.js";
|
|
14
|
+
|
|
15
|
+
/** Keep the daemon's settle path snappy: a hung probe must not stall `stigmer up`. */
|
|
16
|
+
const PROBE_TIMEOUT_MS = 3000;
|
|
17
|
+
|
|
18
|
+
/** Whether the running server serves a bundled web console. */
|
|
19
|
+
export async function isWebConsoleAvailable(
|
|
20
|
+
serverPort: number = SERVER_PORT,
|
|
21
|
+
): Promise<boolean> {
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(`http://127.0.0.1:${serverPort}/config.json`, {
|
|
24
|
+
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
|
|
25
|
+
});
|
|
26
|
+
return response.ok;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
13
30
|
}
|