dev-cockpit 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 +36 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/bin/dev-cockpit.mjs +20 -0
- package/dist/buildCli.d.ts +17 -0
- package/dist/buildCli.d.ts.map +1 -0
- package/dist/buildCli.js +107 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2 -0
- package/dist/cockpit/Cockpit.d.ts +33 -0
- package/dist/cockpit/Cockpit.d.ts.map +1 -0
- package/dist/cockpit/Cockpit.js +73 -0
- package/dist/cockpit/Footer.d.ts +22 -0
- package/dist/cockpit/Footer.d.ts.map +1 -0
- package/dist/cockpit/Footer.js +33 -0
- package/dist/cockpit/TabBar.d.ts +3 -0
- package/dist/cockpit/TabBar.d.ts.map +1 -0
- package/dist/cockpit/TabBar.js +12 -0
- package/dist/cockpit/help/content.d.ts +12 -0
- package/dist/cockpit/help/content.d.ts.map +1 -0
- package/dist/cockpit/help/content.js +22 -0
- package/dist/cockpit/help/loader.d.ts +65 -0
- package/dist/cockpit/help/loader.d.ts.map +1 -0
- package/dist/cockpit/help/loader.js +118 -0
- package/dist/cockpit/help/renderer.d.ts +16 -0
- package/dist/cockpit/help/renderer.d.ts.map +1 -0
- package/dist/cockpit/help/renderer.js +35 -0
- package/dist/cockpit/help/types.d.ts +12 -0
- package/dist/cockpit/help/types.d.ts.map +1 -0
- package/dist/cockpit/help/types.js +1 -0
- package/dist/cockpit/hooks/useCockpitStore.d.ts +3 -0
- package/dist/cockpit/hooks/useCockpitStore.d.ts.map +1 -0
- package/dist/cockpit/hooks/useCockpitStore.js +5 -0
- package/dist/cockpit/hooks/useGlobalKeys.d.ts +56 -0
- package/dist/cockpit/hooks/useGlobalKeys.d.ts.map +1 -0
- package/dist/cockpit/hooks/useGlobalKeys.js +173 -0
- package/dist/cockpit/panes/FilterModal.d.ts +3 -0
- package/dist/cockpit/panes/FilterModal.d.ts.map +1 -0
- package/dist/cockpit/panes/FilterModal.js +22 -0
- package/dist/cockpit/panes/Health.d.ts +13 -0
- package/dist/cockpit/panes/Health.d.ts.map +1 -0
- package/dist/cockpit/panes/Health.js +30 -0
- package/dist/cockpit/panes/Help.d.ts +14 -0
- package/dist/cockpit/panes/Help.d.ts.map +1 -0
- package/dist/cockpit/panes/Help.js +81 -0
- package/dist/cockpit/panes/Output.d.ts +14 -0
- package/dist/cockpit/panes/Output.d.ts.map +1 -0
- package/dist/cockpit/panes/Output.js +108 -0
- package/dist/cockpit/panes/Repos.d.ts +3 -0
- package/dist/cockpit/panes/Repos.d.ts.map +1 -0
- package/dist/cockpit/panes/Repos.js +48 -0
- package/dist/cockpit/panes/SearchModal.d.ts +3 -0
- package/dist/cockpit/panes/SearchModal.d.ts.map +1 -0
- package/dist/cockpit/panes/SearchModal.js +31 -0
- package/dist/cockpit/state/store.d.ts +93 -0
- package/dist/cockpit/state/store.d.ts.map +1 -0
- package/dist/cockpit/state/store.js +111 -0
- package/dist/cockpit/tab-state.d.ts +4 -0
- package/dist/cockpit/tab-state.d.ts.map +1 -0
- package/dist/cockpit/tab-state.js +7 -0
- package/dist/commands/dev.d.ts +20 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +158 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +66 -0
- package/dist/commands/init-config-wizard.d.ts +84 -0
- package/dist/commands/init-config-wizard.d.ts.map +1 -0
- package/dist/commands/init-config-wizard.js +818 -0
- package/dist/commands/init-config.d.ts +35 -0
- package/dist/commands/init-config.d.ts.map +1 -0
- package/dist/commands/init-config.js +131 -0
- package/dist/commands/mount.d.ts +48 -0
- package/dist/commands/mount.d.ts.map +1 -0
- package/dist/commands/mount.js +150 -0
- package/dist/core/config.d.ts +391 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +152 -0
- package/dist/core/logger.d.ts +6 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +38 -0
- package/dist/core/notifier.d.ts +23 -0
- package/dist/core/notifier.d.ts.map +1 -0
- package/dist/core/notifier.js +100 -0
- package/dist/core/paths.d.ts +15 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +18 -0
- package/dist/core/subprocess.d.ts +20 -0
- package/dist/core/subprocess.d.ts.map +1 -0
- package/dist/core/subprocess.js +82 -0
- package/dist/core/types.d.ts +125 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/docker/highlights.d.ts +48 -0
- package/dist/docker/highlights.d.ts.map +1 -0
- package/dist/docker/highlights.js +79 -0
- package/dist/docker/logs.d.ts +84 -0
- package/dist/docker/logs.d.ts.map +1 -0
- package/dist/docker/logs.js +172 -0
- package/dist/docker/restart.d.ts +26 -0
- package/dist/docker/restart.d.ts.map +1 -0
- package/dist/docker/restart.js +45 -0
- package/dist/docker/stack-trace.d.ts +25 -0
- package/dist/docker/stack-trace.d.ts.map +1 -0
- package/dist/docker/stack-trace.js +44 -0
- package/dist/health/builtin.d.ts +8 -0
- package/dist/health/builtin.d.ts.map +1 -0
- package/dist/health/builtin.js +144 -0
- package/dist/health/context.d.ts +3 -0
- package/dist/health/context.d.ts.map +1 -0
- package/dist/health/context.js +31 -0
- package/dist/health/notify-resolver.d.ts +18 -0
- package/dist/health/notify-resolver.d.ts.map +1 -0
- package/dist/health/notify-resolver.js +28 -0
- package/dist/health/registry.d.ts +20 -0
- package/dist/health/registry.d.ts.map +1 -0
- package/dist/health/registry.js +64 -0
- package/dist/health/remediations.d.ts +6 -0
- package/dist/health/remediations.d.ts.map +1 -0
- package/dist/health/remediations.js +41 -0
- package/dist/health/runner.d.ts +4 -0
- package/dist/health/runner.d.ts.map +1 -0
- package/dist/health/runner.js +22 -0
- package/dist/health/scheduler.d.ts +41 -0
- package/dist/health/scheduler.d.ts.map +1 -0
- package/dist/health/scheduler.js +107 -0
- package/dist/health/types.d.ts +73 -0
- package/dist/health/types.d.ts.map +1 -0
- package/dist/health/types.js +1 -0
- package/dist/health/useHealth.d.ts +40 -0
- package/dist/health/useHealth.d.ts.map +1 -0
- package/dist/health/useHealth.js +122 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/ink.d.ts +3 -0
- package/dist/ink.d.ts.map +1 -0
- package/dist/ink.js +1 -0
- package/dist/lint/reactive.d.ts +38 -0
- package/dist/lint/reactive.d.ts.map +1 -0
- package/dist/lint/reactive.js +131 -0
- package/dist/react.d.ts +3 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +1 -0
- package/dist/runCockpit.d.ts +34 -0
- package/dist/runCockpit.d.ts.map +1 -0
- package/dist/runCockpit.js +75 -0
- package/dist/watchers/manager.d.ts +63 -0
- package/dist/watchers/manager.d.ts.map +1 -0
- package/dist/watchers/manager.js +239 -0
- package/dist/watchers/path-mapper.d.ts +23 -0
- package/dist/watchers/path-mapper.d.ts.map +1 -0
- package/dist/watchers/path-mapper.js +29 -0
- package/dist/watchers/types.d.ts +22 -0
- package/dist/watchers/types.d.ts.map +1 -0
- package/dist/watchers/types.js +9 -0
- package/docs/commands.md +71 -0
- package/docs/config-reference.md +20 -0
- package/docs/getting-started.md +39 -0
- package/docs/health.md +120 -0
- package/docs/index.md +13 -0
- package/docs/init-config.md +46 -0
- package/docs/mount.md +55 -0
- package/docs/notifications.md +39 -0
- package/docs/panes.md +45 -0
- package/docs/watchers.md +27 -0
- package/examples/cockpit.yaml +116 -0
- package/package.json +91 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dev-cockpit dev` — generic boot of the three-pane TUI.
|
|
3
|
+
*
|
|
4
|
+
* Loads `cockpit.yaml`, runs the active profile's boot lifecycle hook to
|
|
5
|
+
* collect cockpit handlers + fs-event source + cleanup, wires up docker
|
|
6
|
+
* log tailers and the health framework, then renders the cockpit shell.
|
|
7
|
+
*
|
|
8
|
+
* Workspace root resolution order:
|
|
9
|
+
* 1. `profile.discoverer()` if present
|
|
10
|
+
* 2. parent directory of the resolved config file
|
|
11
|
+
*/
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import fs from 'node:fs';
|
|
14
|
+
import { loadConfig } from '../core/config.js';
|
|
15
|
+
import { runCockpit } from '../runCockpit.js';
|
|
16
|
+
import { buildHealthContext } from '../health/context.js';
|
|
17
|
+
import { buildHealthRegistry } from '../health/registry.js';
|
|
18
|
+
import { cockpitStore } from '../cockpit/state/store.js';
|
|
19
|
+
import { DockerLogTailer } from '../docker/logs.js';
|
|
20
|
+
import { killAllSpawned, spawnStream } from '../core/subprocess.js';
|
|
21
|
+
export async function devCommand(opts = {}) {
|
|
22
|
+
const configPath = path.resolve(opts.config ?? 'cockpit.yaml');
|
|
23
|
+
if (!fs.existsSync(configPath)) {
|
|
24
|
+
process.stderr.write(`dev-cockpit: no cockpit.yaml found at ${configPath}.\n` +
|
|
25
|
+
` Run \`dev-cockpit init-config\` to scaffold one.\n`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const profile = opts.profile;
|
|
29
|
+
const config = loadConfig(configPath, {
|
|
30
|
+
configSchemaExt: profile?.configSchemaExt,
|
|
31
|
+
profileKey: profile?.appName,
|
|
32
|
+
});
|
|
33
|
+
const workspaceRoot = profile?.discoverer?.()?.root ?? path.dirname(configPath);
|
|
34
|
+
// Seed the Repos pane from config.repos[] (and any docker.services that
|
|
35
|
+
// the user listed as tailed — those surface as `docker`-kind entries).
|
|
36
|
+
// Profiles that need richer derivation can call cockpitStore.initRepos
|
|
37
|
+
// themselves from their setupCli command before runCockpit boots.
|
|
38
|
+
const seededRepos = {};
|
|
39
|
+
const seededOrder = [];
|
|
40
|
+
for (const repo of config.repos) {
|
|
41
|
+
seededRepos[repo.id] = { name: repo.label ?? repo.id, status: 'idle', kind: 'repo' };
|
|
42
|
+
seededOrder.push(repo.id);
|
|
43
|
+
}
|
|
44
|
+
const profileCtx = { config, workspaceRoot };
|
|
45
|
+
for (const repo of profile?.reposProvider?.(profileCtx) ?? []) {
|
|
46
|
+
if (seededRepos[repo.id])
|
|
47
|
+
continue;
|
|
48
|
+
seededRepos[repo.id] = { name: repo.label ?? repo.id, status: 'idle', kind: 'repo' };
|
|
49
|
+
seededOrder.push(repo.id);
|
|
50
|
+
}
|
|
51
|
+
for (const svc of config.docker?.services ?? []) {
|
|
52
|
+
if (seededRepos[svc.name])
|
|
53
|
+
continue;
|
|
54
|
+
seededRepos[svc.name] = { name: svc.name, status: 'idle', kind: 'docker' };
|
|
55
|
+
seededOrder.push(svc.name);
|
|
56
|
+
}
|
|
57
|
+
cockpitStore.getState().initRepos(seededRepos, seededOrder);
|
|
58
|
+
const ctx = buildHealthContext(workspaceRoot, (line) => cockpitStore.getState().appendOutput(line));
|
|
59
|
+
const registry = buildHealthRegistry({
|
|
60
|
+
profileChecks: profile?.healthChecks,
|
|
61
|
+
configEntries: config.health,
|
|
62
|
+
});
|
|
63
|
+
const helpSources = (profile?.helpSources ?? []).map((src) => ({
|
|
64
|
+
id: src.id,
|
|
65
|
+
title: src.title,
|
|
66
|
+
path: src.path,
|
|
67
|
+
content: src.content,
|
|
68
|
+
omit: src.omit,
|
|
69
|
+
}));
|
|
70
|
+
// Profile lifecycle hook. Runs after config load + workspaceRoot resolution
|
|
71
|
+
// and before the cockpit renders. Profiles return any combination of
|
|
72
|
+
// pane handlers, an fs-event subscription (typically WatcherManager.
|
|
73
|
+
// subscribeFsEvents) for the health framework, and a cleanup callback
|
|
74
|
+
// awaited at teardown.
|
|
75
|
+
const bootResult = profile?.boot
|
|
76
|
+
? await profile.boot(profileCtx)
|
|
77
|
+
: {};
|
|
78
|
+
const handlers = bootResult.cockpitHandlers ?? {};
|
|
79
|
+
const handle = runCockpit({
|
|
80
|
+
profile: profile
|
|
81
|
+
? {
|
|
82
|
+
...profile,
|
|
83
|
+
helpSources,
|
|
84
|
+
defaultHelpPage: profile.defaultHelpPage ?? config.help.defaultPage,
|
|
85
|
+
}
|
|
86
|
+
: undefined,
|
|
87
|
+
runRepoAction: handlers.runRepoAction,
|
|
88
|
+
onWatchToggle: handlers.onWatchToggle,
|
|
89
|
+
onLint: handlers.onLint,
|
|
90
|
+
onOpenError: handlers.onOpenError,
|
|
91
|
+
footerLegends: handlers.footerLegends,
|
|
92
|
+
health: {
|
|
93
|
+
workspaceRoot,
|
|
94
|
+
profileChecks: registry,
|
|
95
|
+
ctx,
|
|
96
|
+
notifications: {
|
|
97
|
+
enabled: config.notifications.enabled,
|
|
98
|
+
exclude: config.notifications.exclude,
|
|
99
|
+
},
|
|
100
|
+
appName: config.appName,
|
|
101
|
+
subscribeFsEvents: bootResult.subscribeFsEvents,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
// Spawn each declared watcher as a long-running streaming process. Output
|
|
105
|
+
// flows into the Output pane tagged by the watcher's id (or label). The
|
|
106
|
+
// global spawnStream registry tracks each child, so killAllSpawned() at
|
|
107
|
+
// teardown reaps them. No fsevent-driven respawn here — the watcher's own
|
|
108
|
+
// command (e.g. `tsc --watch`) is expected to handle re-runs internally.
|
|
109
|
+
for (const watcher of config.watchers) {
|
|
110
|
+
const [exe, ...args] = watcher.command.split(/\s+/);
|
|
111
|
+
if (!exe)
|
|
112
|
+
continue;
|
|
113
|
+
const source = watcher.label ?? watcher.id;
|
|
114
|
+
spawnStream(exe, args, {
|
|
115
|
+
cwd: watcher.cwd ? path.resolve(workspaceRoot, watcher.cwd) : workspaceRoot,
|
|
116
|
+
env: watcher.env,
|
|
117
|
+
onStdout: (line) => cockpitStore.getState().appendOutput({
|
|
118
|
+
ts: Date.now(),
|
|
119
|
+
source,
|
|
120
|
+
severity: 'info',
|
|
121
|
+
text: line,
|
|
122
|
+
}),
|
|
123
|
+
onStderr: (line) => cockpitStore.getState().appendOutput({
|
|
124
|
+
ts: Date.now(),
|
|
125
|
+
source,
|
|
126
|
+
severity: 'warn',
|
|
127
|
+
text: line,
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Optional docker log tailer — only if config declares services to tail.
|
|
132
|
+
const dockerServices = (config.docker?.services ?? []).filter((s) => s.tail !== false);
|
|
133
|
+
let dockerTailer = null;
|
|
134
|
+
if (dockerServices.length > 0) {
|
|
135
|
+
dockerTailer = new DockerLogTailer({
|
|
136
|
+
workspaceRoot,
|
|
137
|
+
services: dockerServices.map((s) => s.name),
|
|
138
|
+
highlightPatterns: config.highlights.map((h) => h.pattern),
|
|
139
|
+
appendOutput: (line) => cockpitStore.getState().appendOutput(line),
|
|
140
|
+
pushRecentError: (err) => cockpitStore.getState().pushRecentError(err),
|
|
141
|
+
notifyOpts: () => ({
|
|
142
|
+
config: {
|
|
143
|
+
enabled: config.notifications.enabled,
|
|
144
|
+
exclude: config.notifications.exclude,
|
|
145
|
+
},
|
|
146
|
+
sessionEnabled: cockpitStore.getState().notificationsEnabledSession,
|
|
147
|
+
appName: config.appName,
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
dockerTailer.start();
|
|
151
|
+
}
|
|
152
|
+
await handle.waitUntilExit();
|
|
153
|
+
if (dockerTailer)
|
|
154
|
+
await dockerTailer.stop();
|
|
155
|
+
if (bootResult.cleanup)
|
|
156
|
+
await bootResult.cleanup();
|
|
157
|
+
await killAllSpawned();
|
|
158
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dev-cockpit doctor` — one-shot health check.
|
|
3
|
+
*
|
|
4
|
+
* Loads the cockpit config, resolves the workspace root, builds the health
|
|
5
|
+
* registry from `config.health[]` + `profile.healthChecks`, runs the
|
|
6
|
+
* `startup` trigger set once, prints results, and exits non-zero on any
|
|
7
|
+
* `error` severity.
|
|
8
|
+
*/
|
|
9
|
+
import type { Profile } from '../core/types.js';
|
|
10
|
+
import type { HealthStatus } from '../core/types.js';
|
|
11
|
+
export interface DoctorCommandOptions {
|
|
12
|
+
config?: string;
|
|
13
|
+
profile?: Profile;
|
|
14
|
+
}
|
|
15
|
+
export declare function formatResults(results: HealthStatus[], appName: string): {
|
|
16
|
+
lines: string[];
|
|
17
|
+
exitCode: 0 | 1;
|
|
18
|
+
};
|
|
19
|
+
export declare function doctorCommand(opts?: DoctorCommandOptions): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG;IACvE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB,CAoBA;AAED,wBAAsB,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dev-cockpit doctor` — one-shot health check.
|
|
3
|
+
*
|
|
4
|
+
* Loads the cockpit config, resolves the workspace root, builds the health
|
|
5
|
+
* registry from `config.health[]` + `profile.healthChecks`, runs the
|
|
6
|
+
* `startup` trigger set once, prints results, and exits non-zero on any
|
|
7
|
+
* `error` severity.
|
|
8
|
+
*/
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import { loadConfig } from '../core/config.js';
|
|
12
|
+
import { buildHealthContext } from '../health/context.js';
|
|
13
|
+
import { buildHealthRegistry } from '../health/registry.js';
|
|
14
|
+
import { runChecks } from '../health/runner.js';
|
|
15
|
+
const GLYPH = {
|
|
16
|
+
ok: '✓',
|
|
17
|
+
warn: '⚠',
|
|
18
|
+
error: '✗',
|
|
19
|
+
};
|
|
20
|
+
export function formatResults(results, appName) {
|
|
21
|
+
if (results.length === 0) {
|
|
22
|
+
return {
|
|
23
|
+
lines: [`${appName} doctor: no checks ran (empty health registry)`],
|
|
24
|
+
exitCode: 0,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const labelWidth = Math.max(...results.map((r) => r.label.length));
|
|
28
|
+
const lines = [];
|
|
29
|
+
let anyError = false;
|
|
30
|
+
for (const r of results) {
|
|
31
|
+
if (r.severity === 'error')
|
|
32
|
+
anyError = true;
|
|
33
|
+
const detail = r.detail || (r.severity === 'ok' ? 'ok' : '(no detail)');
|
|
34
|
+
let line = `${GLYPH[r.severity]} ${r.label.padEnd(labelWidth)} ${detail}`;
|
|
35
|
+
if (r.severity !== 'ok' && r.remediationKey) {
|
|
36
|
+
line += ` → press ${r.remediationKey} in cockpit`;
|
|
37
|
+
}
|
|
38
|
+
lines.push(line);
|
|
39
|
+
}
|
|
40
|
+
return { lines, exitCode: anyError ? 1 : 0 };
|
|
41
|
+
}
|
|
42
|
+
export async function doctorCommand(opts = {}) {
|
|
43
|
+
const configPath = path.resolve(opts.config ?? 'cockpit.yaml');
|
|
44
|
+
if (!fs.existsSync(configPath)) {
|
|
45
|
+
process.stderr.write(`dev-cockpit doctor: no cockpit.yaml found at ${configPath}.\n`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const profile = opts.profile;
|
|
49
|
+
const config = loadConfig(configPath, {
|
|
50
|
+
configSchemaExt: profile?.configSchemaExt,
|
|
51
|
+
profileKey: profile?.appName,
|
|
52
|
+
});
|
|
53
|
+
const workspaceRoot = profile?.discoverer?.()?.root ?? path.dirname(configPath);
|
|
54
|
+
const ctx = buildHealthContext(workspaceRoot);
|
|
55
|
+
const registry = buildHealthRegistry({
|
|
56
|
+
profileChecks: profile?.healthChecks,
|
|
57
|
+
configEntries: config.health,
|
|
58
|
+
});
|
|
59
|
+
const results = await runChecks(registry, ['startup'], ctx);
|
|
60
|
+
const { lines, exitCode } = formatResults(results, config.appName);
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
process.stdout.write(`${line}\n`);
|
|
63
|
+
}
|
|
64
|
+
if (exitCode !== 0)
|
|
65
|
+
process.exit(exitCode);
|
|
66
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive `cockpit.yaml` wizard for `dev-cockpit init-config --interactive`.
|
|
3
|
+
*
|
|
4
|
+
* Two pieces:
|
|
5
|
+
* 1. {@link runInitWizard} — the prompt loop (lazy-imports @inquirer/prompts
|
|
6
|
+
* so non-interactive code paths don't pay the import cost).
|
|
7
|
+
* 2. {@link renderWizardYaml} — pure function: WizardResult → yaml string.
|
|
8
|
+
* Lives here so tests can exercise it without touching prompts at all.
|
|
9
|
+
*
|
|
10
|
+
* The wizard intentionally stays narrow: it scaffolds a *usable* starter
|
|
11
|
+
* config covering the common knobs (one watcher or two, the five built-in
|
|
12
|
+
* health types with their primary args + a remediation, an optional docker
|
|
13
|
+
* block, optional highlights, the notifications flag). Anything more
|
|
14
|
+
* advanced — custom triggers, expectStatus, exec args — the user edits in
|
|
15
|
+
* the generated yaml.
|
|
16
|
+
*/
|
|
17
|
+
export type HealthBuiltinType = 'container-running' | 'port-open' | 'http-ok' | 'file-exists' | 'exec-zero';
|
|
18
|
+
export type HighlightSeverity = 'info' | 'warn' | 'error';
|
|
19
|
+
export type HealthSeverity = 'ok' | 'warn' | 'error';
|
|
20
|
+
export interface WizardWatcher {
|
|
21
|
+
id: string;
|
|
22
|
+
command: string;
|
|
23
|
+
}
|
|
24
|
+
export interface WizardDockerService {
|
|
25
|
+
name: string;
|
|
26
|
+
}
|
|
27
|
+
export interface WizardDocker {
|
|
28
|
+
composeFile?: string;
|
|
29
|
+
services: WizardDockerService[];
|
|
30
|
+
}
|
|
31
|
+
export interface WizardHighlight {
|
|
32
|
+
pattern: string;
|
|
33
|
+
severity: HighlightSeverity;
|
|
34
|
+
}
|
|
35
|
+
export interface WizardRemediation {
|
|
36
|
+
key: string;
|
|
37
|
+
label: string;
|
|
38
|
+
command: string;
|
|
39
|
+
}
|
|
40
|
+
export interface WizardHealthCheckBase {
|
|
41
|
+
id: string;
|
|
42
|
+
label: string;
|
|
43
|
+
severity: HealthSeverity;
|
|
44
|
+
remediation: WizardRemediation;
|
|
45
|
+
}
|
|
46
|
+
export type WizardHealthCheck = (WizardHealthCheckBase & {
|
|
47
|
+
type: 'container-running';
|
|
48
|
+
container: string;
|
|
49
|
+
}) | (WizardHealthCheckBase & {
|
|
50
|
+
type: 'port-open';
|
|
51
|
+
host: string;
|
|
52
|
+
port: number;
|
|
53
|
+
}) | (WizardHealthCheckBase & {
|
|
54
|
+
type: 'http-ok';
|
|
55
|
+
url: string;
|
|
56
|
+
}) | (WizardHealthCheckBase & {
|
|
57
|
+
type: 'file-exists';
|
|
58
|
+
path: string;
|
|
59
|
+
}) | (WizardHealthCheckBase & {
|
|
60
|
+
type: 'exec-zero';
|
|
61
|
+
command: string;
|
|
62
|
+
});
|
|
63
|
+
export interface WizardRepo {
|
|
64
|
+
id: string;
|
|
65
|
+
path: string;
|
|
66
|
+
label?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface WizardResult {
|
|
69
|
+
appName: string;
|
|
70
|
+
watchers: WizardWatcher[];
|
|
71
|
+
docker?: WizardDocker;
|
|
72
|
+
repos: WizardRepo[];
|
|
73
|
+
highlights: WizardHighlight[];
|
|
74
|
+
health: WizardHealthCheck[];
|
|
75
|
+
notifications: {
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export declare function renderWizardYaml(result: WizardResult): string;
|
|
80
|
+
export declare function runInitWizard(opts: {
|
|
81
|
+
defaultAppName: string;
|
|
82
|
+
cwd?: string;
|
|
83
|
+
}): Promise<WizardResult>;
|
|
84
|
+
//# sourceMappingURL=init-config-wizard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-config-wizard.d.ts","sourceRoot":"","sources":["../../src/commands/init-config-wizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,iBAAiB,GACzB,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC1D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,iBAAiB,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GACzB,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1E,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3E,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1D,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAErE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,aAAa,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CACrC;AA8FD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA+B7D;AAuwBD,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,YAAY,CAAC,CAgDxB"}
|