@victortomaili/skill-cli 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -11,6 +11,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
  - Cursor adapter (`.cursor/rules` format) for `init -g` bootstrap.
12
12
  - Per-agent hook adapters for automatic `/X` triggering (push model).
13
13
 
14
+ ## [0.6.0] - 2026-07-07
15
+
16
+ ### Changed
17
+ - **`skill defaults` is now a description-only catalog.** It lists EVERY installed
18
+ skill (name + full description + triggers; ★ marks defaults) — never the skill
19
+ body. The agent reads the catalog and decides per skill: functional for the task
20
+ → `skill cat <name>`; context-altering (changes HOW the agent responds) → propose
21
+ and wait for the user's confirmation. This follows the existing SKILL.md standard
22
+ — no extra frontmatter field is required or expected on any skill.
23
+ - **Context-altering detection is the agent's judgment, from the description.** Any
24
+ skill can be context-altering (including ones installed later); the agent decides
25
+ from the description text, with no hardcoded list. (`skill cat` is unchanged — it
26
+ still loads a full skill on demand.)
27
+
28
+ ### Added
29
+ - AGENTS.md START GATE now enforces **"LOADED ≠ LISTED"**: a skill is loaded only
30
+ if the agent ran `skill cat <name>` for it this session — listing/cataloging a
31
+ skill (or its ★ / `active` status) is not loading.
32
+
33
+ ## [0.5.1] - 2026-07-07
34
+
35
+ ### Fixed
36
+ - AGENTS.md bootstrap block hardened into hard rules after a live pi-agent test
37
+ surfaced two gaps. **(a) START GATE:** on the first user message, the agent's
38
+ VERY FIRST action — BEFORE ANYTHING ELSE (before thinking, before any tool call)
39
+ — MUST be `skill defaults` + `skill cat <name>` for each, then `skill list`
40
+ (discovery is mandatory, not optional). **(b) Context-altering = PROPOSE-ONLY:**
41
+ `active` / ★-default means *available*, not *applied* — propose ≠ auto-apply,
42
+ and the rule overrides any other skill's "always use" instruction. Also:
43
+ whenever a skill is loaded mid-session, re-evaluate the message and load/propose
44
+ any newly-relevant one.
45
+
14
46
  ## [0.5.0] - 2026-07-07
15
47
 
16
48
  ### Added
package/README.md CHANGED
@@ -196,13 +196,16 @@ default; `space` toggles the per-project override.
196
196
  `skill init -g` injects a short, idempotent block into each detected agent's global
