@antomanc/aginit 0.4.0 → 0.5.0
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/CHANGELOG.md +37 -0
- package/README.md +108 -28
- package/THIRD_PARTY_NOTICES.md +92 -16
- package/dist/adapters/agent-docs.d.ts +32 -0
- package/dist/adapters/agent-docs.d.ts.map +1 -0
- package/dist/adapters/agent-docs.js +146 -0
- package/dist/adapters/agent-docs.js.map +1 -0
- package/dist/adapters/agents-md.d.ts +13 -1
- package/dist/adapters/agents-md.d.ts.map +1 -1
- package/dist/adapters/agents-md.js +137 -120
- package/dist/adapters/agents-md.js.map +1 -1
- package/dist/adapters/e2e.d.ts +15 -0
- package/dist/adapters/e2e.d.ts.map +1 -0
- package/dist/adapters/e2e.js +55 -0
- package/dist/adapters/e2e.js.map +1 -0
- package/dist/adapters/skills.d.ts +5 -0
- package/dist/adapters/skills.d.ts.map +1 -1
- package/dist/adapters/skills.js +17 -0
- package/dist/adapters/skills.js.map +1 -1
- package/dist/adapters/tool-ignores.d.ts +9 -0
- package/dist/adapters/tool-ignores.d.ts.map +1 -0
- package/dist/adapters/tool-ignores.js +121 -0
- package/dist/adapters/tool-ignores.js.map +1 -0
- package/dist/cli/capabilities.d.ts +17 -0
- package/dist/cli/capabilities.d.ts.map +1 -0
- package/dist/cli/capabilities.js +149 -0
- package/dist/cli/capabilities.js.map +1 -0
- package/dist/cli/doctor.d.ts +16 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +104 -70
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +123 -20
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/new.d.ts +15 -1
- package/dist/cli/new.d.ts.map +1 -1
- package/dist/cli/new.js +163 -67
- package/dist/cli/new.js.map +1 -1
- package/dist/cli/wizard.d.ts +5 -0
- package/dist/cli/wizard.d.ts.map +1 -1
- package/dist/cli/wizard.js +104 -102
- package/dist/cli/wizard.js.map +1 -1
- package/dist/config/defaults.d.ts +14 -6
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +38 -174
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +14 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/validation.d.ts +1 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +63 -0
- package/dist/config/validation.js.map +1 -1
- package/dist/detect/index.d.ts +18 -0
- package/dist/detect/index.d.ts.map +1 -0
- package/dist/detect/index.js +120 -0
- package/dist/detect/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/presets/cli.d.ts.map +1 -1
- package/dist/presets/cli.js +7 -0
- package/dist/presets/cli.js.map +1 -1
- package/dist/presets/generic.d.ts.map +1 -1
- package/dist/presets/generic.js +4 -1
- package/dist/presets/generic.js.map +1 -1
- package/dist/presets/testing.d.ts +1 -1
- package/dist/presets/testing.d.ts.map +1 -1
- package/dist/presets/testing.js +22 -8
- package/dist/presets/testing.js.map +1 -1
- package/dist/presets/web.d.ts.map +1 -1
- package/dist/presets/web.js +39 -5
- package/dist/presets/web.js.map +1 -1
- package/dist/registry/catalog.d.ts +13 -0
- package/dist/registry/catalog.d.ts.map +1 -0
- package/dist/registry/catalog.js +544 -0
- package/dist/registry/catalog.js.map +1 -0
- package/dist/registry/index.d.ts +84 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +309 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/setup.d.ts +14 -0
- package/dist/registry/setup.d.ts.map +1 -0
- package/dist/registry/setup.js +25 -0
- package/dist/registry/setup.js.map +1 -0
- package/dist/registry/types.d.ts +115 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +2 -0
- package/dist/registry/types.js.map +1 -0
- package/package.json +3 -2
- package/src/adapters/agent-docs.ts +184 -0
- package/src/adapters/agents-md.ts +160 -137
- package/src/adapters/e2e.ts +58 -0
- package/src/adapters/skills.ts +18 -0
- package/src/adapters/tool-ignores.ts +158 -0
- package/src/cli/capabilities.ts +176 -0
- package/src/cli/doctor.ts +100 -66
- package/src/cli/init.ts +1 -1
- package/src/cli/main.ts +130 -20
- package/src/cli/new.ts +199 -73
- package/src/cli/wizard.ts +130 -103
- package/src/config/defaults.ts +57 -179
- package/src/config/schema.ts +15 -0
- package/src/config/validation.ts +56 -0
- package/src/detect/index.ts +134 -0
- package/src/index.ts +5 -0
- package/src/presets/cli.ts +6 -0
- package/src/presets/generic.ts +4 -1
- package/src/presets/testing.ts +29 -12
- package/src/presets/web.ts +39 -5
- package/src/registry/catalog.ts +569 -0
- package/src/registry/index.ts +395 -0
- package/src/registry/setup.ts +40 -0
- package/src/registry/types.ts +109 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileExists, readTextFile, safeWriteFile } from '../utils/fs.js';
|
|
3
|
+
import { readPackageManifest } from '../config/validation.js';
|
|
4
|
+
// Vendored skill sources ship third-party JS and Markdown that the project's own
|
|
5
|
+
// linters and formatters must not check. No ignore convention is shared across tools,
|
|
6
|
+
// so each tool below says where its ignores live and how to add to them.
|
|
7
|
+
const VENDORED_DIRS = ['.agents', '.claude'];
|
|
8
|
+
const configs = (base, extensions) => extensions.map((ext) => `${base}${ext}`);
|
|
9
|
+
/** Gitignore-syntax files: append the directories. */
|
|
10
|
+
function ignoreFile(name, used) {
|
|
11
|
+
return {
|
|
12
|
+
file: (project) => (used(project) ? name : undefined),
|
|
13
|
+
missing: (text) => {
|
|
14
|
+
const lines = text.split(/\r?\n/).map((line) => line.trim().replace(/^\/|\/(\*\*)?$/g, ''));
|
|
15
|
+
return VENDORED_DIRS.filter((dir) => !lines.includes(dir));
|
|
16
|
+
},
|
|
17
|
+
patch: (text, dirs) => {
|
|
18
|
+
const block = `# Vendored agent skills (aginit)\n${dirs.map((dir) => `${dir}/`).join('\n')}\n`;
|
|
19
|
+
return text.trim() ? `${text.trimEnd()}\n\n${block}` : block;
|
|
20
|
+
},
|
|
21
|
+
advice: (file, dirs) => `add ${dirs.map((dir) => `${dir}/`).join(' and ')} to ${file}`
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const prettier = ignoreFile('.prettierignore', (project) => project.has('prettier') ||
|
|
25
|
+
Boolean(project.manifest?.prettier) ||
|
|
26
|
+
[
|
|
27
|
+
...configs('.prettierrc', ['', '.json', '.json5', '.yaml', '.yml', '.toml']),
|
|
28
|
+
...configs('.prettierrc', ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts']),
|
|
29
|
+
...configs('prettier.config', ['.js', '.cjs', '.mjs', '.ts', '.cts', '.mts'])
|
|
30
|
+
].some(project.exists));
|
|
31
|
+
// Legacy ESLint and oxlint read .eslintignore; flat-config ESLint does not.
|
|
32
|
+
const eslintIgnore = ignoreFile('.eslintignore', (project) => project.has('oxlint') ||
|
|
33
|
+
Boolean(project.manifest?.eslintConfig) ||
|
|
34
|
+
configs('.eslintrc', ['', '.js', '.cjs', '.json', '.yaml', '.yml']).some(project.exists));
|
|
35
|
+
/** Flat ESLint config: extend a global ignores array if there is an unambiguous one,
|
|
36
|
+
* `globalIgnores([...])` or an object holding only `ignores`. */
|
|
37
|
+
const eslintFlat = {
|
|
38
|
+
file: (project) => configs('eslint.config', ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts']).find(project.exists),
|
|
39
|
+
missing: (text) => VENDORED_DIRS.filter((dir) => !text.includes(`${dir}/`)),
|
|
40
|
+
patch: (text, dirs) => {
|
|
41
|
+
const match = /globalIgnores\(\s*\[/.exec(text) ??
|
|
42
|
+
/\{\s*ignores\s*:\s*\[(?=[^[\]]*\]\s*,?\s*\})/.exec(text);
|
|
43
|
+
if (!match)
|
|
44
|
+
return null;
|
|
45
|
+
const at = match.index + match[0].length;
|
|
46
|
+
const rest = text.slice(at);
|
|
47
|
+
const quote = /^\s*(['"`])/.exec(rest)?.[1] ??
|
|
48
|
+
((text.match(/"/g)?.length ?? 0) > (text.match(/'/g)?.length ?? 0) ? '"' : "'");
|
|
49
|
+
const entries = dirs.map((dir) => `${quote}${dir}/**${quote}`);
|
|
50
|
+
const indent = /^(\s*\n[ \t]*)/.exec(rest)?.[1];
|
|
51
|
+
const insertion = indent
|
|
52
|
+
? entries.map((entry) => `${indent}${entry},`).join('')
|
|
53
|
+
: entries.join(', ') + (/^\s*\]/.test(rest) ? '' : ', ');
|
|
54
|
+
return text.slice(0, at) + insertion + rest;
|
|
55
|
+
},
|
|
56
|
+
advice: (file, dirs) => `add { ignores: [${dirs.map((dir) => `'${dir}/**'`).join(', ')}] } to the exported array in ${file}`
|
|
57
|
+
};
|
|
58
|
+
/** Biome 2.2+: force-ignore the folders through files.includes. */
|
|
59
|
+
const biome = {
|
|
60
|
+
file: (project) => ['biome.json', 'biome.jsonc'].find(project.exists),
|
|
61
|
+
missing: (text) => VENDORED_DIRS.filter((dir) => !text.includes(`**/${dir}`)),
|
|
62
|
+
patch: (text, dirs) => {
|
|
63
|
+
let config;
|
|
64
|
+
try {
|
|
65
|
+
config = JSON.parse(text); // a biome.jsonc with comments gets advice instead
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const includes = config.files?.includes ?? ['**'];
|
|
71
|
+
if (!Array.isArray(includes))
|
|
72
|
+
return null;
|
|
73
|
+
config.files = {
|
|
74
|
+
...config.files,
|
|
75
|
+
includes: [...includes, ...dirs.map((dir) => `!!**/${dir}`)]
|
|
76
|
+
};
|
|
77
|
+
const json = JSON.stringify(config, null, /\n([ \t]+)"/.exec(text)?.[1] ?? 2) + '\n';
|
|
78
|
+
// Like Biome's formatter, keep the array on one line when it fits in 80 columns.
|
|
79
|
+
return json.replace(/^([ \t]*"includes": )\[[^\]]*\]/m, (block, key) => {
|
|
80
|
+
const inline = `${key}[${config.files.includes.map((p) => JSON.stringify(p)).join(', ')}]`;
|
|
81
|
+
return inline.replace(/\t/g, ' ').length <= 80 ? inline : block;
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
advice: (file, dirs) => `add ${dirs.map((dir) => `"!!**/${dir}"`).join(', ')} to files.includes in ${file}`
|
|
85
|
+
};
|
|
86
|
+
const TOOLS = [prettier, eslintIgnore, eslintFlat, biome];
|
|
87
|
+
function pendingIgnores(targetDir) {
|
|
88
|
+
const manifest = readPackageManifest(targetDir);
|
|
89
|
+
const project = {
|
|
90
|
+
manifest,
|
|
91
|
+
has: (name) => Boolean(manifest?.dependencies?.[name] || manifest?.devDependencies?.[name]),
|
|
92
|
+
exists: (file) => fileExists(path.join(targetDir, file))
|
|
93
|
+
};
|
|
94
|
+
return TOOLS.flatMap((tool) => {
|
|
95
|
+
const file = tool.file(project);
|
|
96
|
+
if (!file)
|
|
97
|
+
return [];
|
|
98
|
+
const text = readTextFile(path.join(targetDir, file)) ?? '';
|
|
99
|
+
const missing = tool.missing(text);
|
|
100
|
+
return missing.length > 0 ? [{ tool, file, text, missing }] : [];
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** Keeps the project's linters and formatters off vendored skills. Returns the
|
|
104
|
+
* advice for configs that could not be edited safely. */
|
|
105
|
+
export function ignoreVendoredSkills(targetDir, options = {}) {
|
|
106
|
+
const { dryRun = false, silent = false } = options;
|
|
107
|
+
const advice = [];
|
|
108
|
+
for (const { tool, file, text, missing } of pendingIgnores(targetDir)) {
|
|
109
|
+
const patched = tool.patch(text, missing);
|
|
110
|
+
if (patched === null)
|
|
111
|
+
advice.push(`Linters check vendored skills: ${tool.advice(file, missing)}`);
|
|
112
|
+
else
|
|
113
|
+
safeWriteFile(path.join(targetDir, file), patched, { overwrite: true, dryRun, silent });
|
|
114
|
+
}
|
|
115
|
+
return advice;
|
|
116
|
+
}
|
|
117
|
+
/** Doctor view: every config that still lets a linter or formatter see vendored skills. */
|
|
118
|
+
export function vendoredSkillsExposure(targetDir) {
|
|
119
|
+
return pendingIgnores(targetDir).map(({ tool, file, missing }) => tool.advice(file, missing));
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=tool-ignores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-ignores.js","sourceRoot":"","sources":["../../src/adapters/tool-ignores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Print the registry grouped by category, marking what the project has enabled. */
|
|
2
|
+
export declare function listCapabilities(targetDir?: string): void;
|
|
3
|
+
export interface ChangeOptions {
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
silent?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Enable or disable capabilities, then bring the project in line: config,
|
|
9
|
+
* skills (installed or removed through the Skills CLI), upstream setups,
|
|
10
|
+
* AGENTS.md and docs/agents/. Picking a methodology, design or UI driver
|
|
11
|
+
* replaces the current one in that category.
|
|
12
|
+
*/
|
|
13
|
+
export declare function changeCapabilities(targetDir: string, change: {
|
|
14
|
+
add?: string[];
|
|
15
|
+
remove?: string[];
|
|
16
|
+
}, options?: ChangeOptions): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/cli/capabilities.ts"],"names":[],"mappings":"AAoCA,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,MAAsB,GAAG,IAAI,CAoBxE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAeD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAC7C,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAwFlB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { AGINIT_CONFIG_FILENAME } from '../config/schema.js';
|
|
4
|
+
import { readProjectConfig, validateConfig } from '../config/validation.js';
|
|
5
|
+
import { resolvePlatformStack } from '../adapters/agent-docs.js';
|
|
6
|
+
import { installAllSkills, removeSkills, skillAgents } from '../adapters/skills.js';
|
|
7
|
+
import { uninstallGraft } from '../adapters/graft.js';
|
|
8
|
+
import { ignoreVendoredSkills } from '../adapters/tool-ignores.js';
|
|
9
|
+
import { activeIds, applyResolvedProfile, catalogFor, findCapability, inferCapabilities, resolveCapabilities, sourcesFor } from '../registry/index.js';
|
|
10
|
+
import { SETUPS } from '../registry/setup.js';
|
|
11
|
+
import { writeJsonFile } from '../utils/fs.js';
|
|
12
|
+
import { logger } from '../utils/logger.js';
|
|
13
|
+
import { missingBinaries, syncAgentDocs } from './new.js';
|
|
14
|
+
const CATEGORY_ORDER = [
|
|
15
|
+
'codebase-graph',
|
|
16
|
+
'methodology',
|
|
17
|
+
'discipline',
|
|
18
|
+
'design',
|
|
19
|
+
'ui-driver',
|
|
20
|
+
'testing-engine',
|
|
21
|
+
'context-guard',
|
|
22
|
+
'custom'
|
|
23
|
+
];
|
|
24
|
+
/** Print the registry grouped by category, marking what the project has enabled. */
|
|
25
|
+
export function listCapabilities(targetDir = process.cwd()) {
|
|
26
|
+
const config = readProjectConfig(targetDir);
|
|
27
|
+
const enabled = config ? activeIds(config) : new Set();
|
|
28
|
+
logger.banner('Aginit — Capability registry', config ? `Enabled in ${AGINIT_CONFIG_FILENAME}: ●` : `No ${AGINIT_CONFIG_FILENAME} here; showing the catalog`);
|
|
29
|
+
const catalog = catalogFor(config);
|
|
30
|
+
for (const category of CATEGORY_ORDER) {
|
|
31
|
+
const entries = catalog.filter((c) => c.category === category);
|
|
32
|
+
if (entries.length === 0)
|
|
33
|
+
continue;
|
|
34
|
+
console.log(pc.bold(pc.underline(category)));
|
|
35
|
+
for (const c of entries) {
|
|
36
|
+
const mark = enabled.has(c.id) ? pc.green('●') : pc.dim('○');
|
|
37
|
+
const platforms = c.supportedPlatforms.join(', ');
|
|
38
|
+
console.log(` ${mark} ${pc.bold(c.id.padEnd(22))} ${c.description}`);
|
|
39
|
+
console.log(pc.dim(` ${platforms} · ${c.license} · ${c.repoUrl}`));
|
|
40
|
+
}
|
|
41
|
+
console.log();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function requireConfig(targetDir) {
|
|
45
|
+
const config = readProjectConfig(targetDir);
|
|
46
|
+
if (!config)
|
|
47
|
+
throw new Error(`No ${AGINIT_CONFIG_FILENAME} in ${targetDir}. Run \`aginit init\` first.`);
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
/** Skill names to remove; a source installed whole is removed by its repo. */
|
|
51
|
+
const skillsOf = (capabilities) => capabilities.flatMap((c) => c.install.flatMap((s) => (s.kind !== 'skills-sh' ? [] : s.skills.length ? s.skills : [s.repo])));
|
|
52
|
+
/**
|
|
53
|
+
* Enable or disable capabilities, then bring the project in line: config,
|
|
54
|
+
* skills (installed or removed through the Skills CLI), upstream setups,
|
|
55
|
+
* AGENTS.md and docs/agents/. Picking a methodology, design or UI driver
|
|
56
|
+
* replaces the current one in that category.
|
|
57
|
+
*/
|
|
58
|
+
export async function changeCapabilities(targetDir, change, options = {}) {
|
|
59
|
+
const { dryRun = false, silent = false } = options;
|
|
60
|
+
const config = requireConfig(targetDir);
|
|
61
|
+
const { platform, stack } = resolvePlatformStack(config, targetDir);
|
|
62
|
+
const base = config.capabilities ?? inferCapabilities(config);
|
|
63
|
+
const previous = [...base, ...(config.customCapabilities ?? []).map((c) => c.id)];
|
|
64
|
+
const before = activeIds(config);
|
|
65
|
+
const flags = { addons: [], addSkills: [], without: [] };
|
|
66
|
+
for (const id of change.add ?? []) {
|
|
67
|
+
const capability = findCapability(id, config);
|
|
68
|
+
if (!capability) {
|
|
69
|
+
if (id.includes('/'))
|
|
70
|
+
flags.addSkills.push(id);
|
|
71
|
+
else
|
|
72
|
+
throw new Error(`Unknown capability "${id}". Run \`aginit list\` to see the registry.`);
|
|
73
|
+
}
|
|
74
|
+
else if (capability.category === 'methodology')
|
|
75
|
+
flags.methodology = id;
|
|
76
|
+
else if (capability.category === 'design')
|
|
77
|
+
flags.design = id;
|
|
78
|
+
else if (capability.category === 'ui-driver' && !capability.addon)
|
|
79
|
+
flags.uiDriver = id;
|
|
80
|
+
else
|
|
81
|
+
flags.addons.push(id);
|
|
82
|
+
}
|
|
83
|
+
for (const id of change.remove ?? []) {
|
|
84
|
+
if (!findCapability(id, config))
|
|
85
|
+
throw new Error(`Unknown capability "${id}". Run \`aginit list\` to see the registry.`);
|
|
86
|
+
flags.without.push(id);
|
|
87
|
+
}
|
|
88
|
+
const custom = config.customCapabilities ?? [];
|
|
89
|
+
const customIds = new Set(custom.map((c) => c.id));
|
|
90
|
+
const disabled = (config.disabledCapabilities ?? []).filter((id) => !(change.add ?? []).includes(id));
|
|
91
|
+
const resolved = resolveCapabilities({ platform, stack, framework: config.framework, base, basePlatform: platform, flags, custom }, disabled);
|
|
92
|
+
// A removed custom capability is gone, not disabled.
|
|
93
|
+
resolved.disabledCapabilities = resolved.disabledCapabilities.filter((id) => !customIds.has(id));
|
|
94
|
+
const next = validateConfig(applyResolvedProfile({ ...config, platform, stack }, resolved, { skills: true, previous }));
|
|
95
|
+
// Adding graft or playwright turns their legacy switch back on.
|
|
96
|
+
if (next.capabilities?.includes('graft'))
|
|
97
|
+
next.codebase.graft = true;
|
|
98
|
+
const after = activeIds(next);
|
|
99
|
+
const nextCatalog = catalogFor(next);
|
|
100
|
+
const added = nextCatalog.filter((c) => after.has(c.id) && !before.has(c.id));
|
|
101
|
+
const removed = catalogFor(config).filter((c) => before.has(c.id) && !after.has(c.id));
|
|
102
|
+
if (added.length === 0 && removed.length === 0 && JSON.stringify(next) === JSON.stringify(config)) {
|
|
103
|
+
if (!silent)
|
|
104
|
+
logger.info('Nothing to change.');
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (!silent) {
|
|
108
|
+
for (const c of added)
|
|
109
|
+
logger.success(`Enabling ${c.id}`);
|
|
110
|
+
for (const c of removed)
|
|
111
|
+
logger.warn(`Disabling ${c.id}`);
|
|
112
|
+
}
|
|
113
|
+
writeJsonFile(path.join(targetDir, AGINIT_CONFIG_FILENAME), next, { overwrite: true, dryRun, silent });
|
|
114
|
+
let ok = true;
|
|
115
|
+
ok = (await removeSkills(targetDir, skillsOf(removed), { dryRun, silent })) && ok;
|
|
116
|
+
if (removed.some((c) => c.id === 'graft'))
|
|
117
|
+
await uninstallGraft(targetDir, { dryRun, silent });
|
|
118
|
+
const leftovers = removed.filter((c) => c.install.some((s) => s.kind === 'setup' && s.setup !== 'graft'));
|
|
119
|
+
if (!silent)
|
|
120
|
+
for (const c of leftovers)
|
|
121
|
+
logger.dim(`${c.id}: files and global CLIs its setup created are left in place; remove them by hand.`);
|
|
122
|
+
const addedSources = sourcesFor(added);
|
|
123
|
+
if (addedSources.length > 0) {
|
|
124
|
+
const { failed } = await installAllSkills(targetDir, addedSources, {
|
|
125
|
+
agents: skillAgents(next),
|
|
126
|
+
dryRun,
|
|
127
|
+
silent
|
|
128
|
+
});
|
|
129
|
+
ok = failed.length === 0 && ok;
|
|
130
|
+
for (const line of ignoreVendoredSkills(targetDir, { dryRun, silent: true }))
|
|
131
|
+
logger.warn(line);
|
|
132
|
+
}
|
|
133
|
+
for (const c of added)
|
|
134
|
+
for (const step of c.install)
|
|
135
|
+
if (step.kind === 'setup')
|
|
136
|
+
ok = (await SETUPS[step.setup]({ targetDir, config: next, platform, stack, dryRun, silent })) && ok;
|
|
137
|
+
syncAgentDocs(targetDir, next, { dryRun, silent });
|
|
138
|
+
if (!silent)
|
|
139
|
+
for (const { name, bin, install } of await missingBinaries(added, ['graft', 'agent-browser', 'e2e']))
|
|
140
|
+
logger.warn(`${name} needs the \`${bin}\` CLI: ${install}`);
|
|
141
|
+
if (!silent) {
|
|
142
|
+
if (ok)
|
|
143
|
+
logger.success('Capabilities updated. AGENTS.md and docs/agents/ are in sync.');
|
|
144
|
+
else
|
|
145
|
+
logger.warn('Capabilities updated with warnings. Resolve them and rerun `aginit init`.');
|
|
146
|
+
}
|
|
147
|
+
return ok;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/cli/capabilities.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/doctor.d.ts
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
|
+
import { AginitConfig } from '../config/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* One row per active capability, built from its registry entry: every skill
|
|
4
|
+
* file it installs, every CLI it drives and any artifact it declares.
|
|
5
|
+
*/
|
|
6
|
+
export declare function capabilityChecks(targetDir: string, config: AginitConfig): Promise<CheckItem[]>;
|
|
7
|
+
type CheckCategory = 'Environment' | 'AI Tooling' | 'Project Config' | 'Capabilities';
|
|
8
|
+
interface CheckItem {
|
|
9
|
+
name: string;
|
|
10
|
+
category: CheckCategory;
|
|
11
|
+
ok: boolean;
|
|
12
|
+
version?: string;
|
|
13
|
+
detail: string;
|
|
14
|
+
suggestion?: string;
|
|
15
|
+
}
|
|
1
16
|
export declare function runDoctor(targetDir?: string): Promise<void>;
|
|
17
|
+
export {};
|
|
2
18
|
//# sourceMappingURL=doctor.d.ts.map
|
package/dist/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,YAAY,EAEb,MAAM,qBAAqB,CAAC;AAoB7B;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqCtB;AAED,KAAK,aAAa,GAAG,aAAa,GAAG,YAAY,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEtF,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,SAAS,CAAC,SAAS,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ThF"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -7,9 +7,58 @@ import { detectPackageManager } from '../adapters/package-manager.js';
|
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import { claudeCodeEnabled, getInstalledSkills, getSkillsMissingForClaude } from '../adapters/skills.js';
|
|
9
9
|
import { claudeMarkdownImportsAgents } from '../adapters/agents-md.js';
|
|
10
|
-
import {
|
|
10
|
+
import { agentBrowserStubInstalled, findUsernsRestriction, runAgentBrowserDiagnostics } from '../adapters/agent-browser.js';
|
|
11
11
|
import { readProjectConfig } from '../config/validation.js';
|
|
12
|
+
import { vendoredSkillsExposure } from '../adapters/tool-ignores.js';
|
|
12
13
|
import { logger } from '../utils/logger.js';
|
|
14
|
+
import { activeCapabilities, activeIds, doctorChecks, isNodeStack } from '../registry/index.js';
|
|
15
|
+
import { resolvePlatformStack } from '../adapters/agent-docs.js';
|
|
16
|
+
/**
|
|
17
|
+
* One row per active capability, built from its registry entry: every skill
|
|
18
|
+
* file it installs, every CLI it drives and any artifact it declares.
|
|
19
|
+
*/
|
|
20
|
+
export async function capabilityChecks(targetDir, config) {
|
|
21
|
+
const items = [];
|
|
22
|
+
for (const capability of activeCapabilities(config)) {
|
|
23
|
+
const problems = [];
|
|
24
|
+
const fixes = [];
|
|
25
|
+
const missingSkills = [];
|
|
26
|
+
const versions = [];
|
|
27
|
+
for (const check of doctorChecks(capability, config.skills.sources)) {
|
|
28
|
+
if (check.kind === 'file') {
|
|
29
|
+
if (fileExists(path.join(targetDir, check.path)))
|
|
30
|
+
continue;
|
|
31
|
+
const skill = /^\.agents\/skills\/([^/]+)\/SKILL\.md$/.exec(check.path)?.[1];
|
|
32
|
+
if (skill)
|
|
33
|
+
missingSkills.push(skill);
|
|
34
|
+
else {
|
|
35
|
+
problems.push(`${check.path} missing`);
|
|
36
|
+
fixes.push(check.fix);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (!(await commandExists(check.bin))) {
|
|
40
|
+
problems.push(`${check.bin} CLI not found in PATH`);
|
|
41
|
+
fixes.push(check.fix);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const res = await runExecutable(check.bin, check.args, { silent: true, timeout: 30_000 });
|
|
45
|
+
versions.push(res.ok && res.stdout ? `${check.bin} ${res.stdout.split('\n')[0]}` : check.bin);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (missingSkills.length) {
|
|
49
|
+
problems.unshift(`skills missing from .agents/skills/: ${missingSkills.join(', ')}`);
|
|
50
|
+
fixes.unshift('Run `aginit init` to reinstall the configured skills');
|
|
51
|
+
}
|
|
52
|
+
items.push({
|
|
53
|
+
name: `${capability.name} (${capability.category})`,
|
|
54
|
+
category: 'Capabilities',
|
|
55
|
+
ok: problems.length === 0,
|
|
56
|
+
detail: problems.length ? problems.join('; ') : `Ready${versions.length ? ` (${versions.join(', ')})` : ''}`,
|
|
57
|
+
suggestion: fixes.length ? fixes.join(' · ') : undefined
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return items;
|
|
61
|
+
}
|
|
13
62
|
export async function runDoctor(targetDir = process.cwd()) {
|
|
14
63
|
logger.banner('Aginit — System & Project Doctor', `Target: ${targetDir}`);
|
|
15
64
|
// Resolve project config early to detect configured package manager
|
|
@@ -58,18 +107,24 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
58
107
|
detail: nodeDetail,
|
|
59
108
|
suggestion: nodeSuggestion
|
|
60
109
|
});
|
|
61
|
-
// 2. Active Package Manager check (pnpm, npm, yarn, or bun)
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
:
|
|
72
|
-
|
|
110
|
+
// 2. Active Package Manager check (pnpm, npm, yarn, or bun); none for non-Node stacks
|
|
111
|
+
const { stack, platform } = projectConfig
|
|
112
|
+
? resolvePlatformStack(projectConfig, targetDir)
|
|
113
|
+
: { stack: 'node', platform: null };
|
|
114
|
+
const pmRes = isNodeStack(stack)
|
|
115
|
+
? await runExecutable(activePm, ['-v'], { silent: true })
|
|
116
|
+
: null;
|
|
117
|
+
if (pmRes)
|
|
118
|
+
checks.push({
|
|
119
|
+
name: `${activePm} package manager`,
|
|
120
|
+
category: 'Environment',
|
|
121
|
+
ok: pmRes.ok,
|
|
122
|
+
version: pmRes.stdout,
|
|
123
|
+
detail: pmRes.ok ? `Installed (${pmRes.stdout})` : `${activePm} is not found in PATH`,
|
|
124
|
+
suggestion: pmRes.ok
|
|
125
|
+
? undefined
|
|
126
|
+
: `Install ${activePm} (${activePm === 'pnpm' ? 'npm install -g pnpm' : activePm === 'bun' ? 'curl -fsSL https://bun.sh/install | bash' : 'install ' + activePm})`
|
|
127
|
+
});
|
|
73
128
|
// 3. Git check
|
|
74
129
|
const gitExists = await commandExists('git');
|
|
75
130
|
let isGitRepo = fileExists(path.join(targetDir, '.git'));
|
|
@@ -101,21 +156,6 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
101
156
|
? 'Run `git init` or `aginit init` to initialize repository'
|
|
102
157
|
: undefined
|
|
103
158
|
});
|
|
104
|
-
// 4. Graft CLI check
|
|
105
|
-
const graftExists = await commandExists('graft');
|
|
106
|
-
let graftVersion = '';
|
|
107
|
-
if (graftExists) {
|
|
108
|
-
const gv = await runExecutable('graft', ['--version'], { silent: true });
|
|
109
|
-
graftVersion = gv.stdout;
|
|
110
|
-
}
|
|
111
|
-
checks.push({
|
|
112
|
-
name: 'Graft codebase graph CLI',
|
|
113
|
-
category: 'AI Tooling',
|
|
114
|
-
ok: graftExists,
|
|
115
|
-
version: graftVersion,
|
|
116
|
-
detail: graftExists ? `Installed globally (${graftVersion})` : 'Graft CLI not found in PATH',
|
|
117
|
-
suggestion: graftExists ? undefined : 'Install Graft: `npm install -g @nanonets/graft`'
|
|
118
|
-
});
|
|
119
159
|
// 5. Codex CLI check
|
|
120
160
|
const codexExists = await commandExists('codex');
|
|
121
161
|
checks.push({
|
|
@@ -141,7 +181,7 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
141
181
|
category: 'Project Config',
|
|
142
182
|
ok: !!projectConfig,
|
|
143
183
|
detail: projectConfig
|
|
144
|
-
? `Preset: "${projectConfig.preset}" (v${projectConfig.schemaVersion || '1.0.0'}), pm: ${activePm}, agents: ${projectConfig.agents.primary}/${projectConfig.agents.secondary}${claudeCodeEnabled(projectConfig) ? '/claude-code' : ''}`
|
|
184
|
+
? `Preset: "${projectConfig.preset}" (v${projectConfig.schemaVersion || '1.0.0'}), platform: ${platform} (${stack})${pmRes ? `, pm: ${activePm}` : ''}, agents: ${projectConfig.agents.primary}/${projectConfig.agents.secondary}${claudeCodeEnabled(projectConfig) ? '/claude-code' : ''}`
|
|
145
185
|
: configError
|
|
146
186
|
? `Invalid configuration: ${configError}`
|
|
147
187
|
: 'No aginit.config.json found in current directory',
|
|
@@ -187,6 +227,19 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
187
227
|
? undefined
|
|
188
228
|
: 'Run `aginit init` or `npx skills add ...` to install skills'
|
|
189
229
|
});
|
|
230
|
+
// 9a. Vendored skills must stay out of the project's linters and formatters
|
|
231
|
+
if (installedSkills.length > 0) {
|
|
232
|
+
const exposure = vendoredSkillsExposure(targetDir);
|
|
233
|
+
checks.push({
|
|
234
|
+
name: 'Lint/format ignores for vendored skills',
|
|
235
|
+
category: 'Project Config',
|
|
236
|
+
ok: exposure.length === 0,
|
|
237
|
+
detail: exposure.length === 0
|
|
238
|
+
? 'Detected linters and formatters skip .agents/ and .claude/'
|
|
239
|
+
: 'Project linters or formatters will check vendored skill files',
|
|
240
|
+
suggestion: exposure.length === 0 ? undefined : `Run \`aginit update\`, or ${exposure.join('; ')}`
|
|
241
|
+
});
|
|
242
|
+
}
|
|
190
243
|
// 9b. Claude Code: skills linked into .claude/skills/ and AGENTS.md reachable
|
|
191
244
|
if (projectConfig !== null && claudeCodeEnabled(projectConfig)) {
|
|
192
245
|
if (!skillsDisabled && installedSkills.length > 0) {
|
|
@@ -228,43 +281,26 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
228
281
|
: 'Add a line `@AGENTS.md` to CLAUDE.md'
|
|
229
282
|
});
|
|
230
283
|
}
|
|
284
|
+
// 10. Registry: each active capability's checks (skill files, CLIs, artifacts)
|
|
285
|
+
if (projectConfig !== null)
|
|
286
|
+
checks.push(...(await capabilityChecks(targetDir, projectConfig)));
|
|
231
287
|
// 10. agent-browser runtime (only when the project ships the skill)
|
|
232
288
|
const agentBrowserWanted = projectConfig !== null &&
|
|
233
|
-
(
|
|
234
|
-
if (agentBrowserWanted) {
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
: 'agent-browser skill is installed but the CLI is not in PATH',
|
|
249
|
-
suggestion: abExists
|
|
250
|
-
? undefined
|
|
251
|
-
: 'Install the runtime: `npm i -g agent-browser && agent-browser install`'
|
|
252
|
-
});
|
|
253
|
-
if (abExists) {
|
|
254
|
-
const diagnostics = await runAgentBrowserDiagnostics();
|
|
255
|
-
if (diagnostics !== null) {
|
|
256
|
-
checks.push({
|
|
257
|
-
name: 'agent-browser browser runtime',
|
|
258
|
-
category: 'AI Tooling',
|
|
259
|
-
ok: diagnostics.length === 0,
|
|
260
|
-
detail: diagnostics.length === 0
|
|
261
|
-
? 'Upstream doctor reports browser and launch environment healthy'
|
|
262
|
-
: diagnostics.map((d) => d.message).join('; '),
|
|
263
|
-
suggestion: diagnostics.length === 0
|
|
264
|
-
? undefined
|
|
265
|
-
: (diagnostics.find((d) => d.fix)?.fix ?? 'Run `agent-browser doctor` for details')
|
|
266
|
-
});
|
|
267
|
-
}
|
|
289
|
+
(activeIds(projectConfig).has('agent-browser') || agentBrowserStubInstalled(targetDir));
|
|
290
|
+
if (agentBrowserWanted && (await commandExists('agent-browser'))) {
|
|
291
|
+
const diagnostics = await runAgentBrowserDiagnostics();
|
|
292
|
+
if (diagnostics !== null) {
|
|
293
|
+
checks.push({
|
|
294
|
+
name: 'agent-browser browser runtime',
|
|
295
|
+
category: 'AI Tooling',
|
|
296
|
+
ok: diagnostics.length === 0,
|
|
297
|
+
detail: diagnostics.length === 0
|
|
298
|
+
? 'Upstream doctor reports browser and launch environment healthy'
|
|
299
|
+
: diagnostics.map((d) => d.message).join('; '),
|
|
300
|
+
suggestion: diagnostics.length === 0
|
|
301
|
+
? undefined
|
|
302
|
+
: (diagnostics.find((d) => d.fix)?.fix ?? 'Run `agent-browser doctor` for details')
|
|
303
|
+
});
|
|
268
304
|
}
|
|
269
305
|
}
|
|
270
306
|
// 11. Chrome sandbox prerequisites — agent-browser and Playwright both
|
|
@@ -291,14 +327,12 @@ export async function runDoctor(targetDir = process.cwd()) {
|
|
|
291
327
|
}
|
|
292
328
|
}
|
|
293
329
|
// Print grouped results
|
|
294
|
-
const categories = [
|
|
295
|
-
'Environment',
|
|
296
|
-
'AI Tooling',
|
|
297
|
-
'Project Config'
|
|
298
|
-
];
|
|
330
|
+
const categories = ['Environment', 'AI Tooling', 'Project Config', 'Capabilities'];
|
|
299
331
|
for (const cat of categories) {
|
|
300
|
-
console.log(pc.bold(pc.underline(cat)));
|
|
301
332
|
const catChecks = checks.filter((c) => c.category === cat);
|
|
333
|
+
if (catChecks.length === 0)
|
|
334
|
+
continue;
|
|
335
|
+
console.log(pc.bold(pc.underline(cat)));
|
|
302
336
|
for (const c of catChecks) {
|
|
303
337
|
const icon = c.ok ? pc.green('✓') : pc.yellow('⚠');
|
|
304
338
|
const name = pc.bold(c.name);
|