grix-connector 3.28.0 → 3.29.0

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.
Files changed (37) hide show
  1. package/dist/adapter/acp/acp-adapter.js +8 -8
  2. package/dist/adapter/acp/session-activity.js +1 -1
  3. package/dist/adapter/claude/claude-bridge-server.js +1 -1
  4. package/dist/adapter/claude/claude-tools.js +1 -1
  5. package/dist/adapter/claude/claude-worker-client.js +1 -1
  6. package/dist/adapter/claude/mcp-http-launcher.js +2 -2
  7. package/dist/adapter/claude/result-timeout.js +1 -1
  8. package/dist/adapter/codex/codex-bridge.js +8 -8
  9. package/dist/adapter/deepseek-harness/dsh-provider-config.js +5 -5
  10. package/dist/adapter/deepseek-harness/event-mapper.js +1 -1
  11. package/dist/adapter/deepseek-harness/grix-tool-bridge.js +1 -0
  12. package/dist/adapter/deepseek-harness/index.js +1 -1
  13. package/dist/adapter/deepseek-harness/jsonrpc-adapter.js +2 -2
  14. package/dist/adapter/deepseek-harness/plugin-manager.js +1 -2
  15. package/dist/adapter/deepseek-harness/profile-resolver.js +1 -1
  16. package/dist/adapter/deepseek-harness/profile-runtime.js +3 -3
  17. package/dist/adapter/deepseek-harness/session-plugin-overlay.js +4 -0
  18. package/dist/assets/dsh-bridge/grix-dsh-bridge-3.29.0.tgz +0 -0
  19. package/dist/assets/dsh-bridge/manifest.json +6 -6
  20. package/dist/audit/adapters/codex/codex-audit-adapter.js +1 -1
  21. package/dist/audit/adapters/deepseek-harness/deepseek-harness-audit-adapter.js +2 -2
  22. package/dist/bridge/bridge.js +7 -7
  23. package/dist/core/access/allowlist-store.js +1 -1
  24. package/dist/core/file-ops/list-files.js +1 -1
  25. package/dist/core/persistence/session-binding-store.js +2 -2
  26. package/dist/core/util/codex-output-policy.js +1 -1
  27. package/dist/log.js +2 -2
  28. package/dist/mcp/stream-http/config.js +1 -1
  29. package/dist/mcp/stream-http/connection-binding.js +1 -1
  30. package/dist/mcp/stream-http/security.js +1 -1
  31. package/dist/mcp/stream-http/tool-executor.js +1 -1
  32. package/dist/mcp/stream-http/tool-registry.js +1 -1
  33. package/dist/mcp/stream-http/tool-schemas.js +1 -1
  34. package/dist/protocol/acp-client.js +1 -1
  35. package/openclaw-plugin/index.js +3 -1
  36. package/package.json +2 -1
  37. package/dist/assets/dsh-bridge/grix-dsh-bridge-3.28.0.tgz +0 -0
