showdar-skills 0.4.0 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -4,7 +4,68 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
- ## [Unreleased]
7
+ ## [0.6.0]
8
+
9
+ ### Added
10
+
11
+ - Portable workflow execution state (`src/workflow-state.js`): versioned
12
+ JSON checkpoint schema (schemaVersion 1) with stage selection, evidence
13
+ receipts, structured skip, interruption, and resume. State never persists
14
+ authority; resume always re-resolves through Phase 6G. Caller/harness
15
+ owns persistence; no filesystem store, backend, or telemetry.
16
+ - Workflow checkpoint documentation in all four workflow skills
17
+ (feature, bugfix, release, incident): serialization,
18
+ interruption/resume, stale-checkpoint blocking, and stage vs workflow
19
+ completion semantics.
20
+ - Workflow-state policy validation in `src/validate.js`: catalog coverage,
21
+ no authority fields in checkpoints, no harness or storage coupling.
22
+
23
+ ### Changed
24
+
25
+ - Four workflow skills now describe adaptive state semantics instead of
26
+ ephemeral-only tracking.
27
+ - Workflow completion explicitly distinguishes stage completion (primitive
28
+ evidence and stop conditions) from workflow completion (all selected
29
+ stages completed or validly skipped, no blockers, required verification
30
+ satisfied).
31
+
32
+ ### Safety
33
+
34
+ - Checkpoint state never persists authority-derived fields.
35
+ - Caller owns checkpoint persistence; Showdar chooses no storage.
36
+ - Stale checkpoints block with `replanRequired` rather than continuing.
37
+
38
+ ## [0.5.0]
39
+
40
+ ### Added
41
+
42
+ - Native per-harness adapter layer over the unchanged portable core
43
+ (15 primitives + 4 workflows, 19 total installable skills).
44
+ - Generated OpenCode slash commands
45
+ (`.opencode/commands/showdar/`): one direct command per installed skill
46
+ plus a generic `/showdar/skill` aggregator reflecting the installed set.
47
+ - Generated Claude Code slash commands
48
+ (`.claude/commands/showdar/`): one direct command per installed skill
49
+ plus a generic `/showdar/skill` aggregator reflecting the installed set.
50
+ - Claude Code `CLAUDE.md` managed-block integration from the canonical
51
+ instruction body.
52
+ - Cursor native `.cursor/rules/showdar.mdc` rule (Apply Intelligently,
53
+ `alwaysApply: false`, no globs) from the canonical instruction body.
54
+ - Canonical adapter renderers (`src/adapter-renderers.js`) for
55
+ instructions, direct commands, and the generic aggregator.
56
+ - Adapter lifecycle and ownership validation: doctor/status checks for
57
+ active instruction surfaces, generated commands, and aggregators;
58
+ stale Showdar-owned artifact cleanup on target switching.
59
+
60
+ ### Changed
61
+
62
+ - Installer manages harness-native command and instruction artifacts
63
+ alongside portable skills.
64
+ - Doctor/status validate active adapter artifacts; global installs do not
65
+ require instruction files and non-command hosts do not require commands.
66
+ - `--ai all` is a compatibility aggregate: all skill roots, OpenCode and
67
+ Claude commands, and only the canonical `AGENTS.md` instruction block
68
+ (no `CLAUDE.md` block, no Cursor rule).
8
69
 
9
70
  ## [0.4.0]
10
71
 
