dev-cockpit 0.5.0 → 0.6.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.
- package/dist/commands/mount.d.ts +20 -1
- package/dist/commands/mount.d.ts.map +1 -1
- package/dist/health/predicates/composer-drift.d.ts.map +1 -1
- package/dist/health/remediations.d.ts +11 -0
- package/dist/health/remediations.d.ts.map +1 -1
- package/dist/index.js +44 -11
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/commands/mount.d.ts
CHANGED
|
@@ -25,6 +25,25 @@ export interface MountCommandOptions {
|
|
|
25
25
|
quiet?: boolean;
|
|
26
26
|
}
|
|
27
27
|
export declare function mergeMounts(configMounts: readonly Mount[], providerMounts: readonly Mount[]): Mount[];
|
|
28
|
+
/**
|
|
29
|
+
* Seed the candidate list from the currently-applied manifest.
|
|
30
|
+
*
|
|
31
|
+
* Two jobs:
|
|
32
|
+
* 1. Manifest entries with no discovered/config counterpart (ad-hoc custom
|
|
33
|
+
* mounts added via the picker's add-custom loop) are appended as
|
|
34
|
+
* candidates — otherwise they'd be invisible on the next `mount` run and
|
|
35
|
+
* silently dropped by any re-apply, with no way to toggle just one off.
|
|
36
|
+
* 2. Returns the applied-key set so the picker can pre-check exactly the
|
|
37
|
+
* mounts that are currently applied (instead of pre-checking everything,
|
|
38
|
+
* where an absent-minded ⏎ would apply mounts the user never had).
|
|
39
|
+
*
|
|
40
|
+
* `appliedKeys` is null when no manifest exists — first-run pickers keep the
|
|
41
|
+
* legacy default (everything matched pre-checked).
|
|
42
|
+
*/
|
|
43
|
+
export declare function seedCandidatesFromManifest(merged: readonly Mount[], manifestMounts: readonly Mount[] | null): {
|
|
44
|
+
candidates: Mount[];
|
|
45
|
+
appliedKeys: ReadonlySet<string> | null;
|
|
46
|
+
};
|
|
28
47
|
/**
|
|
29
48
|
* Interactive picker. Lazy-imports @inquirer/prompts to keep the `dev`
|
|
30
49
|
* command's startup time clean. Three phases:
|
|
@@ -39,7 +58,7 @@ export declare function mergeMounts(configMounts: readonly Mount[], providerMoun
|
|
|
39
58
|
* Returns the final mount set in source-of-truth order. The caller writes
|
|
40
59
|
* the overlay / manifest from this list.
|
|
41
60
|
*/
|
|
42
|
-
export declare function pickMounts(candidates: readonly Mount[]): Promise<Mount[]>;
|
|
61
|
+
export declare function pickMounts(candidates: readonly Mount[], appliedKeys?: ReadonlySet<string> | null): Promise<Mount[]>;
|
|
43
62
|
export declare function mountCommand(opts?: MountCommandOptions): Promise<void>;
|
|
44
63
|
export declare function mountStatusCommand(opts?: MountCommandOptions): Promise<void>;
|
|
45
64
|
export declare function mountClearCommand(opts?: MountCommandOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/commands/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAoBvD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAWD,wBAAgB,WAAW,CACzB,YAAY,EAAE,SAAS,KAAK,EAAE,EAC9B,cAAc,EAAE,SAAS,KAAK,EAAE,GAC/B,KAAK,EAAE,CAKT;AAsHD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/commands/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAoBvD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAWD,wBAAgB,WAAW,CACzB,YAAY,EAAE,SAAS,KAAK,EAAE,EAC9B,cAAc,EAAE,SAAS,KAAK,EAAE,GAC/B,KAAK,EAAE,CAKT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,cAAc,EAAE,SAAS,KAAK,EAAE,GAAG,IAAI,GACtC;IAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;CAAE,CAUlE;AAsHD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,SAAS,KAAK,EAAE,EAC5B,WAAW,GAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAW,GAC7C,OAAO,CAAC,KAAK,EAAE,CAAC,CA6KlB;AAED,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGhF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoEtF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCrF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composer-drift.d.ts","sourceRoot":"","sources":["../../../src/health/predicates/composer-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"composer-drift.d.ts","sourceRoot":"","sources":["../../../src/health/predicates/composer-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAoBD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,YAAY,CAAC,CA0CvB;AAeD,MAAM,WAAW,+BAAgC,SAAQ,yBAAyB;IAChF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C;AAED,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,+BAAoC,GACzC,WAAW,CA4Bb"}
|
|
@@ -24,4 +24,15 @@ export declare function runRemediation(key: RemediationKey, checks: HealthCheck[
|
|
|
24
24
|
*/
|
|
25
25
|
export declare function findRemediation(key: RemediationKey, checks: HealthCheck[]): HealthCheck | undefined;
|
|
26
26
|
export declare function dispatchRemediation(remediation: Remediation, ctx: HealthContext, workspaceRoot: string, sourceId: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Run a single command, streaming its stdout/stderr into the health output log
|
|
29
|
+
* under `health:<sourceId>`. Resolves with the process exit code once it exits.
|
|
30
|
+
*
|
|
31
|
+
* Shared by the `command`-shape dispatcher above and by `run`-shape
|
|
32
|
+
* remediations that need to invoke one or more commands with a proper per-call
|
|
33
|
+
* `cwd` (e.g. `composer install` in several package dirs). Keeping this the one
|
|
34
|
+
* way a remediation reaches a subprocess means commands stay plain argv — no
|
|
35
|
+
* shell string is ever parsed, so `&&` / `(cd …)` can't leak into argv.
|
|
36
|
+
*/
|
|
37
|
+
export declare function streamCommand(ctx: HealthContext, sourceId: string, program: string, args: string[], cwd: string): Promise<number>;
|
|
27
38
|
//# sourceMappingURL=remediations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remediations.d.ts","sourceRoot":"","sources":["../../src/health/remediations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,WAAW,EAAE,CASf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAevE;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,GACpB,WAAW,GAAG,SAAS,CAEzB;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"remediations.d.ts","sourceRoot":"","sources":["../../src/health/remediations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,WAAW,EAAE,CASf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAevE;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,GACpB,WAAW,GAAG,SAAS,CAEzB;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
package/dist/index.js
CHANGED
|
@@ -88257,6 +88257,9 @@ async function dispatchRemediation(remediation, ctx, workspaceRoot, sourceId) {
|
|
|
88257
88257
|
if (!program2) return;
|
|
88258
88258
|
const args = parts.slice(1);
|
|
88259
88259
|
const cwd = remediation.cwd ?? workspaceRoot;
|
|
88260
|
+
await streamCommand(ctx, sourceId, program2, args, cwd);
|
|
88261
|
+
}
|
|
88262
|
+
async function streamCommand(ctx, sourceId, program2, args, cwd) {
|
|
88260
88263
|
const handle = spawnStream(program2, args, {
|
|
88261
88264
|
cwd,
|
|
88262
88265
|
onStdout: (line2) => ctx.appendOutput?.({
|
|
@@ -88272,7 +88275,7 @@ async function dispatchRemediation(remediation, ctx, workspaceRoot, sourceId) {
|
|
|
88272
88275
|
text: line2
|
|
88273
88276
|
})
|
|
88274
88277
|
});
|
|
88275
|
-
|
|
88278
|
+
return handle.exitCode;
|
|
88276
88279
|
}
|
|
88277
88280
|
|
|
88278
88281
|
// src/health/notify-resolver.ts
|
|
@@ -91186,17 +91189,29 @@ function status3(severity, detail) {
|
|
|
91186
91189
|
}
|
|
91187
91190
|
function createComposerDriftCheck(opts = {}) {
|
|
91188
91191
|
const dirs = opts.packageDirs ?? ["."];
|
|
91189
|
-
const
|
|
91192
|
+
const id = opts.id ?? "composer-drift";
|
|
91190
91193
|
return {
|
|
91191
|
-
id
|
|
91194
|
+
id,
|
|
91192
91195
|
label: opts.label ?? "Composer",
|
|
91193
91196
|
severity: opts.severity ?? "error",
|
|
91194
91197
|
triggers: opts.triggers ?? ["startup", "lockfile"],
|
|
91195
91198
|
predicate: (ctx) => checkComposerDrift(ctx, opts),
|
|
91199
|
+
// Run `composer install` once per package dir, each in its own cwd. A
|
|
91200
|
+
// declarative `command` string can't express this without shell syntax
|
|
91201
|
+
// (`&&`, `(cd …)`), and the dispatcher runs commands as plain argv — so
|
|
91202
|
+
// that syntax would reach composer as bogus package arguments. The `run`
|
|
91203
|
+
// shape keeps each invocation a clean argv in the right directory and
|
|
91204
|
+
// short-circuits on the first failure, mirroring `&&`.
|
|
91196
91205
|
remediation: opts.remediation ?? {
|
|
91197
91206
|
key: "R",
|
|
91198
91207
|
label: "Run composer install",
|
|
91199
|
-
|
|
91208
|
+
run: async (ctx, workspaceRoot) => {
|
|
91209
|
+
for (const d of dirs) {
|
|
91210
|
+
const cwd = d === "" || d === "." ? workspaceRoot : path15.join(workspaceRoot, d);
|
|
91211
|
+
const code = await streamCommand(ctx, id, "composer", ["install"], cwd);
|
|
91212
|
+
if (code !== 0) break;
|
|
91213
|
+
}
|
|
91214
|
+
}
|
|
91200
91215
|
}
|
|
91201
91216
|
};
|
|
91202
91217
|
}
|
|
@@ -93157,6 +93172,17 @@ function mergeMounts(configMounts, providerMounts) {
|
|
|
93157
93172
|
for (const m of configMounts) seen.set(mountKey(m), m);
|
|
93158
93173
|
return Array.from(seen.values());
|
|
93159
93174
|
}
|
|
93175
|
+
function seedCandidatesFromManifest(merged, manifestMounts) {
|
|
93176
|
+
if (manifestMounts === null) {
|
|
93177
|
+
return { candidates: [...merged], appliedKeys: null };
|
|
93178
|
+
}
|
|
93179
|
+
const mergedKeys = new Set(merged.map(mountKey));
|
|
93180
|
+
const extras = manifestMounts.filter((m) => !mergedKeys.has(mountKey(m)));
|
|
93181
|
+
return {
|
|
93182
|
+
candidates: [...merged, ...extras],
|
|
93183
|
+
appliedKeys: new Set(manifestMounts.map(mountKey))
|
|
93184
|
+
};
|
|
93185
|
+
}
|
|
93160
93186
|
async function resolveContext(opts) {
|
|
93161
93187
|
const profile = opts.profile;
|
|
93162
93188
|
let configPath;
|
|
@@ -93243,18 +93269,19 @@ async function pickSourceForMount(m, prompts) {
|
|
|
93243
93269
|
validate: (v) => v.trim().length > 0 && path24.isAbsolute(v.trim()) ? true : "must be an absolute path"
|
|
93244
93270
|
})).trim();
|
|
93245
93271
|
}
|
|
93246
|
-
async function pickMounts(candidates) {
|
|
93272
|
+
async function pickMounts(candidates, appliedKeys = null) {
|
|
93247
93273
|
const { checkbox, confirm, input, select } = await import("@inquirer/prompts");
|
|
93248
93274
|
const prompts = { select, input };
|
|
93249
93275
|
let selected = [];
|
|
93250
93276
|
if (candidates.length > 0) {
|
|
93251
93277
|
const choices = candidates.map((m) => {
|
|
93252
93278
|
const unmatched = isUnmatched(m);
|
|
93253
|
-
const
|
|
93279
|
+
const applied = appliedKeys?.has(mountKey(m)) ?? false;
|
|
93280
|
+
const suffix = unmatched ? " (no source found \u2014 pick one)" : ` ${m.hostPath}${applied ? " [applied]" : ""}`;
|
|
93254
93281
|
return {
|
|
93255
93282
|
name: `${mountLabel(m)}${suffix}`,
|
|
93256
93283
|
value: m,
|
|
93257
|
-
checked: !unmatched
|
|
93284
|
+
checked: !unmatched && (appliedKeys ? applied : true)
|
|
93258
93285
|
};
|
|
93259
93286
|
});
|
|
93260
93287
|
selected = await checkbox({ message: "Select mounts to apply:", choices });
|
|
@@ -93377,26 +93404,32 @@ async function mountCommand(opts = {}) {
|
|
|
93377
93404
|
profile
|
|
93378
93405
|
} = ctx;
|
|
93379
93406
|
const merged = mergeMounts(configMounts, providerMounts);
|
|
93407
|
+
let manifestMounts = null;
|
|
93408
|
+
try {
|
|
93409
|
+
manifestMounts = readMountManifest(manifestPath2)?.mounts ?? null;
|
|
93410
|
+
} catch {
|
|
93411
|
+
}
|
|
93412
|
+
const { candidates, appliedKeys } = seedCandidatesFromManifest(merged, manifestMounts);
|
|
93380
93413
|
let selected;
|
|
93381
93414
|
if (opts.quiet || configMounts.length > 0 && providerMounts.length === 0) {
|
|
93382
|
-
if (
|
|
93415
|
+
if (candidates.length === 0) {
|
|
93383
93416
|
process.stdout.write(
|
|
93384
93417
|
"dev-cockpit mount: no mount candidates from config.mounts[] or profile.mountCandidatesProvider.\n"
|
|
93385
93418
|
);
|
|
93386
93419
|
return;
|
|
93387
93420
|
}
|
|
93388
|
-
selected =
|
|
93421
|
+
selected = candidates;
|
|
93389
93422
|
if (opts.quiet) {
|
|
93390
93423
|
process.stdout.write(`dev-cockpit mount: applying all ${selected.length} candidate(s).
|
|
93391
93424
|
`);
|
|
93392
93425
|
}
|
|
93393
93426
|
} else {
|
|
93394
|
-
if (
|
|
93427
|
+
if (candidates.length === 0) {
|
|
93395
93428
|
process.stdout.write(
|
|
93396
93429
|
"dev-cockpit mount: no mount candidates discovered. You can add custom mounts interactively below, or Ctrl-C to bail.\n"
|
|
93397
93430
|
);
|
|
93398
93431
|
}
|
|
93399
|
-
selected = await pickMounts(
|
|
93432
|
+
selected = await pickMounts(candidates, appliedKeys);
|
|
93400
93433
|
if (selected.length === 0) {
|
|
93401
93434
|
process.stdout.write("dev-cockpit mount: nothing selected; nothing to apply.\n");
|
|
93402
93435
|
return;
|