Skip to content

Commit d97d0e3

Browse files
committed
docs: add local development guide for testing plugins before publishing
1 parent aa20989 commit d97d0e3

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

docs/plugin-development.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,98 @@ assert(usage.cost?.actual?.total === 12.34);
498498
| `createMockHttpClient({ mocks })` | HTTP client that returns canned responses |
499499
| `createMockStorage(initial)` | In-memory KV store |
500500

501+
## Local Development
502+
503+
Before publishing to npm, you'll want to run your plugin inside tokentop to see it working end-to-end. There are three ways to load a local plugin.
504+
505+
### Option 1: The `--plugin` flag (quickest)
506+
507+
Point tokentop at your plugin's directory (or file) for a single run:
508+
509+
```bash
510+
# Load a directory-based plugin (resolves entry point automatically)
511+
ttop --plugin ./my-plugin
512+
513+
# Load a single-file plugin
514+
ttop --plugin ./my-theme.ts
515+
516+
# Load multiple plugins at once
517+
ttop --plugin ./my-provider --plugin ./my-theme.ts
518+
```
519+
520+
This is the fastest way to iterate. The flag is repeatable and accepts both absolute and relative paths.
521+
522+
### Option 2: The config file (`plugins.local`)
523+
524+
For plugins you're actively developing, add the path to your tokentop config so it loads every time you start `ttop`:
525+
526+
```json
527+
// ~/.config/tokentop/config.json
528+
{
529+
"plugins": {
530+
"local": [
531+
"~/development/my-tokentop-provider",
532+
"~/development/my-tokentop-theme/src/index.ts"
533+
]
534+
}
535+
}
536+
```
537+
538+
Paths support tilde expansion (`~/...`) and can be absolute or relative to the config directory. Each entry can be a directory or a direct file path.
539+
540+
### Option 3: The plugins directory
541+
542+
Drop your plugin (file or directory) into the default plugins directory:
543+
544+
```
545+
~/.config/tokentop/plugins/
546+
├── my-theme.ts # Single-file plugin
547+
└── my-provider/ # Directory-based plugin
548+
├── package.json
549+
└── src/
550+
└── index.ts
551+
```
552+
553+
tokentop auto-discovers everything in this directory on startup. Files must end in `.ts` or `.js`. Directories are resolved using the entry point rules below.
554+
555+
### Entry point resolution
556+
557+
When you point tokentop at a directory, it resolves the entry point in this order:
558+
559+
1. `package.json``main` field, then `exports["."]`
560+
2. `src/index.ts`
561+
3. `src/index.js`
562+
4. `index.ts`
563+
5. `index.js`
564+
6. `dist/index.js`
565+
566+
For most plugins, having `"main": "src/index.ts"` in your `package.json` is all you need.
567+
568+
### Recommended workflow
569+
570+
```bash
571+
# 1. Create your plugin
572+
mkdir tokentop-provider-replicate && cd tokentop-provider-replicate
573+
bun init
574+
bun add @tokentop/plugin-sdk
575+
576+
# 2. Write your plugin in src/index.ts (see examples above)
577+
578+
# 3. Run your tests with the SDK test harness
579+
bun test
580+
581+
# 4. Load it in tokentop to verify end-to-end
582+
ttop --plugin .
583+
584+
# 5. When it works, publish to npm
585+
npm publish
586+
```
587+
588+
### Tips
589+
590+
- **Validation errors appear in the console.** If your plugin fails to load, tokentop logs the specific validation error (missing fields, wrong `apiVersion`, etc.).
591+
- **Disable a plugin without removing it.** Add its `id` to `config.plugins.disabled` to skip loading without deleting the path from `plugins.local`.
592+
- **Combine methods freely.** Auto-discovered plugins, `plugins.local` paths, and `--plugin` flags all merge together. Duplicates are handled gracefully.
501593
## Publishing to npm
502594

503595
### Package Name Convention

0 commit comments

Comments
 (0)