synarcx 0.3.1 → 0.3.3

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.
@@ -94,14 +94,14 @@ export function migrateIfNeeded(projectPath, tools) {
94
94
  // No workflows installed, new user — defaults will apply
95
95
  return;
96
96
  }
97
- // Migrate: set profile to custom with detected workflows
98
- config.profile = 'custom';
99
- config.workflows = installedWorkflows;
97
+ // Migrate: pre-profile users had the full installed set that maps to 'core'.
98
+ // Setting 'core' means they automatically receive every future new command
99
+ // (e.g. 'review', and anything added later) without any manual steps.
100
+ config.profile = 'core';
100
101
  if (rawConfig.delivery === undefined) {
101
102
  config.delivery = inferDelivery(artifacts);
102
103
  }
103
104
  saveGlobalConfig(config);
104
- console.log(`Migrated: custom profile with ${installedWorkflows.length} workflows`);
105
- console.log("New in this version: /syn:propose. Try 'synarcx config profile core' for the streamlined experience.");
105
+ console.log(`Migrated to core profile you'll receive all future commands automatically.`);
106
106
  }
107
107
  //# sourceMappingURL=migration.js.map
@@ -4,12 +4,20 @@
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
- import type { Profile } from './global-config.js';
7
+ import type { Profile, GlobalConfig } from './global-config.js';
8
8
  /**
9
9
  * Resolves which workflows should be active for a given profile configuration.
10
10
  *
11
11
  * - 'core' profile always returns CORE_WORKFLOWS
12
12
  * - 'custom' profile returns the provided customWorkflows, or empty array if not provided
13
13
  */
14
- export declare function getProfileWorkflows(profile: Profile, customWorkflows?: string[]): readonly string[];
14
+ export declare function getProfileWorkflows(profile: Profile, customWorkflows?: readonly string[]): readonly string[];
15
+ /**
16
+ * Ensures a 'custom' profile always contains all current ALL_WORKFLOWS entries.
17
+ * Called by both `synarcx init` and `synarcx update` so new commands (e.g. syn:review)
18
+ * are never silently dropped for users on a stale custom profile, regardless of which
19
+ * command they run after upgrading.
20
+ * No-op for 'core' profile (it derives its list from ALL_WORKFLOWS directly).
21
+ */
22
+ export declare function syncNewCoreWorkflowsToCustomProfile(config: GlobalConfig): void;
15
23
  //# sourceMappingURL=profiles.d.ts.map
@@ -4,7 +4,8 @@
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
- import { CORE_WORKFLOWS } from './shared/workflow-registry.js';
7
+ import { saveGlobalConfig } from './global-config.js';
8
+ import { ALL_WORKFLOWS, CORE_WORKFLOWS } from './shared/workflow-registry.js';
8
9
  /**
9
10
  * Resolves which workflows should be active for a given profile configuration.
10
11
  *
@@ -17,4 +18,22 @@ export function getProfileWorkflows(profile, customWorkflows) {
17
18
  }
18
19
  return CORE_WORKFLOWS;
19
20
  }
21
+ /**
22
+ * Ensures a 'custom' profile always contains all current ALL_WORKFLOWS entries.
23
+ * Called by both `synarcx init` and `synarcx update` so new commands (e.g. syn:review)
24
+ * are never silently dropped for users on a stale custom profile, regardless of which
25
+ * command they run after upgrading.
26
+ * No-op for 'core' profile (it derives its list from ALL_WORKFLOWS directly).
27
+ */
28
+ export function syncNewCoreWorkflowsToCustomProfile(config) {
29
+ if (config.profile !== 'custom')
30
+ return;
31
+ const current = config.workflows ?? [];
32
+ const currentSet = new Set(current);
33
+ const missing = ALL_WORKFLOWS.filter(w => !currentSet.has(w));
34
+ if (missing.length === 0)
35
+ return;
36
+ config.workflows = [...current, ...missing];
37
+ saveGlobalConfig(config);
38
+ }
20
39
  //# sourceMappingURL=profiles.js.map
