@agimon-ai/doompi 0.0.1-alpha.13 → 0.0.1-alpha.15

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 (268) hide show
  1. package/README.md +143 -496
  2. package/dist/adapters/bootstrapClaim.cjs +2 -0
  3. package/dist/adapters/bootstrapClaim.cjs.map +1 -0
  4. package/dist/adapters/bootstrapClaim.mjs +2 -0
  5. package/dist/adapters/bootstrapClaim.mjs.map +1 -0
  6. package/dist/adapters/bootstrapLocator.cjs +1 -1
  7. package/dist/adapters/bootstrapLocator.cjs.map +1 -1
  8. package/dist/adapters/bootstrapLocator.d.cts.map +1 -1
  9. package/dist/adapters/bootstrapLocator.d.mts.map +1 -1
  10. package/dist/adapters/bootstrapLocator.mjs +1 -1
  11. package/dist/adapters/bootstrapLocator.mjs.map +1 -1
  12. package/dist/adapters/compatibility/antigravity.cjs +1 -1
  13. package/dist/adapters/compatibility/antigravity.mjs +1 -1
  14. package/dist/adapters/compatibility/codex.cjs +1 -1
  15. package/dist/adapters/compatibility/codex.mjs +1 -1
  16. package/dist/adapters/compatibility/process.cjs +1 -1
  17. package/dist/adapters/compatibility/process.mjs +1 -1
  18. package/dist/adapters/compatibilityContext.cjs +1 -1
  19. package/dist/adapters/compatibilityContext.mjs +1 -1
  20. package/dist/adapters/composer.cjs +1 -1
  21. package/dist/adapters/composer.cjs.map +1 -1
  22. package/dist/adapters/composer.mjs +1 -1
  23. package/dist/adapters/composer.mjs.map +1 -1
  24. package/dist/adapters/compositionState.cjs +1 -1
  25. package/dist/adapters/compositionState.cjs.map +1 -1
  26. package/dist/adapters/compositionState.d.cts.map +1 -1
  27. package/dist/adapters/compositionState.d.mts.map +1 -1
  28. package/dist/adapters/compositionState.mjs +1 -1
  29. package/dist/adapters/compositionState.mjs.map +1 -1
  30. package/dist/adapters/deferredSkills.cjs +4 -4
  31. package/dist/adapters/deferredSkills.cjs.map +1 -1
  32. package/dist/adapters/deferredSkills.mjs +4 -4
  33. package/dist/adapters/deferredSkills.mjs.map +1 -1
  34. package/dist/adapters/doomPackage.cjs +2 -0
  35. package/dist/adapters/doomPackage.cjs.map +1 -0
  36. package/dist/adapters/doomPackage.mjs +2 -0
  37. package/dist/adapters/doomPackage.mjs.map +1 -0
  38. package/dist/adapters/extensionCompiler.cjs +2 -2
  39. package/dist/adapters/extensionCompiler.cjs.map +1 -1
  40. package/dist/adapters/extensionCompiler.mjs +2 -2
  41. package/dist/adapters/extensionCompiler.mjs.map +1 -1
  42. package/dist/adapters/harnessContext.cjs +1 -1
  43. package/dist/adapters/harnessContext.cjs.map +1 -1
  44. package/dist/adapters/harnessContext.mjs +1 -1
  45. package/dist/adapters/matrixSwitcher.cjs +1 -1
  46. package/dist/adapters/matrixSwitcher.mjs +1 -1
  47. package/dist/adapters/mcpFilter.cjs +2 -2
  48. package/dist/adapters/mcpFilter.mjs +2 -2
  49. package/dist/adapters/modules/moduleResolution.cjs +1 -1
  50. package/dist/adapters/modules/moduleResolution.cjs.map +1 -1
  51. package/dist/adapters/modules/moduleResolution.d.cts +27 -15
  52. package/dist/adapters/modules/moduleResolution.d.cts.map +1 -1
  53. package/dist/adapters/modules/moduleResolution.d.mts +27 -15
  54. package/dist/adapters/modules/moduleResolution.d.mts.map +1 -1
  55. package/dist/adapters/modules/moduleResolution.mjs +1 -1
  56. package/dist/adapters/modules/moduleResolution.mjs.map +1 -1
  57. package/dist/adapters/packageBootstrap.cjs +1 -1
  58. package/dist/adapters/packageBootstrap.cjs.map +1 -1
  59. package/dist/adapters/packageBootstrap.d.cts +1 -1
  60. package/dist/adapters/packageBootstrap.d.cts.map +1 -1
  61. package/dist/adapters/packageBootstrap.d.mts +1 -1
  62. package/dist/adapters/packageBootstrap.d.mts.map +1 -1
  63. package/dist/adapters/packageBootstrap.mjs +1 -1
  64. package/dist/adapters/packageBootstrap.mjs.map +1 -1
  65. package/dist/adapters/piExtensionAlias.cjs +1 -1
  66. package/dist/adapters/piExtensionAlias.cjs.map +1 -1
  67. package/dist/adapters/piExtensionAlias.mjs +1 -1
  68. package/dist/adapters/piExtensionAlias.mjs.map +1 -1
  69. package/dist/adapters/piSettings.cjs +1 -1
  70. package/dist/adapters/piSettings.cjs.map +1 -1
  71. package/dist/adapters/piSettings.d.cts +13 -12
  72. package/dist/adapters/piSettings.d.cts.map +1 -1
  73. package/dist/adapters/piSettings.d.mts +13 -12
  74. package/dist/adapters/piSettings.d.mts.map +1 -1
  75. package/dist/adapters/piSettings.mjs +1 -1
  76. package/dist/adapters/piSettings.mjs.map +1 -1
  77. package/dist/adapters/projectPiSettings.cjs +2 -0
  78. package/dist/adapters/projectPiSettings.cjs.map +1 -0
  79. package/dist/adapters/projectPiSettings.d.cts +29 -0
  80. package/dist/adapters/projectPiSettings.d.cts.map +1 -0
  81. package/dist/adapters/projectPiSettings.d.mts +29 -0
  82. package/dist/adapters/projectPiSettings.d.mts.map +1 -0
  83. package/dist/adapters/projectPiSettings.mjs +2 -0
  84. package/dist/adapters/projectPiSettings.mjs.map +1 -0
  85. package/dist/adapters/repository/repository.cjs +1 -1
  86. package/dist/adapters/repository/repository.mjs +1 -1
  87. package/dist/adapters/resourceCollector.cjs +2 -2
  88. package/dist/adapters/resourceCollector.mjs +2 -2
  89. package/dist/adapters/serialization/json.cjs +1 -1
  90. package/dist/adapters/serialization/json.mjs +1 -1
  91. package/dist/adapters/skillCatalog.cjs +1 -1
  92. package/dist/adapters/skillCatalog.mjs +1 -1
  93. package/dist/adapters/skillSources.cjs +1 -1
  94. package/dist/adapters/skillSources.mjs +1 -1
  95. package/dist/adapters/startupPrecompiler.cjs +2 -0
  96. package/dist/adapters/startupPrecompiler.cjs.map +1 -0
  97. package/dist/adapters/startupPrecompiler.d.cts +13 -0
  98. package/dist/adapters/startupPrecompiler.d.cts.map +1 -0
  99. package/dist/adapters/startupPrecompiler.d.mts +13 -0
  100. package/dist/adapters/startupPrecompiler.d.mts.map +1 -0
  101. package/dist/adapters/startupPrecompiler.mjs +2 -0
  102. package/dist/adapters/startupPrecompiler.mjs.map +1 -0
  103. package/dist/adapters/syncState.cjs +1 -1
  104. package/dist/adapters/syncState.cjs.map +1 -1
  105. package/dist/adapters/syncState.d.cts +23 -3
  106. package/dist/adapters/syncState.d.cts.map +1 -1
  107. package/dist/adapters/syncState.d.mts +23 -3
  108. package/dist/adapters/syncState.d.mts.map +1 -1
  109. package/dist/adapters/syncState.mjs +1 -1
  110. package/dist/adapters/syncState.mjs.map +1 -1
  111. package/dist/adapters/syncStateContract.cjs +1 -1
  112. package/dist/adapters/syncStateContract.cjs.map +1 -1
  113. package/dist/adapters/syncStateContract.d.cts +5 -4
  114. package/dist/adapters/syncStateContract.d.cts.map +1 -1
  115. package/dist/adapters/syncStateContract.d.mts +5 -4
  116. package/dist/adapters/syncStateContract.d.mts.map +1 -1
  117. package/dist/adapters/syncStateContract.mjs +1 -1
  118. package/dist/adapters/syncStateContract.mjs.map +1 -1
  119. package/dist/adapters/syncedRuntimeBuilder.cjs +2 -0
  120. package/dist/adapters/syncedRuntimeBuilder.cjs.map +1 -0
  121. package/dist/adapters/syncedRuntimeBuilder.d.cts +11 -0
  122. package/dist/adapters/syncedRuntimeBuilder.d.cts.map +1 -0
  123. package/dist/adapters/syncedRuntimeBuilder.d.mts +11 -0
  124. package/dist/adapters/syncedRuntimeBuilder.d.mts.map +1 -0
  125. package/dist/adapters/syncedRuntimeBuilder.mjs +2 -0
  126. package/dist/adapters/syncedRuntimeBuilder.mjs.map +1 -0
  127. package/dist/commands/buildCommand.cjs +2 -2
  128. package/dist/commands/buildCommand.cjs.map +1 -1
  129. package/dist/commands/buildCommand.d.cts +4 -0
  130. package/dist/commands/buildCommand.d.cts.map +1 -1
  131. package/dist/commands/buildCommand.d.mts +4 -0
  132. package/dist/commands/buildCommand.d.mts.map +1 -1
  133. package/dist/commands/buildCommand.mjs +2 -2
  134. package/dist/commands/buildCommand.mjs.map +1 -1
  135. package/dist/commands/cli/help.cjs +2 -2
  136. package/dist/commands/cli/help.cjs.map +1 -1
  137. package/dist/commands/cli/help.mjs +2 -2
  138. package/dist/commands/cli/help.mjs.map +1 -1
  139. package/dist/commands/compatibilityCommand.cjs +1 -1
  140. package/dist/commands/compatibilityCommand.mjs +1 -1
  141. package/dist/commands/explainCommand.cjs +3 -3
  142. package/dist/commands/explainCommand.mjs +3 -3
  143. package/dist/commands/initCommand.cjs +1 -2
  144. package/dist/commands/initCommand.cjs.map +1 -1
  145. package/dist/commands/initCommand.d.cts +4 -3
  146. package/dist/commands/initCommand.d.cts.map +1 -1
  147. package/dist/commands/initCommand.d.mts +4 -3
  148. package/dist/commands/initCommand.d.mts.map +1 -1
  149. package/dist/commands/initCommand.mjs +1 -2
  150. package/dist/commands/initCommand.mjs.map +1 -1
  151. package/dist/commands/initPresenter.cjs +3 -0
  152. package/dist/commands/initPresenter.cjs.map +1 -0
  153. package/dist/commands/initPresenter.d.cts +8 -0
  154. package/dist/commands/initPresenter.d.cts.map +1 -0
  155. package/dist/commands/initPresenter.d.mts +8 -0
  156. package/dist/commands/initPresenter.d.mts.map +1 -0
  157. package/dist/commands/initPresenter.mjs +3 -0
  158. package/dist/commands/initPresenter.mjs.map +1 -0
  159. package/dist/commands/launchCommand.cjs +1 -1
  160. package/dist/commands/launchCommand.cjs.map +1 -1
  161. package/dist/commands/launchCommand.mjs +1 -1
  162. package/dist/commands/launchCommand.mjs.map +1 -1
  163. package/dist/commands/syncCommand.cjs +5 -5
  164. package/dist/commands/syncCommand.cjs.map +1 -1
  165. package/dist/commands/syncCommand.d.cts +4 -2
  166. package/dist/commands/syncCommand.d.cts.map +1 -1
  167. package/dist/commands/syncCommand.d.mts +4 -2
  168. package/dist/commands/syncCommand.d.mts.map +1 -1
  169. package/dist/commands/syncCommand.mjs +4 -4
  170. package/dist/commands/syncCommand.mjs.map +1 -1
  171. package/dist/config/index.cjs +1 -1
  172. package/dist/config/index.d.cts +2 -2
  173. package/dist/config/index.d.mts +2 -2
  174. package/dist/config/index.mjs +1 -1
  175. package/dist/entries/domains.cjs +1 -1
  176. package/dist/entries/domains.d.cts +2 -2
  177. package/dist/entries/domains.d.mts +2 -2
  178. package/dist/entries/domains.mjs +1 -1
  179. package/dist/entries/doom.cjs +1 -1
  180. package/dist/entries/doom.d.cts +1 -1
  181. package/dist/entries/doom.d.mts +1 -1
  182. package/dist/entries/doom.mjs +1 -1
  183. package/dist/entries/modeCatalog.cjs +1 -0
  184. package/dist/entries/modeCatalog.d.cts +2 -0
  185. package/dist/entries/modeCatalog.d.mts +2 -0
  186. package/dist/entries/modeCatalog.mjs +1 -0
  187. package/dist/extensions/entries/cacheOptimizer.mjs +2 -0
  188. package/dist/extensions/entries/cacheOptimizer.mjs.map +1 -0
  189. package/dist/extensions/entries/components/skillsOverlay.cjs +2 -2
  190. package/dist/extensions/entries/components/skillsOverlay.mjs +2 -2
  191. package/dist/extensions/entries/domains.cjs +1 -1
  192. package/dist/extensions/entries/domains.cjs.map +1 -1
  193. package/dist/extensions/entries/domains.d.cts +10 -2
  194. package/dist/extensions/entries/domains.d.cts.map +1 -1
  195. package/dist/extensions/entries/domains.d.mts +10 -2
  196. package/dist/extensions/entries/domains.d.mts.map +1 -1
  197. package/dist/extensions/entries/domains.mjs +1 -1
  198. package/dist/extensions/entries/domains.mjs.map +1 -1
  199. package/dist/extensions/entries/doom.cjs +1 -1
  200. package/dist/extensions/entries/doom.cjs.map +1 -1
  201. package/dist/extensions/entries/doom.d.cts.map +1 -1
  202. package/dist/extensions/entries/doom.d.mts.map +1 -1
  203. package/dist/extensions/entries/doom.mjs +1 -1
  204. package/dist/extensions/entries/doom.mjs.map +1 -1
  205. package/dist/extensions/entries/modeCatalog.cjs +2 -0
  206. package/dist/extensions/entries/modeCatalog.cjs.map +1 -0
  207. package/dist/extensions/entries/modeCatalog.d.cts +7 -0
  208. package/dist/extensions/entries/modeCatalog.d.cts.map +1 -0
  209. package/dist/extensions/entries/modeCatalog.d.mts +7 -0
  210. package/dist/extensions/entries/modeCatalog.d.mts.map +1 -0
  211. package/dist/extensions/entries/modeCatalog.mjs +2 -0
  212. package/dist/extensions/entries/modeCatalog.mjs.map +1 -0
  213. package/dist/extensions/entries/styleSystem.cjs +2 -2
  214. package/dist/extensions/entries/styleSystem.mjs +2 -2
  215. package/dist/extensions/services/domainSwitchHandoff.cjs +2 -0
  216. package/dist/extensions/services/domainSwitchHandoff.cjs.map +1 -0
  217. package/dist/extensions/services/domainSwitchHandoff.mjs +2 -0
  218. package/dist/extensions/services/domainSwitchHandoff.mjs.map +1 -0
  219. package/dist/index.cjs +1 -1
  220. package/dist/index.d.cts +6 -4
  221. package/dist/index.d.mts +6 -4
  222. package/dist/index.mjs +1 -1
  223. package/dist/pi-cache-optimizer-D9beVnnH.mjs +50 -0
  224. package/dist/pi-cache-optimizer-D9beVnnH.mjs.map +1 -0
  225. package/dist/schemas/domainVoiceTools.cjs +2 -0
  226. package/dist/schemas/domainVoiceTools.cjs.map +1 -0
  227. package/dist/schemas/domainVoiceTools.mjs +2 -0
  228. package/dist/schemas/domainVoiceTools.mjs.map +1 -0
  229. package/dist/services/config/index.d.cts +2 -2
  230. package/dist/services/config/index.d.mts +2 -2
  231. package/dist/services/config/index.mjs +1 -1
  232. package/dist/services/extensionAssembler.cjs +1 -1
  233. package/dist/services/extensionAssembler.cjs.map +1 -1
  234. package/dist/services/extensionAssembler.d.cts +8 -4
  235. package/dist/services/extensionAssembler.d.cts.map +1 -1
  236. package/dist/services/extensionAssembler.d.mts +8 -4
  237. package/dist/services/extensionAssembler.d.mts.map +1 -1
  238. package/dist/services/extensionAssembler.mjs +1 -1
  239. package/dist/services/extensionAssembler.mjs.map +1 -1
  240. package/dist/services/index.cjs +1 -1
  241. package/dist/services/index.d.cts +4 -2
  242. package/dist/services/index.d.mts +4 -2
  243. package/dist/services/index.mjs +1 -1
  244. package/dist/services/modeCatalog.cjs +2 -0
  245. package/dist/services/modeCatalog.cjs.map +1 -0
  246. package/dist/services/modeCatalog.d.cts +18 -0
  247. package/dist/services/modeCatalog.d.cts.map +1 -0
  248. package/dist/services/modeCatalog.d.mts +18 -0
  249. package/dist/services/modeCatalog.d.mts.map +1 -0
  250. package/dist/services/modeCatalog.mjs +2 -0
  251. package/dist/services/modeCatalog.mjs.map +1 -0
  252. package/dist/services/piSettings.cjs +1 -1
  253. package/dist/services/piSettings.d.cts +2 -2
  254. package/dist/services/piSettings.d.mts +2 -2
  255. package/dist/services/piSettings.mjs +1 -1
  256. package/dist/services/syncState.cjs +1 -1
  257. package/dist/services/syncState.d.cts +2 -2
  258. package/dist/services/syncState.d.mts +2 -2
  259. package/dist/services/syncState.mjs +1 -1
  260. package/dist/utils/index.cjs +1 -1
  261. package/dist/utils/index.d.cts +2 -2
  262. package/dist/utils/index.d.mts +2 -2
  263. package/dist/utils/index.mjs +1 -1
  264. package/dist/utils/moduleResolution.cjs +1 -1
  265. package/dist/utils/moduleResolution.d.cts +2 -2
  266. package/dist/utils/moduleResolution.d.mts +2 -2
  267. package/dist/utils/moduleResolution.mjs +1 -1
  268. package/package.json +30 -18
