incitaciones 0.6.0 → 0.7.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.
@@ -32,6 +32,17 @@ Manage `~/.whisper/` — a global, tiered knowledge directory that accumulates o
32
32
 
33
33
  **Worktree slot rule:** `basename $(git rev-parse --git-common-dir 2>/dev/null)` (the `.git` worktree dir name), or `basename $(pwd)` when not in a worktree.
34
34
 
35
+ **Canonical repo key rule — derive it, never invent it:**
36
+
37
+ ```bash
38
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
39
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
40
+ ```
41
+
42
+ `git@cv:org/repo.git` → `cv/org/repo`; `https://github.com/u/r` → `github.com/u/r`; no remote → `local/<repo-name>`. Colons always become slashes (keeps keys path-safe). The same key must come out of the same repo on every machine.
43
+
44
+ If a directory keyed some other way already exists for this repo (bare name like `genesis/`, owner-only like `charly-vibes/`, alias host with a colon like `cv:charly-vibes/`), do **not** add a fourth variant — route new knowledge into the canonical key and offer `/w consolidate` to migrate the legacy one.
45
+
35
46
  ## Knowledge Routing
36
47
 
37
48
  When a session learns something worth keeping, route it by scope:
@@ -47,6 +58,7 @@ When a session learns something worth keeping, route it by scope:
47
58
  **Rules:**
48
59
  - **No secrets anywhere.** Never write tokens, keys, passwords, or PII into `~/.whisper/`.
49
60
  - **Extend, don't duplicate.** Append to or correct an existing note rather than creating a new one that says the same thing.
61
+ - **One repo, one key.** If more than one `repos/` directory belongs to the same repo, write into the canonical key and propose `/w consolidate` — never create a new variant.
50
62
  - **Search first.** Before creating a new entry, check if one already exists for the same topic.
51
63
  - If `bd` is not available, everything falls back to `~/.whisper/` files — there's no beads-backed alternative.
52
64
 
@@ -61,6 +73,7 @@ Determine mode from how the skill is triggered:
61
73
  | `/w check` or called by `renew` | **check** |
62
74
  | `/w link [<path>]` or "link plan" | **link** |
63
75
  | `/w decommission` | **decommission** |
76
+ | `/w consolidate` or "dedupe whisper repos" | **consolidate** |
64
77
 
65
78
  See each reference file for the full procedure:
66
79
 
@@ -69,6 +82,7 @@ See each reference file for the full procedure:
69
82
  - `references/status.md`
70
83
  - `references/link.md`
71
84
  - `references/decommission.md`
85
+ - `references/consolidate.md`
72
86
 
73
87
  ## Rules
74
88
 
@@ -6,7 +6,8 @@ Validate the workspace before starting work. Detects stale branch slots and work
6
6
 
7
7
  1. Get repo URL and branch slug:
8
8
  ```bash
9
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
9
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
10
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
10
11
  branch=$(git rev-parse --abbrev-ref HEAD)
11
12
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
12
13
  context_path=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"/context.md
@@ -0,0 +1,41 @@
1
+ # Consolidate
2
+
3
+ Merge duplicate `~/.whisper/repos/` directories for the same repo into the single canonical key. One repo, one key.
4
+
5
+ ## Why
6
+
7
+ Older sessions keyed repos inconsistently — bare repo name (`genesis/`), owner dir (`charly-vibes/`), ssh-alias host with a colon (`cv:charly-vibes/`), full URL in the wrong shape. The same repo's knowledge ends up scattered across several trees, so `check` and `status` miss notes that exist. Consolidation restores the invariant; the canonical key derivation is defined in SKILL.md.
8
+
9
+ ## Steps
10
+
11
+ 1. **Inventory candidates** — non-canonical top-level entries. Canonical = at least 2 slashes and no colon in the first segment; also flag alias-host dirs (`<alias>:<owner>`):
12
+
13
+ ```bash
14
+ for d in ~/.whisper/repos/*/; do echo "${d#$HOME/.whisper/repos/}"; done
15
+ ```
16
+ A key is a candidate if it has 0 or 1 slashes, or contains `:`.
17
+
18
+ 2. **Derive the canonical target per candidate** — check the actual repo's remote:
19
+
20
+ ```bash
21
+ cd <repo checkout> && git remote get-url origin | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||'
22
+ ```
23
+ If no checkout is reachable for a candidate, leave it in place and report it — never guess the mapping from the name alone.
24
+
25
+ 3. **Produce a migration table and WAIT for approval** — one row per candidate: old key → canonical key, files found, merge conflicts detected. The user must explicitly approve before anything moves. If running non-interactively, output the plan and stop.
26
+
27
+ 4. **Merge per file on approval:**
28
+ - `env.md` — append the candidate's content under a `## Migrated from <old-key>` heading; merge only verbatim-identical lines.
29
+ - `branches/<slug>/*` — if the canonical tree has the same slug, append notes with a provenance heading; otherwise `mv` the whole branch slot into `branches/`.
30
+ - `worktrees/<name>/*` — same rule as branch slots.
31
+ - Never overwrite an existing file silently. Never delete a file.
32
+
33
+ 5. **Clean up** — remove candidate directories only if they are now empty (`rmdir -p --ignore-fail-on-non-empty`). Anything left behind is reported, not deleted.
34
+
35
+ 6. **Verify** — re-run the candidate scan (step 1): nothing non-canonical remains, or every remaining entry is accounted for with a reason. Run the `check` flow for the current repo and confirm it resolves to the canonical tree.
36
+
37
+ ## Rules
38
+
39
+ - Provenance headings are mandatory — the user must be able to trace every merged block back to its original location.
40
+ - `git mv` nothing: `~/.whisper/` is not a git repository. Plain `mv`/append only.
41
+ - If two candidates map to the same canonical key (e.g. `charly-vibes/genesis` and `genesis/`), consolidate them sequentially and re-scan between rounds.
@@ -8,7 +8,8 @@ Safely wind down a worktree or branch: defer open work under the branch epic, re
8
8
 
9
9
  2. Get repo URL and branch slug:
10
10
  ```bash
11
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
11
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
12
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
12
13
  branch=$(git rev-parse --abbrev-ref HEAD)
13
14
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
14
15
  branch_dir=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"
@@ -20,7 +20,8 @@ Create `~/.whisper/` and the current workspace slot.
20
20
 
21
21
  3. Compute the repo path and branch slug:
22
22
  ```bash
23
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
23
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
24
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
24
25
  branch=$(git rev-parse --abbrev-ref HEAD)
25
26
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
26
27
  ```
@@ -10,7 +10,8 @@ This mode is self-contained — it does NOT require `create-plan` to have been u
10
10
 
11
11
  2. Get repo URL and branch slug:
12
12
  ```bash
13
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
13
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
14
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
14
15
  branch=$(git rev-parse --abbrev-ref HEAD)
15
16
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
16
17
  branch_dir=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"
@@ -6,7 +6,8 @@ Show the state of the current workspace.
6
6
 
7
7
  1. Get repo URL and branch slug:
8
8
  ```bash
9
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
9
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
10
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
10
11
  branch=$(git rev-parse --abbrev-ref HEAD)
11
12
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
12
13
  context_path=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"/context.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incitaciones",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Reusable prompts and skills for CLI LLM tools, with native pi package support.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,6 +38,17 @@ Manage `~/.whisper/` — a global, tiered knowledge directory that accumulates o
38
38
 
39
39
  **Worktree slot rule:** `basename $(git rev-parse --git-common-dir 2>/dev/null)` (the `.git` worktree dir name), or `basename $(pwd)` when not in a worktree.
40
40
 
41
+ **Canonical repo key rule — derive it, never invent it:**
42
+
43
+ ```bash
44
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
45
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
46
+ ```
47
+
48
+ `git@cv:org/repo.git` → `cv/org/repo`; `https://github.com/u/r` → `github.com/u/r`; no remote → `local/<repo-name>`. Colons always become slashes (keeps keys path-safe). The same key must come out of the same repo on every machine.
49
+
50
+ If a directory keyed some other way already exists for this repo (bare name like `genesis/`, owner-only like `charly-vibes/`, alias host with a colon like `cv:charly-vibes/`), do **not** add a fourth variant — route new knowledge into the canonical key and offer `/w consolidate` to migrate the legacy one.
51
+
41
52
  ## Knowledge Routing
42
53
 
43
54
  When a session learns something worth keeping, route it by scope:
@@ -53,6 +64,7 @@ When a session learns something worth keeping, route it by scope:
53
64
  **Rules:**
54
65
  - **No secrets anywhere.** Never write tokens, keys, passwords, or PII into `~/.whisper/`.
55
66
  - **Extend, don't duplicate.** Append to or correct an existing note rather than creating a new one that says the same thing.
67
+ - **One repo, one key.** If more than one `repos/` directory belongs to the same repo, write into the canonical key and propose `/w consolidate` — never create a new variant.
56
68
  - **Search first.** Before creating a new entry, check if one already exists for the same topic.
57
69
  - If `bd` is not available, everything falls back to `~/.whisper/` files — there's no beads-backed alternative.
58
70
 
@@ -67,6 +79,7 @@ Determine mode from how the skill is triggered:
67
79
  | `/w check` or called by `renew` | **check** |
68
80
  | `/w link [<path>]` or "link plan" | **link** |
69
81
  | `/w decommission` | **decommission** |
82
+ | `/w consolidate` or "dedupe whisper repos" | **consolidate** |
70
83
 
71
84
  See each reference file for the full procedure:
72
85
 
@@ -75,6 +88,7 @@ See each reference file for the full procedure:
75
88
  - `references/status.md`
76
89
  - `references/link.md`
77
90
  - `references/decommission.md`
91
+ - `references/consolidate.md`
78
92
 
79
93
  ## Rules
80
94
 
@@ -6,7 +6,8 @@ Validate the workspace before starting work. Detects stale branch slots and work
6
6
 
7
7
  1. Get repo URL and branch slug:
8
8
  ```bash
9
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
9
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
10
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
10
11
  branch=$(git rev-parse --abbrev-ref HEAD)
11
12
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
12
13
  context_path=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"/context.md
@@ -0,0 +1,41 @@
1
+ # Consolidate
2
+
3
+ Merge duplicate `~/.whisper/repos/` directories for the same repo into the single canonical key. One repo, one key.
4
+
5
+ ## Why
6
+
7
+ Older sessions keyed repos inconsistently — bare repo name (`genesis/`), owner dir (`charly-vibes/`), ssh-alias host with a colon (`cv:charly-vibes/`), full URL in the wrong shape. The same repo's knowledge ends up scattered across several trees, so `check` and `status` miss notes that exist. Consolidation restores the invariant; the canonical key derivation is defined in SKILL.md.
8
+
9
+ ## Steps
10
+
11
+ 1. **Inventory candidates** — non-canonical top-level entries. Canonical = at least 2 slashes and no colon in the first segment; also flag alias-host dirs (`<alias>:<owner>`):
12
+
13
+ ```bash
14
+ for d in ~/.whisper/repos/*/; do echo "${d#$HOME/.whisper/repos/}"; done
15
+ ```
16
+ A key is a candidate if it has 0 or 1 slashes, or contains `:`.
17
+
18
+ 2. **Derive the canonical target per candidate** — check the actual repo's remote:
19
+
20
+ ```bash
21
+ cd <repo checkout> && git remote get-url origin | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||'
22
+ ```
23
+ If no checkout is reachable for a candidate, leave it in place and report it — never guess the mapping from the name alone.
24
+
25
+ 3. **Produce a migration table and WAIT for approval** — one row per candidate: old key → canonical key, files found, merge conflicts detected. The user must explicitly approve before anything moves. If running non-interactively, output the plan and stop.
26
+
27
+ 4. **Merge per file on approval:**
28
+ - `env.md` — append the candidate's content under a `## Migrated from <old-key>` heading; merge only verbatim-identical lines.
29
+ - `branches/<slug>/*` — if the canonical tree has the same slug, append notes with a provenance heading; otherwise `mv` the whole branch slot into `branches/`.
30
+ - `worktrees/<name>/*` — same rule as branch slots.
31
+ - Never overwrite an existing file silently. Never delete a file.
32
+
33
+ 5. **Clean up** — remove candidate directories only if they are now empty (`rmdir -p --ignore-fail-on-non-empty`). Anything left behind is reported, not deleted.
34
+
35
+ 6. **Verify** — re-run the candidate scan (step 1): nothing non-canonical remains, or every remaining entry is accounted for with a reason. Run the `check` flow for the current repo and confirm it resolves to the canonical tree.
36
+
37
+ ## Rules
38
+
39
+ - Provenance headings are mandatory — the user must be able to trace every merged block back to its original location.
40
+ - `git mv` nothing: `~/.whisper/` is not a git repository. Plain `mv`/append only.
41
+ - If two candidates map to the same canonical key (e.g. `charly-vibes/genesis` and `genesis/`), consolidate them sequentially and re-scan between rounds.
@@ -8,7 +8,8 @@ Safely wind down a worktree or branch: defer open work under the branch epic, re
8
8
 
