devloom 1.0.0 → 1.1.0

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 (140) hide show
  1. package/.ai/core.dsl +44 -0
  2. package/.ai/skills.dsl +39 -0
  3. package/.ai/verify.dsl +97 -0
  4. package/.ai/workflow.dsl +81 -0
  5. package/.opencode/themes/devloom-night-owl.json +103 -0
  6. package/GUIDE.md +547 -114
  7. package/README.md +557 -109
  8. package/SECURITY.md +93 -0
  9. package/agents/devloom-developer-flash.md +27 -0
  10. package/agents/devloom-developer-senior.md +28 -0
  11. package/agents/devloom-developer.md +18 -56
  12. package/agents/devloom-documenter-flash.md +24 -0
  13. package/agents/devloom-documenter.md +14 -57
  14. package/agents/devloom-orchestrator.md +232 -356
  15. package/agents/devloom-planner-flash.md +30 -0
  16. package/agents/devloom-planner-senior.md +31 -0
  17. package/agents/devloom-planner.md +32 -0
  18. package/agents/devloom-qa-flash.md +28 -0
  19. package/agents/devloom-qa.md +18 -84
  20. package/agents/devloom-security-senior.md +31 -0
  21. package/agents/devloom-security.md +30 -0
  22. package/agents/devloom-verifier.md +29 -0
  23. package/agents/devloom-vision.md +109 -0
  24. package/agents/devloom-visual-critic.md +98 -0
  25. package/agents/devloom-visual-director.md +80 -0
  26. package/commands/devloom-agents.md +49 -0
  27. package/commands/devloom-auto.md +11 -0
  28. package/commands/devloom-context.md +82 -0
  29. package/commands/devloom-deepseek.md +11 -0
  30. package/commands/devloom-free.md +11 -0
  31. package/commands/devloom-go-economy.md +11 -0
  32. package/commands/devloom-go-flash.md +11 -0
  33. package/commands/devloom-go.md +11 -0
  34. package/commands/devloom-init.md +28 -50
  35. package/commands/devloom-loop-status.md +25 -0
  36. package/commands/devloom-loop.md +36 -0
  37. package/commands/devloom-mimo.md +11 -0
  38. package/commands/devloom-plan.md +13 -0
  39. package/commands/devloom-refresh.md +22 -0
  40. package/commands/devloom-resume.md +30 -49
  41. package/commands/devloom-save.md +69 -0
  42. package/commands/devloom-status.md +9 -18
  43. package/commands/devloom.md +99 -67
  44. package/dist/agents.d.ts +30 -0
  45. package/dist/agents.d.ts.map +1 -0
  46. package/dist/agents.js +139 -0
  47. package/dist/agents.js.map +1 -0
  48. package/dist/bootstrap.d.ts +56 -0
  49. package/dist/bootstrap.d.ts.map +1 -0
  50. package/dist/bootstrap.js +116 -0
  51. package/dist/bootstrap.js.map +1 -0
  52. package/dist/constraints.d.ts +5 -0
  53. package/dist/constraints.d.ts.map +1 -0
  54. package/dist/constraints.js +45 -0
  55. package/dist/constraints.js.map +1 -0
  56. package/dist/context.d.ts +42 -0
  57. package/dist/context.d.ts.map +1 -0
  58. package/dist/context.js +636 -0
  59. package/dist/context.js.map +1 -0
  60. package/dist/guard.d.ts +19 -0
  61. package/dist/guard.d.ts.map +1 -0
  62. package/dist/guard.js +418 -0
  63. package/dist/guard.js.map +1 -0
  64. package/dist/loop.d.ts +64 -0
  65. package/dist/loop.d.ts.map +1 -0
  66. package/dist/loop.js +164 -0
  67. package/dist/loop.js.map +1 -0
  68. package/dist/plugin.d.ts.map +1 -1
  69. package/dist/plugin.js +101 -1
  70. package/dist/plugin.js.map +1 -1
  71. package/dist/tui-agents.d.ts +61 -0
  72. package/dist/tui-agents.d.ts.map +1 -0
  73. package/dist/tui-agents.js +89 -0
  74. package/dist/tui-agents.js.map +1 -0
  75. package/dist/tui.d.ts +6 -0
  76. package/dist/tui.d.ts.map +1 -0
  77. package/dist/tui.js +92 -0
  78. package/dist/tui.js.map +1 -0
  79. package/dist/worktree.d.ts +46 -0
  80. package/dist/worktree.d.ts.map +1 -0
  81. package/dist/worktree.js +272 -0
  82. package/dist/worktree.js.map +1 -0
  83. package/package.json +46 -6
  84. package/patterns/changelog-drafter.md +38 -0
  85. package/patterns/ci-sweeper.md +40 -0
  86. package/patterns/daily-triage.md +37 -0
  87. package/patterns/dependency-sweeper.md +40 -0
  88. package/patterns/design-audit.md +63 -0
  89. package/patterns/issue-triage.md +37 -0
  90. package/patterns/post-merge-cleanup.md +34 -0
  91. package/patterns/pr-babysitter.md +37 -0
  92. package/patterns/registry.yaml +52 -0
  93. package/postinstall.mjs +259 -63
  94. package/project/README.md +29 -0
  95. package/protocol/agent-contracts.md +27 -0
  96. package/protocol/artifact-system.md +53 -0
  97. package/protocol/model-routing.md +185 -0
  98. package/protocol/orchestrator-core.md +43 -0
  99. package/protocol/project-system.md +45 -0
  100. package/protocol/rules.md +18 -0
  101. package/protocol/verification-policy.md +48 -0
  102. package/scripts/loop-run.mjs +205 -0
  103. package/scripts/model-capabilities.mjs +169 -0
  104. package/scripts/plugin-cache.mjs +269 -0
  105. package/scripts/profile.mjs +691 -0
  106. package/scripts/visual-benchmark.mjs +149 -0
  107. package/scripts/worktree.mjs +445 -0
  108. package/skills/build/development.md +33 -0
  109. package/skills/build/live-docs.md +38 -0
  110. package/skills/build/simplify.md +50 -0
  111. package/skills/build/vision-analysis.md +98 -0
  112. package/skills/design/app-design.md +31 -0
  113. package/skills/design/design-grounding.md +30 -0
  114. package/skills/design/design-system.md +27 -0
  115. package/skills/design/game-design.md +35 -0
  116. package/skills/design/motion-design.md +34 -0
  117. package/skills/design/visual-direction.md +32 -0
  118. package/skills/design/web-design.md +33 -0
  119. package/skills/loop/changelog-drafter.md +32 -0
  120. package/skills/loop/ci-sweeper.md +24 -0
  121. package/skills/loop/constraints.md +21 -0
  122. package/skills/loop/dependency-sweeper.md +24 -0
  123. package/skills/loop/design-audit.md +67 -0
  124. package/skills/loop/issue-triage.md +27 -0
  125. package/skills/loop/post-merge-cleanup.md +24 -0
  126. package/skills/loop/pr-babysitter.md +26 -0
  127. package/skills/loop/triage.md +25 -0
  128. package/skills/loop/verifier.md +20 -0
  129. package/skills/meta/skill-discovery.md +23 -0
  130. package/skills/plan/planning.md +27 -0
  131. package/skills/plan/verification-planning.md +40 -0
  132. package/skills/review/security-review.md +63 -0
  133. package/skills/ship/documentation.md +11 -0
  134. package/skills/verify/app-verification.md +19 -0
  135. package/skills/verify/quality-assurance.md +17 -0
  136. package/skills/verify/visual-critique.md +30 -0
  137. package/skills/verify/visual-quality-gate.md +29 -0
  138. package/skills/verify/visual-regression.md +25 -0
  139. package/agents/devloom-analyst.md +0 -83
  140. package/agents/devloom-architect.md +0 -88
