thomas-agentkit 0.7.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
 
@@ -166,7 +237,7 @@ Interactive personalization only applies during `agentkit init` when files are c
166
237
  Template set mappings:
167
238
 
168
239
  - `minimal`: `AGENTS.md`
169
- - `standard`: `AGENTS.md`, `CHANGE-EXPLANATION.md`, `CODE-QUALITY.md`, `DESIGN-SYSTEM.md`, `WORKFLOWS.md`, `.github/pull_request_template.md`
240
+ - `standard`: `AGENTS.md`, `CHANGE-EXPLANATION.md`, `CODE-QUALITY.md`, `DESIGN-SYSTEM.md`, `.github/pull_request_template.md`
170
241
  - `full`: all bundled templates, including AI tool adapters and planning/testing/security guides
171
242
 
172
243
  AI tool mappings:
@@ -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
@@ -268,3 +359,5 @@ AgentKit should stay:
268
359
  - safe by default
269
360
  - useful immediately
270
361
  - not overengineered
362
+
363
+ Installed guidance is **AGENTS-first**: `AGENTS.md` is enough for daily coding, including required change explanations after file edits. Companion files are loaded on explicit triggers (UI, review, security, stack, planning when requested), not on every task. The `full` template set adds optional guides such as `WORKFLOWS.md`, `TESTING.md`, and planning templates.
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",
@@ -52,7 +62,6 @@ const templateSetFiles = {
52
62
  "CHANGE-EXPLANATION.md",
53
63
  "CODE-QUALITY.md",
54
64
  "DESIGN-SYSTEM.md",
55
- "WORKFLOWS.md",
56
65
  ".github/pull_request_template.md",
57
66
  ],
58
67
  full: [],