@@ -1 +1 @@
1
- import{readJSONFile as o,writeJSONFileAtomic as e}from"../util/json-file.js";function n(t){const r=o(t);return r&&typeof r=="object"&&"owners"in r&&Array.isArray(r.owners)?r.owners.filter(i=>typeof i=="string"&&i.trim().length>0):[]}async function s(t,r){await e(t,{owners:r})}export{n as readAllowlist,s as writeAllowlist};
1
+ import{readJSONFile as o,writeJSONFileAtomic as i}from"../util/json-file.js";function n(t){const r=o(t);return r&&typeof r=="object"&&"owners"in r&&Array.isArray(r.owners)?r.owners.filter(e=>typeof e=="string"&&e.trim().length>0):[]}async function s(t,r){await i(t,{owners:r})}export{n as readAllowlist,s as writeAllowlist};
@@ -1 +1 @@
1
- import{readdir as r,stat as m}from"node:fs/promises";import{join as l,extname as d}from"node:path";const x={pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",txt:"text/plain",md:"text/markdown",csv:"text/csv",json:"application/json",xml:"application/xml",yaml:"text/yaml",yml:"text/yaml",html:"text/html",css:"text/css",js:"text/javascript",ts:"text/typescript",zip:"application/zip",rar:"application/x-rar-compressed","7z":"application/x-7z-compressed",tar:"application/x-tar",gz:"application/gzip",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",mp4:"video/mp4",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",webm:"video/webm",mp3:"audio/mpeg",wav:"audio/wav",flac:"audio/flac",aac:"audio/aac"};function n(a){const p=d(a).slice(1).toLowerCase();return x[p]}async function f(a,p=!1){const c=await r(a,{withFileTypes:!0}),s=[];for(const t of c){if(!p&&t.name.startsWith("."))continue;const i=l(a,t.name),e={id:i,name:t.name,is_directory:t.isDirectory()};try{if(t.isDirectory()){const o=await m(i);e.modified_at=o.mtime.toISOString()}else{const o=await m(i);e.size=o.size,e.modified_at=o.mtime.toISOString(),e.mime_type=n(t.name)}}catch{}s.push(e)}return s.sort((t,i)=>t.is_directory!==i.is_directory?t.is_directory?-1:1:t.name.localeCompare(i.name)),s}export{f as listFiles,n as resolveMimeType};
1
+ import{readdir as r,stat as m}from"node:fs/promises";import{join as l,extname as d}from"node:path";const x={pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",txt:"text/plain",md:"text/markdown",csv:"text/csv",json:"application/json",xml:"application/xml",yaml:"text/yaml",yml:"text/yaml",html:"text/html",css:"text/css",js:"text/javascript",ts:"text/typescript",zip:"application/zip",rar:"application/x-rar-compressed","7z":"application/x-7z-compressed",tar:"application/x-tar",gz:"application/gzip",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",mp4:"video/mp4",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",webm:"video/webm",mp3:"audio/mpeg",wav:"audio/wav",flac:"audio/flac",aac:"audio/aac"};function n(a){const p=d(a).slice(1).toLowerCase();return x[p]}async function f(a,p=!1){const c=await r(a,{withFileTypes:!0}),s=[];for(const i of c){if(!p&&i.name.startsWith("."))continue;const t=l(a,i.name),e={id:t,name:i.name,is_directory:i.isDirectory()};try{if(i.isDirectory()){const o=await m(t);e.modified_at=o.mtime.toISOString()}else{const o=await m(t);e.size=o.size,e.modified_at=o.mtime.toISOString(),e.mime_type=n(i.name)}}catch{}s.push(e)}return s.sort((i,t)=>i.is_directory!==t.is_directory?i.is_directory?-1:1:i.name.localeCompare(t.name)),s}export{f as listFiles,n as resolveMimeType};
@@ -1,2 +1,2 @@
1
- import{readJSONFile as I,writeJSONFileAtomic as m}from"../util/json-file.js";import{log as o}from"../log/index.js";import{SESSION_MODE_IDS as l}from"../../adapter/claude/protocol-contract.js";import{normalizeClaudeEffort as a}from"../config/claude-direct-env.js";import{chmodSync as x,copyFileSync as p,existsSync as h,renameSync as S,rmSync as M,writeFileSync as b}from"node:fs";import{randomUUID as y}from"node:crypto";const P=l.fullAuto;function n(g){const e=String(g??"").trim().toLowerCase();return e===l.approval||e===l.fullAuto?e:P}class E{bindings=new Map;filePath;legacyFilePath;writePromise=Promise.resolve();constructor(e,t){this.filePath=e??null,this.legacyFilePath=t&&t!==e?t:null}load(){if(!this.filePath)return;const e=h(this.filePath);let t=I(this.filePath),i=!1;if(e&&!Array.isArray(t)){const d=this.quarantineUnreadablePrimary();throw new Error(`Refusing to start with unreadable session bindings: primary=${this.filePath}`+(d?` quarantined=${d}`:"")+(this.legacyFilePath?` legacy=${this.legacyFilePath}`:"")+" (legacy fallback disabled to avoid clobbering newer bindings)")}if(!e&&this.legacyFilePath){i=h(this.legacyFilePath);const d=I(this.legacyFilePath);Array.isArray(d)&&(this.writeMigratedSnapshot(d),t=d,o.info("session-binding-store",`Migrated legacy bindings from ${this.legacyFilePath} to ${this.filePath}; legacy file retained`))}if(!Array.isArray(t)){if(e||i)throw new Error(`Refusing to start with unreadable session bindings: primary=${this.filePath}${this.legacyFilePath?` legacy=${this.legacyFilePath}`:""}`);return}this.bindings.clear();for(const d of t)d.aibotSessionId&&this.bindings.set(d.aibotSessionId,{...d,modeId:n(d.modeId),effort:a(d.effort),dshProviderId:typeof d.dshProviderId=="string"&&d.dshProviderId.trim()?d.dshProviderId.trim():void 0,dshModelId:typeof d.dshModelId=="string"&&d.dshModelId.trim()?d.dshModelId.trim():void 0,dshModeId:d.dshModeId===void 0?void 0:d.dshModeId==="full_auto"?"full_auto":"approval",dshMaxTokens:Number.isSafeInteger(d.dshMaxTokens)&&Number(d.dshMaxTokens)>0?Number(d.dshMaxTokens):void 0,dshAgentPreset:typeof d.dshAgentPreset=="string"&&d.dshAgentPreset.trim()?d.dshAgentPreset.trim():void 0,dshSettingsRevision:d.dshSettingsRevision===void 0?void 0:Number.isSafeInteger(d.dshSettingsRevision)&&Number(d.dshSettingsRevision)>=0?Number(d.dshSettingsRevision):0,dshProfileName:typeof d.dshProfileName=="string"&&d.dshProfileName.trim()?d.dshProfileName.trim():void 0,dshProfileSessionId:typeof d.dshProfileSessionId=="string"&&d.dshProfileSessionId.trim()?d.dshProfileSessionId.trim():void 0,dshProfileSessionCreated:d.dshProfileSessionCreated===!0,dshProfileEventCursor:Number.isSafeInteger(d.dshProfileEventCursor)&&Number(d.dshProfileEventCursor)>=0?Number(d.dshProfileEventCursor):0})}set(e,t,i){const d=this.bindings.get(e),s=n(i?.modeId??d?.modeId),r=t!==void 0?t:d?.cwd;this.bindings.set(e,{aibotSessionId:e,cwd:r,acpSessionId:d?.acpSessionId,claudeSessionId:d?.claudeSessionId,codexThreadId:d?.codexThreadId,codexModelId:d?.codexModelId,codexModeId:d?.codexModeId,codewhaleThreadId:d?.codewhaleThreadId,agyConversationId:d?.agyConversationId,codexReasoningEffort:d?.codexReasoningEffort,codexServiceTier:d?.codexServiceTier,codexSandboxMode:d?.codexSandboxMode,piSessionPath:d?.piSessionPath,modeId:s,modelId:d?.modelId,effort:d?.effort,cursorModeId:d?.cursorModeId,acpModelId:d?.acpModelId,acpModeId:d?.acpModeId,dshProviderId:d?.dshProviderId,dshModelId:d?.dshModelId,dshModeId:d?.dshModeId,dshMaxTokens:d?.dshMaxTokens,dshAgentPreset:d?.dshAgentPreset,dshSettingsRevision:d?.dshSettingsRevision,dshSettingsUpdatedAt:d?.dshSettingsUpdatedAt,dshProfileName:d?.dshProfileName,dshProfileSessionId:d?.dshProfileSessionId,dshProfileSessionCreated:d?.dshProfileSessionCreated,dshProfileEventCursor:d?.dshProfileEventCursor,updatedAt:Date.now()}),this.scheduleWrite()}setAcpSessionId(e,t){this.updateBinding(e,{acpSessionId:t})}setClaudeSessionId(e,t){this.updateBinding(e,{claudeSessionId:t})}getClaudeSessionId(e){return this.bindings.get(e)?.claudeSessionId}setCodexThreadId(e,t){this.updateBinding(e,{codexThreadId:t})}getCodexThreadId(e){return this.bindings.get(e)?.codexThreadId}setAgyConversationId(e,t){this.updateBinding(e,{agyConversationId:t})}getAgyConversationId(e){return this.bindings.get(e)?.agyConversationId}setCodexContext(e,t){this.updateBinding(e,{codexModelId:t.modelId,codexModeId:t.modeId,codexReasoningEffort:t.reasoningEffort,codexServiceTier:t.serviceTier,codexSandboxMode:t.sandboxMode})}getCodexModelId(e){return this.bindings.get(e)?.codexModelId}setCodexModelId(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim();!d||i.codexModelId===d||(this.bindings.set(e,{...i,codexModelId:d,updatedAt:Date.now()}),this.scheduleWrite())}setCodexModeId(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim();!d||i.codexModeId===d||(this.bindings.set(e,{...i,codexModeId:d,updatedAt:Date.now()}),this.scheduleWrite())}setCodexServiceTier(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim();!d||i.codexServiceTier===d||(this.bindings.set(e,{...i,codexServiceTier:d,updatedAt:Date.now()}),this.scheduleWrite())}getCodexModeId(e){return this.bindings.get(e)?.codexModeId}getCodexReasoningEffort(e){return this.bindings.get(e)?.codexReasoningEffort}getCodexServiceTier(e){return this.bindings.get(e)?.codexServiceTier}getCodexSandboxMode(e){return this.bindings.get(e)?.codexSandboxMode}setPiSessionPath(e,t){this.updateBinding(e,{piSessionPath:t})}getPiSessionPath(e){return this.bindings.get(e)?.piSessionPath}setCodeWhaleThreadId(e,t){this.updateBinding(e,{codewhaleThreadId:t})}getCodeWhaleThreadId(e){return this.bindings.get(e)?.codewhaleThreadId}setModeId(e,t){const i=this.bindings.get(e);if(!i)return;const d=n(t);i.modeId!==d&&(this.bindings.set(e,{...i,modeId:d,updatedAt:Date.now()}),this.scheduleWrite())}ensureModeId(e,t=P){const i=this.bindings.get(e);i&&(i.modeId||(this.bindings.set(e,{...i,modeId:n(t),updatedAt:Date.now()}),this.scheduleWrite()))}getAcpSessionId(e){return this.bindings.get(e)?.acpSessionId}getModeId(e){const t=this.bindings.get(e)?.modeId;return t?n(t):void 0}setModelId(e,t){const i=this.bindings.get(e);if(!i)return;const d=t.trim();i.modelId!==d&&(this.bindings.set(e,{...i,modelId:d,updatedAt:Date.now()}),this.scheduleWrite())}getModelId(e){return this.bindings.get(e)?.modelId}setEffort(e,t){const i=this.bindings.get(e);if(!i)return;const d=a(t);d&&i.effort!==d&&(this.bindings.set(e,{...i,effort:d,updatedAt:Date.now()}),this.scheduleWrite())}getEffort(e){return a(this.bindings.get(e)?.effort)}setCursorModeId(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim().toLowerCase(),s=d===""?void 0:d;i.cursorModeId!==s&&(this.bindings.set(e,{...i,cursorModeId:s,updatedAt:Date.now()}),this.scheduleWrite())}getCursorModeId(e){return this.bindings.get(e)?.cursorModeId}setAcpModelId(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim(),s=d===""?void 0:d;i.acpModelId!==s&&(this.bindings.set(e,{...i,acpModelId:s,updatedAt:Date.now()}),this.scheduleWrite())}getAcpModelId(e){return this.bindings.get(e)?.acpModelId}setAcpModeId(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t??"").trim(),s=d===""?void 0:d;i.acpModeId!==s&&(this.bindings.set(e,{...i,acpModeId:s,updatedAt:Date.now()}),this.scheduleWrite())}getAcpModeId(e){return this.bindings.get(e)?.acpModeId}getDshSettings(e){const t=this.bindings.get(e);if(t)return{...t.dshProviderId?{providerId:t.dshProviderId}:{},...t.dshModelId?{modelId:t.dshModelId}:{},modeId:t.dshModeId==="full_auto"?"full_auto":"approval",...t.dshMaxTokens?{maxTokens:t.dshMaxTokens}:{},...t.dshAgentPreset?{agentPreset:t.dshAgentPreset}:{},revision:t.dshSettingsRevision??0,...t.dshSettingsUpdatedAt?{updatedAt:t.dshSettingsUpdatedAt}:{}}}updateDshSettings(e,t){const i=this.bindings.get(e);if(!i)return;const d=Object.prototype.hasOwnProperty.call(t,"providerId")?String(t.providerId??"").trim()||void 0:i.dshProviderId,s=Object.prototype.hasOwnProperty.call(t,"modelId")?String(t.modelId??"").trim()||void 0:i.dshModelId,r=Object.prototype.hasOwnProperty.call(t,"modeId")?t.modeId==="full_auto"?"full_auto":"approval":i.dshModeId,f=Object.prototype.hasOwnProperty.call(t,"maxTokens")?Number.isSafeInteger(t.maxTokens)&&Number(t.maxTokens)>0?Number(t.maxTokens):void 0:i.dshMaxTokens;if(d===i.dshProviderId&&s===i.dshModelId&&r===i.dshModeId&&f===i.dshMaxTokens)return i.dshSettingsRevision??0;const c=Date.now(),u=(i.dshSettingsRevision??0)+1;return this.bindings.set(e,{...i,dshProviderId:d,dshModelId:s,dshModeId:r,dshMaxTokens:f,dshSettingsRevision:u,dshSettingsUpdatedAt:c,updatedAt:c}),this.scheduleWrite(),u}getDshSelectedProfile(e){const t=this.bindings.get(e)?.dshProfileName;return typeof t=="string"&&t.trim()?t.trim():void 0}isDshProfileLocked(e){return this.bindings.get(e)?.dshProfileSessionCreated===!0}setDshSelectedProfile(e,t){const i=this.bindings.get(e);if(!i)return!1;const d=String(t??"").trim();return d?i.dshProfileName===d?!0:i.dshProfileSessionCreated===!0?!1:(this.bindings.set(e,{...i,dshProfileName:d,dshProfileSessionId:void 0,dshProfileSessionCreated:!1,dshProfileEventCursor:0,updatedAt:Date.now()}),this.scheduleWrite(),!0):!1}getDshAgentPreset(e){const t=this.bindings.get(e)?.dshAgentPreset;return typeof t=="string"&&t.trim()?t.trim():void 0}isDshAgentPresetLocked(e){return this.bindings.get(e)?.dshProfileSessionCreated===!0}setDshAgentPreset(e,t){const i=this.bindings.get(e);if(!i||i.dshProfileSessionCreated===!0)return!1;const d=String(t??"").trim();return!d||i.dshAgentPreset===d?i.dshAgentPreset===d:(this.bindings.set(e,{...i,dshAgentPreset:d,updatedAt:Date.now()}),this.scheduleWrite(),!0)}getDshProfileBinding(e,t){const i=this.bindings.get(e);if(!(!i?.dshProfileSessionId||i.dshProfileName!==t))return{profileName:t,sessionId:i.dshProfileSessionId,sessionCreated:i.dshProfileSessionCreated===!0,eventCursor:i.dshProfileEventCursor??0}}setDshProfileBinding(e,t){const i=this.bindings.get(e);if(!i)return;const d=String(t.profileName).trim(),s=String(t.sessionId).trim();if(!d||!s)return;const r=Number.isSafeInteger(t.eventCursor)&&t.eventCursor>=0?t.eventCursor:0;i.dshProfileName===d&&i.dshProfileSessionId===s&&i.dshProfileSessionCreated===t.sessionCreated&&(i.dshProfileEventCursor??0)===r||(this.bindings.set(e,{...i,dshProfileName:d,dshProfileSessionId:s,dshProfileSessionCreated:t.sessionCreated,dshProfileEventCursor:r,updatedAt:Date.now()}),this.scheduleWrite())}get(e){return this.bindings.get(e)}getMostRecentlyUpdatedSessionId(e){const t=e?.requireCwd!==!1;let i,d=-1;for(const s of this.bindings.values())t&&!String(s.cwd??"").trim()||s.updatedAt>d&&(d=s.updatedAt,i=s.aibotSessionId);return i}delete(e){const t=this.bindings.get(e);t&&(o.info("session-binding-store",`delete binding session_id=${e} cwd=${t.cwd??""} codexThreadId=${t.codexThreadId??""}`),this.bindings.delete(e),this.scheduleWrite())}quarantineUnreadablePrimary(){if(!this.filePath||!h(this.filePath))return;const e=`${this.filePath}.corrupt.${Date.now()}`;try{return p(this.filePath,e),o.error("session-binding-store",`Copied unreadable primary bindings to ${e} (original retained to block legacy clobber)`),e}catch(t){o.error("session-binding-store",`Failed to copy unreadable primary ${this.filePath}: ${t instanceof Error?t.message:String(t)}`);return}}entries(){return this.bindings.entries()}async flush(){await this.writePromise}scheduleWrite(){this.filePath&&(this.writePromise=this.writePromise.then(()=>this.write()).catch(e=>{o.error("session-binding-store",`Persist failed: ${e instanceof Error?e.message:e}`)}))}async write(){if(!this.filePath)return;const e=Array.from(this.bindings.values());await m(this.filePath,e)}writeMigratedSnapshot(e){if(!this.filePath)return;const t=`${this.filePath}.${y()}.migration.tmp`;try{b(t,`${JSON.stringify(e,null,2)}
2
- `,{encoding:"utf8",mode:384,flag:"wx"}),S(t,this.filePath);try{x(this.filePath,384)}catch{}}catch(i){if(h(t))try{M(t)}catch{}throw new Error(`Failed to migrate legacy session bindings from ${this.legacyFilePath} to ${this.filePath}: ${i instanceof Error?i.message:String(i)}`)}}updateBinding(e,t){const i=this.bindings.get(e),d={aibotSessionId:e,acpSessionId:Object.prototype.hasOwnProperty.call(t,"acpSessionId")?t.acpSessionId:i?.acpSessionId,claudeSessionId:Object.prototype.hasOwnProperty.call(t,"claudeSessionId")?t.claudeSessionId:i?.claudeSessionId,codexThreadId:Object.prototype.hasOwnProperty.call(t,"codexThreadId")?t.codexThreadId:i?.codexThreadId,codexModelId:Object.prototype.hasOwnProperty.call(t,"codexModelId")?t.codexModelId:i?.codexModelId,codexModeId:Object.prototype.hasOwnProperty.call(t,"codexModeId")?t.codexModeId:i?.codexModeId,codewhaleThreadId:Object.prototype.hasOwnProperty.call(t,"codewhaleThreadId")?t.codewhaleThreadId:i?.codewhaleThreadId,agyConversationId:Object.prototype.hasOwnProperty.call(t,"agyConversationId")?t.agyConversationId:i?.agyConversationId,codexReasoningEffort:Object.prototype.hasOwnProperty.call(t,"codexReasoningEffort")?t.codexReasoningEffort:i?.codexReasoningEffort,codexServiceTier:Object.prototype.hasOwnProperty.call(t,"codexServiceTier")?t.codexServiceTier:i?.codexServiceTier,codexSandboxMode:Object.prototype.hasOwnProperty.call(t,"codexSandboxMode")?t.codexSandboxMode:i?.codexSandboxMode,piSessionPath:Object.prototype.hasOwnProperty.call(t,"piSessionPath")?t.piSessionPath:i?.piSessionPath,cwd:i?.cwd,modeId:n(i?.modeId),modelId:i?.modelId,effort:Object.prototype.hasOwnProperty.call(t,"effort")?a(t.effort):a(i?.effort),cursorModeId:i?.cursorModeId,acpModelId:i?.acpModelId,acpModeId:i?.acpModeId,dshProviderId:i?.dshProviderId,dshModelId:i?.dshModelId,dshModeId:i?.dshModeId,dshMaxTokens:i?.dshMaxTokens,dshAgentPreset:i?.dshAgentPreset,dshSettingsRevision:i?.dshSettingsRevision,dshSettingsUpdatedAt:i?.dshSettingsUpdatedAt,dshProfileName:i?.dshProfileName,dshProfileSessionId:i?.dshProfileSessionId,dshProfileSessionCreated:i?.dshProfileSessionCreated,dshProfileEventCursor:i?.dshProfileEventCursor,updatedAt:Date.now()};this.bindings.set(e,d),this.scheduleWrite()}}export{E as SessionBindingStore};
1
+ import{readJSONFile as P,writeJSONFileAtomic as x}from"../util/json-file.js";import{log as h}from"../log/index.js";import{SESSION_MODE_IDS as c}from"../../adapter/claude/protocol-contract.js";import{normalizeClaudeEffort as l}from"../config/claude-direct-env.js";import{chmodSync as S,copyFileSync as p,existsSync as u,renameSync as M,rmSync as b,writeFileSync as y}from"node:fs";import{randomUUID as v}from"node:crypto";const m=c.fullAuto;function o(r){const e=String(r??"").trim().toLowerCase();return e===c.approval||e===c.fullAuto?e:m}class N{bindings=new Map;filePath;legacyFilePath;writePromise=Promise.resolve();constructor(e,t){this.filePath=e??null,this.legacyFilePath=t&&t!==e?t:null}load(){if(!this.filePath)return;const e=u(this.filePath);let t=P(this.filePath),s=!1;if(e&&!Array.isArray(t)){const d=this.quarantineUnreadablePrimary();throw new Error(`Refusing to start with unreadable session bindings: primary=${this.filePath}`+(d?` quarantined=${d}`:"")+(this.legacyFilePath?` legacy=${this.legacyFilePath}`:"")+" (legacy fallback disabled to avoid clobbering newer bindings)")}if(!e&&this.legacyFilePath){s=u(this.legacyFilePath);const d=P(this.legacyFilePath);Array.isArray(d)&&(this.writeMigratedSnapshot(d),t=d,h.info("session-binding-store",`Migrated legacy bindings from ${this.legacyFilePath} to ${this.filePath}; legacy file retained`))}if(!Array.isArray(t)){if(e||s)throw new Error(`Refusing to start with unreadable session bindings: primary=${this.filePath}${this.legacyFilePath?` legacy=${this.legacyFilePath}`:""}`);return}this.bindings.clear();for(const d of t)d.aibotSessionId&&this.bindings.set(d.aibotSessionId,{...d,modeId:o(d.modeId),effort:l(d.effort),dshProviderId:typeof d.dshProviderId=="string"&&d.dshProviderId.trim()?d.dshProviderId.trim():void 0,dshModelId:typeof d.dshModelId=="string"&&d.dshModelId.trim()?d.dshModelId.trim():void 0,dshModeId:d.dshModeId===void 0?void 0:d.dshModeId==="full_auto"?"full_auto":"approval",dshMaxTokens:Number.isSafeInteger(d.dshMaxTokens)&&Number(d.dshMaxTokens)>0?Number(d.dshMaxTokens):void 0,dshAgentPreset:typeof d.dshAgentPreset=="string"&&d.dshAgentPreset.trim()?d.dshAgentPreset.trim():void 0,dshPluginIds:g(d.dshPluginIds),dshSettingsRevision:d.dshSettingsRevision===void 0?void 0:Number.isSafeInteger(d.dshSettingsRevision)&&Number(d.dshSettingsRevision)>=0?Number(d.dshSettingsRevision):0,dshProfileName:typeof d.dshProfileName=="string"&&d.dshProfileName.trim()?d.dshProfileName.trim():void 0,dshProfileSessionId:typeof d.dshProfileSessionId=="string"&&d.dshProfileSessionId.trim()?d.dshProfileSessionId.trim():void 0,dshProfileSessionCreated:d.dshProfileSessionCreated===!0,dshProfileEventCursor:Number.isSafeInteger(d.dshProfileEventCursor)&&Number(d.dshProfileEventCursor)>=0?Number(d.dshProfileEventCursor):0})}set(e,t,s){const d=this.bindings.get(e),i=o(s?.modeId??d?.modeId),n=t!==void 0?t:d?.cwd;this.bindings.set(e,{aibotSessionId:e,cwd:n,acpSessionId:d?.acpSessionId,claudeSessionId:d?.claudeSessionId,codexThreadId:d?.codexThreadId,codexModelId:d?.codexModelId,codexModeId:d?.codexModeId,codewhaleThreadId:d?.codewhaleThreadId,agyConversationId:d?.agyConversationId,codexReasoningEffort:d?.codexReasoningEffort,codexServiceTier:d?.codexServiceTier,codexSandboxMode:d?.codexSandboxMode,piSessionPath:d?.piSessionPath,modeId:i,modelId:d?.modelId,effort:d?.effort,cursorModeId:d?.cursorModeId,acpModelId:d?.acpModelId,acpModeId:d?.acpModeId,dshProviderId:d?.dshProviderId,dshModelId:d?.dshModelId,dshModeId:d?.dshModeId,dshMaxTokens:d?.dshMaxTokens,dshAgentPreset:d?.dshAgentPreset,dshPluginIds:d?.dshPluginIds,dshSettingsRevision:d?.dshSettingsRevision,dshSettingsUpdatedAt:d?.dshSettingsUpdatedAt,dshProfileName:d?.dshProfileName,dshProfileSessionId:d?.dshProfileSessionId,dshProfileSessionCreated:d?.dshProfileSessionCreated,dshProfileEventCursor:d?.dshProfileEventCursor,updatedAt:Date.now()}),this.scheduleWrite()}setAcpSessionId(e,t){this.updateBinding(e,{acpSessionId:t})}setClaudeSessionId(e,t){this.updateBinding(e,{claudeSessionId:t})}getClaudeSessionId(e){return this.bindings.get(e)?.claudeSessionId}setCodexThreadId(e,t){this.updateBinding(e,{codexThreadId:t})}getCodexThreadId(e){return this.bindings.get(e)?.codexThreadId}setAgyConversationId(e,t){this.updateBinding(e,{agyConversationId:t})}getAgyConversationId(e){return this.bindings.get(e)?.agyConversationId}setCodexContext(e,t){this.updateBinding(e,{codexModelId:t.modelId,codexModeId:t.modeId,codexReasoningEffort:t.reasoningEffort,codexServiceTier:t.serviceTier,codexSandboxMode:t.sandboxMode})}getCodexModelId(e){return this.bindings.get(e)?.codexModelId}setCodexModelId(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim();!d||s.codexModelId===d||(this.bindings.set(e,{...s,codexModelId:d,updatedAt:Date.now()}),this.scheduleWrite())}setCodexModeId(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim();!d||s.codexModeId===d||(this.bindings.set(e,{...s,codexModeId:d,updatedAt:Date.now()}),this.scheduleWrite())}setCodexServiceTier(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim();!d||s.codexServiceTier===d||(this.bindings.set(e,{...s,codexServiceTier:d,updatedAt:Date.now()}),this.scheduleWrite())}getCodexModeId(e){return this.bindings.get(e)?.codexModeId}getCodexReasoningEffort(e){return this.bindings.get(e)?.codexReasoningEffort}getCodexServiceTier(e){return this.bindings.get(e)?.codexServiceTier}getCodexSandboxMode(e){return this.bindings.get(e)?.codexSandboxMode}setPiSessionPath(e,t){this.updateBinding(e,{piSessionPath:t})}getPiSessionPath(e){return this.bindings.get(e)?.piSessionPath}setCodeWhaleThreadId(e,t){this.updateBinding(e,{codewhaleThreadId:t})}getCodeWhaleThreadId(e){return this.bindings.get(e)?.codewhaleThreadId}setModeId(e,t){const s=this.bindings.get(e);if(!s)return;const d=o(t);s.modeId!==d&&(this.bindings.set(e,{...s,modeId:d,updatedAt:Date.now()}),this.scheduleWrite())}ensureModeId(e,t=m){const s=this.bindings.get(e);s&&(s.modeId||(this.bindings.set(e,{...s,modeId:o(t),updatedAt:Date.now()}),this.scheduleWrite()))}getAcpSessionId(e){return this.bindings.get(e)?.acpSessionId}getModeId(e){const t=this.bindings.get(e)?.modeId;return t?o(t):void 0}setModelId(e,t){const s=this.bindings.get(e);if(!s)return;const d=t.trim();s.modelId!==d&&(this.bindings.set(e,{...s,modelId:d,updatedAt:Date.now()}),this.scheduleWrite())}getModelId(e){return this.bindings.get(e)?.modelId}setEffort(e,t){const s=this.bindings.get(e);if(!s)return;const d=l(t);d&&s.effort!==d&&(this.bindings.set(e,{...s,effort:d,updatedAt:Date.now()}),this.scheduleWrite())}getEffort(e){return l(this.bindings.get(e)?.effort)}setCursorModeId(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim().toLowerCase(),i=d===""?void 0:d;s.cursorModeId!==i&&(this.bindings.set(e,{...s,cursorModeId:i,updatedAt:Date.now()}),this.scheduleWrite())}getCursorModeId(e){return this.bindings.get(e)?.cursorModeId}setAcpModelId(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim(),i=d===""?void 0:d;s.acpModelId!==i&&(this.bindings.set(e,{...s,acpModelId:i,updatedAt:Date.now()}),this.scheduleWrite())}getAcpModelId(e){return this.bindings.get(e)?.acpModelId}setAcpModeId(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t??"").trim(),i=d===""?void 0:d;s.acpModeId!==i&&(this.bindings.set(e,{...s,acpModeId:i,updatedAt:Date.now()}),this.scheduleWrite())}getAcpModeId(e){return this.bindings.get(e)?.acpModeId}getDshSettings(e){const t=this.bindings.get(e);if(t)return{...t.dshProviderId?{providerId:t.dshProviderId}:{},...t.dshModelId?{modelId:t.dshModelId}:{},modeId:t.dshModeId==="full_auto"?"full_auto":"approval",...t.dshMaxTokens?{maxTokens:t.dshMaxTokens}:{},...t.dshAgentPreset?{agentPreset:t.dshAgentPreset}:{},pluginIds:g(t.dshPluginIds),revision:t.dshSettingsRevision??0,...t.dshSettingsUpdatedAt?{updatedAt:t.dshSettingsUpdatedAt}:{}}}updateDshSettings(e,t){const s=this.bindings.get(e);if(!s)return;const d=Object.prototype.hasOwnProperty.call(t,"providerId")?String(t.providerId??"").trim()||void 0:s.dshProviderId,i=Object.prototype.hasOwnProperty.call(t,"modelId")?String(t.modelId??"").trim()||void 0:s.dshModelId,n=Object.prototype.hasOwnProperty.call(t,"modeId")?t.modeId==="full_auto"?"full_auto":"approval":s.dshModeId,a=Object.prototype.hasOwnProperty.call(t,"maxTokens")?Number.isSafeInteger(t.maxTokens)&&Number(t.maxTokens)>0?Number(t.maxTokens):void 0:s.dshMaxTokens;if(d===s.dshProviderId&&i===s.dshModelId&&n===s.dshModeId&&a===s.dshMaxTokens)return s.dshSettingsRevision??0;const f=Date.now(),I=(s.dshSettingsRevision??0)+1;return this.bindings.set(e,{...s,dshProviderId:d,dshModelId:i,dshModeId:n,dshMaxTokens:a,dshSettingsRevision:I,dshSettingsUpdatedAt:f,updatedAt:f}),this.scheduleWrite(),I}getDshSelectedProfile(e){const t=this.bindings.get(e)?.dshProfileName;return typeof t=="string"&&t.trim()?t.trim():void 0}isDshProfileLocked(e){return this.bindings.get(e)?.dshProfileSessionCreated===!0}setDshSelectedProfile(e,t){const s=this.bindings.get(e);if(!s)return!1;const d=String(t??"").trim();return d?s.dshProfileName===d?!0:s.dshProfileSessionCreated===!0?!1:(this.bindings.set(e,{...s,dshProfileName:d,dshProfileSessionId:void 0,dshProfileSessionCreated:!1,dshProfileEventCursor:0,updatedAt:Date.now()}),this.scheduleWrite(),!0):!1}getDshAgentPreset(e){const t=this.bindings.get(e)?.dshAgentPreset;return typeof t=="string"&&t.trim()?t.trim():void 0}isDshAgentPresetLocked(e){return this.bindings.get(e)?.dshProfileSessionCreated===!0}setDshAgentPreset(e,t){const s=this.bindings.get(e);if(!s||s.dshProfileSessionCreated===!0)return!1;const d=String(t??"").trim();return!d||s.dshAgentPreset===d?s.dshAgentPreset===d:(this.bindings.set(e,{...s,dshAgentPreset:d,updatedAt:Date.now()}),this.scheduleWrite(),!0)}getDshEnabledPlugins(e){return g(this.bindings.get(e)?.dshPluginIds)}setDshEnabledPlugins(e,t){const s=this.bindings.get(e);if(!s)return;const d=g(t),i=g(s.dshPluginIds);if(w(i,d))return s.dshSettingsRevision??0;const n=Date.now(),a=(s.dshSettingsRevision??0)+1;return this.bindings.set(e,{...s,dshPluginIds:d,dshSettingsRevision:a,dshSettingsUpdatedAt:n,updatedAt:n}),this.scheduleWrite(),a}getDshProfileBinding(e,t){const s=this.bindings.get(e);if(!(!s?.dshProfileSessionId||s.dshProfileName!==t))return{profileName:t,sessionId:s.dshProfileSessionId,sessionCreated:s.dshProfileSessionCreated===!0,eventCursor:s.dshProfileEventCursor??0}}setDshProfileBinding(e,t){const s=this.bindings.get(e);if(!s)return;const d=String(t.profileName).trim(),i=String(t.sessionId).trim();if(!d||!i)return;const n=Number.isSafeInteger(t.eventCursor)&&t.eventCursor>=0?t.eventCursor:0;s.dshProfileName===d&&s.dshProfileSessionId===i&&s.dshProfileSessionCreated===t.sessionCreated&&(s.dshProfileEventCursor??0)===n||(this.bindings.set(e,{...s,dshProfileName:d,dshProfileSessionId:i,dshProfileSessionCreated:t.sessionCreated,dshProfileEventCursor:n,updatedAt:Date.now()}),this.scheduleWrite())}get(e){return this.bindings.get(e)}getMostRecentlyUpdatedSessionId(e){const t=e?.requireCwd!==!1;let s,d=-1;for(const i of this.bindings.values())t&&!String(i.cwd??"").trim()||i.updatedAt>d&&(d=i.updatedAt,s=i.aibotSessionId);return s}delete(e){const t=this.bindings.get(e);t&&(h.info("session-binding-store",`delete binding session_id=${e} cwd=${t.cwd??""} codexThreadId=${t.codexThreadId??""}`),this.bindings.delete(e),this.scheduleWrite())}quarantineUnreadablePrimary(){if(!this.filePath||!u(this.filePath))return;const e=`${this.filePath}.corrupt.${Date.now()}`;try{return p(this.filePath,e),h.error("session-binding-store",`Copied unreadable primary bindings to ${e} (original retained to block legacy clobber)`),e}catch(t){h.error("session-binding-store",`Failed to copy unreadable primary ${this.filePath}: ${t instanceof Error?t.message:String(t)}`);return}}entries(){return this.bindings.entries()}async flush(){await this.writePromise}scheduleWrite(){this.filePath&&(this.writePromise=this.writePromise.then(()=>this.write()).catch(e=>{h.error("session-binding-store",`Persist failed: ${e instanceof Error?e.message:e}`)}))}async write(){if(!this.filePath)return;const e=Array.from(this.bindings.values());await x(this.filePath,e)}writeMigratedSnapshot(e){if(!this.filePath)return;const t=`${this.filePath}.${v()}.migration.tmp`;try{y(t,`${JSON.stringify(e,null,2)}
2
+ `,{encoding:"utf8",mode:384,flag:"wx"}),M(t,this.filePath);try{S(this.filePath,384)}catch{}}catch(s){if(u(t))try{b(t)}catch{}throw new Error(`Failed to migrate legacy session bindings from ${this.legacyFilePath} to ${this.filePath}: ${s instanceof Error?s.message:String(s)}`)}}updateBinding(e,t){const s=this.bindings.get(e),d={aibotSessionId:e,acpSessionId:Object.prototype.hasOwnProperty.call(t,"acpSessionId")?t.acpSessionId:s?.acpSessionId,claudeSessionId:Object.prototype.hasOwnProperty.call(t,"claudeSessionId")?t.claudeSessionId:s?.claudeSessionId,codexThreadId:Object.prototype.hasOwnProperty.call(t,"codexThreadId")?t.codexThreadId:s?.codexThreadId,codexModelId:Object.prototype.hasOwnProperty.call(t,"codexModelId")?t.codexModelId:s?.codexModelId,codexModeId:Object.prototype.hasOwnProperty.call(t,"codexModeId")?t.codexModeId:s?.codexModeId,codewhaleThreadId:Object.prototype.hasOwnProperty.call(t,"codewhaleThreadId")?t.codewhaleThreadId:s?.codewhaleThreadId,agyConversationId:Object.prototype.hasOwnProperty.call(t,"agyConversationId")?t.agyConversationId:s?.agyConversationId,codexReasoningEffort:Object.prototype.hasOwnProperty.call(t,"codexReasoningEffort")?t.codexReasoningEffort:s?.codexReasoningEffort,codexServiceTier:Object.prototype.hasOwnProperty.call(t,"codexServiceTier")?t.codexServiceTier:s?.codexServiceTier,codexSandboxMode:Object.prototype.hasOwnProperty.call(t,"codexSandboxMode")?t.codexSandboxMode:s?.codexSandboxMode,piSessionPath:Object.prototype.hasOwnProperty.call(t,"piSessionPath")?t.piSessionPath:s?.piSessionPath,cwd:s?.cwd,modeId:o(s?.modeId),modelId:s?.modelId,effort:Object.prototype.hasOwnProperty.call(t,"effort")?l(t.effort):l(s?.effort),cursorModeId:s?.cursorModeId,acpModelId:s?.acpModelId,acpModeId:s?.acpModeId,dshProviderId:s?.dshProviderId,dshModelId:s?.dshModelId,dshModeId:s?.dshModeId,dshMaxTokens:s?.dshMaxTokens,dshAgentPreset:s?.dshAgentPreset,dshPluginIds:s?.dshPluginIds,dshSettingsRevision:s?.dshSettingsRevision,dshSettingsUpdatedAt:s?.dshSettingsUpdatedAt,dshProfileName:s?.dshProfileName,dshProfileSessionId:s?.dshProfileSessionId,dshProfileSessionCreated:s?.dshProfileSessionCreated,dshProfileEventCursor:s?.dshProfileEventCursor,updatedAt:Date.now()};this.bindings.set(e,d),this.scheduleWrite()}}function g(r){const e=new Set,t=[];for(const s of r??[]){const d=String(s??"").trim();!d||e.has(d)||(e.add(d),t.push(d))}return t}function w(r,e){return r.length===e.length&&r.every((t,s)=>t===e[s])}export{N as SessionBindingStore};
@@ -1 +1 @@
1
- const o=Object.freeze(["commentary","final_answer"]),t=Object.freeze([]);function n(e){if(!e||!e.trim())return t;const r=e.split(",").map(s=>s.trim().toLowerCase()).filter(Boolean);return r.length>0?Object.freeze(r):t}function E(){const e=n(process.env.CODEX_VISIBLE_PHASES);return e.length>0?e:o}const i=E(),S=n(process.env.CODEX_HIDDEN_PHASES);function c(e){if(typeof e!="string")return!0;const r=e.trim().toLowerCase();return r?S.includes(r)?!1:i.includes(r):!0}export{c as isUserVisibleAgentMessagePhase};
1
+ const S=Object.freeze(["final_answer"]),c=Object.freeze(["commentary"]),s=Object.freeze([]);function t(e){if(!e||!e.trim())return s;const n=e.split(",").map(r=>r.trim().toLowerCase()).filter(Boolean);return n.length>0?Object.freeze(n):s}function f(){const e=t(process.env.CODEX_VISIBLE_PHASES);return e.length>0?e:S}const i=f(),o=t(process.env.CODEX_HIDDEN_PHASES),E=t(process.env.CODEX_THINKING_PHASES);function _(e){if(typeof e!="string")return!0;const n=e.trim().toLowerCase();return n?o.includes(n)?!1:i.includes(n):!0}function a(e){if(typeof e!="string")return!1;const n=e.trim().toLowerCase();return!n||o.includes(n)||i.includes(n)?!1:(E.length>0?E:c).includes(n)}export{a as isThinkingAgentMessagePhase,_ as isUserVisibleAgentMessagePhase};
package/dist/log.js CHANGED
@@ -1,3 +1,3 @@
1
- import{createWriteStream as g,mkdirSync as l,existsSync as f}from"node:fs";import{join as t}from"node:path";import{homedir as m}from"node:os";const i=t(m(),".grix"),s={base:i,config:t(i,"config"),log:t(i,"log"),data:t(i,"data")};function S(){for(const o of Object.values(s))f(o)||l(o,{recursive:!0})}let a=null;function $(){const o=new Date().toISOString().slice(0,10),r=t(s.log,`grix-acp-${o}.log`);a=g(r,{flags:"a"})}function c(){return new Date().toISOString().slice(11,19)}const u={info(o,r,...n){const e=`${c()} [${o}] ${r}${n.length?" "+n.map(String).join(" "):""}`;console.log(e),a?.write(e+`
2
- `)},error(o,r,...n){const e=`${c()} [${o}] ERROR ${r}${n.length?" "+n.map(String).join(" "):""}`;console.error(e),a?.write(e+`
1
+ import{createWriteStream as g,mkdirSync as l,existsSync as f}from"node:fs";import{join as i}from"node:path";import{homedir as m}from"node:os";const n=i(m(),".grix"),s={base:n,config:i(n,"config"),log:i(n,"log"),data:i(n,"data")};function S(){for(const o of Object.values(s))f(o)||l(o,{recursive:!0})}let a=null;function $(){const o=new Date().toISOString().slice(0,10),r=i(s.log,`grix-acp-${o}.log`);a=g(r,{flags:"a"})}function c(){return new Date().toISOString().slice(11,19)}const u={info(o,r,...t){const e=`${c()} [${o}] ${r}${t.length?" "+t.map(String).join(" "):""}`;console.log(e),a?.write(e+`
2
+ `)},error(o,r,...t){const e=`${c()} [${o}] ERROR ${r}${t.length?" "+t.map(String).join(" "):""}`;console.error(e),a?.write(e+`
3
3
  `)}};export{s as GRIX_PATHS,S as ensureGrixDirs,$ as initLogger,u as log};
@@ -1 +1 @@
1
- import*as i from"node:net";const e={bind:"127.0.0.1",port:0,endpoint:"/mcp",sessionTimeoutMs:18e5,invokeTimeoutMs:3e4};function n(o){const u={bind:o?.bind??e.bind,port:o?.port??e.port,endpoint:o?.endpoint??e.endpoint,sessionTimeoutMs:o?.sessionTimeoutMs??e.sessionTimeoutMs,invokeTimeoutMs:o?.invokeTimeoutMs??e.invokeTimeoutMs,allowedOrigins:o?.allowedOrigins,allowedHosts:o?.allowedHosts};return s(u.bind),u.port!==0&&t(u.port),r(u.sessionTimeoutMs),u}function s(o){if(!o||!i.isIPv4(o)&&!i.isIPv6(o))throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: bind \u5730\u5740 "${o}" \u4E0D\u662F\u5408\u6CD5\u7684 IPv4 \u6216 IPv6 \u5730\u5740`)}function t(o){if(!Number.isInteger(o)||o<1||o>65535)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: port \u503C ${o} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1-65535 \u5185\u6216\u4E0D\u662F\u6574\u6570`)}function r(o){if(!Number.isInteger(o)||o<1e3||o>864e5)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: session_timeout_ms \u503C ${o} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1000-86400000 \u5185`)}export{n as createDefaultGatewayConfig};
1
+ import*as n from"node:net";const i={bind:"127.0.0.1",port:0,endpoint:"/mcp",sessionTimeoutMs:18e5,invokeTimeoutMs:3e4};function s(u){const e={bind:u?.bind??i.bind,port:u?.port??i.port,endpoint:u?.endpoint??i.endpoint,sessionTimeoutMs:u?.sessionTimeoutMs??i.sessionTimeoutMs,invokeTimeoutMs:u?.invokeTimeoutMs??i.invokeTimeoutMs,allowedOrigins:u?.allowedOrigins,allowedHosts:u?.allowedHosts};return t(e.bind),e.port!==0&&o(e.port),r(e.sessionTimeoutMs),e}function t(u){if(!u||!n.isIPv4(u)&&!n.isIPv6(u))throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: bind \u5730\u5740 "${u}" \u4E0D\u662F\u5408\u6CD5\u7684 IPv4 \u6216 IPv6 \u5730\u5740`)}function o(u){if(!Number.isInteger(u)||u<1||u>65535)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: port \u503C ${u} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1-65535 \u5185\u6216\u4E0D\u662F\u6574\u6570`)}function r(u){if(!Number.isInteger(u)||u<1e3||u>864e5)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: session_timeout_ms \u503C ${u} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1000-86400000 \u5185`)}export{s as createDefaultGatewayConfig};
@@ -1 +1 @@
1
- const r=3e4;class c{connectionManager;onDisconnected;bindings=new Map;constructor(n,i){this.connectionManager=n,this.onDisconnected=i}async bind(n,i){if(this.bindings.has(n))throw new Error(`Session ${n} is already bound to a connection`);const e=await this.connectWithTimeout(i),t=[],s=e.onDisconnected(()=>{this.removeBinding(n),this.onDisconnected(n)});return t.push(s),this.bindings.set(n,{sessionId:n,handle:e,subscriptions:t}),e}getHandle(n){return this.bindings.get(n)?.handle}unbind(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e();i.handle.disconnect()}}unbindAll(){const n=[...this.bindings.keys()];for(const i of n)this.unbind(i)}connectWithTimeout(n){return new Promise((i,e)=>{let t=!1;const s=setTimeout(()=>{t||(t=!0,e(new Error("Connection bind timeout after 30000ms")))},3e4);this.connectionManager.connect({agentId:n.agentId,apiKey:n.apiKey,url:n.wsUrl,clientType:n.clientType,capabilities:["agent_invoke"],adapterHint:`${n.clientType}/base`},{maxRetries:0}).then(o=>{t?o.disconnect():(t=!0,clearTimeout(s),i(o))}).catch(o=>{t||(t=!0,clearTimeout(s),e(o))})})}removeBinding(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e()}}}export{c as ConnectionBindingImpl};
1
+ const a=3e4;class c{connectionManager;onDisconnected;bindings=new Map;constructor(n,i){this.connectionManager=n,this.onDisconnected=i}async bind(n,i){if(this.bindings.has(n))throw new Error(`Session ${n} is already bound to a connection`);const e=await this.connectWithTimeout(i),t=[],s=e.onDisconnected(()=>{this.removeBinding(n),this.onDisconnected(n)});return t.push(s),this.bindings.set(n,{sessionId:n,handle:e,subscriptions:t}),e}getHandle(n){return this.bindings.get(n)?.handle}unbind(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e();i.handle.disconnect()}}unbindAll(){const n=[...this.bindings.keys()];for(const i of n)this.unbind(i)}connectWithTimeout(n){return new Promise((i,e)=>{let t=!1;const s=setTimeout(()=>{t||(t=!0,e(new Error("Connection bind timeout after 30000ms")))},3e4);this.connectionManager.connect({agentId:n.agentId,apiKey:n.apiKey,url:n.wsUrl,clientType:n.clientType,capabilities:["agent_invoke"],adapterHint:`${n.clientType}/base`},{maxRetries:0}).then(o=>{t?o.disconnect():(t=!0,clearTimeout(s),i(o))}).catch(o=>{t||(t=!0,clearTimeout(s),e(o))})})}removeBinding(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e()}}}export{c as ConnectionBindingImpl};
@@ -1 +1 @@
1
- function a(e){const t=new Set([`http://127.0.0.1:${e.serverPort}`,`http://localhost:${e.serverPort}`,...e.allowedOrigins]),o=new Set([`127.0.0.1:${e.serverPort}`,`localhost:${e.serverPort}`,...e.allowedHosts]);return{validateRequest(s){const r=i(s,t);if(!r.ok)return r;const n=l(s,o);return n.ok?{ok:!0}:n}}}function i(e,t){const o=e.headers.origin;return o?t.has(o)?{ok:!0}:{ok:!1,statusCode:403,message:`Origin not allowed: ${o}`}:{ok:!0}}function l(e,t){const o=e.headers.host;return o?t.has(o)?{ok:!0}:{ok:!1,statusCode:403,message:`Host not allowed: ${o}`}:{ok:!1,statusCode:403,message:"Missing Host header"}}export{a as createSecurityPolicy};
1
+ function a(o){const e=new Set([`http://127.0.0.1:${o.serverPort}`,`http://localhost:${o.serverPort}`,...o.allowedOrigins]),t=new Set([`127.0.0.1:${o.serverPort}`,`localhost:${o.serverPort}`,...o.allowedHosts]);return{validateRequest(s){const r=i(s,e);if(!r.ok)return r;const n=l(s,t);return n.ok?{ok:!0}:n}}}function i(o,e){const t=o.headers.origin;return t?e.has(t)?{ok:!0}:{ok:!1,statusCode:403,message:`Origin not allowed: ${t}`}:{ok:!0}}function l(o,e){const t=o.headers.host;return t?e.has(t)?{ok:!0}:{ok:!1,statusCode:403,message:`Host not allowed: ${t}`}:{ok:!1,statusCode:403,message:"Missing Host header"}}export{a as createSecurityPolicy};
@@ -1 +1 @@
1
- import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(t,e,r,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,r);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(t.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${t.status}`);if(p(e))return this.executeEventTool(t,e,r);const o=i(e,r);try{const u=await t.agentInvoke(o.action,o.params,n);return this.normalizeResult(u)}catch(u){const c=u instanceof Error?u.message:String(u);return c.toLowerCase().includes("timeout")?this.errorResult(`\u8C03\u7528\u8D85\u65F6: ${c}`):this.errorResult(`\u8C03\u7528\u5931\u8D25: ${c}`)}}normalizeResult(t){if(t==null||typeof t!="object")return this.successResult(t??null);const e=t,r=typeof e.code=="number"?e.code:0;if(r===0){const s="data"in e?e.data:null;return this.successResult(s??null)}const n=typeof e.msg=="string"?e.msg:"\u672A\u77E5\u9519\u8BEF";return this.errorResult(`\u4E0A\u6E38\u9519\u8BEF [code=${r}]: ${n}`)}successResult(t){return{content:[{type:"text",text:JSON.stringify(t)}],isError:!1}}errorResult(t){return{content:[{type:"text",text:t}],isError:!0}}async executeEventTool(t,e,r){return e==="grix_access_control"?this.executeAccessControl(t,r):d(t,e,r)}async executeAccessControl(t,e){const r=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[r];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${r}`);const s={};e.code!=null&&(s.code=e.code),e.sender_id!=null&&(s.sender_id=e.sender_id),e.policy!=null&&(s.policy=e.policy);try{const o=await t.agentInvoke("claude_access_control",{verb:n,payload:s},3e4);return this.successResult(o)}catch(o){const u=o instanceof Error?o.message:String(o);return this.errorResult(`access_control \u8C03\u7528\u5931\u8D25: ${u}`)}}}export{y as ToolExecutorImpl};
1
+ import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(r,e,t,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,t);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(r.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${r.status}`);if(p(e))return this.executeEventTool(r,e,t);const o=i(e,t);try{const u=await r.agentInvoke(o.action,o.params,n);return this.normalizeResult(u)}catch(u){const c=u instanceof Error?u.message:String(u);return c.toLowerCase().includes("timeout")?this.errorResult(`\u8C03\u7528\u8D85\u65F6: ${c}`):this.errorResult(`\u8C03\u7528\u5931\u8D25: ${c}`)}}normalizeResult(r){if(r==null||typeof r!="object")return this.successResult(r??null);const e=r,t=typeof e.code=="number"?e.code:0;if(t===0){const s="data"in e?e.data:null;return this.successResult(s??null)}const n=typeof e.msg=="string"?e.msg:"\u672A\u77E5\u9519\u8BEF";return this.errorResult(`\u4E0A\u6E38\u9519\u8BEF [code=${t}]: ${n}`)}successResult(r){return{content:[{type:"text",text:JSON.stringify(r)}],isError:!1}}errorResult(r){return{content:[{type:"text",text:r}],isError:!0}}async executeEventTool(r,e,t){return e==="grix_access_control"?this.executeAccessControl(r,t):d(r,e,t)}async executeAccessControl(r,e){const t=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[t];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${t}`);const s={};e.code!=null&&(s.code=e.code),e.sender_id!=null&&(s.sender_id=e.sender_id),e.policy!=null&&(s.policy=e.policy);try{const o=await r.agentInvoke("claude_access_control",{verb:n,payload:s},3e4);return this.successResult(o)}catch(o){const u=o instanceof Error?o.message:String(o);return this.errorResult(`access_control \u8C03\u7528\u5931\u8D25: ${u}`)}}}export{y as ToolExecutorImpl};
@@ -1 +1 @@
1
- import{TOOLS as s,EVENT_TOOLS as t}from"../../core/mcp/tools.js";const e=new Set(["grix_query","grix_group","grix_message_send","grix_message_unsend","grix_admin"]),r=new Set(["grix_reply","grix_complete","grix_event_ack","grix_composing","grix_access_control","grix_status"]);class a{tools;toolMap;constructor(){this.tools=[...s.filter(o=>e.has(o.name)),...t.filter(o=>r.has(o.name))],this.toolMap=new Map(this.tools.map(o=>[o.name,o]))}getTools(){return this.tools}getTool(o){return this.toolMap.get(o)}hasTool(o){return this.toolMap.has(o)}}export{a as ToolRegistryImpl};
1
+ import{TOOLS as o,EVENT_TOOLS as s}from"../../core/mcp/tools.js";const e=new Set(["grix_query","grix_group","grix_message_send","grix_message_unsend","grix_admin"]),r=new Set(["grix_reply","grix_complete","grix_event_ack","grix_composing","grix_access_control","grix_status"]);class a{tools;toolMap;constructor(){this.tools=[...o.filter(t=>e.has(t.name)),...s.filter(t=>r.has(t.name))],this.toolMap=new Map(this.tools.map(t=>[t.name,t]))}getTools(){return this.tools}getTool(t){return this.toolMap.get(t)}hasTool(t){return this.toolMap.has(t)}}export{a as ToolRegistryImpl};
@@ -1 +1 @@
1
- const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(u,t){const e=C[u];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${u}`};for(const i of e.required)if(t[i]===void 0||t[i]===null)return{valid:!1,error:`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${i}`};for(const[i,r]of Object.entries(t)){if(r==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,r,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(u,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${u} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof t=="number"?"\u6D6E\u70B9\u6570":typeof t}`;if(e.minimum!==void 0&&t<e.minimum)return`\u53C2\u6570 ${u} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${u} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${u} \u8D85\u8FC7\u6700\u5927\u5143\u7D20\u6570 ${e.maxItems}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.items)for(let i=0;i<t.length;i++){const r=t[i];if(e.items.type==="string"&&typeof r!="string")return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.type==="integer"){if(typeof r!="number"||!Number.isInteger(r))return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.enum&&!e.items.enum.includes(r))return`\u53C2\u6570 ${u}[${i}] \u503C ${r} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.items.enum.join(", ")}]`}}break}}export{B as validateToolArgs};
1
+ const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(r,t){const e=C[r];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${r}`};for(const i of e.required)if(t[i]===void 0||t[i]===null)return{valid:!1,error:`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${i}`};for(const[i,u]of Object.entries(t)){if(u==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,u,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(r,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof t=="number"?"\u6D6E\u70B9\u6570":typeof t}`;if(e.minimum!==void 0&&t<e.minimum)return`\u53C2\u6570 ${r} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${r} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u5143\u7D20\u6570 ${e.maxItems}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.items)for(let i=0;i<t.length;i++){const u=t[i];if(e.items.type==="string"&&typeof u!="string")return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.type==="integer"){if(typeof u!="number"||!Number.isInteger(u))return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.enum&&!e.items.enum.includes(u))return`\u53C2\u6570 ${r}[${i}] \u503C ${u} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.items.enum.join(", ")}]`}}break}}export{B as validateToolArgs};
@@ -1 +1 @@
1
- import{EventEmitter as S}from"events";import{log as r}from"../core/log/index.js";import{AgentEventType as c}from"../types/events.js";import{mapSessionUpdate as M}from"./event-mapper.js";class p extends Error{authMethods;constructor(e){super("ACP authentication required"),this.name="AcpAuthRequiredError",this.authMethods=e}}function h(l){if(!l||typeof l!="object")return!1;const e=l;return e.code===-32e3?!0:e.code===-32603&&e.data?.details?/\b(401|token\s*expired|access\s*token)\b/i.test(e.data.details):!1}function m(l){return!l||typeof l!="object"?[{id:"oauth"}]:l.data?.authMethods??[{id:"oauth"}]}class u extends S{acpSessionId="";alive=!1;pendingPermissions=new Map;availableModes=[];availableModels=[];currentMode="";currentModel="";listSupported=!1;loadSupported=!1;_supportsCommandsExecute=!1;_availableCommands=[];transport;settleTimer=null;static SETTLE_MS=3e3;pendingToolCallIds=new Set;settleSuppressedSince=0;static SETTLE_SUPPRESS_MAX_MS=900*1e3;constructor(){super(),this.transport=null}get sessionId(){return this.acpSessionId}get isAlive(){return this.alive}get modes(){return[...this.availableModes]}get mode(){return this.currentMode}get models(){return[...this.availableModels]}get model(){return this.currentModel}get sessionOptions(){return{modes:[...this.availableModes],currentModeId:this.currentMode,models:[...this.availableModels],currentModelId:this.currentModel}}get supportsCommandsExecute(){return this._supportsCommandsExecute}get availableCommands(){return[...this._availableCommands]}async connect(e){this.transport=e.transport,this.transport.on("close",()=>{this.alive&&(this.alive=!1,this.emit("session-lost"))}),this.transport.setHandlers((n,a)=>{n==="session/update"?this.handleSessionUpdate(a):n==="_kiro.dev/metadata"?this.handleKiroMetadata(a):n==="_kiro.dev/commands/available"?this.handleCommandsAvailable(a):n==="_kiro.dev/compaction/status"?this.emit("compactionStatus",a):n==="_kiro.dev/clear/status"&&this.emit("clearStatus",a)},(n,a,d)=>{n==="session/request_permission"?this.handlePermissionRequest(a,d):n.startsWith("cursor/")?this.transport.respondSuccess(a,{}).catch(()=>{}):this.transport.respondError(a,-32601,"method not implemented").catch(()=>{})});const t=await this.initialize();this.listSupported=!!t.agentCapabilities?.sessionCapabilities?.list,this.loadSupported=!!t.agentCapabilities?.loadSession;const s=t.agentCapabilities??{};if(this._supportsCommandsExecute=!!(s.extensions?.["_kiro.dev/commands"]||s.commands),e.authMethod)try{await this.transport.call("authenticate",{methodId:e.authMethod})}catch(n){throw h(n)?new p(m(n)):n}const i=e.sessionId&&e.sessionId!=="__continue__";let o=!1;if(i){if(!this.loadSupported)throw new Error(`session/load not supported by agent, cannot resume session ${e.sessionId}`);try{await this.loadSession(e.sessionId,e)&&(o=!0)}catch(n){throw h(n)?new p(m(n)):n}if(!o)throw new Error(`session/load failed for session ${e.sessionId}`)}else try{await this.newSession(e)}catch(n){throw h(n)?new p(m(n)):n}e.initialMode&&await this.setLiveMode(e.initialMode).catch(()=>{}),e.initialModel&&await this.setModel(e.initialModel).catch(()=>{}),this.alive=!0}async initialize(){return await this.transport.call("initialize",{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1},clientInfo:{name:"grix-connector-acp",version:"0.2.0"}})}buildMcpEntries(e){return(e??[]).map(t=>{const s={name:t.name,command:t.command};return t.args&&(s.args=t.args),t.env&&(s.env=Object.entries(t.env).map(([i,o])=>({name:i,value:o}))),s})}async newSession(e){const t=this.buildMcpEntries(e.mcpServers),s={cwd:e.cwd||process.cwd(),mcpServers:t};e.additionalDirectories&&e.additionalDirectories.length>0&&(s.additionalDirectories=e.additionalDirectories);const i=await this.transport.call("session/new",s);if(!i?.sessionId)throw new Error("session/new returned empty sessionId");this.acpSessionId=i.sessionId,this.absorbModes(i.modes),r.info("acp-client",`[handshake] session/new models block: ${JSON.stringify(i.models)}`),this.absorbModels(i.models),this.absorbConfigOptions(i.configOptions)}async loadSession(e,t){const s=this.buildMcpEntries(t.mcpServers),i={sessionId:e,cwd:t.cwd||process.cwd(),mcpServers:s};t.additionalDirectories&&t.additionalDirectories.length>0&&(i.additionalDirectories=t.additionalDirectories);const o=await this.transport.call("session/load",i);return o?.sessionId?(this.acpSessionId=o.sessionId,this.absorbModes(o.modes),r.info("acp-client",`[handshake] session/load models block: ${JSON.stringify(o.models)}`),this.absorbModels(o.models),this.absorbConfigOptions(o.configOptions),!0):o&&(o.modes||o.models||o.configOptions)?(this.acpSessionId=e,this.absorbModes(o.modes),r.info("acp-client",`[handshake] session/load (compat) models block: ${JSON.stringify(o.models)}`),this.absorbModels(o.models),this.absorbConfigOptions(o.configOptions),!0):(r.info("acp-client",`[handshake] session/load returned empty result for ${e}`),this.acpSessionId=e,!0)}absorbModes(e){e?.availableModes?.length&&(this.availableModes=[...e.availableModes],e.currentModeId&&(this.currentMode=e.currentModeId))}absorbConfigOptions(e){if(Array.isArray(e))for(const t of e){const s=t,i=Array.isArray(s?.options)?s.options.filter(n=>typeof n?.value=="string"&&n.value):[];if(i.length===0)continue;const o=s.category||s.id;o==="mode"&&this.availableModes.length===0?(this.availableModes=i.map(n=>({id:n.value,name:n.name||n.value,...n.description?{description:n.description}:{}})),typeof s.currentValue=="string"&&s.currentValue&&(this.currentMode=s.currentValue),r.info("acp-client",`[handshake] absorbConfigOptions modes: count=${this.availableModes.length} ids=${JSON.stringify(this.availableModes.map(n=>n.id))} current=${s.currentValue??"<none>"}`)):o==="model"&&this.availableModels.length===0&&(this.availableModels=i.map(n=>({modelId:n.value,name:n.name||n.value})),typeof s.currentValue=="string"&&s.currentValue&&(this.currentModel=s.currentValue),r.info("acp-client",`[handshake] absorbConfigOptions models: count=${this.availableModels.length} ids=${JSON.stringify(this.availableModels.map(n=>n.modelId))} current=${s.currentValue??"<none>"}`))}}absorbModels(e){if(!e?.availableModels?.length){r.info("acp-client","[handshake] absorbModels skipped: block empty");return}this.availableModels=[...e.availableModels],r.info("acp-client",`[handshake] absorbModels: count=${this.availableModels.length} ids=${JSON.stringify(this.availableModels.map(t=>t.modelId))} current=${e.currentModelId??"<none>"}`),e.currentModelId&&(this.currentModel=e.currentModelId)}async send(e,t,s){if(!this.alive)throw new Error("session not active");if(!this.acpSessionId)throw new Error("no agent session id");const i=[{type:"text",text:e}];if(t)for(const o of t)i.push({type:"image",data:o.data.toString("base64"),mimeType:o.mimeType});this.pendingToolCallIds.clear(),this.settleSuppressedSince=0,await this.transport.call("session/prompt",{sessionId:this.acpSessionId,prompt:i,...this.currentModel?{modelId:this.currentModel}:{}}),this.scheduleSettledResult()}scheduleSettledResult(){this.settleTimer&&clearTimeout(this.settleTimer),this.settleTimer=setTimeout(()=>{if(this.settleTimer=null,!!this.alive){if(this.pendingToolCallIds.size>0){if(this.settleSuppressedSince===0&&(this.settleSuppressedSince=Date.now()),Date.now()-this.settleSuppressedSince<u.SETTLE_SUPPRESS_MAX_MS){r.info("acp-client",`settle suppressed: ${this.pendingToolCallIds.size} pending tool call(s) for session ${this.acpSessionId}`),this.scheduleSettledResult();return}r.warn("acp-client",`settle suppression exceeded ${u.SETTLE_SUPPRESS_MAX_MS/6e4}min with ${this.pendingToolCallIds.size} pending tool call(s), emitting Result anyway`)}this.settleSuppressedSince=0,r.info("acp-client",`settle timer fired, emitting Result for session ${this.acpSessionId}`),this.emit("event",{type:c.Result,sessionId:this.acpSessionId,done:!0})}},u.SETTLE_MS),this.settleTimer.unref()}clearSettleTimer(){this.settleTimer&&(clearTimeout(this.settleTimer),this.settleTimer=null),this.settleSuppressedSince=0}async cancel(){if(this.acpSessionId){this.pendingToolCallIds.clear(),this.settleSuppressedSince=0;try{await this.transport.notify("session/cancel",{sessionId:this.acpSessionId})}catch{}}}async authenticate(e){await this.transport.call("authenticate",{methodId:e})}async respondPermission(e,t){const s=this.pendingPermissions.get(e);if(!s)throw new Error(`unknown permission request: ${e}`);this.pendingPermissions.delete(e);const i=this.pickPermissionOptionId(t.behavior,s.options),o=this.buildPermissionResult(t.behavior,i);await this.transport.respondSuccess(s.rpcId,o)}async respondPermissionOption(e,t){const s=this.pendingPermissions.get(e);if(!s)throw new Error(`unknown permission request: ${e}`);if(!s.options.some(i=>i.optionId===t))throw new Error(`unknown permission option: ${t}`);this.pendingPermissions.delete(e),await this.transport.respondSuccess(s.rpcId,{outcome:{outcome:"selected",optionId:t}})}async ping(e=1e4){if(!this.alive)return!1;try{const t=new AbortController,s=setTimeout(()=>t.abort(),e);return await this.transport.call("session/list",{},t.signal),clearTimeout(s),!0}catch(t){return t?.code===-32601}}async setLiveMode(e){if(!this.acpSessionId)return r.warn("acp-client",`setLiveMode("${e}") skipped: no active session`),!1;const t=this.matchAvailableMode(e);if(!t)return r.warn("acp-client",`setLiveMode("${e}") failed: mode not found in available [${this.availableModes.map(s=>s.id).join(",")}]`),!1;try{const s=new AbortController,i=setTimeout(()=>s.abort(),8e3);return await this.transport.call("session/set_mode",{sessionId:this.acpSessionId,modeId:t},s.signal),clearTimeout(i),this.currentMode=t,!0}catch(s){return r.warn("acp-client",`setLiveMode("${t}") RPC failed: ${s instanceof Error?s.message:s}`),!1}}async setModel(e){if(!this.acpSessionId)return r.warn("acp-client",`setModel("${e}") skipped: no active session`),!1;try{const t=new AbortController,s=setTimeout(()=>t.abort(),8e3);return await this.transport.call("session/set_model",{sessionId:this.acpSessionId,modelId:e},t.signal),clearTimeout(s),this.currentModel=e,!0}catch(t){return r.warn("acp-client",`setModel("${e}") RPC failed: ${t instanceof Error?t.message:t}`),!1}}handleSessionUpdate(e){this.emit("activity");const t=e?.update?.sessionUpdate,s=t==="usage_update";if(t==="tool_call"||t==="tool_call_update"){const o=e?.update??{},n=String(o.toolCallId??""),a=String(o.status??"").toLowerCase().trim();n&&(a==="completed"||a==="failed"?this.pendingToolCallIds.delete(n):t==="tool_call"&&this.pendingToolCallIds.add(n))}this.settleTimer&&!s&&this.scheduleSettledResult();const i=M(this.acpSessionId,e);for(const o of i)o.sessionId||(o.sessionId=this.acpSessionId),o.type===c.Result&&(this.pendingToolCallIds.clear(),this.settleTimer&&this.clearSettleTimer()),this.emit("event",o)}handleKiroMetadata(e){const s=e?.contextUsagePercentage;typeof s!="number"||!Number.isFinite(s)||this.emit("event",{type:c.ContextWindowUpdate,sessionId:this.acpSessionId,contextWindow:{usedPercentage:Math.min(100,Math.max(0,s))}})}handleCommandsAvailable(e){const t=e,s=Array.isArray(t?.commands)?t.commands:[];this._availableCommands=s.map(i=>({name:String(i.name??""),description:i.description?String(i.description):void 0,args:i.args?String(i.args):void 0})),this._supportsCommandsExecute=!0,this.emit("commandsAvailable",this._availableCommands)}async executeCommand(e,t){if(!this.alive)throw new Error("session not active");if(!this.acpSessionId)throw new Error("no agent session id");const s=new AbortController,i=setTimeout(()=>s.abort(),2e4);try{const o=await this.transport.call("_kiro.dev/commands/execute",{sessionId:this.acpSessionId,command:e,...t?{args:t}:{}},s.signal);return clearTimeout(i),{status:o?.status??"ok",message:o?.message,options:o?.options,data:o?.data}}catch(o){clearTimeout(i);const n=o instanceof Error?o.message:String(o);if(o?.code===-32601)throw this._supportsCommandsExecute=!1,o;return{status:"failed",message:n}}}handlePermissionRequest(e,t){const s=t,i=s?.toolCall??{},o=String(e),n=Array.isArray(s?.options)?s.options:[];this.pendingPermissions.set(o,{rpcId:e,options:n});const a=i.title||i.kind||"permission",d=i.toolCallId||o,f=i.title||"",w={type:c.PermissionRequest,requestId:o,toolName:a,toolInput:f||d,sessionId:this.acpSessionId,permissionRequest:{requestId:o,toolCallId:d,toolName:a,toolTitle:f,options:n,rawParams:t}};this.emit("event",w)}matchAvailableMode(e){const t=e.toLowerCase();for(const s of this.availableModes)if(s.id.toLowerCase()===t||s.name.toLowerCase()===t)return s.id;return""}pickPermissionOptionId(e,t){if(t.length===0)return"";if(e==="deny"){for(const i of t)if(i.kind==="reject_once"||i.kind==="reject_always")return i.optionId;for(const i of t)if(i.kind.toLowerCase().includes("reject")||i.kind.toLowerCase().includes("deny"))return i.optionId;for(const i of t)if(i.name.toLowerCase().includes("reject")||i.name.toLowerCase().includes("deny"))return i.optionId;return t[t.length-1].optionId}const s=e==="allow-always"?"allow_always":e==="allow-once"?"allow_once":null;if(s){for(const i of t)if(i.kind===s)return i.optionId}for(const i of t)if(i.kind.toLowerCase().includes("allow"))return i.optionId;for(const i of t)if(i.name.toLowerCase().includes("allow"))return i.optionId;return t[0].optionId}buildPermissionResult(e,t){return e==="deny"?t?{outcome:{outcome:"selected",optionId:t}}:{outcome:{outcome:"cancelled"}}:t?{outcome:{outcome:"selected",optionId:t}}:{outcome:{outcome:"cancelled"}}}}export{p as AcpAuthRequiredError,u as AcpClient,h as isAuthRequiredError};
1
+ import{EventEmitter as S}from"events";import{log as r}from"../core/log/index.js";import{AgentEventType as c}from"../types/events.js";import{mapSessionUpdate as M}from"./event-mapper.js";class p extends Error{authMethods;constructor(e){super("ACP authentication required"),this.name="AcpAuthRequiredError",this.authMethods=e}}function h(l){if(!l||typeof l!="object")return!1;const e=l;return e.code===-32e3?!0:e.code===-32603&&e.data?.details?/\b(401|token\s*expired|access\s*token)\b/i.test(e.data.details):!1}function m(l){return!l||typeof l!="object"?[{id:"oauth"}]:l.data?.authMethods??[{id:"oauth"}]}class u extends S{acpSessionId="";alive=!1;pendingPermissions=new Map;availableModes=[];availableModels=[];currentMode="";currentModel="";listSupported=!1;loadSupported=!1;_supportsCommandsExecute=!1;_availableCommands=[];transport;settleTimer=null;static SETTLE_MS=3e3;pendingToolCallIds=new Set;settleSuppressedSince=0;static SETTLE_SUPPRESS_MAX_MS=900*1e3;constructor(){super(),this.transport=null}get sessionId(){return this.acpSessionId}get isAlive(){return this.alive}get modes(){return[...this.availableModes]}get mode(){return this.currentMode}get models(){return[...this.availableModels]}get model(){return this.currentModel}get sessionOptions(){return{modes:[...this.availableModes],currentModeId:this.currentMode,models:[...this.availableModels],currentModelId:this.currentModel}}get supportsCommandsExecute(){return this._supportsCommandsExecute}get availableCommands(){return[...this._availableCommands]}async connect(e){this.transport=e.transport,this.transport.on("close",()=>{this.alive&&(this.alive=!1,this.emit("session-lost"))}),this.transport.setHandlers((n,a)=>{n==="session/update"?this.handleSessionUpdate(a):n==="_kiro.dev/metadata"?this.handleKiroMetadata(a):n==="_kiro.dev/commands/available"?this.handleCommandsAvailable(a):n==="_kiro.dev/compaction/status"?this.emit("compactionStatus",a):n==="_kiro.dev/clear/status"&&this.emit("clearStatus",a)},(n,a,d)=>{n==="session/request_permission"?this.handlePermissionRequest(a,d):n.startsWith("cursor/")?this.transport.respondSuccess(a,{}).catch(()=>{}):this.transport.respondError(a,-32601,"method not implemented").catch(()=>{})});const t=await this.initialize();this.listSupported=!!t.agentCapabilities?.sessionCapabilities?.list,this.loadSupported=!!t.agentCapabilities?.loadSession;const s=t.agentCapabilities??{};if(this._supportsCommandsExecute=!!(s.extensions?.["_kiro.dev/commands"]||s.commands),e.authMethod)try{await this.transport.call("authenticate",{methodId:e.authMethod})}catch(n){throw h(n)?new p(m(n)):n}const i=e.sessionId&&e.sessionId!=="__continue__";let o=!1;if(i){if(!this.loadSupported)throw new Error(`session/load not supported by agent, cannot resume session ${e.sessionId}`);try{await this.loadSession(e.sessionId,e)&&(o=!0)}catch(n){throw h(n)?new p(m(n)):n}if(!o)throw new Error(`session/load failed for session ${e.sessionId}`)}else try{await this.newSession(e)}catch(n){throw h(n)?new p(m(n)):n}e.initialMode&&await this.setLiveMode(e.initialMode).catch(()=>{}),e.initialModel&&await this.setModel(e.initialModel).catch(()=>{}),this.alive=!0}async initialize(){return await this.transport.call("initialize",{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1},clientInfo:{name:"grix-connector-acp",version:"0.2.0"}})}buildMcpEntries(e){return(e??[]).map(t=>{const s={name:t.name,command:t.command};return t.args&&(s.args=t.args),t.env&&(s.env=Object.entries(t.env).map(([i,o])=>({name:i,value:o}))),s})}async newSession(e){const t=this.buildMcpEntries(e.mcpServers),s={cwd:e.cwd||process.cwd(),mcpServers:t};e.additionalDirectories&&e.additionalDirectories.length>0&&(s.additionalDirectories=e.additionalDirectories);const i=await this.transport.call("session/new",s);if(!i?.sessionId)throw new Error("session/new returned empty sessionId");this.acpSessionId=i.sessionId,this.absorbModes(i.modes),r.info("acp-client",`[handshake] session/new models block: ${JSON.stringify(i.models)}`),this.absorbModels(i.models),this.absorbConfigOptions(i.configOptions)}async loadSession(e,t){const s=this.buildMcpEntries(t.mcpServers),i={sessionId:e,cwd:t.cwd||process.cwd(),mcpServers:s};t.additionalDirectories&&t.additionalDirectories.length>0&&(i.additionalDirectories=t.additionalDirectories);const o=await this.transport.call("session/load",i);return o?.sessionId?(this.acpSessionId=o.sessionId,this.absorbModes(o.modes),r.info("acp-client",`[handshake] session/load models block: ${JSON.stringify(o.models)}`),this.absorbModels(o.models),this.absorbConfigOptions(o.configOptions),!0):o&&(o.modes||o.models||o.configOptions)?(this.acpSessionId=e,this.absorbModes(o.modes),r.info("acp-client",`[handshake] session/load (compat) models block: ${JSON.stringify(o.models)}`),this.absorbModels(o.models),this.absorbConfigOptions(o.configOptions),!0):(r.info("acp-client",`[handshake] session/load returned empty result for ${e}`),this.acpSessionId=e,!0)}absorbModes(e){e?.availableModes?.length&&(this.availableModes=[...e.availableModes],e.currentModeId&&(this.currentMode=e.currentModeId))}absorbConfigOptions(e){if(Array.isArray(e))for(const t of e){const s=t,i=Array.isArray(s?.options)?s.options.filter(n=>typeof n?.value=="string"&&n.value):[];if(i.length===0)continue;const o=s.category||s.id;o==="mode"&&this.availableModes.length===0?(this.availableModes=i.map(n=>({id:n.value,name:n.name||n.value,...n.description?{description:n.description}:{}})),typeof s.currentValue=="string"&&s.currentValue&&(this.currentMode=s.currentValue),r.info("acp-client",`[handshake] absorbConfigOptions modes: count=${this.availableModes.length} ids=${JSON.stringify(this.availableModes.map(n=>n.id))} current=${s.currentValue??"<none>"}`)):o==="model"&&this.availableModels.length===0&&(this.availableModels=i.map(n=>({modelId:n.value,name:n.name||n.value})),typeof s.currentValue=="string"&&s.currentValue&&(this.currentModel=s.currentValue),r.info("acp-client",`[handshake] absorbConfigOptions models: count=${this.availableModels.length} ids=${JSON.stringify(this.availableModels.map(n=>n.modelId))} current=${s.currentValue??"<none>"}`))}}absorbModels(e){if(!e?.availableModels?.length){r.info("acp-client","[handshake] absorbModels skipped: block empty");return}this.availableModels=[...e.availableModels],r.info("acp-client",`[handshake] absorbModels: count=${this.availableModels.length} ids=${JSON.stringify(this.availableModels.map(t=>t.modelId))} current=${e.currentModelId??"<none>"}`),e.currentModelId&&(this.currentModel=e.currentModelId)}async send(e,t,s){if(!this.alive)throw new Error("session not active");if(!this.acpSessionId)throw new Error("no agent session id");const i=[{type:"text",text:e}];if(t)for(const o of t)i.push({type:"image",data:o.data.toString("base64"),mimeType:o.mimeType});this.pendingToolCallIds.clear(),this.settleSuppressedSince=0,await this.transport.call("session/prompt",{sessionId:this.acpSessionId,prompt:i,...this.currentModel?{modelId:this.currentModel}:{}}),this.scheduleSettledResult()}scheduleSettledResult(){this.settleTimer&&clearTimeout(this.settleTimer),this.settleTimer=setTimeout(()=>{if(this.settleTimer=null,!!this.alive){if(this.pendingToolCallIds.size>0){if(this.settleSuppressedSince===0&&(this.settleSuppressedSince=Date.now()),Date.now()-this.settleSuppressedSince<u.SETTLE_SUPPRESS_MAX_MS){r.info("acp-client",`settle suppressed: ${this.pendingToolCallIds.size} pending tool call(s) for session ${this.acpSessionId}`),this.scheduleSettledResult();return}r.warn("acp-client",`settle suppression exceeded ${u.SETTLE_SUPPRESS_MAX_MS/6e4}min with ${this.pendingToolCallIds.size} pending tool call(s), emitting Result anyway`)}this.settleSuppressedSince=0,r.info("acp-client",`settle timer fired, emitting Result for session ${this.acpSessionId}`),this.emit("event",{type:c.Result,sessionId:this.acpSessionId,done:!0,synthetic:!0})}},u.SETTLE_MS),this.settleTimer.unref()}deferSettledResult(){this.scheduleSettledResult()}clearSettleTimer(){this.settleTimer&&(clearTimeout(this.settleTimer),this.settleTimer=null),this.settleSuppressedSince=0}async cancel(){if(this.acpSessionId){this.pendingToolCallIds.clear(),this.settleSuppressedSince=0;try{await this.transport.notify("session/cancel",{sessionId:this.acpSessionId})}catch{}}}async authenticate(e){await this.transport.call("authenticate",{methodId:e})}async respondPermission(e,t){const s=this.pendingPermissions.get(e);if(!s)throw new Error(`unknown permission request: ${e}`);this.pendingPermissions.delete(e);const i=this.pickPermissionOptionId(t.behavior,s.options),o=this.buildPermissionResult(t.behavior,i);await this.transport.respondSuccess(s.rpcId,o)}async respondPermissionOption(e,t){const s=this.pendingPermissions.get(e);if(!s)throw new Error(`unknown permission request: ${e}`);if(!s.options.some(i=>i.optionId===t))throw new Error(`unknown permission option: ${t}`);this.pendingPermissions.delete(e),await this.transport.respondSuccess(s.rpcId,{outcome:{outcome:"selected",optionId:t}})}async ping(e=1e4){if(!this.alive)return!1;try{const t=new AbortController,s=setTimeout(()=>t.abort(),e);return await this.transport.call("session/list",{},t.signal),clearTimeout(s),!0}catch(t){return t?.code===-32601}}async setLiveMode(e){if(!this.acpSessionId)return r.warn("acp-client",`setLiveMode("${e}") skipped: no active session`),!1;const t=this.matchAvailableMode(e);if(!t)return r.warn("acp-client",`setLiveMode("${e}") failed: mode not found in available [${this.availableModes.map(s=>s.id).join(",")}]`),!1;try{const s=new AbortController,i=setTimeout(()=>s.abort(),8e3);return await this.transport.call("session/set_mode",{sessionId:this.acpSessionId,modeId:t},s.signal),clearTimeout(i),this.currentMode=t,!0}catch(s){return r.warn("acp-client",`setLiveMode("${t}") RPC failed: ${s instanceof Error?s.message:s}`),!1}}async setModel(e){if(!this.acpSessionId)return r.warn("acp-client",`setModel("${e}") skipped: no active session`),!1;try{const t=new AbortController,s=setTimeout(()=>t.abort(),8e3);return await this.transport.call("session/set_model",{sessionId:this.acpSessionId,modelId:e},t.signal),clearTimeout(s),this.currentModel=e,!0}catch(t){return r.warn("acp-client",`setModel("${e}") RPC failed: ${t instanceof Error?t.message:t}`),!1}}handleSessionUpdate(e){this.emit("activity");const t=e?.update?.sessionUpdate,s=t==="usage_update";if(t==="tool_call"||t==="tool_call_update"){const o=e?.update??{},n=String(o.toolCallId??""),a=String(o.status??"").toLowerCase().trim();n&&(a==="completed"||a==="failed"?this.pendingToolCallIds.delete(n):t==="tool_call"&&this.pendingToolCallIds.add(n))}this.settleTimer&&!s&&this.scheduleSettledResult();const i=M(this.acpSessionId,e);for(const o of i)o.sessionId||(o.sessionId=this.acpSessionId),o.type===c.Result&&(this.pendingToolCallIds.clear(),this.settleTimer&&this.clearSettleTimer()),this.emit("event",o)}handleKiroMetadata(e){const s=e?.contextUsagePercentage;typeof s!="number"||!Number.isFinite(s)||this.emit("event",{type:c.ContextWindowUpdate,sessionId:this.acpSessionId,contextWindow:{usedPercentage:Math.min(100,Math.max(0,s))}})}handleCommandsAvailable(e){const t=e,s=Array.isArray(t?.commands)?t.commands:[];this._availableCommands=s.map(i=>({name:String(i.name??""),description:i.description?String(i.description):void 0,args:i.args?String(i.args):void 0})),this._supportsCommandsExecute=!0,this.emit("commandsAvailable",this._availableCommands)}async executeCommand(e,t){if(!this.alive)throw new Error("session not active");if(!this.acpSessionId)throw new Error("no agent session id");const s=new AbortController,i=setTimeout(()=>s.abort(),2e4);try{const o=await this.transport.call("_kiro.dev/commands/execute",{sessionId:this.acpSessionId,command:e,...t?{args:t}:{}},s.signal);return clearTimeout(i),{status:o?.status??"ok",message:o?.message,options:o?.options,data:o?.data}}catch(o){clearTimeout(i);const n=o instanceof Error?o.message:String(o);if(o?.code===-32601)throw this._supportsCommandsExecute=!1,o;return{status:"failed",message:n}}}handlePermissionRequest(e,t){const s=t,i=s?.toolCall??{},o=String(e),n=Array.isArray(s?.options)?s.options:[];this.pendingPermissions.set(o,{rpcId:e,options:n});const a=i.title||i.kind||"permission",d=i.toolCallId||o,f=i.title||"",w={type:c.PermissionRequest,requestId:o,toolName:a,toolInput:f||d,sessionId:this.acpSessionId,permissionRequest:{requestId:o,toolCallId:d,toolName:a,toolTitle:f,options:n,rawParams:t}};this.emit("event",w)}matchAvailableMode(e){const t=e.toLowerCase();for(const s of this.availableModes)if(s.id.toLowerCase()===t||s.name.toLowerCase()===t)return s.id;return""}pickPermissionOptionId(e,t){if(t.length===0)return"";if(e==="deny"){for(const i of t)if(i.kind==="reject_once"||i.kind==="reject_always")return i.optionId;for(const i of t)if(i.kind.toLowerCase().includes("reject")||i.kind.toLowerCase().includes("deny"))return i.optionId;for(const i of t)if(i.name.toLowerCase().includes("reject")||i.name.toLowerCase().includes("deny"))return i.optionId;return t[t.length-1].optionId}const s=e==="allow-always"?"allow_always":e==="allow-once"?"allow_once":null;if(s){for(const i of t)if(i.kind===s)return i.optionId}for(const i of t)if(i.kind.toLowerCase().includes("allow"))return i.optionId;for(const i of t)if(i.name.toLowerCase().includes("allow"))return i.optionId;return t[0].optionId}buildPermissionResult(e,t){return e==="deny"?t?{outcome:{outcome:"selected",optionId:t}}:{outcome:{outcome:"cancelled"}}:t?{outcome:{outcome:"selected",optionId:t}}:{outcome:{outcome:"cancelled"}}}}export{p as AcpAuthRequiredError,u as AcpClient,h as isAuthRequiredError};
@@ -2898,7 +2898,8 @@ function isWindowsAbsolutePath(p) {
2898
2898
  }
