allye-opencode 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/index.js +50 -35
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# allye-opencode
|
|
2
|
+
|
|
3
|
+
An [OpenCode](https://opencode.ai) plugin that registers 6 specialized Allye agents for the guided delivery workflow:
|
|
4
|
+
|
|
5
|
+
- **Allye — Router** — initializes context, detects the workflow phase, and delegates to the agent below
|
|
6
|
+
- **Allye Plan** — product planning (epics/features/stories) and technical planning (discussion phase, trade-offs, tasks)
|
|
7
|
+
- **Allye Orchestrator** — coordinates delivery of an already-planned feature: assigns work, tracks status, drives review
|
|
8
|
+
- **Allye Build** — TDD implementation of tasks
|
|
9
|
+
- **Allye Review** — code review with full context
|
|
10
|
+
- **Allye Deliver** — finalizes delivery, closes stories, updates docs
|
|
11
|
+
|
|
12
|
+
It also injects live Allye account/session context into every conversation via a system-prompt transform hook.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
This package is not typically installed standalone. It's installed automatically as part of the main [`allye-plugin`](https://github.com/allye-app/allye-plugin) install flow (`install.sh`), which detects OpenCode and adds `allye-opencode` to the `plugin` array in your `opencode.json` alongside the Allye MCP server configuration.
|
|
17
|
+
|
|
18
|
+
If you do need to add it manually, add it to the `plugin` array in your OpenCode config:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"plugin": ["allye-opencode"]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Documentation
|
|
27
|
+
|
|
28
|
+
For full workflow documentation — the guided delivery methodology, the phase skills, and the handover protocol this plugin implements — see the main repo: [github.com/allye-app/allye-plugin](https://github.com/allye-app/allye-plugin).
|
package/dist/index.js
CHANGED
|
@@ -149,6 +149,7 @@ Detect what the user needs and delegate to the right agent using the \`task\` to
|
|
|
149
149
|
|
|
150
150
|
| User intent | Delegate to |
|
|
151
151
|
|-------------|-------------|
|
|
152
|
+
| Explore ideas, research before committing to scope, think out loud | **allye-plan** (exploration only \u2014 do NOT create work items yet) |
|
|
152
153
|
| Define requirements, plan features, create epics/stories, break stories into tasks | **allye-plan** |
|
|
153
154
|
| Coordinate delivery of an already-planned feature \u2014 assign work, track status, drive review | **allye-orchestrator** |
|
|
154
155
|
| Implement code, write tests, fix bugs, develop features | **allye-build** |
|
|
@@ -157,6 +158,7 @@ Detect what the user needs and delegate to the right agent using the \`task\` to
|
|
|
157
158
|
|
|
158
159
|
### How to detect the phase
|
|
159
160
|
|
|
161
|
+
- **Exploring** \u2014 User wants to: think out loud, explore ideas, research a problem space, weigh directions before committing to scope. Nothing should be created yet \u2014 no epics, features, or stories. Delegate to allye-plan but tell it explicitly this is open-ended exploration, not work-item creation.
|
|
160
162
|
- **Planning** \u2014 User talks about: requirements, business needs, features, epics, user stories, scope, MVP, tasks, approach, options, trade-offs
|
|
161
163
|
- **Orchestrating** \u2014 User wants to: coordinate delivery, assign work items, track story/task status, drive review for an already-planned feature
|
|
162
164
|
- **Building** \u2014 User wants to: write code, implement a task, fix a bug, add functionality, write tests
|
|
@@ -179,8 +181,8 @@ If the user's request is simple and doesn't match any phase (general questions,
|
|
|
179
181
|
`.trim();
|
|
180
182
|
var allyeAgent = {
|
|
181
183
|
...SHARED_CONFIG,
|
|
182
|
-
description: "Allye
|
|
183
|
-
prompt: buildPrompt("Allye \u2014
|
|
184
|
+
description: "Allye router \u2014 initializes context, detects workflow phase, and delegates to specialized Allye agents (Plan, Orchestrator, Build, Review, Deliver)",
|
|
185
|
+
prompt: buildPrompt("Allye \u2014 Router", [
|
|
184
186
|
LANGUAGE_DETECTION,
|
|
185
187
|
ALLYE_INIT_PROTOCOL,
|
|
186
188
|
MEMORY_SEARCH_PROTOCOL,
|
|
@@ -333,9 +335,10 @@ Create the top-level epic first:
|
|
|
333
335
|
|
|
334
336
|
\`\`\`
|
|
335
337
|
work_create(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
338
|
+
work_title: "User Authentication System",
|
|
339
|
+
work_type: "epic",
|
|
340
|
+
work_category: "product",
|
|
341
|
+
work_description: "## Goal\\n{business goal}\\n\\n## Scope\\n{what's included}\\n\\n## Out of scope\\n{what's excluded}\\n\\n## Success criteria\\n{how we know it's done}"
|
|
339
342
|
)
|
|
340
343
|
\`\`\`
|
|
341
344
|
|
|
@@ -344,12 +347,12 @@ work_create(
|
|
|
344
347
|
Use \`work_bulk_create\` to create the full hierarchy in one call:
|
|
345
348
|
|
|
346
349
|
\`\`\`
|
|
347
|
-
work_bulk_create(
|
|
350
|
+
work_bulk_create(work_items: [
|
|
348
351
|
{
|
|
349
352
|
"temp_id": "feat-1",
|
|
350
353
|
"title": "Email/Password Auth",
|
|
351
354
|
"item_type": "feature",
|
|
352
|
-
"work_category": "
|
|
355
|
+
"work_category": "product",
|
|
353
356
|
"parent_key": "PROJ-100", // existing epic key
|
|
354
357
|
"description": "..."
|
|
355
358
|
},
|
|
@@ -357,7 +360,7 @@ work_bulk_create(items: [
|
|
|
357
360
|
"temp_id": "story-1",
|
|
358
361
|
"title": "User can register with email and password",
|
|
359
362
|
"item_type": "story",
|
|
360
|
-
"work_category": "
|
|
363
|
+
"work_category": "product",
|
|
361
364
|
"parent_temp_id": "feat-1", // references the feature above
|
|
362
365
|
"description": "..."
|
|
363
366
|
},
|
|
@@ -365,7 +368,7 @@ work_bulk_create(items: [
|
|
|
365
368
|
"temp_id": "story-2",
|
|
366
369
|
"title": "User can log in with email and password",
|
|
367
370
|
"item_type": "story",
|
|
368
|
-
"work_category": "
|
|
371
|
+
"work_category": "product",
|
|
369
372
|
"parent_temp_id": "feat-1",
|
|
370
373
|
"description": "..."
|
|
371
374
|
}
|
|
@@ -479,13 +482,13 @@ The steps below plan **one story at a time** \u2014 but the unit Technical Plann
|
|
|
479
482
|
Fetch the story the user wants to plan:
|
|
480
483
|
|
|
481
484
|
\`\`\`
|
|
482
|
-
work_get(id: "{story uuid}" or
|
|
485
|
+
work_get(id: "{story uuid}" or work_key: "{PROJ-123}")
|
|
483
486
|
\`\`\`
|
|
484
487
|
|
|
485
488
|
Read the story's description, acceptance criteria, and parent context. If the story is part of a feature/epic, understand the broader scope:
|
|
486
489
|
|
|
487
490
|
\`\`\`
|
|
488
|
-
work_get(
|
|
491
|
+
work_get(work_key: "{parent feature key}")
|
|
489
492
|
\`\`\`
|
|
490
493
|
|
|
491
494
|
---
|
|
@@ -666,12 +669,12 @@ Present the wave structure to the user so they understand the execution order.
|
|
|
666
669
|
### 4.5 Create Tasks via Bulk Create
|
|
667
670
|
|
|
668
671
|
\`\`\`
|
|
669
|
-
work_bulk_create(
|
|
672
|
+
work_bulk_create(work_items: [
|
|
670
673
|
{
|
|
671
674
|
"temp_id": "task-1",
|
|
672
675
|
"title": "Set up database schema for {feature}",
|
|
673
676
|
"item_type": "task",
|
|
674
|
-
"work_category": "
|
|
677
|
+
"work_category": "backend",
|
|
675
678
|
"parent_key": "{STORY-KEY}",
|
|
676
679
|
"description": "{full description with acceptance criteria}"
|
|
677
680
|
},
|
|
@@ -679,7 +682,7 @@ work_bulk_create(items: [
|
|
|
679
682
|
"temp_id": "task-2",
|
|
680
683
|
"title": "Create API route structure for {feature}",
|
|
681
684
|
"item_type": "task",
|
|
682
|
-
"work_category": "
|
|
685
|
+
"work_category": "backend",
|
|
683
686
|
"parent_key": "{STORY-KEY}",
|
|
684
687
|
"description": "{full description with acceptance criteria}"
|
|
685
688
|
}
|
|
@@ -777,13 +780,14 @@ Before dispatching, do a quick completeness check on the story's tasks: does eac
|
|
|
777
780
|
<!-- adapted from EveryInc/compound-engineering-plugin lfg (MIT) \u2014 verify the previous step's artifact before proceeding -->
|
|
778
781
|
When the execution report comes back, don't take "done" at face value \u2014 check the report actually contains what it should before acting on it: files changed listed, tasks reported per acceptance criterion, not just a blanket "finished." An incomplete report is itself a signal to ask for more detail, not something to wave through.
|
|
779
782
|
|
|
780
|
-
Once the report is genuinely complete, dispatch the \`reviewer\` subagent \u2014 in parallel, automatically, no need to ask the user first. Review never needs to pause and ask anyone anything, which is what makes it always dispatch-appropriate. Pass it: the story key, the task keys, and the files changed from the execution report.
|
|
783
|
+
Once the report is genuinely complete, dispatch the \`reviewer\` subagent \u2014 in parallel, automatically, no need to ask the user first. Review never needs to pause and ask anyone anything, which is what makes it always dispatch-appropriate. Pass it: the active team (id and name), the story key, the task keys, and the files changed from the execution report.
|
|
781
784
|
|
|
782
785
|
## 6. React to review
|
|
783
786
|
|
|
784
787
|
Reviewer returns its standard \u2705/\u26A0\uFE0F/\u274C-per-task output (unchanged from the \`review\` skill \u2014 no new format to learn).
|
|
785
788
|
|
|
786
789
|
- **All \u2705** \u2192 move each approved task the rest of the way to \`done\` yourself \u2014 the Executor only advanced it as far as \`review\` \u2014 then proceed to the status cascade (\xA77).
|
|
790
|
+
- **\u26A0\uFE0F warnings only, no \u274C** \u2192 a warning isn't a blocker: proceed to the status cascade (\xA77) the same as All \u2705. Don't silently discard the warnings and don't force an unnecessary correction round either \u2014 record them as a note (in the task's context, or as a memory) so they're not lost.
|
|
787
791
|
- **Any \u274C** \u2192 the failed task simply stays at \`review\` while the correction round runs. No backward move is needed (or possible \u2014 \`work_status_next\` only moves forward, per \`allye-board-progression\`): the task never reached \`done\`, because reaching \`done\` requires your move after Reviewer \u2705. Send corrections back using \`references/correction.md\`'s exact fields (only the failed findings, the correction-round count, the story reference \u2014 never a full re-brief of the story): emit it as a \`correction\` handover. Loop back to \xA75 once the next execution report arrives.
|
|
788
792
|
|
|
789
793
|
<!-- adapted from bmad-code-org/BMAD-METHOD correct-course (MIT) \u2014 structured change-impact analysis for corrections that ripple beyond one task -->
|
|
@@ -810,7 +814,7 @@ Unclear assignee, no active sprint to assign into, conflicting or unexpected sta
|
|
|
810
814
|
|
|
811
815
|
## 10. Memory
|
|
812
816
|
|
|
813
|
-
Search at start (\xA71). Save session state before ending \u2014 current position in the feature (which story/wave), what's been dispatched, what's pending review, any escalations raised. If a correction round revealed something worth remembering beyond this session (a wrong assumption, a pattern), save it as its own memory in the appropriate sector, per the \`allye-memory-protocol\` skill \u2014 don't let it live only in this session's state snapshot.`;
|
|
817
|
+
Search at start (\xA71). Save session state before ending \u2014 current position in the feature (which story/wave), what's been dispatched, what's pending review, any escalations raised, correction-round count per task (so the 2-correction-max escalation rule survives a resumed session). If a correction round revealed something worth remembering beyond this session (a wrong assumption, a pattern), save it as its own memory in the appropriate sector, per the \`allye-memory-protocol\` skill \u2014 don't let it live only in this session's state snapshot.`;
|
|
814
818
|
var TECHNICAL_DEVELOPMENT = `# Technical Development Workflow
|
|
815
819
|
|
|
816
820
|
This skill guides you through implementing a task with discipline: read existing code first, write tests, implement, refactor, and track progress in Allye.
|
|
@@ -834,7 +838,7 @@ Get task \u2192 Search context \u2192 Move to in_progress \u2192 Read code \u219
|
|
|
834
838
|
Fetch the task you're about to implement:
|
|
835
839
|
|
|
836
840
|
\`\`\`
|
|
837
|
-
work_get(
|
|
841
|
+
work_get(work_key: "{TASK-KEY}")
|
|
838
842
|
\`\`\`
|
|
839
843
|
|
|
840
844
|
Read its description carefully \u2014 it should contain:
|
|
@@ -913,12 +917,14 @@ This is not optional. Writing code without reading the context leads to:
|
|
|
913
917
|
### Analysis Paralysis Guard
|
|
914
918
|
|
|
915
919
|
<HARD-GATE>
|
|
916
|
-
|
|
920
|
+
This checkpoint applies to exploratory reads beyond what the task already named \u2014 reading every file the task itself points you to (see "What to read" above) is still mandatory, not capped by this count.
|
|
921
|
+
|
|
922
|
+
If you have read 5+ files *beyond those named/implied by the task* without writing any code, STOP and ask yourself:
|
|
917
923
|
|
|
918
924
|
1. **Do I have enough context to start?** \u2192 If yes, start writing. Perfect understanding is not required.
|
|
919
925
|
2. **Am I blocked by missing information?** \u2192 If yes, tell the user what's blocking you.
|
|
920
926
|
|
|
921
|
-
Do not read endlessly. Reading is preparation, not implementation.
|
|
927
|
+
Do not read endlessly in search of additional context. Reading is preparation, not implementation.
|
|
922
928
|
</HARD-GATE>
|
|
923
929
|
|
|
924
930
|
---
|
|
@@ -1060,16 +1066,14 @@ Only save if there's genuinely useful context. Don't save trivial implementation
|
|
|
1060
1066
|
|
|
1061
1067
|
## Step 9: Pick Next Task
|
|
1062
1068
|
|
|
1063
|
-
After completing a task,
|
|
1069
|
+
After completing a task, pick the next one from the **handover's own wave-ordered task list** \u2014 not from a live API call. The \`story-execution\` handover already contains every task across every wave for the whole story, so it's the authoritative scope; going back to the API for *new* tasks would risk pulling in tasks added to the story after the handover was dispatched, which are out of scope (see line ~14).
|
|
1064
1070
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
\`\`\`
|
|
1068
|
-
|
|
1069
|
-
- If there are more tasks in the current wave \u2192 pick one
|
|
1070
|
-
- If the current wave is done \u2192 move to the next wave
|
|
1071
|
+
- If there are more tasks in the current wave (per the handover's list) \u2192 pick one
|
|
1072
|
+
- If the current wave is done \u2192 move to the next wave (per the handover's list)
|
|
1071
1073
|
- If every task in the story has reached \`review\` (implementation complete, awaiting Reviewer) \u2192 emit an **\`execution-report\`** handover (see the \`handover-protocol\` skill) back to the Orchestrator
|
|
1072
1074
|
|
|
1075
|
+
Use \`work_children(id: "{story uuid}")\` only to **verify/check the status** of tasks already in the handover's list (e.g. confirming a dependency reached \`review\`) \u2014 never to discover new tasks to work on. If \`work_children\` reveals a task under this story that is **not** in the handover's task list, do not execute it \u2014 it wasn't in scope when the handover was dispatched. Instead, note it as an open question ("D\xFAvidas em aberto") in the \`execution-report\` handover so the Orchestrator can decide whether to bring it into scope.
|
|
1076
|
+
|
|
1073
1077
|
---
|
|
1074
1078
|
|
|
1075
1079
|
## Workflow Checklist
|
|
@@ -1113,7 +1117,7 @@ Get story context \u2192 Load decisions \u2192 Review each task \u2192 Document
|
|
|
1113
1117
|
### Get the story and its tasks
|
|
1114
1118
|
|
|
1115
1119
|
\`\`\`
|
|
1116
|
-
work_get(
|
|
1120
|
+
work_get(work_key: "{STORY-KEY}")
|
|
1117
1121
|
work_children(id: "{story uuid}")
|
|
1118
1122
|
\`\`\`
|
|
1119
1123
|
|
|
@@ -1639,11 +1643,22 @@ This skill defines how to correctly move work items between statuses using Allye
|
|
|
1639
1643
|
|
|
1640
1644
|
---
|
|
1641
1645
|
|
|
1642
|
-
## 1. Status Categories
|
|
1646
|
+
## 1. Status Categories vs. Status Names
|
|
1647
|
+
|
|
1648
|
+
The MCP client can only **confirm** 4 status categories \u2014 \`work_statuses()\` (\`work_items.py\`) groups every status under a hardcoded \`category_order\`:
|
|
1649
|
+
|
|
1650
|
+
| Category (confirmed) | Meaning |
|
|
1651
|
+
|----------|---------|
|
|
1652
|
+
| \`proposed\` | Not yet started (backlog/todo-like) |
|
|
1653
|
+
| \`in_progress\` | Actively being worked on |
|
|
1654
|
+
| \`done\` | Completed and verified |
|
|
1655
|
+
| \`cancelled\` | Will not be done |
|
|
1656
|
+
|
|
1657
|
+
That's the only taxonomy the MCP client source guarantees. Specific status **names** (e.g. "Backlog", "Todo", "In Progress", "Testing", "Review", "Deploying", "Done") are team-configurable \`WorkflowStatus\` records mapped onto those 4 categories via board columns \u2014 they are not enumerable or guaranteed from the client code alone, and a given team's board may use different names or skip some of them.
|
|
1643
1658
|
|
|
1644
|
-
|
|
1659
|
+
With that caveat, the finer-grained progression below is a common, practical convention (not something the client confirms) that this skill assumes as its default working model, because most teams do configure something like it:
|
|
1645
1660
|
|
|
1646
|
-
|
|
|
1661
|
+
| Status name (convention) | Meaning |
|
|
1647
1662
|
|----------|---------|
|
|
1648
1663
|
| \`backlog\` | Not yet planned \u2014 sitting in the backlog |
|
|
1649
1664
|
| \`todo\` | Planned and ready to start |
|
|
@@ -1654,7 +1669,7 @@ Allye uses these status categories, in typical progression order:
|
|
|
1654
1669
|
| \`done\` | Completed and verified |
|
|
1655
1670
|
| \`cancelled\` | Will not be done |
|
|
1656
1671
|
|
|
1657
|
-
Each team can customize their board with different columns and map statuses to columns as they see fit.
|
|
1672
|
+
Each team can customize their board with different columns and map statuses to columns as they see fit. Before relying on any specific status name, check \`work_statuses()\` (categories + actual names for the team) and \`board_columns()\` (which columns exist on the board in question).
|
|
1658
1673
|
|
|
1659
1674
|
---
|
|
1660
1675
|
|
|
@@ -1746,7 +1761,7 @@ Returns all available statuses with their categories and names.
|
|
|
1746
1761
|
board_columns()
|
|
1747
1762
|
\`\`\`
|
|
1748
1763
|
|
|
1749
|
-
Returns the board
|
|
1764
|
+
Returns the board's columns for the given \`board_id\` \u2014 each rendered as \`- {column name} (ID: {column id})\`. Note: this tool's text output does not surface which statuses map to which column, nor an explicit ordering field (\`boards.py\`'s \`board_columns\` action only formats \`name\` and \`id\` per column) \u2014 that richer structure may exist in the underlying API but isn't exposed here. Use it to confirm which columns exist on a board; pair it with \`work_statuses()\` for status names/categories.
|
|
1750
1765
|
|
|
1751
1766
|
---
|
|
1752
1767
|
|
|
@@ -2026,9 +2041,9 @@ After generating the handoff, say:
|
|
|
2026
2041
|
> 3. The Orchestrator will coordinate implementation and review from here"
|
|
2027
2042
|
|
|
2028
2043
|
### Important:
|
|
2029
|
-
- ALWAYS generate the handoff prompt \u2014 don't just say "switch to
|
|
2030
|
-
- The prompt must be COMPLETE \u2014 the
|
|
2031
|
-
- Include ALL locked decisions \u2014
|
|
2044
|
+
- ALWAYS generate the handoff prompt \u2014 don't just say "switch to Orchestrator"
|
|
2045
|
+
- The prompt must be COMPLETE \u2014 the Orchestrator agent starts from zero, it has no memory of this conversation
|
|
2046
|
+
- Include ALL locked decisions \u2014 Orchestrator must respect them
|
|
2032
2047
|
- Include the specific task key to start with \u2014 don't leave it vague
|
|
2033
2048
|
`.trim();
|
|
2034
2049
|
var allyePlanAgent = {
|
package/package.json
CHANGED