package/MIGRATION.md CHANGED
@@ -1,3 +1,50 @@
1
+ # Migrating to 0.6.0
2
+
3
+ 0.6.0 adds portable workflow execution state (`src/workflow-state.js`,
4
+ schemaVersion 1) over the unchanged 15 primitives, 4 workflows, and Phase 6G
5
+ authority.
6
+
7
+ - Existing 0.5 installs and configs remain valid; no adapter or config
8
+ migration is required.
9
+ - The four workflows now support explicit portable execution state:
10
+ stage selection and progression, evidence-backed skipping, stage vs
11
+ workflow completion, interruption, and resume.
12
+ - Checkpoints are plain JSON at schemaVersion 1. Persistence is owned by
13
+ the caller or harness; Showdar 0.6 defines no state directory, backend,
14
+ session registry, or telemetry.
15
+ - Resume always re-resolves current context through Phase 6G. Stale
16
+ checkpoints return `BLOCKED` with `replanRequired` instead of silently
17
+ continuing.
18
+ - Checkpoints never persist authority. No migration of prior route or
19
+ authority state exists or is needed.
20
+ - No config change is required. Callers that never persist a checkpoint
21
+ keep the previous ephemeral-only behavior.
22
+
23
+ # Migrating to 0.5.0
24
+
25
+ 0.5.0 adds a thin native adapter layer over the unchanged portable core.
26
+ Existing 0.4 `.showdar.json` v2 configs remain valid; no schema bump is
27
+ required (adapter metadata is additive and optional).
28
+
29
+ - Re-running `showdar init ...` may add native adapter artifacts for the
30
+ selected harness. Existing skill content remains unchanged when hashes
31
+ match.
32
+ - Claude: 0.5 adds the `CLAUDE.md` managed block plus native Showdar
33
+ command files under `.claude/commands/showdar/`.
34
+ - Cursor: 0.5 adds `.cursor/rules/showdar.mdc` (Apply Intelligently,
35
+ `alwaysApply: false`, no globs).
36
+ - OpenCode: existing command behavior is extended through the canonical
37
+ generated command lifecycle (one direct command per installed skill plus
38
+ `/showdar/skill`).
39
+ - `--ai all` is a defined compatibility aggregate: all skill roots,
40
+ OpenCode and Claude commands, and only the `AGENTS.md` block (no
41
+ `CLAUDE.md` block, no Cursor rule).
42
+ - Global scope installs skills and OpenCode/Claude commands where
43
+ applicable, with no managed global instruction files.
44
+ - Removal deletes only Showdar-owned adapter artifacts and managed blocks;
45
+ user content outside Showdar markers remains intact.
46
+ - Portable skill/workflow semantics and Phase 6G authority are unchanged.
47
+
1
48
  # Migrating to 0.4.0
2
49
 
3
50
  0.4.0 adds four optional workflow skills over the unchanged 15 primitives:
package/README.md CHANGED
@@ -89,16 +89,97 @@ instructions.
89
89
  | Cursor | `.cursor/skills/` | `~/.cursor/skills/` | Supported installation target |
90
90
  | Claude Code | `.claude/skills/` | `~/.claude/skills/` | Supported installation target |
91
91
 
92
- Universal uses `.agents/skills/`. Explicit harness targets use their native
93
- skill directories. Codex and Universal intentionally share `.agents/skills/`.
94
- OpenCode additionally receives native `/showdar/...` command files in
95
- `.opencode/commands/showdar/` (project) and
96
- `~/.config/opencode/commands/showdar/` (global).
97
-
98
92
  "Supported installation target" means skills install to the harness-native
99
93
  directory. It does not promise identical implicit invocation, cloud,
100
94
  agent/subagent, or MCP behavior across harnesses.
101
95
 
