@crewbie/cli 0.1.0-alpha.49

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 (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +253 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +506 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.d.ts +84 -0
  7. package/dist/config.js +178 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/core.d.ts +31 -0
  10. package/dist/core.js +186 -0
  11. package/dist/core.js.map +1 -0
  12. package/dist/execution/attribution.d.ts +10 -0
  13. package/dist/execution/attribution.js +102 -0
  14. package/dist/execution/attribution.js.map +1 -0
  15. package/dist/execution/cancel.d.ts +3 -0
  16. package/dist/execution/cancel.js +59 -0
  17. package/dist/execution/cancel.js.map +1 -0
  18. package/dist/execution/capabilities.d.ts +22 -0
  19. package/dist/execution/capabilities.js +101 -0
  20. package/dist/execution/capabilities.js.map +1 -0
  21. package/dist/execution/controls.d.ts +51 -0
  22. package/dist/execution/controls.js +257 -0
  23. package/dist/execution/controls.js.map +1 -0
  24. package/dist/execution/dispatch.d.ts +69 -0
  25. package/dist/execution/dispatch.js +831 -0
  26. package/dist/execution/dispatch.js.map +1 -0
  27. package/dist/execution/fix.d.ts +3 -0
  28. package/dist/execution/fix.js +267 -0
  29. package/dist/execution/fix.js.map +1 -0
  30. package/dist/execution/github.d.ts +15 -0
  31. package/dist/execution/github.js +43 -0
  32. package/dist/execution/github.js.map +1 -0
  33. package/dist/execution/merge.d.ts +15 -0
  34. package/dist/execution/merge.js +133 -0
  35. package/dist/execution/merge.js.map +1 -0
  36. package/dist/execution/planning-approval.d.ts +33 -0
  37. package/dist/execution/planning-approval.js +227 -0
  38. package/dist/execution/planning-approval.js.map +1 -0
  39. package/dist/execution/pr-review.d.ts +86 -0
  40. package/dist/execution/pr-review.js +339 -0
  41. package/dist/execution/pr-review.js.map +1 -0
  42. package/dist/execution/review-loop.d.ts +63 -0
  43. package/dist/execution/review-loop.js +463 -0
  44. package/dist/execution/review-loop.js.map +1 -0
  45. package/dist/execution/test-feature.d.ts +29 -0
  46. package/dist/execution/test-feature.js +240 -0
  47. package/dist/execution/test-feature.js.map +1 -0
  48. package/dist/execution/watch.d.ts +12 -0
  49. package/dist/execution/watch.js +34 -0
  50. package/dist/execution/watch.js.map +1 -0
  51. package/dist/memory/context.d.ts +14 -0
  52. package/dist/memory/context.js +82 -0
  53. package/dist/memory/context.js.map +1 -0
  54. package/dist/memory/improvement.d.ts +25 -0
  55. package/dist/memory/improvement.js +168 -0
  56. package/dist/memory/improvement.js.map +1 -0
  57. package/dist/memory/launch.d.ts +9 -0
  58. package/dist/memory/launch.js +65 -0
  59. package/dist/memory/launch.js.map +1 -0
  60. package/dist/memory/runner.d.ts +4 -0
  61. package/dist/memory/runner.js +74 -0
  62. package/dist/memory/runner.js.map +1 -0
  63. package/dist/memory/state.d.ts +10 -0
  64. package/dist/memory/state.js +42 -0
  65. package/dist/memory/state.js.map +1 -0
  66. package/dist/presentation.d.ts +19 -0
  67. package/dist/presentation.js +128 -0
  68. package/dist/presentation.js.map +1 -0
  69. package/dist/reporting/dashboard.d.ts +2 -0
  70. package/dist/reporting/dashboard.js +106 -0
  71. package/dist/reporting/dashboard.js.map +1 -0
  72. package/dist/reporting/pr-usage.d.ts +24 -0
  73. package/dist/reporting/pr-usage.js +179 -0
  74. package/dist/reporting/pr-usage.js.map +1 -0
  75. package/dist/reporting/records.d.ts +28 -0
  76. package/dist/reporting/records.js +152 -0
  77. package/dist/reporting/records.js.map +1 -0
  78. package/dist/setup/agents.d.ts +8 -0
  79. package/dist/setup/agents.js +83 -0
  80. package/dist/setup/agents.js.map +1 -0
  81. package/dist/setup/assessment.d.ts +31 -0
  82. package/dist/setup/assessment.js +75 -0
  83. package/dist/setup/assessment.js.map +1 -0
  84. package/dist/setup/auto-loaded.d.ts +17 -0
  85. package/dist/setup/auto-loaded.js +49 -0
  86. package/dist/setup/auto-loaded.js.map +1 -0
  87. package/dist/setup/copilot-version.d.ts +7 -0
  88. package/dist/setup/copilot-version.js +39 -0
  89. package/dist/setup/copilot-version.js.map +1 -0
  90. package/dist/setup/copilot.d.ts +22 -0
  91. package/dist/setup/copilot.js +164 -0
  92. package/dist/setup/copilot.js.map +1 -0
  93. package/dist/setup/init.d.ts +41 -0
  94. package/dist/setup/init.js +315 -0
  95. package/dist/setup/init.js.map +1 -0
  96. package/dist/setup/install.d.ts +12 -0
  97. package/dist/setup/install.js +211 -0
  98. package/dist/setup/install.js.map +1 -0
  99. package/dist/setup/instruction-quality.d.ts +25 -0
  100. package/dist/setup/instruction-quality.js +258 -0
  101. package/dist/setup/instruction-quality.js.map +1 -0
  102. package/dist/setup/inventory.d.ts +26 -0
  103. package/dist/setup/inventory.js +78 -0
  104. package/dist/setup/inventory.js.map +1 -0
  105. package/dist/setup/onboarding.d.ts +40 -0
  106. package/dist/setup/onboarding.js +472 -0
  107. package/dist/setup/onboarding.js.map +1 -0
  108. package/dist/setup/package.d.ts +2 -0
  109. package/dist/setup/package.js +8 -0
  110. package/dist/setup/package.js.map +1 -0
  111. package/dist/setup/planning-workflow.d.ts +3 -0
  112. package/dist/setup/planning-workflow.js +250 -0
  113. package/dist/setup/planning-workflow.js.map +1 -0
  114. package/dist/setup/repository-map.d.ts +34 -0
  115. package/dist/setup/repository-map.js +89 -0
  116. package/dist/setup/repository-map.js.map +1 -0
  117. package/dist/setup/review.d.ts +8 -0
  118. package/dist/setup/review.js +137 -0
  119. package/dist/setup/review.js.map +1 -0
  120. package/dist/setup/team.d.ts +18 -0
  121. package/dist/setup/team.js +172 -0
  122. package/dist/setup/team.js.map +1 -0
  123. package/dist/setup/templates.d.ts +11 -0
  124. package/dist/setup/templates.js +494 -0
  125. package/dist/setup/templates.js.map +1 -0
  126. package/dist/setup/terminal.d.ts +12 -0
  127. package/dist/setup/terminal.js +11 -0
  128. package/dist/setup/terminal.js.map +1 -0
  129. package/dist/setup/update.d.ts +6 -0
  130. package/dist/setup/update.js +71 -0
  131. package/dist/setup/update.js.map +1 -0
  132. package/dist/specification/batch.d.ts +50 -0
  133. package/dist/specification/batch.js +127 -0
  134. package/dist/specification/batch.js.map +1 -0
  135. package/dist/specification/plan-checks.d.ts +6 -0
  136. package/dist/specification/plan-checks.js +73 -0
  137. package/dist/specification/plan-checks.js.map +1 -0
  138. package/dist/specification/planning.d.ts +26 -0
  139. package/dist/specification/planning.js +507 -0
  140. package/dist/specification/planning.js.map +1 -0
  141. package/dist/specification/prose.d.ts +1 -0
  142. package/dist/specification/prose.js +15 -0
  143. package/dist/specification/prose.js.map +1 -0
  144. package/dist/tracking/ado.d.ts +19 -0
  145. package/dist/tracking/ado.js +128 -0
  146. package/dist/tracking/ado.js.map +1 -0
  147. package/dist/tracking/github.d.ts +8 -0
  148. package/dist/tracking/github.js +112 -0
  149. package/dist/tracking/github.js.map +1 -0
  150. package/dist/tracking/issues.d.ts +28 -0
  151. package/dist/tracking/issues.js +180 -0
  152. package/dist/tracking/issues.js.map +1 -0
  153. package/dist/tracking/native.d.ts +5 -0
  154. package/dist/tracking/native.js +30 -0
  155. package/dist/tracking/native.js.map +1 -0
  156. package/dist/tracking/refs.d.ts +14 -0
  157. package/dist/tracking/refs.js +56 -0
  158. package/dist/tracking/refs.js.map +1 -0
  159. package/dist/tracking/sources.d.ts +5 -0
  160. package/dist/tracking/sources.js +29 -0
  161. package/dist/tracking/sources.js.map +1 -0
  162. package/docs/operations.md +1114 -0
  163. package/examples/batch.json +27 -0
  164. package/examples/runs.json +22 -0
  165. package/package.json +50 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancel.js","sourceRoot":"","sources":["../../src/execution/cancel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type GitHubReader } from "./github.js";
