ltcai 8.9.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +81 -58
  2. package/auto_setup.py +7 -904
  3. package/desktop/electron/README.md +9 -0
  4. package/desktop/electron/main.cjs +5 -3
  5. package/docs/CHANGELOG.md +221 -238
  6. package/docs/COMMUNITY_AND_PLUGINS.md +3 -2
  7. package/docs/DEVELOPMENT.md +53 -14
  8. package/docs/LEGACY_COMPATIBILITY.md +4 -4
  9. package/docs/ONBOARDING.md +10 -2
  10. package/docs/OPERATIONS.md +8 -4
  11. package/docs/PRODUCT_DIRECTION_REVIEW.md +4 -0
  12. package/docs/ROADMAP_RECOMMENDATIONS.md +61 -36
  13. package/docs/TRUST_MODEL.md +5 -2
  14. package/docs/WHY_LATTICE.md +15 -10
  15. package/docs/WORKFLOW_DESIGNER.md +22 -0
  16. package/docs/kg-schema.md +13 -2
  17. package/docs/mcp-tools.md +17 -6
  18. package/docs/privacy.md +19 -3
  19. package/docs/public-deploy.md +32 -3
  20. package/docs/security-model.md +46 -11
  21. package/lattice_brain/__init__.py +1 -1
  22. package/lattice_brain/archive.py +4 -14
  23. package/lattice_brain/context.py +66 -9
  24. package/lattice_brain/embeddings.py +38 -2
  25. package/lattice_brain/graph/_kg_common.py +27 -462
  26. package/lattice_brain/graph/_kg_constants.py +243 -0
  27. package/lattice_brain/graph/_kg_fsutil.py +293 -0
  28. package/lattice_brain/graph/discovery.py +0 -948
  29. package/lattice_brain/graph/discovery_index.py +1126 -0
  30. package/lattice_brain/graph/documents.py +44 -9
  31. package/lattice_brain/graph/ingest.py +47 -20
  32. package/lattice_brain/graph/provenance.py +13 -6
  33. package/lattice_brain/graph/retrieval.py +141 -610
  34. package/lattice_brain/graph/retrieval_docgen.py +243 -0
  35. package/lattice_brain/graph/retrieval_vector.py +460 -0
  36. package/lattice_brain/graph/store.py +6 -0
  37. package/lattice_brain/ingestion.py +69 -4
  38. package/lattice_brain/portability.py +29 -23
  39. package/lattice_brain/quality.py +98 -4
  40. package/lattice_brain/runtime/agent_runtime.py +169 -7
  41. package/lattice_brain/runtime/hooks.py +30 -13
  42. package/lattice_brain/runtime/multi_agent.py +27 -8
  43. package/lattice_brain/runtime/statuses.py +10 -0
  44. package/lattice_brain/utils.py +46 -0
  45. package/lattice_brain/workflow.py +1 -5
  46. package/latticeai/__init__.py +1 -1
  47. package/latticeai/api/admin.py +1 -1
  48. package/latticeai/api/agent_registry.py +10 -8
  49. package/latticeai/api/agents.py +22 -3
  50. package/latticeai/api/auth.py +78 -16
  51. package/latticeai/api/browser.py +303 -34
  52. package/latticeai/api/chat.py +355 -952
  53. package/latticeai/api/chat_agent_http.py +356 -0
  54. package/latticeai/api/chat_contracts.py +54 -0
  55. package/latticeai/api/chat_documents.py +256 -0
  56. package/latticeai/api/chat_helpers.py +250 -0
  57. package/latticeai/api/chat_history.py +99 -0
  58. package/latticeai/api/chat_intents.py +302 -0
  59. package/latticeai/api/chat_stream.py +115 -0
  60. package/latticeai/api/computer_use.py +211 -40
  61. package/latticeai/api/health.py +9 -3
  62. package/latticeai/api/hooks.py +17 -6
  63. package/latticeai/api/knowledge_graph.py +78 -14
  64. package/latticeai/api/local_files.py +7 -2
  65. package/latticeai/api/marketplace.py +11 -0
  66. package/latticeai/api/mcp.py +102 -23
  67. package/latticeai/api/models.py +72 -33
  68. package/latticeai/api/network.py +5 -5
  69. package/latticeai/api/permissions.py +70 -29
  70. package/latticeai/api/plugins.py +21 -7
  71. package/latticeai/api/portability.py +5 -5
  72. package/latticeai/api/realtime.py +33 -5
  73. package/latticeai/api/setup.py +2 -2
  74. package/latticeai/api/static_routes.py +123 -24
  75. package/latticeai/api/tools.py +97 -14
  76. package/latticeai/api/workflow_designer.py +37 -0
  77. package/latticeai/api/workspace.py +2 -1
  78. package/latticeai/app_factory.py +185 -405
  79. package/latticeai/core/agent.py +19 -9
  80. package/latticeai/core/agent_registry.py +1 -5
  81. package/latticeai/core/config.py +23 -3
  82. package/latticeai/core/context_builder.py +21 -3
  83. package/latticeai/core/invitations.py +1 -4
  84. package/latticeai/core/io_utils.py +45 -0
  85. package/latticeai/core/legacy_compatibility.py +24 -3
  86. package/latticeai/core/local_embeddings.py +2 -4
  87. package/latticeai/core/marketplace.py +33 -2
  88. package/latticeai/core/mcp_catalog.py +450 -0
  89. package/latticeai/core/mcp_registry.py +2 -441
  90. package/latticeai/core/plugins.py +15 -0
  91. package/latticeai/core/policy.py +1 -1
  92. package/latticeai/core/realtime.py +38 -15
  93. package/latticeai/core/sessions.py +7 -2
  94. package/latticeai/core/timeutil.py +10 -0
  95. package/latticeai/core/tool_registry.py +90 -18
  96. package/latticeai/core/users.py +5 -14
  97. package/latticeai/core/workspace_graph_trace.py +31 -5
  98. package/latticeai/core/workspace_memory.py +3 -1
  99. package/latticeai/core/workspace_os.py +18 -7
  100. package/latticeai/core/workspace_os_utils.py +2 -21
  101. package/latticeai/core/workspace_permissions.py +2 -1
  102. package/latticeai/core/workspace_plugins.py +1 -1
  103. package/latticeai/core/workspace_runs.py +14 -5
  104. package/latticeai/core/workspace_skills.py +1 -1
  105. package/latticeai/core/workspace_snapshots.py +2 -1
  106. package/latticeai/core/workspace_timeline.py +2 -1
  107. package/latticeai/integrations/telegram_bot.py +96 -40
  108. package/latticeai/models/model_providers.py +111 -0
  109. package/latticeai/models/router.py +189 -173
  110. package/latticeai/runtime/access_runtime.py +62 -4
  111. package/latticeai/runtime/audit_runtime.py +27 -16
  112. package/latticeai/runtime/automation_runtime.py +22 -7
  113. package/latticeai/runtime/brain_runtime.py +19 -7
  114. package/latticeai/runtime/chat_wiring.py +2 -0
  115. package/latticeai/runtime/config_runtime.py +58 -26
  116. package/latticeai/runtime/context_runtime.py +16 -4
  117. package/latticeai/runtime/history_runtime.py +163 -0
  118. package/latticeai/runtime/hooks_runtime.py +1 -1
  119. package/latticeai/runtime/model_wiring.py +33 -5
  120. package/latticeai/runtime/namespace_runtime.py +163 -0
  121. package/latticeai/runtime/network_config_runtime.py +56 -0
  122. package/latticeai/runtime/platform_runtime_wiring.py +4 -3
  123. package/latticeai/runtime/review_wiring.py +1 -1
  124. package/latticeai/runtime/router_registration.py +34 -1
  125. package/latticeai/runtime/security_runtime.py +110 -13
  126. package/latticeai/runtime/sso_config_runtime.py +128 -0
  127. package/latticeai/runtime/stages.py +27 -0
  128. package/latticeai/runtime/user_key_runtime.py +106 -0
  129. package/latticeai/server_app.py +5 -1
  130. package/latticeai/services/architecture_readiness.py +74 -5
  131. package/latticeai/services/brain_automation.py +3 -26
  132. package/latticeai/services/chat_service.py +205 -15
  133. package/latticeai/services/local_knowledge.py +423 -0
  134. package/latticeai/services/memory_service.py +268 -21
  135. package/latticeai/services/model_engines.py +48 -33
  136. package/latticeai/services/model_errors.py +17 -0
  137. package/latticeai/services/model_loading.py +28 -25
  138. package/latticeai/services/model_runtime.py +228 -162
  139. package/latticeai/services/p_reinforce.py +22 -3
  140. package/latticeai/services/platform_runtime.py +92 -24
  141. package/latticeai/services/product_readiness.py +19 -17
  142. package/latticeai/services/review_queue.py +76 -11
  143. package/latticeai/services/router_context.py +1 -0
  144. package/latticeai/services/run_executor.py +25 -9
  145. package/latticeai/services/search_service.py +203 -28
  146. package/latticeai/services/setup_detection.py +80 -0
  147. package/latticeai/services/tool_dispatch.py +28 -5
  148. package/latticeai/services/triggers.py +53 -4
  149. package/latticeai/services/upload_service.py +13 -2
  150. package/latticeai/setup/__init__.py +25 -0
  151. package/latticeai/setup/auto_setup.py +857 -0
  152. package/latticeai/setup/wizard.py +1264 -0
  153. package/latticeai/tools/__init__.py +278 -0
  154. package/{tools → latticeai/tools}/commands.py +67 -7
  155. package/{tools → latticeai/tools}/computer.py +1 -1
  156. package/{tools → latticeai/tools}/documents.py +1 -1
  157. package/{tools → latticeai/tools}/filesystem.py +3 -3
  158. package/latticeai/tools/knowledge.py +178 -0
  159. package/{tools → latticeai/tools}/local_files.py +7 -1
  160. package/{tools → latticeai/tools}/network.py +0 -1
  161. package/local_knowledge_api.py +4 -342
  162. package/package.json +22 -2
  163. package/scripts/brain_quality_eval.py +3 -1
  164. package/scripts/bump_version.py +3 -0
  165. package/scripts/capture_release_evidence.mjs +180 -0
  166. package/scripts/check_current_release_docs.mjs +142 -0
  167. package/scripts/check_i18n_literals.mjs +107 -31
  168. package/scripts/check_openapi_drift.mjs +56 -0
  169. package/scripts/export_openapi.py +67 -7
  170. package/scripts/i18n_literal_allowlist.json +22 -24
  171. package/scripts/run_integration_tests.mjs +72 -10
  172. package/scripts/validate_release_artifacts.py +49 -7
  173. package/scripts/wheel_smoke.py +5 -0
  174. package/setup_wizard.py +3 -1304
  175. package/src-tauri/Cargo.lock +1 -1
  176. package/src-tauri/Cargo.toml +1 -1
  177. package/src-tauri/tauri.conf.json +1 -1
  178. package/static/app/asset-manifest.json +11 -11
  179. package/static/app/assets/Act-Bzz0bUyW.js +1 -0
  180. package/static/app/assets/Brain-Dj2J20YA.js +321 -0
  181. package/static/app/assets/Capture-CqlEl1Ga.js +1 -0
  182. package/static/app/assets/Library-B03FP1Yx.js +1 -0
  183. package/static/app/assets/System-80lHW0Ux.js +1 -0
  184. package/static/app/assets/index-BiMofBTM.js +17 -0
  185. package/static/app/assets/index-Bmx9rzTc.css +2 -0
  186. package/static/app/assets/primitives-Q1A96_7v.js +1 -0
  187. package/static/app/assets/textarea-D13RtnTo.js +1 -0
  188. package/static/app/index.html +2 -2
  189. package/static/css/tokens.css +4 -2
  190. package/static/sw.js +1 -1
  191. package/tools/__init__.py +21 -269
  192. package/docs/CODE_REVIEW_2026-07-06.md +0 -764
  193. package/latticeai/runtime/app_context_runtime.py +0 -13
  194. package/latticeai/runtime/sso_runtime.py +0 -52
  195. package/latticeai/runtime/tail_wiring.py +0 -21
  196. package/scripts/com.pts.claudecode.discord.plist +0 -31
  197. package/scripts/pts-claudecode-discord-bridge.mjs +0 -207
  198. package/scripts/start-pts-claudecode-discord.sh +0 -51
  199. package/static/app/assets/Act-fZokUnC0.js +0 -1
  200. package/static/app/assets/Brain-DtyuWubr.js +0 -321
  201. package/static/app/assets/Capture-D5KV3Cu7.js +0 -1
  202. package/static/app/assets/Library-C9kyFkSt.js +0 -1
  203. package/static/app/assets/System-VbChmX7r.js +0 -1
  204. package/static/app/assets/index-DCh5AoXt.css +0 -2
  205. package/static/app/assets/index-DPdcPoF0.js +0 -17
  206. package/static/app/assets/primitives-DFeanEV6.js +0 -1
  207. package/static/app/assets/textarea-CD8UNKIy.js +0 -1
  208. package/tools/knowledge.py +0 -95
