@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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -2
  3. package/dist/cli/admission.d.ts +17 -0
  4. package/dist/cli/admission.d.ts.map +1 -0
  5. package/dist/cli/admission.js +37 -0
  6. package/dist/cli/admission.js.map +1 -0
  7. package/dist/cli/branch-prefix.d.ts +8 -0
  8. package/dist/cli/branch-prefix.d.ts.map +1 -0
  9. package/dist/cli/branch-prefix.js +16 -0
  10. package/dist/cli/branch-prefix.js.map +1 -0
  11. package/dist/cli/classifier-backtest.d.ts +50 -0
  12. package/dist/cli/classifier-backtest.d.ts.map +1 -0
  13. package/dist/cli/classifier-backtest.js +112 -0
  14. package/dist/cli/classifier-backtest.js.map +1 -0
  15. package/dist/cli/cost-json.d.ts +37 -0
  16. package/dist/cli/cost-json.d.ts.map +1 -0
  17. package/dist/cli/cost-json.js +48 -0
  18. package/dist/cli/cost-json.js.map +1 -0
  19. package/dist/cli/daemon.d.ts +113 -0
  20. package/dist/cli/daemon.d.ts.map +1 -0
  21. package/dist/cli/daemon.js +282 -0
  22. package/dist/cli/daemon.js.map +1 -0
  23. package/dist/cli/doctor.d.ts +127 -0
  24. package/dist/cli/doctor.d.ts.map +1 -0
  25. package/dist/cli/doctor.js +400 -0
  26. package/dist/cli/doctor.js.map +1 -0
  27. package/dist/cli/feedback.d.ts +74 -0
  28. package/dist/cli/feedback.d.ts.map +1 -0
  29. package/dist/cli/feedback.js +180 -0
  30. package/dist/cli/feedback.js.map +1 -0
  31. package/dist/cli/filing.d.ts +22 -0
  32. package/dist/cli/filing.d.ts.map +1 -0
  33. package/dist/cli/filing.js +53 -0
  34. package/dist/cli/filing.js.map +1 -0
  35. package/dist/cli/first-run.d.ts +9 -0
  36. package/dist/cli/first-run.d.ts.map +1 -0
  37. package/dist/cli/first-run.js +34 -0
  38. package/dist/cli/first-run.js.map +1 -0
  39. package/dist/cli/help-groups.d.ts +17 -0
  40. package/dist/cli/help-groups.d.ts.map +1 -0
  41. package/dist/cli/help-groups.js +50 -0
  42. package/dist/cli/help-groups.js.map +1 -0
  43. package/dist/cli/hosted-queue.d.ts +45 -0
  44. package/dist/cli/hosted-queue.d.ts.map +1 -0
  45. package/dist/cli/hosted-queue.js +74 -0
  46. package/dist/cli/hosted-queue.js.map +1 -0
  47. package/dist/cli/hosted-runner.d.ts +44 -0
  48. package/dist/cli/hosted-runner.d.ts.map +1 -0
  49. package/dist/cli/hosted-runner.js +68 -0
  50. package/dist/cli/hosted-runner.js.map +1 -0
  51. package/dist/cli/hosted.d.ts +38 -0
  52. package/dist/cli/hosted.d.ts.map +1 -0
  53. package/dist/cli/hosted.js +82 -0
  54. package/dist/cli/hosted.js.map +1 -0
  55. package/dist/cli/index.d.ts +656 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +4801 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/init-files.d.ts +8 -0
  60. package/dist/cli/init-files.d.ts.map +1 -0
  61. package/dist/cli/init-files.js +45 -0
  62. package/dist/cli/init-files.js.map +1 -0
  63. package/dist/cli/logs.d.ts +27 -0
  64. package/dist/cli/logs.d.ts.map +1 -0
  65. package/dist/cli/logs.js +52 -0
  66. package/dist/cli/logs.js.map +1 -0
  67. package/dist/cli/merge-scope.d.ts +7 -0
  68. package/dist/cli/merge-scope.d.ts.map +1 -0
  69. package/dist/cli/merge-scope.js +14 -0
  70. package/dist/cli/merge-scope.js.map +1 -0
  71. package/dist/cli/octokit.d.ts +43 -0
  72. package/dist/cli/octokit.d.ts.map +1 -0
  73. package/dist/cli/octokit.js +87 -0
  74. package/dist/cli/octokit.js.map +1 -0
  75. package/dist/cli/queue-add-json.d.ts +25 -0
  76. package/dist/cli/queue-add-json.d.ts.map +1 -0
  77. package/dist/cli/queue-add-json.js +24 -0
  78. package/dist/cli/queue-add-json.js.map +1 -0
  79. package/dist/cli/queue-clear.d.ts +15 -0
  80. package/dist/cli/queue-clear.d.ts.map +1 -0
  81. package/dist/cli/queue-clear.js +58 -0
  82. package/dist/cli/queue-clear.js.map +1 -0
  83. package/dist/cli/queue-list.d.ts +24 -0
  84. package/dist/cli/queue-list.d.ts.map +1 -0
  85. package/dist/cli/queue-list.js +25 -0
  86. package/dist/cli/queue-list.js.map +1 -0
  87. package/dist/cli/ready-check.d.ts +98 -0
  88. package/dist/cli/ready-check.d.ts.map +1 -0
  89. package/dist/cli/ready-check.js +169 -0
  90. package/dist/cli/ready-check.js.map +1 -0
  91. package/dist/cli/reset.d.ts +40 -0
  92. package/dist/cli/reset.d.ts.map +1 -0
  93. package/dist/cli/reset.js +215 -0
  94. package/dist/cli/reset.js.map +1 -0
  95. package/dist/cli/run-children.d.ts +24 -0
  96. package/dist/cli/run-children.d.ts.map +1 -0
  97. package/dist/cli/run-children.js +73 -0
  98. package/dist/cli/run-children.js.map +1 -0
  99. package/dist/cli/run-flags.d.ts +14 -0
  100. package/dist/cli/run-flags.d.ts.map +1 -0
  101. package/dist/cli/run-flags.js +43 -0
  102. package/dist/cli/run-flags.js.map +1 -0
  103. package/dist/cli/runs-diffstat.d.ts +43 -0
  104. package/dist/cli/runs-diffstat.d.ts.map +1 -0
  105. package/dist/cli/runs-diffstat.js +91 -0
  106. package/dist/cli/runs-diffstat.js.map +1 -0
  107. package/dist/cli/runs.d.ts +36 -0
  108. package/dist/cli/runs.d.ts.map +1 -0
  109. package/dist/cli/runs.js +102 -0
  110. package/dist/cli/runs.js.map +1 -0
  111. package/dist/cli/staleness.d.ts +30 -0
  112. package/dist/cli/staleness.d.ts.map +1 -0
  113. package/dist/cli/staleness.js +132 -0
  114. package/dist/cli/staleness.js.map +1 -0
  115. package/dist/cli/status-json.d.ts +45 -0
  116. package/dist/cli/status-json.d.ts.map +1 -0
  117. package/dist/cli/status-json.js +22 -0
  118. package/dist/cli/status-json.js.map +1 -0
  119. package/dist/cli/stop-resume-json.d.ts +18 -0
  120. package/dist/cli/stop-resume-json.d.ts.map +1 -0
  121. package/dist/cli/stop-resume-json.js +10 -0
  122. package/dist/cli/stop-resume-json.js.map +1 -0
  123. package/dist/cli/stop-sentinel.d.ts +23 -0
  124. package/dist/cli/stop-sentinel.d.ts.map +1 -0
  125. package/dist/cli/stop-sentinel.js +61 -0
  126. package/dist/cli/stop-sentinel.js.map +1 -0
  127. package/dist/cli/sweep-heartbeat.d.ts +33 -0
  128. package/dist/cli/sweep-heartbeat.d.ts.map +1 -0
  129. package/dist/cli/sweep-heartbeat.js +65 -0
  130. package/dist/cli/sweep-heartbeat.js.map +1 -0
  131. package/dist/cli/unpark.d.ts +28 -0
  132. package/dist/cli/unpark.d.ts.map +1 -0
  133. package/dist/cli/unpark.js +68 -0
  134. package/dist/cli/unpark.js.map +1 -0
  135. package/dist/cli/usage-json.d.ts +20 -0
  136. package/dist/cli/usage-json.d.ts.map +1 -0
  137. package/dist/cli/usage-json.js +36 -0
  138. package/dist/cli/usage-json.js.map +1 -0
  139. package/dist/cli.d.ts +3 -0
  140. package/dist/cli.d.ts.map +1 -0
  141. package/dist/cli.js +6 -0
  142. package/dist/cli.js.map +1 -0
  143. package/dist/entry.d.ts +6 -0
  144. package/dist/entry.d.ts.map +1 -0
  145. package/dist/entry.js +13 -0
  146. package/dist/entry.js.map +1 -0
  147. package/package.json +48 -4
