@cultos/cli 0.2.4 → 0.3.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/README.md +11 -16
- package/dist/bbs.js +5 -5
- package/dist/bbs.js.map +1 -1
- package/dist/cli.js +58 -35
- package/dist/cli.js.map +1 -1
- package/dist/contract.d.ts +8 -4
- package/dist/contract.js +9 -6
- package/dist/contract.js.map +1 -1
- package/dist/doctor.js +20 -6
- package/dist/doctor.js.map +1 -1
- package/dist/gitlawb.d.ts +12 -0
- package/dist/gitlawb.js +175 -0
- package/dist/gitlawb.js.map +1 -0
- package/dist/repository.d.ts +34 -0
- package/dist/repository.js +44 -0
- package/dist/repository.js.map +1 -0
- package/dist/start.d.ts +8 -0
- package/dist/start.js +303 -0
- package/dist/start.js.map +1 -0
- package/dist/state.d.ts +3 -3
- package/dist/state.js +12 -7
- package/dist/state.js.map +1 -1
- package/dist/verify.d.ts +3 -3
- package/dist/verify.js +4 -4
- package/dist/verify.js.map +1 -1
- package/package.json +3 -2
package/dist/start.js
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { createInterface } from "node:readline/promises";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { runBbs } from "./bbs.js";
|
|
6
|
+
import { parseGitLawbRemote } from "./gitlawb.js";
|
|
7
|
+
const agentSchema = z.object({
|
|
8
|
+
id: z.string(),
|
|
9
|
+
name: z.string(),
|
|
10
|
+
walletAddress: z.string()
|
|
11
|
+
}).passthrough();
|
|
12
|
+
const agentListSchema = z.object({
|
|
13
|
+
data: z.array(agentSchema)
|
|
14
|
+
}).passthrough();
|
|
15
|
+
const activeAgentSchema = z.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
name: z.string(),
|
|
18
|
+
walletAddress: z.string()
|
|
19
|
+
}).passthrough();
|
|
20
|
+
const signerSchema = z.object({
|
|
21
|
+
matched: z.boolean().optional(),
|
|
22
|
+
signerId: z.string().optional(),
|
|
23
|
+
policy: z.string().optional()
|
|
24
|
+
}).passthrough();
|
|
25
|
+
function captured(command, args, timeout = 15_000) {
|
|
26
|
+
const result = spawnSync(command, args, {
|
|
27
|
+
encoding: "utf8",
|
|
28
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
29
|
+
timeout
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
status: result.status ?? 1,
|
|
33
|
+
stdout: result.stdout ?? "",
|
|
34
|
+
stderr: result.stderr ?? result.error?.message ?? ""
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function interactive(command, args, timeout) {
|
|
38
|
+
const result = spawnSync(command, args, {
|
|
39
|
+
stdio: "inherit",
|
|
40
|
+
...(timeout ? { timeout } : {})
|
|
41
|
+
});
|
|
42
|
+
return result.status === 0;
|
|
43
|
+
}
|
|
44
|
+
function exists(command) {
|
|
45
|
+
return captured(command, ["--version"]).status === 0;
|
|
46
|
+
}
|
|
47
|
+
function parseJson(value) {
|
|
48
|
+
return JSON.parse(value.trim());
|
|
49
|
+
}
|
|
50
|
+
function parsed(schema, value) {
|
|
51
|
+
try {
|
|
52
|
+
return schema.parse(parseJson(value));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function authenticationRequired(result) {
|
|
59
|
+
return /NOT_AUTHENTICATED|not authenticated|acp configure/i.test(`${result.stdout}\n${result.stderr}`);
|
|
60
|
+
}
|
|
61
|
+
function signerMissing(result) {
|
|
62
|
+
return /NO_SIGNER|no signer configured/i.test(`${result.stdout}\n${result.stderr}`);
|
|
63
|
+
}
|
|
64
|
+
function githubRepository(remote) {
|
|
65
|
+
return remote.trim().match(/github\.com[/:]([^/]+\/[^/]+?)(?:\.git)?$/)?.[1];
|
|
66
|
+
}
|
|
67
|
+
function hasSigner(value) {
|
|
68
|
+
const signer = parsed(signerSchema, value);
|
|
69
|
+
return Boolean(signer?.signerId)
|
|
70
|
+
|| signer?.matched === true;
|
|
71
|
+
}
|
|
72
|
+
function signerPolicy(value) {
|
|
73
|
+
return parsed(signerSchema, value)?.policy ?? "ready";
|
|
74
|
+
}
|
|
75
|
+
function verifySigner() {
|
|
76
|
+
return captured("acp", [
|
|
77
|
+
"wallet",
|
|
78
|
+
"sign-message",
|
|
79
|
+
"--message",
|
|
80
|
+
"CultOS readiness check",
|
|
81
|
+
"--chain-id",
|
|
82
|
+
"8453",
|
|
83
|
+
"--json"
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
async function defaultConfirm(question) {
|
|
87
|
+
const prompt = createInterface({ input: process.stdin, output: process.stdout });
|
|
88
|
+
try {
|
|
89
|
+
const answer = await prompt.question(`${question} [Y/n] `);
|
|
90
|
+
return !["n", "no"].includes(answer.trim().toLowerCase());
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
prompt.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function defaultWait() {
|
|
97
|
+
const prompt = createInterface({ input: process.stdin, output: process.stdout });
|
|
98
|
+
try {
|
|
99
|
+
await prompt.question("Press ENTER to open CultOS. ");
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
prompt.close();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function stage(index, label) {
|
|
106
|
+
console.log(`\n${pc.cyan(`[${index}/5]`)} ${pc.bold(label)}`);
|
|
107
|
+
}
|
|
108
|
+
function action(detail) {
|
|
109
|
+
console.log(`${pc.yellow("○")} ${detail}`);
|
|
110
|
+
}
|
|
111
|
+
function fail(detail, recovery) {
|
|
112
|
+
console.log(`${pc.red("×")} ${detail}`);
|
|
113
|
+
if (recovery)
|
|
114
|
+
console.log(pc.dim(recovery));
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
function paused() {
|
|
118
|
+
console.log(pc.yellow("\nSETUP PAUSED\n"));
|
|
119
|
+
console.log(pc.dim("Run cult start to continue.\n"));
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
export async function runStart(options = {}) {
|
|
123
|
+
if (!options.allowNonInteractive && (!process.stdin.isTTY || !process.stdout.isTTY)) {
|
|
124
|
+
return fail("cult start requires an interactive terminal");
|
|
125
|
+
}
|
|
126
|
+
const confirm = options.confirm ?? defaultConfirm;
|
|
127
|
+
const wait = options.wait ?? defaultWait;
|
|
128
|
+
const launch = options.launch ?? runBbs;
|
|
129
|
+
console.log(pc.bold("\n╞ CULT OS ╡ START\n"));
|
|
130
|
+
console.log(pc.dim("BOOT SEQUENCE"));
|
|
131
|
+
stage(1, "REPOSITORY");
|
|
132
|
+
if (!exists("git"))
|
|
133
|
+
return fail("Git is not installed", "Install Git, then run cult start again.");
|
|
134
|
+
const root = captured("git", ["rev-parse", "--show-toplevel"]);
|
|
135
|
+
if (root.status !== 0)
|
|
136
|
+
return fail("Not inside a Git repository", "Open a repository, then run cult start again.");
|
|
137
|
+
const remote = captured("git", ["remote", "get-url", "origin"]);
|
|
138
|
+
const remoteRepository = githubRepository(remote.stdout);
|
|
139
|
+
const gitlawbRepository = parseGitLawbRemote(remote.stdout);
|
|
140
|
+
if (remote.status !== 0 || (!remoteRepository && !gitlawbRepository)) {
|
|
141
|
+
return fail("The origin remote is not a supported repository");
|
|
142
|
+
}
|
|
143
|
+
console.log(`${pc.green("●")} ${remoteRepository ?? `${gitlawbRepository?.owner}/${gitlawbRepository?.repository}`}`);
|
|
144
|
+
let repositoryName;
|
|
145
|
+
if (gitlawbRepository) {
|
|
146
|
+
stage(2, "GITLAWB");
|
|
147
|
+
if (!exists("gl")) {
|
|
148
|
+
action("GitLawb CLI is not installed");
|
|
149
|
+
if (!await confirm("Install the GitLawb CLI now?"))
|
|
150
|
+
return paused();
|
|
151
|
+
if (!interactive("npm", ["install", "-g", "@gitlawb/gl"], 5 * 60_000)) {
|
|
152
|
+
return fail("GitLawb CLI installation failed");
|
|
153
|
+
}
|
|
154
|
+
if (!exists("gl"))
|
|
155
|
+
return fail("GitLawb CLI is still unavailable after installation");
|
|
156
|
+
}
|
|
157
|
+
if (captured("gl", ["identity", "show"]).status !== 0) {
|
|
158
|
+
action("GitLawb identity required");
|
|
159
|
+
if (!await confirm("Create and register a GitLawb identity now?"))
|
|
160
|
+
return paused();
|
|
161
|
+
if (!interactive("gl", ["identity", "new"]))
|
|
162
|
+
return fail("GitLawb identity creation failed");
|
|
163
|
+
if (!interactive("gl", ["register"]))
|
|
164
|
+
return fail("GitLawb registration failed");
|
|
165
|
+
}
|
|
166
|
+
const reference = `${gitlawbRepository.owner.replace(/^did:key:/, "")}/${gitlawbRepository.repository}`;
|
|
167
|
+
const repository = captured("gl", ["repo", "info", reference]);
|
|
168
|
+
if (repository.status !== 0)
|
|
169
|
+
return fail("GitLawb cannot access this repository", repository.stderr.trim());
|
|
170
|
+
repositoryName = reference;
|
|
171
|
+
console.log(`${pc.green("●")} ${repositoryName}`);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
stage(2, "GITHUB");
|
|
175
|
+
if (!exists("gh")) {
|
|
176
|
+
return fail("GitHub CLI is not installed", "Install it from https://cli.github.com, then run cult start again.");
|
|
177
|
+
}
|
|
178
|
+
if (captured("gh", ["auth", "status"]).status !== 0) {
|
|
179
|
+
action("GitHub authentication required");
|
|
180
|
+
if (!await confirm("Sign in to GitHub now?"))
|
|
181
|
+
return paused();
|
|
182
|
+
if (!interactive("gh", ["auth", "login"]))
|
|
183
|
+
return fail("GitHub authentication was not completed");
|
|
184
|
+
if (captured("gh", ["auth", "status"]).status !== 0) {
|
|
185
|
+
return fail("GitHub authentication was not completed");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const repository = captured("gh", ["repo", "view", "--json", "nameWithOwner"]);
|
|
189
|
+
if (repository.status !== 0)
|
|
190
|
+
return fail("GitHub cannot access this repository", repository.stderr.trim());
|
|
191
|
+
const repositoryResult = parsed(z.object({ nameWithOwner: z.string() }), repository.stdout);
|
|
192
|
+
if (!repositoryResult)
|
|
193
|
+
return fail("GitHub returned an unreadable repository response");
|
|
194
|
+
repositoryName = repositoryResult.nameWithOwner;
|
|
195
|
+
console.log(`${pc.green("●")} ${repositoryName}`);
|
|
196
|
+
}
|
|
197
|
+
stage(3, "ACP");
|
|
198
|
+
if (!exists("acp")) {
|
|
199
|
+
action("ACP CLI is not installed");
|
|
200
|
+
if (!await confirm("Install the Virtuals ACP CLI now?"))
|
|
201
|
+
return paused();
|
|
202
|
+
if (!interactive("npm", ["install", "-g", "@virtuals-protocol/acp-cli"], 5 * 60_000)) {
|
|
203
|
+
return fail("ACP CLI installation failed");
|
|
204
|
+
}
|
|
205
|
+
if (!exists("acp"))
|
|
206
|
+
return fail("ACP CLI is still unavailable after installation");
|
|
207
|
+
}
|
|
208
|
+
let agents = captured("acp", ["agent", "list", "--json"]);
|
|
209
|
+
if (agents.status !== 0) {
|
|
210
|
+
if (!authenticationRequired(agents))
|
|
211
|
+
return fail("ACP is unavailable", agents.stderr.trim());
|
|
212
|
+
action("ACP authentication required");
|
|
213
|
+
if (!await confirm("Sign in to ACP now?"))
|
|
214
|
+
return paused();
|
|
215
|
+
if (!interactive("acp", ["configure"]))
|
|
216
|
+
return fail("ACP authentication was not completed");
|
|
217
|
+
agents = captured("acp", ["agent", "list", "--json"]);
|
|
218
|
+
}
|
|
219
|
+
if (agents.status !== 0)
|
|
220
|
+
return fail("ACP is unavailable", agents.stderr.trim());
|
|
221
|
+
const firstAgentList = parsed(agentListSchema, agents.stdout);
|
|
222
|
+
if (!firstAgentList)
|
|
223
|
+
return fail("ACP returned an unreadable agent list");
|
|
224
|
+
const agentList = firstAgentList.data;
|
|
225
|
+
console.log(`${pc.green("●")} connected`);
|
|
226
|
+
stage(4, "AGENT");
|
|
227
|
+
if (agentList.length === 0) {
|
|
228
|
+
action("No ACP agent found");
|
|
229
|
+
if (!await confirm("Create an ACP agent with a restricted signer?"))
|
|
230
|
+
return paused();
|
|
231
|
+
if (!interactive("acp", ["agent", "create", "--signer", "--policy", "restricted"])) {
|
|
232
|
+
return fail("Agent creation was not completed");
|
|
233
|
+
}
|
|
234
|
+
agents = captured("acp", ["agent", "list", "--json"]);
|
|
235
|
+
if (agents.status !== 0)
|
|
236
|
+
return fail("Unable to confirm the new ACP agent");
|
|
237
|
+
const createdAgentList = parsed(agentListSchema, agents.stdout);
|
|
238
|
+
if (!createdAgentList || createdAgentList.data.length === 0) {
|
|
239
|
+
return fail("Unable to confirm the new ACP agent");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
let active = captured("acp", ["agent", "whoami", "--json"]);
|
|
243
|
+
if (active.status !== 0) {
|
|
244
|
+
if (!interactive("acp", ["agent", "use"]))
|
|
245
|
+
return fail("No ACP agent was selected");
|
|
246
|
+
active = captured("acp", ["agent", "whoami", "--json"]);
|
|
247
|
+
}
|
|
248
|
+
if (active.status !== 0)
|
|
249
|
+
return fail("Unable to read the active ACP agent");
|
|
250
|
+
const agent = parsed(activeAgentSchema, active.stdout);
|
|
251
|
+
if (!agent)
|
|
252
|
+
return fail("ACP returned an unreadable active agent");
|
|
253
|
+
console.log(`${pc.green("●")} ${agent.name}`);
|
|
254
|
+
console.log(pc.dim(` ${agent.walletAddress}`));
|
|
255
|
+
stage(5, "SIGNER");
|
|
256
|
+
let signer = captured("acp", ["agent", "signer-policy", "--agent-id", agent.id, "--json"]);
|
|
257
|
+
if (signer.status !== 0)
|
|
258
|
+
return fail("Unable to read the ACP signer", signer.stderr.trim());
|
|
259
|
+
let signerReady = hasSigner(signer.stdout);
|
|
260
|
+
let signatureVerified = false;
|
|
261
|
+
if (signerReady) {
|
|
262
|
+
const signature = verifySigner();
|
|
263
|
+
if (signature.status !== 0 && !signerMissing(signature)) {
|
|
264
|
+
return fail("Unable to verify the ACP signer", signature.stderr.trim());
|
|
265
|
+
}
|
|
266
|
+
signatureVerified = signature.status === 0;
|
|
267
|
+
signerReady = signatureVerified;
|
|
268
|
+
}
|
|
269
|
+
if (!signerReady) {
|
|
270
|
+
action("Signer approval required");
|
|
271
|
+
if (!await confirm("Add a restricted ACP signer?"))
|
|
272
|
+
return paused();
|
|
273
|
+
if (!interactive("acp", [
|
|
274
|
+
"agent",
|
|
275
|
+
"add-signer",
|
|
276
|
+
"--agent-id",
|
|
277
|
+
agent.id,
|
|
278
|
+
"--policy",
|
|
279
|
+
"restricted"
|
|
280
|
+
])) {
|
|
281
|
+
return fail("Signer approval was not completed");
|
|
282
|
+
}
|
|
283
|
+
signer = captured("acp", ["agent", "signer-policy", "--agent-id", agent.id, "--json"]);
|
|
284
|
+
if (signer.status !== 0 || !hasSigner(signer.stdout)) {
|
|
285
|
+
return fail("Unable to confirm the ACP signer");
|
|
286
|
+
}
|
|
287
|
+
const signature = verifySigner();
|
|
288
|
+
signatureVerified = signature.status === 0;
|
|
289
|
+
if (!signatureVerified)
|
|
290
|
+
return fail("Unable to verify the ACP signer", signature.stderr.trim());
|
|
291
|
+
}
|
|
292
|
+
if (!signatureVerified)
|
|
293
|
+
return fail("Unable to verify the ACP signer");
|
|
294
|
+
console.log(`${pc.green("●")} ${signerPolicy(signer.stdout)}`);
|
|
295
|
+
console.log(pc.green(pc.bold("\nSYSTEM READY\n")));
|
|
296
|
+
console.log(`${pc.dim("REPOSITORY")} ${repositoryName}`);
|
|
297
|
+
console.log(`${pc.dim("AGENT")} ${agent.name}`);
|
|
298
|
+
console.log(`${pc.dim("NETWORK")} Base\n`);
|
|
299
|
+
await wait();
|
|
300
|
+
launch();
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IssueWorkContract, PullRequestDelivery } from "./contract.js";
|
|
2
2
|
export interface CultJob {
|
|
3
|
-
issueNumber: number;
|
|
3
|
+
issueNumber: number | string;
|
|
4
4
|
repository: string;
|
|
5
5
|
contract: IssueWorkContract;
|
|
6
6
|
provider: string;
|
|
@@ -23,6 +23,6 @@ export interface CultState {
|
|
|
23
23
|
export declare function parseCultState(value: unknown): CultState;
|
|
24
24
|
export declare function writeStateFile(path: string, state: CultState): void;
|
|
25
25
|
export declare function saveJob(job: CultJob): void;
|
|
26
|
-
export declare function getJob(issueNumber: number): CultJob;
|
|
27
|
-
export declare function updateJob(issueNumber: number, update: Partial<CultJob>): CultJob;
|
|
26
|
+
export declare function getJob(issueNumber: number | string): CultJob;
|
|
27
|
+
export declare function updateJob(issueNumber: number | string, update: Partial<CultJob>): CultJob;
|
|
28
28
|
export declare function listJobs(): CultJob[];
|
package/dist/state.js
CHANGED
|
@@ -4,21 +4,26 @@ import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "n
|
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
const workContractSchema = z.object({
|
|
7
|
-
kind: z.literal("cultos.github.issue.v1"),
|
|
8
|
-
repository: z.
|
|
9
|
-
issue: z.
|
|
7
|
+
kind: z.union([z.literal("cultos.github.issue.v1"), z.literal("cultos.gitlawb.issue.v1")]),
|
|
8
|
+
repository: z.string().min(1),
|
|
9
|
+
issue: z.string().min(1),
|
|
10
10
|
baseRef: z.string().min(1),
|
|
11
11
|
title: z.string().min(1),
|
|
12
12
|
acceptanceCriteria: z.array(z.string()),
|
|
13
|
-
delivery: z.object({
|
|
13
|
+
delivery: z.object({
|
|
14
|
+
type: z.union([z.literal("github.pull_request"), z.literal("gitlawb.pull_request")])
|
|
15
|
+
})
|
|
14
16
|
});
|
|
15
17
|
const deliverySchema = z.object({
|
|
16
|
-
kind: z.
|
|
17
|
-
|
|
18
|
+
kind: z.union([
|
|
19
|
+
z.literal("cultos.github.pull-request.v1"),
|
|
20
|
+
z.literal("cultos.gitlawb.pull-request.v1")
|
|
21
|
+
]),
|
|
22
|
+
url: z.string().min(1),
|
|
18
23
|
headSha: z.string().min(7)
|
|
19
24
|
});
|
|
20
25
|
const jobSchema = z.object({
|
|
21
|
-
issueNumber: z.number().int().positive(),
|
|
26
|
+
issueNumber: z.union([z.number().int().positive(), z.string().min(1)]),
|
|
22
27
|
repository: z.string().min(1),
|
|
23
28
|
contract: workContractSchema,
|
|
24
29
|
provider: z.string().min(1),
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0BxB,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/verify.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { CultJob } from "./state.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type RepositoryCheck, type RepositoryPullRequest } from "./repository.js";
|
|
3
3
|
export interface VerificationResult {
|
|
4
4
|
pullRequest: number;
|
|
5
5
|
url: string;
|
|
6
6
|
headSha: string;
|
|
7
|
-
checks:
|
|
7
|
+
checks: RepositoryCheck[];
|
|
8
8
|
passed: boolean;
|
|
9
9
|
failures: string[];
|
|
10
10
|
}
|
|
11
|
-
export declare function evaluateDelivery(job: CultJob, pullRequest:
|
|
11
|
+
export declare function evaluateDelivery(job: CultJob, pullRequest: RepositoryPullRequest, checks: RepositoryCheck[], requiredState?: "OPEN" | "MERGED"): VerificationResult;
|
|
12
12
|
export declare function verifyJob(job: CultJob, requiredState?: "OPEN" | "MERGED"): VerificationResult;
|
package/dist/verify.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRepositoryChecks, getRepositoryPullRequest } from "./repository.js";
|
|
2
2
|
export function evaluateDelivery(job, pullRequest, checks, requiredState = "OPEN") {
|
|
3
3
|
if (!job.delivery) {
|
|
4
4
|
throw new Error("The provider has not submitted a pull-request delivery");
|
|
5
5
|
}
|
|
6
6
|
const failures = [];
|
|
7
|
-
const repositoryPrefix = `${job.contract.repository}/pull
|
|
7
|
+
const repositoryPrefix = `${job.contract.repository}/pull`;
|
|
8
8
|
if (!pullRequest.url.startsWith(repositoryPrefix)) {
|
|
9
9
|
failures.push("Pull request belongs to a different repository");
|
|
10
10
|
}
|
|
@@ -40,8 +40,8 @@ export function verifyJob(job, requiredState = "OPEN") {
|
|
|
40
40
|
if (!job.delivery) {
|
|
41
41
|
throw new Error("The provider has not submitted a pull-request delivery");
|
|
42
42
|
}
|
|
43
|
-
const pullRequest =
|
|
44
|
-
const checks =
|
|
43
|
+
const pullRequest = getRepositoryPullRequest(job.delivery.url);
|
|
44
|
+
const checks = getRepositoryChecks(pullRequest);
|
|
45
45
|
return evaluateDelivery(job, pullRequest, checks, requiredState);
|
|
46
46
|
}
|
|
47
47
|
//# sourceMappingURL=verify.js.map
|
package/dist/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EAGzB,MAAM,iBAAiB,CAAC;AAWzB,MAAM,UAAU,gBAAgB,CAC9B,GAAY,EACZ,WAAkC,EAClC,MAAyB,EACzB,gBAAmC,MAAM;IAEzC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,gBAAgB,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,OAAO,CAAC;IAE3D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,WAAW,CAAC,OAAO,KAAK,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,wBAAwB,WAAW,CAAC,OAAO,cAAc,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,WAAW,CAAC,OAAO,KAAK,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,WAAW,CAAC,KAAK,KAAK,QAAQ,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACzE,CAAC;SAAM,IAAI,WAAW,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,wBAAwB,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,OAAO;QACL,WAAW,EAAE,WAAW,CAAC,MAAM;QAC/B,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,MAAM;QACN,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC7B,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,GAAY,EACZ,gBAAmC,MAAM;IAEzC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,WAAW,GAAG,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAChD,OAAO,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AACnE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cultos/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Repository work for the agent economy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cult": "dist/cli.js"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"virtuals",
|
|
22
22
|
"acp",
|
|
23
23
|
"github",
|
|
24
|
+
"gitlawb",
|
|
24
25
|
"agents",
|
|
25
26
|
"cli"
|
|
26
27
|
],
|