dsh-form-fill-agent 0.2.23 → 0.2.25

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
@@ -1,21 +1,50 @@
1
1
  # AI填表智能体
2
2
 
3
+ > 0.2.25:侧栏为可选依赖,基础安装无需侧栏;内嵌工作台需匹配宿主版本。
4
+
3
5
  > 统一侧栏适配需要 Better Sidebar `>=0.17.1 <0.19.0`。五个流程入口打开同一 Session Tab;侧栏展开、收起和关闭由宿主管理。缺少依赖时会显示安装升级提示。
4
6
 
5
7
  ## 安装与三分钟上手
6
8
 
7
9
  AI填表智能体:支持自动填表、表格填充、表格补全、Excel填表与 Excel回填;使用企查查 MCP 填写 XLSX 空白字段,预览确认后导出新副本。
8
10
 
9
- 先运行 `dsh --version` 确认宿主版本。当前推荐组合为 **DSH 0.1.2-rc.1 + Better Sidebar 0.18.1**:
11
+ ### 基础安装(不需要侧栏)
12
+
13
+ ```sh
14
+ dsh plugin --profile web add dsh-form-fill-agent@0.2.25
15
+ ```
16
+
17
+ 只需 Node.js >=22、完整 DSH 与主包自动安装的内核/Provider。Better Sidebar 和 dsh-context 都是可选项,不会由基础安装强装。
18
+
19
+ 无侧栏可使用原生会话和独立 `/form-fill/` 页面:上传 XLSX、确认映射、查看预览、确认并导出副本。点击会话中的工作台按钮会显示提示及“打开独立填表页面”链接,保留原生草稿和已保存任务。独立页面无法自动回填原生草稿,需复制指令到对话框发送。企查查查询仍需用户授权的 MCP 和模型;无侧栏不会授予额外权限。
20
+
21
+ ### 可选:启用内嵌工作台
22
+
23
+ 先运行 `dsh --version`,按实际宿主在同一 profile 加装:
10
24
 
11
25
  ```sh
26
+ # DSH 0.1.2-rc.1
12
27
  dsh plugin --profile web add dsh-better-sidebar@0.18.1
13
- dsh plugin --profile web add dsh-form-fill-agent@0.2.23
28
+ # 仅旧 DSH 0.1.1-rc.2 使用 0.17.1
14
29
  ```
15
30
 
16
- 若仍使用 **DSH 0.1.1-rc.2**,请将上述侧栏安装命令改为 `dsh plugin --profile web add dsh-better-sidebar@0.17.1`。该旧宿主加载 0.18.1 会因缺少 `SessionLogOffset` 导出而失败。
31
+ 旧宿主配 0.18.1 会缺少 `SessionLogOffset`,新宿主配 0.17.1 会缺少 `settingsNamespace`。侧栏是可选的,但已经安装的错误组合仍会阻断宿主,必须处理。不建议使用无上限的 `@latest`;可接受范围 `>=0.17.1 <0.19.0` 不等于每个版本均已验证。自定义 profile 请替换 `web`,安装后重启对应 profile。
32
+
33
+ ### 升级前检查与回滚
34
+
35
+ 产品必需项是 Node.js、完整 DSH 及插件自身内核/Provider;工作台侧栏需要上述兼容的 Better Sidebar。**dsh-context 不是必装依赖**。如果已有 context:0.36.0 与新 DSH 的设置接口不兼容,须在升级计划中处理;当前共存验证使用 0.48.0,其他版本提示未验证。
36
+
37
+ 0.2.24 新增只读预检工具,在包安装目录运行:
38
+
39
+ ```sh
40
+ node /path/to/dsh-form-fill-agent/lib/preflight.js --dsh-bin /path/to/dsh --profile-dir /path/to/profiles/web --mode basic
41
+ ```
42
+
43
+ 默认 `--mode basic` 允许缺少侧栏;启用内嵌工作台用 `--mode workbench --sidebar-version 0.18.1`。工作台模式会检查版本,运行时还会检查服务能力。已有不兼容侧栏在两种模式下都阻断。`--sidebar-version` 是计划安装版本;省略则检查该 profile 已安装版本。若计划同时更新已有 context,可加 `--context-version 0.48.0`。预检读取版本元数据,不加载插件树、不读凭据、不安装或重启;已知不兼容退出码为 2,未知组合明确显示未验证。通过只代表版本组合,不代表 MCP 权限、费用或业务结果。
44
+
45
+ 升级前记录 `dsh --version` 和该 profile 的精确依赖版本,停止该 profile 并备份其配置及 form-fill-tasks。由宿主管理者升级完整 DSH,不能仅替换某个 SDK 包;如用 npm 管理全局 DSH,新组合的明确命令为 `npm install -g @deepseek-ai/dsh@0.1.2-rc.1`。随后按上文选择侧栏版本;仅当原本安装 context 时才处理它,例如 `dsh plugin --profile web add dsh-context@0.48.0`。
17
46
 