96
+ ## Adapter model
97
+
98
+ The portable core (15 primitives + 4 workflows) never changes per harness.
99
+ A thin native adapter layer renders harness-specific entry surfaces only:
100
+
101
+ ```text
102
+ portable Showdar semantics
103
+ -> canonical renderers
104
+ -> harness adapter
105
+ -> native instruction/command surface
106
+ ```
107
+
108
+ Adapters do NOT change routing, grant authority, rewrite `SKILL.md`
109
+ semantics, or fork workflows per harness.
110
+
111
+ ## Native instruction surfaces (project scope)
112
+
113
+ | Target | Instruction surface |
114
+ | --- | --- |
115
+ | `universal` | `AGENTS.md` managed block |
116
+ | `codex` | `AGENTS.md` managed block |
117
+ | `opencode` | `AGENTS.md` managed block |
118
+ | `claude` | `CLAUDE.md` managed block |
119
+ | `cursor` | `.cursor/rules/showdar.mdc` |
120
+
121
+ One native instruction surface per explicit target. The Cursor rule uses
122
+ Apply Intelligently metadata (`alwaysApply: false`, no globs) and carries
123
+ the same canonical semantic body as the `AGENTS.md`/`CLAUDE.md` blocks.
124
+
125
+ ## Native command surfaces
126
+
127
+ | Target | Commands |
128
+ | --- | --- |
129
+ | `opencode` | Native `/showdar/<skill>` |
130
+ | `claude` | Native `/showdar/<skill>` |
131
+ | `codex` | None (skill invocation only) |
132
+ | `cursor` | None (rule discovery only) |
133
+ | `universal` | None (skill discovery only) |
134
+
135
+ `/showdar/skill` is generated for OpenCode/Claude as generic
136
+ installed-skill discovery. Commands are generated dynamically from the
137
+ installed skill set: `minimal` yields 8 direct commands plus the generic
138
+ entry; adding `feature` yields 9 plus generic. All 19 commands never exist
139
+ unless all 19 skills are installed.
140
+
141
+ ## Native install examples
142
+
143
+ ```bash
144
+ showdar init --ai opencode
145
+ showdar init --ai claude
146
+ showdar init --ai cursor
147
+ showdar add feature --ai claude
148
+ showdar add debug --ai opencode
149
+ ```
150
+
151
+ OpenCode project install produces `.opencode/skills/...`,
152
+ `.opencode/commands/showdar/...`, and the `AGENTS.md` managed block.
153
+ Claude produces `.claude/skills/...`, `.claude/commands/showdar/...`, and
154
+ the `CLAUDE.md` managed block. Cursor produces `.cursor/skills/...` and
155
+ `.cursor/rules/showdar.mdc` with no generated commands.
156
+
157
+ ## `--ai all` compatibility policy
158
+
159
+ `--ai all` is a compatibility aggregate. It installs all native skill
160
+ roots, generates OpenCode and Claude commands, and writes only the
161
+ canonical `AGENTS.md` instruction block. It does NOT generate the
162
+ `CLAUDE.md` Showdar block or the Cursor rule, avoiding duplicate Showdar
163
+ instruction ingestion across compatibility-aware hosts. For native-optimal
164
+ Claude/Cursor behavior use explicit `--ai claude` or `--ai cursor`.
165
+
166
+ ## Global scope
167
+
168
+ Global installs provide skills everywhere and OpenCode/Claude commands
169
+ where applicable, with no managed global instruction files. This is
170
+ deliberate in 0.5.0:
171
+
172
+ | Global target | Contents |
173
+ | --- | --- |
174
+ | `universal` | skills only |
175
+ | `codex` | skills only |
176
+ | `opencode` | skills + commands |
177
+ | `claude` | skills + commands |
178
+ | `cursor` | skills only |
179
+ | `all` | all skill roots + OpenCode/Claude commands |
180
+
181
+ No global `AGENTS.md`, `CLAUDE.md`, or Cursor rule is managed.
182
+
102
183
  ## Project and global installation
103
184
 
104
185
  Global CLI installation and global skill installation are separate decisions.
@@ -304,6 +385,64 @@ primitive (`showdar-review`, `showdar-debug`, `showdar-test`). Phase 6G remains
304
385
  the authority source; workflows consume it and never mint it. Workflows are
305
386
  opt-in through `showdar add <workflow>`; profiles install primitive sets only.
306
387
 
