dsh-form-fill-agent 0.2.21 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/lib/brand.css +9 -11
- package/lib/client.js +63 -67
- package/lib/ui.html +7 -3
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# AI填表智能体
|
|
2
2
|
|
|
3
|
+
> 统一侧栏适配需要 Better Sidebar `>=0.17.1 <0.19.0`。五个流程入口打开同一 Session Tab;侧栏展开、收起和关闭由宿主管理。缺少依赖时会显示安装升级提示。
|
|
4
|
+
|
|
3
5
|
## 安装与三分钟上手
|
|
4
6
|
|
|
5
7
|
AI填表智能体:支持自动填表、表格填充、表格补全、Excel填表与 Excel回填;使用企查查 MCP 填写 XLSX 空白字段,预览确认后导出新副本。
|
|
6
8
|
|
|
7
9
|
```sh
|
|
8
|
-
dsh plugin --profile web add dsh-
|
|
10
|
+
dsh plugin --profile web add dsh-better-sidebar@0.17.1
|
|
11
|
+
dsh plugin --profile web add dsh-form-fill-agent@0.2.22
|
|
9
12
|
```
|
|
10
13
|
|
|
11
14
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -64,7 +67,7 @@ dsh plugin --profile web add dsh-form-fill-agent@latest
|
|
|
64
67
|
|
|
65
68
|
## 使用边界与数据保存
|
|
66
69
|
|
|
67
|
-
补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.
|
|
70
|
+
补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.22,共享内核为 0.2.10,Provider 为 0.2.2,共享字段契约为 0.1.0。
|
|
68
71
|
|
|
69
72
|
支持企业完整登记名称或 18 位信用代码;简称、主体不一致或多候选不会自动猜选。仅有信用代码的表格也可作为查询锚点。连接候选检索工具时可检索简称,仍需人工确认;缺少工具时降级人工输入。字段映射采用确定性规则及人工确认,不让模型编造事实。支持普通内部公式、固定区域下拉、基础条件格式和普通表格对象;复杂 Excel 结构和 Word 暂不支持,保真边界见下方安全说明。
|
|
70
73
|
|
|
@@ -72,7 +75,7 @@ dsh plugin --profile web add dsh-form-fill-agent@latest
|
|
|
72
75
|
|
|
73
76
|
显式设置 DSH_HOME 时,任务保存至其 form-fill-tasks 目录,默认 24 小时过期;未设置时使用内存。任务保存输入表格和归一化预览,不持久化原始 MCP 响应,可主动删除任务。模型及 MCP 凭据由宿主管理。
|
|
74
77
|
|
|
75
|
-
0.2.
|
|
78
|
+
0.2.22 保存任务 schema 5,兼容读取旧 schema 1–4;回退旧版本须使用升级前任务目录副本或新目录,防止丢失已确认的字段/主体设置。
|
|
76
79
|
|
|
77
80
|
## 文档与反馈
|
|
78
81
|
|
package/lib/brand.css
CHANGED
|
@@ -7,23 +7,16 @@
|
|
|
7
7
|
.ff-ui.ff-modal-host{background:transparent;padding:0;overflow:hidden}.ff-ui.ff-modal-host> :not(dialog):not(script):not(link){visibility:hidden}html:has(>body.ff-ui.ff-modal-host){background:transparent;color-scheme:normal}.ff-ui #wizard-message{color:var(--error);padding:0 20px;margin:4px 0;flex-shrink:0}
|
|
8
8
|
[data-composer-card]:has(.ff-ui .ff-prompt){padding-top:48px}.ff-ui .ff-prompt{margin:6px 10px}.ff-ui dialog>.tabs{padding:8px 20px;flex-shrink:0}
|
|
9
9
|
.ff-ui .ff-launcher{display:flex;align-items:center;gap:8px;color:var(--text);padding:10px 8px;text-decoration:none;border-radius:6px;width:100%}.ff-ui .ff-launcher:hover,.ff-ui .ff-launcher[aria-current=page]{background:var(--soft);color:var(--action)}.ff-ui .ff-launcher .ff-icon{color:var(--brand)}.ff-ui.ff-top{width:100%;min-width:0;padding:4px var(--dsh-sidebar-inline-padding,12px) 4px 0}.ff-ui .ff-shortcuts{display:flex;justify-content:center;gap:6px;flex-wrap:wrap;padding:12px 0}.ff-ui .ff-shortcuts button{display:flex;flex-direction:column;align-items:center;gap:6px;border-color:transparent;background:transparent;color:var(--muted);font-size:12px;min-width:72px}.ff-ui .ff-shortcuts button[aria-pressed=true]{background:var(--soft);color:var(--action)}.ff-ui .ff-prompt{color:var(--action);background:var(--soft);border-color:transparent;display:inline-flex;align-items:center;gap:6px;font-size:13px}
|
|
10
|
-
[data-form-fill-reserve=true]{padding-right:var(--ff-panel-inset)!important}
|
|
11
|
-
.ff-ui .ff-panel-resize{position:absolute;left:-4px;top:0;bottom:0;width:8px;z-index:2;cursor:col-resize;touch-action:none;outline:none}
|
|
12
|
-
.ff-ui .ff-panel-resize:after{content:"";position:absolute;left:3px;top:0;bottom:0;width:3px;background:transparent}
|
|
13
|
-
.ff-ui .ff-panel-resize:hover:after,.ff-ui .ff-panel-resize:focus-visible:after,.ff-ui.ff-resizing .ff-panel-resize:after{background:var(--action)}
|
|
14
|
-
.ff-ui.ff-resizing{user-select:none;cursor:col-resize}.ff-ui.ff-resizing iframe{pointer-events:none}
|
|
15
|
-
.ff-ui.ff-panel{container-type:inline-size}
|
|
16
10
|
.ff-ui .ff-mapping-row{display:grid;gap:8px;padding:14px 0;border-bottom:1px solid var(--line);min-width:0}
|
|
17
11
|
.ff-ui .ff-mapping-row>select{width:100%}.ff-ui .ff-mapping-status{margin:0;font-size:12px;color:var(--muted)}
|
|
18
12
|
.ff-ui .ff-mapping-status[data-unmatched=true]{color:var(--review)}
|
|
19
13
|
.ff-ui .ff-mapping-filters{display:flex;gap:8px;flex-wrap:wrap}.ff-ui .ff-mapping-filters input[type=search]{flex:1 1 180px;min-width:0}.ff-ui .ff-mapping-filters select{flex:1 1 150px;max-width:100%}
|
|
20
14
|
.ff-ui .ff-mapping-suggestions{display:flex;gap:6px;align-items:center;flex-wrap:wrap;font-size:12px}.ff-ui .ff-mapping-suggestions:empty{display:none}
|
|
21
|
-
|
|
22
|
-
.ff-ui.ff-panel{position:fixed;right:0;top:0;bottom:0;z-index:1000;background:var(--surface);display:flex;flex-direction:column;border-left:1px solid var(--line)}.ff-ui .ff-panel-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line);flex-shrink:0}.ff-ui .ff-panel-head .ff-mark{width:32px;height:32px}.ff-ui .ff-panel-head .ff-mark svg{width:20px;height:20px}.ff-ui .ff-panel-head h2{font-size:16px}.ff-ui .ff-panel-actions{display:flex;gap:6px}.ff-ui.ff-panel iframe{border:0;width:100%;flex:1;min-height:0}
|
|
15
|
+
|
|
23
16
|
.ff-ui.ff-workbench{margin:0;padding:20px;background:var(--surface);max-width:none}.ff-ui h1{font-size:24px}.ff-ui h2{font-size:18px}.ff-ui p{line-height:1.7}.ff-ui .muted{color:var(--muted);font-size:12px}.ff-ui .toolbar,.ff-ui .controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.ff-ui .toolbar{justify-content:space-between}.ff-ui .tabs{display:flex;gap:10px;overflow:auto;border-bottom:1px solid var(--line);padding:8px 0}.ff-ui .tabs button{white-space:nowrap;background:transparent;border:0;border-bottom:2px solid transparent;border-radius:0;padding:8px 0;font-size:12px;color:var(--muted)}.ff-ui .tabs button[aria-current=true]{border-bottom-color:var(--action);color:var(--action)}.ff-ui .task-tabs{display:flex;gap:20px;border-bottom:1px solid var(--line)}.ff-ui .task-tabs button{border:0;border-bottom:3px solid transparent;border-radius:0;background:transparent;padding:10px 0}.ff-ui .task-tabs button[aria-pressed=true]{color:var(--action);border-bottom-color:var(--action)}.ff-ui .card{padding:16px 0;margin:0;border-bottom:1px solid var(--line)}.ff-ui #status{min-height:26px;color:var(--muted);font-size:13px}.ff-ui #status[data-error=true]{color:var(--error)}.ff-ui .badge{display:inline-block;padding:3px 8px;border-radius:4px;background:var(--soft);color:var(--action);font-size:12px}.ff-ui .badge[data-state=completed]{color:var(--success);background:var(--success-bg)}.ff-ui .badge[data-state=partial],.ff-ui .badge[data-state=interrupted]{color:var(--review);background:var(--review-bg)}.ff-ui .badge[data-state=failed]{color:var(--error)}
|
|
24
17
|
.ff-ui .scroll{overflow:auto;max-height:520px;border:1px solid var(--line);border-radius:6px}.ff-ui .grid-changed{background:var(--soft);color:var(--action);font-weight:600}.ff-ui table{border-collapse:separate;border-spacing:0;width:100%;font-size:13px}.ff-ui th,.ff-ui td{padding:12px;white-space:nowrap;text-align:left;vertical-align:top;border-bottom:1px solid var(--line);border-right:1px solid var(--line);min-width:100px}.ff-ui th{position:sticky;top:0;background:var(--head);font-weight:500;z-index:1}.ff-ui tr:hover td{background:var(--head)}.ff-ui td:last-child,.ff-ui th:last-child{border-right:0}.ff-ui #downloads{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}.ff-ui fieldset{border:1px solid var(--line);border-radius:8px;padding:14px;margin:12px 0;min-width:0}.ff-ui legend{font-weight:600}.ff-ui label{overflow-wrap:anywhere}.ff-ui .history-item{padding:12px 0;border-bottom:1px solid var(--line)}.ff-ui .ff-field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;background:var(--page);padding:12px;border-radius:6px}.ff-ui .ff-field-grid label{display:flex;align-items:center;gap:8px;min-height:36px}.ff-ui .ff-wizard-step{display:none}.ff-ui .ff-wizard-step[aria-current=true]{display:block}
|
|
25
18
|
.ff-ui dialog,.ff-ui.ff-confirm-dialog{border:1px solid var(--line);background:var(--surface);color:var(--text);border-radius:12px;padding:0;width:min(860px,calc(100vw - 32px));max-height:calc(100dvh - 32px);box-shadow:0 16px 60px #10243d24}.ff-ui dialog::backdrop,.ff-ui.ff-confirm-dialog::backdrop{background:#14253870}.ff-ui dialog[open]{display:flex;flex-direction:column}.ff-ui .dialog-head{padding:18px 20px;border-bottom:1px solid var(--line);flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:12px}.ff-ui .dialog-body{padding:20px;overflow:auto;min-height:0;flex:1}.ff-ui .dialog-footer{padding:14px 20px;border-top:1px solid var(--line);flex-shrink:0;display:flex;gap:10px;align-items:center;justify-content:flex-end}.ff-ui .dialog-body textarea{width:100%}.ff-ui .ff-tech{overflow-wrap:anywhere;white-space:pre-wrap;font-size:12px}.ff-ui .ff-summary{padding:12px;background:var(--page);white-space:pre-line}.ff-ui .danger{color:var(--error)}
|
|
26
|
-
@media(max-width:640px){.ff-ui.ff-workbench{padding:14px}.ff-ui input:not([type=checkbox]),.ff-ui select,.ff-ui textarea{font-size:16px}.ff-ui button{min-height:44px}.ff-ui.ff-hero h1{font-size:22px}.ff-ui.ff-hero .ff-mark{width:40px;height:40px}.ff-ui .ff-shortcuts{gap:2px}.ff-ui .ff-shortcuts button{min-width:0;flex:1;padding:8px 2px;font-size:11px}.ff-ui .ff-field-grid{grid-template-columns:1fr}.ff-ui .dialog-body{padding:14px}.ff-ui .dialog-footer{padding:12px;flex-wrap:wrap}
|
|
19
|
+
@media(max-width:640px){.ff-ui.ff-workbench{padding:14px}.ff-ui input:not([type=checkbox]),.ff-ui select,.ff-ui textarea{font-size:16px}.ff-ui button{min-height:44px}.ff-ui.ff-hero h1{font-size:22px}.ff-ui.ff-hero .ff-mark{width:40px;height:40px}.ff-ui .ff-shortcuts{gap:2px}.ff-ui .ff-shortcuts button{min-width:0;flex:1;padding:8px 2px;font-size:11px}.ff-ui .ff-field-grid{grid-template-columns:1fr}.ff-ui .dialog-body{padding:14px}.ff-ui .dialog-footer{padding:12px;flex-wrap:wrap}}
|
|
27
20
|
.ff-ui .ff-stages{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));min-width:0;width:100%;padding:0;border-bottom:1px solid var(--line);background:var(--surface)}
|
|
28
21
|
.ff-ui .ff-stages button{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;min-width:0;min-height:78px;padding:9px 5px;border:0;border-right:1px solid var(--line);border-radius:0;background:transparent;color:var(--muted)}
|
|
29
22
|
.ff-ui .ff-stages button:last-child{border-right:0}.ff-ui .ff-stages button:hover{background:var(--page);color:var(--text)}
|
|
@@ -37,13 +30,12 @@
|
|
|
37
30
|
.ff-ui .ff-shortcuts button:hover:not(:disabled),.ff-ui .ff-shortcuts button:focus-visible{background:var(--soft);border-color:var(--line);color:var(--action)}
|
|
38
31
|
[data-form-fill-mount]{width:100%;min-width:0;max-width:100%}[data-form-fill-mount]>.ff-ui{min-width:0;max-width:100%}
|
|
39
32
|
.ff-ui.ff-workbench{padding:0;background:var(--page);min-width:0}.ff-ui .ff-workbench-head{padding:20px;background:var(--surface);border-bottom:1px solid var(--line)}.ff-ui .ff-workbench-head h1{font-size:18px}.ff-ui .ff-workbench-head p{margin:8px 0 0}.ff-ui.ff-embedded .ff-workbench-head{display:none}
|
|
40
|
-
.ff-ui .ff-panel-head{padding:16px;background:var(--surface)}.ff-ui .ff-panel-actions{flex-shrink:0}.ff-ui .ff-panel-actions button{font-size:12px;padding:6px 8px}.ff-ui .ff-panel-head h2{font-size:16px;white-space:nowrap}
|
|
41
33
|
.ff-ui .task-tabs{padding:0 20px;background:var(--surface)}.ff-ui #status{margin:0;padding:10px 20px;background:var(--head);overflow-wrap:anywhere;min-height:0;border-bottom:1px solid var(--line)}.ff-ui #status:empty,.ff-ui #task-meta:empty{display:none}
|
|
42
34
|
.ff-ui #current,.ff-ui #preview{min-width:0}.ff-ui #current:not(:has(#preview:not([hidden]))) .ff-execution-toolbar{display:none}
|
|
43
35
|
.ff-ui #task-meta{margin:16px 20px 0;max-width:calc(100% - 40px);white-space:normal;overflow-wrap:anywhere}.ff-ui .ff-execution-toolbar{margin:12px 20px;justify-content:flex-start}
|
|
44
36
|
.ff-ui .card{margin:16px 20px;padding:20px;border:1px solid var(--line);border-radius:8px;background:var(--surface);min-width:0}.ff-ui .card h2{margin:0 0 12px;font-size:18px}.ff-ui .card p{margin:8px 0 16px}.ff-ui #grid{margin:16px 20px;padding:16px;background:var(--surface);border:1px solid var(--line);border-radius:8px;min-width:0}.ff-ui #grid summary{cursor:pointer;font-weight:600}
|
|
45
37
|
.ff-ui #history{padding:20px}.ff-ui #preview>.controls{padding:0 20px 20px}.ff-ui input[type=file]{width:100%;max-width:100%;min-width:0;font-size:12px}.ff-ui input[type=file]::file-selector-button{font:inherit;border:1px solid var(--line);border-radius:6px;padding:8px 12px;margin-right:10px;background:var(--surface);color:var(--text);cursor:pointer}.ff-ui #samples{margin-top:12px}.ff-ui .history-item{background:var(--surface);padding:16px;border:1px solid var(--line);border-radius:8px;margin-top:12px}
|
|
46
|
-
@media(max-width:640px){.ff-ui .ff-shortcuts{justify-content:flex-start;padding-inline:12px;gap:8px}.ff-ui .ff-shortcuts button{flex:0 0 auto;min-width:92px;padding:7px 10px;font-size:12px}.ff-ui .card{margin:14px;padding:16px}.ff-ui #grid{margin:14px}.ff-ui .task-tabs{padding-inline:14px}.ff-ui #status{padding-inline:14px}.ff-ui #task-meta{margin-inline:14px;max-width:calc(100% - 28px)}.ff-ui .ff-execution-toolbar{margin-inline:14px}.ff-ui .ff-
|
|
38
|
+
@media(max-width:640px){.ff-ui .ff-shortcuts{justify-content:flex-start;padding-inline:12px;gap:8px}.ff-ui .ff-shortcuts button{flex:0 0 auto;min-width:92px;padding:7px 10px;font-size:12px}.ff-ui .card{margin:14px;padding:16px}.ff-ui #grid{margin:14px}.ff-ui .task-tabs{padding-inline:14px}.ff-ui #status{padding-inline:14px}.ff-ui #task-meta{margin-inline:14px;max-width:calc(100% - 28px)}.ff-ui .ff-execution-toolbar{margin-inline:14px}.ff-ui .ff-workbench-head{padding:16px}}
|
|
47
39
|
.ff-ui .ff-field-picker{position:relative;width:100%;min-width:0}.ff-ui .ff-field-picker>summary{padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--surface);cursor:pointer;overflow-wrap:anywhere}.ff-ui .ff-field-picker[open]>summary{border-color:var(--blue)}.ff-ui .ff-field-panel{padding:12px;border:1px solid var(--line);border-radius:8px;background:var(--surface);margin-top:4px;min-width:0}.ff-ui .ff-field-panel select[data-column]{width:100%;height:auto;max-width:100%}.ff-ui .ff-field-panel optgroup{font-weight:600}.ff-ui .ff-field-panel option{padding:7px;font-weight:400}
|
|
48
40
|
.ff-ui #wizard .dialog-head{align-items:flex-start;border-bottom:0;padding:24px 24px 12px}.ff-ui #wizard .dialog-head h2{margin:0;font-size:22px}.ff-ui #wizard .dialog-head p{margin:8px 0 0;line-height:1.6}.ff-ui #wizard-close{border-radius:50%;width:44px;height:44px;min-width:44px;padding:0;font-size:26px;line-height:1}.ff-ui .ff-wizard-nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding:8px 24px 12px;flex-shrink:0}.ff-ui .ff-wizard-nav button{display:flex;align-items:center;gap:8px;min-height:52px;padding:10px;font-size:14px;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--text);text-align:left}.ff-ui .ff-step-number{display:inline-flex;align-items:center;justify-content:center;flex:0 0 28px;height:28px;border-radius:50%;background:var(--line);color:var(--muted);font-weight:600}.ff-ui .ff-wizard-nav button[aria-current=true]{border-color:var(--action);background:var(--soft);color:var(--action)}.ff-ui .ff-wizard-nav button[aria-current=true] .ff-step-number{background:var(--action);color:white}.ff-ui #wizard .dialog-body{padding:16px 24px 24px}.ff-ui #wizard h3{font-size:18px;margin:0 0 12px}.ff-ui #wizard p{line-height:1.65}.ff-ui .ff-upload-zone{padding:18px;background:var(--page);border:1px dashed var(--line);border-radius:8px}.ff-ui .ff-upload-zone label{display:grid;gap:12px;font-weight:600}.ff-ui .ff-service-note{padding:12px 16px;border-radius:8px;background:var(--page);color:var(--muted)}.ff-ui #wizard .dialog-footer{padding:16px 24px}.ff-ui #wizard .dialog-footer button{min-height:44px}
|
|
49
41
|
@media(max-width:640px){.ff-ui .ff-wizard-nav{grid-template-columns:repeat(2,minmax(0,1fr));padding:8px 14px;gap:6px}.ff-ui .ff-wizard-nav button{min-height:44px;padding:6px 8px}.ff-ui #wizard .dialog-head{padding:16px 14px 8px}.ff-ui #wizard .dialog-head h2{font-size:20px}.ff-ui #wizard .dialog-head p{font-size:13px}.ff-ui #wizard .dialog-body{padding:14px}.ff-ui #wizard .dialog-footer{padding:12px 14px}}
|
|
@@ -73,3 +65,9 @@
|
|
|
73
65
|
.ff-failure-count { color: var(--error); font-weight: 600; }
|
|
74
66
|
#wizard-grid { min-width: 0; margin-bottom: 16px; }
|
|
75
67
|
#task-meta, #task-details { overflow-wrap: anywhere; }
|
|
68
|
+
|
|
69
|
+
.ff-ui.ff-tab-content{height:100%;min-height:0;min-width:0;width:100%;display:flex;flex-direction:column;background:var(--surface);container-type:inline-size}
|
|
70
|
+
.ff-ui .ff-tab-head{flex-shrink:0;padding:12px 16px;border-bottom:1px solid var(--line)}
|
|
71
|
+
.ff-ui .ff-tab-head h2{font-size:16px;margin:0}
|
|
72
|
+
.ff-ui.ff-tab-content iframe{width:100%;border:0;flex:1;min-height:0}
|
|
73
|
+
.ff-ui .ff-sidebar-help{color:var(--error);padding:8px 12px;overflow-wrap:anywhere}
|
package/lib/client.js
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({
|
|
2
2
|
id: 'dsh-form-fill-agent',
|
|
3
3
|
factory(require) {
|
|
4
|
+
const SIDEBAR_TAB='dsh-form-fill-agent:workbench';
|
|
5
|
+
const SIDEBAR_HELP='工作台需要 Better Sidebar >=0.17.1 <0.19.0。请在当前 DSH profile 安装或升级 dsh-better-sidebar,重启后重试;原生对话仍可使用。';
|
|
6
|
+
// The only adapter allowed to reveal host panels. No geometry or business writes.
|
|
7
|
+
function createSidebarAdapter(service,component,icon){
|
|
8
|
+
const version=/^0\.(17|18)\.(\d+)$/.exec(service?.version||'');
|
|
9
|
+
if(!version||version[1]==='17'&&Number(version[2])<1||!Array.isArray(service.features)||!['targetedOpen','stateSubscription'].every(f=>service.features.includes(f))||!['registerTab','isTabEnabled','openTab','closeTab','getSnapshot','subscribeState'].every(k=>typeof service[k]==='function'))throw Error(SIDEBAR_HELP);
|
|
10
|
+
const targets=new Map(),pending=new Set(),opened=new Map();let disposed=false;
|
|
11
|
+
const contains=(node,id)=>node?.kind==='leaf'?node.tabs.some(t=>t.id===id):node?.children?.some(c=>contains(c,id));
|
|
12
|
+
const flush=()=>{
|
|
13
|
+
if(disposed)return;const id=service.getSnapshot().sessionId,target=targets.get(id);
|
|
14
|
+
if(!target||!pending.has(id))return;
|
|
15
|
+
pending.delete(id);
|
|
16
|
+
target.store.reduce(state=>{
|
|
17
|
+
if(state.floats?.some(f=>f.tab.id===target.tabId))return state;
|
|
18
|
+
if(contains(state.bottomSplits,target.tabId))return state.bottomOpen?state:{...state,bottomOpen:true};
|
|
19
|
+
if(contains(state.splits,target.tabId))return state.panelOpen?state:{...state,panelOpen:true};
|
|
20
|
+
return state;
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
const unregister=service.registerTab({id:SIDEBAR_TAB,title:'AI填表',icon,order:20,single:true,hidden:true,component});
|
|
24
|
+
const unsubscribe=service.subscribeState(flush);
|
|
25
|
+
return {
|
|
26
|
+
open(scope){if(disposed)throw Error(SIDEBAR_HELP);if(!service.isTabEnabled(SIDEBAR_TAB))throw Error('AI填表 Tab 已禁用,请在 Better Sidebar 设置中启用。');opened.set(scope.sessionId,scope);pending.add(scope.sessionId);service.openTab({type:SIDEBAR_TAB},scope);flush();},
|
|
27
|
+
attach(scope,store,tab){if(disposed)return()=>{};if(typeof store?.reduce!=='function')throw Error(SIDEBAR_HELP);const target={store,tabId:tab.id};targets.set(scope.sessionId,target);flush();return()=>{if(targets.get(scope.sessionId)===target)targets.delete(scope.sessionId)};},
|
|
28
|
+
dispose(){if(disposed)return;disposed=true;unsubscribe();pending.clear();targets.clear();for(const scope of opened.values())service.closeTab(SIDEBAR_TAB,scope);opened.clear();unregister();}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
4
31
|
function apply(ctx) {
|
|
5
32
|
let React, portal;
|
|
6
33
|
try { React=require('react');portal=require('react-dom').createPortal; } catch {}
|
|
7
34
|
if(typeof React?.createElement!=='function'||!ctx.slots?.inject||!ctx.slots?.register)return;
|
|
8
35
|
const h=React.createElement,prefix='session-dsh-form-fill-agent-';
|
|
9
36
|
const owned=id=>typeof id==='string'&&id.startsWith(prefix);
|
|
10
|
-
const disposers=[],sessionTasks=new Map(),lastDrafts=new Map();let
|
|
37
|
+
const disposers=[],sessionTasks=new Map(),lastDrafts=new Map(),views=new Map(),viewListeners=new Set();let sidebar,pendingStart,activePlugin=true,sidebarError=SIDEBAR_HELP;
|
|
11
38
|
const paths={table:'M3 4h18v16H3zM3 9h18M9 9v11',upload:'M12 16V3M7 8l5-5 5 5M4 14v7h16v-7',check:'M3 5h2v2H3zM9 6h12M3 11h2v2H3zM9 12h12M3 17h2v2H3zM9 18h12',search:'M17 17l5 5M19 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0',history:'M3 11a9 9 0 1 1 2 7M3 4v7h7M12 7v6l4 2',spark:'M12 3l2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5z'};
|
|
12
39
|
const icon=(name='table')=>h('svg',{className:'ff-icon',viewBox:'0 0 24 24','aria-hidden':true},h('path',{d:paths[name]}));
|
|
13
40
|
const mark=()=>h('span',{className:'ff-mark'},icon());
|
|
@@ -16,8 +43,13 @@ window.__ModuleLoader__.load({
|
|
|
16
43
|
const current=()=>ctx.sessions?.list?.getSnapshot?.().current;
|
|
17
44
|
function register(name,component){ctx.slots.inject(name,()=>ctx.slots.register({name,id:'form-fill-agent',order:120},component))}
|
|
18
45
|
function openPanel(id,step='import'){
|
|
19
|
-
if(!owned(id))return;
|
|
20
|
-
|
|
46
|
+
if(!activePlugin||!owned(id))return;
|
|
47
|
+
try{
|
|
48
|
+
if(!sidebar)throw Error(sidebarError);
|
|
49
|
+
const workspace=ctx.workspaces?.list?.getSnapshot?.().items?.find(w=>w.sessionIds?.includes(id));
|
|
50
|
+
views.set(id,{id,step});sidebar.open({sessionId:id,...(workspace?.path?{cwd:workspace.path}:{})});
|
|
51
|
+
for(const listener of viewListeners)listener();
|
|
52
|
+
}catch(error){sidebarError=error.message;for(const listener of viewListeners)listener(sidebarError)}
|
|
21
53
|
}
|
|
22
54
|
async function start(){
|
|
23
55
|
if(pendingStart)return pendingStart;
|
|
@@ -82,7 +114,8 @@ window.__ModuleLoader__.load({
|
|
|
82
114
|
return mount?portal(h(React.Fragment,null,h('div',{className:'ff-brand ff-hero-brand'},mark(),h('h1',null,'AI填表智能体')),h('p',null,'上传已有表格,核对字段映射,确认后生成新副本。')),mount):null;
|
|
83
115
|
}
|
|
84
116
|
function Menu({sessionId}){
|
|
85
|
-
const ref=React.useRef(null),[mount,setMount]=React.useState(null);
|
|
117
|
+
const ref=React.useRef(null),[mount,setMount]=React.useState(null),[error,setError]=React.useState('');
|
|
118
|
+
React.useEffect(()=>{const report=message=>setError(message||'');viewListeners.add(report);return()=>viewListeners.delete(report)},[]);
|
|
86
119
|
React.useEffect(()=>{
|
|
87
120
|
if(!owned(sessionId)||!ref.current)return;
|
|
88
121
|
const marker=ref.current,seat=marker.closest('[data-composer-seat]'),card=seat?.querySelector('[data-composer-card]');
|
|
@@ -95,50 +128,31 @@ window.__ModuleLoader__.load({
|
|
|
95
128
|
if(!owned(sessionId))return null;
|
|
96
129
|
const content=h('div',{className:'ff-ui','data-ff-theme':theme()},h('nav',{className:'ff-shortcuts','aria-label':'AI填表快捷菜单'},...[
|
|
97
130
|
['导入表格','import','upload'],['字段设置','rules','check'],['主体核验','identity','search'],['填写预览','preview','table'],['任务历史','history','history']
|
|
98
|
-
].map(([label,step,symbol])=>h('button',{key:step,type:'button',onClick:()=>openPanel(sessionId,step)},icon(symbol),h('span',{className:'ff-shortcut-label'},label)))));
|
|
131
|
+
].map(([label,step,symbol])=>h('button',{key:step,type:'button',onClick:()=>openPanel(sessionId,step)},icon(symbol),h('span',{className:'ff-shortcut-label'},label)))),error?h('p',{className:'ff-sidebar-help',role:'alert'},error):null);
|
|
99
132
|
return h('div',{ref,'data-form-fill-session':sessionId},h(Hero,{sessionId}),mount?portal(content,mount):content);
|
|
100
133
|
}
|
|
101
|
-
function
|
|
102
|
-
const
|
|
103
|
-
const [
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if(cancel){setPreferred(prior.preferred);setExpanded(prior.expanded)}
|
|
110
|
-
if(prior.node.hasPointerCapture(prior.id))prior.node.releasePointerCapture(prior.id);
|
|
111
|
-
};
|
|
112
|
-
const resizeKeys=event=>{
|
|
113
|
-
if(event.key==='Escape'&&drag.current){event.preventDefault();event.stopPropagation();finishDrag(true);return}
|
|
114
|
-
if(drag.current)return;
|
|
115
|
-
const amount=event.shiftKey?48:16,value={ArrowLeft:panelWidth+amount,ArrowRight:panelWidth-amount,Home:320,End:maxWidth}[event.key];
|
|
116
|
-
if(value===undefined)return;event.preventDefault();setExpanded(false);setPreferred(clamp(value));
|
|
117
|
-
};
|
|
134
|
+
function WorkbenchTab({scope,store,tab,visible}){
|
|
135
|
+
const id=scope.sessionId,frame=React.useRef(null),ready=React.useRef(false);
|
|
136
|
+
const [view,setView]=React.useState(()=>views.get(id)||{id,step:'import'});
|
|
137
|
+
const [src]=React.useState(()=>'/form-fill/?session='+encodeURIComponent(id)+(sessionTasks.has(id)?'#task='+sessionTasks.get(id):''));
|
|
138
|
+
React.useEffect(()=>{
|
|
139
|
+
const update=()=>{const next=views.get(id);if(next)setView(next)};viewListeners.add(update);
|
|
140
|
+
const detach=sidebar?.attach(scope,store,tab);return()=>{viewListeners.delete(update);detach?.()};
|
|
141
|
+
},[id,store,tab.id]);
|
|
118
142
|
React.useEffect(()=>{
|
|
119
|
-
const sync=()=>{
|
|
143
|
+
const sync=()=>{frame.current?.contentWindow?.postMessage({type:'ff-theme',theme:theme()},location.origin)};
|
|
120
144
|
const observer=new MutationObserver(sync);observer.observe(document.documentElement,{attributes:true,attributeFilter:['class','style','data-ds-dark-theme']});const media=matchMedia('(prefers-color-scheme:dark)');media.addEventListener('change',sync);sync();
|
|
121
145
|
return()=>{observer.disconnect();media.removeEventListener('change',sync)};
|
|
122
146
|
},[]);
|
|
123
|
-
React.useEffect(()=>{
|
|
124
|
-
const measure=()=>{const container=document.querySelector('[data-composer-card]')?.closest('[data-phase]')||document.querySelector('[data-slot="conversation"]');setAvailable(Math.max(0,innerWidth-Math.max(0,container?.getBoundingClientRect().left||0)))};
|
|
125
|
-
const resize=()=>{finishDrag(true);measure()},blur=()=>finishDrag(true);
|
|
126
|
-
const escape=event=>{if(event.key==='Escape'&&drag.current){event.preventDefault();event.stopImmediatePropagation();finishDrag(true)}};
|
|
127
|
-
const observer=new ResizeObserver(measure);observer.observe(document.body);
|
|
128
|
-
const container=document.querySelector('[data-composer-card]')?.closest('[data-phase]')||document.querySelector('[data-slot="conversation"]');if(container)observer.observe(container);
|
|
129
|
-
measure();window.addEventListener('resize',resize);window.addEventListener('blur',blur);window.addEventListener('keydown',escape,true);
|
|
130
|
-
return()=>{finishDrag(true);observer.disconnect();window.removeEventListener('resize',resize);window.removeEventListener('blur',blur);window.removeEventListener('keydown',escape,true)};
|
|
131
|
-
},[view?.id,active,modal]);
|
|
132
|
-
React.useEffect(()=>{panel=setView;const timer=setInterval(()=>setActive(current()),200);return()=>{panel=null;clearInterval(timer)}},[]);
|
|
133
|
-
React.useEffect(()=>{if(view&¤t()!==view.id)setView(null);setModal(false)},[active,view?.id]);
|
|
134
|
-
React.useEffect(()=>{frame.current?.contentWindow?.postMessage({type:'ff-navigate',step:view?.step},location.origin)},[view]);
|
|
147
|
+
React.useEffect(()=>{if(ready.current)frame.current?.contentWindow?.postMessage({type:'ff-navigate',step:view.step},location.origin)},[view]);
|
|
135
148
|
React.useEffect(()=>{
|
|
136
149
|
const receive=async event=>{
|
|
137
|
-
if(event.origin!==location.origin||event.source!==frame.current?.contentWindow
|
|
150
|
+
if(event.origin!==location.origin||event.source!==frame.current?.contentWindow)return;
|
|
138
151
|
if(event.data?.type==='ff-capabilities'){frame.current.contentWindow.postMessage({type:'ff-capabilities-result',mappingDraft:2},location.origin);return}
|
|
139
|
-
if(event.data?.type==='ff-
|
|
152
|
+
if(event.data?.type==='ff-view'&&ready.current&&['import','rules','identity','preview','download','history'].includes(event.data.step)){views.set(view.id,{id:view.id,step:event.data.step});return}
|
|
153
|
+
if(event.data?.type==='ff-wizard-state'){if(!event.data.open&&event.data.focusComposer)setTimeout(()=>{if(current()===view.id)document.querySelector('[data-composer-card] textarea, [data-composer-card] [contenteditable=true]')?.focus()},0);return}
|
|
140
154
|
if(event.data?.type==='ff-task'&&/^[a-f0-9-]{36}$/.test(event.data.taskId)){sessionTasks.set(view.id,event.data.taskId);return}
|
|
141
|
-
if(event.data?.type!=='ff-draft')return;
|
|
155
|
+
if(event.data?.type!=='ff-draft'||current()!==view.id)return;
|
|
142
156
|
const {taskId,revision,requirements}=event.data;
|
|
143
157
|
if(!/^[a-f0-9-]{36}$/.test(taskId)||!Number.isSafeInteger(revision))return;
|
|
144
158
|
let ok=false;
|
|
@@ -163,38 +177,20 @@ window.__ModuleLoader__.load({
|
|
|
163
177
|
};
|
|
164
178
|
window.addEventListener('message',receive);return()=>window.removeEventListener('message',receive);
|
|
165
179
|
},[view?.id]);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const marker=[...document.querySelectorAll('[data-form-fill-session]')].find(n=>n.dataset.formFillSession===view.id);
|
|
172
|
-
const container=marker?document.querySelector('[data-composer-card]')?.closest('[data-phase]')||document.querySelector('[data-slot="conversation"]'):null;
|
|
173
|
-
for(const node of touched.keys())if(node!==container){node.removeAttribute('data-form-fill-reserve');node.style.removeProperty('--ff-panel-inset')}
|
|
174
|
-
if(!container)return;
|
|
175
|
-
if(!touched.has(container))touched.set(container,container.style.getPropertyValue('--ff-panel-inset'));
|
|
176
|
-
container.setAttribute('data-form-fill-reserve','true');
|
|
177
|
-
container.style.setProperty('--ff-panel-inset',panelWidth+'px');
|
|
178
|
-
};
|
|
179
|
-
adjust();const observer=new MutationObserver(adjust);observer.observe(document.body,{childList:true,subtree:true});
|
|
180
|
-
return()=>{observer.disconnect();for(const [node,previous]of touched){node.removeAttribute('data-form-fill-reserve');if(previous)node.style.setProperty('--ff-panel-inset',previous);else node.style.removeProperty('--ff-panel-inset')}};
|
|
181
|
-
},[view?.id,panelWidth,active,wide,modal]);
|
|
182
|
-
if(!view||active!==view.id)return null;
|
|
183
|
-
return portal(h('section',{className:'ff-ui ff-panel'+(dragging?' ff-resizing':''),'data-ff-theme':theme(),'aria-label':'AI填表工作台',style:{width:modal?'100%':wide?panelWidth+'px':'100%',...(modal?{background:'transparent',border:0}:{})}},
|
|
184
|
-
wide&&!modal?h('div',{className:'ff-panel-resize',role:'separator',tabIndex:0,'aria-label':'调整工作台宽度','aria-orientation':'vertical','aria-valuemin':320,'aria-valuemax':maxWidth,'aria-valuenow':panelWidth,'aria-valuetext':panelWidth+' 像素',title:'拖动调宽;左右键微调,Home/End 最小/最大;双击恢复默认',onKeyDown:resizeKeys,
|
|
185
|
-
onDoubleClick:()=>{finishDrag(true);setPreferred(null);setExpanded(false)},
|
|
186
|
-
onPointerDown:event=>{if(event.button!==0||drag.current)return;event.preventDefault();event.currentTarget.focus();drag.current={id:event.pointerId,node:event.currentTarget,x:event.clientX,width:panelWidth,preferred,expanded};event.currentTarget.setPointerCapture(event.pointerId);setDragging(true)},
|
|
187
|
-
onPointerMove:event=>{const prior=drag.current;if(prior?.id!==event.pointerId)return;setPreferred(clamp(prior.width+prior.x-event.clientX));setExpanded(false)},
|
|
188
|
-
onPointerUp:()=>finishDrag(),onPointerCancel:()=>finishDrag(true),onLostPointerCapture:()=>finishDrag(true)
|
|
189
|
-
}):null,
|
|
190
|
-
h('div',{className:'ff-panel-head',hidden:modal},h('div',{className:'ff-brand'},mark(),h('h2',null,'AI填表工作台')),h('div',{className:'ff-panel-actions'},h('button',{onClick:()=>setExpanded(v=>!v)},expanded?'收起展开':'展开工作台'),h('button',{onClick:()=>setView(null)},'关闭工作台'))),
|
|
191
|
-
h('iframe',{ref:frame,title:'AI填表任务',src:'/form-fill/?session='+encodeURIComponent(view.id)+(sessionTasks.has(view.id)?'#task='+sessionTasks.get(view.id):''),onLoad:()=>{frame.current.contentWindow.postMessage({type:'ff-theme',theme:theme()},location.origin);frame.current.contentWindow.postMessage({type:'ff-navigate',step:view.step},location.origin)}})),document.body);
|
|
180
|
+
|
|
181
|
+
if(!owned(id))return h('p',null,'请从 AI填表入口打开对应业务会话。');
|
|
182
|
+
return h('section',{className:'ff-ui ff-tab-content','data-ff-theme':theme(),'aria-label':'AI填表工作台'},
|
|
183
|
+
h('div',{className:'ff-tab-head'},h('div',{className:'ff-brand'},mark(),h('h2',null,'AI填表工作台'))),
|
|
184
|
+
h('iframe',{ref:frame,title:'AI填表任务',src,onLoad:()=>{ready.current=true;frame.current.contentWindow.postMessage({type:'ff-theme',theme:theme()},location.origin);frame.current.contentWindow.postMessage({type:'ff-navigate',step:(views.get(id)||view).step},location.origin)}}));
|
|
192
185
|
}
|
|
186
|
+
const connect=scope=>{
|
|
187
|
+
try{const adapter=createSidebarAdapter(scope.betterSidebar,props=>h(WorkbenchTab,{...props,key:props.scope.sessionId}),icon());sidebar=adapter;sidebarError='';const disconnect=()=>{if(sidebar===adapter)sidebar=undefined;adapter.dispose()};scope.effect?.(()=>disconnect);disposers.push(disconnect)}catch(error){sidebarError=error.message}
|
|
188
|
+
};
|
|
189
|
+
if(ctx.inject)ctx.inject(['betterSidebar'],connect);else if(ctx.betterSidebar)connect(ctx);
|
|
193
190
|
register('conversation.input.dock',Menu);
|
|
194
191
|
register('conversation.input.overlay',props=>owned(props.sessionId)?h('div',{className:'ff-ui','data-ff-theme':theme()},h('button',{className:'ff-prompt',type:'button',onClick:()=>openPanel(props.sessionId,'wizard')},icon('spark'),'提示词生成')):null);
|
|
195
|
-
|
|
196
|
-
ctx.effect?.(()=>()=>{for(const dispose of disposers)dispose()});
|
|
192
|
+
ctx.effect?.(()=>()=>{activePlugin=false;for(const dispose of disposers)dispose();viewListeners.clear();views.clear();sessionTasks.clear();lastDrafts.clear()});
|
|
197
193
|
}
|
|
198
|
-
return {name:'form-fill-agent',inject:['slots','sessions','workspaces','conversation'],apply};
|
|
194
|
+
return {createSidebarAdapter,name:'form-fill-agent',inject:['slots','sessions','workspaces','conversation'],apply};
|
|
199
195
|
}
|
|
200
196
|
});
|
package/lib/ui.html
CHANGED
|
@@ -78,7 +78,7 @@ function syncActions(){
|
|
|
78
78
|
$('cancel-run').onclick=async()=>{try{await api('/cancel',{id:current.id});$('status').textContent='已请求取消。已发出的请求可能已在远端执行,本地不再继续后续查询。';await restore()}catch(e){$('status').textContent=e.message}};
|
|
79
79
|
$('retry-run').onclick=()=>{openWizard(true);wizardStep=3;renderWizard()};
|
|
80
80
|
async function api(path,body){if(current&&body?.id===current.id)body={...body,expectedRevision:current.revision};const response=await fetch(basePath+path,{...(body===undefined?{}:{method:'POST',body:JSON.stringify(body)}),headers:{'Content-Type':'application/json','X-Form-Fill-Owner':owner}});const data=await response.json();if(!response.ok)throw Error(data.message);return data}
|
|
81
|
-
function navigate(target){if(target==='wizard'){openWizard();return}if(target!=='import'&&!current){$('status').textContent='请先导入表格。';return}step=target;$('history').hidden=true;$('current').hidden=false;$('current-tab').setAttribute('aria-pressed','true');$('history-tab').setAttribute('aria-pressed','false');document.querySelectorAll('[data-pane]').forEach(p=>p.hidden=p.dataset.pane!==target);document.querySelectorAll('[data-step]').forEach(b=>b.setAttribute('aria-current',String(b.dataset.step===target)))}
|
|
81
|
+
function navigate(target){if(target==='wizard'){openWizard();return}if(target!=='import'&&!current){$('status').textContent='请先导入表格。';return}step=target;if(parent!==window)parent.postMessage({type:'ff-view',step:target},location.origin);$('history').hidden=true;$('current').hidden=false;$('current-tab').setAttribute('aria-pressed','true');$('history-tab').setAttribute('aria-pressed','false');document.querySelectorAll('[data-pane]').forEach(p=>p.hidden=p.dataset.pane!==target);document.querySelectorAll('[data-step]').forEach(b=>b.setAttribute('aria-current',String(b.dataset.step===target)))}
|
|
82
82
|
function downloads(){ $('downloads').replaceChildren();for(const [kind,label,suffix] of [['xlsx','下载已填副本','-已填副本.xlsx'],['changes','下载变更清单','-变更.json'],['incomplete','下载未完成项','-未完成.json']]){if(kind==='incomplete'&&!current.changeSet.incomplete.length)continue;const a=document.createElement('a');Object.assign(a,{className:'download',href:basePath+'/download/'+current.id+'/'+kind,download:filename+suffix,textContent:label});$('downloads').append(a)}}
|
|
83
83
|
function businessSummary(){return current?(retryIntent?'仅重试失败、取消或未执行的部分,保留成功结果。':'')+'填写文件“'+current.filename+'”中的空白字段。共 '+current.analysis.tables.length+' 个工作表,'+wizardFields.size+' 个填写字段,'+current.analysis.opportunities.filter(p=>wizardFields.has(p.field)).length+' 个待补空位置。字段范围以本次保存的映射为准。保留已有值、公式与未确认位置,核验预览后生成新副本。':'请先上传 XLSX 文件。'}
|
|
84
84
|
function command(){return current?businessSummary()+'\n'+$('requirements').value+'\n执行关联:调用 form_fill_enrich:taskId='+current.id+',expectedRevision='+current.revision+(retryIntent?',mode=retry':'')+'。字段范围以工作台确认设置为准。':''}
|
|
@@ -175,6 +175,7 @@ function highlightMappingConflicts(){
|
|
|
175
175
|
}
|
|
176
176
|
function filterResults(){const query=$('result-search').value.trim().toLowerCase(),rows=[...$('changes').rows];let shown=0;for(const tr of rows){tr.hidden=!!query&&!tr.textContent.toLowerCase().includes(query);if(!tr.hidden)shown++}const selected=rows.filter(tr=>tr.querySelector('input')?.checked).length;$('result-count').textContent=rows.length?'显示 '+shown+' / '+rows.length+' 格 · 已选 '+selected+' 格'+(!shown?' · 无匹配结果':''):'暂无可填写单元格'}
|
|
177
177
|
function renderSettings(data){
|
|
178
|
+
try{const saved=JSON.parse(sessionStorage.getItem('ff-ui-mapping:'+data.id));if(saved?.base===JSON.stringify(data.configuration))data={...data,configuration:saved.configuration}}catch{}
|
|
178
179
|
$('mapping').replaceChildren();$('entities').replaceChildren();
|
|
179
180
|
for(const sheet of data.structure||[]){
|
|
180
181
|
const section=document.createElement('fieldset');section.dataset.sheet=sheet.name;
|
|
@@ -304,7 +305,7 @@ $('confirm').onclick=async()=>{if(!current||busy)return;controls(true);try{await
|
|
|
304
305
|
$('selection').onclick=async()=>{if(!current||busy)return;controls(true);try{render(await api('/select',{id:current.id,selectedIds:[...$('changes').querySelectorAll('input:checked')].map(x=>x.value)}));$('status').textContent='选择已应用,请核对新的预览。'}catch(e){$('status').textContent=e.message}finally{controls(false)}};
|
|
305
306
|
$('refresh').onclick=()=>restore();
|
|
306
307
|
$('discard').onclick=async()=>{if(!current||busy)return;controls(true);try{await api('/discard',{id:current.id});current=null;history.replaceState(null,'',location.pathname+location.search);$('preview').hidden=true;$('grid').hidden=true;gridTask=null;navigate('import');$('status').textContent='任务及保存的表格已删除。'}catch(e){$('status').textContent=e.message}finally{controls(false)}};
|
|
307
|
-
$('history-tab').onclick=async()=>{try{const list=await api('/tasks');$('history-list').replaceChildren();for(const item of list){const div=document.createElement('div');div.className='history-item';const button=document.createElement('button');button.textContent=(item.presentation?.title||item.filename)+' · '+(item.presentation?.status||item.state);button.onclick=()=>{location.hash='task='+item.id;restore()};const details=document.createElement('details'),summary=document.createElement('summary');summary.textContent='任务详情';details.append(summary,document.createTextNode('任务 ID:'+item.id));div.append(button,details);$('history-list').append(div)}
|
|
308
|
+
$('history-tab').onclick=async()=>{try{const list=await api('/tasks');$('history-list').replaceChildren();for(const item of list){const div=document.createElement('div');div.className='history-item';const button=document.createElement('button');button.textContent=(item.presentation?.title||item.filename)+' · '+(item.presentation?.status||item.state);button.onclick=()=>{location.hash='task='+item.id;restore()};const details=document.createElement('details'),summary=document.createElement('summary');summary.textContent='任务详情';details.append(summary,document.createTextNode('任务 ID:'+item.id));div.append(button,details);$('history-list').append(div)}if(parent!==window)parent.postMessage({type:'ff-view',step:'history'},location.origin);$('history').hidden=false;$('current').hidden=true;$('current-tab').setAttribute('aria-pressed','false');$('history-tab').setAttribute('aria-pressed','true');if(!list.length)$('history-list').textContent='暂无可恢复的任务。'}catch(e){$('status').textContent=e.message}};
|
|
308
309
|
$('current-tab').onclick=()=>navigate(step);
|
|
309
310
|
$('wizard-open').onclick=()=>directDraft();$('wizard-close').onclick=()=>closeWizard();$('wizard').addEventListener('cancel',e=>{e.preventDefault();closeWizard()});
|
|
310
311
|
document.querySelectorAll('[data-wizard-step]').forEach(b=>b.onclick=()=>{const next=Number(b.dataset.wizardStep);wizardStep=next>1&&wizardMappingApplied!==JSON.stringify([current?.id,readMapping()])?1:next;saveWizard();renderWizard()});
|
|
@@ -320,10 +321,13 @@ $('draft-cancel').onclick=()=>$('draft-conflict').close();
|
|
|
320
321
|
for(const mode of ['append','replace'])$('draft-'+mode).onclick=()=>{$('draft-conflict').close();sendDraft(mode)};
|
|
321
322
|
$('mapping-search').oninput=()=>{const query=$('mapping-search').value.trim().toLowerCase();$('mapping').querySelectorAll('.ff-mapping-row').forEach(row=>row.hidden=!row.dataset.sourceLabel.toLowerCase().includes(query))};
|
|
322
323
|
$('result-search').oninput=filterResults;$('changes').onchange=filterResults;
|
|
323
|
-
window.addEventListener('message',e=>{if(e.origin!==location.origin||e.source!==parent)return;if(e.data?.type==='ff-theme'&&['light','dark'].includes(e.data.theme))document.body.dataset.ffTheme=e.data.theme;if(e.data?.type==='ff-draft-conflict'){expectedDraft=e.data.draft;if(!$('draft-conflict').open)$('draft-conflict').showModal()}if(e.data?.type==='ff-draft-result'){$('status').textContent=e.data.ok?'已回填,请在对话框修改或发送。':'回填失败,任务已保留。';if(e.data.ok){closeWizard(true);navigate('identity');$('status').textContent='指令已回填,发送后将在此显示查询进度。'}}if(e.data?.type==='ff-navigate'){if(!current&&location.hash)pendingNavigation=e.data.step;if(e.data.step==='history')$('history-tab').click();else navigate(e.data.step)}});
|
|
324
|
+
window.addEventListener('message',e=>{if(e.origin!==location.origin||e.source!==parent)return;if(e.data?.type==='ff-theme'&&['light','dark'].includes(e.data.theme))document.body.dataset.ffTheme=e.data.theme;if(e.data?.type==='ff-draft-conflict'){expectedDraft=e.data.draft;if(!$('draft-conflict').open)$('draft-conflict').showModal()}if(e.data?.type==='ff-draft-result'){$('status').textContent=e.data.ok?'已回填,请在对话框修改或发送。':'回填失败,任务已保留。';if(e.data.ok){closeWizard(true);navigate('identity');$('status').textContent='指令已回填,发送后将在此显示查询进度。'}}if(e.data?.type==='ff-navigate'){if(!current&&location.hash){pendingNavigation=e.data.step;return}if(e.data.step==='history')$('history-tab').click();else navigate(e.data.step)}});
|
|
324
325
|
api('/health').then(s=>{$('connection').textContent=s.qccAvailable?'已发现企查查工商工具,可在对话中执行。':'尚未发现企查查工商工具;请先连接 MCP。合成模板仍可体验。'}).catch(()=>{});
|
|
325
326
|
$('preview-continue').onclick=async()=>{if(busy||!current)return;controls(true);try{const ids=[...$('changes').querySelectorAll('input:checked')].map(x=>x.value);if(!current.confirmed&&JSON.stringify([...ids].sort())!==JSON.stringify([...(current.selectedIds||[])].sort()))render(await api('/select',{id:current.id,selectedIds:ids}));navigate('download');$('confirm').scrollIntoView({block:'center'});$('confirm').focus();$('status').textContent=current.confirmed?'副本已生成,请点击下载。':'请确认填写结果,点击蓝色按钮生成新副本。'}catch(e){$('status').textContent=e.message}finally{controls(false)}};
|
|
326
327
|
$('mapping-continue').onclick=()=>{if(busy||!current)return;navigate('identity');$('wizard-open').focus()};
|
|
328
|
+
function saveMappingDraft(){if(!current)return;sessionStorage.setItem('ff-ui-mapping:'+current.id,JSON.stringify({base:JSON.stringify(current.configuration),configuration:readMapping()}));if($('wizard').open)saveWizard()}
|
|
329
|
+
window.addEventListener('pagehide',saveMappingDraft);
|
|
330
|
+
for(const event of ['change','click'])$('mapping').addEventListener(event,saveMappingDraft);
|
|
327
331
|
$('mapping').addEventListener('change',()=>{wizardMappingApplied=false;$('mapping-next').hidden=true;highlightMappingConflicts()});
|
|
328
332
|
window.addEventListener('hashchange',()=>{if(new URLSearchParams(location.hash.slice(1)).get('task')!==current?.id)restore()});
|
|
329
333
|
navigate('import');restore();setInterval(()=>{if(!document.hidden&¤t&&!busy&&!$('wizard').open)restore(true)},2000);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-form-fill-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "AI form filling and spreadsheet autofill for XLSX in DeepSeek Harness, using authorized Qichacha MCP facts with cell previews, user confirmation and export to a new copy.",
|
|
6
6
|
"repository": {
|
|
@@ -35,6 +35,14 @@
|
|
|
35
35
|
"form-fill-core": "0.2.10",
|
|
36
36
|
"qcc-form-fill-provider": "0.2.2"
|
|
37
37
|
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"dsh-better-sidebar": ">=0.17.1 <0.19.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependenciesMeta": {
|
|
42
|
+
"dsh-better-sidebar": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
38
46
|
"dsh": {
|
|
39
47
|
"client": {
|
|
40
48
|
"inject": [
|