fuli-context 0.20.0-beta.8 → 0.20.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.zh-CN.md +1 -0
- package/dist/web/assets/index-DYEE8nDj.js +2 -0
- package/dist/web/index.html +1 -1
- package/docs/agent-apps.md +105 -0
- package/docs/employee-agents.md +1 -1
- package/graph-provider/pyproject.toml +1 -1
- package/native/win32/fuli-win-helper.exe +0 -0
- package/npm-shrinkwrap.json +8 -8
- package/package.json +3 -2
- package/src/agent-apps/activation.js +3 -3
- package/src/agent-apps/app-host.js +2 -0
- package/src/agent-apps/app-launcher.js +25 -0
- package/src/agent-apps/authorization.js +6 -4
- package/src/agent-apps/bounded-wait.js +13 -0
- package/src/agent-apps/{verified-decisions.js → confirmed-decisions.js} +100 -55
- package/src/agent-apps/decision-source.js +17 -17
- package/src/agent-apps/host-identity.js +8 -2
- package/src/agent-apps/instances.js +158 -28
- package/src/agent-apps/operations.js +4 -3
- package/src/agent-apps/run-gate.js +25 -20
- package/src/agent-apps/service.js +39 -16
- package/src/agent-apps/store.js +28 -14
- package/src/agent-apps/trust-terms.js +23 -0
- package/src/agent-apps/trusted-runner.js +136 -0
- package/src/agent-apps/versions.js +5 -4
- package/src/agent-apps/views.js +11 -6
- package/src/agent-tools/agent-app-definitions.js +1 -1
- package/src/agent-tools/interface-catalog.js +2 -2
- package/src/cli/app-command.js +46 -61
- package/src/cli/terminal-io.js +22 -0
- package/src/graphiti/federated-application.js +1 -1
- package/src/presence/platforms.js +3 -2
- package/src/presence/port.js +2 -1
- package/src/presence/windows-helper-pin.js +1 -1
- package/dist/web/assets/index-BczJo3GN.js +0 -2
- package/src/agent-apps/isolation.js +0 -23
package/README.md
CHANGED
|
@@ -742,6 +742,8 @@ Tonborg's workbench shows decisions and feedback. **Project Agents → Hire an A
|
|
|
742
742
|
Recruitment reuses a durable identity with separate project assignments. An installed employee workbench,
|
|
743
743
|
API and A2A share the FULI port; existing FULI MCP clients discover and call its tools. Recruitment does not
|
|
744
744
|
start a model or rewrite client settings. See the [employee package and extension contract](docs/employee-agents.md).
|
|
745
|
+
Agents can also grow small [Agent apps](docs/agent-apps.md); in this version an approved app runs
|
|
746
|
+
unsandboxed with your account's permissions, after you confirm it with `fl app approve` in a terminal.
|
|
745
747
|
|
|
746
748
|
Project Agent identities remain control-plane records rather than one resident process per identity.
|
|
747
749
|
Roles now keep versioned, project-private working memory in the same Neo4j Provider. Task entry
|
package/README.zh-CN.md
CHANGED
|
@@ -632,6 +632,7 @@ Jefa(项目经理)、Bole(AR,Agent Resources)和 Tonborg(决策员
|
|
|
632
632
|
“Agents → 聘请 Agent”提供其他可复用的员工模板。招募复用持久身份,
|
|
633
633
|
按项目单独任职;安装员工包后,侧栏工作台与 API/A2A 共用 FULI 端口,已有 FULI MCP 可发现和调用员工工具。
|
|
634
634
|
招募不等于启动模型,也不改写已有客户端配置。详见[员工包安装与扩展协议](docs/employee-agents.md)。
|
|
635
|
+
Agent 还可以自己做小的 [Agent 应用](docs/agent-apps.md);本版本没有沙箱,经你在终端用 `fl app approve` 确认后,应用以你的账户权限运行。
|
|
635
636
|
|
|
636
637
|
Project Agent 身份仍是控制面记录,不会每个身份常驻一个进程。角色工作记忆按项目私有、
|
|
637
638
|
版本化地保存在同一个 Neo4j Provider 中;任务入口恢复唯一负责人,结束检查跨 MCP 进程持久化。
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/SharedJefaReportPage-_f2bnFY-.js","assets/_plugin-vue_export-helper-Crd8aFkh.js","assets/useApi-CROJJdhE-BMswzZdS.js","assets/button-B4gCj85U.js","assets/GrowthLoading-DssogOkP.js","assets/GrowthLoading-B_QrPkEy.css","assets/Card-96u8qomm.js","assets/shared-report-o1Tvfyn-.js","assets/client-Cg0bLxrO.js","assets/UiIcon-DSkB5Juh.js","assets/UiIcon-EWCwhyKc.css","assets/ui-BkbPVq3y.js","assets/UiDialog-CU8nqGKC.js","assets/UiIconButton-Bgy8Hoy4.js","assets/UiSegmented-BwkPHeLK.js","assets/UiSelect-CW3HNsRZ.js","assets/UiSelect-CiSPw-7k.css","assets/UiToggle--Z_LpW41.js","assets/UiToggle-B2sPCVZe.css","assets/UiWeight-D8U0orbz.js","assets/UiWeight-aUNtanHz.css","assets/ui-CE38wkv4.css","assets/preload-helper-BLdHbfdN.js","assets/task-board-model-BohbBuwF.js","assets/ProjectScopePicker-GjK7Hm4N.js","assets/ProjectScopePicker-BM3MbIYV.css","assets/board-task-peek-C7CQ78B5.js","assets/shared-report-eUYPCJTS.css","assets/SharedJefaReportPage-CcD-06mK.css","assets/RoundtablesPage-Bd3XCn7B.js","assets/console-k05BnLkZ.js","assets/vue-router-BUjBh_Iw.js","assets/agent-identity-color-RqpT7gtx.js","assets/BackLink-Dgc1V1EN.js","assets/task-updates-ChvjLQXV.js","assets/RoundtablesPage-BmmsB1mW.css","assets/OverviewPage-E0tfzQRr.js","assets/project-origin-DI7ft7I8.js","assets/design-lab-CJiqHzsm.js","assets/attention-store-dDH6VA6Z.js","assets/profile-model-kCmPHrmk.js","assets/paths-CDREouhi.js","assets/date-time-Clwafva-.js","assets/badge-BnU2j9Nh.js","assets/dist-2CLFk118.js","assets/workbench-model-CaNC35vW.js","assets/agent-work-summary-BIZoVGaT.js","assets/task-evidence-i9SDhd3E.js","assets/task-labels-dW28Ybet.js","assets/OverviewPage-CpHmwB7u.css","assets/PersonalProfilePage-o5Gpo9nJ.js","assets/useMinimumLoadingDisplay-DEBBYuGI.js","assets/model-YYqd0CSe.js","assets/model-DPykou4S.js","assets/KnowledgeEditDialog-uAzeQbMB.js","assets/identity-NbL1GGSB.js","assets/KnowledgeEditDialog-D0se__D4.css","assets/KnowledgePeek-BD2zoQqA.js","assets/dialog-DQaUWk4W.js","assets/Presence-Bk6m9rvx.js","assets/Teleport-D5d1fEVm.js","assets/handleAndDispatchCustomEvent-Bng2rRDf.js","assets/UiDisclosure-DbxNZe0B.js","assets/conversation-launcher-settings-C745vZJa.js","assets/KnowledgePeek-DEo6IbBP.css","assets/useKnowledgeItemPeek-CGzVMWJz.js","assets/useFocusReturn-DQOtrYO8.js","assets/useRoutePeek-R9W605pr.js","assets/personal-profile-graph-BEjSAQMe.js","assets/PersonalProfilePage-CfqsnB1K.css","assets/WritingTastePage-BsekLhC3.js","assets/CardHeader-4je7E12I.js","assets/CardTitle-bjMusOR6.js","assets/WritingTastePage-Dh1qW6bK.css","assets/PersonalProjectsPage-Boj9kG6I.js","assets/DialogFooter-DwgFgHdH.js","assets/KnowledgeWorkspace-CgFI31jK.js","assets/TabsTrigger-BFj6S2XJ.js","assets/RovingFocusGroup-DyZDm-Bn.js","assets/RovingFocusItem-BKyXKG9n.js","assets/Input-DHF3Ivr3.js","assets/debounce-CFk-gEUl.js","assets/AgentName-CXf8heW-.js","assets/AgentName-BQTFCWn0.css","assets/project-team-api-BZMMPuUd.js","assets/CreateProjectDialog-BDwT_wZd.js","assets/CreateProjectDialog-BaPfiS1T.css","assets/VirtualDirectoryList-BT099Zuk.js","assets/VirtualDirectoryList-pgDELOEf.css","assets/project-capture-BUtkhbr1.js","assets/KnowledgeWorkspace-C6l_yvWO.css","assets/PersonalProjectsPage-aU1rApzX.css","assets/KnowledgeOrganizerPage-BVLMc2jL.js","assets/KnowledgeOrganizerPage-7VC_JAWQ.css","assets/AgentsDirectoryPage-LU-bRYPw.js","assets/agent-pins-CFO-xYmz.js","assets/avatars-CUyfvsKO.js","assets/useAgentRecords-D6BTApmV.js","assets/agent-occupation-BooDHzf0.js","assets/occupation-catalog-JHFMVvBn.js","assets/agent-profile.css_vue_type_style_index_0_src_true_lang-BKk2RVxy.js","assets/agent-profile-Bi--2zRQ.css","assets/orchestration-filters-B7ZbjZKo.js","assets/ProjectAgentFirstTask-CXKvWwhZ.js","assets/ProjectAgentFirstTask-BVDcaNNi.css","assets/UnassignedConversationsPanel-BeWzhuBr.js","assets/short-ids-BpNwVgnt.js","assets/EmployeeRecruitDialog-DjX_wOWx.js","assets/EmployeeRecruitDialog-C6ADVxkQ.css","assets/AgentsDirectoryPage-DvPJNJm-.css","assets/AgentProfilePage-D0YyiAA6.js","assets/TabsContent-CTM6GBGk.js","assets/page-title-BawJ25Bw.js","assets/TaskExecutionPlan-D_MbMVvj.js","assets/motion-preference-CxKthhLy.js","assets/TaskExecutionPlan-C9kJJJKk.css","assets/AgentProfilePage-B2yMnmQP.css","assets/OccupationsPage-CHgGGvDu.js","assets/TextField-DUZTbKVz.js","assets/TextField-CM9C-zEI.css","assets/OccupationsPage-B55DftFp.css","assets/TaskSchedulesPage-Dd38ntqQ.js","assets/dropdown-menu-CN5wjWUD.js","assets/useArrowNavigation-LczgkNfS.js","assets/PopperContent-BDOio_9z.js","assets/TaskSchedulesPage-CDalUfNj.css","assets/ProjectAgentsPage-DHTo0uNy.js","assets/ProjectAgentDialog-C1_KluEx.js","assets/ProjectAgentDialog-DHP7BfAf.css","assets/ProjectAgentsPage-DKNDXWow.css","assets/ProjectAgentDetailPage-Cyl3ZPBO.js","assets/ProjectAgentDetailPage-Ns2ATys8.css","assets/EmployeeWorkbenchPage-DWhBevwY.js","assets/judgment-types-DfSuVLnV.js","assets/EmployeeWorkbenchPage-l_LYqBnr.css","assets/PublicProjectsPage-BuJo0ReR.js","assets/PublicProjectsPage-yA6Md4oM.css","assets/KnowledgePage-8ct5iO0F.js","assets/KnowledgeItemEditPage-Cj5uNVo6.js","assets/RadioGroupItem-DxktHt0c.js","assets/checkbox-CzVOT2cF.js","assets/model-BsfqK9w_.js","assets/field-6gOLsuT_.js","assets/Label-DM1yZ2CL.js","assets/model-BjNAHvfb.js","assets/quick-edit-api-CTMfc9uz.js","assets/KnowledgeHardDeleteSection-qGeE1YrK.js","assets/accordion-C-pFa1cg.js","assets/KnowledgeItemSummaryCard-CeOSN36n.js","assets/SessionRecordsPage-CvGaB3h3.js","assets/model-2BvryZbU.js","assets/SessionMigrationPage-CQhrJ1OQ.js","assets/TagVocabularyPage-Cp1UVDoe.js","assets/KnowledgeTurnReceiptPage-Yn3jhDyx.js","assets/InboxPage-BF38gnSV.js","assets/InboxPage-fFg4gETv.css","assets/ConnectionsPage-EFMP-UeV.js","assets/SettingsPage-OasIZiIz.js","assets/SettingsPage-DG3ialW3.css","assets/ModelSettingsPage-5RkvgNYN.js","assets/model-DrZFCNN6.js","assets/ModelSettingsPage-BqtWIKEA.css","assets/DataFormatPage-PxwqDWeZ.js","assets/DataFormatPage-DERqhmng.css","assets/CaptureChangePage-DcJKvaGf.js","assets/CaptureChangePage-C833Eiqu.css","assets/AboutPage-BybzKsx-.js","assets/fuli-logo-Bu9WBuQe.js","assets/AboutPage-Dy3drTbS.css","assets/NotFoundPage-BUUf2-MZ.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{$ as e,A as t,C as n,D as r,Dt as i,E as a,G as o,J as s,M as c,Mt as l,T as u,U as d,V as f,X as p,Y as m,a as h,b as g,d as _,i as v,it as y,jt as b,k as x,kt as S,n as C,o as w,ot as T,r as E,rt as D,s as O,t as k,v as A,vt as j,w as M,xt as N}from"./_plugin-vue_export-helper-Crd8aFkh.js";import{n as P,t as F}from"./console-k05BnLkZ.js";import{m as I}from"./useApi-CROJJdhE-BMswzZdS.js";import{i as ee,n as L,r as te,t as R}from"./vue-router-BUjBh_Iw.js";import{t as z}from"./button-B4gCj85U.js";import{t as ne}from"./checkbox-CzVOT2cF.js";import{a as re,i as ie,n as ae,r as oe,t as se}from"./dialog-DQaUWk4W.js";import{n as ce,t as le}from"./RadioGroupItem-DxktHt0c.js";import{a as ue,r as de}from"./client-Cg0bLxrO.js";import{i as fe,n as pe,r as me,t as he}from"./agent-pins-CFO-xYmz.js";import{t as ge}from"./UiIcon-DSkB5Juh.js";import{t as _e}from"./DialogFooter-DwgFgHdH.js";import{i as ve,n as ye,r as be}from"./project-origin-DI7ft7I8.js";import{i as xe,n as Se,t as Ce}from"./motion-preference-CxKthhLy.js";import{r as we}from"./ui-BkbPVq3y.js";import{t as B}from"./UiIconButton-Bgy8Hoy4.js";import{t as V}from"./UiSegmented-BwkPHeLK.js";import{t as Te}from"./UiToggle--Z_LpW41.js";import{i as Ee,n as De,r as H,t as Oe}from"./design-lab-CJiqHzsm.js";import{r as ke}from"./attention-store-dDH6VA6Z.js";import{t as Ae}from"./fuli-logo-Bu9WBuQe.js";import{t as je}from"./avatars-CUyfvsKO.js";import{t as Me}from"./agent-identity-color-RqpT7gtx.js";import{n as Ne,t as U}from"./profile-model-kCmPHrmk.js";import{n as Pe}from"./useAgentRecords-D6BTApmV.js";import{n as Fe,t as Ie}from"./paths-CDREouhi.js";import{t as Le}from"./page-title-BawJ25Bw.js";import{t as W}from"./preload-helper-BLdHbfdN.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var Re=[`aria-label`],ze=[`lang`,`aria-label`,`aria-pressed`,`onClick`],Be=c({__name:`LocaleSwitcher`,setup(e){let t=n(()=>E()),a={"zh-CN":`中`,"en-US":`EN`};function o(e){e!==t.value&&w(e)}return(e,n)=>(s(),r(`div`,{class:`locale-switcher`,role:`group`,"aria-label":i(O)(`common.language.label`)},[(s(!0),r(g,null,p(i(C),e=>(s(),r(`button`,{key:e,type:`button`,lang:e,"aria-label":i(O)(e===`zh-CN`?`common.language.chinese`:`common.language.english`),"aria-pressed":t.value===e,onClick:t=>o(e)},l(a[e]),9,ze))),128))],8,Re))}}),G=N(null);function Ve(e){let t=e.onError((t,n)=>{let r=e.resolve(n).href;r.startsWith(`/`)&&!r.startsWith(`//`)&&(G.value={href:r,resourceFailure:/dynamically imported module|module script|loading chunk|preload css|importing a module/i.test(String(t))})}),n=e.afterEach((e,t,n)=>{n||(G.value=null)});return()=>{t(),n()}}var He={key:0,class:`navigation-recovery`,role:`alert`},Ue=[`href`],We=k(c({__name:`NavigationRecovery`,setup(e){return(e,n)=>i(G)?(s(),r(`div`,He,[M(`div`,null,[M(`strong`,null,l(i(O)(`routes.loadFailure.title`)),1),M(`p`,null,l(i(O)(i(G).resourceFailure?`routes.loadFailure.resources`:`routes.loadFailure.message`)),1)]),t(i(z),{"as-child":``,variant:`outline`},{default:T(()=>[M(`a`,{href:i(G).href},l(i(O)(`routes.loadFailure.reload`)),9,Ue)]),_:1}),t(i(z),{variant:`ghost`,onClick:n[0]||=e=>G.value=null},{default:T(()=>[x(l(i(O)(`routes.loadFailure.dismiss`)),1)]),_:1})])):a(``,!0)}}),[[`__scopeId`,`data-v-96f1f3c2`]]);function Ge(e){return e?e.enabled?(e.projectMode??`all`)===`all`?`all`:e.projectMode===`selected`?`selected`:null:`off`:null}var Ke=[`data-capture-scope`,`data-selected`],qe={key:0,class:`onboarding-projects`,"data-capture-scope-projects":``},Je={class:`onboarding-projects-label`},Ye={key:0,class:`onboarding-note`},Xe={key:1},Ze=[`data-capture-scope-project`],Qe={class:`onboarding-project-name`},$e={key:1,class:`onboarding-error`,role:`alert`,"data-capture-scope-error":``},et=k(c({__name:`CaptureOnboardingDialog`,setup(e){let o=[`all`,`selected`,`off`],c=F(),d=j(!1),f=n(()=>c.state?.captureOnboarding?.ask===!0&&!d.value),m=j(null),h=j({}),_=j(null),v=n(()=>_.value!==null),y=j(``),b=n(()=>c.activePersonalSpace?.id??``),S=n(()=>be((c.state?.personalProjects??[]).filter(e=>e.personal_space_id===b.value&&ye(e))).map(e=>({id:e.project_id,name:ve(e)})));function C(e){!e&&!v.value&&(d.value=!0)}function w(e){m.value=e,y.value=``}async function E(){let e=m.value;if(e&&!v.value){_.value=`saving`,y.value=``;try{let t=await c.answerCaptureScope(e===`selected`?{choice:e,selectedProjectIds:S.value.filter(e=>h.value[e.id]).map(e=>e.id)}:{choice:e});c.notify(t.status===`answered`?O(`capture.onboarding.saved.${t.choice}`):O(`capture.onboarding.gone`))}catch(e){await D(de(e))}finally{_.value=null}}}async function D(e){_.value=`checking`,y.value=O(`capture.onboarding.unconfirmed`);try{let t=await c.readCaptureOnboarding();if(t.ask){y.value=O(`capture.onboarding.notSaved`,{reason:e});return}y.value=``;let n=Ge(t.capturePolicy);c.notify(O(n?`capture.onboarding.saved.${n}`:`capture.onboarding.gone`))}catch(e){y.value=O(`capture.onboarding.unknown`,{reason:de(e)})}}return(e,n)=>(s(),u(i(re),{open:f.value,"onUpdate:open":C},{default:T(()=>[t(i(ie),{"data-capture-onboarding":``,onPointerDownOutside:n[1]||=A(()=>{},[`prevent`])},{default:T(()=>[t(i(ae),null,{default:T(()=>[t(i(se),null,{default:T(()=>[x(l(i(O)(`capture.onboarding.title`)),1)]),_:1}),t(i(oe),null,{default:T(()=>[x(l(i(O)(`capture.onboarding.description`)),1)]),_:1})]),_:1}),t(i(ce),{"model-value":m.value??void 0,"aria-label":i(O)(`capture.onboarding.choicesLabel`),class:`grid gap-2`,disabled:v.value,"onUpdate:modelValue":w},{default:T(()=>[(s(),r(g,null,p(o,e=>M(`label`,{key:e,class:`onboarding-option`,"data-capture-scope":e,"data-selected":m.value===e||void 0},[t(i(le),{value:e},null,8,[`value`]),M(`span`,null,[M(`strong`,null,l(i(O)(`capture.onboarding.choices.${e}`)),1),M(`small`,null,l(i(O)(`capture.onboarding.hints.${e}`)),1)])],8,Ke)),64))]),_:1},8,[`model-value`,`aria-label`,`disabled`]),m.value===`selected`?(s(),r(`section`,qe,[M(`span`,Je,l(i(O)(`capture.onboarding.projectsLabel`)),1),S.value.length?(s(),r(`ul`,Xe,[(s(!0),r(g,null,p(S.value,e=>(s(),r(`li`,{key:e.id,"data-capture-scope-project":e.id},[M(`label`,null,[t(i(ne),{"model-value":h.value[e.id]===!0,disabled:v.value,"onUpdate:modelValue":t=>h.value={...h.value,[e.id]:t===!0}},null,8,[`model-value`,`disabled`,`onUpdate:modelValue`]),M(`span`,Qe,l(e.name),1)])],8,Ze))),128))])):(s(),r(`p`,Ye,l(i(O)(`capture.onboarding.noProjects`)),1))])):a(``,!0),y.value?(s(),r(`p`,$e,l(y.value),1)):a(``,!0),t(i(_e),null,{default:T(()=>[t(i(z),{variant:`ghost`,disabled:v.value,"data-capture-scope-later":``,onClick:n[0]||=e=>C(!1)},{default:T(()=>[x(l(i(O)(`capture.onboarding.later`)),1)]),_:1},8,[`disabled`]),t(i(z),{disabled:!m.value,loading:v.value,"loading-label":i(O)(_.value===`checking`?`capture.onboarding.checking`:`capture.onboarding.saving`),"data-capture-scope-save":``,onClick:E},{default:T(()=>[x(l(i(O)(`capture.onboarding.save`)),1)]),_:1},8,[`disabled`,`loading`,`loading-label`])]),_:1})]),_:1})]),_:1},8,[`open`]))}}),[[`__scopeId`,`data-v-257b023c`]]),tt=`fuli.palette`,nt=[`jade`,`ink`,`gold`,`indigo`,`sprout`],K=`jade`,q=j(K),rt=e=>nt.includes(e);function it(){if(typeof window>`u`)return K;try{let e=window.localStorage.getItem(tt);return rt(e)?e:K}catch{return K}}function at(e){typeof document<`u`&&(e===K?delete document.documentElement.dataset.palette:document.documentElement.dataset.palette=e)}function ot(){q.value=it(),at(q.value)}function st(e){if(q.value=e,at(e),typeof window<`u`)try{e===K?window.localStorage.removeItem(tt):window.localStorage.setItem(tt,e)}catch{}}var ct=[{id:`current`,labelKey:`designLab.workbench.current`},{id:`focus`,labelKey:`workbench.variants.focus`},{id:`board`,labelKey:`workbench.variants.board`},{id:`timeline`,labelKey:`workbench.variants.timeline`},{id:`constellation`,labelKey:`workbench.variants.constellation`},{id:`office`,labelKey:`workbench.variants.office`},{id:`galaxy3d`,labelKey:`workbench.variants.galaxy3d`}],lt=[`aria-label`],ut=[`title`],dt={class:`design-lab-hint`},ft={class:`design-lab-group`},pt={class:`design-lab-label`},mt={class:`design-lab-group`},ht={class:`design-lab-label`},gt={class:`design-lab-group`},_t={class:`design-lab-label`},vt={class:`design-lab-row`},yt={class:`design-lab-row`},bt={class:`design-lab-row`},xt={class:`design-lab-row`},St={key:0,class:`design-lab-group`},Ct={class:`design-lab-label`},wt={class:`design-lab-foot`},Tt=4,Et=k(c({__name:`DesignLabPanel`,setup(e){let c=j(null),f=n(()=>nt.map(e=>({value:e,label:O(`designLab.palettes.${e}`),swatch:`var(--palette-swatch-${e})`}))),m=n(()=>De.map(e=>({value:e,label:O(`designLab.transitions.${e}`)}))),h=[`cards`,`density`,`radius`],_=e=>Oe[e].map(t=>({value:t,label:O(`designLab.choices.${e}.${t}`)})),v=n(()=>ct.map(({id:e,labelKey:t})=>({value:e,label:O(t)}))),y=n(()=>H.value.x===null||H.value.y===null?void 0:{left:`${H.value.x}px`,top:`${H.value.y}px`,right:`auto`,bottom:`auto`}),S=null;function C(e){if(!c.value||e.target.closest(`button`))return;let t=c.value.getBoundingClientRect();S={dx:e.clientX-t.left,dy:e.clientY-t.top},window.addEventListener(`pointermove`,w),window.addEventListener(`pointerup`,E,{once:!0})}function w(e){if(!S||!c.value)return;let{width:t,height:n}=c.value.getBoundingClientRect();H.value.x=Math.round(Math.min(Math.max(0,e.clientX-S.dx),window.innerWidth-t)),H.value.y=Math.round(Math.min(Math.max(0,e.clientY-S.dy),window.innerHeight-n))}function E(){S=null,window.removeEventListener(`pointermove`,w)}d(E);let D=j(null),k=n(()=>D.value?{left:`${D.value.x}px`,top:`${D.value.y}px`,right:`auto`,bottom:`auto`}:void 0),A=null,N=!1;function P(e){let t=e.currentTarget.getBoundingClientRect();A={startX:e.clientX,startY:e.clientY,dx:e.clientX-t.left,dy:e.clientY-t.top,width:t.width,height:t.height,moved:!1},window.addEventListener(`pointermove`,F),window.addEventListener(`pointerup`,I,{once:!0})}function F(e){A&&(!A.moved&&Math.hypot(e.clientX-A.startX,e.clientY-A.startY)<Tt||(A.moved=!0,D.value={x:Math.round(Math.min(Math.max(0,e.clientX-A.dx),window.innerWidth-A.width)),y:Math.round(Math.min(Math.max(0,e.clientY-A.dy),window.innerHeight-A.height))}))}function I(){N=!!A?.moved,A=null,window.removeEventListener(`pointermove`,F)}function ee(){N?N=!1:H.value.open=!0}let L=()=>{D.value=null};o(()=>window.addEventListener(`resize`,L)),d(()=>{I(),window.removeEventListener(`resize`,L)});function te(){Ee(),st(`jade`),xe(`system`)}return(e,n)=>i(H).open?(s(),r(`section`,{key:1,ref_key:`panel`,ref:c,class:`design-lab`,style:b(y.value),"aria-label":i(O)(`designLab.title`),"data-design-lab":``},[M(`header`,{class:`design-lab-head`,title:i(O)(`designLab.drag`),onPointerdown:C},[M(`strong`,null,l(i(O)(`designLab.title`)),1),t(i(B),{icon:`close`,size:`sm`,label:i(O)(`designLab.close`),"data-design-lab-close":``,onClick:n[0]||=e=>i(H).open=!1},null,8,[`label`])],40,ut),M(`p`,dt,l(i(O)(`designLab.hint`)),1),M(`div`,ft,[M(`span`,pt,l(i(O)(`designLab.palette`)),1),t(i(V),{class:`design-lab-choices`,"data-lab-palette":``,"model-value":i(q),options:f.value,label:i(O)(`designLab.palette`),"onUpdate:modelValue":i(st)},null,8,[`model-value`,`options`,`label`,`onUpdate:modelValue`])]),M(`div`,mt,[M(`span`,ht,l(i(O)(`designLab.look`)),1),(s(),r(g,null,p(h,e=>M(`div`,{key:e,class:`design-lab-row`},[M(`span`,null,l(i(O)(`designLab.choices.${e}.label`)),1),t(i(V),{modelValue:i(H).choices[e],"onUpdate:modelValue":t=>i(H).choices[e]=t,"data-lab-choice":e,options:_(e),label:i(O)(`designLab.choices.${e}.label`)},null,8,[`modelValue`,`onUpdate:modelValue`,`data-lab-choice`,`options`,`label`])])),64))]),M(`div`,gt,[M(`span`,_t,l(i(O)(`designLab.motion`)),1),M(`label`,vt,[M(`span`,null,l(i(O)(`designLab.reduceMotion`)),1),t(i(Te),{"model-value":i(Se)===`reduced`,label:i(O)(`designLab.reduceMotion`),"onUpdate:modelValue":n[1]||=e=>i(xe)(e?`reduced`:`system`)},null,8,[`model-value`,`label`])]),M(`div`,yt,[M(`span`,null,l(i(O)(`designLab.transition`)),1),t(i(V),{modelValue:i(H).transition,"onUpdate:modelValue":n[2]||=e=>i(H).transition=e,"data-lab-transition":``,options:m.value,label:i(O)(`designLab.transition`)},null,8,[`modelValue`,`options`,`label`])]),M(`div`,bt,[M(`span`,null,l(i(O)(`designLab.choices.ring.label`)),1),t(i(V),{modelValue:i(H).choices.ring,"onUpdate:modelValue":n[3]||=e=>i(H).choices.ring=e,"data-lab-choice":`ring`,options:_(`ring`),label:i(O)(`designLab.choices.ring.label`)},null,8,[`modelValue`,`options`,`label`])]),M(`label`,xt,[M(`span`,null,l(i(O)(`designLab.cardLift`)),1),t(i(Te),{modelValue:i(H).cardLift,"onUpdate:modelValue":n[4]||=e=>i(H).cardLift=e,"data-lab-lift":``,label:i(O)(`designLab.cardLift`)},null,8,[`modelValue`,`label`])])]),v.value.length>1?(s(),r(`div`,St,[M(`span`,Ct,l(i(O)(`designLab.workbench.title`)),1),t(i(V),{modelValue:i(H).workbench,"onUpdate:modelValue":n[5]||=e=>i(H).workbench=e,class:`design-lab-choices`,"data-lab-workbench":``,options:v.value,label:i(O)(`designLab.workbench.title`)},null,8,[`modelValue`,`options`,`label`])])):a(``,!0),M(`footer`,wt,[t(i(z),{variant:`ghost`,size:`sm`,"data-design-lab-reset":``,onClick:te},{default:T(()=>[x(l(i(O)(`designLab.reset`)),1)]),_:1})])],12,lt)):(s(),u(i(B),{key:0,class:`design-lab-launcher`,icon:`grid`,label:i(O)(`designLab.open`),"data-design-lab-open":``,style:b(k.value),onPointerdown:P,onClick:ee},null,8,[`label`,`style`]))}}),[[`__scopeId`,`data-v-9b25bd4d`]]),J=(e,t,n,r)=>({id:`${e}.${t}`,group:e,labelKey:n,bodyKey:r}),Dt=[...[`known_known`,`known_unknown`,`unknown_known`,`unknown_unknown`].map(e=>J(`quadrant`,e,`knowledge.domain.quadrants.${e}`,`knowledge.domain.quadrants.descriptions.${e}`)),...[`confirmed`,`agent_confirmed`,`ai_reviewed`,`pending`].map(e=>J(`review`,e,`knowledge.domain.reviewStates.${e}`,`glossary.review.${e}`)),...[`taste`,`personality`,`judgment_preference`].map(e=>J(`profile`,e,`knowledge.domain.profiles.${e}`,`glossary.profile.${e}`)),...[`running`,`queued`,`backlog`,`paused`,`blocked`,`awaiting_review`,`awaiting_recruitment`,`none`,`ended`].map(e=>J(`work`,e,`agentRedesign.workStatus.${e}`,`glossary.work.${e}`)),...[`working`,`waiting`,`idle`,`error`].map(e=>J(`presence`,e,`glossary.presence.${e}.label`,`glossary.presence.${e}.body`)),...[`pending`,`agent`,`person`].map(e=>J(`weight`,e,`glossary.weight.${e}.label`,`glossary.weight.${e}.body`))],Ot=new Map(Dt.map(e=>[e.id,e]));function kt(e,t){return t.split(`.`).reduce((e,t)=>e&&typeof e==`object`?e[t]:void 0,h[e])}var Y=e=>e.replace(/\s+/g,` `).trim().toLocaleLowerCase(),At=new Map;for(let e of Dt)for(let t of C){let n=kt(t,e.labelKey);typeof n==`string`&&!At.has(Y(n))&&At.set(Y(n),e)}var jt=24,Mt=4;function Nt(e){if(!(e instanceof Element))return;let t=e.closest(`[data-term]`),n=t?.dataset.term&&Ot.get(t.dataset.term);if(t&&n)return{term:n,element:t};let r=e instanceof HTMLElement?e:e.parentElement;for(let e=0;r&&e<Mt;e++,r=r.parentElement){let e=r.textContent??``;if(e.length>jt)return;let t=At.get(Y(e));if(t)return{term:t,element:r}}}var Pt=j(!1),X=j(!1);function Ft(){return{held:Pt,pinned:X,active:n(()=>Pt.value||X.value),toggle:()=>{X.value=!X.value},reset:()=>{Pt.value=!1,X.value=!1}}}var It={key:0,class:`glossary-live`,role:`status`},Lt=[`data-glossary-term`],Rt=k(c({__name:`GlossaryLayer`,setup(e){let{held:n,pinned:c,active:u}=Ft(),f=j(null),p=null;function m(e){p!==e&&(p?.removeAttribute(`data-glossary-hit`),p=e,p?.setAttribute(`data-glossary-hit`,``))}function h(e){e.key!==`Alt`||e.repeat||(e.preventDefault(),n.value=!0)}function _(e){e.key===`Alt`&&(n.value=!1)}function v(){n.value=!1}function y(e){u.value&&m(Nt(e.target)?.element??null)}function b(e){if(!u.value||e.target instanceof Element&&e.target.closest(`[data-glossary-toggle]`))return;e.preventDefault(),e.stopPropagation();let t=Nt(e.target);t&&(f.value={term:t.term,anchor:t.element.getBoundingClientRect()})}return D(u,e=>{document.documentElement.toggleAttribute(`data-glossary`,e),e||m(null)},{immediate:!0}),o(()=>{window.addEventListener(`keydown`,h),window.addEventListener(`keyup`,_),window.addEventListener(`blur`,v),window.addEventListener(`pointermove`,y,{passive:!0}),window.addEventListener(`click`,b,!0)}),d(()=>{window.removeEventListener(`keydown`,h),window.removeEventListener(`keyup`,_),window.removeEventListener(`blur`,v),window.removeEventListener(`pointermove`,y),window.removeEventListener(`click`,b,!0),n.value=!1,c.value=!1,m(null),document.documentElement.removeAttribute(`data-glossary`)}),(e,n)=>(s(),r(g,null,[i(u)?(s(),r(`span`,It,l(i(O)(`glossary.modeOn`)),1)):a(``,!0),t(i(we),{open:!!f.value,anchor:f.value?.anchor??null,label:f.value?i(O)(f.value.term.labelKey):``,onClose:n[0]||=e=>f.value=null},{default:T(()=>[f.value?(s(),r(`div`,{key:0,class:`glossary-card`,"data-glossary-term":f.value.term.id},[M(`small`,null,l(i(O)(`glossary.groups.${f.value.term.group}`)),1),M(`strong`,null,l(i(O)(f.value.term.labelKey)),1),M(`p`,null,l(i(O)(f.value.term.bodyKey)),1)],8,Lt)):a(``,!0)]),_:1},8,[`open`,`anchor`,`label`])],64))}}),[[`__scopeId`,`data-v-b4734ca4`]]),zt=k(c({__name:`GlossaryToggle`,setup(e){let n=Ft();return(e,r)=>i(n).pinned.value?(s(),u(i(z),{key:0,variant:`outline`,class:`glossary-return`,size:`sm`,"data-glossary-toggle":``,"data-glossary-return":``,"aria-label":i(O)(`glossary.toggleOn`),title:i(O)(`glossary.toggleOn`),onClick:i(n).toggle},{default:T(()=>[t(i(ge),{class:`glossary-return-icon`,name:`tray`,size:16}),x(l(i(O)(`glossary.return`)),1)]),_:1},8,[`aria-label`,`title`,`onClick`])):(s(),u(i(B),{key:1,icon:`info`,"data-glossary-toggle":``,active:i(n).active.value,label:i(O)(`glossary.toggle`),onClick:i(n).toggle},null,8,[`active`,`label`,`onClick`]))}}),[[`__scopeId`,`data-v-f3db80f2`]]);function Bt(e,t=``){let n=typeof e==`string`&&e?e:t;return n&&v.global.te(n)?O(n):n}function Vt(e){if(typeof document>`u`)return;let t=Bt(e,`routes.overview.title`);document.title=`${t} · ${O(`common.brand`)}`}var Z={name:`fuli-context`,version:`0.20.0-beta.9`,description:`Local-first collaboration relationship graph for AI agents.`,type:`module`,files:[`README.zh-CN.md`,`npm-shrinkwrap.json`,`src/`,`native/win32/fuli-win-helper.exe`,`packages/roundtable/package.json`,`packages/roundtable/bin/`,`packages/roundtable/src/`,`dist/web/`,`docs/external-knowledge-architecture.md`,`docs/public-personal-architecture.md`,`docs/project-agent-memory.md`,`docs/agent-conversations-and-collaboration.md`,`docs/employee-agents.md`,`docs/agent-apps.md`,`docs/agent-interface-architecture.md`,`docs/agent-roundtable.md`,`examples/external-knowledge/markdown-folder.mjs`,`graph-provider/Dockerfile`,`graph-provider/pyproject.toml`,`graph-provider/fuli_graph/*.py`,`graph-provider/fuli_graph/**/*.py`,`skills/`,`compose.graphiti.yml`,`docs/judgment-and-autonomy.md`,`docs/client-connections.md`],bin:{fl:`src/cli.js`,fuli:`src/cli.js`},keywords:[`ai-agent`,`mcp`,`context`,`knowledge-graph`,`local-first`,`codex`,`claude-code`],scripts:{mcp:`node src/mcp-server.js`,dev:`run-p dev:server dev:web`,"dev:server":`node src/server.js`,"dev:web":`vite`,build:`run-s typecheck:web build:web`,"build:web":`vite build`,"build:site":`node scripts/build-site.js`,"typecheck:web":`vue-tsc --noEmit -p tsconfig.app.json`,"test:node":`node --test`,"test:web":`vitest run --config vitest.config.ts`,"test:package":`node scripts/package-smoke.js`,"test:neo4j":`node --test --test-concurrency=1 test/agent-dismissal-acceptance.test.js test/conversation-hook-neo4j-acceptance.test.js test/project-agent-memory-acceptance.test.js test/task-memory-checkpoint-atomicity.test.js`,"test:knowledge:live":`node acceptance/knowledge-live.js`,"measure:context-delivery":`node acceptance/context-delivery-replay/run.js`,"test:external-knowledge:live":`node scripts/validate-external-knowledge-live.js`,start:`node src/server.js`,"graph:setup":`node src/graphiti/setup.js`,"graph:up":`docker compose -f compose.graphiti.yml up -d --build`,"graph:down":`docker compose -f compose.graphiti.yml down`,"test:structure":`node --test test/source-structure.test.js`,pretest:`npm run build:web`,test:`run-s typecheck:web test:node test:web`,prepack:`npm run build`,prepublishOnly:`node scripts/release-gate.js && npm test`},engines:{node:`>=24.12`},repository:{type:`git`,url:`git+https://github.com/JevonsCode/fuli.git`},homepage:`https://jevonscode.github.io/fuli/`,bugs:{url:`https://github.com/JevonsCode/fuli/issues`},publishConfig:{access:`public`},license:`Apache-2.0`,dependencies:{"@a2a-js/sdk":`1.3.0`,"@agentclientprotocol/sdk":`1.5.0`,"@hono/node-server":`2.0.12`,"@modelcontextprotocol/sdk":`^1.31.0`,"@peculiar/x509":`2.1.0`,"jsonc-parser":`3.3.1`,"reflect-metadata":`0.2.2`,"smol-toml":`1.9.1`,zod:`^4.6.7`},devDependencies:{"@atlaskit/pragmatic-drag-and-drop":`4.0.0`,"@atlaskit/pragmatic-drag-and-drop-auto-scroll":`3.2.1`,"@atlaskit/pragmatic-drag-and-drop-hitbox":`3.0.0`,"@tailwindcss/vite":`4.3.3`,"@types/d3":`^7.4.3`,"@types/node":`^24.13.3`,"@types/three":`0.169.0`,"@vitejs/plugin-vue":`^6.0.8`,"@vue/test-utils":`^2.4.11`,"@vueuse/core":`14.4.0`,"brace-expansion":`5.0.12`,"class-variance-authority":`0.7.1`,clsx:`2.1.1`,d3:`^7.9.0`,jsdom:`^29.1.1`,linkedom:`^0.18.12`,"npm-run-all2":`^9.0.2`,pinia:`^4.0.2`,"reka-ui":`2.11.0`,"tailwind-merge":`3.7.0`,tailwindcss:`4.3.3`,three:`0.169.0`,typescript:`~6.0.0`,vite:`^8.1.5`,vitest:`^4.1.12`,vue:`^3.5.42`,"vue-i18n":`^11.4.8`,"vue-router":`^5.2.0`,"vue-tsc":`^3.3.8`},overrides:{"@modelcontextprotocol/sdk":{"@hono/node-server":`2.0.12`},"brace-expansion":`$brace-expansion`,"fast-uri":`3.1.9`,qs:`6.16.1`}}.version,Ht=[`aria-label`],Ut={class:`brand-mark-wrap`},Wt=[`src`],Gt=[`aria-label`,`aria-expanded`],Kt={key:1,class:`brand-copy`},qt={class:`brand-title-row`},Jt={class:`brand-name`},Yt=[`aria-label`,`aria-expanded`],Xt={class:`brand-version`},Zt={key:1,class:`brand-version`},Qt={class:`brand-title-row`},$t={class:`brand-name`},en={class:`brand-version`},tn=[`aria-label`],nn=[`href`],rn=k(c({__name:`BrandEasterEgg`,props:{compact:{type:Boolean,default:!1}},setup(e){let t=e,c=j(null),u=j(null),p=j(0),m=j(!1),h=j(!1),_=j(!1),v=j(null),y=n(()=>v.value?.status===`ready`&&v.value.updateAvailable&&!!v.value.latestVersion),b=n(()=>v.value?.latestVersion??``),x=n(()=>v.value?.packageUrl??`https://www.npmjs.com/package/fuli-context`),C=new AbortController,w=!1,T;function E(){p.value+=1,m.value=!0,clearTimeout(T),t.compact&&(T=setTimeout(D,700))}function D(){m.value=!1}function k(){y.value&&(_.value=!_.value)}function N(e){w=!1,h.value=!1,_.value&&!c.value?.contains(e.target)&&(_.value=!1)}function P(e){e.key===`Tab`&&(w=!0),e.key===`Escape`&&_.value&&(e.preventDefault(),_.value=!1,f(()=>u.value?.focus()))}function F(){h.value=w}function I(){h.value=!1}return o(()=>{window.addEventListener(`pointerdown`,N,!0),window.addEventListener(`keydown`,P,!0),ue(`/api/system/version`,{signal:C.signal}).then(e=>{v.value=e}).catch(()=>{})}),d(()=>{clearTimeout(T),C.abort(),window.removeEventListener(`pointerdown`,N,!0),window.removeEventListener(`keydown`,P,!0)}),(e,n)=>(s(),r(`div`,{ref_key:`root`,ref:c,class:S([`brand-block`,{"is-compact":t.compact,"is-sparkling":m.value,"is-keyboard-focused":h.value}])},[M(`button`,{class:`brand-effect-button`,type:`button`,"aria-label":i(O)(`console.brandEffect.aria`),onClick:E,onFocus:F,onBlur:I},[M(`span`,Ut,[M(`img`,{class:`brand-mark`,src:i(Ae),alt:``,"aria-hidden":`true`},null,8,Wt),m.value?(s(),r(g,{key:0},[t.compact?a(``,!0):(s(),r(`span`,{key:`ripple-${p.value}`,class:`brand-ripple`,"aria-hidden":`true`}))],64)):a(``,!0)])],40,Ht),t.compact&&y.value?(s(),r(`button`,{key:0,ref_key:`versionButton`,ref:u,class:`brand-compact-update`,type:`button`,"aria-label":i(O)(`console.update.aria`,{version:b.value}),"aria-expanded":_.value,"aria-controls":`brand-update-details`,onClick:k},null,8,Gt)):a(``,!0),t.compact?a(``,!0):(s(),r(`span`,Kt,[M(`span`,qt,[M(`span`,Jt,l(i(O)(`common.brand`)),1),y.value?(s(),r(`button`,{key:0,ref_key:`versionButton`,ref:u,class:`brand-version-button`,type:`button`,"aria-label":i(O)(`console.update.aria`,{version:b.value}),"aria-expanded":_.value,"aria-controls":`brand-update-details`,onClick:k},[M(`span`,Xt,`v`+l(i(Z)),1),n[0]||=M(`span`,{class:`brand-update-dot`,"aria-hidden":`true`},null,-1)],8,Yt)):(s(),r(`span`,Zt,`v`+l(i(Z)),1))]),n[1]||=M(`span`,{class:`brand-subtitle`},`Context Graph`,-1),m.value?(s(),r(`span`,{key:`copy-reflection-${p.value}`,class:`brand-copy-reflection`,"aria-hidden":`true`,onAnimationend:A(D,[`self`])},[M(`span`,Qt,[M(`span`,$t,l(i(O)(`common.brand`)),1),M(`span`,en,`v`+l(i(Z)),1)])],32)):a(``,!0)])),_.value?(s(),r(`div`,{key:2,id:`brand-update-details`,class:`brand-update-popover`,role:`dialog`,"aria-label":i(O)(`console.update.title`,{version:b.value})},[M(`strong`,null,l(i(O)(`console.update.title`,{version:b.value})),1),M(`p`,null,l(i(O)(`console.update.copy`)),1),n[2]||=M(`code`,null,`fuli update --yes`,-1),M(`a`,{href:x.value,target:`_blank`,rel:`noopener noreferrer`},l(i(O)(`console.update.npmLink`)),9,nn)],8,tn)):a(``,!0)],2))}}),[[`__scopeId`,`data-v-f0649f93`]]),an=[`aria-label`],on=[`src`],sn={key:0,class:`pinned-rail-name`},cn={key:1,class:`pinned-rail-error`,role:`alert`},ln=k(c({__name:`PinnedAgentsRail`,props:{spaceId:{},expanded:{type:Boolean}},setup(e){let o=e,c=I(),u=n(()=>o.spaceId),d=fe(u),{records:f,error:m,load:h}=Pe(u,d.agentIds),_=n(()=>d.agentIds.value.map(e=>f.value[e]).filter(e=>e!==void 0)),v=n(()=>d.error.value||m.value),y=e=>c.path===Ne(o.spaceId,e);function C(){d.load({force:!0}),h({force:!0})}return(n,o)=>u.value&&_.value.length?(s(),r(`ul`,{key:0,class:S([`pinned-rail`,{"is-expanded":e.expanded}]),"aria-label":i(pe)(`navigation.title`,`pin`)},[(s(!0),r(g,null,p(_.value,n=>(s(),r(`li`,{key:n.agentId},[t(i(R),{class:S([`pinned-rail-link`,{"is-active":y(n.agentId)}]),to:i(Ne)(u.value,n.agentId),"aria-current":y(n.agentId)?`page`:void 0,"aria-label":`${i(U)(n)} · ${i(O)(`agentProfiles.profile`)}`,title:e.expanded?void 0:i(U)(n),"data-pinned-agent":n.agentId},{default:T(()=>[M(`span`,{class:`pinned-rail-portrait`,style:b(i(Me)(n.agentId)),"aria-hidden":`true`},[i(je)(n.agentId)?(s(),r(`img`,{key:0,src:i(je)(n.agentId),alt:``},null,8,on)):(s(),r(g,{key:1},[x(l(n.profile.occupationEmoji||i(U)(n).slice(0,1)),1)],64))],4),e.expanded?(s(),r(`span`,sn,l(i(U)(n)),1)):a(``,!0)]),_:2},1032,[`class`,`to`,`aria-current`,`aria-label`,`title`,`data-pinned-agent`])]))),128))],10,an)):u.value&&e.expanded&&v.value?(s(),r(`div`,cn,[M(`span`,null,l(v.value),1),t(i(z),{variant:`ghost`,size:`sm`,onClick:C},{default:T(()=>[x(l(i(pe)(`retry`,`Retry`)),1)]),_:1})])):a(``,!0)}}),[[`__scopeId`,`data-v-0bebe48a`]]),un=[`aria-label`,`data-expanded`],dn=[`title`],fn={key:0,class:`nav-rail-wordmark`},pn={class:`nav-rail-links`},mn={class:`nav-rail-label`},hn=[`aria-label`],gn=[`aria-label`],_n={class:`nav-rail-foot`},vn=[`title`],yn={key:0,class:`nav-rail-version`,"data-version":``},bn=`fuli.nav.expanded`,xn=k(c({__name:`NavRail`,props:{destinations:{},activeKey:{},attentionCount:{},runtimeReady:{type:Boolean},spaceId:{}},setup(e){let n=e;function o(){try{return localStorage.getItem(bn)!==`0`}catch{return!0}}let c=j(o()),d=I(),f=[`taste`,`personality`,`judgment_preference`],m=e=>d.path===`/preferences`&&d.query.aspect===e,h=()=>!!n.spaceId&&d.path.startsWith(`/agents/${encodeURIComponent(n.spaceId)}/`),_=e=>c.value&&(e===`memory`&&f.some(m)||e===`agents`&&h());return D(c,e=>{try{localStorage.setItem(bn,e?`1`:`0`)}catch{}}),(n,o)=>(s(),r(`nav`,{class:S([`nav-rail`,{"is-expanded":c.value}]),"aria-label":i(O)(`shell.aria`),"data-expanded":c.value},[M(`div`,{class:`nav-rail-brand`,title:c.value?void 0:i(O)(`shell.brand`)},[t(rn,{compact:``}),c.value?(s(),r(`span`,fn,l(i(O)(`shell.brand`)),1)):a(``,!0)],8,dn),M(`ul`,pn,[(s(!0),r(g,null,p(e.destinations,n=>(s(),r(`li`,{key:n.key},[t(i(R),{to:n.to,class:S([`nav-rail-link`,{"is-active":n.key===e.activeKey,"has-active-child":_(n.key)}]),"aria-current":n.key===e.activeKey?`page`:void 0,"aria-label":i(O)(`shell.destinations.${n.key}`),title:c.value?void 0:i(O)(`shell.destinations.${n.key}`),"data-destination":n.key},{default:T(()=>[t(i(ge),{name:n.icon,size:c.value?20:22},null,8,[`name`,`size`]),M(`span`,mn,l(i(O)(`shell.destinations.${n.key}`)),1),n.key===`chat`&&e.attentionCount?(s(),r(`span`,{key:0,class:`nav-rail-badge`,"aria-label":i(O)(`shell.attentionBadge`,{count:e.attentionCount}),"data-attention-badge":``},l(e.attentionCount>9?`9+`:e.attentionCount),9,hn)):a(``,!0)]),_:2},1032,[`to`,`class`,`aria-current`,`aria-label`,`title`,`data-destination`]),c.value&&n.key===`memory`?(s(),r(`ul`,{key:0,class:`nav-rail-sublinks`,"aria-label":i(O)(`shell.profileAria`)},[(s(),r(g,null,p(f,e=>M(`li`,{key:e},[t(i(R),{to:{path:`/preferences`,query:{aspect:e}},class:S([`nav-rail-sublink`,{"is-active":m(e)}]),"aria-current":m(e)?`page`:void 0,"data-aspect":e},{default:T(()=>[x(l(i(O)(`knowledge.domain.profiles.${e}`)),1)]),_:2},1032,[`to`,`class`,`aria-current`,`data-aspect`])])),64))],8,gn)):a(``,!0),n.key===`agents`?(s(),u(ln,{key:1,"space-id":e.spaceId,expanded:c.value},null,8,[`space-id`,`expanded`])):a(``,!0)]))),128))]),M(`div`,_n,[M(`span`,{class:S([`nav-rail-runtime`,{"is-ready":e.runtimeReady}]),role:`status`,title:`${i(O)(e.runtimeReady?`shell.runtimeReady`:`shell.runtimeOffline`)} · v${i(Z)}`},[o[1]||=M(`span`,{class:`nav-rail-runtime-dot`,"aria-hidden":`true`},null,-1),M(`span`,{class:S([`nav-rail-runtime-text`,{"is-visible":!e.runtimeReady}])},l(i(O)(e.runtimeReady?`shell.runtimeReady`:`shell.runtimeOffline`)),3),c.value&&e.runtimeReady?(s(),r(`span`,yn,`v`+l(i(Z)),1)):a(``,!0)],10,vn),t(i(B),{class:`nav-rail-toggle`,icon:c.value?`chevron-left`:`chevron-right`,size:`sm`,label:i(O)(c.value?`shell.collapse`:`shell.expand`),"data-nav-toggle":``,onClick:o[0]||=e=>c.value=!c.value},null,8,[`icon`,`label`])])],10,un))}}),[[`__scopeId`,`data-v-c3e9fba0`]]),Sn=[`aria-label`],Cn=k(c({__name:`SectionTabs`,props:{sections:{},activeKey:{}},setup(e){return(t,n)=>e.sections.length>1?(s(),r(`nav`,{key:0,class:`section-tabs`,"aria-label":i(O)(`shell.sectionsAria`)},[(s(!0),r(g,null,p(e.sections,t=>(s(),u(i(R),{key:t.key,to:t.to,class:S([`section-tab`,{"is-active":t.key===e.activeKey}]),"aria-current":t.key===e.activeKey?`page`:void 0,"data-section":t.key},{default:T(()=>[x(l(i(O)(`shell.sections.${t.key}`)),1)]),_:2},1032,[`to`,`class`,`aria-current`,`data-section`]))),128))],8,Sn)):a(``,!0)}}),[[`__scopeId`,`data-v-dd883582`]]);function wn({spaceId:e,publicProjects:t}){let n=Fe(e,`graph`),r=Ie(`personal`,e,`directory`);return[{key:`constellation`,icon:`constellation`,to:`/`,owns:[`/`],exact:!0,sections:[]},{key:`agents`,icon:`agents`,to:`/project-agents`,owns:[`/project-agents`,`/agents/`,`/employees/`],sections:[{key:`agentDirectory`,to:`/project-agents`,owns:[`/project-agents`,`/agents/`,`/employees/`]},{key:`orchestrate`,to:`/project-agents/manage`,owns:[`/project-agents/manage`]},{key:`schedules`,to:`/project-agents/schedules`,owns:[`/project-agents/schedules`]},{key:`occupations`,to:`/project-agents/occupations`,owns:[`/project-agents/occupations`]}]},{key:`chat`,icon:`chat`,to:`/roundtables`,owns:[`/roundtables`,`/inbox`],sections:[{key:`roundtables`,to:`/roundtables`,owns:[`/roundtables`]},{key:`askedYou`,to:`/inbox`,owns:[`/inbox`]}]},{key:`projects`,icon:`project`,to:n,owns:[`/personal/`,`/public-projects`],sections:[{key:`myProjects`,to:n,owns:[`/personal/`]},...t?[{key:`publicProjects`,to:`/public-projects`,owns:[`/public-projects`]}]:[]]},{key:`memory`,icon:`memory`,to:r,owns:[`/knowledge`,`/preferences`,`/organize`,`/tags`],sections:[{key:`knowledge`,to:r,owns:[`/knowledge`]},{key:`preferences`,to:`/preferences`,owns:[`/preferences`]},{key:`writing`,to:`/preferences/writing`,owns:[`/preferences/writing`]},{key:`organize`,to:`/organize`,owns:[`/organize`]},{key:`tags`,to:`/tags`,owns:[`/tags`]}]},{key:`settings`,icon:`settings`,to:`/settings`,owns:[`/settings`,`/connections`,`/about`],sections:[{key:`settings`,to:`/settings`,owns:[`/settings`]},{key:`connections`,to:`/connections`,owns:[`/connections`]},{key:`about`,to:`/about`,owns:[`/about`]}]}]}function Tn(e,t,n=!1){return e.some(e=>n||e===`/`?t===e:t===e||t.startsWith(e.endsWith(`/`)?e:`${e}/`))}function En(e,t){return e.find(e=>Tn(e.owns,t,e.exact))}function Dn(e,t){return e?.sections.filter(e=>Tn(e.owns,t)).sort((e,t)=>Math.max(...t.owns.map(e=>e.length))-Math.max(...e.owns.map(e=>e.length)))[0]}var On={class:`app-frame`},kn=[`data-layout`],An={class:`app-topbar`},jn={class:`app-topbar-inner`},Mn={class:`app-title`},Nn={class:`app-actions`},Pn={key:0,class:`app-feedback-row`},Fn=[`role`,`aria-live`],In=k(c({__name:`AppShell`,setup(c){let f=F(),p=I(),h=n(()=>f.activePersonalSpace?.id??``),g=n(()=>wn({spaceId:h.value||`current`,publicProjects:f.state?.capabilities?.browsePublicProjects!==!1})),_=n(()=>En(g.value,p.path)),v=n(()=>Dn(_.value,p.path)),b=n(()=>Le.value.path===p.path?Le.value.text:``),x=n(()=>b.value||(_.value&&_.value.sections.length>1&&v.value&&!p.meta.detail?O(`shell.destinations.${_.value.key}`):Bt(p.meta.title,`routes.overview.title`))),C=n(()=>p.meta.layout),w=n(()=>p.meta.detail?[]:_.value?.sections??[]),E=n(()=>p.name!==`overview`&&p.path!==`/preferences`&&!p.path.startsWith(`/roundtables`)&&p.meta.saveBar!==!0);m(he,me(h));let k=ke();D(h,e=>k.setSpace(e),{immediate:!0});let A;function j(){document.visibilityState===`visible`&&!k.loading&&!k.open&&k.refresh()}function N(){f.refresh(),k.loading||k.refresh()}return o(()=>{f.runtimeStatus===`idle`&&f.refresh(),A=setInterval(j,3e4),document.addEventListener(`visibilitychange`,j)}),d(()=>{clearInterval(A),document.removeEventListener(`visibilitychange`,j),k.setSpace(``)}),y(()=>{p.fullPath,Vt(b.value||p.meta.title)}),(n,o)=>(s(),r(`div`,On,[t(xn,{destinations:g.value,"active-key":_.value?.key,"attention-count":i(k).total,"runtime-ready":i(f).runtimeStatus===`ready`,"space-id":h.value},null,8,[`destinations`,`active-key`,`attention-count`,`runtime-ready`,`space-id`]),M(`main`,{class:`app-main`,"data-layout":C.value},[M(`header`,An,[M(`div`,jn,[M(`h1`,Mn,l(x.value),1),t(Cn,{sections:w.value,"active-key":v.value?.key},null,8,[`sections`,`active-key`]),M(`div`,Nn,[t(zt),t(Be),t(i(B),{icon:`refresh`,label:i(O)(`common.actions.refresh`),disabled:i(f).runtimeStatus===`loading`,"data-shell-refresh":``,onClick:N},null,8,[`label`,`disabled`])])])]),t(We),i(f).feedback?(s(),r(`div`,Pn,[M(`div`,{class:S([`feedback feedback-message`,{success:i(f).feedback.tone===`success`}]),role:i(f).feedback.tone===`error`?`alert`:`status`,"aria-live":i(f).feedback.tone===`error`?`assertive`:`polite`},[M(`span`,null,l(i(f).feedback.message),1),t(i(B),{icon:`close`,size:`sm`,label:i(O)(`common.actions.close`),onClick:i(f).clearFeedback},null,8,[`label`,`onClick`])],10,Fn)])):a(``,!0),t(i(L),null,{default:T(({Component:t})=>[(s(),u(e(t)))]),_:1}),t(Rt),t(et)],8,kn),E.value?(s(),u(Et,{key:0})):a(``,!0)]))}}),[[`__scopeId`,`data-v-13f7e717`]]),Ln=c({__name:`App`,setup(e){let t=I();return(e,n)=>i(t).meta.publicReport?(s(),u(i(L),{key:0})):(s(),u(In,{key:1}))}});function Rn(e){let t=e.match(/^#\/knowledge\/([^/?#]+)\/([^/?#]+)\/(entity|relationship)\/([^/?#]+)(?:\?([^#]*))?$/);if(!t)return null;let[,n,r,i,a,o]=t;return`/knowledge/${n}/${r}/directory/${i}/${a}${o?`?${o}`:``}`}var Q=te({history:ee(`/`),routes:[{path:`/reports/jefa`,name:`shared-jefa-report`,component:()=>W(()=>import(`./SharedJefaReportPage-_f2bnFY-.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28])),meta:{publicReport:!0,title:`employees.share.title`}},{path:`/roundtables/chat/:chatId`,name:`roundtable-chat`,component:()=>W(()=>import(`./RoundtablesPage-Bd3XCn7B.js`),__vite__mapDeps([29,1,30,8,2,31,3,4,5,32,33,34,35])),meta:{title:`routes.roundtable.title`,layout:`canvas`}},{path:`/roundtables/:threadId?`,name:`roundtables`,component:()=>W(()=>import(`./RoundtablesPage-Bd3XCn7B.js`),__vite__mapDeps([29,1,30,8,2,31,3,4,5,32,33,34,35])),meta:{title:`routes.roundtable.title`,layout:`canvas`}},{path:`/`,name:`overview`,component:()=>W(()=>import(`./OverviewPage-E0tfzQRr.js`),__vite__mapDeps([36,1,30,8,31,2,3,4,5,37,15,16,38,39,40,41,22,6,42,43,44,45,46,47,48,49])),meta:{title:`routes.overview.title`,layout:`canvas`}},{path:`/preferences`,name:`personal-profile`,component:()=>W(()=>import(`./PersonalProfilePage-o5Gpo9nJ.js`),__vite__mapDeps([50,1,30,8,2,3,4,5,11,9,10,12,13,14,15,16,17,18,19,20,21,51,52,41,53,42,54,55,56,57,58,59,44,60,61,62,63,64,65,66,67,68,69])),meta:{title:`routes.preferences.title`,layout:`canvas`}},{path:`/preferences/writing`,name:`writing-taste`,component:()=>W(()=>import(`./WritingTastePage-BsekLhC3.js`),__vite__mapDeps([70,1,30,8,3,4,5,11,9,10,12,13,14,15,16,17,18,19,20,21,6,71,72,43,44,51,62,53,42,54,55,56,68,73])),meta:{title:`routes.writingTaste.title`,layout:`canvas`}},{path:`/personal/:spaceId/projects/:projectId/:mode/:itemKind/:itemId`,name:`personal-project-item`,component:()=>W(()=>import(`./PersonalProjectsPage-Boj9kG6I.js`),__vite__mapDeps([74,1,30,8,3,4,5,58,59,44,60,61,9,10,75,37,53,42,76,2,31,77,78,79,11,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,54,56,57,63,64,89,90,91])),meta:{title:`routes.personalProjects.title`,layout:`canvas`}},{path:`/personal/:spaceId/projects/:mode/:itemKind/:itemId`,name:`personal-projects-item`,component:()=>W(()=>import(`./PersonalProjectsPage-Boj9kG6I.js`),__vite__mapDeps([74,1,30,8,3,4,5,58,59,44,60,61,9,10,75,37,53,42,76,2,31,77,78,79,11,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,54,56,57,63,64,89,90,91])),meta:{title:`routes.personalProjects.title`,layout:`canvas`,description:`routes.personalProjects.description`}},{path:`/personal/:spaceId/projects/:mode`,name:`personal-projects`,component:()=>W(()=>import(`./PersonalProjectsPage-Boj9kG6I.js`),__vite__mapDeps([74,1,30,8,3,4,5,58,59,44,60,61,9,10,75,37,53,42,76,2,31,77,78,79,11,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,54,56,57,63,64,89,90,91])),meta:{title:`routes.personalProjects.title`,layout:`canvas`,description:`routes.personalProjects.description`}},{path:`/personal/:spaceId/projects/:projectId/:mode`,name:`personal-project`,component:()=>W(()=>import(`./PersonalProjectsPage-Boj9kG6I.js`),__vite__mapDeps([74,1,30,8,3,4,5,58,59,44,60,61,9,10,75,37,53,42,76,2,31,77,78,79,11,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,54,56,57,63,64,89,90,91])),meta:{title:`routes.personalProjects.title`,layout:`canvas`}},{path:`/organize`,name:`knowledge-organizer`,component:()=>W(()=>import(`./KnowledgeOrganizerPage-BVLMc2jL.js`),__vite__mapDeps([92,1,30,8,3,4,5,11,9,10,12,13,14,15,16,17,18,19,20,21,80,59,44,51,55,87,88,53,42,54,56,57,58,60,61,62,63,64,65,66,2,67,93])),meta:{title:`routes.organizer.title`,layout:`canvas`}},{path:`/project-agents`,name:`project-agents`,component:()=>W(()=>import(`./AgentsDirectoryPage-LU-bRYPw.js`),__vite__mapDeps([94,1,30,8,2,31,3,4,5,58,59,44,60,61,9,10,95,37,13,14,15,16,96,32,40,47,97,41,43,82,83,98,99,46,100,101,84,102,103,75,104,66,67,105,42,85,12,86,106,107,39,24,25,108,109])),meta:{title:`routes.projectAgents.title`,layout:`canvas`}},{path:`/agents/:spaceId/:agentId`,name:`agent-profile`,component:()=>W(()=>import(`./AgentProfilePage-D0YyiAA6.js`),__vite__mapDeps([110,1,30,8,2,31,3,4,5,77,59,44,78,79,111,11,9,10,12,13,14,15,16,17,18,19,20,21,96,32,40,47,97,41,112,6,43,33,62,82,83,99,98,113,114,34,115,46,37,100,101,84,48,42,102,116])),meta:{title:`agentProfiles.profile`,layout:`canvas`,detail:!0}},{path:`/project-agents/occupations`,name:`occupations`,component:()=>W(()=>import(`./OccupationsPage-CHgGGvDu.js`),__vite__mapDeps([117,1,30,8,3,4,5,58,59,44,60,61,9,10,75,11,12,13,14,15,16,17,18,19,20,21,43,99,66,2,67,118,119,120])),meta:{title:`occupations.title`,layout:`canvas`}},{path:`/project-agents/schedules`,name:`task-schedules`,component:()=>W(()=>import(`./TaskSchedulesPage-Dd38ntqQ.js`),__vite__mapDeps([121,1,30,8,2,3,4,5,44,58,59,60,61,9,10,122,123,78,124,75,11,12,13,14,15,16,17,18,19,20,21,47,43,48,42,66,67,106,118,119,125])),meta:{title:`taskSchedules.title`,layout:`canvas`}},{path:`/project-agents/manage`,name:`agent-management`,component:()=>W(()=>import(`./ProjectAgentsPage-DHTo0uNy.js`),__vite__mapDeps([126,1,30,8,2,31,3,4,5,58,59,44,60,61,9,10,14,15,16,96,32,40,47,43,100,101,48,42,102,46,37,103,95,75,98,99,104,66,67,107,12,39,41,24,25,108,127,128,129])),meta:{title:`shell.sections.orchestrate`,layout:`canvas`}},{path:`/project-agents/manage/:spaceId/:agentId`,name:`agent-management-detail`,component:()=>W(()=>import(`./ProjectAgentDetailPage-Cyl3ZPBO.js`),__vite__mapDeps([130,1,30,8,2,31,3,4,5,77,59,44,78,79,111,12,15,16,96,32,40,47,112,6,42,43,33,113,114,34,115,46,37,100,101,48,102,107,39,41,24,25,108,127,128,131])),meta:{title:`projectAgents.pageTitle`,layout:`canvas`,detail:!0}},{path:`/employees/:templateId`,name:`employee-workbench`,component:()=>W(()=>import(`./EmployeeWorkbenchPage-DWhBevwY.js`),__vite__mapDeps([132,1,30,8,2,31,3,4,5,77,59,44,78,79,111,9,10,37,12,14,15,16,96,40,112,42,23,43,80,33,82,83,100,101,48,47,67,105,85,86,106,107,39,41,24,25,108,26,7,11,13,17,18,19,20,21,22,27,133,134])),meta:{title:`routes.employeeWorkbench.title`,layout:`canvas`,detail:!0}},{path:`/public-projects`,name:`public-projects`,component:()=>W(()=>import(`./PublicProjectsPage-BuJo0ReR.js`),__vite__mapDeps([135,1,30,8,2,3,4,5,58,59,44,60,61,9,10,75,12,15,16,41,6,72,42,43,66,67,55,53,136])),meta:{title:`routes.publicProjects.title`,description:`routes.publicProjects.description`,layout:`canvas`}},{path:`/knowledge`,name:`knowledge-default`,component:()=>W(()=>import(`./KnowledgePage-8ct5iO0F.js`),__vite__mapDeps([137,1,76,30,8,2,31,3,4,5,77,59,44,78,79,37,11,9,10,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,53,42,54,56,57,58,60,61,63,64,89,90])),meta:{title:`routes.knowledge.title`,layout:`canvas`}},{path:`/knowledge/item/:spaceId/:itemKind(entity|relationship)/:itemId`,name:`knowledge-item-edit`,component:()=>W(()=>import(`./KnowledgeItemEditPage-Cj5uNVo6.js`),__vite__mapDeps([138,1,30,8,2,31,3,4,5,59,44,58,60,61,9,10,139,140,78,79,75,13,15,16,112,6,71,72,42,43,80,51,141,142,143,33,52,41,144,66,67,145,146,147,123,148,19,20])),meta:{title:`routes.knowledgeItem.title`,layout:`form`,detail:!0}},{path:`/s/:sessionId`,name:`session-records`,component:()=>W(()=>import(`./SessionRecordsPage-CvGaB3h3.js`),__vite__mapDeps([149,1,30,8,2,31,3,4,5,58,59,44,60,61,9,10,75,43,51,52,41,144,42,150,66,67,146,140,78,79,147,123,6,80,142,143,148,19,20])),meta:{title:`routes.sessionRecords.title`,layout:`canvas`,detail:!0}},{path:`/s/:sessionId/migrate`,name:`session-migration`,component:()=>W(()=>import(`./SessionMigrationPage-CQhrJ1OQ.js`),__vite__mapDeps([151,1,30,8,2,31,3,4,5,140,59,44,78,79,9,10,43,80,51,142,143,33,52,41,144,42,150])),meta:{title:`routes.sessionMigration.title`,layout:`form`,detail:!0}},{path:`/tags`,name:`tags`,component:()=>W(()=>import(`./TagVocabularyPage-Cp1UVDoe.js`),__vite__mapDeps([152,1,30,8,2,3,4,5,140,59,44,78,79,9,10,61,60,124,58,139,77,75,42,43,80,51,81,141,142,143])),meta:{title:`routes.tags.title`,layout:`canvas`}},{path:`/knowledge/turn/:spaceId`,name:`knowledge-turn-receipt`,component:()=>W(()=>import(`./KnowledgeTurnReceiptPage-Yn3jhDyx.js`),__vite__mapDeps([153,1,2,31,3,4,5,43,44,51,52,8,41,145,148,19,9,10,20,6])),meta:{title:`routes.knowledgeTurn.title`,layout:`form`,detail:!0}},{path:`/knowledge/:scope/:spaceId/:projectId/:mode/:itemKind/:itemId`,name:`project-knowledge-item`,component:()=>W(()=>import(`./KnowledgePage-8ct5iO0F.js`),__vite__mapDeps([137,1,76,30,8,2,31,3,4,5,77,59,44,78,79,37,11,9,10,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,53,42,54,56,57,58,60,61,63,64,89,90])),meta:{title:`routes.knowledge.title`,layout:`canvas`}},{path:`/knowledge/:scope/:spaceId/:mode/:itemKind/:itemId`,name:`knowledge-item`,component:()=>W(()=>import(`./KnowledgePage-8ct5iO0F.js`),__vite__mapDeps([137,1,76,30,8,2,31,3,4,5,77,59,44,78,79,37,11,9,10,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,53,42,54,56,57,58,60,61,63,64,89,90])),meta:{title:`routes.knowledge.title`,layout:`canvas`}},{path:`/knowledge/:scope/:spaceId/:projectId/:mode`,name:`project-knowledge`,component:()=>W(()=>import(`./KnowledgePage-8ct5iO0F.js`),__vite__mapDeps([137,1,76,30,8,2,31,3,4,5,77,59,44,78,79,37,11,9,10,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,53,42,54,56,57,58,60,61,63,64,89,90])),meta:{title:`routes.knowledge.title`,layout:`canvas`}},{path:`/knowledge/:scope/:spaceId/:mode`,name:`knowledge`,component:()=>W(()=>import(`./KnowledgePage-8ct5iO0F.js`),__vite__mapDeps([137,1,76,30,8,2,31,3,4,5,77,59,44,78,79,37,11,9,10,12,13,14,15,16,17,18,19,20,21,41,80,51,81,52,62,82,40,83,84,85,86,55,87,88,53,42,54,56,57,58,60,61,63,64,89,90])),meta:{title:`routes.knowledge.title`,layout:`canvas`}},{path:`/inbox`,name:`inbox`,component:()=>W(()=>import(`./InboxPage-BF38gnSV.js`),__vite__mapDeps([154,1,30,8,2,31,3,4,5,58,59,44,60,61,9,10,39,97,47,43,62,66,67,155])),meta:{title:`attention.title`,layout:`canvas`}},{path:`/review`,redirect:`/public-projects`},{path:`/connections`,name:`connections`,component:()=>W(()=>import(`./ConnectionsPage-EFMP-UeV.js`),__vite__mapDeps([156,1,30,8,3,4,5,15,16,6,72,43,44,62,118,119,55])),meta:{title:`routes.connections.title`,description:`routes.connections.description`,layout:`form`}},{path:`/settings`,name:`settings`,component:()=>W(()=>import(`./SettingsPage-OasIZiIz.js`),__vite__mapDeps([157,1,30,8,2,3,4,5,140,59,44,78,79,9,10,147,123,139,61,77,111,37,114,15,16,17,18,6,71,72,42,62,133,63,89,158])),meta:{title:`routes.settings.title`,layout:`form`,saveBar:!0}},{path:`/settings/models`,name:`model-settings`,component:()=>W(()=>import(`./ModelSettingsPage-5RkvgNYN.js`),__vite__mapDeps([159,1,30,8,31,2,3,4,5,140,59,44,78,79,9,10,143,11,12,13,14,15,16,17,18,19,20,21,97,47,42,43,80,142,33,82,40,83,67,160,106,26,161])),meta:{title:`modelSettings.title`,layout:`canvas`,detail:!0}},{path:`/settings/data-format`,name:`data-format`,component:()=>W(()=>import(`./DataFormatPage-PxwqDWeZ.js`),__vite__mapDeps([162,1,3,4,5,140,59,44,78,79,9,10,143,11,12,13,14,15,16,17,18,19,20,21,6,71,72,43,33,2,31,160,8,106,163])),meta:{title:`dataFormat.title`,layout:`form`,detail:!0}},{path:`/capture-change/:previewId`,name:`capture-change`,component:()=>W(()=>import(`./CaptureChangePage-DcJKvaGf.js`),__vite__mapDeps([164,1,30,8,2,31,3,4,5,37,6,71,72,42,165])),meta:{title:`capture.confirm.title`,layout:`form`,detail:!0}},{path:`/about`,name:`about`,component:()=>W(()=>import(`./AboutPage-BybzKsx-.js`),__vite__mapDeps([166,1,167,168])),meta:{title:`routes.about.title`,layout:`form`}},{path:`/:pathMatch(.*)*`,name:`not-found`,component:()=>W(()=>import(`./NotFoundPage-BUUf2-MZ.js`),__vite__mapDeps([169,1,31,2,3,4,5,6])),meta:{title:`common.errors.pageNotFound`,layout:`form`}}],scrollBehavior:(e,t,n)=>n??(e.path!==t.path&&{top:0})});Ve(Q),Q.beforeEach(e=>e.path!==`/`||typeof window>`u`?!0:Rn(window.location.hash)??!0),Q.afterEach(e=>{Vt(e.meta.title)}),Ce(),ot();var $=_(Ln);$.use(P()),$.use(v),$.use(Q),await Q.isReady().catch(()=>void 0),$.mount(`#app`);
|
package/dist/web/index.html
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
/>
|
|
10
10
|
<link rel="icon" type="image/png" href="/assets/fuli-logo-ER1wQ8Kk.png" />
|
|
11
11
|
<title>复利 · Context Graph</title>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
+
<script type="module" crossorigin src="/assets/index-DYEE8nDj.js"></script>
|
|
13
13
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-Crd8aFkh.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/client-Cg0bLxrO.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/console-k05BnLkZ.js">
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Agent apps
|
|
2
|
+
|
|
3
|
+
An Agent app is a small tool, page or resident service that a FULI Agent builds for a real, repeated need. An Agent can
|
|
4
|
+
only submit an immutable version (`submit_agent_app_version`) and read the list (`list_agent_apps`). Approving,
|
|
5
|
+
rolling back, disabling and deleting belong to the local user, in a terminal (`fuli app`) or the local console.
|
|
6
|
+
|
|
7
|
+
## Trusted mode: no sandbox in this version
|
|
8
|
+
|
|
9
|
+
This version has no system sandbox. **An approved app runs in trusted mode: as an ordinary process of your own OS
|
|
10
|
+
account, with your account's permissions. FULI does not isolate it.** This is the same footing as an installed
|
|
11
|
+
[Agent workbench package](employee-agents.md), which is trusted JavaScript running with the host's privileges. Approve
|
|
12
|
+
only apps you trust.
|
|
13
|
+
|
|
14
|
+
Approval shows one warning:
|
|
15
|
+
|
|
16
|
+
> 这个应用会用你的账户权限在本机运行,FULI 不会隔离它。只批准你信任的应用。
|
|
17
|
+
> This app runs on this computer with your account's permissions, and FULI does not isolate it. Approve only apps you trust.
|
|
18
|
+
|
|
19
|
+
### What FULI's fences cover, and what they do not
|
|
20
|
+
|
|
21
|
+
FULI's tool allowlist (an app is never granted a tool marked egress, model or launch, nor any tool that grows or
|
|
22
|
+
manages apps), its permission checks, its egress checks, its injection isolation and its hard-delete fence apply
|
|
23
|
+
**only to what an app asks of the FULI Host API**: the calls it makes through its app token, its data directory port
|
|
24
|
+
and the scope FULI injects into each call.
|
|
25
|
+
|
|
26
|
+
They do **not** stop a trusted app from reading or writing files, using the network or starting processes by itself.
|
|
27
|
+
Nothing in FULI is a system isolation of trusted code, and nothing in FULI should be read as one. A refused
|
|
28
|
+
`network` field in a manifest means the FULI host grants no network access; it does not mean the app has none.
|
|
29
|
+
|
|
30
|
+
Sandboxed runners (AppContainer on Windows, bwrap on Linux, sandbox-exec on macOS) are planned for a later version
|
|
31
|
+
(rec#37); they will plug into the same runner contract (`src/agent-apps/trusted-runner.js`).
|
|
32
|
+
|
|
33
|
+
## Approving: the terminal confirmation flow
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
fl app list
|
|
37
|
+
fl app show <app-id>
|
|
38
|
+
fl app approve <app-id> <version> [--hello]
|
|
39
|
+
fl app rollback <app-id> <version> [--hello]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`approve` and `rollback` work the same way on Windows, macOS and Linux, and only in an interactive terminal:
|
|
43
|
+
|
|
44
|
+
1. A resident service and an irreversible data migration each get their own yes/no question first.
|
|
45
|
+
2. FULI shows the app name, a short summary of this version's terms (package digest, permissions, data directory,
|
|
46
|
+
resident service), the trusted-mode warning above and this notice:
|
|
47
|
+
> 输入应用名即完成终端确认流程。这不证明是真人操作,也不能抵御以同一账户运行的其他程序。
|
|
48
|
+
> Typing the app name completes the terminal confirmation flow. This does not prove a person did it, and it does not
|
|
49
|
+
> protect against other programs running under the same account.
|
|
50
|
+
3. You type the app name (the package name, for example `dispatch-log`) to confirm. Enter on an empty line or Ctrl-C
|
|
51
|
+
cancels.
|
|
52
|
+
|
|
53
|
+
Each attempt uses a one-time challenge that expires after 10 minutes. It binds the exact action, the package digest,
|
|
54
|
+
the terms version and `trustMode: 'trusted'`. It is committed in two steps (claim, then finalize), so of concurrent
|
|
55
|
+
attempts exactly one can approve. A wrong name, a cancellation, an expired challenge, a replay, or terms or a package
|
|
56
|
+
that changed after the prompt approves nothing and leaves the challenge used.
|
|
57
|
+
|
|
58
|
+
`--hello` adds Windows Hello on Windows after the name is typed, and records the approval as presence `hello`. It is
|
|
59
|
+
optional and never required; if you ask for it and Hello fails or is cancelled, that decision is refused. Other
|
|
60
|
+
platforms have no `--hello`.
|
|
61
|
+
|
|
62
|
+
An approval from the local console completes no terminal confirmation, so the run gate refuses that version until
|
|
63
|
+
`fl app approve` or `fl app rollback` confirms it.
|
|
64
|
+
|
|
65
|
+
## When an app runs
|
|
66
|
+
|
|
67
|
+
Every start of an app (on demand, an idle restart, a resident launch) passes the run gate. It runs only when:
|
|
68
|
+
|
|
69
|
+
- the active version has an approval that completed the terminal confirmation flow under this version's terms
|
|
70
|
+
(`trustMode: 'trusted'`, the current terms version), recorded with its consumed challenge;
|
|
71
|
+
- that approval covers the version's digest, permissions, data scope and resident service;
|
|
72
|
+
- the package on disk still has the approved digest.
|
|
73
|
+
|
|
74
|
+
Otherwise the gate answers `confirmation_required`, `reconfirmation_required` or `challenge_mismatch`, and no app code
|
|
75
|
+
starts. The app process gets only `FULI_APP_ID`, `FULI_APP_INSTANCE` and `FULI_APP_TOKEN` from FULI, plus the
|
|
76
|
+
platform basics (`PATH`, temp and home directories); none of FULI's own tokens or keys. It runs in its package
|
|
77
|
+
directory and ends when the FULI process that started it exits.
|
|
78
|
+
|
|
79
|
+
## After upgrading from an earlier FULI
|
|
80
|
+
|
|
81
|
+
Approvals made before trusted mode (the isolated mode of the previous version, Windows Hello approvals included) are
|
|
82
|
+
**not** converted. Consent to code that was to run isolated is not consent to run it with your own permissions. The
|
|
83
|
+
registry migrates by itself (format 8 adds the trust mode and terms version to each approval; the earlier ones keep
|
|
84
|
+
none), and each such version answers `reconfirmation_required` until you confirm it again:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
fl app rollback <app-id> <active-version>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Stopping
|
|
91
|
+
|
|
92
|
+
When FULI itself shuts down, it takes no new start, call or decision, lets work in flight finish (30 seconds at most),
|
|
93
|
+
then seals and stops every app it started and releases them, so another FULI process can start them without a takeover.
|
|
94
|
+
A start that returns after that is stopped at once. If FULI cannot confirm that an app process it started has stopped,
|
|
95
|
+
the shutdown says so and names the app instead of reporting a clean close; closing again retries the stop.
|
|
96
|
+
|
|
97
|
+
An app that ends by itself ends its instance. The app's details show the exit code, the signal and one of three fixed
|
|
98
|
+
categories with a fixed message: `load_failed` (it ended before its entry finished loading), `crashed` (it ended with
|
|
99
|
+
an error after that) or `exited` (it finished with code 0). FULI does not read or keep anything the app writes to its
|
|
100
|
+
output. It can then be started again.
|
|
101
|
+
|
|
102
|
+
`fl app stop <app-id>` seals the instance (no new call verifies; a write tool in progress finishes first), stops the
|
|
103
|
+
app process through the handle FULI holds and ends its tokens. `--force` is not supported on any platform in this
|
|
104
|
+
version: when another FULI process holds the app, stop that FULI process first. FULI never ends a process by PID; if
|
|
105
|
+
an app process an exited FULI started is still running, end it yourself and try again.
|
package/docs/employee-agents.md
CHANGED
|
@@ -56,7 +56,7 @@ Packages live under the configured FULI data directory, separately from employee
|
|
|
56
56
|
|
|
57
57
|
Only a regular `.installation.json` at the package root is excluded from content identity as host-generated metadata. File-type validation still rejects receipt symlinks before installation can write through them. Files with that name in subdirectories remain package content: changes require an explicit replacement, and directory contents still undergo normal validation.
|
|
58
58
|
|
|
59
|
-
**Installed runtimes are trusted JavaScript running with the host's privileges, not sandboxed plugins.** Only install trusted packages. Path confinement, manifest validation, size limits, rejection of symlinks, `.env`, `.git` and `node_modules` protect the installation boundary; they do not make malicious runtime code safe.
|
|
59
|
+
**Installed runtimes are trusted JavaScript running with the host's privileges, not sandboxed plugins.** Only install trusted packages. Path confinement, manifest validation, size limits, rejection of symlinks, `.env`, `.git` and `node_modules` protect the installation boundary; they do not make malicious runtime code safe. Manifest permissions and FULI's permission, egress, injection and hard-delete checks constrain only what a runtime asks of the FULI host; they do not stop trusted code from reading files, using the network or starting processes itself. [Agent apps](agent-apps.md) run on the same trusted footing in this version.
|
|
60
60
|
|
|
61
61
|
## Manifest API v1
|
|
62
62
|
|
|
Binary file
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuli-context",
|
|
3
|
-
"version": "0.20.0-beta.
|
|
3
|
+
"version": "0.20.0-beta.9",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "fuli-context",
|
|
9
|
-
"version": "0.20.0-beta.
|
|
9
|
+
"version": "0.20.0-beta.9",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@a2a-js/sdk": "1.3.0",
|
|
@@ -4128,9 +4128,9 @@
|
|
|
4128
4128
|
"license": "MIT"
|
|
4129
4129
|
},
|
|
4130
4130
|
"node_modules/fast-uri": {
|
|
4131
|
-
"version": "3.1.
|
|
4132
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
4133
|
-
"integrity": "sha512-
|
|
4131
|
+
"version": "3.1.9",
|
|
4132
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
|
|
4133
|
+
"integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
|
|
4134
4134
|
"funding": [
|
|
4135
4135
|
{
|
|
4136
4136
|
"type": "github",
|
|
@@ -6427,9 +6427,9 @@
|
|
|
6427
6427
|
"license": "ISC"
|
|
6428
6428
|
},
|
|
6429
6429
|
"node_modules/undici": {
|
|
6430
|
-
"version": "7.30.
|
|
6431
|
-
"resolved": "https://registry.npmjs.org/undici/-/undici-7.30.
|
|
6432
|
-
"integrity": "sha512-
|
|
6430
|
+
"version": "7.30.1",
|
|
6431
|
+
"resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz",
|
|
6432
|
+
"integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==",
|
|
6433
6433
|
"dev": true,
|
|
6434
6434
|
"license": "MIT",
|
|
6435
6435
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuli-context",
|
|
3
|
-
"version": "0.20.0-beta.
|
|
3
|
+
"version": "0.20.0-beta.9",
|
|
4
4
|
"description": "Local-first collaboration relationship graph for AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"docs/project-agent-memory.md",
|
|
18
18
|
"docs/agent-conversations-and-collaboration.md",
|
|
19
19
|
"docs/employee-agents.md",
|
|
20
|
+
"docs/agent-apps.md",
|
|
20
21
|
"docs/agent-interface-architecture.md",
|
|
21
22
|
"docs/agent-roundtable.md",
|
|
22
23
|
"examples/external-knowledge/markdown-folder.mjs",
|
|
@@ -130,7 +131,7 @@
|
|
|
130
131
|
"@hono/node-server": "2.0.12"
|
|
131
132
|
},
|
|
132
133
|
"brace-expansion": "$brace-expansion",
|
|
133
|
-
"fast-uri": "3.1.
|
|
134
|
+
"fast-uri": "3.1.9",
|
|
134
135
|
"qs": "6.16.1"
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -7,8 +7,8 @@ import { storedPackageMatches } from './package-files.js';
|
|
|
7
7
|
|
|
8
8
|
// What approving or re-activating a version requires, and the one place a
|
|
9
9
|
// version becomes the running one. The console's unverified decisions
|
|
10
|
-
// (versions.js) and the CLI's
|
|
11
|
-
// share it; each says which
|
|
10
|
+
// (versions.js) and the CLI's terminal-confirmed ones (confirmed-decisions.js)
|
|
11
|
+
// share it; each says which confirmation the activation carries.
|
|
12
12
|
export function createActivation(context) {
|
|
13
13
|
const { store } = context;
|
|
14
14
|
|
|
@@ -59,7 +59,7 @@ export function createActivation(context) {
|
|
|
59
59
|
return dataTransition(app.dataFormat, version.manifest.data, options);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// detail: what the event records of the decision; check: its
|
|
62
|
+
// detail: what the event records of the decision; check: its confirmation.
|
|
63
63
|
function approve({ app, version, transition }, { at, actor, detail, check }) {
|
|
64
64
|
store.insertApproval({ appId: app.appId, version: version.version, ...approvalTerms(version), approvedBy: actor,
|
|
65
65
|
entrypoint: detail.entrypoint, approvedAt: at }, check);
|
|
@@ -34,6 +34,8 @@ export function createAppHost(context) {
|
|
|
34
34
|
const { store, leases, gates, instances, now } = context;
|
|
35
35
|
|
|
36
36
|
function authorizeCall({ token, toolName, input = {} }) {
|
|
37
|
+
// A closing process takes no new call; one already authorized still runs to its seal.
|
|
38
|
+
instances.assertOpen();
|
|
37
39
|
const tool = context.hostTools().get(toolName);
|
|
38
40
|
if (!tool || tool.marks.length) {
|
|
39
41
|
throw new ApplicationError('tool_not_permitted', `Apps may not call ${toolName}`, { status: 403 });
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { closeSync, writeSync } from 'node:fs';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
|
|
4
|
+
// The first module of an app process the trusted runner starts
|
|
5
|
+
// (trusted-runner.js): it ties the app to its FULI host, loads the app's
|
|
6
|
+
// service entry and then tells the host it loaded. The host holds the other
|
|
7
|
+
// end of stdin; when that FULI process exits, however it exits, the pipe
|
|
8
|
+
// closes and the app ends with it. The pipe does not keep an app alive that
|
|
9
|
+
// would otherwise finish. Trusted app code can undo this; it is a lifetime
|
|
10
|
+
// tie, not a fence.
|
|
11
|
+
const READY_FD = 3;
|
|
12
|
+
const [entry] = process.argv.slice(2);
|
|
13
|
+
const end = () => process.exit(0);
|
|
14
|
+
process.stdin.on('end', end);
|
|
15
|
+
process.stdin.on('error', end);
|
|
16
|
+
process.stdin.resume();
|
|
17
|
+
process.stdin.unref?.();
|
|
18
|
+
await import(pathToFileURL(entry).href);
|
|
19
|
+
// One byte on the ready pipe, which the runner opened; an end before it is a load failure.
|
|
20
|
+
try {
|
|
21
|
+
writeSync(READY_FD, 'r');
|
|
22
|
+
closeSync(READY_FD);
|
|
23
|
+
} catch {
|
|
24
|
+
// Not started by the trusted runner: there is no ready pipe to tell.
|
|
25
|
+
}
|
|
@@ -24,12 +24,14 @@ export function dataDeleting() {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// What no app may ask for, refused at submission and never silently dropped
|
|
27
|
-
// (rec#7 D-28.3, D-28.4): network
|
|
28
|
-
// or launch in the host tool catalog.
|
|
27
|
+
// (rec#7 D-28.3, D-28.4): a network grant, and any tool marked egress, model
|
|
28
|
+
// or launch in the host tool catalog. These limit only what the FULI Host API
|
|
29
|
+
// grants; an app in trusted mode can still use the network or start programs
|
|
30
|
+
// itself (rec#11 D-36.10).
|
|
29
31
|
export function rejectedManifest(submitted, manifest) {
|
|
30
32
|
const reasons = [];
|
|
31
33
|
if (submitted !== null && typeof submitted === 'object' && Object.hasOwn(submitted, 'network')) {
|
|
32
|
-
reasons.push('network:
|
|
34
|
+
reasons.push('network: the FULI host grants apps no network access');
|
|
33
35
|
}
|
|
34
36
|
if (manifest) {
|
|
35
37
|
for (const permission of manifest.permissions) {
|
|
@@ -38,7 +40,7 @@ export function rejectedManifest(submitted, manifest) {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
return reasons.length ? new ApplicationError('manifest_rejected',
|
|
41
|
-
`
|
|
43
|
+
`The FULI host grants apps nothing that sends data off this computer, spends model budget or starts other programs: ${reasons.join('; ')}`,
|
|
42
44
|
{ status: 400 }) : null;
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
+
|
|
3
|
+
// Whether work settles (either way) within ms. The timer is cleared as soon
|
|
4
|
+
// as the work settles.
|
|
5
|
+
export async function settledWithin(work, ms) {
|
|
6
|
+
const timeout = new AbortController();
|
|
7
|
+
try {
|
|
8
|
+
return await Promise.race([work.then(() => true, () => true),
|
|
9
|
+
delay(ms, false, { signal: timeout.signal }).catch(() => false)]);
|
|
10
|
+
} finally {
|
|
11
|
+
timeout.abort();
|
|
12
|
+
}
|
|
13
|
+
}
|