388
+ ## Workflow execution state (0.6.0)
389
+
390
+ ```text
391
+ portable workflow
392
+ -> workflow-state
393
+ -> primitive evidence/stop conditions
394
+ -> current Phase 6G resolution
395
+ -> next stage / blocked / complete
396
+ ```
397
+
398
+ Workflow state (`src/workflow-state.js`, schemaVersion 1) is a portable,
399
+ versioned JSON checkpoint: `workflowId`, selected stages, active stage,
400
+ completed stages, skipped stages, evidence receipts, blockers, next stage,
401
+ `status` (`NEW`/`READY`/`ACTIVE`/`COMPLETE`/`INTERRUPTED`/`BLOCKED`), and a
402
+ deterministic monotonic `revision` counter. Timestamps
403
+ (`createdAt`/`updatedAt`/receipt timestamps) are metadata and provenance only.
404
+
405
+ Workflow state is NOT authority, memory, router intent, or a persistence
406
+ backend. It never persists authority-derived fields
407
+ (`primaryCapability`, `authorizedAction`, `mutationPermission`,
408
+ `routeAuthority` or equivalents). Checkpoint JSON may be stored by a
409
+ caller or harness anywhere; Showdar 0.6 does not choose or manage storage.
410
+
411
+ Evidence receipts are compact copies of primitive evidence at stage
412
+ completion (`kind`, `quality`, `source`, `detail`, timestamp, optional
413
+ provenance). Quality follows `claimed < observed < verified`; `failed` and
414
+ `missing` remain meaningful negative states. High-sensitivity evidence
415
+ (change, tests, build, package, compatibility, regression proof, release
416
+ readiness) may require re-verification after resume; old evidence is not
417
+ permanently valid.
418
+
419
+ Safe resume is always:
420
+
421
+ ```text
422
+ checkpoint
423
+ -> deserialize + validate
424
+ -> resolve current request/context through Phase 6G
425
+ -> compatibility/freshness checks
426
+ -> READY or BLOCKED + replanRequired
427
+ ```
428
+
429
+ A checkpoint alone can never authorize continuation. Previously authorized
430
+ mutation is never restored from a checkpoint. When the current Phase 6G
431
+ resolution no longer matches the checkpoint, resume returns `BLOCKED` with
432
+ `replanRequired` instead of silently continuing.
433
+
434
+ Per-workflow skip policy (evidence-backed, never severity or wording alone):
435
+
436
+ - Feature: requirements/plan/design may be skipped only with policy-backed
437
+ evidence; build, test, and review always run.
438
+ - Bugfix: debug may be skipped only with verified root-cause evidence;
439
+ symptom description alone is insufficient; investigation-only requests stop
440
+ without mutation.
441
+ - Release: readiness does not imply deployment; ops loads only with explicit
442
+ target plus execution authorization.
443
+ - Incident: severity never grants production mutation; recovery and
444
+ verification remain gated by current authority.
445
+
307
446
  ## A typical software workflow
308
447
 
309
448
  ```text
package/bin/showdar.js CHANGED
@@ -32,7 +32,7 @@ function scopeAfter(args) {
32
32
  function printHelp(version, command = null) {
33
33
  const scopeUsage = '[--scope <project|global>]';
34
34
  if (command === 'init') {
35
- console.log(`Showdar Skills ${version}\n\nUsage:\n showdar init ${scopeUsage} [--profile <name>] [--ai <universal|codex|opencode|cursor|claude|all>]\n\nDefaults: scope project, profile full, AI target universal.\nProject scope writes native skills and project .showdar.json. Global scope writes verified user skill directories and ~/.showdar/global.json without project files. Codex and universal use .agents/skills in project scope and ~/.agents/skills in global scope; cursor uses .cursor/skills in project scope and ~/.cursor/skills in global scope; --ai all writes each shared destination once.\n\nProfiles: ${Object.keys(PROFILES).join(', ')}\nDeprecated aliases: ${Object.entries(PROFILE_ALIASES).map(([alias, target]) => `${alias} -> ${target}`).join(', ')}\nAI targets: ${AI_TARGETS.join(', ')}`);
35
+ console.log(`Showdar Skills ${version}\n\nUsage:\n showdar init ${scopeUsage} [--profile <name>] [--ai <universal|codex|opencode|cursor|claude|all>]\n\nDefaults: scope project, profile full, AI target universal.\nProject scope writes native skills, one native instruction surface, and project .showdar.json. Global scope writes verified user skill directories and ~/.showdar/global.json without instruction files. Codex and universal use .agents/skills in project scope and ~/.agents/skills in global scope; cursor uses .cursor/skills in project scope and ~/.cursor/skills in global scope; --ai all writes each shared destination once, generates OpenCode and Claude commands, and writes only the AGENTS.md block.\n\nProfiles: ${Object.keys(PROFILES).join(', ')}\nDeprecated aliases: ${Object.entries(PROFILE_ALIASES).map(([alias, target]) => `${alias} -> ${target}`).join(', ')}\nAI targets: ${AI_TARGETS.join(', ')}`);
36
36
  return;
37
37
  }
38
38
  if (['status', 'doctor', 'remove'].includes(command)) {
@@ -86,10 +86,9 @@ async function main() {
86
86
  const ai = valueAfter(args, '--ai', 'universal');
87
87
  const skillIds = resolveProfile(requestedProfile);
88
88
  if (isDeprecatedProfile(requestedProfile)) console.warn(`Warning: profile "${requestedProfile}" is deprecated; use "${profile}".`);
89
- const commandNames = ai === 'opencode' || ai === 'all' ? COMMANDS : [];
90
89
  const result = scope === 'global'
91
- ? await initGlobal({ homeRoot: homedir(), packageRoot, profile, ai, skillIds, commandNames, packageVersion: version })
92
- : await initProject({ projectRoot, packageRoot, profile, ai, skillIds, commandNames, packageVersion: version });
90
+ ? await initGlobal({ homeRoot: homedir(), packageRoot, profile, ai, skillIds, packageVersion: version })
91
+ : await initProject({ projectRoot, packageRoot, profile, ai, skillIds, packageVersion: version });
93
92
  console.log(`Showdar Skills installed.\nScope: ${scope}\nProfile: ${profile}\nAI: ${ai}\nTargets: ${result.targets.join(', ')}\nSkills: ${result.skills}\nOpenCode commands: ${result.commands}`);
94
93
  if (scope === 'project') {
95
94
  console.log(`Requested: ${result.requestedSkills}\nInstalled in project: ${result.installedSkills}\nSatisfied by global: ${result.satisfiedByGlobal}\nSkipped duplicate copies: ${result.skippedDuplicates}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "showdar-skills",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Production-grade software engineering lifecycle skills for coding agents.",
