onboarding-wizard.mjs
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd
feat(calendar): enforce agent context tiers in retrieval AP…
Human
minor
⚠ breaking
1 day ago
| 1 | /** |
| 2 | * Hub onboarding wizard: state + step definitions (hosted vs self-hosted). |
| 3 | * UI binding lives in hub.js; this module stays testable without a browser DOM. |
| 4 | */ |
| 5 | |
| 6 | export const ONBOARDING_LS_KEY = 'knowtation_onboarding_v1'; |
| 7 | |
| 8 | /** Repo docs on GitHub main (Hub is often opened without a local clone). */ |
| 9 | export const DOCS_BASE = 'https://github.com/aaronrene/knowtation/blob/main/docs'; |
| 10 | |
| 11 | export const AGENT_INTEGRATION_ANCHOR_PROPOSALS = `${DOCS_BASE}/AGENT-INTEGRATION.md#4-proposals-review-before-commit`; |
| 12 | |
| 13 | export const IMPORT_SOURCES_URL = `${DOCS_BASE}/IMPORT-SOURCES.md`; |
| 14 | |
| 15 | /** |
| 16 | * Copyable text: user pastes into ChatGPT / Claude / etc. to get export steps for their stack. |
| 17 | * Grounded in IMPORT-SOURCES.md (chatgpt-export, claude-export, openclaw). |
| 18 | */ |
| 19 | export const LLM_SELF_HELP_EXPORT_PROMPT = [ |
| 20 | 'I am importing chats and memory into Knowtation (Markdown vault notes with frontmatter).', |
| 21 | '', |
| 22 | 'Please give concise, accurate export instructions for my situation:', |
| 23 | '- OpenAI / ChatGPT: account data export (ZIP or folder with conversations.json) suitable for a `chatgpt-export` style import.', |
| 24 | '- Anthropic / Claude: privacy export (chats and/or memory) suitable for a `claude-export` style import.', |
| 25 | '- OpenClaw: any supported export path or files that map to Knowtation `openclaw` import.', |
| 26 | '- Hermes Agent: export from `~/.hermes/memories/` or `hermes memory export`; import via `markdown` or copy MEMORY.md / USER.md.', |
| 27 | '', |
| 28 | 'For each product I name, list the exact menu path (as of my stated app version if I add one), the file types I will get (ZIP, JSON, folder layout), and any size or rate limits I should watch for.', |
| 29 | '', |
| 30 | 'I will upload the result via Knowtation Hub Import or run `knowtation import <source-type> …` from the CLI after export.', |
| 31 | ].join('\n'); |
| 32 | |
| 33 | /** @typedef {'hosted'|'selfhosted'} HostingPath */ |
| 34 | /** @typedef {'in_progress'|'dismissed'|'completed'} OnboardingStatus */ |
| 35 | |
| 36 | /** |
| 37 | * @typedef {Object} OnboardingStateV1 |
| 38 | * @property {1} v |
| 39 | * @property {string} userKey |
| 40 | * @property {HostingPath} hostingPath |
| 41 | * @property {number} stepIndex |
| 42 | * @property {OnboardingStatus} status |
| 43 | * @property {number | null} [dismissedAt] |
| 44 | * @property {number | null} [completedAt] |
| 45 | */ |
| 46 | |
| 47 | /** |
| 48 | * @param {unknown} raw |
| 49 | * @returns {OnboardingStateV1 | null} |
| 50 | */ |
| 51 | export function parseOnboardingState(raw) { |
| 52 | if (raw == null || typeof raw !== 'string') return null; |
| 53 | try { |
| 54 | const o = JSON.parse(raw); |
| 55 | if (!o || o.v !== 1 || typeof o.userKey !== 'string') return null; |
| 56 | if (o.hostingPath !== 'hosted' && o.hostingPath !== 'selfhosted') return null; |
| 57 | const status = o.status; |
| 58 | if (status !== 'in_progress' && status !== 'dismissed' && status !== 'completed') return null; |
| 59 | const stepIndex = Math.max(0, Math.floor(Number(o.stepIndex) || 0)); |
| 60 | return { |
| 61 | v: 1, |
| 62 | userKey: o.userKey, |
| 63 | hostingPath: o.hostingPath, |
| 64 | stepIndex, |
| 65 | status, |
| 66 | dismissedAt: typeof o.dismissedAt === 'number' ? o.dismissedAt : null, |
| 67 | completedAt: typeof o.completedAt === 'number' ? o.completedAt : null, |
| 68 | }; |
| 69 | } catch { |
| 70 | return null; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | /** @param {OnboardingStateV1} s */ |
| 75 | export function serializeOnboardingState(s) { |
| 76 | return JSON.stringify(s); |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * @param {string} userKey |
| 81 | * @param {HostingPath} hostingPath |
| 82 | * @returns {OnboardingStateV1} |
| 83 | */ |
| 84 | export function createFreshState(userKey, hostingPath) { |
| 85 | return { |
| 86 | v: 1, |
| 87 | userKey, |
| 88 | hostingPath, |
| 89 | stepIndex: 0, |
| 90 | status: 'in_progress', |
| 91 | dismissedAt: null, |
| 92 | completedAt: null, |
| 93 | }; |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * @param {boolean} isHosted |
| 98 | * @returns {number} |
| 99 | */ |
| 100 | export function getStepCount(isHosted) { |
| 101 | return isHosted ? 9 : 5; |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Whether to open the wizard automatically after login/settings. |
| 106 | * @param {OnboardingStateV1 | null} state |
| 107 | * @param {string} currentUserKey |
| 108 | * @param {HostingPath} currentHostingPath |
| 109 | * @returns {boolean} |
| 110 | */ |
| 111 | export function shouldAutoOpenWizard(state, currentUserKey, currentHostingPath) { |
| 112 | if (!currentUserKey) return false; |
| 113 | if (!state) return true; |
| 114 | if (state.userKey !== currentUserKey) return true; |
| 115 | if (state.hostingPath !== currentHostingPath) return true; |
| 116 | if (state.status === 'dismissed' || state.status === 'completed') return false; |
| 117 | return state.status === 'in_progress'; |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * @param {boolean} isHosted |
| 122 | * @param {number} index |
| 123 | * @returns {{ id: string, title: string, bodyHtml: string } | null} |
| 124 | */ |
| 125 | export function getStepContent(isHosted, index) { |
| 126 | if (isHosted) { |
| 127 | const steps = [ |
| 128 | { |
| 129 | id: 'h0', |
| 130 | title: 'Your memory home', |
| 131 | bodyHtml: |
| 132 | '<p><strong>Knowtation Hub</strong> holds your team’s indexed notes — Markdown you own, fast search, and one simple rule for AI: <strong>suggested edits wait for your approval</strong> before they become real notes.</p>' + |
| 133 | '<details class="how-to-details">' + |
| 134 | '<summary>More detail — “token savings” (two layers, plain English)</summary>' + |
| 135 | '<div class="how-to-details-body">' + |
| 136 | '<p><strong>Vault & search:</strong> Assistants pull short snippets instead of giant paste-ins — that saves context in any tool.</p>' + |
| 137 | '<p><strong>Terminal chatter:</strong> Shrinking raw shell logs on your laptop is separate optional tooling; it is not what this hosted vault product runs for you.</p>' + |
| 138 | '<p class="onboarding-tip">Same framing as <a href="' + |
| 139 | DOCS_BASE + |
| 140 | '/TOKEN-SAVINGS.md" target="_blank" rel="noopener">Token savings (retrieval & cost discipline)</a>.</p>' + |
| 141 | '</div>' + |
| 142 | '</details>', |
| 143 | }, |
| 144 | { |
| 145 | id: 'h1', |
| 146 | title: 'What do you want to do first?', |
| 147 | bodyHtml: |
| 148 | '<p>For <strong>hosted</strong> Knowtation (what you signed into here), almost everyone starts one of two ways — pick one; you can do the other anytime.</p>' + |
| 149 | '<div class="onboarding-path-grid" role="group" aria-label="Hosted getting started">' + |
| 150 | '<div class="onboarding-path-card">' + |
| 151 | '<h3 class="onboarding-path-card-title">Bring in chats & files</h3>' + |
| 152 | '<p class="onboarding-path-card-body">Upload exports or files with <strong>Import</strong> (header). Use this when you already have a ChatGPT / Claude / OpenClaw export or documents on your computer.</p>' + |
| 153 | '</div>' + |
| 154 | '<div class="onboarding-path-card">' + |
| 155 | '<h3 class="onboarding-path-card-title">Connect your assistant</h3>' + |
| 156 | '<p class="onboarding-path-card-body">Open <strong>Settings → Integrations</strong> and paste the copied block into Cursor, Claude Desktop, or another MCP-capable tool so it can search your vault and queue suggested edits.</p>' + |
| 157 | '</div>' + |
| 158 | '</div>' + |
| 159 | '<details class="how-to-details">' + |
| 160 | '<summary>Self-hosted only — I run Knowtation on my own computer</summary>' + |
| 161 | '<div class="how-to-details-body">' + |
| 162 | '<p>If you cloned this repo and run the Hub locally, the <em>ideas</em> are the same (import vs connect tools), but you also manage disk paths, OAuth apps, and config files. Follow <strong>How to use → Setup → Self-hosted setup</strong> and the repo <a href="' + |
| 163 | DOCS_BASE + |
| 164 | '/TWO-PATHS-HOSTED-AND-SELF-HOSTED.md#quick-start-self-hosted" target="_blank" rel="noopener">Quick start (self-hosted)</a>.</p>' + |
| 165 | '</div>' + |
| 166 | '</details>' + |
| 167 | '<p class="onboarding-tip">Next: <strong>Integrations</strong>, imports by platform, then <strong>Suggested</strong> (where edits wait for approval).</p>', |
| 168 | }, |
| 169 | { |
| 170 | id: 'h2', |
| 171 | title: 'Integrations (MCP + API)', |
| 172 | bodyHtml: |
| 173 | '<p>While signed in, open <strong>Settings → Integrations → Hub API</strong>.</p>' + |
| 174 | '<p><strong>Copy Hub URL, token & vault</strong> — your private “key card” for tools outside the browser (paste into env vars or MCP config).</p>' + |
| 175 | '<p><strong>Copy MCP</strong> — a ready-made snippet for common clients.</p>' + |
| 176 | '<p><strong>Copy prime</strong> — a small <strong>non-secret</strong> JSON reminder (which Hub and vault). Not your password; use it with the key card after your tool connects.</p>' + |
| 177 | '<details class="how-to-details">' + |
| 178 | '<summary>Technical details (headers, env names, prime URI)</summary>' + |
| 179 | '<div class="how-to-details-body">' + |
| 180 | '<p>Requests use <code>Authorization: Bearer …</code> and <code>X-Vault-Id</code> on <code>POST …/mcp</code>, <code>/api/v1/search</code>, and related routes. The copy button names variables such as <code>KNOWTATION_HUB_URL</code>, <code>KNOWTATION_HUB_TOKEN</code>, and <code>KNOWTATION_HUB_VAULT_ID</code>.</p>' + |
| 181 | '<p><strong>Copy prime</strong> JSON points at MCP <code>readResource</code> URI <code>knowtation://hosted/prime</code> plus gateway base URL and vault id — <strong>no JWT inside</strong>. After connect, reading that resource can return session context and prompt names for your role.</p>' + |
| 182 | '</div>' + |
| 183 | '</details>' + |
| 184 | '<p class="onboarding-tip">Deep reference: <a href="' + |
| 185 | DOCS_BASE + |
| 186 | '/AGENT-INTEGRATION.md" target="_blank" rel="noopener">Agent integration</a> (CLI, MCP, Hub API).</p>', |
| 187 | }, |
| 188 | { |
| 189 | id: 'h-imports', |
| 190 | title: 'Imports by platform', |
| 191 | bodyHtml: |
| 192 | '<p>Use <strong>Import</strong> in the header to upload exports. Most people start with one of these:</p>' + |
| 193 | '<ul class="onboarding-import-cards" role="list">' + |
| 194 | '<li><strong>OpenAI / ChatGPT</strong> — account data export (ZIP or folder; often includes <code>conversations.json</code>).</li>' + |
| 195 | '<li><strong>Anthropic / Claude</strong> — privacy / data export (chats and/or memory).</li>' + |
| 196 | '<li><strong>OpenClaw</strong> — supported agent exports per our import matrix.</li>' + |
| 197 | '</ul>' + |
| 198 | '<details class="how-to-details">' + |
| 199 | '<summary>CLI & API source names</summary>' + |
| 200 | '<div class="how-to-details-body">' + |
| 201 | '<p>The Hub and CLI label these as <code>chatgpt-export</code>, <code>claude-export</code>, <code>openclaw</code>, and more. Full list and flags: <a href="' + |
| 202 | IMPORT_SOURCES_URL + |
| 203 | '" target="_blank" rel="noopener">Import sources</a>.</p>' + |
| 204 | '</div>' + |
| 205 | '</details>' + |
| 206 | '<p class="onboarding-tip">Full matrix: <a href="' + |
| 207 | IMPORT_SOURCES_URL + |
| 208 | '" target="_blank" rel="noopener">IMPORT-SOURCES.md</a>.</p>' + |
| 209 | '<p><strong>LLM self-help:</strong> paste the text below into any assistant and name your product; ask it for exact export menu paths and file shapes.</p>' + |
| 210 | '<textarea class="onboarding-llm-prompt" data-onboarding-llm-prompt readonly rows="9" aria-label="Copyable prompt for export instructions"></textarea>' + |
| 211 | '<p class="onboarding-copy-row"><button type="button" class="btn-secondary onboarding-copy-llm-btn">Copy export helper prompt</button></p>', |
| 212 | }, |
| 213 | { |
| 214 | id: 'h4', |
| 215 | title: 'Proposals and the Suggested queue', |
| 216 | bodyHtml: |
| 217 | '<p><strong>Agents suggest; humans approve.</strong> Proposed edits stay out of the canonical vault until someone approves them — same speed as direct writes, with a paper trail and roles.</p>' + |
| 218 | '<p>In the Hub, open the <strong>Suggested</strong> tab (next to Notes and Activity) to review proposals. <strong>Activity</strong> is the timeline; <strong>Discarded</strong> keeps rejected items for reference. You can also start a proposal from a note (<strong>Propose change</strong>) or <strong>New proposal</strong>.</p>' + |
| 219 | '<p class="onboarding-tip">Contract and API details: <a href="' + |
| 220 | AGENT_INTEGRATION_ANCHOR_PROPOSALS + |
| 221 | '" target="_blank" rel="noopener">Agent integration — §4 Proposals</a>.</p>', |
| 222 | }, |
| 223 | { |
| 224 | id: 'h5', |
| 225 | title: 'Your notes live here', |
| 226 | bodyHtml: |
| 227 | '<p>After you sign in, your vault is <strong>your private space</strong> in Knowtation. The list may look empty until you add something — that is normal.</p>' + |
| 228 | '<p class="onboarding-tip">On hosted Knowtation, a <strong>project</strong> is a label on notes to group them (not a disk folder path).</p>', |
| 229 | }, |
| 230 | { |
| 231 | id: 'h6', |
| 232 | title: 'Add your first note or file', |
| 233 | bodyHtml: |
| 234 | '<p>Use <strong>+ New note</strong> to write something small (for example a shopping list or a link you want to remember).</p>' + |
| 235 | '<p>Or use <strong>Import</strong> to bring in a file from your computer.</p>' + |
| 236 | '<p class="onboarding-tip">Want more detail? Open <strong>How to use</strong> → Knowledge & agents anytime.</p>', |
| 237 | }, |
| 238 | { |
| 239 | id: 'h7', |
| 240 | title: 'Keep a copy (optional)', |
| 241 | bodyHtml: |
| 242 | '<p>Your notes are already stored on Knowtation. If you also want a <strong>copy on GitHub</strong> (your account, your repo), use <strong>Settings → Backup</strong> and connect GitHub when you are ready.</p>' + |
| 243 | '<p class="onboarding-tip">You can skip this until later.</p>', |
| 244 | }, |
| 245 | { |
| 246 | id: 'h8', |
| 247 | title: 'Power tools for agents', |
| 248 | bodyHtml: |
| 249 | '<p>On hosted Knowtation, MCP exposes vault operations your role allows — search and read notes, propose changes (with humans approving in <strong>Suggested</strong>), imports, indexing, memory tools where enabled, and more.</p>' + |
| 250 | '<p><strong>MCP prompts</strong> are composition templates registered for your session. After you connect, your client can list them (e.g. via <code>prompts/list</code>) — that list is authoritative for this deployment.</p>' + |
| 251 | '<details class="how-to-details">' + |
| 252 | '<summary>Technical inventory (prompt names & prime)</summary>' + |
| 253 | '<div class="how-to-details-body">' + |
| 254 | '<p>Example prompt names you may see include <strong>daily-brief</strong>, <strong>search-and-synthesize</strong>, <strong>project-summary</strong>, <strong>temporal-summary</strong>, <strong>content-plan</strong>, <strong>meeting-notes</strong>, <strong>knowledge-gap</strong>, <strong>causal-chain</strong>, <strong>extract-entities</strong>, <strong>write-from-capture</strong> (editor+), <strong>memory-context</strong>, <strong>memory-informed-search</strong>, <strong>resume-session</strong> — plus tools such as <strong>search</strong>, <strong>get_note</strong>, <strong>list_notes</strong>, <strong>propose</strong>, <strong>import</strong>, <strong>index</strong>. <strong>Copy prime</strong> JSON references <code>knowtation://hosted/prime</code> and echoes allowed prompt names for your current session.</p>' + |
| 255 | '</div>' + |
| 256 | '</details>' + |
| 257 | '<p class="onboarding-tip">One page for tools, REST, CLI, and proposal semantics: <a href="' + |
| 258 | DOCS_BASE + |
| 259 | '/AGENT-INTEGRATION.md" target="_blank" rel="noopener">AGENT-INTEGRATION.md</a>.</p>' + |
| 260 | '<p>That is the whole hosted loop: notes and imports in the vault, integrations for assistants, proposals for safe writes, optional GitHub backup.</p>', |
| 261 | }, |
| 262 | ]; |
| 263 | return steps[index] || null; |
| 264 | } |
| 265 | const steps = [ |
| 266 | { |
| 267 | id: 's1', |
| 268 | title: 'Where your notes live', |
| 269 | bodyHtml: |
| 270 | '<p>In this <strong>browser Hub</strong>, your note list, Import, and search work without you setting a folder path — that is managed for you.</p>' + |
| 271 | '<details class="how-to-details">' + |
| 272 | '<summary>Self-hosted only — folder on your machine</summary>' + |
| 273 | '<div class="how-to-details-body">' + |
| 274 | '<p>If you run Knowtation from a clone on your computer, notes live in a real <strong>folder</strong>. Match that path in <code>config/local.yaml</code>, <code>KNOWTATION_VAULT_PATH</code> in <code>.env</code>, and <strong>Settings → Backup</strong> so the CLI and Hub agree.</p>' + |
| 275 | '<p class="onboarding-tip"><a href="' + |
| 276 | DOCS_BASE + |
| 277 | '/TWO-PATHS-HOSTED-AND-SELF-HOSTED.md#quick-start-self-hosted" target="_blank" rel="noopener">Quick start (self-hosted)</a> has the exact commands.</p>' + |
| 278 | '</div>' + |
| 279 | '</details>', |
| 280 | }, |
| 281 | { |
| 282 | id: 's2', |
| 283 | title: 'Search and indexing', |
| 284 | bodyHtml: |
| 285 | '<p><strong>Browsing and listing notes</strong> works right away. After you import a lot or change search-related settings, use <strong>Re-index</strong> in the toolbar so “meaning” search stays in sync.</p>' + |
| 286 | '<details class="how-to-details">' + |
| 287 | '<summary>Self-hosted only — CLI from the repo</summary>' + |
| 288 | '<div class="how-to-details-body">' + |
| 289 | '<p>From the project root run <code>npm run index</code>, or use <strong>Re-index</strong> here after embedding or vector config changes. Plain-language steps: <strong>How to use → Setup</strong> (embeddings / sqlite-vec).</p>' + |
| 290 | '</div>' + |
| 291 | '</details>' + |
| 292 | '<p class="onboarding-tip">Open <strong>How to use → Setup</strong> anytime for the full checklist.</p>', |
| 293 | }, |
| 294 | { |
| 295 | id: 's3', |
| 296 | title: 'Signing in', |
| 297 | bodyHtml: |
| 298 | '<p>You sign in with <strong>Google or GitHub</strong> so this Hub knows which account and vault are yours.</p>' + |
| 299 | '<details class="how-to-details">' + |
| 300 | '<summary>Self-hosted only — your own OAuth app (.env)</summary>' + |
| 301 | '<div class="how-to-details-body">' + |
| 302 | '<p>Operators register a Google/GitHub OAuth app and put client ID and secret in <code>.env</code>, then restart the Hub. If you see <strong>OAuth is not configured</strong>, follow <strong>How to use → Setup → Step 3</strong> or ask whoever runs your server.</p>' + |
| 303 | '</div>' + |
| 304 | '</details>', |
| 305 | }, |
| 306 | { |
| 307 | id: 's4', |
| 308 | title: 'Import, agents, and backup', |
| 309 | bodyHtml: |
| 310 | '<p><strong>Import</strong> brings files from other tools. <strong>Settings → Integrations</strong> shows how to connect agents (MCP). <strong>Settings → Backup</strong> walks through GitHub backup when you want version history off-machine.</p>' + |
| 311 | '<p><strong>Proposals:</strong> agents use the same APIs as humans; review queued changes under the Hub <strong>Suggested</strong> tab before they merge into the vault. See <a href="' + |
| 312 | AGENT_INTEGRATION_ANCHOR_PROPOSALS + |
| 313 | '" target="_blank" rel="noopener">Agent integration — §4 Proposals</a>.</p>' + |
| 314 | '<p class="onboarding-tip">The seven steps under <strong>How to use → Setup</strong> stay the full reference — this wizard is the short path.</p>', |
| 315 | }, |
| 316 | { |
| 317 | id: 's5', |
| 318 | title: 'You are set', |
| 319 | bodyHtml: |
| 320 | '<p>Use the tree and search to browse notes, <strong>+ New note</strong> to capture, and <strong>Settings</strong> anytime for backup and integrations.</p>' + |
| 321 | '<p class="onboarding-tip">Come back to <strong>How to use</strong> whenever you need deeper explanations.</p>', |
| 322 | }, |
| 323 | ]; |
| 324 | return steps[index] || null; |
| 325 | } |
| 326 | |
| 327 | /** |
| 328 | * Secondary actions for wizard footer (handled in hub.js). |
| 329 | * @typedef {{ id: string, label: string }} OnboardingAction |
| 330 | * @param {boolean} isHosted |
| 331 | * @param {number} index |
| 332 | * @returns {OnboardingAction[]} |
| 333 | */ |
| 334 | export function getStepSecondaryActions(isHosted, index) { |
| 335 | if (isHosted) { |
| 336 | if (index === 0) return [{ id: 'openWhyTokenDoc', label: 'Why Knowtation (tokens)' }]; |
| 337 | if (index === 1) return [{ id: 'openImportModal', label: 'Open Import' }, { id: 'openSettingsIntegrations', label: 'Settings → Integrations' }]; |
| 338 | if (index === 2) return [{ id: 'openSettingsIntegrations', label: 'Open Settings → Integrations' }]; |
| 339 | if (index === 3) return [{ id: 'openImportModal', label: 'Open Import' }, { id: 'openImportSourcesDoc', label: 'Import sources (docs)' }]; |
| 340 | if (index === 4) return [{ id: 'focusSuggestedTab', label: 'Open Suggested tab' }, { id: 'openAgentDocProposals', label: 'Read §4 Proposals (docs)' }]; |
| 341 | if (index === 5) return [{ id: 'projectsHelp', label: 'How projects work' }]; |
| 342 | if (index === 6) return [{ id: 'howToKnowledge', label: 'How to use: Knowledge & agents' }]; |
| 343 | if (index === 7) return [{ id: 'openSettingsBackup', label: 'Open Settings → Backup' }]; |
| 344 | if (index === 8) return [{ id: 'openAgentIntegrationDoc', label: 'Open AGENT-INTEGRATION.md' }]; |
| 345 | return []; |
| 346 | } |
| 347 | if (index === 0) return [{ id: 'openSettingsBackup', label: 'Open Settings → Backup' }]; |
| 348 | if (index === 1) return [{ id: 'howToSetup4', label: 'How to use: Setup (search)' }]; |
| 349 | if (index === 2) return [{ id: 'howToSetup3', label: 'How to use: Setup (sign in)' }]; |
| 350 | if (index === 3) { |
| 351 | return [ |
| 352 | { id: 'openSettingsIntegrations', label: 'Settings → Integrations' }, |
| 353 | { id: 'openSettingsBackup', label: 'Settings → Backup' }, |
| 354 | { id: 'openAgentDocProposals', label: '§4 Proposals (docs)' }, |
| 355 | ]; |
| 356 | } |
| 357 | return []; |
| 358 | } |
File History
2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd
feat(calendar): enforce agent context tiers in retrieval AP…
Human
minor
⚠
1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6
docs: accept Calendar Events v0 spec with Phase 0 security …
Human
1 day ago