opencodekit 0.15.21 → 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.
Files changed (144) hide show
  1. package/dist/index.js +5 -7
  2. package/dist/template/.opencode/AGENTS.md +85 -23
  3. package/dist/template/.opencode/agent/build.md +88 -7
  4. package/dist/template/.opencode/agent/explore.md +1 -1
  5. package/dist/template/.opencode/agent/general.md +54 -4
  6. package/dist/template/.opencode/agent/looker.md +1 -1
  7. package/dist/template/.opencode/agent/painter.md +1 -1
  8. package/dist/template/.opencode/agent/plan.md +52 -0
  9. package/dist/template/.opencode/agent/review.md +1 -1
  10. package/dist/template/.opencode/agent/scout.md +3 -3
  11. package/dist/template/.opencode/agent/vision.md +1 -1
  12. package/dist/template/.opencode/command/create.md +231 -91
  13. package/dist/template/.opencode/command/design.md +40 -7
  14. package/dist/template/.opencode/command/handoff.md +22 -0
  15. package/dist/template/.opencode/command/init.md +49 -78
  16. package/dist/template/.opencode/command/plan.md +36 -16
  17. package/dist/template/.opencode/command/pr.md +15 -0
  18. package/dist/template/.opencode/command/research.md +3 -0
  19. package/dist/template/.opencode/command/resume.md +8 -18
  20. package/dist/template/.opencode/command/review-codebase.md +30 -0
  21. package/dist/template/.opencode/command/ship.md +199 -0
  22. package/dist/template/.opencode/command/start.md +316 -28
  23. package/dist/template/.opencode/command/status.md +24 -1
  24. package/dist/template/.opencode/command/ui-review.md +36 -7
  25. package/dist/template/.opencode/command/verify.md +307 -0
  26. package/dist/template/.opencode/memory/_templates/prd.md +29 -0
  27. package/dist/template/.opencode/memory/_templates/proposal.md +38 -0
  28. package/dist/template/.opencode/memory/_templates/spec.md +66 -0
  29. package/dist/template/.opencode/memory/_templates/tasks.md +198 -0
  30. package/dist/template/.opencode/memory/_templates/tech-stack.md +50 -0
  31. package/dist/template/.opencode/memory/project/tech-stack.md +53 -0
  32. package/dist/template/.opencode/memory/research/ccpm-analysis.md +334 -0
  33. package/dist/template/.opencode/memory/research/openspec-analysis.md +226 -0
  34. package/dist/template/.opencode/memory.db +0 -0
  35. package/dist/template/.opencode/memory.db-shm +0 -0
  36. package/dist/template/.opencode/memory.db-wal +0 -0
  37. package/dist/template/.opencode/opencode.json +18 -4
  38. package/dist/template/.opencode/package.json +1 -0
  39. package/dist/template/.opencode/plans/1770006237537-mighty-otter.md +418 -0
  40. package/dist/template/.opencode/plans/1770006913647-glowing-forest.md +170 -0
  41. package/dist/template/.opencode/plans/1770013678126-witty-planet.md +278 -0
  42. package/dist/template/.opencode/plugin/lib/memory-db.ts +828 -0
  43. package/dist/template/.opencode/plugin/memory.ts +38 -1
  44. package/dist/template/.opencode/skill/index-knowledge/SKILL.md +76 -31
  45. package/dist/template/.opencode/skill/memory-system/SKILL.md +110 -55
  46. package/dist/template/.opencode/skill/tool-priority/SKILL.md +2 -2
  47. package/dist/template/.opencode/tool/memory-get.ts +143 -0
  48. package/dist/template/.opencode/tool/memory-maintain.ts +167 -0
  49. package/dist/template/.opencode/tool/memory-migrate.ts +319 -0
  50. package/dist/template/.opencode/tool/memory-read.ts +17 -46
  51. package/dist/template/.opencode/tool/memory-search.ts +131 -28
  52. package/dist/template/.opencode/tool/memory-timeline.ts +105 -0
  53. package/dist/template/.opencode/tool/memory-update.ts +21 -26
  54. package/dist/template/.opencode/tool/observation.ts +112 -100
  55. package/dist/template/.opencode/tsconfig.json +19 -19
  56. package/package.json +1 -1
  57. package/dist/template/.opencode/command/accessibility-check.md +0 -331
  58. package/dist/template/.opencode/command/agent-browser.md +0 -21
  59. package/dist/template/.opencode/command/analyze-mockup.md +0 -423
  60. package/dist/template/.opencode/command/analyze-project.md +0 -295
  61. package/dist/template/.opencode/command/brainstorm.md +0 -373
  62. package/dist/template/.opencode/command/cloudflare.md +0 -70
  63. package/dist/template/.opencode/command/commit.md +0 -245
  64. package/dist/template/.opencode/command/complete-next-task.md +0 -77
  65. package/dist/template/.opencode/command/design-audit.md +0 -480
  66. package/dist/template/.opencode/command/edit-image.md +0 -242
  67. package/dist/template/.opencode/command/finish.md +0 -255
  68. package/dist/template/.opencode/command/fix-ci.md +0 -109
  69. package/dist/template/.opencode/command/fix-types.md +0 -104
  70. package/dist/template/.opencode/command/fix-ui.md +0 -117
  71. package/dist/template/.opencode/command/fix.md +0 -168
  72. package/dist/template/.opencode/command/frontend-design.md +0 -21
  73. package/dist/template/.opencode/command/generate-diagram.md +0 -349
  74. package/dist/template/.opencode/command/generate-icon.md +0 -283
  75. package/dist/template/.opencode/command/generate-image.md +0 -246
  76. package/dist/template/.opencode/command/generate-pattern.md +0 -247
  77. package/dist/template/.opencode/command/generate-storyboard.md +0 -250
  78. package/dist/template/.opencode/command/implement.md +0 -609
  79. package/dist/template/.opencode/command/import-plan.md +0 -406
  80. package/dist/template/.opencode/command/index-knowledge.md +0 -25
  81. package/dist/template/.opencode/command/integration-test.md +0 -424
  82. package/dist/template/.opencode/command/issue.md +0 -102
  83. package/dist/template/.opencode/command/new-feature.md +0 -651
  84. package/dist/template/.opencode/command/opensrc.md +0 -58
  85. package/dist/template/.opencode/command/quick-build.md +0 -238
  86. package/dist/template/.opencode/command/ralph.md +0 -41
  87. package/dist/template/.opencode/command/research-and-implement.md +0 -148
  88. package/dist/template/.opencode/command/research-ui.md +0 -466
  89. package/dist/template/.opencode/command/restore-image.md +0 -424
  90. package/dist/template/.opencode/command/revert-feature.md +0 -386
  91. package/dist/template/.opencode/command/skill-create.md +0 -517
  92. package/dist/template/.opencode/command/skill-optimize.md +0 -556
  93. package/dist/template/.opencode/command/summarize.md +0 -412
  94. package/dist/template/.opencode/command/triage.md +0 -398
  95. package/dist/template/.opencode/memory/_templates/README.md +0 -35
  96. package/dist/template/.opencode/memory/_templates/observation.md +0 -39
  97. package/dist/template/.opencode/memory/_templates/project/architecture.md +0 -60
  98. package/dist/template/.opencode/memory/_templates/project/commands.md +0 -72
  99. package/dist/template/.opencode/memory/_templates/project/conventions.md +0 -68
  100. package/dist/template/.opencode/memory/_templates/project/gotchas.md +0 -41
  101. package/dist/template/.opencode/memory/_templates/prompt-engineering.md +0 -333
  102. package/dist/template/.opencode/memory/observations/2026-01-22-decision-agents-md-prompt-engineering-improvement.md +0 -29
  103. package/dist/template/.opencode/memory/observations/2026-01-25-decision-agent-roles-build-orchestrates-general-e.md +0 -14
  104. package/dist/template/.opencode/memory/observations/2026-01-25-decision-simplified-swarm-helper-tool-to-fix-type.md +0 -20
  105. package/dist/template/.opencode/memory/observations/2026-01-25-decision-use-beads-as-swarm-board-source-of-truth.md +0 -14
  106. package/dist/template/.opencode/memory/observations/2026-01-25-learning-user-wants-real-swarm-coordination-guida.md +0 -15
  107. package/dist/template/.opencode/memory/observations/2026-01-28-decision-created-deep-research-skill-for-thorough.md +0 -29
  108. package/dist/template/.opencode/memory/observations/2026-01-28-decision-gh-grep-mcp-wrapper-vs-native-grep-searc.md +0 -21
  109. package/dist/template/.opencode/memory/observations/2026-01-28-decision-oracle-tool-optimal-usage-patterns.md +0 -32
  110. package/dist/template/.opencode/memory/observations/2026-01-28-learning-ampcode-deep-mode-research-integration-w.md +0 -42
  111. package/dist/template/.opencode/memory/observations/2026-01-28-pattern-research-delegation-pattern-explore-for-.md +0 -32
  112. package/dist/template/.opencode/memory/observations/2026-01-29-decision-copilot-auth-plugin-rate-limit-handling.md +0 -27
  113. package/dist/template/.opencode/memory/observations/2026-01-29-decision-spec-driven-approach-for-opencodekit.md +0 -21
  114. package/dist/template/.opencode/memory/observations/2026-01-29-learning-karpathy-llm-coding-insights-dec-2025.md +0 -44
  115. package/dist/template/.opencode/memory/observations/2026-01-30-decision-github-copilot-claude-routing-keep-disab.md +0 -32
  116. package/dist/template/.opencode/memory/observations/2026-01-30-discovery-context-management-research-critical-gap.md +0 -14
  117. package/dist/template/.opencode/memory/observations/2026-01-30-discovery-kimi-k2-5-agent-swarm-architecture-patte.md +0 -45
  118. package/dist/template/.opencode/memory/observations/2026-01-30-pattern-swarm-tools-architecture.md +0 -28
  119. package/dist/template/.opencode/memory/observations/2026-01-31-decision-copilot-auth-plugin-updated-with-baseurl.md +0 -63
  120. package/dist/template/.opencode/memory/observations/2026-01-31-decision-created-dedicated-worker-agent-for-swarm.md +0 -20
  121. package/dist/template/.opencode/memory/observations/2026-01-31-decision-rollback-to-v1-1-47-for-copilot-claude-r.md +0 -21
  122. package/dist/template/.opencode/memory/observations/2026-01-31-decision-simplified-swarm-to-task-tool-pattern.md +0 -44
  123. package/dist/template/.opencode/memory/observations/2026-01-31-decision-swarm-architecture-task-tool-over-tmux.md +0 -33
  124. package/dist/template/.opencode/memory/observations/2026-01-31-decision-worker-skills-defined-for-swarm-delegati.md +0 -30
  125. package/dist/template/.opencode/memory/observations/2026-01-31-learning-gpt-reasoning-config-for-github-copilot.md +0 -51
  126. package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-copilot-auth-comparison-finding.md +0 -61
  127. package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-copilot-reasoning-architecture-.md +0 -66
  128. package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-custom-tools-api.md +0 -48
  129. package/dist/template/.opencode/memory/observations/2026-01-31-learning-opencode-v1-1-48-skills-as-slash-command.md +0 -21
  130. package/dist/template/.opencode/memory/observations/2026-01-31-learning-swarm-system-simplified-removed-mailbox-.md +0 -30
  131. package/dist/template/.opencode/memory/observations/2026-01-31-learning-v1-1-48-native-copilot-reasoning-via-pr-.md +0 -45
  132. package/dist/template/.opencode/memory/observations/2026-01-31-warning-cannot-add-custom-config-to-opencode-jso.md +0 -18
  133. package/dist/template/.opencode/memory/observations/2026-01-31-warning-copilot-claude-v1-endpoint-returns-404-c.md +0 -48
  134. package/dist/template/.opencode/memory/observations/2026-01-31-warning-opencode-v1-1-48-claude-thinking-block-s.md +0 -51
  135. package/dist/template/.opencode/memory/project/architecture.md +0 -60
  136. package/dist/template/.opencode/memory/project/commands.md +0 -72
  137. package/dist/template/.opencode/memory/project/conventions.md +0 -68
  138. package/dist/template/.opencode/memory/project/gotchas.md +0 -41
  139. package/dist/template/.opencode/skill/notebooklm/SKILL.md +0 -272
  140. package/dist/template/.opencode/skill/notebooklm/references/setup.md +0 -353
  141. package/dist/template/.opencode/tool/notebooklm.ts +0 -488
  142. package/dist/template/.opencode/tool/oracle.ts +0 -240
  143. /package/dist/template/.opencode/memory/{user.example.md → _templates/user.md} +0 -0
  144. /package/dist/template/.opencode/memory/{user.md → project/user.md} +0 -0
