@johanesimm/fundamentum 0.1.0 → 0.2.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/README.md +46 -27
- package/bin/cli.mjs +176 -56
- package/package.json +1 -1
- package/primer/SKILL.md +9 -0
package/README.md
CHANGED
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
npx @johanesimm/fundamentum
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
then say *"Initialize this project
|
|
20
|
-
`blueprint`. Full walkthrough in
|
|
16
|
+
The installer asks **which coding agent you use** (Claude Code, Codex,
|
|
17
|
+
Cursor, Gemini CLI, Copilot, …), then installs the skills the way that
|
|
18
|
+
agent expects and preconfigures them for it — no repeated "which tool?"
|
|
19
|
+
questions later. Restart your agent, then say *"Initialize this project
|
|
20
|
+
documentation-first"* to kick off `blueprint`. Full walkthrough in
|
|
21
|
+
[Installation](#installation) below.
|
|
21
22
|
|
|
22
23
|
------------------------------------------------------------------------
|
|
23
24
|
|
|
@@ -110,7 +111,7 @@ jump straight to one phase, provided its inputs already exist.
|
|
|
110
111
|
### The `npx` installer (recommended)
|
|
111
112
|
|
|
112
113
|
**Prerequisites:** [Node.js](https://nodejs.org) 18+ (gives you `npx`)
|
|
113
|
-
and
|
|
114
|
+
and a supported coding agent.
|
|
114
115
|
|
|
115
116
|
**Step 1 — run the installer.** No global install needed; `npx` fetches
|
|
116
117
|
and runs it on the fly:
|
|
@@ -119,33 +120,49 @@ and runs it on the fly:
|
|
|
119
120
|
npx @johanesimm/fundamentum
|
|
120
121
|
```
|
|
121
122
|
|
|
122
|
-
**Step 2 —
|
|
123
|
+
**Step 2 — pick your agent (asked first).** Your choice decides where
|
|
124
|
+
the skills go *and* preconfigures `primer` to write the right
|
|
125
|
+
agent-context file — so nothing re-asks "which tool?" later:
|
|
123
126
|
|
|
124
127
|
```
|
|
125
128
|
Fundamentum — installing: blueprint, excavate, primer
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
1)
|
|
129
|
-
2)
|
|
130
|
-
|
|
130
|
+
Which coding agent do you use?
|
|
131
|
+
1) Claude Code (native skills)
|
|
132
|
+
2) Codex (wires into AGENTS.md)
|
|
133
|
+
3) Cursor (wires into AGENTS.md)
|
|
134
|
+
4) Gemini CLI (wires into GEMINI.md)
|
|
135
|
+
5) GitHub Copilot (wires into .github/copilot-instructions.md)
|
|
136
|
+
6) Other / generic (wires into AGENTS.md)
|
|
137
|
+
Choose [1-6]:
|
|
131
138
|
```
|
|
132
139
|
|
|
133
|
-
|
|
134
|
-
- **Project** → installed only into the repo you're currently in
|
|
135
|
-
(`./.claude/skills/`); commit them to share with your team.
|
|
140
|
+
How each agent is installed:
|
|
136
141
|
|
|
137
|
-
|
|
142
|
+
| Agent | Skills land in | How it's used |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| **Claude Code** | `.claude/skills/` (asks **global** vs **project**) | invoked natively as skills |
|
|
145
|
+
| **Codex / Cursor / Gemini / Copilot / Other** | `.fundamentum/skills/` (this project) | a pointer block is added to that agent's instructions file (`AGENTS.md` / `GEMINI.md` / `copilot-instructions.md`) telling it to follow the workflows |
|
|
146
|
+
|
|
147
|
+
For Claude Code you then choose **global** (every project) or
|
|
148
|
+
**project** (this repo only). Non-Claude agents are always wired into
|
|
149
|
+
the current project.
|
|
150
|
+
|
|
151
|
+
**Step 3 — done.** It copies the folders, wires things up, and confirms
|
|
152
|
+
— e.g. for Codex:
|
|
138
153
|
|
|
139
154
|
```
|
|
140
|
-
✓ blueprint →
|
|
141
|
-
✓ excavate →
|
|
142
|
-
✓ primer →
|
|
155
|
+
✓ blueprint → ./.fundamentum/skills/blueprint
|
|
156
|
+
✓ excavate → ./.fundamentum/skills/excavate
|
|
157
|
+
✓ primer → ./.fundamentum/skills/primer
|
|
143
158
|
|
|
144
|
-
Done. Installed 3 skill(s)
|
|
145
|
-
|
|
159
|
+
Done. Installed 3 skill(s) for Codex.
|
|
160
|
+
Wired into: ./AGENTS.md
|
|
161
|
+
primer is preconfigured to write AGENTS.md — it won't ask which agent.
|
|
146
162
|
```
|
|
147
163
|
|
|
148
|
-
**Step 4 — use them.** Restart
|
|
164
|
+
**Step 4 — use them.** Restart your agent (or start a new session),
|
|
165
|
+
then just ask:
|
|
149
166
|
|
|
150
167
|
| Say this | Runs |
|
|
151
168
|
|---|---|
|
|
@@ -156,12 +173,14 @@ Restart Claude Code (or start a new session) to pick them up.
|
|
|
156
173
|
### More installer options
|
|
157
174
|
|
|
158
175
|
```bash
|
|
159
|
-
npx @johanesimm/fundamentum
|
|
160
|
-
npx @johanesimm/fundamentum --
|
|
161
|
-
npx @johanesimm/fundamentum
|
|
162
|
-
npx @johanesimm/fundamentum --
|
|
163
|
-
npx @johanesimm/fundamentum
|
|
164
|
-
npx @johanesimm/fundamentum --
|
|
176
|
+
npx @johanesimm/fundamentum --agent claude # skip the agent prompt
|
|
177
|
+
npx @johanesimm/fundamentum --agent codex # wire into ./AGENTS.md
|
|
178
|
+
npx @johanesimm/fundamentum add primer # install just one skill (space-separate for several)
|
|
179
|
+
npx @johanesimm/fundamentum --agent claude --global # Claude: install for every project
|
|
180
|
+
npx @johanesimm/fundamentum --agent claude --project # Claude: install into ./.claude/skills
|
|
181
|
+
npx @johanesimm/fundamentum --force # overwrite existing skills without asking
|
|
182
|
+
npx @johanesimm/fundamentum list # show which skills are bundled
|
|
183
|
+
npx @johanesimm/fundamentum --help # full usage
|
|
165
184
|
```
|
|
166
185
|
|
|
167
186
|
### Run without npm (from source)
|
package/bin/cli.mjs
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Fundamentum skill installer
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Fundamentum skill installer.
|
|
3
|
+
//
|
|
4
|
+
// Asks which coding agent you use, then installs the skills the way that
|
|
5
|
+
// agent expects:
|
|
6
|
+
// - Claude Code -> copies invokable skills into ~/.claude/skills or
|
|
7
|
+
// ./.claude/skills (native SKILL.md skills).
|
|
8
|
+
// - Other agents -> copies the skill folders into ./.fundamentum/skills and
|
|
9
|
+
// wires a pointer block into that agent's instructions
|
|
10
|
+
// file (AGENTS.md / GEMINI.md / copilot-instructions.md),
|
|
11
|
+
// since those tools have no skill runtime.
|
|
12
|
+
// The chosen agent is baked into the installed `primer` skill so it never
|
|
13
|
+
// re-asks which agent-context file to generate.
|
|
14
|
+
//
|
|
15
|
+
// Zero dependencies: Node standard library only.
|
|
5
16
|
|
|
6
|
-
import { readdir, cp, mkdir } from 'node:fs/promises';
|
|
17
|
+
import { readdir, cp, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
7
18
|
import { existsSync } from 'node:fs';
|
|
8
19
|
import { fileURLToPath } from 'node:url';
|
|
9
20
|
import { dirname, join, resolve } from 'node:path';
|
|
@@ -14,27 +25,41 @@ import process from 'node:process';
|
|
|
14
25
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
15
26
|
const ROOT = resolve(HERE, '..'); // package root — where the skill folders live
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
// agent key -> how to install + which context file `primer` should write.
|
|
29
|
+
const AGENTS = {
|
|
30
|
+
claude: { label: 'Claude Code', file: 'CLAUDE.md', native: true },
|
|
31
|
+
codex: { label: 'Codex', file: 'AGENTS.md', native: false },
|
|
32
|
+
cursor: { label: 'Cursor', file: 'AGENTS.md', native: false },
|
|
33
|
+
gemini: { label: 'Gemini CLI', file: 'GEMINI.md', native: false },
|
|
34
|
+
copilot: { label: 'GitHub Copilot', file: '.github/copilot-instructions.md', native: false },
|
|
35
|
+
other: { label: 'Other / generic', file: 'AGENTS.md', native: false },
|
|
36
|
+
};
|
|
37
|
+
const AGENT_ORDER = ['claude', 'codex', 'cursor', 'gemini', 'copilot', 'other'];
|
|
38
|
+
const NONCLAUDE_SKILLS_DIR = '.fundamentum/skills'; // relative to the project root
|
|
39
|
+
|
|
40
|
+
const HELP = `fundamentum — install documentation-first coding-agent skills
|
|
18
41
|
|
|
19
42
|
Usage:
|
|
20
|
-
npx fundamentum [add] [skills...] [options]
|
|
21
|
-
npx fundamentum list
|
|
43
|
+
npx @johanesimm/fundamentum [add] [skills...] [options]
|
|
44
|
+
npx @johanesimm/fundamentum list
|
|
22
45
|
|
|
23
46
|
Arguments:
|
|
24
|
-
skills...
|
|
47
|
+
skills... Skills to install (default: all bundled skills)
|
|
25
48
|
|
|
26
49
|
Options:
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
50
|
+
--agent <name> claude | codex | cursor | gemini | copilot | other
|
|
51
|
+
-g, --global Claude Code only: install into ~/.claude/skills
|
|
52
|
+
-p, --project Install into the current project
|
|
53
|
+
-f, --force Overwrite existing skills without asking
|
|
54
|
+
-h, --help Show this help
|
|
31
55
|
|
|
32
|
-
With no --
|
|
56
|
+
With no --agent, you'll be asked which agent you use (asked first).
|
|
57
|
+
Non-Claude agents are always installed into the current project.
|
|
33
58
|
|
|
34
59
|
Examples:
|
|
35
|
-
npx fundamentum
|
|
36
|
-
npx fundamentum
|
|
37
|
-
npx fundamentum --
|
|
60
|
+
npx @johanesimm/fundamentum # ask everything
|
|
61
|
+
npx @johanesimm/fundamentum --agent claude -g # Claude, global, no prompts
|
|
62
|
+
npx @johanesimm/fundamentum --agent codex # wire into ./AGENTS.md
|
|
38
63
|
`;
|
|
39
64
|
|
|
40
65
|
/** Discover bundled skills = top-level dirs that contain a SKILL.md. */
|
|
@@ -51,35 +76,102 @@ async function discoverSkills() {
|
|
|
51
76
|
|
|
52
77
|
function parseArgs(argv) {
|
|
53
78
|
const args = [...argv];
|
|
54
|
-
// optional leading verb
|
|
55
79
|
if (['add', 'install', 'i'].includes(args[0])) args.shift();
|
|
56
80
|
const flags = new Set();
|
|
57
81
|
const names = [];
|
|
58
|
-
|
|
82
|
+
let agent = null;
|
|
83
|
+
for (let i = 0; i < args.length; i++) {
|
|
84
|
+
const a = args[i];
|
|
59
85
|
if (a === '-h' || a === '--help') flags.add('help');
|
|
60
86
|
else if (a === '-g' || a === '--global') flags.add('global');
|
|
61
87
|
else if (a === '-p' || a === '--project') flags.add('project');
|
|
62
88
|
else if (a === '-f' || a === '--force') flags.add('force');
|
|
89
|
+
else if (a === '--agent') agent = (args[++i] || '').toLowerCase();
|
|
90
|
+
else if (a.startsWith('--agent=')) agent = a.slice('--agent='.length).toLowerCase();
|
|
63
91
|
else if (a.startsWith('-')) throw new Error(`Unknown option: ${a}`);
|
|
64
92
|
else names.push(a);
|
|
65
93
|
}
|
|
66
|
-
return { flags, names, verb: argv[0] };
|
|
94
|
+
return { flags, names, agent, verb: argv[0] };
|
|
67
95
|
}
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
97
|
+
/** The note the installer injects into the installed primer/SKILL.md. */
|
|
98
|
+
function preconfiguredNote(agentKey) {
|
|
99
|
+
const { label, file } = AGENTS[agentKey];
|
|
100
|
+
return (
|
|
101
|
+
`> **Installer-preconfigured target: \`${file}\` (${label}).** The agent ` +
|
|
102
|
+
`was chosen at install time — do NOT ask "which tool?"; write ` +
|
|
103
|
+
`\`${file}\` directly. Only generate additional tools' files if the ` +
|
|
104
|
+
`user explicitly asks.`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Rewrite the placeholder in an installed primer so it skips its interview. */
|
|
109
|
+
async function preconfigurePrimer(primerDir, agentKey) {
|
|
110
|
+
const file = join(primerDir, 'SKILL.md');
|
|
111
|
+
if (!existsSync(file)) return;
|
|
112
|
+
const src = await readFile(file, 'utf8');
|
|
113
|
+
const marker = '<!-- FUNDAMENTUM_PRECONFIGURED_TARGET -->';
|
|
114
|
+
if (!src.includes(marker)) return;
|
|
115
|
+
await writeFile(file, src.replace(marker, preconfiguredNote(agentKey)), 'utf8');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Build the pointer block wired into a non-Claude agent's instructions file. */
|
|
119
|
+
function pointerBlock(skills, agentKey) {
|
|
120
|
+
const { file } = AGENTS[agentKey];
|
|
121
|
+
const lines = [
|
|
122
|
+
'<!-- fundamentum:start -->',
|
|
123
|
+
'## Fundamentum documentation workflows',
|
|
124
|
+
'',
|
|
125
|
+
`Installed at \`${NONCLAUDE_SKILLS_DIR}/\` (paths below are relative to the`,
|
|
126
|
+
'project root). When asked to scaffold or write project documentation,',
|
|
127
|
+
'follow the matching workflow file to completion:',
|
|
128
|
+
'',
|
|
129
|
+
];
|
|
130
|
+
const desc = {
|
|
131
|
+
blueprint: 'New project, documentation-first',
|
|
132
|
+
excavate: 'Existing codebase — document what is built + plan the gap',
|
|
133
|
+
primer: `Generate this project's agent-context file (writes \`${file}\`)`,
|
|
134
|
+
};
|
|
135
|
+
for (const s of skills) {
|
|
136
|
+
lines.push(`- ${desc[s] || s} → \`${NONCLAUDE_SKILLS_DIR}/${s}/SKILL.md\``);
|
|
137
|
+
}
|
|
138
|
+
lines.push('<!-- fundamentum:end -->');
|
|
139
|
+
return lines.join('\n');
|
|
140
|
+
}
|
|
71
141
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
142
|
+
/** Create/replace the fundamentum pointer block in an instructions file. */
|
|
143
|
+
async function wirePointer(projectRoot, agentKey, skills) {
|
|
144
|
+
const rel = AGENTS[agentKey].file;
|
|
145
|
+
const dest = join(projectRoot, rel);
|
|
146
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
147
|
+
const block = pointerBlock(skills, agentKey);
|
|
148
|
+
let body = existsSync(dest) ? await readFile(dest, 'utf8') : '';
|
|
149
|
+
const start = '<!-- fundamentum:start -->';
|
|
150
|
+
const end = '<!-- fundamentum:end -->';
|
|
151
|
+
const si = body.indexOf(start);
|
|
152
|
+
const ei = body.indexOf(end);
|
|
153
|
+
if (si !== -1 && ei !== -1) {
|
|
154
|
+
body = body.slice(0, si) + block + body.slice(ei + end.length); // replace in place
|
|
155
|
+
} else {
|
|
156
|
+
if (body && !body.endsWith('\n')) body += '\n';
|
|
157
|
+
body += (body ? '\n' : '') + block + '\n';
|
|
75
158
|
}
|
|
159
|
+
await writeFile(dest, body, 'utf8');
|
|
160
|
+
return dest;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function main() {
|
|
164
|
+
const { flags, names, agent: agentFlag, verb } = parseArgs(process.argv.slice(2));
|
|
165
|
+
|
|
166
|
+
if (flags.has('help')) return void process.stdout.write(HELP);
|
|
76
167
|
|
|
77
168
|
const available = await discoverSkills();
|
|
78
169
|
if (available.length === 0) throw new Error(`No skills found in ${ROOT}`);
|
|
79
170
|
|
|
80
171
|
if (verb === 'list') {
|
|
81
|
-
process.stdout.write(
|
|
82
|
-
|
|
172
|
+
return void process.stdout.write(
|
|
173
|
+
`Bundled skills:\n${available.map((s) => ` - ${s}`).join('\n')}\n`,
|
|
174
|
+
);
|
|
83
175
|
}
|
|
84
176
|
|
|
85
177
|
// Which skills?
|
|
@@ -87,49 +179,66 @@ async function main() {
|
|
|
87
179
|
if (names.length) {
|
|
88
180
|
const unknown = names.filter((n) => !available.includes(n));
|
|
89
181
|
if (unknown.length) {
|
|
90
|
-
throw new Error(
|
|
91
|
-
`Unknown skill(s): ${unknown.join(', ')}\nAvailable: ${available.join(', ')}`,
|
|
92
|
-
);
|
|
182
|
+
throw new Error(`Unknown skill(s): ${unknown.join(', ')}\nAvailable: ${available.join(', ')}`);
|
|
93
183
|
}
|
|
94
184
|
selected = names;
|
|
95
185
|
}
|
|
96
186
|
|
|
97
|
-
// Interactive prompts share one readline instance.
|
|
98
187
|
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
99
188
|
const rl = interactive ? createInterface({ input: process.stdin, output: process.stdout }) : null;
|
|
100
189
|
|
|
101
190
|
try {
|
|
102
|
-
//
|
|
191
|
+
// 1) Agent — asked FIRST.
|
|
192
|
+
let agent = agentFlag;
|
|
193
|
+
if (agent && !AGENTS[agent]) {
|
|
194
|
+
throw new Error(`Unknown agent: ${agent}\nChoose one of: ${AGENT_ORDER.join(', ')}`);
|
|
195
|
+
}
|
|
196
|
+
if (!agent) {
|
|
197
|
+
if (!rl) throw new Error('Non-interactive shell: pass --agent <name>.');
|
|
198
|
+
process.stdout.write(`\nFundamentum — installing: ${selected.join(', ')}\n\nWhich coding agent do you use?\n`);
|
|
199
|
+
AGENT_ORDER.forEach((k, i) => {
|
|
200
|
+
const tag = AGENTS[k].native ? 'native skills' : `wires into ${AGENTS[k].file}`;
|
|
201
|
+
process.stdout.write(` ${i + 1}) ${AGENTS[k].label.padEnd(15)} (${tag})\n`);
|
|
202
|
+
});
|
|
203
|
+
const ans = (await rl.question('Choose [1-6]: ')).trim().toLowerCase();
|
|
204
|
+
agent = AGENT_ORDER[Number(ans) - 1] || AGENT_ORDER.find((k) => k.startsWith(ans) || AGENTS[k].label.toLowerCase().startsWith(ans));
|
|
205
|
+
if (!agent) throw new Error('No agent chosen. Aborting.');
|
|
206
|
+
}
|
|
207
|
+
const meta = AGENTS[agent];
|
|
208
|
+
|
|
209
|
+
// 2) Location.
|
|
103
210
|
let scope;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
211
|
+
let targetBase;
|
|
212
|
+
if (meta.native) {
|
|
213
|
+
if (flags.has('global')) scope = 'global';
|
|
214
|
+
else if (flags.has('project')) scope = 'project';
|
|
215
|
+
else if (rl) {
|
|
216
|
+
process.stdout.write(
|
|
217
|
+
`\n${meta.label} skills — where to?\n` +
|
|
218
|
+
` 1) Global ${join(homedir(), '.claude', 'skills')} (every project)\n` +
|
|
219
|
+
` 2) Project ${join(process.cwd(), '.claude', 'skills')} (this repo only)\n`,
|
|
220
|
+
);
|
|
221
|
+
const ans = (await rl.question('Choose [1/2]: ')).trim().toLowerCase();
|
|
222
|
+
scope = ans === '2' || ans.startsWith('p') ? 'project' : ans === '1' || ans.startsWith('g') ? 'global' : null;
|
|
223
|
+
if (!scope) throw new Error('No location chosen. Aborting.');
|
|
224
|
+
} else {
|
|
225
|
+
throw new Error('Non-interactive shell: pass --global or --project.');
|
|
226
|
+
}
|
|
227
|
+
targetBase = scope === 'global' ? join(homedir(), '.claude', 'skills') : join(process.cwd(), '.claude', 'skills');
|
|
116
228
|
} else {
|
|
117
|
-
|
|
229
|
+
// Non-Claude agents wire into a project instructions file — always project.
|
|
230
|
+
scope = 'project';
|
|
231
|
+
targetBase = join(process.cwd(), ...NONCLAUDE_SKILLS_DIR.split('/'));
|
|
118
232
|
}
|
|
119
233
|
|
|
120
|
-
const targetBase =
|
|
121
|
-
scope === 'global'
|
|
122
|
-
? join(homedir(), '.claude', 'skills')
|
|
123
|
-
: join(process.cwd(), '.claude', 'skills');
|
|
124
|
-
|
|
125
234
|
await mkdir(targetBase, { recursive: true });
|
|
126
235
|
|
|
236
|
+
// 3) Copy skills.
|
|
127
237
|
const force = flags.has('force');
|
|
128
238
|
const installed = [];
|
|
129
239
|
for (const name of selected) {
|
|
130
240
|
const src = join(ROOT, name);
|
|
131
241
|
const dest = join(targetBase, name);
|
|
132
|
-
|
|
133
242
|
if (existsSync(dest) && !force) {
|
|
134
243
|
if (rl) {
|
|
135
244
|
const ans = (await rl.question(` ${dest} exists. Overwrite? [y/N]: `)).trim().toLowerCase();
|
|
@@ -142,19 +251,30 @@ async function main() {
|
|
|
142
251
|
continue;
|
|
143
252
|
}
|
|
144
253
|
}
|
|
145
|
-
|
|
146
254
|
await cp(src, dest, { recursive: true, force: true });
|
|
255
|
+
if (name === 'primer') await preconfigurePrimer(dest, agent);
|
|
147
256
|
installed.push(name);
|
|
148
257
|
process.stdout.write(` ✓ ${name} → ${dest}\n`);
|
|
149
258
|
}
|
|
150
259
|
|
|
151
|
-
if (installed.length)
|
|
260
|
+
if (!installed.length) return void process.stdout.write('\nNothing installed.\n');
|
|
261
|
+
|
|
262
|
+
// 4) Wire the pointer for non-Claude agents.
|
|
263
|
+
let wired = null;
|
|
264
|
+
if (!meta.native) wired = await wirePointer(process.cwd(), agent, installed);
|
|
265
|
+
|
|
266
|
+
// 5) Summary.
|
|
267
|
+
process.stdout.write(`\nDone. Installed ${installed.length} skill(s) for ${meta.label}.\n`);
|
|
268
|
+
if (meta.native) {
|
|
269
|
+
process.stdout.write(`Location: ${targetBase} (${scope}).\nRestart Claude Code (or start a new session) to pick them up.\n`);
|
|
270
|
+
} else {
|
|
152
271
|
process.stdout.write(
|
|
153
|
-
|
|
154
|
-
|
|
272
|
+
`Skills: ${targetBase}\nWired into: ${wired}\n` +
|
|
273
|
+
`${meta.label} reads that file, so it will follow the workflows from there.\n`,
|
|
155
274
|
);
|
|
156
|
-
}
|
|
157
|
-
|
|
275
|
+
}
|
|
276
|
+
if (installed.includes('primer')) {
|
|
277
|
+
process.stdout.write(`\nprimer is preconfigured to write ${meta.file} — it won't ask which agent.\n`);
|
|
158
278
|
}
|
|
159
279
|
} finally {
|
|
160
280
|
rl?.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johanesimm/fundamentum",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Documentation-first Claude Code skill suite (blueprint / excavate / primer) with a one-command installer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Johanes <johanesimm95@gmail.com>",
|
package/primer/SKILL.md
CHANGED
|
@@ -25,6 +25,15 @@ generated file, do not guess.
|
|
|
25
25
|
|
|
26
26
|
## Phase 0 — Pick the target file(s)
|
|
27
27
|
|
|
28
|
+
<!-- FUNDAMENTUM_PRECONFIGURED_TARGET -->
|
|
29
|
+
<!-- The installer rewrites the line above when you choose your agent at
|
|
30
|
+
install time. If it still shows as a bare comment, this copy was
|
|
31
|
+
installed manually — run the interview below as normal. -->
|
|
32
|
+
|
|
33
|
+
If the line above was replaced with a "preconfigured target" note, obey
|
|
34
|
+
it and **skip the question** — the agent was already chosen at install
|
|
35
|
+
time; just write that file. Otherwise:
|
|
36
|
+
|
|
28
37
|
Ask (AskUserQuestion) before anything else: **"Do you use an agentic
|
|
29
38
|
coding assistant, and which one(s)?"** Map the answer to filename(s):
|
|
30
39
|
|