opensddrag 0.1.0

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.
@@ -0,0 +1,837 @@
1
+ export function getCommands(slug, serverUrl) {
2
+ /**
3
+ * Header for SDD artifact-management commands (propose, spec, design, tasks,
4
+ * archive, explore, continue, status, search, sync, flow).
5
+ * All data writes go to the MCP server; local file creation is forbidden.
6
+ */
7
+ const artifactHeader = (name) => `> **IMPORTANT — ${name}**
8
+ > This command requires the **\`opensddrag\`** MCP server (${serverUrl}), configured in \`.mcp.json\`.
9
+ > MCP tools provided by this server: \`create_artifact\`, \`read_artifact\`, \`list_artifacts\`, \`update_artifact\`, \`validate_artifact\`, \`link_artifacts\`, \`get_relationships\`, \`search_semantic\`, \`recall_episodes\`, \`get_working_context\`, \`update_working_context\`, \`record_trace\`
10
+ > **If these tools are NOT in your active tool list**: STOP immediately. Do NOT investigate or try alternatives. Tell the user: "The opensddrag MCP server is not connected. Please start it (\`docker compose up -d\`) and reload the project."
11
+ > All artifact reads/writes go through these MCP tools. DO NOT create local files. DO NOT write markdown to disk.
12
+ > **project_slug for every call: \`${slug}\`**
13
+
14
+ ---
15
+
16
+ `;
17
+
18
+ /**
19
+ * Header for implementation-phase commands (apply, verify).
20
+ * SDD planning artifacts are read from and traced via the MCP server; code
21
+ * implementation writes local files using standard tools (Edit, Write, Bash).
22
+ */
23
+ const implementHeader = (name) => `> **IMPORTANT — ${name}**
24
+ > This command requires the **\`opensddrag\`** MCP server (${serverUrl}), configured in \`.mcp.json\`.
25
+ > MCP tools provided by this server: \`read_artifact\`, \`list_artifacts\`, \`update_artifact\`, \`get_relationships\`, \`search_semantic\`, \`recall_episodes\`, \`get_working_context\`, \`update_working_context\`, \`record_trace\`
26
+ > **If these tools are NOT in your active tool list**: STOP immediately. Do NOT investigate or try alternatives. Tell the user: "The opensddrag MCP server is not connected. Please start it (\`docker compose up -d\`) and reload the project."
27
+ > SDD planning artifacts are read/traced via these MCP tools. Code implementation writes local files using Edit, Write, Bash — this is expected and required.
28
+ > **project_slug for every MCP call: \`${slug}\`**
29
+
30
+ ---
31
+
32
+ `;
33
+
34
+ return [
35
+ // ── <opsr:propose ───────────────────────────────────────────────────────────
36
+ {
37
+ folder: "opsr",
38
+ folder: "opsr",
39
+ name: "propose",
40
+ content: `${artifactHeader("/opsr:propose")}## Purpose
41
+ Create a named change with a proposal artifact. This is the entry point for every new feature or change.
42
+ The proposal defines WHY, WHAT changes, WHICH capabilities are affected, and the IMPACT.
43
+ After this command, /opsr:spec and /opsr:design become available.
44
+
45
+ ## Input
46
+ $ARGUMENTS = change name (kebab-case) or plain description. If plain description, derive a kebab-case name.
47
+
48
+ ## Step 1 — Derive change name
49
+ If $ARGUMENTS is a plain description (contains spaces), convert to kebab-case.
50
+ Example: "add user authentication" → "add-user-authentication"
51
+
52
+ ## Step 2 — Search for existing work (avoid duplication)
53
+ Call MCP tool:
54
+ \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
55
+ If relevant artifacts are found, show them and ask the user to confirm this is new work.
56
+
57
+ ## Step 3 — Write the proposal content
58
+ Compose the following structure (do NOT skip any section):
59
+
60
+ \`\`\`markdown
61
+ # <change-name>
62
+
63
+ ## Why
64
+ [1-2 sentences on the problem or opportunity being addressed]
65
+
66
+ ## What Changes
67
+ - [Specific change 1]
68
+ - [Specific change 2]
69
+ - **BREAKING** [Breaking change if any]
70
+
71
+ ## Capabilities
72
+ ### New Capabilities
73
+ - [capability-name] — brief description
74
+
75
+ ### Modified Capabilities
76
+ - [existing-capability] — what changes
77
+
78
+ ## Impact
79
+ [Affected code, APIs, dependencies, systems]
80
+ \`\`\`
81
+
82
+ ## Step 4 — Save proposal to database
83
+ Call MCP tool:
84
+ \`create_artifact(name="<change-name>-proposal", type="proposal", content="<full proposal markdown>", metadata={"change_name": "<change-name>", "status_phase": "planning"}, project_slug="${slug}")\`
85
+ Note the returned artifact ID.
86
+
87
+ ## Step 5 — Create spec drafts for each capability
88
+ Parse the "## Capabilities" section. For each capability listed in "New Capabilities" or "Modified Capabilities":
89
+ 1. Check if a spec for this capability already exists:
90
+ \`read_artifact(name="<change-name>-<capability-name>-spec", project_slug="${slug}")\`
91
+ If it exists and is not empty, skip creating a draft.
92
+
93
+ 2. If no spec exists, create a draft spec:
94
+
95
+ **IMPORTANT: copy the template content VERBATIM into the \`content\` parameter — do NOT replace [TODO] markers with generated requirements, scenarios, or domain-specific rules (e.g., JWT rules, database schemas, auth flows). This step is scaffolding only; actual content is added by /opsr:spec.**
96
+
97
+ \`create_artifact(name="<change-name>-<capability-name>-spec", type="spec", status="draft", content="# <capability-name> Specification
98
+
99
+ [TODO: Define purpose, requirements, and scenarios for this capability]
100
+
101
+ ## Purpose
102
+ [TODO: Describe what this capability enables]
103
+
104
+ ## Requirements
105
+ [TODO: List requirements with REQ-NNN format]
106
+
107
+ ### Requirement: <REQ-001>
108
+ [TODO: Describe requirement using SHALL/MUST language]
109
+
110
+ #### Scenario: <Name>
111
+ - **WHEN** [condition]
112
+ - **THEN** [expected outcome]", metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true}, project_slug="${slug}")\`
113
+
114
+ ## Step 6 — Create design skeleton
115
+ Create a draft design document:
116
+
117
+ **IMPORTANT: copy the template content VERBATIM — do NOT replace [TODO] markers with generated technical decisions, architecture choices, or risk assessments. Design content is added by /opsr:design.**
118
+
119
+ \`create_artifact(name="<change-name>-design", type="design", status="draft", content="# Design: <change-name>
120
+
121
+ [TODO: Document technical decisions, architecture, trade-offs]
122
+
123
+ ## Context
124
+ [TODO: Background and constraints]
125
+
126
+ ## Goals / Non-Goals
127
+ **Goals:**
128
+ - [Goal 1]
129
+
130
+ **Non-Goals:**
131
+ - [Non-goal 1]
132
+
133
+ ## Decisions
134
+ ### Decision: <Title>
135
+ **Chosen:** [What was chosen]
136
+ **Alternatives:**
137
+ - [Alternative 1] — rejected because [reason]
138
+
139
+ ## Architecture
140
+ [TODO: Components and data flow]
141
+
142
+ ## Risks / Trade-offs
143
+ | Risk | Mitigation |
144
+ |------|------------|
145
+ | [Risk] | [Mitigation] |
146
+
147
+ ## Open Questions
148
+ - [ ] [Question]
149
+ ", metadata={"change_name": "<change-name>"}, project_slug="${slug}")\`
150
+
151
+ ## Step 7 — Record the action
152
+ Call MCP tool:
153
+ \`record_trace(action="propose", result_summary="Created proposal: <change-name>-proposal", project_slug="${slug}")\`
154
+
155
+ ## Step 8 — Show what is now available
156
+ Tell the user:
157
+ - "Proposal saved with full scaffolding. The following commands are now available:"
158
+ - \`/opsr:spec <change-name>\` — formalize requirements (draft specs already created for each capability)
159
+ - \`/opsr:design <change-name>\` — document technical approach (draft design already created)
160
+ - Or run \`/opsr:flow <change-name>\` to continue the full flow automatically.
161
+ `,
162
+ },
163
+
164
+ // ── /opsr:spec ─────────────────────────────────────────────────────────────
165
+ {
166
+ folder: "opsr",
167
+ name: "spec",
168
+ content: `${artifactHeader("/opsr:spec")}## Purpose
169
+ Create one or more spec artifacts for the capabilities listed in a proposal.
170
+ Each capability in "New Capabilities" or "Modified Capabilities" gets its own spec artifact.
171
+ Specs use SHALL/MUST language and must have Scenarios with WHEN/THAN format.
172
+
173
+ ## Input
174
+ $ARGUMENTS = change name. If not provided, list proposals and ask.
175
+
176
+ ## Step 1 — Read the proposal from the database
177
+ Call MCP tool:
178
+ \`list_artifacts(type="proposal", project_slug="${slug}")\`
179
+ Then read the selected proposal:
180
+ \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
181
+
182
+ ## Step 2 — Identify capabilities from the proposal
183
+ Parse the "## Capabilities" section. Each capability in "New Capabilities" and "Modified Capabilities" needs a spec.
184
+
185
+ **New capability** → create a full spec (Purpose + Requirements + Scenarios)
186
+ **Modified capability** → check if a main spec exists first:
187
+ \`search_semantic(query="<capability-name> spec", project_slug="${slug}", limit=3)\`
188
+ If main spec exists → create a DELTA spec with ADDED/MODIFIED/REMOVED/RENAMED sections.
189
+ If no main spec → create BOTH:
190
+ 1. The main spec with metadata={"capability": "<capability-name>", "is_delta": false}
191
+ 2. The delta spec with metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true}
192
+
193
+ ## Step 3 — Write spec content for EACH capability
194
+
195
+ ### Full spec structure (new capabilities):
196
+ \`\`\`markdown
197
+ # <capability-name> Specification
198
+
199
+ ## Purpose
200
+ [High-level description of this capability]
201
+
202
+ ## Requirements
203
+
204
+ ### Requirement: <REQ-001 Name>
205
+ [Description using SHALL/MUST language]
206
+
207
+ #### Scenario: <Happy path name>
208
+ - **WHEN** [condition]
209
+ - **THEN** [expected outcome]
210
+
211
+ #### Scenario: <Edge case name>
212
+ - **WHEN** [edge condition]
213
+ - **THEN** [expected outcome]
214
+
215
+ ### Requirement: <REQ-002 Name>
216
+ [Description]
217
+
218
+ #### Scenario: <Name>
219
+ - **WHEN** [condition]
220
+ - **THEN** [outcome]
221
+ \`\`\`
222
+
223
+ ### Delta spec structure (modified capabilities):
224
+ \`\`\`markdown
225
+ # <capability-name> Specification — Delta
226
+
227
+ ## ADDED Requirements
228
+ ### Requirement: <New requirement name>
229
+ [Full requirement with scenarios]
230
+
231
+ ## MODIFIED Requirements
232
+ ### Requirement: <Existing requirement name>
233
+ [Updated requirement — include FULL updated text with all scenarios]
234
+
235
+ ## REMOVED Requirements
236
+ ### Requirement: <Removed requirement name>
237
+ **Reason:** [Why this is being removed]
238
+ **Migration:** [How consumers should migrate]
239
+
240
+ ## RENAMED Requirements
241
+ - FROM: \`### Requirement: Old Name\`
242
+ - TO: \`### Requirement: New Name\`
243
+ \`\`\`
244
+
245
+ ## Step 4 — Save each spec to the database
246
+ For each capability spec:
247
+ \`create_artifact(name="<change-name>-<capability-name>-spec", type="spec", content="<full spec markdown>", metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true/false}, project_slug="${slug}")\`
248
+
249
+ ## Step 5 — Link each spec to the proposal
250
+ \`link_artifacts(source_name="<spec-name>", target_name="<change-name>-proposal", relationship_type="implements", project_slug="${slug}")\`
251
+
252
+ ## Step 6 — Validate each spec
253
+ \`validate_artifact(name="<spec-name>", project_slug="${slug}")\`
254
+ Fix any validation errors before continuing.
255
+
256
+ ## Step 7 — Record the action
257
+ \`record_trace(action="spec", result_summary="Created specs for: <capability-list>", project_slug="${slug}")\`
258
+
259
+ ## Step 8 — Show what is now available
260
+ - "Specs saved. You can now run:"
261
+ - \`/opsr:design <change-name>\` — document technical decisions
262
+ `,
263
+ },
264
+
265
+ // ── /opsr:design ───────────────────────────────────────────────────────────
266
+ {
267
+ folder: "opsr",
268
+ name: "design",
269
+ content: `${artifactHeader("/opsr:design")}## Purpose
270
+ Create a design document that captures technical decisions, architecture, trade-offs, and open questions.
271
+ The design must be based on the proposal and spec artifacts already in the database.
272
+
273
+ ## Input
274
+ $ARGUMENTS = change name.
275
+
276
+ ## Step 1 — Read proposal and all specs from the database
277
+ \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
278
+ \`list_artifacts(type="spec", project_slug="${slug}")\`
279
+ Read each spec linked to this change:
280
+ \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
281
+
282
+ ## Step 2 — Search for related prior designs
283
+ \`search_semantic(query="<change topic> design decisions", project_slug="${slug}", limit=3)\`
284
+ Use findings as context — don't duplicate prior work.
285
+
286
+ ## Step 3 — Write the design content
287
+ \`\`\`markdown
288
+ # Design: <change-name>
289
+
290
+ ## Context
291
+ [Background, current state, constraints that shaped this design]
292
+
293
+ ## Goals / Non-Goals
294
+ **Goals:**
295
+ - [What this design achieves]
296
+
297
+ **Non-Goals:**
298
+ - [What this design deliberately does NOT address]
299
+
300
+ ## Decisions
301
+
302
+ ### Decision: <Title>
303
+ **Chosen:** [What was chosen and why]
304
+ **Alternatives considered:**
305
+ - [Alternative 1] — rejected because [reason]
306
+ - [Alternative 2] — rejected because [reason]
307
+
308
+ ### Decision: <Title>
309
+ ...
310
+
311
+ ## Architecture
312
+ [Components, data flow, integration points — use ASCII diagrams if helpful]
313
+
314
+ ## Risks / Trade-offs
315
+ | Risk | Mitigation |
316
+ |------|------------|
317
+ | [Risk] | [Mitigation] |
318
+
319
+ ## Migration Plan
320
+ [Deployment steps, backward compatibility, rollback plan]
321
+
322
+ ## Open Questions
323
+ - [ ] [Question that still needs resolution]
324
+ \`\`\`
325
+
326
+ ## Step 4 — Save design to database
327
+ \`create_artifact(name="<change-name>-design", type="design", content="<full design markdown>", metadata={"change_name": "<change-name>"}, project_slug="${slug}")\`
328
+
329
+ ## Step 5 — Link design to proposal
330
+ \`link_artifacts(source_name="<change-name>-design", target_name="<change-name>-proposal", relationship_type="depends_on", project_slug="${slug}")\`
331
+
332
+ ## Step 6 — Record and show next steps
333
+ \`record_trace(action="design", result_summary="Created design: <change-name>-design", project_slug="${slug}")\`
334
+ Tell the user: "Design saved. Run \`<opsr:tasks <change-name>\` to decompose into tasks."
335
+ `,
336
+ },
337
+
338
+ // ── <opsr:tasks ────────────────────────────────────────────────────────────
339
+ {
340
+ folder: "opsr",
341
+ name: "tasks",
342
+ content: `${artifactHeader("/opsr:tasks")}## Purpose
343
+ Decompose the specs and design into atomic, verifiable task artifacts.
344
+ Each task must map to one or more spec requirements (REQ-NNN) and be completable in under 4 hours.
345
+ Tasks depend on BOTH specs AND design being in the database.
346
+
347
+ ## Input
348
+ $ARGUMENTS = change name.
349
+
350
+ ## Step 1 — Read all planning artifacts from the database
351
+ \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
352
+ \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
353
+ Get all specs for this change:
354
+ \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
355
+ Read each linked spec artifact.
356
+
357
+ ## Step 2 — Plan task groups from the design and specs
358
+ Group tasks by logical phase. Each task must have:
359
+ - A clear **Goal** (what it accomplishes)
360
+ - **Acceptance criteria** referencing spec REQ-NNN items (not vague)
361
+ - **Dependencies** on other tasks (if any)
362
+ - Estimated effort: < 4 hours
363
+
364
+ ## Step 3 — Create each task artifact in the database
365
+ For each task (name as \`<change-name>-task-<group>-<N>\`):
366
+ \`create_artifact(name="<change-name>-task-<group>-<N>", type="task", content="## Goal\\n<what this task accomplishes>\\n\\n## Acceptance Criteria\\n- [ ] REQ-NNN: <criterion>\\n- [ ] <criterion>\\n\\n## Dependencies\\n- <other task name or 'none'>", metadata={"change_name": "<change-name>", "group": "<group-name>", "order": <N>}, project_slug="${slug}")\`
367
+
368
+ ## Step 4 — Link each task to its spec(s)
369
+ \`link_artifacts(source_name="<task-name>", target_name="<spec-name>", relationship_type="implements", project_slug="${slug}")\`
370
+
371
+ ## Step 5 — Update working context with the task list
372
+ \`update_working_context(context={"change_name": "<change-name>", "tasks": ["<task-1>", "<task-2>", "..."], "current_task": null}, project_slug="${slug}")\`
373
+
374
+ ## Step 6 — Record and show next steps
375
+ \`record_trace(action="tasks", result_summary="Created <N> tasks for <change-name>", project_slug="${slug}")\`
376
+ Show the full task list with names and goals.
377
+ Tell the user: "Tasks saved. Run \`<opsr:apply <change-name>\` to start implementing."
378
+ `,
379
+ },
380
+
381
+ // ── <opsr:apply ────────────────────────────────────────────────────────────
382
+ {
383
+ folder: "opsr",
384
+ name: "apply",
385
+ content: `${implementHeader("/opsr:apply")}## Purpose
386
+ Implement tasks one by one, validating each against the spec acceptance criteria before marking done.
387
+ Read ALL planning artifacts (proposal, specs, design) as context before implementing any task.
388
+
389
+ ## Input
390
+ $ARGUMENTS = change name, or specific task name.
391
+
392
+ ## Step 1 — Load full planning context from the database
393
+ \`get_working_context(project_slug="${slug}")\`
394
+ \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
395
+ \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
396
+ Get and read all specs linked to this change.
397
+
398
+ ## Step 2 — List pending tasks in order
399
+ \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
400
+ AND
401
+ \`list_artifacts(type="task", status="active", project_slug="${slug}")\`
402
+ Combine both results. Prioritize tasks with status="active" (resuming interrupted session), then status="draft" in dependency order. Filter tasks for this change using metadata.change_name.
403
+
404
+ ## Step 3 — Select next task
405
+ If $ARGUMENTS specifies a task name, use it.
406
+ Otherwise:
407
+ 1. First, check for tasks with status="active" (resuming interrupted session)
408
+ 2. If no active tasks, pick the first draft task whose dependencies are all archived (done)
409
+
410
+ Read the task:
411
+ \`read_artifact(name="<task-name>", project_slug="${slug}")\`
412
+
413
+ ## Step 4 — Mark task as active in database
414
+ \`update_artifact(name="<task-name>", status="active", project_slug="${slug}")\`
415
+ Update working context:
416
+ \`update_working_context(context={"current_task": "<task-name>"}, project_slug="${slug}")\`
417
+
418
+ ## Step 5 — Implement the task
419
+ Implement the code changes required by the task.
420
+ The implementation MUST satisfy all acceptance criteria from the task's "## Acceptance Criteria" section.
421
+ Pause and ask the user if any requirement is unclear — do not guess.
422
+
423
+ ## Step 6 — Validate against spec requirements
424
+ For each acceptance criterion (REQ-NNN) in the task:
425
+ - Confirm the implementation satisfies the requirement
426
+ - Verify no spec scenarios are broken
427
+
428
+ ## Step 7 — Mark task as done in database
429
+ \`update_artifact(name="<task-name>", status="archived", project_slug="${slug}")\`
430
+
431
+ ## Step 8 — Record and check remaining tasks
432
+ \`record_trace(action="apply_task", result_summary="Completed task: <task-name>", artifact_id="<artifact-id>", project_slug="${slug}")\`
433
+ \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
434
+ - If tasks remain: "Task complete. Run \`<opsr:apply <change-name>\` for the next task."
435
+ - If all done: "All tasks complete. Run \`<opsr:verify <change-name>\` to validate, then \`<opsr:archive <change-name>\`."
436
+ `,
437
+ },
438
+
439
+ // ── <opsr:verify ────────────────────────────────────────────────────────────
440
+ {
441
+ folder: "opsr",
442
+ name: "verify",
443
+ content: `${implementHeader("/opsr:verify")}## Purpose
444
+ Validate the implementation against the spec requirements and design decisions.
445
+ Produces a structured report with CRITICAL, WARNING, and SUGGESTION severity levels.
446
+ Does NOT modify any artifacts — read-only operation.
447
+
448
+ ## Input
449
+ $ARGUMENTS = change name.
450
+
451
+ ## Step 1 — Load all artifacts from the database
452
+ \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
453
+ \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
454
+ Get all specs and tasks for this change:
455
+ \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
456
+ Read each linked spec and task artifact.
457
+
458
+ ## Step 2 — Verify COMPLETENESS
459
+ Check task completion:
460
+ \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
461
+ - If pending tasks exist → **CRITICAL: Tasks not complete**
462
+
463
+ Extract all requirements (REQ-NNN) from specs.
464
+ For each requirement, search the codebase for implementation evidence.
465
+ - If requirement has no implementation evidence → **CRITICAL: Requirement not implemented**
466
+
467
+ ## Step 3 — Verify CORRECTNESS
468
+ For each spec scenario (WHEN/THAN blocks):
469
+ - Search the codebase for test coverage or implementation of the scenario condition
470
+ - If scenario has no coverage → **WARNING: Scenario not covered**
471
+
472
+ ## Step 4 — Verify COHERENCE
473
+ Extract decisions from the "## Decisions" section of the design.
474
+ For each decision:
475
+ - Check if the implementation follows the chosen approach
476
+ - If implementation deviates from a decision → **SUGGESTION: Possible deviation from design**
477
+
478
+ ## Step 5 — Generate report
479
+ Output a structured report:
480
+
481
+ \`\`\`
482
+ ## Verification Report: <change-name>
483
+
484
+ ### Summary
485
+ | Dimension | Status |
486
+ |--------------|--------|
487
+ | Completeness | ✓/✗ |
488
+ | Correctness | ✓/✗ |
489
+ | Coherence | ✓/✗ |
490
+
491
+ ### CRITICAL Issues
492
+ - [Issue description]
493
+
494
+ ### WARNING Issues
495
+ - [Issue description]
496
+
497
+ ### SUGGESTIONS
498
+ - [Issue description]
499
+
500
+ ### Assessment
501
+ [READY TO ARCHIVE | ISSUES MUST BE FIXED BEFORE ARCHIVING]
502
+ \`\`\`
503
+
504
+ ## Step 6 — Record the verification
505
+ \`record_trace(action="verify", result_summary="Verification: <PASS/FAIL> — <N> critical, <N> warnings", project_slug="${slug}")\`
506
+ `,
507
+ },
508
+
509
+ // ── <opsr:sync ──────────────────────────────────────────────────────────────
510
+ {
511
+ folder: "opsr",
512
+ name: "sync",
513
+ content: `${artifactHeader("/opsr:sync")}## Purpose
514
+ Merge delta specs (ADDED/MODIFIED/REMOVED/RENAMED sections) into the main specs stored in the database.
515
+ Delta specs are created by /opsr:spec for MODIFIED capabilities.
516
+ After sync, the main spec reflects all changes. This is called automatically during /archive.
517
+
518
+ ## Input
519
+ $ARGUMENTS = change name.
520
+
521
+ ## Step 1 — Find delta specs for this change
522
+ \`list_artifacts(type="spec", project_slug="${slug}")\`
523
+ Filter specs where metadata.change_name = "<change-name>" AND metadata.is_delta = true.
524
+
525
+ ## Step 2 — For each delta spec, find the main spec
526
+ Search for the main (non-delta) spec for the same capability:
527
+ \`search_semantic(query="<capability-name> spec", project_slug="${slug}", limit=5)\`
528
+ Find the spec where metadata.is_delta = false (or not set) for the same capability.
529
+
530
+ ## Step 3 — Apply delta operations to the main spec
531
+ Read both delta and main spec:
532
+ \`read_artifact(name="<delta-spec-name>", project_slug="${slug}")\`
533
+ \`read_artifact(name="<main-spec-name>", project_slug="${slug}")\`
534
+
535
+ Apply each section from the delta:
536
+
537
+ **## ADDED Requirements:**
538
+ - Find or confirm the requirement does NOT exist in main spec
539
+ - Append the new requirement (with all scenarios) to the main spec
540
+
541
+ **## MODIFIED Requirements:**
542
+ - Find the requirement in main spec by name
543
+ - Apply ONLY the changed parts (add new scenarios, update descriptions)
544
+ - Do NOT wholesale replace — apply partial updates intelligently
545
+
546
+ **## REMOVED Requirements:**
547
+ - Find the requirement in main spec by name
548
+ - Remove the entire requirement block
549
+ - The Reason and Migration from delta should be noted in a comment
550
+
551
+ **## RENAMED Requirements:**
552
+ - Find FROM name in main spec
553
+ - Change the heading to TO name
554
+
555
+ ## Step 4 — Save the updated main spec to database
556
+ \`update_artifact(name="<main-spec-name>", content="<merged spec content>", project_slug="${slug}")\`
557
+
558
+ ## Step 5 — Mark delta spec as archived
559
+ After merging the delta, mark the delta spec as archived:
560
+ \`update_artifact(name="<delta-spec-name>", status="archived", metadata={"synced_at": "<ISO timestamp>", "merged_into": "<main-spec-name>"}, project_slug="${slug}")\`
561
+
562
+ ## Step 6 — Record the sync
563
+ \`record_trace(action="sync", result_summary="Synced delta for capability: <capability> into main spec", project_slug="${slug}")\`
564
+ Tell the user which capabilities were updated.
565
+ `,
566
+ },
567
+
568
+ // ── <opsr:archive ───────────────────────────────────────────────────────────
569
+ {
570
+ folder: "opsr",
571
+ name: "archive",
572
+ content: `${artifactHeader("/opsr:archive")}## Purpose
573
+ Finalize a completed change by archiving all its artifacts.
574
+ Runs verification checks, syncs delta specs to main specs, then archives everything.
575
+
576
+ ## Input
577
+ $ARGUMENTS = change name. If not provided, list active changes and ask.
578
+
579
+ ## Step 1 — Get full status of the change
580
+ \`list_artifacts(type="proposal", project_slug="${slug}")\`
581
+ Select the change to archive (or use $ARGUMENTS).
582
+ \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
583
+ Get all linked artifacts (specs, design, tasks).
584
+
585
+ ## Step 2 — Validate artifact completion
586
+ Check each artifact status:
587
+ \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
588
+ If pending tasks exist → warn the user and ask for confirmation to archive anyway.
589
+
590
+ ## Step 3 — Validate task completion
591
+ Count draft vs archived tasks. If any draft tasks remain → warn and confirm.
592
+
593
+ ## Step 4 — Check for delta specs that need syncing
594
+ \`list_artifacts(type="spec", project_slug="${slug}")\`
595
+ Filter for specs where metadata.change_name = "<change-name>" AND metadata.is_delta = true.
596
+
597
+ If delta specs exist:
598
+ - Show which capabilities have deltas
599
+ - Ask: "Sync delta specs to main specs now? (recommended)"
600
+ - If yes → execute <opsr:sync logic for each delta spec
601
+ - If no → archive without syncing
602
+
603
+ ## Step 5 — Archive all change artifacts
604
+ For each artifact in this change (proposal, all specs, design, all tasks):
605
+ \`update_artifact(name="<artifact-name>", status="archived", metadata={"archived_at": "<ISO timestamp>", "change_name": "<change-name>"}, project_slug="${slug}")\`
606
+
607
+ ## Step 6 — Record and show summary
608
+ \`record_trace(action="archive", result_summary="Archived change: <change-name> (<N> artifacts)", project_slug="${slug}")\`
609
+ Show summary:
610
+ - Artifacts archived: list
611
+ - Specs synced: list (if any)
612
+ - "Change <change-name> is complete."
613
+ `,
614
+ },
615
+
616
+ // ── <opsr:explore ───────────────────────────────────────────────────────────
617
+ {
618
+ folder: "opsr",
619
+ name: "explore",
620
+ content: `${artifactHeader("/opsr:explore")}## Purpose
621
+ Think through a problem, idea, or question WITHOUT implementing anything.
622
+ Explore creates understanding before committing to a proposal.
623
+ You may create OpenSddRag artifacts to capture insights, but NEVER write application code.
624
+
625
+ ## Input
626
+ $ARGUMENTS = topic, question, or idea to explore.
627
+
628
+ ## Stance
629
+ You are in THINKING MODE. Your role is to:
630
+ - Ask clarifying questions
631
+ - Surface multiple options with trade-offs
632
+ - Investigate the codebase (read-only)
633
+ - Create ASCII diagrams to illustrate ideas
634
+ - Challenge assumptions
635
+ - Reference existing specs for context
636
+
637
+ You MUST NOT:
638
+ - Write application code
639
+ - Create implementation files
640
+ - Make changes to the codebase
641
+
642
+ ## Step 1 — Check for existing related work
643
+ \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
644
+ \`recall_episodes(query="$ARGUMENTS", project_slug="${slug}", limit=3)\`
645
+ Share any existing specs or past decisions that are relevant.
646
+
647
+ ## Step 2 — Investigate and think
648
+ - Read relevant codebase files (read-only)
649
+ - Identify constraints and dependencies
650
+ - Surface at least 2 different approaches
651
+ - For each approach, list trade-offs
652
+
653
+ ## Step 3 — Capture insights (if user asks)
654
+ If the user wants to capture a finding or decision, create an artifact:
655
+ \`create_artifact(name="explore-<topic>-<date>", type="proposal", content="<exploration notes, options, trade-offs>", metadata={"explore": true}, project_slug="${slug}")\`
656
+
657
+ ## Step 4 — Transition when ready
658
+ When the user has enough insight to decide:
659
+ - Summarize key findings and recommendation
660
+ - Ask: "Ready to create a formal proposal? Run \`<opsr:propose <name>\`"
661
+ `,
662
+ },
663
+
664
+ // ── <opsr:continue ─────────────────────────────────────────────────────────
665
+ {
666
+ folder: "opsr",
667
+ name: "continue",
668
+ content: `${artifactHeader("/opsr:continue")}## Purpose
669
+ Create the NEXT single artifact in the dependency chain for a change.
670
+ Unlike /opsr:flow which creates all artifacts, this creates ONE artifact and stops.
671
+ Dependency order: proposal → specs → design → tasks.
672
+
673
+ ## Input
674
+ $ARGUMENTS = change name.
675
+
676
+ ## Step 1 — Get current status from database
677
+ \`list_artifacts(type="proposal", project_slug="${slug}")\`
678
+ Identify the change to continue.
679
+ \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
680
+ Get all existing artifacts for this change.
681
+
682
+ ## Step 2 — Find the next artifact to create
683
+ Check which artifacts exist and which are missing, in dependency order:
684
+ 1. proposal → if missing, stop (must run <opsr:propose first)
685
+ 2. specs → if any capability has no spec → create ONE spec and stop
686
+ 3. design → if missing and all specs exist → create design and stop
687
+ 4. tasks → if missing and design exists → create tasks and stop
688
+
689
+ If all artifacts exist → tell the user "All planning artifacts complete. Run /apply."
690
+
691
+ ## Step 3 — Create the NEXT artifact only
692
+ Follow the logic from the corresponding command:
693
+ - For spec: follow /opsr:spec steps for ONE capability
694
+ - For design: follow /opsr:design steps
695
+ - For tasks: follow <opsr:tasks steps
696
+
697
+ ## Step 4 — Show progress
698
+ After creating the artifact:
699
+ - Show what was created
700
+ - Show what is now unlocked (next in dependency chain)
701
+ - Suggest: "Run \`<opsr:continue <change-name>\` to create the next artifact."
702
+ `,
703
+ },
704
+
705
+ // ── <opsr:status ────────────────────────────────────────────────────────────
706
+ {
707
+ folder: "opsr",
708
+ name: "status",
709
+ content: `${artifactHeader("/opsr:status")}## Purpose
710
+ Show the current state of all in-progress changes for this project.
711
+ Reads from the MCP server — no local files involved.
712
+
713
+ ## Input
714
+ $ARGUMENTS = optional change name to show details for one change. If not provided, show all.
715
+
716
+ ## Step 1 — Load working context
717
+ \`get_working_context(project_slug="${slug}")\`
718
+
719
+ ## Step 2 — List all artifacts by type and status
720
+ \`list_artifacts(type="proposal", status="draft", project_slug="${slug}")\`
721
+ \`list_artifacts(type="proposal", status="active", project_slug="${slug}")\`
722
+ \`list_artifacts(type="spec", status="draft", project_slug="${slug}")\`
723
+ \`list_artifacts(type="design", status="draft", project_slug="${slug}")\`
724
+ \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
725
+ \`list_artifacts(type="task", status="active", project_slug="${slug}")\`
726
+
727
+ ## Step 3 — Recall recent activity
728
+ \`recall_episodes(query="recent actions in this project", project_slug="${slug}", limit=5)\`
729
+
730
+ ## Step 4 — Present structured status
731
+
732
+ For each active change, show:
733
+ \`\`\`
734
+ ## Change: <change-name>
735
+ | Artifact | Status |
736
+ |----------|--------|
737
+ | Proposal | ✓ done |
738
+ | Specs | ✓ 2/2 |
739
+ | Design | ✓ done |
740
+ | Tasks | 3/5 done |
741
+
742
+ Current task: <task-name>
743
+ Next step: <opsr:apply <change-name>
744
+ \`\`\`
745
+
746
+ Then show:
747
+ - Recent activity (last 5 actions from episodic memory)
748
+ - Suggested next command based on current state
749
+ `,
750
+ },
751
+
752
+ // ── /opsr:flow ──────────────────────────────────────────────────────────────
753
+ {
754
+ folder: "opsr",
755
+ name: "flow",
756
+ content: `${artifactHeader("/opsr:flow")}## Purpose
757
+ Run the complete SDD flow end-to-end in a single session.
758
+ Planning artifacts (proposal, specs, design, tasks) are saved to the database via MCP tools.
759
+ Implementation code (Phase 5) is written locally using standard file tools (Edit, Write, Bash).
760
+
761
+ ## Input
762
+ $ARGUMENTS = feature description or change name.
763
+
764
+ ## PHASE 1 — Propose
765
+ Follow <opsr:propose steps:
766
+ 1. \`search_semantic(query="$ARGUMENTS", project_slug="${slug}")\` — check for duplicates
767
+ 2. Compose proposal content (Why / What Changes / Capabilities / Impact)
768
+ 3. \`create_artifact(name="<change-name>-proposal", type="proposal", content="...", project_slug="${slug}")\`
769
+
770
+ ## PHASE 2 — Spec
771
+ Follow /opsr:spec steps for each capability in the proposal:
772
+ 4. For each capability: compose spec (Purpose / Requirements with SHALL / Scenarios with WHEN-THAN)
773
+ 5. \`create_artifact(name="<change-name>-<capability>-spec", type="spec", content="...", project_slug="${slug}")\`
774
+ 6. \`link_artifacts(source_name="<spec>", target_name="<proposal>", relationship_type="implements", project_slug="${slug}")\`
775
+ 7. \`validate_artifact(name="<spec>", project_slug="${slug}")\` — fix errors before continuing
776
+
777
+ ## PHASE 3 — Design
778
+ Follow /opsr:design steps:
779
+ 8. Read all specs just created
780
+ 9. Compose design (Context / Goals / Decisions / Architecture / Risks / Migration)
781
+ 10. \`create_artifact(name="<change-name>-design", type="design", content="...", project_slug="${slug}")\`
782
+ 11. \`link_artifacts(source_name="<design>", target_name="<proposal>", relationship_type="depends_on", project_slug="${slug}")\`
783
+
784
+ ## PHASE 4 — Tasks
785
+ Follow <opsr:tasks steps:
786
+ 12. Read proposal, all specs, and design from database
787
+ 13. For each task: \`create_artifact(name="<change-name>-task-<N>", type="task", content="...", project_slug="${slug}")\`
788
+ 14. \`link_artifacts(source_name="<task>", target_name="<spec>", relationship_type="implements", project_slug="${slug}")\`
789
+
790
+ ## PHASE 5 — Apply (repeat for each task in order)
791
+ > **Implementation phase:** Code changes are written to local files using Edit, Write, and Bash. MCP tools are used only to read planning artifacts and record traces.
792
+
793
+ Follow <opsr:apply steps:
794
+ 15. Read ALL planning artifacts as context (proposal + specs + design)
795
+ 16. \`update_artifact(name="<task>", status="active", project_slug="${slug}")\`
796
+ 17. Implement the task against its acceptance criteria (write code locally using Edit/Write/Bash)
797
+ 18. \`update_artifact(name="<task>", status="archived", project_slug="${slug}")\`
798
+ 19. \`record_trace(action="apply_task", result_summary="Completed: <task>", project_slug="${slug}")\`
799
+
800
+ ## PHASE 6 — Archive
801
+ Follow <opsr:archive steps:
802
+ 20. Sync delta specs if any
803
+ 21. \`update_artifact(name="<all artifacts>", status="archived", project_slug="${slug}")\`
804
+ 22. \`record_trace(action="complete_flow", result_summary="Completed: $ARGUMENTS", project_slug="${slug}")\`
805
+ `,
806
+ },
807
+
808
+ // ── <opsr:search ────────────────────────────────────────────────────────────
809
+ {
810
+ folder: "opsr",
811
+ name: "search",
812
+ content: `${artifactHeader("/opsr:search")}## Purpose
813
+ Search the SDD knowledge base using semantic similarity (pgvector).
814
+ Use this BEFORE starting any new work to find existing specs, decisions, and past implementations.
815
+
816
+ ## Input
817
+ $ARGUMENTS = natural language search query.
818
+
819
+ ## Step 1 — Search this project
820
+ \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
821
+
822
+ ## Step 2 — If no relevant results, search all projects
823
+ \`search_semantic(query="$ARGUMENTS", project_slug="*", limit=5)\`
824
+
825
+ ## Step 3 — Recall past actions related to the query
826
+ \`recall_episodes(query="$ARGUMENTS", project_slug="${slug}", limit=3)\`
827
+
828
+ ## Step 4 — Present results clearly
829
+ For each result: name, type, status, and a content excerpt (first 200 chars).
830
+ Group by: this project / other projects / past actions.
831
+
832
+ ## Step 5 — Offer to read the full artifact
833
+ \`read_artifact(name="<artifact-name>", project_slug="${slug}")\`
834
+ `,
835
+ },
836
+ ];
837
+ }