@hazem3500/palette 0.9.109 → 0.9.110
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 +26 -22
- package/cli/agent.mjs +7 -6
- package/cli/index.mjs +9 -5
- package/dist/chunk-U55ASP2Y.js +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{onboarding-YZ2MJBS5.js → onboarding-6OSADOWE.js} +1 -1
- package/dist/react.js +1 -1
- package/dist/server.js +1 -1
- package/dist/setup.js +1 -1
- package/package.json +1 -1
- package/server/setup-client.txt +2 -2
- package/dist/chunk-ZIEPA67C.js +0 -1
package/README.md
CHANGED
|
@@ -17,21 +17,16 @@ Review actions update immediately while saving in the background. Failed writes
|
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
19
|
npm install @hazem3500/palette
|
|
20
|
-
npx @hazem3500/palette init
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
Requires Node.js 22 or newer. The unscoped `komo` package on npm is unrelated; use `@hazem3500/palette`.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Palette has no hosted default. Comments go to a Palette server that you run, and every install sets `endpoint` to it. Start a server first:
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
initPalette();
|
|
30
|
-
```
|
|
26
|
+
- **Node and PostgreSQL**, including Cloud Run: run `npx @hazem3500/palette init --node` and follow the [Node self-hosting guide](./NODE.md).
|
|
27
|
+
- **Cloudflare Worker and D1**: run `npx @hazem3500/palette init --self-host`; see [Self-host](#self-host).
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Hosted onboarding is available through the dedicated Palette service. Self-hosting is available through the same CLI.
|
|
29
|
+
Both print the `endpoint` and project key for your site. If your team already runs a Palette server with hosted setup turned on (`PALETTE_HOSTED=true`), connect to it with `npx @hazem3500/palette init --endpoint https://palette.example.com`; see [Hosted setup](#hosted-setup).
|
|
35
30
|
|
|
36
31
|
## Usage
|
|
37
32
|
|
|
@@ -39,13 +34,17 @@ Mount after the page has loaded:
|
|
|
39
34
|
|
|
40
35
|
```js
|
|
41
36
|
import { initPalette } from '@hazem3500/palette';
|
|
42
|
-
initPalette({
|
|
37
|
+
initPalette({
|
|
38
|
+
endpoint: 'https://palette.example.com',
|
|
39
|
+
project: 'YOUR_PROJECT_KEY',
|
|
40
|
+
});
|
|
43
41
|
```
|
|
44
42
|
|
|
45
43
|
Optional configuration stays at the call site:
|
|
46
44
|
|
|
47
45
|
```js
|
|
48
46
|
initPalette({
|
|
47
|
+
endpoint: 'https://palette.example.com',
|
|
49
48
|
project: 'YOUR_PROJECT_KEY',
|
|
50
49
|
enabled: import.meta.env.DEV || import.meta.env.PUBLIC_PREVIEW === 'true',
|
|
51
50
|
pageRoot: document.querySelector('#app'),
|
|
@@ -61,14 +60,17 @@ With React 18.2 or 19, call the hook once near your app root:
|
|
|
61
60
|
import { usePalette } from '@hazem3500/palette/react';
|
|
62
61
|
|
|
63
62
|
export function Palette() {
|
|
64
|
-
usePalette({
|
|
63
|
+
usePalette({
|
|
64
|
+
endpoint: 'https://palette.example.com',
|
|
65
|
+
project: 'YOUR_PROJECT_KEY',
|
|
66
|
+
});
|
|
65
67
|
return null;
|
|
66
68
|
}
|
|
67
69
|
```
|
|
68
70
|
|
|
69
71
|
Render `<Palette />` in your app or layout. The hook handles mounting, cleanup, and React Strict Mode. Inline configuration objects are supported; unchanged values do not restart Palette. Changing configuration remounts it, and `enabled: false` removes it. Memoize callback options with `useCallback` and pass stable DOM elements for `pageRoot` or `drawerContainer`. Mount only one hook per page; do not combine it with a separate `initPalette()` call. Server rendering does not mount the tool.
|
|
70
72
|
|
|
71
|
-
The **endpoint is the comments API**, not your website or preview URL.
|
|
73
|
+
The **endpoint is the comments API**, your Palette server, not your website or preview URL. It is required: without it, Palette logs an error and does not mount. Google sign-in returns to `ENDPOINT/auth/google/callback`, regardless of the website embedding Palette. Your current page comes from the browser. Setup detects repository metadata from Git; include its printed `repo` value to enrich agent prompts.
|
|
72
74
|
|
|
73
75
|
Comments are shared across deployments by default. Use `pnpm exec palette init --branch-scope` to separate them by branch. For automatic branch detection, import from the optional generated `palette.config.js` helper and run `palette sync` before builds. It detects the current branch from deployment environment variables or Git; set `PALETTE_BRANCH` if neither is available. It fails rather than silently grouping unknown branches.
|
|
74
76
|
|
|
@@ -104,7 +106,7 @@ Palette was called komo. Existing installs keep working without changes.
|
|
|
104
106
|
- **Crowded pins** consolidate. Comments on the same target (its persistent owner, including a custom `anchorTarget`) draw as one tight avatar stack at the oldest comment's anchor; more than three collapse to the first author and a count. Hover, keyboard focus or a tap fans the stack out in creation order, and each pin opens its own thread. Pins on different targets whose 24px targets overlap at the current zoom or Frame scale merge into a count bubble; it opens a keyboard-navigable list of those comments. Grouping never changes anchors or saves anything, the open comment's pin is always drawn at its own anchor, and a pin moved with **Move pin** stays out of stacks and bubbles. Set `pins.cluster: false` to draw every pin on its own.
|
|
105
107
|
- Keyboard shortcuts: C to comment, V to browse, D to toggle Design mode, L to view all comments, H to hide or show comments, Shift+K to restore. Remap or disable them with `shortcuts`; see [Choosing shortcuts](#choosing-shortcuts). In Design mode, ? or **Keyboard shortcuts** in the empty inspector lists every canvas key and gesture.
|
|
106
108
|
- Copy open feedback with selectors, source paths, page URLs, replies, and geometry into an agent.
|
|
107
|
-
-
|
|
109
|
+
- Your own Worker/D1 or Node/PostgreSQL service.
|
|
108
110
|
|
|
109
111
|
Comment pins stay anchored during ordinary pointer drags. Authors and verified reviewers can choose **Comment actions → Move pin** to reposition one explicitly: drag it, or use arrow keys (Shift for larger steps), then Enter or **Save position**. Escape or **Cancel move** restores its previous position without saving. Completed moves use the existing thread anchor endpoint and remain attached after reload; the page element itself never moves. Dragging a floating comment card is independent of pin placement.
|
|
110
112
|
|
|
@@ -481,7 +483,7 @@ if (import.meta.env.DEV && isShell(palette.project)) {
|
|
|
481
483
|
|
|
482
484
|
Give a bot its own revocable credential instead of sharing your login.
|
|
483
485
|
|
|
484
|
-
1. **Create a token.** Signed in with Google, open **Account → API tokens** in the Palette toolbar, or `/account` on your Palette server
|
|
486
|
+
1. **Create a token.** Signed in with Google, open **Account → API tokens** in the Palette toolbar, or `/account` on your Palette server. Name the token, pick an expiry, choose scopes, and optionally limit it to projects you own or have joined. The token is shown once; copy it into your secret manager. Guest sessions cannot create tokens.
|
|
485
487
|
2. **Set `PALETTE_TOKEN`.** Export it in the bot's environment, or save it once with `printf %s "$PALETTE_TOKEN" | palette login --token` (stdin only; a token passed as an argument is refused). Check it with `palette whoami`. `palette logout` removes saved credentials.
|
|
486
488
|
3. **Use the CLI as usual.** The project, endpoint, and origin come from `.palette/project.json` or the `PALETTE_*` overrides.
|
|
487
489
|
|
|
@@ -525,11 +527,13 @@ Projects default to link access. Owners can restrict feedback to invited Google
|
|
|
525
527
|
|
|
526
528
|
## Hosted setup
|
|
527
529
|
|
|
530
|
+
A Palette server with `PALETTE_HOSTED=true` lets Google users create their own workspaces. Point the CLI at it:
|
|
531
|
+
|
|
528
532
|
```sh
|
|
529
|
-
pnpm exec palette init
|
|
533
|
+
pnpm exec palette init --endpoint https://palette.example.com
|
|
530
534
|
```
|
|
531
535
|
|
|
532
|
-
Mount the generated `palette.config.js` helper and open your app. Select **Connect** in the sidebar and sign in with Google. Review the detected production and preview addresses in the sidebar and add any others, one per line. Connecting approves the current site and those listed addresses, including production sites that have not launched. Remove a suggested address to leave it unapproved. Google credentials and account-wide management stay on
|
|
536
|
+
Mount the generated `palette.config.js` helper and open your app. Select **Connect** in the sidebar and sign in with Google. Review the detected production and preview addresses in the sidebar and add any others, one per line. Connecting approves the current site and those listed addresses, including production sites that have not launched. Remove a suggested address to leave it unapproved. Google credentials and account-wide management stay on that Palette server; your site receives a session for its new project.
|
|
533
537
|
|
|
534
538
|
The CLI waits up to ten minutes and replaces the temporary setup configuration after connection. Keep the terminal open. Run `palette init` again after an interruption or expiry. The temporary polling secret stays in ignored `.palette/setup.json` and is never bundled into your site. A reload can resume commenting while the CLI finishes. Run `palette sync` before builds that use the generated helper.
|
|
535
539
|
|
|
@@ -539,7 +543,7 @@ Approve your deployed website in **Approved sites**. Palette detects deployment
|
|
|
539
543
|
|
|
540
544
|
The setup page manages your account and approved sites. Leave comments on the website where you installed Palette.
|
|
541
545
|
|
|
542
|
-
Return to `/setup?workspace=<project key>` to approve additional sites (up to ten). Only the Google owner can approve sites. The site address controls where that owner’s project can be embedded; it does not grant ownership of a domain or access to other projects. The API endpoint is
|
|
546
|
+
Return to `/setup?workspace=<project key>` to approve additional sites (up to ten). Only the Google owner can approve sites. The site address controls where that owner’s project can be embedded; it does not grant ownership of a domain or access to other projects. The API endpoint is your Palette server, not your website URL.
|
|
543
547
|
|
|
544
548
|
Starter limits per owner/workspace:
|
|
545
549
|
|
|
@@ -588,11 +592,11 @@ For a Node container with PostgreSQL (including Cloud Run), use the [Node self-h
|
|
|
588
592
|
|
|
589
593
|
Pass these to `initPalette(config)` from `@hazem3500/palette` or `usePalette(config)` from `@hazem3500/palette/react`.
|
|
590
594
|
|
|
591
|
-
`YOUR_PROJECT_KEY` is a placeholder for a string. Hosted
|
|
595
|
+
`YOUR_PROJECT_KEY` is a placeholder for a string. Hosted setup (`palette init --endpoint`) generates the key; copy that value. For self-hosting, use the project identifier configured on your server. Reuse the same key across sites that should share feedback.
|
|
592
596
|
|
|
593
597
|
| Option | Type | Default | Purpose |
|
|
594
598
|
| --- | --- | --- | --- |
|
|
595
|
-
| `endpoint` | `string` |
|
|
599
|
+
| `endpoint` | `string` | Required | Your Palette server's API root; HTTPS outside localhost. Without it, Palette logs an error and does not mount. |
|
|
596
600
|
| `project` | `string` | Required | Public project identifier returned by setup. |
|
|
597
601
|
| `repo` | `string` | Project key | Repository identifier, usually `owner/repo`. |
|
|
598
602
|
| `scope` | `"project" \| "branch"` | `"project"` | `"project"` shares comments; `"branch"` separates branches. |
|
|
@@ -728,12 +732,12 @@ Limits: the image shows the element at the top of its scroll position and up to
|
|
|
728
732
|
|
|
729
733
|
| Command / flag | Purpose |
|
|
730
734
|
| --- | --- |
|
|
731
|
-
| `palette init` | Create a Google-owned hosted
|
|
735
|
+
| `palette init --endpoint URL` | Create a Google-owned workspace on a server with hosted setup turned on. |
|
|
732
736
|
| `palette init --self-host` | Create your Worker and D1 database. |
|
|
733
737
|
| `palette sync` | Regenerate the public client helper. Run before dev/build. |
|
|
734
738
|
| `palette deploy` | Resume or redeploy generated self-host infrastructure. |
|
|
735
739
|
| `--origin URL` | Optional website address. Otherwise detected from Cloudflare Pages, Vercel, or Netlify; defaults to localhost. |
|
|
736
|
-
| `--endpoint URL` |
|
|
740
|
+
| `--endpoint URL` | Your Palette server (or `PALETTE_ENDPOINT`). Required; there is no default. |
|
|
737
741
|
| `--repo OWNER/REPO` | Override Git detection. |
|
|
738
742
|
| `--branch-scope` | Opt into separate comments per branch. |
|
|
739
743
|
| `--google-client-id ID` | Self-hosted Google OAuth client ID. |
|
|
@@ -855,7 +859,7 @@ npx @hazem3500/palette project import --file /path/to/comments.json
|
|
|
855
859
|
|
|
856
860
|
Exports include threads, replies, reactions, element snapshots, anchors, and historical profiles across all pages and branches, including resolved feedback. They exclude sessions, credentials, verified emails, and membership. Imports use the destination repository and keep imported authors unverified. Retrying the same export is safe; existing imported records are not overwritten. Destination quotas still apply. Export retries are required if feedback changes while downloading. Keep export files private.
|
|
857
861
|
|
|
858
|
-
Upgrade self-hosted deployments with `npm install @hazem3500/palette@latest` then `npx @hazem3500/palette deploy`; the CLI applies bundled database migrations before redeploying. Self-hosted project removal is controlled by your Worker configuration.
|
|
862
|
+
Upgrade self-hosted deployments with `npm install @hazem3500/palette@latest` then `npx @hazem3500/palette deploy`; the CLI applies bundled database migrations before redeploying. Self-hosted project removal is controlled by your Worker configuration.
|
|
859
863
|
|
|
860
864
|
Without `pageRoot`, a sole existing content element with a layout box enables Frame. Script and style elements do not count as content roots. Multiple roots or `display: contents` use Floating; pass a suitable existing app container for Frame.
|
|
861
865
|
|
package/cli/agent.mjs
CHANGED
|
@@ -164,12 +164,13 @@ async function configuration(flags, cwd, env) {
|
|
|
164
164
|
const project = flags.project || setting(env, "PROJECT") || settings.project;
|
|
165
165
|
if (!project)
|
|
166
166
|
throw Error("Run palette init in this repository, or pass --project KEY.");
|
|
167
|
-
const
|
|
168
|
-
flags.endpoint ||
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"
|
|
172
|
-
|
|
167
|
+
const configured =
|
|
168
|
+
flags.endpoint || setting(env, "ENDPOINT") || settings.endpoint;
|
|
169
|
+
if (!configured)
|
|
170
|
+
throw Error(
|
|
171
|
+
"No Palette server configured. Pass --endpoint URL, set PALETTE_ENDPOINT, or add endpoint to .palette/project.json."
|
|
172
|
+
);
|
|
173
|
+
const endpoint = safeUrl(configured);
|
|
173
174
|
const origin = safeUrl(
|
|
174
175
|
flags.origin ||
|
|
175
176
|
setting(env, "ORIGIN") ||
|
package/cli/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { createInterface } from "node:readline/promises";
|
|
7
7
|
import { randomUUID, randomBytes, createHash } from "node:crypto";
|
|
8
|
-
import { branchName, clientModule, gitValue, projectLayout, repository } from "./config.mjs";
|
|
8
|
+
import { branchName, clientModule, gitValue, projectLayout, repository, setting } from "./config.mjs";
|
|
9
9
|
|
|
10
10
|
import { installAgentWorkflow } from "./workflow.mjs";
|
|
11
11
|
import { agentCommands, agentHelp, runAgent } from "./agent.mjs";
|
|
@@ -208,8 +208,12 @@ async function init() {
|
|
|
208
208
|
if (!selfHosted && !nodeHosted) {
|
|
209
209
|
const endpoint =
|
|
210
210
|
flag("--endpoint") ||
|
|
211
|
-
(
|
|
212
|
-
|
|
211
|
+
setting(process.env, "ENDPOINT") ||
|
|
212
|
+
(resuming ? previous.endpoint : "");
|
|
213
|
+
if (!endpoint)
|
|
214
|
+
throw Error(
|
|
215
|
+
"Palette has no default server. Pass --endpoint URL or set PALETTE_ENDPOINT to your Palette server, or self-host with palette init --node (see NODE.md) or palette init --self-host."
|
|
216
|
+
);
|
|
213
217
|
const api = new URL(endpoint);
|
|
214
218
|
if (
|
|
215
219
|
api.protocol !== "https:" &&
|
|
@@ -226,7 +230,7 @@ async function init() {
|
|
|
226
230
|
setup.expiresAt <= Date.now() ||
|
|
227
231
|
flag("--origin") ||
|
|
228
232
|
flag("--repo") ||
|
|
229
|
-
|
|
233
|
+
endpoint !== previous?.endpoint
|
|
230
234
|
) {
|
|
231
235
|
setup = {
|
|
232
236
|
...(await request(endpoint, "/setup/start", { repo, origins })),
|
|
@@ -381,7 +385,7 @@ async function init() {
|
|
|
381
385
|
try {
|
|
382
386
|
if (args.includes("--help") || !command)
|
|
383
387
|
console.log(
|
|
384
|
-
`Palette\n\n palette init
|
|
388
|
+
`Palette\n\n palette init --endpoint API_URL Connect to an existing Palette server\n palette init --self-host Deploy your own Worker and D1 database\n palette init --node Prepare a Node/PostgreSQL project\n palette deploy Resume self-hosted deployment\n palette sync Regenerate client settings; detect the current branch\n\nOptions: --origin URL --endpoint API_URL --repo OWNER/REPO --branch-scope\nSelf-host: --google-client-id ID; Node: --preview-origin HTTPS_WILDCARD\n\nComments are shared across deployments unless --branch-scope is set.${
|
|
385
389
|
agentHelp
|
|
386
390
|
}`
|
|
387
391
|
);
|