2
+ export type CapabilityStatus = "ready" | "blocked" | "unknown";
3
+ export interface Finding {
4
+ id: string;
5
+ status: CapabilityStatus;
6
+ detail: string;
7
+ }
8
+ export interface CapabilityReport {
9
+ schemaVersion: 1;
10
+ repository: string;
11
+ accountType: string;
12
+ baseBranch: string;
13
+ findings: Finding[];
14
+ liveAssignmentVerified: false;
15
+ }
16
+ export interface ProbeOptions {
17
+ repository: string;
18
+ agent?: string;
19
+ model?: string;
20
+ }
21
+ export declare function probeCapabilities(reader: GitHubReader, options: ProbeOptions): Promise<CapabilityReport>;
22
+ export declare function renderReport(report: CapabilityReport): string;
@@ -0,0 +1,101 @@
1
+ import { agentName, GitHubError, object, repositoryName, text } from "./github.js";
2
+ const ACTORS_QUERY = `query CrewbieCapabilities($owner: String!, $name: String!) {
3
+ repository(owner: $owner, name: $name) {
4
+ suggestedActors(capabilities: [CAN_BE_ASSIGNED], first: 100) {
5
+ nodes { login }
6
+ }
7
+ }
8
+ }`;
9
+ export async function probeCapabilities(reader, options) {
10
+ const repo = repositoryName(options.repository);
11
+ const selectedAgent = options.agent === undefined ? undefined : agentName(options.agent);
12
+ if (options.model !== undefined && !options.model.trim()) {
13
+ throw new Error("A requested model must be a non-empty model identifier.");
14
+ }
15
+ const prefix = `/repos/${repo.fullName}`;
16
+ const metadata = object(await reader.get(prefix), "repository");
17
+ const owner = object(metadata.owner, "repository owner");
18
+ const accountType = text(owner.type, "repository owner type");
19
+ const baseBranch = text(metadata.default_branch, "default branch");
20
+ const findings = [{
21
+ id: "repository-access",
22
+ status: "ready",
23
+ detail: `Repository metadata is accessible. The default branch is ${baseBranch}.`,
24
+ }];
25
+ if (metadata.archived === true || metadata.disabled === true) {
26
+ findings.push({ id: "repository-state", status: "blocked", detail: "This repository is archived or disabled." });
27
+ }
28
+ const data = object(await reader.query(ACTORS_QUERY, { owner: repo.owner, name: repo.name }), "actor query");
29
+ const actors = object(object(data.repository, "actor repository").suggestedActors, "suggested actors");
30
+ if (!Array.isArray(actors.nodes))
31
+ throw new Error("GitHub returned an invalid suggested-actor list.");
32
+ const enabled = actors.nodes.some((node) => object(node, "suggested actor").login === "copilot-swe-agent");
33
+ findings.push({
34
+ id: "cloud-agent",
35
+ status: enabled ? "ready" : "blocked",
36
+ detail: enabled
37
+ ? "GitHub advertises Copilot as assignable for this credential and repository; no session was started."
38
+ : "GitHub did not advertise Copilot as assignable. Check account entitlement and repository policy.",
39
+ });
40
+ if (selectedAgent) {
41
+ const path = `${prefix}/contents/.github/agents/${selectedAgent}.agent.md?ref=${encodeURIComponent(baseBranch)}`;
42
+ try {
43
+ const file = object(await reader.get(path), "agent profile");
44
+ if (file.type !== "file")
45
+ throw new Error("The selected agent profile is not a regular file.");
46
+ text(file.sha, "agent profile revision");
47
+ findings.push({
48
+ id: "agent-profile",
49
+ status: "ready",
50
+ detail: `${selectedAgent}.agent.md exists on ${baseBranch}. Runtime selection and memory loading still need a live proof.`,
51
+ });
52
+ }
53
+ catch (error) {
54
+ if (!(error instanceof GitHubError) || error.status !== 404)
55
+ throw error;
56
+ findings.push({
57
+ id: "agent-profile",
58
+ status: "blocked",
59
+ detail: `The selected profile was not found on ${baseBranch}, or this credential cannot read it.`,
60
+ });
61
+ }
62
+ }
63
+ else {
64
+ findings.push({ id: "agent-profile", status: "unknown", detail: "Choose a specialist profile with --agent before testing execution." });
65
+ }
66
+ findings.push({
67
+ id: "requested-model",
68
+ status: "unknown",
69
+ detail: options.model
70
+ ? `Requested model: ${options.model}. Read-only discovery cannot prove assignment accepts it or that the runtime uses it.`
71
+ : "No model was selected. Crewbie must obtain an explicit approved model before launch.",
72
+ }, {
73
+ id: "nightly-auth",
74
+ status: "unknown",
75
+ detail: accountType === "Organization"
76
+ ? "Check organization Copilot CLI billing policy and copilot-requests: write in a consenting Actions run."
77
+ : "Personal repositories can use GITHUB_TOKEN with copilot-requests: write, billed to the owner's Copilot seat. Verify entitlement in a consenting Actions run.",
78
+ }, {
79
+ id: "private-dashboard",
80
+ status: "unknown",
81
+ detail: "Private Pages entitlement is not established. Use a repository-access-controlled Actions artifact until verified.",
82
+ }, {
83
+ id: "usage-telemetry",
84
+ status: "unknown",
85
+ detail: "Exact per-specialist cloud tokens, billed spend, and observed model are not guaranteed by a documented public interface.",
86
+ }, {
87
+ id: "live-assignment",
88
+ status: "unknown",
89
+ detail: "User-authorized live issue assignment, PR linkage, selected profile/model, and memory-read evidence remain unverified.",
90
+ });
91
+ return { schemaVersion: 1, repository: repo.fullName, accountType, baseBranch, findings, liveAssignmentVerified: false };
92
+ }
93
+ export function renderReport(report) {
94
+ return [
95
+ `Crewbie capability check: ${report.repository}`,
96
+ ...report.findings.map((finding) => `[${finding.status}] ${finding.id}: ${finding.detail}`),
97
+ "",
98
+ "Read-only check. No issue, session, pull request, workflow, or repository file was changed.",
99
+ ].join("\n");
100
+ }
101
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/execution/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type Config } from "../config.js";
2
+ import { taskMetadata } from "../specification/batch.js";
3
+ import { type GitHubApi } from "../tracking/github.js";
4
+ import { listCopilotModels, type ModelChoice } from "../setup/copilot.js";
5
+ type Metadata = NonNullable<ReturnType<typeof taskMetadata>>;
6
+ export type DiscoverModels = () => Promise<ModelChoice[]>;
7
+ export { listCopilotModels };
8
+ export { RESTART_LABEL } from "../config.js";
9
+ export declare const RESTART_MARKER = "<!-- crewbie-restart:";
10
+ /** Comments after the latest Crewbie restart marker. A forged marker only hides a start failure, which keeps capacity reserved. */
11
+ export declare function sinceRestart(comments: Record<string, unknown>[]): Record<string, unknown>[];
12
+ /** Copilot reported that the current launch (since the latest restart) could not start. */
13
+ export declare function copilotStartFailure(comments: Record<string, unknown>[]): boolean;
14
+ export declare function copilotStartFailures(comments: Record<string, unknown>[]): number;
15
+ export declare const LOCK_WAIT: {
16
+ attempts: number;
17
+ delayMs: number;
18
+ };
19
+ export declare function withDispatchLock<T>(client: GitHubApi, config: Config, action: () => Promise<T>): Promise<T>;
20
+ export declare function launchesPaused(client: GitHubApi, config: Config): Promise<boolean>;
21
+ export declare function setLaunchPause(client: GitHubApi, config: Config, paused: boolean, apply: boolean): Promise<string>;
22
+ export interface LaunchAllowance {
23
+ batch: string;
24
+ task: string;
25
+ issue: number;
26
+ used: number;
27
+ taskUsed: number;
28
+ issueUsed: number;
29
+ maxLaunchesPerBatch: number;
30
+ maxAttemptsPerTask: number;
31
+ blocked: string | null;
32
+ }
33
+ export declare function launchAllowance(client: GitHubApi, config: Config, metadata: Metadata, issue: number): Promise<LaunchAllowance>;
34
+ export declare function baselineLaunches(client: GitHubApi, config: Config, issue: number, attempts: number, apply: boolean): Promise<string>;
35
+ export declare function reserveLaunch(client: GitHubApi, config: Config, metadata: Metadata, issue: number, baseSha: string, initial?: boolean): Promise<LaunchAllowance>;
36
+ /**
37
+ * Whether the Copilot cloud agent accepts a model. The CLI catalog lists models the cloud agent may reject; issue
38
+ * assignment then fails asynchronously with a misleading "ruleset violation" comment. The tasks API validates the
39
+ * model before the base branch, so a nonexistent branch answers without starting a session (it leaves a failed task).
40
+ */
41
+ export declare function cloudAgentAccepts(client: GitHubApi, repository: string, model: string): Promise<boolean>;
42
+ export declare function modelRejection(model: string, owners: string): string;
43
+ /** Validates launch models against policy and the catalog, and returns the ones the cloud agent rejects. */
44
+ export declare function rejectedLaunchModels(models: ModelChoice[], tasks: {
45
+ owner: string;
46
+ model: string;
47
+ }[], config: Config, client: GitHubApi): Promise<Set<string>>;
48
+ export declare function checkLaunchModels(models: ModelChoice[], tasks: {
49
+ owner: string;
50
+ model: string;
51
+ }[], config: Config, client?: GitHubApi): Promise<void>;
@@ -0,0 +1,257 @@
1
+ import { DEFAULT_EXECUTION_LIMITS, requireExecution } from "../config.js";
2
+ import { GitHubError, integer, record, slug, string } from "../core.js";
3
+ import { taskMetadata } from "../specification/batch.js";
4
+ import { requireWriter } from "../tracking/github.js";
5
+ import { listCopilotModels } from "../setup/copilot.js";
6
+ import { createLedger, deleteLedger, ledgerHas, ledgerRef, listLedger } from "../tracking/refs.js";
7
+ export { listCopilotModels };
8
+ const PAUSE = "paused";
9
+ export { RESTART_LABEL } from "../config.js";
10
+ export const RESTART_MARKER = "<!-- crewbie-restart:";
11
+ function isStartFailure(comment) {
12
+ const user = comment.user === null || comment.user === undefined ? {} : record(comment.user, "comment author");
13
+ return user.type === "Bot" && ["Copilot", "copilot-swe-agent[bot]", "copilot-swe-agent"].includes(String(user.login))
14
+ && /unable to start working on this issue/i.test(String(comment.body ?? ""));
15
+ }
16
+ /** Comments after the latest Crewbie restart marker. A forged marker only hides a start failure, which keeps capacity reserved. */
17
+ export function sinceRestart(comments) {
18
+ let start = 0;
19
+ comments.forEach((comment, index) => { if (String(comment.body ?? "").includes(RESTART_MARKER))
20
+ start = index + 1; });
21
+ return comments.slice(start);
22
+ }
23
+ /** Copilot reported that the current launch (since the latest restart) could not start. */
24
+ export function copilotStartFailure(comments) {
25
+ return sinceRestart(comments).some(isStartFailure);
26
+ }
27
+ export function copilotStartFailures(comments) {
28
+ return comments.filter(isStartFailure).length;
29
+ }
30
+ const LOCK = "dispatch-lock";
31
+ export const LOCK_WAIT = { attempts: 60, delayMs: 5_000 };
32
+ export async function withDispatchLock(client, config, action) {
33
+ requireExecution(config);
34
+ const sha = await defaultHead(client, config);
35
+ // Dispatch and plan-release workflows both fire on a planning merge; wait for the short-lived holder instead of failing.
36
+ for (let attempt = 1;; attempt++) {
37
+ try {
38
+ await createLedger(client, config.repository, LOCK, sha);
39
+ break;
40
+ }
41
+ catch (error) {
42
+ if (!(error instanceof GitHubError) || error.status !== 422)
43
+ throw error;
44
+ if (attempt >= LOCK_WAIT.attempts) {
45
+ throw new Error(`Another Crewbie run still holds ${ledgerRef(LOCK)} after ${Math.round(LOCK_WAIT.attempts * LOCK_WAIT.delayMs / 1000)}s. Nothing was launched. If no Crewbie workflow is running, delete it (gh api -X DELETE repos/${config.repository}/git/${ledgerRef(LOCK)}) and rerun this workflow.`);
46
+ }
47
+ await new Promise((resolve) => setTimeout(resolve, LOCK_WAIT.delayMs));
48
+ }
49
+ }
50
+ try {
51
+ return await action();
52
+ }
53
+ finally {
54
+ await deleteLedger(client, config.repository, LOCK);
55
+ }
56
+ }
57
+ async function defaultHead(client, config) {
58
+ const prefix = `/repos/${config.repository}`;
59
+ const repo = record(await client.request("GET", prefix), "repository");
60
+ const branch = string(repo.default_branch, "default branch");
61
+ const current = record(await client.request("GET", `${prefix}/branches/${encodeURIComponent(branch)}`), "branch");
62
+ return string(record(current.commit, "commit").sha, "base commit");
63
+ }
64
+ export async function launchesPaused(client, config) {
65
+ return ledgerHas(client, config.repository, PAUSE);
66
+ }
67
+ export async function setLaunchPause(client, config, paused, apply) {
68
+ if (!apply)
69
+ return `Preview: ${paused ? "pause" : "resume"} future Crewbie implementation/review launches repository-wide. Running sessions are not stopped; allowances and approvals are not reset. Repeat with --apply.`;
70
+ await requireWriter(client, config.repository);
71
+ return withDispatchLock(client, config, async () => {
72
+ if (await launchesPaused(client, config) !== paused) {
73
+ if (paused)
74
+ await createLedger(client, config.repository, PAUSE, await defaultHead(client, config));
75
+ else
76
+ await deleteLedger(client, config.repository, PAUSE, true);
77
+ }
78
+ return `${paused ? "Paused" : "Resumed"} future Crewbie launches. Running sessions, launch allowances and approvals are unchanged. No agents were started.`;
79
+ });
80
+ }
81
+ export async function launchAllowance(client, config, metadata, issue) {
82
+ const batch = slug(metadata.batch, "batch"), task = slug(metadata.task.id, "task");
83
+ integer(issue, "issue");
84
+ const prefix = `/repos/${config.repository}`;
85
+ const refs = await listLedger(client, config.repository, `launches/${batch}/`);
86
+ const entries = [];
87
+ for (const raw of refs) {
88
+ const ref = raw.ref;
89
+ const match = /^launches\/([a-z][a-z0-9-]{0,63})\/([a-z][a-z0-9-]{0,63})\/(\d+)\/(\d+|baseline)$/.exec(raw.name);
90
+ if (!match || match[1] !== batch)
91
+ throw new Error("Invalid launch ledger; do not reset it to bypass limits.");
92
+ const issue = integer(Number(match[3]), "ledger issue");
93
+ let attempts = 1;
94
+ if (match[4] === "baseline") {
95
+ const object = record(raw.object, "baseline object");
96
+ if (object.type !== "tag" || !/^[a-f0-9]{40}$/.test(String(object.sha)))
97
+ throw new Error("Invalid historical launch baseline.");
98
+ const tag = record(await client.request("GET", `${prefix}/git/tags/${object.sha}`), "baseline tag");
99
+ const baseline = record(JSON.parse(string(tag.message, "baseline record")), "historical baseline");
100
+ if (baseline.schemaVersion !== 1 || baseline.batch !== batch || baseline.task !== match[2] || baseline.issue !== issue)
101
+ throw new Error("Historical baseline does not match its launch ref.");
102
+ attempts = integer(baseline.attempts, "historical attempts", 1, 10000);
103
+ }
104
+ else
105
+ integer(Number(match[4]), "ledger attempt");
106
+ entries.push({ ref, task: match[2], issue, attempts, baseline: match[4] === "baseline" });
107
+ }
108
+ if (new Set(entries.map((entry) => entry.ref)).size !== entries.length)
109
+ throw new Error("Duplicate launch-ledger entries.");
110
+ // Each launch Copilot reports it could not start ran no session, so it is not an attempt.
111
+ for (const number of new Set(entries.filter((entry) => !entry.baseline).map((entry) => entry.issue))) {
112
+ let refunds = copilotStartFailures(await client.list(`${prefix}/issues/${number}/comments`));
113
+ for (const entry of entries) {
114
+ if (refunds <= 0)
115
+ break;
116
+ if (entry.baseline || entry.issue !== number)
117
+ continue;
118
+ entry.attempts = 0;
119
+ refunds--;
120
+ }
121
+ }
122
+ const limits = config.execution ?? DEFAULT_EXECUTION_LIMITS;
123
+ const result = { batch, task, issue, used: entries.reduce((n, entry) => n + entry.attempts, 0),
124
+ taskUsed: entries.filter((entry) => entry.task === task).reduce((n, entry) => n + entry.attempts, 0),
125
+ issueUsed: entries.filter((entry) => entry.task === task && entry.issue === issue).reduce((n, entry) => n + entry.attempts, 0), ...limits, blocked: null };
126
+ if (await launchesPaused(client, config))
127
+ result.blocked = "Future Crewbie launches are paused. Running sessions are unchanged.";
128
+ else if (result.used >= limits.maxLaunchesPerBatch)
129
+ result.blocked = `Batch launch allowance exhausted (${result.used}/${limits.maxLaunchesPerBatch}).`;
130
+ else if (result.taskUsed >= limits.maxAttemptsPerTask)
131
+ result.blocked = `Task attempt allowance exhausted (${result.taskUsed}/${limits.maxAttemptsPerTask}); initial and uncertain requests count; verified start failures do not.`;
132
+ if (result.blocked)
133
+ return result;
134
+ // Older claims have no reliable continuation count. Never present a partial history as a lifetime cap.
135
+ const claims = await listLedger(client, config.repository, "claims/");
136
+ for (const raw of claims) {
137
+ const match = /^claims\/(\d+)$/.exec(raw.name);
138
+ if (!match)
139
+ throw new Error("Invalid claim ledger.");
140
+ const number = integer(Number(match[1]), "claimed issue");
141
+ if (entries.some((entry) => entry.issue === number))
142
+ continue;
143
+ const claimed = record(await client.request("GET", `${prefix}/issues/${number}`), "claimed issue");
144
+ const body = string(claimed.body, "claimed body");
145
+ const prior = taskMetadata(body);
146
+ // Tasks published before feature branches are finished by hand and never launch again.
147
+ if (!prior && body.includes("<!-- crewbie-task:"))
148
+ continue;
149
+ if (!prior)
150
+ throw new Error("Claimed issue has no Crewbie metadata.");
151
+ if (prior.batch === batch) {
152
+ result.blocked = `Batch ${batch} has pre-ledger claim #${number}; historical attempts are unverified. Review its history, then use budget --issue ${number} --historical-attempts COUNT to preview an explicit baseline; no automatic allowance reset.`;
153
+ break;
154
+ }
155
+ }
156
+ return result;
157
+ }
158
+ export async function baselineLaunches(client, config, issue, attempts, apply) {
159
+ integer(issue, "issue");
160
+ integer(attempts, "historical attempts", 1, 10000);
161
+ const prefix = `/repos/${config.repository}`;
162
+ const inspect = async () => {
163
+ if (!await ledgerHas(client, config.repository, `claims/${issue}`))
164
+ throw new Error(`Issue #${issue} has no Crewbie launch claim.`);
165
+ const original = record(await client.request("GET", `${prefix}/issues/${issue}`), "claimed issue");
166
+ const metadata = taskMetadata(string(original.body, "issue body"));
167
+ if (!metadata)
168
+ throw new Error("Claimed issue has no Crewbie metadata.");
169
+ const path = `launches/${metadata.batch}/${metadata.task.id}/${issue}/`;
170
+ if ((await listLedger(client, config.repository, path)).length)
171
+ throw new Error("Launch history already exists for this issue; baselines cannot overwrite or refund attempts.");
172
+ return { metadata, path };
173
+ };
174
+ const prior = await inspect();
175
+ if (!apply)
176
+ return `Preview: record ${attempts} historical attempts for #${issue} in batch ${prior.metadata.batch}. This is YOUR attestation after reviewing prior initial, continuation and uncertain launches, not measured telemetry. It consumes allowance and cannot be reset. Repeat with --apply; no agents will start.`;
177
+ await requireWriter(client, config.repository);
178
+ return withDispatchLock(client, config, async () => {
179
+ const fresh = await inspect();
180
+ if (fresh.path !== prior.path)
181
+ throw new Error("Historical task identity changed; preview again.");
182
+ const baseline = { schemaVersion: 1, batch: fresh.metadata.batch, task: fresh.metadata.task.id, issue, attempts };
183
+ const tag = record(await client.request("POST", `${prefix}/git/tags`, {
184
+ tag: `${fresh.path}baseline`, message: JSON.stringify(baseline), object: await defaultHead(client, config), type: "commit",
185
+ }), "baseline tag");
186
+ await createLedger(client, config.repository, `${fresh.path}baseline`, string(tag.sha, "baseline SHA"));
187
+ return `Recorded the human-attested baseline of ${attempts} attempts for #${issue}. No history reset, paid launch or model change occurred. Run preflight again.`;
188
+ });
189
+ }
190
+ export async function reserveLaunch(client, config, metadata, issue, baseSha, initial = false) {
191
+ const allowance = await launchAllowance(client, config, metadata, issue);
192
+ if (allowance.blocked)
193
+ throw new Error(allowance.blocked);
194
+ if (initial && allowance.issueUsed > 0)
195
+ throw new Error("Initial launch already reserved; inspect its outcome instead of retrying.");
196
+ // Refunded start failures lower the count, so number after the highest existing ref rather than reuse one.
197
+ const existing = await listLedger(client, config.repository, `launches/${allowance.batch}/${allowance.task}/`);
198
+ const highest = Math.max(0, ...existing.map((raw) => Number(/\/(\d+)$/.exec(raw.name)?.[1] ?? 0)));
199
+ await createLedger(client, config.repository, `launches/${allowance.batch}/${allowance.task}/${issue}/${Math.max(allowance.taskUsed, highest) + 1}`, baseSha);
200
+ return allowance;
201
+ }
202
+ const PROBE_BRANCH = "crewbie/model-check-never-exists";
203
+ /**
204
+ * Whether the Copilot cloud agent accepts a model. The CLI catalog lists models the cloud agent may reject; issue
205
+ * assignment then fails asynchronously with a misleading "ruleset violation" comment. The tasks API validates the
206
+ * model before the base branch, so a nonexistent branch answers without starting a session (it leaves a failed task).
207
+ */
208
+ export async function cloudAgentAccepts(client, repository, model) {
209
+ try {
210
+ await client.request("POST", `/agents/repos/${repository}/tasks`, {
211
+ model, prompt: "Crewbie model availability check; never runs.", base_ref: PROBE_BRANCH, create_pull_request: false,
212
+ });
213
+ }
214
+ catch (error) {
215
+ if (error instanceof GitHubError && error.status === 400)
216
+ return false;
217
+ if (error instanceof GitHubError && error.status === 412)
218
+ return true;
219
+ // Assignment-only credentials cannot create tasks; an unverifiable model must not block launches that would work.
220
+ if (error instanceof GitHubError && error.status === 403) {
221
+ console.warn(`Crewbie: could not verify that the cloud agent accepts ${model} (the credential cannot create agent tasks; grant Agent tasks read and write to enable the check). Launching without the check. ${error.message}`);
222
+ return true;
223
+ }
224
+ throw error;
225
+ }
226
+ throw new Error(`The cloud-agent model check for ${model} unexpectedly created a task; inspect the Agents tab.`);
227
+ }
228
+ export function modelRejection(model, owners) {
229
+ return `The Copilot cloud agent does not accept model ${model} for this account (specialist ${owners}), although the CLI lists it. Choose another model for that role in .crewbie/config.json; approved tasks using ${model} need replanning or reapproval.`;
230
+ }
231
+ /** Validates launch models against policy and the catalog, and returns the ones the cloud agent rejects. */
232
+ export async function rejectedLaunchModels(models, tasks, config, client) {
233
+ await checkLaunchModels(models, tasks, config);
234
+ const rejected = new Set();
235
+ for (const model of new Set(tasks.map((task) => task.model)))
236
+ if (!await cloudAgentAccepts(client, config.repository, model))
237
+ rejected.add(model);
238
+ return rejected;
239
+ }
240
+ export async function checkLaunchModels(models, tasks, config, client) {
241
+ if (!models.length)
242
+ throw new Error("Launch preflight returned no enabled account models; nothing was launched.");
243
+ for (const task of tasks) {
244
+ if (!config.roles.some((role) => role.id === task.owner && role.model === task.model))
245
+ throw new Error("Launch specialist/model differs from approved policy.");
246
+ if (!models.some((model) => model.id === task.model))
247
+ throw new Error(`Launch model ${task.model} is absent from the live account catalog. Review model selection; no fallback or paid retry was attempted.`);
248
+ }
249
+ // Read-only previews omit the client: the check leaves a failed task.
250
+ for (const model of client ? new Set(tasks.map((task) => task.model)) : []) {
251
+ if (!await cloudAgentAccepts(client, config.repository, model)) {
252
+ const owners = [...new Set(tasks.filter((task) => task.model === model).map((task) => task.owner))].join(", ");
253
+ throw new Error(`${modelRejection(model, owners)} Nothing was launched.`);
254
+ }
255
+ }
256
+ }
257
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../src/execution/controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { type Config } from "../config.js";
2
+ import { taskMetadata, type Batch } from "../specification/batch.js";
3
+ import { type GitHubApi } from "../tracking/github.js";
4
+ import type { AdoApi } from "../tracking/ado.js";
5
+ import { type DiscoverModels } from "./controls.js";
6
+ export { withDispatchLock } from "./controls.js";
7
+ export type WorkState = "blocked" | "ready" | "running" | "review" | "failed" | "done";
8
+ export interface Work {
9
+ issue: Record<string, unknown>;
10
+ metadata: NonNullable<ReturnType<typeof taskMetadata>>;
11
+ state: WorkState;
12
+ approved: boolean;
13
+ claimed: boolean;
14
+ sessionComplete?: boolean;
15
+ /** Verified that no cloud session is still running: native task terminal, or Copilot reported it could not start. */
16
+ sessionEnded?: boolean;
17
+ reason: string;
18
+ pull?: Record<string, unknown>;
19
+ nativeTask?: Record<string, unknown>;
20
+ }
21
+ export interface FeatureBodyItem {
22
+ issue: Record<string, unknown>;
23
+ metadata: NonNullable<ReturnType<typeof taskMetadata>>;
24
+ pull?: Record<string, unknown>;
25
+ }
26
+ export declare function renderDispatchResult(work: Work[], config: Config): string;
27
+ export { cloudTasks } from "../tracking/native.js";
28
+ export declare function selectNativeTask(client: GitHubApi, config: Config, issue: number, matches: Record<string, unknown>[]): Promise<Record<string, unknown> | undefined>;
29
+ /** A continuation whose task is not yet linked to the PR is still starting; the earlier completed task must not count as the outcome. */
30
+ export declare function pendingContinuation(client: GitHubApi, comments: Record<string, unknown>[], config: Config, matches: Record<string, unknown>[]): Promise<string | null>;
31
+ /**
32
+ * The Copilot PR for a task issue. Default-branch PRs are found through GitHub's closing references; GitHub does not link
33
+ * PRs into a feature branch, so those are found through the issue's cross-references and must target that branch.
34
+ */
35
+ export declare function linkedPull(client: GitHubApi, repository: string, issue: number, branch?: string): Promise<Record<string, unknown> | null>;
36
+ /**
37
+ * Only open managed issues, recently closed ones and issues a scoped run names are inspected in full. Older closed
38
+ * issues are read only when an open task depends on them, so each run stays proportional to active work.
39
+ */
40
+ export declare function inspectWork(client: GitHubApi, config: Config, knownIssues?: readonly number[], now?: Date): Promise<Work[]>;
41
+ export declare function batchWork(work: Work[], batch: Batch): Work[];
42
+ export declare function eligible(work: Work[], maxActive: number, batchId?: string): Work[];
43
+ export declare function dispatch(client: GitHubApi, config: Config, ado?: AdoApi, scope?: {
44
+ batch?: Batch;
45
+ issueNumbers: number[];
46
+ }, discoverModels?: DiscoverModels): Promise<Work[]>;
47
+ export declare const FEATURE_MARKER = "<!-- crewbie-feature:";
48
+ export declare function featureBody(config: Config, batch: string, branch: string, items: FeatureBodyItem[]): string;
49
+ /** The "## Checks" section of a task PR body, without closing keywords or comments that would change the feature PR's meaning. */
50
+ export declare function taskChecks(pull: Record<string, unknown>): string | null;
51
+ export declare function updateFeatureBody(config: Config, batch: string, items: FeatureBodyItem[], current: string): string;
52
+ /** Why a restart request cannot relaunch this task, or null when its previous session verifiably ended. */
53
+ export declare function restartProblem(item: Work): string | null;
54
+ export declare function preflight(client: GitHubApi, config: Config, batchId?: string, discoverModels?: DiscoverModels, ado?: AdoApi): Promise<{
55
+ repository: string;
56
+ branch: string;
57
+ tasks: {
58
+ issue: number;
59
+ title: string;
60
+ specialist: string;
61
+ model: string;
62
+ approved: boolean;
63
+ ready: boolean;
64
+ reason: string;
65
+ profileRevision: string | null;
66
+ allowance: import("./controls.js").LaunchAllowance;
67
+ }[];
68
+ notice: string;
69
+ }>;