@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
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# 初始化新会话的规划文件
|
|
3
|
-
# 用法:./init-session.sh [项目名称]
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
PROJECT_NAME="${1:-project}"
|
|
8
|
-
DATE=$(date +%Y-%m-%d)
|
|
9
|
-
|
|
10
|
-
echo "正在初始化规划文件:$PROJECT_NAME"
|
|
11
|
-
|
|
12
|
-
# 如果 task_plan.md 不存在则创建
|
|
13
|
-
if [ ! -f "task_plan.md" ]; then
|
|
14
|
-
cat > task_plan.md << 'EOF'
|
|
15
|
-
# 任务计划:[简要描述]
|
|
16
|
-
|
|
17
|
-
## 目标
|
|
18
|
-
[用一句话描述最终状态]
|
|
19
|
-
|
|
20
|
-
## 当前阶段
|
|
21
|
-
阶段 1
|
|
22
|
-
|
|
23
|
-
## 各阶段
|
|
24
|
-
|
|
25
|
-
### 阶段 1:需求与发现
|
|
26
|
-
- [ ] 理解用户意图
|
|
27
|
-
- [ ] 确定约束条件和需求
|
|
28
|
-
- [ ] 将发现记录到 findings.md
|
|
29
|
-
- **状态:** in_progress
|
|
30
|
-
|
|
31
|
-
### 阶段 2:规划与结构
|
|
32
|
-
- [ ] 确定技术方案
|
|
33
|
-
- [ ] 如有需要创建项目结构
|
|
34
|
-
- [ ] 记录决策及理由
|
|
35
|
-
- **状态:** pending
|
|
36
|
-
|
|
37
|
-
### 阶段 3:实现
|
|
38
|
-
- [ ] 按计划逐步执行
|
|
39
|
-
- [ ] 先将代码写入文件再执行
|
|
40
|
-
- [ ] 增量测试
|
|
41
|
-
- **状态:** pending
|
|
42
|
-
|
|
43
|
-
### 阶段 4:测试与验证
|
|
44
|
-
- [ ] 验证所有需求已满足
|
|
45
|
-
- [ ] 将测试结果记录到 progress.md
|
|
46
|
-
- [ ] 修复发现的问题
|
|
47
|
-
- **状态:** pending
|
|
48
|
-
|
|
49
|
-
### 阶段 5:交付
|
|
50
|
-
- [ ] 检查所有输出文件
|
|
51
|
-
- [ ] 确保交付物完整
|
|
52
|
-
- [ ] 交付给用户
|
|
53
|
-
- **状态:** pending
|
|
54
|
-
|
|
55
|
-
## 已做决策
|
|
56
|
-
| 决策 | 理由 |
|
|
57
|
-
|------|------|
|
|
58
|
-
|
|
59
|
-
## 遇到的错误
|
|
60
|
-
| 错误 | 解决方案 |
|
|
61
|
-
|------|---------|
|
|
62
|
-
EOF
|
|
63
|
-
echo "已创建 task_plan.md"
|
|
64
|
-
else
|
|
65
|
-
echo "task_plan.md 已存在,跳过"
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
# 如果 findings.md 不存在则创建
|
|
69
|
-
if [ ! -f "findings.md" ]; then
|
|
70
|
-
cat > findings.md << 'EOF'
|
|
71
|
-
# 发现与决策
|
|
72
|
-
|
|
73
|
-
## 需求
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
## 研究发现
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
## 技术决策
|
|
80
|
-
| 决策 | 理由 |
|
|
81
|
-
|------|------|
|
|
82
|
-
|
|
83
|
-
## 遇到的问题
|
|
84
|
-
| 问题 | 解决方案 |
|
|
85
|
-
|------|---------|
|
|
86
|
-
|
|
87
|
-
## 资源
|
|
88
|
-
-
|
|
89
|
-
EOF
|
|
90
|
-
echo "已创建 findings.md"
|
|
91
|
-
else
|
|
92
|
-
echo "findings.md 已存在,跳过"
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# 如果 progress.md 不存在则创建
|
|
96
|
-
if [ ! -f "progress.md" ]; then
|
|
97
|
-
cat > progress.md << EOF
|
|
98
|
-
# 进度日志
|
|
99
|
-
|
|
100
|
-
## 会话:$DATE
|
|
101
|
-
|
|
102
|
-
### 当前状态
|
|
103
|
-
- **阶段:** 1 - 需求与发现
|
|
104
|
-
- **开始时间:** $DATE
|
|
105
|
-
|
|
106
|
-
### 已执行操作
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
### 测试结果
|
|
110
|
-
| 测试 | 预期 | 实际 | 状态 |
|
|
111
|
-
|------|------|------|------|
|
|
112
|
-
|
|
113
|
-
### 错误
|
|
114
|
-
| 错误 | 解决方案 |
|
|
115
|
-
|------|---------|
|
|
116
|
-
EOF
|
|
117
|
-
echo "已创建 progress.md"
|
|
118
|
-
else
|
|
119
|
-
echo "progress.md 已存在,跳过"
|
|
120
|
-
fi
|
|
121
|
-
|
|
122
|
-
echo ""
|
|
123
|
-
echo "规划文件已初始化!"
|
|
124
|
-
echo "文件:task_plan.md, findings.md, progress.md"
|
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
planning-with-files 会话恢复脚本
|
|
4
|
-
|
|
5
|
-
分析上一个会话,查找在最后一次规划文件更新后未同步的上下文。
|
|
6
|
-
设计为在 SessionStart 时运行。
|
|
7
|
-
|
|
8
|
-
用法:python3 session-catchup.py [项目路径]
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import json
|
|
12
|
-
import sys
|
|
13
|
-
import os
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
from typing import Any, Dict, Iterable, List, Optional, Tuple
|
|
16
|
-
|
|
17
|
-
try:
|
|
18
|
-
import orjson
|
|
19
|
-
except ImportError:
|
|
20
|
-
orjson = None
|
|
21
|
-
|
|
22
|
-
PLANNING_FILES = ['task_plan.md', 'progress.md', 'findings.md']
|
|
23
|
-
MIN_SESSION_BYTES = 5000
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def json_loads(line: str) -> Optional[Dict[str, Any]]:
|
|
27
|
-
"""Prefer optional orjson while keeping the hook dependency-free."""
|
|
28
|
-
try:
|
|
29
|
-
if orjson is not None:
|
|
30
|
-
data = orjson.loads(line)
|
|
31
|
-
else:
|
|
32
|
-
data = json.loads(line)
|
|
33
|
-
except (ValueError, TypeError, UnicodeDecodeError):
|
|
34
|
-
return None
|
|
35
|
-
return data if isinstance(data, dict) else None
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def normalize_for_compare(path_value: str) -> str:
|
|
39
|
-
expanded = os.path.expanduser(path_value)
|
|
40
|
-
try:
|
|
41
|
-
return str(Path(expanded).resolve())
|
|
42
|
-
except (OSError, ValueError):
|
|
43
|
-
return os.path.abspath(expanded)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def normalize_path(project_path: str) -> str:
|
|
47
|
-
"""Normalize project path to match Claude Code's internal representation.
|
|
48
|
-
|
|
49
|
-
Claude Code stores session directories using the Windows-native path
|
|
50
|
-
(e.g., C:\\Users\\...) sanitized with separators replaced by dashes.
|
|
51
|
-
Git Bash passes /c/Users/... which produces a DIFFERENT sanitized
|
|
52
|
-
string. This function converts Git Bash paths to Windows paths first.
|
|
53
|
-
"""
|
|
54
|
-
p = project_path
|
|
55
|
-
|
|
56
|
-
# Git Bash / MSYS2: /c/Users/... -> C:/Users/...
|
|
57
|
-
if len(p) >= 3 and p[0] == '/' and p[2] == '/':
|
|
58
|
-
p = p[1].upper() + ':' + p[2:]
|
|
59
|
-
|
|
60
|
-
# Resolve to absolute path to handle relative paths and symlinks
|
|
61
|
-
try:
|
|
62
|
-
resolved = str(Path(p).resolve())
|
|
63
|
-
# On Windows, resolve() returns C:\Users\... which is what we want
|
|
64
|
-
if os.name == 'nt' or '\\' in resolved:
|
|
65
|
-
p = resolved
|
|
66
|
-
except (OSError, ValueError):
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
return p
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def get_claude_project_dir(project_path: str) -> Path:
|
|
73
|
-
"""Resolve Claude Code's project-specific session storage path."""
|
|
74
|
-
normalized = normalize_path(project_path)
|
|
75
|
-
|
|
76
|
-
# Claude Code's sanitization: replace path separators and : with -
|
|
77
|
-
sanitized = normalized.replace('\\', '-').replace('/', '-').replace(':', '-')
|
|
78
|
-
sanitized = sanitized.replace('_', '-')
|
|
79
|
-
# Strip leading dash if present (Unix absolute paths start with /)
|
|
80
|
-
if sanitized.startswith('-'):
|
|
81
|
-
sanitized = sanitized[1:]
|
|
82
|
-
|
|
83
|
-
return Path.home() / '.claude' / 'projects' / sanitized
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def get_sessions_sorted(project_dir: Path) -> List[Path]:
|
|
87
|
-
"""Get all session files sorted by modification time (newest first)."""
|
|
88
|
-
sessions = list(project_dir.glob('*.jsonl'))
|
|
89
|
-
main_sessions = [s for s in sessions if not s.name.startswith('agent-')]
|
|
90
|
-
return sorted(main_sessions, key=safe_stat_mtime, reverse=True)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def safe_stat_mtime(path: Path) -> float:
|
|
94
|
-
try:
|
|
95
|
-
return path.stat().st_mtime
|
|
96
|
-
except OSError:
|
|
97
|
-
return 0.0
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def is_substantial_session(session: Path) -> bool:
|
|
101
|
-
try:
|
|
102
|
-
return session.stat().st_size > MIN_SESSION_BYTES
|
|
103
|
-
except OSError:
|
|
104
|
-
return False
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def read_codex_meta(session_file: Path) -> Optional[Dict[str, Any]]:
|
|
108
|
-
"""Read the first session_meta; later meta records may be copied parent context."""
|
|
109
|
-
try:
|
|
110
|
-
with open(session_file, 'r', encoding='utf-8', errors='replace') as f:
|
|
111
|
-
for line in f:
|
|
112
|
-
data = json_loads(line)
|
|
113
|
-
if not data or data.get('type') != 'session_meta':
|
|
114
|
-
continue
|
|
115
|
-
payload = data.get('payload')
|
|
116
|
-
return payload if isinstance(payload, dict) else None
|
|
117
|
-
except OSError:
|
|
118
|
-
return None
|
|
119
|
-
return None
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def codex_meta_cwd(meta: Dict[str, Any]) -> Optional[str]:
|
|
123
|
-
cwd = meta.get('cwd')
|
|
124
|
-
return cwd if isinstance(cwd, str) else None
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def find_current_codex_session(sessions: List[Path]) -> Optional[Path]:
|
|
128
|
-
thread_id = os.getenv('CODEX_THREAD_ID', '').strip()
|
|
129
|
-
if not thread_id:
|
|
130
|
-
return None
|
|
131
|
-
|
|
132
|
-
for session in sessions:
|
|
133
|
-
if thread_id in session.name:
|
|
134
|
-
return session
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def is_codex_project_session(session: Path, project_cmp: str) -> bool:
|
|
139
|
-
if not is_substantial_session(session):
|
|
140
|
-
return False
|
|
141
|
-
|
|
142
|
-
meta = read_codex_meta(session)
|
|
143
|
-
if not meta:
|
|
144
|
-
return False
|
|
145
|
-
source = meta.get('source')
|
|
146
|
-
if isinstance(source, dict) and 'subagent' in source:
|
|
147
|
-
return False
|
|
148
|
-
cwd = codex_meta_cwd(meta)
|
|
149
|
-
return bool(cwd and normalize_for_compare(cwd) == project_cmp)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def get_codex_sessions(project_path: str) -> Iterable[Path]:
|
|
153
|
-
sessions_dir = Path(os.path.expanduser(os.getenv('CODEX_SESSIONS_DIR', '~/.codex/sessions')))
|
|
154
|
-
if not sessions_dir.exists():
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
project_cmp = normalize_for_compare(project_path)
|
|
158
|
-
sessions = sorted(sessions_dir.rglob('rollout-*.jsonl'), key=safe_stat_mtime, reverse=True)
|
|
159
|
-
current = find_current_codex_session(sessions)
|
|
160
|
-
if current and is_codex_project_session(current, project_cmp):
|
|
161
|
-
yield current
|
|
162
|
-
|
|
163
|
-
for session in sessions:
|
|
164
|
-
if session == current:
|
|
165
|
-
continue
|
|
166
|
-
if is_codex_project_session(session, project_cmp):
|
|
167
|
-
yield session
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def get_session_candidates(project_path: str) -> Tuple[str, Iterable[Path]]:
|
|
171
|
-
if '/.codex/' in Path(__file__).resolve().as_posix().lower():
|
|
172
|
-
return 'codex', get_codex_sessions(project_path)
|
|
173
|
-
|
|
174
|
-
claude_project_dir = get_claude_project_dir(project_path)
|
|
175
|
-
if claude_project_dir.exists():
|
|
176
|
-
return 'claude', get_sessions_sorted(claude_project_dir)
|
|
177
|
-
return 'claude', []
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
def parse_session_messages(session_file: Path) -> List[Dict[str, Any]]:
|
|
181
|
-
"""Parse all messages from a session file, preserving order."""
|
|
182
|
-
messages = []
|
|
183
|
-
with open(session_file, 'r', encoding='utf-8', errors='replace') as f:
|
|
184
|
-
for line_num, line in enumerate(f):
|
|
185
|
-
data = json_loads(line)
|
|
186
|
-
if data is not None:
|
|
187
|
-
data['_line_num'] = line_num
|
|
188
|
-
messages.append(data)
|
|
189
|
-
return messages
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def planning_file_from_path(path_value: Any) -> Optional[str]:
|
|
193
|
-
if not isinstance(path_value, str):
|
|
194
|
-
return None
|
|
195
|
-
for pf in PLANNING_FILES:
|
|
196
|
-
if path_value.endswith(pf):
|
|
197
|
-
return pf
|
|
198
|
-
return None
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def planning_file_from_paths(paths: Iterable[Any]) -> Optional[str]:
|
|
202
|
-
matches = {pf for path in paths if (pf := planning_file_from_path(path))}
|
|
203
|
-
for pf in PLANNING_FILES:
|
|
204
|
-
if pf in matches:
|
|
205
|
-
return pf
|
|
206
|
-
return None
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def codex_planning_update(payload: Dict[str, Any]) -> Optional[str]:
|
|
210
|
-
"""Use Codex's structured apply_patch result instead of parsing tool text."""
|
|
211
|
-
if payload.get('type') != 'patch_apply_end' or payload.get('success') is not True:
|
|
212
|
-
return None
|
|
213
|
-
changes = payload.get('changes')
|
|
214
|
-
return planning_file_from_paths(changes.keys()) if isinstance(changes, dict) else None
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def find_last_planning_update(messages: List[Dict[str, Any]]) -> Tuple[int, Optional[str]]:
|
|
218
|
-
"""
|
|
219
|
-
Find the last time a planning file was written/edited.
|
|
220
|
-
Returns (line_number, filename) or (-1, None) if not found.
|
|
221
|
-
"""
|
|
222
|
-
last_update_line = -1
|
|
223
|
-
last_update_file = None
|
|
224
|
-
|
|
225
|
-
for msg in messages:
|
|
226
|
-
line_num = msg.get('_line_num')
|
|
227
|
-
if not isinstance(line_num, int):
|
|
228
|
-
continue
|
|
229
|
-
msg_type = msg.get('type')
|
|
230
|
-
|
|
231
|
-
if msg_type == 'assistant':
|
|
232
|
-
content = msg.get('message', {}).get('content', [])
|
|
233
|
-
if isinstance(content, list):
|
|
234
|
-
for item in content:
|
|
235
|
-
if item.get('type') == 'tool_use':
|
|
236
|
-
tool_name = item.get('name', '')
|
|
237
|
-
tool_input = item.get('input', {})
|
|
238
|
-
if not isinstance(tool_input, dict):
|
|
239
|
-
tool_input = {}
|
|
240
|
-
|
|
241
|
-
if tool_name in ('Write', 'Edit'):
|
|
242
|
-
planning_file = planning_file_from_path(tool_input.get('file_path', ''))
|
|
243
|
-
if planning_file:
|
|
244
|
-
last_update_line = line_num
|
|
245
|
-
last_update_file = planning_file
|
|
246
|
-
|
|
247
|
-
elif msg_type == 'event_msg':
|
|
248
|
-
payload = msg.get('payload')
|
|
249
|
-
if isinstance(payload, dict):
|
|
250
|
-
planning_file = codex_planning_update(payload)
|
|
251
|
-
if planning_file:
|
|
252
|
-
last_update_line = line_num
|
|
253
|
-
last_update_file = planning_file
|
|
254
|
-
|
|
255
|
-
return last_update_line, last_update_file
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def text_content(content: Any) -> str:
|
|
259
|
-
if isinstance(content, str):
|
|
260
|
-
return content
|
|
261
|
-
if not isinstance(content, list):
|
|
262
|
-
return ''
|
|
263
|
-
return '\n'.join(
|
|
264
|
-
item.get('text', '')
|
|
265
|
-
for item in content
|
|
266
|
-
if isinstance(item, dict) and isinstance(item.get('text'), str)
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
def parse_codex_tool_args(payload: Dict[str, Any]) -> Tuple[Dict[str, Any], str]:
|
|
271
|
-
raw_args = payload.get('arguments', payload.get('input', ''))
|
|
272
|
-
if isinstance(raw_args, dict):
|
|
273
|
-
return raw_args, json.dumps(raw_args, ensure_ascii=True)
|
|
274
|
-
if not isinstance(raw_args, str):
|
|
275
|
-
return {}, ''
|
|
276
|
-
decoded = json_loads(raw_args)
|
|
277
|
-
return (decoded, raw_args) if isinstance(decoded, dict) else ({}, raw_args)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def summarize_codex_tool(payload: Dict[str, Any]) -> str:
|
|
281
|
-
tool_name = payload.get('name', 'tool')
|
|
282
|
-
tool_args, raw_args = parse_codex_tool_args(payload)
|
|
283
|
-
if tool_name == 'exec_command':
|
|
284
|
-
command = tool_args.get('cmd', raw_args)
|
|
285
|
-
if isinstance(command, str):
|
|
286
|
-
return f"exec_command: {command[:80]}"
|
|
287
|
-
return str(tool_name)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
def extract_messages_after(messages: List[Dict[str, Any]], after_line: int) -> List[Dict[str, Any]]:
|
|
291
|
-
"""Extract conversation messages after a certain line number."""
|
|
292
|
-
result = []
|
|
293
|
-
for msg in messages:
|
|
294
|
-
line_num = msg.get('_line_num')
|
|
295
|
-
if not isinstance(line_num, int) or line_num <= after_line:
|
|
296
|
-
continue
|
|
297
|
-
|
|
298
|
-
msg_type = msg.get('type')
|
|
299
|
-
is_meta = msg.get('isMeta', False)
|
|
300
|
-
|
|
301
|
-
if msg_type == 'user' and not is_meta:
|
|
302
|
-
content = text_content(msg.get('message', {}).get('content', ''))
|
|
303
|
-
|
|
304
|
-
if content:
|
|
305
|
-
if content.startswith(('<local-command', '<command-', '<task-notification')):
|
|
306
|
-
continue
|
|
307
|
-
if len(content) > 20:
|
|
308
|
-
result.append({'role': 'user', 'content': content, 'line': line_num})
|
|
309
|
-
|
|
310
|
-
elif msg_type == 'assistant':
|
|
311
|
-
msg_content = msg.get('message', {}).get('content', '')
|
|
312
|
-
text = text_content(msg_content)
|
|
313
|
-
tool_uses = []
|
|
314
|
-
|
|
315
|
-
if isinstance(msg_content, list):
|
|
316
|
-
for item in msg_content:
|
|
317
|
-
if isinstance(item, dict) and item.get('type') == 'tool_use':
|
|
318
|
-
tool_name = item.get('name', '')
|
|
319
|
-
tool_input = item.get('input', {})
|
|
320
|
-
if not isinstance(tool_input, dict):
|
|
321
|
-
tool_input = {}
|
|
322
|
-
if tool_name == 'Edit':
|
|
323
|
-
tool_uses.append(f"Edit: {tool_input.get('file_path', 'unknown')}")
|
|
324
|
-
elif tool_name == 'Write':
|
|
325
|
-
tool_uses.append(f"Write: {tool_input.get('file_path', 'unknown')}")
|
|
326
|
-
elif tool_name == 'Bash':
|
|
327
|
-
cmd = tool_input.get('command', '')[:80]
|
|
328
|
-
tool_uses.append(f"Bash: {cmd}")
|
|
329
|
-
else:
|
|
330
|
-
tool_uses.append(f"{tool_name}")
|
|
331
|
-
|
|
332
|
-
if text or tool_uses:
|
|
333
|
-
result.append({
|
|
334
|
-
'role': 'assistant',
|
|
335
|
-
'content': text[:600] if text else '',
|
|
336
|
-
'tools': tool_uses,
|
|
337
|
-
'line': line_num
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
elif msg_type == 'response_item':
|
|
341
|
-
payload = msg.get('payload')
|
|
342
|
-
if not isinstance(payload, dict):
|
|
343
|
-
continue
|
|
344
|
-
|
|
345
|
-
payload_type = payload.get('type')
|
|
346
|
-
if payload_type == 'message':
|
|
347
|
-
role = payload.get('role')
|
|
348
|
-
if role not in ('user', 'assistant'):
|
|
349
|
-
continue
|
|
350
|
-
content = text_content(payload.get('content'))
|
|
351
|
-
if role == 'user':
|
|
352
|
-
if content.startswith(('<local-command', '<command-', '<task-notification')):
|
|
353
|
-
continue
|
|
354
|
-
if len(content) > 20:
|
|
355
|
-
result.append({'role': 'user', 'content': content, 'line': line_num})
|
|
356
|
-
elif content:
|
|
357
|
-
result.append({
|
|
358
|
-
'role': 'assistant',
|
|
359
|
-
'content': content[:600],
|
|
360
|
-
'tools': [],
|
|
361
|
-
'line': line_num
|
|
362
|
-
})
|
|
363
|
-
elif payload_type in ('function_call', 'custom_tool_call'):
|
|
364
|
-
result.append({
|
|
365
|
-
'role': 'assistant',
|
|
366
|
-
'content': '',
|
|
367
|
-
'tools': [summarize_codex_tool(payload)],
|
|
368
|
-
'line': line_num
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
return result
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
def main():
|
|
375
|
-
project_path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
|
|
376
|
-
|
|
377
|
-
# Check if planning files exist (indicates active task)
|
|
378
|
-
has_planning_files = any(
|
|
379
|
-
Path(project_path, f).exists() for f in PLANNING_FILES
|
|
380
|
-
)
|
|
381
|
-
if not has_planning_files:
|
|
382
|
-
# No planning files in this project; skip catchup to avoid noise.
|
|
383
|
-
return
|
|
384
|
-
|
|
385
|
-
runtime_name, sessions = get_session_candidates(project_path)
|
|
386
|
-
|
|
387
|
-
# Find a substantial previous session
|
|
388
|
-
target_session = None
|
|
389
|
-
for session in sessions:
|
|
390
|
-
if runtime_name == 'claude' and not is_substantial_session(session):
|
|
391
|
-
continue
|
|
392
|
-
target_session = session
|
|
393
|
-
break
|
|
394
|
-
|
|
395
|
-
if not target_session:
|
|
396
|
-
return
|
|
397
|
-
|
|
398
|
-
messages = parse_session_messages(target_session)
|
|
399
|
-
last_update_line, last_update_file = find_last_planning_update(messages)
|
|
400
|
-
|
|
401
|
-
# No planning updates in the target session; skip catchup output.
|
|
402
|
-
if last_update_line < 0:
|
|
403
|
-
return
|
|
404
|
-
|
|
405
|
-
# Only output if there's unsynced content
|
|
406
|
-
messages_after = extract_messages_after(messages, last_update_line)
|
|
407
|
-
|
|
408
|
-
if not messages_after:
|
|
409
|
-
return
|
|
410
|
-
|
|
411
|
-
# Output catchup report
|
|
412
|
-
print("\n[planning-with-files] 检测到会话恢复")
|
|
413
|
-
print(f"上一个会话:{target_session.stem}")
|
|
414
|
-
print(f"运行环境:{runtime_name}")
|
|
415
|
-
|
|
416
|
-
print(f"最后规划更新:{last_update_file} at message #{last_update_line}")
|
|
417
|
-
print(f"未同步消息:{len(messages_after)}")
|
|
418
|
-
|
|
419
|
-
print("\n--- 未同步的上下文 ---")
|
|
420
|
-
assistant_label = 'CODEX' if runtime_name == 'codex' else 'CLAUDE'
|
|
421
|
-
for msg in messages_after[-15:]:
|
|
422
|
-
if msg['role'] == 'user':
|
|
423
|
-
print(f"用户:{msg['content'][:300]}")
|
|
424
|
-
else:
|
|
425
|
-
if msg.get('content'):
|
|
426
|
-
print(f"{assistant_label}: {msg['content'][:300]}")
|
|
427
|
-
if msg.get('tools'):
|
|
428
|
-
print(f" 工具:{', '.join(msg['tools'][:4])}")
|
|
429
|
-
|
|
430
|
-
print("\n--- 建议 ---")
|
|
431
|
-
print("1. 运行:git diff --stat")
|
|
432
|
-
print("2. 读取:task_plan.md、progress.md、findings.md")
|
|
433
|
-
print("3. 根据上述上下文更新规划文件")
|
|
434
|
-
print("4. 继续执行任务")
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if __name__ == '__main__':
|
|
438
|
-
main()
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# 发现与决策
|
|
2
|
-
|
|
3
|
-
## 需求
|
|
4
|
-
-
|
|
5
|
-
|
|
6
|
-
## 研究发现
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
## 技术决策
|
|
10
|
-
| 决策 | 理由 |
|
|
11
|
-
|------|------|
|
|
12
|
-
| | |
|
|
13
|
-
|
|
14
|
-
## 遇到的问题
|
|
15
|
-
| 问题 | 解决方案 |
|
|
16
|
-
|------|---------|
|
|
17
|
-
| | |
|
|
18
|
-
|
|
19
|
-
## 资源
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
## 视觉/浏览器发现
|
|
23
|
-
<!-- 关键:每执行2次查看/浏览器操作后必须更新此部分 -->
|
|
24
|
-
<!-- 多模态内容必须立即以文本形式记录 -->
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
*每执行2次查看/浏览器/搜索操作后更新此文件*
|
|
29
|
-
*防止视觉信息丢失*
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# 进度日志
|
|
2
|
-
|
|
3
|
-
## 会话:[日期]
|
|
4
|
-
|
|
5
|
-
### 阶段 1:[标题]
|
|
6
|
-
- **状态:** in_progress
|
|
7
|
-
- **开始时间:** [时间戳]
|
|
8
|
-
- 执行的操作:
|
|
9
|
-
-
|
|
10
|
-
- 创建/修改的文件:
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
### 阶段 2:[标题]
|
|
14
|
-
- **状态:** pending
|
|
15
|
-
- 执行的操作:
|
|
16
|
-
-
|
|
17
|
-
- 创建/修改的文件:
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
## 测试结果
|
|
21
|
-
| 测试 | 输入 | 预期结果 | 实际结果 | 状态 |
|
|
22
|
-
|------|------|---------|---------|------|
|
|
23
|
-
| | | | | |
|
|
24
|
-
|
|
25
|
-
## 错误日志
|
|
26
|
-
| 时间戳 | 错误 | 尝试次数 | 解决方案 |
|
|
27
|
-
|--------|------|---------|---------|
|
|
28
|
-
| | | 1 | |
|
|
29
|
-
|
|
30
|
-
## 五问重启检查
|
|
31
|
-
| 问题 | 答案 |
|
|
32
|
-
|------|------|
|
|
33
|
-
| 我在哪里? | 阶段 X |
|
|
34
|
-
| 我要去哪里? | 剩余阶段 |
|
|
35
|
-
| 目标是什么? | [目标声明] |
|
|
36
|
-
| 我学到了什么? | 见 findings.md |
|
|
37
|
-
| 我做了什么? | 见上方记录 |
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
*每个阶段完成后或遇到错误时更新此文件*
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# 任务计划:[简要描述]
|
|
2
|
-
|
|
3
|
-
## 目标
|
|
4
|
-
[用一句话描述最终状态]
|
|
5
|
-
|
|
6
|
-
## 当前阶段
|
|
7
|
-
阶段 1
|
|
8
|
-
|
|
9
|
-
## 各阶段
|
|
10
|
-
|
|
11
|
-
### 阶段 1:需求与发现
|
|
12
|
-
- [ ] 理解用户意图
|
|
13
|
-
- [ ] 确定约束条件和需求
|
|
14
|
-
- [ ] 将发现记录到 findings.md
|
|
15
|
-
- **状态:** in_progress
|
|
16
|
-
|
|
17
|
-
### 阶段 2:规划与结构
|
|
18
|
-
- [ ] 确定技术方案
|
|
19
|
-
- [ ] 如有需要创建项目结构
|
|
20
|
-
- [ ] 记录决策及理由
|
|
21
|
-
- **状态:** pending
|
|
22
|
-
|
|
23
|
-
### 阶段 3:实现
|
|
24
|
-
- [ ] 按计划逐步执行
|
|
25
|
-
- [ ] 先将代码写入文件再执行
|
|
26
|
-
- [ ] 增量测试
|
|
27
|
-
- **状态:** pending
|
|
28
|
-
|
|
29
|
-
### 阶段 4:测试与验证
|
|
30
|
-
- [ ] 验证所有需求已满足
|
|
31
|
-
- [ ] 将测试结果记录到 progress.md
|
|
32
|
-
- [ ] 修复发现的问题
|
|
33
|
-
- **状态:** pending
|
|
34
|
-
|
|
35
|
-
### 阶段 5:交付
|
|
36
|
-
- [ ] 检查所有输出文件
|
|
37
|
-
- [ ] 确保交付物完整
|
|
38
|
-
- [ ] 交付给用户
|
|
39
|
-
- **状态:** pending
|
|
40
|
-
|
|
41
|
-
## 关键问题
|
|
42
|
-
1. [待回答的问题]
|
|
43
|
-
2. [待回答的问题]
|
|
44
|
-
|
|
45
|
-
## 已做决策
|
|
46
|
-
| 决策 | 理由 |
|
|
47
|
-
|------|------|
|
|
48
|
-
| | |
|
|
49
|
-
|
|
50
|
-
## 遇到的错误
|
|
51
|
-
| 错误 | 尝试次数 | 解决方案 |
|
|
52
|
-
|------|---------|---------|
|
|
53
|
-
| | 1 | |
|
|
54
|
-
|
|
55
|
-
## 备注
|
|
56
|
-
- 随着进度更新阶段状态:pending → in_progress → complete
|
|
57
|
-
- 做重大决策前重新读取此计划(注意力操纵)
|
|
58
|
-
- 记录所有错误,避免重复
|