5
5
  "type": "module",
6
6
  "bin": { "showdar": "./bin/showdar.js" },
@@ -53,8 +53,12 @@ description: Use when resolving an observed defect end-to-end, adaptively sequen
53
53
 
54
54
  - Load one primitive at a time; hand off only when its stop condition is met.
55
55
  - Each primitive's own SKILL.md governs its stage; do not copy primitive instructions here.
56
- - Track ephemeral state only: candidate stages, selected stages, active stage, completed evidence, next stage or complete.
57
- - No persistent checkpoint or resume infrastructure in this version.
56
+ - Track portable workflow state (`src/workflow-state.js`): candidate stages, selected stages, active stage, completed evidence receipts, skipped stages with structured reason plus evidence plus policy, next stage or complete, status, revision.
57
+ - Checkpoint by serializing state to plain JSON; caller or harness owns persistence. No filesystem or backend store is implied.
58
+ - Interrupt explicitly to preserve completed plus skipped plus evidence state without inventing completion.
59
+ - Resume by validating the checkpoint, re-resolving current context through Phase 6G, checking workflow compatibility, then continuing or blocking with replan-required.
60
+ - Stored state never authorizes continuation; debug may be skipped only with proven root-cause evidence under policy, never from symptom description alone.
61
+ - Stage completion comes from primitive evidence and stop conditions; workflow completion requires root cause proven plus fix implemented plus verification plus review.
58
62
 
59
63
  ## Decision points
60
64
 
@@ -56,8 +56,12 @@ description: Use when implementing a complete feature end-to-end, adaptively seq
56
56
 
57
57
  - Load one primitive at a time; hand off only when its stop condition is met.
58
58
  - Each primitive's own SKILL.md governs its stage; do not copy primitive instructions here.
59
- - Track ephemeral state only: candidate stages, selected stages, active stage, completed evidence, next stage or complete.
60
- - No persistent checkpoint or resume infrastructure in this version.
59
+ - Track portable workflow state (`src/workflow-state.js`): candidate stages, selected stages, active stage, completed evidence receipts, skipped stages with structured reason plus evidence plus policy, next stage or complete, status, revision.
60
+ - Checkpoint by serializing state to plain JSON; caller or harness owns persistence. No filesystem or backend store is implied.
61
+ - Interrupt explicitly to preserve completed plus skipped plus evidence state without inventing completion.
62
+ - Resume by validating the checkpoint, re-resolving current context through Phase 6G, checking workflow compatibility, then continuing or blocking with replan-required.
63
+ - Stored state never authorizes continuation; skip requires policy plus evidence, never severity or wording alone.
64
+ - Stage completion comes from primitive evidence and stop conditions; workflow completion requires every selected stage completed or validly skipped, no blockers, and required verification satisfied.
61
65
 
