makersclaw 0.3.2 → 0.4.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.
- package/README.md +3 -1
- package/package.json +1 -1
- package/r/annotate.json +3 -3
- package/r/approval-request.json +2 -2
- package/r/audio-player.json +2 -2
- package/r/auth-form.json +2 -2
- package/r/board.json +2 -2
- package/r/calendar-view.json +3 -3
- package/r/cart.json +2 -2
- package/r/chart.json +2 -2
- package/r/chat.json +2 -2
- package/r/code-editor.json +2 -2
- package/r/comment-box.json +3 -3
- package/r/contact-section.json +2 -2
- package/r/core.json +12 -6
- package/r/csv-import.json +3 -3
- package/r/data-table.json +2 -2
- package/r/diagram.json +2 -2
- package/r/doc-editor.json +2 -2
- package/r/doc-page.json +3 -3
- package/r/email-render.json +2 -2
- package/r/faq.json +2 -2
- package/r/file-upload.json +2 -2
- package/r/flow-canvas.json +2 -2
- package/r/footer.json +2 -2
- package/r/gantt.json +3 -3
- package/r/job-panel.json +8 -5
- package/r/json-editor.json +3 -3
- package/r/map.json +2 -2
- package/r/menubar.json +2 -2
- package/r/mind-map.json +3 -3
- package/r/navigation-menu.json +2 -2
- package/r/order-detail.json +2 -2
- package/r/org-chart.json +3 -3
- package/r/page-builder.json +2 -2
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +2 -2
- package/r/product-detail.json +2 -2
- package/r/product-grid.json +3 -3
- package/r/record-form.json +2 -2
- package/r/record-notes.json +4 -4
- package/r/registry.json +131 -123
- package/r/search-dialog.json +2 -2
- package/r/settings-list.json +2 -2
- package/r/setup-checklist.json +2 -2
- package/r/share-dialog.json +2 -2
- package/r/sidebar.json +2 -2
- package/r/signature-pad.json +2 -2
- package/r/sketch-canvas.json +2 -2
- package/r/spreadsheet.json +2 -2
- package/r/stat-cards.json +3 -3
- package/r/task-list.json +3 -3
- package/r/task-model.json +2 -2
- package/r/testimonials.json +2 -2
- package/r/transaction-list.json +2 -2
- package/r/whiteboard.json +3 -3
- package/registry/blocks/job-panel/README.md +40 -3
- package/registry/blocks/job-panel/block.json +2 -2
- package/registry/blocks/job-panel/demo.jsx +75 -6
- package/registry/blocks/job-panel/job-panel.jsx +60 -11
- package/src/shadcn.mjs +1 -1
- package/templates/next/files/README.md +339 -73
- package/templates/next/files/app/auto-refresh.jsx +72 -10
- package/templates/next/files/app/claw-alive/route.js +17 -0
- package/templates/next/files/app/error-relay.jsx +9 -4
- package/templates/next/files/app/escape-relay.jsx +27 -0
- package/templates/next/files/app/frame.js +218 -0
- package/templates/next/files/app/layout.jsx +18 -3
- package/templates/next/files/check/run.mjs +25 -8
- package/templates/next/files/components/parts/fixture.jsx +29 -4
- package/templates/next/files/components/parts/index.js +2 -1
- package/templates/next/files/components/parts/live-work.jsx +235 -0
- package/templates/next/files/components/ui/button.jsx +6 -1
- package/templates/next/files/components/ui/date-picker.jsx +15 -2
- package/templates/next/files/components/ui/icon.jsx +37 -2
- package/templates/next/files/lib/claw.js +127 -28
- package/templates/next/files/lib/hooks.js +454 -33
- package/templates/next/files/lib/platform.js +113 -15
- package/templates/next/files/surfaces/README.md +3 -0
- package/templates/next/template.json +17 -6
|
@@ -1,29 +1,126 @@
|
|
|
1
|
-
import { claw, clawStream, reportError } from "./claw";
|
|
1
|
+
import { claw, clawBasePath, clawStream, openInDesk, publishDesk, reportError } from "./claw";
|
|
2
2
|
|
|
3
3
|
// Typed wrappers over the _claw API (lib/claw.js), one per route an app
|
|
4
4
|
// has a reason to call. BROWSER only — the grant cookie is the identity —
|
|
5
5
|
// so call these from "use client" files; lib/hooks.js wraps them.
|
|
6
6
|
//
|
|
7
7
|
// Every call resolves { ok, status, data } or { ok: false, status, error,
|
|
8
|
-
// unavailable }; nothing throws. `unavailable: true` (404 or no
|
|
9
|
-
// means the gateway has no such route yet — render a quiet "not
|
|
10
|
-
// yet" state, not an error.
|
|
8
|
+
// unavailable, code? }; nothing throws. `unavailable: true` (404 or no
|
|
9
|
+
// network) means the gateway has no such route yet — render a quiet "not
|
|
10
|
+
// connected yet" state, not an error. `code` names a refusal a caller
|
|
11
|
+
// can act on (`not_your_thread`, `needs_answer`, `queue_full`).
|
|
11
12
|
//
|
|
12
|
-
//
|
|
13
|
-
// (`reportError`), and
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
13
|
+
// What lives here: who the app is (`me`), the error relay
|
|
14
|
+
// (`reportError`), and ASKING — a screen asks its agent for work with a
|
|
15
|
+
// row as context (`ask`), and the conversation lives in the desk's agent
|
|
16
|
+
// column, which the ask opens. `requests` reads this app's asks in
|
|
17
|
+
// flight, so an empty surface can show the work coming instead of a
|
|
18
|
+
// blank; `stopRequest` stops one; `openRequest` opens one in the column
|
|
19
|
+
// again. That is not monitoring: the OS still draws Agent, Runs and
|
|
20
|
+
// Activity as tabs on the window, and nothing here lists chats, runs or
|
|
21
|
+
// activity. `startJob` / `cancelJob` are the 0.3.x door to the same work,
|
|
22
|
+
// streamed into the app; they stay for a claw that has no _claw/ask yet.
|
|
23
|
+
// `claw(path, opts)` and `clawStream` in lib/claw.js are the generic
|
|
24
|
+
// doors for the rest of §5.
|
|
19
25
|
|
|
20
26
|
/** GET _claw/me → { artifact: { id, name, vehicle, status, home },
|
|
21
|
-
* user: { id, email }, blueprint } */
|
|
27
|
+
* user: { id, email }, blueprint, desk_origin } */
|
|
22
28
|
export function me() {
|
|
23
29
|
return claw("me");
|
|
24
30
|
}
|
|
25
31
|
|
|
32
|
+
/** The surface the page is on: the <key> of /s/<key>. Searched anywhere
|
|
33
|
+
* in the path, not only at its start, because in path mode the app is
|
|
34
|
+
* served under /p/<label>/ and the browser's path carries that prefix.
|
|
35
|
+
* The base path is cut first when it is there, so a label that happens
|
|
36
|
+
* to read "s" cannot pass for the surface. */
|
|
37
|
+
export function surfaceOfPath(pathname) {
|
|
38
|
+
let path = String(pathname ?? "");
|
|
39
|
+
const base = clawBasePath();
|
|
40
|
+
if (base && path.startsWith(`${base}/`)) path = path.slice(base.length);
|
|
41
|
+
const match = /\/s\/([^/?#]+)/.exec(path);
|
|
42
|
+
if (!match) return undefined;
|
|
43
|
+
try {
|
|
44
|
+
return decodeURIComponent(match[1]);
|
|
45
|
+
} catch {
|
|
46
|
+
return match[1];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function currentSurface() {
|
|
51
|
+
return typeof location === "undefined" ? undefined : surfaceOfPath(location.pathname);
|
|
52
|
+
}
|
|
53
|
+
|
|
26
54
|
/**
|
|
55
|
+
* Ask the app's agent for work: POST _claw/ask. The platform makes it a
|
|
56
|
+
* request, hands it to the app's agent, and the conversation lives in the
|
|
57
|
+
* desk's agent column — which this opens, unless `open` is false.
|
|
58
|
+
*
|
|
59
|
+
* text what to do, in the founder's words (required)
|
|
60
|
+
* row the row it is about, as context for the agent
|
|
61
|
+
* how instructions for the agent only (the AGENTS.md section)
|
|
62
|
+
* job a declared job's key, or true: let the platform pick the
|
|
63
|
+
* job whose view is this surface, else the app's only job
|
|
64
|
+
* list the list it belongs to, for an app that declares lists
|
|
65
|
+
* surface defaults to the <key> of /s/<key> in the page's path
|
|
66
|
+
* sessionId continue this thread instead of starting one
|
|
67
|
+
*
|
|
68
|
+
* → { ok: true, status, data: { ok, request, desk_origin } }, or a
|
|
69
|
+
* refusal with its `code`: `not_your_thread` (403, a teammate's thread:
|
|
70
|
+
* start your own), `needs_answer` (409, the thread waits on an answer in
|
|
71
|
+
* the column), `queue_full` (409).
|
|
72
|
+
*/
|
|
73
|
+
export async function ask({ text, row, how, job, list, surface, sessionId, open = true, signal } = {}) {
|
|
74
|
+
const words = String(text ?? "").trim();
|
|
75
|
+
if (!words) return { ok: false, status: 0, error: "nothing to ask", unavailable: false };
|
|
76
|
+
const r = await claw("ask", {
|
|
77
|
+
method: "POST",
|
|
78
|
+
body: {
|
|
79
|
+
text: words,
|
|
80
|
+
row: row ?? undefined,
|
|
81
|
+
how: how || undefined,
|
|
82
|
+
// true or a key; anything else is no job, and the key is left out.
|
|
83
|
+
job: job === true || (typeof job === "string" && job) ? job : undefined,
|
|
84
|
+
list: list ?? undefined,
|
|
85
|
+
surface: surface ?? currentSurface(),
|
|
86
|
+
session_id: sessionId || undefined,
|
|
87
|
+
},
|
|
88
|
+
signal,
|
|
89
|
+
});
|
|
90
|
+
if (r.ok) {
|
|
91
|
+
publishDesk(r.data?.desk_origin);
|
|
92
|
+
const request = r.data?.request;
|
|
93
|
+
if (open && request?.id) openInDesk({ requestId: request.id, sessionId: request.app_session_id });
|
|
94
|
+
}
|
|
95
|
+
return r;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** GET _claw/requests → { requests, run, desk_origin }: this app's asks
|
|
99
|
+
* in flight (and those that ended in the last day), every member's, with
|
|
100
|
+
* session ids only on the viewer's own, plus its running scheduled run.
|
|
101
|
+
* With { id }: GET _claw/requests?id=<id> → { request }. */
|
|
102
|
+
export function requests({ id, signal } = {}) {
|
|
103
|
+
return claw(id ? `requests?id=${encodeURIComponent(id)}` : "requests", { signal });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** POST _claw/requests/<id>/stop → { ok, request }. The asker may stop
|
|
107
|
+
* their own; an admin or the app's owner may stop anyone's. */
|
|
108
|
+
export function stopRequest(id) {
|
|
109
|
+
return claw(`requests/${encodeURIComponent(id)}/stop`, { method: "POST", body: {} });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Open a request's conversation in the desk's agent column again. Takes
|
|
113
|
+
* the request (its thread opens with it when it is yours) or its id.
|
|
114
|
+
* → true when the desk was asked. */
|
|
115
|
+
export function openRequest(requestOrId) {
|
|
116
|
+
const request = requestOrId && typeof requestOrId === "object" ? requestOrId : { id: requestOrId };
|
|
117
|
+
return openInDesk({ requestId: request.id, sessionId: request.app_session_id ?? null });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Legacy: the 0.3.x job door. useJob falls back to it on a claw that has
|
|
122
|
+
* no _claw/ask; new code calls ask().
|
|
123
|
+
*
|
|
27
124
|
* Commission work: POST _claw/chat as a stream, and call `onEvent` for
|
|
28
125
|
* every frame — `session` (once, first, carrying the thread's id),
|
|
29
126
|
* `delta` ({ text } as the answer is written), `tool` ({ name, label,
|
|
@@ -46,14 +143,15 @@ export function startJob(message, { sessionId, onEvent, signal } = {}) {
|
|
|
46
143
|
);
|
|
47
144
|
}
|
|
48
145
|
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
146
|
+
/** Legacy: the 0.3.x job door (stopRequest is the new one). POST
|
|
147
|
+
* _claw/cancel — stop a job's turn. The rows it already wrote stay; so
|
|
148
|
+
* does its run in the Runs tab. */
|
|
51
149
|
export function cancelJob(sessionId) {
|
|
52
150
|
return claw("cancel", { method: "POST", body: { session_id: sessionId } });
|
|
53
151
|
}
|
|
54
152
|
|
|
55
153
|
export { reportError };
|
|
56
154
|
|
|
57
|
-
export const platform = { me, startJob, cancelJob, reportError };
|
|
155
|
+
export const platform = { me, ask, requests, stopRequest, openRequest, surfaceOfPath, startJob, cancelJob, reportError };
|
|
58
156
|
|
|
59
157
|
export default platform;
|
|
@@ -25,6 +25,9 @@ that follows it — `useJob()` in `../lib/hooks.js`, §5 of `../README.md`.
|
|
|
25
25
|
The panel is not a surface and takes no key: it opens because the founder
|
|
26
26
|
pressed something and closes when the work lands.
|
|
27
27
|
|
|
28
|
+
An empty table shows `LiveEmpty` — the live work coming, never an
|
|
29
|
+
example (`../README.md` §3a).
|
|
30
|
+
|
|
28
31
|
Register each in `../surfaces.js` (import + entry with `component`).
|
|
29
32
|
Until the entry has a `component` the surface is planned: marked in the
|
|
30
33
|
nav, "Makersclaw is building this" on its page.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next",
|
|
3
3
|
"title": "Makersclaw app (Next.js 15)",
|
|
4
|
-
"description": "The behaviour every app shares, the parts every app is assembled from, and none of the app's own look — the colours are the workspace's. It carries the data layer (lib/data.js, lib/db.js), the write actions that log activity (lib/actions.js), the _claw platform client with its identity wrapper and hooks (lib/claw.js, lib/platform.js, lib/hooks.js), routing (/s/<key>), the middleware, error boundaries, Tailwind v4 mapped to the workspace theme (app/globals.css + _claw/theme.css), the kit (components/ui), the parts bound to the data layer (components/parts) and `npm run check`. The app designs the inside of the App tab on top: app/shell.jsx and every domain surface, assembled from the kit and the blocks with tokens only.",
|
|
4
|
+
"description": "The behaviour every app shares, the parts every app is assembled from, and none of the app's own look — the colours are the workspace's. It carries the data layer (lib/data.js, lib/db.js), the write actions that log activity (lib/actions.js), the _claw platform client with its identity wrapper, the ask bridge (a screen's ask becomes a request, answered in the desk's agent column) and the hooks that follow requests (lib/claw.js, lib/platform.js, lib/hooks.js), routing (/s/<key>), the middleware, error boundaries, Tailwind v4 mapped to the workspace theme (app/globals.css + _claw/theme.css), the kit (components/ui), the parts bound to the data layer and to the live requests (components/parts) and `npm run check`. The app designs the inside of the App tab on top: app/shell.jsx and every domain surface, assembled from the kit and the blocks with tokens only.",
|
|
5
5
|
"files": {
|
|
6
6
|
"fixed": [
|
|
7
7
|
"app/globals.css",
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"app/not-found.jsx",
|
|
13
13
|
"app/error-relay.jsx",
|
|
14
14
|
"app/auto-refresh.jsx",
|
|
15
|
+
"app/escape-relay.jsx",
|
|
16
|
+
"app/frame.js",
|
|
17
|
+
"app/claw-alive/route.js",
|
|
15
18
|
"app/s/[key]/page.jsx",
|
|
16
19
|
"lib/*.js",
|
|
17
20
|
"components/ui/*",
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
"name": "button",
|
|
31
34
|
"type": "component",
|
|
32
35
|
"title": "Button, IconButton",
|
|
33
|
-
"description": "The one button: variant primary (one
|
|
36
|
+
"description": "The one button: variant primary (the surface's one main action, in the app's accent; ask for it — a Button with no variant is secondary) · secondary (the default) · quiet · danger · link (inline text: no padding, no min-height, wraps and truncates with its sentence; size inherit takes the sentence's text; tone primary · muted for a secondary link) · nav (a full-width, start-aligned, normal-weight navigation row, filled when aria-current); size md (44px) · sm; align center · start; icon; href for a link; loading (a spinner, same width, aria-busy, disabled). IconButton for an icon alone, label required.",
|
|
34
37
|
"tags": ["button", "action", "link", "icon button"],
|
|
35
38
|
"files": ["components/ui/button.jsx"]
|
|
36
39
|
},
|
|
@@ -102,7 +105,7 @@
|
|
|
102
105
|
"name": "date-picker",
|
|
103
106
|
"type": "component",
|
|
104
107
|
"title": "DatePicker, DateInput, DATE_PRESETS",
|
|
105
|
-
"description": "DatePicker: a field that reads like an input and opens a Calendar in a Popover — mode single · range (formatRange in the field), presets beside the calendar (true for Today, Last 7 days, This month… or your own), clearable, disabled, min/max, a hidden input for forms; goes in <Field>. DateInput: the browser's own typed date field with the Calendar one button away.",
|
|
108
|
+
"description": "DatePicker: a field that reads like an input and opens a Calendar in a Popover — mode single · range (formatRange in the field), presets beside the calendar (true for Today, Last 7 days, This month… or your own), clearable, disabled, min/max, a hidden input for forms; goes in <Field>. DateInput: the browser's own typed date field with the Calendar one button away; clearable adds an × once it holds a date.",
|
|
106
109
|
"tags": ["date picker", "date", "range", "due date", "presets", "date input", "report period"],
|
|
107
110
|
"files": ["components/ui/date-picker.jsx"]
|
|
108
111
|
},
|
|
@@ -142,7 +145,7 @@
|
|
|
142
145
|
"name": "icon",
|
|
143
146
|
"type": "component",
|
|
144
147
|
"title": "Icon",
|
|
145
|
-
"description": "One inline sprite of stroke glyphs; ICON_NAMES lists them.
|
|
148
|
+
"description": "One inline sprite of stroke glyphs; ICON_NAMES lists them. size is pixels or xs 12 · sm 14 · md 16 (the default) · lg 20 · xl 24. The sprite is fixed: a glyph it lacks is added in the template, never drawn as an <svg> in a surface.",
|
|
146
149
|
"tags": ["icon", "glyph", "svg"],
|
|
147
150
|
"files": ["components/ui/icon.jsx"]
|
|
148
151
|
},
|
|
@@ -357,8 +360,8 @@
|
|
|
357
360
|
{
|
|
358
361
|
"name": "fixture",
|
|
359
362
|
"type": "part",
|
|
360
|
-
"title": "useFixture, isSample, FixtureNotice",
|
|
361
|
-
"description": "The worked example shown while a table is empty — rows in code, never INSERTed; clearing writes nothing; a sample row carries _sample.",
|
|
363
|
+
"title": "useFixture, isSample, FixtureNotice, Examples, useExamples",
|
|
364
|
+
"description": "The worked example shown while a table is empty — examples shown only outside a Makersclaw workspace (the Examples provider, off in a workspace: there an empty table shows its live requests, LiveEmpty); rows in code, never INSERTed; clearing writes nothing; a sample row carries _sample.",
|
|
362
365
|
"tags": ["example", "sample", "fixture", "empty state", "onboarding"],
|
|
363
366
|
"files": ["components/parts/fixture.jsx"]
|
|
364
367
|
},
|
|
@@ -369,6 +372,14 @@
|
|
|
369
372
|
"description": "Pick a saved record or make a new one; with nothing saved it shows only New.",
|
|
370
373
|
"tags": ["switcher", "picker", "saved", "records", "select"],
|
|
371
374
|
"files": ["components/parts/record-switcher.jsx"]
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"name": "live-work",
|
|
378
|
+
"type": "part",
|
|
379
|
+
"title": "LiveEmpty, LiveWork, liveWords",
|
|
380
|
+
"description": "The empty state that shows the live job, never example rows. LiveEmpty takes useRequests() and shows the request in flight on this surface or job — its line, whose request it is, Queued · after …, Answer when it needs you, Stop for the asker — with \"Rows appear here as they land\", or the app's scheduled run while it goes; with nothing in flight, the empty block (icon, title, line, one action). LiveWork is that one row; liveWords the status word (Working, Needs you, Answered, Done, Stopped, Didn't finish).",
|
|
381
|
+
"tags": ["empty state", "live", "request", "working", "needs you", "queued"],
|
|
382
|
+
"files": ["components/parts/live-work.jsx"]
|
|
372
383
|
}
|
|
373
384
|
]
|
|
374
385
|
}
|