agentflex 0.0.0-stage → 0.1.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 +49 -2
- package/bin/agentflex.js +108 -0
- package/package.json +27 -4
package/README.md
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
-
#
|
|
1
|
+
# agentflex
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**An animated card of your coding-agent week, in one command.**
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx agentflex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
No install, no account, no upload. It reads the local histories of Claude Code, Codex, OpenCode and Pi, adds up the last 7 days, and plays the card in your terminal. Press `s` to save a 1200×630 PNG for posting, `r` to replay, `q` to quit.
|
|
12
|
+
|
|
13
|
+
Also works with `pnpm dlx agentflex` and `bunx agentflex`.
|
|
14
|
+
|
|
15
|
+
## What the card shows
|
|
16
|
+
|
|
17
|
+
- **Tokens** for the period, as each assistant recorded them (cache reads included).
|
|
18
|
+
- **Sessions**, **tokens per day** and **peak parallel sessions** (the most agent sessions active at the same moment).
|
|
19
|
+
- **Agent share** across Claude Code, Codex, OpenCode and Pi.
|
|
20
|
+
- **Activity** by weekday and hour, with your busiest hour.
|
|
21
|
+
|
|
22
|
+
## Options
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx agentflex --month # last 30 days
|
|
26
|
+
npx agentflex --all # all retained history
|
|
27
|
+
npx agentflex --png week.png # write the image and exit
|
|
28
|
+
npx agentflex --json # print the numbers as JSON
|
|
29
|
+
npx agentflex --no-anim # final card without animation
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Fast
|
|
33
|
+
|
|
34
|
+
The default 7-day card is computed in well under a second on a heavy-use machine (about 900 MB of history): histories are read in parallel, pruned to the period, and only the fields that matter are decoded. The parsing engine is [SessKit](https://github.com/x0c/sesskit)'s native `sesskit-stats` crate, checked session by session against SessKit's reference implementation.
|
|
35
|
+
|
|
36
|
+
## Platforms
|
|
37
|
+
|
|
38
|
+
macOS (Apple silicon, Intel), Linux (x64, arm64) and Windows (x64, arm64). Histories are found in each assistant's standard location; `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `XDG_DATA_HOME`, `OPENCODE_DB`, `PI_CODING_AGENT_DIR` and `PI_CODING_AGENT_SESSION_DIR` are honored.
|
|
39
|
+
|
|
40
|
+
## Privacy
|
|
41
|
+
|
|
42
|
+
Everything stays on your machine. The card shows totals only: no prompts, file names, project names or paths.
|
|
43
|
+
|
|
44
|
+
## From the makers of Corral
|
|
45
|
+
|
|
46
|
+
agentflex comes from [Corral](https://github.com/corral-dev/corral), a terminal home for all your coding-agent sessions: see who needs you, run agents side by side, and pick up from your phone. Corral users can also run `corral flex`.
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT. The PNG export embeds a subset of the [Spleen](https://github.com/fcambus/spleen) bitmap font (BSD-2-Clause, see https://github.com/corral-dev/agentflex/blob/main/assets/SPLEEN-LICENSE.txt).
|
package/bin/agentflex.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// agentflex npm launcher.
|
|
3
|
+
//
|
|
4
|
+
// The real binary lives in a per-platform optional dependency
|
|
5
|
+
// (agentflex-darwin-arm64, agentflex-linux-x64, ...). This script resolves
|
|
6
|
+
// the matching package at *run* time and spawns the binary, so no
|
|
7
|
+
// postinstall step is needed (pnpm 10 and Bun block postinstall scripts by
|
|
8
|
+
// default, which is why install-time downloading is avoided).
|
|
9
|
+
//
|
|
10
|
+
// Reused pattern: one main package plus per-platform optional packages with
|
|
11
|
+
// `os`/`cpu` constraints, as in `@biomejs/biome` (CJS launcher resolving
|
|
12
|
+
// `<pkg>/biome[.exe]` and spawning it with stdio "inherit") and `ccusage`
|
|
13
|
+
// (explicit unsupported-platform error, exit-code forwarding, re-raising the
|
|
14
|
+
// child's termination signal, repairing the run-time executable bit). Like
|
|
15
|
+
// Biome the launcher is CJS with `spawnSync`, so `require.resolve` works
|
|
16
|
+
// verbatim on npm, pnpm and Bun; like ccusage a killed child re-raises the
|
|
17
|
+
// same signal on this process instead of silently mapping it to exit 0.
|
|
18
|
+
"use strict";
|
|
19
|
+
|
|
20
|
+
const { spawnSync } = require("node:child_process");
|
|
21
|
+
const { chmodSync, statSync } = require("node:fs");
|
|
22
|
+
|
|
23
|
+
// Test-only overrides (documented for launcher verification, e.g.
|
|
24
|
+
// `AGENTFLEX_PLATFORM=freebsd AGENTFLEX_ARCH=x64 npx agentflex` must print
|
|
25
|
+
// the unsupported-platform line below and exit 1).
|
|
26
|
+
const OVERRIDE_PLATFORM = process.env.AGENTFLEX_PLATFORM || undefined;
|
|
27
|
+
const OVERRIDE_ARCH = process.env.AGENTFLEX_ARCH || undefined;
|
|
28
|
+
|
|
29
|
+
// platform -> arch -> { package, file }
|
|
30
|
+
const PLATFORMS = {
|
|
31
|
+
darwin: {
|
|
32
|
+
arm64: { package: "agentflex-darwin-arm64", file: "bin/agentflex" },
|
|
33
|
+
x64: { package: "agentflex-darwin-x64", file: "bin/agentflex" },
|
|
34
|
+
},
|
|
35
|
+
linux: {
|
|
36
|
+
arm64: { package: "agentflex-linux-arm64", file: "bin/agentflex" },
|
|
37
|
+
x64: { package: "agentflex-linux-x64", file: "bin/agentflex" },
|
|
38
|
+
},
|
|
39
|
+
win32: {
|
|
40
|
+
arm64: { package: "agentflex-win32-arm64", file: "bin/agentflex.exe" },
|
|
41
|
+
x64: { package: "agentflex-win32-x64", file: "bin/agentflex.exe" },
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const SUPPORTED = "darwin (arm64, x64), linux (x64, arm64), win32 (x64, arm64)";
|
|
46
|
+
|
|
47
|
+
function currentTarget() {
|
|
48
|
+
return {
|
|
49
|
+
platform: OVERRIDE_PLATFORM || process.platform,
|
|
50
|
+
arch: OVERRIDE_ARCH || process.arch,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Every failure is one clear English line on stderr, exit code 1.
|
|
55
|
+
function fail(message) {
|
|
56
|
+
process.stderr.write(`agentflex: ${message}\n`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function ensureExecutable(path, platform) {
|
|
61
|
+
if (platform === "win32") {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
if ((statSync(path).mode & 0o111) !== 0) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
chmodSync(path, 0o755);
|
|
69
|
+
} catch {
|
|
70
|
+
// Leave the error to spawn reporting below.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function main() {
|
|
75
|
+
const { platform, arch } = currentTarget();
|
|
76
|
+
const target = `${platform}-${arch}`;
|
|
77
|
+
const entry = Object.prototype.hasOwnProperty.call(PLATFORMS, platform)
|
|
78
|
+
? PLATFORMS[platform][arch]
|
|
79
|
+
: undefined;
|
|
80
|
+
if (!entry) {
|
|
81
|
+
fail(`unsupported platform ${target}; supported platforms: ${SUPPORTED}.`);
|
|
82
|
+
}
|
|
83
|
+
let binary;
|
|
84
|
+
try {
|
|
85
|
+
binary = require.resolve(`${entry.package}/${entry.file}`);
|
|
86
|
+
} catch {
|
|
87
|
+
fail(
|
|
88
|
+
`package "${entry.package}" for ${target} is not installed (reinstall agentflex with optional dependencies enabled); supported platforms: ${SUPPORTED}.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
ensureExecutable(binary, platform);
|
|
92
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
93
|
+
if (result.error) {
|
|
94
|
+
fail(`cannot run "${entry.package}" for ${target}: ${result.error.message}.`);
|
|
95
|
+
}
|
|
96
|
+
if (result.signal) {
|
|
97
|
+
// Re-raise so callers observe the same termination signal.
|
|
98
|
+
try {
|
|
99
|
+
process.kill(process.pid, result.signal);
|
|
100
|
+
} catch {
|
|
101
|
+
// Fall through to exit(1) when re-raising is impossible.
|
|
102
|
+
}
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
process.exit(result.status === null || result.status === undefined ? 1 : result.status);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentflex",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Animated, shareable card of your coding-agent week (terminal + PNG export)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/corral-dev/agentflex.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/corral-dev/agentflex#readme",
|
|
11
|
+
"bin": {
|
|
12
|
+
"agentflex": "./bin/agentflex.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"optionalDependencies": {
|
|
19
|
+
"agentflex-darwin-arm64": "0.1.0",
|
|
20
|
+
"agentflex-darwin-x64": "0.1.0",
|
|
21
|
+
"agentflex-linux-arm64": "0.1.0",
|
|
22
|
+
"agentflex-linux-x64": "0.1.0",
|
|
23
|
+
"agentflex-win32-arm64": "0.1.0",
|
|
24
|
+
"agentflex-win32-x64": "0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
}
|
|
29
|
+
}
|