@claudemini/shit-cli 1.4.0 → 1.5.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/README.md +126 -117
- package/lib/checkpoint.js +39 -32
- package/lib/checkpoints.js +3 -15
- package/lib/commit.js +7 -15
- package/lib/config.js +3 -1
- package/lib/disable.js +54 -18
- package/lib/doctor.js +17 -24
- package/lib/enable.js +24 -13
- package/lib/explain.js +43 -38
- package/lib/reset.js +8 -16
- package/lib/resume.js +32 -27
- package/lib/rewind.js +63 -38
- package/lib/session.js +6 -0
- package/lib/status.js +44 -19
- package/lib/summarize.js +2 -13
- package/package.json +21 -4
- package/.claude/settings.json +0 -81
- package/.claude/settings.local.json +0 -20
- package/COMPARISON.md +0 -92
- package/DESIGN_PHILOSOPHY.md +0 -138
- package/QUICKSTART.md +0 -109
package/lib/status.js
CHANGED
|
@@ -5,20 +5,10 @@
|
|
|
5
5
|
* Similar to 'entire status' - displays active session info
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { existsSync, readFileSync } from 'fs';
|
|
8
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
9
9
|
import { join } from 'path';
|
|
10
10
|
import { execSync } from 'child_process';
|
|
11
|
-
|
|
12
|
-
function findProjectRoot() {
|
|
13
|
-
let dir = process.cwd();
|
|
14
|
-
while (dir !== '/') {
|
|
15
|
-
if (existsSync(join(dir, '.git'))) {
|
|
16
|
-
return dir;
|
|
17
|
-
}
|
|
18
|
-
dir = join(dir, '..');
|
|
19
|
-
}
|
|
20
|
-
throw new Error('Not in a git repository');
|
|
21
|
-
}
|
|
11
|
+
import { getProjectRoot, SESSION_ID_REGEX } from './config.js';
|
|
22
12
|
|
|
23
13
|
function getCurrentSession(projectRoot) {
|
|
24
14
|
const shitLogsDir = join(projectRoot, '.shit-logs');
|
|
@@ -27,9 +17,11 @@ function getCurrentSession(projectRoot) {
|
|
|
27
17
|
}
|
|
28
18
|
|
|
29
19
|
// Find the most recent session directory
|
|
30
|
-
const { readdirSync, statSync } = await import('fs');
|
|
31
20
|
const sessions = readdirSync(shitLogsDir)
|
|
32
|
-
.filter(name =>
|
|
21
|
+
.filter(name => {
|
|
22
|
+
const fullPath = join(shitLogsDir, name);
|
|
23
|
+
return SESSION_ID_REGEX.test(name) && statSync(fullPath).isDirectory();
|
|
24
|
+
})
|
|
33
25
|
.map(name => ({
|
|
34
26
|
name,
|
|
35
27
|
path: join(shitLogsDir, name),
|
|
@@ -90,11 +82,45 @@ function formatDuration(startTime) {
|
|
|
90
82
|
}
|
|
91
83
|
}
|
|
92
84
|
|
|
85
|
+
function getTouchedFileCount(state) {
|
|
86
|
+
const ops = state?.file_ops;
|
|
87
|
+
if (!ops || typeof ops !== 'object') {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const touched = new Set([
|
|
92
|
+
...(Array.isArray(ops.write) ? ops.write : []),
|
|
93
|
+
...(Array.isArray(ops.edit) ? ops.edit : []),
|
|
94
|
+
...(Array.isArray(ops.read) ? ops.read : []),
|
|
95
|
+
].filter(Boolean));
|
|
96
|
+
|
|
97
|
+
return touched.size;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function hasShitHooks(settings) {
|
|
101
|
+
if (!settings?.hooks || typeof settings.hooks !== 'object') {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return Object.values(settings.hooks).some(value => {
|
|
106
|
+
if (typeof value === 'string') {
|
|
107
|
+
return value.includes('shit log');
|
|
108
|
+
}
|
|
109
|
+
if (!Array.isArray(value)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return value.some(entry =>
|
|
113
|
+
Array.isArray(entry?.hooks) &&
|
|
114
|
+
entry.hooks.some(hook => typeof hook?.command === 'string' && hook.command.includes('shit log'))
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
93
119
|
export default async function status(args) {
|
|
94
120
|
try {
|
|
95
|
-
const projectRoot =
|
|
121
|
+
const projectRoot = getProjectRoot();
|
|
96
122
|
const gitInfo = getGitInfo(projectRoot);
|
|
97
|
-
const currentSession =
|
|
123
|
+
const currentSession = getCurrentSession(projectRoot);
|
|
98
124
|
|
|
99
125
|
console.log('📊 shit-cli Status\n');
|
|
100
126
|
|
|
@@ -121,7 +147,7 @@ export default async function status(args) {
|
|
|
121
147
|
console.log(` Started: ${new Date(state.start_time).toLocaleString()}`);
|
|
122
148
|
console.log(` Duration: ${formatDuration(state.start_time)}`);
|
|
123
149
|
console.log(` Events: ${state.event_count || 0}`);
|
|
124
|
-
console.log(` Files: ${
|
|
150
|
+
console.log(` Files: ${getTouchedFileCount(state)}`);
|
|
125
151
|
|
|
126
152
|
if (state.shadow_branch) {
|
|
127
153
|
console.log(` Shadow: ${state.shadow_branch}`);
|
|
@@ -149,8 +175,7 @@ export default async function status(args) {
|
|
|
149
175
|
if (existsSync(claudeSettings)) {
|
|
150
176
|
try {
|
|
151
177
|
const settings = JSON.parse(readFileSync(claudeSettings, 'utf-8'));
|
|
152
|
-
const hasHooks = settings
|
|
153
|
-
(settings.hooks.session_start || settings.hooks.session_end);
|
|
178
|
+
const hasHooks = hasShitHooks(settings);
|
|
154
179
|
|
|
155
180
|
console.log();
|
|
156
181
|
if (hasHooks) {
|
package/lib/summarize.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
|
-
import {
|
|
11
|
+
import { getProjectRoot } from './config.js';
|
|
12
12
|
|
|
13
13
|
// Default configuration
|
|
14
14
|
const DEFAULT_CONFIG = {
|
|
@@ -294,7 +294,7 @@ export async function summarizeSession(projectRoot, sessionId, sessionDir) {
|
|
|
294
294
|
* CLI command for manual summarization
|
|
295
295
|
*/
|
|
296
296
|
export default async function summarize(args) {
|
|
297
|
-
const projectRoot =
|
|
297
|
+
const projectRoot = getProjectRoot();
|
|
298
298
|
const sessionId = args[0];
|
|
299
299
|
|
|
300
300
|
if (!sessionId) {
|
|
@@ -329,14 +329,3 @@ export default async function summarize(args) {
|
|
|
329
329
|
process.exit(1);
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
|
-
|
|
333
|
-
function findProjectRoot() {
|
|
334
|
-
let dir = process.cwd();
|
|
335
|
-
while (dir !== '/') {
|
|
336
|
-
if (existsSync(join(dir, '.git'))) {
|
|
337
|
-
return dir;
|
|
338
|
-
}
|
|
339
|
-
dir = join(dir, '..');
|
|
340
|
-
}
|
|
341
|
-
throw new Error('Not in a git repository');
|
|
342
|
-
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudemini/shit-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Session-based Hook Intelligence Tracker -
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "Session-based Hook Intelligence Tracker - Zero-dependency memory system for human-AI coding sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"shit": "./bin/shit.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"lib/",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
|
+
},
|
|
9
18
|
"scripts": {
|
|
10
19
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
20
|
},
|
|
12
21
|
"keywords": [
|
|
13
22
|
"claude-code",
|
|
23
|
+
"gemini-cli",
|
|
24
|
+
"cursor",
|
|
25
|
+
"ai-coding",
|
|
14
26
|
"hooks",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
27
|
+
"session-tracking",
|
|
28
|
+
"code-review",
|
|
29
|
+
"checkpoint"
|
|
17
30
|
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/anthropics/shit-cli.git"
|
|
34
|
+
},
|
|
18
35
|
"author": "",
|
|
19
36
|
"license": "MIT",
|
|
20
37
|
"dependencies": {},
|
package/.claude/settings.json
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"SessionStart": [
|
|
4
|
-
{
|
|
5
|
-
"matcher": "",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "shit log session-start"
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
"SessionEnd": [
|
|
15
|
-
{
|
|
16
|
-
"matcher": "",
|
|
17
|
-
"hooks": [
|
|
18
|
-
{
|
|
19
|
-
"type": "command",
|
|
20
|
-
"command": "shit log session-end"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"UserPromptSubmit": [
|
|
26
|
-
{
|
|
27
|
-
"matcher": "",
|
|
28
|
-
"hooks": [
|
|
29
|
-
{
|
|
30
|
-
"type": "command",
|
|
31
|
-
"command": "shit log user-prompt-submit"
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
"PreToolUse": [
|
|
37
|
-
{
|
|
38
|
-
"matcher": "",
|
|
39
|
-
"hooks": [
|
|
40
|
-
{
|
|
41
|
-
"type": "command",
|
|
42
|
-
"command": "shit log pre-tool-use"
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
],
|
|
47
|
-
"PostToolUse": [
|
|
48
|
-
{
|
|
49
|
-
"matcher": "",
|
|
50
|
-
"hooks": [
|
|
51
|
-
{
|
|
52
|
-
"type": "command",
|
|
53
|
-
"command": "shit log post-tool-use"
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
}
|
|
57
|
-
],
|
|
58
|
-
"Notification": [
|
|
59
|
-
{
|
|
60
|
-
"matcher": "",
|
|
61
|
-
"hooks": [
|
|
62
|
-
{
|
|
63
|
-
"type": "command",
|
|
64
|
-
"command": "shit log notification"
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
],
|
|
69
|
-
"Stop": [
|
|
70
|
-
{
|
|
71
|
-
"matcher": "",
|
|
72
|
-
"hooks": [
|
|
73
|
-
{
|
|
74
|
-
"type": "command",
|
|
75
|
-
"command": "shit log stop"
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(git remote add:*)",
|
|
5
|
-
"Bash(git push:*)",
|
|
6
|
-
"Bash(npm publish:*)",
|
|
7
|
-
"Bash(npm whoami:*)",
|
|
8
|
-
"WebFetch(domain:www.npmjs.com)",
|
|
9
|
-
"Bash(npm config delete:*)",
|
|
10
|
-
"Bash(sudo chown:*)",
|
|
11
|
-
"Bash(npm cache clean:*)",
|
|
12
|
-
"Bash(npm install:*)",
|
|
13
|
-
"Bash(git add:*)",
|
|
14
|
-
"Bash(git commit -m \"$\\(cat <<''EOF''\n更新包名和版本号\n\n- 包名改为 @cluademini/shit-cli\n- 版本号升至 1.0.3\nEOF\n\\)\")",
|
|
15
|
-
"Bash(git commit:*)",
|
|
16
|
-
"Bash(npm config set:*)",
|
|
17
|
-
"WebFetch(domain:github.com)"
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
}
|
package/COMPARISON.md
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# Project Structure Comparison
|
|
2
|
-
|
|
3
|
-
## Directory Layout
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
your-project/
|
|
7
|
-
├── .claude/ # Claude Code configuration
|
|
8
|
-
│ └── settings.json # Hook configurations
|
|
9
|
-
├── .entire/ # Entire tool (session management)
|
|
10
|
-
│ ├── metadata/
|
|
11
|
-
│ │ └── <session-id>/
|
|
12
|
-
│ │ ├── full.jsonl # Complete transcript
|
|
13
|
-
│ │ ├── prompt.txt # User prompts
|
|
14
|
-
│ │ ├── context.md # Session context
|
|
15
|
-
│ │ └── summary.txt # Session summary
|
|
16
|
-
│ ├── logs/
|
|
17
|
-
│ └── settings.json
|
|
18
|
-
└── .shit-logs/ # shit-cli (hook event logging)
|
|
19
|
-
├── <session-id>/
|
|
20
|
-
│ ├── events.jsonl # Hook events only
|
|
21
|
-
│ ├── prompts.txt # User prompts
|
|
22
|
-
│ ├── context.md # Session context
|
|
23
|
-
│ ├── summary.txt # Session summary
|
|
24
|
-
│ └── metadata.json # Session metadata
|
|
25
|
-
└── index.txt # Global index
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Feature Comparison
|
|
29
|
-
|
|
30
|
-
| Feature | `.entire` | `.shit-logs` |
|
|
31
|
-
|---------|-----------|--------------|
|
|
32
|
-
| **Scope** | Complete session transcript | Hook events only |
|
|
33
|
-
| **Location** | Project root | Project root ✓ |
|
|
34
|
-
| **Session-based** | ✓ | ✓ |
|
|
35
|
-
| **Transcript** | `full.jsonl` (all messages) | `events.jsonl` (hooks only) |
|
|
36
|
-
| **Prompts** | `prompt.txt` | `prompts.txt` |
|
|
37
|
-
| **Context** | `context.md` | `context.md` |
|
|
38
|
-
| **Summary** | `summary.txt` | `summary.txt` |
|
|
39
|
-
| **Checkpoints** | Git shadow branches | Not implemented |
|
|
40
|
-
| **CLI** | `entire` commands | `shit` commands |
|
|
41
|
-
| **Auto-init** | `entire enable` | `shit init` |
|
|
42
|
-
|
|
43
|
-
## Key Differences
|
|
44
|
-
|
|
45
|
-
### `.entire` (Entire Tool)
|
|
46
|
-
- **Purpose**: Complete session management and checkpointing
|
|
47
|
-
- **Data**: Full conversation transcript (user + assistant messages)
|
|
48
|
-
- **Features**: Git integration, checkpoints, session replay
|
|
49
|
-
- **Trigger**: Automatic (entire daemon)
|
|
50
|
-
|
|
51
|
-
### `.shit-logs` (shit-cli)
|
|
52
|
-
- **Purpose**: Hook event logging and analysis
|
|
53
|
-
- **Data**: Hook events only (tool calls, session events)
|
|
54
|
-
- **Features**: Session aggregation, event filtering, cleanup
|
|
55
|
-
- **Trigger**: Hook-based (Claude Code hooks)
|
|
56
|
-
|
|
57
|
-
## Use Cases
|
|
58
|
-
|
|
59
|
-
### Use `.entire` when you need:
|
|
60
|
-
- Complete session history
|
|
61
|
-
- Git-based checkpointing
|
|
62
|
-
- Session replay and analysis
|
|
63
|
-
- Cross-session context
|
|
64
|
-
|
|
65
|
-
### Use `.shit-logs` when you need:
|
|
66
|
-
- Hook event debugging
|
|
67
|
-
- Tool usage analysis
|
|
68
|
-
- Session statistics
|
|
69
|
-
- Lightweight logging
|
|
70
|
-
|
|
71
|
-
## Both Together
|
|
72
|
-
|
|
73
|
-
Running both systems provides:
|
|
74
|
-
- **Complete coverage**: Full transcript + hook events
|
|
75
|
-
- **Different perspectives**: Conversation flow + tool execution
|
|
76
|
-
- **Complementary data**: `.entire` for context, `.shit-logs` for debugging
|
|
77
|
-
|
|
78
|
-
## .gitignore
|
|
79
|
-
|
|
80
|
-
Both directories are typically excluded from git:
|
|
81
|
-
|
|
82
|
-
```gitignore
|
|
83
|
-
# Entire tool
|
|
84
|
-
.entire/store/
|
|
85
|
-
.entire/monitor.pid
|
|
86
|
-
.entire/monitor.sessions.json
|
|
87
|
-
|
|
88
|
-
# shit-cli logs
|
|
89
|
-
.shit-logs/
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Note: `.entire/settings.json` and `.entire/.gitignore` are usually committed.
|
package/DESIGN_PHILOSOPHY.md
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
# shit-cli Design Philosophy
|
|
2
|
-
|
|
3
|
-
## Core Vision
|
|
4
|
-
|
|
5
|
-
### 1. Human-AI Interaction Memory System
|
|
6
|
-
Long-term memory storage for human-AI interactions, not just temporary logs. Each session is analyzed for semantic meaning — what was the intent, what changed, what's the risk.
|
|
7
|
-
|
|
8
|
-
### 2. Code Review Bot Data Support
|
|
9
|
-
Provide reliable, structured data to support code review automation. The bot doesn't need to parse raw events — it gets pre-classified changes, risk assessments, and review hints.
|
|
10
|
-
|
|
11
|
-
## Architecture
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
Human ↔ AI (Claude Code)
|
|
15
|
-
↓ (hooks)
|
|
16
|
-
Event Ingestion (log.js)
|
|
17
|
-
↓
|
|
18
|
-
Semantic Extraction (extract.js)
|
|
19
|
-
↓
|
|
20
|
-
Session State (session.js) + Reports (report.js)
|
|
21
|
-
↓
|
|
22
|
-
Memory System (.shit-logs + index.json)
|
|
23
|
-
↓
|
|
24
|
-
Code Review Bot / Human Queries
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Three-Layer Architecture
|
|
28
|
-
|
|
29
|
-
1. **Ingestion Layer** — `log.js` reads stdin, parses events, dispatches
|
|
30
|
-
2. **Intelligence Layer** — `extract.js` classifies intent, changes, risk
|
|
31
|
-
3. **Storage Layer** — `session.js` manages state, `report.js` generates outputs
|
|
32
|
-
|
|
33
|
-
## Semantic Model
|
|
34
|
-
|
|
35
|
-
### Intent Extraction
|
|
36
|
-
From user prompts, extract:
|
|
37
|
-
- **Goal**: What the user is trying to accomplish
|
|
38
|
-
- **Type**: bugfix, feature, refactor, debug, test, docs, etc.
|
|
39
|
-
- **Scope**: Which domains are involved (auth, api, database, etc.)
|
|
40
|
-
|
|
41
|
-
### Change Extraction
|
|
42
|
-
From tool events, extract:
|
|
43
|
-
- **Files**: Categorized (source, test, config, doc, script, infra, deps, migration)
|
|
44
|
-
- **Operations**: What was done to each file (read, write, edit)
|
|
45
|
-
- **Commands**: Categorized (test, build, git, deploy, install, lint, database)
|
|
46
|
-
|
|
47
|
-
### Session Classification
|
|
48
|
-
Combining intent + changes:
|
|
49
|
-
- **Type**: Dominant activity category
|
|
50
|
-
- **Risk**: Assessment based on file count, config changes, test coverage
|
|
51
|
-
- **Review Hints**: Actionable flags for code review bots
|
|
52
|
-
|
|
53
|
-
## File Structure
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
.shit-logs/
|
|
57
|
-
├── index.json # Cross-session index (file history, session types)
|
|
58
|
-
└── <session-id>/
|
|
59
|
-
├── events.jsonl # Raw hook events (complete history)
|
|
60
|
-
├── state.json # Incremental processing state
|
|
61
|
-
├── summary.json # Bot data interface (v2 schema)
|
|
62
|
-
├── summary.txt # Human-readable semantic report
|
|
63
|
-
├── prompts.txt # User prompts with timestamps
|
|
64
|
-
└── metadata.json # Lightweight session metadata
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Key Design Decisions
|
|
68
|
-
|
|
69
|
-
### 1. Rule-Based Classification (No AI Dependency)
|
|
70
|
-
Intent and change classification use simple pattern matching rules. This ensures:
|
|
71
|
-
- Zero latency — runs during hook processing
|
|
72
|
-
- Zero cost — no API calls
|
|
73
|
-
- Predictable — deterministic output
|
|
74
|
-
- Offline — works without network
|
|
75
|
-
|
|
76
|
-
### 2. Cross-Session Index
|
|
77
|
-
The `index.json` file enables:
|
|
78
|
-
- File history queries ("how often was this file changed?")
|
|
79
|
-
- Session type filtering ("show all bugfix sessions")
|
|
80
|
-
- Risk tracking over time
|
|
81
|
-
- Bot can query without scanning all sessions
|
|
82
|
-
|
|
83
|
-
### 3. summary.json v2 Schema
|
|
84
|
-
Upgraded from v1 (statistics-only) to v2 (semantic):
|
|
85
|
-
- **v1**: event counts, file lists, tool usage
|
|
86
|
-
- **v2**: intent, type, risk, review_hints, categorized changes/commands
|
|
87
|
-
|
|
88
|
-
### 4. Incremental Processing
|
|
89
|
-
State is maintained incrementally in `state.json`. Each event updates the state, and reports are regenerated from the latest state. This means:
|
|
90
|
-
- Fast processing per event (~5ms)
|
|
91
|
-
- Reports always reflect current session state
|
|
92
|
-
- No need to re-read events.jsonl
|
|
93
|
-
|
|
94
|
-
### 5. Best-Effort Shadow Branches
|
|
95
|
-
Git shadow branches and index updates are best-effort — failures don't affect core logging. This ensures hooks never block Claude Code.
|
|
96
|
-
|
|
97
|
-
## Bot Integration Patterns
|
|
98
|
-
|
|
99
|
-
### Direct File Read
|
|
100
|
-
```javascript
|
|
101
|
-
const summary = JSON.parse(fs.readFileSync('.shit-logs/<id>/summary.json'));
|
|
102
|
-
// Use summary.review_hints for automated review decisions
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Cross-Session Query
|
|
106
|
-
```javascript
|
|
107
|
-
const index = JSON.parse(fs.readFileSync('.shit-logs/index.json'));
|
|
108
|
-
// Find all sessions that touched a specific file
|
|
109
|
-
const sessions = index.file_history['src/auth/service.ts'];
|
|
110
|
-
// Filter by type or risk
|
|
111
|
-
const risky = index.sessions.filter(s => s.risk === 'high');
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### CLI Query (for humans)
|
|
115
|
-
```bash
|
|
116
|
-
shit query --file=src/auth/service.ts # File history
|
|
117
|
-
shit query --type=bugfix --recent=5 # Recent bugfixes
|
|
118
|
-
shit query --risk=high --json # High-risk as JSON
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Comparison with `.entire`
|
|
122
|
-
|
|
123
|
-
| Aspect | `.entire` | `.shit-logs` |
|
|
124
|
-
|--------|-----------|--------------|
|
|
125
|
-
| **Data Source** | Full transcript | Hook events |
|
|
126
|
-
| **Intelligence** | Raw messages | Semantic extraction |
|
|
127
|
-
| **Bot Interface** | Parse messages | Structured JSON (v2) |
|
|
128
|
-
| **Cross-Session** | No | Index with file history |
|
|
129
|
-
| **Review Hints** | No | Tests, risk, coverage |
|
|
130
|
-
| **Purpose** | Conversation memory | Operation intelligence |
|
|
131
|
-
|
|
132
|
-
## Future Enhancements
|
|
133
|
-
|
|
134
|
-
- AI-powered intent extraction (optional, when available)
|
|
135
|
-
- Diff-level change tracking (what exactly changed in each edit)
|
|
136
|
-
- Session linking (detect related sessions across time)
|
|
137
|
-
- Anomaly detection (unusual patterns in session activity)
|
|
138
|
-
- Bot API endpoint (serve session data over HTTP)
|
package/QUICKSTART.md
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Quick Start Guide
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
# Clone or download shit-cli
|
|
7
|
-
cd ~/Desktop/shit-cli
|
|
8
|
-
|
|
9
|
-
# Install globally
|
|
10
|
-
npm link
|
|
11
|
-
|
|
12
|
-
# Or add to PATH
|
|
13
|
-
echo 'export PATH="$HOME/Desktop/shit-cli/bin:$PATH"' >> ~/.zshrc
|
|
14
|
-
source ~/.zshrc
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Setup (One-time)
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Navigate to your project
|
|
21
|
-
cd /path/to/your/project
|
|
22
|
-
|
|
23
|
-
# Initialize hooks
|
|
24
|
-
shit init
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
This creates `.claude/settings.json` with all necessary hooks.
|
|
28
|
-
|
|
29
|
-
## Verify Installation
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
# Check if shit is available
|
|
33
|
-
shit help
|
|
34
|
-
|
|
35
|
-
# Should output:
|
|
36
|
-
# shit-cli - Session-based Hook Intelligence Tracker
|
|
37
|
-
# Usage: shit <command> [options]
|
|
38
|
-
# ...
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Usage
|
|
42
|
-
|
|
43
|
-
Once initialized, hooks will automatically log events to `~/.shit-logs/`.
|
|
44
|
-
|
|
45
|
-
### View your sessions
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
# List all sessions
|
|
49
|
-
shit list
|
|
50
|
-
|
|
51
|
-
# View specific session
|
|
52
|
-
shit view <session-id>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Clean up old logs
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Preview what will be deleted
|
|
59
|
-
shit clean --days=7 --dry-run
|
|
60
|
-
|
|
61
|
-
# Actually delete
|
|
62
|
-
shit clean --days=7
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Troubleshooting
|
|
66
|
-
|
|
67
|
-
### Command not found: shit
|
|
68
|
-
|
|
69
|
-
If `npm link` doesn't work, use the full path:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
node ~/Desktop/shit-cli/bin/shit.js init
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Or create an alias:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
echo 'alias shit="node ~/Desktop/shit-cli/bin/shit.js"' >> ~/.zshrc
|
|
79
|
-
source ~/.zshrc
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Hooks not working
|
|
83
|
-
|
|
84
|
-
1. Check if `.claude/settings.json` exists in your project
|
|
85
|
-
2. Verify hooks are registered: `cat .claude/settings.json`
|
|
86
|
-
3. Restart Claude Code
|
|
87
|
-
|
|
88
|
-
### Logs not appearing
|
|
89
|
-
|
|
90
|
-
1. Check log directory: `ls -la ~/.shit-logs/`
|
|
91
|
-
2. Verify hooks are being triggered (check Claude Code output)
|
|
92
|
-
3. Test manually:
|
|
93
|
-
```bash
|
|
94
|
-
echo '{"session_id":"test-123","hook_event_name":"Test"}' | shit log test
|
|
95
|
-
shit list
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Uninstall
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
# Remove global link
|
|
102
|
-
npm unlink -g shit-cli
|
|
103
|
-
|
|
104
|
-
# Remove logs
|
|
105
|
-
rm -rf ~/.shit-logs
|
|
106
|
-
|
|
107
|
-
# Remove hooks from project
|
|
108
|
-
# Edit .claude/settings.json and remove shit-related hooks
|
|
109
|
-
```
|