2899
2899
 
2900
2900
  // src/core/util/codex-output-policy.ts
2901
- var DEFAULT_VISIBLE_PHASES = Object.freeze(["commentary", "final_answer"]);
2901
+ var DEFAULT_VISIBLE_PHASES = Object.freeze(["final_answer"]);
2902
+ var DEFAULT_THINKING_PHASES = Object.freeze(["commentary"]);
2902
2903
  var EMPTY_PHASES = Object.freeze([]);
2903
2904
  function parsePhaseEnvVar(envValue) {
2904
2905
  if (!envValue || !envValue.trim()) return EMPTY_PHASES;
@@ -2911,6 +2912,7 @@ function loadVisiblePhases() {
2911
2912
  }
2912
2913
  var USER_VISIBLE_AGENT_MESSAGE_PHASES = loadVisiblePhases();
2913
2914
  var USER_HIDDEN_AGENT_MESSAGE_PHASES = parsePhaseEnvVar(process.env.CODEX_HIDDEN_PHASES);
2915
+ var USER_THINKING_AGENT_MESSAGE_PHASES = parsePhaseEnvVar(process.env.CODEX_THINKING_PHASES);
2914
2916
 
2915
2917
  // src/core/util/host-info.ts
2916
2918
  import os3 from "node:os";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grix-connector",
3
- "version": "3.28.0",
3
+ "version": "3.29.0",
4
4
  "description": "Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,6 +39,7 @@
39
39
  "test:e2e:codex-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/codex-audit-replay.test.ts",
40
40
  "test:e2e:native-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/native-event-audit-replay.test.ts",
41
41
  "test:e2e:kimi-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/native-event-audit-replay.test.ts -t \"kimi:\"",
42
+ "test:e2e:kimi-question": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/kimi-acp-features.test.ts -t \"问答卡文本回执\"",
42
43
  "test:e2e:pi-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/pi-audit-replay.test.ts",
43
44
  "test:e2e:reasonix-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/reasonix-audit-replay.test.ts",
44
45
  "test:e2e:codewhale-audit": "RUN_REAL_AGENT_E2E=1 node --experimental-vm-modules node_modules/vitest/vitest.mjs run tests/e2e/codewhale-audit-replay.test.ts",