create-academic-research 0.1.7 → 0.1.8
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 +4 -3
- package/dist/src/capabilities.d.ts +3 -0
- package/dist/src/capabilities.js +74 -0
- package/dist/src/cli.js +35 -7
- package/dist/src/project.js +1 -1
- package/dist/src/stack.d.ts +6 -0
- package/dist/src/stack.js +70 -0
- package/package.json +1 -1
- package/template/README.md +1 -0
- package/template/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,6 +93,7 @@ npx academic-research agents list
|
|
|
93
93
|
npx academic-research skills presets
|
|
94
94
|
npx academic-research skills install --preset default
|
|
95
95
|
npx academic-research skills install --preset enhanced
|
|
96
|
+
npx academic-research skills install source-ingestion sota-literature-review
|
|
96
97
|
npx academic-research skills list
|
|
97
98
|
npx academic-research skills status
|
|
98
99
|
npx academic-research skills remove source-ingestion
|
|
@@ -122,7 +123,7 @@ Skills are project-local by default.
|
|
|
122
123
|
| Command | Meaning |
|
|
123
124
|
|---|---|
|
|
124
125
|
| `skills presets` | List available capability presets. |
|
|
125
|
-
| `skills install` | Install project-local skills
|
|
126
|
+
| `skills install` | Install project-local skills by preset, or selected skill ids such as `source-ingestion`. This does not change MCP records. |
|
|
126
127
|
| `skills list` | List skills found in project-local skill loader directories. |
|
|
127
128
|
| `skills status` | Show configured project preset, agent, scope, skill roots, unique skill ids, and installed copies. |
|
|
128
129
|
| `skills remove` / `skills uninstall` | Remove selected project-local skills. |
|
|
@@ -215,8 +216,8 @@ Releases are tag-driven. Update `package.json` and `package-lock.json`, commit
|
|
|
215
216
|
the change, create `vX.Y.Z`, and push the tag:
|
|
216
217
|
|
|
217
218
|
```bash
|
|
218
|
-
git tag -a v0.1.
|
|
219
|
-
git push origin main v0.1.
|
|
219
|
+
git tag -a v0.1.8 -m "v0.1.8"
|
|
220
|
+
git push origin main v0.1.8
|
|
220
221
|
```
|
|
221
222
|
|
|
222
223
|
Once the GitHub repository is public, the release workflow validates the tag
|
|
@@ -16,6 +16,7 @@ export interface InitializeCapabilitiesOptions {
|
|
|
16
16
|
export interface CapabilityCommandResult {
|
|
17
17
|
ok: true;
|
|
18
18
|
count?: number;
|
|
19
|
+
skills?: string[];
|
|
19
20
|
servers?: string[];
|
|
20
21
|
}
|
|
21
22
|
export interface InstalledSkill {
|
|
@@ -36,7 +37,9 @@ export declare function readCapabilities(root: string): Promise<CapabilityState>
|
|
|
36
37
|
export declare function writeCapabilities(root: string, state: Partial<CapabilityState>): Promise<void>;
|
|
37
38
|
export declare function initializeCapabilities(root: string, options?: InitializeCapabilitiesOptions): Promise<void>;
|
|
38
39
|
export declare function buildSkillInstallCommands(root: string, preset?: string, options?: SkillInstallOptions): Promise<string[][]>;
|
|
40
|
+
export declare function buildExplicitSkillInstallCommands(root: string, skills: string[], options?: SkillInstallOptions): Promise<string[][]>;
|
|
39
41
|
export declare function installSkills(root: string, preset?: string, options?: SkillInstallOptions, runner?: Runner): Promise<CapabilityCommandResult>;
|
|
42
|
+
export declare function installSkillIds(root: string, skills: string[], options?: SkillInstallOptions, runner?: Runner): Promise<CapabilityCommandResult>;
|
|
40
43
|
export declare function listInstalledSkills(root: string): Promise<InstalledSkill[]>;
|
|
41
44
|
export declare function removeSkills(root: string, skills: string[], runner?: Runner): Promise<CapabilityCommandResult>;
|
|
42
45
|
export declare function updateSkills(root: string, runner?: Runner): Promise<CapabilityCommandResult>;
|
package/dist/src/capabilities.js
CHANGED
|
@@ -60,6 +60,21 @@ export async function buildSkillInstallCommands(root, preset = "default", option
|
|
|
60
60
|
}
|
|
61
61
|
return commands;
|
|
62
62
|
}
|
|
63
|
+
export async function buildExplicitSkillInstallCommands(root, skills, options = {}) {
|
|
64
|
+
const selectedSkills = normalizeSkillIds(skills);
|
|
65
|
+
const state = await readCapabilities(root);
|
|
66
|
+
const agent = assertKnownAgentTarget(options.agent ?? state.agent);
|
|
67
|
+
const skillsBySource = new Map();
|
|
68
|
+
for (const skill of selectedSkills) {
|
|
69
|
+
const source = skillSourceForId(skill);
|
|
70
|
+
if (!source)
|
|
71
|
+
throw new Error(`unknown skill id: ${skill}`);
|
|
72
|
+
const sourceSkills = skillsBySource.get(source) ?? [];
|
|
73
|
+
sourceSkills.push(skill);
|
|
74
|
+
skillsBySource.set(source, sourceSkills);
|
|
75
|
+
}
|
|
76
|
+
return [...skillsBySource.entries()].map(([source, sourceSkills]) => skillAddCommand(source, sourceSkills, agent));
|
|
77
|
+
}
|
|
63
78
|
export async function installSkills(root, preset = "default", options = {}, runner = defaultRunner) {
|
|
64
79
|
const state = await readCapabilities(root);
|
|
65
80
|
const agent = assertKnownAgentTarget(options.agent ?? state.agent);
|
|
@@ -76,6 +91,22 @@ export async function installSkills(root, preset = "default", options = {}, runn
|
|
|
76
91
|
}
|
|
77
92
|
return { ok: true, count: commands.length };
|
|
78
93
|
}
|
|
94
|
+
export async function installSkillIds(root, skills, options = {}, runner = defaultRunner) {
|
|
95
|
+
const state = await readCapabilities(root);
|
|
96
|
+
const agent = assertKnownAgentTarget(options.agent ?? state.agent);
|
|
97
|
+
const selectedSkills = normalizeSkillIds(skills);
|
|
98
|
+
const commands = await buildExplicitSkillInstallCommands(root, selectedSkills, options);
|
|
99
|
+
for (const command of commands) {
|
|
100
|
+
await runner.run(command, { cwd: root });
|
|
101
|
+
}
|
|
102
|
+
if (state.agent !== agent) {
|
|
103
|
+
await writeCapabilities(root, {
|
|
104
|
+
...state,
|
|
105
|
+
agent
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return { ok: true, count: commands.length, skills: selectedSkills };
|
|
109
|
+
}
|
|
79
110
|
export async function listInstalledSkills(root) {
|
|
80
111
|
const roots = await discoverProjectSkillRoots(root);
|
|
81
112
|
const skills = [];
|
|
@@ -287,6 +318,7 @@ async function writeCapabilityProfile(root, state) {
|
|
|
287
318
|
"## Skills",
|
|
288
319
|
"",
|
|
289
320
|
`- Install with: \`academic-research skills install --preset ${state.preset ?? "default"}\``,
|
|
321
|
+
"- Install selected skills with: `academic-research skills install <skill-id> [...]`",
|
|
290
322
|
"- List installed with: `academic-research skills list`",
|
|
291
323
|
"- List presets with: `academic-research skills presets`",
|
|
292
324
|
"- Remove with: `academic-research skills remove <skill>`",
|
|
@@ -355,6 +387,48 @@ function renderSkillCommand(command, agent) {
|
|
|
355
387
|
const agentFlag = normalized === AUTO_AGENT ? "" : `--agent '${normalized}'`;
|
|
356
388
|
return command.replaceAll("{agent_flag}", agentFlag).replaceAll("{agent}", normalized);
|
|
357
389
|
}
|
|
390
|
+
function skillAddCommand(source, skills, agent) {
|
|
391
|
+
return [
|
|
392
|
+
"npm",
|
|
393
|
+
"exec",
|
|
394
|
+
"--yes",
|
|
395
|
+
"--package",
|
|
396
|
+
"skills",
|
|
397
|
+
"--",
|
|
398
|
+
"skills",
|
|
399
|
+
"add",
|
|
400
|
+
source,
|
|
401
|
+
...skillAgentArgs(agent),
|
|
402
|
+
"--skill",
|
|
403
|
+
...skills,
|
|
404
|
+
"--copy",
|
|
405
|
+
"-y"
|
|
406
|
+
];
|
|
407
|
+
}
|
|
408
|
+
function skillAgentArgs(agent) {
|
|
409
|
+
const normalized = assertKnownAgentTarget(agent);
|
|
410
|
+
return normalized === AUTO_AGENT ? [] : ["--agent", normalized];
|
|
411
|
+
}
|
|
412
|
+
function normalizeSkillIds(skills) {
|
|
413
|
+
if (skills.length === 0)
|
|
414
|
+
throw new Error("no skills selected");
|
|
415
|
+
const result = [];
|
|
416
|
+
for (const skill of skills) {
|
|
417
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(skill)) {
|
|
418
|
+
throw new Error(`invalid skill id: ${skill}`);
|
|
419
|
+
}
|
|
420
|
+
if (!result.includes(skill))
|
|
421
|
+
result.push(skill);
|
|
422
|
+
}
|
|
423
|
+
return result;
|
|
424
|
+
}
|
|
425
|
+
function skillSourceForId(skill) {
|
|
426
|
+
for (const source of Object.values(AGENT_STACK.skill_sources)) {
|
|
427
|
+
if (source.skills.includes(skill))
|
|
428
|
+
return source.source;
|
|
429
|
+
}
|
|
430
|
+
return undefined;
|
|
431
|
+
}
|
|
358
432
|
function appendMcpPrerequisiteLines(lines, requiredEnv, recommendedEnv, localService) {
|
|
359
433
|
if (requiredEnv.length > 0)
|
|
360
434
|
lines.push(` - Requires env: ${requiredEnv.map((name) => `\`${name}\``).join(", ")}`);
|
package/dist/src/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { basename, delimiter, dirname, join, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { assertKnownMcpServers, disableMcpServers, doctorMcpServers, enableMcpServers, DEFAULT_AGENT, installMcpTools, installSkills, listInstalledSkills, mcpToolCommandTexts, readCapabilities, removeSkills, uninstallMcpTools, updateSkills } from "./capabilities.js";
|
|
4
|
+
import { assertKnownMcpServers, disableMcpServers, doctorMcpServers, enableMcpServers, DEFAULT_AGENT, installMcpTools, installSkillIds, installSkills, listInstalledSkills, mcpToolCommandTexts, readCapabilities, removeSkills, uninstallMcpTools, updateSkills } from "./capabilities.js";
|
|
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";
|
|
@@ -9,7 +9,15 @@ import { formatAgentAliasLines, formatAgentTargetList, formatSupportedAgentTarge
|
|
|
9
9
|
import { packageify, slugify, titleFromSlug } from "./names.js";
|
|
10
10
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
11
11
|
const packageVersion = readPackageVersion();
|
|
12
|
-
const CREATE_FLAGS = flagSchema([
|
|
12
|
+
const CREATE_FLAGS = flagSchema([
|
|
13
|
+
"yes",
|
|
14
|
+
"help",
|
|
15
|
+
"version",
|
|
16
|
+
"install-skills",
|
|
17
|
+
"no-install-skills",
|
|
18
|
+
"install-mcp-tools",
|
|
19
|
+
"no-install-mcp-tools"
|
|
20
|
+
], ["title", "slug", "package", "preset", "profile", "agent"]);
|
|
13
21
|
const ROOT_FLAGS = flagSchema(["help"], ["root"]);
|
|
14
22
|
const RENAME_FLAGS = flagSchema(["help"], ["root", "title", "slug", "package"]);
|
|
15
23
|
const SKILLS_FLAGS = flagSchema(["help"], ["root", "preset", "agent"]);
|
|
@@ -43,6 +51,9 @@ async function createMain(argv) {
|
|
|
43
51
|
if (flagBool(parsed.flags, "install-skills") && flagBool(parsed.flags, "no-install-skills")) {
|
|
44
52
|
throw new Error("cannot use --install-skills and --no-install-skills together");
|
|
45
53
|
}
|
|
54
|
+
if (flagBool(parsed.flags, "install-mcp-tools") && flagBool(parsed.flags, "no-install-mcp-tools")) {
|
|
55
|
+
throw new Error("cannot use --install-mcp-tools and --no-install-mcp-tools together");
|
|
56
|
+
}
|
|
46
57
|
if (parsed.positionals.length > 1) {
|
|
47
58
|
throw new Error(`unexpected argument: ${parsed.positionals[1]}`);
|
|
48
59
|
}
|
|
@@ -60,7 +71,9 @@ async function createMain(argv) {
|
|
|
60
71
|
const installSkillsLock = flagBool(parsed.flags, "install-skills") || flagBool(parsed.flags, "no-install-skills")
|
|
61
72
|
? defaults.installSkills
|
|
62
73
|
: undefined;
|
|
63
|
-
const installMcpToolsLock = flagBool(parsed.flags, "install-mcp-tools")
|
|
74
|
+
const installMcpToolsLock = flagBool(parsed.flags, "install-mcp-tools") || flagBool(parsed.flags, "no-install-mcp-tools")
|
|
75
|
+
? defaults.installMcpTools
|
|
76
|
+
: undefined;
|
|
64
77
|
const answers = interactive
|
|
65
78
|
? await askInteractiveCreateOptions(defaults, {
|
|
66
79
|
installSkills: installSkillsLock,
|
|
@@ -240,8 +253,18 @@ async function skillsCommand(argv) {
|
|
|
240
253
|
if (subcommand === "install") {
|
|
241
254
|
assertOnlyOptions(parsed.flags, "skills install", ["root", "preset", "agent"]);
|
|
242
255
|
const root = resolve(flagString(parsed.flags, "root") ?? ".");
|
|
243
|
-
|
|
244
|
-
const
|
|
256
|
+
const explicitSkills = parsed.positionals;
|
|
257
|
+
const explicitPreset = flagString(parsed.flags, "preset");
|
|
258
|
+
if (explicitSkills.length > 0) {
|
|
259
|
+
if (explicitPreset)
|
|
260
|
+
throw new Error("skills install does not accept --preset when skill ids are provided");
|
|
261
|
+
const result = await installSkillIds(root, explicitSkills, {
|
|
262
|
+
agent: flagString(parsed.flags, "agent")
|
|
263
|
+
});
|
|
264
|
+
console.log(`Installed ${result.skills?.length ?? explicitSkills.length} skill(s) with ${result.count ?? 0} command(s).`);
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
const preset = explicitPreset ?? "default";
|
|
245
268
|
const result = await installSkills(root, preset, {
|
|
246
269
|
agent: flagString(parsed.flags, "agent")
|
|
247
270
|
});
|
|
@@ -516,6 +539,7 @@ function printCreateHelp() {
|
|
|
516
539
|
" --install-skills Install project-local skills without prompting.",
|
|
517
540
|
" --no-install-skills Skip project-local skill installation.",
|
|
518
541
|
" --install-mcp-tools Run finite external MCP install commands after creation.",
|
|
542
|
+
" --no-install-mcp-tools Skip finite external MCP install commands.",
|
|
519
543
|
" -h, --help Show this help.",
|
|
520
544
|
" -v, --version Show package version."
|
|
521
545
|
].join("\n"));
|
|
@@ -568,13 +592,17 @@ function printAgentsHelp() {
|
|
|
568
592
|
}
|
|
569
593
|
function printSkillsHelp() {
|
|
570
594
|
console.log([
|
|
571
|
-
"Usage: academic-research skills <list|status|presets|install|remove|uninstall|update> [options]",
|
|
595
|
+
"Usage: academic-research skills <list|status|presets|install|remove|uninstall|update> [skill-id...] [options]",
|
|
572
596
|
"",
|
|
573
597
|
"Manage project-local skill installs for a generated research repository.",
|
|
574
598
|
"",
|
|
599
|
+
"Examples:",
|
|
600
|
+
" academic-research skills install --preset default",
|
|
601
|
+
" academic-research skills install source-ingestion sota-literature-review",
|
|
602
|
+
"",
|
|
575
603
|
"Options:",
|
|
576
604
|
" --root <path> Project root for list, status, install, remove, uninstall, update.",
|
|
577
|
-
" --preset <name> Capability preset for install.",
|
|
605
|
+
" --preset <name> Capability preset for install when no skill ids are provided.",
|
|
578
606
|
" --agent <id> Agent selector for install. Default: project capability agent.",
|
|
579
607
|
" -h, --help Show this help."
|
|
580
608
|
].join("\n"));
|
package/dist/src/project.js
CHANGED
|
@@ -214,7 +214,7 @@ async function writeGeneratedPackageJson(root, { slug }) {
|
|
|
214
214
|
const path = join(root, "package.json");
|
|
215
215
|
const data = await readJson(path);
|
|
216
216
|
const existingSpec = data.devDependencies?.["create-academic-research"];
|
|
217
|
-
const packageSpec = process.env.CREATE_ACADEMIC_RESEARCH_PACKAGE_SPEC ?? existingSpec ?? "0.1.
|
|
217
|
+
const packageSpec = process.env.CREATE_ACADEMIC_RESEARCH_PACKAGE_SPEC ?? existingSpec ?? "0.1.8";
|
|
218
218
|
data.name = slug;
|
|
219
219
|
data.devDependencies = {
|
|
220
220
|
...(data.devDependencies ?? {}),
|
package/dist/src/stack.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ export interface SkillBundle {
|
|
|
2
2
|
description: string;
|
|
3
3
|
commands: string[];
|
|
4
4
|
}
|
|
5
|
+
export interface SkillSource {
|
|
6
|
+
description: string;
|
|
7
|
+
source: string;
|
|
8
|
+
skills: string[];
|
|
9
|
+
}
|
|
5
10
|
export interface CapabilityPreset {
|
|
6
11
|
description: string;
|
|
7
12
|
skill_bundles: string[];
|
|
@@ -30,6 +35,7 @@ export interface AgentStack {
|
|
|
30
35
|
version: number;
|
|
31
36
|
description: string;
|
|
32
37
|
skill_bundles: Record<string, SkillBundle>;
|
|
38
|
+
skill_sources: Record<string, SkillSource>;
|
|
33
39
|
presets: Record<string, CapabilityPreset>;
|
|
34
40
|
mcp_servers: Record<string, McpServer>;
|
|
35
41
|
}
|
package/dist/src/stack.js
CHANGED
|
@@ -22,6 +22,76 @@ export const AGENT_STACK = {
|
|
|
22
22
|
]
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
|
+
skill_sources: {
|
|
26
|
+
academic_research: {
|
|
27
|
+
description: "Academic research skills maintained by this project.",
|
|
28
|
+
source: "VincenzoImp/academic-research-skills",
|
|
29
|
+
skills: [
|
|
30
|
+
"academic-mcp-tooling",
|
|
31
|
+
"adversarial-peer-review",
|
|
32
|
+
"artifact-open-science",
|
|
33
|
+
"citation-bibliography-tooling",
|
|
34
|
+
"citation-claim-audit",
|
|
35
|
+
"cs-methodology-evaluation",
|
|
36
|
+
"cs-venue-strategy",
|
|
37
|
+
"document-conversion",
|
|
38
|
+
"ethics-data-governance",
|
|
39
|
+
"experiment-logbook",
|
|
40
|
+
"paper-writing-review",
|
|
41
|
+
"rebuttal-revision-strategy",
|
|
42
|
+
"repo-migration",
|
|
43
|
+
"research-data-analysis",
|
|
44
|
+
"research-design-positioning",
|
|
45
|
+
"research-project-maintenance",
|
|
46
|
+
"research-project-router",
|
|
47
|
+
"research-repo-reproduction",
|
|
48
|
+
"research-ui-prototyping",
|
|
49
|
+
"skill-evaluation",
|
|
50
|
+
"sota-literature-review",
|
|
51
|
+
"source-ingestion",
|
|
52
|
+
"systematic-review-prisma"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
superpowers: {
|
|
56
|
+
description: "General agent engineering skills from Superpowers.",
|
|
57
|
+
source: "obra/superpowers",
|
|
58
|
+
skills: [
|
|
59
|
+
"brainstorming",
|
|
60
|
+
"dispatching-parallel-agents",
|
|
61
|
+
"executing-plans",
|
|
62
|
+
"finishing-a-development-branch",
|
|
63
|
+
"receiving-code-review",
|
|
64
|
+
"requesting-code-review",
|
|
65
|
+
"subagent-driven-development",
|
|
66
|
+
"systematic-debugging",
|
|
67
|
+
"test-driven-development",
|
|
68
|
+
"using-git-worktrees",
|
|
69
|
+
"using-superpowers",
|
|
70
|
+
"verification-before-completion",
|
|
71
|
+
"writing-plans",
|
|
72
|
+
"writing-skills"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
anthropics: {
|
|
76
|
+
description: "Document, frontend, testing, MCP, and skill-authoring helpers.",
|
|
77
|
+
source: "anthropics/skills",
|
|
78
|
+
skills: [
|
|
79
|
+
"docx",
|
|
80
|
+
"frontend-design",
|
|
81
|
+
"mcp-builder",
|
|
82
|
+
"pdf",
|
|
83
|
+
"pptx",
|
|
84
|
+
"skill-creator",
|
|
85
|
+
"webapp-testing",
|
|
86
|
+
"xlsx"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
docling: {
|
|
90
|
+
description: "Document conversion helper from the Beagle collection.",
|
|
91
|
+
source: "existential-birds/beagle",
|
|
92
|
+
skills: ["docling"]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
25
95
|
presets: {
|
|
26
96
|
minimal: {
|
|
27
97
|
description: "Academic research skills only, no MCP records.",
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -57,6 +57,7 @@ npx academic-research skills presets
|
|
|
57
57
|
npx academic-research agents list
|
|
58
58
|
npx academic-research skills install --preset default
|
|
59
59
|
npx academic-research skills install --preset enhanced
|
|
60
|
+
npx academic-research skills install source-ingestion sota-literature-review
|
|
60
61
|
npx academic-research skills list
|
|
61
62
|
npx academic-research skills status
|
|
62
63
|
npx academic-research setup
|