@sylphx/flow 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/chunk-01gv4qey.js +4 -0
- package/dist/chunk-01gv4qey.js.map +11 -0
- package/dist/{chunk-f9yb2zk3.js → chunk-3m9whg4q.js} +2 -2
- package/dist/{chunk-f9yb2zk3.js.map → chunk-3m9whg4q.js.map} +1 -1
- package/dist/{chunk-sgafqzer.js → chunk-3w6pd43t.js} +3 -3
- package/dist/{chunk-sgafqzer.js.map → chunk-3w6pd43t.js.map} +2 -2
- package/dist/{chunk-d6k94684.js → chunk-4nm4ere4.js} +3 -3
- package/dist/{chunk-d6k94684.js.map → chunk-4nm4ere4.js.map} +1 -1
- package/dist/{chunk-ceyg2zjg.js → chunk-4vrj3f8r.js} +3 -3
- package/dist/{chunk-ceyg2zjg.js.map → chunk-4vrj3f8r.js.map} +1 -1
- package/dist/chunk-5njgv5k5.js +161 -0
- package/dist/{chunk-rsagxdqj.js.map → chunk-5njgv5k5.js.map} +4 -6
- package/dist/{chunk-6eb5a8kv.js → chunk-67n29s4q.js} +4 -4
- package/dist/chunk-67n29s4q.js.map +10 -0
- package/dist/{chunk-66qzap9m.js → chunk-86ce45n6.js} +2 -2
- package/dist/{chunk-66qzap9m.js.map → chunk-86ce45n6.js.map} +1 -1
- package/dist/{chunk-fyvtp08n.js → chunk-99pz5wm0.js} +2 -2
- package/dist/{chunk-fyvtp08n.js.map → chunk-99pz5wm0.js.map} +1 -1
- package/dist/chunk-d409xn8f.js +6 -0
- package/dist/{chunk-cjy100rr.js.map → chunk-d409xn8f.js.map} +2 -2
- package/dist/chunk-g0qpndpd.js +23 -0
- package/dist/{chunk-gmmm7xpw.js.map → chunk-g0qpndpd.js.map} +5 -5
- package/dist/{chunk-51kpynby.js → chunk-g4baca7p.js} +3 -3
- package/dist/{chunk-51kpynby.js.map → chunk-g4baca7p.js.map} +1 -1
- package/dist/chunk-gc66xe7z.js +4 -0
- package/dist/{chunk-8ep9gk6d.js.map → chunk-gc66xe7z.js.map} +2 -2
- package/dist/{chunk-2nfq57ym.js → chunk-hj6qtsqp.js} +2 -2
- package/dist/{chunk-2nfq57ym.js.map → chunk-hj6qtsqp.js.map} +2 -2
- package/dist/{chunk-etqfkn4f.js → chunk-jbd95k1f.js} +3 -3
- package/dist/{chunk-etqfkn4f.js.map → chunk-jbd95k1f.js.map} +1 -1
- package/dist/{chunk-z61qdct1.js → chunk-kn908zkk.js} +2 -2
- package/dist/{chunk-z61qdct1.js.map → chunk-kn908zkk.js.map} +1 -1
- package/dist/{chunk-rvx8bgqk.js → chunk-mw13a082.js} +3 -3
- package/dist/{chunk-rvx8bgqk.js.map → chunk-mw13a082.js.map} +1 -1
- package/dist/chunk-nke51f3c.js +4 -0
- package/dist/chunk-nke51f3c.js.map +10 -0
- package/dist/{chunk-ny1s8fnh.js → chunk-ns5atzyz.js} +2 -2
- package/dist/{chunk-ny1s8fnh.js.map → chunk-ns5atzyz.js.map} +1 -1
- package/dist/chunk-pp4r3hp4.js +105 -0
- package/dist/chunk-pp4r3hp4.js.map +27 -0
- package/dist/{chunk-372bgp30.js → chunk-q4nh3vst.js} +3 -3
- package/dist/{chunk-372bgp30.js.map → chunk-q4nh3vst.js.map} +1 -1
- package/dist/{chunk-585jp0rg.js → chunk-q5gqgs0p.js} +3 -3
- package/dist/chunk-q5gqgs0p.js.map +10 -0
- package/dist/{chunk-f676awyz.js → chunk-s9bsh0gp.js} +3 -3
- package/dist/{chunk-f676awyz.js.map → chunk-s9bsh0gp.js.map} +1 -1
- package/dist/chunk-ss51dw5h.js +27 -0
- package/dist/{chunk-weshapwk.js.map → chunk-ss51dw5h.js.map} +5 -5
- package/dist/{chunk-mtrcdhzn.js → chunk-xs370t8p.js} +3 -3
- package/dist/{chunk-mtrcdhzn.js.map → chunk-xs370t8p.js.map} +8 -8
- package/dist/chunk-xtrn4wn0.js +3 -0
- package/dist/{chunk-b0047ggx.js.map → chunk-xtrn4wn0.js.map} +2 -2
- package/dist/{chunk-7h737bp8.js → chunk-xvfz960r.js} +3 -3
- package/dist/{chunk-7h737bp8.js.map → chunk-xvfz960r.js.map} +1 -1
- package/dist/chunk-xytc0fks.js +27 -0
- package/dist/{chunk-vc4xy6dm.js.map → chunk-xytc0fks.js.map} +2 -2
- package/dist/chunk-yxv7hqse.js +23 -0
- package/dist/chunk-yxv7hqse.js.map +11 -0
- package/dist/chunk-zv5y8yfq.js +19 -0
- package/dist/chunk-zv5y8yfq.js.map +11 -0
- package/dist/index.js +278 -285
- package/dist/index.js.map +34 -30
- package/drizzle/0002_lyrical_random.sql +2 -0
- package/drizzle/0003_romantic_lockjaw.sql +4 -0
- package/drizzle/0004_blushing_meteorite.sql +6 -0
- package/drizzle/meta/0002_snapshot.json +920 -0
- package/drizzle/meta/0003_snapshot.json +920 -0
- package/drizzle/meta/0004_snapshot.json +921 -0
- package/drizzle/meta/_journal.json +21 -0
- package/package.json +4 -1
- package/dist/chunk-057m762a.js +0 -4
- package/dist/chunk-057m762a.js.map +0 -10
- package/dist/chunk-2j2gmjg5.js +0 -107
- package/dist/chunk-2j2gmjg5.js.map +0 -25
- package/dist/chunk-585jp0rg.js.map +0 -10
- package/dist/chunk-6eb5a8kv.js.map +0 -10
- package/dist/chunk-8ep9gk6d.js +0 -4
- package/dist/chunk-9qzv4trv.js +0 -23
- package/dist/chunk-9qzv4trv.js.map +0 -11
- package/dist/chunk-b0047ggx.js +0 -3
- package/dist/chunk-cjy100rr.js +0 -6
- package/dist/chunk-e74zv5ct.js +0 -19
- package/dist/chunk-e74zv5ct.js.map +0 -10
- package/dist/chunk-gmmm7xpw.js +0 -23
- package/dist/chunk-rsagxdqj.js +0 -161
- package/dist/chunk-vc4xy6dm.js +0 -27
- package/dist/chunk-weshapwk.js +0 -27
|
@@ -15,6 +15,27 @@
|
|
|
15
15
|
"when": 1762132080296,
|
|
16
16
|
"tag": "0001_material_pyro",
|
|
17
17
|
"breakpoints": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"idx": 2,
|
|
21
|
+
"version": "6",
|
|
22
|
+
"when": 1762198876177,
|
|
23
|
+
"tag": "0002_lyrical_random",
|
|
24
|
+
"breakpoints": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"idx": 3,
|
|
28
|
+
"version": "6",
|
|
29
|
+
"when": 1762204641153,
|
|
30
|
+
"tag": "0003_romantic_lockjaw",
|
|
31
|
+
"breakpoints": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"idx": 4,
|
|
35
|
+
"version": "6",
|
|
36
|
+
"when": 1762204810820,
|
|
37
|
+
"tag": "0004_blushing_meteorite",
|
|
38
|
+
"breakpoints": true
|
|
18
39
|
}
|
|
19
40
|
]
|
|
20
41
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/flow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "Sylphx Flow - Type-safe development flow for modern web development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -105,6 +105,9 @@
|
|
|
105
105
|
"@vitest/ui": "^4.0.6",
|
|
106
106
|
"drizzle-kit": "^0.31.6",
|
|
107
107
|
"esbuild": "^0.25.11",
|
|
108
|
+
"jscpd": "^4.0.5",
|
|
109
|
+
"madge": "^8.0.0",
|
|
110
|
+
"ts-prune": "^0.10.3",
|
|
108
111
|
"tsx": "^4.20.6",
|
|
109
112
|
"typescript": "^5.9.3",
|
|
110
113
|
"vitest": "^4.0.6"
|
package/dist/chunk-057m762a.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{Ha as b}from"./chunk-mtrcdhzn.js";import"./chunk-etqfkn4f.js";import"./chunk-cv1nhr27.js";import"./chunk-ceyg2zjg.js";import"./chunk-f9yb2zk3.js";async function A(k,q={}){return b(k).fetchModels(q)}export{A as fetchModels};
|
|
2
|
-
export{A as Ga};
|
|
3
|
-
|
|
4
|
-
//# debugId=35791A05F979131364756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/utils/ai-model-fetcher.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * AI Model Fetcher\n * Dynamically fetch available models from providers using provider registry\n */\n\nimport type { ProviderId } from '../config/ai-config.js';\nimport type { ProviderConfig } from '../providers/base-provider.js';\nimport { getProvider } from '../providers/index.js';\n\nexport interface ModelInfo {\n id: string;\n name: string;\n description?: string;\n}\n\n/**\n * Fetch models for a provider using provider registry\n */\nexport async function fetchModels(provider: ProviderId, config: ProviderConfig = {}): Promise<ModelInfo[]> {\n const providerInstance = getProvider(provider);\n return providerInstance.fetchModels(config);\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "iLAkBA,SAAsB,LAAW,LAAC,JAAsB,EAAyB,CAAC,EAAyB,CAEzG,OADyB,EAAY,CAAQ,EACrB,YAAY,CAAM",
|
|
8
|
-
"debugId": "35791A05F979131364756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
package/dist/chunk-2j2gmjg5.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import{Rb as j,Ub as N}from"./chunk-f9yb2zk3.js";async function k($,q){let{AI_PROVIDERS:F}=await import("./chunk-6eb5a8kv.js"),{getProvider:b}=await import("./chunk-mtrcdhzn.js"),G=$.getConfig(),h=b(q).getConfigSchema(),Q=h.map((Z)=>({label:Z.label,value:Z.key}));$.sendMessage(`Configure ${F[q].name} - Select setting:`);let W=await $.waitForInput({type:"selection",questions:[{id:"key",question:"Which setting do you want to configure?",options:Q}]}),H=typeof W==="object"&&!Array.isArray(W)?W.key:"";if(!H)return"Configuration cancelled.";let z=h.find((Z)=>Z.key===H),X;if(z?.type==="boolean"){$.sendMessage(`Select value for ${H}:`);let Z=await $.waitForInput({type:"selection",questions:[{id:"value",question:`${z.label}:`,options:[{label:"true",value:"true"},{label:"false",value:"false"}]}]});X=typeof Z==="object"&&!Array.isArray(Z)?Z.value:""}else{$.sendMessage(`Enter value for ${H}:`);let Z=await $.waitForInput({type:"text",prompt:`${H}:`});X=typeof Z==="string"?Z:""}if(!X)return"Value is required.";let Y={...G,providers:{...G.providers,[q]:{...G.providers?.[q],[H]:X}}};if(!G?.defaultProvider)Y.defaultProvider=q;$.setAIConfig(Y),await $.saveConfig(Y);let U=h.find((Z)=>Z.key===H)?.secret?"***":X;return`Set ${F[q].name} ${H} to: ${U}`}var z$={id:"provider",label:"/provider",description:"Manage AI providers",args:[{name:"action",description:'Action: "use" or "set"',required:!1,loadOptions:async($)=>{return[{id:"use",label:"use",value:"use"},{id:"set",label:"set",value:"set"}]}},{name:"provider-name",description:"Provider name (anthropic, openai, google, openrouter)",required:!1,loadOptions:async($)=>{let{AI_PROVIDERS:q}=await import("./chunk-6eb5a8kv.js");return Object.values(q).map((F)=>({id:F.id,label:F.name,value:F.id}))}},{name:"key",description:"Setting key (for set action)",required:!1,loadOptions:async($)=>{let q=$[1];if(!q)return[];try{let{getProvider:F}=await import("./chunk-mtrcdhzn.js");return F(q).getConfigSchema().map((h)=>({id:h.key,label:h.label,value:h.key}))}catch(F){return[]}}},{name:"value",description:"Setting value (for set action)",required:!1,loadOptions:async($)=>{let q=$[1],F=$[2];if(!q||!F)return[];try{let{getProvider:b}=await import("./chunk-mtrcdhzn.js");if(b(q).getConfigSchema().find((Q)=>Q.key===F)?.type==="boolean")return[{id:"true",label:"true",value:"true"},{id:"false",label:"false",value:"false"}];return[]}catch(b){return[]}}}],execute:async($)=>{let{AI_PROVIDERS:q}=await import("./chunk-6eb5a8kv.js"),F=$.getConfig();if($.args.length===0){$.sendMessage("What do you want to do?");let b=await $.waitForInput({type:"selection",questions:[{id:"action",question:"Select action:",options:[{label:"Use a provider",value:"use"},{label:"Configure a provider",value:"set"}]}]}),G=typeof b==="object"&&!Array.isArray(b)?b.action:"";if(!G)return"Action cancelled.";let{getProvider:J}=await import("./chunk-mtrcdhzn.js"),h=Object.values(q).map((H)=>{let z=!1;try{let X=J(H.id),Y=F?.providers?.[H.id];z=Y?X.isConfigured(Y):!1}catch{}return{label:`${H.name} ${z?"✓":""}`,value:H.id}});$.sendMessage(G==="use"?"Which provider do you want to use?":"Which provider do you want to configure?");let Q=await $.waitForInput({type:"selection",questions:[{id:"provider",question:G==="use"?"Select provider to use:":"Select provider to configure:",options:h}]}),W=typeof Q==="object"&&!Array.isArray(Q)?Q.provider:"";if(!W)return"Provider selection cancelled.";if(G==="use"){let{getProvider:H}=await import("./chunk-mtrcdhzn.js"),z=H(W),X=F?.providers?.[W];if(!X||!z.isConfigured(X)){$.sendMessage(`${q[W].name} is not configured yet.`);let O=await $.waitForInput({type:"selection",questions:[{id:"configure",question:"Do you want to configure it now?",options:[{label:"Yes, configure now",value:"yes"},{label:"No, cancel",value:"no"}]}]});if(!(typeof O==="object"&&!Array.isArray(O)?O.configure==="yes":!1))return"Cancelled. You can configure later using: /provider set";let y=await k($,W),M=$.getConfig(),D=M?.providers?.[W];if(!D||!z.isConfigured(D))return`${y}
|
|
2
|
-
|
|
3
|
-
Provider still not fully configured. Please continue configuration with: /provider set ${W}`;$.sendMessage(y);let _=D,E={...M,defaultProvider:W},{getDefaultModel:u}=await import("./chunk-vc4xy6dm.js"),T=await u(W,_);if(!T)return`Provider configured but failed to get default model for ${q[W].name}`;E.providers={...E.providers,[W]:{..._,"default-model":T}},$.setAIConfig(E),await $.saveConfig(E),$.setUISelectedProvider(W),$.setUISelectedModel(T);let w=$.getCurrentSessionId();if(w)$.updateSessionProvider(w,W,T);else $.createSession(W,T);return`Now using ${q[W].name} with model: ${T}`}let Y={...F,defaultProvider:W},{getDefaultModel:K}=await import("./chunk-vc4xy6dm.js"),U=await K(W,X);if(!U)return`Failed to get default model for ${q[W].name}`;Y.providers={...Y.providers,[W]:{...X,"default-model":U}},$.setAIConfig(Y),await $.saveConfig(Y);let Z=$.getCurrentSessionId();if(Z)$.updateSessionProvider(Z,W,U);else $.createSession(W,U);return`Switched to ${q[W].name}`}else return await k($,W)}if($.args.length===1&&$.args[0]==="use"){let{getProvider:b}=await import("./chunk-mtrcdhzn.js"),G=Object.values(q).map((K)=>{let U=!1;try{let Z=b(K.id),O=F?.providers?.[K.id];U=O?Z.isConfigured(O):!1}catch{}return{label:`${K.name} ${U?"✓":""}`,value:K.id}});$.sendMessage("Which provider do you want to use?");let J=await $.waitForInput({type:"selection",questions:[{id:"provider",question:"Select provider:",options:G}]}),h=typeof J==="object"&&!Array.isArray(J)?J.provider:"";if(!h)return"Provider selection cancelled.";let Q=b(h),W=F?.providers?.[h];if(!W||!Q.isConfigured(W)){$.sendMessage(`${q[h].name} is not configured yet.`);let K=await $.waitForInput({type:"selection",questions:[{id:"configure",question:"Do you want to configure it now?",options:[{label:"Yes, configure now",value:"yes"},{label:"No, cancel",value:"no"}]}]});if(!(typeof K==="object"&&!Array.isArray(K)?K.configure==="yes":!1))return"Cancelled. You can configure later using: /provider set";let Z=await k($,h),O=$.getConfig(),B=O?.providers?.[h];if(!B||!Q.isConfigured(B))return`${Z}
|
|
4
|
-
|
|
5
|
-
Provider still not fully configured. Please continue configuration with: /provider set ${h}`;$.sendMessage(Z);let y=B,M={...O,defaultProvider:h},{getDefaultModel:D}=await import("./chunk-vc4xy6dm.js"),_=await D(h,y);if(!_)return`Provider configured but failed to get default model for ${q[h].name}`;M.providers={...M.providers,[h]:{...y,"default-model":_}},$.setAIConfig(M),await $.saveConfig(M),$.setUISelectedProvider(h),$.setUISelectedModel(_);let E=$.getCurrentSessionId();if(E)$.updateSessionProvider(E,h,_);else $.createSession(h,_);return`Now using ${q[h].name} with model: ${_}`}let H={...F,defaultProvider:h},{getDefaultModel:z}=await import("./chunk-vc4xy6dm.js"),X=await z(h,W);if(!X)return`Failed to get default model for ${q[h].name}`;H.providers={...H.providers,[h]:{...W,"default-model":X}},$.setAIConfig(H),await $.saveConfig(H);let Y=$.getCurrentSessionId();if(Y)$.updateSessionProvider(Y,h,X);else $.createSession(h,X);return`Switched to ${q[h].name}`}if($.args.length===2&&$.args[0]==="use"){let b=$.args[1];if(!(b in q))return`Invalid provider: ${b}. Available: ${Object.keys(q).join(", ")}`;let{getProvider:G}=await import("./chunk-mtrcdhzn.js"),J=G(b),h=F?.providers?.[b];if(!h||!J.isConfigured(h))return`${q[b].name} is not configured. Use: /provider set ${b}`;let Q={...F,defaultProvider:b},{getDefaultModel:W}=await import("./chunk-vc4xy6dm.js"),H=await W(b,h);if(!H)return`Failed to get default model for ${q[b].name}`;Q.providers={...Q.providers,[b]:{...h,"default-model":H}},$.setAIConfig(Q),await $.saveConfig(Q);let z=$.getCurrentSessionId();if(z)$.updateSessionProvider(z,b,H);else $.createSession(b,H);return`Switched to ${q[b].name}`}if($.args.length===1&&$.args[0]==="set"){let b=Object.values(q).map((Y)=>({label:Y.name,value:Y.id}));$.sendMessage("Which provider do you want to configure?");let G=await $.waitForInput({type:"selection",questions:[{id:"provider",question:"Select provider:",options:b}]}),J=typeof G==="object"&&!Array.isArray(G)?G.provider:"";if(!J)return"Provider selection cancelled.";let{getProvider:h}=await import("./chunk-mtrcdhzn.js"),W=h(J).getConfigSchema(),H=W.map((Y)=>({label:Y.label,value:Y.key}));$.sendMessage(`Configure ${q[J].name} - Select setting:`);let z=await $.waitForInput({type:"selection",questions:[{id:"key",question:"Which setting do you want to configure?",options:H}]}),X=typeof z==="object"&&!Array.isArray(z)?z.key:"";if(!X)return"Configuration cancelled.";{let Y=W.find((B)=>B.key===X),K;if(Y?.type==="boolean"){$.sendMessage(`Select value for ${X}:`);let B=await $.waitForInput({type:"selection",questions:[{id:"value",question:`${Y.label}:`,options:[{label:"true",value:"true"},{label:"false",value:"false"}]}]});K=typeof B==="object"&&!Array.isArray(B)?B.value:""}else{$.sendMessage(`Enter value for ${X}:`);let B=await $.waitForInput({type:"text",placeholder:`Enter ${X}...`});K=typeof B==="string"?B:""}if(!K)return"Value is required.";let U={...F,providers:{...F.providers,[J]:{...F.providers?.[J],[X]:K}}};if(!F?.defaultProvider)U.defaultProvider=J;$.setAIConfig(U),await $.saveConfig(U);let O=W.find((B)=>B.key===X)?.secret?"***":K;return`Set ${q[J].name} ${X} to: ${O}`}}if($.args.length===2&&$.args[0]==="set"){let b=$.args[1];if(!(b in q))return`Invalid provider: ${b}. Available: ${Object.keys(q).join(", ")}`;let{getProvider:G}=await import("./chunk-mtrcdhzn.js"),h=G(b).getConfigSchema(),Q=h.map((z)=>({label:z.label,value:z.key}));$.sendMessage(`Configure ${q[b].name} - Select setting:`);let W=await $.waitForInput({type:"selection",questions:[{id:"key",question:"Which setting do you want to configure?",options:Q}]}),H=typeof W==="object"&&!Array.isArray(W)?W.key:"";if(!H)return"Configuration cancelled.";{let z=h.find((Z)=>Z.key===H),X;if(z?.type==="boolean"){$.sendMessage(`Select value for ${H}:`);let Z=await $.waitForInput({type:"selection",questions:[{id:"value",question:`${z.label}:`,options:[{label:"true",value:"true"},{label:"false",value:"false"}]}]});X=typeof Z==="object"&&!Array.isArray(Z)?Z.value:""}else{$.sendMessage(`Enter value for ${H}:`);let Z=await $.waitForInput({type:"text",placeholder:`Enter ${H}...`});X=typeof Z==="string"?Z:""}if(!X)return"Value is required.";let Y={...F,providers:{...F.providers,[b]:{...F.providers?.[b],[H]:X}}};if(!F?.defaultProvider)Y.defaultProvider=b;$.setAIConfig(Y),await $.saveConfig(Y);let U=h.find((Z)=>Z.key===H)?.secret?"***":X;return`Set ${q[b].name} ${H} to: ${U}`}}if($.args.length>=4&&$.args[0]==="set"){let b=$.args[1],G=$.args[2],J=$.args.slice(3).join(" ");if(!(b in q))return`Invalid provider: ${b}. Available: ${Object.keys(q).join(", ")}`;let{getProvider:h}=await import("./chunk-mtrcdhzn.js"),W=h(b).getConfigSchema(),H=W.map((K)=>K.key);if(!H.includes(G))return`Invalid key: ${G}. Valid keys for ${b}: ${H.join(", ")}`;let z={...F,providers:{...F.providers,[b]:{...F.providers?.[b],[G]:J}}};if(!F?.defaultProvider)z.defaultProvider=b;$.setAIConfig(z),await $.saveConfig(z);let Y=W.find((K)=>K.key===G)?.secret?"***":J;return`Set ${q[b].name} ${G} to: ${Y}`}return`Usage:
|
|
6
|
-
/provider - Select action and provider
|
|
7
|
-
/provider use - Select provider to use
|
|
8
|
-
/provider use [name] - Switch to provider
|
|
9
|
-
/provider set - Configure a provider
|
|
10
|
-
/provider set [name] - Configure specific provider
|
|
11
|
-
/provider set [name] [key] [value] - Set provider config directly`}},p=z$;var J$={id:"model",label:"/model",description:"Switch AI model",args:[{name:"model-name",description:"Model to switch to",required:!1,loadOptions:async($,q)=>{try{let F=q?.getConfig();if(!F?.providers)return[];let G=q?.getCurrentSession()?.provider||F.defaultProvider;if(!G)return[];let J=F.providers[G];if(!J)return[];try{let{fetchModels:h}=await import("./chunk-057m762a.js");return(await h(G,J)).map((W)=>({id:W.id,label:W.name,value:W.id}))}catch(h){if(q)q.addLog(`Failed to fetch models for ${G}: ${h instanceof Error?h.message:String(h)}`);return[]}}catch(F){if(q)q.addLog(`Error loading models: ${F instanceof Error?F.message:String(F)}`);return[]}}}],execute:async($)=>{let q;if($.args.length===0)try{let Q=$.getConfig();if(!Q?.providers)return"No providers configured. Please configure a provider first.";let H=$.getCurrentSession()?.provider||Q.defaultProvider;if(!H)return"No provider selected. Use /provider to select a provider first.";let z=Q.providers[H];if(!z)return`Provider ${H} is not configured.`;let X=[];try{let{fetchModels:K}=await import("./chunk-057m762a.js"),U=await K(H,z);X=U.map((Z)=>({label:Z.name,value:Z.id})),$.addLog(`Loaded ${U.length} models from ${H}`)}catch(K){let U=K instanceof Error?K.message:String(K);return $.addLog(`Failed to fetch models for ${H}: ${U}`),`Failed to load models from ${H}: ${U}`}if(X.length===0)return`No models available for ${H}`;$.sendMessage("Which model do you want to use?");let Y=await $.waitForInput({type:"selection",questions:[{id:"model",question:"Which model do you want to use?",options:X}]});q=typeof Y==="object"&&!Array.isArray(Y)?Y.model:""}catch(Q){return`Failed to load models: ${Q instanceof Error?Q.message:String(Q)}`}else q=$.args[0];let F=$.getCurrentSession(),b=$.getConfig(),G=F?.provider||b?.defaultProvider;if(!G)return"No provider configured. Please configure a provider first.";let J={...b,defaultModel:q,providers:{...b.providers,[G]:{...b.providers?.[G],"default-model":q}}};$.setAIConfig(J),await $.saveConfig(J);let h=$.getCurrentSessionId();if(h)$.updateSessionModel(h,q);else $.createSession(G,q);return`Switched to model: ${q}`}},v=J$;var Q$={id:"logs",label:"/logs",description:"View debug logs",execute:async($)=>{return $.navigateTo("logs"),"Opening debug logs..."}},I=Q$;var X$={id:"help",label:"/help",description:"Show available commands",execute:async($)=>{let{commands:q}=await import("./chunk-2j2gmjg5.js");return`Available commands:
|
|
12
|
-
${q.map((b)=>{let G=b.args?` ${b.args.map((J)=>`[${J.name}]`).join(" ")}`:"";return`${b.label}${G} - ${b.description}`}).join(`
|
|
13
|
-
`)}`}},l=X$;var Y$={id:"survey",label:"/survey",description:"Test multi-question selection (demo)",execute:async($)=>{$.sendMessage("Let me ask you a few questions...");let q=await $.waitForInput({type:"selection",questions:[{id:"language",question:"What is your favorite programming language?",options:[{label:"TypeScript"},{label:"JavaScript"},{label:"Python"},{label:"Rust"},{label:"Go"}]},{id:"framework",question:"Which framework do you prefer?",options:[{label:"React"},{label:"Vue"},{label:"Angular"},{label:"Svelte"},{label:"Solid"}]},{id:"editor",question:"What is your favorite code editor?",options:[{label:"Visual Studio Code"},{label:"Vim/Neovim"},{label:"Emacs"},{label:"Sublime Text"},{label:"Atom"}]}]});if(typeof q==="object"&&!Array.isArray(q))return`Survey completed! Your answers: ${Object.entries(q).map(([b,G])=>`${b}: ${G}`).join(", ")}`;return"Survey cancelled."}},f=Y$;var Z$={id:"context",label:"/context",description:"Display context window usage and token breakdown",execute:async($)=>{let{countTokens:q,formatTokenCount:F}=await import("./chunk-585jp0rg.js"),{getSystemPrompt:b}=await import("./chunk-9qzv4trv.js"),{getAISDKTools:G}=await import("./chunk-weshapwk.js"),J=$.getCurrentSession();if(!J)return"No active session. Start chatting first to see context usage.";let h=J.model,W=((L)=>{if(L.includes("gpt-4")){if(L.includes("32k")||L.includes("turbo"))return 128000;if(L.includes("vision"))return 128000;return 8192}if(L.includes("gpt-3.5")){if(L.includes("16k"))return 16385;return 4096}if(L.includes("claude-3")){if(L.includes("opus"))return 200000;if(L.includes("sonnet"))return 200000;if(L.includes("haiku"))return 200000}return 200000})(h);$.addLog(`[Context] Calculating token counts for ${h} (limit: ${F(W)})...`);let H=b(),z=await q(H,h),{getEnabledRulesContent:X}=await import("./chunk-cjy100rr.js"),{getCurrentSystemPrompt:Y}=await import("./chunk-7h737bp8.js"),K="You are Sylphx, an AI development assistant.",U={};try{U["Base prompt"]=await q(K,h);let L=X();if(L)U.Rules=await q(L,h);let V=Y();U["Agent prompt"]=await q(V,h)}catch(L){$.addLog(`[Context] Failed to calculate system prompt breakdown: ${L}`)}let Z=G(),O={},B=0;for(let[L,V]of Object.entries(Z)){let S={name:L,description:V.description||"",parameters:V.parameters||{}},R=JSON.stringify(S,null,0),P=await q(R,h);O[L]=P,B+=P}let y=0;for(let L of J.messages){let V=L.content;if(L.attachments&&L.attachments.length>0)try{let{readFile:R}=await import("node:fs/promises"),C=(await Promise.all(L.attachments.map(async(A)=>{try{let m=await R(A.path,"utf8");return{path:A.relativePath,content:m}}catch{return{path:A.relativePath,content:"[Error reading file]"}}}))).map((A)=>`
|
|
14
|
-
|
|
15
|
-
<file path="${A.path}">
|
|
16
|
-
${A.content}
|
|
17
|
-
</file>`).join("");V+=C}catch(R){console.warn("[Context] Failed to read attachments for token count:",R)}let S=await q(V,h);y+=S}let M=z+B+y,D=W-M,_=Math.floor(W*0.225),E=D-_,u=(M/W*100).toFixed(1),T=(z/W*100).toFixed(1),w=(B/W*100).toFixed(1),t=(y/W*100).toFixed(1),e=(E/W*100).toFixed(1),$$=(_/W*100).toFixed(1),q$=()=>{let V=Math.floor(z/W*30),S=Math.floor(B/W*30),R=Math.floor(y/W*30),C=30-(V+S+R),A="█".repeat(V)+"░".repeat(30-V),m="░".repeat(V)+"█".repeat(S)+"░".repeat(30-V-S),H$="░".repeat(V+S)+"█".repeat(R)+"░".repeat(C);return[A,m,H$]},[W$,b$,h$]=q$(),F$=Object.entries(O).sort((L,V)=>V[1]-L[1]).map(([L,V])=>` ${L}: ${F(V)} tokens`).join(`
|
|
18
|
-
`),G$=Object.entries(U).map(([L,V])=>` ${L}: ${F(V)} tokens`).join(`
|
|
19
|
-
`);return`
|
|
20
|
-
Context Usage: ${F(M)}/${F(W)} tokens (${u}%)
|
|
21
|
-
Model: ${h}
|
|
22
|
-
|
|
23
|
-
Visual Breakdown:
|
|
24
|
-
${W$} System prompt: ${F(z)} (${T}%)
|
|
25
|
-
${b$} Tools: ${F(B)} (${w}%)
|
|
26
|
-
${h$} Messages: ${F(y)} (${t}%)
|
|
27
|
-
|
|
28
|
-
Available Space:
|
|
29
|
-
• Free: ${F(E)} tokens (${e}%)
|
|
30
|
-
• Buffer: ${F(_)} tokens (${$$}%)
|
|
31
|
-
|
|
32
|
-
System Prompt Breakdown:
|
|
33
|
-
${G$}
|
|
34
|
-
|
|
35
|
-
System Tools (${Object.keys(Z).length} total):
|
|
36
|
-
${F$}
|
|
37
|
-
`.trim()}},a=Z$;var U$={id:"sessions",label:"/sessions",description:"View and switch between chat sessions",execute:async($)=>{let{formatSessionDisplay:q}=await import("./chunk-e74zv5ct.js"),F=$.getSessions();if(F.length===0)return"No sessions available. Start chatting to create a session.";let b=$.getCurrentSessionId(),G=[...F].sort((z,X)=>{let Y=X.updated-z.updated;if(Y!==0)return Y;return X.created-z.created}),J=G.map((z)=>{let X=z.id===b,Y=q(z.title,z.created);return{label:X?`${Y} (current)`:Y,value:z.id}});$.sendMessage("Select a session to switch to:");let h=await $.waitForInput({type:"selection",questions:[{id:"session",question:"Which session do you want to switch to?",options:J}]}),Q=typeof h==="object"&&!Array.isArray(h)?h.session:"";if(!Q)return"Session selection cancelled.";$.setCurrentSession(Q);let W=G.find((z)=>z.id===Q);return`Switched to session: ${W?q(W.title,W.created):"Unknown session"}`}},g=U$;var K$={id:"new",label:"/new",description:"Create a new chat session",execute:async($)=>{let q=$.getConfig();if(!q?.defaultProvider||!q?.defaultModel)return"No AI provider configured. Use /provider to configure a provider first.";let F=$.createSession(q.defaultProvider,q.defaultModel);return $.setCurrentSession(F),`Created new chat session with ${q.defaultProvider} (${q.defaultModel})`}},x=K$;var j$={id:"bashes",label:"/bashes",description:"Manage background bash processes",execute:async($)=>{let{bashManager:q}=await import("./chunk-rvx8bgqk.js"),F=q.list();if(F.length===0)return"No background bash processes found.";let b=F.map((W)=>{let H=W.isRunning?"[*] Running":"[x] Completed",z=Math.floor(W.duration/1000),X=z>60?`${Math.floor(z/60)}m ${z%60}s`:`${z}s`;return{label:`${H} [${X}] ${W.command}`,value:W.id}});$.sendMessage(`Found ${F.length} background bash process${F.length!==1?"es":""}:`);let G=await $.waitForInput({type:"selection",questions:[{id:"action",question:"What do you want to do?",options:[{label:"View details",value:"view"},{label:"Kill a process",value:"kill"},{label:"Cancel",value:"cancel"}]}]}),J=typeof G==="object"&&!Array.isArray(G)?G.action:"";if(!J||J==="cancel")return"Cancelled.";$.sendMessage("Select a process:");let h=await $.waitForInput({type:"selection",questions:[{id:"process",question:"Which process?",options:b}]}),Q=typeof h==="object"&&!Array.isArray(h)?h.process:"";if(!Q)return"No process selected.";if(J==="view"){let W=q.getOutput(Q);if(!W)return"Process not found.";let H=W.isRunning?"Running":`Completed (exit code: ${W.exitCode})`,z=Math.floor(W.duration/1000),X=`
|
|
38
|
-
Process: ${Q}
|
|
39
|
-
Command: ${W.command}
|
|
40
|
-
Status: ${H}
|
|
41
|
-
Duration: ${z}s
|
|
42
|
-
|
|
43
|
-
=== stdout ===
|
|
44
|
-
${W.stdout||"(empty)"}
|
|
45
|
-
`;if(W.stderr)X+=`
|
|
46
|
-
=== stderr ===
|
|
47
|
-
${W.stderr}`;return X.trim()}if(J==="kill"){if(!q.kill(Q))return"Failed to kill process (not found).";return`Sent termination signal to process ${Q}`}return"Unknown action."}},c=j$;var N$={id:"agent",label:"/agent",description:"Switch between AI agents with different system prompts",args:[{name:"agent-name",description:"Agent to switch to (coder, planner, etc.)",required:!1,loadOptions:async($)=>{let{getAllAgents:q}=await import("./chunk-7h737bp8.js");return q().map((b)=>({id:b.id,label:`${b.metadata.name} - ${b.metadata.description}`,value:b.id}))}}],execute:async($)=>{let{getAllAgents:q,getCurrentAgent:F,switchAgent:b}=await import("./chunk-7h737bp8.js"),G;if($.args.length===0){let W=q(),H=F();if(W.length===0)return"No agents available.";let z=W.map((Y)=>{return{label:Y.id===H.id?`${Y.metadata.name} (current) - ${Y.metadata.description}`:`${Y.metadata.name} - ${Y.metadata.description}`,value:Y.id}});$.sendMessage("Which agent do you want to use?");let X=await $.waitForInput({type:"selection",questions:[{id:"agent",question:"Select agent:",options:z}]});if(G=typeof X==="object"&&!Array.isArray(X)?X.agent:"",!G)return"Agent selection cancelled."}else G=$.args[0];if(!b(G))return`Agent not found: ${G}. Use /agent to see available agents.`;let{getAgentById:h}=await import("./chunk-7h737bp8.js"),Q=h(G);if(!Q)return"Failed to get agent details.";return`Switched to agent: ${Q.metadata.name}
|
|
48
|
-
${Q.metadata.description}`}},s=N$;var L$={id:"rules",label:"/rules",description:"Select enabled shared system prompt rules",execute:async($)=>{let{getAllRules:q,getEnabledRuleIds:F,setEnabledRules:b}=await import("./chunk-cjy100rr.js"),G=q(),J=F();if(G.length===0)return"No rules available.";let h=G.map((U)=>({label:`${U.metadata.name} - ${U.metadata.description}`,value:U.id}));$.sendMessage(`Select rules to enable (currently ${J.length} enabled):`);let Q=await $.waitForInput({type:"selection",questions:[{id:"rules",question:"Select all rules you want to enable:",options:h,multiSelect:!0,preSelected:J}]}),W=typeof Q==="object"&&!Array.isArray(Q)?Array.isArray(Q.rules)?Q.rules:[]:[];if(!Array.isArray(W))return"Rule selection cancelled.";if(!b(W))return"Failed to update rules.";let z=W.length,X=G.length-z,K=G.filter((U)=>W.includes(U.id)).map((U)=>` • ${U.metadata.name}`).join(`
|
|
49
|
-
`);return`Updated rules configuration:
|
|
50
|
-
${z} enabled, ${X} disabled
|
|
51
|
-
|
|
52
|
-
Enabled rules:
|
|
53
|
-
${K||" (none)"}`}},i=L$;var B$={id:"compact",label:"/compact",description:"Summarize current session and create a new session with the summary",execute:async($)=>{let q=$.getCurrentSession();if(!q)return"No active session to compact.";if(q.messages.length===0)return"Current session has no messages to compact.";let F=$.getConfig();if(!F?.defaultProvider||!F?.defaultModel)return"No AI provider configured. Use /provider to configure a provider first.";$.sendMessage("Analyzing conversation and creating detailed summary...");try{let{getProvider:b}=await import("./chunk-mtrcdhzn.js"),{streamText:G}=await import("./chunk-sgafqzer.js"),{getSystemPrompt:J}=await import("./chunk-9qzv4trv.js"),h=b(q.provider),Q=F.providers?.[q.provider];if(!Q||!h.isConfigured(Q))return`Provider ${q.provider} is not properly configured.`;let W=h.createClient(Q,q.model),z=`You are a conversation summarizer. Your task is to create a comprehensive, detailed summary of the following conversation that preserves ALL important information.
|
|
54
|
-
|
|
55
|
-
CRITICAL REQUIREMENTS:
|
|
56
|
-
1. DO NOT omit any important details, decisions, code snippets, file paths, commands, or configurations
|
|
57
|
-
2. Preserve technical accuracy - include exact function names, variable names, file paths, and command syntax
|
|
58
|
-
3. Maintain chronological flow of the conversation
|
|
59
|
-
4. Highlight key decisions, problems solved, and solutions implemented
|
|
60
|
-
5. Include all context that would be needed to continue this conversation naturally
|
|
61
|
-
6. Use clear markdown formatting with sections and bullet points
|
|
62
|
-
7. If code was discussed or written, include the essential parts or describe what was implemented
|
|
63
|
-
8. **CRITICAL**: If there is ongoing work or tasks in progress, create a section called "## Current Work" that describes:
|
|
64
|
-
- What was being worked on when the conversation was compacted
|
|
65
|
-
- What the next steps should be
|
|
66
|
-
- Any pending tasks or unfinished work
|
|
67
|
-
- The current state of the implementation
|
|
68
|
-
|
|
69
|
-
The summary will be used to start a fresh conversation while maintaining full context.
|
|
70
|
-
|
|
71
|
-
CONVERSATION TO SUMMARIZE:
|
|
72
|
-
${q.messages.map((B)=>{let M=B.content.filter((D)=>D.type==="text").map((D)=>D.content).join(`
|
|
73
|
-
`);if(B.attachments&&B.attachments.length>0){let D=B.attachments.map((_)=>`[Attached: ${_.relativePath}]`).join(`
|
|
74
|
-
`);M+=`
|
|
75
|
-
${D}`}return`${B.role==="user"?"User":"Assistant"}: ${M}`}).join(`
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
`)}
|
|
80
|
-
|
|
81
|
-
Please provide a detailed, structured summary now:`,X=await G({model:W,messages:[{role:"user",content:z}],maxTokens:4096}),Y="";for await(let B of X.textStream)Y+=B;if(!Y||Y.trim().length===0)return"Failed to generate summary. Please try again.";let K=$.createSession(q.provider,q.model);$.setCurrentSession(K);let U=q.messages.length,Z=q.title||"Untitled session",O=`This session is being continued from a previous conversation that ran out of context. The conversation is summarized below:
|
|
82
|
-
${Y}`;return await $.triggerAIResponse(O),`✓ Compacted session "${Z}" (${U} messages)
|
|
83
|
-
✓ Created new session with detailed summary
|
|
84
|
-
✓ Switched to new session
|
|
85
|
-
✓ AI is processing the summary and will continue working...`}catch(b){let G=b instanceof Error?b.message:String(b);return $.addLog(`[Compact] Error: ${G}`),`Failed to compact session: ${G}`}}},d=B$;var r={id:"notifications",label:"/notifications",description:"Manage notification settings for AI responses",args:[{name:"action",description:"Action to perform (show, enable, disable)",required:!0,suggestions:["show","enable","disable"]},{name:"type",description:"Notification type to configure (os, terminal, sound, all)",required:!1,suggestions:["os","terminal","sound","all"]}],async execute($,q){let{updateNotificationSettings:F,notificationSettings:b}=q;if($.length===0){q.updateOutput(`
|
|
86
|
-
❌ Please specify an action: show, enable, or disable
|
|
87
|
-
`);return}let G=$[0].toLowerCase();switch(G){case"show":q.updateOutput(`
|
|
88
|
-
\uD83D\uDD14 Notification Settings:
|
|
89
|
-
`),q.updateOutput(` OS Notifications: ${b.osNotifications?"✅ Enabled":"❌ Disabled"}
|
|
90
|
-
`),q.updateOutput(` Terminal Notifications: ${b.terminalNotifications?"✅ Enabled":"❌ Disabled"}
|
|
91
|
-
`),q.updateOutput(` Sound Effects: ${b.sound?"✅ Enabled":"❌ Disabled"}
|
|
92
|
-
`),q.updateOutput(`
|
|
93
|
-
Use /notifications enable/disable [type] to change settings.
|
|
94
|
-
`);break;case"enable":case"disable":{let J=G==="enable";if($.length===1||$[1]==="all")F({osNotifications:J,terminalNotifications:J,sound:J}),q.updateOutput(`
|
|
95
|
-
${J?"✅":"❌"} All notifications ${J?"enabled":"disabled"}
|
|
96
|
-
`);else{let h=$[1].toLowerCase(),Q={};switch(h){case"os":Q.osNotifications=J;break;case"terminal":Q.terminalNotifications=J;break;case"sound":Q.sound=J;break;default:q.updateOutput(`
|
|
97
|
-
❌ Unknown notification type: ${h}
|
|
98
|
-
`),q.updateOutput(`Valid types: os, terminal, sound, all
|
|
99
|
-
`);return}F(Q),q.updateOutput(`
|
|
100
|
-
${J?"✅":"❌"} ${h} notifications ${J?"enabled":"disabled"}
|
|
101
|
-
`)}break}default:q.updateOutput(`
|
|
102
|
-
❌ Unknown action: ${G}
|
|
103
|
-
`),q.updateOutput(`Valid actions: show, enable, disable
|
|
104
|
-
`)}}};var n={id:"dashboard",label:"/dashboard",description:"Open control panel - central hub for all features",execute:async($)=>{return $.navigateTo("dashboard"),"Opening control panel..."}};var o=[n,p,v,s,i,d,r,I,l,f,a,g,x,c];function o$($){return o.find((q)=>q.id===$)}function t$($){return o.find((q)=>q.label===$)}export{t$ as getCommandByLabel,o$ as getCommand,o as commands};
|
|
105
|
-
export{o as s};
|
|
106
|
-
|
|
107
|
-
//# debugId=4E21CB18698CD9A964756E2164756E21
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/ui/commands/helpers/provider-config.ts", "../src/ui/commands/definitions/provider.command.ts", "../src/ui/commands/definitions/model.command.ts", "../src/ui/commands/definitions/logs.command.ts", "../src/ui/commands/definitions/help.command.ts", "../src/ui/commands/definitions/survey.command.ts", "../src/ui/commands/definitions/context.command.ts", "../src/ui/commands/definitions/sessions.command.ts", "../src/ui/commands/definitions/new.command.ts", "../src/ui/commands/definitions/bashes.command.ts", "../src/ui/commands/definitions/agent.command.ts", "../src/ui/commands/definitions/rules.command.ts", "../src/ui/commands/definitions/compact.command.ts", "../src/ui/commands/definitions/notifications.command.ts", "../src/ui/commands/definitions/dashboard.command.ts", "../src/ui/commands/registry.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Provider Configuration Helper\n * Shared helper function for provider configuration\n */\n\nimport type { CommandContext } from '../types.js';\n\n/**\n * Configure a provider interactively\n */\nexport async function configureProvider(\n context: CommandContext,\n providerId: string\n): Promise<string> {\n const { AI_PROVIDERS } = await import('../../../config/ai-config.js');\n const { getProvider } = await import('../../../providers/index.js');\n const aiConfig = context.getConfig();\n\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n const availableKeys = schema.map((field) => ({\n label: field.label,\n value: field.key,\n }));\n\n context.sendMessage(\n `Configure ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} - Select setting:`\n );\n const keyAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'key',\n question: 'Which setting do you want to configure?',\n options: availableKeys,\n },\n ],\n });\n\n const key =\n typeof keyAnswers === 'object' && !Array.isArray(keyAnswers)\n ? keyAnswers['key']\n : '';\n if (!key) {\n return 'Configuration cancelled.';\n }\n\n // Ask for value - check if boolean type for selection\n const field = schema.find((f) => f.key === key);\n let value: string;\n\n if (field?.type === 'boolean') {\n context.sendMessage(`Select value for ${key}:`);\n const boolAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'value',\n question: `${field.label}:`,\n options: [\n { label: 'true', value: 'true' },\n { label: 'false', value: 'false' },\n ],\n },\n ],\n });\n value =\n typeof boolAnswers === 'object' && !Array.isArray(boolAnswers)\n ? boolAnswers['value']\n : '';\n } else {\n context.sendMessage(`Enter value for ${key}:`);\n const valueAnswers = await context.waitForInput({\n type: 'text',\n prompt: `${key}:`,\n });\n value = typeof valueAnswers === 'string' ? valueAnswers : '';\n }\n\n if (!value) {\n return 'Value is required.';\n }\n\n // Update config\n const newConfig = {\n ...aiConfig!,\n providers: {\n ...aiConfig!.providers,\n [providerId]: {\n ...aiConfig!.providers?.[\n providerId as keyof typeof aiConfig.providers\n ],\n [key]: value,\n },\n },\n };\n\n if (!aiConfig?.defaultProvider) {\n newConfig.defaultProvider = providerId;\n }\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Mask secret values in response\n const displayField = schema.find((f) => f.key === key);\n const displayValue = displayField?.secret ? '***' : value;\n\n return `Set ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} ${key} to: ${displayValue}`;\n}\n\n/**\n * Options cache for dynamic option loading\n */\nexport const optionsCache = new Map<\n string,\n Array<{ id: string; name: string }>\n>();\n",
|
|
6
|
-
"/**\n * Provider Command\n * Configure and switch AI providers\n */\n\nimport type { Command } from '../types.js';\nimport { configureProvider } from '../helpers/provider-config.js';\n\nexport const providerCommand: Command = {\n id: 'provider',\n label: '/provider',\n description: 'Manage AI providers',\n args: [\n {\n name: 'action',\n description: 'Action: \"use\" or \"set\"',\n required: false,\n loadOptions: async (previousArgs) => {\n return [\n { id: 'use', label: 'use', value: 'use' },\n { id: 'set', label: 'set', value: 'set' },\n ];\n },\n },\n {\n name: 'provider-name',\n description: 'Provider name (anthropic, openai, google, openrouter)',\n required: false,\n loadOptions: async (previousArgs) => {\n const { AI_PROVIDERS } = await import('../../../config/ai-config.js');\n return Object.values(AI_PROVIDERS).map((p) => ({\n id: p.id,\n label: p.name,\n value: p.id,\n }));\n },\n },\n {\n name: 'key',\n description: 'Setting key (for set action)',\n required: false,\n loadOptions: async (previousArgs) => {\n // previousArgs: [action, provider-name]\n // Load keys from provider's config schema\n const providerId = previousArgs[1]; // e.g., \"anthropic\", \"openai\", \"openrouter\"\n\n if (!providerId) {\n return [];\n }\n\n try {\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n // Convert schema fields to options\n const keys = schema.map(field => ({\n id: field.key,\n label: field.label,\n value: field.key,\n }));\n\n return keys;\n } catch (error) {\n // Fallback to empty if provider not found\n return [];\n }\n },\n },\n {\n name: 'value',\n description: 'Setting value (for set action)',\n required: false,\n loadOptions: async (previousArgs) => {\n // previousArgs: [action, provider-name, key]\n const providerId = previousArgs[1];\n const key = previousArgs[2];\n\n if (!providerId || !key) {\n return [];\n }\n\n try {\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n // Find the field\n const field = schema.find(f => f.key === key);\n\n // If boolean type, provide true/false options\n if (field?.type === 'boolean') {\n return [\n { id: 'true', label: 'true', value: 'true' },\n { id: 'false', label: 'false', value: 'false' },\n ];\n }\n\n return [];\n } catch (error) {\n return [];\n }\n },\n },\n ],\n execute: async (context) => {\n const { AI_PROVIDERS } = await import('../../../config/ai-config.js');\n const aiConfig = context.getConfig();\n\n // Case 1: /provider - ask use or set\n if (context.args.length === 0) {\n context.sendMessage('What do you want to do?');\n const actionAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'action',\n question: 'Select action:',\n options: [\n { label: 'Use a provider', value: 'use' },\n { label: 'Configure a provider', value: 'set' },\n ],\n },\n ],\n });\n\n const action = typeof actionAnswers === 'object' && !Array.isArray(actionAnswers) ? actionAnswers['action'] : '';\n if (!action) {\n return 'Action cancelled.';\n }\n\n // Ask which provider\n const { getProvider } = await import('../../../providers/index.js');\n const providerOptions = Object.values(AI_PROVIDERS).map((p) => {\n let isConfigured = false;\n try {\n const provider = getProvider(p.id as any);\n const providerConfig = aiConfig?.providers?.[p.id as keyof typeof aiConfig.providers];\n isConfigured = providerConfig ? provider.isConfigured(providerConfig) : false;\n } catch {\n // Provider not found or error checking config\n }\n return {\n label: `${p.name} ${isConfigured ? '✓' : ''}`,\n value: p.id,\n };\n });\n\n context.sendMessage(action === 'use' ? 'Which provider do you want to use?' : 'Which provider do you want to configure?');\n const providerAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'provider',\n question: action === 'use' ? 'Select provider to use:' : 'Select provider to configure:',\n options: providerOptions,\n },\n ],\n });\n\n const providerId = typeof providerAnswers === 'object' && !Array.isArray(providerAnswers) ? providerAnswers['provider'] : '';\n if (!providerId) {\n return 'Provider selection cancelled.';\n }\n\n if (action === 'use') {\n // Use provider\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const providerConfig = aiConfig?.providers?.[providerId as keyof typeof aiConfig.providers];\n\n if (!providerConfig || !provider.isConfigured(providerConfig)) {\n // Provider not configured - ask if user wants to configure now\n context.sendMessage(`${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} is not configured yet.`);\n const configureAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'configure',\n question: 'Do you want to configure it now?',\n options: [\n { label: 'Yes, configure now', value: 'yes' },\n { label: 'No, cancel', value: 'no' },\n ],\n },\n ],\n });\n\n const shouldConfigure = typeof configureAnswers === 'object' && !Array.isArray(configureAnswers)\n ? configureAnswers['configure'] === 'yes'\n : false;\n\n if (!shouldConfigure) {\n return 'Cancelled. You can configure later using: /provider set';\n }\n\n // Configure the provider\n const configResult = await configureProvider(context, providerId);\n\n // After configuration, get fresh config from store\n const updatedConfig = context.getConfig();\n const updatedProviderConfig = updatedConfig?.providers?.[providerId as keyof typeof updatedConfig.providers];\n\n // Check if fully configured\n if (!updatedProviderConfig || !provider.isConfigured(updatedProviderConfig)) {\n return `${configResult}\\n\\nProvider still not fully configured. Please continue configuration with: /provider set ${providerId}`;\n }\n\n // Continue with \"use\" flow - update to use this provider\n context.sendMessage(configResult);\n const providerConfigToUse = updatedProviderConfig;\n\n // Now proceed to set as default provider\n const newConfig = {\n ...updatedConfig!,\n defaultProvider: providerId,\n };\n\n // Get default model and update config\n const { getDefaultModel } = await import('../../../core/session-service.js');\n const defaultModel = await getDefaultModel(providerId as any, providerConfigToUse);\n if (!defaultModel) {\n return `Provider configured but failed to get default model for ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Save default model to config\n newConfig.providers = {\n ...newConfig.providers,\n [providerId]: {\n ...providerConfigToUse,\n 'default-model': defaultModel,\n },\n };\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Update UI state\n context.setUISelectedProvider(providerId as ProviderId);\n context.setUISelectedModel(defaultModel);\n\n // Update current session's provider (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionProvider(currentSessionId, providerId, defaultModel);\n } else {\n // Fallback: create new session if no active session\n context.createSession(providerId, defaultModel);\n }\n\n return `Now using ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} with model: ${defaultModel}`;\n }\n\n const newConfig = {\n ...aiConfig!,\n defaultProvider: providerId,\n };\n\n // Get default model and update config\n const { getDefaultModel } = await import('../../../core/session-service.js');\n const defaultModel = await getDefaultModel(providerId as any, providerConfig);\n if (!defaultModel) {\n return `Failed to get default model for ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Save default model to config\n newConfig.providers = {\n ...newConfig.providers,\n [providerId]: {\n ...providerConfig,\n 'default-model': defaultModel,\n },\n };\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Update current session's provider (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionProvider(currentSessionId, providerId, defaultModel);\n } else {\n // Fallback: create new session if no active session\n context.createSession(providerId, defaultModel);\n }\n\n return `Switched to ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n } else {\n // Set provider - use helper function\n return await configureProvider(context, providerId);\n }\n }\n\n // Case 2: /provider use - ask which provider to use\n if (context.args.length === 1 && context.args[0] === 'use') {\n const { getProvider } = await import('../../../providers/index.js');\n const providerOptions = Object.values(AI_PROVIDERS).map((p) => {\n let isConfigured = false;\n try {\n const provider = getProvider(p.id as any);\n const providerConfig = aiConfig?.providers?.[p.id as keyof typeof aiConfig.providers];\n isConfigured = providerConfig ? provider.isConfigured(providerConfig) : false;\n } catch {\n // Provider not found or error checking config\n }\n return {\n label: `${p.name} ${isConfigured ? '✓' : ''}`,\n value: p.id,\n };\n });\n\n context.sendMessage('Which provider do you want to use?');\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'provider',\n question: 'Select provider:',\n options: providerOptions,\n },\n ],\n });\n\n const providerId = typeof answers === 'object' && !Array.isArray(answers) ? answers['provider'] : '';\n if (!providerId) {\n return 'Provider selection cancelled.';\n }\n\n const provider = getProvider(providerId as any);\n const providerConfig = aiConfig?.providers?.[providerId as keyof typeof aiConfig.providers];\n\n if (!providerConfig || !provider.isConfigured(providerConfig)) {\n // Provider not configured - ask if user wants to configure now\n context.sendMessage(`${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} is not configured yet.`);\n const configureAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'configure',\n question: 'Do you want to configure it now?',\n options: [\n { label: 'Yes, configure now', value: 'yes' },\n { label: 'No, cancel', value: 'no' },\n ],\n },\n ],\n });\n\n const shouldConfigure = typeof configureAnswers === 'object' && !Array.isArray(configureAnswers)\n ? configureAnswers['configure'] === 'yes'\n : false;\n\n if (!shouldConfigure) {\n return 'Cancelled. You can configure later using: /provider set';\n }\n\n // Configure the provider\n const configResult = await configureProvider(context, providerId);\n\n // After configuration, check if it's now configured\n const updatedConfig = context.getConfig();\n const updatedProviderConfig = updatedConfig?.providers?.[providerId as keyof typeof updatedConfig.providers];\n if (!updatedProviderConfig || !provider.isConfigured(updatedProviderConfig)) {\n return `${configResult}\\n\\nProvider still not fully configured. Please continue configuration with: /provider set ${providerId}`;\n }\n\n // Continue with \"use\" flow - update to use this provider\n context.sendMessage(configResult);\n const providerConfigToUse = updatedProviderConfig;\n\n // Now proceed to set as default provider\n const newConfig = {\n ...updatedConfig!,\n defaultProvider: providerId,\n };\n\n // Get default model and update config\n const { getDefaultModel } = await import('../../../core/session-service.js');\n const defaultModel = await getDefaultModel(providerId as any, providerConfigToUse);\n if (!defaultModel) {\n return `Provider configured but failed to get default model for ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Save default model to config\n newConfig.providers = {\n ...newConfig.providers,\n [providerId]: {\n ...providerConfigToUse,\n 'default-model': defaultModel,\n },\n };\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Update UI state\n context.setUISelectedProvider(providerId as ProviderId);\n context.setUISelectedModel(defaultModel);\n\n // Update current session's provider (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionProvider(currentSessionId, providerId, defaultModel);\n } else {\n // Fallback: create new session if no active session\n context.createSession(providerId, defaultModel);\n }\n\n return `Now using ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} with model: ${defaultModel}`;\n }\n\n const newConfig = {\n ...aiConfig!,\n defaultProvider: providerId,\n };\n\n // Get default model and update config\n const { getDefaultModel } = await import('../../../core/session-service.js');\n const defaultModel = await getDefaultModel(providerId as any, providerConfig);\n if (!defaultModel) {\n return `Failed to get default model for ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Save default model to config\n newConfig.providers = {\n ...newConfig.providers,\n [providerId]: {\n ...providerConfig,\n 'default-model': defaultModel,\n },\n };\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Update current session's provider (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionProvider(currentSessionId, providerId, defaultModel);\n } else {\n // Fallback: create new session if no active session\n context.createSession(providerId, defaultModel);\n }\n\n return `Switched to ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Case 3: /provider use [name] - switch to specific provider\n if (context.args.length === 2 && context.args[0] === 'use') {\n const providerId = context.args[1];\n\n if (!(providerId in AI_PROVIDERS)) {\n return `Invalid provider: ${providerId}. Available: ${Object.keys(AI_PROVIDERS).join(', ')}`;\n }\n\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const providerConfig = aiConfig?.providers?.[providerId as keyof typeof aiConfig.providers];\n\n if (!providerConfig || !provider.isConfigured(providerConfig)) {\n return `${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} is not configured. Use: /provider set ${providerId}`;\n }\n\n const newConfig = {\n ...aiConfig!,\n defaultProvider: providerId,\n };\n\n // Get default model and update config\n const { getDefaultModel } = await import('../../../core/session-service.js');\n const defaultModel = await getDefaultModel(providerId as any, providerConfig);\n if (!defaultModel) {\n return `Failed to get default model for ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Save default model to config\n newConfig.providers = {\n ...newConfig.providers,\n [providerId]: {\n ...providerConfig,\n 'default-model': defaultModel,\n },\n };\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Update current session's provider (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionProvider(currentSessionId, providerId, defaultModel);\n } else {\n // Fallback: create new session if no active session\n context.createSession(providerId, defaultModel);\n }\n\n return `Switched to ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name}`;\n }\n\n // Case 4: /provider set - ask which provider to configure\n if (context.args.length === 1 && context.args[0] === 'set') {\n const providerOptions = Object.values(AI_PROVIDERS).map((p) => ({\n label: p.name,\n value: p.id,\n }));\n\n context.sendMessage('Which provider do you want to configure?');\n const providerAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'provider',\n question: 'Select provider:',\n options: providerOptions,\n },\n ],\n });\n\n const providerId = typeof providerAnswers === 'object' && !Array.isArray(providerAnswers) ? providerAnswers['provider'] : '';\n if (!providerId) {\n return 'Provider selection cancelled.';\n }\n\n // Ask for key\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n const availableKeys = schema.map(field => ({\n label: field.label,\n value: field.key,\n }));\n\n\n context.sendMessage(`Configure ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} - Select setting:`);\n const keyAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'key',\n question: 'Which setting do you want to configure?',\n options: availableKeys,\n },\n ],\n });\n\n const key = typeof keyAnswers === 'object' && !Array.isArray(keyAnswers) ? keyAnswers['key'] : '';\n if (!key) {\n return 'Configuration cancelled.';\n }\n\n // Ask for value - check if boolean type for selection\n {\n const field = schema.find(f => f.key === key);\n let value: string;\n\n if (field?.type === 'boolean') {\n context.sendMessage(`Select value for ${key}:`);\n const boolAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'value',\n question: `${field.label}:`,\n options: [\n { label: 'true', value: 'true' },\n { label: 'false', value: 'false' },\n ],\n },\n ],\n });\n value = typeof boolAnswers === 'object' && !Array.isArray(boolAnswers) ? boolAnswers['value'] : '';\n } else {\n context.sendMessage(`Enter value for ${key}:`);\n const valueAnswers = await context.waitForInput({\n type: 'text',\n placeholder: `Enter ${key}...`,\n });\n value = typeof valueAnswers === 'string' ? valueAnswers : '';\n }\n\n if (!value) {\n return 'Value is required.';\n }\n\n // Update config\n const newConfig = {\n ...aiConfig!,\n providers: {\n ...aiConfig!.providers,\n [providerId]: {\n ...aiConfig!.providers?.[providerId as keyof typeof aiConfig.providers],\n [key]: value,\n },\n },\n };\n\n if (!aiConfig?.defaultProvider) {\n newConfig.defaultProvider = providerId;\n }\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Mask secret values in response\n const displayField = schema.find(f => f.key === key);\n const displayValue = displayField?.secret ? '***' : value;\n\n return `Set ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} ${key} to: ${displayValue}`;\n }\n }\n\n // Case 5: /provider set [name] - ask which key to set\n if (context.args.length === 2 && context.args[0] === 'set') {\n const providerId = context.args[1];\n\n if (!(providerId in AI_PROVIDERS)) {\n return `Invalid provider: ${providerId}. Available: ${Object.keys(AI_PROVIDERS).join(', ')}`;\n }\n\n // Ask for key\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n const availableKeys = schema.map(field => ({\n label: field.label,\n value: field.key,\n }));\n\n\n context.sendMessage(`Configure ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} - Select setting:`);\n const keyAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'key',\n question: 'Which setting do you want to configure?',\n options: availableKeys,\n },\n ],\n });\n\n const key = typeof keyAnswers === 'object' && !Array.isArray(keyAnswers) ? keyAnswers['key'] : '';\n if (!key) {\n return 'Configuration cancelled.';\n }\n\n // Ask for value - check if boolean type for selection\n {\n const field = schema.find(f => f.key === key);\n let value: string;\n\n if (field?.type === 'boolean') {\n context.sendMessage(`Select value for ${key}:`);\n const boolAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'value',\n question: `${field.label}:`,\n options: [\n { label: 'true', value: 'true' },\n { label: 'false', value: 'false' },\n ],\n },\n ],\n });\n value = typeof boolAnswers === 'object' && !Array.isArray(boolAnswers) ? boolAnswers['value'] : '';\n } else {\n context.sendMessage(`Enter value for ${key}:`);\n const valueAnswers = await context.waitForInput({\n type: 'text',\n placeholder: `Enter ${key}...`,\n });\n value = typeof valueAnswers === 'string' ? valueAnswers : '';\n }\n\n if (!value) {\n return 'Value is required.';\n }\n\n // Update config\n const newConfig = {\n ...aiConfig!,\n providers: {\n ...aiConfig!.providers,\n [providerId]: {\n ...aiConfig!.providers?.[providerId as keyof typeof aiConfig.providers],\n [key]: value,\n },\n },\n };\n\n if (!aiConfig?.defaultProvider) {\n newConfig.defaultProvider = providerId;\n }\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Mask secret values in response\n const displayField = schema.find(f => f.key === key);\n const displayValue = displayField?.secret ? '***' : value;\n\n return `Set ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} ${key} to: ${displayValue}`;\n }\n }\n\n // Case 6: /provider set [name] [key] [value] - direct configuration\n if (context.args.length >= 4 && context.args[0] === 'set') {\n const providerId = context.args[1];\n const key = context.args[2];\n const value = context.args.slice(3).join(' ');\n\n if (!(providerId in AI_PROVIDERS)) {\n return `Invalid provider: ${providerId}. Available: ${Object.keys(AI_PROVIDERS).join(', ')}`;\n }\n\n // Get valid keys from provider schema\n const { getProvider } = await import('../../../providers/index.js');\n const provider = getProvider(providerId as any);\n const schema = provider.getConfigSchema();\n\n const validKeys = schema.map(f => f.key);\n if (!validKeys.includes(key)) {\n return `Invalid key: ${key}. Valid keys for ${providerId}: ${validKeys.join(', ')}`;\n }\n\n const newConfig = {\n ...aiConfig!,\n providers: {\n ...aiConfig!.providers,\n [providerId]: {\n ...aiConfig!.providers?.[providerId as keyof typeof aiConfig.providers],\n [key]: value,\n },\n },\n };\n\n if (!aiConfig?.defaultProvider) {\n newConfig.defaultProvider = providerId;\n }\n\n context.setAIConfig(newConfig);\n await context.saveConfig(newConfig);\n\n // Mask secret values in response\n const field = schema.find(f => f.key === key);\n const displayValue = field?.secret ? '***' : value;\n\n return `Set ${AI_PROVIDERS[providerId as keyof typeof AI_PROVIDERS].name} ${key} to: ${displayValue}`;\n }\n\n return 'Usage:\\n /provider - Select action and provider\\n /provider use - Select provider to use\\n /provider use [name] - Switch to provider\\n /provider set - Configure a provider\\n /provider set [name] - Configure specific provider\\n /provider set [name] [key] [value] - Set provider config directly';\n },\n};\n\nexport default providerCommand;\n",
|
|
7
|
-
"/**\n * Model Command\n * Switch AI model\n */\n\nimport type { Command } from '../types.js';\n\nexport const modelCommand: Command = {\n id: 'model',\n label: '/model',\n description: 'Switch AI model',\n args: [\n {\n name: 'model-name',\n description: 'Model to switch to',\n required: false,\n loadOptions: async (previousArgs, context) => {\n try {\n // Get AI config from context\n const aiConfig = context?.getConfig();\n if (!aiConfig?.providers) {\n return [];\n }\n\n // Get current session's provider\n const currentSession = context?.getCurrentSession();\n const currentProviderId = currentSession?.provider || aiConfig.defaultProvider;\n\n if (!currentProviderId) {\n return [];\n }\n\n // Fetch models from current provider only\n const config = aiConfig.providers[currentProviderId];\n if (!config) {\n return [];\n }\n\n try {\n const { fetchModels } = await import('../../../utils/ai-model-fetcher.js');\n const models = await fetchModels(currentProviderId as any, config);\n return models.map(m => ({\n id: m.id,\n label: m.name,\n value: m.id,\n }));\n } catch (error) {\n if (context) {\n context.addLog(`Failed to fetch models for ${currentProviderId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n return [];\n }\n } catch (error) {\n if (context) {\n context.addLog(`Error loading models: ${error instanceof Error ? error.message : String(error)}`);\n }\n return [];\n }\n },\n },\n ],\n execute: async (context) => {\n let modelId: string;\n\n // If no args provided, ask user to select\n if (context.args.length === 0) {\n try {\n // Load models from current provider only\n const aiConfig = context.getConfig();\n if (!aiConfig?.providers) {\n return 'No providers configured. Please configure a provider first.';\n }\n\n // Get current session's provider\n const currentSession = context.getCurrentSession();\n const currentProviderId = currentSession?.provider || aiConfig.defaultProvider;\n\n if (!currentProviderId) {\n return 'No provider selected. Use /provider to select a provider first.';\n }\n\n const config = aiConfig.providers[currentProviderId];\n if (!config) {\n return `Provider ${currentProviderId} is not configured.`;\n }\n\n // Fetch models from current provider\n let allModels: Array<{ label: string; value: string }> = [];\n try {\n const { fetchModels } = await import('../../../utils/ai-model-fetcher.js');\n const models = await fetchModels(currentProviderId as any, config);\n allModels = models.map(m => ({ label: m.name, value: m.id }));\n context.addLog(`Loaded ${models.length} models from ${currentProviderId}`);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n context.addLog(`Failed to fetch models for ${currentProviderId}: ${errorMsg}`);\n return `Failed to load models from ${currentProviderId}: ${errorMsg}`;\n }\n\n if (allModels.length === 0) {\n return `No models available for ${currentProviderId}`;\n }\n\n // Ask user to select\n context.sendMessage('Which model do you want to use?');\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'model',\n question: 'Which model do you want to use?',\n options: allModels,\n },\n ],\n });\n\n // Extract answer from Record\n modelId = typeof answers === 'object' && !Array.isArray(answers) ? answers['model'] : '';\n } catch (error) {\n return `Failed to load models: ${error instanceof Error ? error.message : String(error)}`;\n }\n } else {\n modelId = context.args[0];\n }\n\n const currentSession = context.getCurrentSession();\n const aiConfig = context.getConfig();\n const provider = currentSession?.provider || aiConfig?.defaultProvider;\n\n if (!provider) {\n return 'No provider configured. Please configure a provider first.';\n }\n\n // Update model and save to provider config\n const newConfig = {\n ...aiConfig!,\n defaultModel: modelId,\n providers: {\n ...aiConfig!.providers,\n [provider]: {\n ...aiConfig!.providers?.[provider],\n 'default-model': modelId,\n },\n },\n };\n context.setAIConfig(newConfig);\n\n // Save config to file\n await context.saveConfig(newConfig);\n\n // Update current session's model (preserve history)\n const currentSessionId = context.getCurrentSessionId();\n if (currentSessionId) {\n context.updateSessionModel(currentSessionId, modelId);\n } else {\n // Fallback: create new session if no active session\n context.createSession(provider, modelId);\n }\n\n return `Switched to model: ${modelId}`;\n },\n};\n\nexport default modelCommand;\n",
|
|
8
|
-
"/**\n * Logs Command\n * View debug logs\n */\n\nimport type { Command } from '../types.js';\n\nexport const logsCommand: Command = {\n id: 'logs',\n label: '/logs',\n description: 'View debug logs',\n execute: async (context) => {\n context.navigateTo('logs');\n return 'Opening debug logs...';\n },\n};\n\nexport default logsCommand;\n",
|
|
9
|
-
"/**\n * Help Command\n * Show available commands\n */\n\nimport type { Command } from '../types.js';\n\nexport const helpCommand: Command = {\n id: 'help',\n label: '/help',\n description: 'Show available commands',\n execute: async (context) => {\n const { commands } = await import('../registry.js');\n const commandList = commands\n .map((cmd) => {\n const argsText = cmd.args\n ? ` ${cmd.args.map((a) => `[${a.name}]`).join(' ')}`\n : '';\n return `${cmd.label}${argsText} - ${cmd.description}`;\n })\n .join('\\n');\n return `Available commands:\\n${commandList}`;\n },\n};\n\nexport default helpCommand;\n",
|
|
10
|
-
"/**\n * Survey Command\n * Test multi-selection feature\n */\n\nimport type { Command } from '../types.js';\n\nexport const surveyCommand: Command = {\n id: 'survey',\n label: '/survey',\n description: 'Test multi-question selection (demo)',\n execute: async (context) => {\n context.sendMessage('Let me ask you a few questions...');\n\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'language',\n question: 'What is your favorite programming language?',\n options: [\n { label: 'TypeScript' },\n { label: 'JavaScript' },\n { label: 'Python' },\n { label: 'Rust' },\n { label: 'Go' },\n ],\n },\n {\n id: 'framework',\n question: 'Which framework do you prefer?',\n options: [\n { label: 'React' },\n { label: 'Vue' },\n { label: 'Angular' },\n { label: 'Svelte' },\n { label: 'Solid' },\n ],\n },\n {\n id: 'editor',\n question: 'What is your favorite code editor?',\n options: [\n { label: 'Visual Studio Code' },\n { label: 'Vim/Neovim' },\n { label: 'Emacs' },\n { label: 'Sublime Text' },\n { label: 'Atom' },\n ],\n },\n ],\n });\n\n if (typeof answers === 'object' && !Array.isArray(answers)) {\n const summary = Object.entries(answers)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ');\n return `Survey completed! Your answers: ${summary}`;\n }\n\n return 'Survey cancelled.';\n },\n};\n\nexport default surveyCommand;\n",
|
|
11
|
-
"/**\n * Context Command\n * Display context window usage\n */\n\nimport type { Command } from '../types.js';\n\nexport const contextCommand: Command = {\n id: 'context',\n label: '/context',\n description: 'Display context window usage and token breakdown',\n execute: async (context) => {\n const { countTokens, formatTokenCount } = await import('../../../utils/token-counter.js');\n const { getSystemPrompt } = await import('../../../core/ai-sdk.js');\n const { getAISDKTools } = await import('../../../tools/index.js');\n\n const currentSession = context.getCurrentSession();\n if (!currentSession) {\n return 'No active session. Start chatting first to see context usage.';\n }\n\n const modelName = currentSession.model;\n\n // Get model-specific context limit\n const getContextLimit = (model: string): number => {\n // Default limits for common models\n if (model.includes('gpt-4')) {\n if (model.includes('32k') || model.includes('turbo')) return 128000;\n if (model.includes('vision')) return 128000;\n return 8192; // Original GPT-4\n }\n if (model.includes('gpt-3.5')) {\n if (model.includes('16k')) return 16385;\n return 4096; // Original GPT-3.5\n }\n // Claude models\n if (model.includes('claude-3')) {\n if (model.includes('opus')) return 200000;\n if (model.includes('sonnet')) return 200000;\n if (model.includes('haiku')) return 200000;\n }\n // Default fallback\n return 200000;\n };\n\n const contextLimit = getContextLimit(modelName);\n\n // Calculate token counts\n context.addLog(`[Context] Calculating token counts for ${modelName} (limit: ${formatTokenCount(contextLimit)})...`);\n\n // System prompt tokens - use the actual system prompt that gets sent\n const systemPrompt = getSystemPrompt();\n const systemPromptTokens = await countTokens(systemPrompt, modelName);\n\n // Also calculate breakdown of system prompt components for debugging\n const { getEnabledRulesContent } = await import('../../../core/rule-manager.js');\n const { getCurrentSystemPrompt } = await import('../../../core/agent-manager.js');\n const BASE_SYSTEM_PROMPT = `You are Sylphx, an AI development assistant.`;\n\n let systemPromptBreakdown: Record<string, number> = {};\n try {\n systemPromptBreakdown['Base prompt'] = await countTokens(BASE_SYSTEM_PROMPT, modelName);\n\n const rulesContent = getEnabledRulesContent();\n if (rulesContent) {\n systemPromptBreakdown['Rules'] = await countTokens(rulesContent, modelName);\n }\n\n const agentPrompt = getCurrentSystemPrompt();\n systemPromptBreakdown['Agent prompt'] = await countTokens(agentPrompt, modelName);\n } catch (error) {\n context.addLog(`[Context] Failed to calculate system prompt breakdown: ${error}`);\n }\n\n // System tools tokens (calculate individual tool tokens)\n const tools = getAISDKTools();\n const toolTokens: Record<string, number> = {};\n let toolsTokensTotal = 0;\n\n for (const [toolName, toolDef] of Object.entries(tools)) {\n // Create a more accurate representation of how tools are sent to the AI\n // Tools are typically sent as function definitions with name, description, and parameters\n const toolRepresentation = {\n name: toolName,\n description: toolDef.description || '',\n parameters: toolDef.parameters || {}\n };\n const toolJson = JSON.stringify(toolRepresentation, null, 0); // No spaces for compact representation\n const tokens = await countTokens(toolJson, modelName);\n toolTokens[toolName] = tokens;\n toolsTokensTotal += tokens;\n }\n\n // Messages tokens - include attachments and parts for accurate calculation\n let messagesTokens = 0;\n for (const msg of currentSession.messages) {\n let msgText = msg.content;\n\n // Add attachment content if present (as it would be sent to AI)\n if (msg.attachments && msg.attachments.length > 0) {\n try {\n const { readFile } = await import('node:fs/promises');\n const fileContents = await Promise.all(\n msg.attachments.map(async (att) => {\n try {\n const content = await readFile(att.path, 'utf8');\n return { path: att.relativePath, content };\n } catch {\n return { path: att.relativePath, content: '[Error reading file]' };\n }\n })\n );\n\n const fileContentsText = fileContents\n .map((f) => `\\n\\n<file path=\"${f.path}\">\\n${f.content}\\n</file>`)\n .join('');\n\n msgText += fileContentsText;\n } catch (error) {\n // If we can't read attachments, just count the content we have\n console.warn('[Context] Failed to read attachments for token count:', error);\n }\n }\n\n const msgTokens = await countTokens(msgText, modelName);\n messagesTokens += msgTokens;\n }\n\n // Calculate totals and percentages\n const usedTokens = systemPromptTokens + toolsTokensTotal + messagesTokens;\n const freeTokens = contextLimit - usedTokens;\n const autocompactBuffer = Math.floor(contextLimit * 0.225); // 22.5%\n const realFreeTokens = freeTokens - autocompactBuffer;\n\n const usedPercent = ((usedTokens / contextLimit) * 100).toFixed(1);\n const systemPromptPercent = ((systemPromptTokens / contextLimit) * 100).toFixed(1);\n const toolsPercent = ((toolsTokensTotal / contextLimit) * 100).toFixed(1);\n const messagesPercent = ((messagesTokens / contextLimit) * 100).toFixed(1);\n const freePercent = ((realFreeTokens / contextLimit) * 100).toFixed(1);\n const bufferPercent = ((autocompactBuffer / contextLimit) * 100).toFixed(1);\n\n // Create visual bar chart (30 blocks for better resolution)\n const createBarChart = (): string[] => {\n const totalBlocks = 30;\n const systemPromptBlocks = Math.floor((systemPromptTokens / contextLimit) * totalBlocks);\n const toolsBlocks = Math.floor((toolsTokensTotal / contextLimit) * totalBlocks);\n const messagesBlocks = Math.floor((messagesTokens / contextLimit) * totalBlocks);\n const usedBlocks = systemPromptBlocks + toolsBlocks + messagesBlocks;\n const freeBlocks = totalBlocks - usedBlocks;\n\n // Line 1: System prompt (blue)\n const line1 = '█'.repeat(systemPromptBlocks) + '░'.repeat(totalBlocks - systemPromptBlocks);\n\n // Line 2: Tools (green)\n const line2 = '░'.repeat(systemPromptBlocks) + '█'.repeat(toolsBlocks) + '░'.repeat(totalBlocks - systemPromptBlocks - toolsBlocks);\n\n // Line 3: Messages (yellow)\n const line3 = '░'.repeat(systemPromptBlocks + toolsBlocks) + '█'.repeat(messagesBlocks) + '░'.repeat(freeBlocks);\n\n return [line1, line2, line3];\n };\n\n const [bar1, bar2, bar3] = createBarChart();\n\n // Format tool list with tokens (sorted by size)\n const toolList = Object.entries(toolTokens)\n .sort((a, b) => b[1] - a[1])\n .map(([name, tokens]) => ` ${name}: ${formatTokenCount(tokens)} tokens`)\n .join('\\n');\n\n // Format system prompt breakdown\n const systemPromptBreakdownText = Object.entries(systemPromptBreakdown)\n .map(([name, tokens]) => ` ${name}: ${formatTokenCount(tokens)} tokens`)\n .join('\\n');\n\n // Format output with clean visual hierarchy\n const output = `\nContext Usage: ${formatTokenCount(usedTokens)}/${formatTokenCount(contextLimit)} tokens (${usedPercent}%)\nModel: ${modelName}\n\nVisual Breakdown:\n ${bar1} System prompt: ${formatTokenCount(systemPromptTokens)} (${systemPromptPercent}%)\n ${bar2} Tools: ${formatTokenCount(toolsTokensTotal)} (${toolsPercent}%)\n ${bar3} Messages: ${formatTokenCount(messagesTokens)} (${messagesPercent}%)\n\nAvailable Space:\n • Free: ${formatTokenCount(realFreeTokens)} tokens (${freePercent}%)\n • Buffer: ${formatTokenCount(autocompactBuffer)} tokens (${bufferPercent}%)\n\nSystem Prompt Breakdown:\n${systemPromptBreakdownText}\n\nSystem Tools (${Object.keys(tools).length} total):\n${toolList}\n`.trim();\n\n return output;\n },\n};\n\nexport default contextCommand;\n",
|
|
12
|
-
"/**\n * Sessions Command\n * Switch between chat sessions\n */\n\nimport type { Command } from '../types.js';\n\nexport const sessionsCommand: Command = {\n id: 'sessions',\n label: '/sessions',\n description: 'View and switch between chat sessions',\n execute: async (context) => {\n const { formatSessionDisplay } = await import('../../../utils/session-title.js');\n const sessions = context.getSessions();\n\n if (sessions.length === 0) {\n return 'No sessions available. Start chatting to create a session.';\n }\n\n const currentSessionId = context.getCurrentSessionId();\n\n // Sort sessions by updated time (most recent first), then by created time\n const sortedSessions = [...sessions].sort((a, b) => {\n // First compare by updated time (descending)\n const updateDiff = b.updated - a.updated;\n if (updateDiff !== 0) return updateDiff;\n \n // If updated is same, compare by created time (descending)\n return b.created - a.created;\n });\n\n // Ask user to select a session\n const sessionOptions = sortedSessions.map((session) => {\n const isCurrent = session.id === currentSessionId;\n const displayText = formatSessionDisplay(session.title, session.created);\n const label = isCurrent ? `${displayText} (current)` : displayText;\n\n return {\n label,\n value: session.id,\n };\n });\n\n context.sendMessage('Select a session to switch to:');\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'session',\n question: 'Which session do you want to switch to?',\n options: sessionOptions,\n },\n ],\n });\n\n const selectedSessionId = typeof answers === 'object' && !Array.isArray(answers) ? answers['session'] : '';\n\n if (!selectedSessionId) {\n return 'Session selection cancelled.';\n }\n\n // Switch to selected session\n context.setCurrentSession(selectedSessionId);\n\n const selectedSession = sortedSessions.find((s) => s.id === selectedSessionId);\n const displayName = selectedSession\n ? formatSessionDisplay(selectedSession.title, selectedSession.created)\n : 'Unknown session';\n\n return `Switched to session: ${displayName}`;\n },\n};\n\nexport default sessionsCommand;\n",
|
|
13
|
-
"/**\n * New Command\n * Create a new chat session\n */\n\nimport type { Command } from '../types.js';\n\nexport const newCommand: Command = {\n id: 'new',\n label: '/new',\n description: 'Create a new chat session',\n execute: async (context) => {\n const aiConfig = context.getConfig();\n\n if (!aiConfig?.defaultProvider || !aiConfig?.defaultModel) {\n return 'No AI provider configured. Use /provider to configure a provider first.';\n }\n\n // Create new session with current provider and model\n const newSessionId = context.createSession(aiConfig.defaultProvider, aiConfig.defaultModel);\n context.setCurrentSession(newSessionId);\n\n return `Created new chat session with ${aiConfig.defaultProvider} (${aiConfig.defaultModel})`;\n },\n};\n\nexport default newCommand;\n",
|
|
14
|
-
"/**\n * Bashes Command\n * Manage background bash processes\n */\n\nimport type { Command } from '../types.js';\n\nexport const bashesCommand: Command = {\n id: 'bashes',\n label: '/bashes',\n description: 'Manage background bash processes',\n execute: async (context) => {\n const { bashManager } = await import('../../../tools/bash-manager.js');\n const processes = bashManager.list();\n\n if (processes.length === 0) {\n return 'No background bash processes found.';\n }\n\n // Format process list\n const processOptions = processes.map((proc) => {\n const status = proc.isRunning ? '[*] Running' : '[x] Completed';\n const duration = Math.floor(proc.duration / 1000);\n const durationStr = duration > 60\n ? `${Math.floor(duration / 60)}m ${duration % 60}s`\n : `${duration}s`;\n\n return {\n label: `${status} [${durationStr}] ${proc.command}`,\n value: proc.id,\n };\n });\n\n context.sendMessage(`Found ${processes.length} background bash process${processes.length !== 1 ? 'es' : ''}:`);\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'action',\n question: 'What do you want to do?',\n options: [\n { label: 'View details', value: 'view' },\n { label: 'Kill a process', value: 'kill' },\n { label: 'Cancel', value: 'cancel' },\n ],\n },\n ],\n });\n\n const action = typeof answers === 'object' && !Array.isArray(answers) ? answers['action'] : '';\n\n if (!action || action === 'cancel') {\n return 'Cancelled.';\n }\n\n // Select process\n context.sendMessage('Select a process:');\n const processAnswers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'process',\n question: 'Which process?',\n options: processOptions,\n },\n ],\n });\n\n const selectedId = typeof processAnswers === 'object' && !Array.isArray(processAnswers)\n ? processAnswers['process']\n : '';\n\n if (!selectedId) {\n return 'No process selected.';\n }\n\n if (action === 'view') {\n const output = bashManager.getOutput(selectedId);\n if (!output) {\n return 'Process not found.';\n }\n\n const status = output.isRunning ? 'Running' : `Completed (exit code: ${output.exitCode})`;\n const duration = Math.floor(output.duration / 1000);\n\n let result = `\nProcess: ${selectedId}\nCommand: ${output.command}\nStatus: ${status}\nDuration: ${duration}s\n\n=== stdout ===\n${output.stdout || '(empty)'}\n`;\n\n if (output.stderr) {\n result += `\n=== stderr ===\n${output.stderr}`;\n }\n\n return result.trim();\n }\n\n if (action === 'kill') {\n const success = bashManager.kill(selectedId);\n if (!success) {\n return 'Failed to kill process (not found).';\n }\n\n return `Sent termination signal to process ${selectedId}`;\n }\n\n return 'Unknown action.';\n },\n};\n\nexport default bashesCommand;\n",
|
|
15
|
-
"/**\n * Agent Command\n * Switch between agents\n */\n\nimport type { Command } from '../types.js';\n\nexport const agentCommand: Command = {\n id: 'agent',\n label: '/agent',\n description: 'Switch between AI agents with different system prompts',\n args: [\n {\n name: 'agent-name',\n description: 'Agent to switch to (coder, planner, etc.)',\n required: false,\n loadOptions: async (previousArgs) => {\n const { getAllAgents } = await import('../../../core/agent-manager.js');\n const agents = getAllAgents();\n return agents.map((agent) => ({\n id: agent.id,\n label: `${agent.metadata.name} - ${agent.metadata.description}`,\n value: agent.id,\n }));\n },\n },\n ],\n execute: async (context) => {\n const { getAllAgents, getCurrentAgent, switchAgent } = await import('../../../core/agent-manager.js');\n\n let agentId: string;\n\n // If no args provided, ask user to select\n if (context.args.length === 0) {\n const agents = getAllAgents();\n const currentAgent = getCurrentAgent();\n\n if (agents.length === 0) {\n return 'No agents available.';\n }\n\n // Create options with current agent indicator\n const agentOptions = agents.map((agent) => {\n const isCurrent = agent.id === currentAgent.id;\n const label = isCurrent\n ? `${agent.metadata.name} (current) - ${agent.metadata.description}`\n : `${agent.metadata.name} - ${agent.metadata.description}`;\n\n return {\n label,\n value: agent.id,\n };\n });\n\n context.sendMessage('Which agent do you want to use?');\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'agent',\n question: 'Select agent:',\n options: agentOptions,\n },\n ],\n });\n\n agentId = typeof answers === 'object' && !Array.isArray(answers) ? answers['agent'] : '';\n\n if (!agentId) {\n return 'Agent selection cancelled.';\n }\n } else {\n agentId = context.args[0];\n }\n\n // Switch to selected agent\n const success = switchAgent(agentId);\n\n if (!success) {\n return `Agent not found: ${agentId}. Use /agent to see available agents.`;\n }\n\n const { getAgentById } = await import('../../../core/agent-manager.js');\n const selectedAgent = getAgentById(agentId);\n\n if (!selectedAgent) {\n return 'Failed to get agent details.';\n }\n\n return `Switched to agent: ${selectedAgent.metadata.name}\\n${selectedAgent.metadata.description}`;\n },\n};\n\nexport default agentCommand;\n",
|
|
16
|
-
"/**\n * Rules Command\n * Select enabled shared system prompt rules\n */\n\nimport type { Command } from '../types.js';\n\nexport const rulesCommand: Command = {\n id: 'rules',\n label: '/rules',\n description: 'Select enabled shared system prompt rules',\n execute: async (context) => {\n const { getAllRules, getEnabledRuleIds, setEnabledRules } = await import('../../../core/rule-manager.js');\n\n const allRules = getAllRules();\n const enabledIds = getEnabledRuleIds();\n\n if (allRules.length === 0) {\n return 'No rules available.';\n }\n\n // Create options without status indicators (checkboxes will show selection)\n const ruleOptions = allRules.map((rule) => ({\n label: `${rule.metadata.name} - ${rule.metadata.description}`,\n value: rule.id,\n }));\n\n context.sendMessage(`Select rules to enable (currently ${enabledIds.length} enabled):`);\n const answers = await context.waitForInput({\n type: 'selection',\n questions: [\n {\n id: 'rules',\n question: 'Select all rules you want to enable:',\n options: ruleOptions,\n multiSelect: true,\n preSelected: enabledIds, // Pre-select currently enabled rules\n },\n ],\n });\n\n // Extract selected rule IDs\n const selectedRuleIds = typeof answers === 'object' && !Array.isArray(answers)\n ? (Array.isArray(answers['rules']) ? answers['rules'] : [])\n : [];\n\n if (!Array.isArray(selectedRuleIds)) {\n return 'Rule selection cancelled.';\n }\n\n // Update enabled rules\n const success = setEnabledRules(selectedRuleIds);\n\n if (!success) {\n return 'Failed to update rules.';\n }\n\n // Build summary message\n const enabledCount = selectedRuleIds.length;\n const disabledCount = allRules.length - enabledCount;\n\n const enabledRules = allRules.filter((r) => selectedRuleIds.includes(r.id));\n const enabledNames = enabledRules.map((r) => ` • ${r.metadata.name}`).join('\\n');\n\n return `Updated rules configuration:\n${enabledCount} enabled, ${disabledCount} disabled\n\nEnabled rules:\n${enabledNames || ' (none)'}`;\n },\n};\n\nexport default rulesCommand;\n",
|
|
17
|
-
"/**\n * Compact Command\n * Summarize current session and start fresh\n */\n\nimport type { Command } from '../types.js';\n\nexport const compactCommand: Command = {\n id: 'compact',\n label: '/compact',\n description: 'Summarize current session and create a new session with the summary',\n execute: async (context) => {\n const currentSession = context.getCurrentSession();\n\n if (!currentSession) {\n return 'No active session to compact.';\n }\n\n if (currentSession.messages.length === 0) {\n return 'Current session has no messages to compact.';\n }\n\n const aiConfig = context.getConfig();\n if (!aiConfig?.defaultProvider || !aiConfig?.defaultModel) {\n return 'No AI provider configured. Use /provider to configure a provider first.';\n }\n\n context.sendMessage('Analyzing conversation and creating detailed summary...');\n\n try {\n // Import necessary modules\n const { getProvider } = await import('../../../providers/index.js');\n const { streamText } = await import('ai');\n const { getSystemPrompt } = await import('../../../core/ai-sdk.js');\n\n // Get provider and model\n const provider = getProvider(currentSession.provider);\n const providerConfig = aiConfig.providers?.[currentSession.provider];\n\n if (!providerConfig || !provider.isConfigured(providerConfig)) {\n return `Provider ${currentSession.provider} is not properly configured.`;\n }\n\n const model = provider.createClient(providerConfig, currentSession.model);\n\n // Build conversation history for summarization\n const conversationHistory = currentSession.messages.map((msg) => {\n // Extract text content from MessagePart array\n const textParts = msg.content\n .filter((part) => part.type === 'text')\n .map((part: any) => part.content);\n let content = textParts.join('\\n');\n\n // Include attachments info\n if (msg.attachments && msg.attachments.length > 0) {\n const attachmentsList = msg.attachments\n .map((att) => `[Attached: ${att.relativePath}]`)\n .join('\\n');\n content += `\\n${attachmentsList}`;\n }\n\n return `${msg.role === 'user' ? 'User' : 'Assistant'}: ${content}`;\n }).join('\\n\\n---\\n\\n');\n\n // Create summarization prompt\n const summaryPrompt = `You are a conversation summarizer. Your task is to create a comprehensive, detailed summary of the following conversation that preserves ALL important information.\n\nCRITICAL REQUIREMENTS:\n1. DO NOT omit any important details, decisions, code snippets, file paths, commands, or configurations\n2. Preserve technical accuracy - include exact function names, variable names, file paths, and command syntax\n3. Maintain chronological flow of the conversation\n4. Highlight key decisions, problems solved, and solutions implemented\n5. Include all context that would be needed to continue this conversation naturally\n6. Use clear markdown formatting with sections and bullet points\n7. If code was discussed or written, include the essential parts or describe what was implemented\n8. **CRITICAL**: If there is ongoing work or tasks in progress, create a section called \"## Current Work\" that describes:\n - What was being worked on when the conversation was compacted\n - What the next steps should be\n - Any pending tasks or unfinished work\n - The current state of the implementation\n\nThe summary will be used to start a fresh conversation while maintaining full context.\n\nCONVERSATION TO SUMMARIZE:\n${conversationHistory}\n\nPlease provide a detailed, structured summary now:`;\n\n // Call AI to generate summary\n const result = await streamText({\n model,\n messages: [\n {\n role: 'user',\n content: summaryPrompt,\n },\n ],\n maxTokens: 4096, // Allow longer summary\n });\n\n // Collect the full summary\n let summary = '';\n for await (const chunk of result.textStream) {\n summary += chunk;\n }\n\n if (!summary || summary.trim().length === 0) {\n return 'Failed to generate summary. Please try again.';\n }\n\n // Create new session with same provider/model\n const newSessionId = context.createSession(\n currentSession.provider,\n currentSession.model\n );\n\n // Switch to new session\n context.setCurrentSession(newSessionId);\n\n const messageCount = currentSession.messages.length;\n const sessionTitle = currentSession.title || 'Untitled session';\n\n // Format summary as a user message and trigger AI response\n const summaryMessage = `This session is being continued from a previous conversation that ran out of context. The conversation is summarized below:\n${summary}`;\n\n // Send summary and automatically trigger AI response\n // This allows the LLM to acknowledge the summary and continue working\n await context.triggerAIResponse(summaryMessage);\n\n return `✓ Compacted session \"${sessionTitle}\" (${messageCount} messages)\\n✓ Created new session with detailed summary\\n✓ Switched to new session\\n✓ AI is processing the summary and will continue working...`;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n context.addLog(`[Compact] Error: ${errorMsg}`);\n return `Failed to compact session: ${errorMsg}`;\n }\n },\n};\n\nexport default compactCommand;\n",
|
|
18
|
-
"/**\n * Notifications Command\n * Manage notification settings\n */\n\nimport type { Command, CommandContext } from '../types.js';\n\nexport default {\n id: 'notifications',\n label: '/notifications',\n description: 'Manage notification settings for AI responses',\n args: [\n {\n name: 'action',\n description: 'Action to perform (show, enable, disable)',\n required: true,\n suggestions: ['show', 'enable', 'disable']\n },\n {\n name: 'type',\n description: 'Notification type to configure (os, terminal, sound, all)',\n required: false,\n suggestions: ['os', 'terminal', 'sound', 'all']\n }\n ],\n \n async execute(args: string[], context: CommandContext): Promise<void> {\n const { updateNotificationSettings, notificationSettings } = context;\n \n if (args.length === 0) {\n context.updateOutput('\\n❌ Please specify an action: show, enable, or disable\\n');\n return;\n }\n\n const action = args[0].toLowerCase();\n \n switch (action) {\n case 'show':\n context.updateOutput('\\n🔔 Notification Settings:\\n');\n context.updateOutput(` OS Notifications: ${notificationSettings.osNotifications ? '✅ Enabled' : '❌ Disabled'}\\n`);\n context.updateOutput(` Terminal Notifications: ${notificationSettings.terminalNotifications ? '✅ Enabled' : '❌ Disabled'}\\n`);\n context.updateOutput(` Sound Effects: ${notificationSettings.sound ? '✅ Enabled' : '❌ Disabled'}\\n`);\n context.updateOutput('\\nUse /notifications enable/disable [type] to change settings.\\n');\n break;\n \n case 'enable':\n case 'disable': {\n const isEnabled = action === 'enable';\n \n if (args.length === 1 || args[1] === 'all') {\n // Enable/disable all notifications\n updateNotificationSettings({\n osNotifications: isEnabled,\n terminalNotifications: isEnabled,\n sound: isEnabled\n });\n context.updateOutput(`\\n${isEnabled ? '✅' : '❌'} All notifications ${isEnabled ? 'enabled' : 'disabled'}\\n`);\n } else {\n const type = args[1].toLowerCase();\n const updates: any = {};\n \n switch (type) {\n case 'os':\n updates.osNotifications = isEnabled;\n break;\n case 'terminal':\n updates.terminalNotifications = isEnabled;\n break;\n case 'sound':\n updates.sound = isEnabled;\n break;\n default:\n context.updateOutput(`\\n❌ Unknown notification type: ${type}\\n`);\n context.updateOutput('Valid types: os, terminal, sound, all\\n');\n return;\n }\n \n updateNotificationSettings(updates);\n context.updateOutput(`\\n${isEnabled ? '✅' : '❌'} ${type} notifications ${isEnabled ? 'enabled' : 'disabled'}\\n`);\n }\n break;\n }\n \n default:\n context.updateOutput(`\\n❌ Unknown action: ${action}\\n`);\n context.updateOutput('Valid actions: show, enable, disable\\n');\n }\n }\n} as Command;",
|
|
19
|
-
"/**\n * Dashboard Command\n * Open the full-screen control panel\n */\n\nimport type { Command } from '../types.js';\n\nexport const dashboardCommand: Command = {\n id: 'dashboard',\n label: '/dashboard',\n description: 'Open control panel - central hub for all features',\n execute: async (context) => {\n context.navigateTo('dashboard');\n return 'Opening control panel...';\n },\n};\n",
|
|
20
|
-
"/**\n * Command Registry\n * All available commands with their definitions and implementations\n */\n\nimport type { Command } from './types.js';\n\n// Import all command definitions\nimport providerCommand from './definitions/provider.command.js';\nimport modelCommand from './definitions/model.command.js';\nimport logsCommand from './definitions/logs.command.js';\nimport helpCommand from './definitions/help.command.js';\nimport surveyCommand from './definitions/survey.command.js';\nimport contextCommand from './definitions/context.command.js';\nimport sessionsCommand from './definitions/sessions.command.js';\nimport newCommand from './definitions/new.command.js';\nimport bashesCommand from './definitions/bashes.command.js';\nimport agentCommand from './definitions/agent.command.js';\nimport rulesCommand from './definitions/rules.command.js';\nimport compactCommand from './definitions/compact.command.js';\nimport notificationsCommand from './definitions/notifications.command.js';\nimport { dashboardCommand } from './definitions/dashboard.command.js';\n\n/**\n * All registered commands\n */\nexport const commands: Command[] = [\n dashboardCommand,\n providerCommand,\n modelCommand,\n agentCommand,\n rulesCommand,\n compactCommand,\n notificationsCommand,\n logsCommand,\n helpCommand,\n surveyCommand,\n contextCommand,\n sessionsCommand,\n newCommand,\n bashesCommand,\n];\n\n/**\n * Get command by ID\n */\nexport function getCommand(id: string): Command | undefined {\n return commands.find(cmd => cmd.id === id);\n}\n\n/**\n * Get command by label (e.g., '/model')\n */\nexport function getCommandByLabel(label: string): Command | undefined {\n return commands.find(cmd => cmd.label === label);\n}\n"
|
|
21
|
-
],
|
|
22
|
-
"mappings": "iDAUA,eAAsB,CAAiB,CACrC,EACA,EACiB,CACjB,IAAQ,gBAAiB,KAAa,gCAC9B,eAAgB,KAAa,+BAC/B,EAAW,EAAQ,UAAU,EAG7B,EADW,EAAY,CAAiB,EACtB,gBAAgB,EAElC,EAAgB,EAAO,IAAI,CAAC,KAAW,CAC3C,MAAO,EAAM,MACb,MAAO,EAAM,GACf,EAAE,EAEF,EAAQ,YACN,aAAa,EAAa,GAAyC,wBACrE,EACA,IAAM,EAAa,MAAM,EAAQ,aAAa,CAC5C,KAAM,YACN,UAAW,CACT,CACE,GAAI,MACJ,SAAU,0CACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EACJ,OAAO,IAAe,UAAY,CAAC,MAAM,QAAQ,CAAU,EACvD,EAAW,IACX,GACN,GAAI,CAAC,EACH,MAAO,2BAIT,IAAM,EAAQ,EAAO,KAAK,CAAC,IAAM,EAAE,MAAQ,CAAG,EAC1C,EAEJ,GAAI,GAAO,OAAS,UAAW,CAC7B,EAAQ,YAAY,oBAAoB,IAAM,EAC9C,IAAM,EAAc,MAAM,EAAQ,aAAa,CAC7C,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,GAAG,EAAM,SACnB,QAAS,CACP,CAAE,MAAO,OAAQ,MAAO,MAAO,EAC/B,CAAE,MAAO,QAAS,MAAO,OAAQ,CACnC,CACF,CACF,CACF,CAAC,EACD,EACE,OAAO,IAAgB,UAAY,CAAC,MAAM,QAAQ,CAAW,EACzD,EAAY,MACZ,GACD,KACL,EAAQ,YAAY,mBAAmB,IAAM,EAC7C,IAAM,EAAe,MAAM,EAAQ,aAAa,CAC9C,KAAM,OACN,OAAQ,GAAG,IACb,CAAC,EACD,EAAQ,OAAO,IAAiB,SAAW,EAAe,GAG5D,GAAI,CAAC,EACH,MAAO,qBAIT,IAAM,EAAY,IACb,EACH,UAAW,IACN,EAAU,WACZ,GAAa,IACT,EAAU,YACX,IAED,GAAM,CACT,CACF,CACF,EAEA,GAAI,CAAC,GAAU,gBACb,EAAU,gBAAkB,EAG9B,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAIlC,IAAM,EADe,EAAO,KAAK,CAAC,IAAM,EAAE,MAAQ,CAAG,GAClB,OAAS,MAAQ,EAEpD,MAAO,OAAO,EAAa,GAAyC,QAAQ,SAAW,ICrGlF,IAAM,GAA2B,CACtC,GAAI,WACJ,MAAO,YACP,YAAa,sBACb,KAAM,CACJ,CACE,KAAM,SACN,YAAa,yBACb,SAAU,GACV,YAAa,MAAO,IAAiB,CACnC,MAAO,CACL,CAAE,GAAI,MAAO,MAAO,MAAO,MAAO,KAAM,EACxC,CAAE,GAAI,MAAO,MAAO,MAAO,MAAO,KAAM,CAC1C,EAEJ,EACA,CACE,KAAM,gBACN,YAAa,wDACb,SAAU,GACV,YAAa,MAAO,IAAiB,CACnC,IAAQ,gBAAiB,KAAa,+BACtC,OAAO,OAAO,OAAO,CAAY,EAAE,IAAI,CAAC,KAAO,CAC7C,GAAI,EAAE,GACN,MAAO,EAAE,KACT,MAAO,EAAE,EACX,EAAE,EAEN,EACA,CACE,KAAM,MACN,YAAa,+BACb,SAAU,GACV,YAAa,MAAO,IAAiB,CAGnC,IAAM,EAAa,EAAa,GAEhC,GAAI,CAAC,EACH,MAAO,CAAC,EAGV,GAAI,CACF,IAAQ,eAAgB,KAAa,+BAWrC,OAViB,EAAY,CAAiB,EACtB,gBAAgB,EAGpB,IAAI,MAAU,CAChC,GAAI,EAAM,IACV,MAAO,EAAM,MACb,MAAO,EAAM,GACf,EAAE,EAGF,MAAO,EAAO,CAEd,MAAO,CAAC,GAGd,EACA,CACE,KAAM,QACN,YAAa,iCACb,SAAU,GACV,YAAa,MAAO,IAAiB,CAEnC,IAAM,EAAa,EAAa,GAC1B,EAAM,EAAa,GAEzB,GAAI,CAAC,GAAc,CAAC,EAClB,MAAO,CAAC,EAGV,GAAI,CACF,IAAQ,eAAgB,KAAa,+BAQrC,GAPiB,EAAY,CAAiB,EACtB,gBAAgB,EAGnB,KAAK,KAAK,EAAE,MAAQ,CAAG,GAGjC,OAAS,UAClB,MAAO,CACL,CAAE,GAAI,OAAQ,MAAO,OAAQ,MAAO,MAAO,EAC3C,CAAE,GAAI,QAAS,MAAO,QAAS,MAAO,OAAQ,CAChD,EAGF,MAAO,CAAC,EACR,MAAO,EAAO,CACd,MAAO,CAAC,GAGd,CACF,EACA,QAAS,MAAO,IAAY,CAC1B,IAAQ,gBAAiB,KAAa,+BAChC,EAAW,EAAQ,UAAU,EAGnC,GAAI,EAAQ,KAAK,SAAW,EAAG,CAC7B,EAAQ,YAAY,yBAAyB,EAC7C,IAAM,EAAgB,MAAM,EAAQ,aAAa,CAC/C,KAAM,YACN,UAAW,CACT,CACE,GAAI,SACJ,SAAU,iBACV,QAAS,CACP,CAAE,MAAO,iBAAkB,MAAO,KAAM,EACxC,CAAE,MAAO,uBAAwB,MAAO,KAAM,CAChD,CACF,CACF,CACF,CAAC,EAEK,EAAS,OAAO,IAAkB,UAAY,CAAC,MAAM,QAAQ,CAAa,EAAI,EAAc,OAAY,GAC9G,GAAI,CAAC,EACH,MAAO,oBAIT,IAAQ,eAAgB,KAAa,+BAC/B,EAAkB,OAAO,OAAO,CAAY,EAAE,IAAI,CAAC,IAAM,CAC7D,IAAI,EAAe,GACnB,GAAI,CACF,IAAM,EAAW,EAAY,EAAE,EAAS,EAClC,EAAiB,GAAU,YAAY,EAAE,IAC/C,EAAe,EAAiB,EAAS,aAAa,CAAc,EAAI,GACxE,KAAM,EAGR,MAAO,CACL,MAAO,GAAG,EAAE,QAAQ,EAAe,IAAK,KACxC,MAAO,EAAE,EACX,EACD,EAED,EAAQ,YAAY,IAAW,MAAQ,qCAAuC,0CAA0C,EACxH,IAAM,EAAkB,MAAM,EAAQ,aAAa,CACjD,KAAM,YACN,UAAW,CACT,CACE,GAAI,WACJ,SAAU,IAAW,MAAQ,0BAA4B,gCACzD,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAa,OAAO,IAAoB,UAAY,CAAC,AAAM,QAAQ,CAAe,EAAI,EAAgB,SAAc,GAC1H,GAAI,CAAC,EACH,MAAO,gCAGT,GAAI,IAAW,MAAO,CAEpB,IAAQ,eAAgB,KAAa,qCAC/B,EAAW,EAAY,CAAiB,EACxC,EAAiB,GAAU,YAAY,GAE7C,GAAI,CAAC,GAAkB,CAAC,EAAS,aAAa,CAAc,EAAG,CAE7D,EAAQ,YAAY,GAAG,EAAa,GAAyC,6BAA6B,EAC1G,IAAM,EAAmB,MAAM,EAAQ,aAAa,CAClD,KAAM,YACN,UAAW,CACT,CACE,GAAI,YACJ,SAAU,mCACV,QAAS,CACP,CAAE,MAAO,qBAAsB,MAAO,KAAM,EAC5C,CAAE,MAAO,aAAc,MAAO,IAAK,CACrC,CACF,CACF,CACF,CAAC,EAMD,GAAI,EAJoB,OAAO,IAAqB,UAAY,CAAC,MAAM,QAAQ,CAAgB,EAC3F,EAAiB,YAAiB,MAClC,IAGF,MAAO,0DAIT,IAAM,EAAe,MAAM,EAAkB,EAAS,CAAU,EAG1D,EAAgB,EAAQ,UAAU,EAClC,EAAwB,GAAe,YAAY,GAGzD,GAAI,CAAC,GAAyB,CAAC,EAAS,aAAa,CAAqB,EACxE,MAAO,GAAG;AAAA;AAAA,yFAA0G,IAItH,EAAQ,YAAY,CAAY,EAChC,IAAM,EAAsB,EAGtB,EAAY,IACb,EACH,gBAAiB,CACnB,GAGQ,mBAAoB,KAAa,+BACnC,EAAe,MAAM,EAAgB,EAAmB,CAAmB,EACjF,GAAI,CAAC,EACH,MAAO,2DAA2D,EAAa,GAAyC,OAI1H,EAAU,UAAY,IACjB,EAAU,WACZ,GAAa,IACT,EACH,gBAAiB,CACnB,CACF,EAEA,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,EAAQ,sBAAsB,CAAwB,EACtD,EAAQ,mBAAmB,CAAY,EAGvC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,sBAAsB,EAAkB,EAAY,CAAY,EAGxE,OAAQ,cAAc,EAAY,CAAY,EAGhD,MAAO,aAAa,EAAa,GAAyC,oBAAoB,IAGhG,IAAM,EAAY,IACb,EACH,gBAAiB,CACnB,GAGQ,mBAAoB,KAAa,+BACnC,EAAe,MAAM,EAAgB,EAAmB,CAAc,EAC5E,GAAI,CAAC,EACH,MAAO,mCAAmC,EAAa,GAAyC,OAIlG,EAAU,UAAY,IACjB,EAAU,WACZ,GAAa,IACT,EACH,gBAAiB,CACnB,CACF,EAEA,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,sBAAsB,EAAkB,EAAY,CAAY,EAGxE,OAAQ,cAAc,EAAY,CAAY,EAGhD,MAAO,eAAe,EAAa,GAAyC,OAG5E,YAAO,MAAM,EAAkB,EAAS,CAAU,EAKtD,GAAI,EAAQ,KAAK,SAAW,GAAK,EAAQ,KAAK,KAAO,MAAO,CAC1D,IAAQ,eAAgB,KAAa,+BAC/B,EAAkB,OAAO,OAAO,CAAY,EAAE,IAAI,CAAC,IAAM,CAC7D,IAAI,EAAe,GACnB,GAAI,CACF,IAAM,EAAW,EAAY,EAAE,EAAS,EAClC,EAAiB,GAAU,YAAY,EAAE,IAC/C,EAAe,EAAiB,EAAS,aAAa,CAAc,EAAI,GACxE,KAAM,EAGR,MAAO,CACL,MAAO,GAAG,EAAE,QAAQ,EAAe,IAAK,KACxC,MAAO,EAAE,EACX,EACD,EAED,EAAQ,YAAY,oCAAoC,EACxD,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,WACJ,SAAU,mBACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAa,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAAI,EAAQ,SAAc,GAClG,GAAI,CAAC,EACH,MAAO,gCAGT,IAAM,EAAW,EAAY,CAAiB,EACxC,EAAiB,GAAU,YAAY,GAE7C,GAAI,CAAC,GAAkB,CAAC,EAAS,aAAa,CAAc,EAAG,CAE7D,EAAQ,YAAY,GAAG,EAAa,GAAyC,6BAA6B,EAC1G,IAAM,EAAmB,MAAM,EAAQ,aAAa,CAClD,KAAM,YACN,UAAW,CACT,CACE,GAAI,YACJ,SAAU,mCACV,QAAS,CACP,CAAE,MAAO,qBAAsB,MAAO,KAAM,EAC5C,CAAE,MAAO,aAAc,MAAO,IAAK,CACrC,CACF,CACF,CACF,CAAC,EAMD,GAAI,EAJoB,OAAO,IAAqB,UAAY,CAAC,MAAM,QAAQ,CAAgB,EAC3F,EAAiB,YAAiB,MAClC,IAGF,MAAO,0DAIT,IAAM,EAAe,MAAM,EAAkB,EAAS,CAAU,EAG1D,EAAgB,EAAQ,UAAU,EAClC,EAAwB,GAAe,YAAY,GACzD,GAAI,CAAC,GAAyB,CAAC,EAAS,aAAa,CAAqB,EACxE,MAAO,GAAG;AAAA;AAAA,yFAA0G,IAItH,EAAQ,YAAY,CAAY,EAChC,IAAM,EAAsB,EAGtB,EAAY,IACb,EACH,gBAAiB,CACnB,GAGQ,mBAAoB,KAAa,+BACnC,EAAe,MAAM,EAAgB,EAAmB,CAAmB,EACjF,GAAI,CAAC,EACH,MAAO,2DAA2D,EAAa,GAAyC,OAI1H,EAAU,UAAY,IACjB,EAAU,WACZ,GAAa,IACT,EACH,gBAAiB,CACnB,CACF,EAEA,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,EAAQ,sBAAsB,CAAwB,EACtD,EAAQ,mBAAmB,CAAY,EAGvC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,sBAAsB,EAAkB,EAAY,CAAY,EAGxE,OAAQ,cAAc,EAAY,CAAY,EAGhD,MAAO,aAAa,EAAa,GAAyC,oBAAoB,IAGhG,IAAM,EAAY,IACb,EACH,gBAAiB,CACnB,GAGQ,mBAAoB,KAAa,+BACnC,EAAe,MAAM,EAAgB,EAAmB,CAAc,EAC5E,GAAI,CAAC,EACH,MAAO,mCAAmC,EAAa,GAAyC,OAIlG,EAAU,UAAY,IACjB,EAAU,WACZ,GAAa,IACT,EACH,gBAAiB,CACnB,CACF,EAEA,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,sBAAsB,EAAkB,EAAY,CAAY,EAGxE,OAAQ,cAAc,EAAY,CAAY,EAGhD,MAAO,eAAe,EAAa,GAAyC,OAI9E,GAAI,EAAQ,KAAK,SAAW,GAAK,EAAQ,KAAK,KAAO,MAAO,CAC1D,IAAM,EAAa,EAAQ,KAAK,GAEhC,GAAI,EAAE,KAAc,GAClB,MAAO,qBAAqB,iBAA0B,OAAO,KAAK,CAAY,EAAE,KAAK,IAAI,IAG3F,IAAQ,eAAgB,KAAa,+BAC/B,EAAW,EAAY,CAAiB,EACxC,EAAiB,GAAU,YAAY,GAE7C,GAAI,CAAC,GAAkB,CAAC,EAAS,aAAa,CAAc,EAC1D,MAAO,GAAG,EAAa,GAAyC,8CAA8C,IAGhH,IAAM,EAAY,IACb,EACH,gBAAiB,CACnB,GAGQ,mBAAoB,KAAa,+BACnC,EAAe,MAAM,EAAgB,EAAmB,CAAc,EAC5E,GAAI,CAAC,EACH,MAAO,mCAAmC,EAAa,GAAyC,OAIlG,EAAU,UAAY,IACjB,EAAU,WACZ,GAAa,IACT,EACH,gBAAiB,CACnB,CACF,EAEA,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,sBAAsB,EAAkB,EAAY,CAAY,EAGxE,OAAQ,cAAc,EAAY,CAAY,EAGhD,MAAO,eAAe,EAAa,GAAyC,OAI9E,GAAI,EAAQ,KAAK,SAAW,GAAK,EAAQ,KAAK,KAAO,MAAO,CAC1D,IAAM,EAAkB,OAAO,OAAO,CAAY,EAAE,IAAI,CAAC,KAAO,CAC9D,MAAO,EAAE,KACT,MAAO,EAAE,EACX,EAAE,EAEF,EAAQ,YAAY,0CAA0C,EAC9D,IAAM,EAAkB,MAAM,EAAQ,aAAa,CACjD,KAAM,YACN,UAAW,CACT,CACE,GAAI,WACJ,SAAU,mBACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAa,OAAO,IAAoB,UAAY,CAAC,MAAM,QAAQ,CAAe,EAAI,EAAgB,SAAc,GAC1H,GAAI,CAAC,EACH,MAAO,gCAIT,IAAQ,eAAgB,KAAa,+BAE/B,EADW,EAAY,CAAiB,EACtB,gBAAgB,EAElC,EAAgB,EAAO,IAAI,MAAU,CACzC,MAAO,EAAM,MACb,MAAO,EAAM,GACf,EAAE,EAGF,EAAQ,YAAY,aAAa,EAAa,GAAyC,wBAAwB,EAC/G,IAAM,EAAa,MAAM,EAAQ,aAAa,CAC5C,KAAM,YACN,UAAW,CACT,CACE,GAAI,MACJ,SAAU,0CACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAM,OAAO,IAAe,UAAY,CAAC,MAAM,QAAQ,CAAU,EAAI,EAAW,IAAS,GAC/F,GAAI,CAAC,EACH,MAAO,2BAIT,CACE,IAAM,EAAQ,EAAO,KAAK,KAAK,EAAE,MAAQ,CAAG,EACxC,EAEJ,GAAI,GAAO,OAAS,UAAW,CAC7B,EAAQ,YAAY,oBAAoB,IAAM,EAC9C,IAAM,EAAc,MAAM,EAAQ,aAAa,CAC7C,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,GAAG,EAAM,SACnB,QAAS,CACP,CAAE,MAAO,OAAQ,MAAO,MAAO,EAC/B,CAAE,MAAO,QAAS,MAAO,OAAQ,CACnC,CACF,CACF,CACF,CAAC,EACD,EAAQ,OAAO,IAAgB,UAAY,CAAC,MAAM,QAAQ,CAAW,EAAI,EAAY,MAAW,GAC3F,KACL,EAAQ,YAAY,mBAAmB,IAAM,EAC7C,IAAM,EAAe,MAAM,EAAQ,aAAa,CAC9C,KAAM,OACN,YAAa,SAAS,MACxB,CAAC,EACD,EAAQ,OAAO,IAAiB,SAAW,EAAe,GAG5D,GAAI,CAAC,EACH,MAAO,qBAIT,IAAM,EAAY,IACb,EACH,UAAW,IACN,EAAU,WACZ,GAAa,IACT,EAAU,YAAY,IACxB,GAAM,CACT,CACF,CACF,EAEA,GAAI,CAAC,GAAU,gBACb,EAAU,gBAAkB,EAG9B,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAIlC,IAAM,EADe,EAAO,KAAK,KAAK,EAAE,MAAQ,CAAG,GAChB,OAAS,MAAQ,EAEpD,MAAO,OAAO,EAAa,GAAyC,QAAQ,SAAW,GACzF,EAIF,GAAI,EAAQ,KAAK,SAAW,GAAK,EAAQ,KAAK,KAAO,MAAO,CAC1D,IAAM,EAAa,EAAQ,KAAK,GAEhC,GAAI,EAAE,KAAc,GAClB,MAAO,qBAAqB,iBAA0B,OAAO,KAAK,CAAY,EAAE,KAAK,IAAI,IAI3F,IAAQ,eAAgB,KAAa,+BAE/B,EADW,EAAY,CAAiB,EACtB,gBAAgB,EAElC,EAAgB,EAAO,IAAI,MAAU,CACzC,MAAO,EAAM,MACb,MAAO,EAAM,GACf,EAAE,EAGF,EAAQ,YAAY,aAAa,EAAa,GAAyC,wBAAwB,EAC/G,IAAM,EAAa,MAAM,EAAQ,aAAa,CAC5C,KAAM,YACN,UAAW,CACT,CACE,GAAI,MACJ,SAAU,0CACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAM,OAAO,IAAe,UAAY,CAAC,MAAM,QAAQ,CAAU,EAAI,EAAW,IAAS,GAC/F,GAAI,CAAC,EACH,MAAO,2BAIT,CACE,IAAM,EAAQ,EAAO,KAAK,KAAK,EAAE,MAAQ,CAAG,EACxC,EAEJ,GAAI,GAAO,OAAS,UAAW,CAC7B,EAAQ,YAAY,oBAAoB,IAAM,EAC9C,IAAM,EAAc,MAAM,EAAQ,aAAa,CAC7C,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,GAAG,EAAM,SACnB,QAAS,CACP,CAAE,MAAO,OAAQ,MAAO,MAAO,EAC/B,CAAE,MAAO,QAAS,MAAO,OAAQ,CACnC,CACF,CACF,CACF,CAAC,EACD,EAAQ,OAAO,IAAgB,UAAY,CAAC,MAAM,QAAQ,CAAW,EAAI,EAAY,MAAW,GAC3F,KACL,EAAQ,YAAY,mBAAmB,IAAM,EAC7C,IAAM,EAAe,MAAM,EAAQ,aAAa,CAC9C,KAAM,OACN,YAAa,SAAS,MACxB,CAAC,EACD,EAAQ,OAAO,IAAiB,SAAW,EAAe,GAG5D,GAAI,CAAC,EACH,MAAO,qBAIT,IAAM,EAAY,IACb,EACH,UAAW,IACN,EAAU,WACZ,GAAa,IACT,EAAU,YAAY,IACxB,GAAM,CACT,CACF,CACF,EAEA,GAAI,CAAC,GAAU,gBACb,EAAU,gBAAkB,EAG9B,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAIlC,IAAM,EADe,EAAO,KAAK,KAAK,EAAE,MAAQ,CAAG,GAChB,OAAS,MAAQ,EAEpD,MAAO,OAAO,EAAa,GAAyC,QAAQ,SAAW,GACzF,EAIF,GAAI,EAAQ,KAAK,QAAU,GAAK,EAAQ,KAAK,KAAO,MAAO,CACzD,IAAM,EAAa,EAAQ,KAAK,GAC1B,EAAM,EAAQ,KAAK,GACnB,EAAQ,EAAQ,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,EAE5C,GAAI,EAAE,KAAc,GAClB,MAAO,qBAAqB,iBAA0B,OAAO,KAAK,CAAY,EAAE,KAAK,IAAI,IAI3F,IAAQ,eAAgB,KAAa,+BAE/B,EADW,EAAY,CAAiB,EACtB,gBAAgB,EAElC,EAAY,EAAO,IAAI,KAAK,EAAE,GAAG,EACvC,GAAI,CAAC,EAAU,SAAS,CAAG,EACzB,MAAO,gBAAgB,qBAAuB,MAAe,EAAU,KAAK,IAAI,IAGlF,IAAM,EAAY,IACb,EACH,UAAW,IACN,EAAU,WACZ,GAAa,IACT,EAAU,YAAY,IACxB,GAAM,CACT,CACF,CACF,EAEA,GAAI,CAAC,GAAU,gBACb,EAAU,gBAAkB,EAG9B,EAAQ,YAAY,CAAS,EAC7B,MAAM,EAAQ,WAAW,CAAS,EAIlC,IAAM,EADQ,EAAO,KAAK,KAAK,EAAE,MAAQ,CAAG,GAChB,OAAS,MAAQ,EAE7C,MAAO,OAAO,EAAa,GAAyC,QAAQ,SAAW,IAGzF,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qEAEX,EAEe,KC/uBR,IAAM,GAAwB,CACnC,GAAI,QACJ,MAAO,SACP,YAAa,kBACb,KAAM,CACJ,CACE,KAAM,aACN,YAAa,qBACb,SAAU,GACV,YAAa,MAAO,EAAc,IAAY,CAC5C,GAAI,CAEF,IAAM,EAAW,GAAS,UAAU,EACpC,GAAI,CAAC,GAAU,UACb,MAAO,CAAC,EAKV,IAAM,EADiB,GAAS,kBAAkB,GACR,UAAY,EAAS,gBAE/D,GAAI,CAAC,EACH,MAAO,CAAC,EAIV,IAAM,EAAS,EAAS,UAAU,GAClC,GAAI,CAAC,EACH,MAAO,CAAC,EAGV,GAAI,CACF,IAAQ,eAAgB,KAAa,+BAErC,OADe,MAAM,EAAY,EAA0B,CAAM,GACnD,IAAI,MAAM,CACtB,GAAI,EAAE,GACN,MAAO,EAAE,KACT,MAAO,EAAE,EACX,EAAE,EACF,MAAO,EAAO,CACd,GAAI,EACF,EAAQ,OAAO,8BAA8B,MAAsB,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GAAG,EAE7H,MAAO,CAAC,GAEV,MAAO,EAAO,CACd,GAAI,EACF,EAAQ,OAAO,yBAAyB,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GAAG,EAElG,MAAO,CAAC,GAGd,CACF,EACA,QAAS,MAAO,IAAY,CAC1B,IAAI,EAGJ,GAAI,EAAQ,KAAK,SAAW,EAC1B,GAAI,CAEF,IAAM,EAAW,EAAQ,UAAU,EACnC,GAAI,CAAC,GAAU,UACb,MAAO,8DAKT,IAAM,EADiB,EAAQ,kBAAkB,GACP,UAAY,EAAS,gBAE/D,GAAI,CAAC,EACH,MAAO,kEAGT,IAAM,EAAS,EAAS,UAAU,GAClC,GAAI,CAAC,EACH,MAAO,YAAY,uBAIrB,IAAI,EAAqD,CAAC,EAC1D,GAAI,CACF,IAAQ,eAAgB,KAAa,+BAC/B,EAAS,MAAM,EAAY,EAA0B,CAAM,EACjE,EAAY,EAAO,IAAI,MAAM,CAAE,MAAO,EAAE,KAAM,MAAO,EAAE,EAAG,EAAE,EAC5D,EAAQ,OAAO,UAAU,EAAO,sBAAsB,GAAmB,EACzE,MAAO,EAAO,CACd,IAAM,EAAW,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAEtE,OADA,EAAQ,OAAO,8BAA8B,MAAsB,GAAU,EACtE,8BAA8B,MAAsB,IAG7D,GAAI,EAAU,SAAW,EACvB,MAAO,2BAA2B,IAIpC,EAAQ,YAAY,iCAAiC,EACrD,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,kCACV,QAAS,CACX,CACF,CACF,CAAC,EAGD,EAAU,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAAI,EAAQ,MAAW,GACtF,MAAO,EAAO,CACd,MAAO,0BAA0B,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,IAGxF,OAAU,EAAQ,KAAK,GAGzB,IAAM,EAAiB,EAAQ,kBAAkB,EAC3C,EAAW,EAAQ,UAAU,EAC7B,EAAW,GAAgB,UAAY,GAAU,gBAEvD,GAAI,CAAC,EACH,MAAO,6DAIT,IAAM,EAAY,IACb,EACH,aAAc,EACd,UAAW,IACN,EAAU,WACZ,GAAW,IACP,EAAU,YAAY,GACzB,gBAAiB,CACnB,CACF,CACF,EACA,EAAQ,YAAY,CAAS,EAG7B,MAAM,EAAQ,WAAW,CAAS,EAGlC,IAAM,EAAmB,EAAQ,oBAAoB,EACrD,GAAI,EACF,EAAQ,mBAAmB,EAAkB,CAAO,EAGpD,OAAQ,cAAc,EAAU,CAAO,EAGzC,MAAO,sBAAsB,IAEjC,EAEe,KC5JR,IAAM,GAAuB,CAClC,GAAI,OACJ,MAAO,QACP,YAAa,kBACb,QAAS,MAAO,IAAY,CAE1B,OADA,EAAQ,WAAW,MAAM,EAClB,wBAEX,EAEe,KCVR,IAAM,GAAuB,CAClC,GAAI,OACJ,MAAO,QACP,YAAa,0BACb,QAAS,MAAO,IAAY,CAC1B,IAAQ,YAAa,KAAa,+BASlC,MAAO;AAAA,EARa,EACjB,IAAI,CAAC,IAAQ,CACZ,IAAM,EAAW,EAAI,KACjB,IAAI,EAAI,KAAK,IAAI,CAAC,IAAM,IAAI,EAAE,OAAO,EAAE,KAAK,GAAG,IAC/C,GACJ,MAAO,GAAG,EAAI,QAAQ,OAAc,EAAI,cACzC,EACA,KAAK;AAAA,CAAI,IAGhB,EAEe,KClBR,IAAM,GAAyB,CACpC,GAAI,SACJ,MAAO,UACP,YAAa,uCACb,QAAS,MAAO,IAAY,CAC1B,EAAQ,YAAY,mCAAmC,EAEvD,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,WACJ,SAAU,8CACV,QAAS,CACP,CAAE,MAAO,YAAa,EACtB,CAAE,MAAO,YAAa,EACtB,CAAE,MAAO,QAAS,EAClB,CAAE,MAAO,MAAO,EAChB,CAAE,MAAO,IAAK,CAChB,CACF,EACA,CACE,GAAI,YACJ,SAAU,iCACV,QAAS,CACP,CAAE,MAAO,OAAQ,EACjB,CAAE,MAAO,KAAM,EACf,CAAE,MAAO,SAAU,EACnB,CAAE,MAAO,QAAS,EAClB,CAAE,MAAO,OAAQ,CACnB,CACF,EACA,CACE,GAAI,SACJ,SAAU,qCACV,QAAS,CACP,CAAE,MAAO,oBAAqB,EAC9B,CAAE,MAAO,YAAa,EACtB,CAAE,MAAO,OAAQ,EACjB,CAAE,MAAO,cAAe,EACxB,CAAE,MAAO,MAAO,CAClB,CACF,CACF,CACF,CAAC,EAED,GAAI,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAIvD,MAAO,mCAHS,OAAO,QAAQ,CAAO,EACnC,IAAI,EAAE,EAAK,KAAW,GAAG,MAAQ,GAAO,EACxC,KAAK,IAAI,IAId,MAAO,oBAEX,EAEe,KCzDR,IAAM,GAA0B,CACrC,GAAI,UACJ,MAAO,WACP,YAAa,mDACb,QAAS,MAAO,IAAY,CAC1B,IAAQ,cAAa,oBAAqB,KAAa,gCAC/C,mBAAoB,KAAa,gCACjC,iBAAkB,KAAa,+BAEjC,EAAiB,EAAQ,kBAAkB,EACjD,GAAI,CAAC,EACH,MAAO,gEAGT,IAAM,EAAY,EAAe,MAwB3B,GArBkB,CAAC,IAA0B,CAEjD,GAAI,EAAM,SAAS,OAAO,EAAG,CAC3B,GAAI,EAAM,SAAS,KAAK,GAAK,EAAM,SAAS,OAAO,EAAG,MAAO,QAC7D,GAAI,EAAM,SAAS,QAAQ,EAAG,MAAO,QACrC,MAAO,MAET,GAAI,EAAM,SAAS,SAAS,EAAG,CAC7B,GAAI,EAAM,SAAS,KAAK,EAAG,MAAO,OAClC,MAAO,MAGT,GAAI,EAAM,SAAS,UAAU,EAAG,CAC9B,GAAI,EAAM,SAAS,MAAM,EAAG,MAAO,QACnC,GAAI,EAAM,SAAS,QAAQ,EAAG,MAAO,QACrC,GAAI,EAAM,SAAS,OAAO,EAAG,MAAO,QAGtC,MAAO,UAG4B,CAAS,EAG9C,EAAQ,OAAO,0CAA0C,aAAqB,EAAiB,CAAY,OAAO,EAGlH,IAAM,EAAe,EAAgB,EAC/B,EAAqB,MAAM,EAAY,EAAc,CAAS,GAG5D,0BAA2B,KAAa,gCACxC,0BAA2B,KAAa,+BAC1C,EAAqB,+CAEvB,EAAgD,CAAC,EACrD,GAAI,CACF,EAAsB,eAAiB,MAAM,EAAY,EAAoB,CAAS,EAEtF,IAAM,EAAe,EAAuB,EAC5C,GAAI,EACF,EAAsB,MAAW,MAAM,EAAY,EAAc,CAAS,EAG5E,IAAM,EAAc,EAAuB,EAC3C,EAAsB,gBAAkB,MAAM,EAAY,EAAa,CAAS,EAChF,MAAO,EAAO,CACd,EAAQ,OAAO,0DAA0D,GAAO,EAIlF,IAAM,EAAQ,EAAc,EACtB,EAAqC,CAAC,EACxC,EAAmB,EAEvB,QAAY,EAAU,KAAY,OAAO,QAAQ,CAAK,EAAG,CAGvD,IAAM,EAAqB,CACzB,KAAM,EACN,YAAa,EAAQ,aAAe,GACpC,WAAY,EAAQ,YAAc,CAAC,CACrC,EACM,EAAW,KAAK,UAAU,EAAoB,KAAM,CAAC,EACrD,EAAS,MAAM,EAAY,EAAU,CAAS,EACpD,EAAW,GAAY,EACvB,GAAoB,EAItB,IAAI,EAAiB,EACrB,QAAW,KAAO,EAAe,SAAU,CACzC,IAAI,EAAU,EAAI,QAGlB,GAAI,EAAI,aAAe,EAAI,YAAY,OAAS,EAC9C,GAAI,CACF,IAAQ,YAAa,KAAa,4BAY5B,GAXe,MAAM,QAAQ,IACjC,EAAI,YAAY,IAAI,MAAO,IAAQ,CACjC,GAAI,CACF,IAAM,EAAU,MAAM,EAAS,EAAI,KAAM,MAAM,EAC/C,MAAO,CAAE,KAAM,EAAI,aAAc,SAAQ,EACzC,KAAM,CACN,MAAO,CAAE,KAAM,EAAI,aAAc,QAAS,sBAAuB,GAEpE,CACH,GAGG,IAAI,CAAC,IAAM;AAAA;AAAA,cAAmB,EAAE;AAAA,EAAW,EAAE;AAAA,QAAkB,EAC/D,KAAK,EAAE,EAEV,GAAW,EACX,MAAO,EAAO,CAEd,QAAQ,KAAK,wDAAyD,CAAK,EAI/E,IAAM,EAAY,MAAM,EAAY,EAAS,CAAS,EACtD,GAAkB,EAIpB,IAAM,EAAa,EAAqB,EAAmB,EACrD,EAAa,EAAe,EAC5B,EAAoB,KAAK,MAAM,EAAe,KAAK,EACnD,EAAiB,EAAa,EAE9B,GAAgB,EAAa,EAAgB,KAAK,QAAQ,CAAC,EAC3D,GAAwB,EAAqB,EAAgB,KAAK,QAAQ,CAAC,EAC3E,GAAiB,EAAmB,EAAgB,KAAK,QAAQ,CAAC,EAClE,GAAoB,EAAiB,EAAgB,KAAK,QAAQ,CAAC,EACnE,GAAgB,EAAiB,EAAgB,KAAK,QAAQ,CAAC,EAC/D,IAAkB,EAAoB,EAAgB,KAAK,QAAQ,CAAC,EAGpE,GAAiB,IAAgB,CAErC,IAAM,EAAqB,KAAK,MAAO,EAAqB,EADxC,EACmE,EACjF,EAAc,KAAK,MAAO,EAAmB,EAF/B,EAE0D,EACxE,EAAiB,KAAK,MAAO,EAAiB,EAHhC,EAG2D,EAEzE,EALc,IAID,EAAqB,EAAc,GAIhD,EAAQ,IAAG,OAAO,CAAkB,EAAI,IAAI,OAR9B,GAQmD,CAAkB,EAGnF,EAAQ,IAAG,OAAO,CAAkB,EAAI,IAAI,OAAO,CAAW,EAAI,IAAI,OAXxD,GAW6E,EAAqB,CAAW,EAG3H,GAAQ,IAAG,OAAO,EAAqB,CAAW,EAAI,IAAI,OAAO,CAAc,EAAI,IAAI,OAAO,CAAU,EAE9G,MAAO,CAAC,EAAO,EAAO,EAAK,IAGtB,GAAM,GAAM,IAAQ,GAAe,EAGpC,GAAW,OAAO,QAAQ,CAAU,EACvC,KAAK,CAAC,EAAG,IAAM,EAAE,GAAK,EAAE,EAAE,EAC1B,IAAI,EAAE,EAAM,KAAY,OAAO,MAAS,EAAiB,CAAM,UAAU,EACzE,KAAK;AAAA,CAAI,EAGN,GAA4B,OAAO,QAAQ,CAAqB,EACnE,IAAI,EAAE,EAAM,KAAY,OAAO,MAAS,EAAiB,CAAM,UAAU,EACzE,KAAK;AAAA,CAAI,EAuBZ,MApBe;AAAA,iBACF,EAAiB,CAAU,KAAK,EAAiB,CAAY,aAAa;AAAA,SAClF;AAAA;AAAA;AAAA,IAGL,sBAAwB,EAAiB,CAAkB,MAAM;AAAA,IACjE,sBAAwB,EAAiB,CAAgB,MAAM;AAAA,IAC/D,sBAAwB,EAAiB,CAAc,MAAM;AAAA;AAAA;AAAA,YAGtD,EAAiB,CAAc,aAAa;AAAA,cAC1C,EAAiB,CAAiB,aAAa;AAAA;AAAA;AAAA,EAG1D;AAAA;AAAA,gBAEc,OAAO,KAAK,CAAK,EAAE;AAAA,EACjC;AAAA,EACA,KAAK,EAIP,EAEe,KCjMR,IAAM,GAA2B,CACtC,GAAI,WACJ,MAAO,YACP,YAAa,wCACb,QAAS,MAAO,IAAY,CAC1B,IAAQ,wBAAyB,KAAa,+BACxC,EAAW,EAAQ,YAAY,EAErC,GAAI,EAAS,SAAW,EACtB,MAAO,6DAGT,IAAM,EAAmB,EAAQ,oBAAoB,EAG/C,EAAiB,CAAC,GAAG,CAAQ,EAAE,KAAK,CAAC,EAAG,IAAM,CAElD,IAAM,EAAa,EAAE,QAAU,EAAE,QACjC,GAAI,IAAe,EAAG,OAAO,EAG7B,OAAO,EAAE,QAAU,EAAE,QACtB,EAGK,EAAiB,EAAe,IAAI,CAAC,IAAY,CACrD,IAAM,EAAY,EAAQ,KAAO,EAC3B,EAAc,EAAqB,EAAQ,MAAO,EAAQ,OAAO,EAGvE,MAAO,CACL,MAHY,EAAY,GAAG,cAA0B,EAIrD,MAAO,EAAQ,EACjB,EACD,EAED,EAAQ,YAAY,gCAAgC,EACpD,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,UACJ,SAAU,0CACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAoB,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAAI,EAAQ,QAAa,GAExG,GAAI,CAAC,EACH,MAAO,+BAIT,EAAQ,kBAAkB,CAAiB,EAE3C,IAAM,EAAkB,EAAe,KAAK,CAAC,IAAM,EAAE,KAAO,CAAiB,EAK7E,MAAO,wBAJa,EAChB,EAAqB,EAAgB,MAAO,EAAgB,OAAO,EACnE,oBAIR,EAEe,KClER,IAAM,GAAsB,CACjC,GAAI,MACJ,MAAO,OACP,YAAa,4BACb,QAAS,MAAO,IAAY,CAC1B,IAAM,EAAW,EAAQ,UAAU,EAEnC,GAAI,CAAC,GAAU,iBAAmB,CAAC,GAAU,aAC3C,MAAO,0EAIT,IAAM,EAAe,EAAQ,cAAc,EAAS,gBAAiB,EAAS,YAAY,EAG1F,OAFA,EAAQ,kBAAkB,CAAY,EAE/B,iCAAiC,EAAS,oBAAoB,EAAS,gBAElF,EAEe,KCnBR,IAAM,GAAyB,CACpC,GAAI,SACJ,MAAO,UACP,YAAa,mCACb,QAAS,MAAO,IAAY,CAC1B,IAAQ,eAAgB,KAAa,+BAC/B,EAAY,EAAY,KAAK,EAEnC,GAAI,EAAU,SAAW,EACvB,MAAO,sCAIT,IAAM,EAAiB,EAAU,IAAI,CAAC,IAAS,CAC7C,IAAM,EAAS,EAAK,UAAY,cAAgB,gBAC1C,EAAW,KAAK,MAAM,EAAK,SAAW,IAAI,EAC1C,EAAc,EAAW,GAC3B,GAAG,KAAK,MAAM,EAAW,EAAE,MAAM,EAAW,MAC5C,GAAG,KAEP,MAAO,CACL,MAAO,GAAG,MAAW,MAAgB,EAAK,UAC1C,MAAO,EAAK,EACd,EACD,EAED,EAAQ,YAAY,SAAS,EAAU,iCAAiC,EAAU,SAAW,EAAI,KAAO,KAAK,EAC7G,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,SACJ,SAAU,0BACV,QAAS,CACP,CAAE,MAAO,eAAgB,MAAO,MAAO,EACvC,CAAE,MAAO,iBAAkB,MAAO,MAAO,EACzC,CAAE,MAAO,SAAU,MAAO,QAAS,CACrC,CACF,CACF,CACF,CAAC,EAEK,EAAS,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAAI,EAAQ,OAAY,GAE5F,GAAI,CAAC,GAAU,IAAW,SACxB,MAAO,aAIT,EAAQ,YAAY,mBAAmB,EACvC,IAAM,EAAiB,MAAM,EAAQ,aAAa,CAChD,KAAM,YACN,UAAW,CACT,CACE,GAAI,UACJ,SAAU,iBACV,QAAS,CACX,CACF,CACF,CAAC,EAEK,EAAa,OAAO,IAAmB,UAAY,CAAC,MAAM,QAAQ,CAAc,EAClF,EAAe,QACf,GAEJ,GAAI,CAAC,EACH,MAAO,uBAGT,GAAI,IAAW,OAAQ,CACrB,IAAM,EAAS,EAAY,UAAU,CAAU,EAC/C,GAAI,CAAC,EACH,MAAO,qBAGT,IAAM,EAAS,EAAO,UAAY,UAAY,yBAAyB,EAAO,YACxE,EAAW,KAAK,MAAM,EAAO,SAAW,IAAI,EAE9C,EAAS;AAAA,WACR;AAAA,WACA,EAAO;AAAA,UACR;AAAA,YACE;AAAA;AAAA;AAAA,EAGV,EAAO,QAAU;AAAA,EAGb,GAAI,EAAO,OACT,GAAU;AAAA;AAAA,EAEhB,EAAO,SAGH,OAAO,EAAO,KAAK,EAGrB,GAAI,IAAW,OAAQ,CAErB,GAAI,CADY,EAAY,KAAK,CAAU,EAEzC,MAAO,sCAGT,MAAO,sCAAsC,IAG/C,MAAO,kBAEX,EAEe,KC9GR,IAAM,GAAwB,CACnC,GAAI,QACJ,MAAO,SACP,YAAa,yDACb,KAAM,CACJ,CACE,KAAM,aACN,YAAa,4CACb,SAAU,GACV,YAAa,MAAO,IAAiB,CACnC,IAAQ,gBAAiB,KAAa,+BAEtC,OADe,EAAa,EACd,IAAI,CAAC,KAAW,CAC5B,GAAI,EAAM,GACV,MAAO,GAAG,EAAM,SAAS,UAAU,EAAM,SAAS,cAClD,MAAO,EAAM,EACf,EAAE,EAEN,CACF,EACA,QAAS,MAAO,IAAY,CAC1B,IAAQ,eAAc,kBAAiB,eAAgB,KAAa,+BAEhE,EAGJ,GAAI,EAAQ,KAAK,SAAW,EAAG,CAC7B,IAAM,EAAS,EAAa,EACtB,EAAe,EAAgB,EAErC,GAAI,EAAO,SAAW,EACpB,MAAO,uBAIT,IAAM,EAAe,EAAO,IAAI,CAAC,IAAU,CAMzC,MAAO,CACL,MANgB,EAAM,KAAO,EAAa,GAExC,GAAG,EAAM,SAAS,oBAAoB,EAAM,SAAS,cACrD,GAAG,EAAM,SAAS,UAAU,EAAM,SAAS,cAI7C,MAAO,EAAM,EACf,EACD,EAED,EAAQ,YAAY,iCAAiC,EACrD,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,gBACV,QAAS,CACX,CACF,CACF,CAAC,EAID,GAFA,EAAU,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EAAI,EAAQ,MAAW,GAElF,CAAC,EACH,MAAO,6BAGT,OAAU,EAAQ,KAAK,GAMzB,GAAI,CAFY,EAAY,CAAO,EAGjC,MAAO,oBAAoB,yCAG7B,IAAQ,gBAAiB,KAAa,+BAChC,EAAgB,EAAa,CAAO,EAE1C,GAAI,CAAC,EACH,MAAO,+BAGT,MAAO,sBAAsB,EAAc,SAAS;AAAA,EAAS,EAAc,SAAS,cAExF,EAEe,KCtFR,IAAM,GAAwB,CACnC,GAAI,QACJ,MAAO,SACP,YAAa,4CACb,QAAS,MAAO,IAAY,CAC1B,IAAQ,cAAa,oBAAmB,mBAAoB,KAAa,+BAEnE,EAAW,EAAY,EACvB,EAAa,EAAkB,EAErC,GAAI,EAAS,SAAW,EACtB,MAAO,sBAIT,IAAM,EAAc,EAAS,IAAI,CAAC,KAAU,CAC1C,MAAO,GAAG,EAAK,SAAS,UAAU,EAAK,SAAS,cAChD,MAAO,EAAK,EACd,EAAE,EAEF,EAAQ,YAAY,qCAAqC,EAAW,kBAAkB,EACtF,IAAM,EAAU,MAAM,EAAQ,aAAa,CACzC,KAAM,YACN,UAAW,CACT,CACE,GAAI,QACJ,SAAU,uCACV,QAAS,EACT,YAAa,GACb,YAAa,CACf,CACF,CACF,CAAC,EAGK,EAAkB,OAAO,IAAY,UAAY,CAAC,MAAM,QAAQ,CAAO,EACxE,MAAM,QAAQ,EAAQ,KAAQ,EAAI,EAAQ,MAAW,CAAC,EACvD,CAAC,EAEL,GAAI,CAAC,MAAM,QAAQ,CAAe,EAChC,MAAO,4BAMT,GAAI,CAFY,EAAgB,CAAe,EAG7C,MAAO,0BAIT,IAAM,EAAe,EAAgB,OAC/B,EAAgB,EAAS,OAAS,EAGlC,EADe,EAAS,OAAO,CAAC,IAAM,EAAgB,SAAS,EAAE,EAAE,CAAC,EACxC,IAAI,CAAC,IAAM,OAAM,EAAE,SAAS,MAAM,EAAE,KAAK;AAAA,CAAI,EAE/E,MAAO;AAAA,EACT,cAAyB;AAAA;AAAA;AAAA,EAGzB,GAAgB,aAElB,EAEe,KCjER,IAAM,GAA0B,CACrC,GAAI,UACJ,MAAO,WACP,YAAa,sEACb,QAAS,MAAO,IAAY,CAC1B,IAAM,EAAiB,EAAQ,kBAAkB,EAEjD,GAAI,CAAC,EACH,MAAO,gCAGT,GAAI,EAAe,SAAS,SAAW,EACrC,MAAO,8CAGT,IAAM,EAAW,EAAQ,UAAU,EACnC,GAAI,CAAC,GAAU,iBAAmB,CAAC,GAAU,aAC3C,MAAO,0EAGT,EAAQ,YAAY,yDAAyD,EAE7E,GAAI,CAEF,IAAQ,eAAgB,KAAa,gCAC7B,cAAe,KAAa,gCAC5B,mBAAoB,KAAa,+BAGnC,EAAW,EAAY,EAAe,QAAQ,EAC9C,EAAiB,EAAS,YAAY,EAAe,UAE3D,GAAI,CAAC,GAAkB,CAAC,EAAS,aAAa,CAAc,EAC1D,MAAO,YAAY,EAAe,uCAGpC,IAAM,EAAQ,EAAS,aAAa,EAAgB,EAAe,KAAK,EAsBlE,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAnBM,EAAe,SAAS,IAAI,CAAC,IAAQ,CAK/D,IAAI,EAHc,EAAI,QACnB,OAAO,CAAC,IAAS,EAAK,OAAS,MAAM,EACrC,IAAI,CAAC,IAAc,EAAK,OAAO,EACV,KAAK;AAAA,CAAI,EAGjC,GAAI,EAAI,aAAe,EAAI,YAAY,OAAS,EAAG,CACjD,IAAM,EAAkB,EAAI,YACzB,IAAI,CAAC,IAAQ,cAAc,EAAI,eAAe,EAC9C,KAAK;AAAA,CAAI,EACZ,GAAW;AAAA,EAAK,IAGlB,MAAO,GAAG,EAAI,OAAS,OAAS,OAAS,gBAAgB,IAC1D,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA,CAAa;AAAA;AAAA,oDA2Bf,EAAS,MAAM,EAAW,CAC9B,QACA,SAAU,CACR,CACE,KAAM,OACN,QAAS,CACX,CACF,EACA,UAAW,IACb,CAAC,EAGG,EAAU,GACd,cAAiB,KAAS,EAAO,WAC/B,GAAW,EAGb,GAAI,CAAC,GAAW,EAAQ,KAAK,EAAE,SAAW,EACxC,MAAO,gDAIT,IAAM,EAAe,EAAQ,cAC3B,EAAe,SACf,EAAe,KACjB,EAGA,EAAQ,kBAAkB,CAAY,EAEtC,IAAM,EAAe,EAAe,SAAS,OACvC,EAAe,EAAe,OAAS,mBAGvC,EAAiB;AAAA,EAC3B,IAMI,OAFA,MAAM,EAAQ,kBAAkB,CAAc,EAEvC,wBAAuB,OAAkB;AAAA;AAAA;AAAA,6DAChD,MAAO,EAAO,CACd,IAAM,EAAW,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAEtE,OADA,EAAQ,OAAO,oBAAoB,GAAU,EACtC,8BAA8B,KAG3C,EAEe,KCpIf,IAAe,GACb,GAAI,gBACJ,MAAO,iBACP,YAAa,gDACb,KAAM,CACJ,CACE,KAAM,SACN,YAAa,4CACb,SAAU,GACV,YAAa,CAAC,OAAQ,SAAU,SAAS,CAC3C,EACA,CACE,KAAM,OACN,YAAa,4DACb,SAAU,GACV,YAAa,CAAC,KAAM,WAAY,QAAS,KAAK,CAChD,CACF,OAEM,QAAO,CAAC,EAAgB,EAAwC,CACpE,IAAQ,6BAA4B,wBAAyB,EAE7D,GAAI,EAAK,SAAW,EAAG,CACrB,EAAQ,aAAa;AAAA;AAAA,CAAyD,EAC9E,OAGF,IAAM,EAAS,EAAK,GAAG,YAAY,EAEnC,OAAQ,OACD,OACH,EAAQ,aAAa;AAAA;AAAA,CAA8B,EACnD,EAAQ,aAAa,uBAAuB,EAAqB,gBAAkB,YAAa;AAAA,CAAgB,EAChH,EAAQ,aAAa,6BAA6B,EAAqB,sBAAwB,YAAa;AAAA,CAAgB,EAC5H,EAAQ,aAAa,oBAAoB,EAAqB,MAAQ,YAAa;AAAA,CAAgB,EACnG,EAAQ,aAAa;AAAA;AAAA,CAAkE,EACvF,UAEG,aACA,UAAW,CACd,IAAM,EAAY,IAAW,SAE7B,GAAI,EAAK,SAAW,GAAK,EAAK,KAAO,MAEnC,EAA2B,CACzB,gBAAiB,EACjB,sBAAuB,EACvB,MAAO,CACT,CAAC,EACD,EAAQ,aAAa;AAAA,EAAK,EAAY,IAAK,yBAAyB,EAAY,UAAY;AAAA,CAAc,EACrG,KACL,IAAM,EAAO,EAAK,GAAG,YAAY,EAC3B,EAAe,CAAC,EAEtB,OAAQ,OACD,KACH,EAAQ,gBAAkB,EAC1B,UACG,WACH,EAAQ,sBAAwB,EAChC,UACG,QACH,EAAQ,MAAQ,EAChB,cAEA,EAAQ,aAAa;AAAA,+BAAiC;AAAA,CAAQ,EAC9D,EAAQ,aAAa;AAAA,CAAyC,EAC9D,OAGJ,EAA2B,CAAO,EAClC,EAAQ,aAAa;AAAA,EAAK,EAAY,IAAK,OAAO,mBAAsB,EAAY,UAAY;AAAA,CAAc,EAEhH,KACF,SAGE,EAAQ,aAAa;AAAA,oBAAsB;AAAA,CAAU,EACrD,EAAQ,aAAa;AAAA,CAAwC,GAGrE,ECjFO,IAAM,EAA4B,CACvC,GAAI,YACJ,MAAO,aACP,YAAa,oDACb,QAAS,MAAO,IAAY,CAE1B,OADA,EAAQ,WAAW,WAAW,EACvB,2BAEX,ECWO,IAAM,EAAsB,CACjC,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,EAKO,SAAS,EAAU,CAAC,EAAiC,CAC1D,OAAO,EAAS,KAAK,KAAO,EAAI,KAAO,CAAE,EAMpC,SAAS,EAAiB,CAAC,EAAoC,CACpE,OAAO,EAAS,KAAK,KAAO,EAAI,QAAU,CAAK",
|
|
23
|
-
"debugId": "4E21CB18698CD9A964756E2164756E21",
|
|
24
|
-
"names": []
|
|
25
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/utils/token-counter.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Token Counter Utility\n * BPE-based token counting using Hugging Face AutoTokenizer\n *\n * Primary method: BPE tokenizer (auto-selected by Hugging Face)\n * Fallback: Fast estimation when tokenizer unavailable\n */\n\nimport { AutoTokenizer } from '@huggingface/transformers';\n\n// Cache for multiple tokenizers (keyed by tokenizer name)\n// Limited to 3 tokenizers to prevent memory leak (each ~100-500MB)\nconst tokenizerCache = new Map<string, any>();\nconst tokenizerInitializing = new Set<string>();\nconst tokenizerFailed = new Set<string>();\nconst MAX_CACHED_TOKENIZERS = 3;\n\n/**\n * Map provider model names to tokenizer names\n * AutoTokenizer will automatically find the right tokenizer for each model\n */\nconst MODEL_TO_TOKENIZER: Record<string, string> = {\n // OpenAI models\n 'gpt-4': 'Xenova/gpt-4',\n 'gpt-4-turbo': 'Xenova/gpt-4',\n 'gpt-4o': 'Xenova/gpt-4',\n 'gpt-3.5-turbo': 'Xenova/gpt-3.5-turbo',\n 'gpt-3.5': 'Xenova/gpt-3.5-turbo',\n\n // Anthropic Claude models\n 'claude-3-opus': 'Xenova/claude-tokenizer',\n 'claude-3-sonnet': 'Xenova/claude-tokenizer',\n 'claude-3-haiku': 'Xenova/claude-tokenizer',\n 'claude-3.5-sonnet': 'Xenova/claude-tokenizer',\n 'claude-3.5-haiku': 'Xenova/claude-tokenizer',\n\n // Code models\n 'starcoder': 'bigcode/starcoder',\n 'starcoder2': 'bigcode/starcoder2-3b',\n 'codellama': 'codellama/CodeLlama-7b-hf',\n\n // Google models\n 'gemini': 'Xenova/gpt-4', // Fallback to GPT-4 (no official Gemini tokenizer)\n\n // Fallback\n 'default': 'Xenova/gpt-4',\n};\n\n/**\n * Get tokenizer name for a model\n * AutoTokenizer will find the right tokenizer automatically\n */\nfunction getTokenizerForModel(modelName?: string): string {\n if (!modelName) return MODEL_TO_TOKENIZER['default'];\n\n // Direct match\n if (MODEL_TO_TOKENIZER[modelName]) {\n return MODEL_TO_TOKENIZER[modelName];\n }\n\n // Fuzzy match (e.g., \"gpt-4-turbo-preview\" → \"gpt-4\")\n const modelLower = modelName.toLowerCase();\n for (const [key, tokenizer] of Object.entries(MODEL_TO_TOKENIZER)) {\n if (modelLower.includes(key)) {\n return tokenizer;\n }\n }\n\n // Default fallback\n return MODEL_TO_TOKENIZER['default'];\n}\n\n/**\n * Fast fallback estimation (only when BPE tokenizer unavailable)\n * Based on ~3.5 chars per token for code\n */\nfunction estimateFallback(text: string): number {\n if (!text) return 0;\n\n const words = text.split(/\\s+/).filter(Boolean).length;\n const chars = text.length;\n\n const charBasedEstimate = Math.ceil(chars / 3.5);\n const wordBasedEstimate = Math.ceil(words * 1.3);\n\n return Math.round((charBasedEstimate + wordBasedEstimate) / 2);\n}\n\n/**\n * Initialize BPE tokenizer (lazy, cached per tokenizer name)\n * Uses Hugging Face AutoTokenizer to automatically select best tokenizer\n */\nasync function ensureTokenizer(modelName?: string): Promise<any | null> {\n // Get tokenizer name for this model\n const tokenizerName = getTokenizerForModel(modelName);\n\n // Check if already cached\n if (tokenizerCache.has(tokenizerName)) {\n return tokenizerCache.get(tokenizerName);\n }\n\n // Check if previous initialization failed\n if (tokenizerFailed.has(tokenizerName)) {\n return null;\n }\n\n // Wait if initialization in progress for this tokenizer\n while (tokenizerInitializing.has(tokenizerName)) {\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n\n // Check again after waiting\n if (tokenizerCache.has(tokenizerName)) {\n return tokenizerCache.get(tokenizerName);\n }\n if (tokenizerFailed.has(tokenizerName)) {\n return null;\n }\n\n // Initialize with Hugging Face AutoTokenizer\n try {\n tokenizerInitializing.add(tokenizerName);\n\n // Let Hugging Face auto-select and load the best tokenizer\n const tokenizer = await AutoTokenizer.from_pretrained(tokenizerName, {\n // Cache models locally for faster subsequent loads\n cache_dir: './models/.cache',\n // Use local files if available, otherwise download\n local_files_only: false,\n });\n\n // Limit cache size - evict oldest tokenizer if limit reached\n if (tokenizerCache.size >= MAX_CACHED_TOKENIZERS) {\n const oldestKey = tokenizerCache.keys().next().value;\n if (oldestKey) {\n tokenizerCache.delete(oldestKey);\n }\n }\n\n tokenizerCache.set(tokenizerName, tokenizer);\n tokenizerInitializing.delete(tokenizerName);\n return tokenizer;\n } catch (error) {\n console.warn('[TokenCounter] BPE tokenizer initialization failed, using fallback estimation:', error);\n tokenizerFailed.add(tokenizerName);\n tokenizerInitializing.delete(tokenizerName);\n return null;\n }\n}\n\n/**\n * Count tokens using BPE tokenizer (Hugging Face AutoTokenizer)\n * Falls back to estimation if tokenizer unavailable\n *\n * @param text Text to count tokens for\n * @param modelName Optional model name to use specific tokenizer\n * @returns Token count\n */\nexport async function countTokens(text: string, modelName?: string): Promise<number> {\n if (!text) return 0;\n\n const tokenizer = await ensureTokenizer(modelName);\n\n if (!tokenizer) {\n // Tokenizer unavailable, use fallback\n return estimateFallback(text);\n }\n\n try {\n // Use Hugging Face tokenizer API\n const encoded = await tokenizer(text);\n\n // Get token count from encoded result\n if (encoded.input_ids && encoded.input_ids.size) {\n return encoded.input_ids.size;\n }\n\n // Fallback: count array length\n if (Array.isArray(encoded.input_ids)) {\n return encoded.input_ids.length;\n }\n\n // Fallback: if it's a tensor, get its length\n if (encoded.input_ids.data) {\n return encoded.input_ids.data.length;\n }\n\n // Last resort fallback\n return estimateFallback(text);\n } catch (error) {\n console.warn('[TokenCounter] Token counting failed, using fallback:', error);\n return estimateFallback(text);\n }\n}\n\n/**\n * Synchronous token estimation (for cases where async is not possible)\n * Uses fallback estimation only\n */\nexport function estimateTokens(text: string): number {\n return estimateFallback(text);\n}\n\n/**\n * Format token count for display\n * Examples: 150 -> \"150\", 1500 -> \"1.5K\", 1500000 -> \"1.5M\"\n */\nexport function formatTokenCount(count: number): string {\n if (count < 1000) {\n return count.toString();\n }\n\n if (count < 1000000) {\n const k = count / 1000;\n return `${k.toFixed(1)}K`;\n }\n\n const m = count / 1000000;\n return `${m.toFixed(1)}M`;\n}\n\n/**\n * Count tokens for specific model\n * Uses the correct tokenizer for that model\n */\nexport async function countTokensForModel(text: string, modelName: string): Promise<number> {\n return countTokens(text, modelName);\n}\n\n/**\n * Count tokens with display formatting\n * Uses BPE tokenizer (async)\n */\nexport async function countAndFormat(text: string, modelName?: string): Promise<string> {\n const count = await countTokens(text, modelName);\n return `${formatTokenCount(count)} Tokens`;\n}\n\n/**\n * Count tokens with display formatting (sync, estimation only)\n * Use this only when async is not possible\n */\nexport function countAndFormatSync(text: string): string {\n const count = estimateTokens(text);\n return `${formatTokenCount(count)} Tokens`;\n}\n\n/**\n * Batch count tokens for multiple texts\n * Uses BPE tokenizer\n */\nexport async function countTokensBatch(texts: string[], modelName?: string): Promise<number[]> {\n return Promise.all(texts.map(text => countTokens(text, modelName)));\n}\n\n/**\n * Batch count tokens (sync estimation fallback)\n */\nexport function estimateTokensBatch(texts: string[]): number[] {\n return texts.map(estimateTokens);\n}\n\n/**\n * Get tokenizer info (for debugging)\n */\nexport async function getTokenizerInfo(modelName?: string): Promise<{\n modelName: string;\n tokenizerName: string;\n loaded: boolean;\n failed: boolean;\n} | null> {\n const tokenizerName = getTokenizerForModel(modelName);\n const tokenizer = await ensureTokenizer(modelName);\n\n return {\n modelName: modelName || 'default',\n tokenizerName,\n loaded: tokenizer !== null,\n failed: tokenizerFailed.has(tokenizerName),\n };\n}\n\n/**\n * Get supported models\n */\nexport function getSupportedModels(): string[] {\n return Object.keys(MODEL_TO_TOKENIZER).filter(k => k !== 'default');\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "4BAQA,wBAAS,kCAIT,IAAM,EAAiB,IAAI,IACrB,EAAwB,IAAI,IAC5B,EAAkB,IAAI,IACtB,EAAwB,EAMxB,EAA6C,CAEjD,QAAS,eACT,cAAe,eACf,SAAU,eACV,gBAAiB,uBACjB,UAAW,uBAGX,gBAAiB,0BACjB,kBAAmB,0BACnB,iBAAkB,0BAClB,oBAAqB,0BACrB,mBAAoB,0BAGpB,UAAa,oBACb,WAAc,wBACd,UAAa,4BAGb,OAAU,eAGV,QAAW,cACb,EAMA,SAAS,CAAoB,CAAC,EAA4B,CACxD,GAAI,CAAC,EAAW,OAAO,EAAmB,QAG1C,GAAI,EAAmB,GACrB,OAAO,EAAmB,GAI5B,IAAM,EAAa,EAAU,YAAY,EACzC,QAAY,EAAK,KAAc,OAAO,QAAQ,CAAkB,EAC9D,GAAI,EAAW,SAAS,CAAG,EACzB,OAAO,EAKX,OAAO,EAAmB,QAO5B,SAAS,CAAgB,CAAC,EAAsB,CAC9C,GAAI,CAAC,EAAM,MAAO,GAElB,IAAM,EAAQ,EAAK,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE,OAC1C,EAAQ,EAAK,OAEb,EAAoB,KAAK,KAAK,EAAQ,GAAG,EACzC,EAAoB,KAAK,KAAK,EAAQ,GAAG,EAE/C,OAAO,KAAK,OAAO,EAAoB,GAAqB,CAAC,EAO/D,eAAe,CAAe,CAAC,EAAyC,CAEtE,IAAM,EAAgB,EAAqB,CAAS,EAGpD,GAAI,EAAe,IAAI,CAAa,EAClC,OAAO,EAAe,IAAI,CAAa,EAIzC,GAAI,EAAgB,IAAI,CAAa,EACnC,OAAO,KAIT,MAAO,EAAsB,IAAI,CAAa,EAC5C,MAAM,IAAI,QAAQ,KAAW,WAAW,EAAS,GAAG,CAAC,EAIvD,GAAI,EAAe,IAAI,CAAa,EAClC,OAAO,EAAe,IAAI,CAAa,EAEzC,GAAI,EAAgB,IAAI,CAAa,EACnC,OAAO,KAIT,GAAI,CACF,EAAsB,IAAI,CAAa,EAGvC,IAAM,EAAY,MAAM,EAAc,gBAAgB,EAAe,CAEnE,UAAW,kBAEX,iBAAkB,EACpB,CAAC,EAGD,GAAI,EAAe,MAAQ,EAAuB,CAChD,IAAM,EAAY,EAAe,KAAK,EAAE,KAAK,EAAE,MAC/C,GAAI,EACF,EAAe,OAAO,CAAS,EAMnC,OAFA,EAAe,IAAI,EAAe,CAAS,EAC3C,EAAsB,OAAO,CAAa,EACnC,EACP,MAAO,EAAO,CAId,OAHA,QAAQ,KAAK,iFAAkF,CAAK,EACpG,EAAgB,IAAI,CAAa,EACjC,EAAsB,OAAO,CAAa,EACnC,MAYX,eAAsB,CAAW,CAAC,EAAc,EAAqC,CACnF,GAAI,CAAC,EAAM,MAAO,GAElB,IAAM,EAAY,MAAM,EAAgB,CAAS,EAEjD,GAAI,CAAC,EAEH,OAAO,EAAiB,CAAI,EAG9B,GAAI,CAEF,IAAM,EAAU,MAAM,EAAU,CAAI,EAGpC,GAAI,EAAQ,WAAa,EAAQ,UAAU,KACzC,OAAO,EAAQ,UAAU,KAI3B,GAAI,MAAM,QAAQ,EAAQ,SAAS,EACjC,OAAO,EAAQ,UAAU,OAI3B,GAAI,EAAQ,UAAU,KACpB,OAAO,EAAQ,UAAU,KAAK,OAIhC,OAAO,EAAiB,CAAI,EAC5B,MAAO,EAAO,CAEd,OADA,QAAQ,KAAK,wDAAyD,CAAK,EACpE,EAAiB,CAAI,GAQzB,SAAS,CAAc,CAAC,EAAsB,CACnD,OAAO,EAAiB,CAAI,EAOvB,SAAS,CAAgB,CAAC,EAAuB,CACtD,GAAI,EAAQ,KACV,OAAO,EAAM,SAAS,EAGxB,GAAI,EAAQ,IAEV,MAAO,IADG,EAAQ,MACN,QAAQ,CAAC,KAIvB,MAAO,IADG,EAAQ,KACN,QAAQ,CAAC,KAOvB,eAAsB,CAAmB,CAAC,EAAc,EAAoC,CAC1F,OAAO,EAAY,EAAM,CAAS,EAOpC,eAAsB,CAAc,CAAC,EAAc,EAAqC,CACtF,IAAM,EAAQ,MAAM,EAAY,EAAM,CAAS,EAC/C,MAAO,GAAG,EAAiB,CAAK,WAO3B,SAAS,CAAkB,CAAC,EAAsB,CACvD,IAAM,EAAQ,EAAe,CAAI,EACjC,MAAO,GAAG,EAAiB,CAAK,WAOlC,eAAsB,CAAgB,CAAC,EAAiB,EAAuC,CAC7F,OAAO,QAAQ,IAAI,EAAM,IAAI,KAAQ,EAAY,EAAM,CAAS,CAAC,CAAC,EAM7D,SAAS,CAAmB,CAAC,EAA2B,CAC7D,OAAO,EAAM,IAAI,CAAc,EAMjC,eAAsB,CAAgB,CAAC,EAK7B,CACR,IAAM,EAAgB,EAAqB,CAAS,EAC9C,EAAY,MAAM,EAAgB,CAAS,EAEjD,MAAO,CACL,UAAW,GAAa,UACxB,gBACA,OAAQ,IAAc,KACtB,OAAQ,EAAgB,IAAI,CAAa,CAC3C,EAMK,SAAS,CAAkB,EAAa,CAC7C,OAAO,OAAO,KAAK,CAAkB,EAAE,OAAO,KAAK,IAAM,SAAS",
|
|
8
|
-
"debugId": "0C9FB9C9D50392DD64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/config/ai-config.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * AI Configuration Management\n *\n * Three-tier configuration system:\n * 1. Global: ~/.sylphx-flow/settings.json (user defaults, contains API keys)\n * 2. Project: ./.sylphx-flow/settings.json (project preferences, no secrets)\n * 3. Local: ./.sylphx-flow/settings.local.json (local overrides, gitignored)\n *\n * Priority: local > project > global\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { z } from 'zod';\nimport { type Result, success, tryCatchAsync } from '../core/functional/result.js';\nimport { getAllProviders } from '../providers/index.js';\n\n/**\n * Provider IDs\n * Provider metadata (name, config schema, etc) comes from provider registry\n */\nexport type ProviderId = 'anthropic' | 'openai' | 'google' | 'openrouter' | 'claude-code' | 'zai';\n\n/**\n * AI_PROVIDERS - Provider metadata from registry\n * Contains basic info (id, name) for UI components\n * Config schemas are defined in each provider's getConfigSchema()\n */\nexport const AI_PROVIDERS = getAllProviders();\n\n/**\n * Provider configuration\n * Each provider can have different config fields (defined by provider.getConfigSchema())\n * Common fields: apiKey, defaultModel, etc\n */\nexport interface ProviderConfigValue {\n defaultModel?: string;\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * AI configuration schema\n * Uses generic Record for provider configs - validation happens at provider level\n */\nconst aiConfigSchema = z.object({\n defaultProvider: z.enum(['anthropic', 'openai', 'google', 'openrouter', 'claude-code', 'zai']).optional(),\n defaultModel: z.string().optional(),\n providers: z.record(\n z.string(),\n z.object({\n defaultModel: z.string().optional(),\n }).passthrough() // Allow additional fields defined by provider\n ).optional(),\n});\n\nexport type AIConfig = z.infer<typeof aiConfigSchema>;\n\n/**\n * Configuration file paths\n */\nconst GLOBAL_CONFIG_FILE = path.join(os.homedir(), '.sylphx-flow', 'settings.json');\nconst PROJECT_CONFIG_FILE = '.sylphx-flow/settings.json';\nconst LOCAL_CONFIG_FILE = '.sylphx-flow/settings.local.json';\n\n/**\n * Deprecated config file (for migration)\n */\nconst LEGACY_CONFIG_FILE = '.sylphx-flow/ai-config.json';\n\n/**\n * Get AI config file paths in priority order\n */\nexport const getAIConfigPaths = (cwd: string = process.cwd()): {\n global: string;\n project: string;\n local: string;\n legacy: string;\n} => ({\n global: GLOBAL_CONFIG_FILE,\n project: path.join(cwd, PROJECT_CONFIG_FILE),\n local: path.join(cwd, LOCAL_CONFIG_FILE),\n legacy: path.join(cwd, LEGACY_CONFIG_FILE),\n});\n\n/**\n * Load config from a single file\n */\nconst loadConfigFile = async (filePath: string): Promise<AIConfig | null> => {\n try {\n const content = await fs.readFile(filePath, 'utf8');\n const parsed = JSON.parse(content);\n return aiConfigSchema.parse(parsed);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n return null; // File doesn't exist\n }\n throw error; // Re-throw other errors\n }\n};\n\n/**\n * Deep merge two configs (b overwrites a)\n */\nconst mergeConfigs = (a: AIConfig, b: AIConfig): AIConfig => {\n // Merge provider configs dynamically\n const allProviderIds = new Set([\n ...Object.keys(a.providers || {}),\n ...Object.keys(b.providers || {}),\n ]);\n\n const mergedProviders: Record<string, any> = {};\n for (const providerId of allProviderIds) {\n mergedProviders[providerId] = {\n ...a.providers?.[providerId],\n ...b.providers?.[providerId],\n };\n }\n\n return {\n defaultProvider: b.defaultProvider ?? a.defaultProvider,\n defaultModel: b.defaultModel ?? a.defaultModel,\n providers: mergedProviders,\n };\n};\n\n/**\n * Check if any AI config exists\n */\nexport const aiConfigExists = async (cwd: string = process.cwd()): Promise<boolean> => {\n const paths = getAIConfigPaths(cwd);\n try {\n // Check any of the config files\n await fs.access(paths.global).catch(() => {});\n return true;\n } catch {}\n\n try {\n await fs.access(paths.project);\n return true;\n } catch {}\n\n try {\n await fs.access(paths.local);\n return true;\n } catch {}\n\n try {\n await fs.access(paths.legacy);\n return true;\n } catch {}\n\n return false;\n};\n\n/**\n * Load AI configuration\n * Merges global, project, and local configs with priority: local > project > global\n * Automatically migrates legacy config on first load\n */\nexport const loadAIConfig = async (cwd: string = process.cwd()): Promise<Result<AIConfig, Error>> => {\n return tryCatchAsync(\n async () => {\n const paths = getAIConfigPaths(cwd);\n\n // Load all config files\n const [globalConfig, projectConfig, localConfig, legacyConfig] = await Promise.all([\n loadConfigFile(paths.global),\n loadConfigFile(paths.project),\n loadConfigFile(paths.local),\n loadConfigFile(paths.legacy),\n ]);\n\n // Auto-migrate legacy config if it exists and global doesn't\n if (legacyConfig && !globalConfig) {\n await migrateLegacyConfig(cwd);\n // Reload global config after migration\n const migratedGlobal = await loadConfigFile(paths.global);\n if (migratedGlobal) {\n // Start with empty config\n let merged: AIConfig = {};\n\n // Merge in priority order: global < project < local\n merged = mergeConfigs(merged, migratedGlobal);\n if (projectConfig) merged = mergeConfigs(merged, projectConfig);\n if (localConfig) merged = mergeConfigs(merged, localConfig);\n\n return merged;\n }\n }\n\n // Start with empty config\n let merged: AIConfig = {};\n\n // Merge in priority order: global < project < local < legacy (for backwards compat)\n if (globalConfig) merged = mergeConfigs(merged, globalConfig);\n if (projectConfig) merged = mergeConfigs(merged, projectConfig);\n if (localConfig) merged = mergeConfigs(merged, localConfig);\n if (legacyConfig) merged = mergeConfigs(merged, legacyConfig);\n\n return merged;\n },\n (error: any) => new Error(`Failed to load AI config: ${error.message}`)\n );\n};\n\n/**\n * Save AI configuration to global settings\n * By default, all configuration (including API keys) goes to ~/.sylphx-flow/settings.json\n * Automatically sets default provider if not set\n */\nexport const saveAIConfig = async (\n config: AIConfig,\n cwd: string = process.cwd()\n): Promise<Result<void, Error>> => {\n const paths = getAIConfigPaths(cwd);\n const configPath = paths.global; // Save to global by default\n\n return tryCatchAsync(\n async () => {\n // Ensure directory exists\n await fs.mkdir(path.dirname(configPath), { recursive: true });\n\n // Auto-set default provider if not set\n const configToSave = { ...config };\n if (!configToSave.defaultProvider && configToSave.providers) {\n // Get configured providers (those that pass isConfigured check)\n const { getProvider } = await import('../providers/index.js');\n const configuredProviders: ProviderId[] = [];\n\n for (const [providerId, providerConfig] of Object.entries(configToSave.providers)) {\n try {\n const provider = getProvider(providerId as ProviderId);\n if (provider.isConfigured(providerConfig)) {\n configuredProviders.push(providerId as ProviderId);\n }\n } catch {\n // Skip unknown providers\n }\n }\n\n // Use last configured provider as default\n if (configuredProviders.length > 0) {\n configToSave.defaultProvider = configuredProviders[configuredProviders.length - 1];\n }\n }\n\n // Validate config\n const validated = aiConfigSchema.parse(configToSave);\n\n // Write config\n await fs.writeFile(configPath, JSON.stringify(validated, null, 2) + '\\n', 'utf8');\n },\n (error: any) => new Error(`Failed to save AI config: ${error.message}`)\n );\n};\n\n/**\n * Save AI configuration to a specific location\n */\nexport const saveAIConfigTo = async (\n config: AIConfig,\n location: 'global' | 'project' | 'local',\n cwd: string = process.cwd()\n): Promise<Result<void, Error>> => {\n const paths = getAIConfigPaths(cwd);\n const configPath = paths[location];\n\n return tryCatchAsync(\n async () => {\n // Ensure directory exists\n await fs.mkdir(path.dirname(configPath), { recursive: true });\n\n // Validate config\n const validated = aiConfigSchema.parse(config);\n\n // Write config\n await fs.writeFile(configPath, JSON.stringify(validated, null, 2) + '\\n', 'utf8');\n },\n (error: any) => new Error(`Failed to save AI config to ${location}: ${error.message}`)\n );\n};\n\n/**\n * Update AI configuration (merge with existing)\n * Default provider is auto-set by saveAIConfig to last configured provider\n */\nexport const updateAIConfig = async (\n updates: Partial<AIConfig>,\n cwd: string = process.cwd()\n): Promise<Result<void, Error>> => {\n const currentResult = await loadAIConfig(cwd);\n\n if (currentResult._tag === 'Failure') {\n return currentResult;\n }\n\n const merged: AIConfig = {\n ...currentResult.value,\n ...updates,\n providers: {\n ...currentResult.value.providers,\n ...updates.providers,\n },\n };\n\n // saveAIConfig will auto-set default provider if not set\n return saveAIConfig(merged, cwd);\n};\n\n/**\n * Get configured providers\n * Uses provider's isConfigured() method to check\n */\nexport const getConfiguredProviders = async (\n cwd: string = process.cwd()\n): Promise<ProviderId[]> => {\n const result = await loadAIConfig(cwd);\n\n if (result._tag === 'Failure') {\n return [];\n }\n\n const providers: ProviderId[] = [];\n const config = result.value;\n\n if (!config.providers) {\n return [];\n }\n\n // Dynamically import provider registry to avoid circular dependency\n const { getProvider } = await import('../providers/index.js');\n\n for (const [providerId, providerConfig] of Object.entries(config.providers)) {\n try {\n const provider = getProvider(providerId as ProviderId);\n if (provider.isConfigured(providerConfig)) {\n providers.push(providerId as ProviderId);\n }\n } catch {\n // Skip unknown providers\n }\n }\n\n return providers;\n};\n\n/**\n * Migrate legacy ai-config.json to new settings system\n * Automatically called on first load if legacy config exists\n */\nexport const migrateLegacyConfig = async (cwd: string = process.cwd()): Promise<Result<void, Error>> => {\n return tryCatchAsync(\n async () => {\n const paths = getAIConfigPaths(cwd);\n\n // Check if legacy config exists\n const legacyConfig = await loadConfigFile(paths.legacy);\n if (!legacyConfig) {\n return; // No legacy config to migrate\n }\n\n // Check if global config already exists\n const globalConfig = await loadConfigFile(paths.global);\n if (globalConfig) {\n // Global config exists, don't overwrite it\n console.log('Legacy config found but global config already exists. Skipping migration.');\n console.log(`You can manually delete ${paths.legacy} if migration is complete.`);\n return;\n }\n\n // Migrate to global config\n await fs.mkdir(path.dirname(paths.global), { recursive: true });\n await fs.writeFile(paths.global, JSON.stringify(legacyConfig, null, 2) + '\\n', 'utf8');\n\n console.log(`✓ Migrated configuration from ${paths.legacy} to ${paths.global}`);\n console.log(` You can now safely delete the legacy file: ${paths.legacy}`);\n },\n (error: any) => new Error(`Failed to migrate legacy config: ${error.message}`)\n );\n};\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "CC92FC8B2C680A5264756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
package/dist/chunk-8ep9gk6d.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{ba as J}from"./chunk-f676awyz.js";import{Sb as C,Ub as W}from"./chunk-f9yb2zk3.js";var V=C((zq,u)=>{var{create:x,defineProperty:X,getOwnPropertyDescriptor:D,getOwnPropertyNames:S,getPrototypeOf:I}=Object,M=Object.prototype.hasOwnProperty,y=(q,z)=>{for(var B in z)X(q,B,{get:z[B],enumerable:!0})},w=(q,z,B,F)=>{if(z&&typeof z==="object"||typeof z==="function"){for(let G of S(z))if(!M.call(q,G)&&G!==B)X(q,G,{get:()=>z[G],enumerable:!(F=D(z,G))||F.enumerable})}return q},v=(q,z,B)=>(B=q!=null?x(I(q)):{},w(z||!q||!q.__esModule?X(B,"default",{value:q,enumerable:!0}):B,q)),g=(q)=>w(X({},"__esModule",{value:!0}),q),R={};y(R,{findRootDir:()=>l,getUserDataDir:()=>P});u.exports=g(R);var Q=v(W("path")),h=v(W("fs")),$=v(W("os")),b=J();function l(){try{let q=process.cwd();while(q!==Q.default.dirname(q)){let z=Q.default.join(q,".vercel");if(h.default.existsSync(z))return q;q=Q.default.dirname(q)}}catch(q){throw new b.VercelOidcTokenError("Token refresh only supported in node server environments")}throw new b.VercelOidcTokenError("Unable to find root directory")}function P(){if(process.env.XDG_DATA_HOME)return process.env.XDG_DATA_HOME;switch($.default.platform()){case"darwin":return Q.default.join($.default.homedir(),"Library/Application Support");case"linux":return Q.default.join($.default.homedir(),".local/share");case"win32":if(process.env.LOCALAPPDATA)return process.env.LOCALAPPDATA;return null;default:return null}}});var qq=C((Bq,j)=>{var{create:c,defineProperty:Y,getOwnPropertyDescriptor:f,getOwnPropertyNames:k,getPrototypeOf:i}=Object,s=Object.prototype.hasOwnProperty,n=(q,z)=>{for(var B in z)Y(q,B,{get:z[B],enumerable:!0})},N=(q,z,B,F)=>{if(z&&typeof z==="object"||typeof z==="function"){for(let G of k(z))if(!s.call(q,G)&&G!==B)Y(q,G,{get:()=>z[G],enumerable:!(F=f(z,G))||F.enumerable})}return q},E=(q,z,B)=>(B=q!=null?c(i(q)):{},N(z||!q||!q.__esModule?Y(B,"default",{value:q,enumerable:!0}):B,q)),p=(q)=>N(Y({},"__esModule",{value:!0}),q),O={};n(O,{assertVercelOidcTokenResponse:()=>A,findProjectInfo:()=>m,getTokenPayload:()=>t,getVercelCliToken:()=>d,getVercelDataDir:()=>T,getVercelOidcToken:()=>a,isExpired:()=>o,loadToken:()=>r,saveToken:()=>_});j.exports=p(O);var L=E(W("path")),H=E(W("fs")),K=J(),Z=V();function T(){let z=(0,Z.getUserDataDir)();if(!z)return null;return L.join(z,"com.vercel.cli")}function d(){let q=T();if(!q)return null;let z=L.join(q,"auth.json");if(!H.existsSync(z))return null;let B=H.readFileSync(z,"utf8");if(!B)return null;return JSON.parse(B).token}async function a(q,z,B){try{let F=`https://api.vercel.com/v1/projects/${z}/token?source=vercel-oidc-refresh${B?`&teamId=${B}`:""}`,G=await fetch(F,{method:"POST",headers:{Authorization:`Bearer ${q}`}});if(!G.ok)throw new K.VercelOidcTokenError(`Failed to refresh OIDC token: ${G.statusText}`);let U=await G.json();return A(U),U}catch(F){throw new K.VercelOidcTokenError("Failed to refresh OIDC token",F)}}function A(q){if(!q||typeof q!=="object")throw TypeError("Expected an object");if(!("token"in q)||typeof q.token!=="string")throw TypeError("Expected a string-valued token property")}function m(){let q=(0,Z.findRootDir)();if(!q)throw new K.VercelOidcTokenError("Unable to find root directory");try{let z=L.join(q,".vercel","project.json");if(!H.existsSync(z))throw new K.VercelOidcTokenError("project.json not found");let B=JSON.parse(H.readFileSync(z,"utf8"));if(typeof B.projectId!=="string"&&typeof B.orgId!=="string")throw TypeError("Expected a string-valued projectId property");return{projectId:B.projectId,teamId:B.orgId}}catch(z){throw new K.VercelOidcTokenError("Unable to find project ID",z)}}function _(q,z){try{let B=(0,Z.getUserDataDir)();if(!B)throw new K.VercelOidcTokenError("Unable to find user data directory");let F=L.join(B,"com.vercel.token",`${z}.json`),G=JSON.stringify(q);H.mkdirSync(L.dirname(F),{mode:432,recursive:!0}),H.writeFileSync(F,G),H.chmodSync(F,432);return}catch(B){throw new K.VercelOidcTokenError("Failed to save token",B)}}function r(q){try{let z=(0,Z.getUserDataDir)();if(!z)return null;let B=L.join(z,"com.vercel.token",`${q}.json`);if(!H.existsSync(B))return null;let F=JSON.parse(H.readFileSync(B,"utf8"));return A(F),F}catch(z){throw new K.VercelOidcTokenError("Failed to load token",z)}}function t(q){let z=q.split(".");if(z.length!==3)throw new K.VercelOidcTokenError("Invalid token");let B=z[1].replace(/-/g,"+").replace(/_/g,"/"),F=B.padEnd(B.length+(4-B.length%4)%4,"=");return JSON.parse(Buffer.from(F,"base64").toString("utf8"))}var e=900000;function o(q){return q.exp*1000<Date.now()+e}});export default qq();
|
|
2
|
-
export{qq as aa};
|
|
3
|
-
|
|
4
|
-
//# debugId=AB3F4FE84D0EEB4564756E2164756E21
|