Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ _export/
.vscode/
.idea/
page_tmp.html

# Plugin directory ZIP (scripts/pack-plugin.mjs)
dist-plugin/
19 changes: 17 additions & 2 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@ local files only:

every write is triggered by a command you ran. no background writes, no opportunistic writes.

- **`.sipcode/` artifacts in your repo** — manifest, receipts (HTML + PNG), stats HTML, badge JSON, score HTML, benchmark HTML.
- **`.sipcode/` artifacts in your repo**: manifest, receipts (HTML + PNG), stats HTML, badge JSON, score HTML, benchmark HTML, and `install-state.json` (when you last ran `rules --install` or `hygiene --install`, and the rules mode, used by `impact`).
- **one named sub-block in your `CLAUDE.md`** — between recognizable markers. `sipcode rules --uninstall` reverses it byte-identically.
- **optional entries in `~/.claude/settings.json`** — ONLY when you run `sipcode hygiene --install`. never otherwise. `--uninstall` removes them.
- **optional hook scripts at `~/.claude/hooks/sipcode-*.mjs`** — same gate. these scripts also run zero-network; the privacy guard test scans them too.
- **the proxy hook: `~/.claude/hooks/sipcode-proxy.mjs` plus its entry in `~/.claude/settings.json`**, only when you run `sipcode proxy --install` or `sipcode init` (skip it with `init --no-proxy`). `sipcode proxy --uninstall` removes it. it runs inside Claude Code before each tool call, reads and writes only local files, and makes no network calls.
- **local caches under `~/.sipcode/`**, written by the commands that use them, so repeat runs do not re-read every log:
- `~/.sipcode/usage-cache/claude-code.json` and `~/.sipcode/usage-cache/codex.json` (`today`, `forecast`, `limits`, `regress`): for each session log, its size and modified time plus token counts, model names, timestamps, request ids, each Claude Code request's version and entrypoint and whether it followed a tool result, the session's working folder and the paths of files the agent read. never message text, prompts, file contents or command output.
- `~/.sipcode/drift/sessions-v3.jsonl` (`drift`): per-session metrics (session id, end time, token counts, cache-hit rate, duplicate-read tokens, and the project folder as a readable encoded name such as `C--Projects-app`). `~/.sipcode/drift/configs.jsonl` keeps the names of your Claude Code MCP servers over time, so drift can say when a change lines up with a regression. an older `~/.sipcode/drift/sessions.jsonl` from before v1.7.0 is no longer used and can be deleted.
- none of these are ever uploaded. to remove them, delete the folder (for example `rm -rf ~/.sipcode/usage-cache ~/.sipcode/drift`). they are rebuilt on the next run; the only cost is a slower first run.
- `~/.sipcode/proxy-reads/<session-id>.jsonl` (the proxy hook's re-read check, Claude Code only): for each file Claude read in that session, its path, a sha256 hash of its contents, modified time, size, a rough token estimate, the turn and the time it was first read. never the file contents. a `<session-id>.warmed` marker beside it records that the cache was filled once from the session transcript.
- `~/.sipcode/proxy-stats/proxy-stats-*.jsonl` (the proxy hook, read by `sipcode proxy --stats`): one line per rewritten or deduplicated tool call, with its time, the tool name, which rewriter acted, the estimated tokens saved and an integrity score. never the command output.
- `~/.sipcode/proxy-signals/<session-id>.jsonl` (the proxy hook, Claude Code only): the search patterns Claude sent to Grep, Glob or a grep command in that session, with the tool name and the time, so a later read can return only the matching symbols.
- `~/.sipcode/install-pending.json`: written only when `sipcode init` runs while a Claude Code session is active; it holds the hook script and settings paths so the next quiet `sipcode` command can finish the proxy install. it is removed once applied.
- `~/.sipcode/benchmark-live/results.jsonl`: written only when you run `sipcode benchmark --vs-rtk --live`; one line per run with the task id, condition, model, token counts, the cost Claude Code reported and the duration. that command runs `claude --print`, which uses your Claude account and the network the way Claude Code always does.
- `~/.sipcode/.star-nudge`: a marker file (its only content is `sipcode-star-nudge/1`) so the one-time "star on GitHub" line after `proxy --stats` is shown only once per machine.
- none of these are ever uploaded. to remove them, delete the folder (for example `rm -rf ~/.sipcode/usage-cache ~/.sipcode/drift`, or all of `~/.sipcode`). they are rebuilt on the next run; the only cost is a slower first run.
- **the receipt PNG is copied to your system clipboard** — ONLY when you run `sipcode receipt`, never silently. via the OS's standard clipboard tool, locally.

## What sipcode never does without you running a command
Expand All @@ -58,6 +65,14 @@ every command file in `src/commands/` also imports a marker constant `ASSERT_NO_

the guarantee covers **sipcode's own code paths**. it does not extend to third-party libraries (chalk, commander, prompts, etc.), to claude code itself, or to your shell / OS / editor. we publish the test and the source so you can re-verify.

two commands start another program that uses the network, and only when you run them: `sipcode update --run` runs `npm i -g sipcode@latest` (npm downloads the new version), and `sipcode benchmark --vs-rtk --live` runs `claude --print`. without `--run`, `sipcode update` only prints the npm command.

## This website

the website (anuj7411.github.io/sipcode) is separate from the CLI and the plugin. it is hosted on GitHub Pages and counts page views with Umami Cloud, which does not set cookies and records page-level data such as the page address, referring site, browser, operating system, screen size and language. the page loads fonts from Google Fonts and the Product Hunt badge image from Product Hunt, so those services and GitHub receive your browser's request (including your IP address) under their own privacy policies. nothing the CLI or the plugin does is sent to the website.

the web version of this document is at https://anuj7411.github.io/sipcode/privacy/.

## Future telemetry

if a cloud feature ever ships, it will be:
Expand Down
131 changes: 131 additions & 0 deletions docs/plugin-directory/LISTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Sipcode: plugin directory listing kit

Everything the OpenAI plugin directory (shared by ChatGPT and Codex) asks for, filled in.
Most fields are imported from the ZIP's `plugin.json` when you upload it, so you mostly check them instead of typing them.
Source of truth: `plugins/sipcode/plugin.json` (`extensions["com.openai"]`). If a value here and the manifest ever differ, the manifest wins; fix this file.

Requirements are from [Upload and submit your plugin](https://developers.openai.com/plugins/deploy/submission), [Plugin submission errors](https://developers.openai.com/plugins/deploy/submission-errors), [Submit desktop-only plugins](https://developers.openai.com/plugins/deploy/desktop-only) and the [plugin guidelines](https://developers.openai.com/plugins/plugin-guidelines), read on 2026-10-16.

## Submission type

| Question in the portal | Answer |
|---|---|
| With MCP or Skills only | **Skills only** (four skills, no MCP server, no hooks, no apps) |
| Desktop only | Yes. The manifest sets `requires_local_executor: true`, because each skill runs the `sipcode` command on the user's computer. The listing shows a **Desktop only** badge; people install it from the ChatGPT desktop app. |
| Package version | `1.7.5` (same as the npm package) |
| ZIP | `dist-plugin/sipcode-plugin-1.7.5.zip`, built by `node scripts/pack-plugin.mjs` |

## Listing fields

| Field (manifest key) | Limit | Value | Length |
|---|---|---|---|
| Display name (`displayName`) | 30 | `Sipcode` | 7 |
| Short description (`shortDescription`) | 30 | `Spend, limits and regressions` | 29 |
| Long description (`longDescription`) | 4,000 | see below | 1,001 |
| Developer name (`developerName`) | 80 | `Anuj Ojha` (the portal replaces it with the name on your verified identity) | 9 |
| Category (`category`) | one of the list | `Developer Tools` | |
| Capabilities (`capabilities`) | 20 items, 120 chars each | `Read` | |
| Website (`websiteURL`) | HTTPS, 1,024 | https://anuj7411.github.io/sipcode/ | |
| Support (`supportURL`) | HTTPS, 1,024 | https://anuj7411.github.io/sipcode/support/ | |
| Privacy policy (`privacyPolicyURL`) | HTTPS, 1,024 | https://anuj7411.github.io/sipcode/privacy/ | |
| Terms of service (`termsOfServiceURL`) | HTTPS, 1,024 | https://anuj7411.github.io/sipcode/terms/ | |
| Brand color (`brandColor`) | `#RRGGBB`, 2:1 against white | `#5B4FCF` (about 6:1 against white) | |
| Brand color, dark (`brandColorDark`) | optional | not set; the portal derives one | |
| Starter prompts (`defaultPrompt`) | 3, 128 chars each, unique, no @mentions | see below | |
| Logo (`logo`) | square, 48 to 4,096 px, 5 MiB | `./assets/logo.png` | |
| Composer icon (`composerIcon`) | same | `./assets/logo.png` | |
| Screenshots (`screenshots`) | not allowed for skills-only | none (see SCREENSHOTS.md) | |

Valid categories (from `plugin_category_unknown` in the errors reference): Productivity, Creativity, Developer Tools, Business & Operations, Data & Analytics, Communication, Education & Research, Security, Finance, Healthcare, Travel, Entertainment, Other.

The four listing URLs are optional for a skills-only plugin ("Website, privacy policy, terms, and support URLs are optional for skills-only plugins"), but the guidelines require a published privacy policy and support contact, so all four are set. They go live when the `docs/site` change is deployed to GitHub Pages (merging to `main` runs `.github/workflows/deploy-site.yml`). Check each one opens before you submit.

### Long description

Paste exactly (the blank lines are part of it; line breaks are allowed):

```
Sipcode answers questions about your own Codex use from the logs Codex already writes on this computer: how much you spent today or this month (estimated at API prices), how close you are to your usage limits and whether a limit may have shrunk, why a session used so many tokens, and whether Codex or Claude Code got worse after an update. Each answer comes from the Sipcode command-line tool (npm package sipcode), which reads the logs locally and makes no network calls.

Setup: install the tool once with npm i -g sipcode (Node.js 20 or newer; Node.js 22.15 or newer to read the logs Codex compresses). The plugin runs that command on your computer, so it works where Codex can run local commands: Codex in the ChatGPT desktop app and the Codex CLI.

Limitations: dollar figures are estimates at API prices, not your bill. Usage limits cover your whole account, so Codex use on other devices or in the cloud raises the percent without local tokens, and a possible limit cut is a signal, not proof.
```

### Starter prompts

The directory takes at most three. These are in the manifest:

1. `How much did I spend on Codex this month?` (41 characters)
2. `How close am I to my Codex usage limit?` (39)
3. `Did Codex get worse after an update?` (36)

The fourth question does not fit as a starter prompt but works the same way, and the long description names it:

4. `Why was my last Codex session so expensive?`

What each one runs:

| Ask | Skill | Sipcode runs |
|---|---|---|
| How much did I spend on Codex this month? | `sipcode-spend` | `sipcode forecast --agent codex --json` (also `today` and `stats`) |
| How close am I to my Codex usage limit? | `sipcode-limits` | `sipcode limits` |
| Why was my last Codex session so expensive? | `sipcode-why` | `sipcode why --agent codex --json` |
| Did Codex or Claude Code get worse after an update? | `sipcode-regress` | `sipcode regress --bug-report` (this prompt names both tools; a Codex-only question runs `--agent codex`, which takes about a second, and the Claude Code logs are read only when the user asks about Claude Code) |

## Package identity (root of `plugin.json`)

| Field | Value |
|---|---|
| `name` | `sipcode` |
| `version` | `1.7.5` |
| `description` | "Ask about your Codex usage in plain words: spend, usage limits, why a session was expensive, and whether Codex or Claude Code got worse after an update. Runs the Sipcode CLI on this computer, which reads your local Codex and Claude Code logs and makes no network calls." (269 characters) |
| `author.name` / `author.url` | `Anuj Ojha` / https://github.com/Anuj7411 |
| `author.email` | not set (optional). Decision for you, see below. |
| `homepage` | https://anuj7411.github.io/sipcode/ |
| `repository` | https://github.com/Anuj7411/sipcode |
| `license` | `MIT` |
| `keywords` | codex, usage, limits, tokens, spend, regression |

## Logo and icon

| File | Format | Size | Bytes | Used for |
|---|---|---|---|---|
| `plugins/sipcode/assets/logo.png` | PNG | 180 x 180 (square) | 4,004 | `logo` and `composerIcon` |

The spec is "square and at least 48 by 48 pixels", at most 4,096 px and 5 MiB, in PNG, JPEG, WebP or SVG. The current file meets it, so no new icon was made. Optional later: a `logoDark` / `composerIconDark` variant, because the black outline is hard to see on a dark background.

## Skills in the package

| Skill | What it answers |
|---|---|
| `sipcode-spend` | Spend today, this month, the month-end forecast, or a period |
| `sipcode-limits` | How close you are to the 5-hour, weekly or 30-day limit, and whether a limit may have shrunk |
| `sipcode-why` | Why a session used so many tokens |
| `sipcode-regress` | Whether Codex or Claude Code got worse after an update |

Each skill: runs one `sipcode` command, never reads the log files itself, never installs anything, asks the user before re-running with read access when the sandbox blocks `~/.codex`, and tells the user `npm i -g sipcode` when the command is missing.

## Setup required (say this wherever the form allows notes)

- Install the CLI once: `npm i -g sipcode`.
- Node.js 20 or newer. Node.js 22.15 or newer to read the session logs Codex compresses (`.jsonl.zst`); on an older Node.js they are skipped, with a warning.
- Works where Codex can run local commands: Codex in the ChatGPT desktop app and the Codex CLI. Not on ChatGPT web or mobile (hence Desktop only).
- No account, no sign-in, no API key, so there are no reviewer credentials to enter.

## Fields left out on purpose

| Field | Why |
|---|---|
| `review.test_cases`, `review.demo_recording_url` | "Skills-only plugins don't need MCP app review cases or a demo recording." |
| `screenshots` | `screenshot_configuration_excluded`: screenshots need a remote MCP server with custom UI. |
| `onboardingSkill` | Optional. Could later point at a setup skill that checks `sipcode` is installed. |
| `publication.countries` | Omitted: available everywhere the directory is. |
| `publication.release_notes` | Optional; type them in the portal if asked. |
| `test_credentials`, `reviewer_instructions` | Rejected in ZIP metadata. Nothing to sign in to anyway. |

## Decisions for Anuj

- **Support email.** The docs do not require an email: the support URL plus GitHub issues is the support contact. If the portal asks for one, use an address you will read, in place of `SUPPORT_EMAIL_TBD`, and optionally add it as `author.email` in both manifests (the test keeps them identical).
- **Desktop only.** Kept on because the skills cannot work without a local shell. If the portal says `requires_local_executor` is not allowed, the desktop-only page says to send your organization ID to an OpenAI representative; see SUBMIT.md for what to do if you do not have one.
- **Read the terms page** (`docs/site/src/pages/terms.astro`). It is plain words, not legal advice.
35 changes: 35 additions & 0 deletions docs/plugin-directory/SCREENSHOTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Screenshots for the Sipcode plugin

## Do not put screenshots in the ZIP

For a skills-only plugin the directory does not take screenshots:

- Upload check `screenshot_configuration_excluded`: "Remove `interface.screenshots`. Screenshots require **With MCP** and a custom UI." ([submission errors](https://developers.openai.com/plugins/deploy/submission-errors))
- Final submission: "No screenshots, since those require a remote MCP server with custom UI."
- The [plugin guidelines](https://developers.openai.com/plugins/plugin-guidelines) say the directory no longer shows screenshots and to provide example prompts instead. The three starter prompts in the manifest do that job.

So `plugin.json` has no `screenshots` field, and `scripts/pack-plugin.mjs` refuses to build a ZIP if one is added.

## Shots worth taking anyway

For the README, the website, a launch post, or if a reviewer asks how it works. Only you can take these: they show your own Codex app and your own numbers.

Setup for every shot:

- `npm i -g sipcode@latest` first, so the output matches the current release.
- The Sipcode plugin installed (README, "Use Sipcode inside Codex"), the ChatGPT desktop app restarted.
- A **new, empty chat** for each shot (a long chat costs more of your limit and clutters the picture).
- Window about 1600 x 1000, light theme, PNG. Crop to the chat; keep the question and the whole answer in frame.
- Before saving, check nothing private is visible: folder names, project names and session titles in the sidebar can name clients. Collapse the sidebar or crop it out.

| # | Ask, word for word | Must be visible | File name |
|---|---|---|---|
| 1 | `How much did I spend on Codex this month?` | The question, the "ran sipcode" step, the month-to-date and projected month-end amounts, and the line that they are at API prices | `plugin-spend.png` |
| 2 | `How close am I to my Codex usage limit?` | The 5-hour and weekly percents, the reset times in your local time, and the account-wide caveat (other devices and the cloud) | `plugin-limits.png` |
| 3 | `Why was my last Codex session so expensive?` | The session total, the largest requests list, and the output share | `plugin-why.png` |
| 4 | `Did Codex or Claude Code get worse after an update?` | The coverage lines (requests, sessions, dates, versions) and either the findings or "No regressions detected in your logs" | `plugin-regress.png` |
| 5 | (optional) Open **Plugins** in the desktop app | The Sipcode card with its name, short description and icon | `plugin-card.png` |

If the limits answer says "a possible limit cut", keep the word "possible" and the caveat in the crop. Do not crop a number away from its caveat.

Store the files under `docs/screenshots/plugin/` if you want them in the repo, never under `plugins/sipcode/` (that folder is the package).
Loading
Loading