create-academic-research 0.1.6 → 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 +18 -4
- package/dist/src/capabilities.d.ts +3 -0
- package/dist/src/capabilities.js +74 -0
- package/dist/src/cli.js +151 -12
- package/dist/src/project.js +9 -2
- package/dist/src/stack.d.ts +6 -0
- package/dist/src/stack.js +70 -0
- package/package.json +1 -1
- package/template/AGENTS.md +5 -1
- package/template/README.md +10 -0
- package/template/package.json +3 -1
- package/template/scripts/README.md +10 -0
- package/template/tests/test_project_structure.py +7 -0
- package/template/wiki/index.md +9 -0
- package/template/wiki/templates/claim-page.md +24 -0
- package/template/wiki/templates/decision-record.md +26 -0
- package/template/wiki/templates/experiment-page.md +30 -0
- package/template/wiki/templates/research-question.md +27 -0
- package/template/wiki/templates/reviewer-concern.md +25 -0
- package/template/wiki/templates/source-page.md +31 -0
- package/template/wiki/templates/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -53,6 +53,9 @@ By default, the wizard:
|
|
|
53
53
|
- writes `docs/agent/capability-profile.md`;
|
|
54
54
|
- writes `docs/agent/mcp-setup.md`;
|
|
55
55
|
- writes `docs/agent/generated/mcp.json` unless an explicit agent target is set;
|
|
56
|
+
- includes `scripts/README.md` for repeatable command entrypoints;
|
|
57
|
+
- includes reusable `wiki/templates/` pages for sources, claims, experiments,
|
|
58
|
+
decisions, reviewer concerns, and research questions;
|
|
56
59
|
- appends the onboarding event to `wiki/log.md`;
|
|
57
60
|
- does not install external MCP tools unless explicitly requested.
|
|
58
61
|
|
|
@@ -84,11 +87,13 @@ Inside a generated project:
|
|
|
84
87
|
|
|
85
88
|
```bash
|
|
86
89
|
npx academic-research doctor
|
|
90
|
+
npx academic-research setup
|
|
87
91
|
npx academic-research rename --title "New Title" --slug new-title --package new_title
|
|
88
92
|
npx academic-research agents list
|
|
89
93
|
npx academic-research skills presets
|
|
90
94
|
npx academic-research skills install --preset default
|
|
91
95
|
npx academic-research skills install --preset enhanced
|
|
96
|
+
npx academic-research skills install source-ingestion sota-literature-review
|
|
92
97
|
npx academic-research skills list
|
|
93
98
|
npx academic-research skills status
|
|
94
99
|
npx academic-research skills remove source-ingestion
|
|
@@ -99,21 +104,26 @@ npx academic-research mcp enabled
|
|
|
99
104
|
npx academic-research mcp available
|
|
100
105
|
npx academic-research mcp commands arxiv
|
|
101
106
|
npx academic-research mcp env openalex semantic-scholar zotero
|
|
102
|
-
npx academic-research mcp enable arxiv
|
|
107
|
+
npx academic-research mcp enable arxiv dblp
|
|
103
108
|
npx academic-research mcp disable arxiv
|
|
104
109
|
npx academic-research mcp install arxiv
|
|
105
110
|
npx academic-research mcp uninstall arxiv
|
|
111
|
+
npx academic-research mcp smoke
|
|
106
112
|
npx academic-research mcp doctor
|
|
107
113
|
```
|
|
108
114
|
|
|
109
115
|
## Command Model
|
|
110
116
|
|
|
117
|
+
`academic-research setup` is a non-destructive onboarding status command. It
|
|
118
|
+
prints the active preset, agent, skill counts, enabled MCP records, and next
|
|
119
|
+
commands without changing files.
|
|
120
|
+
|
|
111
121
|
Skills are project-local by default.
|
|
112
122
|
|
|
113
123
|
| Command | Meaning |
|
|
114
124
|
|---|---|
|
|
115
125
|
| `skills presets` | List available capability presets. |
|
|
116
|
-
| `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. |
|
|
117
127
|
| `skills list` | List skills found in project-local skill loader directories. |
|
|
118
128
|
| `skills status` | Show configured project preset, agent, scope, skill roots, unique skill ids, and installed copies. |
|
|
119
129
|
| `skills remove` / `skills uninstall` | Remove selected project-local skills. |
|
|
@@ -132,6 +142,7 @@ MCP commands are split by side-effect:
|
|
|
132
142
|
| `mcp disable` | Remove an MCP server from project records and generated snippets. |
|
|
133
143
|
| `mcp install` | Run finite external tool install commands for selected MCP servers. It must not launch stdio MCP servers. |
|
|
134
144
|
| `mcp uninstall` | Run the external uninstall command when one exists. |
|
|
145
|
+
| `mcp smoke` | Print non-launching readiness diagnostics for enabled or selected MCP servers. |
|
|
135
146
|
| `mcp doctor` | Validate enabled MCP records, generated snippets, required env vars, and documented manual prerequisites. |
|
|
136
147
|
|
|
137
148
|
## Companion Skills
|
|
@@ -185,6 +196,9 @@ live tools by themselves. Your MCP client must load the generated snippet, and
|
|
|
185
196
|
the referenced commands must be available on your machine or runnable through
|
|
186
197
|
`uvx`/`npx`. `mcp install` only runs finite setup commands such as the arXiv
|
|
187
198
|
tool install; it deliberately does not launch stdio MCP servers.
|
|
199
|
+
Use `mcp smoke` for a non-launching readiness pass before wiring a client: it
|
|
200
|
+
checks required env vars, manual/local-service status, and whether runtime
|
|
201
|
+
commands are visible on `PATH`.
|
|
188
202
|
|
|
189
203
|
## Validate This Package
|
|
190
204
|
|
|
@@ -202,8 +216,8 @@ Releases are tag-driven. Update `package.json` and `package-lock.json`, commit
|
|
|
202
216
|
the change, create `vX.Y.Z`, and push the tag:
|
|
203
217
|
|
|
204
218
|
```bash
|
|
205
|
-
git tag -a v0.1.
|
|
206
|
-
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
|
|
207
221
|
```
|
|
208
222
|
|
|
209
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
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { basename, dirname, join, resolve } from "node:path";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
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,
|
|
@@ -100,6 +113,8 @@ async function lifecycleMain(argv) {
|
|
|
100
113
|
}
|
|
101
114
|
if (command === "doctor")
|
|
102
115
|
return doctorCommand(argv.slice(1));
|
|
116
|
+
if (command === "setup")
|
|
117
|
+
return setupCommand(argv.slice(1));
|
|
103
118
|
if (command === "rename")
|
|
104
119
|
return renameCommand(argv.slice(1));
|
|
105
120
|
if (command === "agents")
|
|
@@ -125,6 +140,41 @@ async function doctorCommand(argv) {
|
|
|
125
140
|
console.log(`OK: ${root}`);
|
|
126
141
|
return result.ok ? 0 : 1;
|
|
127
142
|
}
|
|
143
|
+
async function setupCommand(argv) {
|
|
144
|
+
const parsed = parseFlags(argv, ROOT_FLAGS);
|
|
145
|
+
if (flagBool(parsed.flags, "help")) {
|
|
146
|
+
printSetupHelp();
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
assertNoArguments(parsed.positionals, "setup");
|
|
150
|
+
const root = resolve(flagString(parsed.flags, "root") ?? ".");
|
|
151
|
+
const project = await doctorProject(root);
|
|
152
|
+
const state = await readCapabilities(root);
|
|
153
|
+
const skills = await listInstalledSkills(root);
|
|
154
|
+
const skillIds = new Set(skills.map((skill) => skill.name));
|
|
155
|
+
console.log("Project Setup");
|
|
156
|
+
console.log(`root\t${root}`);
|
|
157
|
+
console.log(`doctor\t${project.ok ? "ok" : "error"}`);
|
|
158
|
+
console.log(`agent\t${state.agent}`);
|
|
159
|
+
console.log(`preset\t${state.preset}`);
|
|
160
|
+
console.log(`scope\t${state.scope}`);
|
|
161
|
+
console.log(`installed_skill_ids\t${skillIds.size}`);
|
|
162
|
+
console.log(`installed_skill_copies\t${skills.length}`);
|
|
163
|
+
console.log(`mcp_enabled\t${state.mcp_servers.length > 0 ? state.mcp_servers.join(",") : "none"}`);
|
|
164
|
+
if (!project.ok) {
|
|
165
|
+
for (const error of project.errors)
|
|
166
|
+
console.error(`ERROR: ${error}`);
|
|
167
|
+
}
|
|
168
|
+
console.log("");
|
|
169
|
+
console.log("Next Commands");
|
|
170
|
+
console.log(`academic-research skills install --preset ${state.preset}`);
|
|
171
|
+
console.log("academic-research skills status");
|
|
172
|
+
console.log("academic-research mcp list");
|
|
173
|
+
console.log("academic-research mcp env");
|
|
174
|
+
console.log("academic-research mcp smoke");
|
|
175
|
+
console.log("academic-research doctor");
|
|
176
|
+
return project.ok ? 0 : 1;
|
|
177
|
+
}
|
|
128
178
|
async function renameCommand(argv) {
|
|
129
179
|
const parsed = parseFlags(argv, RENAME_FLAGS);
|
|
130
180
|
if (flagBool(parsed.flags, "help")) {
|
|
@@ -203,8 +253,18 @@ async function skillsCommand(argv) {
|
|
|
203
253
|
if (subcommand === "install") {
|
|
204
254
|
assertOnlyOptions(parsed.flags, "skills install", ["root", "preset", "agent"]);
|
|
205
255
|
const root = resolve(flagString(parsed.flags, "root") ?? ".");
|
|
206
|
-
|
|
207
|
-
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";
|
|
208
268
|
const result = await installSkills(root, preset, {
|
|
209
269
|
agent: flagString(parsed.flags, "agent")
|
|
210
270
|
});
|
|
@@ -317,6 +377,24 @@ async function mcpCommand(argv) {
|
|
|
317
377
|
console.log(`Ran ${result.count ?? 0} MCP uninstall command(s).`);
|
|
318
378
|
return 0;
|
|
319
379
|
}
|
|
380
|
+
if (subcommand === "smoke") {
|
|
381
|
+
assertOnlyOptions(parsed.flags, "mcp smoke", ["root"]);
|
|
382
|
+
const root = resolve(flagString(parsed.flags, "root") ?? ".");
|
|
383
|
+
const state = await readCapabilities(root);
|
|
384
|
+
const explicitSelection = parsed.positionals.length > 0;
|
|
385
|
+
const selected = explicitSelection ? parsed.positionals : state.mcp_servers;
|
|
386
|
+
assertKnownMcpServers(selected);
|
|
387
|
+
const failed = printMcpSmokeDiagnostics(selected);
|
|
388
|
+
if (!explicitSelection) {
|
|
389
|
+
const result = await doctorMcpServers(root);
|
|
390
|
+
for (const error of result.errors)
|
|
391
|
+
console.error(`ERROR: ${error}`);
|
|
392
|
+
for (const warning of result.warnings)
|
|
393
|
+
console.warn(`WARN: ${warning}`);
|
|
394
|
+
return result.ok && !failed ? 0 : 1;
|
|
395
|
+
}
|
|
396
|
+
return failed ? 1 : 0;
|
|
397
|
+
}
|
|
320
398
|
if (subcommand === "doctor") {
|
|
321
399
|
assertOnlyOptions(parsed.flags, "mcp doctor", ["root"]);
|
|
322
400
|
const root = resolve(flagString(parsed.flags, "root") ?? ".");
|
|
@@ -461,6 +539,7 @@ function printCreateHelp() {
|
|
|
461
539
|
" --install-skills Install project-local skills without prompting.",
|
|
462
540
|
" --no-install-skills Skip project-local skill installation.",
|
|
463
541
|
" --install-mcp-tools Run finite external MCP install commands after creation.",
|
|
542
|
+
" --no-install-mcp-tools Skip finite external MCP install commands.",
|
|
464
543
|
" -h, --help Show this help.",
|
|
465
544
|
" -v, --version Show package version."
|
|
466
545
|
].join("\n"));
|
|
@@ -476,7 +555,7 @@ function printMissingTargetHelp() {
|
|
|
476
555
|
}
|
|
477
556
|
function printLifecycleHelp() {
|
|
478
557
|
console.log([
|
|
479
|
-
"Usage: academic-research <doctor|rename|agents|skills|mcp>",
|
|
558
|
+
"Usage: academic-research <doctor|setup|rename|agents|skills|mcp>",
|
|
480
559
|
"",
|
|
481
560
|
"Manage a generated academic research repository after creation.",
|
|
482
561
|
"",
|
|
@@ -485,6 +564,17 @@ function printLifecycleHelp() {
|
|
|
485
564
|
" -v, --version Show package version."
|
|
486
565
|
].join("\n"));
|
|
487
566
|
}
|
|
567
|
+
function printSetupHelp() {
|
|
568
|
+
console.log([
|
|
569
|
+
"Usage: academic-research setup [options]",
|
|
570
|
+
"",
|
|
571
|
+
"Print project onboarding status and next commands without changing files.",
|
|
572
|
+
"",
|
|
573
|
+
"Options:",
|
|
574
|
+
" --root <path> Project root. Default: current directory.",
|
|
575
|
+
" -h, --help Show this help."
|
|
576
|
+
].join("\n"));
|
|
577
|
+
}
|
|
488
578
|
function printAgentsHelp() {
|
|
489
579
|
console.log([
|
|
490
580
|
"Usage: academic-research agents <list>",
|
|
@@ -502,22 +592,26 @@ function printAgentsHelp() {
|
|
|
502
592
|
}
|
|
503
593
|
function printSkillsHelp() {
|
|
504
594
|
console.log([
|
|
505
|
-
"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]",
|
|
506
596
|
"",
|
|
507
597
|
"Manage project-local skill installs for a generated research repository.",
|
|
508
598
|
"",
|
|
599
|
+
"Examples:",
|
|
600
|
+
" academic-research skills install --preset default",
|
|
601
|
+
" academic-research skills install source-ingestion sota-literature-review",
|
|
602
|
+
"",
|
|
509
603
|
"Options:",
|
|
510
604
|
" --root <path> Project root for list, status, install, remove, uninstall, update.",
|
|
511
|
-
" --preset <name> Capability preset for install.",
|
|
605
|
+
" --preset <name> Capability preset for install when no skill ids are provided.",
|
|
512
606
|
" --agent <id> Agent selector for install. Default: project capability agent.",
|
|
513
607
|
" -h, --help Show this help."
|
|
514
608
|
].join("\n"));
|
|
515
609
|
}
|
|
516
610
|
function printMcpHelp() {
|
|
517
611
|
console.log([
|
|
518
|
-
"Usage: academic-research mcp <list|enabled|available|commands|env|enable|disable|install|uninstall|doctor> [servers...]",
|
|
612
|
+
"Usage: academic-research mcp <list|enabled|available|commands|env|enable|disable|install|uninstall|smoke|doctor> [servers...]",
|
|
519
613
|
"",
|
|
520
|
-
"Manage MCP records and finite external MCP tool installs.",
|
|
614
|
+
"Manage MCP records, readiness checks, and finite external MCP tool installs.",
|
|
521
615
|
"",
|
|
522
616
|
"Options:",
|
|
523
617
|
" --root <path> Project root for project-state commands.",
|
|
@@ -525,6 +619,32 @@ function printMcpHelp() {
|
|
|
525
619
|
" -h, --help Show this help."
|
|
526
620
|
].join("\n"));
|
|
527
621
|
}
|
|
622
|
+
function printMcpSmokeDiagnostics(servers) {
|
|
623
|
+
let failed = false;
|
|
624
|
+
console.log("id\tstatus\truntime\tcheck");
|
|
625
|
+
for (const name of servers) {
|
|
626
|
+
const server = AGENT_STACK.mcp_servers[name];
|
|
627
|
+
const missingRequired = server.required_env.filter((envName) => !process.env[envName]);
|
|
628
|
+
if (missingRequired.length > 0)
|
|
629
|
+
failed = true;
|
|
630
|
+
const runtime = server.command ? [server.command, ...server.args].join(" ") : "manual setup";
|
|
631
|
+
let status = "manual";
|
|
632
|
+
if (missingRequired.length > 0) {
|
|
633
|
+
status = `missing-required-env:${missingRequired.join(",")}`;
|
|
634
|
+
}
|
|
635
|
+
else if (server.command && commandExists(server.command)) {
|
|
636
|
+
status = "runtime-found";
|
|
637
|
+
}
|
|
638
|
+
else if (server.command) {
|
|
639
|
+
status = "runtime-missing";
|
|
640
|
+
}
|
|
641
|
+
else if (server.local_service) {
|
|
642
|
+
status = "manual-local-service";
|
|
643
|
+
}
|
|
644
|
+
console.log(`${name}\t${status}\t${runtime}\t${server.smoke_test}`);
|
|
645
|
+
}
|
|
646
|
+
return failed;
|
|
647
|
+
}
|
|
528
648
|
function printMcpEnvironment(servers) {
|
|
529
649
|
for (const name of servers) {
|
|
530
650
|
const server = AGENT_STACK.mcp_servers[name];
|
|
@@ -553,6 +673,25 @@ function printMcpEnvironment(servers) {
|
|
|
553
673
|
console.log(`${name}\tnone\t-`);
|
|
554
674
|
}
|
|
555
675
|
}
|
|
676
|
+
function commandExists(command) {
|
|
677
|
+
if (!command)
|
|
678
|
+
return false;
|
|
679
|
+
if (command.includes("/") || command.includes("\\"))
|
|
680
|
+
return existsSync(command);
|
|
681
|
+
const pathValue = process.env.PATH ?? "";
|
|
682
|
+
const extensions = process.platform === "win32"
|
|
683
|
+
? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";")
|
|
684
|
+
: [""];
|
|
685
|
+
for (const directory of pathValue.split(delimiter).filter(Boolean)) {
|
|
686
|
+
for (const extension of extensions) {
|
|
687
|
+
const hasExtension = extension && command.toLowerCase().endsWith(extension.toLowerCase());
|
|
688
|
+
const candidate = join(directory, hasExtension ? command : `${command}${extension}`);
|
|
689
|
+
if (existsSync(candidate))
|
|
690
|
+
return true;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
556
695
|
function readPackageVersion() {
|
|
557
696
|
try {
|
|
558
697
|
const packageJson = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8"));
|
package/dist/src/project.js
CHANGED
|
@@ -138,10 +138,17 @@ export async function doctorProject(root) {
|
|
|
138
138
|
"docs/agent/capability-profile.md",
|
|
139
139
|
"docs/agent/mcp-setup.md",
|
|
140
140
|
"docs/agent/generated",
|
|
141
|
+
"scripts/README.md",
|
|
141
142
|
"sources/source-ledger.csv",
|
|
142
143
|
"sota/literature-matrix.csv",
|
|
143
144
|
"wiki/index.md",
|
|
144
|
-
"wiki/log.md"
|
|
145
|
+
"wiki/log.md",
|
|
146
|
+
"wiki/templates/source-page.md",
|
|
147
|
+
"wiki/templates/claim-page.md",
|
|
148
|
+
"wiki/templates/experiment-page.md",
|
|
149
|
+
"wiki/templates/decision-record.md",
|
|
150
|
+
"wiki/templates/reviewer-concern.md",
|
|
151
|
+
"wiki/templates/research-question.md"
|
|
145
152
|
];
|
|
146
153
|
for (const relative of required) {
|
|
147
154
|
if (!(await exists(join(target, relative))))
|
|
@@ -207,7 +214,7 @@ async function writeGeneratedPackageJson(root, { slug }) {
|
|
|
207
214
|
const path = join(root, "package.json");
|
|
208
215
|
const data = await readJson(path);
|
|
209
216
|
const existingSpec = data.devDependencies?.["create-academic-research"];
|
|
210
|
-
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";
|
|
211
218
|
data.name = slug;
|
|
212
219
|
data.devDependencies = {
|
|
213
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/AGENTS.md
CHANGED
|
@@ -6,7 +6,8 @@ scholarly record.
|
|
|
6
6
|
## Core Rules
|
|
7
7
|
|
|
8
8
|
- Preserve source originals under `sources/`, `data/raw/`, and `data/external/`.
|
|
9
|
-
- Keep reusable logic in `src/`; keep
|
|
9
|
+
- Keep reusable logic in `src/`; keep `scripts/` as thin repeatable entrypoints.
|
|
10
|
+
- Keep notebooks for exploration and narrative output.
|
|
10
11
|
- Tie claims to sources, datasets, experiment records, or decision records.
|
|
11
12
|
- Update durable records when project knowledge changes.
|
|
12
13
|
- Keep large data, generated caches, credentials, and private review material out of git.
|
|
@@ -35,6 +36,8 @@ scholarly record.
|
|
|
35
36
|
- `wiki/synthesis.md` changes only when the project-level interpretation changes.
|
|
36
37
|
- `wiki/open_questions.md` tracks unresolved questions.
|
|
37
38
|
- `wiki/contradictions.md` tracks conflicts across sources, data, or runs.
|
|
39
|
+
- `wiki/templates/` contains reusable source, claim, experiment, decision,
|
|
40
|
+
reviewer-concern, and research-question page structures.
|
|
38
41
|
|
|
39
42
|
## Evidence
|
|
40
43
|
|
|
@@ -45,3 +48,4 @@ scholarly record.
|
|
|
45
48
|
- Citation issues go in `sources/bib/citation-audit.csv`.
|
|
46
49
|
- SOTA records go in `sota/`.
|
|
47
50
|
- Curated experiment records go in `experiments/`.
|
|
51
|
+
- Repeatable command entrypoints go in `scripts/`.
|
package/template/README.md
CHANGED
|
@@ -41,6 +41,7 @@ npx academic-research doctor
|
|
|
41
41
|
- `docs/agent/`: active agent workflows, capability profile, and MCP setup.
|
|
42
42
|
- `docs/methodology/`: research design, evaluation plan, and validity threats.
|
|
43
43
|
- `experiments/`: curated experiment registry and run records.
|
|
44
|
+
- `scripts/`: thin repeatable entrypoints that call reusable code in `src/`.
|
|
44
45
|
- `notebooks/`: optional exploratory and narrative notebooks.
|
|
45
46
|
- `outputs/`: final figures, tables, models, and paper-supporting derived assets.
|
|
46
47
|
- `reports/`: proposal, paper, slides, reviews, and rebuttal material.
|
|
@@ -56,13 +57,16 @@ npx academic-research skills presets
|
|
|
56
57
|
npx academic-research agents list
|
|
57
58
|
npx academic-research skills install --preset default
|
|
58
59
|
npx academic-research skills install --preset enhanced
|
|
60
|
+
npx academic-research skills install source-ingestion sota-literature-review
|
|
59
61
|
npx academic-research skills list
|
|
60
62
|
npx academic-research skills status
|
|
63
|
+
npx academic-research setup
|
|
61
64
|
npx academic-research mcp list
|
|
62
65
|
npx academic-research mcp env openalex semantic-scholar zotero
|
|
63
66
|
npx academic-research mcp enable arxiv dblp
|
|
64
67
|
npx academic-research mcp commands arxiv
|
|
65
68
|
npx academic-research mcp install arxiv
|
|
69
|
+
npx academic-research mcp smoke
|
|
66
70
|
npx academic-research mcp doctor
|
|
67
71
|
```
|
|
68
72
|
|
|
@@ -74,6 +78,12 @@ enable optional servers. `mcp install` runs only finite tool installation
|
|
|
74
78
|
commands; runtime-only `uvx`/`npx` MCP servers may have no install step and are
|
|
75
79
|
started later by the MCP client.
|
|
76
80
|
|
|
81
|
+
`setup` prints the current project capability state, installed skill counts,
|
|
82
|
+
enabled MCP records, and the next onboarding commands without changing files.
|
|
83
|
+
`mcp smoke` performs a non-launching MCP readiness check: it reports required
|
|
84
|
+
env vars, local/manual setup, and whether client runtime commands such as `uvx`
|
|
85
|
+
or `npx` are available.
|
|
86
|
+
|
|
77
87
|
`default` installs the companion academic research skill package and keeps the
|
|
78
88
|
MCP records focused on low-friction arXiv discovery. `literature` and `full`
|
|
79
89
|
add DBLP for computer science bibliography. Credentialed, local-service, or
|
package/template/package.json
CHANGED
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"doctor": "academic-research doctor",
|
|
7
|
+
"setup": "academic-research setup",
|
|
7
8
|
"skills:install": "academic-research skills install --preset default",
|
|
8
9
|
"skills:list": "academic-research skills list",
|
|
9
10
|
"skills:presets": "academic-research skills presets",
|
|
10
11
|
"mcp:list": "academic-research mcp list",
|
|
11
12
|
"mcp:commands": "academic-research mcp commands",
|
|
12
13
|
"mcp:env": "academic-research mcp env",
|
|
14
|
+
"mcp:smoke": "academic-research mcp smoke",
|
|
13
15
|
"mcp:doctor": "academic-research mcp doctor"
|
|
14
16
|
},
|
|
15
17
|
"devDependencies": {
|
|
16
|
-
"create-academic-research": "0.1.
|
|
18
|
+
"create-academic-research": "0.1.8"
|
|
17
19
|
}
|
|
18
20
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Scripts
|
|
2
|
+
|
|
3
|
+
Use this folder for thin, repeatable command entrypoints.
|
|
4
|
+
|
|
5
|
+
Scripts should orchestrate project code, not contain core scientific logic. Put
|
|
6
|
+
reusable methods, models, data transforms, and analysis functions in `src/`.
|
|
7
|
+
|
|
8
|
+
Each script should make its inputs, outputs, config path, and expected side
|
|
9
|
+
effects clear enough to reproduce later from `docs/reproducibility/` or an
|
|
10
|
+
experiment record.
|
|
@@ -8,6 +8,7 @@ def test_core_research_structure_exists() -> None:
|
|
|
8
8
|
"configs/default.yaml",
|
|
9
9
|
"configs/capabilities.yaml",
|
|
10
10
|
"docs/agent/capability-profile.md",
|
|
11
|
+
"scripts/README.md",
|
|
11
12
|
"notebooks/README.md",
|
|
12
13
|
"outputs/figures",
|
|
13
14
|
"outputs/tables",
|
|
@@ -21,5 +22,11 @@ def test_core_research_structure_exists() -> None:
|
|
|
21
22
|
"sota/literature-matrix.csv",
|
|
22
23
|
"wiki/index.md",
|
|
23
24
|
"wiki/log.md",
|
|
25
|
+
"wiki/templates/source-page.md",
|
|
26
|
+
"wiki/templates/claim-page.md",
|
|
27
|
+
"wiki/templates/experiment-page.md",
|
|
28
|
+
"wiki/templates/decision-record.md",
|
|
29
|
+
"wiki/templates/reviewer-concern.md",
|
|
30
|
+
"wiki/templates/research-question.md",
|
|
24
31
|
):
|
|
25
32
|
assert (root / relative).exists()
|
package/template/wiki/index.md
CHANGED
|
@@ -7,3 +7,12 @@ This is the content index for the LLM-maintained project wiki.
|
|
|
7
7
|
- [[synthesis]]
|
|
8
8
|
- [[open_questions]]
|
|
9
9
|
- [[contradictions]]
|
|
10
|
+
|
|
11
|
+
## Templates
|
|
12
|
+
|
|
13
|
+
- [[templates/source-page]]
|
|
14
|
+
- [[templates/claim-page]]
|
|
15
|
+
- [[templates/experiment-page]]
|
|
16
|
+
- [[templates/decision-record]]
|
|
17
|
+
- [[templates/reviewer-concern]]
|
|
18
|
+
- [[templates/research-question]]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Claim: <claim_id>
|
|
2
|
+
|
|
3
|
+
## Claim
|
|
4
|
+
|
|
5
|
+
<fill: atomic claim>
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
- Verdict:
|
|
10
|
+
- Confidence:
|
|
11
|
+
- Last checked:
|
|
12
|
+
|
|
13
|
+
## Evidence
|
|
14
|
+
|
|
15
|
+
| source_or_run_id | path | support_span | verdict | notes |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
|
|
18
|
+
## Safe Wording
|
|
19
|
+
|
|
20
|
+
<fill: wording that current evidence supports>
|
|
21
|
+
|
|
22
|
+
## Risk
|
|
23
|
+
|
|
24
|
+
<fill: what would weaken, falsify, or narrow this claim>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Decision: <decision_id>
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
<fill: situation and constraints>
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
<fill: chosen option>
|
|
10
|
+
|
|
11
|
+
## Alternatives Considered
|
|
12
|
+
|
|
13
|
+
| option | reason rejected |
|
|
14
|
+
|---|---|
|
|
15
|
+
|
|
16
|
+
## Evidence
|
|
17
|
+
|
|
18
|
+
- Sources:
|
|
19
|
+
- Experiments:
|
|
20
|
+
- Reviews:
|
|
21
|
+
|
|
22
|
+
## Consequences
|
|
23
|
+
|
|
24
|
+
- Expected benefit:
|
|
25
|
+
- Risk:
|
|
26
|
+
- Review date:
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Experiment: <run_id>
|
|
2
|
+
|
|
3
|
+
## Question
|
|
4
|
+
|
|
5
|
+
<fill: research question or hypothesis>
|
|
6
|
+
|
|
7
|
+
## Run
|
|
8
|
+
|
|
9
|
+
- Date:
|
|
10
|
+
- Git commit:
|
|
11
|
+
- Command:
|
|
12
|
+
- Config:
|
|
13
|
+
- Seed:
|
|
14
|
+
- Dataset:
|
|
15
|
+
- Metric:
|
|
16
|
+
- Output path:
|
|
17
|
+
|
|
18
|
+
## Result
|
|
19
|
+
|
|
20
|
+
<fill: measured outcome>
|
|
21
|
+
|
|
22
|
+
## Interpretation
|
|
23
|
+
|
|
24
|
+
<fill: claim status, limitations, and next action>
|
|
25
|
+
|
|
26
|
+
## Links
|
|
27
|
+
|
|
28
|
+
- Registry row: `experiments/registry.csv`
|
|
29
|
+
- Related claims:
|
|
30
|
+
- Related sources:
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Research Question: <rq_id>
|
|
2
|
+
|
|
3
|
+
## Question
|
|
4
|
+
|
|
5
|
+
<fill: answerable research question>
|
|
6
|
+
|
|
7
|
+
## Scope
|
|
8
|
+
|
|
9
|
+
- Population/domain:
|
|
10
|
+
- Evidence type:
|
|
11
|
+
- Exclusions:
|
|
12
|
+
|
|
13
|
+
## Contribution Link
|
|
14
|
+
|
|
15
|
+
- Candidate claim:
|
|
16
|
+
- Closest prior work:
|
|
17
|
+
- Delta:
|
|
18
|
+
- Failure condition:
|
|
19
|
+
|
|
20
|
+
## Evidence Plan
|
|
21
|
+
|
|
22
|
+
| evidence_needed | path_or_source | status | risk |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
|
|
25
|
+
## Current Status
|
|
26
|
+
|
|
27
|
+
<fill: hypothesis, active, answered, rejected, or out of scope>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Reviewer Concern: <concern_id>
|
|
2
|
+
|
|
3
|
+
## Concern
|
|
4
|
+
|
|
5
|
+
<fill: reviewer or internal-review concern>
|
|
6
|
+
|
|
7
|
+
## Classification
|
|
8
|
+
|
|
9
|
+
- Source:
|
|
10
|
+
- Severity:
|
|
11
|
+
- Paper location:
|
|
12
|
+
- Claim or issue:
|
|
13
|
+
- Action: concede | clarify | add-evidence | reframe | defend | defer
|
|
14
|
+
|
|
15
|
+
## Evidence
|
|
16
|
+
|
|
17
|
+
<fill: source, experiment, or manuscript evidence>
|
|
18
|
+
|
|
19
|
+
## Response Plan
|
|
20
|
+
|
|
21
|
+
<fill: exact response and manuscript change>
|
|
22
|
+
|
|
23
|
+
## Status
|
|
24
|
+
|
|
25
|
+
<fill: open, addressed, deferred, rejected with rationale>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Source: <source_id>
|
|
2
|
+
|
|
3
|
+
## Bibliographic Record
|
|
4
|
+
|
|
5
|
+
- Title:
|
|
6
|
+
- Authors:
|
|
7
|
+
- Year:
|
|
8
|
+
- Venue:
|
|
9
|
+
- Identifiers:
|
|
10
|
+
- Native path:
|
|
11
|
+
- Derived path:
|
|
12
|
+
- Metadata path:
|
|
13
|
+
|
|
14
|
+
## Summary
|
|
15
|
+
|
|
16
|
+
<fill: concise source summary>
|
|
17
|
+
|
|
18
|
+
## Evidence Record
|
|
19
|
+
|
|
20
|
+
- Supports:
|
|
21
|
+
- Contradicts:
|
|
22
|
+
- Method / data / metric:
|
|
23
|
+
- Limitations:
|
|
24
|
+
- Project relevance:
|
|
25
|
+
- Claim strength:
|
|
26
|
+
- Allowed wording:
|
|
27
|
+
- Forbidden stronger wording:
|
|
28
|
+
|
|
29
|
+
## Follow-Up
|
|
30
|
+
|
|
31
|
+
- <fill: unresolved checks>
|
|
File without changes
|