Skip to content

feat(init): prompt to install AI DevKit built-in skills during interactive init#60

Merged
codeaholicguy merged 3 commits intocodeaholicguy:mainfrom
nnhhoang:feat/auto-install-skills-on-init
Apr 17, 2026
Merged

feat(init): prompt to install AI DevKit built-in skills during interactive init#60
codeaholicguy merged 3 commits intocodeaholicguy:mainfrom
nnhhoang:feat/auto-install-skills-on-init

Conversation

@nnhhoang
Copy link
Copy Markdown
Contributor

@nnhhoang nnhhoang commented Apr 16, 2026

Summary

Fixes #56. Before this change, `ai-devkit init` without a template never installed any skills into `.claude`/`.cursor`/etc., even though agents need them for the guided SDLC workflow. Users had to discover and run `ai-devkit skill add codeaholicguy/ai-devkit` separately, or init with a specific template.

This PR adds a single `Y/n` prompt after phase setup asking whether to install the built-in AI DevKit skills. Default is Yes so fresh users get the expected experience out of the box; users who want a lean setup can decline.

Behavior

Mode Before After
Interactive (`ai-devkit init`) No skills installed Prompt Y/n (default Yes) → installs 8 built-in skills
Template (`-t foo.yaml` with `skills:`) Installs template skills Unchanged
Template (`-t foo.yaml` without `skills:`) No skills installed Unchanged (no built-in prompt in template mode)

Built-in skills

Hardcoded curated list from the `codeaholicguy/ai-devkit` registry:

  • `dev-lifecycle`, `debug`, `capture-knowledge`, `memory`, `simplify-implementation`, `technical-writer`, `verify`, `tdd`

Matches what `templates/senior-engineer.yaml` already declares as the recommended devkit set.

Implementation

  • Reuses the existing `installTemplateSkills` helper → failures are reported as warnings instead of aborting init (same contract as template-driven installs).
  • Only runs when `!hasTemplate`, so template mode is completely untouched.

Test plan

  • `nx run-many -t build test lint` → 397 tests pass across 4 packages, 0 lint errors
  • 4 new tests in `init.test.ts`:
    • Installs built-ins when user confirms
    • Skips install when user declines (still shows prompt)
    • Does not show built-in prompt in template mode
    • Continues init gracefully when a built-in install fails
  • Manual smoke test: built the CLI and ran `init --environment claude --all` in a scratch dir — accept path installed all 8 skills and listed them in `.ai-devkit.json`, decline path left `.claude/skills/` absent. Output posted as a comment on this PR.

Notes

Happy to adjust the default (Yes → No), the skill list, or expose a `--skip-builtin-skills`/`--with-builtin-skills` flag for CI/non-interactive use if you prefer a different UX.

@nnhhoang
Copy link
Copy Markdown
Contributor Author

Manual smoke test in a scratch directory

Built the CLI from this branch and ran it against a fresh scratch dir to confirm the prompt actually appears and both paths work end-to-end.

Accept path (user presses y)

Command:

cd /tmp/ai-devkit-smoke && git init
printf 'y\n' | node ./dist/cli.js init --environment claude --all

Relevant output:

✔ Created requirements phase
... (all phases created)
✔ Created monitoring phase
? Install AI DevKit built-in skills from codeaholicguy/ai-devkit? (Y/n) y
? Install AI DevKit built-in skills from codeaholicguy/ai-devkit? Yes
Installing AI DevKit built-in skills...
ℹ Validating skill: dev-lifecycle from codeaholicguy/ai-devkit
  → .claude/skills/dev-lifecycle (symlinked)
... (each of 8 skills)
✔ Installed 8 built-in skill(s).

AI DevKit initialized successfully!

Filesystem state:

$ ls .claude/skills/
capture-knowledge -> ~/.ai-devkit/skills/codeaholicguy/ai-devkit/skills/capture-knowledge
debug             -> ...
dev-lifecycle     -> ...
memory            -> ...
simplify-implementation -> ...
tdd               -> ...
technical-writer  -> ...
verify            -> ...

.ai-devkit.json lists all 8 entries under skills.installed.

Decline path (user presses n)

Same command with printf 'n\n':