@@ -77,18 +77,18 @@ export function generateSkillContent(template, generatedByVersion, transformInst
77
77
  const instructions = transformInstructions
78
78
  ? transformInstructions(template.instructions)
79
79
  : template.instructions;
80
- return `---
81
- name: ${template.name}
82
- description: ${template.description}
83
- license: ${template.license || 'MIT'}
84
- compatibility: ${template.compatibility || 'Requires synarcx CLI.'}
85
- metadata:
86
- author: ${template.metadata?.author || 'synarcx'}
87
- version: "${template.metadata?.version || '1.0'}"
88
- generatedBy: "${generatedByVersion}"
89
- ---
90
-
91
- ${instructions}
80
+ return `---
81
+ name: ${template.name}
82
+ description: ${template.description}
83
+ license: ${template.license || 'MIT'}
84
+ compatibility: ${template.compatibility || 'Requires synarcx CLI.'}
85
+ metadata:
86
+ author: ${template.metadata?.author || 'synarcx'}
87
+ version: "${template.metadata?.version || '1.0'}"
88
+ generatedBy: "${generatedByVersion}"
89
+ ---
90
+
91
+ ${instructions}
92
92
  `;
93
93
  }
94
94
  //# sourceMappingURL=skill-generation.js.map
@@ -270,7 +270,10 @@ export async function writeUpdatedSpec(update, rebuilt, counts) {
270
270
  // Create target directory if needed
271
271
  const targetDir = path.dirname(update.target);
272
272
  await fs.mkdir(targetDir, { recursive: true });
273
- await fs.writeFile(update.target, rebuilt);
273
+ // Atomic write: write to .tmp then rename (prevents half-written files on crash)
274
+ const tmpPath = update.target + '.tmp';
275
+ await fs.writeFile(tmpPath, rebuilt);
276
+ await fs.rename(tmpPath, update.target);
274
277
  const specName = path.basename(path.dirname(update.target));
275
278
  console.log(`Applying changes to synspec/specs/${specName}/spec.md:`);
276
279
  if (counts.added)
@@ -347,10 +350,12 @@ export async function applySpecs(projectRoot, changeName, options = {}) {
347
350
  for (const p of prepared) {
348
351
  const capability = path.basename(path.dirname(p.update.target));
349
352
  if (!options.dryRun) {
350
- // Write the updated spec
353
+ // Write the updated spec (atomic: .tmp + rename)
351
354
  const targetDir = path.dirname(p.update.target);
352
355
  await fs.mkdir(targetDir, { recursive: true });
353
- await fs.writeFile(p.update.target, p.rebuilt);
356
+ const tmpPath = p.update.target + '.tmp';
357
+ await fs.writeFile(tmpPath, p.rebuilt);
358
+ await fs.rename(tmpPath, p.update.target);
354
359
  if (!options.silent) {
355
360
  console.log(`Applying changes to synspec/specs/${capability}/spec.md:`);
356
361
  if (p.counts.added)
@@ -71,7 +71,7 @@ export function getSynDebugCommandTemplate() {
71
71
  name: 'syn:debug',
72
72
  description: 'Investigate a known error — root cause analysis through hypothesis, explicitly prompts /syn:propose',
73
73
  tags: ['workflow', 'debug', 'fix'],
74
- content: `Investigate a known error or failure systematically in 3 phases. Produces a diagnosis and suggests \`/syn:propose\` for creating the fix change.
74
+ content: `Investigate a known error or failure systematically in 3 phases. Produces a diagnosis and explicitly prompts the user to run \`/syn:propose\` does NOT auto-create artifacts or auto-hand off.
75
75
 
76
76
  **Input**: Error message, symptom, or failure description. The argument after \`/syn:debug\` is what went wrong.
77
77
 
@@ -79,7 +79,12 @@ export function getSynDebugCommandTemplate() {
79
79
 
80
80
  ## Initial Context
81
81
 
82
- If a change is active, read its artifacts first to understand what was intended vs. what went wrong.
82
+ If a change is active, read its artifacts first:
83
+ - \`synspec/changes/<name>/proposal.md\`
84
+ - \`synspec/changes/<name>/design.md\`
85
+ - \`synspec/changes/<name>/tasks.md\`
86
+
87
+ Use that context to understand what was intended vs. what went wrong.
83
88
 
84
89
  ---
85
90
 
@@ -111,7 +116,19 @@ If a change is active, read its artifacts first to understand what was intended
111
116
 
112
117
  ## Output
113
118
 
114
- After completing, present the diagnosis and explicitly prompt the user to run \`/syn:propose\` to formalize the fix. Do NOT auto-create artifacts.`
119
+ After completing the 3-phase investigation, present findings and prompt explicitly:
120
+
121
+ \`\`\`
122
+ ### Diagnosis
123
+
124
+ **Root Cause**: <what was found>
125
+ **Pattern**: <similar issues or novel>
126
+ **Hypothesis**: <proposed fix approach>
127
+
128
+ **Ready to formalize?** Run \`/syn:propose\` to create a change with these findings.
129
+ \`\`\`
130
+
131
+ Do NOT create any artifacts, do NOT start the pipeline automatically. The user must explicitly run \`/syn:propose\` to formalize.`
115
132
  });