18
- 不建议侧栏使用无上限的 `@latest`:本插件当前支持 `>=0.17.1 <0.19.0`,未来 latest 可能超出范围或要求更新的 DSH。依赖与主包必须安装在同一 profile;自定义 profile 请替换命令中的 `web`。安装后完整停止并重启对应 profile。
47
+ 先在独立 profile 验证启动、原生会话、合成 XLSX 导入/预览/确认/导出,再重启目标 profile。失败时恢复升级前完整宿主、侧栏及已安装插件版本组合和备份的任务目录,不移动发布标签、不让旧版直接读取已迁移任务目录。本预检不会替你修改全局环境。
19
48
 
20
49
  打开“AI填表”并展开合成演示,选择客户台账模板,检查工作表、企业主体和空白字段。需要真实补全时确认数据来源及范围并手动发送指令;核对单元格预览后下载新 XLSX 副本。
21
50
 
@@ -37,7 +66,7 @@ AI填表是 DeepSeek Harness(DSH)的企业表格填写插件:识别已有
37
66
 
38
67
  ## 安装
39
68
 
40
- 需要 Node.js 22 或以上,以及 DSH。已验证的 DSH 基线为 0.1.1-rc.2 和 0.1.2-alpha.2。
69
+ 需要 Node.js 22 或以上和完整 DSH。当前验证组合为 DSH 0.1.2-rc.1 + Better Sidebar 0.18.1,旧组合为 DSH 0.1.1-rc.2 + Better Sidebar 0.17.1。历史 alpha 测试不作为当前兼容承诺。
41
70
 
42
71
  请先按文首的宿主版本选择并安装 Better Sidebar,再安装主包:
43
72
 
@@ -73,7 +102,7 @@ dsh plugin --profile web add dsh-form-fill-agent@latest
73
102
 
74
103
  ## 使用边界与数据保存
75
104
 
76
- 补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.23,共享内核为 0.2.10,Provider 为 0.2.2,共享字段契约为 0.1.0。
105
+ 补充要求为模型可读文本;字段或工作表范围请通过向导/工作台修改,不能仅改文字后假定执行范围已同步。任务 schema 5 可读取 schema 1–5;回退旧版本请使用升级前目录副本或独立任务目录。主包为 0.2.25,共享内核为 0.2.10,Provider 为 0.2.2,共享字段契约为 0.1.0。
77
106
 
78
107
  支持企业完整登记名称或 18 位信用代码;简称、主体不一致或多候选不会自动猜选。仅有信用代码的表格也可作为查询锚点。连接候选检索工具时可检索简称,仍需人工确认;缺少工具时降级人工输入。字段映射采用确定性规则及人工确认,不让模型编造事实。支持普通内部公式、固定区域下拉、基础条件格式和普通表格对象;复杂 Excel 结构和 Word 暂不支持,保真边界见下方安全说明。
79
108
 
