gnosys 5.12.0 → 5.12.2
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/cli.js +48 -7
- package/dist/index.js +179 -10
- package/dist/lib/addCommand.js +0 -1
- package/dist/lib/archive.js +0 -2
- package/dist/lib/askCommand.js +1 -1
- package/dist/lib/attachCommand.d.ts +17 -0
- package/dist/lib/attachCommand.js +66 -0
- package/dist/lib/attachments.d.ts +43 -2
- package/dist/lib/attachments.js +81 -2
- package/dist/lib/chat/choose.js +2 -2
- package/dist/lib/clientReadOverlay.js +3 -0
- package/dist/lib/config.d.ts +1 -48
- package/dist/lib/configCommand.js +2 -2
- package/dist/lib/db.d.ts +16 -1
- package/dist/lib/db.js +216 -119
- package/dist/lib/dbWrite.d.ts +1 -1
- package/dist/lib/dearchiveCommand.js +1 -1
- package/dist/lib/docxExtract.js +1 -1
- package/dist/lib/dream.d.ts +8 -0
- package/dist/lib/dream.js +35 -1
- package/dist/lib/dreamLogCommand.js +1 -1
- package/dist/lib/dreamRunLog.d.ts +1 -1
- package/dist/lib/dreamRunLog.js +26 -4
- package/dist/lib/embeddings.js +0 -3
- package/dist/lib/exportProject.d.ts +3 -2
- package/dist/lib/exportProject.js +2 -1
- package/dist/lib/federated.js +1 -1
- package/dist/lib/hybridSearchCommand.js +1 -1
- package/dist/lib/importProject.js +2 -1
- package/dist/lib/llm.js +1 -1
- package/dist/lib/lock.d.ts +1 -1
- package/dist/lib/lock.js +5 -3
- package/dist/lib/migrate.js +0 -1
- package/dist/lib/multimodalIngest.js +1 -1
- package/dist/lib/platform.d.ts +0 -6
- package/dist/lib/platform.js +0 -28
- package/dist/lib/readCommand.js +11 -10
- package/dist/lib/remoteWizard.d.ts +1 -1
- package/dist/lib/remoteWizard.js +4 -4
- package/dist/lib/rulesGen.d.ts +8 -0
- package/dist/lib/rulesGen.js +16 -0
- package/dist/lib/search.d.ts +0 -2
- package/dist/lib/search.js +0 -7
- package/dist/lib/semanticSearchCommand.js +1 -1
- package/dist/lib/setup/sections/providers.js +56 -4
- package/dist/lib/setup/sections/routing.js +42 -5
- package/dist/lib/setup/sections/taskRoutingEditor.d.ts +1 -5
- package/dist/lib/setup/sections/taskRoutingEditor.js +0 -10
- package/dist/lib/setup/ui/header.js +0 -1
- package/dist/lib/setup/ui/status.d.ts +0 -1
- package/dist/lib/setup/ui/status.js +0 -2
- package/dist/lib/setup.d.ts +0 -15
- package/dist/lib/setup.js +13 -158
- package/dist/lib/staleCommand.js +2 -2
- package/dist/lib/syncClient.d.ts +0 -6
- package/dist/lib/syncClient.js +36 -14
- package/dist/lib/syncDoctorCommand.js +2 -2
- package/dist/lib/syncIngest.d.ts +11 -0
- package/dist/lib/syncIngest.js +24 -1
- package/dist/lib/syncIngestStartup.js +2 -2
- package/dist/lib/syncSnapshot.d.ts +2 -0
- package/dist/lib/syncSnapshot.js +4 -0
- package/dist/lib/syncStaging.d.ts +0 -2
- package/dist/lib/syncStaging.js +0 -2
- package/dist/lib/updateCommand.js +1 -1
- package/dist/lib/webBuildCommand.js +1 -1
- package/dist/lib/webIndex.js +0 -1
- package/dist/lib/webIngestCommand.js +1 -1
- package/dist/sandbox/client.js +1 -1
- package/dist/sandbox/manager.js +1 -14
- package/dist/sandbox/server.js +3 -5
- package/package.json +5 -2
|
@@ -78,14 +78,49 @@ export async function runRoutingSetup(opts) {
|
|
|
78
78
|
console.log("");
|
|
79
79
|
const choice = await askChoice(opts.rl, "What would you like to do?", [
|
|
80
80
|
"Keep current routing (no changes)",
|
|
81
|
-
"Edit tasks —
|
|
82
|
-
"
|
|
81
|
+
"Edit tasks — set the same provider + model for all tasks (simple global default)",
|
|
82
|
+
"Edit tasks — pick different providers/models for specific tasks (advanced)",
|
|
83
|
+
"Reset all task overrides to the current default (the one shown in the main setup summary)",
|
|
83
84
|
], 0);
|
|
84
85
|
if (choice === 0) {
|
|
85
86
|
console.log(`${DIM}No changes.${RESET}`);
|
|
86
87
|
return false;
|
|
87
88
|
}
|
|
88
|
-
if (choice ===
|
|
89
|
+
if (choice === 1) {
|
|
90
|
+
// Edit tasks — set the same provider + model for all tasks (simple global default)
|
|
91
|
+
console.log("");
|
|
92
|
+
printStatus("progress", "setting a single default for all tasks…");
|
|
93
|
+
try {
|
|
94
|
+
const { fetchDynamicModels } = await import("../../setup.js");
|
|
95
|
+
const { pickModel } = await import("../../setup.js");
|
|
96
|
+
const dynamicModels = await fetchDynamicModels();
|
|
97
|
+
const currentModel = getProviderModel(cfg, provider);
|
|
98
|
+
const chosenModel = await pickModel(opts.rl, provider, dynamicModels, `Default model for ${provider} (used for all tasks + dream)`, currentModel);
|
|
99
|
+
if (chosenModel && chosenModel !== currentModel) {
|
|
100
|
+
const after = await loadConfig(storePath);
|
|
101
|
+
await updateConfig(storePath, {
|
|
102
|
+
llm: {
|
|
103
|
+
...after.llm,
|
|
104
|
+
[provider]: {
|
|
105
|
+
...(after.llm[provider] || {}),
|
|
106
|
+
model: chosenModel,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
// Clear per-task overrides so everything truly uses the single default
|
|
110
|
+
taskModels: {},
|
|
111
|
+
});
|
|
112
|
+
printStatus("ok", `default set for everything · ${provider} / ${chosenModel}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
printStatus("ok", "no change to the global default");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
printStatus("warn", "could not update default model", String(err));
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (choice === 3) {
|
|
89
124
|
const { Diff } = await import("../ui/diff.js");
|
|
90
125
|
const overridesBeingCleared = Object.entries(cfg.taskModels ?? {})
|
|
91
126
|
.filter(([, v]) => v.provider !== provider || v.model !== model)
|
|
@@ -102,16 +137,18 @@ export async function runRoutingSetup(opts) {
|
|
|
102
137
|
else {
|
|
103
138
|
console.log(`${DIM}No overrides to clear — already using default everywhere.${RESET}`);
|
|
104
139
|
}
|
|
105
|
-
|
|
140
|
+
console.log(`${DIM}The current default is ${provider} / ${model} (set via the main setup "Default provider" or the simple global option above).${RESET}`);
|
|
141
|
+
const confirmReset = await askYesNo(opts.rl, "Reset all task overrides to the current default?", true);
|
|
106
142
|
if (!confirmReset) {
|
|
107
143
|
console.log(`${DIM}Cancelled.${RESET}`);
|
|
108
144
|
return false;
|
|
109
145
|
}
|
|
110
146
|
await updateConfig(storePath, { taskModels: {} });
|
|
111
|
-
printStatus("ok", "routing reset", "all tasks use default provider/model");
|
|
147
|
+
printStatus("ok", "routing reset", "all tasks now use the global default provider/model");
|
|
112
148
|
console.log(Footer("press enter to return"));
|
|
113
149
|
return true;
|
|
114
150
|
}
|
|
151
|
+
// choice === 2 → advanced per-task editor (the powerful comma-list path)
|
|
115
152
|
const patch = await runCommaListRoutingEditor(opts.rl, storePath, cfg);
|
|
116
153
|
if (!patch) {
|
|
117
154
|
return false;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Comma-list task routing editor (provider + model per selected task).
|
|
3
3
|
*/
|
|
4
4
|
import type { Interface as ReadlineInterface } from "readline/promises";
|
|
5
|
-
import {
|
|
5
|
+
import type { GnosysConfig } from "../../config.js";
|
|
6
6
|
/**
|
|
7
7
|
* Let the user pick tasks by number, then provider + model for each.
|
|
8
8
|
* Returns a patch for taskModels + dream, or null if cancelled.
|
|
@@ -11,7 +11,3 @@ export declare function runCommaListRoutingEditor(rl: ReadlineInterface, storePa
|
|
|
11
11
|
taskModels: NonNullable<GnosysConfig["taskModels"]>;
|
|
12
12
|
dream: GnosysConfig["dream"];
|
|
13
13
|
} | null>;
|
|
14
|
-
export declare function applyRoutingPatch(projectDir: string, patch: {
|
|
15
|
-
taskModels: NonNullable<GnosysConfig["taskModels"]>;
|
|
16
|
-
dream: GnosysConfig["dream"];
|
|
17
|
-
}): Promise<GnosysConfig>;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Comma-list task routing editor (provider + model per selected task).
|
|
3
3
|
*/
|
|
4
|
-
import { loadConfig, updateConfig, } from "../../config.js";
|
|
5
4
|
import { ASSIGNABLE_TASK_LIST, fetchDynamicModels, getAssignableRouting, modelForTaskAssignment, parseCommaSeparatedTaskSelection, pickModel, pickProvider, TASK_DESCRIPTIONS, } from "../../setup.js";
|
|
6
|
-
import { resolveActiveStorePath } from "../storePath.js";
|
|
7
5
|
import { safeQuestion } from "../ui/safePrompt.js";
|
|
8
6
|
import { renderProviderMark } from "../providerGlyphs.js";
|
|
9
7
|
import { c, color, glyph } from "../ui/tokens.js";
|
|
@@ -139,11 +137,3 @@ export async function runCommaListRoutingEditor(rl, storePath, cfg) {
|
|
|
139
137
|
}
|
|
140
138
|
return { taskModels, dream };
|
|
141
139
|
}
|
|
142
|
-
export async function applyRoutingPatch(projectDir, patch) {
|
|
143
|
-
const storePath = resolveActiveStorePath(projectDir);
|
|
144
|
-
await updateConfig(storePath, {
|
|
145
|
-
taskModels: patch.taskModels,
|
|
146
|
-
dream: patch.dream,
|
|
147
|
-
});
|
|
148
|
-
return loadConfig(storePath);
|
|
149
|
-
}
|
|
@@ -39,7 +39,6 @@ export function Header(crumbs, opts = {}) {
|
|
|
39
39
|
}
|
|
40
40
|
/** Strip ANSI escapes so we can measure printable width. Exported for callers/tests that need printable measurement. */
|
|
41
41
|
export function stripAnsi(s) {
|
|
42
|
-
// eslint-disable-next-line no-control-regex
|
|
43
42
|
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
44
43
|
}
|
|
45
44
|
/** Convenience: print header + trailing blank line to stdout. */
|
|
@@ -18,4 +18,3 @@ export type StatusKind = "ok" | "warn" | "fail" | "progress";
|
|
|
18
18
|
export declare function Status(kind: StatusKind, text: string, meta?: string): string;
|
|
19
19
|
/** Convenience: print a single status line. */
|
|
20
20
|
export declare function printStatus(kind: StatusKind, text: string, meta?: string): void;
|
|
21
|
-
export { MASTER_UNREACHABLE_MESSAGE, formatMemoriesWaitingToSync, formatFailedToSyncCount, formatOfflinePushStarting, renderClientSyncStatusLines, type ClientSyncStatusInput, } from "../remoteRender.js";
|
|
@@ -46,5 +46,3 @@ export function Status(kind, text, meta) {
|
|
|
46
46
|
export function printStatus(kind, text, meta) {
|
|
47
47
|
process.stdout.write(`${Status(kind, text, meta)}\n`);
|
|
48
48
|
}
|
|
49
|
-
// ─── v13 multi-machine sync (re-export render helpers for CLI/MCP callers) ─
|
|
50
|
-
export { MASTER_UNREACHABLE_MESSAGE, formatMemoriesWaitingToSync, formatFailedToSyncCount, formatOfflinePushStarting, renderClientSyncStatusLines, } from "../remoteRender.js";
|
package/dist/lib/setup.d.ts
CHANGED
|
@@ -138,20 +138,6 @@ export declare function runSetup(opts: {
|
|
|
138
138
|
directory?: string;
|
|
139
139
|
nonInteractive?: boolean;
|
|
140
140
|
}): Promise<SetupResult>;
|
|
141
|
-
export interface ProviderOnlySetupOpts {
|
|
142
|
-
directory?: string;
|
|
143
|
-
rl?: ReadlineInterface;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Update ONLY `llm.defaultProvider` in gnosys.json. Used by the summary
|
|
147
|
-
* panel row 1 ("provider") so it stops dragging the user into the full
|
|
148
|
-
* model picker — that's row 2's job.
|
|
149
|
-
*
|
|
150
|
-
* v5.9.4 Bug 4 — before this split, both summary rows routed through
|
|
151
|
-
* `runModelsSetup`, leaving no way to swap provider without also choosing
|
|
152
|
-
* a new model. Now row 1 picks a provider, row 2 picks a model.
|
|
153
|
-
*/
|
|
154
|
-
export declare function runProviderOnlySetup(opts?: ProviderOnlySetupOpts): Promise<void>;
|
|
155
141
|
/** Where validated keys are persisted (§3.10). */
|
|
156
142
|
export type KeyPersistDestination = "secure" | "dotenv" | "none";
|
|
157
143
|
/**
|
|
@@ -252,4 +238,3 @@ export declare function getApiKeyForProvider(provider: string, opts?: {
|
|
|
252
238
|
task?: LlmTaskName;
|
|
253
239
|
directory?: string;
|
|
254
240
|
}): Promise<string>;
|
|
255
|
-
export { getApiKeyForProviderFromConfig } from "./apiKeyVault.js";
|
package/dist/lib/setup.js
CHANGED
|
@@ -271,16 +271,6 @@ export async function fetchDynamicModels() {
|
|
|
271
271
|
return {};
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
|
-
/**
|
|
275
|
-
* Get model tiers for a provider — tries dynamic first, falls back to hardcoded.
|
|
276
|
-
*/
|
|
277
|
-
async function getModelTiers(provider) {
|
|
278
|
-
const dynamic = await fetchDynamicModels();
|
|
279
|
-
if (dynamic[provider] && dynamic[provider].length > 0) {
|
|
280
|
-
return dynamic[provider];
|
|
281
|
-
}
|
|
282
|
-
return PROVIDER_TIERS[provider] ?? [];
|
|
283
|
-
}
|
|
284
274
|
// ─── Provider display names and env var mapping ─────────────────────────────
|
|
285
275
|
const PROVIDER_DISPLAY = {
|
|
286
276
|
anthropic: "Anthropic (Claude)",
|
|
@@ -675,7 +665,7 @@ export async function detectIDEs(projectDir) {
|
|
|
675
665
|
*/
|
|
676
666
|
export function upsertGrokMcpBlock(existing, name, entry) {
|
|
677
667
|
// Drop mistaken v5.9.4 `[mcp.<name>]` sections so we don't leave dead config.
|
|
678
|
-
|
|
668
|
+
const content = removeTomlSection(existing, `[mcp.${name}]`);
|
|
679
669
|
const sectionHeader = `[mcp_servers.${name}]`;
|
|
680
670
|
const lines = content.split("\n");
|
|
681
671
|
const headerIdx = lines.findIndex((line) => line.trim() === sectionHeader);
|
|
@@ -779,7 +769,7 @@ export async function setupIDE(ide, projectDir) {
|
|
|
779
769
|
// 1. Strip legacy hand-written sections in ~/.codex/config.toml.
|
|
780
770
|
const userCodexConfig = path.join(os.homedir(), ".codex", "config.toml");
|
|
781
771
|
try {
|
|
782
|
-
|
|
772
|
+
const existing = await fs.readFile(userCodexConfig, "utf-8");
|
|
783
773
|
const cleaned = removeTomlSection(removeTomlSection(existing, "[mcp.gnosys]"), "[gnosys]");
|
|
784
774
|
if (cleaned !== existing) {
|
|
785
775
|
await fs.writeFile(userCodexConfig, cleaned, "utf-8");
|
|
@@ -796,7 +786,7 @@ export async function setupIDE(ide, projectDir) {
|
|
|
796
786
|
let alreadyCorrect = false;
|
|
797
787
|
try {
|
|
798
788
|
const existing = runCli("codex", ["mcp", "get", "gnosys"], { allowFailure: true });
|
|
799
|
-
if (existing
|
|
789
|
+
if (existing?.includes(gnosysCmd) && !existing.includes(" serve")) {
|
|
800
790
|
alreadyCorrect = true;
|
|
801
791
|
}
|
|
802
792
|
else if (existing) {
|
|
@@ -1439,8 +1429,7 @@ export async function runSetup(opts) {
|
|
|
1439
1429
|
const gnomeIdx = hasSecret ? idx++ : -1;
|
|
1440
1430
|
const envIdx = idx++;
|
|
1441
1431
|
const dotenvIdx = idx++;
|
|
1442
|
-
|
|
1443
|
-
// skipIdx is unused as a variable but documents the last index
|
|
1432
|
+
idx++; // skip entry consumes the last index (value itself unused)
|
|
1444
1433
|
if (keyChoice === keychainIdx) {
|
|
1445
1434
|
// macOS Keychain — reuse existing key if available, otherwise ask
|
|
1446
1435
|
console.log();
|
|
@@ -1974,60 +1963,6 @@ export async function runSetup(opts) {
|
|
|
1974
1963
|
throw err;
|
|
1975
1964
|
}
|
|
1976
1965
|
}
|
|
1977
|
-
/**
|
|
1978
|
-
* Update ONLY `llm.defaultProvider` in gnosys.json. Used by the summary
|
|
1979
|
-
* panel row 1 ("provider") so it stops dragging the user into the full
|
|
1980
|
-
* model picker — that's row 2's job.
|
|
1981
|
-
*
|
|
1982
|
-
* v5.9.4 Bug 4 — before this split, both summary rows routed through
|
|
1983
|
-
* `runModelsSetup`, leaving no way to swap provider without also choosing
|
|
1984
|
-
* a new model. Now row 1 picks a provider, row 2 picks a model.
|
|
1985
|
-
*/
|
|
1986
|
-
export async function runProviderOnlySetup(opts = {}) {
|
|
1987
|
-
const projectDir = opts.directory ? path.resolve(opts.directory) : process.cwd();
|
|
1988
|
-
const ownsRl = !opts.rl;
|
|
1989
|
-
const rl = opts.rl ?? createInterface({ input: stdin, output: stdout });
|
|
1990
|
-
try {
|
|
1991
|
-
const { Header } = await import("./setup/ui/header.js");
|
|
1992
|
-
const { Title } = await import("./setup/ui/title.js");
|
|
1993
|
-
const { Spinner } = await import("./setup/ui/spinner.js");
|
|
1994
|
-
const { printStatus } = await import("./setup/ui/status.js");
|
|
1995
|
-
console.log();
|
|
1996
|
-
console.log(Header(["gnosys", "setup", "provider"]));
|
|
1997
|
-
console.log();
|
|
1998
|
-
console.log(Title("Default provider", "pick the LLM provider — model stays as configured"));
|
|
1999
|
-
console.log();
|
|
2000
|
-
const existingConfig = await loadExistingConfig(projectDir);
|
|
2001
|
-
const currentProvider = existingConfig?.llm.defaultProvider;
|
|
2002
|
-
const pricingSpin = Spinner("fetching latest pricing from openrouter…");
|
|
2003
|
-
const fetchStart = Date.now();
|
|
2004
|
-
const dynamicModels = await fetchDynamicModels();
|
|
2005
|
-
const fetchMs = Date.now() - fetchStart;
|
|
2006
|
-
if (Object.keys(dynamicModels).length > 0) {
|
|
2007
|
-
pricingSpin.ok("pricing loaded", `${fetchMs} ms`);
|
|
2008
|
-
}
|
|
2009
|
-
else {
|
|
2010
|
-
pricingSpin.fail("pricing fetch failed", "using bundled tiers");
|
|
2011
|
-
}
|
|
2012
|
-
console.log();
|
|
2013
|
-
const provider = await pickProvider(rl, dynamicModels, "Choose your LLM provider", currentProvider);
|
|
2014
|
-
if (!provider || provider === currentProvider) {
|
|
2015
|
-
printStatus("warn", "no change · provider unchanged");
|
|
2016
|
-
return;
|
|
2017
|
-
}
|
|
2018
|
-
const storePath = ensureActiveStorePath(projectDir);
|
|
2019
|
-
const existingLlm = existingConfig?.llm ?? {};
|
|
2020
|
-
await updateConfig(storePath, {
|
|
2021
|
-
llm: { ...existingLlm, defaultProvider: provider },
|
|
2022
|
-
});
|
|
2023
|
-
printStatus("ok", `default provider · ${provider}`, `${storePath}/gnosys.json`);
|
|
2024
|
-
printStatus("progress", "model unchanged", "use row 2 to swap the model");
|
|
2025
|
-
}
|
|
2026
|
-
finally {
|
|
2027
|
-
if (ownsRl)
|
|
2028
|
-
rl.close();
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
1966
|
/**
|
|
2032
1967
|
* Build API key requirements from the selected task set only (§3.7).
|
|
2033
1968
|
* One global key per distinct cloud provider in the selection.
|
|
@@ -2142,7 +2077,6 @@ export async function promptKeyDestinationAndPersist(opts) {
|
|
|
2142
2077
|
(await askChoice(opts.rl, "Where should I store this key?", options));
|
|
2143
2078
|
const secureIdx = 0;
|
|
2144
2079
|
const dotenvIdx = 1;
|
|
2145
|
-
const noneIdx = 2;
|
|
2146
2080
|
if (choice === secureIdx) {
|
|
2147
2081
|
if (storeApiKeySecret(opts.service, opts.key, opts.provider)) {
|
|
2148
2082
|
const store = process.platform === "darwin" ? "macOS Keychain" : "GNOME Keyring";
|
|
@@ -2571,84 +2505,6 @@ async function runModelsTaskRoutingSetup(ctx) {
|
|
|
2571
2505
|
await updateConfig(storePath, updatePayload);
|
|
2572
2506
|
printStatus("ok", `saved task routing · ${storePath}/gnosys.json`);
|
|
2573
2507
|
}
|
|
2574
|
-
/**
|
|
2575
|
-
* Lightweight model-management command. Supports three operations:
|
|
2576
|
-
* --list: print available models for the current provider
|
|
2577
|
-
* --refresh: clear the OpenRouter cache and re-fetch
|
|
2578
|
-
* --set X: update the default model in gnosys.json (no prompts)
|
|
2579
|
-
*/
|
|
2580
|
-
async function runModelsCommand(opts = {}) {
|
|
2581
|
-
const projectDir = opts.directory ? path.resolve(opts.directory) : process.cwd();
|
|
2582
|
-
const existingConfig = await loadExistingConfig(projectDir);
|
|
2583
|
-
const currentProvider = existingConfig?.llm.defaultProvider;
|
|
2584
|
-
if (opts.refresh) {
|
|
2585
|
-
const cacheFile = path.join(os.homedir(), ".config", "gnosys", "models-cache.json");
|
|
2586
|
-
try {
|
|
2587
|
-
await fs.unlink(cacheFile);
|
|
2588
|
-
console.log(`${CHECK} Cache cleared.`);
|
|
2589
|
-
}
|
|
2590
|
-
catch {
|
|
2591
|
-
console.log(`${DIM}No cache to clear.${RESET}`);
|
|
2592
|
-
}
|
|
2593
|
-
}
|
|
2594
|
-
if (opts.list) {
|
|
2595
|
-
if (!currentProvider) {
|
|
2596
|
-
console.log(`${WARN} No provider configured. Run 'gnosys setup' first.`);
|
|
2597
|
-
return;
|
|
2598
|
-
}
|
|
2599
|
-
console.log();
|
|
2600
|
-
console.log(`${BOLD}Available models for ${currentProvider}:${RESET}`);
|
|
2601
|
-
console.log();
|
|
2602
|
-
const dynamicModels = await fetchDynamicModels();
|
|
2603
|
-
const tiers = dynamicModels[currentProvider] ?? PROVIDER_TIERS[currentProvider] ?? [];
|
|
2604
|
-
if (tiers.length === 0) {
|
|
2605
|
-
console.log(` ${DIM}No models in catalog. Try '--refresh' or use a custom model name.${RESET}`);
|
|
2606
|
-
return;
|
|
2607
|
-
}
|
|
2608
|
-
for (const t of tiers) {
|
|
2609
|
-
const rec = t.recommended ? ` ${CYAN}<- recommended${RESET}` : "";
|
|
2610
|
-
const price = t.input === 0 && t.output === 0
|
|
2611
|
-
? "free"
|
|
2612
|
-
: `$${t.input.toFixed(2)}–$${t.output.toFixed(2)}/M`;
|
|
2613
|
-
console.log(` ${t.name.padEnd(24)} ${t.model.padEnd(40)} ${DIM}${price}${RESET}${rec}`);
|
|
2614
|
-
}
|
|
2615
|
-
return;
|
|
2616
|
-
}
|
|
2617
|
-
if (opts.set) {
|
|
2618
|
-
if (!currentProvider) {
|
|
2619
|
-
console.log(`${WARN} No provider configured. Run 'gnosys setup' first.`);
|
|
2620
|
-
return;
|
|
2621
|
-
}
|
|
2622
|
-
// v5.9.4 Bug 10 — unified store resolution.
|
|
2623
|
-
const storePath = ensureActiveStorePath(projectDir);
|
|
2624
|
-
const existingProviderConfig = existingConfig?.llm?.[currentProvider];
|
|
2625
|
-
const providerConfigBase = (typeof existingProviderConfig === "object" && existingProviderConfig !== null)
|
|
2626
|
-
? existingProviderConfig
|
|
2627
|
-
: {};
|
|
2628
|
-
await updateConfig(storePath, {
|
|
2629
|
-
llm: {
|
|
2630
|
-
...(existingConfig?.llm ?? {}),
|
|
2631
|
-
defaultProvider: currentProvider,
|
|
2632
|
-
[currentProvider]: { ...providerConfigBase, model: opts.set },
|
|
2633
|
-
},
|
|
2634
|
-
});
|
|
2635
|
-
console.log(`${CHECK} Default model set to ${GREEN}${opts.set}${RESET} for ${currentProvider}.`);
|
|
2636
|
-
return;
|
|
2637
|
-
}
|
|
2638
|
-
// No flags: show current config
|
|
2639
|
-
if (!currentProvider) {
|
|
2640
|
-
console.log(`${WARN} No provider configured. Run 'gnosys setup' first.`);
|
|
2641
|
-
return;
|
|
2642
|
-
}
|
|
2643
|
-
const currentModel = existingConfig
|
|
2644
|
-
? getProviderModel(existingConfig, existingConfig.llm.defaultProvider)
|
|
2645
|
-
: "";
|
|
2646
|
-
console.log();
|
|
2647
|
-
console.log(`Provider: ${GREEN}${currentProvider}${RESET}`);
|
|
2648
|
-
console.log(`Model: ${GREEN}${currentModel}${RESET}`);
|
|
2649
|
-
console.log();
|
|
2650
|
-
console.log(`${DIM}Use '--list' to see options, '--set <model>' to change, '--refresh' to update catalog.${RESET}`);
|
|
2651
|
-
}
|
|
2652
2508
|
/**
|
|
2653
2509
|
* Walks the user through configuring dream mode. Handles:
|
|
2654
2510
|
* - enable/disable
|
|
@@ -2857,23 +2713,23 @@ export async function runDreamSetup(opts = {}) {
|
|
|
2857
2713
|
let discoverRelationships = dDiscover;
|
|
2858
2714
|
if (editChoice === "e") {
|
|
2859
2715
|
const idleAns = await askInput(rl, "idle minutes before triggering", { default: String(dIdle) });
|
|
2860
|
-
idleMinutes = Math.max(1, parseInt(idleAns) || dIdle);
|
|
2716
|
+
idleMinutes = Math.max(1, parseInt(idleAns, 10) || dIdle);
|
|
2861
2717
|
const runtimeAns = await askInput(rl, "max runtime minutes", { default: String(dRuntime) });
|
|
2862
|
-
maxRuntimeMinutes = Math.max(1, parseInt(runtimeAns) || dRuntime);
|
|
2718
|
+
maxRuntimeMinutes = Math.max(1, parseInt(runtimeAns, 10) || dRuntime);
|
|
2863
2719
|
const minMemAns = await askInput(rl, "minimum memories before activating", { default: String(dMinMem) });
|
|
2864
|
-
minMemories = Math.max(1, parseInt(minMemAns) || dMinMem);
|
|
2720
|
+
minMemories = Math.max(1, parseInt(minMemAns, 10) || dMinMem);
|
|
2865
2721
|
const scheduleStartAns = await askInput(rl, "night window start hour (0-23)", { default: String(dScheduleStart) });
|
|
2866
|
-
scheduleStartHour = Math.min(23, Math.max(0, parseInt(scheduleStartAns) || dScheduleStart));
|
|
2722
|
+
scheduleStartHour = Math.min(23, Math.max(0, parseInt(scheduleStartAns, 10) || dScheduleStart));
|
|
2867
2723
|
const scheduleEndAns = await askInput(rl, "night window end hour (0-23)", { default: String(dScheduleEnd) });
|
|
2868
|
-
scheduleEndHour = Math.min(23, Math.max(0, parseInt(scheduleEndAns) || dScheduleEnd));
|
|
2724
|
+
scheduleEndHour = Math.min(23, Math.max(0, parseInt(scheduleEndAns, 10) || dScheduleEnd));
|
|
2869
2725
|
const systemIdleAns = await askInput(rl, "real machine idle minutes required", { default: String(dSystemIdle) });
|
|
2870
|
-
systemIdleMinutes = Math.max(1, parseInt(systemIdleAns) || dSystemIdle);
|
|
2726
|
+
systemIdleMinutes = Math.max(1, parseInt(systemIdleAns, 10) || dSystemIdle);
|
|
2871
2727
|
const minNewAns = await askInput(rl, "minimum changed memories before dreaming", { default: String(dMinNewMemories) });
|
|
2872
|
-
minNewMemoriesToDream = Math.max(0, parseInt(minNewAns) || dMinNewMemories);
|
|
2728
|
+
minNewMemoriesToDream = Math.max(0, parseInt(minNewAns, 10) || dMinNewMemories);
|
|
2873
2729
|
const minHoursAns = await askInput(rl, "minimum hours between successful dreams", { default: String(dMinHours) });
|
|
2874
|
-
minHoursBetweenRuns = Math.max(0, parseInt(minHoursAns) || dMinHours);
|
|
2730
|
+
minHoursBetweenRuns = Math.max(0, parseInt(minHoursAns, 10) || dMinHours);
|
|
2875
2731
|
const maxCallsAns = await askInput(rl, "maximum LLM calls per dream run", { default: String(dMaxCalls) });
|
|
2876
|
-
maxLLMCallsPerRun = Math.max(0, parseInt(maxCallsAns) || dMaxCalls);
|
|
2732
|
+
maxLLMCallsPerRun = Math.max(0, parseInt(maxCallsAns, 10) || dMaxCalls);
|
|
2877
2733
|
selfCritique = await askYesNo(rl, "self-critique (rule + LLM-based review flagging)", dSelfCritique);
|
|
2878
2734
|
generateSummaries = await askYesNo(rl, "generate summaries (LLM)", dGenSummaries);
|
|
2879
2735
|
discoverRelationships = await askYesNo(rl, "discover relationships (LLM)", dDiscover);
|
|
@@ -3009,4 +2865,3 @@ export async function getApiKeyForProvider(provider, opts) {
|
|
|
3009
2865
|
}
|
|
3010
2866
|
return readFirstInChain(provider) ?? "";
|
|
3011
2867
|
}
|
|
3012
|
-
export { getApiKeyForProviderFromConfig } from "./apiKeyVault.js";
|
package/dist/lib/staleCommand.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export async function runStaleCommand(getResolver, opts) {
|
|
2
2
|
const resolver = await getResolver();
|
|
3
|
-
const threshold = parseInt(opts.days);
|
|
3
|
+
const threshold = parseInt(opts.days, 10);
|
|
4
4
|
const cutoff = new Date();
|
|
5
5
|
cutoff.setDate(cutoff.getDate() - threshold);
|
|
6
6
|
const cutoffStr = cutoff.toISOString().split("T")[0];
|
|
@@ -18,7 +18,7 @@ export async function runStaleCommand(getResolver, opts) {
|
|
|
18
18
|
b.frontmatter.modified;
|
|
19
19
|
return (aDate || "").localeCompare(bDate || "");
|
|
20
20
|
})
|
|
21
|
-
.slice(0, parseInt(opts.limit));
|
|
21
|
+
.slice(0, parseInt(opts.limit, 10));
|
|
22
22
|
if (stale.length === 0) {
|
|
23
23
|
console.log(`No memories older than ${threshold} days.`);
|
|
24
24
|
return;
|
package/dist/lib/syncClient.d.ts
CHANGED
|
@@ -33,15 +33,9 @@ export interface V13SyncStatus {
|
|
|
33
33
|
}
|
|
34
34
|
export declare function isMasterReachable(masterPath: string): boolean;
|
|
35
35
|
export declare function countClientWaitingStaging(masterPath: string, machineId: string): number;
|
|
36
|
-
/** Client should hide snapshot reads when master is unreachable (v13 offline rule). */
|
|
37
|
-
export declare function shouldHideSnapshotReads(masterPath: string): boolean;
|
|
38
36
|
export declare function listClientReceipts(masterPath: string, machineId: string): IngestReceipt[];
|
|
39
37
|
export declare function getIngestedUlids(masterPath: string, machineId: string): Set<string>;
|
|
40
38
|
export declare function openClientReadContext(localDb: GnosysDB, masterPath: string, machineId: string): ClientReadContext;
|
|
41
39
|
/** Release snapshot/master DB handles opened by openClientReadContext. */
|
|
42
40
|
export declare function closeClientReadContext(ctx: ClientReadContext): void;
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated Use openClientReadContext — returns only the read DB without overlay or cleanup.
|
|
45
|
-
*/
|
|
46
|
-
export declare function openClientReadDb(localDb: GnosysDB, masterPath: string): GnosysDB;
|
|
47
41
|
export declare function getV13SyncStatus(localDb: GnosysDB): V13SyncStatus;
|
package/dist/lib/syncClient.js
CHANGED
|
@@ -6,7 +6,7 @@ import path from "path";
|
|
|
6
6
|
import { GnosysDB } from "./db.js";
|
|
7
7
|
import { readMachineConfig, getMachineId } from "./machineConfig.js";
|
|
8
8
|
import { getConfiguredRemotePath } from "./remote.js";
|
|
9
|
-
import { clientSnapshotStore, formatSnapshotAge, getClientAcceptedManifest, } from "./syncSnapshot.js";
|
|
9
|
+
import { acceptClientSnapshot, clientSnapshotStore, compareSnapshotVersion, formatSnapshotAge, getClientAcceptedManifest, getMasterManifest, } from "./syncSnapshot.js";
|
|
10
10
|
import { countFailedStagingFiles, machineStagingDir, stagingRoot } from "./syncStaging.js";
|
|
11
11
|
import { renderClientSyncStatusLines, } from "./setup/remoteRender.js";
|
|
12
12
|
const REACHABILITY_TTL_MS = 30_000;
|
|
@@ -53,10 +53,6 @@ export function countClientWaitingStaging(masterPath, machineId) {
|
|
|
53
53
|
return 0;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
/** Client should hide snapshot reads when master is unreachable (v13 offline rule). */
|
|
57
|
-
export function shouldHideSnapshotReads(masterPath) {
|
|
58
|
-
return !isMasterReachable(masterPath);
|
|
59
|
-
}
|
|
60
56
|
export function listClientReceipts(masterPath, machineId) {
|
|
61
57
|
const dir = path.join(stagingRoot(masterPath), machineId, "receipts");
|
|
62
58
|
if (!existsSync(dir))
|
|
@@ -92,7 +88,39 @@ export function openClientReadContext(localDb, masterPath, machineId) {
|
|
|
92
88
|
const reachable = isMasterReachable(masterPath);
|
|
93
89
|
const ingestedUlids = getIngestedUlids(masterPath, machineId);
|
|
94
90
|
const pendingAdds = localDb.listActivePendingAdds().filter((p) => !ingestedUlids.has(p.id));
|
|
91
|
+
const store = clientSnapshotStore(masterPath);
|
|
92
|
+
const snapPath = path.join(store, "gnosys.db");
|
|
95
93
|
if (reachable) {
|
|
94
|
+
// v13 completion (5.12.x): clients must not open the live gnosys.db over
|
|
95
|
+
// the network (concurrent master writes + network FS = torn-page hazard,
|
|
96
|
+
// DESIGN.md "The Simple Rule"). Refresh the verified local snapshot copy
|
|
97
|
+
// when the master has published a newer one, then read the local copy.
|
|
98
|
+
const manifest = getMasterManifest(masterPath);
|
|
99
|
+
if (manifest) {
|
|
100
|
+
const accepted = getClientAcceptedManifest(masterPath);
|
|
101
|
+
if (compareSnapshotVersion(accepted, manifest)) {
|
|
102
|
+
// Best effort — on checksum/copy failure we fall through to whatever
|
|
103
|
+
// local snapshot (or live-DB fallback) is still available.
|
|
104
|
+
acceptClientSnapshot(masterPath, manifest);
|
|
105
|
+
}
|
|
106
|
+
if (existsSync(snapPath)) {
|
|
107
|
+
const snapDb = new GnosysDB(store);
|
|
108
|
+
if (snapDb.isAvailable()) {
|
|
109
|
+
return {
|
|
110
|
+
db: snapDb,
|
|
111
|
+
localDb,
|
|
112
|
+
pendingOverlay: pendingAdds,
|
|
113
|
+
source: "snapshot",
|
|
114
|
+
masterReachable: true,
|
|
115
|
+
ownsReadDb: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
snapDb.close();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Compatibility fallback: master has never published a snapshot (older
|
|
122
|
+
// master version, or first sweep still pending) — open the live DB as
|
|
123
|
+
// before. Disappears once the master runs one publish-enabled sweep.
|
|
96
124
|
const masterDb = new GnosysDB(masterPath);
|
|
97
125
|
if (masterDb.isAvailable()) {
|
|
98
126
|
return {
|
|
@@ -106,8 +134,9 @@ export function openClientReadContext(localDb, masterPath, machineId) {
|
|
|
106
134
|
}
|
|
107
135
|
masterDb.close();
|
|
108
136
|
}
|
|
109
|
-
|
|
110
|
-
|
|
137
|
+
// Offline (soft rule, signed off 2026-06-11): the last-accepted snapshot
|
|
138
|
+
// stays readable — immutable + checksummed, and offline clients are
|
|
139
|
+
// add-only, so staleness is the only risk. Status surfaces snapshotAge.
|
|
111
140
|
if (existsSync(snapPath)) {
|
|
112
141
|
const snapDb = new GnosysDB(store);
|
|
113
142
|
if (snapDb.isAvailable()) {
|
|
@@ -137,13 +166,6 @@ export function closeClientReadContext(ctx) {
|
|
|
137
166
|
ctx.db.close();
|
|
138
167
|
}
|
|
139
168
|
}
|
|
140
|
-
/**
|
|
141
|
-
* @deprecated Use openClientReadContext — returns only the read DB without overlay or cleanup.
|
|
142
|
-
*/
|
|
143
|
-
export function openClientReadDb(localDb, masterPath) {
|
|
144
|
-
const ctx = openClientReadContext(localDb, masterPath, getMachineId());
|
|
145
|
-
return ctx.db;
|
|
146
|
-
}
|
|
147
169
|
export function getV13SyncStatus(localDb) {
|
|
148
170
|
const mc = readMachineConfig();
|
|
149
171
|
const masterPath = getConfiguredRemotePath(localDb);
|
|
@@ -2,7 +2,7 @@ import { GnosysDB } from "./db.js";
|
|
|
2
2
|
import { getConfiguredRemotePath } from "./remote.js";
|
|
3
3
|
import { readMachineConfig } from "./machineConfig.js";
|
|
4
4
|
import { getV13SyncStatus } from "./syncClient.js";
|
|
5
|
-
import {
|
|
5
|
+
import { runMasterIngestSweepAndPublish } from "./syncIngest.js";
|
|
6
6
|
import { getSyncIngestTimerStatus } from "./syncIngestTimer.js";
|
|
7
7
|
import { quarantineStaleTmpFiles, stagingRoot } from "./syncStaging.js";
|
|
8
8
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -48,7 +48,7 @@ export async function runSyncDoctorCommand(opts) {
|
|
|
48
48
|
quarantineStaleTmpFiles(masterPath, id);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
ingestResult =
|
|
51
|
+
ingestResult = await runMasterIngestSweepAndPublish(masterPath, {
|
|
52
52
|
quiet: opts.quiet || !!opts.json,
|
|
53
53
|
});
|
|
54
54
|
if (ingestResult.errors.length > 0) {
|
package/dist/lib/syncIngest.d.ts
CHANGED
|
@@ -17,3 +17,14 @@ export interface IngestSweepOptions {
|
|
|
17
17
|
* Always-on cheap ingest sweep (agent start + timer). Single-writer lock on local disk.
|
|
18
18
|
*/
|
|
19
19
|
export declare function runMasterIngestSweep(masterPath: string, opts?: IngestSweepOptions): IngestSweepResult;
|
|
20
|
+
/**
|
|
21
|
+
* v13 completion (5.12.x): sweep, then publish a fresh immutable snapshot
|
|
22
|
+
* when the sweep changed the DB (or none has ever been published). Clients
|
|
23
|
+
* read the published snapshot via a verified local copy instead of opening
|
|
24
|
+
* the live gnosys.db over the network — the hazard the design forbids.
|
|
25
|
+
*
|
|
26
|
+
* Kept separate from runMasterIngestSweep: publishMasterSnapshot acquires
|
|
27
|
+
* the same master-ingest lock, so it must run after the sweep releases it,
|
|
28
|
+
* and the sweep itself stays synchronous for existing callers.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runMasterIngestSweepAndPublish(masterPath: string, opts?: IngestSweepOptions): Promise<IngestSweepResult>;
|
package/dist/lib/syncIngest.js
CHANGED
|
@@ -8,7 +8,7 @@ import { getGnosysHome } from "./paths.js";
|
|
|
8
8
|
import { ensureMachineConfig } from "./machineConfig.js";
|
|
9
9
|
import { listPendingStagingQueue, observeStagingFile, parseStagedFile, quarantineStagingFile, quarantineStaleTmpFiles, stagingRoot, verifyMemoryExistsInDb, } from "./syncStaging.js";
|
|
10
10
|
import { assertMasterLeaseHeld, readMasterMarker, touchMasterMarkerHeartbeat, validateLeaseEpochBeforeWrite, } from "./masterLease.js";
|
|
11
|
-
import { acquireWriteLockSync } from "./syncLock.js";
|
|
11
|
+
import { acquireWriteLockSync, } from "./syncLock.js";
|
|
12
12
|
const INGEST_LOCK_NAME = "master-ingest.lock";
|
|
13
13
|
function payloadToMemory(p, now) {
|
|
14
14
|
const contentHash = fnv1a(`${p.title}\n${p.content}`);
|
|
@@ -150,3 +150,26 @@ export function runMasterIngestSweep(masterPath, opts) {
|
|
|
150
150
|
}
|
|
151
151
|
return result;
|
|
152
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* v13 completion (5.12.x): sweep, then publish a fresh immutable snapshot
|
|
155
|
+
* when the sweep changed the DB (or none has ever been published). Clients
|
|
156
|
+
* read the published snapshot via a verified local copy instead of opening
|
|
157
|
+
* the live gnosys.db over the network — the hazard the design forbids.
|
|
158
|
+
*
|
|
159
|
+
* Kept separate from runMasterIngestSweep: publishMasterSnapshot acquires
|
|
160
|
+
* the same master-ingest lock, so it must run after the sweep releases it,
|
|
161
|
+
* and the sweep itself stays synchronous for existing callers.
|
|
162
|
+
*/
|
|
163
|
+
export async function runMasterIngestSweepAndPublish(masterPath, opts) {
|
|
164
|
+
const result = runMasterIngestSweep(masterPath, opts);
|
|
165
|
+
try {
|
|
166
|
+
const { getMasterManifest, publishMasterSnapshot } = await import("./syncSnapshot.js");
|
|
167
|
+
if (result.ingested > 0 || !getMasterManifest(masterPath)) {
|
|
168
|
+
await publishMasterSnapshot(masterPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
result.errors.push(`snapshot publish: ${err instanceof Error ? err.message : String(err)}`);
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GnosysDB } from "./db.js";
|
|
2
2
|
import { readMachineConfig } from "./machineConfig.js";
|
|
3
3
|
import { getConfiguredRemotePath } from "./remote.js";
|
|
4
|
-
import {
|
|
4
|
+
import { runMasterIngestSweepAndPublish } from "./syncIngest.js";
|
|
5
5
|
/**
|
|
6
6
|
* Run one ingest sweep on MCP server startup (master role only).
|
|
7
7
|
* Non-blocking — callers should fire-and-forget.
|
|
@@ -22,7 +22,7 @@ export async function maybeRunStartupIngestSweep() {
|
|
|
22
22
|
}
|
|
23
23
|
if (!masterPath)
|
|
24
24
|
return;
|
|
25
|
-
const result =
|
|
25
|
+
const result = await runMasterIngestSweepAndPublish(masterPath, { quiet: true });
|
|
26
26
|
if (result.errors.length > 0) {
|
|
27
27
|
console.error(`[sync] Startup ingest sweep: ${result.ingested} ingested, ${result.errors.length} error(s)`);
|
|
28
28
|
}
|
|
@@ -11,6 +11,8 @@ export interface SnapshotManifestFile {
|
|
|
11
11
|
}
|
|
12
12
|
export declare function masterSnapshotsDir(masterPath: string): string;
|
|
13
13
|
export declare function clientSnapshotStore(masterPath: string): string;
|
|
14
|
+
/** Read the master's currently published snapshot manifest (null if none). */
|
|
15
|
+
export declare function getMasterManifest(masterPath: string): SnapshotManifestFile | null;
|
|
14
16
|
/** Publish a new immutable snapshot on the master (re-validates lease epoch first). */
|
|
15
17
|
export declare function publishMasterSnapshot(masterPath: string): Promise<SnapshotManifestFile | null>;
|
|
16
18
|
export declare function compareSnapshotVersion(accepted: {
|
package/dist/lib/syncSnapshot.js
CHANGED
|
@@ -34,6 +34,10 @@ function readManifestFile(masterPath) {
|
|
|
34
34
|
return null;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
/** Read the master's currently published snapshot manifest (null if none). */
|
|
38
|
+
export function getMasterManifest(masterPath) {
|
|
39
|
+
return readManifestFile(masterPath);
|
|
40
|
+
}
|
|
37
41
|
function writeManifestFile(masterPath, manifest) {
|
|
38
42
|
const dir = masterSnapshotsDir(masterPath);
|
|
39
43
|
mkdirSync(dir, { recursive: true });
|
|
@@ -34,8 +34,6 @@ export type StagedFileParseResult = {
|
|
|
34
34
|
};
|
|
35
35
|
export declare function stagingRoot(masterPath: string): string;
|
|
36
36
|
export declare function machineStagingDir(masterPath: string, machineId: string): string;
|
|
37
|
-
/** Alias used by remoteWizard and tests. */
|
|
38
|
-
export declare const stagingDirForMachine: typeof machineStagingDir;
|
|
39
37
|
export declare function clientPresencePath(masterPath: string, machineId: string): string;
|
|
40
38
|
export declare function failedQuarantineDir(masterPath: string, machineId: string): string;
|
|
41
39
|
export declare function buildStagingFileName(memoryUlid: string, unixMs?: number): string;
|