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.
Files changed (169) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +21 -0
  3. package/README.md +131 -0
  4. package/bin/dev-cockpit.mjs +20 -0
  5. package/dist/buildCli.d.ts +17 -0
  6. package/dist/buildCli.d.ts.map +1 -0
  7. package/dist/buildCli.js +107 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +2 -0
  11. package/dist/cockpit/Cockpit.d.ts +33 -0
  12. package/dist/cockpit/Cockpit.d.ts.map +1 -0
  13. package/dist/cockpit/Cockpit.js +73 -0
  14. package/dist/cockpit/Footer.d.ts +22 -0
  15. package/dist/cockpit/Footer.d.ts.map +1 -0
  16. package/dist/cockpit/Footer.js +33 -0
  17. package/dist/cockpit/TabBar.d.ts +3 -0
  18. package/dist/cockpit/TabBar.d.ts.map +1 -0
  19. package/dist/cockpit/TabBar.js +12 -0
  20. package/dist/cockpit/help/content.d.ts +12 -0
  21. package/dist/cockpit/help/content.d.ts.map +1 -0
  22. package/dist/cockpit/help/content.js +22 -0
  23. package/dist/cockpit/help/loader.d.ts +65 -0
  24. package/dist/cockpit/help/loader.d.ts.map +1 -0
  25. package/dist/cockpit/help/loader.js +118 -0
  26. package/dist/cockpit/help/renderer.d.ts +16 -0
  27. package/dist/cockpit/help/renderer.d.ts.map +1 -0
  28. package/dist/cockpit/help/renderer.js +35 -0
  29. package/dist/cockpit/help/types.d.ts +12 -0
  30. package/dist/cockpit/help/types.d.ts.map +1 -0
  31. package/dist/cockpit/help/types.js +1 -0
  32. package/dist/cockpit/hooks/useCockpitStore.d.ts +3 -0
  33. package/dist/cockpit/hooks/useCockpitStore.d.ts.map +1 -0
  34. package/dist/cockpit/hooks/useCockpitStore.js +5 -0
  35. package/dist/cockpit/hooks/useGlobalKeys.d.ts +56 -0
  36. package/dist/cockpit/hooks/useGlobalKeys.d.ts.map +1 -0
  37. package/dist/cockpit/hooks/useGlobalKeys.js +173 -0
  38. package/dist/cockpit/panes/FilterModal.d.ts +3 -0
  39. package/dist/cockpit/panes/FilterModal.d.ts.map +1 -0
  40. package/dist/cockpit/panes/FilterModal.js +22 -0
  41. package/dist/cockpit/panes/Health.d.ts +13 -0
  42. package/dist/cockpit/panes/Health.d.ts.map +1 -0
  43. package/dist/cockpit/panes/Health.js +30 -0
  44. package/dist/cockpit/panes/Help.d.ts +14 -0
  45. package/dist/cockpit/panes/Help.d.ts.map +1 -0
  46. package/dist/cockpit/panes/Help.js +81 -0
  47. package/dist/cockpit/panes/Output.d.ts +14 -0
  48. package/dist/cockpit/panes/Output.d.ts.map +1 -0
  49. package/dist/cockpit/panes/Output.js +108 -0
  50. package/dist/cockpit/panes/Repos.d.ts +3 -0
  51. package/dist/cockpit/panes/Repos.d.ts.map +1 -0
  52. package/dist/cockpit/panes/Repos.js +48 -0
  53. package/dist/cockpit/panes/SearchModal.d.ts +3 -0
  54. package/dist/cockpit/panes/SearchModal.d.ts.map +1 -0
  55. package/dist/cockpit/panes/SearchModal.js +31 -0
  56. package/dist/cockpit/state/store.d.ts +93 -0
  57. package/dist/cockpit/state/store.d.ts.map +1 -0
  58. package/dist/cockpit/state/store.js +111 -0
  59. package/dist/cockpit/tab-state.d.ts +4 -0
  60. package/dist/cockpit/tab-state.d.ts.map +1 -0
  61. package/dist/cockpit/tab-state.js +7 -0
  62. package/dist/commands/dev.d.ts +20 -0
  63. package/dist/commands/dev.d.ts.map +1 -0
  64. package/dist/commands/dev.js +158 -0
  65. package/dist/commands/doctor.d.ts +20 -0
  66. package/dist/commands/doctor.d.ts.map +1 -0
  67. package/dist/commands/doctor.js +66 -0
  68. package/dist/commands/init-config-wizard.d.ts +84 -0
  69. package/dist/commands/init-config-wizard.d.ts.map +1 -0
  70. package/dist/commands/init-config-wizard.js +818 -0
  71. package/dist/commands/init-config.d.ts +35 -0
  72. package/dist/commands/init-config.d.ts.map +1 -0
  73. package/dist/commands/init-config.js +131 -0
  74. package/dist/commands/mount.d.ts +48 -0
  75. package/dist/commands/mount.d.ts.map +1 -0
  76. package/dist/commands/mount.js +150 -0
  77. package/dist/core/config.d.ts +391 -0
  78. package/dist/core/config.d.ts.map +1 -0
  79. package/dist/core/config.js +152 -0
  80. package/dist/core/logger.d.ts +6 -0
  81. package/dist/core/logger.d.ts.map +1 -0
  82. package/dist/core/logger.js +38 -0
  83. package/dist/core/notifier.d.ts +23 -0
  84. package/dist/core/notifier.d.ts.map +1 -0
  85. package/dist/core/notifier.js +100 -0
  86. package/dist/core/paths.d.ts +15 -0
  87. package/dist/core/paths.d.ts.map +1 -0
  88. package/dist/core/paths.js +18 -0
  89. package/dist/core/subprocess.d.ts +20 -0
  90. package/dist/core/subprocess.d.ts.map +1 -0
  91. package/dist/core/subprocess.js +82 -0
  92. package/dist/core/types.d.ts +125 -0
  93. package/dist/core/types.d.ts.map +1 -0
  94. package/dist/core/types.js +1 -0
  95. package/dist/docker/highlights.d.ts +48 -0
  96. package/dist/docker/highlights.d.ts.map +1 -0
  97. package/dist/docker/highlights.js +79 -0
  98. package/dist/docker/logs.d.ts +84 -0
  99. package/dist/docker/logs.d.ts.map +1 -0
  100. package/dist/docker/logs.js +172 -0
  101. package/dist/docker/restart.d.ts +26 -0
  102. package/dist/docker/restart.d.ts.map +1 -0
  103. package/dist/docker/restart.js +45 -0
  104. package/dist/docker/stack-trace.d.ts +25 -0
  105. package/dist/docker/stack-trace.d.ts.map +1 -0
  106. package/dist/docker/stack-trace.js +44 -0
  107. package/dist/health/builtin.d.ts +8 -0
  108. package/dist/health/builtin.d.ts.map +1 -0
  109. package/dist/health/builtin.js +144 -0
  110. package/dist/health/context.d.ts +3 -0
  111. package/dist/health/context.d.ts.map +1 -0
  112. package/dist/health/context.js +31 -0
  113. package/dist/health/notify-resolver.d.ts +18 -0
  114. package/dist/health/notify-resolver.d.ts.map +1 -0
  115. package/dist/health/notify-resolver.js +28 -0
  116. package/dist/health/registry.d.ts +20 -0
  117. package/dist/health/registry.d.ts.map +1 -0
  118. package/dist/health/registry.js +64 -0
  119. package/dist/health/remediations.d.ts +6 -0
  120. package/dist/health/remediations.d.ts.map +1 -0
  121. package/dist/health/remediations.js +41 -0
  122. package/dist/health/runner.d.ts +4 -0
  123. package/dist/health/runner.d.ts.map +1 -0
  124. package/dist/health/runner.js +22 -0
  125. package/dist/health/scheduler.d.ts +41 -0
  126. package/dist/health/scheduler.d.ts.map +1 -0
  127. package/dist/health/scheduler.js +107 -0
  128. package/dist/health/types.d.ts +73 -0
  129. package/dist/health/types.d.ts.map +1 -0
  130. package/dist/health/types.js +1 -0
  131. package/dist/health/useHealth.d.ts +40 -0
  132. package/dist/health/useHealth.d.ts.map +1 -0
  133. package/dist/health/useHealth.js +122 -0
  134. package/dist/index.d.ts +50 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +53 -0
  137. package/dist/ink.d.ts +3 -0
  138. package/dist/ink.d.ts.map +1 -0
  139. package/dist/ink.js +1 -0
  140. package/dist/lint/reactive.d.ts +38 -0
  141. package/dist/lint/reactive.d.ts.map +1 -0
  142. package/dist/lint/reactive.js +131 -0
  143. package/dist/react.d.ts +3 -0
  144. package/dist/react.d.ts.map +1 -0
  145. package/dist/react.js +1 -0
  146. package/dist/runCockpit.d.ts +34 -0
  147. package/dist/runCockpit.d.ts.map +1 -0
  148. package/dist/runCockpit.js +75 -0
  149. package/dist/watchers/manager.d.ts +63 -0
  150. package/dist/watchers/manager.d.ts.map +1 -0
  151. package/dist/watchers/manager.js +239 -0
  152. package/dist/watchers/path-mapper.d.ts +23 -0
  153. package/dist/watchers/path-mapper.d.ts.map +1 -0
  154. package/dist/watchers/path-mapper.js +29 -0
  155. package/dist/watchers/types.d.ts +22 -0
  156. package/dist/watchers/types.d.ts.map +1 -0
  157. package/dist/watchers/types.js +9 -0
  158. package/docs/commands.md +71 -0
  159. package/docs/config-reference.md +20 -0
  160. package/docs/getting-started.md +39 -0
  161. package/docs/health.md +120 -0
  162. package/docs/index.md +13 -0
  163. package/docs/init-config.md +46 -0
  164. package/docs/mount.md +55 -0
  165. package/docs/notifications.md +39 -0
  166. package/docs/panes.md +45 -0
  167. package/docs/watchers.md +27 -0
  168. package/examples/cockpit.yaml +116 -0
  169. package/package.json +91 -0
