noeta-cli 0.1.0 → 0.1.1

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/AGENTS.md ADDED
@@ -0,0 +1,72 @@
1
+ # Using `noeta-cli` (for coding agents)
2
+
3
+ You are an agent with shell access. `noeta-cli` is a portal to a **Noeta Cloud** workspace —
4
+ read, write, edit, and find documents (and tables, comments, chat) from the command line, with
5
+ **no MCP client configuration**. This file is the playbook; the CLI itself is the live reference.
6
+
7
+ ## The loop: authenticate → discover → act
8
+
9
+ ```bash
10
+ # 1. AUTHENTICATE (once per machine/deployment). Opens the user's browser to approve; finishes
11
+ # on their click. If you're headless, add --no-open: login prints BOTH a direct link and a
12
+ # short code + /activate URL — hand either to the user. They can approve on any already-signed-in
13
+ # device (e.g. their phone) by typing the code at /activate. Nothing is emailed.
14
+ npx noeta-cli login # defaults to https://noeta.cloud
15
+ npx noeta-cli whoami # confirm identity + which workspace + your access cap
16
+
17
+ # 2. DISCOVER the tool surface + exact argument schemas (authoritative — do this, don't guess):
18
+ npx noeta-cli tools # names + one-line descriptions
19
+ npx noeta-cli tools --json # full JSON with inputSchema for every tool
20
+
21
+ # 3. ACT — every tool is `call <name> '<json-args>'`:
22
+ npx noeta-cli call <tool> '{"...":"..."}'
23
+ ```
24
+
25
+ Installed globally (`npm i -g noeta-cli`) the command is just `noeta`; `npx noeta-cli` always
26
+ works with no install. Everything below uses `noeta`.
27
+
28
+ ## Finding, reading, writing, editing documents
29
+
30
+ The tool set is discovered at runtime (`noeta tools --json`) — treat that as SSOT, not this list.
31
+ As of writing the verbs map like so:
32
+
33
+ | Intent | Tool(s) | Notes |
34
+ |---|---|---|
35
+ | **Find** a doc/folder/table | `list_resources`, `get_related` | Browse the workspace tree; get the `docId` you need |
36
+ | **Read** a doc | `get_doc` | Returns the block tree (ids, types, content). **Call this first** — edits target block ids |
37
+ | **Create** a doc / folder | `create_doc`, `create_folder` | New document or folder; pass `parentId` to nest (else workspace root) |
38
+ | **Write** into a doc | `insert_blocks` | Append, or place `afterId`/`beforeId` a block id from `get_doc` |
39
+ | **Edit** a block | `update_block` | Change a block's type/props/content by id |
40
+ | **Delete** blocks | `remove_blocks` | By id; ids already gone are skipped, not errors |
41
+ | **Organize** | `move_resource` | Move a doc/folder into a folder (or to root with `parentId: null`); needs editor on both ends |
42
+ | **Share** with a member/team | `share_resource` | Grant an existing member (`user`) or team (`group`) a role; needs **manager** on the resource |
43
+ | **Invite an outsider** | `invite_guest` | Invite someone by email to a SINGLE resource as a scoped guest (no workspace-wide access); needs **manager**. Sends an invite email; the grant applies when they accept |
44
+ | Comment / versions / chat / tables | `comment`, `list_versions`, `restore_version`, `post_message`, `get_thread`, table ops | See `noeta tools --json` |
45
+
46
+ Typical edit session:
47
+
48
+ ```bash
49
+ noeta call list_resources '{}' # find the doc, note its id
50
+ noeta call get_doc '{"docId":"<id>"}' # read block tree, pick target ids
51
+ noeta call insert_blocks '{"docId":"<id>","blocks":[{"type":"paragraph","content":"…"}]}'
52
+ noeta call update_block '{"docId":"<id>","id":"<blockId>","block":{"content":"revised"}}'
53
+ ```
54
+
55
+ ## The agent contract
56
+
57
+ - **No command reads stdin** — safe to run noninteractively.
58
+ - `--json` makes **stdout a single machine-readable value**; all progress/errors go to **stderr**.
59
+ - **Exit codes:** `0` ok · `1` usage/network/server error · `2` login denied/expired/timed out ·
60
+ `3` the tool call itself returned an error (reason on stderr). Branch on these, not on parsing text.
61
+ - **Target/token resolution:** `--url` flag > `NOETA_URL` > last login; token `NOETA_TOKEN` > stored.
62
+ Credentials live in `~/.config/noeta/credentials.json` (override dir with `NOETA_CONFIG_DIR`).
63
+
64
+ ## What your identity is (and safety)
65
+
66
+ Approving mints a **delegated identity**: you act on the approving user's behalf, capped at the
67
+ access level they picked — you can do at most what they can, and everything you write is attributed
68
+ to them *via* the agent. There's no separate secret to manage. The user can revoke you any time
69
+ (`noeta logout`, or `DELETE /api/agents/<id>` as themselves). Prefer read tools when exploring;
70
+ only write when the task calls for it.
71
+
72
+ Full human reference: `README.md` in this package, or `noeta help`.
package/README.md CHANGED
@@ -15,6 +15,12 @@ finishes on the click — it never asks for terminal input — and saves the tok
15
15
  locally. From then on the CLI *is* the integration; no MCP client
