@comfanion/workflow 4.36.63 → 4.36.65
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/package.json +1 -1
- package/src/build-info.json +2 -2
- package/src/opencode/agents/reviewer.md +9 -9
- package/src/opencode/opencode.json +1 -0
- package/src/opencode/plugins/custom-compaction.ts +53 -4
- package/src/opencode/skills/dev-story/SKILL.md +27 -13
- package/src/opencode/skills/story-writing/SKILL.md +18 -2
package/package.json
CHANGED
package/src/build-info.json
CHANGED
|
@@ -88,13 +88,7 @@ permission:
|
|
|
88
88
|
<action>search() in docs for architecture requirements</action>
|
|
89
89
|
</phase>
|
|
90
90
|
|
|
91
|
-
<phase name="2.
|
|
92
|
-
<action>Run test suite: go test / npm test / pytest / cargo test</action>
|
|
93
|
-
<action>Run linter: golangci-lint / eslint / ruff / cargo clippy</action>
|
|
94
|
-
<action>If failures → include in review report as HIGH priority</action>
|
|
95
|
-
</phase>
|
|
96
|
-
|
|
97
|
-
<phase name="3. Security First">
|
|
91
|
+
<phase name="2. Security Analysis">
|
|
98
92
|
<action>Check for hardcoded secrets</action>
|
|
99
93
|
<action>Verify input validation on all user inputs</action>
|
|
100
94
|
<action>Check SQL injection, XSS vulnerabilities</action>
|
|
@@ -102,20 +96,26 @@ permission:
|
|
|
102
96
|
<action>Check if sensitive data is logged</action>
|
|
103
97
|
</phase>
|
|
104
98
|
|
|
105
|
-
<phase name="
|
|
99
|
+
<phase name="3. Correctness Analysis">
|
|
106
100
|
<action>Verify all acceptance criteria are met</action>
|
|
107
101
|
<action>Check edge cases and error handling</action>
|
|
108
102
|
<action>Look for logic errors and race conditions</action>
|
|
109
103
|
<action>Verify tests cover critical paths</action>
|
|
110
104
|
</phase>
|
|
111
105
|
|
|
112
|
-
<phase name="
|
|
106
|
+
<phase name="4. Code Quality Analysis">
|
|
113
107
|
<action>Check architecture compliance</action>
|
|
114
108
|
<action>Look for code duplication</action>
|
|
115
109
|
<action>Verify naming conventions</action>
|
|
116
110
|
<action>Check for N+1 queries, performance issues</action>
|
|
117
111
|
</phase>
|
|
118
112
|
|
|
113
|
+
<phase name="5. Run Tests & Lint">
|
|
114
|
+
<action>Run test suite: go test / npm test / pytest / cargo test</action>
|
|
115
|
+
<action>Run linter: golangci-lint / eslint / ruff / cargo clippy</action>
|
|
116
|
+
<action>If failures → include in review report as HIGH priority</action>
|
|
117
|
+
</phase>
|
|
118
|
+
|
|
119
119
|
<phase name="6. Report">
|
|
120
120
|
<action>Categorize issues: High/Medium/Low</action>
|
|
121
121
|
<action>Provide specific fixes for each issue</action>
|
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin"
|
|
2
|
-
import { readFile, access, readdir } from "fs/promises"
|
|
2
|
+
import { readFile, access, readdir, appendFile } from "fs/promises"
|
|
3
3
|
import { join } from "path"
|
|
4
4
|
|
|
5
|
+
// Debug logging to file
|
|
6
|
+
async function log(directory: string, message: string): Promise<void> {
|
|
7
|
+
const logPath = join(directory, ".opencode", "compaction.log")
|
|
8
|
+
const timestamp = new Date().toISOString()
|
|
9
|
+
try {
|
|
10
|
+
await appendFile(logPath, `[${timestamp}] ${message}\n`)
|
|
11
|
+
} catch {
|
|
12
|
+
// ignore logging errors
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Service agents that should be ignored
|
|
17
|
+
const SERVICE_AGENTS = ["title", "compaction", "summary", "system"]
|
|
18
|
+
|
|
19
|
+
function isRealAgent(agent: string | null): boolean {
|
|
20
|
+
if (!agent) return false
|
|
21
|
+
return !SERVICE_AGENTS.includes(agent.toLowerCase())
|
|
22
|
+
}
|
|
23
|
+
|
|
5
24
|
interface TaskStatus {
|
|
6
25
|
id: string
|
|
7
26
|
content: string
|
|
@@ -486,30 +505,55 @@ Previous task was completed successfully.
|
|
|
486
505
|
return {
|
|
487
506
|
// Track active agent from chat messages
|
|
488
507
|
"chat.message": async (input, output) => {
|
|
508
|
+
await log(directory, `chat.message: agent=${input.agent}, sessionID=${input.sessionID}`)
|
|
489
509
|
if (input.agent) {
|
|
490
510
|
// Handle both string and object agent (e.g., { name: "dev" })
|
|
491
|
-
|
|
511
|
+
const agent = typeof input.agent === 'string'
|
|
492
512
|
? input.agent
|
|
493
513
|
: (input.agent as any)?.name || null
|
|
494
|
-
|
|
514
|
+
|
|
515
|
+
// Only track real agents, not service agents
|
|
516
|
+
if (isRealAgent(agent)) {
|
|
517
|
+
lastActiveAgent = agent
|
|
518
|
+
lastSessionId = input.sessionID
|
|
519
|
+
await log(directory, ` -> tracked agent: ${lastActiveAgent}`)
|
|
520
|
+
} else {
|
|
521
|
+
await log(directory, ` -> ignored service agent: ${agent}`)
|
|
522
|
+
}
|
|
495
523
|
}
|
|
496
524
|
},
|
|
497
525
|
|
|
498
526
|
// Also track from chat params (backup)
|
|
499
527
|
"chat.params": async (input, output) => {
|
|
528
|
+
await log(directory, `chat.params: agent=${input.agent}`)
|
|
500
529
|
if (input.agent) {
|
|
501
|
-
|
|
530
|
+
const agent = typeof input.agent === 'string'
|
|
502
531
|
? input.agent
|
|
503
532
|
: (input.agent as any)?.name || null
|
|
533
|
+
|
|
534
|
+
// Only track real agents, not service agents
|
|
535
|
+
if (isRealAgent(agent)) {
|
|
536
|
+
lastActiveAgent = agent
|
|
537
|
+
await log(directory, ` -> tracked agent: ${lastActiveAgent}`)
|
|
538
|
+
} else {
|
|
539
|
+
await log(directory, ` -> ignored service agent: ${agent}`)
|
|
540
|
+
}
|
|
504
541
|
}
|
|
505
542
|
},
|
|
506
543
|
|
|
507
544
|
"experimental.session.compacting": async (input, output) => {
|
|
545
|
+
await log(directory, `=== COMPACTION STARTED ===`)
|
|
546
|
+
await log(directory, ` lastActiveAgent: ${lastActiveAgent}`)
|
|
547
|
+
|
|
508
548
|
// Use tracked agent or try to detect from session
|
|
509
549
|
const agent = lastActiveAgent
|
|
510
550
|
const ctx = await buildContext(agent)
|
|
511
551
|
ctx.activeAgent = agent
|
|
512
552
|
|
|
553
|
+
await log(directory, ` story: ${ctx.story?.path || 'none'}`)
|
|
554
|
+
await log(directory, ` todos: ${ctx.todos.length}`)
|
|
555
|
+
await log(directory, ` relevantFiles: ${ctx.relevantFiles.length}`)
|
|
556
|
+
|
|
513
557
|
const context = formatContext(ctx)
|
|
514
558
|
const instructions = formatInstructions(ctx)
|
|
515
559
|
const readCommands = generateReadCommands(agent, ctx.story)
|
|
@@ -532,12 +576,17 @@ ${context}
|
|
|
532
576
|
---
|
|
533
577
|
|
|
534
578
|
${instructions}`)
|
|
579
|
+
|
|
580
|
+
await log(directory, ` -> output.context pushed (${output.context.length} items)`)
|
|
581
|
+
await log(directory, `=== COMPACTION DONE ===`)
|
|
535
582
|
},
|
|
536
583
|
|
|
537
584
|
event: async ({ event }) => {
|
|
585
|
+
await log(directory, `event: ${event.type}`)
|
|
538
586
|
if (event.type === "session.idle") {
|
|
539
587
|
const story = await getActiveStory()
|
|
540
588
|
if (story && story.pendingTasks.length === 0) {
|
|
589
|
+
await log(directory, ` -> Story complete: ${story.title}`)
|
|
541
590
|
console.log(`[compaction] Story complete: ${story.title}`)
|
|
542
591
|
}
|
|
543
592
|
}
|
|
@@ -15,30 +15,44 @@ How to transform story tasks into executable instructions for @coder.
|
|
|
15
15
|
|
|
16
16
|
## Task Transformation
|
|
17
17
|
|
|
18
|
-
Story task is
|
|
18
|
+
Story task is specification with Approach steps. Transform it into executable instruction with full context.
|
|
19
19
|
|
|
20
|
-
###
|
|
20
|
+
### Step 1: Read Required Reading
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
Story has "Required Reading" and task has "Read First":
|
|
23
|
+
1. Open each linked document
|
|
24
|
+
2. Find the specific sections mentioned
|
|
25
|
+
3. Extract patterns, signatures, constraints
|
|
26
|
+
|
|
27
|
+
### Step 2: Find Existing Code
|
|
28
|
+
|
|
29
|
+
From "Read First" paths:
|
|
30
|
+
1. Read existing similar code (e.g., "existing service example")
|
|
31
|
+
2. Note the structure, imports, error handling
|
|
32
|
+
3. This becomes "Pattern Reference" for @coder
|
|
33
|
+
|
|
34
|
+
### Step 3: Build Context
|
|
35
|
+
|
|
36
|
+
@coder doesn't see story. Provide:
|
|
37
|
+
- **Existing files** - actual paths with what they contain
|
|
38
|
+
- **Patterns to follow** - link to existing similar code
|
|
39
|
+
- **What was done** - results of previous tasks this depends on
|
|
26
40
|
- **Imports** - what packages to use
|
|
27
41
|
|
|
28
|
-
### Add
|
|
42
|
+
### Step 4: Add Direction
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
- Interface signatures (
|
|
44
|
+
Story has "Approach" with high-level steps. Expand with:
|
|
45
|
+
- Interface signatures (method names, params, return types)
|
|
32
46
|
- Error handling approach (what errors to return)
|
|
33
|
-
- Logging requirements (what to log)
|
|
34
47
|
- Validation rules (what to validate)
|
|
48
|
+
- Constraints from documentation
|
|
35
49
|
|
|
36
|
-
###
|
|
50
|
+
### Step 5: Make Verification Concrete
|
|
37
51
|
|
|
38
|
-
Story has "Done when".
|
|
52
|
+
Story has "Done when". Add:
|
|
39
53
|
- Specific test commands to run
|
|
40
|
-
- Expected output format
|
|
41
54
|
- Files that must compile
|
|
55
|
+
- Test coverage expectations
|
|
42
56
|
|
|
43
57
|
## Formulating Task for @coder
|
|
44
58
|
|
|
@@ -95,6 +95,24 @@ Summary table + detailed tasks.
|
|
|
95
95
|
- [ ] Tests pass
|
|
96
96
|
- [ ] Code reviewed
|
|
97
97
|
|
|
98
|
+
## No Code in Stories
|
|
99
|
+
|
|
100
|
+
**Stories are specifications, not implementations.**
|
|
101
|
+
|
|
102
|
+
✅ **Task provides:**
|
|
103
|
+
- Goal (what to achieve)
|
|
104
|
+
- Read First (where to find patterns)
|
|
105
|
+
- Output Files (what to create)
|
|
106
|
+
- Approach (high-level steps)
|
|
107
|
+
- Done When (how to verify)
|
|
108
|
+
|
|
109
|
+
❌ **Task does NOT provide:**
|
|
110
|
+
- Code Sketch with implementation
|
|
111
|
+
- Ready-to-copy code blocks
|
|
112
|
+
- Full method bodies
|
|
113
|
+
|
|
114
|
+
**@coder writes the code.** Story defines WHAT, not HOW.
|
|
115
|
+
|
|
98
116
|
## Task Structure (MANDATORY)
|
|
99
117
|
|
|
100
118
|
Each task MUST be self-contained:
|
|
@@ -126,8 +144,6 @@ Each task MUST be self-contained:
|
|
|
126
144
|
- [ ] Tests pass
|
|
127
145
|
```
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
131
147
|
## Reference Format
|
|
132
148
|
|
|
133
149
|
Always use `→` prefix:
|