@on-par/factory-cli 0.9.18-next.2 → 0.9.18-next.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.
- package/dist/cli/awaiting-ci-recheck.d.ts +31 -0
- package/dist/cli/awaiting-ci-recheck.d.ts.map +1 -0
- package/dist/cli/awaiting-ci-recheck.js +61 -0
- package/dist/cli/awaiting-ci-recheck.js.map +1 -0
- package/dist/cli/awaiting-ci-wiring.d.ts +6 -0
- package/dist/cli/awaiting-ci-wiring.d.ts.map +1 -0
- package/dist/cli/awaiting-ci-wiring.js +45 -0
- package/dist/cli/awaiting-ci-wiring.js.map +1 -0
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +3 -3
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/errors.d.ts +6 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +11 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/index.d.ts +4 -14
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +50 -77
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/land-pr.d.ts +11 -0
- package/dist/cli/land-pr.d.ts.map +1 -1
- package/dist/cli/land-pr.js +27 -1
- package/dist/cli/land-pr.js.map +1 -1
- package/dist/cli/land.d.ts.map +1 -1
- package/dist/cli/land.js +3 -3
- package/dist/cli/land.js.map +1 -1
- package/dist/cli/queue-startup.d.ts +2 -0
- package/dist/cli/queue-startup.d.ts.map +1 -1
- package/dist/cli/repo-live-run-lock.d.ts +7 -0
- package/dist/cli/repo-live-run-lock.d.ts.map +1 -0
- package/dist/cli/repo-live-run-lock.js +14 -0
- package/dist/cli/repo-live-run-lock.js.map +1 -0
- package/dist/cli/repo-run-lock.d.ts +14 -0
- package/dist/cli/repo-run-lock.d.ts.map +1 -0
- package/dist/cli/repo-run-lock.js +27 -0
- package/dist/cli/repo-run-lock.js.map +1 -0
- package/dist/cli/run-lane-deps.d.ts +7 -1
- package/dist/cli/run-lane-deps.d.ts.map +1 -1
- package/dist/cli/run-lane.d.ts.map +1 -1
- package/dist/cli/run-lane.js +31 -3
- package/dist/cli/run-lane.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +4 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/self-update-apply.d.ts +1 -1
- package/dist/cli/self-update-apply.d.ts.map +1 -1
- package/dist/cli/self-update-apply.js +4 -5
- package/dist/cli/self-update-apply.js.map +1 -1
- package/package.json +4 -4
package/dist/cli/index.js
CHANGED
|
@@ -12,7 +12,10 @@ import { startupSweeps, warnQueueDiagnostics } from './queue-startup.js';
|
|
|
12
12
|
import { proposeTriageQueue } from './triage-open-prs.js';
|
|
13
13
|
import { makeQueuePreflightOps, preflightQueuedIssue, } from './queue-preflight.js';
|
|
14
14
|
import { acquirePortLease, aggregateCosts, appendKpiHistoryLine, applyRepoConfig, buildPhase, checkPhase, clearProxyState, computeHealthKpis, ConstitutionLoader, createDefaultWorkSourceRegistry, createLogger, createLaneProxy, defaultFindPortListeners, describeEffectiveConfig, detectPostMergeDefects, diagnoseModels, probeDeclaredHarnesses, estimateTrailingSpend, fetchDefectSources, fetchSubscriptionUsage, formatUsageReport, getConstitutionsDir, getFactoryPaths, GITHUB_ISSUE_SOURCE, hasUnresolvedPark, InvalidArtifactsDirError, InvalidWorkRequestInputError, InvalidWorkspaceError, isCommandAvailable, isProxyRunning, kpiBranchPrefixes, kpisToHistoryRecord, laneBaseUrl, laneEnv, laneHostLabel, loadFactoryConfigForRepo, loadModelsConfig, loadRepoConfig, loadRoutesConfig, LOCAL_BRIEF_SOURCE, joinClassifierOutcomes, mergeClassifierOutcomes, parseClassifierOutcomes, summarizeClassifierOutcomes, formatClassifierReport, mergedPrRefs, ModelRegistry, ModelRouter, parkReasonFor, parseKpiHistory, parseQueue, planPhase, readEvents, readPortLeases, readQueue, readUsage, reapOrphanProcesses, reconstructKpiEvents, recordLeasePgid, releasePortLease, renderKpiReport, renderKpiTrend, resolveDefectWindowDays, parseSizeGateMode, parseMaxSlices, SIZE_GATE_MODES, resolveEffectiveModelPins, resolveEnvironmentProxy, resolveArtifactsDir, resolveLocalOnlyPolicy, resolveMergePolicy, resolveSkipCI, resolveTimeouts, resolveUsageCap, resolveWatchdogPolicy, runAutoIngest, shipPhase, formatCostTotal, validateQueue, watchUsage, writeLocalRunReport, workKeyFromIssue, writeProxyState, } from '@on-par/factory-core';
|
|
15
|
-
import { acquirePidFile, createCheckResumeStore, DEFAULT_GARDEN_MAX_CLUSTERS, DEFAULT_GARDEN_SINCE, capGardenClusters, clusterGarden, dedupGardenClusters, filterGardenOnlyNew, filterGardenWindow, markGardenTrackingUnknown, parseGardenDuration, readHarvestEvents, renderGardenJson, renderGardenReport, laneWorktreePath, migrateRepoConfigToYaml, readRepoConfigFile, rewriteRepoConfigFile, REPO_CONFIG_YAML_HEADER, claudeConfigDirOverride, claudeKeychainService, cleanupWorktree, createDaemonLogSink, factoryBranchIssue, factoryBranchPrefixes, createFactorydServer, createRunRuntime, createShipExecutor, createGithubQueue, createLocalSmallDryRun, createOctokitFilingClient, createOctokitGreenPrClient, createOctokitQueueClient, daemonRuntimePaths, defaultRegistryPath, ensureDir, fetchHumanEventSourcesCached, FACTORY_RUNTIME_CONFIG_KEYS, findUnmergedGreenPrs, listStatelessLaneIssues, formatGcReport, gitFetch, listMicroVms, listOrphanContainers, logCost, logEvent, planQueueMigration, pollBlockedParks, readCosts, readGithubQueueSnapshot, reapCleanShipWorktree, reapLaneWorktree, reapOrphanContainers, reapOrphanMicroVm, releaseRuntimeFiles, releaseStaleClaims, resolveBranchPrefix, resolveEffectiveConfig, resolveExperimental, resolveLocalOnly, describeDraftPrPolicy, resolveDraftPrPolicy, resolvePrClassifierPolicy, resolveReviewFloorRules,
|
|
15
|
+
import { acquirePidFile, createCheckResumeStore, DEFAULT_GARDEN_MAX_CLUSTERS, DEFAULT_GARDEN_SINCE, capGardenClusters, clusterGarden, dedupGardenClusters, filterGardenOnlyNew, filterGardenWindow, markGardenTrackingUnknown, parseGardenDuration, readHarvestEvents, renderGardenJson, renderGardenReport, laneWorktreePath, migrateRepoConfigToYaml, readRepoConfigFile, rewriteRepoConfigFile, REPO_CONFIG_YAML_HEADER, claudeConfigDirOverride, claudeKeychainService, cleanupWorktree, createDaemonLogSink, factoryBranchIssue, factoryBranchPrefixes, createFactorydServer, createRunRuntime, createShipExecutor, createGithubQueue, createLocalSmallDryRun, createOctokitFilingClient, createOctokitGreenPrClient, createOctokitQueueClient, daemonRuntimePaths, defaultRegistryPath, ensureDir, fetchHumanEventSourcesCached, FACTORY_RUNTIME_CONFIG_KEYS, findUnmergedGreenPrs, listStatelessLaneIssues, formatGcReport, gitFetch, listMicroVms, listOrphanContainers, logCost, logEvent, planQueueMigration, pollBlockedParks, readCosts, readGithubQueueSnapshot, reapCleanShipWorktree, reapLaneWorktree, reapOrphanContainers, reapOrphanMicroVm, releaseRuntimeFiles, releaseStaleClaims, resolveBranchPrefix, resolveEffectiveConfig, resolveExperimental, resolveLocalOnly, describeDraftPrPolicy, resolveDraftPrPolicy, resolvePrClassifierPolicy, resolveReviewFloorRules, runOvernightQueue, parseRemoteSlug, setupWorktree, shellEscape, listBuiltInCheckers, sweepWorktrees, watchChecks, withFileLock, withGitLock, writePortFile, buildTriagePrompt, parseTriageCandidates, laneSlug, formatStopMarker, readStopMarker, detectClaudePlan, } from '@on-par/factory-core/internal';
|
|
16
|
+
import { CliExitError } from './errors.js';
|
|
17
|
+
import { withRepoRunLock } from './repo-run-lock.js';
|
|
18
|
+
export { CliExitError, withRepoRunLock };
|
|
16
19
|
import { formatSteerabilityReport } from '@on-par/factory-core/internal';
|
|
17
20
|
import { runTui } from '@on-par/factory-tui';
|
|
18
21
|
import { clearSelfUpdateStop } from './self-update-stop.js';
|
|
@@ -22,7 +25,7 @@ import { buildSteerabilityReport } from './steerability-report.js';
|
|
|
22
25
|
import { runHarnessCheckCommand } from './harness-check.js';
|
|
23
26
|
import { landIssue } from './land.js';
|
|
24
27
|
import { STOP_SET_MESSAGE } from './stop-sentinel.js';
|
|
25
|
-
import { AwaitingReviewError, CiFailedError,
|
|
28
|
+
import { AwaitingReviewError, CiFailedError, isCiNotGreen, LandConflictError, LandFailureError, MergeGatedError, } from './land-pr.js';
|
|
26
29
|
import { setLandRuntime } from './land-runtime.js';
|
|
27
30
|
import { cmdRun } from './run.js';
|
|
28
31
|
import { shipIssue } from './ship.js';
|
|
@@ -578,15 +581,6 @@ async function cmdMigrate(opts = {}) {
|
|
|
578
581
|
}
|
|
579
582
|
export class InvalidProductNameError extends Error {
|
|
580
583
|
}
|
|
581
|
-
/** Expected user-facing CLI failure. Thrown by command helpers; only main() maps it to a process exit code. */
|
|
582
|
-
export class CliExitError extends Error {
|
|
583
|
-
code;
|
|
584
|
-
constructor(message, code) {
|
|
585
|
-
super(message);
|
|
586
|
-
this.code = code;
|
|
587
|
-
this.name = 'CliExitError';
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
584
|
/** Parse a CLI <issue> argument; rejects unsafe integers (#2836), also used by reset. Throws CliExitError(2) before any git/GitHub work runs. */
|
|
591
585
|
export function parseIssueArg(raw) {
|
|
592
586
|
const n = /^\d+$/.test(raw.trim()) ? Number(raw) : NaN;
|
|
@@ -1597,7 +1591,7 @@ async function cmdShip(issueNum, opts) {
|
|
|
1597
1591
|
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1598
1592
|
throw new CliExitError(`Ship failed for issue #${issueNum}: ${err.message}`, 1);
|
|
1599
1593
|
}
|
|
1600
|
-
});
|
|
1594
|
+
}, { scope: { kind: 'issue', key: workKeyFromIssue(issueNum) } });
|
|
1601
1595
|
}
|
|
1602
1596
|
async function cmdRunIssue(issueNum, opts) {
|
|
1603
1597
|
if (availableAgentClis(coreOps.isCommandAvailable).length === 0) {
|
|
@@ -1659,7 +1653,7 @@ async function cmdRunIssue(issueNum, opts) {
|
|
|
1659
1653
|
}
|
|
1660
1654
|
throw new CliExitError(`Run failed for issue #${issueNum}: ${err.message}`, 1);
|
|
1661
1655
|
}
|
|
1662
|
-
});
|
|
1656
|
+
}, { scope: { kind: 'issue', key: workKeyFromIssue(issueNum) } });
|
|
1663
1657
|
}
|
|
1664
1658
|
/** Runs each decomposed child through the one-shot pipeline in build order, inside the caller's
|
|
1665
1659
|
* run lock, then prints a per-child summary. Nested decompositions expand in place and closed
|
|
@@ -1684,14 +1678,14 @@ async function runDecomposedChildren(parent, children, opts, env) {
|
|
|
1684
1678
|
console.log(styleText('cyan', `one-shot: resolved ${work.id} — running the pipeline (queue untouched)`));
|
|
1685
1679
|
let outcome;
|
|
1686
1680
|
try {
|
|
1687
|
-
await shipIssue(child, opts, {
|
|
1681
|
+
await withRepoRunLock(paths, 'factory run-issue', () => shipIssue(child, opts, {
|
|
1688
1682
|
repoRoot: env.repoRoot,
|
|
1689
1683
|
ghRepo: env.ghRepo,
|
|
1690
1684
|
workRequest: work,
|
|
1691
1685
|
onOutcome: (o) => {
|
|
1692
1686
|
outcome = o;
|
|
1693
1687
|
},
|
|
1694
|
-
});
|
|
1688
|
+
}), { scope: { kind: 'issue', key: workKeyFromIssue(child) } });
|
|
1695
1689
|
}
|
|
1696
1690
|
catch (err) {
|
|
1697
1691
|
if (err instanceof IssueDecomposedError) {
|
|
@@ -1731,51 +1725,51 @@ async function cmdRunBrief(briefPath, opts) {
|
|
|
1731
1725
|
throw new CliExitError(`factory: ${notInitializedMessage()}`, 2);
|
|
1732
1726
|
}
|
|
1733
1727
|
const branchPrefix = branchPrefixOrExit(opts.branchPrefix);
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
try {
|
|
1739
|
-
localOnly = resolveLocalOnlyPolicy(opts.workspace);
|
|
1740
|
-
}
|
|
1741
|
-
catch (err) {
|
|
1742
|
-
if (err instanceof InvalidWorkspaceError)
|
|
1743
|
-
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1744
|
-
throw err;
|
|
1745
|
-
}
|
|
1728
|
+
let localOnly;
|
|
1729
|
+
if (opts.workspace !== undefined) {
|
|
1730
|
+
try {
|
|
1731
|
+
localOnly = resolveLocalOnlyPolicy(opts.workspace);
|
|
1746
1732
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1758
|
-
throw err;
|
|
1759
|
-
}
|
|
1760
|
-
console.log(styleText('cyan', `local-only: benchmark artifacts will be written to ${artifactsDir}`));
|
|
1733
|
+
catch (err) {
|
|
1734
|
+
if (err instanceof InvalidWorkspaceError)
|
|
1735
|
+
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1736
|
+
throw err;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
let artifactsDir;
|
|
1740
|
+
if (opts.artifacts !== undefined) {
|
|
1741
|
+
if (!localOnly) {
|
|
1742
|
+
throw new CliExitError('factory: --artifacts requires --workspace (local-only runs only)', 2);
|
|
1761
1743
|
}
|
|
1762
|
-
// Local-only runs never touch GitHub — no remote required, no mutation possible.
|
|
1763
|
-
const ghRepo = localOnly ? 'local/workspace' : await getGitHubRepo();
|
|
1764
|
-
// Pre-flight: resolve the brief through the canonical work-request seam
|
|
1765
|
-
// BEFORE any worktree or PR exists — a malformed brief exits here, so BUILD never starts.
|
|
1766
|
-
const workSources = createDefaultWorkSourceRegistry({ octokit: getOctokit() });
|
|
1767
|
-
let work;
|
|
1768
1744
|
try {
|
|
1769
|
-
|
|
1745
|
+
artifactsDir = resolveArtifactsDir(opts.artifacts);
|
|
1770
1746
|
}
|
|
1771
1747
|
catch (err) {
|
|
1772
|
-
if (err instanceof
|
|
1748
|
+
if (err instanceof InvalidArtifactsDirError)
|
|
1773
1749
|
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1774
|
-
|
|
1775
|
-
|
|
1750
|
+
throw err;
|
|
1751
|
+
}
|
|
1752
|
+
console.log(styleText('cyan', `local-only: benchmark artifacts will be written to ${artifactsDir}`));
|
|
1753
|
+
}
|
|
1754
|
+
// Local-only runs never touch GitHub — no remote required, no mutation possible.
|
|
1755
|
+
const ghRepo = localOnly ? 'local/workspace' : await getGitHubRepo();
|
|
1756
|
+
// Pre-flight: resolve the brief through the canonical work-request seam
|
|
1757
|
+
// BEFORE any worktree or PR exists — a malformed brief exits here, so BUILD never starts.
|
|
1758
|
+
const workSources = createDefaultWorkSourceRegistry({ octokit: getOctokit() });
|
|
1759
|
+
let work;
|
|
1760
|
+
try {
|
|
1761
|
+
work = await workSources.resolve(LOCAL_BRIEF_SOURCE, { path: briefPath });
|
|
1762
|
+
}
|
|
1763
|
+
catch (err) {
|
|
1764
|
+
if (err instanceof InvalidWorkRequestInputError) {
|
|
1765
|
+
throw new CliExitError(`factory: ${err.message}`, 2);
|
|
1776
1766
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1767
|
+
throw new CliExitError(`factory: could not resolve brief at ${briefPath} (${errorDetail(err)}) — no worktree or PR was created`, 2);
|
|
1768
|
+
}
|
|
1769
|
+
const digest = work.reference?.externalId ?? '';
|
|
1770
|
+
const runNum = briefRunNumber(digest);
|
|
1771
|
+
await withRepoRunLock(paths, 'factory run-brief', async () => {
|
|
1772
|
+
recordDraftPrFlag(paths.runFlags, opts.draftPr);
|
|
1779
1773
|
console.log(styleText('cyan', `one-shot: resolved ${work.id} — running the pipeline (queue untouched)`));
|
|
1780
1774
|
logEvent(paths.events, 'work-source', runNum, `inline local brief ${briefPath} (sha256 ${digest})`);
|
|
1781
1775
|
if (localOnly) {
|
|
@@ -1801,7 +1795,7 @@ async function cmdRunBrief(briefPath, opts) {
|
|
|
1801
1795
|
catch (err) {
|
|
1802
1796
|
throw new CliExitError(`Run failed for brief ${briefPath}: ${err.message}`, 1);
|
|
1803
1797
|
}
|
|
1804
|
-
});
|
|
1798
|
+
}, { scope: { kind: 'issue', key: workKeyFromIssue(runNum) } });
|
|
1805
1799
|
}
|
|
1806
1800
|
async function cmdLocalSmallDryRun(issueNum, opts) {
|
|
1807
1801
|
const repoRoot = await getRepoRoot();
|
|
@@ -1891,27 +1885,6 @@ function worktreePathFor(repoRoot, ghRepo, issueNum, prefix, loaders = configLoa
|
|
|
1891
1885
|
prefix,
|
|
1892
1886
|
});
|
|
1893
1887
|
}
|
|
1894
|
-
/** Fences a whole run behind the checkout's `.factory/run.lock` (#598). A live holder is
|
|
1895
|
-
* refused immediately — never queued behind a multi-hour run — and a dead holder's lock is
|
|
1896
|
-
* reclaimed by withRunLock. Nested acquisition inside one process is a pass-through, so
|
|
1897
|
-
* `factory supervise` can hold this across its loop. */
|
|
1898
|
-
export async function withRepoRunLock(paths, command, fn, deps = {}) {
|
|
1899
|
-
const { runLock = withRunLock, emitEvent = logEvent } = deps;
|
|
1900
|
-
try {
|
|
1901
|
-
return await runLock(paths.runLock, fn, {
|
|
1902
|
-
command,
|
|
1903
|
-
onReclaim: (pid) => emitEvent(paths.events, 'lock-stolen', '-', `reclaimed ${paths.runLock} from dead holder pid ${pid ?? 'unknown'}`),
|
|
1904
|
-
});
|
|
1905
|
-
}
|
|
1906
|
-
catch (err) {
|
|
1907
|
-
if (err instanceof RunLockHeldError) {
|
|
1908
|
-
emitEvent(paths.events, 'run_lock_conflict', '-', `${command} refused: ${err.message}`);
|
|
1909
|
-
throw new CliExitError(`factory: ${err.message} — stop that run (or wait for it to finish) before starting another. ` +
|
|
1910
|
-
`A dead run's lock is reclaimed automatically; remove ${paths.runLock} only if you are sure no factory run is live.`, 2);
|
|
1911
|
-
}
|
|
1912
|
-
throw err;
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
1888
|
export async function reapParkedLaneWorktree(issue, repoRoot, ghRepo, paths, prefixOverride) {
|
|
1916
1889
|
await reapParkedLane({ configLoaders, worktreePathFor }, reapLaneWorktree, [
|
|
1917
1890
|
issue,
|
|
@@ -2033,7 +2006,7 @@ export async function cmdLand(issueNum, opts = {}, deps = {}) {
|
|
|
2033
2006
|
console.log(styleText('yellow', `⏸ PR #${err.prNumber} for issue #${issueNum} awaiting human review — left open`));
|
|
2034
2007
|
return;
|
|
2035
2008
|
}
|
|
2036
|
-
if (err
|
|
2009
|
+
if (isCiNotGreen(err)) {
|
|
2037
2010
|
console.log(styleText('yellow', `⏸ PR #${err.prNumber} for issue #${issueNum} — CI never reached a green verdict — left open, not merged`));
|
|
2038
2011
|
return;
|
|
2039
2012
|
}
|
|
@@ -3026,7 +2999,7 @@ async function resumeFromCheck(issueNum) {
|
|
|
3026
2999
|
return;
|
|
3027
3000
|
throw new CliExitError(`Resume failed for issue #${issueNum}: ${err.message}`, 1);
|
|
3028
3001
|
}
|
|
3029
|
-
});
|
|
3002
|
+
}, { scope: { kind: 'issue', key: workKeyFromIssue(issueNum) } });
|
|
3030
3003
|
}
|
|
3031
3004
|
/** index.ts bindings the commander registrations in program*.ts call (#2793); type-only imports there avoid a runtime cycle. */
|
|
3032
3005
|
/** `factory supervise` (#2797): the handler lives in ./supervise.ts; this binds its runtime. */
|