@pokelo/cli 0.1.0
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 +121 -0
- package/bin/pokelo.mjs +8 -0
- package/package.json +33 -0
- package/skill/SKILL.md +98 -0
- package/skill/reference.md +59 -0
- package/skill/scripts/ensure-pokelo.sh +47 -0
- package/src/cli.mjs +256 -0
- package/src/commands/assets.mjs +283 -0
- package/src/commands/auth.mjs +109 -0
- package/src/commands/docs.mjs +131 -0
- package/src/commands/projects.mjs +35 -0
- package/src/commands/search.mjs +36 -0
- package/src/config.mjs +148 -0
- package/src/exit.mjs +13 -0
- package/src/http.mjs +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# pokelo
|
|
2
|
+
|
|
3
|
+
Official CLI for [Pokelo](https://pokelo.bearly.pro) — a thin client over the **public REST API** (`/v1`), designed for AI agents, skills, CI, and shell automation.
|
|
4
|
+
|
|
5
|
+
CLI does **not** call MCP. MCP remains a separate adapter for IDEs that support it.
|
|
6
|
+
|
|
7
|
+
| npm package | Binary |
|
|
8
|
+
|-------------|--------|
|
|
9
|
+
| `@pokelo/cli` | `pokelo` |
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @pokelo/cli
|
|
15
|
+
pokelo --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
From this monorepo (before publish / local dev):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm --filter @pokelo/cli exec pokelo --help
|
|
22
|
+
# or
|
|
23
|
+
node tools/pokelo-cli/bin/pokelo.mjs --help
|
|
24
|
+
|
|
25
|
+
cd tools/pokelo-cli && pnpm link --global
|
|
26
|
+
pokelo --help
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Requires Node.js ≥ 18 (uses global `fetch`).
|
|
30
|
+
|
|
31
|
+
Agent skill (Cursor): [`.cursor/skills/pokelo-cli/`](../../.cursor/skills/pokelo-cli/) — also shipped under `skill/` in the npm package.
|
|
32
|
+
|
|
33
|
+
## Auth (agents)
|
|
34
|
+
|
|
35
|
+
Non-interactive (required for headless agents):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pokelo auth login \
|
|
39
|
+
--url https://pokelo.example.com \
|
|
40
|
+
--token "$POKELO_TOKEN"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Safer token input (not visible in `ps`):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
printenv POKELO_TOKEN | pokelo auth login --url https://pokelo.example.com --token-stdin
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or skip the config file entirely:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
export POKELO_URL=https://pokelo.example.com
|
|
53
|
+
export POKELO_TOKEN=mcp_…
|
|
54
|
+
export POKELO_PROJECT=my-project-slug # optional default
|
|
55
|
+
pokelo projects list
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Interactive (TTY):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pokelo auth login
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Check config (never prints the full token):
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pokelo auth status
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Config priority
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
CLI flags (--url, --token, --project)
|
|
74
|
+
> environment (POKELO_URL, POKELO_TOKEN, POKELO_PROJECT)
|
|
75
|
+
> ~/.config/pokelo/config.json
|
|
76
|
+
> legacy ~/.pokelo-cli.json (read-only migrate of url/token)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
URL may be `https://host` or `https://host/v1` — normalized to `…/v1`.
|
|
80
|
+
|
|
81
|
+
Create a Personal Access Token in the Pokelo UI (Settings → MCP / PAT). Prefix is `mcp_`; the same token works for REST and MCP.
|
|
82
|
+
|
|
83
|
+
## Commands
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pokelo projects list
|
|
87
|
+
pokelo projects get <project-id-or-slug>
|
|
88
|
+
|
|
89
|
+
pokelo search "how does auth work" --project <ref> --limit 5
|
|
90
|
+
|
|
91
|
+
pokelo docs list --project <ref>
|
|
92
|
+
pokelo docs get <document-id-or-slug> --project <ref>
|
|
93
|
+
pokelo docs create --title "Note" --type Note --content "# Hi" --project <ref>
|
|
94
|
+
pokelo docs update <id> --content-file ./body.md --project <ref>
|
|
95
|
+
|
|
96
|
+
pokelo assets list --project <ref>
|
|
97
|
+
pokelo assets get <asset-id> --project <ref>
|
|
98
|
+
pokelo assets upload ./shot.png --project <ref> --description "screenshot"
|
|
99
|
+
pokelo assets download <asset-id> --out ./shot.png --project <ref>
|
|
100
|
+
pokelo assets update <asset-id> --name "renamed.png" --project <ref>
|
|
101
|
+
pokelo assets delete <asset-id> --project <ref>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`assets upload` uses `POST …/assets/base64` for files ≤ 8 MiB; larger files use init → PUT → complete.
|
|
105
|
+
|
|
106
|
+
Stdout is always JSON. Errors go to stderr.
|
|
107
|
+
|
|
108
|
+
Exit codes: `0` ok, `1` usage/config, `2` API/network.
|
|
109
|
+
|
|
110
|
+
## Agent happy path
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pokelo auth login --url https://pokelo.example.com --token "$TOKEN"
|
|
114
|
+
pokelo search "jak działa auth" --project khirby --limit 5
|
|
115
|
+
pokelo docs get <document-id> --project khirby
|
|
116
|
+
pokelo assets upload ./diagram.png --project khirby
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Spec
|
|
120
|
+
|
|
121
|
+
Product SSOT: *Pokelo CLI — public API client for agents (Single Source of Truth)* in the Pokelo project.
|
package/bin/pokelo.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pokelo/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Pokelo CLI — public REST client for agents and developers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pokelo": "./bin/pokelo.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src",
|
|
12
|
+
"README.md",
|
|
13
|
+
"skill"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"pokelo",
|
|
20
|
+
"knowledge-base",
|
|
21
|
+
"cli",
|
|
22
|
+
"rag",
|
|
23
|
+
"agents"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"start": "node ./bin/pokelo.mjs",
|
|
31
|
+
"pokelo": "node ./bin/pokelo.mjs"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pokelo-cli
|
|
3
|
+
description: >-
|
|
4
|
+
Uses the Pokelo CLI (`pokelo` binary from npm package `@pokelo/cli`) over the
|
|
5
|
+
public REST API for auth, projects, semantic search, documents, and assets.
|
|
6
|
+
Use when working with Pokelo knowledge bases from the shell, provisioning
|
|
7
|
+
agents without MCP, or when the user mentions pokelo CLI, @pokelo/cli, or
|
|
8
|
+
PAT-based Pokelo access.
|
|
9
|
+
disable-model-invocation: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Pokelo CLI
|
|
13
|
+
|
|
14
|
+
Official shell client for Pokelo. Speaks **public REST `/v1` + Personal Access Token** — never MCP.
|
|
15
|
+
|
|
16
|
+
| Concept | Value |
|
|
17
|
+
|---------|--------|
|
|
18
|
+
| npm package | `@pokelo/cli` |
|
|
19
|
+
| Command on PATH | `pokelo` |
|
|
20
|
+
| Config | flags > `POKELO_*` env > `~/.config/pokelo/config.json` |
|
|
21
|
+
|
|
22
|
+
## 1. Ensure installed (idempotent)
|
|
23
|
+
|
|
24
|
+
Run before the first `pokelo` call in a session:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# From package install or checkout:
|
|
28
|
+
bash skill/scripts/ensure-pokelo.sh
|
|
29
|
+
# Or: command -v pokelo || npm install -g @pokelo/cli
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or manually:
|
|
33
|
+
|
|
34
|
+
1. If `command -v pokelo` succeeds → **do not install**; use it.
|
|
35
|
+
2. Else: `npm install -g @pokelo/cli` (exposes the `pokelo` binary).
|
|
36
|
+
3. In this monorepo only, if npm package is unpublished: use
|
|
37
|
+
`node tools/pokelo-cli/bin/pokelo.mjs` or symlink it to `~/.local/bin/pokelo`.
|
|
38
|
+
|
|
39
|
+
Never reinstall when `pokelo` is already available.
|
|
40
|
+
|
|
41
|
+
## 2. Auth
|
|
42
|
+
|
|
43
|
+
Prefer env in CI / ephemeral sandboxes (no disk write):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export POKELO_URL=https://<host> # or http://localhost:3001 for local API
|
|
47
|
+
export POKELO_TOKEN=mcp_… # Personal Access Token
|
|
48
|
+
export POKELO_PROJECT=<slug-or-uuid> # optional default
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or persist config (agents, headless):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pokelo auth login --url "$POKELO_URL" --token-stdin <<< "$POKELO_TOKEN"
|
|
55
|
+
# or: pokelo auth login --url … --token "$TOKEN"
|
|
56
|
+
pokelo auth status # never prints the full token
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Local Vite (`:5173`) does **not** proxy `/v1` — point `POKELO_URL` at the API (`:3001`), not the frontend.
|
|
60
|
+
|
|
61
|
+
## 3. Commands (stdout = JSON)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pokelo projects list
|
|
65
|
+
pokelo projects get <project-ref>
|
|
66
|
+
|
|
67
|
+
pokelo search "<query>" --project <ref> [--limit n]
|
|
68
|
+
|
|
69
|
+
pokelo docs list --project <ref>
|
|
70
|
+
pokelo docs get <doc-ref> --project <ref>
|
|
71
|
+
pokelo docs create --title "…" [--type] [--content|--content-file] [--parent] --project <ref>
|
|
72
|
+
pokelo docs update <doc-ref> [--title] [--content|--content-file] --project <ref>
|
|
73
|
+
|
|
74
|
+
pokelo assets list --project <ref>
|
|
75
|
+
pokelo assets get <asset-id> --project <ref>
|
|
76
|
+
pokelo assets upload <file> [--name] [--mime] [--visibility] [--document] [--description] --project <ref>
|
|
77
|
+
pokelo assets download <asset-id> --out <path> --project <ref>
|
|
78
|
+
pokelo assets update <asset-id> [--name] [--description] … --project <ref>
|
|
79
|
+
pokelo assets delete <asset-id> --project <ref>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Exit codes: `0` ok, `1` usage/config, `2` API/network. Errors on stderr.
|
|
83
|
+
|
|
84
|
+
`assets upload`: ≤ 8 MiB → `POST …/base64`; larger → init → PUT → complete.
|
|
85
|
+
|
|
86
|
+
## 4. Agent workflow
|
|
87
|
+
|
|
88
|
+
1. Ensure `pokelo` is installed (step 1).
|
|
89
|
+
2. Confirm auth (`auth status` or env vars).
|
|
90
|
+
3. Resolve project (`projects list` / known slug).
|
|
91
|
+
4. `search` → if snippets are thin, `docs get`.
|
|
92
|
+
5. Write only when asked (`docs create/update`, `assets upload`).
|
|
93
|
+
6. Do **not** echo tokens; do **not** call MCP from this skill.
|
|
94
|
+
|
|
95
|
+
## 5. Extra detail
|
|
96
|
+
|
|
97
|
+
- Command cheat sheet: [reference.md](reference.md)
|
|
98
|
+
- This directory is the copy shipped inside the `@pokelo/cli` npm package (`skill/`).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Pokelo CLI reference
|
|
2
|
+
|
|
3
|
+
## Package vs binary
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
npm i -g @pokelo/cli → installs package @pokelo/cli
|
|
7
|
+
→ binary name: pokelo
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Config priority
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
--url / --token / --project
|
|
14
|
+
> POKELO_URL / POKELO_TOKEN / POKELO_PROJECT
|
|
15
|
+
> ~/.config/pokelo/config.json
|
|
16
|
+
> legacy ~/.pokelo-cli.json (read for migration on login)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
URL forms `https://host` and `https://host/v1` both normalize to `…/v1`.
|
|
20
|
+
|
|
21
|
+
## Auth
|
|
22
|
+
|
|
23
|
+
| Command | Notes |
|
|
24
|
+
|---------|--------|
|
|
25
|
+
| `pokelo auth login --url U --token T` | Persist config; never echo T |
|
|
26
|
+
| `pokelo auth login --url U --token-stdin` | Token from stdin |
|
|
27
|
+
| `pokelo auth login` | Interactive TTY only |
|
|
28
|
+
| `pokelo auth status` | Masked preview `mcp_…****` |
|
|
29
|
+
|
|
30
|
+
## Projects / search / docs
|
|
31
|
+
|
|
32
|
+
| Command | REST |
|
|
33
|
+
|---------|------|
|
|
34
|
+
| `projects list` | `GET /projects` |
|
|
35
|
+
| `projects get <ref>` | `GET /projects/:id` |
|
|
36
|
+
| `search "q" -p <ref> -l n` | `POST /projects/:id/documents/search` |
|
|
37
|
+
| `docs list -p <ref>` | `GET /projects/:id/documents` |
|
|
38
|
+
| `docs get <ref> -p <ref>` | `GET /projects/:id/documents/:id` |
|
|
39
|
+
| `docs create --title …` | `POST /projects/:id/documents` |
|
|
40
|
+
| `docs update <ref> …` | `PATCH /projects/:id/documents/:id` |
|
|
41
|
+
|
|
42
|
+
## Assets
|
|
43
|
+
|
|
44
|
+
| Command | REST |
|
|
45
|
+
|---------|------|
|
|
46
|
+
| `assets list` | `GET /projects/:id/assets` |
|
|
47
|
+
| `assets get <id>` | `GET /projects/:id/assets/:id` |
|
|
48
|
+
| `assets upload <file>` | `POST …/base64` or uploads+complete |
|
|
49
|
+
| `assets download <id> --out F` | get + downloadUrl / content redirect |
|
|
50
|
+
| `assets update <id>` | `PATCH /projects/:id/assets/:id` |
|
|
51
|
+
| `assets delete <id>` | `DELETE /projects/:id/assets/:id` |
|
|
52
|
+
|
|
53
|
+
Filters for list: `--type`, `--source`, `--visibility`, `--document`, `--page`, `--limit`.
|
|
54
|
+
|
|
55
|
+
## Safety
|
|
56
|
+
|
|
57
|
+
- Never print the full PAT.
|
|
58
|
+
- Prefer `--token-stdin` or env over `--token` when possible.
|
|
59
|
+
- Do not commit `~/.config/pokelo/config.json`.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Ensure the `pokelo` binary is on PATH. No-op if already available.
|
|
3
|
+
# npm package name: @pokelo/cli → CLI command: pokelo
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
if command -v pokelo >/dev/null 2>&1; then
|
|
7
|
+
echo "pokelo already available: $(command -v pokelo)"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
if command -v npm >/dev/null 2>&1; then
|
|
12
|
+
echo "Installing @pokelo/cli (provides \`pokelo\` binary)…"
|
|
13
|
+
if npm install -g @pokelo/cli; then
|
|
14
|
+
if command -v pokelo >/dev/null 2>&1; then
|
|
15
|
+
echo "Installed: $(command -v pokelo)"
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
echo "Package installed but \`pokelo\` not on PATH; check npm global bin." >&2
|
|
19
|
+
else
|
|
20
|
+
echo "npm install -g @pokelo/cli failed (package may be unpublished)." >&2
|
|
21
|
+
fi
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Monorepo / package-local fallbacks
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
CANDIDATES=(
|
|
27
|
+
# skill shipped inside tools/pokelo-cli/skill/scripts
|
|
28
|
+
"$SCRIPT_DIR/../../bin/pokelo.mjs"
|
|
29
|
+
# .cursor/skills/pokelo-cli/scripts → repo tools/pokelo-cli
|
|
30
|
+
"$SCRIPT_DIR/../../../tools/pokelo-cli/bin/pokelo.mjs"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
mkdir -p "${HOME}/.local/bin"
|
|
34
|
+
for candidate in "${CANDIDATES[@]}"; do
|
|
35
|
+
if [[ -f "$candidate" ]]; then
|
|
36
|
+
ln -sfn "$candidate" "${HOME}/.local/bin/pokelo"
|
|
37
|
+
export PATH="${HOME}/.local/bin:${PATH}"
|
|
38
|
+
if command -v pokelo >/dev/null 2>&1; then
|
|
39
|
+
echo "Linked local CLI: $candidate → ~/.local/bin/pokelo"
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
echo "Error: could not locate or install pokelo." >&2
|
|
46
|
+
echo "Fix: npm install -g @pokelo/cli OR symlink tools/pokelo-cli/bin/pokelo.mjs" >&2
|
|
47
|
+
exit 1
|
package/src/cli.mjs
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { fail } from './exit.mjs';
|
|
2
|
+
import { runAssets } from './commands/assets.mjs';
|
|
3
|
+
import { runAuth } from './commands/auth.mjs';
|
|
4
|
+
import { runDocs } from './commands/docs.mjs';
|
|
5
|
+
import { runProjects } from './commands/projects.mjs';
|
|
6
|
+
import { runSearch } from './commands/search.mjs';
|
|
7
|
+
|
|
8
|
+
function printHelp() {
|
|
9
|
+
process.stdout.write(
|
|
10
|
+
`pokelo — Pokelo public API CLI for agents and developers
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
pokelo auth login --url <url> --token <token>
|
|
14
|
+
pokelo auth login --url <url> --token-stdin
|
|
15
|
+
pokelo auth login
|
|
16
|
+
pokelo auth status
|
|
17
|
+
|
|
18
|
+
pokelo projects list
|
|
19
|
+
pokelo projects get <project-id-or-slug>
|
|
20
|
+
|
|
21
|
+
pokelo search "<query>" [--project <ref>] [--limit <n>]
|
|
22
|
+
|
|
23
|
+
pokelo docs list [--project <ref>]
|
|
24
|
+
pokelo docs get <document-id-or-slug> [--project <ref>]
|
|
25
|
+
pokelo docs create --title <t> [--type] [--content|--content-file] [--parent] [--project]
|
|
26
|
+
pokelo docs update <document-id-or-slug> [options]
|
|
27
|
+
|
|
28
|
+
pokelo assets list [--project] [--type] [--visibility] [--document]
|
|
29
|
+
pokelo assets get <asset-id> [--project]
|
|
30
|
+
pokelo assets upload <file> [--name] [--mime] [--visibility] [--document] [--description]
|
|
31
|
+
pokelo assets download <asset-id> --out <path> [--project]
|
|
32
|
+
pokelo assets update <asset-id> [--name] [--description] [--visibility] [--document]
|
|
33
|
+
pokelo assets delete <asset-id> [--project]
|
|
34
|
+
|
|
35
|
+
Global options:
|
|
36
|
+
--project, -p <ref> Project UUID or slug (or POKELO_PROJECT / config default)
|
|
37
|
+
--url <url> Instance URL (overrides env/config)
|
|
38
|
+
--token <token> Personal Access Token (overrides env/config; prefer env/--token-stdin)
|
|
39
|
+
--json Accepted for compatibility (stdout is always JSON)
|
|
40
|
+
--help, -h Show help
|
|
41
|
+
|
|
42
|
+
Config (priority: flags > env > file):
|
|
43
|
+
POKELO_URL, POKELO_TOKEN, POKELO_PROJECT
|
|
44
|
+
~/.config/pokelo/config.json
|
|
45
|
+
|
|
46
|
+
Exit codes: 0 ok, 1 usage/config, 2 API/network error
|
|
47
|
+
`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Minimal argv parser: supports long flags, -p/-l/-h, and --flag=value.
|
|
53
|
+
* @param {string[]} argv
|
|
54
|
+
*/
|
|
55
|
+
export function parseArgs(argv) {
|
|
56
|
+
/** @type {Record<string, unknown>} */
|
|
57
|
+
const flags = {};
|
|
58
|
+
const positional = [];
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < argv.length; i++) {
|
|
61
|
+
const arg = argv[i];
|
|
62
|
+
if (arg === '--') {
|
|
63
|
+
positional.push(...argv.slice(i + 1));
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if (arg === '--help' || arg === '-h') {
|
|
67
|
+
flags.help = true;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (arg === '--json') {
|
|
71
|
+
flags.json = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (arg === '--token-stdin') {
|
|
75
|
+
flags.tokenStdin = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (arg === '--tree') {
|
|
79
|
+
flags.tree = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const eq = arg.match(/^--([a-zA-Z0-9-]+)=(.*)$/);
|
|
84
|
+
if (eq) {
|
|
85
|
+
setFlag(flags, eq[1], eq[2]);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (arg === '--project' || arg === '-p') {
|
|
90
|
+
flags.project = needValue(argv, ++i, arg);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (arg === '--limit' || arg === '-l') {
|
|
94
|
+
flags.limit = parseInt(needValue(argv, ++i, arg), 10);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (arg === '--page') {
|
|
98
|
+
flags.page = parseInt(needValue(argv, ++i, arg), 10);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (arg === '--url') {
|
|
102
|
+
flags.url = needValue(argv, ++i, arg);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (arg === '--token') {
|
|
106
|
+
flags.token = needValue(argv, ++i, arg);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (arg === '--title') {
|
|
110
|
+
flags.title = needValue(argv, ++i, arg);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (arg === '--type') {
|
|
114
|
+
flags.type = needValue(argv, ++i, arg);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (arg === '--content') {
|
|
118
|
+
flags.content = needValue(argv, ++i, arg);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (arg === '--content-file') {
|
|
122
|
+
flags.contentFile = needValue(argv, ++i, arg);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (arg === '--parent') {
|
|
126
|
+
flags.parent = needValue(argv, ++i, arg);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (arg === '--status') {
|
|
130
|
+
flags.status = needValue(argv, ++i, arg);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (arg === '--search' || arg === '-q') {
|
|
134
|
+
flags.search = needValue(argv, ++i, arg);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (arg === '--name') {
|
|
138
|
+
flags.name = needValue(argv, ++i, arg);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (arg === '--mime' || arg === '--mime-type') {
|
|
142
|
+
flags.mime = needValue(argv, ++i, arg);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (arg === '--visibility') {
|
|
146
|
+
flags.visibility = needValue(argv, ++i, arg);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (arg === '--document' || arg === '--document-id') {
|
|
150
|
+
flags.document = needValue(argv, ++i, arg);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (arg === '--description') {
|
|
154
|
+
flags.description = needValue(argv, ++i, arg);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (arg === '--source') {
|
|
158
|
+
flags.source = needValue(argv, ++i, arg);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (arg === '--out') {
|
|
162
|
+
flags.out = needValue(argv, ++i, arg);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (arg.startsWith('-')) {
|
|
167
|
+
fail(`unknown option: ${arg}`);
|
|
168
|
+
}
|
|
169
|
+
positional.push(arg);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return { flags, positional };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function needValue(argv, index, flag) {
|
|
176
|
+
if (index >= argv.length) fail(`missing value for ${flag}`);
|
|
177
|
+
return argv[index];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function setFlag(flags, name, value) {
|
|
181
|
+
const map = {
|
|
182
|
+
project: 'project',
|
|
183
|
+
limit: 'limit',
|
|
184
|
+
page: 'page',
|
|
185
|
+
url: 'url',
|
|
186
|
+
token: 'token',
|
|
187
|
+
title: 'title',
|
|
188
|
+
type: 'type',
|
|
189
|
+
content: 'content',
|
|
190
|
+
'content-file': 'contentFile',
|
|
191
|
+
parent: 'parent',
|
|
192
|
+
status: 'status',
|
|
193
|
+
search: 'search',
|
|
194
|
+
name: 'name',
|
|
195
|
+
mime: 'mime',
|
|
196
|
+
'mime-type': 'mime',
|
|
197
|
+
visibility: 'visibility',
|
|
198
|
+
document: 'document',
|
|
199
|
+
'document-id': 'document',
|
|
200
|
+
description: 'description',
|
|
201
|
+
source: 'source',
|
|
202
|
+
out: 'out',
|
|
203
|
+
};
|
|
204
|
+
const key = map[name];
|
|
205
|
+
if (!key) fail(`unknown option: --${name}`);
|
|
206
|
+
if (key === 'limit' || key === 'page') {
|
|
207
|
+
flags[key] = parseInt(value, 10);
|
|
208
|
+
} else {
|
|
209
|
+
flags[key] = value;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @param {string[]} argv
|
|
215
|
+
*/
|
|
216
|
+
export async function main(argv) {
|
|
217
|
+
const { flags, positional } = parseArgs(argv);
|
|
218
|
+
|
|
219
|
+
if (flags.help || positional.length === 0) {
|
|
220
|
+
printHelp();
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const cmd = positional[0];
|
|
225
|
+
const rest = positional.slice(1);
|
|
226
|
+
|
|
227
|
+
switch (cmd) {
|
|
228
|
+
case 'help':
|
|
229
|
+
printHelp();
|
|
230
|
+
break;
|
|
231
|
+
case 'auth':
|
|
232
|
+
await runAuth(rest, flags);
|
|
233
|
+
break;
|
|
234
|
+
case 'projects':
|
|
235
|
+
await runProjects(rest, flags);
|
|
236
|
+
break;
|
|
237
|
+
case 'search':
|
|
238
|
+
await runSearch(rest, flags);
|
|
239
|
+
break;
|
|
240
|
+
case 'docs':
|
|
241
|
+
await runDocs(rest, flags);
|
|
242
|
+
break;
|
|
243
|
+
case 'assets':
|
|
244
|
+
await runAssets(rest, flags);
|
|
245
|
+
break;
|
|
246
|
+
// Back-compat aliases from MCP PoC
|
|
247
|
+
case 'list':
|
|
248
|
+
await runDocs(['list', ...rest], flags);
|
|
249
|
+
break;
|
|
250
|
+
case 'get':
|
|
251
|
+
await runDocs(['get', ...rest], flags);
|
|
252
|
+
break;
|
|
253
|
+
default:
|
|
254
|
+
fail(`unknown command: ${cmd}\nRun: pokelo --help`);
|
|
255
|
+
}
|
|
256
|
+
}
|