@neurodock/cli 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +11 -0
- package/README.md +101 -0
- package/dist/clients/claude-code.d.ts +3 -0
- package/dist/clients/claude-code.d.ts.map +1 -0
- package/dist/clients/claude-code.js +22 -0
- package/dist/clients/claude-code.js.map +1 -0
- package/dist/clients/claude-desktop.d.ts +3 -0
- package/dist/clients/claude-desktop.d.ts.map +1 -0
- package/dist/clients/claude-desktop.js +18 -0
- package/dist/clients/claude-desktop.js.map +1 -0
- package/dist/clients/cursor.d.ts +3 -0
- package/dist/clients/cursor.d.ts.map +1 -0
- package/dist/clients/cursor.js +22 -0
- package/dist/clients/cursor.js.map +1 -0
- package/dist/clients/index.d.ts +17 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +16 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +107 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +189 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/profile.d.ts +14 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +29 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/env.d.ts +11 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +37 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/json-patch.d.ts +22 -0
- package/dist/lib/json-patch.d.ts.map +1 -0
- package/dist/lib/json-patch.js +76 -0
- package/dist/lib/json-patch.js.map +1 -0
- package/dist/lib/mcp-entries.d.ts +9 -0
- package/dist/lib/mcp-entries.d.ts.map +1 -0
- package/dist/lib/mcp-entries.js +56 -0
- package/dist/lib/mcp-entries.js.map +1 -0
- package/dist/lib/paths.d.ts +23 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +91 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/profile/defaults.d.ts +29 -0
- package/dist/profile/defaults.d.ts.map +1 -0
- package/dist/profile/defaults.js +50 -0
- package/dist/profile/defaults.js.map +1 -0
- package/dist/profile/loader.d.ts +23 -0
- package/dist/profile/loader.d.ts.map +1 -0
- package/dist/profile/loader.js +52 -0
- package/dist/profile/loader.js.map +1 -0
- package/dist/profile/validator.d.ts +12 -0
- package/dist/profile/validator.d.ts.map +1 -0
- package/dist/profile/validator.js +62 -0
- package/dist/profile/validator.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEjF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC,CAalE;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAQ1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readEnv } from "../lib/env.js";
|
|
3
|
+
import { profilePath } from "../lib/paths.js";
|
|
4
|
+
import { loadProfileFromFile, renderResolvedYaml } from "../profile/loader.js";
|
|
5
|
+
import { validateProfile } from "../profile/validator.js";
|
|
6
|
+
export async function runProfileValidate() {
|
|
7
|
+
const env = readEnv();
|
|
8
|
+
const p = profilePath(env);
|
|
9
|
+
if (!existsSync(p)) {
|
|
10
|
+
return {
|
|
11
|
+
path: p,
|
|
12
|
+
missing: true,
|
|
13
|
+
result: { valid: false, violations: [{ path: "/", message: "profile file does not exist", keyword: "missing" }] },
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const loaded = loadProfileFromFile(p);
|
|
17
|
+
const result = validateProfile(loaded.raw);
|
|
18
|
+
return { path: p, missing: false, result };
|
|
19
|
+
}
|
|
20
|
+
export async function runProfileShow() {
|
|
21
|
+
const env = readEnv();
|
|
22
|
+
const p = profilePath(env);
|
|
23
|
+
if (!existsSync(p)) {
|
|
24
|
+
return { path: p, yaml: "", missing: true };
|
|
25
|
+
}
|
|
26
|
+
const loaded = loadProfileFromFile(p);
|
|
27
|
+
return { path: p, yaml: renderResolvedYaml(loaded.resolved), missing: false };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAyB,MAAM,yBAAyB,CAAC;AAQjF,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO;YACL,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,6BAA6B,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE;SAClH,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAChF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,wBAAgB,YAAY,IAAI,OAAO,CAwEtC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { runInit } from "./commands/init.js";
|
|
5
|
+
import { runDoctor } from "./commands/doctor.js";
|
|
6
|
+
import { runProfileValidate, runProfileShow } from "./commands/profile.js";
|
|
7
|
+
import { colorEnabled } from "./lib/env.js";
|
|
8
|
+
export const CLI_VERSION = "0.1.0";
|
|
9
|
+
export function buildProgram() {
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name("neurodock")
|
|
13
|
+
.description("NeuroDock installer and diagnostic CLI.")
|
|
14
|
+
.version(CLI_VERSION, "-v, --version", "print the version")
|
|
15
|
+
.helpOption("-h, --help", "show help");
|
|
16
|
+
program
|
|
17
|
+
.command("init")
|
|
18
|
+
.description("install NeuroDock MCP servers into your MCP-aware clients")
|
|
19
|
+
.option("--client <id>", "claude-desktop | claude-code | cursor | all", "all")
|
|
20
|
+
.option("--profile <id>", "minimal | example", "example")
|
|
21
|
+
.option("--dry-run", "print the diff without writing anything", false)
|
|
22
|
+
.option("--yes", "answer yes to all prompts (idempotent re-runs, collisions)", false)
|
|
23
|
+
.action(async (opts) => {
|
|
24
|
+
const client = validateClient(opts.client);
|
|
25
|
+
const profile = validateProfile(opts.profile);
|
|
26
|
+
const result = await runInit({ client, profile, dryRun: opts.dryRun, yes: opts.yes });
|
|
27
|
+
for (const m of result.messages)
|
|
28
|
+
print(m);
|
|
29
|
+
process.exit(0);
|
|
30
|
+
});
|
|
31
|
+
program
|
|
32
|
+
.command("doctor")
|
|
33
|
+
.description("diagnose your NeuroDock installation")
|
|
34
|
+
.action(async () => {
|
|
35
|
+
const r = await runDoctor();
|
|
36
|
+
print("NeuroDock doctor");
|
|
37
|
+
print("");
|
|
38
|
+
for (const c of r.checks)
|
|
39
|
+
print(formatCheck(c));
|
|
40
|
+
print("");
|
|
41
|
+
print(r.ok ? "All checks passed." : "One or more checks failed.");
|
|
42
|
+
process.exit(r.ok ? 0 : 1);
|
|
43
|
+
});
|
|
44
|
+
const profileCmd = program.command("profile").description("profile utilities");
|
|
45
|
+
profileCmd
|
|
46
|
+
.command("validate")
|
|
47
|
+
.description("validate ~/.neurodock/profile.yaml against the schema")
|
|
48
|
+
.action(async () => {
|
|
49
|
+
const r = await runProfileValidate();
|
|
50
|
+
if (r.missing) {
|
|
51
|
+
print(`No profile at ${r.path}. Run 'neurodock init' to create one.`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
if (r.result.valid) {
|
|
55
|
+
print(`Valid: ${r.path}`);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
print(`Invalid: ${r.path}`);
|
|
59
|
+
for (const v of r.result.violations) {
|
|
60
|
+
print(` ${v.path} (${v.keyword}): ${v.message}`);
|
|
61
|
+
}
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
profileCmd
|
|
65
|
+
.command("show")
|
|
66
|
+
.description("print the resolved profile (with loader defaults applied)")
|
|
67
|
+
.action(async () => {
|
|
68
|
+
const r = await runProfileShow();
|
|
69
|
+
if (r.missing) {
|
|
70
|
+
print(`No profile at ${r.path}.`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
process.stdout.write(r.yaml);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
});
|
|
76
|
+
return program;
|
|
77
|
+
}
|
|
78
|
+
function validateClient(value) {
|
|
79
|
+
if (value === "all" || value === "claude-desktop" || value === "claude-code" || value === "cursor") {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Unknown --client value: ${value}`);
|
|
83
|
+
}
|
|
84
|
+
function validateProfile(value) {
|
|
85
|
+
if (value === "minimal" || value === "example")
|
|
86
|
+
return value;
|
|
87
|
+
throw new Error(`Unknown --profile value: ${value}`);
|
|
88
|
+
}
|
|
89
|
+
function print(line) {
|
|
90
|
+
process.stdout.write(`${line}\n`);
|
|
91
|
+
}
|
|
92
|
+
function formatCheck(c) {
|
|
93
|
+
const useColor = colorEnabled();
|
|
94
|
+
const marker = c.status === "PASS"
|
|
95
|
+
? useColor
|
|
96
|
+
? chalk.green("PASS")
|
|
97
|
+
: "PASS"
|
|
98
|
+
: c.status === "FAIL"
|
|
99
|
+
? useColor
|
|
100
|
+
? chalk.red("FAIL")
|
|
101
|
+
: "FAIL"
|
|
102
|
+
: useColor
|
|
103
|
+
? chalk.yellow("SKIP")
|
|
104
|
+
: "SKIP";
|
|
105
|
+
const detail = c.detail ? ` — ${c.detail}` : "";
|
|
106
|
+
return ` [${marker}] ${c.name}${detail}`;
|
|
107
|
+
}
|
|
108
|
+
const isMain = process.argv[1] !== undefined &&
|
|
109
|
+
(process.argv[1].endsWith("index.js") || process.argv[1].endsWith("neurodock"));
|
|
110
|
+
if (isMain) {
|
|
111
|
+
buildProgram().parseAsync(process.argv).catch((err) => {
|
|
112
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
113
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Platform } from "../types.js";
|
|
2
|
+
export interface EnvSnapshot {
|
|
3
|
+
readonly platform: Platform;
|
|
4
|
+
readonly home: string;
|
|
5
|
+
readonly user: string;
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
readonly env: NodeJS.ProcessEnv;
|
|
8
|
+
}
|
|
9
|
+
export declare function readEnv(overrides?: Partial<EnvSnapshot>): EnvSnapshot;
|
|
10
|
+
export declare function colorEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
11
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACjC;AAED,wBAAgB,OAAO,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAOzE;AAoBD,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAQ1E"}
|
package/dist/lib/env.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { homedir, platform, userInfo } from "node:os";
|
|
2
|
+
export function readEnv(overrides = {}) {
|
|
3
|
+
const plat = (overrides.platform ?? platform());
|
|
4
|
+
const home = overrides.home ?? homedir();
|
|
5
|
+
const env = overrides.env ?? process.env;
|
|
6
|
+
const user = overrides.user ?? deriveUser(env);
|
|
7
|
+
const cwd = overrides.cwd ?? process.cwd();
|
|
8
|
+
return { platform: plat, home, user, cwd, env };
|
|
9
|
+
}
|
|
10
|
+
function deriveUser(env) {
|
|
11
|
+
const candidates = [env["USER"], env["USERNAME"], env["LOGNAME"]];
|
|
12
|
+
for (const c of candidates) {
|
|
13
|
+
if (c && c.trim().length > 0) {
|
|
14
|
+
return c.trim();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const info = userInfo();
|
|
19
|
+
if (info.username && info.username.trim().length > 0) {
|
|
20
|
+
return info.username.trim();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// userInfo() can throw on some sandboxes; fall through.
|
|
25
|
+
}
|
|
26
|
+
return "neurodock-user";
|
|
27
|
+
}
|
|
28
|
+
export function colorEnabled(env = process.env) {
|
|
29
|
+
if (env["NO_COLOR"] !== undefined && env["NO_COLOR"] !== "") {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (env["FORCE_COLOR"] !== undefined && env["FORCE_COLOR"] !== "") {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return process.stdout.isTTY === true;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAWtD,MAAM,UAAU,OAAO,CAAC,YAAkC,EAAE;IAC1D,MAAM,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,IAAK,QAAQ,EAAe,CAAa,CAAC;IAC1E,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;IACzC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACzC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,GAAsB;IACxC,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC/D,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,CAAC,aAAa,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { McpClientConfig, McpServerEntry } from "../types.js";
|
|
2
|
+
export interface MergeResult {
|
|
3
|
+
readonly merged: McpClientConfig;
|
|
4
|
+
readonly added: ReadonlyArray<string>;
|
|
5
|
+
readonly collisions: ReadonlyArray<string>;
|
|
6
|
+
readonly unchanged: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Deep-merge MCP server entries into a client config, preserving all unknown
|
|
10
|
+
* top-level keys and never clobbering existing server keys unless `overwrite`
|
|
11
|
+
* is explicitly true. Existing keys go into `collisions`; the caller decides
|
|
12
|
+
* whether to overwrite (with `--yes`) or skip.
|
|
13
|
+
*/
|
|
14
|
+
export declare function mergeMcpServers(current: McpClientConfig | null | undefined, desired: Readonly<Record<string, McpServerEntry>>, overwrite: boolean): MergeResult;
|
|
15
|
+
export declare function parseJsonSafely(source: string): {
|
|
16
|
+
ok: true;
|
|
17
|
+
value: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=json-patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-patch.d.ts","sourceRoot":"","sources":["../../src/lib/json-patch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACjD,SAAS,EAAE,OAAO,GACjB,WAAW,CA8Bb;AA6BD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAO3G"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep-merge MCP server entries into a client config, preserving all unknown
|
|
3
|
+
* top-level keys and never clobbering existing server keys unless `overwrite`
|
|
4
|
+
* is explicitly true. Existing keys go into `collisions`; the caller decides
|
|
5
|
+
* whether to overwrite (with `--yes`) or skip.
|
|
6
|
+
*/
|
|
7
|
+
export function mergeMcpServers(current, desired, overwrite) {
|
|
8
|
+
const base = current ?? {};
|
|
9
|
+
const existingServers = (base.mcpServers ?? {});
|
|
10
|
+
const added = [];
|
|
11
|
+
const collisions = [];
|
|
12
|
+
const nextServers = { ...existingServers };
|
|
13
|
+
for (const [key, entry] of Object.entries(desired)) {
|
|
14
|
+
const existing = existingServers[key];
|
|
15
|
+
if (existing === undefined) {
|
|
16
|
+
nextServers[key] = entry;
|
|
17
|
+
added.push(key);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (serverEntriesEqual(existing, entry)) {
|
|
21
|
+
// no-op
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (overwrite) {
|
|
25
|
+
nextServers[key] = entry;
|
|
26
|
+
added.push(key);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
collisions.push(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const unchanged = added.length === 0 && collisions.length === 0;
|
|
33
|
+
const merged = { ...base, mcpServers: nextServers };
|
|
34
|
+
return { merged, added, collisions, unchanged };
|
|
35
|
+
}
|
|
36
|
+
function serverEntriesEqual(a, b) {
|
|
37
|
+
if (a.command !== b.command)
|
|
38
|
+
return false;
|
|
39
|
+
if (a.cwd !== b.cwd)
|
|
40
|
+
return false;
|
|
41
|
+
if (a.args.length !== b.args.length)
|
|
42
|
+
return false;
|
|
43
|
+
for (let i = 0; i < a.args.length; i += 1) {
|
|
44
|
+
if (a.args[i] !== b.args[i])
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return shallowEnvEqual(a.env, b.env);
|
|
48
|
+
}
|
|
49
|
+
function shallowEnvEqual(a, b) {
|
|
50
|
+
if (a === b)
|
|
51
|
+
return true;
|
|
52
|
+
if (!a || !b)
|
|
53
|
+
return Object.keys(a ?? {}).length === 0 && Object.keys(b ?? {}).length === 0;
|
|
54
|
+
const ka = Object.keys(a).sort();
|
|
55
|
+
const kb = Object.keys(b).sort();
|
|
56
|
+
if (ka.length !== kb.length)
|
|
57
|
+
return false;
|
|
58
|
+
for (let i = 0; i < ka.length; i += 1) {
|
|
59
|
+
if (ka[i] !== kb[i])
|
|
60
|
+
return false;
|
|
61
|
+
const key = ka[i];
|
|
62
|
+
if (a[key] !== b[key])
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
export function parseJsonSafely(source) {
|
|
68
|
+
try {
|
|
69
|
+
return { ok: true, value: JSON.parse(source) };
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73
|
+
return { ok: false, error: message };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=json-patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-patch.js","sourceRoot":"","sources":["../../src/lib/json-patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpServerEntry } from "../types.js";
|
|
2
|
+
import type { EnvSnapshot } from "./env.js";
|
|
3
|
+
export interface McpEntryContext {
|
|
4
|
+
/** Set when the user is running from a cloned monorepo; undefined otherwise. */
|
|
5
|
+
readonly repoRoot?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function detectRepoRoot(env: EnvSnapshot): string | undefined;
|
|
8
|
+
export declare function buildMcpServers(ctx: McpEntryContext): Record<string, McpServerEntry>;
|
|
9
|
+
//# sourceMappingURL=mcp-entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-entries.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-entries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAenE;AAQD,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAsBpF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
export function detectRepoRoot(env) {
|
|
4
|
+
let current = env.cwd;
|
|
5
|
+
// Walk up to 8 levels max — well above any reasonable nested call site.
|
|
6
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
7
|
+
const marker = join(current, "pnpm-workspace.yaml");
|
|
8
|
+
if (existsSync(marker)) {
|
|
9
|
+
return current;
|
|
10
|
+
}
|
|
11
|
+
const parent = dirname(current);
|
|
12
|
+
if (parent === current)
|
|
13
|
+
break;
|
|
14
|
+
current = parent;
|
|
15
|
+
}
|
|
16
|
+
// Also try the directory containing the running script (when packaged the
|
|
17
|
+
// user typically runs from elsewhere and there will be no marker).
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const NEURODOCK_SERVERS = [
|
|
21
|
+
{ key: "neurodock-chronometric", pkg: "mcp-chronometric", entrypoint: "neurodock-mcp-chronometric" },
|
|
22
|
+
{ key: "neurodock-cognitive-graph", pkg: "mcp-cognitive-graph", entrypoint: "neurodock-mcp-cognitive-graph" },
|
|
23
|
+
{ key: "neurodock-task-fractionator", pkg: "mcp-task-fractionator", entrypoint: "neurodock-mcp-task-fractionator" },
|
|
24
|
+
];
|
|
25
|
+
export function buildMcpServers(ctx) {
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const s of NEURODOCK_SERVERS) {
|
|
28
|
+
if (ctx.repoRoot) {
|
|
29
|
+
const pkgPath = resolve(ctx.repoRoot, "packages", s.pkg);
|
|
30
|
+
if (pathIsDir(pkgPath)) {
|
|
31
|
+
out[s.key] = {
|
|
32
|
+
command: "uv",
|
|
33
|
+
args: ["run", s.entrypoint],
|
|
34
|
+
cwd: pkgPath,
|
|
35
|
+
};
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Installed-package fallback. Assumes the user installed the Python
|
|
40
|
+
// distributions globally via `uv tool install` or `pip install`.
|
|
41
|
+
out[s.key] = {
|
|
42
|
+
command: "uv",
|
|
43
|
+
args: ["run", s.entrypoint],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function pathIsDir(p) {
|
|
49
|
+
try {
|
|
50
|
+
return statSync(p).isDirectory();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=mcp-entries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-entries.js","sourceRoot":"","sources":["../../src/lib/mcp-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASnD,MAAM,UAAU,cAAc,CAAC,GAAgB;IAC7C,IAAI,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;IACtB,wEAAwE;IACxE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO;YAAE,MAAM;QAC9B,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,0EAA0E;IAC1E,mEAAmE;IACnE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,iBAAiB,GAAG;IACxB,EAAE,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAE,kBAAkB,EAAE,UAAU,EAAE,4BAA4B,EAAE;IACpG,EAAE,GAAG,EAAE,2BAA2B,EAAE,GAAG,EAAE,qBAAqB,EAAE,UAAU,EAAE,+BAA+B,EAAE;IAC7G,EAAE,GAAG,EAAE,6BAA6B,EAAE,GAAG,EAAE,uBAAuB,EAAE,UAAU,EAAE,iCAAiC,EAAE;CAC3G,CAAC;AAEX,MAAM,UAAU,eAAe,CAAC,GAAoB;IAClD,MAAM,GAAG,GAAmC,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;QAClC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACzD,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;oBACX,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC;oBAC3B,GAAG,EAAE,OAAO;iBACb,CAAC;gBACF,SAAS;YACX,CAAC;QACH,CAAC;QACD,oEAAoE;QACpE,iEAAiE;QACjE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;YACX,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC;SAC5B,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ClientLocation, ClientId } from "../types.js";
|
|
2
|
+
import { type EnvSnapshot } from "./env.js";
|
|
3
|
+
export declare function profilePath(env?: EnvSnapshot): string;
|
|
4
|
+
export declare function profileDir(env?: EnvSnapshot): string;
|
|
5
|
+
export declare function claudeDesktopConfigPath(env?: EnvSnapshot): string;
|
|
6
|
+
export interface ClaudeCodePaths {
|
|
7
|
+
readonly user: string;
|
|
8
|
+
readonly project: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function claudeCodeConfigPaths(env?: EnvSnapshot): ClaudeCodePaths;
|
|
11
|
+
export interface CursorPaths {
|
|
12
|
+
readonly user: string;
|
|
13
|
+
readonly project: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function cursorConfigPaths(env?: EnvSnapshot): CursorPaths;
|
|
16
|
+
export declare function clientLocations(env?: EnvSnapshot): ReadonlyArray<ClientLocation>;
|
|
17
|
+
export interface DetectionResult extends ClientLocation {
|
|
18
|
+
readonly exists: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function detectClients(env?: EnvSnapshot): ReadonlyArray<DetectionResult>;
|
|
21
|
+
export declare function pickClient(detections: ReadonlyArray<DetectionResult>, requested: ClientId | "all"): ReadonlyArray<DetectionResult>;
|
|
22
|
+
export declare function fileExists(p: string): boolean;
|
|
23
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAW,MAAM,UAAU,CAAC;AAErD,wBAAgB,WAAW,CAAC,GAAG,GAAE,WAAuB,GAAG,MAAM,CAchE;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,WAAuB,GAAG,MAAM,CAU/D;AAOD,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,WAAuB,GAAG,MAAM,CAY5E;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,WAAuB,GAAG,eAAe,CAKnF;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,WAAuB,GAAG,WAAW,CAK3E;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,WAAuB,GAAG,aAAa,CAAC,cAAc,CAAC,CAU3F;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,GAAG,GAAE,WAAuB,GAAG,aAAa,CAAC,eAAe,CAAC,CAE1F;AAED,wBAAgB,UAAU,CACxB,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,EAC1C,SAAS,EAAE,QAAQ,GAAG,KAAK,GAC1B,aAAa,CAAC,eAAe,CAAC,CAKhC;AAWD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE7C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, statSync } from "node:fs";
|
|
3
|
+
import { readEnv } from "./env.js";
|
|
4
|
+
export function profilePath(env = readEnv()) {
|
|
5
|
+
// Loader precedence (see profile.schema.json $comment):
|
|
6
|
+
// 1. $NEURODOCK_PROFILE_PATH
|
|
7
|
+
// 2. $XDG_CONFIG_HOME/neurodock/profile.yaml
|
|
8
|
+
// 3. ~/.neurodock/profile.yaml
|
|
9
|
+
const override = env.env["NEURODOCK_PROFILE_PATH"];
|
|
10
|
+
if (override && override.trim().length > 0) {
|
|
11
|
+
return override;
|
|
12
|
+
}
|
|
13
|
+
const xdg = env.env["XDG_CONFIG_HOME"];
|
|
14
|
+
if (xdg && xdg.trim().length > 0) {
|
|
15
|
+
return join(xdg, "neurodock", "profile.yaml");
|
|
16
|
+
}
|
|
17
|
+
return join(env.home, ".neurodock", "profile.yaml");
|
|
18
|
+
}
|
|
19
|
+
export function profileDir(env = readEnv()) {
|
|
20
|
+
const override = env.env["NEURODOCK_PROFILE_PATH"];
|
|
21
|
+
if (override && override.trim().length > 0) {
|
|
22
|
+
return dirOf(override);
|
|
23
|
+
}
|
|
24
|
+
const xdg = env.env["XDG_CONFIG_HOME"];
|
|
25
|
+
if (xdg && xdg.trim().length > 0) {
|
|
26
|
+
return join(xdg, "neurodock");
|
|
27
|
+
}
|
|
28
|
+
return join(env.home, ".neurodock");
|
|
29
|
+
}
|
|
30
|
+
function dirOf(filePath) {
|
|
31
|
+
const idx = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\"));
|
|
32
|
+
return idx <= 0 ? "." : filePath.slice(0, idx);
|
|
33
|
+
}
|
|
34
|
+
export function claudeDesktopConfigPath(env = readEnv()) {
|
|
35
|
+
switch (env.platform) {
|
|
36
|
+
case "darwin":
|
|
37
|
+
return join(env.home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
38
|
+
case "win32": {
|
|
39
|
+
const appdata = env.env["APPDATA"];
|
|
40
|
+
const root = appdata && appdata.trim().length > 0 ? appdata : join(env.home, "AppData", "Roaming");
|
|
41
|
+
return join(root, "Claude", "claude_desktop_config.json");
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
return join(env.home, ".config", "Claude", "claude_desktop_config.json");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function claudeCodeConfigPaths(env = readEnv()) {
|
|
48
|
+
return {
|
|
49
|
+
user: join(env.home, ".claude", "settings.json"),
|
|
50
|
+
project: join(env.cwd, ".claude", "settings.json"),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function cursorConfigPaths(env = readEnv()) {
|
|
54
|
+
return {
|
|
55
|
+
user: join(env.home, ".cursor", "mcp.json"),
|
|
56
|
+
project: join(env.cwd, ".cursor", "mcp.json"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function clientLocations(env = readEnv()) {
|
|
60
|
+
const cc = claudeCodeConfigPaths(env);
|
|
61
|
+
const cu = cursorConfigPaths(env);
|
|
62
|
+
return [
|
|
63
|
+
{ id: "claude-desktop", path: claudeDesktopConfigPath(env), scope: "user" },
|
|
64
|
+
{ id: "claude-code", path: cc.project, scope: "project" },
|
|
65
|
+
{ id: "claude-code", path: cc.user, scope: "user" },
|
|
66
|
+
{ id: "cursor", path: cu.project, scope: "project" },
|
|
67
|
+
{ id: "cursor", path: cu.user, scope: "user" },
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
export function detectClients(env = readEnv()) {
|
|
71
|
+
return clientLocations(env).map((loc) => ({ ...loc, exists: pathExists(loc.path) }));
|
|
72
|
+
}
|
|
73
|
+
export function pickClient(detections, requested) {
|
|
74
|
+
if (requested === "all") {
|
|
75
|
+
return detections;
|
|
76
|
+
}
|
|
77
|
+
return detections.filter((d) => d.id === requested);
|
|
78
|
+
}
|
|
79
|
+
function pathExists(p) {
|
|
80
|
+
try {
|
|
81
|
+
statSync(p);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function fileExists(p) {
|
|
89
|
+
return existsSync(p);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ProfileDefaults {
|
|
2
|
+
readonly preferences: {
|
|
3
|
+
readonly output_format: string;
|
|
4
|
+
readonly max_chunk_size: number;
|
|
5
|
+
readonly reading_font_hint: string;
|
|
6
|
+
readonly motion: string;
|
|
7
|
+
};
|
|
8
|
+
readonly chronometric: {
|
|
9
|
+
readonly hyperfocus_break_minutes: number;
|
|
10
|
+
readonly session_overlap_policy: string;
|
|
11
|
+
};
|
|
12
|
+
readonly guardrails: {
|
|
13
|
+
readonly rumination_threshold: number;
|
|
14
|
+
readonly rumination_window_minutes: number;
|
|
15
|
+
readonly sycophancy_check: string;
|
|
16
|
+
};
|
|
17
|
+
readonly privacy: {
|
|
18
|
+
readonly embeddings: string;
|
|
19
|
+
readonly telemetry: string;
|
|
20
|
+
readonly os_idle_consent: boolean;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare const PROFILE_DEFAULTS: ProfileDefaults;
|
|
24
|
+
/**
|
|
25
|
+
* Returns a NEW object — never mutates input. Applies defaults only when a
|
|
26
|
+
* field is absent. Unknown keys at every level are preserved.
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyDefaults(raw: unknown): Record<string, unknown>;
|
|
29
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/profile/defaults.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;QAC1C,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;KACzC,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;QAC3C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;KACnC,CAAC;CACH;AAED,eAAO,MAAM,gBAAgB,EAAE,eAqB9B,CAAC;AAMF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Loader-applied defaults per ADR 0004 §15. The schema declares these as
|
|
2
|
+
// `default` values, but JSON Schema validation does not apply defaults — the
|
|
3
|
+
// loader must. Keep this table in sync with profile.schema.json.
|
|
4
|
+
export const PROFILE_DEFAULTS = {
|
|
5
|
+
preferences: {
|
|
6
|
+
output_format: "answer_first",
|
|
7
|
+
max_chunk_size: 7,
|
|
8
|
+
reading_font_hint: "atkinson_hyperlegible",
|
|
9
|
+
motion: "reduced",
|
|
10
|
+
},
|
|
11
|
+
chronometric: {
|
|
12
|
+
hyperfocus_break_minutes: 90,
|
|
13
|
+
session_overlap_policy: "auto_close",
|
|
14
|
+
},
|
|
15
|
+
guardrails: {
|
|
16
|
+
rumination_threshold: 3,
|
|
17
|
+
rumination_window_minutes: 90,
|
|
18
|
+
sycophancy_check: "warn",
|
|
19
|
+
},
|
|
20
|
+
privacy: {
|
|
21
|
+
embeddings: "local",
|
|
22
|
+
telemetry: "off",
|
|
23
|
+
os_idle_consent: false,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
function isObject(x) {
|
|
27
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns a NEW object — never mutates input. Applies defaults only when a
|
|
31
|
+
* field is absent. Unknown keys at every level are preserved.
|
|
32
|
+
*/
|
|
33
|
+
export function applyDefaults(raw) {
|
|
34
|
+
const out = isObject(raw) ? { ...raw } : {};
|
|
35
|
+
out["preferences"] = mergeBlock(out["preferences"], PROFILE_DEFAULTS.preferences);
|
|
36
|
+
out["chronometric"] = mergeBlock(out["chronometric"], PROFILE_DEFAULTS.chronometric);
|
|
37
|
+
out["guardrails"] = mergeBlock(out["guardrails"], PROFILE_DEFAULTS.guardrails);
|
|
38
|
+
out["privacy"] = mergeBlock(out["privacy"], PROFILE_DEFAULTS.privacy);
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function mergeBlock(existing, defaults) {
|
|
42
|
+
const base = isObject(existing) ? { ...existing } : {};
|
|
43
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
44
|
+
if (!(key in base) || base[key] === undefined || base[key] === null) {
|
|
45
|
+
base[key] = value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return base;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=defaults.js.map
|