synarcx 0.2.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.
- package/README.md +233 -39
- package/dist/commands/config.js +7 -6
- package/dist/core/command-generation/adapters/bob.js +7 -20
- package/dist/core/command-generation/adapters/claude.js +9 -29
- package/dist/core/command-generation/adapters/cursor.js +9 -22
- package/dist/core/command-generation/adapters/pi.js +6 -19
- package/dist/core/command-generation/adapters/windsurf.js +9 -29
- package/dist/core/command-generation/yaml-utils.d.ts +3 -0
- package/dist/core/command-generation/yaml-utils.js +12 -0
- package/dist/core/completions/installers/bash-installer.d.ts +1 -0
- package/dist/core/completions/installers/bash-installer.js +14 -3
- package/dist/core/completions/installers/powershell-installer.d.ts +1 -0
- package/dist/core/completions/installers/powershell-installer.js +18 -10
- package/dist/core/config.js +0 -3
- package/dist/core/index.js +1 -1
- package/dist/core/init.d.ts +0 -2
- package/dist/core/init.js +27 -77
- package/dist/core/migration.js +1 -2
- package/dist/core/profile-sync-drift.d.ts +0 -7
- package/dist/core/profile-sync-drift.js +2 -17
- package/dist/core/profiles.d.ts +0 -11
- package/dist/core/profiles.js +1 -20
- package/dist/core/shared/artifact-cleanup.d.ts +5 -0
- package/dist/core/shared/artifact-cleanup.js +89 -0
- package/dist/core/shared/tool-detection.d.ts +4 -10
- package/dist/core/shared/tool-detection.js +3 -31
- package/dist/core/shared/workflow-registry.d.ts +40 -0
- package/dist/core/shared/workflow-registry.js +19 -0
- package/dist/core/templates/types.d.ts +7 -0
- package/dist/core/templates/types.js +9 -1
- package/dist/core/templates/workflows/analyze.js +84 -84
- package/dist/core/templates/workflows/apply-change.js +291 -291
- package/dist/core/templates/workflows/archive-change.js +254 -254
- package/dist/core/templates/workflows/clarify.js +91 -91
- package/dist/core/templates/workflows/debug.js +100 -100
- package/dist/core/templates/workflows/explore.js +462 -462
- package/dist/core/templates/workflows/propose.js +199 -199
- package/dist/core/templates/workflows/quick.js +112 -112
- package/dist/core/templates/workflows/refactor.js +109 -109
- package/dist/core/templates/workflows/sync.js +148 -148
- package/dist/core/update.d.ts +1 -21
- package/dist/core/update.js +18 -117
- package/dist/core/view.js +8 -8
- package/dist/core/workspace/open-surface.d.ts +2 -2
- package/dist/core/workspace/open-surface.js +13 -13
- package/package.json +84 -76
package/dist/core/update.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import ora from 'ora';
|
|
10
|
-
import * as fs from 'fs';
|
|
11
10
|
import { createRequire } from 'module';
|
|
12
11
|
import { FileSystemUtils } from '../utils/file-system.js';
|
|
13
12
|
import { transformToHyphenCommands } from '../utils/command-references.js';
|
|
@@ -17,12 +16,14 @@ import { getToolVersionStatus, getSkillTemplates, getCommandContents, generateSk
|
|
|
17
16
|
import { detectLegacyArtifacts, cleanupLegacyArtifacts, formatCleanupSummary, formatDetectionSummary, getToolsFromLegacyArtifacts, } from './legacy-cleanup.js';
|
|
18
17
|
import { isInteractive } from '../utils/interactive.js';
|
|
19
18
|
import { getGlobalConfig } from './global-config.js';
|
|
20
|
-
import { getProfileWorkflows
|
|
19
|
+
import { getProfileWorkflows } from './profiles.js';
|
|
20
|
+
import { ALL_WORKFLOWS } from './shared/workflow-registry.js';
|
|
21
|
+
import { removeSkillDirs, removeUnselectedSkillDirs, removeCommandFiles, removeUnselectedCommandFiles, } from './shared/artifact-cleanup.js';
|
|
21
22
|
import { getAvailableTools } from './available-tools.js';
|
|
22
|
-
import {
|
|
23
|
+
import { getCommandConfiguredTools, getConfiguredToolsForProfileSync, getToolsNeedingProfileSync, } from './profile-sync-drift.js';
|
|
23
24
|
import { scanInstalledWorkflows as scanInstalledWorkflowsShared, migrateIfNeeded as migrateIfNeededShared, } from './migration.js';
|
|
24
25
|
const require = createRequire(import.meta.url);
|
|
25
|
-
const { version:
|
|
26
|
+
const { version: SYNARCX_VERSION } = require('../../package.json');
|
|
26
27
|
const OLD_CORE_WORKFLOWS = ['propose', 'explore', 'apply', 'archive'];
|
|
27
28
|
/**
|
|
28
29
|
* Scans installed workflow artifacts (skills and managed commands) across all configured tools.
|
|
@@ -43,9 +44,9 @@ export class UpdateCommand {
|
|
|
43
44
|
}
|
|
44
45
|
async execute(projectPath) {
|
|
45
46
|
const resolvedProjectPath = path.resolve(projectPath);
|
|
46
|
-
const
|
|
47
|
+
const synspecPath = path.join(resolvedProjectPath, SYNSPEC_DIR_NAME);
|
|
47
48
|
// 1. Check synspec directory exists
|
|
48
|
-
if (!await FileSystemUtils.directoryExists(
|
|
49
|
+
if (!await FileSystemUtils.directoryExists(synspecPath)) {
|
|
49
50
|
throw new Error(`No synarcx directory found. Run 'synarcx init' first.`);
|
|
50
51
|
}
|
|
51
52
|
// 2. Perform one-time migration if needed before any legacy upgrade generation.
|
|
@@ -73,7 +74,7 @@ export class UpdateCommand {
|
|
|
73
74
|
const commandConfiguredTools = getCommandConfiguredTools(resolvedProjectPath);
|
|
74
75
|
const commandConfiguredSet = new Set(commandConfiguredTools);
|
|
75
76
|
const toolStatuses = configuredTools.map((toolId) => {
|
|
76
|
-
const status = getToolVersionStatus(resolvedProjectPath, toolId,
|
|
77
|
+
const status = getToolVersionStatus(resolvedProjectPath, toolId, SYNARCX_VERSION);
|
|
77
78
|
if (!status.configured && commandConfiguredSet.has(toolId)) {
|
|
78
79
|
return { ...status, configured: true };
|
|
79
80
|
}
|
|
@@ -132,14 +133,14 @@ export class UpdateCommand {
|
|
|
132
133
|
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
133
134
|
// Use hyphen-based command references for tools where filename = command name
|
|
134
135
|
const transformer = tool.value === 'pi' ? transformToHyphenCommands : undefined;
|
|
135
|
-
const skillContent = generateSkillContent(template,
|
|
136
|
+
const skillContent = generateSkillContent(template, SYNARCX_VERSION, transformer);
|
|
136
137
|
await FileSystemUtils.writeFile(skillFile, skillContent);
|
|
137
138
|
}
|
|
138
|
-
removedDeselectedSkillCount += await
|
|
139
|
+
removedDeselectedSkillCount += await removeUnselectedSkillDirs(skillsDir, desiredWorkflows);
|
|
139
140
|
}
|
|
140
141
|
// Delete skill directories if delivery is commands-only
|
|
141
142
|
if (!shouldGenerateSkills) {
|
|
142
|
-
removedSkillCount += await
|
|
143
|
+
removedSkillCount += await removeSkillDirs(skillsDir);
|
|
143
144
|
}
|
|
144
145
|
// Generate commands if delivery includes commands
|
|
145
146
|
if (shouldGenerateCommands) {
|
|
@@ -150,12 +151,12 @@ export class UpdateCommand {
|
|
|
150
151
|
const commandFile = path.isAbsolute(cmd.path) ? cmd.path : path.join(resolvedProjectPath, cmd.path);
|
|
151
152
|
await FileSystemUtils.writeFile(commandFile, cmd.fileContent);
|
|
152
153
|
}
|
|
153
|
-
removedDeselectedCommandCount += await
|
|
154
|
+
removedDeselectedCommandCount += await removeUnselectedCommandFiles(resolvedProjectPath, toolId, desiredWorkflows);
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
// Delete command files if delivery is skills-only
|
|
157
158
|
if (!shouldGenerateCommands) {
|
|
158
|
-
removedCommandCount += await
|
|
159
|
+
removedCommandCount += await removeCommandFiles(resolvedProjectPath, toolId);
|
|
159
160
|
}
|
|
160
161
|
spinner.succeed(`Updated ${tool.name}`);
|
|
161
162
|
updatedTools.push(tool.name);
|
|
@@ -171,7 +172,7 @@ export class UpdateCommand {
|
|
|
171
172
|
// 11. Summary
|
|
172
173
|
console.log();
|
|
173
174
|
if (updatedTools.length > 0) {
|
|
174
|
-
console.log(chalk.green(`✓ Updated: ${updatedTools.join(', ')} (v${
|
|
175
|
+
console.log(chalk.green(`✓ Updated: ${updatedTools.join(', ')} (v${SYNARCX_VERSION})`));
|
|
175
176
|
}
|
|
176
177
|
if (failedTools.length > 0) {
|
|
177
178
|
console.log(chalk.red(`✗ Failed: ${failedTools.map(f => `${f.name} (${f.error})`).join(', ')}`));
|
|
@@ -215,7 +216,7 @@ export class UpdateCommand {
|
|
|
215
216
|
*/
|
|
216
217
|
displayUpToDateMessage(toolStatuses) {
|
|
217
218
|
const toolNames = toolStatuses.map((s) => s.toolId);
|
|
218
|
-
console.log(chalk.green(`✓ All ${toolStatuses.length} tool(s) up to date (v${
|
|
219
|
+
console.log(chalk.green(`✓ All ${toolStatuses.length} tool(s) up to date (v${SYNARCX_VERSION})`));
|
|
219
220
|
console.log(chalk.dim(` Tools: ${toolNames.join(', ')}`));
|
|
220
221
|
console.log();
|
|
221
222
|
console.log(chalk.dim('Use --force to refresh files anyway.'));
|
|
@@ -228,7 +229,7 @@ export class UpdateCommand {
|
|
|
228
229
|
const status = statusByTool.get(toolId);
|
|
229
230
|
if (status?.needsUpdate) {
|
|
230
231
|
const fromVersion = status.generatedByVersion ?? 'unknown';
|
|
231
|
-
return `${status.toolId} (${fromVersion} → ${
|
|
232
|
+
return `${status.toolId} (${fromVersion} → ${SYNARCX_VERSION})`;
|
|
232
233
|
}
|
|
233
234
|
return `${toolId} (config sync)`;
|
|
234
235
|
});
|
|
@@ -283,107 +284,7 @@ export class UpdateCommand {
|
|
|
283
284
|
console.log(chalk.dim('Run `synarcx config profile core` and then `synarcx update` to add sync.'));
|
|
284
285
|
}
|
|
285
286
|
/**
|
|
286
|
-
*
|
|
287
|
-
* Returns the number of directories removed.
|
|
288
|
-
*/
|
|
289
|
-
async removeSkillDirs(skillsDir) {
|
|
290
|
-
let removed = 0;
|
|
291
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
292
|
-
const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
|
|
293
|
-
if (!dirName)
|
|
294
|
-
continue;
|
|
295
|
-
const skillDir = path.join(skillsDir, dirName);
|
|
296
|
-
try {
|
|
297
|
-
if (fs.existsSync(skillDir)) {
|
|
298
|
-
await fs.promises.rm(skillDir, { recursive: true, force: true });
|
|
299
|
-
removed++;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
catch {
|
|
303
|
-
// Ignore errors
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return removed;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Removes skill directories for workflows that are no longer selected in the active profile.
|
|
310
|
-
* Returns the number of directories removed.
|
|
311
|
-
*/
|
|
312
|
-
async removeUnselectedSkillDirs(skillsDir, desiredWorkflows) {
|
|
313
|
-
const desiredSet = new Set(desiredWorkflows);
|
|
314
|
-
let removed = 0;
|
|
315
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
316
|
-
if (desiredSet.has(workflow))
|
|
317
|
-
continue;
|
|
318
|
-
const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
|
|
319
|
-
if (!dirName)
|
|
320
|
-
continue;
|
|
321
|
-
const skillDir = path.join(skillsDir, dirName);
|
|
322
|
-
try {
|
|
323
|
-
if (fs.existsSync(skillDir)) {
|
|
324
|
-
await fs.promises.rm(skillDir, { recursive: true, force: true });
|
|
325
|
-
removed++;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
catch {
|
|
329
|
-
// Ignore errors
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return removed;
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Removes command files for workflows when delivery changed to skills-only.
|
|
336
|
-
* Returns the number of files removed.
|
|
337
|
-
*/
|
|
338
|
-
async removeCommandFiles(projectPath, toolId) {
|
|
339
|
-
let removed = 0;
|
|
340
|
-
const adapter = CommandAdapterRegistry.get(toolId);
|
|
341
|
-
if (!adapter)
|
|
342
|
-
return 0;
|
|
343
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
344
|
-
const cmdPath = adapter.getFilePath(workflow);
|
|
345
|
-
const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
|
|
346
|
-
try {
|
|
347
|
-
if (fs.existsSync(fullPath)) {
|
|
348
|
-
await fs.promises.unlink(fullPath);
|
|
349
|
-
removed++;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
// Ignore errors
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return removed;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Removes command files for workflows that are no longer selected in the active profile.
|
|
360
|
-
* Returns the number of files removed.
|
|
361
|
-
*/
|
|
362
|
-
async removeUnselectedCommandFiles(projectPath, toolId, desiredWorkflows) {
|
|
363
|
-
let removed = 0;
|
|
364
|
-
const adapter = CommandAdapterRegistry.get(toolId);
|
|
365
|
-
if (!adapter)
|
|
366
|
-
return 0;
|
|
367
|
-
const desiredSet = new Set(desiredWorkflows);
|
|
368
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
369
|
-
if (desiredSet.has(workflow))
|
|
370
|
-
continue;
|
|
371
|
-
const cmdPath = adapter.getFilePath(workflow);
|
|
372
|
-
const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
|
|
373
|
-
try {
|
|
374
|
-
if (fs.existsSync(fullPath)) {
|
|
375
|
-
await fs.promises.unlink(fullPath);
|
|
376
|
-
removed++;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
catch {
|
|
380
|
-
// Ignore errors
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return removed;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Detect and handle legacy OpenSpec artifacts.
|
|
287
|
+
* Detect and handle legacy artifacts.
|
|
387
288
|
* Unlike init, update warns but continues if legacy files found in non-interactive mode.
|
|
388
289
|
* Returns array of tool IDs that were newly configured during legacy upgrade.
|
|
389
290
|
*/
|
|
@@ -523,7 +424,7 @@ export class UpdateCommand {
|
|
|
523
424
|
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
524
425
|
// Use hyphen-based command references for tools where filename = command name
|
|
525
426
|
const transformer = tool.value === 'pi' ? transformToHyphenCommands : undefined;
|
|
526
|
-
const skillContent = generateSkillContent(template,
|
|
427
|
+
const skillContent = generateSkillContent(template, SYNARCX_VERSION, transformer);
|
|
527
428
|
await FileSystemUtils.writeFile(skillFile, skillContent);
|
|
528
429
|
}
|
|
529
430
|
}
|
package/dist/core/view.js
CHANGED
|
@@ -6,16 +6,16 @@ import { MarkdownParser } from './parsers/markdown-parser.js';
|
|
|
6
6
|
import { SYNSPEC_DIR_NAME } from './config.js';
|
|
7
7
|
export class ViewCommand {
|
|
8
8
|
async execute(targetPath = '.') {
|
|
9
|
-
const
|
|
10
|
-
if (!fs.existsSync(
|
|
9
|
+
const synspecDir = path.join(targetPath, SYNSPEC_DIR_NAME);
|
|
10
|
+
if (!fs.existsSync(synspecDir)) {
|
|
11
11
|
console.error(chalk.red('No synspec directory found'));
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
14
|
console.log(chalk.bold('\nsynarcx Dashboard\n'));
|
|
15
15
|
console.log('═'.repeat(60));
|
|
16
16
|
// Get changes and specs data
|
|
17
|
-
const changesData = await this.getChangesData(
|
|
18
|
-
const specsData = await this.getSpecsData(
|
|
17
|
+
const changesData = await this.getChangesData(synspecDir);
|
|
18
|
+
const specsData = await this.getSpecsData(synspecDir);
|
|
19
19
|
// Display summary metrics
|
|
20
20
|
this.displaySummary(changesData, specsData);
|
|
21
21
|
// Display draft changes
|
|
@@ -60,8 +60,8 @@ export class ViewCommand {
|
|
|
60
60
|
console.log('\n' + '═'.repeat(60));
|
|
61
61
|
console.log(chalk.dim(`\nUse ${chalk.white('synarcx list --changes')} or ${chalk.white('synarcx list --specs')} for detailed views`));
|
|
62
62
|
}
|
|
63
|
-
async getChangesData(
|
|
64
|
-
const changesDir = path.join(
|
|
63
|
+
async getChangesData(synspecDir) {
|
|
64
|
+
const changesDir = path.join(synspecDir, 'changes');
|
|
65
65
|
if (!fs.existsSync(changesDir)) {
|
|
66
66
|
return { draft: [], active: [], completed: [] };
|
|
67
67
|
}
|
|
@@ -101,8 +101,8 @@ export class ViewCommand {
|
|
|
101
101
|
completed.sort((a, b) => a.name.localeCompare(b.name));
|
|
102
102
|
return { draft, active, completed };
|
|
103
103
|
}
|
|
104
|
-
async getSpecsData(
|
|
105
|
-
const specsDir = path.join(
|
|
104
|
+
async getSpecsData(synspecDir) {
|
|
105
|
+
const specsDir = path.join(synspecDir, 'specs');
|
|
106
106
|
if (!fs.existsSync(specsDir)) {
|
|
107
107
|
return [];
|
|
108
108
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WorkspaceLocalState, WorkspaceSharedState } from './foundation.js';
|
|
2
|
-
export declare const WORKSPACE_GUIDANCE_START_MARKER = "<!--
|
|
3
|
-
export declare const WORKSPACE_GUIDANCE_END_MARKER = "<!--
|
|
2
|
+
export declare const WORKSPACE_GUIDANCE_START_MARKER = "<!-- SYNARCX:WORKSPACE-GUIDANCE:START -->";
|
|
3
|
+
export declare const WORKSPACE_GUIDANCE_END_MARKER = "<!-- SYNARCX:WORKSPACE-GUIDANCE:END -->";
|
|
4
4
|
export declare const WORKSPACE_GUIDANCE_BODY = "# synarcx Workspace Guidance\n\nThis directory is a synarcx workspace for planning across linked repos or folders.\n\n- Use `changes/` for workspace-level planning.\n- Linked repos and folders are available for exploration and planning.\n- Repo or folder visibility supports exploration and planning.\n- Make implementation edits after the user explicitly asks for implementation work.\n- Treat linked repos and folders as the implementation homes for their owned code.\n- Use synarcx workspace commands instead of hand-editing `.synarcx-workspace/*.yaml`.";
|
|
5
5
|
export interface WorkspaceOpenLink {
|
|
6
6
|
name: string;
|
|
@@ -3,17 +3,17 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
4
4
|
import { getWorkspaceCodeWorkspacePath, getWorkspacePortableIgnorePatterns, } from './foundation.js';
|
|
5
5
|
const fs = nodeFs.promises;
|
|
6
|
-
export const WORKSPACE_GUIDANCE_START_MARKER = '<!--
|
|
7
|
-
export const WORKSPACE_GUIDANCE_END_MARKER = '<!--
|
|
8
|
-
export const WORKSPACE_GUIDANCE_BODY = `# synarcx Workspace Guidance
|
|
9
|
-
|
|
10
|
-
This directory is a synarcx workspace for planning across linked repos or folders.
|
|
11
|
-
|
|
12
|
-
- Use \`changes/\` for workspace-level planning.
|
|
13
|
-
- Linked repos and folders are available for exploration and planning.
|
|
14
|
-
- Repo or folder visibility supports exploration and planning.
|
|
15
|
-
- Make implementation edits after the user explicitly asks for implementation work.
|
|
16
|
-
- Treat linked repos and folders as the implementation homes for their owned code.
|
|
6
|
+
export const WORKSPACE_GUIDANCE_START_MARKER = '<!-- SYNARCX:WORKSPACE-GUIDANCE:START -->';
|
|
7
|
+
export const WORKSPACE_GUIDANCE_END_MARKER = '<!-- SYNARCX:WORKSPACE-GUIDANCE:END -->';
|
|
8
|
+
export const WORKSPACE_GUIDANCE_BODY = `# synarcx Workspace Guidance
|
|
9
|
+
|
|
10
|
+
This directory is a synarcx workspace for planning across linked repos or folders.
|
|
11
|
+
|
|
12
|
+
- Use \`changes/\` for workspace-level planning.
|
|
13
|
+
- Linked repos and folders are available for exploration and planning.
|
|
14
|
+
- Repo or folder visibility supports exploration and planning.
|
|
15
|
+
- Make implementation edits after the user explicitly asks for implementation work.
|
|
16
|
+
- Treat linked repos and folders as the implementation homes for their owned code.
|
|
17
17
|
- Use synarcx workspace commands instead of hand-editing \`.synarcx-workspace/*.yaml\`.`;
|
|
18
18
|
async function fileExists(filePath) {
|
|
19
19
|
try {
|
|
@@ -32,8 +32,8 @@ async function directoryExists(dirPath) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
export function buildWorkspaceGuidanceBlock() {
|
|
35
|
-
return `${WORKSPACE_GUIDANCE_START_MARKER}
|
|
36
|
-
${WORKSPACE_GUIDANCE_BODY}
|
|
35
|
+
return `${WORKSPACE_GUIDANCE_START_MARKER}
|
|
36
|
+
${WORKSPACE_GUIDANCE_BODY}
|
|
37
37
|
${WORKSPACE_GUIDANCE_END_MARKER}`;
|
|
38
38
|
}
|
|
39
39
|
export function applyWorkspaceGuidanceBlock(existingContent) {
|
package/package.json
CHANGED
|
@@ -1,76 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "synarcx",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
5
|
-
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"@
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "synarcx",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Structured engineering workflows for AI coding assistants — persistent project memory, spec-driven development, and architecture drift prevention across every session.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai-workflow",
|
|
7
|
+
"claude-code",
|
|
8
|
+
"cursor",
|
|
9
|
+
"spec-driven-development",
|
|
10
|
+
"ai-coding-assistant",
|
|
11
|
+
"architecture-drift",
|
|
12
|
+
"persistent-context",
|
|
13
|
+
"engineering-workflow",
|
|
14
|
+
"ai-coding-workflow",
|
|
15
|
+
"specification",
|
|
16
|
+
"claude-code-workflow",
|
|
17
|
+
"ai-context-management"
|
|
18
|
+
],
|
|
19
|
+
"homepage": "https://github.com/funara/synarcx",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/funara/synarcx.git"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "Adhi Rahmadian",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"bin": {
|
|
37
|
+
"synarcx": "bin/synarcx.js"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"bin",
|
|
42
|
+
"schemas",
|
|
43
|
+
"scripts/postinstall.js",
|
|
44
|
+
"!dist/**/*.test.js",
|
|
45
|
+
"!dist/**/__tests__",
|
|
46
|
+
"!dist/**/*.map"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"lint": "eslint src/",
|
|
50
|
+
"build": "node build.js",
|
|
51
|
+
"dev": "tsc --watch",
|
|
52
|
+
"dev:cli": "pnpm build && node bin/synarcx.js",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:watch": "vitest",
|
|
55
|
+
"test:ui": "vitest --ui",
|
|
56
|
+
"test:coverage": "vitest --coverage",
|
|
57
|
+
"test:postinstall": "node scripts/postinstall.js",
|
|
58
|
+
"prepare": "pnpm run build",
|
|
59
|
+
"postinstall": "node scripts/postinstall.js"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.19.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/node": "^24.2.0",
|
|
66
|
+
"@vitest/ui": "^3.2.4",
|
|
67
|
+
"eslint": "^9.39.2",
|
|
68
|
+
"typescript": "^5.9.3",
|
|
69
|
+
"typescript-eslint": "^8.50.1",
|
|
70
|
+
"vitest": "^3.2.4"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@inquirer/core": "^10.2.2",
|
|
74
|
+
"@inquirer/prompts": "^7.8.0",
|
|
75
|
+
"chalk": "^5.5.0",
|
|
76
|
+
"commander": "^14.0.0",
|
|
77
|
+
"cross-spawn": "7.0.6",
|
|
78
|
+
"fast-glob": "^3.3.3",
|
|
79
|
+
"ora": "^8.2.0",
|
|
80
|
+
"synarcx": "link:",
|
|
81
|
+
"yaml": "^2.8.2",
|
|
82
|
+
"zod": "^4.0.17"
|
|
83
|
+
}
|
|
84
|
+
}
|