thomas-agentkit 0.8.0 → 0.9.0-alpha.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 CHANGED
@@ -6,14 +6,81 @@ It installs reusable agent instructions, workflow guides, quality checklists, de
6
6
 
7
7
  AgentKit is not an AI agent. It is a small scaffolding tool for making repositories easier and safer to work on with AI-assisted development.
8
8
 
9
+ ## Bootstrap paths
10
+
11
+ AgentKit supports two first-time setup paths. Pick one — they are not interchangeable.
12
+
13
+ | | Template path | Skill path |
14
+ | --- | --- | --- |
15
+ | **CLI command** | `agentkit init` | `agentkit skill install` |
16
+ | **When to use** | Immediate offline setup; you want files now | Agent-guided setup; guidance created from your repo in a later session |
17
+ | **What you get** | Bundled `.md` templates copied into the project | Bundled `agentkit` Agent Skill installed; no guidance `.md` files yet |
18
+ | **Ongoing maintenance** | CLI `agentkit update` (managed-block merge) | Skill routes in your agent: `/agentkit update`, `/agentkit doctor`, `/agentkit repair`, `/agentkit learn` |
19
+ | **Config** | `installMode: template` | `installMode: skill` |
20
+
21
+ ```text
22
+ FIRST-TIME SETUP (terminal)
23
+ ├── agentkit init → copies templates, installMode: template
24
+ └── agentkit skill install → copies skill to .agents/skills/agentkit/, installMode: skill
25
+
26
+ ONGOING WORK (agent + skill path only)
27
+ ├── /agentkit init → agent creates AGENTS.md and companion files from repo context
28
+ ├── /agentkit update → agent syncs guidance after code changes
29
+ ├── /agentkit doctor → agent audits guidance quality
30
+ ├── /agentkit repair → agent repairs guidance structure when explicitly requested
31
+ └── /agentkit learn → agent teaches what changed after implementation
32
+ ```
33
+
34
+ Interactive `agentkit init` asks whether to copy templates or install the AgentKit skill, then runs the chosen path in the same session.
35
+
9
36
  ## Usage
10
37
 
38
+ ### Template path
39
+
11
40
  Install templates into the current directory:
12
41
 
13
42
  ```bash
14
43
  npx thomas-agentkit init
15
44
  ```
16
45
 
46
+ ### Skill path
47
+
48
+ Install the bundled AgentKit skill (v0.9.x+). This does **not** create `AGENTS.md` or other guidance files — run `/agentkit init` in your agent afterward:
49
+
50
+ ```bash
51
+ npx thomas-agentkit skill install
52
+ ```
53
+
54
+ Preview skill install without writing files:
55
+
56
+ ```bash
57
+ npx thomas-agentkit skill install --dry-run
58
+ ```
59
+
60
+ Overwrite an existing skill install:
61
+
62
+ ```bash
63
+ npx thomas-agentkit skill install --force
64
+ ```
65
+
66
+ After install, the CLI prints:
67
+
68
+ ```text
69
+ Installed AgentKit skill in .agents/skills/agentkit/
70
+ Wrote agentkit.config.json (installMode: skill)
71
+
72
+ Next step: In your agent, run agentkit init.
73
+ The skill will create AGENTS.md and companion files from your repository.
74
+ ```
75
+
76
+ After skill install, use the project-local skill from your agent:
77
+
78
+ - `/agentkit init` creates missing guidance files from repository context.
79
+ - `/agentkit update` syncs managed guidance with current repository context.
80
+ - `/agentkit doctor` audits guidance quality without editing by default.
81
+ - `/agentkit repair` repairs guidance structure, such as malformed managed blocks or thick AI adapters, after an explicit request.
82
+ - `/agentkit learn` teaches recent codebase changes, design decisions, edge cases, validation, and impact without writing files by default.
83
+
17
84
  If the package is installed in a project, use the local `agentkit` binary:
18
85
 
19
86
  ```bash
@@ -77,6 +144,8 @@ Standardize install defaults with `agentkit.config.json`:
77
144
 
78
145
  ```json
