codewhale.history 2.0.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 +44 -0
- package/_list_sessions.js +56 -0
- package/instructions.md +7 -0
- package/package.json +19 -0
- package/skills/history/SKILL.md +23 -0
- package/skills/tools/tools-skill/SKILL.md +19 -0
- package/tools-install.js +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# CodeWhale Tools Pack
|
|
2
|
+
|
|
3
|
+
A portable pack of global CodeWhale commands: `//tools` and `//history`.
|
|
4
|
+
|
|
5
|
+
Cross-platform — works on Windows, Mac, Linux.
|
|
6
|
+
|
|
7
|
+
## What's inside
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
tools_for_codewhale/
|
|
11
|
+
├── _list_sessions.js # codewhale-history command (Node.js)
|
|
12
|
+
├── package.json # npm package config
|
|
13
|
+
├── tools-install.js # Cross-platform installer (skills + instructions)
|
|
14
|
+
├── skills/
|
|
15
|
+
│ ├── history/SKILL.md # //history — calls codewhale-history
|
|
16
|
+
│ └── tools/tools-skill/SKILL.md # //tools — lists all available tools
|
|
17
|
+
├── instructions.md # Trigger config (drop into any .codewhale/)
|
|
18
|
+
└── README.md # This file
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
One command:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g codewhale.history && codewhale-tools-install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then in any CodeWhale workspace, `//tools` and `//history` work immediately.
|
|
30
|
+
|
|
31
|
+
### Manual per-workspace install (if already globally installed)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
codewhale-tools-install # current workspace
|
|
35
|
+
codewhale-tools-install -p <target-path> # specific workspace
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## After install
|
|
39
|
+
- **`//tools`** — lists every tool available in the current session
|
|
40
|
+
- **`//history`** — lists all chat sessions for the current workspace with cost totals
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
- Node.js (for the `codewhale-history` command)
|
|
44
|
+
- CodeWhale
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
const sessionsDir = path.join(os.homedir(), '.codewhale', 'sessions');
|
|
7
|
+
const targetWorkspace = process.cwd();
|
|
8
|
+
|
|
9
|
+
let files = [];
|
|
10
|
+
try {
|
|
11
|
+
files = fs.readdirSync(sessionsDir)
|
|
12
|
+
.filter(f => f.endsWith('.json'))
|
|
13
|
+
.map(f => ({
|
|
14
|
+
name: f,
|
|
15
|
+
filepath: path.join(sessionsDir, f),
|
|
16
|
+
mtime: fs.statSync(path.join(sessionsDir, f)).mtimeMs
|
|
17
|
+
}))
|
|
18
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
19
|
+
} catch {
|
|
20
|
+
console.log('No sessions found for this workspace.');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const results = [];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
try {
|
|
27
|
+
const data = JSON.parse(fs.readFileSync(file.filepath, 'utf-8'));
|
|
28
|
+
const meta = data.metadata;
|
|
29
|
+
if (meta.workspace === targetWorkspace) {
|
|
30
|
+
const created = (meta.created_at || '').substring(0, 16) || '?';
|
|
31
|
+
const title = meta.title || 'Untitled';
|
|
32
|
+
const msgs = meta.message_count ?? '?';
|
|
33
|
+
const tokens = meta.total_tokens ?? '?';
|
|
34
|
+
const cost = meta.cost?.session_cost_usd ?? 0;
|
|
35
|
+
const model = meta.model || '?';
|
|
36
|
+
console.log(
|
|
37
|
+
`${created} | ${title} | ${msgs} msgs | ${typeof tokens === 'number' ? tokens.toLocaleString() : tokens} tok | $${cost.toFixed(4)} | ${model}`
|
|
38
|
+
);
|
|
39
|
+
results.push({ msgs: meta.message_count ?? 0, tokens: meta.total_tokens ?? 0, cost });
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// skip files that don't parse
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (results.length > 0) {
|
|
47
|
+
const totalMsgs = results.reduce((s, r) => s + r.msgs, 0);
|
|
48
|
+
const totalTokens = results.reduce((s, r) => s + r.tokens, 0);
|
|
49
|
+
const totalCost = results.reduce((s, r) => s + r.cost, 0);
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(
|
|
52
|
+
`TOTAL | ${results.length} sessions | ${totalMsgs} msgs | ${totalTokens.toLocaleString()} tok | $${totalCost.toFixed(4)} |`
|
|
53
|
+
);
|
|
54
|
+
} else {
|
|
55
|
+
console.log('No sessions found for this workspace.');
|
|
56
|
+
}
|
package/instructions.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Delegated Instructions
|
|
2
|
+
|
|
3
|
+
## //tools Command
|
|
4
|
+
When the user types `//tools`, immediately load the `tools` skill (from `tools-skill/SKILL.md`) and enumerate every tool available in this session grouped by category with brief descriptions. This works in all sessions once the skill is installed globally.
|
|
5
|
+
|
|
6
|
+
## //history Command
|
|
7
|
+
When the user types `//history`, immediately load the `history` skill (from `history/SKILL.md`) and list all CodeWhale chat sessions for the current workspace with message count, tokens, cost, and totals. This works in all sessions once the skill is installed globally.
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codewhale.history",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "CodeWhale utility commands: session history, tool listing — global install",
|
|
5
|
+
"bin": {
|
|
6
|
+
"codewhale-history": "./_list_sessions.js",
|
|
7
|
+
"codewhale-tools-install": "./tools-install.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"_list_sessions.js",
|
|
11
|
+
"tools-install.js",
|
|
12
|
+
"README.md",
|
|
13
|
+
"instructions.md",
|
|
14
|
+
"skills"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=14"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: history
|
|
3
|
+
description: Lists all CodeWhale chat sessions for the current workspace with message count, tokens, cost, and totals. Triggered when the user types `//history`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `//history` Command
|
|
7
|
+
|
|
8
|
+
When the user types `//history`, list all chat sessions from the current workspace with their metadata and a total summary row.
|
|
9
|
+
|
|
10
|
+
## Behavior
|
|
11
|
+
|
|
12
|
+
1. Run `codewhale-history` (installed globally via `npm install -g`)
|
|
13
|
+
2. Present the output as a formatted table with columns: Date/Time, Title, Messages, Tokens, Cost, Model
|
|
14
|
+
3. Include the TOTAL row at the bottom
|
|
15
|
+
|
|
16
|
+
### Important: No-sessions handling
|
|
17
|
+
If the output says "No sessions found for this workspace.", that's **normal**. Do NOT create debug scripts, investigate further, or treat it as an error. Simply relay that message and stop.
|
|
18
|
+
|
|
19
|
+
## Notes
|
|
20
|
+
- `codewhale-history` is a global npm package — works on Windows, Mac, Linux
|
|
21
|
+
- Filter sessions by the current workspace directory (`process.cwd()`)
|
|
22
|
+
- The skill is installed globally — works in any workspace
|
|
23
|
+
- Do NOT recreate the script or embed it — the npm package is the source of truth
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tools
|
|
3
|
+
description: Lists all available tools and their capabilities. Triggered when the user types /tools.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `//tools` Command
|
|
7
|
+
|
|
8
|
+
When the user types `//tools`, enumerate every tool available to the model in this session, grouped by category with a brief description of each. I want the tool listing, not just the activation notice.
|
|
9
|
+
|
|
10
|
+
## Behavior
|
|
11
|
+
1. Scan all tools currently available in the runtime
|
|
12
|
+
2. Group by category (File I/O, Search, Git, Sub-agents, RLM, Shell/Execution, Planning, etc.)
|
|
13
|
+
3. For each tool, provide the name and a one-line description of what it does
|
|
14
|
+
4. Present as a readable terminal-friendly list
|
|
15
|
+
|
|
16
|
+
## Notes
|
|
17
|
+
- Read-only — no files modified or state changed
|
|
18
|
+
- The tool list is dynamic per-session — do not hardcode it
|
|
19
|
+
- Do not fabricate tools; list only what's actually available
|
package/tools-install.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeWhale Tools Installer
|
|
4
|
+
*
|
|
5
|
+
* Installs global skills and workspace triggers for //tools and //history.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node tools-install.js # current directory
|
|
9
|
+
* node tools-install.js -p <target-path> # specific workspace
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
|
|
16
|
+
const sourceDir = __dirname;
|
|
17
|
+
|
|
18
|
+
// Parse -p flag
|
|
19
|
+
const pIndex = process.argv.indexOf('-p');
|
|
20
|
+
const workspaceArg = pIndex !== -1 ? process.argv[pIndex + 1] : null;
|
|
21
|
+
const workspacePath = path.resolve(workspaceArg || process.cwd());
|
|
22
|
+
|
|
23
|
+
// ── 1. Install skills ──────────────────────────────────
|
|
24
|
+
const skillsSource = path.join(sourceDir, 'skills');
|
|
25
|
+
const skillsDest = path.join(os.homedir(), '.codewhale', 'skills');
|
|
26
|
+
|
|
27
|
+
console.log('[1/3] Installing global skills...');
|
|
28
|
+
if (fs.existsSync(skillsSource)) {
|
|
29
|
+
for (const entry of fs.readdirSync(skillsSource)) {
|
|
30
|
+
const src = path.join(skillsSource, entry);
|
|
31
|
+
if (fs.statSync(src).isDirectory()) {
|
|
32
|
+
const dest = path.join(skillsDest, entry);
|
|
33
|
+
fs.cpSync(src, dest, { recursive: true, force: true });
|
|
34
|
+
console.log(` -> Copied skill '${entry}'`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
console.log(' Skills installed.');
|
|
38
|
+
} else {
|
|
39
|
+
console.log(' WARNING: Skills folder not found.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ── 2. Install instructions ────────────────────────────
|
|
43
|
+
console.log('[2/3] Setting up workspace instructions...');
|
|
44
|
+
const dotCodeWhale = path.join(workspacePath, '.codewhale');
|
|
45
|
+
const instructionsDest = path.join(dotCodeWhale, 'instructions.md');
|
|
46
|
+
const instructionsSource = path.join(sourceDir, 'instructions.md');
|
|
47
|
+
|
|
48
|
+
if (!fs.existsSync(dotCodeWhale)) {
|
|
49
|
+
fs.mkdirSync(dotCodeWhale, { recursive: true });
|
|
50
|
+
console.log(' Created .codewhale folder.');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (fs.existsSync(instructionsSource)) {
|
|
54
|
+
if (fs.existsSync(instructionsDest)) {
|
|
55
|
+
const backup = instructionsDest + '.bak';
|
|
56
|
+
fs.cpSync(instructionsDest, backup);
|
|
57
|
+
console.log(' Backed up existing instructions.md -> instructions.md.bak');
|
|
58
|
+
}
|
|
59
|
+
fs.cpSync(instructionsSource, instructionsDest);
|
|
60
|
+
console.log(' instructions.md deployed.');
|
|
61
|
+
} else {
|
|
62
|
+
console.log(' WARNING: instructions.md not found.');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ── 3. Verify ──────────────────────────────────────────
|
|
66
|
+
console.log('[3/3] Verifying installation...');
|
|
67
|
+
let errors = 0;
|
|
68
|
+
|
|
69
|
+
const checklist = {
|
|
70
|
+
'history skill': path.join(skillsDest, 'history', 'SKILL.md'),
|
|
71
|
+
'tools skill': path.join(skillsDest, 'tools', 'tools-skill', 'SKILL.md'),
|
|
72
|
+
'workspace instructions': instructionsDest
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
for (const [name, filePath] of Object.entries(checklist)) {
|
|
76
|
+
if (fs.existsSync(filePath)) {
|
|
77
|
+
console.log(` [OK] ${name}`);
|
|
78
|
+
} else {
|
|
79
|
+
console.log(` [FAIL] ${name} not found at ${filePath}`);
|
|
80
|
+
errors++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log('');
|
|
85
|
+
if (errors === 0) {
|
|
86
|
+
console.log('=== Installation complete! ===');
|
|
87
|
+
console.log('Make sure codewhale-history is installed globally: npm install -g <path-to-tools_for_codewhale>');
|
|
88
|
+
console.log('Then type //tools or //history in any CodeWhale session.');
|
|
89
|
+
} else {
|
|
90
|
+
console.log(`=== Installation finished with ${errors} error(s). ===`);
|
|
91
|
+
}
|