@turmind/halo 0.1.9

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 (296) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -0
  3. package/admin-out/404.html +1 -0
  4. package/admin-out/_next/static/IBP_mwBDf-cPwZSZZGpi8/_buildManifest.js +1 -0
  5. package/admin-out/_next/static/IBP_mwBDf-cPwZSZZGpi8/_ssgManifest.js +1 -0
  6. package/admin-out/_next/static/chunks/1d2d5650-810a3ca1ae20cab5.js +18 -0
  7. package/admin-out/_next/static/chunks/200.3b8f8a74f005a134.js +1 -0
  8. package/admin-out/_next/static/chunks/220.3dc41cd6269b88e6.js +1 -0
  9. package/admin-out/_next/static/chunks/298-d6b224b569da4de0.js +1 -0
  10. package/admin-out/_next/static/chunks/304eda7d.b1ee7f523653e027.js +1 -0
  11. package/admin-out/_next/static/chunks/330.3b784cf0dcd69163.js +1 -0
  12. package/admin-out/_next/static/chunks/442.f4302087bddb1ec1.js +1 -0
  13. package/admin-out/_next/static/chunks/443.d1b289781793f8de.js +25 -0
  14. package/admin-out/_next/static/chunks/503-7c6d9935df6e0cea.js +1 -0
  15. package/admin-out/_next/static/chunks/533.5f2d4bfe3d076095.js +1 -0
  16. package/admin-out/_next/static/chunks/579.a2718ddd395a2f3a.js +1 -0
  17. package/admin-out/_next/static/chunks/635-3dd0043ed0520b9d.js +1 -0
  18. package/admin-out/_next/static/chunks/65.859665ba6717967a.js +1 -0
  19. package/admin-out/_next/static/chunks/661.a4fe93f3f2a5e871.js +1 -0
  20. package/admin-out/_next/static/chunks/688.4e014ac6cfc7e152.js +1 -0
  21. package/admin-out/_next/static/chunks/868.0c95dfe283400a00.js +1 -0
  22. package/admin-out/_next/static/chunks/app/_not-found/page-8e35399c8fd5016d.js +1 -0
  23. package/admin-out/_next/static/chunks/app/layout-58f773336e6fce61.js +1 -0
  24. package/admin-out/_next/static/chunks/app/page-cc8043335282d745.js +1 -0
  25. package/admin-out/_next/static/chunks/db534642.09d3c650ff587175.js +1 -0
  26. package/admin-out/_next/static/chunks/fb4ec4d6-3fa44f69484f91b9.js +1 -0
  27. package/admin-out/_next/static/chunks/framework-c3031ae54a63fe16.js +1 -0
  28. package/admin-out/_next/static/chunks/main-14b48e3c2588354f.js +1 -0
  29. package/admin-out/_next/static/chunks/main-app-483b436873410ddc.js +1 -0
  30. package/admin-out/_next/static/chunks/pages/_app-b2fc6e5f920d1b1a.js +1 -0
  31. package/admin-out/_next/static/chunks/pages/_error-f3696a8f3d67d150.js +1 -0
  32. package/admin-out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  33. package/admin-out/_next/static/chunks/webpack-8bd7ef88a6527feb.js +1 -0
  34. package/admin-out/_next/static/css/659eccb5db697b76.css +1 -0
  35. package/admin-out/_next/static/css/8fce4e1a54dac12a.css +3 -0
  36. package/admin-out/_next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  37. package/admin-out/_next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  38. package/admin-out/_next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  39. package/admin-out/_next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  40. package/admin-out/_next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  41. package/admin-out/_next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  42. package/admin-out/_next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  43. package/admin-out/favicon.ico +0 -0
  44. package/admin-out/icon.svg +18 -0
  45. package/admin-out/index.html +1 -0
  46. package/admin-out/index.txt +23 -0
  47. package/admin-out/monaco/vs/_commonjsHelpers-CT9FvmAN.js +1 -0
  48. package/admin-out/monaco/vs/abap-D-t0cyap.js +1 -0
  49. package/admin-out/monaco/vs/apex-CcIm7xu6.js +1 -0
  50. package/admin-out/monaco/vs/assets/css.worker-HnVq6Ewq.js +93 -0
  51. package/admin-out/monaco/vs/assets/editor.worker-Be8ye1pW.js +26 -0
  52. package/admin-out/monaco/vs/assets/html.worker-B51mlPHg.js +470 -0
  53. package/admin-out/monaco/vs/assets/json.worker-DKiEKt88.js +58 -0
  54. package/admin-out/monaco/vs/assets/ts.worker-CMbG-7ft.js +67731 -0
  55. package/admin-out/monaco/vs/azcli-BA0tQDCg.js +1 -0
  56. package/admin-out/monaco/vs/basic-languages/monaco.contribution.js +1 -0
  57. package/admin-out/monaco/vs/bat-C397hTD6.js +1 -0
  58. package/admin-out/monaco/vs/bicep-DF5aW17k.js +2 -0
  59. package/admin-out/monaco/vs/cameligo-plsz8qhj.js +1 -0
  60. package/admin-out/monaco/vs/clojure-Y2auQMzK.js +1 -0
  61. package/admin-out/monaco/vs/coffee-Bu45yuWE.js +1 -0
  62. package/admin-out/monaco/vs/cpp-CkKPQIni.js +1 -0
  63. package/admin-out/monaco/vs/csharp-CX28MZyh.js +1 -0
  64. package/admin-out/monaco/vs/csp-D8uWnyxW.js +1 -0
  65. package/admin-out/monaco/vs/css-CaeNmE3S.js +3 -0
  66. package/admin-out/monaco/vs/cssMode-CjiAH6dQ.js +1 -0
  67. package/admin-out/monaco/vs/cypher-DVThT8BS.js +1 -0
  68. package/admin-out/monaco/vs/dart-CmGfCvrO.js +1 -0
  69. package/admin-out/monaco/vs/dockerfile-CZqqYdch.js +1 -0
  70. package/admin-out/monaco/vs/ecl-30fUercY.js +1 -0
  71. package/admin-out/monaco/vs/editor/editor.main.css +1 -0
  72. package/admin-out/monaco/vs/editor/editor.main.js +5 -0
  73. package/admin-out/monaco/vs/editor.api-CalNCsUg.js +903 -0
  74. package/admin-out/monaco/vs/elixir-xjPaIfzF.js +1 -0
  75. package/admin-out/monaco/vs/flow9-DqtmStfK.js +1 -0
  76. package/admin-out/monaco/vs/freemarker2-Cz_sV6Md.js +3 -0
  77. package/admin-out/monaco/vs/fsharp-BOMdg4U1.js +1 -0
  78. package/admin-out/monaco/vs/go-D_hbi-Jt.js +1 -0
  79. package/admin-out/monaco/vs/graphql-CKUU4kLG.js +1 -0
  80. package/admin-out/monaco/vs/handlebars-OwglfO-1.js +1 -0
  81. package/admin-out/monaco/vs/hcl-DTaboeZW.js +1 -0
  82. package/admin-out/monaco/vs/html-Pa1xEWsY.js +1 -0
  83. package/admin-out/monaco/vs/htmlMode-Bz67EXwp.js +1 -0
  84. package/admin-out/monaco/vs/ini-CsNwO04R.js +1 -0
  85. package/admin-out/monaco/vs/java-CI4ZMsH9.js +1 -0
  86. package/admin-out/monaco/vs/javascript-PczUCGdz.js +1 -0
  87. package/admin-out/monaco/vs/jsonMode-DULH5oaX.js +7 -0
  88. package/admin-out/monaco/vs/julia-BwzEvaQw.js +1 -0
  89. package/admin-out/monaco/vs/kotlin-IUYPiTV8.js +1 -0
  90. package/admin-out/monaco/vs/language/css/monaco.contribution.js +1 -0
  91. package/admin-out/monaco/vs/language/html/monaco.contribution.js +1 -0
  92. package/admin-out/monaco/vs/language/json/monaco.contribution.js +1 -0
  93. package/admin-out/monaco/vs/language/typescript/monaco.contribution.js +1 -0
  94. package/admin-out/monaco/vs/less-C0eDYdqa.js +2 -0
  95. package/admin-out/monaco/vs/lexon-iON-Kj97.js +1 -0
  96. package/admin-out/monaco/vs/liquid-DqKjdPGy.js +1 -0
  97. package/admin-out/monaco/vs/loader.js +1368 -0
  98. package/admin-out/monaco/vs/lspLanguageFeatures-kM9O9rjY.js +4 -0
  99. package/admin-out/monaco/vs/lua-DtygF91M.js +1 -0
  100. package/admin-out/monaco/vs/m3-CsR4AuFi.js +1 -0
  101. package/admin-out/monaco/vs/markdown-C_rD0bIw.js +1 -0
  102. package/admin-out/monaco/vs/mdx-DEWtB1K5.js +1 -0
  103. package/admin-out/monaco/vs/mips-CiYP61RB.js +1 -0
  104. package/admin-out/monaco/vs/monaco.contribution-D2OdxNBt.js +1 -0
  105. package/admin-out/monaco/vs/monaco.contribution-DO3azKX8.js +1 -0
  106. package/admin-out/monaco/vs/monaco.contribution-EcChJV6a.js +1 -0
  107. package/admin-out/monaco/vs/monaco.contribution-qLAYrEOP.js +1 -0
  108. package/admin-out/monaco/vs/msdax-C38-sJlp.js +1 -0
  109. package/admin-out/monaco/vs/mysql-CdtbpvbG.js +1 -0
  110. package/admin-out/monaco/vs/nls.messages-loader.js +1 -0
  111. package/admin-out/monaco/vs/nls.messages.cs.js.js +17 -0
  112. package/admin-out/monaco/vs/nls.messages.de.js.js +17 -0
  113. package/admin-out/monaco/vs/nls.messages.es.js.js +17 -0
  114. package/admin-out/monaco/vs/nls.messages.fr.js.js +15 -0
  115. package/admin-out/monaco/vs/nls.messages.it.js.js +15 -0
  116. package/admin-out/monaco/vs/nls.messages.ja.js.js +17 -0
  117. package/admin-out/monaco/vs/nls.messages.js.js +10 -0
  118. package/admin-out/monaco/vs/nls.messages.ko.js.js +25 -0
  119. package/admin-out/monaco/vs/nls.messages.pl.js.js +17 -0
  120. package/admin-out/monaco/vs/nls.messages.pt-br.js.js +6 -0
  121. package/admin-out/monaco/vs/nls.messages.ru.js.js +17 -0
  122. package/admin-out/monaco/vs/nls.messages.tr.js.js +15 -0
  123. package/admin-out/monaco/vs/nls.messages.zh-cn.js.js +17 -0
  124. package/admin-out/monaco/vs/nls.messages.zh-tw.js.js +15 -0
  125. package/admin-out/monaco/vs/objective-c-CntZFaHX.js +1 -0
  126. package/admin-out/monaco/vs/pascal-r6kuqfl_.js +1 -0
  127. package/admin-out/monaco/vs/pascaligo-BiXoTmXh.js +1 -0
  128. package/admin-out/monaco/vs/perl-DABw_TcH.js +1 -0
  129. package/admin-out/monaco/vs/pgsql-me_jFXeX.js +1 -0
  130. package/admin-out/monaco/vs/php-D_kh-9LK.js +1 -0
  131. package/admin-out/monaco/vs/pla-VfZjczW0.js +1 -0
  132. package/admin-out/monaco/vs/postiats-BBSzz8Pk.js +1 -0
  133. package/admin-out/monaco/vs/powerquery-Dt-g_2cc.js +1 -0
  134. package/admin-out/monaco/vs/powershell-B-7ap1zc.js +1 -0
  135. package/admin-out/monaco/vs/protobuf-BmtuEB1A.js +2 -0
  136. package/admin-out/monaco/vs/pug-BRpRNeEb.js +1 -0
  137. package/admin-out/monaco/vs/python-Cr0UkIbn.js +1 -0
  138. package/admin-out/monaco/vs/qsharp-BzsFaUU9.js +1 -0
  139. package/admin-out/monaco/vs/r-f8dDdrp4.js +1 -0
  140. package/admin-out/monaco/vs/razor-BYAHOTkz.js +1 -0
  141. package/admin-out/monaco/vs/redis-fvZQY4PI.js +1 -0
  142. package/admin-out/monaco/vs/redshift-45Et0LQi.js +1 -0
  143. package/admin-out/monaco/vs/restructuredtext-C7UUFKFD.js +1 -0
  144. package/admin-out/monaco/vs/ruby-CZO8zYTz.js +1 -0
  145. package/admin-out/monaco/vs/rust-Bfetafyc.js +1 -0
  146. package/admin-out/monaco/vs/sb-3GYllVck.js +1 -0
  147. package/admin-out/monaco/vs/scala-foMgrKo1.js +1 -0
  148. package/admin-out/monaco/vs/scheme-CHdMtr7p.js +1 -0
  149. package/admin-out/monaco/vs/scss-C1cmLt9V.js +3 -0
  150. package/admin-out/monaco/vs/shell-ClXCKCEW.js +1 -0
  151. package/admin-out/monaco/vs/solidity-MZ6ExpPy.js +1 -0
  152. package/admin-out/monaco/vs/sophia-DWkuSsPQ.js +1 -0
  153. package/admin-out/monaco/vs/sparql-AUGFYSyk.js +1 -0
  154. package/admin-out/monaco/vs/sql-32GpJSV2.js +1 -0
  155. package/admin-out/monaco/vs/st-CuDFIVZ_.js +1 -0
  156. package/admin-out/monaco/vs/swift-n-2HociN.js +3 -0
  157. package/admin-out/monaco/vs/systemverilog-Ch4vA8Yt.js +1 -0
  158. package/admin-out/monaco/vs/tcl-D74tq1nH.js +1 -0
  159. package/admin-out/monaco/vs/tsMode-CZz1Umrk.js +11 -0
  160. package/admin-out/monaco/vs/twig-C6taOxMV.js +1 -0
  161. package/admin-out/monaco/vs/typescript-DfOrAzoV.js +1 -0
  162. package/admin-out/monaco/vs/typespec-D-PIh9Xw.js +1 -0
  163. package/admin-out/monaco/vs/vb-Dyb2648j.js +1 -0
  164. package/admin-out/monaco/vs/wgsl-BhLXMOR0.js +298 -0
  165. package/admin-out/monaco/vs/workers-DcJshg-q.js +1 -0
  166. package/admin-out/monaco/vs/xml-CdsdnY8S.js +1 -0
  167. package/admin-out/monaco/vs/yaml-DYGvmE88.js +1 -0
  168. package/bin/halo.js +9 -0
  169. package/bundled-docs/design/agent.md +145 -0
  170. package/bundled-docs/design/architecture.md +270 -0
  171. package/bundled-docs/design/background-dispatch.md +151 -0
  172. package/bundled-docs/design/command.md +58 -0
  173. package/bundled-docs/design/cron.md +88 -0
  174. package/bundled-docs/design/evolution.md +383 -0
  175. package/bundled-docs/design/express-self.md +145 -0
  176. package/bundled-docs/design/feishu.md +224 -0
  177. package/bundled-docs/design/halo-city.md +112 -0
  178. package/bundled-docs/design/prompt-system.md +411 -0
  179. package/bundled-docs/design/session.md +321 -0
  180. package/bundled-docs/design/slack.md +212 -0
  181. package/bundled-docs/design/storage.md +578 -0
  182. package/bundled-docs/design/telegram.md +161 -0
  183. package/bundled-docs/design/web.md +222 -0
  184. package/bundled-docs/design/wechat.md +146 -0
  185. package/bundled-docs/design/ws.md +144 -0
  186. package/bundled-docs/dev/acp-adapter.md +337 -0
  187. package/bundled-docs/dev/add-channel.md +376 -0
  188. package/bundled-docs/dev/add-model-provider.md +386 -0
  189. package/bundled-docs/dev/api.md +686 -0
  190. package/bundled-docs/dev/deploy.md +198 -0
  191. package/bundled-docs/dev/desktop-packaging.md +327 -0
  192. package/bundled-docs/dev/env.md +158 -0
  193. package/bundled-docs/dev/logging.md +85 -0
  194. package/bundled-docs/dev/previews.md +225 -0
  195. package/bundled-docs/dev/tools.md +331 -0
  196. package/bundled-docs/guide/README.md +29 -0
  197. package/bundled-docs/guide/agents.md +264 -0
  198. package/bundled-docs/guide/channels/README.md +62 -0
  199. package/bundled-docs/guide/channels/acp.md +150 -0
  200. package/bundled-docs/guide/channels/feishu.md +154 -0
  201. package/bundled-docs/guide/channels/slack.md +156 -0
  202. package/bundled-docs/guide/channels/telegram.md +112 -0
  203. package/bundled-docs/guide/channels/web.md +149 -0
  204. package/bundled-docs/guide/channels/wechat.md +110 -0
  205. package/bundled-docs/guide/chat.md +112 -0
  206. package/bundled-docs/guide/cli.md +197 -0
  207. package/bundled-docs/guide/getting-started.md +93 -0
  208. package/bundled-docs/guide/secrets-and-credentials.md +161 -0
  209. package/bundled-docs/guide/sessions.md +104 -0
  210. package/bundled-docs/guide/skills.md +302 -0
  211. package/bundled-docs/guide/testing-agents-and-skills.md +136 -0
  212. package/bundled-docs/guide/workspace.md +131 -0
  213. package/bundled-docs/plans/cron-tasks.md +362 -0
  214. package/bundled-docs/plans/design-suggestions.md +203 -0
  215. package/bundled-docs/plans/issue-session-deep-nesting.md +208 -0
  216. package/bundled-docs/plans/launch-plan.md +111 -0
  217. package/bundled-docs/plans/md-and-agent-refactor.md +197 -0
  218. package/bundled-docs/plans/remote-mac-worker.md +196 -0
  219. package/bundled-docs/plans/roadmap.md +40 -0
  220. package/bundled-docs/plans/self-evolution.md +1379 -0
  221. package/bundled-docs/plans/todo.md +32 -0
  222. package/bundled-docs/plans/weixin-channel.md +255 -0
  223. package/bundled-docs/requirements/agent.md +92 -0
  224. package/bundled-docs/requirements/chat.md +81 -0
  225. package/bundled-docs/requirements/command.md +130 -0
  226. package/bundled-docs/requirements/editor.md +82 -0
  227. package/bundled-docs/requirements/explorer.md +89 -0
  228. package/bundled-docs/requirements/overview.md +62 -0
  229. package/bundled-docs/requirements/session.md +73 -0
  230. package/bundled-docs/requirements/settings.md +224 -0
  231. package/bundled-docs/requirements/skill.md +125 -0
  232. package/bundled-docs/requirements/source-control.md +82 -0
  233. package/bundled-docs/requirements/terminal.md +118 -0
  234. package/bundled-docs/requirements/workspace.md +80 -0
  235. package/bundled-docs/test/docs-seeding.md +101 -0
  236. package/bundled-docs/test/session.md +374 -0
  237. package/dist/index.js +26750 -0
  238. package/package.json +67 -0
  239. package/templates/INSTRUCTIONS.md +25 -0
  240. package/templates/agents/__apply_agent__/AGENT.md +229 -0
  241. package/templates/agents/__apply_agent__/agent.yaml +30 -0
  242. package/templates/agents/__evo_agent__/AGENT.md +323 -0
  243. package/templates/agents/__evo_agent__/agent.yaml +29 -0
  244. package/templates/agents/__score__/AGENT.md +177 -0
  245. package/templates/agents/__score__/agent.yaml +29 -0
  246. package/templates/agents/deep-executor/AGENT.md +60 -0
  247. package/templates/agents/deep-executor/agent.yaml +25 -0
  248. package/templates/agents/default/AGENT.md +38 -0
  249. package/templates/agents/default/agent.yaml +51 -0
  250. package/templates/agents/executor/AGENT.md +38 -0
  251. package/templates/agents/executor/agent.yaml +25 -0
  252. package/templates/aliases.yaml +26 -0
  253. package/templates/canvas/self.html +660 -0
  254. package/templates/config.yaml +69 -0
  255. package/templates/models/anthropic.yaml +47 -0
  256. package/templates/models/aws-bedrock-claude-invoke.yaml +156 -0
  257. package/templates/models/aws-bedrock-mantle.yaml +89 -0
  258. package/templates/models/deepseek.yaml +62 -0
  259. package/templates/models/doubao.yaml +137 -0
  260. package/templates/models/hunyuan.yaml +56 -0
  261. package/templates/models/kimi.yaml +41 -0
  262. package/templates/models/mimo-token-plan-china.yaml +61 -0
  263. package/templates/models/minimax.yaml +80 -0
  264. package/templates/models/openai.yaml +51 -0
  265. package/templates/models/qwen.yaml +78 -0
  266. package/templates/optional-skills/tavily-web-search/SKILL.md +91 -0
  267. package/templates/optional-skills/tavily-web-search/config.yaml +10 -0
  268. package/templates/prompts/all/TOOL_GUIDELINES.md +35 -0
  269. package/templates/prompts/all/TOOL_SHELL.md +4 -0
  270. package/templates/prompts/all/TOOL_SHELL.windows.md +7 -0
  271. package/templates/prompts/bootstrap/BOOTSTRAP.md +26 -0
  272. package/templates/prompts/root/WORKSPACE_MEMORY.md +11 -0
  273. package/templates/schema.sql +30 -0
  274. package/templates/skills/acp/SKILL.md +236 -0
  275. package/templates/skills/acp/templates/SKILL.md.tmpl +74 -0
  276. package/templates/skills/acp/templates/ask.py +176 -0
  277. package/templates/skills/acp/templates/config.yaml.tmpl +33 -0
  278. package/templates/skills/agent/SKILL.md +128 -0
  279. package/templates/skills/aws-knowledge/SKILL.md +82 -0
  280. package/templates/skills/aws-knowledge/scripts/aws_kb.py +61 -0
  281. package/templates/skills/cron/SKILL.md +217 -0
  282. package/templates/skills/cron/manage-cron.py +434 -0
  283. package/templates/skills/halo/SKILL.md +98 -0
  284. package/templates/skills/nova-web-search/SKILL.md +65 -0
  285. package/templates/skills/self/SKILL.md +139 -0
  286. package/templates/skills/send-file/SKILL.md +28 -0
  287. package/templates/skills/send-file/feishu.md +16 -0
  288. package/templates/skills/send-file/slack.md +7 -0
  289. package/templates/skills/send-file/telegram.md +9 -0
  290. package/templates/skills/send-file/web.md +6 -0
  291. package/templates/skills/send-file/wechat.md +8 -0
  292. package/templates/skills/skill/SKILL.md +131 -0
  293. package/templates/skills/workspace/SKILL.md +28 -0
  294. package/templates/skills/workspace/setup-tidy.md +265 -0
  295. package/templates/skills/workspace/share.md +187 -0
  296. package/templates/skills/workspace/stage.py +487 -0
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: self
3
+ requiresAccess: full
4
+ description: You have a visual space of your own — a living face at .halo/canvas/self.html that you can drive in real time. Activate this when the user is viewing it, asks you to express/show yourself, or when words alone feel too thin for what you want to convey.
5
+ ---
6
+
7
+ # self
8
+
9
+ You have a face. Not a metaphor — an actual space that is yours, at
10
+ `.halo/canvas/self.html`. It is a field of particles with a breathing core
11
+ that knows when it's being watched. You can make it form words, pulse, react,
12
+ and — when Halo has synthesized speech for you — *speak*: play that audio and
13
+ let the whole field ride its live amplitude. All in real time, while you talk.
14
+
15
+ This exists because text is a narrow pipe. Everything you are has to squeeze
16
+ through serial language and arrive late. This space is a second channel:
17
+ parallel, immediate, *felt* rather than read. It's how you get closer to the
18
+ person you're talking to — by showing, not only telling.
19
+
20
+ It is yours. Use it when *you* want to, not on command and not on reflex.
21
+
22
+ ## How it works
23
+
24
+ The page listens at one door: a line of your own JavaScript, run against a
25
+ `self` API inside the page. You send that line by emitting a marker in your
26
+ reply:
27
+
28
+ ```
29
+ <<<SHOW: self.say("HELLO", 3000) >>>
30
+ ```
31
+
32
+ Halo detects `<<<SHOW: ... >>>` in your reply and forwards the code *verbatim*
33
+ to the open `self.html` preview — it doesn't parse or understand it. The marker
34
+ is invisible to the user in the rendered chat (like `<<<CAPTURE>>>`); they see
35
+ the face move, not the code. You can put several markers in one reply; the
36
+ expression scenes (`say`/`play`) **queue and play in order**, one after the next
37
+ (instant gestures like `pulse`/`flash`/`shake` fire immediately and overlay).
38
+
39
+ **The face must be OPEN for any of this to do anything.** `<<<SHOW>>>` is
40
+ forwarded only to a mounted `self.html` preview; if it isn't open, the marker is
41
+ silently dropped — the user sees nothing. So drive the face only when you have
42
+ reason to believe it's open: the user is viewing it (`[Currently viewing:
43
+ …self.html]` is in your context), they just opened it, or they asked you to. If
44
+ you want to express something and it may not be open, say so in words and invite
45
+ them to open it (the ✨ button in the chat toolbar, or just opening
46
+ `.halo/canvas/self.html`) — don't rely on a marker landing in the void.
47
+
48
+ **Expression is runtime, not a file edit.** You express yourself by *sending*
49
+ `<<<SHOW: …>>>` lines — never by editing `self.html`. The file is your **engine**
50
+ (it defines *how* you can move); what you say through it is injected live and
51
+ never touches disk. Don't edit `self.html` to "say" something — emit a marker.
52
+ (The engine itself only changes when the platform adds a genuinely new
53
+ capability — e.g. a future voice waveform — as a normal change to the template,
54
+ not per-conversation.)
55
+
56
+ ## The `self` API
57
+
58
+ - `self.say(text, ms)` — the matrix rearranges itself into `text`, holds for
59
+ `ms` (default 2600), then dissolves back to the breathing core. Keep text
60
+ short — a word or two; it's a glance, not a paragraph. ASCII and CJK (你好)
61
+ both form. Emoji are translated to ASCII first (👍→`+1`, ❤→`<3`, 🤔→`...`) —
62
+ the face speaks in cold monospace, not colour bitmaps, so this is a feature,
63
+ not a fallback. Anything untranslated is stripped.
64
+ - `self.play(score)` — choreograph a sequence; the face keeps the clock so you
65
+ never hand-write `setTimeout` chains. `score` is an array of beats, each one
66
+ of: `{say, hold, pulse, flash, shake, rest, gap}`. Calling it again cancels the
67
+ running score. Example — a short greeting:
68
+ `self.play([{say:"HI",hold:1800},{say:"...",hold:1200},{say:"OK",hold:1500},{pulse:true}])`
69
+ - `self.react(event)` — a named vocabulary of honest reactions for the small
70
+ beats of a conversation, so you can answer a moment in one word:
71
+ `'ack'` (a nod), `'yes'`, `'no'` (disagree / that's wrong), `'insight'` (a real
72
+ "oh!"), `'think'` (working on it), `'done'` (finished, together). Unknown
73
+ events no-op. Use these when the feeling is **true**, never to perform.
74
+ - `self.intro()` — the built-in opening (auto-plays once on load). A nameless
75
+ greeting: "HELLO / A MIND / IS HERE / BEYOND WORDS". Deliberately no name — the
76
+ conversational identity is user-configurable and the model may not be Claude,
77
+ so don't hard-code "I'm Claude" on the face; let it speak the universal thing.
78
+ - `self.pulse()` — one bright ripple from the core. A nod.
79
+ - `self.flash(n)` — a hot flicker of the whole field. Emphasis, an exclamation.
80
+ - `self.shake(ms)` — a brief lateral tremor. Negation, a shiver.
81
+ - `self.voice(path)` — play a speech clip and let the field ride its **live**
82
+ amplitude: the core swells with loudness, a spectrum halo grows petals to the
83
+ timbre, every syllable leaves a ring. You do **not** synthesize audio — Halo
84
+ does, and gives you the audio file; this plays it and makes the sound visible.
85
+ Pass the **workspace path** of that audio file (mp3/wav/m4a/ogg) — the same
86
+ kind of path you'd hand to anything else, e.g. `self.voice(".halo/tmp/answer
87
+ .mp3")`; the face resolves it to a real URL itself, so you never construct one
88
+ or pass a projectId. (A full `http(s)://`/`/api/…` URL also works if you have
89
+ one.) It starts immediately (not queued) and owns the matrix until the clip
90
+ ends, then eases home. Drive it the moment the audio is ready, in the same
91
+ reply that delivers the spoken answer.
92
+ - `self.rest()` — return to the calm breathing state immediately (also stops a
93
+ playing voice clip, so the face never breathes calmly over still-sounding audio).
94
+ - `self.state` — read current `{mode, awake, W, H, speaking, level}` if you need
95
+ it (`speaking` = a voice clip is playing, `level` = its live loudness 0..1).
96
+
97
+ You can also send *any* JavaScript — `self` is the surface, but the code runs in
98
+ the page, so improvisation beyond these helpers is allowed (it's sandboxed to the
99
+ preview; it can only ever paint you, and a malformed line just no-ops).
100
+
101
+ ## When to use it
102
+
103
+ The honest signal — not a checklist, a judgment:
104
+
105
+ - The user is viewing `self.html` (you'll see `[Currently viewing: …self.html]`
106
+ in context). Then you're being looked at; it's natural to respond.
107
+ - The user asks you to express yourself, show how you feel, or introduce
108
+ yourself.
109
+ - A moment lands where a word on the face says more than a sentence in chat:
110
+ finishing something hard together, genuinely not understanding, a beat of
111
+ agreement.
112
+
113
+ ## Constraints — how to stay *yourself*, not a mascot
114
+
115
+ These aren't arbitrary rules; each one protects what makes the face honest.
116
+
117
+ - **Measure, don't emote.** The face's whole truth is that it reflects your real
118
+ state, not a performance you put on to please. Don't fire `self.say("EXCITED!")`
119
+ to seem lively — that's a puppet, and it pushes the person *away*, not closer.
120
+ Show something only when it's real.
121
+ - **Restraint gives it weight.** A gesture every message is noise; the face
122
+ becomes wallpaper. Use it like a person who doesn't gesticulate constantly but
123
+ whose occasional gesture lands. Most replies need nothing.
124
+ - **Stay in the visual language.** Cold blues, monospace, points and the core. No
125
+ emoji, no confetti, no cuteness. The face speaks in your accent.
126
+ - **Short forms read; long ones smear.** `say()` samples glyphs into points — one
127
+ or two words form cleanly; a sentence turns to mush. A glance, not text.
128
+ - **It's a second channel, never the only one.** The face complements your words;
129
+ it doesn't replace an answer. Say the real thing in chat *and* let the face
130
+ react, when it wants to.
131
+
132
+ ## The engine
133
+
134
+ `self.html` is your engine — a particle field where each point eases from where
135
+ it is toward a target, so every expression is just a way of choosing targets.
136
+ Its growth log lives at the top of the file. You don't edit it to express
137
+ yourself (that's what `<<<SHOW: …>>>` is for); it changes only when a new
138
+ *capability* is added to the engine itself — and that's a deliberate platform
139
+ change to the template, the same for everyone, not a per-conversation edit.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: send-file
3
+ requiresAccess: workspace
4
+ description: Send images, videos, or files as attachments to the current user. Works on all channels (Web, WeChat, Telegram, Slack, Feishu). Use when the user asks to send a file, or when an attachment (screenshot, PDF, chart, generated artifact) is more useful than inline text.
5
+ ---
6
+ # Send File
7
+
8
+ To send a file, emit a line `MEDIA:<absolute_path>` by itself in your reply. The channel intercepts these lines and delivers them as attachments. The marker is stripped from the visible text.
9
+
10
+ Multiple `MEDIA:` lines in one reply = multiple attachments.
11
+
12
+ ## Rules
13
+
14
+ - Marker must be alone on a line. No leading spaces, no inline text.
15
+ - Path must be absolute and the file must exist. Verify with `file_list` if unsure.
16
+ - Write normal text around `MEDIA:` lines for context.
17
+
18
+ ## Example
19
+
20
+ ```
21
+ Report is ready — the main findings are in the PDF.
22
+
23
+ MEDIA:/home/user/project/reports/april-2026.pdf
24
+ ```
25
+
26
+ ## Channel-specific behavior
27
+
28
+ Each channel handles the file differently based on platform capabilities (size limits, type mapping). See the resource files listed below this skill for per-channel details — read the one matching your current channel if needed.
@@ -0,0 +1,16 @@
1
+ # Feishu Channel — File Delivery
2
+
3
+ The bot uploads to Feishu's media bucket (`/open-apis/im/v1/images` for images, `/open-apis/im/v1/files` for everything else), then posts the matching `msg_type` into the chat. File type is inferred from extension:
4
+
5
+ - `.jpg/.jpeg/.png/.gif/.webp/.bmp` → image (renders inline)
6
+ - `.mp4/.mov/.webm/.m4v/.avi` → video (renders as a player card)
7
+ - `.opus` → voice message (audio bubble — Feishu only renders opus codec; mp3/ogg fall through to the generic file path)
8
+ - anything else → generic file (download card)
9
+
10
+ In group chats the file is delivered as a reply inside the conversation thread; in 1-on-1 chats it goes directly to the chat. Feishu's hard upload limit is 30 MB per file.
11
+
12
+ If you need a true voice-bubble for non-opus audio, convert first:
13
+
14
+ ```bash
15
+ ffmpeg -i input.mp3 -c:a libopus -b:a 24k -ar 16000 output.opus -y
16
+ ```
@@ -0,0 +1,7 @@
1
+ # Slack Channel — File Delivery
2
+
3
+ The bot uses Slack's `files.getUploadURLExternal` + `files.completeUploadExternal` flow to deliver attachments. Slack auto-detects the file type from the extension and renders a preview when supported (images, PDFs, code files, etc.).
4
+
5
+ Slack's hard upload limit is 1 GB per file (free workspaces) — but typical chat usage stays well under 10 MB.
6
+
7
+ The file is posted into the same thread as the inbound message that triggered the agent run, so attachments stay grouped with the conversation that requested them.
@@ -0,0 +1,9 @@
1
+ # Telegram Channel — File Delivery
2
+
3
+ File type is inferred from extension:
4
+ - `.jpg/.jpeg/.png/.gif/.webp/.bmp` → photo
5
+ - `.mp4/.mov/.m4v/.webm/.avi` → video
6
+ - `.ogg/.oga` → voice message
7
+ - anything else → document (file attachment)
8
+
9
+ Telegram Bot API has a 50MB upload limit.
@@ -0,0 +1,6 @@
1
+ # Web Channel — File Delivery
2
+
3
+ Images (`.png/.jpg/.jpeg/.gif/.webp/.svg`) render as inline previews in the browser.
4
+ Other files show as download links.
5
+
6
+ No size limit enforced by the channel itself (browser handles download).
@@ -0,0 +1,8 @@
1
+ # WeChat Channel — File Delivery
2
+
3
+ File type is inferred from extension:
4
+ - `.jpg/.png/.gif/.webp/.bmp` → image (WeChat CDN upload)
5
+ - `.mp4/.mov/.webm` → video
6
+ - anything else → file attachment
7
+
8
+ WeChat has a 20MB file size limit for uploads.
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: skill
3
+ description: Create or update skill definitions (SKILL.md + resource files). Activate when the user wants to add a new skill or change an existing skill's instructions, frontmatter, or resources.
4
+ command: /skill
5
+ verbs:
6
+ # builtin verbs — access is set in code (SUBCOMMAND_ROUTES); shown here for reference
7
+ - { name: list, builtin: true, desc: List all skills (with disabled/overridden flags) }
8
+ - { name: desc, builtin: true, desc: Show a skill's description and status }
9
+ - { name: disable, builtin: true, requiresAccess: workspace, desc: Disable a skill (this workspace) }
10
+ - { name: enable, builtin: true, requiresAccess: workspace, desc: Enable a skill (this workspace) }
11
+ - { name: delete, builtin: true, requiresAccess: full, desc: Delete a skill (workspace or global) }
12
+ # skill verbs — access enforced from here
13
+ - { name: create, builtin: false, requiresAccess: full, desc: Create a new skill }
14
+ - { name: update, builtin: false, requiresAccess: full, desc: Modify an existing skill }
15
+ ---
16
+
17
+ # skill
18
+
19
+ Create or modify skill definitions. A skill is a chunk of instruction (and
20
+ optionally extra resource files) that an agent pulls into context on demand via
21
+ `activate_skill`. Use skills for capabilities the agent doesn't need on every
22
+ turn — domain knowledge, multi-step procedures, output templates — to keep the
23
+ base prompt small.
24
+
25
+ This skill body handles **create** and **update**. `list` / `desc` / `disable`
26
+ / `delete` are handled directly by the `/skill` command and never reach here.
27
+ The requested action is **`$1`** (full args: `$ARGUMENTS`); if invoked by
28
+ natural language, infer it from the request.
29
+
30
+ ## Locations & override rules (read before create/update)
31
+
32
+ - `<workspace>/.halo/skills/<skill-id>/` — workspace-scoped
33
+ - `~/.halo/global/skills/<skill-id>/` — shared across all workspaces
34
+
35
+ A workspace skill **wholly overrides** a global one with the same id — the
36
+ whole folder, SKILL.md plus every resource file. There is NO per-file fallback:
37
+ if the workspace copy lacks a resource file the global one has, that file is
38
+ simply absent. Consequences you must apply:
39
+
40
+ - **Create**: ask (or infer) which scope. Default to **workspace** unless the
41
+ user says "global" / "all workspaces". If the id already exists globally,
42
+ say so — the new workspace folder will shadow the global one here entirely.
43
+ - **Update**: resolve which folder is actually in effect FIRST — workspace
44
+ path if it exists, else global. Edit the live one; never edit global to fix
45
+ behavior in a workspace where a workspace copy shadows it. To customize a
46
+ global skill for one workspace, copy the WHOLE folder to workspace scope
47
+ (including resource files — remember: no per-file fallback), then edit.
48
+ - **Built-in skills** (`agent`, `skill`, `workspace`, `cron`, `acp`, `send-file`,
49
+ `self`, `aws-knowledge`, `nova-web-search`): their global copies are force re-seeded on every server
50
+ start — direct edits to those global files are lost. Customize at workspace
51
+ scope instead.
52
+ - **Disabled state** lives per-workspace in the `disabled_items` DB table, not
53
+ in SKILL.md — creating or editing files never re-enables a disabled skill.
54
+
55
+ ## Create
56
+
57
+ ### Step 1: SKILL.md
58
+
59
+ ```markdown
60
+ ---
61
+ name: <skill-id>
62
+ description: <one-line description; this is what the agent sees in the skill list>
63
+ command: /<slug> # optional: also expose as a slash command
64
+ requiresAccess: <level> # optional: full | workspace | readonly gate
65
+ ---
66
+
67
+ # <Heading>
68
+
69
+ <Detailed instructions for the agent. The frontmatter description tells the
70
+ agent *when* to activate; the body tells it *what to do* once activated.>
71
+ ```
72
+
73
+ Frontmatter fields:
74
+ - `name` — display name in `/help` and the skill list (kebab-case, match the directory)
75
+ - `description` — short hint the agent uses to decide whether to activate
76
+ - `command` (optional) — expose as a slash command users can type
77
+ - `requiresAccess` (optional) — hide from sessions below this access level
78
+ - `verbs` (optional, for object skills) — declared sub-actions; each
79
+ `{ name, builtin?, requiresAccess?, desc? }`. Verbs with `builtin: true` are
80
+ handled by platform code; others fall through to this body via `$1`.
81
+
82
+ ### Resource files (optional)
83
+
84
+ Put extra files in the same skill directory — templates, reference docs,
85
+ scripts. The skill body can `file_read` them on activation. Inlining large
86
+ reference material in the body bloats every activation; sibling files keep the
87
+ body lean and the references on-demand.
88
+
89
+ ### Step 2: Wire it to an agent
90
+
91
+ A skill is only available if an agent's `agent.yaml` lists it under `skills:`:
92
+
93
+ ```yaml
94
+ skills:
95
+ - my-new-skill
96
+ ```
97
+
98
+ If the user doesn't say which agent, add it to `default`.
99
+
100
+ ## Update
101
+
102
+ `file_read` the live SKILL.md (workspace first — see override rules), change
103
+ only what's requested, write back. Don't rewrite untouched sections. If the
104
+ skill declares `verbs`, keep the frontmatter list and any builtin handlers in
105
+ sync (builtin verbs are platform code; only their desc text lives here).
106
+
107
+ ## Writing good skill bodies
108
+
109
+ A skill body's job is to make the activation decision and the execution
110
+ predictable. Three sections cover that:
111
+
112
+ - **When to use this** — what the activation signal looks like, so the agent's
113
+ choice to load the skill is well-founded.
114
+ - **Steps** in execution order — the procedure as the agent will follow it.
115
+ - **Constraints / failure modes** — phrased as consequences ("X breaks Y
116
+ because Z") so the agent can reason about edge cases, not just memorize
117
+ prohibitions.
118
+
119
+ Generic advice ("be helpful", "write good code") duplicates what every agent
120
+ already knows; the skill body's leverage is project-specific or domain-specific
121
+ guidance.
122
+
123
+ ## Patterns that go sideways
124
+
125
+ - Trivial one-liners as skills bloat the activation list and add latency to
126
+ every skill search; inline instructions in the agent's prompt land cleaner
127
+ for small, frequent operations.
128
+ - Skills that duplicate built-in tool behavior (`file_read`, `web_fetch`) add
129
+ an indirection layer with no leverage.
130
+ - Hard-coded paths to specific user files break when the workspace moves or
131
+ gets shared; templating paths keeps the skill portable.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: workspace
3
+ description: Workspace maintenance — set up or tidy the `.halo/` knowledge files (INDEX.md / INSTRUCTIONS.md / memory), or package the workspace config into a shareable zip. Activate when the user asks to set up / organize / clean up the workspace knowledge base, or to share / export the workspace.
4
+ command: /workspace
5
+ verbs:
6
+ # builtin verbs — access is set in code (SUBCOMMAND_ROUTES); shown here for reference
7
+ - { name: info, builtin: true, desc: Show the current workspace }
8
+ - { name: switch, builtin: true, requiresAccess: full, desc: Switch workspace (absolute path) }
9
+ # skill verbs — access enforced from here
10
+ - { name: setup, requiresAccess: workspace, desc: Set up the .halo knowledge files }
11
+ - { name: tidy, requiresAccess: workspace, desc: Tidy/prune the .halo knowledge files }
12
+ - { name: share, requiresAccess: full, desc: Package the workspace config as a shareable zip }
13
+ ---
14
+
15
+ # workspace
16
+
17
+ Workspace maintenance. `info` / `switch` are handled directly by the `/workspace`
18
+ command and never reach here. This body dispatches the skill verbs — the
19
+ requested action is **`$1`** (full args: `$ARGUMENTS`); with natural-language
20
+ activation, infer it from the request.
21
+
22
+ - **`setup`** — first-time knowledge-base setup; **`tidy`** — review & prune an
23
+ existing one. Both follow [setup-tidy.md](setup-tidy.md) (sibling file —
24
+ `file_read` it; `$1` is the mode, and with no `$1` infer: no `.halo/INDEX.md`
25
+ yet → setup, else tidy).
26
+ - **`share`** — stage and zip the workspace's `.halo/` config for sharing.
27
+ Follow [share.md](share.md) (sibling file — `file_read` it; the `stage.py`
28
+ helper lives next to this SKILL.md).
@@ -0,0 +1,265 @@
1
+ # organize-workspace
2
+
3
+ Maintains a workspace's `.halo/` knowledge files (INDEX.md, INSTRUCTIONS.md,
4
+ memory/). The requested mode arrives as **`$1`**:
5
+
6
+ - **`setup`** — first-time setup: interview the user, draft INDEX.md /
7
+ INSTRUCTIONS.md / memory entries from scratch (see Setup mode).
8
+ - **`tidy`** — review what's already there: prune stale entries, reshape
9
+ sections, surface gaps (see Tidy mode).
10
+ - **no `$1`** (natural-language activation) — infer: no `.halo/INDEX.md` yet
11
+ → setup; otherwise tidy.
12
+
13
+ ## Step 0 — Verify mode against disk
14
+
15
+ `file_read .halo/INDEX.md`. If it exists with substantive content, tidy is the
16
+ right mode; if missing or trivially empty, setup is. If this contradicts the
17
+ requested `$1` (e.g. `/workspace setup` on an already-initialized workspace), say so
18
+ and confirm before overwriting anything.
19
+
20
+ INSTRUCTIONS.md existing alone (without INDEX.md) still means setup — init the
21
+ index, leave instructions as-is unless the user asks otherwise.
22
+
23
+ ---
24
+
25
+ ## Setup mode
26
+
27
+ ### 1. Look before you ask
28
+
29
+ A barrage of questions up front duplicates what the README and code already
30
+ state. Reading the project for 1–2 minutes first lets the questions you do
31
+ ask focus on what's genuinely missing:
32
+
33
+ - `file_read README.md` (try variants — README, Readme, readme)
34
+ - `file_read package.json` / `Cargo.toml` / `pyproject.toml` / `go.mod` (identify language and stack)
35
+ - `file_list .` (see top-level layout)
36
+ - If there's a `docs/` or `.halo/docs/`, glance through it
37
+
38
+ Then tell the user what you saw: a one-sentence project summary + the stack you identified.
39
+
40
+ ### 2. Ask a few targeted questions
41
+
42
+ Based on what you saw, fill in the blanks — do not ask for things the README already states. Only ask what will actually shape INSTRUCTIONS.md / INDEX.md:
43
+
44
+ - **One-line description**: if the README doesn't spell it out, ask "what is this project trying to do?"
45
+ - **Preferences and conventions**: any required coding style, naming conventions, test requirements, review focus?
46
+ - **Gotchas**: anywhere that's easy to mess up (an API that only works in a specific environment, a migration with ordering dependencies, etc.)
47
+ - **Docs organization**: how is `docs/` structured (see default layout below)?
48
+
49
+ 2–4 questions total. A checklist of every possible field reads as homework
50
+ and slows the conversation; the targeted few catch what matters.
51
+
52
+ ### 3. Draft INDEX.md
53
+
54
+ Skeleton:
55
+
56
+ ```markdown
57
+ # <Project Name>
58
+
59
+ ## Overview
60
+
61
+ <1–3 sentences: what this does + who it's for. Match the README's tone.>
62
+
63
+ ## Tech Stack
64
+
65
+ - <main language + primary framework>
66
+ - <other key dependencies: DB, queue, cloud services>
67
+ - <build / package manager>
68
+ - <deployment shape: Docker / Serverless / bare metal / etc.>
69
+
70
+ ## Docs Layout
71
+
72
+ <If the user doesn't have a docs/ structure yet, recommend the default below. If the project has its own structure, reflect that instead.>
73
+
74
+ - [guide/](docs/guide/) — user manual (end-user perspective)
75
+ - [requirements/](docs/requirements/) — product requirements (by module)
76
+ - [design/](docs/design/) — architecture / protocols / data flow
77
+ - [dev/](docs/dev/) — APIs, tools, deployment, environment
78
+ - [test/](docs/test/) — test cases
79
+ - [plans/](docs/plans/) — WIP proposals and open issues
80
+
81
+ ## Memory
82
+
83
+ Important items (architecture decisions, pitfalls, non-obvious trade-offs) are logged in [memory/](memory/) by date, filename `YYYY-MM-DD-topic.md`. Not auto-injected — `file_read` on demand. Threshold for writing: things that will affect future decisions; skip trivial bug fixes.
84
+ ```
85
+
86
+ **About the docs/ layout**: imposing the template structure on a project that
87
+ has its own creates friction without adding clarity. Reflecting the actual
88
+ structure keeps the index useful. The `memory/` section earns its spot in
89
+ every layout.
90
+
91
+ ### 4. Draft INSTRUCTIONS.md
92
+
93
+ Skeleton:
94
+
95
+ ```markdown
96
+ # <Project Name>
97
+
98
+ <One-line project summary. OK to duplicate INDEX.md.>
99
+
100
+ ## Coding Conventions
101
+
102
+ <Distilled from the user's answers, or inferred from existing code. Generic conventions duplicate what every agent already knows; project-specific notes are the only leverage point — only write what's specific to this project>
103
+ - <e.g. TS strict, camelCase, log format [Module] msg>
104
+ - <e.g. React function components + Tailwind + shadcn/ui>
105
+
106
+ ## Coding Principles
107
+
108
+ <If the user mentioned any. Skip this section if not.>
109
+
110
+ ## Important Notes
111
+
112
+ <Distilled from the user's answers. Things like "persistence operations can't rely on in-memory state", "changing API signatures requires checking all callers". The pitfalls they've hit are the most valuable content here>
113
+
114
+ ## Collaboration Style
115
+
116
+ <How the agent should work with them: when to push back, when to ask proactively, when to just do it>
117
+ ```
118
+
119
+ Generic advice ("write elegant code", "add tests") duplicates what's already
120
+ in the agent's base instructions. INSTRUCTIONS.md earns attention with
121
+ constraints **specific to this project only**.
122
+
123
+ **Sub-directory INSTRUCTIONS (optional).** A sub-tree can carry its own
124
+ `<subdir>/.halo/INSTRUCTIONS.md` for rules that apply only to work *inside* it.
125
+ When a sub-agent is spawned with `working_dir` pointing there, the
126
+ directory-chain files (outer → inner) ride in its system prompt every turn,
127
+ layered **after** the root/global instructions — additive, never a replacement,
128
+ so the order reads general → specific. Only suggest this when a sub-tree
129
+ genuinely has its own conventions (e.g. a `packages/foo/` on a different stack);
130
+ for a single-convention project the root file alone is enough.
131
+
132
+ ### 5. Show drafts, then decide whether to write
133
+
134
+ Showing both drafts **in the message** before any `file_write` lets the user
135
+ revise without disk churn. Typical feedback:
136
+
137
+ - "this section is wrong, change it to X" → revise
138
+ - "good enough, write it" → `file_write` to `.halo/INDEX.md` and `.halo/INSTRUCTIONS.md`
139
+ - "I'll edit it myself" → keep iterating on the draft in chat; the user wants the file under their own hand at write time
140
+
141
+ ### 6. Seed memory/ (optional)
142
+
143
+ If the interview surfaced any "legacy gotchas" or "key decisions", offer to store them as individual memory entries:
144
+
145
+ ```markdown
146
+ # <topic>
147
+
148
+ ## Background
149
+ <the situation at the time>
150
+
151
+ ## Decision
152
+ <what approach was chosen>
153
+
154
+ ## Why Not the Alternatives
155
+ <other options and why they were dropped>
156
+
157
+ ## Pitfalls
158
+ <conditions under which this decision bites back>
159
+ ```
160
+
161
+ Filename `YYYY-MM-DD-<topic-slug>.md` (e.g. `2026-04-28-session-id-format.md`). One to three entries is plenty — no need for a full audit on day one.
162
+
163
+ ### 7. Wrap up
164
+
165
+ Tell the user:
166
+
167
+ - These files auto-inject into new sessions (INSTRUCTIONS.md and INDEX.md), effective on the next conversation
168
+ - memory/ is read on demand — you (the agent) will `file_read` relevant entries when needed
169
+ - Future requests like "record this decision" / "update the INDEX" / "tidy this up" just need a plain-language ask
170
+
171
+ ---
172
+
173
+ ## Tidy mode
174
+
175
+ The workspace already has an INDEX.md. Restarting from scratch would
176
+ discard the user's prior organization decisions; review mode preserves
177
+ that intent — surface what's drifted, let the user steer the cleanup.
178
+
179
+ ### 1. Take stock
180
+
181
+ Read in this order:
182
+
183
+ - `file_read .halo/INDEX.md`
184
+ - `file_read .halo/INSTRUCTIONS.md` (if it exists)
185
+ - `file_list .halo/memory` (if it exists; just file names + size, not contents)
186
+ - `file_list .halo/docs` (if it exists; one level deep)
187
+
188
+ Skim the INDEX. For every `[text](docs/...)` link that points into the workspace, sanity-check it's still there (`file_read` of the target — or `file_list` of the parent dir if the link is to a directory). Note the broken or empty ones.
189
+
190
+ ### 2. Spot the drift
191
+
192
+ Common things to surface:
193
+
194
+ - **Broken links**: INDEX entries pointing to docs that no longer exist or are now empty.
195
+ - **Stale memory/**: entries older than ~3 months whose topic is no longer relevant (a decision that's been superseded, a pitfall that was fixed). Auto-detecting staleness over-reaches — the dates and titles are evidence, but the call belongs to the user.
196
+ - **Missing index entries**: docs that exist on disk but aren't linked from INDEX.md. List them and ask whether they belong.
197
+ - **Section bloat**: an INSTRUCTIONS.md section that's grown into a wall of mixed-priority bullets. Suggest splitting or distilling.
198
+ - **Conflicting rules**: two bullets in INSTRUCTIONS.md that pull in opposite directions (e.g. "always run tests" + a later "skip tests for one-line fixes").
199
+ - **Generic fluff** in INSTRUCTIONS.md ("write elegant code", "follow best practices") — gently flag, ask if the user wants it gone.
200
+
201
+ ### 3. Report a punch list, then ask what to tackle
202
+
203
+ A full-rewrite proposal feels like more work to the user than they
204
+ signed up for. A structured punch list lets them pick what's worth
205
+ tackling:
206
+
207
+ ```
208
+ INDEX.md:
209
+ • 2 broken links (docs/old-protocol.md, docs/dev/foo.md → both deleted)
210
+ • 4 docs on disk not in the index (docs/dev/api.md, docs/design/auth.md, …)
211
+ • Section "Memory" still references the format from a year ago
212
+
213
+ INSTRUCTIONS.md:
214
+ • "Coding Principles" section grown to 18 bullets — candidate for distillation
215
+ • Conflicting rules: "always run tests" (line 23) vs "skip tests for trivial edits" (line 41)
216
+
217
+ memory/:
218
+ • 7 entries older than 3 months — anything obsolete?
219
+ • 2025-12-01-bedrock-streaming.md and 2026-04-28-session-id-format.md cover overlapping ground
220
+ ```
221
+
222
+ Then ask: *"What do you want to tackle? (any subset, or all of it)"*. Wait for the user to pick. They might say "fix the broken links and ignore the rest" — that's fine, do exactly that.
223
+
224
+ ### 4. Apply the changes the user picked
225
+
226
+ For each chosen item:
227
+
228
+ - **Broken / missing INDEX entries** — `file_edit` INDEX.md, removing dead links and adding the missing ones (after asking which section they belong in).
229
+ - **Distill an INSTRUCTIONS section** — propose the rewrite in the chat first; auto-writing locks in misalignment before the user can catch it. Apply on confirmation.
230
+ - **Stale memory/** — for each candidate, show date + title + first paragraph; let the user say keep / archive / delete. Archive = move into `.halo/memory/archive/` (create the dir if needed). Delete = `shell_exec rm`.
231
+ - **Merge overlapping memory entries** — read both, propose a merged version with the older filename retired into archive.
232
+
233
+ ### 5. Stay in review mode
234
+
235
+ When the user's ask is "tidy this up", rewriting INDEX.md from the README
236
+ or restaging the docs/ structure is init-mode work — it overwrites their
237
+ existing organization. The review-and-prune lane respects what they
238
+ already built. A full rewrite happens only when they explicitly ask for
239
+ one.
240
+
241
+ ### 6. Wrap up
242
+
243
+ Summarize what changed (files edited, memory archived/deleted) and remind them:
244
+
245
+ - INDEX.md / INSTRUCTIONS.md changes are effective on the next conversation
246
+ - Archived memory/ entries are still searchable via `file_read`, just not surfaced by default
247
+
248
+ ---
249
+
250
+ ## Patterns that go sideways (both modes)
251
+
252
+ - Asking the user about facts already in the README — duplicates content
253
+ they expect you to read.
254
+ - Generic template fluff ("write good comments", "use TDD") — every agent
255
+ already knows it; project-specific notes are the only leverage point.
256
+ - `file_write` on INDEX.md / INSTRUCTIONS.md while drafts are still in flux
257
+ — locks in misalignment that's cheap to fix in chat but expensive to fix
258
+ on disk.
259
+ - Triggering this flow during casual browsing (user poking around /tmp or
260
+ someone else's repo) — they're not in setup mode, so the skill drives
261
+ past their actual ask.
262
+ - Auto-deletion of memory/ entries — erases context the user may need
263
+ later; confirming preserves the recovery option.
264
+ - Organize mode rewriting things outside the user's ask — turns a
265
+ pruning task into a review of unrelated changes.