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 +72 -0
- package/README.md +9 -0
- package/cli.mjs +12 -3
- package/package.json +3 -2
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
|
-
|
|
169
|
-
|
|
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.
|
|
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"
|