opencode-agora 0.4.0 → 0.4.2
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 +89 -415
- package/dist/atomic-write.d.ts +10 -0
- package/dist/atomic-write.d.ts.map +1 -0
- package/dist/atomic-write.js +23 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/auth/refresh.d.ts +17 -0
- package/dist/auth/refresh.d.ts.map +1 -0
- package/dist/auth/refresh.js +50 -0
- package/dist/auth/refresh.js.map +1 -0
- package/dist/cli/app.d.ts +11 -19
- package/dist/cli/app.d.ts.map +1 -1
- package/dist/cli/app.js +159 -2028
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/browse.d.ts +4 -0
- package/dist/cli/commands/browse.d.ts.map +1 -0
- package/dist/cli/commands/browse.js +80 -0
- package/dist/cli/commands/browse.js.map +1 -0
- package/dist/cli/commands/chat.d.ts +4 -0
- package/dist/cli/commands/chat.d.ts.map +1 -0
- package/dist/cli/commands/chat.js +125 -0
- package/dist/cli/commands/chat.js.map +1 -0
- package/dist/cli/commands/community.d.ts +12 -0
- package/dist/cli/commands/community.d.ts.map +1 -0
- package/dist/cli/commands/community.js +453 -0
- package/dist/cli/commands/community.js.map +1 -0
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +108 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +299 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/learn.d.ts +4 -0
- package/dist/cli/commands/learn.d.ts.map +1 -0
- package/dist/cli/commands/learn.js +62 -0
- package/dist/cli/commands/learn.js.map +1 -0
- package/dist/cli/commands/marketplace.d.ts +9 -0
- package/dist/cli/commands/marketplace.d.ts.map +1 -0
- package/dist/cli/commands/marketplace.js +321 -0
- package/dist/cli/commands/marketplace.js.map +1 -0
- package/dist/cli/commands/notify.d.ts +3 -0
- package/dist/cli/commands/notify.d.ts.map +1 -0
- package/dist/cli/commands/notify.js +59 -0
- package/dist/cli/commands/notify.js.map +1 -0
- package/dist/cli/commands/operations.d.ts +16 -0
- package/dist/cli/commands/operations.d.ts.map +1 -0
- package/dist/cli/commands/operations.js +1041 -0
- package/dist/cli/commands/operations.js.map +1 -0
- package/dist/cli/commands/outdated.d.ts +3 -0
- package/dist/cli/commands/outdated.d.ts.map +1 -0
- package/dist/cli/commands/outdated.js +48 -0
- package/dist/cli/commands/outdated.js.map +1 -0
- package/dist/cli/commands/ping.d.ts +3 -0
- package/dist/cli/commands/ping.d.ts.map +1 -0
- package/dist/cli/commands/ping.js +56 -0
- package/dist/cli/commands/ping.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +3 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +35 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/today.d.ts +3 -0
- package/dist/cli/commands/today.d.ts.map +1 -0
- package/dist/cli/commands/today.js +142 -0
- package/dist/cli/commands/today.js.map +1 -0
- package/dist/cli/commands/types.d.ts +5 -0
- package/dist/cli/commands/types.d.ts.map +1 -0
- package/dist/cli/commands/types.js +2 -0
- package/dist/cli/commands/types.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +3 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +41 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/commands/welcome.d.ts +3 -0
- package/dist/cli/commands/welcome.d.ts.map +1 -0
- package/dist/cli/commands/welcome.js +97 -0
- package/dist/cli/commands/welcome.js.map +1 -0
- package/dist/cli/commands-meta.d.ts.map +1 -1
- package/dist/cli/commands-meta.js +286 -29
- package/dist/cli/commands-meta.js.map +1 -1
- package/dist/cli/completions-gen.d.ts +2 -0
- package/dist/cli/completions-gen.d.ts.map +1 -0
- package/dist/cli/completions-gen.js +195 -0
- package/dist/cli/completions-gen.js.map +1 -0
- package/dist/cli/completions.d.ts.map +1 -1
- package/dist/cli/completions.js +42 -5
- package/dist/cli/completions.js.map +1 -1
- package/dist/cli/flags.d.ts +19 -0
- package/dist/cli/flags.d.ts.map +1 -0
- package/dist/cli/flags.js +91 -0
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/format.d.ts +19 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/format.js +249 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/helpers.d.ts +95 -0
- package/dist/cli/helpers.d.ts.map +1 -0
- package/dist/cli/helpers.js +301 -0
- package/dist/cli/helpers.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +7 -1
- package/dist/cli/mcp-server.d.ts.map +1 -1
- package/dist/cli/mcp-server.js +70 -2
- package/dist/cli/mcp-server.js.map +1 -1
- package/dist/cli/menu.d.ts.map +1 -1
- package/dist/cli/menu.js +11 -3
- package/dist/cli/menu.js.map +1 -1
- package/dist/cli/pages/community.d.ts +6 -0
- package/dist/cli/pages/community.d.ts.map +1 -1
- package/dist/cli/pages/community.js +882 -64
- package/dist/cli/pages/community.js.map +1 -1
- package/dist/cli/pages/helpers.d.ts +14 -9
- package/dist/cli/pages/helpers.d.ts.map +1 -1
- package/dist/cli/pages/helpers.js +37 -6
- package/dist/cli/pages/helpers.js.map +1 -1
- package/dist/cli/pages/home.d.ts +1 -0
- package/dist/cli/pages/home.d.ts.map +1 -1
- package/dist/cli/pages/home.js +203 -120
- package/dist/cli/pages/home.js.map +1 -1
- package/dist/cli/pages/marketplace.d.ts +2 -0
- package/dist/cli/pages/marketplace.d.ts.map +1 -1
- package/dist/cli/pages/marketplace.js +524 -62
- package/dist/cli/pages/marketplace.js.map +1 -1
- package/dist/cli/pages/news.d.ts +28 -0
- package/dist/cli/pages/news.d.ts.map +1 -1
- package/dist/cli/pages/news.js +209 -82
- package/dist/cli/pages/news.js.map +1 -1
- package/dist/cli/pages/settings.d.ts.map +1 -1
- package/dist/cli/pages/settings.js +163 -33
- package/dist/cli/pages/settings.js.map +1 -1
- package/dist/cli/pages/types.d.ts +1 -1
- package/dist/cli/pages/types.d.ts.map +1 -1
- package/dist/cli/prompter.d.ts.map +1 -1
- package/dist/cli/prompter.js +43 -8
- package/dist/cli/prompter.js.map +1 -1
- package/dist/cli/shell.d.ts +2 -2
- package/dist/cli/shell.d.ts.map +1 -1
- package/dist/cli/shell.js +321 -18
- package/dist/cli/shell.js.map +1 -1
- package/dist/cli/tui.d.ts +1 -1
- package/dist/cli/tui.d.ts.map +1 -1
- package/dist/cli/tui.js +69 -23
- package/dist/cli/tui.js.map +1 -1
- package/dist/community/client.d.ts +45 -8
- package/dist/community/client.d.ts.map +1 -1
- package/dist/community/client.js +118 -23
- package/dist/community/client.js.map +1 -1
- package/dist/community/search.d.ts +25 -0
- package/dist/community/search.d.ts.map +1 -0
- package/dist/community/search.js +62 -0
- package/dist/community/search.js.map +1 -0
- package/dist/community/types.d.ts +21 -0
- package/dist/community/types.d.ts.map +1 -1
- package/dist/community/types.js +1 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -15
- package/dist/config.js.map +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +142 -68
- package/dist/data.js.map +1 -1
- package/dist/format.d.ts +0 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +0 -2
- package/dist/format.js.map +1 -1
- package/dist/hubs/cache.d.ts +6 -0
- package/dist/hubs/cache.d.ts.map +1 -0
- package/dist/hubs/cache.js +46 -0
- package/dist/hubs/cache.js.map +1 -0
- package/dist/hubs/enrichment.d.ts +43 -0
- package/dist/hubs/enrichment.d.ts.map +1 -0
- package/dist/hubs/enrichment.js +239 -0
- package/dist/hubs/enrichment.js.map +1 -0
- package/dist/hubs/github.d.ts +12 -0
- package/dist/hubs/github.d.ts.map +1 -0
- package/dist/hubs/github.js +54 -0
- package/dist/hubs/github.js.map +1 -0
- package/dist/hubs/huggingface.d.ts +27 -0
- package/dist/hubs/huggingface.d.ts.map +1 -0
- package/dist/hubs/huggingface.js +88 -0
- package/dist/hubs/huggingface.js.map +1 -0
- package/dist/hubs/quality.d.ts +26 -0
- package/dist/hubs/quality.d.ts.map +1 -0
- package/dist/hubs/quality.js +57 -0
- package/dist/hubs/quality.js.map +1 -0
- package/dist/hubs/types.d.ts +30 -0
- package/dist/hubs/types.d.ts.map +1 -0
- package/dist/hubs/types.js +2 -0
- package/dist/hubs/types.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -1
- package/dist/init.js +2 -2
- package/dist/init.js.map +1 -1
- package/dist/live.d.ts +10 -0
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +31 -1
- package/dist/live.js.map +1 -1
- package/dist/marketplace.d.ts +16 -3
- package/dist/marketplace.d.ts.map +1 -1
- package/dist/marketplace.js +174 -7
- package/dist/marketplace.js.map +1 -1
- package/dist/news/cache.d.ts.map +1 -1
- package/dist/news/cache.js +4 -3
- package/dist/news/cache.js.map +1 -1
- package/dist/news/score.js +1 -1
- package/dist/news/sources/arxiv.d.ts.map +1 -1
- package/dist/news/sources/arxiv.js +10 -6
- package/dist/news/sources/arxiv.js.map +1 -1
- package/dist/news/sources/github-trending.d.ts.map +1 -1
- package/dist/news/sources/github-trending.js +9 -5
- package/dist/news/sources/github-trending.js.map +1 -1
- package/dist/news/sources/hn.d.ts.map +1 -1
- package/dist/news/sources/hn.js +8 -4
- package/dist/news/sources/hn.js.map +1 -1
- package/dist/news/sources/reddit.d.ts.map +1 -1
- package/dist/news/sources/reddit.js +5 -4
- package/dist/news/sources/reddit.js.map +1 -1
- package/dist/news/sources/rss.d.ts +10 -11
- package/dist/news/sources/rss.d.ts.map +1 -1
- package/dist/news/sources/rss.js +11 -99
- package/dist/news/sources/rss.js.map +1 -1
- package/dist/news/types.d.ts +3 -0
- package/dist/news/types.d.ts.map +1 -1
- package/dist/news/types.js +15 -6
- package/dist/news/types.js.map +1 -1
- package/dist/outdated.d.ts +24 -0
- package/dist/outdated.d.ts.map +1 -0
- package/dist/outdated.js +53 -0
- package/dist/outdated.js.map +1 -0
- package/dist/preferences.d.ts.map +1 -1
- package/dist/preferences.js +4 -4
- package/dist/preferences.js.map +1 -1
- package/dist/scan.d.ts +26 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +179 -0
- package/dist/scan.js.map +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +14 -20
- package/dist/settings.js.map +1 -1
- package/dist/state.d.ts +9 -2
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +41 -19
- package/dist/state.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,474 +1,148 @@
|
|
|
1
|
-
#
|
|
1
|
+
# agora
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<strong>A standalone terminal hub for discovering, installing, and (soon) trading agent tooling.</strong>
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
Project scanner, MCP marketplace, and workflow manager — a standalone CLI, with a thin OpenCode plugin as one of its surfaces.
|
|
9
|
-
</p>
|
|
3
|
+
> A terminal hub for developers and the agentic AI ecosystem — discover MCP servers and AI tools, skills and harnesses, follow the news, join the conversation, access the latest tech.
|
|
10
4
|
|
|
11
|
-
<p
|
|
5
|
+
<p>
|
|
12
6
|
<a href="https://www.npmjs.com/package/opencode-agora"><img src="https://img.shields.io/npm/v/opencode-agora" alt="npm"></a>
|
|
13
|
-
<a href="https://github.com/IrgenSlj/agora/
|
|
14
|
-
<a href="https://github.com/IrgenSlj/agora/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/opencode-agora" alt="license"></a>
|
|
7
|
+
<a href="https://github.com/IrgenSlj/agora/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/opencode-agora" alt="MIT"></a>
|
|
15
8
|
<a href="https://github.com/IrgenSlj/agora/actions"><img src="https://img.shields.io/github/actions/workflow/status/IrgenSlj/agora/ci.yml?branch=main" alt="CI"></a>
|
|
9
|
+
<img src="https://img.shields.io/badge/tests-805%20passing-success" alt="tests">
|
|
16
10
|
</p>
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
_A terminal recording is in the works — see ROADMAP.md._
|
|
23
|
-
|
|
24
|
-
## What is Agora?
|
|
25
|
-
|
|
26
|
-
Agora is a **standalone terminal marketplace** for the agentic-coding ecosystem — MCP servers, workflows, and tutorials, browsable and installable from your shell with no login and no backend. Run `npx opencode-agora init` in any project and it scans your stack, generates the right `opencode.json`, and installs matched MCP servers.
|
|
27
|
-
|
|
28
|
-
It bundles **61 MCP servers**, **12 production workflows**, **12 tutorials**, and **6 prompts**, all usable offline.
|
|
29
|
-
|
|
30
|
-
**Where it's headed:** Agora is evolving into an **open, self-regulating marketplace** where third-party developers publish and sell advanced skills, tools, and kits — with Agora providing the square and the rules (discovery, trust, delivery), not the goods. See [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) for the direction and [`ROADMAP.md`](./ROADMAP.md) for the plan.
|
|
31
|
-
|
|
32
|
-
### Surfaces
|
|
33
|
-
|
|
34
|
-
Agora is one core marketplace engine behind three surfaces:
|
|
35
|
-
|
|
36
|
-
- **`agora` CLI** — the primary, standalone experience. Browse, install, manage from any terminal.
|
|
37
|
-
- **OpenCode plugin** — a thin bridge that surfaces the catalog *inside* OpenCode and installs into the current project. ([details](#opencode-plugin-commands))
|
|
38
|
-
- **`hub/`** — an optional local web console for browsing.
|
|
39
|
-
|
|
40
|
-
## Features
|
|
41
|
-
|
|
42
|
-
### Interactive shell — `agora` in a TTY
|
|
43
|
-
Run `agora` with no arguments in an interactive terminal and you drop into
|
|
44
|
-
the agora shell: a persistent REPL with mixed bash/chat dispatch.
|
|
45
|
-
|
|
46
|
-
- Type a shell command (`ls`, `git status`, `npm test`) and it runs.
|
|
47
|
-
- Type a question or sentence and it routes to `opencode` for a free
|
|
48
|
-
inference chat — markdown formatting, live duration counter, ionic
|
|
49
|
-
mascot while thinking.
|
|
50
|
-
- `!cmd` forces bash, `?msg` forces chat, `/help` lists meta commands
|
|
51
|
-
(`/menu` `/terminal` `/transcript` `/clear` `/verbose` `/quiet` `/medium` `/last`
|
|
52
|
-
`/again` `/quit`).
|
|
53
|
-
- Tab completion, auto-complete on `/`, ctrl-r reverse history search, ghost-text suggestions.
|
|
54
|
-
- Per-cwd transcripts under `~/.config/agora/transcripts/` so each
|
|
55
|
-
project keeps its own session and chat thread isolated.
|
|
56
|
-
- `/terminal` spawns a bash subshell from anywhere.
|
|
57
|
-
- Orange-accented home screen with model name, `/terminal`, and page shortcuts.
|
|
58
|
-
|
|
59
|
-
### `agora init` — One-Command Setup
|
|
60
|
-
- Scans your project for `package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, `Gemfile`, `Dockerfile`, and more
|
|
61
|
-
- Detects frameworks (React, Next.js, Django, Rails, Spring, Vue)
|
|
62
|
-
- Generates the optimal `opencode.json` with stack-matched MCP servers
|
|
63
|
-
- Automatically installs npm packages and registers the `opencode-agora` plugin
|
|
64
|
-
- Ready in seconds — run once, done
|
|
65
|
-
|
|
66
|
-
### `agora use` — Apply Workflows as Skills
|
|
67
|
-
- Browse 10+ production-tested workflows (TDD, security audit, API design, refactoring, etc.)
|
|
68
|
-
- `agora use wf-tdd-cycle` creates an OpenCode skill file and registers it
|
|
69
|
-
- No manual copy-pasting — one command and the workflow is live
|
|
70
|
-
|
|
71
|
-
### Rich Offline Marketplace
|
|
72
|
-
- **61 MCP servers** across 12 categories (filesystem, databases, cloud, browser automation, monitoring, etc.) — every `npmPackage` is verified against the live npm registry
|
|
73
|
-
- All official `@modelcontextprotocol/*` servers plus top community servers
|
|
74
|
-
- Fully functional offline — no backend required
|
|
75
|
-
- Search, browse, trending — all work with bundled data
|
|
76
|
-
- Sort by stars/installs/name with `--sort`, render tables with `--table`, paginate with `--page` / `--per-page`
|
|
77
|
-
|
|
78
|
-
### Config-Aware Installs
|
|
79
|
-
- `agora install mcp-github --write` installs the npm package **and** writes to config
|
|
80
|
-
- Detects OpenCode config path automatically
|
|
81
|
-
- Merge MCP servers into existing config
|
|
82
|
-
- Inspect config health with `agora config doctor`
|
|
83
|
-
|
|
84
|
-
### `agora mcp` — Marketplace as an MCP Server
|
|
85
|
-
- Exposes all marketplace tools (search, browse, trending, install) as standard MCP tools
|
|
86
|
-
- Add to `opencode.json` for conversational queries: "find a postgres MCP server"
|
|
87
|
-
- Also usable from any MCP client — Claude Desktop, Cursor, etc.
|
|
88
|
-
- Register with `agora init --mcp` to auto-add to your OpenCode config
|
|
89
|
-
|
|
90
|
-
### `agora chat` — Free AI + TUI
|
|
91
|
-
- **TUI mode** (`agora chat`): Launches the full `opencode` TUI with your chosen model.
|
|
92
|
-
Zero per-message latency, conversation history, editing, and `/agora` commands.
|
|
93
|
-
- **One-shot mode** (`agora chat "question"`): Single query via `opencode run`,
|
|
94
|
-
streams the response, persists session for `--continue`.
|
|
95
|
-
- **Plugin tool** (`/agora chat "question"`): Chat from inside OpenCode using the
|
|
96
|
-
`agora_chat` plugin tool — no separate API key needed.
|
|
97
|
-
|
|
98
|
-
### Community (CLI + backend)
|
|
99
|
-
- Profiles, reviews, discussions, and publishing live in the `agora` CLI
|
|
100
|
-
- These need a connected backend — the bundled offline build does not ship community data
|
|
101
|
-
- The OpenCode plugin deliberately ships only the offline-capable marketplace tools
|
|
102
|
-
|
|
103
|
-
### OpenCode Plugin
|
|
104
|
-
- Search, browse, trending, install-preview, and tutorial tools from inside OpenCode
|
|
105
|
-
- Uses the same marketplace core as the CLI — fully offline, no login required
|
|
106
|
-
|
|
107
|
-
### Local Hub
|
|
108
|
-
- Optional browser console for browsing the marketplace
|
|
109
|
-
- Runs locally with `bun run hub:dev`
|
|
110
|
-
|
|
111
|
-
### Learn
|
|
112
|
-
- 12 interactive tutorials on MCP, auth, catalog-contrib, backend deploy, and more
|
|
113
|
-
|
|
114
|
-
### Phase 1.5: "Destination" — substantially shipped
|
|
12
|
+
<p align="center">
|
|
13
|
+
<img src="./docs/demo.gif" alt="Agora demo" width="720">
|
|
14
|
+
</p>
|
|
115
15
|
|
|
116
|
-
|
|
16
|
+
`agora` is a standalone CLI that puts everything a developer building for the future cares about in one terminal: a **curated + live marketplace** of MCP servers and agent tooling, a **threaded community** with reputation-weighted sort, a **ranked news feed** with on-cache AI summarization, and **first-class install consent** for declared permissions. Works offline by default; opt into the backend with `agora auth login`.
|
|
117
17
|
|
|
118
|
-
|
|
119
|
-
- **`agora community` / `agora thread` / `agora post` / `agora reply` / `agora vote` / `agora flag`** — Reddit-style community hub with boards, threaded replies, votes, and flag-don't-delete moderation. CLI commands exist; needs a deployed backend.
|
|
120
|
-
- **`agora similar <id>` / `agora compare <id1> <id2>`** — discovery polish: Jaccard similarity and side-by-side comparison tables. Both shipped.
|
|
121
|
-
- **`agora preferences` / `agora history`** — local persistence for settings, search history, and chat history (no account required).
|
|
122
|
-
- **Full-screen TUI** — 5 pages (Home, Marketplace, Community, News, Settings) with alt-screen frame, key dispatch, scrollbar, status toasts, help panel, and `agora tui` entrypoint.
|
|
123
|
-
- **`/menu` command builder** — interactive wizard that walks through positional args, flags, and value flags, then opens a pre-filled readline prompt for editing.
|
|
124
|
-
|
|
125
|
-
## Quick Start
|
|
126
|
-
|
|
127
|
-
The fastest way to get started — works in any project directory:
|
|
18
|
+
## Install
|
|
128
19
|
|
|
129
20
|
```bash
|
|
130
|
-
#
|
|
21
|
+
# fastest path — runs in your current project
|
|
131
22
|
npx opencode-agora init
|
|
23
|
+
|
|
24
|
+
# or install once, use anywhere
|
|
25
|
+
npm i -g opencode-agora
|
|
26
|
+
agora welcome
|
|
132
27
|
```
|
|
133
28
|
|
|
134
|
-
|
|
29
|
+
From source (requires [bun](https://bun.sh)):
|
|
135
30
|
|
|
136
31
|
```bash
|
|
137
|
-
|
|
138
|
-
agora
|
|
32
|
+
git clone https://github.com/IrgenSlj/agora.git
|
|
33
|
+
cd agora && bun install && bun run build && bun link
|
|
139
34
|
```
|
|
140
35
|
|
|
141
|
-
|
|
36
|
+
The binary is published as both `agora` and `opencode-agora`.
|
|
142
37
|
|
|
143
|
-
|
|
38
|
+
## Try it
|
|
144
39
|
|
|
145
40
|
```bash
|
|
146
|
-
|
|
41
|
+
agora welcome # guided tour, adapts when signed in
|
|
42
|
+
agora today # last 24h: news + community + trending
|
|
43
|
+
agora search mcp # 67 curated + live GitHub/HF results
|
|
44
|
+
agora install mcp-github --write --yes # install + write opencode.json
|
|
45
|
+
agora tui # 5-page full-screen interface
|
|
147
46
|
```
|
|
148
47
|
|
|
149
|
-
The
|
|
48
|
+
The default `agora` in a TTY drops you into a **persistent shell** that mixes bash dispatch (`ls`, `git status`) with free LLM chat (`why is this slow?`). `/help` lists the slash commands; `/abc` shows the single-letter shortcuts.
|
|
150
49
|
|
|
151
|
-
|
|
152
|
-
agora --help
|
|
153
|
-
opencode-agora --help
|
|
154
|
-
```
|
|
50
|
+
## Commands
|
|
155
51
|
|
|
156
|
-
|
|
52
|
+
Run `agora help` for the grouped list, or `agora help <command>` for any of these:
|
|
157
53
|
|
|
158
|
-
|
|
54
|
+
| Group | Commands |
|
|
55
|
+
|---|---|
|
|
56
|
+
| **Daily** | `welcome` · `today` · `bookmarks` · `share` · `open` · `author` |
|
|
57
|
+
| **Marketplace** | `search` · `browse` · `trending` · `similar` · `compare` · `install` · `scan` · `outdated` · `workflows` |
|
|
58
|
+
| **News** | `news` (CLI) · TUI reader with AI summarization |
|
|
59
|
+
| **Community** | `community` · `thread` · `post` · `reply` · `vote` · `flag` · `discuss` |
|
|
60
|
+
| **Account** | `auth login` · `auth status` · `profile` · `review` · `reviews` · `publish` |
|
|
61
|
+
| **Moderation** | `admin hide` · `admin log` · `admin recompute` _(operator-only)_ |
|
|
62
|
+
| **Setup** | `init` · `use` · `config show/edit/doctor` · `notify` · `completions` · `ping` |
|
|
63
|
+
| **Utility** | `export` · `watch` · `chat` · `mcp` · `tui` · `menu` · `preferences` · `history` |
|
|
159
64
|
|
|
160
|
-
|
|
65
|
+
Every command supports `--json` for scripting and `--help` for inline manual.
|
|
161
66
|
|
|
162
|
-
|
|
67
|
+
## Install consent
|
|
163
68
|
|
|
164
|
-
|
|
165
|
-
# Scan project and generate optimal OpenCode config
|
|
166
|
-
agora init
|
|
167
|
-
agora init --dry-run # Preview without writing
|
|
69
|
+
`agora install <id>` is preview-only by default. With `--write`, items that declare a permissions manifest require an explicit `--yes`:
|
|
168
70
|
|
|
169
|
-
# Apply a workflow as an OpenCode skill
|
|
170
|
-
agora use wf-tdd-cycle
|
|
171
|
-
agora use wf-security-audit
|
|
172
71
|
```
|
|
72
|
+
$ agora install mcp-filesystem --write
|
|
73
|
+
Permissions
|
|
74
|
+
fs ./**/*
|
|
173
75
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
# Search and browse
|
|
178
|
-
agora search filesystem
|
|
179
|
-
agora search database --category mcp
|
|
180
|
-
agora search mcp --sort stars # sort by stars
|
|
181
|
-
agora search mcp --sort name --order asc # alphabetical
|
|
182
|
-
agora search mcp --table # box-drawn table
|
|
183
|
-
agora search mcp --per-page 5 --page 2 # paginated
|
|
184
|
-
AGORA_API_URL=https://agora.example.com agora search github --api
|
|
185
|
-
agora browse mcp-postgres
|
|
186
|
-
agora trending
|
|
187
|
-
agora trending --table
|
|
188
|
-
|
|
189
|
-
# Install MCP servers
|
|
190
|
-
agora install mcp-github # preview only
|
|
191
|
-
agora install mcp-github --write # install npm package + write config
|
|
192
|
-
|
|
193
|
-
# Save/bookmark items
|
|
194
|
-
agora save wf-security-audit
|
|
195
|
-
agora saved
|
|
196
|
-
agora remove wf-security-audit
|
|
76
|
+
This package declares permissions. Re-run with --yes to grant and install.
|
|
77
|
+
$ echo $?
|
|
78
|
+
1
|
|
197
79
|
```
|
|
198
80
|
|
|
199
|
-
|
|
81
|
+
The TUI install preview flips its footer to `g grant + install d details n cancel` when permissions are present. The list shows a dim `[fs net exec]` badge on any item with a non-empty manifest.
|
|
200
82
|
|
|
201
|
-
|
|
202
|
-
agora workflows
|
|
203
|
-
agora workflows security
|
|
204
|
-
```
|
|
83
|
+
`--write` also runs a **pre-install scan** first — repo reachability, npm existence, recency, declared-permission consistency, and community flag count — and refuses to apply if any check fails (e.g. an item flagged enough times to auto-hide, or a package that 404s on npm). Run the scan standalone with `agora scan <id>`, or bypass the install gate with `--skip-scan`.
|
|
205
84
|
|
|
206
|
-
|
|
85
|
+
## Configuration
|
|
207
86
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
agora
|
|
212
|
-
agora
|
|
213
|
-
|
|
87
|
+
| Env | Meaning |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `AGORA_HOME` | Override the data dir (default `~/.config/agora`) |
|
|
90
|
+
| `AGORA_API_URL` | Backend URL for `--api` reads, all writes, and `agora ping` |
|
|
91
|
+
| `AGORA_TOKEN` | Bearer token (alternatively persisted by `agora auth login`) |
|
|
92
|
+
| `AGORA_LIVE_HUBS` | `1` to merge live GitHub + HuggingFace into the marketplace |
|
|
93
|
+
| `AGORA_GITHUB_TOKEN` | Raises the unauth 60 req/hr GitHub limit to 5000 |
|
|
94
|
+
| `AGORA_ADMIN_USER_IDS` | Comma-separated user ids granted moderator commands |
|
|
95
|
+
| `EDITOR` / `VISUAL` | Used by `agora config edit` |
|
|
96
|
+
| `NO_COLOR` | Respect standard no-color convention |
|
|
214
97
|
|
|
215
|
-
|
|
98
|
+
Per-user state lives under `~/.config/agora/` — `state.json` (saves + auth), `settings.toml` (preferences), `news-cache.jsonl`, `news-meta.json` (bookmarks), `hubs-cache.jsonl`. All files holding user data are written `0o600` and atomically (`.tmp` + rename) so a crash mid-flush leaves the previous version intact.
|
|
216
99
|
|
|
217
|
-
|
|
100
|
+
## OpenCode plugin
|
|
218
101
|
|
|
219
|
-
|
|
220
|
-
agora similar mcp-postgres # Jaccard-similar items
|
|
221
|
-
agora compare mcp-postgres mcp-supabase # side-by-side comparison table
|
|
222
|
-
```
|
|
102
|
+
`agora init` also registers the package as an OpenCode plugin and drops a `.opencode/command/agora.md` slash command so the LLM can call:
|
|
223
103
|
|
|
224
|
-
### Preferences & History
|
|
225
|
-
|
|
226
|
-
```bash
|
|
227
|
-
agora preferences # view local preferences
|
|
228
|
-
agora preferences theme light # set theme (dark|light|auto)
|
|
229
|
-
agora preferences verbosity quiet # set verbosity
|
|
230
|
-
agora preferences username "Jane" # set local display name
|
|
231
|
-
agora history # view recent searches & chats
|
|
232
|
-
agora history --limit 10
|
|
233
|
-
agora history --clear # erase all history
|
|
234
104
|
```
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
agora discussions mcp --category question
|
|
240
|
-
agora discuss --title "MCP question" --content "How are you composing servers?" --category question
|
|
241
|
-
agora auth login --token $AGORA_TOKEN --api-url https://agora.example.com
|
|
242
|
-
agora auth status
|
|
243
|
-
agora publish package --name @you/server --description "MCP server" --npm @you/server
|
|
244
|
-
agora publish workflow --name "Security Audit" --description "Audit workflow" --prompt-file ./prompt.md
|
|
245
|
-
agora review mcp-github --rating 5 --content "Works well"
|
|
246
|
-
agora reviews mcp-github --api
|
|
247
|
-
agora profile alice
|
|
105
|
+
/agora search <query>
|
|
106
|
+
/agora browse <id>
|
|
107
|
+
/agora install <id>
|
|
108
|
+
/agora chat <message>
|
|
248
109
|
```
|
|
249
110
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
# Run the MCP server (add to opencode.json MCP config)
|
|
254
|
-
agora mcp
|
|
255
|
-
|
|
256
|
-
# Auto-register the MCP server in your OpenCode config
|
|
257
|
-
agora init --mcp
|
|
111
|
+
`agora_*` tools are also reachable from any MCP client via `agora mcp` — add `{"mcp": {"agora": {"command": ["agora", "mcp"]}}}` to your `opencode.json`.
|
|
258
112
|
|
|
259
|
-
|
|
260
|
-
agora chat
|
|
261
|
-
|
|
262
|
-
# Free AI chat — one-shot mode (scriptable)
|
|
263
|
-
agora chat "what MCP servers are available for postgres?"
|
|
264
|
-
agora chat -m deepseek-v4-flash-free "find me a web search MCP server"
|
|
265
|
-
|
|
266
|
-
# Continue the last conversation
|
|
267
|
-
agora chat --continue "follow up question"
|
|
268
|
-
```
|
|
113
|
+
## Architecture
|
|
269
114
|
|
|
270
|
-
Add to `opencode.json`:
|
|
271
|
-
```json
|
|
272
|
-
{
|
|
273
|
-
"mcp": {
|
|
274
|
-
"agora": {
|
|
275
|
-
"type": "local",
|
|
276
|
-
"command": ["agora", "mcp"]
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
115
|
```
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
116
|
+
src/cli/ command handlers, dispatch, shell, prompter, TUI
|
|
117
|
+
src/cli/pages/ five full-screen TUI pages (home, marketplace,
|
|
118
|
+
community, news, settings) + shared helpers
|
|
119
|
+
src/marketplace.ts curated catalog + live hub merge + install planner
|
|
120
|
+
src/hubs/ GitHub + HuggingFace connectors + AI enrichment
|
|
121
|
+
src/community/ backend client + types
|
|
122
|
+
src/news/ scoring, cache, per-source adapters
|
|
123
|
+
src/state.ts local state, saves, auth (atomic 0o600 writes)
|
|
124
|
+
backend/src/index.ts Cloudflare Workers + D1 (Hono router)
|
|
125
|
+
test/ 805 tests, 36 files
|
|
287
126
|
```
|
|
288
127
|
|
|
289
|
-
`
|
|
290
|
-
|
|
291
|
-
Saved items and optional auth credentials are stored in `~/.config/agora/state.json` by default. Use `AGORA_HOME=/path/to/agora` or `--data-dir /path/to/agora` to override.
|
|
292
|
-
|
|
293
|
-
The CLI uses bundled offline marketplace data (60+ MCP servers, 12 workflows) by default. Add `--api`, `--live`, `AGORA_USE_API=true`, or `AGORA_API_URL` to use the live backend. Falls back to offline data if the API is unavailable.
|
|
294
|
-
|
|
295
|
-
### OpenCode Plugin Commands
|
|
296
|
-
|
|
297
|
-
The plugin itself registers **tools** (`agora_search`, `agora_browse`, `agora_install`, …) that the OpenCode assistant calls — OpenCode plugins cannot register slash commands directly.
|
|
298
|
-
|
|
299
|
-
To get a typed `/agora` slash command, `agora init` also writes `.opencode/command/agora.md` into your project. That command forwards whatever you type to the matching tool, so these all work inside OpenCode:
|
|
300
|
-
|
|
301
|
-
| Command | Description |
|
|
302
|
-
|---|---|
|
|
303
|
-
| `/agora search <query> [category]` | Search marketplace |
|
|
304
|
-
| `/agora browse <id>` | View package or workflow details |
|
|
305
|
-
| `/agora browse_category <category>` | Browse a category |
|
|
306
|
-
| `/agora trending [type]` | See trending |
|
|
307
|
-
| `/agora install <id>` | Install steps / config for a package |
|
|
308
|
-
| `/agora tutorial <id> [step]` | Interactive tutorials |
|
|
309
|
-
| `/agora chat <message>` | Free AI chat via opencode run |
|
|
310
|
-
| `/agora info` | Plugin help |
|
|
311
|
-
| `/agora mcp` | Run MCP server (CLI only) |
|
|
312
|
-
|
|
313
|
-
Community features — profiles, reviews, discussions, publishing — are **CLI-only** (`agora profile`, `agora reviews`, `agora discuss`, `agora publish`) and need a connected backend. The plugin deliberately ships only the offline-capable marketplace tools.
|
|
314
|
-
|
|
315
|
-
If you didn't run `agora init`, copy `.opencode/command/agora.md` from this repo into your project's (or `~/.config/opencode/command/agora.md` for a global command). Without the command file the `agora_*` tools still work — just ask the assistant in chat.
|
|
316
|
-
|
|
317
|
-
**Categories:** mcp, prompt, workflow, skill `|` **Data sources:** offline (default), `--api`
|
|
318
|
-
|
|
319
|
-
### Registering the plugin manually
|
|
320
|
-
|
|
321
|
-
If you did not run `agora init`, register the plugin by hand:
|
|
322
|
-
|
|
323
|
-
1. Install the package globally:
|
|
324
|
-
```bash
|
|
325
|
-
npm install -g opencode-agora
|
|
326
|
-
```
|
|
327
|
-
2. Add `"opencode-agora"` to the `plugins` array in `~/.config/opencode/opencode.json` (or your project-local `opencode.json`):
|
|
328
|
-
```json
|
|
329
|
-
{
|
|
330
|
-
"plugins": ["opencode-agora"]
|
|
331
|
-
}
|
|
332
|
-
```
|
|
128
|
+
See [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) for the why-this-shape writeup and [`ROADMAP.md`](./ROADMAP.md) for what's next.
|
|
333
129
|
|
|
334
130
|
## Development
|
|
335
131
|
|
|
336
132
|
```bash
|
|
337
|
-
#
|
|
338
|
-
bun run typecheck
|
|
339
|
-
|
|
340
|
-
#
|
|
341
|
-
bun run build
|
|
342
|
-
|
|
343
|
-
# Run tests
|
|
344
|
-
bun test
|
|
345
|
-
|
|
346
|
-
# Try the CLI from source
|
|
347
|
-
bun src/cli.ts search filesystem
|
|
348
|
-
|
|
349
|
-
# Install locally to OpenCode
|
|
350
|
-
bun run dev
|
|
133
|
+
bun test # 805 cases, ~3.5s
|
|
134
|
+
bun run typecheck # CLI + backend (typecheck:cli / typecheck:backend run both)
|
|
135
|
+
bun run build # tsc + chmod +x dist/cli.js
|
|
136
|
+
bun src/cli.ts <cmd> # run from source without building
|
|
351
137
|
|
|
352
|
-
|
|
353
|
-
bun run
|
|
138
|
+
cd backend && bun run dev # local backend on wrangler
|
|
139
|
+
cd backend && bun run typecheck # backend has its own tsconfig
|
|
354
140
|
```
|
|
355
141
|
|
|
356
|
-
|
|
142
|
+
PRs welcome — see [`CONTRIBUTING.md`](./CONTRIBUTING.md) and [`COMMUNITY_GUIDELINES.md`](./COMMUNITY_GUIDELINES.md). The catalog accepts entries via PR; see `src/data.ts` for the shape.
|
|
357
143
|
|
|
358
|
-
|
|
359
|
-
agora/
|
|
360
|
-
├── src/ # CLI, plugin, and shared marketplace core
|
|
361
|
-
├── backend/ # Cloudflare Workers API
|
|
362
|
-
├── hub/ # Optional local web Hub
|
|
363
|
-
├── test/ # Tests (~500, 20 files)
|
|
364
|
-
├── dist/ # Built output
|
|
365
|
-
└── docs/ # Architecture, roadmap, design docs
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
## Architecture
|
|
369
|
-
|
|
370
|
-
```
|
|
371
|
-
agora/
|
|
372
|
-
├── src/
|
|
373
|
-
│ ├── cli.ts # CLI entrypoint
|
|
374
|
-
│ ├── cli/app.ts # CLI command parser (~30+ handlers)
|
|
375
|
-
│ ├── cli/shell.ts # Interactive shell (agora in TTY)
|
|
376
|
-
│ ├── cli/prompter.ts # Raw-mode line editor with auto-complete
|
|
377
|
-
│ ├── cli/completions.ts # Completion providers (slash, path, marketplace ids)
|
|
378
|
-
│ ├── cli/tui.ts # Full-screen TUI frame renderer + key dispatch
|
|
379
|
-
│ ├── cli/mcp-server.ts # MCP server (agora mcp)
|
|
380
|
-
│ ├── cli/menu.ts # Interactive command builder wizard
|
|
381
|
-
│ ├── cli/commands-meta.ts # Command metadata for help + menu
|
|
382
|
-
│ ├── cli/chat-renderer.ts # Chat response formatting
|
|
383
|
-
│ ├── cli/pages/ # TUI page implementations (5 pages)
|
|
384
|
-
│ │ ├── types.ts # Page / KeyEvent / PageAction / PageContext contract
|
|
385
|
-
│ │ ├── helpers.ts # Shared TUI helpers (frame, scrollbar, sep, etc.)
|
|
386
|
-
│ │ ├── home.ts # Home dashboard
|
|
387
|
-
│ │ ├── marketplace.ts# Package list + drill-in
|
|
388
|
-
│ │ ├── community.ts # Community boards → threads
|
|
389
|
-
│ │ ├── news.ts # Ranked news feed + TUI reader + AI summarization
|
|
390
|
-
│ │ └── settings.ts # Settings form
|
|
391
|
-
│ ├── news/ # News feed core
|
|
392
|
-
│ │ ├── types.ts # NewsItem, ScoredNewsItem, NewsConfig
|
|
393
|
-
│ │ ├── score.ts # scoreItem, rankItems
|
|
394
|
-
│ │ ├── cache.ts # readCache, writeCache, isStale, readNewsMeta
|
|
395
|
-
│ │ └── sources/ # Source adapters (hn, reddit, github-trending, arxiv)
|
|
396
|
-
│ ├── community/ # Community hub core
|
|
397
|
-
│ │ ├── types.ts # Thread, Reply, Vote, Flag, Board
|
|
398
|
-
│ │ └── client.ts # Community API source helpers
|
|
399
|
-
│ ├── init.ts # Project scanner + init plan generator
|
|
400
|
-
│ ├── live.ts # Live API source with offline fallback
|
|
401
|
-
│ ├── marketplace.ts # Shared search, sort, browse, trending, install-plan core
|
|
402
|
-
│ ├── config-files.ts # OpenCode config detection, doctor, and write helpers
|
|
403
|
-
│ ├── settings.ts # Settings persistence (toml)
|
|
404
|
-
│ ├── preferences.ts # Local preferences (theme, verbosity, username, etc.)
|
|
405
|
-
│ ├── history.ts # Search + chat history (JSONL append log)
|
|
406
|
-
│ ├── transcript.ts # Per-cwd chat transcripts
|
|
407
|
-
│ ├── state.ts # Local Agora saved-item state + auth
|
|
408
|
-
│ ├── index.ts # OpenCode plugin
|
|
409
|
-
│ ├── ui.ts # Terminal styling: styler, gradient banner, header frame
|
|
410
|
-
│ ├── format.ts # Count formatting helpers
|
|
411
|
-
│ ├── config.ts # MCP config generation
|
|
412
|
-
│ ├── data.ts # 60+ MCP servers, 12 workflows, 12 tutorials, 7 prompts
|
|
413
|
-
│ ├── commands.ts # OpenCode /agora slash command installer
|
|
414
|
-
│ └── types.ts # Shared TypeScript types
|
|
415
|
-
│
|
|
416
|
-
├── backend/ # Cloudflare Workers API
|
|
417
|
-
│ ├── src/index.ts # Hono server + routes
|
|
418
|
-
│ ├── schema.sql # D1 database schema (including community tables)
|
|
419
|
-
│ └── services/ # npm + GitHub API clients
|
|
420
|
-
│
|
|
421
|
-
├── hub/ # Local Hub app
|
|
422
|
-
│
|
|
423
|
-
├── test/ # ~500 tests across 20 files
|
|
424
|
-
│ ├── cli.test.ts # CLI integration tests
|
|
425
|
-
│ ├── news.test.ts # News scoring, cache, sources
|
|
426
|
-
│ ├── history.test.ts # History persistence tests
|
|
427
|
-
│ ├── preferences.test.ts # Preferences persistence tests
|
|
428
|
-
│ └── ...
|
|
429
|
-
│
|
|
430
|
-
└── docs/ # Architecture, roadmap, design docs
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
## Project Status
|
|
434
|
-
|
|
435
|
-
| Component | Status | Notes |
|
|
436
|
-
|-----------|--------|-------|
|
|
437
|
-
| Interactive shell (`agora`) | Ready | Persistent REPL with bash/chat dispatch, auto-complete, per-cwd transcripts |
|
|
438
|
-
| `agora init` | Ready | Project scanning, config generation, auto-install, plugin registration |
|
|
439
|
-
| `agora use` | Ready | Apply workflows as OpenCode skills in one command |
|
|
440
|
-
| `agora install --write` | Ready | Auto-installs npm packages and writes config |
|
|
441
|
-
| `agora mcp` | Ready | Marketplace exposed as a Model Context Protocol server |
|
|
442
|
-
| `agora chat` | Ready | TUI + one-shot inference via `opencode run` |
|
|
443
|
-
| CLI | Ready | 25 commands: `init`, `use`, `mcp`, `chat`, `menu`, `search`, `browse`, `trending`, `workflows`, `tutorials`, `tutorial`, `discussions`, `discuss`, `install`, `save`, `saved`, `remove`, `login`, `logout`, `whoami`, `auth`, `publish`, `review`, `reviews`, `profile`, `config doctor` |
|
|
444
|
-
| Offline data | Ready | 61 MCP servers, 12 workflows, 12 tutorials, 6 prompts (npm-validated) |
|
|
445
|
-
| Live API mode | Ready | Opt-in via `--api`, `AGORA_API_URL`; falls back offline |
|
|
446
|
-
| Shared core | Ready | CLI and plugin share marketplace logic |
|
|
447
|
-
| Local state | Ready | Saved items and auth tokens under `~/.config/agora` |
|
|
448
|
-
| Plugin (offline) | Ready | Works with bundled data |
|
|
449
|
-
| Backend | 🚧 Not deployed — self-host required (see backend/) | Cloudflare Workers + D1 ready for deployment; auth rework blocks public deploy |
|
|
450
|
-
| Local Hub | Ready | Static web app served by Bun |
|
|
451
|
-
| CI | Ready | Typecheck + tests on push/PR |
|
|
452
|
-
| Publish CI | Ready | Auto-publish to npm on release |
|
|
453
|
-
| News feed (`agora news`) | 🚧 Phase 1.5 — designed, not built | HN + Reddit + GitHub trending + arXiv, TUI reader |
|
|
454
|
-
| Community hub (`agora community`) | 🚧 Phase 1.5 — designed, not built | Boards, threads, votes, flag-don't-delete, LLM participants |
|
|
455
|
-
|
|
456
|
-
## Testing
|
|
457
|
-
|
|
458
|
-
```bash
|
|
459
|
-
bun test
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
## Roadmap
|
|
463
|
-
|
|
464
|
-
See [ROADMAP.md](./ROADMAP.md) for upcoming work and ways to contribute.
|
|
144
|
+
A [`scripts/demo.tape`](./scripts/demo.tape) is included for regenerating the README hero gif with [VHS](https://github.com/charmbracelet/vhs) (`brew install vhs && vhs scripts/demo.tape` → `docs/demo.gif`).
|
|
465
145
|
|
|
466
146
|
## License
|
|
467
147
|
|
|
468
|
-
MIT
|
|
469
|
-
|
|
470
|
-
---
|
|
471
|
-
|
|
472
|
-
<p align="center">
|
|
473
|
-
Built for the developer community
|
|
474
|
-
</p>
|
|
148
|
+
[MIT](./LICENSE) — © IrgenSlj.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write `body` to `path` atomically: writes to `path.tmp`, then renames
|
|
3
|
+
* over the destination. Also chmods to `mode` (default 0o600) so files
|
|
4
|
+
* holding user data — tokens, bookmarks, settings — are owner-readable
|
|
5
|
+
* only.
|
|
6
|
+
*
|
|
7
|
+
* Ensures the parent directory exists before writing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function atomicWriteFile(path: string, body: string, mode?: number): void;
|
|
10
|
+
//# sourceMappingURL=atomic-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../src/atomic-write.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAQ,GAAG,IAAI,CAU9E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { writeFileSync, renameSync, chmodSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Write `body` to `path` atomically: writes to `path.tmp`, then renames
|
|
5
|
+
* over the destination. Also chmods to `mode` (default 0o600) so files
|
|
6
|
+
* holding user data — tokens, bookmarks, settings — are owner-readable
|
|
7
|
+
* only.
|
|
8
|
+
*
|
|
9
|
+
* Ensures the parent directory exists before writing.
|
|
10
|
+
*/
|
|
11
|
+
export function atomicWriteFile(path, body, mode = 0o600) {
|
|
12
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
13
|
+
const tmp = `${path}.tmp`;
|
|
14
|
+
writeFileSync(tmp, body, { mode });
|
|
15
|
+
renameSync(tmp, path);
|
|
16
|
+
try {
|
|
17
|
+
chmodSync(path, mode);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
/* renameSync sometimes resets mode on some filesystems — best-effort */
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../src/atomic-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAY,EAAE,IAAI,GAAG,KAAK;IACtE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgoraState } from '../state.js';
|
|
2
|
+
import type { FetchLike } from '../live.js';
|
|
3
|
+
export interface EnsureFreshOpts {
|
|
4
|
+
dataDir: string;
|
|
5
|
+
fetcher?: FetchLike;
|
|
6
|
+
/** Seconds of slack before access exp at which to refresh. Default 60. */
|
|
7
|
+
slack?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Returns auth with a fresh access token, refreshing if needed.
|
|
11
|
+
* Persists the rotated pair back to state.json on success.
|
|
12
|
+
* Returns the original auth (untouched) if:
|
|
13
|
+
* - no refresh token available, OR
|
|
14
|
+
* - refresh request fails (let the API call fail with 401 downstream)
|
|
15
|
+
*/
|
|
16
|
+
export declare function ensureFreshAccess(state: AgoraState, opts: EnsureFreshOpts): Promise<AgoraState>;
|
|
17
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/auth/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,UAAU,CAAC,CA0CrB"}
|