archgen-skill 0.0.2 → 0.0.4
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 +29 -3
- package/bin/archgen.mjs +146 -12
- package/lib/block.js +197 -8
- package/lib/config.js +96 -0
- package/lib/doctor.js +283 -0
- package/lib/init.js +130 -27
- package/lib/install.js +105 -14
- package/lib/migrate.js +88 -0
- package/lib/migrations/001-stamp-provenance.mjs +77 -0
- package/lib/migrations/index.mjs +170 -0
- package/lib/restore.js +239 -0
- package/lib/store.js +161 -0
- package/lib/uninstall-project.js +95 -0
- package/lib/version-stamp.js +47 -0
- package/lib/version.js +23 -0
- package/package.json +37 -9
- package/vendor/skills/archgen/SKILL.md +252 -73
- package/vendor/skills/archgen/archgen.config.json +16 -0
- package/vendor/skills/archgen/assets/skill-registry.json +4 -3
- package/vendor/skills/archgen/references/artifact-templates.md +251 -7
- package/vendor/skills/archgen/references/interview.md +180 -16
- package/vendor/skills/archgen/references/mcp-and-skills.md +88 -17
- package/vendor/skills/archgen/references/orchestration.md +102 -39
- package/vendor/skills/archgen/references/platforms.md +18 -14
- package/vendor/skills/archgen/scripts/doc-index.mjs +457 -0
- package/vendor/skills/archgen/scripts/impact.mjs +14 -1
- package/vendor/skills/archgen/scripts/lib/graph.mjs +82 -3
- package/vendor/skills/archgen/scripts/lib/scope.mjs +65 -0
- package/vendor/skills/archgen/scripts/lib/yaml.mjs +19 -3
- package/vendor/skills/archgen/scripts/plan-graph.mjs +329 -0
- package/vendor/skills/archgen/scripts/set-status.mjs +26 -6
- package/vendor/skills/archgen/scripts/update-agents.mjs +204 -0
- package/vendor/skills/archgen/scripts/validate.mjs +18 -1
- package/vendor/skills/archgen/scripts/verify-plan.mjs +8 -3
package/lib/store.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// store.js — shared primitives for the single-store project layout.
|
|
2
|
+
//
|
|
3
|
+
// Layout (all paths relative to the project root):
|
|
4
|
+
// .agents/skills/archgen canonical store (the ONLY real copy)
|
|
5
|
+
// .agents/skills/archgen/.archgen-version CLI version stamp (rewritten every init)
|
|
6
|
+
// .claude/skills/archgen RELATIVE symlink -> ../../.agents/skills/archgen
|
|
7
|
+
// .archgen/.install-manifest.json manifest of everything archgen created
|
|
8
|
+
// .archgen/.backup/<timestamp>/ divergent copies moved aside before replace
|
|
9
|
+
//
|
|
10
|
+
// Safety rails:
|
|
11
|
+
// - hashDir() fingerprints a tree (stable-order walk of relpaths + contents,
|
|
12
|
+
// sha256) so mutations only ever happen after verifying ownership/divergence;
|
|
13
|
+
// - GUARDED_RELPATHS (.claude, .agents, .claude/skills, .agents/skills) are
|
|
14
|
+
// never deleted: parent pruning stops before touching those levels.
|
|
15
|
+
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
17
|
+
import {
|
|
18
|
+
cpSync,
|
|
19
|
+
existsSync,
|
|
20
|
+
lstatSync,
|
|
21
|
+
mkdirSync,
|
|
22
|
+
readFileSync,
|
|
23
|
+
readdirSync,
|
|
24
|
+
readlinkSync,
|
|
25
|
+
renameSync,
|
|
26
|
+
rmSync,
|
|
27
|
+
writeFileSync,
|
|
28
|
+
} from 'node:fs';
|
|
29
|
+
import { dirname, join } from 'node:path';
|
|
30
|
+
import { loadConfig } from './config.js';
|
|
31
|
+
|
|
32
|
+
export const STORE_REL = '.agents/skills/archgen';
|
|
33
|
+
export const CLAUDE_LINK_REL = '.claude/skills/archgen';
|
|
34
|
+
|
|
35
|
+
// Filenames routed through the canonical config (STORE_REL/CLAUDE_LINK_REL
|
|
36
|
+
// stay literal: they are path semantics, not config).
|
|
37
|
+
const CONFIG_FILES = loadConfig().files;
|
|
38
|
+
export const MANIFEST_REL = '.archgen/' + CONFIG_FILES.projectManifest;
|
|
39
|
+
export const BACKUP_ROOT_REL = '.archgen/' + CONFIG_FILES.backupDir;
|
|
40
|
+
export const VERSION_FILE = CONFIG_FILES.stamp;
|
|
41
|
+
|
|
42
|
+
const GUARDED_RELPATHS = new Set(['.claude', '.agents', '.claude/skills', '.agents/skills']);
|
|
43
|
+
|
|
44
|
+
/** Version string of this CLI package (used for the in-store stamp). */
|
|
45
|
+
export function cliVersion(packageRoot) {
|
|
46
|
+
return JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')).version;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function byName(a, b) {
|
|
50
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Stable-order directory fingerprint: sha256 over sorted relpaths plus file
|
|
55
|
+
* contents (symlinks hashed via their targets). Deterministic across machines.
|
|
56
|
+
* The version stamp is ALWAYS ignored on both sides of a comparison: it is
|
|
57
|
+
* CLI metadata written at destination time (global symlink installs stamp the
|
|
58
|
+
* shared real copy), never skill content, so it must not read as divergence.
|
|
59
|
+
* @param {string} dir absolute directory to hash
|
|
60
|
+
* @param {{ignore?: string[]}} opts EXTRA relpaths to skip
|
|
61
|
+
*/
|
|
62
|
+
export function hashDir(dir, opts = {}) {
|
|
63
|
+
const ignore = new Set([VERSION_FILE, ...(opts.ignore ?? [])]);
|
|
64
|
+
const hash = createHash('sha256');
|
|
65
|
+
(function walk(abs, rel) {
|
|
66
|
+
const entries = readdirSync(abs, { withFileTypes: true }).sort((a, b) => byName(a.name, b.name));
|
|
67
|
+
for (const ent of entries) {
|
|
68
|
+
const r = rel ? rel + '/' + ent.name : ent.name;
|
|
69
|
+
if (ignore.has(r)) continue;
|
|
70
|
+
const p = join(abs, ent.name);
|
|
71
|
+
if (ent.isSymbolicLink()) hash.update('l ' + r + ' -> ' + readlinkSync(p) + '\n');
|
|
72
|
+
else if (ent.isDirectory()) { hash.update('d ' + r + '\n'); walk(p, r); }
|
|
73
|
+
else { hash.update('f ' + r + '\0'); hash.update(readFileSync(p)); hash.update('\n'); }
|
|
74
|
+
}
|
|
75
|
+
})(dir, '');
|
|
76
|
+
return hash.digest('hex');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Load `.archgen/.install-manifest.json`; null when absent/corrupt. */
|
|
80
|
+
export function loadManifest(root) {
|
|
81
|
+
const p = join(root, ...MANIFEST_REL.split('/'));
|
|
82
|
+
if (!existsSync(p)) return null;
|
|
83
|
+
try {
|
|
84
|
+
const m = JSON.parse(readFileSync(p, 'utf8'));
|
|
85
|
+
return m && typeof m === 'object' ? m : null;
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function saveManifest(root, manifest) {
|
|
92
|
+
const p = join(root, ...MANIFEST_REL.split('/'));
|
|
93
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
94
|
+
writeFileSync(p, JSON.stringify(manifest, null, 2) + '\n');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Record a created dir/link/block; dedupes on kind+path. */
|
|
98
|
+
export function appendEntry(root, kind, relPath) {
|
|
99
|
+
const now = new Date().toISOString();
|
|
100
|
+
const m = loadManifest(root) ?? { version: 1, createdAt: now, entries: [] };
|
|
101
|
+
if (!Array.isArray(m.entries)) m.entries = [];
|
|
102
|
+
if (m.entries.some((e) => e && e.kind === kind && e.path === relPath)) return;
|
|
103
|
+
m.version = m.version ?? 1;
|
|
104
|
+
m.createdAt = m.createdAt ?? now;
|
|
105
|
+
m.entries.push({ kind, path: relPath, createdAt: now });
|
|
106
|
+
saveManifest(root, m);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Move an existing path into `<root>/<backupRootRel>/<ts>/<relPath>`, preserving
|
|
111
|
+
* the relative layout so backups restore unambiguously. Generalized core shared
|
|
112
|
+
* by the project vault (.archgen/.backup) and the global vault
|
|
113
|
+
* (<skills-dir>/.archgen-backups); `ts` can be injected so one operation lands
|
|
114
|
+
* every entry under a single timestamp.
|
|
115
|
+
* @returns {string} backup location relative to `root`
|
|
116
|
+
*/
|
|
117
|
+
export function moveToBackupInto(root, relPath, backupRootRel, ts = new Date().toISOString().replace(/:/g, '-')) {
|
|
118
|
+
const destRel = backupRootRel + '/' + ts + '/' + relPath;
|
|
119
|
+
const destAbs = join(root, ...destRel.split('/'));
|
|
120
|
+
mkdirSync(dirname(destAbs), { recursive: true });
|
|
121
|
+
const srcAbs = join(root, ...relPath.split('/'));
|
|
122
|
+
try {
|
|
123
|
+
renameSync(srcAbs, destAbs);
|
|
124
|
+
} catch {
|
|
125
|
+
cpSync(srcAbs, destAbs, { recursive: true });
|
|
126
|
+
rmSync(srcAbs, { recursive: true, force: true });
|
|
127
|
+
}
|
|
128
|
+
return destRel;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Project-root flavor: move `relPath` under `.archgen/.backup/<ts>/<relPath>`. */
|
|
132
|
+
export function moveToBackup(root, relPath) {
|
|
133
|
+
return moveToBackupInto(root, relPath, BACKUP_ROOT_REL);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function rmIfExists(absPath) {
|
|
137
|
+
let st = null;
|
|
138
|
+
try { st = lstatSync(absPath); } catch { /* absent */ }
|
|
139
|
+
if (!st) return false;
|
|
140
|
+
rmSync(absPath, { force: true, recursive: st.isDirectory() && !st.isSymbolicLink() });
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Walk UPWARD from relPath removing directories only while they are left
|
|
146
|
+
* completely empty by our removals. Stops at guarded levels and the root —
|
|
147
|
+
* `.claude`, `.agents`, `.claude/skills`, `.agents/skills` are never deleted.
|
|
148
|
+
*/
|
|
149
|
+
export function pruneEmptyParents(root, relPath) {
|
|
150
|
+
let cur = relPath;
|
|
151
|
+
while (cur && cur !== '.') {
|
|
152
|
+
if (GUARDED_RELPATHS.has(cur)) break;
|
|
153
|
+
const abs = join(root, ...cur.split('/'));
|
|
154
|
+
let empty = false;
|
|
155
|
+
try { empty = readdirSync(abs).length === 0; } catch { break; }
|
|
156
|
+
if (!empty) break;
|
|
157
|
+
rmSync(abs, { recursive: true, force: true });
|
|
158
|
+
const parent = dirname(cur);
|
|
159
|
+
cur = parent === '.' ? '' : parent;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// uninstall-project.js — `archgen uninstall --project [dir]` removal with rails.
|
|
2
|
+
//
|
|
3
|
+
// Removes exactly what archgen owns in a project: the claude symlink, the
|
|
4
|
+
// managed blocks, the canonical store (ONLY when unmodified vs the vendor
|
|
5
|
+
// skill — a customized store is kept with a warning), and the install
|
|
6
|
+
// manifest. `.archgen/<slug>` feature folders and `.archgen/.backup/` are
|
|
7
|
+
// always preserved. Parents are pruned only when left completely empty, and
|
|
8
|
+
// never past the guarded .claude/.agents levels.
|
|
9
|
+
|
|
10
|
+
import { existsSync, lstatSync, readlinkSync, rmSync, unlinkSync } from 'node:fs';
|
|
11
|
+
import { dirname, join, resolve } from 'node:path';
|
|
12
|
+
import { stripManagedFile } from './block.js';
|
|
13
|
+
import {
|
|
14
|
+
CLAUDE_LINK_REL,
|
|
15
|
+
MANIFEST_REL,
|
|
16
|
+
STORE_REL,
|
|
17
|
+
VERSION_FILE,
|
|
18
|
+
hashDir,
|
|
19
|
+
pruneEmptyParents,
|
|
20
|
+
rmIfExists,
|
|
21
|
+
} from './store.js';
|
|
22
|
+
import { resolveSkillSource } from './init.js';
|
|
23
|
+
|
|
24
|
+
function lstatSafe(p) {
|
|
25
|
+
try { return lstatSync(p); } catch { return null; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function relJoin(rel) {
|
|
29
|
+
return join(...rel.split('/'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} projectDir project root to clean
|
|
34
|
+
* @param {string} packageRoot dir containing this CLI package (vendor source)
|
|
35
|
+
* @returns {{root: string, linkRemoved: boolean, strippedBlocks: string[],
|
|
36
|
+
* storeRemoved: boolean, storeKept: boolean, manifestRemoved: boolean, warnings: string[]}}
|
|
37
|
+
*/
|
|
38
|
+
export function uninstallProject(projectDir, packageRoot) {
|
|
39
|
+
const root = resolve(projectDir);
|
|
40
|
+
const warnings = [];
|
|
41
|
+
const strippedBlocks = [];
|
|
42
|
+
|
|
43
|
+
const storeAbs = join(root, relJoin(STORE_REL));
|
|
44
|
+
const claudeAbs = join(root, relJoin(CLAUDE_LINK_REL));
|
|
45
|
+
|
|
46
|
+
// 1. Claude adapter — remove only our own symlink (dangling included).
|
|
47
|
+
let linkRemoved = false;
|
|
48
|
+
const lst = lstatSafe(claudeAbs);
|
|
49
|
+
if (lst && lst.isSymbolicLink()) {
|
|
50
|
+
const target = resolve(dirname(claudeAbs), readlinkSync(claudeAbs));
|
|
51
|
+
if (target === storeAbs || !existsSync(claudeAbs)) {
|
|
52
|
+
unlinkSync(claudeAbs); // removes the link itself, never its target
|
|
53
|
+
linkRemoved = true;
|
|
54
|
+
} else {
|
|
55
|
+
warnings.push('foreign symlink at .claude/skills/archgen - left untouched');
|
|
56
|
+
}
|
|
57
|
+
} else if (lst && lst.isDirectory()) {
|
|
58
|
+
warnings.push('.claude/skills/archgen is a real directory - left untouched (remove manually if unwanted)');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 2. Managed blocks — strip markers, keep all user content.
|
|
62
|
+
for (const name of ['AGENTS.md', 'CLAUDE.md']) {
|
|
63
|
+
if (stripManagedFile(join(root, name)).hadBlock) strippedBlocks.push(name);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 3. Canonical store — remove ONLY if unmodified vs vendor.
|
|
67
|
+
// The version stamp is our metadata, so it is ignored when comparing.
|
|
68
|
+
let storeRemoved = false;
|
|
69
|
+
let storeKept = false;
|
|
70
|
+
if (lstatSafe(storeAbs)) {
|
|
71
|
+
const st = lstatSafe(storeAbs);
|
|
72
|
+
let mine = null;
|
|
73
|
+
if (st.isDirectory() && !st.isSymbolicLink()) {
|
|
74
|
+
// An unreadable/diverging-mid-walk tree must degrade to "kept", never
|
|
75
|
+
// crash the uninstall.
|
|
76
|
+
try { mine = hashDir(storeAbs, { ignore: [VERSION_FILE] }); } catch { mine = null; }
|
|
77
|
+
}
|
|
78
|
+
let vendor = null;
|
|
79
|
+
try { vendor = hashDir(resolveSkillSource(packageRoot)); } catch { vendor = null; }
|
|
80
|
+
if (vendor !== null && mine === vendor) {
|
|
81
|
+
rmSync(storeAbs, { recursive: true, force: true });
|
|
82
|
+
storeRemoved = true;
|
|
83
|
+
} else {
|
|
84
|
+
storeKept = true;
|
|
85
|
+
warnings.push('canonical store kept at .agents/skills/archgen: modified vs vendor (or unverifiable) - review manually');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 4. Manifest file — then prune .archgen only if nothing else remains
|
|
90
|
+
// (feature folders / backups keep it alive).
|
|
91
|
+
const manifestRemoved = rmIfExists(join(root, relJoin(MANIFEST_REL)));
|
|
92
|
+
if (manifestRemoved) pruneEmptyParents(root, dirname(MANIFEST_REL));
|
|
93
|
+
|
|
94
|
+
return { root, linkRemoved, strippedBlocks, storeRemoved, storeKept, manifestRemoved, warnings };
|
|
95
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// version-stamp.js — the `.archgen-version` stamp contract.
|
|
2
|
+
//
|
|
3
|
+
// WHY: the VS Code extension reads `<skillRoot>/.archgen-version` to tell an
|
|
4
|
+
// outdated skill copy from a current one and warns non-blockingly (missing or
|
|
5
|
+
// unparseable content means "unknown (legacy)" — a pre-stamp install). The
|
|
6
|
+
// CLI is the only writer: every operation that lays down skill files (init,
|
|
7
|
+
// global install in symlink AND --copy mode, update via its init/doctor
|
|
8
|
+
// refresh) rewrites the stamp with the CLI's own package version.
|
|
9
|
+
//
|
|
10
|
+
// Format: EXACTLY `MAJOR.MINOR.PATCH\n`, utf8, no BOM. Readers elsewhere trim
|
|
11
|
+
// before validating, so CRLF/whitespace is tolerated on read — this writer
|
|
12
|
+
// never produces it. Absent file and invalid content both read as null.
|
|
13
|
+
|
|
14
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { dirname, join } from 'node:path';
|
|
16
|
+
import { VERSION_FILE } from './store.js';
|
|
17
|
+
|
|
18
|
+
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Read the stamp from a skill root (the directory containing SKILL.md).
|
|
22
|
+
* @returns {string|null} the trimmed `MAJOR.MINOR.PATCH` string, or null when
|
|
23
|
+
* the stamp is absent, unreadable, or not plain semver ("unknown").
|
|
24
|
+
*/
|
|
25
|
+
export function readStamp(skillRoot) {
|
|
26
|
+
if (!skillRoot) return null;
|
|
27
|
+
let raw;
|
|
28
|
+
try {
|
|
29
|
+
raw = readFileSync(join(skillRoot, VERSION_FILE), 'utf8');
|
|
30
|
+
} catch {
|
|
31
|
+
return null; // absent (legacy pre-stamp install) or unreadable
|
|
32
|
+
}
|
|
33
|
+
const body = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
34
|
+
const v = body.trim();
|
|
35
|
+
return SEMVER_RE.test(v) ? v : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Write/refresh the stamp inside a skill root. Idempotent: overwriting an
|
|
40
|
+
* existing stamp with the same version yields byte-identical content.
|
|
41
|
+
* Creates parent directories as needed.
|
|
42
|
+
*/
|
|
43
|
+
export function writeStamp(skillRoot, version) {
|
|
44
|
+
const p = join(skillRoot, VERSION_FILE);
|
|
45
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
46
|
+
writeFileSync(p, version + '\n', 'utf8');
|
|
47
|
+
}
|
package/lib/version.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// version.js — semver compare + npm registry lookup (zero deps).
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
export function parseSemver(v) {
|
|
5
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(String(v ?? '').trim());
|
|
6
|
+
return m ? { major: +m[1], minor: +m[2], patch: +m[3] } : null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function compareSemver(a, b) {
|
|
10
|
+
const x = parseSemver(a);
|
|
11
|
+
const y = parseSemver(b);
|
|
12
|
+
if (!x || !y) return 0;
|
|
13
|
+
for (const k of ['major', 'minor', 'patch']) {
|
|
14
|
+
if (x[k] !== y[k]) return x[k] < y[k] ? -1 : 1;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function fetchLatestVersion(pkg) {
|
|
20
|
+
const r = spawnSync('npm', ['view', pkg, 'version'], { encoding: 'utf8', timeout: 15000 });
|
|
21
|
+
if (r.status !== 0 || !r.stdout) return null;
|
|
22
|
+
return r.stdout.trim().split(/\r?\n/).pop() || null;
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "archgen-skill",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Architecture generation & autonomous task execution for coding agents - conversational requirements in, dependency-ordered tasks out, executed wave-by-wave with verifier gates. Works with Claude Code, OpenCode, Cursor, Codex, Gemini CLI and any agentskills.io harness.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
7
|
+
"bin": {
|
|
8
|
+
"archgen-skill": "bin/archgen.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"lib/",
|
|
13
|
+
"vendor/",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"ai",
|
|
21
|
+
"agents",
|
|
22
|
+
"claude",
|
|
23
|
+
"codex",
|
|
24
|
+
"cursor",
|
|
25
|
+
"opencode",
|
|
26
|
+
"gemini",
|
|
27
|
+
"architecture",
|
|
28
|
+
"skills",
|
|
29
|
+
"orchestration",
|
|
30
|
+
"task-graph",
|
|
31
|
+
"planning"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/akashmaurya99/archgen.git"
|
|
36
|
+
},
|
|
12
37
|
"homepage": "https://github.com/akashmaurya99/archgen#readme",
|
|
13
|
-
"bugs": {
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/akashmaurya99/archgen/issues"
|
|
40
|
+
},
|
|
14
41
|
"//": "vendor/skills/archgen is synced from ../skills/archgen by scripts/sync-vendor.mjs (run automatically via prepublishOnly). The extension ships separately as a VS Code vsix.",
|
|
15
42
|
"scripts": {
|
|
16
|
-
"sync": "node scripts/sync-
|
|
17
|
-
"
|
|
43
|
+
"sync:config": "node scripts/sync-config.mjs",
|
|
44
|
+
"sync": "node scripts/sync-config.mjs && node scripts/sync-vendor.mjs",
|
|
45
|
+
"prepublishOnly": "node scripts/sync-config.mjs && node scripts/sync-vendor.mjs",
|
|
18
46
|
"test": "node --test test/*.test.mjs"
|
|
19
47
|
}
|
|
20
48
|
}
|