@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 CHANGED
@@ -5,7 +5,7 @@
5
5
  **Everything [pi](https://pi.dev/) is missing, in one install.**
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@jameslovespancakes/pi-plus?color=%234D9ABF&label=npm)](https://www.npmjs.com/package/@jameslovespancakes/pi-plus)
8
- [![CI](https://github.com/jameslovespancakes/pi-plus/actions/workflows/ci.yml/badge.svg)](https://github.com/jameslovespancakes/pi-plus/actions/workflows/ci.yml)
8
+ [![build](https://github.com/jameslovespancakes/pi-plus/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/jameslovespancakes/pi-plus/actions/workflows/release.yml)
9
9
  [![license](https://img.shields.io/badge/license-MIT-F1BE58)](LICENSE)
10
10
  [![pi-package](https://img.shields.io/badge/pi--package-F09082)](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.5",
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
- }
@@ -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.
@@ -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
- }