@agent-native/core 0.69.0 → 0.70.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +48 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/changelog/parse.ts +245 -0
- package/corpus/core/src/cli/changelog.ts +199 -0
- package/corpus/core/src/cli/index.ts +19 -0
- package/corpus/core/src/cli/recap.ts +24 -1
- package/corpus/core/src/cli/skills.ts +72 -45
- package/corpus/core/src/client/CommandMenu.tsx +183 -75
- package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
- package/corpus/core/src/client/analytics.ts +181 -0
- package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
- package/corpus/core/src/client/index.ts +11 -0
- package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
- package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
- package/corpus/core/src/mcp/build-server.ts +1 -1
- package/corpus/core/src/mcp/embed-app.ts +112 -6
- package/corpus/core/src/server/attribution.ts +211 -0
- package/corpus/core/src/server/auth.ts +6 -0
- package/corpus/core/src/server/better-auth-instance.ts +49 -5
- package/corpus/core/src/server/builder-browser.ts +27 -1
- package/corpus/core/src/server/core-routes-plugin.ts +58 -0
- package/corpus/core/src/server/google-oauth.ts +19 -6
- package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
- package/corpus/core/src/styles/agent-conversation.css +21 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/corpus/templates/analytics/CHANGELOG.md +10 -0
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +2 -2
- package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/update-dashboard.ts +5 -3
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
- package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -2
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -213
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -3
- package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
- package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
- package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
- package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
- package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
- package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
- package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
- package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
- package/corpus/templates/analytics/server/db/index.ts +1 -1
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
- package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
- package/corpus/templates/assets/CHANGELOG.md +10 -0
- package/corpus/templates/assets/app/root.tsx +7 -1
- package/corpus/templates/assets/app/routes/settings.tsx +6 -0
- package/corpus/templates/brain/CHANGELOG.md +10 -0
- package/corpus/templates/brain/app/root.tsx +7 -1
- package/corpus/templates/brain/app/routes/settings.tsx +8 -1
- package/corpus/templates/calendar/CHANGELOG.md +10 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
- package/corpus/templates/calendar/app/root.tsx +7 -1
- package/corpus/templates/chat/CHANGELOG.md +10 -0
- package/corpus/templates/chat/app/root.tsx +7 -1
- package/corpus/templates/clips/CHANGELOG.md +10 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
- package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +7 -11
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +31 -0
- package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
- package/corpus/templates/clips/app/root.tsx +7 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
- package/corpus/templates/clips/app/routes/record.tsx +78 -5
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
- package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
- package/corpus/templates/clips/desktop/src/main.tsx +3 -0
- package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
- package/corpus/templates/clips/desktop/src/styles.css +49 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +67 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +51 -1
- package/corpus/templates/clips/shared/share-attribution.ts +79 -0
- package/corpus/templates/content/CHANGELOG.md +10 -0
- package/corpus/templates/content/app/root.tsx +7 -1
- package/corpus/templates/design/CHANGELOG.md +10 -0
- package/corpus/templates/design/actions/generate-design.ts +4 -0
- package/corpus/templates/design/app/root.tsx +7 -1
- package/corpus/templates/design/app/routes/settings.tsx +10 -2
- package/corpus/templates/dispatch/CHANGELOG.md +10 -0
- package/corpus/templates/dispatch/app/root.tsx +7 -1
- package/corpus/templates/forms/CHANGELOG.md +10 -0
- package/corpus/templates/forms/app/root.tsx +7 -1
- package/corpus/templates/macros/CHANGELOG.md +10 -0
- package/corpus/templates/macros/app/root.tsx +7 -1
- package/corpus/templates/mail/CHANGELOG.md +10 -0
- package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
- package/corpus/templates/plan/AGENTS.md +4 -0
- package/corpus/templates/plan/CHANGELOG.md +10 -0
- package/corpus/templates/plan/actions/view-screen.ts +5 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
- package/corpus/templates/plan/app/root.tsx +7 -1
- package/corpus/templates/plan/shared/share-attribution.ts +72 -0
- package/corpus/templates/slides/CHANGELOG.md +10 -0
- package/corpus/templates/slides/app/root.tsx +7 -1
- package/corpus/templates/videos/CHANGELOG.md +4 -151
- package/corpus/templates/videos/app/root.tsx +7 -1
- package/dist/changelog/parse.d.ts +70 -0
- package/dist/changelog/parse.d.ts.map +1 -0
- package/dist/changelog/parse.js +200 -0
- package/dist/changelog/parse.js.map +1 -0
- package/dist/cli/changelog.d.ts +4 -0
- package/dist/cli/changelog.d.ts.map +1 -0
- package/dist/cli/changelog.js +166 -0
- package/dist/cli/changelog.js.map +1 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +22 -1
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +72 -45
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/CommandMenu.d.ts +17 -1
- package/dist/client/CommandMenu.d.ts.map +1 -1
- package/dist/client/CommandMenu.js +49 -13
- package/dist/client/CommandMenu.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +43 -6
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts +18 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +177 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/changelog/Changelog.d.ts +47 -0
- package/dist/client/changelog/Changelog.d.ts.map +1 -0
- package/dist/client/changelog/Changelog.js +138 -0
- package/dist/client/changelog/Changelog.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
- package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
- package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +58 -10
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/mcp/build-server.js +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.d.ts.map +1 -1
- package/dist/mcp/embed-app.js +112 -6
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/server/attribution.d.ts +83 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +178 -0
- package/dist/server/attribution.js.map +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +7 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +9 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +32 -2
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +20 -1
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +25 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +38 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +16 -2
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/shared/mcp-embed-headers.js +1 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-conversation.css +21 -0
- package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
|
@@ -36,8 +36,9 @@ In local-files mode:
|
|
|
36
36
|
`npx @agent-native/core@latest plan blocks --out plan-blocks.md` when the Plan
|
|
37
37
|
MCP connector is not registered; it calls the public no-auth
|
|
38
38
|
`get-plan-blocks` route and sends no recap content. If network access is
|
|
39
|
-
unavailable, use the bundled references and validate with
|
|
40
|
-
`plan local check
|
|
39
|
+
unavailable, use the bundled references and validate the MDX with
|
|
40
|
+
`plan local check`; do not run `plan local serve` unless the hosted Plan UI is
|
|
41
|
+
reachable or a local Plan app is already running. For `checklist` and `question-form`,
|
|
41
42
|
copy the catalog examples verbatim: checklist items need `id` and `label`;
|
|
42
43
|
question-form questions need `id`, `title`, and `mode`; and each option needs
|
|
43
44
|
`id` and `label`. `plan local check` validates these required fields against
|
|
@@ -47,21 +48,24 @@ In local-files mode:
|
|
|
47
48
|
folder such as `.agent-native/plans/<slug>/` or `/tmp/agent-native-plans/<slug>/`
|
|
48
49
|
when it should not be checked in. The folder contains `plan.mdx`, optional
|
|
49
50
|
`canvas.mdx`, optional `prototype.mdx`, and optional `.plan-state.json`. Set
|
|
50
|
-
`kind: "recap"` and `localOnly: true` in frontmatter/state when authoring
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
`kind: "recap"` and `localOnly: true` in frontmatter/state when authoring the
|
|
52
|
+
source. Use that exact chosen folder as `<plan-dir>` in every local CLI command
|
|
53
|
+
below.
|
|
54
|
+
- Run `npx @agent-native/core@latest plan local check --dir <plan-dir>` before
|
|
55
|
+
any preview. When the hosted Plan UI is reachable, run
|
|
56
|
+
`npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open`.
|
|
57
|
+
Report the returned local bridge URL from stdout or `<plan-dir>/.plan-url`.
|
|
56
58
|
Treat `.plan-url` as a local token file and do not commit it. The URL opens
|
|
57
59
|
the hosted Plan UI but reads from the localhost bridge on this machine, so it
|
|
58
60
|
is not shareable across machines. On macOS, `--open` prefers Chromium browsers;
|
|
59
61
|
if Safari opens, switch to Chrome/Chromium because Safari can block the hosted
|
|
60
62
|
HTTPS page from fetching the HTTP localhost bridge. If the Plan app itself is
|
|
61
63
|
running locally with the same `PLAN_LOCAL_DIR`, the `/local-plans/<slug>` route
|
|
62
|
-
is also valid.
|
|
64
|
+
is also valid. In a truly offline environment, hand off the local `<plan-dir>`
|
|
65
|
+
path after `plan local check` and note that interactive preview requires either
|
|
66
|
+
network access to the hosted Plan UI or a running local Plan app.
|
|
63
67
|
- For headless verification, run
|
|
64
|
-
`npx @agent-native/core@latest plan local verify --dir
|
|
68
|
+
`npx @agent-native/core@latest plan local verify --dir <plan-dir> --kind recap`.
|
|
65
69
|
It starts the bridge, checks the private-network preflight and JSON payload,
|
|
66
70
|
prints diagnostics, and exits. If the browser hangs on "Loading plan", fetch
|
|
67
71
|
the `bridgeUrl` from the verify/serve JSON to read the concrete validation
|
|
@@ -72,7 +76,9 @@ In local-files mode:
|
|
|
72
76
|
`set-resource-visibility`, or any hosted Plan tool for that recap except the
|
|
73
77
|
schema-only block catalog lookup above.
|
|
74
78
|
- Treat review feedback as file or chat feedback: update the MDX files directly,
|
|
75
|
-
rerun
|
|
79
|
+
rerun `plan local check`, and rerun `serve` or `verify` only when that preview
|
|
80
|
+
path is available. Summarize the new local URL when one exists; otherwise
|
|
81
|
+
summarize the checked local folder path.
|
|
76
82
|
Hosted comments, sharing, screenshots, usage attachment, and PR sticky comment
|
|
77
83
|
publishing are unavailable until the user explicitly opts into publishing.
|
|
78
84
|
|
|
@@ -288,10 +294,10 @@ and re-import before reporting the link. A text-match screenshot is not enough;
|
|
|
288
294
|
visually inspect the captured image. When no browser is available (for example
|
|
289
295
|
a headless CI agent), state that in the recap handoff instead.
|
|
290
296
|
|
|
291
|
-
## Top Canvas Recaps — read `../visual-
|
|
297
|
+
## Top Canvas Recaps — read `../visual-plan/references/canvas.md`
|
|
292
298
|
|
|
293
299
|
When a recap includes a top canvas, storyboard, or flow view, READ
|
|
294
|
-
`../visual-
|
|
300
|
+
`../visual-plan/references/canvas.md` before authoring `canvas.mdx`. Recap
|
|
295
301
|
canvas artboards must use the same HTML wireframe path as good document-body
|
|
296
302
|
wireframes: `<Screen surface="..." html={...} />` with a semantic HTML fragment.
|
|
297
303
|
Do not author fresh kit-tree children such as `<FrameScreen>`, `<Card>`,
|
|
@@ -305,8 +311,8 @@ assume it used the legacy kit path and replace it with an HTML screen.
|
|
|
305
311
|
|
|
306
312
|
In local-files privacy mode, run `plan local check` first, then report the local
|
|
307
313
|
bridge URL from
|
|
308
|
-
`npx @agent-native/core@latest plan local serve --dir
|
|
309
|
-
or from
|
|
314
|
+
`npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open`
|
|
315
|
+
or from `<plan-dir>/.plan-url`. It opens the hosted Plan UI but reads from the
|
|
310
316
|
localhost bridge on this machine, so it is not shareable across machines. If the
|
|
311
317
|
Plan app itself is running locally with the same `PLAN_LOCAL_DIR`, the
|
|
312
318
|
`/local-plans/<slug>` route is also valid. Do not invent a hosted database URL
|
|
@@ -471,7 +477,8 @@ installed as plain text and no MCP tools are registered after discovery, run
|
|
|
471
477
|
`npx @agent-native/core@latest plan blocks --out plan-blocks.md` and read that
|
|
472
478
|
file first. The CLI command calls the public no-auth `get-plan-blocks` route and
|
|
473
479
|
sends no plan/recap content. If network access is unavailable, use the bundled
|
|
474
|
-
references and validate with `plan local check
|
|
480
|
+
references and validate with `plan local check`; run `plan local serve` only
|
|
481
|
+
when the hosted Plan UI is reachable or a local Plan app is already running.
|
|
475
482
|
|
|
476
483
|
The catalog returns the authoritative, always-current block vocabulary generated
|
|
477
484
|
live from the app's own block registry — the same config the renderer and MDX
|
|
@@ -579,14 +586,17 @@ inferred (not extracted) as inferred in prose.
|
|
|
579
586
|
|
|
580
587
|
## Bidirectional Loop
|
|
581
588
|
|
|
582
|
-
|
|
583
|
-
applies: a reviewer can annotate any block, and the coding
|
|
584
|
-
`get-plan-feedback` to drive fixes back into the code — annotation →
|
|
585
|
-
diff, the same close-the-loop flow forward plans use. After a reviewer
|
|
586
|
-
a block, call `get-plan-feedback` to read the structured feedback,
|
|
587
|
-
update the recap with `create-visual-recap` (passing the existing
|
|
588
|
-
replace it in place) or apply targeted changes with
|
|
589
|
-
loop is live and wired.
|
|
589
|
+
In hosted mode, because a recap is a real, editable plan, the same review loop
|
|
590
|
+
as forward plans applies: a reviewer can annotate any block, and the coding
|
|
591
|
+
agent reads `get-plan-feedback` to drive fixes back into the code — annotation →
|
|
592
|
+
agent → diff, the same close-the-loop flow forward plans use. After a reviewer
|
|
593
|
+
annotates a block, call `get-plan-feedback` to read the structured feedback,
|
|
594
|
+
then either update the recap with `create-visual-recap` (passing the existing
|
|
595
|
+
`planId` to replace it in place) or apply targeted changes with
|
|
596
|
+
`update-visual-plan`. The loop is live and wired. In local-files privacy mode,
|
|
597
|
+
do not call those hosted tools; read review notes from chat or local files, edit
|
|
598
|
+
`<plan-dir>/*.mdx` directly, and rerun `plan local check`, `serve`, or `verify`
|
|
599
|
+
for `<plan-dir>`. The one thing not yet automatic is PR-comment-triggered
|
|
590
600
|
re-runs: the GitHub Action creates an initial recap per PR, but it does not yet
|
|
591
601
|
re-run automatically when new review feedback is posted in GitHub — that
|
|
592
602
|
auto-re-run is the remaining fast-follow.
|
|
@@ -135,12 +135,15 @@ no labels or copy. The renderer drops borders, sketch, and color into the
|
|
|
135
135
|
skeleton register automatically. Never escape to a `custom-html` document block
|
|
136
136
|
to fake a loader.
|
|
137
137
|
|
|
138
|
-
**Editing an existing mockup.**
|
|
139
|
-
existing html mockup, call
|
|
140
|
-
|
|
138
|
+
**Editing an existing mockup.** In hosted mode, to change one element, text, or
|
|
139
|
+
color in an existing html mockup, do not regenerate the frame — call
|
|
140
|
+
`update-visual-plan` with
|
|
141
|
+
`contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
|
|
141
142
|
replace }] }]`. Each `find` is a unique snippet of the current html (read it
|
|
142
143
|
first with `get-visual-plan`); set `all: true` on an edit to replace every
|
|
143
|
-
occurrence. The result is re-sanitized.
|
|
144
|
+
occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
145
|
+
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
146
|
+
check/serve or verify command for `<plan-dir>`.
|
|
144
147
|
|
|
145
148
|
**Treat the wireframe border as part of the visible design.** Always wrap HTML
|
|
146
149
|
wireframe content in a root container with real inner padding before drawing
|
|
@@ -46,6 +46,10 @@ review before code changes happen.
|
|
|
46
46
|
resource paths for the latest code index, file tree, and captured source
|
|
47
47
|
snapshots.
|
|
48
48
|
- `navigate` moves the UI to the plan list or a specific visual plan.
|
|
49
|
+
- The sidebar brand header has a `Customize branding` popover. Treat it as a
|
|
50
|
+
source-code request, not plan data: local Code mode edits `templates/plan`
|
|
51
|
+
source directly, while hosted/live surfaces route people to Desktop or
|
|
52
|
+
Builder for code customization.
|
|
49
53
|
|
|
50
54
|
## Normal Planning Flow
|
|
51
55
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable user-facing changes to Agent-Native Plan are documented here. Open it any
|
|
4
|
+
time from the command menu (Cmd+K → "What's new").
|
|
5
|
+
|
|
6
|
+
## 2026-06-23
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- See what's new right inside Agent-Native Plan — a changelog now lives in the command menu (Cmd+K).
|
|
@@ -34,6 +34,11 @@ export default defineAction({
|
|
|
34
34
|
const screen: Record<string, unknown> = {};
|
|
35
35
|
if (navigation) screen.navigation = navigation;
|
|
36
36
|
if (localCodebase) screen.localCodebase = localCodebase;
|
|
37
|
+
screen.brandingCustomization = {
|
|
38
|
+
surface: "sidebar brand header",
|
|
39
|
+
workflow:
|
|
40
|
+
"The Customize branding popover sends a source-code request. In local Code mode it routes to the local code agent; on hosted/live surfaces it should guide the user to Desktop or Builder for source edits.",
|
|
41
|
+
};
|
|
37
42
|
const nav = navigation as {
|
|
38
43
|
planId?: string;
|
|
39
44
|
localPlanSlug?: string;
|
|
@@ -28,7 +28,11 @@ import {
|
|
|
28
28
|
appPath,
|
|
29
29
|
markAgentChatHomeHandoff,
|
|
30
30
|
navigateWithAgentChatViewTransition,
|
|
31
|
+
PromptComposer,
|
|
32
|
+
sendToAgentChat,
|
|
33
|
+
useCodeMode,
|
|
31
34
|
useChatThreads,
|
|
35
|
+
useSendToAgentChat,
|
|
32
36
|
useSession,
|
|
33
37
|
type ChatThreadSummary,
|
|
34
38
|
} from "@agent-native/core/client";
|
|
@@ -44,6 +48,11 @@ import {
|
|
|
44
48
|
DropdownMenuTrigger,
|
|
45
49
|
} from "@/components/ui/dropdown-menu";
|
|
46
50
|
import { Input } from "@/components/ui/input";
|
|
51
|
+
import {
|
|
52
|
+
Popover,
|
|
53
|
+
PopoverContent,
|
|
54
|
+
PopoverTrigger,
|
|
55
|
+
} from "@/components/ui/popover";
|
|
47
56
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
48
57
|
import {
|
|
49
58
|
Tooltip,
|
|
@@ -53,6 +62,23 @@ import {
|
|
|
53
62
|
|
|
54
63
|
const PLAN_CHAT_STORAGE_KEY = "plans";
|
|
55
64
|
|
|
65
|
+
const PLAN_BRANDING_CODE_CONTEXT = [
|
|
66
|
+
"The user is using the Plan app branding customization popover.",
|
|
67
|
+
"Make source-code changes for Agent-Native Plan branding in templates/plan.",
|
|
68
|
+
"Inspect the current brand surfaces first: app/lib/app-config.ts, app/components/layout/Sidebar.tsx, app/root.tsx metadata/icons, public brand assets, and app/global.css theme tokens.",
|
|
69
|
+
"Keep runtime plan data, stored plans, recaps, comments, and generated plan content unchanged unless the user explicitly asks for those data changes.",
|
|
70
|
+
"Use existing Plan styling, shadcn primitives, Tabler icons, and repo patterns. Keep changes tightly scoped.",
|
|
71
|
+
].join("\n");
|
|
72
|
+
|
|
73
|
+
function buildBrandingCustomizationMessage(request: string) {
|
|
74
|
+
return [
|
|
75
|
+
"Customize the Agent-Native Plan app branding.",
|
|
76
|
+
"",
|
|
77
|
+
"Request:",
|
|
78
|
+
request,
|
|
79
|
+
].join("\n");
|
|
80
|
+
}
|
|
81
|
+
|
|
56
82
|
const navItems = [
|
|
57
83
|
{ icon: IconMessageCircle, label: "Ask", href: "/" },
|
|
58
84
|
{ icon: IconClipboardCheck, label: "Plan", href: "/plans" },
|
|
@@ -521,6 +547,76 @@ function PlansSidebarSection({ collapsed }: { collapsed: boolean }) {
|
|
|
521
547
|
);
|
|
522
548
|
}
|
|
523
549
|
|
|
550
|
+
function BrandingCustomizePopover() {
|
|
551
|
+
const [open, setOpen] = useState(false);
|
|
552
|
+
const { isCodeMode } = useCodeMode();
|
|
553
|
+
const { send, isGenerating, codeRequiredDialog } = useSendToAgentChat();
|
|
554
|
+
|
|
555
|
+
function handleSubmit(text: string) {
|
|
556
|
+
const trimmed = text.trim();
|
|
557
|
+
if (!trimmed || isGenerating) return;
|
|
558
|
+
const message = buildBrandingCustomizationMessage(trimmed);
|
|
559
|
+
const payload = {
|
|
560
|
+
message,
|
|
561
|
+
context: PLAN_BRANDING_CODE_CONTEXT,
|
|
562
|
+
submit: true,
|
|
563
|
+
type: "code" as const,
|
|
564
|
+
newTab: true,
|
|
565
|
+
};
|
|
566
|
+
const tabId = isCodeMode ? sendToAgentChat(payload) : send(payload);
|
|
567
|
+
setOpen(false);
|
|
568
|
+
if (tabId) {
|
|
569
|
+
toast.success(
|
|
570
|
+
isCodeMode
|
|
571
|
+
? "Sent branding request to the local code agent"
|
|
572
|
+
: "Sent branding request to the code agent",
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return (
|
|
578
|
+
<>
|
|
579
|
+
{codeRequiredDialog}
|
|
580
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
581
|
+
<PopoverTrigger asChild>
|
|
582
|
+
<button
|
|
583
|
+
type="button"
|
|
584
|
+
aria-label="Customize Plan branding"
|
|
585
|
+
title="Customize branding"
|
|
586
|
+
className="flex size-7 shrink-0 items-center justify-center rounded-md text-sidebar-foreground/55 opacity-0 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/brand:opacity-100 group-focus-within/brand:opacity-100 data-[state=open]:opacity-100"
|
|
587
|
+
>
|
|
588
|
+
<IconEdit className="size-3.5" />
|
|
589
|
+
</button>
|
|
590
|
+
</PopoverTrigger>
|
|
591
|
+
<PopoverContent
|
|
592
|
+
side="right"
|
|
593
|
+
align="start"
|
|
594
|
+
sideOffset={8}
|
|
595
|
+
className="w-[calc(100vw-2rem)] max-w-[420px] rounded-xl border-border bg-card p-3 shadow-xl sm:w-[420px]"
|
|
596
|
+
>
|
|
597
|
+
<div className="mb-2 px-1">
|
|
598
|
+
<h3 className="text-sm font-semibold text-foreground">
|
|
599
|
+
Customize branding
|
|
600
|
+
</h3>
|
|
601
|
+
<p className="mt-1 text-xs text-muted-foreground">
|
|
602
|
+
Describe the brand changes to make across Plan.
|
|
603
|
+
</p>
|
|
604
|
+
</div>
|
|
605
|
+
<PromptComposer
|
|
606
|
+
autoFocus
|
|
607
|
+
disabled={isGenerating}
|
|
608
|
+
attachmentsEnabled={false}
|
|
609
|
+
showModelSelector={false}
|
|
610
|
+
placeholder="Use our logo, change the app name, update colors..."
|
|
611
|
+
draftScope="plans:customize-branding"
|
|
612
|
+
onSubmit={handleSubmit}
|
|
613
|
+
/>
|
|
614
|
+
</PopoverContent>
|
|
615
|
+
</Popover>
|
|
616
|
+
</>
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
524
620
|
export function Sidebar({
|
|
525
621
|
collapsed = false,
|
|
526
622
|
collapsible = true,
|
|
@@ -562,7 +658,7 @@ export function Sidebar({
|
|
|
562
658
|
>
|
|
563
659
|
<div
|
|
564
660
|
className={cn(
|
|
565
|
-
"flex h-12 shrink-0 items-center border-b border-border",
|
|
661
|
+
"group/brand flex h-12 shrink-0 items-center border-b border-border",
|
|
566
662
|
collapsed ? "justify-center px-0" : "gap-2 px-3",
|
|
567
663
|
)}
|
|
568
664
|
>
|
|
@@ -590,6 +686,7 @@ export function Sidebar({
|
|
|
590
686
|
</span>
|
|
591
687
|
)}
|
|
592
688
|
</div>
|
|
689
|
+
{!collapsed && <BrandingCustomizePopover />}
|
|
593
690
|
</div>
|
|
594
691
|
|
|
595
692
|
<nav className="flex-1 space-y-1 overflow-y-auto px-2 py-2">
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
useAgentEngineConfigured,
|
|
69
69
|
useActionQuery,
|
|
70
70
|
useSession,
|
|
71
|
+
track,
|
|
71
72
|
emailToColor,
|
|
72
73
|
emailToName,
|
|
73
74
|
type AgentSidebarStateChangeDetail,
|
|
@@ -219,6 +220,11 @@ import {
|
|
|
219
220
|
type PlanVersionDetail,
|
|
220
221
|
type PlanVersionSummary,
|
|
221
222
|
} from "@shared/types";
|
|
223
|
+
import {
|
|
224
|
+
PLAN_SHARE_SURFACE,
|
|
225
|
+
readPlanShareAttribution,
|
|
226
|
+
withPlanShareAttribution,
|
|
227
|
+
} from "@shared/share-attribution";
|
|
222
228
|
import {
|
|
223
229
|
diffPlanVersions,
|
|
224
230
|
formatVersionDiffSummary,
|
|
@@ -3783,13 +3789,92 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
|
|
|
3783
3789
|
}
|
|
3784
3790
|
if (!selectedId) return undefined;
|
|
3785
3791
|
const base = bundle?.plan.kind === "recap" ? "recaps" : "plans";
|
|
3786
|
-
|
|
3792
|
+
const url = `${window.location.origin}${appPath(`/${base}/${selectedId}`)}`;
|
|
3793
|
+
// Viral attribution: tag the shared/public plan link so signups arriving
|
|
3794
|
+
// from it can be attributed even when `document.referrer` is empty. `via`
|
|
3795
|
+
// is a non-PII owner id and is only set when the current viewer is the
|
|
3796
|
+
// owner (the only person whose session userId is the plan owner's id).
|
|
3797
|
+
const ownerViaId =
|
|
3798
|
+
effectivePlanAccessRole === "owner" ? (session?.userId ?? null) : null;
|
|
3799
|
+
return withPlanShareAttribution(url, ownerViaId);
|
|
3787
3800
|
}, [
|
|
3788
3801
|
bundle?.plan.kind,
|
|
3802
|
+
effectivePlanAccessRole,
|
|
3789
3803
|
localPlanMode,
|
|
3790
3804
|
localPlanRepoPath,
|
|
3791
3805
|
localPlanSlug,
|
|
3792
3806
|
selectedId,
|
|
3807
|
+
session?.userId,
|
|
3808
|
+
]);
|
|
3809
|
+
|
|
3810
|
+
// Viral attribution: read the `ref`/`via` the visitor arrived on (from a
|
|
3811
|
+
// tagged share link) so funnel events carry the same attribution the
|
|
3812
|
+
// framework first-touch cookie captured. Read once from the URL on mount.
|
|
3813
|
+
const shareAttribution = useMemo(
|
|
3814
|
+
() =>
|
|
3815
|
+
readPlanShareAttribution(
|
|
3816
|
+
typeof window === "undefined" ? "" : window.location.search,
|
|
3817
|
+
),
|
|
3818
|
+
[],
|
|
3819
|
+
);
|
|
3820
|
+
|
|
3821
|
+
// A logged-out visitor looking at a public plan/recap is the share funnel
|
|
3822
|
+
// audience. Their CTAs (comment, sign in) route through `openSignIn`.
|
|
3823
|
+
const isLoggedOutPublicPlanView =
|
|
3824
|
+
!sessionLoading &&
|
|
3825
|
+
!session &&
|
|
3826
|
+
!localPlanMode &&
|
|
3827
|
+
Boolean(selectedId) &&
|
|
3828
|
+
effectivePlanVisibility === "public";
|
|
3829
|
+
|
|
3830
|
+
// share_cta_click — fire alongside (never instead of) the real navigation.
|
|
3831
|
+
// `track` is non-throwing, but guard anyway so analytics can never break a
|
|
3832
|
+
// CTA. Only fires for the logged-out public-plan funnel audience.
|
|
3833
|
+
const fireShareCtaClick = useCallback(
|
|
3834
|
+
(cta: string) => {
|
|
3835
|
+
if (!isLoggedOutPublicPlanView) return;
|
|
3836
|
+
try {
|
|
3837
|
+
void track("share_cta_click", {
|
|
3838
|
+
surface: PLAN_SHARE_SURFACE,
|
|
3839
|
+
plan_id: selectedId ?? "",
|
|
3840
|
+
cta,
|
|
3841
|
+
ref: shareAttribution.ref,
|
|
3842
|
+
via: shareAttribution.via,
|
|
3843
|
+
});
|
|
3844
|
+
} catch {
|
|
3845
|
+
// Never let analytics break a CTA.
|
|
3846
|
+
}
|
|
3847
|
+
},
|
|
3848
|
+
[
|
|
3849
|
+
isLoggedOutPublicPlanView,
|
|
3850
|
+
selectedId,
|
|
3851
|
+
shareAttribution.ref,
|
|
3852
|
+
shareAttribution.via,
|
|
3853
|
+
],
|
|
3854
|
+
);
|
|
3855
|
+
|
|
3856
|
+
// share_view — fire once when a logged-out visitor views a public plan. The
|
|
3857
|
+
// ref guard prevents double-fire across re-renders / StrictMode double-invoke.
|
|
3858
|
+
const shareViewFiredRef = useRef(false);
|
|
3859
|
+
useEffect(() => {
|
|
3860
|
+
if (!isLoggedOutPublicPlanView) return;
|
|
3861
|
+
if (shareViewFiredRef.current) return;
|
|
3862
|
+
shareViewFiredRef.current = true;
|
|
3863
|
+
try {
|
|
3864
|
+
void track("share_view", {
|
|
3865
|
+
surface: PLAN_SHARE_SURFACE,
|
|
3866
|
+
plan_id: selectedId ?? "",
|
|
3867
|
+
ref: shareAttribution.ref,
|
|
3868
|
+
via: shareAttribution.via,
|
|
3869
|
+
});
|
|
3870
|
+
} catch {
|
|
3871
|
+
// Never let analytics break the page render.
|
|
3872
|
+
}
|
|
3873
|
+
}, [
|
|
3874
|
+
isLoggedOutPublicPlanView,
|
|
3875
|
+
selectedId,
|
|
3876
|
+
shareAttribution.ref,
|
|
3877
|
+
shareAttribution.via,
|
|
3793
3878
|
]);
|
|
3794
3879
|
|
|
3795
3880
|
useEffect(() => {
|
|
@@ -6227,11 +6312,14 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
|
|
|
6227
6312
|
{!session ? (
|
|
6228
6313
|
<GuestCommentCta
|
|
6229
6314
|
position={inlineCommentPosition}
|
|
6230
|
-
onSignIn={() =>
|
|
6315
|
+
onSignIn={() => {
|
|
6316
|
+
// share funnel: logged-out viewer of a public plan
|
|
6317
|
+
// clicking the "create account to comment" CTA.
|
|
6318
|
+
fireShareCtaClick("comment_signin");
|
|
6231
6319
|
openSignIn(
|
|
6232
6320
|
window.location.pathname + window.location.search,
|
|
6233
|
-
)
|
|
6234
|
-
}
|
|
6321
|
+
);
|
|
6322
|
+
}}
|
|
6235
6323
|
onCancel={closeInlineComment}
|
|
6236
6324
|
/>
|
|
6237
6325
|
) : (
|
|
@@ -6669,9 +6757,12 @@ function PlanShareControl({
|
|
|
6669
6757
|
effectivePublishedUrl && hostedPlanOnCurrentOrigin && effectiveHostedPlanId
|
|
6670
6758
|
? effectiveHostedPlanId
|
|
6671
6759
|
: planId;
|
|
6760
|
+
// Viral attribution: the owner is the one publishing/managing the share here,
|
|
6761
|
+
// so `via` is their non-PII session userId. `localShareUrl` is already tagged
|
|
6762
|
+
// upstream; tag the hosted/public URL too so both paths self-attribute.
|
|
6672
6763
|
const managedShareUrl =
|
|
6673
6764
|
effectivePublishedUrl && hostedPlanOnCurrentOrigin
|
|
6674
|
-
? effectivePublishedUrl
|
|
6765
|
+
? withPlanShareAttribution(effectivePublishedUrl, session?.userId ?? null)
|
|
6675
6766
|
: localShareUrl;
|
|
6676
6767
|
|
|
6677
6768
|
useEffect(() => {
|
|
@@ -6713,11 +6804,20 @@ function PlanShareControl({
|
|
|
6713
6804
|
hostedPlanId: result.hostedPlanId,
|
|
6714
6805
|
});
|
|
6715
6806
|
setAuthPrompt(null);
|
|
6716
|
-
|
|
6807
|
+
// Tag the freshly-minted public link so signups from it are
|
|
6808
|
+
// attributed. The publisher is the owner, so `via` is their userId.
|
|
6809
|
+
copyPublishedUrl(
|
|
6810
|
+
withPlanShareAttribution(
|
|
6811
|
+
result.hostedPlanUrl ?? result.url,
|
|
6812
|
+
session?.userId ?? null,
|
|
6813
|
+
) ??
|
|
6814
|
+
result.hostedPlanUrl ??
|
|
6815
|
+
result.url,
|
|
6816
|
+
);
|
|
6717
6817
|
},
|
|
6718
6818
|
},
|
|
6719
6819
|
);
|
|
6720
|
-
}, [copyPublishedUrl, planId, publishPlan]);
|
|
6820
|
+
}, [copyPublishedUrl, planId, publishPlan, session?.userId]);
|
|
6721
6821
|
|
|
6722
6822
|
// Logged-in / local-dev: manage shares for the plan in this app instance.
|
|
6723
6823
|
if (canManageLocalShares) {
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from "@agent-native/core/client";
|
|
23
23
|
import { IconSun, IconMoon } from "@tabler/icons-react";
|
|
24
24
|
import { useTheme } from "next-themes";
|
|
25
|
+
import changelog from "../CHANGELOG.md?raw";
|
|
25
26
|
import { Toaster } from "@/components/ui/sonner";
|
|
26
27
|
import { Layout as AppLayout } from "@/components/layout/Layout";
|
|
27
28
|
import { TAB_ID } from "@/lib/tab-id";
|
|
@@ -106,7 +107,12 @@ function AppContent() {
|
|
|
106
107
|
);
|
|
107
108
|
return (
|
|
108
109
|
<>
|
|
109
|
-
<CommandMenu
|
|
110
|
+
<CommandMenu
|
|
111
|
+
open={cmdkOpen}
|
|
112
|
+
onOpenChange={setCmdkOpen}
|
|
113
|
+
changelog={changelog}
|
|
114
|
+
changelogKey="plan"
|
|
115
|
+
>
|
|
110
116
|
<CommandMenu.Group heading="Actions">
|
|
111
117
|
<CommandMenu.Item onSelect={() => go("/")}>Ask Plan</CommandMenu.Item>
|
|
112
118
|
<CommandMenu.Item onSelect={() => go("/plans")}>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viral attribution contract for shared/public Plan links.
|
|
3
|
+
*
|
|
4
|
+
* Public plan/recap URLs self-attribute so the signup funnel can be measured
|
|
5
|
+
* even when `document.referrer` is empty (desktop app, Slack, native clients,
|
|
6
|
+
* etc.). The framework captures first-touch from these params into a cookie and
|
|
7
|
+
* enriches the `signup` event; Plan's job is to (a) tag the share/public URLs it
|
|
8
|
+
* mints and (b) emit funnel events when a logged-out visitor views a public plan
|
|
9
|
+
* and clicks a sign-up CTA.
|
|
10
|
+
*
|
|
11
|
+
* Contract strings are centralized here so the minting side (share popover /
|
|
12
|
+
* copy-link) and the measuring side (public plan view) cannot drift apart. The
|
|
13
|
+
* framework also derives `plan_share` from public plan paths (`/p/`, `/plan/`,
|
|
14
|
+
* `/plans/`, `/recaps/`, `/share-plan/`) as a fallback when the param is lost.
|
|
15
|
+
*
|
|
16
|
+
* Privacy: `via` must be a non-PII stable id (the owner's user id), never an
|
|
17
|
+
* email. Omit `via` rather than leak PII into a public URL or event.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Fixed referral source for plan shares. */
|
|
21
|
+
export const PLAN_SHARE_REF = "plan_share";
|
|
22
|
+
|
|
23
|
+
/** Surface tag included on plan share funnel events. */
|
|
24
|
+
export const PLAN_SHARE_SURFACE = "plan";
|
|
25
|
+
|
|
26
|
+
/** Query param names that carry attribution. */
|
|
27
|
+
export const REF_PARAM = "ref";
|
|
28
|
+
export const VIA_PARAM = "via";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Append `ref=plan_share` (and `via=<ownerId>` when a non-PII owner id is known)
|
|
32
|
+
* to an absolute share/public plan URL, preserving any existing query params.
|
|
33
|
+
* Returns the input unchanged when it isn't a parseable absolute URL.
|
|
34
|
+
*/
|
|
35
|
+
export function withPlanShareAttribution(
|
|
36
|
+
url: string | undefined,
|
|
37
|
+
ownerId?: string | null,
|
|
38
|
+
): string | undefined {
|
|
39
|
+
if (!url) return url;
|
|
40
|
+
try {
|
|
41
|
+
const parsed = new URL(url);
|
|
42
|
+
parsed.searchParams.set(REF_PARAM, PLAN_SHARE_REF);
|
|
43
|
+
const owner = (ownerId ?? "").trim();
|
|
44
|
+
if (owner) parsed.searchParams.set(VIA_PARAM, owner);
|
|
45
|
+
return parsed.toString();
|
|
46
|
+
} catch {
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type ShareAttribution = {
|
|
52
|
+
ref: string | undefined;
|
|
53
|
+
via: string | undefined;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Read `ref`/`via` from a query string (e.g. `window.location.search`). Falls
|
|
58
|
+
* back to `ref=plan_share` so downstream attribution stays meaningful even when
|
|
59
|
+
* the visitor arrived via a link that lost the param. Never throws.
|
|
60
|
+
*/
|
|
61
|
+
export function readPlanShareAttribution(search: string): ShareAttribution {
|
|
62
|
+
let ref: string | undefined;
|
|
63
|
+
let via: string | undefined;
|
|
64
|
+
try {
|
|
65
|
+
const params = new URLSearchParams(search ?? "");
|
|
66
|
+
ref = params.get(REF_PARAM) ?? undefined;
|
|
67
|
+
via = params.get(VIA_PARAM) ?? undefined;
|
|
68
|
+
} catch {
|
|
69
|
+
// Ignore malformed query strings — fall through to the default below.
|
|
70
|
+
}
|
|
71
|
+
return { ref: ref || PLAN_SHARE_REF, via: via || undefined };
|
|
72
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable user-facing changes to Agent-Native Slides are documented here. Open it any
|
|
4
|
+
time from the command menu (Cmd+K → "What's new").
|
|
5
|
+
|
|
6
|
+
## 2026-06-23
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- See what's new right inside Agent-Native Slides — a changelog now lives in the command menu (Cmd+K).
|
|
@@ -28,6 +28,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
|
|
28
28
|
import type { LinksFunction } from "react-router";
|
|
29
29
|
import stylesheet from "./global.css?url";
|
|
30
30
|
import { configureTracking } from "@agent-native/core/client";
|
|
31
|
+
import changelog from "../CHANGELOG.md?raw";
|
|
31
32
|
import { getThemeInitScript } from "@agent-native/core/client";
|
|
32
33
|
import { TAB_ID } from "@/lib/tab-id";
|
|
33
34
|
configureTracking({
|
|
@@ -162,7 +163,12 @@ function AppContent() {
|
|
|
162
163
|
|
|
163
164
|
return (
|
|
164
165
|
<>
|
|
165
|
-
<CommandMenu
|
|
166
|
+
<CommandMenu
|
|
167
|
+
open={cmdkOpen}
|
|
168
|
+
onOpenChange={setCmdkOpen}
|
|
169
|
+
changelog={changelog}
|
|
170
|
+
changelogKey="slides"
|
|
171
|
+
>
|
|
166
172
|
<CommandMenu.Group heading="Presentations">
|
|
167
173
|
<CommandMenu.Item onSelect={() => {}}>Search decks</CommandMenu.Item>
|
|
168
174
|
</CommandMenu.Group>
|