muonroi-cli 1.8.5 → 1.9.0
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/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +20 -4
- package/dist/packages/agent-harness-core/src/event-tee.js +32 -5
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +14 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +86 -10
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +24 -2
- package/dist/src/agent-harness/mock-model.d.ts +10 -0
- package/dist/src/agent-harness/mock-model.js +6 -2
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/keys.d.ts +8 -45
- package/dist/src/cli/keys.js +18 -324
- package/dist/src/council/clarifier.d.ts +4 -2
- package/dist/src/council/clarifier.js +158 -36
- package/dist/src/council/debate-planner.js +3 -2
- package/dist/src/council/debate.js +59 -5
- package/dist/src/council/index.d.ts +23 -0
- package/dist/src/council/index.js +37 -2
- package/dist/src/council/llm.d.ts +62 -0
- package/dist/src/council/llm.js +123 -23
- package/dist/src/council/panel-select.js +13 -3
- package/dist/src/council/planner.js +17 -0
- package/dist/src/council/preflight.d.ts +10 -0
- package/dist/src/council/preflight.js +36 -0
- package/dist/src/council/prompts.d.ts +9 -1
- package/dist/src/council/prompts.js +23 -6
- package/dist/src/council/types.d.ts +10 -0
- package/dist/src/ee/auth.d.ts +19 -0
- package/dist/src/ee/auth.js +39 -0
- package/dist/src/ee/client.js +28 -3
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/flow/compaction/compress.d.ts +2 -2
- package/dist/src/flow/compaction/compress.js +21 -8
- package/dist/src/flow/compaction/extract.d.ts +3 -3
- package/dist/src/flow/compaction/extract.js +6 -6
- package/dist/src/flow/compaction/index.d.ts +2 -1
- package/dist/src/flow/compaction/index.js +29 -3
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/flags.d.ts +11 -0
- package/dist/src/gsd/flags.js +19 -0
- package/dist/src/gsd/plan-council.js +104 -72
- package/dist/src/gsd/verdict-schema.d.ts +1 -1
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/index.js +129 -260
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/mcp/client-pool.js +43 -15
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog.json +19 -19
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/compaction.d.ts +2 -3
- package/dist/src/orchestrator/compaction.js +8 -8
- package/dist/src/orchestrator/council-manager.js +9 -8
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +26 -8
- package/dist/src/orchestrator/orchestrator.d.ts +25 -0
- package/dist/src/orchestrator/orchestrator.js +204 -50
- package/dist/src/orchestrator/preprocessor.js +2 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +5 -0
- package/dist/src/orchestrator/safety-intercept.js +7 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +8 -1
- package/dist/src/orchestrator/stall-watchdog.js +24 -3
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +54 -21
- package/dist/src/orchestrator/tool-engine.d.ts +19 -0
- package/dist/src/orchestrator/tool-engine.js +241 -25
- package/dist/src/orchestrator/turn-watchdog.d.ts +7 -0
- package/dist/src/orchestrator/turn-watchdog.js +38 -9
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +2 -2
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/llm-classify.d.ts +78 -3
- package/dist/src/pil/llm-classify.js +351 -111
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +7 -0
- package/dist/src/pil/pipeline.js +2 -0
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +37 -18
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +14 -1
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/index.js +7 -0
- package/dist/src/product-loop/loop-driver.js +21 -8
- package/dist/src/product-loop/phase-plan.d.ts +16 -0
- package/dist/src/product-loop/phase-plan.js +42 -4
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +30 -11
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +62 -0
- package/dist/src/product-loop/sprint-runner.js +309 -8
- package/dist/src/product-loop/types.d.ts +25 -0
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +14 -0
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -70
- package/dist/src/providers/auth/types.d.ts +8 -0
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +21 -17
- package/dist/src/providers/keychain.js +124 -135
- package/dist/src/providers/runtime.d.ts +24 -9
- package/dist/src/providers/runtime.js +48 -37
- package/dist/src/providers/strategies/thinking-mode.js +9 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/self-qa/agentic-loop.js +3 -2
- package/dist/src/storage/transcript.js +56 -2
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +76 -1
- package/dist/src/tools/registry.d.ts +17 -0
- package/dist/src/tools/registry.js +116 -1
- package/dist/src/types/index.d.ts +29 -1
- package/dist/src/ui/app.js +67 -4
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/council-phase-timeline.js +17 -2
- package/dist/src/ui/components/council-question-card.js +1 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +2 -1
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/menu-items.js +11 -2
- package/dist/src/ui/use-app-logic.js +354 -224
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/settings.d.ts +27 -0
- package/dist/src/utils/settings.js +38 -2
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/verify/entrypoint.js +51 -16
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/package.json +1 -2
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -194
package/dist/src/cli/keys.d.ts
CHANGED
|
@@ -1,62 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `muonroi-cli keys` subcommand group.
|
|
3
3
|
*
|
|
4
|
-
* Manages provider API keys via the
|
|
5
|
-
*
|
|
6
|
-
* keychain → env → settings.json priority chain in providers/keychain.ts.
|
|
7
|
-
*
|
|
8
|
-
* On Linux without libsecret + an active secret service (gnome-keyring etc.),
|
|
9
|
-
* or in headless sessions, keychain writes return false and callers fall back
|
|
10
|
-
* to advising environment variables (which are still honored at runtime).
|
|
4
|
+
* Manages provider API keys via the env-store. Keys are read by the CLI through
|
|
5
|
+
* the env-store → env → settings.json priority chain in providers/keychain.ts.
|
|
11
6
|
*
|
|
12
7
|
* Subcommands:
|
|
13
|
-
* keys set <provider> — interactive prompt, stores
|
|
8
|
+
* keys set <provider> — interactive prompt, stores the key
|
|
14
9
|
* keys list — show masked keys currently stored
|
|
15
10
|
* keys delete <provider> — remove a stored key
|
|
16
|
-
* keys
|
|
17
|
-
* keys
|
|
11
|
+
* keys export <file> — export keys to an encrypted portable bundle
|
|
12
|
+
* keys import <file> — import an encrypted bundle
|
|
18
13
|
* keys login <provider> — OAuth login (openai, xai)
|
|
19
14
|
* keys logout <provider> — OAuth logout (openai, xai)
|
|
20
15
|
*/
|
|
21
16
|
import { type ChatSecretId } from "../chat/chat-keychain.js";
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
export declare function runKeysSet(provider: string, options?: KeysSetOptions): Promise<void>;
|
|
27
|
-
export declare function runMcpKeysSet(id: string, options?: KeysSetOptions): Promise<void>;
|
|
17
|
+
export type KeysSetOptions = Record<string, never>;
|
|
18
|
+
export declare function runKeysSet(provider: string, _options?: KeysSetOptions): Promise<void>;
|
|
19
|
+
export declare function runMcpKeysSet(id: string, _options?: KeysSetOptions): Promise<void>;
|
|
28
20
|
export declare function runKeysList(): Promise<void>;
|
|
29
21
|
export declare function runKeysDelete(provider: string): Promise<void>;
|
|
30
22
|
export declare function runKeysExport(filePath: string): Promise<void>;
|
|
31
23
|
export declare function runKeysImport(filePath: string): Promise<void>;
|
|
32
|
-
interface BwImportOptions {
|
|
33
|
-
providers?: string[];
|
|
34
|
-
itemPrefix?: string;
|
|
35
|
-
}
|
|
36
|
-
export declare function runKeysImportBw(opts?: BwImportOptions): Promise<void>;
|
|
37
|
-
interface McpBwImportOptions {
|
|
38
|
-
keys?: string[];
|
|
39
|
-
itemPrefix?: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Import MCP secrets (e.g. Tavily) from a Bitwarden vault into the OS
|
|
43
|
-
* keychain via mcp-keychain. Vault items are expected at `<prefix><id>` —
|
|
44
|
-
* default prefix `muonroi-cli/`. The key value is read from the item's
|
|
45
|
-
* notes field, mirroring the provider import-bw flow.
|
|
46
|
-
*/
|
|
47
|
-
export declare function runMcpImportBw(opts?: McpBwImportOptions): Promise<void>;
|
|
48
24
|
export declare function runChatKeySet(id: ChatSecretId, value: string): Promise<void>;
|
|
49
|
-
interface ChatBwImportOptions {
|
|
50
|
-
ids?: ChatSecretId[];
|
|
51
|
-
itemPrefix?: string;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Import chat secrets (discord-token, discord-guild-id, slack-token, slack-team-id)
|
|
55
|
-
* from a Bitwarden vault into the OS keychain. Vault items are expected at
|
|
56
|
-
* `<prefix><id>` — default prefix `muonroi-cli/chat-`. The value is read from
|
|
57
|
-
* the item's notes field, mirroring the provider/MCP import-bw flow.
|
|
58
|
-
*/
|
|
59
|
-
export declare function runChatImportBw(opts?: ChatBwImportOptions): Promise<void>;
|
|
60
25
|
/**
|
|
61
26
|
* `muonroi-cli keys login <provider>`
|
|
62
27
|
*
|
|
@@ -74,5 +39,3 @@ export declare function runKeysLogin(provider: string): Promise<void>;
|
|
|
74
39
|
* through the OAuth registry — no provider branching.
|
|
75
40
|
*/
|
|
76
41
|
export declare function runKeysLogout(provider: string): Promise<void>;
|
|
77
|
-
export declare function runKeysCleanupSettings(): Promise<void>;
|
|
78
|
-
export {};
|
package/dist/src/cli/keys.js
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `muonroi-cli keys` subcommand group.
|
|
3
3
|
*
|
|
4
|
-
* Manages provider API keys via the
|
|
5
|
-
*
|
|
6
|
-
* keychain → env → settings.json priority chain in providers/keychain.ts.
|
|
7
|
-
*
|
|
8
|
-
* On Linux without libsecret + an active secret service (gnome-keyring etc.),
|
|
9
|
-
* or in headless sessions, keychain writes return false and callers fall back
|
|
10
|
-
* to advising environment variables (which are still honored at runtime).
|
|
4
|
+
* Manages provider API keys via the env-store. Keys are read by the CLI through
|
|
5
|
+
* the env-store → env → settings.json priority chain in providers/keychain.ts.
|
|
11
6
|
*
|
|
12
7
|
* Subcommands:
|
|
13
|
-
* keys set <provider> — interactive prompt, stores
|
|
8
|
+
* keys set <provider> — interactive prompt, stores the key
|
|
14
9
|
* keys list — show masked keys currently stored
|
|
15
10
|
* keys delete <provider> — remove a stored key
|
|
16
|
-
* keys
|
|
17
|
-
* keys
|
|
11
|
+
* keys export <file> — export keys to an encrypted portable bundle
|
|
12
|
+
* keys import <file> — import an encrypted bundle
|
|
18
13
|
* keys login <provider> — OAuth login (openai, xai)
|
|
19
14
|
* keys logout <provider> — OAuth logout (openai, xai)
|
|
20
15
|
*/
|
|
21
|
-
import { spawnSync } from "node:child_process";
|
|
22
16
|
import { promises as fs } from "node:fs";
|
|
23
|
-
import * as os from "node:os";
|
|
24
17
|
import * as path from "node:path";
|
|
25
18
|
import { getChatSecret, listChatSecrets, setChatSecret } from "../chat/chat-keychain.js";
|
|
26
19
|
import { setMcpKey } from "../mcp/mcp-keychain.js";
|
|
@@ -39,11 +32,6 @@ const MCP_KEY_IDS = ["tavily"];
|
|
|
39
32
|
function isMcpKeyId(value) {
|
|
40
33
|
return MCP_KEY_IDS.includes(value);
|
|
41
34
|
}
|
|
42
|
-
const CHAT_SECRET_IDS = ["discord-token", "discord-guild-id", "slack-token", "slack-team-id"];
|
|
43
|
-
function isChatSecretId(value) {
|
|
44
|
-
return CHAT_SECRET_IDS.includes(value);
|
|
45
|
-
}
|
|
46
|
-
const getSettingsPath = () => path.join(os.homedir(), ".muonroi-cli", "user-settings.json");
|
|
47
35
|
function maskKey(key) {
|
|
48
36
|
if (key.length <= 10)
|
|
49
37
|
return "***";
|
|
@@ -110,7 +98,7 @@ async function promptHidden(question) {
|
|
|
110
98
|
process.stdin.on("data", onData);
|
|
111
99
|
});
|
|
112
100
|
}
|
|
113
|
-
export async function runKeysSet(provider,
|
|
101
|
+
export async function runKeysSet(provider, _options = {}) {
|
|
114
102
|
const norm = normalizeProvider(provider);
|
|
115
103
|
if (!norm) {
|
|
116
104
|
console.error(`Unknown provider '${provider}'. Valid: ${KEYCHAIN_PROVIDER_IDS.join(", ")}`);
|
|
@@ -121,16 +109,6 @@ export async function runKeysSet(provider, options = {}) {
|
|
|
121
109
|
console.error("Aborted (empty key).");
|
|
122
110
|
process.exit(1);
|
|
123
111
|
}
|
|
124
|
-
if (options.bw) {
|
|
125
|
-
const { writeBwSecureNote } = await import("./bw-vault.js");
|
|
126
|
-
const itemName = `${options.itemPrefix ?? "muonroi-cli/"}${provider}`;
|
|
127
|
-
const res = await writeBwSecureNote(itemName, key);
|
|
128
|
-
if (!res.ok) {
|
|
129
|
-
console.error(`Bitwarden write failed: ${res.error}`);
|
|
130
|
-
process.exit(2);
|
|
131
|
-
}
|
|
132
|
-
console.log(`Bitwarden vault: ${res.action} '${itemName}'.`);
|
|
133
|
-
}
|
|
134
112
|
try {
|
|
135
113
|
const ok = await setKeyForProvider(norm, key);
|
|
136
114
|
if (!ok) {
|
|
@@ -150,7 +128,7 @@ export async function runKeysSet(provider, options = {}) {
|
|
|
150
128
|
process.exit(1);
|
|
151
129
|
}
|
|
152
130
|
}
|
|
153
|
-
export async function runMcpKeysSet(id,
|
|
131
|
+
export async function runMcpKeysSet(id, _options = {}) {
|
|
154
132
|
if (!isMcpKeyId(id)) {
|
|
155
133
|
console.error(`Unknown MCP key '${id}'. Valid: ${MCP_KEY_IDS.join(", ")}`);
|
|
156
134
|
process.exit(1);
|
|
@@ -160,16 +138,6 @@ export async function runMcpKeysSet(id, options = {}) {
|
|
|
160
138
|
console.error("Aborted (empty key).");
|
|
161
139
|
process.exit(1);
|
|
162
140
|
}
|
|
163
|
-
if (options.bw) {
|
|
164
|
-
const { writeBwSecureNote } = await import("./bw-vault.js");
|
|
165
|
-
const itemName = `${options.itemPrefix ?? "muonroi-cli/"}${id}`;
|
|
166
|
-
const res = await writeBwSecureNote(itemName, key);
|
|
167
|
-
if (!res.ok) {
|
|
168
|
-
console.error(`Bitwarden write failed: ${res.error}`);
|
|
169
|
-
process.exit(2);
|
|
170
|
-
}
|
|
171
|
-
console.log(`Bitwarden vault: ${res.action} '${itemName}'.`);
|
|
172
|
-
}
|
|
173
141
|
try {
|
|
174
142
|
const ok = await setMcpKey(id, key);
|
|
175
143
|
if (!ok) {
|
|
@@ -211,7 +179,7 @@ export async function runKeysList() {
|
|
|
211
179
|
const hasAnything = stored.length > 0 || chatStored.length > 0 || oauthRows.length > 0;
|
|
212
180
|
if (!hasAnything) {
|
|
213
181
|
console.log("No keys stored in OS keychain.");
|
|
214
|
-
console.log("Run 'muonroi-cli keys set <provider>'
|
|
182
|
+
console.log("Run 'muonroi-cli keys set <provider>' to add some.");
|
|
215
183
|
console.log("Run 'muonroi-cli keys login openai' to log in with your OpenAI subscription.");
|
|
216
184
|
console.log("Run 'muonroi-cli keys login xai' to log in with your SuperGrok / X Premium+ subscription.");
|
|
217
185
|
return;
|
|
@@ -365,161 +333,6 @@ export async function runKeysImport(filePath) {
|
|
|
365
333
|
}
|
|
366
334
|
console.log(`\nImported ${imported} key(s); ${skipped} skipped.`);
|
|
367
335
|
}
|
|
368
|
-
export async function runKeysImportBw(opts = {}) {
|
|
369
|
-
const which = spawnSync("bw", ["--version"], { encoding: "utf8" });
|
|
370
|
-
if (which.status !== 0) {
|
|
371
|
-
console.error("Bitwarden CLI ('bw') not found in PATH.");
|
|
372
|
-
console.error("Install: https://bitwarden.com/help/cli/");
|
|
373
|
-
process.exit(2);
|
|
374
|
-
}
|
|
375
|
-
const session = process.env.BW_SESSION;
|
|
376
|
-
if (!session) {
|
|
377
|
-
console.error("BW_SESSION not set. Run:");
|
|
378
|
-
console.error(" export BW_SESSION=$(bw unlock --raw)");
|
|
379
|
-
process.exit(2);
|
|
380
|
-
}
|
|
381
|
-
const status = spawnSync("bw", ["status", "--session", session], { encoding: "utf8" });
|
|
382
|
-
if (status.status !== 0) {
|
|
383
|
-
console.error(`bw status failed: ${status.stderr || status.stdout}`);
|
|
384
|
-
process.exit(2);
|
|
385
|
-
}
|
|
386
|
-
let parsed;
|
|
387
|
-
try {
|
|
388
|
-
parsed = JSON.parse(status.stdout);
|
|
389
|
-
}
|
|
390
|
-
catch {
|
|
391
|
-
parsed = {};
|
|
392
|
-
}
|
|
393
|
-
if (parsed.status !== "unlocked") {
|
|
394
|
-
console.error(`Bitwarden vault is not unlocked (status: ${parsed.status ?? "unknown"}).`);
|
|
395
|
-
console.error("Run: export BW_SESSION=$(bw unlock --raw)");
|
|
396
|
-
process.exit(2);
|
|
397
|
-
}
|
|
398
|
-
const requested = opts.providers && opts.providers.length > 0 ? opts.providers : KEYCHAIN_PROVIDER_IDS.slice();
|
|
399
|
-
const prefix = opts.itemPrefix ?? "muonroi-cli/";
|
|
400
|
-
let imported = 0;
|
|
401
|
-
let skipped = 0;
|
|
402
|
-
for (const provider of requested) {
|
|
403
|
-
const norm = normalizeProvider(provider);
|
|
404
|
-
if (!norm) {
|
|
405
|
-
console.warn(`Skip unknown provider: ${provider}`);
|
|
406
|
-
skipped++;
|
|
407
|
-
continue;
|
|
408
|
-
}
|
|
409
|
-
const itemName = `${prefix}${provider}`;
|
|
410
|
-
const got = spawnSync("bw", ["get", "notes", itemName, "--session", session], { encoding: "utf8" });
|
|
411
|
-
if (got.status !== 0) {
|
|
412
|
-
// bw prints "Not found." on stderr when the item is missing — treat as skip.
|
|
413
|
-
skipped++;
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
416
|
-
const key = got.stdout.trim();
|
|
417
|
-
if (!key || key.length < 20) {
|
|
418
|
-
console.warn(`Skip ${provider}: vault item '${itemName}' empty or too short.`);
|
|
419
|
-
skipped++;
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
try {
|
|
423
|
-
const ok = await setKeyForProvider(norm, key);
|
|
424
|
-
if (!ok) {
|
|
425
|
-
console.warn(`! ${provider} — OS keychain unavailable (keytar or secret service backend).`);
|
|
426
|
-
console.warn(" Linux fix: sudo dnf install libsecret (Fedora) or sudo apt-get install libsecret-1-0 (Ubuntu)");
|
|
427
|
-
console.warn(` Fallback (works at runtime): export ${provider.toUpperCase()}_API_KEY=...`);
|
|
428
|
-
skipped++;
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
console.log(`Imported ${provider} → keychain.`);
|
|
432
|
-
imported++;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
catch (e) {
|
|
436
|
-
console.warn(`Failed ${provider}: ${e.message}`);
|
|
437
|
-
skipped++;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
console.log(`\nDone. Imported: ${imported}, skipped: ${skipped}.`);
|
|
441
|
-
if (imported > 0) {
|
|
442
|
-
console.log("Run 'muonroi-cli keys cleanup-settings' to strip any plaintext keys from settings.json.");
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Import MCP secrets (e.g. Tavily) from a Bitwarden vault into the OS
|
|
447
|
-
* keychain via mcp-keychain. Vault items are expected at `<prefix><id>` —
|
|
448
|
-
* default prefix `muonroi-cli/`. The key value is read from the item's
|
|
449
|
-
* notes field, mirroring the provider import-bw flow.
|
|
450
|
-
*/
|
|
451
|
-
export async function runMcpImportBw(opts = {}) {
|
|
452
|
-
const which = spawnSync("bw", ["--version"], { encoding: "utf8" });
|
|
453
|
-
if (which.status !== 0) {
|
|
454
|
-
console.error("Bitwarden CLI ('bw') not found in PATH.");
|
|
455
|
-
console.error("Install: https://bitwarden.com/help/cli/");
|
|
456
|
-
process.exit(2);
|
|
457
|
-
}
|
|
458
|
-
const session = process.env.BW_SESSION;
|
|
459
|
-
if (!session) {
|
|
460
|
-
console.error("BW_SESSION not set. Run:");
|
|
461
|
-
console.error(" export BW_SESSION=$(bw unlock --raw)");
|
|
462
|
-
process.exit(2);
|
|
463
|
-
}
|
|
464
|
-
const status = spawnSync("bw", ["status", "--session", session], { encoding: "utf8" });
|
|
465
|
-
if (status.status !== 0) {
|
|
466
|
-
console.error(`bw status failed: ${status.stderr || status.stdout}`);
|
|
467
|
-
process.exit(2);
|
|
468
|
-
}
|
|
469
|
-
let parsed;
|
|
470
|
-
try {
|
|
471
|
-
parsed = JSON.parse(status.stdout);
|
|
472
|
-
}
|
|
473
|
-
catch {
|
|
474
|
-
parsed = {};
|
|
475
|
-
}
|
|
476
|
-
if (parsed.status !== "unlocked") {
|
|
477
|
-
console.error(`Bitwarden vault is not unlocked (status: ${parsed.status ?? "unknown"}).`);
|
|
478
|
-
console.error("Run: export BW_SESSION=$(bw unlock --raw)");
|
|
479
|
-
process.exit(2);
|
|
480
|
-
}
|
|
481
|
-
const requested = opts.keys && opts.keys.length > 0 ? opts.keys : MCP_KEY_IDS.slice();
|
|
482
|
-
const prefix = opts.itemPrefix ?? "muonroi-cli/";
|
|
483
|
-
let imported = 0;
|
|
484
|
-
let skipped = 0;
|
|
485
|
-
for (const id of requested) {
|
|
486
|
-
if (!isMcpKeyId(id)) {
|
|
487
|
-
console.warn(`Skip unknown MCP key: ${id}`);
|
|
488
|
-
skipped++;
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
const itemName = `${prefix}${id}`;
|
|
492
|
-
const got = spawnSync("bw", ["get", "notes", itemName, "--session", session], { encoding: "utf8" });
|
|
493
|
-
if (got.status !== 0) {
|
|
494
|
-
skipped++;
|
|
495
|
-
continue;
|
|
496
|
-
}
|
|
497
|
-
const key = got.stdout.trim();
|
|
498
|
-
if (!key || key.length < 16) {
|
|
499
|
-
console.warn(`Skip ${id}: vault item '${itemName}' empty or too short.`);
|
|
500
|
-
skipped++;
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
try {
|
|
504
|
-
const ok = await setMcpKey(id, key);
|
|
505
|
-
if (!ok) {
|
|
506
|
-
console.warn(`! ${id} — OS keychain unavailable (keytar or secret service backend).`);
|
|
507
|
-
console.warn(" Linux fix: sudo dnf install libsecret (Fedora) or sudo apt-get install libsecret-1-0 (Ubuntu)");
|
|
508
|
-
console.warn(` Fallback (works at runtime): export ${id.toUpperCase()}_API_KEY=...`);
|
|
509
|
-
skipped++;
|
|
510
|
-
}
|
|
511
|
-
else {
|
|
512
|
-
console.log(`Imported MCP key '${id}' → keychain.`);
|
|
513
|
-
imported++;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
catch (e) {
|
|
517
|
-
console.warn(`Failed ${id}: ${e.message}`);
|
|
518
|
-
skipped++;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
console.log(`\nDone. Imported: ${imported}, skipped: ${skipped}.`);
|
|
522
|
-
}
|
|
523
336
|
export async function runChatKeySet(id, value) {
|
|
524
337
|
if (!value || value.length < 8) {
|
|
525
338
|
console.error(`Value for chat secret '${id}' is too short (< 8 chars).`);
|
|
@@ -540,85 +353,6 @@ export async function runChatKeySet(id, value) {
|
|
|
540
353
|
process.exit(1);
|
|
541
354
|
}
|
|
542
355
|
}
|
|
543
|
-
/**
|
|
544
|
-
* Import chat secrets (discord-token, discord-guild-id, slack-token, slack-team-id)
|
|
545
|
-
* from a Bitwarden vault into the OS keychain. Vault items are expected at
|
|
546
|
-
* `<prefix><id>` — default prefix `muonroi-cli/chat-`. The value is read from
|
|
547
|
-
* the item's notes field, mirroring the provider/MCP import-bw flow.
|
|
548
|
-
*/
|
|
549
|
-
export async function runChatImportBw(opts = {}) {
|
|
550
|
-
const which = spawnSync("bw", ["--version"], { encoding: "utf8" });
|
|
551
|
-
if (which.status !== 0) {
|
|
552
|
-
console.error("Bitwarden CLI ('bw') not found in PATH.");
|
|
553
|
-
console.error("Install: https://bitwarden.com/help/cli/");
|
|
554
|
-
process.exit(2);
|
|
555
|
-
}
|
|
556
|
-
const session = process.env.BW_SESSION;
|
|
557
|
-
if (!session) {
|
|
558
|
-
console.error("BW_SESSION not set. Run:");
|
|
559
|
-
console.error(" export BW_SESSION=$(bw unlock --raw)");
|
|
560
|
-
process.exit(2);
|
|
561
|
-
}
|
|
562
|
-
const status = spawnSync("bw", ["status", "--session", session], { encoding: "utf8" });
|
|
563
|
-
if (status.status !== 0) {
|
|
564
|
-
console.error(`bw status failed: ${status.stderr || status.stdout}`);
|
|
565
|
-
process.exit(2);
|
|
566
|
-
}
|
|
567
|
-
let parsed;
|
|
568
|
-
try {
|
|
569
|
-
parsed = JSON.parse(status.stdout);
|
|
570
|
-
}
|
|
571
|
-
catch {
|
|
572
|
-
parsed = {};
|
|
573
|
-
}
|
|
574
|
-
if (parsed.status !== "unlocked") {
|
|
575
|
-
console.error(`Bitwarden vault is not unlocked (status: ${parsed.status ?? "unknown"}).`);
|
|
576
|
-
console.error("Run: export BW_SESSION=$(bw unlock --raw)");
|
|
577
|
-
process.exit(2);
|
|
578
|
-
}
|
|
579
|
-
const requested = opts.ids && opts.ids.length > 0 ? opts.ids : CHAT_SECRET_IDS.slice();
|
|
580
|
-
const prefix = opts.itemPrefix ?? "muonroi-cli/chat-";
|
|
581
|
-
let imported = 0;
|
|
582
|
-
let skipped = 0;
|
|
583
|
-
for (const id of requested) {
|
|
584
|
-
if (!isChatSecretId(id)) {
|
|
585
|
-
console.warn(`Skip unknown chat secret: ${id}`);
|
|
586
|
-
skipped++;
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
589
|
-
const itemName = `${prefix}${id}`;
|
|
590
|
-
const got = spawnSync("bw", ["get", "notes", itemName, "--session", session], { encoding: "utf8" });
|
|
591
|
-
if (got.status !== 0) {
|
|
592
|
-
// bw prints "Not found." on stderr when the item is missing — treat as skip.
|
|
593
|
-
skipped++;
|
|
594
|
-
continue;
|
|
595
|
-
}
|
|
596
|
-
const value = got.stdout.trim();
|
|
597
|
-
if (!value || value.length < 8) {
|
|
598
|
-
console.warn(`Skip ${id}: vault item '${itemName}' empty or too short.`);
|
|
599
|
-
skipped++;
|
|
600
|
-
continue;
|
|
601
|
-
}
|
|
602
|
-
try {
|
|
603
|
-
const ok = await setChatSecret(id, value);
|
|
604
|
-
if (!ok) {
|
|
605
|
-
console.warn(`! ${id} — OS keychain unavailable (keytar or secret service backend).`);
|
|
606
|
-
console.warn(" Linux fix: sudo dnf install libsecret (Fedora) or sudo apt-get install libsecret-1-0 (Ubuntu)");
|
|
607
|
-
console.warn(` Fallback (works at runtime): export ${id.includes("token") ? "MUONROI_" : "MUONROI_"}${id.replace("-", "_").toUpperCase()}=...`);
|
|
608
|
-
skipped++;
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
console.log(`Imported chat secret '${id}' → keychain.`);
|
|
612
|
-
imported++;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
catch (e) {
|
|
616
|
-
console.warn(`Failed ${id}: ${e.message}`);
|
|
617
|
-
skipped++;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
console.log(`\nDone. Imported: ${imported}, skipped: ${skipped}.`);
|
|
621
|
-
}
|
|
622
356
|
// ---------------------------------------------------------------------------
|
|
623
357
|
// OAuth login / logout
|
|
624
358
|
// ---------------------------------------------------------------------------
|
|
@@ -667,6 +401,16 @@ export async function runKeysLogin(provider) {
|
|
|
667
401
|
},
|
|
668
402
|
});
|
|
669
403
|
await saveTokens(norm, tokens);
|
|
404
|
+
// One auth mode per provider (OAuth XOR API key): logging in via OAuth clears
|
|
405
|
+
// any stored API key for this provider so a stale key can never shadow OAuth.
|
|
406
|
+
try {
|
|
407
|
+
const { clearEnvVar } = await import("../providers/env-store.js");
|
|
408
|
+
const { ENV_BY_PROVIDER } = await import("../providers/keychain.js");
|
|
409
|
+
clearEnvVar(ENV_BY_PROVIDER[norm]);
|
|
410
|
+
}
|
|
411
|
+
catch (err) {
|
|
412
|
+
console.error(`[keys] failed to clear API key after OAuth login for ${norm}: ${err instanceof Error ? err.message : String(err)}`);
|
|
413
|
+
}
|
|
670
414
|
const emailDisplay = tokens.email ? ` (${tokens.email})` : "";
|
|
671
415
|
const expiry = new Date(tokens.expiresAt).toLocaleString();
|
|
672
416
|
console.log(`\nLogged in to ${name}${emailDisplay}. Token expires: ${expiry}`);
|
|
@@ -701,54 +445,4 @@ export async function runKeysLogout(provider) {
|
|
|
701
445
|
const name = cfg?.displayName ?? provider;
|
|
702
446
|
console.log(`Logged out of ${name}. OAuth tokens revoked and deleted.`);
|
|
703
447
|
}
|
|
704
|
-
export async function runKeysCleanupSettings() {
|
|
705
|
-
let raw;
|
|
706
|
-
try {
|
|
707
|
-
raw = await fs.readFile(getSettingsPath(), "utf8");
|
|
708
|
-
}
|
|
709
|
-
catch (e) {
|
|
710
|
-
if (e.code === "ENOENT") {
|
|
711
|
-
console.log("No user-settings.json found — nothing to clean.");
|
|
712
|
-
return;
|
|
713
|
-
}
|
|
714
|
-
throw e;
|
|
715
|
-
}
|
|
716
|
-
let json;
|
|
717
|
-
try {
|
|
718
|
-
json = JSON.parse(raw);
|
|
719
|
-
}
|
|
720
|
-
catch {
|
|
721
|
-
console.error(`Settings file is not valid JSON: ${getSettingsPath()}`);
|
|
722
|
-
process.exit(1);
|
|
723
|
-
}
|
|
724
|
-
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
725
|
-
const backup = `${getSettingsPath()}.bak.${ts}`;
|
|
726
|
-
await fs.writeFile(backup, raw, "utf8");
|
|
727
|
-
let removed = 0;
|
|
728
|
-
if ("apiKey" in json) {
|
|
729
|
-
delete json.apiKey;
|
|
730
|
-
removed++;
|
|
731
|
-
}
|
|
732
|
-
if (json.providers && typeof json.providers === "object") {
|
|
733
|
-
const providers = json.providers;
|
|
734
|
-
for (const [name, block] of Object.entries(providers)) {
|
|
735
|
-
if (block && "apiKey" in block) {
|
|
736
|
-
delete block.apiKey;
|
|
737
|
-
removed++;
|
|
738
|
-
if (Object.keys(block).length === 0) {
|
|
739
|
-
delete providers[name];
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
if (Object.keys(providers).length === 0) {
|
|
744
|
-
delete json.providers;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
await fs.writeFile(getSettingsPath(), `${JSON.stringify(json, null, 2)}\n`, "utf8");
|
|
748
|
-
console.log(`Backed up to: ${backup}`);
|
|
749
|
-
console.log(`Removed ${removed} plaintext key field(s) from: ${getSettingsPath()}`);
|
|
750
|
-
if (removed === 0) {
|
|
751
|
-
console.log("(File was already clean.)");
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
448
|
//# sourceMappingURL=keys.js.map
|
|
@@ -46,6 +46,7 @@ export declare function judgeReadiness(spec: ClarifiedSpec, topic: string, qa: A
|
|
|
46
46
|
confidence: number;
|
|
47
47
|
gaps: string[];
|
|
48
48
|
}>;
|
|
49
|
+
export declare function resolveInterviewLanguage(topic: string): string;
|
|
49
50
|
export interface ClarifyOptionsResult {
|
|
50
51
|
options: CouncilQuestionOption[];
|
|
51
52
|
/**
|
|
@@ -68,7 +69,7 @@ export interface ClarifyOptionsResult {
|
|
|
68
69
|
* returned `defaultIndex` points to it. Otherwise `defaultIndex` is omitted
|
|
69
70
|
* so the UI knows to suppress the "(Recommended)" tag.
|
|
70
71
|
*/
|
|
71
|
-
export declare function buildClarifyOptions(suggestions: string[] | undefined, recommended?: string): ClarifyOptionsResult;
|
|
72
|
+
export declare function buildClarifyOptions(suggestions: string[] | undefined, recommended?: string, lang?: string): ClarifyOptionsResult;
|
|
72
73
|
/**
|
|
73
74
|
* Model-designed option object: a choice the user picks between, carrying its
|
|
74
75
|
* own explanation. `recommended:true` marks the pre-selected default. This is
|
|
@@ -88,7 +89,8 @@ export interface ClarifyOptionSpec {
|
|
|
88
89
|
* "Chat about this" escape-hatches are appended as in `buildClarifyOptions`.
|
|
89
90
|
* Pure + exported for unit testing.
|
|
90
91
|
*/
|
|
91
|
-
export declare function buildClarifyOptionsRich(specs: ClarifyOptionSpec[] | undefined): ClarifyOptionsResult;
|
|
92
|
+
export declare function buildClarifyOptionsRich(specs: ClarifyOptionSpec[] | undefined, lang?: string): ClarifyOptionsResult;
|
|
93
|
+
export declare function researchScopeForClarification(topic: string, conversationContext: string, leaderModelId: string, llm: CouncilLLM, signal: AbortSignal | undefined, reachableModels: string[]): AsyncGenerator<StreamChunk, string, unknown>;
|
|
92
94
|
export declare function runClarification(topic: string, leaderModelId: string, conversationContext: string, respondToQuestion: QuestionResponder, llm: CouncilLLM, signal?: AbortSignal, seedQuestions?: GrayAreaQuestion[], maxRounds?: number,
|
|
93
95
|
/**
|
|
94
96
|
* Optional pre-filled answers keyed by seed-question id. When the loop's
|