opencodekit 0.23.1 → 0.23.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 +354 -825
  2. package/dist/template/.opencode/AGENTS.md +15 -2
  3. package/dist/template/.opencode/command/init.md +198 -34
  4. package/dist/template/.opencode/context/fallow.md +137 -0
  5. package/dist/template/.opencode/opencode.json +12 -315
  6. package/dist/template/.opencode/plugin/codesearch.ts +730 -0
  7. package/dist/template/.opencode/plugin/memory/compile.ts +171 -186
  8. package/dist/template/.opencode/plugin/memory/index-generator.ts +118 -133
  9. package/dist/template/.opencode/plugin/memory/lint.ts +253 -275
  10. package/dist/template/.opencode/plugin/memory/tools.ts +224 -268
  11. package/dist/template/.opencode/plugin/memory/validate.ts +154 -164
  12. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-preview.ts +13 -30
  13. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-shared.ts +25 -0
  14. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search.ts +17 -34
  15. package/dist/template/.opencode/plugin/session-summary.ts +0 -2
  16. package/dist/template/.opencode/plugin/srcwalk.ts +646 -667
  17. package/dist/template/.opencode/skill/code-navigation/SKILL.md +10 -10
  18. package/dist/template/.opencode/skill/code-review-and-quality/SKILL.md +1 -1
  19. package/dist/template/.opencode/skill/condition-based-waiting/example.ts +15 -2
  20. package/dist/template/.opencode/skill/debugging-and-error-recovery/SKILL.md +1 -1
  21. package/dist/template/.opencode/skill/deep-module-design/SKILL.md +1 -1
  22. package/dist/template/.opencode/skill/fallow/SKILL.md +409 -0
  23. package/dist/template/.opencode/skill/fallow/references/cli-reference.md +1905 -0
  24. package/dist/template/.opencode/skill/fallow/references/gotchas.md +644 -0
  25. package/dist/template/.opencode/skill/fallow/references/patterns.md +791 -0
  26. package/dist/template/.opencode/skill/planning-and-task-breakdown/SKILL.md +1 -1
  27. package/dist/template/.opencode/skill/srcwalk/SKILL.md +10 -13
  28. package/dist/template/.opencode/skill/ubiquitous-language/SKILL.md +1 -1
  29. package/dist/template/.opencode/tool/grepsearch.ts +92 -103
  30. package/package.json +1 -1
@@ -10,7 +10,7 @@
10
10
 
11
11
  import { upsertMemoryFile } from "./db/maintenance.js";
12
12
  import type { ObservationRow } from "./db/types.js";
13
- import { getMemoryDB } from "./db.js";
13
+ import { getMemoryDB } from "./db/schema.js";
14
14
  import { TYPE_ICONS, parseConcepts } from "./helpers.js";
15
15
 
16
16
  // ============================================================================
@@ -18,17 +18,17 @@ import { TYPE_ICONS, parseConcepts } from "./helpers.js";
18
18
  // ============================================================================
19
19
 
20
20
  export interface IndexEntry {
21
- id: number;
22
- type: string;
23
- title: string;
24
- concepts: string[];
25
- created_at: string;
21
+ id: number;
22
+ type: string;
23
+ title: string;
24
+ concepts: string[];
25
+ created_at: string;
26
26
  }
27
27
 
28
28
  export interface IndexResult {
29
- entryCount: number;
30
- conceptCount: number;
31
- content: string;
29
+ entryCount: number;
30
+ conceptCount: number;
31
+ content: string;
32
32
  }
33
33
 
34
34
  // ============================================================================
