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.
- package/README.md +307 -296
- package/dist/core/init.js +4 -1
- package/dist/core/migration.js +5 -5
- package/dist/core/profiles.d.ts +10 -2
- package/dist/core/profiles.js +20 -1
- package/dist/core/shared/skill-generation.js +12 -12
- package/dist/core/specs-apply.js +8 -3
- package/dist/core/templates/workflows/debug.js +20 -3
- package/dist/core/templates/workflows/refactor.js +58 -5
- package/dist/core/templates/workflows/review.js +324 -273
- package/dist/core/templates/workflows/sync.js +62 -18
- package/dist/core/update.d.ts +6 -0
- package/dist/core/update.js +25 -2
- package/package.json +1 -1
|
@@ -3,11 +3,47 @@ export function getSynSyncSkillTemplate() {
|
|
|
3
3
|
return {
|
|
4
4
|
name: 'syn-sync',
|
|
5
5
|
description: 'Generate or update synspec/constitution.md with README validation, supporting file scan, guardrail Q&A, and structured constitution generation.',
|
|
6
|
-
instructions: `## Step 0:
|
|
6
|
+
instructions: `## Step 0: Pending Spec Sync Check (runs before version check)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Check for pending spec syncs from recently archived changes. This runs before the version check because it's a local filesystem operation and should not be blocked by network issues.
|
|
9
9
|
|
|
10
|
-
### 0.1 Read
|
|
10
|
+
### 0.1 Read \`synspec/.pending-sync.json\`
|
|
11
|
+
|
|
12
|
+
If the file doesn't exist, skip this step entirely (no pending syncs).
|
|
13
|
+
|
|
14
|
+
Expected format:
|
|
15
|
+
\`\`\`json
|
|
16
|
+
{ "pending": [{ "change": "YYYY-MM-DD-<name>", "archivedAt": "<ISO>", "syncedAt": null }] }
|
|
17
|
+
\`\`\`
|
|
18
|
+
|
|
19
|
+
### 0.2 Process pending entries (FIFO order)
|
|
20
|
+
|
|
21
|
+
For each entry where \`syncedAt\` is \`null\`:
|
|
22
|
+
- Construct path: \`synspec/changes/archive/<change>/\`
|
|
23
|
+
- Call \`findSpecUpdates(archivePath, synspec/specs/)\` to discover delta specs in the archived change
|
|
24
|
+
- For each delta spec, call \`buildUpdatedSpec()\` to merge into main specs
|
|
25
|
+
- Write rebuilt specs atomically (\`.tmp\` + rename to \`spec.md\`)
|
|
26
|
+
- Show per-change output: "Synced specs from <change>: <capability>: +N ~M"
|
|
27
|
+
- After each change processed, update its \`syncedAt\` field
|
|
28
|
+
- If \`buildUpdatedSpec()\` throws: show error, leave \`syncedAt\` as \`null\` (retry next time)
|
|
29
|
+
|
|
30
|
+
### 0.3 Clean up marker
|
|
31
|
+
|
|
32
|
+
After all pending entries are processed:
|
|
33
|
+
- If all entries have \`syncedAt\` set: delete \`synspec/.pending-sync.json\` entirely (clean slate)
|
|
34
|
+
- If some entries failed (\`syncedAt\` still \`null\`): keep the marker, show which changes still need attention, and why
|
|
35
|
+
|
|
36
|
+
### 0.4 Proceed to version check
|
|
37
|
+
|
|
38
|
+
Once pending syncs are handled, proceed to Step 1.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Step 1: SynArcX Version Check
|
|
43
|
+
|
|
44
|
+
Do NOT read any project files yet. Run this version check after pending spec syncs are handled.
|
|
45
|
+
|
|
46
|
+
### 1.1 Read the daily cache
|
|
11
47
|
|
|
12
48
|
Read \`synspec/.version-cache.json\`. If \`lastCheck\` matches today's UTC date (YYYY-MM-DD), skip the version check entirely — proceed to "Main Sync Flow" below.
|
|
13
49
|
|
|
@@ -18,15 +54,15 @@ Expected cache format:
|
|
|
18
54
|
|
|
19
55
|
If missing or malformed, treat as cache miss and continue.
|
|
20
56
|
|
|
21
|
-
###
|
|
57
|
+
### 1.2 Fetch latest from npm
|
|
22
58
|
|
|
23
|
-
Run \`npm view synarcx version\`. On failure (no npm, no network, non-zero exit): silently skip to
|
|
59
|
+
Run \`npm view synarcx version\`. On failure (no npm, no network, non-zero exit): silently skip to 1.5, write cache with \`latestVersion: null\`.
|
|
24
60
|
|
|
25
|
-
###
|
|
61
|
+
### 1.3 Get installed version
|
|
26
62
|
|
|
27
|
-
Run \`synarcx --version\`. On failure: silently skip to
|
|
63
|
+
Run \`synarcx --version\`. On failure: silently skip to 1.5.
|
|
28
64
|
|
|
29
|
-
###
|
|
65
|
+
### 1.4 Compare and prompt
|
|
30
66
|
|
|
31
67
|
Parse both as semver: split on \`.\`, parse each as integer, compare major→minor→patch. If npm version > installed:
|
|
32
68
|
|
|
@@ -37,7 +73,7 @@ Parse both as semver: split on \`.\`, parse each as integer, compare major→min
|
|
|
37
73
|
|
|
38
74
|
If versions match, proceed silently.
|
|
39
75
|
|
|
40
|
-
###
|
|
76
|
+
### 1.5 Write cache
|
|
41
77
|
|
|
42
78
|
Write \`synspec/.version-cache.json\` with today's UTC date and latest version (or \`null\` on failure). Use \`new Date().toISOString().split('T')[0]\`.
|
|
43
79
|
|
|
@@ -150,23 +186,31 @@ export function getSynSyncCommandTemplate() {
|
|
|
150
186
|
name: 'syn:sync',
|
|
151
187
|
description: 'Generate/update project constitution with README validation, guardrail Q&A, and constraint capture',
|
|
152
188
|
tags: ['workflow', 'sync', 'project'],
|
|
153
|
-
content: `## Step 0:
|
|
189
|
+
content: `## Step 0: Pending Spec Sync Check (runs before version check)
|
|
190
|
+
|
|
191
|
+
Check \`synspec/.pending-sync.json\`. If file missing, skip (no pending syncs). Expected format: \`{ "pending": [{ "change": "YYYY-MM-DD-<name>", "archivedAt": "<ISO>", "syncedAt": null }] }\`.
|
|
192
|
+
|
|
193
|
+
For each entry with \`syncedAt: null\`: construct path \`synspec/changes/archive/<change>/\`, call \`findSpecUpdates()\` + \`buildUpdatedSpec()\`, write atomically (\`.tmp\` + rename), update \`syncedAt\`. On error: leave \`syncedAt: null\` for retry.
|
|
194
|
+
|
|
195
|
+
After all processed: if all entries have \`syncedAt\`, delete marker file. If some still \`null\`, keep marker with error info. Then proceed.
|
|
196
|
+
|
|
197
|
+
---
|
|
154
198
|
|
|
155
|
-
|
|
199
|
+
## Step 1: SynArcX Version Check
|
|
156
200
|
|
|
157
|
-
###
|
|
201
|
+
### 1.1 Read the daily cache
|
|
158
202
|
|
|
159
203
|
Read \`synspec/.version-cache.json\`. If \`lastCheck\` matches today's UTC date (YYYY-MM-DD), skip to "Main Sync Flow" below. Expected format: \`{ "lastCheck": "2026-05-13", "latestVersion": "0.4.0" }\`.
|
|
160
204
|
|
|
161
|
-
###
|
|
205
|
+
### 1.2 Fetch latest from npm
|
|
162
206
|
|
|
163
|
-
Run \`npm view synarcx version\`. On failure, silently skip to
|
|
207
|
+
Run \`npm view synarcx version\`. On failure, silently skip to 1.5, write cache with \`latestVersion: null\`.
|
|
164
208
|
|
|
165
|
-
###
|
|
209
|
+
### 1.3 Get installed version
|
|
166
210
|
|
|
167
|
-
Run \`synarcx --version\`. On failure, silently skip to
|
|
211
|
+
Run \`synarcx --version\`. On failure, silently skip to 1.5.
|
|
168
212
|
|
|
169
|
-
###
|
|
213
|
+
### 1.4 Compare and prompt
|
|
170
214
|
|
|
171
215
|
Parse both as semver: split on \`.\`, parse each as integer, compare major→minor→patch. If npm version > installed:
|
|
172
216
|
|
|
@@ -177,7 +221,7 @@ Parse both as semver: split on \`.\`, parse each as integer, compare major→min
|
|
|
177
221
|
|
|
178
222
|
If versions match, proceed silently.
|
|
179
223
|
|
|
180
|
-
###
|
|
224
|
+
### 1.5 Write cache
|
|
181
225
|
|
|
182
226
|
Write \`synspec/.version-cache.json\` with today's UTC date and latest version (or \`null\` on failure). Use \`new Date().toISOString().split('T')[0]\`.
|
|
183
227
|
|
package/dist/core/update.d.ts
CHANGED
|
@@ -38,6 +38,12 @@ export declare class UpdateCommand {
|
|
|
38
38
|
* Displays a note about extra workflows installed that aren't in the current profile.
|
|
39
39
|
*/
|
|
40
40
|
private displayExtraWorkflowsNote;
|
|
41
|
+
/**
|
|
42
|
+
* Runs on every `synarcx update` so any newly introduced workflow (e.g. syn:review)
|
|
43
|
+
* is automatically added to the saved custom workflow list rather than silently dropped.
|
|
44
|
+
* Also prints a dim notice listing what was added.
|
|
45
|
+
*/
|
|
46
|
+
private runSyncNewCoreWorkflowsToCustomProfile;
|
|
41
47
|
/**
|
|
42
48
|
* Suggest opting back into core when a custom profile still matches the old
|
|
43
49
|
* pre-sync core set. Keep custom profiles user-owned; do not mutate them.
|
package/dist/core/update.js
CHANGED
|
@@ -16,7 +16,7 @@ import { getToolVersionStatus, getSkillTemplates, getCommandContents, generateSk
|
|
|
16
16
|
import { detectLegacyArtifacts, cleanupLegacyArtifacts, formatCleanupSummary, formatDetectionSummary, getToolsFromLegacyArtifacts, } from './legacy-cleanup.js';
|
|
17
17
|
import { isInteractive } from '../utils/interactive.js';
|
|
18
18
|
import { getGlobalConfig } from './global-config.js';
|
|
19
|
-
import { getProfileWorkflows } from './profiles.js';
|
|
19
|
+
import { getProfileWorkflows, syncNewCoreWorkflowsToCustomProfile } from './profiles.js';
|
|
20
20
|
import { ALL_WORKFLOWS } from './shared/workflow-registry.js';
|
|
21
21
|
import { removeSkillDirs, removeUnselectedSkillDirs, removeCommandFiles, removeUnselectedCommandFiles, } from './shared/artifact-cleanup.js';
|
|
22
22
|
import { getAvailableTools } from './available-tools.js';
|
|
@@ -57,7 +57,13 @@ export class UpdateCommand {
|
|
|
57
57
|
const globalConfig = getGlobalConfig();
|
|
58
58
|
const profile = globalConfig.profile ?? 'core';
|
|
59
59
|
const delivery = globalConfig.delivery ?? 'both';
|
|
60
|
-
|
|
60
|
+
// 3b. For custom profiles, auto-merge any new ALL_WORKFLOWS entries that aren't
|
|
61
|
+
// listed yet (e.g. 'syn:review' added in a new release). This prevents future
|
|
62
|
+
// versions from silently dropping new commands for existing custom-profile users.
|
|
63
|
+
this.runSyncNewCoreWorkflowsToCustomProfile(globalConfig);
|
|
64
|
+
// Re-read after potential mutation so desiredWorkflows is always current.
|
|
65
|
+
const effectiveConfig = getGlobalConfig();
|
|
66
|
+
const profileWorkflows = getProfileWorkflows(profile, effectiveConfig.workflows);
|
|
61
67
|
const desiredWorkflows = profileWorkflows.filter((workflow) => ALL_WORKFLOWS.includes(workflow));
|
|
62
68
|
const shouldGenerateSkills = delivery !== 'commands';
|
|
63
69
|
const shouldGenerateCommands = delivery !== 'skills';
|
|
@@ -266,6 +272,23 @@ export class UpdateCommand {
|
|
|
266
272
|
console.log(chalk.dim(`Note: ${extraWorkflows.length} extra workflows not in profile (use \`synarcx config profile\` to manage)`));
|
|
267
273
|
}
|
|
268
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Runs on every `synarcx update` so any newly introduced workflow (e.g. syn:review)
|
|
277
|
+
* is automatically added to the saved custom workflow list rather than silently dropped.
|
|
278
|
+
* Also prints a dim notice listing what was added.
|
|
279
|
+
*/
|
|
280
|
+
runSyncNewCoreWorkflowsToCustomProfile(config) {
|
|
281
|
+
const before = config.workflows ? [...config.workflows] : null;
|
|
282
|
+
syncNewCoreWorkflowsToCustomProfile(config);
|
|
283
|
+
const after = config.workflows ?? [];
|
|
284
|
+
const beforeSet = new Set(before ?? []);
|
|
285
|
+
const added = after.filter(w => !beforeSet.has(w));
|
|
286
|
+
if (added.length > 0) {
|
|
287
|
+
const listed = added.map(w => `/syn:${w}`).join(', ');
|
|
288
|
+
console.log(chalk.dim(`Auto-added new workflow(s) to your profile: ${listed}`));
|
|
289
|
+
console.log();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
269
292
|
/**
|
|
270
293
|
* Suggest opting back into core when a custom profile still matches the old
|
|
271
294
|
* pre-sync core set. Keep custom profiles user-owned; do not mutate them.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synarcx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Structured engineering workflows for AI coding assistants — persistent project memory, spec-driven development, and architecture drift prevention across every session.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-workflow",
|