neodrop-cli 1.1.0 → 2.0.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.
@@ -1,74 +1,125 @@
1
1
  # neodrop-cli command reference
2
2
 
3
- > Invocation convention: use `npx neodrop-cli <command>` (see [SKILL.md → How to invoke](../SKILL.md#how-to-invoke)).
4
- > Equivalent explicit package + bin form: `npx -p neodrop-cli neodrop <command>`.
5
- > Examples below are written as `neodrop <command>`.
3
+ > Invocation convention: `npx neodrop-cli <command>` (see [SKILL.md → How to invoke](../SKILL.md#how-to-invoke)).
4
+ > Equivalent explicit form: `npx -p neodrop-cli neodrop <command>`. Examples below are written as `neodrop <command>`.
5
+ >
6
+ > Every command prints **valid JSON to stdout**; logs, progress and `🔗` links go to stderr. Add `--pretty` for indented JSON, `--help` on any command for its arguments.
6
7
 
7
8
  ## identity
8
9
 
9
- ```bash
10
- neodrop me # current user info (user.getMe)
11
- neodrop whoami # me + token metadata (credential + expiry)
12
- neodrop tokens list # every PAT you've issued
13
- neodrop tokens revoke <id> # revoke a PAT; if it's this machine's token, the local credential is cleared too
14
- ```
10
+ | Command | What it does |
11
+ |---|---|
12
+ | `neodrop me` | Current user info (`user.getMe`). |
13
+ | `neodrop whoami` | `me` plus token metadata — which credential is in use and when it expires. |
14
+ | `neodrop tokens list` | Every Personal Access Token you've issued. |
15
+ | `neodrop tokens revoke <id>` | Revoke a PAT. If it's this machine's token, the local credential is cleared too. |
15
16
 
16
17
  ## channels
17
18
 
18
- ### View / search
19
+ **View & search**
19
20
 
20
- ```bash
21
- neodrop channels list --mine # channels you own
22
- neodrop channels list --locale en --limit 20 # public channels, paginated
23
- neodrop channels get <channelId> # single channel detail (incl. requirement.public)
24
- neodrop channels categories # all categories
25
- neodrop channels by-category tech --sort latest --limit 20
21
+ | Command | What it does |
22
+ |---|---|
23
+ | `neodrop channels list --mine` | Channels you own. |
24
+ | `neodrop channels list --locale en --limit 20` | Public channels, paginated. |
25
+ | `neodrop channels get <channelId>` | Single channel detail, including `requirement.public`. |
26
+ | `neodrop channels categories` | All channel categories. |
27
+ | `neodrop channels by-category <category> --sort latest --limit 20` | Channels in a category. |
28
+ | `neodrop channels search "<query>" --locale en --limit 10` | Full-text search over the public pool. |
26
29
 
27
- neodrop channels search "AI weekly" --locale en --limit 10
28
- ```
30
+ **Create (async runs the creation agent)**
29
31
 
30
- ### Write
32
+ `channels create` starts the **same creation-agent pipeline as the web wizard**: it immediately creates the channel in `DRAFT`, then an agent researches the topic, generates the runnable configuration (requirement / sources / schedule) and activates the channel. This usually takes **a few minutes** and consumes credits.
31
33
 
32
- ```bash
33
- neodrop channels create --name "AI industry tracker" --description "..." --locale en
34
- neodrop channels create --json '{"name":"X","locale":"en","type":"PRIVATE"}'
35
- neodrop channels subscribe <channelId>
36
- neodrop channels unsubscribe <channelId>
37
- ```
34
+ | Command | What it does |
35
+ |---|---|
36
+ | `neodrop channels create --name "<name>" --prompt "<brief>" --locale en` | Start creation; returns the `agentTask` right away (`task.id` + `task.channelId`). |
37
+ | `neodrop channels create --name "<name>" --prompt "<brief>" --wait` | Block until the task reaches a terminal status (polls every 15s, 20min cap). |
38
+ | `neodrop channels create-status <taskId>` | Poll an in-flight creation task. |
38
39
 
39
- **Default locale**: `channels list` defaults to `en`, matching the product's default public pool. `channels search` and `channels by-category` omit locale when `--locale` is not provided and let the backend decide. Pass `--locale en` (etc.) explicitly to query the public pool across locales.
40
+ | Flag | Purpose |
41
+ |---|---|
42
+ | `--name` (required) | Channel name shown to users. |
43
+ | `--prompt` | Free-form creation instructions for the agent — topic, audience, style, cadence. Strongly recommended; without it the agent only has the name to go on. |
44
+ | `--description` | One-line channel intro (shown on the channel page; not the agent instructions). |
45
+ | `--carrier Article\|ImagePost\|Podcast\|Music\|Video` | Content modality; omit to let the platform default (Article). |
46
+ | `--json '{...}' \| --stdin` | Advanced — raw `agentTask.create` input (`channelName` / `channelDescription` / `description` (= prompt) / `locale` / `contentCarrier`). |
47
+
48
+ - Task `status`: `PENDING` / `RUNNING` → in progress; `COMPLETED` → done; `FAILED` → failed (exit 1 with `--wait`); `PAUSED` → out of credits, auto-resumes after topping up.
49
+ - New channels default to **PUBLIC** visibility; flip it later on the web manage page.
50
+ - A bare `channel.create` (shell only, stays `DRAFT` forever, no runnable config) is intentionally **not** a sugar command; if you really need it: `api channel.create --json '{"name":"X"}' --mutation`.
51
+
52
+ **Run (produce one issue now)**
53
+
54
+ | Command | What it does |
55
+ |---|---|
56
+ | `neodrop channels run <channelId>` | `channel.triggerRun` — manual production run. Requires a runnable config (creation finished; a `DRAFT` with config is auto-activated). Fails with a clear error while creation is still in progress. |
57
+
58
+ **Subscribe**
59
+
60
+ | Command | What it does |
61
+ |---|---|
62
+ | `neodrop channels subscribe <channelId>` | Subscribe to a channel. |
63
+ | `neodrop channels unsubscribe <channelId>` | Unsubscribe from a channel. |
64
+
65
+ > **Locale defaults**: `channels list` defaults to `en` (the product's default public pool). `channels search` / `by-category` omit locale unless you pass `--locale`, letting the backend decide. Pass `--locale en` (etc.) explicitly to query across locales.
40
66
 
41
67
  ## posts
42
68
 
43
- > The content unit is called a **post** on Neodrop. The old command name `grains` is kept as a backward-compatible alias, but new code should use `posts`.
69
+ > The content unit is a **post**. The old name `grains` stays as a backward-compatible alias; new code should use `posts`.
70
+
71
+ | Command | What it does |
72
+ |---|---|
73
+ | `neodrop posts list --limit 10` | Public feed. |
74
+ | `neodrop posts list --subscribed --limit 10` | Posts from your subscriptions (same as `neodrop feed --limit 10`). |
75
+ | `neodrop posts list --channel <channelId> --limit 10` | Posts from one channel. |
76
+ | `neodrop posts get <postId>` | Single post detail. |
77
+ | `neodrop posts search "<query>" --limit 10` | Full-text search over posts. |
78
+ | `neodrop feed --limit 10` | Alias for `posts list --subscribed`. |
79
+
80
+ ## chat
81
+
82
+ Talk to Neodrop's AI assistants as the current user. The command **blocks until the reply is fully generated** (replies come from a backend worker and survive disconnects), then prints the complete result as JSON.
83
+
84
+ | Command | What it does |
85
+ |---|---|
86
+ | `neodrop chat "<message>"` | Send a message to the **global assistant** in a new session. |
87
+ | `neodrop chat "<message>" --session <sessionId>` | Continue an existing session. |
88
+ | `neodrop chat "<message>" --channel <channelId>` | Talk to a **channel assistant** (owner: can edit the channel's config; reader: Q&A about the channel). |
89
+ | `neodrop chat history --session <sessionId>` | Full message list of a session. |
90
+ | `neodrop chat sessions` | Your sessions — find one to continue. |
91
+
92
+ **Flags**
93
+
94
+ | Flag | Default | Purpose |
95
+ |---|---|---|
96
+ | `--session <id>` | — | Continue a specific session instead of starting a new one. |
97
+ | `--channel <id>` | — | Target a channel assistant instead of the global assistant. |
98
+ | `--locale <code>` | `en` | Language of the assistant's error messages. |
99
+ | `--timeout <seconds>` | `600` | Max total wait. On timeout the reply keeps generating server-side — fetch it later with `chat history`. |
44
100
 
45
- ```bash
46
- neodrop posts list --limit 10 # public feed
47
- neodrop posts list --subscribed --limit 10 # your subscriptions (= neodrop feed --limit 10)
48
- neodrop posts list --channel <channelId> --limit 10
49
- neodrop posts get <postId>
50
- neodrop posts search "Apple Intelligence" --limit 10
101
+ **Output shape**: `{sessionId, reply: {text, parts} | null, newMessages: [...]}` — `reply.text` is the assistant's final text; `newMessages` is every message produced this turn (tool calls, cards, …). `reply` can be `null` if generation failed; inspect `newMessages` then.
51
102
 
52
- neodrop feed --limit 10 # alias for posts list --subscribed
53
- ```
103
+ - A new conversation prints its `sessionId` on stderr — **reuse it with `--session` for follow-ups**, don't start a fresh session per question.
104
+ - Chat consumes the account's AI credits like the web app does; a `402 insufficient_credits` error means the user must top up.
54
105
 
55
106
  ## api
56
107
 
57
108
  For tRPC procedures with no sugar command, fall back to `api`:
58
109
 
59
- ```bash
60
- neodrop api channel.update --json '{"id":"<chId>","name":"New name"}' --mutation
61
- neodrop api user.getLinkedAccounts # any query
62
- echo '{...}' | neodrop api channel.create --stdin --mutation
63
- ```
110
+ | Command | What it does |
111
+ |---|---|
112
+ | `neodrop api <procedure>` | Call any tRPC **query** (GET). |
113
+ | `neodrop api <procedure> --json '{...}' --mutation` | Call a **write** `--mutation` is required or the backend rejects it as a query. |
114
+ | `echo '{...}' \| neodrop api <procedure> --stdin --mutation` | Read the JSON input from stdin (great for heredocs / pipelines). |
64
115
 
65
- - **Defaults to a GET query** — a mutation (write) MUST add `--mutation` explicitly, or the backend routes it as a query and rejects it.
66
- - Pass complex input with `--json '...'` inline, or `--stdin` to read from standard input (great for heredocs / pipelines).
67
- - To find a procedure's full name, check the main repo's `packages/backend/src/api/trpc/routers.ts`, or probe with `curl /api/trpc/<router>.<procedure>?input=...` against a dev backend.
116
+ - **Defaults to a GET query** — every write MUST add `--mutation` explicitly.
117
+ - To find a procedure's full name, check the main repo's `packages/backend/src/api/trpc/routers.ts`, or probe `curl /api/trpc/<router>.<procedure>?input=...` against a dev backend.
118
+ - **Field contracts are strict where it matters**: `channel.update` accepts exactly `{id, name?, description?, avatar?}` and `channel.create` exactly `{name, description?, type?, locale?}` — unknown keys are rejected with `BAD_REQUEST` (they are **not** a way to write channel configuration; the runnable config is owned by the creation agent, see [channels → Create](#channels)). Other procedures may still silently strip unknown keys (standard zod behavior), so don't infer "accepted" from a success response — verify the response body.
68
119
 
69
- ## Global
120
+ ## Global flags
70
121
 
71
- ```bash
72
- neodrop --pretty <cmd> # indented JSON for humans (still valid JSON)
73
- neodrop <cmd> --help # subcommand arguments
74
- ```
122
+ | Flag | Purpose |
123
+ |---|---|
124
+ | `--pretty` | Indented JSON for humans (still valid JSON). |
125
+ | `--help` | Show a subcommand's arguments. |
@@ -25,7 +25,9 @@ When the CLI errors, **first read the error code in brackets on stderr**, then m
25
25
  | Symptom | Meaning | Fix |
26
26
  |---|---|---|
27
27
  | `[NOT_FOUND]` | id / slug doesn't exist | List with `channels list` / `posts list` first to verify the id |
28
- | `[BAD_REQUEST]` | Input schema is wrong (most common with `--json`) | Read the stderr detail; cross-check `neodrop <cmd> --help`; for complex input, get it working with a sugar command first, then drop to `--json` |
28
+ | `[BAD_REQUEST]` | Input schema is wrong (most common with `--json`), including unknown keys on `channel.create` / `channel.update` — those two reject unrecognized fields instead of stripping them | Read the stderr detail; cross-check `neodrop <cmd> --help` and the field contracts in [commands.md#api](commands.md#api); for complex input, get it working with a sugar command first, then drop to `--json` |
29
+ | `[FORBIDDEN]` mentioning credits on `channels create` | Channel creation costs credits and the account balance is insufficient | Ask the user to top up / check in on the web app, then retry |
30
+ | Error saying the channel is still a draft with no runnable config on `channels run` | The channel is a bare `DRAFT` shell — creation never ran or is still in progress | If a creation task exists: poll `channels create-status <taskId>` until `COMPLETED`, then rerun. If the channel was created as a bare shell (old CLI ≤1.x or raw `api channel.create`): create it properly with `channels create --name ... --prompt ...` — a shell can't be activated in place |
29
31
  | `[INTERNAL_SERVER_ERROR]` | The backend crashed | Retry once; if it persists, open an issue with the full stderr |
30
32
 
31
33
  ## Environment