plures 1.9.1 → 1.11.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 +3 -1
- package/dist/{chunk-23ZYPCPM.js → chunk-WPSUIAVZ.js} +20 -1
- package/dist/cli.cjs +138 -5
- package/dist/cli.js +119 -5
- package/dist/index.cjs +20 -1
- package/dist/index.d.cts +80 -2
- package/dist/index.d.ts +80 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,9 @@ if (event.type === "task.completed" && event.data.result?.agreement === 1) {
|
|
|
48
48
|
- `plures.tasks.retrieve(id)`, `plures.tasks.list({ status?, limit?, starting_after?, app? })`, `plures.tasks.cancel(id)`
|
|
49
49
|
- `new Plures(key, { app: "support-agent" })` or `PLURES_APP`: send everything to one of your apps. `plures.apps.list()`, `.create({ name, id? })`, `.retrieve(id)`, `.update(id, { name?, id?, default? })`, `.del(id)`. Each app keeps its own tasks, ledger view, map and quality.
|
|
50
50
|
- `plures.maps.guide()`, `.retrieve(app)`, `.upload(app, map)`, `.setCheckpoint(app, id, status)`: the agent map, where your agent needs a person. Or run `npx plures map` in your repo: your own coding agent reads the code and only the map is sent.
|
|
51
|
-
- `plures.maps.createKey(app, { label? })`, `.keys(app)`, `.revokeKey(app, id)`: map keys for CI, which can only read and upload that app's map. `.workflow(app, branch?)` returns the GitHub Action that maps on every push; `npx plures map workflow` writes it to `.github/workflows/plures-map.yml`. Or use **Map with GitHub** on the app's map page and Plures opens the pull request for you. `plures.maps.startRun(app)` and `.runs(app)`: in CI with no Claude key, `npx plures map` starts a run where Plures runs Claude (first map free, then Claude's cost plus 30%, at most $5).
|
|
51
|
+
- `plures.maps.createKey(app, { label? })`, `.keys(app)`, `.revokeKey(app, id)`: map keys for CI, which can only read and upload that app's map. `.workflow(app, branch?)` returns the GitHub Action that maps on every push; `npx plures map workflow` writes it to `.github/workflows/plures-map.yml`. Or use **Map with GitHub** on the app's map page and Plures opens the pull request for you, then **Turn on mapping** merges it. `plures.maps.startRun(app)` and `.runs(app)`: in CI with no Claude key, `npx plures map` starts a run where Plures runs Claude (first map free, then Claude's cost plus 30%, at most $5).
|
|
52
|
+
- `npx plures map` shows each file as Claude Code reads it and sends the file names (never their contents) to Plures, so the map page shows the reading live and the map builds itself when it lands. `plures.maps.progress(app, { session, phase, events })` is the call behind it.
|
|
53
|
+
- `plures.github.repos()`, `.connect(app, "owner/repo")`, `.turnOn(app)`, `.status(app)`, `.disconnect(app)`: Map with GitHub from code. Plures sets the repo's map key secret and opens a pull request adding the workflow; `turnOn` merges it. Installing the Plures GitHub App needs a browser once (`install_url`). From a terminal: `npx plures map github connect`, then `npx plures map github on`.
|
|
52
54
|
- `plures.quality.sample({ rubric, output, input? })`: send every output; a share is graded by people against the rubric, with personal details taken out first. `plures.quality.rubrics.create({ name, question, options, sample_rate })`, `.retrieve(name)` (score by day, this week against the four before, drift), `.list()`, `.update()`, `.del()`. `plures.quality.compare({ release, input, a, b })` and `plures.quality.release(name)` for blind release checks. `plures.quality.export(rubric)` returns graded samples for evals or fine tuning.
|
|
53
55
|
- `plures.testMix.set({ unanimous: 70, split: 20, tie: 5, expired: 5 })`, `.get()`, `.clear()`: with a test key, makes a share of test tasks split, tie or expire at random so you can test routing to your team without changing your agent. A task can override it with `metadata.test_mix`, and `metadata.test_outcome` beats both.
|
|
54
56
|
- `plures.routing.get()`, `plures.routing.set({ groups, rules, team })`: named teams of your own people and rules by category, like `{ groups: [{ name: "Finance", emails: ["ap@acme.com"] }], rules: [{ category: "refunds", route: "team", group: "Finance" }] }`. What you send replaces what's there; the rest stays.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
var VERSION = "1.
|
|
2
|
+
var VERSION = "1.11.0";
|
|
3
3
|
var PluresError = class extends Error {
|
|
4
4
|
constructor(message, status, type) {
|
|
5
5
|
super(message);
|
|
@@ -109,12 +109,31 @@ var Plures = class {
|
|
|
109
109
|
/** Starts a map run where Plures runs Claude (CI with no Anthropic key). npx plures map does this. */
|
|
110
110
|
startRun: (app) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/map_runs`, {}),
|
|
111
111
|
runs: (app) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/map_runs`),
|
|
112
|
+
/** While mapping, which files the coding agent is reading, shown live on the map page. File names only. npx plures map does this. */
|
|
113
|
+
progress: (app, p) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/map/progress`, p),
|
|
112
114
|
/** The GitHub Actions workflow that maps a repo on every push to its main branch. */
|
|
113
115
|
workflow: async (app, branch = "main") => {
|
|
114
116
|
const r = await fetch(`${this.base}/api/v1/map_workflow?app=${encodeURIComponent(app)}&branch=${encodeURIComponent(branch)}`);
|
|
115
117
|
return r.text();
|
|
116
118
|
}
|
|
117
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Map with GitHub: Plures adds a workflow to your repo by pull request and keeps the app's map
|
|
122
|
+
* current on every push. Installing the Plures GitHub App needs a browser once (installUrl);
|
|
123
|
+
* everything after that works here.
|
|
124
|
+
*/
|
|
125
|
+
github = {
|
|
126
|
+
/** Repos the Plures GitHub App can reach. installed is false until you install it at install_url. */
|
|
127
|
+
repos: () => this.req("GET", "/api/v1/github/repos"),
|
|
128
|
+
/** Where an app's GitHub link stands: repo, pull request, mapping on, latest run, last map. */
|
|
129
|
+
status: (app) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/github`),
|
|
130
|
+
/** Connects a repo ("owner/name"): sets its map key secret and opens the pull request. */
|
|
131
|
+
connect: (app, repo) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/github`, { repo }),
|
|
132
|
+
/** Turns mapping on by merging the pull request. The repo's own rules (reviews, checks) still apply. */
|
|
133
|
+
turnOn: (app) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/github/merge`, {}),
|
|
134
|
+
/** Revokes the repo's map key. Delete the workflow file in the repo to stop runs. */
|
|
135
|
+
disconnect: (app) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(app)}/github`)
|
|
136
|
+
};
|
|
118
137
|
/**
|
|
119
138
|
* Quality: people grade a sample of your agent's outputs against a rubric, so you see drift
|
|
120
139
|
* early, and compare two versions blind before you ship. Personal details are taken out first.
|
package/dist/cli.cjs
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
5
|
var import_node_child_process = require("child_process");
|
|
6
|
+
var import_node_crypto = require("crypto");
|
|
7
|
+
var import_node_path = require("path");
|
|
6
8
|
var import_node_fs = require("fs");
|
|
7
9
|
|
|
8
10
|
// src/index.ts
|
|
9
|
-
var VERSION = "1.
|
|
11
|
+
var VERSION = "1.11.0";
|
|
10
12
|
var PluresError = class extends Error {
|
|
11
13
|
constructor(message, status, type) {
|
|
12
14
|
super(message);
|
|
@@ -116,12 +118,31 @@ var Plures = class {
|
|
|
116
118
|
/** Starts a map run where Plures runs Claude (CI with no Anthropic key). npx plures map does this. */
|
|
117
119
|
startRun: (app2) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app2)}/map_runs`, {}),
|
|
118
120
|
runs: (app2) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app2)}/map_runs`),
|
|
121
|
+
/** While mapping, which files the coding agent is reading, shown live on the map page. File names only. npx plures map does this. */
|
|
122
|
+
progress: (app2, p) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app2)}/map/progress`, p),
|
|
119
123
|
/** The GitHub Actions workflow that maps a repo on every push to its main branch. */
|
|
120
124
|
workflow: async (app2, branch2 = "main") => {
|
|
121
125
|
const r = await fetch(`${this.base}/api/v1/map_workflow?app=${encodeURIComponent(app2)}&branch=${encodeURIComponent(branch2)}`);
|
|
122
126
|
return r.text();
|
|
123
127
|
}
|
|
124
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Map with GitHub: Plures adds a workflow to your repo by pull request and keeps the app's map
|
|
131
|
+
* current on every push. Installing the Plures GitHub App needs a browser once (installUrl);
|
|
132
|
+
* everything after that works here.
|
|
133
|
+
*/
|
|
134
|
+
github = {
|
|
135
|
+
/** Repos the Plures GitHub App can reach. installed is false until you install it at install_url. */
|
|
136
|
+
repos: () => this.req("GET", "/api/v1/github/repos"),
|
|
137
|
+
/** Where an app's GitHub link stands: repo, pull request, mapping on, latest run, last map. */
|
|
138
|
+
status: (app2) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app2)}/github`),
|
|
139
|
+
/** Connects a repo ("owner/name"): sets its map key secret and opens the pull request. */
|
|
140
|
+
connect: (app2, repo) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app2)}/github`, { repo }),
|
|
141
|
+
/** Turns mapping on by merging the pull request. The repo's own rules (reviews, checks) still apply. */
|
|
142
|
+
turnOn: (app2) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app2)}/github/merge`, {}),
|
|
143
|
+
/** Revokes the repo's map key. Delete the workflow file in the repo to stop runs. */
|
|
144
|
+
disconnect: (app2) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(app2)}/github`)
|
|
145
|
+
};
|
|
125
146
|
/**
|
|
126
147
|
* Quality: people grade a sample of your agent's outputs against a rubric, so you see drift
|
|
127
148
|
* early, and compare two versions blind before you ship. Personal details are taken out first.
|
|
@@ -283,11 +304,73 @@ With plures-mcp connected, just ask: ${cyan("Map this app for Plures")}`);
|
|
|
283
304
|
const prompt = `${guide}
|
|
284
305
|
|
|
285
306
|
Write the map to ${FILE} in the current directory now. Read the code; don't run it or change anything else.`;
|
|
307
|
+
const live = key ? client() : null;
|
|
308
|
+
const session = (0, import_node_crypto.randomBytes)(12).toString("base64url");
|
|
309
|
+
const source = process.env.GITHUB_ACTIONS ? "github" : "cli";
|
|
310
|
+
let queue = [], phase = "reading", sent = "", reads = 0;
|
|
311
|
+
const flush = async () => {
|
|
312
|
+
if (!live) return;
|
|
313
|
+
const events = queue;
|
|
314
|
+
queue = [];
|
|
315
|
+
if (!events.length && sent === phase) return;
|
|
316
|
+
sent = phase;
|
|
317
|
+
await live.maps.progress(app, { session, phase, source, events }).catch(() => {
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
const tick = setInterval(() => {
|
|
321
|
+
void flush();
|
|
322
|
+
}, 900);
|
|
323
|
+
void flush();
|
|
324
|
+
const rel = (p) => {
|
|
325
|
+
if (typeof p !== "string" || !p) return null;
|
|
326
|
+
const r = (0, import_node_path.isAbsolute)(p) ? (0, import_node_path.relative)(process.cwd(), p) : p;
|
|
327
|
+
return r.startsWith("..") ? null : r.replace(/\\/g, "/");
|
|
328
|
+
};
|
|
329
|
+
let result = "";
|
|
286
330
|
const code = await new Promise((resolve) => {
|
|
287
|
-
const p = (0, import_node_child_process.spawn)("claude", ["-p", prompt, "--allowedTools", "Read,Grep,Glob,Write,Bash(git rev-parse:*),Bash(git remote:*)"], { stdio: ["ignore", "
|
|
331
|
+
const p = (0, import_node_child_process.spawn)("claude", ["-p", prompt, "--output-format", "stream-json", "--verbose", "--allowedTools", "Read,Grep,Glob,Write,Bash(git rev-parse:*),Bash(git remote:*)"], { stdio: ["ignore", "pipe", "inherit"], env: childEnv });
|
|
332
|
+
let buf = "";
|
|
333
|
+
p.stdout.on("data", (chunk) => {
|
|
334
|
+
buf += chunk.toString();
|
|
335
|
+
let i;
|
|
336
|
+
while ((i = buf.indexOf("\n")) >= 0) {
|
|
337
|
+
const line = buf.slice(0, i);
|
|
338
|
+
buf = buf.slice(i + 1);
|
|
339
|
+
let ev;
|
|
340
|
+
try {
|
|
341
|
+
ev = JSON.parse(line);
|
|
342
|
+
} catch {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (ev.type === "result" && typeof ev.result === "string") result = ev.result;
|
|
346
|
+
for (const b of ev.type === "assistant" ? ev.message?.content ?? [] : []) {
|
|
347
|
+
if (b.type !== "tool_use") continue;
|
|
348
|
+
if (b.name === "Read") {
|
|
349
|
+
const f = rel(b.input?.file_path);
|
|
350
|
+
if (!f) continue;
|
|
351
|
+
reads++;
|
|
352
|
+
queue.push({ path: f, tool: "Read" });
|
|
353
|
+
console.log(` ${dim(String(reads).padStart(3))} ${dim("reading")} ${f}`);
|
|
354
|
+
} else if (b.name === "Write" && String(b.input?.file_path ?? "").endsWith(FILE)) {
|
|
355
|
+
phase = "drawing";
|
|
356
|
+
console.log(`
|
|
357
|
+
${violet("drawing")} the map`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
288
362
|
p.on("close", (n) => resolve(n ?? 1));
|
|
289
363
|
p.on("error", () => resolve(1));
|
|
290
364
|
});
|
|
365
|
+
clearInterval(tick);
|
|
366
|
+
if (result) console.log(`
|
|
367
|
+
${result.trim()}
|
|
368
|
+
`);
|
|
369
|
+
const ok = code === 0 && (0, import_node_fs.existsSync)(FILE) && (0, import_node_fs.statSync)(FILE).mtimeMs !== before;
|
|
370
|
+
if (!ok) {
|
|
371
|
+
phase = "failed";
|
|
372
|
+
await flush();
|
|
373
|
+
} else await flush();
|
|
291
374
|
if (code !== 0 || !(0, import_node_fs.existsSync)(FILE) || (0, import_node_fs.statSync)(FILE).mtimeMs === before) die(`Claude Code didn't write ${FILE}. Ask it directly, then run npx plures map upload.`);
|
|
292
375
|
await upload(FILE);
|
|
293
376
|
}
|
|
@@ -301,11 +384,58 @@ async function workflow() {
|
|
|
301
384
|
(0, import_node_fs.writeFileSync)(path, await r.text());
|
|
302
385
|
console.log(`${bold("Wrote " + path)}: maps this repo on every push to ${b}.
|
|
303
386
|
|
|
304
|
-
Then add
|
|
387
|
+
Then add a repository secret (Settings, Secrets and variables, Actions):
|
|
305
388
|
${cyan("PLURES_MAP_KEY")} a map key: ${dim(`${base}/dashboard/apps/${app}/map`)} or ${dim("POST /api/v1/apps/" + app + "/map_keys")}
|
|
306
|
-
|
|
389
|
+
Optional: ${cyan("ANTHROPIC_API_KEY")}, or ${cyan("CLAUDE_CODE_OAUTH_TOKEN")} from ${dim("claude setup-token")}, to map on your own key for free.
|
|
390
|
+
Without it Plures maps it: the first map is free.
|
|
307
391
|
|
|
308
|
-
Or let Plures do all of this: ${bold("
|
|
392
|
+
Or let Plures do all of this: ${bold("npx plures map github connect")}.`);
|
|
393
|
+
}
|
|
394
|
+
function originRepo() {
|
|
395
|
+
const u = (0, import_node_child_process.spawnSync)("git", ["remote", "get-url", "origin"], { encoding: "utf8" }).stdout?.trim() ?? "";
|
|
396
|
+
return /github\.com[:/]([\w.-]+\/[\w.-]+?)(?:\.git)?$/.exec(u)?.[1];
|
|
397
|
+
}
|
|
398
|
+
async function github(action, arg) {
|
|
399
|
+
const p = client();
|
|
400
|
+
const show = (g) => {
|
|
401
|
+
if (!g.connected) return console.log(`${bold(app)} has no repo connected. Run ${cyan("npx plures map github connect")} in the repo, or pass ${cyan("owner/repo")}.`);
|
|
402
|
+
const on = g.mapping_on ? cyan("on") : coral("off until the pull request is merged");
|
|
403
|
+
console.log(`${bold(app)} maps from ${bold(g.repo)}: mapping ${on}.
|
|
404
|
+
Pull request ${g.pull_request?.state} ${dim(g.pull_request?.url ?? "")}
|
|
405
|
+
Mapped by ${g.mapped_by === "your_anthropic_key" ? "your Anthropic key, free" : g.mapped_by === "plures" ? `Plures${g.first_map_free ? ", first map free" : ""}` : coral("needs ANTHROPIC_API_KEY in the repo's secrets")}
|
|
406
|
+
Latest run ${g.latest_run ? `${g.latest_run.conclusion ?? g.latest_run.status} ${dim(g.latest_run.url)}` : dim("none yet")}
|
|
407
|
+
Map ${g.mapped_at ? `uploaded ${g.mapped_at}` : dim("arrives a few minutes after the first run")}`);
|
|
408
|
+
if (g.pull_request?.state === "open") console.log(`
|
|
409
|
+
Turn it on: ${cyan("npx plures map github on")}${app !== "default" ? ` --app ${app}` : ""}`);
|
|
410
|
+
};
|
|
411
|
+
try {
|
|
412
|
+
if (!action || action === "status") return show(await p.github.status(app));
|
|
413
|
+
if (action === "on") {
|
|
414
|
+
const r = await p.github.turnOn(app);
|
|
415
|
+
console.log(r.already_merged ? "Mapping was already on." : `${bold("Mapping is on.")} The first run is starting on GitHub.`);
|
|
416
|
+
return show(await p.github.status(app));
|
|
417
|
+
}
|
|
418
|
+
if (action === "off") {
|
|
419
|
+
await p.github.disconnect(app);
|
|
420
|
+
return console.log(`Disconnected. The repo's map key is revoked. Delete ${cyan(".github/workflows/plures-map.yml")} in the repo to stop runs.`);
|
|
421
|
+
}
|
|
422
|
+
if (action === "connect") {
|
|
423
|
+
const repo = arg ?? originRepo();
|
|
424
|
+
if (!repo) die("Pass the repo as owner/name, or run this inside a clone of it.");
|
|
425
|
+
const list = await p.github.repos();
|
|
426
|
+
if (!list.installed || !list.data.some((r) => r.repo.toLowerCase() === repo.toLowerCase()))
|
|
427
|
+
die(`The Plures GitHub App can't reach ${repo} yet. Open this once, pick the repo, then run this again:
|
|
428
|
+
${list.install_url}?app=${app}`);
|
|
429
|
+
const g = await p.github.connect(app, repo);
|
|
430
|
+
console.log(`${bold("Pull request opened")} in ${repo}: ${g.pull_request?.url}
|
|
431
|
+
It adds one workflow file. Review it, then turn mapping on with ${cyan("npx plures map github on")}${app !== "default" ? ` --app ${app}` : ""}, or merge it on GitHub.`);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
die("npx plures map github [connect [owner/repo] | on | off]");
|
|
435
|
+
} catch (e) {
|
|
436
|
+
if (e instanceof PluresError) die(e.message);
|
|
437
|
+
throw e;
|
|
438
|
+
}
|
|
309
439
|
}
|
|
310
440
|
async function main() {
|
|
311
441
|
const [cmd, sub, arg] = argv;
|
|
@@ -316,6 +446,8 @@ async function main() {
|
|
|
316
446
|
npx plures map upload [file] upload ${FILE}
|
|
317
447
|
npx plures map guide print the steps for any coding agent
|
|
318
448
|
npx plures map workflow add a GitHub Action that maps on every push
|
|
449
|
+
npx plures map github connect let Plures add that Action by pull request
|
|
450
|
+
npx plures map github on merge it, which turns mapping on
|
|
319
451
|
|
|
320
452
|
Docs: https://plures.si/docs`);
|
|
321
453
|
return;
|
|
@@ -323,6 +455,7 @@ Docs: https://plures.si/docs`);
|
|
|
323
455
|
if (sub === "upload") return upload(arg ?? FILE);
|
|
324
456
|
if (sub === "guide") return void console.log(await (await fetch(`${base}/api/v1/map_guide`)).text());
|
|
325
457
|
if (sub === "workflow") return workflow();
|
|
458
|
+
if (sub === "github") return github(arg, argv[3]);
|
|
326
459
|
return map();
|
|
327
460
|
}
|
|
328
461
|
main().catch((e) => die(String(e?.message ?? e)));
|
package/dist/cli.js
CHANGED
|
@@ -3,10 +3,12 @@ import {
|
|
|
3
3
|
Plures,
|
|
4
4
|
PluresError,
|
|
5
5
|
VERSION
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WPSUIAVZ.js";
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { spawnSync, spawn } from "child_process";
|
|
10
|
+
import { randomBytes } from "crypto";
|
|
11
|
+
import { relative, isAbsolute } from "path";
|
|
10
12
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
11
13
|
var argv = process.argv.slice(2);
|
|
12
14
|
var flag = (name) => {
|
|
@@ -106,11 +108,73 @@ With plures-mcp connected, just ask: ${cyan("Map this app for Plures")}`);
|
|
|
106
108
|
const prompt = `${guide}
|
|
107
109
|
|
|
108
110
|
Write the map to ${FILE} in the current directory now. Read the code; don't run it or change anything else.`;
|
|
111
|
+
const live = key ? client() : null;
|
|
112
|
+
const session = randomBytes(12).toString("base64url");
|
|
113
|
+
const source = process.env.GITHUB_ACTIONS ? "github" : "cli";
|
|
114
|
+
let queue = [], phase = "reading", sent = "", reads = 0;
|
|
115
|
+
const flush = async () => {
|
|
116
|
+
if (!live) return;
|
|
117
|
+
const events = queue;
|
|
118
|
+
queue = [];
|
|
119
|
+
if (!events.length && sent === phase) return;
|
|
120
|
+
sent = phase;
|
|
121
|
+
await live.maps.progress(app, { session, phase, source, events }).catch(() => {
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
const tick = setInterval(() => {
|
|
125
|
+
void flush();
|
|
126
|
+
}, 900);
|
|
127
|
+
void flush();
|
|
128
|
+
const rel = (p) => {
|
|
129
|
+
if (typeof p !== "string" || !p) return null;
|
|
130
|
+
const r = isAbsolute(p) ? relative(process.cwd(), p) : p;
|
|
131
|
+
return r.startsWith("..") ? null : r.replace(/\\/g, "/");
|
|
132
|
+
};
|
|
133
|
+
let result = "";
|
|
109
134
|
const code = await new Promise((resolve) => {
|
|
110
|
-
const p = spawn("claude", ["-p", prompt, "--allowedTools", "Read,Grep,Glob,Write,Bash(git rev-parse:*),Bash(git remote:*)"], { stdio: ["ignore", "
|
|
135
|
+
const p = spawn("claude", ["-p", prompt, "--output-format", "stream-json", "--verbose", "--allowedTools", "Read,Grep,Glob,Write,Bash(git rev-parse:*),Bash(git remote:*)"], { stdio: ["ignore", "pipe", "inherit"], env: childEnv });
|
|
136
|
+
let buf = "";
|
|
137
|
+
p.stdout.on("data", (chunk) => {
|
|
138
|
+
buf += chunk.toString();
|
|
139
|
+
let i;
|
|
140
|
+
while ((i = buf.indexOf("\n")) >= 0) {
|
|
141
|
+
const line = buf.slice(0, i);
|
|
142
|
+
buf = buf.slice(i + 1);
|
|
143
|
+
let ev;
|
|
144
|
+
try {
|
|
145
|
+
ev = JSON.parse(line);
|
|
146
|
+
} catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (ev.type === "result" && typeof ev.result === "string") result = ev.result;
|
|
150
|
+
for (const b of ev.type === "assistant" ? ev.message?.content ?? [] : []) {
|
|
151
|
+
if (b.type !== "tool_use") continue;
|
|
152
|
+
if (b.name === "Read") {
|
|
153
|
+
const f = rel(b.input?.file_path);
|
|
154
|
+
if (!f) continue;
|
|
155
|
+
reads++;
|
|
156
|
+
queue.push({ path: f, tool: "Read" });
|
|
157
|
+
console.log(` ${dim(String(reads).padStart(3))} ${dim("reading")} ${f}`);
|
|
158
|
+
} else if (b.name === "Write" && String(b.input?.file_path ?? "").endsWith(FILE)) {
|
|
159
|
+
phase = "drawing";
|
|
160
|
+
console.log(`
|
|
161
|
+
${violet("drawing")} the map`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
111
166
|
p.on("close", (n) => resolve(n ?? 1));
|
|
112
167
|
p.on("error", () => resolve(1));
|
|
113
168
|
});
|
|
169
|
+
clearInterval(tick);
|
|
170
|
+
if (result) console.log(`
|
|
171
|
+
${result.trim()}
|
|
172
|
+
`);
|
|
173
|
+
const ok = code === 0 && existsSync(FILE) && statSync(FILE).mtimeMs !== before;
|
|
174
|
+
if (!ok) {
|
|
175
|
+
phase = "failed";
|
|
176
|
+
await flush();
|
|
177
|
+
} else await flush();
|
|
114
178
|
if (code !== 0 || !existsSync(FILE) || statSync(FILE).mtimeMs === before) die(`Claude Code didn't write ${FILE}. Ask it directly, then run npx plures map upload.`);
|
|
115
179
|
await upload(FILE);
|
|
116
180
|
}
|
|
@@ -124,11 +188,58 @@ async function workflow() {
|
|
|
124
188
|
writeFileSync(path, await r.text());
|
|
125
189
|
console.log(`${bold("Wrote " + path)}: maps this repo on every push to ${b}.
|
|
126
190
|
|
|
127
|
-
Then add
|
|
191
|
+
Then add a repository secret (Settings, Secrets and variables, Actions):
|
|
128
192
|
${cyan("PLURES_MAP_KEY")} a map key: ${dim(`${base}/dashboard/apps/${app}/map`)} or ${dim("POST /api/v1/apps/" + app + "/map_keys")}
|
|
129
|
-
|
|
193
|
+
Optional: ${cyan("ANTHROPIC_API_KEY")}, or ${cyan("CLAUDE_CODE_OAUTH_TOKEN")} from ${dim("claude setup-token")}, to map on your own key for free.
|
|
194
|
+
Without it Plures maps it: the first map is free.
|
|
130
195
|
|
|
131
|
-
Or let Plures do all of this: ${bold("
|
|
196
|
+
Or let Plures do all of this: ${bold("npx plures map github connect")}.`);
|
|
197
|
+
}
|
|
198
|
+
function originRepo() {
|
|
199
|
+
const u = spawnSync("git", ["remote", "get-url", "origin"], { encoding: "utf8" }).stdout?.trim() ?? "";
|
|
200
|
+
return /github\.com[:/]([\w.-]+\/[\w.-]+?)(?:\.git)?$/.exec(u)?.[1];
|
|
201
|
+
}
|
|
202
|
+
async function github(action, arg) {
|
|
203
|
+
const p = client();
|
|
204
|
+
const show = (g) => {
|
|
205
|
+
if (!g.connected) return console.log(`${bold(app)} has no repo connected. Run ${cyan("npx plures map github connect")} in the repo, or pass ${cyan("owner/repo")}.`);
|
|
206
|
+
const on = g.mapping_on ? cyan("on") : coral("off until the pull request is merged");
|
|
207
|
+
console.log(`${bold(app)} maps from ${bold(g.repo)}: mapping ${on}.
|
|
208
|
+
Pull request ${g.pull_request?.state} ${dim(g.pull_request?.url ?? "")}
|
|
209
|
+
Mapped by ${g.mapped_by === "your_anthropic_key" ? "your Anthropic key, free" : g.mapped_by === "plures" ? `Plures${g.first_map_free ? ", first map free" : ""}` : coral("needs ANTHROPIC_API_KEY in the repo's secrets")}
|
|
210
|
+
Latest run ${g.latest_run ? `${g.latest_run.conclusion ?? g.latest_run.status} ${dim(g.latest_run.url)}` : dim("none yet")}
|
|
211
|
+
Map ${g.mapped_at ? `uploaded ${g.mapped_at}` : dim("arrives a few minutes after the first run")}`);
|
|
212
|
+
if (g.pull_request?.state === "open") console.log(`
|
|
213
|
+
Turn it on: ${cyan("npx plures map github on")}${app !== "default" ? ` --app ${app}` : ""}`);
|
|
214
|
+
};
|
|
215
|
+
try {
|
|
216
|
+
if (!action || action === "status") return show(await p.github.status(app));
|
|
217
|
+
if (action === "on") {
|
|
218
|
+
const r = await p.github.turnOn(app);
|
|
219
|
+
console.log(r.already_merged ? "Mapping was already on." : `${bold("Mapping is on.")} The first run is starting on GitHub.`);
|
|
220
|
+
return show(await p.github.status(app));
|
|
221
|
+
}
|
|
222
|
+
if (action === "off") {
|
|
223
|
+
await p.github.disconnect(app);
|
|
224
|
+
return console.log(`Disconnected. The repo's map key is revoked. Delete ${cyan(".github/workflows/plures-map.yml")} in the repo to stop runs.`);
|
|
225
|
+
}
|
|
226
|
+
if (action === "connect") {
|
|
227
|
+
const repo = arg ?? originRepo();
|
|
228
|
+
if (!repo) die("Pass the repo as owner/name, or run this inside a clone of it.");
|
|
229
|
+
const list = await p.github.repos();
|
|
230
|
+
if (!list.installed || !list.data.some((r) => r.repo.toLowerCase() === repo.toLowerCase()))
|
|
231
|
+
die(`The Plures GitHub App can't reach ${repo} yet. Open this once, pick the repo, then run this again:
|
|
232
|
+
${list.install_url}?app=${app}`);
|
|
233
|
+
const g = await p.github.connect(app, repo);
|
|
234
|
+
console.log(`${bold("Pull request opened")} in ${repo}: ${g.pull_request?.url}
|
|
235
|
+
It adds one workflow file. Review it, then turn mapping on with ${cyan("npx plures map github on")}${app !== "default" ? ` --app ${app}` : ""}, or merge it on GitHub.`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
die("npx plures map github [connect [owner/repo] | on | off]");
|
|
239
|
+
} catch (e) {
|
|
240
|
+
if (e instanceof PluresError) die(e.message);
|
|
241
|
+
throw e;
|
|
242
|
+
}
|
|
132
243
|
}
|
|
133
244
|
async function main() {
|
|
134
245
|
const [cmd, sub, arg] = argv;
|
|
@@ -139,6 +250,8 @@ async function main() {
|
|
|
139
250
|
npx plures map upload [file] upload ${FILE}
|
|
140
251
|
npx plures map guide print the steps for any coding agent
|
|
141
252
|
npx plures map workflow add a GitHub Action that maps on every push
|
|
253
|
+
npx plures map github connect let Plures add that Action by pull request
|
|
254
|
+
npx plures map github on merge it, which turns mapping on
|
|
142
255
|
|
|
143
256
|
Docs: https://plures.si/docs`);
|
|
144
257
|
return;
|
|
@@ -146,6 +259,7 @@ Docs: https://plures.si/docs`);
|
|
|
146
259
|
if (sub === "upload") return upload(arg ?? FILE);
|
|
147
260
|
if (sub === "guide") return void console.log(await (await fetch(`${base}/api/v1/map_guide`)).text());
|
|
148
261
|
if (sub === "workflow") return workflow();
|
|
262
|
+
if (sub === "github") return github(arg, argv[3]);
|
|
149
263
|
return map();
|
|
150
264
|
}
|
|
151
265
|
main().catch((e) => die(String(e?.message ?? e)));
|
package/dist/index.cjs
CHANGED
|
@@ -26,7 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
default: () => index_default
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(index_exports);
|
|
29
|
-
var VERSION = "1.
|
|
29
|
+
var VERSION = "1.11.0";
|
|
30
30
|
var PluresError = class extends Error {
|
|
31
31
|
constructor(message, status, type) {
|
|
32
32
|
super(message);
|
|
@@ -136,12 +136,31 @@ var Plures = class {
|
|
|
136
136
|
/** Starts a map run where Plures runs Claude (CI with no Anthropic key). npx plures map does this. */
|
|
137
137
|
startRun: (app) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/map_runs`, {}),
|
|
138
138
|
runs: (app) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/map_runs`),
|
|
139
|
+
/** While mapping, which files the coding agent is reading, shown live on the map page. File names only. npx plures map does this. */
|
|
140
|
+
progress: (app, p) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/map/progress`, p),
|
|
139
141
|
/** The GitHub Actions workflow that maps a repo on every push to its main branch. */
|
|
140
142
|
workflow: async (app, branch = "main") => {
|
|
141
143
|
const r = await fetch(`${this.base}/api/v1/map_workflow?app=${encodeURIComponent(app)}&branch=${encodeURIComponent(branch)}`);
|
|
142
144
|
return r.text();
|
|
143
145
|
}
|
|
144
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Map with GitHub: Plures adds a workflow to your repo by pull request and keeps the app's map
|
|
149
|
+
* current on every push. Installing the Plures GitHub App needs a browser once (installUrl);
|
|
150
|
+
* everything after that works here.
|
|
151
|
+
*/
|
|
152
|
+
github = {
|
|
153
|
+
/** Repos the Plures GitHub App can reach. installed is false until you install it at install_url. */
|
|
154
|
+
repos: () => this.req("GET", "/api/v1/github/repos"),
|
|
155
|
+
/** Where an app's GitHub link stands: repo, pull request, mapping on, latest run, last map. */
|
|
156
|
+
status: (app) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/github`),
|
|
157
|
+
/** Connects a repo ("owner/name"): sets its map key secret and opens the pull request. */
|
|
158
|
+
connect: (app, repo) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/github`, { repo }),
|
|
159
|
+
/** Turns mapping on by merging the pull request. The repo's own rules (reviews, checks) still apply. */
|
|
160
|
+
turnOn: (app) => this.req("POST", `/api/v1/apps/${encodeURIComponent(app)}/github/merge`, {}),
|
|
161
|
+
/** Revokes the repo's map key. Delete the workflow file in the repo to stop runs. */
|
|
162
|
+
disconnect: (app) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(app)}/github`)
|
|
163
|
+
};
|
|
145
164
|
/**
|
|
146
165
|
* Quality: people grade a sample of your agent's outputs against a rubric, so you see drift
|
|
147
166
|
* early, and compare two versions blind before you ship. Personal details are taken out first.
|
package/dist/index.d.cts
CHANGED
|
@@ -350,7 +350,30 @@ type WebhookEvent = {
|
|
|
350
350
|
created_at: string;
|
|
351
351
|
data: Task;
|
|
352
352
|
};
|
|
353
|
-
declare const VERSION = "1.
|
|
353
|
+
declare const VERSION = "1.11.0";
|
|
354
|
+
type GitHubLink = {
|
|
355
|
+
object: "github_link";
|
|
356
|
+
app: string;
|
|
357
|
+
installed: boolean;
|
|
358
|
+
install_url: string;
|
|
359
|
+
connected: boolean;
|
|
360
|
+
repo?: string;
|
|
361
|
+
pull_request?: {
|
|
362
|
+
url: string | null;
|
|
363
|
+
state: "open" | "merged" | "closed" | "unknown";
|
|
364
|
+
};
|
|
365
|
+
mapping_on?: boolean;
|
|
366
|
+
mapped_by?: "plures" | "your_anthropic_key" | "needs_key";
|
|
367
|
+
first_map_free?: boolean;
|
|
368
|
+
latest_run?: {
|
|
369
|
+
status: string;
|
|
370
|
+
conclusion: string | null;
|
|
371
|
+
url: string;
|
|
372
|
+
created_at: string;
|
|
373
|
+
} | null;
|
|
374
|
+
mapped_at?: string | null;
|
|
375
|
+
connected_at?: string;
|
|
376
|
+
};
|
|
354
377
|
declare class PluresError extends Error {
|
|
355
378
|
readonly status: number;
|
|
356
379
|
readonly type: string;
|
|
@@ -484,9 +507,64 @@ declare class Plures {
|
|
|
484
507
|
created_at: string;
|
|
485
508
|
}[];
|
|
486
509
|
}>;
|
|
510
|
+
/** While mapping, which files the coding agent is reading, shown live on the map page. File names only. npx plures map does this. */
|
|
511
|
+
progress: (app: string, p: {
|
|
512
|
+
session: string;
|
|
513
|
+
phase?: "reading" | "drawing" | "done" | "failed";
|
|
514
|
+
source?: "cli" | "github";
|
|
515
|
+
events?: {
|
|
516
|
+
path: string;
|
|
517
|
+
tool?: string;
|
|
518
|
+
}[];
|
|
519
|
+
}) => Promise<{
|
|
520
|
+
object: "map_progress";
|
|
521
|
+
app: string;
|
|
522
|
+
session: string;
|
|
523
|
+
phase: string;
|
|
524
|
+
received: number;
|
|
525
|
+
}>;
|
|
487
526
|
/** The GitHub Actions workflow that maps a repo on every push to its main branch. */
|
|
488
527
|
workflow: (app: string, branch?: string) => Promise<string>;
|
|
489
528
|
};
|
|
529
|
+
/**
|
|
530
|
+
* Map with GitHub: Plures adds a workflow to your repo by pull request and keeps the app's map
|
|
531
|
+
* current on every push. Installing the Plures GitHub App needs a browser once (installUrl);
|
|
532
|
+
* everything after that works here.
|
|
533
|
+
*/
|
|
534
|
+
github: {
|
|
535
|
+
/** Repos the Plures GitHub App can reach. installed is false until you install it at install_url. */
|
|
536
|
+
repos: () => Promise<{
|
|
537
|
+
object: "list";
|
|
538
|
+
installed: boolean;
|
|
539
|
+
install_url: string;
|
|
540
|
+
data: {
|
|
541
|
+
object: "github_repo";
|
|
542
|
+
repo: string;
|
|
543
|
+
private: boolean;
|
|
544
|
+
account: string;
|
|
545
|
+
default_branch: string;
|
|
546
|
+
}[];
|
|
547
|
+
}>;
|
|
548
|
+
/** Where an app's GitHub link stands: repo, pull request, mapping on, latest run, last map. */
|
|
549
|
+
status: (app: string) => Promise<GitHubLink>;
|
|
550
|
+
/** Connects a repo ("owner/name"): sets its map key secret and opens the pull request. */
|
|
551
|
+
connect: (app: string, repo: string) => Promise<GitHubLink>;
|
|
552
|
+
/** Turns mapping on by merging the pull request. The repo's own rules (reviews, checks) still apply. */
|
|
553
|
+
turnOn: (app: string) => Promise<{
|
|
554
|
+
object: "github_merge";
|
|
555
|
+
app: string;
|
|
556
|
+
merged: true;
|
|
557
|
+
already_merged: boolean;
|
|
558
|
+
sha: string | null;
|
|
559
|
+
}>;
|
|
560
|
+
/** Revokes the repo's map key. Delete the workflow file in the repo to stop runs. */
|
|
561
|
+
disconnect: (app: string) => Promise<{
|
|
562
|
+
object: "github_link";
|
|
563
|
+
app: string;
|
|
564
|
+
connected: false;
|
|
565
|
+
deleted: true;
|
|
566
|
+
}>;
|
|
567
|
+
};
|
|
490
568
|
/**
|
|
491
569
|
* Quality: people grade a sample of your agent's outputs against a rubric, so you see drift
|
|
492
570
|
* early, and compare two versions blind before you ship. Personal details are taken out first.
|
|
@@ -578,4 +656,4 @@ declare class Plures {
|
|
|
578
656
|
static verifyWebhook(rawBody: string, signatureHeader: string | null, secret: string, toleranceSec?: number): Promise<WebhookEvent>;
|
|
579
657
|
}
|
|
580
658
|
|
|
581
|
-
export { type AgentMap, type App, type Balance, type Consensus, type CreateTask, type Escalation, type MapCheckpoint, type MapDraft, type MapKey, type MapNode, type Mix, type Option, Plures, PluresError, type Release, type Result, type Route, type Routing, type RoutingRule, type RoutingUpdate, type Rubric, type RubricParams, type Sample, type StoredAgentMap, type Task, type TaskStatus, type TeamTally, type TeamVote, type TestMix, VERSION, type WebhookEvent, Plures as default };
|
|
659
|
+
export { type AgentMap, type App, type Balance, type Consensus, type CreateTask, type Escalation, type GitHubLink, type MapCheckpoint, type MapDraft, type MapKey, type MapNode, type Mix, type Option, Plures, PluresError, type Release, type Result, type Route, type Routing, type RoutingRule, type RoutingUpdate, type Rubric, type RubricParams, type Sample, type StoredAgentMap, type Task, type TaskStatus, type TeamTally, type TeamVote, type TestMix, VERSION, type WebhookEvent, Plures as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -350,7 +350,30 @@ type WebhookEvent = {
|
|
|
350
350
|
created_at: string;
|
|
351
351
|
data: Task;
|
|
352
352
|
};
|
|
353
|
-
declare const VERSION = "1.
|
|
353
|
+
declare const VERSION = "1.11.0";
|
|
354
|
+
type GitHubLink = {
|
|
355
|
+
object: "github_link";
|
|
356
|
+
app: string;
|
|
357
|
+
installed: boolean;
|
|
358
|
+
install_url: string;
|
|
359
|
+
connected: boolean;
|
|
360
|
+
repo?: string;
|
|
361
|
+
pull_request?: {
|
|
362
|
+
url: string | null;
|
|
363
|
+
state: "open" | "merged" | "closed" | "unknown";
|
|
364
|
+
};
|
|
365
|
+
mapping_on?: boolean;
|
|
366
|
+
mapped_by?: "plures" | "your_anthropic_key" | "needs_key";
|
|
367
|
+
first_map_free?: boolean;
|
|
368
|
+
latest_run?: {
|
|
369
|
+
status: string;
|
|
370
|
+
conclusion: string | null;
|
|
371
|
+
url: string;
|
|
372
|
+
created_at: string;
|
|
373
|
+
} | null;
|
|
374
|
+
mapped_at?: string | null;
|
|
375
|
+
connected_at?: string;
|
|
376
|
+
};
|
|
354
377
|
declare class PluresError extends Error {
|
|
355
378
|
readonly status: number;
|
|
356
379
|
readonly type: string;
|
|
@@ -484,9 +507,64 @@ declare class Plures {
|
|
|
484
507
|
created_at: string;
|
|
485
508
|
}[];
|
|
486
509
|
}>;
|
|
510
|
+
/** While mapping, which files the coding agent is reading, shown live on the map page. File names only. npx plures map does this. */
|
|
511
|
+
progress: (app: string, p: {
|
|
512
|
+
session: string;
|
|
513
|
+
phase?: "reading" | "drawing" | "done" | "failed";
|
|
514
|
+
source?: "cli" | "github";
|
|
515
|
+
events?: {
|
|
516
|
+
path: string;
|
|
517
|
+
tool?: string;
|
|
518
|
+
}[];
|
|
519
|
+
}) => Promise<{
|
|
520
|
+
object: "map_progress";
|
|
521
|
+
app: string;
|
|
522
|
+
session: string;
|
|
523
|
+
phase: string;
|
|
524
|
+
received: number;
|
|
525
|
+
}>;
|
|
487
526
|
/** The GitHub Actions workflow that maps a repo on every push to its main branch. */
|
|
488
527
|
workflow: (app: string, branch?: string) => Promise<string>;
|
|
489
528
|
};
|
|
529
|
+
/**
|
|
530
|
+
* Map with GitHub: Plures adds a workflow to your repo by pull request and keeps the app's map
|
|
531
|
+
* current on every push. Installing the Plures GitHub App needs a browser once (installUrl);
|
|
532
|
+
* everything after that works here.
|
|
533
|
+
*/
|
|
534
|
+
github: {
|
|
535
|
+
/** Repos the Plures GitHub App can reach. installed is false until you install it at install_url. */
|
|
536
|
+
repos: () => Promise<{
|
|
537
|
+
object: "list";
|
|
538
|
+
installed: boolean;
|
|
539
|
+
install_url: string;
|
|
540
|
+
data: {
|
|
541
|
+
object: "github_repo";
|
|
542
|
+
repo: string;
|
|
543
|
+
private: boolean;
|
|
544
|
+
account: string;
|
|
545
|
+
default_branch: string;
|
|
546
|
+
}[];
|
|
547
|
+
}>;
|
|
548
|
+
/** Where an app's GitHub link stands: repo, pull request, mapping on, latest run, last map. */
|
|
549
|
+
status: (app: string) => Promise<GitHubLink>;
|
|
550
|
+
/** Connects a repo ("owner/name"): sets its map key secret and opens the pull request. */
|
|
551
|
+
connect: (app: string, repo: string) => Promise<GitHubLink>;
|
|
552
|
+
/** Turns mapping on by merging the pull request. The repo's own rules (reviews, checks) still apply. */
|
|
553
|
+
turnOn: (app: string) => Promise<{
|
|
554
|
+
object: "github_merge";
|
|
555
|
+
app: string;
|
|
556
|
+
merged: true;
|
|
557
|
+
already_merged: boolean;
|
|
558
|
+
sha: string | null;
|
|
559
|
+
}>;
|
|
560
|
+
/** Revokes the repo's map key. Delete the workflow file in the repo to stop runs. */
|
|
561
|
+
disconnect: (app: string) => Promise<{
|
|
562
|
+
object: "github_link";
|
|
563
|
+
app: string;
|
|
564
|
+
connected: false;
|
|
565
|
+
deleted: true;
|
|
566
|
+
}>;
|
|
567
|
+
};
|
|
490
568
|
/**
|
|
491
569
|
* Quality: people grade a sample of your agent's outputs against a rubric, so you see drift
|
|
492
570
|
* early, and compare two versions blind before you ship. Personal details are taken out first.
|
|
@@ -578,4 +656,4 @@ declare class Plures {
|
|
|
578
656
|
static verifyWebhook(rawBody: string, signatureHeader: string | null, secret: string, toleranceSec?: number): Promise<WebhookEvent>;
|
|
579
657
|
}
|
|
580
658
|
|
|
581
|
-
export { type AgentMap, type App, type Balance, type Consensus, type CreateTask, type Escalation, type MapCheckpoint, type MapDraft, type MapKey, type MapNode, type Mix, type Option, Plures, PluresError, type Release, type Result, type Route, type Routing, type RoutingRule, type RoutingUpdate, type Rubric, type RubricParams, type Sample, type StoredAgentMap, type Task, type TaskStatus, type TeamTally, type TeamVote, type TestMix, VERSION, type WebhookEvent, Plures as default };
|
|
659
|
+
export { type AgentMap, type App, type Balance, type Consensus, type CreateTask, type Escalation, type GitHubLink, type MapCheckpoint, type MapDraft, type MapKey, type MapNode, type Mix, type Option, Plures, PluresError, type Release, type Result, type Route, type Routing, type RoutingRule, type RoutingUpdate, type Rubric, type RubricParams, type Sample, type StoredAgentMap, type Task, type TaskStatus, type TeamTally, type TeamVote, type TestMix, VERSION, type WebhookEvent, Plures as default };
|
package/dist/index.js
CHANGED