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
package/README.md CHANGED
@@ -3,26 +3,29 @@
3
3
  A reusable, domain-neutral terminal UI dev cockpit. One window for the long-running processes you babysit during development: code, logs, health, and the keystrokes to fix things when they break.
4
4
 
5
5
  ```
6
- ┌── Repos ── Output ── Health ── Help ────────────────── [↔ / tab] cycle ──┐
7
- Repos
8
- │ web docker idle
9
- db docker idle
10
- cache docker idle
11
-
12
- Recent errors:
13
- │ web │ Stack trace at /srv/app/handler.ts:42 │
14
- └───────────────────────────────────────────────────────────────────────────┘
6
+ ┌── Targets ── Output ── Health ── Help ────────────────────────────────────┐
7
+ Targets Actions for `web` (docker) │
8
+ web [docker] [r] Restart web (default) │
9
+ ticker [process] [L] Tail logs │
10
+ api
11
+
12
+
13
+ └────────────────────────────────┴────────────────────────────────────────┘
14
+ [↑↓] select [r] restart [L] tail
15
15
  ```
16
16
 
17
17
  ## What's in the box
18
18
 
19
- - **Four-pane TUI** — Repos / Output / Health / Help, tab-cycle nav, filter + search modals.
20
- - **Watchers** — long-running processes spawned once on boot; their stdout streams into Output, tagged by id.
21
- - **Docker log tailing** — stream `docker compose logs -f <services>` into the same Output pane with regex-driven highlights for errors / stack traces.
22
- - **Health framework** — five built-in check types (`container-running`, `port-open`, `http-ok`, `file-exists`, `exec-zero`) plus profile-contributed ones; each gets a row on the Health pane and a single-keystroke remediation.
23
- - **Profile interface** — drop-in adapter so a domain-specific tool can wire its own discoverer / repos / health / commands / cockpit handlers without forking the shell.
19
+ - **Four-pane TUI** — Targets / Output / Health / Help, tab-cycle navigation, filter + search modals, narrow-terminal layouts.
20
+ - **Processes** — long-running commands spawned once on boot; stdout/stderr streamed into Output, tagged by id, with shell-out execution so pipes/redirects/quoted args just work.
21
+ - **Docker log tailing** — stream `docker compose logs -f <services>` into Output with regex-driven highlights (configurable severity per pattern).
22
+ - **Health framework** — five built-in check types (`container-running`, `port-open`, `http-ok`, `file-exists`, `exec-zero`) plus profile-contributed ones; each gets a row + a single-keystroke remediation.
23
+ - **Mount overlay manager** — `dev-cockpit mount` writes a docker-compose overlay + manifest, with an interactive picker, branch / dirty / broken-symlink status table, and profile hooks for restart + dependency-restore on clear.
24
+ - **Actions library** — `config.actions[]` + `Profile.actions` (declarative shell-out OR programmatic `invoke` callbacks). Reach via the vim-style `:` palette or single-keystroke binding scoped to a Targets row.
25
+ - **Profile interface** — drop-in adapter so a domain-specific tool plugs in its discoverer / repos / health / actions / commands / cockpit handlers without forking the shell.
24
26
  - **Live markdown Help** — pages render inside the cockpit; profiles can layer their own docs over the generic ones.
25
27
  - **Native OS notifications** — fire on state transitions only (no spam). Detached helper, never blocks process exit.
28
+ - **A11y** — `NO_COLOR` strips all styles; semantic glyphs (`✓` `⚠` `✗` `●` `○`) carry severity / status info without color.
26
29
 
27
30
  ## Install
28
31
 
@@ -32,29 +35,41 @@ npm install -g dev-cockpit
32
35
 
33
36
  Or `npm link` from a checkout for development.
34
37
 
38
+ Requires Node ≥ 20.12 (chalk + inquirer use `node:util.styleText`). The bin guards this at startup with a friendly error message.
39
+
35
40
  ## Quick start
36
41
 
37
42
  ```sh
38
43
  cd your-project
39
- dev-cockpit init-config -i # interactive wizard, 7 steps with auto-detection
44
+ dev-cockpit init-config -i # interactive wizard, 8 steps with auto-detection
40
45
  dev-cockpit doctor # validate + print initial health
41
46
  dev-cockpit dev # boot the cockpit
42
47
  ```
43
48
 
