dev-cockpit 0.1.0 → 0.2.1

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.
Files changed (140) hide show
  1. package/README.md +64 -29
  2. package/bin/dev-cockpit.mjs +26 -4
  3. package/dist/actions/builtin.d.ts +25 -0
  4. package/dist/actions/builtin.d.ts.map +1 -0
  5. package/dist/actions/dispatch.d.ts +21 -0
  6. package/dist/actions/dispatch.d.ts.map +1 -0
  7. package/dist/actions/registry.d.ts +11 -0
  8. package/dist/actions/registry.d.ts.map +1 -0
  9. package/dist/actions/types.d.ts +76 -0
  10. package/dist/actions/types.d.ts.map +1 -0
  11. package/dist/buildCli.d.ts.map +1 -1
  12. package/dist/chunk-6XGHLLYT.js +46 -0
  13. package/dist/chunk-6XGHLLYT.js.map +7 -0
  14. package/dist/chunk-Q6677JQF.js +32609 -0
  15. package/dist/chunk-Q6677JQF.js.map +7 -0
  16. package/dist/chunk-VN6UILQW.js +1460 -0
  17. package/dist/chunk-VN6UILQW.js.map +7 -0
  18. package/dist/cockpit/Cockpit.d.ts +6 -0
  19. package/dist/cockpit/Cockpit.d.ts.map +1 -1
  20. package/dist/cockpit/Footer.d.ts +6 -4
  21. package/dist/cockpit/Footer.d.ts.map +1 -1
  22. package/dist/cockpit/TabBar.d.ts.map +1 -1
  23. package/dist/cockpit/hooks/useGlobalKeys.d.ts +15 -15
  24. package/dist/cockpit/hooks/useGlobalKeys.d.ts.map +1 -1
  25. package/dist/cockpit/hooks/useTerminalWidth.d.ts +12 -0
  26. package/dist/cockpit/hooks/useTerminalWidth.d.ts.map +1 -0
  27. package/dist/cockpit/panes/CommandModal.d.ts +18 -0
  28. package/dist/cockpit/panes/CommandModal.d.ts.map +1 -0
  29. package/dist/cockpit/panes/Help.d.ts.map +1 -1
  30. package/dist/cockpit/panes/Output.d.ts +7 -0
  31. package/dist/cockpit/panes/Output.d.ts.map +1 -1
  32. package/dist/cockpit/panes/Repos.d.ts.map +1 -1
  33. package/dist/cockpit/state/store.d.ts +14 -11
  34. package/dist/cockpit/state/store.d.ts.map +1 -1
  35. package/dist/cockpit/tab-state.d.ts +12 -0
  36. package/dist/cockpit/tab-state.d.ts.map +1 -1
  37. package/dist/commands/dev.d.ts.map +1 -1
  38. package/dist/commands/init-config-wizard.d.ts +103 -2
  39. package/dist/commands/init-config-wizard.d.ts.map +1 -1
  40. package/dist/commands/init-config.d.ts.map +1 -1
  41. package/dist/commands/migrate-config.d.ts +18 -0
  42. package/dist/commands/migrate-config.d.ts.map +1 -0
  43. package/dist/commands/mount.d.ts +17 -32
  44. package/dist/commands/mount.d.ts.map +1 -1
  45. package/dist/core/config.d.ts +73 -5
  46. package/dist/core/config.d.ts.map +1 -1
  47. package/dist/core/migrations.d.ts +33 -0
  48. package/dist/core/migrations.d.ts.map +1 -0
  49. package/dist/core/subprocess.d.ts +20 -0
  50. package/dist/core/subprocess.d.ts.map +1 -1
  51. package/dist/core/types.d.ts +36 -12
  52. package/dist/core/types.d.ts.map +1 -1
  53. package/dist/devtools-YXMW6JJ6.js +3720 -0
  54. package/dist/devtools-YXMW6JJ6.js.map +7 -0
  55. package/dist/docker/highlights.d.ts +14 -4
  56. package/dist/docker/highlights.d.ts.map +1 -1
  57. package/dist/docker/logs.d.ts +3 -2
  58. package/dist/docker/logs.d.ts.map +1 -1
  59. package/dist/health/builtin.d.ts.map +1 -1
  60. package/dist/index.d.ts +14 -3
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +92837 -53
  63. package/dist/index.js.map +7 -0
  64. package/dist/ink.js +38 -1
  65. package/dist/ink.js.map +7 -0
  66. package/dist/mount/compose.d.ts +21 -0
  67. package/dist/mount/compose.d.ts.map +1 -0
  68. package/dist/mount/discovery.d.ts +35 -0
  69. package/dist/mount/discovery.d.ts.map +1 -0
  70. package/dist/mount/git-status.d.ts +12 -0
  71. package/dist/mount/git-status.d.ts.map +1 -0
  72. package/dist/mount/manifest.d.ts +16 -0
  73. package/dist/mount/manifest.d.ts.map +1 -0
  74. package/dist/mount/symlinks.d.ts +30 -0
  75. package/dist/mount/symlinks.d.ts.map +1 -0
  76. package/dist/mount/types.d.ts +60 -0
  77. package/dist/mount/types.d.ts.map +1 -0
  78. package/dist/react.js +35 -1
  79. package/dist/react.js.map +7 -0
  80. package/dist/runCockpit.d.ts +3 -0
  81. package/dist/runCockpit.d.ts.map +1 -1
  82. package/docs/commands.md +29 -16
  83. package/docs/config-reference.md +115 -11
  84. package/docs/getting-started.md +9 -6
  85. package/docs/index.md +5 -1
  86. package/docs/init-config.md +34 -8
  87. package/docs/mount.md +198 -25
  88. package/docs/notifications.md +14 -13
  89. package/docs/panes.md +36 -15
  90. package/docs/processes.md +42 -0
  91. package/package.json +93 -90
  92. package/dist/buildCli.js +0 -107
  93. package/dist/cli.js +0 -2
  94. package/dist/cockpit/Cockpit.js +0 -73
  95. package/dist/cockpit/Footer.js +0 -33
  96. package/dist/cockpit/TabBar.js +0 -12
  97. package/dist/cockpit/help/content.js +0 -22
  98. package/dist/cockpit/help/loader.js +0 -118
  99. package/dist/cockpit/help/renderer.js +0 -35
  100. package/dist/cockpit/help/types.js +0 -1
  101. package/dist/cockpit/hooks/useCockpitStore.js +0 -5
  102. package/dist/cockpit/hooks/useGlobalKeys.js +0 -173
  103. package/dist/cockpit/panes/FilterModal.js +0 -22
  104. package/dist/cockpit/panes/Health.js +0 -30
  105. package/dist/cockpit/panes/Help.js +0 -81
  106. package/dist/cockpit/panes/Output.js +0 -108
  107. package/dist/cockpit/panes/Repos.js +0 -48
  108. package/dist/cockpit/panes/SearchModal.js +0 -31
  109. package/dist/cockpit/state/store.js +0 -111
  110. package/dist/cockpit/tab-state.js +0 -7
  111. package/dist/commands/dev.js +0 -158
  112. package/dist/commands/doctor.js +0 -66
  113. package/dist/commands/init-config-wizard.js +0 -818
  114. package/dist/commands/init-config.js +0 -131
  115. package/dist/commands/mount.js +0 -150
  116. package/dist/core/config.js +0 -152
  117. package/dist/core/logger.js +0 -38
  118. package/dist/core/notifier.js +0 -100
  119. package/dist/core/paths.js +0 -18
  120. package/dist/core/subprocess.js +0 -82
  121. package/dist/core/types.js +0 -1
  122. package/dist/docker/highlights.js +0 -79
  123. package/dist/docker/logs.js +0 -172
  124. package/dist/docker/restart.js +0 -45
  125. package/dist/docker/stack-trace.js +0 -44
  126. package/dist/health/builtin.js +0 -144
  127. package/dist/health/context.js +0 -31
  128. package/dist/health/notify-resolver.js +0 -28
  129. package/dist/health/registry.js +0 -64
  130. package/dist/health/remediations.js +0 -41
  131. package/dist/health/runner.js +0 -22
  132. package/dist/health/scheduler.js +0 -107
  133. package/dist/health/types.js +0 -1
  134. package/dist/health/useHealth.js +0 -122
  135. package/dist/lint/reactive.js +0 -131
  136. package/dist/runCockpit.js +0 -75
  137. package/dist/watchers/manager.js +0 -239
  138. package/dist/watchers/path-mapper.js +0 -29
  139. package/dist/watchers/types.js +0 -9
  140. package/docs/watchers.md +0 -27
@@ -1,158 +0,0 @@
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
- }
@@ -1,66 +0,0 @@
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
- }