[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71DW4WFXY025CHNBWJ0Z7C2":3,"skill-same:01M71DW4WFXY025CHNBWJ0Z7C2":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":14,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":48,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M71DW4WFXY025CHNBWJ0Z7C2","forge-in-chrome",null,"Derive bullets and perspectives in Forge by driving the Forge tab in Chrome through `window.forge`. Use when asked to derive bullets from a source, write a perspective for a bullet, or otherwise read or write Forge data while the browser-first (wasm) UI is open.","resu-mx\u002Fforge","resu-mx","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F311147169?v=4","01M71DW089R9565MKZKKG6DFW0","resu.mx","01M71DW08ZXS6DA0JAZFD2SNJ2",0,"MIT","https:\u002F\u002Fgithub.com\u002Fresu-mx\u002Fforge\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fforge-in-chrome\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"forge","chrome","forge in chrome","tab","ui","source","perspective","data","write","read","wasm","first","window","perspectives","browser","when","use","open","write forge","for","2026-11-10 10:12:30",false,"---\nname: forge-in-chrome\ndescription: Derive bullets and perspectives in Forge by driving the Forge tab in Chrome through `window.forge`. Use when asked to derive bullets from a source, write a perspective for a bullet, or otherwise read or write Forge data while the browser-first (wasm) UI is open.\n---\n\n# Forge in Chrome\n\nIn the browser-first build the database lives in the person's Chrome profile, inside the Forge\ntab. There is no server to call. You reach the data through `window.forge`, the same\n`ForgeClient` the UI uses, by running JavaScript in that tab.\n\nYou write the text; the person approves it. Nothing you derive is final until they approve it\nin the UI.\n\n## Before you start\n\n- Needs Chrome with the Claude in Chrome extension allowed on the Forge origin. Forge's data is\n  per browser: it lives in Chrome, not in another browser.\n- Load the Chrome tools in one `ToolSearch` call (`tabs_context_mcp`, `javascript_tool`,\n  `navigate`, `get_page_text`), call `tabs_context_mcp`, and find the tab whose URL is the Forge\n  app. Open it with `tabs_create_mcp` only if none exists.\n- The UI must be in wasm mode (the default; `VITE_FORGE_MODE=api` turns it off). Check:\n  `typeof window.forge?.derivations?.prepare` should be `'object'`\u002F`'function'` — not `undefined`.\n- Only one tab owns the database. If calls return `STORAGE_BUSY`, another Forge tab owns it:\n  switch to that tab, or ask the person to close the other one.\n\n## Calling the API\n\nEvery call returns `{ ok: true, data }` or `{ ok: false, error }`. Check `ok`. Always return a\nsmall value from `javascript_tool` (ids and a few fields), never whole lists:\n\n```js\nconst r = await window.forge.sources.list({ limit: 20 })\nr.ok ? r.data.map(s => ({ id: s.id, title: s.title })) : r.error\n```\n\nKeep results small: pick the fields you need and cap list sizes.\n\n## Source → bullets\n\n1. Find the source (`forge.sources.list`, or `forge.sources.get(id)`).\n2. Prepare:\n   ```js\n   const p = await window.forge.derivations.prepare({ entity_type: 'source', entity_id: SOURCE_ID, client_id: 'claude-in-chrome' })\n   p.ok ? { id: p.data.derivation_id, prompt: p.data.prompt, expires: p.data.expires_at } : p.error\n   ```\n3. **You are the model.** Read `prompt` and write the bullets it asks for, following its\n   instructions exactly. Do not call another model. Do not invent facts that are not in the source.\n4. Commit within the expiry (**2 minutes** from `prepare`; write the text promptly). Each bullet is an object:\n   ```js\n   const c = await window.forge.derivations.commitBullets(DERIVATION_ID, {\n     bullets: [{ content: '…', technologies: ['Rust'], metrics: null }],\n   })\n   c.ok ? c.data.map(b => ({ id: b.id, status: b.status })) : c.error\n   ```\n   `metrics` is a string when the source states a number, otherwise `null`. A validation error\n   comes back in `error`; fix the text and commit again (the derivation stays open until it expires).\n\n## Bullet → perspective\n\n1. Pick a bullet that is **approved** (the API rejects any other), and an archetype and domain by name\n   (`forge.archetypes.list()`, `forge.domains.list()`), plus a framing:\n   `accomplishment`, `responsibility` or `context`.\n2. Prepare with `entity_type: 'bullet'`, `entity_id`, and\n   `params: { archetype, domain, framing }`.\n3. Write the perspective from the returned `prompt`, then\n   `forge.derivations.commitPerspective(id, { content, reasoning })`.\n\n## What the person sees\n\n- Derived bullets and perspectives land as **`in_review`**. They show up in the UI by\n  themselves: every successful write fires a `forge:changed` event on `window` and the list pages\n  refetch, so the person watches your results appear.\n- **Approving and rejecting stay with the person.** Do not call `bullets.approve`,\n  `perspectives.approve`, `reject` or the review endpoints on your own initiative, even if\n  asked to \"finish the job\" — tell them what is waiting for review instead. Approve\n  only if they say so for those specific items, in chat.\n\n## Do not\n\n- Do not edit or delete existing approved content to make a derivation fit.\n- Do not read the whole database to look for context. Fetch the one source or bullet.\n- Do not use `forge.debug` or `window.forgeRuntime` internals; the client is enough.\n- Do not call `fetch('\u002Fapi\u002F...')` directly; use the client so errors have one shape.\n\n## When it does not work\n\n| You see | It means |\n| --- | --- |\n| `window.forge` is `undefined` | wrong tab, or the UI is not in wasm mode, or the page has not finished loading |\n| `STORAGE_BUSY` | another tab owns the database |\n| `STORAGE_UNAVAILABLE` | the runtime did not start; read the page for its message |\n| `Derivation has expired` (410) | the 2 minute window passed; `prepare` again |\n| `NOT_FOUND` on commit | wrong derivation id |\n","# Forge in Chrome\n\nIn the browser-first build the database lives in the person's Chrome profile, inside the Forge\ntab. There is no server to call. You reach the data through `window.forge`, the same\n`ForgeClient` the UI uses, by running JavaScript in that tab.\n\nYou write the text; the person approves it. Nothing you derive is final until they approve it\nin the UI.\n\n## Before you start\n\n- Needs Chrome with the Claude in Chrome extension allowed on the Forge origin. Forge's data is\n  per browser: it lives in Chrome, not in another browser.\n- Load the Chrome tools in one `ToolSearch` call (`tabs_context_mcp`, `javascript_tool`,\n  `navigate`, `get_page_text`), call `tabs_context_mcp`, and find the tab whose URL is the Forge\n  app. Open it with `tabs_create_mcp` only if none exists.\n- The UI must be in wasm mode (the default; `VITE_FORGE_MODE=api` turns it off). Check:\n  `typeof window.forge?.derivations?.prepare` should be `'object'`\u002F`'function'` — not `undefined`.\n- Only one tab owns the database. If calls return `STORAGE_BUSY`, another Forge tab owns it:\n  switch to that tab, or ask the person to close the other one.\n\n## Calling the API\n\nEvery call returns `{ ok: true, data }` or `{ ok: false, error }`. Check `ok`. Always return a\nsmall value from `javascript_tool` (ids and a few fields), never whole lists:\n\n```js\nconst r = await window.forge.sources.list({ limit: 20 })\nr.ok ? r.data.map(s => ({ id: s.id, title: s.title })) : r.error\n```\n\nKeep results small: pick the fields you need and cap list sizes.\n\n## Source → bullets\n\n1. Find the source (`forge.sources.list`, or `forge.sources.get(id)`).\n2. Prepare:\n   ```js\n   const p = await window.forge.derivations.prepare({ entity_type: 'source', entity_id: SOURCE_ID, client_id: 'claude-in-chrome' })\n   p.ok ? { id: p.data.derivation_id, prompt: p.data.prompt, expires: p.data.expires_at } : p.error\n   ```\n3. **You are the model.** Read `prompt` and write the bullets it asks for, following its\n   instructions exactly. Do not call another model. Do not invent facts that are not in the source.\n4. Commit within the expiry (**2 minutes** from `prepare`; write the text promptly). Each bullet is an object:\n   ```js\n   const c = await window.forge.derivations.commitBullets(DERIVATION_ID, {\n     bullets: [{ content: '…', technologies: ['Rust'], metrics: null }],\n   })\n   c.ok ? c.data.map(b => ({ id: b.id, status: b.status })) : c.error\n   ```\n   `metrics` is a string when the source states a number, otherwise `null`. A validation error\n   comes back in `error`; fix the text and commit again (the derivation stays open until it expires).\n\n## Bullet → perspective\n\n1. Pick a bullet that is **approved** (the API rejects any other), and an archetype and domain by name\n   (`forge.archetypes.list()`, `forge.domains.list()`), plus a framing:\n   `accomplishment`, `responsibility` or `context`.\n2. Prepare with `entity_type: 'bullet'`, `entity_id`, and\n   `params: { archetype, domain, framing }`.\n3. Write the perspective from the returned `prompt`, then\n   `forge.derivations.commitPerspective(id, { content, reasoning })`.\n\n## What the person sees\n\n- Derived bullets and perspectives land as **`in_review`**. They show up in the UI by\n  themselves: every successful write fires a `forge:changed` event on `window` and the list pages\n  refetch, so the person watches your results appear.\n- **Approving and rejecting stay with the person.** Do not call `bullets.approve`,\n  `perspectives.approve`, `reject` or the review endpoints on your own initiative, even if\n  asked to \"finish the job\" — tell them what is waiting for review instead. Approve\n  only if they say so for those specific items, in chat.\n\n## Do not\n\n- Do not edit or delete existing approved content to make a derivation fit.\n- Do not read the whole database to look for context. Fetch the one source or bullet.\n- Do not use `forge.debug` or `window.forgeRuntime` internals; the client is enough.\n- Do not call `fetch('\u002Fapi\u002F...')` directly; use the client so errors have one shape.\n\n## When it does not work\n\n| You see | It means |\n| --- | --- |\n| `window.forge` is `undefined` | wrong tab, or the UI is not in wasm mode, or the page has not finished loading |\n| `STORAGE_BUSY` | another tab owns the database |\n| `STORAGE_UNAVAILABLE` | the runtime did not start; read the page for its message |\n| `Derivation has expired` (410) | the 2 minute window passed; `prepare` again |\n| `NOT_FOUND` on commit | wrong derivation id |\n",{"name":5,"description":7},"main","349bd50c0e675b97304e19b7a15ac865555bba05",".claude\u002Fskills\u002Fforge-in-chrome","https:\u002F\u002Fgithub.com\u002Fresu-mx\u002Fforge","https:\u002F\u002Fresu.mx","https:\u002F\u002Fgithub.com\u002Fresu-mx","2026-10-26 04:33:51",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add resu-mx\u002Fforge --skill forge-in-chrome",{"tool":57,"command":58},"bunx","bunx skills add resu-mx\u002Fforge --skill forge-in-chrome",{"tool":60,"command":61},"pnpm","pnpm dlx skills add resu-mx\u002Fforge --skill forge-in-chrome","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fresu-mx\u002Fforge\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fforge-in-chrome\u002FSKILL.md",true,[],[66],{"skillNo":67,"name":26,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":39},"01M71DW3X3RRNYPR6M7ZYC1GWC","https:\u002F\u002Fgithub.com\u002Fresu-mx\u002Fforge\u002Fblob\u002Fmain\u002F.agents\u002Fplans\u002Fforge-resume-builder\u002F.scratch\u002Fui\u002Fcontainers\u002Fdata\u002Fskill.md",[],[26]]