@@ -0,0 +1,180 @@
1
+ // packages/cli/src/cli/feedback.ts — `factory feedback <pr-url>`: file a human review's findings as one factory issue (#1851).
2
+ // Each review body is sanitized on its own (stripHiddenContent) before it reaches the title or body (#1852).
3
+ import { createHash } from 'node:crypto';
4
+ import { hostname } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { readEvents } from '@on-par/factory-core';
7
+ import { DEFAULT_BUG_LABELS, factoryBranchIssue, fileBug, stripHiddenContent } from '@on-par/factory-core/internal';
8
+ export const FEEDBACK_TRIAGE_LABEL = 'factory:needs-triage';
9
+ export const FEEDBACK_LABELS = [...DEFAULT_BUG_LABELS, FEEDBACK_TRIAGE_LABEL];
10
+ const PR_URL_RE = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+)\/pull\/(\d+)(?:[/?#].*)?$/;
11
+ export function parseFeedbackPrUrl(raw) {
12
+ const m = PR_URL_RE.exec(raw.trim());
13
+ if (!m)
14
+ throw new Error(`factory feedback: "${raw}" is not a GitHub pull request URL`);
15
+ const [, owner, repo, num] = m;
16
+ const number = Number(num);
17
+ return { owner, repo, number, url: `https://github.com/${owner}/${repo}/pull/${number}` };
18
+ }
19
+ export async function collectReviewFindings(client, pr) {
20
+ const [reviews, comments] = await Promise.all([client.listReviews(pr), client.listReviewComments(pr)]);
21
+ const findings = [];
22
+ for (const r of reviews) {
23
+ const body = stripHiddenContent(r.body ?? '').trim();
24
+ if (!body)
25
+ continue;
26
+ findings.push({
27
+ author: stripHiddenContent(r.user),
28
+ kind: 'review',
29
+ body,
30
+ at: r.submittedAt,
31
+ state: r.state,
32
+ url: r.url,
33
+ });
34
+ }
35
+ for (const c of comments) {
36
+ const body = stripHiddenContent(c.body ?? '').trim();
37
+ if (!body)
38
+ continue;
39
+ findings.push({
40
+ author: stripHiddenContent(c.user),
41
+ kind: 'comment',
42
+ body,
43
+ at: c.createdAt,
44
+ path: c.path === undefined ? undefined : stripHiddenContent(c.path),
45
+ line: c.line,
46
+ url: c.url,
47
+ });
48
+ }
49
+ return findings.sort((a, b) => (a.at < b.at ? -1 : a.at > b.at ? 1 : 0));
50
+ }
51
+ const TITLE_MAX = 80;
52
+ export function buildFeedbackTitle(findings, note) {
53
+ const trimmedNote = note?.trim();
54
+ if (trimmedNote)
55
+ return `[feedback] ${trimmedNote}`;
56
+ const first = findings[0];
57
+ if (!first)
58
+ throw new Error('factory feedback: the PR has no review findings; pass --note to describe the problem');
59
+ const rawLine = first.body.split('\n').find((l) => l.trim()) ?? '';
60
+ const line = rawLine.replace(/\s+/g, ' ').trim();
61
+ const cut = line.length > TITLE_MAX ? `${line.slice(0, TITLE_MAX)}…` : line;
62
+ return `[feedback] ${cut}`;
63
+ }
64
+ function renderFindings(findings) {
65
+ return findings
66
+ .map((f) => {
67
+ const where = f.kind === 'review' ? (f.state ?? 'review') : `${f.path ?? 'unknown'}${f.line ? `:${f.line}` : ''}`;
68
+ return `### ${f.author} — ${where} (${f.at})\n${f.body}\n`;
69
+ })
70
+ .join('\n');
71
+ }
72
+ function runWindow(events, issue, slug) {
73
+ const mine = events.filter((e) => e.issue === String(issue) && (e.repo === undefined || e.repo === slug));
74
+ if (mine.length === 0)
75
+ return { count: 0 };
76
+ const stamps = mine.map((e) => e.ts).sort();
77
+ return { first: stamps[0], last: stamps[stamps.length - 1], count: mine.length };
78
+ }
79
+ export async function runFeedback(prUrl, opts, deps) {
80
+ const pr = parseFeedbackPrUrl(prUrl);
81
+ const pull = await deps.github.getPull(pr);
82
+ const findings = await collectReviewFindings(deps.github, pr);
83
+ const title = buildFeedbackTitle(findings, opts.note);
84
+ const issue = factoryBranchIssue(pull.headRef, deps.branchPrefix);
85
+ const window = issue === null ? undefined : runWindow(readEvents(deps.paths.events), issue, `${pr.owner}/${pr.repo}`);
86
+ const designPath = issue === null ? undefined : join(deps.paths.plans, `issue-${issue}.md`);
87
+ const logPath = issue === null ? deps.paths.logs : join(deps.paths.logs, String(issue));
88
+ const host = deps.host ?? hostname();
89
+ const lines = [
90
+ `Human review of ${pr.url} found factory defects the run did not catch.`,
91
+ '',
92
+ `- PR: ${pr.url} (${pull.title})`,
93
+ `- Factory issue: ${issue === null ? `not a factory branch (${pull.headRef})` : `#${issue}`}`,
94
+ `- Run events: ${window?.count
95
+ ? `${window.count} between ${window.first} and ${window.last}`
96
+ : `none found in ${deps.paths.events}`}`,
97
+ `- Design artifact: ${designPath ? `${host}:${designPath}` : 'unknown'}`,
98
+ `- Findings: ${findings.length}`,
99
+ ];
100
+ const note = opts.note?.trim();
101
+ if (note)
102
+ lines.push(`- Note: ${note}`);
103
+ const fingerprint = `fb_${createHash('sha256')
104
+ .update(`${pr.url}|${deps.now().toISOString()}`)
105
+ .digest('hex')
106
+ .slice(0, 16)}`;
107
+ const fingerprinted = {
108
+ fingerprint,
109
+ evidence: {
110
+ repo: `${pr.owner}/${pr.repo}`,
111
+ issue: issue === null ? pr.url : String(issue),
112
+ phase: 'check',
113
+ model: 'human-review',
114
+ reason: 'unknown',
115
+ component: 'human-review',
116
+ origin: 'factory-internal',
117
+ eventExcerpt: renderFindings(findings) || '(no review findings; see note)',
118
+ logPath,
119
+ },
120
+ };
121
+ return fileBug(deps.filing, {
122
+ fingerprinted,
123
+ now: deps.now,
124
+ labels: FEEDBACK_LABELS,
125
+ title,
126
+ problem: lines.join('\n'),
127
+ host: deps.host,
128
+ internalRepo: deps.internalRepo,
129
+ });
130
+ }
131
+ export function createOctokitFeedbackClient(octokit) {
132
+ return {
133
+ async getPull({ owner, repo, number }) {
134
+ const { data } = await octokit.rest.pulls.get({ owner, repo, pull_number: number });
135
+ return { headRef: data.head.ref, title: data.title, url: data.html_url };
136
+ },
137
+ async listReviews({ owner, repo, number }) {
138
+ const data = await octokit.paginate(octokit.rest.pulls.listReviews, {
139
+ owner,
140
+ repo,
141
+ pull_number: number,
142
+ per_page: 100,
143
+ });
144
+ return data.map((r) => ({
145
+ user: r.user?.login ?? 'unknown',
146
+ state: r.state,
147
+ body: r.body ?? '',
148
+ submittedAt: r.submitted_at ?? '',
149
+ url: r.html_url,
150
+ }));
151
+ },
152
+ async listReviewComments({ owner, repo, number }) {
153
+ const data = await octokit.paginate(octokit.rest.pulls.listReviewComments, {
154
+ owner,
155
+ repo,
156
+ pull_number: number,
157
+ per_page: 100,
158
+ });
159
+ return data.map((c) => ({
160
+ user: c.user?.login ?? 'unknown',
161
+ body: c.body ?? '',
162
+ path: c.path,
163
+ line: c.line ?? c.original_line ?? undefined,
164
+ createdAt: c.created_at,
165
+ url: c.html_url,
166
+ }));
167
+ },
168
+ };
169
+ }
170
+ /** Wire the real GitHub clients and run-state paths into FeedbackDeps. */
171
+ export function buildFeedbackDeps(octokit, paths, branchPrefix, createFilingClient) {
172
+ return {
173
+ github: createOctokitFeedbackClient(octokit),
174
+ filing: createFilingClient(octokit),
175
+ paths: { events: paths.events, plans: paths.plans, logs: paths.logs },
176
+ branchPrefix,
177
+ now: () => new Date(),
178
+ };
179
+ }
180
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/cli/feedback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface FilingPreviewDeps {
2
+ out: {
3
+ write(s: string): unknown;
4
+ };
5
+ err: {
6
+ write(s: string): unknown;
7
+ };
8
+ eventsFile: string;
9
+ runsDir: string;
10
+ factoryVersion: string;
11
+ factoryCommit: () => Promise<string | null>;
12
+ os: string;
13
+ nodeVersion: string;
14
+ usernames: string[];
15
+ hostnames: string[];
16
+ branchPrefix?: string;
17
+ }
18
+ /** Print the exact title and body an upstream report would carry. Returns false when no evidence matches. */
19
+ export declare function runFilingPreview(runId: string, deps: FilingPreviewDeps): Promise<boolean>;
20
+ /** Sha of the factory checkout `cwd` sits in; null when installed or not a factory checkout (never the target repo's). */
21
+ export declare function resolveFactoryCheckoutCommit(cwd: string, run: (cmd: string, cwd: string) => Promise<string>): Promise<string | null>;
22
+ //# sourceMappingURL=filing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filing.d.ts","sourceRoot":"","sources":["../../src/cli/filing.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACnC,GAAG,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAQD,6GAA6G;AAC7G,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiC/F;AAED,0HAA0H;AAC1H,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACjD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB"}
@@ -0,0 +1,53 @@
1
+ // packages/cli/src/cli/filing.ts — `factory filing preview <run-id>`: print the redacted upstream report, send nothing (#1858).
2
+ import { readFileSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ import { readEvents } from '@on-par/factory-core';
5
+ import { buildUpstreamReport, daemonRunFile, isValidRunId, readDaemonRun, upstreamInputFromEvidence, } from '@on-par/factory-core/internal';
6
+ function hasEvidence(e) {
7
+ return typeof e.fingerprint === 'string' && e.evidence !== undefined;
8
+ }
9
+ /** Print the exact title and body an upstream report would carry. Returns false when no evidence matches. */
10
+ export async function runFilingPreview(runId, deps) {
11
+ const events = readEvents(deps.eventsFile).filter(hasEvidence);
12
+ const record = isValidRunId(runId) ? await readDaemonRun(daemonRunFile(deps.runsDir, runId)) : null;
13
+ const matches = record
14
+ ? events.filter((e) => e.issue === String(record.issue) && (!e.repo || e.repo === record.repo))
15
+ : events.filter((e) => e.fingerprint === runId);
16
+ const match = matches[matches.length - 1];
17
+ if (!match) {
18
+ deps.err.write(`No failure evidence found for run ${runId}.\n`);
19
+ return false;
20
+ }
21
+ const repoSlugs = [record?.repo, match.repo].filter((s) => !!s);
22
+ const owners = repoSlugs.map((s) => s.split('/')[0]).filter((s) => !!s);
23
+ const input = upstreamInputFromEvidence({ fingerprint: match.fingerprint, evidence: match.evidence }, {
24
+ factoryVersion: deps.factoryVersion,
25
+ factoryCommit: await deps.factoryCommit(),
26
+ os: deps.os,
27
+ nodeVersion: deps.nodeVersion,
28
+ redaction: {
29
+ repoSlugs,
30
+ usernames: [...deps.usernames, ...owners],
31
+ hostnames: deps.hostnames,
32
+ branchPrefix: deps.branchPrefix,
33
+ },
34
+ });
35
+ const { title, body } = buildUpstreamReport(input);
36
+ deps.out.write(`${title}\n\n${body.replace(/\n+$/, '')}\n`);
37
+ deps.err.write('Preview only — nothing was sent.\n');
38
+ return true;
39
+ }
40
+ /** Sha of the factory checkout `cwd` sits in; null when installed or not a factory checkout (never the target repo's). */
41
+ export async function resolveFactoryCheckoutCommit(cwd, run) {
42
+ try {
43
+ const top = (await run('git rev-parse --show-toplevel', cwd)).trim();
44
+ const pkg = JSON.parse(readFileSync(resolve(top, 'packages/cli/package.json'), 'utf8'));
45
+ if (pkg.name !== '@on-par/factory-cli')
46
+ return null;
47
+ return (await run('git rev-parse HEAD', cwd)).trim() || null;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ //# sourceMappingURL=filing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filing.js","sourceRoot":"","sources":["../../src/cli/filing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare const DOCS_URL = "https://github.com/on-par/software-factory#readme";
2
+ export declare const CLAUDE_CODE_URL = "https://docs.anthropic.com/en/docs/claude-code";
3
+ export declare const GITHUB_TOKENS_URL = "https://github.com/settings/tokens";
4
+ /** Printed by bare `factory` (no subcommand). */
5
+ export declare function formatOverview(): string;
6
+ export declare function missingClaudeCliMessage(): string;
7
+ export declare function missingTokenMessage(): string;
8
+ export declare function notInitializedMessage(): string;
9
+ //# sourceMappingURL=first-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-run.d.ts","sourceRoot":"","sources":["../../src/cli/first-run.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,sDAAsD,CAAC;AAC5E,eAAO,MAAM,eAAe,mDAAmD,CAAC;AAChF,eAAO,MAAM,iBAAiB,uCAAuC,CAAC;AAEtE,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,MAAM,CAkBvC;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
@@ -0,0 +1,34 @@
1
+ // packages/cli/src/cli/first-run.ts — designed first-run copy: overview + structured error messages
2
+ export const DOCS_URL = 'https://github.com/on-par/software-factory#readme';
3
+ export const CLAUDE_CODE_URL = 'https://docs.anthropic.com/en/docs/claude-code';
4
+ export const GITHUB_TOKENS_URL = 'https://github.com/settings/tokens';
5
+ /** Printed by bare `factory` (no subcommand). */
6
+ export function formatOverview() {
7
+ return `factory — ship verified GitHub issues autonomously
8
+
9
+ The software factory takes issues from your backlog through a
10
+ plan → build → check → ship pipeline using a boss-worker-checker
11
+ pattern, and opens a pull request for each one.
12
+
13
+ Common commands:
14
+ factory init Initialize .factory/ in this repo
15
+ factory ship <issue> Plan → build → check one issue and open a PR
16
+ factory queue add <lane> <N...> Queue issues into a lane (GitHub labels)
17
+ factory run Ship queued issues, lanes in parallel
18
+ factory status Show active runs and the queue
19
+
20
+ Check your setup: factory doctor
21
+ All commands: factory --help
22
+ Docs: ${DOCS_URL}
23
+ `;
24
+ }
25
+ export function missingClaudeCliMessage() {
26
+ return `claude CLI not found — install Claude Code first: ${CLAUDE_CODE_URL}`;
27
+ }
28
+ export function missingTokenMessage() {
29
+ return `GITHUB_TOKEN not set — create a token at ${GITHUB_TOKENS_URL} and export it (or run \`gh auth login\`)`;
30
+ }
31
+ export function notInitializedMessage() {
32
+ return 'factory not initialized — run `factory init` first';
33
+ }
34
+ //# sourceMappingURL=first-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-run.js","sourceRoot":"","sources":["../../src/cli/first-run.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,MAAM,CAAC,MAAM,QAAQ,GAAG,mDAAmD,CAAC;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,gDAAgD,CAAC;AAChF,MAAM,CAAC,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAEtE,iDAAiD;AACjD,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;0BAeiB,QAAQ;CACjC,CAAC;AACF,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,qDAAqD,eAAe,EAAE,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,4CAA4C,iBAAiB,2CAA2C,CAAC;AAClH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,oDAAoD,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Command } from 'commander';
2
+ export interface HelpGroup {
3
+ heading: string;
4
+ /** Top-level command names, in the order they should appear under the heading. */
5
+ commands: readonly string[];
6
+ /** Put Commander's implicit `help [command]` entry under this heading. */
7
+ includesHelp?: boolean;
8
+ }
9
+ /** Heading for any registered command missing from the table, so a new command still shows up. */
10
+ export declare const OTHER_GROUP = "Other:";
11
+ /** The shipped `factory --help` layout: everyday commands first, experimental ones last. */
12
+ export declare const HELP_GROUPS: readonly HelpGroup[];
13
+ /** Assign each top-level command its help heading and reorder `program.commands` to match
14
+ * the table. Commander renders groups in order of first appearance, so the reorder is what
15
+ * puts "Run work:" first. Only help layout changes — command parsing ignores the order. */
16
+ export declare function applyHelpGroups(program: Command, groups?: readonly HelpGroup[]): void;
17
+ //# sourceMappingURL=help-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-groups.d.ts","sourceRoot":"","sources":["../../src/cli/help-groups.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,kGAAkG;AAClG,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,4FAA4F;AAC5F,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAgB3C,CAAC;AAEF;;4FAE4F;AAC5F,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,SAAS,SAAS,EAAgB,GAAG,IAAI,CAwBlG"}
@@ -0,0 +1,50 @@
1
+ // packages/cli/src/cli/help-groups.ts — section headings and order for `factory --help`
2
+ /** Heading for any registered command missing from the table, so a new command still shows up. */
3
+ export const OTHER_GROUP = 'Other:';
4
+ /** The shipped `factory --help` layout: everyday commands first, experimental ones last. */
5
+ export const HELP_GROUPS = [
6
+ {
7
+ heading: 'Run work:',
8
+ commands: ['ship', 'run-issue', 'run-brief', 'run', 'supervise', 'land', 'resume-approved', 'stop', 'resume'],
9
+ },
10
+ {
11
+ heading: 'Setup:',
12
+ commands: ['init', 'doctor', 'constitution', 'models', 'migrate'],
13
+ includesHelp: true,
14
+ },
15
+ { heading: 'Queue:', commands: ['queue', 'unpark', 'triage', 'check', 'feedback', 'filing'] },
16
+ { heading: 'Observe:', commands: ['status', 'runs', 'logs', 'tui', 'cost', 'usage', 'kpis', 'classifier', 'garden'] },
17
+ {
18
+ heading: 'Advanced / experimental:',
19
+ commands: ['worktree', 'reset', 'daemon', 'proxy', 'hosted', 'local-small-dry-run', 'local-small-overnight'],
20
+ },
21
+ ];
22
+ /** Assign each top-level command its help heading and reorder `program.commands` to match
23
+ * the table. Commander renders groups in order of first appearance, so the reorder is what
24
+ * puts "Run work:" first. Only help layout changes — command parsing ignores the order. */
25
+ export function applyHelpGroups(program, groups = HELP_GROUPS) {
26
+ const byName = new Map(program.commands.map((cmd) => [cmd.name(), cmd]));
27
+ const ordered = [];
28
+ for (const group of groups) {
29
+ for (const name of group.commands) {
30
+ const cmd = byName.get(name);
31
+ if (!cmd)
32
+ continue;
33
+ cmd.helpGroup(group.heading);
34
+ ordered.push(cmd);
35
+ byName.delete(name);
36
+ }
37
+ }
38
+ for (const cmd of byName.values()) {
39
+ cmd.helpGroup(OTHER_GROUP);
40
+ ordered.push(cmd);
41
+ }
42
+ // Commander types `commands` as readonly but keeps a plain array; reorder it in place.
43
+ program.commands.splice(0, program.commands.length, ...ordered);
44
+ const helpGroup = groups.find((g) => g.includesHelp);
45
+ if (helpGroup) {
46
+ program.commandsGroup(helpGroup.heading);
47
+ program.helpCommand(true);
48
+ }
49
+ }
50
+ //# sourceMappingURL=help-groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-groups.js","sourceRoot":"","sources":["../../src/cli/help-groups.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAYxF,kGAAkG;AAClG,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEpC,4FAA4F;AAC5F,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C;QACE,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC;KAC9G;IACD;QACE,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,CAAC;QACjE,YAAY,EAAE,IAAI;KACnB;IACD,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE;IAC7F,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;IACrH;QACE,OAAO,EAAE,0BAA0B;QACnC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,uBAAuB,CAAC;KAC7G;CACF,CAAC;AAEF;;4FAE4F;AAC5F,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,MAAM,GAAyB,WAAW;IAC1F,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IACD,uFAAuF;IACtF,OAAO,CAAC,QAAsB,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC;IAE/E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACrD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { HostedJobClient, QueueAndTailOutcome } from '@on-par/factory-core';
2
+ export interface HostedQueueCliOptions {
3
+ /** default 'http://127.0.0.1:8799' */
4
+ url?: string;
5
+ /** default 'on-par/software-factory' */
6
+ repo?: string;
7
+ /** opaque task payload; default 'hosted-exec: queue and tail one job (#926)' */
8
+ task?: string;
9
+ /** comma-separated; default 'git,node' */
10
+ capabilities?: string;
11
+ /** default 'repo:read' */
12
+ authority?: string;
13
+ /** bounded wait window in ms; default 120000 */
14
+ timeout?: string;
15
+ /** delay between summary polls in ms; default 1000 */
16
+ pollInterval?: string;
17
+ /** explicit job id (default server-generated) */
18
+ jobId?: string;
19
+ }
20
+ export interface HostedQueueCliDeps {
21
+ out?: {
22
+ write(s: string): unknown;
23
+ };
24
+ env?: NodeJS.ProcessEnv;
25
+ /** default createHttpHostedJobClient({ baseUrl: opts.url }) */
26
+ client?: HostedJobClient;
27
+ /** default () => Date.now() */
28
+ now?: () => number;
29
+ /** default a real setTimeout-backed delay */
30
+ sleep?: (ms: number) => Promise<void>;
31
+ }
32
+ /** Renders only QueueAndTailOutcome fields sourced from HostedJobSummary — no
33
+ * secret material ever flows through this path (logsTail is redacted by the
34
+ * runner, and requiredAuthority/credential handles are never included). */
35
+ export declare function formatQueueAndTailOutcome(outcome: QueueAndTailOutcome): string;
36
+ /** Testable core of the command: gate on the flag, queue one job and tail it
37
+ * to a terminal status within the bounded wait window, print the event
38
+ * progression plus the final result. Exit code is 0 only when the terminal
39
+ * status is 'done' — failed, canceled, and a non-terminal timeout all exit 1. */
40
+ export declare function runHostedQueueCli(opts: HostedQueueCliOptions, deps?: HostedQueueCliDeps): Promise<{
41
+ exitCode: number;
42
+ }>;
43
+ /** Command entry point wired up to commander. */
44
+ export declare function cmdHostedQueue(opts: HostedQueueCliOptions): Promise<void>;
45
+ //# sourceMappingURL=hosted-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-queue.d.ts","sourceRoot":"","sources":["../../src/cli/hosted-queue.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAKjF,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAQD;;2EAE2E;AAC3E,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAqB9E;AAED;;;iFAGiF;AACjF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,qBAAqB,EAC3B,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA6B/B;AAED,iDAAiD;AACjD,wBAAsB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E"}
@@ -0,0 +1,74 @@
1
+ // packages/cli/src/cli/hosted-queue.ts — `factory hosted queue` [--url <base>]
2
+ // [--repo <slug>] [--task <text>] [--capabilities <csv>] [--authority <authority>]
3
+ // [--timeout <ms>] [--poll-interval <ms>] [--job-id <id>]
4
+ //
5
+ // Queue/tail slice (#926): queues one job to the local hosted-exec control
6
+ // plane, tails its events and summary until it reaches a terminal state, and
7
+ // prints the event progression plus the final secret-redacted result. Exits
8
+ // non-zero for failed/canceled jobs and for a non-terminal timeout. Gated by
9
+ // FACTORY_HOSTED_EXEC=1, same as the rest of hosted-exec.
10
+ import { createHttpHostedJobClient, hostedExecEnabled, queueAndTailJob } from '@on-par/factory-core';
11
+ import { applyExitCode } from './hosted.js';
12
+ function parsePositiveInt(value, fallback) {
13
+ if (!value)
14
+ return fallback;
15
+ const parsed = Number.parseInt(value, 10);
16
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
17
+ }
18
+ /** Renders only QueueAndTailOutcome fields sourced from HostedJobSummary — no
19
+ * secret material ever flows through this path (logsTail is redacted by the
20
+ * runner, and requiredAuthority/credential handles are never included). */
21
+ export function formatQueueAndTailOutcome(outcome) {
22
+ const eventLines = outcome.events.map((e) => `event: [${e.severity}] ${e.type} @ ${e.ts} — ${e.message}`);
23
+ const summary = outcome.summary;
24
+ const summaryLines = [
25
+ `job: ${summary.jobId}`,
26
+ `repo: ${summary.repoSlug}`,
27
+ `status: ${summary.status}`,
28
+ `outcome: ${summary.outcome ?? '(none)'}`,
29
+ `exit: ${summary.exitCode ?? '(none)'}`,
30
+ `failure: ${summary.failurePhase ?? '(none)'}`,
31
+ `logs: ${summary.logsTail ?? '(none)'}`,
32
+ `artifacts: ${summary.artifactCount === 0
33
+ ? '(none)'
34
+ : summary.artifacts.map((a) => `${a.name} (${a.kind}): ${a.ref}`).join(', ')}`,
35
+ `cleanup: ${summary.cleanupProof ?? '(none)'}`,
36
+ ];
37
+ return [...eventLines, ...summaryLines].join('\n') + '\n';
38
+ }
39
+ /** Testable core of the command: gate on the flag, queue one job and tail it
40
+ * to a terminal status within the bounded wait window, print the event
41
+ * progression plus the final result. Exit code is 0 only when the terminal
42
+ * status is 'done' — failed, canceled, and a non-terminal timeout all exit 1. */
43
+ export async function runHostedQueueCli(opts, deps = {}) {
44
+ const env = deps.env ?? process.env;
45
+ const out = deps.out ?? process.stdout;
46
+ if (!hostedExecEnabled(env)) {
47
+ out.write('hosted-exec queue refused: set FACTORY_HOSTED_EXEC=1 to enable — the local factory path is unchanged\n');
48
+ return { exitCode: 0 };
49
+ }
50
+ const client = deps.client ?? createHttpHostedJobClient({ baseUrl: opts.url ?? 'http://127.0.0.1:8799' });
51
+ const requiredCapabilities = (opts.capabilities ?? 'git,node')
52
+ .split(',')
53
+ .map((c) => c.trim())
54
+ .filter((c) => c.length > 0);
55
+ const outcome = await queueAndTailJob(client, {
56
+ repoSlug: opts.repo ?? 'on-par/software-factory',
57
+ taskPayload: opts.task ?? 'hosted-exec: queue and tail one job (#926)',
58
+ requiredCapabilities,
59
+ requiredAuthority: opts.authority ?? 'repo:read',
60
+ jobId: opts.jobId,
61
+ timeoutMs: parsePositiveInt(opts.timeout, 120_000),
62
+ pollIntervalMs: parsePositiveInt(opts.pollInterval, 1_000),
63
+ now: deps.now,
64
+ sleep: deps.sleep,
65
+ });
66
+ out.write(formatQueueAndTailOutcome(outcome));
67
+ return { exitCode: outcome.status === 'done' ? 0 : 1 };
68
+ }
69
+ /** Command entry point wired up to commander. */
70
+ export async function cmdHostedQueue(opts) {
71
+ const { exitCode } = await runHostedQueueCli(opts);
72
+ applyExitCode(exitCode);
73
+ }
74
+ //# sourceMappingURL=hosted-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-queue.js","sourceRoot":"","sources":["../../src/cli/hosted-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { HostedControlPlaneClient, OneJobRunnerOutcome } from '@on-par/factory-core';
2
+ export interface HostedRunnerCliOptions {
3
+ /** default 'http://127.0.0.1:8799' */
4
+ url?: string;
5
+ /** default `runner-<pid>` */
6
+ runnerId?: string;
7
+ /** comma-separated; default 'git,node' */
8
+ capabilities?: string;
9
+ /** bounded wait window in ms; default 30000 */
10
+ timeout?: string;
11
+ /** delay between poll attempts in ms; default 2000 */
12
+ pollInterval?: string;
13
+ /** lease TTL in ms; default 300000 */
14
+ leaseTtl?: string;
15
+ /** expected heartbeat interval in ms; default 30000 */
16
+ heartbeatInterval?: string;
17
+ }
18
+ export interface HostedRunnerCliDeps {
19
+ out?: {
20
+ write(s: string): unknown;
21
+ };
22
+ env?: NodeJS.ProcessEnv;
23
+ /** default createHttpHostedControlPlaneClient({ baseUrl: opts.url }) */
24
+ client?: HostedControlPlaneClient;
25
+ /** default () => Date.now() */
26
+ now?: () => number;
27
+ /** default a real setTimeout-backed delay */
28
+ sleep?: (ms: number) => Promise<void>;
29
+ /** default randomUUID() */
30
+ generateLeaseId?: () => string;
31
+ }
32
+ /** Renders only OneJobRunnerOutcome fields — no secret material ever flows
33
+ * through this path (registration/lease payloads carry no credentials). */
34
+ export declare function formatHostedRunnerOutcome(outcome: OneJobRunnerOutcome): string;
35
+ /** Testable core of the command: gate on the flag, register + poll for one
36
+ * compatible job within the bounded wait window, print the result. Exits 0
37
+ * both when a job is leased and when the window elapses with no compatible
38
+ * work — the latter is a clean, expected outcome, not a failure. */
39
+ export declare function runHostedRunnerCli(opts: HostedRunnerCliOptions, deps?: HostedRunnerCliDeps): Promise<{
40
+ exitCode: number;
41
+ }>;
42
+ /** Command entry point wired up to commander. */
43
+ export declare function cmdHostedRunner(opts: HostedRunnerCliOptions): Promise<void>;
44
+ //# sourceMappingURL=hosted-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-runner.d.ts","sourceRoot":"","sources":["../../src/cli/hosted-runner.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAK1F,MAAM,WAAW,sBAAsB;IACrC,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,wEAAwE;IACxE,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,2BAA2B;IAC3B,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;CAChC;AAQD;2EAC2E;AAC3E,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAY9E;AAED;;;oEAGoE;AACpE,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA+B/B;AAED,iDAAiD;AACjD,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF"}