@tea-agent/loop-agent 0.40.0-next.14 → 0.40.0-next.15
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/AGENTS.md +1 -1
- package/CHANGELOG.md +4 -0
- package/dist/build-stamp.json +3 -3
- package/dist/worker/console/pi-plugins.js +88 -9
- package/dist/worker/console/routes.js +27 -2
- package/dist/worker/console/server.js +2 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-B0gRLXJs.js → abnfDiagram-N423BO3Z-ZRowCaoB.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DldY0Hsk.js → arc-Bj6ZtQJ7.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-4xHhMRM9.js → architectureDiagram-T3A2C74G-n4cTQxyl.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-DPym7n0M.js → blockDiagram-VBNYF7ZC-CrqqRR1r.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-cSFzY5yS.js → c4Diagram-5PPSVZJV-CUMa3_oJ.js} +1 -1
- package/dist/worker/console/static/assets/channel-CzEKG-cL.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-w-64RMuc.js → chunk-2GRJ4B5K-DTvksUI8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-Bvue--jh.js → chunk-2Q5K7J3B-uLaMhsnm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DxqkQnCh.js → chunk-5RXB4S5H-TNZa_h2Z.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-C83gOKLK.js → chunk-5VM5RSS4-DeT4DTvU.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-C_V6tKAV.js → chunk-6Q2QTUOP-DpDwrgBX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CPvZQuL9.js → chunk-GF5L2VYU-7m3mc3kT.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-w31Z_ATM.js → chunk-JWPE2WC7-qD6tz6st.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DermQC9f.js → chunk-KBJHAD2P-DmxuvfwY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CmwaYcnB.js → chunk-RYQCIY6F-CtloYW08.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DLwZqUBf.js → chunk-XXDRQBXY-Mt0SdMYe.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BjVCAg3v.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BjVCAg3v.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-Dzh7bT73.js → cose-bilkent-JH36ORCC-CypzApsM.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CfOcBHtp.js → cynefin-VYW2F7L2-CdtlN9h7.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D0EbCVDZ.js → cynefinDiagram-MW4NZA55-B5mmrWYJ.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-MfOFA6PZ.js → dagre-VZM6K2ZE-CuGLsIWX.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BOa5-9PN.js → diagram-7IWD3JNH-7K_sTV8C.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B6zvJ-aL.js → diagram-B4RE2ZJO-C6uYQF8O.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-BKwr5bRF.js → diagram-LBJQPF4R-iQEMjbjB.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-PLI5QLpX.js → diagram-Q27KOJAE-Da_RHa6E.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BgYYME3o.js → diagram-UB23O5K3-DxSC07de.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-D-SpjXk2.js → ebnfDiagram-BXEA7PRR-DrcKS2O2.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK--JHpEOka.js → erDiagram-JOGREHBK-DwtF5lPU.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CbkQgWUz.js → flowDiagram-UKHOOZJN-DvaYG3Dj.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CTZMAMVE.js → ganttDiagram-PKOTCBZU-CdvS2BFz.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-BaUGSDig.js → gitGraphDiagram-DS77QQ5N-C90crnKQ.js} +1 -1
- package/dist/worker/console/static/assets/index-CffSxmqh.css +1 -0
- package/dist/worker/console/static/assets/index-OwqawHso.js +437 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DA3WbWjf.js → infoDiagram-6WML65LV-RFJJaIj1.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DbhI82U4.js → ishikawaDiagram-WSZJBQD7-Ptyp28qF.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CJKA3OBG.js → journeyDiagram-NVQOT4AX-BOLs4CJr.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CF6dIVRa.js → kanban-definition-27J2QSJJ-DmAd2lo5.js} +1 -1
- package/dist/worker/console/static/assets/{linear-D4dEtOUL.js → linear-gYqIaDdo.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-ClhMic6O.js → mermaid.core-D7l0d1KR.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-NfRin7S2.js → mindmap-definition-FAOFIHXS-CfEUCuOg.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DlBtBwW-.js → pegDiagram-VL7TDLO6-DrsrmQAq.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DdIkNHZO.js → pieDiagram-7S7Q4E2Y-B_BtPjTs.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-YD8T98WX.js → quadrantDiagram-CIZ2JOQS-DHdtYoZ0.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CS4e5zGK.js → railroadDiagram-AXF67PYL-C3ZRzhji.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BpbWoL9r.js → requirementDiagram-LRYGKXZP-C02rlD1p.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DvWy-Mc9.js → sankeyDiagram-W5VNT64P-uKJwyQoD.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DmoXH5pJ.js → sequenceDiagram-SI44F4Z6-Dy9LwdvZ.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BY89V1SW.js → sizeCapture-X5ZJPWSS-BZv-lCxE.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-DaK2Iuqr.js → stateDiagram-OKZ733FA-BoBhkFkN.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-SrHPpkR3.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-VVcozat-.js → swimlanes-SLNWSIFB-MQ6V_d3o.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-vkKJWZ7P.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-D4l1E4Mu.js → timeline-definition-Z64GVDOM-1ewj4q0J.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-CJmewqcq.js → vennDiagram-T6HMQDX7-C7tpjTmO.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CsCCYorj.js → wardleyDiagram-T6FBY63Y-9hGeqY7M.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CwjILi0N.js → xychartDiagram-ELKLHX3M-DgW7AyLR.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/shell/workspace-route.js +3 -1
- package/dist/worker/observe/static/operator-chrome.js +1 -0
- package/package.json +1 -1
- package/dist/worker/console/static/assets/channel-4xBA5kwn.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CkefOueI.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CkefOueI.js +0 -1
- package/dist/worker/console/static/assets/index-C4mO0i6P.js +0 -437
- package/dist/worker/console/static/assets/index-C86Y55Or.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DLc5WD-z.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DhjxpI7d.js +0 -8
package/AGENTS.md
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
- 机器校验契约真源:`docs/init-surface.manifest.json`、`docs/architecture/runtime-boundaries.md`、`src/cli/command-definitions.ts`、`skills/loop-agent/`、`scripts/check-*.sh`;本文件只指路。
|
|
25
25
|
- 本仓库既是源项目也是 init 默认模板;新增能力必须判断 npm 内置 vs `loop-agent init` 投影。
|
|
26
26
|
- 委托写入前必须结构化 `task.json.allowedPaths` / `forbiddenPaths`,并审查 DAG writer `writeSet`。
|
|
27
|
-
- Shell 搜索优先 `rg`,按名找文件优先 `fd`;脚本用 Git Bash / 兼容 Bash。
|
|
27
|
+
- Shell 搜索优先 `rg`,按名找文件优先 `fd`;脚本用 Git Bash / 兼容 Bash。rg 短标志禁止粘写:rg 的 `-r` 是 `--replace`(grep 里才是递归,rg 递归默认开启),`rg -rln pat` 会把匹配文本静默替换成 `ln` 且无报错;行号搜索用 `rg -n pat`,仅列文件用 `rg -l pat`,输出呈 `文件名:内容`(单冒号无行号)即为替换污染,须重跑。
|
|
28
28
|
- 用 loop-agent 迭代本仓库时,控制器必须来自已发布 npm 包(记录实际版本);启动后不要中途升级;不要用工作区 `npm link` / `npm run dev` 控制可能改 CLI/runtime/package 的任务。
|
|
29
29
|
- 反复出现的约束固化为文档、脚本、检查、测试或模板;禁止占位实现(除非 contract 标明脚手架)。
|
|
30
30
|
- 非微小实现:`exec-plan` 不能替代 Agent DAG;除非用户要求 one-shot 或计划记录 escape hatch,否则改实现前完成 `task advance`(PRD + 结构化路径边界)与 writeSet gate 审查。长跑 DAG 启动一律走 `prepareDagExecution → runDag → operationId` 由 Console operation 后台持有;**禁止**在前台 Bash 直接执行 `task advance --approve-gate`(会阻塞会话且超时杀 runner)、禁止把长跑命令管道到 `tail`/`head`、禁止自行拼接 `nohup`/`Start-Process`/`start`。
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
- 修复 Console 对话页「轨迹」视图工具行(如 bash)展开后参数与结果仍被截断在 420 字符的问题:展开现在显示完整内容(块内滚动收纳长输出),并复用聊天工具卡同款的结果解包与参数格式化,HTML 导出同步生效。
|
|
5
6
|
- Operator Chat 输入框下方的「调用记录」入口现在会常驻显示;没有记录时显示为 0,发送消息或刷新运行状态时不再突然消失。
|
|
6
7
|
- 初始化选择模型时现在能识别公司内部 `wizard-local` 的 AICoder 型号梯度:`aicoder-default`、`aicoder-plus`、`aicoder-pro`、`aicoder-max` 从左到右能力逐级增强;它会作为选择 LOW/MED/HIGH 的参考,但不会忽略成本和项目需求机械分档。
|
|
7
8
|
- 修复 Operator Chat 左侧栏工作区名称过长时遮挡悬浮「更多」「新建对话」按钮的问题:工作区行改为 flex 行布局,名称过长时单行省略,操作按钮改为行尾占位显示,悬浮背景整行连续无断层。
|
|
@@ -9,6 +10,9 @@
|
|
|
9
10
|
|
|
10
11
|
### 重点更新
|
|
11
12
|
|
|
13
|
+
- Console「Pi 插件」增强:已安装插件显示实际安装版本;安装时提供版本下拉(从 npm 配置的仓库拉取该包全部已发布版本,默认装最新);版本号带 `@version` 的已装包(如 `npm:pi-lens@3.8.72`)也能被正确识别为已安装。
|
|
14
|
+
- Console「Pi 插件」的版本号改为从 **npm 配置的仓库地址**(`npm config get registry`)拉取,不再硬编码官方源,内网镜像可用;安装/卸载进度条改用 JS(requestAnimationFrame)驱动,不受系统「减少动态效果」影响,任何环境都显示滑动动画。
|
|
15
|
+
- Console「操作」页的「Pi 插件」从「设置」页提升为与「设置」同级的独立 tab(`/#/operate/pi-plugins`):共享壳操作导航新增入口,独立子面板承载插件目录/搜索/分页/一键安装卸载。
|
|
12
16
|
- Console 设置页新增「Pi 插件」区块:内置一份经 npm 校验的插件目录(6303 个,仅展示 5562 个可安装、含中文说明),支持搜索、每页条数(10/20/50/100)、分页、一键安装/卸载(调用 `pi install/remove`,全局 `~/.pi/agent`),安装/卸载带进度过渡与结果提示。
|
|
13
17
|
- CLI 命令 `--help` 现在直接显示真实 usage(此前 raw-args 命令只在解析出错时才抛 usage):`task advance` / `task status` / `task source prepare` 与 `dag resume|doctor|report|reconcile-run|rerun|rerun-task|reject|approve|status` 的 `--help` 顶部即列出完整参数契约,`task advance` 并附 `--verify "label:command"` 示例;`init` 提示补全局 `--repo-root <path>`(置于子命令前)约定。
|
|
14
18
|
- `task source prepare`(确定性任务源投影,managed 需求.md/执行约束.md)从死代码转正:此前 `TASK_SUBCOMMANDS` 缺少 `source` 导致命令不可达,现 `task source prepare <task-id> --from-text/--from-file/--from-stdin/--from-draft --dry-run|--apply` 可直接调用。
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.40.0-next.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-08-
|
|
3
|
+
"version": "0.40.0-next.15",
|
|
4
|
+
"gitSha": "17468c22b184e41c1364620d68ad016c9d2e0c42",
|
|
5
|
+
"builtAt": "2026-08-30T12:56:34.875Z"
|
|
6
6
|
}
|
|
@@ -27,7 +27,13 @@ function readSettings() {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
function packageNameFromSpec(spec) {
|
|
30
|
-
|
|
30
|
+
const base = spec.startsWith("npm:") ? spec.slice(4) : spec;
|
|
31
|
+
// 剥掉尾部 @<version>(如 pi-lens@3.8.72 → pi-lens),但保留 scoped 包名开头的 @
|
|
32
|
+
// (如 @scope/pkg → @scope/pkg,@scope/pkg@1.0.0 → @scope/pkg)。
|
|
33
|
+
const at = base.lastIndexOf("@");
|
|
34
|
+
if (at > 0)
|
|
35
|
+
return base.slice(0, at);
|
|
36
|
+
return base;
|
|
31
37
|
}
|
|
32
38
|
function listInstalledPackageNames() {
|
|
33
39
|
const settings = readSettings();
|
|
@@ -36,15 +42,87 @@ function listInstalledPackageNames() {
|
|
|
36
42
|
function isPackageInstalledOnDisk(pkg) {
|
|
37
43
|
return existsSync(path.join(nodeModulesRoot(), ...pkg.split("/")));
|
|
38
44
|
}
|
|
39
|
-
/**
|
|
45
|
+
/** 读取已安装包的实际版本(node_modules 里 package.json 的 version)。 */
|
|
46
|
+
function readInstalledVersion(pkg) {
|
|
47
|
+
try {
|
|
48
|
+
const manifest = JSON.parse(readFileSync(path.join(nodeModulesRoot(), ...pkg.split("/"), "package.json"), "utf8"));
|
|
49
|
+
return typeof manifest.version === "string" ? manifest.version : undefined;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** 目录 + 每个插件的已装状态(settings.packages 声明 + node_modules 存在)+ 已装版本。 */
|
|
40
56
|
export function listPiPlugins() {
|
|
41
57
|
const installed = new Set(listInstalledPackageNames());
|
|
42
|
-
const plugins = catalogData.plugins.map((p) =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
const plugins = catalogData.plugins.map((p) => {
|
|
59
|
+
const isInstalled = installed.has(p.name) && isPackageInstalledOnDisk(p.name);
|
|
60
|
+
return {
|
|
61
|
+
...p,
|
|
62
|
+
installed: isInstalled,
|
|
63
|
+
installedVersion: isInstalled ? readInstalledVersion(p.name) : undefined,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
46
66
|
return { summary: catalogData.summary, plugins };
|
|
47
67
|
}
|
|
68
|
+
let cachedRegistry;
|
|
69
|
+
/** 读取 npm 配置的 registry(`npm config get registry`),失败回退官方源。 */
|
|
70
|
+
function getNpmRegistry() {
|
|
71
|
+
if (cachedRegistry)
|
|
72
|
+
return Promise.resolve(cachedRegistry);
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
const fallback = () => {
|
|
75
|
+
cachedRegistry = "https://registry.npmjs.org/";
|
|
76
|
+
resolve(cachedRegistry);
|
|
77
|
+
};
|
|
78
|
+
try {
|
|
79
|
+
const child = spawn("npm", ["config", "get", "registry"], {
|
|
80
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
81
|
+
cwd: getPiAgentDir(),
|
|
82
|
+
shell: process.platform === "win32",
|
|
83
|
+
});
|
|
84
|
+
let out = "";
|
|
85
|
+
child.stdout.on("data", (d) => (out += d.toString("utf8")));
|
|
86
|
+
child.on("close", () => {
|
|
87
|
+
const reg = out.trim();
|
|
88
|
+
cachedRegistry = reg || "https://registry.npmjs.org/";
|
|
89
|
+
resolve(cachedRegistry);
|
|
90
|
+
});
|
|
91
|
+
child.on("error", fallback);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
fallback();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** 从 npm 配置的仓库拉取某包的全部已发布版本 + latest。 */
|
|
99
|
+
export async function listPiPluginVersions(name) {
|
|
100
|
+
const registry = (await getNpmRegistry()).replace(/\/+$/, "");
|
|
101
|
+
const url = `${registry}/${encodeURIComponent(name).replace(/%2F/g, "/")}`;
|
|
102
|
+
try {
|
|
103
|
+
const res = await fetch(url, {
|
|
104
|
+
headers: { accept: "application/json", "user-agent": "loop-agent/1.0" },
|
|
105
|
+
});
|
|
106
|
+
if (!res.ok)
|
|
107
|
+
return { ok: false, error: `npm registry HTTP ${res.status}` };
|
|
108
|
+
const body = (await res.json());
|
|
109
|
+
const versions = body.versions && typeof body.versions === "object"
|
|
110
|
+
? Object.keys(body.versions).sort((a, b) => b.localeCompare(a, undefined, { numeric: true }))
|
|
111
|
+
: [];
|
|
112
|
+
const latest = body["dist-tags"]?.latest;
|
|
113
|
+
return {
|
|
114
|
+
ok: true,
|
|
115
|
+
versions,
|
|
116
|
+
latest: typeof latest === "string" ? latest : undefined,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: error instanceof Error ? error.message : String(error),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
48
126
|
function runPi(args) {
|
|
49
127
|
return new Promise((resolve) => {
|
|
50
128
|
mkdirSync(getPiAgentDir(), { recursive: true });
|
|
@@ -66,8 +144,8 @@ function runPi(args) {
|
|
|
66
144
|
export function findCatalogPlugin(name) {
|
|
67
145
|
return catalogData.plugins.find((p) => p.name === name);
|
|
68
146
|
}
|
|
69
|
-
/** 全局(用户级 ~/.pi/agent)安装:调用 `pi install npm:<name
|
|
70
|
-
export async function installPiPlugin(name) {
|
|
147
|
+
/** 全局(用户级 ~/.pi/agent)安装:调用 `pi install npm:<name>`(可带版本,缺省为最新)。 */
|
|
148
|
+
export async function installPiPlugin(name, version) {
|
|
71
149
|
const entry = findCatalogPlugin(name);
|
|
72
150
|
if (!entry) {
|
|
73
151
|
return { ok: false, error: `包 ${name} 不在插件目录中` };
|
|
@@ -78,7 +156,8 @@ export async function installPiPlugin(name) {
|
|
|
78
156
|
error: `包 ${name} 未声明 pi.extensions,无法作为 Pi 扩展使用`,
|
|
79
157
|
};
|
|
80
158
|
}
|
|
81
|
-
const
|
|
159
|
+
const spec = version && version.trim() ? `npm:${name}@${version.trim()}` : `npm:${name}`;
|
|
160
|
+
const result = await runPi(["install", spec]);
|
|
82
161
|
if (result.code !== 0) {
|
|
83
162
|
return {
|
|
84
163
|
ok: false,
|
|
@@ -8,7 +8,7 @@ import { buildOperatorSurfaceHealthV1 } from "./operator-surface-health.js";
|
|
|
8
8
|
import { ROUTES } from "../observe/routes.js";
|
|
9
9
|
import { evaluateMutationGate, injectConfirmationTokenScript, isMutationMethod, } from "./security.js";
|
|
10
10
|
import { listDagRunsForRecovery } from "./resolve-dag-run-for-task.js";
|
|
11
|
-
import { installPiPlugin, listPiPlugins, uninstallPiPlugin, } from "./pi-plugins.js";
|
|
11
|
+
import { installPiPlugin, listPiPluginVersions, listPiPlugins, uninstallPiPlugin, } from "./pi-plugins.js";
|
|
12
12
|
import { pickNativeWorkspaceDirectory } from "./native-directory-picker.js";
|
|
13
13
|
export function sendJson(res, status, body, extraHeaders) {
|
|
14
14
|
const payload = JSON.stringify(body);
|
|
@@ -486,8 +486,9 @@ async function handlePiPluginInstall(req, res) {
|
|
|
486
486
|
});
|
|
487
487
|
return;
|
|
488
488
|
}
|
|
489
|
+
const version = typeof body.version === "string" ? body.version.trim() : undefined;
|
|
489
490
|
try {
|
|
490
|
-
const result = await installPiPlugin(name);
|
|
491
|
+
const result = await installPiPlugin(name, version);
|
|
491
492
|
if (!result.ok) {
|
|
492
493
|
sendJson(res, 400, {
|
|
493
494
|
ok: false,
|
|
@@ -588,6 +589,30 @@ export async function handleConsoleOperatorRequest(req, res, ctx) {
|
|
|
588
589
|
sendJson(res, 200, { ok: true, data: listPiPlugins() });
|
|
589
590
|
return true;
|
|
590
591
|
}
|
|
592
|
+
if (method === "GET" &&
|
|
593
|
+
pathname === "/api/operator/v1/pi-plugins/versions") {
|
|
594
|
+
const name = url.searchParams.get("name")?.trim() ?? "";
|
|
595
|
+
if (!name) {
|
|
596
|
+
sendJson(res, 400, {
|
|
597
|
+
ok: false,
|
|
598
|
+
error: { code: "INVALID_INPUT", message: "missing name" },
|
|
599
|
+
});
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
const result = await listPiPluginVersions(name);
|
|
603
|
+
if (!result.ok) {
|
|
604
|
+
sendJson(res, 400, {
|
|
605
|
+
ok: false,
|
|
606
|
+
error: { code: "FETCH_FAILED", message: result.error },
|
|
607
|
+
});
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
sendJson(res, 200, {
|
|
611
|
+
ok: true,
|
|
612
|
+
data: { versions: result.versions, latest: result.latest },
|
|
613
|
+
});
|
|
614
|
+
return true;
|
|
615
|
+
}
|
|
591
616
|
const opMatch = pathname.match(/^\/api\/operator\/v1\/operations\/([^/]+)(?:\/(events))?$/);
|
|
592
617
|
if (opMatch) {
|
|
593
618
|
const operationId = decodeURIComponent(opMatch[1]);
|
|
@@ -714,8 +714,9 @@ export async function createConsoleServer(options) {
|
|
|
714
714
|
await handleConsoleOperatorRequest(req, res, operatorRouteContext(startup));
|
|
715
715
|
return;
|
|
716
716
|
}
|
|
717
|
-
// Pi 插件目录 / 安装 / 卸载:全局用户级(~/.pi/agent),非工作区作用域,用 startup context。
|
|
717
|
+
// Pi 插件目录 / 版本 / 安装 / 卸载:全局用户级(~/.pi/agent),非工作区作用域,用 startup context。
|
|
718
718
|
if (pathname === "/api/operator/v1/pi-plugins" ||
|
|
719
|
+
pathname === "/api/operator/v1/pi-plugins/versions" ||
|
|
719
720
|
pathname === "/api/operator/v1/pi-plugins/install" ||
|
|
720
721
|
pathname === "/api/operator/v1/pi-plugins/uninstall") {
|
|
721
722
|
await handleConsoleOperatorRequest(req, res, operatorRouteContext(startup));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-DpDwrgBX.js";import{p as f}from"./chunk-JWPE2WC7-qD6tz6st.js";import{_ as n,l as o}from"./mermaid.core-D7l0d1KR.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CdtlN9h7.js";import"./index-OwqawHso.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-D7l0d1KR.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|