44
- The wizard sniffs your project: if there's a `compose.yaml` it suggests services to tail, if `package.json` has a `dev` script it offers it as a watcher, if there are workspaces it surfaces them as repo entries. Most prompts just need an enter.
49
+ The wizard sniffs your project: docker compose services from `compose.yaml`, long-running processes from `package.json` (`dev`, `watch`), one-shot actions from the rest of your scripts (`test`, `build`, `lint`, `format`), workspaces as repo entries. Most prompts just need an enter.
45
50
 
46
51
  ## Configuration
47
52
 
48
- Single file, `cockpit.yaml` at your project root. Schema enforced by zod (`version: 1`). Full reference: [`docs/config-reference.md`](./docs/config-reference.md). Minimal example:
53
+ Single file, `cockpit.yaml` at your project root. Schema enforced by zod (`version: 2`). Full reference: [`docs/config-reference.md`](./docs/config-reference.md). Minimal example:
49
54
 
50
55
  ```yaml
51
- version: 1
56
+ version: 2
52
57
  appName: my-app
53
58
 
54
- watchers:
59
+ processes:
55
60
  - id: vite
56
61
  command: npm run dev
57
62
 
63
+ actions:
64
+ - id: test
65
+ label: Run tests
66
+ command: npm test
67
+ key: t # `:` palette + single-keystroke binding
68
+ - id: lint
69
+ label: Lint
70
+ command: npm run lint
71
+ key: l
72
+
58
73
  docker:
59
74
  composeFile: compose.yaml
60
75
  services:
@@ -76,20 +91,29 @@ notifications:
76
91
  enabled: true
77
92
  ```
78
93
 
94
+ Wrappers upgrading from v1 (pre-rename) configs run `dev-cockpit migrate-config` to persist the v1 → v2 migration (auto-applied in memory on load with a stderr warning).
95
+
79
96
  ## Profiles
80
97
 
81
98
  A profile is a domain-specific bundle that plugs into dev-cockpit's lifecycle. It contributes any combination of:
82
99
 
83
100
  - `discoverer` — workspace root resolution
84
- - `reposProvider` — Repos-pane entries
101
+ - `reposProvider` — Targets-pane entries (kind: `repo`)
85
102
  - `healthChecks` — pre-built `HealthCheck[]` (programmatic, beyond the five built-ins)
