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.
- package/dist/index.js +5 -7
- package/dist/template/.opencode/AGENTS.md +85 -23
- package/dist/template/.opencode/agent/build.md +88 -7
- package/dist/template/.opencode/agent/explore.md +1 -1
- package/dist/template/.opencode/agent/general.md +54 -4
- package/dist/template/.opencode/agent/looker.md +1 -1
- package/dist/template/.opencode/agent/painter.md +1 -1
- package/dist/template/.opencode/agent/plan.md +52 -0
- package/dist/template/.opencode/agent/review.md +1 -1
- package/dist/template/.opencode/agent/scout.md +3 -3
- package/dist/template/.opencode/agent/vision.md +1 -1
- package/dist/template/.opencode/command/create.md +231 -91
- package/dist/template/.opencode/command/design.md +40 -7
- package/dist/template/.opencode/command/handoff.md +22 -0
- package/dist/template/.opencode/command/init.md +49 -78
- package/dist/template/.opencode/command/plan.md +36 -16
- 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 +8 -18
- package/dist/template/.opencode/command/review-codebase.md +30 -0
- package/dist/template/.opencode/command/ship.md +199 -0
- package/dist/template/.opencode/command/start.md +316 -28
- package/dist/template/.opencode/command/status.md +24 -1
- package/dist/template/.opencode/command/ui-review.md +36 -7
- package/dist/template/.opencode/command/verify.md +307 -0
- package/dist/template/.opencode/memory/_templates/prd.md +29 -0
- package/dist/template/.opencode/memory/_templates/proposal.md +38 -0
- package/dist/template/.opencode/memory/_templates/spec.md +66 -0
- package/dist/template/.opencode/memory/_templates/tasks.md +198 -0
- package/dist/template/.opencode/memory/_templates/tech-stack.md +50 -0
- package/dist/template/.opencode/memory/project/tech-stack.md +53 -0
- package/dist/template/.opencode/memory/research/ccpm-analysis.md +334 -0
- package/dist/template/.opencode/memory/research/openspec-analysis.md +226 -0
- 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 +18 -4
- 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/skill/tool-priority/SKILL.md +2 -2
- 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/command/accessibility-check.md +0 -331
- package/dist/template/.opencode/command/agent-browser.md +0 -21
- package/dist/template/.opencode/command/analyze-mockup.md +0 -423
- package/dist/template/.opencode/command/analyze-project.md +0 -295
- package/dist/template/.opencode/command/brainstorm.md +0 -373
- package/dist/template/.opencode/command/cloudflare.md +0 -70
- package/dist/template/.opencode/command/commit.md +0 -245
- package/dist/template/.opencode/command/complete-next-task.md +0 -77
- package/dist/template/.opencode/command/design-audit.md +0 -480
- package/dist/template/.opencode/command/edit-image.md +0 -242
- package/dist/template/.opencode/command/finish.md +0 -255
- package/dist/template/.opencode/command/fix-ci.md +0 -109
- package/dist/template/.opencode/command/fix-types.md +0 -104
- package/dist/template/.opencode/command/fix-ui.md +0 -117
- package/dist/template/.opencode/command/fix.md +0 -168
- package/dist/template/.opencode/command/frontend-design.md +0 -21
- package/dist/template/.opencode/command/generate-diagram.md +0 -349
- package/dist/template/.opencode/command/generate-icon.md +0 -283
- package/dist/template/.opencode/command/generate-image.md +0 -246
- package/dist/template/.opencode/command/generate-pattern.md +0 -247
- package/dist/template/.opencode/command/generate-storyboard.md +0 -250
- package/dist/template/.opencode/command/implement.md +0 -609
- package/dist/template/.opencode/command/import-plan.md +0 -406
- package/dist/template/.opencode/command/index-knowledge.md +0 -25
- package/dist/template/.opencode/command/integration-test.md +0 -424
- package/dist/template/.opencode/command/issue.md +0 -102
- package/dist/template/.opencode/command/new-feature.md +0 -651
- package/dist/template/.opencode/command/opensrc.md +0 -58
- package/dist/template/.opencode/command/quick-build.md +0 -238
- package/dist/template/.opencode/command/ralph.md +0 -41
- package/dist/template/.opencode/command/research-and-implement.md +0 -148
- package/dist/template/.opencode/command/research-ui.md +0 -466
- package/dist/template/.opencode/command/restore-image.md +0 -424
- package/dist/template/.opencode/command/revert-feature.md +0 -386
- package/dist/template/.opencode/command/skill-create.md +0 -517
- package/dist/template/.opencode/command/skill-optimize.md +0 -556
- package/dist/template/.opencode/command/summarize.md +0 -412
- package/dist/template/.opencode/command/triage.md +0 -398
- package/dist/template/.opencode/memory/_templates/README.md +0 -35
- package/dist/template/.opencode/memory/_templates/observation.md +0 -39
- package/dist/template/.opencode/memory/_templates/project/architecture.md +0 -60
- package/dist/template/.opencode/memory/_templates/project/commands.md +0 -72
- package/dist/template/.opencode/memory/_templates/project/conventions.md +0 -68
- package/dist/template/.opencode/memory/_templates/project/gotchas.md +0 -41
- 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/project/architecture.md +0 -60
- 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/skill/notebooklm/SKILL.md +0 -272
- package/dist/template/.opencode/skill/notebooklm/references/setup.md +0 -353
- package/dist/template/.opencode/tool/notebooklm.ts +0 -488
- package/dist/template/.opencode/tool/oracle.ts +0 -240
- /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
|
@@ -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
|
-
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
|
82
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
-
//
|
|
167
|
-
const
|
|
168
|
-
const
|
|
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
|
|
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
|
|
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
|
|
184
|
-
const detectedRefs = extractFileReferences(
|
|
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
|
-
|
|
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
|
-
//
|
|
196
|
-
let
|
|
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
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
//
|
|
224
|
-
|
|
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 = `${
|
|
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
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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,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
|
-
```
|