62
66
  ## Decision points
63
67
 
@@ -57,8 +57,12 @@ description: Use when investigating and recovering from an active operational in
57
57
 
58
58
  - Load one primitive at a time; hand off only when its stop condition is met.
59
59
  - Each primitive's own SKILL.md governs its stage; do not copy primitive instructions here.
60
- - Track ephemeral state only: candidate stages, selected stages, active stage, completed evidence, next stage or complete.
61
- - No persistent checkpoint or resume infrastructure in this version.
60
+ - Track portable workflow state (`src/workflow-state.js`): candidate stages, selected stages, active stage, completed evidence receipts, skipped stages with structured reason plus evidence plus policy, next stage or complete, status, revision.
61
+ - Checkpoint by serializing state to plain JSON; caller or harness owns persistence. No filesystem or backend store is implied.
62
+ - Interrupt explicitly to preserve completed plus skipped plus evidence state without inventing completion.
63
+ - Resume by validating the checkpoint, re-resolving current context through Phase 6G, checking workflow compatibility, then continuing or blocking with replan-required.
64
+ - Stored state never authorizes continuation; severity never grants production mutation, and ops loads only with explicit environment plus action authority.
65
+ - Stage completion comes from primitive evidence and stop conditions; workflow completion requires recovery plus verification per policy, not merely diagnosis.
62
66
 
63
67
  ## Decision points
64
68
 
@@ -54,8 +54,12 @@ description: Use when preparing, validating, or executing a release lifecycle, a
54
54
 
55
55
  - Load one primitive at a time; hand off only when its stop condition is met.
56
56
  - Each primitive's own SKILL.md governs its stage; do not copy primitive instructions here.
57
- - Track ephemeral state only: candidate stages, selected stages, active stage, completed evidence, next stage or complete.
58
- - No persistent checkpoint or resume infrastructure in this version.
57
+ - Track portable workflow state (`src/workflow-state.js`): candidate stages, selected stages, active stage, completed evidence receipts, skipped stages with structured reason plus evidence plus policy, next stage or complete, status, revision.
58
+ - Checkpoint by serializing state to plain JSON; caller or harness owns persistence. No filesystem or backend store is implied.
59
+ - Interrupt explicitly to preserve completed plus skipped plus evidence state without inventing completion.
60
+ - Resume by validating the checkpoint, re-resolving current context through Phase 6G, checking workflow compatibility, then continuing or blocking with replan-required.
61
+ - Stored state never authorizes continuation; ops is skipped under readiness-only policy and never implied by release completion.
62
+ - Stage completion comes from primitive evidence and stop conditions; workflow completion means readiness verification per policy, not implicit deployment.
59
63
 
60
64
  ## Decision points
61
65
 
