@surph_ai/cli 0.0.38 → 0.0.39
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/package.json
CHANGED
package/scaffold/board/AGENTS.md
CHANGED
|
@@ -25,7 +25,7 @@ Previewing and publishing the board need **Node.js 20 or later**. The pages them
|
|
|
25
25
|
|
|
26
26
|
Keep them in step on a board that hasn't been published yet. The person won't think about the slug, so you do:
|
|
27
27
|
|
|
28
|
-
1. **Whenever you set or change the board's name on an unpublished board, set `slug` from it in the same edit:** lowercase, spaces and punctuation turned into single dashes (BreakLedger → `breakledger`, "DC Tech Events" → `dc-tech-events`). Tell the person the slug you chose, in a word: it's the board's address (`https://<slug>.surph-boards.com`).
|
|
28
|
+
1. **Whenever you set or change the board's name on an unpublished board, set `slug` from it in the same edit:** lowercase, spaces and punctuation turned into single dashes (BreakLedger → `breakledger`, "DC Tech Events" → `dc-tech-events`). Tell the person the slug you chose, in a word: it's the board's address (`https://<slug>.surph-boards.com`). (Pages don't repeat the slug: Surph finds the board from where they're served. Only a page served from a site outside Surph names it, with `data-board="<slug>"` on its SDK tag; change it there too.)
|
|
29
29
|
2. **A new board's slug starts from its folder name** (`surph board break-ledger` → `break-ledger`). Older boards may still have the placeholder `my-board`: replace it as soon as the board has a name. `npm run deploy` refuses to publish with `my-board`.
|
|
30
30
|
3. **Check the slug is free before you settle on it:** `curl -s -o /dev/null -w "%{http_code}" https://surph.s3.us-east-1.amazonaws.com/boards/<slug>/board.json`. `200` means a board with that slug already exists. If this folder never published it, it's someone else's: pick another (add a short suffix, e.g. `breakledger-dk`) and say so. Anything else (403 or 404) means it's free.
|
|
31
31
|
4. **Is this board published?** Treat it as published if the person says so, or if you ran `npm run deploy` for it. If unsure, ask.
|
|
@@ -34,7 +34,7 @@ Keep them in step on a board that hasn't been published yet. The person won't th
|
|
|
34
34
|
## The working loop
|
|
35
35
|
|
|
36
36
|
1. **Preview:** run `npm run dev` from this folder and leave it running. It serves the board at `http://localhost:4180`: the pages in `site/` as its base (`/` is `site/index.html`), plus `/board.json` (nothing to install; it uses the Surph CLI through `npx`).
|
|
37
|
-
2. **See it in Surph:** ask the person to open Surph, go to **Settings → Developer**, turn on **Run Surph as a local board**, and keep the address `http://localhost:4180`. Surph reloads as this board. Or, simpler: with `npm run dev` running, the person says "open http://localhost:4180" in Surph's chat, and the board joins the chat (its pages
|
|
37
|
+
2. **See it in Surph:** ask the person to open Surph, go to **Settings → Developer**, turn on **Run Surph as a local board**, and keep the address `http://localhost:4180`. Surph reloads as this board. Or, simpler: with `npm run dev` running, the person says "open http://localhost:4180" in Surph's chat, and the board joins the chat (its pages load the board SDK; see the README).
|
|
38
38
|
3. **Configure the board** (name, contexts, tools, instructions): the person can click the **DEV** label in Surph's canvas header to open the Local board panel, which saves `board.json` for you. You can also edit `board.json` directly; the README describes every field.
|
|
39
39
|
4. **Change pages:** the pages and their assets live in `site/` (`site/index.html`, `site/assets/…`). Edit them there and keep `board.json`'s `config.pages` in step (every page listed, `shows` written as plain facts, `ops` matching the page's `host.rpc` calls). The person reloads Surph to see the change.
|
|
40
40
|
5. **Publish:** `npm run deploy`. **Only when the person asks you to in this conversation.** It replaces the live board for everyone who uses it. Check the board in dev mode first, and check `slug` first (see above): not `my-board`, and either free or this board's own. Once deployed, the site is live at `https://<slug>.surph-boards.com/`.
|
package/scaffold/board/README.md
CHANGED
|
@@ -96,7 +96,7 @@ Surph only shows pages that are registered with the board. The board itself is d
|
|
|
96
96
|
| `tools` | Slugs of Surph tools the board's chat can use. Optional. |
|
|
97
97
|
| `config.instructions` | Instructions from the board's owner for the board's chat: tone, behavior, what it helps with. On a board they take the place of each context's own instructions. |
|
|
98
98
|
| `config.pages` | The board's pages, one registry entry each (below). |
|
|
99
|
-
| `origins` | Optional. Other sites allowed to speak for this board, as origins (`["https://breakledger.com"]`), for pages hosted outside Surph
|
|
99
|
+
| `origins` | Optional. Other sites allowed to speak for this board, as origins (`["https://breakledger.com"]`), for pages hosted outside Surph (their SDK tag names the board: `data-board="<slug>"`). The board's own `https://<slug>.surph-boards.com` is always allowed. List only sites you control: a listed site can speak as the board. |
|
|
100
100
|
| `config.icon` | Optional. The board's icon: a file in `site/`, by its path there (`apple-touch-icon.png`, `assets/img/icon.png`). Surph shows it beside the board's name: on each of the chat's replies ("@BreakLedger") and in the header. A small square image works best. |
|
|
101
101
|
|
|
102
102
|
A registry entry:
|
|
@@ -122,13 +122,13 @@ A registry entry:
|
|
|
122
122
|
|
|
123
123
|
## The SDK
|
|
124
124
|
|
|
125
|
-
Every page loads the SDK from this exact URL
|
|
125
|
+
Every page loads the SDK from this exact URL. Don't copy, bundle, edit or replace it.
|
|
126
126
|
|
|
127
127
|
```html
|
|
128
|
-
<script
|
|
128
|
+
<script src="https://surph.s3.us-east-1.amazonaws.com/admin/desktop/js/board-sdk/v1/surph-board.js"></script>
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
Loading it is all a page needs: the SDK connects to Surph and announces the page as this board's page as it loads, with nothing to call. Surph finds the board from where the page is served: locally, from the `board.json` beside it (so renaming the board needs no change to the pages); live, from its address, `https://<slug>.surph-boards.com`. A page served from any other site names its board on the tag, `<script data-board="<slug>" src="…">`, and that site goes in `board.json`'s `origins`. Add `data-page="events"` to name the page (optional). The SDK defines one global, `SurphBoard`, for the page's own scripts:
|
|
132
132
|
|
|
133
133
|
```js
|
|
134
134
|
const host = SurphBoard.host; // The page's connection to Surph
|
|
@@ -137,14 +137,14 @@ host.rpc(op, args, { timeout }); // Ask Surph for something; returns a Promis
|
|
|
137
137
|
host.hosted; // true inside the Surph canvas, false when opened directly
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
There's one connection per page: `SurphBoard.connect({ onRefresh })` returns `SurphBoard.host`, and `SurphBoard.connect({ board: '<slug>' })` names the board the way `data-board` does.
|
|
141
141
|
|
|
142
142
|
- `rpc(op, args, extra)` sends `args` as an object (use `{}` when there are none). It resolves with the operation's result object.
|
|
143
143
|
- It rejects with:
|
|
144
144
|
- `Error('host timeout')`: no reply in time. The default wait is 15 seconds; pass `{ timeout: 800 }` on reads.
|
|
145
145
|
- `Error('not in a Surph host')`: the page isn't inside the canvas (`hosted` is false).
|
|
146
146
|
- `Error('<message>')`: Surph answered with an error, for example `Unknown op: …` for an operation it doesn't support.
|
|
147
|
-
-
|
|
147
|
+
- Surph checks the page's site against the board's: the board's own `https://<slug>.surph-boards.com`, plus any listed in `board.json`'s `origins` (and, while you develop, a board server on your own machine). A page that doesn't pass is shown as an ordinary web page.
|
|
148
148
|
- When the chat reads the page, the SDK answers with the page's visible text on its own; nothing to add.
|
|
149
149
|
- Pages written before the board SDK load `surph-wave.js` and call `SurphWave.connect({ pageSlug, board, onRefresh })`. They still work; use the board SDK's tag for new pages and when you touch an old one.
|
|
150
150
|
|
|
@@ -156,7 +156,7 @@ Every page that reads data uses this loop. Keep its rules:
|
|
|
156
156
|
- paint only after a successful reply.
|
|
157
157
|
|
|
158
158
|
```js
|
|
159
|
-
// The page loads <script
|
|
159
|
+
// The page loads <script src="…/surph-board.js"></script> first.
|
|
160
160
|
const host = SurphBoard.host;
|
|
161
161
|
SurphBoard.onRefresh(paint);
|
|
162
162
|
|
|
@@ -423,7 +423,7 @@ A field marked "omitted" is missing from the object, not `null`. Every URL is `h
|
|
|
423
423
|
2. Keep it running while you work; the terminal shows a line each time Surph saves `board.json`.
|
|
424
424
|
3. Open `http://localhost:4180/` (your `site/index.html`) to check a page loads without console errors. It shows its empty layout there (`hosted` is false); real data only appears inside the Surph canvas.
|
|
425
425
|
4. **Run Surph as your board with dev mode.** Keep `npm run dev` running. In Surph, open **Settings → Developer**, turn on **Run Surph as a local board**, and keep the address `http://localhost:4180`. Surph reloads as the board `board.json` describes: its name and icon in the header, its contexts and instructions in the chat, and its pages in the canvas (it opens on your start page, the Pages menu lists your pages, and the chat's model sees their `shows` lines). The status under the address says what loaded, or why it couldn't read `board.json`; until it loads, Surph runs as usual. A **DEV** label in the canvas header shows your board is loaded. While it's on, anything the chat saves goes to your own space in Surph, not to a board's shared space.
|
|
426
|
-
- **Or chat with the board without dev mode:** with `npm run dev` running, say "open http://localhost:4180" in Surph's chat. When the page loads the
|
|
426
|
+
- **Or chat with the board without dev mode:** with `npm run dev` running, say "open http://localhost:4180" in Surph's chat. When the page loads the board SDK, the board joins the chat from the `board.json` at that address (it's your own machine, so no live board is needed): the canvas header shows it, its description opens its part of the conversation, and its replies are signed with its name. Live, the same happens for pages on `https://<slug>.surph-boards.com` or a site in `origins`.
|
|
427
427
|
5. **Configure the board from Surph.** Click the **DEV** label to open the **Local board** panel: set the board's name, slug, description and icon (an image in `site/`), pick its contexts (yours, or public ones by search) and which one the chat starts with, pick its tools, and write its instructions. The panel also lists the pages and flags a missing `shows` line or an operation the host doesn't answer. **Save and reload** writes `board.json` through the dev server and reloads Surph as the updated board. Pages and any other fields are kept as they are in the file; edit pages in `board.json` itself.
|
|
428
428
|
6. Dev mode affects only your browser. Turn it off in the same place to get Surph's own pages back.
|
|
429
429
|
7. In Surph, keep your browser's DevTools open with **Network → Disable cache** checked, or the canvas may keep showing an older copy of a page after you change it. After editing `board.json` by hand, reload Surph so it reads the file again.
|
|
@@ -454,7 +454,7 @@ Each step prints what it did; a failure prints why and stops. After a deploy, th
|
|
|
454
454
|
- [ ] Reads use the call pattern: a timeout retries, other errors stop, nothing is cleared before a reply.
|
|
455
455
|
- [ ] Data from Surph is written with `textContent`; links and images use only `http(s)` values.
|
|
456
456
|
- [ ] Operations that act for the person run only from their click (a start page's `page.open` aside).
|
|
457
|
-
- [ ] The SDK `<script>` tag is the v1 URL above, unchanged
|
|
457
|
+
- [ ] The SDK `<script>` tag is the v1 URL above, unchanged (with `data-board="<slug>"` only on pages served from a site outside Surph).
|
|
458
458
|
- [ ] Every page (in `site/`) links `assets/css/site.css?v=<n>`; if `site.css` changed, `<n>` is bumped in every page.
|
|
459
459
|
- [ ] `board.json`'s `config.pages` lists every page: `name`, `file` (or `url`), `shows` written as facts, `ops` matching the file's `rpc` calls, and one `start` page.
|
|
460
460
|
- [ ] Opened at `http://localhost:4180/<page>`, every page loads without console errors.
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
<li><strong>See them in Surph:</strong> open <strong>Settings → Developer</strong> and turn on dev mode for <code>http://localhost:4180</code>. The canvas then shows the board's pages, with real data.</li>
|
|
96
96
|
</ol>
|
|
97
97
|
|
|
98
|
-
<!--
|
|
99
|
-
<script
|
|
98
|
+
<!-- The board SDK: it connects to Surph and announces this board as it loads. -->
|
|
99
|
+
<script src="https://surph.s3.us-east-1.amazonaws.com/admin/desktop/js/board-sdk/v1/surph-board.js"></script>
|
|
100
100
|
<script>
|
|
101
101
|
const host = SurphBoard.host;
|
|
102
102
|
SurphBoard.onRefresh(paint);
|
package/scaffold/index.js
CHANGED
|
@@ -285,9 +285,7 @@ const scaffoldBoard = async (name) => {
|
|
|
285
285
|
// The board's pages and assets go in site/ (boards/<slug>/site/ when live).
|
|
286
286
|
shell.mkdir('-p', 'site/assets/css')
|
|
287
287
|
shell.mkdir('-p', 'site/assets/js')
|
|
288
|
-
|
|
289
|
-
const indexHtml = utils.readFile(path.join(__dirname, 'board/site/index.html'))
|
|
290
|
-
utils.write('site/index.html', indexHtml.replace('data-board="my-board"', `data-board="${boardJson.slug}"`))
|
|
288
|
+
shell.cp('-R', path.join(__dirname, `board/site/index.html`), 'site/index.html')
|
|
291
289
|
shell.cp('-R', path.join(__dirname, `board/site/assets/css/site.css`), 'site/assets/css/site.css')
|
|
292
290
|
|
|
293
291
|
await progress.done()
|