gnosys 5.9.3 → 5.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +34 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/dream.d.ts.map +1 -1
- package/dist/lib/dream.js +14 -3
- package/dist/lib/dream.js.map +1 -1
- package/dist/lib/ingest.js +1 -1
- package/dist/lib/ingest.js.map +1 -1
- package/dist/lib/remote.d.ts +16 -0
- package/dist/lib/remote.d.ts.map +1 -1
- package/dist/lib/remote.js +47 -6
- package/dist/lib/remote.js.map +1 -1
- package/dist/lib/setup/dreamState.d.ts +50 -0
- package/dist/lib/setup/dreamState.d.ts.map +1 -0
- package/dist/lib/setup/dreamState.js +68 -0
- package/dist/lib/setup/dreamState.js.map +1 -0
- package/dist/lib/setup/routingRender.d.ts +4 -0
- package/dist/lib/setup/routingRender.d.ts.map +1 -1
- package/dist/lib/setup/routingRender.js +40 -23
- package/dist/lib/setup/routingRender.js.map +1 -1
- package/dist/lib/setup/sections/ides.d.ts.map +1 -1
- package/dist/lib/setup/sections/ides.js +56 -23
- package/dist/lib/setup/sections/ides.js.map +1 -1
- package/dist/lib/setup/sections/preferences.d.ts.map +1 -1
- package/dist/lib/setup/sections/preferences.js +25 -12
- package/dist/lib/setup/sections/preferences.js.map +1 -1
- package/dist/lib/setup/sections/routing.d.ts.map +1 -1
- package/dist/lib/setup/sections/routing.js +31 -9
- package/dist/lib/setup/sections/routing.js.map +1 -1
- package/dist/lib/setup/storePath.d.ts +30 -0
- package/dist/lib/setup/storePath.d.ts.map +1 -0
- package/dist/lib/setup/storePath.js +47 -0
- package/dist/lib/setup/storePath.js.map +1 -0
- package/dist/lib/setup/summary.d.ts +1 -1
- package/dist/lib/setup/summary.d.ts.map +1 -1
- package/dist/lib/setup/summary.js +27 -22
- package/dist/lib/setup/summary.js.map +1 -1
- package/dist/lib/setup/syncProjectsRender.d.ts +2 -1
- package/dist/lib/setup/syncProjectsRender.d.ts.map +1 -1
- package/dist/lib/setup/syncProjectsRender.js +54 -38
- package/dist/lib/setup/syncProjectsRender.js.map +1 -1
- package/dist/lib/setup/ui/index.d.ts +2 -0
- package/dist/lib/setup/ui/index.d.ts.map +1 -1
- package/dist/lib/setup/ui/index.js +1 -0
- package/dist/lib/setup/ui/index.js.map +1 -1
- package/dist/lib/setup/ui/panel.d.ts.map +1 -1
- package/dist/lib/setup/ui/panel.js +10 -3
- package/dist/lib/setup/ui/panel.js.map +1 -1
- package/dist/lib/setup/ui/table.d.ts +37 -0
- package/dist/lib/setup/ui/table.d.ts.map +1 -0
- package/dist/lib/setup/ui/table.js +82 -0
- package/dist/lib/setup/ui/table.js.map +1 -0
- package/dist/lib/setup.d.ts +31 -0
- package/dist/lib/setup.d.ts.map +1 -1
- package/dist/lib/setup.js +237 -79
- package/dist/lib/setup.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table atom — generic tabular layout for the v5.9.4 CLI vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Per `arch-004`: every tabular CLI screen reaches for `Table` first instead
|
|
5
|
+
* of hand-rolling `padEnd` columns. Header row + thin divider + auto-fit
|
|
6
|
+
* or fixed-width columns + optional per-row marker formatter (e.g. `▶` for
|
|
7
|
+
* changed routing rows).
|
|
8
|
+
*
|
|
9
|
+
* The renderer measures printable width with ANSI stripped so coloured
|
|
10
|
+
* cell contents don't break alignment. Cell `render(row)` returns the
|
|
11
|
+
* RAW string; `color` is applied per-column for the cell value (header
|
|
12
|
+
* is always `text-dim` per design §4).
|
|
13
|
+
*/
|
|
14
|
+
import { c, color, glyph } from "./tokens.js";
|
|
15
|
+
import { stripAnsi } from "./header.js";
|
|
16
|
+
/**
|
|
17
|
+
* Render a table. Returns one string per line (header + divider + rows),
|
|
18
|
+
* never trailing newline. Returns `[]` for an empty `rows` array unless
|
|
19
|
+
* `showHeader` is true (in which case header + divider are still emitted).
|
|
20
|
+
*/
|
|
21
|
+
export function renderTable(rows, columns, opts = {}) {
|
|
22
|
+
if (columns.length === 0)
|
|
23
|
+
return [];
|
|
24
|
+
const showHeader = opts.showHeader !== false;
|
|
25
|
+
const drawDivider = opts.dividerAfterHeader !== false;
|
|
26
|
+
const indent = " ".repeat(opts.indent ?? 1);
|
|
27
|
+
const gap = " ".repeat(opts.gap ?? 2);
|
|
28
|
+
// Pre-compute raw cell values + per-column widths.
|
|
29
|
+
const rawCells = rows.map((row) => columns.map((col) => col.render(row)));
|
|
30
|
+
const widths = columns.map((col, idx) => {
|
|
31
|
+
if (typeof col.width === "number")
|
|
32
|
+
return col.width;
|
|
33
|
+
const headerLen = col.header.length;
|
|
34
|
+
const maxCell = rawCells.reduce((max, cells) => {
|
|
35
|
+
const len = stripAnsi(cells[idx] ?? "").length;
|
|
36
|
+
return len > max ? len : max;
|
|
37
|
+
}, 0);
|
|
38
|
+
return Math.max(headerLen, maxCell);
|
|
39
|
+
});
|
|
40
|
+
const lines = [];
|
|
41
|
+
if (showHeader) {
|
|
42
|
+
const headerCells = columns.map((col, idx) => color(c.textDim, padCell(col.header, widths[idx], col.align ?? "left")));
|
|
43
|
+
lines.push(`${indent}${headerCells.join(gap)}`);
|
|
44
|
+
if (drawDivider) {
|
|
45
|
+
const ruleWidth = widths.reduce((sum, w) => sum + w, 0) + gap.length * (columns.length - 1);
|
|
46
|
+
lines.push(`${indent}${color(c.textGhost, glyph.ruleLight.repeat(Math.max(1, ruleWidth)))}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
rows.forEach((row, rowIdx) => {
|
|
50
|
+
const cells = columns.map((col, colIdx) => {
|
|
51
|
+
const raw = rawCells[rowIdx][colIdx];
|
|
52
|
+
// Last left-aligned column doesn't need trailing pad — saves a row of
|
|
53
|
+
// ghost whitespace per snapshot and matches the v5.9.3 hand-rolled output.
|
|
54
|
+
const isLastCol = colIdx === columns.length - 1;
|
|
55
|
+
const align = col.align ?? "left";
|
|
56
|
+
const padded = isLastCol && align === "left"
|
|
57
|
+
? raw
|
|
58
|
+
: padCell(raw, widths[colIdx], align);
|
|
59
|
+
// Empty string opts out of column-level colouring — useful when the
|
|
60
|
+
// cell's `render()` already emits its own ANSI (e.g. cost tiers).
|
|
61
|
+
const cellColor = col.color === "" ? null : col.color ?? c.text;
|
|
62
|
+
return cellColor ? color(cellColor, padded) : padded;
|
|
63
|
+
});
|
|
64
|
+
const line = `${indent}${cells.join(gap)}`;
|
|
65
|
+
lines.push(opts.rowFormatter ? opts.rowFormatter(row, line) : line);
|
|
66
|
+
});
|
|
67
|
+
return lines;
|
|
68
|
+
}
|
|
69
|
+
/** Convenience: render + print + trailing newline. */
|
|
70
|
+
export function printTable(rows, columns, opts = {}) {
|
|
71
|
+
const lines = renderTable(rows, columns, opts);
|
|
72
|
+
if (lines.length > 0)
|
|
73
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
74
|
+
}
|
|
75
|
+
/** Pad a cell value (which may contain ANSI) to a target printable width. */
|
|
76
|
+
function padCell(value, width, align) {
|
|
77
|
+
const bareLen = stripAnsi(value).length;
|
|
78
|
+
const padLen = Math.max(0, width - bareLen);
|
|
79
|
+
const pad = " ".repeat(padLen);
|
|
80
|
+
return align === "right" ? `${pad}${value}` : `${value}${pad}`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../../../../src/lib/setup/ui/table.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/setup.d.ts
CHANGED
|
@@ -70,6 +70,23 @@ export declare function writeApiKeyToKeychain(envVar: string, key: string): bool
|
|
|
70
70
|
* Returns an array like ["claude", "cursor", "codex"].
|
|
71
71
|
*/
|
|
72
72
|
export declare function detectIDEs(projectDir: string): Promise<string[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Replace (or append) a `[mcp.<name>]` block inside the TOML text for
|
|
75
|
+
* Grok Build's config file. Preserves every line outside that block —
|
|
76
|
+
* deci-046 read-then-merge rule. We can't pull in a TOML dependency
|
|
77
|
+
* without adding to package.json, so we ship a minimal hand-rolled
|
|
78
|
+
* updater scoped exactly to the `[mcp.gnosys]` use case.
|
|
79
|
+
*
|
|
80
|
+
* Spec assumption: TOML headers we touch are simple `[a.b]` lines with
|
|
81
|
+
* no inline tables or nested arrays. Any other content is left alone.
|
|
82
|
+
*
|
|
83
|
+
* Exported for tests.
|
|
84
|
+
*/
|
|
85
|
+
export declare function upsertGrokMcpBlock(existing: string, name: string, entry: {
|
|
86
|
+
command: string;
|
|
87
|
+
args: string[];
|
|
88
|
+
startup_timeout_sec?: number;
|
|
89
|
+
}): string;
|
|
73
90
|
/**
|
|
74
91
|
* Set up Gnosys MCP integration for a specific IDE.
|
|
75
92
|
*/
|
|
@@ -81,6 +98,20 @@ export declare function runSetup(opts: {
|
|
|
81
98
|
directory?: string;
|
|
82
99
|
nonInteractive?: boolean;
|
|
83
100
|
}): Promise<SetupResult>;
|
|
101
|
+
export interface ProviderOnlySetupOpts {
|
|
102
|
+
directory?: string;
|
|
103
|
+
rl?: ReadlineInterface;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Update ONLY `llm.defaultProvider` in gnosys.json. Used by the summary
|
|
107
|
+
* panel row 1 ("provider") so it stops dragging the user into the full
|
|
108
|
+
* model picker — that's row 2's job.
|
|
109
|
+
*
|
|
110
|
+
* v5.9.4 Bug 4 — before this split, both summary rows routed through
|
|
111
|
+
* `runModelsSetup`, leaving no way to swap provider without also choosing
|
|
112
|
+
* a new model. Now row 1 picks a provider, row 2 picks a model.
|
|
113
|
+
*/
|
|
114
|
+
export declare function runProviderOnlySetup(opts?: ProviderOnlySetupOpts): Promise<void>;
|
|
84
115
|
export interface ModelsSetupOpts {
|
|
85
116
|
provider?: string;
|
|
86
117
|
model?: string;
|
package/dist/lib/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAmB,SAAS,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAkDpF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE;QACd,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,SAAS,CAAC,EAAE,WAAW,CAAC;QACxB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,aAAa,CAAC,EAAE,WAAW,CAAC;QAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;KACrB,CAAC;IACF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAID,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAkCtD,CAAC;AA0BF;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/setup.js
CHANGED
|
@@ -16,7 +16,7 @@ import os from "os";
|
|
|
16
16
|
import { execSync } from "child_process";
|
|
17
17
|
import { loadConfig, updateConfig, getProviderModel, } from "./config.js";
|
|
18
18
|
import { validateModel } from "./modelValidation.js";
|
|
19
|
-
import {
|
|
19
|
+
import { resolveActiveStorePath, ensureActiveStorePath } from "./setup/storePath.js";
|
|
20
20
|
import { safeQuestion } from "./setup/ui/safePrompt.js";
|
|
21
21
|
// ─── ANSI Colors ────────────────────────────────────────────────────────────
|
|
22
22
|
const BOLD = "\x1b[1m";
|
|
@@ -139,6 +139,12 @@ export async function fetchDynamicModels() {
|
|
|
139
139
|
})
|
|
140
140
|
.filter((m) => m.input > 0 && !m.isFree && !m.isVariant && !m.isGuard)
|
|
141
141
|
.filter((m) => !/audio|search|embed|tts|vision|image|code-/i.test(m.modelId)) // skip specialized models
|
|
142
|
+
// v5.9.4 Bug 3 — xAI: OpenRouter returns weird names like
|
|
143
|
+
// `grok-build-0.1` and `grok-4.20-multi-agent`. Keep only canonical
|
|
144
|
+
// numbered Grok flagship/preview models (e.g. `grok-3`, `grok-4.0`,
|
|
145
|
+
// `grok-4.3`). When nothing matches we fall through to the static
|
|
146
|
+
// tiers a few lines down.
|
|
147
|
+
.filter((m) => ourProvider !== "xai" || /^grok-[0-9]/.test(m.modelId))
|
|
142
148
|
.sort((a, b) => b.created - a.created); // newest first
|
|
143
149
|
if (models.length === 0)
|
|
144
150
|
continue;
|
|
@@ -227,6 +233,19 @@ export async function fetchDynamicModels() {
|
|
|
227
233
|
if (!tiers.some((t) => t.recommended) && tiers.length > 0) {
|
|
228
234
|
tiers[0].recommended = true;
|
|
229
235
|
}
|
|
236
|
+
// v5.9.4 Bug 3 — UNION OpenRouter tiers with static PROVIDER_TIERS.xai
|
|
237
|
+
// so the static catalog (e.g. grok-4.3) always shows up even when
|
|
238
|
+
// OpenRouter omits it. Dedup by model id; static entries win the tie
|
|
239
|
+
// (their pricing matches the launch price more reliably).
|
|
240
|
+
if (ourProvider === "xai") {
|
|
241
|
+
const seen = new Set(tiers.map((t) => t.model));
|
|
242
|
+
for (const staticTier of PROVIDER_TIERS.xai ?? []) {
|
|
243
|
+
if (!seen.has(staticTier.model)) {
|
|
244
|
+
tiers.push(staticTier);
|
|
245
|
+
seen.add(staticTier.model);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
230
249
|
result[ourProvider] = tiers;
|
|
231
250
|
}
|
|
232
251
|
// Cache the result
|
|
@@ -533,6 +552,16 @@ export async function detectIDEs(projectDir) {
|
|
|
533
552
|
// Not installed
|
|
534
553
|
}
|
|
535
554
|
}
|
|
555
|
+
// v5.9.4 Bug 12 — Grok Build (xAI's coding agent) stores MCP config at
|
|
556
|
+
// ~/.grok/config.toml. The directory's presence is the detection signal.
|
|
557
|
+
try {
|
|
558
|
+
const stat = await fs.stat(path.join(home, ".grok"));
|
|
559
|
+
if (stat.isDirectory())
|
|
560
|
+
detected.push("grok-build");
|
|
561
|
+
}
|
|
562
|
+
catch {
|
|
563
|
+
// Not installed
|
|
564
|
+
}
|
|
536
565
|
return detected;
|
|
537
566
|
}
|
|
538
567
|
/**
|
|
@@ -552,6 +581,68 @@ function claudeDesktopConfigPath() {
|
|
|
552
581
|
}
|
|
553
582
|
return path.join(home, ".config", "Claude", "claude_desktop_config.json");
|
|
554
583
|
}
|
|
584
|
+
/**
|
|
585
|
+
* Replace (or append) a `[mcp.<name>]` block inside the TOML text for
|
|
586
|
+
* Grok Build's config file. Preserves every line outside that block —
|
|
587
|
+
* deci-046 read-then-merge rule. We can't pull in a TOML dependency
|
|
588
|
+
* without adding to package.json, so we ship a minimal hand-rolled
|
|
589
|
+
* updater scoped exactly to the `[mcp.gnosys]` use case.
|
|
590
|
+
*
|
|
591
|
+
* Spec assumption: TOML headers we touch are simple `[a.b]` lines with
|
|
592
|
+
* no inline tables or nested arrays. Any other content is left alone.
|
|
593
|
+
*
|
|
594
|
+
* Exported for tests.
|
|
595
|
+
*/
|
|
596
|
+
export function upsertGrokMcpBlock(existing, name, entry) {
|
|
597
|
+
const sectionHeader = `[mcp.${name}]`;
|
|
598
|
+
const lines = existing.split("\n");
|
|
599
|
+
const headerIdx = lines.findIndex((line) => line.trim() === sectionHeader);
|
|
600
|
+
const blockBody = renderGrokMcpBlock(entry);
|
|
601
|
+
if (headerIdx === -1) {
|
|
602
|
+
// Append a fresh block, separated by a blank line if the file has content.
|
|
603
|
+
const prefix = existing.length === 0 || existing.endsWith("\n\n")
|
|
604
|
+
? existing
|
|
605
|
+
: existing.endsWith("\n") ? `${existing}\n` : `${existing}\n\n`;
|
|
606
|
+
return `${prefix}${sectionHeader}\n${blockBody}`;
|
|
607
|
+
}
|
|
608
|
+
// Replace the existing block — everything from sectionHeader up to the
|
|
609
|
+
// next `[` header (or EOF). Count blank lines immediately after the block
|
|
610
|
+
// so we can preserve the original spacing before the next section.
|
|
611
|
+
let endIdx = lines.length;
|
|
612
|
+
for (let i = headerIdx + 1; i < lines.length; i++) {
|
|
613
|
+
if (/^\s*\[/.test(lines[i])) {
|
|
614
|
+
endIdx = i;
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
let trailingBlankBeforeNext = 0;
|
|
619
|
+
while (endIdx > headerIdx + 1 && lines[endIdx - 1].trim() === "") {
|
|
620
|
+
trailingBlankBeforeNext++;
|
|
621
|
+
endIdx--;
|
|
622
|
+
}
|
|
623
|
+
const afterLines = lines.slice(endIdx);
|
|
624
|
+
const hasFollowingSection = afterLines.some((l) => /^\s*\[/.test(l));
|
|
625
|
+
const beforeBlock = lines.slice(0, headerIdx).join("\n");
|
|
626
|
+
const head = beforeBlock.length > 0 ? `${beforeBlock}\n` : "";
|
|
627
|
+
if (!hasFollowingSection) {
|
|
628
|
+
// No following section — drop trailing blank lines and end with a single \n.
|
|
629
|
+
return `${head}${sectionHeader}\n${blockBody}`;
|
|
630
|
+
}
|
|
631
|
+
const gap = "\n".repeat(Math.max(1, trailingBlankBeforeNext));
|
|
632
|
+
const afterBlock = afterLines.join("\n");
|
|
633
|
+
return `${head}${sectionHeader}\n${blockBody}${gap}${afterBlock}`;
|
|
634
|
+
}
|
|
635
|
+
function renderGrokMcpBlock(entry) {
|
|
636
|
+
const argsStr = `[${entry.args.map((a) => JSON.stringify(a)).join(", ")}]`;
|
|
637
|
+
const lines = [
|
|
638
|
+
`command = ${JSON.stringify(entry.command)}`,
|
|
639
|
+
`args = ${argsStr}`,
|
|
640
|
+
];
|
|
641
|
+
if (typeof entry.startup_timeout_sec === "number") {
|
|
642
|
+
lines.push(`startup_timeout_sec = ${entry.startup_timeout_sec}`);
|
|
643
|
+
}
|
|
644
|
+
return `${lines.join("\n")}\n`;
|
|
645
|
+
}
|
|
555
646
|
/**
|
|
556
647
|
* Set up Gnosys MCP integration for a specific IDE.
|
|
557
648
|
*/
|
|
@@ -717,6 +808,29 @@ export async function setupIDE(ide, projectDir) {
|
|
|
717
808
|
await fs.writeFile(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
718
809
|
return { success: true, message: "Antigravity MCP config updated (~/.gemini/antigravity/mcp_config.json)" };
|
|
719
810
|
}
|
|
811
|
+
case "grok-build": {
|
|
812
|
+
// v5.9.4 Bug 12 — Grok Build reads its MCP servers from a
|
|
813
|
+
// `[mcp.<name>]` block in ~/.grok/config.toml. We never clobber
|
|
814
|
+
// unrelated TOML content (per deci-046 read-then-merge rule); the
|
|
815
|
+
// helper preserves every line outside the `[mcp.gnosys]` block.
|
|
816
|
+
const grokDir = path.join(os.homedir(), ".grok");
|
|
817
|
+
const configPath = path.join(grokDir, "config.toml");
|
|
818
|
+
await fs.mkdir(grokDir, { recursive: true });
|
|
819
|
+
let existing = "";
|
|
820
|
+
try {
|
|
821
|
+
existing = await fs.readFile(configPath, "utf-8");
|
|
822
|
+
}
|
|
823
|
+
catch {
|
|
824
|
+
// File doesn't exist yet — start fresh
|
|
825
|
+
}
|
|
826
|
+
const updated = upsertGrokMcpBlock(existing, "gnosys", {
|
|
827
|
+
command: "gnosys",
|
|
828
|
+
args: ["serve"],
|
|
829
|
+
startup_timeout_sec: 90,
|
|
830
|
+
});
|
|
831
|
+
await fs.writeFile(configPath, updated, "utf-8");
|
|
832
|
+
return { success: true, message: "Grok Build MCP config updated (~/.grok/config.toml)" };
|
|
833
|
+
}
|
|
720
834
|
case "claude-desktop": {
|
|
721
835
|
// Claude Desktop reads MCP servers from claude_desktop_config.json
|
|
722
836
|
// in a platform-specific app data directory. Distinct from Claude
|
|
@@ -867,31 +981,21 @@ async function getRegisteredProjects() {
|
|
|
867
981
|
}
|
|
868
982
|
/**
|
|
869
983
|
* Try to load existing gnosys.json config for displaying current values.
|
|
870
|
-
*
|
|
871
|
-
*
|
|
984
|
+
* Resolves the active store via the shared `resolveActiveStorePath` helper
|
|
985
|
+
* (v5.9.4 Bug 10 — was reading from a different store than the summary
|
|
986
|
+
* panel, producing stale-display bugs in `gnosys setup models`).
|
|
987
|
+
* Returns null if no config exists in either project or global stores.
|
|
872
988
|
*/
|
|
873
989
|
async function loadExistingConfig(projectDir) {
|
|
874
|
-
|
|
875
|
-
try {
|
|
876
|
-
const projectStore = path.join(projectDir, ".gnosys");
|
|
877
|
-
const stat = await fs.stat(path.join(projectStore, "gnosys.json"));
|
|
878
|
-
if (stat.isFile()) {
|
|
879
|
-
return await loadConfig(projectStore);
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
catch {
|
|
883
|
-
// No project config
|
|
884
|
-
}
|
|
885
|
-
// Try global config at ~/.gnosys
|
|
990
|
+
const storePath = resolveActiveStorePath(projectDir);
|
|
886
991
|
try {
|
|
887
|
-
const
|
|
888
|
-
const stat = await fs.stat(path.join(globalStore, "gnosys.json"));
|
|
992
|
+
const stat = await fs.stat(path.join(storePath, "gnosys.json"));
|
|
889
993
|
if (stat.isFile()) {
|
|
890
|
-
return await loadConfig(
|
|
994
|
+
return await loadConfig(storePath);
|
|
891
995
|
}
|
|
892
996
|
}
|
|
893
997
|
catch {
|
|
894
|
-
// No
|
|
998
|
+
// No config in the resolved store
|
|
895
999
|
}
|
|
896
1000
|
return null;
|
|
897
1001
|
}
|
|
@@ -1508,12 +1612,14 @@ export async function runSetup(opts) {
|
|
|
1508
1612
|
codex: "Codex",
|
|
1509
1613
|
"gemini-cli": "Gemini CLI",
|
|
1510
1614
|
antigravity: "Antigravity",
|
|
1615
|
+
// v5.9.4 Bug 12 — Grok Build (~/.grok/config.toml).
|
|
1616
|
+
"grok-build": "Grok Build",
|
|
1511
1617
|
};
|
|
1512
1618
|
// IDEs whose MCP config lives at the user level (~/...) rather than per-project.
|
|
1513
1619
|
// We don't try to create a project-level directory for these.
|
|
1514
|
-
const userLevelIdes = new Set(["claude", "claude-desktop", "gemini-cli", "antigravity"]);
|
|
1620
|
+
const userLevelIdes = new Set(["claude", "claude-desktop", "gemini-cli", "antigravity", "grok-build"]);
|
|
1515
1621
|
// Build IDE options: show detected ones and offer to create missing ones
|
|
1516
|
-
const allIdeKeys = ["claude", "claude-desktop", "cursor", "codex", "gemini-cli", "antigravity"];
|
|
1622
|
+
const allIdeKeys = ["claude", "claude-desktop", "cursor", "codex", "gemini-cli", "antigravity", "grok-build"];
|
|
1517
1623
|
const ideOptions = [];
|
|
1518
1624
|
const ideKeyForOption = []; // parallel array mapping option index to IDE key
|
|
1519
1625
|
for (const ide of allIdeKeys) {
|
|
@@ -1595,21 +1701,8 @@ export async function runSetup(opts) {
|
|
|
1595
1701
|
const structuringModel = isSkip ? "" : (taskOverrides.structuring?.model ?? getStructuringModel(provider, model));
|
|
1596
1702
|
// ─── Write config to gnosys.json ─────────────────────────────────
|
|
1597
1703
|
if (!isSkip) {
|
|
1598
|
-
//
|
|
1599
|
-
|
|
1600
|
-
const projectStore = path.join(projectDir, ".gnosys");
|
|
1601
|
-
const globalStore = getGnosysHome();
|
|
1602
|
-
if (fsSync.existsSync(path.join(projectStore, "gnosys.json"))) {
|
|
1603
|
-
storePath = projectStore;
|
|
1604
|
-
}
|
|
1605
|
-
else if (fsSync.existsSync(path.join(globalStore, "gnosys.json"))) {
|
|
1606
|
-
storePath = globalStore;
|
|
1607
|
-
}
|
|
1608
|
-
else {
|
|
1609
|
-
// Default to global store — create directory if needed
|
|
1610
|
-
await fs.mkdir(globalStore, { recursive: true });
|
|
1611
|
-
storePath = globalStore;
|
|
1612
|
-
}
|
|
1704
|
+
// v5.9.4 Bug 10 — unified store resolution.
|
|
1705
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
1613
1706
|
// Build the config updates
|
|
1614
1707
|
// Build LLM config update, preserving existing provider-specific settings
|
|
1615
1708
|
const existingLlm = existingConfig?.llm;
|
|
@@ -1772,6 +1865,60 @@ export async function runSetup(opts) {
|
|
|
1772
1865
|
throw err;
|
|
1773
1866
|
}
|
|
1774
1867
|
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Update ONLY `llm.defaultProvider` in gnosys.json. Used by the summary
|
|
1870
|
+
* panel row 1 ("provider") so it stops dragging the user into the full
|
|
1871
|
+
* model picker — that's row 2's job.
|
|
1872
|
+
*
|
|
1873
|
+
* v5.9.4 Bug 4 — before this split, both summary rows routed through
|
|
1874
|
+
* `runModelsSetup`, leaving no way to swap provider without also choosing
|
|
1875
|
+
* a new model. Now row 1 picks a provider, row 2 picks a model.
|
|
1876
|
+
*/
|
|
1877
|
+
export async function runProviderOnlySetup(opts = {}) {
|
|
1878
|
+
const projectDir = opts.directory ? path.resolve(opts.directory) : process.cwd();
|
|
1879
|
+
const ownsRl = !opts.rl;
|
|
1880
|
+
const rl = opts.rl ?? createInterface({ input: stdin, output: stdout });
|
|
1881
|
+
try {
|
|
1882
|
+
const { Header } = await import("./setup/ui/header.js");
|
|
1883
|
+
const { Title } = await import("./setup/ui/title.js");
|
|
1884
|
+
const { Spinner } = await import("./setup/ui/spinner.js");
|
|
1885
|
+
const { printStatus } = await import("./setup/ui/status.js");
|
|
1886
|
+
console.log();
|
|
1887
|
+
console.log(Header(["gnosys", "setup", "provider"]));
|
|
1888
|
+
console.log();
|
|
1889
|
+
console.log(Title("Default provider", "pick the LLM provider — model stays as configured"));
|
|
1890
|
+
console.log();
|
|
1891
|
+
const existingConfig = await loadExistingConfig(projectDir);
|
|
1892
|
+
const currentProvider = existingConfig?.llm.defaultProvider;
|
|
1893
|
+
const pricingSpin = Spinner("fetching latest pricing from openrouter…");
|
|
1894
|
+
const fetchStart = Date.now();
|
|
1895
|
+
const dynamicModels = await fetchDynamicModels();
|
|
1896
|
+
const fetchMs = Date.now() - fetchStart;
|
|
1897
|
+
if (Object.keys(dynamicModels).length > 0) {
|
|
1898
|
+
pricingSpin.ok("pricing loaded", `${fetchMs} ms`);
|
|
1899
|
+
}
|
|
1900
|
+
else {
|
|
1901
|
+
pricingSpin.fail("pricing fetch failed", "using bundled tiers");
|
|
1902
|
+
}
|
|
1903
|
+
console.log();
|
|
1904
|
+
const provider = await pickProvider(rl, dynamicModels, "Choose your LLM provider", currentProvider);
|
|
1905
|
+
if (!provider || provider === currentProvider) {
|
|
1906
|
+
printStatus("warn", "no change · provider unchanged");
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
1910
|
+
const existingLlm = existingConfig?.llm ?? {};
|
|
1911
|
+
await updateConfig(storePath, {
|
|
1912
|
+
llm: { ...existingLlm, defaultProvider: provider },
|
|
1913
|
+
});
|
|
1914
|
+
printStatus("ok", `default provider · ${provider}`, `${storePath}/gnosys.json`);
|
|
1915
|
+
printStatus("progress", "model unchanged", "use row 2 to swap the model");
|
|
1916
|
+
}
|
|
1917
|
+
finally {
|
|
1918
|
+
if (ownsRl)
|
|
1919
|
+
rl.close();
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1775
1922
|
/**
|
|
1776
1923
|
* Models-only configuration — prompts for provider, model, and key (or accepts
|
|
1777
1924
|
* them via options for non-interactive use). Validates the model against the
|
|
@@ -1894,20 +2041,8 @@ export async function runModelsSetup(opts = {}) {
|
|
|
1894
2041
|
}
|
|
1895
2042
|
}
|
|
1896
2043
|
}
|
|
1897
|
-
// Step 5: write config
|
|
1898
|
-
const
|
|
1899
|
-
const globalStore = getGnosysHome();
|
|
1900
|
-
let storePath;
|
|
1901
|
-
if (fsSync.existsSync(path.join(projectStore, "gnosys.json"))) {
|
|
1902
|
-
storePath = projectStore;
|
|
1903
|
-
}
|
|
1904
|
-
else if (fsSync.existsSync(path.join(globalStore, "gnosys.json"))) {
|
|
1905
|
-
storePath = globalStore;
|
|
1906
|
-
}
|
|
1907
|
-
else {
|
|
1908
|
-
await fs.mkdir(globalStore, { recursive: true });
|
|
1909
|
-
storePath = globalStore;
|
|
1910
|
-
}
|
|
2044
|
+
// Step 5: write config (v5.9.4 Bug 10 — unified store resolution).
|
|
2045
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
1911
2046
|
const existingLlm = existingConfig?.llm;
|
|
1912
2047
|
const existingProviderConfig = existingLlm
|
|
1913
2048
|
? existingLlm[provider]
|
|
@@ -1985,11 +2120,8 @@ export async function runModelsCommand(opts = {}) {
|
|
|
1985
2120
|
console.log(`${WARN} No provider configured. Run 'gnosys setup' first.`);
|
|
1986
2121
|
return;
|
|
1987
2122
|
}
|
|
1988
|
-
|
|
1989
|
-
const
|
|
1990
|
-
const storePath = fsSync.existsSync(path.join(projectStore, "gnosys.json"))
|
|
1991
|
-
? projectStore
|
|
1992
|
-
: globalStore;
|
|
2123
|
+
// v5.9.4 Bug 10 — unified store resolution.
|
|
2124
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
1993
2125
|
const existingProviderConfig = existingConfig?.llm?.[currentProvider];
|
|
1994
2126
|
const providerConfigBase = (typeof existingProviderConfig === "object" && existingProviderConfig !== null)
|
|
1995
2127
|
? existingProviderConfig
|
|
@@ -2046,17 +2178,31 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2046
2178
|
const existingDream = existingConfig?.dream;
|
|
2047
2179
|
// Show current state via central DB
|
|
2048
2180
|
const { GnosysDB } = await import("./db.js");
|
|
2181
|
+
const { getMachineId } = await import("./remote.js");
|
|
2049
2182
|
const localDb = GnosysDB.openLocal();
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2183
|
+
// v5.9.4 Bugs 7+8 — also peek at the remote DB (if configured) so re-entry
|
|
2184
|
+
// sees a designation made on a different machine. Open remote read-only;
|
|
2185
|
+
// we'll mirror writes below.
|
|
2186
|
+
const remoteDb = await openRemoteDbIfConfigured(localDb);
|
|
2187
|
+
const designatedMachine = localDb.getDreamMachineId() ?? remoteDb?.getDreamMachineId() ?? null;
|
|
2188
|
+
// v5.9.4 Bug 9 — share the canonical machine-id resolver (os.hostname()
|
|
2189
|
+
// fallback included) instead of re-rolling HOSTNAME/COMPUTERNAME logic.
|
|
2190
|
+
const localMachine = getMachineId(localDb);
|
|
2191
|
+
// Mirror dream_machine_id writes to both DBs (Bug 8).
|
|
2192
|
+
const setDreamMachineEverywhere = (id) => {
|
|
2193
|
+
localDb.setDreamMachineId(id);
|
|
2194
|
+
try {
|
|
2195
|
+
remoteDb?.setDreamMachineId(id);
|
|
2196
|
+
}
|
|
2197
|
+
catch { /* remote may be transiently unavailable */ }
|
|
2198
|
+
};
|
|
2199
|
+
const clearDreamMachineEverywhere = () => {
|
|
2200
|
+
localDb.clearDreamMachineId();
|
|
2201
|
+
try {
|
|
2202
|
+
remoteDb?.clearDreamMachineId();
|
|
2057
2203
|
}
|
|
2058
|
-
|
|
2059
|
-
}
|
|
2204
|
+
catch { /* remote may be transiently unavailable */ }
|
|
2205
|
+
};
|
|
2060
2206
|
// ─── 7.0 Overview & enable ────────────────────────────────────────
|
|
2061
2207
|
console.log();
|
|
2062
2208
|
console.log(Header(["gnosys", "setup", "dream"], { version: "step 1 of 3" }));
|
|
@@ -2071,14 +2217,15 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2071
2217
|
const enabled = await askYesNo(rl, "enable Dream Mode?", existingDream?.enabled ?? true);
|
|
2072
2218
|
if (!enabled) {
|
|
2073
2219
|
// Persist disabled state and clear designation
|
|
2074
|
-
const storePath =
|
|
2220
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
2075
2221
|
await updateConfig(storePath, {
|
|
2076
2222
|
dream: { ...(existingDream ?? {}), enabled: false },
|
|
2077
2223
|
});
|
|
2078
|
-
|
|
2224
|
+
clearDreamMachineEverywhere();
|
|
2079
2225
|
console.log();
|
|
2080
2226
|
printStatus("ok", "dream mode disabled · designation cleared");
|
|
2081
2227
|
localDb.close();
|
|
2228
|
+
remoteDb?.close();
|
|
2082
2229
|
return;
|
|
2083
2230
|
}
|
|
2084
2231
|
// ─── 7.1 Designated machine + model ───────────────────────────────
|
|
@@ -2093,11 +2240,11 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2093
2240
|
? "this machine is currently the dreamer — keep it?"
|
|
2094
2241
|
: `designate THIS machine (${localMachine}) as the dreamer?`, true);
|
|
2095
2242
|
if (designate) {
|
|
2096
|
-
|
|
2243
|
+
setDreamMachineEverywhere(localMachine);
|
|
2097
2244
|
printStatus("ok", `${localMachine} is the dreamer`);
|
|
2098
2245
|
}
|
|
2099
2246
|
else if (designatedMachine === localMachine) {
|
|
2100
|
-
|
|
2247
|
+
clearDreamMachineEverywhere();
|
|
2101
2248
|
printStatus("warn", "designation cleared", "no machine will dream until you re-run on another");
|
|
2102
2249
|
}
|
|
2103
2250
|
else {
|
|
@@ -2150,6 +2297,7 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2150
2297
|
if (!proceed) {
|
|
2151
2298
|
printStatus("warn", "setup cancelled · no changes written");
|
|
2152
2299
|
localDb.close();
|
|
2300
|
+
remoteDb?.close();
|
|
2153
2301
|
return;
|
|
2154
2302
|
}
|
|
2155
2303
|
}
|
|
@@ -2203,7 +2351,7 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2203
2351
|
discoverRelationships = await askYesNo(rl, "discover relationships (LLM)", dDiscover);
|
|
2204
2352
|
}
|
|
2205
2353
|
// Save
|
|
2206
|
-
const storePath =
|
|
2354
|
+
const storePath = ensureActiveStorePath(projectDir);
|
|
2207
2355
|
await updateConfig(storePath, {
|
|
2208
2356
|
dream: {
|
|
2209
2357
|
enabled: true,
|
|
@@ -2221,6 +2369,7 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2221
2369
|
// doesn't fire immediately based on stale history.
|
|
2222
2370
|
localDb.resetDreamConsecutiveFailures();
|
|
2223
2371
|
localDb.close();
|
|
2372
|
+
remoteDb?.close();
|
|
2224
2373
|
// Final Diff block per the design — provider/machine + the two
|
|
2225
2374
|
// threshold fields most users actually care about.
|
|
2226
2375
|
console.log();
|
|
@@ -2247,7 +2396,7 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2247
2396
|
}));
|
|
2248
2397
|
const dreamerName = designate ? localMachine : (designatedMachine ?? "the designated machine");
|
|
2249
2398
|
printStatus("progress", `first cycle runs after ${dreamerName} is idle for ${idleMinutes} min`);
|
|
2250
|
-
printStatus("progress", "check status anytime with
|
|
2399
|
+
printStatus("progress", "check status anytime with `gnosys status --system`");
|
|
2251
2400
|
}
|
|
2252
2401
|
finally {
|
|
2253
2402
|
if (ownsRl)
|
|
@@ -2284,17 +2433,26 @@ export async function runChatSetup(opts = {}) {
|
|
|
2284
2433
|
// Provider/model override + recall tuning + tools fence + auto-summarize
|
|
2285
2434
|
// + system prompt prefix all move to the v6.0 chat TUI's settings panel
|
|
2286
2435
|
// (road-014). The exported stub above renders a deprecation notice.
|
|
2287
|
-
/**
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2436
|
+
/**
|
|
2437
|
+
* Open the remote central DB ONLY when sync is configured AND the share
|
|
2438
|
+
* is reachable. Returns null otherwise. Used by the dream wizard so it
|
|
2439
|
+
* can mirror `dream_machine_id` writes to both DB meta tables (Bug 8).
|
|
2440
|
+
*/
|
|
2441
|
+
async function openRemoteDbIfConfigured(localDb) {
|
|
2442
|
+
try {
|
|
2443
|
+
if (!localDb.isAvailable())
|
|
2444
|
+
return null;
|
|
2445
|
+
const remotePath = localDb.getMeta("remote_path");
|
|
2446
|
+
if (!remotePath)
|
|
2447
|
+
return null;
|
|
2448
|
+
if (!fsSync.existsSync(path.join(remotePath, "gnosys.db")))
|
|
2449
|
+
return null;
|
|
2450
|
+
const { GnosysDB } = await import("./db.js");
|
|
2451
|
+
return new GnosysDB(remotePath);
|
|
2293
2452
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2453
|
+
catch {
|
|
2454
|
+
return null;
|
|
2296
2455
|
}
|
|
2297
|
-
return globalStore;
|
|
2298
2456
|
}
|
|
2299
2457
|
/**
|
|
2300
2458
|
* Best-effort lookup of the API key for a provider. Used by the dream setup
|