package/README.md CHANGED
@@ -2,13 +2,23 @@
2
2
 
3
3
  **A coding agent that loads only the skills and tools you name.**
4
4
 
5
- Plugin systems scope what an agent knows. Nothing scopes what it can reach. Claude Code
6
- gives you `enableAllProjectMcpServers` and a static denylist, both repository-wide, so
7
- every session pays for every MCP server's tool schemas whether the task is a database
8
- migration or a landing page.
5
+ > It begins with one useful MCP server. Then another. Soon the agent fixing a heading
6
+ > wakes up with database tools, browser controls, and their small novel of schemas. This
7
+ > is our config.
9
8
 
10
- Doompi makes both a declared input. Three YAML files decide what a session loads, and
11
- `--explain` prints the bill before you launch.
9
+ Doompi is a configuration framework for [Pi](https://github.com/earendil-works/pi)
10
+ tailored for people whose agent has one MCP server too many. It turns extensions, skills,
11
+ MCP servers, and system prompts into config instead of background noise.
12
+
13
+ Plugin systems scope what an agent knows. Nothing scopes what it can reach. Claude Code's
14
+ `enableAllProjectMcpServers` and static denylist are repository-wide. Doompi draws that
15
+ boundary around the session. Pick a major mode and some domains; add a profile if you want
16
+ one. Three YAML files decide what loads; `doompi --explain` tells you what got in, why, and
17
+ what it costs before launch.
18
+
19
+ It borrows its shape from [Doom Emacs Core](https://github.com/doomemacs/core): quick to
20
+ start, close to Pi, opinionated where defaults help, and easy to pull apart when they do
21
+ not. Use it as-is, build your own config on top, or raid it for parts.
12
22
 
13
23
  ## Install
14
24
 
@@ -25,8 +35,11 @@ doompi --explain # what would load, and why
25
35
  doompi # start a session
26
36
  ```
27
37
 
28
- `.doom/` is committed to git, so a checkout carries its own agent configuration. Edit a
29
- YAML file and the next launch picks it up.
38
+ `doompi init` is the one machine-wide step. It seeds `~/.pi/.doom`; copy those files into
39
+ a repository when the repository needs its own agent. Commit `.doom/`. Now the config
40
+ follows the code instead of living in someone's shell history.
41
+
42
+ Flags override the defaults for one session:
30
43
 
31
44
  ```bash
32
45
  doompi --major-mode dev --domains development
@@ -34,342 +47,80 @@ doompi --domains marketing --profile marketing
34
47
  doompi --domains analytics --explain
35
48
  ```
36
49
 
37
- ## The three axes
38
-
39
- Doompi wraps [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) and
40
- resolves a declared configuration into a session rather than asking you to wire one up.
41
- The three choices are independent: adding a domain requires no knowledge of major modes,
42
- and swapping a profile changes nothing about either.
43
-
44
- | Choice | Decides | Declared in |
45
- | -------------- | ------------------------------------ | --------------------- |
46
- | **Major mode** | what the agent is wrapped in | `.doom/modes.yaml` |
47
- | **Domains** | what it knows, and what it can reach | `.doom/domains.yaml` |
48
- | **Profile** | who it speaks as | `.doom/profiles.yaml` |
49
-
50
- A domain names plugins and an MCP allowlist together, so `--domains marketing` and
51
- `--domains development` are the same agent with different knowledge and a different reach,
52
- not two different agents. That is the lever for keeping context small, and
53
- [`--explain`](#minimal-context) prices it before you commit.
54
-
55
- ## What is actually different
56
-
57
- **Compaction reads state, it does not summarize prose.** When the context fills, Doompi
58
- does not guess at coordination state from the transcript. It reads the live plan, task
59
- graph, and team snapshot, and commits them next to the summary as authoritative. The agent
60
- comes out the other side knowing what it was doing, what is still running, and who is doing
61
- what. See [Long runs](#long-runs).
62
-
63
- **Spec-driven and meta-prompting systems change what the agent is told. Doompi changes what
64
- it loads.** The two compose fine. This one is about the context window, not the prompt.
65
-
66
- **One configuration serves two readers.** A human gets a keyboard surface that does not
67
- move; an autonomous agent gets a small tool surface and a context window that compacts
68
- itself.
69
-
70
50
  ## Philosophy
71
51
 
72
- **Give the agent fewer things to choose between.** [Major modes, domains, and
73
- profiles](#major-modes-domains-profiles) decide what loads, so a session carries the skills
74
- and MCP servers its domains named and nothing else. Whatever still overflows [compacts in
75
- the background](#long-runs).
76
-
77
- **Shift the work onto deterministic workflows.** Autonomous runs are [GitHub Actions
78
- shaped](#workflows), with jobs, dependencies, steps, timeouts, and declared artifacts, so
79
- the same job resolves the same way every time.
80
-
81
- **Keep the keyboard ergonomic.** `SPC` is the whole surface, Spacemacs and Doom Emacs
82
- style, and [it opens only when the draft is empty](#leader-space), so a half-written prompt
83
- is never a casualty.
84
-
85
- **Batteries included, without the bloat.** Plan mode, tasks, teams, a supervised runner,
86
- voice, and workflows ship in the box, but [core is not a
87
- layer](#core-is-not-a-layer) and every opinion waits behind a layer or a domain.
88
-
89
- **One major mode, several minor modes.** A session runs under exactly one major mode, which
90
- is what selects its layers. [Plan, loop, and workflow](#minor-modes) are minor modes: you
91
- toggle them mid-session, they stack, and they report themselves on a shared status line.
92
-
93
- ## Two ways to run
94
-
95
- The launcher resolves your three choices per run and spawns Pi with them. Skills, agents,
96
- MCP configs, and the persona prompt are assembled into a temporary directory that is
97
- deleted on exit. Nothing is written back into the repository, and every session pays the
98
- resolution cost.
99
-
100
- `doompi sync` is the other way in, and the Doom Emacs one. Resolve once, write the
101
- result where Pi looks, then run `pi` yourself.
102
-
103
- ```bash
104
- doompi init # seed ~/.pi/.doom, once per machine
105
- doompi build # warm the selected launch bundle and skill cache
106
- doompi sync # resolve the selection into .pi/
107
- pi # the agent
108
-
109
- doompi sync --check # exit non-zero when the synced config is out of date
110
- ```
111
-
112
- A synced session takes `--major-mode`, `--domains`, `--profile`, and `--mute` the same way
113
- the launcher does, and `/mode`, `/domains`, and `/profile` all switch in place: the
114
- extension set is composed on every load rather than frozen at startup, so a reload is
115
- enough.
116
-
117
- Both paths compose the extension set from the same function, `assembleExtensions`, which
118
- owns load order. Two things differ. A synced session forces `--auto-stop` off, and it
119
- reads mute from `DOOMPI_MUTE` instead of an argument.
120
-
121
- `doompi build` is the launcher warm-up step, analogous to `doom build`: it resolves the
122
- selected matrix, compiles its exact extension graph into one `.pi/doom/dist` ESM file,
123
- and warms the persistent skill manifest without starting Pi or changing
124
- `.pi/settings.json`. A sidecar manifest retains every original extension and exact
125
- `SKILL.md` path, so resource discovery never depends on the bundle's location.
126
- Launch still builds on a cache miss, so the command is optional; run it after installing
127
- or upgrading Doom packages when first-input latency matters.
128
-
129
- Syncing does not disturb the launcher. Pi merges the extensions a project declares with
130
- the ones passed on the command line, so the synced entry stands down whenever it sees the
131
- composed set already there, which is what the launcher and every detached subagent pass.
132
-
133
- ## For humans
134
-
135
- ### Leader Space
136
-
137
- `@agimon-ai/doompi-ui` owns the leader state machine, rendering, conflict handling, and the
138
- core bindings.
139
-
140
- Space opens the leader **only when the draft is empty**. With text in the editor, space is
141
- a space. `ctrl+space` opens the leader either way, and the draft survives the sequence, so
142
- you never lose a half-written prompt to a keystroke. That is the space the human keeps.
143
-
144
- Inside a sequence: `escape` cancels, `backspace` pops one segment, and any key that
145
- matches nothing cancels. There is no partial state to get stuck in.
146
-
147
- Core groups. Every level of the map renders in leader-key alphabetical order, so the table
148
- below is the order you see:
149
-
150
- | Key | Group | Bindings |
151
- | --- | --------- | ---------------------------------------- |
152
- | `e` | extension | `e` external editor, `t` tools browser |
153
- | `h` | help | `h` hotkeys, `l` log metrics |
154
- | `m` | models | `m` select, `n` next, `t` thinking level |
155
- | `q` | quit | `q` exit |
156
- | `s` | sessions | `f` fork, `n` new, `r` resume, `t` tree |
157
-
158
- `t` is deliberately left out of core at the root and reserved for doom-task.
159
-
160
- Optional feature extensions own the bindings for their own commands. The UI never
161
- hardcodes a binding for a layer that may not be loaded, so a group appears only while its
162
- extension is loaded:
163
-
164
- | Chord | Source | Opens |
165
- | -------------------- | ----------------------------- | ------------------------------ |
166
- | `SPC a` | `@agimon-ai/doompi-team` | subagent fleet |
167
- | `SPC h l` | `@agimon-ai/doompi-log` | log metrics |
168
- | `SPC l s`, `SPC l l` | `@agimon-ai/doompi-loop` | start loops, list/stop loops |
169
- | `SPC p p/c/d/f` | `@agimon-ai/doompi-plan` | plan normal/cancel/debug/fable |
170
- | `SPC t t` | `@agimon-ai/doompi-task` | tasks |
171
- | `SPC r r` | `@agimon-ai/doompi-runner` | background processes |
172
- | `SPC v v` | `@agimon-ai/doompi-voice` | record or transcribe |
173
- | `SPC w w/l/r` | `@agimon-ai/doompi-workflow` | launch/manage/recover |
174
- | `SPC e f` | `@agimon-ai/doompi-file-edit` | session edits |
175
- | `SPC e s` | `@agimon-ai/doompi` | skills catalog |
176
- | `SPC e c` | `@agimon-ai/doompi-ui` | config panel (core binding) |
177
- | `SPC g s/e/p` | `@agimon-ai/doompi-goal` | start/end/history |
178
-
179
- Contributions go through the public `@agimon-ai/doompi-ui/leader` API:
180
-
181
- ```ts
182
- registerDoomLeaderContribution(pi, {
183
- source: '@agimon-ai/doompi-log',
184
- bindings: [
185
- {
186
- id: 'log.metrics',
187
- path: [
188
- { key: 'h', label: 'help', order: 70 },
189
- { key: 'l', label: 'logs', detail: 'telemetry' },
190
- ],
191
- command: { name: 'log-metrics' },
192
- },
193
- ],
194
- });
195
- ```
196
-
197
- A path excludes the leading `SPC`. The UI turns this into `SPC h l`, dispatches
198
- `/log-metrics` through the normal editor submission path, and preserves the draft. A
199
- binding carries either a `command` descriptor or an `action` name, never both. Commands
200
- stay owned by the extension that registered the slash command; actions route back to the
201
- contributor through `registerDoomLeaderActionHandlers`, which is what doom-plan uses.
202
-
203
- The map is deterministic because the registry is strict:
204
-
205
- - Keys are a single lowercase alphanumeric character, paths are at most four segments.
206
- - Shared group prefixes must agree on label, detail, and order, or the contribution is
207
- rejected.
208
- - Exact chord conflicts are rejected rather than silently overridden. A conflict in a core
209
- binding throws; a conflict from a contributor produces a diagnostic and a warning.
210
- - Re-registering the same `source` replaces that source's complete binding set. Registering
211
- an empty set removes it.
212
- - Rebuilds sort by source name then binding id, so load order does not affect the result.
213
- - Options render in leader-key alphabetical order at every level. A segment's `order` is
214
- group identity that shared prefixes must agree on, not a display position.
215
-
216
- Registration runs over Pi's shared extension event bus with a 250 ms timeout. A timeout is
217
- swallowed, so an extension loaded without the UI degrades quietly instead of failing.
218
-
219
- ### Major modes, domains, profiles
220
-
221
- Three choices, three files, committed to git. They are independent. Adding a domain
222
- requires no knowledge of major modes, and swapping a profile changes nothing about either.
223
-
224
- | Choice | Loads | Declared in |
225
- | --------------- | ------------------------------------- | --------------------- |
226
- | **Major modes** | a named set of layers | `.doom/modes.yaml` |
227
- | **Domains** | plugins, meaning skills and MCP | `.doom/domains.yaml` |
228
- | **Profiles** | a persona and the brand it speaks for | `.doom/profiles.yaml` |
229
-
230
- **Layers are protection and steering.** A layer is a set of Pi extensions plus a set of
231
- hook groups. The extensions add behavior the agent runs with; the hooks fire around its
232
- tool calls and can block it, warn it, or steer it back. You define the set you want, along
233
- the lines of `guardrails`, `lint`, `code-intel`, `team`, `plan-mode`, `runner`, and
234
- `ask-user`. The hooks themselves live in `.doom/hooks.yaml`, one registry shared by every
235
- frontend, where a group is either `core` and always loads, or is pulled in by whichever
236
- layer wants it.
237
-
238
- **A major mode is the one you actually pick.** You do not assemble layers one by one at the
239
- prompt. You select one named major mode with `--major-mode <name>`, and
240
- `.doom/modes.yaml` says which layers it contains. A session has exactly one, the way
241
- an Emacs buffer has exactly one major mode. The file can choose the fallback without
242
- renaming that mode:
243
-
244
- ```yaml
245
- defaultMajorMode: minimal
246
- majorMode:
247
- minimal: [guardrails, team]
248
- copilot: [guardrails, team, plan-mode, runner]
249
- ```
250
-
251
- An explicit `--major-mode` wins, then `DOOMPI_MAJOR_MODE`, then
252
- `defaultMajorMode`. Omitting the field preserves the compatible `copilot` fallback.
253
-
254
- The flag is `--major-mode` and not `--mode` because Pi already owns `--mode` for its output
255
- mode (`text`, `json`, `rpc`), and for any other value it consumes the argument and ignores
256
- it without a diagnostic. Use `--output-format` for Pi's output mode.
257
-
258
- **Domains are plugins, and a plugin is skills plus MCP.** Selecting a domain decides which
259
- plugins contribute their skills and subagents, which MCP servers the session can reach,
260
- and whether the always-on shared skills apply. A domain can take a whole plugin or a named
261
- subset of one. This is the choice that decides how much the agent can see, so it is also
262
- the lever for keeping context small. Defaults are plural because domains compose:
263
-
264
- ```yaml
265
- defaultDomains: [development, qa]
266
- domains:
267
- development:
268
- plugins: [plugins/development]
269
- qa:
270
- plugins: [plugins/qa]
271
- ```
272
-
273
- Explicit `--domain` or `--domains` flags win, then `DOOMPI_DOMAINS`, then
274
- `defaultDomains`.
52
+ An agent does not need every tool for every job. Doompi separates the base session from
53
+ the things you switch on for a while: modes choose behavior, domains choose subject
54
+ matter, and profiles choose a point of view.
275
55
 
276
- **Profiles are a persona and a brand.** `.doom/profiles.yaml` points at a directory under
277
- `agents/<brand>/<person>/`, and doom concatenates that person's `profile.md`, `SOUL.md`,
278
- and `AGENTS.md` into the system prompt: identity and the brand it represents, then voice,
279
- then role and rules. A profile also carries environment defaults, and nothing else. It
280
- cannot select domains, major modes, models, presets, or policy, and an exported value
281
- always beats a profile default.
56
+ ### Major and minor modes
282
57
 
283
- Switching is live. `/mode`, `/domains`, and `/profile` re-resolve into the running
284
- session and reload. A domain or profile switch always applies in place. A major mode switch
285
- applies in place too unless the new mode changes which extension packages load, since Pi
286
- freezes the `--extension` set at construction; the picker tells you when a relaunch is
287
- needed.
58
+ A major mode is the base config. It names the extension layers for development, marketing,
59
+ or whatever else you do. Define as many as you like; only one is active at a time, and you
60
+ can switch it without leaving the session.
288
61
 
289
- ### Minor modes
62
+ Minor modes are switches inside that base. They start off, stack freely, and bring their
63
+ own tools and instructions when turned on. Doompi ships five:
290
64
 
291
- A major mode is chosen once per session and selects layers. Minor modes are the opposite:
292
- you toggle them while the session runs, several can be on at once, and none of them changes
293
- which extensions are loaded.
65
+ - **Plan mode** make the repository read-only while you agree on an approach.
66
+ - **Loop mode** run a prompt now, then run it again on a schedule.
67
+ - **Goal mode** — keep one objective in view until it is done or dismissed.
68
+ - **Workflow mode** — run jobs with dependencies, timeouts, and artifacts.
69
+ - **Voice mode** — replace typing with local speech.
294
70
 
295
- | Minor mode | Toggle | Owned by |
296
- | ---------- | -------------------- | ---------------------------- |
297
- | goal | `/goal`, `SPC g` | `@agimon-ai/doompi-goal` |
298
- | plan | `/plan`, `SPC p` | `@agimon-ai/doompi-plan` |
299
- | loop | `/loop`, `SPC l` | `@agimon-ai/doompi-loop` |
300
- | workflow | `/workflow`, `SPC w` | `@agimon-ai/doompi-workflow` |
71
+ ### Domains
301
72
 
302
- Goal is assembled in `minimal`, `copilot`, custom major modes, and detached children rather
303
- than selected by a layer. It starts dormant: `/goal` is available, but its tools, system
304
- prompt, automatic continuation, and `GOAL` status stay off until an objective is accepted
305
- or an active Goal is restored. Paused, blocked, limited, and queue-waiting Goals retain the
306
- status item without retaining execution capabilities. Parent hosts load the Doom entry;
307
- detached children load the UI-independent Pi entry.
73
+ A domain is a named group of Pi plugins. It carries the skills and MCP servers for one
74
+ kind of work, and `/domains` switches it while the session is running.
308
75
 
309
- Each enabled minor mode publishes a label to a shared `MODES` line rather than painting a
310
- row of its own. The registry is `@agimon-ai/doompi-extension-contracts/mode`.
76
+ A blog is not one task. Research it, draft it, make the assets, then review it. Turn on the
77
+ `visual` domain while making assets; the other three steps have no reason to carry it.
311
78
 
312
- Existing `pi-goal.json` files remain readable. Both legacy `toolVisibility` values now mean
313
- that Goal tools are managed only while execution is operational; neither exposes tools in
314
- a dormant session. `experimental.goals` controls queues only.
79
+ ### Profile
315
80
 
316
- If an edited `modes.yaml` still defines or selects a Goal layer, remove that definition and
317
- its major-mode references, then run `doompi sync`. Normal `doompi init` preserves edited
318
- files. `doompi init --force` is a full template reset and may overwrite unrelated edits.
81
+ An LLM has no house style until you give it one. A profile can supply a narrative, brand
82
+ rules, or a different voice. It is optional; no profile is a perfectly good profile.
319
83
 
320
- ## For autonomous agents
84
+ ## What this buys you
321
85
 
322
- ### Minimal context
86
+ Every tool schema and skill name competes for the same context. Loading less has two
87
+ immediate effects:
323
88
 
324
- Fewer options, better choices. Domains cut the skill list and the tool list together. A
325
- domain that names three plugins gives the agent those plugins' skills and nothing else,
326
- and one with an `mcp` allowlist reaches only the servers and proxy upstreams it names.
89
+ 1. You spend fewer tokens before the work begins.
90
+ 2. The model has fewer plausible-but-wrong tools and skills to choose from.
327
91
 
328
- `--explain` prints what any combination costs before you launch it, and ends with the bill:
92
+ The savings get larger when each workflow job starts with its own config instead of
93
+ inheriting the last job's toolbox.
329
94
 
330
- ```
331
- $ doompi --domains development --explain
332
- ...
333
- skills: 24 (from 3 directories)
334
-
335
- context cost (tokens)
336
- skills prompt 3,772 always on
337
- persona 0 always on
338
- startup total 3,772
339
- skill bodies 54,145 read on demand
340
-
341
- Excludes MCP tool schemas, which the servers only report once connected,
342
- and skills contributed by extensions, which register after startup.
343
- ```
95
+ ### Copilot
344
96
 
345
- Every figure comes from files on disk, so two runs of the same selection print the same
346
- numbers and you can reproduce them on your own repository rather than trusting these.
97
+ I got tired of remembering slash commands, so `SPC` is the map. It opens only when the
98
+ draft is empty; a space in the middle of a prompt remains a space. Press it, read the
99
+ choices, then press the next key.
347
100
 
348
- MCP tool schemas are the one cost this cannot price. They exist only after a server
349
- connects, and pricing them would mean spawning every configured server on a command meant
350
- to be instant. Scoping them is still a declared choice; the saving is just not counted here.
101
+ When the keyboard is the wrong tool, autonomous Voice mode keeps the conversation going.
102
+ You can talk to the agent while doing the chores instead of carrying a laptop around the
103
+ house.
351
104
 
352
- A domain without an `mcp` key admits everything, and one unscoped domain in the selection
353
- unfilters the rest. Scoping applies only when every selected domain declares it.
105
+ ### Autopilot
354
106
 
355
- A domain can also take a named subset of one plugin's skills, by name or glob.
107
+ Copilot helps while you are present. Loop and Workflow keep work moving when you are not.
108
+ Together they can dispatch structured jobs from one live session.
356
109
 
357
- ### Workflows
110
+ #### Workflows
358
111
 
359
- Long autonomous work runs as workflows, in the shape a GitHub Actions user already knows:
360
- `on:`, `jobs:`, `needs:`, `steps:`, timeouts, and declared artifacts.
361
-
362
- The payoff is that every step names the session it wants. A workflow is where
363
- `--major-mode`, `--domains`, and `--profile` stop being things you type and become part of
364
- the definition, so one run can hand each job exactly the context that job needs and nothing
365
- else:
112
+ GitHub Actions already has a decent vocabulary for long jobs, so Doompi reuses it. Each job
113
+ declares the Doompi session it wants. Here, implementation gets coding tools; the release
114
+ note waits for it and gets marketing context plus a brand voice:
366
115
 
367
116
  ```yaml
117
+ on:
118
+ workflow_dispatch:
119
+
368
120
  jobs:
369
121
  implement:
370
- needs: intake
371
122
  steps:
372
- - name: Implement
123
+ - name: Build the feature
373
124
  timeout-minutes: 180
374
125
  artifacts: [implementation/report.md]
375
126
  interactiveRun:
@@ -377,10 +128,10 @@ jobs:
377
128
  doompi --major-mode dev --domains development --auto-stop \
378
129
  --cwd "$PWD" "$JOB_SYSTEM_PROMPT"
379
130
 
380
- announce:
131
+ release-note:
381
132
  needs: implement
382
133
  steps:
383
- - name: Draft the release note
134
+ - name: Write the release note
384
135
  timeout-minutes: 30
385
136
  artifacts: [marketing/release-note.md]
386
137
  interactiveRun:
@@ -390,211 +141,107 @@ jobs:
390
141
  --cwd "$PWD" "$JOB_SYSTEM_PROMPT"
391
142
  ```
392
143
 
393
- Two jobs, two different agents. `implement` runs under a major mode carrying lint and code
394
- intelligence and a domain carrying coding skills. `announce` drops both, takes a domain
395
- scoped to a handful of MCP servers, and adds a profile, so the release note comes out in a
396
- named persona's voice rather than the agent's own. Neither job can drift into the other's
397
- context, and the same job resolves the same way on every run.
398
-
399
- The one real departure from GitHub Actions is `extends:`, which lets a job inherit shared
400
- setup from a named template rather than repeating it.
401
-
402
- The engine itself is not in this package. `@agimon-ai/doompi-workflow` provides the in-session
403
- surface on `SPC w`, and its dispatcher exposes `list_workflows` to any session but scopes
404
- `launch_workflow` to the root session, so a subagent can look but not spawn. The `workflow`
405
- hook group is `core`, so it loads in any major mode.
406
-
407
- ### Long runs
408
-
409
- Tasks, teams, runners, and compaction share one working state, so a long autonomous run
410
- does not lose its place.
411
-
412
- - **Tasks** (`SPC t`) are a file-backed graph with dependencies and delegation, not a
413
- scratch list.
414
- - **Teams** (`SPC a`) run named subagents asynchronously against that same board,
415
- sequentially or in parallel.
416
- - **Runners** (`SPC r`) replace the bash tool and detach long commands, then reconcile
417
- them afterwards.
418
- - **Compaction** runs on a three-pass ladder in a worker thread, so the session never
419
- blocks on it.
144
+ #### Loop
420
145
 
421
- The integration is the point. When compaction summarizes, it does not guess at
422
- coordination state: it reads the live plan, tasks, and team snapshot, and commits them
423
- next to the summary as authoritative rather than leaving them to be reconstructed from
424
- prose. Detached runners reconcile themselves once the context has been rewritten. The
425
- agent comes out the other side knowing what it was doing, what is still running, and who
426
- is doing what.
146
+ Workflow definitions are exposed like skills, so the agent can choose one for the job. A
147
+ loop can send a subagent to fetch the next task, then dispatch the workflow that matches
148
+ it. One session becomes the dispatcher instead of the place every job has to fit.
427
149
 
428
- ## Core is not a layer
150
+ ## Features
429
151
 
430
- Telemetry, workflow orchestration, Goal's dormant runtime, the dispatch loop, and editor
431
- plumbing ship unconditionally and are absent from `modes.yaml` on purpose. They are the
432
- reason the harness exists, so making them optional would only create broken configurations.
433
- Layers are for opinions, not foundations.
152
+ Doompi is a distribution, not one giant extension. Each package owns one job; shared TUI
153
+ and session contracts make them behave like one. Use the defaults together or replace
154
+ them one at a time.
434
155
 
435
- ## Who owns what
156
+ ### Configuration and composition
436
157
 
437
- Doom Pi is a meta-package. It depends on the Doom closure (`@agimon-ai/doompi-*`) and composes
438
- it, and it depends on nothing that belongs to the repository consuming it. The Agiflow and
439
- Agent Hooks extensions are consumer-owned: the repository declares them in its own
440
- `.doom/modes.yaml` and installs them itself, and they load after the Doom packages.
158
+ `@agimon-ai/doompi` is both an extension and the command-line config compiler. The
159
+ `doompi init` command writes the config; `doompi sync` resolves every major mode and
160
+ domain into a distribution Pi can load quickly. A large major mode with 15 extensions
161
+ adds only 400 ms of code startup time.
441
162
 
442
- That split decides where a specifier resolves. A package the repository declares resolves
443
- from the repository root, walking its module chain; anything that does not resolve there
444
- falls back to what ships with the installed meta-package. So a consumer can add a layer
445
- without Doom Pi knowing the package exists, and Doom Pi can ship its own closure without
446
- the consumer declaring it.
163
+ ### Leader key
447
164
 
448
- Package resources follow the same rule: the UI theme is shipped by `@agimon-ai/doompi-ui`
449
- and the workflow-recovery skill by `@agimon-ai/doompi-workflow`, each declared in its own
450
- manifest, so an installed package is discoverable without this checkout. Every Doom package
451
- publishes through an explicit `files` allowlist, which keeps repository material such as
452
- `docs/ideas/` out of any tarball.
165
+ `@agimon-ai/doompi-ui` turns `SPC` into a map of the available commands. It stays out of
166
+ the way when a draft is not empty, and other packages contribute bindings through one
167
+ leader API instead of hardcoding their own menus.
453
168
 
454
- A repository is recognised by a Doom or trusted Pi marker: a `.doom/` directory, or an
455
- existing `.pi/settings.json`. No Nx, pnpm workspace, or plugins profile is required, so a
456
- plain repository that installs the package can launch it.
169
+ ### Agent team
457
170
 
458
- ## Lazy config
171
+ `@agimon-ai/doompi-team` runs named subagents asynchronously against a shared task board.
172
+ They can work in parallel, message one another, and use the model policy attached to the
173
+ selected Team package entry. `SPC a l` lists available agents; `SPC a r` opens current-session runs and
174
+ their controls.
459
175
 
460
- Under the launcher, everything is resolved per run and nothing is written back into the
461
- repository. Editing a YAML file is the entire change.
176
+ ### Tasks
462
177
 
463
- `doompi sync` trades that for a pinned setup: the same resolution runs once and lands in
464
- `.pi/doom/`, while `.pi/settings.json` keeps the stable `@agimon-ai/doompi` extension name.
465
- An internal `.pi/@agimon-ai/doompi` package alias lets Pi resolve that stable name; the
466
- package entry then locates and dynamically loads the generated bootstrap from synced state.
467
- Edit a YAML file and the next session says the config changed, the way doom emacs asks you
468
- to re-run `doom sync`.
178
+ `@agimon-ai/doompi-task` keeps a task graph on disk, not a disposable checklist in the
179
+ transcript. Dependencies and delegation survive compaction, and work can be handed to a
180
+ subagent—including a smaller model when the job does not need the expensive one.
469
181
 
470
- `doompi init` seeds `~/.pi/.doom` with all five file names, but only `config.yaml` from
471
- there is read at runtime. Major modes, domains, profiles, and hooks are always read from the
472
- repository `.doom/`, so the other four seeded files affect nothing beyond the inputs hash.
182
+ ### Auto-compact
473
183
 
474
- Either way the hook registry compiles to the files other frontends read before any harness
475
- code runs, and `doompi sync` regenerates them.
184
+ Ordinary compaction waits for one summary to save an overgrown session.
185
+ `@agimon-ai/doompi-autocompact` leaves checkpoints instead:
476
186
 
477
- ## Other frontends
187
+ 1. At 50%, it writes the first compact summary.
188
+ 2. Later, it combines that summary with the messages since; the model decides whether the
189
+ result is ready to use.
190
+ 3. On the third pass, it combines them again and forces compaction.
478
191
 
479
- Pi is the primary frontend. Claude Code, Codex, and Antigravity run through
480
- `doompi compat <provider>` and share the same domain config as far as each can:
192
+ The work runs off-thread. Each checkpoint carries the live plan, task graph, team state,
193
+ and user request with it, so coordination does not have to be guessed back out of prose.
481
194
 
482
- | | Pi | Claude Code | Codex | Antigravity |
483
- | ------------------- | ----------------- | ----------------------------- | ------------------------ | ------------------- |
484
- | domains to plugins | yes | yes | yes | yes |
485
- | hooks | from the registry | generated `settings.json` | generated `hooks.json` | copied `hooks.json` |
486
- | MCP servers | scoped | scoped | unscoped | scoped |
487
- | MCP proxy upstreams | scoped | scoped | scoped | scoped |
488
- | major mode | packages + hooks | shared hook groups | shared hook groups | shared hook groups |
489
- | personas | system prompt | `--append-system-prompt-file` | `developer_instructions` | no |
195
+ ### MCP
490
196
 
491
- Compatibility frontends use the selected major mode for shared hook state. Layer packages
492
- and Pi extensions are loaded only by Pi.
493
-
494
- Antigravity is the odd one. It reads its configuration from the workspace and from the
495
- user's home directory rather than from arguments, so every selection is written to disk
496
- before launch and reverted when it is no longer selected. Everything the harness writes is
497
- tracked in a managed-state file, so a file you created by hand is never silently replaced.
498
- Its hooks are copied from `.antigravity-local/hooks.json`, which is maintained by hand
499
- rather than generated from the registry.
197
+ `@agimon-ai/doompi-mcp` is the gate between a session and its servers. It reads `.mcp.json`
198
+ and other common formats, then exposes only the servers and proxy upstreams allowed by the
199
+ selected domains. Switch domains and that boundary reloads with them.
500
200
 
501
- Where a concept has no equivalent, it is left out rather than approximated.
502
-
503
- ## Files
201
+ ### Ask user question
504
202
 
505
- All Doompi configuration lives in `.doom/`, committed to git.
203
+ `@agimon-ai/doompi-user-feedback` gives the agent a structured question that actually
204
+ waits for an answer. In autonomous Voice mode it skips the modal, narrates the choices,
205
+ and accepts the next spoken response as an ordinary user message.
506
206
 
507
- ```
508
- .doom/
509
- config.yaml projectTrust, plus the selection sync pins
510
- domains.yaml domains, plus aliases for shorthand bundles
511
- modes.yaml layer definitions and the named major modes built from them
512
- hooks.yaml canonical hooks for all three frontends
513
- profiles.yaml persona and environment profiles
514
-
515
- agents/<product>/<person>/ persona source, referenced never copied
516
- ```
517
-
518
- `doompi sync` writes into `.pi/`:
519
-
520
- ```
521
- .pi/settings.json committed; sync owns extensions, themes, and theme
522
- .pi/doom/ generated and gitignored
523
- state.json environment, resolved paths, and the inputs hash
524
- mcp.json mcp-extension.ts agents/ persona.md doom-pi-dark.json
525
- run/<pid>/ one session's live switches, never the baseline
526
- harness-state.json that session's own state, owned by its process
527
- ```
528
-
529
- ### One owner for the state
207
+ ### Logging and telemetry
530
208
 
531
- The resolved matrix a session runs on is a file, not a set of variables.
532
- `DOOMPI_STATE` points at it, and everything else the harness exports is derived from
533
- it: a projection published for the readers that can only see an environment, which are bash
534
- hooks, the shell launchers, `agent-hooks`, and any process spawned by any of them. Two
535
- fields never appear there at all, because nothing outside `@agimon-ai/doompi-config` reads
536
- them and every hook spawn would otherwise copy them: the plugin hook list and the profile's
537
- environment defaults.
209
+ Doompi telemetry records counters and spans, never prompt text or file content, in a local
210
+ SQLite database by default. `SPC h l` opens the metrics, and `@agimon-ai/log-sink-mcp`
211
+ gives the agent CLI tools for inspecting its own runs.
538
212
 
539
- Ownership is per process, and that is the point. Doom Team subagents run detached, from an
540
- environment snapshot, and can outlive the parent that spawned them. So a spawner writes the
541
- child a file of its own in that run's directory, and any process that finds a file it does
542
- not own copies it before its first write. A child can neither corrupt its parent's session
543
- nor lose its own when the parent cleans up.
213
+ ### Plan mode
544
214
 
545
- It also regenerates the two hook files the other frontends read before any harness code
546
- runs, which live outside `.pi/`:
215
+ A promise to "only plan" is not a permission boundary. `@agimon-ai/doompi-plan` makes the
216
+ repository read-only while the agent explores, persists the plan, and hands it back for
217
+ approval. Use `SPC p p` for normal planning, `SPC p d` for debug planning, `SPC p f` for
218
+ the Fable flow, and `SPC p e` to exit. Turn it on when the approach should be settled
219
+ before the files move.
547
220
 
548
- ```
549
- .claude/settings.json the "hooks" key only; every other key is preserved
550
- .codex-local/hooks.json the whole file
551
- ```
552
-
553
- Edit `hooks.yaml` and re-run `doompi sync` to regenerate both.
554
-
555
- ## Selection
221
+ ### Loop mode
556
222
 
557
- Use singular `--profile <name>` for one persona and its environment defaults. Use
558
- `--domains <name[,name...]>` for plugin bundles. Both `--major-mode` and `--profile` take
559
- exactly one name, reject a comma, and can be given only once. The removed `--layer`,
560
- `--layers`, `--profiles`, and `--target` flags throw and point at the replacement, and so
561
- does the removed `DOOMPI_LAYER` variable: a stale export is worth an error rather than a
562
- session quietly starting on the default.
223
+ `@agimon-ai/doompi-loop` is an in-session scheduler. It runs a prompt immediately and then
224
+ repeats it on an interval; several loops can coexist. Use `SPC l s` to start one and
225
+ `SPC l l` to list or stop them. It is for recurring checks and prompts that belong to the
226
+ current session.
563
227
 
564
- Defaults when you name nothing: `defaultMajorMode` from `.doom/modes.yaml` and the
565
- `defaultDomains` list from `.doom/domains.yaml`. Omitting those fields preserves the
566
- compatible fallbacks: major mode `copilot`, plus domain `marketing` for the legacy
567
- `marketing` mode or `default` for every other mode.
228
+ ### Goal mode
568
229
 
569
- Environment equivalents are `DOOMPI_MAJOR_MODE`, `DOOMPI_DOMAINS`, and `DOOMPI_PROFILE`.
570
- `DOOMPI_PRESET` and `DOOMPI_ADDITIONAL_DIRS` work the same way for `--preset` and
571
- `--add-dir`. An empty `DOOMPI_DOMAINS` means no domains, not the default. No profile is
572
- selected unless one is named.
230
+ `@agimon-ai/doompi-goal` pins one objective to the session until it completes or you end
231
+ it. Use `SPC g g` for status, `SPC g s` to start, `SPC g e` to end, and `SPC g p` for
232
+ history. Finished goals leave the prompt and tools behind but remain in history when you
233
+ want to restart one.
573
234
 
574
- There is one variable per axis. A nested run inherits its launcher's choice because the
575
- launcher writes the resolved value into the child environment under the same name, so
576
- anything you exported yourself is what a top-level run uses and what a spawned run
577
- overrides. These used to be two variables, `DOOM_PI_*` for the selection and
578
- `AGENT_HARNESS_*` for the resolved projection, with the second outranking the first. Any
579
- surviving `AGENT_HARNESS_*` variable now throws and names its replacement, because a stale
580
- export in a shell profile is worth an error.
235
+ ### Workflow mode
581
236
 
582
- `DOOMPI_LAYERS`, plural, is a different variable from `DOOMPI_LAYER`. It carries the
583
- resolved layer components rather than the mode that selected them.
237
+ `@agimon-ai/doompi-workflow` runs GitHub Actions-style job graphs with dependencies,
238
+ timeouts, artifacts, and a separate Doompi session for each step. Use `SPC w w` to launch,
239
+ `SPC w l` to manage, `SPC w r` to recover a failed run, and `SPC w e` to give the agent
240
+ workflow tools or take them back. It is for work that needs hard job boundaries and
241
+ explicit handoffs rather than one long conversation.
584
242
 
585
- A repository can also pin the full selection used by a bare `doompi sync` or
586
- `doompi build`. A flag still wins, then an exported variable, then the matching
587
- `selection` field, then `modes.yaml`'s `defaultMajorMode` or `domains.yaml`'s
588
- `defaultDomains`:
589
-
590
- ```yaml
591
- # .doom/config.yaml
592
- selection:
593
- majorMode: dev
594
- domains: [development]
595
- profile: house-voice
596
- ```
243
+ ### Voice mode
597
244
 
598
- Pi asks once before it trusts a project and loads `.pi` resources, so a synced session
599
- prompts on first run regardless of `projectTrust`, which reaches Pi as a launcher flag.
600
- Answer yes, or run `/trust`.
245
+ `@agimon-ai/doompi-voice` records and transcribes speech locally; audio stays on the
246
+ machine. Use `SPC v v` for one recording or `SPC v a` to toggle autonomous capture. It
247
+ replaces the keyboard without replacing the work already in progress.