@traice/codex-collector 0.1.0 → 0.1.3
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 +74 -11
- package/cli.mjs +8 -11
- package/collector.mjs +261 -204
- package/credentials.mjs +75 -0
- package/install.mjs +171 -133
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -12,26 +12,50 @@ collector data goes to `/api/v1/internal-usage`, not `/api/v1/events`.
|
|
|
12
12
|
- Codex OTel `response.completed` token events from `127.0.0.1:4318/v1/logs`
|
|
13
13
|
- local install identity: employee email/name, team name, device principal
|
|
14
14
|
- Codex context metadata: repo/cwd, model, thread id, sandbox/approval mode
|
|
15
|
-
- optional monthly seat/subscription commitment, e.g. `--seat-monthly-usd
|
|
15
|
+
- optional monthly seat/subscription commitment, e.g. `--seat-monthly-usd 100`
|
|
16
16
|
|
|
17
17
|
Prompts are not sent. Codex OTel is configured with `log_user_prompt = false`.
|
|
18
18
|
|
|
19
|
+
For an overview of OTel, the collector data path, and how Codex differs from the planned Claude Code collector, see
|
|
20
|
+
[Coding-agent collectors](../../docs/collectors.md).
|
|
21
|
+
|
|
19
22
|
## Install On This Device
|
|
20
23
|
|
|
21
24
|
Published install shape:
|
|
22
25
|
|
|
23
26
|
```sh
|
|
24
|
-
|
|
27
|
+
printf "trAIce API key: "
|
|
28
|
+
stty -echo
|
|
29
|
+
IFS= read -r TRAICE_API_KEY
|
|
30
|
+
stty echo
|
|
31
|
+
printf "\n"
|
|
25
32
|
export TRAICE_API_KEY
|
|
26
33
|
npx @traice/codex-collector@latest install \
|
|
27
|
-
--server-url https://
|
|
34
|
+
--server-url https://www.runtraice.com \
|
|
28
35
|
--employee-email you@company.com \
|
|
29
36
|
--employee-name "Your Name" \
|
|
30
37
|
--team-name Engineering \
|
|
31
|
-
--seat-monthly-usd
|
|
38
|
+
--seat-monthly-usd 100 \
|
|
39
|
+
--backfill-hours all \
|
|
40
|
+
--patch-codex-config
|
|
32
41
|
unset TRAICE_API_KEY
|
|
33
42
|
```
|
|
34
43
|
|
|
44
|
+
PowerShell on Windows:
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
$secureKey = Read-Host "trAIce API key" -AsSecureString
|
|
48
|
+
$plainKey = [Net.NetworkCredential]::new("", $secureKey).Password
|
|
49
|
+
$plainKey | npx @traice/codex-collector@latest install --api-key-stdin `
|
|
50
|
+
--server-url 'https://www.runtraice.com' `
|
|
51
|
+
--employee-email 'you@company.com' `
|
|
52
|
+
--team-name 'Engineering' `
|
|
53
|
+
--seat-monthly-usd 100 `
|
|
54
|
+
--backfill-hours all `
|
|
55
|
+
--patch-codex-config
|
|
56
|
+
Remove-Variable plainKey, secureKey
|
|
57
|
+
```
|
|
58
|
+
|
|
35
59
|
Local repo development can still run:
|
|
36
60
|
|
|
37
61
|
```sh
|
|
@@ -39,7 +63,7 @@ node tools/internal-spend-codex/install.mjs \
|
|
|
39
63
|
--employee-email you@company.com \
|
|
40
64
|
--employee-name "Your Name" \
|
|
41
65
|
--team-name Engineering \
|
|
42
|
-
--seat-monthly-usd
|
|
66
|
+
--seat-monthly-usd 100
|
|
43
67
|
```
|
|
44
68
|
|
|
45
69
|
The installer:
|
|
@@ -47,7 +71,9 @@ The installer:
|
|
|
47
71
|
- creates or reuses the `internal-spend-poc` workspace in local dev
|
|
48
72
|
- enables the workspace `internalSpendEnabled` flag
|
|
49
73
|
- creates a real API key for `/api/v1/internal-usage`
|
|
50
|
-
-
|
|
74
|
+
- stores the API key in macOS Keychain, Windows Credential Manager, or Linux
|
|
75
|
+
Secret Service and writes only its reference to
|
|
76
|
+
`~/.traice/internal-spend-codex/install.json`
|
|
51
77
|
- appends an idempotent trAIce `[otel]` block to user-level
|
|
52
78
|
`~/.codex/config.toml`
|
|
53
79
|
|
|
@@ -67,13 +93,18 @@ Local repo development can use `node tools/internal-spend-codex/collector.mjs`.
|
|
|
67
93
|
macOS LaunchAgent:
|
|
68
94
|
|
|
69
95
|
```sh
|
|
70
|
-
|
|
96
|
+
printf "trAIce API key: "
|
|
97
|
+
stty -echo
|
|
98
|
+
IFS= read -r TRAICE_API_KEY
|
|
99
|
+
stty echo
|
|
100
|
+
printf "\n"
|
|
71
101
|
export TRAICE_API_KEY
|
|
72
102
|
npx @traice/codex-collector@latest install \
|
|
73
|
-
--server-url https://
|
|
103
|
+
--server-url https://www.runtraice.com \
|
|
74
104
|
--employee-email you@company.com \
|
|
75
105
|
--team-name Engineering \
|
|
76
|
-
--seat-monthly-usd
|
|
106
|
+
--seat-monthly-usd 100 \
|
|
107
|
+
--backfill-hours all \
|
|
77
108
|
--launch-agent
|
|
78
109
|
unset TRAICE_API_KEY
|
|
79
110
|
```
|
|
@@ -113,7 +144,21 @@ contract and fill employee/team fields directly or via identity mapping.
|
|
|
113
144
|
|
|
114
145
|
The API key can be provided with `TRAICE_API_KEY`, `--api-key-stdin`, or
|
|
115
146
|
`--api-key`. Prefer `TRAICE_API_KEY` or `--api-key-stdin` for user installs so
|
|
116
|
-
keys do not end up in shell history.
|
|
147
|
+
keys do not end up in shell history. A later `install` reuses the saved key, and
|
|
148
|
+
`collect` resolves it from secure storage, so neither command prompts again.
|
|
149
|
+
|
|
150
|
+
Credential storage defaults to `--credential-store auto`. It uses the native OS
|
|
151
|
+
credential manager when available. On headless systems it falls back explicitly
|
|
152
|
+
to `~/.traice/internal-spend-codex/credentials.json` with a user-only directory
|
|
153
|
+
and file (`0700`/`0600` on POSIX); that fallback is not encrypted at rest. Use
|
|
154
|
+
`--credential-store keyring` to require native secure storage and fail rather
|
|
155
|
+
than fall back, or `--credential-store file` for an externally encrypted or
|
|
156
|
+
managed environment. Existing plaintext `install.json` credentials migrate on
|
|
157
|
+
the next `install` or `collect`.
|
|
158
|
+
|
|
159
|
+
For containers, CI, MDM, or an external secret manager, inject
|
|
160
|
+
`TRAICE_API_KEY` only into the `collect` process. That override is used without
|
|
161
|
+
being persisted.
|
|
117
162
|
|
|
118
163
|
Private config and collector state default to `~/.traice/internal-spend-codex`.
|
|
119
164
|
Use `--out /path/to/private-dir` only when an org installer manages that
|
|
@@ -134,12 +179,17 @@ New or restarted Codex agents use native OTel export through the installed
|
|
|
134
179
|
`[otel]` config. Already-open agents are covered by session JSONL token-count
|
|
135
180
|
tailing where those files are available.
|
|
136
181
|
|
|
182
|
+
By default the first session scan imports all available Codex history. To limit
|
|
183
|
+
history, pass `--backfill-hours N` to `install` or `collect`; use
|
|
184
|
+
`--backfill-hours all` explicitly for a full import. Collector state is scoped
|
|
185
|
+
to the configured trAIce destination and source event IDs dedupe later restarts.
|
|
186
|
+
|
|
137
187
|
## One-Shot Backfill
|
|
138
188
|
|
|
139
189
|
Run a single session-file scan without opening the OTel listener:
|
|
140
190
|
|
|
141
191
|
```sh
|
|
142
|
-
npx @traice/codex-collector@latest collect --once
|
|
192
|
+
npx @traice/codex-collector@latest collect --once --backfill-hours 6
|
|
143
193
|
```
|
|
144
194
|
|
|
145
195
|
The collector keeps local dedupe state in:
|
|
@@ -149,3 +199,16 @@ The collector keeps local dedupe state in:
|
|
|
149
199
|
```
|
|
150
200
|
|
|
151
201
|
so restarting it should not intentionally duplicate historical rows.
|
|
202
|
+
|
|
203
|
+
## Releasing
|
|
204
|
+
|
|
205
|
+
Do not run `npm publish` locally. From the platform repository, run:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
npm run release:prepare
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
This opens a version PR. Merging the reviewed PR triggers GitHub Actions and npm
|
|
212
|
+
trusted publishing (OIDC), so publishing never requires an npm token or an
|
|
213
|
+
interactive `npm login`. Pass `minor`, `major`, or an explicit version after `--`
|
|
214
|
+
when the default patch bump is not appropriate.
|
package/cli.mjs
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from
|
|
3
|
-
import { dirname, resolve } from
|
|
4
|
-
import { fileURLToPath } from
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
5
|
|
|
6
6
|
const dir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const [command =
|
|
8
|
-
const script =
|
|
9
|
-
?
|
|
10
|
-
: command === 'collect' || command === 'collector'
|
|
11
|
-
? 'collector.mjs'
|
|
12
|
-
: null;
|
|
7
|
+
const [command = "collect", ...args] = process.argv.slice(2);
|
|
8
|
+
const script =
|
|
9
|
+
command === "install" ? "install.mjs" : command === "collect" || command === "collector" ? "collector.mjs" : null;
|
|
13
10
|
|
|
14
11
|
if (!script) {
|
|
15
|
-
console.error(
|
|
12
|
+
console.error("Usage: traice-codex-collector <install|collect> [options]");
|
|
16
13
|
process.exit(2);
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
const result = spawnSync(process.execPath, [resolve(dir, script), ...args], {
|
|
20
|
-
stdio:
|
|
17
|
+
stdio: "inherit",
|
|
21
18
|
});
|
|
22
19
|
|
|
23
20
|
if (result.signal) {
|