@@ -0,0 +1,88 @@
1
+ import { ALL_SKILLS } from './catalog.js';
2
+
3
+ const CANONICAL_ROUTE_ORDER = [
4
+ ['map repository architecture, dependencies, or impact', 'showdar-understand'],
5
+ ['plan implementation of agreed behavior and scope', 'showdar-plan'],
6
+ ['design product UI, UX, responsive layout, accessibility, or visual polish', 'showdar-design'],
7
+ ['implement or refactor an agreed application change', 'showdar-build'],
8
+ ['debug an observed bug, crash, regression, build, or performance failure', 'showdar-debug'],
9
+ ['choose or implement automated tests and coverage', 'showdar-test'],
10
+ ['review code or diffs for general correctness, architecture, performance, maintainability, or tests', 'showdar-review'],
11
+ ['upgrade dependencies, frameworks, runtimes, or platforms', 'showdar-upgrade'],
12
+ ['check release, artifact, or handoff readiness', 'showdar-ship'],
13
+ ['recover interrupted or partial engineering work', 'showdar-recover'],
14
+ ['perform local Git inspection, staging, commit, merge, rebase, or conflict work', 'showdar-git'],
15
+ ['define product behavior, business rules, ambiguity, or acceptance criteria', 'showdar-requirements'],
16
+ ['plan QA scenarios, risk coverage, regression, compatibility, or bug evidence', 'showdar-quality'],
17
+ ['assess threats, attack surface, trust boundaries, auth, secrets, exposure, or exploitability', 'showdar-security'],
18
+ ['inspect or change CI/CD, containers, environments, deployment, observability, rollback, or runtime operations', 'showdar-ops'],
19
+ ['implement a complete feature end-to-end across multiple lifecycle stages', 'showdar-feature'],
20
+ ['resolve an observed defect end-to-end', 'showdar-bugfix'],
21
+ ['prepare, validate, or execute a release lifecycle', 'showdar-release'],
22
+ ['investigate or recover from an active operational incident', 'showdar-incident'],
23
+ ];
24
+
25
+ function getSkillDescription(skillId) {
26
+ const skill = ALL_SKILLS.find((s) => s.id === skillId);
27
+ return skill?.description ?? '';
28
+ }
29
+
30
+ export function renderShowdarInstruction(skillIds) {
31
+ const wanted = new Set(skillIds);
32
+ const routes = CANONICAL_ROUTE_ORDER
33
+ .filter(([, id]) => wanted.has(id))
34
+ .map(([intent, id]) => `- ${intent} -> \`${id}\``);
35
+ for (const id of [...wanted].sort()) {
36
+ if (!CANONICAL_ROUTE_ORDER.some(([, known]) => known === id)) {
37
+ routes.push(`- ${getSkillDescription(id)} -> \`${id}\``);
38
+ }
39
+ }
40
+ return `${routes.join('\n')}\n`;
41
+ }
42
+
43
+ export function renderShowdarCommand(skillId) {
44
+ const description = getSkillDescription(skillId);
45
+ return `---
46
+ description: ${description}
47
+ ---
48
+
49
+ Load and follow \`${skillId}\`.
50
+ Ground in the current repository.
51
+ Request: \$ARGUMENTS
52
+ `;
53
+ }
54
+
55
+ export function renderShowdarAggregator(skillIds) {
56
+ const sorted = [...new Set(skillIds)].sort((a, b) => a.localeCompare(b));
57
+ const ids = sorted.join(', ');
58
+ return `---
59
+ description: Invoke a specific Showdar flagship skill explicitly
60
+ ---
61
+ Select exactly one requested Showdar skill and follow it: ${ids}. Whole-task intent (complete feature, end-to-end fix, release lifecycle, active incident) selects a workflow; single primitive intent stays primitive. If the requested name is ambiguous, choose the smallest matching skill from this list and say which one was selected.
62
+
63
+ Request: \$ARGUMENTS
64
+ `;
65
+ }
66
+
67
+ export function renderCursorRuleBody(skillIds) {
68
+ const body = renderShowdarInstruction(skillIds).trimEnd();
69
+ return `---
70
+ description: Showdar skill and workflow routing guidance for software-engineering tasks
71
+ alwaysApply: false
72
+ ---
73
+
74
+ ${body}
75
+ `;
76
+ }
77
+
78
+ export function renderManagedBlock(skillIds, kind) {
79
+ const body = renderShowdarInstruction(skillIds).trimEnd();
80
+ if (kind === 'block') {
81
+ const START = '<!-- showdar-skills:start -->';
82
+ const END = '<!-- showdar-skills:end -->';
83
+ return `${START}\n## Showdar Skills routing\n\nUse the smallest Showdar skill that fully matches the current task. Do not load unrelated Showdar skills.\n\n${body}\n\nFor debugging, gather evidence before modifying code. For shipping or destructive operations, require explicit user approval and fresh verification. Never print or commit secrets.\n${END}\n`;
84
+ } else if (kind === 'file') {
85
+ return renderCursorRuleBody(skillIds);
86
+ }
87
+ return body;
88
+ }
package/src/adapters.js CHANGED
@@ -3,6 +3,29 @@ import { homedir } from 'node:os';
3
3
 
