opencodekit 0.16.0 → 0.16.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/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +64 -3
- package/dist/template/.opencode/command/create.md +34 -0
- package/dist/template/.opencode/command/design.md +35 -0
- package/dist/template/.opencode/command/handoff.md +15 -0
- package/dist/template/.opencode/command/init.md +40 -47
- package/dist/template/.opencode/command/plan.md +1 -0
- package/dist/template/.opencode/command/pr.md +15 -0
- package/dist/template/.opencode/command/research.md +3 -0
- package/dist/template/.opencode/command/resume.md +1 -0
- package/dist/template/.opencode/command/review-codebase.md +30 -0
- package/dist/template/.opencode/command/ship.md +43 -0
- package/dist/template/.opencode/command/start.md +1 -0
- package/dist/template/.opencode/command/status.md +24 -1
- package/dist/template/.opencode/command/ui-review.md +31 -0
- package/dist/template/.opencode/command/verify.md +35 -7
- package/dist/template/.opencode/memory/project/tech-stack.md +25 -22
- package/dist/template/.opencode/memory.db +0 -0
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/opencode.json +817 -916
- package/dist/template/.opencode/package.json +1 -0
- package/dist/template/.opencode/plans/1770006237537-mighty-otter.md +418 -0
- package/dist/template/.opencode/plans/1770006913647-glowing-forest.md +170 -0
- package/dist/template/.opencode/plans/1770013678126-witty-planet.md +278 -0
- package/dist/template/.opencode/plugin/lib/memory-db.ts +828 -0
- package/dist/template/.opencode/plugin/memory.ts +38 -1
- package/dist/template/.opencode/skill/index-knowledge/SKILL.md +76 -31
- package/dist/template/.opencode/skill/memory-system/SKILL.md +110 -55
- package/dist/template/.opencode/tool/memory-get.ts +143 -0
- package/dist/template/.opencode/tool/memory-maintain.ts +167 -0
- package/dist/template/.opencode/tool/memory-migrate.ts +319 -0
- package/dist/template/.opencode/tool/memory-read.ts +17 -46
- package/dist/template/.opencode/tool/memory-search.ts +131 -28
- package/dist/template/.opencode/tool/memory-timeline.ts +105 -0
- package/dist/template/.opencode/tool/memory-update.ts +21 -26
- package/dist/template/.opencode/tool/observation.ts +112 -100
- package/dist/template/.opencode/tsconfig.json +19 -19
- package/package.json +1 -1
- package/dist/template/.opencode/memory/_templates/README.md +0 -73
- package/dist/template/.opencode/memory/_templates/observation.md +0 -39
- package/dist/template/.opencode/memory/_templates/prompt-engineering.md +0 -333
- package/dist/template/.opencode/memory/observations/2026-01-22-decision-agents-md-prompt-engineering-improvement.md +0 -29
- package/dist/template/.opencode/memory/observations/2026-01-25-decision-agent-roles-build-orchestrates-general-e.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-01-25-decision-simplified-swarm-helper-tool-to-fix-type.md +0 -20
- package/dist/template/.opencode/memory/observations/2026-01-25-decision-use-beads-as-swarm-board-source-of-truth.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-01-25-learning-user-wants-real-swarm-coordination-guida.md +0 -15
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-created-deep-research-skill-for-thorough.md +0 -29
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-gh-grep-mcp-wrapper-vs-native-grep-searc.md +0 -21
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-oracle-tool-optimal-usage-patterns.md +0 -32
- package/dist/template/.opencode/memory/observations/2026-01-28-learning-ampcode-deep-mode-research-integration-w.md +0 -42
- package/dist/template/.opencode/memory/observations/2026-01-28-pattern-research-delegation-pattern-explore-for-.md +0 -32
- package/dist/template/.opencode/memory/observations/2026-01-29-decision-copilot-auth-plugin-rate-limit-handling.md +0 -27
- package/dist/template/.opencode/memory/observations/2026-01-29-decision-spec-driven-approach-for-opencodekit.md +0 -21
- package/dist/template/.opencode/memory/observations/2026-01-29-learning-karpathy-llm-coding-insights-dec-2025.md +0 -44
- package/dist/template/.opencode/memory/observations/2026-01-30-decision-github-copilot-claude-routing-keep-disab.md +0 -32
- package/dist/template/.opencode/memory/observations/2026-01-30-discovery-context-management-research-critical-gap.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-01-30-discovery-kimi-k2-5-agent-swarm-architecture-patte.md +0 -45
- package/dist/template/.opencode/memory/observations/2026-01-30-pattern-swarm-tools-architecture.md +0 -28
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-copilot-auth-plugin-updated-with-baseurl.md +0 -63
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-created-dedicated-worker-agent-for-swarm.md +0 -20
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-rollback-to-v1-1-47-for-copilot-claude-r.md +0 -21
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-simplified-swarm-to-task-tool-pattern.md +0 -44
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-swarm-architecture-task-tool-over-tmux.md +0 -33
- package/dist/template/.opencode/memory/observations/2026-01-31-decision-worker-skills-defined-for-swarm-delegati.md +0 -30
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-gpt-reasoning-config-for-github-copilot.md +0 -51
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-copilot-auth-comparison-finding.md +0 -61
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-copilot-reasoning-architecture-.md +0 -66
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-custom-tools-api.md +0 -48
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-v1-1-48-skills-as-slash-command.md +0 -21
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-swarm-system-simplified-removed-mailbox-.md +0 -30
- package/dist/template/.opencode/memory/observations/2026-01-31-learning-v1-1-48-native-copilot-reasoning-via-pr-.md +0 -45
- package/dist/template/.opencode/memory/observations/2026-01-31-warning-cannot-add-custom-config-to-opencode-jso.md +0 -18
- package/dist/template/.opencode/memory/observations/2026-01-31-warning-copilot-claude-v1-endpoint-returns-404-c.md +0 -48
- package/dist/template/.opencode/memory/observations/2026-01-31-warning-opencode-v1-1-48-claude-thinking-block-s.md +0 -51
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-add-skills-vs-commands-to-global-agents-.md +0 -15
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-build-agent-auto-loads-skills-contextual.md +0 -31
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-fixed-agent-configuration-for-opencodeki.md +0 -25
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-focused-agents-md-upgrade-for-opencode-k.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-implement-tier-1-permission-upgrades.md +0 -15
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-instructions-config-explicit-paths-not-w.md +0 -40
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-merged-context-into-memory-project-singl.md +0 -42
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-oracle-tool-should-use-review-agent-not-.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-plan-agent-auto-loads-skills-contextuall.md +0 -31
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-plan-phased-oracle-command-merge-into-ne.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-prd-workflow-uses-prd-and-prd-task-skill.md +0 -23
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-prefer-review-agent-via-opencode-cli-ove.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-remove-oracle-tool-add-ship-command-with.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-remove-oracle-tool-and-add-ship-command-.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-remove-oracle-tool-and-add-ship-command.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-remove-skills-vs-commands-section-from-a.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-replace-oracle-tool-with-ship-command-fl.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-replace-oracle-with-ship-command-workflo.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-replace-proxypal-oracle-with-cli-review-.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-simplified-dist-template-only-tech-stack.md +0 -50
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-simplified-templates-only-tech-stack-md.md +0 -26
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-subagents-load-minimal-skills-stay-lean.md +0 -29
- package/dist/template/.opencode/memory/observations/2026-02-01-decision-user-approved-permission-upgrades-in-ope.md +0 -15
- package/dist/template/.opencode/memory/observations/2026-02-01-discovery-verify-command-already-implemented.md +0 -28
- package/dist/template/.opencode/memory/observations/2026-02-01-feature-openspec-phase-b-complete-template-upgra.md +0 -43
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-build-agent-should-use-dynamic-lsp-not-f.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-kimi-k2-5-model-requires-temperature-1-0.md +0 -22
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-opencode-context-injection-already-imple.md +0 -27
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-opencode-context-injection-uses-instruct.md +0 -35
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-update-build-agent-prompt-to-use-context.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-upgrade-agents-md-using-opencode-expert-.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-upgrade-agents-md-with-opencode-expert-g.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-upgrade-agents-md-with-opencode-expert-r.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-user-prefers-copilot-gpt-5-2-codex-mediu.md +0 -14
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-user-wants-general-agent-prompt-contextu.md +0 -15
- package/dist/template/.opencode/memory/observations/2026-02-01-learning-user-wants-general-agent-prompt-reviewed.md +0 -15
- package/dist/template/.opencode/memory/project/architecture.md +0 -60
- package/dist/template/.opencode/memory/project/command-rules.md +0 -122
- package/dist/template/.opencode/memory/project/commands.md +0 -72
- package/dist/template/.opencode/memory/project/conventions.md +0 -68
- package/dist/template/.opencode/memory/project/gotchas.md +0 -41
- /package/dist/template/.opencode/memory/_templates/{project/tech-stack.md → tech-stack.md} +0 -0
- /package/dist/template/.opencode/memory/{user.example.md → _templates/user.md} +0 -0
- /package/dist/template/.opencode/memory/{user.md → project/user.md} +0 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# Memory System Upgrade Plan
|
|
2
|
+
|
|
3
|
+
**Goal**: Upgrade OpenCodeKit memory from file-based markdown to hybrid SQLite + FTS5 with progressive disclosure.
|
|
4
|
+
|
|
5
|
+
**Key Benefits**:
|
|
6
|
+
|
|
7
|
+
1. **10x token savings** via progressive disclosure (compact index → timeline → full details)
|
|
8
|
+
2. **Fast full-text search** via SQLite FTS5 (vs O(n) regex scan)
|
|
9
|
+
3. **Richer schema** with facts, narrative, files_read/modified distinction
|
|
10
|
+
4. **Backward compatible** - existing tools continue working, markdown remains human-readable
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1: Database Foundation
|
|
15
|
+
|
|
16
|
+
### 1.1 Create SQLite Module
|
|
17
|
+
|
|
18
|
+
**File**: `.opencode/plugin/lib/memory-db.ts`
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// Core database class using bun:sqlite
|
|
22
|
+
import { Database } from "bun:sqlite";
|
|
23
|
+
|
|
24
|
+
const DB_PATH = path.join(process.cwd(), ".opencode/memory.db");
|
|
25
|
+
|
|
26
|
+
export function getMemoryDB(): Database {
|
|
27
|
+
const db = new Database(DB_PATH, { create: true });
|
|
28
|
+
db.run("PRAGMA journal_mode = WAL"); // Better concurrency
|
|
29
|
+
db.run("PRAGMA foreign_keys = ON");
|
|
30
|
+
initializeSchema(db);
|
|
31
|
+
return db;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 1.2 Database Schema
|
|
36
|
+
|
|
37
|
+
**File**: `.opencode/plugin/lib/memory-schema.ts`
|
|
38
|
+
|
|
39
|
+
**Tables**:
|
|
40
|
+
|
|
41
|
+
- `schema_versions` - Migration tracking
|
|
42
|
+
- `observations` - Enhanced observation records
|
|
43
|
+
- `observations_fts` - FTS5 virtual table
|
|
44
|
+
- `memory_files` - Non-observation memory files
|
|
45
|
+
|
|
46
|
+
**Schema**:
|
|
47
|
+
|
|
48
|
+
```sql
|
|
49
|
+
CREATE TABLE IF NOT EXISTS observations (
|
|
50
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
51
|
+
type TEXT NOT NULL CHECK(type IN ('decision','bugfix','feature','pattern','discovery','learning','warning')),
|
|
52
|
+
title TEXT NOT NULL,
|
|
53
|
+
subtitle TEXT,
|
|
54
|
+
facts TEXT, -- JSON array
|
|
55
|
+
narrative TEXT, -- Long-form content
|
|
56
|
+
concepts TEXT, -- JSON array
|
|
57
|
+
files_read TEXT, -- JSON array
|
|
58
|
+
files_modified TEXT, -- JSON array
|
|
59
|
+
confidence TEXT CHECK(confidence IN ('high','medium','low')) DEFAULT 'high',
|
|
60
|
+
bead_id TEXT,
|
|
61
|
+
supersedes INTEGER,
|
|
62
|
+
superseded_by INTEGER,
|
|
63
|
+
valid_until TEXT,
|
|
64
|
+
markdown_file TEXT, -- Reference to backup markdown file
|
|
65
|
+
created_at TEXT NOT NULL,
|
|
66
|
+
created_at_epoch INTEGER NOT NULL,
|
|
67
|
+
updated_at TEXT
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
-- FTS5 for full-text search
|
|
71
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5(
|
|
72
|
+
title, subtitle, narrative, facts, concepts,
|
|
73
|
+
content='observations', content_rowid='id'
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
-- Auto-sync triggers for FTS5
|
|
77
|
+
CREATE TRIGGER observations_fts_ai AFTER INSERT ON observations BEGIN
|
|
78
|
+
INSERT INTO observations_fts(rowid, title, subtitle, narrative, facts, concepts)
|
|
79
|
+
VALUES (new.id, new.title, new.subtitle, new.narrative, new.facts, new.concepts);
|
|
80
|
+
END;
|
|
81
|
+
-- (plus UPDATE and DELETE triggers)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Phase 2: Progressive Disclosure Tools
|
|
87
|
+
|
|
88
|
+
### 2.1 Update `memory-search.ts` - Compact Index
|
|
89
|
+
|
|
90
|
+
**File**: `.opencode/tool/memory-search.ts`
|
|
91
|
+
|
|
92
|
+
**Change**: Return compact index instead of full content.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// NEW: Returns compact index only (~50-100 tokens per result)
|
|
96
|
+
interface SearchIndexResult {
|
|
97
|
+
id: number;
|
|
98
|
+
type: string;
|
|
99
|
+
title: string;
|
|
100
|
+
snippet: string; // First 100 chars of narrative
|
|
101
|
+
created_at: string;
|
|
102
|
+
relevance_score: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
execute: async (args) => {
|
|
106
|
+
const db = getMemoryDB();
|
|
107
|
+
|
|
108
|
+
// Check if FTS5 available (bun:sqlite supports it)
|
|
109
|
+
const useFTS = checkFTS5Available(db);
|
|
110
|
+
|
|
111
|
+
if (useFTS && args.query) {
|
|
112
|
+
// Use FTS5 for text search with ranking
|
|
113
|
+
const results = db
|
|
114
|
+
.query(
|
|
115
|
+
`
|
|
116
|
+
SELECT o.id, o.type, o.title,
|
|
117
|
+
substr(o.narrative, 1, 100) as snippet,
|
|
118
|
+
o.created_at,
|
|
119
|
+
bm25(observations_fts) as relevance_score
|
|
120
|
+
FROM observations o
|
|
121
|
+
JOIN observations_fts fts ON fts.rowid = o.id
|
|
122
|
+
WHERE observations_fts MATCH ?
|
|
123
|
+
ORDER BY relevance_score
|
|
124
|
+
LIMIT ?
|
|
125
|
+
`,
|
|
126
|
+
)
|
|
127
|
+
.all(args.query, args.limit || 10);
|
|
128
|
+
return formatCompactIndex(results);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Fallback to regex search (backward compat)
|
|
132
|
+
return fallbackKeywordSearch(args);
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2.2 Create `memory-timeline.ts` - Chronological Context
|
|
137
|
+
|
|
138
|
+
**File**: `.opencode/tool/memory-timeline.ts` (NEW)
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// Get observations around an anchor point
|
|
142
|
+
execute: async (args) => {
|
|
143
|
+
const db = getMemoryDB();
|
|
144
|
+
const anchor = db
|
|
145
|
+
.query(
|
|
146
|
+
`
|
|
147
|
+
SELECT created_at_epoch FROM observations WHERE id = ?
|
|
148
|
+
`,
|
|
149
|
+
)
|
|
150
|
+
.get(args.anchor_id);
|
|
151
|
+
|
|
152
|
+
const before = db
|
|
153
|
+
.query(
|
|
154
|
+
`
|
|
155
|
+
SELECT id, type, title, substr(narrative, 1, 100) as snippet
|
|
156
|
+
FROM observations
|
|
157
|
+
WHERE created_at_epoch < ?
|
|
158
|
+
ORDER BY created_at_epoch DESC
|
|
159
|
+
LIMIT ?
|
|
160
|
+
`,
|
|
161
|
+
)
|
|
162
|
+
.all(anchor.created_at_epoch, args.depth_before || 5);
|
|
163
|
+
|
|
164
|
+
const after = db
|
|
165
|
+
.query(
|
|
166
|
+
`
|
|
167
|
+
SELECT id, type, title, substr(narrative, 1, 100) as snippet
|
|
168
|
+
FROM observations
|
|
169
|
+
WHERE created_at_epoch > ?
|
|
170
|
+
ORDER BY created_at_epoch ASC
|
|
171
|
+
LIMIT ?
|
|
172
|
+
`,
|
|
173
|
+
)
|
|
174
|
+
.all(anchor.created_at_epoch, args.depth_after || 5);
|
|
175
|
+
|
|
176
|
+
return { anchor: args.anchor_id, before: before.reverse(), after };
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 2.3 Create `memory-get.ts` - Full Details
|
|
181
|
+
|
|
182
|
+
**File**: `.opencode/tool/memory-get.ts` (NEW)
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Get full observation details by ID(s)
|
|
186
|
+
execute: async (args) => {
|
|
187
|
+
const db = getMemoryDB();
|
|
188
|
+
const ids = args.ids.split(",").map(Number);
|
|
189
|
+
|
|
190
|
+
const observations = db
|
|
191
|
+
.query(
|
|
192
|
+
`
|
|
193
|
+
SELECT * FROM observations WHERE id IN (${ids.join(",")})
|
|
194
|
+
`,
|
|
195
|
+
)
|
|
196
|
+
.all();
|
|
197
|
+
|
|
198
|
+
return observations.map(formatFullObservation);
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Phase 3: Enhanced Observation Tool
|
|
205
|
+
|
|
206
|
+
### 3.1 Update `observation.ts` - Dual Write + Enhanced Schema
|
|
207
|
+
|
|
208
|
+
**File**: `.opencode/tool/observation.ts`
|
|
209
|
+
|
|
210
|
+
**New Args**:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
args: {
|
|
214
|
+
type: string;
|
|
215
|
+
title: string;
|
|
216
|
+
subtitle?: string; // NEW
|
|
217
|
+
facts?: string; // NEW: Comma-separated structured facts
|
|
218
|
+
narrative?: string; // NEW: Renamed from 'content'
|
|
219
|
+
content?: string; // DEPRECATED: Alias for narrative (backward compat)
|
|
220
|
+
concepts?: string;
|
|
221
|
+
files_read?: string; // NEW: Files read during task
|
|
222
|
+
files_modified?: string; // NEW: Files changed during task
|
|
223
|
+
files?: string; // DEPRECATED: Alias for files_modified
|
|
224
|
+
bead_id?: string;
|
|
225
|
+
confidence?: string;
|
|
226
|
+
supersedes?: string;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Execute**:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
execute: async (args) => {
|
|
234
|
+
const normalized = normalizeArgs(args); // Handle deprecated fields
|
|
235
|
+
|
|
236
|
+
// 1. Write to SQLite
|
|
237
|
+
const db = getMemoryDB();
|
|
238
|
+
const result = db
|
|
239
|
+
.query(
|
|
240
|
+
`
|
|
241
|
+
INSERT INTO observations (type, title, subtitle, facts, narrative, concepts,
|
|
242
|
+
files_read, files_modified, confidence, bead_id,
|
|
243
|
+
markdown_file, created_at, created_at_epoch)
|
|
244
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
245
|
+
`,
|
|
246
|
+
)
|
|
247
|
+
.run(/* ... */);
|
|
248
|
+
|
|
249
|
+
// 2. Write to markdown (backup)
|
|
250
|
+
const markdownPath = generateMarkdownPath(normalized);
|
|
251
|
+
await fs.writeFile(markdownPath, renderToMarkdown(normalized, result.lastInsertRowid));
|
|
252
|
+
|
|
253
|
+
return `✓ Observation #${result.lastInsertRowid} saved (SQLite + markdown backup)`;
|
|
254
|
+
};
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Phase 4: Migration Script
|
|
260
|
+
|
|
261
|
+
### 4.1 Create Migration Tool
|
|
262
|
+
|
|
263
|
+
**File**: `.opencode/tool/memory-migrate.ts` (NEW)
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
execute: async () => {
|
|
267
|
+
const obsDir = path.join(process.cwd(), ".opencode/memory/observations");
|
|
268
|
+
const db = getMemoryDB();
|
|
269
|
+
|
|
270
|
+
// Get all markdown files
|
|
271
|
+
const files = await fs.readdir(obsDir);
|
|
272
|
+
const mdFiles = files.filter((f) => f.endsWith(".md") && !f.startsWith("."));
|
|
273
|
+
|
|
274
|
+
let migrated = 0,
|
|
275
|
+
errors = [];
|
|
276
|
+
|
|
277
|
+
for (const file of mdFiles) {
|
|
278
|
+
try {
|
|
279
|
+
const content = await fs.readFile(path.join(obsDir, file), "utf-8");
|
|
280
|
+
const parsed = parseMarkdownObservation(content, file);
|
|
281
|
+
|
|
282
|
+
// Insert into SQLite
|
|
283
|
+
db.query(`INSERT INTO observations ...`).run(parsed);
|
|
284
|
+
migrated++;
|
|
285
|
+
} catch (e) {
|
|
286
|
+
errors.push({ file, error: e.message });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Write migration marker
|
|
291
|
+
await fs.writeFile(
|
|
292
|
+
path.join(obsDir, ".migrated"),
|
|
293
|
+
`Migrated ${migrated} observations on ${new Date().toISOString()}`,
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
return `✓ Migration complete: ${migrated} observations, ${errors.length} errors`;
|
|
297
|
+
};
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Phase 5: Update Existing Tools
|
|
303
|
+
|
|
304
|
+
### 5.1 Update `memory-read.ts`
|
|
305
|
+
|
|
306
|
+
Add SQLite lookup before file fallback:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
execute: async (args) => {
|
|
310
|
+
// NEW: Check for observation by ID
|
|
311
|
+
if (args.file?.match(/^#?\d+$/)) {
|
|
312
|
+
const db = getMemoryDB();
|
|
313
|
+
const id = parseInt(args.file.replace("#", ""));
|
|
314
|
+
const obs = db.query("SELECT * FROM observations WHERE id = ?").get(id);
|
|
315
|
+
if (obs) return formatFullObservation(obs);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Existing file-based lookup (unchanged)
|
|
319
|
+
return readMarkdownFile(args.file);
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### 5.2 Update `memory-update.ts`
|
|
324
|
+
|
|
325
|
+
Add dual-write to SQLite:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
execute: async (args) => {
|
|
329
|
+
const db = getMemoryDB();
|
|
330
|
+
|
|
331
|
+
// Write to SQLite memory_files table
|
|
332
|
+
db.query(
|
|
333
|
+
`
|
|
334
|
+
INSERT INTO memory_files (file_path, content, mode, created_at, created_at_epoch)
|
|
335
|
+
VALUES (?, ?, ?, ?, ?)
|
|
336
|
+
ON CONFLICT(file_path) DO UPDATE SET content = ?, updated_at = ?
|
|
337
|
+
`,
|
|
338
|
+
).run(/* ... */);
|
|
339
|
+
|
|
340
|
+
// Also write to markdown (unchanged)
|
|
341
|
+
await writeMarkdownFile(args.file, args.content, args.mode);
|
|
342
|
+
|
|
343
|
+
return `Updated ${args.file} (SQLite + markdown)`;
|
|
344
|
+
};
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Implementation Order
|
|
350
|
+
|
|
351
|
+
| Order | Task | Files | Effort | Depends On |
|
|
352
|
+
| ----- | ------------------------- | --------------------------------------- | ------ | ---------- |
|
|
353
|
+
| 1 | Create memory-db.ts | `.opencode/plugin/lib/memory-db.ts` | 3h | - |
|
|
354
|
+
| 2 | Create memory-schema.ts | `.opencode/plugin/lib/memory-schema.ts` | 2h | 1 |
|
|
355
|
+
| 3 | Create memory-migrate.ts | `.opencode/tool/memory-migrate.ts` | 3h | 1, 2 |
|
|
356
|
+
| 4 | Update observation.ts | `.opencode/tool/observation.ts` | 3h | 1, 2 |
|
|
357
|
+
| 5 | Update memory-search.ts | `.opencode/tool/memory-search.ts` | 3h | 1, 2 |
|
|
358
|
+
| 6 | Create memory-timeline.ts | `.opencode/tool/memory-timeline.ts` | 2h | 1, 2 |
|
|
359
|
+
| 7 | Create memory-get.ts | `.opencode/tool/memory-get.ts` | 2h | 1, 2 |
|
|
360
|
+
| 8 | Update memory-read.ts | `.opencode/tool/memory-read.ts` | 1h | 1, 2 |
|
|
361
|
+
| 9 | Update memory-update.ts | `.opencode/tool/memory-update.ts` | 1h | 1, 2 |
|
|
362
|
+
| 10 | Update memory.ts plugin | `.opencode/plugin/memory.ts` | 2h | 4, 5 |
|
|
363
|
+
|
|
364
|
+
**Total**: ~22 hours of implementation
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Files to Modify/Create
|
|
369
|
+
|
|
370
|
+
**NEW FILES**:
|
|
371
|
+
|
|
372
|
+
- `.opencode/plugin/lib/memory-db.ts` - SQLite database manager
|
|
373
|
+
- `.opencode/plugin/lib/memory-schema.ts` - Schema definitions + migrations
|
|
374
|
+
- `.opencode/tool/memory-migrate.ts` - Migration tool
|
|
375
|
+
- `.opencode/tool/memory-timeline.ts` - Timeline context tool
|
|
376
|
+
- `.opencode/tool/memory-get.ts` - Full observation retrieval
|
|
377
|
+
|
|
378
|
+
**MODIFY**:
|
|
379
|
+
|
|
380
|
+
- `.opencode/tool/observation.ts` - Dual write + enhanced schema
|
|
381
|
+
- `.opencode/tool/memory-search.ts` - FTS5 + compact index
|
|
382
|
+
- `.opencode/tool/memory-read.ts` - SQLite lookup + fallback
|
|
383
|
+
- `.opencode/tool/memory-update.ts` - Dual write
|
|
384
|
+
- `.opencode/plugin/memory.ts` - Add FTS5 optimization hook
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Verification
|
|
389
|
+
|
|
390
|
+
### Manual Testing
|
|
391
|
+
|
|
392
|
+
1. Run `memory-migrate` to import existing observations
|
|
393
|
+
2. Create new observation with `observation` tool
|
|
394
|
+
3. Search with `memory-search` and verify FTS5 is used
|
|
395
|
+
4. Use `memory-timeline` around a result
|
|
396
|
+
5. Use `memory-get` to fetch full details
|
|
397
|
+
6. Verify markdown backups are created
|
|
398
|
+
7. Verify existing tools still work (backward compat)
|
|
399
|
+
|
|
400
|
+
### Check Database
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Verify SQLite file created
|
|
404
|
+
ls -la .opencode/memory.db
|
|
405
|
+
|
|
406
|
+
# Verify FTS5 table
|
|
407
|
+
sqlite3 .opencode/memory.db "SELECT * FROM observations_fts LIMIT 5;"
|
|
408
|
+
|
|
409
|
+
# Verify observation count matches markdown files
|
|
410
|
+
sqlite3 .opencode/memory.db "SELECT COUNT(*) FROM observations;"
|
|
411
|
+
ls .opencode/memory/observations/*.md | wc -l
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Backward Compatibility
|
|
415
|
+
|
|
416
|
+
1. `memory-read({ file: "handoffs/2024-01-01" })` still works
|
|
417
|
+
2. `observation({ type: "decision", title: "X", content: "Y" })` still works (deprecated `content` field)
|
|
418
|
+
3. `memory-search({ query: "auth" })` returns results (may be faster with FTS5)
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Plan: Implement `/create` Command for Bead Artifacts
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
Implement a new CLI command `ock create <bead-id>` that creates structured artifacts for beads using templates. This command will set up the artifact directory structure and copy appropriate templates (spec.md, prd.md, or proposal.md) based on flags.
|
|
6
|
+
|
|
7
|
+
## Phases
|
|
8
|
+
|
|
9
|
+
### Phase 1: Create Command Implementation
|
|
10
|
+
|
|
11
|
+
**Owner**: @build
|
|
12
|
+
**Deliverable**: `src/commands/create.ts` file
|
|
13
|
+
**Files to Create**:
|
|
14
|
+
|
|
15
|
+
- `src/commands/create.ts` - Main command implementation
|
|
16
|
+
|
|
17
|
+
**Implementation Details**:
|
|
18
|
+
|
|
19
|
+
The command follows the established pattern from `skill.ts` and `command.ts`:
|
|
20
|
+
|
|
21
|
+
1. **Argument Parsing**:
|
|
22
|
+
- `<bead-id>` (required) - The bead to create artifacts for
|
|
23
|
+
- `--prd` flag - Use PRD template (combined format)
|
|
24
|
+
- `--proposal` flag - Create proposal.md first (for epics)
|
|
25
|
+
|
|
26
|
+
2. **Validation**:
|
|
27
|
+
- Check if `.opencode/` exists (project initialized)
|
|
28
|
+
- Check if `.beads/` exists (beads initialized)
|
|
29
|
+
- Validate bead-id format (lowercase, alphanumeric, hyphens)
|
|
30
|
+
- Check if artifact directory already exists
|
|
31
|
+
|
|
32
|
+
3. **Directory Structure**:
|
|
33
|
+
- Create `.beads/artifacts/<bead-id>/` directory
|
|
34
|
+
- Copy templates from `.opencode/memory/_templates/`
|
|
35
|
+
|
|
36
|
+
4. **Template Selection Logic**:
|
|
37
|
+
| Flag | Template(s) Created |
|
|
38
|
+
|------|---------------------|
|
|
39
|
+
| (none) | spec.md |
|
|
40
|
+
| `--prd` | prd.md |
|
|
41
|
+
| `--proposal` | proposal.md + spec.md |
|
|
42
|
+
|
|
43
|
+
5. **Template Variable Substitution**:
|
|
44
|
+
- Replace `[bead-id]` with actual bead ID
|
|
45
|
+
- Replace `[date]` with current date (YYYY-MM-DD)
|
|
46
|
+
- Replace `[YYYY-MM-DD]` with current date
|
|
47
|
+
|
|
48
|
+
6. **Interactive Prompts** (when no flags):
|
|
49
|
+
- Ask for bead title/description if not provided
|
|
50
|
+
- Ask for template type preference
|
|
51
|
+
|
|
52
|
+
**Validation Steps**:
|
|
53
|
+
|
|
54
|
+
- Run `npm run typecheck` - TypeScript compiles without errors
|
|
55
|
+
- Run `npm run lint` - No linting errors
|
|
56
|
+
|
|
57
|
+
### Phase 2: Register Command in CLI
|
|
58
|
+
|
|
59
|
+
**Owner**: @build
|
|
60
|
+
**Deliverable**: Updated `src/index.ts`
|
|
61
|
+
**Files to Modify**:
|
|
62
|
+
|
|
63
|
+
- `src/index.ts` - Add command registration
|
|
64
|
+
|
|
65
|
+
**Changes**:
|
|
66
|
+
|
|
67
|
+
1. Import `createCommand` from `./commands/create.js`
|
|
68
|
+
2. Register CLI command:
|
|
69
|
+
```typescript
|
|
70
|
+
cli
|
|
71
|
+
.command("create <bead-id>", "Create structured artifacts for a bead")
|
|
72
|
+
.option("--prd", "Use PRD template (combined format)")
|
|
73
|
+
.option("--proposal", "Create proposal.md first (for epics)")
|
|
74
|
+
.action(createCommand);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Validation Steps**:
|
|
78
|
+
|
|
79
|
+
- Run `bun run src/index.ts create --help` - Shows help text
|
|
80
|
+
- Run `npm run typecheck` - No type errors
|
|
81
|
+
|
|
82
|
+
### Phase 3: Testing
|
|
83
|
+
|
|
84
|
+
**Owner**: @build
|
|
85
|
+
**Deliverable**: Verified command works end-to-end
|
|
86
|
+
|
|
87
|
+
**Test Cases**:
|
|
88
|
+
|
|
89
|
+
1. **Basic spec creation**:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
ock create test-bead-123
|
|
93
|
+
# Expected: Creates .beads/artifacts/test-bead-123/spec.md
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
2. **PRD template**:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
ock create test-bead-456 --prd
|
|
100
|
+
# Expected: Creates .beads/artifacts/test-bead-456/prd.md
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. **Proposal template**:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
ock create test-epic-789 --proposal
|
|
107
|
+
# Expected: Creates .beads/artifacts/test-epic-789/proposal.md AND spec.md
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
4. **Error cases**:
|
|
111
|
+
- Missing bead-id: Shows usage help
|
|
112
|
+
- Invalid bead-id format: Shows validation error
|
|
113
|
+
- Project not initialized: Shows "Run: ock init" error
|
|
114
|
+
- Beads not initialized: Shows warning
|
|
115
|
+
- Artifact already exists: Shows confirmation prompt
|
|
116
|
+
|
|
117
|
+
**Validation Steps**:
|
|
118
|
+
|
|
119
|
+
- Run `bun test src/commands/create.test.ts` (if test file created)
|
|
120
|
+
- Manual testing of all scenarios above
|
|
121
|
+
|
|
122
|
+
## Dependencies
|
|
123
|
+
|
|
124
|
+
- Phase 2 depends on Phase 1 completion
|
|
125
|
+
- Phase 3 depends on Phase 2 completion
|
|
126
|
+
|
|
127
|
+
## Risks
|
|
128
|
+
|
|
129
|
+
| Risk | Likelihood | Impact | Mitigation |
|
|
130
|
+
| ------------------------------ | ---------- | ------ | -------------------------------------------------------------- |
|
|
131
|
+
| Template files not found | Low | High | Check template existence, show clear error with fix suggestion |
|
|
132
|
+
| Bead ID validation too strict | Medium | Low | Allow common formats, provide clear validation messages |
|
|
133
|
+
| Overwriting existing artifacts | Low | High | Check before creating, prompt for confirmation |
|
|
134
|
+
|
|
135
|
+
## Acceptance Criteria
|
|
136
|
+
|
|
137
|
+
- [ ] `ock create <bead-id>` creates `.beads/artifacts/<bead-id>/spec.md` from template
|
|
138
|
+
- [ ] `ock create <bead-id> --prd` creates `prd.md` instead
|
|
139
|
+
- [ ] `ock create <bead-id> --proposal` creates both `proposal.md` and `spec.md`
|
|
140
|
+
- [ ] Template variables (bead-id, date) are substituted correctly
|
|
141
|
+
- [ ] Validates project is initialized (`.opencode/` exists)
|
|
142
|
+
- [ ] Validates beads is initialized (`.beads/` exists) or warns
|
|
143
|
+
- [ ] Shows clear error for invalid bead-id format
|
|
144
|
+
- [ ] Prompts for confirmation if artifacts already exist
|
|
145
|
+
- [ ] TypeScript compiles without errors (`npm run typecheck`)
|
|
146
|
+
- [ ] No linting errors (`npm run lint`)
|
|
147
|
+
- [ ] Command appears in `ock --help` output
|
|
148
|
+
|
|
149
|
+
## Critical Files to Modify
|
|
150
|
+
|
|
151
|
+
| File | Purpose |
|
|
152
|
+
| ------------------------ | -------------------------- |
|
|
153
|
+
| `src/commands/create.ts` | New command implementation |
|
|
154
|
+
| `src/index.ts` | CLI registration |
|
|
155
|
+
|
|
156
|
+
## Templates Used
|
|
157
|
+
|
|
158
|
+
| Template | Path |
|
|
159
|
+
| ----------- | ----------------------------------------- |
|
|
160
|
+
| spec.md | `.opencode/memory/_templates/spec.md` |
|
|
161
|
+
| prd.md | `.opencode/memory/_templates/prd.md` |
|
|
162
|
+
| proposal.md | `.opencode/memory/_templates/proposal.md` |
|
|
163
|
+
|
|
164
|
+
## Notes
|
|
165
|
+
|
|
166
|
+
- Follow existing command patterns from `skill.ts` and `command.ts`
|
|
167
|
+
- Use `@clack/prompts` for interactive elements
|
|
168
|
+
- Use `picocolors` for styling
|
|
169
|
+
- Reuse error utilities from `src/utils/errors.ts`
|
|
170
|
+
- Bead ID validation: lowercase letters, numbers, hyphens (start with letter)
|