86
103
  - `setupCli` — extra CLI commands (the profile's own `select`, `release`, etc.)
87
104
  - `helpSources` — markdown docs that layer over the generic Help
105
+ - `defaultHelpPage` — landing page slug for the Help tab
106
+ - `defaultPane` — which tab the cockpit lands on (overrides `config.defaultPane`)
88
107
  - `configSchemaExt` — zod schema validating the profile's `profile.<appName>` namespace
108
+ - `actions` — static action defaults merged into the registry
109
+ - `wizardSteps` — extra `init-config -i` steps; output lands under `profile.<appName>:`
89
110
  - `mountCandidatesProvider` — auto-detected bind-mount candidates
90
- - `boot` async lifecycle hook returning Cockpit pane handlers + `subscribeFsEvents` + `cleanup`
111
+ - `mountSymlinks` IDE-facing symlink strategy for mount apply / clear
112
+ - `onMountApply` / `onMountClear` — post-mount lifecycle hooks (restart docker, run installer, etc.)
113
+ - `mountStatusEnricher` — extra columns in `mount status`
114
+ - `boot` — async lifecycle hook returning Cockpit pane handlers + dynamic `actions` (per-row invoke callbacks) + `subscribeFsEvents` + `cleanup`
91
115
 
92
- A profile is its own npm package — its bin entry composes `buildCli({ profile })` and that's it. The skeleton:
116
+ A profile is its own npm package — its bin entry composes `buildCli({ profile })` and that's it.
93
117
 
94
118
  ```ts
95
119
  import type { Profile } from 'dev-cockpit';
@@ -97,11 +121,22 @@ import type { Profile } from 'dev-cockpit';
97
121
  export const myProfile: Profile = {
98
122
  appName: 'my-app',
99
123
  healthChecks: [...],
100
- boot: ({ config, workspaceRoot }) => ({
101
- cockpitHandlers: { runRepoAction, onWatchToggle, onLint, onOpenError },
102
- subscribeFsEvents: (listener) => watcherManager.subscribeFsEvents(listener),
103
- cleanup: () => watcherManager.stop(),
104
- }),
124
+ boot: ({ config, workspaceRoot }) => {
125
+ const manager = new WatcherManager(...);
126
+ manager.start();
127
+ return {
128
+ // Per-repo programmatic actions: closure over the live WatcherManager.
129
+ actions: managedRepos.map((repo) => ({
130
+ id: `repo-rebuild:${repo.name}`,
131
+ label: `Rebuild ${repo.name}`,
132
+ scope: `repos:${repo.name}`,
133
+ key: 'r',
134
+ invoke: () => manager.rebuild(repo.name),
135
+ })),
136
+ subscribeFsEvents: (listener) => manager.subscribeFsEvents(listener),
137
+ cleanup: () => manager.stop(),
138
+ };
139
+ },
105
140
  };
106
141
 
107
142
  // Bin entry — that's it.
@@ -117,7 +152,7 @@ buildCli({ profile: myProfile }).parse(process.argv);
117
152
  | Commands | [`docs/commands.md`](./docs/commands.md) |
118
153
  | `init-config` wizard | [`docs/init-config.md`](./docs/init-config.md) |
119
154
  | Panes | [`docs/panes.md`](./docs/panes.md) |
120
- | Watchers | [`docs/watchers.md`](./docs/watchers.md) |
155
+ | Processes | [`docs/processes.md`](./docs/processes.md) |
121
156
  | Health | [`docs/health.md`](./docs/health.md) |
122
157
  | Mounts | [`docs/mount.md`](./docs/mount.md) |
123
158
  | Notifications | [`docs/notifications.md`](./docs/notifications.md) |
@@ -128,4 +163,4 @@ buildCli({ profile: myProfile }).parse(process.argv);
128
163
 
129
164
  ## Status
130
165
 
131
- Pre-1.0. The public surface (`Profile` interface, `buildCli`, the four core commands, `cockpit.yaml` schema with `version: 1`) is stable enough for first consumers to depend on; expect minor churn until the post-1.0 roadmap items land. See `CHANGELOG.md` for what's shipped.
166
+ Pre-1.0. The public surface (`Profile` interface, `buildCli`, the four core commands plus `migrate-config`, `cockpit.yaml` schema with `version: 2`) is stable enough for first consumers to depend on; expect minor churn until the rest of the post-1.0 roadmap items land. See `CHANGELOG.md` for what's shipped.
@@ -1,4 +1,30 @@
1
1
  #!/usr/bin/env node
2
+
3
+ // Engine guard. dev-cockpit's import graph (inquirer, ink/@inquirer/core
4
+ // transitives) uses `node:util.styleText` — added in Node 20.12 — at parse
5
+ // time, so older Node fails with a cryptic `SyntaxError: ... does not
6
+ // provide an export named 'styleText'`. Catch it here with a friendly
7
+ // message before any heavy import resolves.
8
+ {
9
+ const [major, minor] = process.versions.node.split('.').map(Number);
10
+ if (major < 20 || (major === 20 && minor < 12)) {
11
+ process.stderr.write(
12
+ `\ndev-cockpit: Node 20.12+ required (you are on ${process.versions.node}).\n` +
13
+ ` Run \`nvm use 22\` (or install Node >= 20.12) and retry.\n\n`,
14
+ );
15
+ process.exit(1);
16
+ }
17
+ }
18
+
19
+ // A11y: honour NO_COLOR strictly. chalk reads NO_COLOR at module-load time
20
+ // and disables foreground/background colours, but it keeps "style" modifiers
21
+ // (bold, inverse, dim) intact. Some terminals still render those visibly.
22
+ // Forcing FORCE_COLOR=0 before any import ensures chalk's level drops to 0,
23
+ // stripping styles too — true monochrome under NO_COLOR.
24
+ if (process.env.NO_COLOR !== undefined && process.env.NO_COLOR !== '') {
25
+ process.env.FORCE_COLOR = '0';
26
+ }
27
+
2
28
  // Filter Node 22's ExperimentalWarning about JSON modules. The warning fires
3
29
  // from a transitive dep (cli-boxes uses `import boxes from './boxes.json' with
4
30
  // {type: 'json'}`) the moment the cockpit shell's import graph resolves. It's
@@ -7,10 +33,6 @@
7
33
  // before cli-boxes loads.
8
34
  const orig = process.emitWarning.bind(process);
9
35
  process.emitWarning = (w, ...rest) => {
10
- // The JSON-modules warning fires as a plain string with the type passed
11
- // separately (`process.emitWarning(text, 'ExperimentalWarning')`), so we
12
- // match on the message text directly. The `.name` check from earlier
13
- // only worked when the caller handed us an Error object.
14
36
  const msg = typeof w === 'string' ? w : (w?.message ?? '');
15
37
  if (/JSON modules/i.test(msg)) return;
16
38
  return orig(w, ...rest);
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Built-in action synthesis.
3
+ *
4
+ * Generates default ActionConfig entries for kinds that have a natural
5
+ * single-keystroke action — docker services and processes both get `r` to
6
+ * restart by default. Users can shadow them by declaring an action with
7
+ * the same scope + key (declared wins during dispatch).
8
+ *
9
+ * Built-in ids are prefixed with `__builtin:` so the executor can detect
10
+ * them and run the right programmatic handler instead of shelling out.
11
+ */
12
+ import type { BaseCockpitConfig } from '../core/config.js';
13
+ import type { ActionConfig } from './types.js';
14
+ export declare const BUILTIN_PREFIX = "__builtin:";
15
+ export declare const BUILTIN_RESTART_DOCKER = "__builtin:restart-docker:";
16
+ export declare const BUILTIN_RESTART_PROCESS = "__builtin:restart-process:";
17
+ /**
18
+ * Synthesize built-in restart actions for every docker service and process
19
+ * declared in the config. Each action lives at `scope: repos:<id>` with
20
+ * `key: 'r'`. Commands carry a sentinel string only; the executor branches
21
+ * on the action's id, not its command.
22
+ */
23
+ export declare function buildBuiltinActions(config: BaseCockpitConfig): ActionConfig[];
24
+ export declare function isBuiltinAction(action: ActionConfig): boolean;
25
+ //# sourceMappingURL=builtin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../src/actions/builtin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,sBAAsB,8BAAqC,CAAC;AACzE,eAAO,MAAM,uBAAuB,+BAAsC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,YAAY,EAAE,CA0B7E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE7D"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Action dispatch helpers — pure lookup functions used by pane keystroke
3
+ * handlers and the right-hand Repos action panel.
4
+ *
5
+ * Precedence rule: user-declared (non-builtin) wins over built-in on
6
+ * matching (scope, key) collisions. This lets a user shadow the default
7
+ * `r` on a docker/process row with their own command.
8
+ */
9
+ import type { ActionConfig } from './types.js';
10
+ /**
11
+ * Actions that apply when the given row key is selected in Repos. Matches:
12
+ * - scope === `repos:${rowKey}` (row-specific)
13
+ * - scope === 'repos' (any row)
14
+ *
15
+ * Built-ins are placed AFTER declared so callers that take the first match
16
+ * get the user override automatically.
17
+ */
18
+ export declare function actionsForRepoRow(actions: readonly ActionConfig[], rowKey: string): ActionConfig[];
19
+ /** First action in scope matching the keypress, or undefined. */
20
+ export declare function findActionByKey(actions: readonly ActionConfig[], rowKey: string, keypress: string): ActionConfig | undefined;
21
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/actions/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,MAAM,EAAE,MAAM,GACb,YAAY,EAAE,CAehB;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,YAAY,GAAG,SAAS,CAE1B"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Build the action registry from config + profile sources.
3
+ *
4
+ * Merge rule: config entries win on `id` collision. Profile actions act
5
+ * as defaults the wrapper can override or remove (by re-declaring with
6
+ * the same id and a different command, or by omitting from config to
7
+ * keep the profile default).
8
+ */
9
+ import type { ActionConfig } from './types.js';
10
+ export declare function buildActionRegistry(configActions: readonly ActionConfig[], profileActions?: readonly ActionConfig[]): ActionConfig[];
11
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/actions/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,SAAS,YAAY,EAAE,EACtC,cAAc,GAAE,SAAS,YAAY,EAAO,GAC3C,YAAY,EAAE,CAKhB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Action subsystem types.
3
+ *
4
+ * An "action" is a named, optionally keystroke-bound shell command surfaced
5
+ * through the cockpit's `:` command palette and/or via direct keypress in a
6
+ * pane (when `key` + `scope` are set). Actions land via two sources merged
7
+ * at boot:
8
+ * 1. config.actions[] in cockpit.yaml — user/wrapper declarations
9
+ * 2. profile.actions — profile-bundle defaults
10
+ *
11
+ * Config entries win on `id` collision.
12
+ *
13
+ * Scope semantics:
14
+ * - 'global' — appears in the `:` palette regardless of focus
15
+ * - 'repos' — appears in `:` AND fires on Repos pane regardless of
16
+ * which row is selected (key dispatch applies to any
17
+ * Repos selection)
18
+ * - 'repos:<id>' — only fires on Repos pane when that specific row is
19
+ * selected; appears in the right-hand action panel
20
+ *
21
+ * If `key` is set, the action is dispatchable by a single keypress in the
22
+ * matching scope. Without `key`, the action is only reachable via `:`.
23
+ */
24
+ /**
25
+ * Action scope string. Runtime values:
26
+ * - 'global'
27
+ * - 'repos'
28
+ * - 'repos:<id>' where <id> matches /^[\w-]+$/
29
+ * Validated at the schema boundary; expressed as plain string in TS to keep
30
+ * the zod inference aligned with the runtime type (template-literal types
31
+ * can't be produced by `.regex()`).
32
+ */
33
+ export type ActionScope = string;
34
+ /** Per-invocation context passed to programmatic action handlers. */
35
+ export interface ActionInvokeContext {
36
+ /** Workspace root resolved by the cockpit's discoverer / config path. */
37
+ workspaceRoot: string;
38
+ /** Action that was matched (the same object the executor received). */
39
+ action: ActionConfig;
40
+ /** The Repos row id that was selected when the action fired, if any. */
41
+ rowKey?: string;
42
+ /** Push a line into the Output pane, tagged by the action's id. */
43
+ log: (line: string) => void;
44
+ /** Push a stderr-shaped warn line into the Output pane. */
45
+ errLog: (line: string) => void;
46
+ }
47
+ export interface ActionConfig {
48
+ /** Stable identifier — used by config-vs-profile dedup. */
49
+ id: string;
50
+ /** Display label in the `:` palette and the Repos action panel. */
51
+ label: string;
52
+ /**
53
+ * Shell command. Executed via `sh -c <command>` (cmd /c on Windows) so
54
+ * users can write pipes, redirects, env-prefixes, and quoted args. Mutually
55
+ * exclusive with `invoke`.
56
+ */
57
+ command?: string;
58
+ /**
59
+ * Programmatic handler — fires instead of shelling out. Profile-only:
60
+ * functions don't survive a YAML round-trip, so `config.actions[]` entries
61
+ * never carry this. Use for actions that mutate in-memory cockpit / profile
62
+ * state (rebuild via WatcherManager, toggle a chokidar watcher, etc.).
63
+ */
64
+ invoke?: (ctx: ActionInvokeContext) => void | Promise<void>;
65
+ /** Working directory; relative paths resolve against workspaceRoot. */
66
+ cwd?: string;
67
+ /** Action visibility / dispatch context. Default: 'global'. */
68
+ scope?: ActionScope;
69
+ /**
70
+ * Optional single-keystroke binding. Matched against the keypress within
71
+ * the action's scope. Case-sensitive at dispatch time so users can declare
72
+ * uppercase-only bindings. If absent, the action is reachable only via `:`.
73
+ */
74
+ key?: string;
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/actions/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,MAAM,EAAE,YAAY,CAAC;IACrB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,2DAA2D;IAC3D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildCli.d.ts","sourceRoot":"","sources":["../src/buildCli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAU/C,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAkBD,wBAAgB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAwF5D"}
1
+ {"version":3,"file":"buildCli.d.ts","sourceRoot":"","sources":["../src/buildCli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAW/C,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAkBD,wBAAgB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAgH5D"}
@@ -0,0 +1,46 @@
1
+ import { createRequire as __createRequireDC } from 'node:module';
2
+ const require = __createRequireDC(import.meta.url);
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
+ }) : x)(function(x) {
13
+ if (typeof require !== "undefined") return require.apply(this, arguments);
14
+ throw Error('Dynamic require of "' + x + '" is not supported');
15
+ });
16
+ var __commonJS = (cb, mod) => function __require2() {
17
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, { get: all[name], enumerable: true });
22
+ };
23
+ var __copyProps = (to, from, except, desc) => {
24
+ if (from && typeof from === "object" || typeof from === "function") {
25
+ for (let key of __getOwnPropNames(from))
26
+ if (!__hasOwnProp.call(to, key) && key !== except)
27
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28
+ }
29
+ return to;
30
+ };
31
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32
+ // If the importer is in node compatibility mode or this is not an ESM
33
+ // file that has been converted to a CommonJS file using a Babel-
34
+ // compatible transform (i.e. "__esModule" has not been set), then set
35
+ // "default" to the CommonJS "module.exports" for node compatibility.
36
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37
+ mod
38
+ ));
39
+
40
+ export {
41
+ __require,
42
+ __commonJS,
43
+ __export,
44
+ __toESM
45
+ };
46
+ //# sourceMappingURL=chunk-6XGHLLYT.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }