opencodekit 0.12.7 → 0.13.1
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 +2 -2
- package/dist/index.js +2753 -508
- package/dist/template/.opencode/AGENTS.md +35 -128
- package/dist/template/.opencode/README.md +4 -3
- package/dist/template/.opencode/command/design.md +1 -0
- package/dist/template/.opencode/command/fix.md +28 -1
- package/dist/template/.opencode/command/implement.md +195 -39
- package/dist/template/.opencode/command/new-feature.md +229 -188
- package/dist/template/.opencode/command/plan.md +354 -82
- package/dist/template/.opencode/command/research.md +29 -6
- package/dist/template/.opencode/command/start.md +227 -0
- package/dist/template/.opencode/command/triage.md +66 -12
- package/dist/template/.opencode/memory/project/beads-workflow.md +510 -0
- package/dist/template/.opencode/memory/session-context.md +40 -0
- package/dist/template/.opencode/opencode.json +20 -5
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/plugin/compaction.ts +62 -18
- package/dist/template/.opencode/plugin/lib/notify.ts +2 -3
- package/dist/template/.opencode/plugin/sessions.ts +1 -1
- package/dist/template/.opencode/plugin/skill-mcp.ts +11 -12
- package/dist/template/.opencode/skill/beads/SKILL.md +44 -0
- package/dist/template/.opencode/skill/source-code-research/SKILL.md +537 -0
- package/dist/template/.opencode/tool/ast-grep.ts +3 -3
- package/dist/template/.opencode/tool/bd-inbox.ts +7 -6
- package/dist/template/.opencode/tool/bd-msg.ts +3 -3
- package/dist/template/.opencode/tool/bd-release.ts +2 -2
- package/dist/template/.opencode/tool/bd-reserve.ts +5 -4
- package/dist/template/.opencode/tool/memory-read.ts +2 -2
- package/dist/template/.opencode/tool/memory-search.ts +2 -2
- package/dist/template/.opencode/tool/memory-update.ts +11 -12
- package/dist/template/.opencode/tool/observation.ts +6 -6
- package/package.json +5 -2
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Memory & Compaction Plugin
|
|
2
|
+
* Memory & Compaction Plugin (Codex-Inspired Continuity)
|
|
3
3
|
*
|
|
4
|
-
* Injects
|
|
5
|
-
* 1. Load
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
4
|
+
* Injects continuity context into session compaction:
|
|
5
|
+
* 1. Load session-context.md (CONTINUITY.md pattern)
|
|
6
|
+
* 2. Load project memory files
|
|
7
|
+
* 3. Inject beads in-progress state
|
|
8
|
+
* 4. Append workflow-specific compaction rules
|
|
9
|
+
*
|
|
10
|
+
* Session context format (agent-maintained via memory-update):
|
|
11
|
+
* - Goal: What we're trying to achieve + success criteria
|
|
12
|
+
* - Constraints: User-specified limits, discovered guardrails
|
|
13
|
+
* - Decisions: Key choices made this session
|
|
14
|
+
* - State: Done/Now/Next
|
|
15
|
+
* - Open Questions: Uncertainties marked UNCONFIRMED
|
|
16
|
+
* - Working Set: Files, bead IDs, branch
|
|
8
17
|
*/
|
|
9
18
|
|
|
10
19
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
@@ -14,7 +23,19 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
14
23
|
|
|
15
24
|
return {
|
|
16
25
|
"experimental.session.compacting": async (input, output) => {
|
|
17
|
-
// Load
|
|
26
|
+
// 1. Load session context (CONTINUITY.md pattern) - HIGHEST PRIORITY
|
|
27
|
+
let sessionContext = "";
|
|
28
|
+
try {
|
|
29
|
+
const sessionFile = `${MEMORY_DIR}/session-context.md`;
|
|
30
|
+
const content = await $`cat ${sessionFile} 2>/dev/null`.text();
|
|
31
|
+
if (content.trim()) {
|
|
32
|
+
sessionContext = `\n## Session Continuity (Compaction-Safe)\n${content}`;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// No session context yet
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 2. Load project memory files
|
|
18
39
|
let memoryContext = "";
|
|
19
40
|
try {
|
|
20
41
|
const memoryFiles =
|
|
@@ -33,7 +54,7 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
33
54
|
// Memory dir doesn't exist or other error
|
|
34
55
|
}
|
|
35
56
|
|
|
36
|
-
// Inject beads in-progress state
|
|
57
|
+
// 3. Inject beads in-progress state
|
|
37
58
|
let beadsContext = "";
|
|
38
59
|
try {
|
|
39
60
|
const result =
|
|
@@ -48,12 +69,13 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
48
69
|
// Beads not available, skip
|
|
49
70
|
}
|
|
50
71
|
|
|
51
|
-
// Inject
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
// Inject all context - session context FIRST (most important)
|
|
73
|
+
const allContext = [sessionContext, beadsContext, memoryContext]
|
|
74
|
+
.filter(Boolean)
|
|
75
|
+
.join("\n");
|
|
76
|
+
|
|
77
|
+
if (allContext) {
|
|
78
|
+
output.context.push(`## Session Context\n${allContext}\n`);
|
|
57
79
|
}
|
|
58
80
|
|
|
59
81
|
// Append workflow-specific rules to OpenCode's default prompt
|
|
@@ -61,6 +83,28 @@ ${memoryContext}
|
|
|
61
83
|
|
|
62
84
|
## Additional Rules for This Workflow
|
|
63
85
|
|
|
86
|
+
### Session Continuity
|
|
87
|
+
Maintain session-context.md via memory-update tool. Format:
|
|
88
|
+
\`\`\`
|
|
89
|
+
Goal: [What + success criteria]
|
|
90
|
+
Constraints: [Limits, mark UNCONFIRMED if inferred]
|
|
91
|
+
Decisions: [Key choices this session]
|
|
92
|
+
State:
|
|
93
|
+
Done: [Completed]
|
|
94
|
+
Now: [Current focus - ONE thing]
|
|
95
|
+
Next: [Queued]
|
|
96
|
+
Open Questions: [Uncertainties - mark UNCONFIRMED]
|
|
97
|
+
Working Set: [Files, bead ID, branch]
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
Update session-context.md when:
|
|
101
|
+
- Goal changes or clarifies
|
|
102
|
+
- Key decision made
|
|
103
|
+
- State shifts (Done/Now/Next)
|
|
104
|
+
- Uncertainty discovered
|
|
105
|
+
|
|
106
|
+
After compaction: Check session-context.md, ask 1-3 targeted questions if gaps exist.
|
|
107
|
+
|
|
64
108
|
### Beads Workflow
|
|
65
109
|
- PRESERVE: Bead IDs (bd-xxx format), bead states, in-progress task IDs
|
|
66
110
|
- DROP: Closed/completed beads (already tracked in git)
|
|
@@ -71,13 +115,13 @@ ${memoryContext}
|
|
|
71
115
|
|
|
72
116
|
### Memory System
|
|
73
117
|
If you discover:
|
|
74
|
-
- Gotchas/edge cases →
|
|
75
|
-
- Build/test commands →
|
|
76
|
-
- Code patterns/conventions →
|
|
77
|
-
- Architecture insights →
|
|
118
|
+
- Gotchas/edge cases → Save to .opencode/memory/project/gotchas.md
|
|
119
|
+
- Build/test commands → Save to .opencode/memory/project/commands.md
|
|
120
|
+
- Code patterns/conventions → Save to .opencode/memory/project/conventions.md
|
|
121
|
+
- Architecture insights → Save to .opencode/memory/project/architecture.md
|
|
78
122
|
|
|
79
123
|
### Preservation Priorities
|
|
80
|
-
- PRESERVE: File paths
|
|
124
|
+
- PRESERVE: File paths (file:line_number), user constraints, decisions, UNCONFIRMED items
|
|
81
125
|
- DROP: Failed attempts, superseded info, verbose tool outputs, exploration dead-ends
|
|
82
126
|
`;
|
|
83
127
|
},
|
|
@@ -12,7 +12,7 @@ let _isWSL: boolean | null = null;
|
|
|
12
12
|
export function isWSL(): boolean {
|
|
13
13
|
if (_isWSL !== null) return _isWSL;
|
|
14
14
|
try {
|
|
15
|
-
const fs = require("fs");
|
|
15
|
+
const fs = require("node:fs");
|
|
16
16
|
const release = fs.readFileSync("/proc/version", "utf8").toLowerCase();
|
|
17
17
|
_isWSL = release.includes("microsoft") || release.includes("wsl");
|
|
18
18
|
} catch {
|
|
@@ -28,7 +28,6 @@ export function isWSL(): boolean {
|
|
|
28
28
|
* @param message - Notification body
|
|
29
29
|
*/
|
|
30
30
|
export async function notify(
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
31
|
$: any,
|
|
33
32
|
title: string,
|
|
34
33
|
message: string,
|
|
@@ -39,7 +38,7 @@ export async function notify(
|
|
|
39
38
|
|
|
40
39
|
try {
|
|
41
40
|
if (platform === "darwin") {
|
|
42
|
-
await $`osascript -e ${
|
|
41
|
+
await $`osascript -e ${`display notification "${safeMessage}" with title "${safeTitle}"`}`;
|
|
43
42
|
} else if (platform === "linux") {
|
|
44
43
|
if (isWSL()) {
|
|
45
44
|
// WSL: try notify-send, fail silently
|
|
@@ -116,7 +116,7 @@ export const SessionsPlugin: Plugin = async ({ client }) => {
|
|
|
116
116
|
const userMessages = messageData.filter(
|
|
117
117
|
(m) => m.info?.role === "user",
|
|
118
118
|
);
|
|
119
|
-
summary +=
|
|
119
|
+
summary += "## Recent User Messages\n\n";
|
|
120
120
|
for (let i = 0; i < Math.min(userMessages.length, 5); i++) {
|
|
121
121
|
const m = userMessages[i];
|
|
122
122
|
const content = extractContent(m.info);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type ChildProcess, spawn } from "child_process";
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
import { join } from "path";
|
|
1
|
+
import { type ChildProcess, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
6
6
|
import { tool } from "@opencode-ai/plugin/tool";
|
|
7
7
|
|
|
@@ -155,7 +155,7 @@ export const SkillMcpPlugin: Plugin = async ({ directory }) => {
|
|
|
155
155
|
},
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
client.process.stdin?.write(JSON.stringify(request)
|
|
158
|
+
client.process.stdin?.write(`${JSON.stringify(request)}\n`);
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -232,10 +232,10 @@ export const SkillMcpPlugin: Plugin = async ({ directory }) => {
|
|
|
232
232
|
|
|
233
233
|
// Send initialized notification
|
|
234
234
|
proc.stdin?.write(
|
|
235
|
-
JSON.stringify({
|
|
235
|
+
`${JSON.stringify({
|
|
236
236
|
jsonrpc: "2.0",
|
|
237
237
|
method: "notifications/initialized",
|
|
238
|
-
})
|
|
238
|
+
})}\n`,
|
|
239
239
|
);
|
|
240
240
|
|
|
241
241
|
// Discover capabilities
|
|
@@ -430,7 +430,7 @@ The skill must be loaded first via the skill() tool to register its MCP config.`
|
|
|
430
430
|
if (args.skill_name) {
|
|
431
431
|
const toDisconnect: string[] = [];
|
|
432
432
|
for (const key of state.clients.keys()) {
|
|
433
|
-
if (key.startsWith(args.skill_name
|
|
433
|
+
if (key.startsWith(`${args.skill_name}:`)) {
|
|
434
434
|
toDisconnect.push(key);
|
|
435
435
|
}
|
|
436
436
|
}
|
|
@@ -440,11 +440,10 @@ The skill must be loaded first via the skill() tool to register its MCP config.`
|
|
|
440
440
|
state.clients.delete(key);
|
|
441
441
|
}
|
|
442
442
|
return JSON.stringify({ disconnected: toDisconnect });
|
|
443
|
-
} else {
|
|
444
|
-
const count = state.clients.size;
|
|
445
|
-
disconnectAll();
|
|
446
|
-
return JSON.stringify({ disconnected: "all", count });
|
|
447
443
|
}
|
|
444
|
+
const count = state.clients.size;
|
|
445
|
+
disconnectAll();
|
|
446
|
+
return JSON.stringify({ disconnected: "all", count });
|
|
448
447
|
},
|
|
449
448
|
}),
|
|
450
449
|
},
|
|
@@ -506,6 +506,50 @@ bd_claim(); // Gets frontend task that was waiting on API
|
|
|
506
506
|
5. **Use `bd_msg(to="all")`** - For team-wide announcements
|
|
507
507
|
6. **Sync regularly** - `bd_sync()` at session end
|
|
508
508
|
|
|
509
|
+
## Best Practices (from Steve Yegge)
|
|
510
|
+
|
|
511
|
+
### Daily/Weekly Maintenance
|
|
512
|
+
|
|
513
|
+
| Task | Frequency | Command | Why |
|
|
514
|
+
| ------------ | -------------- | --------------------- | ---------------------------------------------- |
|
|
515
|
+
| Health check | Weekly | `bd doctor` | Repairs database issues, detects orphaned work |
|
|
516
|
+
| Cleanup | Every few days | `bd cleanup --days 7` | Keep DB under 200-500 issues for performance |
|
|
517
|
+
| Upgrade | Weekly | `bd upgrade` | Get latest features and fixes |
|
|
518
|
+
| Git hooks | Once per repo | `bd hooks install` | Auto-sync on commit/merge/checkout |
|
|
519
|
+
|
|
520
|
+
### Key Principles
|
|
521
|
+
|
|
522
|
+
1. **Plan outside Beads first** - Use planning tools, then import tasks to beads
|
|
523
|
+
2. **One task per session, then restart** - Fresh context prevents confusion
|
|
524
|
+
3. **File lots of issues** - Any work >2 minutes should be tracked
|
|
525
|
+
4. **Use short prefixes** - `bd-`, `vc-`, `wy-` etc.
|
|
526
|
+
5. **"Land the plane" = PUSH** - `bd sync` means git push, not "ready when you are"
|
|
527
|
+
6. **Include issue ID in commits** - `git commit -m "Fix bug (bd-abc)"`
|
|
528
|
+
|
|
529
|
+
### Database Health
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
# Check database size
|
|
533
|
+
bd list --status=all --json | wc -l
|
|
534
|
+
|
|
535
|
+
# Target: under 200-500 issues
|
|
536
|
+
# If over, run cleanup more aggressively:
|
|
537
|
+
bd cleanup --days 3
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Git Hooks (Essential)
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
bd hooks install
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Installs hooks for:
|
|
547
|
+
|
|
548
|
+
- **pre-commit**: Sync before commit
|
|
549
|
+
- **post-merge**: Import changes after merge
|
|
550
|
+
- **pre-push**: Ensure sync before push
|
|
551
|
+
- **post-checkout**: Refresh after branch switch
|
|
552
|
+
|
|
509
553
|
## Quick Reference
|
|
510
554
|
|
|
511
555
|
```
|