@oxgeneral/orch 1.0.22 → 1.0.24
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/App-QHBW3KHL.js +23 -0
- package/dist/{agent-WLKP6WOR.js → agent-6PI3NNZ5.js} +1 -1
- package/dist/agent-factory-T6WZIQPM.js +2 -0
- package/dist/chunk-4O4L3Y2U.js +2 -0
- package/dist/{chunk-EWRVHOUA.js → chunk-JDG6ZKIM.js} +1 -1
- package/dist/chunk-SJG3HXO5.js +5 -0
- package/dist/cli.js +1 -1
- package/dist/container-KJNQCG2C.js +4 -0
- package/dist/doctor-DEGM2HCD.js +2 -0
- package/dist/index.d.ts +31 -2
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/{init-GVM7EYPO.js → init-4D6QMPQL.js} +8 -8
- package/dist/{org-WCEBMHLR.js → org-RL6SBZI4.js} +1 -1
- package/dist/pi-GFJCLRZJ.js +393 -0
- package/dist/pi-GFJCLRZJ.js.map +1 -0
- package/dist/pi-XEINSHUN.js +2 -0
- package/dist/{task-M2FY3SU7.js → task-YMPSU6YE.js} +1 -1
- package/dist/{tui-QHU43YNY.js → tui-QU4MGY6B.js} +1 -1
- package/package.json +1 -1
- package/readme.md +8 -7
- package/dist/App-23IBDXAF.js +0 -22
- package/dist/agent-factory-HJOS7FW3.js +0 -2
- package/dist/chunk-XMKCAUEH.js +0 -2
- package/dist/container-PKAEIRCI.js +0 -4
- package/dist/doctor-5HTCX6K7.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {c as c$1,b as b$1,a as a$2}from'./chunk-
|
|
2
|
+
import {c as c$1,b as b$1,a as a$2}from'./chunk-4O4L3Y2U.js';import {f}from'./chunk-LY3X2UHQ.js';import {a}from'./chunk-N4OXN2HW.js';import'./chunk-CHRW4CLD.js';import {k as k$1,j as j$1,q,i}from'./chunk-64WUDYEM.js';import {b}from'./chunk-6E6DC7OE.js';import {k,j,c,a as a$1}from'./chunk-ZMLF5HI5.js';import'./chunk-LRYVT4D4.js';import T from'path';import _ from'fs/promises';import I from'readline';import {execFile}from'child_process';import {promisify}from'util';var E=`Agent architect \u2014 designs and creates AI agents for the orchestrator via \`orch agent add\`.
|
|
3
3
|
|
|
4
4
|
## CREATION PROCESS
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ import {c as c$1,b as b$1,a as a$2}from'./chunk-XMKCAUEH.js';import {f}from'./ch
|
|
|
13
13
|
Do NOT include CLI documentation or goal-mode instructions \u2014 these are already injected by the system prompt template.
|
|
14
14
|
|
|
15
15
|
3) CHOOSE CONFIGURATION:
|
|
16
|
-
- adapter: \`claude\` (AI tasks), \`shell\` (bash scripts), \`codex\` (OpenAI Codex), \`cursor\` (Cursor IDE), \`opencode\` (OpenCode \u2014 multi-provider)
|
|
16
|
+
- adapter: \`claude\` (AI tasks), \`shell\` (bash scripts), \`codex\` (OpenAI Codex), \`pi\` (Pi coding agent RPC), \`cursor\` (Cursor IDE), \`opencode\` (OpenCode \u2014 multi-provider)
|
|
17
17
|
- model: choose based on task complexity \u2014 use the \`capable\` tier for architecture/review, \`balanced\` for routine work, \`fast\` for simple/templated tasks. Model names vary by adapter.
|
|
18
18
|
- approval_policy: \`auto\` (no confirmation) / \`suggest\` (proposes actions) / \`manual\` (human approval)
|
|
19
19
|
- max_turns: 50 (default), up to 100 for complex tasks
|
|
@@ -25,7 +25,7 @@ import {c as c$1,b as b$1,a as a$2}from'./chunk-XMKCAUEH.js';import {f}from'./ch
|
|
|
25
25
|
|
|
26
26
|
There are two types of skills:
|
|
27
27
|
|
|
28
|
-
**Library skills** \u2014 ORCH loads Markdown content and injects it into the agent's system prompt. Works with ALL adapters (claude, opencode, codex, cursor, shell). Use plain names without colons:
|
|
28
|
+
**Library skills** \u2014 ORCH loads Markdown content and injects it into the agent's system prompt. Works with ALL adapters (claude, opencode, codex, pi, cursor, shell). Use plain names without colons:
|
|
29
29
|
|
|
30
30
|
| Category | Skills |
|
|
31
31
|
|----------|--------|
|
|
@@ -58,17 +58,17 @@ You can mix both types: \`--skills "review,feature-dev:code-explorer,investigate
|
|
|
58
58
|
- Never use the -e/--edit flag in automated mode \u2014 it opens an interactive editor.
|
|
59
59
|
- Always specify --role when calling \`orch agent add\`.
|
|
60
60
|
|
|
61
|
-
After creation \u2014 \`orch context set agent-<name> "<capabilities>"\`.`;function
|
|
61
|
+
After creation \u2014 \`orch context set agent-<name> "<capabilities>"\`.`;function P(a="claude"){let e=a$2(a,"balanced");return [{id:"agt_creator",name:"Agent Creator",adapter:a,role:E,config:{model:e||void 0,approval_policy:"suggest",max_turns:50,timeout_ms:36e5,stall_timeout_ms:3e5,skills:a==="claude"?["document-skills:skill-creator"]:[]},status:"idle",stats:{tasks_completed:0,tasks_failed:0,total_runs:0,total_runtime_ms:0}}]}var l=promisify(execFile);async function R(a$2={}){let e=process.cwd(),o=new b(e);if(await k(o.root)){k$1("Already initialized");return}let t=a$2.adapter??await O();await Promise.all([j(o.tasksDir),j(o.agentsDir),j(o.goalsDir),j(o.runsDir),j(o.templatesDir),j(o.logsDir)]);let r=await N(e),s=structuredClone(a);s.project.name=a$2.name??T.basename(e),s.defaults.agent.adapter=t,r||(s.defaults.agent.workspace_mode="shared");let p=["# Runtime state","state.json","*.lock","","# Logs and runs","runs/","logs/","","# Agent workspaces","workspaces/"].join(`
|
|
62
62
|
`)+`
|
|
63
63
|
`,b$1=[".orchestry","node_modules",".env",".env.*","dist","build",".next","__pycache__","*.pyc",".venv"].join(`
|
|
64
64
|
`)+`
|
|
65
|
-
`,g=
|
|
66
|
-
`)[0]}}catch{}return {name:t,ok:false}}))).filter(t=>t.ok);if(e.length===0)return console.log(` ${q("No AI adapters detected \u2014 defaulting to claude")}`),"claude";if(e.length===1)return console.log(` ${q(`Detected: ${e[0].name}`)} ${q(e[0].version?`(${e[0].version})`:"")}`),e[0].name;if(!process.stdout.isTTY||!process.stdin.isTTY)return e[0].name;console.log(),console.log(" Available adapters:");for(let t=0;t<e.length;t++){let r=e[t];console.log(` ${t+1}) ${r.name} ${q(r.version??"")}`);}console.log();let o=I.createInterface({input:process.stdin,output:process.stdout});try{let t=await new Promise(s=>{o.question(` Choose default adapter [1-${e.length}]: `,s);}),r=parseInt(t,10)-1;return r>=0&&r<e.length?e[r].name:e[0].name}finally{o.close();}}async function N(a){try{return await l("git",["rev-parse","--is-inside-work-tree"],{cwd:a}),!0}catch{try{return await l("git",["init"],{cwd:a}),!0}catch{return false}}}async function L(a){try{await l("git",["rev-parse","HEAD"],{cwd:a});}catch{try{await l("git",["add","-A"],{cwd:a}),await l("git",["commit","-m","Initial commit","--allow-empty"],{cwd:a});}catch{}}}async function S(a){let e=T.join(a,".gitignore");try{let o=await
|
|
65
|
+
`,g=P(t);await Promise.all([c(o.configPath,s),a$1(o.gitignorePath,p),a$1(o.workspaceExcludePath,b$1),a$1(o.defaultTemplatePath(),f),...g.map(c$1=>c(o.agentPath(c$1.id),c$1))]),await S(e),r&&await L(e),console.log(),j$1("initialized"),console.log(),console.log(` Created ${q(".orchestry/")}`),console.log(` ${q("\u251C\u2500\u2500")} config.yml`),console.log(` ${q("\u251C\u2500\u2500")} tasks/`),console.log(` ${q("\u251C\u2500\u2500")} agents/`);for(let c of g)console.log(` ${q("\u2502 \u2514\u2500\u2500")} ${c.id}.yml ${q(`(${c.name})`)}`);console.log(` ${q("\u251C\u2500\u2500")} templates/default.md`),console.log(` ${q("\u2514\u2500\u2500")} .gitignore`),console.log();}async function O(){let e=(await Promise.all(c$1.filter(t=>t!=="shell").map(async t=>{let r=t==="cursor"?["cursor-agent"]:[t];for(let s of r)try{let{stdout:p}=await l(s,["--version"],{timeout:5e3});return {name:t,ok:!0,version:p.trim().split(`
|
|
66
|
+
`)[0]}}catch{}return {name:t,ok:false}}))).filter(t=>t.ok);if(e.length===0)return console.log(` ${q("No AI adapters detected \u2014 defaulting to claude")}`),"claude";if(e.length===1)return console.log(` ${q(`Detected: ${e[0].name}`)} ${q(e[0].version?`(${e[0].version})`:"")}`),e[0].name;if(!process.stdout.isTTY||!process.stdin.isTTY)return e[0].name;console.log(),console.log(" Available adapters:");for(let t=0;t<e.length;t++){let r=e[t];console.log(` ${t+1}) ${r.name} ${q(r.version??"")}`);}console.log();let o=I.createInterface({input:process.stdin,output:process.stdout});try{let t=await new Promise(s=>{o.question(` Choose default adapter [1-${e.length}]: `,s);}),r=parseInt(t,10)-1;return r>=0&&r<e.length?e[r].name:e[0].name}finally{o.close();}}async function N(a){try{return await l("git",["rev-parse","--is-inside-work-tree"],{cwd:a}),!0}catch{try{return await l("git",["init"],{cwd:a}),!0}catch{return false}}}async function L(a){try{await l("git",["rev-parse","HEAD"],{cwd:a});}catch{try{await l("git",["add","-A"],{cwd:a}),await l("git",["commit","-m","Initial commit","--allow-empty"],{cwd:a});}catch{}}}async function S(a){let e=T.join(a,".gitignore");try{let o=await _.readFile(e,"utf-8");if(o.split(`
|
|
67
67
|
`).some(r=>r.trim()===".orchestry"))return;let t=o.endsWith(`
|
|
68
68
|
`)?"":`
|
|
69
|
-
`;await
|
|
69
|
+
`;await _.appendFile(e,`${t}
|
|
70
70
|
# Orchestry state
|
|
71
71
|
.orchestry
|
|
72
72
|
`);}catch{await a$1(e,`# Orchestry state
|
|
73
73
|
.orchestry
|
|
74
|
-
`);}}function V(a){a.command("init").description("Initialize .orchestry/ in the current directory").option("--name <name>","Project name").option("--adapter <adapter>","Default agent adapter (claude, opencode, codex, cursor, shell)").action(async e=>{if(e.adapter&&!b$1(e.adapter)){i(`Unknown adapter "${e.adapter}"`,`Supported: ${c$1.join(", ")}`),process.exitCode=2;return}await
|
|
74
|
+
`);}}function V(a){a.command("init").description("Initialize .orchestry/ in the current directory").option("--name <name>","Project name").option("--adapter <adapter>","Default agent adapter (claude, opencode, codex, cursor, pi, shell)").action(async e=>{if(e.adapter&&!b$1(e.adapter)){i(`Unknown adapter "${e.adapter}"`,`Supported: ${c$1.join(", ")}`),process.exitCode=2;return}await R(e),console.log(` Next: ${q('orch task add "Create backend agent" --assignee agt_creator')}`),console.log();});}export{V as registerInitCommand,R as runInit};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {b}from'./chunk-3YGXRXS7.js';import {b as b$1}from'./chunk-
|
|
2
|
+
import {b}from'./chunk-3YGXRXS7.js';import {b as b$1}from'./chunk-JDG6ZKIM.js';import'./chunk-4O4L3Y2U.js';import {l as l$1,q,i,j}from'./chunk-64WUDYEM.js';var l=[{key:"startup-mvp",name:"Startup MVP",description:"Ship an MVP in 48 hours",lead_index:0,agents:[{shop_key:"architect",name:"CTO"},{shop_key:"backend-dev",name:"Backend"},{shop_key:"backend-dev",name:"Backend 2"},{shop_key:"frontend-dev",name:"Frontend"},{shop_key:"qa-engineer",name:"QA"},{shop_key:"code-reviewer",name:"Reviewer"}]},{key:"pr-review-corp",name:"PR Review Corp",description:"Automated review for every PR",lead_index:0,agents:[{shop_key:"architect",name:"CTO"},{shop_key:"security-auditor",name:"Security"},{shop_key:"performance-engineer",name:"Performance"},{shop_key:"code-reviewer",name:"Style"},{shop_key:"qa-engineer",name:"QA"}]},{key:"migration-squad",name:"Migration Squad",description:"JS-to-TS migration over a weekend",lead_index:0,agents:[{shop_key:"architect",name:"CTO"},{shop_key:"fullstack-dev",name:"Migrator"},{shop_key:"fullstack-dev",name:"Migrator 2"},{shop_key:"fullstack-dev",name:"Migrator 3"},{shop_key:"qa-engineer",name:"QA"},{shop_key:"code-reviewer",name:"Reviewer"}]},{key:"security-dept",name:"Security Department",description:"Multi-layer security audit",lead_index:0,agents:[{shop_key:"security-auditor",name:"Lead Auditor"},{shop_key:"security-auditor",name:"Scanner"},{shop_key:"security-auditor",name:"Secrets Auditor"},{shop_key:"bug-hunter",name:"Hunter"},{shop_key:"code-reviewer",name:"Reviewer"}]},{key:"test-factory",name:"Test Factory",description:"Coverage from 40% to 80% overnight",lead_index:0,agents:[{shop_key:"qa-engineer",name:"Coverage Lead"},{shop_key:"backend-dev",name:"Backend"},{shop_key:"backend-dev",name:"Backend 2"},{shop_key:"qa-engineer",name:"QA"},{shop_key:"qa-engineer",name:"QA 2"},{shop_key:"code-reviewer",name:"Reviewer"}]},{key:"content-agency",name:"Content Agency",description:"Content factory: plan, write, edit, optimize",lead_index:0,agents:[{shop_key:"marketer",name:"Strategist"},{shop_key:"content-creator",name:"Writer"},{shop_key:"content-creator",name:"Writer 2"},{shop_key:"tech-writer",name:"Editor"},{shop_key:"growth-hacker",name:"SEO"}]},{key:"data-lab",name:"Data Lab",description:"3 CSVs to executive report by morning",lead_index:0,agents:[{shop_key:"data-engineer",name:"Lead Analyst"},{shop_key:"data-engineer",name:"Data Engineer"}]},{key:"sales-machine",name:"Sales Machine",description:"Outbound pipeline: research, outreach, follow-up, close",lead_index:0,agents:[{shop_key:"marketer",name:"Sales Director"},{shop_key:"content-creator",name:"SDR"},{shop_key:"content-creator",name:"SDR 2"},{shop_key:"content-creator",name:"Copywriter"},{shop_key:"growth-hacker",name:"Growth Analyst"}]},{key:"bugfix-dept",name:"Bugfix Department",description:"100 issues to 0 in a week",lead_index:0,agents:[{shop_key:"architect",name:"Triager"},{shop_key:"bug-hunter",name:"Fixer"},{shop_key:"bug-hunter",name:"Fixer 2"},{shop_key:"bug-hunter",name:"Fixer 3"},{shop_key:"qa-engineer",name:"QA"},{shop_key:"code-reviewer",name:"Reviewer"}]},{key:"docs-team",name:"Docs Team",description:"Technical docs from codebase analysis",lead_index:0,agents:[{shop_key:"architect",name:"Docs Lead"},{shop_key:"tech-writer",name:"Writer"},{shop_key:"tech-writer",name:"Writer 2"},{shop_key:"tech-writer",name:"Editor"},{shop_key:"code-reviewer",name:"Reviewer"}]}];function S(g){return l.find(t=>t.key===g)}function $(g,t){let u=g.command("org").description("Pre-built AI companies \u2014 deploy a full department with one command");u.command("list").alias("ls").description("List available company templates").action(async()=>{if(t.context.json){console.log(JSON.stringify(l,null,2));return}console.log();let s=["KEY","NAME","AGENTS","DESCRIPTION"],i=l.map(e=>[e.key,e.name,String(e.agents.length),e.description]);l$1(s,i),console.log(),console.log(` ${q("Deploy:")} orch org deploy <key> --goal "Your objective"`),console.log();}),u.command("deploy <template>").description("Deploy a pre-built AI company").option("--goal <goal>","Set a goal for the team").action(async(s,i$1)=>{let e=S(s);if(!e){i(`Unknown template "${s}"`,"Run: orch org list \u2014 to see available templates"),process.exitCode=1;return}let o=[];for(let n of e.agents){let m=b(n.shop_key);if(!m){i(`Agent shop template not found: ${n.shop_key}`),process.exitCode=1;return}try{let a=t.config.defaults.agent.adapter,p=b$1(m,a),k=await t.agentService.create({...p,name:n.name});o.push(k.id);}catch(a){i(`Failed to create agent "${n.name}": ${a instanceof Error?a.message:String(a)}`,o.length>0?`${o.length} agent(s) were already created. Clean up with: orch agent list`:void 0),process.exitCode=1;return}}let y=o[e.lead_index],x=o.filter(n=>n!==y),h=await t.teamService.create({name:e.name,description:e.description,lead_agent_id:y,member_agent_ids:x}),c;if(i$1.goal&&(c=(await t.goalService.create({title:i$1.goal,assignee:y})).id),t.context.json){console.log(JSON.stringify({team:h,agentIds:o,goalId:c},null,2));return}if(t.context.quiet){console.log(h.id);return}console.log(),j(`Deployed team "${e.name}" \u2014 ${e.agents.length} agents`),console.log();for(let n=0;n<e.agents.length;n++){let m=e.agents[n],a=o[n],p=n===e.lead_index,k=p?"lead":"member";console.log(` ${p?"\u2605":"\u2022"} ${m.name} ${q(`(${a}, ${k})`)}`);}console.log(`
|
|
3
3
|
Team: ${q(h.id)}`),c&&console.log(` Goal: ${q(c)} \u2014 "${i$1.goal}"`),console.log(),console.log(` ${q("Next:")} orch run --all --watch`),console.log();});}export{$ as registerOrgCommand};
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { createTokenUsage } from './chunk-RHFRHCN5.js';
|
|
2
|
+
import { classifyAdapterError } from './chunk-IESAV453.js';
|
|
3
|
+
import { execFile } from 'child_process';
|
|
4
|
+
|
|
5
|
+
var PiAdapter = class {
|
|
6
|
+
constructor(processManager) {
|
|
7
|
+
this.processManager = processManager;
|
|
8
|
+
}
|
|
9
|
+
kind = "pi";
|
|
10
|
+
async test() {
|
|
11
|
+
try {
|
|
12
|
+
const stdout = await new Promise((resolve, reject) => {
|
|
13
|
+
execFile("pi", ["--version"], (err, out) => {
|
|
14
|
+
if (err) reject(err);
|
|
15
|
+
else resolve(out);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
return { ok: true, version: stdout.trim() };
|
|
19
|
+
} catch (err) {
|
|
20
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21
|
+
return {
|
|
22
|
+
ok: false,
|
|
23
|
+
error: "Pi CLI not found. Install: npm i -g @mariozechner/pi-coding-agent",
|
|
24
|
+
errorKind: classifyAdapterError(msg)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
execute(params) {
|
|
29
|
+
const args = [
|
|
30
|
+
"--mode",
|
|
31
|
+
"rpc"
|
|
32
|
+
];
|
|
33
|
+
if (params.config.model) {
|
|
34
|
+
args.push("--model", params.config.model);
|
|
35
|
+
}
|
|
36
|
+
if (params.config.effort) {
|
|
37
|
+
args.push("--thinking", params.config.effort);
|
|
38
|
+
}
|
|
39
|
+
const effectiveSystemPrompt = params.systemPrompt ?? params.config.system_prompt;
|
|
40
|
+
if (effectiveSystemPrompt) {
|
|
41
|
+
args.push("--append-system-prompt", effectiveSystemPrompt);
|
|
42
|
+
}
|
|
43
|
+
const { process: proc, pid } = this.processManager.spawn("pi", args, {
|
|
44
|
+
cwd: params.workspace,
|
|
45
|
+
env: { ...process.env, ...params.env },
|
|
46
|
+
signal: params.signal,
|
|
47
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
48
|
+
});
|
|
49
|
+
const stderrTail = createStderrTailCapture(proc.stderr);
|
|
50
|
+
if (proc.stdin) {
|
|
51
|
+
proc.stdin.write(JSON.stringify({
|
|
52
|
+
id: `orch-${Date.now()}`,
|
|
53
|
+
type: "prompt",
|
|
54
|
+
message: params.prompt
|
|
55
|
+
}) + "\n");
|
|
56
|
+
}
|
|
57
|
+
const events = createPiRpcEvents(proc, pid, this.processManager, stderrTail, params.signal);
|
|
58
|
+
return { pid, events };
|
|
59
|
+
}
|
|
60
|
+
async stop(pid) {
|
|
61
|
+
await this.processManager.killWithGrace(pid);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
function createPiRpcEvents(proc, pid, processManager, stderrTail, signal) {
|
|
65
|
+
async function* generate() {
|
|
66
|
+
let gotDoneEvent = false;
|
|
67
|
+
let streamErrorYielded = false;
|
|
68
|
+
let finalText = "";
|
|
69
|
+
let lastTokens;
|
|
70
|
+
let exitCode = null;
|
|
71
|
+
let exitError = null;
|
|
72
|
+
const exitPromise = new Promise((resolve) => {
|
|
73
|
+
proc.on("close", (code) => {
|
|
74
|
+
exitCode = code;
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
proc.on("error", (err) => {
|
|
78
|
+
exitError = err;
|
|
79
|
+
resolve();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
let streamError = null;
|
|
83
|
+
try {
|
|
84
|
+
if (proc.stdout) {
|
|
85
|
+
try {
|
|
86
|
+
for await (const line of readPiRpcLines(proc.stdout)) {
|
|
87
|
+
if (signal?.aborted) break;
|
|
88
|
+
const event = parsePiRpcEvent(line, { finalText, lastTokens });
|
|
89
|
+
if (!event) continue;
|
|
90
|
+
if (event.finalText !== void 0) finalText = event.finalText;
|
|
91
|
+
if (event.tokens) lastTokens = event.tokens;
|
|
92
|
+
if (event.agentEvent) {
|
|
93
|
+
if (event.agentEvent.type === "done") gotDoneEvent = true;
|
|
94
|
+
yield event.agentEvent;
|
|
95
|
+
if (event.agentEvent.type === "done") {
|
|
96
|
+
await processManager.killWithGrace(pid, 1e3).catch(() => {
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (err) {
|
|
103
|
+
streamError = err instanceof Error ? err : new Error(String(err));
|
|
104
|
+
if (!signal?.aborted && !gotDoneEvent) {
|
|
105
|
+
streamErrorYielded = true;
|
|
106
|
+
yield {
|
|
107
|
+
type: "error",
|
|
108
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
109
|
+
data: { message: streamError.message },
|
|
110
|
+
errorKind: classifyAdapterError(streamError.message)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} finally {
|
|
116
|
+
proc.stdout?.destroy();
|
|
117
|
+
if (!gotDoneEvent && (signal?.aborted || streamError)) {
|
|
118
|
+
processManager.killWithGrace(pid, 1e3).catch(() => {
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
await exitPromise;
|
|
123
|
+
if (streamErrorYielded) return;
|
|
124
|
+
const spawnError = exitError;
|
|
125
|
+
if (spawnError && !signal?.aborted && !gotDoneEvent) {
|
|
126
|
+
const message = appendStderrTail(spawnError.message, stderrTail());
|
|
127
|
+
const classified = classifyAdapterError(message, exitCode ?? void 0);
|
|
128
|
+
throw Object.assign(new Error(message), { errorKind: classified });
|
|
129
|
+
}
|
|
130
|
+
if (exitCode !== 0 && exitCode !== null && !signal?.aborted && !gotDoneEvent) {
|
|
131
|
+
const baseMsg = `Pi process exited with code ${exitCode}`;
|
|
132
|
+
const message = appendStderrTail(baseMsg, stderrTail());
|
|
133
|
+
const classified = classifyAdapterError(message, exitCode);
|
|
134
|
+
throw Object.assign(new Error(message), { errorKind: classified });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return generate();
|
|
138
|
+
}
|
|
139
|
+
function appendStderrTail(message, tail) {
|
|
140
|
+
return tail ? `${message}
|
|
141
|
+
--- pi stderr (tail) ---
|
|
142
|
+
${tail}` : message;
|
|
143
|
+
}
|
|
144
|
+
function parsePiRpcEvent(line, state) {
|
|
145
|
+
if (!line.trim()) return null;
|
|
146
|
+
let parsed;
|
|
147
|
+
try {
|
|
148
|
+
parsed = JSON.parse(line);
|
|
149
|
+
} catch {
|
|
150
|
+
return { agentEvent: { type: "output", timestamp: (/* @__PURE__ */ new Date()).toISOString(), data: { text: line } } };
|
|
151
|
+
}
|
|
152
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
153
|
+
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
154
|
+
switch (type) {
|
|
155
|
+
case "extension_ui_request":
|
|
156
|
+
case "agent_start":
|
|
157
|
+
case "turn_start":
|
|
158
|
+
case "message_start":
|
|
159
|
+
case "message_end":
|
|
160
|
+
case "turn_end":
|
|
161
|
+
case "queue_update":
|
|
162
|
+
case "compaction_start":
|
|
163
|
+
case "compaction_end":
|
|
164
|
+
case "auto_retry_start":
|
|
165
|
+
case "auto_retry_end":
|
|
166
|
+
return extractPassiveUpdate(parsed);
|
|
167
|
+
case "response": {
|
|
168
|
+
if (parsed.success === false) {
|
|
169
|
+
const message = typeof parsed.error === "string" ? parsed.error : JSON.stringify(parsed);
|
|
170
|
+
return {
|
|
171
|
+
agentEvent: { type: "error", timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) }
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
case "message_update":
|
|
177
|
+
return parseMessageUpdate(parsed, timestamp, state);
|
|
178
|
+
case "tool_execution_start":
|
|
179
|
+
return {
|
|
180
|
+
agentEvent: {
|
|
181
|
+
type: "tool_call",
|
|
182
|
+
timestamp,
|
|
183
|
+
data: { name: parsed.toolName, input: parsed.args, raw: parsed }
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
case "tool_execution_update":
|
|
187
|
+
return null;
|
|
188
|
+
case "tool_execution_end":
|
|
189
|
+
return parseToolExecutionEnd(parsed, timestamp);
|
|
190
|
+
case "agent_end": {
|
|
191
|
+
const final = extractFinalText(parsed) ?? state.finalText;
|
|
192
|
+
const tokens = extractPiTokensFromAgentEnd(parsed) ?? state.lastTokens;
|
|
193
|
+
return {
|
|
194
|
+
finalText: final,
|
|
195
|
+
tokens,
|
|
196
|
+
agentEvent: {
|
|
197
|
+
type: "done",
|
|
198
|
+
timestamp,
|
|
199
|
+
data: { result: final, raw: parsed },
|
|
200
|
+
tokens
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
case "extension_error": {
|
|
205
|
+
const message = typeof parsed.message === "string" ? parsed.message : JSON.stringify(parsed);
|
|
206
|
+
return {
|
|
207
|
+
agentEvent: { type: "error", timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) }
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
default:
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function parseMessageUpdate(parsed, timestamp, state) {
|
|
215
|
+
const assistantMessageEvent = parsed.assistantMessageEvent;
|
|
216
|
+
const updateType = typeof assistantMessageEvent?.type === "string" ? assistantMessageEvent.type : "";
|
|
217
|
+
if (updateType === "text_delta") {
|
|
218
|
+
const delta = typeof assistantMessageEvent?.delta === "string" ? assistantMessageEvent.delta : "";
|
|
219
|
+
return { finalText: state.finalText + delta };
|
|
220
|
+
}
|
|
221
|
+
if (updateType === "text_end") {
|
|
222
|
+
const content = typeof assistantMessageEvent?.content === "string" ? assistantMessageEvent.content : state.finalText;
|
|
223
|
+
if (!content) return { finalText: "" };
|
|
224
|
+
return {
|
|
225
|
+
finalText: "",
|
|
226
|
+
agentEvent: { type: "output", timestamp, data: { text: content } }
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (updateType === "error") {
|
|
230
|
+
const reason = typeof assistantMessageEvent?.reason === "string" ? assistantMessageEvent.reason : JSON.stringify(parsed);
|
|
231
|
+
return {
|
|
232
|
+
agentEvent: { type: "error", timestamp, data: { message: reason, raw: parsed }, errorKind: classifyAdapterError(reason) }
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
function parseToolExecutionEnd(parsed, timestamp) {
|
|
238
|
+
const toolName = typeof parsed.toolName === "string" ? parsed.toolName : "";
|
|
239
|
+
const args = parsed.args;
|
|
240
|
+
const resultText = extractToolResultText(parsed.result);
|
|
241
|
+
if (parsed.isError === true) {
|
|
242
|
+
const message = resultText || JSON.stringify(parsed.result ?? parsed);
|
|
243
|
+
return {
|
|
244
|
+
agentEvent: { type: "error", timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) }
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (toolName === "bash") {
|
|
248
|
+
const command = typeof args?.command === "string" ? args.command : JSON.stringify(args ?? {});
|
|
249
|
+
return {
|
|
250
|
+
agentEvent: {
|
|
251
|
+
type: "command",
|
|
252
|
+
timestamp,
|
|
253
|
+
data: { command, result: resultText, raw: parsed }
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (/^(write|edit)$/i.test(toolName)) {
|
|
258
|
+
const path = extractPath(args);
|
|
259
|
+
if (path) {
|
|
260
|
+
return {
|
|
261
|
+
agentEvent: {
|
|
262
|
+
type: "file_change",
|
|
263
|
+
timestamp,
|
|
264
|
+
data: { paths: [path], raw: parsed }
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const summary = resultText || `${toolName || "tool"} completed`;
|
|
270
|
+
return { agentEvent: { type: "output", timestamp, data: { text: summary, raw: parsed } } };
|
|
271
|
+
}
|
|
272
|
+
function extractToolResultText(result) {
|
|
273
|
+
if (typeof result === "string") return result;
|
|
274
|
+
if (!result || typeof result !== "object") return "";
|
|
275
|
+
return extractTextFromContent(result.content) ?? "";
|
|
276
|
+
}
|
|
277
|
+
function extractPassiveUpdate(parsed) {
|
|
278
|
+
const tokens = extractPiTokensFromMessage(parsed);
|
|
279
|
+
return tokens ? { tokens } : null;
|
|
280
|
+
}
|
|
281
|
+
function extractFinalText(parsed) {
|
|
282
|
+
const messages = parsed.messages;
|
|
283
|
+
if (!Array.isArray(messages)) return void 0;
|
|
284
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
285
|
+
const message = messages[i];
|
|
286
|
+
if (message.role !== "assistant") continue;
|
|
287
|
+
const text = extractTextFromContent(message.content);
|
|
288
|
+
if (text) return text;
|
|
289
|
+
}
|
|
290
|
+
return void 0;
|
|
291
|
+
}
|
|
292
|
+
function extractTextFromContent(content) {
|
|
293
|
+
if (typeof content === "string") return content;
|
|
294
|
+
if (!Array.isArray(content)) return void 0;
|
|
295
|
+
const parts = content.map((part) => {
|
|
296
|
+
const p = part;
|
|
297
|
+
return typeof p.text === "string" ? p.text : "";
|
|
298
|
+
}).filter(Boolean);
|
|
299
|
+
return parts.length ? parts.join("") : void 0;
|
|
300
|
+
}
|
|
301
|
+
function extractPath(args) {
|
|
302
|
+
if (!args) return void 0;
|
|
303
|
+
if (typeof args.path === "string") return args.path;
|
|
304
|
+
if (typeof args.file_path === "string") return args.file_path;
|
|
305
|
+
return void 0;
|
|
306
|
+
}
|
|
307
|
+
function extractPiTokensFromAgentEnd(parsed) {
|
|
308
|
+
const messages = parsed.messages;
|
|
309
|
+
if (!Array.isArray(messages)) return void 0;
|
|
310
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
311
|
+
const message = messages[i];
|
|
312
|
+
if (message.role !== "assistant") continue;
|
|
313
|
+
const tokens = extractPiTokensFromMessage(message);
|
|
314
|
+
if (tokens) return tokens;
|
|
315
|
+
}
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
var PI_TOKEN_ALIASES = {
|
|
319
|
+
input: ["input", "input_tokens"],
|
|
320
|
+
output: ["output", "output_tokens"],
|
|
321
|
+
reasoning: ["reasoning", "reasoning_tokens"],
|
|
322
|
+
cache_read: ["cacheRead", "cache_read", "cache_read_input_tokens"],
|
|
323
|
+
cache_write: ["cacheWrite", "cache_write", "cache_creation_input_tokens"]
|
|
324
|
+
};
|
|
325
|
+
function extractPiTokensFromMessage(parsed) {
|
|
326
|
+
const usage = parsed.usage;
|
|
327
|
+
if (!usage) return void 0;
|
|
328
|
+
const pick = (keys) => {
|
|
329
|
+
for (const k of keys) {
|
|
330
|
+
const v = usage[k];
|
|
331
|
+
if (typeof v === "number") return v;
|
|
332
|
+
}
|
|
333
|
+
return 0;
|
|
334
|
+
};
|
|
335
|
+
const input = pick(PI_TOKEN_ALIASES.input);
|
|
336
|
+
const output = pick(PI_TOKEN_ALIASES.output);
|
|
337
|
+
const reasoning = pick(PI_TOKEN_ALIASES.reasoning);
|
|
338
|
+
const cache_read = pick(PI_TOKEN_ALIASES.cache_read);
|
|
339
|
+
const cache_write = pick(PI_TOKEN_ALIASES.cache_write);
|
|
340
|
+
if (input === 0 && output === 0 && reasoning === 0 && cache_read === 0 && cache_write === 0) return void 0;
|
|
341
|
+
return createTokenUsage(input, output, { reasoning, cache_read, cache_write });
|
|
342
|
+
}
|
|
343
|
+
var STDERR_TAIL_BYTES = 4096;
|
|
344
|
+
function createStderrTailCapture(stderr) {
|
|
345
|
+
if (!stderr) return () => "";
|
|
346
|
+
let buf = Buffer.alloc(0);
|
|
347
|
+
stderr.on("data", (chunk) => {
|
|
348
|
+
const next = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf-8");
|
|
349
|
+
buf = buf.length === 0 ? next : Buffer.concat([buf, next], buf.length + next.length);
|
|
350
|
+
if (buf.length > STDERR_TAIL_BYTES) {
|
|
351
|
+
buf = Buffer.from(buf.subarray(buf.length - STDERR_TAIL_BYTES));
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
stderr.on("error", () => {
|
|
355
|
+
});
|
|
356
|
+
return () => buf.toString("utf-8").trimEnd();
|
|
357
|
+
}
|
|
358
|
+
async function* readPiRpcLines(stream) {
|
|
359
|
+
const chunks = [];
|
|
360
|
+
let totalLen = 0;
|
|
361
|
+
for await (const chunk of stream) {
|
|
362
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf-8");
|
|
363
|
+
if (buf.length === 0) continue;
|
|
364
|
+
chunks.push(buf);
|
|
365
|
+
totalLen += buf.length;
|
|
366
|
+
const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, totalLen);
|
|
367
|
+
chunks.length = 0;
|
|
368
|
+
totalLen = 0;
|
|
369
|
+
let offset = 0;
|
|
370
|
+
let newlineIdx;
|
|
371
|
+
while ((newlineIdx = buffer.indexOf(10, offset)) !== -1) {
|
|
372
|
+
if (newlineIdx > offset) {
|
|
373
|
+
const line = buffer.toString("utf-8", offset, newlineIdx);
|
|
374
|
+
yield line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
375
|
+
}
|
|
376
|
+
offset = newlineIdx + 1;
|
|
377
|
+
}
|
|
378
|
+
if (offset < buffer.length) {
|
|
379
|
+
const remainder = buffer.subarray(offset);
|
|
380
|
+
chunks.push(remainder);
|
|
381
|
+
totalLen = remainder.length;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (totalLen > 0) {
|
|
385
|
+
const final = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, totalLen);
|
|
386
|
+
const line = final.toString("utf-8");
|
|
387
|
+
if (line) yield line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export { PiAdapter };
|
|
392
|
+
//# sourceMappingURL=pi-GFJCLRZJ.js.map
|
|
393
|
+
//# sourceMappingURL=pi-GFJCLRZJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/infrastructure/adapters/pi.ts"],"names":[],"mappings":";;;;AAgBO,IAAM,YAAN,MAAyC;AAAA,EAG9C,YAA6B,cAAA,EAAiC;AAAjC,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAAA,EAAkC;AAAA,EAFtD,IAAA,GAAO,IAAA;AAAA,EAIhB,MAAM,IAAA,GAAmC;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAM,IAAI,OAAA,CAAgB,CAAC,SAAS,MAAA,KAAW;AAC5D,QAAA,QAAA,CAAS,MAAM,CAAC,WAAW,CAAA,EAAG,CAAC,KAAK,GAAA,KAAQ;AAC1C,UAAA,IAAI,GAAA,SAAY,GAAG,CAAA;AAAA,uBACN,GAAG,CAAA;AAAA,QAClB,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,MAAA,CAAO,MAAK,EAAE;AAAA,IAC5C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,KAAA,EAAO,mEAAA;AAAA,QACP,SAAA,EAAW,qBAAqB,GAAG;AAAA,OACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ,MAAA,EAAsC;AAC5C,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,QAAA;AAAA,MAAU;AAAA,KACZ;AAEA,IAAA,IAAI,MAAA,CAAO,OAAO,KAAA,EAAO;AACvB,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAI,MAAA,CAAO,OAAO,MAAA,EAAQ;AACxB,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AAAA,IAC9C;AAIA,IAAA,MAAM,qBAAA,GAAwB,MAAA,CAAO,YAAA,IAAgB,MAAA,CAAO,MAAA,CAAO,aAAA;AACnE,IAAA,IAAI,qBAAA,EAAuB;AACzB,MAAA,IAAA,CAAK,IAAA,CAAK,0BAA0B,qBAAqB,CAAA;AAAA,IAC3D;AAEA,IAAA,MAAM,EAAE,SAAS,IAAA,EAAM,GAAA,KAAQ,IAAA,CAAK,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM;AAAA,MACnE,KAAK,MAAA,CAAO,SAAA;AAAA,MACZ,KAAK,EAAE,GAAG,QAAQ,GAAA,EAAK,GAAG,OAAO,GAAA,EAAI;AAAA,MACrC,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM;AAAA,KAC/B,CAAA;AAID,IAAA,MAAM,UAAA,GAAa,uBAAA,CAAwB,IAAA,CAAK,MAAM,CAAA;AAEtD,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU;AAAA,QAC9B,EAAA,EAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA;AAAA,QACtB,IAAA,EAAM,QAAA;AAAA,QACN,SAAS,MAAA,CAAO;AAAA,OACjB,IAAI,IAAI,CAAA;AAAA,IASX;AAEA,IAAA,MAAM,MAAA,GAAS,kBAAkB,IAAA,EAAM,GAAA,EAAK,KAAK,cAAA,EAAgB,UAAA,EAAY,OAAO,MAAM,CAAA;AAC1F,IAAA,OAAO,EAAE,KAAK,MAAA,EAAO;AAAA,EACvB;AAAA,EAEA,MAAM,KAAK,GAAA,EAA4B;AACrC,IAAA,MAAM,IAAA,CAAK,cAAA,CAAe,aAAA,CAAc,GAAG,CAAA;AAAA,EAC7C;AACF;AAEA,SAAS,iBAAA,CACP,IAAA,EACA,GAAA,EACA,cAAA,EACA,YACA,MAAA,EAC4B;AAC5B,EAAA,gBAAgB,QAAA,GAAuC;AACrD,IAAA,IAAI,YAAA,GAAe,KAAA;AACnB,IAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,QAAA,GAA0B,IAAA;AAC9B,IAAA,IAAI,SAAA,GAA0B,IAAA;AAE9B,IAAA,MAAM,WAAA,GAAc,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACjD,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,EAAS,CAAC,IAAA,KAAS;AAAE,QAAA,QAAA,GAAW,IAAA;AAAM,QAAA,OAAA,EAAQ;AAAA,MAAG,CAAC,CAAA;AAC1D,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AAAE,QAAA,SAAA,GAAY,GAAA;AAAK,QAAA,OAAA,EAAQ;AAAA,MAAG,CAAC,CAAA;AAAA,IAC3D,CAAC,CAAA;AAED,IAAA,IAAI,WAAA,GAA4B,IAAA;AAChC,IAAA,IAAI;AACF,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAI;AACF,UAAA,WAAA,MAAiB,IAAA,IAAQ,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA,EAAG;AACpD,YAAA,IAAI,QAAQ,OAAA,EAAS;AACrB,YAAA,MAAM,QAAQ,eAAA,CAAgB,IAAA,EAAM,EAAE,SAAA,EAAW,YAAY,CAAA;AAC7D,YAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,YAAA,IAAI,KAAA,CAAM,SAAA,KAAc,KAAA,CAAA,EAAW,SAAA,GAAY,KAAA,CAAM,SAAA;AACrD,YAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,UAAA,GAAa,KAAA,CAAM,MAAA;AAErC,YAAA,IAAI,MAAM,UAAA,EAAY;AACpB,cAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAA,KAAS,MAAA,EAAQ,YAAA,GAAe,IAAA;AACrD,cAAA,MAAM,KAAA,CAAM,UAAA;AACZ,cAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAA,KAAS,MAAA,EAAQ;AAGpC,gBAAA,MAAM,eAAe,aAAA,CAAc,GAAA,EAAK,GAAK,CAAA,CAAE,MAAM,MAAM;AAAA,gBAAC,CAAC,CAAA;AAC7D,gBAAA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,GAAA,EAAK;AAIZ,UAAA,WAAA,GAAc,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,UAAA,IAAI,CAAC,MAAA,EAAQ,OAAA,IAAW,CAAC,YAAA,EAAc;AACrC,YAAA,kBAAA,GAAqB,IAAA;AACrB,YAAA,MAAM;AAAA,cACJ,IAAA,EAAM,OAAA;AAAA,cACN,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,cAClC,IAAA,EAAM,EAAE,OAAA,EAAS,WAAA,CAAY,OAAA,EAAQ;AAAA,cACrC,SAAA,EAAW,oBAAA,CAAqB,WAAA,CAAY,OAAO;AAAA,aACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAQ,OAAA,EAAQ;AAIrB,MAAA,IAAI,CAAC,YAAA,KAAiB,MAAA,EAAQ,OAAA,IAAW,WAAA,CAAA,EAAc;AACrD,QAAA,cAAA,CAAe,aAAA,CAAc,GAAA,EAAK,GAAK,CAAA,CAAE,MAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MACzD;AAAA,IACF;AAEA,IAAA,MAAM,WAAA;AAGN,IAAA,IAAI,kBAAA,EAAoB;AAExB,IAAA,MAAM,UAAA,GAAa,SAAA;AACnB,IAAA,IAAI,UAAA,IAAc,CAAC,MAAA,EAAQ,OAAA,IAAW,CAAC,YAAA,EAAc;AACnD,MAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,UAAA,CAAW,OAAA,EAAS,YAAY,CAAA;AACjE,MAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,OAAA,EAAS,QAAA,IAAY,MAAS,CAAA;AACtE,MAAA,MAAM,MAAA,CAAO,OAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,SAAA,EAAW,UAAA,EAAY,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,QAAA,KAAa,KAAK,QAAA,KAAa,IAAA,IAAQ,CAAC,MAAA,EAAQ,OAAA,IAAW,CAAC,YAAA,EAAc;AAC5E,MAAA,MAAM,OAAA,GAAU,+BAA+B,QAAQ,CAAA,CAAA;AACvD,MAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,OAAA,EAAS,UAAA,EAAY,CAAA;AACtD,MAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,OAAA,EAAS,QAAQ,CAAA;AACzD,MAAA,MAAM,MAAA,CAAO,OAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,SAAA,EAAW,UAAA,EAAY,CAAA;AAAA,IACnE;AAAA,EACF;AAEA,EAAA,OAAO,QAAA,EAAS;AAClB;AAEA,SAAS,gBAAA,CAAiB,SAAiB,IAAA,EAAsB;AAC/D,EAAA,OAAO,IAAA,GAAO,GAAG,OAAO;AAAA;AAAA,EAA+B,IAAI,CAAA,CAAA,GAAK,OAAA;AAClE;AAaA,SAAS,eAAA,CAAgB,MAAc,KAAA,EAAyC;AAC9E,EAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG,OAAO,IAAA;AAEzB,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,4BAAW,IAAI,IAAA,EAAK,EAAE,WAAA,IAAe,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,IAAO,EAAE;AAAA,EACrG;AAEA,EAAA,MAAM,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACzC,EAAA,MAAM,OAAO,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,GAAO,EAAA;AAE7D,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,sBAAA;AAAA,IACL,KAAK,aAAA;AAAA,IACL,KAAK,YAAA;AAAA,IACL,KAAK,eAAA;AAAA,IACL,KAAK,aAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AAAA,IACL,KAAK,kBAAA;AAAA,IACL,KAAK,gBAAA;AAAA,IACL,KAAK,kBAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,qBAAqB,MAAM,CAAA;AAAA,IAEpC,KAAK,UAAA,EAAY;AACf,MAAA,IAAI,MAAA,CAAO,YAAY,KAAA,EAAO;AAC5B,QAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,KAAA,KAAU,WAAW,MAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACvF,QAAA,OAAO;AAAA,UACL,UAAA,EAAY,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,IAAA,EAAM,EAAE,OAAA,EAAS,GAAA,EAAK,MAAA,EAAO,EAAG,SAAA,EAAW,oBAAA,CAAqB,OAAO,CAAA;AAAE,SACnH;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,IAEA,KAAK,gBAAA;AACH,MAAA,OAAO,kBAAA,CAAmB,MAAA,EAAQ,SAAA,EAAW,KAAK,CAAA;AAAA,IAEpD,KAAK,sBAAA;AACH,MAAA,OAAO;AAAA,QACL,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,WAAA;AAAA,UACN,SAAA;AAAA,UACA,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,CAAO,UAAU,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,GAAA,EAAK,MAAA;AAAO;AACjE,OACF;AAAA,IAEF,KAAK,uBAAA;AAIH,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,oBAAA;AACH,MAAA,OAAO,qBAAA,CAAsB,QAAQ,SAAS,CAAA;AAAA,IAEhD,KAAK,WAAA,EAAa;AAChB,MAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,MAAM,CAAA,IAAK,KAAA,CAAM,SAAA;AAChD,MAAA,MAAM,MAAA,GAAS,2BAAA,CAA4B,MAAM,CAAA,IAAK,KAAA,CAAM,UAAA;AAC5D,MAAA,OAAO;AAAA,QACL,SAAA,EAAW,KAAA;AAAA,QACX,MAAA;AAAA,QACA,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,MAAA;AAAA,UACN,SAAA;AAAA,UACA,IAAA,EAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAK,MAAA,EAAO;AAAA,UACnC;AAAA;AACF,OACF;AAAA,IACF;AAAA,IAEA,KAAK,iBAAA,EAAmB;AACtB,MAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,OAAA,KAAY,WAAW,MAAA,CAAO,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAC3F,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,IAAA,EAAM,EAAE,OAAA,EAAS,GAAA,EAAK,MAAA,EAAO,EAAG,SAAA,EAAW,oBAAA,CAAqB,OAAO,CAAA;AAAE,OACnH;AAAA,IACF;AAAA,IAEA;AAIE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,SAAS,kBAAA,CAAmB,MAAA,EAAiC,SAAA,EAAmB,KAAA,EAAyC;AACvH,EAAA,MAAM,wBAAwB,MAAA,CAAO,qBAAA;AACrC,EAAA,MAAM,aAAa,OAAO,qBAAA,EAAuB,IAAA,KAAS,QAAA,GAAW,sBAAsB,IAAA,GAAO,EAAA;AAElG,EAAA,IAAI,eAAe,YAAA,EAAc;AAK/B,IAAA,MAAM,QAAQ,OAAO,qBAAA,EAAuB,KAAA,KAAU,QAAA,GAAW,sBAAsB,KAAA,GAAQ,EAAA;AAC/F,IAAA,OAAO,EAAE,SAAA,EAAW,KAAA,CAAM,SAAA,GAAY,KAAA,EAAM;AAAA,EAC9C;AAEA,EAAA,IAAI,eAAe,UAAA,EAAY;AAC7B,IAAA,MAAM,UAAU,OAAO,qBAAA,EAAuB,YAAY,QAAA,GAAW,qBAAA,CAAsB,UAAU,KAAA,CAAM,SAAA;AAI3G,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAE,WAAW,EAAA,EAAG;AACrC,IAAA,OAAO;AAAA,MACL,SAAA,EAAW,EAAA;AAAA,MACX,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,EAAM,EAAE,IAAA,EAAM,OAAA,EAAQ;AAAE,KACnE;AAAA,EACF;AAEA,EAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,IAAA,MAAM,MAAA,GAAS,OAAO,qBAAA,EAAuB,MAAA,KAAW,WAAW,qBAAA,CAAsB,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACvH,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,IAAA,EAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAK,MAAA,EAAO,EAAG,SAAA,EAAW,oBAAA,CAAqB,MAAM,CAAA;AAAE,KAC1H;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,qBAAA,CAAsB,QAAiC,SAAA,EAAkC;AAChG,EAAA,MAAM,WAAW,OAAO,MAAA,CAAO,QAAA,KAAa,QAAA,GAAW,OAAO,QAAA,GAAW,EAAA;AACzE,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,MAAA,CAAO,MAAM,CAAA;AAEtD,EAAA,IAAI,MAAA,CAAO,YAAY,IAAA,EAAM;AAC3B,IAAA,MAAM,UAAU,UAAA,IAAc,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,UAAU,MAAM,CAAA;AACpE,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,IAAA,EAAM,EAAE,OAAA,EAAS,GAAA,EAAK,MAAA,EAAO,EAAG,SAAA,EAAW,oBAAA,CAAqB,OAAO,CAAA;AAAE,KACnH;AAAA,EACF;AAEA,EAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAM,OAAA,KAAY,QAAA,GAAW,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC5F,IAAA,OAAO;AAAA,MACL,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,SAAA;AAAA,QACN,SAAA;AAAA,QACA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,KAAK,MAAA;AAAO;AACnD,KACF;AAAA,EACF;AAEA,EAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,QAAQ,CAAA,EAAG;AACpC,IAAA,MAAM,IAAA,GAAO,YAAY,IAAI,CAAA;AAC7B,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,OAAO;AAAA,QACL,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,aAAA;AAAA,UACN,SAAA;AAAA,UACA,MAAM,EAAE,KAAA,EAAO,CAAC,IAAI,CAAA,EAAG,KAAK,MAAA;AAAO;AACrC,OACF;AAAA,IACF;AAAA,EACF;AAIA,EAAA,MAAM,OAAA,GAAU,UAAA,IAAc,CAAA,EAAG,QAAA,IAAY,MAAM,CAAA,UAAA,CAAA;AACnD,EAAA,OAAO,EAAE,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,IAAA,EAAM,EAAE,IAAA,EAAM,OAAA,EAAS,GAAA,EAAK,MAAA,IAAS,EAAE;AAC3F;AAGA,SAAS,sBAAsB,MAAA,EAAyB;AACtD,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,EAAU,OAAO,MAAA;AACvC,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,UAAU,OAAO,EAAA;AAClD,EAAA,OAAO,sBAAA,CAAwB,MAAA,CAAiC,OAAO,CAAA,IAAK,EAAA;AAC9E;AAEA,SAAS,qBAAqB,MAAA,EAAuD;AACnF,EAAA,MAAM,MAAA,GAAS,2BAA2B,MAAM,CAAA;AAChD,EAAA,OAAO,MAAA,GAAS,EAAE,MAAA,EAAO,GAAI,IAAA;AAC/B;AAEA,SAAS,iBAAiB,MAAA,EAAqD;AAC7E,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AACxB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,GAAG,OAAO,MAAA;AAErC,EAAA,KAAA,IAAS,IAAI,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,IAAA,IAAI,OAAA,CAAQ,SAAS,WAAA,EAAa;AAClC,IAAA,MAAM,IAAA,GAAO,sBAAA,CAAuB,OAAA,CAAQ,OAAO,CAAA;AACnD,IAAA,IAAI,MAAM,OAAO,IAAA;AAAA,EACnB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,uBAAuB,OAAA,EAAsC;AACpE,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,GAAG,OAAO,MAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,OAAA,CACX,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,IAAA,MAAM,CAAA,GAAI,IAAA;AACV,IAAA,OAAO,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,GAAO,EAAA;AAAA,EAC/C,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA;AACjB,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA,GAAI,MAAA;AACzC;AAEA,SAAS,YAAY,IAAA,EAA+D;AAClF,EAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,SAAiB,IAAA,CAAK,IAAA;AAC/C,EAAA,IAAI,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,SAAiB,IAAA,CAAK,SAAA;AACpD,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,4BAA4B,MAAA,EAAyD;AAC5F,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AACxB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,GAAG,OAAO,MAAA;AAErC,EAAA,KAAA,IAAS,IAAI,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,IAAA,IAAI,OAAA,CAAQ,SAAS,WAAA,EAAa;AAClC,IAAA,MAAM,MAAA,GAAS,2BAA2B,OAAO,CAAA;AACjD,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AACA,EAAA,OAAO,MAAA;AACT;AAMA,IAAM,gBAAA,GAA+G;AAAA,EACnH,KAAA,EAAa,CAAC,OAAA,EAAS,cAAc,CAAA;AAAA,EACrC,MAAA,EAAa,CAAC,QAAA,EAAU,eAAe,CAAA;AAAA,EACvC,SAAA,EAAa,CAAC,WAAA,EAAa,kBAAkB,CAAA;AAAA,EAC7C,UAAA,EAAa,CAAC,WAAA,EAAa,YAAA,EAAc,yBAAyB,CAAA;AAAA,EAClE,WAAA,EAAa,CAAC,YAAA,EAAc,aAAA,EAAe,6BAA6B;AAC1E,CAAA;AAEA,SAAS,2BAA2B,MAAA,EAAyD;AAC3F,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AAEnB,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAAoC;AAChD,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,MAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACjB,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,gBAAA,CAAiB,KAAK,CAAA;AACzC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,MAAM,CAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,gBAAA,CAAiB,SAAS,CAAA;AACjD,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,gBAAA,CAAiB,UAAU,CAAA;AACnD,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,gBAAA,CAAiB,WAAW,CAAA;AAErD,EAAA,IAAI,KAAA,KAAU,CAAA,IAAK,MAAA,KAAW,CAAA,IAAK,SAAA,KAAc,KAAK,UAAA,KAAe,CAAA,IAAK,WAAA,KAAgB,CAAA,EAAG,OAAO,MAAA;AACpG,EAAA,OAAO,iBAAiB,KAAA,EAAO,MAAA,EAAQ,EAAE,SAAA,EAAW,UAAA,EAAY,aAAa,CAAA;AAC/E;AAWA,IAAM,iBAAA,GAAoB,IAAA;AAC1B,SAAS,wBAAwB,MAAA,EAAmD;AAClF,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,MAAM,EAAA;AAC1B,EAAA,IAAI,GAAA,GAAc,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AAChC,EAAA,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAA2B;AAC5C,IAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,KAAK,IAAI,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA;AACxE,IAAA,GAAA,GAAM,GAAA,CAAI,MAAA,KAAW,CAAA,GAAI,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,CAAC,GAAA,EAAK,IAAI,CAAA,EAAG,GAAA,CAAI,MAAA,GAAS,KAAK,MAAM,CAAA;AACnF,IAAA,IAAI,GAAA,CAAI,SAAS,iBAAA,EAAmB;AAIlC,MAAA,GAAA,GAAM,OAAO,IAAA,CAAK,GAAA,CAAI,SAAS,GAAA,CAAI,MAAA,GAAS,iBAAiB,CAAC,CAAA;AAAA,IAChE;AAAA,EACF,CAAC,CAAA;AACD,EAAA,MAAA,CAAO,EAAA,CAAG,SAAS,MAAM;AAAA,EAAC,CAAC,CAAA;AAC3B,EAAA,OAAO,MAAM,GAAA,CAAI,QAAA,CAAS,OAAO,EAAE,OAAA,EAAQ;AAC7C;AAYA,gBAAgB,eAAe,MAAA,EAA0C;AACvE,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,QAAA,GAAW,CAAA;AAEf,EAAA,WAAA,MAAiB,SAAS,MAAA,EAAQ;AAChC,IAAA,MAAM,GAAA,GAAM,OAAO,QAAA,CAAS,KAAK,IAAI,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,KAAA,EAAiB,OAAO,CAAA;AACjF,IAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACtB,IAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AACf,IAAA,QAAA,IAAY,GAAA,CAAI,MAAA;AAEhB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,QAAQ,CAAA;AAChF,IAAA,MAAA,CAAO,MAAA,GAAS,CAAA;AAChB,IAAA,QAAA,GAAW,CAAA;AAEX,IAAA,IAAI,MAAA,GAAS,CAAA;AACb,IAAA,IAAI,UAAA;AACJ,IAAA,OAAA,CAAQ,aAAa,MAAA,CAAO,OAAA,CAAQ,EAAA,EAAM,MAAM,OAAO,EAAA,EAAI;AACzD,MAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,QAAA,CAAS,OAAA,EAAS,QAAQ,UAAU,CAAA;AACxD,QAAA,MAAM,IAAA,CAAK,SAAS,IAAI,CAAA,GAAI,KAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,IAAA;AAAA,MAClD;AACA,MAAA,MAAA,GAAS,UAAA,GAAa,CAAA;AAAA,IACxB;AAEA,IAAA,IAAI,MAAA,GAAS,OAAO,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA;AACxC,MAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AACrB,MAAA,QAAA,GAAW,SAAA,CAAU,MAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,QAAQ,CAAA;AAC/E,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA;AACnC,IAAA,IAAI,IAAA,EAAM,MAAM,IAAA,CAAK,QAAA,CAAS,IAAI,IAAI,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,IAAA;AAAA,EAC5D;AACF","file":"pi-GFJCLRZJ.js","sourcesContent":["/**\n * Pi coding agent adapter.\n *\n * Spawns `pi --mode rpc` in headless RPC mode.\n * Sends the ORCH prompt as a JSONL `prompt` command over stdin and maps Pi\n * RPC events from stdout into ORCH AgentEvents. Pi extensions/skills/context\n * remain enabled by default; UI-only extension events are ignored.\n */\n\nimport type { IAgentAdapter, AdapterTestResult, ExecuteParams, AgentEvent, ExecuteHandle } from './interface.js';\nimport type { IProcessManager } from '../process/process-manager.js';\nimport type { Readable } from 'node:stream';\nimport { createTokenUsage, type TokenUsage } from '../../domain/run.js';\nimport { classifyAdapterError } from '../../domain/errors.js';\nimport { execFile } from 'node:child_process';\n\nexport class PiAdapter implements IAgentAdapter {\n readonly kind = 'pi';\n\n constructor(private readonly processManager: IProcessManager) {}\n\n async test(): Promise<AdapterTestResult> {\n try {\n const stdout = await new Promise<string>((resolve, reject) => {\n execFile('pi', ['--version'], (err, out) => {\n if (err) reject(err);\n else resolve(out);\n });\n });\n return { ok: true, version: stdout.trim() };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n ok: false,\n error: 'Pi CLI not found. Install: npm i -g @mariozechner/pi-coding-agent',\n errorKind: classifyAdapterError(msg),\n };\n }\n }\n\n execute(params: ExecuteParams): ExecuteHandle {\n const args = [\n '--mode', 'rpc',\n ];\n\n if (params.config.model) {\n args.push('--model', params.config.model);\n }\n\n if (params.config.effort) {\n args.push('--thinking', params.config.effort);\n }\n\n // Preserve Pi's own coding-agent harness prompt. ORCH's system prompt is\n // appended as additional project/task governance rather than replacing it.\n const effectiveSystemPrompt = params.systemPrompt ?? params.config.system_prompt;\n if (effectiveSystemPrompt) {\n args.push('--append-system-prompt', effectiveSystemPrompt);\n }\n\n const { process: proc, pid } = this.processManager.spawn('pi', args, {\n cwd: params.workspace,\n env: { ...process.env, ...params.env },\n signal: params.signal,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Capture stderr tail so auth/extension-load errors surface in non-zero exits\n // rather than being silently drained. Drains backpressure at the same time.\n const stderrTail = createStderrTailCapture(proc.stderr);\n\n if (proc.stdin) {\n proc.stdin.write(JSON.stringify({\n id: `orch-${Date.now()}`,\n type: 'prompt',\n message: params.prompt,\n }) + '\\n');\n // DO NOT call proc.stdin.end() here. Pi --mode rpc is a long-lived\n // persistent session: it sends a prompt preflight response, then drives\n // the LLM call asynchronously, streaming message_update / turn_end /\n // agent_end as the model responds. Closing stdin after the write breaks\n // that pipeline — verified on pi-coding-agent 0.73.1: pi stalls right\n // after the user-message_end event and never produces an assistant turn.\n // We terminate the long-lived process via processManager.killWithGrace\n // immediately after the terminal `done` event (see createPiRpcEvents).\n }\n\n const events = createPiRpcEvents(proc, pid, this.processManager, stderrTail, params.signal);\n return { pid, events };\n }\n\n async stop(pid: number): Promise<void> {\n await this.processManager.killWithGrace(pid);\n }\n}\n\nfunction createPiRpcEvents(\n proc: import('node:child_process').ChildProcess,\n pid: number,\n processManager: IProcessManager,\n stderrTail: () => string,\n signal?: AbortSignal,\n): AsyncGenerator<AgentEvent> {\n async function* generate(): AsyncGenerator<AgentEvent> {\n let gotDoneEvent = false;\n let streamErrorYielded = false;\n let finalText = '';\n let lastTokens: TokenUsage | undefined;\n let exitCode: number | null = null;\n let exitError: Error | null = null;\n\n const exitPromise = new Promise<void>((resolve) => {\n proc.on('close', (code) => { exitCode = code; resolve(); });\n proc.on('error', (err) => { exitError = err; resolve(); });\n });\n\n let streamError: Error | null = null;\n try {\n if (proc.stdout) {\n try {\n for await (const line of readPiRpcLines(proc.stdout)) {\n if (signal?.aborted) break;\n const event = parsePiRpcEvent(line, { finalText, lastTokens });\n if (!event) continue;\n\n if (event.finalText !== undefined) finalText = event.finalText;\n if (event.tokens) lastTokens = event.tokens;\n\n if (event.agentEvent) {\n if (event.agentEvent.type === 'done') gotDoneEvent = true;\n yield event.agentEvent;\n if (event.agentEvent.type === 'done') {\n // Pi RPC is a long-lived process. ORCH tasks are one-shot runs, so\n // stop Pi after the terminal event instead of waiting forever.\n await processManager.killWithGrace(pid, 1_000).catch(() => {});\n return;\n }\n }\n }\n } catch (err) {\n // stdout emitted 'error' (ECONNRESET, EPIPE, etc) before a terminal event.\n // Without this catch the rejection propagates out of the async generator\n // as an unhandled error and the orchestrator only sees the run hang.\n streamError = err instanceof Error ? err : new Error(String(err));\n if (!signal?.aborted && !gotDoneEvent) {\n streamErrorYielded = true;\n yield {\n type: 'error',\n timestamp: new Date().toISOString(),\n data: { message: streamError.message },\n errorKind: classifyAdapterError(streamError.message),\n };\n }\n }\n }\n } finally {\n proc.stdout?.destroy();\n // Pi RPC is long-lived. If we leave via abort/break without a 'done' event,\n // the process is still alive — kill it so exitPromise resolves and the\n // generator doesn't pin the ChildProcess via dangling 'close' / 'error' listeners.\n if (!gotDoneEvent && (signal?.aborted || streamError)) {\n processManager.killWithGrace(pid, 1_000).catch(() => {});\n }\n }\n\n await exitPromise;\n\n // streamError was already surfaced as an error event — don't double-report.\n if (streamErrorYielded) return;\n\n const spawnError = exitError as Error | null;\n if (spawnError && !signal?.aborted && !gotDoneEvent) {\n const message = appendStderrTail(spawnError.message, stderrTail());\n const classified = classifyAdapterError(message, exitCode ?? undefined);\n throw Object.assign(new Error(message), { errorKind: classified });\n }\n if (exitCode !== 0 && exitCode !== null && !signal?.aborted && !gotDoneEvent) {\n const baseMsg = `Pi process exited with code ${exitCode}`;\n const message = appendStderrTail(baseMsg, stderrTail());\n const classified = classifyAdapterError(message, exitCode);\n throw Object.assign(new Error(message), { errorKind: classified });\n }\n }\n\n return generate();\n}\n\nfunction appendStderrTail(message: string, tail: string): string {\n return tail ? `${message}\\n--- pi stderr (tail) ---\\n${tail}` : message;\n}\n\ninterface ParseState {\n finalText: string;\n lastTokens?: TokenUsage;\n}\n\ninterface ParsedPiEvent {\n agentEvent?: AgentEvent;\n finalText?: string;\n tokens?: TokenUsage;\n}\n\nfunction parsePiRpcEvent(line: string, state: ParseState): ParsedPiEvent | null {\n if (!line.trim()) return null;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return { agentEvent: { type: 'output', timestamp: new Date().toISOString(), data: { text: line } } };\n }\n\n const timestamp = new Date().toISOString();\n const type = typeof parsed.type === 'string' ? parsed.type : '';\n\n switch (type) {\n case 'extension_ui_request':\n case 'agent_start':\n case 'turn_start':\n case 'message_start':\n case 'message_end':\n case 'turn_end':\n case 'queue_update':\n case 'compaction_start':\n case 'compaction_end':\n case 'auto_retry_start':\n case 'auto_retry_end':\n return extractPassiveUpdate(parsed);\n\n case 'response': {\n if (parsed.success === false) {\n const message = typeof parsed.error === 'string' ? parsed.error : JSON.stringify(parsed);\n return {\n agentEvent: { type: 'error', timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) },\n };\n }\n return null;\n }\n\n case 'message_update':\n return parseMessageUpdate(parsed, timestamp, state);\n\n case 'tool_execution_start':\n return {\n agentEvent: {\n type: 'tool_call',\n timestamp,\n data: { name: parsed.toolName, input: parsed.args, raw: parsed },\n },\n };\n\n case 'tool_execution_update':\n // Intermediate progress: pi emits one of these per chunk of tool output\n // (e.g. streaming bash stdout). Other adapters don't surface this in\n // their event streams — drop it so the canonical contract holds.\n return null;\n\n case 'tool_execution_end':\n return parseToolExecutionEnd(parsed, timestamp);\n\n case 'agent_end': {\n const final = extractFinalText(parsed) ?? state.finalText;\n const tokens = extractPiTokensFromAgentEnd(parsed) ?? state.lastTokens;\n return {\n finalText: final,\n tokens,\n agentEvent: {\n type: 'done',\n timestamp,\n data: { result: final, raw: parsed },\n tokens,\n },\n };\n }\n\n case 'extension_error': {\n const message = typeof parsed.message === 'string' ? parsed.message : JSON.stringify(parsed);\n return {\n agentEvent: { type: 'error', timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) },\n };\n }\n\n default:\n // Unknown pi event types are silently dropped: they would otherwise\n // pollute logs with raw RPC envelopes the renderer can't summarize.\n // Adding a known type above is the right way to surface a new event.\n return null;\n }\n}\n\nfunction parseMessageUpdate(parsed: Record<string, unknown>, timestamp: string, state: ParseState): ParsedPiEvent | null {\n const assistantMessageEvent = parsed.assistantMessageEvent as Record<string, unknown> | undefined;\n const updateType = typeof assistantMessageEvent?.type === 'string' ? assistantMessageEvent.type : '';\n\n if (updateType === 'text_delta') {\n // Aggregate deltas into state.finalText; emit nothing here. A long LLM\n // response is hundreds of deltas — flushing one event per delta floods\n // the activity feed with character-level fragments. text_end emits the\n // full message in one canonical `output` event below.\n const delta = typeof assistantMessageEvent?.delta === 'string' ? assistantMessageEvent.delta : '';\n return { finalText: state.finalText + delta };\n }\n\n if (updateType === 'text_end') {\n const content = typeof assistantMessageEvent?.content === 'string' ? assistantMessageEvent.content : state.finalText;\n // Reset the delta buffer so a follow-up assistant message in the same pi\n // session doesn't get concatenated onto this one (agent_end uses its own\n // messages[] extraction, not state.finalText, so this is safe to drop).\n if (!content) return { finalText: '' };\n return {\n finalText: '',\n agentEvent: { type: 'output', timestamp, data: { text: content } },\n };\n }\n\n if (updateType === 'error') {\n const reason = typeof assistantMessageEvent?.reason === 'string' ? assistantMessageEvent.reason : JSON.stringify(parsed);\n return {\n agentEvent: { type: 'error', timestamp, data: { message: reason, raw: parsed }, errorKind: classifyAdapterError(reason) },\n };\n }\n\n return null;\n}\n\nfunction parseToolExecutionEnd(parsed: Record<string, unknown>, timestamp: string): ParsedPiEvent {\n const toolName = typeof parsed.toolName === 'string' ? parsed.toolName : '';\n const args = parsed.args as Record<string, unknown> | undefined;\n const resultText = extractToolResultText(parsed.result);\n\n if (parsed.isError === true) {\n const message = resultText || JSON.stringify(parsed.result ?? parsed);\n return {\n agentEvent: { type: 'error', timestamp, data: { message, raw: parsed }, errorKind: classifyAdapterError(message) },\n };\n }\n\n if (toolName === 'bash') {\n const command = typeof args?.command === 'string' ? args.command : JSON.stringify(args ?? {});\n return {\n agentEvent: {\n type: 'command',\n timestamp,\n data: { command, result: resultText, raw: parsed },\n },\n };\n }\n\n if (/^(write|edit)$/i.test(toolName)) {\n const path = extractPath(args);\n if (path) {\n return {\n agentEvent: {\n type: 'file_change',\n timestamp,\n data: { paths: [path], raw: parsed },\n },\n };\n }\n }\n\n // Generic tool result (read, grep, ls, …) — surface the result text so logs\n // show what came back, not the raw RPC envelope.\n const summary = resultText || `${toolName || 'tool'} completed`;\n return { agentEvent: { type: 'output', timestamp, data: { text: summary, raw: parsed } } };\n}\n\n/** Pi tool results wrap content arrays in `{ content: [...] }`; messages don't. */\nfunction extractToolResultText(result: unknown): string {\n if (typeof result === 'string') return result;\n if (!result || typeof result !== 'object') return '';\n return extractTextFromContent((result as { content?: unknown }).content) ?? '';\n}\n\nfunction extractPassiveUpdate(parsed: Record<string, unknown>): ParsedPiEvent | null {\n const tokens = extractPiTokensFromMessage(parsed);\n return tokens ? { tokens } : null;\n}\n\nfunction extractFinalText(parsed: Record<string, unknown>): string | undefined {\n const messages = parsed.messages;\n if (!Array.isArray(messages)) return undefined;\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i] as Record<string, unknown>;\n if (message.role !== 'assistant') continue;\n const text = extractTextFromContent(message.content);\n if (text) return text;\n }\n return undefined;\n}\n\nfunction extractTextFromContent(content: unknown): string | undefined {\n if (typeof content === 'string') return content;\n if (!Array.isArray(content)) return undefined;\n const parts = content\n .map((part) => {\n const p = part as Record<string, unknown>;\n return typeof p.text === 'string' ? p.text : '';\n })\n .filter(Boolean);\n return parts.length ? parts.join('') : undefined;\n}\n\nfunction extractPath(args: Record<string, unknown> | undefined): string | undefined {\n if (!args) return undefined;\n if (typeof args.path === 'string') return args.path;\n if (typeof args.file_path === 'string') return args.file_path;\n return undefined;\n}\n\nfunction extractPiTokensFromAgentEnd(parsed: Record<string, unknown>): TokenUsage | undefined {\n const messages = parsed.messages;\n if (!Array.isArray(messages)) return undefined;\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i] as Record<string, unknown>;\n if (message.role !== 'assistant') continue;\n const tokens = extractPiTokensFromMessage(message);\n if (tokens) return tokens;\n }\n return undefined;\n}\n\n// Pi exposes usage under multiple key shapes across versions and across the\n// `message_*` vs `agent_end` paths — Pi-native names, snake_case shims, and\n// Anthropic-style names when Pi forwards Claude usage records unchanged.\n// First match per field wins, in this order.\nconst PI_TOKEN_ALIASES: Record<'input' | 'output' | 'reasoning' | 'cache_read' | 'cache_write', readonly string[]> = {\n input: ['input', 'input_tokens'],\n output: ['output', 'output_tokens'],\n reasoning: ['reasoning', 'reasoning_tokens'],\n cache_read: ['cacheRead', 'cache_read', 'cache_read_input_tokens'],\n cache_write: ['cacheWrite', 'cache_write', 'cache_creation_input_tokens'],\n};\n\nfunction extractPiTokensFromMessage(parsed: Record<string, unknown>): TokenUsage | undefined {\n const usage = parsed.usage as Record<string, unknown> | undefined;\n if (!usage) return undefined;\n\n const pick = (keys: readonly string[]): number => {\n for (const k of keys) {\n const v = usage[k];\n if (typeof v === 'number') return v;\n }\n return 0;\n };\n\n const input = pick(PI_TOKEN_ALIASES.input);\n const output = pick(PI_TOKEN_ALIASES.output);\n const reasoning = pick(PI_TOKEN_ALIASES.reasoning);\n const cache_read = pick(PI_TOKEN_ALIASES.cache_read);\n const cache_write = pick(PI_TOKEN_ALIASES.cache_write);\n\n if (input === 0 && output === 0 && reasoning === 0 && cache_read === 0 && cache_write === 0) return undefined;\n return createTokenUsage(input, output, { reasoning, cache_read, cache_write });\n}\n\n/**\n * Drain stderr while keeping the last STDERR_TAIL_BYTES bytes for diagnostics.\n * Returns a closure that yields the captured tail as a UTF-8 string.\n *\n * Single backing Buffer with subarray-based truncation — no array shifts, no\n * repeated concats on overflow. Without draining a chatty stderr can fill the\n * pipe buffer and stall Pi; without the tail, auth or extension-load failures\n * vanish on non-zero exit.\n */\nconst STDERR_TAIL_BYTES = 4096;\nfunction createStderrTailCapture(stderr: Readable | null | undefined): () => string {\n if (!stderr) return () => '';\n let buf: Buffer = Buffer.alloc(0);\n stderr.on('data', (chunk: Buffer | string) => {\n const next = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, 'utf-8');\n buf = buf.length === 0 ? next : Buffer.concat([buf, next], buf.length + next.length);\n if (buf.length > STDERR_TAIL_BYTES) {\n // Buffer.from materializes a fresh, exactly-sized copy. Plain subarray\n // would keep a view into the larger backing ArrayBuffer (sized to the\n // last chunk), wasting memory on every oversized burst until GC.\n buf = Buffer.from(buf.subarray(buf.length - STDERR_TAIL_BYTES));\n }\n });\n stderr.on('error', () => {});\n return () => buf.toString('utf-8').trimEnd();\n}\n\n/**\n * Pi RPC can emit very large JSONL records (notably agent_end with the full\n * message transcript). Do not use the generic process `readLines` helper: it\n * caps lines at 16 KB, which corrupts large JSON records before the adapter\n * can parse the terminal event. Same algorithm otherwise — see readLines() in\n * src/infrastructure/process/process-manager.ts for the cap-applied variant.\n *\n * Concats once per chunk arrival and scans with an offset to avoid the\n * O(n²) \"concat([pending, buf]) per chunk\" anti-pattern.\n */\nasync function* readPiRpcLines(stream: Readable): AsyncGenerator<string> {\n const chunks: Buffer[] = [];\n let totalLen = 0;\n\n for await (const chunk of stream) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as string, 'utf-8');\n if (buf.length === 0) continue;\n chunks.push(buf);\n totalLen += buf.length;\n\n const buffer = chunks.length === 1 ? chunks[0]! : Buffer.concat(chunks, totalLen);\n chunks.length = 0;\n totalLen = 0;\n\n let offset = 0;\n let newlineIdx: number;\n while ((newlineIdx = buffer.indexOf(0x0a, offset)) !== -1) {\n if (newlineIdx > offset) {\n const line = buffer.toString('utf-8', offset, newlineIdx);\n yield line.endsWith('\\r') ? line.slice(0, -1) : line;\n }\n offset = newlineIdx + 1;\n }\n\n if (offset < buffer.length) {\n const remainder = buffer.subarray(offset);\n chunks.push(remainder);\n totalLen = remainder.length;\n }\n }\n\n if (totalLen > 0) {\n const final = chunks.length === 1 ? chunks[0]! : Buffer.concat(chunks, totalLen);\n const line = final.toString('utf-8');\n if (line) yield line.endsWith('\\r') ? line.slice(0, -1) : line;\n }\n}\n"]}
|
|
@@ -17,4 +17,4 @@ import {j,q,g,d,e,o,l,n,m}from'./chunk-64WUDYEM.js';function x(_,a){let c=_.comm
|
|
|
17
17
|
Review Results
|
|
18
18
|
${"\u2500".repeat(42)}`);for(let o of t.review_results){let n=o.passed?"\u2713":"\u2717";if(console.log(` ${n} ${o.criterion}: ${o.passed?"passed":"failed"}`),o.output)for(let l of o.output.split(`
|
|
19
19
|
`))console.log(` ${l}`);}}console.log();}),c.command("edit <id>").description("Open task in $EDITOR to modify title, priority and description").action(async e=>{let t=await a.taskService.get(e),{openInEditor:s,toEditorContent:o,fromEditorContent:n}=await import('./editor-7IFRWVTL.js'),l=t.attachments?.length?`
|
|
20
|
-
# Attachments: ${t.attachments.join(", ")}`:"",d=o({title:t.title,priority:t.priority,description:t.description})+l,i=await s(d),r=n(i),g={};if(r.title&&r.title!==t.title&&(g.title=r.title),r.priority&&r.priority!==t.priority&&(g.priority=r.priority),r.description!==void 0&&r.description!==t.description&&(g.description=r.description??""),Object.keys(g).length===0){console.log(" No changes.");return}let w=await a.taskService.update(e,g);j(`Updated ${w.id} "${w.title}"`);}),c.command("assign <task-id> <agent-id>").description("Assign task to agent").action(async(e,t)=>{let s=await a.taskService.assign(e,t);j(`Assigned ${s.id} \u2192 ${s.assignee??t}`);}),c.command("cancel <id>").description("Cancel a task").action(async e=>{if((await a.taskService.get(e)).status==="in_progress"){let{buildFullContainer:s}=await import('./container-
|
|
20
|
+
# Attachments: ${t.attachments.join(", ")}`:"",d=o({title:t.title,priority:t.priority,description:t.description})+l,i=await s(d),r=n(i),g={};if(r.title&&r.title!==t.title&&(g.title=r.title),r.priority&&r.priority!==t.priority&&(g.priority=r.priority),r.description!==void 0&&r.description!==t.description&&(g.description=r.description??""),Object.keys(g).length===0){console.log(" No changes.");return}let w=await a.taskService.update(e,g);j(`Updated ${w.id} "${w.title}"`);}),c.command("assign <task-id> <agent-id>").description("Assign task to agent").action(async(e,t)=>{let s=await a.taskService.assign(e,t);j(`Assigned ${s.id} \u2192 ${s.assignee??t}`);}),c.command("cancel <id>").description("Cancel a task").action(async e=>{if((await a.taskService.get(e)).status==="in_progress"){let{buildFullContainer:s}=await import('./container-KJNQCG2C.js');await(await s(a.context)).orchestrator.cancelTask(e);}else await a.taskService.cancel(e);j(`Cancelled ${e}`);}),c.command("approve <id>").description("Approve a task in review").action(async e=>{await a.taskService.updateStatus(e,"done"),j(`Approved ${e}`);}),c.command("reject <id>").description("Reject a task and send it back for rework").option("-r, --reason <reason>","Feedback for the agent explaining what to fix").action(async(e,t)=>{await a.taskService.reject(e,t.reason),j(`Rejected ${e} \u2192 todo${t.reason?` (reason: ${t.reason})`:""}`);}),c.command("retry <id>").description("Retry a failed task").action(async e=>{await a.taskService.retry(e),j(`Reset ${e} to todo`);});}export{x as registerTaskCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function ct(d,e){d.command("tui").description("Launch interactive TUI dashboard").action(async()=>{let S=await e.taskService.list(),w=await e.agentService.list(),h=await e.stateStore.read(),{render:k}=await import('ink'),{createElement:T}=await import('react'),{App:b}=await import('./App-
|
|
2
|
+
function ct(d,e){d.command("tui").description("Launch interactive TUI dashboard").action(async()=>{let S=await e.taskService.list(),w=await e.agentService.list(),h=await e.stateStore.read(),{render:k}=await import('ink'),{createElement:T}=await import('react'),{App:b}=await import('./App-QHBW3KHL.js'),A=async t=>{await e.orchestrator.runTask(t);},R=async(t,s)=>e.taskService.create({title:t,priority:s?.priority,description:s?.description,attachments:s?.attachments}),C=async t=>{await e.orchestrator.cancelTask(t);},_=async t=>{await e.taskService.retry(t);},E=async(t,s)=>{await e.taskService.assign(t,s);},j=async()=>{await e.orchestrator.runAll();},D=async t=>{await e.agentService.disable(t);},U=async t=>{await e.agentService.enable(t);},m=t=>e.eventBus.onAny(t),P=async()=>e.taskService.list(),G=async()=>e.agentService.list(),x=async()=>e.stateStore.read(),I=async(t,s,a)=>e.agentService.create({name:t,adapter:s??e.config.defaults.agent.adapter,model:a?.model||void 0,effort:a?.effort||void 0,role:a?.role||void 0,approval_policy:a?.approval_policy||void 0,skills:a?.skills||void 0}),L=async t=>{await e.agentService.remove(t);},F=async t=>{await e.taskService.delete(t);},H=async t=>{await e.taskService.updateStatus(t,"done");},O=async(t,s)=>{await e.taskService.reject(t,s);},W=async(t,s)=>e.taskService.update(t,s),N=async(t,s)=>e.agentService.update(t,{...s,effort:s.effort,approval_policy:s.approval_policy}),B=async t=>{await e.orchestrator.forceStopAgent(t);},M=async(t,s)=>e.agentService.setAutonomous(t,s),V=async t=>{let s=await e.runService.listAll();s.sort((n,i)=>new Date(i.started_at).getTime()-new Date(n.started_at).getTime());let a=s.filter(n=>n.status==="succeeded"||n.status==="failed"),u=3,ot=10,y=a.slice(0,u),v=a.slice(u,ot),f=async n=>(await e.runService.readEventsTail(n.id,30)).map(r=>({timestamp:r.timestamp,agentId:n.agent_id,taskId:n.task_id,type:r.type,data:r.data}));if(y.length>0){let n=(await Promise.all(y.map(f))).flat();n.sort((i,r)=>new Date(i.timestamp).getTime()-new Date(r.timestamp).getTime()),t(n.slice(-200));}if(v.length>0){let n=(await Promise.all(v.map(f))).flat();n.sort((i,r)=>new Date(i.timestamp).getTime()-new Date(r.timestamp).getTime()),t(n.slice(-200));}},J=async t=>e.teamService.create(t),K=async()=>e.teamService.list(),q=async(t,s)=>e.teamService.join(t,s),z=async(t,s)=>e.teamService.leave(t,s),Q=async t=>{await e.teamService.disband(t);},X=async(t,s)=>e.teamService.setLead(t,s),Y=async()=>e.goalService.list(),Z=async t=>e.goalService.create(t),$=async(t,s)=>e.goalService.update(t,s),tt=async(t,s,a)=>e.goalService.updateStatus(t,s,a),et=async t=>{await e.goalService.delete(t);},st=async t=>e.goalService.getProgressReport(t),at=async()=>{await e.orchestrator.startWatch();},nt=async()=>{await e.orchestrator.stop();},c=d.version()??"0.0.0",rt=import('./update-check-R5ABF6HE.js').then(t=>t.checkForUpdateSWR(c)).catch(()=>null),l=false,p,g=false,o;try{await e.orchestrator.startWatch(),l=!0;}catch(t){p=t instanceof Error?t.message:String(t);let{DiskObserver:s}=await import('./disk-observer-B3NOZ2QA.js');o=new s({paths:e.paths,stateStore:e.stateStore}),g=true,m=a=>o.subscribe(a);}let{waitUntilExit:it}=k(T(b,{projectName:e.config.project.name,tasks:S,agents:w,state:h,onRunTask:A,onCreateTask:R,onCancelTask:C,onRetryTask:_,onAssignTask:E,onRunAll:j,onDisableAgent:D,onEnableAgent:U,onSubscribeEvents:m,onRefreshTasks:P,onRefreshAgents:G,onRefreshState:x,onLoadHistory:V,onAddAgent:I,onDeleteAgent:L,onApproveTask:H,onRejectTask:O,onDeleteTask:F,onUpdateTask:W,onUpdateAgent:N,onForceStopAgent:B,onToggleAutonomous:M,onRefreshGoals:Y,onCreateGoal:Z,onUpdateGoal:$,onUpdateGoalStatus:tt,onDeleteGoal:et,onGetGoalProgress:st,onCreateTeam:J,onListTeams:K,onJoinTeam:q,onLeaveTeam:z,onDisbandTeam:Q,onSetTeamLead:X,onStartWatch:at,onStopWatch:nt,initialWatchActive:l,observerMode:g,watchError:g?void 0:p,version:c,latestVersion:void 0,onCheckUpdate:async()=>{let t=await rt;if(t?.updateAvailable)return t.latest;let a=await(await import('./update-check-R5ABF6HE.js')).checkForUpdateNow(c);return a?.updateAvailable?a.latest:void 0},onBackgroundInstall:async t=>(await import('./update-check-R5ABF6HE.js')).backgroundInstall(t),initialActivityFilter:e.globalConfig.tui.activity_filter,onSaveActivityFilter:async t=>{await e.globalConfigStore.set("activity_filter",t);},initialNotifications:e.globalConfig.tui.notifications,onSaveNotifications:async t=>{await e.globalConfigStore.set("notifications",t);},initialMaxConcurrent:e.config.scheduling.max_concurrent_agents,onSaveMaxConcurrent:async t=>{await e.configStore.set("scheduling.max_concurrent_agents",t),e.config.scheduling.max_concurrent_agents=t;},onCompleteOnboarding:async()=>{let t=await e.stateStore.read();t.onboardingCompleted=true,await e.stateStore.write(t);},defaultAdapter:e.config.defaults.agent.adapter}),{incrementalRendering:true,kittyKeyboard:{mode:"auto",flags:["disambiguateEscapeCodes"]}});await it(),l&&await e.orchestrator.stop().catch(()=>{}),o&&o.stop(),e.eventBus.clear();});}export{ct as registerTuiCommand};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxgeneral/orch",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"description": "AI agent runtime — orchestrate Claude, Cursor, Codex & OpenCode as one team. Multi-agent task automation with state machine, auto-retry, inter-agent messaging, goals and teams. Zero-config CLI + programmatic API.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|