makersclaw 0.6.0 → 0.7.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 +48 -8
- package/package.json +1 -1
- package/r/annotate.json +4 -4
- package/r/approval-request.json +3 -3
- package/r/audio-player.json +3 -3
- package/r/auth-form.json +2 -2
- package/r/board.json +4 -4
- package/r/calendar-view.json +4 -4
- package/r/cart.json +3 -3
- package/r/chart.json +3 -3
- package/r/chat.json +3 -3
- package/r/code-editor.json +4 -4
- package/r/comment-box.json +4 -4
- package/r/contact-section.json +3 -3
- package/r/core.json +3 -3
- package/r/csv-import.json +4 -4
- package/r/data-table.json +3 -3
- package/r/diagram.json +3 -3
- package/r/doc-editor.json +4 -4
- package/r/doc-page.json +4 -4
- package/r/email-render.json +2 -2
- package/r/faq.json +2 -2
- package/r/file-upload.json +3 -3
- package/r/flow-canvas.json +4 -4
- package/r/footer.json +3 -3
- package/r/gantt.json +4 -4
- package/r/job-panel.json +3 -3
- package/r/json-editor.json +4 -4
- package/r/map.json +5 -5
- package/r/menubar.json +2 -2
- package/r/mind-map.json +4 -4
- package/r/navigation-menu.json +2 -2
- package/r/order-detail.json +2 -2
- package/r/org-chart.json +4 -4
- package/r/page-builder.json +6 -6
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +6 -6
- package/r/product-detail.json +3 -3
- package/r/product-grid.json +4 -4
- package/r/record-form.json +3 -3
- package/r/record-notes.json +5 -5
- package/r/registry.json +121 -121
- package/r/search-dialog.json +3 -3
- package/r/settings-list.json +3 -3
- package/r/setup-checklist.json +3 -3
- package/r/share-dialog.json +3 -3
- package/r/sidebar.json +2 -2
- package/r/signature-pad.json +3 -3
- package/r/sketch-canvas.json +5 -5
- package/r/spreadsheet.json +3 -3
- package/r/stat-cards.json +4 -4
- package/r/task-list.json +4 -4
- package/r/task-model.json +3 -3
- package/r/testimonials.json +2 -2
- package/r/transaction-list.json +3 -3
- package/r/whiteboard.json +4 -4
- package/registry/blocks/annotate/README.md +14 -5
- package/registry/blocks/approval-request/README.md +15 -8
- package/registry/blocks/audio-player/README.md +17 -10
- package/registry/blocks/board/README.md +13 -9
- package/registry/blocks/board/board.jsx +1 -1
- package/registry/blocks/calendar-view/README.md +28 -4
- package/registry/blocks/cart/README.md +14 -10
- package/registry/blocks/chart/README.md +14 -7
- package/registry/blocks/chat/README.md +43 -13
- package/registry/blocks/code-editor/README.md +4 -0
- package/registry/blocks/code-editor/code-editor.jsx +1 -1
- package/registry/blocks/comment-box/README.md +20 -13
- package/registry/blocks/contact-section/README.md +7 -6
- package/registry/blocks/csv-import/README.md +34 -12
- package/registry/blocks/data-table/README.md +41 -8
- package/registry/blocks/diagram/diagram.jsx +1 -1
- package/registry/blocks/doc-editor/README.md +18 -6
- package/registry/blocks/doc-editor/doc-editor.jsx +1 -1
- package/registry/blocks/doc-page/README.md +16 -6
- package/registry/blocks/file-upload/README.md +7 -1
- package/registry/blocks/flow-canvas/README.md +16 -5
- package/registry/blocks/flow-canvas/flow-canvas.jsx +1 -1
- package/registry/blocks/footer/README.md +4 -2
- package/registry/blocks/gantt/README.md +18 -12
- package/registry/blocks/job-panel/README.md +1 -1
- package/registry/blocks/json-editor/README.md +16 -4
- package/registry/blocks/map/README.md +19 -3
- package/registry/blocks/map/map-view.jsx +1 -1
- package/registry/blocks/map/maplibre.js +1 -1
- package/registry/blocks/mind-map/README.md +16 -5
- package/registry/blocks/org-chart/README.md +10 -7
- package/registry/blocks/page-builder/README.md +13 -6
- package/registry/blocks/page-builder/page-builder.jsx +1 -1
- package/registry/blocks/page-builder/page-view.jsx +1 -1
- package/registry/blocks/page-builder/page.js +1 -1
- package/registry/blocks/pdf-viewer/README.md +22 -20
- package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1 -1
- package/registry/blocks/pdf-viewer/pdfjs.js +1 -1
- package/registry/blocks/pdf-viewer/ssr-shim.js +1 -1
- package/registry/blocks/product-detail/README.md +13 -7
- package/registry/blocks/product-detail/demo.jsx +1 -1
- package/registry/blocks/product-grid/README.md +12 -10
- package/registry/blocks/record-form/README.md +26 -9
- package/registry/blocks/record-notes/README.md +42 -30
- package/registry/blocks/search-dialog/README.md +38 -7
- package/registry/blocks/settings-list/README.md +29 -17
- package/registry/blocks/setup-checklist/README.md +12 -14
- package/registry/blocks/share-dialog/README.md +1 -1
- package/registry/blocks/signature-pad/README.md +15 -4
- package/registry/blocks/sketch-canvas/README.md +13 -4
- package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1 -1
- package/registry/blocks/sketch-canvas/ssr-shim.js +3 -3
- package/registry/blocks/spreadsheet/README.md +17 -8
- package/registry/blocks/stat-cards/README.md +17 -8
- package/registry/blocks/task-list/README.md +14 -11
- package/registry/blocks/task-model/README.md +3 -3
- package/registry/blocks/transaction-list/README.md +15 -7
- package/registry/blocks/whiteboard/README.md +19 -13
- package/src/cli.mjs +31 -4
- package/src/install.mjs +263 -21
- package/src/registry.mjs +78 -1
- package/templates/next/browser/app/auto-refresh.jsx +67 -0
- package/templates/next/browser/app/layout.jsx +94 -0
- package/templates/next/browser/app/page.jsx +60 -0
- package/templates/next/browser/app/s/[key]/page.jsx +95 -0
- package/templates/next/browser/lib/actions.js +16 -0
- package/templates/next/browser/lib/data.js +43 -0
- package/templates/next/files/README.md +810 -79
- package/templates/next/files/app/frame.js +128 -4
- package/templates/next/files/check/run.mjs +1438 -41
- package/templates/next/files/components/ui/item.jsx +2 -2
- package/templates/next/files/components/ui/notice.jsx +1 -1
- package/templates/next/files/components/ui/separator.jsx +1 -1
- package/templates/next/files/lib/actions.js +170 -51
- package/templates/next/files/lib/brain-server.js +96 -0
- package/templates/next/files/lib/brain.js +413 -0
- package/templates/next/files/lib/claw.js +11 -0
- package/templates/next/files/lib/data.js +119 -29
- package/templates/next/files/lib/db.js +97 -17
- package/templates/next/files/lib/door.js +680 -0
- package/templates/next/files/next.config.mjs +36 -2
- package/templates/next/files/surfaces.js +3 -2
- package/templates/next/template.json +9 -3
- package/templates/next/files/schema.sql +0 -22
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { headers } from "next/headers";
|
|
1
2
|
import { Pool, types } from "pg";
|
|
2
3
|
|
|
3
4
|
// A `date` column is a day on a wall calendar, not an instant, so it is
|
|
@@ -26,18 +27,84 @@ globalThis._pgPool = pool;
|
|
|
26
27
|
|
|
27
28
|
export const query = (text, params) => pool.query(text, params);
|
|
28
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Who is asking: the member the platform's proxy named on this request
|
|
32
|
+
* (`x-claw-user-id`, `x-claw-user-email`; the proxy drops a browser's own
|
|
33
|
+
* copies first, so they are only ever its word). `''` for each one it did
|
|
34
|
+
* not name: a local run, a render outside a request, a job.
|
|
35
|
+
* → { id, email }
|
|
36
|
+
*/
|
|
37
|
+
export async function requestMember() {
|
|
38
|
+
try {
|
|
39
|
+
const asked = await headers();
|
|
40
|
+
return { id: asked.get("x-claw-user-id") || "", email: asked.get("x-claw-user-email") || "" };
|
|
41
|
+
} catch {
|
|
42
|
+
return { id: "", email: "" };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The member, told to the database inside the write's own transaction. The
|
|
47
|
+
// third argument, true, makes each setting local: the COMMIT ends it, so the
|
|
48
|
+
// next statement on this pooled connection never runs as this member. Never
|
|
49
|
+
// false (the platform's rule since the Neon probe; test/data.test.mjs greps
|
|
50
|
+
// the template for it). Values are bound, never written into the text.
|
|
51
|
+
const MEMBER_SETTINGS =
|
|
52
|
+
"SELECT set_config('claw.member_id', $1, true), set_config('claw.member_email', $2, true)";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Run `work(query)` in one transaction on one connection, after telling
|
|
56
|
+
* the database who is asking. A default, a trigger or an action function
|
|
57
|
+
* reads it the same way in a server app and a browser one (where the
|
|
58
|
+
* platform's data door sets the same two):
|
|
59
|
+
*
|
|
60
|
+
* nullif(current_setting('claw.member_email', true), '')
|
|
61
|
+
*
|
|
62
|
+
* It is a label, not a permission: nothing in the platform trusts it, and
|
|
63
|
+
* a column the page must not choose (`created_by`) is set by a trigger
|
|
64
|
+
* that reads it. Every lib/actions.js write runs here. `work` gets a
|
|
65
|
+
* `query(text, params)` bound to the transaction's connection; use only
|
|
66
|
+
* that inside it. → whatever `work` returns. A failure rolls back and
|
|
67
|
+
* throws on.
|
|
68
|
+
*/
|
|
69
|
+
export async function transaction(work) {
|
|
70
|
+
const member = await requestMember();
|
|
71
|
+
const client = await pool.connect();
|
|
72
|
+
let broken;
|
|
73
|
+
try {
|
|
74
|
+
await client.query("BEGIN");
|
|
75
|
+
await client.query(MEMBER_SETTINGS, [member.id, member.email]);
|
|
76
|
+
const result = await work((text, params) => client.query(text, params));
|
|
77
|
+
await client.query("COMMIT");
|
|
78
|
+
return result;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
try {
|
|
81
|
+
await client.query("ROLLBACK");
|
|
82
|
+
} catch (lost) {
|
|
83
|
+
// The connection itself failed: the pool must not lend it again.
|
|
84
|
+
broken = lost;
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
} finally {
|
|
88
|
+
client.release(broken);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
29
92
|
/** The artifact this app belongs to. product_run sets it from the folder
|
|
30
|
-
* the app runs in;
|
|
31
|
-
*
|
|
93
|
+
* the app runs in; app/layout.jsx reads it to turn examples off, and an
|
|
94
|
+
* app may use it to name itself. The activity lines no longer need it:
|
|
95
|
+
* claw_app.activity fills in the app itself (logActivity, below). */
|
|
32
96
|
export function artifactId() {
|
|
33
97
|
return process.env.CLAW_ARTIFACT_ID || null;
|
|
34
98
|
}
|
|
35
99
|
|
|
36
100
|
const IDENT = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
37
101
|
|
|
38
|
-
/** Quote a table or column name for SQL: "investors" → "investors"
|
|
39
|
-
*
|
|
40
|
-
*
|
|
102
|
+
/** Quote a table or column name for SQL: "investors" → "investors".
|
|
103
|
+
* An app names its tables bare: its own schema is first on its role's
|
|
104
|
+
* search_path. Two parts still pass ("public.investors" →
|
|
105
|
+
* "public"."investors"), for an app from before 0.7.0 whose tables are
|
|
106
|
+
* in public and whose code says so. Anything else throws, so a typo in a
|
|
107
|
+
* surface config can never reach the database as SQL. */
|
|
41
108
|
export function ident(name) {
|
|
42
109
|
const parts = String(name ?? "").split(".");
|
|
43
110
|
if (!parts.length || parts.length > 2 || !parts.every((p) => IDENT.test(p))) {
|
|
@@ -46,13 +113,26 @@ export function ident(name) {
|
|
|
46
113
|
return parts.map((p) => `"${p}"`).join(".");
|
|
47
114
|
}
|
|
48
115
|
|
|
116
|
+
// Postgres's "relation does not exist": no claw_app.activity to write to.
|
|
117
|
+
const NO_SUCH_RELATION = "42P01";
|
|
118
|
+
|
|
49
119
|
/**
|
|
50
120
|
* Record what happened, for the Activity tab the OS draws on the app
|
|
51
|
-
* window (and any surface that reads the
|
|
52
|
-
* lib/actions.js write calls this; the
|
|
53
|
-
*
|
|
121
|
+
* window (and any surface that reads the lines with loadActivity). Every
|
|
122
|
+
* lib/actions.js write calls this; the app's agent writes the same lines
|
|
123
|
+
* with the sql verb.
|
|
54
124
|
* Never throws — an activity line must not fail the write it describes.
|
|
55
125
|
*
|
|
126
|
+
* The line goes into claw_app.activity: the platform's view of the
|
|
127
|
+
* workspace's activity table, holding only this app's lines. The view
|
|
128
|
+
* fills in `artifact_id` (the app whose role the connection runs as) and
|
|
129
|
+
* `id`, so this names neither: the app needs no CLAW_ARTIFACT_ID, and it
|
|
130
|
+
* cannot write a line as another app. Up to 0.6.x it inserted into
|
|
131
|
+
* public.artifact_activity with CLAW_ARTIFACT_ID; an app on its own schema
|
|
132
|
+
* can reach nothing in public. Outside Makersclaw, or on a platform from
|
|
133
|
+
* before the view, there is no claw_app.activity: the line is not
|
|
134
|
+
* recorded, and this returns false, as on any other failure.
|
|
135
|
+
*
|
|
56
136
|
* action found, drafted, sent, replied, skipped, edited, moved, added…
|
|
57
137
|
* surface the surface key the row belongs to (the OS tab shows its
|
|
58
138
|
* label; a link into the app is /s/<surface>?row=<row_ref>)
|
|
@@ -62,17 +142,11 @@ export function ident(name) {
|
|
|
62
142
|
* by 'agent' | 'user:<email>' | 'run:<id>'
|
|
63
143
|
*/
|
|
64
144
|
export async function logActivity({ action, surface, row_ref, detail, data, by }) {
|
|
65
|
-
const id = artifactId();
|
|
66
|
-
if (!id) {
|
|
67
|
-
console.warn(`[activity] not recorded (no CLAW_ARTIFACT_ID): ${action} ${detail ?? ""}`);
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
145
|
try {
|
|
71
146
|
await query(
|
|
72
|
-
`INSERT INTO
|
|
73
|
-
VALUES ($1, $2, $3, $4, $5
|
|
147
|
+
`INSERT INTO claw_app.activity (action, surface, row_ref, detail, data, by)
|
|
148
|
+
VALUES ($1, $2, $3, $4, $5::jsonb, $6)`,
|
|
74
149
|
[
|
|
75
|
-
id,
|
|
76
150
|
String(action || "edited"),
|
|
77
151
|
surface ?? null,
|
|
78
152
|
row_ref == null ? null : String(row_ref),
|
|
@@ -83,7 +157,13 @@ export async function logActivity({ action, surface, row_ref, detail, data, by }
|
|
|
83
157
|
);
|
|
84
158
|
return true;
|
|
85
159
|
} catch (error) {
|
|
86
|
-
|
|
160
|
+
// No view is where the app runs, not a fault in it: a warning, as the
|
|
161
|
+
// missing CLAW_ARTIFACT_ID was up to 0.6.x. Anything else is an error.
|
|
162
|
+
if (error?.code === NO_SUCH_RELATION) {
|
|
163
|
+
console.warn(`[activity] not recorded (no claw_app.activity here): ${action} ${detail ?? ""}`);
|
|
164
|
+
} else {
|
|
165
|
+
console.error(`[activity] not recorded: ${String(error)}`);
|
|
166
|
+
}
|
|
87
167
|
return false;
|
|
88
168
|
}
|
|
89
169
|
}
|