@flexkit/studio 0.2.26 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/{activity-nav-button-4VTYGP4T.js → activity-nav-button-E4I4YC3X.js} +2 -2
  2. package/dist/{activity-nav-button-4VTYGP4T.js.map → activity-nav-button-E4I4YC3X.js.map} +1 -1
  3. package/dist/chat-page-SLY7JDT3.js +4 -0
  4. package/dist/chat-page-SLY7JDT3.js.map +1 -0
  5. package/dist/{chunk-NAUY7EN3.js → chunk-52RJAZXC.js} +2 -2
  6. package/dist/{chunk-NAUY7EN3.js.map → chunk-52RJAZXC.js.map} +1 -1
  7. package/dist/{chunk-RARRMN5A.js → chunk-5JQ4T6EJ.js} +3 -3
  8. package/dist/{chunk-RARRMN5A.js.map → chunk-5JQ4T6EJ.js.map} +1 -1
  9. package/dist/chunk-5LGIALCK.js +2 -0
  10. package/dist/chunk-5LGIALCK.js.map +1 -0
  11. package/dist/chunk-AHYUN6BW.js +10 -0
  12. package/dist/chunk-AHYUN6BW.js.map +1 -0
  13. package/dist/{chunk-7QHGKOAB.js → chunk-DUH7EUOQ.js} +3 -3
  14. package/dist/{chunk-7QHGKOAB.js.map → chunk-DUH7EUOQ.js.map} +1 -1
  15. package/dist/{chunk-5OGT6WGZ.js → chunk-ERCVR23U.js} +2 -2
  16. package/dist/{chunk-5OGT6WGZ.js.map → chunk-ERCVR23U.js.map} +1 -1
  17. package/dist/{chunk-P5YGMKPO.js → chunk-GELQFNMW.js} +2 -2
  18. package/dist/{chunk-P5YGMKPO.js.map → chunk-GELQFNMW.js.map} +1 -1
  19. package/dist/{chunk-3L4LYXSR.js → chunk-JL7F6DNM.js} +2 -2
  20. package/dist/{chunk-3L4LYXSR.js.map → chunk-JL7F6DNM.js.map} +1 -1
  21. package/dist/{chunk-BCFG4FXM.js → chunk-KOPI2BA6.js} +3 -3
  22. package/dist/{chunk-BCFG4FXM.js.map → chunk-KOPI2BA6.js.map} +1 -1
  23. package/dist/{chunk-ZI22345U.js → chunk-O45E7U6A.js} +3 -3
  24. package/dist/{chunk-ZI22345U.js.map → chunk-O45E7U6A.js.map} +1 -1
  25. package/dist/{chunk-HE7I5LVU.js → chunk-OVV3SPEI.js} +2 -2
  26. package/dist/{chunk-HE7I5LVU.js.map → chunk-OVV3SPEI.js.map} +1 -1
  27. package/dist/{chunk-Z6WDRVBW.js → chunk-T2F2LSKT.js} +2 -2
  28. package/dist/{chunk-Z6WDRVBW.js.map → chunk-T2F2LSKT.js.map} +1 -1
  29. package/dist/{chunk-V45Z7U6J.js → chunk-TZQIYXV6.js} +2 -2
  30. package/dist/{chunk-V45Z7U6J.js.map → chunk-TZQIYXV6.js.map} +1 -1
  31. package/dist/chunk-U6VZY3V2.js +3 -0
  32. package/dist/chunk-U6VZY3V2.js.map +1 -0
  33. package/dist/{chunk-3YL7XGH5.js → chunk-VFORIVVT.js} +3 -3
  34. package/dist/{chunk-3YL7XGH5.js.map → chunk-VFORIVVT.js.map} +1 -1
  35. package/dist/{chunk-WFJICDCL.js → chunk-XYLLG7TG.js} +3 -3
  36. package/dist/{chunk-WFJICDCL.js.map → chunk-XYLLG7TG.js.map} +1 -1
  37. package/dist/{entry-TFSFZ6FA.js → entry-MWNECEGJ.js} +2 -2
  38. package/dist/{entry-TFSFZ6FA.js.map → entry-MWNECEGJ.js.map} +1 -1
  39. package/dist/index.css +15 -0
  40. package/dist/index.js +2 -2
  41. package/dist/{list-ORNZB5HP.js → list-IB75TGDL.js} +2 -2
  42. package/dist/{list-ORNZB5HP.js.map → list-IB75TGDL.js.map} +1 -1
  43. package/dist/{list-Q5R3QLQU.js → list-L2ZOEIPM.js} +3 -3
  44. package/dist/{list-Q5R3QLQU.js.map → list-L2ZOEIPM.js.map} +1 -1
  45. package/dist/{pages-IYR7KLDW.js → pages-EMWNEUIL.js} +3 -3
  46. package/dist/{pages-IYR7KLDW.js.map → pages-EMWNEUIL.js.map} +1 -1
  47. package/dist/{plugin-pages-QVUZRBF7.js → plugin-pages-FCCI6LUM.js} +2 -2
  48. package/dist/{plugin-pages-QVUZRBF7.js.map → plugin-pages-FCCI6LUM.js.map} +1 -1
  49. package/dist/record-links-MQVSKVHN.js +2 -0
  50. package/dist/{record-links-XNRXCW3Y.js.map → record-links-MQVSKVHN.js.map} +1 -1
  51. package/dist/{root-5T3UQRUT.js → root-EFNWUWPN.js} +2 -2
  52. package/dist/{root-5T3UQRUT.js.map → root-EFNWUWPN.js.map} +1 -1
  53. package/dist/{root-LGCOXNRR.js → root-JEOBPU7A.js} +2 -2
  54. package/dist/{root-LGCOXNRR.js.map → root-JEOBPU7A.js.map} +1 -1
  55. package/dist/{root-2BTH6M5K.js → root-LQAVWIY3.js} +3 -3
  56. package/dist/{root-2BTH6M5K.js.map → root-LQAVWIY3.js.map} +1 -1
  57. package/dist/{root-TOTFZUJI.js → root-NJZRHKIE.js} +2 -2
  58. package/dist/{root-TOTFZUJI.js.map → root-NJZRHKIE.js.map} +1 -1
  59. package/dist/{root-A76E3Z35.js → root-NU5FDZDZ.js} +3 -3
  60. package/dist/{root-A76E3Z35.js.map → root-NU5FDZDZ.js.map} +1 -1
  61. package/dist/{root-XPFHRGVP.js → root-WQ46J72W.js} +3 -3
  62. package/dist/{root-XPFHRGVP.js.map → root-WQ46J72W.js.map} +1 -1
  63. package/dist/{search-4UVG2IJ5.js → search-X5IUEVYF.js} +2 -2
  64. package/dist/{search-4UVG2IJ5.js.map → search-X5IUEVYF.js.map} +1 -1
  65. package/dist/skills-pages-LHPLYVNU.js +2 -0
  66. package/dist/skills-pages-LHPLYVNU.js.map +1 -0
  67. package/dist/{source-P5W56BKA.js → source-2KGHPYXB.js} +2 -2
  68. package/dist/{source-P5W56BKA.js.map → source-2KGHPYXB.js.map} +1 -1
  69. package/package.json +3 -3
  70. package/dist/chat-page-U46RRUKG.js +0 -4
  71. package/dist/chat-page-U46RRUKG.js.map +0 -1
  72. package/dist/chunk-HPLIQBUP.js +0 -8
  73. package/dist/chunk-HPLIQBUP.js.map +0 -1
  74. package/dist/chunk-MNLYE7DK.js +0 -3
  75. package/dist/chunk-MNLYE7DK.js.map +0 -1
  76. package/dist/chunk-U6E7GNQW.js +0 -2
  77. package/dist/chunk-U6E7GNQW.js.map +0 -1
  78. package/dist/record-links-XNRXCW3Y.js +0 -2
  79. package/dist/skills-pages-3RFTYQ2K.js +0 -2
  80. package/dist/skills-pages-3RFTYQ2K.js.map +0 -1