@@ -1 +0,0 @@
1
- import{C as e,E as t,I as n,M as r,O as i,P as a,S as o,T as s,_ as c,a as l,b as u,j as d,k as f,l as p,n as m,x as h,y as g}from"./index-DPdcPoF0.js";var _=g(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),v=g(`lock-keyhole`,[[`circle`,{cx:`12`,cy:`16`,r:`1`,key:`1au0dj`}],[`rect`,{x:`3`,y:`10`,width:`18`,height:`12`,rx:`2`,key:`6s8ecr`}],[`path`,{d:`M7 10V7a5 5 0 0 1 10 0v3`,key:`1pqi11`}]]),y=n(a()),b=r(),x={default:`border-primary/25 bg-primary/12 text-primary`,success:`border-success/30 bg-success/12 text-success`,warning:`border-warning/30 bg-warning/12 text-warning`,muted:`border-border bg-muted/70 text-muted-foreground`,danger:`border-destructive/30 bg-destructive/12 text-destructive`};function S({className:e,variant:t=`default`,...n}){return(0,b.jsx)(`span`,{className:o(`inline-flex min-h-6 max-w-full items-center whitespace-nowrap rounded-md border px-2 py-0.5 text-xs font-semibold leading-none`,x[t],e),...n})}function C({className:e,...t}){return(0,b.jsx)(`section`,{className:o(`premium-surface rounded-lg text-card-foreground`,e),...t})}function w({className:e,...t}){return(0,b.jsx)(`div`,{className:o(`flex flex-col gap-1.5 p-5`,e),...t})}function T({className:e,...t}){return(0,b.jsx)(`h2`,{className:o(`text-base font-semibold tracking-normal`,e),...t})}function E({className:e,...t}){return(0,b.jsx)(`p`,{className:o(`text-sm leading-6 text-muted-foreground`,e),...t})}function D({className:e,...t}){return(0,b.jsx)(`div`,{className:o(`p-5 pt-0`,e),...t})}function O({result:e}){let t=i(e=>e.mode),n=i(e=>e.language);return e?e.source===`live`&&e.ok?(0,b.jsx)(S,{variant:`success`,children:t===`basic`?u(n,`ui.status.ready`):u(n,`ui.status.connected`)}):(0,b.jsx)(S,{variant:`warning`,children:t===`basic`?u(n,`ui.status.needsSetup`):u(n,`ui.status.unavailable`)}):(0,b.jsx)(S,{variant:`muted`,children:u(n,`ui.status.notLoaded`)})}function k({title:e,detail:t}){let n=i(e=>e.language);return(0,b.jsxs)(`div`,{className:`flex min-h-36 flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border bg-muted/24 p-6 text-center text-sm text-muted-foreground`,children:[(0,b.jsx)(`div`,{className:`grid h-10 w-10 place-items-center rounded-md border border-border bg-card`,children:(0,b.jsx)(l,{className:`h-5 w-5 text-primary`})}),(0,b.jsx)(`div`,{className:`text-base font-semibold text-foreground`,children:e||u(n,`ui.empty.title`)}),t?(0,b.jsx)(`div`,{className:`max-w-md leading-6`,children:t}):null]})}function A({title:e,description:t,result:n,children:r,className:a}){let s=i(e=>e.mode),c=i(e=>e.language);return(0,b.jsxs)(C,{className:o(`overflow-hidden`,a),children:[(0,b.jsxs)(w,{className:`flex-row items-start justify-between gap-3`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(T,{children:e}),t?(0,b.jsx)(E,{children:t}):null]}),(0,b.jsx)(O,{result:n})]}),(0,b.jsx)(D,{children:n?.ok?r(n.data):(0,b.jsx)(k,{detail:s===`basic`?u(c,`ui.empty.basicDetail`):n?.error||u(c,`ui.empty.advancedDetail`)})})]})}function j({title:e}){let t=i(e=>e.language);return(0,b.jsxs)(C,{children:[(0,b.jsx)(w,{children:(0,b.jsx)(T,{children:e})}),(0,b.jsx)(D,{children:(0,b.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,b.jsx)(p,{className:`h-4 w-4 animate-spin`}),` `,u(t,`ui.loading`)]})})]})}function M({stats:t}){return(0,b.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2 xl:grid-cols-4`,children:t.map(t=>(0,b.jsxs)(`div`,{className:`rounded-lg border border-border bg-background/55 p-4`,children:[(0,b.jsx)(`div`,{className:`text-xs uppercase text-muted-foreground`,children:t.label}),(0,b.jsx)(`div`,{className:`mt-2 text-2xl font-semibold leading-tight`,children:typeof t.value==`number`?e(t.value):String(t.value??`-`)}),t.hint?(0,b.jsx)(`div`,{className:`mt-2 text-xs leading-5 text-muted-foreground`,children:t.hint}):null]},t.label))})}function N(e){return!!(e&&typeof e==`object`&&!Array.isArray(e))}function P(t){return t==null||t===``?`-`:typeof t==`number`?Number.isFinite(t)?e(t):`-`:typeof t==`boolean`?t?`Enabled`:`Disabled`:String(t)}var F=/(^id$|_id$|token|secret|passphrase|fingerprint|public_key|private_key|dsn|schema|endpoint|base_url|localhost|127\.0\.0\.1|stack|trace|raw|runtime|engine|module|port|host|api|internal)/i;function I(e){return F.test(e)}function L(e){let n=P(e);return n===`-`||n.includes(`/`)||n.includes(`@`)||/\.[a-z0-9]{2,5}$/i.test(n)?n:t(n.replace(/^agent:/i,``).replace(/^tool:/i,``))}function R(e){for(let t of[`documents`,`sources`,`items`,`agents`,`workflows`,`runs`,`events`,`permissions`,`models`,`peers`,`invitations`,`roles`,`policies`,`hooks`,`tools`,`templates`,`plugins`,`recent_events`]){let n=h(e[t]);if(n.length)return n}return[]}function z({value:n}){if(typeof n==`boolean`)return(0,b.jsx)(S,{variant:n?`success`:`muted`,children:n?`enabled`:`disabled`});if(Array.isArray(n))return n.length?n.every(e=>e===null||[`string`,`number`,`boolean`].includes(typeof e))?(0,b.jsxs)(`span`,{className:`flex flex-wrap gap-1`,children:[n.slice(0,5).map((e,t)=>(0,b.jsx)(S,{variant:`muted`,children:P(e)},`${String(e)}-${t}`)),n.length>5?(0,b.jsxs)(S,{variant:`muted`,children:[`+`,n.length-5]}):null]}):(0,b.jsxs)(`span`,{className:`text-muted-foreground`,children:[e(n.length),` records`]}):(0,b.jsx)(`span`,{className:`text-muted-foreground`,children:`None`});if(N(n)){let e=Object.keys(n);return e.length?(0,b.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.slice(0,4).map(t).join(`, `),e.length>4?` +${e.length-4}`:``]}):(0,b.jsx)(`span`,{className:`text-muted-foreground`,children:`No fields`})}let r=P(n);return(0,b.jsx)(`span`,{className:`break-words`,children:r.length>96?s(r,96):r})}function B({data:e,limit:n=8}){let r=i(e=>e.mode),a=i(e=>e.language),o=Object.entries(e||{}).filter(([e])=>r!==`basic`||!I(e)).slice(0,n);return o.length?(0,b.jsx)(`div`,{className:`divide-y divide-border rounded-md border border-border`,children:o.map(([e,n])=>(0,b.jsxs)(`div`,{className:`grid grid-cols-[minmax(9rem,0.5fr)_1fr] gap-3 p-3 text-sm`,children:[(0,b.jsx)(`span`,{className:`font-medium text-muted-foreground`,children:t(e)}),(0,b.jsx)(`span`,{className:`min-w-0 break-words`,children:(0,b.jsx)(z,{value:n})})]},e))}):(0,b.jsx)(k,{title:u(a,`ui.noValues`)})}function V({value:e,titleKey:t=`title`,metaKey:n=`status`,limit:r=8}){let a=i(e=>e.mode),o=i(e=>e.language);return a===`basic`?(0,b.jsx)(H,{value:e,titleKey:t,metaKey:n,limit:r}):Array.isArray(e)?e.length?e.every(e=>N(e))?(0,b.jsx)(W,{items:e,titleKey:t,metaKey:n,limit:r}):(0,b.jsxs)(`div`,{className:`flex flex-wrap gap-1 rounded-md border border-border bg-background p-3`,children:[e.slice(0,r).map((e,t)=>(0,b.jsx)(S,{variant:`muted`,children:P(e)},`${String(e)}-${t}`)),e.length>r?(0,b.jsxs)(S,{variant:`muted`,children:[`+`,e.length-r]}):null]}):(0,b.jsx)(k,{detail:u(o,`ui.empty.listDetail`)}):N(e)?(0,b.jsx)(B,{data:e,limit:r}):(0,b.jsx)(`div`,{className:`rounded-md border border-border bg-background p-3 text-sm`,children:(0,b.jsx)(z,{value:e})})}function H({value:t,titleKey:n=`title`,metaKey:r=`status`,limit:a=6}){let o=i(e=>e.language);if(Array.isArray(t))return t.length?t.every(e=>N(e))?(0,b.jsx)(W,{items:t,titleKey:n,metaKey:r,limit:a}):(0,b.jsxs)(`div`,{className:`flex flex-wrap gap-1 rounded-md border border-border bg-background/55 p-3`,children:[t.slice(0,a).map((e,t)=>(0,b.jsx)(S,{variant:`muted`,children:L(e)},`${String(e)}-${t}`)),t.length>a?(0,b.jsxs)(S,{variant:`muted`,children:[`+`,t.length-a]}):null]}):(0,b.jsx)(k,{detail:u(o,`ui.empty.listDetail`)});if(N(t)){let i=R(t);return i.length?(0,b.jsx)(W,{items:i,titleKey:n,metaKey:r,limit:a}):(0,b.jsx)(B,{data:Object.fromEntries(Object.entries(t).filter(([e])=>!I(e)).map(([t,n])=>[t,Array.isArray(n)?`${e(n.length)} items`:N(n)?`available`:n])),limit:a})}return(0,b.jsx)(`div`,{className:`rounded-md border border-border bg-background/55 p-3 text-sm`,children:L(t)})}function U({result:e,successLabel:t}){let n=i(e=>e.mode),r=i(e=>e.language);return e?e.ok?(0,b.jsxs)(`div`,{className:`space-y-2 rounded-md border border-border bg-background p-3`,children:[(0,b.jsx)(S,{variant:`success`,children:t||u(r,`ui.requestCompleted`)}),n===`basic`?(0,b.jsx)(H,{value:e.data}):(0,b.jsx)(V,{value:e.data})]}):(0,b.jsx)(k,{title:u(r,`ui.requestUnavailable`),detail:e.error||(0,b.jsx)(z,{value:e.data})}):null}function W({items:e,titleKey:t=`title`,metaKey:n=`type`,limit:r=8}){let a=i(e=>e.mode),o=i(e=>e.language),c=h(e).slice(0,r);return c.length?(0,b.jsx)(`div`,{className:`grid gap-2`,children:c.map((e,r)=>(0,b.jsxs)(`div`,{className:`rounded-lg border border-border bg-background/55 p-3`,children:[(0,b.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,b.jsx)(`div`,{className:`font-medium`,children:a===`basic`?L(e[t]||e.name||e.label||`Item ${r+1}`):String(e[t]||e.name||e.id||`Record ${r+1}`)}),(0,b.jsx)(S,{variant:`muted`,children:a===`basic`?L(e[n]||e.status||e.state||`ready`):String(e[n]||e.status||e.state||`record`)})]}),e.summary||e.description||e.path||e.id&&e[t]!==e.id?(0,b.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:String(e.summary||e.description||e.path||e.id)}):null,a!==`basic`&&e.id&&e[t]!==e.id?(0,b.jsx)(`div`,{className:`mt-1 text-xs text-muted-foreground`,children:s(e.id,48)}):null]},String(e.id||e.name||r)))}):(0,b.jsx)(k,{detail:u(o,`ui.empty.listDetail`)})}function G({title:e,detail:t,target:n=`advanced`}){let r=i(e=>e.setMode),a=i(e=>e.language);return(0,b.jsx)(C,{children:(0,b.jsxs)(D,{className:`flex flex-col items-start gap-3 p-6`,children:[(0,b.jsx)(`div`,{className:`grid h-10 w-10 place-items-center rounded-md border border-border bg-background/70`,children:(0,b.jsx)(v,{className:`h-5 w-5 text-primary`})}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`div`,{className:`text-lg font-semibold`,children:e||u(a,`ui.modeGate.title`)}),(0,b.jsx)(`p`,{className:`mt-1 max-w-2xl text-sm leading-6 text-muted-foreground`,children:t||u(a,`ui.modeGate.detail`)})]}),(0,b.jsx)(m,{onClick:()=>r(n),children:n===`admin`?u(a,`ui.modeGate.admin`):u(a,`ui.modeGate.advanced`)})]})})}function K({label:e,successLabel:t,action:n,invalidate:r,variant:a=`outline`,disabled:s}){let l=d(),h=i(e=>e.language),g=t||u(h,`ui.done`),[v,x]=y.useState(null),S=f({mutationFn:n,onSuccess:async e=>{x(e.ok?g:e.error||u(h,`ui.status.unavailable`)),r&&await Promise.all(r.map(e=>l.invalidateQueries({queryKey:[e]})))}});return(0,b.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,b.jsxs)(m,{variant:a,disabled:s||S.isPending,onClick:()=>S.mutate(),children:[S.isPending?(0,b.jsx)(p,{className:`h-4 w-4 animate-spin`}):null,e]}),v?(0,b.jsxs)(`span`,{className:o(`inline-flex items-center gap-1 text-xs`,v===g?`text-success`:`text-warning`),children:[v===g?(0,b.jsx)(c,{className:`h-3.5 w-3.5`}):(0,b.jsx)(_,{className:`h-3.5 w-3.5`}),v]}):null]})}function q({tabs:e,value:t,onChange:n}){return(0,b.jsx)(`div`,{className:`inline-flex max-w-full flex-wrap gap-1 rounded-lg border border-border bg-muted/28 p-1`,children:e.map(e=>(0,b.jsx)(`button`,{onClick:()=>n(e.id),className:o(`h-9 rounded-md px-3.5 text-sm font-semibold transition`,t===e.id?`bg-card text-foreground shadow-sm`:`text-muted-foreground hover:bg-card/60 hover:text-foreground`),children:e.label},e.id))})}export{T as _,B as a,U as c,q as d,z as f,w as g,E as h,W as i,M as l,D as m,A as n,j as o,C as p,k as r,G as s,K as t,V as u,S as v,_ as y};
@@ -1 +0,0 @@
1
- import{I as e,M as t,P as n,S as r}from"./index-DPdcPoF0.js";var i=e(n()),a=t(),o=i.forwardRef(({className:e,...t},n)=>(0,a.jsx)(`textarea`,{ref:n,className:r(`min-h-28 w-full resize-y rounded-md border border-input bg-background/70 px-3 py-3 text-sm leading-6 outline-none transition placeholder:text-muted-foreground focus:border-ring focus:ring-2 focus:ring-ring/35 disabled:cursor-not-allowed disabled:opacity-50`,e),...t}));o.displayName=`Textarea`;export{o as t};
@@ -1,95 +0,0 @@
1
- """Knowledge-base / Obsidian vault tools over the local brain directory."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import Any, Dict, List, Optional
6
-
7
- from p_reinforce import BRAIN_DIR, STRUCTURE
8
- from tools import MAX_FILE_BYTES, ToolError
9
-
10
-
11
- def _safe_brain_folder(folder: str) -> str:
12
- if folder not in STRUCTURE:
13
- raise ToolError(f"Unknown knowledge folder: {folder}")
14
- return folder
15
-
16
-
17
- def knowledge_save(content: str, folder: str = "00_Raw", title: Optional[str] = None) -> Dict[str, Any]:
18
- folder = _safe_brain_folder(folder)
19
- if not content:
20
- raise ToolError("Knowledge content is required.")
21
- if len(content.encode("utf-8")) > MAX_FILE_BYTES:
22
- raise ToolError("Knowledge content is too large.")
23
-
24
- target_dir = BRAIN_DIR / folder
25
- target_dir.mkdir(parents=True, exist_ok=True)
26
- safe_title = title or content.strip().splitlines()[0][:60] or "note"
27
- safe_title = "".join(ch if ch.isalnum() or ch in (" ", "-", "_") else "" for ch in safe_title).strip()
28
- safe_title = "_".join(safe_title.split()) or "note"
29
- filename = f"{safe_title}.md"
30
- target = target_dir / filename
31
- counter = 2
32
- while target.exists():
33
- target = target_dir / f"{safe_title}_{counter}.md"
34
- counter += 1
35
- target.write_text(content, encoding="utf-8")
36
- return {"folder": folder, "filename": target.name, "path": str(target)}
37
-
38
-
39
- def knowledge_search(query: str, max_results: int = 5) -> Dict[str, Any]:
40
- if not query:
41
- raise ToolError("Query is required.")
42
- max_results = max(1, min(int(max_results), 20))
43
- query_lower = query.lower()
44
- results: List[Dict[str, Any]] = []
45
-
46
- for file_path in BRAIN_DIR.rglob("*.md"):
47
- if len(results) >= max_results:
48
- break
49
- try:
50
- content = file_path.read_text(encoding="utf-8")
51
- except UnicodeDecodeError:
52
- continue
53
- if query_lower in content.lower() or query_lower in file_path.name.lower():
54
- results.append(
55
- {
56
- "path": str(file_path),
57
- "relative_path": str(file_path.relative_to(BRAIN_DIR)),
58
- "preview": content[:500],
59
- }
60
- )
61
-
62
- return {"query": query, "results": results}
63
-
64
-
65
- def knowledge_tree() -> Dict[str, Any]:
66
- entries: List[Dict[str, Any]] = []
67
- for folder in STRUCTURE:
68
- root = BRAIN_DIR / folder
69
- root.mkdir(parents=True, exist_ok=True)
70
- for file_path in sorted(root.rglob("*.md")):
71
- entries.append(
72
- {
73
- "folder": folder,
74
- "relative_path": str(file_path.relative_to(BRAIN_DIR)),
75
- "size": file_path.stat().st_size,
76
- }
77
- )
78
- return {"root": str(BRAIN_DIR), "entries": entries}
79
-
80
-
81
- def obsidian_save(content: str, folder: str = "00_Raw", title: Optional[str] = None) -> Dict[str, Any]:
82
- result = knowledge_save(content, folder, title)
83
- result["vault_root"] = str(BRAIN_DIR)
84
- result["obsidian_uri_hint"] = f"obsidian://open?path={result['path']}"
85
- return result
86
-
87
-
88
- def obsidian_search(query: str, max_results: int = 5) -> Dict[str, Any]:
89
- result = knowledge_search(query, max_results)
90
- result["vault_root"] = str(BRAIN_DIR)
91
- return result
92
-
93
-
94
- def obsidian_tree() -> Dict[str, Any]:
95
- return knowledge_tree()