116
133
  }
117
134
  //# sourceMappingURL=debug.js.map
@@ -103,12 +103,52 @@ export function getSynRefactorCommandTemplate() {
103
103
 
104
104
  ---
105
105
 
106
+ ## Initial Context
107
+
108
+ Check for existing context:
109
+ \`\`\`bash
110
+ synarcx list --json
111
+ \`\`\`
112
+
113
+ If a relevant change exists, read its artifacts. Otherwise, start fresh.
114
+
115
+ ---
116
+
117
+ ## Reframing the Problem
118
+
119
+ This is a structural-change investigation. The goal is to improve code organization, reduce duplication, increase cohesion, or decrease coupling — without changing what the system does.
120
+
121
+ ### Opening Question
122
+
123
+ Start by asking (use AskUserQuestion tool, open-ended):
124
+ > "What part of the codebase feels like it needs restructuring?"
125
+
126
+ Let the user describe the pain point before diving in.
127
+
128
+ ---
129
+
106
130
  ## Investigation
107
131
 
108
- 1. **Map the current shape** — read relevant source files, identify module boundaries, dependencies, duplication.
109
- 2. **Identify the target shape** — define what the ideal structure looks like.
110
- 3. **Surface risks** — flag implicit dependencies, testing hazards, areas that could get worse.
111
- 4. **Visualize** use ASCII diagrams to show current vs. target structure.
132
+ 1. **Map the current shape** — read relevant source files, identify:
133
+ - Module boundaries and responsibilities
134
+ - Dependency direction
135
+ - Code duplication or overlapping concerns
136
+ - Testing patterns
137
+
138
+ 2. **Identify the target shape** — work with the user to define:
139
+ - What the ideal structure would look like
140
+ - Which modules or files move where
141
+ - How dependencies should flow
142
+
143
+ 3. **Surface risks** — flag areas of concern:
144
+ - Implicit dependencies that aren't visible in imports
145
+ - Areas where refactoring could make things worse
146
+ - Testing hazards (brittle tests, high coupling to internals)
147
+
148
+ 4. **Visualize** — use ASCII diagrams to show:
149
+ - Current vs. target module structure
150
+ - Dependency direction changes
151
+ - File/move relationships
112
152
 
113
153
  ---
114
154
 
@@ -120,7 +160,20 @@ When artifacts are created, the analyze phase MUST check for behavior contract v
120
160
 
121
161
  ## Hand-Off
122
162
 
123
- Present a summary with Current Shape, Target Shape, Key Changes, and Risks. Then explicitly prompt: "Ready to formalize? Run \`/syn:propose\` to create a change with these findings."`
163
+ When the investigation reaches a clear conclusion, present findings and explicitly prompt:
164
+
165
+ \`\`\`
166
+ ### Refactoring Plan
167
+
168
+ **Current Shape**: <summary of current structure>
169
+ **Target Shape**: <proposed structure>
170
+ **Key Changes**: <list of structural moves>
171
+ **Risks**: <potential issues>
172
+
173
+ **Ready to formalize?** Run \`/syn:propose\` to create a change with these findings.
174
+ \`\`\`
175
+
176
+ Do NOT create any artifacts or start the pipeline. The user must explicitly run \`/syn:propose\`.`
124
177
  });
125
178
  }
126
179
  //# sourceMappingURL=refactor.js.map