@dotobokuri/fleet-console 1.45.0 → 1.46.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 (68) hide show
  1. package/dist/cli.d.ts +4 -0
  2. package/dist/cli.mjs +416 -899
  3. package/dist/client/assets/{_baseUniq-DtJH2bh8.js → _baseUniq-CaqaUUIT.js} +1 -1
  4. package/dist/client/assets/{arc-DHCKMqqF.js → arc-B4MjkR5w.js} +1 -1
  5. package/dist/client/assets/{architectureDiagram-Q4EWVU46-BOuyINL8.js → architectureDiagram-Q4EWVU46-wP-4WWY-.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-DXYQGD6D-cIre3_5n.js → blockDiagram-DXYQGD6D-D5Y2AdkX.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-AHTNJAMY-DTX-qjSW.js → c4Diagram-AHTNJAMY-hKNJrUod.js} +1 -1
  8. package/dist/client/assets/channel-Cy7Wdt-y.js +1 -0
  9. package/dist/client/assets/{chunk-4BX2VUAB-DiBwpozK.js → chunk-4BX2VUAB-RdaAserw.js} +1 -1
  10. package/dist/client/assets/{chunk-4TB4RGXK-uCZ-B3-y.js → chunk-4TB4RGXK-BVvGheRq.js} +1 -1
  11. package/dist/client/assets/{chunk-55IACEB6-CmBu2sf0.js → chunk-55IACEB6-BKBu793s.js} +1 -1
  12. package/dist/client/assets/{chunk-EDXVE4YY-BXpw2VyB.js → chunk-EDXVE4YY-CF6P1HJI.js} +1 -1
  13. package/dist/client/assets/{chunk-FMBD7UC4-Cn9sKTn5.js → chunk-FMBD7UC4-DYrffXxC.js} +1 -1
  14. package/dist/client/assets/{chunk-OYMX7WX6-BDgH1zlW.js → chunk-OYMX7WX6-ggkv39bf.js} +1 -1
  15. package/dist/client/assets/{chunk-QZHKN3VN-BOdvRibu.js → chunk-QZHKN3VN-DfsoMKS1.js} +1 -1
  16. package/dist/client/assets/{chunk-YZCP3GAM-BDIEapcU.js → chunk-YZCP3GAM-nK3fd1vK.js} +1 -1
  17. package/dist/client/assets/classDiagram-6PBFFD2Q-BXKZy3mo.js +1 -0
  18. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BXKZy3mo.js +1 -0
  19. package/dist/client/assets/clone-BaDkZwuY.js +1 -0
  20. package/dist/client/assets/{cose-bilkent-S5V4N54A-BVlc3Dad.js → cose-bilkent-S5V4N54A-BXTuHPIj.js} +1 -1
  21. package/dist/client/assets/{dagre-KV5264BT-raV4BK6w.js → dagre-KV5264BT-Bz4nIBUS.js} +1 -1
  22. package/dist/client/assets/{diagram-5BDNPKRD-BMAh1LJt.js → diagram-5BDNPKRD-ByqgG2sy.js} +1 -1
  23. package/dist/client/assets/{diagram-G4DWMVQ6-AM5t2f3j.js → diagram-G4DWMVQ6-D6Bh5CCC.js} +1 -1
  24. package/dist/client/assets/{diagram-MMDJMWI5-DMw_UwWR.js → diagram-MMDJMWI5-CfDQLuVW.js} +1 -1
  25. package/dist/client/assets/{diagram-TYMM5635-CiDAD3e9.js → diagram-TYMM5635-KI98IUyc.js} +1 -1
  26. package/dist/client/assets/{erDiagram-SMLLAGMA-D1IXSwFZ.js → erDiagram-SMLLAGMA-CqprUEiC.js} +1 -1
  27. package/dist/client/assets/{flowDiagram-DWJPFMVM-pEq1L6HP.js → flowDiagram-DWJPFMVM-ABvSPDqG.js} +1 -1
  28. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BAXTU16v.js → ganttDiagram-T4ZO3ILL-Dsx-U_Nn.js} +1 -1
  29. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-PkEvpSio.js → gitGraphDiagram-UUTBAWPF-BSUFEUnR.js} +1 -1
  30. package/dist/client/assets/{graph-OOLam9NE.js → graph-CzNfjcWq.js} +1 -1
  31. package/dist/client/assets/index-DJz5h6Wn.js +482 -0
  32. package/dist/client/assets/index-DuMyAui7.css +1 -0
  33. package/dist/client/assets/{infoDiagram-42DDH7IO-CcLveXnw.js → infoDiagram-42DDH7IO-Ds0ENS7R.js} +1 -1
  34. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-D-p_eX0W.js → ishikawaDiagram-UXIWVN3A-B18YRUdD.js} +1 -1
  35. package/dist/client/assets/{journeyDiagram-VCZTEJTY-D81ht6ZY.js → journeyDiagram-VCZTEJTY-BupFc-Zd.js} +1 -1
  36. package/dist/client/assets/{kanban-definition-6JOO6SKY-D8SIIBWy.js → kanban-definition-6JOO6SKY-BSLofAt_.js} +1 -1
  37. package/dist/client/assets/{layout-CeMy87tl.js → layout-Dv50_a5m.js} +1 -1
  38. package/dist/client/assets/{linear-C0Txkuhf.js → linear-BrKghOcX.js} +1 -1
  39. package/dist/client/assets/{mermaid.core-zdTcCzmD.js → mermaid.core-CxEBNiNY.js} +4 -4
  40. package/dist/client/assets/{min-BPp_9Vnv.js → min-CCGzVC9y.js} +1 -1
  41. package/dist/client/assets/{mindmap-definition-QFDTVHPH-DRJbMf8W.js → mindmap-definition-QFDTVHPH-BrgndQgy.js} +1 -1
  42. package/dist/client/assets/{pieDiagram-DEJITSTG-CqPISwE-.js → pieDiagram-DEJITSTG-DaQb845q.js} +1 -1
  43. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-BGLaujDD.js → quadrantDiagram-34T5L4WZ-BKqKJrUA.js} +1 -1
  44. package/dist/client/assets/{requirementDiagram-MS252O5E-DWF6sFQ_.js → requirementDiagram-MS252O5E-DDEiXfFB.js} +1 -1
  45. package/dist/client/assets/{sankeyDiagram-XADWPNL6-Dv2O23aj.js → sankeyDiagram-XADWPNL6-Bz8ZuIVc.js} +1 -1
  46. package/dist/client/assets/{sequenceDiagram-FGHM5R23-BXgYtweg.js → sequenceDiagram-FGHM5R23-DIKllaFC.js} +1 -1
  47. package/dist/client/assets/{stateDiagram-FHFEXIEX-COtDK2gC.js → stateDiagram-FHFEXIEX-DVGXi05S.js} +1 -1
  48. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BpjJbYdv.js +1 -0
  49. package/dist/client/assets/{timeline-definition-GMOUNBTQ-B_-QYLHK.js → timeline-definition-GMOUNBTQ-BysxZqEH.js} +1 -1
  50. package/dist/client/assets/{vennDiagram-DHZGUBPP-BNVDRgAa.js → vennDiagram-DHZGUBPP-zKrKFH0U.js} +1 -1
  51. package/dist/client/assets/{wardley-RL74JXVD-B3XwoW1A.js → wardley-RL74JXVD-Bfs1dQE_.js} +1 -1
  52. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-B6-OKLa-.js → wardleyDiagram-NUSXRM2D-9Nv_Fl4e.js} +1 -1
  53. package/dist/client/assets/{xychartDiagram-5P7HB3ND-DepfDqrZ.js → xychartDiagram-5P7HB3ND-BxnDNWHU.js} +1 -1
  54. package/dist/client/index.html +2 -2
  55. package/dist/fleet-plugins/ledger/routes.mjs +45 -105
  56. package/dist/fleet-plugins/quota/routes.mjs +455 -64
  57. package/dist/fleet-plugins/repository/routes.mjs +26 -9
  58. package/dist/fleet-plugins/scuttlebutt/routes.mjs +150 -703
  59. package/dist/fleet-plugins/skills/routes.mjs +45 -105
  60. package/dist/fleet-plugins/terminal/routes.mjs +1297 -975
  61. package/package.json +1 -1
  62. package/dist/client/assets/channel-BhciS8jR.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-BjRUnHce.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BjRUnHce.js +0 -1
  65. package/dist/client/assets/clone-DygBt67n.js +0 -1
  66. package/dist/client/assets/index-BgHFwZy9.css +0 -1
  67. package/dist/client/assets/index-CvXOp1di.js +0 -452
  68. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BzCFtEfV.js +0 -1
package/dist/cli.mjs CHANGED
@@ -31899,225 +31899,6 @@ function inferBinName(packageName) {
31899
31899
  return lastSegment.replace(/@[^@/]+$/, "");
31900
31900
  }
31901
31901
 