? Install AI DevKit built-in skills from codeaholicguy/ai-devkit? (Y/n) n
? Install AI DevKit built-in skills from codeaholicguy/ai-devkit? No

AI DevKit initialized successfully!

Filesystem: .claude/skills/ does not exist, .ai-devkit.json has no skills section. Init still completes successfully.

Summary

  • Prompt text renders correctly, default is Yes
  • Accept → all 8 built-in skills installed, symlinked the same way ai-devkit skill add does
  • Decline → zero side effects on skills, init still reports success
  • No regression in phase/environment setup in either path

@codeaholicguy
Copy link
Copy Markdown
Owner

@nnhhoang Thanks for the contribution, this is a good one.

I have a concern that if ai-devkit init runs in a CI pipeline or any environment without a TTY, inquirer.prompt will hang or crash. Tools commonly run in CI.

We need to detect no TTY (!process.stdin.isTTY) and skip the prompt (default to no); the logic of checking can be extracted from SkillManager to a utility for reusability.

Other than that, I think we can add an option so that it will automatically install the built-in skills without prompting.

Scenario Behavior
Interactive, no flag Prompt Y/n (default Yes)
Interactive, --built-in Install without prompting
Non-interactive (CI), no flag Skip silently
Non-interactive (CI), --built-in Install without prompting

The flag gives CI users explicit control, and the TTY detection is the safe fallback.

Comment thread packages/cli/src/commands/init.ts
@nnhhoang
Copy link
Copy Markdown
Contributor Author

nnhhoang commented Apr 17, 2026

Addressed both feedback points in d5821b7.

Changes

  • Constants extraction (per the inline comment on init.ts:81) — moved `BUILTIN_SKILL_REGISTRY` and `BUILTIN_SKILL_NAMES` into `packages/cli/src/constants.ts`. `BUILTIN_SKILLS` in init.ts is now derived via `.map()` over the shared names array so the registry string appears once. Future commands (doctor, upgrade, ...) can import the same list.

  • TTY detection + `--built-in` flag — extracted the previously-private `isInteractiveTerminal()` from SkillManager into `packages/cli/src/util/terminal.ts` and added a new `--built-in` flag. The init flow now implements the 4-state matrix you proposed:

    Scenario Behavior
    Interactive, no flag Prompt Y/n (default Yes)
    Interactive, `--built-in` Install without prompting
    Non-interactive (CI), no flag Skip, log a hint pointing at `--built-in`
    Non-interactive (CI), `--built-in` Install without prompting

Test coverage

  • `init.test.ts` now has three new tests covering the non-interactive paths (skip silently, `--built-in` forces install) and `--built-in` in an interactive context (still skips the prompt).
  • Existing five tests for the interactive-with-prompt flow continue to pass, so the default UX is unchanged.
  • `nx run-many -t test` → 401 tests across 4 packages, 0 failures. Lint clean.

Smoke test evidence

Scenario 1 — Non-interactive (piped stdin), no flag:
```
$ echo "" | node ./dist/cli.js init --environment claude --all
Created monitoring phase
Skipping built-in skills (non-interactive environment). Pass --built-in to install them from codeaholicguy/ai-devkit.

AI DevKit initialized successfully!

$ ls .claude/skills
ls: .claude/skills: No such file or directory # correct — install skipped
```

Scenario 2 — Non-interactive + `--built-in`:
```
$ echo "" | node ./dist/cli.js init --environment claude --all --built-in
Installing AI DevKit built-in skills...
Installing skill to project...
Installed to (project): claude
... (8 skills)

$ ls .claude/skills
capture-knowledge dev-lifecycle simplify-implementation technical-writer
debug memory tdd verify
```

Interactive paths are covered by the existing unit tests plus the earlier end-to-end smoke test I posted above.

…ctive init

Before this change, `ai-devkit init` without a template only set up
environments and phases — built-in skills were never installed, even
though agents need them for the guided SDLC workflow. Users had to
discover and run `ai-devkit skill add codeaholicguy/ai-devkit`
separately, or init with a specific template.

