dev-cockpit 0.2.2 → 0.2.4

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.
@@ -7,7 +7,7 @@ import {
7
7
  manifestPath,
8
8
  removeMapping,
9
9
  setMapping
10
- } from "./chunk-C4GFJDMG.js";
10
+ } from "./chunk-A446TCT5.js";
11
11
  import "./chunk-6XGHLLYT.js";
12
12
 
13
13
  // src/commands/link.ts
@@ -62,4 +62,4 @@ export {
62
62
  linkListCommand,
63
63
  linkRemoveCommand
64
64
  };
65
- //# sourceMappingURL=link-HXNII7EU.js.map
65
+ //# sourceMappingURL=link-VWT2VQH6.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Resolve where the docker-compose overlay file should be written for a
3
+ * workspace.
4
+ *
5
+ * Default (no `mount.overlayPath` in cockpit.yaml):
6
+ * <stateDir>/dev-mount-overlay.yml
7
+ * — sibling to `mount.manifest.json`. Keeps the wrapper repo clean of
8
+ * per-developer state; aligns the overlay's lifecycle with the
9
+ * manifest's.
10
+ *
11
+ * Override (cockpit.yaml `mount.overlayPath` is set):
12
+ * - Workspace-relative paths resolve against `workspaceRoot`.
13
+ * - Absolute paths are honoured verbatim.
14
+ *
15
+ * Pure: no I/O. Tested in isolation.
16
+ */
17
+ export interface ResolveOverlayPathOptions {
18
+ /** Cockpit state dir for this workspace. */
19
+ stateDir: string;
20
+ /** Workspace root, used to resolve relative `configOverride`. */
21
+ workspaceRoot: string;
22
+ /** Optional `mount.overlayPath` value from cockpit.yaml. */
23
+ configOverride?: string | undefined;
24
+ }
25
+ export declare function resolveOverlayPath(opts: ResolveOverlayPathOptions): string;
26
+ //# sourceMappingURL=overlay-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-path.d.ts","sourceRoot":"","sources":["../../src/mount/overlay-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,yBAAyB;IACxC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAM1E"}
@@ -14,7 +14,7 @@ A `cockpit.yaml` lives at the root of your project. The cockpit reads it on star
14
14
  | `highlights` | array | no | Regex patterns applied to all output streams (process + docker). Each can carry an explicit `severity:` (else inferred). |
15
15
  | `health` | array | no | Health check declarations — see `health:` below. |
16
16
  | `actions` | array | no | Named, optionally key-bound shell commands surfaced via the `:` palette and the Targets pane. |
17
- | `mount` | object | no | `overlayPath`, `manifestFile` overrides. Defaults: `docker-compose.dev-cockpit.yml`, `mount.manifest.json`. |
17
+ | `mount` | object | no | `overlayPath`, `manifestFile` overrides. Defaults: `<stateDir>/dev-mount-overlay.yml` (sibling to the manifest, keeps the wrapper repo clean), `mount.manifest.json`. |
18
18
  | `mounts` | array | no | Explicit `{hostPath, containerPath, meta?}` entries for `dev-cockpit mount`. |
19
19
  | `help` | object | no | Extra `sources[]` + `defaultPage`. |
20
20
  | `notifications` | object | no | `enabled`, `onTransitionTo[]`, `exclude[]`. |
@@ -84,8 +84,9 @@ health:
84
84
  ## `mount:` + `mounts:`
85
85
 
86
86
  ```yaml
87
- mount: # path overrides
88
- overlayPath: docker-compose.dev-cockpit.yml # workspace-relative
87
+ mount: # path overrides — omit for defaults
88
+ # overlayPath: docker-compose.dev-cockpit.yml # default: <stateDir>/dev-mount-overlay.yml
89
+ # set to keep the overlay in-repo (workspace-relative or absolute)
89
90
  manifestFile: mount.manifest.json # basename within stateDir
90
91
 
91
92
  mounts: # explicit candidates
package/docs/mount.md CHANGED
@@ -26,22 +26,22 @@ dev-cockpit mount status # active mounts with branch / dirty / broken-sy
26
26
  dev-cockpit mount clear # remove overlay + manifest + symlinks
27
27
  ```
28
28
 
29
- Apply the generated overlay alongside your existing compose file:
29
+ Apply the generated overlay alongside your existing compose file (the path is printed by `dev-cockpit mount` — copy it from there):
30
30
 
31
31
  ```sh
32
- docker compose -f docker-compose.yml -f docker-compose.dev-cockpit.yml up -d
32
+ docker compose -f docker-compose.yml -f <stateDir>/dev-mount-overlay.yml up -d
33
33
  ```