@@ -1,3 +0,0 @@
1
- import'./index.css';import {e}from'./chunk-7KLXWCDS.js';import {b as b$1,c}from'./chunk-5CVDMZUI.js';import {put}from'@vercel/blob/client';function w(s,o){let l=o.trim();return l?s.trim()?/\s$/.test(s)||/^[.,!?;:]/.test(l)?`${s}${l}`:`${s} ${l}`:s.length===0?l:`${s}${l}`:s}async function C(s){if(typeof window>"u")throw new Error("Dictation is only available in the browser.");let o=window.AudioContext??window.webkitAudioContext;if(!o)throw new Error("This browser cannot decode recorded audio.");let l=await s.arrayBuffer(),u=new o;try{let n=await u.decodeAudioData(l.slice(0)),i=$(n),t=I(i,n.sampleRate,24e3),e=P(t),a=t.length/24e3;if(a<.25)throw new Error("No speech was captured. Try again.");if(a>60)throw new Error(`Dictation is limited to ${String(60)} seconds.`);return {durationSeconds:a,pcm:new Blob([e],{type:"audio/pcm"})}}finally{await u.close();}}function $(s){let{length:o,numberOfChannels:l}=s;if(l===1)return s.getChannelData(0).slice();let u=new Float32Array(o);for(let n=0;n<o;n+=1){let i=0;for(let t=0;t<l;t+=1)i+=s.getChannelData(t)[n]??0;u[n]=i/l;}return u}function I(s,o,l){if(o===l)return s;let u=o/l,n=Math.max(1,Math.round(s.length/u)),i=new Float32Array(n);for(let t=0;t<n;t+=1){let e=t*u,a=Math.floor(e),c=Math.min(a+1,s.length-1),r=e-a,g=s[a]??0,m=s[c]??0;i[t]=g+(m-g)*r;}return i}function P(s){let o=new ArrayBuffer(s.length*2),l=new DataView(o);for(let u=0;u<s.length;u+=1){let n=Math.max(-1,Math.min(1,s[u]??0));l.setInt16(u*2,n<0?n*32768:n*32767,true);}return o}async function b(s){if(!(typeof crypto>"u"||!crypto.subtle))try{let o=await crypto.subtle.digest("SHA-256",await s.arrayBuffer());return Array.from(new Uint8Array(o),l=>l.toString(16).padStart(2,"0")).join("")}catch{return}}var d=class extends Error{code;status;constructor(o,l,u=null){super(l),this.name="AgentUploadError",this.code=u,this.status=o;}};function y(){if(typeof window>"u")return "flexkit.io";if(b$1())return c;let{hostname:s}=window.location;return s==="localhost"||s==="127.0.0.1"||s==="flexkit.test"||s.endsWith(".flexkit.test")?"flexkit.test":"flexkit.io"}function v(){return `https://${y()}`}function x(s,o){return `https://${s}.api.${y()}/automations/webhook/${encodeURIComponent(o)}`}function N(s){let o=`/api/flexkit/${s}`,l=`${o}/automations`,u=`${o}/skills`,n=`${o}/agent/chats`;async function i(t,e){let a=await fetch(t,{credentials:"include",headers:{"Content-Type":"application/json",...e?.headers??{}},...e}),c=await a.json();if(!a.ok){let r=c&&typeof c=="object"&&"error"in c?String(c.error):"Request failed";throw new Error(r)}return c}return {connectPlugins:t=>i(`${o}/plugins/connect`,{method:"POST",body:JSON.stringify(t)}),connectPluginToken:t=>i(`${o}/plugins/connect-token`,{method:"POST",body:JSON.stringify(t)}),pluginOAuthStatus:t=>i(`${o}/plugins/oauth-transactions/${encodeURIComponent(t)}`),updatePluginConnection:(t,e)=>i(`${o}/plugin-connections/${encodeURIComponent(t)}`,{method:"PATCH",body:JSON.stringify(e)}),disconnectPlugin:t=>i(`${o}/plugin-connections/${encodeURIComponent(t)}`,{method:"DELETE"}),installPlugin:t=>i(`${o}/plugins/${encodeURIComponent(t)}/installation`,{method:"PUT",body:JSON.stringify({})}),setPluginPolicy:(t,e)=>i(`${o}/plugins/${encodeURIComponent(t)}/policy`,{method:"PATCH",body:JSON.stringify(e)}),refreshPluginTools:t=>i(`${o}/plugin-connections/${encodeURIComponent(t)}/tools/refresh`,{method:"POST"}),cancelRun:async t=>i(`${l}/runs/${encodeURIComponent(t)}/cancel`,{method:"POST"}),createAgentChat:async t=>i(n,{body:JSON.stringify({modelId:t?.modelId??null}),method:"POST"}),deleteAgentChat:async t=>i(`${n}/${encodeURIComponent(t)}`,{method:"DELETE"}),getAgentChatStreamUrl:(t,e)=>`${n}/${encodeURIComponent(t)}/stream?workflowRunId=${encodeURIComponent(e)}`,renameAgentChat:async(t,e)=>i(`${n}/${encodeURIComponent(t)}`,{body:JSON.stringify({title:e}),method:"PATCH"}),sendAgentChatMessage:async(t,e)=>i(`${n}/${encodeURIComponent(t)}/messages`,{body:JSON.stringify(e),method:"POST"}),announcePluginConnected:async(t,e)=>i(`${n}/${encodeURIComponent(t)}/plugin-connected`,{body:JSON.stringify({pluginId:e}),method:"POST"}),sendAgentChatFollowUp:async(t,e)=>i(`${n}/${encodeURIComponent(t)}/follow-ups`,{body:JSON.stringify(e),method:"POST"}),answerAgentChatQuestion:async(t,e,a)=>{let c=await fetch(`${n}/${encodeURIComponent(t)}/questions/${encodeURIComponent(e)}/answer`,{body:JSON.stringify(a),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST"}),r=await c.json();if(!c.ok&&!r.question)throw new Error(r.errorMessage??r.error??"Request failed");return {errorMessage:c.ok?void 0:r.errorMessage,question:r.question}},startAgentChat:async({attachments:t,content:e,modelId:a})=>i(n,{body:JSON.stringify({message:{attachments:t,content:e},modelId:a??null}),method:"POST"}),startQueuedAgentChatMessage:async(t,e)=>i(`${n}/${encodeURIComponent(t)}/follow-ups/${encodeURIComponent(e)}/start`,{method:"POST"}),stopAgentChat:async t=>i(`${n}/${encodeURIComponent(t)}/stop`,{method:"POST"}),stopAgentChatMonitor:async(t,e)=>i(`${n}/${encodeURIComponent(t)}/monitors/${encodeURIComponent(e)}/stop`,{method:"POST"}),transcribeAgentAudio:async(t,e)=>{let{durationSeconds:a,pcm:c}=await C(t),r=new FormData;r.append("file",c,"audio.pcm"),r.append("durationSeconds",String(a));let g=await fetch(`${o}/agent/transcribe`,{body:r,credentials:"include",method:"POST",signal:e}),m=await g.json();if(!g.ok){let S=m&&typeof m=="object"&&m.error?String(m.error):"Request failed";throw new Error(S)}if(!m.text?.trim())throw new Error("No speech was recognized. Try again.");return {text:m.text}},uploadAgentChatAttachment:async(t,e$1)=>{let[a,c]=await Promise.all([fetch(`${o}/agent/uploads`,{body:JSON.stringify({filename:t.name,mediaType:t.type||null,sizeBytes:t.size}),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST",signal:e$1}),e({name:t.name,size:t.size})===null?b(t):void 0]),r=await a.json();if(!a.ok||!r.pathname||!r.token||!r.mediaType)throw new d(a.status,r.error?String(r.error):"The file could not be uploaded.",r.code??null);let g=await put(r.pathname,t,{abortSignal:e$1,access:"public",contentType:r.mediaType,token:r.token});return {filename:t.name,mediaType:r.mediaType,sizeBytes:t.size,url:g.url,...c?{sha256:c}:{}}},decideApproval:async(t,e)=>{let a=await fetch(`${l}/approvals/${encodeURIComponent(t)}/decide`,{body:JSON.stringify(e),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST"}),c=await a.json();if(!a.ok&&typeof c.success!="boolean")throw new Error(c.error?String(c.error):"Request failed");return c},markActivityRead:async t=>i(`${o}/activity/read`,{body:JSON.stringify(t==="all"?{all:true}:{ids:t}),method:"POST"}),setActivityItemState:async(t,e)=>i(`${o}/activity/${encodeURIComponent(t)}`,{body:JSON.stringify({state:e}),method:"PATCH"}),createAutomation:async t=>i(l,{body:JSON.stringify(t),method:"POST"}),createSkill:async t=>i(u,{body:JSON.stringify(t),method:"POST"}),deleteAutomation:async t=>i(`${l}/${encodeURIComponent(t)}`,{method:"DELETE"}),deleteSkill:async t=>i(`${u}/${encodeURIComponent(t)}`,{method:"DELETE"}),getArtifactUrl:(t,e)=>{let a=e?.download?"?download=1":"";return `${l}/artifacts/${encodeURIComponent(t)}/content${a}`},getRunArtifacts:async t=>i(`${l}/runs/${encodeURIComponent(t)}/artifacts`).then(e=>e.artifacts),getStreamUrl:t=>`${l}/runs/${encodeURIComponent(t)}/stream`,getTranscriptUrl:t=>`${l}/runs/${encodeURIComponent(t)}/transcript`,listChannels:async(t,e)=>{let a=e?`${o}/plugin-connections/${encodeURIComponent(e)}/channels`:`${o}/plugins/${t}/channels`,c=await fetch(a,{credentials:"include",headers:{"Content-Type":"application/json"}}),r=await c.json();if(c.ok)return {channels:r.channels??[],errorMessage:r.errorMessage,success:r.success??true};if(r.success===false)return {channels:r.channels??[],errorMessage:r.errorMessage??`Failed to load ${t==="slack"?"Slack":"Teams"} channels.`,success:false};let g=r.error?String(r.error):"Request failed";throw new Error(g)},runAutomation:async t=>i(`${l}/${encodeURIComponent(t)}/runs`,{method:"POST"}),updateAutomation:async(t,e)=>i(`${l}/${encodeURIComponent(t)}`,{body:JSON.stringify(e),method:"PATCH"}),updateSkill:async(t,e)=>i(`${u}/${encodeURIComponent(t)}`,{body:JSON.stringify(e),method:"PATCH"})}}var p=class extends Error{status;constructor(o,l="Request failed"){super(l),this.name="FetcherError",this.status=o;}},D=async s=>{let o=await fetch(s,{credentials:"include"});if(!o.ok)throw new p(o.status);return await o.json()};function E(s){let o=`/api/flexkit/${s}/automations`,l=`/api/flexkit/${s}/skills`,u=`/api/flexkit/${s}/agent/chats`;return {activity:(n={})=>{let{filter:i="all",limit:t=25,offset:e=0}=n,a=new URLSearchParams({filter:i,limit:t.toString(),offset:e.toString()});return `/api/flexkit/${s}/activity?${a.toString()}`},activityItem:n=>`/api/flexkit/${s}/activity/${encodeURIComponent(n)}`,activitySummary:n=>n?`/api/flexkit/${s}/activity/summary?since=${encodeURIComponent(n)}`:`/api/flexkit/${s}/activity/summary`,agentChat:n=>`${u}/${encodeURIComponent(n)}`,agentChatSearch:n=>`${u}/search?q=${encodeURIComponent(n)}`,agentChats:(n=0)=>`${u}?offset=${n.toString()}`,agentProfile:()=>`/api/flexkit/${s}/agent/profile`,approval:n=>`${o}/approvals/${encodeURIComponent(n)}`,approvals:(n={})=>{let{limit:i=25,offset:t=0,runId:e,status:a}=n,c=new URLSearchParams({limit:i.toString(),offset:t.toString()});return a&&c.set("status",a),e&&c.set("runId",e),`${o}/approvals?${c.toString()}`},approvalsCount:`${o}/approvals?limit=1`,automation:n=>`${o}/${encodeURIComponent(n)}`,automationRuns:(n,i=0,t=25)=>`${o}/${encodeURIComponent(n)}/runs?offset=${i.toString()}&limit=${t.toString()}`,automations:(n={})=>{let{enabled:i,limit:t=25,offset:e=0,search:a,visibility:c}=n,r=new URLSearchParams({limit:t.toString(),offset:e.toString()});i&&i.length>0&&r.set("enabled",i.map(m=>m?"true":"false").join(",")),c&&c.length>0&&r.set("visibility",c.join(","));let g=a?.trim();return g&&r.set("q",g),`${o}?${r.toString()}`},creditBalance:`${o}/credits`,entities:`${o}/entities`,run:n=>`${o}/runs/${encodeURIComponent(n)}`,runHistory:(n,i=0,t=25)=>`${o}/runs?scope=${n}&offset=${i.toString()}&limit=${t.toString()}`,skill:n=>`${l}/${encodeURIComponent(n)}`,skills:(n={})=>{let{limit:i=25,offset:t=0,search:e,visibility:a}=n,c=new URLSearchParams({limit:i.toString(),offset:t.toString()});a&&a.length>0&&c.set("visibility",a.join(","));let r=e?.trim();return r&&c.set("q",r),`${l}?${c.toString()}`},spaces:`/api/flexkit/${s}/spaces`,members:n=>n?`/api/flexkit/${s}/members?spaceId=${encodeURIComponent(n)}`:`/api/flexkit/${s}/members`,tools:n=>n?`${o}/${encodeURIComponent(n)}/tools`:`${o}/tools`}}
2
- export{w as a,v as b,x as c,N as d,p as e,D as f,E as g};//# sourceMappingURL=chunk-MNLYE7DK.js.map
3
- //# sourceMappingURL=chunk-MNLYE7DK.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/ai/agent/dictation.ts","../src/apps/ai/api.ts"],"names":["appendDictatedText","existing","transcript","dictated","convertRecordedAudioToPcm","blob","AudioContextCtor","arrayBuffer","audioContext","audioBuffer","mono","mixToMono","resampled","resample","pcm","floatToPcm16","durationSeconds","buffer","length","channelCount","index","sum","channel","samples","sourceRate","targetRate","ratio","outputLength","output","sourceIndex","left","right","fraction","leftSample","rightSample","view","sample","sha256Hex","file","digest","byte","AgentUploadError","status","message","code","getApiRootDomain","getDesktop","flexkitDomain","hostname","getPlatformOrigin","getWebhookTriggerUrl","projectId","token","createApiClient","projectBasePath","automationsBasePath","skillsBasePath","agentChatsBasePath","request","url","init","response","data","error","input","id","runId","chatId","workflowRunId","title","pluginId","questionId","result","attachments","content","modelId","messageId","monitorId","audio","signal","formData","tokenResponse","sha256","getKnowledgeFileProblem","tokenData","put","approvalId","ids","itemId","state","automationId","skillId","artifactId","options","suffix","provider","connectionId","FetcherError","fetcher","paths","basePath","filter","limit","offset","params","since","query","enabled","search","visibility","value","trimmedSearch","scope","spaceId"],"mappings":"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","file":"chunk-MNLYE7DK.js","sourcesContent":["export const DICTATION_SAMPLE_RATE = 24_000;\nexport const DICTATION_MAX_DURATION_SECONDS = 60;\nexport const DICTATION_MIN_DURATION_SECONDS = 0.25;\n\nexport function appendDictatedText(existing: string, transcript: string): string {\n const dictated = transcript.trim();\n\n if (!dictated) {\n return existing;\n }\n\n if (!existing.trim()) {\n return existing.length === 0 ? dictated : `${existing}${dictated}`;\n }\n\n if (/\\s$/.test(existing) || /^[.,!?;:]/.test(dictated)) {\n return `${existing}${dictated}`;\n }\n\n return `${existing} ${dictated}`;\n}\n\nexport async function convertRecordedAudioToPcm(blob: Blob): Promise<{ durationSeconds: number; pcm: Blob }> {\n if (typeof window === 'undefined') {\n throw new Error('Dictation is only available in the browser.');\n }\n\n const AudioContextCtor = window.AudioContext ?? window.webkitAudioContext;\n\n if (!AudioContextCtor) {\n throw new Error('This browser cannot decode recorded audio.');\n }\n\n const arrayBuffer = await blob.arrayBuffer();\n const audioContext = new AudioContextCtor();\n\n try {\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer.slice(0));\n const mono = mixToMono(audioBuffer);\n const resampled = resample(mono, audioBuffer.sampleRate, DICTATION_SAMPLE_RATE);\n const pcm = floatToPcm16(resampled);\n const durationSeconds = resampled.length / DICTATION_SAMPLE_RATE;\n\n if (durationSeconds < DICTATION_MIN_DURATION_SECONDS) {\n throw new Error('No speech was captured. Try again.');\n }\n\n if (durationSeconds > DICTATION_MAX_DURATION_SECONDS) {\n throw new Error(`Dictation is limited to ${String(DICTATION_MAX_DURATION_SECONDS)} seconds.`);\n }\n\n return {\n durationSeconds,\n pcm: new Blob([pcm], { type: 'audio/pcm' }),\n };\n } finally {\n await audioContext.close();\n }\n}\n\nfunction mixToMono(buffer: AudioBuffer): Float32Array {\n const { length, numberOfChannels: channelCount } = buffer;\n\n if (channelCount === 1) {\n return buffer.getChannelData(0).slice();\n }\n\n const mono = new Float32Array(length);\n\n for (let index = 0; index < length; index += 1) {\n let sum = 0;\n\n for (let channel = 0; channel < channelCount; channel += 1) {\n sum += buffer.getChannelData(channel)[index] ?? 0;\n }\n\n mono[index] = sum / channelCount;\n }\n\n return mono;\n}\n\nfunction resample(samples: Float32Array, sourceRate: number, targetRate: number): Float32Array {\n if (sourceRate === targetRate) {\n return samples;\n }\n\n const ratio = sourceRate / targetRate;\n const outputLength = Math.max(1, Math.round(samples.length / ratio));\n const output = new Float32Array(outputLength);\n\n for (let index = 0; index < outputLength; index += 1) {\n const sourceIndex = index * ratio;\n const left = Math.floor(sourceIndex);\n const right = Math.min(left + 1, samples.length - 1);\n const fraction = sourceIndex - left;\n const leftSample = samples[left] ?? 0;\n const rightSample = samples[right] ?? 0;\n output[index] = leftSample + (rightSample - leftSample) * fraction;\n }\n\n return output;\n}\n\nfunction floatToPcm16(samples: Float32Array): ArrayBuffer {\n const buffer = new ArrayBuffer(samples.length * 2);\n const view = new DataView(buffer);\n\n for (let index = 0; index < samples.length; index += 1) {\n const sample = Math.max(-1, Math.min(1, samples[index] ?? 0));\n view.setInt16(index * 2, sample < 0 ? sample * 0x8000 : sample * 0x7fff, true);\n }\n\n return buffer;\n}\n\ndeclare global {\n interface Window {\n webkitAudioContext?: typeof AudioContext;\n }\n}\n","import { getKnowledgeFileProblem } from '../knowledge/knowledge';\nimport type { PluginConnection, PluginScope, PluginTools } from './plugin-types';\nimport { put } from '@vercel/blob/client';\nimport { convertRecordedAudioToPcm } from './agent/dictation';\nimport { getDesktop } from '../../core/desktop';\nimport { flexkitDomain } from '../../core/domains';\nimport type {\n ActivityItem,\n ActivityItemState,\n AgentChat,\n AgentChatAttachment,\n AgentChatFollowUpResult,\n AgentChatMessage,\n AgentChatMonitor,\n AgentChatQuestion,\n AgentChatQuestionResponse,\n AgentChatTurn,\n Automation,\n AutomationApproval,\n AutomationApprovalStatus,\n AutomationArtifact,\n AutomationInput,\n AutomationToolChannel,\n AutomationToolProvider,\n AutomationVisibility,\n MutationResult,\n Skill,\n SkillInput,\n} from './types';\n\nexport interface DecideApprovalInput {\n /** Approve and always allow this plugin tool for the automation. */\n remember?: boolean;\n approved: boolean;\n /** For a proposed automation: the approver's edited instructions and whether to run it once now. */\n automationEdits?: { instructions?: string; runOnce?: boolean };\n force?: boolean;\n reason?: string;\n}\n\nexport interface SendAgentChatMessageInput {\n attachments?: AgentChatAttachment[];\n content: string;\n modelId?: string | null;\n}\n\n/** A new chat and its first turn, started by one request. */\nexport interface StartAgentChatResult {\n chat: AgentChat;\n turn: AgentChatTurn;\n}\n\n/** Lowercase hex SHA-256 of a file, or undefined where the browser cannot hash (insecure contexts). */\nasync function sha256Hex(file: File): Promise<string | undefined> {\n if (typeof crypto === 'undefined' || !crypto.subtle) {\n return undefined;\n }\n\n try {\n const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');\n } catch {\n return undefined;\n }\n}\n\n/** Thrown when the API refuses an upload; `code` lets the UI tailor the message. */\nexport class AgentUploadError extends Error {\n code: string | null;\n status: number;\n\n constructor(status: number, message: string, code: string | null = null) {\n super(message);\n this.name = 'AgentUploadError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport interface ApiClient {\n /** Starts OAuth for a new account, or for `connectionId` to reconnect that specific account. */\n connectPlugins: (_input: {\n pluginId: string;\n scope: PluginScope;\n studioOrigin: string;\n connectionId?: string;\n }) => Promise<{ transactionId: string; authorizeUrl: string; completionOrigin: string; launchTicket: string }>;\n /** Connects a token plugin with a pasted token, or replaces the token of `connectionId`. */\n connectPluginToken: (_input: {\n pluginId: string;\n scope: PluginScope;\n token: string;\n connectionId?: string;\n }) => Promise<{ connection: PluginConnection }>;\n /** Renames (label null resets to the provider name) or makes a connection primary. */\n updatePluginConnection: (\n _id: string,\n _input: { label?: string | null; primary?: true }\n ) => Promise<{ connection: PluginConnection }>;\n pluginOAuthStatus: (\n _id: string\n ) => Promise<{ id: string; status: 'pending' | 'exchanging' | 'complete' | 'failed'; expires_at: string }>;\n disconnectPlugin: (_id: string) => Promise<{ success: boolean }>;\n installPlugin: (_id: string) => Promise<unknown>;\n setPluginPolicy: (_id: string, _input: { enabled: boolean; allowPersonal: boolean }) => Promise<{ success: boolean }>;\n refreshPluginTools: (_id: string) => Promise<PluginTools>;\n\n cancelRun: (_runId: string) => Promise<MutationResult>;\n createAgentChat: (_input?: { modelId?: string | null }) => Promise<{ chat: AgentChat }>;\n deleteAgentChat: (_chatId: string) => Promise<{ success: boolean }>;\n getAgentChatStreamUrl: (_chatId: string, _workflowRunId: string) => string;\n renameAgentChat: (_chatId: string, _title: string) => Promise<{ chat: AgentChat }>;\n sendAgentChatMessage: (_chatId: string, _input: SendAgentChatMessageInput) => Promise<AgentChatTurn>;\n /**\n * Sends a message while the chat's turn is running. The platform decides\n * whether it steers that turn or waits as the next one; if the turn has\n * meanwhile ended, the message starts the next turn.\n */\n sendAgentChatFollowUp: (_chatId: string, _input: SendAgentChatMessageInput) => Promise<AgentChatFollowUpResult>;\n /** The user connected a plugin from the chat's connect card: starts the turn that uses it, or queues it. */\n announcePluginConnected: (\n _chatId: string,\n _pluginId: string\n ) => Promise<Extract<AgentChatFollowUpResult, { followUp: unknown } | { turn: unknown }>>;\n /** Answers (or dismisses) the questions a chat turn waits on; a settled question comes back with an error. */\n answerAgentChatQuestion: (\n _chatId: string,\n _questionId: string,\n _response: AgentChatQuestionResponse\n ) => Promise<{ errorMessage?: string; question?: AgentChatQuestion }>;\n /** Creates a chat and sends its first message in one request. */\n startAgentChat: (_input: SendAgentChatMessageInput) => Promise<StartAgentChatResult>;\n /** Starts the next turn from a queued follow-up once the previous turn has ended. */\n startQueuedAgentChatMessage: (_chatId: string, _messageId: string) => Promise<AgentChatTurn>;\n stopAgentChat: (_chatId: string) => Promise<{ message: AgentChatMessage }>;\n stopAgentChatMonitor: (_chatId: string, _monitorId: string) => Promise<{ monitor: AgentChatMonitor }>;\n transcribeAgentAudio: (_audio: Blob, _signal?: AbortSignal) => Promise<{ text: string }>;\n /** Uploads a chat attachment straight to the platform file store. */\n uploadAgentChatAttachment: (_file: File, _signal?: AbortSignal) => Promise<AgentChatAttachment>;\n decideApproval: (\n _approvalId: string,\n _input: DecideApprovalInput\n ) => Promise<MutationResult & { approval?: AutomationApproval }>;\n createAutomation: (_input: AutomationInput) => Promise<MutationResult & { automation?: Automation }>;\n createSkill: (_input: SkillInput) => Promise<MutationResult & { skill?: Skill }>;\n deleteAutomation: (_automationId: string) => Promise<MutationResult>;\n deleteSkill: (_skillId: string) => Promise<MutationResult>;\n getArtifactUrl: (_artifactId: string, _options?: { download?: boolean }) => string;\n getRunArtifacts: (_workflowRunId: string) => Promise<AutomationArtifact[]>;\n getStreamUrl: (_workflowRunId: string) => string;\n /** JSON transcript of a finished run (owners and developers). */\n getTranscriptUrl: (_runId: string) => string;\n /** Lists delivery channels of `connectionId`, or of the provider's primary project account when omitted. */\n listChannels: (\n _provider: AutomationToolProvider,\n _connectionId?: string | null\n ) => Promise<{\n channels: AutomationToolChannel[];\n errorMessage?: string;\n success: boolean;\n }>;\n runAutomation: (_automationId: string) => Promise<MutationResult & { runId?: string }>;\n updateAutomation: (\n _automationId: string,\n _input: AutomationInput\n ) => Promise<MutationResult & { automation?: Automation }>;\n updateSkill: (_skillId: string, _input: SkillInput) => Promise<MutationResult & { skill?: Skill }>;\n /** Marks the caller's Activity items read; `'all'` marks every unread item. */\n markActivityRead: (_ids: string[] | 'all') => Promise<{ success: boolean }>;\n setActivityItemState: (\n _itemId: string,\n _state: Extract<ActivityItemState, 'unread' | 'read' | 'dismissed'>\n ) => Promise<{ item: ActivityItem }>;\n}\n\nfunction getApiRootDomain(): string {\n if (typeof window === 'undefined') {\n return 'flexkit.io';\n }\n\n // The desktop app serves the Studio on its own scheme (`flexkit://app`), so\n // its page hostname says nothing; the backend it was built for does.\n if (getDesktop()) {\n return flexkitDomain;\n }\n\n const { hostname } = window.location;\n const isDevHost =\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname === 'flexkit.test' ||\n hostname.endsWith('.flexkit.test');\n\n return isDevHost ? 'flexkit.test' : 'flexkit.io';\n}\n\n/** Origin that hosts plugin OAuth start and completion. */\nexport function getPlatformOrigin(): string {\n return `https://${getApiRootDomain()}`;\n}\n\n/** Public URL an external system calls to fire a webhook trigger. */\nexport function getWebhookTriggerUrl(projectId: string, token: string): string {\n return `https://${projectId}.api.${getApiRootDomain()}/automations/webhook/${encodeURIComponent(token)}`;\n}\n\nexport function createApiClient(projectId: string): ApiClient {\n const projectBasePath = `/api/flexkit/${projectId}`;\n const automationsBasePath = `${projectBasePath}/automations`;\n const skillsBasePath = `${projectBasePath}/skills`;\n const agentChatsBasePath = `${projectBasePath}/agent/chats`;\n\n async function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n ...init,\n });\n const data = (await response.json()) as T;\n\n if (!response.ok) {\n const error = data && typeof data === 'object' && 'error' in data ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n }\n\n return data;\n }\n\n return {\n connectPlugins: (input) =>\n request(`${projectBasePath}/plugins/connect`, { method: 'POST', body: JSON.stringify(input) }),\n connectPluginToken: (input) =>\n request(`${projectBasePath}/plugins/connect-token`, { method: 'POST', body: JSON.stringify(input) }),\n pluginOAuthStatus: (id) => request(`${projectBasePath}/plugins/oauth-transactions/${encodeURIComponent(id)}`),\n updatePluginConnection: (id, input) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n }),\n disconnectPlugin: (id) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}`, { method: 'DELETE' }),\n installPlugin: (id) =>\n request(`${projectBasePath}/plugins/${encodeURIComponent(id)}/installation`, {\n method: 'PUT',\n body: JSON.stringify({}),\n }),\n setPluginPolicy: (id, input) =>\n request(`${projectBasePath}/plugins/${encodeURIComponent(id)}/policy`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n }),\n refreshPluginTools: (id) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}/tools/refresh`, { method: 'POST' }),\n cancelRun: async (runId) =>\n request<MutationResult>(`${automationsBasePath}/runs/${encodeURIComponent(runId)}/cancel`, { method: 'POST' }),\n createAgentChat: async (input) =>\n request<{ chat: AgentChat }>(agentChatsBasePath, {\n body: JSON.stringify({ modelId: input?.modelId ?? null }),\n method: 'POST',\n }),\n deleteAgentChat: async (chatId) =>\n request<{ success: boolean }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}`, { method: 'DELETE' }),\n getAgentChatStreamUrl: (chatId, workflowRunId) =>\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/stream?workflowRunId=${encodeURIComponent(workflowRunId)}`,\n renameAgentChat: async (chatId, title) =>\n request<{ chat: AgentChat }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}`, {\n body: JSON.stringify({ title }),\n method: 'PATCH',\n }),\n sendAgentChatMessage: async (chatId, input) =>\n request<AgentChatTurn>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/messages`, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n announcePluginConnected: async (chatId, pluginId) =>\n request(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/plugin-connected`, {\n body: JSON.stringify({ pluginId }),\n method: 'POST',\n }),\n sendAgentChatFollowUp: async (chatId, input) =>\n request<AgentChatFollowUpResult>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/follow-ups`, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n answerAgentChatQuestion: async (chatId, questionId, response) => {\n const result = await fetch(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/questions/${encodeURIComponent(questionId)}/answer`,\n {\n body: JSON.stringify(response),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n }\n );\n const data = (await result.json()) as { errorMessage?: string; error?: string; question?: AgentChatQuestion };\n\n // A question settled elsewhere (409) comes back with its final state for the card to show.\n if (!result.ok && !data.question) {\n throw new Error(data.errorMessage ?? data.error ?? 'Request failed');\n }\n\n return { errorMessage: result.ok ? undefined : data.errorMessage, question: data.question };\n },\n startAgentChat: async ({ attachments, content, modelId }) =>\n request<StartAgentChatResult>(agentChatsBasePath, {\n body: JSON.stringify({ message: { attachments, content }, modelId: modelId ?? null }),\n method: 'POST',\n }),\n startQueuedAgentChatMessage: async (chatId, messageId) =>\n request<AgentChatTurn>(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/follow-ups/${encodeURIComponent(messageId)}/start`,\n { method: 'POST' }\n ),\n stopAgentChat: async (chatId) =>\n request<{ message: AgentChatMessage }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/stop`, {\n method: 'POST',\n }),\n stopAgentChatMonitor: async (chatId, monitorId) =>\n request<{ monitor: AgentChatMonitor }>(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/monitors/${encodeURIComponent(monitorId)}/stop`,\n { method: 'POST' }\n ),\n transcribeAgentAudio: async (audio, signal) => {\n const { durationSeconds, pcm } = await convertRecordedAudioToPcm(audio);\n const formData = new FormData();\n formData.append('file', pcm, 'audio.pcm');\n formData.append('durationSeconds', String(durationSeconds));\n\n const response = await fetch(`${projectBasePath}/agent/transcribe`, {\n body: formData,\n credentials: 'include',\n method: 'POST',\n signal,\n });\n const data = (await response.json()) as { error?: string; text?: string };\n\n if (!response.ok) {\n const error = data && typeof data === 'object' && data.error ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n }\n\n if (!data.text?.trim()) {\n throw new Error('No speech was recognized. Try again.');\n }\n\n return { text: data.text };\n },\n uploadAgentChatAttachment: async (file, signal) => {\n // The platform issues a token scoped to one pathname, type and size; the\n // browser then writes the bytes to the store directly, so large files\n // never pass through the API function body limit. The hash is computed\n // alongside: Knowledge documents are keyed by it, so the platform can tell\n // later whether this file is already one.\n const [tokenResponse, sha256] = await Promise.all([\n fetch(`${projectBasePath}/agent/uploads`, {\n body: JSON.stringify({ filename: file.name, mediaType: file.type || null, sizeBytes: file.size }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal,\n }),\n // Only files Knowledge can index are worth hashing; a screenshot never matches a document.\n getKnowledgeFileProblem({ name: file.name, size: file.size }) === null ? sha256Hex(file) : undefined,\n ]);\n const tokenData = (await tokenResponse.json()) as {\n code?: string;\n error?: string;\n mediaType?: string;\n pathname?: string;\n token?: string;\n };\n\n if (!tokenResponse.ok || !tokenData.pathname || !tokenData.token || !tokenData.mediaType) {\n throw new AgentUploadError(\n tokenResponse.status,\n tokenData.error ? String(tokenData.error) : 'The file could not be uploaded.',\n tokenData.code ?? null\n );\n }\n\n const blob = await put(tokenData.pathname, file, {\n abortSignal: signal,\n access: 'public',\n contentType: tokenData.mediaType,\n token: tokenData.token,\n });\n\n return {\n filename: file.name,\n mediaType: tokenData.mediaType,\n sizeBytes: file.size,\n url: blob.url,\n ...(sha256 ? { sha256 } : {}),\n };\n },\n decideApproval: async (approvalId, input) => {\n const response = await fetch(`${automationsBasePath}/approvals/${encodeURIComponent(approvalId)}/decide`, {\n body: JSON.stringify(input),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n });\n const data = (await response.json()) as MutationResult & { approval?: AutomationApproval; error?: string };\n\n // Business errors (stale_preview, already_decided) come back as 400\n // with a structured body the caller must be able to inspect.\n if (!response.ok && typeof data.success !== 'boolean') {\n throw new Error(data.error ? String(data.error) : 'Request failed');\n }\n\n return data;\n },\n markActivityRead: async (ids) =>\n request<{ success: boolean }>(`${projectBasePath}/activity/read`, {\n body: JSON.stringify(ids === 'all' ? { all: true } : { ids }),\n method: 'POST',\n }),\n setActivityItemState: async (itemId, state) =>\n request<{ item: ActivityItem }>(`${projectBasePath}/activity/${encodeURIComponent(itemId)}`, {\n body: JSON.stringify({ state }),\n method: 'PATCH',\n }),\n createAutomation: async (input) =>\n request<MutationResult & { automation?: Automation }>(automationsBasePath, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n createSkill: async (input) =>\n request<MutationResult & { skill?: Skill }>(skillsBasePath, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n deleteAutomation: async (automationId) =>\n request<MutationResult>(`${automationsBasePath}/${encodeURIComponent(automationId)}`, { method: 'DELETE' }),\n deleteSkill: async (skillId) =>\n request<MutationResult>(`${skillsBasePath}/${encodeURIComponent(skillId)}`, { method: 'DELETE' }),\n getArtifactUrl: (artifactId, options) => {\n const suffix = options?.download ? '?download=1' : '';\n\n return `${automationsBasePath}/artifacts/${encodeURIComponent(artifactId)}/content${suffix}`;\n },\n getRunArtifacts: async (workflowRunId) =>\n request<{ artifacts: AutomationArtifact[] }>(\n `${automationsBasePath}/runs/${encodeURIComponent(workflowRunId)}/artifacts`\n ).then((response) => response.artifacts),\n getStreamUrl: (workflowRunId) => `${automationsBasePath}/runs/${encodeURIComponent(workflowRunId)}/stream`,\n getTranscriptUrl: (runId) => `${automationsBasePath}/runs/${encodeURIComponent(runId)}/transcript`,\n listChannels: async (provider, connectionId) => {\n const url = connectionId\n ? `${projectBasePath}/plugin-connections/${encodeURIComponent(connectionId)}/channels`\n : `${projectBasePath}/plugins/${provider}/channels`;\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n const data = (await response.json()) as {\n channels?: AutomationToolChannel[];\n error?: string;\n errorMessage?: string;\n success?: boolean;\n };\n\n if (response.ok) {\n return {\n channels: data.channels ?? [],\n errorMessage: data.errorMessage,\n success: data.success ?? true,\n };\n }\n\n if (data.success === false) {\n return {\n channels: data.channels ?? [],\n errorMessage: data.errorMessage ?? `Failed to load ${provider === 'slack' ? 'Slack' : 'Teams'} channels.`,\n success: false,\n };\n }\n\n const error = data.error ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n },\n runAutomation: async (automationId) =>\n request<MutationResult & { runId?: string }>(`${automationsBasePath}/${encodeURIComponent(automationId)}/runs`, {\n method: 'POST',\n }),\n updateAutomation: async (automationId, input) =>\n request<MutationResult & { automation?: Automation }>(\n `${automationsBasePath}/${encodeURIComponent(automationId)}`,\n {\n body: JSON.stringify(input),\n method: 'PATCH',\n }\n ),\n updateSkill: async (skillId, input) =>\n request<MutationResult & { skill?: Skill }>(`${skillsBasePath}/${encodeURIComponent(skillId)}`, {\n body: JSON.stringify(input),\n method: 'PATCH',\n }),\n };\n}\n\nexport class FetcherError extends Error {\n status: number;\n\n constructor(status: number, message = 'Request failed') {\n super(message);\n this.name = 'FetcherError';\n this.status = status;\n }\n}\n\nexport const fetcher = async <T>(url: string): Promise<T> => {\n const response = await fetch(url, { credentials: 'include' });\n\n if (!response.ok) {\n throw new FetcherError(response.status);\n }\n\n return (await response.json()) as T;\n};\n\nexport function paths(projectId: string): {\n activity: (_options?: { filter?: 'all' | 'needs_action'; limit?: number; offset?: number }) => string;\n activityItem: (_itemId: string) => string;\n /** Badge counts; with `since`, also the unread items created after it. */\n activitySummary: (_since?: string | null) => string;\n agentChat: (_chatId: string) => string;\n agentChatSearch: (_query: string) => string;\n agentChats: (_offset?: number) => string;\n agentProfile: () => string;\n approval: (_approvalId: string) => string;\n approvals: (_options?: {\n limit?: number;\n offset?: number;\n runId?: string;\n status?: AutomationApprovalStatus;\n }) => string;\n approvalsCount: string;\n automation: (_automationId: string) => string;\n automationRuns: (_automationId: string, _offset?: number, _limit?: number) => string;\n automations: (_options?: {\n enabled?: boolean[];\n limit?: number;\n offset?: number;\n search?: string;\n visibility?: AutomationVisibility[];\n }) => string;\n creditBalance: string;\n entities: string;\n run: (_runId: string) => string;\n runHistory: (_scope: 'mine' | 'team', _offset?: number, _limit?: number) => string;\n skill: (_skillId: string) => string;\n skills: (_options?: {\n limit?: number;\n offset?: number;\n search?: string;\n visibility?: AutomationVisibility[];\n }) => string;\n spaces: string;\n /** Members for pickers; with a space id, only members who can see that space. */\n members: (_spaceId?: string | null) => string;\n tools: (_automationId?: string) => string;\n} {\n const basePath = `/api/flexkit/${projectId}/automations`;\n const skillsBasePath = `/api/flexkit/${projectId}/skills`;\n const agentChatsBasePath = `/api/flexkit/${projectId}/agent/chats`;\n\n return {\n activity: (options = {}) => {\n const { filter = 'all', limit = 25, offset = 0 } = options;\n const params = new URLSearchParams({ filter, limit: limit.toString(), offset: offset.toString() });\n\n return `/api/flexkit/${projectId}/activity?${params.toString()}`;\n },\n activityItem: (itemId) => `/api/flexkit/${projectId}/activity/${encodeURIComponent(itemId)}`,\n activitySummary: (since) =>\n since\n ? `/api/flexkit/${projectId}/activity/summary?since=${encodeURIComponent(since)}`\n : `/api/flexkit/${projectId}/activity/summary`,\n agentChat: (chatId) => `${agentChatsBasePath}/${encodeURIComponent(chatId)}`,\n agentChatSearch: (query) => `${agentChatsBasePath}/search?q=${encodeURIComponent(query)}`,\n agentChats: (offset = 0) => `${agentChatsBasePath}?offset=${offset.toString()}`,\n agentProfile: () => `/api/flexkit/${projectId}/agent/profile`,\n approval: (approvalId) => `${basePath}/approvals/${encodeURIComponent(approvalId)}`,\n approvals: (options = {}) => {\n const { limit = 25, offset = 0, runId, status } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (status) {\n params.set('status', status);\n }\n\n if (runId) {\n params.set('runId', runId);\n }\n\n return `${basePath}/approvals?${params.toString()}`;\n },\n approvalsCount: `${basePath}/approvals?limit=1`,\n automation: (automationId) => `${basePath}/${encodeURIComponent(automationId)}`,\n automationRuns: (automationId, offset = 0, limit = 25) =>\n `${basePath}/${encodeURIComponent(automationId)}/runs?offset=${offset.toString()}&limit=${limit.toString()}`,\n automations: (options = {}) => {\n const { enabled, limit = 25, offset = 0, search, visibility } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (enabled && enabled.length > 0) {\n params.set('enabled', enabled.map((value) => (value ? 'true' : 'false')).join(','));\n }\n\n if (visibility && visibility.length > 0) {\n params.set('visibility', visibility.join(','));\n }\n\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n return `${basePath}?${params.toString()}`;\n },\n creditBalance: `${basePath}/credits`,\n entities: `${basePath}/entities`,\n run: (runId) => `${basePath}/runs/${encodeURIComponent(runId)}`,\n runHistory: (scope, offset = 0, limit = 25) =>\n `${basePath}/runs?scope=${scope}&offset=${offset.toString()}&limit=${limit.toString()}`,\n skill: (skillId) => `${skillsBasePath}/${encodeURIComponent(skillId)}`,\n skills: (options = {}) => {\n const { limit = 25, offset = 0, search, visibility } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (visibility && visibility.length > 0) {\n params.set('visibility', visibility.join(','));\n }\n\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n return `${skillsBasePath}?${params.toString()}`;\n },\n spaces: `/api/flexkit/${projectId}/spaces`,\n members: (spaceId) =>\n spaceId\n ? `/api/flexkit/${projectId}/members?spaceId=${encodeURIComponent(spaceId)}`\n : `/api/flexkit/${projectId}/members`,\n tools: (automationId) =>\n automationId ? `${basePath}/${encodeURIComponent(automationId)}/tools` : `${basePath}/tools`,\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- import'./index.css';import {b as b$1}from'./chunk-MNLYE7DK.js';import {s}from'./chunk-DGIY4SKN.js';import {c,h,i,k,l,j as j$1}from'./chunk-32ZU4MLE.js';import {b}from'./chunk-6NRQMG26.js';import {useSyncExternalStore,useId,useState}from'react';import {ExternalLinkIcon,LoaderCircle}from'lucide-react';import {jsx,jsxs}from'react/jsx-runtime';var $="/plugins/oauth/start",P=class extends Error{code="account_mismatch";constructor(){super('You signed in with a different account. Use "Connect another account" to add it.'),this.name="PluginAccountMismatchError";}};function O(e){let t;try{t=new URL(e);}catch{return null}return t.protocol!=="https:"||t.username!==""||t.password!==""?null:t}function M(e,t){let r=b$1(),i=O(e),n=O(t);return !i||!n||i.origin!==r||i.pathname!==$||n.origin!==r||n.pathname!=="/"?null:{href:i.href,origin:r}}async function _(e,t,r,i){let n=window.open("about:blank",`flexkit-plugin-${crypto.randomUUID()}`,"popup,width=560,height=720");if(!n)throw new Error("Allow popups for Studio, then connect again.");let o;try{o=await e.connectPlugins({pluginId:t,scope:r,studioOrigin:window.location.origin,...i?.connectionId?{connectionId:i.connectionId}:{}});}catch(l){throw n.close(),l}let s=M(o.authorizeUrl,o.completionOrigin);if(!s)throw n.close(),new Error("Connection could not be started.");let u=s.origin;await new Promise((l,w)=>{let g=false,k=false,c=false,f=a=>{if(!k){if(k=true,window.clearInterval(N),window.clearTimeout(z),window.removeEventListener("message",I),n.close(),a){w(a);return}l();}},h=async()=>{if(g||k)return;g=true;let a;try{a=await e.pluginOAuthStatus(o.transactionId);}catch{g=false;return}if(g=false,a.status==="complete"){f();return}if(!c&&n.closed&&a.status==="pending"){f(new Error("Connection window was closed."));return}(a.status==="failed"||new Date(a.expires_at).getTime()<Date.now())&&f(new Error("Connection was not completed. Please try again."));},I=a=>{if(a.origin!==u||a.source!==n||!a.data||typeof a.data!="object")return;let m=a.data;if(m.type==="flexkit:plugin-oauth-ready"&&m.transactionId===o.transactionId){c=true,n.postMessage({type:"flexkit:plugin-oauth-start",transactionId:o.transactionId,ticket:o.launchTicket},u);return}if(m.type==="flexkit:plugin-oauth"&&m.transactionId===o.transactionId){if(m.status==="failed"&&m.error==="account_mismatch"){f(new P);return}h();}},N=window.setInterval(()=>{h();},2e3),z=window.setTimeout(()=>f(new Error("Connection timed out. Please try again.")),6e5);window.addEventListener("message",I),n.location.href=s.href;});}function H(e,t){if(!t)return true;try{return new RegExp(t,"u").test(e)}catch{return true}}function B(e){if(!e)return null;try{return new RegExp(e,"u")}catch{return null}}function Z(e,t){let r=e.split(/[\s"'`()<>[\]{},;:=!?&]+/).map(o=>o.replace(/\.+$/,"")).filter(Boolean),i=null,n=new Set;for(let o of t){let s=B(o.connect?.type==="api-token"?o.connect.pattern:null);for(let u of s?r:[])s.test(u)&&(i??=o,n.add(u));}return i?{plugin:i,tokens:[...n]}:null}var T=null,v=0,C=null,x=new Set;function F(e){T=e,x.forEach(t=>t());}function j(e){return x.add(e),()=>x.delete(e)}function le(e,t,r,i){let{connect:n}=t;if(n?.type!=="api-token")return _(e,t.id,r,i).then(()=>true);C?.();let o=++v;return new Promise(s=>{let u={id:o,plugin:{...t,connect:n},submit:async l=>{await e.connectPluginToken({pluginId:t.id,scope:r,token:l,...i?.connectionId?{connectionId:i.connectionId}:{}});},settle:l=>{T?.id===o&&F(null),v===o&&(C=null),s(l);}};C=()=>u.settle(false),setTimeout(()=>{v===o&&F(u);});})}function K(e){if(!e)return null;try{let t=new URL(e);return t.protocol==="https:"?t.href:null}catch{return null}}function ae(){let e=useSyncExternalStore(j,()=>T,()=>null);return e?jsx(Q,{request:e},e.id):null}function Q({request:e}){let{connect:t,name:r}=e.plugin,i$1=useId(),[n,o]=useState(""),[s$1,u]=useState(null),[l$1,w]=useState(false),g=K(t.helpUrl);async function k$1(c){c.preventDefault();let f=n.trim();if(!(l$1||!f)){if(!H(f,t.pattern)){u(`That does not look like a ${t.tokenLabel}.`);return}w(true),u(null);try{await e.submit(f),o(""),e.settle(!0);}catch(h){u(h instanceof Error?h.message:`${r} could not be connected.`);}finally{w(false);}}}return jsx(c,{open:true,onOpenChange:c=>{!c&&!l$1&&e.settle(false);},children:jsx(h,{children:jsxs("form",{className:"fk:flex fk:flex-col fk:gap-4",onSubmit:c=>{k$1(c);},children:[jsxs(i,{children:[jsxs(k,{children:["Connect ",r]}),jsxs(l,{children:["Paste a ",t.tokenLabel,". Flexkit stores it encrypted and sends it only to ",r,"; the agent can use"," ",r,"'s tools but never sees the token. Give it read access only, unless the agent should change things in ",r,"."]})]}),jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx("label",{className:"fk:text-sm fk:font-medium",htmlFor:i$1,children:t.tokenLabel}),jsx(s,{"aria-describedby":s$1?`${i$1}-error`:void 0,"aria-invalid":s$1?true:void 0,autoComplete:"off",autoFocus:true,disabled:l$1,id:i$1,placeholder:t.placeholder??void 0,spellCheck:false,type:"password",value:n,onChange:c=>{o(c.target.value),u(null);}}),s$1?jsx("p",{className:"fk:text-sm fk:text-destructive",id:`${i$1}-error`,children:s$1}):null,g?jsxs("a",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline",href:g,rel:"noreferrer",target:"_blank",children:["How to create a ",t.tokenLabel,jsx(ExternalLinkIcon,{className:"fk:size-3.5"})]}):null]}),jsxs(j$1,{children:[jsx(b,{disabled:l$1,size:"sm",type:"button",variant:"outline",onClick:()=>e.settle(false),children:"Cancel"}),jsxs(b,{disabled:l$1||!n.trim(),size:"sm",type:"submit",children:[l$1?jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}):null,"Connect"]})]})]})})})}export{P as a,_ as b,Z as c,le as d,ae as e};//# sourceMappingURL=chunk-U6E7GNQW.js.map
2
- //# sourceMappingURL=chunk-U6E7GNQW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/ai/plugin-oauth.ts","../src/apps/ai/plugin-token-format.ts","../src/apps/ai/plugin-token.tsx"],"names":["OAUTH_START_PATH","PluginAccountMismatchError","httpsUrl","value","url","trustedPluginOAuthTargets","authorizeUrl","completionOrigin","origin","getPlatformOrigin","authorize","completion","connectPluginPopup","api","pluginId","scope","options","popup","transaction","error","targets","expectedOrigin","resolve","reject","polling","finished","handedOff","finish","interval","timeout","onMessage","poll","status","event","payload","matchesTokenPattern","token","pattern","compileTokenPattern","findPastedPluginToken","text","plugins","words","word","found","tokens","plugin","request","lastRequestId","cancelLatest","listeners","setRequest","next","listener","subscribe","connectPlugin","connect","id","connected","httpsHref","PluginTokenDialogHost","current","useSyncExternalStore","jsx","PluginTokenDialog","name","inputId","useId","setToken","useState","setError","saving","setSaving","helpHref","save","failure","Dialog","open","DialogContent","jsxs","DialogHeader","DialogTitle","DialogDescription","Input","ExternalLinkIcon","DialogFooter","Button","LoaderCircle"],"mappings":"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","file":"chunk-U6E7GNQW.js","sourcesContent":["import { getPlatformOrigin, type ApiClient } from './api';\nimport type { PluginScope } from './plugin-types';\n\nconst OAUTH_START_PATH = '/plugins/oauth/start';\n\n/** A Reconnect was completed with a different provider account than the one being reconnected. */\nexport class PluginAccountMismatchError extends Error {\n readonly code = 'account_mismatch';\n\n constructor() {\n super('You signed in with a different account. Use \"Connect another account\" to add it.');\n this.name = 'PluginAccountMismatchError';\n }\n}\n\nfunction httpsUrl(value: string): URL | null {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== 'https:' || url.username !== '' || url.password !== '') {\n return null;\n }\n\n return url;\n}\n\n/** Popup navigation and postMessage stay on the platform OAuth start page. */\nfunction trustedPluginOAuthTargets(\n authorizeUrl: string,\n completionOrigin: string\n): { href: string; origin: string } | null {\n const origin = getPlatformOrigin();\n const authorize = httpsUrl(authorizeUrl);\n const completion = httpsUrl(completionOrigin);\n\n if (!authorize || !completion) {\n return null;\n }\n\n if (authorize.origin !== origin || authorize.pathname !== OAUTH_START_PATH) {\n return null;\n }\n\n if (completion.origin !== origin || completion.pathname !== '/') {\n return null;\n }\n\n return { href: authorize.href, origin };\n}\n\n/** Must be called directly from the click handler so browsers allow the popup. */\nexport async function connectPluginPopup(\n api: ApiClient,\n pluginId: string,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<void> {\n const popup = window.open('about:blank', `flexkit-plugin-${crypto.randomUUID()}`, 'popup,width=560,height=720');\n\n if (!popup) {\n throw new Error('Allow popups for Studio, then connect again.');\n }\n\n let transaction: Awaited<ReturnType<ApiClient['connectPlugins']>>;\n\n try {\n transaction = await api.connectPlugins({\n pluginId,\n scope,\n studioOrigin: window.location.origin,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n } catch (error) {\n popup.close();\n throw error;\n }\n\n const targets = trustedPluginOAuthTargets(transaction.authorizeUrl, transaction.completionOrigin);\n\n if (!targets) {\n popup.close();\n throw new Error('Connection could not be started.');\n }\n\n const expectedOrigin = targets.origin;\n\n await new Promise<void>((resolve, reject) => {\n let polling = false;\n let finished = false;\n // Once the popup leaves for the provider, `popup.closed` says nothing:\n // providers isolate their pages (Cross-Origin-Opener-Policy), which severs\n // the opener and reports the window as closed while it is open. From then\n // on only the transaction's status (and the timeout) ends the wait.\n let handedOff = false;\n const finish = (error?: Error) => {\n if (finished) {\n return;\n }\n\n finished = true;\n window.clearInterval(interval);\n window.clearTimeout(timeout);\n window.removeEventListener('message', onMessage);\n popup.close();\n\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n };\n const poll = async () => {\n if (polling || finished) {\n return;\n }\n\n polling = true;\n let status: Awaited<ReturnType<ApiClient['pluginOAuthStatus']>>;\n\n try {\n status = await api.pluginOAuthStatus(transaction.transactionId);\n } catch {\n polling = false;\n\n return;\n }\n\n polling = false;\n\n if (status.status === 'complete') {\n finish();\n\n return;\n }\n\n if (!handedOff && popup.closed && status.status === 'pending') {\n finish(new Error('Connection window was closed.'));\n\n return;\n }\n\n if (status.status === 'failed' || new Date(status.expires_at).getTime() < Date.now()) {\n finish(new Error('Connection was not completed. Please try again.'));\n }\n };\n const onMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== expectedOrigin || event.source !== popup || !event.data || typeof event.data !== 'object') {\n return;\n }\n\n const payload = event.data as { type?: string; transactionId?: string; status?: string; error?: string };\n\n if (payload.type === 'flexkit:plugin-oauth-ready' && payload.transactionId === transaction.transactionId) {\n handedOff = true;\n popup.postMessage(\n {\n type: 'flexkit:plugin-oauth-start',\n transactionId: transaction.transactionId,\n ticket: transaction.launchTicket,\n },\n expectedOrigin\n );\n\n return;\n }\n\n if (payload.type === 'flexkit:plugin-oauth' && payload.transactionId === transaction.transactionId) {\n if (payload.status === 'failed' && payload.error === 'account_mismatch') {\n finish(new PluginAccountMismatchError());\n\n return;\n }\n\n void poll();\n }\n };\n const interval = window.setInterval(() => {\n void poll();\n }, 2000);\n const timeout = window.setTimeout(() => finish(new Error('Connection timed out. Please try again.')), 600_000);\n window.addEventListener('message', onMessage);\n popup.location.href = targets.href;\n });\n}\n","import type { MarketplacePlugin } from './plugin-types';\n\nexport type ConnectablePlugin = Pick<MarketplacePlugin, 'connect' | 'id' | 'name'>;\n\nexport function matchesTokenPattern(token: string, pattern: string | null): boolean {\n if (!pattern) {\n return true;\n }\n\n try {\n return new RegExp(pattern, 'u').test(token);\n } catch {\n // The server validates the pattern when it admits the plugin; never block on a bad one here.\n return true;\n }\n}\n\n/** A pattern that compiles; an empty or broken one detects nothing rather than every word. */\nfunction compileTokenPattern(pattern: string | null): RegExp | null {\n if (!pattern) {\n return null;\n }\n\n try {\n return new RegExp(pattern, 'u');\n } catch {\n return null;\n }\n}\n\n/**\n * The first plugin whose token format `text` contains, if any, with every\n * token-shaped word in the message: a token pasted into the chat would be\n * stored in the conversation and sent to the model.\n */\nexport function findPastedPluginToken(\n text: string,\n plugins: readonly ConnectablePlugin[]\n): { plugin: ConnectablePlugin; tokens: string[] } | null {\n // A token is often glued to a label (`token=…`, `key: …`) or wrapped in\n // brackets, quotes or a sentence's punctuation; none of those are part of it.\n const words = text\n .split(/[\\s\"'`()<>[\\]{},;:=!?&]+/)\n .map((word) => word.replace(/\\.+$/, ''))\n .filter(Boolean);\n let found: ConnectablePlugin | null = null;\n const tokens = new Set<string>();\n\n for (const plugin of plugins) {\n const pattern = compileTokenPattern(plugin.connect?.type === 'api-token' ? plugin.connect.pattern : null);\n\n for (const word of pattern ? words : []) {\n if (pattern!.test(word)) {\n found ??= plugin;\n tokens.add(word);\n }\n }\n }\n\n return found ? { plugin: found, tokens: [...tokens] } : null;\n}\n","import type { FormEvent, JSX } from 'react';\nimport { useId, useState, useSyncExternalStore } from 'react';\nimport { ExternalLinkIcon, LoaderCircle } from 'lucide-react';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '../../ui';\nimport type { ApiClient } from './api';\nimport { connectPluginPopup } from './plugin-oauth';\nimport { matchesTokenPattern, type ConnectablePlugin } from './plugin-token-format';\nimport type { PluginApiTokenConnect, PluginScope } from './plugin-types';\n\ninterface TokenRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginApiTokenConnect };\n /** Saves the token; rejects with a message the dialog shows next to the field. */\n submit: (_token: string) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\n/** The one open token dialog, outside React so any connect button can open it. */\nlet request: TokenRequest | null = null;\nlet lastRequestId = 0;\n/** Cancels the latest request, whether its dialog has opened yet or not. */\nlet cancelLatest: (() => void) | null = null;\nconst listeners = new Set<() => void>();\n\nfunction setRequest(next: TokenRequest | null): void {\n request = next;\n listeners.forEach((listener) => listener());\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n}\n\n/**\n * Connects a plugin: a sign-in popup for OAuth plugins, the token dialog for\n * plugins that take a pasted token. Resolves `false` when the user closes the\n * token dialog without connecting.\n *\n * Call it straight from a click handler: browsers only allow the popup there.\n */\nexport function connectPlugin(\n api: ApiClient,\n plugin: ConnectablePlugin,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<boolean> {\n const { connect } = plugin;\n\n if (connect?.type !== 'api-token') {\n return connectPluginPopup(api, plugin.id, scope, options).then(() => true);\n }\n\n // Opening a second dialog closes the first, as if cancelled.\n cancelLatest?.();\n\n const id = ++lastRequestId;\n\n return new Promise<boolean>((resolve) => {\n const next: TokenRequest = {\n id,\n plugin: { ...plugin, connect },\n submit: async (token) => {\n await api.connectPluginToken({\n pluginId: plugin.id,\n scope,\n token,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n },\n settle: (connected) => {\n // A save still running for a replaced dialog must not close its successor.\n if (request?.id === id) {\n setRequest(null);\n }\n\n if (lastRequestId === id) {\n cancelLatest = null;\n }\n\n resolve(connected);\n },\n };\n\n cancelLatest = () => next.settle(false);\n\n // Open after the current event: a menu item that started this closes first\n // and returns focus to its trigger, which would take it from the token field.\n setTimeout(() => {\n if (lastRequestId === id) {\n setRequest(next);\n }\n });\n });\n}\n\nfunction httpsHref(value: string | null): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const url = new URL(value);\n\n return url.protocol === 'https:' ? url.href : null;\n } catch {\n return null;\n }\n}\n\n/** Mounted once by the Studio layout; renders the dialog `connectPlugin` opens for token plugins. */\nexport function PluginTokenDialogHost(): JSX.Element | null {\n const current = useSyncExternalStore(\n subscribe,\n () => request,\n () => null\n );\n\n // A new key per request resets the field, so a token never outlives its dialog.\n return current ? <PluginTokenDialog key={current.id} request={current} /> : null;\n}\n\nfunction PluginTokenDialog({ request: current }: { request: TokenRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const inputId = useId();\n const [token, setToken] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const helpHref = httpsHref(connect.helpUrl);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n const value = token.trim();\n\n if (saving || !value) {\n return;\n }\n\n if (!matchesTokenPattern(value, connect.pattern)) {\n setError(`That does not look like a ${connect.tokenLabel}.`);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(value);\n setToken('');\n current.settle(true);\n } catch (failure) {\n setError(failure instanceof Error ? failure.message : `${name} could not be connected.`);\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n Paste a {connect.tokenLabel}. Flexkit stores it encrypted and sends it only to {name}; the agent can use{' '}\n {name}&apos;s tools but never sees the token. Give it read access only, unless the agent should change\n things in {name}.\n </DialogDescription>\n </DialogHeader>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {connect.tokenLabel}\n </label>\n <Input\n aria-describedby={error ? `${inputId}-error` : undefined}\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n disabled={saving}\n id={inputId}\n placeholder={connect.placeholder ?? undefined}\n spellCheck={false}\n type=\"password\"\n value={token}\n onChange={(event) => {\n setToken(event.target.value);\n setError(null);\n }}\n />\n {error ? (\n <p className=\"fk:text-sm fk:text-destructive\" id={`${inputId}-error`}>\n {error}\n </p>\n ) : null}\n {helpHref ? (\n <a\n className=\"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline\"\n href={helpHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n How to create a {connect.tokenLabel}\n <ExternalLinkIcon className=\"fk:size-3.5\" />\n </a>\n ) : null}\n </div>\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !token.trim()} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
@@ -1,2 +0,0 @@
1
- import'./index.css';export{a as EntityKnowledgeButton,c as LinkedRecordsSection,b as RecordKnowledgePanel}from'./chunk-3L4LYXSR.js';import'./chunk-NAUY7EN3.js';import'./chunk-2NXQF2F7.js';import'./chunk-RARRMN5A.js';import'./chunk-V7C4EHK3.js';import'./chunk-ZI22345U.js';import'./chunk-XMOSCJOI.js';import'./chunk-7KLXWCDS.js';import'./chunk-HKN6BX5U.js';import'./chunk-YDVO6XWD.js';import'./chunk-ERDARDGB.js';import'./chunk-WFJICDCL.js';import'./chunk-WPCPL2TQ.js';import'./chunk-5CVDMZUI.js';import'./chunk-DGIY4SKN.js';import'./chunk-SZEGGBOC.js';import'./chunk-32ZU4MLE.js';import'./chunk-U45E5X3H.js';import'./chunk-HDOIOXMP.js';import'./chunk-USNXQOMJ.js';import'./chunk-6NRQMG26.js';import'./chunk-O2QMYUPS.js';//# sourceMappingURL=record-links-XNRXCW3Y.js.map
2
- //# sourceMappingURL=record-links-XNRXCW3Y.js.map
@@ -1,2 +0,0 @@
1
- import'./index.css';import {b as b$1}from'./chunk-HE7I5LVU.js';import {a as a$1}from'./chunk-QSTWBKPN.js';import {b as b$5,a as a$2}from'./chunk-MLHXPTBT.js';import'./chunk-U6E7GNQW.js';import {f,g,d as d$1}from'./chunk-MNLYE7DK.js';import {b}from'./chunk-V7C4EHK3.js';import'./chunk-7KLXWCDS.js';import'./chunk-HKN6BX5U.js';import {f as f$1}from'./chunk-WFJICDCL.js';import {g as g$1}from'./chunk-WPCPL2TQ.js';import'./chunk-5CVDMZUI.js';import {Tc,Vc,s,na,qa,O,e as e$2,ha,ia,ja}from'./chunk-DGIY4SKN.js';import {t}from'./chunk-SZEGGBOC.js';import {v,w,b as b$4}from'./chunk-32ZU4MLE.js';import'./chunk-U45E5X3H.js';import {a,d,c,e,g as g$2}from'./chunk-HDOIOXMP.js';import {b as b$3,c as c$1,e as e$1}from'./chunk-USNXQOMJ.js';import {b as b$2}from'./chunk-6NRQMG26.js';import'./chunk-O2QMYUPS.js';import {useState,useRef,useMemo,useEffect}from'react';import {Plus,LoaderCircle,Trash2,GraduationCapIcon,ArrowLeft,Info,PenLine,Eye}from'lucide-react';import Ct from'react-markdown';import {useNavigate,Link,useParams}from'react-router-dom';import pe from'swr';import Tt from'swr/infinite';import {history,defaultKeymap,historyKeymap,indentWithTab}from'@codemirror/commands';import {markdown}from'@codemirror/lang-markdown';import {languages}from'@codemirror/language-data';import {foldGutter,indentOnInput,bracketMatching,foldKeymap}from'@codemirror/language';import {highlightSelectionMatches,searchKeymap}from'@codemirror/search';import {Compartment,EditorState,Prec}from'@codemirror/state';import {EditorView,lineNumbers,highlightActiveLineGutter,highlightSpecialChars,drawSelection,dropCursor,highlightActiveLine,keymap,placeholder}from'@codemirror/view';import {jsx,jsxs,Fragment}from'react/jsx-runtime';function ce(){let t=document.documentElement;return t.getAttribute("data-theme")==="dark"||t.classList.contains("dark")||t.style.colorScheme==="dark"}var pt=EditorView.theme({"&":{fontSize:"13px",height:"100%",maxHeight:"100%",maxWidth:"100%",minHeight:"0",minWidth:"0",width:"100%"},"&.cm-focused":{outline:"none"},".cm-scroller":{height:"100%",lineHeight:"1.6",minHeight:"0",minWidth:"0",overflow:"auto",width:"100%"},".cm-content":{fontSize:"13px",fontStyle:"normal",fontWeight:"400",minWidth:"0 !important",padding:"12px 0"},".cm-line, .cm-line span":{fontSize:"inherit",fontStyle:"inherit",fontWeight:"inherit",lineHeight:"inherit"},".cm-gutters":{borderRight:"1px solid transparent"},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none"}});function de(t){return [t?a$2:b$5,pt]}function je(t){return [EditorState.readOnly.of(t),EditorView.editable.of(!t)]}function Be(t){let i={"aria-multiline":"true",role:"textbox"};return t.ariaLabel&&(i["aria-label"]=t.ariaLabel),t.ariaLabelledBy&&(i["aria-labelledby"]=t.ariaLabelledBy),t.ariaDescribedBy&&(i["aria-describedby"]=t.ariaDescribedBy),t.ariaInvalid&&(i["aria-invalid"]="true"),t.readOnly&&(i["aria-readonly"]="true"),i}function Re({ariaDescribedBy:t,ariaInvalid:i,ariaLabel:o,ariaLabelledBy:a,className:l,onBlur:c,onChange:d,onSave:m,placeholder:k,readOnly:f=false,value:u}){let g=useRef(null),x=useRef(null),T=useRef(new Compartment),M=useRef(new Compartment),y=useRef(new Compartment),N=useRef(c),w=useRef(d),E=useRef(m),h=useRef(u);return N.current=c,w.current=d,E.current=m,h.current=u,useEffect(()=>{let s=g.current;if(!s)return;let p=new EditorView({parent:s,state:EditorState.create({doc:h.current,extensions:[lineNumbers(),highlightActiveLineGutter(),highlightSpecialChars(),history(),foldGutter(),drawSelection(),dropCursor(),EditorState.allowMultipleSelections.of(true),indentOnInput(),bracketMatching(),highlightActiveLine(),highlightSelectionMatches(),EditorView.lineWrapping,markdown({codeLanguages:languages}),keymap.of([...defaultKeymap,...historyKeymap,...searchKeymap,...foldKeymap,indentWithTab]),Prec.highest(keymap.of([{key:"Mod-s",run:()=>(E.current?.(),true)}])),EditorView.updateListener.of(F=>{F.docChanged&&w.current?.(F.state.doc.toString()),F.focusChanged&&!F.view.hasFocus&&N.current?.();}),T.current.of(de(ce())),M.current.of(je(f)),y.current.of(EditorView.contentAttributes.of(Be({ariaDescribedBy:t,ariaInvalid:i,ariaLabel:o,ariaLabelledBy:a,readOnly:f}))),...k?[placeholder(k)]:[]]})});x.current=p;let q=new ResizeObserver(()=>{p.requestMeasure();});q.observe(s);let K=new MutationObserver(()=>{p.dispatch({effects:T.current.reconfigure(de(ce()))});});return K.observe(document.documentElement,{attributeFilter:["class","data-theme","style"],attributes:true}),()=>{q.disconnect(),K.disconnect(),p.destroy(),x.current=null;}},[]),useEffect(()=>{let s=x.current;s&&s.dispatch({effects:T.current.reconfigure(de(ce()))});},[b$5,a$2]),useEffect(()=>{let s=x.current;if(!s)return;let p=s.state.doc.toString();p!==u&&s.dispatch({changes:{from:0,to:p.length,insert:u}});},[u]),useEffect(()=>{let s=x.current;s&&s.dispatch({effects:[M.current.reconfigure(je(f)),y.current.reconfigure(EditorView.contentAttributes.of(Be({ariaDescribedBy:t,ariaInvalid:i,ariaLabel:o,ariaLabelledBy:a,readOnly:f})))]});},[t,i,o,a,f]),jsx("div",{className:l??"fk:h-full fk:min-h-0 fk:min-w-0 fk:w-full fk:overflow-hidden",ref:g})}var Xe=25,Et=[{descriptionWidth:"fk:w-44",id:"skill-a",nameWidth:"fk:w-28"},{descriptionWidth:"fk:w-52",id:"skill-b",nameWidth:"fk:w-20"},{descriptionWidth:"fk:w-40",id:"skill-c",nameWidth:"fk:w-36"},{descriptionWidth:"fk:w-48",id:"skill-d",nameWidth:"fk:w-24"},{descriptionWidth:"fk:w-36",id:"skill-e",nameWidth:"fk:w-32"},{descriptionWidth:"fk:w-56",id:"skill-f",nameWidth:"fk:w-16"}];function It(){return jsxs("div",{"aria-busy":"true",className:"fk:grid fk:grid-cols-1 fk:gap-x-16 fk:gap-y-1 fk:lg:grid-cols-2",children:[jsx("span",{className:"fk:sr-only",children:"Loading skills"}),Et.map(t$1=>jsxs("div",{className:"fk:-mx-3 fk:flex fk:min-w-0 fk:items-center fk:gap-3 fk:px-3 fk:py-2",children:[jsx(t,{className:"fk:size-10 fk:shrink-0 fk:rounded-lg"}),jsxs("span",{className:"fk:flex fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-1.5",children:[jsx(t,{className:`fk:h-4 ${t$1.nameWidth}`}),jsx(t,{className:`fk:h-4 ${t$1.descriptionWidth}`})]})]},t$1.id))]})}var Mt={code({children:t,className:i,node:o,...a}){return typeof i=="string"&&i.split(" ").some(c=>c.startsWith("language-"))?jsx("code",{className:i,...a,children:t}):jsx("code",{className:"fk:rounded fk:bg-muted fk:px-1.5 fk:py-0.5 fk:font-mono fk:text-[0.875em] fk:font-medium fk:before:content-none fk:after:content-none fk:corner-squircle",...a,children:t})}};function ge(){let{currentProjectId:t}=f$1();return {api:useMemo(()=>t?d$1(t):null,[t]),projectId:t}}function Y({children:t}){return jsx("div",{className:"fk:rounded-md fk:border fk:border-dashed fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground fk:corner-squircle",children:t})}function Pt({onVisible:t}){let i=useRef(null),o=useRef(t);return o.current=t,useEffect(()=>{let a=i.current;if(!a)return;let l=new IntersectionObserver(c=>{c.some(d=>d.isIntersecting)&&o.current();});return l.observe(a),()=>{l.disconnect();}},[]),jsx("div",{"aria-hidden":true,className:"fk:h-px",ref:i})}function At(t,i){return t.visibility==="space"?(t.spaceId?i.get(t.spaceId):void 0)??"Space":t.visibility==="personal"?"Personal":"Project"}function Ft({skill:t}){return t.logoUrl?jsx(a$1,{className:"fk:size-10 fk:rounded-lg",src:t.logoUrl}):jsx("span",{className:"fk:flex fk:size-10 fk:shrink-0 fk:items-center fk:justify-center fk:rounded-lg fk:bg-muted fk:text-muted-foreground fk:corner-squircle",children:jsx(GraduationCapIcon,{className:"fk:size-5"})})}function oi(){let{api:t,projectId:i}=ge(),o=useNavigate(),[a,l]=useState(""),c=b(),d=a.trim().length>0,m=(s,p)=>!i||p&&!p.hasMore?null:g(i).skills({limit:Xe,offset:s*Xe,search:a.trim()||void 0}),{data:k,isLoading:f$1,setSize:u,size:g$1}=Tt(m,f),x=k?.flatMap(s=>s.skills)??[],M=k?.[k.length-1]?.hasMore??false,y=k!==void 0&&g$1>k.length,N=f$1&&x.length===0;if(!i||!t)return jsx(Y,{children:"Select a project to view skills."});function w(){u(s=>s+1);}let E="No skills yet.";d&&(E="No skills match your search.");let h=jsx("div",{className:"fk:grid fk:grid-cols-1 fk:gap-x-16 fk:gap-y-1 fk:lg:grid-cols-2",children:x.map(s=>jsxs("button",{type:"button",onClick:()=>o(s.id),className:"fk:-mx-3 fk:flex fk:min-w-0 fk:items-center fk:gap-3 fk:rounded-lg fk:px-3 fk:py-2 fk:text-left fk:transition-colors fk:hover:bg-accent fk:focus-visible:bg-accent fk:focus-visible:outline-none fk:corner-squircle",children:[jsx(Ft,{skill:s}),jsxs("span",{className:"fk:min-w-0 fk:flex-1",children:[jsx("span",{className:"fk:block fk:truncate fk:text-sm fk:font-medium",children:s.name}),jsx("span",{className:"fk:block fk:truncate fk:text-sm fk:text-muted-foreground",children:s.description})]})]},s.id))});return N?h=jsx(It,{}):x.length===0&&(h=jsx(Tc,{children:jsx(Vc,{children:E})})),jsxs("main",{className:"fk:flex fk:min-h-0 fk:flex-1 fk:flex-col",children:[jsx(b$1,{}),jsx("div",{className:"fk:min-h-0 fk:flex-1 fk:overflow-auto",children:jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-4xl fk:flex-col fk:gap-8 fk:py-6 fk:pl-4 fk:pr-6",children:[jsxs("div",{children:[jsx("h2",{className:"fk:text-2xl fk:font-semibold",children:"Skills for your agents"}),jsx("p",{className:"fk:mt-2 fk:text-muted-foreground",children:"Reusable Markdown instructions that agents load when relevant, or always when attached to an automation."})]}),jsxs("div",{className:"fk:flex fk:flex-wrap fk:items-center fk:gap-3",children:[jsx(s,{"aria-label":"Search skills",className:"fk:w-full fk:max-w-xs",placeholder:"Search skills\u2026",value:a,onChange:s=>{u(1),l(s.target.value);}}),c?jsx(b$2,{asChild:true,className:"fk:ml-auto",size:"sm",children:jsxs(Link,{to:"new",children:[jsx(Plus,{}),"New Skill"]})}):jsx(na,{disabled:true,children:jsxs(b$2,{className:"fk:ml-auto",disabled:true,size:"sm",children:[jsx(Plus,{}),"New Skill"]})})]}),h,M&&!y?jsx(Pt,{onVisible:w}):null,y?jsxs("div",{className:"fk:flex fk:items-center fk:justify-center fk:gap-2 fk:py-4 fk:text-sm fk:text-muted-foreground",children:[jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}),jsx("span",{children:"Loading more skills..."})]}):null]})})]})}function Q({className:t,id:i,message:o}){return jsx("p",{className:`fk:text-sm fk:text-destructive ${t??""}`,id:i,children:o})}function z({children:t,hint:i,htmlFor:o,id:a}){return jsxs("div",{className:"fk:mb-1.5 fk:pl-2.5 fk:flex fk:items-center fk:gap-1",children:[jsx(e$2,{htmlFor:o,id:a,children:t}),jsxs(b$3,{children:[jsx(c$1,{asChild:true,children:jsx("button",{"aria-label":`About ${t.toLowerCase()}`,className:"fk:rounded-sm fk:text-muted-foreground hover:fk:text-foreground fk:corner-squircle",type:"button",children:jsx(Info,{className:"fk:size-3.5"})})}),jsx(e$1,{className:"fk:max-w-xs",children:i})]})]})}function he({actions:t,title:i}){return jsxs(Fragment,{children:[jsxs("div",{className:"fk:flex fk:shrink-0 fk:items-center fk:gap-2 fk:pr-4",children:[jsxs(b$3,{children:[jsx(c$1,{asChild:true,children:jsx(O,{className:"fk:-ml-1 fk:h-4 fk:w-4"})}),jsx(e$1,{children:"Toggle Sidebar"})]}),jsx(v,{orientation:"vertical",className:"fk:h-4"}),jsx("h1",{className:"fk:min-w-0 fk:flex-1 fk:truncate fk:text-lg fk:font-semibold fk:leading-none fk:tracking-tight",children:i}),t]}),jsx(b$2,{asChild:true,className:"fk:shrink-0 fk:w-fit",size:"sm",variant:"ghost",children:jsxs(Link,{relative:"path",to:"..",children:[jsx(ArrowLeft,{className:"fk:mr-2 fk:size-4"}),"Skills"]})})]})}function Wt(){return jsxs("div",{"aria-busy":"true",className:"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:overflow-hidden fk:pb-3",children:[jsx("span",{className:"fk:sr-only",children:"Loading skill"}),jsx(he,{actions:jsx(t,{className:"fk:h-8 fk:w-24"}),title:jsx(t,{className:"fk:h-5 fk:w-40"})}),jsxs("div",{className:"fk:m-auto fk:flex fk:min-h-0 fk:w-full fk:max-w-6xl fk:flex-1 fk:flex-col fk:gap-8 fk:px-6",children:[jsxs("div",{className:"fk:grid fk:shrink-0 fk:gap-3 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]",children:[["name","description"].map(t$1=>jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(t,{className:"fk:h-4 fk:w-20"}),jsx(t,{className:"fk:h-9 fk:w-full"})]},t$1)),jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(t,{className:"fk:h-4 fk:w-20"}),jsx(t,{className:"fk:h-9 fk:w-32"})]})]}),jsxs("div",{className:"fk:flex fk:min-h-0 fk:flex-1 fk:flex-col fk:gap-1.5",children:[jsx(t,{className:"fk:h-4 fk:w-16"}),jsx(t,{className:"fk:min-h-48 fk:flex-1 fk:rounded-md"})]})]})]})}function Ve({content:t,onBlur:i,onChange:o,onSave:a,readOnly:l=false,showContentError:c,validationMessage:d}){let[m,k]=useState("write"),f=t.length>5e4,u;return t.trim()?u=jsx(Ct,{components:Mt,children:t}):u=jsx("p",{className:"fk:text-muted-foreground",children:"Nothing to preview."}),jsxs("div",{className:"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-1.5",children:[jsxs("div",{className:"fk:pl-3.25 fk:flex fk:shrink-0 fk:items-center fk:gap-1",children:[jsx(e$2,{htmlFor:"skill-content",id:"skill-content-label",children:"Content"}),jsxs(b$3,{children:[jsx(c$1,{asChild:true,children:jsx("button",{"aria-label":"About skill content",className:"fk:rounded-sm fk:text-muted-foreground hover:fk:text-foreground fk:corner-squircle",type:"button",children:jsx(Info,{className:"fk:size-3.5"})})}),jsx(e$1,{className:"fk:max-w-sm",children:"The skill itself, in Markdown. Write it like instructions for a capable colleague: procedures, rules, examples, and edge cases. Attached skills are always loaded; other visible skills are loaded on demand."})]})]}),jsxs("div",{className:`fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:ml-0.75 fk:overflow-hidden fk:rounded-md fk:border ${c?"fk:border-destructive":""} fk:corner-squircle`,children:[jsxs("div",{className:"fk:flex fk:shrink-0 fk:items-center fk:justify-between fk:gap-2 fk:border-b fk:px-2.5 fk:py-1",children:[jsx(ha,{value:m,onValueChange:g=>{k(g==="preview"?"preview":"write");},children:jsxs(ia,{children:[jsxs(b$3,{children:[jsx(c$1,{asChild:true,children:jsx("span",{className:"fk:inline-flex",children:jsx(ja,{"aria-label":"Write",className:"fk:px-2.5",value:"write",children:jsx(PenLine,{className:"fk:size-3.5"})})})}),jsx(e$1,{children:"Write"})]}),jsxs(b$3,{children:[jsx(c$1,{asChild:true,children:jsx("span",{className:"fk:inline-flex",children:jsx(ja,{"aria-label":"Preview",className:"fk:px-2.5",value:"preview",children:jsx(Eye,{className:"fk:size-3.5"})})})}),jsx(e$1,{children:"Preview"})]})]})}),jsxs("span",{className:f?"fk:text-xs fk:text-destructive":"fk:text-xs fk:text-muted-foreground",children:[t.length.toLocaleString()," / ",5e4.toLocaleString()]})]}),jsx("div",{className:"fk:min-h-0 fk:min-w-0 fk:flex-1 fk:overflow-hidden",hidden:m!=="write",children:jsx(Re,{ariaDescribedBy:c?"skill-content-error":void 0,ariaInvalid:c,ariaLabelledBy:"skill-content-label",className:"fk:h-full fk:min-h-0 fk:min-w-0 fk:w-full fk:overflow-hidden",readOnly:l,value:t,onBlur:i,onChange:o,onSave:a})}),m==="preview"?jsx(w,{className:"fk:min-h-0 fk:flex-1",children:jsx("div",{className:"fk:prose fk:prose-sm fk:dark:prose-invert fk:max-w-none fk:px-4 fk:py-3",children:u})}):null,c&&d?jsx(Q,{className:"fk:border-t fk:px-3 fk:py-2",id:"skill-content-error",message:d}):null]})]})}function He({api:t,mode:i,onSaved:o,projectId:a$1,skill:l}){let[c$1,d$1]=useState(l?.name??""),[m,k]=useState(l?.description??""),[f$1,u]=useState(l?.content??""),[g$3,x]=useState(l?.visibility??"project"),[T,M]=useState(l?.spaceId??null),[y,N]=useState(false),w=useRef(false),[E,h]=useState(""),[s$1,p]=useState({content:false,description:false,name:false}),q=useNavigate(),{data:K}=pe(g(a$1).spaces,f),[,F]=g$1(),X=b(),Oe=F.user?.spaces??[],ve=(K?.spaces??[]).filter(r=>Oe.includes(r.code)),te="";f$1.trim()?f$1.length>5e4&&(te=`Content must be at most ${String(5e4)} characters`):te="Content is required";let v={content:te,description:m.trim()?"":"Description is required",name:c$1.trim()?"":"Name is required",space:g$3==="space"&&!T?"Select a space":""},ie=!v.content&&!v.description&&!v.name&&!v.space,$=s$1.name&&!!v.name,G=s$1.description&&!!v.description,_e=s$1.content&&!!v.content,qe=i==="create"?"New Skill":l?.name??"Skill",ne="Update skill";y?ne="Saving...":i==="create"&&(ne="Create skill");async function be(){if(!X||w.current)return;if(!ie){p({content:true,description:true,name:true});return}w.current=true,N(true),h("");let r={content:f$1,description:m,name:c$1,spaceId:g$3==="space"?T:null,visibility:g$3};try{let I=i==="create"||!l?await t.createSkill(r):await t.updateSkill(l.id,r);if(!I.success){h(Array.isArray(I.errorMessage)?I.errorMessage.join(", "):I.errorMessage);return}qa.success(i==="create"||!l?"Skill created.":"Skill saved."),o(I.skill);}catch(I){h(I instanceof Error?I.message:"Failed to save skill.");}finally{w.current=false,N(false);}}async function Ke(r){r.preventDefault(),await be();}async function $e(){if(!(!l||!X||w.current)){w.current=true,N(true),h("");try{let r=await t.deleteSkill(l.id);if(!r.success){h(Array.isArray(r.errorMessage)?r.errorMessage.join(", "):r.errorMessage);return}q("..",{relative:"path"});}catch(r){h(r instanceof Error?r.message:"Failed to delete skill.");}finally{w.current=false,N(false);}}}return jsxs("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:pb-3",children:[jsx(he,{actions:jsxs("div",{className:"fk:flex fk:items-center fk:gap-3",children:[ie?null:jsx("span",{className:"fk:text-xs fk:text-muted-foreground",children:"Complete the required fields to save"}),i==="edit"&&l?jsxs(b$2,{disabled:y||!X,size:"sm",type:"button",variant:"outline",onClick:()=>{$e();},children:[jsx(Trash2,{}),"Delete"]}):null,jsx(na,{disabled:!X,children:jsx(b$2,{disabled:y||!ie||!X,form:"skill-editor-form",size:"sm",type:"submit",children:ne})})]}),title:qe}),E?jsx("div",{className:"fk:shrink-0 fk:rounded-md fk:border fk:border-destructive/30 fk:bg-destructive/5 fk:p-3 fk:text-sm fk:text-destructive fk:corner-squircle",children:E}):null,jsxs("form",{className:"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-6 fk:w-full fk:max-w-6xl fk:m-auto fk:gap-8 fk:px-4",id:"skill-editor-form",onSubmit:r=>{Ke(r);},children:[jsxs("div",{className:"fk:grid fk:min-w-0 fk:shrink-0 fk:gap-3 fk:px-0.75 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]",children:[jsxs("div",{children:[jsx(z,{hint:"Identifying label for this skill",htmlFor:"skill-name",children:"Name"}),jsx(s,{"aria-describedby":$?"skill-name-error":void 0,"aria-invalid":$,className:$?"fk:border-destructive focus-visible:fk:ring-destructive":"",id:"skill-name",value:c$1,onBlur:()=>p(r=>({...r,name:true})),onChange:r=>d$1(r.target.value)}),$?jsx(Q,{id:"skill-name-error",message:v.name}):null]}),jsxs("div",{children:[jsx(z,{hint:"One or two sentences describing when to use this skill. Agents rely on it to decide whether the skill applies to their current task.",htmlFor:"skill-description",children:"Description"}),jsx(s,{"aria-describedby":G?"skill-description-error":void 0,"aria-invalid":G,className:G?"fk:border-destructive focus-visible:fk:ring-destructive":"",id:"skill-description",placeholder:"e.g. Rules for writing product descriptions in our brand voice",value:m,onBlur:()=>p(r=>({...r,description:true})),onChange:r=>k(r.target.value)}),G?jsx(Q,{id:"skill-description-error",message:v.description}):null]}),jsxs("div",{children:[jsx(z,{hint:"Who can see and use this skill. Space skills are only visible to members of the selected space and only usable by automations in that space; personal skills are private to you.",htmlFor:"skill-visibility",children:"Visibility"}),jsxs("div",{className:"fk:flex fk:items-center fk:gap-2",children:[jsxs(a,{value:g$3,onValueChange:r=>{x(r==="space"||r==="personal"?r:"project"),r!=="space"&&M(null);},children:[jsx(d,{"aria-label":"Visibility",className:"fk:w-fit fk:min-w-26",id:"skill-visibility",children:jsx(c,{})}),jsxs(e,{align:"start",children:[jsx(g$2,{value:"project",children:"Project"}),jsx(g$2,{disabled:ve.length===0,value:"space",children:"Space"}),jsx(g$2,{value:"personal",children:"Personal"})]})]}),g$3==="space"?jsxs(a,{value:T??"",onValueChange:r=>{M(r||null);},children:[jsx(d,{"aria-label":"Space",className:"fk:w-fit fk:min-w-34",children:jsx(c,{placeholder:"Select a space"})}),jsx(e,{align:"start",children:ve.map(r=>jsx(g$2,{value:r.id,children:r.label},r.id))})]}):null]}),g$3==="space"&&v.space?jsx(Q,{message:v.space}):null]})]}),jsx(Ve,{content:f$1,showContentError:_e,validationMessage:v.content,onBlur:()=>p(r=>({...r,content:true})),onChange:u,onSave:()=>{be();}})]})]})}function jt({projectId:t,skill:i,spaceLabelById:o}){let a$1=b(),l=useNavigate(),[c$1,d$1]=useState(false),[m,k]=useState("");async function f(){d$1(true),k("");let u;try{u=await fetch(`/api/flexkit/${t}/skills/${i.id}/fork`,{method:"POST",credentials:"include"});}catch{k("Unable to create a copy. Try again."),d$1(false);return}if(d$1(false),!u.ok){k("Unable to create a copy. Check your permissions.");return}l("..",{relative:"path"});}return jsxs("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:pb-3",children:[jsx(he,{actions:jsxs("div",{className:"fk:flex fk:items-center fk:gap-2",children:[jsx(b$4,{variant:"secondary",children:i.source==="plugin"?"Plugin":"Code"}),i.source==="plugin"&&jsx(b$2,{type:"button",disabled:c$1||!a$1,onClick:()=>{f();},size:"sm",children:"Edit a copy"})]}),title:i.name}),jsxs("div",{className:"fk:flex fk:flex-col fk:h-full fk:px-4 fk:gap-3 fk:max-w-6xl fk:m-auto",children:[jsxs("div",{className:"fk:shrink-0 fk:rounded-md fk:border fk:bg-muted/30 fk:px-3 fk:py-2 fk:corner-squircle",children:[jsx("p",{className:"fk:text-sm fk:font-medium",children:"Version-controlled skill"}),jsx("p",{className:"fk:text-sm fk:text-muted-foreground",children:i.source==="plugin"?"This skill is managed by its plugin. Edit a copy to create a personal Studio skill.":"Edit this skill in your repository and re-sync it from the Custom Tools settings."})]}),jsxs("div",{className:"fk:grid fk:min-w-0 fk:shrink-0 fk:gap-3 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]",children:[jsxs("div",{children:[jsx(z,{hint:"Identifying label for this skill",htmlFor:"skill-name",children:"Name"}),jsx(s,{className:"fk:opacity-100!",disabled:true,id:"skill-name",value:i.name})]}),jsxs("div",{children:[jsx(z,{hint:"One or two sentences describing when to use this skill. Agents rely on it to decide whether the skill applies to their current task.",htmlFor:"skill-description",children:"Description"}),jsx(s,{className:"fk:opacity-100!",disabled:true,id:"skill-description",placeholder:"e.g. Rules for writing product descriptions in our brand voice",value:i.description})]}),jsxs("div",{children:[jsx(z,{hint:"Who can see and use this skill. Space skills are only visible to members of the selected space and only usable by automations in that space; personal skills are private to you.",htmlFor:"skill-visibility",children:"Visibility"}),jsxs("div",{className:"fk:flex fk:items-center fk:gap-2",children:[jsxs(a,{disabled:true,value:i.visibility,children:[jsx(d,{"aria-label":"Visibility",className:"fk:w-fit fk:min-w-26 fk:opacity-100!",id:"skill-visibility",children:jsx(c,{})}),jsxs(e,{align:"start",children:[jsx(g$2,{value:"project",children:"Project"}),jsx(g$2,{disabled:!i.spaceId,value:"space",children:"Space"}),jsx(g$2,{value:"personal",children:"Personal"})]})]}),i.visibility==="space"?jsxs(a,{disabled:true,value:i.spaceId??"",children:[jsx(d,{"aria-label":"Space",className:"fk:w-fit fk:min-w-34 fk:opacity-100!",children:jsx(c,{placeholder:"Select a space"})}),jsx(e,{align:"start",children:jsx(g$2,{value:i.spaceId??"",children:At(i,o)})})]}):null]})]})]}),m&&jsx("p",{role:"alert",children:m}),jsx(Ve,{content:i.content,readOnly:true})]})]})}function fi(){let{api:t,projectId:i}=ge(),o=useNavigate();return !i||!t?jsx(Y,{children:"Select a project to create skills."}):jsx(He,{api:t,mode:"create",projectId:i,onSaved:()=>o("..",{relative:"path"})})}function ci(){let{api:t,projectId:i}=ge(),{skillId:o}=useParams(),{data:a,error:l,isLoading:c,mutate:d}=pe(i&&o?g(i).skill(o):null,f),{data:m}=pe(i?g(i).spaces:null,f);if(!i||!t||!o)return jsx(Y,{children:"Select a skill."});if(l)return jsx(Y,{children:"Failed to load skill."});if(c||!a?.skill)return jsx(Wt,{});let k=new Map((m?.spaces??[]).map(f=>[f.id,f.label]));return a.skill.source!=="studio"?jsx(jt,{projectId:i,skill:a.skill,spaceLabelById:k}):jsx(He,{api:t,mode:"edit",projectId:i,skill:a.skill,onSaved:f=>{f?d({skill:f},{revalidate:false}):d();}})}export{fi as CreateSkillPage,ci as SkillDetailPage,He as SkillForm,oi as SkillsPage};//# sourceMappingURL=skills-pages-3RFTYQ2K.js.map
2
- //# sourceMappingURL=skills-pages-3RFTYQ2K.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/ai/markdown-editor.tsx","../src/apps/ai/skills-pages.tsx"],"names":["isDarkTheme","root","editorChrome","EditorView","themeExtensions","dark","darkTheme","lightTheme","readOnlyExtensions","readOnly","EditorState","contentAttributes","options","attributes","MarkdownEditor","ariaDescribedBy","ariaInvalid","ariaLabel","ariaLabelledBy","className","onBlur","onChange","onSave","placeholder","value","parentRef","useRef","viewRef","themeCompartmentRef","Compartment","readOnlyCompartmentRef","a11yCompartmentRef","onBlurRef","onChangeRef","onSaveRef","valueRef","useEffect","parent","view","lineNumbers","highlightActiveLineGutter","highlightSpecialChars","history","foldGutter","drawSelection","dropCursor","indentOnInput","bracketMatching","highlightActiveLine","highlightSelectionMatches","markdown","languages","keymap","defaultKeymap","historyKeymap","searchKeymap","foldKeymap","indentWithTab","Prec","update","placeholderExtension","resizeObserver","themeObserver","current","jsx","SKILLS_PAGE_SIZE","SKILL_SKELETON_ROWS","SkillListSkeleton","jsxs","row","Skeleton","skillMarkdownComponents","children","_node","props","part","useProjectApi","currentProjectId","useConfig","useMemo","createApiClient","PageMessage","InfiniteScrollSentinel","onVisible","sentinelRef","onVisibleRef","node","observer","entries","entry","getSkillVisibilityLabel","skill","spaceLabelById","SkillLogo","PluginLogo","GraduationCapIcon","SkillsPage","api","projectId","navigate","useNavigate","search","setSearch","useState","canMutate","useCanMutate","hasActiveFilters","getSkillsKey","pageIndex","previousPage","paths","skillPages","isLoading","setSize","size","useSWRInfinite","fetcher","skills","page","hasMore","isLoadingMore","isInitialLoading","handleLoadMore","currentSize","emptyMessage","content","Alert","AlertDescription","CatalogHeader","Input","event","Button","Link","Plus","PermissionTooltip","LoaderCircle","FieldError","id","message","FieldHintLabel","hint","htmlFor","Label","Tooltip","TooltipTrigger","Info","TooltipContent","SkillPageHeader","actions","title","Fragment","SidebarTrigger","Separator","ArrowLeft","SkillDetailSkeleton","field","SkillContentPane","showContentError","validationMessage","viewMode","setViewMode","isOverLimit","preview","Markdown","Tabs","TabsList","TabsTrigger","PenLine","Eye","ScrollArea","SkillForm","mode","onSaved","name","setName","description","setDescription","setContent","visibility","setVisibility","spaceId","setSpaceId","isSaving","setIsSaving","isSavingRef","setMessage","touched","setTouched","spacesData","useSWR","auth","useAuth","userSpaceCodes","selectableSpaces","space","contentError","validation","isValid","showNameError","showDescriptionError","saveLabel","save","input","result","toast","error","handleSubmit","deleteSkill","Trash2","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","ReadOnlyCodeSkill","forking","setForking","forkError","setForkError","fork","response","Badge","CreateSkillPage","SkillDetailPage","skillId","useParams","data","mutate"],"mappings":"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","file":"skills-pages-3RFTYQ2K.js","sourcesContent":["import type { JSX } from 'react';\nimport { useEffect, useRef } from 'react';\nimport { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';\nimport { markdown } from '@codemirror/lang-markdown';\nimport { languages } from '@codemirror/language-data';\nimport { bracketMatching, foldGutter, foldKeymap, indentOnInput } from '@codemirror/language';\nimport { highlightSelectionMatches, searchKeymap } from '@codemirror/search';\nimport { Compartment, EditorState, Prec } from '@codemirror/state';\nimport {\n drawSelection,\n dropCursor,\n EditorView,\n highlightActiveLine,\n highlightActiveLineGutter,\n highlightSpecialChars,\n keymap,\n lineNumbers,\n placeholder as placeholderExtension,\n} from '@codemirror/view';\nimport { lightTheme, darkTheme } from './markdown-editor-themes';\n\nexport interface MarkdownEditorProps {\n ariaDescribedBy?: string;\n ariaInvalid?: boolean;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n className?: string;\n onBlur?: () => void;\n onChange?: (_value: string) => void;\n onSave?: () => void;\n placeholder?: string;\n readOnly?: boolean;\n value: string;\n}\n\nfunction isDarkTheme(): boolean {\n const root = document.documentElement;\n\n return (\n root.getAttribute('data-theme') === 'dark' || root.classList.contains('dark') || root.style.colorScheme === 'dark'\n );\n}\n\nconst editorChrome = EditorView.theme({\n '&': {\n fontSize: '13px',\n height: '100%',\n maxHeight: '100%',\n maxWidth: '100%',\n minHeight: '0',\n minWidth: '0',\n width: '100%',\n },\n '&.cm-focused': {\n outline: 'none',\n },\n '.cm-scroller': {\n height: '100%',\n lineHeight: '1.6',\n minHeight: '0',\n minWidth: '0',\n overflow: 'auto',\n width: '100%',\n },\n '.cm-content': {\n fontSize: '13px',\n fontStyle: 'normal',\n fontWeight: '400',\n minWidth: '0 !important',\n padding: '12px 0',\n },\n '.cm-line, .cm-line span': {\n fontSize: 'inherit',\n fontStyle: 'inherit',\n fontWeight: 'inherit',\n lineHeight: 'inherit',\n },\n '.cm-gutters': {\n borderRight: '1px solid transparent',\n },\n '.cm-foldPlaceholder': {\n backgroundColor: 'transparent',\n border: 'none',\n },\n});\n\nfunction themeExtensions(dark: boolean) {\n return [dark ? darkTheme : lightTheme, editorChrome];\n}\n\nfunction readOnlyExtensions(readOnly: boolean) {\n return [EditorState.readOnly.of(readOnly), EditorView.editable.of(!readOnly)];\n}\n\nfunction contentAttributes(options: {\n ariaDescribedBy?: string;\n ariaInvalid?: boolean;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n readOnly?: boolean;\n}): { [name: string]: string } {\n const attributes: { [name: string]: string } = {\n 'aria-multiline': 'true',\n role: 'textbox',\n };\n\n if (options.ariaLabel) {\n attributes['aria-label'] = options.ariaLabel;\n }\n\n if (options.ariaLabelledBy) {\n attributes['aria-labelledby'] = options.ariaLabelledBy;\n }\n\n if (options.ariaDescribedBy) {\n attributes['aria-describedby'] = options.ariaDescribedBy;\n }\n\n if (options.ariaInvalid) {\n attributes['aria-invalid'] = 'true';\n }\n\n if (options.readOnly) {\n attributes['aria-readonly'] = 'true';\n }\n\n return attributes;\n}\n\nexport function MarkdownEditor({\n ariaDescribedBy,\n ariaInvalid,\n ariaLabel,\n ariaLabelledBy,\n className,\n onBlur,\n onChange,\n onSave,\n placeholder,\n readOnly = false,\n value,\n}: MarkdownEditorProps): JSX.Element {\n const parentRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const themeCompartmentRef = useRef(new Compartment());\n const readOnlyCompartmentRef = useRef(new Compartment());\n const a11yCompartmentRef = useRef(new Compartment());\n const onBlurRef = useRef(onBlur);\n const onChangeRef = useRef(onChange);\n const onSaveRef = useRef(onSave);\n const valueRef = useRef(value);\n\n onBlurRef.current = onBlur;\n onChangeRef.current = onChange;\n onSaveRef.current = onSave;\n valueRef.current = value;\n\n useEffect(() => {\n const parent = parentRef.current;\n\n if (!parent) {\n return;\n }\n\n const view = new EditorView({\n parent,\n state: EditorState.create({\n doc: valueRef.current,\n extensions: [\n lineNumbers(),\n highlightActiveLineGutter(),\n highlightSpecialChars(),\n history(),\n foldGutter(),\n drawSelection(),\n dropCursor(),\n EditorState.allowMultipleSelections.of(true),\n indentOnInput(),\n bracketMatching(),\n highlightActiveLine(),\n highlightSelectionMatches(),\n EditorView.lineWrapping,\n markdown({ codeLanguages: languages }),\n keymap.of([...defaultKeymap, ...historyKeymap, ...searchKeymap, ...foldKeymap, indentWithTab]),\n Prec.highest(\n keymap.of([\n {\n key: 'Mod-s',\n run: () => {\n onSaveRef.current?.();\n\n return true;\n },\n },\n ])\n ),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n onChangeRef.current?.(update.state.doc.toString());\n }\n\n if (update.focusChanged && !update.view.hasFocus) {\n onBlurRef.current?.();\n }\n }),\n themeCompartmentRef.current.of(themeExtensions(isDarkTheme())),\n readOnlyCompartmentRef.current.of(readOnlyExtensions(readOnly)),\n a11yCompartmentRef.current.of(\n EditorView.contentAttributes.of(\n contentAttributes({\n ariaDescribedBy,\n ariaInvalid,\n ariaLabel,\n ariaLabelledBy,\n readOnly,\n })\n )\n ),\n ...(placeholder ? [placeholderExtension(placeholder)] : []),\n ],\n }),\n });\n\n viewRef.current = view;\n\n const resizeObserver = new ResizeObserver(() => {\n view.requestMeasure();\n });\n\n resizeObserver.observe(parent);\n\n const themeObserver = new MutationObserver(() => {\n view.dispatch({\n effects: themeCompartmentRef.current.reconfigure(themeExtensions(isDarkTheme())),\n });\n });\n\n themeObserver.observe(document.documentElement, {\n attributeFilter: ['class', 'data-theme', 'style'],\n attributes: true,\n });\n\n return () => {\n resizeObserver.disconnect();\n themeObserver.disconnect();\n view.destroy();\n viewRef.current = null;\n };\n // Mount once; later prop changes are applied through compartments / document transactions.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- editor view is created once\n }, []);\n\n useEffect(() => {\n const view = viewRef.current;\n\n if (!view) {\n return;\n }\n\n view.dispatch({\n effects: themeCompartmentRef.current.reconfigure(themeExtensions(isDarkTheme())),\n });\n // Imported palettes live at module scope; this re-applies them after tsup/HMR.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- theme extensions change on hot reload\n }, [lightTheme, darkTheme]);\n\n useEffect(() => {\n const view = viewRef.current;\n\n if (!view) {\n return;\n }\n\n const current = view.state.doc.toString();\n\n if (current === value) {\n return;\n }\n\n view.dispatch({\n changes: { from: 0, to: current.length, insert: value },\n });\n }, [value]);\n\n useEffect(() => {\n const view = viewRef.current;\n\n if (!view) {\n return;\n }\n\n view.dispatch({\n effects: [\n readOnlyCompartmentRef.current.reconfigure(readOnlyExtensions(readOnly)),\n a11yCompartmentRef.current.reconfigure(\n EditorView.contentAttributes.of(\n contentAttributes({\n ariaDescribedBy,\n ariaInvalid,\n ariaLabel,\n ariaLabelledBy,\n readOnly,\n })\n )\n ),\n ],\n });\n }, [ariaDescribedBy, ariaInvalid, ariaLabel, ariaLabelledBy, readOnly]);\n\n return (\n <div className={className ?? 'fk:h-full fk:min-h-0 fk:min-w-0 fk:w-full fk:overflow-hidden'} ref={parentRef} />\n );\n}\n","import type { FormEvent, JSX } from 'react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { ArrowLeft, Eye, GraduationCapIcon, Info, LoaderCircle, PenLine, Plus, Trash2 } from 'lucide-react';\nimport Markdown, { type Components } from 'react-markdown';\nimport { Link, useNavigate, useParams } from 'react-router-dom';\nimport { useAuth } from '../../auth/auth-context';\nimport { useCanMutate } from '../../core/permissions';\nimport { useConfig } from '../../core/config/config-context';\nimport { MAX_SKILL_CONTENT_LENGTH } from './skill-limits';\nimport {\n Alert,\n AlertDescription,\n Badge,\n Button,\n Input,\n Label,\n PermissionTooltip,\n ScrollArea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Separator,\n SidebarTrigger,\n Skeleton,\n Tabs,\n TabsList,\n TabsTrigger,\n toast,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../../ui';\nimport useSWR from 'swr';\nimport useSWRInfinite from 'swr/infinite';\nimport { createApiClient, fetcher, paths, type ApiClient } from './api';\nimport { MarkdownEditor } from './markdown-editor';\nimport { CatalogHeader } from './plugin-pages';\nimport type { AutomationVisibility, ProjectSpace, Skill, SkillInput, SkillsList } from './types';\nimport { PluginLogo } from './plugin-logo';\n\nconst SKILLS_PAGE_SIZE = 25;\n\nconst SKILL_SKELETON_ROWS: { descriptionWidth: string; id: string; nameWidth: string }[] = [\n { descriptionWidth: 'fk:w-44', id: 'skill-a', nameWidth: 'fk:w-28' },\n { descriptionWidth: 'fk:w-52', id: 'skill-b', nameWidth: 'fk:w-20' },\n { descriptionWidth: 'fk:w-40', id: 'skill-c', nameWidth: 'fk:w-36' },\n { descriptionWidth: 'fk:w-48', id: 'skill-d', nameWidth: 'fk:w-24' },\n { descriptionWidth: 'fk:w-36', id: 'skill-e', nameWidth: 'fk:w-32' },\n { descriptionWidth: 'fk:w-56', id: 'skill-f', nameWidth: 'fk:w-16' },\n];\n\nfunction SkillListSkeleton(): JSX.Element {\n return (\n <div aria-busy=\"true\" className=\"fk:grid fk:grid-cols-1 fk:gap-x-16 fk:gap-y-1 fk:lg:grid-cols-2\">\n <span className=\"fk:sr-only\">Loading skills</span>\n {SKILL_SKELETON_ROWS.map((row) => (\n <div className=\"fk:-mx-3 fk:flex fk:min-w-0 fk:items-center fk:gap-3 fk:px-3 fk:py-2\" key={row.id}>\n <Skeleton className=\"fk:size-10 fk:shrink-0 fk:rounded-lg\" />\n <span className=\"fk:flex fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-1.5\">\n <Skeleton className={`fk:h-4 ${row.nameWidth}`} />\n <Skeleton className={`fk:h-4 ${row.descriptionWidth}`} />\n </span>\n </div>\n ))}\n </div>\n );\n}\n\nconst skillMarkdownComponents: Components = {\n code({ children, className, node: _node, ...props }) {\n const isFenced = typeof className === 'string' && className.split(' ').some((part) => part.startsWith('language-'));\n\n if (isFenced) {\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n }\n\n return (\n <code\n className=\"fk:rounded fk:bg-muted fk:px-1.5 fk:py-0.5 fk:font-mono fk:text-[0.875em] fk:font-medium fk:before:content-none fk:after:content-none fk:corner-squircle\"\n {...props}\n >\n {children}\n </code>\n );\n },\n};\n\nfunction useProjectApi(): { api: ApiClient | null; projectId: string | undefined } {\n const { currentProjectId } = useConfig();\n const api = useMemo(() => (currentProjectId ? createApiClient(currentProjectId) : null), [currentProjectId]);\n\n return { api, projectId: currentProjectId };\n}\n\nfunction PageMessage({ children }: { children: string }): JSX.Element {\n return (\n <div className=\"fk:rounded-md fk:border fk:border-dashed fk:p-8 fk:text-center fk:text-sm fk:text-muted-foreground fk:corner-squircle\">\n {children}\n </div>\n );\n}\n\nfunction InfiniteScrollSentinel({ onVisible }: { onVisible: () => void }): JSX.Element {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onVisibleRef = useRef(onVisible);\n\n onVisibleRef.current = onVisible;\n\n useEffect(() => {\n const node = sentinelRef.current;\n\n if (!node) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n onVisibleRef.current();\n }\n });\n\n observer.observe(node);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n return <div aria-hidden className=\"fk:h-px\" ref={sentinelRef} />;\n}\n\nfunction getSkillVisibilityLabel(skill: Skill, spaceLabelById: Map<string, string>): string {\n if (skill.visibility === 'space') {\n return (skill.spaceId ? spaceLabelById.get(skill.spaceId) : undefined) ?? 'Space';\n }\n\n if (skill.visibility === 'personal') {\n return 'Personal';\n }\n\n return 'Project';\n}\n\nfunction SkillLogo({ skill }: { skill: Skill }): JSX.Element {\n if (skill.logoUrl) {\n return <PluginLogo className=\"fk:size-10 fk:rounded-lg\" src={skill.logoUrl} />;\n }\n\n return (\n <span className=\"fk:flex fk:size-10 fk:shrink-0 fk:items-center fk:justify-center fk:rounded-lg fk:bg-muted fk:text-muted-foreground fk:corner-squircle\">\n <GraduationCapIcon className=\"fk:size-5\" />\n </span>\n );\n}\n\nexport function SkillsPage(): JSX.Element {\n const { api, projectId } = useProjectApi();\n const navigate = useNavigate();\n const [search, setSearch] = useState('');\n const canMutate = useCanMutate();\n const hasActiveFilters = search.trim().length > 0;\n\n const getSkillsKey = (pageIndex: number, previousPage: SkillsList | null): string | null => {\n if (!projectId) {\n return null;\n }\n\n if (previousPage && !previousPage.hasMore) {\n return null;\n }\n\n return paths(projectId).skills({\n limit: SKILLS_PAGE_SIZE,\n offset: pageIndex * SKILLS_PAGE_SIZE,\n search: search.trim() || undefined,\n });\n };\n const { data: skillPages, isLoading, setSize, size } = useSWRInfinite<SkillsList>(getSkillsKey, fetcher);\n const skills = skillPages?.flatMap((page) => page.skills) ?? [];\n const lastPage = skillPages?.[skillPages.length - 1];\n const hasMore = lastPage?.hasMore ?? false;\n const isLoadingMore = skillPages !== undefined && size > skillPages.length;\n const isInitialLoading = isLoading && skills.length === 0;\n\n if (!projectId || !api) {\n return <PageMessage>Select a project to view skills.</PageMessage>;\n }\n\n function handleLoadMore(): void {\n void setSize((currentSize) => currentSize + 1);\n }\n\n let emptyMessage = 'No skills yet.';\n\n if (hasActiveFilters) {\n emptyMessage = 'No skills match your search.';\n }\n\n let content: JSX.Element = (\n <div className=\"fk:grid fk:grid-cols-1 fk:gap-x-16 fk:gap-y-1 fk:lg:grid-cols-2\">\n {skills.map((skill) => (\n <button\n key={skill.id}\n type=\"button\"\n onClick={() => navigate(skill.id)}\n className=\"fk:-mx-3 fk:flex fk:min-w-0 fk:items-center fk:gap-3 fk:rounded-lg fk:px-3 fk:py-2 fk:text-left fk:transition-colors fk:hover:bg-accent fk:focus-visible:bg-accent fk:focus-visible:outline-none fk:corner-squircle\"\n >\n <SkillLogo skill={skill} />\n <span className=\"fk:min-w-0 fk:flex-1\">\n <span className=\"fk:block fk:truncate fk:text-sm fk:font-medium\">{skill.name}</span>\n <span className=\"fk:block fk:truncate fk:text-sm fk:text-muted-foreground\">{skill.description}</span>\n </span>\n </button>\n ))}\n </div>\n );\n\n if (isInitialLoading) {\n content = <SkillListSkeleton />;\n } else if (skills.length === 0) {\n content = (\n <Alert>\n <AlertDescription>{emptyMessage}</AlertDescription>\n </Alert>\n );\n }\n\n return (\n <main className=\"fk:flex fk:min-h-0 fk:flex-1 fk:flex-col\">\n <CatalogHeader />\n <div className=\"fk:min-h-0 fk:flex-1 fk:overflow-auto\">\n <div className=\"fk:mx-auto fk:flex fk:w-full fk:max-w-4xl fk:flex-col fk:gap-8 fk:py-6 fk:pl-4 fk:pr-6\">\n <div>\n <h2 className=\"fk:text-2xl fk:font-semibold\">Skills for your agents</h2>\n <p className=\"fk:mt-2 fk:text-muted-foreground\">\n Reusable Markdown instructions that agents load when relevant, or always when attached to an automation.\n </p>\n </div>\n <div className=\"fk:flex fk:flex-wrap fk:items-center fk:gap-3\">\n <Input\n aria-label=\"Search skills\"\n className=\"fk:w-full fk:max-w-xs\"\n placeholder=\"Search skills…\"\n value={search}\n onChange={(event) => {\n void setSize(1);\n setSearch(event.target.value);\n }}\n />\n {canMutate ? (\n <Button asChild className=\"fk:ml-auto\" size=\"sm\">\n <Link to=\"new\">\n <Plus />\n New Skill\n </Link>\n </Button>\n ) : (\n <PermissionTooltip disabled>\n <Button className=\"fk:ml-auto\" disabled size=\"sm\">\n <Plus />\n New Skill\n </Button>\n </PermissionTooltip>\n )}\n </div>\n {content}\n {hasMore && !isLoadingMore ? <InfiniteScrollSentinel onVisible={handleLoadMore} /> : null}\n {isLoadingMore ? (\n <div className=\"fk:flex fk:items-center fk:justify-center fk:gap-2 fk:py-4 fk:text-sm fk:text-muted-foreground\">\n <LoaderCircle className=\"fk:size-4 fk:animate-spin\" />\n <span>Loading more skills...</span>\n </div>\n ) : null}\n </div>\n </div>\n </main>\n );\n}\n\nfunction FieldError({ className, id, message }: { className?: string; id?: string; message: string }): JSX.Element {\n return (\n <p className={`fk:text-sm fk:text-destructive ${className ?? ''}`} id={id}>\n {message}\n </p>\n );\n}\n\nfunction FieldHintLabel({\n children,\n hint,\n htmlFor,\n id,\n}: {\n children: string;\n hint: string;\n htmlFor?: string;\n id?: string;\n}): JSX.Element {\n return (\n <div className=\"fk:mb-1.5 fk:pl-2.5 fk:flex fk:items-center fk:gap-1\">\n <Label htmlFor={htmlFor} id={id}>\n {children}\n </Label>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n aria-label={`About ${children.toLowerCase()}`}\n className=\"fk:rounded-sm fk:text-muted-foreground hover:fk:text-foreground fk:corner-squircle\"\n type=\"button\"\n >\n <Info className=\"fk:size-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent className=\"fk:max-w-xs\">{hint}</TooltipContent>\n </Tooltip>\n </div>\n );\n}\n\nfunction SkillPageHeader({ actions, title }: { actions?: JSX.Element; title: string | JSX.Element }): JSX.Element {\n return (\n <>\n <div className=\"fk:flex fk:shrink-0 fk:items-center fk:gap-2 fk:pr-4\">\n <Tooltip>\n <TooltipTrigger asChild>\n <SidebarTrigger className=\"fk:-ml-1 fk:h-4 fk:w-4\" />\n </TooltipTrigger>\n <TooltipContent>Toggle Sidebar</TooltipContent>\n </Tooltip>\n <Separator orientation=\"vertical\" className=\"fk:h-4\" />\n <h1 className=\"fk:min-w-0 fk:flex-1 fk:truncate fk:text-lg fk:font-semibold fk:leading-none fk:tracking-tight\">\n {title}\n </h1>\n {actions}\n </div>\n <Button asChild className=\"fk:shrink-0 fk:w-fit\" size=\"sm\" variant=\"ghost\">\n <Link relative=\"path\" to=\"..\">\n <ArrowLeft className=\"fk:mr-2 fk:size-4\" />\n Skills\n </Link>\n </Button>\n </>\n );\n}\n\nfunction SkillDetailSkeleton(): JSX.Element {\n return (\n <div aria-busy=\"true\" className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:overflow-hidden fk:pb-3\">\n <span className=\"fk:sr-only\">Loading skill</span>\n <SkillPageHeader actions={<Skeleton className=\"fk:h-8 fk:w-24\" />} title={<Skeleton className=\"fk:h-5 fk:w-40\" />} />\n <div className=\"fk:m-auto fk:flex fk:min-h-0 fk:w-full fk:max-w-6xl fk:flex-1 fk:flex-col fk:gap-8 fk:px-6\">\n <div className=\"fk:grid fk:shrink-0 fk:gap-3 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]\">\n {['name', 'description'].map((field) => (\n <div className=\"fk:flex fk:flex-col fk:gap-2\" key={field}>\n <Skeleton className=\"fk:h-4 fk:w-20\" />\n <Skeleton className=\"fk:h-9 fk:w-full\" />\n </div>\n ))}\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Skeleton className=\"fk:h-4 fk:w-20\" />\n <Skeleton className=\"fk:h-9 fk:w-32\" />\n </div>\n </div>\n <div className=\"fk:flex fk:min-h-0 fk:flex-1 fk:flex-col fk:gap-1.5\">\n <Skeleton className=\"fk:h-4 fk:w-16\" />\n <Skeleton className=\"fk:min-h-48 fk:flex-1 fk:rounded-md\" />\n </div>\n </div>\n </div>\n );\n}\n\nfunction SkillContentPane({\n content,\n onBlur,\n onChange,\n onSave,\n readOnly = false,\n showContentError,\n validationMessage,\n}: {\n content: string;\n onBlur?: () => void;\n onChange?: (_value: string) => void;\n onSave?: () => void;\n readOnly?: boolean;\n showContentError?: boolean;\n validationMessage?: string;\n}): JSX.Element {\n const [viewMode, setViewMode] = useState<'preview' | 'write'>('write');\n const isOverLimit = content.length > MAX_SKILL_CONTENT_LENGTH;\n let preview: JSX.Element;\n\n if (content.trim()) {\n preview = <Markdown components={skillMarkdownComponents}>{content}</Markdown>;\n } else {\n preview = <p className=\"fk:text-muted-foreground\">Nothing to preview.</p>;\n }\n\n return (\n <div className=\"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-1.5\">\n <div className=\"fk:pl-3.25 fk:flex fk:shrink-0 fk:items-center fk:gap-1\">\n <Label htmlFor=\"skill-content\" id=\"skill-content-label\">\n Content\n </Label>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n aria-label=\"About skill content\"\n className=\"fk:rounded-sm fk:text-muted-foreground hover:fk:text-foreground fk:corner-squircle\"\n type=\"button\"\n >\n <Info className=\"fk:size-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent className=\"fk:max-w-sm\">\n The skill itself, in Markdown. Write it like instructions for a capable colleague: procedures, rules,\n examples, and edge cases. Attached skills are always loaded; other visible skills are loaded on demand.\n </TooltipContent>\n </Tooltip>\n </div>\n <div\n className={`fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:ml-0.75 fk:overflow-hidden fk:rounded-md fk:border ${showContentError ? 'fk:border-destructive' : ''} fk:corner-squircle`}\n >\n <div className=\"fk:flex fk:shrink-0 fk:items-center fk:justify-between fk:gap-2 fk:border-b fk:px-2.5 fk:py-1\">\n <Tabs\n value={viewMode}\n onValueChange={(value) => {\n setViewMode(value === 'preview' ? 'preview' : 'write');\n }}\n >\n <TabsList>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"fk:inline-flex\">\n <TabsTrigger aria-label=\"Write\" className=\"fk:px-2.5\" value=\"write\">\n <PenLine className=\"fk:size-3.5\" />\n </TabsTrigger>\n </span>\n </TooltipTrigger>\n <TooltipContent>Write</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"fk:inline-flex\">\n <TabsTrigger aria-label=\"Preview\" className=\"fk:px-2.5\" value=\"preview\">\n <Eye className=\"fk:size-3.5\" />\n </TabsTrigger>\n </span>\n </TooltipTrigger>\n <TooltipContent>Preview</TooltipContent>\n </Tooltip>\n </TabsList>\n </Tabs>\n <span className={isOverLimit ? 'fk:text-xs fk:text-destructive' : 'fk:text-xs fk:text-muted-foreground'}>\n {content.length.toLocaleString()} / {MAX_SKILL_CONTENT_LENGTH.toLocaleString()}\n </span>\n </div>\n <div className=\"fk:min-h-0 fk:min-w-0 fk:flex-1 fk:overflow-hidden\" hidden={viewMode !== 'write'}>\n <MarkdownEditor\n ariaDescribedBy={showContentError ? 'skill-content-error' : undefined}\n ariaInvalid={showContentError}\n ariaLabelledBy=\"skill-content-label\"\n className=\"fk:h-full fk:min-h-0 fk:min-w-0 fk:w-full fk:overflow-hidden\"\n readOnly={readOnly}\n value={content}\n onBlur={onBlur}\n onChange={onChange}\n onSave={onSave}\n />\n </div>\n {viewMode === 'preview' ? (\n <ScrollArea className=\"fk:min-h-0 fk:flex-1\">\n <div className=\"fk:prose fk:prose-sm fk:dark:prose-invert fk:max-w-none fk:px-4 fk:py-3\">{preview}</div>\n </ScrollArea>\n ) : null}\n {showContentError && validationMessage ? (\n <FieldError className=\"fk:border-t fk:px-3 fk:py-2\" id=\"skill-content-error\" message={validationMessage} />\n ) : null}\n </div>\n </div>\n );\n}\n\ninterface SkillFormProps {\n api: ApiClient;\n mode: 'create' | 'edit';\n onSaved: (_skill?: Skill) => void;\n projectId: string;\n skill?: Skill;\n}\n\nexport function SkillForm({ api, mode, onSaved, projectId, skill }: SkillFormProps): JSX.Element {\n const [name, setName] = useState(skill?.name ?? '');\n const [description, setDescription] = useState(skill?.description ?? '');\n const [content, setContent] = useState(skill?.content ?? '');\n const [visibility, setVisibility] = useState<AutomationVisibility>(skill?.visibility ?? 'project');\n const [spaceId, setSpaceId] = useState<string | null>(skill?.spaceId ?? null);\n const [isSaving, setIsSaving] = useState(false);\n const isSavingRef = useRef(false);\n const [message, setMessage] = useState('');\n const [touched, setTouched] = useState({ content: false, description: false, name: false });\n const navigate = useNavigate();\n const { data: spacesData } = useSWR<{ spaces: ProjectSpace[] }>(paths(projectId).spaces, fetcher);\n const [, auth] = useAuth();\n const canMutate = useCanMutate();\n const userSpaceCodes = auth.user?.spaces ?? [];\n // Only spaces the caller belongs to are offered; the server rejects\n // bindings to spaces outside the caller's membership anyway.\n const selectableSpaces = (spacesData?.spaces ?? []).filter((space) => userSpaceCodes.includes(space.code));\n let contentError = '';\n\n if (!content.trim()) {\n contentError = 'Content is required';\n } else if (content.length > MAX_SKILL_CONTENT_LENGTH) {\n contentError = `Content must be at most ${String(MAX_SKILL_CONTENT_LENGTH)} characters`;\n }\n\n const validation = {\n content: contentError,\n description: description.trim() ? '' : 'Description is required',\n name: name.trim() ? '' : 'Name is required',\n space: visibility === 'space' && !spaceId ? 'Select a space' : '',\n };\n const isValid = !validation.content && !validation.description && !validation.name && !validation.space;\n const showNameError = touched.name && Boolean(validation.name);\n const showDescriptionError = touched.description && Boolean(validation.description);\n const showContentError = touched.content && Boolean(validation.content);\n const title = mode === 'create' ? 'New Skill' : (skill?.name ?? 'Skill');\n let saveLabel = 'Update skill';\n\n if (isSaving) {\n saveLabel = 'Saving...';\n } else if (mode === 'create') {\n saveLabel = 'Create skill';\n }\n\n async function save(): Promise<void> {\n if (!canMutate || isSavingRef.current) {\n return;\n }\n\n if (!isValid) {\n setTouched({ content: true, description: true, name: true });\n\n return;\n }\n\n isSavingRef.current = true;\n setIsSaving(true);\n setMessage('');\n\n const input: SkillInput = {\n content,\n description,\n name,\n spaceId: visibility === 'space' ? spaceId : null,\n visibility,\n };\n\n try {\n const result =\n mode === 'create' || !skill ? await api.createSkill(input) : await api.updateSkill(skill.id, input);\n\n if (!result.success) {\n setMessage(Array.isArray(result.errorMessage) ? result.errorMessage.join(', ') : result.errorMessage);\n\n return;\n }\n\n toast.success(mode === 'create' || !skill ? 'Skill created.' : 'Skill saved.');\n onSaved(result.skill);\n } catch (error) {\n setMessage(error instanceof Error ? error.message : 'Failed to save skill.');\n } finally {\n isSavingRef.current = false;\n setIsSaving(false);\n }\n }\n\n async function handleSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {\n event.preventDefault();\n await save();\n }\n\n async function deleteSkill(): Promise<void> {\n if (!skill || !canMutate || isSavingRef.current) {\n return;\n }\n\n isSavingRef.current = true;\n setIsSaving(true);\n setMessage('');\n\n try {\n const result = await api.deleteSkill(skill.id);\n\n if (!result.success) {\n setMessage(Array.isArray(result.errorMessage) ? result.errorMessage.join(', ') : result.errorMessage);\n\n return;\n }\n\n navigate('..', { relative: 'path' });\n } catch (error) {\n setMessage(error instanceof Error ? error.message : 'Failed to delete skill.');\n } finally {\n isSavingRef.current = false;\n setIsSaving(false);\n }\n }\n\n return (\n <div className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:pb-3\">\n <SkillPageHeader\n actions={\n <div className=\"fk:flex fk:items-center fk:gap-3\">\n {!isValid ? (\n <span className=\"fk:text-xs fk:text-muted-foreground\">Complete the required fields to save</span>\n ) : null}\n {mode === 'edit' && skill ? (\n <Button disabled={isSaving || !canMutate} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => void deleteSkill()}>\n <Trash2 />\n Delete\n </Button>\n ) : null}\n <PermissionTooltip disabled={!canMutate}>\n <Button disabled={isSaving || !isValid || !canMutate} form=\"skill-editor-form\" size=\"sm\" type=\"submit\">\n {saveLabel}\n </Button>\n </PermissionTooltip>\n </div>\n }\n title={title}\n />\n {message ? (\n <div className=\"fk:shrink-0 fk:rounded-md fk:border fk:border-destructive/30 fk:bg-destructive/5 fk:p-3 fk:text-sm fk:text-destructive fk:corner-squircle\">\n {message}\n </div>\n ) : null}\n <form\n className=\"fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-6 fk:w-full fk:max-w-6xl fk:m-auto fk:gap-8 fk:px-4\"\n id=\"skill-editor-form\"\n onSubmit={(event) => void handleSubmit(event)}\n >\n <div className=\"fk:grid fk:min-w-0 fk:shrink-0 fk:gap-3 fk:px-0.75 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]\">\n <div>\n <FieldHintLabel hint=\"Identifying label for this skill\" htmlFor=\"skill-name\">\n Name\n </FieldHintLabel>\n <Input\n aria-describedby={showNameError ? 'skill-name-error' : undefined}\n aria-invalid={showNameError}\n className={showNameError ? 'fk:border-destructive focus-visible:fk:ring-destructive' : ''}\n id=\"skill-name\"\n value={name}\n onBlur={() => setTouched((current) => ({ ...current, name: true }))}\n onChange={(event) => setName(event.target.value)}\n />\n {showNameError ? <FieldError id=\"skill-name-error\" message={validation.name} /> : null}\n </div>\n <div>\n <FieldHintLabel\n hint=\"One or two sentences describing when to use this skill. Agents rely on it to decide whether the skill applies to their current task.\"\n htmlFor=\"skill-description\"\n >\n Description\n </FieldHintLabel>\n <Input\n aria-describedby={showDescriptionError ? 'skill-description-error' : undefined}\n aria-invalid={showDescriptionError}\n className={showDescriptionError ? 'fk:border-destructive focus-visible:fk:ring-destructive' : ''}\n id=\"skill-description\"\n placeholder=\"e.g. Rules for writing product descriptions in our brand voice\"\n value={description}\n onBlur={() => setTouched((current) => ({ ...current, description: true }))}\n onChange={(event) => setDescription(event.target.value)}\n />\n {showDescriptionError ? <FieldError id=\"skill-description-error\" message={validation.description} /> : null}\n </div>\n <div>\n <FieldHintLabel\n hint=\"Who can see and use this skill. Space skills are only visible to members of the selected space and only usable by automations in that space; personal skills are private to you.\"\n htmlFor=\"skill-visibility\"\n >\n Visibility\n </FieldHintLabel>\n <div className=\"fk:flex fk:items-center fk:gap-2\">\n <Select\n value={visibility}\n onValueChange={(value) => {\n setVisibility(value === 'space' || value === 'personal' ? value : 'project');\n\n if (value !== 'space') {\n setSpaceId(null);\n }\n }}\n >\n <SelectTrigger aria-label=\"Visibility\" className=\"fk:w-fit fk:min-w-26\" id=\"skill-visibility\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"start\">\n <SelectItem value=\"project\">Project</SelectItem>\n <SelectItem disabled={selectableSpaces.length === 0} value=\"space\">\n Space\n </SelectItem>\n <SelectItem value=\"personal\">Personal</SelectItem>\n </SelectContent>\n </Select>\n {visibility === 'space' ? (\n <Select\n value={spaceId ?? ''}\n onValueChange={(value) => {\n setSpaceId(value || null);\n }}\n >\n <SelectTrigger aria-label=\"Space\" className=\"fk:w-fit fk:min-w-34\">\n <SelectValue placeholder=\"Select a space\" />\n </SelectTrigger>\n <SelectContent align=\"start\">\n {selectableSpaces.map((space) => (\n <SelectItem key={space.id} value={space.id}>\n {space.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : null}\n </div>\n {visibility === 'space' && validation.space ? <FieldError message={validation.space} /> : null}\n </div>\n </div>\n <SkillContentPane\n content={content}\n showContentError={showContentError}\n validationMessage={validation.content}\n onBlur={() => setTouched((current) => ({ ...current, content: true }))}\n onChange={setContent}\n onSave={() => {\n void save();\n }}\n />\n </form>\n </div>\n );\n}\n\nfunction ReadOnlyCodeSkill({\n projectId,\n skill,\n spaceLabelById,\n}: {\n skill: Skill;\n projectId: string;\n spaceLabelById: Map<string, string>;\n}): JSX.Element {\n const canMutate = useCanMutate();\n const navigate = useNavigate();\n const [forking, setForking] = useState(false);\n const [forkError, setForkError] = useState('');\n\n async function fork(): Promise<void> {\n setForking(true);\n setForkError('');\n let response: Response;\n\n try {\n response = await fetch(`/api/flexkit/${projectId}/skills/${skill.id}/fork`, { method: 'POST', credentials: 'include' });\n } catch {\n setForkError('Unable to create a copy. Try again.');\n setForking(false);\n\n return;\n }\n\n setForking(false);\n\n if (!response.ok) {\n setForkError('Unable to create a copy. Check your permissions.');\n\n return;\n }\n\n navigate('..', { relative: 'path' });\n }\n\n return (\n <div className=\"fk:flex fk:h-full fk:min-h-0 fk:min-w-0 fk:flex-col fk:gap-3 fk:pb-3\">\n <SkillPageHeader\n actions={\n <div className=\"fk:flex fk:items-center fk:gap-2\">\n <Badge variant=\"secondary\">{skill.source === 'plugin' ? 'Plugin' : 'Code'}</Badge>\n {skill.source === 'plugin' && <Button type=\"button\" disabled={forking || !canMutate} onClick={() => void fork()} size=\"sm\">Edit a copy</Button>}\n </div>\n }\n title={skill.name}\n />\n <div className=\"fk:flex fk:flex-col fk:h-full fk:px-4 fk:gap-3 fk:max-w-6xl fk:m-auto\">\n <div className=\"fk:shrink-0 fk:rounded-md fk:border fk:bg-muted/30 fk:px-3 fk:py-2 fk:corner-squircle\">\n <p className=\"fk:text-sm fk:font-medium\">Version-controlled skill</p>\n <p className=\"fk:text-sm fk:text-muted-foreground\">\n {skill.source === 'plugin' ? 'This skill is managed by its plugin. Edit a copy to create a personal Studio skill.' : 'Edit this skill in your repository and re-sync it from the Custom Tools settings.'}\n </p>\n </div>\n <div className=\"fk:grid fk:min-w-0 fk:shrink-0 fk:gap-3 fk:lg:grid-cols-[minmax(0,1fr)_minmax(0,1.6fr)_auto]\">\n <div>\n <FieldHintLabel hint=\"Identifying label for this skill\" htmlFor=\"skill-name\">\n Name\n </FieldHintLabel>\n <Input\n className=\"fk:opacity-100!\"\n disabled={true}\n id=\"skill-name\"\n value={skill.name}\n />\n </div>\n <div>\n <FieldHintLabel\n hint=\"One or two sentences describing when to use this skill. Agents rely on it to decide whether the skill applies to their current task.\"\n htmlFor=\"skill-description\"\n >\n Description\n </FieldHintLabel>\n <Input\n className=\"fk:opacity-100!\"\n disabled={true}\n id=\"skill-description\"\n placeholder=\"e.g. Rules for writing product descriptions in our brand voice\"\n value={skill.description}\n />\n </div>\n <div>\n <FieldHintLabel\n hint=\"Who can see and use this skill. Space skills are only visible to members of the selected space and only usable by automations in that space; personal skills are private to you.\"\n htmlFor=\"skill-visibility\"\n >\n Visibility\n </FieldHintLabel>\n <div className=\"fk:flex fk:items-center fk:gap-2\">\n <Select\n disabled={true}\n value={skill.visibility}\n >\n <SelectTrigger aria-label=\"Visibility\" className=\"fk:w-fit fk:min-w-26 fk:opacity-100!\" id=\"skill-visibility\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"start\">\n <SelectItem value=\"project\">Project</SelectItem>\n <SelectItem disabled={!skill.spaceId} value=\"space\">\n Space\n </SelectItem>\n <SelectItem value=\"personal\">Personal</SelectItem>\n </SelectContent>\n </Select>\n {skill.visibility === 'space' ? (\n <Select\n disabled={true}\n value={skill.spaceId ?? ''}\n >\n <SelectTrigger aria-label=\"Space\" className=\"fk:w-fit fk:min-w-34 fk:opacity-100!\">\n <SelectValue placeholder=\"Select a space\" />\n </SelectTrigger>\n <SelectContent align=\"start\">\n <SelectItem value={skill.spaceId ?? ''}>\n {getSkillVisibilityLabel(skill, spaceLabelById)}\n </SelectItem>\n </SelectContent>\n </Select>\n ) : null}\n </div>\n </div>\n </div>\n {forkError && <p role=\"alert\">{forkError}</p>}\n <SkillContentPane content={skill.content} readOnly />\n </div>\n </div>\n );\n}\n\nexport function CreateSkillPage(): JSX.Element {\n const { api, projectId } = useProjectApi();\n const navigate = useNavigate();\n\n if (!projectId || !api) {\n return <PageMessage>Select a project to create skills.</PageMessage>;\n }\n\n return (\n <SkillForm api={api} mode=\"create\" projectId={projectId} onSaved={() => navigate('..', { relative: 'path' })} />\n );\n}\n\nexport function SkillDetailPage(): JSX.Element {\n const { api, projectId } = useProjectApi();\n const { skillId } = useParams<{ skillId: string }>();\n const { data, error, isLoading, mutate } = useSWR<{ skill: Skill }>(\n projectId && skillId ? paths(projectId).skill(skillId) : null,\n fetcher\n );\n const { data: spacesData } = useSWR<{ spaces: ProjectSpace[] }>(projectId ? paths(projectId).spaces : null, fetcher);\n\n if (!projectId || !api || !skillId) {\n return <PageMessage>Select a skill.</PageMessage>;\n }\n\n if (error) {\n return <PageMessage>Failed to load skill.</PageMessage>;\n }\n\n if (isLoading || !data?.skill) {\n return <SkillDetailSkeleton />;\n }\n\n const spaceLabelById = new Map((spacesData?.spaces ?? []).map((space) => [space.id, space.label]));\n\n if (data.skill.source !== 'studio') {\n return <ReadOnlyCodeSkill projectId={projectId} skill={data.skill} spaceLabelById={spaceLabelById} />;\n }\n\n return (\n <SkillForm\n api={api}\n mode=\"edit\"\n projectId={projectId}\n skill={data.skill}\n onSaved={(skill) => {\n if (skill) {\n void mutate({ skill }, { revalidate: false });\n } else {\n void mutate();\n }\n }}\n />\n );\n}\n"]}