synarcx 0.3.3 → 0.3.5
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
CHANGED
|
@@ -147,7 +147,7 @@ Each step suggests the next — you decide when to advance. Works in Claude Code
|
|
|
147
147
|
- `sync` generates the `constitution.md` — run once, re-run when the project shifts. Also runs a daily version check (prompts to auto-update) and checks for pending spec syncs from recently archived changes.
|
|
148
148
|
- `explore`, `debug`, and `refactor` are entry points that hand off to `propose`
|
|
149
149
|
- `quick` skips the pipeline for small, low-risk changes
|
|
150
|
-
- Run `synarcx update` in your terminal to refresh all
|
|
150
|
+
- Run `synarcx update` in your terminal to refresh all command files after installing a new version
|
|
151
151
|
- `review` is a three-way fork:
|
|
152
152
|
- **Archive now**: auto-syncs delta specs to main spec via `buildUpdatedSpec()`, writes `.pending-sync.json` marker, moves to archive. If spec sync fails, the change is already safely in archive; retry on next sync run.
|
|
153
153
|
- **Add more work**: scope gate reads proposal capabilities + design goals/non-goals. In-scope → update artifacts, MUST `/syn:clarify` then `/syn:apply` then `/syn:review` again (loop). Out-of-scope → offer archive then route to `/syn:propose`.
|
|
@@ -213,7 +213,7 @@ Used in your terminal:
|
|
|
213
213
|
| Command | Description |
|
|
214
214
|
| ------------------- | ------------------------------------------------------------ |
|
|
215
215
|
| `synarcx init` | Set up SynArcX workflow structure in your repository |
|
|
216
|
-
| `synarcx update` | Refresh
|
|
216
|
+
| `synarcx update` | Refresh command files for all configured tools |
|
|
217
217
|
| `synarcx sync` | Regenerate `constitution.md` |
|
|
218
218
|
| `synarcx explore` | Open explore session |
|
|
219
219
|
| `synarcx propose` | Create a structured change proposal |
|
package/dist/core/config.js
CHANGED
|
@@ -4,32 +4,32 @@ export const SYNSPEC_MARKERS = {
|
|
|
4
4
|
end: '<!-- SYNSPEC:END -->'
|
|
5
5
|
};
|
|
6
6
|
export const AI_TOOLS = [
|
|
7
|
-
{ name: 'Amazon Q Developer', value: 'amazon-q', available: true, successLabel: 'Amazon Q Developer', skillsDir: '.amazonq' },
|
|
8
|
-
{ name: 'Antigravity', value: 'antigravity', available: true, successLabel: 'Antigravity', skillsDir: '.agent' },
|
|
9
|
-
{ name: 'Auggie (Augment CLI)', value: 'auggie', available: true, successLabel: 'Auggie', skillsDir: '.augment' },
|
|
10
|
-
{ name: 'Bob Shell', value: 'bob', available: true, successLabel: 'Bob Shell', skillsDir: '.bob' },
|
|
7
|
+
{ name: 'Amazon Q Developer', value: 'amazon-q', available: true, successLabel: 'Amazon Q Developer', skillsDir: '.amazonq', hasCommands: true },
|
|
8
|
+
{ name: 'Antigravity', value: 'antigravity', available: true, successLabel: 'Antigravity', skillsDir: '.agent', hasCommands: true },
|
|
9
|
+
{ name: 'Auggie (Augment CLI)', value: 'auggie', available: true, successLabel: 'Auggie', skillsDir: '.augment', hasCommands: true },
|
|
10
|
+
{ name: 'Bob Shell', value: 'bob', available: true, successLabel: 'Bob Shell', skillsDir: '.bob', hasCommands: true },
|
|
11
11
|
{ name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code', skillsDir: '.claude', hasCommands: true },
|
|
12
|
-
{ name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline' },
|
|
13
|
-
{ name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex' },
|
|
14
|
-
{ name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code', skillsDir: '.codebuddy' },
|
|
15
|
-
{ name: 'Continue', value: 'continue', available: true, successLabel: 'Continue (VS Code / JetBrains / Cli)', skillsDir: '.continue' },
|
|
16
|
-
{ name: 'CoStrict', value: 'costrict', available: true, successLabel: 'CoStrict', skillsDir: '.cospec' },
|
|
17
|
-
{ name: 'Crush', value: 'crush', available: true, successLabel: 'Crush', skillsDir: '.crush' },
|
|
18
|
-
{ name: 'Cursor', value: 'cursor', available: true, successLabel: 'Cursor', skillsDir: '.cursor' },
|
|
19
|
-
{ name: 'Factory Droid', value: 'factory', available: true, successLabel: 'Factory Droid', skillsDir: '.factory' },
|
|
20
|
-
{ name: 'Gemini CLI', value: 'gemini', available: true, successLabel: 'Gemini CLI', skillsDir: '.gemini' },
|
|
21
|
-
{ name: 'GitHub Copilot', value: 'github-copilot', available: true, successLabel: 'GitHub Copilot', skillsDir: '.github', detectionPaths: ['.github/copilot-instructions.md', '.github/instructions', '.github/workflows/copilot-setup-steps.yml', '.github/prompts', '.github/agents', '.github/skills', '.github/.mcp.json'] },
|
|
22
|
-
{ name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow' },
|
|
23
|
-
{ name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie' },
|
|
24
|
-
{ name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code', skillsDir: '.kilocode' },
|
|
25
|
-
{ name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro' },
|
|
12
|
+
{ name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline', hasCommands: true },
|
|
13
|
+
{ name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex', hasCommands: true },
|
|
14
|
+
{ name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code', skillsDir: '.codebuddy', hasCommands: true },
|
|
15
|
+
{ name: 'Continue', value: 'continue', available: true, successLabel: 'Continue (VS Code / JetBrains / Cli)', skillsDir: '.continue', hasCommands: true },
|
|
16
|
+
{ name: 'CoStrict', value: 'costrict', available: true, successLabel: 'CoStrict', skillsDir: '.cospec', hasCommands: true },
|
|
17
|
+
{ name: 'Crush', value: 'crush', available: true, successLabel: 'Crush', skillsDir: '.crush', hasCommands: true },
|
|
18
|
+
{ name: 'Cursor', value: 'cursor', available: true, successLabel: 'Cursor', skillsDir: '.cursor', hasCommands: true },
|
|
19
|
+
{ name: 'Factory Droid', value: 'factory', available: true, successLabel: 'Factory Droid', skillsDir: '.factory', hasCommands: true },
|
|
20
|
+
{ name: 'Gemini CLI', value: 'gemini', available: true, successLabel: 'Gemini CLI', skillsDir: '.gemini', hasCommands: true },
|
|
21
|
+
{ name: 'GitHub Copilot', value: 'github-copilot', available: true, successLabel: 'GitHub Copilot', skillsDir: '.github', detectionPaths: ['.github/copilot-instructions.md', '.github/instructions', '.github/workflows/copilot-setup-steps.yml', '.github/prompts', '.github/agents', '.github/skills', '.github/.mcp.json'], hasCommands: true },
|
|
22
|
+
{ name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow', hasCommands: true },
|
|
23
|
+
{ name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie', hasCommands: true },
|
|
24
|
+
{ name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code', skillsDir: '.kilocode', hasCommands: true },
|
|
25
|
+
{ name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro', hasCommands: true },
|
|
26
26
|
{ name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode', skillsDir: '.opencode', hasCommands: true },
|
|
27
|
-
{ name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi' },
|
|
28
|
-
{ name: 'Qoder', value: 'qoder', available: true, successLabel: 'Qoder', skillsDir: '.qoder' },
|
|
29
|
-
{ name: 'Lingma', value: 'lingma', available: true, successLabel: 'Lingma', skillsDir: '.lingma' },
|
|
30
|
-
{ name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code', skillsDir: '.qwen' },
|
|
31
|
-
{ name: 'RooCode', value: 'roocode', available: true, successLabel: 'RooCode', skillsDir: '.roo' },
|
|
32
|
-
{ name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf', skillsDir: '.windsurf' },
|
|
27
|
+
{ name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi', hasCommands: true },
|
|
28
|
+
{ name: 'Qoder', value: 'qoder', available: true, successLabel: 'Qoder', skillsDir: '.qoder', hasCommands: true },
|
|
29
|
+
{ name: 'Lingma', value: 'lingma', available: true, successLabel: 'Lingma', skillsDir: '.lingma', hasCommands: true },
|
|
30
|
+
{ name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code', skillsDir: '.qwen', hasCommands: true },
|
|
31
|
+
{ name: 'RooCode', value: 'roocode', available: true, successLabel: 'RooCode', skillsDir: '.roo', hasCommands: true },
|
|
32
|
+
{ name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf', skillsDir: '.windsurf', hasCommands: true },
|
|
33
33
|
{ name: 'AGENTS.md (works with Amp, VS Code, …)', value: 'agents', available: false, successLabel: 'your AGENTS.md-compatible assistant' }
|
|
34
34
|
];
|
|
35
35
|
//# sourceMappingURL=config.js.map
|
package/dist/core/init.js
CHANGED
|
@@ -384,8 +384,8 @@ export class InitCommand {
|
|
|
384
384
|
const skillsDir = path.join(projectPath, tool.skillsDir, 'skills');
|
|
385
385
|
removedSkillCount += await removeSkillDirs(skillsDir);
|
|
386
386
|
}
|
|
387
|
-
// Generate commands if delivery includes commands
|
|
388
|
-
if (shouldGenerateCommands) {
|
|
387
|
+
// Generate commands if delivery includes commands and tool supports them
|
|
388
|
+
if (shouldGenerateCommands && hasCommands) {
|
|
389
389
|
const adapter = CommandAdapterRegistry.get(tool.value);
|
|
390
390
|
if (adapter) {
|
|
391
391
|
const generatedCommands = generateCommands(commandContents, adapter);
|
|
@@ -19,6 +19,18 @@ export async function removeSkillDirs(skillsDir) {
|
|
|
19
19
|
// Ignore errors
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
// Remove empty parent skills directory
|
|
23
|
+
try {
|
|
24
|
+
if (fs.existsSync(skillsDir)) {
|
|
25
|
+
const remaining = await fs.promises.readdir(skillsDir);
|
|
26
|
+
if (remaining.length === 0) {
|
|
27
|
+
await fs.promises.rmdir(skillsDir);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Ignore errors
|
|
33
|
+
}
|
|
22
34
|
return removed;
|
|
23
35
|
}
|
|
24
36
|
export async function removeUnselectedSkillDirs(skillsDir, desiredWorkflows) {
|
|
@@ -98,7 +98,7 @@ export function getSynReviewSkillTemplate() {
|
|
|
98
98
|
4. **OUT OF SCOPE** (new capability, different concern, violates non-goal):
|
|
99
99
|
- Inform user: "This is outside the current change's scope."
|
|
100
100
|
- Offer: "Archive current change first?" — YES archives with spec sync, NO leaves active
|
|
101
|
-
- Route: "Start a new change with \`/syn:propose\`"
|
|
101
|
+
- Route: "Start a new change with \`/syn:propose\`"
|
|
102
102
|
|
|
103
103
|
**If any checks failed** (dirty):
|
|
104
104
|
|
|
@@ -140,7 +140,7 @@ export function getSynReviewSkillTemplate() {
|
|
|
140
140
|
|
|
141
141
|
e. **Confirm**:
|
|
142
142
|
- "Archived <change-name> to synspec/changes/archive/YYYY-MM-DD-<name>/"
|
|
143
|
-
- If specs were synced: "Specs synced: <capability>: +N ~M"
|
|
143
|
+
- If specs were synced: "Specs synced: <capability>: +N ~M"
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
@@ -301,7 +301,7 @@ export function getSynReviewCommandTemplate() {
|
|
|
301
301
|
c. Move: \`mv synspec/changes/<name> synspec/changes/archive/YYYY-MM-DD-<name>\`
|
|
302
302
|
d. Sync specs: \`findSpecUpdates(archivePath)\` → \`buildUpdatedSpec()\` → atomic write (\`.tmp\` + rename) → per-capability output
|
|
303
303
|
e. Update marker with \`syncedAt\` timestamp
|
|
304
|
-
f. On failure: archive is already moved, marker stays \`null\`, backstop retries on next sync
|
|
304
|
+
f. On failure: archive is already moved, marker stays \`null\`, backstop retries on next sync
|
|
305
305
|
|
|
306
306
|
---
|
|
307
307
|
|
package/dist/core/update.js
CHANGED
|
@@ -144,12 +144,12 @@ export class UpdateCommand {
|
|
|
144
144
|
}
|
|
145
145
|
removedDeselectedSkillCount += await removeUnselectedSkillDirs(skillsDir, desiredWorkflows);
|
|
146
146
|
}
|
|
147
|
-
// Delete skill directories if delivery is commands-only
|
|
148
|
-
if (!shouldGenerateSkills) {
|
|
147
|
+
// Delete skill directories if delivery is commands-only or tool uses commands
|
|
148
|
+
if (!shouldGenerateSkills || tool.hasCommands) {
|
|
149
149
|
removedSkillCount += await removeSkillDirs(skillsDir);
|
|
150
150
|
}
|
|
151
|
-
// Generate commands if delivery includes commands
|
|
152
|
-
if (shouldGenerateCommands) {
|
|
151
|
+
// Generate commands if delivery includes commands and tool supports them
|
|
152
|
+
if (shouldGenerateCommands && tool.hasCommands) {
|
|
153
153
|
const adapter = CommandAdapterRegistry.get(tool.value);
|
|
154
154
|
if (adapter) {
|
|
155
155
|
const generatedCommands = generateCommands(commandContents, adapter);
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synarcx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
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",
|
|
7
7
|
"claude-code",
|
|
8
8
|
"cursor",
|
|
9
|
+
"opencode",
|
|
10
|
+
"codex",
|
|
11
|
+
"gemini",
|
|
9
12
|
"spec-driven-development",
|
|
10
13
|
"ai-coding-assistant",
|
|
11
14
|
"architecture-drift",
|
|
@@ -34,7 +37,7 @@
|
|
|
34
37
|
}
|
|
35
38
|
},
|
|
36
39
|
"bin": {
|
|
37
|
-
"synarcx": "
|
|
40
|
+
"synarcx": "./dist/index.js"
|
|
38
41
|
},
|
|
39
42
|
"files": [
|
|
40
43
|
"dist",
|