package/lib/client.js CHANGED
@@ -2,7 +2,7 @@ window.__ModuleLoader__.load({
2
2
  id: 'dsh-form-fill-agent',
3
3
  factory(require) {
4
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,重启后重试;原生对话仍可使用。';
5
+ const SIDEBAR_HELP='内嵌工作台暂不可用。原生对话与独立填表页面仍可使用,输入和已保存任务不会清除。启用内嵌工作台需与宿主匹配的 Better Sidebar(>=0.17.1 <0.19.0),请按安装说明选择版本。';
6
6
  // The only adapter allowed to reveal host panels. No geometry or business writes.
7
7
  function createSidebarAdapter(service,component,icon){
8
8
  const version=/^0\.(17|18)\.(\d+)$/.exec(service?.version||'');
@@ -128,7 +128,7 @@ window.__ModuleLoader__.load({
128
128
  if(!owned(sessionId))return null;
129
129
  const content=h('div',{className:'ff-ui','data-ff-theme':theme()},h('nav',{className:'ff-shortcuts','aria-label':'AI填表快捷菜单'},...[
130
130
  ['导入表格','import','upload'],['字段设置','rules','check'],['主体核验','identity','search'],['填写预览','preview','table'],['任务历史','history','history']
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);
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('div',{className:'ff-sidebar-help',role:'alert'},h('p',null,error),h('a',{href:'/form-fill/?session='+encodeURIComponent(sessionId)+(sessionTasks.has(sessionId)?'#task='+sessionTasks.get(sessionId):''),target:'_blank',rel:'noopener noreferrer'},'打开独立填表页面'),h('p',null,'独立页面生成的指令请复制到对话框后发送。')):null);
132
132
  return h('div',{ref,'data-form-fill-session':sessionId},h(Hero,{sessionId}),mount?portal(content,mount):content);
133
133
  }
134
134
  function WorkbenchTab({scope,store,tab,visible}){
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ // Read-only installation planning. Never imports plugins, reads credentials or mutates a profile.
3
+ import {readFile, realpath, mkdtemp, rm, stat} from 'node:fs/promises';
4
+ import {tmpdir} from 'node:os';
5
+ import {join, resolve} from 'node:path';
6
+ import {fileURLToPath} from 'node:url';
7
+ import {execFileSync} from 'node:child_process';
8
+
9
+ export function assessCompatibility({nodeVersion,hostVersion,sidebarVersion,contextVersion,mode='basic'}) {
10
+ if(!['basic','workbench'].includes(mode))throw Error('mode 仅支持 basic 或 workbench');
11
+ const issues=[];
12
+ const add=(severity,code,message)=>issues.push({severity,code,message});
13
+ if(Number(String(nodeVersion).replace(/^v/,'').split('.')[0])<22)add('blocked','NODE_TOO_OLD','AI 填表需要 Node.js >=22;请先更新运行该 DSH 的 Node.js。');
14
+ if(!hostVersion)add('blocked','HOST_UNKNOWN','无法读取实际 DSH 版本;请用 --dsh-bin 指定实际 dsh 可执行文件。');
15
+ if(!sidebarVersion)add(mode==='workbench'?'blocked':'info','SIDEBAR_MISSING','未安装侧栏:基础会话与独立 /form-fill/ 页面可用;内嵌工作台及自动草稿回填需安装与宿主匹配的 Better Sidebar。');
16
+ if(sidebarVersion&&!/^0\.(?:17|18)\.\d+$/.test(sidebarVersion)||sidebarVersion==='0.17.0')add('blocked','SIDEBAR_RANGE','侧栏必须满足 >=0.17.1 <0.19.0;请使用已验证的固定版本,不要直接使用 latest。');
17
+ if(hostVersion==='0.1.1-rc.2'&&/^0\.18\./.test(sidebarVersion||''))add('blocked','HOST_SIDEBAR','旧 DSH 缺少 SessionLogOffset,不能加载该侧栏。保留 dsh-better-sidebar@0.17.1,或由宿主管理者升级完整 DSH 到 0.1.2-rc.1 后安装 0.18.1;不要只升级单个 SDK 包。');
18
+ if(hostVersion==='0.1.2-rc.1'&&sidebarVersion==='0.17.1')add('blocked','SIDEBAR_LEGACY','Better Sidebar 0.17.1 使用旧 settingsNamespace,不能加载到 DSH 0.1.2-rc.1。请在同一 profile 安装 dsh-better-sidebar@0.18.1。');
19
+ if(hostVersion==='0.1.2-rc.1'&&contextVersion==='0.36.0')add('blocked','CONTEXT_LEGACY','已安装 dsh-context@0.36.0 使用旧 settingsNamespace,会阻断新宿主。升级前备份 profile,将已安装的 context 升级到 0.48.0;例如 dsh plugin --profile <名称> add dsh-context@0.48.0。context 不是 AI 填表必装项。');
20
+ if(contextVersion&&!(hostVersion==='0.1.2-rc.1'&&['0.48.0','0.36.0'].includes(contextVersion)))add('warning','CONTEXT_UNVERIFIED','此宿主与 context 组合未纳入当前共存验证;不要据此推断兼容。');
21
+ const known=(!sidebarVersion&&['0.1.1-rc.2','0.1.2-rc.1'].includes(hostVersion))||hostVersion==='0.1.1-rc.2'&&sidebarVersion==='0.17.1'||hostVersion==='0.1.2-rc.1'&&sidebarVersion==='0.18.1';
22
+ if(!known)add('warning','COMBINATION_UNVERIFIED','此宿主与侧栏组合未验证;版本范围可接受不等于已通过业务验收。');
23
+ const blocked=issues.some(i=>i.severity==='blocked');
24
+ return {status:blocked?'blocked':issues.some(i=>i.severity==='warning')?'unverified':'verified-combination',mode,nodeVersion,hostVersion,sidebarVersion:sidebarVersion||null,contextVersion:contextVersion||null,issues,scope:'版本预检;不代表模型、MCP 权限或全部业务验收通过。不会自动安装、升级、重启。'};
25
+ }
26
+
27
+ export async function inspectInstallation({dshBin,profileDir,sidebarVersion,contextVersion,mode='basic'}) {
28
+ if(!(await stat(profileDir)).isDirectory())throw Error('指定 profile 路径不是目录,无法核对已安装插件。');
29
+ const installed=async name=>{try{return JSON.parse(await readFile(join(profileDir,'node_modules',name,'package.json'),'utf8')).version}catch(e){if(e.code==='ENOENT')return undefined;throw e}};
30
+ const installedSidebar=await installed('dsh-better-sidebar'),installedContext=await installed('dsh-context');
31
+ // Run version command with an empty environment profile to avoid activating the actual plugin tree.
32
+ const isolatedHome=await mkdtemp(join(tmpdir(),'form-fill-preflight-'));let raw;
33
+ try{raw=execFileSync(dshBin.endsWith('.js')?process.execPath:dshBin,[...(dshBin.endsWith('.js')?[dshBin]:[]),'--version'],{cwd:isolatedHome,encoding:'utf8',timeout:15000,env:{PATH:process.env.PATH,HOME:isolatedHome,DSH_HOME:isolatedHome,NO_COLOR:'1'}}).trim()}finally{await rm(isolatedHome,{recursive:true,force:true})}
34
+ const hostVersion=raw.match(/\b\d+\.\d+\.\d+(?:-[\w.]+)?\b/)?.[0];
35
+ return {...assessCompatibility({nodeVersion:process.version,hostVersion,sidebarVersion:sidebarVersion||installedSidebar,contextVersion:contextVersion||installedContext,mode}),installed:{sidebar:installedSidebar||null,context:installedContext||null},proposed:{sidebar:sidebarVersion||null,context:contextVersion||null}};
36
+ }
37
+
38
+ if(process.argv[1]&&await realpath(process.argv[1]).catch(()=>resolve(process.argv[1]))===fileURLToPath(import.meta.url)) {
39
+ try {
40
+ const args=process.argv.slice(2),options={};
41
+ if(args.includes('--help')){console.log('form-fill-preflight --dsh-bin /absolute/path/to/dsh --profile-dir /path/to/profiles/web [--mode basic|workbench] [--sidebar-version 0.18.1] [--context-version 0.48.0]\n只读当前版本;可预检计划安装版本。阻断退出码 2,未验证组合会显式提示。');}
42
+ else {
43
+ const keys={'--mode':'mode','--dsh-bin':'dshBin','--profile-dir':'profileDir','--sidebar-version':'sidebarVersion','--context-version':'contextVersion'};
44
+ for(let i=0;i<args.length;i+=2){if(!keys[args[i]]||!args[i+1]||args[i+1].startsWith('--'))throw Error('无效参数;使用 --help 查看用法');options[keys[args[i]]]=args[i+1]}
45
+ if(!options.dshBin||!options.profileDir)throw Error('必须指定 --dsh-bin 和 --profile-dir;不默认读取生产 profile。');
46
+ const result=await inspectInstallation(options);console.log(JSON.stringify(result,null,2));if(result.status==='blocked')process.exitCode=2;
47
+ }
48
+ } catch(error){console.error('预检未完成:'+error.message);process.exitCode=2}
49
+ }
package/lib/ui.html CHANGED
@@ -330,5 +330,6 @@ window.addEventListener('pagehide',saveMappingDraft);
330
330
  for(const event of ['change','click'])$('mapping').addEventListener(event,saveMappingDraft);
331
331
  $('mapping').addEventListener('change',()=>{wizardMappingApplied=false;$('mapping-next').hidden=true;highlightMappingConflicts()});
332
332
  window.addEventListener('hashchange',()=>{if(new URLSearchParams(location.hash.slice(1)).get('task')!==current?.id)restore()});
333
- navigate('import');restore();setInterval(()=>{if(!document.hidden&&current&&!busy&&!$('wizard').open)restore(true)},2000);
333
+ async function restoreSessionTask(){if(location.hash||!sessionId){restore();return}try{const list=await api('/tasks');if(current||location.hash)return;const task=list.filter(item=>item.sessionId===sessionId).sort((a,b)=>(b.updatedAt||b.created)-(a.updatedAt||a.created))[0];if(task){location.hash='task='+task.id;await restore()}}catch(e){$('status').textContent='恢复任务失败,可在任务历史中重试:'+e.message}}
334
+ navigate('import');restoreSessionTask();setInterval(()=>{if(!document.hidden&&current&&!busy&&!$('wizard').open)restore(true)},2000);
334
335
  </script></html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-form-fill-agent",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
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": {
@@ -19,7 +19,8 @@
19
19
  ".": "./lib/index.js",
20
20
  "./http": "./lib/http.js",
21
21
  "./client": "./lib/client.js",
22
- "./package.json": "./package.json"
22
+ "./package.json": "./package.json",
23
+ "./preflight": "./lib/preflight.js"
23
24
  },
24
25
  "files": [
25
26
  "lib",
@@ -71,5 +72,8 @@
71
72
  "spreadsheet-autofill",
72
73
  "xlsx",
73
74
  "enterprise-data"
74
- ]
75
+ ],
76
+ "bin": {
77
+ "form-fill-preflight": "lib/preflight.js"
78
+ }
75
79
  }