@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @neurodock/cli changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (unreleased)
|
|
4
|
+
|
|
5
|
+
First implementation. Phase 1 deliverable per .
|
|
6
|
+
|
|
7
|
+
- `neurodock init` — detect Claude Desktop, Claude Code, and Cursor on macOS, Linux, and Windows; install profile from `profile.example.yaml` (default) or `profile.minimal.yaml`; wire three Python MCP servers into the detected client configs.
|
|
8
|
+
- `neurodock doctor` — checklist diagnostic: Node >= 22, `uv` available, Python available, profile presence + schema validity, client config JSON syntax, NeuroDock server wiring.
|
|
9
|
+
- `neurodock profile validate` — Ajv-driven schema validation with field-path violation output.
|
|
10
|
+
- `neurodock profile show` — print the resolved profile with loader defaults applied (per ADR 0004 §15).
|
|
11
|
+
- `--dry-run` and `--yes` flags on `init`.
|
|
12
|
+
- Preserves existing `mcpServers` keys, comments in profile YAML, and unknown top-level keys (forward-compat per ADR 0004).
|
|
13
|
+
- 24+ unit tests across paths, validator, defaults, client adapters, init, and doctor.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
NeuroDock is licensed under the GNU Affero General Public License v3.0 or later.
|
|
2
|
+
|
|
3
|
+
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
The canonical license text is available at:
|
|
6
|
+
https://www.gnu.org/licenses/agpl-3.0.txt
|
|
7
|
+
|
|
8
|
+
A local copy can be added by running:
|
|
9
|
+
curl -o LICENSE-AGPL-3.0 https://www.gnu.org/licenses/agpl-3.0.txt
|
|
10
|
+
|
|
11
|
+
License intent confirmed by the founding council at first meeting (see GOVERNANCE.md).
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# @neurodock/cli
|
|
2
|
+
|
|
3
|
+
The `neurodock` installer and diagnostic CLI.
|
|
4
|
+
|
|
5
|
+
Status: Phase 1 (v0.1 developer preview).
|
|
6
|
+
|
|
7
|
+
## Quickstart
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# From a published package once it lands on npm:
|
|
11
|
+
npx neurodock init
|
|
12
|
+
|
|
13
|
+
# From a fresh clone of the monorepo:
|
|
14
|
+
pnpm install
|
|
15
|
+
pnpm --filter @neurodock/cli build
|
|
16
|
+
node packages/cli/dist/index.js init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`neurodock init` wires three Python MCP servers (chronometric, cognitive-graph,
|
|
20
|
+
task-fractionator) into every MCP-aware client it can detect.
|
|
21
|
+
|
|
22
|
+
**Prerequisite:** the CLI does not install Python deps for you. From a clone
|
|
23
|
+
run `uv sync` (or `pip install -e packages/mcp-chronometric` etc.) so the
|
|
24
|
+
`neurodock-mcp-*` console entry points are on `$PATH` for `uv run`. From a
|
|
25
|
+
published install this matures into `uv tool install neurodock-mcp-*`.
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
| Command | What it does |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `neurodock init` | Install MCP servers into Claude Desktop / Claude Code / Cursor. |
|
|
32
|
+
| `neurodock doctor` | Diagnose your install — profile validity, client wiring, tool availability. |
|
|
33
|
+
| `neurodock profile validate` | Validate `~/.neurodock/profile.yaml` against the v0.1 schema. |
|
|
34
|
+
| `neurodock profile show` | Print the resolved profile with loader defaults applied. |
|
|
35
|
+
|
|
36
|
+
### `neurodock init`
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
neurodock init [--client=claude-desktop|claude-code|cursor|all] \
|
|
40
|
+
[--profile=minimal|example] \
|
|
41
|
+
[--dry-run] [--yes]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- `--client` defaults to `all`. With `all` we only act on already-existing client configs.
|
|
45
|
+
- `--profile` defaults to `example` (the worked "T" profile). Use `minimal` for the shortest valid file.
|
|
46
|
+
- `--dry-run` prints the diff and exits 0.
|
|
47
|
+
- `--yes` overwrites colliding `mcpServers` keys without prompting.
|
|
48
|
+
|
|
49
|
+
What `init` does, in order:
|
|
50
|
+
|
|
51
|
+
1. Detects supported clients per platform (see "Detection locations" below).
|
|
52
|
+
2. Copies `profile.example.yaml` or `profile.minimal.yaml` to `~/.neurodock/profile.yaml` if it does not already exist. Sets `identity.display_name` from `$USER` / `%USERNAME%`.
|
|
53
|
+
3. Adds three `mcpServers` entries (`neurodock-chronometric`, `neurodock-cognitive-graph`, `neurodock-task-fractionator`) to each detected client's config.
|
|
54
|
+
4. Preserves all unrelated keys, comments, and unknown server entries already in those configs.
|
|
55
|
+
|
|
56
|
+
Idempotent. Re-running with no changes is a no-op. Collisions on a previous
|
|
57
|
+
key are skipped unless `--yes` is supplied.
|
|
58
|
+
|
|
59
|
+
### Detection locations
|
|
60
|
+
|
|
61
|
+
| Client | Platform | Path |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| Claude Desktop | macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
64
|
+
| Claude Desktop | Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
65
|
+
| Claude Desktop | Linux | `~/.config/Claude/claude_desktop_config.json` |
|
|
66
|
+
| Claude Code | All | `./.claude/settings.json` (project, preferred) then `~/.claude/settings.json` (user) |
|
|
67
|
+
| Cursor | All | `./.cursor/mcp.json` (project, preferred) then `~/.cursor/mcp.json` (user) |
|
|
68
|
+
|
|
69
|
+
### Profile precedence
|
|
70
|
+
|
|
71
|
+
Loader precedence (highest first):
|
|
72
|
+
|
|
73
|
+
1. `$NEURODOCK_PROFILE_PATH`
|
|
74
|
+
2. `$XDG_CONFIG_HOME/neurodock/profile.yaml`
|
|
75
|
+
3. `~/.neurodock/profile.yaml`
|
|
76
|
+
|
|
77
|
+
## Build and test
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd packages/cli
|
|
81
|
+
pnpm install
|
|
82
|
+
pnpm run typecheck
|
|
83
|
+
pnpm run test
|
|
84
|
+
pnpm run build
|
|
85
|
+
node dist/index.js --version
|
|
86
|
+
node dist/index.js --help
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Design notes
|
|
90
|
+
|
|
91
|
+
- Strict TypeScript, NodeNext modules, ES2022 target.
|
|
92
|
+
- Profile YAML round-trip preserves comments (the `yaml` package's
|
|
93
|
+
`parseDocument` API), per ADR 0004 §14.
|
|
94
|
+
- All loader defaults live in `src/profile/defaults.ts` and mirror
|
|
95
|
+
`profile.schema.json` — JSON Schema validation does not apply defaults
|
|
96
|
+
itself, so the loader does.
|
|
97
|
+
- No telemetry, no remote calls, no auto-install of Python packages.
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
AGPL-3.0-or-later.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/clients/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,eAAO,MAAM,iBAAiB,EAAE,aAgB/B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { claudeCodeConfigPaths } from "../lib/paths.js";
|
|
2
|
+
export const claudeCodeAdapter = {
|
|
3
|
+
id: "claude-code",
|
|
4
|
+
displayName: "Claude Code",
|
|
5
|
+
configPaths(env) {
|
|
6
|
+
const paths = claudeCodeConfigPaths(env);
|
|
7
|
+
return [
|
|
8
|
+
{ path: paths.project, scope: "project" },
|
|
9
|
+
{ path: paths.user, scope: "user" },
|
|
10
|
+
];
|
|
11
|
+
},
|
|
12
|
+
shapeConfig(existing, mcpServers) {
|
|
13
|
+
const base = isObject(existing) ? { ...existing } : {};
|
|
14
|
+
const prev = isObject(base["mcpServers"]) ? base["mcpServers"] : {};
|
|
15
|
+
base["mcpServers"] = { ...prev, ...mcpServers };
|
|
16
|
+
return base;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
function isObject(x) {
|
|
20
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/clients/claude-code.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,EAAE,EAAE,aAAa;IACjB,WAAW,EAAE,aAAa;IAC1B,WAAW,CAAC,GAAG;QACb,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACzC,OAAO;YACL,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;YACzC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;SACpC,CAAC;IACJ,CAAC;IACD,WAAW,CAAC,QAAQ,EAAE,UAAU;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAoC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/clients/claude-desktop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,eAAO,MAAM,oBAAoB,EAAE,aAYlC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { claudeDesktopConfigPath } from "../lib/paths.js";
|
|
2
|
+
export const claudeDesktopAdapter = {
|
|
3
|
+
id: "claude-desktop",
|
|
4
|
+
displayName: "Claude Desktop",
|
|
5
|
+
configPaths(env) {
|
|
6
|
+
return [{ path: claudeDesktopConfigPath(env), scope: "user" }];
|
|
7
|
+
},
|
|
8
|
+
shapeConfig(existing, mcpServers) {
|
|
9
|
+
const base = isObject(existing) ? { ...existing } : {};
|
|
10
|
+
const prev = isObject(base["mcpServers"]) ? base["mcpServers"] : {};
|
|
11
|
+
base["mcpServers"] = { ...prev, ...mcpServers };
|
|
12
|
+
return base;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
function isObject(x) {
|
|
16
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=claude-desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/clients/claude-desktop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,CAAC,MAAM,oBAAoB,GAAkB;IACjD,EAAE,EAAE,gBAAgB;IACpB,WAAW,EAAE,gBAAgB;IAC7B,WAAW,CAAC,GAAG;QACb,OAAO,CAAC,EAAE,IAAI,EAAE,uBAAuB,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,WAAW,CAAC,QAAQ,EAAE,UAAU;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAoC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/clients/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,eAAO,MAAM,aAAa,EAAE,aAgB3B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cursorConfigPaths } from "../lib/paths.js";
|
|
2
|
+
export const cursorAdapter = {
|
|
3
|
+
id: "cursor",
|
|
4
|
+
displayName: "Cursor",
|
|
5
|
+
configPaths(env) {
|
|
6
|
+
const paths = cursorConfigPaths(env);
|
|
7
|
+
return [
|
|
8
|
+
{ path: paths.project, scope: "project" },
|
|
9
|
+
{ path: paths.user, scope: "user" },
|
|
10
|
+
];
|
|
11
|
+
},
|
|
12
|
+
shapeConfig(existing, mcpServers) {
|
|
13
|
+
const base = isObject(existing) ? { ...existing } : {};
|
|
14
|
+
const prev = isObject(base["mcpServers"]) ? base["mcpServers"] : {};
|
|
15
|
+
base["mcpServers"] = { ...prev, ...mcpServers };
|
|
16
|
+
return base;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
function isObject(x) {
|
|
20
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/clients/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,QAAQ;IACrB,WAAW,CAAC,GAAG;QACb,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO;YACL,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;YACzC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;SACpC,CAAC;IACJ,CAAC;IACD,WAAW,CAAC,QAAQ,EAAE,UAAU;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAoC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ClientId, McpServerEntry } from "../types.js";
|
|
2
|
+
import type { EnvSnapshot } from "../lib/env.js";
|
|
3
|
+
export interface ClientAdapter {
|
|
4
|
+
readonly id: ClientId;
|
|
5
|
+
readonly displayName: string;
|
|
6
|
+
/** Possible config file locations, highest precedence first. */
|
|
7
|
+
configPaths(env: EnvSnapshot): ReadonlyArray<ConfigCandidate>;
|
|
8
|
+
/** Wrap an mcpServers map into the shape this client expects. */
|
|
9
|
+
shapeConfig(existing: unknown, mcpServers: Record<string, McpServerEntry>): unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface ConfigCandidate {
|
|
12
|
+
readonly path: string;
|
|
13
|
+
readonly scope: "user" | "project";
|
|
14
|
+
}
|
|
15
|
+
export declare const allAdapters: ReadonlyArray<ClientAdapter>;
|
|
16
|
+
export declare function adapterFor(id: ClientId): ClientAdapter;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,gEAAgE;IAChE,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9D,iEAAiE;IACjE,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC;CACrF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAIpD,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,CAMtD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { claudeDesktopAdapter } from "./claude-desktop.js";
|
|
2
|
+
import { claudeCodeAdapter } from "./claude-code.js";
|
|
3
|
+
import { cursorAdapter } from "./cursor.js";
|
|
4
|
+
export const allAdapters = [
|
|
5
|
+
claudeDesktopAdapter,
|
|
6
|
+
claudeCodeAdapter,
|
|
7
|
+
cursorAdapter,
|
|
8
|
+
];
|
|
9
|
+
export function adapterFor(id) {
|
|
10
|
+
const found = allAdapters.find((a) => a.id === id);
|
|
11
|
+
if (!found) {
|
|
12
|
+
throw new Error(`Unknown client id: ${id}`);
|
|
13
|
+
}
|
|
14
|
+
return found;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgB5C,MAAM,CAAC,MAAM,WAAW,GAAiC;IACvD,oBAAoB;IACpB,iBAAiB;IACjB,aAAa;CACd,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,EAAY;IACrC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CA8EvD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { readEnv } from "../lib/env.js";
|
|
4
|
+
import { profilePath, detectClients } from "../lib/paths.js";
|
|
5
|
+
import { loadProfileFromFile } from "../profile/loader.js";
|
|
6
|
+
import { validateProfile } from "../profile/validator.js";
|
|
7
|
+
import { parseJsonSafely } from "../lib/json-patch.js";
|
|
8
|
+
export async function runDoctor() {
|
|
9
|
+
const env = readEnv();
|
|
10
|
+
const checks = [];
|
|
11
|
+
checks.push(checkNodeVersion());
|
|
12
|
+
checks.push(checkCommandAvailable("uv", ["--version"]));
|
|
13
|
+
checks.push(checkCommandAvailable("python3", ["--version"], "python3 or python >= 3.11"));
|
|
14
|
+
// Profile presence + validity.
|
|
15
|
+
const pPath = profilePath(env);
|
|
16
|
+
if (!existsSync(pPath)) {
|
|
17
|
+
checks.push({
|
|
18
|
+
name: "Profile exists",
|
|
19
|
+
status: "FAIL",
|
|
20
|
+
detail: `No profile at ${pPath}. Run 'neurodock init' to create one.`,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
checks.push({ name: "Profile exists", status: "PASS", detail: pPath });
|
|
25
|
+
try {
|
|
26
|
+
const loaded = loadProfileFromFile(pPath);
|
|
27
|
+
const result = validateProfile(loaded.raw);
|
|
28
|
+
if (result.valid) {
|
|
29
|
+
checks.push({ name: "Profile schema valid", status: "PASS" });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
checks.push({
|
|
33
|
+
name: "Profile schema valid",
|
|
34
|
+
status: "FAIL",
|
|
35
|
+
detail: result.violations.map((v) => `${v.path}: ${v.message}`).join("; "),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
checks.push({
|
|
41
|
+
name: "Profile schema valid",
|
|
42
|
+
status: "FAIL",
|
|
43
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Client configs syntax check.
|
|
48
|
+
const detections = detectClients(env);
|
|
49
|
+
const existing = detections.filter((d) => d.exists);
|
|
50
|
+
if (existing.length === 0) {
|
|
51
|
+
checks.push({
|
|
52
|
+
name: "Client configs",
|
|
53
|
+
status: "SKIP",
|
|
54
|
+
detail: "No supported client config found. Skipping wiring check.",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
for (const d of existing) {
|
|
59
|
+
const raw = readFileSync(d.path, "utf8");
|
|
60
|
+
const parsed = parseJsonSafely(raw);
|
|
61
|
+
if (!parsed.ok) {
|
|
62
|
+
checks.push({
|
|
63
|
+
name: `Client config syntax: ${d.id} (${d.scope})`,
|
|
64
|
+
status: "FAIL",
|
|
65
|
+
detail: `${d.path}: ${parsed.error}`,
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
checks.push({
|
|
70
|
+
name: `Client config syntax: ${d.id} (${d.scope})`,
|
|
71
|
+
status: "PASS",
|
|
72
|
+
detail: d.path,
|
|
73
|
+
});
|
|
74
|
+
const cfg = (parsed.value ?? {});
|
|
75
|
+
const servers = cfg.mcpServers ?? {};
|
|
76
|
+
const wired = Object.keys(servers).filter((k) => k.startsWith("neurodock-"));
|
|
77
|
+
checks.push({
|
|
78
|
+
name: `NeuroDock servers wired: ${d.id} (${d.scope})`,
|
|
79
|
+
status: wired.length > 0 ? "PASS" : "FAIL",
|
|
80
|
+
detail: wired.length > 0 ? wired.join(", ") : "no neurodock-* entries found",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const ok = checks.every((c) => c.status !== "FAIL");
|
|
85
|
+
return { checks, ok };
|
|
86
|
+
}
|
|
87
|
+
function checkNodeVersion() {
|
|
88
|
+
const v = process.versions.node;
|
|
89
|
+
const major = Number.parseInt(v.split(".")[0] ?? "0", 10);
|
|
90
|
+
if (Number.isFinite(major) && major >= 22) {
|
|
91
|
+
return { name: "Node >= 22", status: "PASS", detail: `node ${v}` };
|
|
92
|
+
}
|
|
93
|
+
return { name: "Node >= 22", status: "FAIL", detail: `node ${v}` };
|
|
94
|
+
}
|
|
95
|
+
function checkCommandAvailable(cmd, args, label) {
|
|
96
|
+
const name = label ?? `${cmd} available`;
|
|
97
|
+
try {
|
|
98
|
+
const out = execFileSync(cmd, args, { stdio: ["ignore", "pipe", "pipe"], timeout: 4000 });
|
|
99
|
+
const text = out.toString().trim().split("\n")[0] ?? "";
|
|
100
|
+
return { name, status: "PASS", detail: text };
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const detail = err instanceof Error ? err.message.split("\n")[0] ?? "unknown error" : String(err);
|
|
104
|
+
return { name, status: "FAIL", detail };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { InitDiff, InitOptions } from "../types.js";
|
|
2
|
+
import { readEnv } from "../lib/env.js";
|
|
3
|
+
export interface InitRunResult {
|
|
4
|
+
readonly diff: InitDiff;
|
|
5
|
+
readonly applied: boolean;
|
|
6
|
+
readonly messages: ReadonlyArray<string>;
|
|
7
|
+
}
|
|
8
|
+
export interface InitDependencies {
|
|
9
|
+
/** Override the environment snapshot (for tests). */
|
|
10
|
+
readonly envOverrides?: Parameters<typeof readEnv>[0];
|
|
11
|
+
}
|
|
12
|
+
export declare function runInit(options: InitOptions, deps?: InitDependencies): Promise<InitRunResult>;
|
|
13
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,QAAQ,EACR,WAAW,EAEZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;CACvD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC,CAgGvG"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { readEnv } from "../lib/env.js";
|
|
5
|
+
import { profilePath, detectClients } from "../lib/paths.js";
|
|
6
|
+
import { adapterFor } from "../clients/index.js";
|
|
7
|
+
import { mergeMcpServers, parseJsonSafely } from "../lib/json-patch.js";
|
|
8
|
+
import { writeProfileFromTemplate } from "../profile/loader.js";
|
|
9
|
+
import { buildMcpServers, detectRepoRoot } from "../lib/mcp-entries.js";
|
|
10
|
+
export async function runInit(options, deps = {}) {
|
|
11
|
+
const env = readEnv(deps.envOverrides ?? {});
|
|
12
|
+
const messages = [];
|
|
13
|
+
// 1. Detect clients.
|
|
14
|
+
const detections = detectClients(env);
|
|
15
|
+
const targets = pickTargets(detections, options.client);
|
|
16
|
+
const detectedTargets = targets.filter((t) => t.exists);
|
|
17
|
+
if (options.client !== "all" && targets.length === 0) {
|
|
18
|
+
messages.push(`No supported client locations exist for '${options.client}'.`);
|
|
19
|
+
}
|
|
20
|
+
if (options.client === "all" && detectedTargets.length === 0) {
|
|
21
|
+
messages.push("No supported MCP client detected.");
|
|
22
|
+
messages.push("Looked for:");
|
|
23
|
+
for (const t of targets) {
|
|
24
|
+
messages.push(` - ${t.id} (${t.scope}): ${t.path}`);
|
|
25
|
+
}
|
|
26
|
+
messages.push("See: https://docs.neurodock.org/install#supported-clients");
|
|
27
|
+
return {
|
|
28
|
+
diff: { profileAction: "skipped", profilePath: profilePath(env), clients: [] },
|
|
29
|
+
applied: false,
|
|
30
|
+
messages,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// 2. Build the desired mcpServers entries once.
|
|
34
|
+
const repoRoot = detectRepoRoot(env);
|
|
35
|
+
const desiredServers = buildMcpServers({
|
|
36
|
+
...(repoRoot !== undefined ? { repoRoot } : {}),
|
|
37
|
+
});
|
|
38
|
+
// 3. Profile.
|
|
39
|
+
const pPath = profilePath(env);
|
|
40
|
+
const profileAction = existsSync(pPath) ? "exists" : "create";
|
|
41
|
+
// 4. Per-client diff.
|
|
42
|
+
const clientDiffs = [];
|
|
43
|
+
// For "all" mode, only act on already-existing locations; for explicit
|
|
44
|
+
// client choice, act on the highest-precedence path even if absent.
|
|
45
|
+
const actOn = options.client === "all" ? detectedTargets : targets.slice(0, 1);
|
|
46
|
+
for (const target of actOn) {
|
|
47
|
+
const diff = await diffClient(target, desiredServers, options);
|
|
48
|
+
clientDiffs.push(diff);
|
|
49
|
+
}
|
|
50
|
+
const diff = {
|
|
51
|
+
profileAction,
|
|
52
|
+
profilePath: pPath,
|
|
53
|
+
clients: clientDiffs,
|
|
54
|
+
};
|
|
55
|
+
if (options.dryRun) {
|
|
56
|
+
return {
|
|
57
|
+
diff,
|
|
58
|
+
applied: false,
|
|
59
|
+
messages: ["Dry run. No changes written.", ...messages, ...formatDiff(diff)],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// 5. Apply.
|
|
63
|
+
// 5a. Profile.
|
|
64
|
+
if (profileAction === "create") {
|
|
65
|
+
const templatePath = resolveTemplatePath(options.profile);
|
|
66
|
+
writeProfileFromTemplate({
|
|
67
|
+
templatePath,
|
|
68
|
+
targetPath: pPath,
|
|
69
|
+
displayName: env.user,
|
|
70
|
+
});
|
|
71
|
+
messages.push(`Profile created at ${pPath}.`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
messages.push(`Profile already exists at ${pPath}. Left untouched.`);
|
|
75
|
+
}
|
|
76
|
+
// 5b. Client configs.
|
|
77
|
+
for (const cd of clientDiffs) {
|
|
78
|
+
if (cd.action === "create" || cd.action === "update") {
|
|
79
|
+
applyClientDiff(cd, desiredServers, options.yes);
|
|
80
|
+
messages.push(`Wired ${cd.client} at ${cd.path}.`);
|
|
81
|
+
}
|
|
82
|
+
else if (cd.action === "no-change") {
|
|
83
|
+
messages.push(`${cd.client} already wired at ${cd.path}.`);
|
|
84
|
+
}
|
|
85
|
+
else if (cd.action === "skip") {
|
|
86
|
+
messages.push(`Skipped ${cd.client} at ${cd.path}: ${cd.reason ?? "collision (re-run with --yes to overwrite)"}.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 5c. What-next.
|
|
90
|
+
messages.push("");
|
|
91
|
+
messages.push("What next:");
|
|
92
|
+
messages.push(" 1. Restart your MCP client so it picks up the new servers.");
|
|
93
|
+
messages.push(` 2. Edit ${pPath} to set your neurotypes and preferences.`);
|
|
94
|
+
return { diff, applied: true, messages };
|
|
95
|
+
}
|
|
96
|
+
function pickTargets(detections, client) {
|
|
97
|
+
if (client === "all")
|
|
98
|
+
return detections;
|
|
99
|
+
return detections.filter((d) => d.id === client);
|
|
100
|
+
}
|
|
101
|
+
async function diffClient(target, desired, options) {
|
|
102
|
+
let existing = null;
|
|
103
|
+
if (existsSync(target.path)) {
|
|
104
|
+
const raw = readFileSync(target.path, "utf8");
|
|
105
|
+
const parsed = parseJsonSafely(raw);
|
|
106
|
+
if (!parsed.ok) {
|
|
107
|
+
return {
|
|
108
|
+
client: target.id,
|
|
109
|
+
path: target.path,
|
|
110
|
+
action: "skip",
|
|
111
|
+
added: [],
|
|
112
|
+
collisions: [],
|
|
113
|
+
reason: `existing config is not valid JSON: ${parsed.error}`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
existing = parsed.value ?? {};
|
|
117
|
+
}
|
|
118
|
+
const merge = mergeMcpServers((existing ?? {}), desired, options.yes);
|
|
119
|
+
if (merge.collisions.length > 0 && !options.yes) {
|
|
120
|
+
return {
|
|
121
|
+
client: target.id,
|
|
122
|
+
path: target.path,
|
|
123
|
+
action: "skip",
|
|
124
|
+
added: merge.added,
|
|
125
|
+
collisions: merge.collisions,
|
|
126
|
+
reason: "existing keys would be overwritten; re-run with --yes to confirm",
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (merge.unchanged && existing !== null) {
|
|
130
|
+
return {
|
|
131
|
+
client: target.id,
|
|
132
|
+
path: target.path,
|
|
133
|
+
action: "no-change",
|
|
134
|
+
added: [],
|
|
135
|
+
collisions: [],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
client: target.id,
|
|
140
|
+
path: target.path,
|
|
141
|
+
action: existing === null ? "create" : "update",
|
|
142
|
+
added: merge.added,
|
|
143
|
+
collisions: merge.collisions,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function applyClientDiff(cd, desired, overwrite) {
|
|
147
|
+
const adapter = adapterFor(cd.client);
|
|
148
|
+
let existing = null;
|
|
149
|
+
if (existsSync(cd.path)) {
|
|
150
|
+
const raw = readFileSync(cd.path, "utf8");
|
|
151
|
+
const parsed = parseJsonSafely(raw);
|
|
152
|
+
if (parsed.ok)
|
|
153
|
+
existing = parsed.value;
|
|
154
|
+
}
|
|
155
|
+
const merged = mergeMcpServers(existing ?? {}, desired, overwrite);
|
|
156
|
+
const shaped = adapter.shapeConfig(existing, merged.merged.mcpServers);
|
|
157
|
+
mkdirSync(dirname(cd.path), { recursive: true });
|
|
158
|
+
writeFileSync(cd.path, `${JSON.stringify(shaped, null, 2)}\n`, "utf8");
|
|
159
|
+
}
|
|
160
|
+
function resolveTemplatePath(profile) {
|
|
161
|
+
const filename = profile === "minimal" ? "profile.minimal.yaml" : "profile.example.yaml";
|
|
162
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
163
|
+
const candidates = [
|
|
164
|
+
resolve(here, "..", "..", "..", "core", "schemas", filename),
|
|
165
|
+
resolve(here, "..", "..", "..", "..", "core", "schemas", filename),
|
|
166
|
+
resolve(here, "..", "..", "core", "schemas", filename),
|
|
167
|
+
join(process.cwd(), "packages", "core", "schemas", filename),
|
|
168
|
+
];
|
|
169
|
+
for (const c of candidates) {
|
|
170
|
+
if (existsSync(c))
|
|
171
|
+
return c;
|
|
172
|
+
}
|
|
173
|
+
throw new Error(`Could not locate template: ${filename}`);
|
|
174
|
+
}
|
|
175
|
+
function formatDiff(diff) {
|
|
176
|
+
const out = [];
|
|
177
|
+
out.push(`Profile: ${diff.profileAction} -> ${diff.profilePath}`);
|
|
178
|
+
for (const cd of diff.clients) {
|
|
179
|
+
out.push(`Client ${cd.client} (${cd.action}): ${cd.path}`);
|
|
180
|
+
for (const a of cd.added)
|
|
181
|
+
out.push(` + mcpServers.${a}`);
|
|
182
|
+
for (const c of cd.collisions)
|
|
183
|
+
out.push(` ! mcpServers.${c} (collision)`);
|
|
184
|
+
if (cd.reason)
|
|
185
|
+
out.push(` reason: ${cd.reason}`);
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAQzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAaxE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAoB,EAAE,OAAyB,EAAE;IAC7E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,qBAAqB;IACrB,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAExD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,4CAA4C,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,QAAQ,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAC3E,OAAO;YACL,IAAI,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YAC9E,OAAO,EAAE,KAAK;YACd,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,eAAe,CAAC;QACrC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;IAEH,cAAc;IACd,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,aAAa,GAA8B,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEzF,sBAAsB;IACtB,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,KAAK,GACT,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnE,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QAC/D,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,GAAa;QACrB,aAAa;QACb,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,WAAW;KACrB,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,CAAC,8BAA8B,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;SAC7E,CAAC;IACJ,CAAC;IAED,YAAY;IACZ,eAAe;IACf,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1D,wBAAwB,CAAC;YACvB,YAAY;YACZ,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,GAAG,CAAC,IAAI;SACtB,CAAC,CAAC;QACH,QAAQ,CAAC,IAAI,CAAC,sBAAsB,KAAK,GAAG,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,6BAA6B,KAAK,mBAAmB,CAAC,CAAC;IACvE,CAAC;IAED,sBAAsB;IACtB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACrD,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,qBAAqB,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,MAAM,IAAI,4CAA4C,GAAG,CAAC,CAAC;QACrH,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC9E,QAAQ,CAAC,IAAI,CAAC,aAAa,KAAK,0CAA0C,CAAC,CAAC;IAE5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAClB,UAA0C,EAC1C,MAAwB;IAExB,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,UAAU,CAAC;IACxC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,MAAuB,EACvB,OAAuC,EACvC,OAAoB;IAEpB,IAAI,QAAQ,GAAmC,IAAI,CAAC;IACpD,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,EAAE;gBACjB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,MAAM;gBACd,KAAK,EAAE,EAAE;gBACT,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,sCAAsC,MAAM,CAAC,KAAK,EAAE;aAC7D,CAAC;QACJ,CAAC;QACD,QAAQ,GAAI,MAAM,CAAC,KAAiC,IAAI,EAAE,CAAC;IAC7D,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAC3B,CAAC,QAAQ,IAAI,EAAE,CAAoD,EACnE,OAAO,EACP,OAAO,CAAC,GAAG,CACZ,CAAC;IAEF,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAChD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,kEAAkE;SAC3E,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACzC,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,EAAE;SACf,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;QAC/C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,EAAc,EACd,OAAuC,EACvC,SAAkB;IAElB,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,QAAQ,GAAY,IAAI,CAAC;IAC7B,IAAI,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,EAAE;YAAE,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;IACzC,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAC3B,QAA4D,IAAI,EAAE,EACnE,OAAO,EACP,SAAS,CACV,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,UAA4C,CAAC,CAAC;IACzG,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA8B;IACzD,MAAM,QAAQ,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IACzF,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG;QACjB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;QAC5D,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;QAClE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;QACtD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;KAC7D,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU,CAAC,IAAc;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,aAAa,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAClE,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU;YAAE,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAC3E,IAAI,EAAE,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ValidationResult } from "../profile/validator.js";
|
|
2
|
+
export interface ValidateResult {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly result: ValidationResult;
|
|
5
|
+
readonly missing: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function runProfileValidate(): Promise<ValidateResult>;
|
|
8
|
+
export interface ShowResult {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly yaml: string;
|
|
11
|
+
readonly missing: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function runProfileShow(): Promise<ShowResult>;
|
|
14
|
+
//# sourceMappingURL=profile.d.ts.map
|