@on-par/factory-cli 0.0.0-stage → 0.9.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.
- package/LICENSE +21 -0
- package/README.md +23 -2
- package/dist/cli/admission.d.ts +17 -0
- package/dist/cli/admission.d.ts.map +1 -0
- package/dist/cli/admission.js +37 -0
- package/dist/cli/admission.js.map +1 -0
- package/dist/cli/branch-prefix.d.ts +8 -0
- package/dist/cli/branch-prefix.d.ts.map +1 -0
- package/dist/cli/branch-prefix.js +16 -0
- package/dist/cli/branch-prefix.js.map +1 -0
- package/dist/cli/classifier-backtest.d.ts +50 -0
- package/dist/cli/classifier-backtest.d.ts.map +1 -0
- package/dist/cli/classifier-backtest.js +112 -0
- package/dist/cli/classifier-backtest.js.map +1 -0
- package/dist/cli/cost-json.d.ts +37 -0
- package/dist/cli/cost-json.d.ts.map +1 -0
- package/dist/cli/cost-json.js +48 -0
- package/dist/cli/cost-json.js.map +1 -0
- package/dist/cli/daemon.d.ts +113 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +282 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/doctor.d.ts +127 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +400 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/feedback.d.ts +74 -0
- package/dist/cli/feedback.d.ts.map +1 -0
- package/dist/cli/feedback.js +180 -0
- package/dist/cli/feedback.js.map +1 -0
- package/dist/cli/filing.d.ts +22 -0
- package/dist/cli/filing.d.ts.map +1 -0
- package/dist/cli/filing.js +53 -0
- package/dist/cli/filing.js.map +1 -0
- package/dist/cli/first-run.d.ts +9 -0
- package/dist/cli/first-run.d.ts.map +1 -0
- package/dist/cli/first-run.js +34 -0
- package/dist/cli/first-run.js.map +1 -0
- package/dist/cli/help-groups.d.ts +17 -0
- package/dist/cli/help-groups.d.ts.map +1 -0
- package/dist/cli/help-groups.js +50 -0
- package/dist/cli/help-groups.js.map +1 -0
- package/dist/cli/hosted-queue.d.ts +45 -0
- package/dist/cli/hosted-queue.d.ts.map +1 -0
- package/dist/cli/hosted-queue.js +74 -0
- package/dist/cli/hosted-queue.js.map +1 -0
- package/dist/cli/hosted-runner.d.ts +44 -0
- package/dist/cli/hosted-runner.d.ts.map +1 -0
- package/dist/cli/hosted-runner.js +68 -0
- package/dist/cli/hosted-runner.js.map +1 -0
- package/dist/cli/hosted.d.ts +38 -0
- package/dist/cli/hosted.d.ts.map +1 -0
- package/dist/cli/hosted.js +82 -0
- package/dist/cli/hosted.js.map +1 -0
- package/dist/cli/index.d.ts +656 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4801 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-files.d.ts +8 -0
- package/dist/cli/init-files.d.ts.map +1 -0
- package/dist/cli/init-files.js +45 -0
- package/dist/cli/init-files.js.map +1 -0
- package/dist/cli/logs.d.ts +27 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +52 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/merge-scope.d.ts +7 -0
- package/dist/cli/merge-scope.d.ts.map +1 -0
- package/dist/cli/merge-scope.js +14 -0
- package/dist/cli/merge-scope.js.map +1 -0
- package/dist/cli/octokit.d.ts +43 -0
- package/dist/cli/octokit.d.ts.map +1 -0
- package/dist/cli/octokit.js +87 -0
- package/dist/cli/octokit.js.map +1 -0
- package/dist/cli/queue-add-json.d.ts +25 -0
- package/dist/cli/queue-add-json.d.ts.map +1 -0
- package/dist/cli/queue-add-json.js +24 -0
- package/dist/cli/queue-add-json.js.map +1 -0
- package/dist/cli/queue-clear.d.ts +15 -0
- package/dist/cli/queue-clear.d.ts.map +1 -0
- package/dist/cli/queue-clear.js +58 -0
- package/dist/cli/queue-clear.js.map +1 -0
- package/dist/cli/queue-list.d.ts +24 -0
- package/dist/cli/queue-list.d.ts.map +1 -0
- package/dist/cli/queue-list.js +25 -0
- package/dist/cli/queue-list.js.map +1 -0
- package/dist/cli/ready-check.d.ts +98 -0
- package/dist/cli/ready-check.d.ts.map +1 -0
- package/dist/cli/ready-check.js +169 -0
- package/dist/cli/ready-check.js.map +1 -0
- package/dist/cli/reset.d.ts +40 -0
- package/dist/cli/reset.d.ts.map +1 -0
- package/dist/cli/reset.js +215 -0
- package/dist/cli/reset.js.map +1 -0
- package/dist/cli/run-children.d.ts +24 -0
- package/dist/cli/run-children.d.ts.map +1 -0
- package/dist/cli/run-children.js +73 -0
- package/dist/cli/run-children.js.map +1 -0
- package/dist/cli/run-flags.d.ts +14 -0
- package/dist/cli/run-flags.d.ts.map +1 -0
- package/dist/cli/run-flags.js +43 -0
- package/dist/cli/run-flags.js.map +1 -0
- package/dist/cli/runs-diffstat.d.ts +43 -0
- package/dist/cli/runs-diffstat.d.ts.map +1 -0
- package/dist/cli/runs-diffstat.js +91 -0
- package/dist/cli/runs-diffstat.js.map +1 -0
- package/dist/cli/runs.d.ts +36 -0
- package/dist/cli/runs.d.ts.map +1 -0
- package/dist/cli/runs.js +102 -0
- package/dist/cli/runs.js.map +1 -0
- package/dist/cli/staleness.d.ts +30 -0
- package/dist/cli/staleness.d.ts.map +1 -0
- package/dist/cli/staleness.js +132 -0
- package/dist/cli/staleness.js.map +1 -0
- package/dist/cli/status-json.d.ts +45 -0
- package/dist/cli/status-json.d.ts.map +1 -0
- package/dist/cli/status-json.js +22 -0
- package/dist/cli/status-json.js.map +1 -0
- package/dist/cli/stop-resume-json.d.ts +18 -0
- package/dist/cli/stop-resume-json.d.ts.map +1 -0
- package/dist/cli/stop-resume-json.js +10 -0
- package/dist/cli/stop-resume-json.js.map +1 -0
- package/dist/cli/stop-sentinel.d.ts +23 -0
- package/dist/cli/stop-sentinel.d.ts.map +1 -0
- package/dist/cli/stop-sentinel.js +61 -0
- package/dist/cli/stop-sentinel.js.map +1 -0
- package/dist/cli/sweep-heartbeat.d.ts +33 -0
- package/dist/cli/sweep-heartbeat.d.ts.map +1 -0
- package/dist/cli/sweep-heartbeat.js +65 -0
- package/dist/cli/sweep-heartbeat.js.map +1 -0
- package/dist/cli/unpark.d.ts +28 -0
- package/dist/cli/unpark.d.ts.map +1 -0
- package/dist/cli/unpark.js +68 -0
- package/dist/cli/unpark.js.map +1 -0
- package/dist/cli/usage-json.d.ts +20 -0
- package/dist/cli/usage-json.d.ts.map +1 -0
- package/dist/cli/usage-json.js +36 -0
- package/dist/cli/usage-json.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -0
- package/dist/entry.d.ts +6 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +13 -0
- package/dist/entry.js.map +1 -0
- package/package.json +48 -4
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { type StdioOptions } from 'node:child_process';
|
|
2
|
+
import type { Octokit } from '@octokit/rest';
|
|
3
|
+
import type { Environment, EnvironmentProxySettings, EventKind, FactoryConfig, IngestSettings, LaneProxy, LocalOnlyPolicy, MergePolicyOverrides, ModelDiagnosis, LanePausedPayload, ParkReason, QueueDiagnostic, RepoFactoryConfig, RunOutcome, RunPorts, SandboxRuntime, UsageReading, WatchdogPolicyOverrides, WatchdogPolicySource, WorkRequest, WorkRequestSourceKind } from '@on-par/factory-core';
|
|
4
|
+
import { ConstitutionLoader, createLaneProxy, defaultFindPortListeners, diagnoseModels, estimateTrailingSpend, fetchSubscriptionUsage, formatUsageReport, getConstitutionsDir, getFactoryPaths, isCommandAvailable, isProxyRunning, loadFactoryConfigForRepo, loadModelsConfig, loadRepoConfig, loadRoutesConfig, ModelRegistry, ModelRouter, reapOrphanProcesses, type SizeGateMode, resolveEffectiveModelPins, resolveSkipCI, resolveTimeouts, runAutoIngest, watchUsage, writeLocalRunReport } from '@on-par/factory-core';
|
|
5
|
+
import type { CiOutcome, GithubQueue, QueueClaim, QueueIssue, QueuePreflightDecision, QueueReleaseOutcome, SlicePlan, SlicePlanCommentLookup, WatchChecksOptions } from '@on-par/factory-core/internal';
|
|
6
|
+
import { migrateRepoConfigToYaml, cleanupWorktree, createLocalSmallDryRun, findUnmergedGreenPrs, formatGcReport, gitFetch, listMicroVms, listOrphanContainers, logEvent, readCosts, reapOrphanContainers, reapOrphanMicroVm, releaseStaleClaims, setupWorktree, sweepWorktrees, watchChecks, withRunLock } from '@on-par/factory-core/internal';
|
|
7
|
+
import { type QueueReader, runTui } from '@on-par/factory-tui';
|
|
8
|
+
import { type DaemonCtlDeps } from './daemon.js';
|
|
9
|
+
import { type FeedbackDeps } from './feedback.js';
|
|
10
|
+
type ConfigLoaderKey = 'loadModelsConfig' | 'loadRoutesConfig' | 'loadFactoryConfigForRepo' | 'loadRepoConfig' | 'resolveTimeouts' | 'resolveSkipCI' | 'getConstitutionsDir' | 'resolveEffectiveModelPins';
|
|
11
|
+
type GitOpKey = 'setupWorktree' | 'cleanupWorktree' | 'gitFetch';
|
|
12
|
+
type InternalOpKey = 'watchChecks' | 'createLocalSmallDryRun' | 'readCosts' | 'sweepWorktrees' | 'releaseStaleClaims' | 'findUnmergedGreenPrs' | 'listOrphanContainers' | 'reapOrphanContainers' | 'listMicroVms' | 'reapOrphanMicroVm' | 'formatGcReport';
|
|
13
|
+
export type ShellExec = (command: string, options?: {
|
|
14
|
+
cwd?: string;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
}) => Promise<{
|
|
17
|
+
stdout: string;
|
|
18
|
+
stderr: string;
|
|
19
|
+
}>;
|
|
20
|
+
export type ShellExecSync = (command: string, options?: {
|
|
21
|
+
timeout?: number;
|
|
22
|
+
stdio?: StdioOptions;
|
|
23
|
+
}) => string;
|
|
24
|
+
type ShellOpKey = 'exec' | 'execSync';
|
|
25
|
+
type CoreOpKey = 'ModelRouter' | 'ConstitutionLoader' | 'ModelRegistry' | 'isCommandAvailable' | 'defaultFindPortListeners' | 'reapOrphanProcesses' | 'estimateTrailingSpend' | 'formatUsageReport' | 'watchUsage' | 'fetchSubscriptionUsage' | 'diagnoseModels' | 'writeLocalRunReport';
|
|
26
|
+
type CommandRunner = (command: string, options?: {
|
|
27
|
+
cwd?: string;
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}) => Promise<unknown>;
|
|
30
|
+
export declare const PREREQUISITES_TEXT = "Prerequisites:\n - Claude Code CLI installed and authenticated (Claude subscription): https://claude.com/claude-code\n - GitHub CLI authenticated: gh auth login\n - GITHUB_TOKEN or GH_TOKEN set (falls back to `gh auth token`)\nRun inside a git repository with a GitHub remote.\n";
|
|
31
|
+
/** Printed after the command list in `factory --help`: the env vars operators reach for most. */
|
|
32
|
+
export declare const HELP_FOOTER_TEXT = "\nCommon environment variables:\n FACTORY_MERGE=1 Squash-merge eligible PRs (--auto-merge / --no-auto-merge win)\n FACTORY_MERGE_ADMIN=1 Merge with GitHub admin bypass of unmet requirements\n FACTORY_SKIP_CI=1 Do not wait for CI before merging\n FACTORY_SANDBOX=0 Disable the containment sandbox for agent runs (dangerous)\n FACTORY_PLAN_MODEL=<id> Pick the PLAN model\n FACTORY_BUILD_MODEL=<id> Pick the BUILD model\n FACTORY_STOP_AT=<fraction> Usage fraction (0-1] at which work pauses\n FACTORY_RESUME_AT=<fraction> Usage fraction (0-1] at which paused work resumes\n FACTORY_ALLOW_STALE=1 Run even when the built CLI is older than its source\nEvery config key, its default, and its env var: docs/config.example.yaml\n\nRun `factory <command> --help` for a command's options.\nDocs: https://github.com/on-par/software-factory#readme";
|
|
33
|
+
export declare function errorDetail(err: unknown): string;
|
|
34
|
+
export declare function hasGitHubToken(env?: NodeJS.ProcessEnv, tryToken?: () => string): boolean;
|
|
35
|
+
/** The minimal, pin-free repo config `factory init` writes. No model pins → routing
|
|
36
|
+
* stays on packaged defaults (policy=auto). YAML (header comment + `version: 2`) by default;
|
|
37
|
+
* `'json'` gives two-space JSON + trailing newline for repos that already use config.json.
|
|
38
|
+
* Every available key is documented in docs/config.example.jsonc. */
|
|
39
|
+
export declare function buildInitConfig(format?: 'yaml' | 'json'): string;
|
|
40
|
+
/** One-line onboarding reachability summary, e.g. "policy=auto, 3/7 models reachable". */
|
|
41
|
+
export declare function formatInitReachability(diagnoses: ModelDiagnosis[]): string;
|
|
42
|
+
/** Rewrite a checkout's legacy `.factory/` inputs and runtime files to the v2
|
|
43
|
+
* layout. Every write is idempotent so it is safe to run this more than once. */
|
|
44
|
+
export declare function runMigrate(repoRoot: string, opts?: {
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
toYaml?: boolean;
|
|
47
|
+
migrateToYaml?: typeof migrateRepoConfigToYaml;
|
|
48
|
+
}): Promise<void>;
|
|
49
|
+
export declare class InvalidProductNameError extends Error {
|
|
50
|
+
}
|
|
51
|
+
/** Expected user-facing CLI failure. Thrown by command helpers; only main() maps it to a process exit code. */
|
|
52
|
+
export declare class CliExitError extends Error {
|
|
53
|
+
readonly code: number;
|
|
54
|
+
constructor(message: string, code: number);
|
|
55
|
+
}
|
|
56
|
+
/** Parse a CLI <issue> argument. Throws CliExitError(2) before any git/GitHub work runs. */
|
|
57
|
+
export declare function parseIssueArg(raw: string): number;
|
|
58
|
+
/** Run `factory feedback` and print the filed issue; validation errors become exit-2 CliExitErrors. */
|
|
59
|
+
export declare function runFeedbackCommand(prUrl: string, opts: {
|
|
60
|
+
note?: string;
|
|
61
|
+
}, deps: FeedbackDeps, log?: (line: string) => void): Promise<void>;
|
|
62
|
+
export declare function cmdFeedback(prUrl: string, opts: {
|
|
63
|
+
note?: string;
|
|
64
|
+
branchPrefix?: string;
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
export declare function cmdFilingPreview(runId: string, opts: {
|
|
67
|
+
branchPrefix?: string;
|
|
68
|
+
}): Promise<void>;
|
|
69
|
+
export declare function assertValidProduct(product: string): void;
|
|
70
|
+
export interface ReadActiveProductDeps {
|
|
71
|
+
fileExists?: (p: string) => boolean;
|
|
72
|
+
readFile?: (p: string) => string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Read the active product name from the `.factory/product` file.
|
|
76
|
+
* Returns the trimmed content, or undefined when the file is missing
|
|
77
|
+
* or contains only whitespace.
|
|
78
|
+
*/
|
|
79
|
+
export declare function readActiveProduct(productPath: string, deps?: ReadActiveProductDeps): string | undefined;
|
|
80
|
+
/** Extract the template's ```markdown skeleton and fill in the product name. */
|
|
81
|
+
export declare function scaffoldConstitution(template: string, product: string): string;
|
|
82
|
+
export declare function cmdConstitution(opts: {
|
|
83
|
+
list?: boolean;
|
|
84
|
+
product?: string;
|
|
85
|
+
init?: string | boolean;
|
|
86
|
+
force?: boolean;
|
|
87
|
+
}, deps?: Pick<CliDeps, 'ConstitutionLoader'>): Promise<void>;
|
|
88
|
+
export declare function formatDoctorReport(diagnoses: ModelDiagnosis[]): string;
|
|
89
|
+
export declare function hasReachableWorker(diagnoses: ModelDiagnosis[]): boolean;
|
|
90
|
+
export interface UsageKnobs {
|
|
91
|
+
cap: number;
|
|
92
|
+
stopAt: number;
|
|
93
|
+
resumeAt: number;
|
|
94
|
+
pollMs: number;
|
|
95
|
+
watch: boolean;
|
|
96
|
+
estimator: boolean;
|
|
97
|
+
/** Where `watch` was decided — `'flag'` when `--usage-watch`/`--no-usage-watch` was supplied. */
|
|
98
|
+
watchSource: WatchdogPolicySource;
|
|
99
|
+
stopAtSource: WatchdogPolicySource;
|
|
100
|
+
resumeAtSource: WatchdogPolicySource;
|
|
101
|
+
pollSource: WatchdogPolicySource;
|
|
102
|
+
}
|
|
103
|
+
export declare function resolveUsageKnobs(env?: NodeJS.ProcessEnv, repoConfig?: RepoFactoryConfig | null, overrides?: WatchdogPolicyOverrides): UsageKnobs;
|
|
104
|
+
/** Human-readable name for whatever decided the usage-watch gate, used in the `factory run`
|
|
105
|
+
* and `factory supervise` logs so an explicit operator override is always attributable (#1404). */
|
|
106
|
+
export declare function usageWatchSourceLabel(source: WatchdogPolicySource, watch: boolean): string;
|
|
107
|
+
export declare function cmdUsage(deps?: Pick<CliDeps, ShellOpKey | 'fetchSubscriptionUsage' | 'estimateTrailingSpend' | 'formatUsageReport'>, opts?: {
|
|
108
|
+
json?: boolean;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
export declare function cmdStatus(opts?: {
|
|
111
|
+
kpis?: boolean;
|
|
112
|
+
json?: boolean;
|
|
113
|
+
}): Promise<void>;
|
|
114
|
+
/** The Queue tab's backlog source for `factory tui` (#1362). Mirrors `factory run`: GitHub Issues
|
|
115
|
+
* by default, the local queue file only under `--local-queue`. Never throws at build time — a
|
|
116
|
+
* missing repo or token becomes a snapshot error the tab renders, so the TUI still starts.
|
|
117
|
+
*
|
|
118
|
+
* The token is resolved here, before Ink takes the terminal, so the `gh auth token` subprocess
|
|
119
|
+
* never runs inside the first poll. Octokit is built at most once and only on the GitHub path;
|
|
120
|
+
* when no token is present at startup, each poll re-resolves it so a `gh auth login` in another
|
|
121
|
+
* terminal is picked up without restarting the TUI. */
|
|
122
|
+
export declare function tuiQueueReader(input: {
|
|
123
|
+
localQueue: boolean;
|
|
124
|
+
queueFile: string;
|
|
125
|
+
queueProposedFile: string;
|
|
126
|
+
repo: string | undefined;
|
|
127
|
+
token?: () => string | undefined;
|
|
128
|
+
octokit?: (token: string) => Octokit;
|
|
129
|
+
}): QueueReader;
|
|
130
|
+
export type { ParkReason, RunOutcome } from '@on-par/factory-core';
|
|
131
|
+
export { parkEvents, parkReasonFor } from '@on-par/factory-core';
|
|
132
|
+
export declare class LaneParkError extends Error {
|
|
133
|
+
readonly outcome: Extract<RunOutcome, {
|
|
134
|
+
state: 'parked';
|
|
135
|
+
}>;
|
|
136
|
+
constructor(message: string, reason: ParkReason, failure?: {
|
|
137
|
+
failureSignature?: string;
|
|
138
|
+
failingChecks?: string[];
|
|
139
|
+
});
|
|
140
|
+
get reason(): ParkReason;
|
|
141
|
+
get failureSignature(): string | undefined;
|
|
142
|
+
get failingChecks(): string[] | undefined;
|
|
143
|
+
}
|
|
144
|
+
/** CHECK found every failing checker also failing on the base SHA (#1928): the issue is
|
|
145
|
+
* released to queued (not parked) and the lane pauses. */
|
|
146
|
+
export declare class LaneEnvironmentPauseError extends Error {
|
|
147
|
+
readonly baseSha: string;
|
|
148
|
+
readonly failingChecks: string[];
|
|
149
|
+
readonly failureSignature?: string;
|
|
150
|
+
constructor(message: string, failure: {
|
|
151
|
+
baseSha: string;
|
|
152
|
+
failingChecks: string[];
|
|
153
|
+
failureSignature?: string;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/** Resolves the stable lane URL a build/check agent should use, by probing whether
|
|
157
|
+
* a factory proxy (started by `factory run`/`supervise` or `factory proxy`) is
|
|
158
|
+
* currently alive for the configured domain. Never throws — an absent/dead proxy
|
|
159
|
+
* just degrades to the existing port-based URL, single informational note either way. */
|
|
160
|
+
export declare function resolveLaneBaseUrl(paths: ReturnType<typeof getFactoryPaths>, settings: EnvironmentProxySettings, worktree: string, appPort: number | undefined, deps?: {
|
|
161
|
+
isRunning?: typeof isProxyRunning;
|
|
162
|
+
}): {
|
|
163
|
+
baseUrl?: string;
|
|
164
|
+
note: string;
|
|
165
|
+
};
|
|
166
|
+
/** Builds the port-lease acquirer passed to runIssue, or undefined to skip it. A
|
|
167
|
+
* docker-sandbox lane runs inside its own microVM network namespace and binds its
|
|
168
|
+
* normal port there, so it needs no host port-lease and (since the proxy resolves
|
|
169
|
+
* routes solely from the lease registry) no proxy route either — every other
|
|
170
|
+
* runtime keeps acquiring a lease exactly as before. */
|
|
171
|
+
export declare function resolveEnvironmentAcquirer(opts: {
|
|
172
|
+
laneSandboxRuntime: SandboxRuntime;
|
|
173
|
+
paths: ReturnType<typeof getFactoryPaths>;
|
|
174
|
+
worktree: string;
|
|
175
|
+
branch: string;
|
|
176
|
+
range: [number, number];
|
|
177
|
+
processGroupGraceMs: number;
|
|
178
|
+
log: (type: EventKind, msg: string) => void;
|
|
179
|
+
findPortListeners?: typeof defaultFindPortListeners;
|
|
180
|
+
reapOrphanProcesses?: typeof reapOrphanProcesses;
|
|
181
|
+
}): (() => Promise<Environment>) | undefined;
|
|
182
|
+
export declare function shipIssue(issueNum: number, opts: {
|
|
183
|
+
product?: string;
|
|
184
|
+
autoRework?: boolean;
|
|
185
|
+
interactive?: boolean;
|
|
186
|
+
sandbox?: boolean;
|
|
187
|
+
approvePlan?: boolean;
|
|
188
|
+
branchPrefix?: string;
|
|
189
|
+
/** `run-issue --size-gate` (ADR-0147); undefined defers to sizeGate.mode in the config. */
|
|
190
|
+
sizeGate?: SizeGateMode;
|
|
191
|
+
/** run-issue --max-slices (ADR-0156); undefined defers to sizeGate.maxSlices. */
|
|
192
|
+
maxSlices?: number;
|
|
193
|
+
/** `--pr-classifier` / `--no-pr-classifier` (#1724); undefined defers to config/env. */
|
|
194
|
+
prClassifier?: boolean;
|
|
195
|
+
}, ctx?: {
|
|
196
|
+
repoRoot: string;
|
|
197
|
+
ghRepo: string;
|
|
198
|
+
/** Resolved factory state paths, supplied by daemon lanes with an external state root. */
|
|
199
|
+
paths?: ReturnType<typeof getFactoryPaths>;
|
|
200
|
+
lane?: string;
|
|
201
|
+
workRequest?: WorkRequest;
|
|
202
|
+
/** Receives the core RunOutcome before shipIssue maps it to a return/throw — lets
|
|
203
|
+
* `run-issue --run-children` read the PR number as data (#1747). */
|
|
204
|
+
onOutcome?: (outcome: RunOutcome) => void;
|
|
205
|
+
/** Input source for planPhase to resolve; defaults inside planPhase to this run's GitHub issue. */
|
|
206
|
+
workSource?: {
|
|
207
|
+
kind: WorkRequestSourceKind;
|
|
208
|
+
params: unknown;
|
|
209
|
+
};
|
|
210
|
+
/** Local-only policy (#508): run in this caller-provided workspace, skip
|
|
211
|
+
* worktree creation, disable publishing, and skip the SHIP phase. */
|
|
212
|
+
localOnly?: LocalOnlyPolicy;
|
|
213
|
+
/** Benchmark artifact directory (#509) — only set for local-only runs. */
|
|
214
|
+
artifactsDir?: string;
|
|
215
|
+
}, deps?: Pick<CliDeps, 'octokit' | 'planPhase' | 'buildPhase' | 'checkPhase' | 'shipPhase' | ConfigLoaderKey | GitOpKey | ShellOpKey | CoreOpKey>): Promise<string>;
|
|
216
|
+
export interface LaneGcDeps {
|
|
217
|
+
loadConfig?: (configPath: string) => Pick<FactoryConfig, 'worktree' | 'sandbox'>;
|
|
218
|
+
sweep?: typeof sweepWorktrees;
|
|
219
|
+
emitEvent?: typeof logEvent;
|
|
220
|
+
octokit?: () => NonNullable<Parameters<typeof sweepWorktrees>[1]>['octokit'];
|
|
221
|
+
}
|
|
222
|
+
/** Mid-run worktree GC between issues in a lane (#1757). Honors worktree.autoGcOnRun, holds
|
|
223
|
+
* the git + file locks every worktree mutation holds, and skips (never waits) when another
|
|
224
|
+
* lane holds the land lock so a sweep can never race a merge. Logs worktree-gc only when it
|
|
225
|
+
* removed something. Never throws. */
|
|
226
|
+
export declare function sweepBetweenLaneIssues(issue: number, lane: string, repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, deps?: LaneGcDeps): Promise<'disabled' | 'land-in-progress' | 'swept' | 'failed'>;
|
|
227
|
+
/** Fences a whole run behind the checkout's `.factory/run.lock` (#598). A live holder is
|
|
228
|
+
* refused immediately — never queued behind a multi-hour run — and a dead holder's lock is
|
|
229
|
+
* reclaimed by withRunLock. Nested acquisition inside one process is a pass-through, so
|
|
230
|
+
* `factory supervise` can hold this across its loop. */
|
|
231
|
+
export declare function withRepoRunLock<T>(paths: ReturnType<typeof getFactoryPaths>, command: string, fn: () => Promise<T>, deps?: {
|
|
232
|
+
runLock?: typeof withRunLock;
|
|
233
|
+
emitEvent?: typeof logEvent;
|
|
234
|
+
}): Promise<T>;
|
|
235
|
+
/** Eagerly reaps a parked lane's own worktree inside `factory run` (#1007). All the safety
|
|
236
|
+
* gates live in reapLaneWorktree; this wrapper resolves the lane's conventional worktree
|
|
237
|
+
* path and holds the same git+file lock pairing as every other worktree mutation site. A
|
|
238
|
+
* reap failure is logged as a warn and never surfaces — parking must always succeed. */
|
|
239
|
+
export declare function reapParkedLaneWorktree(issue: number, repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, prefixOverride?: string): Promise<void>;
|
|
240
|
+
export declare function cmdWorktreeGc(opts: {
|
|
241
|
+
dryRun?: boolean;
|
|
242
|
+
ttlDays?: string;
|
|
243
|
+
branchPrefix?: string;
|
|
244
|
+
}): Promise<void>;
|
|
245
|
+
/** `factory reset <issue...>` (#1787): wipes an issue's local state; see reset.ts. */
|
|
246
|
+
export declare function cmdReset(issues: string[], opts: {
|
|
247
|
+
branchPrefix?: string;
|
|
248
|
+
dryRun?: boolean;
|
|
249
|
+
force?: boolean;
|
|
250
|
+
}): Promise<void>;
|
|
251
|
+
/** deps overrides the config loaders, git ops, internal ops and octokit for this call, like shipIssue. */
|
|
252
|
+
export declare function cmdLand(issueNum: number, opts?: {
|
|
253
|
+
branchPrefix?: string;
|
|
254
|
+
allowGated?: boolean;
|
|
255
|
+
}, deps?: Pick<CliDeps, ConfigLoaderKey | GitOpKey | InternalOpKey | ShellOpKey | 'octokit'>): Promise<void>;
|
|
256
|
+
declare function landIssue(issueNum: number, repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, octokit: Octokit, skipCI?: boolean, branchPrefix?: string, opts?: {
|
|
257
|
+
allowGated?: boolean;
|
|
258
|
+
}): Promise<{
|
|
259
|
+
branch: string;
|
|
260
|
+
prNumber: number;
|
|
261
|
+
}>;
|
|
262
|
+
export declare function prLookupFailure(issueNum: number, branch: string, err: unknown): LandFailureError;
|
|
263
|
+
export declare function triageProposalMessage(proposed: string, proposedPath: string, queuePath: string): string | null;
|
|
264
|
+
export declare function cmdTriageAccept(opts: {
|
|
265
|
+
force?: boolean;
|
|
266
|
+
}): Promise<void>;
|
|
267
|
+
export declare function cmdQueueMigrate(opts?: {
|
|
268
|
+
file?: string;
|
|
269
|
+
dryRun?: boolean;
|
|
270
|
+
}): Promise<void>;
|
|
271
|
+
export declare function cmdUnpark(issueArg: string, opts?: {
|
|
272
|
+
lane?: string;
|
|
273
|
+
json?: boolean;
|
|
274
|
+
}): Promise<void>;
|
|
275
|
+
export declare function cmdQueueAdd(lane: string, issueArgs: string[], opts?: {
|
|
276
|
+
json?: boolean;
|
|
277
|
+
}): Promise<void>;
|
|
278
|
+
export declare function cmdQueueReconcile(opts?: {
|
|
279
|
+
lane?: string;
|
|
280
|
+
}): Promise<void>;
|
|
281
|
+
export declare function cmdQueueList(opts?: {
|
|
282
|
+
json?: boolean;
|
|
283
|
+
lane?: string;
|
|
284
|
+
}): Promise<void>;
|
|
285
|
+
export declare function cmdRuns(opts?: {
|
|
286
|
+
json?: boolean;
|
|
287
|
+
limit?: string;
|
|
288
|
+
diffstat?: string;
|
|
289
|
+
}): Promise<void>;
|
|
290
|
+
export declare function cmdQueueClear(opts?: {
|
|
291
|
+
dryRun?: boolean;
|
|
292
|
+
yes?: boolean;
|
|
293
|
+
lane?: string;
|
|
294
|
+
}): Promise<void>;
|
|
295
|
+
export declare function triageNoProposalError(plannerError: unknown): CliExitError;
|
|
296
|
+
/** Starts the in-process lane proxy for `factory run`/`supervise` when
|
|
297
|
+
* `environment.proxy.enabled`. Never throws: a bind failure (EACCES on :80,
|
|
298
|
+
* EADDRINUSE, …) is logged as a single `environment_proxy_unavailable` event
|
|
299
|
+
* and lanes degrade to port-based URLs, exactly as if the proxy were disabled. */
|
|
300
|
+
export declare function startLaneProxy(paths: ReturnType<typeof getFactoryPaths>, settings: EnvironmentProxySettings, deps?: {
|
|
301
|
+
createProxy?: typeof createLaneProxy;
|
|
302
|
+
emitEvent?: typeof logEvent;
|
|
303
|
+
}): Promise<{
|
|
304
|
+
proxy?: LaneProxy;
|
|
305
|
+
}>;
|
|
306
|
+
/** Wraps cmdRun so an empty queue is a no-op (not a throw) while auto-ingest is enabled and watching. */
|
|
307
|
+
export declare function createSuperviseRunQueue(paths: ReturnType<typeof getFactoryPaths>, ingestCfg: IngestSettings, deps?: {
|
|
308
|
+
cmdRunFn?: () => Promise<void>;
|
|
309
|
+
readQueueFile?: () => string;
|
|
310
|
+
pendingCount?: () => Promise<number>;
|
|
311
|
+
emitEvent?: typeof logEvent;
|
|
312
|
+
}): () => Promise<void>;
|
|
313
|
+
/** Builds the per-cycle auto-ingest hook passed to superviseLoop; failures are logged, never thrown. */
|
|
314
|
+
export declare function createIngestHook(repoRoot: string, paths: ReturnType<typeof getFactoryPaths>, ingestCfg: IngestSettings, deps?: {
|
|
315
|
+
runAutoIngestFn?: typeof runAutoIngest;
|
|
316
|
+
emitEvent?: typeof logEvent;
|
|
317
|
+
branchPrefix?: string;
|
|
318
|
+
}): () => Promise<number>;
|
|
319
|
+
type RunLaneDeps = {
|
|
320
|
+
/** Lane circuit breaker (#1918): pause after this many consecutive parks with the same
|
|
321
|
+
* non-empty failure signature. 0 or absent = off; cmdRun wires the resolved
|
|
322
|
+
* budget.laneBreakerThreshold. */
|
|
323
|
+
laneBreakerThreshold?: number;
|
|
324
|
+
/** Posts the lane-paused comment on the tripping issue (#1919). Defaults to a no-op so
|
|
325
|
+
* injected-deps callers and tests are unaffected; cmdRun wires it to issues.createComment. */
|
|
326
|
+
commentIssue?: (issue: number, body: string) => Promise<void>;
|
|
327
|
+
ship?: (issue: number, opts: {
|
|
328
|
+
product?: string;
|
|
329
|
+
autoRework?: boolean;
|
|
330
|
+
interactive?: boolean;
|
|
331
|
+
approvePlan?: boolean;
|
|
332
|
+
}, ctx?: {
|
|
333
|
+
repoRoot: string;
|
|
334
|
+
ghRepo: string;
|
|
335
|
+
paths: ReturnType<typeof getFactoryPaths>;
|
|
336
|
+
lane?: string;
|
|
337
|
+
onOutcome?: (outcome: RunOutcome) => void;
|
|
338
|
+
}) => Promise<string>;
|
|
339
|
+
waitMerge?: typeof waitForMerge;
|
|
340
|
+
pathExists?: (path: string) => boolean;
|
|
341
|
+
emitEvent?: typeof logEvent;
|
|
342
|
+
claimNext?: () => Promise<QueueClaim | null>;
|
|
343
|
+
releaseIssue?: (issue: number, outcome: QueueReleaseOutcome) => Promise<void>;
|
|
344
|
+
/** Refreshes the claim lease every HEARTBEAT_INTERVAL_MS while an issue is in flight
|
|
345
|
+
* (#1500). Absent for static local-queue lanes, which carry no remote claim to lease. */
|
|
346
|
+
heartbeat?: (issue: number) => Promise<unknown>;
|
|
347
|
+
/** Eager park-time worktree reap (#1007). Defaults to a no-op so injected-deps callers and
|
|
348
|
+
* tests are unaffected; cmdRun wires it to reapParkedLaneWorktree. */
|
|
349
|
+
reapWorktree?: (issue: number) => Promise<void>;
|
|
350
|
+
/** Between-issues worktree GC pass (#1757), run after every terminal outcome before the
|
|
351
|
+
* lane moves on. Defaults to a no-op so injected-deps callers and tests are unaffected;
|
|
352
|
+
* cmdRun wires it to sweepBetweenLaneIssues. */
|
|
353
|
+
sweepFinished?: (issue: number) => Promise<void>;
|
|
354
|
+
/** Number of issues still claimable on this lane's remote queue (#1222). Absent for
|
|
355
|
+
* static local lanes, whose pending list is the whole truth. */
|
|
356
|
+
countRemaining?: () => Promise<number>;
|
|
357
|
+
};
|
|
358
|
+
export interface PlannedLane {
|
|
359
|
+
lane: string;
|
|
360
|
+
/** Seed issues to work before claiming. Always empty in GitHub-queue mode. */
|
|
361
|
+
issues: number[];
|
|
362
|
+
deps: Pick<RunLaneDeps, 'claimNext' | 'releaseIssue' | 'heartbeat' | 'countRemaining'>;
|
|
363
|
+
}
|
|
364
|
+
export declare function laneQueueDeps(queue: GithubQueue, lane: string): Pick<RunLaneDeps, 'claimNext' | 'releaseIssue' | 'heartbeat' | 'countRemaining'>;
|
|
365
|
+
export interface OpenPullRequestEvidence {
|
|
366
|
+
number: number;
|
|
367
|
+
branch: string;
|
|
368
|
+
headSha: string;
|
|
369
|
+
headRepoFullName: string | null;
|
|
370
|
+
}
|
|
371
|
+
/** A slice PR's state as the queue preflight sees it (ADR-0147). */
|
|
372
|
+
export type SlicePullState = 'open' | 'merged' | 'closed';
|
|
373
|
+
export interface QueuePreflightOps {
|
|
374
|
+
expectedHeadRepoFullName: string;
|
|
375
|
+
findOpenPR(issue: number): Promise<OpenPullRequestEvidence | undefined>;
|
|
376
|
+
getLandState(prNumber: number): ReturnType<typeof getPullRequestLandState>;
|
|
377
|
+
watch(ref: string): Promise<CiOutcome>;
|
|
378
|
+
/** The factory-written slice plan comment on the issue (ADR-0147). */
|
|
379
|
+
findSlicePlan(issue: number): Promise<SlicePlanCommentLookup>;
|
|
380
|
+
/** State of a slice PR found by the number recorded in the slice plan. */
|
|
381
|
+
getPullState(prNumber: number): Promise<SlicePullState>;
|
|
382
|
+
/** Rewrite the factory's slice plan comment in place. */
|
|
383
|
+
saveSlicePlan(issue: number, plan: SlicePlan): Promise<void>;
|
|
384
|
+
}
|
|
385
|
+
export declare function createQueuePreflightOps(octokit: Octokit, owner: string, repo: string): QueuePreflightOps;
|
|
386
|
+
/** Resolve queued work from GitHub evidence without consuming model or worktree resources. */
|
|
387
|
+
export declare function preflightQueuedIssue(issue: QueueIssue, deps: QueuePreflightOps): Promise<QueuePreflightDecision>;
|
|
388
|
+
export declare function planRunLanes(input: {
|
|
389
|
+
localQueue: boolean;
|
|
390
|
+
/** `null` when `.factory/queue` does not exist. */
|
|
391
|
+
readLocalQueue: () => string | null;
|
|
392
|
+
/** Lazy so the octokit client is never built under --local-queue. */
|
|
393
|
+
queue: () => GithubQueue;
|
|
394
|
+
}): Promise<{
|
|
395
|
+
lanes: PlannedLane[];
|
|
396
|
+
diagnostics: QueueDiagnostic[];
|
|
397
|
+
}>;
|
|
398
|
+
export declare function renderLanePausedComment(payload: LanePausedPayload): string;
|
|
399
|
+
export declare function runLane(lane: string, issues: number[], repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, deps?: RunLaneDeps): Promise<void>;
|
|
400
|
+
export declare function isPrMerged(octokit: Octokit, owner: string, repoName: string, branch: string): Promise<boolean>;
|
|
401
|
+
export declare function findOpenPRNumber(octokit: Octokit, owner: string, repoName: string, branch: string): Promise<number | undefined>;
|
|
402
|
+
export declare function findOpenPRForIssue(octokit: Octokit, owner: string, repoName: string, issueNum: number): Promise<OpenPullRequestEvidence | undefined>;
|
|
403
|
+
export declare function squashMergeAndDelete(octokit: Octokit, owner: string, repoName: string, branch: string, prNumber: number,
|
|
404
|
+
/** `sha`: the CI-verified head commit. GitHub refuses the merge if the PR head has moved. */
|
|
405
|
+
opts?: {
|
|
406
|
+
admin?: boolean;
|
|
407
|
+
run?: CommandRunner;
|
|
408
|
+
sha?: string;
|
|
409
|
+
}): Promise<void>;
|
|
410
|
+
export declare class MergeGatedError extends Error {
|
|
411
|
+
readonly issue: number;
|
|
412
|
+
readonly prNumber: number;
|
|
413
|
+
readonly label: string;
|
|
414
|
+
constructor(message: string, issue: number, prNumber: number, label: string);
|
|
415
|
+
}
|
|
416
|
+
export declare class LandConflictError extends Error {
|
|
417
|
+
readonly parkReason: ParkReason;
|
|
418
|
+
}
|
|
419
|
+
/** The target issue was already resolved before the run started — a clean skip,
|
|
420
|
+
* not a park. Callers advance to the next queue entry. (#681) */
|
|
421
|
+
export declare class IssueSkippedError extends Error {
|
|
422
|
+
readonly reason: 'already-closed';
|
|
423
|
+
constructor(message: string, reason: 'already-closed');
|
|
424
|
+
}
|
|
425
|
+
export declare class AwaitingReviewError extends Error {
|
|
426
|
+
readonly prNumber: number;
|
|
427
|
+
constructor(message: string, prNumber: number);
|
|
428
|
+
}
|
|
429
|
+
/** The target issue tripped the PLAN pre-flight size gate and was decomposed into real
|
|
430
|
+
* filed sub-issues; the queue was rewritten. Not a park — the lane continues with the
|
|
431
|
+
* children in place of the oversized issue. (#823) */
|
|
432
|
+
export declare class IssueDecomposedError extends Error {
|
|
433
|
+
readonly childIssues: number[];
|
|
434
|
+
constructor(message: string, childIssues: number[]);
|
|
435
|
+
}
|
|
436
|
+
export declare class LandFailureError extends Error {
|
|
437
|
+
readonly code: number;
|
|
438
|
+
constructor(message: string, code: number);
|
|
439
|
+
}
|
|
440
|
+
/** Thrown when watchChecks reports a confirmed CI failure — a completed check run with a
|
|
441
|
+
* non-passing conclusion. A confirmed failing check must never be merged, admin override
|
|
442
|
+
* or not. See CiUnverifiedError for the no-verdict case. */
|
|
443
|
+
export declare class CiFailedError extends Error {
|
|
444
|
+
readonly prNumber: number;
|
|
445
|
+
readonly parkReason: ParkReason;
|
|
446
|
+
constructor(message: string, prNumber: number);
|
|
447
|
+
}
|
|
448
|
+
/** Thrown when the CI watch never reached a green verdict — a deadline timeout, no check runs ever
|
|
449
|
+
* registering, or repeated API failures. A subclass of CiFailedError so every existing guard
|
|
450
|
+
* (parkReasonFor → 'ci-failed', worktree cleanup, cmdLand's exit-0 path) treats "we don't know"
|
|
451
|
+
* exactly like "we know it's red": never merge. */
|
|
452
|
+
export declare class CiUnverifiedError extends CiFailedError {
|
|
453
|
+
}
|
|
454
|
+
/** True when GitHub refused a SHA-pinned merge because the PR head moved past the verified
|
|
455
|
+
* commit (REST 409, or gh's "Head branch was modified"). Retrying as-is can never succeed. */
|
|
456
|
+
export declare function isHeadModifiedMergeError(err: unknown): boolean;
|
|
457
|
+
export declare function isReviewRequiredMergeError(err: unknown, state: {
|
|
458
|
+
mergeStateStatus?: string;
|
|
459
|
+
reviewDecision?: string;
|
|
460
|
+
}): boolean;
|
|
461
|
+
export declare function getPullRequestLandState(octokit: Octokit, owner: string, repoName: string, prNumber: number): Promise<{
|
|
462
|
+
id?: string;
|
|
463
|
+
isDraft?: boolean;
|
|
464
|
+
mergeStateStatus?: string;
|
|
465
|
+
reviewDecision?: string;
|
|
466
|
+
}>;
|
|
467
|
+
export declare function markPullRequestReady(octokit: Octokit, pullRequestId: string): Promise<void>;
|
|
468
|
+
export declare function rebaseDirtyPullRequest(opts: {
|
|
469
|
+
issue: number;
|
|
470
|
+
branch: string;
|
|
471
|
+
worktree: string;
|
|
472
|
+
prNumber: number;
|
|
473
|
+
log: (type: EventKind, msg: string) => void;
|
|
474
|
+
run?: CommandRunner;
|
|
475
|
+
pathExists?: (path: string) => boolean;
|
|
476
|
+
}): Promise<void>;
|
|
477
|
+
/** A critical section runner: the land path takes this instead of owning lock composition,
|
|
478
|
+
* so the locks can be scoped to git mutations and stubbed in tests (#645). */
|
|
479
|
+
export type LandLock = <T>(fn: () => Promise<T>) => Promise<T>;
|
|
480
|
+
export declare function landOpenPullRequest(opts: {
|
|
481
|
+
octokit: Octokit;
|
|
482
|
+
owner: string;
|
|
483
|
+
repoName: string;
|
|
484
|
+
ghRepo: string;
|
|
485
|
+
repoRoot: string;
|
|
486
|
+
issue: number;
|
|
487
|
+
branch: string;
|
|
488
|
+
worktree: string;
|
|
489
|
+
prNumber: number;
|
|
490
|
+
log: (type: EventKind, msg: string) => void;
|
|
491
|
+
run?: CommandRunner;
|
|
492
|
+
pathExists?: (path: string) => boolean;
|
|
493
|
+
sleep?: (ms: number) => Promise<void>;
|
|
494
|
+
skipCI?: boolean;
|
|
495
|
+
adminMerge?: boolean;
|
|
496
|
+
watch?: (opts: WatchChecksOptions) => Promise<CiOutcome>;
|
|
497
|
+
withLock?: LandLock;
|
|
498
|
+
/** Materializes an adopted branch only after its locked state re-read confirms it needs rebasing. */
|
|
499
|
+
ensureWorktree?: () => Promise<void>;
|
|
500
|
+
}): Promise<void>;
|
|
501
|
+
export declare function issueFromFactoryBranch(branch: string, prefix?: string): number | undefined;
|
|
502
|
+
export declare function listOpenFactoryPRs(octokit: Octokit, owner: string, repoName: string, branchPrefix?: string): Promise<Array<{
|
|
503
|
+
number: number;
|
|
504
|
+
branch: string;
|
|
505
|
+
reviewDecision?: string;
|
|
506
|
+
isDraft?: boolean;
|
|
507
|
+
}>>;
|
|
508
|
+
export interface SweepDeps {
|
|
509
|
+
createOctokit?: () => Octokit;
|
|
510
|
+
loadConfig?: (configPath: string) => FactoryConfig;
|
|
511
|
+
listPRs?: typeof listOpenFactoryPRs;
|
|
512
|
+
land?: typeof landIssue;
|
|
513
|
+
emitEvent?: typeof logEvent;
|
|
514
|
+
writeLine?: (line: string) => void;
|
|
515
|
+
}
|
|
516
|
+
export declare function sweepApprovedPRs(repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, deps?: SweepDeps, opts?: {
|
|
517
|
+
branchPrefix?: string;
|
|
518
|
+
}): Promise<{
|
|
519
|
+
landed: number[];
|
|
520
|
+
skipped: Array<{
|
|
521
|
+
pr: number;
|
|
522
|
+
branch: string;
|
|
523
|
+
reason: string;
|
|
524
|
+
}>;
|
|
525
|
+
failed: Array<{
|
|
526
|
+
pr: number;
|
|
527
|
+
issue: number;
|
|
528
|
+
reason: string;
|
|
529
|
+
}>;
|
|
530
|
+
}>;
|
|
531
|
+
export declare function cmdResumeApproved(opts?: {
|
|
532
|
+
branchPrefix?: string;
|
|
533
|
+
}): Promise<void>;
|
|
534
|
+
/** Consecutive merged-state check failures tolerated before waitForMerge parks the lane.
|
|
535
|
+
* At the shipped 120s poll that is ~20 minutes of 100% failure (ADR: sustained-failure park). */
|
|
536
|
+
export declare const MERGE_CHECK_MAX_CONSECUTIVE_FAILURES = 10;
|
|
537
|
+
/** Wall-clock backstop: continuous merged-state check failure for this long parks the lane even
|
|
538
|
+
* if fewer than MERGE_CHECK_MAX_CONSECUTIVE_FAILURES attempts were made (slower poll cadence). */
|
|
539
|
+
export declare const MERGE_CHECK_FAILURE_BUDGET_MS: number;
|
|
540
|
+
/** True when a merged-state check failure cannot recover by retrying: an expired/revoked token
|
|
541
|
+
* (401) or a token missing `pulls:read` (403 with no rate-limit evidence). */
|
|
542
|
+
export declare function isPermanentMergeCheckError(err: unknown): boolean;
|
|
543
|
+
type WaitForMergeDeps = {
|
|
544
|
+
createOctokit?: () => Octokit;
|
|
545
|
+
pathExists?: (path: string) => boolean;
|
|
546
|
+
checkMerged?: typeof isPrMerged;
|
|
547
|
+
loadConfig?: (configPath: string) => FactoryConfig;
|
|
548
|
+
land?: (issueNum: number, repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, octokit: Octokit) => Promise<{
|
|
549
|
+
branch: string;
|
|
550
|
+
prNumber: number;
|
|
551
|
+
}>;
|
|
552
|
+
listIssueLabels?: (octokit: Octokit, owner: string, repo: string, issue: number) => Promise<string[]>;
|
|
553
|
+
sleep?: (ms: number) => Promise<void>;
|
|
554
|
+
emitEvent?: typeof logEvent;
|
|
555
|
+
mergeEnabled?: () => boolean;
|
|
556
|
+
writeLine?: (line: string) => void;
|
|
557
|
+
/** Injectable clock so the wall-clock failure budget is testable. Default `() => Date.now()`. */
|
|
558
|
+
now?: () => number;
|
|
559
|
+
/** Per-invocation CLI flag overrides (`--auto-merge`/`--no-auto-merge`). Threaded in by
|
|
560
|
+
* cmdRun rather than read from disk so a live run's merge gate cannot change underneath
|
|
561
|
+
* it (#1400). */
|
|
562
|
+
mergeOverrides?: MergePolicyOverrides;
|
|
563
|
+
};
|
|
564
|
+
export declare function waitForMerge(issue: number, branch: string, repoRoot: string, ghRepo: string, paths: ReturnType<typeof getFactoryPaths>, deps?: WaitForMergeDeps): Promise<void>;
|
|
565
|
+
export interface SuperviseDeps {
|
|
566
|
+
cap: number;
|
|
567
|
+
resumeAt: number;
|
|
568
|
+
pollMs: number;
|
|
569
|
+
watch?: boolean;
|
|
570
|
+
/** Where `watch` was decided, so the loop can attribute an explicit operator override
|
|
571
|
+
* to the flag rather than always blaming FACTORY_USAGE_WATCH (#1404). */
|
|
572
|
+
watchSource?: WatchdogPolicySource;
|
|
573
|
+
/** Where the resume threshold was decided, for attribution of explicit CLI overrides. */
|
|
574
|
+
resumeAtSource?: WatchdogPolicySource;
|
|
575
|
+
/** Where the poll interval was decided, for attribution of explicit CLI overrides. */
|
|
576
|
+
pollSource?: WatchdogPolicySource;
|
|
577
|
+
estimator?: boolean;
|
|
578
|
+
stopFile: string;
|
|
579
|
+
eventsFile: string;
|
|
580
|
+
now?: boolean;
|
|
581
|
+
runQueue: () => Promise<void>;
|
|
582
|
+
readUsageFn?: () => Promise<UsageReading | null>;
|
|
583
|
+
pathExists?: (path: string) => boolean;
|
|
584
|
+
clearStop?: (path: string) => void;
|
|
585
|
+
sleep?: (ms: number) => Promise<void>;
|
|
586
|
+
emitEvent?: typeof logEvent;
|
|
587
|
+
writeLine?: (line: string) => void;
|
|
588
|
+
/** When set, run once per cycle before draining the queue; returns count appended. Its presence
|
|
589
|
+
* also switches the loop into perpetual-poll mode (see superviseLoop). */
|
|
590
|
+
ingest?: () => Promise<number>;
|
|
591
|
+
}
|
|
592
|
+
export declare function superviseLoop(deps: SuperviseDeps): Promise<void>;
|
|
593
|
+
export declare function getCliVersion(): string;
|
|
594
|
+
/** Injectable seams for main(). Unset fields fall back to the real implementations. */
|
|
595
|
+
export interface CliDeps {
|
|
596
|
+
/** Shell seams for every `exec` / `execSync` the CLI runs (git, gh, claude, ollama, security). Default to node:child_process. */
|
|
597
|
+
exec?: ShellExec;
|
|
598
|
+
execSync?: ShellExecSync;
|
|
599
|
+
/** Passed to the `factory daemon start|stop|status|logs` wrappers. */
|
|
600
|
+
daemon?: DaemonCtlDeps;
|
|
601
|
+
/** Replaces the TUI entry point used by `factory tui`. */
|
|
602
|
+
runTui?: typeof runTui;
|
|
603
|
+
/** Builds the GitHub client for every CLI GitHub call (shipIssue, land, queue, triage, …). Defaults to createFactoryOctokit with the resolved token. */
|
|
604
|
+
octokit?: () => Octokit;
|
|
605
|
+
/** Phase overrides forwarded into RunPorts by shipIssue, including calls made from main(). Each defaults to the factory-core phase. */
|
|
606
|
+
planPhase?: RunPorts['planPhase'];
|
|
607
|
+
buildPhase?: RunPorts['buildPhase'];
|
|
608
|
+
checkPhase?: RunPorts['checkPhase'];
|
|
609
|
+
shipPhase?: RunPorts['shipPhase'];
|
|
610
|
+
/** Config loaders and resolvers. Each defaults to the factory-core export of the same name. */
|
|
611
|
+
loadModelsConfig?: typeof loadModelsConfig;
|
|
612
|
+
loadRoutesConfig?: typeof loadRoutesConfig;
|
|
613
|
+
loadFactoryConfigForRepo?: typeof loadFactoryConfigForRepo;
|
|
614
|
+
loadRepoConfig?: typeof loadRepoConfig;
|
|
615
|
+
resolveTimeouts?: typeof resolveTimeouts;
|
|
616
|
+
resolveSkipCI?: typeof resolveSkipCI;
|
|
617
|
+
getConstitutionsDir?: typeof getConstitutionsDir;
|
|
618
|
+
resolveEffectiveModelPins?: typeof resolveEffectiveModelPins;
|
|
619
|
+
/** Git worktree/fetch side effects. Each defaults to the factory-core export of the same name. */
|
|
620
|
+
setupWorktree?: typeof setupWorktree;
|
|
621
|
+
cleanupWorktree?: typeof cleanupWorktree;
|
|
622
|
+
gitFetch?: typeof gitFetch;
|
|
623
|
+
/** factory-core/internal ops (CI watch, costs, worktree GC, reconcile reaps, local-small). Each defaults to the export of the same name. */
|
|
624
|
+
watchChecks?: typeof watchChecks;
|
|
625
|
+
createLocalSmallDryRun?: typeof createLocalSmallDryRun;
|
|
626
|
+
readCosts?: typeof readCosts;
|
|
627
|
+
sweepWorktrees?: typeof sweepWorktrees;
|
|
628
|
+
releaseStaleClaims?: typeof releaseStaleClaims;
|
|
629
|
+
findUnmergedGreenPrs?: typeof findUnmergedGreenPrs;
|
|
630
|
+
listOrphanContainers?: typeof listOrphanContainers;
|
|
631
|
+
reapOrphanContainers?: typeof reapOrphanContainers;
|
|
632
|
+
listMicroVms?: typeof listMicroVms;
|
|
633
|
+
reapOrphanMicroVm?: typeof reapOrphanMicroVm;
|
|
634
|
+
formatGcReport?: typeof formatGcReport;
|
|
635
|
+
/** factory-core classes and ops (routing, constitutions, process/port probes, usage, diagnose, local report). Each defaults to the export of the same name. */
|
|
636
|
+
ModelRouter?: typeof ModelRouter;
|
|
637
|
+
ConstitutionLoader?: typeof ConstitutionLoader;
|
|
638
|
+
ModelRegistry?: typeof ModelRegistry;
|
|
639
|
+
isCommandAvailable?: typeof isCommandAvailable;
|
|
640
|
+
defaultFindPortListeners?: typeof defaultFindPortListeners;
|
|
641
|
+
reapOrphanProcesses?: typeof reapOrphanProcesses;
|
|
642
|
+
estimateTrailingSpend?: typeof estimateTrailingSpend;
|
|
643
|
+
formatUsageReport?: typeof formatUsageReport;
|
|
644
|
+
watchUsage?: typeof watchUsage;
|
|
645
|
+
fetchSubscriptionUsage?: typeof fetchSubscriptionUsage;
|
|
646
|
+
diagnoseModels?: typeof diagnoseModels;
|
|
647
|
+
writeLocalRunReport?: typeof writeLocalRunReport;
|
|
648
|
+
}
|
|
649
|
+
export declare function cmdStop(opts?: {
|
|
650
|
+
json?: boolean;
|
|
651
|
+
}): Promise<void>;
|
|
652
|
+
export declare function cmdResume(opts?: {
|
|
653
|
+
json?: boolean;
|
|
654
|
+
}): Promise<void>;
|
|
655
|
+
export declare function main(argv?: string[], deps?: CliDeps): Promise<void>;
|
|
656
|
+
//# sourceMappingURL=index.d.ts.map
|