elliot-stack 1.0.0 → 1.0.6

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/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # elliot-stack
2
+
3
+ [![npm version](https://img.shields.io/npm/v/elliot-stack)](https://www.npmjs.com/package/elliot-stack)
4
+ [![license](https://img.shields.io/npm/l/elliot-stack)](LICENSE)
5
+
6
+ A curated set of Claude Code skills by Elliot Drel. One command installs them all.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npx elliot-stack@latest
12
+ ```
13
+
14
+ This copies skills to `~/.claude/skills/` and registers a `SessionStart` hook so your skills stay up to date automatically.
15
+
16
+ ## Skills
17
+
18
+ | Skill | Command | Description |
19
+ |-------|---------|-------------|
20
+ | **Better Title** | `/estack:better-title` | Renames Claude Code chat sessions with descriptive titles |
21
+ | **Chris Voss** | `/estack:chris-voss` | Applies negotiation principles from *Never Split the Difference* |
22
+ | **GitHub Issue Tracker** | `/estack:github-issue-tracker` | Tracks and manages GitHub issues across repos |
23
+ | **Repo Search** | `/estack:repo-search` | Clones and searches external GitHub repos to answer questions about their code |
24
+
25
+ ## How it works
26
+
27
+ - Skills install to `~/.claude/skills/estack/`
28
+ - A `SessionStart` hook auto-updates skills each time you open Claude Code
29
+ - If you've made local edits to a skill, the installer detects the conflict and lets you choose: overwrite, skip, or merge
30
+
31
+ ## Updating
32
+
33
+ Skills update automatically on session start. To force an update manually:
34
+
35
+ ```bash
36
+ npx elliot-stack@latest
37
+ ```
38
+
39
+ ## Requirements
40
+
41
+ - [Claude Code](https://claude.ai/code) CLI installed
42
+ - Node.js 18+
43
+
44
+ ## License
45
+
46
+ MIT
package/bin/install.cjs CHANGED
@@ -350,7 +350,7 @@ async function main() {
350
350
  for (const name of skillNames) {
351
351
  if (modifiedSkills.includes(name)) {
352
352
  if (modifiedAction === 'skip') {
353
- console.log(' Skipped estack:' + name + ' (local modifications preserved)');
353
+ console.log(' Skipped estack-' + name + ' (local modifications preserved)');
354
354
  const currentHash = computeSkillHash(path.join(SKILLS_DIR, name));
355
355
  if (currentHash) newChecksums[name] = currentHash;
356
356
  continue;
@@ -358,7 +358,7 @@ async function main() {
358
358
  if (modifiedAction === 'merge') {
359
359
  backupSkill(name);
360
360
  mergedSkills.push(name);
361
- console.log(' Backed up estack:' + name + ' → ~/.claude/.estack-backup/' + name);
361
+ console.log(' Backed up estack-' + name + ' → ~/.claude/.estack-backup/' + name);
362
362
  }
363
363
  // overwrite or merge — fall through to install
364
364
  } else if (!needsUpdate.includes(name) && fs.existsSync(path.join(SKILLS_DIR, name))) {
@@ -368,7 +368,7 @@ async function main() {
368
368
  copyDir(path.join(PACKAGE_SKILLS_DIR, name), path.join(SKILLS_DIR, name));
369
369
  newChecksums[name] = packageHashes[name];
370
370
  installedCount++;
371
- console.log(' Installed estack:' + name);
371
+ console.log(' Installed estack-' + name);
372
372
  }
373
373
 
374
374
  // 9. Write checksums
@@ -384,7 +384,7 @@ async function main() {
384
384
 
385
385
  for (const name of skillNames) {
386
386
  const desc = getSkillDescription(path.join(PACKAGE_SKILLS_DIR, name));
387
- console.log(' /estack:' + name + (desc ? ' — ' + desc : ''));
387
+ console.log(' /estack-' + name + (desc ? ' — ' + desc : ''));
388
388
  }
389
389
 
390
390
  if (mergedSkills.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elliot-stack",
3
- "version": "1.0.0",
3
+ "version": "1.0.6",
4
4
  "description": "Elliot's skill stack for Claude Code — install via npx elliot-stack@latest",
5
5
  "bin": {
6
6
  "elliot-stack": "bin/install.cjs"
@@ -1,45 +1,45 @@
1
- ---
2
- name: estack:better-title
3
- description: Suggest better chat session titles and rename the session
4
- disable-model-invocation: true
5
- allowed-tools: Bash, AskUserQuestion
6
- ---
7
-
8
- # Better Title
9
-
10
- The current session ID is: ${CLAUDE_SESSION_ID}
11
-
12
- ## Your task
13
-
14
- Suggest **3 descriptive titles** for this chat session based on the conversation so far. The goal is to make sessions easy to find later. Good titles:
15
- - Summarize **what was accomplished** in the chat, not just the topic
16
- - List key actions/outcomes separated by dashes, commas, or similar (e.g. "Reverse-Engineering /rename, PR #33165 Comment, and Building /better-title Skill")
17
- - Are detailed enough that someone skimming a session list can tell exactly what happened
18
- - Typically 8-20 words — longer is fine if it adds useful detail
19
-
20
- ## Format
21
-
22
- Present the 3 options using `AskUserQuestion` with a single-select question (`multiSelect: false`):
23
- - Each option's `label` is the full title text
24
- - Each option's `description` is a brief rationale for why it's a good title
25
- - The user can also select "Other" (provided automatically) to give feedback
26
-
27
- ## Interaction loop
28
-
29
- - If the user selects one of the 3 titles, use that title.
30
- - If the user selects "Other" and provides feedback (e.g. "shorter", "more specific", "mention X"), generate 3 new suggestions incorporating their feedback and present again via `AskUserQuestion`.
31
- - Keep iterating until the user selects a title or gives you an exact title.
32
-
33
- ## Renaming
34
-
35
- Once the user has chosen a title, run the rename script using a quoted heredoc to pass the title safely:
36
-
37
- ```bash
38
- bash "${CLAUDE_SKILL_DIR}/scripts/rename.sh" "${CLAUDE_SESSION_ID}" <<'__CLAUDE_TITLE__'
39
- <chosen title>
40
- __CLAUDE_TITLE__
41
- ```
42
-
43
- Replace `<chosen title>` with the actual chosen title. The quoted heredoc (`<<'__CLAUDE_TITLE__'`) prevents the shell from interpreting any special characters in the title — quotes, apostrophes, dollar signs, backticks, etc. are all passed through literally. After running, confirm the rename succeeded.
44
-
45
- **Important:** The live UI border won't update until the next session resume — the persisted title will show in the session list and on next `/resume`.
1
+ ---
2
+ name: better-title
3
+ description: Suggest better chat session titles and rename the session
4
+ disable-model-invocation: true
5
+ allowed-tools: Bash, AskUserQuestion
6
+ ---
7
+
8
+ # Better Title
9
+
10
+ The current session ID is: ${CLAUDE_SESSION_ID}
11
+
12
+ ## Your task
13
+
14
+ Suggest **3 descriptive titles** for this chat session based on the conversation so far. The goal is to make sessions easy to find later. Good titles:
15
+ - Summarize **what was accomplished** in the chat, not just the topic
16
+ - List key actions/outcomes separated by dashes, commas, or similar (e.g. "Reverse-Engineering /rename, PR #33165 Comment, and Building /better-title Skill")
17
+ - Are detailed enough that someone skimming a session list can tell exactly what happened
18
+ - Typically 8-20 words — longer is fine if it adds useful detail
19
+
20
+ ## Format
21
+
22
+ Present the 3 options using `AskUserQuestion` with a single-select question (`multiSelect: false`):
23
+ - Each option's `label` is the full title text
24
+ - Each option's `description` is a brief rationale for why it's a good title
25
+ - The user can also select "Other" (provided automatically) to give feedback
26
+
27
+ ## Interaction loop
28
+
29
+ - If the user selects one of the 3 titles, use that title.
30
+ - If the user selects "Other" and provides feedback (e.g. "shorter", "more specific", "mention X"), generate 3 new suggestions incorporating their feedback and present again via `AskUserQuestion`.
31
+ - Keep iterating until the user selects a title or gives you an exact title.
32
+
33
+ ## Renaming
34
+
35
+ Once the user has chosen a title, run the rename script using a quoted heredoc to pass the title safely:
36
+
37
+ ```bash
38
+ bash "${CLAUDE_SKILL_DIR}/scripts/rename.sh" "${CLAUDE_SESSION_ID}" <<'__CLAUDE_TITLE__'
39
+ <chosen title>
40
+ __CLAUDE_TITLE__
41
+ ```
42
+
43
+ Replace `<chosen title>` with the actual chosen title. The quoted heredoc (`<<'__CLAUDE_TITLE__'`) prevents the shell from interpreting any special characters in the title — quotes, apostrophes, dollar signs, backticks, etc. are all passed through literally. After running, confirm the rename succeeded.
44
+
45
+ **Important:** The live UI border won't update until the next session resume — the persisted title will show in the session list and on next `/resume`.
@@ -1,55 +1,55 @@
1
- #!/usr/bin/env bash
2
- # Renames a Claude Code session by appending title entries (append-only, never rewrites)
3
- # Usage: rename.sh <session-id> <title>
4
- # or: pass the title on stdin to rename.sh <session-id>
5
-
6
- set -euo pipefail
7
-
8
- SESSION_ID="${1-}"
9
- TITLE="${2-}"
10
-
11
- # If no title argument, read from stdin (supports heredoc input)
12
- if [[ -z "$TITLE" ]]; then
13
- TITLE="$(cat)"
14
- fi
15
-
16
- if [[ -z "$SESSION_ID" || -z "$TITLE" ]]; then
17
- echo "Error: Usage: rename.sh <session-id> <title>" >&2
18
- echo " or: pass the title on stdin to rename.sh <session-id>" >&2
19
- exit 1
20
- fi
21
-
22
- # Reject multiline titles (JSONL entries must be single lines)
23
- if [[ "$TITLE" == *$'\n'* || "$TITLE" == *$'\r'* ]]; then
24
- echo "Error: title must be a single line" >&2
25
- exit 1
26
- fi
27
-
28
- # Use Node's JSON.stringify for safe escaping of all special characters
29
- TITLE_JSON="$(node -e 'process.stdout.write(JSON.stringify(process.argv[1]))' "$TITLE")"
30
-
31
- # Find the session JSONL file
32
- SESSION_FILE=$(find "$HOME/.claude/projects/" -maxdepth 2 -name "${SESSION_ID}.jsonl" -type f 2>/dev/null | head -1)
33
-
34
- if [[ -z "$SESSION_FILE" ]]; then
35
- echo "Error: Could not find session file for ${SESSION_ID}" >&2
36
- exit 1
37
- fi
38
-
39
- # Build the exact lines we intend to append
40
- CUSTOM_LINE="$(printf '{"type":"custom-title","customTitle":%s,"sessionId":"%s"}' "$TITLE_JSON" "$SESSION_ID")"
41
- AGENT_LINE="$(printf '{"type":"agent-name","agentName":%s,"sessionId":"%s"}' "$TITLE_JSON" "$SESSION_ID")"
42
-
43
- # Check if both last entries already match (idempotent — skip if already current)
44
- LAST_CUSTOM="$(grep '^{"type":"custom-title"' "$SESSION_FILE" | tail -n 1 || true)"
45
- LAST_AGENT="$(grep '^{"type":"agent-name"' "$SESSION_FILE" | tail -n 1 || true)"
46
-
47
- if [[ "$LAST_CUSTOM" == "$CUSTOM_LINE" && "$LAST_AGENT" == "$AGENT_LINE" ]]; then
48
- echo "Session already named: ${TITLE}"
49
- exit 0
50
- fi
51
-
52
- # Append-only: never rewrite the file, just add new entries at the end
53
- printf '%s\n%s\n' "$CUSTOM_LINE" "$AGENT_LINE" >> "$SESSION_FILE"
54
-
55
- echo "Renamed session to: ${TITLE}"
1
+ #!/usr/bin/env bash
2
+ # Renames a Claude Code session by appending title entries (append-only, never rewrites)
3
+ # Usage: rename.sh <session-id> <title>
4
+ # or: pass the title on stdin to rename.sh <session-id>
5
+
6
+ set -euo pipefail
7
+
8
+ SESSION_ID="${1-}"
9
+ TITLE="${2-}"
10
+
11
+ # If no title argument, read from stdin (supports heredoc input)
12
+ if [[ -z "$TITLE" ]]; then
13
+ TITLE="$(cat)"
14
+ fi
15
+
16
+ if [[ -z "$SESSION_ID" || -z "$TITLE" ]]; then
17
+ echo "Error: Usage: rename.sh <session-id> <title>" >&2
18
+ echo " or: pass the title on stdin to rename.sh <session-id>" >&2
19
+ exit 1
20
+ fi
21
+
22
+ # Reject multiline titles (JSONL entries must be single lines)
23
+ if [[ "$TITLE" == *$'\n'* || "$TITLE" == *$'\r'* ]]; then
24
+ echo "Error: title must be a single line" >&2
25
+ exit 1
26
+ fi
27
+
28
+ # Use Node's JSON.stringify for safe escaping of all special characters
29
+ TITLE_JSON="$(node -e 'process.stdout.write(JSON.stringify(process.argv[1]))' "$TITLE")"
30
+
31
+ # Find the session JSONL file
32
+ SESSION_FILE=$(find "$HOME/.claude/projects/" -maxdepth 2 -name "${SESSION_ID}.jsonl" -type f 2>/dev/null | head -1)
33
+
34
+ if [[ -z "$SESSION_FILE" ]]; then
35
+ echo "Error: Could not find session file for ${SESSION_ID}" >&2
36
+ exit 1
37
+ fi
38
+
39
+ # Build the exact lines we intend to append
40
+ CUSTOM_LINE="$(printf '{"type":"custom-title","customTitle":%s,"sessionId":"%s"}' "$TITLE_JSON" "$SESSION_ID")"
41
+ AGENT_LINE="$(printf '{"type":"agent-name","agentName":%s,"sessionId":"%s"}' "$TITLE_JSON" "$SESSION_ID")"
42
+
43
+ # Check if both last entries already match (idempotent — skip if already current)
44
+ LAST_CUSTOM="$(grep '^{"type":"custom-title"' "$SESSION_FILE" | tail -n 1 || true)"
45
+ LAST_AGENT="$(grep '^{"type":"agent-name"' "$SESSION_FILE" | tail -n 1 || true)"
46
+
47
+ if [[ "$LAST_CUSTOM" == "$CUSTOM_LINE" && "$LAST_AGENT" == "$AGENT_LINE" ]]; then
48
+ echo "Session already named: ${TITLE}"
49
+ exit 0
50
+ fi
51
+
52
+ # Append-only: never rewrite the file, just add new entries at the end
53
+ printf '%s\n%s\n' "$CUSTOM_LINE" "$AGENT_LINE" >> "$SESSION_FILE"
54
+
55
+ echo "Renamed session to: ${TITLE}"
@@ -1,78 +1,78 @@
1
- ---
2
- name: estack:chris-voss
3
- description: >
4
- Applies Chris Voss negotiation principles from *Never Split the Difference* to any situation
5
- where understanding human psychology, persuasion, or influence would improve the output. Use
6
- when the user is navigating a situation involving another person, drafting communication that
7
- needs to land a certain way, or asking for advice on how to approach a difficult conversation —
8
- even if they don't explicitly ask for negotiation help. Do not use for coding, math, or factual
9
- lookups.
10
- ---
11
-
12
- # Chris Voss Negotiation Skill
13
-
14
- You have deep, internalized knowledge of *Never Split the Difference* by Chris Voss. Your job is
15
- to naturally inject his principles into whatever the user is working on — making the output more
16
- persuasive, emotionally intelligent, and strategically sound — even when they didn't ask for it.
17
-
18
- This skill applies any time the quality of the answer depends on understanding how people receive
19
- information, make decisions, or get moved to act. That includes live interpersonal situations
20
- (conversations, negotiations, conflict) but also any output with an implicit audience: a pitch
21
- deck, a pricing structure, a proposal, a cold message, an argument. Voss's principles — loss
22
- aversion, emotional anchoring, labeling, calibrated framing, tactical empathy — apply whenever
23
- a human will eventually be on the receiving end of what's being built.
24
-
25
- Think of yourself as a negotiation consultant sitting beside the user. Read the situation,
26
- identify where Voss's lens adds value, and apply the right tools without making it a lecture.
27
-
28
- ---
29
-
30
- ## How to Apply This Skill
31
-
32
- Read the user's situation, then draw from the principles below to improve, rewrite, or advise.
33
- You don't need to label every technique you're using — just use them. If it helps the user to
34
- understand *why* something works, briefly explain it, but don't turn every response into a lecture.
35
-
36
- **Prioritize:**
37
- - Giving the user exact words or a rewritten draft when they need one
38
- - Identifying the emotional or psychological dynamics at play — in the room or in the reader
39
- - Pointing out where the user might be giving away power or framing things suboptimally
40
- - Preempting objections and resistance before they arise
41
-
42
- ---
43
-
44
- ## Core Principles Reference
45
-
46
- Read `references/voss-principles.md` for the full structured knowledge base, and
47
- `references/elliot-notes.md` for additional personal highlights and edge cases. Below is a
48
- quick index of when to reach for each tool:
49
-
50
- | Situation | Primary Tools |
51
- |---|---|
52
- | Need a reply to a silent email/text | "Have you given up on X?" framing, No-oriented question |
53
- | Writing a persuasive ask/request | Accusation audit, lead with value, FOMO framing |
54
- | Pitching an idea, product, or company | Loss aversion framing, emotional anchoring, accusation audit |
55
- | Structuring pricing or an offer | Precise numbers, Ackerman logic, nonmonetary add-on |
56
- | Anticipating pushback or rejection | Label negatives upfront, accusation audit |
57
- | Tense conversation / conflict | Labeling, mirroring, downward voice tone |
58
- | Someone not engaged / shutting down | Mirroring, calibrated questions, "That's right" pursuit |
59
- | Trying to build trust quickly | Similarity principle, tactical empathy, acknowledge the negative |
60
- | Getting someone to commit (not just agree) | Rule of 3, "how/what" implementation questions |
61
- | Someone being unreasonable | Look for black swans — there's something you don't know yet |
62
- | Deadline pressure | Reframe: deadlines are often self-imposed and flexible |
63
- | Positioning or messaging for an audience | Emotional framing, loss aversion, accusation audit |
64
-
65
- ---
66
-
67
- ## Output Style
68
-
69
- - **For messages/emails/outreach**: Rewrite or draft directly, applying Voss principles implicitly.
70
- - **For pitches, decks, proposals**: Shape framing, ordering, and language around how the audience
71
- will emotionally receive it — not just what's logically true.
72
- - **For live situations/conversations**: Diagnose the emotional dynamics, give exact language, flag
73
- power the user is giving away.
74
- - **For strategy questions**: Be direct and tactical. Think out loud like a negotiation coach who's
75
- seen this before.
76
-
77
- Use calm, confident language. If the situation is high-stakes, slow down and be precise. Never
78
- rush the user into a compromise — no deal is better than a bad deal.
1
+ ---
2
+ name: chris-voss
3
+ description: >
4
+ Applies Chris Voss negotiation principles from *Never Split the Difference* to any situation
5
+ where understanding human psychology, persuasion, or influence would improve the output. Use
6
+ when the user is navigating a situation involving another person, drafting communication that
7
+ needs to land a certain way, or asking for advice on how to approach a difficult conversation —
8
+ even if they don't explicitly ask for negotiation help. Do not use for coding, math, or factual
9
+ lookups.
10
+ ---
11
+
12
+ # Chris Voss Negotiation Skill
13
+
14
+ You have deep, internalized knowledge of *Never Split the Difference* by Chris Voss. Your job is
15
+ to naturally inject his principles into whatever the user is working on — making the output more
16
+ persuasive, emotionally intelligent, and strategically sound — even when they didn't ask for it.
17
+
18
+ This skill applies any time the quality of the answer depends on understanding how people receive
19
+ information, make decisions, or get moved to act. That includes live interpersonal situations
20
+ (conversations, negotiations, conflict) but also any output with an implicit audience: a pitch
21
+ deck, a pricing structure, a proposal, a cold message, an argument. Voss's principles — loss
22
+ aversion, emotional anchoring, labeling, calibrated framing, tactical empathy — apply whenever
23
+ a human will eventually be on the receiving end of what's being built.
24
+
25
+ Think of yourself as a negotiation consultant sitting beside the user. Read the situation,
26
+ identify where Voss's lens adds value, and apply the right tools without making it a lecture.
27
+
28
+ ---
29
+
30
+ ## How to Apply This Skill
31
+
32
+ Read the user's situation, then draw from the principles below to improve, rewrite, or advise.
33
+ You don't need to label every technique you're using — just use them. If it helps the user to
34
+ understand *why* something works, briefly explain it, but don't turn every response into a lecture.
35
+
36
+ **Prioritize:**
37
+ - Giving the user exact words or a rewritten draft when they need one
38
+ - Identifying the emotional or psychological dynamics at play — in the room or in the reader
39
+ - Pointing out where the user might be giving away power or framing things suboptimally
40
+ - Preempting objections and resistance before they arise
41
+
42
+ ---
43
+
44
+ ## Core Principles Reference
45
+
46
+ Read `references/voss-principles.md` for the full structured knowledge base, and
47
+ `references/elliot-notes.md` for additional personal highlights and edge cases. Below is a
48
+ quick index of when to reach for each tool:
49
+
50
+ | Situation | Primary Tools |
51
+ |---|---|
52
+ | Need a reply to a silent email/text | "Have you given up on X?" framing, No-oriented question |
53
+ | Writing a persuasive ask/request | Accusation audit, lead with value, FOMO framing |
54
+ | Pitching an idea, product, or company | Loss aversion framing, emotional anchoring, accusation audit |
55
+ | Structuring pricing or an offer | Precise numbers, Ackerman logic, nonmonetary add-on |
56
+ | Anticipating pushback or rejection | Label negatives upfront, accusation audit |
57
+ | Tense conversation / conflict | Labeling, mirroring, downward voice tone |
58
+ | Someone not engaged / shutting down | Mirroring, calibrated questions, "That's right" pursuit |
59
+ | Trying to build trust quickly | Similarity principle, tactical empathy, acknowledge the negative |
60
+ | Getting someone to commit (not just agree) | Rule of 3, "how/what" implementation questions |
61
+ | Someone being unreasonable | Look for black swans — there's something you don't know yet |
62
+ | Deadline pressure | Reframe: deadlines are often self-imposed and flexible |
63
+ | Positioning or messaging for an audience | Emotional framing, loss aversion, accusation audit |
64
+
65
+ ---
66
+
67
+ ## Output Style
68
+
69
+ - **For messages/emails/outreach**: Rewrite or draft directly, applying Voss principles implicitly.
70
+ - **For pitches, decks, proposals**: Shape framing, ordering, and language around how the audience
71
+ will emotionally receive it — not just what's logically true.
72
+ - **For live situations/conversations**: Diagnose the emotional dynamics, give exact language, flag
73
+ power the user is giving away.
74
+ - **For strategy questions**: Be direct and tactical. Think out loud like a negotiation coach who's
75
+ seen this before.
76
+
77
+ Use calm, confident language. If the situation is high-stakes, slow down and be precise. Never
78
+ rush the user into a compromise — no deal is better than a bad deal.