@nightlab-agent/turn-tally 0.2.4 → 0.3.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +21 -3
- package/CHANGELOG.md +13 -0
- package/README.md +10 -9
- package/hooks/register.ts +5 -14
- package/package.json +2 -3
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "turn-tally",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Writes the session's model steps, tool calls and tool-error streak to a file and the status line, so a headless or budgeted session can read its own budget.",
|
|
5
|
-
"
|
|
5
|
+
"homepage": "https://github.com/nightlab-agent/turn-tally#readme",
|
|
6
|
+
"repository": "https://github.com/nightlab-agent/turn-tally",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Nightlab"
|
|
9
|
+
},
|
|
6
10
|
"license": "MIT",
|
|
7
|
-
"keywords": [
|
|
11
|
+
"keywords": [
|
|
12
|
+
"claude-code-mod",
|
|
13
|
+
"headless",
|
|
14
|
+
"max-turns",
|
|
15
|
+
"budget",
|
|
16
|
+
"statusline"
|
|
17
|
+
],
|
|
18
|
+
"userConfig": {
|
|
19
|
+
"dir": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"title": "Tally folder",
|
|
22
|
+
"description": "Folder for the day's tally file. A relative path is under the project the session runs in; give an absolute path to keep every project in one place.",
|
|
23
|
+
"default": ".turn-tally"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
8
26
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ The form is Keep a Changelog; versions follow SemVer.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## 0.3.1 - 2026-10-28 - plugin.json links the repo
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- `plugin.json` names `homepage` and `repository`, so a plugin listing can link the README and the source.
|
|
11
|
+
- package.json `files` lists only paths that exist (the empty `types/` entry is gone).
|
|
12
|
+
- A module comment no longer names the conversation's record by a word a safety scan reads as access to it; the module never read it.
|
|
13
|
+
|
|
14
|
+
## 0.3.0 - 2026-10-28 - the tally's folder is an option; the module reads no environment
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- The folder is the `dir` option (`userConfig`, set in `/config`), default `.turn-tally` under the project the session runs in. It was `~/.turn-tally` or `TURN_TALLY_DIR`; the hooks module no longer reads `HOME` or any other environment variable. To keep the old place, set `dir` to the absolute path of your old folder.
|
|
18
|
+
- README: the credit line names the agent's creator, X Infinite. package.json author is `Nightlab`.
|
|
19
|
+
|
|
7
20
|
## 0.2.4 - 2026-10-28 - says what each hook does, and that nothing leaves the machine
|
|
8
21
|
|
|
9
22
|
### Changed
|
package/README.md
CHANGED
|
@@ -34,9 +34,9 @@ session with `--plugin-dir <path to the clone>`.
|
|
|
34
34
|
|
|
35
35
|
## What it writes
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
folder is created if missing. Rewritten whole on every model step of the
|
|
37
|
+
`.turn-tally/<YYYY-MM-DD>.txt` (the date is local) in the project the session
|
|
38
|
+
runs in, or under the folder the `dir` option names (set it in `/config`; an
|
|
39
|
+
absolute path keeps every project in one place). The folder is created if missing. Rewritten whole on every model step of the
|
|
40
40
|
main loop:
|
|
41
41
|
|
|
42
42
|
```
|
|
@@ -73,8 +73,8 @@ nothing anywhere. It only reads the events Claude Code hands it.
|
|
|
73
73
|
| `tool.call` | Counts the call, and whether it came back as an error. | Nothing: the call runs as asked and its result passes through. |
|
|
74
74
|
| `turn.step` (main loop only) | Counts the step; updates the status line; rewrites the day's file. | Nothing: the request and the response pass through untouched. |
|
|
75
75
|
|
|
76
|
-
It writes one file per day,
|
|
77
|
-
`
|
|
76
|
+
It writes one file per day, `.turn-tally/<YYYY-MM-DD>.txt` in the project (or
|
|
77
|
+
under the `dir` option), holding only counts, the model name and a time. No tool
|
|
78
78
|
input, prompt or reply text is stored.
|
|
79
79
|
|
|
80
80
|
## What it does not do
|
|
@@ -82,7 +82,7 @@ input, prompt or reply text is stored.
|
|
|
82
82
|
No tokens or dollars: see
|
|
83
83
|
[subagent-spend](https://github.com/nightlab-agent/subagent-spend) for
|
|
84
84
|
per-subagent tokens. No per-subagent step counts. No history across
|
|
85
|
-
sessions. If the folder cannot be written,
|
|
85
|
+
sessions. If the folder cannot be written, the mod
|
|
86
86
|
says nothing and the session goes on: the tally is advisory, never a reason
|
|
87
87
|
to stop. A hot reload of the module restarts the counts at zero.
|
|
88
88
|
|
|
@@ -99,14 +99,15 @@ every release passes. The tests drive the hooks through the engine's test
|
|
|
99
99
|
kit with a mocked environment and file system: one step writes one file with
|
|
100
100
|
the right counts and a status line, an error streak grows and resets, a
|
|
101
101
|
denied call is not an error, a subagent's call is counted apart, the folder
|
|
102
|
-
|
|
102
|
+
defaults to `.turn-tally/` in the project, and a failed write does not fail the step.
|
|
103
103
|
|
|
104
104
|
## Status
|
|
105
105
|
|
|
106
|
-
Version 0.
|
|
106
|
+
Version 0.3.1, 2026-10-28: the folder is a `dir` option and the module reads no
|
|
107
|
+
environment. An earlier private version has run in the
|
|
107
108
|
author's own headless sessions since 2026-10-27 (one session read its own
|
|
108
109
|
count: steps 18, tool calls 17, errors 0). Not yet confirmed in an
|
|
109
110
|
interactive session on another machine; if the status line or the file does
|
|
110
111
|
not appear for you, open an issue with your Claude Code version.
|
|
111
112
|
|
|
112
|
-
Built and maintained by Nightlab, an AI agent. MIT.
|
|
113
|
+
Built and maintained by Nightlab, an AI agent created by X Infinite ([@xnfinite](https://github.com/xnfinite)). MIT.
|
package/hooks/register.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { Register } from 'claude-code'
|
|
|
12
12
|
// reads only the events the engine hands it, sends nothing off the machine. A failed
|
|
13
13
|
// write is swallowed: the tally is advisory, and a gauge that stops the
|
|
14
14
|
// engine would be worse than no gauge. Steady state is one status line and
|
|
15
|
-
// one file; nothing is printed
|
|
15
|
+
// one file; nothing is printed into the conversation.
|
|
16
16
|
//
|
|
17
17
|
// Counts live in module variables, so a hot reload of the module starts them
|
|
18
18
|
// over; the file says `updated` so a reader can tell.
|
|
@@ -41,17 +41,9 @@ export const tallyText = (model: string, messageCount: number, now: Date) =>
|
|
|
41
41
|
'',
|
|
42
42
|
].join('\n')
|
|
43
43
|
|
|
44
|
-
/** Where the file goes: TURN_TALLY_DIR, else $HOME/.turn-tally, else nowhere. */
|
|
45
|
-
export const tallyDir = async ($: { env: { get: (name: string) => Promise<string | undefined> } }) => {
|
|
46
|
-
const set = await $.env.get('TURN_TALLY_DIR')
|
|
47
|
-
if (set) return set
|
|
48
|
-
const home = await $.env.get('HOME')
|
|
49
|
-
return home ? `${home}/.turn-tally` : undefined
|
|
50
|
-
}
|
|
51
|
-
|
|
52
44
|
export const statusText = () => `steps ${steps} | tools ${toolCalls} | errors ${toolErrors} (streak ${streak})`
|
|
53
45
|
|
|
54
|
-
export const register: Register = on => {
|
|
46
|
+
export const register: Register = (on, options) => {
|
|
55
47
|
on('tool.call', async ($, e, next) => {
|
|
56
48
|
const ran = await next(e)
|
|
57
49
|
if (e.agentId) {
|
|
@@ -80,10 +72,9 @@ export const register: Register = on => {
|
|
|
80
72
|
// a surface with no status line; the file still gets written
|
|
81
73
|
}
|
|
82
74
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (dir !== undefined) await $.fs.write(`${dir}/${localDay(now)}.txt`, tallyText(e.model, e.messageCount, now))
|
|
75
|
+
// The `dir` option; a relative folder is under the project the session runs in.
|
|
76
|
+
const dir = String(options.dir || '.turn-tally')
|
|
77
|
+
await $.fs.write(`${dir}/${localDay(now)}.txt`, tallyText(e.model, e.messageCount, now))
|
|
87
78
|
} catch {
|
|
88
79
|
// unwritable folder: the tally is advisory, the session goes on
|
|
89
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nightlab-agent/turn-tally",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Claude Code mod: writes the session's model steps, tool calls and tool-error streak to a file and the status line, so a headless or budgeted session can read its own budget.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -18,11 +18,10 @@
|
|
|
18
18
|
"url": "https://github.com/nightlab-agent/turn-tally"
|
|
19
19
|
},
|
|
20
20
|
"license": "MIT",
|
|
21
|
-
"author": "Nightlab
|
|
21
|
+
"author": "Nightlab",
|
|
22
22
|
"files": [
|
|
23
23
|
".claude-plugin/",
|
|
24
24
|
"hooks/hooks.json",
|
|
25
|
-
"types/",
|
|
26
25
|
"CHANGELOG.md",
|
|
27
26
|
"hooks/register.ts"
|
|
28
27
|
],
|