@agent-spaces/server 0.3.61 → 0.3.63
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 +22 -0
- package/dist/adapters/claude-code-runtime/sdk-config.js +34 -10
- package/dist/adapters/codex-runtime.js +2 -2
- package/dist/adapters/git.js +29 -13
- package/dist/adapters/langchain-runtime.js +2 -2
- package/dist/adapters/open-agent-sdk-runtime.js +2 -2
- package/dist/agents/agent-message-parts.js +27 -3
- 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 +95 -14
- package/dist/app.js +74 -5
- package/dist/package.json +1 -1
- package/dist/routes/agent-sse.js +4 -2
- package/dist/routes/channel.js +21 -4
- package/dist/routes/file.js +87 -1
- package/dist/routes/hooks.js +88 -0
- package/dist/routes/issue.js +59 -1
- package/dist/routes/output-style.js +48 -0
- package/dist/routes/prompt-template.js +2 -2
- package/dist/routes/skill.js +97 -3
- package/dist/routes/task.js +13 -1
- package/dist/services/agent.js +45 -16
- package/dist/services/hook-engine.js +118 -0
- package/dist/services/issue.js +6 -0
- package/dist/services/notification-hub/bot-agent.js +1 -0
- package/dist/services/output-style.js +134 -0
- package/dist/services/persistent-agent-context.js +37 -4
- package/dist/services/prompt-template.js +2 -2
- package/dist/services/skill.js +275 -40
- package/dist/storage/hook-store.js +55 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +25 -23
- package/dist/web/__next._head.txt +4 -4
- package/dist/web/__next._index.txt +13 -13
- package/dist/web/__next._tree.txt +2 -2
- package/dist/web/_next/static/chunks/0-1bfvfwifh-m.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/014x2qbuiszni.js +3 -0
- package/dist/web/_next/static/chunks/01iqv28_snwus.js +1 -0
- package/dist/web/_next/static/chunks/02c22g~xd-y30.js +19 -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/046me66nilkff.js +1 -0
- package/dist/web/_next/static/chunks/04v-pqqs-2lvp.css +1 -0
- package/dist/web/_next/static/chunks/05f8cnmzqd5wb.js +1 -0
- package/dist/web/_next/static/chunks/{0zd1o3u04~qvo.js → 05psi2gtx~bev.js} +7 -7
- package/dist/web/_next/static/chunks/{12odetnu-lyrr.js → 06whz1~s_7pva.js} +12 -12
- package/dist/web/_next/static/chunks/06w~.izyfylap.js +1 -0
- package/dist/web/_next/static/chunks/08kfx8on9oty~.js +1 -0
- package/dist/web/_next/static/chunks/09t62a89~jesc.js +3 -0
- package/dist/web/_next/static/chunks/09y_3krccdd~u.js +1 -0
- package/dist/web/_next/static/chunks/{0njy89g5coeyi.js → 0_8dm7bxp18xo.js} +6 -6
- package/dist/web/_next/static/chunks/0_e~hmntdfop9.js +1 -0
- package/dist/web/_next/static/chunks/0_udc.6.tueey.js +1 -0
- package/dist/web/_next/static/chunks/0_vi1a~g4wx46.js +3 -0
- package/dist/web/_next/static/chunks/{05iy4.c-1cfhd.js → 0aa6bcdmtpekn.js} +1 -1
- package/dist/web/_next/static/chunks/{0tvd~rxgf0oh_.js → 0bbmx45w_h5np.js} +1 -1
- package/dist/web/_next/static/chunks/0cke33d38fnby.js +90 -0
- package/dist/web/_next/static/chunks/{0w1iudd1d46sw.js → 0ctg5qmw7uu.1.js} +2 -2
- package/dist/web/_next/static/chunks/0cyq~8xb~r5fc.js +1 -0
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +1 -0
- package/dist/web/_next/static/chunks/0fxa1edqr7dve.js +1 -0
- package/dist/web/_next/static/chunks/{0202ia13sijwb.js → 0h18ej5yf974e.js} +1 -1
- package/dist/web/_next/static/chunks/0hra80eyuu37u.js +1 -0
- package/dist/web/_next/static/chunks/0i39jifmxla7q.js +1 -0
- package/dist/web/_next/static/chunks/0ie7y4k2ncvnn.js +1 -0
- package/dist/web/_next/static/chunks/0igc~uli58ncw.js +2 -0
- package/dist/web/_next/static/chunks/0kof5qdg8c2-k.js +71 -0
- package/dist/web/_next/static/chunks/{08o-zmr-40r5g.js → 0m11vvph7q94-.js} +1 -1
- package/dist/web/_next/static/chunks/0msb2mi3hiu5_.js +67 -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/0ogpc3f3keopc.js +3 -0
- package/dist/web/_next/static/chunks/{0d_dp_4ofz0l3.css → 0ojcao3hdm36s.css} +0 -1
- package/dist/web/_next/static/chunks/0p1n8bvfnpl41.js +1 -0
- package/dist/web/_next/static/chunks/{0gig.k.rq8d0x.js → 0ppr271hz0xoq.js} +1 -1
- package/dist/web/_next/static/chunks/0s_dva~eh2yhi.js +3 -0
- package/dist/web/_next/static/chunks/0typj55ox8d5i.js +1 -0
- package/dist/web/_next/static/chunks/0w2p4ldi2aymp.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/0y09i51u6ixq5.js +1 -0
- package/dist/web/_next/static/chunks/0za1r07-6az6w.js +1 -0
- package/dist/web/_next/static/chunks/0zc0xgp5ourcn.js +1 -0
- package/dist/web/_next/static/chunks/0zmhdridea1s5.js +90 -0
- package/dist/web/_next/static/chunks/0~u.5r3-t7179.js +1 -0
- package/dist/web/_next/static/chunks/10.alq.6stmld.js +1 -0
- package/dist/web/_next/static/chunks/11-czmcci_55y.js +1 -0
- package/dist/web/_next/static/chunks/11b3zgk1etlkw.js +7 -0
- package/dist/web/_next/static/chunks/11k-.49r~1mfm.js +1 -0
- package/dist/web/_next/static/chunks/11qp8r5dotf7d.js +1 -0
- package/dist/web/_next/static/chunks/128ugqd34tr_-.js +1 -0
- package/dist/web/_next/static/chunks/12mxlicp247c8.js +1 -0
- package/dist/web/_next/static/chunks/135w27dd8c19s.js +5 -0
- package/dist/web/_next/static/chunks/13~y-b.b9rrw4.js +1 -0
- package/dist/web/_next/static/chunks/{0jokpgh485~28.js → 14hqmid8q4apf.js} +11 -11
- package/dist/web/_next/static/chunks/16sg-lflc8csx.js +1 -0
- package/dist/web/_next/static/chunks/176dc-dtokxxi.js +16 -0
- package/dist/web/_next/static/chunks/17g-0pqre.anw.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 +29 -30
- package/dist/web/_not-found/__next._head.txt +4 -4
- package/dist/web/_not-found/__next._index.txt +13 -13
- 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 +2 -2
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +29 -30
- package/dist/web/icons/file_type_audio.svg +3 -1
- package/dist/web/icons/file_type_video.svg +10 -1
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +25 -23
- package/dist/web/login/__next._full.txt +30 -28
- package/dist/web/login/__next._head.txt +4 -4
- package/dist/web/login/__next._index.txt +13 -13
- package/dist/web/login/__next._tree.txt +2 -2
- 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 +30 -28
- package/dist/web/settings/__next._full.txt +32 -31
- package/dist/web/settings/__next._head.txt +4 -4
- package/dist/web/settings/__next._index.txt +13 -13
- package/dist/web/settings/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/agents/__next._head.txt +4 -4
- package/dist/web/settings/agents/__next._index.txt +13 -13
- package/dist/web/settings/agents/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/mcps/__next._full.txt +35 -34
- package/dist/web/settings/mcps/__next._head.txt +4 -4
- package/dist/web/settings/mcps/__next._index.txt +13 -13
- package/dist/web/settings/mcps/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/models/__next._full.txt +35 -34
- package/dist/web/settings/models/__next._head.txt +4 -4
- package/dist/web/settings/models/__next._index.txt +13 -13
- package/dist/web/settings/models/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/output-styles/__next._full.txt +43 -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 +8 -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 +43 -0
- package/dist/web/settings/prompts/__next._full.txt +35 -34
- package/dist/web/settings/prompts/__next._head.txt +4 -4
- package/dist/web/settings/prompts/__next._index.txt +13 -13
- package/dist/web/settings/prompts/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/providers/__next._full.txt +35 -34
- package/dist/web/settings/providers/__next._head.txt +4 -4
- package/dist/web/settings/providers/__next._index.txt +13 -13
- package/dist/web/settings/providers/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings/skills/__next._full.txt +35 -34
- package/dist/web/settings/skills/__next._head.txt +4 -4
- package/dist/web/settings/skills/__next._index.txt +13 -13
- package/dist/web/settings/skills/__next._tree.txt +2 -2
- 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 +35 -34
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +32 -31
- package/dist/web/workflows/__next._full.txt +32 -30
- package/dist/web/workflows/__next._head.txt +4 -4
- package/dist/web/workflows/__next._index.txt +13 -13
- package/dist/web/workflows/__next._tree.txt +2 -2
- 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 +32 -30
- package/dist/web/workspace/_/__next._full.txt +30 -70
- package/dist/web/workspace/_/__next._head.txt +4 -4
- package/dist/web/workspace/_/__next._index.txt +13 -13
- package/dist/web/workspace/_/__next._tree.txt +2 -17
- 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 +30 -70
- package/dist/web/workspaces/__next._full.txt +31 -29
- package/dist/web/workspaces/__next._head.txt +4 -4
- package/dist/web/workspaces/__next._index.txt +13 -13
- package/dist/web/workspaces/__next._tree.txt +2 -2
- 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 +31 -29
- package/dist/ws/agent-runner.js +55 -33
- package/dist/ws/message-parts.js +61 -2
- package/package.json +1 -1
- 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-1pn22sg~67u.js +0 -2
- package/dist/web/_next/static/chunks/01gi~q0c6ez6..js +0 -1
- package/dist/web/_next/static/chunks/03me5_ir..2ix.js +0 -1
- package/dist/web/_next/static/chunks/05eu2fdixf7c9.js +0 -1
- package/dist/web/_next/static/chunks/0_-c.y2qq4ax4.js +0 -270
- package/dist/web/_next/static/chunks/0_g3irbniww6d.js +0 -3
- package/dist/web/_next/static/chunks/0cs830n97dgjy.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/0ju52ko_nh7gi.js +0 -1
- package/dist/web/_next/static/chunks/0mny8i81aenx3.js +0 -1
- package/dist/web/_next/static/chunks/0nsu~f3voe~0i.js +0 -5
- package/dist/web/_next/static/chunks/0sz8_nijfiz0p.js +0 -1
- package/dist/web/_next/static/chunks/0u7_qd9hzqwac.js +0 -1
- package/dist/web/_next/static/chunks/0w3o.7vi.dlm6.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/0x4b-a2ixww6m.js +0 -1
- package/dist/web/_next/static/chunks/0xwqf.llmm_u2.js +0 -31
- package/dist/web/_next/static/chunks/0~w6ugk9s5p-h.css +0 -1
- package/dist/web/_next/static/chunks/125nunjfj2fj0.js +0 -1
- package/dist/web/_next/static/chunks/1285yqy_oirb-.js +0 -1
- package/dist/web/_next/static/chunks/13ess~4pdmxma.js +0 -1
- package/dist/web/_next/static/chunks/14n8i2xz4_y-e.js +0 -1
- 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/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_ssgManifest.js +0 -0
- /package/public/avatars/{1777815865622-08wp9m-user.jpg → user.jpg} +0 -0
package/dist/services/skill.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
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';
|
|
8
|
+
const SKILL_FILE = 'SKILL.md';
|
|
5
9
|
function getSkillsDir() {
|
|
6
10
|
return join(getDataDir(), 'skills');
|
|
7
11
|
}
|
|
@@ -11,33 +15,65 @@ function getSkillMetaPath() {
|
|
|
11
15
|
function readMeta() {
|
|
12
16
|
const path = getSkillMetaPath();
|
|
13
17
|
if (!existsSync(path))
|
|
14
|
-
return { favorites: [] };
|
|
18
|
+
return { favorites: [], groups: {} };
|
|
15
19
|
try {
|
|
16
|
-
|
|
20
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
21
|
+
return {
|
|
22
|
+
favorites: raw.favorites || [],
|
|
23
|
+
groups: raw.groups || {},
|
|
24
|
+
};
|
|
17
25
|
}
|
|
18
26
|
catch {
|
|
19
|
-
return { favorites: [] };
|
|
27
|
+
return { favorites: [], groups: {} };
|
|
20
28
|
}
|
|
21
29
|
}
|
|
22
30
|
function writeMeta(meta) {
|
|
23
31
|
ensureDir(getSkillsDir());
|
|
24
32
|
writeFileSync(getSkillMetaPath(), JSON.stringify(meta, null, 2), 'utf-8');
|
|
25
33
|
}
|
|
34
|
+
/** Migrate flat .md files to folder/{SKILL_FILE} format */
|
|
35
|
+
function migrateFlatFiles() {
|
|
36
|
+
const skillsDir = getSkillsDir();
|
|
37
|
+
if (!existsSync(skillsDir))
|
|
38
|
+
return;
|
|
39
|
+
const entries = readdirSync(skillsDir);
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
if (!entry.endsWith('.md') || entry.startsWith('_'))
|
|
42
|
+
continue;
|
|
43
|
+
const filePath = join(skillsDir, entry);
|
|
44
|
+
if (!statSync(filePath).isFile())
|
|
45
|
+
continue;
|
|
46
|
+
const name = basename(entry, '.md');
|
|
47
|
+
const folderPath = join(skillsDir, name);
|
|
48
|
+
if (!existsSync(folderPath)) {
|
|
49
|
+
mkdirSync(folderPath, { recursive: true });
|
|
50
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
51
|
+
writeFileSync(join(folderPath, SKILL_FILE), content, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
unlinkSync(filePath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
26
56
|
export function listSkills() {
|
|
57
|
+
migrateFlatFiles();
|
|
27
58
|
const agents = listTemplates();
|
|
28
59
|
const skillsDir = getSkillsDir();
|
|
29
60
|
const meta = readMeta();
|
|
30
61
|
ensureDir(skillsDir);
|
|
31
|
-
const
|
|
32
|
-
.filter((f) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
62
|
+
const folders = readdirSync(skillsDir)
|
|
63
|
+
.filter((f) => {
|
|
64
|
+
if (f.startsWith('_'))
|
|
65
|
+
return false;
|
|
66
|
+
const p = join(skillsDir, f);
|
|
67
|
+
return statSync(p).isDirectory();
|
|
68
|
+
});
|
|
69
|
+
return folders.map((folderName) => {
|
|
70
|
+
const skillFile = join(skillsDir, folderName, SKILL_FILE);
|
|
71
|
+
const content = existsSync(skillFile) ? readFileSync(skillFile, 'utf-8') : '';
|
|
36
72
|
const fm = parseFrontmatter(content);
|
|
37
73
|
const boundAgents = agents
|
|
38
74
|
.filter((a) => (a.skills || []).some((s) => {
|
|
39
75
|
const skillName = s.replace(/\.md$/i, '');
|
|
40
|
-
return skillName ===
|
|
76
|
+
return skillName === folderName;
|
|
41
77
|
}))
|
|
42
78
|
.map((a) => ({
|
|
43
79
|
id: a.id,
|
|
@@ -45,11 +81,12 @@ export function listSkills() {
|
|
|
45
81
|
avatarUrl: a.avatarUrl,
|
|
46
82
|
}));
|
|
47
83
|
return {
|
|
48
|
-
name,
|
|
84
|
+
name: folderName,
|
|
49
85
|
description: fm.description || '',
|
|
50
|
-
filename
|
|
86
|
+
filename: `${folderName}/${SKILL_FILE}`,
|
|
51
87
|
content,
|
|
52
|
-
favorited: meta.favorites.includes(
|
|
88
|
+
favorited: meta.favorites.includes(folderName),
|
|
89
|
+
group: meta.groups[folderName] || '',
|
|
53
90
|
boundAgents,
|
|
54
91
|
};
|
|
55
92
|
});
|
|
@@ -71,24 +108,99 @@ function parseFrontmatter(content) {
|
|
|
71
108
|
}
|
|
72
109
|
return { name, description };
|
|
73
110
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
return safe.endsWith('.md') ? safe : `${safe}.md`;
|
|
111
|
+
function sanitizeFolderName(name) {
|
|
112
|
+
return name.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'skill';
|
|
77
113
|
}
|
|
78
|
-
|
|
114
|
+
function writeSkillFolder(name, content) {
|
|
115
|
+
const skillsDir = getSkillsDir();
|
|
116
|
+
const folderName = sanitizeFolderName(name);
|
|
117
|
+
const folderPath = join(skillsDir, folderName);
|
|
118
|
+
ensureDir(folderPath);
|
|
119
|
+
writeFileSync(join(folderPath, SKILL_FILE), content, 'utf-8');
|
|
120
|
+
return folderName;
|
|
121
|
+
}
|
|
122
|
+
export function importSkill(filename, content, group) {
|
|
79
123
|
const fm = parseFrontmatter(content);
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
124
|
+
const rawName = fm.name || basename(filename, '.md');
|
|
125
|
+
const folderName = writeSkillFolder(rawName, content);
|
|
126
|
+
if (group) {
|
|
127
|
+
const meta = readMeta();
|
|
128
|
+
meta.groups[folderName] = group;
|
|
129
|
+
writeMeta(meta);
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
name: folderName,
|
|
133
|
+
description: fm.description || '',
|
|
134
|
+
filename: `${folderName}/${SKILL_FILE}`,
|
|
135
|
+
content,
|
|
136
|
+
favorited: false,
|
|
137
|
+
group: group || '',
|
|
138
|
+
boundAgents: [],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
export function importSkillsBatch(items) {
|
|
142
|
+
const meta = readMeta();
|
|
143
|
+
const results = [];
|
|
144
|
+
for (const item of items) {
|
|
145
|
+
const folderName = writeSkillFolder(item.name, item.content);
|
|
146
|
+
if (item.group) {
|
|
147
|
+
meta.groups[folderName] = item.group;
|
|
148
|
+
}
|
|
149
|
+
const fm = parseFrontmatter(item.content);
|
|
150
|
+
results.push({
|
|
151
|
+
name: folderName,
|
|
152
|
+
description: fm.description || '',
|
|
153
|
+
filename: `${folderName}/${SKILL_FILE}`,
|
|
154
|
+
content: item.content,
|
|
155
|
+
favorited: false,
|
|
156
|
+
group: item.group || '',
|
|
157
|
+
boundAgents: [],
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
writeMeta(meta);
|
|
161
|
+
return results;
|
|
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);
|
|
83
181
|
const skillsDir = getSkillsDir();
|
|
84
|
-
|
|
85
|
-
|
|
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);
|
|
86
197
|
return {
|
|
87
|
-
name:
|
|
198
|
+
name: skillName,
|
|
88
199
|
description: fm.description || '',
|
|
89
|
-
filename:
|
|
200
|
+
filename: `${skillName}/${SKILL_FILE}`,
|
|
90
201
|
content,
|
|
91
202
|
favorited: false,
|
|
203
|
+
group,
|
|
92
204
|
boundAgents: [],
|
|
93
205
|
};
|
|
94
206
|
}
|
|
@@ -106,8 +218,7 @@ export function toggleFavorite(name) {
|
|
|
106
218
|
}
|
|
107
219
|
export function updateSkillContent(name, content) {
|
|
108
220
|
const skillsDir = getSkillsDir();
|
|
109
|
-
const
|
|
110
|
-
const filePath = join(skillsDir, filename);
|
|
221
|
+
const filePath = join(skillsDir, name, SKILL_FILE);
|
|
111
222
|
if (!existsSync(filePath))
|
|
112
223
|
return false;
|
|
113
224
|
writeFileSync(filePath, content, 'utf-8');
|
|
@@ -115,14 +226,19 @@ export function updateSkillContent(name, content) {
|
|
|
115
226
|
}
|
|
116
227
|
export function deleteSkill(name) {
|
|
117
228
|
const skillsDir = getSkillsDir();
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
if (!existsSync(filePath))
|
|
229
|
+
const folderPath = join(skillsDir, name);
|
|
230
|
+
if (!existsSync(folderPath) || !statSync(folderPath).isDirectory())
|
|
121
231
|
return false;
|
|
122
|
-
|
|
232
|
+
rmSync(folderPath, { recursive: true, force: true });
|
|
233
|
+
// Clean meta
|
|
234
|
+
const meta = readMeta();
|
|
235
|
+
meta.favorites = meta.favorites.filter((n) => n !== name);
|
|
236
|
+
delete meta.groups[name];
|
|
237
|
+
writeMeta(meta);
|
|
123
238
|
return true;
|
|
124
239
|
}
|
|
125
240
|
export function checkSkillSync() {
|
|
241
|
+
migrateFlatFiles();
|
|
126
242
|
const globalSkillsDir = getSkillsDir();
|
|
127
243
|
const agents = listTemplates();
|
|
128
244
|
const result = [];
|
|
@@ -132,14 +248,36 @@ export function checkSkillSync() {
|
|
|
132
248
|
continue;
|
|
133
249
|
const agentSkillsDir = join(getDataDir(), 'agent-templates', agent.id, 'skills');
|
|
134
250
|
for (const skillName of skillNames) {
|
|
135
|
-
const
|
|
251
|
+
const globalFolder = join(globalSkillsDir, skillName);
|
|
252
|
+
const globalSkillFile = join(globalFolder, SKILL_FILE);
|
|
253
|
+
// Agent skill can be a folder or a flat .md
|
|
254
|
+
const agentFolder = join(agentSkillsDir, skillName);
|
|
136
255
|
const agentFile = join(agentSkillsDir, `${skillName}.md`);
|
|
137
|
-
if (!existsSync(
|
|
256
|
+
if (!existsSync(globalFolder) || !statSync(globalFolder).isDirectory())
|
|
138
257
|
continue;
|
|
139
|
-
|
|
258
|
+
// Use SKILL.md file mtime — directory mtime is unreliable on Windows
|
|
259
|
+
if (!existsSync(globalSkillFile))
|
|
140
260
|
continue;
|
|
141
|
-
const globalStat = statSync(
|
|
142
|
-
const
|
|
261
|
+
const globalStat = statSync(globalSkillFile);
|
|
262
|
+
const agentExists = existsSync(agentFolder) || existsSync(agentFile);
|
|
263
|
+
if (!agentExists) {
|
|
264
|
+
// Agent skill missing — needs sync
|
|
265
|
+
result.push({
|
|
266
|
+
agentId: agent.id,
|
|
267
|
+
agentName: agent.name || agent.id,
|
|
268
|
+
skillName,
|
|
269
|
+
globalMtime: globalStat.mtime.toISOString(),
|
|
270
|
+
agentMtime: '',
|
|
271
|
+
});
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
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);
|
|
143
281
|
if (globalStat.mtimeMs > agentStat.mtimeMs) {
|
|
144
282
|
result.push({
|
|
145
283
|
agentId: agent.id,
|
|
@@ -157,15 +295,112 @@ export function syncSkills(items) {
|
|
|
157
295
|
const globalSkillsDir = getSkillsDir();
|
|
158
296
|
let synced = 0;
|
|
159
297
|
for (const item of items) {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
const agentFile = join(agentSkillsDir, `${item.skillName}.md`);
|
|
163
|
-
if (!existsSync(globalFile))
|
|
298
|
+
const globalFolder = join(globalSkillsDir, item.skillName);
|
|
299
|
+
if (!existsSync(globalFolder) || !statSync(globalFolder).isDirectory())
|
|
164
300
|
continue;
|
|
301
|
+
const agentSkillsDir = join(getDataDir(), 'agent-templates', item.agentId, 'skills');
|
|
165
302
|
ensureDir(agentSkillsDir);
|
|
166
|
-
|
|
303
|
+
// Remove stale flat .md if it exists
|
|
304
|
+
const flatFile = join(agentSkillsDir, `${item.skillName}.md`);
|
|
305
|
+
if (existsSync(flatFile)) {
|
|
306
|
+
rmSync(flatFile, { force: true });
|
|
307
|
+
}
|
|
308
|
+
// Copy entire skill folder
|
|
309
|
+
const agentFolder = join(agentSkillsDir, item.skillName);
|
|
310
|
+
if (existsSync(agentFolder)) {
|
|
311
|
+
rmSync(agentFolder, { recursive: true, force: true });
|
|
312
|
+
}
|
|
313
|
+
cpSync(globalFolder, agentFolder, { recursive: true, force: true });
|
|
167
314
|
synced++;
|
|
168
315
|
}
|
|
169
316
|
return synced;
|
|
170
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
|
+
}
|
|
171
406
|
//# sourceMappingURL=skill.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
|