4
4
  export const NATIVE_TARGETS = ['codex', 'opencode', 'cursor', 'claude', 'universal'];
5
5
 
6
+ export const ADAPTERS = {
7
+ universal: {
8
+ instruction: { kind: 'block', file: 'AGENTS.md' },
9
+ commands: null,
10
+ },
11
+ codex: {
12
+ instruction: { kind: 'block', file: 'AGENTS.md' },
13
+ commands: null,
14
+ },
15
+ opencode: {
16
+ instruction: { kind: 'block', file: 'AGENTS.md' },
17
+ commands: { destination: ['.opencode', 'commands', 'showdar'] },
18
+ },
19
+ claude: {
20
+ instruction: { kind: 'block', file: 'CLAUDE.md' },
21
+ commands: { destination: ['.claude', 'commands', 'showdar'] },
22
+ },
23
+ cursor: {
24
+ instruction: { kind: 'file', file: path.join('.cursor', 'rules', 'showdar.mdc') },
25
+ commands: null,
26
+ },
27
+ };
28
+
6
29
  const ROOTS = {
7
30
  codex: ['.agents', 'skills'],
8
31
  opencode: ['.opencode', 'skills'],
@@ -19,6 +42,11 @@ const GLOBAL_ROOTS = {
19
42
  universal: ({ homeRoot }) => path.join(homeRoot, '.agents', 'skills'),
20
43
  };
21
44
 
45
+ const GLOBAL_COMMAND_ROOTS = {
46
+ opencode: ({ homeRoot }) => path.join(homeRoot, '.config', 'opencode', 'commands', 'showdar'),
47
+ claude: ({ homeRoot }) => path.join(homeRoot, '.claude', 'commands', 'showdar'),
48
+ };
49
+
22
50
  export function resolveTargets(ai) {
23
51
  if (ai === 'all') return [...NATIVE_TARGETS];
24
52
  if (!NATIVE_TARGETS.includes(ai)) throw new Error(`Unknown AI target "${ai}". Expected codex, opencode, cursor, claude, universal, or all.`);
@@ -52,10 +80,40 @@ export const COMPATIBILITY_MATRIX = {
52
80
  universal: { project: true, global: true },
53
81
  };
54
82
 
83
+ export function commandRootFor(target, projectRoot) {
84
+ const adapter = ADAPTERS[target];
85
+ if (!adapter?.commands?.destination) return null;
86
+ return path.join(projectRoot, ...adapter.commands.destination);
87
+ }
88
+
89
+ export function globalCommandRootForTarget(target, { homeRoot = homedir() } = {}) {
90
+ const resolver = GLOBAL_COMMAND_ROOTS[target];
91
+ if (!resolver) return null;
92
+ return resolver({ homeRoot });
93
+ }
94
+
55
95
  export function opencodeCommandRoot(projectRoot) {
56
- return path.join(projectRoot, '.opencode', 'commands', 'showdar');
96
+ return commandRootFor('opencode', projectRoot);
57
97
  }
58
98
 
59
99
  export function globalCommandRootFor({ homeRoot = homedir() } = {}) {
60
- return path.join(homeRoot, '.config', 'opencode', 'commands', 'showdar');
61
- }
100
+ return globalCommandRootForTarget('opencode', { homeRoot });
101
+ }
102
+
103
+ export function claudeCommandRoot(projectRoot) {
104
+ return commandRootFor('claude', projectRoot);
105
+ }
106
+
107
+ export function globalClaudeCommandRootFor({ homeRoot = homedir() } = {}) {
108
+ return globalCommandRootForTarget('claude', { homeRoot });
109
+ }
110
+
111
+ export function instructionSurfaceFor(target, projectRoot) {
112
+ const adapter = ADAPTERS[target];
113
+ if (!adapter?.instruction) return null;
114
+ return {
115
+ kind: adapter.instruction.kind,
116
+ file: adapter.instruction.file,
117
+ targetPath: path.join(projectRoot, adapter.instruction.file),
118
+ };
119
+ }