@tbox.cn/tboxcode-dsh-runtime 0.1.0-rc.3 → 0.1.0-rc.5

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/lib/index.d.ts CHANGED
@@ -30,8 +30,9 @@ interface ConfigWatchHandle {
30
30
  }
31
31
  /**
32
32
  * 监听 configDir 目录(平铺布局)中对 filenames 集合内文件的变更。
33
- * 目录级监听捕获文件创建 / 修改 / 删除;500ms 稳定窗口去抖(编辑器多写
34
- * 合并为一次回调);回调不携带事件细节——消费方语义是"文件集脏了,重读"。
33
+ * 目录级 fs.watch 捕获文件创建 / 修改 / 删除;stat 轮询兜底覆盖高负载下
34
+ * 事件合并/丢失;500ms 稳定窗口去抖(编辑器多写合并为一次回调);回调不
35
+ * 携带事件细节——消费方语义是"文件集脏了,重读"。
35
36
  * headless 短命形态的空转开销接受(不做形态条件化——S1a 注记)。
36
37
  */
37
38
  declare function watchConfigFiles(configDir: string, filenames: readonly string[], onChange: () => void, stableWindowMs?: number): ConfigWatchHandle;
@@ -84,6 +85,8 @@ declare class ModelMalformedError extends Error {
84
85
  declare const TOOL_SKILL_ROW_ID = "tool-skill";
85
86
  /** tboxcode-webfetch 行 id(本仓 tools 包——同 id 覆盖截断参数)。 */
86
87
  declare const TOOL_WEBFETCH_ROW_ID = "tboxcode-webfetch";
88
+ /** pre-execute 行 id(denyPaths / permission 翻译落点)。 */
89
+ declare const TOOL_PRE_EXECUTE_ROW_ID = "tboxcode-pre-execute";
87
90
  /** patch 行域产物行(overlay 数组元素;config 值经密钥扫描)。 */
88
91
  interface PatchRow {
89
92
  id: string;
@@ -137,4 +140,4 @@ interface OverlayPatch {
137
140
  /** 单文件 overlay,其数组全体即我方行集(识别规则免配置——config-translation-contract overlay 行规则)。 */
138
141
  declare function writeOverlayPatch(rows: PatchRow[]): Promise<OverlayPatch>;
139
142
  //#endregion
140
- export { AGENT_DEFAULT_MODEL_PLUGIN, AGENT_DEFAULT_MODEL_ROW_ID, type ConfigWatchHandle, type LoadedConfig, ModelMalformedError, ModelNotSetError, OVERLAY_ROW_IDS, type OverlayPatch, type PatchRow, SecretInTranslationError, TOOL_SKILL_ROW_ID, TOOL_WEBFETCH_ROW_ID, type Translation, type TranslationWarning, configFilePath, interpolateEnv, loadConfig, resolveConfigDir, resolveConfigPath, rowsToPatchElements, stripJsonc, translateConfig, watchConfigFiles, writeOverlayPatch };
143
+ export { AGENT_DEFAULT_MODEL_PLUGIN, AGENT_DEFAULT_MODEL_ROW_ID, type ConfigWatchHandle, type LoadedConfig, ModelMalformedError, ModelNotSetError, OVERLAY_ROW_IDS, type OverlayPatch, type PatchRow, SecretInTranslationError, TOOL_PRE_EXECUTE_ROW_ID, TOOL_SKILL_ROW_ID, TOOL_WEBFETCH_ROW_ID, type Translation, type TranslationWarning, configFilePath, interpolateEnv, loadConfig, resolveConfigDir, resolveConfigPath, rowsToPatchElements, stripJsonc, translateConfig, watchConfigFiles, writeOverlayPatch };
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{existsSync as e,readFileSync as t,watch as n}from"node:fs";import{homedir as r,tmpdir as i}from"node:os";import{join as a}from"node:path";import{mkdtemp as o,rm as s,writeFile as c}from"node:fs/promises";import{stringify as l}from"yaml";function u(){return process.env.TBOXCODE_DSH_CONFIG_DIR??a(r(),`.config`,`tboxcode-dsh`)}function d(t=u()){for(let n of[`config.jsonc`,`config.json`]){let r=a(t,n);if(e(r))return r}return null}function f(e){let t=``,n=0,r=e.length,i=!1;for(;n<r;){let a=e[n];if(i){if(t+=a,a===`\\`){n+1<r&&(t+=e[n+1]),n+=2;continue}a===`"`&&(i=!1),n++;continue}if(a===`"`){i=!0,t+=a,n++;continue}if(a===`/`&&e[n+1]===`/`){for(;n<r&&e[n]!==`
2
- `;)n++;continue}if(a===`/`&&e[n+1]===`*`){for(n+=2;n<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2;continue}t+=a,n++}return t.replace(/,(\s*[}\]])/g,`$1`)}function p(e,t=new WeakSet){if(typeof e==`string`)return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(e,t)=>{let n=process.env[t];return n===void 0?e:n});if(Array.isArray(e))return e.map(e=>p(e,t));if(typeof e==`object`&&e){let n=e;if(t.has(n))return e;t.add(n);let r={};for(let[e,i]of Object.entries(n))r[e]=p(i,t);return t.delete(n),r}return e}function m(e=u()){let n=d(e);if(n===null)return{path:null,config:{}};let r=t(n,`utf-8`);try{let e=JSON.parse(f(r));if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`config 顶层必须是对象`);return{path:n,config:p(e)}}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`config 解析失败(${n}):${t}`)}}function h(e,t,r,i=500){let a=new Set(t),o,s=!1,c=()=>{o!==void 0&&clearTimeout(o),o=setTimeout(()=>{s||r()},i)},l;try{l=n(e,{persistent:!1},(e,t)=>{t!==null&&!a.has(t)||c()})}catch{return{dispose:()=>{s=!0}}}return l.on(`error`,()=>{}),{dispose:()=>{s=!0,o!==void 0&&clearTimeout(o),l.close()}}}function g(e,t){return a(e,t)}const _=`agent-default-model`,v=`@deepseek-ai/dsh-agent-default-model`;var y=class extends Error{code=`MODEL_NOT_SET`;constructor(e,t){let n=t?e:`${e}(配置文件尚不存在)`;super(`tboxcode: config 未设置 model——spawn 拒绝(fail fast,跨形态一致)。base 默认行指向 deepseek-official 专有 provider,本栈禁用该行族,静默回落即首请求失败(决策:default-model-row-mapping 未设明错)。请在 ${n} 的 config.jsonc 设置 model: "<provider>/<model>",或运行 tboxcode-dsh init --config 生成配置骨架。`),this.name=`ModelNotSetError`}},b=class extends Error{code=`MODEL_MALFORMED`;constructor(e){super(`tboxcode: config model 形态非法(${JSON.stringify(e)})——须为 "<provider>/<model>" 两段式`),this.name=`ModelMalformedError`}};const x=`tool-skill`,S=`tboxcode-webfetch`;var C=class extends Error{code=`SECRET_IN_TRANSLATION`;constructor(e){super(`tboxcode: 翻译输出疑似密钥材料(${e})——翻译输出永不含密钥(契约密钥铁律)。凭据三来源:auth.jsonc / provider.options.apiKey 值内 \${VAR} / reload 旁路;若 \${VAR} 引用的 env 值本身是密钥,请改走 auth.jsonc(0600)。`),this.name=`SecretInTranslationError`}};const w=[/api[_-]?key/i,/secret/i,/password/i,/authorization/i,/private[_-]?key/i],T=[/\bsk-[A-Za-z0-9]{16,}/,/\bAKIA[A-Z0-9]{16}\b/,/Bearer\s+[A-Za-z0-9._-]{24,}/];function E(e,t,n=new WeakSet){if(typeof e==`string`){for(let n of T)if(n.test(e))throw new C(`${t}: 值命中密钥模式 ${n.source}`);return}if(Array.isArray(e)){for(let r of e)E(r,t,n);return}if(typeof e==`object`&&e){if(n.has(e))return;n.add(e);for(let[r,i]of Object.entries(e)){if(w.some(e=>e.test(r))&&typeof i==`string`&&i.length>0)throw new C(`${t}: 键 ${r} 携带疑似凭据面(凭据归 auth.jsonc / \${VAR} 值引用)`);E(i,`${t}.${r}`,n)}}}function D(e,t){if(typeof e!=`string`)throw new b(`${t}=${JSON.stringify(e)}`.slice(0,120));let n=e.indexOf(`/`),r=n>0?e.slice(0,n):``,i=n>0?e.slice(n+1):``;if(r.length===0||i.length===0)throw new b(`${t}=${JSON.stringify(e)}`.slice(0,120));return{provider:r,model:i}}function O(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:void 0}function k(e,t,n){let r=e.model;if(r==null||r===``)throw new y(t,n);let i=D(r,`model`),a=[],o=[];a.push({id:_,name:v,config:{provider:i.provider,model:i.model}});let s=e.tools?.output;if(s!==void 0&&typeof s==`object`){let e=O(s.max_lines),t=O(s.max_bytes);if(e===void 0&&s.max_lines!==void 0&&o.push({field:`tools.output.max_lines`,reason:`非正整数——跳过`}),t===void 0&&s.max_bytes!==void 0&&o.push({field:`tools.output.max_bytes`,reason:`非正整数——跳过`}),e!==void 0||t!==void 0){let n={};e!==void 0&&(n.maxLines=e),t!==void 0&&(n.maxBytes=t),a.push({id:S,name:`@tbox.cn/tboxcode-dsh-tools/webfetch`,config:n})}}a.push({id:x,name:`@deepseek-ai/dsh-tool-skill`,config:{catalogDescriptionMaxLength:1024}}),e.bash!==void 0&&o.push({field:`bash`,reason:`dsh tool-bash Config 无超时面(enableRunInBackground/promoteOnTimeout),shell spec timeoutMs 是调用面非行 config——无等价翻译面,跳过`}),e.watchdog!==void 0&&o.push({field:`watchdog`,reason:`dsh timeout-policy 零 Config(声明制 timeoutMs 归工具定义硬编码)——turn 级 idle 超时无对位,跳过(近似对位非同构的落点修正)`}),e.compaction!==void 0&&o.push({field:`compaction`,reason:`dsh compaction-basic 是字符阈值制(thresholdChars),基线是上下文比例制(threshold ≤1)——语义异构不硬译,跳过`}),e.subagent!==void 0&&o.push({field:`subagent.max_parallel`,reason:`dsh 无 per-tool 并发上限可翻译(契约既定 warn + skip)`}),e.small_model!==void 0&&o.push({field:`small_model`,reason:`键已退役(subagent-native-adoption——0.2.1 原生采纳,委派模型路由归 modelSelectionSettings/agent_preset),值被忽略`}),e.agents!==void 0&&o.push({field:`agents`,reason:`键已退役(subagent-native-adoption——0.2.1 类型面弃用,委派全链原生单实例),值被忽略`});let c={};for(let t of[`provider`,`enabled_providers`,`disabled_providers`,`effort`,`effort_templates`,`trait_presets`,`llm_log`,`retention`,`system_prompt`,`rules`,`skills`,`permission`,`title`,`interaction`,`env`])e[t]!==void 0&&(c[t]=e[t]);return E(a,`rows`),{rows:a,passthrough:c,warnings:o}}const A=new Set([`agent-default-model`,`tool-skill`,`tboxcode-webfetch`]);function j(e){let t=e.filter(e=>A.has(e.id)),n=e.filter(e=>!A.has(e.id)),r=t.map(e=>({...e}));return n.length>0&&r.push({insert:n.map(e=>({...e}))}),r}async function M(e){let t=await o(a(i(),`tboxcode-overlay-`)),n=a(t,`tboxcode-overlay.yml`);return await c(n,l(j(e),{lineWidth:0}),`utf-8`),{path:n,dispose:async()=>{await s(t,{recursive:!0,force:!0})}}}export{v as AGENT_DEFAULT_MODEL_PLUGIN,_ as AGENT_DEFAULT_MODEL_ROW_ID,b as ModelMalformedError,y as ModelNotSetError,A as OVERLAY_ROW_IDS,C as SecretInTranslationError,x as TOOL_SKILL_ROW_ID,S as TOOL_WEBFETCH_ROW_ID,g as configFilePath,p as interpolateEnv,m as loadConfig,u as resolveConfigDir,d as resolveConfigPath,j as rowsToPatchElements,f as stripJsonc,k as translateConfig,h as watchConfigFiles,M as writeOverlayPatch};
1
+ import{existsSync as e,readFileSync as t,statSync as n,watch as r}from"node:fs";import{homedir as i,tmpdir as a}from"node:os";import{join as o}from"node:path";import{mkdtemp as s,rm as c,writeFile as l}from"node:fs/promises";import{stringify as u}from"yaml";function d(){return process.env.TBOXCODE_DSH_CONFIG_DIR??o(i(),`.config`,`tboxcode-dsh`)}function f(t=d()){for(let n of[`config.jsonc`,`config.json`]){let r=o(t,n);if(e(r))return r}return null}function p(e){let t=``,n=0,r=e.length,i=!1;for(;n<r;){let a=e[n];if(i){if(t+=a,a===`\\`){n+1<r&&(t+=e[n+1]),n+=2;continue}a===`"`&&(i=!1),n++;continue}if(a===`"`){i=!0,t+=a,n++;continue}if(a===`/`&&e[n+1]===`/`){for(;n<r&&e[n]!==`
2
+ `;)n++;continue}if(a===`/`&&e[n+1]===`*`){for(n+=2;n<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2;continue}t+=a,n++}return t.replace(/,(\s*[}\]])/g,`$1`)}function m(e,t=new WeakSet){if(typeof e==`string`)return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(e,t)=>{let n=process.env[t];return n===void 0?e:n});if(Array.isArray(e))return e.map(e=>m(e,t));if(typeof e==`object`&&e){let n=e;if(t.has(n))return e;t.add(n);let r={};for(let[e,i]of Object.entries(n))r[e]=m(i,t);return t.delete(n),r}return e}function h(e=d()){let n=f(e);if(n===null)return{path:null,config:{}};let r=t(n,`utf-8`);try{let e=JSON.parse(p(r));if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`config 顶层必须是对象`);return{path:n,config:m(e)}}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`config 解析失败(${n}):${t}`)}}function g(e,t,i,a=500){let s=new Set(t),c,l=!1,u=()=>{c!==void 0&&clearTimeout(c),c=setTimeout(()=>{l||i()},a)},d=()=>{let t=[];for(let r of s)try{let i=n(o(e,r));t.push(`${r}:${i.mtimeMs}:${i.size}:${i.ino}`)}catch{t.push(`${r}:-`)}return t.join(`|`)},f=d(),p=setInterval(()=>{if(l)return;let e=d();e!==f&&(f=e,u())},1e3);p.unref?.();let m;try{m=r(e,{persistent:!1},(e,t)=>{t!==null&&!s.has(t)||u()})}catch{return clearInterval(p),{dispose:()=>{l=!0,clearInterval(p)}}}return m.on(`error`,()=>{}),{dispose:()=>{l=!0,clearInterval(p),c!==void 0&&clearTimeout(c),m.close()}}}function _(e,t){return o(e,t)}const v=`agent-default-model`,y=`@deepseek-ai/dsh-agent-default-model`;var b=class extends Error{code=`MODEL_NOT_SET`;constructor(e,t){let n=t?e:`${e}(配置文件尚不存在)`;super(`tboxcode: config 未设置 model——spawn 拒绝(fail fast,跨形态一致)。base 默认行指向 deepseek-official 专有 provider,本栈禁用该行族,静默回落即首请求失败(决策:default-model-row-mapping 未设明错)。请在 ${n} 的 config.jsonc 设置 model: "<provider>/<model>",或运行 tboxcode-dsh init --config 生成配置骨架。`),this.name=`ModelNotSetError`}},x=class extends Error{code=`MODEL_MALFORMED`;constructor(e){super(`tboxcode: config model 形态非法(${JSON.stringify(e)})——须为 "<provider>/<model>" 两段式`),this.name=`ModelMalformedError`}};const S=`tool-skill`,C=`tboxcode-webfetch`,w=`tboxcode-pre-execute`;var T=class extends Error{code=`SECRET_IN_TRANSLATION`;constructor(e){super(`tboxcode: 翻译输出疑似密钥材料(${e})——翻译输出永不含密钥(契约密钥铁律)。凭据三来源:auth.jsonc / provider.options.apiKey 值内 \${VAR} / reload 旁路;若 \${VAR} 引用的 env 值本身是密钥,请改走 auth.jsonc(0600)。`),this.name=`SecretInTranslationError`}};const E=[/api[_-]?key/i,/secret/i,/password/i,/authorization/i,/private[_-]?key/i],D=[/\bsk-[A-Za-z0-9]{16,}/,/\bAKIA[A-Z0-9]{16}\b/,/Bearer\s+[A-Za-z0-9._-]{24,}/];function O(e,t,n=new WeakSet){if(typeof e==`string`){for(let n of D)if(n.test(e))throw new T(`${t}: 值命中密钥模式 ${n.source}`);return}if(Array.isArray(e)){for(let r of e)O(r,t,n);return}if(typeof e==`object`&&e){if(n.has(e))return;n.add(e);for(let[r,i]of Object.entries(e)){if(E.some(e=>e.test(r))&&typeof i==`string`&&i.length>0)throw new T(`${t}: 键 ${r} 携带疑似凭据面(凭据归 auth.jsonc / \${VAR} 值引用)`);O(i,`${t}.${r}`,n)}}}function k(e,t){if(typeof e!=`string`)throw new x(`${t}=${JSON.stringify(e)}`.slice(0,120));let n=e.indexOf(`/`),r=n>0?e.slice(0,n):``,i=n>0?e.slice(n+1):``;if(r.length===0||i.length===0)throw new x(`${t}=${JSON.stringify(e)}`.slice(0,120));return{provider:r,model:i}}function A(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:void 0}function j(e,t,n){let r=e.model;if(r==null||r===``)throw new b(t,n);let i=k(r,`model`),a=[],o=[];a.push({id:v,name:y,config:{provider:i.provider,model:i.model}});let s=e.tools?.output;if(s!==void 0&&typeof s==`object`){let e=A(s.max_lines),t=A(s.max_bytes);if(e===void 0&&s.max_lines!==void 0&&o.push({field:`tools.output.max_lines`,reason:`非正整数——跳过`}),t===void 0&&s.max_bytes!==void 0&&o.push({field:`tools.output.max_bytes`,reason:`非正整数——跳过`}),e!==void 0||t!==void 0){let n={};e!==void 0&&(n.maxLines=e),t!==void 0&&(n.maxBytes=t),a.push({id:C,name:`@tbox.cn/tboxcode-dsh-tools/webfetch`,config:n})}}let c=e.permission,l=e.security,u=l?.denyPaths??e.denyPaths,d=Array.isArray(u)?u.filter(e=>typeof e==`string`&&e.trim().length>0):void 0,f=l?.mcpDenyPatterns??e.mcpDenyPatterns,p=Array.isArray(f)?f.filter(e=>typeof e==`string`&&e.length>0):void 0;(c!==void 0||d!==void 0||p!==void 0)&&a.push({id:w,name:`@tbox.cn/tboxcode-dsh-tools/pre-execute`,config:{...c===void 0?{}:{permission:c},...d===void 0?{}:{denyPaths:d},...p===void 0?{}:{mcpDenyPatterns:p}}}),a.push({id:S,name:`@deepseek-ai/dsh-tool-skill`,config:{catalogDescriptionMaxLength:1024}}),e.bash!==void 0&&o.push({field:`bash`,reason:`dsh tool-bash Config 无超时面(enableRunInBackground/promoteOnTimeout),shell spec timeoutMs 是调用面非行 config——无等价翻译面,跳过`}),e.watchdog!==void 0&&o.push({field:`watchdog`,reason:`dsh timeout-policy 零 Config(声明制 timeoutMs 归工具定义硬编码)——turn 级 idle 超时无对位,跳过(近似对位非同构的落点修正)`}),e.compaction!==void 0&&o.push({field:`compaction`,reason:`dsh compaction-basic 是字符阈值制(thresholdChars),基线是上下文比例制(threshold ≤1)——语义异构不硬译,跳过`}),e.subagent!==void 0&&o.push({field:`subagent.max_parallel`,reason:`dsh 无 per-tool 并发上限可翻译(契约既定 warn + skip)`}),e.small_model!==void 0&&o.push({field:`small_model`,reason:`键已退役(subagent-native-adoption——0.2.1 原生采纳,委派模型路由归 modelSelectionSettings/agent_preset),值被忽略`}),e.agents!==void 0&&o.push({field:`agents`,reason:`键已退役(subagent-native-adoption——0.2.1 类型面弃用,委派全链原生单实例),值被忽略`});let m={};for(let t of[`workspace`,`media_policy`,`auto_commit`,`security`,`attachments`,`provider`,`enabled_providers`,`disabled_providers`,`effort`,`effort_templates`,`trait_presets`,`llm_log`,`retention`,`system_prompt`,`rules`,`skills`,`permission`,`title`,`interaction`,`env`])e[t]!==void 0&&(m[t]=e[t]);return O(a,`rows`),{rows:a,passthrough:m,warnings:o}}const M=new Set([`agent-default-model`,`tool-skill`,`tboxcode-webfetch`]);function N(e){let t=e.filter(e=>M.has(e.id)),n=e.filter(e=>!M.has(e.id)),r=t.map(e=>({...e}));return n.length>0&&r.push({insert:n.map(e=>({...e}))}),r}async function P(e){let t=await s(o(a(),`tboxcode-overlay-`)),n=o(t,`tboxcode-overlay.yml`);return await l(n,u(N(e),{lineWidth:0}),`utf-8`),{path:n,dispose:async()=>{await c(t,{recursive:!0,force:!0})}}}export{y as AGENT_DEFAULT_MODEL_PLUGIN,v as AGENT_DEFAULT_MODEL_ROW_ID,x as ModelMalformedError,b as ModelNotSetError,M as OVERLAY_ROW_IDS,T as SecretInTranslationError,w as TOOL_PRE_EXECUTE_ROW_ID,S as TOOL_SKILL_ROW_ID,C as TOOL_WEBFETCH_ROW_ID,_ as configFilePath,m as interpolateEnv,h as loadConfig,d as resolveConfigDir,f as resolveConfigPath,N as rowsToPatchElements,p as stripJsonc,j as translateConfig,g as watchConfigFiles,P as writeOverlayPatch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/tboxcode-dsh-runtime",
3
- "version": "0.1.0-rc.3",
3
+ "version": "0.1.0-rc.5",
4
4
  "type": "module",
5
5
  "description": "config 翻译器(密钥铁律)+ stdout 双档守卫 + requestedSchema 构造器",
6
6
  "main": "lib/index.js",