197
197
  instruction file (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`):
198
198
 
199
- > On session start, run `skill defaults` and load each with `skill cat <name>`.
200
- > Skills are NOT in context until you load them each message, decide whether one
201
- > is relevant and load it (`skill cat <name>` / `skill trigger <keyword>`); load each
202
- > only once. A skill that changes HOW you respond (output style/mode) is PROPOSED,
203
- > not auto-applied apply only after the user confirms (an explicit `/X` counts).
204
- > When the user types `/X`, run `skill trigger X` single match → apply; multiple →
205
- > show candidates.
199
+ > **START GATE:** on the first user message, your VERY FIRST action BEFORE
200
+ > ANYTHING ELSE (before thinking, before any tool call)is `skill defaults`, the
201
+ > skill **catalog** (every skill's name + full description; never the body). Read
202
+ > it and decide per skill from its description: **functional** for the task load
203
+ > it (`skill cat <name>`); **context-altering** (changes HOW you respond
204
+ > style/mode) **propose**, apply only after the user confirms (`/X` = confirm).
205
+ > **LOADED ≠ LISTED**: a skill is loaded only if you `cat`-ed it this session —
206
+ > listing it (or its ★ / `active` status) is not loading. Any skill can be
207
+ > context-altering; the agent judges from the description (no flag, no fixed list).
208
+ > `/X` → `skill trigger X`.
206
209
 
207
210
  It's wrapped in `<!-- BEGIN skill-cli --> … <!-- END skill-cli -->` markers, never
208
211
  duplicates, and preserves your existing file content. Re-run `init -g` any time —
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victortomaili/skill-cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Cross-agent skill manager — one global store, clean agent folders, activation via skill.config",
5
5
  "license": "MIT",
6
6
  "author": "Victor Tomaili <victor@tomaili.com>",
@@ -1,7 +1,6 @@
1
1
  import c from 'picocolors'
2
2
  import { listStore } from '../lib/store.js'
3
- import { readGlobalConfig, writeGlobalConfig, computeDefaults } from '../lib/config.js'
4
- import { trunc } from '../lib/format.js'
3
+ import { readGlobalConfig, writeGlobalConfig } from '../lib/config.js'
5
4
 
6
5
  // `skill defaults` — list the skills marked as defaults. In the unified model a
7
6
  // default skill is BOTH active-by-default in every project AND auto-loaded on
@@ -11,24 +10,31 @@ import { trunc } from '../lib/format.js'
11
10
  export function cmdDefaults() {
12
11
  const installed = listStore()
13
12
  const globalCfg = readGlobalConfig()
14
- const eff = computeDefaults(installed, globalCfg)
13
+ const defs = new Set((globalCfg.defaults || []).map(d => String(d).toLowerCase()))
15
14
 
16
- console.log(c.bold('skill defaults') + c.gray(' — active by default + auto-load on session start (global)'))
15
+ console.log(c.bold('skill defaults') + c.gray(' — skill catalog (descriptions only; the agent decides: functional → `skill cat`, context-altering → propose)'))
17
16
  console.log()
18
17
 
19
- if (eff.length === 0) {
20
- console.log(c.gray(' No default skills yet. Mark with: ') + c.cyan('skill default <name>'))
18
+ if (installed.length === 0) {
19
+ console.log(c.gray(' No skills installed. Install with: ') + c.cyan('skill install <source>'))
21
20
  return
22
21
  }
23
22
 
24
- for (const name of eff) {
25
- const s = installed.find(x => x.name === name)
26
- const trg = s && s.triggers.length ? ' ' + c.gray('/' + s.triggers.join(', /')) : ''
27
- console.log(` ${c.yellow('')} ${c.bold(name.padEnd(22))}${trg}`)
28
- if (s && s.description) console.log(c.gray(' ' + trunc(s.description, 66)))
23
+ // CATALOG, not a loader: print every installed skill's name + FULL description
24
+ // (collapsed to one line) + triggers. Never dump the skill body here — the
25
+ // agent reads descriptions, then itself decides per skill: load (skill cat) if
26
+ // it's functional for the task, or PROPOSE if it's context-altering (changes
27
+ // HOW the agent responds). Detection is the agent's judgment from the
28
+ // description, so it works for any skill — including ones loaded later — with
29
+ // no hardcoded list or flag.
30
+ for (const s of installed) {
31
+ const star = defs.has(s.name.toLowerCase()) ? c.yellow('★') + ' ' : ' '
32
+ const trg = s.triggers.length ? ' ' + c.gray('/' + s.triggers.join(', /')) : ''
33
+ console.log(` ${star}${c.bold(s.name)}${trg}`)
34
+ if (s.description) console.log(c.gray(' ' + String(s.description).replace(/[\r\n]+/g, ' ').trim()))
29
35
  }
30
36
  console.log()
31
- console.log(c.gray('Load each into context: ') + c.cyan('skill cat <name>'))
37
+ console.log(c.yellow('★') + c.gray(' = default (active by default). Load a skill: ') + c.cyan('skill cat <name>'))
32
38
  }
33
39
 
34
40
  // `skill default <name>` — mark a skill as a default (active by default in every
@@ -6,8 +6,10 @@ const BEGIN = '<!-- BEGIN skill-cli -->'
6
6
  const END = '<!-- END skill-cli -->'
7
7
 
8
8
  // Global instruction block — injected into each agent's global instruction file.
9
- // Covers usage, defaults (auto-load), per-message discovery, and the
10
- // propose-then-confirm rule for context-altering skills.
9
+ // `skill defaults` is a description-only CATALOG; the agent reads it, then itself
10
+ // decides per skill: functional → `skill cat`, context-altering → propose. No flag
11
+ // or fixed list — detection is the agent's judgment from the description, so it
12
+ // covers any skill (including ones installed later).
11
13
  export const AGENTS_BLOCK = `## skill-cli
12
14
 
13
15
  This machine uses the \`skill\` command to manage skills (instruction / workflow
@@ -16,24 +18,36 @@ NOT copied into agent directories (\`~/.claude\`, \`~/.codex\`, etc.) — so the
16
18
  won't appear here.
17
19
 
18
20
  Usage:
19
- - \`skill list\` — skills installed and active in the current project
21
+ - \`skill list\` — skills installed + active in the current project (with triggers)
20
22
  - \`skill show <name>\` — skill summary (path, triggers, version)
21
23
  - \`skill cat <name>\` — load skill content into context
24
+ - \`skill default <name>\` — mark a skill as a global default (active + auto-load)
22
25
 
23
- Defaults: on session start, run \`skill defaults\` to list skills marked as
24
- defaults (active by default + auto-load), then \`skill cat <name>\` for each. Mark
25
- your own with \`skill default <name>\` (global active in every project).
26
+ START GATE (mandatory): On the FIRST user message of a session, your VERY FIRST
27
+ action BEFORE ANYTHING ELSE: before you start thinking/reasoning about the task
28
+ and before any tool call MUST be to run \`skill defaults\`. It prints the skill
29
+ CATALOG — every installed skill's name + FULL description (NOT the skill body).
30
+ Read it, then for EACH skill decide FROM ITS DESCRIPTION:
31
+ - Functional / useful for THIS task → load it: \`skill cat <name>\`.
32
+ - Changes HOW you respond (a style, tone, format, or persistent MODE — e.g. a
33
+ brevity/compression style) → it is CONTEXT-ALTERING: PROPOSE it to the user and
34
+ apply ONLY after they confirm (\`/X\` = confirm). Do NOT load/apply it yourself.
35
+ LOADED ≠ LISTED. A skill is loaded ONLY if you have run \`skill cat <name>\` for
36
+ it THIS session. Seeing a skill in \`skill defaults\` / \`skill list\` does NOT load
37
+ it — you then know only its name + description, nothing more. Never infer a skill
38
+ is in your context from its name, the \u2605 marker, or an \`active\` status: if you
39
+ haven't catted it, treat it as NOT loaded (then decide: cat it, or propose it).
40
+ Do not assume a skill is already applied — \`active\`/\u2605-default = AVAILABLE, not
41
+ APPLIED. ANY skill can be context-altering; judge from the description — there is
42
+ no fixed list and no flag. Do this even if the task looks trivial: skills shape
43
+ how you approach it, so you cannot reason about it correctly until you've reviewed
44
+ them.
26
45
 
27
- Discovery: skills are NOT used unless you load them never assume a skill is
28
- already in context. On each user message, decide whether a skill is relevant to
29
- the task (match the message against a skill's triggers/topic); if one is relevant
30
- AND not yet loaded, load it with \`skill cat <name>\` (or \`skill trigger <keyword>\`
31
- to resolve a keyword to a skill). Load each skill only ONCE per session.
32
-
33
- Context-altering skills: some skills change HOW you respond — output style, tone,
34
- format, or a persistent mode (e.g. a terseness/compression style) — rather than
35
- just adding task knowledge. Do NOT auto-apply these. PROPOSE the skill and apply
36
- it only after the user confirms; an explicit \`/X\` trigger counts as confirmation.
46
+ Discovery (every message): On EVERY later user message, re-check the catalog
47
+ against the new request; load any newly-relevant functional skill
48
+ (\`skill cat <name>\`), and PROPOSE any newly-relevant context-altering one.
49
+ Load each skill only ONCE per session (\`skill trigger <keyword>\` resolves a
50
+ keyword to a skill).
37
51
 
38
52
  Triggers: when the user types \`/X\`, run \`skill trigger X\`.
39
53
  - Single match → apply the output directly.