Now the interactive init prompts the user after phase setup asking
whether to install the built-in AI DevKit skills
(dev-lifecycle, debug, capture-knowledge, memory,
simplify-implementation, technical-writer, verify, tdd). Default is
Yes so fresh users get the expected experience out of the box, but
users who want a lean setup can decline.

Reuses the existing installTemplateSkills helper so failures are
reported as warnings instead of aborting init — matches the behavior
already established for template-driven installs.

The prompt only appears in interactive mode. Template mode
(`-t some.yaml`) is unchanged: templates that declare skills still
drive the install, and templates without skills still skip the
interactive prompt.

Fixes codeaholicguy#56
…n skills flow

Addresses PR review feedback:

- Detect non-interactive environments via a new isInteractiveTerminal()
  utility shared with SkillManager, so inquirer.prompt is never called
  when stdin is not a TTY. Prevents the init command from hanging
  in CI pipelines or any piped execution context.

- Introduce a --built-in CLI flag so users can opt in to installing the
  curated built-in skills without an interactive prompt. Behavior matrix:

    Interactive, no flag        -> prompt Y/n (default Yes)
    Interactive, --built-in     -> install without prompting
    Non-interactive, no flag    -> skip, log a hint pointing at --built-in
    Non-interactive, --built-in -> install without prompting

- Extract BUILTIN_SKILL_REGISTRY and BUILTIN_SKILL_NAMES into
  packages/cli/src/constants.ts so future commands (doctor, upgrade, ...)
  can import the same canonical list instead of duplicating names.
  BUILTIN_SKILLS in init.ts is now derived via .map() over the shared
  names array.

- Extract the previously-private isInteractiveTerminal() logic from
  SkillManager into util/terminal.ts. SkillManager now delegates to
  the shared helper so both commands see identical TTY semantics.

Adds three unit tests covering the new non-interactive paths and the
--built-in flag in both interactive and non-interactive contexts.
@nnhhoang nnhhoang force-pushed the feat/auto-install-skills-on-init branch from d5821b7 to 0e05326 Compare April 17, 2026 16:46
@codeaholicguy
Copy link
Copy Markdown
Owner

codeaholicguy commented Apr 17, 2026

Test organization misleads future readers (init.test.ts:201)

Both new describe blocks: built-in skills prompt (interactive init without template) and built-in skills in non-interactive environments (CI) are nested inside describe('init command template mode', ...). They test the opposite: non-template mode. This inverts the meaning of the outer describe scope and will confuse anyone running a single test suite by name.

Recommendation: Move the two new describe blocks to sit alongside the existing outer describe, not inside it.

@codeaholicguy
Copy link
Copy Markdown
Owner

codeaholicguy commented Apr 17, 2026

No test for --built-in when template already has skills

If a user runs ai-devkit init -t template.yaml --built-in and the template declares skills, --built-in is silently ignored (the else if (!hasTemplate) branch is never reached). This is probably the right behavior, but it's untested. Worth adding a test that asserts the silent-ignore.

…n + template

Addresses review feedback on PR codeaholicguy#60:

- Move the 'built-in skills prompt (interactive init without template)'
  and 'built-in skills in non-interactive environments (CI)' describe
  blocks out of 'init command template mode' and make them siblings
  under a single outer 'init command' describe. The previous nesting
  implied these scenarios ran under template mode when they test the
  opposite, which is misleading when a single describe is selected
  by name.

- Add two test cases in the 'template mode' describe that pin down
  the silent-ignore behavior of --built-in when a template is in play:
  once with skills declared (template skills install, no built-in
  path), once without (no install at all). This closes a previously
  untested invariant that future refactors could otherwise break.

No production code changes. 14 init tests across 3 sibling describes.
@nnhhoang
Copy link
Copy Markdown
Contributor Author

Done in 50559f2 — pulled the two new describes out so they sit next to template mode under a single init command describe instead of nested inside it. Also added two tests in the template describe to lock down the silent-ignore behavior of --built-in (once with template skills, once without). 448 tests still green.

@codeaholicguy
Copy link
Copy Markdown
Owner

LGTM.

Thanks for your contribution.

@codeaholicguy codeaholicguy merged commit 9419d3a into codeaholicguy:main Apr 17, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Claude Code] Skill is not packed inside when init kit

2 participants