@on-par/factory-cli 0.9.7-next.3 → 0.9.7-next.31
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/cli/doctor-config.d.ts +14 -0
- package/dist/cli/doctor-config.d.ts.map +1 -0
- package/dist/cli/doctor-config.js +126 -0
- package/dist/cli/doctor-config.js.map +1 -0
- package/dist/cli/doctor-harness-view.d.ts +18 -0
- package/dist/cli/doctor-harness-view.d.ts.map +1 -0
- package/dist/cli/doctor-harness-view.js +21 -0
- package/dist/cli/doctor-harness-view.js.map +1 -0
- package/dist/cli/doctor-health.d.ts +73 -0
- package/dist/cli/doctor-health.d.ts.map +1 -0
- package/dist/cli/doctor-health.js +156 -0
- package/dist/cli/doctor-health.js.map +1 -0
- package/dist/cli/doctor-queue-reconcile.d.ts +7 -0
- package/dist/cli/doctor-queue-reconcile.d.ts.map +1 -0
- package/dist/cli/doctor-queue-reconcile.js +55 -0
- package/dist/cli/doctor-queue-reconcile.js.map +1 -0
- package/dist/cli/doctor.d.ts +26 -81
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +201 -267
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +22 -73
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +91 -828
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run-lane.d.ts +52 -0
- package/dist/cli/run-lane.d.ts.map +1 -0
- package/dist/cli/run-lane.js +240 -0
- package/dist/cli/run-lane.js.map +1 -0
- package/dist/cli/run.d.ts +52 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +200 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/ship.d.ts.map +1 -1
- package/dist/cli/ship.js.map +1 -1
- package/dist/cli/status.d.ts +23 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +179 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/unpark.d.ts +5 -27
- package/dist/cli/unpark.d.ts.map +1 -1
- package/dist/cli/unpark.js +5 -66
- package/dist/cli/unpark.js.map +1 -1
- package/dist/cli/update-state.d.ts.map +1 -1
- package/dist/cli/update-state.js +2 -4
- package/dist/cli/update-state.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DeclaredHarnessProbe } from '@on-par/factory-core';
|
|
2
|
+
import type { ConfigLintInput } from '@on-par/factory-core/internal';
|
|
3
|
+
import { type DoctorCheck } from './doctor.js';
|
|
4
|
+
/** One doctor check per user-declared harness, from its `probe` result. */
|
|
5
|
+
export declare function declaredHarnessChecks(probes: DeclaredHarnessProbe[]): DoctorCheck[];
|
|
6
|
+
/** One failed check per models.registry entry whose harness is missing or unknown;
|
|
7
|
+
* a single ok row when every entry is valid; nothing when there is no registry. */
|
|
8
|
+
export declare function modelsRegistryChecks(configPath: string, registry: Readonly<Record<string, {
|
|
9
|
+
harness?: string;
|
|
10
|
+
}>> | undefined, validHarnesses: readonly string[]): DoctorCheck[];
|
|
11
|
+
/** `config` rows from the shared pre-PLAN lint (#2612): one failing row per finding, so doctor fails exactly when
|
|
12
|
+
* the run preflight would escalate or park. A single ok row when clean. Read-only. */
|
|
13
|
+
export declare function configLintChecks(input: ConfigLintInput, loadError?: string): DoctorCheck[];
|
|
14
|
+
//# sourceMappingURL=doctor-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-config.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAQrE,OAAO,EAAE,KAAK,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7D,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,WAAW,EAAE,CAoBnF;AAID;oFACoF;AACpF,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,GAAG,SAAS,EACpE,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,WAAW,EAAE,CA0Bf;AAED;uFACuF;AACvF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CA4D1F"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// packages/cli/src/cli/doctor-config.ts — config and registry rows, moved out of doctor.ts (#2799)
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { findConfigSchemaErrors, isTemplateToken, lintFactoryConfig, listBuiltInCheckers, } from '@on-par/factory-core/internal';
|
|
4
|
+
import { REPO_SECTION } from './doctor.js';
|
|
5
|
+
/** One doctor check per user-declared harness, from its `probe` result. */
|
|
6
|
+
export function declaredHarnessChecks(probes) {
|
|
7
|
+
return probes.map((p) => {
|
|
8
|
+
const name = `harness ${p.harness}`;
|
|
9
|
+
if (p.status === 'available')
|
|
10
|
+
return { name, ok: true, detail: `available (probe: ${p.probe})` };
|
|
11
|
+
if (p.status === 'unavailable') {
|
|
12
|
+
return {
|
|
13
|
+
name,
|
|
14
|
+
ok: false,
|
|
15
|
+
detail: `unavailable: probe \`${p.probe}\` failed: ${p.detail}`,
|
|
16
|
+
fix: 'install the agent CLI on PATH or fix the "probe" command in the models config harnesses section',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
name,
|
|
21
|
+
ok: false,
|
|
22
|
+
optional: true,
|
|
23
|
+
detail: 'unverified: no probe configured',
|
|
24
|
+
fix: 'add a "probe" command (exit 0 = reachable) to the harness in the models config',
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const REGISTRY_CHECK = 'models.registry';
|
|
29
|
+
/** One failed check per models.registry entry whose harness is missing or unknown;
|
|
30
|
+
* a single ok row when every entry is valid; nothing when there is no registry. */
|
|
31
|
+
export function modelsRegistryChecks(configPath, registry, validHarnesses) {
|
|
32
|
+
const entries = Object.entries(registry ?? {});
|
|
33
|
+
if (entries.length === 0)
|
|
34
|
+
return [];
|
|
35
|
+
const failed = [];
|
|
36
|
+
for (const [id, def] of entries) {
|
|
37
|
+
const field = `models.registry.${id}.harness`;
|
|
38
|
+
const name = `${REGISTRY_CHECK} ${id}`;
|
|
39
|
+
if (def.harness === undefined || def.harness.trim() === '') {
|
|
40
|
+
failed.push({
|
|
41
|
+
name,
|
|
42
|
+
ok: false,
|
|
43
|
+
detail: `${configPath}: ${field} is missing`,
|
|
44
|
+
fix: `set "harness" to one of: ${validHarnesses.join(', ')}`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (!validHarnesses.includes(def.harness)) {
|
|
48
|
+
failed.push({
|
|
49
|
+
name,
|
|
50
|
+
ok: false,
|
|
51
|
+
detail: `${configPath}: ${field} '${def.harness}' is not a known harness (valid harnesses: ${validHarnesses.join(', ')})`,
|
|
52
|
+
fix: 'use a built-in harness id or declare it under "harnesses" in the models config',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (failed.length > 0)
|
|
57
|
+
return failed;
|
|
58
|
+
const n = entries.length;
|
|
59
|
+
return [{ name: REGISTRY_CHECK, ok: true, detail: `${n} entr${n === 1 ? 'y' : 'ies'} valid (${configPath})` }];
|
|
60
|
+
}
|
|
61
|
+
/** `config` rows from the shared pre-PLAN lint (#2612): one failing row per finding, so doctor fails exactly when
|
|
62
|
+
* the run preflight would escalate or park. A single ok row when clean. Read-only. */
|
|
63
|
+
export function configLintChecks(input, loadError) {
|
|
64
|
+
const schemaRows = (input.configFile ? findConfigSchemaErrors(input.configFile) : []).map((f) => ({
|
|
65
|
+
name: 'config',
|
|
66
|
+
ok: false,
|
|
67
|
+
section: REPO_SECTION,
|
|
68
|
+
detail: `${f.file}${f.line ? `:${f.line}` : ''}: schema error at '${f.path}': ${f.message}`,
|
|
69
|
+
fix: f.fix,
|
|
70
|
+
}));
|
|
71
|
+
if (loadError !== undefined) {
|
|
72
|
+
return [
|
|
73
|
+
{
|
|
74
|
+
name: 'config',
|
|
75
|
+
ok: false,
|
|
76
|
+
section: REPO_SECTION,
|
|
77
|
+
detail: loadError,
|
|
78
|
+
fix: 'fix the constitution frontmatter YAML',
|
|
79
|
+
},
|
|
80
|
+
...schemaRows,
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
const { findings } = lintFactoryConfig(input);
|
|
84
|
+
if (findings.length > 0) {
|
|
85
|
+
const names = [...listBuiltInCheckers().map((c) => c.name), 'custom_*'].join(', ');
|
|
86
|
+
const lintRows = findings.map((f) => {
|
|
87
|
+
const where = `${f.file}${f.line ? `:${f.line}` : ''}`;
|
|
88
|
+
if (f.rule === 'unknown-checker') {
|
|
89
|
+
const kind = isTemplateToken(f.token) ? 'placeholder' : 'unknown';
|
|
90
|
+
return {
|
|
91
|
+
name: 'config',
|
|
92
|
+
ok: false,
|
|
93
|
+
section: REPO_SECTION,
|
|
94
|
+
detail: `${where}: ${kind} checker '${f.token}'`,
|
|
95
|
+
fix: `replace '${f.token}' with a real checker name (${names}) or delete the line`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
name: 'config',
|
|
100
|
+
ok: false,
|
|
101
|
+
section: REPO_SECTION,
|
|
102
|
+
detail: `${where}: unfilled template token '${f.token}'`,
|
|
103
|
+
fix: `replace '${f.token}' with a real value`,
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
return [...lintRows, ...schemaRows];
|
|
107
|
+
}
|
|
108
|
+
if (schemaRows.length > 0)
|
|
109
|
+
return schemaRows;
|
|
110
|
+
const scanned = [];
|
|
111
|
+
if (input.constitution?.repoInstance)
|
|
112
|
+
scanned.push(input.constitution.repoInstance.relPath);
|
|
113
|
+
if (input.configFile && existsSync(input.configFile.absPath))
|
|
114
|
+
scanned.push(input.configFile.relPath);
|
|
115
|
+
return [
|
|
116
|
+
{
|
|
117
|
+
name: 'config',
|
|
118
|
+
ok: true,
|
|
119
|
+
section: REPO_SECTION,
|
|
120
|
+
detail: scanned.length > 0
|
|
121
|
+
? `no unfilled placeholders, unknown checkers or schema errors in ${scanned.join(', ')}`
|
|
122
|
+
: 'no constitution or config file to scan',
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=doctor-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-config.js","sourceRoot":"","sources":["../../src/cli/doctor-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DoctorRuntime } from './doctor.js';
|
|
2
|
+
/** The harness view doctor judges with: packaged harnesses merged with `.factory/config.yaml` (#2870). */
|
|
3
|
+
export interface DoctorHarnessView {
|
|
4
|
+
/** `applyRepoConfig(...).harnesses`; undefined when loading or merging threw. */
|
|
5
|
+
merged?: Readonly<Record<string, {
|
|
6
|
+
command: string;
|
|
7
|
+
agentic: boolean;
|
|
8
|
+
}>>;
|
|
9
|
+
registry?: Readonly<Record<string, {
|
|
10
|
+
harness?: string;
|
|
11
|
+
}>>;
|
|
12
|
+
/** Packaged plus repo-declared harness ids, even when the merge threw. */
|
|
13
|
+
declaredIds: string[];
|
|
14
|
+
/** The applyRepoConfig error; undefined when it succeeded or when loading the repo config threw (the config row reports that). */
|
|
15
|
+
mergeError?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveDoctorHarnesses(loaders: Pick<DoctorRuntime['configLoaders'], 'loadModelsConfig' | 'loadRepoConfig'>, repoRoot: string): DoctorHarnessView;
|
|
18
|
+
//# sourceMappingURL=doctor-harness-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-harness-view.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-harness-view.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,0GAA0G;AAC1G,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IACzE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC1D,0EAA0E;IAC1E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kIAAkI;IAClI,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,EAAE,kBAAkB,GAAG,gBAAgB,CAAC,EACpF,QAAQ,EAAE,MAAM,GACf,iBAAiB,CAgBnB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { applyRepoConfig } from '@on-par/factory-core';
|
|
2
|
+
export function resolveDoctorHarnesses(loaders, repoRoot) {
|
|
3
|
+
let models;
|
|
4
|
+
let repo;
|
|
5
|
+
try {
|
|
6
|
+
models = loaders.loadModelsConfig();
|
|
7
|
+
repo = loaders.loadRepoConfig(repoRoot);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return { declaredIds: [] };
|
|
11
|
+
}
|
|
12
|
+
const registry = repo?.models?.registry;
|
|
13
|
+
const declaredIds = [...new Set([...Object.keys(models.harnesses ?? {}), ...Object.keys(repo?.harnesses ?? {})])];
|
|
14
|
+
try {
|
|
15
|
+
return { merged: applyRepoConfig(models, repo).harnesses, registry, declaredIds };
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
return { registry, declaredIds, mergeError: err instanceof Error ? err.message : String(err) };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=doctor-harness-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-harness-view.js","sourceRoot":"","sources":["../../src/cli/doctor-harness-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAevD,MAAM,UAAU,sBAAsB,CACpC,OAAoF,EACpF,QAAgB;IAEhB,IAAI,MAAmD,CAAC;IACxD,IAAI,IAA+C,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;QACpC,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC7B,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC;IACxC,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAClH,IAAI,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACpF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACjG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { DoctorCheck } from './doctor.js';
|
|
2
|
+
export interface LeaseHealthRow {
|
|
3
|
+
worktreeId: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
port: number;
|
|
6
|
+
pid: number;
|
|
7
|
+
alive: boolean;
|
|
8
|
+
reason?: 'dead-pid' | 'missing-worktree';
|
|
9
|
+
portSquatted?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function leaseChecks(rows: LeaseHealthRow[]): DoctorCheck[];
|
|
12
|
+
export interface EventLogIntegrity {
|
|
13
|
+
total: number;
|
|
14
|
+
unparseable: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function analyzeEventLog(content: string): EventLogIntegrity;
|
|
17
|
+
export declare function eventLogCheck(integrity: EventLogIntegrity | null): DoctorCheck;
|
|
18
|
+
export interface ReapRow {
|
|
19
|
+
name: string;
|
|
20
|
+
removed: boolean;
|
|
21
|
+
detail: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function orphanContainerChecks(names: readonly string[]): DoctorCheck[];
|
|
24
|
+
export declare function orphanMicroVmChecks(names: readonly string[]): DoctorCheck[];
|
|
25
|
+
export declare function formatContainerReconcileReport(reaped: ReapRow[]): string;
|
|
26
|
+
export declare function formatMicroVmReconcileReport(reaped: ReapRow[]): string;
|
|
27
|
+
export declare function formatReconcileReport(reaped: Array<{
|
|
28
|
+
lease: {
|
|
29
|
+
worktreeId: string;
|
|
30
|
+
port: number;
|
|
31
|
+
};
|
|
32
|
+
reason: string;
|
|
33
|
+
}>): string;
|
|
34
|
+
/** One worktree the reconcile pass removed. Structurally the subset of core's `GcCandidate`
|
|
35
|
+
* that the report renders — kept local so `doctor.ts` stays dependency-free and unit-testable. */
|
|
36
|
+
export interface ReconciledWorktree {
|
|
37
|
+
path: string;
|
|
38
|
+
branch: string | null;
|
|
39
|
+
reason: string;
|
|
40
|
+
branchDeleted: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function formatWorktreeReconcileReport(removed: ReconciledWorktree[]): string;
|
|
43
|
+
/** One claim the reconcile pass put back in the queue. Structurally the subset of core's
|
|
44
|
+
* `StaleClaimRelease` that the report renders — kept local so `doctor.ts` stays
|
|
45
|
+
* dependency-free and unit-testable. */
|
|
46
|
+
export interface ReleasedClaim {
|
|
47
|
+
issue: number;
|
|
48
|
+
expiresAt: number;
|
|
49
|
+
released: boolean;
|
|
50
|
+
detail?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function formatClaimReconcileReport(released: ReleasedClaim[]): string;
|
|
53
|
+
/** One green-and-ready PR nobody merged. Structurally the subset of core's `UnmergedGreenPr`
|
|
54
|
+
* the report renders — kept local so `doctor.ts` stays dependency-free and unit-testable. */
|
|
55
|
+
export interface UnmergedGreenPrRow {
|
|
56
|
+
number: number;
|
|
57
|
+
branch: string;
|
|
58
|
+
issue: number | null;
|
|
59
|
+
ageHours: number;
|
|
60
|
+
}
|
|
61
|
+
/** Outcome of the green-PR scan: it ran, it was skipped (no repo/token), or it failed. */
|
|
62
|
+
export type GreenPrScanResult = {
|
|
63
|
+
status: 'ok';
|
|
64
|
+
rows: UnmergedGreenPrRow[];
|
|
65
|
+
} | {
|
|
66
|
+
status: 'skipped';
|
|
67
|
+
detail: string;
|
|
68
|
+
} | {
|
|
69
|
+
status: 'failed';
|
|
70
|
+
detail: string;
|
|
71
|
+
};
|
|
72
|
+
export declare function unmergedGreenPrChecks(result: GreenPrScanResult): DoctorCheck[];
|
|
73
|
+
//# sourceMappingURL=doctor-health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-health.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-health.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,GAAG,kBAAkB,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,WAAW,EAAE,CAwBjE;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAWlE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,GAAG,WAAW,CAuB9E;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,CAU7E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,CAU3E;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CASxE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAStE;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7E,MAAM,CAMR;AAED;mGACmG;AACnG,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAUnF;AAED;;yCAEyC;AACzC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAU5E;AAED;8FAC8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0FAA0F;AAC1F,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,kBAAkB,EAAE,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAIzC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAyB9E"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// packages/cli/src/cli/doctor-health.ts — runtime-health rows and reconcile reports, moved out of doctor.ts (#2799)
|
|
2
|
+
export function leaseChecks(rows) {
|
|
3
|
+
if (rows.length === 0) {
|
|
4
|
+
return [{ name: 'port leases', ok: true, optional: true, detail: 'no active leases' }];
|
|
5
|
+
}
|
|
6
|
+
return rows.map((row) => {
|
|
7
|
+
if (row.alive) {
|
|
8
|
+
return {
|
|
9
|
+
name: `port lease :${row.port}`,
|
|
10
|
+
ok: true,
|
|
11
|
+
optional: true,
|
|
12
|
+
detail: `${row.worktreeId}: port ${row.port}, pid ${row.pid}, live`,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const squatted = row.portSquatted ? '; port still in use by another process' : '';
|
|
16
|
+
return {
|
|
17
|
+
name: `port lease :${row.port}`,
|
|
18
|
+
ok: false,
|
|
19
|
+
optional: true,
|
|
20
|
+
detail: `${row.worktreeId}: port ${row.port}, pid ${row.pid}, stale (${row.reason})${squatted}`,
|
|
21
|
+
fix: 'run `factory doctor --reconcile` to reclaim stale leases',
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function analyzeEventLog(content) {
|
|
26
|
+
const lines = content.split('\n').filter((l) => l.trim() !== '');
|
|
27
|
+
let unparseable = 0;
|
|
28
|
+
for (const line of lines) {
|
|
29
|
+
try {
|
|
30
|
+
JSON.parse(line);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
unparseable++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { total: lines.length, unparseable };
|
|
37
|
+
}
|
|
38
|
+
export function eventLogCheck(integrity) {
|
|
39
|
+
if (integrity === null) {
|
|
40
|
+
return { name: 'event log integrity', ok: true, optional: true, detail: 'no events.ndjson yet' };
|
|
41
|
+
}
|
|
42
|
+
if (integrity.total === 0) {
|
|
43
|
+
return { name: 'event log integrity', ok: true, optional: true, detail: 'events.ndjson is empty' };
|
|
44
|
+
}
|
|
45
|
+
const pct = ((integrity.unparseable / integrity.total) * 100).toFixed(1);
|
|
46
|
+
if (integrity.unparseable === 0) {
|
|
47
|
+
return {
|
|
48
|
+
name: 'event log integrity',
|
|
49
|
+
ok: true,
|
|
50
|
+
optional: true,
|
|
51
|
+
detail: `${integrity.total} lines, 0 unparseable (0.0%)`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
name: 'event log integrity',
|
|
56
|
+
ok: false,
|
|
57
|
+
optional: true,
|
|
58
|
+
detail: `${integrity.unparseable} of ${integrity.total} lines unparseable (${pct}%)`,
|
|
59
|
+
fix: 'historical corruption from pre-lock parallel writes; appends are now serialized; metrics over this file carry this error bar',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function orphanContainerChecks(names) {
|
|
63
|
+
if (names.length === 0) {
|
|
64
|
+
return [{ name: 'orphan containers', ok: true, detail: 'no orphan sf-job-*/factory.managed containers' }];
|
|
65
|
+
}
|
|
66
|
+
return names.map((name) => ({
|
|
67
|
+
name: `orphan container ${name}`,
|
|
68
|
+
ok: false,
|
|
69
|
+
detail: `${name} is stopped and not tied to any running job`,
|
|
70
|
+
fix: 'run `factory doctor --reconcile` to remove it and its anonymous volumes',
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
export function orphanMicroVmChecks(names) {
|
|
74
|
+
if (names.length === 0) {
|
|
75
|
+
return [{ name: 'orphan sbx VMs', ok: true, detail: 'no orphan factory-* sbx VMs' }];
|
|
76
|
+
}
|
|
77
|
+
return names.map((name) => ({
|
|
78
|
+
name: `orphan sbx VM ${name}`,
|
|
79
|
+
ok: false,
|
|
80
|
+
detail: `${name} has no active lane holding its worktree`,
|
|
81
|
+
fix: 'run `factory doctor --reconcile` to remove it via `sbx rm --force`',
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
export function formatContainerReconcileReport(reaped) {
|
|
85
|
+
if (reaped.length === 0)
|
|
86
|
+
return 'reconcile: no orphan containers';
|
|
87
|
+
return reaped
|
|
88
|
+
.map((r) => r.removed
|
|
89
|
+
? `reconcile: removed container ${r.name}`
|
|
90
|
+
: `reconcile: failed to remove container ${r.name}: ${r.detail}`)
|
|
91
|
+
.join('\n');
|
|
92
|
+
}
|
|
93
|
+
export function formatMicroVmReconcileReport(reaped) {
|
|
94
|
+
if (reaped.length === 0)
|
|
95
|
+
return 'reconcile: no orphan sbx VMs';
|
|
96
|
+
return reaped
|
|
97
|
+
.map((r) => r.removed
|
|
98
|
+
? `reconcile: removed sbx VM ${r.name} (sbx rm --force)`
|
|
99
|
+
: `reconcile: failed to remove sbx VM ${r.name}: ${r.detail}`)
|
|
100
|
+
.join('\n');
|
|
101
|
+
}
|
|
102
|
+
export function formatReconcileReport(reaped) {
|
|
103
|
+
if (reaped.length === 0)
|
|
104
|
+
return 'reconcile: no stale leases';
|
|
105
|
+
return reaped
|
|
106
|
+
.map((r) => `reconcile: freed port ${r.lease.port} (worktree ${r.lease.worktreeId}, reason ${r.reason})`)
|
|
107
|
+
.join('\n');
|
|
108
|
+
}
|
|
109
|
+
export function formatWorktreeReconcileReport(removed) {
|
|
110
|
+
if (removed.length === 0)
|
|
111
|
+
return 'reconcile: no dead-run worktrees';
|
|
112
|
+
return removed
|
|
113
|
+
.map((w) => {
|
|
114
|
+
const branchLabel = w.branch ?? 'detached';
|
|
115
|
+
const deleted = w.branchDeleted ? `, deleted branch ${w.branch}` : '';
|
|
116
|
+
return `reconcile: removed worktree ${w.path} (branch ${branchLabel}, reason ${w.reason})${deleted}`;
|
|
117
|
+
})
|
|
118
|
+
.join('\n');
|
|
119
|
+
}
|
|
120
|
+
export function formatClaimReconcileReport(released) {
|
|
121
|
+
if (released.length === 0)
|
|
122
|
+
return 'reconcile: no stale claims';
|
|
123
|
+
return released
|
|
124
|
+
.map((c) => c.released
|
|
125
|
+
? `reconcile: released issue #${c.issue} back to factory:queued (lease expired at ${c.expiresAt})`
|
|
126
|
+
: `reconcile: failed to release issue #${c.issue} (lease expired at ${c.expiresAt}): ${c.detail ?? 'unknown error'}`)
|
|
127
|
+
.join('\n');
|
|
128
|
+
}
|
|
129
|
+
const GREEN_PR_CHECK = 'green PRs awaiting merge';
|
|
130
|
+
export function unmergedGreenPrChecks(result) {
|
|
131
|
+
if (result.status === 'skipped') {
|
|
132
|
+
return [{ name: GREEN_PR_CHECK, ok: true, optional: true, detail: result.detail }];
|
|
133
|
+
}
|
|
134
|
+
if (result.status === 'failed') {
|
|
135
|
+
return [
|
|
136
|
+
{
|
|
137
|
+
name: GREEN_PR_CHECK,
|
|
138
|
+
ok: false,
|
|
139
|
+
optional: true,
|
|
140
|
+
detail: `scan failed: ${result.detail}`,
|
|
141
|
+
fix: 'check `gh auth status` and network access, then re-run `factory doctor`',
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
if (result.rows.length === 0) {
|
|
146
|
+
return [{ name: GREEN_PR_CHECK, ok: true, optional: true, detail: 'no green-and-ready PRs awaiting merge' }];
|
|
147
|
+
}
|
|
148
|
+
return result.rows.map((row) => ({
|
|
149
|
+
name: `green PR #${row.number}`,
|
|
150
|
+
ok: false,
|
|
151
|
+
optional: true,
|
|
152
|
+
detail: `${row.issue === null ? 'owning issue unknown' : `issue #${row.issue}`}: green and ready on ${row.branch}, open ${row.ageHours}h, not merged`,
|
|
153
|
+
fix: `review and merge #${row.number} (or close it); the factory never auto-merges an orphaned PR`,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=doctor-health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-health.js","sourceRoot":"","sources":["../../src/cli/doctor-health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Octokit } from '@octokit/rest';
|
|
2
|
+
import type { CliDeps } from './index.js';
|
|
3
|
+
type QueueOps = Required<Pick<CliDeps, 'releaseStaleClaims' | 'pollBlockedParks'>>;
|
|
4
|
+
/** Never throws: each step prints its own failure line. */
|
|
5
|
+
export declare function reconcileQueue(ops: QueueOps, ghRepo: string | undefined, octokit: Octokit | undefined, eventsFile: string): Promise<void>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=doctor-queue-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-queue-reconcile.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-queue-reconcile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAK7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,KAAK,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,GAAG,kBAAkB,CAAC,CAAC,CAAC;AAInF,2DAA2D;AAC3D,wBAAsB,cAAc,CAClC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// packages/cli/src/cli/doctor-queue-reconcile.ts — `doctor --reconcile` queue steps: stale claims (#999) and blocked parks (#2318)
|
|
2
|
+
import { createLogger } from '@on-par/factory-core';
|
|
3
|
+
import { createOctokitBlockedParkStore, createOctokitQueueClient } from '@on-par/factory-core/internal';
|
|
4
|
+
import { formatClaimReconcileReport } from './doctor-health.js';
|
|
5
|
+
const errMessage = (err) => err?.message ?? String(err);
|
|
6
|
+
/** Never throws: each step prints its own failure line. */
|
|
7
|
+
export async function reconcileQueue(ops, ghRepo, octokit, eventsFile) {
|
|
8
|
+
const [owner, repo] = ghRepo?.split('/') ?? [];
|
|
9
|
+
// Stale claim reap (#999): factory:in-progress claims naming a dead local pid go back to
|
|
10
|
+
// factory:queued so the next run can claim them with no manual label surgery.
|
|
11
|
+
try {
|
|
12
|
+
if (ghRepo && octokit) {
|
|
13
|
+
const released = await ops.releaseStaleClaims({ client: createOctokitQueueClient(octokit), owner, repo });
|
|
14
|
+
console.log(formatClaimReconcileReport(released));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log('reconcile: skipping stale claims: no GitHub repo or token');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.log(`reconcile: stale claim release failed: ${errMessage(err)}`);
|
|
22
|
+
}
|
|
23
|
+
// Blocked-park poll (#2318): parents parked `blocked` resume once their blockers close.
|
|
24
|
+
try {
|
|
25
|
+
if (ghRepo && octokit) {
|
|
26
|
+
const results = await ops.pollBlockedParks({
|
|
27
|
+
client: createOctokitQueueClient(octokit),
|
|
28
|
+
owner,
|
|
29
|
+
repo,
|
|
30
|
+
store: createOctokitBlockedParkStore(octokit, ghRepo),
|
|
31
|
+
logEvent: (kind, issue, msg) => {
|
|
32
|
+
const log = createLogger(eventsFile, { issue }, { out: { write: () => true } });
|
|
33
|
+
if (kind === 'warn')
|
|
34
|
+
log.warn('warn', msg);
|
|
35
|
+
else
|
|
36
|
+
log.info('issue_unparked', msg);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const count = (o) => results.filter((r) => r.outcome === o).length;
|
|
40
|
+
console.log(`reconcile: blocked parks: ${count('unparked')} unparked, ${count('held')} held, ${count('capped')} capped, ${count('waiting')} waiting`);
|
|
41
|
+
for (const r of results) {
|
|
42
|
+
if (r.outcome === 'waiting' || r.outcome === 'skipped')
|
|
43
|
+
continue;
|
|
44
|
+
console.log(`reconcile: #${r.issue} ${r.outcome}${r.detail ? ` — ${r.detail}` : ''}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log('reconcile: skipping blocked parks: no GitHub repo or token');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
console.log(`reconcile: blocked park poll failed: ${errMessage(err)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=doctor-queue-reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-queue-reconcile.js","sourceRoot":"","sources":["../../src/cli/doctor-queue-reconcile.ts"],"names":[],"mappings":"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"}
|