@@ -0,0 +1,391 @@
1
+ import { z } from 'zod';
2
+ /** Schema version constant. Bumps reserved for breaking changes (see ADR 0004). */
3
+ export declare const CONFIG_VERSION = 1;
4
+ export declare const BaseCockpitConfigSchema: z.ZodObject<{
5
+ version: z.ZodNumber;
6
+ appName: z.ZodString;
7
+ watchers: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
8
+ id: z.ZodString;
9
+ label: z.ZodOptional<z.ZodString>;
10
+ command: z.ZodString;
11
+ cwd: z.ZodOptional<z.ZodString>;
12
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
13
+ color: z.ZodOptional<z.ZodString>;
14
+ restartOn: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
+ notify: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodObject<{
16
+ onTransitionTo: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ onTransitionTo?: string[] | undefined;
19
+ }, {
20
+ onTransitionTo?: string[] | undefined;
21
+ }>]>>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ id: string;
24
+ command: string;
25
+ label?: string | undefined;
26
+ cwd?: string | undefined;
27
+ env?: Record<string, string> | undefined;
28
+ color?: string | undefined;
29
+ restartOn?: string[] | undefined;
30
+ notify?: false | {
31
+ onTransitionTo?: string[] | undefined;
32
+ } | undefined;
33
+ }, {
34
+ id: string;
35
+ command: string;
36
+ label?: string | undefined;
37
+ cwd?: string | undefined;
38
+ env?: Record<string, string> | undefined;
39
+ color?: string | undefined;
40
+ restartOn?: string[] | undefined;
41
+ notify?: false | {
42
+ onTransitionTo?: string[] | undefined;
43
+ } | undefined;
44
+ }>, "many">>>;
45
+ repos: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
46
+ id: z.ZodString;
47
+ path: z.ZodString;
48
+ label: z.ZodOptional<z.ZodString>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ path: string;
51
+ id: string;
52
+ label?: string | undefined;
53
+ }, {
54
+ path: string;
55
+ id: string;
56
+ label?: string | undefined;
57
+ }>, "many">>>;
58
+ docker: z.ZodOptional<z.ZodObject<{
59
+ composeFile: z.ZodOptional<z.ZodString>;
60
+ services: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
61
+ name: z.ZodString;
62
+ tail: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ name: string;
65
+ tail: boolean;
66
+ }, {
67
+ name: string;
68
+ tail?: boolean | undefined;
69
+ }>, "many">>>;
70
+ }, "strip", z.ZodTypeAny, {
71
+ services: {
72
+ name: string;
73
+ tail: boolean;
74
+ }[];
75
+ composeFile?: string | undefined;
76
+ }, {
77
+ composeFile?: string | undefined;
78
+ services?: {
79
+ name: string;
80
+ tail?: boolean | undefined;
81
+ }[] | undefined;
82
+ }>>;
83
+ highlights: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
84
+ pattern: z.ZodString;
85
+ severity: z.ZodDefault<z.ZodOptional<z.ZodEnum<["info", "warn", "error"]>>>;
86
+ }, "strip", z.ZodTypeAny, {
87
+ pattern: string;
88
+ severity: "info" | "warn" | "error";
89
+ }, {
90
+ pattern: string;
91
+ severity?: "info" | "warn" | "error" | undefined;
92
+ }>, "many">>>;
93
+ health: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
94
+ id: z.ZodString;
95
+ label: z.ZodString;
96
+ type: z.ZodString;
97
+ severity: z.ZodOptional<z.ZodEnum<["ok", "warn", "error"]>>;
98
+ triggers: z.ZodOptional<z.ZodArray<z.ZodEnum<["startup", "fsevent", "lockfile", "docker"]>, "many">>;
99
+ url: z.ZodOptional<z.ZodString>;
100
+ expectStatus: z.ZodOptional<z.ZodNumber>;
101
+ container: z.ZodOptional<z.ZodString>;
102
+ port: z.ZodOptional<z.ZodNumber>;
103
+ host: z.ZodOptional<z.ZodString>;
104
+ path: z.ZodOptional<z.ZodString>;
105
+ command: z.ZodOptional<z.ZodString>;
106
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
107
+ cwd: z.ZodOptional<z.ZodString>;
108
+ notify: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodObject<{
109
+ onTransitionTo: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
110
+ }, "strip", z.ZodTypeAny, {
111
+ onTransitionTo?: string[] | undefined;
112
+ }, {
113
+ onTransitionTo?: string[] | undefined;
114
+ }>]>>;
115
+ remediation: z.ZodObject<{
116
+ key: z.ZodString;
117
+ label: z.ZodString;
118
+ command: z.ZodString;
119
+ cwd: z.ZodOptional<z.ZodString>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ label: string;
122
+ command: string;
123
+ key: string;
124
+ cwd?: string | undefined;
125
+ }, {
126
+ label: string;
127
+ command: string;
128
+ key: string;
129
+ cwd?: string | undefined;
130
+ }>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ type: string;
133
+ id: string;
134
+ label: string;
135
+ remediation: {
136
+ label: string;
137
+ command: string;
138
+ key: string;
139
+ cwd?: string | undefined;
140
+ };
141
+ path?: string | undefined;
142
+ command?: string | undefined;
143
+ cwd?: string | undefined;
144
+ notify?: false | {
145
+ onTransitionTo?: string[] | undefined;
146
+ } | undefined;
147
+ severity?: "warn" | "error" | "ok" | undefined;
148
+ triggers?: ("startup" | "fsevent" | "lockfile" | "docker")[] | undefined;
149
+ url?: string | undefined;
150
+ expectStatus?: number | undefined;
151
+ container?: string | undefined;
152
+ port?: number | undefined;
153
+ host?: string | undefined;
154
+ args?: string[] | undefined;
155
+ }, {
156
+ type: string;
157
+ id: string;
158
+ label: string;
159
+ remediation: {
160
+ label: string;
161
+ command: string;
162
+ key: string;
163
+ cwd?: string | undefined;
164
+ };
165
+ path?: string | undefined;
166
+ command?: string | undefined;
167
+ cwd?: string | undefined;
168
+ notify?: false | {
169
+ onTransitionTo?: string[] | undefined;
170
+ } | undefined;
171
+ severity?: "warn" | "error" | "ok" | undefined;
172
+ triggers?: ("startup" | "fsevent" | "lockfile" | "docker")[] | undefined;
173
+ url?: string | undefined;
174
+ expectStatus?: number | undefined;
175
+ container?: string | undefined;
176
+ port?: number | undefined;
177
+ host?: string | undefined;
178
+ args?: string[] | undefined;
179
+ }>, "many">>>;
180
+ help: z.ZodDefault<z.ZodOptional<z.ZodObject<{
181
+ sources: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
182
+ defaultPage: z.ZodOptional<z.ZodString>;
183
+ }, "strip", z.ZodTypeAny, {
184
+ sources: string[];
185
+ defaultPage?: string | undefined;
186
+ }, {
187
+ sources?: string[] | undefined;
188
+ defaultPage?: string | undefined;
189
+ }>>>;
190
+ notifications: z.ZodDefault<z.ZodOptional<z.ZodObject<{
191
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
192
+ onTransitionTo: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
193
+ exclude: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
194
+ }, "strip", z.ZodTypeAny, {
195
+ onTransitionTo: string[];
196
+ enabled: boolean;
197
+ exclude: string[];
198
+ }, {
199
+ onTransitionTo?: string[] | undefined;
200
+ enabled?: boolean | undefined;
201
+ exclude?: string[] | undefined;
202
+ }>>>;
203
+ mounts: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
204
+ hostPath: z.ZodString;
205
+ containerPath: z.ZodString;
206
+ }, "strip", z.ZodTypeAny, {
207
+ hostPath: string;
208
+ containerPath: string;
209
+ }, {
210
+ hostPath: string;
211
+ containerPath: string;
212
+ }>, "many">>>;
213
+ /**
214
+ * Profile-specific config namespace. Each profile owns one key under here
215
+ * (e.g. `profile.myapp = { ... }`) and validates it with its own zod schema
216
+ * passed to the loader as `configSchemaExt`.
217
+ */
218
+ profile: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
219
+ }, "strip", z.ZodTypeAny, {
220
+ version: number;
221
+ appName: string;
222
+ watchers: {
223
+ id: string;
224
+ command: string;
225
+ label?: string | undefined;
226
+ cwd?: string | undefined;
227
+ env?: Record<string, string> | undefined;
228
+ color?: string | undefined;
229
+ restartOn?: string[] | undefined;
230
+ notify?: false | {
231
+ onTransitionTo?: string[] | undefined;
232
+ } | undefined;
233
+ }[];
234
+ repos: {
235
+ path: string;
236
+ id: string;
237
+ label?: string | undefined;
238
+ }[];
239
+ highlights: {
240
+ pattern: string;
241
+ severity: "info" | "warn" | "error";
242
+ }[];
243
+ health: {
244
+ type: string;
245
+ id: string;
246
+ label: string;
247
+ remediation: {
248
+ label: string;
249
+ command: string;
250
+ key: string;
251
+ cwd?: string | undefined;
252
+ };
253
+ path?: string | undefined;
254
+ command?: string | undefined;
255
+ cwd?: string | undefined;
256
+ notify?: false | {
257
+ onTransitionTo?: string[] | undefined;
258
+ } | undefined;
259
+ severity?: "warn" | "error" | "ok" | undefined;
260
+ triggers?: ("startup" | "fsevent" | "lockfile" | "docker")[] | undefined;
261
+ url?: string | undefined;
262
+ expectStatus?: number | undefined;
263
+ container?: string | undefined;
264
+ port?: number | undefined;
265
+ host?: string | undefined;
266
+ args?: string[] | undefined;
267
+ }[];
268
+ help: {
269
+ sources: string[];
270
+ defaultPage?: string | undefined;
271
+ };
272
+ notifications: {
273
+ onTransitionTo: string[];
274
+ enabled: boolean;
275
+ exclude: string[];
276
+ };
277
+ mounts: {
278
+ hostPath: string;
279
+ containerPath: string;
280
+ }[];
281
+ profile: Record<string, unknown>;
282
+ docker?: {
283
+ services: {
284
+ name: string;
285
+ tail: boolean;
286
+ }[];
287
+ composeFile?: string | undefined;
288
+ } | undefined;
289
+ }, {
290
+ version: number;
291
+ appName: string;
292
+ docker?: {
293
+ composeFile?: string | undefined;
294
+ services?: {
295
+ name: string;
296
+ tail?: boolean | undefined;
297
+ }[] | undefined;
298
+ } | undefined;
299
+ watchers?: {
300
+ id: string;
301
+ command: string;
302
+ label?: string | undefined;
303
+ cwd?: string | undefined;
304
+ env?: Record<string, string> | undefined;
305
+ color?: string | undefined;
306
+ restartOn?: string[] | undefined;
307
+ notify?: false | {
308
+ onTransitionTo?: string[] | undefined;
309
+ } | undefined;
310
+ }[] | undefined;
311
+ repos?: {
312
+ path: string;
313
+ id: string;
314
+ label?: string | undefined;
315
+ }[] | undefined;
316
+ highlights?: {
317
+ pattern: string;
318
+ severity?: "info" | "warn" | "error" | undefined;
319
+ }[] | undefined;
320
+ health?: {
321
+ type: string;
322
+ id: string;
323
+ label: string;
324
+ remediation: {
325
+ label: string;
326
+ command: string;
327
+ key: string;
328
+ cwd?: string | undefined;
329
+ };
330
+ path?: string | undefined;
331
+ command?: string | undefined;
332
+ cwd?: string | undefined;
333
+ notify?: false | {
334
+ onTransitionTo?: string[] | undefined;
335
+ } | undefined;
336
+ severity?: "warn" | "error" | "ok" | undefined;
337
+ triggers?: ("startup" | "fsevent" | "lockfile" | "docker")[] | undefined;
338
+ url?: string | undefined;
339
+ expectStatus?: number | undefined;
340
+ container?: string | undefined;
341
+ port?: number | undefined;
342
+ host?: string | undefined;
343
+ args?: string[] | undefined;
344
+ }[] | undefined;
345
+ help?: {
346
+ sources?: string[] | undefined;
347
+ defaultPage?: string | undefined;
348
+ } | undefined;
349
+ notifications?: {
350
+ onTransitionTo?: string[] | undefined;
351
+ enabled?: boolean | undefined;
352
+ exclude?: string[] | undefined;
353
+ } | undefined;
354
+ mounts?: {
355
+ hostPath: string;
356
+ containerPath: string;
357
+ }[] | undefined;
358
+ profile?: Record<string, unknown> | undefined;
359
+ }>;
360
+ export type BaseCockpitConfig = z.infer<typeof BaseCockpitConfigSchema>;
361
+ export declare class ConfigVersionError extends Error {
362
+ readonly filePath: string;
363
+ readonly found: unknown;
364
+ readonly supported: number;
365
+ constructor(filePath: string, found: unknown, supported: number);
366
+ }
367
+ export declare class ConfigValidationError extends Error {
368
+ readonly filePath: string;
369
+ readonly cause: unknown;
370
+ constructor(filePath: string, cause: unknown);
371
+ }
372
+ export interface LoadConfigOptions {
373
+ /**
374
+ * Optional zod schema for the profile namespace. If supplied, the loader
375
+ * validates `profile.<profileKey>` against it and merges the typed result
376
+ * back into the returned config.
377
+ */
378
+ configSchemaExt?: z.ZodObject<z.ZodRawShape>;
379
+ /**
380
+ * Profile namespace key under `profile`. Required when `configSchemaExt`
381
+ * is supplied. Example: `profileKey: 'myapp'` validates `profile.myapp`.
382
+ */
383
+ profileKey?: string;
384
+ }
385
+ /**
386
+ * Loads, parses, and validates a `cockpit.yaml` (or any path the caller chooses).
387
+ * Throws `ConfigVersionError` if the file's `version` does not match `CONFIG_VERSION`.
388
+ * Throws `ConfigValidationError` if the schema fails.
389
+ */
390
+ export declare function loadConfig(filePath: string, opts?: LoadConfigOptions): BaseCockpitConfig;
391
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mFAAmF;AACnF,eAAO,MAAM,cAAc,IAAI,CAAC;AAyFhC,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAelC;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;aACd,SAAS,EAAE,MAAM;gBAFjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM;CAOpC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;gBADd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO;CAKjC;AAID,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,iBAAsB,GAC3B,iBAAiB,CA6BnB"}
@@ -0,0 +1,152 @@
1
+ import fs from 'node:fs';
2
+ import { parse as parseYaml } from 'yaml';
3
+ import { z } from 'zod';
4
+ /** Schema version constant. Bumps reserved for breaking changes (see ADR 0004). */
5
+ export const CONFIG_VERSION = 1;
6
+ // ─── Sub-schemas ────────────────────────────────────────────────────────────
7
+ const NotifyOverrideSchema = z.union([
8
+ z.literal(false),
9
+ z.object({
10
+ onTransitionTo: z.array(z.string()).optional(),
11
+ }),
12
+ ]);
13
+ const WatcherSchema = z.object({
14
+ id: z.string(),
15
+ label: z.string().optional(),
16
+ command: z.string(),
17
+ cwd: z.string().optional(),
18
+ env: z.record(z.string()).optional(),
19
+ color: z.string().optional(),
20
+ restartOn: z.array(z.string()).optional(),
21
+ notify: NotifyOverrideSchema.optional(),
22
+ });
23
+ const RepoSchema = z.object({
24
+ id: z.string(),
25
+ path: z.string(),
26
+ label: z.string().optional(),
27
+ });
28
+ const ServiceSchema = z.object({
29
+ name: z.string(),
30
+ tail: z.boolean().optional().default(true),
31
+ });
32
+ const DockerSchema = z.object({
33
+ composeFile: z.string().optional(),
34
+ services: z.array(ServiceSchema).optional().default([]),
35
+ });
36
+ const HighlightSchema = z.object({
37
+ pattern: z.string(),
38
+ severity: z.enum(['info', 'warn', 'error']).optional().default('info'),
39
+ });
40
+ const RemediationSchema = z.object({
41
+ key: z.string(),
42
+ label: z.string(),
43
+ command: z.string(),
44
+ cwd: z.string().optional(),
45
+ });
46
+ const TriggerKindSchema = z.enum(['startup', 'fsevent', 'lockfile', 'docker']);
47
+ const HealthCheckSchema = z.object({
48
+ id: z.string(),
49
+ label: z.string(),
50
+ type: z.string(),
51
+ severity: z.enum(['ok', 'warn', 'error']).optional(),
52
+ triggers: z.array(TriggerKindSchema).optional(),
53
+ url: z.string().optional(),
54
+ expectStatus: z.number().int().optional(),
55
+ container: z.string().optional(),
56
+ port: z.number().int().optional(),
57
+ host: z.string().optional(),
58
+ path: z.string().optional(),
59
+ command: z.string().optional(),
60
+ args: z.array(z.string()).optional(),
61
+ cwd: z.string().optional(),
62
+ notify: NotifyOverrideSchema.optional(),
63
+ remediation: RemediationSchema,
64
+ });
65
+ const HelpSchema = z.object({
66
+ sources: z.array(z.string()).optional().default([]),
67
+ defaultPage: z.string().optional(),
68
+ });
69
+ const NotificationsSchema = z.object({
70
+ enabled: z.boolean().optional().default(true),
71
+ onTransitionTo: z.array(z.string()).optional().default([]),
72
+ exclude: z.array(z.string()).optional().default([]),
73
+ });
74
+ const MountSchema = z.object({
75
+ hostPath: z.string(),
76
+ containerPath: z.string(),
77
+ });
78
+ // ─── Base schema ────────────────────────────────────────────────────────────
79
+ export const BaseCockpitConfigSchema = z.object({
80
+ version: z.number().int(),
81
+ appName: z.string(),
82
+ watchers: z.array(WatcherSchema).optional().default([]),
83
+ repos: z.array(RepoSchema).optional().default([]),
84
+ docker: DockerSchema.optional(),
85
+ highlights: z.array(HighlightSchema).optional().default([]),
86
+ health: z.array(HealthCheckSchema).optional().default([]),
87
+ help: HelpSchema.optional().default({ sources: [] }),
88
+ notifications: NotificationsSchema.optional().default({
89
+ enabled: true,
90
+ onTransitionTo: [],
91
+ exclude: [],
92
+ }),
93
+ mounts: z.array(MountSchema).optional().default([]),
94
+ /**
95
+ * Profile-specific config namespace. Each profile owns one key under here
96
+ * (e.g. `profile.myapp = { ... }`) and validates it with its own zod schema
97
+ * passed to the loader as `configSchemaExt`.
98
+ */
99
+ profile: z.record(z.unknown()).optional().default({}),
100
+ });
101
+ // ─── Errors ─────────────────────────────────────────────────────────────────
102
+ export class ConfigVersionError extends Error {
103
+ filePath;
104
+ found;
105
+ supported;
106
+ constructor(filePath, found, supported) {
107
+ super(`cockpit config at "${filePath}" declares version ${String(found)}, but this build supports version ${supported}`);
108
+ this.filePath = filePath;
109
+ this.found = found;
110
+ this.supported = supported;
111
+ this.name = 'ConfigVersionError';
112
+ }
113
+ }
114
+ export class ConfigValidationError extends Error {
115
+ filePath;
116
+ cause;
117
+ constructor(filePath, cause) {
118
+ super(`invalid cockpit config at "${filePath}": ${String(cause)}`);
119
+ this.filePath = filePath;
120
+ this.cause = cause;
121
+ this.name = 'ConfigValidationError';
122
+ }
123
+ }
124
+ /**
125
+ * Loads, parses, and validates a `cockpit.yaml` (or any path the caller chooses).
126
+ * Throws `ConfigVersionError` if the file's `version` does not match `CONFIG_VERSION`.
127
+ * Throws `ConfigValidationError` if the schema fails.
128
+ */
129
+ export function loadConfig(filePath, opts = {}) {
130
+ if (!fs.existsSync(filePath)) {
131
+ throw new ConfigValidationError(filePath, 'file does not exist');
132
+ }
133
+ const content = fs.readFileSync(filePath, 'utf8');
134
+ const raw = (parseYaml(content) ?? {});
135
+ if (typeof raw['version'] !== 'number' || raw['version'] !== CONFIG_VERSION) {
136
+ throw new ConfigVersionError(filePath, raw['version'], CONFIG_VERSION);
137
+ }
138
+ const baseResult = BaseCockpitConfigSchema.safeParse(raw);
139
+ if (!baseResult.success) {
140
+ throw new ConfigValidationError(filePath, baseResult.error);
141
+ }
142
+ const config = baseResult.data;
143
+ if (opts.configSchemaExt && opts.profileKey) {
144
+ const profileBlock = config.profile?.[opts.profileKey] ?? {};
145
+ const profileResult = opts.configSchemaExt.safeParse(profileBlock);
146
+ if (!profileResult.success) {
147
+ throw new ConfigValidationError(filePath, profileResult.error);
148
+ }
149
+ config.profile[opts.profileKey] = profileResult.data;
150
+ }
151
+ return config;
152
+ }
@@ -0,0 +1,6 @@
1
+ import pino from 'pino';
2
+ export type Logger = pino.Logger;
3
+ export declare function createLogger(logFile: string): Logger;
4
+ export declare function initLogger(logFile: string): Logger;
5
+ export declare function getLogger(): Logger;
6
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAexB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAEjC,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgBpD;AAID,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAKlC"}
@@ -0,0 +1,38 @@
1
+ import fs from 'node:fs';
2
+ import pino from 'pino';
3
+ const LOG_SIZE_CAP = 10 * 1024 * 1024;
4
+ function rotateIfNeeded(logFile) {
5
+ try {
6
+ const stat = fs.statSync(logFile);
7
+ if (stat.size > LOG_SIZE_CAP) {
8
+ fs.renameSync(logFile, `${logFile}.1`);
9
+ }
10
+ }
11
+ catch {
12
+ // File doesn't exist yet — no rotation needed.
13
+ }
14
+ }
15
+ export function createLogger(logFile) {
16
+ rotateIfNeeded(logFile);
17
+ const level = process.env['LOG_LEVEL'] ?? 'info';
18
+ return pino({ level }, pino.transport({
19
+ targets: [
20
+ {
21
+ target: 'pino/file',
22
+ level,
23
+ options: { destination: logFile, mkdir: true },
24
+ },
25
+ ],
26
+ }));
27
+ }
28
+ let _logger = null;
29
+ export function initLogger(logFile) {
30
+ _logger = createLogger(logFile);
31
+ return _logger;
32
+ }
33
+ export function getLogger() {
34
+ if (!_logger) {
35
+ throw new Error('logger not initialized — call initLogger(logFile) first');
36
+ }
37
+ return _logger;
38
+ }
@@ -0,0 +1,23 @@
1
+ import type { HealthStatus, NotifiableEvent, Transition } from './types.js';
2
+ /** Notifications policy. Generic shape consumed by the notifier. */
3
+ export interface NotificationsConfig {
4
+ /** Global enable flag. */
5
+ enabled: boolean;
6
+ /** Event kinds to suppress (substring matches against `Transition.event`). */
7
+ exclude: NotifiableEvent[];
8
+ }
9
+ export interface NotifyOptions {
10
+ config: NotificationsConfig;
11
+ /** Session toggle (e.g. 'n' keystroke). When false, all notifications are silenced. */
12
+ sessionEnabled: boolean;
13
+ /** Prefix for notification titles. Default: 'cockpit'. */
14
+ appName?: string;
15
+ /** Injectable OS notifier. Defaults to a detached osascript / notify-send
16
+ * spawn. Tests pass a no-op. */
17
+ sender?: (title: string, message: string) => void;
18
+ }
19
+ export declare function detectTransitions(prev: HealthStatus[], next: HealthStatus[]): Transition[];
20
+ export declare function notify(transition: Transition, opts: NotifyOptions): void;
21
+ export declare function notifyTransitions(prev: HealthStatus[], next: HealthStatus[], opts: NotifyOptions): void;
22
+ export declare function emitEvent(event: NotifiableEvent, label: string, detail: string, opts: NotifyOptions): void;
23
+ //# sourceMappingURL=notifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/core/notifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5E,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC,0BAA0B;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,uFAAuF;IACvF,cAAc,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;qCACiC;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CA4C1F;AAED,wBAAgB,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAgBxE;AAwCD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAAE,EACpB,IAAI,EAAE,YAAY,EAAE,EACpB,IAAI,EAAE,aAAa,GAClB,IAAI,CAKN;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,GAClB,IAAI,CAEN"}