@@ -129,7 +138,7 @@ async function collectInstallableTemplatePaths(dir, base) {
129
138
  for (const entry of entries) {
130
139
  const absolutePath = path.join(dir, entry.name);
131
140
  if (entry.isDirectory()) {
132
- if (dir === templatesDir && entry.name === "design-systems") {
141
+ if (dir === templatesDir && (entry.name === "design-systems" || entry.name === "skills")) {
133
142
  continue;
134
143
  }
135
144
  discovered.push(...(await collectInstallableTemplatePaths(absolutePath, base)));
@@ -258,13 +267,31 @@ function readConfigPersonalization(value) {
258
267
  }
259
268
  return personalization;
260
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
+ }
261
280
  function parseConfig(rawConfig, configPath) {
262
281
  assertPlainObject(rawConfig, configFileName);
263
282
  assertKnownKeys(rawConfig, configKeys, configFileName);
264
283
  const preset = optionalConfigString(rawConfig, "preset");
265
284
  const templateSet = optionalConfigString(rawConfig, "templateSet");
266
285
  const designSystem = optionalConfigString(rawConfig, "designSystem");
286
+ const installMode = optionalConfigString(rawConfig, "installMode");
287
+ const agentkitVersion = optionalConfigString(rawConfig, "agentkitVersion");
267
288
  const config = {};
289
+ if (installMode !== undefined) {
290
+ config.installMode = resolveInstallMode(installMode);
291
+ }
292
+ if (agentkitVersion !== undefined) {
293
+ config.agentkitVersion = agentkitVersion;
294
+ }
268
295
  if (preset !== undefined) {
269
296
  config.preset = resolvePreset(preset);
270
297
  }
@@ -395,8 +422,10 @@ function cleanPersonalizationValue(value) {
395
422
  const trimmed = value?.trim();
396
423
  return trimmed ? trimmed : undefined;
397
424
  }
398
- function getResolvedConfig(options) {
425
+ function getResolvedConfig(options, installMode, agentkitVersion) {
399
426
  const config = {
427
+ installMode,
428
+ agentkitVersion,
400
429
  templateSet: options.templateSet ?? "standard",
401
430
  aiTools: options.aiTools ?? [],
402
431
  designSystem: effectiveDesignSystem(options.designSystem),
@@ -574,7 +603,7 @@ async function resolveInitTemplateFiles(options) {
574
603
  }
575
604
  return getSelectedTemplateFiles(options.templateSet ?? "standard", options.aiTools ?? [], allTemplateFiles);
576
605
  }
577
- async function installTemplates(targetArg, options) {
606
+ async function installTemplates(targetArg, options, agentkitVersion) {
578
607
  const targetDir = path.resolve(process.cwd(), targetArg || ".");
579
608
  const files = await resolveInitTemplateFiles(options);
580
609
  const preset = resolvePreset(options.preset);
@@ -584,7 +613,7 @@ async function installTemplates(targetArg, options) {
584
613
  await mkdir(targetDir, { recursive: true });
585
614
  }
586
615
  if (options.writeConfig) {
587
- await installFileIfAllowed(targetDir, configFileName, options, result, () => serializeConfig(getResolvedConfig(options)));
616
+ await installFileIfAllowed(targetDir, configFileName, options, result, () => serializeConfig(getResolvedConfig(options, "template", agentkitVersion)));
588
617
  }
589
618
  for (const file of files) {
590
619
  await installFileIfAllowed(targetDir, file, options, result, async () => {
@@ -791,7 +820,23 @@ async function promptForConflictStrategy(existingFiles) {
791
820
  ],
792
821
  }));
793
822
  }
794
- 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) {
795
840
  if (!providedPreset) {
796
841
  options.preset = await promptForProjectPreset();
797
842
  }
@@ -804,25 +849,50 @@ async function applyInteractiveSelections(resolvedTarget, providedPreset, option
804
849
  if (templateSet === "standard" || templateSet === "full") {
805
850
  options.designSystem = await promptForDesignSystem(options.designSystem);
806
851
  }
807
- 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 {
808
863
  const preset = resolvePreset(options.preset);
809
- const installFiles = preset ? [...options.files, "STACK.md"] : options.files;
810
- const existingFiles = await findExistingInstallFiles(resolvedTarget, installFiles);
811
- if (existingFiles.length > 0) {
812
- options.force = (await promptForConflictStrategy(existingFiles)) === "overwrite";
813
- }
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";
814
869
  }
815
870
  }
816
- async function resolveInteractiveTarget(target, options) {
871
+ async function runInteractiveInstall(target, options, agentkitVersion) {
872
+ intro("Welcome to AgentKit");
873
+ const bootstrapPath = await promptForBootstrapPath();
817
874
  const providedPreset = resolvePreset(options.preset);
818
- if (!shouldPromptForInit(options, process)) {
819
- 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;
820
883
  }
884
+ const result = await installTemplates(resolvedTarget, options, agentkitVersion);
885
+ printInstallResult(result, Boolean(options.dryRun));
886
+ }
887
+ async function runSkillInstallInteractive(target, options, agentkitVersion) {
821
888
  intro("Welcome to AgentKit");
889
+ const providedPreset = resolvePreset(options.preset);
822
890
  const resolvedTarget = await promptForTarget(target);
823
- await applyInteractiveSelections(resolvedTarget, providedPreset, options);
891
+ await collectInstallOptions(resolvedTarget, providedPreset, options);
824
892
  options.personalization = await promptForPersonalization(options.personalization);
825
- return resolvedTarget;
893
+ await resolveConflictForInstall(resolvedTarget, options, "skill");
894
+ const result = await installSkill(resolvedTarget, options, packageRoot, agentkitVersion);
895
+ printSkillInstallResult(result, Boolean(options.dryRun));
826
896
  }
827
897
  async function main() {
828
898
  if (process.argv.slice(2).includes("--list")) {
@@ -856,6 +926,7 @@ async function main() {
856
926
 
857
927
  Examples:
858
928
  agentkit init
929
+ agentkit skill install
859
930
  agentkit update
860
931
  agentkit init --preset next
861
932
  agentkit init ./my-project --yes --dry-run
@@ -875,10 +946,35 @@ Examples:
875
946
  .option("--design-system <name>", `design system guidance for DESIGN-SYSTEM.md (${formatDesignSystemList()})`)
876
947
  .action(async (target, options) => {
877
948
  await applyInitConfig(options, await loadConfigForTarget(target));
878
- const resolvedTarget = await resolveInteractiveTarget(target, options);
879
- 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);
880
955
  printInstallResult(result, Boolean(options.dryRun));
881
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
+ });
882
978
  program
883
979
  .command("update")
884
980
  .description("update AgentKit managed template blocks in a project")
@@ -887,7 +983,14 @@ Examples:
887
983
  .option("--preset <name>", `update stack-specific guidance (${formatPresetList()})`)
888
984
  .option("--design-system <name>", `design system guidance for DESIGN-SYSTEM.md (${formatDesignSystemList()})`)
889
985
  .action(async (target, options) => {
890
- 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);
891
994
  const result = await updateTemplates(target, options);
892
995
  printUpdateResult(result, Boolean(options.dryRun));
893
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.7.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",
@@ -6,21 +6,22 @@ Use this rule as a repository guidance router for Cursor agents and composer wor
6
6
 
7
7
  - Follow `AGENTS.md` first.
8
8
  - Treat `AGENTS.md` as the source of truth for repository-wide agent behavior.
9
- - Keep context focused. Read companion files only when relevant to the task.
9
+ - Do not load companion files for routine coding unless a trigger in `AGENTS.md` applies or the user asks.
10
10
 
11
- ## Read When Relevant
11
+ ## When Relevant
12
12
 
13
- - `CODE-QUALITY.md`: code quality, review, refactors, dependencies.
14
- - `WORKFLOWS.md`: planning, implementation, review, release.
15
- - `CHANGE-EXPLANATION.md`: final handoff and developer-facing explanation.
16
- - `DESIGN-SYSTEM.md`: UI, styling, layout, navigation, components.
17
- - `TESTING.md`: tests, fixtures, mocks, QA strategy.
18
- - `SECURITY-CHECKLIST.md`: auth, permissions, secrets, PII, data handling.
19
- - `STACK.md`: stack-specific rules when present.
13
+ - **File edits (final message):** change-explanation format in `AGENTS.md` and `CHANGE-EXPLANATION.md`.
14
+ - **UI / styling / layout:** `DESIGN-SYSTEM.md` or the project design-system path from `AGENTS.md`.
15
+ - **Review / refactor / dependencies:** `CODE-QUALITY.md`.
16
+ - **Tests / QA strategy:** `TESTING.md` if present.
17
+ - **Auth / secrets / PII:** `SECURITY-CHECKLIST.md` if present.
18
+ - **Stack-specific code:** `STACK.md` if present.
19
+ - **Planning docs requested:** create from `PRD-TEMPLATE.md` or `IMPLEMENTATION-BRIEF-TEMPLATE.md` under the project's briefs path.
20
+ - **Process map (optional):** `WORKFLOWS.md` if present.
20
21
 
21
22
  ## Cursor Behavior
22
23
 
23
24
  - Prefer existing repository patterns over generic generated patterns.
24
25
  - Keep changes scoped and reviewable.
25
26
  - Do not change foundational architecture, schema, dependencies, or theme primitives without explicit approval.
26
- - Summarize changed files, checks run, risks, and review focus before handoff.
27
+ - After modifying files, end every task with a change explanation per `AGENTS.md` (summary, what changed, verification, risks, review focus). Scale depth to the change; do not skip for small fixes.
@@ -2,15 +2,7 @@
2
2
 
3
3
  Follow `AGENTS.md` first. It is the primary source of truth for this repository's AI-agent guidance.
4
4
 
5
- When relevant, also read:
6
-
7
- - `CODE-QUALITY.md`
8
- - `WORKFLOWS.md`
9
- - `CHANGE-EXPLANATION.md`
10
- - `DESIGN-SYSTEM.md`
11
- - `TESTING.md`
12
- - `SECURITY-CHECKLIST.md`
13
- - `STACK.md`
5
+ Do not load companion files for routine coding. Use `AGENTS.md` triggers: change explanation after file edits; `CODE-QUALITY.md` for review/refactors; design-system path or `DESIGN-SYSTEM.md` for UI; `TESTING.md`, `SECURITY-CHECKLIST.md`, or `STACK.md` when present and relevant; planning templates only when explicitly requested.
14
6
 
15
7
  For files covered by additional GitHub instructions under `.github/instructions/`, apply those path-specific instructions together with this file.
16
8