@fission-ai/openspec 0.20.0 → 0.21.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/README.md +35 -0
- package/dist/cli/index.js +17 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/core/completions/command-registry.js +12 -0
- package/dist/core/templates/skill-templates.d.ts +5 -0
- package/dist/core/templates/skill-templates.js +165 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -140,6 +140,8 @@ These tools automatically read workflow instructions from `openspec/AGENTS.md`.
|
|
|
140
140
|
|
|
141
141
|
#### Step 1: Install the CLI globally
|
|
142
142
|
|
|
143
|
+
**Option A: Using npm**
|
|
144
|
+
|
|
143
145
|
```bash
|
|
144
146
|
npm install -g @fission-ai/openspec@latest
|
|
145
147
|
```
|
|
@@ -149,6 +151,39 @@ Verify installation:
|
|
|
149
151
|
openspec --version
|
|
150
152
|
```
|
|
151
153
|
|
|
154
|
+
**Option B: Using Nix (NixOS and Nix package manager)**
|
|
155
|
+
|
|
156
|
+
Run OpenSpec directly without installation:
|
|
157
|
+
```bash
|
|
158
|
+
nix run github:Fission-AI/OpenSpec -- init
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Or install to your profile:
|
|
162
|
+
```bash
|
|
163
|
+
nix profile install github:Fission-AI/OpenSpec
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Or add to your development environment in `flake.nix`:
|
|
167
|
+
```nix
|
|
168
|
+
{
|
|
169
|
+
inputs = {
|
|
170
|
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
171
|
+
openspec.url = "github:Fission-AI/OpenSpec";
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
outputs = { nixpkgs, openspec, ... }: {
|
|
175
|
+
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
|
|
176
|
+
buildInputs = [ openspec.packages.x86_64-linux.default ];
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Verify installation:
|
|
183
|
+
```bash
|
|
184
|
+
openspec --version
|
|
185
|
+
```
|
|
186
|
+
|
|
152
187
|
#### Step 2: Initialize OpenSpec in your project
|
|
153
188
|
|
|
154
189
|
Navigate to your project directory:
|
package/dist/cli/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { ChangeCommand } from '../commands/change.js';
|
|
|
13
13
|
import { ValidateCommand } from '../commands/validate.js';
|
|
14
14
|
import { ShowCommand } from '../commands/show.js';
|
|
15
15
|
import { CompletionCommand } from '../commands/completion.js';
|
|
16
|
+
import { FeedbackCommand } from '../commands/feedback.js';
|
|
16
17
|
import { registerConfigCommand } from '../commands/config.js';
|
|
17
18
|
import { registerArtifactWorkflowCommands } from '../commands/artifact-workflow.js';
|
|
18
19
|
import { maybeShowTelemetryNotice, trackCommand, shutdown } from '../telemetry/index.js';
|
|
@@ -279,6 +280,22 @@ program
|
|
|
279
280
|
process.exit(1);
|
|
280
281
|
}
|
|
281
282
|
});
|
|
283
|
+
// Feedback command
|
|
284
|
+
program
|
|
285
|
+
.command('feedback <message>')
|
|
286
|
+
.description('Submit feedback about OpenSpec')
|
|
287
|
+
.option('--body <text>', 'Detailed description for the feedback')
|
|
288
|
+
.action(async (message, options) => {
|
|
289
|
+
try {
|
|
290
|
+
const feedbackCommand = new FeedbackCommand();
|
|
291
|
+
await feedbackCommand.execute(message, options);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.log();
|
|
295
|
+
ora().fail(`Error: ${error.message}`);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
282
299
|
// Completion command with subcommands
|
|
283
300
|
const completionCmd = program
|
|
284
301
|
.command('completion')
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { execSync, execFileSync } from 'child_process';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
/**
|
|
6
|
+
* Check if gh CLI is installed and available in PATH
|
|
7
|
+
* Uses platform-appropriate command: 'where' on Windows, 'which' on Unix/macOS
|
|
8
|
+
*/
|
|
9
|
+
function isGhInstalled() {
|
|
10
|
+
try {
|
|
11
|
+
const command = process.platform === 'win32' ? 'where gh' : 'which gh';
|
|
12
|
+
execSync(command, { stdio: 'pipe' });
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if gh CLI is authenticated
|
|
21
|
+
*/
|
|
22
|
+
function isGhAuthenticated() {
|
|
23
|
+
try {
|
|
24
|
+
execSync('gh auth status', { stdio: 'pipe' });
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get OpenSpec version from package.json
|
|
33
|
+
*/
|
|
34
|
+
function getVersion() {
|
|
35
|
+
try {
|
|
36
|
+
const { version } = require('../../package.json');
|
|
37
|
+
return version;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return 'unknown';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get platform name
|
|
45
|
+
*/
|
|
46
|
+
function getPlatform() {
|
|
47
|
+
return os.platform();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get current timestamp in ISO format
|
|
51
|
+
*/
|
|
52
|
+
function getTimestamp() {
|
|
53
|
+
return new Date().toISOString();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate metadata footer for feedback
|
|
57
|
+
*/
|
|
58
|
+
function generateMetadata() {
|
|
59
|
+
const version = getVersion();
|
|
60
|
+
const platform = getPlatform();
|
|
61
|
+
const timestamp = getTimestamp();
|
|
62
|
+
return `---
|
|
63
|
+
Submitted via OpenSpec CLI
|
|
64
|
+
- Version: ${version}
|
|
65
|
+
- Platform: ${platform}
|
|
66
|
+
- Timestamp: ${timestamp}`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Format the feedback title
|
|
70
|
+
*/
|
|
71
|
+
function formatTitle(message) {
|
|
72
|
+
return `Feedback: ${message}`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Format the full feedback body
|
|
76
|
+
*/
|
|
77
|
+
function formatBody(bodyText) {
|
|
78
|
+
const parts = [];
|
|
79
|
+
if (bodyText) {
|
|
80
|
+
parts.push(bodyText);
|
|
81
|
+
parts.push(''); // Empty line before metadata
|
|
82
|
+
}
|
|
83
|
+
parts.push(generateMetadata());
|
|
84
|
+
return parts.join('\n');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate a pre-filled GitHub issue URL for manual submission
|
|
88
|
+
*/
|
|
89
|
+
function generateManualSubmissionUrl(title, body) {
|
|
90
|
+
const repo = 'Fission-AI/OpenSpec';
|
|
91
|
+
const encodedTitle = encodeURIComponent(title);
|
|
92
|
+
const encodedBody = encodeURIComponent(body);
|
|
93
|
+
const encodedLabels = encodeURIComponent('feedback');
|
|
94
|
+
return `https://github.com/${repo}/issues/new?title=${encodedTitle}&body=${encodedBody}&labels=${encodedLabels}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Display formatted feedback content for manual submission
|
|
98
|
+
*/
|
|
99
|
+
function displayFormattedFeedback(title, body) {
|
|
100
|
+
console.log('\n--- FORMATTED FEEDBACK ---');
|
|
101
|
+
console.log(`Title: ${title}`);
|
|
102
|
+
console.log(`Labels: feedback`);
|
|
103
|
+
console.log('\nBody:');
|
|
104
|
+
console.log(body);
|
|
105
|
+
console.log('--- END FEEDBACK ---\n');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Submit feedback via gh CLI
|
|
109
|
+
* Uses execFileSync to prevent shell injection vulnerabilities
|
|
110
|
+
*/
|
|
111
|
+
function submitViaGhCli(title, body) {
|
|
112
|
+
try {
|
|
113
|
+
const result = execFileSync('gh', [
|
|
114
|
+
'issue',
|
|
115
|
+
'create',
|
|
116
|
+
'--repo',
|
|
117
|
+
'Fission-AI/OpenSpec',
|
|
118
|
+
'--title',
|
|
119
|
+
title,
|
|
120
|
+
'--body',
|
|
121
|
+
body,
|
|
122
|
+
'--label',
|
|
123
|
+
'feedback',
|
|
124
|
+
], { encoding: 'utf-8', stdio: 'pipe' });
|
|
125
|
+
const issueUrl = result.trim();
|
|
126
|
+
console.log(`\n✓ Feedback submitted successfully!`);
|
|
127
|
+
console.log(`Issue URL: ${issueUrl}\n`);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
// Display the error output from gh CLI
|
|
131
|
+
if (error.stderr) {
|
|
132
|
+
console.error(error.stderr.toString());
|
|
133
|
+
}
|
|
134
|
+
else if (error.message) {
|
|
135
|
+
console.error(error.message);
|
|
136
|
+
}
|
|
137
|
+
// Exit with the same code as gh CLI
|
|
138
|
+
process.exit(error.status ?? 1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Handle fallback when gh CLI is not available or not authenticated
|
|
143
|
+
*/
|
|
144
|
+
function handleFallback(title, body, reason) {
|
|
145
|
+
if (reason === 'missing') {
|
|
146
|
+
console.log('⚠️ GitHub CLI not found. Manual submission required.');
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log('⚠️ GitHub authentication required. Manual submission required.');
|
|
150
|
+
}
|
|
151
|
+
displayFormattedFeedback(title, body);
|
|
152
|
+
const manualUrl = generateManualSubmissionUrl(title, body);
|
|
153
|
+
console.log('Please submit your feedback manually:');
|
|
154
|
+
console.log(manualUrl);
|
|
155
|
+
if (reason === 'unauthenticated') {
|
|
156
|
+
console.log('\nTo auto-submit in the future: gh auth login');
|
|
157
|
+
}
|
|
158
|
+
// Exit with success code (fallback is successful)
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Feedback command implementation
|
|
163
|
+
*/
|
|
164
|
+
export class FeedbackCommand {
|
|
165
|
+
async execute(message, options) {
|
|
166
|
+
// Format title and body once for all code paths
|
|
167
|
+
const title = formatTitle(message);
|
|
168
|
+
const body = formatBody(options?.body);
|
|
169
|
+
// Check if gh CLI is installed
|
|
170
|
+
if (!isGhInstalled()) {
|
|
171
|
+
handleFallback(title, body, 'missing');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Check if gh CLI is authenticated
|
|
175
|
+
if (!isGhAuthenticated()) {
|
|
176
|
+
handleFallback(title, body, 'unauthenticated');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Submit via gh CLI
|
|
180
|
+
submitViaGhCli(title, body);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -152,6 +152,18 @@ export const COMMAND_REGISTRY = [
|
|
|
152
152
|
},
|
|
153
153
|
],
|
|
154
154
|
},
|
|
155
|
+
{
|
|
156
|
+
name: 'feedback',
|
|
157
|
+
description: 'Submit feedback about OpenSpec',
|
|
158
|
+
acceptsPositional: true,
|
|
159
|
+
flags: [
|
|
160
|
+
{
|
|
161
|
+
name: 'body',
|
|
162
|
+
description: 'Detailed description for the feedback',
|
|
163
|
+
takesValue: true,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
155
167
|
{
|
|
156
168
|
name: 'change',
|
|
157
169
|
description: 'Manage OpenSpec change proposals (deprecated)',
|
|
@@ -92,4 +92,9 @@ export declare function getOpsxArchiveCommandTemplate(): CommandTemplate;
|
|
|
92
92
|
* Template for /opsx:verify slash command
|
|
93
93
|
*/
|
|
94
94
|
export declare function getOpsxVerifyCommandTemplate(): CommandTemplate;
|
|
95
|
+
/**
|
|
96
|
+
* Template for feedback skill
|
|
97
|
+
* For collecting and submitting user feedback with context enrichment
|
|
98
|
+
*/
|
|
99
|
+
export declare function getFeedbackSkillTemplate(): SkillTemplate;
|
|
95
100
|
//# sourceMappingURL=skill-templates.d.ts.map
|
|
@@ -17,6 +17,8 @@ export function getExploreSkillTemplate() {
|
|
|
17
17
|
description: 'Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.',
|
|
18
18
|
instructions: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
|
19
19
|
|
|
20
|
+
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first (e.g., start a change with \`/opsx:new\` or \`/opsx:ff\`). You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
|
|
21
|
+
|
|
20
22
|
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
|
21
23
|
|
|
22
24
|
---
|
|
@@ -24,6 +26,7 @@ export function getExploreSkillTemplate() {
|
|
|
24
26
|
## The Stance
|
|
25
27
|
|
|
26
28
|
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
|
|
29
|
+
- **Open threads, not interrogations** - Surface multiple interesting directions and let the user follow what resonates. Don't funnel them through a single path of questions.
|
|
27
30
|
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
|
|
28
31
|
- **Adaptive** - Follow interesting threads, pivot when new information emerges
|
|
29
32
|
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
|
|
@@ -283,6 +286,7 @@ But this summary is optional. Sometimes the thinking IS the value.
|
|
|
283
286
|
|
|
284
287
|
## Guardrails
|
|
285
288
|
|
|
289
|
+
- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not.
|
|
286
290
|
- **Don't fake understanding** - If something is unclear, dig deeper
|
|
287
291
|
- **Don't rush** - Discovery is thinking time, not task time
|
|
288
292
|
- **Don't force structure** - Let patterns emerge naturally
|
|
@@ -376,7 +380,7 @@ export function getContinueChangeSkillTemplate() {
|
|
|
376
380
|
description: 'Continue working on an OpenSpec change by creating the next artifact. Use when the user wants to progress their change, create the next artifact, or continue their workflow.',
|
|
377
381
|
instructions: `Continue working on a change by creating the next artifact.
|
|
378
382
|
|
|
379
|
-
**Input**: Optionally specify a change name. If omitted, MUST prompt for available changes.
|
|
383
|
+
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
380
384
|
|
|
381
385
|
**Steps**
|
|
382
386
|
|
|
@@ -489,19 +493,18 @@ export function getApplyChangeSkillTemplate() {
|
|
|
489
493
|
description: 'Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.',
|
|
490
494
|
instructions: `Implement tasks from an OpenSpec change.
|
|
491
495
|
|
|
492
|
-
**Input**: Optionally specify a change name. If omitted, MUST prompt for available changes.
|
|
496
|
+
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
493
497
|
|
|
494
498
|
**Steps**
|
|
495
499
|
|
|
496
|
-
1. **
|
|
500
|
+
1. **Select the change**
|
|
497
501
|
|
|
498
|
-
|
|
502
|
+
If a name is provided, use it. Otherwise:
|
|
503
|
+
- Infer from conversation context if the user mentioned a change
|
|
504
|
+
- Auto-select if only one active change exists
|
|
505
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
|
|
499
506
|
|
|
500
|
-
|
|
501
|
-
Include the schema used for each change if available.
|
|
502
|
-
Mark changes with incomplete tasks as "(In Progress)".
|
|
503
|
-
|
|
504
|
-
**IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
|
|
507
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:apply <other>\`).
|
|
505
508
|
|
|
506
509
|
2. **Check status to understand the schema**
|
|
507
510
|
\`\`\`bash
|
|
@@ -742,7 +745,7 @@ export function getSyncSpecsSkillTemplate() {
|
|
|
742
745
|
|
|
743
746
|
This is an **agent-driven** operation - you will read delta specs and directly edit main specs to apply the changes. This allows intelligent merging (e.g., adding a scenario without copying the entire requirement).
|
|
744
747
|
|
|
745
|
-
**Input**: Optionally specify a change name. If omitted, MUST prompt for available changes.
|
|
748
|
+
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
746
749
|
|
|
747
750
|
**Steps**
|
|
748
751
|
|
|
@@ -879,6 +882,8 @@ export function getOpsxExploreCommandTemplate() {
|
|
|
879
882
|
tags: ['workflow', 'explore', 'experimental', 'thinking'],
|
|
880
883
|
content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
|
881
884
|
|
|
885
|
+
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first (e.g., start a change with \`/opsx:new\` or \`/opsx:ff\`). You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
|
|
886
|
+
|
|
882
887
|
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
|
883
888
|
|
|
884
889
|
**Input**: The argument after \`/opsx:explore\` is whatever the user wants to think about. Could be:
|
|
@@ -893,6 +898,7 @@ export function getOpsxExploreCommandTemplate() {
|
|
|
893
898
|
## The Stance
|
|
894
899
|
|
|
895
900
|
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
|
|
901
|
+
- **Open threads, not interrogations** - Surface multiple interesting directions and let the user follow what resonates. Don't funnel them through a single path of questions.
|
|
896
902
|
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
|
|
897
903
|
- **Adaptive** - Follow interesting threads, pivot when new information emerges
|
|
898
904
|
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
|
|
@@ -1033,6 +1039,7 @@ When things crystallize, you might offer a summary - but it's optional. Sometime
|
|
|
1033
1039
|
|
|
1034
1040
|
## Guardrails
|
|
1035
1041
|
|
|
1042
|
+
- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not.
|
|
1036
1043
|
- **Don't fake understanding** - If something is unclear, dig deeper
|
|
1037
1044
|
- **Don't rush** - Discovery is thinking time, not task time
|
|
1038
1045
|
- **Don't force structure** - Let patterns emerge naturally
|
|
@@ -1127,7 +1134,7 @@ export function getOpsxContinueCommandTemplate() {
|
|
|
1127
1134
|
tags: ['workflow', 'artifacts', 'experimental'],
|
|
1128
1135
|
content: `Continue working on a change by creating the next artifact.
|
|
1129
1136
|
|
|
1130
|
-
**Input**: Optionally specify
|
|
1137
|
+
**Input**: Optionally specify a change name after \`/opsx:continue\` (e.g., \`/opsx:continue add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1131
1138
|
|
|
1132
1139
|
**Steps**
|
|
1133
1140
|
|
|
@@ -1241,19 +1248,18 @@ export function getOpsxApplyCommandTemplate() {
|
|
|
1241
1248
|
tags: ['workflow', 'artifacts', 'experimental'],
|
|
1242
1249
|
content: `Implement tasks from an OpenSpec change.
|
|
1243
1250
|
|
|
1244
|
-
**Input**: Optionally specify
|
|
1251
|
+
**Input**: Optionally specify a change name (e.g., \`/opsx:apply add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1245
1252
|
|
|
1246
1253
|
**Steps**
|
|
1247
1254
|
|
|
1248
|
-
1. **
|
|
1255
|
+
1. **Select the change**
|
|
1249
1256
|
|
|
1250
|
-
|
|
1257
|
+
If a name is provided, use it. Otherwise:
|
|
1258
|
+
- Infer from conversation context if the user mentioned a change
|
|
1259
|
+
- Auto-select if only one active change exists
|
|
1260
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
|
|
1251
1261
|
|
|
1252
|
-
|
|
1253
|
-
Include the schema used for each change if available.
|
|
1254
|
-
Mark changes with incomplete tasks as "(In Progress)".
|
|
1255
|
-
|
|
1256
|
-
**IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
|
|
1262
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:apply <other>\`).
|
|
1257
1263
|
|
|
1258
1264
|
2. **Check status to understand the schema**
|
|
1259
1265
|
\`\`\`bash
|
|
@@ -1493,7 +1499,7 @@ export function getArchiveChangeSkillTemplate() {
|
|
|
1493
1499
|
description: 'Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.',
|
|
1494
1500
|
instructions: `Archive a completed change in the experimental workflow.
|
|
1495
1501
|
|
|
1496
|
-
**Input**: Optionally specify a change name. If omitted, MUST prompt for available changes.
|
|
1502
|
+
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1497
1503
|
|
|
1498
1504
|
**Steps**
|
|
1499
1505
|
|
|
@@ -1532,38 +1538,20 @@ export function getArchiveChangeSkillTemplate() {
|
|
|
1532
1538
|
|
|
1533
1539
|
**If no tasks file exists:** Proceed without task-related warning.
|
|
1534
1540
|
|
|
1535
|
-
4. **
|
|
1541
|
+
4. **Assess delta spec sync state**
|
|
1536
1542
|
|
|
1537
|
-
Check
|
|
1543
|
+
Check for delta specs at \`openspec/changes/<name>/specs/\`. If none exist, proceed without sync prompt.
|
|
1538
1544
|
|
|
1539
|
-
**If delta specs exist
|
|
1545
|
+
**If delta specs exist:**
|
|
1546
|
+
- Compare each delta spec with its corresponding main spec at \`openspec/specs/<capability>/spec.md\`
|
|
1547
|
+
- Determine what changes would be applied (adds, modifications, removals, renames)
|
|
1548
|
+
- Show a combined summary before prompting
|
|
1540
1549
|
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1550
|
+
**Prompt options:**
|
|
1551
|
+
- If changes needed: "Sync now (recommended)", "Archive without syncing"
|
|
1552
|
+
- If already synced: "Archive now", "Sync anyway", "Cancel"
|
|
1544
1553
|
|
|
1545
|
-
|
|
1546
|
-
- If main spec doesn't exist → needs sync
|
|
1547
|
-
- If main spec exists, check if ADDED requirement names appear in it
|
|
1548
|
-
- If any ADDED requirements are missing from main spec → needs sync
|
|
1549
|
-
|
|
1550
|
-
c. **Report findings:**
|
|
1551
|
-
|
|
1552
|
-
**If sync needed:**
|
|
1553
|
-
\`\`\`
|
|
1554
|
-
⚠️ Delta specs may not be synced:
|
|
1555
|
-
- specs/auth/spec.md → Main spec missing requirement "Token Refresh"
|
|
1556
|
-
- specs/api/spec.md → Main spec doesn't exist yet
|
|
1557
|
-
|
|
1558
|
-
Would you like to sync now before archiving?
|
|
1559
|
-
\`\`\`
|
|
1560
|
-
- Use **AskUserQuestion tool** with options: "Sync now", "Archive without syncing"
|
|
1561
|
-
- If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill)
|
|
1562
|
-
|
|
1563
|
-
**If already synced (all requirements found):**
|
|
1564
|
-
- Proceed without prompting (specs appear to be in sync)
|
|
1565
|
-
|
|
1566
|
-
**If no delta specs exist:** Proceed without sync-related checks.
|
|
1554
|
+
If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of choice.
|
|
1567
1555
|
|
|
1568
1556
|
5. **Perform the archive**
|
|
1569
1557
|
|
|
@@ -1599,7 +1587,7 @@ export function getArchiveChangeSkillTemplate() {
|
|
|
1599
1587
|
**Change:** <change-name>
|
|
1600
1588
|
**Schema:** <schema-name>
|
|
1601
1589
|
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
|
1602
|
-
**Specs:** ✓ Synced to main specs (or "No delta specs" or "
|
|
1590
|
+
**Specs:** ✓ Synced to main specs (or "No delta specs" or "Sync skipped")
|
|
1603
1591
|
|
|
1604
1592
|
All artifacts complete. All tasks complete.
|
|
1605
1593
|
\`\`\`
|
|
@@ -1611,7 +1599,7 @@ All artifacts complete. All tasks complete.
|
|
|
1611
1599
|
- Preserve .openspec.yaml when moving to archive (it moves with the directory)
|
|
1612
1600
|
- Show clear summary of what happened
|
|
1613
1601
|
- If sync is requested, use openspec-sync-specs approach (agent-driven)
|
|
1614
|
-
-
|
|
1602
|
+
- If delta specs exist, always run the sync assessment and show the combined summary before prompting`
|
|
1615
1603
|
};
|
|
1616
1604
|
}
|
|
1617
1605
|
/**
|
|
@@ -1627,7 +1615,7 @@ export function getOpsxSyncCommandTemplate() {
|
|
|
1627
1615
|
|
|
1628
1616
|
This is an **agent-driven** operation - you will read delta specs and directly edit main specs to apply the changes. This allows intelligent merging (e.g., adding a scenario without copying the entire requirement).
|
|
1629
1617
|
|
|
1630
|
-
**Input**: Optionally specify
|
|
1618
|
+
**Input**: Optionally specify a change name after \`/opsx:sync\` (e.g., \`/opsx:sync add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1631
1619
|
|
|
1632
1620
|
**Steps**
|
|
1633
1621
|
|
|
@@ -1762,7 +1750,7 @@ export function getVerifyChangeSkillTemplate() {
|
|
|
1762
1750
|
description: 'Verify implementation matches change artifacts. Use when the user wants to validate that implementation is complete, correct, and coherent before archiving.',
|
|
1763
1751
|
instructions: `Verify that an implementation matches the change artifacts (specs, tasks, design).
|
|
1764
1752
|
|
|
1765
|
-
**Input**: Optionally specify a change name. If omitted, MUST prompt for available changes.
|
|
1753
|
+
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1766
1754
|
|
|
1767
1755
|
**Steps**
|
|
1768
1756
|
|
|
@@ -1930,7 +1918,7 @@ export function getOpsxArchiveCommandTemplate() {
|
|
|
1930
1918
|
tags: ['workflow', 'archive', 'experimental'],
|
|
1931
1919
|
content: `Archive a completed change in the experimental workflow.
|
|
1932
1920
|
|
|
1933
|
-
**Input**: Optionally specify
|
|
1921
|
+
**Input**: Optionally specify a change name after \`/opsx:archive\` (e.g., \`/opsx:archive add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
1934
1922
|
|
|
1935
1923
|
**Steps**
|
|
1936
1924
|
|
|
@@ -1969,38 +1957,20 @@ export function getOpsxArchiveCommandTemplate() {
|
|
|
1969
1957
|
|
|
1970
1958
|
**If no tasks file exists:** Proceed without task-related warning.
|
|
1971
1959
|
|
|
1972
|
-
4. **
|
|
1973
|
-
|
|
1974
|
-
Check if \`specs/\` directory exists in the change with spec files.
|
|
1975
|
-
|
|
1976
|
-
**If delta specs exist, perform a quick sync check:**
|
|
1960
|
+
4. **Assess delta spec sync state**
|
|
1977
1961
|
|
|
1978
|
-
|
|
1979
|
-
- Extract requirement names (lines matching \`### Requirement: <name>\`)
|
|
1980
|
-
- Note which sections exist (ADDED, MODIFIED, REMOVED)
|
|
1962
|
+
Check for delta specs at \`openspec/changes/<name>/specs/\`. If none exist, proceed without sync prompt.
|
|
1981
1963
|
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1964
|
+
**If delta specs exist:**
|
|
1965
|
+
- Compare each delta spec with its corresponding main spec at \`openspec/specs/<capability>/spec.md\`
|
|
1966
|
+
- Determine what changes would be applied (adds, modifications, removals, renames)
|
|
1967
|
+
- Show a combined summary before prompting
|
|
1986
1968
|
|
|
1987
|
-
|
|
1969
|
+
**Prompt options:**
|
|
1970
|
+
- If changes needed: "Sync now (recommended)", "Archive without syncing"
|
|
1971
|
+
- If already synced: "Archive now", "Sync anyway", "Cancel"
|
|
1988
1972
|
|
|
1989
|
-
|
|
1990
|
-
\`\`\`
|
|
1991
|
-
⚠️ Delta specs may not be synced:
|
|
1992
|
-
- specs/auth/spec.md → Main spec missing requirement "Token Refresh"
|
|
1993
|
-
- specs/api/spec.md → Main spec doesn't exist yet
|
|
1994
|
-
|
|
1995
|
-
Would you like to sync now before archiving?
|
|
1996
|
-
\`\`\`
|
|
1997
|
-
- Use **AskUserQuestion tool** with options: "Sync now", "Archive without syncing"
|
|
1998
|
-
- If user chooses sync, execute \`/opsx:sync\` logic
|
|
1999
|
-
|
|
2000
|
-
**If already synced (all requirements found):**
|
|
2001
|
-
- Proceed without prompting (specs appear to be in sync)
|
|
2002
|
-
|
|
2003
|
-
**If no delta specs exist:** Proceed without sync-related checks.
|
|
1973
|
+
If user chooses sync, execute \`/opsx:sync\` logic. Proceed to archive regardless of choice.
|
|
2004
1974
|
|
|
2005
1975
|
5. **Perform the archive**
|
|
2006
1976
|
|
|
@@ -2025,7 +1995,7 @@ export function getOpsxArchiveCommandTemplate() {
|
|
|
2025
1995
|
- Change name
|
|
2026
1996
|
- Schema that was used
|
|
2027
1997
|
- Archive location
|
|
2028
|
-
- Spec sync status (synced /
|
|
1998
|
+
- Spec sync status (synced / sync skipped / no delta specs)
|
|
2029
1999
|
- Note about any warnings (incomplete artifacts/tasks)
|
|
2030
2000
|
|
|
2031
2001
|
**Output On Success**
|
|
@@ -2062,12 +2032,12 @@ All artifacts complete. All tasks complete.
|
|
|
2062
2032
|
**Change:** <change-name>
|
|
2063
2033
|
**Schema:** <schema-name>
|
|
2064
2034
|
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
|
2065
|
-
**Specs:**
|
|
2035
|
+
**Specs:** Sync skipped (user chose to skip)
|
|
2066
2036
|
|
|
2067
2037
|
**Warnings:**
|
|
2068
2038
|
- Archived with 2 incomplete artifacts
|
|
2069
2039
|
- Archived with 3 incomplete tasks
|
|
2070
|
-
- Delta
|
|
2040
|
+
- Delta spec sync was skipped (user chose to skip)
|
|
2071
2041
|
|
|
2072
2042
|
Review the archive if this was not intentional.
|
|
2073
2043
|
\`\`\`
|
|
@@ -2093,9 +2063,9 @@ Target archive directory already exists.
|
|
|
2093
2063
|
- Use artifact graph (openspec status --json) for completion checking
|
|
2094
2064
|
- Don't block archive on warnings - just inform and confirm
|
|
2095
2065
|
- Preserve .openspec.yaml when moving to archive (it moves with the directory)
|
|
2096
|
-
- Quick sync check: look for requirement names in delta specs, verify they exist in main specs
|
|
2097
2066
|
- Show clear summary of what happened
|
|
2098
|
-
- If sync is requested, use /opsx:sync approach (agent-driven)
|
|
2067
|
+
- If sync is requested, use /opsx:sync approach (agent-driven)
|
|
2068
|
+
- If delta specs exist, always run the sync assessment and show the combined summary before prompting`
|
|
2099
2069
|
};
|
|
2100
2070
|
}
|
|
2101
2071
|
/**
|
|
@@ -2109,7 +2079,7 @@ export function getOpsxVerifyCommandTemplate() {
|
|
|
2109
2079
|
tags: ['workflow', 'verify', 'experimental'],
|
|
2110
2080
|
content: `Verify that an implementation matches the change artifacts (specs, tasks, design).
|
|
2111
2081
|
|
|
2112
|
-
**Input**: Optionally specify
|
|
2082
|
+
**Input**: Optionally specify a change name after \`/opsx:verify\` (e.g., \`/opsx:verify add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
2113
2083
|
|
|
2114
2084
|
**Steps**
|
|
2115
2085
|
|
|
@@ -2266,4 +2236,112 @@ Use clear markdown with:
|
|
|
2266
2236
|
- No vague suggestions like "consider reviewing"`
|
|
2267
2237
|
};
|
|
2268
2238
|
}
|
|
2239
|
+
/**
|
|
2240
|
+
* Template for feedback skill
|
|
2241
|
+
* For collecting and submitting user feedback with context enrichment
|
|
2242
|
+
*/
|
|
2243
|
+
export function getFeedbackSkillTemplate() {
|
|
2244
|
+
return {
|
|
2245
|
+
name: 'feedback',
|
|
2246
|
+
description: 'Collect and submit user feedback about OpenSpec with context enrichment and anonymization.',
|
|
2247
|
+
instructions: `Help the user submit feedback about OpenSpec.
|
|
2248
|
+
|
|
2249
|
+
**Goal**: Guide the user through collecting, enriching, and submitting feedback while ensuring privacy through anonymization.
|
|
2250
|
+
|
|
2251
|
+
**Process**
|
|
2252
|
+
|
|
2253
|
+
1. **Gather context from the conversation**
|
|
2254
|
+
- Review recent conversation history for context
|
|
2255
|
+
- Identify what task was being performed
|
|
2256
|
+
- Note what worked well or poorly
|
|
2257
|
+
- Capture specific friction points or praise
|
|
2258
|
+
|
|
2259
|
+
2. **Draft enriched feedback**
|
|
2260
|
+
- Create a clear, descriptive title (single sentence, no "Feedback:" prefix needed)
|
|
2261
|
+
- Write a body that includes:
|
|
2262
|
+
- What the user was trying to do
|
|
2263
|
+
- What happened (good or bad)
|
|
2264
|
+
- Relevant context from the conversation
|
|
2265
|
+
- Any specific suggestions or requests
|
|
2266
|
+
|
|
2267
|
+
3. **Anonymize sensitive information**
|
|
2268
|
+
- Replace file paths with \`<path>\` or generic descriptions
|
|
2269
|
+
- Replace API keys, tokens, secrets with \`<redacted>\`
|
|
2270
|
+
- Replace company/organization names with \`<company>\`
|
|
2271
|
+
- Replace personal names with \`<user>\`
|
|
2272
|
+
- Replace specific URLs with \`<url>\` unless public/relevant
|
|
2273
|
+
- Keep technical details that help understand the issue
|
|
2274
|
+
|
|
2275
|
+
4. **Present draft for approval**
|
|
2276
|
+
- Show the complete draft to the user
|
|
2277
|
+
- Display both title and body clearly
|
|
2278
|
+
- Ask for explicit approval before submitting
|
|
2279
|
+
- Allow the user to request modifications
|
|
2280
|
+
|
|
2281
|
+
5. **Submit on confirmation**
|
|
2282
|
+
- Use the \`openspec feedback\` command to submit
|
|
2283
|
+
- Format: \`openspec feedback "title" --body "body content"\`
|
|
2284
|
+
- The command will automatically add metadata (version, platform, timestamp)
|
|
2285
|
+
|
|
2286
|
+
**Example Draft**
|
|
2287
|
+
|
|
2288
|
+
\`\`\`
|
|
2289
|
+
Title: Error handling in artifact workflow needs improvement
|
|
2290
|
+
|
|
2291
|
+
Body:
|
|
2292
|
+
I was working on creating a new change and encountered an issue with
|
|
2293
|
+
the artifact workflow. When I tried to continue after creating the
|
|
2294
|
+
proposal, the system didn't clearly indicate that I needed to complete
|
|
2295
|
+
the specs first.
|
|
2296
|
+
|
|
2297
|
+
Suggestion: Add clearer error messages that explain dependency chains
|
|
2298
|
+
in the artifact workflow. Something like "Cannot create design.md
|
|
2299
|
+
because specs are not complete (0/2 done)."
|
|
2300
|
+
|
|
2301
|
+
Context: Using the spec-driven schema with <path>/my-project
|
|
2302
|
+
\`\`\`
|
|
2303
|
+
|
|
2304
|
+
**Anonymization Examples**
|
|
2305
|
+
|
|
2306
|
+
Before:
|
|
2307
|
+
\`\`\`
|
|
2308
|
+
Working on /Users/john/mycompany/auth-service/src/oauth.ts
|
|
2309
|
+
Failed with API key: sk_live_abc123xyz
|
|
2310
|
+
Working at Acme Corp
|
|
2311
|
+
\`\`\`
|
|
2312
|
+
|
|
2313
|
+
After:
|
|
2314
|
+
\`\`\`
|
|
2315
|
+
Working on <path>/oauth.ts
|
|
2316
|
+
Failed with API key: <redacted>
|
|
2317
|
+
Working at <company>
|
|
2318
|
+
\`\`\`
|
|
2319
|
+
|
|
2320
|
+
**Guardrails**
|
|
2321
|
+
|
|
2322
|
+
- MUST show complete draft before submitting
|
|
2323
|
+
- MUST ask for explicit approval
|
|
2324
|
+
- MUST anonymize sensitive information
|
|
2325
|
+
- ALLOW user to modify draft before submitting
|
|
2326
|
+
- DO NOT submit without user confirmation
|
|
2327
|
+
- DO include relevant technical context
|
|
2328
|
+
- DO keep conversation-specific insights
|
|
2329
|
+
|
|
2330
|
+
**User Confirmation Required**
|
|
2331
|
+
|
|
2332
|
+
Always ask:
|
|
2333
|
+
\`\`\`
|
|
2334
|
+
Here's the feedback I've drafted:
|
|
2335
|
+
|
|
2336
|
+
Title: [title]
|
|
2337
|
+
|
|
2338
|
+
Body:
|
|
2339
|
+
[body]
|
|
2340
|
+
|
|
2341
|
+
Does this look good? I can modify it if you'd like, or submit it as-is.
|
|
2342
|
+
\`\`\`
|
|
2343
|
+
|
|
2344
|
+
Only proceed with submission after user confirms.`
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
2269
2347
|
//# sourceMappingURL=skill-templates.js.map
|