synarcx 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +240 -34
  2. package/dist/commands/config.js +7 -6
  3. package/dist/core/command-generation/adapters/bob.js +7 -20
  4. package/dist/core/command-generation/adapters/claude.js +9 -29
  5. package/dist/core/command-generation/adapters/cursor.js +9 -22
  6. package/dist/core/command-generation/adapters/pi.js +6 -19
  7. package/dist/core/command-generation/adapters/windsurf.js +9 -29
  8. package/dist/core/command-generation/yaml-utils.d.ts +3 -0
  9. package/dist/core/command-generation/yaml-utils.js +12 -0
  10. package/dist/core/completions/installers/bash-installer.d.ts +1 -0
  11. package/dist/core/completions/installers/bash-installer.js +14 -3
  12. package/dist/core/completions/installers/powershell-installer.d.ts +1 -0
  13. package/dist/core/completions/installers/powershell-installer.js +18 -10
  14. package/dist/core/config.js +0 -3
  15. package/dist/core/index.js +1 -1
  16. package/dist/core/init.d.ts +0 -2
  17. package/dist/core/init.js +27 -75
  18. package/dist/core/migration.js +1 -2
  19. package/dist/core/profile-sync-drift.d.ts +0 -7
  20. package/dist/core/profile-sync-drift.js +2 -15
  21. package/dist/core/profiles.d.ts +0 -11
  22. package/dist/core/profiles.js +1 -18
  23. package/dist/core/shared/artifact-cleanup.d.ts +5 -0
  24. package/dist/core/shared/artifact-cleanup.js +89 -0
  25. package/dist/core/shared/skill-generation.js +5 -1
  26. package/dist/core/shared/tool-detection.d.ts +4 -10
  27. package/dist/core/shared/tool-detection.js +3 -27
  28. package/dist/core/shared/workflow-registry.d.ts +40 -0
  29. package/dist/core/shared/workflow-registry.js +19 -0
  30. package/dist/core/templates/skill-templates.d.ts +2 -0
  31. package/dist/core/templates/skill-templates.js +2 -0
  32. package/dist/core/templates/types.d.ts +7 -0
  33. package/dist/core/templates/types.js +9 -1
  34. package/dist/core/templates/workflows/analyze.js +84 -84
  35. package/dist/core/templates/workflows/apply-change.js +291 -291
  36. package/dist/core/templates/workflows/archive-change.js +254 -254
  37. package/dist/core/templates/workflows/clarify.js +91 -91
  38. package/dist/core/templates/workflows/debug.js +104 -104
  39. package/dist/core/templates/workflows/explore.js +462 -462
  40. package/dist/core/templates/workflows/propose.js +199 -199
  41. package/dist/core/templates/workflows/quick.d.ts +4 -0
  42. package/dist/core/templates/workflows/quick.js +129 -0
  43. package/dist/core/templates/workflows/refactor.d.ts +4 -0
  44. package/dist/core/templates/workflows/refactor.js +126 -0
  45. package/dist/core/templates/workflows/sync.js +152 -95
  46. package/dist/core/update.d.ts +1 -21
  47. package/dist/core/update.js +18 -117
  48. package/dist/core/view.js +8 -8
  49. package/dist/core/workspace/open-surface.d.ts +2 -2
  50. package/dist/core/workspace/open-surface.js +13 -13
  51. package/package.json +84 -76
