Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
da0e69a
feat(claude/mcp): optional capability filter for genesis-tools MCP
genesiscz Jul 13, 2026
c26a6df
fix(agents): survive repeated shutdown signals without orphaning the …
genesiscz Jul 13, 2026
bc15f8e
fix(agents): bump listener sanity cap to 8h
genesiscz Jul 13, 2026
de07733
fix(jenkins-mcp): stage event duration/status + parallel branch context
genesiscz Jul 13, 2026
81efb07
feat(agents): add --body-file to message command
genesiscz Jul 13, 2026
0003c2d
feat(agents): echo body_length in message command's JSON output
genesiscz Jul 13, 2026
62290fd
docs(agents): document idle-teammate wake asymmetry + dual-channel pr…
genesiscz Jul 13, 2026
bf6f20e
docs(agents): monitor events are dropped for idle teammates, not queued
genesiscz Jul 13, 2026
6db0de8
docs(agents): refine idle-teammate monitor semantics (no wake, no wak…
genesiscz Jul 13, 2026
19006f0
feat(cli): shared port-style box tables in @app/utils/table
genesiscz Jul 14, 2026
349a889
fix(tools): strip socks proxy env when spawning tool children
genesiscz Jul 14, 2026
6c7d370
feat(ai-proxy): xai-api-key provider, live catalogs, cleaner model list
genesiscz Jul 14, 2026
76d8e34
feat(github): stack-safe merge command and smarter 403 rate-limit det…
genesiscz Jul 14, 2026
d067c01
feat(ai): grok-sub account type, env-referenced API keys, explicit su…
genesiscz Jul 15, 2026
ac0b854
feat(youtube): extension side-panel overhaul — shadow-DOM fixes, dev …
genesiscz Jul 15, 2026
1823d38
chore: add puppeteer-core dev-dep for headless extension verification
genesiscz Jul 15, 2026
49a794d
feat(ai): authFile reference mode for openai-sub accounts (Codex CLI …
genesiscz Jul 15, 2026
31338c4
feat(youtube): ask tab, live job progress, shadow-DOM select dismiss,…
genesiscz Jul 15, 2026
8bffeaa
fix(ai): resolve subscription tokens per-request in sub resolvers (40…
genesiscz Jul 15, 2026
85d9376
feat(youtube): themed markdown Ask answers + strip LiteLLM routing pr…
genesiscz Jul 15, 2026
fa0bc35
feat(youtube): users/credits/qa-history DB schema and methods
genesiscz Jul 15, 2026
07a34aa
feat(youtube): users lib with argon2id register/login
genesiscz Jul 15, 2026
22443ad
feat(youtube): user auth guard, users routes, credit-gated LLM endpoints
genesiscz Jul 15, 2026
abd38b7
feat(youtube-ext): user auth messages, token storage, account hooks
genesiscz Jul 15, 2026
7ac1ddb
feat(youtube-ext): settings dialog, diamonds chip, server-backed ask …
genesiscz Jul 15, 2026
067d76f
style(youtube): biome formatting for users tests and types barrel
genesiscz Jul 15, 2026
8934c32
feat(youtube/billing): diamond packs, stripe env accessors, signature…
genesiscz Jul 15, 2026
bcd1dad
feat(youtube/billing): checkout session creation + webhook grant/refu…
genesiscz Jul 15, 2026
b846302
feat(youtube/server): checkout + stripe webhook routes
genesiscz Jul 15, 2026
b41b588
feat(youtube/extension): checkout message/hook + diamonds pack picker UI
genesiscz Jul 15, 2026
2d35604
feat(youtube/usage): ledger-views aggregation lib for the activity da…
genesiscz Jul 15, 2026
7035376
feat(youtube): ledger + usage-summary routes, messages, hooks
genesiscz Jul 15, 2026
8f37b06
feat(youtube/extension): settings "activity · last 30 days" compact b…
genesiscz Jul 15, 2026
6cf5b35
feat(youtube/extension): panel Activity view with reason filters + in…
genesiscz Jul 15, 2026
ce8652b
feat(youtube/shares): migration + shares lib (snapshot, slug, HTML te…
genesiscz Jul 15, 2026
5282fc8
feat(youtube/server): shares CRUD routes + public share page
genesiscz Jul 15, 2026
1d4d655
feat(youtube/extension): share buttons + settings Shares management
genesiscz Jul 15, 2026
9fbb051
feat(youtube/presets): prompt_presets table + CRUD lib
genesiscz Jul 15, 2026
3069477
feat(youtube/presets): prompt injection + presets CRUD routes + prese…
genesiscz Jul 15, 2026
24bd2ad
feat(youtube/extension): Style preset picker in Summary + Ask, preset…
genesiscz Jul 15, 2026
6524a96
feat(youtube/extension): settings Presets section with edit/delete/ex…
genesiscz Jul 15, 2026
7c05da0
feat(youtube): artifact_access table, reuse pricing lib, one-time bac…
genesiscz Jul 15, 2026
14ae9ca
feat(youtube): reuse-priced summary routes — locked GET envelope, POS…
genesiscz Jul 15, 2026
806d181
feat(youtube-ext): locked-artifact envelope plumbing through messages…
genesiscz Jul 15, 2026
2bb177f
feat(youtube-ext): reuse unlock UI — Sparkles confirm variant, locked…
genesiscz Jul 15, 2026
a10f9b5
feat(youtube): qa chunk source tagging, comment thread chunker, polym…
genesiscz Jul 15, 2026
3c42643
feat(youtube): comments-aware qa indexing, merged retrieval with tran…
genesiscz Jul 15, 2026
651c3a1
feat(youtube): qa sources through route, 409 on unfetched comments, e…
genesiscz Jul 15, 2026
ffc226d
feat(youtube-ext): ask scope selector, comment author chips with jump…
genesiscz Jul 15, 2026
de94c61
feat(youtube): channel-ask candidate selection with FTS pre-filter an…
genesiscz Jul 15, 2026
147699e
feat(youtube): channel-scope ask — 10-diamond price, cross-video attr…
genesiscz Jul 15, 2026
b0d6945
feat(youtube-ext): channel ask scope UI, grouped per-video citations,…
genesiscz Jul 15, 2026
504eae1
feat(youtube): multi-video reports — reportSynthesize stage, reports …
genesiscz Jul 15, 2026
dd661b9
feat(youtube-ext): playlist report panel — generate confirm, polling …
genesiscz Jul 15, 2026
16c5b71
style(youtube): biome formatting sync after staged-fix pre-commit runs
genesiscz Jul 15, 2026
294d47b
fix(youtube): keep qa:channel whole in ledger reason grouping
genesiscz Jul 15, 2026
78858b4
feat(youtube): add latest-wins partial throttle helper
genesiscz Jul 15, 2026
4fc47c9
feat(youtube): stream structured summaries via streamObject with thro…
genesiscz Jul 15, 2026
5a09bde
feat(youtube-ext): thread streamed summary partials into the side panel
genesiscz Jul 15, 2026
920c38b
feat(youtube-ext): partial-tolerant summary rendering with skeletons …
genesiscz Jul 15, 2026
2f38a93
feat(youtube): anchor long-summary chapters to transcript timestamps …
genesiscz Jul 15, 2026
3561061
feat(youtube-ext): chapter tick overlay module for the player progres…
genesiscz Jul 15, 2026
dd9f83d
feat(youtube-ext): chapter ticks lifecycle + panel/content window bri…
genesiscz Jul 15, 2026
be01db4
feat(youtube-ext): chapter card seek pills + playing state synced to …
genesiscz Jul 15, 2026
f5ab3ab
feat(youtube): persist Deepgram speaker diarization + speaker-aware p…
genesiscz Jul 15, 2026
6d64a48
feat(youtube): video_speakers label table + PUT /videos/:id/speakers …
genesiscz Jul 15, 2026
42cc631
docs(youtube): reflect chapter startSec/endSec and segment speaker in…
genesiscz Jul 15, 2026
c43a5f8
feat(youtube-ext): editor-grade transcript search (counter, next/prev…
genesiscz Jul 15, 2026
360cf71
feat(youtube-ext): transcript follow mode synced to playback with man…
genesiscz Jul 15, 2026
d144f63
feat(youtube): speaker chips with inline rename wired through PUT /sp…
genesiscz Jul 15, 2026
2d66170
style(youtube): biome line-width formatting in summary-partials
genesiscz Jul 15, 2026
0e381a5
style(youtube): biome formatting after rebase re-integration
genesiscz Jul 15, 2026
6d6e6da
style(youtube): biome formatting after second rebase re-integration
genesiscz Jul 15, 2026
3049291
feat(youtube): output-language preference + lang plumbing through sum…
genesiscz Jul 15, 2026
282861a
feat(youtube): line-anchored transcript translation endpoint
genesiscz Jul 15, 2026
7840cf4
feat(youtube): generation + transcript language UI (extension)
genesiscz Jul 15, 2026
b681abf
feat(youtube): settings language section + Czech UI catalog
genesiscz Jul 15, 2026
a06ff53
feat(youtube): Audio TL;DR narration, cache/synthesis, Range-capable …
genesiscz Jul 15, 2026
087a7af
feat(youtube): Audio TL;DR mini player + exclusivity bridge
genesiscz Jul 15, 2026
dd78a66
fix(youtube): use \u0000 escapes instead of raw NUL bytes in audio ca…
genesiscz Jul 15, 2026
67b7540
fix(youtube-ext): don't inline-inject panel when #secondary is out-of…
genesiscz Jul 15, 2026
157d611
fix(youtube-ext): stack panel above the live chat, retreat off the pl…
genesiscz Jul 15, 2026
edf3f62
style(youtube-ext): biome one-line format for player selector
genesiscz Jul 15, 2026
9d68e6e
fix(youtube-ext): pin flex:0 0 auto so above-chat panel keeps natural…
genesiscz Jul 15, 2026
8b01f4c
fix(youtube): gate dev top-up endpoint behind YOUTUBE_ALLOW_DEV_TOPUP
genesiscz Jul 15, 2026
e895468
fix(youtube): enforce long-summary artifact access on audio routes
genesiscz Jul 15, 2026
c6740f4
fix(youtube): debit credits atomically before LLM/TTS work, refund on…
genesiscz Jul 15, 2026
19989f7
fix(youtube): review a11y/theme-token/logging batch for extension + s…
genesiscz Jul 15, 2026
9b50884
fix(youtube): per-video lang reset, interval follow mode, streamed ch…
genesiscz Jul 15, 2026
21056d2
fix(youtube): extension dev watcher — shared UI deps, posix paths, de…
genesiscz Jul 15, 2026
ef5bfda
fix(youtube): shared strict safeJsonBody with logging + full-segment …
genesiscz Jul 15, 2026
02db08d
fix(youtube): voice-aware audio URL, lang-aware estimate, preset null…
genesiscz Jul 15, 2026
6f64e57
fix(youtube): track QA jobs under a dedicated qa stage (was mislabele…
genesiscz Jul 15, 2026
d580ff2
fix(ask): make DetectedProvider.subscription required and populate it…
genesiscz Jul 15, 2026
3c524d9
fix(youtube): translate lines mapped by [#id] tags, not array position
genesiscz Jul 15, 2026
eea848f
fix(youtube): merged comment chunks keep every thread root for citations
genesiscz Jul 15, 2026
33eb63e
chore: align @types/jsdom with jsdom 29
genesiscz Jul 15, 2026
59b864f
style(youtube): biome formatting in qa.ts
genesiscz Jul 15, 2026
5eaf47d
fix(youtube): wire confirm dialog's live language into the estimate q…
genesiscz Jul 15, 2026
604675c
feat(ui): register WEB_SERVICES and matchProcess on all ports
genesiscz Jul 15, 2026
9cd2bde
feat(dev-dashboard/ports): batch resolve, kind classify, and identity…
genesiscz Jul 15, 2026
edc130e
feat(dev-dashboard): unified /api/live SSE bus for ports and pulse
genesiscz Jul 15, 2026
7beb84d
feat(dev-dashboard/ui): ports filters, sort, live stream, stable kind…
genesiscz Jul 15, 2026
5c25f43
style: biome format after ports/live commits
genesiscz Jul 15, 2026
67b89b5
feat(utils): expose @genesis/tools-utils pure export map
genesiscz Jul 15, 2026
d312eac
feat(github-merge): add --ff-only true fast-forward with stack retarget
genesiscz Jul 16, 2026
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
1 change: 1 addition & 0 deletions .claude/docs/tool-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ spinner.succeed("Done!");
8. **Add verbose/debug modes** for troubleshooting
9. **Use meaningful exit codes** (0 for success, 1+ for errors)
10. **Test with various input scenarios** including edge cases
11. **Multi-column inventory output** (lists of models, accounts, ports, …): use `@app/utils/table` port-style helpers (`createBoxTable`, `renderCliHeader`, `formatDotStatus`) + `out.println` — not clack `out.log.info` lines. See CLAUDE.md → *CLI inventory tables*. Keep `--json` via `out.result`.

### 5. Testing Your Tool

Expand Down
42 changes: 40 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ When creating a new tool and writing helper functions, check if the utility is *

- `src/utils/format.ts` - Formatting: `formatDuration()`, `formatBytes()`, `formatTokens()`, `formatNumber()`, `formatList()`, `formatTimestamp()`, `createStopwatch()`
- `src/utils/Stopwatch.ts` - High-res stopwatch class: `elapsed()`, `lap()`, `stamp()` (wall-clock + elapsed), `now()` (HH:MM:SS.mmm)
- `src/utils/table.ts` - Text table formatting
- `src/utils/table.ts` - CLI tables: `formatTable()` (plain padded), **`createBoxTable()` / `renderCliHeader()` / `formatDotStatus()`** (port-style boxed inventories via `cli-table3`)
- `src/utils/string.ts` - String utilities (glob matching, ANSI stripping)
- `src/utils/cli/executor.ts` - CLI helpers: `suggestCommand()`, `isInteractive()`, `buildCommand()`, `Executor`, `enhanceHelp()`
- `src/utils/storage/storage.ts` - Config & cache management
Expand Down Expand Up @@ -169,8 +169,9 @@ Most tools follow these common patterns:

- Support multiple output destinations: file, clipboard, stdout
- Use `clipboardy` for clipboard operations
- Use `chalk` for colored terminal output (but strip ANSI codes for non-TTY)
- Use `picocolors` (or `chalk`) for colored terminal output (but strip ANSI codes for non-TTY)
- Respect `--silent` and `--verbose` flags
- **Human inventory lists (models, accounts, ports, processes, …):** do **not** dump multi-column data via clack `out.log.info`. Use the port-style table helpers from `@app/utils/table` + `out.println` — see **CLI inventory tables** below.

**Process Execution**:

Expand Down Expand Up @@ -246,6 +247,35 @@ Two cleanly separated layers (the 2026-05 logger+out overhaul):
- **Every commander entrypoint** ends with `await runTool(program, { tool })` (from `@app/utils/cli`) — it owns `-v`/`--readme`/help registration, console-level resolution, and the `{tool}` log binding, then `parseAsync`. The subprocess **spawner** is `execTool` (renamed from the old `runTool`).
- **`scripts/ci/logging-guard.sh`** enforces this convention repo-wide in CI: no default/extension/relative-path/any-name import of the logger module (root `./tools` and `scripts/` included — not just `src/`), no bare `logger.*(SafeJSON.stringify(…))` result dumps, no reintroduced transitional shims, and that the browser-client isolation test exists. Browser-client trees never value-importing `@app/logger` is authoritatively enforced by `src/logger/client-isolation.test.ts`.
- **`@app/utils/cli/ui` — high-density CLI status.** For tools that emit many short status lines per command (e.g. `tools stash`), clack's `│ ◆ ●` box-drawing is the wrong texture. Import `{ ui }` from `@app/utils/cli/ui` to get plain stderr writes with chalk decoration (`ui.ok/info/warn/err/dim/header/kv/section/raw`). Use this INSTEAD of `out.log.*` for high-density status; keep `out.log.*` for clack-shaped task lifecycles. `out.print()` / `out.result()` are still the only writers to stdout for machine-readable output.
- **CLI inventory tables (port-style) — prefer this for multi-column human output.** Canonical helpers live in `@app/utils/table` (not reimplemented per tool). Reference UIs: `tools port`, `tools ai-proxy models`, `tools macos swap`.

| Need | API | Notes |
|---|---|---|
| Boxed inventory table | `createBoxTable(headers)` | `cli-table3` + shared box chars; `table.push(row)` then `out.println(table.toString())` |
| Title box | `renderCliHeader(title, subtitle)` | Cyan frame via `out.println` |
| Section + key rows | `renderCliSection` / `renderCliKeyRow` | Column legends, detail blocks |
| Status cell | `formatDotStatus("ok"\|"warn"\|"err"\|"dim", label)` | `● ok` / `● fail` coloring |
| Cell truncate | `truncateDisplay(value, max)` | Em dash for empty; `…` ellipsis |
| Plain padded table | `formatTable(rows, headers)` | Dense / non-TTY dumps without box borders |
| Machine-readable | `out.result(...)` + `--json` | Never put JSON through the table path |

Pattern:

```typescript
import { out } from "@app/logger";
import { suggestCommand } from "@app/utils/cli";
import { createBoxTable, formatDotStatus, renderCliHeader, renderCliSection } from "@app/utils/table";
import pc from "picocolors";

renderCliHeader("Proxy Models", "ids clients can call");
const table = createBoxTable(["PROXY ID", "PROBE"]);
table.push([pc.white(id), formatDotStatus("ok", "ok")]);
out.println(table.toString());
renderCliSection("Columns");
// footer: counts · Next/Debug via suggestCommand("tools <tool>", { replaceCommand: [...] })
```

**Do not** hand-roll `new Table({ chars: … })` or copy/paste box-drawing from `src/port/` — import from `@app/utils/table`. Keep domain coloring (framework names, etc.) in the tool's `display.ts`; keep the table chrome shared.

## Claude Agent SDK Types Reference

Expand Down Expand Up @@ -284,6 +314,14 @@ Key SDK type files: `sdk.d.ts` (session/message/streaming types), `sdk-tools.d.t
- **TypeScript Config**: Strict mode enabled, ES modules, no emit (Bun runs TS directly)
- **Logging**: Check `~/.genesis-tools/logs/` for debug information if tools encounter errors

## LLM Model Library & Pricing (one place — do not add new rate tables)

- **Canonical model list + pricing**: `providerManager.detectProviders()` (`src/ask/providers/ProviderManager.ts`) returns `ModelInfo[]` with `pricing?: PricingInfo` (`inputPer1M`/`outputPer1M`, `src/ask/types/provider.ts`). Pricing is populated by `dynamicPricingManager.getPricing(provider, modelId)` (`src/ask/providers/DynamicPricing.ts`), sourced from LiteLLM's `model_prices_and_context_window.json` (cached as `litellm-pricing.json`) + OpenRouter.
- **Cost math (pure)**: `src/utils/ai/llm-cost.ts` — `estimateLlmCallCostUsd({pricing, inputTokens, outputTokens})`, `estimateSpeechTokens(durationSec)`. No rates in there, math only.
- **Deliberate exception**: `src/ai-proxy/lib/billing/pricing.ts` keeps a small STATIC table — it's the ai-proxy client-ledger invoicing source of truth (deterministic, offline). Don't "deduplicate" it into the dynamic path, and don't copy it anywhere else.
- Resolving a user's provider/model choice (default account, `-sub` suffix handling): `resolveProviderChoice()` in `src/youtube/lib/provider-choice.ts` wraps `modelSelector`/`providerManager`.
- **Accounts** live in `~/.genesis-tools/ai/config.json` (`AIConfig`, types in `src/utils/config/ai.types.ts`). Subscription billing is flagged by `DetectedProvider.subscription` (set by the `*SubResolver`s in `src/utils/ai/resolvers/`) — never infer it from name suffixes. API-key accounts may REFERENCE an env var via `tokens.apiKeyEnv` (resolved by `AIConfig.resolveApiKey`, never copied); `grok-sub` accounts reference the Grok CLI auth file via `tokens.authFile` (default `~/.grok/auth.json`, resolved by `resolveGrokSubToken` in `src/utils/ai/grok/account.ts`). ai-proxy's subscription providers bill these same accounts by `accountName` reference.

## Database Infrastructure

- **Storage**: `src/utils/storage/storage.ts` owns per-tool config/cache directories under `~/.genesis-tools/<tool>/`; wrap it with tool-specific subclasses such as `IndexerStorage`.
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ Answer a question, then preserve the Q→A to the local question store so it can

Captured via the `question_answer` MCP tool, falling back to the `tools question record` CLI.

#### genesis-tools MCP server (`tools claude mcp`)

The plugin's own MCP server (stdio) exposes two capabilities: `question_answer` (the Q&A capture tool above) and `boards` (dev-dashboard annotation boards — `boards_list_boards`, `boards_wait_for_work`, `boards_compose_board`, etc.). Both are enabled by default. To restrict which capabilities are registered, set `GENESIS_TOOLS_MCP_CAPABILITIES` to a comma-delimited list of capability names in the server's environment (e.g. in `~/.claude.json`'s `mcpServers.genesis-tools.env`):

```bash
GENESIS_TOOLS_MCP_CAPABILITIES=question_answer,boards # both (default when unset)
GENESIS_TOOLS_MCP_CAPABILITIES=question_answer # only the Q&A tool
GENESIS_TOOLS_MCP_CAPABILITIES=boards # only boards tools
```

---

### Skill Details
Expand Down
10 changes: 10 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@
}
}
},
{
"includes": ["src/youtube/extension/**"],
"linter": {
"rules": {
"style": {
"noRestrictedGlobals": "off"
}
}
}
},
{
"includes": ["**/*.test.ts", "**/*.test.tsx", "**/__tests__/**", "**/*.data.ts"],
"plugins": []
Expand Down
Loading
Loading