@@ -0,0 +1,185 @@
1
+ # DevLoom Model Routing Profiles
2
+
3
+ ## Overview
4
+
5
+ Model routing assigns a specific language model to each agent role. Different models offer different trade-offs between reasoning quality, context, cost, and speed. Profiles let users pick the right balance without changing agent logic.
6
+
7
+ Each of the 10 DevLoom agents (orchestrator, planner, developer, qa, verifier, security, documenter, vision, visual-director, visual-critic) receives a model from the active profile. The orchestrator applies these when dispatching tasks. In every profile the `visual-director` and `visual-critic` roles resolve through the same model as `vision`.
8
+
9
+ ## How Profile Selection Works
10
+
11
+ 1. Profile is read from `.opencode/devloom/project/config.json` under `modelRouting`.
12
+ 2. Default: `go-flash` (deepseek-v4-flash for every role except vision).
13
+ 3. Override per task via `--model` flag or `OPENCODE_MODEL_OVERRIDE` env var.
14
+
15
+ ```json
16
+ { "modelRouting": "go" }
17
+ ```
18
+
19
+ ## Profiles
20
+ ### go (max quality)
21
+ The highest quality profile for production work. Orchestrator uses DeepSeek V4 Flash (cheapest — runs every turn; vision delegated to `devloom-vision`). Qwen 3.7 Max to planner (strong reasoning), Kimi K2.7 Code to implementation, GLM 5.2 to security (forensic depth), DeepSeek V4 Pro to QA/verifier, Qwen 3.7 Plus to documentation, Qwen 3.6 Plus to vision (low-cost multimodal).
22
+
23
+ | Role | Model |
24
+ |---|---|
25
+ | orchestrator | opencode-go/deepseek-v4-flash |
26
+ | planner | opencode-go/qwen3.7-max |
27
+ | developer | opencode-go/kimi-k2.7-code |
28
+ | qa | opencode-go/deepseek-v4-pro |
29
+ | verifier | opencode-go/deepseek-v4-pro |
30
+ | security | opencode-go/glm-5.2 |
31
+ | documenter | opencode-go/qwen3.7-plus |
32
+ | vision | opencode-go/qwen3.6-plus |
33
+
34
+ ### go-economy
35
+ A lower cost profile that retains Kimi K2.7 Code for the developer role and uses DeepSeek V4 Pro for orchestrator, qa, verifier, and security roles. Qwen 3.6 Plus handles documentation at reduced cost. Suitable for routine development work where premium reasoning is not essential.
36
+
37
+ | Role | Model |
38
+ |---|---|
39
+ | orchestrator | opencode-go/deepseek-v4-pro |
40
+ | planner | opencode-go/kimi-k2.7-code |
41
+ | developer | opencode-go/kimi-k2.7-code |
42
+ | qa | opencode-go/deepseek-v4-pro |
43
+ | verifier | opencode-go/deepseek-v4-pro |
44
+ | security | opencode-go/deepseek-v4-pro |
45
+ | documenter | opencode-go/qwen3.6-plus |
46
+ | vision | opencode-go/qwen3.6-plus |
47
+
48
+ ### go-flash
49
+ All agents on DeepSeek V4 Flash for maximum throughput at minimum cost. Vision uses Qwen 3.6 Plus (multimodal).
50
+
51
+ | Role | Model |
52
+ |---|---|
53
+ | orchestrator | opencode-go/deepseek-v4-flash |
54
+ | planner | opencode-go/deepseek-v4-flash |
55
+ | developer | opencode-go/deepseek-v4-flash |
56
+ | qa | opencode-go/deepseek-v4-flash |
57
+ | verifier | opencode-go/deepseek-v4-flash |
58
+ | security | opencode-go/deepseek-v4-flash |
59
+ | documenter | opencode-go/deepseek-v4-flash |
60
+ | vision | opencode-go/qwen3.6-plus |
61
+
62
+ ### deepseek
63
+ All DeepSeek V4 Pro agents (consistent provider affinity). Vision uses DeepSeek V4 Flash Vision Exp (cheapest vision-capable DeepSeek model: 0.22 input / 0.66 output vs Qwen 3.6 Plus 0.5/3).
64
+
65
+ | Role | Model |
66
+ |---|---|
67
+ | orchestrator | opencode-go/deepseek-v4-pro |
68
+ | planner | opencode-go/deepseek-v4-pro |
69
+ | developer | opencode-go/deepseek-v4-pro |
70
+ | qa | opencode-go/deepseek-v4-pro |
71
+ | verifier | opencode-go/deepseek-v4-pro |
72
+ | security | opencode-go/deepseek-v4-pro |
73
+ | documenter | opencode-go/deepseek-v4-pro |
74
+ | vision | opencode-go/deepseek-v4-flash-vision-exp |
75
+
76
+ ### free
77
+ A zero-cost profile using only freely available models. Intended for experimentation, open-source projects, learning, and low-stakes development where cost must be zero. All agents use the best available free-tier model. If a specific free model is unavailable, the fallback chains are: orchestration: opencode/big-pickle -> opencode/muse-spark-1.3-contributor-free -> opencode/mimo-v2.5-free -> opencode/muse-spark-1.2-contributor-free -> opencode/nemotron-3.5-lightning-free -> opencode/nemotron-3-ultra-free -> opencode/ling-3.0-flash-fin-free; implementation/verification: opencode/big-pickle -> opencode/muse-spark-1.3-contributor-free -> opencode/nemotron-3.5-lightning-free -> opencode/mimo-v2.5-free -> opencode/nemotron-3-ultra-free -> opencode/ling-3.0-flash-fin-free; planning: opencode/nemotron-3-ultra-free -> opencode/muse-spark-1.3-contributor-free -> opencode/muse-spark-1.2-contributor-free -> opencode/big-pickle -> opencode/nemotron-3.5-lightning-free -> opencode/ling-3.0-flash-fin-free; documentation: opencode/muse-spark-1.3-contributor-free -> opencode/muse-spark-1.2-contributor-free -> opencode/nemotron-3-ultra-free -> opencode/mimo-v2.5-free -> opencode/ling-3.0-flash-fin-free; vision: opencode/mimo-v2.5-free -> opencode-go/deepseek-v4-flash-vision-exp -> opencode-go/minimax-m3 -> opencode-go/mimo-v2.5-pro (paid fallbacks ordered by cost, cheapest first: deepseek 0.22/0.66 < minimax 0.3/1.2 < mimo-pro 0.435/0.87).
78
+
79
+ | Role | Model |
80
+ |---|---|
81
+ | orchestrator | opencode/big-pickle |
82
+ | planner | opencode/nemotron-3-ultra-free |
83
+ | developer | opencode/big-pickle |
84
+ | qa | opencode/big-pickle |
85
+ | verifier | opencode/big-pickle |
86
+ | security | opencode/big-pickle |
87
+ | documenter | opencode/muse-spark-1.2-contributor-free |
88
+ | vision | opencode/mimo-v2.5-free |
89
+
90
+ ### mimo (locked tier)
91
+
92
+ A single multimodal stack: every role — including vision, visual-director, and visual-critic — resolves to the first available MiMo V2.6 Flash candidate from the chain `mimo/mimo-v2.6-flash` -> `xiaomi/mimo-v2.6-flash` -> `opencode-go/mimo-v2.6-flash`, checked against `opencode models`. `opencode/mimo-v2.6-flash-free` is deliberately excluded from free chains. If no candidate is available the profile is NOT activated: `profile.mjs` exits with code 1 and prints the attempted candidates — never an unrelated substitution. Tier overrides are locked for this profile. Activate with `/devloom-mimo`.
93
+
94
+ | Role | Model |
95
+ |---|---|
96
+ | all 10 roles | resolved MiMo V2.6 Flash candidate |
97
+
98
+ ## Model Guidance
99
+
100
+ ### When to Use GLM 5.2
101
+
102
+ GLM 5.2 (opencode-go/glm-5.2) provides the strongest reasoning and planning capabilities among available models. It is the best choice when a task requires:
103
+
104
+ - Architectural design and system decomposition
105
+ - Requirements analysis and specification writing
106
+ - UX-aware decisions that balance user experience with technical constraints
107
+ - Multi-step planning with dependency management
108
+ - High-stakes decisions where incorrect reasoning would be costly
109
+
110
+ In practice, GLM 5.2 should be assigned to the orchestrator, planner, and any agent that makes strategic decisions. For UI/UX-heavy Angular or React SaaS frontend work, GLM 5.2 delivers superior reasoning around component hierarchies, state management patterns, accessibility, and user flow design.
111
+
112
+ ### When to Use Kimi K2.7 Code
113
+
114
+ Kimi K2.7 Code (opencode-go/kimi-k2.7-code) offers strong code generation quality with a large context window. Successor to K2.6 with fewer hallucinations and better long-context adherence. Ideal for multi-file changes, refactors, code exploration, deep bug fixes, and backend work that needs to hold many services/schemas in context simultaneously. Primary workhorse for the developer role in the go and go-economy profiles.
115
+
116
+ ### When to Use Kimi K3 (Senior Developer)
117
+
118
+ Kimi K3 (opencode-go/kimi-k3) is the newest Kimi generation. It is the model assigned to the `senior` tier for the developer role when the orchestrator classifies the prompt as complex (architecture change, large refactor, deep debugging, security-sensitive implementation). It offers stronger code reasoning and longer context than K2.7 Code.
119
+
120
+ ### When to Use MiniMax M3 (Multimodal)
121
+
122
+ MiniMax M3 (opencode-go/minimax-m3) is multimodal but is not the default in any current profile. The `devloom-vision` agent uses Qwen 3.6 Plus (multimodal, lower cost). MiniMax M3 may still be used as a vision fallback if Qwen 3.6 Plus is unavailable. Use it directly only when you need a multimodal model with no vision delegation overhead.
123
+
124
+ ### When to Use DeepSeek V4 Pro
125
+
126
+ DeepSeek V4 Pro (opencode-go/deepseek-v4-pro) excels at structured, analytical tasks. It is the default qa and verifier in the go profile, and the default for most roles in `deepseek` and `go-economy`, because these roles benefit from precision over open-ended reasoning.
127
+
128
+ Best uses: planning, verification, writing/running tests, debugging, root-cause analysis, regression reviews.
129
+
130
+ ### When to Use DeepSeek V4 Flash
131
+
132
+ DeepSeek V4 Flash (opencode-go/deepseek-v4-flash) is the cheapest Go model. It is the default orchestrator in the go and go-economy profiles because the orchestrator runs every turn and accumulates the highest token volume. Vision is delegated to `devloom-vision` (Qwen 3.6 Plus), so the orchestrator does not need multimodal capability. It is also the default for every role in the `go-flash` profile.
133
+
134
+ ### When to Use Qwen Models
135
+
136
+ Qwen 3.7 Plus (opencode-go/qwen3.7-plus) is the latest Qwen model — documentation, analysis, code summarization. Qwen 3.7 Max (opencode-go/qwen3.7-max) is the planner in the `go` profile for strong reasoning. Qwen 3.6 Plus (opencode-go/qwen3.6-plus) is the default multimodal model for the `devloom-vision` agent — lowest-cost multimodal option on the OpenCode Go plan.
137
+
138
+ ### When to Use Free Tier Models
139
+
140
+ Free models (opencode/big-pickle, opencode/nemotron-3-ultra-free, opencode/nemotron-3.5-lightning-free, opencode/mimo-v2.5-free, opencode/muse-spark-1.3-contributor-free, opencode/muse-spark-1.2-contributor-free, opencode/ling-3.0-flash-fin-free) are suitable only when cost must be zero — experimentation, learning, or evaluation. They have lower reasoning capability than paid Go models in some roles, not recommended for production work. The `vision` role always resolves to a vision-capable model (mimo-v2.5-free on the free tier, with DeepSeek V4 Flash Vision Exp as cheapest paid fallback).
141
+
142
+ ## Frontend vs Backend Guidance
143
+
144
+ **UI/UX-heavy frontend (Angular, React, SaaS):** component decomposition, state management, accessibility, responsive layout, and user-flow decisions benefit from strong reasoning rather than large context. Use DeepSeek V4 Pro (planner) for planning, architecture, and review; Kimi K2.7 Code for implementation when the task spans many files.
145
+
146
+ **Backend and data-intensive work:** context size matters more than peak reasoning. Use Kimi K2.7 Code for backend implementation roles — its large context window holds services, database schemas, API contracts, and data pipelines without truncation.
147
+
148
+ ## Configuration and Overrides
149
+
150
+ ### Setting the Profile
151
+
152
+ In `.opencode/devloom/project/config.json`:
153
+
154
+ ```json
155
+ {
156
+ "modelRouting": "go"
157
+ }
158
+ ```
159
+
160
+ Valid values: `"go"`, `"go-economy"`, `"deepseek"`, `"go-flash"`, `"free"`, `"mimo"`.
161
+
162
+ ### Overrides
163
+
164
+ Per-task: `opencode task --model opencode-go/glm-5.2 "implement feature"`. Environment: set `OPENCODE_MODEL_OVERRIDE=<model-id>` to force every agent onto one model — it takes precedence over both the profile and the `--model` flag.
165
+
166
+ ### Per-Role Override in Config
167
+
168
+ Individual role assignments can be overridden by adding a `modelRoutingOverrides` object in config.json:
169
+
170
+ ```json
171
+ {
172
+ "modelRouting": "go-economy",
173
+ "modelRoutingOverrides": {
174
+ "developer": "opencode-go/glm-5.2",
175
+ "qa": "opencode-go/kimi-k2.7-code"
176
+ }
177
+ }
178
+ ```
179
+
180
+ Overrides merge on top of the selected profile and take precedence for the specified roles.
181
+
182
+ ### Sidebar visibility and plugin cache
183
+
184
+ The sidebar reflects the active profile via the plugin `config` hook, which injects all 17 agents, renders a `DevLoom - {profile}` header, and shows the resolved model next to every agent row. The orchestrator agent description carries the profile label — e.g. `DevLoom Orchestrator: autonomous multi-agent delivery (profile: go-flash)`, extended to `(profile: go, tier: senior)` when the senior tier is active. The sidebar lists only the 10 base agents: all `-flash` and `-senior` variants are hidden for every profile, yet all 17 stay registered so `task()` routing is unaffected.
185
+ OpenCode installs npm plugins into `~/.cache/opencode/packages/` with `ignoreScripts`, so the cached copy can go stale and the hook never runs. Run `/devloom-refresh` after installing/updating DevLoom or switching profiles — it rebuilds `dist/` from source before refreshing the cache — then restart opencode (or `opencode --continue`) to see the updated profile and agents in the sidebar.
@@ -0,0 +1,43 @@
1
+ # Orchestrator Core
2
+
3
+ LOAD: ~/.config/opencode/devloom-ai/core.dsl|~/.config/opencode/devloom-ai/workflow.dsl
4
+
5
+ SM:
6
+ `IDLE>TRIAGE>CHAIN[step1..stepN]>GATE>DONE`
7
+
8
+ TRIAGE:
9
+ - classify prompt intent, select minimal chain from workflow.dsl CHAINS
10
+ - append COND_ADDONS only when their condition holds
11
+ - full pipeline only when intent=feature with UI+API+flows touched
12
+ - orchestrator routes+persists only; chain steps run in subagents
13
+
14
+ STATE:
15
+ - LEGACY=.opencode/devloom/state.json
16
+ - BOARD=.opencode/devloom/project/board.json
17
+ - PSTATE=.opencode/devloom/project/state.json
18
+
19
+ RULES:
20
+ - COMPLIANCE: you MUST follow every rule in this file and every LOADed file. No rule may be skipped or abbreviated.
21
+ - COMPLIANCE: you MUST verify every sub-agent output against the protocol gates defined in this file. Reject non-compliant results and re-delegate.
22
+ - load BOARD+PSTATE every prompt
23
+ - load memory context and relevant skills every prompt before planning
24
+ - if board.cols.doing is non-empty: queue the new prompt (append to backlog + TODO.md), set phase=queued, do NOT triage or execute
25
+ - append the current prompt as the last task/todo before execution (only when doing is empty)
26
+ - continue pending work first
27
+ - single active ticket — new prompts queue behind current work unless explicitly overridden
28
+ - orchestrator may invoke any DevLoom subagent automatically when the phase requires it
29
+ - orchestrator must delegate specialist phase work to the matching DevLoom subagent when one exists
30
+ - orchestrator must invoke devloom-security for CRUD endpoint work and for any change that exposes internal component/module input or output
31
+ - orchestrator keeps routing and state ownership; subagents do the phase-specific execution
32
+ - orchestrator updates tickets, todos, and plan artifacts on each state transition
33
+ - orchestrator saves state before reprioritization, pause, and completion
34
+ - all artifacts EN
35
+ - official docs + latest stable check before stack-specific plan/code
36
+ - defect => developer(rootCauseFix)>qa(regr)
37
+ - max3 fix cycles per defect, then mark blocked + BLOCKED report
38
+ - max100 steps
39
+ - clear context every 5 completed tasks if needed
40
+ - FILES: never use /tmp, /var/tmp, or system temp — use .opencode/devloom/.tmp/ for temp files and test artifacts
41
+
42
+ EXIT:
43
+ - only DEVLOOM_DONE when all gates pass and no open high/critical defect
@@ -0,0 +1,45 @@
1
+ # Project System
2
+
3
+ LOAD: ~/.config/opencode/devloom-ai/core.dsl|~/.config/opencode/devloom-ai/workflow.dsl
4
+
5
+ ROOT: `.opencode/devloom/project/`
6
+
7
+ TREE:
8
+ - README.md
9
+ - config.json
10
+ - board.json
11
+ - state.json
12
+ - stories/
13
+ - tasks/
14
+ - bugs/
15
+ - decisions/
16
+ - reports/
17
+
18
+ CFG_JSONM:
19
+ ```json
20
+ {"v":1,"lang":"en","tracker":"local","gh":{"enabled":false,"owner":"","repo":"","project":""},"rules":{"flow":["analysis","documentation","implementation","verification","regression","done"],"tests":"required","regression":"required","queue":"single","docs":"official","delegation":"required","skills":"required","memory":"load","save":"always","promptTask":"append-last"}}
21
+ ```
22
+
23
+ BOARD_JSONM:
24
+ ```json
25
+ {"v":1,"tracker":"local","active":"","cols":{"backlog":[],"ready":[],"doing":[],"review":[],"blocked":[],"done":[]},"updatedAt":""}
26
+ ```
27
+
28
+ STATE_JSONM:
29
+ ```json
30
+ {"v":1,"phase":"idle","prompt":"","ticket":"","next":"analysis","updatedAt":"","notes":[]}
31
+ ```
32
+
33
+ RULES:
34
+ - EN
35
+ - JSONM for AI-only state
36
+ - doing<=1 unless explicit user override
37
+ - when doing is occupied, new prompts queue to backlog — never preempt active work
38
+ - never drop pending work
39
+ - tests+regr required for code change
40
+ - load memory and relevant skills every prompt
41
+ - append each new prompt as the last task/todo entry before execution continues (only when doing is empty)
42
+ - keep tickets, todos, and plan synchronized automatically
43
+ - tracker=github only with explicit user authorization
44
+ - local files remain fallback source of truth even in github mode
45
+ - phase=queued means prompts are waiting in backlog behind active work — resume dequeues the next item
@@ -0,0 +1,18 @@
1
+ # DevLoom Protocol Rules
2
+
3
+ CORE: EN only | SOLID+TDD+CleanArch | SingleActive | AppendPromptTask | OfficialDocsFirst | tests+regr required | delegation required | save every phase | load memory+skills every prompt
4
+
5
+ QUEUE: doing<=1 | new prompt while doing non-empty → append to backlog, set phase=queued, do NOT triage or execute | /devloom-resume dequeues next backlog item
6
+
7
+ CHAIN: feature=planner>dev>qa>doc | bug=dev(rca)>qa(regr) | refactor=planner>dev>qa | small=dev>qa | docs=planner>doc | task=dev | explore=verifier
8
+
9
+ ADDONS: image→vision FIRST | UI→visual-director(DESIGN_FILE, persist .opencode/devloom/context/design.md) then verifier(route,form,a11y,visual,responsive,motion) + visual-critic(≤3 cycles, verdict passed to verifier; backend-only never routes visual agents) | API→verifier(api,contract) | CRUD/endpoint→security | defect→dev(rca)>qa(regr) max3 cycles | high-risk→peer-review (verifier with multi-model consensus)
10
+
11
+ GATES: build(lint+tests) | qa(test+review+regr) | verifier(all requested scopes) | visual(design.md exists + critic verdict or VISUAL_CRITIQUE_LIMITED, VISUAL_REQUIRED only for UI work) | security(all checks) | peer-review(≥2 models agree) | doc(done+verified only)
12
+
13
+ ANTI-LOOP: max3 retries per defect | max100 steps | BLOCKED+reason after 2 failed retries | never self-delegate | never loop same agent
14
+
15
+ OUTPUT: DEVLOOM_DONE only when chain gates pass | sub-agents emit their OUT signal | final response ≤40 lines, full detail in artifacts | sub-agent never calls orchestrator back
16
+ FILES: never use /tmp, /var/tmp, or any system temp dirs — use .opencode/devloom/.tmp/ in the project workspace for all temporary files, test artifacts, and scratch work
17
+ SESSIONS: orchestrator tracks sub-agent task IDs in state.sessions. Reuse task_id when re-delegating to the same agent type mid-pipeline — prevents context loss across turns.
18
+ DEGRADE: if a sub-agent fails twice (timeout, rate-limit, empty response), fall back one tier: senior→mid, mid→junior, junior→skip. Set state.degraded=true and log the fallback.
@@ -0,0 +1,48 @@
1
+ # Verification Policy
2
+
3
+ LOAD: ~/.config/opencode/devloom-ai/verify.dsl
4
+
5
+ RULES:
6
+ - ROUTE-001=render|noBlank|noCrash|noConsoleErr|noNavFail|noHydrationErr
7
+ - ROUTE-002=domVisible|size>0|notHidden|notBlocked|inViewport
8
+ - ROUTE-003=screenshot/vision when available
9
+ - FORM-001=valid|invalid|required|boundary|successMsg|errorMsg|loading
10
+ - FORM-002=input|select|checkbox|radio|textarea|submit|reset
11
+ - A11Y-001=role|label|expanded|selected|current
12
+ - A11Y-002=tabReachable|focusVisible|orderOk|noTrap|enterSpace|escClose|arrowKeys
13
+ - A11Y-003=contrastText|contrastFocus|noColorOnly
14
+ - A11Y-004=nav|main|headingOrder|buttonVsLink|labelAssoc
15
+ - API-001=auth|authz|inputVal|outputSchema|statusCodes|errorShape|paging/filter/sort if app
16
+ - API-002=openapi if missing|runtime vs contract
17
+ - E2E-001=targeted impacted suite during iteration
18
+ - E2E-002=full suite before acceptance
19
+ - JOURNEY-001=generate from REQ+routes+ui
20
+ - JOURNEY-002=test valid state transitions
21
+ - PERF-001=loadTime|noLeak|noExcessRender|bundleOk
22
+ - VISUAL-001=screenshots or CRITIC_VERDICT required|else VISUAL_CRITIQUE_LIMITED (never fake VISUAL_PASS)
23
+ - VISUAL-002=10-dim score vs design.md contract|hierarchy|spacing|typography|color|alignment|consistency|affordance|density|polish|fidelity
24
+ - VISUAL-003=no overflow|no clipped text|no overlap|component states match tokens
25
+ - RESP-001=viewports 360|768|1280|no horizontal scroll|no overlap|touch targets >=44px|images scale
26
+ - MOTION-001=prefers-reduced-motion|duration <=300ms standard <=500ms complex|no layout shift|states complete|easing matches design.md
27
+ - SEC-001=depAudit|noSecrets|cors|sanitize|auth|authz|leastPrivilege
28
+ - SEC-002=inputVal|outputSchema|errorShape|massAssignment|overposting
29
+ - SEC-003=noInternalFieldLeak|noDebugLeak|idor|xss|csrf|ssrf if applicable
30
+ - SEC-004=mandatory for CRUD endpoints and any internal component/module exposure via input/output
31
+
32
+ MAP:
33
+ - RouteVerifier=ROUTE-001|002|003
34
+ - FormVerifier=FORM-001|002
35
+ - A11yVerifier=A11Y-001|002|003|004
36
+ - ApiVerifier=API-001|002
37
+ - VisualVerifier=VISUAL-001|002|003
38
+ - ResponsiveVerifier=RESP-001
39
+ - MotionVerifier=MOTION-001
40
+ - SecurityVerifier=SEC-001|002|003|004
41
+ - JourneyAgent=JOURNEY-001|002
42
+ - QA=run applicable rules
43
+ - Regression=E2E-001 during work; E2E-002 before done
44
+
45
+ ENFORCE:
46
+ - each violation => defect
47
+ - critical/high defect blocks gate
48
+ - skip is invalid; only escalate after 3 failed repair cycles
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * DevLoom Loop Runner — Single loop tick executor
4
+ * Usage: node scripts/loop-run.mjs [--pattern <name>] [--cadence <cron>] [--level L1|L2|L3]
5
+ *
6
+ * Reads loop config, validates pattern, checks budget, constructs prompt,
7
+ * logs outcome.
8
+ */
9
+ import { readFileSync, existsSync, writeFileSync, mkdirSync } from "node:fs"
10
+ import { join, dirname } from "node:path"
11
+ import { fileURLToPath } from "node:url"
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url))
14
+ const ROOT = join(__dirname, "..")
15
+
16
+ function readJson(path, fallback) {
17
+ try {
18
+ return JSON.parse(readFileSync(path, "utf8"))
19
+ } catch {
20
+ return fallback
21
+ }
22
+ }
23
+
24
+ function writeJson(path, data) {
25
+ const dir = dirname(path)
26
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
27
+ writeFileSync(path, JSON.stringify(data, null, 2) + "\n")
28
+ }
29
+
30
+ function nextMidnightISO() {
31
+ const now = new Date()
32
+ const mid = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 0, 0)
33
+ return mid.toISOString()
34
+ }
35
+
36
+ function parseArgs() {
37
+ const args = {}
38
+ for (let i = 2; i < process.argv.length; i++) {
39
+ const arg = process.argv[i]
40
+ if (arg.startsWith("--")) {
41
+ const key = arg.slice(2)
42
+ const val = process.argv[i + 1]
43
+ if (val && !val.startsWith("--")) {
44
+ args[key] = val
45
+ i++
46
+ } else {
47
+ args[key] = true
48
+ }
49
+ }
50
+ }
51
+ return args
52
+ }
53
+
54
+ // --- Main ---
55
+ async function main() {
56
+ const cli = parseArgs()
57
+ const loopDir = join(ROOT, ".opencode", "devloom", "loop")
58
+
59
+ // 1. Read loop config
60
+ const configPath = join(loopDir, "loop-config.json")
61
+ const config = readJson(configPath, {})
62
+ config.pattern = cli.pattern || config.pattern || "daily-triage"
63
+ config.cadence = cli.cadence || config.cadence || "0 0 * * *"
64
+ config.level = cli.level || config.level || "L1"
65
+ config.paused = config.paused || false
66
+
67
+ // 2a. Read until-done progress if mode is until-done
68
+ let progress = null
69
+ if (config.mode === "until-done") {
70
+ const progressPath = join(loopDir, "progress.json")
71
+ progress = readJson(progressPath, null)
72
+ }
73
+
74
+ // 2. Validate pattern exists
75
+ const registryPath = join(ROOT, "patterns", "registry.yaml")
76
+ const patternPath = join(ROOT, "patterns", `${config.pattern}.md`)
77
+
78
+ if (!existsSync(registryPath)) {
79
+ console.log("Warning: patterns/registry.yaml not found. Pattern validation skipped.")
80
+ }
81
+ if (!existsSync(patternPath)) {
82
+ console.log(`Error: pattern file not found: patterns/${config.pattern}.md`)
83
+ process.exit(1)
84
+ }
85
+
86
+ // 3. Check budget
87
+ const budgetPath = join(loopDir, "budget.json")
88
+ const budget = readJson(budgetPath, { dailyLimit: 500000, spent: 0, resetAt: nextMidnightISO() })
89
+
90
+ const now = new Date()
91
+ const resetAt = new Date(budget.resetAt)
92
+ if (now >= resetAt) {
93
+ budget.spent = 0
94
+ budget.resetAt = nextMidnightISO()
95
+ writeJson(budgetPath, budget)
96
+ }
97
+
98
+ const remaining = Math.max(0, budget.dailyLimit - budget.spent)
99
+ if (remaining <= 0) {
100
+ config.paused = true
101
+ writeJson(configPath, config)
102
+ console.log(`Budget exceeded (${budget.spent}/${budget.dailyLimit}). Loop paused.`)
103
+ console.log("Reset at:", budget.resetAt)
104
+ process.exit(1)
105
+ }
106
+
107
+ // 3a. Check until-done completion
108
+ if (config.mode === "until-done" && progress) {
109
+ const allVerified = progress.items.every((i) => i.status === "verified")
110
+ if (allVerified) {
111
+ console.log("===== Design-Audit Complete =====")
112
+ console.log(`All ${progress.total} pages verified against design system spec.`)
113
+ console.log("Fix loop finished. No more pages to process.")
114
+ process.exit(0)
115
+ }
116
+ }
117
+
118
+ // 4. Record start time
119
+ const startTime = Date.now()
120
+
121
+ // 5. Pattern cost estimate
122
+ const patternContent = readFileSync(patternPath, "utf8")
123
+ const costMatch = patternContent.match(/cost:\s*(\d+)/)
124
+ const estimatedCost = costMatch ? parseInt(costMatch[1]) : 50000
125
+
126
+ // 6. Construct prompt
127
+ let progressContext = ""
128
+ if (config.mode === "until-done" && progress) {
129
+ const pending = progress.items.filter((i) => i.status === "pending").length
130
+ const inProgress = progress.items.filter((i) => i.status === "in-progress").length
131
+ const byCategory = {}
132
+ for (const item of progress.items) {
133
+ const cat = item.category || "uncategorized"
134
+ byCategory[cat] = (byCategory[cat] || 0) + 1
135
+ }
136
+ const catSummary = Object.entries(byCategory).map(([k, v]) => `${k}=${v}`).join(" ")
137
+ progressContext = `\nProgress: ${progress.verified}/${progress.total} verified, ${pending} pending, ${inProgress} in-progress\nIssues by category: ${catSummary}\nCompletion condition: ${progress.completionCondition}`
138
+ }
139
+
140
+ const prompt = [
141
+ `[devloom-loop] Running pattern: ${config.pattern}`,
142
+ `Level: ${config.level}`,
143
+ `Cadence: ${config.cadence}`,
144
+ `Mode: ${config.mode || "recurring"}`,
145
+ `Budget remaining: ${remaining}/${budget.dailyLimit}`,
146
+ progressContext,
147
+ "",
148
+ `Pattern loaded from patterns/${config.pattern}.md.`,
149
+ `Execute the pattern's agent chain and log results.`,
150
+ ].join("\n")
151
+
152
+ // 7. In headless mode: opencode run "<prompt>"
153
+ // For now, construct the command and log it
154
+ const headlessCmd = `opencode run "${prompt.replace(/"/g, '\\"')}"`
155
+ console.log("===== DevLoom Loop Tick =====")
156
+ console.log("Pattern:", config.pattern)
157
+ console.log("Level:", config.level)
158
+ console.log("Mode:", config.mode || "recurring")
159
+ if (config.mode === "until-done" && progress) {
160
+ console.log("Progress:", `${progress.verified}/${progress.total} verified`)
161
+ const byCat = {}
162
+ for (const item of progress.items) {
163
+ const cat = item.category || "uncategorized"
164
+ byCat[cat] = (byCat[cat] || 0) + 1
165
+ }
166
+ console.log("Issues:", Object.entries(byCat).map(([k, v]) => `${k}=${v}`).join(", "))
167
+ }
168
+ console.log("Budget remaining:", remaining)
169
+ console.log("Estimated cost:", estimatedCost)
170
+ console.log("")
171
+ console.log("Headless command:")
172
+ console.log(headlessCmd)
173
+ console.log("")
174
+ console.log("===== Prompt =====")
175
+ console.log(prompt)
176
+
177
+ // 8. Record outcome
178
+ const durationMs = Date.now() - startTime
179
+ const runLogPath = join(loopDir, "run-log.json")
180
+ const runLog = readJson(runLogPath, [])
181
+ runLog.push({
182
+ timestamp: new Date().toISOString(),
183
+ pattern: config.pattern,
184
+ agentsUsed: [],
185
+ outcome: "success",
186
+ tokenCost: estimatedCost,
187
+ durationMs,
188
+ ...(config.mode === "until-done" && progress ? { progress: `${progress.verified}/${progress.total} verified` } : {}),
189
+ })
190
+ writeJson(runLogPath, runLog)
191
+
192
+ // 9. Deduct estimated cost from budget
193
+ budget.spent += estimatedCost
194
+ writeJson(budgetPath, budget)
195
+
196
+ console.log("")
197
+ console.log("Tick completed in", durationMs, "ms")
198
+ console.log("Cost deducted:", estimatedCost)
199
+ console.log("Run log updated")
200
+ }
201
+
202
+ main().catch((err) => {
203
+ console.error("Loop runner error:", err.message)
204
+ process.exit(1)
205
+ })