@raybase/guide 0.0.1 → 0.1.2

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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli.d.ts +8 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +9 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/guide-client.d.ts +48 -0
  7. package/dist/guide-client.d.ts.map +1 -0
  8. package/dist/guide-client.js +202 -0
  9. package/dist/guide-client.js.map +1 -0
  10. package/dist/guide-corpus.d.ts +64 -0
  11. package/dist/guide-corpus.d.ts.map +1 -0
  12. package/dist/guide-corpus.js +113 -0
  13. package/dist/guide-corpus.js.map +1 -0
  14. package/dist/guide-tables.d.ts +4 -0
  15. package/dist/guide-tables.d.ts.map +1 -0
  16. package/dist/guide-tables.js +17 -0
  17. package/dist/guide-tables.js.map +1 -0
  18. package/dist/guide.d.ts +164 -0
  19. package/dist/guide.d.ts.map +1 -0
  20. package/dist/guide.js +348 -0
  21. package/dist/guide.js.map +1 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +6 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/install.d.ts +28 -0
  27. package/dist/install.d.ts.map +1 -0
  28. package/dist/install.js +18 -0
  29. package/dist/install.js.map +1 -0
  30. package/dist/runtime.d.ts +19 -0
  31. package/dist/runtime.d.ts.map +1 -0
  32. package/dist/runtime.js +136 -0
  33. package/dist/runtime.js.map +1 -0
  34. package/package.json +49 -8
  35. package/templates/astro-emdash/content/guide/capability-map.md +17 -0
  36. package/templates/astro-emdash/src/components/guide-widget.tsx +41 -0
  37. package/templates/astro-emdash/src/guide/actions.ts +8 -0
  38. package/templates/astro-emdash/src/guide/config.ts +21 -0
  39. package/templates/astro-emdash/src/guide/corpus.gen.ts +4 -0
  40. package/templates/astro-emdash/src/guide/corpus.manifest.json +72 -0
  41. package/templates/astro-emdash/src/guide/corpus.ts +4 -0
  42. package/templates/astro-emdash/src/guide/resources.json +4 -0
  43. package/templates/react-router/app/components/guide-widget.tsx +29 -0
  44. package/templates/react-router/app/guide/actions.ts +3 -0
  45. package/templates/react-router/app/guide/config.ts +21 -0
  46. package/templates/react-router/app/guide/corpus.gen.ts +4 -0
  47. package/templates/react-router/app/guide/corpus.manifest.json +22 -0
  48. package/templates/react-router/app/guide/corpus.ts +4 -0
  49. package/templates/react-router/app/guide/resources.json +4 -0
  50. package/templates/react-router/content/guide/capability-map.md +13 -0
  51. package/templates/tanstack-start/content/guide/capability-map.md +17 -0
  52. package/templates/tanstack-start/src/components/guide-widget.tsx +41 -0
  53. package/templates/tanstack-start/src/guide/actions.ts +17 -0
  54. package/templates/tanstack-start/src/guide/config.ts +21 -0
  55. package/templates/tanstack-start/src/guide/corpus.gen.ts +4 -0
  56. package/templates/tanstack-start/src/guide/corpus.manifest.json +22 -0
  57. package/templates/tanstack-start/src/guide/corpus.ts +4 -0
  58. package/templates/tanstack-start/src/guide/resources.json +4 -0
  59. package/README.md +0 -3