@@ -1,18 +1,10 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
1
  import { tool } from "@opencode-ai/plugin";
4
-
5
- // Observation types following claude-mem patterns
6
- type ObservationType =
7
- | "decision"
8
- | "bugfix"
9
- | "feature"
10
- | "pattern"
11
- | "discovery"
12
- | "learning"
13
- | "warning";
14
-
15
- type ConfidenceLevel = "high" | "medium" | "low";
2
+ import {
3
+ type ConfidenceLevel,
4
+ type ObservationInput,
5
+ type ObservationType,
6
+ storeObservation,
7
+ } from "../plugin/lib/memory-db.js";
16
8
 
17
9
  const TYPE_ICONS: Record<ObservationType, string> = {
18
10
  decision: "🎯",
@@ -78,14 +70,15 @@ export default tool({
78
70
  Purpose:
79
71
  - Capture decisions, bugs, features, patterns, discoveries, learnings, or warnings
80
72
  - Auto-detects file references from content (file:line, \`path\`, src/, .opencode/)
81
- - Stores in .opencode/memory/observations/ with YAML frontmatter
82
- - Optionally updates bead notes and handles observation supersession
73
+ - Stores in SQLite with FTS5 index for fast search
74
+ - Supports enhanced schema: facts, subtitle, files_read/files_modified
83
75
 
84
76
  Example:
85
77
  observation({
86
78
  type: "decision",
87
79
  title: "Use JWT for auth",
88
- content: "Decided to use JWT tokens because...",
80
+ narrative: "Decided to use JWT tokens because...",
81
+ facts: "stateless, scalable, industry standard",
89
82
  concepts: "authentication, jwt, security",
90
83
  confidence: "high"
91
84
  })`,
@@ -96,20 +89,43 @@ export default tool({
96
89
  "Observation type: decision, bugfix, feature, pattern, discovery, learning, warning",
97
90
  ),
98
91
  title: tool.schema.string().describe("Brief title for the observation"),
99
- content: tool.schema
92
+ subtitle: tool.schema
93
+ .string()
94
+ .optional()
95
+ .describe("Optional subtitle or tagline"),
96
+ facts: tool.schema
100
97
  .string()
98
+ .optional()
99
+ .describe("Comma-separated key facts (e.g., 'stateless, scalable')"),
100
+ narrative: tool.schema
101
+ .string()
102
+ .optional()
101
103
  .describe("Detailed observation content with context"),
104
+ content: tool.schema
105
+ .string()
106
+ .optional()
107
+ .describe(
108
+ "DEPRECATED: Use 'narrative' instead. Alias for backward compat.",
109
+ ),
102
110
  concepts: tool.schema
103
111
  .string()
104
112
  .optional()
105
113
  .describe(
106
114
  "Comma-separated concept tags (e.g., 'authentication, oauth, security')",
107
115
  ),
116
+ files_read: tool.schema
117
+ .string()
118
+ .optional()
119
+ .describe("Comma-separated files that were read (e.g., 'src/auth.ts')"),
120
+ files_modified: tool.schema
121
+ .string()
122
+ .optional()
123
+ .describe("Comma-separated files that were modified"),
108
124
  files: tool.schema
109
125
  .string()
110
126
  .optional()
111
127
  .describe(
112
- "Comma-separated related files (e.g., 'src/auth.ts, src/login.ts')",
128
+ "DEPRECATED: Use 'files_modified' instead. Alias for backward compat.",
113
129
  ),
114
130
  bead_id: tool.schema
115
131
  .string()
@@ -125,21 +141,24 @@ export default tool({
125
141
  .string()
126
142
  .optional()
127
143
  .describe(
128
- "Filename of observation this supersedes (for contradiction handling)",
144
+ "ID or filename of observation this supersedes (for contradiction handling)",
129
145
  ),
130
146
  },
131
147
  execute: async (args: {
132
148
  type: string;
133
149
  title: string;
134
- content: string;
150
+ subtitle?: string;
151
+ facts?: string;
152
+ narrative?: string;
153
+ content?: string;
135
154
  concepts?: string;
155
+ files_read?: string;
156
+ files_modified?: string;
136
157
  files?: string;
137
158
  bead_id?: string;
138
159
  confidence?: string;
139
160
  supersedes?: string;
140
161
  }) => {
141
- const obsDir = path.join(process.cwd(), ".opencode/memory/observations");
142
-
143
162
  // Validate type
144
163
  const validTypes: ObservationType[] = [
145
164
  "decision",
@@ -163,96 +182,77 @@ export default tool({
163
182
  return `Error: Invalid confidence level '${args.confidence}'.\nValid levels: ${validConfidence.join(", ")}`;
164
183
  }
165
184
 
166
- // Generate filename: YYYY-MM-DD-type-slug.md
167
- const now = new Date();
168
- const dateStr = now.toISOString().split("T")[0];
169
- const slug = args.title
170
- .toLowerCase()
171
- .replace(/[^a-z0-9]+/g, "-")
172
- .replace(/^-|-$/g, "")
173
- .substring(0, 40);
174
- const filename = `${dateStr}-${obsType}-${slug}.md`;
175
- const filePath = path.join(obsDir, filename);
185
+ // Handle deprecated fields (backward compat)
186
+ const narrative = args.narrative || args.content || "";
187
+ const filesModifiedRaw = args.files_modified || args.files || "";
176
188
 
177
- // Parse concepts and files
189
+ // Parse arrays from comma-separated strings
190
+ const facts = args.facts
191
+ ? args.facts
192
+ .split(",")
193
+ .map((f) => f.trim())
194
+ .filter(Boolean)
195
+ : [];
178
196
  const concepts = args.concepts
179
- ? args.concepts.split(",").map((c) => c.trim())
197
+ ? args.concepts
198
+ .split(",")
199
+ .map((c) => c.trim())
200
+ .filter(Boolean)
201
+ : [];
202
+ let filesRead = args.files_read
203
+ ? args.files_read
204
+ .split(",")
205
+ .map((f) => f.trim())
206
+ .filter(Boolean)
207
+ : [];
208
+ const filesModified = filesModifiedRaw
209
+ ? filesModifiedRaw
210
+ .split(",")
211
+ .map((f) => f.trim())
212
+ .filter(Boolean)
180
213
  : [];
181
- let files = args.files ? args.files.split(",").map((f) => f.trim()) : [];
182
214
 
183
- // Auto-detect file references from content
184
- const detectedRefs = extractFileReferences(args.content);
215
+ // Auto-detect file references from narrative
216
+ const detectedRefs = extractFileReferences(narrative);
185
217
  const detectedFiles = detectedRefs.map((r) => r.file);
186
218
 
187
219
  // Merge detected files with explicitly provided files
188
- const allFiles = [...new Set([...files, ...detectedFiles])];
189
- files = allFiles;
190
-
191
- // Build observation content with YAML frontmatter
192
- const icon = TYPE_ICONS[obsType];
193
- const confidenceIcon = CONFIDENCE_ICONS[confidence];
220
+ filesRead = [...new Set([...filesRead, ...detectedFiles])];
194
221
 
195
- // YAML frontmatter for temporal validity
196
- let observation = "---\n";
197
- observation += `type: ${obsType}\n`;
198
- observation += `created: ${now.toISOString()}\n`;
199
- observation += `confidence: ${confidence}\n`;
200
- observation += "valid_until: null\n";
201
- observation += "superseded_by: null\n";
222
+ // Parse supersedes (could be numeric ID or filename)
223
+ let supersedesId: number | undefined;
202
224
  if (args.supersedes) {
203
- observation += `supersedes: ${args.supersedes}\n`;
204
- }
205
- if (args.bead_id) {
206
- observation += `bead_id: ${args.bead_id}\n`;
207
- }
208
- if (concepts.length > 0) {
209
- observation += `concepts: [${concepts.map((c) => `"${c}"`).join(", ")}]\n`;
210
- }
211
- if (files.length > 0) {
212
- observation += `files: [${files.map((f) => `"${f}"`).join(", ")}]\n`;
225
+ const parsed = Number.parseInt(args.supersedes, 10);
226
+ if (!Number.isNaN(parsed)) {
227
+ supersedesId = parsed;
228
+ }
213
229
  }
214
- observation += "---\n\n";
215
230
 
216
- // Content
217
- observation += `# ${icon} ${args.title}\n\n`;
218
- observation += `${confidenceIcon} **Confidence:** ${confidence}\n\n`;
219
- observation += args.content;
220
- observation += "\n";
231
+ // Prepare observation input
232
+ const input: ObservationInput = {
233
+ type: obsType,
234
+ title: args.title,
235
+ subtitle: args.subtitle,
236
+ facts: facts.length > 0 ? facts : undefined,
237
+ narrative: narrative || undefined,
238
+ concepts: concepts.length > 0 ? concepts : undefined,
239
+ files_read: filesRead.length > 0 ? filesRead : undefined,
240
+ files_modified: filesModified.length > 0 ? filesModified : undefined,
241
+ confidence,
242
+ bead_id: args.bead_id,
243
+ supersedes: supersedesId,
244
+ };
221
245
 
222
246
  try {
223
- // Ensure directory exists
224
- await fs.mkdir(obsDir, { recursive: true });
225
-
226
- // Write observation
227
- await fs.writeFile(filePath, observation, "utf-8");
228
-
229
- // Handle supersedes - update old observation's superseded_by field
230
- let supersedesStatus = "";
231
- if (args.supersedes) {
232
- try {
233
- const oldPath = path.join(obsDir, args.supersedes);
234
- const oldContent = await fs.readFile(oldPath, "utf-8");
235
- // Update superseded_by in frontmatter
236
- const updatedContent = oldContent.replace(
237
- /superseded_by: null/,
238
- `superseded_by: "${filename}"`,
239
- );
240
- if (updatedContent !== oldContent) {
241
- await fs.writeFile(oldPath, updatedContent, "utf-8");
242
- supersedesStatus = `\nSupersedes: ✓ Marked ${args.supersedes} as superseded`;
243
- }
244
- } catch {
245
- supersedesStatus = `\nSupersedes: ⚠ Could not update ${args.supersedes}`;
246
- }
247
- }
248
-
249
- let beadUpdate = "";
247
+ // Store in SQLite (single source of truth)
248
+ const sqliteId = storeObservation(input);
250
249
 
251
250
  // Update bead notes if bead_id provided
251
+ let beadUpdate = "";
252
252
  if (args.bead_id) {
253
253
  try {
254
254
  const { execSync } = await import("node:child_process");
255
- const noteContent = `${icon} ${obsType}: ${args.title}`;
255
+ const noteContent = `${TYPE_ICONS[obsType]} ${obsType}: ${args.title}`;
256
256
  execSync(
257
257
  `bd edit ${args.bead_id} --note "${noteContent.replace(/"/g, '\\"')}"`,
258
258
  {
@@ -267,13 +267,25 @@ export default tool({
267
267
  }
268
268
  }
269
269
 
270
- // Build auto-detected files info
271
- let autoDetectedInfo = "";
272
- if (detectedFiles.length > 0) {
273
- autoDetectedInfo = `\nAuto-detected: ${detectedFiles.length} file reference(s)`;
270
+ // Build output
271
+ const icon = TYPE_ICONS[obsType];
272
+ const confIcon = CONFIDENCE_ICONS[confidence];
273
+
274
+ let output = `✓ Observation #${sqliteId} saved\n\n`;
275
+ output += `**Type**: ${icon} ${obsType}\n`;
276
+ output += `**Title**: ${args.title}\n`;
277
+ output += `**Confidence**: ${confIcon} ${confidence}\n`;
278
+
279
+ if (concepts.length > 0) {
280
+ output += `**Concepts**: ${concepts.join(", ")}\n`;
274
281
  }
282
+ if (facts.length > 0) {
283
+ output += `**Facts**: ${facts.length} extracted\n`;
284
+ }
285
+
286
+ output += beadUpdate;
275
287
 
276
- return `✓ Observation saved: ${filename}\n\nType: ${icon} ${obsType}\nTitle: ${args.title}\nConfidence: ${confidenceIcon} ${confidence}\nConcepts: ${concepts.join(", ") || "none"}\nFiles: ${files.join(", ") || "none"}${autoDetectedInfo}${supersedesStatus}${beadUpdate}\n\nPath: ${filePath}`;
288
+ return output;
277
289
  } catch (error) {
278
290
  if (error instanceof Error) {
279
291
  return `Error saving observation: ${error.message}`;
@@ -1,21 +1,21 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "allowSyntheticDefaultImports": true,
7
- "esModuleInterop": true,
8
- "allowJs": true,
9
- "strict": false,
10
- "noEmit": true,
11
- "declaration": true,
12
- "outDir": "./dist",
13
- "rootDir": "./",
14
- "skipLibCheck": true,
15
- "forceConsistentCasingInFileNames": true,
16
- "resolveJsonModule": true,
17
- "types": ["node"]
18
- },
19
- "include": ["plugin/**/*.ts", "tool/**/*.ts", "agent/**/*.ts", "*.ts"],
20
- "exclude": ["node_modules", "dist", "**/*.js", "**/*.test.ts"]
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "allowSyntheticDefaultImports": true,
7
+ "esModuleInterop": true,
8
+ "allowJs": true,
9
+ "strict": false,
10
+ "noEmit": true,
11
+ "declaration": true,
12
+ "outDir": "./dist",
13
+ "rootDir": "./",
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "resolveJsonModule": true,
17
+ "types": ["node", "bun-types"]
18
+ },
19
+ "include": ["plugin/**/*.ts", "tool/**/*.ts", "agent/**/*.ts", "*.ts"],
20
+ "exclude": ["node_modules", "dist", "**/*.js", "**/*.test.ts"]
21
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.15.21",
3
+ "version": "0.16.1",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
6
6
  "license": "MIT",
@@ -1,331 +0,0 @@
1
- ---
2
- description: WCAG accessibility audit
3
- argument-hint: "<image-or-component-path> [level: A|AA|AAA]"
4
- agent: vision
5
- model: proxypal/gemini-3-flash-preview
6
- subtask: true
7
- ---
8
-
9
- # Accessibility Check: $ARGUMENTS
10
-
11
- ## Phase 1: Load Context
12
-
13
- **Load skills:**
14
-
15
- ````typescript
16
- skill({ name: "beads" }); // Session protocol
17
- skill({ name: "accessibility-audit" });
18
-
19
- ```typescript
20
- skill({ name: "accessibility-audit" });
21
- ````
22
-
23
- **Check for bead context:**
24
-
25
- !`bd show $ARGUMENTS` # If bead ID provided
26
-
27
- Parse path and WCAG level from `$ARGUMENTS` (default: AA).
28
-
29
- ## Phase 2: Estimate Complexity
30
-
31
- | Signals | Estimate | Approach |
32
- | ------------------------------ | -------- | --------------- |
33
- | Single component, few elements | S (~10) | Quick audit |
34
- | Page with multiple components | M (~30) | Full audit |
35
- | Complex app, multiple pages | L (~100) | Comprehensive |
36
- | Design system audit | XL | Systematic scan |
37
-
38
- ## Phase 3: Determine Input Type
39
-
40
- - **Image/screenshot**: Visual accessibility analysis (Phase 4)
41
- - **Component path**: Code accessibility patterns (Phase 5)
42
- - **URL**: Run automated + visual analysis (Phase 4 + 5)
43
-
44
- ## Phase 4: Visual Analysis
45
-
46
- ### Color & Contrast
47
-
48
- | Check | WCAG Ref | Requirement |
49
- | ------------------------ | ----------- | ---------------------------- |
50
- | Text contrast | 1.4.3 (AA) | 4.5:1 normal, 3:1 large text |
51
- | UI component contrast | 1.4.11 (AA) | 3:1 against adjacent colors |
52
- | Focus indicator contrast | 1.4.11 (AA) | 3:1 contrast |
53
- | Color-only information | 1.4.1 (A) | Don't rely on color alone |
54
-
55
- ### Touch & Interaction
56
-
57
- | Check | WCAG Ref | Requirement |
58
- | ----------------- | ----------- | -------------------------- |
59
- | Touch target size | 2.5.5 (AAA) | ≥44x44px (≥24x24 for AA) |
60
- | Target spacing | 2.5.8 (AA) | Adequate spacing between |
61
- | Pointer gestures | 2.5.1 (A) | Single pointer alternative |
62
-
63
- ### Visual Structure
64
-
65
- | Check | WCAG Ref | Requirement |
66
- | ----------------- | ----------- | ----------------------------- |
67
- | Heading hierarchy | 1.3.1 (A) | Logical heading order |
68
- | Reading order | 1.3.2 (A) | Meaningful sequence |
69
- | Text spacing | 1.4.12 (AA) | Adjustable without loss |
70
- | Reflow | 1.4.10 (AA) | No horizontal scroll at 320px |
71
-
72
- ### Motion & Animation
73
-
74
- | Check | WCAG Ref | Requirement |
75
- | ----------------------- | ----------- | ------------------------------- |
76
- | Motion from interaction | 2.3.3 (AAA) | Can be disabled |
77
- | Reduced motion | 2.3.3 | Respects prefers-reduced-motion |
78
- | Auto-playing media | 1.4.2 (A) | Pause/stop/hide controls |
79
- | Flashing content | 2.3.1 (A) | No more than 3 flashes/second |
80
-
81
- ## Phase 5: Code Analysis
82
-
83
- ### Automated Testing
84
-
85
- Run axe-core or Lighthouse:
86
-
87
- ```bash
88
- # Using Lighthouse
89
- npx lighthouse <url> --only-categories=accessibility --output=json
90
-
91
- # Using axe-core in tests
92
- npm install -D @axe-core/playwright # or jest-axe
93
- ```
94
-
95
- ```typescript
96
- // Playwright + axe example
97
- import { injectAxe, checkA11y } from "@axe-core/playwright";
98
-
99
- await injectAxe(page);
100
- await checkA11y(page);
101
- ```
102
-
103
- ### Semantic HTML Checks
104
-
105
- ```typescript
106
- // Find images without alt text
107
- ast - grep({ pattern: "<img $$$>" }); // Check for alt attribute
108
-
109
- // Find click handlers on non-interactive elements
110
- ast - grep({ pattern: "<div onClick={$$$}>" });
111
- ast - grep({ pattern: "<span onClick={$$$}>" });
112
-
113
- // Find form inputs without labels
114
- ast - grep({ pattern: "<input $$$>" }); // Check for id + matching label
115
- ```
116
-
117
- ### ARIA Pattern Checks
118
-
119
- !`grep -r "role=" --include="*.tsx" --include="*.jsx" | head -20`
120
-
121
- | Pattern | Required ARIA |
122
- | --------------- | ------------------------------------------ |
123
- | Modal dialog | role="dialog", aria-modal, aria-labelledby |
124
- | Dropdown menu | role="menu", aria-expanded, aria-haspopup |
125
- | Tab panel | role="tablist/tab/tabpanel", aria-selected |
126
- | Accordion | aria-expanded, aria-controls |
127
- | Alert | role="alert", aria-live="assertive" |
128
- | Toast | role="status", aria-live="polite" |
129
- | Loading spinner | aria-busy, aria-live |
130
-
131
- ### Focus Management
132
-
133
- | Check | Requirement |
134
- | ------------------- | ----------------------------------- |
135
- | Focus visible | All interactive elements show focus |
136
- | Focus order | Logical tab sequence |
137
- | Focus trap (modals) | Focus contained within modal |
138
- | Focus restoration | Focus returns after modal closes |
139
- | Skip links | Skip to main content available |
140
-
141
- !`grep -r ":focus" --include="*.css" | head -10`
142
- !`grep -r "focus:" --include="*.tsx" | head -10` // Tailwind
143
-
144
- ## Phase 6: Keyboard Navigation Testing
145
-
146
- Test manually or with Playwright:
147
-
148
- ```typescript
149
- skill({ name: "playwright" });
150
- skill_mcp({
151
- skill_name: "playwright",
152
- tool_name: "browser_press_key",
153
- arguments: '{"key": "Tab"}',
154
- });
155
- ```
156
-
157
- | Action | Expected Behavior |
158
- | ---------- | ---------------------------------------- |
159
- | Tab | Moves to next interactive element |
160
- | Shift+Tab | Moves to previous element |
161
- | Enter | Activates buttons, links |
162
- | Space | Toggles checkboxes, activates buttons |
163
- | Arrow keys | Navigate within components (tabs, menus) |
164
- | Escape | Closes modals, dropdowns |
165
-
166
- ```
167
- Keyboard Navigation:
168
- ━━━━━━━━━━━━━━━━━━━━
169
-
170
- - Tab order: [logical/broken at X]
171
- - Focus visible: [all/missing on X]
172
- - Enter/Space: [working/broken on X]
173
- - Escape: [working/not implemented]
174
- - Skip link: [present/missing]
175
- ```
176
-
177
- ## Phase 7: Screen Reader Guidance
178
-
179
- For manual testing, suggest:
180
-
181
- | Platform | Screen Reader | Command to Start |
182
- | -------- | ------------- | ------------------------ |
183
- | macOS | VoiceOver | Cmd + F5 |
184
- | Windows | NVDA | Ctrl + Alt + N |
185
- | Windows | Narrator | Win + Ctrl + Enter |
186
- | iOS | VoiceOver | Settings > Accessibility |
187
- | Android | TalkBack | Settings > Accessibility |
188
-
189
- **Key things to verify:**
190
-
191
- - [ ] All content is announced
192
- - [ ] Images have meaningful alt text
193
- - [ ] Form fields announce labels
194
- - [ ] Error messages are announced
195
- - [ ] Dynamic content updates are announced (aria-live)
196
-
197
- ## Phase 8: Generate Report
198
-
199
- ````markdown
200
- ## Accessibility Audit: [Component/Page]
201
-
202
- **WCAG Level:** [A/AA/AAA]
203
- **Automated Score:** [Lighthouse score if available]
204
-
205
- ### Summary
206
-
207
- | Category | Critical | Major | Minor | Passed |
208
- | -------------- | -------- | ----- | ----- | ------ |
209
- | Perceivable | [N] | [N] | [N] | [N] |
210
- | Operable | [N] | [N] | [N] | [N] |
211
- | Understandable | [N] | [N] | [N] | [N] |
212
- | Robust | [N] | [N] | [N] | [N] |
213
-
214
- ### Critical Issues (Must Fix)
215
-
216
- #### [Issue Title]
217
-
218
- - **WCAG:** [criterion number and name]
219
- - **Location:** [file:line or element description]
220
- - **Problem:** [description]
221
- - **Fix:**
222
-
223
- ```[language]
224
- [code fix]
225
- ```
226
- ````
227
-
228
- ### Major Issues
229
-
230
- [Same format]
231
-
232
- ### Minor Issues
233
-
234
- [Same format]
235
-
236
- ### Passed Checks
237
-
238
- - Color contrast: [ratio] meets [level]
239
- - Touch targets: [size] meets requirement
240
- - Heading structure: Logical hierarchy
241
- - Keyboard navigation: All elements reachable
242
- - Focus indicators: Visible on all elements
243
-
244
- ````
245
-
246
- ## Phase 9: Create Observation
247
-
248
- If patterns discovered:
249
-
250
- ```typescript
251
- observation({
252
- type: "pattern",
253
- title: "A11y pattern: [name]",
254
- content: `
255
- ## Pattern
256
- [Description of accessibility pattern]
257
-
258
- ## Implementation
259
- \`\`\`tsx
260
- [Accessible code example]
261
- \`\`\`
262
-
263
- ## Common Mistakes
264
- - [What to avoid]
265
- `,
266
- concepts: "accessibility, wcag, [specific area]",
267
- bead_id: "<bead-id>",
268
- });
269
- ````
270
-
271
- ## Phase 10: Verify Fixes
272
-
273
- After fixes applied, re-run checks:
274
-
275
- ```bash
276
- npx lighthouse <url> --only-categories=accessibility
277
- ```
278
-
279
- ```
280
- Verification:
281
- ━━━━━━━━━━━━━
282
-
283
- Before: [N] issues
284
- After: [N] issues
285
- Resolved: [N]
286
-
287
- Remaining:
288
- - [Any outstanding issues]
289
- ```
290
-
291
- ## Phase 11: Sync
292
-
293
- ```bash
294
- bd sync
295
- ```
296
-
297
- ## Output
298
-
299
- ```
300
- Accessibility Audit Complete: $ARGUMENTS
301
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
302
-
303
- WCAG Level: [AA]
304
- Estimate: [S/M/L]
305
-
306
- Results:
307
- - Critical: [N]
308
- - Major: [N]
309
- - Minor: [N]
310
- - Passed: [N]
311
-
312
- Automated Score: [N]/100 (Lighthouse)
313
-
314
- Key Fixes Needed:
315
- 1. [Most critical issue]
316
- 2. [Second issue]
317
- 3. [Third issue]
318
-
319
- Report: .beads/artifacts/<bead-id>/a11y-audit.md (if bead)
320
- ```
321
-
322
- **Next steps:**
323
-
324
- ```
325
- Fix issues:
326
- /fix-ui <bead-id> # Fix visual issues
327
- /fix <bead-id> # Fix code issues
328
-
329
- After fixing:
330
- /accessibility-check <path> # Re-run audit
331
- ```