34
34
 
35
35
  ## What gets written
36
36
 
37
37
  | File | Default path | Configurable via |
38
38
  |---|---|---|
39
- | Compose overlay | `<workspace>/docker-compose.dev-cockpit.yml` | `config.mount.overlayPath` |
39
+ | Compose overlay | `<stateDir>/dev-mount-overlay.yml` | `config.mount.overlayPath` |
40
40
  | Manifest | `<stateDir>/mount.manifest.json` | `config.mount.manifestFile` |
41
41
 
42
- `<stateDir>` lives under `$XDG_STATE_HOME/<appName>/<workspace-hash>/`. The manifest tracks what was applied and when, and is the source of truth for `status` and `clear`.
42
+ `<stateDir>` lives under `$XDG_STATE_HOME/<appName>/<workspace-hash>/`. Both files share that location, so anything cockpit knows about *this workspace's mounts* sits in one dir — clean wrapper repo, no per-developer artefacts to gitignore.
43
43
 
44
- Override the paths when the wrapper has its own conventions:
44
+ Override the overlay path when the wrapper has its own conventions (workspace-relative or absolute):
45
45
 
46
46
  ```yaml
47
47
  mount:
@@ -0,0 +1,280 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/frankfava/package--dev-cockpit/main/examples/cockpit.schema.json",
4
+ "title": "dev-cockpit cockpit.yaml",
5
+ "description": "Configuration file for dev-cockpit and profile-based cockpits. Mirrors BaseCockpitConfigSchema in src/core/config.ts — keep both in sync when adding fields.",
6
+ "type": "object",
7
+ "required": ["version", "appName"],
8
+ "properties": {
9
+ "version": {
10
+ "type": "integer",
11
+ "const": 2,
12
+ "description": "Config schema version. Current: 2. Older configs (v1) are migrated in memory; run `dev-cockpit migrate-config` to persist."
13
+ },
14
+ "appName": {
15
+ "type": "string",
16
+ "description": "State-dir name under $XDG_STATE_HOME (default: ~/.local/state/<appName>/<workspace-hash>/)."
17
+ },
18
+ "processes": {
19
+ "type": "array",
20
+ "description": "Long-running commands streamed into the Output pane. Each runs once at startup and is restarted on `restartOn` fsevents.",
21
+ "items": { "$ref": "#/$defs/Process" }
22
+ },
23
+ "repos": {
24
+ "type": "array",
25
+ "description": "Rows shown in the Repos/Targets pane.",
26
+ "items": { "$ref": "#/$defs/Repo" }
27
+ },
28
+ "docker": {
29
+ "$ref": "#/$defs/Docker",
30
+ "description": "Compose log tailing + container health-check enabler. Omit for non-docker projects to hide the docker pieces entirely."
31
+ },
32
+ "highlights": {
33
+ "type": "array",
34
+ "description": "Regex patterns applied to all output streams (processes + docker). Each can carry an explicit severity; otherwise inferred.",
35
+ "items": { "$ref": "#/$defs/Highlight" }
36
+ },
37
+ "health": {
38
+ "type": "array",
39
+ "description": "Health-check declarations. `type` references a built-in (`container-running` | `port-open` | `http-ok` | `file-exists` | `exec-zero`) or a profile-registered check id.",
40
+ "items": { "$ref": "#/$defs/HealthCheck" }
41
+ },
42
+ "help": {
43
+ "$ref": "#/$defs/Help",
44
+ "description": "Extra markdown directories layered on top of the built-in help."
45
+ },
46
+ "notifications": {
47
+ "$ref": "#/$defs/Notifications",
48
+ "description": "Native OS notifications, transition-only by default."
49
+ },
50
+ "mounts": {
51
+ "type": "array",
52
+ "description": "Explicit `{hostPath, containerPath, meta?}` candidates for `dev-cockpit mount`. Merged with `profile.mountCandidatesProvider()`.",
53
+ "items": { "$ref": "#/$defs/Mount" }
54
+ },
55
+ "mount": {
56
+ "$ref": "#/$defs/MountSettings",
57
+ "description": "Overlay/manifest path overrides. Default overlay lives at <stateDir>/dev-mount-overlay.yml (out of the repo)."
58
+ },
59
+ "defaultPane": {
60
+ "type": "string",
61
+ "enum": ["repos", "output", "health", "help"],
62
+ "description": "Which pane the cockpit lands on when it boots. Profile may override; falls back to Output when the requested tab is hidden."
63
+ },
64
+ "actions": {
65
+ "type": "array",
66
+ "description": "Named, key-bound shell commands surfaced via the `:` command palette and the Targets pane.",
67
+ "items": { "$ref": "#/$defs/Action" }
68
+ },
69
+ "profile": {
70
+ "type": "object",
71
+ "description": "Profile-specific config namespace. Each profile owns one key under here (e.g. `profile.awc-cockpit: { gitlab: {...} }`) and validates it via its own configSchemaExt."
72
+ }
73
+ },
74
+ "additionalProperties": false,
75
+ "$defs": {
76
+ "NotifyOverride": {
77
+ "description": "Either `false` (mute notifications for this item) or `{ onTransitionTo: [...] }` to override the global transition list.",
78
+ "oneOf": [
79
+ { "type": "boolean", "const": false },
80
+ {
81
+ "type": "object",
82
+ "properties": {
83
+ "onTransitionTo": {
84
+ "type": "array",
85
+ "items": { "type": "string" }
86
+ }
87
+ },
88
+ "additionalProperties": false
89
+ }
90
+ ]
91
+ },
92
+ "Process": {
93
+ "type": "object",
94
+ "required": ["id", "command"],
95
+ "properties": {
96
+ "id": { "type": "string" },
97
+ "label": { "type": "string" },
98
+ "command": { "type": "string", "description": "Shell command. Spawned via the wrapper with the workspace as cwd by default." },
99
+ "cwd": { "type": "string", "description": "Workspace-relative override of the process working dir." },
100
+ "env": { "type": "object", "additionalProperties": { "type": "string" } },
101
+ "color": { "type": "string", "description": "ANSI colour for prefixed output (cyan / magenta / yellow / blue / green / red / white)." },
102
+ "restartOn": {
103
+ "type": "array",
104
+ "items": { "type": "string" },
105
+ "description": "Glob patterns; when a matching file changes, the process is killed + respawned."
106
+ },
107
+ "notify": { "$ref": "#/$defs/NotifyOverride" }
108
+ },
109
+ "additionalProperties": false
110
+ },
111
+ "Repo": {
112
+ "type": "object",
113
+ "required": ["id", "path"],
114
+ "properties": {
115
+ "id": { "type": "string" },
116
+ "path": { "type": "string", "description": "Workspace-relative path to the repo root." },
117
+ "label": { "type": "string" }
118
+ },
119
+ "additionalProperties": false
120
+ },
121
+ "Service": {
122
+ "type": "object",
123
+ "required": ["name"],
124
+ "properties": {
125
+ "name": { "type": "string", "description": "Compose service name." },
126
+ "tail": { "type": "boolean", "default": true }
127
+ },
128
+ "additionalProperties": false
129
+ },
130
+ "Docker": {
131
+ "type": "object",
132
+ "properties": {
133
+ "composeFile": {
134
+ "type": "string",
135
+ "description": "Workspace-relative path to docker-compose.yml. When unset, docker compose auto-discovers from cwd."
136
+ },
137
+ "services": {
138
+ "type": "array",
139
+ "items": { "$ref": "#/$defs/Service" },
140
+ "description": "Services to tail in the Output pane + reference as `container-running` health check targets."
141
+ }
142
+ },
143
+ "additionalProperties": false
144
+ },
145
+ "Highlight": {
146
+ "type": "object",
147
+ "required": ["pattern"],
148
+ "properties": {
149
+ "pattern": { "type": "string", "description": "JavaScript-flavour regex." },
150
+ "severity": {
151
+ "type": "string",
152
+ "enum": ["info", "warn", "error"],
153
+ "default": "info"
154
+ }
155
+ },
156
+ "additionalProperties": false
157
+ },
158
+ "Remediation": {
159
+ "type": "object",
160
+ "required": ["key", "label", "command"],
161
+ "properties": {
162
+ "key": { "type": "string", "minLength": 1, "maxLength": 1, "description": "Single key character that triggers the remediation in the Health pane." },
163
+ "label": { "type": "string" },
164
+ "command": { "type": "string" },
165
+ "cwd": { "type": "string" }
166
+ },
167
+ "additionalProperties": false
168
+ },
169
+ "HealthCheck": {
170
+ "type": "object",
171
+ "required": ["id", "label", "type", "remediation"],
172
+ "properties": {
173
+ "id": { "type": "string" },
174
+ "label": { "type": "string" },
175
+ "type": {
176
+ "type": "string",
177
+ "description": "Built-in: container-running | port-open | http-ok | file-exists | exec-zero. Profiles may register additional check types."
178
+ },
179
+ "severity": {
180
+ "type": "string",
181
+ "enum": ["ok", "warn", "error"],
182
+ "description": "Severity to report on failure (default error)."
183
+ },
184
+ "triggers": {
185
+ "type": "array",
186
+ "items": { "type": "string", "enum": ["startup", "fsevent", "lockfile", "docker"] },
187
+ "description": "When to re-run this check. Sensible defaults per check type when omitted."
188
+ },
189
+ "url": { "type": "string", "description": "http-ok target." },
190
+ "expectStatus": { "type": "integer", "description": "http-ok success status (default 200)." },
191
+ "container": { "type": "string", "description": "container-running target — compose service or container name (substring match against `docker ps --filter name=`)." },
192
+ "port": { "type": "integer", "description": "port-open TCP port." },
193
+ "host": { "type": "string", "description": "port-open / http-ok host override (default 127.0.0.1)." },
194
+ "path": { "type": "string", "description": "file-exists path (workspace-relative)." },
195
+ "command": { "type": "string", "description": "exec-zero command to run (success = exit 0)." },
196
+ "args": { "type": "array", "items": { "type": "string" }, "description": "exec-zero argv." },
197
+ "cwd": { "type": "string", "description": "exec-zero cwd override." },
198
+ "notify": { "$ref": "#/$defs/NotifyOverride" },
199
+ "remediation": { "$ref": "#/$defs/Remediation" }
200
+ },
201
+ "additionalProperties": false
202
+ },
203
+ "Help": {
204
+ "type": "object",
205
+ "properties": {
206
+ "sources": {
207
+ "type": "array",
208
+ "items": { "type": "string" },
209
+ "description": "Workspace-relative paths to markdown dirs layered on top of built-in help."
210
+ },
211
+ "defaultPage": { "type": "string", "description": "Slug of the page to land on when Help opens." }
212
+ },
213
+ "additionalProperties": false
214
+ },
215
+ "Notifications": {
216
+ "type": "object",
217
+ "properties": {
218
+ "enabled": { "type": "boolean", "default": true },
219
+ "onTransitionTo": {
220
+ "type": "array",
221
+ "items": { "type": "string" },
222
+ "description": "Severities that fire a notification on transition (default: [error, recovered])."
223
+ },
224
+ "exclude": {
225
+ "type": "array",
226
+ "items": { "type": "string" },
227
+ "description": "Check ids to mute even when their severity matches."
228
+ }
229
+ },
230
+ "additionalProperties": false
231
+ },
232
+ "Mount": {
233
+ "type": "object",
234
+ "required": ["hostPath", "containerPath"],
235
+ "properties": {
236
+ "hostPath": { "type": "string" },
237
+ "containerPath": { "type": "string" },
238
+ "meta": { "type": "object", "description": "Opaque to dev-cockpit core; consumed by profile hooks (e.g. awc reads meta.name and meta.type)." }
239
+ },
240
+ "additionalProperties": false
241
+ },
242
+ "MountSettings": {
243
+ "type": "object",
244
+ "properties": {
245
+ "overlayPath": {
246
+ "type": "string",
247
+ "description": "Override for the generated docker-compose overlay. Unset = <stateDir>/dev-mount-overlay.yml (recommended). Set values are workspace-relative; absolute paths honoured verbatim."
248
+ },
249
+ "manifestFile": {
250
+ "type": "string",
251
+ "default": "mount.manifest.json",
252
+ "description": "Basename inside stateDir for the mount manifest."
253
+ }
254
+ },
255
+ "additionalProperties": false
256
+ },
257
+ "Action": {
258
+ "type": "object",
259
+ "required": ["id", "label", "command"],
260
+ "properties": {
261
+ "id": { "type": "string" },
262
+ "label": { "type": "string" },
263
+ "command": { "type": "string", "description": "Shell command to run. cwd defaults to the workspace." },
264
+ "cwd": { "type": "string" },
265
+ "scope": {
266
+ "type": "string",
267
+ "pattern": "^(global|repos(:[\\w-]+)?)$",
268
+ "description": "Where the action appears: 'global' (palette only), 'repos' (every repo row), or 'repos:<id>' (a specific repo)."
269
+ },
270
+ "key": {
271
+ "type": "string",
272
+ "minLength": 1,
273
+ "maxLength": 1,
274
+ "description": "Single key character that fires the action when the row is focused or the palette is open."
275
+ }
276
+ },
277
+ "additionalProperties": false
278
+ }
279
+ }
280
+ }
@@ -1,11 +1,18 @@
1
- # cockpit.yaml — example config
1
+ # yaml-language-server: $schema=./cockpit.schema.json
2
+ # cockpit.yaml — example config (schema v2)
2
3
  # Run `dev-cockpit dev` from the directory containing this file.
4
+ # Or, if it lives elsewhere:
5
+ # dev-cockpit link <path/to/this-file> # registers cwd → this config
6
+ # dev-cockpit dev # picks it up via the manifest
7
+ # DEV_COCKPIT_CONFIG=<path> dev-cockpit dev # one-shot env override
8
+ # dev-cockpit dev --config <path> # one-shot CLI override
3
9
 
4
- version: 1 # config schema version; required
5
- appName: my-app # state dir: ~/.local/state/my-app/
10
+ version: 2 # config schema version; required (v1 auto-migrated in memory)
11
+ appName: my-app # state dir: ~/.local/state/my-app/<workspace-hash>/
6
12
 
7
- # Watchers — long-running commands streamed into the Output pane.
8
- watchers:
13
+ # Processes — long-running commands streamed into the Output pane.
14
+ # Renamed from `watchers` in schema v2; v1 configs still load with a one-time warning.
15
+ processes:
9
16
  - id: typecheck
10
17
  label: tsc --watch
11
18
  command: npx tsc --watch --noEmit
@@ -18,12 +25,12 @@ watchers:
18
25
  label: eslint
19
26
  command: npx eslint . --watch
20
27
  color: yellow
21
- notify: false # mute notifications for this watcher
28
+ notify: false # mute notifications for this process
22
29
  restartOn:
23
30
  - package.json
24
31
  - .eslintrc.*
25
32
 
26
- # Repos — what shows in the Repos pane (optional; default = empty).
33
+ # Repos — rows in the Repos/Targets pane.
27
34
  repos:
28
35
  - id: api
29
36
  path: ./packages/api
@@ -33,7 +40,7 @@ repos:
33
40
  label: Web
34
41
 
35
42
  # Docker — enables container log tailing, container health checks, mount overlay.
36
- # Omit this whole block for plain-Node projects; the docker tab/section won't appear.
43
+ # Omit this whole block for plain-Node projects; the docker pieces stay hidden.
37
44
  docker:
38
45
  composeFile: ./docker-compose.yml
39
46
  services:
@@ -44,7 +51,7 @@ docker:
44
51
  - name: redis
45
52
  tail: false
46
53
 
47
- # Highlight patterns — applied to all log streams.
54
+ # Highlight patterns — applied to all output streams (processes + docker logs).
48
55
  highlights:
49
56
  - pattern: ERROR
50
57
  severity: error
@@ -96,7 +103,7 @@ health:
96
103
  label: run migrations
97
104
  command: npm run db:migrate
98
105
 
99
- # Help — extra markdown directories layered on top of core's built-in docs.
106
+ # Help — extra markdown directories layered on top of the built-in help.
100
107
  help:
101
108
  sources:
102
109
  - ./docs
@@ -109,6 +116,25 @@ notifications:
109
116
  - error
110
117
  - recovered
111
118
 
119
+ # Mount overlay placement (optional). Default: <stateDir>/dev-mount-overlay.yml,
120
+ # sibling to mount.manifest.json — keeps the wrapper repo clean of per-developer
121
+ # state. Set if you want the overlay in-repo for any reason.
122
+ # mount:
123
+ # overlayPath: docker/compose/dev-mount-overlay.yml # workspace-relative
124
+ # manifestFile: mount.manifest.json # basename inside stateDir
125
+
126
+ # Actions — named, key-bound shell commands surfaced via the `:` palette and
127
+ # the Targets pane. `scope` values: `global` | `repos` | `repos:<id>`.
128
+ actions:
129
+ - id: docs
130
+ label: Open docs
131
+ command: open ./docs/index.html
132
+ scope: global
133
+ key: o
134
+
135
+ # Which pane the cockpit lands on when it boots.
136
+ defaultPane: repos # repos | output | health | help
137
+
112
138
  # Profile-specific config lives under `profile.<name>` — validated by the
113
139
  # profile's `configSchemaExt` zod extension. Generic core ignores this block.
114
140
  # profile:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-cockpit",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "A reusable, domain-neutral terminal UI dev cockpit — tabbed pane shell, watcher streaming, optional Docker log tail with highlights, health framework with one-keystroke remediations, transition-only OS notifications, live-markdown Help. Profiles extend it with project-specific commands, repos, and health checks.",
5
5
  "license": "MIT",
6
6
  "repository": {