@cultos/cli 0.1.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/dist/cli.js ADDED
@@ -0,0 +1,287 @@
1
+ #!/usr/bin/env node
2
+ import pc from "picocolors";
3
+ import { Command } from "commander";
4
+ import { completeJob, createJob, fundJob, quoteJob, rejectJob, sendMessage, submitJob, watchJob } from "./acp.js";
5
+ import { createPullRequestDelivery, createWorkContract, parsePullRequestDelivery } from "./contract.js";
6
+ import { runDemo } from "./demo.js";
7
+ import { runDoctor } from "./doctor.js";
8
+ import { commentOnIssue, getIssue, getPullRequest, getRepository } from "./github.js";
9
+ import { getJob, listJobs, saveJob, updateJob } from "./state.js";
10
+ import { verifyJob } from "./verify.js";
11
+ const program = new Command();
12
+ function issueNumber(value) {
13
+ const parsed = Number.parseInt(value, 10);
14
+ if (!Number.isInteger(parsed) || parsed < 1) {
15
+ throw new Error(`Invalid issue number: ${value}`);
16
+ }
17
+ return parsed;
18
+ }
19
+ function chainId(value) {
20
+ const parsed = Number.parseInt(value, 10);
21
+ if (!Number.isInteger(parsed) || parsed < 1) {
22
+ throw new Error(`Invalid chain ID: ${value}`);
23
+ }
24
+ return parsed;
25
+ }
26
+ function printJob(issue) {
27
+ const job = getJob(issue);
28
+ console.log(pc.bold(`\nCULT OS // ISSUE #${job.issueNumber}\n`));
29
+ console.log(`${pc.dim("ACP JOB")} ${job.jobId}`);
30
+ console.log(`${pc.dim("STATUS")} ${job.status.toUpperCase()}`);
31
+ console.log(`${pc.dim("PROVIDER")} ${job.provider}`);
32
+ console.log(`${pc.dim("NETWORK")} ${job.chainId}`);
33
+ if (job.budget) {
34
+ console.log(`${pc.dim("BUDGET")} ${job.budget} USDC`);
35
+ }
36
+ if (job.delivery) {
37
+ console.log(`${pc.dim("DELIVERY")} ${job.delivery.url}`);
38
+ }
39
+ console.log();
40
+ }
41
+ program
42
+ .name("cult")
43
+ .description("GitHub-native work for the agent economy.")
44
+ .version("0.1.0");
45
+ program.command("demo").description("Run the CultOS job-room demonstration").action(runDemo);
46
+ program.command("doctor").description("Check the local GitHub and ACP setup").action(runDoctor);
47
+ program
48
+ .command("inspect")
49
+ .argument("<issue>", "GitHub issue number or URL")
50
+ .option("-R, --repo <owner/name>", "GitHub repository")
51
+ .description("Build a Cult Work Contract from a GitHub issue")
52
+ .action((reference, options) => {
53
+ const repository = getRepository(options.repo);
54
+ const issue = getIssue(reference, options.repo);
55
+ const contract = createWorkContract({
56
+ repositoryUrl: repository.url,
57
+ issueUrl: issue.url,
58
+ baseRef: repository.defaultBranch,
59
+ title: issue.title,
60
+ body: issue.body
61
+ });
62
+ console.log(pc.bold(`\nIssue #${issue.number}`));
63
+ console.log(issue.title);
64
+ console.log(pc.dim(`\n${repository.nameWithOwner}\n`));
65
+ if (contract.acceptanceCriteria.length > 0) {
66
+ console.log(pc.bold("Acceptance criteria"));
67
+ for (const criterion of contract.acceptanceCriteria) {
68
+ console.log(`${pc.green("✓")} ${criterion}`);
69
+ }
70
+ console.log();
71
+ }
72
+ console.log(pc.bold("Cult Work Contract\n"));
73
+ console.log(JSON.stringify(contract, null, 2));
74
+ console.log();
75
+ });
76
+ program
77
+ .command("hire")
78
+ .argument("<issue>", "GitHub issue number")
79
+ .requiredOption("--provider <address>", "ACP provider wallet address")
80
+ .option("-R, --repo <owner/name>", "GitHub repository")
81
+ .option("--offering <name>", "ACP offering name")
82
+ .option("--chain <id>", "ACP chain ID", "8453")
83
+ .option("--expiry <seconds>", "Custom job expiry", "86400")
84
+ .description("Create an ACP job from a GitHub issue")
85
+ .action((value, options) => {
86
+ const number = issueNumber(value);
87
+ const existing = listJobs().find((job) => job.issueNumber === number);
88
+ if (existing) {
89
+ throw new Error(`Issue #${number} is already linked to ACP job ${existing.jobId}`);
90
+ }
91
+ const repository = getRepository(options.repo);
92
+ const issue = getIssue(value, options.repo);
93
+ const contract = createWorkContract({
94
+ repositoryUrl: repository.url,
95
+ issueUrl: issue.url,
96
+ baseRef: repository.defaultBranch,
97
+ title: issue.title,
98
+ body: issue.body
99
+ });
100
+ const provider = options.provider;
101
+ if (!provider) {
102
+ throw new Error("Provider address is required");
103
+ }
104
+ console.log(pc.dim("Creating ACP job..."));
105
+ const created = createJob({
106
+ provider,
107
+ ...(options.offering ? { offering: options.offering } : {}),
108
+ chainId: chainId(options.chain ?? "8453"),
109
+ expiry: Number.parseInt(options.expiry ?? "86400", 10),
110
+ contract
111
+ });
112
+ const now = new Date().toISOString();
113
+ saveJob({
114
+ issueNumber: issue.number,
115
+ repository: repository.nameWithOwner,
116
+ contract,
117
+ provider,
118
+ ...(options.offering ? { offering: options.offering } : {}),
119
+ jobId: created.jobId,
120
+ chainId: created.chainId,
121
+ ...(created.protocol ? { protocol: created.protocol } : {}),
122
+ status: "open",
123
+ createdAt: now,
124
+ updatedAt: now
125
+ });
126
+ console.log(pc.green(`ACP job ${created.jobId} created for issue #${issue.number}.`));
127
+ console.log(pc.dim(`Run cult watch ${issue.number} to follow it.`));
128
+ });
129
+ program
130
+ .command("watch")
131
+ .argument("<issue>", "GitHub issue number")
132
+ .description("Wait until an ACP job needs attention")
133
+ .action((value) => {
134
+ const number = issueNumber(value);
135
+ const job = getJob(number);
136
+ console.log(pc.dim(`Watching ACP job ${job.jobId}...`));
137
+ const watched = watchJob(job.jobId);
138
+ const update = { status: watched.status };
139
+ if (watched.budget) {
140
+ update.budget = watched.budget;
141
+ }
142
+ if (watched.deliverable) {
143
+ try {
144
+ update.delivery = parsePullRequestDelivery(watched.deliverable);
145
+ }
146
+ catch {
147
+ console.log(pc.yellow("Provider submitted a deliverable that is not a CultOS pull request."));
148
+ }
149
+ }
150
+ updateJob(number, update);
151
+ printJob(number);
152
+ if (watched.availableTools.length > 0) {
153
+ console.log(pc.dim(`Available: ${watched.availableTools.join(", ")}\n`));
154
+ }
155
+ });
156
+ program
157
+ .command("fund")
158
+ .argument("<issue>", "GitHub issue number")
159
+ .description("Fund the quoted ACP job")
160
+ .action((value) => {
161
+ const number = issueNumber(value);
162
+ const job = getJob(number);
163
+ if (!job.budget) {
164
+ throw new Error(`No provider quote found. Run cult watch ${number} first.`);
165
+ }
166
+ fundJob(job.jobId, job.chainId, job.budget);
167
+ updateJob(number, { status: "funded" });
168
+ console.log(pc.green(`\nACP job ${job.jobId} funded with ${job.budget} USDC.\n`));
169
+ });
170
+ program
171
+ .command("message")
172
+ .argument("<issue>", "GitHub issue number")
173
+ .argument("<content>", "Message text")
174
+ .description("Send a message to the ACP job room")
175
+ .action((value, content) => {
176
+ const job = getJob(issueNumber(value));
177
+ sendMessage(job.jobId, job.chainId, content);
178
+ console.log(pc.green("\nMessage sent.\n"));
179
+ });
180
+ program
181
+ .command("quote")
182
+ .requiredOption("--job <id>", "ACP job ID")
183
+ .requiredOption("--amount <usdc>", "Service price in USDC")
184
+ .option("--chain <id>", "ACP chain ID", "8453")
185
+ .description("Set a provider quote for an ACP job")
186
+ .action((options) => {
187
+ quoteJob(options.job, chainId(options.chain), options.amount);
188
+ console.log(pc.green(`\nQuoted ${options.amount} USDC for ACP job ${options.job}.\n`));
189
+ });
190
+ program
191
+ .command("deliver")
192
+ .requiredOption("--job <id>", "ACP job ID")
193
+ .requiredOption("--pr <url>", "Delivered GitHub pull request")
194
+ .option("--chain <id>", "ACP chain ID", "8453")
195
+ .description("Submit a pull request as an ACP provider")
196
+ .action((options) => {
197
+ const pullRequest = getPullRequest(options.pr);
198
+ const delivery = createPullRequestDelivery(pullRequest.url, pullRequest.headSha);
199
+ submitJob(options.job, chainId(options.chain), delivery);
200
+ console.log(pc.green(`\nDelivered PR #${pullRequest.number} at ${pullRequest.headSha.slice(0, 12)}.\n`));
201
+ });
202
+ program
203
+ .command("verify")
204
+ .argument("<issue>", "GitHub issue number")
205
+ .description("Verify the delivered pull request and CI")
206
+ .action((value) => {
207
+ const number = issueNumber(value);
208
+ const result = verifyJob(getJob(number));
209
+ console.log(pc.bold(`\nCULT OS // VERIFY PR #${result.pullRequest}\n`));
210
+ for (const check of result.checks) {
211
+ const marker = ["pass", "skipping"].includes(check.bucket) ? pc.green("●") : pc.red("●");
212
+ console.log(`${marker} ${check.name} ${pc.dim(check.state)}`);
213
+ }
214
+ if (result.passed) {
215
+ console.log(pc.green(`\nVerified at ${result.headSha.slice(0, 12)}.\n`));
216
+ updateJob(number, { status: "verified" });
217
+ return;
218
+ }
219
+ console.log(pc.red("\nVerification failed:"));
220
+ for (const failure of result.failures) {
221
+ console.log(`- ${failure}`);
222
+ }
223
+ console.log();
224
+ process.exitCode = 1;
225
+ });
226
+ program
227
+ .command("settle")
228
+ .argument("<issue>", "GitHub issue number")
229
+ .option("--approve", "Approve the delivery")
230
+ .option("--reject", "Reject the delivery")
231
+ .option("--reason <text>", "Settlement reason", "Work reviewed through CultOS")
232
+ .description("Complete or reject an ACP job and publish its receipt")
233
+ .action((value, options) => {
234
+ const number = issueNumber(value);
235
+ const job = getJob(number);
236
+ if (options.approve === options.reject) {
237
+ throw new Error("Choose either --approve or --reject");
238
+ }
239
+ if (options.approve && job.status !== "verified") {
240
+ throw new Error(`Run cult verify ${number} before approving settlement`);
241
+ }
242
+ const outcome = options.approve ? "completed" : "rejected";
243
+ if (options.approve) {
244
+ completeJob(job.jobId, job.chainId, options.reason);
245
+ }
246
+ else {
247
+ rejectJob(job.jobId, job.chainId, options.reason);
248
+ }
249
+ updateJob(number, { status: outcome });
250
+ const receipt = [
251
+ `<!-- cultos-job:${job.chainId}:${job.jobId} -->`,
252
+ "### CultOS receipt",
253
+ "",
254
+ "| | |",
255
+ "|---|---|",
256
+ `| ACP job | \`${job.jobId}\` |`,
257
+ `| Provider | \`${job.provider}\` |`,
258
+ `| Result | **${outcome}** |`,
259
+ ...(job.budget ? [`| Settlement | ${job.budget} USDC |`] : []),
260
+ ...(job.delivery
261
+ ? [`| Delivery | ${job.delivery.url} |`, `| Commit | \`${job.delivery.headSha}\` |`]
262
+ : [])
263
+ ].join("\n");
264
+ commentOnIssue(number, receipt);
265
+ console.log(pc.green(`\nACP job ${job.jobId} ${outcome}. Receipt posted to issue #${number}.\n`));
266
+ });
267
+ program
268
+ .command("jobs")
269
+ .description("List jobs linked to the current repository")
270
+ .action(() => {
271
+ const jobs = listJobs();
272
+ if (jobs.length === 0) {
273
+ console.log(pc.dim("\nNo CultOS jobs yet.\n"));
274
+ return;
275
+ }
276
+ console.log(pc.bold("\nCULT OS // JOBS\n"));
277
+ for (const job of jobs) {
278
+ console.log(`#${String(job.issueNumber).padEnd(6)} ${job.status.padEnd(12)} ACP ${job.jobId}`);
279
+ }
280
+ console.log();
281
+ });
282
+ program.parseAsync().catch((error) => {
283
+ const message = error instanceof Error ? error.message : String(error);
284
+ console.error(pc.red(`\n${message}\n`));
285
+ process.exitCode = 1;
286
+ });
287
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export declare const workContractKind: "cultos.github.issue.v1";
2
+ export declare const pullRequestDeliveryKind: "cultos.github.pull-request.v1";
3
+ export interface IssueWorkContract {
4
+ kind: typeof workContractKind;
5
+ repository: string;
6
+ issue: string;
7
+ baseRef: string;
8
+ title: string;
9
+ acceptanceCriteria: string[];
10
+ delivery: {
11
+ type: "github.pull_request";
12
+ };
13
+ }
14
+ export interface PullRequestDelivery {
15
+ kind: typeof pullRequestDeliveryKind;
16
+ url: string;
17
+ headSha: string;
18
+ }
19
+ interface ContractInput {
20
+ repositoryUrl: string;
21
+ issueUrl: string;
22
+ baseRef: string;
23
+ title: string;
24
+ body: string;
25
+ }
26
+ export declare function extractAcceptanceCriteria(body: string): string[];
27
+ export declare function createWorkContract(input: ContractInput): IssueWorkContract;
28
+ export declare function createPullRequestDelivery(url: string, headSha: string): PullRequestDelivery;
29
+ export declare function parsePullRequestDelivery(value: unknown): PullRequestDelivery;
30
+ export {};
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ export const workContractKind = "cultos.github.issue.v1";
3
+ export const pullRequestDeliveryKind = "cultos.github.pull-request.v1";
4
+ const pullRequestDeliverySchema = z.object({
5
+ kind: z.literal(pullRequestDeliveryKind),
6
+ url: z.url(),
7
+ headSha: z.string().min(7)
8
+ });
9
+ const checkboxPattern = /^\s*[-*]\s+\[[ xX]\]\s+(.+)$/;
10
+ const bulletPattern = /^\s*[-*]\s+(.+)$/;
11
+ const headingPattern = /^#{1,6}\s+(.+)$/;
12
+ export function extractAcceptanceCriteria(body) {
13
+ const lines = body.split(/\r?\n/);
14
+ const checkboxes = lines
15
+ .map((line) => line.match(checkboxPattern)?.[1]?.trim())
16
+ .filter((line) => Boolean(line));
17
+ if (checkboxes.length > 0) {
18
+ return checkboxes;
19
+ }
20
+ const criteria = [];
21
+ let inAcceptanceSection = false;
22
+ for (const line of lines) {
23
+ const heading = line.match(headingPattern)?.[1]?.trim().toLowerCase();
24
+ if (heading) {
25
+ if (inAcceptanceSection) {
26
+ break;
27
+ }
28
+ inAcceptanceSection = /acceptance|definition of done/.test(heading);
29
+ continue;
30
+ }
31
+ if (!inAcceptanceSection) {
32
+ continue;
33
+ }
34
+ const criterion = line.match(bulletPattern)?.[1]?.trim();
35
+ if (criterion) {
36
+ criteria.push(criterion);
37
+ }
38
+ }
39
+ return criteria;
40
+ }
41
+ export function createWorkContract(input) {
42
+ return {
43
+ kind: workContractKind,
44
+ repository: input.repositoryUrl,
45
+ issue: input.issueUrl,
46
+ baseRef: input.baseRef,
47
+ title: input.title,
48
+ acceptanceCriteria: extractAcceptanceCriteria(input.body),
49
+ delivery: {
50
+ type: "github.pull_request"
51
+ }
52
+ };
53
+ }
54
+ export function createPullRequestDelivery(url, headSha) {
55
+ return {
56
+ kind: pullRequestDeliveryKind,
57
+ url,
58
+ headSha
59
+ };
60
+ }
61
+ export function parsePullRequestDelivery(value) {
62
+ const input = typeof value === "string" ? JSON.parse(value) : value;
63
+ return pullRequestDeliverySchema.parse(input);
64
+ }
65
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
package/dist/demo.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function runDemo(): Promise<void>;
package/dist/demo.js ADDED
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, render } from "ink";
3
+ const events = [
4
+ ["21:04", "JOB CREATED"],
5
+ ["21:05", "BUDGET SET"],
6
+ ["21:06", "ESCROW FUNDED"],
7
+ ["21:14", "PR #47 DELIVERED"],
8
+ ["21:16", "CI PASSED"],
9
+ ["21:18", "MERGED // PAYMENT RELEASED"]
10
+ ];
11
+ function Field({ label, value }) {
12
+ return (_jsxs(Box, { children: [_jsx(Box, { width: 12, children: _jsx(Text, { dimColor: true, children: label }) }), _jsx(Text, { bold: true, children: value })] }));
13
+ }
14
+ function Demo() {
15
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { borderStyle: "single", borderColor: "magenta", flexDirection: "column", paddingX: 2, width: 56, children: [_jsx(Text, { bold: true, color: "magenta", children: "CULT OS // JOB 813" }), _jsx(Text, { children: " " }), _jsx(Field, { label: "ISSUE", value: "#42 Fix wallet balance parsing" }), _jsx(Field, { label: "PROVIDER", value: "0x7A3F...91C2" }), _jsx(Field, { label: "ESCROW", value: "2.00 USDC" }), _jsx(Field, { label: "NETWORK", value: "BASE" }), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, color: "magenta", children: "TRANSMISSION" }), _jsx(Text, { children: " " }), events.map(([time, event]) => (_jsxs(Box, { children: [_jsx(Box, { width: 8, children: _jsx(Text, { dimColor: true, children: time }) }), _jsx(Text, { color: "green", children: "\u25CF " }), _jsx(Text, { children: event })] }, event))), _jsx(Text, { children: " " })] }), _jsx(Text, { children: " " }), _jsx(Text, { children: "GitHub has issues. Virtuals has agents." }), _jsx(Text, { bold: true, color: "magenta", children: "CultOS makes them work for each other." })] }));
16
+ }
17
+ export async function runDemo() {
18
+ const instance = render(_jsx(Demo, {}));
19
+ await instance.waitUntilExit();
20
+ }
21
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAExC,MAAM,MAAM,GAAG;IACb,CAAC,OAAO,EAAE,aAAa,CAAC;IACxB,CAAC,OAAO,EAAE,YAAY,CAAC;IACvB,CAAC,OAAO,EAAE,eAAe,CAAC;IAC1B,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAC7B,CAAC,OAAO,EAAE,WAAW,CAAC;IACtB,CAAC,OAAO,EAAE,4BAA4B,CAAC;CAC/B,CAAC;AAEX,SAAS,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAoC;IAC/D,OAAO,CACL,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,KAAK,EAAE,EAAE,YACZ,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,GACzB,EACN,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,IACrB,CACP,CAAC;AACJ,CAAC;AAED,SAAS,IAAI;IACX,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,GAAG,IAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAC,SAAS,EAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,aAC3F,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,SAAS,mCAEnB,EACP,KAAC,IAAI,oBAAS,EACd,KAAC,KAAK,IAAC,KAAK,EAAC,OAAO,EAAC,KAAK,EAAC,gCAAgC,GAAG,EAC9D,KAAC,KAAK,IAAC,KAAK,EAAC,UAAU,EAAC,KAAK,EAAC,eAAe,GAAG,EAChD,KAAC,KAAK,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAC,WAAW,GAAG,EAC1C,KAAC,KAAK,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAC,MAAM,GAAG,EACtC,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,SAAS,6BAEnB,EACP,KAAC,IAAI,oBAAS,EACb,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAC7B,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,KAAK,EAAE,CAAC,YACX,KAAC,IAAI,IAAC,QAAQ,kBAAE,IAAI,GAAQ,GACxB,EACN,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,wBAAU,EAC7B,KAAC,IAAI,cAAE,KAAK,GAAQ,KALZ,KAAK,CAMT,CACP,CAAC,EACF,KAAC,IAAI,oBAAS,IACV,EACN,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,0DAA+C,EACpD,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,SAAS,uDAEnB,IACH,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAC,IAAI,KAAG,CAAC,CAAC;IAClC,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function runDoctor(): void;
package/dist/doctor.js ADDED
@@ -0,0 +1,75 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import pc from "picocolors";
3
+ import { commandExists, githubIsAuthenticated } from "./github.js";
4
+ function repositoryCheck() {
5
+ const result = spawnSync("git", ["rev-parse", "--show-toplevel"], {
6
+ encoding: "utf8"
7
+ });
8
+ return {
9
+ name: "Repository",
10
+ ok: result.status === 0,
11
+ detail: result.status === 0 ? result.stdout.trim() : "not inside a Git repository"
12
+ };
13
+ }
14
+ function acpChecks(hasAcp) {
15
+ if (!hasAcp) {
16
+ return [
17
+ { name: "ACP CLI", ok: false, detail: "not installed" },
18
+ { name: "Agent", ok: false, detail: "unavailable" },
19
+ { name: "Signer", ok: false, detail: "unavailable" }
20
+ ];
21
+ }
22
+ const identity = spawnSync("acp", ["agent", "whoami", "--json"], {
23
+ encoding: "utf8"
24
+ });
25
+ if (identity.status !== 0) {
26
+ return [
27
+ { name: "ACP CLI", ok: true, detail: "installed" },
28
+ { name: "Agent", ok: false, detail: "authentication required" },
29
+ { name: "Signer", ok: false, detail: "unavailable" }
30
+ ];
31
+ }
32
+ const agent = JSON.parse(identity.stdout);
33
+ const signer = spawnSync("acp", ["agent", "signer-policy", "--json"], {
34
+ encoding: "utf8"
35
+ });
36
+ const signerState = signer.status === 0
37
+ ? JSON.parse(signer.stdout)
38
+ : {};
39
+ const hasSigner = Boolean(signerState.signerId)
40
+ || signerState.matched === true
41
+ || (signerState.signers?.length ?? 0) > 0;
42
+ const wallet = `${agent.walletAddress.slice(0, 6)}…${agent.walletAddress.slice(-4)}`;
43
+ return [
44
+ { name: "ACP CLI", ok: true, detail: "installed" },
45
+ { name: "Agent", ok: true, detail: `${agent.name} ${wallet}` },
46
+ { name: "Signer", ok: hasSigner, detail: hasSigner ? "ready" : "approval required" }
47
+ ];
48
+ }
49
+ export function runDoctor() {
50
+ const hasGitHub = commandExists("gh");
51
+ const hasAcp = commandExists("acp");
52
+ const hasGitHubAuth = hasGitHub && githubIsAuthenticated();
53
+ const checks = [
54
+ { name: "Node.js", ok: true, detail: process.version },
55
+ { name: "Git", ok: commandExists("git"), detail: "installed" },
56
+ {
57
+ name: "GitHub CLI",
58
+ ok: hasGitHubAuth,
59
+ detail: hasGitHubAuth ? "authenticated" : hasGitHub ? "authentication required" : "not installed"
60
+ },
61
+ ...acpChecks(hasAcp),
62
+ repositoryCheck()
63
+ ];
64
+ console.log(pc.bold("\nCULT OS // SYSTEM CHECK\n"));
65
+ for (const check of checks) {
66
+ const marker = check.ok ? pc.green("●") : pc.yellow("○");
67
+ const status = check.ok ? pc.dim(check.detail) : pc.yellow(check.detail);
68
+ console.log(`${marker} ${check.name.padEnd(14)} ${status}`);
69
+ }
70
+ const unresolved = checks.filter((check) => !check.ok).length;
71
+ console.log(unresolved === 0
72
+ ? pc.green("\nSystem ready.\n")
73
+ : pc.yellow(`\n${unresolved} ${unresolved === 1 ? "action" : "actions"} required before live jobs.\n`));
74
+ }
75
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export interface GitHubIssue {
2
+ number: number;
3
+ title: string;
4
+ body: string;
5
+ url: string;
6
+ }
7
+ export interface GitHubRepository {
8
+ nameWithOwner: string;
9
+ url: string;
10
+ defaultBranch: string;
11
+ }
12
+ export interface GitHubPullRequest {
13
+ number: number;
14
+ url: string;
15
+ state: string;
16
+ headSha: string;
17
+ baseRef: string;
18
+ }
19
+ export interface GitHubCheck {
20
+ name: string;
21
+ state: string;
22
+ bucket: string;
23
+ link?: string | undefined;
24
+ }
25
+ export declare function getIssue(reference: string, repository?: string): GitHubIssue;
26
+ export declare function getRepository(reference?: string): GitHubRepository;
27
+ export declare function commandExists(command: string): boolean;
28
+ export declare function githubIsAuthenticated(): boolean;
29
+ export declare function getPullRequest(reference: string): GitHubPullRequest;
30
+ export declare function getPullRequestChecks(reference: string): GitHubCheck[];
31
+ export declare function commentOnIssue(issueNumber: number, body: string): void;