opencodekit 0.18.2 → 0.18.3

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 (30) hide show
  1. package/dist/index.js +161 -38
  2. package/dist/template/.opencode/.version +1 -1
  3. package/dist/template/.opencode/AGENTS.md +39 -9
  4. package/dist/template/.opencode/AGENT_ALIGNMENT.md +6 -6
  5. package/dist/template/.opencode/agent/build.md +7 -103
  6. package/dist/template/.opencode/agent/general.md +0 -52
  7. package/dist/template/.opencode/agent/plan.md +10 -0
  8. package/dist/template/.opencode/agent/runner.md +79 -0
  9. package/dist/template/.opencode/command/create.md +13 -1
  10. package/dist/template/.opencode/command/init-context.md +20 -6
  11. package/dist/template/.opencode/command/init-user.md +18 -16
  12. package/dist/template/.opencode/command/lfg.md +3 -4
  13. package/dist/template/.opencode/command/ship.md +6 -48
  14. package/dist/template/.opencode/command/start.md +20 -3
  15. package/dist/template/.opencode/command/verify.md +12 -17
  16. package/dist/template/.opencode/context/README.md +29 -0
  17. package/dist/template/.opencode/memory/_templates/{STATE.md → state.md} +1 -1
  18. package/dist/template/.opencode/memory.db +0 -0
  19. package/dist/template/.opencode/memory.db-shm +0 -0
  20. package/dist/template/.opencode/memory.db-wal +0 -0
  21. package/dist/template/.opencode/opencode.json +131 -7
  22. package/dist/template/.opencode/package.json +1 -1
  23. package/dist/template/.opencode/plugin/lib/memory-helpers.ts +51 -16
  24. package/dist/template/.opencode/plugin/lib/memory-hooks.ts +1 -1
  25. package/dist/template/.opencode/skill/beads/references/TROUBLESHOOTING.md +25 -0
  26. package/dist/template/.opencode/skill/using-git-worktrees/SKILL.md +26 -0
  27. package/dist/template/.opencode/skill/verification-before-completion/references/VERIFICATION_PROTOCOL.md +67 -0
  28. package/package.json +1 -1
  29. /package/dist/template/.opencode/memory/_templates/{PROJECT.md → project.md} +0 -0
  30. /package/dist/template/.opencode/memory/_templates/{ROADMAP.md → roadmap.md} +0 -0
@@ -11,7 +11,7 @@
11
11
  "type-check": "tsc --noEmit"
12
12
  },