31902
- // ../../packages/core-unified-agent/models.json
31903
- var models_default = {
31904
- version: 1,
31905
- updatedAt: "2026-07-25T00:00:00Z",
31906
- providers: {
31907
- claude: {
31908
- name: "Claude Code",
31909
- defaultModel: "opus[1m]",
31910
- models: [
31911
- { modelId: "haiku", name: "Claude Haiku", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "low" } },
31912
- { modelId: "sonnet", name: "Claude Sonnet", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31913
- { modelId: "opus", name: "Claude Opus", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31914
- { modelId: "opus[1m]", name: "Claude Opus [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31915
- { modelId: "claude-opus-4-6[1m]", name: "Claude Opus 4.6 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31916
- { modelId: "claude-opus-4-7[1m]", name: "Claude Opus 4.7 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31917
- { modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
31918
- ]
31919
- },
31920
- codex: {
31921
- name: "Codex",
31922
- defaultModel: "gpt-5.6-sol",
31923
- models: [
31924
- { modelId: "gpt-5.6-sol", name: "GPT-5.6-Sol", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
31925
- { modelId: "gpt-5.6-sol-fast", name: "GPT-5.6-Sol Fast", providerModelId: "gpt-5.6-sol", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
31926
- { modelId: "gpt-5.6-terra", name: "GPT-5.6-Terra", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
31927
- { modelId: "gpt-5.6-terra-fast", name: "GPT-5.6-Terra Fast", providerModelId: "gpt-5.6-terra", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
31928
- { modelId: "gpt-5.6-luna", name: "GPT-5.6-Luna", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31929
- { modelId: "gpt-5.6-luna-fast", name: "GPT-5.6-Luna Fast", providerModelId: "gpt-5.6-luna", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31930
- { modelId: "gpt-5.5", name: "GPT-5.5", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
31931
- { modelId: "gpt-5.5-fast", name: "GPT-5.5 Fast", providerModelId: "gpt-5.5", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
31932
- ]
31933
- },
31934
- cursor: {
31935
- name: "Cursor Agent",
31936
- defaultModel: "auto",
31937
- models: [
31938
- { modelId: "auto", name: "Auto", effort: { supported: false } },
31939
- { modelId: "composer-2.5", name: "Composer 2.5", effort: { supported: false } },
31940
- { modelId: "composer-2.5-fast", name: "Composer 2.5 Fast", effort: { supported: false } },
31941
- { modelId: "gpt-5.6-sol", name: "GPT-5.6 Sol", spawnModelTemplate: "gpt-5.6-sol-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31942
- { modelId: "gpt-5.6-sol-fast", name: "GPT-5.6 Sol Fast", spawnModelTemplate: "gpt-5.6-sol-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31943
- { modelId: "gpt-5.6-sol-none", name: "GPT-5.6 Sol None", effort: { supported: false } },
31944
- { modelId: "gpt-5.6-sol-none-fast", name: "GPT-5.6 Sol None Fast", effort: { supported: false } },
31945
- { modelId: "gpt-5.6-luna", name: "GPT-5.6 Luna", spawnModelTemplate: "gpt-5.6-luna-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31946
- { modelId: "gpt-5.6-luna-fast", name: "GPT-5.6 Luna Fast", spawnModelTemplate: "gpt-5.6-luna-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31947
- { modelId: "gpt-5.6-luna-none", name: "GPT-5.6 Luna None", effort: { supported: false } },
31948
- { modelId: "gpt-5.6-luna-none-fast", name: "GPT-5.6 Luna None Fast", effort: { supported: false } },
31949
- { modelId: "gpt-5.6-terra", name: "GPT-5.6 Terra", spawnModelTemplate: "gpt-5.6-terra-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31950
- { modelId: "gpt-5.6-terra-fast", name: "GPT-5.6 Terra Fast", spawnModelTemplate: "gpt-5.6-terra-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
31951
- { modelId: "gpt-5.6-terra-none", name: "GPT-5.6 Terra None", effort: { supported: false } },
31952
- { modelId: "gpt-5.6-terra-none-fast", name: "GPT-5.6 Terra None Fast", effort: { supported: false } },
31953
- { modelId: "cursor-grok-4.5", name: "Cursor Grok 4.5", spawnModelTemplate: "cursor-grok-4.5-{effort}", effort: { supported: true, levels: ["low", "medium", "high"], default: "high" } },
31954
- { modelId: "cursor-grok-4.5-fast", name: "Cursor Grok 4.5 Fast", spawnModelTemplate: "cursor-grok-4.5-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high"], default: "high" } },
31955
- { modelId: "claude-opus-4-8", name: "Claude Opus 4.8", spawnModelTemplate: "claude-opus-4-8-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31956
- { modelId: "claude-opus-4-8-fast", name: "Claude Opus 4.8 Fast", spawnModelTemplate: "claude-opus-4-8-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31957
- { modelId: "claude-opus-4-8-thinking", name: "Claude Opus 4.8 Thinking", spawnModelTemplate: "claude-opus-4-8-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31958
- { modelId: "claude-opus-4-8-thinking-fast", name: "Claude Opus 4.8 Thinking Fast", spawnModelTemplate: "claude-opus-4-8-thinking-{effort}-fast", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31959
- { modelId: "claude-sonnet-5", name: "Claude Sonnet 5", spawnModelTemplate: "claude-sonnet-5-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31960
- { modelId: "claude-sonnet-5-thinking", name: "Claude Sonnet 5 Thinking", spawnModelTemplate: "claude-sonnet-5-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31961
- { modelId: "claude-fable-5", name: "Claude Fable 5", description: "NO ZDR per cursor-agent model list", spawnModelTemplate: "claude-fable-5-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
31962
- { modelId: "claude-fable-5-thinking", name: "Claude Fable 5 Thinking", description: "NO ZDR per cursor-agent model list", spawnModelTemplate: "claude-fable-5-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
31963
- { modelId: "gemini-3.1-pro", name: "Gemini 3.1 Pro", effort: { supported: false } },
31964
- { modelId: "gemini-3.5-flash", name: "Gemini 3.5 Flash", effort: { supported: false } },
31965
- { modelId: "kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } },
31966
- { modelId: "glm-5.2", name: "GLM 5.2", spawnModelTemplate: "glm-5.2-{effort}", effort: { supported: true, levels: ["high", "max"], default: "max" } }
31967
- ]
31968
- }
31969
- }
31970
- };
31971
-
31972
- // ../../packages/core-unified-agent/src/models/registry.ts
31973
- var EffortLevelSchema = external_exports.enum([
31974
- "low",
31975
- "medium",
31976
- "high",
31977
- "xhigh",
31978
- "max",
31979
- "ultra"
31980
- ]);
31981
- var EffortSchema = external_exports.union([
31982
- external_exports.object({
31983
- supported: external_exports.literal(true),
31984
- levels: external_exports.array(EffortLevelSchema).min(1),
31985
- default: EffortLevelSchema
31986
- }).strict(),
31987
- external_exports.object({
31988
- supported: external_exports.literal(false)
31989
- }).strict()
31990
- ]);
31991
- var ModelEntrySchema = external_exports.object({
31992
- /** 모델 고유 식별자 (session/set_model에 전달되는 값) */
31993
- modelId: external_exports.string(),
31994
- /** 사람이 읽을 수 있는 모델 이름 */
31995
- name: external_exports.string(),
31996
- /** 모델 설명 (선택) */
31997
- description: external_exports.string().optional(),
31998
- /** spawn 시 실제 CLI 모델 ID를 조립해야 하는 경우의 템플릿 */
31999
- spawnModelTemplate: external_exports.string().optional(),
32000
- /** 카탈로그 ID와 실제 provider 모델 ID가 다른 경우의 원본 모델 ID */
32001
- providerModelId: external_exports.string().optional(),
32002
- /** provider가 모델과 별도로 받는 서비스 티어 */
32003
- serviceTier: external_exports.string().optional(),
32004
- /** 모델의 컨텍스트 윈도우 크기 (토큰) */
32005
- contextWindow: external_exports.number().int().positive().optional(),
32006
- /** 모델별 effort 설정 */
32007
- effort: EffortSchema
32008
- }).check((ctx) => {
32009
- const effort = ctx.value.effort;
32010
- if (effort.supported && !effort.levels.includes(effort.default)) {
32011
- ctx.issues.push({
32012
- code: "custom",
32013
- input: effort.default,
32014
- message: `effort.default "${effort.default}"\uC740(\uB294) levels \uBAA9\uB85D\uC5D0 \uC874\uC7AC\uD574\uC57C \uD569\uB2C8\uB2E4`,
32015
- path: ["effort", "default"]
32016
- });
32017
- }
32018
- if (effort.supported && ctx.value.spawnModelTemplate && !ctx.value.spawnModelTemplate.includes("{effort}")) {
32019
- ctx.issues.push({
32020
- code: "custom",
32021
- input: ctx.value.spawnModelTemplate,
32022
- message: 'effort \uC9C0\uC6D0 \uBAA8\uB378\uC758 spawnModelTemplate\uC740 "{effort}" \uD50C\uB808\uC774\uC2A4\uD640\uB354\uB97C \uD3EC\uD568\uD574\uC57C \uD569\uB2C8\uB2E4',
32023
- path: ["spawnModelTemplate"]
32024
- });
32025
- }
32026
- if (ctx.value.serviceTier && !ctx.value.providerModelId) {
32027
- ctx.issues.push({
32028
- code: "custom",
32029
- input: ctx.value.serviceTier,
32030
- message: "serviceTier\uB97C \uC9C0\uC815\uD55C \uBAA8\uB378\uC740 providerModelId\uB3C4 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4",
32031
- path: ["serviceTier"]
32032
- });
32033
- }
32034
- });
32035
- var ProviderSchema = external_exports.object({
32036
- /** 프로바이더 표시 이름 */
32037
- name: external_exports.string(),
32038
- /** 기본 모델 ID */
32039
- defaultModel: external_exports.string(),
32040
- /** 사용 가능한 모델 목록 */
32041
- models: external_exports.array(ModelEntrySchema).min(1)
32042
- }).check((ctx) => {
32043
- const ids = new Set(ctx.value.models.map((m) => m.modelId));
32044
- if (!ids.has(ctx.value.defaultModel)) {
32045
- ctx.issues.push({
32046
- code: "custom",
32047
- input: ctx.value.defaultModel,
32048
- message: `defaultModel "${ctx.value.defaultModel}"\uC740(\uB294) models \uBAA9\uB85D\uC5D0 \uC874\uC7AC\uD574\uC57C \uD569\uB2C8\uB2E4`,
32049
- path: ["defaultModel"]
32050
- });
32051
- }
32052
- });
32053
- var ModelMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
32054
- var ModelsMapperEntrySchema = external_exports.object({
32055
- /** modelId와 연관된 매핑 모델 */
32056
- modelMapping: ModelMappingSchema,
32057
- /** 추가 환경변수 (선택) */
32058
- env: external_exports.record(external_exports.string(), external_exports.string()).optional()
32059
- });
32060
- external_exports.record(external_exports.string(), ModelsMapperEntrySchema);
32061
- var ModelsRegistrySchema = external_exports.object({
32062
- /** 스키마 버전 */
32063
- version: external_exports.number().int().positive(),
32064
- /** 최종 업데이트 시각 */
32065
- updatedAt: external_exports.string(),
32066
- /** 프로바이더별 모델 정보 */
32067
- providers: external_exports.record(external_exports.string(), ProviderSchema)
32068
- });
32069
- var registry2 = Object.freeze(ModelsRegistrySchema.parse(models_default));
32070
- function getProviderModels(cli) {
32071
- const provider = registry2.providers[cli];
32072
- if (!provider) {
32073
- throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
32074
- }
32075
- return structuredClone(provider);
32076
- }
32077
- function getEffort(cli, modelId) {
32078
- const model = findProviderModel(cli, modelId);
32079
- return structuredClone(model.effort);
32080
- }
32081
- function getCursorSpawnEffortInfo(modelId) {
32082
- const model = findProviderModel("cursor", modelId);
32083
- if (!model.spawnModelTemplate || !model.effort.supported) {
32084
- return { supported: false, levels: [], default: null };
32085
- }
32086
- return {
32087
- supported: true,
32088
- levels: [...model.effort.levels],
32089
- default: model.effort.default
32090
- };
32091
- }
32092
- function resolveCursorSpawnModel(modelId, effort) {
32093
- const model = findProviderModel("cursor", modelId);
32094
- if (!model.spawnModelTemplate) {
32095
- return model.modelId;
32096
- }
32097
- if (!model.effort.supported) {
32098
- return model.spawnModelTemplate;
32099
- }
32100
- const level = effort ?? model.effort.default;
32101
- const resolvedLevel = model.effort.levels.includes(level) ? level : model.effort.default;
32102
- if (!model.effort.levels.includes(resolvedLevel)) {
32103
- throw new Error(
32104
- `cursor/${modelId} \uBAA8\uB378\uC740 effort "${level}"\uC744(\uB97C) \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9 \uAC00\uB2A5: ${model.effort.levels.join(", ")}`
32105
- );
32106
- }
32107
- return model.spawnModelTemplate.replace("{effort}", resolvedLevel);
32108
- }
32109
- function findProviderModel(cli, modelId) {
32110
- const provider = registry2.providers[cli];
32111
- if (!provider) {
32112
- throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
32113
- }
32114
- const model = provider.models.find((m) => m.modelId === modelId);
32115
- if (!model) {
32116
- throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uBAA8\uB378: "${cli}/${modelId}"`);
32117
- }
32118
- return model;
32119
- }
32120
-
32121
31902
  // ../../packages/core-unified-agent/src/config/CliConfigs.ts
32122
31903
  var CLI_BACKENDS = {
32123
31904
  claude: {
@@ -32153,21 +31934,6 @@ var CLI_BACKENDS = {
32153
31934
  requiresModelAtSpawn: false,
32154
31935
  usesNpxBridge: false,
32155
31936
  defaultMaxTokens: 1e5
32156
- },
32157
- cursor: {
32158
- id: "cursor",
32159
- cliCommand: "cursor-agent",
32160
- protocol: "acp",
32161
- authRequired: true,
32162
- acpArgs: ["acp"],
32163
- modes: [
32164
- { id: "agent", label: "Agent" }
32165
- ],
32166
- supportsSessionClose: false,
32167
- supportsSessionLoad: true,
32168
- requiresModelAtSpawn: true,
32169
- usesNpxBridge: false,
32170
- defaultMaxTokens: 2e5
32171
31937
  }
32172
31938
  };
32173
31939
  function createSpawnConfig(cli, options) {
@@ -32198,9 +31964,6 @@ function createSpawnConfig(cli, options) {
32198
31964
  }
32199
31965
  const command2 = options.cliPath ?? backend.cliCommand;
32200
31966
  const args = backend.acpArgs ? [...backend.acpArgs] : [];
32201
- if (cli === "cursor" && options.model) {
32202
- args.unshift("--model", resolveCursorSpawnModel(options.model, options.effort));
32203
- }
32204
31967
  return {
32205
31968
  command: command2,
32206
31969
  args,
@@ -32214,8 +31977,6 @@ function getYoloModeId(cli) {
32214
31977
  switch (cli) {
32215
31978
  case "claude":
32216
31979
  return "bypassPermissions";
32217
- case "cursor":
32218
- return "agent";
32219
31980
  case "codex":
32220
31981
  return "yolo";
32221
31982
  }
@@ -32417,61 +32178,207 @@ var CliDetector = class {
32417
32178
  }
32418
32179
  };
32419
32180
 
32420
- // ../../packages/core-unified-agent/src/client/UnifiedClaudeAgentClient.ts
32421
- var UnifiedClaudeAgentClient = class extends EventEmitter {
32422
- connection = null;
32423
- sessionId = null;
32424
- sessionCwd = null;
32425
- currentSystemPrompt = null;
32426
- currentSystemPromptMode = "prepend";
32427
- firstPromptPending = null;
32428
- currentEffort = null;
32429
- detector = new CliDetector();
32430
- cliType = "claude";
32431
- on(event, listener) {
32432
- return super.on(event, listener);
32433
- }
32434
- once(event, listener) {
32435
- return super.once(event, listener);
32436
- }
32437
- off(event, listener) {
32438
- return super.off(event, listener);
32439
- }
32440
- emitTyped(event, ...args) {
32441
- return super.emit(event, ...args);
32442
- }
32443
- async connect(options) {
32444
- await this.disconnect();
32445
- const systemPromptMode = options.systemPromptMode ?? "prepend";
32446
- if (options.cli && options.cli !== this.cliType) {
32447
- throw new Error(`UnifiedClaudeAgentClient\uB294 ${this.cliType} CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.`);
32448
- }
32449
- const acpMcpServers = this.resolveMcpServers(options.mcpServers);
32450
- const spawnConfig = createSpawnConfig(this.cliType, options);
32451
- const backendConfig = getBackendConfig(this.cliType);
32452
- const defaultEnv = backendConfig.defaultEnv ?? {};
32453
- const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...options.env });
32454
- if (defaultEnv.ANTHROPIC_BASE_URL && !cleanEnv.ANTHROPIC_API_KEY && !cleanEnv.ANTHROPIC_AUTH_TOKEN) {
32455
- throw new Error(
32456
- `[${this.cliType}] ANTHROPIC_API_KEY \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${getProviderModels(this.cliType).name} API \uD0A4\uB97C \uC124\uC815\uD574\uC8FC\uC138\uC694.`
32457
- );
32181
+ // ../../packages/core-unified-agent/models.json
32182
+ var models_default = {
32183
+ version: 1,
32184
+ updatedAt: "2026-07-25T00:00:00Z",
32185
+ providers: {
32186
+ claude: {
32187
+ name: "Claude Code",
32188
+ defaultModel: "opus[1m]",
32189
+ models: [
32190
+ { modelId: "haiku", name: "Claude Haiku", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "low" } },
32191
+ { modelId: "sonnet", name: "Claude Sonnet", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
32192
+ { modelId: "opus", name: "Claude Opus", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
32193
+ { modelId: "opus[1m]", name: "Claude Opus [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
32194
+ { modelId: "claude-opus-4-6[1m]", name: "Claude Opus 4.6 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
32195
+ { modelId: "claude-opus-4-7[1m]", name: "Claude Opus 4.7 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } },
32196
+ { modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
32197
+ ]
32198
+ },
32199
+ codex: {
32200
+ name: "Codex",
32201
+ defaultModel: "gpt-5.6-sol",
32202
+ models: [
32203
+ { modelId: "gpt-5.6-sol", name: "GPT-5.6-Sol", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
32204
+ { modelId: "gpt-5.6-sol-fast", name: "GPT-5.6-Sol Fast", providerModelId: "gpt-5.6-sol", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
32205
+ { modelId: "gpt-5.6-terra", name: "GPT-5.6-Terra", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
32206
+ { modelId: "gpt-5.6-terra-fast", name: "GPT-5.6-Terra Fast", providerModelId: "gpt-5.6-terra", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
32207
+ { modelId: "gpt-5.6-luna", name: "GPT-5.6-Luna", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
32208
+ { modelId: "gpt-5.6-luna-fast", name: "GPT-5.6-Luna Fast", providerModelId: "gpt-5.6-luna", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
32209
+ { modelId: "gpt-5.5", name: "GPT-5.5", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
32210
+ { modelId: "gpt-5.5-fast", name: "GPT-5.5 Fast", providerModelId: "gpt-5.5", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
32211
+ ]
32458
32212
  }
32459
- const connection = new AcpConnection({
32460
- command: spawnConfig.command,
32461
- args: spawnConfig.args,
32462
- cliType: this.cliType,
32463
- cwd: options.cwd,
32464
- env: { ...cleanEnv },
32465
- requestTimeout: options.timeout,
32466
- initTimeout: options.timeout,
32467
- promptIdleTimeout: options.promptIdleTimeout,
32468
- clientInfo: options.clientInfo,
32469
- autoApprove: options.autoApprove,
32470
- fsAccess: options.fsAccess
32471
- });
32472
- this.connection = connection;
32473
- this.setupEventForwarding();
32474
- const recentLogs = [];
32213
+ }
32214
+ };
32215
+
32216
+ // ../../packages/core-unified-agent/src/models/registry.ts
32217
+ var EffortLevelSchema = external_exports.enum([
32218
+ "low",
32219
+ "medium",
32220
+ "high",
32221
+ "xhigh",
32222
+ "max",
32223
+ "ultra"
32224
+ ]);
32225
+ var EffortSchema = external_exports.union([
32226
+ external_exports.object({
32227
+ supported: external_exports.literal(true),
32228
+ levels: external_exports.array(EffortLevelSchema).min(1),
32229
+ default: EffortLevelSchema
32230
+ }).strict(),
32231
+ external_exports.object({
32232
+ supported: external_exports.literal(false)
32233
+ }).strict()
32234
+ ]);
32235
+ var ModelEntrySchema = external_exports.object({
32236
+ /** 모델 고유 식별자 (session/set_model에 전달되는 값) */
32237
+ modelId: external_exports.string(),
32238
+ /** 사람이 읽을 수 있는 모델 이름 */
32239
+ name: external_exports.string(),
32240
+ /** 모델 설명 (선택) */
32241
+ description: external_exports.string().optional(),
32242
+ /** 카탈로그 ID와 실제 provider 모델 ID가 다른 경우의 원본 모델 ID */
32243
+ providerModelId: external_exports.string().optional(),
32244
+ /** provider가 모델과 별도로 받는 서비스 티어 */
32245
+ serviceTier: external_exports.string().optional(),
32246
+ /** 모델의 컨텍스트 윈도우 크기 (토큰) */
32247
+ contextWindow: external_exports.number().int().positive().optional(),
32248
+ /** 모델별 effort 설정 */
32249
+ effort: EffortSchema
32250
+ }).check((ctx) => {
32251
+ const effort = ctx.value.effort;
32252
+ if (effort.supported && !effort.levels.includes(effort.default)) {
32253
+ ctx.issues.push({
32254
+ code: "custom",
32255
+ input: effort.default,
32256
+ message: `effort.default "${effort.default}"\uC740(\uB294) levels \uBAA9\uB85D\uC5D0 \uC874\uC7AC\uD574\uC57C \uD569\uB2C8\uB2E4`,
32257
+ path: ["effort", "default"]
32258
+ });
32259
+ }
32260
+ if (ctx.value.serviceTier && !ctx.value.providerModelId) {
32261
+ ctx.issues.push({
32262
+ code: "custom",
32263
+ input: ctx.value.serviceTier,
32264
+ message: "serviceTier\uB97C \uC9C0\uC815\uD55C \uBAA8\uB378\uC740 providerModelId\uB3C4 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4",
32265
+ path: ["serviceTier"]
32266
+ });
32267
+ }
32268
+ });
32269
+ var ProviderSchema = external_exports.object({
32270
+ /** 프로바이더 표시 이름 */
32271
+ name: external_exports.string(),
32272
+ /** 기본 모델 ID */
32273
+ defaultModel: external_exports.string(),
32274
+ /** 사용 가능한 모델 목록 */
32275
+ models: external_exports.array(ModelEntrySchema).min(1)
32276
+ }).check((ctx) => {
32277
+ const ids = new Set(ctx.value.models.map((m) => m.modelId));
32278
+ if (!ids.has(ctx.value.defaultModel)) {
32279
+ ctx.issues.push({
32280
+ code: "custom",
32281
+ input: ctx.value.defaultModel,
32282
+ message: `defaultModel "${ctx.value.defaultModel}"\uC740(\uB294) models \uBAA9\uB85D\uC5D0 \uC874\uC7AC\uD574\uC57C \uD569\uB2C8\uB2E4`,
32283
+ path: ["defaultModel"]
32284
+ });
32285
+ }
32286
+ });
32287
+ var ModelMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
32288
+ var ModelsMapperEntrySchema = external_exports.object({
32289
+ /** modelId와 연관된 매핑 모델 */
32290
+ modelMapping: ModelMappingSchema,
32291
+ /** 추가 환경변수 (선택) */
32292
+ env: external_exports.record(external_exports.string(), external_exports.string()).optional()
32293
+ });
32294
+ external_exports.record(external_exports.string(), ModelsMapperEntrySchema);
32295
+ var ModelsRegistrySchema = external_exports.object({
32296
+ /** 스키마 버전 */
32297
+ version: external_exports.number().int().positive(),
32298
+ /** 최종 업데이트 시각 */
32299
+ updatedAt: external_exports.string(),
32300
+ /** 프로바이더별 모델 정보 */
32301
+ providers: external_exports.record(external_exports.string(), ProviderSchema)
32302
+ });
32303
+ var registry2 = Object.freeze(ModelsRegistrySchema.parse(models_default));
32304
+ function getProviderModels(cli) {
32305
+ const provider = registry2.providers[cli];
32306
+ if (!provider) {
32307
+ throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
32308
+ }
32309
+ return structuredClone(provider);
32310
+ }
32311
+ function getEffort(cli, modelId) {
32312
+ const model = findProviderModel(cli, modelId);
32313
+ return structuredClone(model.effort);
32314
+ }
32315
+ function findProviderModel(cli, modelId) {
32316
+ const provider = registry2.providers[cli];
32317
+ if (!provider) {
32318
+ throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uD504\uB85C\uBC14\uC774\uB354: "${cli}"`);
32319
+ }
32320
+ const model = provider.models.find((m) => m.modelId === modelId);
32321
+ if (!model) {
32322
+ throw new Error(`\uC54C \uC218 \uC5C6\uB294 \uBAA8\uB378: "${cli}/${modelId}"`);
32323
+ }
32324
+ return model;
32325
+ }
32326
+
32327
+ // ../../packages/core-unified-agent/src/client/UnifiedClaudeAgentClient.ts
32328
+ var UnifiedClaudeAgentClient = class extends EventEmitter {
32329
+ connection = null;
32330
+ sessionId = null;
32331
+ sessionCwd = null;
32332
+ currentSystemPrompt = null;
32333
+ currentSystemPromptMode = "prepend";
32334
+ firstPromptPending = null;
32335
+ currentEffort = null;
32336
+ detector = new CliDetector();
32337
+ cliType = "claude";
32338
+ on(event, listener) {
32339
+ return super.on(event, listener);
32340
+ }
32341
+ once(event, listener) {
32342
+ return super.once(event, listener);
32343
+ }
32344
+ off(event, listener) {
32345
+ return super.off(event, listener);
32346
+ }
32347
+ emitTyped(event, ...args) {
32348
+ return super.emit(event, ...args);
32349
+ }
32350
+ async connect(options) {
32351
+ await this.disconnect();
32352
+ const systemPromptMode = options.systemPromptMode ?? "prepend";
32353
+ if (options.cli && options.cli !== this.cliType) {
32354
+ throw new Error(`UnifiedClaudeAgentClient\uB294 ${this.cliType} CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.`);
32355
+ }
32356
+ const acpMcpServers = this.resolveMcpServers(options.mcpServers);
32357
+ const spawnConfig = createSpawnConfig(this.cliType, options);
32358
+ const backendConfig = getBackendConfig(this.cliType);
32359
+ const defaultEnv = backendConfig.defaultEnv ?? {};
32360
+ const cleanEnv = cleanEnvironment(process.env, { ...defaultEnv, ...options.env });
32361
+ if (defaultEnv.ANTHROPIC_BASE_URL && !cleanEnv.ANTHROPIC_API_KEY && !cleanEnv.ANTHROPIC_AUTH_TOKEN) {
32362
+ throw new Error(
32363
+ `[${this.cliType}] ANTHROPIC_API_KEY \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${getProviderModels(this.cliType).name} API \uD0A4\uB97C \uC124\uC815\uD574\uC8FC\uC138\uC694.`
32364
+ );
32365
+ }
32366
+ const connection = new AcpConnection({
32367
+ command: spawnConfig.command,
32368
+ args: spawnConfig.args,
32369
+ cliType: this.cliType,
32370
+ cwd: options.cwd,
32371
+ env: { ...cleanEnv },
32372
+ requestTimeout: options.timeout,
32373
+ initTimeout: options.timeout,
32374
+ promptIdleTimeout: options.promptIdleTimeout,
32375
+ clientInfo: options.clientInfo,
32376
+ autoApprove: options.autoApprove,
32377
+ fsAccess: options.fsAccess
32378
+ });
32379
+ this.connection = connection;
32380
+ this.setupEventForwarding();
32381
+ const recentLogs = [];
32475
32382
  const collectLog = (message) => {
32476
32383
  recentLogs.push(message);
32477
32384
  if (recentLogs.length > 30) {
@@ -33943,656 +33850,209 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
33943
33850
  this.pendingOverrides = {
33944
33851
  turnConfig: {},
33945
33852
  threadConfig: this.pendingOverrides?.threadConfig ?? {}
33946
- };
33947
- return {
33948
- cli: "codex",
33949
- protocol: "codex-app-server"
33950
- };
33951
- }
33952
- clearSessionState() {
33953
- this.sessionId = null;
33954
- this.sessionCwd = null;
33955
- this.currentSystemPrompt = null;
33956
- this.firstPromptPending = null;
33957
- this.pendingOverrides = null;
33958
- this.currentModelSelection = {};
33959
- this.archiveSessionOnDisconnect = false;
33960
- }
33961
- validateModelEffort(modelId, effort) {
33962
- if (!effort) {
33963
- return;
33964
- }
33965
- const provider = getProviderModels("codex");
33966
- const resolvedModelId = modelId ?? provider.defaultModel;
33967
- const model = provider.models.find((entry) => entry.modelId === resolvedModelId);
33968
- if (!model) {
33969
- return;
33970
- }
33971
- if (!model.effort.supported) {
33972
- throw new Error(`codex/${resolvedModelId} \uBAA8\uB378\uC740 reasoning effort\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`);
33973
- }
33974
- if (!model.effort.levels.includes(effort)) {
33975
- throw new Error(
33976
- `codex/${resolvedModelId} \uBAA8\uB378\uC740 effort "${effort}"\uC744(\uB97C) \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9 \uAC00\uB2A5: ${model.effort.levels.join(", ")}`
33977
- );
33978
- }
33979
- }
33980
- setupEventForwarding() {
33981
- if (!this.connection) return;
33982
- this.setupAppServerEventForwarding(this.connection);
33983
- }
33984
- setupAppServerEventForwarding(connection) {
33985
- connection.on("stateChange", (state) => {
33986
- this.emitTyped("stateChange", state);
33987
- });
33988
- connection.on("userMessageChunk", (text, sessionId) => {
33989
- this.emitTyped("userMessageChunk", text, sessionId);
33990
- });
33991
- connection.on("messageChunk", (text, sessionId) => {
33992
- this.emitTyped("messageChunk", text, sessionId);
33993
- });
33994
- connection.on("thoughtChunk", (text, sessionId) => {
33995
- this.emitTyped("thoughtChunk", text, sessionId);
33996
- });
33997
- connection.on("toolCall", (title, status, sessionId, data) => {
33998
- this.emitTyped("toolCall", title, status, sessionId, data);
33999
- });
34000
- connection.on("toolCallUpdate", (title, status, sessionId, data) => {
34001
- this.emitTyped("toolCallUpdate", title, status, sessionId, data);
34002
- });
34003
- connection.on("plan", (plan, sessionId) => {
34004
- this.emitTyped("plan", plan, sessionId);
34005
- });
34006
- connection.on("promptComplete", (sessionId) => {
34007
- this.emitTyped("promptComplete", sessionId);
34008
- });
34009
- connection.on("permissionRequest", (params, resolve3) => {
34010
- this.emitTyped(
34011
- "permissionRequest",
34012
- params,
34013
- resolve3
34014
- );
34015
- });
34016
- connection.on("sessionUpdate", (update) => {
34017
- this.emitTyped("sessionUpdate", update);
34018
- });
34019
- connection.on("error", (err) => {
34020
- this.emitTyped("error", err);
34021
- });
34022
- connection.on("exit", (code, signal) => {
34023
- this.emitTyped("exit", code, signal);
34024
- });
34025
- connection.on("log", (msg) => {
34026
- this.emitTyped("log", msg);
34027
- });
34028
- connection.on("logEntry", (entry) => {
34029
- this.emitTyped("logEntry", entry);
34030
- });
34031
- }
34032
- ensurePendingOverrides() {
34033
- if (!this.pendingOverrides) {
34034
- this.pendingOverrides = {
34035
- turnConfig: {},
34036
- threadConfig: {}
34037
- };
34038
- }
34039
- return this.pendingOverrides;
34040
- }
34041
- applyPendingOverrides() {
34042
- if (!this.pendingOverrides || !this.connection) {
34043
- return;
34044
- }
34045
- if (this.pendingOverrides.model) {
34046
- this.connection.setPendingModel(this.pendingOverrides.model.providerModelId ?? null);
34047
- this.connection.setPendingServiceTier(this.pendingOverrides.model.serviceTier ?? null);
34048
- this.pendingOverrides.model = void 0;
34049
- }
34050
- if (this.pendingOverrides.turnConfig.model) {
34051
- const selection = this.resolveModelSelection(this.pendingOverrides.turnConfig.model);
34052
- this.connection.setPendingModel(selection.providerModelId ?? null);
34053
- this.connection.setPendingServiceTier(selection.serviceTier ?? null);
34054
- delete this.pendingOverrides.turnConfig.model;
34055
- }
34056
- if (this.pendingOverrides.turnConfig.effort) {
34057
- this.connection.setPendingEffort(this.pendingOverrides.turnConfig.effort);
34058
- delete this.pendingOverrides.turnConfig.effort;
34059
- }
34060
- }
34061
- buildCodexThreadDefaultsForReset(cwd) {
34062
- const threadConfig = this.pendingOverrides?.threadConfig ?? {};
34063
- const { approvalPolicy, sandbox } = threadConfig;
34064
- const configEntries = Object.entries(threadConfig).filter(([key]) => !CODEX_THREAD_POLICY_CONFIG_KEYS.has(key));
34065
- const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
34066
- return {
34067
- cwd,
34068
- model: this.currentModelSelection.providerModelId,
34069
- serviceTier: this.currentModelSelection.serviceTier,
34070
- approvalPolicy,
34071
- sandbox,
34072
- developerInstructions: void 0,
34073
- config: config2
34074
- };
34075
- }
34076
- buildCodexThreadDefaultsForResume(cwd, modelSelection, systemPrompt, threadConfig) {
34077
- const { approvalPolicy, sandbox } = threadConfig;
34078
- const configEntries = Object.entries(threadConfig).filter(([key]) => !CODEX_THREAD_POLICY_CONFIG_KEYS.has(key));
34079
- const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
34080
- return {
34081
- cwd,
34082
- ...modelSelection.providerModelId ? { model: modelSelection.providerModelId } : {},
34083
- ...modelSelection.serviceTier ? { serviceTier: modelSelection.serviceTier } : {},
34084
- approvalPolicy,
34085
- sandbox,
34086
- developerInstructions: systemPrompt ?? void 0,
34087
- config: config2
34088
- };
34089
- }
34090
- resolveMode(modeId) {
34091
- switch (modeId) {
34092
- case "autoEdit":
34093
- return { approvalPolicy: "on-request", sandbox: "workspace-write" };
34094
- case "yolo":
34095
- return { approvalPolicy: "never", sandbox: "danger-full-access" };
34096
- default:
34097
- return { approvalPolicy: "on-request", sandbox: "read-only" };
34098
- }
34099
- }
34100
- buildStartupConfigArgs(overrides, servers, modeMapping) {
34101
- const configArgs = [
34102
- ...modeMapping ? [
34103
- `approval_policy="${modeMapping.approvalPolicy}"`,
34104
- `sandbox_mode="${modeMapping.sandbox}"`
34105
- ] : [],
34106
- ...overrides ?? [],
34107
- ...servers?.length ? mcpServerConfigsToCodexArgs(servers) : []
34108
- ];
34109
- return buildConfigOverrideArgs(configArgs);
34110
- }
34111
- resolveMcpServerNames(overrides, servers) {
34112
- const names = /* @__PURE__ */ new Set();
34113
- for (const server of servers ?? []) {
34114
- names.add(server.name);
34115
- }
34116
- for (const override of overrides ?? []) {
34117
- const match = /^mcp_servers\.([^.]+)\./.exec(override);
34118
- if (match) {
34119
- names.add(match[1]);
34120
- }
34121
- }
34122
- return [...names];
34123
- }
34124
- async cleanupFailedConnection() {
34125
- if (!this.connection) {
34126
- return;
34127
- }
34128
- try {
34129
- if (this.archiveSessionOnDisconnect && this.sessionId) {
34130
- await this.connection.endSession().catch(() => {
34131
- });
34132
- }
34133
- await this.connection.disconnect();
34134
- } catch {
34135
- }
34136
- this.connection.removeAllListeners();
34137
- this.connection = null;
34138
- this.clearSessionState();
34139
- }
34140
- resolveModelSelection(modelId) {
34141
- if (!modelId) {
34142
- return {};
34143
- }
34144
- const model = getProviderModels("codex").models.find((entry) => entry.modelId === modelId);
34145
- return {
34146
- providerModelId: model?.providerModelId ?? modelId,
34147
- serviceTier: model?.serviceTier
34148
- };
34149
- }
34150
- };
34151
- var UnifiedCursorAgentClient = class extends EventEmitter {
34152
- connection = null;
34153
- sessionId = null;
34154
- sessionCwd = null;
34155
- currentSystemPrompt = null;
34156
- firstPromptPending = null;
34157
- currentConnectOptions = null;
34158
- detector = new CliDetector();
34159
- on(event, listener) {
34160
- return super.on(event, listener);
34161
- }
34162
- once(event, listener) {
34163
- return super.once(event, listener);
34164
- }
34165
- off(event, listener) {
34166
- return super.off(event, listener);
34167
- }
34168
- emitTyped(event, ...args) {
34169
- return super.emit(event, ...args);
34170
- }
34171
- async connect(options) {
34172
- await this.disconnect();
34173
- if (options.cli && options.cli !== "cursor") {
34174
- throw new Error("UnifiedCursorAgentClient\uB294 cursor CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.");
34175
- }
34176
- const acpMcpServers = this.resolveMcpServers(options.mcpServers);
34177
- const spawnConfig = createSpawnConfig("cursor", options);
34178
- const cleanEnv = cleanEnvironment(process.env, options.env);
34179
- const env = { ...cleanEnv };
34180
- const connection = new AcpConnection({
34181
- command: spawnConfig.command,
34182
- args: spawnConfig.args,
34183
- cliType: "cursor",
34184
- cwd: options.cwd,
34185
- env,
34186
- requestTimeout: options.timeout,
34187
- initTimeout: options.timeout,
34188
- promptIdleTimeout: options.promptIdleTimeout,
34189
- clientInfo: options.clientInfo,
34190
- autoApprove: options.autoApprove,
34191
- fsAccess: options.fsAccess
34192
- });
34193
- this.connection = connection;
34194
- this.setupEventForwarding();
34195
- const recentLogs = [];
34196
- const collectLog = (message) => {
34197
- recentLogs.push(message);
34198
- if (recentLogs.length > 30) {
34199
- recentLogs.shift();
34200
- }
34201
- };
34202
- connection.on("log", collectLog);
34203
- let session;
34204
- try {
34205
- session = await connection.connect(
34206
- options.cwd,
34207
- options.sessionId,
34208
- acpMcpServers,
34209
- options.systemPrompt
34210
- );
34211
- } catch (error51) {
34212
- const connectionError = this.buildConnectionError(error51, recentLogs);
34213
- await this.cleanupFailedConnection();
34214
- throw connectionError;
34215
- } finally {
34216
- connection.off("log", collectLog);
34217
- }
34218
- return this.finalizeConnect(options, session);
34219
- }
34220
- async disconnect() {
34221
- if (!this.connection) {
34222
- this.clearSessionState();
34223
- return;
34224
- }
34225
- const conn = this.connection;
34226
- if (this.sessionId && conn.canResetSession) {
34227
- try {
34228
- await conn.endSession(this.sessionId);
34229
- } catch {
34230
- }
34231
- }
34232
- await conn.disconnect();
34233
- conn.removeAllListeners();
34234
- this.connection = null;
34235
- this.clearSessionState();
34236
- }
34237
- async endSession() {
34238
- if (!this.connection || !this.sessionId) {
34239
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34240
- }
34241
- await this.connection.endSession(this.sessionId);
34242
- this.sessionId = null;
34243
- }
34244
- getConnectionInfo() {
34245
- return {
34246
- cli: this.connection ? "cursor" : null,
34247
- protocol: this.connection ? "acp" : null,
34248
- sessionId: this.sessionId,
34249
- state: this.connection ? this.connection.connectionState : "disconnected"
34250
- };
34251
- }
34252
- async detectClis() {
34253
- return this.detector.detectAll(true);
34254
- }
34255
- async sendMessage(content) {
34256
- if (!this.connection || !this.sessionId) {
34257
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34258
- }
34259
- const systemPrompt = this.firstPromptPending;
34260
- if (!systemPrompt) {
34261
- return this.connection.sendPrompt(this.sessionId, content);
34262
- }
34263
- const userBlocks = typeof content === "string" ? [{ type: "text", text: content }] : content;
34264
- const response = await this.connection.sendPrompt(this.sessionId, [
34265
- { type: "text", text: systemPrompt },
34266
- ...userBlocks
34267
- ]);
34268
- this.firstPromptPending = null;
34269
- return response;
34270
- }
34271
- async cancelPrompt() {
34272
- if (!this.connection || !this.sessionId) {
34273
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34274
- }
34275
- await this.connection.cancelSession(this.sessionId);
34276
- }
34277
- async setModel(model) {
34278
- if (!this.connection || !this.sessionId) {
34279
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34280
- }
34281
- const reconnectOptions = this.buildReconnectOptions(model);
34282
- await this.reconnectWithRestore(reconnectOptions, "\uBAA8\uB378 \uBCC0\uACBD");
34283
- }
34284
- async setConfigOption(configId, value) {
34285
- if (!this.connection || !this.sessionId) {
34286
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34287
- }
34288
- if (configId === "effort" || configId === "reasoning_effort") {
34289
- const reconnectOptions = this.buildEffortReconnectOptions(value);
34290
- if (!reconnectOptions) {
34291
- return;
34292
- }
34293
- await this.reconnectWithRestore(reconnectOptions, "effort \uBCC0\uACBD");
34294
- return;
34295
- }
34296
- if (configId === "model") {
34297
- return this.setModel(value);
34298
- }
34299
- await this.connection.setConfigOption(this.sessionId, configId, value);
34300
- }
34301
- async setMode(mode) {
34302
- if (!this.connection || !this.sessionId) {
34303
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34304
- }
34305
- await this.connection.setMode(this.sessionId, mode);
34306
- }
34307
- async setYoloMode(enabled) {
34308
- return this.setMode(enabled ? getYoloModeId("cursor") : "default");
34309
- }
34310
- getAvailableModes() {
34311
- return getBackendConfig("cursor").modes ?? [];
34312
- }
34313
- getAvailableModels() {
34314
- return getProviderModels("cursor");
34315
- }
34316
- getCurrentSystemPrompt() {
34317
- return this.currentSystemPrompt;
34318
- }
34319
- async loadSession(sessionId, mcpServers) {
34320
- if (!this.connection) {
34321
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34322
- }
34323
- await this.connection.loadSession({
34324
- sessionId,
34325
- cwd: this.sessionCwd ?? process.cwd(),
34326
- mcpServers: this.resolveMcpServers(mcpServers)
34327
- });
34328
- this.sessionId = sessionId;
34329
- this.currentSystemPrompt = null;
34330
- this.firstPromptPending = null;
34331
- }
34332
- async resetSession(cwd) {
34333
- if (!this.connection || !this.sessionId) {
34334
- throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
34335
- }
34336
- const targetCwd = cwd ?? this.sessionCwd ?? process.cwd();
34337
- if (!this.connection.canResetSession) {
34338
- throw new Error("[cursor] \uC138\uC158 \uB9AC\uC14B\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. disconnect() \uD6C4 \uC7AC\uC5F0\uACB0\uD558\uC138\uC694.");
34339
- }
34340
- await this.connection.endSession(this.sessionId);
34341
- this.sessionId = null;
34342
- const session = this.currentSystemPrompt ? await this.connection.reconnectSession(
34343
- targetCwd,
34344
- void 0,
34345
- void 0,
34346
- this.currentSystemPrompt
34347
- ) : await this.connection.reconnectSession(targetCwd);
34348
- this.sessionId = session.sessionId;
34349
- this.sessionCwd = targetCwd;
34350
- this.firstPromptPending = this.currentSystemPrompt;
34351
- return {
34352
- cli: "cursor",
34353
- protocol: "acp",
34354
- session
34355
- };
34356
- }
34357
- resolveMcpServers(servers) {
34358
- return servers?.length ? mcpServerConfigsToAcp(servers) : [];
34359
- }
34360
- async finalizeConnect(options, session) {
34361
- if (options.yoloMode && session.sessionId) {
34362
- try {
34363
- await this.connection.setMode(session.sessionId, getYoloModeId("cursor"));
34364
- } catch {
34365
- }
34366
- }
34367
- this.sessionId = session.sessionId;
34368
- this.sessionCwd = options.cwd;
34369
- this.currentSystemPrompt = options.systemPrompt ?? null;
34370
- this.firstPromptPending = options.sessionId ? null : this.currentSystemPrompt;
34371
- this.currentConnectOptions = this.cloneConnectOptions(options);
34372
- return {
34373
- cli: "cursor",
34374
- protocol: "acp",
34375
- session
34376
- };
34377
- }
34378
- clearSessionState() {
34379
- this.sessionId = null;
34380
- this.sessionCwd = null;
34381
- this.currentSystemPrompt = null;
34382
- this.firstPromptPending = null;
34383
- this.currentConnectOptions = null;
34384
- }
34385
- buildReconnectOptions(model) {
34386
- if (!this.currentConnectOptions) {
34387
- throw new Error("[cursor] \uBAA8\uB378 \uC804\uD658\uC744 \uC704\uD55C \uAE30\uC874 \uC5F0\uACB0 \uC635\uC158\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. connect()\uB85C \uB2E4\uC2DC \uC5F0\uACB0\uD558\uC138\uC694.");
34388
- }
34389
- const options = this.cloneConnectOptions(this.currentConnectOptions);
34390
- const effort = this.resolveEffortForModel(model, options.effort);
34391
- delete options.sessionId;
34392
- if (effort) {
34393
- options.effort = effort;
34394
- } else {
34395
- delete options.effort;
34396
- }
34397
- return {
34398
- ...options,
34399
- cli: "cursor",
34400
- model
34401
- };
34402
- }
34403
- buildEffortReconnectOptions(effort) {
34404
- if (!this.currentConnectOptions) {
34405
- throw new Error("[cursor] effort \uC804\uD658\uC744 \uC704\uD55C \uAE30\uC874 \uC5F0\uACB0 \uC635\uC158\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. connect()\uB85C \uB2E4\uC2DC \uC5F0\uACB0\uD558\uC138\uC694.");
34406
- }
34407
- if (!this.currentConnectOptions.model) {
34408
- throw new Error("[cursor] effort \uC804\uD658\uC744 \uC704\uD55C \uD604\uC7AC \uBAA8\uB378 \uC815\uBCF4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBAA8\uB378\uC744 \uC9C0\uC815\uD574 \uB2E4\uC2DC \uC5F0\uACB0\uD558\uC138\uC694.");
34409
- }
34410
- if (this.currentConnectOptions.effort === effort) {
34411
- return null;
34412
- }
34413
- const effortInfo = getCursorSpawnEffortInfo(this.currentConnectOptions.model);
34414
- if (!effortInfo.supported) {
34415
- return null;
34416
- }
34417
- if (!effortInfo.levels.includes(effort)) {
34418
- throw new Error(
34419
- `[cursor] ${this.currentConnectOptions.model} \uBAA8\uB378\uC740 effort "${effort}"\uC744(\uB97C) \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9 \uAC00\uB2A5: ${effortInfo.levels.join(", ")}`
34420
- );
34421
- }
34422
- const options = this.cloneConnectOptions(this.currentConnectOptions);
34423
- delete options.sessionId;
33853
+ };
34424
33854
  return {
34425
- ...options,
34426
- cli: "cursor",
34427
- effort
33855
+ cli: "codex",
33856
+ protocol: "codex-app-server"
34428
33857
  };
34429
33858
  }
34430
- resolveEffortForModel(model, effort) {
34431
- const effortInfo = getCursorSpawnEffortInfo(model);
34432
- if (!effortInfo.supported) {
34433
- return void 0;
33859
+ clearSessionState() {
33860
+ this.sessionId = null;
33861
+ this.sessionCwd = null;
33862
+ this.currentSystemPrompt = null;
33863
+ this.firstPromptPending = null;
33864
+ this.pendingOverrides = null;
33865
+ this.currentModelSelection = {};
33866
+ this.archiveSessionOnDisconnect = false;
33867
+ }
33868
+ validateModelEffort(modelId, effort) {
33869
+ if (!effort) {
33870
+ return;
34434
33871
  }
34435
- if (effort && effortInfo.levels.includes(effort)) {
34436
- return effort;
33872
+ const provider = getProviderModels("codex");
33873
+ const resolvedModelId = modelId ?? provider.defaultModel;
33874
+ const model = provider.models.find((entry) => entry.modelId === resolvedModelId);
33875
+ if (!model) {
33876
+ return;
34437
33877
  }
34438
- return effortInfo.default ?? void 0;
34439
- }
34440
- async reconnectWithRestore(nextOptions, label) {
34441
- if (!this.currentConnectOptions) {
34442
- throw new Error(`[cursor] ${label}\uC744 \uC704\uD55C \uAE30\uC874 \uC5F0\uACB0 \uC635\uC158\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. connect()\uB85C \uB2E4\uC2DC \uC5F0\uACB0\uD558\uC138\uC694.`);
33878
+ if (!model.effort.supported) {
33879
+ throw new Error(`codex/${resolvedModelId} \uBAA8\uB378\uC740 reasoning effort\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`);
34443
33880
  }
34444
- const previousOptions = this.cloneConnectOptions(this.currentConnectOptions);
34445
- try {
34446
- await this.connect(nextOptions);
34447
- } catch (error51) {
34448
- try {
34449
- await this.connect(previousOptions);
34450
- } catch (restoreError) {
34451
- throw new Error(
34452
- `[cursor] ${label} \uC2E4\uD328 \uD6C4 \uC774\uC804 \uC5F0\uACB0 \uBCF5\uAD6C\uB3C4 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. ${label} \uC624\uB958: ${this.formatErrorMessage(error51)} / \uBCF5\uAD6C \uC624\uB958: ${this.formatErrorMessage(restoreError)}`
34453
- );
34454
- }
33881
+ if (!model.effort.levels.includes(effort)) {
34455
33882
  throw new Error(
34456
- `[cursor] ${label} \uC2E4\uD328\uB85C \uC774\uC804 \uC5F0\uACB0\uC744 \uBCF5\uAD6C\uD588\uC2B5\uB2C8\uB2E4. ${label} \uC624\uB958: ${this.formatErrorMessage(error51)}`
33883
+ `codex/${resolvedModelId} \uBAA8\uB378\uC740 effort "${effort}"\uC744(\uB97C) \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9 \uAC00\uB2A5: ${model.effort.levels.join(", ")}`
34457
33884
  );
34458
33885
  }
34459
33886
  }
34460
- formatErrorMessage(error51) {
34461
- if (error51 instanceof Error) {
34462
- return error51.message;
34463
- }
34464
- return String(error51);
34465
- }
34466
- cloneConnectOptions(options) {
34467
- return {
34468
- ...options,
34469
- cli: "cursor",
34470
- env: options.env ? { ...options.env } : void 0,
34471
- clientInfo: options.clientInfo ? { ...options.clientInfo } : void 0,
34472
- mcpServers: options.mcpServers?.map((server) => ({
34473
- ...server,
34474
- headers: server.headers?.map((header) => ({ ...header }))
34475
- }))
34476
- };
34477
- }
34478
33887
  setupEventForwarding() {
34479
33888
  if (!this.connection) return;
34480
- this.connection.on("stateChange", (state) => {
33889
+ this.setupAppServerEventForwarding(this.connection);
33890
+ }
33891
+ setupAppServerEventForwarding(connection) {
33892
+ connection.on("stateChange", (state) => {
34481
33893
  this.emitTyped("stateChange", state);
34482
33894
  });
34483
- this.connection.on("userMessageChunk", (text, sessionId) => {
33895
+ connection.on("userMessageChunk", (text, sessionId) => {
34484
33896
  this.emitTyped("userMessageChunk", text, sessionId);
34485
33897
  });
34486
- this.connection.on("messageChunk", (text, sessionId) => {
33898
+ connection.on("messageChunk", (text, sessionId) => {
34487
33899
  this.emitTyped("messageChunk", text, sessionId);
34488
33900
  });
34489
- this.connection.on("thoughtChunk", (text, sessionId) => {
33901
+ connection.on("thoughtChunk", (text, sessionId) => {
34490
33902
  this.emitTyped("thoughtChunk", text, sessionId);
34491
33903
  });
34492
- this.connection.on("toolCall", (title, status, sessionId, data) => {
33904
+ connection.on("toolCall", (title, status, sessionId, data) => {
34493
33905
  this.emitTyped("toolCall", title, status, sessionId, data);
34494
33906
  });
34495
- this.connection.on("toolCallUpdate", (title, status, sessionId, data) => {
33907
+ connection.on("toolCallUpdate", (title, status, sessionId, data) => {
34496
33908
  this.emitTyped("toolCallUpdate", title, status, sessionId, data);
34497
33909
  });
34498
- this.connection.on("plan", (plan, sessionId) => {
33910
+ connection.on("plan", (plan, sessionId) => {
34499
33911
  this.emitTyped("plan", plan, sessionId);
34500
33912
  });
34501
- this.connection.on("availableCommandsUpdate", (commands, sessionId) => {
34502
- this.emitTyped("availableCommandsUpdate", commands, sessionId);
34503
- });
34504
- this.connection.on("sessionUpdate", (update) => {
34505
- this.emitTyped("sessionUpdate", update);
34506
- });
34507
- this.connection.on("permissionRequest", (params, resolve3) => {
34508
- this.emitTyped("permissionRequest", params, resolve3);
34509
- });
34510
- this.connection.on("fileRead", (params, resolve3) => {
34511
- this.emitTyped("fileRead", params, resolve3);
33913
+ connection.on("promptComplete", (sessionId) => {
33914
+ this.emitTyped("promptComplete", sessionId);
34512
33915
  });
34513
- this.connection.on("fileWrite", (params, resolve3) => {
34514
- this.emitTyped("fileWrite", params, resolve3);
33916
+ connection.on("permissionRequest", (params, resolve3) => {
33917
+ this.emitTyped(
33918
+ "permissionRequest",
33919
+ params,
33920
+ resolve3
33921
+ );
34515
33922
  });
34516
- this.connection.on("promptComplete", (sessionId) => {
34517
- this.emitTyped("promptComplete", sessionId);
33923
+ connection.on("sessionUpdate", (update) => {
33924
+ this.emitTyped("sessionUpdate", update);
34518
33925
  });
34519
- this.connection.on("error", (err) => {
33926
+ connection.on("error", (err) => {
34520
33927
  this.emitTyped("error", err);
34521
33928
  });
34522
- this.connection.on("exit", (code, signal) => {
33929
+ connection.on("exit", (code, signal) => {
34523
33930
  this.emitTyped("exit", code, signal);
34524
33931
  });
34525
- this.connection.on("log", (msg) => {
33932
+ connection.on("log", (msg) => {
34526
33933
  this.emitTyped("log", msg);
34527
33934
  });
34528
- this.connection.on("logEntry", (entry) => {
33935
+ connection.on("logEntry", (entry) => {
34529
33936
  this.emitTyped("logEntry", entry);
34530
33937
  });
34531
33938
  }
34532
- async cleanupFailedConnection() {
34533
- if (!this.connection) {
33939
+ ensurePendingOverrides() {
33940
+ if (!this.pendingOverrides) {
33941
+ this.pendingOverrides = {
33942
+ turnConfig: {},
33943
+ threadConfig: {}
33944
+ };
33945
+ }
33946
+ return this.pendingOverrides;
33947
+ }
33948
+ applyPendingOverrides() {
33949
+ if (!this.pendingOverrides || !this.connection) {
34534
33950
  return;
34535
33951
  }
34536
- try {
34537
- await this.connection.disconnect();
34538
- } catch {
33952
+ if (this.pendingOverrides.model) {
33953
+ this.connection.setPendingModel(this.pendingOverrides.model.providerModelId ?? null);
33954
+ this.connection.setPendingServiceTier(this.pendingOverrides.model.serviceTier ?? null);
33955
+ this.pendingOverrides.model = void 0;
34539
33956
  }
34540
- this.connection.removeAllListeners();
34541
- this.connection = null;
34542
- this.clearSessionState();
34543
- }
34544
- buildConnectionError(error51, recentLogs) {
34545
- if (getBackendConfig("cursor").authRequired && this.isAuthenticationError(error51, recentLogs)) {
34546
- return new Error(
34547
- "[cursor] \uC778\uC99D\uC774 \uD544\uC694\uD558\uAC70\uB098 \uC778\uC99D\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uD574\uB2F9 CLI\uC5D0\uC11C \uB85C\uADF8\uC778/\uC778\uC99D\uC744 \uC644\uB8CC\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
34548
- );
33957
+ if (this.pendingOverrides.turnConfig.model) {
33958
+ const selection = this.resolveModelSelection(this.pendingOverrides.turnConfig.model);
33959
+ this.connection.setPendingModel(selection.providerModelId ?? null);
33960
+ this.connection.setPendingServiceTier(selection.serviceTier ?? null);
33961
+ delete this.pendingOverrides.turnConfig.model;
34549
33962
  }
34550
- if (error51 instanceof Error) {
34551
- return error51;
33963
+ if (this.pendingOverrides.turnConfig.effort) {
33964
+ this.connection.setPendingEffort(this.pendingOverrides.turnConfig.effort);
33965
+ delete this.pendingOverrides.turnConfig.effort;
34552
33966
  }
34553
- if (typeof error51 === "object" && error51 !== null) {
34554
- const obj = error51;
34555
- if (typeof obj.message === "string") {
34556
- const code = typeof obj.code === "number" ? ` (code: ${obj.code})` : "";
34557
- const data = obj.data ? ` \u2014 ${JSON.stringify(obj.data)}` : "";
34558
- return new Error(`${obj.message}${code}${data}`);
34559
- }
34560
- return new Error(JSON.stringify(error51));
33967
+ }
33968
+ buildCodexThreadDefaultsForReset(cwd) {
33969
+ const threadConfig = this.pendingOverrides?.threadConfig ?? {};
33970
+ const { approvalPolicy, sandbox } = threadConfig;
33971
+ const configEntries = Object.entries(threadConfig).filter(([key]) => !CODEX_THREAD_POLICY_CONFIG_KEYS.has(key));
33972
+ const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
33973
+ return {
33974
+ cwd,
33975
+ model: this.currentModelSelection.providerModelId,
33976
+ serviceTier: this.currentModelSelection.serviceTier,
33977
+ approvalPolicy,
33978
+ sandbox,
33979
+ developerInstructions: void 0,
33980
+ config: config2
33981
+ };
33982
+ }
33983
+ buildCodexThreadDefaultsForResume(cwd, modelSelection, systemPrompt, threadConfig) {
33984
+ const { approvalPolicy, sandbox } = threadConfig;
33985
+ const configEntries = Object.entries(threadConfig).filter(([key]) => !CODEX_THREAD_POLICY_CONFIG_KEYS.has(key));
33986
+ const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
33987
+ return {
33988
+ cwd,
33989
+ ...modelSelection.providerModelId ? { model: modelSelection.providerModelId } : {},
33990
+ ...modelSelection.serviceTier ? { serviceTier: modelSelection.serviceTier } : {},
33991
+ approvalPolicy,
33992
+ sandbox,
33993
+ developerInstructions: systemPrompt ?? void 0,
33994
+ config: config2
33995
+ };
33996
+ }
33997
+ resolveMode(modeId) {
33998
+ switch (modeId) {
33999
+ case "autoEdit":
34000
+ return { approvalPolicy: "on-request", sandbox: "workspace-write" };
34001
+ case "yolo":
34002
+ return { approvalPolicy: "never", sandbox: "danger-full-access" };
34003
+ default:
34004
+ return { approvalPolicy: "on-request", sandbox: "read-only" };
34561
34005
  }
34562
- return new Error(String(error51));
34563
34006
  }
34564
- isAuthenticationError(error51, recentLogs) {
34565
- const authPatterns = [
34566
- /auth_required/i,
34567
- /authentication required/i,
34568
- /not authenticated/i,
34569
- /please login/i,
34570
- /please log in/i,
34571
- /sign in/i,
34572
- /reauth/i,
34573
- /unauthorized/i,
34574
- /invalid api key/i
34007
+ buildStartupConfigArgs(overrides, servers, modeMapping) {
34008
+ const configArgs = [
34009
+ ...modeMapping ? [
34010
+ `approval_policy="${modeMapping.approvalPolicy}"`,
34011
+ `sandbox_mode="${modeMapping.sandbox}"`
34012
+ ] : [],
34013
+ ...overrides ?? [],
34014
+ ...servers?.length ? mcpServerConfigsToCodexArgs(servers) : []
34575
34015
  ];
34576
- if (this.matchAnyPattern(this.extractErrorText(error51), authPatterns)) {
34577
- return true;
34578
- }
34579
- return recentLogs.some((log) => this.matchAnyPattern(log, authPatterns));
34016
+ return buildConfigOverrideArgs(configArgs);
34580
34017
  }
34581
- extractErrorText(error51) {
34582
- if (error51 instanceof Error) {
34583
- const code = error51.code;
34584
- if (code === -32e3) {
34585
- return `auth_required ${error51.message}`;
34018
+ resolveMcpServerNames(overrides, servers) {
34019
+ const names = /* @__PURE__ */ new Set();
34020
+ for (const server of servers ?? []) {
34021
+ names.add(server.name);
34022
+ }
34023
+ for (const override of overrides ?? []) {
34024
+ const match = /^mcp_servers\.([^.]+)\./.exec(override);
34025
+ if (match) {
34026
+ names.add(match[1]);
34586
34027
  }
34587
- return error51.message;
34588
34028
  }
34589
- if (typeof error51 === "string") {
34590
- return error51;
34029
+ return [...names];
34030
+ }
34031
+ async cleanupFailedConnection() {
34032
+ if (!this.connection) {
34033
+ return;
34591
34034
  }
34592
- return String(error51);
34035
+ try {
34036
+ if (this.archiveSessionOnDisconnect && this.sessionId) {
34037
+ await this.connection.endSession().catch(() => {
34038
+ });
34039
+ }
34040
+ await this.connection.disconnect();
34041
+ } catch {
34042
+ }
34043
+ this.connection.removeAllListeners();
34044
+ this.connection = null;
34045
+ this.clearSessionState();
34593
34046
  }
34594
- matchAnyPattern(text, patterns) {
34595
- return patterns.some((pattern) => pattern.test(text));
34047
+ resolveModelSelection(modelId) {
34048
+ if (!modelId) {
34049
+ return {};
34050
+ }
34051
+ const model = getProviderModels("codex").models.find((entry) => entry.modelId === modelId);
34052
+ return {
34053
+ providerModelId: model?.providerModelId ?? modelId,
34054
+ serviceTier: model?.serviceTier
34055
+ };
34596
34056
  }
34597
34057
  };
34598
34058
 
@@ -34604,8 +34064,6 @@ var UnifiedAgent = {
34604
34064
  return new UnifiedClaudeAgentClient();
34605
34065
  case "codex":
34606
34066
  return new UnifiedCodexAgentClient();
34607
- case "cursor":
34608
- return new UnifiedCursorAgentClient();
34609
34067
  }
34610
34068
  },
34611
34069
  async build(options = {}) {
@@ -34618,7 +34076,7 @@ var UnifiedAgent = {
34618
34076
  const preferred = await new CliDetector().getPreferred();
34619
34077
  if (!preferred) {
34620
34078
  throw new Error(
34621
- "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
34079
+ "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
34622
34080
  );
34623
34081
  }
34624
34082
  return this.createClient(preferred.cli);
@@ -34888,6 +34346,9 @@ async function routeGet(url2, response, context) {
34888
34346
  if (url2.pathname === "/api/search") {
34889
34347
  return handleSearch(url2, response, context);
34890
34348
  }
34349
+ if (url2.pathname === "/api/health") {
34350
+ return handleHealth(response, context);
34351
+ }
34891
34352
  const entryMatch = url2.pathname.match(/^\/api\/entry\/([^/]+)$/);
34892
34353
  if (entryMatch) {
34893
34354
  return handleEntry(entryMatch[1] ?? "", url2, response, context);
@@ -34995,7 +34456,7 @@ async function handleSearch(url2, response, context) {
34995
34456
  rawSourceRef: hit.rawSourceRef,
34996
34457
  rawSourceRefs: hit.rawSourceRefs,
34997
34458
  score: hit.score,
34998
- excerpt: hit.excerpt,
34459
+ excerpt: buildSearchExcerpt(hit, query),
34999
34460
  reason: hit.reason,
35000
34461
  aliases: hit.aliases,
35001
34462
  type: hit.type,
@@ -35059,6 +34520,36 @@ async function handleEntry(rawSegment, url2, response, context) {
35059
34520
  };
35060
34521
  sendJson(response, 200, responseBody);
35061
34522
  }
34523
+ async function handleHealth(response, context) {
34524
+ let logUnreadable = false;
34525
+ const [logEntries, conflicts, pending] = await Promise.all([
34526
+ parseLog(context.paths).catch(() => {
34527
+ logUnreadable = true;
34528
+ return [];
34529
+ }),
34530
+ listConflictSummaries(context.paths),
34531
+ listQueue(context.paths)
34532
+ ]);
34533
+ const latest = logEntries.findLast((entry) => entry.event === "drydock run") ?? null;
34534
+ const numberPayload = (key) => {
34535
+ const value = latest?.payload[key];
34536
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
34537
+ };
34538
+ const lastDrydock = latest ? {
34539
+ at: latest.timestamp,
34540
+ ok: latest.payload.ok === true,
34541
+ errorCount: numberPayload("error_count"),
34542
+ warningCount: numberPayload("warning_count"),
34543
+ infoCount: numberPayload("info_count"),
34544
+ issueCount: numberPayload("issue_count")
34545
+ } : null;
34546
+ sendJson(response, 200, {
34547
+ lastDrydock,
34548
+ conflictCount: conflicts.filter((item) => item.status === "open").length,
34549
+ pendingCount: pending.length,
34550
+ ...logUnreadable ? { logUnreadable: true } : {}
34551
+ });
34552
+ }
35062
34553
  async function handleDrydockList(url2, response, context) {
35063
34554
  const status = url2.searchParams.get("status") ?? "pending";
35064
34555
  if (!["pending", "archived", "all"].includes(status)) {
@@ -35214,6 +34705,26 @@ async function runDecisionAction(patchId, request, response, context) {
35214
34705
  sendJson(response, 500, { error: "internal_error" });
35215
34706
  }
35216
34707
  }
34708
+ function buildSearchExcerpt(hit, query) {
34709
+ const candidates = [
34710
+ ...hit.matchedSnippets?.map((match) => match.snippet) ?? [],
34711
+ hit.excerpt
34712
+ ].map(sanitizeSearchExcerpt).filter(Boolean);
34713
+ const normalizedQuery = query.trim().toLowerCase();
34714
+ const matched = normalizedQuery ? candidates.find((candidate) => candidate.toLowerCase().includes(normalizedQuery)) : void 0;
34715
+ return centerSearchExcerpt(matched ?? candidates[0] ?? "", query);
34716
+ }
34717
+ function sanitizeSearchExcerpt(value) {
34718
+ return value.replace(/^<<<FLEET_WIKI_[A-Z0-9_]+(?:\s[^\r\n]*)?>>>\s*$/gm, "").replace(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/, "").trim();
34719
+ }
34720
+ function centerSearchExcerpt(value, query) {
34721
+ const maxLength = 180;
34722
+ if (value.length <= maxLength) return value;
34723
+ const matchIndex = value.toLowerCase().indexOf(query.trim().toLowerCase());
34724
+ if (matchIndex === -1) return value.slice(0, maxLength).trim();
34725
+ const start = Math.max(0, Math.min(matchIndex - 50, value.length - maxLength));
34726
+ return value.slice(start, start + maxLength).trim();
34727
+ }
35217
34728
  async function readRequestBody(request) {
35218
34729
  return new Promise((resolve3) => {
35219
34730
  const chunks = [];
@@ -40468,7 +39979,7 @@ function createConsoleServer(deps = {}) {
40468
39979
  }
40469
39980
  if (tryServeStaticConsole2(req, res, pathname)) return;
40470
39981
  if (pathname === "/api/v1/health") {
40471
- handleHealth(req, res);
39982
+ handleHealth2(req, res);
40472
39983
  return;
40473
39984
  }
40474
39985
  runAsyncBooleanHandler(routeRegistry.handle({ req, res, pathname }), res, () => {
@@ -40556,7 +40067,7 @@ function createConsoleServer(deps = {}) {
40556
40067
  }
40557
40068
  return false;
40558
40069
  }
40559
- function handleHealth(req, res) {
40070
+ function handleHealth2(req, res) {
40560
40071
  const handle = lockHandle;
40561
40072
  const token = handle?.payload.token;
40562
40073
  if (handle && token && req.headers.authorization === `Bearer ${token}`) {
@@ -41324,7 +40835,7 @@ function createConsoleStalePolicy(deps = {}) {
41324
40835
  var FIXED_HOST = "127.0.0.1";
41325
40836
  var HELP_BANNER_INDENT = " ";
41326
40837
  var DEFAULT_HELP_RELEASE = "local";
41327
- var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "turn-start", "turn-end", "attention", "auto-name"]);
40838
+ var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "turn-start", "turn-end", "background-spawn", "background-stop", "attention", "auto-name"]);
41328
40839
  function parseConsoleCliMode(argv) {
41329
40840
  if (argv.length === 0) return "start";
41330
40841
  const [first, ...rest] = argv;
@@ -41356,6 +40867,8 @@ function parseConsoleHookCommand(argv) {
41356
40867
  }
41357
40868
  if (commandName === "turn-start" && rest.length === 0) return { command: "turn-start" };
41358
40869
  if (commandName === "turn-end" && rest.length === 0) return { command: "turn-end" };
40870
+ if (commandName === "background-spawn" && rest.length === 0) return { command: "background-spawn" };
40871
+ if (commandName === "background-stop" && rest.length === 0) return { command: "background-stop" };
41359
40872
  if (commandName === "attention" && rest.length === 0) return { command: "attention" };
41360
40873
  if (commandName === "auto-name" && rest.length === 0) return { command: "auto-name" };
41361
40874
  if (commandName === "capture-session" && rest.length === 1 && rest[0] === "claude") return { command: "capture-session", provider: rest[0] };
@@ -41540,6 +41053,10 @@ async function main() {
41540
41053
  await postAgentHook(`/sessions/${readHookSessionId(process4.env)}/turn`, { phase: hookCommand.command === "turn-start" ? "start" : "end" }, process4.env);
41541
41054
  return;
41542
41055
  }
41056
+ if (hookCommand.command === "background-spawn" || hookCommand.command === "background-stop") {
41057
+ await postAgentHook(`/sessions/${readHookSessionId(process4.env)}/background`, { event: hookCommand.command === "background-spawn" ? "spawn" : "stop" }, process4.env);
41058
+ return;
41059
+ }
41543
41060
  if (hookCommand.command === "attention") {
41544
41061
  await postAgentHook(`/sessions/${readHookSessionId(process4.env)}/attention`, { input: await readStdinBestEffort() }, process4.env);
41545
41062
  return;