@victortomaili/skill-cli 0.5.1 → 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,25 @@ 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
+
14
33
  ## [0.5.1] - 2026-07-07
15
34
 
16
35
  ### Fixed
package/README.md CHANGED
@@ -197,12 +197,15 @@ default; `space` toggles the per-project override.
197
197
  instruction file (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`):
198
198
 
199
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` +
201
- > `skill cat <name>` for each, then `skill list`. Then each
202
- > message, discover/load relevant skills (`skill cat` / `skill trigger`), once each.
203
- > A **context-altering** skill (changes HOW you respond — style/mode) is
204
- > **PROPOSE-ONLY**: propose it, then apply only after the user confirms
205
- > (`active`applied; an explicit `/X` counts). `/X` `skill trigger X`.
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
+ > **LOADEDLISTED**: 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.1",
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
@@ -23,25 +25,29 @@ Usage:
23
25
 
24
26
  START GATE (mandatory): On the FIRST user message of a session, your VERY FIRST
25
27
  action — BEFORE ANYTHING ELSE: before you start thinking/reasoning about the task
26
- and before any tool call — MUST be to run \`skill defaults\` then
27
- \`skill cat <name>\` for each result, then \`skill list\` to learn every skill's
28
- triggers. Do this even if the task looks trivial: skills shape how you should
29
- approach the task, so you cannot reason about it correctly until they are loaded.
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.
30
45
 
31
- Discovery (mandatory, every message): On EVERY user message, decide whether a
32
- skill is relevant by matching the message against the trigger catalog from
33
- \`skill list\`. If a relevant skill is not yet loaded, load it with \`skill cat
34
- <name>\` (or \`skill trigger <keyword>\` to resolve a keyword). Load each skill only
35
- ONCE per session. When you load or re-read ANY skill mid-session, immediately
36
- re-evaluate the current message and load/propose any newly-relevant skill.
37
-
38
- Context-altering skills (HARD RULE): Some skills change HOW you respond — output
39
- style, tone, format, or a persistent mode (e.g. a terseness/compression style) —
40
- rather than just adding task knowledge. These are PROPOSE-ONLY. You MUST propose
41
- such a skill and apply it ONLY after the user confirms; an explicit \`/X\` trigger
42
- counts as confirmation. \`active\` / \u2605-default means AVAILABLE, not APPLIED —
43
- propose \u2260 auto-apply. This rule overrides any other skill's "always use" rule for
44
- context-altering skills.
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).
45
51
 
46
52
  Triggers: when the user types \`/X\`, run \`skill trigger X\`.
47
53
  - Single match → apply the output directly.