13
13
  "dependencies": {
14
- "@opencode-ai/plugin": "1.2.15"
14
+ "@opencode-ai/plugin": "1.2.19"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/node": "^25.3.0",
@@ -48,6 +48,8 @@ export const MAX_PROJECT_FILE_CHARS = 900;
48
48
  export const MAX_HANDOFF_CHARS = 2500;
49
49
  export const MAX_BEADS = 8;
50
50
  export const MAX_COMBINED_CONTEXT_CHARS = 10000;
51
+ const BEADS_DB_READ_ATTEMPTS = 3;
52
+ const BEADS_DB_RETRY_DELAY_MS = 500;
51
53
 
52
54
  // ============================================================================
53
55
  // Compaction Helpers
@@ -122,24 +124,57 @@ export async function readLatestHandoff(handoffDir: string): Promise<string> {
122
124
  return `Source: ${latest.name}\n${truncate(content, MAX_HANDOFF_CHARS)}`;
123
125
  }
124
126
 
125
- export function readInProgressBeads(directory: string): string {
127
+ function delay(ms: number): Promise<void> {
128
+ return new Promise((resolve) => setTimeout(resolve, ms));
129
+ }
130
+
131
+ export async function readInProgressBeads(directory: string): Promise<string> {
126
132
  const dbPath = path.join(directory, ".beads", "beads.db");
127
- let db: Database | undefined;
128
- try {
129
- db = new Database(dbPath, { readonly: true });
130
- const rows = db
131
- .query<{ id: string; title: string }, [number]>(
132
- "SELECT id, title FROM issues WHERE status = 'in_progress' ORDER BY updated_at DESC LIMIT ?",
133
- )
134
- .all(MAX_BEADS);
135
- return rows.length > 0
136
- ? rows.map((r) => `- ${r.id}: ${r.title}`).join("\n")
137
- : "";
138
- } catch {
139
- return "";
140
- } finally {
141
- db?.close();
133
+
134
+ for (let attempt = 0; attempt < BEADS_DB_READ_ATTEMPTS; attempt++) {
135
+ let db: Database | undefined;
136
+ try {
137
+ db = new Database(dbPath, { readonly: true });
138
+ const rows = db
139
+ .query<{ id: string; title: string }, [number]>(
140
+ "SELECT id, title FROM issues WHERE status = 'in_progress' ORDER BY updated_at DESC LIMIT ?",
141
+ )
142
+ .all(MAX_BEADS);
143
+ return rows.length > 0
144
+ ? rows.map((r) => `- ${r.id}: ${r.title}`).join("\n")
145
+ : "";
146
+ } catch (error) {
147
+ const code = String((error as { code?: string } | undefined)?.code ?? "");
148
+ const message = String(
149
+ (error as { message?: string } | undefined)?.message ?? error,
150
+ );
151
+ const isRetryable =
152
+ code.includes("SQLITE_BUSY") ||
153
+ code.includes("SQLITE_LOCKED") ||
154
+ message.includes("SQLITE_BUSY") ||
155
+ message.includes("SQLITE_LOCKED");
156
+
157
+ if (isRetryable && attempt < BEADS_DB_READ_ATTEMPTS - 1) {
158
+ await delay(BEADS_DB_RETRY_DELAY_MS);
159
+ continue;
160
+ }
161
+
162
+ if (isRetryable) {
163
+ console.warn(
164
+ `[memory] Failed to read beads.db after ${BEADS_DB_READ_ATTEMPTS} attempts: ${message}`,
165
+ );
166
+ } else {
167
+ console.warn(
168
+ `[memory] Failed to read beads.db, continuing without bead context: ${message}`,
169
+ );
170
+ }
171
+ return "";
172
+ } finally {
173
+ db?.close();
174
+ }
142
175
  }
176
+
177
+ return "";
143
178
  }
144
179
 
145
180
  // ============================================================================
@@ -180,7 +180,7 @@ export function createHooks(deps: HookDeps) {
180
180
  readLatestHandoff(handoffDir),
181
181
  ]);
182
182
 
183
- const beadsContext = readInProgressBeads(directory);
183
+ const beadsContext = await readInProgressBeads(directory);
184
184
 
185
185
  // Add relevant observations for session
186
186
  let knowledgeContext = "";
@@ -11,3 +11,28 @@
11
11
 
12
12
  - Run `br doctor` to repair database
13
13
  - Check git remote access
14
+
15
+ ## Database Lock / WAL Conflicts
16
+
17
+ **Symptoms:**
18
+
19
+ - `SQLITE_BUSY` or `SQLITE_LOCKED` errors when reading beads
20
+ - Stale `.beads/beads.db-wal` or `.beads/beads.db-journal` files after agent crash
21
+
22
+ **Cause:**
23
+ Agent interruption during bead operations can leave WAL/journal files in an inconsistent state.
24
+
25
+ **Fix:**
26
+
27
+ 1. Ensure no agents are actively writing to beads.db
28
+ 2. Remove stale lock files:
29
+ ```bash
30
+ rm -f .beads/beads.db-wal .beads/beads.db-journal
31
+ ```
32
+ 3. Run `br sync --flush-only` to rebuild from JSONL source of truth
33
+ 4. Verify: `br ready` should work without errors
34
+
35
+ **Prevention:**
36
+
37
+ - The memory plugin now retries bead.db reads automatically (3 attempts, 500ms delay)
38
+ - If persistent, check for zombie agent processes: `ps aux | grep opencode`
@@ -110,6 +110,32 @@ git worktree add "$path" -b "$BRANCH_NAME"
110
110
  cd "$path"
111
111
  ```
112
112
 
113
+ ## Worktree Tracking
114
+
115
+ After creating a worktree, persist its absolute path for session resume:
116
+
117
+ ```bash
118
+ # After creating worktree
119
+ mkdir -p .beads/artifacts/$BEAD_ID
120
+ echo "/absolute/path/to/worktree" > .beads/artifacts/$BEAD_ID/worktree.txt
121
+ ```
122
+
123
+ On session resume, restore the active worktree if tracking exists:
124
+
125
+ ```bash
126
+ # Check if worktree exists for active bead
127
+ if [ -f .beads/artifacts/$BEAD_ID/worktree.txt ]; then
128
+ WORKTREE_PATH=$(cat .beads/artifacts/$BEAD_ID/worktree.txt)
129
+ cd "$WORKTREE_PATH"
130
+ fi
131
+ ```
132
+
133
+ On worktree cleanup (after merge), remove the tracking file:
134
+
135
+ ```bash
136
+ rm -f .beads/artifacts/$BEAD_ID/worktree.txt
137
+ ```
138
+
113
139
  ### 3. Run Project Setup
114
140
 
115
141
  Auto-detect and run appropriate setup:
@@ -0,0 +1,67 @@
1
+ # Verification Protocol
2
+
3
+ ## Standard Gates
4
+
5
+ Run these gates in parallel where possible:
6
+
7
+ ### Parallel Group (independent — run simultaneously)
8
+
9
+ ```bash
10
+ # Gate 1: Typecheck
11
+ npm run typecheck 2>&1 &
12
+ PID_TC=$!
13
+
14
+ # Gate 2: Lint (incremental when possible)
15
+ # Full codebase:
16
+ npm run lint 2>&1 &
17
+ # Or incremental (changed files only):
18
+ # npx oxlint $(git diff --name-only --diff-filter=d HEAD | grep -E '\.(ts|tsx|js|jsx)$')
19
+ PID_LINT=$!
20
+
21
+ wait $PID_TC $PID_LINT
22
+ ```
23
+
24
+ ### Sequential Group (depends on parallel group passing)
25
+
26
+ ```bash
27
+ # Gate 3: Tests (incremental when possible)
28
+ # Full: npm test
29
+ # Incremental: npx vitest --changed
30
+ npm test
31
+
32
+ # Gate 4: Build (only if shipping)
33
+ npm run build
34
+ ```
35
+
36
+ ## Incremental Mode
37
+
38
+ Use incremental mode when:
39
+
40
+ - Only a few files changed (< 20 files)
41
+ - Not shipping/releasing (pre-commit, mid-development)
42
+
43
+ | Gate | Full Command | Incremental Command |
44
+ | --------- | ------------------- | ------------------------------------------ |
45
+ | Typecheck | `npm run typecheck` | `npm run typecheck` (always full — needed) |
46
+ | Lint | `npm run lint` | `npx oxlint $(git diff --name-only HEAD)` |
47
+ | Test | `npm test` | `npx vitest --changed` |
48
+ | Build | `npm run build` | Skip (only needed for ship/release) |
49
+
50
+ ## Gate Results Format
51
+
52
+ Report results as:
53
+
54
+ ```text
55
+ | Gate | Status | Time |
56
+ |-----------|--------|--------|
57
+ | Typecheck | PASS | 2.1s |
58
+ | Lint | PASS | 0.8s |
59
+ | Test | PASS | 5.3s |
60
+ | Build | SKIP | — |
61
+ ```
62
+
63
+ ## Failure Handling
64
+
65
+ - If any gate fails, stop and fix before proceeding
66
+ - Show the FULL error output for failed gates
67
+ - After fixing, re-run ONLY the failed gate(s) + any downstream gates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.18.2",
3
+ "version": "0.18.3",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": [
6
6
  "agents",