16
16
  configuration required:
17
17
 
18
+ **No browser on this machine?** (a server, an SSH session, a container.) `login`
19
+ also prints a short code and an `/activate` URL. On any device that's already
20
+ signed in — your phone, say — go to `https://noeta.cloud/activate`, type the
21
+ code, and approve there. Nothing is emailed; you initiate it from the terminal
22
+ and confirm on a device you're already logged into.
23
+
18
24
  ```bash
19
25
  npx noeta-cli whoami # who am I, which workspace, what cap
20
26
  npx noeta-cli tools # list the workspace's tools
@@ -39,6 +45,9 @@ signed-in user).
39
45
 
40
46
  ## For agents driving this programmatically
41
47
 
48
+ **Coding agent?** Read [`AGENTS.md`](./AGENTS.md) — the playbook for driving this from a shell
49
+ (authenticate → `noeta tools --json` to discover → `noeta call`). The short version:
50
+
42
51
  No command reads stdin, and `--json` makes stdout a single machine-readable
43
52
  value (progress and errors go to stderr):
44
53
 
package/cli.mjs CHANGED
@@ -162,11 +162,20 @@ async function cmdLogin() {
162
162
 
163
163
  const startRes = await post(baseUrl, "/api/agent-auth/start", { clientName: opts.name });
164
164
  if (!startRes.ok) die(`start failed: HTTP ${startRes.status} ${await startRes.text()}`);
165
- const { deviceCode, verifyUrl, expiresIn, interval } = await startRes.json();
165
+ const { deviceCode, verifyUrl, activateUrl, userCode, expiresIn, interval } = await startRes.json();
166
166
 
167
167
  const windowSec = Number.isFinite(opts.timeout) && opts.timeout > 0 ? opts.timeout : expiresIn;
168
- log(`\nAuthorize ${opts.name} in your browser (link expires in ${Math.round(expiresIn / 60)} min):\n`);
169
- log(`\n ${verifyUrl}\n\n`);
168
+ const mins = Math.round(expiresIn / 60);
169
+ // Group the short code as XXXX-XXXX so it's easy to read off one screen and type on another.
170
+ const grouped = userCode ? userCode.replace(/(.{4})(?=.)/g, "$1-") : null;
171
+ log(`\nAuthorize ${opts.name} (expires in ${mins} min):\n`);
172
+ if (activateUrl && grouped) {
173
+ // Cross-device path (e.g. approve on your phone): type the code at /activate.
174
+ log(`\n • This machine — your browser should open; if not, visit:\n ${verifyUrl}\n`);
175
+ log(`\n • Another device already signed in (e.g. your phone):\n go to ${activateUrl}\n enter ${grouped}\n\n`);
176
+ } else {
177
+ log(`\n ${verifyUrl}\n\n`);
178
+ }
170
179
  if (opts.open) openBrowser(verifyUrl);
171
180
  log("Waiting for approval…");
172
181
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noeta-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI portal to Noeta Cloud for agents & humans: `npx noeta-cli login` (browser approval, no prompts), then call the workspace API/MCP tools directly — no MCP client configuration required.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,8 @@
8
8
  },
9
9
  "files": [
10
10
  "cli.mjs",
11
- "README.md"
11
+ "README.md",
12
+ "AGENTS.md"
12
13
  ],
13
14
  "engines": {
14
15
  "node": ">=18"