dsh-form-fill-agent 0.2.1 → 0.2.2

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 CHANGED
@@ -43,7 +43,7 @@ dsh plugin --profile web add dsh-form-fill-agent@latest
43
43
 
44
44
  ## 使用边界与数据保存
45
45
 
46
- 补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.1,共享内核和 Provider 保持 0.2.0。
46
+ 补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.2,共享内核和 Provider 保持 0.2.0。
47
47
 
48
48
  支持企业完整登记名称或 18 位信用代码;简称、主体不一致或多候选不会自动猜选。仅有信用代码的表格也可作为查询锚点。连接候选检索工具时可检索简称,仍需人工确认;缺少工具时降级人工输入。字段映射采用确定性规则及人工确认,不让模型编造事实。支持普通内部公式、固定区域下拉、基础条件格式和普通表格对象;复杂 Excel 结构和 Word 暂不支持,保真边界见下方安全说明。
49
49
 
@@ -51,7 +51,7 @@ dsh plugin --profile web add dsh-form-fill-agent@latest
51
51
 
52
52
  显式设置 DSH_HOME 时,任务保存至其 form-fill-tasks 目录,默认 24 小时过期;未设置时使用内存。任务保存输入表格和归一化预览,不持久化原始 MCP 响应,可主动删除任务。模型及 MCP 凭据由宿主管理。
53
53
 
54
- 0.2.1 保存任务 schema 5,兼容读取旧 schema 1–4;回退旧版本须使用升级前任务目录副本或新目录,防止丢失已确认的字段/主体设置。
54
+ 0.2.2 保存任务 schema 5,兼容读取旧 schema 1–4;回退旧版本须使用升级前任务目录副本或新目录,防止丢失已确认的字段/主体设置。
55
55
 
56
56
  ## 文档与反馈
57
57
 
package/lib/brand.css CHANGED
@@ -7,7 +7,13 @@
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
- @media(min-width:1100px){[data-form-fill-reserve=true]{padding-right:var(--ff-panel-inset)!important}}
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
+ @container(max-width:480px){.ff-ui .ff-panel-head{flex-wrap:wrap;padding:10px}.ff-ui .ff-panel-actions{margin-left:auto}.ff-ui .ff-panel-head h2{font-size:14px}}
11
17
  .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}
12
18
  .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)}
13
19
  .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}
package/lib/client.js CHANGED
@@ -99,13 +99,36 @@ window.__ModuleLoader__.load({
99
99
  return h('div',{ref,'data-form-fill-session':sessionId},h(Hero,{sessionId}),mount?portal(content,mount):content);
100
100
  }
101
101
  function Panel(){
102
- const [view,setView]=React.useState(null),frame=React.useRef(null),[active,setActive]=React.useState(current()),[wide,setWide]=React.useState(innerWidth>=1100),[expanded,setExpanded]=React.useState(false),[modal,setModal]=React.useState(false);
102
+ const [view,setView]=React.useState(null),frame=React.useRef(null),[active,setActive]=React.useState(current()),[available,setAvailable]=React.useState(innerWidth),[expanded,setExpanded]=React.useState(false),[modal,setModal]=React.useState(false);
103
+ const [preferred,setPreferred]=React.useState(null),[dragging,setDragging]=React.useState(false),drag=React.useRef(null);
104
+ const wide=available>=740&&innerWidth>760,maxWidth=Math.max(320,available-420);
105
+ const clamp=value=>Math.round(Math.max(320,Math.min(maxWidth,value)));
106
+ const panelWidth=clamp(expanded?maxWidth:preferred??Math.min(640,available*.48));
107
+ const finishDrag=(cancel=false)=>{
108
+ const prior=drag.current;if(!prior)return;drag.current=null;setDragging(false);
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
+ };
103
118
  React.useEffect(()=>{
104
119
  const sync=()=>{const value=theme();document.querySelectorAll('.ff-ui').forEach(n=>n.dataset.ffTheme=value);frame.current?.contentWindow?.postMessage({type:'ff-theme',theme:value},location.origin)};
105
120
  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();
106
121
  return()=>{observer.disconnect();media.removeEventListener('change',sync)};
107
122
  },[]);
108
- React.useEffect(()=>{const resize=()=>setWide(innerWidth>=1100);window.addEventListener('resize',resize);return()=>window.removeEventListener('resize',resize)},[]);
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]);
109
132
  React.useEffect(()=>{panel=setView;const timer=setInterval(()=>setActive(current()),200);return()=>{panel=null;clearInterval(timer)}},[]);
110
133
  React.useEffect(()=>{if(view&&current()!==view.id)setView(null);setModal(false)},[active,view?.id]);
111
134
  React.useEffect(()=>{frame.current?.contentWindow?.postMessage({type:'ff-navigate',step:view?.step},location.origin)},[view]);
@@ -140,7 +163,7 @@ window.__ModuleLoader__.load({
140
163
  window.addEventListener('message',receive);return()=>window.removeEventListener('message',receive);
141
164
  },[view?.id]);
142
165
  React.useEffect(()=>{
143
- if(!view||active!==view.id)return;
166
+ if(!view||active!==view.id||!wide||modal)return;
144
167
  const touched=new Map();
145
168
  const adjust=()=>{
146
169
  if(current()!==view.id)return;
@@ -150,13 +173,19 @@ window.__ModuleLoader__.load({
150
173
  if(!container)return;
151
174
  if(!touched.has(container))touched.set(container,container.style.getPropertyValue('--ff-panel-inset'));
152
175
  container.setAttribute('data-form-fill-reserve','true');
153
- container.style.setProperty('--ff-panel-inset',expanded?'calc(min(58vw, 860px) + 1px)':'calc(min(48vw, 640px) + 1px)');
176
+ container.style.setProperty('--ff-panel-inset',panelWidth+'px');
154
177
  };
155
178
  adjust();const observer=new MutationObserver(adjust);observer.observe(document.body,{childList:true,subtree:true});
156
179
  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')}};
157
- },[view?.id,expanded,active]);
180
+ },[view?.id,panelWidth,active,wide,modal]);
158
181
  if(!view||active!==view.id)return null;
159
- return portal(h('section',{className:'ff-ui ff-panel','data-ff-theme':theme(),'aria-label':'AI填表工作台',style:{width:modal?'100%':wide?(expanded?'min(58vw, 860px)':'min(48vw, 640px)'):'100%',...(modal?{background:'transparent',border:0}:{})}},
182
+ 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}:{})}},
183
+ 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,
184
+ onDoubleClick:()=>{finishDrag(true);setPreferred(null);setExpanded(false)},
185
+ 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)},
186
+ onPointerMove:event=>{const prior=drag.current;if(prior?.id!==event.pointerId)return;setPreferred(clamp(prior.width+prior.x-event.clientX));setExpanded(false)},
187
+ onPointerUp:()=>finishDrag(),onPointerCancel:()=>finishDrag(true),onLostPointerCapture:()=>finishDrag(true)
188
+ }):null,
160
189
  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)},'关闭工作台'))),
161
190
  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);
162
191
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-form-fill-agent",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "description": "AI填表智能体:XLSX blank-cell preview, QCC enrichment and persistent tasks for DSH.",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/duhu2000/dsh-form-fill-agent.git", "directory": "packages/dsh-form-fill-agent" },