cc-discipline 2.15.2 → 2.16.1
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/init.sh
CHANGED
|
@@ -541,7 +541,24 @@ echo -e "${GREEN}Installing skills...${NC}"
|
|
|
541
541
|
# in the preserved case. That is what makes adoption self-healing: if the user
|
|
542
542
|
# later replaces their file with the .new one, the next run sees disk == manifest
|
|
543
543
|
# and resumes silent updates.
|
|
544
|
+
#
|
|
545
|
+
# The flip side: an older template that was once misjudged as edited stays
|
|
546
|
+
# "edited" for good, because the manifest names the newer template and the file
|
|
547
|
+
# never matches it. That happened on every install from before 2.12.2, which had
|
|
548
|
+
# no manifest at all: 7 installs carried a never-edited 2026-04 /think until
|
|
549
|
+
# 2026-09-28, with a fresh .new beside it after every upgrade. So a file that
|
|
550
|
+
# matches any version we ever shipped (lib/skill-hashes, frozen) is also
|
|
551
|
+
# treated as ours, and a .new left beside a file that is now current is removed.
|
|
544
552
|
SKILLS_MANIFEST=".claude/.cc-discipline-skills.manifest"
|
|
553
|
+
KNOWN_SKILL_HASHES="$SCRIPT_DIR/lib/skill-hashes"
|
|
554
|
+
_cc_skill_shipped() { # $1=file $2=path under .claude/skills/ -> 0 if we once shipped it
|
|
555
|
+
[ -f "$1" ] && [ -f "$KNOWN_SKILL_HASHES" ] || return 1
|
|
556
|
+
_sa=$(_cc_algo)
|
|
557
|
+
[ "$(_cc_label "$_sa")" = sha256 ] || return 1
|
|
558
|
+
# CRs stripped first: a CRLF checkout of this list must not flag every skill
|
|
559
|
+
tr -d '\r' < "$KNOWN_SKILL_HASHES" | grep -q "^$2 sha256:$(_cc_digest_with "$_sa" "$1" norm)\$"
|
|
560
|
+
}
|
|
561
|
+
STALE_NEW=""
|
|
545
562
|
NEW_MANIFEST=$(mktemp 2>/dev/null || echo ".claude/.skills-manifest.tmp")
|
|
546
563
|
PRESERVED_SKILLS=""
|
|
547
564
|
RETIRED_SKILLS=""
|
|
@@ -565,6 +582,7 @@ for skill_dir in "$SCRIPT_DIR"/templates/.claude/skills/*/; do
|
|
|
565
582
|
rel="$skill_name/$base"
|
|
566
583
|
dst=".claude/skills/$rel"
|
|
567
584
|
tpl_hash=$(_cc_hash "$src")
|
|
585
|
+
kept=false
|
|
568
586
|
|
|
569
587
|
if [ ! -f "$dst" ]; then
|
|
570
588
|
cp "$src" "$dst" # new file — nothing to protect
|
|
@@ -574,17 +592,26 @@ for skill_dir in "$SCRIPT_DIR"/templates/.claude/skills/*/; do
|
|
|
574
592
|
: # already current
|
|
575
593
|
elif _cc_hash_matches "$dst" "$recorded"; then
|
|
576
594
|
cp "$src" "$dst" # pristine older version — safe
|
|
595
|
+
elif _cc_skill_shipped "$dst" "$rel"; then
|
|
596
|
+
cp "$src" "$dst" # a version we shipped, never edited
|
|
577
597
|
elif [ -z "$recorded" ]; then
|
|
578
|
-
# No manifest yet (first run on an existing install) and the file
|
|
579
|
-
#
|
|
580
|
-
# "user edited", so assume the user's work matters.
|
|
598
|
+
# No manifest yet (first run on an existing install), and the file
|
|
599
|
+
# matches no version we ever shipped: someone edited it.
|
|
581
600
|
cp "$src" "$dst.new"
|
|
582
|
-
skill_status="preserved"
|
|
601
|
+
skill_status="preserved"; kept=true
|
|
583
602
|
else
|
|
584
603
|
cp "$src" "$dst.new" # user-modified — keep theirs
|
|
585
|
-
skill_status="preserved"
|
|
604
|
+
skill_status="preserved"; kept=true
|
|
586
605
|
fi
|
|
587
606
|
fi
|
|
607
|
+
# A .new from an earlier run is stale once the file itself is current.
|
|
608
|
+
# Remove it only when it is one of ours: a file the user saved under
|
|
609
|
+
# that name is theirs.
|
|
610
|
+
if [ "$kept" = false ] && [ -f "$dst.new" ] && \
|
|
611
|
+
{ _cc_hash_matches "$dst.new" "$tpl_hash" || _cc_skill_shipped "$dst.new" "$rel"; }; then
|
|
612
|
+
rm -f "$dst.new"
|
|
613
|
+
STALE_NEW="$STALE_NEW $rel.new"
|
|
614
|
+
fi
|
|
588
615
|
echo "$rel $tpl_hash" >> "$NEW_MANIFEST"
|
|
589
616
|
done
|
|
590
617
|
|
|
@@ -652,6 +679,9 @@ if [ -n "$KEPT_RETIRED" ]; then
|
|
|
652
679
|
echo -e " ${YELLOW}Delete by hand once you no longer need them.${NC}"
|
|
653
680
|
fi
|
|
654
681
|
|
|
682
|
+
if [ -n "$STALE_NEW" ]; then
|
|
683
|
+
echo " ✓ removed templates left from earlier upgrades (the skill is current now):$STALE_NEW"
|
|
684
|
+
fi
|
|
655
685
|
if [ -n "$PRESERVED_SKILLS" ]; then
|
|
656
686
|
echo -e " ${YELLOW}Locally modified skills were not overwritten:${PRESERVED_SKILLS}${NC}"
|
|
657
687
|
echo -e " ${YELLOW}Compare with: diff .claude/skills/<name>/SKILL.md{,.new}${NC}"
|
package/lib/skill-hashes
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# sha256 of every version of each framework skill file ever shipped: every
|
|
2
|
+
# version committed to templates/, plus every skill file in every version
|
|
3
|
+
# published to npm (git history does not hold the files 2.2.0-2.10.0 shipped).
|
|
4
|
+
# Up to 2.16.0, CRs stripped before hashing (sed 's/\r$//', as init.sh does).
|
|
5
|
+
# init.sh uses it to tell an older shipped skill from a locally edited one.
|
|
6
|
+
# Without it, an install that predates the skills manifest (before 2.12.2) had
|
|
7
|
+
# every older skill kept as "edited", and because the manifest then records the
|
|
8
|
+
# new template's hash, the misjudgement repeated on every upgrade: 7 installs
|
|
9
|
+
# carried a never-edited 2026-04 /think until 2026-09-28. Includes the retired
|
|
10
|
+
# /finish and /retro. Frozen: do not regenerate. Generated 2026-09-28.
|
|
11
|
+
ask-me/SKILL.md sha256:b8635eec4ff11e7e252feb00845edc58c93b8afaf35b8fcef4066215e7450077
|
|
12
|
+
commit/SKILL.md sha256:908d81cd310a3e67f6dbace6358cb0cd261513650e127ccedc584914deb9aa30
|
|
13
|
+
commit/SKILL.md sha256:d57ca8d8fa5b8bfa9c11e4fa112e96e232dd427137bcac4c6ea1fa9f8ad5e1a0
|
|
14
|
+
commit/SKILL.md sha256:d9fe08f5e76f26942c833d1ce1fe88334035dc2190c75132f0761b618e0a37e1
|
|
15
|
+
commit/SKILL.md sha256:dc9ccfe019d818d3e401b04700224e05b0818a9264ab08353efbf4c4e5146c3f
|
|
16
|
+
coplan/SKILL.md sha256:1186ddc4e188fffeb445c65e8f51fb0f5d0f7ba64292a38febe36905cbd21afa
|
|
17
|
+
coplan/SKILL.md sha256:334b6df4f172a7762fbf276068bdce08b5fe43081bfaf2c48fc02665bb57f9f9
|
|
18
|
+
coplan/SKILL.md sha256:77946c2d14a7ac487cfe748047b7d36db58a0c8eb769a62e2e19bf0b5cfaf2c3
|
|
19
|
+
coplan/SKILL.md sha256:cff387e308819e20b5f54967ff3f912dde65e93e7c28d09571ee8e1ea2cc40de
|
|
20
|
+
evaluate/SKILL.md sha256:1f453d38ca1280074ea6e0461ace61aea40c99fe40e518a9afda07e4d061ab6e
|
|
21
|
+
finish/SKILL.md sha256:1013f03c0e65ce52e7dd5ff0d15eb6bf4fdb093635e00103b63aedfb0db4e84c
|
|
22
|
+
investigate/SKILL.md sha256:7768d38e43f8ca2ce394207b5d0236ecd3ce36e7d0517a545cf7fb130e73a24e
|
|
23
|
+
investigate/SKILL.md sha256:a4e376040c878fd50d4cd24ee20565aac90e1f2b185c80092b6cbac69b86e760
|
|
24
|
+
retro/SKILL.md sha256:87ff53378b2bcbdd023466935856b821c7da9309935c502024cb08f68858caae
|
|
25
|
+
retro/SKILL.md sha256:fea6183280de35424a2f3c4aa21f8b81f108f9ec0ad69b9666e95cce7058be39
|
|
26
|
+
self-check/SKILL.md sha256:34b8847e013d7b64b9de13ccbe850384ea003dfe0ae7188b41efd3e6b99b2061
|
|
27
|
+
self-check/SKILL.md sha256:512e13b28b1f31c7f8e46c10583dafd633ecbdced44187c962625dc6a91135ac
|
|
28
|
+
self-check/SKILL.md sha256:5fa6f562ba74a6f46cbfa7910ecf2351101030900618cdcc58df044260d86b4e
|
|
29
|
+
self-check/SKILL.md sha256:6e8e91889cd7b3753026d8213528712013fd96c6a076453dea51bd4cd4564276
|
|
30
|
+
self-check/SKILL.md sha256:75a915cbaecd98a2befdf3981110bde89fc02e7d82d34f22c2cb92470aa07f34
|
|
31
|
+
self-check/SKILL.md sha256:8f0903c3bb68529b07d61c0ccb7471b760a6fa09cb7fe2ca77b99671b7273380
|
|
32
|
+
self-check/SKILL.md sha256:9dbfbb4112459fcbde0aae1cc016f24b6c66bfa770f1e5399cc703bc3c070ae9
|
|
33
|
+
self-check/SKILL.md sha256:c83e23a5abad31367d8b2d19200686e4140ef1ee94a55bd366141a0152588407
|
|
34
|
+
self-check/SKILL.md sha256:c99ebd040235efc435ae45e835badbd061524d61a0303ba8577ac6ddf67a53f3
|
|
35
|
+
self-check/SKILL.md sha256:d31b2a40d45759b882611dd6768e8d176e8c630863444602a27d500a9bf2f5df
|
|
36
|
+
summary/SKILL.md sha256:a3ac35c409cd3bff3286e365bb6bc973f9703c0312f49c22c5bc273c0f2bab4c
|
|
37
|
+
summary/SKILL.md sha256:ccf598d2f3c777894bd674a74791e5d2b50de6d017fe555a2d63e7016432210a
|
|
38
|
+
think/SKILL.md sha256:29597a4e7151f9ea9f6990988e05e44172620c2aea9708d91ec039ac85f92fb4
|
|
39
|
+
think/SKILL.md sha256:3d91e093d2de30d4c98196f14c1d653297ebd51958ec1e6fc791959ee5390619
|
|
40
|
+
think/SKILL.md sha256:6acca4f5055c3c7556ffb30c29558eb24aa509473bcd12ad0960f6c7c29a8600
|
|
41
|
+
think/SKILL.md sha256:7f7738d61a207b89399c45730d9a7f9f93e3cf0213866292affbe5127b026e15
|
|
42
|
+
think/SKILL.md sha256:92a82a23d247e9681715b151d0bef4786524c64a625e9aa8775e2256d9f673a7
|
|
43
|
+
think/SKILL.md sha256:9686da003338b2181bd63143acc9c4fdf7652f0197e04ae4aff510c4c54eb36c
|
|
44
|
+
think/SKILL.md sha256:b63832f82415aa4a56a3e9a2d35489861ba5317705f8ce52bc2e41ee9cee3b8f
|
|
45
|
+
think/SKILL.md sha256:ec136443d668e47ce15484643192c1f9e7865b31d1c0c91d24e99b40117b0107
|
package/package.json
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ask-me
|
|
3
|
+
description: Put a decision to the user so they can answer in one step — a few lines of background, then a single- or multi-select question with the recommended option first.
|
|
4
|
+
when_to_use: When the user types /ask-me or says "带着背景和选项问我" / "带着选项问我" / "ask me with options". On your own, only when you are blocked on something that is the user's call (scope, approach, a trade-off, anything irreversible or outward-facing) or on intent or environment that no file or command can tell you. Not for what the code, the docs or a conventional default settles.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Ask the user a question they can answer in one step.
|
|
8
|
+
|
|
9
|
+
This replaces two failures. One is a wall of text with the real question buried at the end. The other is a bare open question the user cannot answer, because the context needed to answer it is in your head, not theirs.
|
|
10
|
+
|
|
11
|
+
## 1. Decide what actually needs asking
|
|
12
|
+
|
|
13
|
+
- **Topic.** If the user gave arguments, that is the topic. Otherwise it is whatever decision is pending in the conversation: the thing you would otherwise ask in prose, or quietly guess.
|
|
14
|
+
- **Settle what you can first.** Read the file, run the command, check `docs/progress.md` and `docs/todo.md`. Ask only what is left, which should be the user's preferences and direction, or facts only they know. A question whose answer is in the repo wastes the user's turn.
|
|
15
|
+
- **Nothing pending?** If nothing is actually open, say so in one line and stop. Do not invent a question so that the skill has something to do.
|
|
16
|
+
|
|
17
|
+
## 2. Background first, in plain text, briefly
|
|
18
|
+
|
|
19
|
+
Write three to six lines before the question, covering only what the user needs in order to choose:
|
|
20
|
+
|
|
21
|
+
- what is already settled;
|
|
22
|
+
- where things are stuck, and why it is the user's call: a trade-off, a preference, a risk;
|
|
23
|
+
- anything you checked that changes the options, with `file:line` when it helps.
|
|
24
|
+
|
|
25
|
+
Save the analysis of each option for that option's description. If the background runs past about six lines, you are explaining too much or asking too early.
|
|
26
|
+
|
|
27
|
+
## 3. Ask with AskUserQuestion
|
|
28
|
+
|
|
29
|
+
- **Questions.** Ask one to four per call, and only ones whose answer changes what you do next. Put related questions in the same call rather than drip-feeding them. Write them in the user's language.
|
|
30
|
+
- **Options.**
|
|
31
|
+
- Give two to four per question, and make them genuinely different.
|
|
32
|
+
- Do not add an "Other" option; the tool provides one.
|
|
33
|
+
- Put your recommendation first and mark it in the user's language, "(推荐)" or "(Recommended)". Its description says why in one sentence.
|
|
34
|
+
- If you have no basis for recommending one, say that in the background rather than marking one at random.
|
|
35
|
+
- **Descriptions.** Each option's description says what happens if it is chosen and what that costs. Do not restate the label.
|
|
36
|
+
- **Header.** At most 12 characters.
|
|
37
|
+
- **multiSelect.** Use it only when the choices combine, for example which items to include. An empty multi-select answer is ambiguous: ask again rather than assume.
|
|
38
|
+
- **preview.** Use it when the user needs to compare concrete artifacts: code, configuration, layouts. It works for single-select questions only.
|
|
39
|
+
|
|
40
|
+
## 4. After the answer
|
|
41
|
+
|
|
42
|
+
- **Act on what was answered, and only that.** An answer to "which approach" chooses the approach. It is not approval for irreversible or outward-facing steps, such as publishing, pushing or deleting; those still get their own confirmation.
|
|
43
|
+
- **"Other" with free text.** Treat it as the user's own words. If it changes the premise, re-plan instead of squeezing it into one of your options.
|
|
44
|
+
- **Question rejected or interrupted.** Stop and wait: the user is about to tell you something. Do not re-ask the same questions. When they reply, work out which of your assumptions their correction overturns.
|
|
45
|
+
|
|
46
|
+
## When the tool is unavailable
|
|
47
|
+
|
|
48
|
+
Some contexts block the question tool: `/self-check` lists it under `disallowed-tools`, and non-interactive runs have no UI. Fall back to text:
|
|
49
|
+
|
|
50
|
+
1. Give the same background.
|
|
51
|
+
2. Number the questions and letter the options, recommendation first and marked, so the user can reply "1A 2B".
|
|
52
|
+
|
|
53
|
+
Keep it as short as the tool version would be.
|
|
@@ -28,15 +28,14 @@ State your assessment: "This looks [small/medium/large] because [reason]."
|
|
|
28
28
|
|
|
29
29
|
## Step 2: Understand
|
|
30
30
|
|
|
31
|
-
Ask
|
|
31
|
+
Ask only what Step 0 could not settle. After the research, what is left should be preference and direction, not facts you could have read. A question asked before looking is one the user should never have had to answer. Focus on:
|
|
32
32
|
- What exactly should change? (scope)
|
|
33
33
|
- What should NOT change? (boundaries)
|
|
34
34
|
- How will we know it's done? (success criteria)
|
|
35
35
|
|
|
36
36
|
Rules:
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- Reference what you learned in Step 0 — ask about gaps in your understanding, not things you can read yourself
|
|
37
|
+
- Ask them the `/ask-me` way: a few lines of background from Step 0, then the question tool, with your recommendation first
|
|
38
|
+
- As many questions as the task needs, up to four per call, all at once rather than drip-fed
|
|
40
39
|
- If the task is already crystal clear from Step 0, say so and skip to Step 3
|
|
41
40
|
|
|
42
41
|
## Step 3: Propose
|
|
@@ -91,6 +90,8 @@ If self-review reveals issues, revise your proposals before presenting. Don't sh
|
|
|
91
90
|
|
|
92
91
|
**Stop here. Do not proceed until the user picks an approach or gives a green light.**
|
|
93
92
|
|
|
93
|
+
Ask for the pick the `/ask-me` way: one question, the approaches from Step 3 as its options, your recommendation first. The write-up from Step 3 is the background. If `/coplan` is stacked, it writes the plan and offers the review first, and the pick comes after.
|
|
94
|
+
|
|
94
95
|
Do not:
|
|
95
96
|
- Start coding "while waiting"
|
|
96
97
|
- Create files or scaffolding — **except** writing the plan itself to disk, which is not implementation. `/coplan` does exactly that and is designed to stack here.
|