trybeacon 0.1.66 → 0.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/app-path-routes-manifest.json +8 -8
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +11 -11
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +11 -11
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  24. package/.next/server/app/api/lesson/close/route.js +1 -1
  25. package/.next/server/app/api/lesson/questions/route.js +1 -1
  26. package/.next/server/app/api/lesson/route.js +1 -1
  27. package/.next/server/app/api/lesson/save/route.js +1 -1
  28. package/.next/server/app/api/lesson/verdict/route.js +1 -1
  29. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  30. package/.next/server/app/docs.html +1 -1
  31. package/.next/server/app/docs.rsc +11 -11
  32. package/.next/server/app/docs.segments/_full.segment.rsc +11 -11
  33. package/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  34. package/.next/server/app/docs.segments/_index.segment.rsc +11 -11
  35. package/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
  36. package/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  37. package/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  38. package/.next/server/app/feedback/page_client-reference-manifest.js +1 -1
  39. package/.next/server/app/feedback.html +1 -1
  40. package/.next/server/app/feedback.rsc +11 -11
  41. package/.next/server/app/feedback.segments/_full.segment.rsc +11 -11
  42. package/.next/server/app/feedback.segments/_head.segment.rsc +1 -1
  43. package/.next/server/app/feedback.segments/_index.segment.rsc +11 -11
  44. package/.next/server/app/feedback.segments/_tree.segment.rsc +2 -2
  45. package/.next/server/app/feedback.segments/feedback/__PAGE__.segment.rsc +1 -1
  46. package/.next/server/app/feedback.segments/feedback.segment.rsc +1 -1
  47. package/.next/server/app/help/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/help.html +1 -1
  49. package/.next/server/app/help.rsc +11 -11
  50. package/.next/server/app/help.segments/_full.segment.rsc +11 -11
  51. package/.next/server/app/help.segments/_head.segment.rsc +1 -1
  52. package/.next/server/app/help.segments/_index.segment.rsc +11 -11
  53. package/.next/server/app/help.segments/_tree.segment.rsc +2 -2
  54. package/.next/server/app/help.segments/help/__PAGE__.segment.rsc +1 -1
  55. package/.next/server/app/help.segments/help.segment.rsc +1 -1
  56. package/.next/server/app/index.html +1 -1
  57. package/.next/server/app/index.rsc +12 -12
  58. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  59. package/.next/server/app/index.segments/_full.segment.rsc +12 -12
  60. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  61. package/.next/server/app/index.segments/_index.segment.rsc +11 -11
  62. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  63. package/.next/server/app/learn/page.js +5 -3
  64. package/.next/server/app/learn/page.js.nft.json +1 -1
  65. package/.next/server/app/learn/page_client-reference-manifest.js +1 -1
  66. package/.next/server/app/map/page.js +2 -2
  67. package/.next/server/app/map/page.js.nft.json +1 -1
  68. package/.next/server/app/map/page_client-reference-manifest.js +1 -1
  69. package/.next/server/app/page.js +2 -2
  70. package/.next/server/app/page.js.nft.json +1 -1
  71. package/.next/server/app/page_client-reference-manifest.js +1 -1
  72. package/.next/server/app/plan/page.js +2 -2
  73. package/.next/server/app/plan/page.js.nft.json +1 -1
  74. package/.next/server/app/plan/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/s/[token]/page.js +2 -2
  76. package/.next/server/app/s/[token]/page.js.nft.json +1 -1
  77. package/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
  78. package/.next/server/app/settings/page.js +1 -1
  79. package/.next/server/app/settings/page.js.nft.json +1 -1
  80. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  81. package/.next/server/app-paths-manifest.json +8 -8
  82. package/.next/server/chunks/2025.js +1 -0
  83. package/.next/server/chunks/2994.js +2 -0
  84. package/.next/server/chunks/4046.js +3 -3
  85. package/.next/server/chunks/5683.js +1 -0
  86. package/.next/server/chunks/5719.js +1 -0
  87. package/.next/server/chunks/7720.js +154 -0
  88. package/.next/server/middleware-build-manifest.js +1 -1
  89. package/.next/server/pages/404.html +1 -1
  90. package/.next/server/pages/500.html +1 -1
  91. package/.next/server/server-reference-manifest.js +1 -1
  92. package/.next/server/server-reference-manifest.json +1 -1
  93. package/.next/static/chunks/1276-b84f61ec9c0df862.js +1 -0
  94. package/.next/static/chunks/1a258343-954e0e6619585d3c.js +2 -0
  95. package/.next/static/chunks/2059-fba06ba63ba64522.js +62 -0
  96. package/.next/static/chunks/4607-a668ea431c41e60e.js +1 -0
  97. package/.next/static/chunks/4853-6dc402b4ce452fa5.js +1 -0
  98. package/.next/static/chunks/{7043-254590cf9891391f.js → 4888-911c0da3c2d785d2.js} +1 -1
  99. package/.next/static/chunks/5957-83f611fcd5a08b45.js +1 -0
  100. package/.next/static/chunks/766-242213d211df0afd.js +1 -0
  101. package/.next/static/chunks/8997-78a359d0d238622e.js +1 -0
  102. package/.next/static/chunks/app/{layout-0c993f55d3a798f4.js → layout-9f0f4d8e4534a62e.js} +1 -1
  103. package/.next/static/chunks/app/learn/page-03acad0a37068966.js +7 -0
  104. package/.next/static/chunks/app/map/page-5cfad64d5feea695.js +1 -0
  105. package/.next/static/chunks/app/page-d08947a671077569.js +1 -0
  106. package/.next/static/chunks/app/plan/page-5eacb6b83bd4873d.js +1 -0
  107. package/.next/static/chunks/app/s/[token]/page-1a350cf50a45500c.js +1 -0
  108. package/.next/static/chunks/app/settings/page-7e176d120b1effa9.js +1 -0
  109. package/.next/static/css/63986592e2be7d62.css +1 -0
  110. package/.next/trace +43 -43
  111. package/.next/trace-build +1 -1
  112. package/dist/bin/beacon.js +14 -12
  113. package/dist/bin/doctor.js +22 -15
  114. package/dist/bin/hook.js +18 -11
  115. package/dist/bin/mcp.js +41 -34
  116. package/dist/bin/plan.js +21 -14
  117. package/dist/bin/uninstall.js +26 -19
  118. package/dist/lib/assets.js +7 -0
  119. package/dist/lib/codex-install.js +28 -21
  120. package/dist/lib/global-install.js +27 -20
  121. package/package.json +1 -1
  122. package/plugin/skills/beacon-explain/SKILL.md +7 -0
  123. package/.next/server/chunks/3584.js +0 -154
  124. package/.next/server/chunks/6024.js +0 -2
  125. package/.next/server/chunks/7187.js +0 -1
  126. package/.next/server/chunks/8035.js +0 -1
  127. package/.next/static/chunks/1936-7fea5225b5bfcfda.js +0 -1
  128. package/.next/static/chunks/1a258343-6baccd9e573fdfaf.js +0 -2
  129. package/.next/static/chunks/2019-3be80edc82176878.js +0 -1
  130. package/.next/static/chunks/3845-6fe7e66d4bf82eb5.js +0 -1
  131. package/.next/static/chunks/4549-591415d55ca009a3.js +0 -62
  132. package/.next/static/chunks/6638-4e53879181b1df75.js +0 -1
  133. package/.next/static/chunks/7643-6c7ff4b9400f68fc.js +0 -1
  134. package/.next/static/chunks/app/learn/page-797d74e02b98fa88.js +0 -5
  135. package/.next/static/chunks/app/map/page-634b6d5d98e921b3.js +0 -1
  136. package/.next/static/chunks/app/page-84dc684d45002cfb.js +0 -1
  137. package/.next/static/chunks/app/plan/page-df829b2054c40611.js +0 -1
  138. package/.next/static/chunks/app/s/[token]/page-f97dec75856a7952.js +0 -1
  139. package/.next/static/chunks/app/settings/page-59d90685cd17fc1f.js +0 -1
  140. package/.next/static/css/b3d3212da726bbfb.css +0 -1
  141. /package/.next/static/{P3uXQySdS-m6_bxuiezYe → hkOIw5DQW9WSwBwZrD8_9}/_buildManifest.js +0 -0
  142. /package/.next/static/{P3uXQySdS-m6_bxuiezYe → hkOIw5DQW9WSwBwZrD8_9}/_ssgManifest.js +0 -0
@@ -1,21 +1,21 @@
1
1
  // @bun