79
146
  {
147
+ "installMode": "template",
148
+ "agentkitVersion": "0.9.0",
80
149
  "preset": "next",
81
150
  "templateSet": "standard",
82
151
  "designSystem": "linear",
@@ -105,7 +174,9 @@ npx thomas-agentkit init --write-config
105
174
 
106
175
  `--write-config` writes `agentkit.config.json` in the target directory. Existing config files are skipped by default; use `--force` to overwrite one intentionally.
107
176
 
108
- Config values are validated when loaded. Unknown config keys, invalid preset/template/design-system names, invalid AI tool names, and non-string personalization values exit with an error.
177
+ `installMode` is `"template"` or `"skill"` and records how the project was bootstrapped. `agentkitVersion` records the package version at install time. Configs without `installMode` are treated as template-path installs.
178
+
179
+ Config values are validated when loaded. Unknown config keys, invalid preset/template/design-system names, invalid AI tool names, invalid `installMode` values, and non-string personalization values exit with an error.
109
180
 
110
181
  List bundled templates:
111
182
 
@@ -188,10 +259,30 @@ Presets add stack-specific guidance without scaffolding framework app files.
188
259
  - `convex`
189
260
  - `fullstack` (`Next.js` + `Convex`)
190
261
 
262
+ ## CLI vs agent commands
263
+
264
+ The same names mean different things in the terminal vs in an agent session:
265
+
266
+ | Name | Where | What |
267
+ | --- | --- | --- |
268
+ | `agentkit init` | Terminal | Install **templates** |
269
+ | `agentkit skill install` | Terminal | Install **bundled skill** + config |
270
+ | `agentkit init` | Agent | Create **guidance files** (skill path) |
271
+ | `agentkit update` | Terminal | Template-path managed-block merge only |
272
+ | `agentkit update` | Agent | Sync guidance to repo changes |
273
+ | `agentkit doctor` | Agent | Audit guidance quality |
274
+ | `agentkit repair` | Agent | Repair guidance structure after explicit request |
275
+ | `agentkit learn` | Agent | Teach recent codebase changes and check understanding |
276
+
277
+ Never use CLI `agentkit init` for skill installation.
278
+
279
+ On skill-path repos (`installMode: skill`), CLI `agentkit update` prints an informational message and does not modify guidance files. Use `/agentkit update` in your agent for skill-path guidance sync.
280
+
191
281
  ## CLI Reference
192
282
 
193
283
  ```text
194
284
  agentkit init [target] [--force] [--dry-run] [--interactive] [--yes] [--write-config] [--preset <name>] [--design-system <name>]
285
+ agentkit skill install [target] [--force] [--dry-run] [--yes] [--preset <name>] [--design-system <name>]
195
286
  agentkit update [target] [--dry-run] [--preset <name>] [--design-system <name>]
196
287
  agentkit --list
197
288
  agentkit --list-presets
@@ -206,7 +297,7 @@ Options:
206
297
  - `--dry-run`: print planned changes without writing files
207
298
  - `-i, --interactive`: explicitly prompt for install options
208
299
  - `-y, --yes`: accept defaults without prompts
209
- - `--write-config`: write resolved install defaults to `agentkit.config.json`
300
+ - `--write-config`: write resolved template install defaults to `agentkit.config.json`
210
301
  - `--preset <name>`: install stack-specific guidance (`next`, `sveltekit`, `express`, `convex`, `fullstack`)
211
302
  - `--design-system <name>`: design system variant for `DESIGN-SYSTEM.md` (`linear`, `apple`)
212
303
  - `--list`: list bundled template files
package/dist/cli.js CHANGED
@@ -5,6 +5,7 @@ import { constants as fsConstants, realpathSync } from "node:fs";
5
5
  import { access, mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
+ import { getSkillDestinationPaths, getSkillSourceDir, installSkill, listSkillFiles, printSkillInstallResult, } from "./skill-install.js";
8
9
  const __filename = fileURLToPath(import.meta.url);
9
10
  const __dirname = path.dirname(__filename);
10
11
  const packageRoot = path.resolve(__dirname, "..");
@@ -20,7 +21,16 @@ const designSystemLabels = {
20
21
  apple: "Apple-inspired",
21
22
  };
22
23
  const configFileName = "agentkit.config.json";
23
- const configKeys = ["preset", "templateSet", "aiTools", "designSystem", "personalization"];
24
+ const configKeys = [
25
+ "installMode",
26
+ "agentkitVersion",
27
+ "preset",
28
+ "templateSet",
29
+ "aiTools",
30
+ "designSystem",
31
+ "personalization",
32
+ ];
33
+ const validInstallModes = ["template", "skill"];
24
34
  const personalizationKeys = [
25
35
  "projectName",
26
36
  "projectDescription",
@@ -128,7 +138,7 @@ async function collectInstallableTemplatePaths(dir, base) {
128
138
  for (const entry of entries) {
129
139
  const absolutePath = path.join(dir, entry.name);
130
140
  if (entry.isDirectory()) {
131
- if (dir === templatesDir && entry.name === "design-systems") {
141
+ if (dir === templatesDir && (entry.name === "design-systems" || entry.name === "skills")) {
132
142
  continue;
133
143
  }
134
144
  discovered.push(...(await collectInstallableTemplatePaths(absolutePath, base)));
@@ -257,13 +267,31 @@ function readConfigPersonalization(value) {
257
267
  }
258
268
  return personalization;
259
269
  }
270
+ function resolveInstallMode(installMode) {
271
+ const normalizedInstallMode = installMode.toLowerCase();
272
+ if (!validInstallModes.includes(normalizedInstallMode)) {
273
+ throw new Error(`Unknown install mode "${installMode}". Valid install modes: ${validInstallModes.join(", ")}.`);
274
+ }
275
+ return normalizedInstallMode;
276
+ }
277
+ export function getInstallMode(config) {
278
+ return config?.installMode ?? "template";
279
+ }
260
280
  function parseConfig(rawConfig, configPath) {
261
281
  assertPlainObject(rawConfig, configFileName);
262
282
  assertKnownKeys(rawConfig, configKeys, configFileName);
263
283
  const preset = optionalConfigString(rawConfig, "preset");
264
284
  const templateSet = optionalConfigString(rawConfig, "templateSet");
265
285
  const designSystem = optionalConfigString(rawConfig, "designSystem");
286
+ const installMode = optionalConfigString(rawConfig, "installMode");
287
+ const agentkitVersion = optionalConfigString(rawConfig, "agentkitVersion");
266
288
  const config = {};
289
+ if (installMode !== undefined) {
290
+ config.installMode = resolveInstallMode(installMode);
291
+ }
292
+ if (agentkitVersion !== undefined) {
293
+ config.agentkitVersion = agentkitVersion;
294
+ }
267
295
  if (preset !== undefined) {
268
296
  config.preset = resolvePreset(preset);
269
297
  }
@@ -394,8 +422,10 @@ function cleanPersonalizationValue(value) {
394
422
  const trimmed = value?.trim();
395
423
  return trimmed ? trimmed : undefined;
396
424
  }
397
- function getResolvedConfig(options) {
425
+ function getResolvedConfig(options, installMode, agentkitVersion) {
398
426
  const config = {
427
+ installMode,
428
+ agentkitVersion,
399
429
  templateSet: options.templateSet ?? "standard",
400
430
  aiTools: options.aiTools ?? [],
401
431
  designSystem: effectiveDesignSystem(options.designSystem),
@@ -573,7 +603,7 @@ async function resolveInitTemplateFiles(options) {
573
603
  }
574
604
  return getSelectedTemplateFiles(options.templateSet ?? "standard", options.aiTools ?? [], allTemplateFiles);
575
605
  }
576
- async function installTemplates(targetArg, options) {
606
+ async function installTemplates(targetArg, options, agentkitVersion) {
577
607
  const targetDir = path.resolve(process.cwd(), targetArg || ".");
578
608
  const files = await resolveInitTemplateFiles(options);
579
609
  const preset = resolvePreset(options.preset);
@@ -583,7 +613,7 @@ async function installTemplates(targetArg, options) {
583
613
  await mkdir(targetDir, { recursive: true });
584
614
  }
585
615
  if (options.writeConfig) {
586
- await installFileIfAllowed(targetDir, configFileName, options, result, () => serializeConfig(getResolvedConfig(options)));
616
+ await installFileIfAllowed(targetDir, configFileName, options, result, () => serializeConfig(getResolvedConfig(options, "template", agentkitVersion)));
587
617
  }
588
618
  for (const file of files) {
589
619
  await installFileIfAllowed(targetDir, file, options, result, async () => {
@@ -790,7 +820,23 @@ async function promptForConflictStrategy(existingFiles) {
790
820
  ],
791
821
  }));
792
822
  }
793
- async function applyInteractiveSelections(resolvedTarget, providedPreset, options) {
823
+ async function promptForBootstrapPath() {
824
+ return resolvePrompt(await select({
825
+ message: "How do you want to set up AgentKit?",
826
+ initialValue: "template",
827
+ options: [
828
+ {
829
+ label: "Copy templates now (install AGENTS.md and companion files)",
830
+ value: "template",
831
+ },
832
+ {
833
+ label: "Install AgentKit skill (create guidance files later in your agent)",
834
+ value: "skill",
835
+ },
836
+ ],
837
+ }));
838
+ }
839
+ async function collectInstallOptions(resolvedTarget, providedPreset, options) {
794
840
  if (!providedPreset) {
795
841
  options.preset = await promptForProjectPreset();
796
842
  }
@@ -803,25 +849,50 @@ async function applyInteractiveSelections(resolvedTarget, providedPreset, option
803
849
  if (templateSet === "standard" || templateSet === "full") {
804
850
  options.designSystem = await promptForDesignSystem(options.designSystem);
805
851
  }
806
- if (!options.force) {
852
+ }
853
+ async function resolveConflictForInstall(resolvedTarget, options, bootstrapPath) {
854
+ if (options.force) {
855
+ return;
856
+ }
857
+ let installFiles;
858
+ if (bootstrapPath === "skill") {
859
+ const skillFiles = await listSkillFiles(getSkillSourceDir(packageRoot));
860
+ installFiles = [...getSkillDestinationPaths(skillFiles), configFileName];
861
+ }
862
+ else {
807
863
  const preset = resolvePreset(options.preset);
808
- const installFiles = preset ? [...options.files, "STACK.md"] : options.files;
809
- const existingFiles = await findExistingInstallFiles(resolvedTarget, installFiles);
810
- if (existingFiles.length > 0) {
811
- options.force = (await promptForConflictStrategy(existingFiles)) === "overwrite";
812
- }
864
+ installFiles = preset ? [...(options.files ?? []), "STACK.md"] : (options.files ?? []);
865
+ }
866
+ const existingFiles = await findExistingInstallFiles(resolvedTarget, installFiles);
867
+ if (existingFiles.length > 0) {
868
+ options.force = (await promptForConflictStrategy(existingFiles)) === "overwrite";
813
869
  }
814
870
  }
815
- async function resolveInteractiveTarget(target, options) {
871
+ async function runInteractiveInstall(target, options, agentkitVersion) {
872
+ intro("Welcome to AgentKit");
873
+ const bootstrapPath = await promptForBootstrapPath();
816
874
  const providedPreset = resolvePreset(options.preset);
817
- if (!shouldPromptForInit(options, process)) {
818
- return target;
875
+ const resolvedTarget = await promptForTarget(target);
876
+ await collectInstallOptions(resolvedTarget, providedPreset, options);
877
+ options.personalization = await promptForPersonalization(options.personalization);
878
+ await resolveConflictForInstall(resolvedTarget, options, bootstrapPath);
879
+ if (bootstrapPath === "skill") {
880
+ const result = await installSkill(resolvedTarget, options, packageRoot, agentkitVersion);
881
+ printSkillInstallResult(result, Boolean(options.dryRun));
882
+ return;
819
883
  }
884
+ const result = await installTemplates(resolvedTarget, options, agentkitVersion);
885
+ printInstallResult(result, Boolean(options.dryRun));
886
+ }
887
+ async function runSkillInstallInteractive(target, options, agentkitVersion) {
820
888
  intro("Welcome to AgentKit");
889
+ const providedPreset = resolvePreset(options.preset);
821
890
  const resolvedTarget = await promptForTarget(target);
822
- await applyInteractiveSelections(resolvedTarget, providedPreset, options);
891
+ await collectInstallOptions(resolvedTarget, providedPreset, options);
823
892
  options.personalization = await promptForPersonalization(options.personalization);
824
- return resolvedTarget;
893
+ await resolveConflictForInstall(resolvedTarget, options, "skill");
894
+ const result = await installSkill(resolvedTarget, options, packageRoot, agentkitVersion);
895
+ printSkillInstallResult(result, Boolean(options.dryRun));
825
896
  }
826
897
  async function main() {
827
898
  if (process.argv.slice(2).includes("--list")) {
@@ -855,6 +926,7 @@ async function main() {
855
926
 
856
927
  Examples:
857
928
  agentkit init
929
+ agentkit skill install
858
930
  agentkit update
859
931
  agentkit init --preset next
860
932
  agentkit init ./my-project --yes --dry-run
@@ -874,10 +946,35 @@ Examples:
874
946
  .option("--design-system <name>", `design system guidance for DESIGN-SYSTEM.md (${formatDesignSystemList()})`)
875
947
  .action(async (target, options) => {
876
948
  await applyInitConfig(options, await loadConfigForTarget(target));
877
- const resolvedTarget = await resolveInteractiveTarget(target, options);
878
- const result = await installTemplates(resolvedTarget, options);
949
+ const agentkitVersion = await readPackageVersion();
950
+ if (shouldPromptForInit(options, process)) {
951
+ await runInteractiveInstall(target, options, agentkitVersion);
952
+ return;
953
+ }
954
+ const result = await installTemplates(target, options, agentkitVersion);
879
955
  printInstallResult(result, Boolean(options.dryRun));
880
956
  });
957
+ const skill = program.command("skill").description("install the bundled AgentKit Agent Skill");
958
+ skill
959
+ .command("install")
960
+ .description("install the bundled agentkit skill and write agentkit.config.json")
961
+ .argument("[target]", "target project directory", ".")
962
+ .option("--force", "overwrite existing skill files and config")
963
+ .option("--dry-run", "print planned changes without writing files")
964
+ .option("-i, --interactive", "prompt for install options")
965
+ .option("-y, --yes", "accept defaults for non-interactive runs")
966
+ .option("--preset <name>", `store stack preset in config (${formatPresetList()})`)
967
+ .option("--design-system <name>", `store design system choice in config (${formatDesignSystemList()})`)
968
+ .action(async (target, options) => {
969
+ await applyInitConfig(options, await loadConfigForTarget(target));
970
+ const agentkitVersion = await readPackageVersion();
971
+ if (shouldPromptForInit(options, process)) {
972
+ await runSkillInstallInteractive(target, options, agentkitVersion);
973
+ return;
974
+ }
975
+ const result = await installSkill(target, options, packageRoot, agentkitVersion);
976
+ printSkillInstallResult(result, Boolean(options.dryRun));
977
+ });
881
978
  program
882
979
  .command("update")
883
980
  .description("update AgentKit managed template blocks in a project")
@@ -886,7 +983,14 @@ Examples:
886
983
  .option("--preset <name>", `update stack-specific guidance (${formatPresetList()})`)
887
984
  .option("--design-system <name>", `design system guidance for DESIGN-SYSTEM.md (${formatDesignSystemList()})`)
888
985
  .action(async (target, options) => {
889
- applyUpdateConfig(options, await loadConfigForTarget(target));
986
+ const config = await loadConfigForTarget(target);
987
+ if (getInstallMode(config) === "skill") {
988
+ console.log("This project uses installMode: skill.");
989
+ console.log("Run agentkit update in your agent to sync guidance files.");
990
+ console.log("(CLI agentkit update applies to template-path installs.)");
991
+ return;
992
+ }
993
+ applyUpdateConfig(options, config);
890
994
  const result = await updateTemplates(target, options);
891
995
  printUpdateResult(result, Boolean(options.dryRun));
892
996
  });
@@ -0,0 +1,125 @@
1
+ import { constants as fsConstants } from "node:fs";
2
+ import { access, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export const SKILL_DEST_DIR = ".agents/skills/agentkit";
5
+ export const CONFIG_FILE_NAME = "agentkit.config.json";
6
+ export function getSkillSourceDir(packageRoot) {
7
+ return path.join(packageRoot, "templates", "skills", "agentkit");
8
+ }
9
+ export async function listSkillFiles(sourceDir) {
10
+ const files = [];
11
+ async function walk(dir, prefix) {
12
+ const entries = await readdir(dir, { withFileTypes: true });
13
+ for (const entry of entries) {
14
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
15
+ const fullPath = path.join(dir, entry.name);
16
+ if (entry.isDirectory()) {
17
+ await walk(fullPath, relative);
18
+ }
19
+ else if (entry.isFile()) {
20
+ files.push(relative);
21
+ }
22
+ }
23
+ }
24
+ await walk(sourceDir, "");
25
+ return files.sort();
26
+ }
27
+ export function buildSkillConfig(options, agentkitVersion) {
28
+ const config = {
29
+ installMode: "skill",
30
+ agentkitVersion,
31
+ templateSet: options.templateSet ?? "standard",
32
+ aiTools: options.aiTools ?? [],
33
+ designSystem: options.designSystem ?? "linear",
34
+ };
35
+ if (options.preset) {
36
+ config.preset = options.preset;
37
+ }
38
+ if (options.personalization) {
39
+ const personalization = {};
40
+ for (const [key, value] of Object.entries(options.personalization)) {
41
+ const trimmed = value?.trim();
42
+ if (trimmed) {
43
+ personalization[key] = trimmed;
44
+ }
45
+ }
46
+ if (Object.keys(personalization).length > 0) {
47
+ config.personalization = personalization;
48
+ }
49
+ }
50
+ return config;
51
+ }
52
+ export function getSkillDestinationPaths(skillFiles) {
53
+ return skillFiles.map((file) => path.posix.join(SKILL_DEST_DIR, file.replace(/\\/g, "/")));
54
+ }
55
+ async function pathExists(filePath) {
56
+ try {
57
+ await access(filePath, fsConstants.F_OK);
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ export async function installSkill(targetArg, options, packageRoot, agentkitVersion) {
65
+ const targetDir = path.resolve(process.cwd(), targetArg || ".");
66
+ const sourceDir = getSkillSourceDir(packageRoot);
67
+ const skillFiles = await listSkillFiles(sourceDir);
68
+ const result = { targetDir, created: [], skipped: [] };
69
+ if (!options.dryRun) {
70
+ await mkdir(targetDir, { recursive: true });
71
+ }
72
+ for (const file of skillFiles) {
73
+ const destination = path.join(targetDir, SKILL_DEST_DIR, file);
74
+ const destinationRelative = path.posix.join(SKILL_DEST_DIR, file.replace(/\\/g, "/"));
75
+ if ((await pathExists(destination)) && !options.force) {
76
+ result.skipped.push(destinationRelative);
77
+ continue;
78
+ }
79
+ result.created.push(destinationRelative);
80
+ if (!options.dryRun) {
81
+ await mkdir(path.dirname(destination), { recursive: true });
82
+ const content = await readFile(path.join(sourceDir, file), "utf8");
83
+ await writeFile(destination, content);
84
+ }
85
+ }
86
+ const configPath = path.join(targetDir, CONFIG_FILE_NAME);
87
+ const configRelative = CONFIG_FILE_NAME;
88
+ if ((await pathExists(configPath)) && !options.force) {
89
+ if (!result.skipped.includes(configRelative)) {
90
+ result.skipped.push(configRelative);
91
+ }
92
+ }
93
+ else {
94
+ if (!result.created.includes(configRelative)) {
95
+ result.created.push(configRelative);
96
+ }
97
+ if (!options.dryRun) {
98
+ const configContent = `${JSON.stringify(buildSkillConfig(options, agentkitVersion), null, 2)}\n`;
99
+ await writeFile(configPath, configContent);
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ export function printSkillInstallResult(result, dryRun = false) {
105
+ if (dryRun) {
106
+ console.log(`Would install AgentKit skill in ${SKILL_DEST_DIR}/`);
107
+ if (result.created.length > 0) {
108
+ console.log(`Would create: ${result.created.join(", ")}`);
109
+ }
110
+ if (result.skipped.length > 0) {
111
+ console.log(`Would skip existing: ${result.skipped.join(", ")}`);
112
+ console.log("Use --force to overwrite existing files.");
113
+ }
114
+ return;
115
+ }
116
+ console.log(`Installed AgentKit skill in ${SKILL_DEST_DIR}/`);
117
+ console.log(`Wrote ${CONFIG_FILE_NAME} (installMode: skill)`);
118
+ console.log("");
119
+ console.log("Next step: In your agent, run agentkit init.");
120
+ console.log("The skill will create AGENTS.md and companion files from your repository.");
121
+ if (result.skipped.length > 0) {
122
+ console.log(`Skipped existing: ${result.skipped.join(", ")}`);
123
+ console.log("Use --force to overwrite existing files.");
124
+ }
125
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thomas-agentkit",
3
- "version": "0.8.0",
3
+ "version": "0.9.0-alpha.0",
4
4
  "description": "Install AI-agent-ready development templates into a project.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,6 +33,7 @@
33
33
  "build": "tsc",
34
34
  "dev": "tsx src/cli.ts",
35
35
  "test": "vitest run",
36
+ "validate:skill": "skills-ref validate ./templates/skills/agentkit",
36
37
  "prepack": "npm run build"
37
38
  },
38
39
  "dependencies": {
@@ -40,6 +41,7 @@
40
41
  "commander": "^12.1.0"
41
42
  },
42
43
  "devDependencies": {
44
+ "skills-ref": "^0.1.5",
43
45
  "@types/node": "^22.10.2",
44
46
  "tsx": "^4.19.2",
45
47
  "typescript": "^5.7.2",
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: agentkit
3
+ description: Use when creating, syncing, auditing, repairing, or learning AgentKit-managed repository guidance and codebase changes in an agent session, especially after `agentkit skill install`, when `/agentkit init`, `/agentkit update`, `/agentkit doctor`, `/agentkit repair`, or `/agentkit learn` is requested, or when AGENTS.md, STACK.md, companion guides, managed blocks, commands, placeholders, AI tool adapters, recent diffs, or completed changes need context-aware maintenance or explanation.
4
+ compatibility: Requires agentkit CLI and agentkit.config.json with installMode skill, or existing AgentKit-managed files with block markers.
5
+ metadata:
6
+ author: thomas-agentkit
7
+ version: "1.0"
8
+ ---
9
+
10
+ # AgentKit Skill
11
+
12
+ Create, sync, audit, repair, and teach AgentKit-managed repository guidance and codebase changes using live repository context.
13
+
14
+ ## When to use
15
+
16
+ - User ran `agentkit skill install`
17
+ - User asks `/agentkit init`, `/agentkit update`, `/agentkit doctor`, `/agentkit repair`, or `/agentkit learn`
18
+ - `AGENTS.md`, `STACK.md`, companion guides, or AI adapters are missing
19
+ - Guidance has stale commands, stack details, project paths, placeholders, or broken references
20
+ - Managed blocks need context-aware update, audit, or repair
21
+ - User wants to understand recent codebase changes, a completed implementation, a diff, a bug fix, or the session
22
+
23
+ ## When not to use
24
+
25
+ - User wants terminal template install -> direct them to CLI `agentkit init`
26
+ - User wants terminal template update -> direct them to CLI `agentkit update` unless config says `installMode: skill`
27
+ - Generic documentation requests unrelated to AgentKit guidance
28
+ - Code review findings, debugging, or feature implementation requests
29
+ - Short summaries that do not require a guided teaching workflow
30
+
31
+ ## Route
32
+
33
+ Always read `references/file-contract.md` before editing or auditing AgentKit-managed files. Do not act from `SKILL.md` alone.
34
+
35
+ 1. User asks to **initialize** missing guidance files from repo context
36
+ → `references/init.md`
37
+
38
+ 2. User asks to **update** or **sync** existing guidance with current repo context
39
+ → `references/update.md`
40
+
41
+ 3. User asks to **doctor**, **audit**, **review**, **diagnose**, or **health check** guidance quality
42
+ → `references/doctor.md`
43
+
44
+ 4. User asks to **repair**, **fix malformed blocks**, **convert unmanaged guidance**, or **fix adapters**
45
+ → `references/repair.md`
46
+
47
+ 5. User asks to **learn**, **understand recent changes**, **explain the session**, **teach me what changed**, **ELI5**, **ELI14**, **explain like an intern**, or **check my understanding**
48
+ → `references/learn.md`
49
+
50
+ 6. Unsure which workflow applies
51
+ → If no guidance files exist: `references/init.md`
52
+ → If guidance exists but commands, stack, files, placeholders, adapters, or references are stale: `references/update.md`
53
+ → If user wants audit, doctor, health check, diagnosis, or review: `references/doctor.md`
54
+ → If managed blocks are malformed or unmanaged files need conversion: `references/repair.md`
55
+ → If user wants to understand completed changes or a session: `references/learn.md`
56
+
57
+ ## Non-negotiables
58
+
59
+ - `AGENTS.md` is the source of truth; AI tool adapters stay thin pointers
60
+ - Read the route reference and `references/file-contract.md` before file edits
61
+ - Preserve user content **outside** AgentKit managed blocks
62
+ - Skip unmanaged existing files unless conversion is explicitly requested
63
+ - Defer malformed managed blocks to `references/repair.md`
64
+ - Commands in guidance must come from `package.json` scripts or `agentkit.config.json` personalization — never invent scripts
65
+ - Prefer repo facts over config personalization
66
+ - Do not modify app source, lockfiles, package manifests, or CI config during AgentKit workflows
67
+ - `/agentkit learn` is read-only by default and keeps learning checklists in the conversation unless the user explicitly asks for notes
68
+ - CLI `agentkit init` installs **templates**; this skill's `agentkit init` **creates guidance files** — never confuse them
69
+
70
+ ## Gotchas
71
+
72
+ | Gotcha | Reality |
73
+ | --- | --- |
74
+ | `installMode: skill` but no `.md` files yet | Expected after `agentkit skill install`; run `/agentkit init` |
75
+ | `templateSet: minimal` | `AGENTS.md` only, plus selected adapters if explicitly configured |
76
+ | `templateSet: standard` | Core companions only; not testing/security/workflow docs |
77
+ | `templateSet: full` | Full guidance docs; adapters still follow `aiTools` |
78
+ | AI tool adapters | Thin pointers to `AGENTS.md`; never duplicate full guidance |
79
+ | `STACK.md` | Create/update when preset is configured, user asks, or stack is confidently inferred |
80
+ | Existing unmanaged files | Skip unless user asks to convert |
81
+ | Malformed managed blocks | Use `/agentkit repair` before update/refresh |
82
+ | Learning workflow | `/agentkit learn` teaches from diffs and code; it does not create notes or files by default |
83
+ | Docs-only guidance workflow | Does not require running project tests/builds |
84
+
85
+ ## Quick reference
86
+
87
+ | User says | Load |
88
+ | --- | --- |
89
+ | "/agentkit init" / "set up AGENTS.md" | `references/init.md` |
90
+ | "/agentkit update" / "sync guidance" | `references/update.md` |
91
+ | "/agentkit doctor" / "audit AgentKit guidance" | `references/doctor.md` |
92
+ | "/agentkit repair" / "fix managed blocks" | `references/repair.md` |
93
+ | "/agentkit learn" / "teach me what changed" | `references/learn.md` |
94
+ | Before any file edit | `references/file-contract.md` |
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "AgentKit"
3
+ short_description: "Create, maintain, and learn repo guidance"
4
+ default_prompt: "Use $agentkit to initialize, sync, audit, repair, or learn repository guidance and changes."