@@ -0,0 +1,136 @@
1
+ import { corpusSearchSource, defineRaybaseModule, defineSearchIndex, mergeRaybaseSearch, raybaseSupportRequestsTableName } from "@raybase/core";
2
+ import { guideActions, guideAgent, guideAgentSurfaces, guideAudienceFromConfig, normalizeGuideConfig } from "./guide.js";
3
+ import { guideFailuresTableName, raybaseGuideSystemTables } from "./guide-tables.js";
4
+ const guideSearchIndexName = "guide";
5
+ export function guideModule(options = {}) {
6
+ return defineRaybaseModule({
7
+ id: "guide",
8
+ packageName: "@raybase/guide",
9
+ runtime: (ctx) => guideRuntime(ctx, options)
10
+ });
11
+ }
12
+ export function guideRuntime(ctx, options) {
13
+ const config = normalizeGuideConfig({ ...(options.config ?? {}), endpoint: options.endpoint ?? options.config?.endpoint, agent: { ...(options.config?.agent ?? {}), ...(options.agent ?? {}) } });
14
+ if (!config.enabled) {
15
+ return {
16
+ agentSurfaces: guideAgentSurfaces(config),
17
+ manifest: {
18
+ id: "guide",
19
+ packageName: "@raybase/guide",
20
+ guide: {
21
+ enabled: false,
22
+ agentName: config.agent.name,
23
+ mode: "implicit",
24
+ hasExplicitCorpus: false,
25
+ corpusDocumentCount: 0,
26
+ actionNames: [],
27
+ explicitActionNames: []
28
+ }
29
+ }
30
+ };
31
+ }
32
+ const search = searchWithGuideCorpus(options.corpus);
33
+ const actionSearch = mergeRaybaseSearch(ctx.search, search);
34
+ const actions = guideActions({
35
+ config,
36
+ schema: ctx.schema,
37
+ search: actionSearch,
38
+ retrieval: ctx.retrieval,
39
+ actions: options.actions
40
+ });
41
+ const explicitActionNames = (options.actions ?? []).map((action) => action.name);
42
+ return {
43
+ systemTables: raybaseGuideSystemTables,
44
+ agents: {
45
+ [config.agent.name]: guideAgent({
46
+ name: config.agent.name,
47
+ audience: guideAudienceFromConfig(config),
48
+ corpus: options.corpus,
49
+ actions,
50
+ title: config.agent.title,
51
+ model: config.agent.model,
52
+ maxOutputTokens: config.agent.maxOutputTokens,
53
+ limits: config.limits
54
+ })
55
+ },
56
+ search,
57
+ adminRoutes: [
58
+ {
59
+ method: "GET",
60
+ path: "/api/admin/guide/support-requests",
61
+ handle: async (routeCtx) => {
62
+ routeCtx.requireAdmin();
63
+ const url = new URL(routeCtx.request.url);
64
+ const limit = Math.min(Number(url.searchParams.get("limit") ?? 100), 500);
65
+ const rows = routeCtx.organizationId
66
+ ? await routeCtx.control.all(`SELECT * FROM "${raybaseSupportRequestsTableName}" WHERE "sourceKind" = 'guide' AND "organizationId" = ? ORDER BY "updatedAt" DESC LIMIT ?`, [routeCtx.organizationId, limit])
67
+ : await routeCtx.control.all(`SELECT * FROM "${raybaseSupportRequestsTableName}" WHERE "sourceKind" = 'guide' ORDER BY "updatedAt" DESC LIMIT ?`, [limit]);
68
+ return routeCtx.json({ supportRequests: rows, organizationId: routeCtx.organizationId ?? null });
69
+ }
70
+ },
71
+ {
72
+ method: "GET",
73
+ path: "/api/admin/guide/failures",
74
+ handle: async (routeCtx) => {
75
+ routeCtx.requireAdmin();
76
+ const url = new URL(routeCtx.request.url);
77
+ const limit = Math.min(Number(url.searchParams.get("limit") ?? 100), 500);
78
+ const rows = routeCtx.organizationId
79
+ ? await routeCtx.control.all(`SELECT * FROM "${guideFailuresTableName}" WHERE "organizationId" = ? ORDER BY "createdAt" DESC LIMIT ?`, [routeCtx.organizationId, limit])
80
+ : await routeCtx.control.all(`SELECT * FROM "${guideFailuresTableName}" ORDER BY "createdAt" DESC LIMIT ?`, [limit]);
81
+ return routeCtx.json({ failures: rows, organizationId: routeCtx.organizationId ?? null });
82
+ }
83
+ }
84
+ ],
85
+ agentSurfaces: guideAgentSurfaces(config),
86
+ manifest: {
87
+ id: "guide",
88
+ packageName: "@raybase/guide",
89
+ guide: {
90
+ enabled: true,
91
+ agentName: config.agent.name,
92
+ mode: options.mode ?? (explicitActionNames.length ? "actions" : "implicit"),
93
+ hasExplicitCorpus: options.corpus !== undefined,
94
+ corpusDocumentCount: options.corpus?.length ?? 0,
95
+ actionNames: actions.map((action) => action.name),
96
+ explicitActionNames
97
+ }
98
+ }
99
+ };
100
+ }
101
+ function searchWithGuideCorpus(corpus) {
102
+ if (!corpus?.length)
103
+ return undefined;
104
+ return {
105
+ indexes: {
106
+ [guideSearchIndexName]: defineSearchIndex({
107
+ name: guideSearchIndexName,
108
+ title: "App help",
109
+ description: "Docs and app help knowledge",
110
+ sources: [
111
+ corpusSearchSource("guide", {
112
+ title: "App help",
113
+ documents: () => guideCorpusSearchDocuments(corpus)
114
+ })
115
+ ]
116
+ })
117
+ }
118
+ };
119
+ }
120
+ function guideCorpusSearchDocuments(corpus) {
121
+ return corpus.map((document) => ({
122
+ id: document.id,
123
+ title: document.title,
124
+ body: document.text,
125
+ url: document.url ?? null,
126
+ version: document.updatedAt ?? null,
127
+ public: document.public === true,
128
+ metadata: {
129
+ ...(document.metadata ?? {}),
130
+ guideContext: document.guideContext,
131
+ source: document.source,
132
+ routePatterns: document.routePatterns ?? []
133
+ }
134
+ }));
135
+ }
136
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,16 +1,57 @@
1
1
  {
2
2
  "name": "@raybase/guide",
3
- "version": "0.0.1",
4
- "description": "Reserved for Raybase. Nothing is released under this name yet.",
5
- "license": "UNLICENSED",
3
+ "version": "0.1.2",
4
+ "description": "First-party Raybase Guide module for end-user app and docs assistance.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./client": {
15
+ "types": "./dist/guide-client.d.ts",
16
+ "default": "./dist/guide-client.js"
17
+ },
18
+ "./corpus": {
19
+ "types": "./dist/guide-corpus.d.ts",
20
+ "default": "./dist/guide-corpus.js"
21
+ },
22
+ "./install": {
23
+ "types": "./dist/install.d.ts",
24
+ "default": "./dist/install.js"
25
+ },
26
+ "./cli": {
27
+ "types": "./dist/cli.d.ts",
28
+ "default": "./dist/cli.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "templates"
34
+ ],
35
+ "peerDependencies": {
36
+ "zod": "^4.4.3",
37
+ "@raybase/core": "0.3.3"
38
+ },
39
+ "devDependencies": {
40
+ "@cloudflare/workers-types": "^4.20260609.0",
41
+ "typescript": "^5.8.3",
42
+ "zod": "^4.4.3",
43
+ "@raybase/core": "0.3.3"
44
+ },
6
45
  "repository": {
7
46
  "type": "git",
8
- "url": "git+https://github.com/raybasedev/raybase.git"
47
+ "url": "git+https://github.com/raybasedev/raybase.git",
48
+ "directory": "packages/guide"
9
49
  },
10
50
  "publishConfig": {
11
51
  "access": "public"
12
52
  },
13
- "files": [
14
- "README.md"
15
- ]
16
- }
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.json",
55
+ "check": "tsc -p tsconfig.json --noEmit"
56
+ }
57
+ }
@@ -0,0 +1,17 @@
1
+ ---
2
+ title: What Guide can do in this app
3
+ guideContext: app-capability-map
4
+ public: false
5
+ ---
6
+
7
+ Guide should answer from the checked-in app docs, help knowledge, and explicit Agent actions registered by the app.
8
+
9
+ It can explain where to go, how common site editing workflows work, what the current user is allowed to do, and which tasks it can help perform.
10
+
11
+ For the Astro/EmDash starter, Guide should help editors open the CMS, find pages, edit reusable sections, preview changes, publish safely, connect approved assistants, and know when to ask the project maintainer for a new page section or layout.
12
+
13
+ Guide should not claim it can publish, delete, or restructure content unless the app registers an explicit action for that task.
14
+
15
+ When the app registers Agent actions, Guide may use those actions only after the user clearly asks and the action policy allows it. If no action is registered for a task, it can explain the workflow but should not claim it can perform the task.
16
+
17
+ Guide should not expose raw tool names, internal errors, JSON, SQL, source-code details, platform settings, or implementation jargon. If context is missing or a tool fails, it should respond plainly, offer a useful next step, and ask one clarifying question only when needed.
@@ -0,0 +1,41 @@
1
+ import { useRouter } from "@tanstack/react-router";
2
+ import { RaybaseAgentWidget } from "@raybase/agent-ui";
3
+ import { useEffect } from "react";
4
+ import { guideConfig } from "../guide/config";
5
+
6
+ export function GuideWidget() {
7
+ const router = useRouter();
8
+
9
+ useEffect(() => {
10
+ const refreshData = () => {
11
+ void router.invalidate();
12
+ };
13
+ window.addEventListener("raybase:data-changed", refreshData);
14
+ return () => window.removeEventListener("raybase:data-changed", refreshData);
15
+ }, [router]);
16
+
17
+ return (
18
+ <RaybaseAgentWidget
19
+ agentName={guideConfig.agent?.name ?? "guide"}
20
+ enabled={guideConfig.enabled ?? true}
21
+ isSurfaceEnabled={isGuideSurfaceEnabled}
22
+ resolveSurface={resolveGuideSurface}
23
+ title={guideConfig.agent?.title ?? "Guide"}
24
+ />
25
+ );
26
+ }
27
+
28
+ type GuideSurface = "app" | "docs";
29
+
30
+ function resolveGuideSurface(route: string): GuideSurface {
31
+ return route.startsWith("/docs") ? "docs" : "app";
32
+ }
33
+
34
+ function isGuideSurfaceEnabled(surface: string): boolean {
35
+ if (!isGuideSurface(surface)) return false;
36
+ return guideConfig.surfaces?.[surface]?.enabled ?? surface === "app";
37
+ }
38
+
39
+ function isGuideSurface(surface: string): surface is GuideSurface {
40
+ return surface === "app" || surface === "docs";
41
+ }
@@ -0,0 +1,8 @@
1
+ import type { RaybaseAction } from "@raybase/core/actions";
2
+ import type { RaybaseEnv } from "@raybase/core/worker";
3
+ import { actions } from "../actions";
4
+
5
+ // Keep Guide on a narrow allow-list of app-declared actions.
6
+ export const guideActions = [
7
+ actions.contentSiteSnapshot
8
+ ] satisfies Array<RaybaseAction<any, any, RaybaseEnv>>;
@@ -0,0 +1,21 @@
1
+ import type { GuideConfig } from "@raybase/guide";
2
+
3
+ export const guideConfig = {
4
+ enabled: true,
5
+ surfaces: {
6
+ app: { enabled: true, audience: "signed-in" },
7
+ docs: { enabled: true, audience: "signed-in" }
8
+ },
9
+ agent: {
10
+ name: "guide",
11
+ title: "Guide"
12
+ },
13
+ limits: {
14
+ publicIpHourlyRequests: 20,
15
+ publicIpHourlyOutputTokens: 12000,
16
+ publicDailyRequests: 200,
17
+ publicDailyOutputTokens: 60000,
18
+ signedInDailyRequests: 50,
19
+ maxCorpusSnippets: 8
20
+ }
21
+ } satisfies GuideConfig;
@@ -0,0 +1,4 @@
1
+ import type { GuideCorpusDocument } from "@raybase/guide";
2
+ import manifest from "./corpus.manifest.json";
3
+
4
+ export const generatedGuideCorpus = manifest.documents as GuideCorpusDocument[];
@@ -0,0 +1,72 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "generatedAt": "2026-11-14T04:05:39.782Z",
4
+ "sources": [
5
+ {
6
+ "kind": "docs",
7
+ "path": "content/docs"
8
+ }
9
+ ],
10
+ "documents": [
11
+ {
12
+ "id": "docs:content/docs:getting-started.mdx",
13
+ "title": "Opening the CMS",
14
+ "source": "docs",
15
+ "text": "Sign in with the account your team gave you, then open the public site and choose CMS from the signed in menu. Start with Pages. Open an existing draft to review the editing pattern, or create a page when you need a new public URL. Use the page content field to arrange reusable sections. Each section owns its own copy, media, links, and display options. Preview before publishing. If a page needs a new reusable section or a layout change, note the goal clearly and ask the project maintainer to add the building block. Local time travel In local development, use the fixed dev chrome or POST /api/dev/time with \"now\":\"2030 08 12T09:00:00.000Z\" to move the application clock. GET /api/dev/time reports virtual and real time; \"reset\":true returns to wall time. Forward jumps start bounded catch up for Jobs, Agent schedules, wakes, and follow ups. Repeating schedules coalesce to one run, while one shot work drains without waiting for the HTTP response. Auth, leases, retries, tokens, provider calls, and diagnostics remain on real time. Moving backward or resetting does not rewrite future dated rows; reset and reseed when a QA scenario crosses that edge. Local tooling can restore the spine's base world with POST /api/dev/seed and \"reset\":true or apply one named variant with \"variant\":\"empty spine\" . Reset is destructive for spine app tables; use sequential calls to layer variants, and use restore after time travel leaves future dated rows. Content site demo data remains owned by site/ . GET /api/dev/manifest serves the same validated manifestVersion: 1 checkpoint written to .raybase/app.manifest.json at dev startup. Route sources use project relative POSIX paths. Restart raybase dev after changing routes or declarations. The endpoint is local only.",
16
+ "url": "/docs/getting-started",
17
+ "routePatterns": [
18
+ "/docs/getting-started",
19
+ "/docs/getting-started/*"
20
+ ],
21
+ "public": false,
22
+ "guideContext": null,
23
+ "updatedAt": "2026-11-14T04:05:26.116Z",
24
+ "hash": "sha256:6aec1b2e381585c532b62df227dd807aef7dbf91fe71d1f804a05e7793ce36ae"
25
+ },
26
+ {
27
+ "id": "docs:content/docs:index.mdx",
28
+ "title": "Editing the site",
29
+ "source": "docs",
30
+ "text": "The CMS is where signed in editors manage public site pages, drafts, media, and reusable page sections. Use the CMS link in the signed in site menu to open the editing workspace. If the link is not visible, ask the person who manages access to invite you or adjust your role. Most pages are built from a title, slug, metadata, and a sequence of reusable sections. Edit copy and media in the CMS, preview changes, then publish when the page is ready. Keep structural changes deliberate. If you need a new section type, navigation pattern, layout, or data backed block, ask the project maintainer to add it safely.",
31
+ "url": "/docs",
32
+ "routePatterns": [
33
+ "/docs",
34
+ "/docs/*"
35
+ ],
36
+ "public": false,
37
+ "guideContext": null,
38
+ "updatedAt": "2026-11-14T04:05:26.115Z",
39
+ "hash": "sha256:cee1dfcd47c0cc800581e7557c206d725f783ebcab122825455ada421faf13b4"
40
+ },
41
+ {
42
+ "id": "docs:content/docs:mcp.mdx",
43
+ "title": "Connecting an assistant",
44
+ "source": "docs",
45
+ "text": "Some apps let signed in members connect an approved AI assistant through the app's /mcp endpoint. Only connect assistants you trust. The assistant should explain what it can read or change before you approve a task. If the connection fails, confirm you are signed in and ask the project maintainer whether assistant access is enabled for your role.",
46
+ "url": "/docs/mcp",
47
+ "routePatterns": [
48
+ "/docs/mcp",
49
+ "/docs/mcp/*"
50
+ ],
51
+ "public": false,
52
+ "guideContext": null,
53
+ "updatedAt": "2026-11-14T04:05:26.116Z",
54
+ "hash": "sha256:9b7a64f4ce851af9f6664b4de67c6d92c4770228e76f06b3916f050d4b2f6467"
55
+ },
56
+ {
57
+ "id": "docs:content/docs:site-templates.mdx",
58
+ "title": "Reusable sections",
59
+ "source": "docs",
60
+ "text": "Templates are reusable Liquid templates for the public content site. Use them when a template fits the page section, layout, or page starter you need and the result should stay editable in the CMS. Discovery works from any directory: Installed templates are staged under site/seed/templates/ / : template.json is the draft Galley template payload. sample content.json carries registry sample data for review. page starters are Liquid templates that compose their sections with % render % tags; they also stage a page seed under site/seed/pages/ .json that points the page's design field at the starter. optional behavior sidecars are copied beside the staged payload when a template declares one. provenance.json records source URLs, generated hashes, dependencies, bindings, and install choices. Packs that read an EmDash collection through galley.dataSources use their manifest default collection when one is declared. Override or provide a required collection with bind : Theme manifests group a family's voice and vocabulary: palettes, sections, and page starter choices. A theme install stages the required dependencies plus the choices you select: palette is required when a theme lists more than one palette. page stages an EmDash page from a theme page starter key or exact template id. Use all optional only when you intentionally want every optional dependency staged. The site's structure is a shell: a layout with its welded nav and footer, selected by the site plan's capacity needs rather than by theme membership. raybase templates shell match nav items 5 footer links 12 theme raybase/lumen studio filters shells that fit and ranks them by voice fit. For one page sites, add anchor to filter to anchor tuned brand bar shells ( nav items 0 is valid — the logo block still renders at zero links). Then stage the chosen shell: activate stages an ephemeral activation.json work order beside the selected layout; during apply, selected templates are published, the active Galley layout pointer (and palette) is updated in the app database, and the work order is deleted. With the Astro/EmDash dev server running, apply staged templates: Without activate , templates are installed as draft templates. Structural pages point their design field at a page starter template; prose pages keep Portable Text in pages.content , where inline galley.block or galley.shared embeds are still supported. With shell add activate , templates:apply publishes the selected shell and section templates, upserts staged page seeds, and activates the layout for public rendering. Review staged JSON before apply and commit .raybase/templates.json , site/seed/templates/ , and site/seed/pages/ . The visual editor edits copy, fields, rich text, and Portable Text content. Page structure lives in Liquid: page starters compose sections with % render % tags, and structural changes remain agent/code work in Galley templates, resolved by installation (bare template ids, no per reference version pins).",
61
+ "url": "/docs/site-templates",
62
+ "routePatterns": [
63
+ "/docs/site-templates",
64
+ "/docs/site-templates/*"
65
+ ],
66
+ "public": false,
67
+ "guideContext": null,
68
+ "updatedAt": "2026-11-14T04:05:26.116Z",
69
+ "hash": "sha256:9799eff846de2718833130cbdeda6309a584705c1a536fbe95647c7596fef05f"
70
+ }
71
+ ]
72
+ }
@@ -0,0 +1,4 @@
1
+ import type { GuideCorpusDocument } from "@raybase/guide";
2
+ import { generatedGuideCorpus } from "./corpus.gen";
3
+
4
+ export const guideCorpus = generatedGuideCorpus satisfies GuideCorpusDocument[];
@@ -0,0 +1,4 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "resources": []
4
+ }
@@ -0,0 +1,29 @@
1
+ import { RaybaseAgentWidget } from "@raybase/agent-ui";
2
+ import { guideConfig } from "../guide/config";
3
+
4
+ export function GuideWidget() {
5
+ return (
6
+ <RaybaseAgentWidget
7
+ agentName={guideConfig.agent?.name ?? "guide"}
8
+ enabled={guideConfig.enabled ?? true}
9
+ isSurfaceEnabled={isGuideSurfaceEnabled}
10
+ resolveSurface={resolveGuideSurface}
11
+ title={guideConfig.agent?.title ?? "Guide"}
12
+ />
13
+ );
14
+ }
15
+
16
+ type GuideSurface = "app" | "docs";
17
+
18
+ function resolveGuideSurface(route: string): GuideSurface {
19
+ return route.startsWith("/docs") ? "docs" : "app";
20
+ }
21
+
22
+ function isGuideSurfaceEnabled(surface: string): boolean {
23
+ if (!isGuideSurface(surface)) return false;
24
+ return guideConfig.surfaces?.[surface]?.enabled ?? surface === "app";
25
+ }
26
+
27
+ function isGuideSurface(surface: string): surface is GuideSurface {
28
+ return surface === "app" || surface === "docs";
29
+ }
@@ -0,0 +1,3 @@
1
+ import type { RaybaseAction } from "@raybase/core/actions";
2
+
3
+ export const guideActions: RaybaseAction[] = [];
@@ -0,0 +1,21 @@
1
+ import type { GuideConfig } from "@raybase/guide";
2
+
3
+ export const guideConfig = {
4
+ enabled: true,
5
+ surfaces: {
6
+ app: { enabled: true, audience: "signed-in" },
7
+ docs: { enabled: true, audience: "signed-in" }
8
+ },
9
+ agent: {
10
+ name: "guide",
11
+ title: "Guide"
12
+ },
13
+ limits: {
14
+ publicIpHourlyRequests: 20,
15
+ publicIpHourlyOutputTokens: 12000,
16
+ publicDailyRequests: 200,
17
+ publicDailyOutputTokens: 60000,
18
+ signedInDailyRequests: 50,
19
+ maxCorpusSnippets: 8
20
+ }
21
+ } satisfies GuideConfig;
@@ -0,0 +1,4 @@
1
+ import type { GuideCorpusDocument } from "@raybase/guide";
2
+ import manifest from "./corpus.manifest.json";
3
+
4
+ export const generatedGuideCorpus = manifest.documents as GuideCorpusDocument[];
@@ -0,0 +1,22 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "generatedAt": "2026-11-14T04:05:33.795Z",
4
+ "sources": [
5
+ {
6
+ "kind": "guide",
7
+ "path": "content/guide"
8
+ }
9
+ ],
10
+ "documents": [
11
+ {
12
+ "id": "faq:capability-map.md",
13
+ "title": "What Guide can do in this app",
14
+ "source": "faq",
15
+ "text": "Guide should answer from the checked in app docs, help knowledge, and explicit Agent actions registered by the app. It can explain what the app tracks, where to go, how common workflows work, what the current user is allowed to do, and which tasks it can help perform. When the app registers Agent actions, Guide may use those actions only after the user clearly asks and the action policy allows it. If no action is registered for a task, it can explain the workflow but should not claim it can perform the task. Guide should not expose raw tool names, internal errors, JSON, SQL, source code details, admin/operator capabilities, secrets, or implementation jargon. If context is missing or a tool fails, it should respond plainly, offer a useful next step, and ask one clarifying question only when needed.",
16
+ "public": false,
17
+ "guideContext": "app-capability-map",
18
+ "updatedAt": "2026-11-14T04:05:26.038Z",
19
+ "hash": "sha256:9744984def63323f0435b3386509a0ff7d6f6a9986d1f159a1d04d037351ee53"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,4 @@
1
+ import type { GuideCorpusDocument } from "@raybase/guide";
2
+ import { generatedGuideCorpus } from "./corpus.gen";
3
+
4
+ export const guideCorpus = generatedGuideCorpus satisfies GuideCorpusDocument[];
@@ -0,0 +1,4 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "resources": []
4
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ title: What Guide can do in this app
3
+ guideContext: app-capability-map
4
+ public: false
5
+ ---
6
+
7
+ Guide should answer from the checked-in app docs, help knowledge, and explicit Agent actions registered by the app.
8
+
9
+ It can explain what the app tracks, where to go, how common workflows work, what the current user is allowed to do, and which tasks it can help perform.
10
+
11
+ When the app registers Agent actions, Guide may use those actions only after the user clearly asks and the action policy allows it. If no action is registered for a task, it can explain the workflow but should not claim it can perform the task.
12
+
13
+ Guide should not expose raw tool names, internal errors, JSON, SQL, source-code details, admin/operator capabilities, secrets, or implementation jargon. If context is missing or a tool fails, it should respond plainly, offer a useful next step, and ask one clarifying question only when needed.
@@ -0,0 +1,17 @@
1
+ ---
2
+ title: What Guide can do in this app
3
+ guideContext: app-capability-map
4
+ public: false
5
+ ---
6
+
7
+ Guide should answer from the checked-in app docs, help knowledge, and explicit Agent actions registered by the app.
8
+
9
+ It can explain what the app tracks, where to go, how common workflows work, what the current user is allowed to do, and which tasks it can help perform.
10
+
11
+ In the Team Tasks starter, Guide can summarize visible projects and tasks, list visible projects and tasks, create projects, create tasks, update task fields, mark tasks done, archive tasks or projects, and list assignable users through narrow declared app actions that share the same policies and invariants as the UI workflow.
12
+
13
+ Guide should prefer archive over hard delete. It does not have hard-delete actions in its allow-list. If a user asks to permanently delete work, explain that deletion is handled from the app UI by someone with permission after the item is archived.
14
+
15
+ When the app registers Agent actions, Guide may use those actions only after the user clearly asks and the action policy allows it. If no action is registered for a task, it can explain the workflow but should not claim it can perform the task.
16
+
17
+ Guide should not expose raw tool names, internal errors, JSON, SQL, source-code details, admin/operator capabilities, or implementation jargon. If context is missing or a tool fails, it should respond plainly, offer a useful next step, and ask one clarifying question only when needed.
@@ -0,0 +1,41 @@
1
+ import { useRouter } from "@tanstack/react-router";
2
+ import { RaybaseAgentWidget } from "@raybase/agent-ui";
3
+ import { useEffect } from "react";
4
+ import { guideConfig } from "../guide/config";
5
+
6
+ export function GuideWidget() {
7
+ const router = useRouter();
8
+
9
+ useEffect(() => {
10
+ const refreshData = () => {
11
+ void router.invalidate();
12
+ };
13
+ window.addEventListener("raybase:data-changed", refreshData);
14
+ return () => window.removeEventListener("raybase:data-changed", refreshData);
15
+ }, [router]);
16
+
17
+ return (
18
+ <RaybaseAgentWidget
19
+ agentName={guideConfig.agent?.name ?? "guide"}
20
+ enabled={guideConfig.enabled ?? true}
21
+ isSurfaceEnabled={isGuideSurfaceEnabled}
22
+ resolveSurface={resolveGuideSurface}
23
+ title={guideConfig.agent?.title ?? "Guide"}
24
+ />
25
+ );
26
+ }
27
+
28
+ type GuideSurface = "app" | "docs";
29
+
30
+ function resolveGuideSurface(route: string): GuideSurface {
31
+ return route.startsWith("/docs") ? "docs" : "app";
32
+ }
33
+
34
+ function isGuideSurfaceEnabled(surface: string): boolean {
35
+ if (!isGuideSurface(surface)) return false;
36
+ return guideConfig.surfaces?.[surface]?.enabled ?? surface === "app";
37
+ }
38
+
39
+ function isGuideSurface(surface: string): surface is GuideSurface {
40
+ return surface === "app" || surface === "docs";
41
+ }
@@ -0,0 +1,17 @@
1
+ import type { RaybaseAction } from "@raybase/core/actions";
2
+ import type { RaybaseEnv } from "@raybase/core/worker";
3
+ import { actions } from "../actions";
4
+
5
+ // Keep Guide on a narrow allow-list of app-declared actions.
6
+ export const guideActions = [
7
+ actions.workspaceSnapshot,
8
+ actions.listVisibleProjects,
9
+ actions.listVisibleTodos,
10
+ actions.createProject,
11
+ actions.createTodo,
12
+ actions.updateTodo,
13
+ actions.markTodoDone,
14
+ actions.archiveTodo,
15
+ actions.archiveProject,
16
+ actions.listAssignableUsers
17
+ ] satisfies Array<RaybaseAction<any, any, RaybaseEnv>>;
@@ -0,0 +1,21 @@
1
+ import type { GuideConfig } from "@raybase/guide";
2
+
3
+ export const guideConfig = {
4
+ enabled: true,
5
+ surfaces: {
6
+ app: { enabled: true, audience: "signed-in" },
7
+ docs: { enabled: true, audience: "signed-in" }
8
+ },
9
+ agent: {
10
+ name: "guide",
11
+ title: "Guide"
12
+ },
13
+ limits: {
14
+ publicIpHourlyRequests: 20,
15
+ publicIpHourlyOutputTokens: 12000,
16
+ publicDailyRequests: 200,
17
+ publicDailyOutputTokens: 60000,
18
+ signedInDailyRequests: 50,
19
+ maxCorpusSnippets: 8
20
+ }
21
+ } satisfies GuideConfig;
@@ -0,0 +1,4 @@
1
+ import type { GuideCorpusDocument } from "@raybase/guide";
2
+ import manifest from "./corpus.manifest.json";
3
+
4
+ export const generatedGuideCorpus = manifest.documents as GuideCorpusDocument[];