@tekmidian/pai 0.37.0 → 0.38.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/index.mjs +2 -2
- package/dist/cli/program.mjs +2 -2
- package/dist/daemon-mcp/index.mjs +153 -32
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/hooks/route-agents-to-worker.mjs +76 -14
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/worker-proxy.mjs +76 -14
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +76 -14
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/{program-CEIHn_Ma.mjs → program-Y0hAiVy8.mjs} +207 -49
- package/dist/program-Y0hAiVy8.mjs.map +1 -0
- package/dist/{providers-sXcK5bDZ.mjs → providers-DUshcB-d.mjs} +1171 -207
- package/dist/providers-DUshcB-d.mjs.map +1 -0
- package/dist/skills/Worker/SKILL.md +34 -12
- package/docs/commands/README.md +8 -7
- package/docs/commands/worker.md +54 -17
- package/docs/worker.md +156 -25
- package/package.json +1 -1
- package/dist/program-CEIHn_Ma.mjs.map +0 -1
- package/dist/providers-sXcK5bDZ.mjs.map +0 -1
|
@@ -12,7 +12,7 @@ import { a as schedulerLogPath, i as paiSocketPath, n as daemonLogPath, r as dae
|
|
|
12
12
|
import { t as PaiClient } from "./ipc-client-BmypMNYk.mjs";
|
|
13
13
|
import { a as expandHome, c as UNROUTED, i as ensureConfigDir, n as CONFIG_FILE$2, o as loadConfig, s as OWNER_LABEL_PREFIX, t as CONFIG_DIR } from "./config-B64vFg14.mjs";
|
|
14
14
|
import { r as humanDuration, t as createStorageBackend } from "./factory-DD2T33C9.mjs";
|
|
15
|
-
import { A as
|
|
15
|
+
import { A as ledgerPath, C as checkPaneForWorker, E as loadStatus, F as readJsonStrict, I as writeJsonAtomic, M as PROVIDER_TAGS, N as WorkersConfigError, O as parseRunnerArgs, P as readWorkersSection, S as describeMcp, T as openPaneForWorker, _ as testProvider, a as setClass, b as stopProxy, c as unsetClass, d as followWorkers, f as psOutput, g as runWorker, h as runChain, i as removeProvider, j as workersLogDir, k as eventsPath, l as updateProvider, m as statusLineOutput, n as classTargetText, o as setProviderEnabled, p as replayOutput, r as describeProviders, s as setWorkersEnabled, t as addProvider, u as useProvider, v as DEFAULT_PROXY_PORT, w as openFollowPane, x as sayToWorker, y as ensureProxyRunning } from "./providers-DUshcB-d.mjs";
|
|
16
16
|
import { s as kgQuery } from "./kg-entity-r8duqhi9.mjs";
|
|
17
17
|
import { _ as scanSessions, a as renderDedupedSessions, c as probeResume, d as callAiBroker, f as fetchLiveSessions, g as resolveSessionByNameOrId, h as fmtAge, i as normalizeName$2, l as restoreTopLevel, m as sendToSession, o as hasConversation, p as revealItermSession, r as buildDeduped, s as launchInDir, t as cmdMain, u as printExitDir } from "./main-resolver-DlaLOFBA.mjs";
|
|
18
18
|
import { appendFileSync, chmodSync, copyFileSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
@@ -6253,7 +6253,7 @@ async function stepWorkers(rl) {
|
|
|
6253
6253
|
return { workers: {
|
|
6254
6254
|
enabled: false,
|
|
6255
6255
|
providers: {},
|
|
6256
|
-
|
|
6256
|
+
classes: {}
|
|
6257
6257
|
} };
|
|
6258
6258
|
}
|
|
6259
6259
|
line$1();
|
|
@@ -6265,14 +6265,14 @@ async function stepWorkers(rl) {
|
|
|
6265
6265
|
line$1(c.dim(" --key-file ~/.config/example/api_key \\"));
|
|
6266
6266
|
line$1(c.dim(" --model example-4.7 --fast-model example-4.7-flash"));
|
|
6267
6267
|
line$1();
|
|
6268
|
-
line$1(" The first provider turns workers on and seeds the
|
|
6268
|
+
line$1(" The first provider turns workers on and seeds the classes.");
|
|
6269
6269
|
line$1();
|
|
6270
6270
|
const r = installWorkers();
|
|
6271
6271
|
for (const l of r.lines) line$1(` ${l}`);
|
|
6272
6272
|
return { workers: {
|
|
6273
6273
|
enabled: false,
|
|
6274
6274
|
providers: {},
|
|
6275
|
-
|
|
6275
|
+
classes: {}
|
|
6276
6276
|
} };
|
|
6277
6277
|
}
|
|
6278
6278
|
|
|
@@ -13577,6 +13577,99 @@ function registerSessionCommands(sessionCmd, getDb) {
|
|
|
13577
13577
|
});
|
|
13578
13578
|
}
|
|
13579
13579
|
|
|
13580
|
+
//#endregion
|
|
13581
|
+
//#region src/workers/agents.ts
|
|
13582
|
+
/**
|
|
13583
|
+
* agents.ts — run agent definitions (~/.claude/agents/<name>.md) as workers.
|
|
13584
|
+
*
|
|
13585
|
+
* The file format is the Claude Code agent one: YAML front matter (`model`,
|
|
13586
|
+
* `tools`, `description`) followed by a Markdown body that is the agent's
|
|
13587
|
+
* system prompt. `pai worker run --agent <name>` loads it and maps it onto
|
|
13588
|
+
* the worker runner:
|
|
13589
|
+
*
|
|
13590
|
+
* - body → --append-system-prompt (prepended, so an explicit caller
|
|
13591
|
+
* flag still wins);
|
|
13592
|
+
* - tools → --allowedTools;
|
|
13593
|
+
* - model → a task class (haiku→simple, sonnet→implement, opus→complex),
|
|
13594
|
+
* unless --class is given.
|
|
13595
|
+
*/
|
|
13596
|
+
/** Directory the agent library lives in. */
|
|
13597
|
+
function agentsDir() {
|
|
13598
|
+
return join(homedir(), ".claude", "agents");
|
|
13599
|
+
}
|
|
13600
|
+
function agentPath(name) {
|
|
13601
|
+
return join(agentsDir(), `${name}.md`);
|
|
13602
|
+
}
|
|
13603
|
+
/** `key: value` (bare) or `key: [a, b]` / `key:\n - a\n - b` (list). */
|
|
13604
|
+
function parseFrontMatter(text) {
|
|
13605
|
+
const out = {};
|
|
13606
|
+
let key = "";
|
|
13607
|
+
for (const raw of text.split("\n")) {
|
|
13608
|
+
const listItem = /^\s+-\s+(.*)$/.exec(raw);
|
|
13609
|
+
if (listItem && key) {
|
|
13610
|
+
const cur = out[key];
|
|
13611
|
+
const item = listItem[1].trim().replace(/^["']|["']$/g, "");
|
|
13612
|
+
out[key] = Array.isArray(cur) ? [...cur, item] : [item];
|
|
13613
|
+
continue;
|
|
13614
|
+
}
|
|
13615
|
+
const kv = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(raw);
|
|
13616
|
+
if (!kv) continue;
|
|
13617
|
+
key = kv[1];
|
|
13618
|
+
const val = kv[2].trim();
|
|
13619
|
+
if (!val) out[key] = [];
|
|
13620
|
+
else if (val.startsWith("[") && val.endsWith("]")) out[key] = val.slice(1, -1).split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
13621
|
+
else out[key] = val.replace(/^["']|["']$/g, "");
|
|
13622
|
+
}
|
|
13623
|
+
return out;
|
|
13624
|
+
}
|
|
13625
|
+
/** Parse an agent file's text (front matter + body). Throws on empty body. */
|
|
13626
|
+
function parseAgentFile(name, text, path) {
|
|
13627
|
+
const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
|
|
13628
|
+
if (!m) throw new Error(`${path}: expected YAML front matter (--- … ---) before the agent body`);
|
|
13629
|
+
const fm = parseFrontMatter(m[1]);
|
|
13630
|
+
const body = m[2].trim();
|
|
13631
|
+
if (!body) throw new Error(`${path}: the agent body (after the front matter) is empty`);
|
|
13632
|
+
const def = {
|
|
13633
|
+
name,
|
|
13634
|
+
body,
|
|
13635
|
+
path
|
|
13636
|
+
};
|
|
13637
|
+
if (typeof fm.model === "string" && fm.model) def.model = fm.model;
|
|
13638
|
+
if (Array.isArray(fm.tools) && fm.tools.length) def.tools = fm.tools;
|
|
13639
|
+
if (typeof fm.description === "string" && fm.description) def.description = fm.description;
|
|
13640
|
+
return def;
|
|
13641
|
+
}
|
|
13642
|
+
/** Load ~/.claude/agents/<name>.md; the error names the library when missing. */
|
|
13643
|
+
function loadAgent(name) {
|
|
13644
|
+
const path = agentPath(name);
|
|
13645
|
+
let text;
|
|
13646
|
+
try {
|
|
13647
|
+
text = readFileSync(path, "utf8");
|
|
13648
|
+
} catch {
|
|
13649
|
+
throw new Error(`no agent named "${name}" at ${path}. The agent library lives in ~/.claude/agents/<name>.md and runs on workers.`);
|
|
13650
|
+
}
|
|
13651
|
+
return parseAgentFile(name, text, path);
|
|
13652
|
+
}
|
|
13653
|
+
/** Map an agent's front-matter model to a worker class. */
|
|
13654
|
+
function modelToClass(model) {
|
|
13655
|
+
if (!model) return void 0;
|
|
13656
|
+
const m = model.toLowerCase();
|
|
13657
|
+
if (m.includes("haiku")) return "simple";
|
|
13658
|
+
if (m.includes("sonnet")) return "implement";
|
|
13659
|
+
if (m.includes("opus")) return "complex";
|
|
13660
|
+
}
|
|
13661
|
+
/** Extra claude args the definition contributes (before the caller's own). */
|
|
13662
|
+
function agentClaudeArgs(def) {
|
|
13663
|
+
const args = [];
|
|
13664
|
+
if (def.tools?.length) args.push("--allowedTools", def.tools.join(","));
|
|
13665
|
+
args.push("--append-system-prompt", def.body);
|
|
13666
|
+
return args;
|
|
13667
|
+
}
|
|
13668
|
+
/** `<agent>: <first 50 chars of prompt>` — the default label for a run. */
|
|
13669
|
+
function agentLabel(name, prompt) {
|
|
13670
|
+
return `${name}: ${prompt ?? "(no prompt)"}`.slice(0, name.length + 2 + 50);
|
|
13671
|
+
}
|
|
13672
|
+
|
|
13580
13673
|
//#endregion
|
|
13581
13674
|
//#region src/cli/commands/worker/providers.ts
|
|
13582
13675
|
function fail$1(e) {
|
|
@@ -13599,14 +13692,37 @@ function parseIntArg$1(v) {
|
|
|
13599
13692
|
if (Number.isNaN(n) || n <= 0) throw new WorkersConfigError(`expected a positive number, got "${v}"`);
|
|
13600
13693
|
return n;
|
|
13601
13694
|
}
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
if (
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13695
|
+
function parseCostTier(v) {
|
|
13696
|
+
const n = parseInt(v, 10);
|
|
13697
|
+
if (!Number.isInteger(n) || n < 1 || n > 5) throw new WorkersConfigError(`cost tier must be an integer 1 (cheapest) … 5 (most expensive), got "${v}"`);
|
|
13698
|
+
return n;
|
|
13699
|
+
}
|
|
13700
|
+
/** `--tags a,b` (repeatable) → validated tag list. */
|
|
13701
|
+
function collectTags(vals) {
|
|
13702
|
+
const out = [];
|
|
13703
|
+
for (const v of vals ?? []) for (const t of v.split(",").map((s) => s.trim()).filter(Boolean)) {
|
|
13704
|
+
if (!PROVIDER_TAGS.includes(t)) throw new WorkersConfigError(`"${t}" is not a tag (from: ${PROVIDER_TAGS.join(", ")})`);
|
|
13705
|
+
if (!out.includes(t)) out.push(t);
|
|
13608
13706
|
}
|
|
13609
|
-
return
|
|
13707
|
+
return out;
|
|
13708
|
+
}
|
|
13709
|
+
/** Positional target + constraint flags → a ClassTarget for setClass. */
|
|
13710
|
+
function buildClassTarget(target, opts) {
|
|
13711
|
+
const hasConstraints = opts.provider !== void 0 || opts.mcp !== void 0 || opts.maxCostTier !== void 0 || opts.requireTags !== void 0 || opts.order !== void 0;
|
|
13712
|
+
if (target !== void 0 && !hasConstraints) return target;
|
|
13713
|
+
const obj = {};
|
|
13714
|
+
if (target !== void 0) obj.provider = target.split("/")[0];
|
|
13715
|
+
if (opts.provider !== void 0) obj.provider = opts.provider;
|
|
13716
|
+
if (opts.mcp !== void 0) obj.mcp = opts.mcp.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13717
|
+
if (opts.maxCostTier !== void 0) obj.maxCostTier = opts.maxCostTier;
|
|
13718
|
+
if (opts.requireTags !== void 0) obj.requireTags = opts.requireTags;
|
|
13719
|
+
if (opts.order !== void 0) obj.order = opts.order.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13720
|
+
if (target !== void 0 && target.includes("/") && obj.provider) {
|
|
13721
|
+
const alias = target.split("/")[1];
|
|
13722
|
+
if (alias && alias !== "default") throw new WorkersConfigError(`a provider alias ("${alias}") cannot be combined with constraint flags — use the plain "<target>" form for pinning`);
|
|
13723
|
+
}
|
|
13724
|
+
if (!Object.keys(obj).length) throw new WorkersConfigError("give a target (provider, provider/fast) or a constraint (--max-cost-tier, --require-tags, …)");
|
|
13725
|
+
return obj;
|
|
13610
13726
|
}
|
|
13611
13727
|
function registerWorkerProviderCommands(providersCmd) {
|
|
13612
13728
|
providersCmd.description("Providers: list (default), add, remove, use, enable, disable, test").action(() => {
|
|
@@ -13617,13 +13733,14 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13617
13733
|
console.log(dim$1(` workers are ${workers.enabled ? "on" : "off"} — pai worker ${workers.enabled ? "off" : "on"}`));
|
|
13618
13734
|
console.log();
|
|
13619
13735
|
});
|
|
13620
|
-
providersCmd.command("add <name>").description("Add a provider; the first one also turns workers on and seeds
|
|
13736
|
+
providersCmd.command("add <name>").description("Add a provider; the first one also turns workers on and seeds classes.\nExample: pai worker providers add glm --base-url https://…/anthropic \\\n --key-file ~/.config/zai/api_key --model glm-5.3 --fast-model glm-5.3-flash\nOpenAI-protocol: --protocol openai --upstream-url https://…/v1 (runs via the PAI proxy).\nCodex (ChatGPT plan): --engine codex — runs through the Codex CLI.").option("--base-url <url>", "Anthropic-compatible API base URL (required unless --protocol openai)").requiredOption("--model <model>", "Default model id for this provider").option("--key-file <path>", "File holding the API token (0600); omit for token \"local\"").option("--fast-model <model>", "Cheaper model for spotchecks and routing").option("--env <name=value>", "Extra env for runs (repeatable)", (v, acc) => [...acc, v], []).option("--note <text>", "Human note shown in `providers list`").option("--protocol <proto>", "anthropic (default) or openai — openai runs through the local PAI proxy").option("--upstream-url <url>", "Chat Completions base URL (required for --protocol openai)").option("--engine <engine>", "claude (default) or codex — codex runs `codex exec --json`").option("--context-window <tokens>", "Context window for the meter (default 200000; init event overrides)", parseIntArg$1).option("--quota-probe <url>", "URL whose JSON first number is the quota percent (0-100)").option("--cost-tier <1-5>", "Cost tier 1 (cheapest) … 5 (most expensive; default 3)", parseCostTier).option("--tags <tags>", "Capability tags, comma-separated (from: " + PROVIDER_TAGS.join(", ") + ")", (v, acc) => [...acc, v], []).action((name, opts) => {
|
|
13621
13737
|
try {
|
|
13622
13738
|
const protocol = opts.protocol;
|
|
13623
13739
|
const engine = opts.engine;
|
|
13624
13740
|
if (protocol && protocol !== "anthropic" && protocol !== "openai") throw new WorkersConfigError(`--protocol must be anthropic or openai, got "${protocol}"`);
|
|
13625
13741
|
if (engine && engine !== "claude" && engine !== "codex") throw new WorkersConfigError(`--engine must be claude or codex, got "${engine}"`);
|
|
13626
13742
|
if (protocol !== "openai" && !opts.baseUrl) throw new WorkersConfigError("--base-url is required (only --protocol openai goes without it)");
|
|
13743
|
+
const tags = collectTags(opts.tags);
|
|
13627
13744
|
addProvider({
|
|
13628
13745
|
name,
|
|
13629
13746
|
baseUrl: opts.baseUrl ?? "",
|
|
@@ -13636,7 +13753,9 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13636
13753
|
...opts.upstreamUrl ? { upstreamUrl: opts.upstreamUrl } : {},
|
|
13637
13754
|
...engine ? { engine } : {},
|
|
13638
13755
|
...opts.contextWindow ? { contextWindow: opts.contextWindow } : {},
|
|
13639
|
-
quotaProbe: opts.quotaProbe
|
|
13756
|
+
quotaProbe: opts.quotaProbe,
|
|
13757
|
+
...opts.costTier !== void 0 ? { costTier: opts.costTier } : {},
|
|
13758
|
+
...tags.length ? { tags } : {}
|
|
13640
13759
|
});
|
|
13641
13760
|
const { workers } = readWorkersSection();
|
|
13642
13761
|
console.log(ok$1(`provider ${name} added`));
|
|
@@ -13646,7 +13765,22 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13646
13765
|
fail$1(e);
|
|
13647
13766
|
}
|
|
13648
13767
|
});
|
|
13649
|
-
providersCmd.command("
|
|
13768
|
+
providersCmd.command("update <name>").description("Change cost tier and tags of a provider (routing constraints use these)").option("--cost-tier <1-5>", "Cost tier 1 (cheapest) … 5 (most expensive)", parseCostTier).option("--tags <tags>", "Capability tags, comma-separated (from: " + PROVIDER_TAGS.join(", ") + "); --tags '' clears", (v, acc) => [...acc, v], []).action((name, opts) => {
|
|
13769
|
+
try {
|
|
13770
|
+
if (opts.costTier === void 0 && opts.tags === void 0) throw new WorkersConfigError("nothing to update — pass --cost-tier and/or --tags");
|
|
13771
|
+
const tags = opts.tags === void 0 ? void 0 : collectTags(opts.tags);
|
|
13772
|
+
updateProvider(name, {
|
|
13773
|
+
...opts.costTier !== void 0 ? { costTier: opts.costTier } : {},
|
|
13774
|
+
...tags !== void 0 ? { tags } : {}
|
|
13775
|
+
});
|
|
13776
|
+
console.log(ok$1(`provider ${name} updated`));
|
|
13777
|
+
const { workers } = readWorkersSection();
|
|
13778
|
+
for (const line of describeProviders(workers)) console.log(dim$1(` ${line}`));
|
|
13779
|
+
} catch (e) {
|
|
13780
|
+
fail$1(e);
|
|
13781
|
+
}
|
|
13782
|
+
});
|
|
13783
|
+
providersCmd.command("remove <name>").description("Remove a provider and any classes pointing at it").action((name) => {
|
|
13650
13784
|
try {
|
|
13651
13785
|
removeProvider(name);
|
|
13652
13786
|
console.log(ok$1(`provider ${name} removed`));
|
|
@@ -13654,7 +13788,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13654
13788
|
fail$1(e);
|
|
13655
13789
|
}
|
|
13656
13790
|
});
|
|
13657
|
-
providersCmd.command("use <name>").description("Make this provider the active one for runs without --provider/--
|
|
13791
|
+
providersCmd.command("use <name>").description("Make this provider the active one for runs without --provider/--class").action((name) => {
|
|
13658
13792
|
try {
|
|
13659
13793
|
useProvider(name);
|
|
13660
13794
|
console.log(ok$1(`active provider: ${name}`));
|
|
@@ -13699,43 +13833,40 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13699
13833
|
}
|
|
13700
13834
|
});
|
|
13701
13835
|
}
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
const
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
const { workers } = readWorkersSection();
|
|
13715
|
-
const entries = Object.entries(workers.roles);
|
|
13716
|
-
if (!entries.length) {
|
|
13717
|
-
console.log(dim$1(" no roles set — runs use the active provider"));
|
|
13718
|
-
return;
|
|
13719
|
-
}
|
|
13720
|
-
for (const [role, target] of entries) console.log(` ${role.padEnd(12)} ${roleTargetText(target)}`);
|
|
13721
|
-
});
|
|
13722
|
-
rolesCmd.command("set <role> <provider[/alias]>").description("Point a role at a provider, optionally its fast model (e.g. glm/fast)").action((role, target) => {
|
|
13836
|
+
function printClasses() {
|
|
13837
|
+
const { workers } = readWorkersSection();
|
|
13838
|
+
const entries = Object.entries(workers.classes);
|
|
13839
|
+
if (!entries.length) {
|
|
13840
|
+
console.log(dim$1(" no classes set — runs use the active provider (or auto routing)"));
|
|
13841
|
+
return;
|
|
13842
|
+
}
|
|
13843
|
+
for (const [cls, target] of entries) console.log(` ${cls.padEnd(12)} ${classTargetText(target)}`);
|
|
13844
|
+
}
|
|
13845
|
+
function registerClassSubcommands(classesCmd) {
|
|
13846
|
+
classesCmd.command("list").description("List classes and their targets (default action)").action(() => printClasses());
|
|
13847
|
+
classesCmd.command("set <class> [target]").description("Point a class at a provider (or provider/fast), or give only constraints:\nclasses set research --max-cost-tier 2 --require-tags long-context,reasoning").option("--provider <name>", "Pin the class to this provider (object form)").option("--mcp <names>", "MCP servers/sets for runs of this class (comma-separated)").option("--max-cost-tier <1-5>", "Auto-routing considers only providers up to this cost tier", parseCostTier).option("--require-tags <tags>", "Auto-routing needs these tags (comma-separated)", (v) => v.split(",").map((s) => s.trim()).filter(Boolean)).option("--order <providers>", "Per-class routing order overriding workers.routing.order (comma-separated)").action((cls, target, opts) => {
|
|
13723
13848
|
try {
|
|
13724
|
-
|
|
13725
|
-
|
|
13849
|
+
const built = buildClassTarget(target, opts);
|
|
13850
|
+
setClass(cls, built);
|
|
13851
|
+
console.log(ok$1(`class ${cls} → ${classTargetText(built)}`));
|
|
13726
13852
|
} catch (e) {
|
|
13727
13853
|
fail$1(e);
|
|
13728
13854
|
}
|
|
13729
13855
|
});
|
|
13730
|
-
|
|
13856
|
+
classesCmd.command("unset <class>").description("Remove a class (runs then use the active provider)").action((cls) => {
|
|
13731
13857
|
try {
|
|
13732
|
-
|
|
13733
|
-
console.log(ok$1(`
|
|
13858
|
+
unsetClass(cls);
|
|
13859
|
+
console.log(ok$1(`class ${cls} removed`));
|
|
13734
13860
|
} catch (e) {
|
|
13735
13861
|
fail$1(e);
|
|
13736
13862
|
}
|
|
13737
13863
|
});
|
|
13738
13864
|
}
|
|
13865
|
+
/** `pai worker classes` — class → target assignment (roles is the old name). */
|
|
13866
|
+
function registerWorkerClassCommands(workerCmd) {
|
|
13867
|
+
registerClassSubcommands(workerCmd.command("classes").description("Classes: which provider serves draft / implement / review / …").action(() => printClasses()));
|
|
13868
|
+
registerClassSubcommands(workerCmd.command("roles", { hidden: true }).description("Alias of `classes` (roles was renamed to classes)").action(() => printClasses()));
|
|
13869
|
+
}
|
|
13739
13870
|
|
|
13740
13871
|
//#endregion
|
|
13741
13872
|
//#region src/cli/commands/worker/index.ts
|
|
@@ -13749,16 +13880,43 @@ function fail(e) {
|
|
|
13749
13880
|
process.exitCode = 1;
|
|
13750
13881
|
}
|
|
13751
13882
|
function registerWorkerCommands(workerCmd) {
|
|
13752
|
-
workerCmd.command("run").description("Run one claude-code worker through the configured provider.\nUnknown options are passed to claude verbatim (e.g. -p, --allowedTools);\n--output-format/--verbose are handled here.").allowUnknownOption(true).option("--provider <name>", "Provider to run on (default: active, else routing order)").option("--
|
|
13883
|
+
workerCmd.command("run").description("Run one claude-code worker through the configured provider.\nUnknown options are passed to claude verbatim (e.g. -p, --allowedTools);\n--output-format/--verbose are handled here.\n--chain draft,implement[,review] runs a spec-first pipeline;\n--agent <name> runs an agent definition from ~/.claude/agents.").allowUnknownOption(true).option("--provider <name>", "Provider to run on (default: active, else routing order)").option("--class <name>", "Use the provider of this class (draft, implement, review, research, spotcheck, simple, complex, image)").option("--role <name>", "Alias of --class (roles were renamed to classes)").option("--chain <stages>", "Comma-separated stage classes, e.g. draft,implement or draft,implement,review").option("--agent <name>", "Run the agent definition ~/.claude/agents/<name>.md on a worker").option("--model <model>", "Override the provider's model for this run").option("--label <text>", "Short task label shown in ps / follow / status line").option("--mcp <names>", "MCP servers/sets this worker may use (comma-separated; see `pai worker mcp`)").option("--no-pane", "Do not open a follow pane for this worker").argument("[args...]", "claude arguments, e.g. -p '<task>' --allowedTools 'Read,Edit,Bash'").action(async (args, opts) => {
|
|
13753
13884
|
try {
|
|
13885
|
+
const className = opts.class ?? opts.role;
|
|
13886
|
+
let claudeArgs = args;
|
|
13887
|
+
let label = opts.label;
|
|
13888
|
+
let agentClass;
|
|
13889
|
+
if (opts.agent) {
|
|
13890
|
+
const def = loadAgent(opts.agent);
|
|
13891
|
+
claudeArgs = [...agentClaudeArgs(def), ...args];
|
|
13892
|
+
agentClass = modelToClass(def.model);
|
|
13893
|
+
if (!label) label = agentLabel(opts.agent, parseRunnerArgs(args).prompt);
|
|
13894
|
+
}
|
|
13895
|
+
if (opts.chain) {
|
|
13896
|
+
const brief = parseRunnerArgs(claudeArgs).prompt;
|
|
13897
|
+
if (!brief) throw new Error("--chain needs the task as -p '<brief>'");
|
|
13898
|
+
const rc = await runChain({
|
|
13899
|
+
stages: opts.chain.split(","),
|
|
13900
|
+
className: className ?? agentClass,
|
|
13901
|
+
providerFlag: opts.provider,
|
|
13902
|
+
modelFlag: opts.model,
|
|
13903
|
+
label,
|
|
13904
|
+
noPane: opts.pane === false,
|
|
13905
|
+
mcpFlag: opts.mcp,
|
|
13906
|
+
brief,
|
|
13907
|
+
claudeArgs
|
|
13908
|
+
});
|
|
13909
|
+
process.exitCode = rc;
|
|
13910
|
+
return;
|
|
13911
|
+
}
|
|
13754
13912
|
const rc = await runWorker({
|
|
13755
13913
|
providerFlag: opts.provider,
|
|
13756
|
-
|
|
13914
|
+
className: className ?? agentClass,
|
|
13757
13915
|
modelFlag: opts.model,
|
|
13758
|
-
label
|
|
13916
|
+
label,
|
|
13759
13917
|
mcpFlag: opts.mcp,
|
|
13760
13918
|
noPane: opts.pane === false,
|
|
13761
|
-
claudeArgs
|
|
13919
|
+
claudeArgs
|
|
13762
13920
|
});
|
|
13763
13921
|
process.exitCode = rc;
|
|
13764
13922
|
} catch (e) {
|
|
@@ -13799,13 +13957,13 @@ function registerWorkerCommands(workerCmd) {
|
|
|
13799
13957
|
process.exitCode = code ?? 1;
|
|
13800
13958
|
});
|
|
13801
13959
|
});
|
|
13802
|
-
workerCmd.command("pane [id]").description("Open the follow pane for a worker (or one shared pane for this session)").option("--check", "Only report whether the pane is open, plus the profile file's path and
|
|
13960
|
+
workerCmd.command("pane [id]").description("Open the follow pane for a worker (or one shared pane for this session)").option("--check", "Only report whether the pane is open, plus the profile file's path, font, and the hosting window's bounds").action(async (id, opts) => {
|
|
13803
13961
|
try {
|
|
13804
13962
|
const { workers } = readWorkersSection();
|
|
13805
13963
|
const logDir = currentLogDir();
|
|
13806
13964
|
const term = process.env.ITERM_SESSION_ID ?? "";
|
|
13807
13965
|
if (id) {
|
|
13808
|
-
const msg = opts.check ? await checkPaneForWorker(id, workers.pane.fontSize) : await openPaneForWorker(logDir, workers, id, term);
|
|
13966
|
+
const msg = opts.check ? await checkPaneForWorker(id, workers.pane.fontSize, term) : await openPaneForWorker(logDir, workers, id, term);
|
|
13809
13967
|
console.log(msg);
|
|
13810
13968
|
} else console.log(await openFollowPane(logDir, workers, term, opts.check === true));
|
|
13811
13969
|
} catch (e) {
|
|
@@ -13955,7 +14113,7 @@ function registerWorkerCommands(workerCmd) {
|
|
|
13955
14113
|
}
|
|
13956
14114
|
});
|
|
13957
14115
|
registerWorkerProviderCommands(workerCmd.command("providers").description("Providers: list, add, remove, use, enable, disable, test"));
|
|
13958
|
-
|
|
14116
|
+
registerWorkerClassCommands(workerCmd);
|
|
13959
14117
|
}
|
|
13960
14118
|
function parseIntArg(v) {
|
|
13961
14119
|
const n = parseInt(v, 10);
|
|
@@ -15872,4 +16030,4 @@ claude() {
|
|
|
15872
16030
|
|
|
15873
16031
|
//#endregion
|
|
15874
16032
|
export { drainStdio as n, buildProgram as t };
|
|
15875
|
-
//# sourceMappingURL=program-
|
|
16033
|
+
//# sourceMappingURL=program-Y0hAiVy8.mjs.map
|