@thiagodiogo/pscode 1.0.1 → 2.0.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/bin/pscode.js CHANGED
File without changes
package/dist/cli/index.js CHANGED
@@ -253,7 +253,6 @@ program
253
253
  .command('complete [change-name]')
254
254
  .description('Complete a change and update main specs')
255
255
  .option('-y, --yes', 'Skip confirmation prompts')
256
- .option('--skip-specs', 'Skip spec update operations (useful for infrastructure, tooling, or doc-only changes)')
257
256
  .option('--no-validate', 'Skip validation (not recommended, requires confirmation)')
258
257
  .action(async (changeName, options) => {
259
258
  try {
@@ -1,7 +1,6 @@
1
1
  export declare class CompleteCommand {
2
2
  execute(changeName?: string, options?: {
3
3
  yes?: boolean;
4
- skipSpecs?: boolean;
5
4
  noValidate?: boolean;
6
5
  validate?: boolean;
7
6
  }): Promise<void>;
@@ -182,73 +182,49 @@ export class CompleteCommand {
182
182
  console.log(`Warning: ${incompleteTasks} incomplete task(s) found. Continuing due to --yes flag.`);
183
183
  }
184
184
  }
185
- // Handle spec updates unless skipSpecs flag is set
186
- if (options.skipSpecs) {
187
- console.log('Skipping spec updates (--skip-specs flag provided).');
188
- }
189
- else {
190
- // Find specs to update
191
- const specUpdates = await findSpecUpdates(changeDir, mainSpecsDir);
192
- if (specUpdates.length > 0) {
193
- console.log('\nSpecs to update:');
185
+ // Sync delta specs to main specs
186
+ const specUpdates = await findSpecUpdates(changeDir, mainSpecsDir);
187
+ if (specUpdates.length > 0) {
188
+ console.log('\nSincronizando specs...');
189
+ // Prepare all updates first (validation pass, no writes)
190
+ const prepared = [];
191
+ try {
194
192
  for (const update of specUpdates) {
195
- const status = update.exists ? 'update' : 'create';
196
- const capability = path.basename(path.dirname(update.target));
197
- console.log(` ${capability}: ${status}`);
193
+ const built = await buildUpdatedSpec(update, changeName);
194
+ prepared.push({ update, rebuilt: built.rebuilt, counts: built.counts });
198
195
  }
199
- let shouldUpdateSpecs = true;
200
- if (!options.yes) {
201
- const { confirm } = await import('@inquirer/prompts');
202
- shouldUpdateSpecs = await confirm({
203
- message: 'Proceed with spec updates?',
204
- default: true
205
- });
206
- if (!shouldUpdateSpecs) {
207
- console.log('Skipping spec updates. Proceeding with archive.');
208
- }
209
- }
210
- if (shouldUpdateSpecs) {
211
- // Prepare all updates first (validation pass, no writes)
212
- const prepared = [];
213
- try {
214
- for (const update of specUpdates) {
215
- const built = await buildUpdatedSpec(update, changeName);
216
- prepared.push({ update, rebuilt: built.rebuilt, counts: built.counts });
196
+ }
197
+ catch (err) {
198
+ console.log(String(err.message || err));
199
+ console.log('Aborted. No files were changed.');
200
+ return;
201
+ }
202
+ // All validations passed; pre-validate rebuilt full spec and then write files and display counts
203
+ let totals = { added: 0, modified: 0, removed: 0, renamed: 0 };
204
+ for (const p of prepared) {
205
+ const specName = path.basename(path.dirname(p.update.target));
206
+ if (!skipValidation) {
207
+ const report = await new Validator().validateSpecContent(specName, p.rebuilt);
208
+ if (!report.valid) {
209
+ console.log(chalk.red(`\nValidation errors in rebuilt spec for ${specName} (will not write changes):`));
210
+ for (const issue of report.issues) {
211
+ if (issue.level === 'ERROR')
212
+ console.log(chalk.red(` ✗ ${issue.message}`));
213
+ else if (issue.level === 'WARNING')
214
+ console.log(chalk.yellow(` ⚠ ${issue.message}`));
217
215
  }
218
- }
219
- catch (err) {
220
- console.log(String(err.message || err));
221
216
  console.log('Aborted. No files were changed.');
222
217
  return;
223
218
  }
224
- // All validations passed; pre-validate rebuilt full spec and then write files and display counts
225
- let totals = { added: 0, modified: 0, removed: 0, renamed: 0 };
226
- for (const p of prepared) {
227
- const specName = path.basename(path.dirname(p.update.target));
228
- if (!skipValidation) {
229
- const report = await new Validator().validateSpecContent(specName, p.rebuilt);
230
- if (!report.valid) {
231
- console.log(chalk.red(`\nValidation errors in rebuilt spec for ${specName} (will not write changes):`));
232
- for (const issue of report.issues) {
233
- if (issue.level === 'ERROR')
234
- console.log(chalk.red(` ✗ ${issue.message}`));
235
- else if (issue.level === 'WARNING')
236
- console.log(chalk.yellow(` ⚠ ${issue.message}`));
237
- }
238
- console.log('Aborted. No files were changed.');
239
- return;
240
- }
241
- }
242
- await writeUpdatedSpec(p.update, p.rebuilt, p.counts);
243
- totals.added += p.counts.added;
244
- totals.modified += p.counts.modified;
245
- totals.removed += p.counts.removed;
246
- totals.renamed += p.counts.renamed;
247
- }
248
- console.log(`Totals: + ${totals.added}, ~ ${totals.modified}, - ${totals.removed}, → ${totals.renamed}`);
249
- console.log('Specs updated successfully.');
250
219
  }
220
+ await writeUpdatedSpec(p.update, p.rebuilt, p.counts);
221
+ totals.added += p.counts.added;
222
+ totals.modified += p.counts.modified;
223
+ totals.removed += p.counts.removed;
224
+ totals.renamed += p.counts.renamed;
251
225
  }
226
+ console.log(`Totals: + ${totals.added}, ~ ${totals.modified}, - ${totals.removed}, → ${totals.renamed}`);
227
+ console.log('Specs updated successfully.');
252
228
  }
253
229
  // Create archive directory with date prefix
254
230
  const archiveName = `${this.getArchiveDate()}-${changeName}`;
@@ -139,10 +139,6 @@ export const COMMAND_REGISTRY = [
139
139
  short: 'y',
140
140
  description: 'Skip confirmation prompts',
141
141
  },
142
- {
143
- name: 'skip-specs',
144
- description: 'Skip spec update operations',
145
- },
146
142
  {
147
143
  name: 'no-validate',
148
144
  description: 'Skip validation (not recommended)',
package/dist/core/init.js CHANGED
@@ -42,7 +42,6 @@ const WORKFLOW_TO_SKILL_DIR = {
42
42
  'continue': 'pscode-continue-change',
43
43
  'apply': 'pscode-apply-change',
44
44
  'ff': 'pscode-ff-change',
45
- 'sync': 'pscode-sync-specs',
46
45
  'complete': 'pscode-archive-change',
47
46
  'bulk-archive': 'pscode-bulk-archive-change',
48
47
  'verify': 'pscode-verify-change',
@@ -13,7 +13,6 @@ export const WORKFLOW_TO_SKILL_DIR = {
13
13
  'continue': 'pscode-continue-change',
14
14
  'apply': 'pscode-apply-change',
15
15
  'ff': 'pscode-ff-change',
16
- 'sync': 'pscode-sync-specs',
17
16
  'complete': 'pscode-archive-change',
18
17
  'bulk-archive': 'pscode-bulk-archive-change',
19
18
  'verify': 'pscode-verify-change',
@@ -5,7 +5,7 @@
5
5
  * `pscode init --profile <name>` or `pscode config profile <name>`.
6
6
  * The workflow lists are fixed in code — users cannot customise them.
7
7
  */
8
- export declare const ALL_WORKFLOWS: readonly ["propose", "explore", "new", "continue", "apply", "ff", "sync", "complete", "bulk-archive", "verify", "onboard", "trello-setup", "draft", "rfc", "design", "tasks", "arch-check", "adr", "jira-sync", "dod"];
8
+ export declare const ALL_WORKFLOWS: readonly ["propose", "explore", "new", "continue", "apply", "ff", "complete", "bulk-archive", "verify", "onboard", "trello-setup", "draft", "rfc", "design", "tasks", "arch-check", "adr", "jira-sync", "dod"];
9
9
  export type WorkflowId = (typeof ALL_WORKFLOWS)[number];
10
10
  export interface ProfileDefinition {
11
11
  description: string;
@@ -13,8 +13,8 @@ export interface ProfileDefinition {
13
13
  }
14
14
  export declare const PROFILES: {
15
15
  readonly standard: {
16
- readonly description: "Padrão — propose, explore, apply, sync, complete";
17
- readonly workflows: readonly ["propose", "explore", "apply", "sync", "complete"];
16
+ readonly description: "Padrão — propose, explore, apply, complete";
17
+ readonly workflows: readonly ["propose", "explore", "apply", "complete"];
18
18
  };
19
19
  readonly dixi: {
20
20
  readonly description: "Dixi — RFC→Design→Tasks→Apply com guardrails para Java/Spring e React/Next.js";
@@ -12,7 +12,6 @@ export const ALL_WORKFLOWS = [
12
12
  'continue',
13
13
  'apply',
14
14
  'ff',
15
- 'sync',
16
15
  'complete',
17
16
  'bulk-archive',
18
17
  'verify',
@@ -29,8 +28,8 @@ export const ALL_WORKFLOWS = [
29
28
  ];
30
29
  export const PROFILES = {
31
30
  standard: {
32
- description: 'Padrão — propose, explore, apply, sync, complete',
33
- workflows: ['propose', 'explore', 'apply', 'sync', 'complete'],
31
+ description: 'Padrão — propose, explore, apply, complete',
32
+ workflows: ['propose', 'explore', 'apply', 'complete'],
34
33
  },
35
34
  dixi: {
36
35
  description: 'Dixi — RFC→Design→Tasks→Apply com guardrails para Java/Spring e React/Next.js',
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Shared utilities for generating skill and command files.
5
5
  */
6
- import { getExploreSkillTemplate, getNewChangeSkillTemplate, getContinueChangeSkillTemplate, getApplyChangeSkillTemplate, getFfChangeSkillTemplate, getSyncSpecsSkillTemplate, getCompleteChangeSkillTemplate, getBulkArchiveChangeSkillTemplate, getVerifyChangeSkillTemplate, getOnboardSkillTemplate, getProposeSkillTemplate, getTrelloSetupSkillTemplate, getTrelloDraftSkillTemplate, getPsExploreCommandTemplate, getPsNewCommandTemplate, getPsContinueCommandTemplate, getPsApplyCommandTemplate, getPsFfCommandTemplate, getPsSyncCommandTemplate, getPsCompleteCommandTemplate, getPsBulkArchiveCommandTemplate, getPsVerifyCommandTemplate, getPsOnboardCommandTemplate, getPsProposeCommandTemplate, getTrelloSetupCommandTemplate, getTrelloDraftCommandTemplate, } from '../templates/skill-templates.js';
6
+ import { getExploreSkillTemplate, getNewChangeSkillTemplate, getContinueChangeSkillTemplate, getApplyChangeSkillTemplate, getFfChangeSkillTemplate, getCompleteChangeSkillTemplate, getBulkArchiveChangeSkillTemplate, getVerifyChangeSkillTemplate, getOnboardSkillTemplate, getProposeSkillTemplate, getTrelloSetupSkillTemplate, getTrelloDraftSkillTemplate, getPsExploreCommandTemplate, getPsNewCommandTemplate, getPsContinueCommandTemplate, getPsApplyCommandTemplate, getPsFfCommandTemplate, getPsCompleteCommandTemplate, getPsBulkArchiveCommandTemplate, getPsVerifyCommandTemplate, getPsOnboardCommandTemplate, getPsProposeCommandTemplate, getTrelloSetupCommandTemplate, getTrelloDraftCommandTemplate, } from '../templates/skill-templates.js';
7
7
  /**
8
8
  * Gets skill templates with their directory names, optionally filtered by workflow IDs.
9
9
  *
@@ -16,7 +16,6 @@ export function getSkillTemplates(workflowFilter) {
16
16
  { template: getContinueChangeSkillTemplate(), dirName: 'pscode-continue-change', workflowId: 'continue' },
17
17
  { template: getApplyChangeSkillTemplate(), dirName: 'pscode-apply-change', workflowId: 'apply' },
18
18
  { template: getFfChangeSkillTemplate(), dirName: 'pscode-ff-change', workflowId: 'ff' },
19
- { template: getSyncSpecsSkillTemplate(), dirName: 'pscode-sync-specs', workflowId: 'sync' },
20
19
  { template: getCompleteChangeSkillTemplate(), dirName: 'pscode-archive-change', workflowId: 'complete' },
21
20
  { template: getBulkArchiveChangeSkillTemplate(), dirName: 'pscode-bulk-archive-change', workflowId: 'bulk-archive' },
22
21
  { template: getVerifyChangeSkillTemplate(), dirName: 'pscode-verify-change', workflowId: 'verify' },
@@ -43,7 +42,6 @@ export function getCommandTemplates(workflowFilter) {
43
42
  { template: getPsContinueCommandTemplate(), id: 'continue' },
44
43
  { template: getPsApplyCommandTemplate(), id: 'apply' },
45
44
  { template: getPsFfCommandTemplate(), id: 'ff' },
46
- { template: getPsSyncCommandTemplate(), id: 'sync' },
47
45
  { template: getPsCompleteCommandTemplate(), id: 'complete' },
48
46
  { template: getPsBulkArchiveCommandTemplate(), id: 'bulk-archive' },
49
47
  { template: getPsVerifyCommandTemplate(), id: 'verify' },
@@ -6,12 +6,12 @@
6
6
  /**
7
7
  * Names of skill directories created by pscode init.
8
8
  */
9
- export declare const SKILL_NAMES: readonly ["pscode-explore", "pscode-new-change", "pscode-continue-change", "pscode-apply-change", "pscode-ff-change", "pscode-sync-specs", "pscode-archive-change", "pscode-bulk-archive-change", "pscode-verify-change", "pscode-onboard", "pscode-propose"];
9
+ export declare const SKILL_NAMES: readonly ["pscode-explore", "pscode-new-change", "pscode-continue-change", "pscode-apply-change", "pscode-ff-change", "pscode-archive-change", "pscode-bulk-archive-change", "pscode-verify-change", "pscode-onboard", "pscode-propose"];
10
10
  export type SkillName = (typeof SKILL_NAMES)[number];
11
11
  /**
12
12
  * IDs of command templates created by pscode init.
13
13
  */
14
- export declare const COMMAND_IDS: readonly ["explore", "new", "continue", "apply", "ff", "sync", "complete", "bulk-archive", "verify", "onboard", "propose"];
14
+ export declare const COMMAND_IDS: readonly ["explore", "new", "continue", "apply", "ff", "complete", "bulk-archive", "verify", "onboard", "propose"];
15
15
  export type CommandId = (typeof COMMAND_IDS)[number];
16
16
  /**
17
17
  * Status of skill configuration for a tool.
@@ -15,7 +15,6 @@ export const SKILL_NAMES = [
15
15
  'pscode-continue-change',
16
16
  'pscode-apply-change',
17
17
  'pscode-ff-change',
18
- 'pscode-sync-specs',
19
18
  'pscode-archive-change',
20
19
  'pscode-bulk-archive-change',
21
20
  'pscode-verify-change',
@@ -31,7 +30,6 @@ export const COMMAND_IDS = [
31
30
  'continue',
32
31
  'apply',
33
32
  'ff',
34
- 'sync',
35
33
  'complete',
36
34
  'bulk-archive',
37
35
  'verify',
@@ -9,7 +9,6 @@ export { getNewChangeSkillTemplate, getPsNewCommandTemplate } from './workflows/
9
9
  export { getContinueChangeSkillTemplate, getPsContinueCommandTemplate } from './workflows/continue-change.js';
10
10
  export { getApplyChangeSkillTemplate, getPsApplyCommandTemplate } from './workflows/apply-change.js';
11
11
  export { getFfChangeSkillTemplate, getPsFfCommandTemplate } from './workflows/ff-change.js';
12
- export { getSyncSpecsSkillTemplate, getPsSyncCommandTemplate } from './workflows/sync-specs.js';
13
12
  export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/archive-change.js';
14
13
  export { getBulkArchiveChangeSkillTemplate, getPsBulkArchiveCommandTemplate } from './workflows/bulk-archive-change.js';
15
14
  export { getVerifyChangeSkillTemplate, getPsVerifyCommandTemplate } from './workflows/verify-change.js';
@@ -8,7 +8,6 @@ export { getNewChangeSkillTemplate, getPsNewCommandTemplate } from './workflows/
8
8
  export { getContinueChangeSkillTemplate, getPsContinueCommandTemplate } from './workflows/continue-change.js';
9
9
  export { getApplyChangeSkillTemplate, getPsApplyCommandTemplate } from './workflows/apply-change.js';
10
10
  export { getFfChangeSkillTemplate, getPsFfCommandTemplate } from './workflows/ff-change.js';
11
- export { getSyncSpecsSkillTemplate, getPsSyncCommandTemplate } from './workflows/sync-specs.js';
12
11
  export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/archive-change.js';
13
12
  export { getBulkArchiveChangeSkillTemplate, getPsBulkArchiveCommandTemplate } from './workflows/bulk-archive-change.js';
14
13
  export { getVerifyChangeSkillTemplate, getPsVerifyCommandTemplate } from './workflows/verify-change.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thiagodiogo/pscode",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "AI-native system for spec-driven development",
5
5
  "keywords": [
6
6
  "pscode",
@@ -39,24 +39,6 @@
39
39
  "!dist/**/__tests__",
40
40
  "!dist/**/*.map"
41
41
  ],
42
- "scripts": {
43
- "lint": "eslint src/",
44
- "build": "node build.js",
45
- "dev": "tsc --watch",
46
- "dev:cli": "pnpm build && node bin/pscode.js",
47
- "test": "vitest run",
48
- "test:watch": "vitest",
49
- "test:ui": "vitest --ui",
50
- "test:coverage": "vitest --coverage",
51
- "test:postinstall": "node scripts/postinstall.js",
52
- "prepare": "pnpm run build",
53
- "prepublishOnly": "pnpm run build",
54
- "postinstall": "node scripts/postinstall.js",
55
- "check:pack-version": "node scripts/pack-version-check.mjs",
56
- "release": "pnpm run release:ci",
57
- "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
58
- "changeset": "changeset"
59
- },
60
42
  "engines": {
61
43
  "node": ">=20.19.0"
62
44
  },
@@ -81,5 +63,21 @@
81
63
  "posthog-node": "^5.20.0",
82
64
  "yaml": "^2.8.2",
83
65
  "zod": "^4.0.17"
66
+ },
67
+ "scripts": {
68
+ "lint": "eslint src/",
69
+ "build": "node build.js",
70
+ "dev": "tsc --watch",
71
+ "dev:cli": "pnpm build && node bin/pscode.js",
72
+ "test": "vitest run",
73
+ "test:watch": "vitest",
74
+ "test:ui": "vitest --ui",
75
+ "test:coverage": "vitest --coverage",
76
+ "test:postinstall": "node scripts/postinstall.js",
77
+ "postinstall": "node scripts/postinstall.js",
78
+ "check:pack-version": "node scripts/pack-version-check.mjs",
79
+ "release": "pnpm run release:ci",
80
+ "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
81
+ "changeset": "changeset"
84
82
  }
85
- }
83
+ }
@@ -1,10 +0,0 @@
1
- /**
2
- * Skill Template Workflow Modules
3
- *
4
- * This file is generated by splitting the legacy monolithic
5
- * templates file into workflow-focused modules.
6
- */
7
- import type { SkillTemplate, CommandTemplate } from '../types.js';
8
- export declare function getSyncSpecsSkillTemplate(): SkillTemplate;
9
- export declare function getPsSyncCommandTemplate(): CommandTemplate;
10
- //# sourceMappingURL=sync-specs.d.ts.map
@@ -1,290 +0,0 @@
1
- export function getSyncSpecsSkillTemplate() {
2
- return {
3
- name: 'pscode-sync-specs',
4
- description: 'Sync delta specs from a change to main specs. Use when the user wants to update main specs with changes from a delta spec, without archiving the change.',
5
- instructions: `Sync delta specs from a change to main specs.
6
-
7
- 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).
8
-
9
- **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.
10
-
11
- **Steps**
12
-
13
- 1. **If no change name provided, prompt for selection**
14
-
15
- Run \`pscode list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
16
-
17
- Show changes that have delta specs (under \`specs/\` directory).
18
-
19
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
20
-
21
- 2. **Resolve change context**
22
-
23
- Run:
24
- \`\`\`bash
25
- pscode status --change "<name>" --json
26
- \`\`\`
27
-
28
- If status reports \`actionContext.mode: "workspace-planning"\`, explain that workspace spec sync is not supported in this slice and STOP. Do not fall back to repo-local paths or edit linked repos.
29
-
30
- 3. **Find delta specs**
31
-
32
- Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the list of delta spec files.
33
-
34
- Each delta spec file contains sections like:
35
- - \`## ADDED Requirements\` - New requirements to add
36
- - \`## MODIFIED Requirements\` - Changes to existing requirements
37
- - \`## REMOVED Requirements\` - Requirements to remove
38
- - \`## RENAMED Requirements\` - Requirements to rename (FROM:/TO: format)
39
-
40
- If no delta specs found, inform user and stop.
41
-
42
- 4. **For each delta spec, apply changes to main specs**
43
-
44
- For each repo-local capability delta spec path returned by the CLI:
45
-
46
- a. **Read the delta spec** to understand the intended changes
47
-
48
- b. **Read the main spec** at \`pscode/specs/<capability>/spec.md\` (may not exist yet)
49
-
50
- c. **Apply changes intelligently**:
51
-
52
- **ADDED Requirements:**
53
- - If requirement doesn't exist in main spec → add it
54
- - If requirement already exists → update it to match (treat as implicit MODIFIED)
55
-
56
- **MODIFIED Requirements:**
57
- - Find the requirement in main spec
58
- - Apply the changes - this can be:
59
- - Adding new scenarios (don't need to copy existing ones)
60
- - Modifying existing scenarios
61
- - Changing the requirement description
62
- - Preserve scenarios/content not mentioned in the delta
63
-
64
- **REMOVED Requirements:**
65
- - Remove the entire requirement block from main spec
66
-
67
- **RENAMED Requirements:**
68
- - Find the FROM requirement, rename to TO
69
-
70
- d. **Create new main spec** if capability doesn't exist yet:
71
- - Create \`pscode/specs/<capability>/spec.md\`
72
- - Add Purpose section (can be brief, mark as TBD)
73
- - Add Requirements section with the ADDED requirements
74
-
75
- 5. **Show summary**
76
-
77
- After applying all changes, summarize:
78
- - Which capabilities were updated
79
- - What changes were made (requirements added/modified/removed/renamed)
80
-
81
- **Delta Spec Format Reference**
82
-
83
- \`\`\`markdown
84
- ## ADDED Requirements
85
-
86
- ### Requirement: New Feature
87
- The system SHALL do something new.
88
-
89
- #### Scenario: Basic case
90
- - **WHEN** user does X
91
- - **THEN** system does Y
92
-
93
- ## MODIFIED Requirements
94
-
95
- ### Requirement: Existing Feature
96
- #### Scenario: New scenario to add
97
- - **WHEN** user does A
98
- - **THEN** system does B
99
-
100
- ## REMOVED Requirements
101
-
102
- ### Requirement: Deprecated Feature
103
-
104
- ## RENAMED Requirements
105
-
106
- - FROM: \`### Requirement: Old Name\`
107
- - TO: \`### Requirement: New Name\`
108
- \`\`\`
109
-
110
- **Key Principle: Intelligent Merging**
111
-
112
- Unlike programmatic merging, you can apply **partial updates**:
113
- - To add a scenario, just include that scenario under MODIFIED - don't copy existing scenarios
114
- - The delta represents *intent*, not a wholesale replacement
115
- - Use your judgment to merge changes sensibly
116
-
117
- **Output On Success**
118
-
119
- \`\`\`
120
- ## Specs Synced: <change-name>
121
-
122
- Updated main specs:
123
-
124
- **<capability-1>**:
125
- - Added requirement: "New Feature"
126
- - Modified requirement: "Existing Feature" (added 1 scenario)
127
-
128
- **<capability-2>**:
129
- - Created new spec file
130
- - Added requirement: "Another Feature"
131
-
132
- Main specs are now updated. The change remains active - archive when implementation is complete.
133
- \`\`\`
134
-
135
- **Guardrails**
136
- - Read both delta and main specs before making changes
137
- - Preserve existing content not mentioned in delta
138
- - If something is unclear, ask for clarification
139
- - Show what you're changing as you go
140
- - The operation should be idempotent - running twice should give same result`,
141
- license: 'MIT',
142
- compatibility: 'Requires pscode CLI.',
143
- metadata: { author: 'pscode', version: '1.0' },
144
- };
145
- }
146
- export function getPsSyncCommandTemplate() {
147
- return {
148
- name: 'PS: Sync',
149
- description: 'Sync delta specs from a change to main specs',
150
- category: 'Workflow',
151
- tags: ['workflow', 'specs', 'experimental'],
152
- content: `Sync delta specs from a change to main specs.
153
-
154
- 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).
155
-
156
- **Input**: Optionally specify a change name after \`/ps:sync\` (e.g., \`/ps:sync add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
157
-
158
- **Steps**
159
-
160
- 1. **If no change name provided, prompt for selection**
161
-
162
- Run \`pscode list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
163
-
164
- Show changes that have delta specs (under \`specs/\` directory).
165
-
166
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
167
-
168
- 2. **Resolve change context**
169
-
170
- Run:
171
- \`\`\`bash
172
- pscode status --change "<name>" --json
173
- \`\`\`
174
-
175
- If status reports \`actionContext.mode: "workspace-planning"\`, explain that workspace spec sync is not supported in this slice and STOP. Do not fall back to repo-local paths or edit linked repos.
176
-
177
- 3. **Find delta specs**
178
-
179
- Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the list of delta spec files.
180
-
181
- Each delta spec file contains sections like:
182
- - \`## ADDED Requirements\` - New requirements to add
183
- - \`## MODIFIED Requirements\` - Changes to existing requirements
184
- - \`## REMOVED Requirements\` - Requirements to remove
185
- - \`## RENAMED Requirements\` - Requirements to rename (FROM:/TO: format)
186
-
187
- If no delta specs found, inform user and stop.
188
-
189
- 4. **For each delta spec, apply changes to main specs**
190
-
191
- For each repo-local capability delta spec path returned by the CLI:
192
-
193
- a. **Read the delta spec** to understand the intended changes
194
-
195
- b. **Read the main spec** at \`pscode/specs/<capability>/spec.md\` (may not exist yet)
196
-
197
- c. **Apply changes intelligently**:
198
-
199
- **ADDED Requirements:**
200
- - If requirement doesn't exist in main spec → add it
201
- - If requirement already exists → update it to match (treat as implicit MODIFIED)
202
-
203
- **MODIFIED Requirements:**
204
- - Find the requirement in main spec
205
- - Apply the changes - this can be:
206
- - Adding new scenarios (don't need to copy existing ones)
207
- - Modifying existing scenarios
208
- - Changing the requirement description
209
- - Preserve scenarios/content not mentioned in the delta
210
-
211
- **REMOVED Requirements:**
212
- - Remove the entire requirement block from main spec
213
-
214
- **RENAMED Requirements:**
215
- - Find the FROM requirement, rename to TO
216
-
217
- d. **Create new main spec** if capability doesn't exist yet:
218
- - Create \`pscode/specs/<capability>/spec.md\`
219
- - Add Purpose section (can be brief, mark as TBD)
220
- - Add Requirements section with the ADDED requirements
221
-
222
- 5. **Show summary**
223
-
224
- After applying all changes, summarize:
225
- - Which capabilities were updated
226
- - What changes were made (requirements added/modified/removed/renamed)
227
-
228
- **Delta Spec Format Reference**
229
-
230
- \`\`\`markdown
231
- ## ADDED Requirements
232
-
233
- ### Requirement: New Feature
234
- The system SHALL do something new.
235
-
236
- #### Scenario: Basic case
237
- - **WHEN** user does X
238
- - **THEN** system does Y
239
-
240
- ## MODIFIED Requirements
241
-
242
- ### Requirement: Existing Feature
243
- #### Scenario: New scenario to add
244
- - **WHEN** user does A
245
- - **THEN** system does B
246
-
247
- ## REMOVED Requirements
248
-
249
- ### Requirement: Deprecated Feature
250
-
251
- ## RENAMED Requirements
252
-
253
- - FROM: \`### Requirement: Old Name\`
254
- - TO: \`### Requirement: New Name\`
255
- \`\`\`
256
-
257
- **Key Principle: Intelligent Merging**
258
-
259
- Unlike programmatic merging, you can apply **partial updates**:
260
- - To add a scenario, just include that scenario under MODIFIED - don't copy existing scenarios
261
- - The delta represents *intent*, not a wholesale replacement
262
- - Use your judgment to merge changes sensibly
263
-
264
- **Output On Success**
265
-
266
- \`\`\`
267
- ## Specs Synced: <change-name>
268
-
269
- Updated main specs:
270
-
271
- **<capability-1>**:
272
- - Added requirement: "New Feature"
273
- - Modified requirement: "Existing Feature" (added 1 scenario)
274
-
275
- **<capability-2>**:
276
- - Created new spec file
277
- - Added requirement: "Another Feature"
278
-
279
- Main specs are now updated. The change remains active - archive when implementation is complete.
280
- \`\`\`
281
-
282
- **Guardrails**
283
- - Read both delta and main specs before making changes
284
- - Preserve existing content not mentioned in delta
285
- - If something is unclear, ask for clarification
286
- - Show what you're changing as you go
287
- - The operation should be idempotent - running twice should give same result`
288
- };
289
- }
290
- //# sourceMappingURL=sync-specs.js.map