docs: 为 CLI、网页编排器和插件协议补充学习向注释
在核心类型、图执行器、stdio 插件和前端入口写清职责与对照路径,不改运行行为。
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* 编排器布局:顶栏、三栏(节点 / 画布 / 检查器)、底部日志、确认弹层。 */
|
||||
:root {
|
||||
--bg: #0f1419;
|
||||
--panel: #171e26;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- 单页编排器:左节点列表、中画布、右检查器、下日志。逻辑全在 /js/app.js。 -->
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
@@ -37,6 +38,7 @@
|
||||
<h2>运行结果</h2>
|
||||
<pre id="log">尚未运行。</pre>
|
||||
</section>
|
||||
<!-- 缺城市时的确认层,对应后端 status=needsDecision -->
|
||||
<div id="decisionModal" class="modal hidden" aria-hidden="true">
|
||||
<div class="dialog">
|
||||
<h2>需要你确认</h2>
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/**
|
||||
* 可视化编排器前端(无框架)。
|
||||
*
|
||||
* 学习路径:
|
||||
* 1. init → loadCatalog:拉系统节点和插件节点
|
||||
* 2. 示例图 / 拖节点、点端口连线;图数据在 state.nodes / state.edges
|
||||
* 3. runGraph POST /api/run;若 status=needsDecision 弹出确认框
|
||||
* 4. 确认走 /api/run/{id}/decide;超时则 pollRun 等服务端自动采用默认方案
|
||||
*
|
||||
* selected / pending 只用于点击交互。发给后端的 JSON 不含 API Key,只有 credentialId。
|
||||
*/
|
||||
const state = {
|
||||
catalog: [],
|
||||
system: [],
|
||||
@@ -44,6 +55,7 @@ function pickNode(list, inputName) {
|
||||
return (list || []).find((item) => item.inputs?.some((p) => p.name === inputName));
|
||||
}
|
||||
|
||||
/** 生成「抽城市 → 有城市才查天气」的示例图。连线 when=hasValidCities。 */
|
||||
function exampleGraph() {
|
||||
const fileInfo = pickNode(state.system, "filePath") || pickNode(state.catalog, "filePath");
|
||||
const weatherInfo = pickNode(state.plugins, "cities") || pickNode(state.system, "cities") || pickNode(state.catalog, "cities");
|
||||
@@ -110,6 +122,7 @@ function addNode(type) {
|
||||
render();
|
||||
}
|
||||
|
||||
/** 根据 state 重画节点 DOM;连线是 SVG,在 drawWires。 */
|
||||
function render() {
|
||||
canvas.innerHTML = "";
|
||||
for (const node of state.nodes) {
|
||||
@@ -172,6 +185,7 @@ function startDrag(e, node) {
|
||||
window.addEventListener("mouseup", up);
|
||||
}
|
||||
|
||||
/** 先点输出端口记下 pending,再点输入端口生成一条边。 */
|
||||
function onPort(nodeId, port, dir) {
|
||||
if (dir === "out") {
|
||||
state.pending = { nodeId, port };
|
||||
@@ -293,6 +307,7 @@ function renderInspector() {
|
||||
};
|
||||
}
|
||||
|
||||
/** 把画布图交给后端。可能直接完成,也可能弹出 decisionModal。 */
|
||||
async function runGraph() {
|
||||
closeDecision();
|
||||
logEl.textContent = "运行中…";
|
||||
@@ -379,6 +394,7 @@ function syncDecisionText() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 倒计时到 0 后去 GET 运行结果,因为服务端会自己按默认方案继续。 */
|
||||
function startDecisionTimer(deadline) {
|
||||
if (decisionTimer) {
|
||||
clearInterval(decisionTimer);
|
||||
@@ -447,6 +463,7 @@ decisionSubmit.onclick = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 拉节点目录和凭据列表,刷新左侧面板。 */
|
||||
async function loadCatalog() {
|
||||
const [catalog, credentials] = await Promise.all([
|
||||
(await fetch("/api/catalog")).json(),
|
||||
|
||||
Reference in New Issue
Block a user