create-academic-research 0.1.4 → 0.1.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 +10 -7
- package/dist/src/agents.d.ts +9 -0
- package/dist/src/agents.js +126 -0
- package/dist/src/capabilities.d.ts +2 -2
- package/dist/src/capabilities.js +11 -15
- package/dist/src/cli.js +46 -7
- package/dist/src/project.js +3 -2
- package/package.json +1 -1
- package/template/README.md +1 -0
- package/template/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,9 +35,10 @@ adjacent interdisciplinary CS.
|
|
|
35
35
|
|
|
36
36
|
The generated repository is agent-neutral. By default the wizard records
|
|
37
37
|
`agent: universal`, installs one shared project-local `.agents/skills` copy,
|
|
38
|
-
and writes generic MCP snippets. Use `--agent <
|
|
39
|
-
|
|
40
|
-
`
|
|
38
|
+
and writes generic MCP snippets. Use `--agent <id>` only when you want to force
|
|
39
|
+
a specific target recognized by the `skills` CLI. Run
|
|
40
|
+
`npx academic-research agents list` inside a generated project to see every
|
|
41
|
+
supported target and alias.
|
|
41
42
|
|
|
42
43
|
## Default Experience
|
|
43
44
|
|
|
@@ -76,6 +77,7 @@ Inside a generated project:
|
|
|
76
77
|
```bash
|
|
77
78
|
npx academic-research doctor
|
|
78
79
|
npx academic-research rename --title "New Title" --slug new-title --package new_title
|
|
80
|
+
npx academic-research agents list
|
|
79
81
|
npx academic-research skills presets
|
|
80
82
|
npx academic-research skills install --preset default
|
|
81
83
|
npx academic-research skills install --preset enhanced
|
|
@@ -134,8 +136,9 @@ The create wizard can install that project-local package automatically.
|
|
|
134
136
|
Those skills are portable `SKILL.md` instructions, but they require an
|
|
135
137
|
agent/runtime that can load skills or include the relevant instructions in
|
|
136
138
|
context. They are not automatic capabilities of every raw model API.
|
|
137
|
-
Use `--agent <
|
|
138
|
-
`--agent claude
|
|
139
|
+
Use `--agent <id>` for explicit setup with any id from
|
|
140
|
+
`academic-research agents list`. The shorthand `--agent claude` is normalized
|
|
141
|
+
to the supported `claude-code` target.
|
|
139
142
|
Avoid `--agent auto` for unattended setup: the upstream `skills` CLI may expand
|
|
140
143
|
it to every agent it detects on the machine.
|
|
141
144
|
|
|
@@ -166,8 +169,8 @@ Releases are tag-driven. Update `package.json` and `package-lock.json`, commit
|
|
|
166
169
|
the change, create `vX.Y.Z`, and push the tag:
|
|
167
170
|
|
|
168
171
|
```bash
|
|
169
|
-
git tag -a v0.1.
|
|
170
|
-
git push origin main v0.1.
|
|
172
|
+
git tag -a v0.1.5 -m "v0.1.5"
|
|
173
|
+
git push origin main v0.1.5
|
|
171
174
|
```
|
|
172
175
|
|
|
173
176
|
Once the GitHub repository is public, the release workflow validates the tag
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const DEFAULT_AGENT = "universal";
|
|
2
|
+
export declare const AUTO_AGENT = "auto";
|
|
3
|
+
export declare const SUPPORTED_SKILL_AGENT_TARGETS: readonly ["adal", "aider-desk", "amp", "antigravity", "augment", "bob", "claude-code", "cline", "codearts-agent", "codebuddy", "codemaker", "codestudio", "codex", "command-code", "continue", "cortex", "crush", "cursor", "deepagents", "devin", "dexto", "droid", "firebender", "forgecode", "gemini-cli", "github-copilot", "goose", "hermes-agent", "iflow-cli", "junie", "kilo", "kimi-cli", "kiro-cli", "kode", "mcpjam", "mistral-vibe", "mux", "neovate", "openclaw", "opencode", "openhands", "pi", "pochi", "qoder", "qwen-code", "replit", "roo", "rovodev", "tabnine-cli", "trae", "trae-cn", "universal", "warp", "windsurf", "zencoder"];
|
|
4
|
+
export declare const AGENT_TARGET_ALIASES: Record<string, string>;
|
|
5
|
+
export declare function normalizeAgentTarget(agent: string | undefined): string;
|
|
6
|
+
export declare function assertKnownAgentTarget(agent: string | undefined): string;
|
|
7
|
+
export declare function formatAgentTargetList(): string;
|
|
8
|
+
export declare function formatSupportedAgentTargetLines(indent?: string, width?: number): string[];
|
|
9
|
+
export declare function formatAgentAliasLines(indent?: string): string[];
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
export const DEFAULT_AGENT = "universal";
|
|
2
|
+
export const AUTO_AGENT = "auto";
|
|
3
|
+
export const SUPPORTED_SKILL_AGENT_TARGETS = [
|
|
4
|
+
"adal",
|
|
5
|
+
"aider-desk",
|
|
6
|
+
"amp",
|
|
7
|
+
"antigravity",
|
|
8
|
+
"augment",
|
|
9
|
+
"bob",
|
|
10
|
+
"claude-code",
|
|
11
|
+
"cline",
|
|
12
|
+
"codearts-agent",
|
|
13
|
+
"codebuddy",
|
|
14
|
+
"codemaker",
|
|
15
|
+
"codestudio",
|
|
16
|
+
"codex",
|
|
17
|
+
"command-code",
|
|
18
|
+
"continue",
|
|
19
|
+
"cortex",
|
|
20
|
+
"crush",
|
|
21
|
+
"cursor",
|
|
22
|
+
"deepagents",
|
|
23
|
+
"devin",
|
|
24
|
+
"dexto",
|
|
25
|
+
"droid",
|
|
26
|
+
"firebender",
|
|
27
|
+
"forgecode",
|
|
28
|
+
"gemini-cli",
|
|
29
|
+
"github-copilot",
|
|
30
|
+
"goose",
|
|
31
|
+
"hermes-agent",
|
|
32
|
+
"iflow-cli",
|
|
33
|
+
"junie",
|
|
34
|
+
"kilo",
|
|
35
|
+
"kimi-cli",
|
|
36
|
+
"kiro-cli",
|
|
37
|
+
"kode",
|
|
38
|
+
"mcpjam",
|
|
39
|
+
"mistral-vibe",
|
|
40
|
+
"mux",
|
|
41
|
+
"neovate",
|
|
42
|
+
"openclaw",
|
|
43
|
+
"opencode",
|
|
44
|
+
"openhands",
|
|
45
|
+
"pi",
|
|
46
|
+
"pochi",
|
|
47
|
+
"qoder",
|
|
48
|
+
"qwen-code",
|
|
49
|
+
"replit",
|
|
50
|
+
"roo",
|
|
51
|
+
"rovodev",
|
|
52
|
+
"tabnine-cli",
|
|
53
|
+
"trae",
|
|
54
|
+
"trae-cn",
|
|
55
|
+
"universal",
|
|
56
|
+
"warp",
|
|
57
|
+
"windsurf",
|
|
58
|
+
"zencoder"
|
|
59
|
+
];
|
|
60
|
+
export const AGENT_TARGET_ALIASES = {
|
|
61
|
+
claude: "claude-code",
|
|
62
|
+
claude_code: "claude-code"
|
|
63
|
+
};
|
|
64
|
+
const SUPPORTED_AGENT_TARGETS = new Set([
|
|
65
|
+
AUTO_AGENT,
|
|
66
|
+
...SUPPORTED_SKILL_AGENT_TARGETS
|
|
67
|
+
]);
|
|
68
|
+
export function normalizeAgentTarget(agent) {
|
|
69
|
+
const value = agent?.trim();
|
|
70
|
+
if (!value)
|
|
71
|
+
return DEFAULT_AGENT;
|
|
72
|
+
const normalized = value.toLowerCase();
|
|
73
|
+
return AGENT_TARGET_ALIASES[normalized] ?? normalized;
|
|
74
|
+
}
|
|
75
|
+
export function assertKnownAgentTarget(agent) {
|
|
76
|
+
const normalized = normalizeAgentTarget(agent);
|
|
77
|
+
if (!SUPPORTED_AGENT_TARGETS.has(normalized)) {
|
|
78
|
+
const value = agent?.trim() || DEFAULT_AGENT;
|
|
79
|
+
throw new Error([
|
|
80
|
+
`unknown agent target: ${value}`,
|
|
81
|
+
`Use ${DEFAULT_AGENT}, ${AUTO_AGENT}, or one supported skills.sh agent id.`,
|
|
82
|
+
"List targets with: npx -p create-academic-research academic-research agents list",
|
|
83
|
+
`Supported ids: ${specificAgentTargets().join(", ")}`,
|
|
84
|
+
`Aliases: ${formatAgentAliasesInline()}`
|
|
85
|
+
].join("\n"));
|
|
86
|
+
}
|
|
87
|
+
return normalized;
|
|
88
|
+
}
|
|
89
|
+
export function formatAgentTargetList() {
|
|
90
|
+
const lines = [
|
|
91
|
+
`${DEFAULT_AGENT}\tRecommended shared project-local .agents/skills copy`,
|
|
92
|
+
`${AUTO_AGENT}\tLet the skills CLI detect installed agents; may create multiple agent-specific copies`,
|
|
93
|
+
...specificAgentTargets().map((agent) => `${agent}\tskills.sh agent id`),
|
|
94
|
+
...Object.entries(AGENT_TARGET_ALIASES).map(([alias, target]) => `alias\t${alias}\t${target}`)
|
|
95
|
+
];
|
|
96
|
+
return `${lines.join("\n")}\n`;
|
|
97
|
+
}
|
|
98
|
+
export function formatSupportedAgentTargetLines(indent = " ", width = 100) {
|
|
99
|
+
const labels = specificAgentTargets();
|
|
100
|
+
const lines = [];
|
|
101
|
+
let current = indent;
|
|
102
|
+
for (const label of labels) {
|
|
103
|
+
const next = current === indent ? label : `, ${label}`;
|
|
104
|
+
if (current.length + next.length > width) {
|
|
105
|
+
lines.push(current);
|
|
106
|
+
current = `${indent}${label}`;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
current += next;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (current.trim())
|
|
113
|
+
lines.push(current);
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
export function formatAgentAliasLines(indent = " ") {
|
|
117
|
+
return Object.entries(AGENT_TARGET_ALIASES).map(([alias, target]) => `${indent}${alias} -> ${target}`);
|
|
118
|
+
}
|
|
119
|
+
function formatAgentAliasesInline() {
|
|
120
|
+
return Object.entries(AGENT_TARGET_ALIASES)
|
|
121
|
+
.map(([alias, target]) => `${alias} -> ${target}`)
|
|
122
|
+
.join(", ");
|
|
123
|
+
}
|
|
124
|
+
function specificAgentTargets() {
|
|
125
|
+
return SUPPORTED_SKILL_AGENT_TARGETS.filter((agent) => agent !== DEFAULT_AGENT);
|
|
126
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { DEFAULT_AGENT, SUPPORTED_SKILL_AGENT_TARGETS } from "./agents.js";
|
|
1
2
|
import { type Runner } from "./runner.js";
|
|
2
3
|
import { type McpToolCommandKey } from "./stack.js";
|
|
3
|
-
export
|
|
4
|
+
export { DEFAULT_AGENT, SUPPORTED_SKILL_AGENT_TARGETS };
|
|
4
5
|
export interface CapabilityState {
|
|
5
6
|
agent: string;
|
|
6
7
|
preset: string;
|
|
@@ -51,4 +52,3 @@ export declare function installMcpTools(root: string, servers: string[], runner?
|
|
|
51
52
|
export declare function uninstallMcpTools(root: string, servers: string[], runner?: Runner): Promise<CapabilityCommandResult>;
|
|
52
53
|
export declare function doctorMcpServers(root: string): Promise<McpDoctorResult>;
|
|
53
54
|
export declare function assertKnownMcpServers(servers: string[]): void;
|
|
54
|
-
export {};
|
package/dist/src/capabilities.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join, relative } from "node:path";
|
|
3
3
|
import YAML from "yaml";
|
|
4
|
+
import { assertKnownAgentTarget, AUTO_AGENT, DEFAULT_AGENT, normalizeAgentTarget, SUPPORTED_SKILL_AGENT_TARGETS } from "./agents.js";
|
|
4
5
|
import { defaultRunner } from "./runner.js";
|
|
5
6
|
import { AGENT_STACK, presetMcpServers } from "./stack.js";
|
|
6
|
-
export
|
|
7
|
-
const AUTO_AGENT = "auto";
|
|
7
|
+
export { DEFAULT_AGENT, SUPPORTED_SKILL_AGENT_TARGETS };
|
|
8
8
|
export async function readCapabilities(root) {
|
|
9
9
|
try {
|
|
10
10
|
return readCapabilitiesFile(root);
|
|
@@ -18,7 +18,7 @@ export async function readCapabilities(root) {
|
|
|
18
18
|
}
|
|
19
19
|
export async function writeCapabilities(root, state) {
|
|
20
20
|
const next = {
|
|
21
|
-
agent:
|
|
21
|
+
agent: assertKnownAgentTarget(state.agent),
|
|
22
22
|
preset: state.preset ?? "default",
|
|
23
23
|
scope: "project-local",
|
|
24
24
|
mcp_servers: [...(state.mcp_servers ?? [])]
|
|
@@ -42,7 +42,7 @@ export async function buildSkillInstallCommands(root, preset = "default", option
|
|
|
42
42
|
if (!selected)
|
|
43
43
|
throw new Error(`unknown skill preset: ${preset}`);
|
|
44
44
|
const state = await readCapabilities(root);
|
|
45
|
-
const agent =
|
|
45
|
+
const agent = assertKnownAgentTarget(options.agent ?? state.agent);
|
|
46
46
|
const commands = [];
|
|
47
47
|
for (const bundleName of selected.skill_bundles) {
|
|
48
48
|
const bundle = AGENT_STACK.skill_bundles[bundleName];
|
|
@@ -61,7 +61,7 @@ export async function buildSkillInstallCommands(root, preset = "default", option
|
|
|
61
61
|
}
|
|
62
62
|
export async function installSkills(root, preset = "default", options = {}, runner = defaultRunner) {
|
|
63
63
|
const state = await readCapabilities(root);
|
|
64
|
-
const agent =
|
|
64
|
+
const agent = assertKnownAgentTarget(options.agent ?? state.agent);
|
|
65
65
|
const commands = await buildSkillInstallCommands(root, preset, options);
|
|
66
66
|
for (const command of commands) {
|
|
67
67
|
await runner.run(command, { cwd: root });
|
|
@@ -135,7 +135,7 @@ export async function enableMcpServers(root, servers, options = {}) {
|
|
|
135
135
|
const selected = dedupe([...(state.mcp_servers ?? []), ...servers]);
|
|
136
136
|
await writeCapabilities(root, {
|
|
137
137
|
...state,
|
|
138
|
-
agent: options.agent ?? state.agent,
|
|
138
|
+
agent: assertKnownAgentTarget(options.agent ?? state.agent),
|
|
139
139
|
mcp_servers: selected
|
|
140
140
|
});
|
|
141
141
|
return { ok: true, servers: selected };
|
|
@@ -147,7 +147,7 @@ export async function disableMcpServers(root, servers, options = {}) {
|
|
|
147
147
|
const selected = (state.mcp_servers ?? []).filter((server) => !blocked.has(server));
|
|
148
148
|
await writeCapabilities(root, {
|
|
149
149
|
...state,
|
|
150
|
-
agent: options.agent ?? state.agent,
|
|
150
|
+
agent: assertKnownAgentTarget(options.agent ?? state.agent),
|
|
151
151
|
mcp_servers: selected
|
|
152
152
|
});
|
|
153
153
|
return { ok: true, servers: selected };
|
|
@@ -269,7 +269,7 @@ async function writeCapabilityProfile(root, state) {
|
|
|
269
269
|
const lines = [
|
|
270
270
|
"# Agent Capability Profile",
|
|
271
271
|
"",
|
|
272
|
-
`- Agent target: \`${
|
|
272
|
+
`- Agent target: \`${assertKnownAgentTarget(state.agent)}\``,
|
|
273
273
|
`- Preset: \`${state.preset ?? "default"}\``,
|
|
274
274
|
"- Scope: `project-local`",
|
|
275
275
|
"",
|
|
@@ -307,7 +307,7 @@ function dedupe(values) {
|
|
|
307
307
|
return [...new Set(values)];
|
|
308
308
|
}
|
|
309
309
|
function renderSkillCommand(command, agent) {
|
|
310
|
-
const normalized =
|
|
310
|
+
const normalized = assertKnownAgentTarget(agent);
|
|
311
311
|
const agentFlag = normalized === AUTO_AGENT ? "" : `--agent '${normalized}'`;
|
|
312
312
|
return command.replaceAll("{agent_flag}", agentFlag).replaceAll("{agent}", normalized);
|
|
313
313
|
}
|
|
@@ -352,7 +352,7 @@ function splitCommand(command) {
|
|
|
352
352
|
function normalizeCapabilityState(value) {
|
|
353
353
|
const record = typeof value === "object" && value !== null ? value : {};
|
|
354
354
|
return {
|
|
355
|
-
agent:
|
|
355
|
+
agent: assertKnownAgentTarget(typeof record.agent === "string" ? record.agent : undefined),
|
|
356
356
|
preset: typeof record.preset === "string" ? record.preset : "default",
|
|
357
357
|
scope: "project-local",
|
|
358
358
|
mcp_servers: Array.isArray(record.mcp_servers)
|
|
@@ -397,12 +397,8 @@ async function removeSkillsFromLock(root, skills) {
|
|
|
397
397
|
await writeFile(path, `${JSON.stringify(record, null, 2)}\n`, "utf8");
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
|
-
function normalizeAgent(agent) {
|
|
401
|
-
const value = agent?.trim();
|
|
402
|
-
return value ? value : DEFAULT_AGENT;
|
|
403
|
-
}
|
|
404
400
|
function mcpSnippetFileName(agent) {
|
|
405
|
-
const normalized =
|
|
401
|
+
const normalized = normalizeAgentTarget(agent);
|
|
406
402
|
return normalized === DEFAULT_AGENT || normalized === AUTO_AGENT ? "mcp.json" : `${normalized}-mcp.json`;
|
|
407
403
|
}
|
|
408
404
|
async function removeInactiveMcpSnippets(outputDir, activeFile) {
|
package/dist/src/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { disableMcpServers, doctorMcpServers, enableMcpServers, DEFAULT_AGENT, i
|
|
|
5
5
|
import { createProject, doctorProject, renameProject } from "./project.js";
|
|
6
6
|
import { askCreateOptions } from "./prompts.js";
|
|
7
7
|
import { AGENT_STACK, presetMcpServers } from "./stack.js";
|
|
8
|
+
import { formatAgentAliasLines, formatAgentTargetList, formatSupportedAgentTargetLines } from "./agents.js";
|
|
8
9
|
import { packageify, slugify, titleFromSlug } from "./names.js";
|
|
9
10
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
10
11
|
const packageVersion = readPackageVersion();
|
|
@@ -101,6 +102,8 @@ async function lifecycleMain(argv) {
|
|
|
101
102
|
return doctorCommand(argv.slice(1));
|
|
102
103
|
if (command === "rename")
|
|
103
104
|
return renameCommand(argv.slice(1));
|
|
105
|
+
if (command === "agents")
|
|
106
|
+
return agentsCommand(argv.slice(1));
|
|
104
107
|
if (command === "skills")
|
|
105
108
|
return skillsCommand(argv.slice(1));
|
|
106
109
|
if (command === "mcp")
|
|
@@ -137,6 +140,21 @@ async function renameCommand(argv) {
|
|
|
137
140
|
console.log(`Renamed project to ${result.slug}`);
|
|
138
141
|
return 0;
|
|
139
142
|
}
|
|
143
|
+
async function agentsCommand(argv) {
|
|
144
|
+
const subcommand = argv[0] ?? "list";
|
|
145
|
+
const parsed = parseFlags(argv.slice(1), ROOT_FLAGS);
|
|
146
|
+
if (subcommand === "help" || subcommand === "--help" || subcommand === "-h" || flagBool(parsed.flags, "help")) {
|
|
147
|
+
printAgentsHelp();
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
if (subcommand === "list") {
|
|
151
|
+
assertOnlyOptions(parsed.flags, "agents list", []);
|
|
152
|
+
assertNoArguments(parsed.positionals, "agents list");
|
|
153
|
+
process.stdout.write(formatAgentTargetList());
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`unknown agents command: ${subcommand}`);
|
|
157
|
+
}
|
|
140
158
|
async function skillsCommand(argv) {
|
|
141
159
|
const subcommand = argv[0] ?? "list";
|
|
142
160
|
const parsed = parseFlags(argv.slice(1), SKILLS_FLAGS);
|
|
@@ -401,9 +419,15 @@ export function formatInteractiveCreateGuide() {
|
|
|
401
419
|
...presetLines,
|
|
402
420
|
"",
|
|
403
421
|
"Agent target:",
|
|
404
|
-
" universal
|
|
405
|
-
"
|
|
406
|
-
"
|
|
422
|
+
" universal Recommended. One shared project-local .agents/skills copy.",
|
|
423
|
+
" auto Let the skills CLI detect installed agents; may create multiple agent-specific copies.",
|
|
424
|
+
" <id> Any supported skills.sh agent id.",
|
|
425
|
+
"",
|
|
426
|
+
"Supported specific agent ids:",
|
|
427
|
+
...formatSupportedAgentTargetLines(),
|
|
428
|
+
"",
|
|
429
|
+
"Aliases:",
|
|
430
|
+
...formatAgentAliasLines(),
|
|
407
431
|
"",
|
|
408
432
|
"Skill and MCP behavior:",
|
|
409
433
|
" Skills are copied into the project, not installed globally.",
|
|
@@ -426,7 +450,7 @@ function printCreateHelp() {
|
|
|
426
450
|
" --package <name> Python package name. Default: normalized project name.",
|
|
427
451
|
" --preset <name> Capability preset: minimal, default, enhanced, literature, writing, full.",
|
|
428
452
|
" --profile <name> Project profile metadata. Default: academic-general.",
|
|
429
|
-
" --agent <
|
|
453
|
+
" --agent <id> Agent target: universal, auto, or a supported skills.sh id.",
|
|
430
454
|
" --install-skills Install project-local skills without prompting.",
|
|
431
455
|
" --no-install-skills Skip project-local skill installation.",
|
|
432
456
|
" --install-mcp-tools Run finite external MCP install commands after creation.",
|
|
@@ -445,7 +469,7 @@ function printMissingTargetHelp() {
|
|
|
445
469
|
}
|
|
446
470
|
function printLifecycleHelp() {
|
|
447
471
|
console.log([
|
|
448
|
-
"Usage: academic-research <doctor|rename|skills|mcp>",
|
|
472
|
+
"Usage: academic-research <doctor|rename|agents|skills|mcp>",
|
|
449
473
|
"",
|
|
450
474
|
"Manage a generated academic research repository after creation.",
|
|
451
475
|
"",
|
|
@@ -454,6 +478,21 @@ function printLifecycleHelp() {
|
|
|
454
478
|
" -v, --version Show package version."
|
|
455
479
|
].join("\n"));
|
|
456
480
|
}
|
|
481
|
+
function printAgentsHelp() {
|
|
482
|
+
console.log([
|
|
483
|
+
"Usage: academic-research agents <list>",
|
|
484
|
+
"",
|
|
485
|
+
"List supported project-local agent targets.",
|
|
486
|
+
"",
|
|
487
|
+
"Targets:",
|
|
488
|
+
" universal Recommended shared project-local .agents/skills copy.",
|
|
489
|
+
" auto Let the skills CLI detect installed agents.",
|
|
490
|
+
" <id> A supported skills.sh agent id.",
|
|
491
|
+
"",
|
|
492
|
+
"Options:",
|
|
493
|
+
" -h, --help Show this help."
|
|
494
|
+
].join("\n"));
|
|
495
|
+
}
|
|
457
496
|
function printSkillsHelp() {
|
|
458
497
|
console.log([
|
|
459
498
|
"Usage: academic-research skills <list|status|presets|install|remove|uninstall|update> [options]",
|
|
@@ -463,7 +502,7 @@ function printSkillsHelp() {
|
|
|
463
502
|
"Options:",
|
|
464
503
|
" --root <path> Project root for list, status, install, remove, uninstall, update.",
|
|
465
504
|
" --preset <name> Capability preset for install.",
|
|
466
|
-
" --agent <
|
|
505
|
+
" --agent <id> Agent selector for install. Default: project capability agent.",
|
|
467
506
|
" -h, --help Show this help."
|
|
468
507
|
].join("\n"));
|
|
469
508
|
}
|
|
@@ -475,7 +514,7 @@ function printMcpHelp() {
|
|
|
475
514
|
"",
|
|
476
515
|
"Options:",
|
|
477
516
|
" --root <path> Project root for project-state commands.",
|
|
478
|
-
" --agent <
|
|
517
|
+
" --agent <id> Agent for enable/disable generated snippets.",
|
|
479
518
|
" -h, --help Show this help."
|
|
480
519
|
].join("\n"));
|
|
481
520
|
}
|
package/dist/src/project.js
CHANGED
|
@@ -3,6 +3,7 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import YAML from "yaml";
|
|
5
5
|
import { DEFAULT_AGENT, initializeCapabilities, installSkills } from "./capabilities.js";
|
|
6
|
+
import { assertKnownAgentTarget } from "./agents.js";
|
|
6
7
|
import { copyDirectory, exists, isNonEmptyDirectory, movePath, readJson, writeJson } from "./files.js";
|
|
7
8
|
import { packageify, slugify, titleFromSlug } from "./names.js";
|
|
8
9
|
import { AGENT_STACK } from "./stack.js";
|
|
@@ -90,7 +91,7 @@ export async function createProject(options) {
|
|
|
90
91
|
const slug = slugify(options.slug ?? title);
|
|
91
92
|
const packageName = packageify(options.packageName ?? slug);
|
|
92
93
|
const preset = options.preset ?? "default";
|
|
93
|
-
const agent = options.agent ?? DEFAULT_AGENT;
|
|
94
|
+
const agent = assertKnownAgentTarget(options.agent ?? DEFAULT_AGENT);
|
|
94
95
|
if (!AGENT_STACK.presets[preset]) {
|
|
95
96
|
throw new Error(`unknown capability preset: ${preset}. Expected one of: ${Object.keys(AGENT_STACK.presets).join(", ")}`);
|
|
96
97
|
}
|
|
@@ -205,7 +206,7 @@ async function writeGeneratedPackageJson(root, { slug }) {
|
|
|
205
206
|
const path = join(root, "package.json");
|
|
206
207
|
const data = await readJson(path);
|
|
207
208
|
const existingSpec = data.devDependencies?.["create-academic-research"];
|
|
208
|
-
const packageSpec = process.env.CREATE_ACADEMIC_RESEARCH_PACKAGE_SPEC ?? existingSpec ?? "0.1.
|
|
209
|
+
const packageSpec = process.env.CREATE_ACADEMIC_RESEARCH_PACKAGE_SPEC ?? existingSpec ?? "0.1.5";
|
|
209
210
|
data.name = slug;
|
|
210
211
|
data.devDependencies = {
|
|
211
212
|
...(data.devDependencies ?? {}),
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -53,6 +53,7 @@ Project-local skills and MCP records are managed with:
|
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
npx academic-research skills presets
|
|
56
|
+
npx academic-research agents list
|
|
56
57
|
npx academic-research skills install --preset default
|
|
57
58
|
npx academic-research skills install --preset enhanced
|
|
58
59
|
npx academic-research skills list
|