@jameslovespancakes/pi-plus 1.0.5 → 1.0.7
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 +1 -1
- package/package.json +2 -4
- package/CHANGELOG.md +0 -119
- package/config/pi-plus.example.json +0 -60
- package/images/pi-plus.svg +0 -10
- package/src/core/anthropic/vendor/README.md +0 -36
- package/src/vendor/anthropic.ts +0 -109
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**Everything [pi](https://pi.dev/) is missing, in one install.**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@jameslovespancakes/pi-plus)
|
|
8
|
-
[](https://github.com/jameslovespancakes/pi-plus/actions/workflows/release.yml)
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://pi.dev/packages)
|
|
11
11
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jameslovespancakes/pi-plus",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Consolidated pi extensions: Claude subscription accounts and quota HUD, benchmark-driven model catalog and billing policy, live agent board, and capacity-gated remote test workers.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,11 +24,9 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"src",
|
|
27
|
+
"!src/core/anthropic/vendor/README.md",
|
|
27
28
|
"server",
|
|
28
29
|
"config/skills",
|
|
29
|
-
"config/pi-plus.example.json",
|
|
30
|
-
"images",
|
|
31
|
-
"CHANGELOG.md",
|
|
32
30
|
"README.md",
|
|
33
31
|
"LICENSE"
|
|
34
32
|
],
|
package/CHANGELOG.md
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project are documented here.
|
|
4
|
-
|
|
5
|
-
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
-
and versions follow an odometer scheme: patch rolls into minor at 100, minor
|
|
7
|
-
rolls into major at 10.
|
|
8
|
-
|
|
9
|
-
## [Unreleased]
|
|
10
|
-
|
|
11
|
-
## [1.0.5] - 2026-09-19
|
|
12
|
-
|
|
13
|
-
### Changed
|
|
14
|
-
|
|
15
|
-
- The README shows each interface as text rather than a screenshot. The blocks
|
|
16
|
-
are generated from the real renderers with dummy data, so they cannot drift
|
|
17
|
-
from the code the way the screenshots had, and they stay readable in a
|
|
18
|
-
terminal, a diff and on npm.
|
|
19
|
-
|
|
20
|
-
### Removed
|
|
21
|
-
|
|
22
|
-
- The five demo screenshots. Only the project mark remains, which takes the
|
|
23
|
-
published package from 489KB to 375KB.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## [1.0.4] - 2026-09-19
|
|
27
|
-
|
|
28
|
-
### Changed
|
|
29
|
-
|
|
30
|
-
- The README leads with the mark alone instead of repeating the name beneath
|
|
31
|
-
it, and credits the Anthropic provider correctly: it was adopted from
|
|
32
|
-
`@cortexkit/pi-anthropic-auth` and has since been reimplemented here.
|
|
33
|
-
|
|
34
|
-
### Added
|
|
35
|
-
|
|
36
|
-
- A disclaimer covering provider terms of service.
|
|
37
|
-
|
|
38
|
-
## [1.0.3] - 2026-09-19
|
|
39
|
-
|
|
40
|
-
### Added
|
|
41
|
-
|
|
42
|
-
- A `CHANGELOG.md`, and GitHub releases whose notes are generated from it.
|
|
43
|
-
`scripts/changelog.mjs --promote` retitles `## [Unreleased]` as the new
|
|
44
|
-
version at release time, so entries are written without needing to know the
|
|
45
|
-
next version number.
|
|
46
|
-
|
|
47
|
-
## [1.0.2] - 2026-09-19
|
|
48
|
-
|
|
49
|
-
### Fixed
|
|
50
|
-
|
|
51
|
-
- Release tags now reach the remote. `git tag` creates a lightweight tag and
|
|
52
|
-
`git push --follow-tags` pushes only annotated ones, so every tag was
|
|
53
|
-
silently dropped while the job still reported success.
|
|
54
|
-
- The release job name no longer renders twice. GitHub prefixes a reusable
|
|
55
|
-
workflow's job name with the caller's, so naming both produced
|
|
56
|
-
`Lint / Typecheck / Tests / Lint / Typecheck / Tests`.
|
|
57
|
-
|
|
58
|
-
## [1.0.1] - 2026-09-19
|
|
59
|
-
|
|
60
|
-
### Added
|
|
61
|
-
|
|
62
|
-
- Releases are gated on lint, typecheck and tests as a separate job.
|
|
63
|
-
Publishing cannot begin unless every check passes, rather than relying on
|
|
64
|
-
step ordering inside one job.
|
|
65
|
-
|
|
66
|
-
### Changed
|
|
67
|
-
|
|
68
|
-
- CI and release run on Node 24, which ships the npm 11.5.1+ required for
|
|
69
|
-
trusted publishing.
|
|
70
|
-
- `actions/checkout` and `actions/setup-node` upgraded to v5; v4 targets the
|
|
71
|
-
deprecated Node 20 runtime.
|
|
72
|
-
|
|
73
|
-
## [1.0.0] - 2026-09-19
|
|
74
|
-
|
|
75
|
-
First published release.
|
|
76
|
-
|
|
77
|
-
### Added
|
|
78
|
-
|
|
79
|
-
- **Subscription accounts.** Multiple Anthropic and Codex subscriptions in one
|
|
80
|
-
pool, with quota-aware routing. `/accounts` lists every provider's accounts
|
|
81
|
-
and toggles them in place; `/accounts add` and `/accounts rename` run as
|
|
82
|
-
wizards.
|
|
83
|
-
- **Codex multi-account.** PKCE OAuth, per-account quota from `x-codex-*`
|
|
84
|
-
response headers, and duplicate detection by ChatGPT account id so two
|
|
85
|
-
entries cannot share one quota pool.
|
|
86
|
-
- **Quota from response headers.** Anthropic reports utilisation on every
|
|
87
|
-
reply, so the account serving traffic refreshes at no request cost. Idle
|
|
88
|
-
accounts are polled at most once per 10 minutes, triggered by sending a
|
|
89
|
-
message rather than a timer.
|
|
90
|
-
- **Usage HUD.** Pooled 5h, weekly and per-model tiers for Claude, and 5h and
|
|
91
|
-
weekly for Codex, served from cached snapshots.
|
|
92
|
-
- **Model catalogue and billing policy.** `/models`, `/model-info` and
|
|
93
|
-
`/provider` with benchmark-driven selection and an approval gate.
|
|
94
|
-
- **Agent board.** `/board` for live cross-agent messaging.
|
|
95
|
-
- **Remote workers.** `/remote` for capacity-gated test and build workers.
|
|
96
|
-
- **Own the Anthropic provider.** OAuth, routing, quota and client identity
|
|
97
|
-
are implemented in this repository rather than pulled from a dependency.
|
|
98
|
-
|
|
99
|
-
### Fixed
|
|
100
|
-
|
|
101
|
-
- The account list and `/usage` both returned empty because they still
|
|
102
|
-
imported a package that had been removed during the provider extraction.
|
|
103
|
-
The failure was swallowed, so it looked like "no accounts" rather than an
|
|
104
|
-
error.
|
|
105
|
-
- Cached usage rows omitted `checkedAt`, so freshness checks discarded every
|
|
106
|
-
one and the HUD read `unknown/stale` with no bars.
|
|
107
|
-
- The provider picker redrew the whole screen on each toggle. It now updates
|
|
108
|
-
in place inside pi's own inline chrome.
|
|
109
|
-
- Scoped per-model limits were labelled from Anthropic's internal id, which
|
|
110
|
-
truncated to `claude` and named neither the window nor the model. They now
|
|
111
|
-
show the model family, for example `Fable`.
|
|
112
|
-
|
|
113
|
-
[Unreleased]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.5...HEAD
|
|
114
|
-
[1.0.5]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.4...v1.0.5
|
|
115
|
-
[1.0.4]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.3...v1.0.4
|
|
116
|
-
[1.0.3]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.2...v1.0.3
|
|
117
|
-
[1.0.2]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.1...v1.0.2
|
|
118
|
-
[1.0.1]: https://github.com/jameslovespancakes/pi-plus/compare/v1.0.0...v1.0.1
|
|
119
|
-
[1.0.0]: https://github.com/jameslovespancakes/pi-plus/releases/tag/v1.0.0
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"ARTIFICIAL_ANALYSIS_API_KEY": "<artificial-analysis-api-key>",
|
|
4
|
-
"AGENT_BOARD_URL": "ws://<board-host>:8787/ws",
|
|
5
|
-
"AGENT_BOARD_TOKEN": "<agent-board-token>",
|
|
6
|
-
"AGENT_BOARD_NAME": "you"
|
|
7
|
-
},
|
|
8
|
-
"policy": {
|
|
9
|
-
"autoApprove": [
|
|
10
|
-
"anthropic/*",
|
|
11
|
-
"openai-codex/*",
|
|
12
|
-
"openrouter/stealth/union-alpha"
|
|
13
|
-
],
|
|
14
|
-
"requireApproval": [
|
|
15
|
-
"openrouter/*",
|
|
16
|
-
"google/*",
|
|
17
|
-
"openai/*",
|
|
18
|
-
"xai/*"
|
|
19
|
-
],
|
|
20
|
-
"deny": []
|
|
21
|
-
},
|
|
22
|
-
"remote": {
|
|
23
|
-
"injectStatus": true,
|
|
24
|
-
"defaults": {
|
|
25
|
-
"cpuBlockPercent": 90,
|
|
26
|
-
"gpuBlockPercent": 90,
|
|
27
|
-
"gpuMemoryBlockPercent": 90,
|
|
28
|
-
"memoryBlockPercent": 90,
|
|
29
|
-
"minimumFreeDiskGB": 10,
|
|
30
|
-
"statusCacheSeconds": 30,
|
|
31
|
-
"retentionHours": 24
|
|
32
|
-
},
|
|
33
|
-
"workers": [
|
|
34
|
-
{
|
|
35
|
-
"name": "mac-mini",
|
|
36
|
-
"ssh": "mac-mini",
|
|
37
|
-
"root": "~/remote_tests",
|
|
38
|
-
"nice": 10,
|
|
39
|
-
"tags": [
|
|
40
|
-
"macos",
|
|
41
|
-
"arm64",
|
|
42
|
-
"gpu",
|
|
43
|
-
"metal"
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"name": "hyperion",
|
|
48
|
-
"ssh": "hyperion",
|
|
49
|
-
"root": "~/remote_tests",
|
|
50
|
-
"nice": 10,
|
|
51
|
-
"tags": [
|
|
52
|
-
"linux",
|
|
53
|
-
"x64",
|
|
54
|
-
"gpu",
|
|
55
|
-
"cuda"
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
}
|
package/images/pi-plus.svg
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
|
|
3
|
-
<!-- Original Pi logo paths, unchanged -->
|
|
4
|
-
<path fill="#F09082" d="M165.29 165.29H517.36V400H400V282.65H165.29Z"/>
|
|
5
|
-
<path fill="#4D9ABF" d="M165.29 282.65H282.65V400H400V517.36H282.65V634.72H165.29Z"/>
|
|
6
|
-
<path fill="#F1BE58" d="M517.36 400H634.72V634.72H517.36Z"/>
|
|
7
|
-
|
|
8
|
-
<!-- Plus mark, matching the logo's square/pixel geometry -->
|
|
9
|
-
<path fill="#F09082" d="M697.84 223.97H736.96V263.09H776.08V302.21H736.96V341.33H697.84V302.21H658.72V263.09H697.84Z"/>
|
|
10
|
-
</svg>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Vendored: xxhash-wasm
|
|
2
|
-
|
|
3
|
-
`xxhash-wasm.js` is the ESM build of [xxhash-wasm](https://github.com/jungomi/xxhash-wasm),
|
|
4
|
-
MIT licensed (see `xxhash-wasm.LICENSE.md`), copied in verbatim.
|
|
5
|
-
|
|
6
|
-
## Why vendored rather than depended on
|
|
7
|
-
|
|
8
|
-
The billing checksum in `../client-identity.ts` needs xxHash64. Two things were
|
|
9
|
-
tried before this:
|
|
10
|
-
|
|
11
|
-
1. **A hand-written BigInt implementation.** It produced correct values for
|
|
12
|
-
empty and very short inputs and wrong values for everything longer. Four
|
|
13
|
-
separate bugs were found and fixed, each time with the output still wrong.
|
|
14
|
-
Guessing further at a hash function was not converging.
|
|
15
|
-
2. **`xxhash-wasm` as an npm dependency.** Rejected: the point of the extraction
|
|
16
|
-
is that no unaudited package sits in the auth path.
|
|
17
|
-
|
|
18
|
-
Vendoring gets both: the algorithm is known-correct, and the code lives in this
|
|
19
|
-
repository with no install-time dependency.
|
|
20
|
-
|
|
21
|
-
## What this is
|
|
22
|
-
|
|
23
|
-
A single self-contained ~11 KB `.js` file with the compiled WebAssembly inlined
|
|
24
|
-
as a byte array. It is not fetched, built, or downloaded at runtime. The only
|
|
25
|
-
import is the file itself.
|
|
26
|
-
|
|
27
|
-
## Regenerating
|
|
28
|
-
|
|
29
|
-
```sh
|
|
30
|
-
npm pack xxhash-wasm@<version>
|
|
31
|
-
tar -xzf xxhash-wasm-*.tgz
|
|
32
|
-
cp package/esm/xxhash-wasm.js src/core/anthropic/vendor/
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Record the version when you do. The current copy came from `xxhash-wasm` as
|
|
36
|
-
installed by pi's own tree on 2026-09-19.
|
package/src/vendor/anthropic.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { pathToFileURL } from "node:url";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The single import point for `@cortexkit/anthropic-auth-core`.
|
|
7
|
-
*
|
|
8
|
-
* Nothing else in this repo may reach into the pi-managed npm tree. The old
|
|
9
|
-
* code hardcoded `../npm/node_modules/@cortexkit/...` relative to the
|
|
10
|
-
* extension file, which broke whenever an extension moved directory depth.
|
|
11
|
-
* Resolving from the agent dir at runtime makes placement irrelevant.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
function agentDir(): string {
|
|
15
|
-
return process.env.PI_AGENT_DIR ?? join(homedir(), ".pi", "agent");
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function coreEntry(): string {
|
|
19
|
-
return pathToFileURL(
|
|
20
|
-
join(agentDir(), "npm", "node_modules", "@cortexkit", "anthropic-auth-core", "dist", "index.js"),
|
|
21
|
-
).href;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface AnthropicAccount {
|
|
25
|
-
id: string;
|
|
26
|
-
label?: string;
|
|
27
|
-
type: string;
|
|
28
|
-
enabled?: boolean;
|
|
29
|
-
access?: string;
|
|
30
|
-
refresh?: string;
|
|
31
|
-
expires?: number;
|
|
32
|
-
addedAt?: number;
|
|
33
|
-
lastRefreshedAt?: number;
|
|
34
|
-
authLineageId?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface AccountStorage {
|
|
38
|
-
accounts: AnthropicAccount[];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface AnthropicCore {
|
|
42
|
-
addAccountPersistent(account: AnthropicAccount, path: string): Promise<void>;
|
|
43
|
-
loadAccounts(path: string): Promise<AccountStorage | undefined>;
|
|
44
|
-
authorize(mode: string): Promise<{ url: string; verifier: string; redirectUri: string; state: string }>;
|
|
45
|
-
exchange(
|
|
46
|
-
callback: string,
|
|
47
|
-
verifier: string,
|
|
48
|
-
redirectUri: string,
|
|
49
|
-
state: string,
|
|
50
|
-
): Promise<{ type: string; access: string; refresh: string; expires: number }>;
|
|
51
|
-
refreshClaudeOAuthToken(options: {
|
|
52
|
-
refreshToken: string;
|
|
53
|
-
maxRetries?: number;
|
|
54
|
-
fetchImpl?: typeof fetch;
|
|
55
|
-
}): Promise<{ access: string; refresh: string; expires: number }>;
|
|
56
|
-
getRoutingMode(storage: unknown): string;
|
|
57
|
-
setRoutingMode(mode: string, path: string): Promise<unknown>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let cached: Promise<AnthropicCore> | undefined;
|
|
61
|
-
|
|
62
|
-
/** Lazily loads and memoizes the vendor core module. */
|
|
63
|
-
export function core(): Promise<AnthropicCore> {
|
|
64
|
-
cached ??= import(coreEntry()).then((module) => module as unknown as AnthropicCore).catch((error) => {
|
|
65
|
-
cached = undefined;
|
|
66
|
-
throw new Error(
|
|
67
|
-
`@cortexkit/anthropic-auth-core is unavailable (${error instanceof Error ? error.message : String(error)}). `
|
|
68
|
-
+ "Reinstall with: pi package add @cortexkit/pi-anthropic-auth",
|
|
69
|
-
);
|
|
70
|
-
});
|
|
71
|
-
return cached;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Where the multi-account OAuth store lives. */
|
|
75
|
-
export function accountStoragePath(): string {
|
|
76
|
-
return process.env.PI_ANTHROPIC_AUTH_FILE ?? join(agentDir(), "anthropic-auth.json");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export async function loadAccounts(): Promise<AccountStorage | undefined> {
|
|
80
|
-
return (await core()).loadAccounts(accountStoragePath());
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function saveAccount(account: AnthropicAccount): Promise<void> {
|
|
84
|
-
return (await core()).addAccountPersistent(account, accountStoragePath());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export async function refreshToken(
|
|
88
|
-
refreshTokenValue: string,
|
|
89
|
-
options: { maxRetries?: number; timeoutMs?: number } = {},
|
|
90
|
-
): Promise<{ access: string; refresh: string; expires: number }> {
|
|
91
|
-
const { refreshClaudeOAuthToken } = await core();
|
|
92
|
-
return refreshClaudeOAuthToken({
|
|
93
|
-
refreshToken: refreshTokenValue,
|
|
94
|
-
maxRetries: options.maxRetries,
|
|
95
|
-
fetchImpl: options.timeoutMs
|
|
96
|
-
? (input, init) => fetch(input, { ...init, signal: AbortSignal.timeout(options.timeoutMs!) })
|
|
97
|
-
: undefined,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export async function routingMode(): Promise<string> {
|
|
102
|
-
const { getRoutingMode } = await core();
|
|
103
|
-
return getRoutingMode(await loadAccounts());
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export async function setRoutingMode(mode: "sticky-balanced" | "main-first"): Promise<string> {
|
|
107
|
-
const { setRoutingMode: apply, getRoutingMode } = await core();
|
|
108
|
-
return getRoutingMode(await apply(mode, accountStoragePath()));
|
|
109
|
-
}
|