nah-studio 0.0.1-beta.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AstraCollab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # nah-studio
2
+
3
+ The dashboard for `nah`. Every agent on the machine, what each one did, and what
4
+ it cost.
5
+
6
+ Normally you do not install this yourself — type `/studio` inside `nah` and it is
7
+ installed on first use, started in the background, and opened in a browser. The
8
+ command it runs is `nah serve`, and it works on its own too, which is the case
9
+ that matters when several agents are running and none of them is at your terminal.
10
+
11
+ ```sh
12
+ npx nah-studio # 127.0.0.1:4111, watching this directory
13
+ nah-studio --port 0 # any free port; the real one is printed
14
+ nah-studio --host 0.0.0.0 # on the network — needs NAH_STUDIO_TOKEN
15
+ nah-studio --no-publish # invisible to agents; nothing reports to it
16
+ ```
17
+
18
+ | Flag | What it does |
19
+ | --- | --- |
20
+ | `--port <n>` | Port to listen on (default 4111) |
21
+ | `--host <addr>` | Address to bind (default 127.0.0.1) |
22
+ | `--cwd <dir>` | Where the built-in chat agent works (default: cwd) |
23
+ | `--model <spec>` | `provider:model-id` for the chat tab and evaluations |
24
+ | `--db <path>` | SQLite file (default `~/.nah/studio/studio.sqlite`) |
25
+ | `--nah-bin <path>` | The `nah` to launch agents with (default: the one on PATH) |
26
+ | `--no-publish` | Do not write `~/.nah/studio.json`, so no agent finds this Studio |
27
+
28
+ ## How agents get here
29
+
30
+ There is no registration step and nothing to configure in the agent. The Studio
31
+ writes `~/.nah/studio.json` when it starts — its URL, its pid, and the `nah` that
32
+ started it — and every `nah` session on the machine reads that file once, at
33
+ startup.
34
+
35
+ A session that finds a live Studio registers itself (`POST /api/agents`) and pushes
36
+ each finished turn to `POST /api/traces` with its spans. A session that finds
37
+ nothing sends nothing anywhere. That is the whole opt-in: telemetry is off unless
38
+ a dashboard asked for it by existing.
39
+
40
+ One row per process. Two sessions in one repository are two agents, because
41
+ "is anything running right now" is a question a merged row cannot answer. The
42
+ friendly name defaults to the directory's name, and `NAH_AGENT_NAME` overrides it —
43
+ which is how an agent the Studio launched gets named for the row already on screen.
44
+
45
+ **Status is inferred, never waited for.** The column records what an agent last
46
+ said about itself, and the online dot is decided at read time from how long ago
47
+ that was. Nothing writes "offline": a machine that sleeps, or a process that was
48
+ killed, cannot file that report.
49
+
50
+ ## Starting agents
51
+
52
+ Give the Studio a directory and a task and it runs a real `nah` process with one
53
+ prompt, captures its output line by line, and watches it like any other agent —
54
+ which is the point, because the agent reports itself and pushes its own traces
55
+ rather than being driven through a private channel. One prompt per launch, so a
56
+ launch is a task with an end and the status column stays honest.
57
+
58
+ `--nah-bin` matters more than it looks. A global `nah` from npm and a `nah` built
59
+ from a checkout produce different traces, so the Studio launches the build that
60
+ started it — `/studio` records it in the endpoint file — rather than whatever
61
+ happens to be first on PATH.
62
+
63
+ ## The built-in agent
64
+
65
+ The chat tab and evaluations run an agent assembled by `nah` itself, published as
66
+ the `nah/agent` subpath: the same system prompt, the same tools, the same model
67
+ resolution and the same memory as the agent in your terminal, with one difference —
68
+ every mutating tool is refused.
69
+
70
+ That is deliberate. A dashboard that assembled its own copy of the agent would be
71
+ debugging a different program from the one you use, and its traces would be
72
+ evidence about the wrong thing.
73
+
74
+ Each request gets a fresh state: an HTTP request has no transcript to inherit, and
75
+ a turn carrying the previous one's history could answer a question about a file it
76
+ never read.
77
+
78
+ ## Views
79
+
80
+ | View | What it answers |
81
+ | --- | --- |
82
+ | **Agents** | Who is running, what each has cost, its output; start one from here |
83
+ | **Overview** | Volume, error rate, spend, median latency, runs over time |
84
+ | **Traces** | Every run, filterable; a span waterfall and inspector behind each |
85
+ | **Tools** | Per-tool call counts, error rates, p50 and p95 latency |
86
+ | **Evaluations** | Datasets, scorers, experiments with live progress and score spread |
87
+ | **Chat** | Talk to the read-only agent; the run is traced like any other |
88
+
89
+ ⌘1–⌘6 moves between them. The agent selector in the header scopes every view, not
90
+ just the list — a summary of everything shown next to a filter that says otherwise
91
+ is how a dashboard starts lying.
92
+
93
+ Updates arrive over `GET /api/stream`. The interval polling still in the code is a
94
+ floor for a stream a proxy has blocked, not the mechanism.
95
+
96
+ ## Security
97
+
98
+ - Loopback by default. `0.0.0.0` requires `NAH_STUDIO_TOKEN`, and without one the
99
+ server refuses anything that is not from loopback — the store holds prompts, file
100
+ paths and tool output.
101
+ - The token is written to `~/.nah/studio.json` at mode 0600, and an agent that gets
102
+ a 401 gets a warning naming the problem rather than silence.
103
+ - Credential-shaped values are redacted before anything is written, and every span
104
+ is size-limited: a trace is a debugging aid, and an unbounded one is a liability.
105
+ - An agent can be stopped only by the machine it runs on, and only if this Studio
106
+ started it.
107
+
108
+ ## Development
109
+
110
+ ```sh
111
+ pnpm --filter nah-studio build # UI into dist/ui, then the server into dist/
112
+ pnpm --filter nah-studio test
113
+ pnpm --filter nah-studio dev # the UI with HMR on :4112, proxying /api
114
+
115
+ # develop the UI against a Studio that is already running
116
+ pnpm --filter nah-studio dev
117
+ ```
118
+
119
+ `dist/` holds both halves of the product: `cli.js` and the `dist/ui` files the
120
+ server reads relative to itself. One published package, no copy step between two.