2
- var bq=Object.defineProperty;var wq=(q)=>q;function gq(q,z){this[q]=wq.bind(null,z)}var d=(q,z)=>{for(var J in z)bq(q,J,{get:z[J],enumerable:!0,configurable:!0,set:gq.bind(z,J)})};var x=(q,z)=>()=>(q&&(z=q(q=0)),z);var tq=1500,nq=480000,rq=1800000,C=3600000,oq=3000;var c=()=>{};var o={};d(o,{removeRepoAssets:()=>Aq,installRefreshSkill:()=>Cq,installPlanSkill:()=>Kq,installInitSkill:()=>jq,installExplainSkill:()=>Nq,installCodexRepoSkills:()=>Rq,ensureWorkflowDoc:()=>fq,ensureMcp:()=>Dq,auditRepo:()=>Tq,REFRESH_SKILL:()=>L,PLAN_SKILL:()=>n,INIT_SKILL:()=>O,EXPLAIN_SKILL:()=>r});import{existsSync as G,mkdirSync as u,readFileSync as B,rmSync as K,writeFileSync as H}from"fs";import{join as Z}from"path";function jq(q){let z=Z(q,".claude","skills","beacon-init");u(z,{recursive:!0});let J=Z(z,"SKILL.md");return H(J,O),J}function Cq(q){let z=Z(q,".claude","skills","beacon-refresh");u(z,{recursive:!0});let J=Z(z,"SKILL.md");return H(J,L),J}function Kq(q){let z=Z(q,".claude","skills","beacon-plan");u(z,{recursive:!0});let J=Z(z,"SKILL.md");return H(J,n),J}function Nq(q){let z=Z(q,".claude","skills","beacon-explain");u(z,{recursive:!0});let J=Z(z,"SKILL.md");return H(J,r),J}function Rq(q){let z=[];for(let J of Mq){let Q=Z(q,".agents","skills",J.name);u(Q,{recursive:!0});let V=Z(Q,"SKILL.md");H(V,J.body()),z.push(V)}return z}function fq(q){let z=Z(q,"AGENTS.md"),J="";try{J=B(z,"utf8")}catch{}let Q=new RegExp(`${N}[\\s\\S]*?${y}`);J=Q.test(J)?J.replace(Q,t):`${J.trim()}
2
+ var bq=Object.defineProperty;var wq=(q)=>q;function gq(q,J){this[q]=wq.bind(null,J)}var d=(q,J)=>{for(var z in J)bq(q,z,{get:J[z],enumerable:!0,configurable:!0,set:gq.bind(J,z)})};var u=(q,J)=>()=>(q&&(J=q(q=0)),J);var tq=1500,nq=480000,rq=1800000,C=3600000,oq=3000;var c=()=>{};var o={};d(o,{removeRepoAssets:()=>Aq,installRefreshSkill:()=>Cq,installPlanSkill:()=>Kq,installInitSkill:()=>jq,installExplainSkill:()=>Nq,installCodexRepoSkills:()=>Rq,ensureWorkflowDoc:()=>fq,ensureMcp:()=>Dq,auditRepo:()=>Tq,REFRESH_SKILL:()=>L,PLAN_SKILL:()=>n,INIT_SKILL:()=>O,EXPLAIN_SKILL:()=>r});import{existsSync as G,mkdirSync as b,readFileSync as B,rmSync as K,writeFileSync as H}from"fs";import{join as Z}from"path";function jq(q){let J=Z(q,".claude","skills","beacon-init");b(J,{recursive:!0});let z=Z(J,"SKILL.md");return H(z,O),z}function Cq(q){let J=Z(q,".claude","skills","beacon-refresh");b(J,{recursive:!0});let z=Z(J,"SKILL.md");return H(z,L),z}function Kq(q){let J=Z(q,".claude","skills","beacon-plan");b(J,{recursive:!0});let z=Z(J,"SKILL.md");return H(z,n),z}function Nq(q){let J=Z(q,".claude","skills","beacon-explain");b(J,{recursive:!0});let z=Z(J,"SKILL.md");return H(z,r),z}function Rq(q){let J=[];for(let z of Mq){let Q=Z(q,".agents","skills",z.name);b(Q,{recursive:!0});let V=Z(Q,"SKILL.md");H(V,z.body()),J.push(V)}return J}function fq(q){let J=Z(q,"AGENTS.md"),z="";try{z=B(J,"utf8")}catch{}let Q=new RegExp(`${N}[\\s\\S]*?${y}`);z=Q.test(z)?z.replace(Q,t):`${z.trim()}
3
3
 
4
4
  ${t}
5
- `.trimStart(),H(z,J.endsWith(`
6
- `)?J:`${J}
5
+ `.trimStart(),H(J,z.endsWith(`
6
+ `)?z:`${z}
7
7
  `);let V=Z(q,"CLAUDE.md"),Y="";try{Y=B(V,"utf8")}catch{}if(!/@AGENTS\.md/.test(Y))H(V,`${Y?`${Y.trim()}
8
8
 
9
9
  `:""}@AGENTS.md
10
- `)}function Dq(q){let z=Z(q,".mcp.json"),J={};try{J=JSON.parse(B(z,"utf8"))}catch{}J.mcpServers=J.mcpServers??{};let Q=J.mcpServers.beacon;if(Q){if(!Q.timeout||Q.timeout<C)return Q.timeout=C,H(z,JSON.stringify(J,null,2)+`
11
- `),{path:z,added:!1,updated:!0};return{path:z,added:!1,updated:!1}}return J.mcpServers.beacon={command:"beacon",args:["mcp"],timeout:C},H(z,JSON.stringify(J,null,2)+`
12
- `),{path:z,added:!0,updated:!1}}function Tq(q){let z=Z(q,".mcp.json"),J=!1;try{J=!!JSON.parse(B(z,"utf8")).mcpServers?.beacon}catch{}let Q=!1;try{Q=B(Z(q,"AGENTS.md"),"utf8").includes(N)}catch{}let V=!1;try{V=/@AGENTS\.md/.test(B(Z(q,"CLAUDE.md"),"utf8"))}catch{}return{repo:q,mcpRegistered:J,agentsMdBlock:Q,claudeMdImport:V,skills:{"beacon-init":G(Z(q,".claude","skills","beacon-init","SKILL.md")),"beacon-refresh":G(Z(q,".claude","skills","beacon-refresh","SKILL.md"))},codexSkills:{"beacon-init":G(Z(q,".agents","skills","beacon-init","SKILL.md")),"beacon-refresh":G(Z(q,".agents","skills","beacon-refresh","SKILL.md"))}}}function Aq(q){let z=[];for(let $ of["beacon-init","beacon-refresh","beacon-db-design"]){let U=Z(q,".claude","skills",$);if(G(U))K(U,{recursive:!0,force:!0}),z.push($)}for(let $ of["beacon-init","beacon-refresh"]){let U=Z(q,".agents","skills",$);if(G(U))K(U,{recursive:!0,force:!0}),z.push(`codex:${$}`)}let J=!1,Q=Z(q,".mcp.json");try{let $=JSON.parse(B(Q,"utf8"));if($.mcpServers?.beacon){if(delete $.mcpServers.beacon,J=!0,$.mcpServers&&Object.keys($.mcpServers).length===0)delete $.mcpServers;if(Object.keys($).length===0)K(Q,{force:!0});else H(Q,JSON.stringify($,null,2)+`
13
- `)}}catch{}let V=!1,Y=Z(q,"AGENTS.md");try{let $=B(Y,"utf8"),U=new RegExp(`\\n?${N}[\\s\\S]*?${y}\\n?`);if(U.test($)){let E=$.replace(U,`
10
+ `)}function Dq(q){let J=Z(q,".mcp.json"),z={};try{z=JSON.parse(B(J,"utf8"))}catch{}z.mcpServers=z.mcpServers??{};let Q=z.mcpServers.beacon;if(Q){if(!Q.timeout||Q.timeout<C)return Q.timeout=C,H(J,JSON.stringify(z,null,2)+`
11
+ `),{path:J,added:!1,updated:!0};return{path:J,added:!1,updated:!1}}return z.mcpServers.beacon={command:"beacon",args:["mcp"],timeout:C},H(J,JSON.stringify(z,null,2)+`
12
+ `),{path:J,added:!0,updated:!1}}function Tq(q){let J=Z(q,".mcp.json"),z=!1;try{z=!!JSON.parse(B(J,"utf8")).mcpServers?.beacon}catch{}let Q=!1;try{Q=B(Z(q,"AGENTS.md"),"utf8").includes(N)}catch{}let V=!1;try{V=/@AGENTS\.md/.test(B(Z(q,"CLAUDE.md"),"utf8"))}catch{}return{repo:q,mcpRegistered:z,agentsMdBlock:Q,claudeMdImport:V,skills:{"beacon-init":G(Z(q,".claude","skills","beacon-init","SKILL.md")),"beacon-refresh":G(Z(q,".claude","skills","beacon-refresh","SKILL.md"))},codexSkills:{"beacon-init":G(Z(q,".agents","skills","beacon-init","SKILL.md")),"beacon-refresh":G(Z(q,".agents","skills","beacon-refresh","SKILL.md"))}}}function Aq(q){let J=[];for(let $ of["beacon-init","beacon-refresh","beacon-db-design"]){let U=Z(q,".claude","skills",$);if(G(U))K(U,{recursive:!0,force:!0}),J.push($)}for(let $ of["beacon-init","beacon-refresh"]){let U=Z(q,".agents","skills",$);if(G(U))K(U,{recursive:!0,force:!0}),J.push(`codex:${$}`)}let z=!1,Q=Z(q,".mcp.json");try{let $=JSON.parse(B(Q,"utf8"));if($.mcpServers?.beacon){if(delete $.mcpServers.beacon,z=!0,$.mcpServers&&Object.keys($.mcpServers).length===0)delete $.mcpServers;if(Object.keys($).length===0)K(Q,{force:!0});else H(Q,JSON.stringify($,null,2)+`
13
+ `)}}catch{}let V=!1,Y=Z(q,"AGENTS.md");try{let $=B(Y,"utf8"),U=new RegExp(`\\n?${N}[\\s\\S]*?${y}\\n?`);if(U.test($)){let k=$.replace(U,`
14
14
  `).replace(/\n{3,}/g,`
15
15
 
16
- `).trimStart();H(Y,E.endsWith(`
17
- `)?E:`${E}
18
- `),V=!0}}catch{}let W=!1,P=Z(q,"CLAUDE.md");try{let $=B(P,"utf8"),U=$.replace(/^[ \t]*@AGENTS\.md[ \t]*\n?/m,"");if(U!==$){if(!U.trim())K(P,{force:!0});else H(P,U);W=!0}}catch{}return{skillsRemoved:z,mcpUnregistered:J,agentsBlockRemoved:V,claudeImportRemoved:W}}var O=`---
16
+ `).trimStart();H(Y,k.endsWith(`
17
+ `)?k:`${k}
18
+ `),V=!0}}catch{}let W=!1,P=Z(q,"CLAUDE.md");try{let $=B(P,"utf8"),U=$.replace(/^[ \t]*@AGENTS\.md[ \t]*\n?/m,"");if(U!==$){if(!U.trim())K(P,{force:!0});else H(P,U);W=!0}}catch{}return{skillsRemoved:J,mcpUnregistered:z,agentsBlockRemoved:V,claudeImportRemoved:W}}var O=`---
19
19
  name: beacon-init
20
20
  description: Read this repository and map its architecture, schema, and roadmap into Beacon (the local visual planning panel). Use when the user runs /beacon-init, asks to "set up Beacon for this repo", or asks to initialize/bootstrap Beacon's map of this codebase.
21
21
  ---
@@ -213,6 +213,13 @@ push depth into \`detail\`, not the node face. Supply \`steps\` for the guided w
213
213
  is the overview (empty \`focusIds\`), then teach one node (or a few) per step in order, each with its
214
214
  \`focusIds\`.
215
215
 
216
+ When the topic involves DATABASE tables, pass them in \`tables\` (they render as annotated schema cards
217
+ on the SAME board, not just raw schemas). For each table give a one-line \`note\` (why it exists), mark
218
+ the key columns \`isPk\`, point FKs at another table with \`fkTo: "<that table's id>"\`, give EVERY column a
219
+ short plain-English \`note\`, and add a \`sample\` row or two (the worked example, made concrete). Connect a
220
+ concept to its table with an \`edge\` (e.g. \`persists to\` / \`reads from\`) whose \`toId\` is the table's id \u2014
221
+ so the learner sees the table IN CONTEXT, wired to the code that uses it.
222
+
216
223
  ## 4. Answer in the loop \u2014 don't stop after one round
217
224
 
218
225
  \`beacon_explain\` returns the user's questions, each tagged \`[q:ID]\`. Answer EACH by calling
@@ -220,7 +227,7 @@ is the overview (empty \`focusIds\`), then teach one node (or a few) per step in
220
227
  Every answer must ADD understanding (rationale, trade-off) \u2014 never just restate the question. Expand
221
228
  the narrative or add nodes where it helps. Keep looping until the tool reports the user saved or closed
222
229
  the lesson.
223
- `,Mq,N="<!-- beacon:workflow:start -->",y="<!-- beacon:workflow:end -->",t;var i=x(()=>{c();Mq=[{name:"beacon-init",body:()=>O},{name:"beacon-refresh",body:()=>L}];t=`${N}
230
+ `,Mq,N="<!-- beacon:workflow:start -->",y="<!-- beacon:workflow:end -->",t;var i=u(()=>{c();Mq=[{name:"beacon-init",body:()=>O},{name:"beacon-refresh",body:()=>L}];t=`${N}
224
231
  ## Beacon \u2014 feature workflow
225
232
 
226
233
  This project uses Beacon (a local planning/visualization panel; run \`beacon\` to open it). When you start work on a FEATURE \u2014 whether referenced via an \`@beacon:feature://\u2026\` mention, an \`@beacon:note://\u2026\` note the user wrote in the Notes panel (treat its checkbox \`- [ ]\` todos as subtasks and order features by their dependencies), or just described in chat \u2014 follow these steps in order:
@@ -292,18 +299,18 @@ Register them all in that single batched call. If a plan added five features, th
292
299
  If the feature added or materially changed a REAL architectural component (a subsystem \u2014 NOT a file), also pass \`architecture: [{ title, domain, role, \u2026 }]\` so the Architecture map stays accurate. It upserts curated components by title; never list files as components. If you found a bug or something worth investigating in a component's code, add \`bugs: [{ note }]\` to its architecture entry \u2014 it renders as a bug flag on the node (attributed to the agent); identical open flags are not duplicated. Only flag what you actually saw in the code.
293
300
 
294
301
  Pull raw planning data anytime with \`beacon_entities\` (features / architecture / tables / endpoints).
295
- ${y}`});import{existsSync as M,mkdirSync as h,readdirSync as Iq,readFileSync as b,rmSync as kq,writeFileSync as R}from"fs";import{dirname as e,join as v}from"path";function Vz(){return!!process.env.CLAUDE_PLUGIN_ROOT}function Fq(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;let z=v(q,".claude","plugins");if(!M(z))return null;let J=[z];for(let Q=0;Q<3&&J.length;Q++){let V=[];for(let Y of J){let W=v(Y,".claude-plugin","plugin.json");try{if(M(W)&&JSON.parse(b(W,"utf8")).name==="beacon")return Y}catch{}try{for(let P of Iq(Y,{withFileTypes:!0}))if(P.isDirectory())V.push(v(Y,P.name))}catch{}}J=V}return null}function Yz(q){return Fq(q)!==null}function _(q){try{return JSON.parse(b(q,"utf8"))}catch{return{}}}function zq(q,z){h(e(q),{recursive:!0}),R(q,JSON.stringify(z,null,2)+`
296
- `)}function Jq(q,z){let J=_(q);J.hooks=J.hooks??{},J.hooks[z.event]=J.hooks[z.event]??[];let Q=J.hooks[z.event];if(Q.some((Y)=>Y.matcher===z.matcher&&Y.hooks?.some((W)=>W.command===z.command)))return!1;return Q.push({matcher:z.matcher,hooks:[{type:"command",command:z.command}]}),zq(q,J),!0}function Qq(q,z){return(_(q).hooks?.[z.event]??[]).some((V)=>V.hooks?.some((Y)=>Y.command===z.command))}function Vq(q,z){let J=_(q),Q=J.hooks?.[z.event];if(!Q)return!1;let V=!1,Y=Q.map((W)=>{let P=W.hooks?.length??0,$=(W.hooks??[]).filter((U)=>U.command!==z.command);if($.length!==P)V=!0;return{...W,hooks:$}}).filter((W)=>(W.hooks??[]).length>0);if(!V)return!1;if(Y.length)J.hooks[z.event]=Y;else delete J.hooks[z.event];if(J.hooks&&Object.keys(J.hooks).length===0)delete J.hooks;return zq(q,J),!0}function Yq(q,z,J,Q){let V=`${z}
302
+ ${y}`});import{existsSync as M,mkdirSync as h,readdirSync as Iq,readFileSync as X,rmSync as Fq,writeFileSync as R}from"fs";import{dirname as e,join as v}from"path";function Vz(){return!!process.env.CLAUDE_PLUGIN_ROOT}function Eq(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;let J=v(q,".claude","plugins");if(!M(J))return null;let z=[J];for(let Q=0;Q<3&&z.length;Q++){let V=[];for(let Y of z){let W=v(Y,".claude-plugin","plugin.json");try{if(M(W)&&JSON.parse(X(W,"utf8")).name==="beacon")return Y}catch{}try{for(let P of Iq(Y,{withFileTypes:!0}))if(P.isDirectory())V.push(v(Y,P.name))}catch{}}z=V}return null}function Yz(q){return Eq(q)!==null}function Zz(q){return/[\\/]\.claude[\\/]plugins[\\/]/.test(q)}function $z(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;try{let J=JSON.parse(X(v(q,".claude","plugins","installed_plugins.json"),"utf8"));for(let z of Object.keys(J.plugins??{}))if(/^beacon@/.test(z))return{key:z,marketplace:z.split("@")[1]??""}}catch{}return null}function _(q){try{return JSON.parse(X(q,"utf8"))}catch{return{}}}function zq(q,J){h(e(q),{recursive:!0}),R(q,JSON.stringify(J,null,2)+`
303
+ `)}function Jq(q,J){let z=_(q);z.hooks=z.hooks??{},z.hooks[J.event]=z.hooks[J.event]??[];let Q=z.hooks[J.event];if(Q.some((Y)=>Y.matcher===J.matcher&&Y.hooks?.some((W)=>W.command===J.command)))return!1;return Q.push({matcher:J.matcher,hooks:[{type:"command",command:J.command}]}),zq(q,z),!0}function Qq(q,J){return(_(q).hooks?.[J.event]??[]).some((V)=>V.hooks?.some((Y)=>Y.command===J.command))}function Vq(q,J){let z=_(q),Q=z.hooks?.[J.event];if(!Q)return!1;let V=!1,Y=Q.map((W)=>{let P=W.hooks?.length??0,$=(W.hooks??[]).filter((U)=>U.command!==J.command);if($.length!==P)V=!0;return{...W,hooks:$}}).filter((W)=>(W.hooks??[]).length>0);if(!V)return!1;if(Y.length)z.hooks[J.event]=Y;else delete z.hooks[J.event];if(z.hooks&&Object.keys(z.hooks).length===0)delete z.hooks;return zq(q,z),!0}function Yq(q,J,z,Q){let V=`${J}
297
304
  ${Q.trim()}
298
- ${J}`,Y="";try{Y=b(q,"utf8")}catch{}let W=new RegExp(`${z}[\\s\\S]*?${J}`);Y=W.test(Y)?Y.replace(W,V):Y.trim()?`${Y.trim()}
305
+ ${z}`,Y="";try{Y=X(q,"utf8")}catch{}let W=new RegExp(`${J}[\\s\\S]*?${z}`);Y=W.test(Y)?Y.replace(W,V):Y.trim()?`${Y.trim()}
299
306
 
300
307
  ${V}
301
308
  `:`${V}
302
309
  `,h(e(q),{recursive:!0}),R(q,Y.endsWith(`
303
310
  `)?Y:`${Y}
304
- `)}function m(q,z){try{return b(q,"utf8").includes(z)}catch{return!1}}function Zq(q,z,J){let Q="";try{Q=b(q,"utf8")}catch{return!1}let V=new RegExp(`${z}[\\s\\S]*?${J}\\n?`);if(!V.test(Q))return!1;let Y=Q.replace(V,"").replace(/\n{3,}/g,`
311
+ `)}function m(q,J){try{return X(q,"utf8").includes(J)}catch{return!1}}function Zq(q,J,z){let Q="";try{Q=X(q,"utf8")}catch{return!1}let V=new RegExp(`${J}[\\s\\S]*?${z}\\n?`);if(!V.test(Q))return!1;let Y=Q.replace(V,"").replace(/\n{3,}/g,`
305
312
 
306
- `).trimStart();return R(q,Y),!0}function $q(q,z,J){let Q=v(q,z);h(Q,{recursive:!0});let V=v(Q,"SKILL.md");return R(V,J),V}function S(q,z){return M(v(q,z,"SKILL.md"))}function Uq(q,z){let J=v(q,z);if(!M(J))return!1;return kq(J,{recursive:!0,force:!0}),!0}var f,qq=`## Beacon (visual planning panel)
313
+ `).trimStart();return R(q,Y),!0}function $q(q,J,z){let Q=v(q,J);h(Q,{recursive:!0});let V=v(Q,"SKILL.md");return R(V,z),V}function S(q,J){return M(v(q,J,"SKILL.md"))}function Uq(q,J){let z=v(q,J);if(!M(z))return!1;return Fq(z,{recursive:!0,force:!0}),!0}var f,qq=`## Beacon (visual planning panel)
307
314
 
308
315
  This machine has Beacon installed \u2014 a local visual planning surface for the terminal-side
309
316
  agent. Beacon proposes feature plans (roadmap features + DB schema + endpoints) via MCP,
@@ -327,17 +334,17 @@ the user reviews on a canvas at /plan, and feedback flows back as the next round
327
334
  Feedback bundles inline annotations on the markdown PLUS any edits the user made directly
328
335
  on the /map and /db boards (added features, attached subtasks, edited columns, new
329
336
  endpoints). Treat board edits as the user's revision intent \u2014 re-propose matching them
330
- verbatim. Do NOT implement until the tool returns approval.`;var Wq=x(()=>{f=["beacon-init","beacon-refresh","beacon-plan","beacon-explain"]});import{mkdirSync as Eq,renameSync as Oq,rmSync as Lq,writeFileSync as yq}from"fs";import{dirname as hq}from"path";function D(q,z){Eq(hq(q),{recursive:!0});let J=`${q}.tmp`;try{yq(J,z),Oq(J,q)}catch(Q){throw Lq(J,{force:!0}),Q}}function Wz(q,z,J=!1){D(q,JSON.stringify(z,null,J?2:void 0))}var Hq=()=>{};var sq={};d(sq,{setupCodexAssets:()=>pq,removeCodexMcp:()=>uq,removeCodexArtifacts:()=>lq,hasCodexMcp:()=>s,ensureCodexMcp:()=>xq,codexMcpProblem:()=>Sq,codexDetected:()=>vq,auditCodex:()=>aq,CODEX_HOOKS:()=>F});import{readFileSync as k}from"fs";import{homedir as _q}from"os";import{join as j}from"path";function Pq(){return process.env.HOME||process.env.USERPROFILE||_q()}function vq(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(p===void 0)p=Bun.which("codex")!==null;return p}function g(q){try{return Bun.TOML.parse(q)}catch{return null}}function s(){try{return Boolean(g(k(X(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function Sq(){let q="";try{q=k(X(),"utf8")}catch{return null}let z=g(q);if(!z)return`~/.codex/config.toml does not parse \u2014 ${w}`;if(z.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(q))return`mcp_servers is an inline table \u2014 ${w}`;return null}function xq(){let q="",z=!1;try{q=k(X(),"utf8"),z=!0}catch{}if(z){let Y=g(q);if(!Y)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${w}`};if(Y.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${w}`}}let J=!q?"":q.endsWith(`
337
+ verbatim. Do NOT implement until the tool returns approval.`;var Wq=u(()=>{f=["beacon-init","beacon-refresh","beacon-plan","beacon-explain"]});import{mkdirSync as kq,renameSync as Oq,rmSync as Lq,writeFileSync as yq}from"fs";import{dirname as hq}from"path";function D(q,J){kq(hq(q),{recursive:!0});let z=`${q}.tmp`;try{yq(z,J),Oq(z,q)}catch(Q){throw Lq(z,{force:!0}),Q}}function Pz(q,J,z=!1){D(q,JSON.stringify(J,null,z?2:void 0))}var Hq=()=>{};var sq={};d(sq,{setupCodexAssets:()=>pq,removeCodexMcp:()=>uq,removeCodexArtifacts:()=>lq,hasCodexMcp:()=>s,ensureCodexMcp:()=>xq,codexMcpProblem:()=>Sq,codexDetected:()=>vq,auditCodex:()=>aq,CODEX_HOOKS:()=>E});import{readFileSync as F}from"fs";import{homedir as _q}from"os";import{join as j}from"path";function Pq(){return process.env.HOME||process.env.USERPROFILE||_q()}function vq(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(p===void 0)p=Bun.which("codex")!==null;return p}function g(q){try{return Bun.TOML.parse(q)}catch{return null}}function s(){try{return Boolean(g(F(x(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function Sq(){let q="";try{q=F(x(),"utf8")}catch{return null}let J=g(q);if(!J)return`~/.codex/config.toml does not parse \u2014 ${w}`;if(J.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(q))return`mcp_servers is an inline table \u2014 ${w}`;return null}function xq(){let q="",J=!1;try{q=F(x(),"utf8"),J=!0}catch{}if(J){let Y=g(q);if(!Y)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${w}`};if(Y.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${w}`}}let z=!q?"":q.endsWith(`
331
338
  `)?`
332
339
  `:`
333
340
 
334
- `,Q=q+J+mq;if(g(Q)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${w}`};return D(X(),Q),{added:!0}}function uq(){let q="";try{q=k(X(),"utf8")}catch{return{removed:!1}}let z=q.split(`
335
- `),J=z.indexOf(Gq);if(J===-1)return{removed:!1,skipped:s()};let Q=z.indexOf(Xq,J);if(Q===-1)return{removed:!1,skipped:!0};z.splice(J,Q-J+1);let V=z.join(`
341
+ `,Q=q+z+mq;if(g(Q)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${w}`};return D(x(),Q),{added:!0}}function uq(){let q="";try{q=F(x(),"utf8")}catch{return{removed:!1}}let J=q.split(`
342
+ `),z=J.indexOf(Gq);if(z===-1)return{removed:!1,skipped:s()};let Q=J.indexOf(Xq,z);if(Q===-1)return{removed:!1,skipped:!0};J.splice(z,Q-z+1);let V=J.join(`
336
343
  `).replace(/\n{3,}/g,`
337
344
 
338
- `).replace(/^\n+/,"");if(g(V)===null)return{removed:!1,skipped:!0};return D(X(),V),{removed:!0}}async function pq(){let{INIT_SKILL:q,REFRESH_SKILL:z,PLAN_SKILL:J,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),o)),V={"beacon-init":q,"beacon-refresh":z,"beacon-plan":J,"beacon-explain":Q},Y=[];for(let U of f){if(!S(A(),U))Y.push(U);$q(A(),U,V[U])}let W=0;for(let U of F)if(Jq(l(),{event:U.event,matcher:U.matcher,command:U.command}))W++;let P=m(T(),I);Yq(T(),I,Bq,qq);let $=xq();return{skillsAdded:Y,hooksAdded:W,agentsMdBlockTouched:!P,mcp:$}}function aq(){let q={};for(let J of f)q[J]=S(A(),J);let z={};for(let J of F)z[J.event]=Qq(l(),{event:J.event,command:J.command});return{detected:vq(),skills:q,hooks:z,agentsMdBlock:m(T(),I),mcp:s()}}function lq(){let q=[];for(let V of f)if(Uq(A(),V))q.push(V);let z=0;for(let V of F)if(Vq(l(),{event:V.event,command:V.command}))z++;let J=Zq(T(),I,Bq),Q=uq();return{skillsRemoved:q,hooksRemoved:z,agentsMdBlockRemoved:J,mcpRemoved:Q.removed,mcpSkipped:Q.skipped}}var a=()=>j(Pq(),".codex"),l=()=>j(a(),"hooks.json"),X=()=>j(a(),"config.toml"),T=()=>j(a(),"AGENTS.md"),A=()=>j(Pq(),".agents","skills"),I="<!-- beacon:global:start -->",Bq="<!-- beacon:global:end -->",F,p,Gq="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",Xq="# beacon:end",mq,w="add it manually: codex mcp add beacon -- beacon mcp";var dq=x(()=>{Wq();Hq();F=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];mq=`${Gq}
345
+ `).replace(/^\n+/,"");if(g(V)===null)return{removed:!1,skipped:!0};return D(x(),V),{removed:!0}}async function pq(){let{INIT_SKILL:q,REFRESH_SKILL:J,PLAN_SKILL:z,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),o)),V={"beacon-init":q,"beacon-refresh":J,"beacon-plan":z,"beacon-explain":Q},Y=[];for(let U of f){if(!S(A(),U))Y.push(U);$q(A(),U,V[U])}let W=0;for(let U of E)if(Jq(l(),{event:U.event,matcher:U.matcher,command:U.command}))W++;let P=m(T(),I);Yq(T(),I,Bq,qq);let $=xq();return{skillsAdded:Y,hooksAdded:W,agentsMdBlockTouched:!P,mcp:$}}function aq(){let q={};for(let z of f)q[z]=S(A(),z);let J={};for(let z of E)J[z.event]=Qq(l(),{event:z.event,command:z.command});return{detected:vq(),skills:q,hooks:J,agentsMdBlock:m(T(),I),mcp:s()}}function lq(){let q=[];for(let V of f)if(Uq(A(),V))q.push(V);let J=0;for(let V of E)if(Vq(l(),{event:V.event,command:V.command}))J++;let z=Zq(T(),I,Bq),Q=uq();return{skillsRemoved:q,hooksRemoved:J,agentsMdBlockRemoved:z,mcpRemoved:Q.removed,mcpSkipped:Q.skipped}}var a=()=>j(Pq(),".codex"),l=()=>j(a(),"hooks.json"),x=()=>j(a(),"config.toml"),T=()=>j(a(),"AGENTS.md"),A=()=>j(Pq(),".agents","skills"),I="<!-- beacon:global:start -->",Bq="<!-- beacon:global:end -->",E,p,Gq="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",Xq="# beacon:end",mq,w="add it manually: codex mcp add beacon -- beacon mcp";var dq=u(()=>{Wq();Hq();E=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];mq=`${Gq}
339
346
  [mcp_servers.beacon]
340
347
  command = "beacon"
341
348
  args = ["mcp"]
342
349
  ${Xq}
343
- `});dq();export{pq as setupCodexAssets,uq as removeCodexMcp,lq as removeCodexArtifacts,s as hasCodexMcp,xq as ensureCodexMcp,Sq as codexMcpProblem,vq as codexDetected,aq as auditCodex,F as CODEX_HOOKS};
350
+ `});dq();export{pq as setupCodexAssets,uq as removeCodexMcp,lq as removeCodexArtifacts,s as hasCodexMcp,xq as ensureCodexMcp,Sq as codexMcpProblem,vq as codexDetected,aq as auditCodex,E as CODEX_HOOKS};
@@ -1,21 +1,21 @@
1
1
  // @bun
2
- var Iq=Object.defineProperty;var Aq=(q)=>q;function Oq(q,z){this[q]=Aq.bind(null,z)}var Pq=(q,z)=>{for(var J in z)Iq(q,J,{get:z[J],enumerable:!0,configurable:!0,set:Oq.bind(z,J)})};var B=(q,z)=>()=>(q&&(z=q(q=0)),z);var Gz=1500,Nz=480000,bz=1800000,f=3600000,uz=3000;var Xq=()=>{};var l={};Pq(l,{removeRepoAssets:()=>tq,installRefreshSkill:()=>hq,installPlanSkill:()=>Lq,installInitSkill:()=>kq,installExplainSkill:()=>_q,installCodexRepoSkills:()=>pq,ensureWorkflowDoc:()=>Sq,ensureMcp:()=>cq,auditRepo:()=>aq,REFRESH_SKILL:()=>s,PLAN_SKILL:()=>wq,INIT_SKILL:()=>r,EXPLAIN_SKILL:()=>xq});import{existsSync as v,mkdirSync as g,readFileSync as H,rmSync as F,writeFileSync as X}from"fs";import{join as $}from"path";function kq(q){let z=$(q,".claude","skills","beacon-init");g(z,{recursive:!0});let J=$(z,"SKILL.md");return X(J,r),J}function hq(q){let z=$(q,".claude","skills","beacon-refresh");g(z,{recursive:!0});let J=$(z,"SKILL.md");return X(J,s),J}function Lq(q){let z=$(q,".claude","skills","beacon-plan");g(z,{recursive:!0});let J=$(z,"SKILL.md");return X(J,wq),J}function _q(q){let z=$(q,".claude","skills","beacon-explain");g(z,{recursive:!0});let J=$(z,"SKILL.md");return X(J,xq),J}function pq(q){let z=[];for(let J of mq){let Q=$(q,".agents","skills",J.name);g(Q,{recursive:!0});let V=$(Q,"SKILL.md");X(V,J.body()),z.push(V)}return z}function Sq(q){let z=$(q,"AGENTS.md"),J="";try{J=H(z,"utf8")}catch{}let Q=new RegExp(`${R}[\\s\\S]*?${n}`);J=Q.test(J)?J.replace(Q,Hq):`${J.trim()}
2
+ var Iq=Object.defineProperty;var Oq=(q)=>q;function yq(q,z){this[q]=Oq.bind(null,z)}var Xq=(q,z)=>{for(var J in z)Iq(q,J,{get:z[J],enumerable:!0,configurable:!0,set:yq.bind(z,J)})};var g=(q,z)=>()=>(q&&(z=q(q=0)),z);var bz=1500,uz=480000,Kz=1800000,f=3600000,Cz=3000;var Hq=()=>{};var l={};Xq(l,{removeRepoAssets:()=>tq,installRefreshSkill:()=>hq,installPlanSkill:()=>Lq,installInitSkill:()=>kq,installExplainSkill:()=>_q,installCodexRepoSkills:()=>mq,ensureWorkflowDoc:()=>Sq,ensureMcp:()=>cq,auditRepo:()=>aq,REFRESH_SKILL:()=>s,PLAN_SKILL:()=>wq,INIT_SKILL:()=>r,EXPLAIN_SKILL:()=>xq});import{existsSync as v,mkdirSync as G,readFileSync as P,rmSync as F,writeFileSync as H}from"fs";import{join as $}from"path";function kq(q){let z=$(q,".claude","skills","beacon-init");G(z,{recursive:!0});let J=$(z,"SKILL.md");return H(J,r),J}function hq(q){let z=$(q,".claude","skills","beacon-refresh");G(z,{recursive:!0});let J=$(z,"SKILL.md");return H(J,s),J}function Lq(q){let z=$(q,".claude","skills","beacon-plan");G(z,{recursive:!0});let J=$(z,"SKILL.md");return H(J,wq),J}function _q(q){let z=$(q,".claude","skills","beacon-explain");G(z,{recursive:!0});let J=$(z,"SKILL.md");return H(J,xq),J}function mq(q){let z=[];for(let J of pq){let Q=$(q,".agents","skills",J.name);G(Q,{recursive:!0});let V=$(Q,"SKILL.md");H(V,J.body()),z.push(V)}return z}function Sq(q){let z=$(q,"AGENTS.md"),J="";try{J=P(z,"utf8")}catch{}let Q=new RegExp(`${R}[\\s\\S]*?${n}`);J=Q.test(J)?J.replace(Q,Pq):`${J.trim()}
3
3
 
4
- ${Hq}
5
- `.trimStart(),X(z,J.endsWith(`
4
+ ${Pq}
5
+ `.trimStart(),H(z,J.endsWith(`
6
6
  `)?J:`${J}
7
- `);let V=$(q,"CLAUDE.md"),Y="";try{Y=H(V,"utf8")}catch{}if(!/@AGENTS\.md/.test(Y))X(V,`${Y?`${Y.trim()}
7
+ `);let V=$(q,"CLAUDE.md"),Y="";try{Y=P(V,"utf8")}catch{}if(!/@AGENTS\.md/.test(Y))H(V,`${Y?`${Y.trim()}
8
8
 
9
9
  `:""}@AGENTS.md
10
- `)}function cq(q){let z=$(q,".mcp.json"),J={};try{J=JSON.parse(H(z,"utf8"))}catch{}J.mcpServers=J.mcpServers??{};let Q=J.mcpServers.beacon;if(Q){if(!Q.timeout||Q.timeout<f)return Q.timeout=f,X(z,JSON.stringify(J,null,2)+`
11
- `),{path:z,added:!1,updated:!0};return{path:z,added:!1,updated:!1}}return J.mcpServers.beacon={command:"beacon",args:["mcp"],timeout:f},X(z,JSON.stringify(J,null,2)+`
12
- `),{path:z,added:!0,updated:!1}}function aq(q){let z=$(q,".mcp.json"),J=!1;try{J=!!JSON.parse(H(z,"utf8")).mcpServers?.beacon}catch{}let Q=!1;try{Q=H($(q,"AGENTS.md"),"utf8").includes(R)}catch{}let V=!1;try{V=/@AGENTS\.md/.test(H($(q,"CLAUDE.md"),"utf8"))}catch{}return{repo:q,mcpRegistered:J,agentsMdBlock:Q,claudeMdImport:V,skills:{"beacon-init":v($(q,".claude","skills","beacon-init","SKILL.md")),"beacon-refresh":v($(q,".claude","skills","beacon-refresh","SKILL.md"))},codexSkills:{"beacon-init":v($(q,".agents","skills","beacon-init","SKILL.md")),"beacon-refresh":v($(q,".agents","skills","beacon-refresh","SKILL.md"))}}}function tq(q){let z=[];for(let Z of["beacon-init","beacon-refresh","beacon-db-design"]){let W=$(q,".claude","skills",Z);if(v(W))F(W,{recursive:!0,force:!0}),z.push(Z)}for(let Z of["beacon-init","beacon-refresh"]){let W=$(q,".agents","skills",Z);if(v(W))F(W,{recursive:!0,force:!0}),z.push(`codex:${Z}`)}let J=!1,Q=$(q,".mcp.json");try{let Z=JSON.parse(H(Q,"utf8"));if(Z.mcpServers?.beacon){if(delete Z.mcpServers.beacon,J=!0,Z.mcpServers&&Object.keys(Z.mcpServers).length===0)delete Z.mcpServers;if(Object.keys(Z).length===0)F(Q,{force:!0});else X(Q,JSON.stringify(Z,null,2)+`
13
- `)}}catch{}let V=!1,Y=$(q,"AGENTS.md");try{let Z=H(Y,"utf8"),W=new RegExp(`\\n?${R}[\\s\\S]*?${n}\\n?`);if(W.test(Z)){let d=Z.replace(W,`
10
+ `)}function cq(q){let z=$(q,".mcp.json"),J={};try{J=JSON.parse(P(z,"utf8"))}catch{}J.mcpServers=J.mcpServers??{};let Q=J.mcpServers.beacon;if(Q){if(!Q.timeout||Q.timeout<f)return Q.timeout=f,H(z,JSON.stringify(J,null,2)+`
11
+ `),{path:z,added:!1,updated:!0};return{path:z,added:!1,updated:!1}}return J.mcpServers.beacon={command:"beacon",args:["mcp"],timeout:f},H(z,JSON.stringify(J,null,2)+`
12
+ `),{path:z,added:!0,updated:!1}}function aq(q){let z=$(q,".mcp.json"),J=!1;try{J=!!JSON.parse(P(z,"utf8")).mcpServers?.beacon}catch{}let Q=!1;try{Q=P($(q,"AGENTS.md"),"utf8").includes(R)}catch{}let V=!1;try{V=/@AGENTS\.md/.test(P($(q,"CLAUDE.md"),"utf8"))}catch{}return{repo:q,mcpRegistered:J,agentsMdBlock:Q,claudeMdImport:V,skills:{"beacon-init":v($(q,".claude","skills","beacon-init","SKILL.md")),"beacon-refresh":v($(q,".claude","skills","beacon-refresh","SKILL.md"))},codexSkills:{"beacon-init":v($(q,".agents","skills","beacon-init","SKILL.md")),"beacon-refresh":v($(q,".agents","skills","beacon-refresh","SKILL.md"))}}}function tq(q){let z=[];for(let Z of["beacon-init","beacon-refresh","beacon-db-design"]){let W=$(q,".claude","skills",Z);if(v(W))F(W,{recursive:!0,force:!0}),z.push(Z)}for(let Z of["beacon-init","beacon-refresh"]){let W=$(q,".agents","skills",Z);if(v(W))F(W,{recursive:!0,force:!0}),z.push(`codex:${Z}`)}let J=!1,Q=$(q,".mcp.json");try{let Z=JSON.parse(P(Q,"utf8"));if(Z.mcpServers?.beacon){if(delete Z.mcpServers.beacon,J=!0,Z.mcpServers&&Object.keys(Z.mcpServers).length===0)delete Z.mcpServers;if(Object.keys(Z).length===0)F(Q,{force:!0});else H(Q,JSON.stringify(Z,null,2)+`
13
+ `)}}catch{}let V=!1,Y=$(q,"AGENTS.md");try{let Z=P(Y,"utf8"),W=new RegExp(`\\n?${R}[\\s\\S]*?${n}\\n?`);if(W.test(Z)){let d=Z.replace(W,`
14
14
  `).replace(/\n{3,}/g,`
15
15
 
16
- `).trimStart();X(Y,d.endsWith(`
16
+ `).trimStart();H(Y,d.endsWith(`
17
17
  `)?d:`${d}
18
- `),V=!0}}catch{}let U=!1,P=$(q,"CLAUDE.md");try{let Z=H(P,"utf8"),W=Z.replace(/^[ \t]*@AGENTS\.md[ \t]*\n?/m,"");if(W!==Z){if(!W.trim())F(P,{force:!0});else X(P,W);U=!0}}catch{}return{skillsRemoved:z,mcpUnregistered:J,agentsBlockRemoved:V,claudeImportRemoved:U}}var r=`---
18
+ `),V=!0}}catch{}let U=!1,X=$(q,"CLAUDE.md");try{let Z=P(X,"utf8"),W=Z.replace(/^[ \t]*@AGENTS\.md[ \t]*\n?/m,"");if(W!==Z){if(!W.trim())F(X,{force:!0});else H(X,W);U=!0}}catch{}return{skillsRemoved:z,mcpUnregistered:J,agentsBlockRemoved:V,claudeImportRemoved:U}}var r=`---
19
19
  name: beacon-init
20
20
  description: Read this repository and map its architecture, schema, and roadmap into Beacon (the local visual planning panel). Use when the user runs /beacon-init, asks to "set up Beacon for this repo", or asks to initialize/bootstrap Beacon's map of this codebase.
21
21
  ---
@@ -213,6 +213,13 @@ push depth into \`detail\`, not the node face. Supply \`steps\` for the guided w
213
213
  is the overview (empty \`focusIds\`), then teach one node (or a few) per step in order, each with its
214
214
  \`focusIds\`.
215
215
 
216
+ When the topic involves DATABASE tables, pass them in \`tables\` (they render as annotated schema cards
217
+ on the SAME board, not just raw schemas). For each table give a one-line \`note\` (why it exists), mark
218
+ the key columns \`isPk\`, point FKs at another table with \`fkTo: "<that table's id>"\`, give EVERY column a
219
+ short plain-English \`note\`, and add a \`sample\` row or two (the worked example, made concrete). Connect a
220
+ concept to its table with an \`edge\` (e.g. \`persists to\` / \`reads from\`) whose \`toId\` is the table's id \u2014
221
+ so the learner sees the table IN CONTEXT, wired to the code that uses it.
222
+
216
223
  ## 4. Answer in the loop \u2014 don't stop after one round
217
224
 
218
225
  \`beacon_explain\` returns the user's questions, each tagged \`[q:ID]\`. Answer EACH by calling
@@ -220,7 +227,7 @@ is the overview (empty \`focusIds\`), then teach one node (or a few) per step in
220
227
  Every answer must ADD understanding (rationale, trade-off) \u2014 never just restate the question. Expand
221
228
  the narrative or add nodes where it helps. Keep looping until the tool reports the user saved or closed
222
229
  the lesson.
223
- `,mq,R="<!-- beacon:workflow:start -->",n="<!-- beacon:workflow:end -->",Hq;var i=B(()=>{Xq();mq=[{name:"beacon-init",body:()=>r},{name:"beacon-refresh",body:()=>s}];Hq=`${R}
230
+ `,pq,R="<!-- beacon:workflow:start -->",n="<!-- beacon:workflow:end -->",Pq;var i=g(()=>{Hq();pq=[{name:"beacon-init",body:()=>r},{name:"beacon-refresh",body:()=>s}];Pq=`${R}
224
231
  ## Beacon \u2014 feature workflow
225
232
 
226
233
  This project uses Beacon (a local planning/visualization panel; run \`beacon\` to open it). When you start work on a FEATURE \u2014 whether referenced via an \`@beacon:feature://\u2026\` mention, an \`@beacon:note://\u2026\` note the user wrote in the Notes panel (treat its checkbox \`- [ ]\` todos as subtasks and order features by their dependencies), or just described in chat \u2014 follow these steps in order:
@@ -292,18 +299,18 @@ Register them all in that single batched call. If a plan added five features, th
292
299
  If the feature added or materially changed a REAL architectural component (a subsystem \u2014 NOT a file), also pass \`architecture: [{ title, domain, role, \u2026 }]\` so the Architecture map stays accurate. It upserts curated components by title; never list files as components. If you found a bug or something worth investigating in a component's code, add \`bugs: [{ note }]\` to its architecture entry \u2014 it renders as a bug flag on the node (attributed to the agent); identical open flags are not duplicated. Only flag what you actually saw in the code.
293
300
 
294
301
  Pull raw planning data anytime with \`beacon_entities\` (features / architecture / tables / endpoints).
295
- ${n}`});import{existsSync as M,mkdirSync as o,readdirSync as dq,readFileSync as G,rmSync as rq,writeFileSync as T}from"fs";import{dirname as vq,join as x}from"path";function jq(){return!!process.env.CLAUDE_PLUGIN_ROOT}function Bq(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;let z=x(q,".claude","plugins");if(!M(z))return null;let J=[z];for(let Q=0;Q<3&&J.length;Q++){let V=[];for(let Y of J){let U=x(Y,".claude-plugin","plugin.json");try{if(M(U)&&JSON.parse(G(U,"utf8")).name==="beacon")return Y}catch{}try{for(let P of dq(Y,{withFileTypes:!0}))if(P.isDirectory())V.push(x(Y,P.name))}catch{}}J=V}return null}function gq(q){return Bq(q)!==null}function e(q){try{return JSON.parse(G(q,"utf8"))}catch{return{}}}function Gq(q,z){o(vq(q),{recursive:!0}),T(q,JSON.stringify(z,null,2)+`
296
- `)}function y(q,z){let J=e(q);J.hooks=J.hooks??{},J.hooks[z.event]=J.hooks[z.event]??[];let Q=J.hooks[z.event];if(Q.some((Y)=>Y.matcher===z.matcher&&Y.hooks?.some((U)=>U.command===z.command)))return!1;return Q.push({matcher:z.matcher,hooks:[{type:"command",command:z.command}]}),Gq(q,J),!0}function E(q,z){return(e(q).hooks?.[z.event]??[]).some((V)=>V.hooks?.some((Y)=>Y.command===z.command))}function I(q,z){let J=e(q),Q=J.hooks?.[z.event];if(!Q)return!1;let V=!1,Y=Q.map((U)=>{let P=U.hooks?.length??0,Z=(U.hooks??[]).filter((W)=>W.command!==z.command);if(Z.length!==P)V=!0;return{...U,hooks:Z}}).filter((U)=>(U.hooks??[]).length>0);if(!V)return!1;if(Y.length)J.hooks[z.event]=Y;else delete J.hooks[z.event];if(J.hooks&&Object.keys(J.hooks).length===0)delete J.hooks;return Gq(q,J),!0}function A(q,z,J,Q){let V=`${z}
302
+ ${n}`});import{existsSync as M,mkdirSync as o,readdirSync as dq,readFileSync as j,rmSync as rq,writeFileSync as T}from"fs";import{dirname as vq,join as w}from"path";function jq(){return!!process.env.CLAUDE_PLUGIN_ROOT}function Bq(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;let z=w(q,".claude","plugins");if(!M(z))return null;let J=[z];for(let Q=0;Q<3&&J.length;Q++){let V=[];for(let Y of J){let U=w(Y,".claude-plugin","plugin.json");try{if(M(U)&&JSON.parse(j(U,"utf8")).name==="beacon")return Y}catch{}try{for(let X of dq(Y,{withFileTypes:!0}))if(X.isDirectory())V.push(w(Y,X.name))}catch{}}J=V}return null}function gq(q){return Bq(q)!==null}function sq(q){return/[\\/]\.claude[\\/]plugins[\\/]/.test(q)}function nq(q=process.env.HOME||process.env.USERPROFILE||""){if(!q)return null;try{let z=JSON.parse(j(w(q,".claude","plugins","installed_plugins.json"),"utf8"));for(let J of Object.keys(z.plugins??{}))if(/^beacon@/.test(J))return{key:J,marketplace:J.split("@")[1]??""}}catch{}return null}function e(q){try{return JSON.parse(j(q,"utf8"))}catch{return{}}}function Gq(q,z){o(vq(q),{recursive:!0}),T(q,JSON.stringify(z,null,2)+`
303
+ `)}function E(q,z){let J=e(q);J.hooks=J.hooks??{},J.hooks[z.event]=J.hooks[z.event]??[];let Q=J.hooks[z.event];if(Q.some((Y)=>Y.matcher===z.matcher&&Y.hooks?.some((U)=>U.command===z.command)))return!1;return Q.push({matcher:z.matcher,hooks:[{type:"command",command:z.command}]}),Gq(q,J),!0}function A(q,z){return(e(q).hooks?.[z.event]??[]).some((V)=>V.hooks?.some((Y)=>Y.command===z.command))}function I(q,z){let J=e(q),Q=J.hooks?.[z.event];if(!Q)return!1;let V=!1,Y=Q.map((U)=>{let X=U.hooks?.length??0,Z=(U.hooks??[]).filter((W)=>W.command!==z.command);if(Z.length!==X)V=!0;return{...U,hooks:Z}}).filter((U)=>(U.hooks??[]).length>0);if(!V)return!1;if(Y.length)J.hooks[z.event]=Y;else delete J.hooks[z.event];if(J.hooks&&Object.keys(J.hooks).length===0)delete J.hooks;return Gq(q,J),!0}function O(q,z,J,Q){let V=`${z}
297
304
  ${Q.trim()}
298
- ${J}`,Y="";try{Y=G(q,"utf8")}catch{}let U=new RegExp(`${z}[\\s\\S]*?${J}`);Y=U.test(Y)?Y.replace(U,V):Y.trim()?`${Y.trim()}
305
+ ${J}`,Y="";try{Y=j(q,"utf8")}catch{}let U=new RegExp(`${z}[\\s\\S]*?${J}`);Y=U.test(Y)?Y.replace(U,V):Y.trim()?`${Y.trim()}
299
306
 
300
307
  ${V}
301
308
  `:`${V}
302
309
  `,o(vq(q),{recursive:!0}),T(q,Y.endsWith(`
303
310
  `)?Y:`${Y}
304
- `)}function N(q,z){try{return G(q,"utf8").includes(z)}catch{return!1}}function O(q,z,J){let Q="";try{Q=G(q,"utf8")}catch{return!1}let V=new RegExp(`${z}[\\s\\S]*?${J}\\n?`);if(!V.test(Q))return!1;let Y=Q.replace(V,"").replace(/\n{3,}/g,`
311
+ `)}function N(q,z){try{return j(q,"utf8").includes(z)}catch{return!1}}function y(q,z,J){let Q="";try{Q=j(q,"utf8")}catch{return!1}let V=new RegExp(`${z}[\\s\\S]*?${J}\\n?`);if(!V.test(Q))return!1;let Y=Q.replace(V,"").replace(/\n{3,}/g,`
305
312
 
306
- `).trimStart();return T(q,Y),!0}function k(q,z,J){let Q=x(q,z);o(Q,{recursive:!0});let V=x(Q,"SKILL.md");return T(V,J),V}function b(q,z){return M(x(q,z,"SKILL.md"))}function h(q,z){let J=x(q,z);if(!M(J))return!1;return rq(J,{recursive:!0,force:!0}),!0}var w,D=`## Beacon (visual planning panel)
313
+ `).trimStart();return T(q,Y),!0}function k(q,z,J){let Q=w(q,z);o(Q,{recursive:!0});let V=w(Q,"SKILL.md");return T(V,J),V}function b(q,z){return M(w(q,z,"SKILL.md"))}function h(q,z){let J=w(q,z);if(!M(J))return!1;return rq(J,{recursive:!0,force:!0}),!0}var x,D=`## Beacon (visual planning panel)
307
314
 
308
315
  This machine has Beacon installed \u2014 a local visual planning surface for the terminal-side
309
316
  agent. Beacon proposes feature plans (roadmap features + DB schema + endpoints) via MCP,
@@ -327,17 +334,17 @@ the user reviews on a canvas at /plan, and feedback flows back as the next round
327
334
  Feedback bundles inline annotations on the markdown PLUS any edits the user made directly
328
335
  on the /map and /db boards (added features, attached subtasks, edited columns, new
329
336
  endpoints). Treat board edits as the user's revision intent \u2014 re-propose matching them
330
- verbatim. Do NOT implement until the tool returns approval.`;var qq=B(()=>{w=["beacon-init","beacon-refresh","beacon-plan","beacon-explain"]});import{mkdirSync as sq,renameSync as nq,rmSync as lq,writeFileSync as iq}from"fs";import{dirname as oq}from"path";function L(q,z){sq(oq(q),{recursive:!0});let J=`${q}.tmp`;try{iq(J,z),nq(J,q)}catch(Q){throw lq(J,{force:!0}),Q}}function Ez(q,z,J=!1){L(q,JSON.stringify(z,null,J?2:void 0))}var Nq=()=>{};var Mq={};Pq(Mq,{setupCodexAssets:()=>Jz,removeCodexMcp:()=>Rq,removeCodexArtifacts:()=>Vz,hasCodexMcp:()=>Vq,ensureCodexMcp:()=>Fq,codexMcpProblem:()=>zz,codexDetected:()=>Kq,auditCodex:()=>Qz,CODEX_HOOKS:()=>c});import{readFileSync as S}from"fs";import{homedir as eq}from"os";import{join as C}from"path";function bq(){return process.env.HOME||process.env.USERPROFILE||eq()}function Kq(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(zq===void 0)zq=Bun.which("codex")!==null;return zq}function K(q){try{return Bun.TOML.parse(q)}catch{return null}}function Vq(){try{return Boolean(K(S(j(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function zz(){let q="";try{q=S(j(),"utf8")}catch{return null}let z=K(q);if(!z)return`~/.codex/config.toml does not parse \u2014 ${u}`;if(z.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(q))return`mcp_servers is an inline table \u2014 ${u}`;return null}function Fq(){let q="",z=!1;try{q=S(j(),"utf8"),z=!0}catch{}if(z){let Y=K(q);if(!Y)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${u}`};if(Y.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${u}`}}let J=!q?"":q.endsWith(`
337
+ verbatim. Do NOT implement until the tool returns approval.`;var qq=g(()=>{x=["beacon-init","beacon-refresh","beacon-plan","beacon-explain"]});import{mkdirSync as lq,renameSync as iq,rmSync as oq,writeFileSync as eq}from"fs";import{dirname as qz}from"path";function L(q,z){lq(qz(q),{recursive:!0});let J=`${q}.tmp`;try{eq(J,z),iq(J,q)}catch(Q){throw oq(J,{force:!0}),Q}}function Oz(q,z,J=!1){L(q,JSON.stringify(z,null,J?2:void 0))}var Nq=()=>{};var Mq={};Xq(Mq,{setupCodexAssets:()=>Vz,removeCodexMcp:()=>Rq,removeCodexArtifacts:()=>Zz,hasCodexMcp:()=>Vq,ensureCodexMcp:()=>Fq,codexMcpProblem:()=>Qz,codexDetected:()=>Kq,auditCodex:()=>Yz,CODEX_HOOKS:()=>c});import{readFileSync as S}from"fs";import{homedir as zz}from"os";import{join as C}from"path";function bq(){return process.env.HOME||process.env.USERPROFILE||zz()}function Kq(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(zq===void 0)zq=Bun.which("codex")!==null;return zq}function K(q){try{return Bun.TOML.parse(q)}catch{return null}}function Vq(){try{return Boolean(K(S(B(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function Qz(){let q="";try{q=S(B(),"utf8")}catch{return null}let z=K(q);if(!z)return`~/.codex/config.toml does not parse \u2014 ${u}`;if(z.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(q))return`mcp_servers is an inline table \u2014 ${u}`;return null}function Fq(){let q="",z=!1;try{q=S(B(),"utf8"),z=!0}catch{}if(z){let Y=K(q);if(!Y)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${u}`};if(Y.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${u}`}}let J=!q?"":q.endsWith(`
331
338
  `)?`
332
339
  `:`
333
340
 
334
- `,Q=q+J+qz;if(K(Q)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${u}`};return L(j(),Q),{added:!0}}function Rq(){let q="";try{q=S(j(),"utf8")}catch{return{removed:!1}}let z=q.split(`
341
+ `,Q=q+J+Jz;if(K(Q)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${u}`};return L(B(),Q),{added:!0}}function Rq(){let q="";try{q=S(B(),"utf8")}catch{return{removed:!1}}let z=q.split(`
335
342
  `),J=z.indexOf(Cq);if(J===-1)return{removed:!1,skipped:Vq()};let Q=z.indexOf(fq,J);if(Q===-1)return{removed:!1,skipped:!0};z.splice(J,Q-J+1);let V=z.join(`
336
343
  `).replace(/\n{3,}/g,`
337
344
 
338
- `).replace(/^\n+/,"");if(K(V)===null)return{removed:!1,skipped:!0};return L(j(),V),{removed:!0}}async function Jz(){let{INIT_SKILL:q,REFRESH_SKILL:z,PLAN_SKILL:J,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),l)),V={"beacon-init":q,"beacon-refresh":z,"beacon-plan":J,"beacon-explain":Q},Y=[];for(let W of w){if(!b(m(),W))Y.push(W);k(m(),W,V[W])}let U=0;for(let W of c)if(y(Qq(),{event:W.event,matcher:W.matcher,command:W.command}))U++;let P=N(_(),p);A(_(),p,uq,D);let Z=Fq();return{skillsAdded:Y,hooksAdded:U,agentsMdBlockTouched:!P,mcp:Z}}function Qz(){let q={};for(let J of w)q[J]=b(m(),J);let z={};for(let J of c)z[J.event]=E(Qq(),{event:J.event,command:J.command});return{detected:Kq(),skills:q,hooks:z,agentsMdBlock:N(_(),p),mcp:Vq()}}function Vz(){let q=[];for(let V of w)if(h(m(),V))q.push(V);let z=0;for(let V of c)if(I(Qq(),{event:V.event,command:V.command}))z++;let J=O(_(),p,uq),Q=Rq();return{skillsRemoved:q,hooksRemoved:z,agentsMdBlockRemoved:J,mcpRemoved:Q.removed,mcpSkipped:Q.skipped}}var Jq=()=>C(bq(),".codex"),Qq=()=>C(Jq(),"hooks.json"),j=()=>C(Jq(),"config.toml"),_=()=>C(Jq(),"AGENTS.md"),m=()=>C(bq(),".agents","skills"),p="<!-- beacon:global:start -->",uq="<!-- beacon:global:end -->",c,zq,Cq="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",fq="# beacon:end",qz,u="add it manually: codex mcp add beacon -- beacon mcp";var Tq=B(()=>{qq();Nq();c=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];qz=`${Cq}
345
+ `).replace(/^\n+/,"");if(K(V)===null)return{removed:!1,skipped:!0};return L(B(),V),{removed:!0}}async function Vz(){let{INIT_SKILL:q,REFRESH_SKILL:z,PLAN_SKILL:J,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),l)),V={"beacon-init":q,"beacon-refresh":z,"beacon-plan":J,"beacon-explain":Q},Y=[];for(let W of x){if(!b(p(),W))Y.push(W);k(p(),W,V[W])}let U=0;for(let W of c)if(E(Qq(),{event:W.event,matcher:W.matcher,command:W.command}))U++;let X=N(_(),m);O(_(),m,uq,D);let Z=Fq();return{skillsAdded:Y,hooksAdded:U,agentsMdBlockTouched:!X,mcp:Z}}function Yz(){let q={};for(let J of x)q[J]=b(p(),J);let z={};for(let J of c)z[J.event]=A(Qq(),{event:J.event,command:J.command});return{detected:Kq(),skills:q,hooks:z,agentsMdBlock:N(_(),m),mcp:Vq()}}function Zz(){let q=[];for(let V of x)if(h(p(),V))q.push(V);let z=0;for(let V of c)if(I(Qq(),{event:V.event,command:V.command}))z++;let J=y(_(),m,uq),Q=Rq();return{skillsRemoved:q,hooksRemoved:z,agentsMdBlockRemoved:J,mcpRemoved:Q.removed,mcpSkipped:Q.skipped}}var Jq=()=>C(bq(),".codex"),Qq=()=>C(Jq(),"hooks.json"),B=()=>C(Jq(),"config.toml"),_=()=>C(Jq(),"AGENTS.md"),p=()=>C(bq(),".agents","skills"),m="<!-- beacon:global:start -->",uq="<!-- beacon:global:end -->",c,zq,Cq="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",fq="# beacon:end",Jz,u="add it manually: codex mcp add beacon -- beacon mcp";var Tq=g(()=>{qq();Nq();c=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];Jz=`${Cq}
339
346
  [mcp_servers.beacon]
340
347
  command = "beacon"
341
348
  args = ["mcp"]
342
349
  ${fq}
343
- `});qq();import{existsSync as Yz}from"fs";import{homedir as Zz}from"os";import{join as a}from"path";function $z(){return process.env.HOME||process.env.USERPROFILE||Zz()}var t=()=>a($z(),".claude"),Yq=()=>a(t(),"skills"),Zq=()=>a(t(),"settings.json"),$q=()=>a(t(),"CLAUDE.md"),Wq="<!-- beacon:global:start -->",Dq="<!-- beacon:global:end -->";var Wz=D,Uq=[{event:"PreToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon guard",description:"Gate edits against the active plan's scope contract (when the scope-guard flag is on): in-scope \u2192 allow, off-scope \u2192 ask the user to authorize. No-op + fail-open otherwise."},{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}];function Uz(q,z){return k(Yq(),q,z)}function yq(q){return b(Yq(),q)}function Pz(q){return h(Yq(),q)}function Xz(q){return y(Zq(),q)}function Hz(q){return E(Zq(),q)}function wz(q){return I(Zq(),q)}function xz(q){A($q(),Wq,Dq,q)}function Eq(){return N($q(),Wq)}function vz(){return O($q(),Wq,Dq)}function cz(){let q={};for(let J of w)q[J]=yq(J);let z={};for(let J of Uq)z[J.event]=Hz({event:J.event,command:J.command});return{homeExists:Yz(t()),skills:q,hooks:z,claudeMdBlock:Eq()}}async function jz(){let{INIT_SKILL:q,REFRESH_SKILL:z,PLAN_SKILL:J,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),l)),V={"beacon-init":q,"beacon-refresh":z,"beacon-plan":J,"beacon-explain":Q},Y=[];for(let Z of w){if(!yq(Z))Y.push(Z);Uz(Z,V[Z])}let U=0;for(let Z of Uq)if(Xz({event:Z.event,matcher:Z.matcher,command:Z.command}))U++;let P=Eq();return xz(Wz),{skillsAdded:Y,hooksAdded:U,claudeMdBlockTouched:!P}}async function az(){if(jq())return{ok:!0,skipped:"plugin",skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1};let q;if(gq()){try{Bz()}catch{}q={ok:!0,skipped:"plugin-present",skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}else try{q={ok:!0,...await jz()}}catch(z){q={ok:!1,error:z instanceof Error?z.message:String(z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let z=await Promise.resolve().then(() => (Tq(),Mq));if(z.codexDetected())q.codex={ok:!0,...await z.setupCodexAssets()}}catch(z){q.codex={ok:!1,error:z instanceof Error?z.message:String(z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return q}function Bz(){let q=[];for(let Q of w)if(Pz(Q))q.push(Q);let z=0;for(let Q of Uq)if(wz(Q))z++;let J=vz();return{skillsRemoved:q,hooksRemoved:z,claudeMdBlockRemoved:J}}export{jz as setupGlobalAssets,az as selfHealGlobal,Pz as removeGlobalSkill,wz as removeGlobalHook,vz as removeGlobalClaudeMdBlock,Bz as removeBeaconArtifacts,jq as isPluginManaged,yq as isGlobalSkillInstalled,Uz as installGlobalSkill,Hz as hasGlobalHook,Eq as hasGlobalClaudeMdBlock,Bq as findBeaconPluginDir,Xz as ensureGlobalHook,xz as ensureGlobalClaudeMdBlock,gq as beaconPluginInstalled,cz as auditGlobal,w as GLOBAL_SKILLS,Uq as GLOBAL_HOOKS,Wz as GLOBAL_CLAUDE_MD_BLOCK};
350
+ `});qq();import{existsSync as $z}from"fs";import{homedir as Wz}from"os";import{join as a}from"path";function Uz(){return process.env.HOME||process.env.USERPROFILE||Wz()}var t=()=>a(Uz(),".claude"),Yq=()=>a(t(),"skills"),Zq=()=>a(t(),"settings.json"),$q=()=>a(t(),"CLAUDE.md"),Wq="<!-- beacon:global:start -->",Dq="<!-- beacon:global:end -->";var Xz=D,Uq=[{event:"PreToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon guard",description:"Gate edits against the active plan's scope contract (when the scope-guard flag is on): in-scope \u2192 allow, off-scope \u2192 ask the user to authorize. No-op + fail-open otherwise."},{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}];function Hz(q,z){return k(Yq(),q,z)}function Eq(q){return b(Yq(),q)}function Pz(q){return h(Yq(),q)}function wz(q){return E(Zq(),q)}function xz(q){return A(Zq(),q)}function vz(q){return I(Zq(),q)}function jz(q){O($q(),Wq,Dq,q)}function Aq(){return N($q(),Wq)}function Bz(){return y($q(),Wq,Dq)}function tz(){let q={};for(let J of x)q[J]=Eq(J);let z={};for(let J of Uq)z[J.event]=xz({event:J.event,command:J.command});return{homeExists:$z(t()),skills:q,hooks:z,claudeMdBlock:Aq()}}async function gz(){let{INIT_SKILL:q,REFRESH_SKILL:z,PLAN_SKILL:J,EXPLAIN_SKILL:Q}=await Promise.resolve().then(() => (i(),l)),V={"beacon-init":q,"beacon-refresh":z,"beacon-plan":J,"beacon-explain":Q},Y=[];for(let Z of x){if(!Eq(Z))Y.push(Z);Hz(Z,V[Z])}let U=0;for(let Z of Uq)if(wz({event:Z.event,matcher:Z.matcher,command:Z.command}))U++;let X=Aq();return jz(Xz),{skillsAdded:Y,hooksAdded:U,claudeMdBlockTouched:!X}}async function dz(){if(jq())return{ok:!0,skipped:"plugin",skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1};let q;if(gq()){try{Gz()}catch{}q={ok:!0,skipped:"plugin-present",skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}else try{q={ok:!0,...await gz()}}catch(z){q={ok:!1,error:z instanceof Error?z.message:String(z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let z=await Promise.resolve().then(() => (Tq(),Mq));if(z.codexDetected())q.codex={ok:!0,...await z.setupCodexAssets()}}catch(z){q.codex={ok:!1,error:z instanceof Error?z.message:String(z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return q}function Gz(){let q=[];for(let Q of x)if(Pz(Q))q.push(Q);let z=0;for(let Q of Uq)if(vz(Q))z++;let J=Bz();return{skillsRemoved:q,hooksRemoved:z,claudeMdBlockRemoved:J}}export{gz as setupGlobalAssets,dz as selfHealGlobal,Pz as removeGlobalSkill,vz as removeGlobalHook,Bz as removeGlobalClaudeMdBlock,Gz as removeBeaconArtifacts,jq as isPluginManaged,sq as isInstalledPluginPath,Eq as isGlobalSkillInstalled,nq as installedBeaconPlugin,Hz as installGlobalSkill,xz as hasGlobalHook,Aq as hasGlobalClaudeMdBlock,Bq as findBeaconPluginDir,wz as ensureGlobalHook,jz as ensureGlobalClaudeMdBlock,gq as beaconPluginInstalled,tz as auditGlobal,x as GLOBAL_SKILLS,Uq as GLOBAL_HOOKS,Xz as GLOBAL_CLAUDE_MD_BLOCK};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trybeacon",
3
- "version": "0.1.66",
3
+ "version": "0.1.67",
4
4
  "description": "The visual planning surface for the coding agent in your terminal.",
5
5
  "homepage": "https://trybeacon.sh",
6
6
  "license": "Apache-2.0",
@@ -54,6 +54,13 @@ push depth into `detail`, not the node face. Supply `steps` for the guided walkt
54
54
  is the overview (empty `focusIds`), then teach one node (or a few) per step in order, each with its
55
55
  `focusIds`.
56
56
 
57
+ When the topic involves DATABASE tables, pass them in `tables` (they render as annotated schema cards
58
+ on the SAME board, not just raw schemas). For each table give a one-line `note` (why it exists), mark
59
+ the key columns `isPk`, point FKs at another table with `fkTo: "<that table's id>"`, give EVERY column a
60
+ short plain-English `note`, and add a `sample` row or two (the worked example, made concrete). Connect a
61
+ concept to its table with an `edge` (e.g. `persists to` / `reads from`) whose `toId` is the table's id —
62
+ so the learner sees the table IN CONTEXT, wired to the code that uses it.
63
+
57
64
  ## 4. Answer in the loop — don't stop after one round
58
65
 
59
66
  `beacon_explain` returns the user's questions, each tagged `[q:ID]`. Answer EACH by calling