@@ -11,6 +11,10 @@ export class PowerShellInstaller {
11
11
  * Markers for PowerShell profile configuration management
12
12
  */
13
13
  PROFILE_MARKERS = {
14
+ start: '# SYNARCX:START',
15
+ end: '# SYNARCX:END',
16
+ };
17
+ LEGACY_MARKERS = {
14
18
  start: '# OPENSPEC:START',
15
19
  end: '# OPENSPEC:END',
16
20
  };
@@ -107,7 +111,7 @@ export class PowerShellInstaller {
107
111
  getInstallationPath() {
108
112
  const profilePath = this.getProfilePath();
109
113
  const profileDir = path.dirname(profilePath);
110
- return path.join(profileDir, 'OpenSpecCompletion.ps1');
114
+ return path.join(profileDir, 'SynArcXCompletion.ps1');
111
115
  }
112
116
  /**
113
117
  * Backup an existing completion file if it exists
@@ -182,15 +186,15 @@ export class PowerShellInstaller {
182
186
  if (profileContent.includes(scriptLine)) {
183
187
  continue; // Already configured, skip
184
188
  }
185
- // Add OpenSpec completion configuration with markers
186
- const openspecBlock = [
189
+ // Add synarcx completion configuration with markers
190
+ const synarcxBlock = [
187
191
  '',
188
- '# OPENSPEC:START - synarcx completion (managed block, do not edit manually)',
192
+ this.PROFILE_MARKERS.start + ' - synarcx completion (managed block, do not edit manually)',
189
193
  scriptLine,
190
- '# OPENSPEC:END',
194
+ this.PROFILE_MARKERS.end,
191
195
  '',
192
196
  ].join('\n');
193
- const newContent = profileContent + openspecBlock;
197
+ const newContent = profileContent + synarcxBlock;
194
198
  await this.writeProfileFile(profilePath, newContent, fileEncoding, fileBom);
195
199
  anyConfigured = true;
196
200
  }
@@ -229,12 +233,16 @@ export class PowerShellInstaller {
229
233
  console.warn(`Warning: Could not read ${profilePath}: ${err?.message ?? String(err)}`);
230
234
  continue;
231
235
  }
232
- // Remove OPENSPEC:START -> OPENSPEC:END block
233
- const startMarker = '# OPENSPEC:START';
234
- const endMarker = '# OPENSPEC:END';
236
+ // Determine which markers to use (check new first, fall back to legacy)
237
+ const startMarker = profileContent.includes(this.PROFILE_MARKERS.start)
238
+ ? this.PROFILE_MARKERS.start
239
+ : this.LEGACY_MARKERS.start;
240
+ const endMarker = profileContent.includes(this.PROFILE_MARKERS.end)
241
+ ? this.PROFILE_MARKERS.end
242
+ : this.LEGACY_MARKERS.end;
235
243
  const startIndex = profileContent.indexOf(startMarker);
236
244
  if (startIndex === -1) {
237
- continue; // No OpenSpec block found
245
+ continue; // No synarcx block found
238
246
  }
239
247
  const endIndex = profileContent.indexOf(endMarker, startIndex);
240
248
  if (endIndex === -1) {
@@ -11,7 +11,6 @@ export const AI_TOOLS = [
11
11
  { name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code', skillsDir: '.claude', hasCommands: true },
12
12
  { name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline' },
13
13
  { name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex' },
14
- { name: 'ForgeCode', value: 'forgecode', available: true, successLabel: 'ForgeCode', skillsDir: '.forge' },
15
14
  { name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code', skillsDir: '.codebuddy' },
16
15
  { name: 'Continue', value: 'continue', available: true, successLabel: 'Continue (VS Code / JetBrains / Cli)', skillsDir: '.continue' },
17
16
  { name: 'CoStrict', value: 'costrict', available: true, successLabel: 'CoStrict', skillsDir: '.cospec' },
@@ -23,7 +22,6 @@ export const AI_TOOLS = [
23
22
  { name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow' },
24
23
  { name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie' },
25
24
  { name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code', skillsDir: '.kilocode' },
26
- { name: 'Kimi CLI', value: 'kimi', available: true, successLabel: 'Kimi CLI', skillsDir: '.kimi' },
27
25
  { name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro' },
28
26
  { name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode', skillsDir: '.opencode', hasCommands: true },
29
27
  { name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi' },
@@ -31,7 +29,6 @@ export const AI_TOOLS = [
31
29
  { name: 'Lingma', value: 'lingma', available: true, successLabel: 'Lingma', skillsDir: '.lingma' },
32
30
  { name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code', skillsDir: '.qwen' },
33
31
  { name: 'RooCode', value: 'roocode', available: true, successLabel: 'RooCode', skillsDir: '.roo' },
34
- { name: 'Trae', value: 'trae', available: true, successLabel: 'Trae', skillsDir: '.trae' },
35
32
  { name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf', skillsDir: '.windsurf' },
36
33
  { name: 'AGENTS.md (works with Amp, VS Code, …)', value: 'agents', available: false, successLabel: 'your AGENTS.md-compatible assistant' }
37
34
  ];
@@ -1,4 +1,4 @@
1
- // Core OpenSpec logic will be implemented here
1
+ // Core synarcx logic will be implemented here
2
2
  export { GLOBAL_CONFIG_DIR_NAME, GLOBAL_CONFIG_FILE_NAME, GLOBAL_DATA_DIR_NAME, getGlobalConfigDir, getGlobalConfigPath, getGlobalConfig, saveGlobalConfig, getGlobalDataDir } from './global-config.js';
3
3
  export * from './workspace/index.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -30,8 +30,6 @@ export declare class InitCommand {
30
30
  private createConfig;
31
31
  private displaySuccessMessage;
32
32
  private startSpinner;
33
- private removeSkillDirs;
34
- private removeCommandFiles;
35
33
  }
36
34
  export {};
37
35
  //# sourceMappingURL=init.d.ts.map
package/dist/core/init.js CHANGED
@@ -19,29 +19,20 @@ import { generateCommands, CommandAdapterRegistry, } from './command-generation/
19
19
  import { detectLegacyArtifacts, cleanupLegacyArtifacts, formatCleanupSummary, formatDetectionSummary, } from './legacy-cleanup.js';
20
20
  import { getToolsWithSkillsDir, getToolStates, getSkillTemplates, getCommandContents, generateSkillContent, } from './shared/index.js';
21
21
  import { getGlobalConfig } from './global-config.js';
22
- import { getProfileWorkflows, ALL_WORKFLOWS } from './profiles.js';
22
+ import { getProfileWorkflows } from './profiles.js';
23
+ import { DEFAULT_SCHEMA } from './shared/workflow-registry.js';
24
+ import { removeSkillDirs, removeCommandFiles } from './shared/artifact-cleanup.js';
23
25
  import { getAvailableTools } from './available-tools.js';
24
26
  import { migrateIfNeeded } from './migration.js';
25
27
  const require = createRequire(import.meta.url);
26
- const { version: SYNC_VERSION } = require('../../package.json');
28
+ const { version: SYNARCX_VERSION } = require('../../package.json');
27
29
  // -----------------------------------------------------------------------------
28
30
  // Constants
29
31
  // -----------------------------------------------------------------------------
30
- const DEFAULT_SCHEMA = 'synarcx';
31
32
  const PROGRESS_SPINNER = {
32
33
  interval: 80,
33
34
  frames: ['░░░', '▒░░', '▒▒░', '▒▒▒', '▓▒▒', '▓▓▒', '▓▓▓', '▒▓▓', '░▒▓'],
34
35
  };
35
- const WORKFLOW_TO_SKILL_DIR = {
36
- 'explore': 'syn-explore',
37
- 'apply': 'syn-apply',
38
- 'archive': 'syn-archive',
39
- 'propose': 'syn-propose',
40
- 'sync': 'syn-sync',
41
- 'clarify': 'syn-clarify',
42
- 'analyze': 'syn-analyze',
43
- 'debug': 'syn-debug',
44
- };
45
36
  // -----------------------------------------------------------------------------
46
37
  // Init Command Class
47
38
  // -----------------------------------------------------------------------------
@@ -58,10 +49,10 @@ export class InitCommand {
58
49
  }
59
50
  async execute(targetPath) {
60
51
  const projectPath = path.resolve(targetPath);
61
- const openspecDir = SYNSPEC_DIR_NAME;
62
- const openspecPath = path.join(projectPath, openspecDir);
52
+ const synspecDir = SYNSPEC_DIR_NAME;
53
+ const synspecPath = path.join(projectPath, synspecDir);
63
54
  // Validation happens silently in the background
64
- const extendMode = await this.validate(projectPath, openspecPath);
55
+ const extendMode = await this.validate(projectPath, synspecPath);
65
56
  // Check for legacy artifacts and handle cleanup
66
57
  await this.handleLegacyCleanup(projectPath, extendMode);
67
58
  // Detect available tools in the project (task 7.1)
@@ -86,19 +77,19 @@ export class InitCommand {
86
77
  // Validate selected tools
87
78
  const validatedTools = this.validateTools(selectedToolIds, toolStates);
88
79
  // Create directory structure and config
89
- await this.createDirectoryStructure(openspecPath, extendMode);
80
+ await this.createDirectoryStructure(synspecPath, extendMode);
90
81
  // Generate skills and commands for each tool
91
82
  const results = await this.generateSkillsAndCommands(projectPath, validatedTools);
92
83
  // Create config.yaml if needed
93
- const configStatus = await this.createConfig(openspecPath, extendMode);
84
+ const configStatus = await this.createConfig(synspecPath, extendMode);
94
85
  // Display success message
95
86
  this.displaySuccessMessage(projectPath, validatedTools, results, configStatus);
96
87
  }
97
88
  // ═══════════════════════════════════════════════════════════
98
89
  // VALIDATION & SETUP
99
90
  // ═══════════════════════════════════════════════════════════
100
- async validate(projectPath, openspecPath) {
101
- const extendMode = await FileSystemUtils.directoryExists(openspecPath);
91
+ async validate(projectPath, synspecPath) {
92
+ const extendMode = await FileSystemUtils.directoryExists(synspecPath);
102
93
  // Check write permissions
103
94
  if (!(await FileSystemUtils.ensureWritePermissions(projectPath))) {
104
95
  throw new Error(`Insufficient permissions to write to ${projectPath}`);
@@ -137,7 +128,7 @@ export class InitCommand {
137
128
  const canPrompt = this.canPromptInteractively();
138
129
  if (this.force || !canPrompt) {
139
130
  // --force flag or non-interactive mode: proceed with cleanup automatically.
140
- // Legacy slash commands are 100% OpenSpec-managed, and config file cleanup
131
+ // Legacy slash commands are 100% synarcx-managed, and config file cleanup
141
132
  // only removes markers (never deletes files), so auto-cleanup is safe.
142
133
  await this.performLegacyCleanup(projectPath, detection);
143
134
  return;
@@ -314,14 +305,14 @@ export class InitCommand {
314
305
  // ═══════════════════════════════════════════════════════════
315
306
  // DIRECTORY STRUCTURE
316
307
  // ═══════════════════════════════════════════════════════════
317
- async createDirectoryStructure(openspecPath, extendMode) {
308
+ async createDirectoryStructure(synspecPath, extendMode) {
318
309
  if (extendMode) {
319
310
  // In extend mode, just ensure directories exist without spinner
320
311
  const directories = [
321
- openspecPath,
322
- path.join(openspecPath, 'specs'),
323
- path.join(openspecPath, 'changes'),
324
- path.join(openspecPath, 'changes', 'archive'),
312
+ synspecPath,
313
+ path.join(synspecPath, 'specs'),
314
+ path.join(synspecPath, 'changes'),
315
+ path.join(synspecPath, 'changes', 'archive'),
325
316
  ];
326
317
  for (const dir of directories) {
327
318
  await FileSystemUtils.createDirectory(dir);
@@ -330,10 +321,10 @@ export class InitCommand {
330
321
  }
331
322
  const spinner = this.startSpinner('Creating synarcx structure...');
332
323
  const directories = [
333
- openspecPath,
334
- path.join(openspecPath, 'specs'),
335
- path.join(openspecPath, 'changes'),
336
- path.join(openspecPath, 'changes', 'archive'),
324
+ synspecPath,
325
+ path.join(synspecPath, 'specs'),
326
+ path.join(synspecPath, 'changes'),
327
+ path.join(synspecPath, 'changes', 'archive'),
337
328
  ];
338
329
  for (const dir of directories) {
339
330
  await FileSystemUtils.createDirectory(dir);
@@ -381,14 +372,14 @@ export class InitCommand {
381
372
  // Generate SKILL.md content with YAML frontmatter including generatedBy
382
373
  // Use hyphen-based command references for tools where filename = command name
383
374
  const transformer = tool.value === 'pi' ? transformToHyphenCommands : undefined;
384
- const skillContent = generateSkillContent(template, SYNC_VERSION, transformer);
375
+ const skillContent = generateSkillContent(template, SYNARCX_VERSION, transformer);
385
376
  // Write the skill file
386
377
  await FileSystemUtils.writeFile(skillFile, skillContent);
387
378
  }
388
379
  }
389
380
  if (!generateSkillsForTool) {
390
381
  const skillsDir = path.join(projectPath, tool.skillsDir, 'skills');
391
- removedSkillCount += await this.removeSkillDirs(skillsDir);
382
+ removedSkillCount += await removeSkillDirs(skillsDir);
392
383
  }
393
384
  // Generate commands if delivery includes commands
394
385
  if (shouldGenerateCommands) {
@@ -405,7 +396,7 @@ export class InitCommand {
405
396
  }
406
397
  }
407
398
  if (!shouldGenerateCommands) {
408
- removedCommandCount += await this.removeCommandFiles(projectPath, tool.value);
399
+ removedCommandCount += await removeCommandFiles(projectPath, tool.value);
409
400
  }
410
401
  spinner.succeed(`Setup complete for ${tool.name}`);
411
402
  if (tool.wasConfigured) {
@@ -432,9 +423,9 @@ export class InitCommand {
432
423
  // ═══════════════════════════════════════════════════════════
433
424
  // CONFIG FILE
434
425
  // ═══════════════════════════════════════════════════════════
435
- async createConfig(openspecPath, extendMode) {
436
- const configPath = path.join(openspecPath, 'config.yaml');
437
- const configYmlPath = path.join(openspecPath, 'config.yml');
426
+ async createConfig(synspecPath, extendMode) {
427
+ const configPath = path.join(synspecPath, 'config.yaml');
428
+ const configYmlPath = path.join(synspecPath, 'config.yml');
438
429
  const configYamlExists = fs.existsSync(configPath);
439
430
  const configYmlExists = fs.existsSync(configYmlPath);
440
431
  if (configYamlExists || configYmlExists) {
@@ -542,44 +533,5 @@ export class InitCommand {
542
533
  spinner: PROGRESS_SPINNER,
543
534
  }).start();
544
535
  }
545
- async removeSkillDirs(skillsDir) {
546
- let removed = 0;
547
- for (const workflow of ALL_WORKFLOWS) {
548
- const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
549
- if (!dirName)
550
- continue;
551
- const skillDir = path.join(skillsDir, dirName);
552
- try {
553
- if (fs.existsSync(skillDir)) {
554
- await fs.promises.rm(skillDir, { recursive: true, force: true });
555
- removed++;
556
- }
557
- }
558
- catch {
559
- // Ignore errors
560
- }
561
- }
562
- return removed;
563
- }
564
- async removeCommandFiles(projectPath, toolId) {
565
- let removed = 0;
566
- const adapter = CommandAdapterRegistry.get(toolId);
567
- if (!adapter)
568
- return 0;
569
- for (const workflow of ALL_WORKFLOWS) {
570
- const cmdPath = adapter.getFilePath(workflow);
571
- const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
572
- try {
573
- if (fs.existsSync(fullPath)) {
574
- await fs.promises.unlink(fullPath);
575
- removed++;
576
- }
577
- }
578
- catch {
579
- // Ignore errors
580
- }
581
- }
582
- return removed;
583
- }
584
536
  }
585
537
  //# sourceMappingURL=init.js.map
@@ -6,8 +6,7 @@
6
6
  */
7
7
  import { getGlobalConfig, getGlobalConfigPath, saveGlobalConfig } from './global-config.js';
8
8
  import { CommandAdapterRegistry } from './command-generation/index.js';
9
- import { WORKFLOW_TO_SKILL_DIR } from './profile-sync-drift.js';
10
- import { ALL_WORKFLOWS } from './profiles.js';
9
+ import { ALL_WORKFLOWS, WORKFLOW_TO_SKILL_DIR } from './shared/workflow-registry.js';
11
10
  import path from 'path';
12
11
  import * as fs from 'fs';
13
12
  function scanInstalledWorkflowArtifacts(projectPath, tools) {
@@ -1,10 +1,4 @@
1
1
  import type { Delivery } from './global-config.js';
2
- import { ALL_WORKFLOWS } from './profiles.js';
3
- type WorkflowId = (typeof ALL_WORKFLOWS)[number];
4
- /**
5
- * Maps workflow IDs to their skill directory names.
6
- */
7
- export declare const WORKFLOW_TO_SKILL_DIR: Record<WorkflowId, string>;
8
2
  /**
9
3
  * Checks whether a tool has at least one generated synarcx command file.
10
4
  */
@@ -34,5 +28,4 @@ export declare function getToolsNeedingProfileSync(projectPath: string, desiredW
34
28
  * Detects whether the current project has any profile/delivery drift.
35
29
  */
36
30
  export declare function hasProjectConfigDrift(projectPath: string, desiredWorkflows: readonly string[], delivery: Delivery): boolean;
37
- export {};
38
31
  //# sourceMappingURL=profile-sync-drift.d.ts.map
@@ -1,22 +1,9 @@
1
1
  import path from 'path';
2
2
  import * as fs from 'fs';
3
3
  import { AI_TOOLS } from './config.js';
4
- import { ALL_WORKFLOWS } from './profiles.js';
4
+ import { ALL_WORKFLOWS, WORKFLOW_TO_SKILL_DIR, COMMAND_IDS } from './shared/workflow-registry.js';
5
5
  import { CommandAdapterRegistry } from './command-generation/index.js';
6
- import { COMMAND_IDS, getConfiguredTools } from './shared/index.js';
7
- /**
8
- * Maps workflow IDs to their skill directory names.
9
- */
10
- export const WORKFLOW_TO_SKILL_DIR = {
11
- 'explore': 'syn-explore',
12
- 'apply': 'syn-apply',
13
- 'archive': 'syn-archive',
14
- 'propose': 'syn-propose',
15
- 'sync': 'syn-sync',
16
- 'clarify': 'syn-clarify',
17
- 'analyze': 'syn-analyze',
18
- 'debug': 'syn-debug',
19
- };
6
+ import { getConfiguredTools } from './shared/index.js';
20
7
  function toKnownWorkflows(workflows) {
21
8
  return workflows.filter((workflow) => ALL_WORKFLOWS.includes(workflow));
22
9
  }
@@ -5,17 +5,6 @@
5
5
  * Profiles determine WHICH workflows; delivery (in global config) determines HOW.
6
6
  */
7
7
  import type { Profile } from './global-config.js';
8
- /**
9
- * Core workflows included in the 'core' profile.
10
- * These provide the streamlined experience for new users.
11
- */
12
- export declare const CORE_WORKFLOWS: readonly ["explore", "propose", "clarify", "analyze", "apply", "debug", "archive", "sync"];
13
- /**
14
- * All available workflows in the system.
15
- */
16
- export declare const ALL_WORKFLOWS: readonly ["explore", "propose", "clarify", "analyze", "apply", "debug", "archive", "sync"];
17
- export type WorkflowId = (typeof ALL_WORKFLOWS)[number];
18
- export type CoreWorkflowId = (typeof CORE_WORKFLOWS)[number];
19
8
  /**
20
9
  * Resolves which workflows should be active for a given profile configuration.
21
10
  *
@@ -4,24 +4,7 @@
4
4
  * Defines workflow profiles that control which workflows are installed.
5
5
  * Profiles determine WHICH workflows; delivery (in global config) determines HOW.
6
6
  */
7
- /**
8
- * Core workflows included in the 'core' profile.
9
- * These provide the streamlined experience for new users.
10
- */
11
- export const CORE_WORKFLOWS = ['explore', 'propose', 'clarify', 'analyze', 'apply', 'debug', 'archive', 'sync'];
12
- /**
13
- * All available workflows in the system.
14
- */
15
- export const ALL_WORKFLOWS = [
16
- 'explore',
17
- 'propose',
18
- 'clarify',
19
- 'analyze',
20
- 'apply',
21
- 'debug',
22
- 'archive',
23
- 'sync',
24
- ];
7
+ import { CORE_WORKFLOWS } from './shared/workflow-registry.js';
25
8
  /**
26
9
  * Resolves which workflows should be active for a given profile configuration.
27
10
  *
@@ -0,0 +1,5 @@
1
+ export declare function removeSkillDirs(skillsDir: string): Promise<number>;
2
+ export declare function removeUnselectedSkillDirs(skillsDir: string, desiredWorkflows: readonly string[]): Promise<number>;
3
+ export declare function removeCommandFiles(projectPath: string, toolId: string): Promise<number>;
4
+ export declare function removeUnselectedCommandFiles(projectPath: string, toolId: string, desiredWorkflows: readonly string[]): Promise<number>;
5
+ //# sourceMappingURL=artifact-cleanup.d.ts.map
@@ -0,0 +1,89 @@
1
+ import path from 'path';
2
+ import * as fs from 'fs';
3
+ import { ALL_WORKFLOWS, WORKFLOW_TO_SKILL_DIR } from './workflow-registry.js';
4
+ import { CommandAdapterRegistry } from '../command-generation/index.js';
5
+ export async function removeSkillDirs(skillsDir) {
6
+ let removed = 0;
7
+ for (const workflow of ALL_WORKFLOWS) {
8
+ const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
9
+ if (!dirName)
10
+ continue;
11
+ const skillDir = path.join(skillsDir, dirName);
12
+ try {
13
+ if (fs.existsSync(skillDir)) {
14
+ await fs.promises.rm(skillDir, { recursive: true, force: true });
15
+ removed++;
16
+ }
17
+ }
18
+ catch {
19
+ // Ignore errors
20
+ }
21
+ }
22
+ return removed;
23
+ }
24
+ export async function removeUnselectedSkillDirs(skillsDir, desiredWorkflows) {
25
+ const desiredSet = new Set(desiredWorkflows);
26
+ let removed = 0;
27
+ for (const workflow of ALL_WORKFLOWS) {
28
+ if (desiredSet.has(workflow))
29
+ continue;
30
+ const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
31
+ if (!dirName)
32
+ continue;
33
+ const skillDir = path.join(skillsDir, dirName);
34
+ try {
35
+ if (fs.existsSync(skillDir)) {
36
+ await fs.promises.rm(skillDir, { recursive: true, force: true });
37
+ removed++;
38
+ }
39
+ }
40
+ catch {
41
+ // Ignore errors
42
+ }
43
+ }
44
+ return removed;
45
+ }
46
+ export async function removeCommandFiles(projectPath, toolId) {
47
+ let removed = 0;
48
+ const adapter = CommandAdapterRegistry.get(toolId);
49
+ if (!adapter)
50
+ return 0;
51
+ for (const workflow of ALL_WORKFLOWS) {
52
+ const cmdPath = adapter.getFilePath(workflow);
53
+ const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
54
+ try {
55
+ if (fs.existsSync(fullPath)) {
56
+ await fs.promises.unlink(fullPath);
57
+ removed++;
58
+ }
59
+ }
60
+ catch {
61
+ // Ignore errors
62
+ }
63
+ }
64
+ return removed;
65
+ }
66
+ export async function removeUnselectedCommandFiles(projectPath, toolId, desiredWorkflows) {
67
+ let removed = 0;
68
+ const adapter = CommandAdapterRegistry.get(toolId);
69
+ if (!adapter)
70
+ return 0;
71
+ const desiredSet = new Set(desiredWorkflows);
72
+ for (const workflow of ALL_WORKFLOWS) {
73
+ if (desiredSet.has(workflow))
74
+ continue;
75
+ const cmdPath = adapter.getFilePath(workflow);
76
+ const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
77
+ try {
78
+ if (fs.existsSync(fullPath)) {
79
+ await fs.promises.unlink(fullPath);
80
+ removed++;
81
+ }
82
+ }
83
+ catch {
84
+ // Ignore errors
85
+ }
86
+ }
87
+ return removed;
88
+ }
89
+ //# sourceMappingURL=artifact-cleanup.js.map
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Shared utilities for generating skill and command files.
5
5
  */
6
- import { getSynExploreSkillTemplate, getSynApplySkillTemplate, getSynArchiveSkillTemplate, getSynProposeSkillTemplate, getSynSyncSkillTemplate, getSynClarifySkillTemplate, getSynAnalyzeSkillTemplate, getSynDebugSkillTemplate, getSynExploreCommandTemplate, getSynApplyCommandTemplate, getSynArchiveCommandTemplate, getSynProposeCommandTemplate, getSynSyncCommandTemplate, getSynClarifyCommandTemplate, getSynAnalyzeCommandTemplate, getSynDebugCommandTemplate, } from '../templates/skill-templates.js';
6
+ import { getSynExploreSkillTemplate, getSynApplySkillTemplate, getSynArchiveSkillTemplate, getSynProposeSkillTemplate, getSynSyncSkillTemplate, getSynClarifySkillTemplate, getSynAnalyzeSkillTemplate, getSynDebugSkillTemplate, getSynRefactorSkillTemplate, getSynQuickSkillTemplate, getSynExploreCommandTemplate, getSynApplyCommandTemplate, getSynArchiveCommandTemplate, getSynProposeCommandTemplate, getSynSyncCommandTemplate, getSynClarifyCommandTemplate, getSynAnalyzeCommandTemplate, getSynDebugCommandTemplate, getSynRefactorCommandTemplate, getSynQuickCommandTemplate, } from '../templates/skill-templates.js';
7
7
  /**
8
8
  * Gets skill templates with their directory names, optionally filtered by workflow IDs.
9
9
  *
@@ -19,6 +19,8 @@ export function getSkillTemplates(workflowFilter) {
19
19
  { template: getSynClarifySkillTemplate(), dirName: 'syn-clarify', workflowId: 'clarify' },
20
20
  { template: getSynAnalyzeSkillTemplate(), dirName: 'syn-analyze', workflowId: 'analyze' },
21
21
  { template: getSynDebugSkillTemplate(), dirName: 'syn-debug', workflowId: 'debug' },
22
+ { template: getSynRefactorSkillTemplate(), dirName: 'syn-refactor', workflowId: 'refactor' },
23
+ { template: getSynQuickSkillTemplate(), dirName: 'syn-quick', workflowId: 'quick' },
22
24
  ];
23
25
  if (!workflowFilter)
24
26
  return all;
@@ -40,6 +42,8 @@ export function getCommandTemplates(workflowFilter) {
40
42
  { template: getSynClarifyCommandTemplate(), id: 'clarify' },
41
43
  { template: getSynAnalyzeCommandTemplate(), id: 'analyze' },
42
44
  { template: getSynDebugCommandTemplate(), id: 'debug' },
45
+ { template: getSynRefactorCommandTemplate(), id: 'refactor' },
46
+ { template: getSynQuickCommandTemplate(), id: 'quick' },
43
47
  ];
44
48
  if (!workflowFilter)
45
49
  return all;
@@ -3,16 +3,10 @@
3
3
  *
4
4
  * Shared utilities for detecting tool configurations and version status.
5
5
  */
6
- /**
7
- * Names of skill directories created by synarcx init.
8
- */
9
- export declare const SKILL_NAMES: readonly ["syn-explore", "syn-apply", "syn-archive", "syn-propose", "syn-sync", "syn-clarify", "syn-analyze", "syn-debug"];
10
- export type SkillName = (typeof SKILL_NAMES)[number];
11
- /**
12
- * IDs of command templates created by synarcx init.
13
- */
14
- export declare const COMMAND_IDS: readonly ["explore", "apply", "archive", "propose", "sync", "clarify", "analyze", "debug"];
15
- export type CommandId = (typeof COMMAND_IDS)[number];
6
+ import { SKILL_NAMES, COMMAND_IDS } from './workflow-registry.js';
7
+ export type SkillName = string;
8
+ export type CommandId = string;
9
+ export { SKILL_NAMES, COMMAND_IDS };
16
10
  /**
17
11
  * Status of skill configuration for a tool.
18
12
  */
@@ -6,32 +6,8 @@
6
6
  import path from 'path';
7
7
  import * as fs from 'fs';
8
8
  import { AI_TOOLS } from '../config.js';
9
- /**
10
- * Names of skill directories created by synarcx init.
11
- */
12
- export const SKILL_NAMES = [
13
- 'syn-explore',
14
- 'syn-apply',
15
- 'syn-archive',
16
- 'syn-propose',
17
- 'syn-sync',
18
- 'syn-clarify',
19
- 'syn-analyze',
20
- 'syn-debug',
21
- ];
22
- /**
23
- * IDs of command templates created by synarcx init.
24
- */
25
- export const COMMAND_IDS = [
26
- 'explore',
27
- 'apply',
28
- 'archive',
29
- 'propose',
30
- 'sync',
31
- 'clarify',
32
- 'analyze',
33
- 'debug',
34
- ];
9
+ import { SKILL_NAMES, COMMAND_IDS } from './workflow-registry.js';
10
+ export { SKILL_NAMES, COMMAND_IDS };
35
11
  /**
36
12
  * Gets the list of tools with skillsDir configured.
37
13
  */
@@ -86,7 +62,7 @@ export function extractGeneratedByVersion(skillFilePath) {
86
62
  // ---
87
63
  // ...
88
64
  // metadata:
89
- // author: openspec
65
+ // author: synarcx
90
66
  // version: "1.0"
91
67
  // generatedBy: "0.23.0"
92
68
  // ---
@@ -0,0 +1,40 @@
1
+ export declare const DEFAULT_SCHEMA = "synarcx";
2
+ export declare const WORKFLOWS: readonly [{
3
+ readonly id: "explore";
4
+ readonly skillDir: "syn-explore";
5
+ }, {
6
+ readonly id: "apply";
7
+ readonly skillDir: "syn-apply";
8
+ }, {
9
+ readonly id: "archive";
10
+ readonly skillDir: "syn-archive";
11
+ }, {
12
+ readonly id: "propose";
13
+ readonly skillDir: "syn-propose";
14
+ }, {
15
+ readonly id: "sync";
16
+ readonly skillDir: "syn-sync";
17
+ }, {
18
+ readonly id: "clarify";
19
+ readonly skillDir: "syn-clarify";
20
+ }, {
21
+ readonly id: "analyze";
22
+ readonly skillDir: "syn-analyze";
23
+ }, {
24
+ readonly id: "debug";
25
+ readonly skillDir: "syn-debug";
26
+ }, {
27
+ readonly id: "refactor";
28
+ readonly skillDir: "syn-refactor";
29
+ }, {
30
+ readonly id: "quick";
31
+ readonly skillDir: "syn-quick";
32
+ }];
33
+ export declare const ALL_WORKFLOWS: readonly string[];
34
+ export declare const CORE_WORKFLOWS: readonly string[];
35
+ export declare const SKILL_NAMES: readonly string[];
36
+ export declare const COMMAND_IDS: readonly string[];
37
+ export declare const WORKFLOW_TO_SKILL_DIR: Record<string, string>;
38
+ export type WorkflowId = string;
39
+ export type CoreWorkflowId = string;
40
+ //# sourceMappingURL=workflow-registry.d.ts.map
@@ -0,0 +1,19 @@
1
+ export const DEFAULT_SCHEMA = 'synarcx';
2
+ export const WORKFLOWS = [
3
+ { id: 'explore', skillDir: 'syn-explore' },
4
+ { id: 'apply', skillDir: 'syn-apply' },
5
+ { id: 'archive', skillDir: 'syn-archive' },
6
+ { id: 'propose', skillDir: 'syn-propose' },
7
+ { id: 'sync', skillDir: 'syn-sync' },
8
+ { id: 'clarify', skillDir: 'syn-clarify' },
9
+ { id: 'analyze', skillDir: 'syn-analyze' },
10
+ { id: 'debug', skillDir: 'syn-debug' },
11
+ { id: 'refactor', skillDir: 'syn-refactor' },
12
+ { id: 'quick', skillDir: 'syn-quick' },
13
+ ];
14
+ export const ALL_WORKFLOWS = WORKFLOWS.map(w => w.id);
15
+ export const CORE_WORKFLOWS = [...ALL_WORKFLOWS];
16
+ export const SKILL_NAMES = WORKFLOWS.map(w => w.skillDir);
17
+ export const COMMAND_IDS = [...ALL_WORKFLOWS];
18
+ export const WORKFLOW_TO_SKILL_DIR = Object.fromEntries(WORKFLOWS.map(w => [w.id, w.skillDir]));
19
+ //# sourceMappingURL=workflow-registry.js.map