@agent-spaces/server 0.3.62 → 0.3.64
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/dist/adapters/agent-runtime-types.js +12 -0
- package/dist/adapters/claude-code-runtime/index.js +3 -0
- package/dist/adapters/claude-code-runtime/message-format.js +1 -1
- package/dist/adapters/codex-runtime.js +2 -2
- package/dist/adapters/git.js +161 -57
- package/dist/adapters/langchain-runtime.js +2 -2
- package/dist/adapters/open-agent-sdk-runtime.js +2 -2
- package/dist/agents/agent-designer.js +66 -12
- package/dist/agents/commit-agent.js +1 -0
- package/dist/agents/issue-agent-progress.js +4 -2
- package/dist/agents/issue-agent-runner.js +5 -5
- package/dist/agents/issue-task-controller.js +96 -15
- package/dist/app.js +123 -5
- package/dist/package.json +1 -1
- package/dist/routes/agent-commands.js +72 -0
- package/dist/routes/agent-sse.js +10 -2
- package/dist/routes/agent.js +15 -1
- package/dist/routes/database.js +345 -0
- package/dist/routes/git.js +52 -1
- package/dist/routes/hooks.js +88 -0
- package/dist/routes/issue.js +59 -1
- package/dist/routes/kanban.js +39 -0
- package/dist/routes/output-style.js +48 -0
- package/dist/routes/prompt-template.js +2 -2
- package/dist/routes/skill.js +86 -15
- package/dist/routes/task.js +13 -1
- package/dist/services/agent-commands.js +168 -0
- package/dist/services/builtin-tools/command-tools.js +117 -0
- package/dist/services/builtin-tools/database-tools.js +578 -0
- package/dist/services/builtin-tools/index.js +5 -0
- package/dist/services/builtin-tools/input-helpers.js +26 -0
- package/dist/services/builtin-tools/issue-tools.js +209 -0
- package/dist/services/builtin-tools/kanban-tools.js +277 -0
- package/dist/services/database-vector.js +244 -0
- package/dist/services/hook-engine.js +118 -0
- package/dist/services/issue.js +6 -0
- package/dist/services/kanban.js +50 -0
- package/dist/services/notification-hub/bot-agent.js +1 -0
- package/dist/services/output-style.js +134 -0
- package/dist/services/prompt-template.js +2 -2
- package/dist/services/skill.js +148 -35
- package/dist/storage/database-store.js +365 -0
- package/dist/storage/hook-store.js +55 -0
- package/dist/storage/kanban-store.js +142 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +26 -30
- package/dist/web/__next._head.txt +4 -4
- package/dist/web/__next._index.txt +14 -14
- package/dist/web/__next._tree.txt +3 -8
- package/dist/web/_next/static/chunks/0-9194nbxy_6d.js +1 -0
- package/dist/web/_next/static/chunks/0-f~0xmwl__u5.js +1 -0
- package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +1 -0
- package/dist/web/_next/static/chunks/002_j970b9gdx.js +1 -0
- package/dist/web/_next/static/chunks/01iqv28_snwus.js +1 -0
- package/dist/web/_next/static/chunks/01~quun6sefgl.js +1 -0
- package/dist/web/_next/static/chunks/02mf61htij8g0.js +31 -0
- package/dist/web/_next/static/chunks/03scq1-0ykve3.js +1 -0
- package/dist/web/_next/static/chunks/04a4vsq2wknm4.js +1 -0
- package/dist/web/_next/static/chunks/04dg4l4hv11q2.js +3 -0
- package/dist/web/_next/static/chunks/04fxddw-y20~-.js +7 -0
- package/dist/web/_next/static/chunks/04w7~5ooz_pwm.js +1 -0
- package/dist/web/_next/static/chunks/05oc21sj24wtq.js +1 -0
- package/dist/web/_next/static/chunks/{0zd1o3u04~qvo.js → 05psi2gtx~bev.js} +7 -7
- package/dist/web/_next/static/chunks/{0-oog4zg4_m~m.css → 062f9zqctzg.b.css} +0 -3
- package/dist/web/_next/static/chunks/{12odetnu-lyrr.js → 06whz1~s_7pva.js} +12 -12
- package/dist/web/_next/static/chunks/08ckpwmmwlors.js +3 -0
- package/dist/web/_next/static/chunks/08k~meqbd8d6v.js +1 -0
- package/dist/web/_next/static/chunks/099h96wjsdb25.js +2 -0
- package/dist/web/_next/static/chunks/09h23logvq65m.js +1 -0
- package/dist/web/_next/static/chunks/{0njy89g5coeyi.js → 0_8dm7bxp18xo.js} +6 -6
- package/dist/web/_next/static/chunks/0_mvduwjsm35w.js +1 -0
- package/dist/web/_next/static/chunks/0_vi1a~g4wx46.js +3 -0
- package/dist/web/_next/static/chunks/0a5y-vhf4i5id.js +3 -0
- package/dist/web/_next/static/chunks/0ake2f3x2uan4.js +24 -0
- package/dist/web/_next/static/chunks/{0tvd~rxgf0oh_.js → 0bbmx45w_h5np.js} +1 -1
- package/dist/web/_next/static/chunks/0ck8dw_9-1cdx.js +1 -0
- package/dist/web/_next/static/chunks/{07a0rktf_nr5h.js → 0ctg5qmw7uu.1.js} +2 -2
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +1 -0
- package/dist/web/_next/static/chunks/0f7cb9li~3jra.js +67 -0
- package/dist/web/_next/static/chunks/0fttswpzu69qx.js +1 -0
- package/dist/web/_next/static/chunks/0ghs9on7wodrm.js +1 -0
- package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +1 -0
- package/dist/web/_next/static/chunks/{0202ia13sijwb.js → 0h18ej5yf974e.js} +1 -1
- package/dist/web/_next/static/chunks/0h9cu-k6z5o08.js +1 -0
- package/dist/web/_next/static/chunks/0i39jifmxla7q.js +1 -0
- package/dist/web/_next/static/chunks/0iuf30t0rjsjv.js +19 -0
- package/dist/web/_next/static/chunks/0jb4~3qqkw2ps.js +1 -0
- package/dist/web/_next/static/chunks/0k4zdm72k_bfy.js +1 -0
- package/dist/web/_next/static/chunks/{08o-zmr-40r5g.js → 0m11vvph7q94-.js} +1 -1
- package/dist/web/_next/static/chunks/0n6_4so_afuwk.js +71 -0
- package/dist/web/_next/static/chunks/0nb8.iteznuvx.js +1 -0
- package/dist/web/_next/static/chunks/0np.d~hc1-pmh.js +4 -0
- package/dist/web/_next/static/chunks/{0qpq0~_58fe9a.js → 0oaq67r7ix.vg.js} +1 -1
- package/dist/web/_next/static/chunks/{0d_dp_4ofz0l3.css → 0ojcao3hdm36s.css} +0 -1
- package/dist/web/_next/static/chunks/0os58q93stt7j.js +3 -0
- package/dist/web/_next/static/chunks/{0gig.k.rq8d0x.js → 0ppr271hz0xoq.js} +1 -1
- package/dist/web/_next/static/chunks/0s9lmk8iauou3.js +1 -0
- package/dist/web/_next/static/chunks/0sp_zbx~w0am7.js +1 -0
- package/dist/web/_next/static/chunks/0tel~zsv4z8l_.js +1 -0
- package/dist/web/_next/static/chunks/0twamv4wr_dbv.js +1 -0
- package/dist/web/_next/static/chunks/0uhol5wafdbl~.js +1 -0
- package/dist/web/_next/static/chunks/0v3a_x4vt42kx.js +5 -0
- package/dist/web/_next/static/chunks/{002-dxhags4dj.js → 0v6hte2z-32ca.js} +2 -2
- package/dist/web/_next/static/chunks/0v7q4mys.mnm..css +1 -0
- package/dist/web/_next/static/chunks/0vbqaynjq8ga..js +3 -0
- package/dist/web/_next/static/chunks/0xbaakj0dfc0..js +1 -0
- package/dist/web/_next/static/chunks/{0..g0jl-8qup7.js → 0xoo17yef_b8g.js} +1 -1
- package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +1 -0
- package/dist/web/_next/static/chunks/0za1r07-6az6w.js +1 -0
- package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +1 -0
- package/dist/web/_next/static/chunks/0~3xm80~j9ddg.js +1 -0
- package/dist/web/_next/static/chunks/0~u.5r3-t7179.js +1 -0
- package/dist/web/_next/static/chunks/10l-9myrdo3x9.js +1 -0
- package/dist/web/_next/static/chunks/11-czmcci_55y.js +1 -0
- package/dist/web/_next/static/chunks/11k-.49r~1mfm.js +1 -0
- package/dist/web/_next/static/chunks/{0k.8qdk7oi_os.js → 128ugqd34tr_-.js} +1 -1
- package/dist/web/_next/static/chunks/12jm4gwmvq-0q.js +90 -0
- package/dist/web/_next/static/chunks/{0rke_patcovgr.js → 1442stwa0gbxe.js} +1 -1
- package/dist/web/_next/static/chunks/{0jokpgh485~28.js → 14hqmid8q4apf.js} +11 -11
- package/dist/web/_next/static/chunks/14s37n6h0_q3x.js +16 -0
- package/dist/web/_next/static/chunks/161ik5kfyuwtd.js +1 -0
- package/dist/web/_next/static/chunks/16sg-lflc8csx.js +1 -0
- package/dist/web/_next/static/chunks/17k~zbv0_4rep.js +1 -0
- package/dist/web/_next/static/chunks/17oc2l.ekcs8b.css +1 -0
- package/dist/web/_next/static/chunks/{turbopack-0lrdxynxb9-1t.js → turbopack-0ndm2zc_pdptk.js} +1 -1
- package/dist/web/_not-found/__next._full.txt +30 -31
- package/dist/web/_not-found/__next._head.txt +4 -4
- package/dist/web/_not-found/__next._index.txt +14 -14
- package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/web/_not-found/__next._not-found.txt +3 -3
- package/dist/web/_not-found/__next._tree.txt +3 -3
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +30 -31
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +26 -30
- package/dist/web/login/__next._full.txt +32 -36
- package/dist/web/login/__next._head.txt +4 -4
- package/dist/web/login/__next._index.txt +14 -14
- package/dist/web/login/__next._tree.txt +3 -8
- package/dist/web/login/__next.login.__PAGE__.txt +4 -4
- package/dist/web/login/__next.login.txt +3 -3
- package/dist/web/login.html +1 -1
- package/dist/web/login.txt +32 -36
- package/dist/web/settings/__next._full.txt +29 -34
- package/dist/web/settings/__next._head.txt +4 -4
- package/dist/web/settings/__next._index.txt +14 -14
- package/dist/web/settings/__next._tree.txt +3 -8
- package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
- package/dist/web/settings/__next.settings.txt +5 -5
- package/dist/web/settings/agents/__next._full.txt +27 -32
- package/dist/web/settings/agents/__next._head.txt +4 -4
- package/dist/web/settings/agents/__next._index.txt +14 -14
- package/dist/web/settings/agents/__next._tree.txt +3 -8
- package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
- package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
- package/dist/web/settings/agents/__next.settings.txt +5 -5
- package/dist/web/settings/agents.html +1 -1
- package/dist/web/settings/agents.txt +27 -32
- package/dist/web/settings/mcps/__next._full.txt +27 -32
- package/dist/web/settings/mcps/__next._head.txt +4 -4
- package/dist/web/settings/mcps/__next._index.txt +14 -14
- package/dist/web/settings/mcps/__next._tree.txt +3 -8
- package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
- package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
- package/dist/web/settings/mcps/__next.settings.txt +5 -5
- package/dist/web/settings/mcps.html +1 -1
- package/dist/web/settings/mcps.txt +27 -32
- package/dist/web/settings/models/__next._full.txt +27 -32
- package/dist/web/settings/models/__next._head.txt +4 -4
- package/dist/web/settings/models/__next._index.txt +14 -14
- package/dist/web/settings/models/__next._tree.txt +3 -8
- package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
- package/dist/web/settings/models/__next.settings.models.txt +3 -3
- package/dist/web/settings/models/__next.settings.txt +5 -5
- package/dist/web/settings/models.html +1 -1
- package/dist/web/settings/models.txt +27 -32
- package/dist/web/settings/output-styles/__next._full.txt +38 -0
- package/dist/web/settings/output-styles/__next._head.txt +6 -0
- package/dist/web/settings/output-styles/__next._index.txt +15 -0
- package/dist/web/settings/output-styles/__next._tree.txt +3 -0
- package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +9 -0
- package/dist/web/settings/output-styles/__next.settings.output-styles.txt +5 -0
- package/dist/web/settings/output-styles/__next.settings.txt +7 -0
- package/dist/web/settings/output-styles.html +1 -0
- package/dist/web/settings/output-styles.txt +38 -0
- package/dist/web/settings/prompts/__next._full.txt +27 -32
- package/dist/web/settings/prompts/__next._head.txt +4 -4
- package/dist/web/settings/prompts/__next._index.txt +14 -14
- package/dist/web/settings/prompts/__next._tree.txt +3 -8
- package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
- package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
- package/dist/web/settings/prompts/__next.settings.txt +5 -5
- package/dist/web/settings/prompts.html +1 -1
- package/dist/web/settings/prompts.txt +27 -32
- package/dist/web/settings/providers/__next._full.txt +27 -32
- package/dist/web/settings/providers/__next._head.txt +4 -4
- package/dist/web/settings/providers/__next._index.txt +14 -14
- package/dist/web/settings/providers/__next._tree.txt +3 -8
- package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
- package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
- package/dist/web/settings/providers/__next.settings.txt +5 -5
- package/dist/web/settings/providers.html +1 -1
- package/dist/web/settings/providers.txt +27 -32
- package/dist/web/settings/skills/__next._full.txt +27 -32
- package/dist/web/settings/skills/__next._head.txt +4 -4
- package/dist/web/settings/skills/__next._index.txt +14 -14
- package/dist/web/settings/skills/__next._tree.txt +3 -8
- package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
- package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
- package/dist/web/settings/skills/__next.settings.txt +5 -5
- package/dist/web/settings/skills.html +1 -1
- package/dist/web/settings/skills.txt +27 -32
- package/dist/web/settings/tools/__next._full.txt +38 -0
- package/dist/web/settings/tools/__next._head.txt +6 -0
- package/dist/web/settings/tools/__next._index.txt +15 -0
- package/dist/web/settings/tools/__next._tree.txt +3 -0
- package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +9 -0
- package/dist/web/settings/tools/__next.settings.tools.txt +5 -0
- package/dist/web/settings/tools/__next.settings.txt +7 -0
- package/dist/web/settings/tools.html +1 -0
- package/dist/web/settings/tools.txt +38 -0
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +29 -34
- package/dist/web/workflows/__next._full.txt +34 -37
- package/dist/web/workflows/__next._head.txt +4 -4
- package/dist/web/workflows/__next._index.txt +14 -14
- package/dist/web/workflows/__next._tree.txt +3 -8
- package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
- package/dist/web/workflows/__next.workflows.txt +3 -3
- package/dist/web/workflows.html +1 -1
- package/dist/web/workflows.txt +34 -37
- package/dist/web/workspace/_/__next._full.txt +32 -77
- package/dist/web/workspace/_/__next._head.txt +4 -4
- package/dist/web/workspace/_/__next._index.txt +14 -14
- package/dist/web/workspace/_/__next._tree.txt +4 -23
- package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -18
- package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
- package/dist/web/workspace/_/__next.workspace.txt +3 -3
- package/dist/web/workspace/_.html +1 -1
- package/dist/web/workspace/_.txt +32 -77
- package/dist/web/workspaces/__next._full.txt +32 -38
- package/dist/web/workspaces/__next._head.txt +4 -4
- package/dist/web/workspaces/__next._index.txt +14 -14
- package/dist/web/workspaces/__next._tree.txt +3 -8
- package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
- package/dist/web/workspaces/__next.workspaces.txt +3 -3
- package/dist/web/workspaces.html +1 -1
- package/dist/web/workspaces.txt +32 -38
- package/dist/ws/agent-prompt.js +45 -8
- package/dist/ws/agent-runner.js +10 -6
- package/package.json +11 -10
- package/public/output-styles/carmack-mode.md +381 -0
- package/public/output-styles/codex-rigor-mode.md +114 -0
- package/public/output-styles/dhh-mode.md +265 -0
- package/public/output-styles/evan-you-mode.md +539 -0
- package/public/output-styles/index.json +37 -0
- package/public/output-styles/jobs-mode.md +369 -0
- package/public/output-styles/linus-mode.md +135 -0
- package/public/output-styles/uncle-bob-mode.md +221 -0
- package/public/prompt/andrej-karpathy-skills.md +65 -0
- package/public/prompt/claude-token-efficient-coding.md +35 -0
- package/public/prompt/index.json +12 -0
- package/public/skills/index.json +92 -0
- package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +243 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +44 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +46 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +124 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +124 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +438 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +29 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +40 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +58 -0
- package/public/skills/superpowers/brainstorming/SKILL.md +164 -0
- package/public/skills/superpowers/brainstorming/scripts/frame-template.html +214 -0
- package/public/skills/superpowers/brainstorming/scripts/helper.js +88 -0
- package/public/skills/superpowers/brainstorming/scripts/server.cjs +354 -0
- package/public/skills/superpowers/brainstorming/scripts/start-server.sh +148 -0
- package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +56 -0
- package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/public/skills/superpowers/brainstorming/visual-companion.md +287 -0
- package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +182 -0
- package/public/skills/superpowers/executing-plans/SKILL.md +70 -0
- package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +251 -0
- package/public/skills/superpowers/receiving-code-review/SKILL.md +213 -0
- package/public/skills/superpowers/requesting-code-review/SKILL.md +103 -0
- package/public/skills/superpowers/requesting-code-review/code-reviewer.md +168 -0
- package/public/skills/superpowers/subagent-driven-development/SKILL.md +279 -0
- package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +25 -0
- package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +113 -0
- package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +119 -0
- package/public/skills/superpowers/systematic-debugging/SKILL.md +296 -0
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +115 -0
- package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +122 -0
- package/public/skills/superpowers/systematic-debugging/find-polluter.sh +63 -0
- package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +169 -0
- package/public/skills/superpowers/systematic-debugging/test-academic.md +14 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +58 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +68 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +69 -0
- package/public/skills/superpowers/test-driven-development/SKILL.md +371 -0
- package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +299 -0
- package/public/skills/superpowers/using-git-worktrees/SKILL.md +215 -0
- package/public/skills/superpowers/using-superpowers/SKILL.md +117 -0
- package/public/skills/superpowers/using-superpowers/references/codex-tools.md +59 -0
- package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +42 -0
- package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +51 -0
- package/public/skills/superpowers/verification-before-completion/SKILL.md +139 -0
- package/public/skills/superpowers/writing-plans/SKILL.md +152 -0
- package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/public/skills/superpowers/writing-skills/SKILL.md +655 -0
- package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +1150 -0
- package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +172 -0
- package/public/skills/superpowers/writing-skills/persuasion-principles.md +187 -0
- package/public/skills/superpowers/writing-skills/render-graphs.js +168 -0
- package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +384 -0
- package/dist/web/_next/static/chunks/0-81wi7xr2nd-.js +0 -270
- package/dist/web/_next/static/chunks/00lca9lsasdm7.js +0 -1
- package/dist/web/_next/static/chunks/01gi~q0c6ez6..js +0 -1
- package/dist/web/_next/static/chunks/02shswpmybici.js +0 -1
- package/dist/web/_next/static/chunks/05tx6hzdtkgi9.js +0 -2
- package/dist/web/_next/static/chunks/07nbyndvzftr1.js +0 -3
- package/dist/web/_next/static/chunks/0bn~onkv~9xza.js +0 -1
- package/dist/web/_next/static/chunks/0g-0n6glz_z6w.js +0 -1
- package/dist/web/_next/static/chunks/0gyede80jpy3n.js +0 -4
- package/dist/web/_next/static/chunks/0hrbuvzuxrjfl.js +0 -1
- package/dist/web/_next/static/chunks/0i51q.5s_-.vh.css +0 -1
- package/dist/web/_next/static/chunks/0qf163pbrwy4z.js +0 -1
- package/dist/web/_next/static/chunks/0rnt-f3pjxb-d.js +0 -5
- package/dist/web/_next/static/chunks/0tgbcgsca9mrg.js +0 -1
- package/dist/web/_next/static/chunks/0tyhv6.y7~yxd.js +0 -1
- package/dist/web/_next/static/chunks/0u7_qd9hzqwac.js +0 -1
- package/dist/web/_next/static/chunks/0vuvql8rloda5.js +0 -1
- package/dist/web/_next/static/chunks/0wv0h27jafag4.js +0 -1
- package/dist/web/_next/static/chunks/0wwvc4zc2q6bn.js +0 -1
- package/dist/web/_next/static/chunks/0xmmk3vebw8xs.js +0 -1
- package/dist/web/_next/static/chunks/0xwqf.llmm_u2.js +0 -31
- package/dist/web/_next/static/chunks/0yo22_w53mo~5.js +0 -1
- package/dist/web/_next/static/chunks/12c0jp0qvlr1t.js +0 -1
- package/dist/web/_next/static/chunks/12pg1nn3v~~5k.js +0 -1
- package/dist/web/_next/static/chunks/16cyr8ilpx1nn.js +0 -1
- package/dist/web/_next/static/media/0a7740363b4d4863-s.1110aazvokzp..woff2 +0 -0
- package/dist/web/_next/static/media/0da9c7f357bd9d4d-s.0ek5sshv8wk3m.woff2 +0 -0
- package/dist/web/_next/static/media/1b99372b3eaef0c8-s.p.0gx2haw2tmll8.woff2 +0 -0
- package/dist/web/_next/static/media/41e95f694c5c4549-s.0r1jrq7neqdsq.woff2 +0 -0
- package/dist/web/_next/static/media/5c285b27cdda1fe8-s.p.0yo6-5yoeeudq.woff2 +0 -0
- package/dist/web/_next/static/media/5f9d24ebef5d5292-s.0esuu2f5si~v8.woff2 +0 -0
- package/dist/web/_next/static/media/6c55a692938ebbbc-s.0g6rbszwfgn9y.woff2 +0 -0
- package/dist/web/_next/static/media/8e6fa89aa22d24ec-s.p.0uvzar8hswo3p.woff2 +0 -0
- package/dist/web/_next/static/media/a218039a3287bcfd-s.p.17-1enzs_j91b.woff2 +0 -0
- package/dist/web/_next/static/media/b2ea385cb5ae8625-s.0kjod.kaq1k69.woff2 +0 -0
- package/dist/web/_next/static/media/bdc7e24a509eb931-s.0apt5mko2.qn3.woff2 +0 -0
- package/dist/web/_next/static/media/c3cb240f9c892514-s.163v2i5cux7-c.woff2 +0 -0
- package/dist/web/_next/static/media/e2334d715941921e-s.p.12skym0rqknxy.woff2 +0 -0
- package/public/avatars/1777813826407-bea0ja-minimax.svg +0 -1
- package/public/avatars/1777813967088-3xlvd0-minimax.svg +0 -1
- package/public/avatars/1777814041714-yp0qeq-minimax.svg +0 -1
- package/public/avatars/1777904986095-rg26je-icon.png +0 -0
- package/public/avatars/1778953228323-5je54x-user.jpg +0 -0
- package/public/avatars/1778954057880-g01q6y-user.jpg +0 -0
- /package/dist/web/_next/static/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_ssgManifest.js +0 -0
- /package/public/avatars/{1777815865622-08wp9m-user.jpg → user.jpg} +0 -0
package/dist/services/skill.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { basename, join } from 'node:path';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { execFileSync } from 'node:child_process';
|
|
3
6
|
import { ensureDir, getDataDir } from '../storage/json-store.js';
|
|
4
7
|
import { listTemplates } from './agent.js';
|
|
5
8
|
const SKILL_FILE = 'SKILL.md';
|
|
@@ -12,17 +15,16 @@ function getSkillMetaPath() {
|
|
|
12
15
|
function readMeta() {
|
|
13
16
|
const path = getSkillMetaPath();
|
|
14
17
|
if (!existsSync(path))
|
|
15
|
-
return { favorites: [], groups: {}
|
|
18
|
+
return { favorites: [], groups: {} };
|
|
16
19
|
try {
|
|
17
20
|
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
18
21
|
return {
|
|
19
22
|
favorites: raw.favorites || [],
|
|
20
23
|
groups: raw.groups || {},
|
|
21
|
-
disabled: raw.disabled || [],
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
catch {
|
|
25
|
-
return { favorites: [], groups: {}
|
|
27
|
+
return { favorites: [], groups: {} };
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
function writeMeta(meta) {
|
|
@@ -84,7 +86,6 @@ export function listSkills() {
|
|
|
84
86
|
filename: `${folderName}/${SKILL_FILE}`,
|
|
85
87
|
content,
|
|
86
88
|
favorited: meta.favorites.includes(folderName),
|
|
87
|
-
enabled: !meta.disabled.includes(folderName),
|
|
88
89
|
group: meta.groups[folderName] || '',
|
|
89
90
|
boundAgents,
|
|
90
91
|
};
|
|
@@ -133,7 +134,6 @@ export function importSkill(filename, content, group) {
|
|
|
133
134
|
filename: `${folderName}/${SKILL_FILE}`,
|
|
134
135
|
content,
|
|
135
136
|
favorited: false,
|
|
136
|
-
enabled: true,
|
|
137
137
|
group: group || '',
|
|
138
138
|
boundAgents: [],
|
|
139
139
|
};
|
|
@@ -153,7 +153,6 @@ export function importSkillsBatch(items) {
|
|
|
153
153
|
filename: `${folderName}/${SKILL_FILE}`,
|
|
154
154
|
content: item.content,
|
|
155
155
|
favorited: false,
|
|
156
|
-
enabled: true,
|
|
157
156
|
group: item.group || '',
|
|
158
157
|
boundAgents: [],
|
|
159
158
|
});
|
|
@@ -161,6 +160,50 @@ export function importSkillsBatch(items) {
|
|
|
161
160
|
writeMeta(meta);
|
|
162
161
|
return results;
|
|
163
162
|
}
|
|
163
|
+
export function importSkillFromStore(storePath, group) {
|
|
164
|
+
// storePath is like "group-name/skill-name", relative to public/skills/
|
|
165
|
+
const publicSkillsDir = join(getDataDir(), '..', 'public', 'skills');
|
|
166
|
+
// Try relative to package first
|
|
167
|
+
let srcDir = null;
|
|
168
|
+
const candidates = [
|
|
169
|
+
join(process.cwd(), 'public', 'skills', storePath),
|
|
170
|
+
join(import.meta.dirname ?? '', '..', 'public', 'skills', storePath),
|
|
171
|
+
];
|
|
172
|
+
for (const c of candidates) {
|
|
173
|
+
if (existsSync(c) && statSync(c).isDirectory()) {
|
|
174
|
+
srcDir = c;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (!srcDir)
|
|
179
|
+
return null;
|
|
180
|
+
const skillName = basename(storePath);
|
|
181
|
+
const skillsDir = getSkillsDir();
|
|
182
|
+
const destDir = join(skillsDir, skillName);
|
|
183
|
+
// Copy entire folder
|
|
184
|
+
if (existsSync(destDir))
|
|
185
|
+
rmSync(destDir, { recursive: true, force: true });
|
|
186
|
+
cpSync(srcDir, destDir, { recursive: true, force: true });
|
|
187
|
+
// Set group in meta
|
|
188
|
+
if (group) {
|
|
189
|
+
const meta = readMeta();
|
|
190
|
+
meta.groups[skillName] = group;
|
|
191
|
+
writeMeta(meta);
|
|
192
|
+
}
|
|
193
|
+
// Read content for return
|
|
194
|
+
const skillFile = join(destDir, SKILL_FILE);
|
|
195
|
+
const content = existsSync(skillFile) ? readFileSync(skillFile, 'utf-8') : '';
|
|
196
|
+
const fm = parseFrontmatter(content);
|
|
197
|
+
return {
|
|
198
|
+
name: skillName,
|
|
199
|
+
description: fm.description || '',
|
|
200
|
+
filename: `${skillName}/${SKILL_FILE}`,
|
|
201
|
+
content,
|
|
202
|
+
favorited: false,
|
|
203
|
+
group,
|
|
204
|
+
boundAgents: [],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
164
207
|
export function toggleFavorite(name) {
|
|
165
208
|
const meta = readMeta();
|
|
166
209
|
const idx = meta.favorites.indexOf(name);
|
|
@@ -173,31 +216,6 @@ export function toggleFavorite(name) {
|
|
|
173
216
|
writeMeta(meta);
|
|
174
217
|
return idx < 0;
|
|
175
218
|
}
|
|
176
|
-
export function toggleEnabled(name) {
|
|
177
|
-
const meta = readMeta();
|
|
178
|
-
const idx = meta.disabled.indexOf(name);
|
|
179
|
-
if (idx >= 0) {
|
|
180
|
-
meta.disabled.splice(idx, 1);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
meta.disabled.push(name);
|
|
184
|
-
}
|
|
185
|
-
writeMeta(meta);
|
|
186
|
-
return idx >= 0; // true = now enabled
|
|
187
|
-
}
|
|
188
|
-
export function toggleAllEnabled(names, enabled) {
|
|
189
|
-
const meta = readMeta();
|
|
190
|
-
if (enabled) {
|
|
191
|
-
meta.disabled = meta.disabled.filter((n) => !names.includes(n));
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
const set = new Set(meta.disabled);
|
|
195
|
-
for (const n of names)
|
|
196
|
-
set.add(n);
|
|
197
|
-
meta.disabled = [...set];
|
|
198
|
-
}
|
|
199
|
-
writeMeta(meta);
|
|
200
|
-
}
|
|
201
219
|
export function updateSkillContent(name, content) {
|
|
202
220
|
const skillsDir = getSkillsDir();
|
|
203
221
|
const filePath = join(skillsDir, name, SKILL_FILE);
|
|
@@ -216,7 +234,6 @@ export function deleteSkill(name) {
|
|
|
216
234
|
const meta = readMeta();
|
|
217
235
|
meta.favorites = meta.favorites.filter((n) => n !== name);
|
|
218
236
|
delete meta.groups[name];
|
|
219
|
-
meta.disabled = meta.disabled.filter((n) => n !== name);
|
|
220
237
|
writeMeta(meta);
|
|
221
238
|
return true;
|
|
222
239
|
}
|
|
@@ -238,7 +255,10 @@ export function checkSkillSync() {
|
|
|
238
255
|
const agentFile = join(agentSkillsDir, `${skillName}.md`);
|
|
239
256
|
if (!existsSync(globalFolder) || !statSync(globalFolder).isDirectory())
|
|
240
257
|
continue;
|
|
241
|
-
|
|
258
|
+
// Use SKILL.md file mtime — directory mtime is unreliable on Windows
|
|
259
|
+
if (!existsSync(globalSkillFile))
|
|
260
|
+
continue;
|
|
261
|
+
const globalStat = statSync(globalSkillFile);
|
|
242
262
|
const agentExists = existsSync(agentFolder) || existsSync(agentFile);
|
|
243
263
|
if (!agentExists) {
|
|
244
264
|
// Agent skill missing — needs sync
|
|
@@ -251,8 +271,13 @@ export function checkSkillSync() {
|
|
|
251
271
|
});
|
|
252
272
|
continue;
|
|
253
273
|
}
|
|
254
|
-
|
|
255
|
-
const
|
|
274
|
+
// Find the actual agent SKILL.md path
|
|
275
|
+
const agentSkillFile = existsSync(agentFolder)
|
|
276
|
+
? join(agentFolder, SKILL_FILE)
|
|
277
|
+
: agentFile;
|
|
278
|
+
if (!existsSync(agentSkillFile))
|
|
279
|
+
continue;
|
|
280
|
+
const agentStat = statSync(agentSkillFile);
|
|
256
281
|
if (globalStat.mtimeMs > agentStat.mtimeMs) {
|
|
257
282
|
result.push({
|
|
258
283
|
agentId: agent.id,
|
|
@@ -290,4 +315,92 @@ export function syncSkills(items) {
|
|
|
290
315
|
}
|
|
291
316
|
return synced;
|
|
292
317
|
}
|
|
318
|
+
export function listSkillFiles(name) {
|
|
319
|
+
const skillsDir = getSkillsDir();
|
|
320
|
+
const folderPath = join(skillsDir, name);
|
|
321
|
+
if (!existsSync(folderPath) || !statSync(folderPath).isDirectory())
|
|
322
|
+
return [];
|
|
323
|
+
function walk(dir, prefix) {
|
|
324
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
325
|
+
const result = [];
|
|
326
|
+
for (const entry of entries) {
|
|
327
|
+
if (entry.name.startsWith('_') || entry.name === '.DS_Store')
|
|
328
|
+
continue;
|
|
329
|
+
const fullPath = join(dir, entry.name);
|
|
330
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
331
|
+
if (entry.isDirectory()) {
|
|
332
|
+
result.push({ name: entry.name, path: relativePath, isDirectory: true });
|
|
333
|
+
result.push(...walk(fullPath, relativePath));
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
result.push({ name: entry.name, path: relativePath, isDirectory: false });
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
return walk(folderPath, '');
|
|
342
|
+
}
|
|
343
|
+
export function readSkillFile(name, filePath) {
|
|
344
|
+
const skillsDir = getSkillsDir();
|
|
345
|
+
const fullPath = join(skillsDir, name, filePath);
|
|
346
|
+
// Prevent path traversal
|
|
347
|
+
if (!fullPath.startsWith(join(skillsDir, name)))
|
|
348
|
+
return null;
|
|
349
|
+
if (!existsSync(fullPath) || !statSync(fullPath).isFile())
|
|
350
|
+
return null;
|
|
351
|
+
return readFileSync(fullPath, 'utf-8');
|
|
352
|
+
}
|
|
353
|
+
export function writeSkillFile(name, filePath, content) {
|
|
354
|
+
const skillsDir = getSkillsDir();
|
|
355
|
+
const fullPath = join(skillsDir, name, filePath);
|
|
356
|
+
// Prevent path traversal
|
|
357
|
+
if (!fullPath.startsWith(join(skillsDir, name)))
|
|
358
|
+
return false;
|
|
359
|
+
const dir = join(fullPath, '..');
|
|
360
|
+
ensureDir(dir);
|
|
361
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
export function importSkillsFromGit(gitUrl) {
|
|
365
|
+
const cloneDir = join(tmpdir(), `agent-spaces-git-${randomUUID()}`);
|
|
366
|
+
try {
|
|
367
|
+
execFileSync('git', ['clone', '--depth', '1', gitUrl, cloneDir], {
|
|
368
|
+
timeout: 60_000,
|
|
369
|
+
stdio: 'pipe',
|
|
370
|
+
});
|
|
371
|
+
const results = [];
|
|
372
|
+
function walk(dir) {
|
|
373
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
374
|
+
for (const entry of entries) {
|
|
375
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules')
|
|
376
|
+
continue;
|
|
377
|
+
const full = join(dir, entry.name);
|
|
378
|
+
if (entry.isDirectory()) {
|
|
379
|
+
walk(full);
|
|
380
|
+
}
|
|
381
|
+
else if (entry.name === SKILL_FILE || entry.name.endsWith('.md')) {
|
|
382
|
+
const folderName = basename(dir);
|
|
383
|
+
if (folderName === basename(cloneDir))
|
|
384
|
+
continue; // skip repo root
|
|
385
|
+
const existing = results.find((r) => r.name === folderName);
|
|
386
|
+
// Prefer SKILL.md over generic .md
|
|
387
|
+
if (!existing || (entry.name === SKILL_FILE && existing.content)) {
|
|
388
|
+
const content = readFileSync(full, 'utf-8');
|
|
389
|
+
if (!existing) {
|
|
390
|
+
results.push({ name: folderName, content });
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
existing.content = content;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
walk(cloneDir);
|
|
400
|
+
return results;
|
|
401
|
+
}
|
|
402
|
+
finally {
|
|
403
|
+
rmSync(cloneDir, { recursive: true, force: true });
|
|
404
|
+
}
|
|
405
|
+
}
|
|
293
406
|
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { v4 as uuid } from 'uuid';
|
|
5
|
+
import { getDataDir, ensureDir } from './json-store.js';
|
|
6
|
+
let db = null;
|
|
7
|
+
function openDb() {
|
|
8
|
+
if (db)
|
|
9
|
+
return db;
|
|
10
|
+
const dir = join(getDataDir(), 'database');
|
|
11
|
+
ensureDir(dir);
|
|
12
|
+
db = new DatabaseSync(join(dir, 'database.sqlite'));
|
|
13
|
+
const hasDocNodes = Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'doc_nodes'").get());
|
|
14
|
+
const hasDatabaseId = hasDocNodes
|
|
15
|
+
&& db.prepare('PRAGMA table_info(doc_nodes)').all()
|
|
16
|
+
.some((column) => column.name === 'database_id');
|
|
17
|
+
if (hasDocNodes && !hasDatabaseId) {
|
|
18
|
+
db.exec('DROP TABLE IF EXISTS doc_nodes; DROP TABLE IF EXISTS databases;');
|
|
19
|
+
}
|
|
20
|
+
db.exec(`
|
|
21
|
+
CREATE TABLE IF NOT EXISTS databases (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
workspace_id TEXT NOT NULL,
|
|
24
|
+
name TEXT NOT NULL DEFAULT '',
|
|
25
|
+
description TEXT NOT NULL DEFAULT '',
|
|
26
|
+
embedding_model_id TEXT,
|
|
27
|
+
created_at INTEGER NOT NULL,
|
|
28
|
+
updated_at INTEGER NOT NULL
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS doc_nodes (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
workspace_id TEXT NOT NULL,
|
|
34
|
+
database_id TEXT NOT NULL,
|
|
35
|
+
title TEXT NOT NULL DEFAULT '',
|
|
36
|
+
icon TEXT NOT NULL DEFAULT '',
|
|
37
|
+
cover TEXT NOT NULL DEFAULT '',
|
|
38
|
+
content TEXT NOT NULL DEFAULT '',
|
|
39
|
+
parent_id TEXT,
|
|
40
|
+
is_trash INTEGER NOT NULL DEFAULT 0,
|
|
41
|
+
created_at INTEGER NOT NULL,
|
|
42
|
+
updated_at INTEGER NOT NULL
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE TABLE IF NOT EXISTS database_embeddings (
|
|
46
|
+
workspace_id TEXT NOT NULL,
|
|
47
|
+
database_id TEXT NOT NULL,
|
|
48
|
+
node_id TEXT NOT NULL,
|
|
49
|
+
title TEXT NOT NULL DEFAULT '',
|
|
50
|
+
path TEXT NOT NULL DEFAULT '',
|
|
51
|
+
content TEXT NOT NULL DEFAULT '',
|
|
52
|
+
content_hash TEXT NOT NULL,
|
|
53
|
+
embedding TEXT NOT NULL,
|
|
54
|
+
model_id TEXT NOT NULL DEFAULT '',
|
|
55
|
+
agent_id TEXT NOT NULL DEFAULT '',
|
|
56
|
+
updated_at INTEGER NOT NULL,
|
|
57
|
+
PRIMARY KEY (workspace_id, database_id, node_id)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE TABLE IF NOT EXISTS doc_node_versions (
|
|
61
|
+
id TEXT PRIMARY KEY,
|
|
62
|
+
workspace_id TEXT NOT NULL,
|
|
63
|
+
database_id TEXT NOT NULL,
|
|
64
|
+
node_id TEXT NOT NULL,
|
|
65
|
+
title TEXT NOT NULL DEFAULT '',
|
|
66
|
+
patch_json TEXT NOT NULL,
|
|
67
|
+
old_hash TEXT NOT NULL,
|
|
68
|
+
new_hash TEXT NOT NULL,
|
|
69
|
+
created_at INTEGER NOT NULL
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
CREATE INDEX IF NOT EXISTS idx_databases_workspace ON databases(workspace_id);
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_doc_nodes_workspace ON doc_nodes(workspace_id);
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_doc_nodes_database ON doc_nodes(workspace_id, database_id);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_doc_nodes_parent ON doc_nodes(workspace_id, database_id, parent_id);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_database_embeddings_database ON database_embeddings(workspace_id, database_id);
|
|
77
|
+
CREATE INDEX IF NOT EXISTS idx_doc_node_versions_node ON doc_node_versions(workspace_id, database_id, node_id, created_at DESC);
|
|
78
|
+
`);
|
|
79
|
+
ensureColumn('databases', 'embedding_model_id', 'TEXT');
|
|
80
|
+
migrateEmbeddingModelColumn();
|
|
81
|
+
return db;
|
|
82
|
+
}
|
|
83
|
+
function ensureColumn(table, column, type) {
|
|
84
|
+
const database = db;
|
|
85
|
+
const exists = database.prepare(`PRAGMA table_info(${table})`).all()
|
|
86
|
+
.some((item) => item.name === column);
|
|
87
|
+
if (!exists)
|
|
88
|
+
database.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${type}`);
|
|
89
|
+
}
|
|
90
|
+
function migrateEmbeddingModelColumn() {
|
|
91
|
+
const database = db;
|
|
92
|
+
const columns = database.prepare('PRAGMA table_info(databases)').all();
|
|
93
|
+
const hasLegacyAgentColumn = columns.some((item) => item.name === 'embedding_agent_id');
|
|
94
|
+
if (!hasLegacyAgentColumn)
|
|
95
|
+
return;
|
|
96
|
+
database.exec(`
|
|
97
|
+
UPDATE databases
|
|
98
|
+
SET embedding_model_id = COALESCE(embedding_model_id, embedding_agent_id)
|
|
99
|
+
WHERE embedding_agent_id IS NOT NULL AND embedding_agent_id != ''
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
function rowToDatabase(row) {
|
|
103
|
+
return {
|
|
104
|
+
id: row.id,
|
|
105
|
+
workspaceId: row.workspace_id,
|
|
106
|
+
name: row.name,
|
|
107
|
+
description: row.description,
|
|
108
|
+
embeddingModelId: row.embedding_model_id || undefined,
|
|
109
|
+
createdAt: row.created_at,
|
|
110
|
+
updatedAt: row.updated_at,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function rowToNode(row) {
|
|
114
|
+
return {
|
|
115
|
+
id: row.id,
|
|
116
|
+
databaseId: row.database_id,
|
|
117
|
+
title: row.title,
|
|
118
|
+
icon: row.icon,
|
|
119
|
+
cover: row.cover,
|
|
120
|
+
content: row.content,
|
|
121
|
+
parentId: row.parent_id || null,
|
|
122
|
+
isTrash: !!row.is_trash,
|
|
123
|
+
createdAt: row.created_at,
|
|
124
|
+
updatedAt: row.updated_at,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function rowToVersionRow(row) {
|
|
128
|
+
return {
|
|
129
|
+
id: row.id,
|
|
130
|
+
nodeId: row.node_id,
|
|
131
|
+
databaseId: row.database_id,
|
|
132
|
+
title: row.title,
|
|
133
|
+
patch: JSON.parse(row.patch_json),
|
|
134
|
+
oldHash: row.old_hash,
|
|
135
|
+
newHash: row.new_hash,
|
|
136
|
+
createdAt: row.created_at,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export function listDatabases(workspaceId) {
|
|
140
|
+
const database = openDb();
|
|
141
|
+
const rows = database.prepare('SELECT * FROM databases WHERE workspace_id = ? ORDER BY created_at ASC').all(workspaceId);
|
|
142
|
+
return rows.map(rowToDatabase);
|
|
143
|
+
}
|
|
144
|
+
export function getDatabase(workspaceId, databaseId) {
|
|
145
|
+
const database = openDb();
|
|
146
|
+
const row = database.prepare('SELECT * FROM databases WHERE workspace_id = ? AND id = ?').get(workspaceId, databaseId);
|
|
147
|
+
return row ? rowToDatabase(row) : null;
|
|
148
|
+
}
|
|
149
|
+
export function getDefaultDatabase(workspaceId) {
|
|
150
|
+
const existing = listDatabases(workspaceId)[0];
|
|
151
|
+
if (existing)
|
|
152
|
+
return existing;
|
|
153
|
+
return createDatabase(workspaceId, { name: 'Default Database' });
|
|
154
|
+
}
|
|
155
|
+
export function createDatabase(workspaceId, input) {
|
|
156
|
+
const database = openDb();
|
|
157
|
+
const id = input.id || uuid();
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
database.prepare(`INSERT INTO databases (id, workspace_id, name, description, created_at, updated_at)
|
|
160
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(id, workspaceId, input.name?.trim() || 'Untitled Database', input.description || '', now, now);
|
|
161
|
+
return getDatabase(workspaceId, id);
|
|
162
|
+
}
|
|
163
|
+
export function updateDatabase(workspaceId, databaseId, updates) {
|
|
164
|
+
const existing = getDatabase(workspaceId, databaseId);
|
|
165
|
+
if (!existing)
|
|
166
|
+
return null;
|
|
167
|
+
const database = openDb();
|
|
168
|
+
const merged = { ...existing, ...updates, updatedAt: Date.now() };
|
|
169
|
+
database.prepare('UPDATE databases SET name = ?, description = ?, embedding_model_id = ?, updated_at = ? WHERE workspace_id = ? AND id = ?').run(merged.name.trim() || 'Untitled Database', merged.description, merged.embeddingModelId ?? null, merged.updatedAt, workspaceId, databaseId);
|
|
170
|
+
return getDatabase(workspaceId, databaseId);
|
|
171
|
+
}
|
|
172
|
+
export function deleteDatabase(workspaceId, databaseId) {
|
|
173
|
+
const database = openDb();
|
|
174
|
+
database.prepare('DELETE FROM doc_nodes WHERE workspace_id = ? AND database_id = ?').run(workspaceId, databaseId);
|
|
175
|
+
database.prepare('DELETE FROM database_embeddings WHERE workspace_id = ? AND database_id = ?').run(workspaceId, databaseId);
|
|
176
|
+
const result = database.prepare('DELETE FROM databases WHERE workspace_id = ? AND id = ?').run(workspaceId, databaseId);
|
|
177
|
+
if (result.changes > 0 && listDatabases(workspaceId).length === 0)
|
|
178
|
+
getDefaultDatabase(workspaceId);
|
|
179
|
+
return result.changes > 0;
|
|
180
|
+
}
|
|
181
|
+
export function listNodes(workspaceId, databaseId) {
|
|
182
|
+
const database = openDb();
|
|
183
|
+
const activeDatabaseId = databaseId ?? getDefaultDatabase(workspaceId).id;
|
|
184
|
+
const rows = database.prepare('SELECT * FROM doc_nodes WHERE workspace_id = ? AND database_id = ? ORDER BY created_at ASC').all(workspaceId, activeDatabaseId);
|
|
185
|
+
return rows.map(rowToNode);
|
|
186
|
+
}
|
|
187
|
+
export function getNode(workspaceId, nodeId, databaseId) {
|
|
188
|
+
const database = openDb();
|
|
189
|
+
const row = databaseId
|
|
190
|
+
? database.prepare('SELECT * FROM doc_nodes WHERE workspace_id = ? AND database_id = ? AND id = ?').get(workspaceId, databaseId, nodeId)
|
|
191
|
+
: database.prepare('SELECT * FROM doc_nodes WHERE workspace_id = ? AND id = ?').get(workspaceId, nodeId);
|
|
192
|
+
return row ? rowToNode(row) : null;
|
|
193
|
+
}
|
|
194
|
+
export function createNode(workspaceId, node) {
|
|
195
|
+
const database = openDb();
|
|
196
|
+
const databaseId = node.databaseId || getDefaultDatabase(workspaceId).id;
|
|
197
|
+
if (!getDatabase(workspaceId, databaseId))
|
|
198
|
+
throw new Error(`Database not found: ${databaseId}`);
|
|
199
|
+
const id = node.id || uuid();
|
|
200
|
+
const now = Date.now();
|
|
201
|
+
database.prepare(`INSERT INTO doc_nodes (id, workspace_id, database_id, title, icon, cover, content, parent_id, is_trash, created_at, updated_at)
|
|
202
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, workspaceId, databaseId, node.title || 'Untitled Document', node.icon || '\u{1F4DD}', node.cover || '', node.content || '', node.parentId ?? null, node.isTrash ? 1 : 0, node.createdAt || now, node.updatedAt || now);
|
|
203
|
+
return getNode(workspaceId, id, databaseId);
|
|
204
|
+
}
|
|
205
|
+
export function updateNode(workspaceId, nodeId, updates, databaseId) {
|
|
206
|
+
const existing = getNode(workspaceId, nodeId, databaseId);
|
|
207
|
+
if (!existing)
|
|
208
|
+
return null;
|
|
209
|
+
const database = openDb();
|
|
210
|
+
const merged = { ...existing, ...updates, updatedAt: Date.now() };
|
|
211
|
+
if (Object.hasOwn(updates, 'content') && merged.content !== existing.content) {
|
|
212
|
+
insertNodeVersion(database, workspaceId, existing, merged.content);
|
|
213
|
+
}
|
|
214
|
+
database.prepare(`UPDATE doc_nodes SET title = ?, icon = ?, cover = ?, content = ?, parent_id = ?, is_trash = ?, updated_at = ?
|
|
215
|
+
WHERE workspace_id = ? AND database_id = ? AND id = ?`).run(merged.title, merged.icon, merged.cover, merged.content, merged.parentId, merged.isTrash ? 1 : 0, merged.updatedAt, workspaceId, existing.databaseId, nodeId);
|
|
216
|
+
return getNode(workspaceId, nodeId, existing.databaseId);
|
|
217
|
+
}
|
|
218
|
+
export function listNodeVersions(workspaceId, nodeId, databaseId, limit = 50) {
|
|
219
|
+
const node = getNode(workspaceId, nodeId, databaseId);
|
|
220
|
+
if (!node)
|
|
221
|
+
return [];
|
|
222
|
+
const database = openDb();
|
|
223
|
+
const normalizedLimit = Number.isFinite(limit) ? Math.max(1, Math.min(100, Math.trunc(limit))) : 50;
|
|
224
|
+
const rows = database.prepare(`SELECT * FROM doc_node_versions
|
|
225
|
+
WHERE workspace_id = ? AND database_id = ? AND node_id = ?
|
|
226
|
+
ORDER BY created_at DESC
|
|
227
|
+
LIMIT ?`).all(workspaceId, node.databaseId, nodeId, normalizedLimit);
|
|
228
|
+
const stored = rows.map(rowToVersionRow);
|
|
229
|
+
let after = node.content;
|
|
230
|
+
return stored.map((item) => {
|
|
231
|
+
const before = applyReversePatch(after, item.patch);
|
|
232
|
+
const version = {
|
|
233
|
+
id: item.id,
|
|
234
|
+
nodeId: item.nodeId,
|
|
235
|
+
databaseId: item.databaseId,
|
|
236
|
+
title: item.title,
|
|
237
|
+
patch: item.patch,
|
|
238
|
+
oldContent: before,
|
|
239
|
+
newContent: after,
|
|
240
|
+
createdAt: item.createdAt,
|
|
241
|
+
};
|
|
242
|
+
after = before;
|
|
243
|
+
return version;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
export function deleteNode(workspaceId, nodeId, databaseId) {
|
|
247
|
+
const database = openDb();
|
|
248
|
+
const existing = getNode(workspaceId, nodeId, databaseId);
|
|
249
|
+
if (!existing)
|
|
250
|
+
return false;
|
|
251
|
+
database.prepare('DELETE FROM database_embeddings WHERE workspace_id = ? AND database_id = ? AND node_id = ?')
|
|
252
|
+
.run(workspaceId, existing.databaseId, nodeId);
|
|
253
|
+
database.prepare('DELETE FROM doc_node_versions WHERE workspace_id = ? AND database_id = ? AND node_id = ?')
|
|
254
|
+
.run(workspaceId, existing.databaseId, nodeId);
|
|
255
|
+
const result = database.prepare('DELETE FROM doc_nodes WHERE workspace_id = ? AND database_id = ? AND id = ?').run(workspaceId, existing.databaseId, nodeId);
|
|
256
|
+
return result.changes > 0;
|
|
257
|
+
}
|
|
258
|
+
function insertNodeVersion(database, workspaceId, existing, nextContent) {
|
|
259
|
+
const patch = createContentPatch(existing.content, nextContent);
|
|
260
|
+
database.prepare(`INSERT INTO doc_node_versions
|
|
261
|
+
(id, workspace_id, database_id, node_id, title, patch_json, old_hash, new_hash, created_at)
|
|
262
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(uuid(), workspaceId, existing.databaseId, existing.id, existing.title, JSON.stringify(patch), hashContent(existing.content), hashContent(nextContent), Date.now());
|
|
263
|
+
}
|
|
264
|
+
function createContentPatch(oldContent, newContent) {
|
|
265
|
+
let start = 0;
|
|
266
|
+
while (start < oldContent.length
|
|
267
|
+
&& start < newContent.length
|
|
268
|
+
&& oldContent[start] === newContent[start]) {
|
|
269
|
+
start++;
|
|
270
|
+
}
|
|
271
|
+
let oldEnd = oldContent.length;
|
|
272
|
+
let newEnd = newContent.length;
|
|
273
|
+
while (oldEnd > start
|
|
274
|
+
&& newEnd > start
|
|
275
|
+
&& oldContent[oldEnd - 1] === newContent[newEnd - 1]) {
|
|
276
|
+
oldEnd--;
|
|
277
|
+
newEnd--;
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
start,
|
|
281
|
+
deleteText: oldContent.slice(start, oldEnd),
|
|
282
|
+
insertText: newContent.slice(start, newEnd),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function applyReversePatch(content, patch) {
|
|
286
|
+
const insertEnd = patch.start + patch.insertText.length;
|
|
287
|
+
return `${content.slice(0, patch.start)}${patch.deleteText}${content.slice(insertEnd)}`;
|
|
288
|
+
}
|
|
289
|
+
function hashContent(content) {
|
|
290
|
+
return createHash('sha256').update(content).digest('hex');
|
|
291
|
+
}
|
|
292
|
+
export function moveNode(workspaceId, nodeId, newParentId, databaseId) {
|
|
293
|
+
return updateNode(workspaceId, nodeId, { parentId: newParentId }, databaseId);
|
|
294
|
+
}
|
|
295
|
+
export function trashNode(workspaceId, nodeId, databaseId) {
|
|
296
|
+
return updateNode(workspaceId, nodeId, { isTrash: true }, databaseId);
|
|
297
|
+
}
|
|
298
|
+
export function restoreNode(workspaceId, nodeId, databaseId) {
|
|
299
|
+
const node = getNode(workspaceId, nodeId, databaseId);
|
|
300
|
+
if (!node)
|
|
301
|
+
return null;
|
|
302
|
+
if (node.parentId) {
|
|
303
|
+
const parent = getNode(workspaceId, node.parentId, node.databaseId);
|
|
304
|
+
if (parent && parent.isTrash) {
|
|
305
|
+
return updateNode(workspaceId, nodeId, { isTrash: false, parentId: null }, node.databaseId);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return updateNode(workspaceId, nodeId, { isTrash: false }, node.databaseId);
|
|
309
|
+
}
|
|
310
|
+
export function getVectorStats(workspaceId, databaseId) {
|
|
311
|
+
const database = openDb();
|
|
312
|
+
const meta = getDatabase(workspaceId, databaseId);
|
|
313
|
+
const indexed = database.prepare('SELECT COUNT(*) AS count, MAX(updated_at) AS last_indexed_at FROM database_embeddings WHERE workspace_id = ? AND database_id = ?').get(workspaceId, databaseId);
|
|
314
|
+
const nodes = database.prepare('SELECT COUNT(*) AS count FROM doc_nodes WHERE workspace_id = ? AND database_id = ? AND is_trash = 0').get(workspaceId, databaseId);
|
|
315
|
+
return {
|
|
316
|
+
databaseId,
|
|
317
|
+
embeddingModelId: meta?.embeddingModelId ?? null,
|
|
318
|
+
indexedCount: indexed.count,
|
|
319
|
+
nodeCount: nodes.count,
|
|
320
|
+
lastIndexedAt: indexed.last_indexed_at,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
export function setDatabaseEmbeddingModel(workspaceId, databaseId, embeddingModelId) {
|
|
324
|
+
return updateDatabase(workspaceId, databaseId, { embeddingModelId: embeddingModelId ?? undefined });
|
|
325
|
+
}
|
|
326
|
+
export function upsertDatabaseEmbedding(workspaceId, databaseId, record) {
|
|
327
|
+
const database = openDb();
|
|
328
|
+
database.prepare(`INSERT INTO database_embeddings
|
|
329
|
+
(workspace_id, database_id, node_id, title, path, content, content_hash, embedding, model_id, agent_id, updated_at)
|
|
330
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
331
|
+
ON CONFLICT(workspace_id, database_id, node_id) DO UPDATE SET
|
|
332
|
+
title = excluded.title,
|
|
333
|
+
path = excluded.path,
|
|
334
|
+
content = excluded.content,
|
|
335
|
+
content_hash = excluded.content_hash,
|
|
336
|
+
embedding = excluded.embedding,
|
|
337
|
+
model_id = excluded.model_id,
|
|
338
|
+
agent_id = excluded.agent_id,
|
|
339
|
+
updated_at = excluded.updated_at`).run(workspaceId, databaseId, record.nodeId, record.title, record.path, record.content, record.contentHash, JSON.stringify(record.embedding), record.modelId, record.agentId, Date.now());
|
|
340
|
+
}
|
|
341
|
+
export function deleteStaleDatabaseEmbeddings(workspaceId, databaseId, activeNodeIds) {
|
|
342
|
+
const database = openDb();
|
|
343
|
+
if (activeNodeIds.length === 0) {
|
|
344
|
+
const result = database.prepare('DELETE FROM database_embeddings WHERE workspace_id = ? AND database_id = ?')
|
|
345
|
+
.run(workspaceId, databaseId);
|
|
346
|
+
return result.changes;
|
|
347
|
+
}
|
|
348
|
+
const placeholders = activeNodeIds.map(() => '?').join(',');
|
|
349
|
+
const result = database.prepare(`DELETE FROM database_embeddings WHERE workspace_id = ? AND database_id = ? AND node_id NOT IN (${placeholders})`).run(workspaceId, databaseId, ...activeNodeIds);
|
|
350
|
+
return result.changes;
|
|
351
|
+
}
|
|
352
|
+
export function listDatabaseEmbeddings(workspaceId, databaseId) {
|
|
353
|
+
const database = openDb();
|
|
354
|
+
const rows = database.prepare('SELECT node_id, title, path, content, embedding, updated_at FROM database_embeddings WHERE workspace_id = ? AND database_id = ?').all(workspaceId, databaseId);
|
|
355
|
+
return rows.map((row) => ({
|
|
356
|
+
nodeId: row.node_id,
|
|
357
|
+
title: row.title,
|
|
358
|
+
path: row.path,
|
|
359
|
+
content: row.content,
|
|
360
|
+
score: 0,
|
|
361
|
+
updatedAt: row.updated_at,
|
|
362
|
+
embedding: JSON.parse(row.embedding),
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=database-store.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { readdirSync } from 'node:fs';
|
|
3
|
+
import { getDataDir, ensureDir, readJsonFile, writeJsonFile, deleteFile } from './json-store.js';
|
|
4
|
+
function workspaceDir(id) {
|
|
5
|
+
return join(getDataDir(), 'workspaces', id);
|
|
6
|
+
}
|
|
7
|
+
function hooksDir(wsId) {
|
|
8
|
+
return join(workspaceDir(wsId), 'hooks');
|
|
9
|
+
}
|
|
10
|
+
function hookPath(wsId, name) {
|
|
11
|
+
return join(hooksDir(wsId), `${name}.hook.json`);
|
|
12
|
+
}
|
|
13
|
+
export function listHooks(wsId) {
|
|
14
|
+
const dir = hooksDir(wsId);
|
|
15
|
+
try {
|
|
16
|
+
const files = readdirSync(dir);
|
|
17
|
+
return files
|
|
18
|
+
.filter(f => f.endsWith('.hook.json'))
|
|
19
|
+
.map(f => readJsonFile(join(dir, f)))
|
|
20
|
+
.filter((h) => h !== null);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function getHook(wsId, name) {
|
|
27
|
+
return readJsonFile(hookPath(wsId, name));
|
|
28
|
+
}
|
|
29
|
+
export function saveHook(wsId, config) {
|
|
30
|
+
ensureDir(hooksDir(wsId));
|
|
31
|
+
writeJsonFile(hookPath(wsId, config.name), config);
|
|
32
|
+
}
|
|
33
|
+
export function deleteHook(wsId, name) {
|
|
34
|
+
deleteFile(hookPath(wsId, name));
|
|
35
|
+
}
|
|
36
|
+
export function uploadHook(wsId, jsonString) {
|
|
37
|
+
const parsed = JSON.parse(jsonString);
|
|
38
|
+
if (!parsed.name || typeof parsed.name !== 'string') {
|
|
39
|
+
throw new Error('Hook must have a "name" string field');
|
|
40
|
+
}
|
|
41
|
+
if (!parsed.hooks || typeof parsed.hooks !== 'object') {
|
|
42
|
+
parsed.hooks = { PreToolUse: [], PostToolUse: [] };
|
|
43
|
+
}
|
|
44
|
+
if (parsed.enabled === undefined)
|
|
45
|
+
parsed.enabled = true;
|
|
46
|
+
saveHook(wsId, parsed);
|
|
47
|
+
return parsed;
|
|
48
|
+
}
|
|
49
|
+
export function applyToWorkspace(sourceWsId, name, targetWsId) {
|
|
50
|
+
const config = getHook(sourceWsId, name);
|
|
51
|
+
if (!config)
|
|
52
|
+
throw new Error(`Hook "${name}" not found in workspace ${sourceWsId}`);
|
|
53
|
+
saveHook(targetWsId, config);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=hook-store.js.map
|