@agent-spaces/server 0.3.63 → 0.3.65
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/claude-code-runtime/index.js +68 -2
- package/dist/adapters/claude-code-runtime/message-format.js +27 -1
- package/dist/adapters/claude-code-runtime/sdk-config.js +12 -0
- package/dist/adapters/git.js +168 -57
- package/dist/agents/agent-designer.js +66 -12
- package/dist/agents/agent-message-parts.js +1 -1
- package/dist/agents/commit-agent.js +4 -2
- package/dist/agents/issue-task-controller.js +7 -3
- package/dist/app.js +56 -69
- package/dist/package.json +1 -1
- package/dist/routes/agent-commands.js +72 -0
- package/dist/routes/agent-sse.js +7 -0
- package/dist/routes/agent.js +18 -1
- package/dist/routes/database.js +346 -0
- package/dist/routes/git.js +198 -267
- package/dist/routes/kanban.js +39 -0
- package/dist/routes/robot-account.js +68 -0
- package/dist/services/agent-commands.js +168 -0
- package/dist/services/agent.js +36 -2
- 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 +281 -0
- package/dist/services/database-vector.js +244 -0
- package/dist/services/git-operation-log.js +40 -0
- package/dist/services/global-wechat-qr.js +72 -0
- package/dist/services/hook-engine.js +175 -17
- package/dist/services/kanban.js +50 -0
- package/dist/services/notification-hub/bot-agent.js +3 -1
- package/dist/services/notification-hub/service.js +12 -2
- package/dist/services/robot-account.js +34 -0
- package/dist/services/workspace.js +2 -0
- package/dist/storage/database-store.js +365 -0
- package/dist/storage/kanban-store.js +142 -0
- package/dist/storage/robot-account-store.js +39 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +24 -31
- 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-a.-hl3wv99k.js +1 -0
- package/dist/web/_next/static/chunks/{0ctg5qmw7uu.1.js → 0-pi.67w.ymsr.js} +3 -3
- package/dist/web/_next/static/chunks/0-v_p6j5u3_9l.js +1 -0
- package/dist/web/_next/static/chunks/0.-x29t-8gk0r.js +1 -0
- package/dist/web/_next/static/chunks/0.6b64sy0g5.3.js +3 -0
- package/dist/web/_next/static/chunks/0.l5e8~r7_0~p.js +1 -0
- package/dist/web/_next/static/chunks/00-syqzi-6zxr.js +1 -0
- package/dist/web/_next/static/chunks/{13~y-b.b9rrw4.js → 01~quun6sefgl.js} +1 -1
- package/dist/web/_next/static/chunks/02802taez976w.js +67 -0
- package/dist/web/_next/static/chunks/02j4sr9psucf-.js +1 -0
- package/dist/web/_next/static/chunks/033.awk90g6eh.js +1 -0
- package/dist/web/_next/static/chunks/06.kdsa9rr2h1.js +1 -0
- package/dist/web/_next/static/chunks/{0-oog4zg4_m~m.css → 062f9zqctzg.b.css} +0 -3
- package/dist/web/_next/static/chunks/06si8l0doqe8p.js +1 -0
- package/dist/web/_next/static/chunks/08ugbvzr20drp.js +2 -0
- package/dist/web/_next/static/chunks/{0kof5qdg8c2-k.js → 08x85faoz58i7.js} +37 -37
- package/dist/web/_next/static/chunks/0_cqojbge48kq.js +5 -0
- package/dist/web/_next/static/chunks/0_mvduwjsm35w.js +1 -0
- package/dist/web/_next/static/chunks/0d6~~lv0-6kex.js +3 -0
- package/dist/web/_next/static/chunks/{0ogpc3f3keopc.js → 0db14450oqzhg.js} +2 -2
- package/dist/web/_next/static/chunks/0fttswpzu69qx.js +1 -0
- package/dist/web/_next/static/chunks/0gdwop9cnpmtu.js +1 -0
- package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +1 -0
- package/dist/web/_next/static/chunks/0j-l7l_k9jt45.js +1 -0
- package/dist/web/_next/static/chunks/0k4zdm72k_bfy.js +1 -0
- package/dist/web/_next/static/chunks/0kbvoxla7f751.js +1 -0
- package/dist/web/_next/static/chunks/{0aa6bcdmtpekn.js → 0l2w0qz1ea7ql.js} +2 -2
- package/dist/web/_next/static/chunks/0p3h-h3zj5ujg.js +30 -0
- package/dist/web/_next/static/chunks/0paaat8y96ayc.js +7 -0
- package/dist/web/_next/static/chunks/0pm-un~-sy3rl.js +1 -0
- package/dist/web/_next/static/chunks/0pq318f8xgafg.js +1 -0
- package/dist/web/_next/static/chunks/0t6s8of0qr6nc.js +1 -0
- package/dist/web/_next/static/chunks/0u6h-hqc_i52e.js +1 -0
- package/dist/web/_next/static/chunks/0uxzi~9b~k4mn.js +31 -0
- package/dist/web/_next/static/chunks/{002-dxhags4dj.js → 0v6hte2z-32ca.js} +2 -2
- package/dist/web/_next/static/chunks/{014x2qbuiszni.js → 0vis~lx0nxgn-.js} +3 -3
- package/dist/web/_next/static/chunks/{0y09i51u6ixq5.js → 0w7.tb29958zj.js} +1 -1
- package/dist/web/_next/static/chunks/0xbaakj0dfc0..js +1 -0
- package/dist/web/_next/static/chunks/0yd.m1afqg.2t.js +3 -0
- package/dist/web/_next/static/chunks/0yhbr8hl09b-5.js +1 -0
- package/dist/web/_next/static/chunks/0zncg76rgtbm-.js +1 -0
- package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +1 -0
- package/dist/web/_next/static/chunks/0~~_ltu6dx_ch.js +1 -0
- package/dist/web/_next/static/chunks/{02c22g~xd-y30.js → 11cchuwoupmbf.js} +2 -2
- package/dist/web/_next/static/chunks/12jm4gwmvq-0q.js +90 -0
- package/dist/web/_next/static/chunks/12oxcgyhpaxw~.js +1 -0
- package/dist/web/_next/static/chunks/1452eibz62gs6.css +1 -0
- package/dist/web/_next/static/chunks/16zlreiems5cn.js +1 -0
- package/dist/web/_next/static/chunks/18awqjk9-o5m0.js +1 -0
- package/dist/web/_next/static/chunks/18c7g84y01mj0.js +1 -0
- package/dist/web/_next/static/chunks/{turbopack-0ndm2zc_pdptk.js → turbopack-11qjwlynmfc-n.js} +1 -1
- package/dist/web/_not-found/__next._full.txt +31 -30
- 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 +31 -30
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +24 -31
- 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 +34 -38
- 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 +27 -32
- package/dist/web/settings/output-styles/__next._head.txt +4 -4
- package/dist/web/settings/output-styles/__next._index.txt +14 -14
- package/dist/web/settings/output-styles/__next._tree.txt +3 -8
- package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
- package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
- package/dist/web/settings/output-styles/__next.settings.txt +5 -5
- package/dist/web/settings/output-styles.html +1 -1
- package/dist/web/settings/output-styles.txt +27 -32
- 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 +34 -38
- package/dist/web/workflows/__next._full.txt +32 -38
- 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 +32 -38
- package/dist/web/workspace/_/__next._full.txt +31 -36
- 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 -8
- package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
- 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 +31 -36
- package/dist/web/workspaces/__next._full.txt +30 -37
- 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 +30 -37
- package/dist/ws/agent-prompt.js +45 -8
- package/dist/ws/agent-runner.js +88 -10
- package/package.json +1 -1
- package/dist/web/_next/static/chunks/0-1bfvfwifh-m.js +0 -1
- package/dist/web/_next/static/chunks/02mf61htij8g0.js +0 -31
- package/dist/web/_next/static/chunks/046me66nilkff.js +0 -1
- package/dist/web/_next/static/chunks/04v-pqqs-2lvp.css +0 -1
- package/dist/web/_next/static/chunks/06w~.izyfylap.js +0 -1
- package/dist/web/_next/static/chunks/09t62a89~jesc.js +0 -3
- package/dist/web/_next/static/chunks/09y_3krccdd~u.js +0 -1
- package/dist/web/_next/static/chunks/0_e~hmntdfop9.js +0 -1
- package/dist/web/_next/static/chunks/0_udc.6.tueey.js +0 -1
- package/dist/web/_next/static/chunks/0cke33d38fnby.js +0 -90
- package/dist/web/_next/static/chunks/0cyq~8xb~r5fc.js +0 -1
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +0 -1
- package/dist/web/_next/static/chunks/0fxa1edqr7dve.js +0 -1
- package/dist/web/_next/static/chunks/0hra80eyuu37u.js +0 -1
- package/dist/web/_next/static/chunks/0ie7y4k2ncvnn.js +0 -1
- package/dist/web/_next/static/chunks/0igc~uli58ncw.js +0 -2
- package/dist/web/_next/static/chunks/0msb2mi3hiu5_.js +0 -67
- package/dist/web/_next/static/chunks/0p1n8bvfnpl41.js +0 -1
- package/dist/web/_next/static/chunks/0ppr271hz0xoq.js +0 -1
- package/dist/web/_next/static/chunks/0s_dva~eh2yhi.js +0 -3
- package/dist/web/_next/static/chunks/0typj55ox8d5i.js +0 -1
- package/dist/web/_next/static/chunks/0w2p4ldi2aymp.js +0 -1
- package/dist/web/_next/static/chunks/0zc0xgp5ourcn.js +0 -1
- package/dist/web/_next/static/chunks/0zmhdridea1s5.js +0 -90
- package/dist/web/_next/static/chunks/10.alq.6stmld.js +0 -1
- package/dist/web/_next/static/chunks/11b3zgk1etlkw.js +0 -7
- package/dist/web/_next/static/chunks/11qp8r5dotf7d.js +0 -1
- package/dist/web/_next/static/chunks/12mxlicp247c8.js +0 -1
- package/dist/web/_next/static/chunks/135w27dd8c19s.js +0 -5
- package/dist/web/_next/static/chunks/176dc-dtokxxi.js +0 -16
- package/dist/web/_next/static/chunks/17g-0pqre.anw.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/output-styles/carmack-mode.md +0 -381
- package/public/output-styles/codex-rigor-mode.md +0 -114
- package/public/output-styles/dhh-mode.md +0 -265
- package/public/output-styles/evan-you-mode.md +0 -539
- package/public/output-styles/index.json +0 -37
- package/public/output-styles/jobs-mode.md +0 -369
- package/public/output-styles/linus-mode.md +0 -135
- package/public/output-styles/uncle-bob-mode.md +0 -221
- package/public/prompt/andrej-karpathy-skills.md +0 -65
- package/public/prompt/claude-token-efficient-coding.md +0 -35
- package/public/prompt/index.json +0 -12
- package/public/skills/index.json +0 -92
- package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +0 -243
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +0 -44
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +0 -46
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +0 -124
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +0 -124
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +0 -438
- package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +0 -29
- package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +0 -40
- package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +0 -58
- package/public/skills/superpowers/brainstorming/SKILL.md +0 -164
- package/public/skills/superpowers/brainstorming/scripts/frame-template.html +0 -214
- package/public/skills/superpowers/brainstorming/scripts/helper.js +0 -88
- package/public/skills/superpowers/brainstorming/scripts/server.cjs +0 -354
- package/public/skills/superpowers/brainstorming/scripts/start-server.sh +0 -148
- package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +0 -56
- package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/public/skills/superpowers/brainstorming/visual-companion.md +0 -287
- package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -182
- package/public/skills/superpowers/executing-plans/SKILL.md +0 -70
- package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +0 -251
- package/public/skills/superpowers/receiving-code-review/SKILL.md +0 -213
- package/public/skills/superpowers/requesting-code-review/SKILL.md +0 -103
- package/public/skills/superpowers/requesting-code-review/code-reviewer.md +0 -168
- package/public/skills/superpowers/subagent-driven-development/SKILL.md +0 -279
- package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
- package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
- package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
- package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +0 -119
- package/public/skills/superpowers/systematic-debugging/SKILL.md +0 -296
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +0 -158
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -115
- package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +0 -122
- package/public/skills/superpowers/systematic-debugging/find-polluter.sh +0 -63
- package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -169
- package/public/skills/superpowers/systematic-debugging/test-academic.md +0 -14
- package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +0 -58
- package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +0 -68
- package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +0 -69
- package/public/skills/superpowers/test-driven-development/SKILL.md +0 -371
- package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -299
- package/public/skills/superpowers/using-git-worktrees/SKILL.md +0 -215
- package/public/skills/superpowers/using-superpowers/SKILL.md +0 -117
- package/public/skills/superpowers/using-superpowers/references/codex-tools.md +0 -59
- package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +0 -42
- package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +0 -51
- package/public/skills/superpowers/verification-before-completion/SKILL.md +0 -139
- package/public/skills/superpowers/writing-plans/SKILL.md +0 -152
- package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
- package/public/skills/superpowers/writing-skills/SKILL.md +0 -655
- package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +0 -1150
- package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +0 -172
- package/public/skills/superpowers/writing-skills/persuasion-principles.md +0 -187
- package/public/skills/superpowers/writing-skills/render-graphs.js +0 -168
- package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +0 -384
- /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { BUILT_IN_AGENT_TOOLS } from '@agent-spaces/shared';
|
|
2
|
+
import * as issueService from '../issue.js';
|
|
3
|
+
import * as issueCommentService from '../issue-comment.js';
|
|
4
|
+
import * as channelService from '../channel.js';
|
|
5
|
+
import * as taskService from '../task.js';
|
|
6
|
+
import * as agentService from '../agent.js';
|
|
7
|
+
const issueStatuses = [
|
|
8
|
+
'draft',
|
|
9
|
+
'planned',
|
|
10
|
+
'in_progress',
|
|
11
|
+
'review_pending',
|
|
12
|
+
'changes_requested',
|
|
13
|
+
'approved',
|
|
14
|
+
'completed',
|
|
15
|
+
'archived',
|
|
16
|
+
'error',
|
|
17
|
+
];
|
|
18
|
+
const currentChannelInputSchema = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
channelId: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'Must match the current channel id.',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ['channelId'],
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
};
|
|
29
|
+
const createIssueInputSchema = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
channelId: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'Must match the current channel id.',
|
|
35
|
+
},
|
|
36
|
+
title: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'Issue title to create for the current channel.',
|
|
39
|
+
},
|
|
40
|
+
description: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Issue description to create for the current channel.',
|
|
43
|
+
},
|
|
44
|
+
status: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: issueStatuses,
|
|
47
|
+
description: 'Issue status to create. Use completed when creating a finished issue report. Defaults to draft.',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ['channelId', 'title'],
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
};
|
|
53
|
+
const addCommentInputSchema = {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
channelId: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'Must match the current channel id.',
|
|
59
|
+
},
|
|
60
|
+
content: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'Comment content to add to the issue bound to the current channel.',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ['channelId', 'content'],
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
};
|
|
68
|
+
export function createIssueFunctionTools(workspaceId, channel, actor, allowedTools) {
|
|
69
|
+
if (!channel)
|
|
70
|
+
return [];
|
|
71
|
+
const allowedToolNames = new Set(allowedTools ?? BUILT_IN_AGENT_TOOLS.map((tool) => tool.name));
|
|
72
|
+
const tools = [
|
|
73
|
+
{
|
|
74
|
+
name: 'CreateCurrentChannelIssue',
|
|
75
|
+
description: 'Create an issue for the current channel and bind it to this channel. The channelId must be the current channel id.',
|
|
76
|
+
inputSchema: createIssueInputSchema,
|
|
77
|
+
annotations: { destructive: false, openWorld: false },
|
|
78
|
+
execute: async (input) => createCurrentChannelIssue(workspaceId, channel, input),
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
tools.push({
|
|
82
|
+
name: 'ViewCurrentChannelIssue',
|
|
83
|
+
description: 'View the issue and comments bound to the current channel. The channelId must be the current channel id.',
|
|
84
|
+
inputSchema: currentChannelInputSchema,
|
|
85
|
+
annotations: { readOnly: true, openWorld: false },
|
|
86
|
+
execute: async (input) => viewCurrentChannelIssue(workspaceId, channel, input),
|
|
87
|
+
}, {
|
|
88
|
+
name: 'AddCurrentChannelComment',
|
|
89
|
+
description: 'Add a comment to the issue bound to the current channel. The channelId must be the current channel id.',
|
|
90
|
+
inputSchema: addCommentInputSchema,
|
|
91
|
+
annotations: { destructive: false, openWorld: false },
|
|
92
|
+
execute: async (input) => addCurrentChannelComment(workspaceId, channel, actor, input),
|
|
93
|
+
});
|
|
94
|
+
return tools.filter((tool) => allowedToolNames.has(tool.name));
|
|
95
|
+
}
|
|
96
|
+
export function isBuiltInIssueToolName(name) {
|
|
97
|
+
return name === 'CreateCurrentChannelIssue'
|
|
98
|
+
|| name === 'ViewCurrentChannelIssue'
|
|
99
|
+
|| name === 'AddCurrentChannelComment'
|
|
100
|
+
|| name === 'agent-spaces.CreateCurrentChannelIssue'
|
|
101
|
+
|| name === 'agent-spaces.ViewCurrentChannelIssue'
|
|
102
|
+
|| name === 'agent-spaces.AddCurrentChannelComment';
|
|
103
|
+
}
|
|
104
|
+
function createCurrentChannelIssue(workspaceId, channel, input) {
|
|
105
|
+
const data = assertCurrentChannelId(channel, input);
|
|
106
|
+
const currentChannel = getCurrentChannel(workspaceId, channel);
|
|
107
|
+
if (currentChannel.issueId)
|
|
108
|
+
throw new Error(`Current channel already has a bound issue: ${currentChannel.issueId}`);
|
|
109
|
+
const title = typeof data.title === 'string' ? data.title.trim() : '';
|
|
110
|
+
const description = typeof data.description === 'string' ? data.description.trim() : '';
|
|
111
|
+
const status = parseIssueStatus(data.status);
|
|
112
|
+
if (!title)
|
|
113
|
+
throw new Error('title is required.');
|
|
114
|
+
const issue = issueService.createForChannel(workspaceId, currentChannel.id, { title, description, status });
|
|
115
|
+
if (!issue)
|
|
116
|
+
throw new Error(`Current channel not found: ${currentChannel.id}`);
|
|
117
|
+
channel.issueId = issue.id;
|
|
118
|
+
channel.type = 'issue';
|
|
119
|
+
channel.name = title;
|
|
120
|
+
return issue;
|
|
121
|
+
}
|
|
122
|
+
function parseIssueStatus(status) {
|
|
123
|
+
if (status === undefined)
|
|
124
|
+
return undefined;
|
|
125
|
+
if (typeof status !== 'string' || !issueStatuses.includes(status)) {
|
|
126
|
+
throw new Error(`status must be one of: ${issueStatuses.join(', ')}.`);
|
|
127
|
+
}
|
|
128
|
+
return status;
|
|
129
|
+
}
|
|
130
|
+
function viewCurrentChannelIssue(workspaceId, channel, input) {
|
|
131
|
+
assertCurrentChannelId(channel, input);
|
|
132
|
+
const issue = getBoundIssue(workspaceId, channel);
|
|
133
|
+
const currentChannel = getCurrentChannel(workspaceId, channel);
|
|
134
|
+
const assignableAgents = getAssignableAgents(workspaceId, currentChannel);
|
|
135
|
+
return {
|
|
136
|
+
issue,
|
|
137
|
+
comments: issueCommentService.listIssueComments(workspaceId, issue.id),
|
|
138
|
+
tasks: taskService.list(workspaceId, issue.id),
|
|
139
|
+
channel: {
|
|
140
|
+
id: currentChannel.id,
|
|
141
|
+
name: currentChannel.name,
|
|
142
|
+
type: currentChannel.type,
|
|
143
|
+
issueId: currentChannel.issueId,
|
|
144
|
+
members: currentChannel.members,
|
|
145
|
+
pinnedMentionId: currentChannel.pinnedMentionId,
|
|
146
|
+
todos: currentChannel.todos,
|
|
147
|
+
},
|
|
148
|
+
assignableAgents,
|
|
149
|
+
validAgentConfigIds: assignableAgents.map((agent) => agent.id),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function addCurrentChannelComment(workspaceId, channel, actor, input) {
|
|
153
|
+
const data = assertCurrentChannelId(channel, input);
|
|
154
|
+
const issue = getBoundIssue(workspaceId, channel);
|
|
155
|
+
const content = typeof data.content === 'string' ? data.content.trim() : '';
|
|
156
|
+
if (!content)
|
|
157
|
+
throw new Error('content is required.');
|
|
158
|
+
const comment = issueCommentService.createIssueComment(workspaceId, issue.id, {
|
|
159
|
+
senderId: actor.senderId,
|
|
160
|
+
senderRole: actor.senderRole,
|
|
161
|
+
content,
|
|
162
|
+
source: actor.senderId === 'user' ? 'user' : 'agent_progress',
|
|
163
|
+
metadata: {
|
|
164
|
+
channelId: channel.id,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
if (!comment)
|
|
168
|
+
throw new Error(`Bound issue not found: ${issue.id}`);
|
|
169
|
+
return comment;
|
|
170
|
+
}
|
|
171
|
+
function getBoundIssue(workspaceId, channel) {
|
|
172
|
+
const currentChannel = getCurrentChannel(workspaceId, channel);
|
|
173
|
+
if (!currentChannel.issueId)
|
|
174
|
+
throw new Error('Current channel is not bound to an issue.');
|
|
175
|
+
const issue = issueService.getById(workspaceId, currentChannel.issueId);
|
|
176
|
+
if (!issue)
|
|
177
|
+
throw new Error(`Bound issue not found: ${currentChannel.issueId}`);
|
|
178
|
+
return issue;
|
|
179
|
+
}
|
|
180
|
+
function getCurrentChannel(workspaceId, channel) {
|
|
181
|
+
const currentChannel = channelService.getChannel(workspaceId, channel.id);
|
|
182
|
+
if (!currentChannel)
|
|
183
|
+
throw new Error(`Current channel not found: ${channel.id}`);
|
|
184
|
+
return currentChannel;
|
|
185
|
+
}
|
|
186
|
+
function getAssignableAgents(workspaceId, channel) {
|
|
187
|
+
const members = new Set(channel.members);
|
|
188
|
+
return (agentService.listPresets(workspaceId) ?? [])
|
|
189
|
+
.filter((agent) => members.has(agent.id) && agent.enabled !== false)
|
|
190
|
+
.map((agent) => ({
|
|
191
|
+
id: agent.id,
|
|
192
|
+
name: agent.name,
|
|
193
|
+
role: agent.role,
|
|
194
|
+
description: agent.description,
|
|
195
|
+
enabled: agent.enabled,
|
|
196
|
+
sandboxDirs: agent.sandboxDirs,
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
function assertCurrentChannelId(channel, input) {
|
|
200
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
201
|
+
throw new Error('Tool input must be an object.');
|
|
202
|
+
}
|
|
203
|
+
const data = input;
|
|
204
|
+
if (data.channelId !== channel.id) {
|
|
205
|
+
throw new Error(`channelId must match the current channel id: ${channel.id}`);
|
|
206
|
+
}
|
|
207
|
+
return data;
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=issue-tools.js.map
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { BUILT_IN_AGENT_TOOLS } from '@agent-spaces/shared';
|
|
2
|
+
import * as kanbanStore from '../../storage/kanban-store.js';
|
|
3
|
+
import { broadcastToWorkspace } from '../../ws/connection-manager.js';
|
|
4
|
+
import { assertRecord, readOptionalString, readRequiredString, readString } from './input-helpers.js';
|
|
5
|
+
const kanbanLayoutModes = ['horizontal', 'vertical'];
|
|
6
|
+
const kanbanPriorities = ['low', 'medium', 'high'];
|
|
7
|
+
const listKanbanBoardsInputSchema = {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {},
|
|
10
|
+
additionalProperties: false,
|
|
11
|
+
};
|
|
12
|
+
const viewKanbanBoardInputSchema = {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
boardId: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Optional Kanban board ID. Omit to view the current workspace board.',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
};
|
|
22
|
+
const createKanbanBoardInputSchema = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
title: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Board title. Defaults to Kanban Board.',
|
|
28
|
+
},
|
|
29
|
+
layoutMode: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
enum: kanbanLayoutModes,
|
|
32
|
+
description: 'Board layout mode. Defaults to horizontal.',
|
|
33
|
+
},
|
|
34
|
+
columns: {
|
|
35
|
+
type: 'array',
|
|
36
|
+
description: 'Optional complete column list. Defaults to To Do, In Progress, Done, Archive.',
|
|
37
|
+
items: { type: 'object' },
|
|
38
|
+
},
|
|
39
|
+
tasks: {
|
|
40
|
+
type: 'array',
|
|
41
|
+
description: 'Optional complete task list. Defaults to empty.',
|
|
42
|
+
items: { type: 'object' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
};
|
|
47
|
+
const updateKanbanBoardInputSchema = {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
boardId: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: 'Optional Kanban board ID. Omit to update the current workspace board.',
|
|
53
|
+
},
|
|
54
|
+
title: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'New board title.',
|
|
57
|
+
},
|
|
58
|
+
layoutMode: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
enum: kanbanLayoutModes,
|
|
61
|
+
description: 'New board layout mode.',
|
|
62
|
+
},
|
|
63
|
+
columns: {
|
|
64
|
+
type: 'array',
|
|
65
|
+
description: 'Complete replacement column list. Existing columns are replaced.',
|
|
66
|
+
items: { type: 'object' },
|
|
67
|
+
},
|
|
68
|
+
tasks: {
|
|
69
|
+
type: 'array',
|
|
70
|
+
description: 'Complete replacement task list. Existing tasks are replaced.',
|
|
71
|
+
items: { type: 'object' },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
additionalProperties: false,
|
|
75
|
+
};
|
|
76
|
+
const deleteKanbanBoardInputSchema = {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
boardId: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
description: 'Optional Kanban board ID. Omit to delete the current workspace board.',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
additionalProperties: false,
|
|
85
|
+
};
|
|
86
|
+
export function createKanbanFunctionTools(workspaceId, allowedTools) {
|
|
87
|
+
const allowedToolNames = getAllowedKanbanToolNames(allowedTools);
|
|
88
|
+
const tools = [
|
|
89
|
+
{
|
|
90
|
+
name: 'ListKanbanBoards',
|
|
91
|
+
description: 'List Kanban boards in the current workspace. Agent Spaces currently uses one board per workspace.',
|
|
92
|
+
inputSchema: listKanbanBoardsInputSchema,
|
|
93
|
+
annotations: { readOnly: true, openWorld: false },
|
|
94
|
+
execute: async () => listKanbanBoards(workspaceId),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'ViewKanbanBoard',
|
|
98
|
+
description: 'View the current workspace Kanban board, including board metadata, columns, and tasks.',
|
|
99
|
+
inputSchema: viewKanbanBoardInputSchema,
|
|
100
|
+
annotations: { readOnly: true, openWorld: false },
|
|
101
|
+
execute: async (input) => viewKanbanBoard(workspaceId, input),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'CreateKanbanBoard',
|
|
105
|
+
description: 'Create the current workspace Kanban board. Use this only when ListKanbanBoards returns no board.',
|
|
106
|
+
inputSchema: createKanbanBoardInputSchema,
|
|
107
|
+
annotations: { destructive: false, openWorld: false },
|
|
108
|
+
execute: async (input) => createKanbanBoard(workspaceId, input),
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'UpdateKanbanBoard',
|
|
112
|
+
description: 'Update the current workspace Kanban board metadata and optionally replace its complete columns or tasks arrays.',
|
|
113
|
+
inputSchema: updateKanbanBoardInputSchema,
|
|
114
|
+
annotations: { destructive: false, openWorld: false },
|
|
115
|
+
execute: async (input) => updateKanbanBoard(workspaceId, input),
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'DeleteKanbanBoard',
|
|
119
|
+
description: 'Delete the current workspace Kanban board, including all columns and tasks.',
|
|
120
|
+
inputSchema: deleteKanbanBoardInputSchema,
|
|
121
|
+
annotations: { destructive: true, openWorld: false },
|
|
122
|
+
execute: async (input) => deleteKanbanBoard(workspaceId, input),
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
return tools.filter((tool) => allowedToolNames.has(tool.name));
|
|
126
|
+
}
|
|
127
|
+
function getAllowedKanbanToolNames(allowedTools) {
|
|
128
|
+
const names = new Set(allowedTools ?? BUILT_IN_AGENT_TOOLS.map((tool) => tool.name));
|
|
129
|
+
const hasKanbanTools = Array.from(names).some((name) => isKanbanToolName(name));
|
|
130
|
+
if (hasKanbanTools) {
|
|
131
|
+
names.add('ListKanbanBoards');
|
|
132
|
+
names.add('ViewKanbanBoard');
|
|
133
|
+
names.add('CreateKanbanBoard');
|
|
134
|
+
}
|
|
135
|
+
return names;
|
|
136
|
+
}
|
|
137
|
+
function listKanbanBoards(workspaceId) {
|
|
138
|
+
return kanbanStore.listBoards(workspaceId);
|
|
139
|
+
}
|
|
140
|
+
function viewKanbanBoard(workspaceId, input) {
|
|
141
|
+
const data = assertRecord(input);
|
|
142
|
+
const board = resolveKanbanBoard(workspaceId, readOptionalString(data.boardId));
|
|
143
|
+
return board;
|
|
144
|
+
}
|
|
145
|
+
function createKanbanBoard(workspaceId, input) {
|
|
146
|
+
const data = assertRecord(input);
|
|
147
|
+
const existing = kanbanStore.getBoard(workspaceId);
|
|
148
|
+
if (existing)
|
|
149
|
+
throw new Error(`Kanban board already exists for this workspace: ${existing.id}. Use UpdateKanbanBoard instead.`);
|
|
150
|
+
const title = readOptionalString(data.title) ?? 'Kanban Board';
|
|
151
|
+
const layoutMode = parseLayoutMode(data.layoutMode);
|
|
152
|
+
const board = kanbanStore.createBoard(workspaceId, title);
|
|
153
|
+
if (layoutMode !== 'horizontal')
|
|
154
|
+
kanbanStore.updateBoard(workspaceId, { layoutMode }, board.id);
|
|
155
|
+
const columns = Object.hasOwn(data, 'columns') ? parseColumns(data.columns) : createDefaultColumns();
|
|
156
|
+
kanbanStore.saveColumns(board.id, columns);
|
|
157
|
+
if (Object.hasOwn(data, 'tasks'))
|
|
158
|
+
kanbanStore.saveTasks(board.id, parseTasks(data.tasks, columns));
|
|
159
|
+
const created = kanbanStore.getBoard(workspaceId);
|
|
160
|
+
if (!created)
|
|
161
|
+
throw new Error('Failed to create Kanban board.');
|
|
162
|
+
broadcastToWorkspace(workspaceId, 'kanban.updated', created);
|
|
163
|
+
return created;
|
|
164
|
+
}
|
|
165
|
+
function updateKanbanBoard(workspaceId, input) {
|
|
166
|
+
const data = assertRecord(input);
|
|
167
|
+
const board = resolveKanbanBoard(workspaceId, readOptionalString(data.boardId));
|
|
168
|
+
const updates = {};
|
|
169
|
+
if (Object.hasOwn(data, 'title'))
|
|
170
|
+
updates.title = readRequiredString(data.title, 'title');
|
|
171
|
+
if (Object.hasOwn(data, 'layoutMode'))
|
|
172
|
+
updates.layoutMode = parseLayoutMode(data.layoutMode);
|
|
173
|
+
if (!updates.title && !updates.layoutMode && !Object.hasOwn(data, 'columns') && !Object.hasOwn(data, 'tasks')) {
|
|
174
|
+
throw new Error('At least one field is required: title, layoutMode, columns, or tasks.');
|
|
175
|
+
}
|
|
176
|
+
const nextColumns = Object.hasOwn(data, 'columns') ? parseColumns(data.columns) : board.columns;
|
|
177
|
+
const nextTasks = Object.hasOwn(data, 'tasks') ? parseTasks(data.tasks, nextColumns) : parseTasks(board.tasks, nextColumns);
|
|
178
|
+
if (updates.title || updates.layoutMode) {
|
|
179
|
+
const updated = kanbanStore.updateBoard(workspaceId, updates, board.id);
|
|
180
|
+
if (!updated)
|
|
181
|
+
throw new Error(`Kanban board not found: ${board.id}`);
|
|
182
|
+
}
|
|
183
|
+
if (Object.hasOwn(data, 'columns'))
|
|
184
|
+
kanbanStore.saveColumns(board.id, nextColumns);
|
|
185
|
+
if (Object.hasOwn(data, 'tasks'))
|
|
186
|
+
kanbanStore.saveTasks(board.id, nextTasks);
|
|
187
|
+
const updated = kanbanStore.listBoards(workspaceId).find((item) => item.id === board.id);
|
|
188
|
+
if (!updated)
|
|
189
|
+
throw new Error(`Kanban board not found: ${board.id}`);
|
|
190
|
+
broadcastToWorkspace(workspaceId, 'kanban.updated', updated);
|
|
191
|
+
return updated;
|
|
192
|
+
}
|
|
193
|
+
function deleteKanbanBoard(workspaceId, input) {
|
|
194
|
+
const data = assertRecord(input);
|
|
195
|
+
const board = resolveKanbanBoard(workspaceId, readOptionalString(data.boardId));
|
|
196
|
+
const ok = kanbanStore.deleteBoard(workspaceId, board.id);
|
|
197
|
+
if (!ok)
|
|
198
|
+
throw new Error(`Kanban board not found: ${board.id}`);
|
|
199
|
+
broadcastToWorkspace(workspaceId, 'kanban.deleted', { boardId: board.id });
|
|
200
|
+
return { ok: true, deletedBoardId: board.id };
|
|
201
|
+
}
|
|
202
|
+
function resolveKanbanBoard(workspaceId, boardId) {
|
|
203
|
+
const boards = kanbanStore.listBoards(workspaceId);
|
|
204
|
+
const board = boardId ? boards.find((item) => item.id === boardId) : boards[0];
|
|
205
|
+
if (!board)
|
|
206
|
+
throw new Error('Kanban board not found. Use CreateKanbanBoard to create one.');
|
|
207
|
+
return board;
|
|
208
|
+
}
|
|
209
|
+
function createDefaultColumns() {
|
|
210
|
+
return [
|
|
211
|
+
{ id: 'todo', title: 'To Do', color: 'sky', order: 0 },
|
|
212
|
+
{ id: 'progress', title: 'In Progress', color: 'amber', order: 1 },
|
|
213
|
+
{ id: 'done', title: 'Done', color: 'emerald', order: 2 },
|
|
214
|
+
{ id: 'archive', title: 'Archive', color: 'slate', order: 3 },
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
function parseColumns(value) {
|
|
218
|
+
if (!Array.isArray(value))
|
|
219
|
+
throw new Error('columns must be an array.');
|
|
220
|
+
return value.map((item, index) => {
|
|
221
|
+
const data = assertRecord(item);
|
|
222
|
+
return {
|
|
223
|
+
id: readRequiredString(data.id, `columns[${index}].id`),
|
|
224
|
+
title: readRequiredString(data.title, `columns[${index}].title`),
|
|
225
|
+
color: readOptionalString(data.color) ?? 'sky',
|
|
226
|
+
order: readInteger(data.order, `columns[${index}].order`, index),
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function parseTasks(value, columns) {
|
|
231
|
+
if (!Array.isArray(value))
|
|
232
|
+
throw new Error('tasks must be an array.');
|
|
233
|
+
const columnIds = new Set(columns.map((column) => column.id));
|
|
234
|
+
return value.map((item, index) => {
|
|
235
|
+
const data = assertRecord(item);
|
|
236
|
+
const columnId = readRequiredString(data.columnId, `tasks[${index}].columnId`);
|
|
237
|
+
if (!columnIds.has(columnId))
|
|
238
|
+
throw new Error(`tasks[${index}].columnId does not match any column: ${columnId}`);
|
|
239
|
+
return {
|
|
240
|
+
id: readRequiredString(data.id, `tasks[${index}].id`),
|
|
241
|
+
title: readRequiredString(data.title, `tasks[${index}].title`),
|
|
242
|
+
description: readString(data.description ?? '', `tasks[${index}].description`),
|
|
243
|
+
priority: parsePriority(data.priority, `tasks[${index}].priority`),
|
|
244
|
+
columnId,
|
|
245
|
+
order: readInteger(data.order, `tasks[${index}].order`, index),
|
|
246
|
+
createdAt: readInteger(data.createdAt, `tasks[${index}].createdAt`, Date.now()),
|
|
247
|
+
dueDate: readOptionalString(data.dueDate),
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function parseLayoutMode(value) {
|
|
252
|
+
if (value === undefined)
|
|
253
|
+
return 'horizontal';
|
|
254
|
+
if (typeof value !== 'string' || !kanbanLayoutModes.includes(value)) {
|
|
255
|
+
throw new Error(`layoutMode must be one of: ${kanbanLayoutModes.join(', ')}.`);
|
|
256
|
+
}
|
|
257
|
+
return value;
|
|
258
|
+
}
|
|
259
|
+
function parsePriority(value, field) {
|
|
260
|
+
if (value === undefined)
|
|
261
|
+
return 'medium';
|
|
262
|
+
if (typeof value !== 'string' || !kanbanPriorities.includes(value)) {
|
|
263
|
+
throw new Error(`${field} must be one of: ${kanbanPriorities.join(', ')}.`);
|
|
264
|
+
}
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
function readInteger(value, field, fallback) {
|
|
268
|
+
if (value === undefined)
|
|
269
|
+
return fallback;
|
|
270
|
+
if (typeof value !== 'number' || !Number.isInteger(value))
|
|
271
|
+
throw new Error(`${field} must be an integer.`);
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
function isKanbanToolName(name) {
|
|
275
|
+
return name === 'ListKanbanBoards'
|
|
276
|
+
|| name === 'ViewKanbanBoard'
|
|
277
|
+
|| name === 'CreateKanbanBoard'
|
|
278
|
+
|| name === 'UpdateKanbanBoard'
|
|
279
|
+
|| name === 'DeleteKanbanBoard';
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=kanban-tools.js.map
|