@stigmer/cli 3.12.6 → 3.12.8
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/commands/mcp-server.js +1 -1
- package/commands/setup.d.ts.map +1 -1
- package/commands/setup.js +38 -18
- package/commands/setup.js.map +1 -1
- package/local/daemon/components.d.ts.map +1 -1
- package/local/daemon/components.js +11 -1
- package/local/daemon/components.js.map +1 -1
- package/local/daemon/env.d.ts +6 -0
- package/local/daemon/env.d.ts.map +1 -1
- package/local/daemon/env.js +8 -0
- package/local/daemon/env.js.map +1 -1
- package/local/daemon/launch.d.ts.map +1 -1
- package/local/daemon/launch.js +15 -0
- package/local/daemon/launch.js.map +1 -1
- package/local/operator-config.d.ts +28 -0
- package/local/operator-config.d.ts.map +1 -0
- package/local/operator-config.js +77 -0
- package/local/operator-config.js.map +1 -0
- package/local/setup/wizard.d.ts +16 -3
- package/local/setup/wizard.d.ts.map +1 -1
- package/local/setup/wizard.js +72 -13
- package/local/setup/wizard.js.map +1 -1
- package/package.json +5 -5
- package/src/commands/mcp-server.ts +1 -1
- package/src/commands/setup.ts +48 -18
- package/src/local/daemon/components.test.ts +20 -0
- package/src/local/daemon/components.ts +9 -1
- package/src/local/daemon/env.test.ts +21 -0
- package/src/local/daemon/env.ts +14 -0
- package/src/local/daemon/launch.ts +17 -0
- package/src/local/operator-config.test.ts +72 -0
- package/src/local/operator-config.ts +95 -0
- package/src/local/setup/wizard.test.ts +46 -1
- package/src/local/setup/wizard.ts +82 -13
|
@@ -7,13 +7,19 @@
|
|
|
7
7
|
// Local agent execution is Anthropic-only (the native runner only constructs
|
|
8
8
|
// Anthropic clients and the registry's native entries are Anthropic models),
|
|
9
9
|
// so the interactive flow is a single API-key prompt rather than a provider
|
|
10
|
-
// menu
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// menu, followed by the skippable operator-identity prompt (oss#796). There
|
|
11
|
+
// is no model concept here at all: the platform model registry owns the
|
|
12
|
+
// execution default, and per-run overrides belong to `stigmer run --model`
|
|
13
|
+
// (oss#314 removed the dead setup-level pin).
|
|
13
14
|
|
|
14
15
|
import type { Config } from "../../config/config.js";
|
|
15
16
|
import { type LlmSettings, setLlm } from "../llm-config.js";
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
type OperatorSettings,
|
|
19
|
+
setOperator,
|
|
20
|
+
validateOperatorIdentity,
|
|
21
|
+
} from "../operator-config.js";
|
|
22
|
+
import { promptLine, promptSecret } from "./prompt.js";
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* The providers `stigmer setup` accepts. This is the single source of truth
|
|
@@ -47,25 +53,88 @@ export function applyChoice(config: Config, choice: ProviderChoice, inputs: Sele
|
|
|
47
53
|
return setLlm(config, buildLlmForChoice(choice, inputs));
|
|
48
54
|
}
|
|
49
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Resolve operator-identity inputs to the settings to persist, validating the
|
|
58
|
+
* way the server's boot check will (oss#796) — the pure decision core shared
|
|
59
|
+
* by the flag path and the interactive prompt, like buildLlmForChoice. An
|
|
60
|
+
* empty email with an empty name yields `undefined` (nothing to persist —
|
|
61
|
+
* identity stays whatever it was; the anonymous default is the absence of
|
|
62
|
+
* the section, not an empty one). Throws on inputs the server would refuse
|
|
63
|
+
* at boot, so the failure surfaces at setup time.
|
|
64
|
+
*/
|
|
65
|
+
export function buildOperatorForInputs(email: string, name: string): OperatorSettings | undefined {
|
|
66
|
+
const error = validateOperatorIdentity(email, name);
|
|
67
|
+
if (error !== undefined) {
|
|
68
|
+
throw new Error(error);
|
|
69
|
+
}
|
|
70
|
+
const trimmedEmail = email.trim();
|
|
71
|
+
if (trimmedEmail === "") return undefined;
|
|
72
|
+
const trimmedName = name.trim();
|
|
73
|
+
return trimmedName === "" ? { email: trimmedEmail } : { email: trimmedEmail, name: trimmedName };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Apply operator-identity inputs to a config, returning the updated copy. */
|
|
77
|
+
export function applyOperatorIdentity(config: Config, email: string, name: string): Config {
|
|
78
|
+
const settings = buildOperatorForInputs(email, name);
|
|
79
|
+
return settings === undefined ? config : setOperator(config, settings);
|
|
80
|
+
}
|
|
81
|
+
|
|
50
82
|
/**
|
|
51
83
|
* Run the interactive setup against the current terminal: one Anthropic
|
|
52
|
-
* API-key prompt
|
|
53
|
-
*
|
|
54
|
-
* entry is an explicit skip.
|
|
84
|
+
* API-key prompt, then the (skippable) operator-identity prompt. A key
|
|
85
|
+
* already in the environment is used without prompting (and never persisted —
|
|
86
|
+
* env precedence makes a copy redundant); an empty entry is an explicit skip.
|
|
55
87
|
*/
|
|
56
88
|
export async function runInteractiveWizard(config: Config, env: NodeJS.ProcessEnv = process.env): Promise<Config> {
|
|
57
89
|
process.stderr.write("\nStigmer runs local agents on Anthropic Claude models.\n");
|
|
58
90
|
process.stderr.write("The model is chosen automatically from the platform model registry.\n\n");
|
|
59
91
|
|
|
92
|
+
let updated: Config;
|
|
60
93
|
if (env.ANTHROPIC_API_KEY) {
|
|
61
94
|
process.stderr.write("Using ANTHROPIC_API_KEY from environment\n");
|
|
62
|
-
|
|
95
|
+
updated = applyChoice(config, "anthropic");
|
|
96
|
+
} else {
|
|
97
|
+
const key = (await promptSecret("Enter your Anthropic API key (press Enter to skip)")).trim();
|
|
98
|
+
if (key === "") {
|
|
99
|
+
process.stderr.write("Skipped. Agents won't execute until a provider is configured (stigmer setup).\n");
|
|
100
|
+
updated = applyChoice(config, "skip");
|
|
101
|
+
} else {
|
|
102
|
+
updated = applyChoice(config, "anthropic", { apiKey: key });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return runOperatorIdentityStep(updated, env);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The operator-identity step (oss#796): opt-in, skippable, and env-aware in
|
|
111
|
+
* the same way the API-key step is — an env-provided identity is used without
|
|
112
|
+
* prompting and never persisted (env precedence makes a copy redundant). An
|
|
113
|
+
* invalid entry is refused and NOT persisted (re-run `stigmer setup`), the
|
|
114
|
+
* same rule the server enforces at boot, just earlier.
|
|
115
|
+
*/
|
|
116
|
+
async function runOperatorIdentityStep(config: Config, env: NodeJS.ProcessEnv): Promise<Config> {
|
|
117
|
+
process.stderr.write(
|
|
118
|
+
"\nAn operator identity attributes local creates to you and unlocks identity-gated MCP tools.\n",
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if ((env.STIGMER_OPERATOR_EMAIL ?? "").trim() !== "") {
|
|
122
|
+
process.stderr.write("Using STIGMER_OPERATOR_EMAIL from environment\n");
|
|
123
|
+
return config;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const email = (await promptLine("Operator email (press Enter to skip): ")).trim();
|
|
127
|
+
if (email === "") {
|
|
128
|
+
return config;
|
|
63
129
|
}
|
|
130
|
+
const name = (await promptLine("Operator display name (optional): ")).trim();
|
|
64
131
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
132
|
+
try {
|
|
133
|
+
return applyOperatorIdentity(config, email, name);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
process.stderr.write(
|
|
136
|
+
`Not saved: ${error instanceof Error ? error.message : String(error)} — re-run stigmer setup.\n`,
|
|
137
|
+
);
|
|
138
|
+
return config;
|
|
69
139
|
}
|
|
70
|
-
return applyChoice(config, "anthropic", { apiKey: key });
|
|
71
140
|
}
|