@@ -40,131 +40,116 @@ export interface IndexResult {
40
40
  * Groups by type, lists concept clusters, and writes to memory_files.
41
41
  */
42
42
  export function generateMemoryIndex(): IndexResult {
43
- const db = getMemoryDB();
43
+ const db = getMemoryDB();
44
44
 
45
- const observations = db
46
- .query(
47
- `SELECT id, type, title, concepts, created_at FROM observations
45
+ const observations = db
46
+ .query(
47
+ `SELECT id, type, title, concepts, created_at FROM observations
48
48
  WHERE superseded_by IS NULL
49
49
  ORDER BY type, created_at_epoch DESC`,
50
- )
51
- .all() as Pick<
52
- ObservationRow,
53
- "id" | "type" | "title" | "concepts" | "created_at"
54
- >[];
55
-
56
- // Group by type
57
- const byType = new Map<string, IndexEntry[]>();
58
- const allConcepts = new Map<string, number[]>();
59
-
60
- for (const obs of observations) {
61
- const entry: IndexEntry = {
62
- id: obs.id,
63
- type: obs.type,
64
- title: obs.title,
65
- concepts: parseConcepts(obs.concepts),
66
- created_at: obs.created_at,
67
- };
68
-
69
- const group = byType.get(obs.type) ?? [];
70
- group.push(entry);
71
- byType.set(obs.type, group);
72
-
73
- for (const concept of entry.concepts) {
74
- const ids = allConcepts.get(concept) ?? [];
75
- ids.push(obs.id);
76
- allConcepts.set(concept, ids);
77
- }
78
- }
79
-
80
- // Build markdown
81
- const lines: string[] = [];
82
- lines.push("# Memory Index");
83
- lines.push("");
84
- lines.push(
85
- `> Auto-generated catalog of ${observations.length} active observations.`,
86
- );
87
- lines.push(`> Last updated: ${new Date().toISOString().slice(0, 19)}`);
88
- lines.push("");
89
-
90
- // Summary table
91
- lines.push("## Summary");
92
- lines.push("");
93
- lines.push("| Type | Count |");
94
- lines.push("|------|-------|");
95
- for (const [type, entries] of byType) {
96
- const icon = TYPE_ICONS[type] ?? "📌";
97
- lines.push(`| ${icon} ${type} | ${entries.length} |`);
98
- }
99
- lines.push(`| **Total** | **${observations.length}** |`);
100
- lines.push("");
101
-
102
- // By type
103
- for (const [type, entries] of byType) {
104
- const icon = TYPE_ICONS[type] ?? "📌";
105
- lines.push(
106
- `## ${icon} ${type.charAt(0).toUpperCase() + type.slice(1)} (${entries.length})`,
107
- );
108
- lines.push("");
109
- for (const entry of entries) {
110
- const concepts =
111
- entry.concepts.length > 0 ? ` [${entry.concepts.join(", ")}]` : "";
112
- lines.push(
113
- `- **#${entry.id}** ${entry.title}${concepts} _(${entry.created_at.slice(0, 10)})_`,
114
- );
115
- }
116
- lines.push("");
117
- }
118
-
119
- // Concept clusters
120
- const significantConcepts = [...allConcepts.entries()]
121
- .filter(([, ids]) => ids.length >= 2)
122
- .sort((a, b) => b[1].length - a[1].length);
123
-
124
- if (significantConcepts.length > 0) {
125
- lines.push("## Concept Clusters");
126
- lines.push("");
127
- lines.push("Concepts appearing in 2+ observations:");
128
- lines.push("");
129
- for (const [concept, ids] of significantConcepts.slice(0, 30)) {
130
- lines.push(
131
- `- **${concept}** (${ids.length}): ${ids.map((id) => `#${id}`).join(", ")}`,
132
- );
133
- }
134
- lines.push("");
135
- }
136
-
137
- // Orphan concepts
138
- const orphanConcepts = [...allConcepts.entries()].filter(
139
- ([, ids]) => ids.length === 1,
140
- );
141
-
142
- if (orphanConcepts.length > 0) {
143
- lines.push("## Orphan Concepts");
144
- lines.push("");
145
- lines.push(
146
- `${orphanConcepts.length} concepts appear in only 1 observation:`,
147
- );
148
- lines.push("");
149
- const orphanList = orphanConcepts
150
- .slice(0, 20)
151
- .map(([concept, ids]) => `${concept} (#${ids[0]})`);
152
- lines.push(orphanList.join(", "));
153
- if (orphanConcepts.length > 20) {
154
- lines.push(`... and ${orphanConcepts.length - 20} more`);
155
- }
156
- lines.push("");
157
- }
158
-
159
- const content = lines.join("\n");
160
-
161
- // Store in memory_files
162
- upsertMemoryFile("index", content, "replace");
163
-
164
- return {
165
- entryCount: observations.length,
166
- conceptCount: allConcepts.size,
167
- content,
168
- };
50
+ )
51
+ .all() as Pick<ObservationRow, "id" | "type" | "title" | "concepts" | "created_at">[];
52
+
53
+ // Group by type
54
+ const byType = new Map<string, IndexEntry[]>();
55
+ const allConcepts = new Map<string, number[]>();
56
+
57
+ for (const obs of observations) {
58
+ const entry: IndexEntry = {
59
+ id: obs.id,
60
+ type: obs.type,
61
+ title: obs.title,
62
+ concepts: parseConcepts(obs.concepts),
63
+ created_at: obs.created_at,
64
+ };
65
+
66
+ const group = byType.get(obs.type) ?? [];
67
+ group.push(entry);
68
+ byType.set(obs.type, group);
69
+
70
+ for (const concept of entry.concepts) {
71
+ const ids = allConcepts.get(concept) ?? [];
72
+ ids.push(obs.id);
73
+ allConcepts.set(concept, ids);
74
+ }
75
+ }
76
+
77
+ // Build markdown
78
+ const lines: string[] = [];
79
+ lines.push("# Memory Index");
80
+ lines.push("");
81
+ lines.push(`> Auto-generated catalog of ${observations.length} active observations.`);
82
+ lines.push(`> Last updated: ${new Date().toISOString().slice(0, 19)}`);
83
+ lines.push("");
84
+
85
+ // Summary table
86
+ lines.push("## Summary");
87
+ lines.push("");
88
+ lines.push("| Type | Count |");
89
+ lines.push("|------|-------|");
90
+ for (const [type, entries] of byType) {
91
+ const icon = TYPE_ICONS[type] ?? "📌";
92
+ lines.push(`| ${icon} ${type} | ${entries.length} |`);
93
+ }
94
+ lines.push(`| **Total** | **${observations.length}** |`);
95
+ lines.push("");
96
+
97
+ // By type
98
+ for (const [type, entries] of byType) {
99
+ const icon = TYPE_ICONS[type] ?? "📌";
100
+ lines.push(`## ${icon} ${type.charAt(0).toUpperCase() + type.slice(1)} (${entries.length})`);
101
+ lines.push("");
102
+ for (const entry of entries) {
103
+ const concepts = entry.concepts.length > 0 ? ` [${entry.concepts.join(", ")}]` : "";
104
+ lines.push(
105
+ `- **#${entry.id}** ${entry.title}${concepts} _(${entry.created_at.slice(0, 10)})_`,
106
+ );
107
+ }
108
+ lines.push("");
109
+ }
110
+
111
+ // Concept clusters
112
+ const significantConcepts = [...allConcepts.entries()]
113
+ .filter(([, ids]) => ids.length >= 2)
114
+ .sort((a, b) => b[1].length - a[1].length);
115
+
116
+ if (significantConcepts.length > 0) {
117
+ lines.push("## Concept Clusters");
118
+ lines.push("");
119
+ lines.push("Concepts appearing in 2+ observations:");
120
+ lines.push("");
121
+ for (const [concept, ids] of significantConcepts.slice(0, 30)) {
122
+ lines.push(`- **${concept}** (${ids.length}): ${ids.map((id) => `#${id}`).join(", ")}`);
123
+ }
124
+ lines.push("");
125
+ }
126
+
127
+ // Orphan concepts
128
+ const orphanConcepts = [...allConcepts.entries()].filter(([, ids]) => ids.length === 1);
129
+
130
+ if (orphanConcepts.length > 0) {
131
+ lines.push("## Orphan Concepts");
132
+ lines.push("");
133
+ lines.push(`${orphanConcepts.length} concepts appear in only 1 observation:`);
134
+ lines.push("");
135
+ const orphanList = orphanConcepts
136
+ .slice(0, 20)
137
+ .map(([concept, ids]) => `${concept} (#${ids[0]})`);
138
+ lines.push(orphanList.join(", "));
139
+ if (orphanConcepts.length > 20) {
140
+ lines.push(`... and ${orphanConcepts.length - 20} more`);
141
+ }
142
+ lines.push("");
143
+ }
144
+
145
+ const content = lines.join("\n");
146
+
147
+ // Store in memory_files
148
+ upsertMemoryFile("index", content, "replace");
149
+
150
+ return {
151
+ entryCount: observations.length,
152
+ conceptCount: allConcepts.size,
153
+ content,
154
+ };
169
155
  }
170
-