9
9
  2. Get repo URL and branch slug:
10
10
  ```bash
11
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
11
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
12
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
12
13
  branch=$(git rev-parse --abbrev-ref HEAD)
13
14
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
14
15
  branch_dir=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"
@@ -20,7 +20,8 @@ Create `~/.whisper/` and the current workspace slot.
20
20
 
21
21
  3. Compute the repo path and branch slug:
22
22
  ```bash
23
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
23
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
24
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
24
25
  branch=$(git rev-parse --abbrev-ref HEAD)
25
26
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
26
27
  ```
@@ -10,7 +10,8 @@ This mode is self-contained — it does NOT require `create-plan` to have been u
10
10
 
11
11
  2. Get repo URL and branch slug:
12
12
  ```bash
13
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
13
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
14
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
14
15
  branch=$(git rev-parse --abbrev-ref HEAD)
15
16
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
16
17
  branch_dir=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"
@@ -6,7 +6,8 @@ Show the state of the current workspace.
6
6
 
7
7
  1. Get repo URL and branch slug:
8
8
  ```bash
9
- repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|git@||;s|\.git$||')
9
+ repo_url=$(git remote get-url origin 2>/dev/null | sed 's|https://||;s|http://||;s|ssh://||;s|git@||;s|:|/|g;s|\.git$||')
10
+ [ -z "$repo_url" ] && repo_url="local/$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")"
10
11
  branch=$(git rev-parse --abbrev-ref HEAD)
11
12
  branch_slug=$(echo "$branch" | sed 's|/|--|g')
12
13
  context_path=~/.whisper/repos/"${repo_url}"/branches/"${branch_slug}"/context.md