{"skill":{"slug":"feishu-sheet-tabs","displayName":"feishu-sheet-tabs","summary":"Create and organize multiple tabs (worksheets/pages) inside an existing Feishu sheet when the normal feishu_sheet API cannot create new worksheet tabs. Use w...","description":"---\nname: feishu-sheet-tabs\ndescription: Create and organize multiple tabs (worksheets/pages) inside an existing Feishu sheet when the normal feishu_sheet API cannot create new worksheet tabs. Use when the user wants one spreadsheet split into categories/pages/tabs, asks for pagination inside a sheet, or wants separate worksheet tabs such as 总览 / Skills / Workflows / Templates / Content. Prefer this skill only after confirming feishu_sheet API lacks tab-creation support.\n---\n\n# Feishu Sheet Tabs\n\nUse this skill to add worksheet tabs inside an existing Feishu sheet by browser automation when `feishu_sheet` API can create/read/write spreadsheets but cannot create worksheet tabs.\n\n## Core conclusion\n\nCurrent `feishu_sheet` API supports spreadsheet-level actions like:\n- create\n- info\n- read\n- write\n- append\n- find\n- export\n\nIt can target an existing sheet via `sheet_id`, but it does **not** expose a direct action for creating worksheet tabs/pages.\n\nWhen the user explicitly wants tabs/pages inside one spreadsheet, switch to browser automation.\n\n## Preconditions\n\nBefore using browser automation, ensure all of the following:\n\n1. The target spreadsheet URL/token is known.\n2. The user is logged into Feishu in a browser tab.\n3. Prefer using the user's real Chrome tab via Browser Relay when available.\n4. If Browser Relay is not attached, isolated browser may work only if it has a valid Feishu login state.\n\n## Preferred operating mode\n\n### Mode A: User's Chrome tab (preferred)\nUse `browser` with `profile=\"chrome\"` if the user has attached the tab via OpenClaw Browser Relay.\n\nWhy:\n- stable login state\n- real user session\n- fewer auth surprises\n\n### Mode B: OpenClaw managed browser\nUse `profile=\"openclaw\"` only if it is already logged into Feishu.\n\n## Reliable workflow\n\n### Step 1: Verify API limitation first\nDo **not** claim “can’t do it” without checking.\n\nConfirm from tool docs / current tool signature that `feishu_sheet` has no `add_sheet` / `create_worksheet` / `add_tab` action.\n\n### Step 2: Open the spreadsheet in browser\nUse browser automation to open the spreadsheet.\n\n### Step 3: Inspect runtime objects\nFeishu Sheets exposes internal JS objects on the page. In practice, these were found useful:\n- `window.spread`\n- `window.spreadApp`\n\nRelevant methods discovered from runtime introspection:\n- `spread.addSheet(name)`\n- `spread.renameSheet(sheetId, name)`\n- `spread.copySheet(...)`\n- `spread.moveSheet(...)`\n- `spread.hideSheet(...)`\n\n### Step 4: Read current sheet ids/names\nUse page evaluation to inspect current sheets before mutation.\n\nPattern:\n\n```js\nwindow.spread.sheets.map((s,i)=>({\n  i,\n  id: s.id?.() ?? s._id ?? s.sheetId ?? null,\n  name: s.name?.() ?? s._name ?? null\n}))\n```\n\n### Step 5: Rename default first tab if needed\nTypical pattern:\n- rename `Sheet1` → `总览`\n\n### Step 6: Add tabs with `spread.addSheet(name)`\nFor example:\n- Skills\n- Workflows\n- Templates\n- Content\n\n### Step 7: Fill each tab with `feishu_sheet write`\nAfter tabs exist and their `sheet_id`s are known, return to `feishu_sheet` for structured writes. This is more stable than trying to type cell-by-cell in browser automation.\n\n## Proven pattern from this workspace\n\nFor spreadsheet:\n- `https://bytedance.larkoffice.com/sheets/Bf6qsMV9fhqrD6tPE6TcQhF7nEe`\n\nThe following sequence worked:\n\n1. Inspect `window.spread`\n2. Discover `spread.addSheet` and `spread.renameSheet`\n3. Read current sheet list and ids\n4. Rename `Sheet1` to `总览`\n5. Create:\n   - `Skills`\n   - `Workflows`\n   - `Templates`\n   - `Content`\n6. Use `feishu_sheet write` with returned sheet ids to populate each tab\n\n## Example evaluation snippets\n\n### Discover methods\n\n```js\nfunction protoMethods(obj,name){\n  if(!obj) return [];\n  const out=[];\n  let p=Object.getPrototypeOf(obj);\n  let depth=0;\n  while(p && depth<4){\n    for(const k of Object.getOwnPropertyNames(p)){\n      if(k==='constructor') continue;\n      if(/sheet|tab|workbook|insert|create|add|page|name|rename/i.test(k)) out.push(`${name}.${k}`);\n    }\n    p=Object.getPrototypeOf(p); depth++;\n  }\n  return [...new Set(out)];\n}\n```\n\n### Rename + create tabs\n\n```js\nasync () => {\n  const spread = window.spread;\n  const results = [];\n\n  const current = spread.sheets.map(s => ({\n    id: s.id?.() ?? s._id ?? null,\n    name: s.name?.() ?? s._name ?? null\n  }));\n\n  const first = current[0];\n  if (first?.name === 'Sheet1') {\n    results.push(await spread.renameSheet(first.id, '总览'));\n  }\n\n  for (const name of ['Skills','Workflows','Templates','Content']) {\n    const names = spread.sheets.map(s => s.name?.() ?? s._name);\n    if (!names.includes(name)) {\n      results.push(await spread.addSheet(name));\n    }\n  }\n\n  return spread.sheets.map((s,i)=>({\n    i,\n    id: s.id?.() ?? s._id ?? null,\n    name: s.name?.() ?? s._name ?? null\n  }));\n}\n```\n\n## Important caveats\n\n1. **Prefer internal methods over brittle UI clicking**\n   Clicking `+` in the UI was less reliable than runtime JS calls.\n\n2. **Do not assume a visible plus button is the right entry**\n   In this case, one nearby button turned out to be a template entry, not “new tab”.\n\n3. **Use browser only for the tab creation step**\n   Once tabs are created, switch back to `feishu_sheet write`.\n\n4. **Inspect current ids before writing**\n   New tabs get generated `sheet_id`s such as `GxGIGa`, `9dJYiB`, etc. Use actual returned ids.\n\n5. **Avoid blind UI automation first**\n   Inspect runtime objects and methods before pixel-clicking.\n\n## When to use this skill\n\nUse this skill when the user says things like:\n- “把这个表做成分页”\n- “按类别分开 sheet”\n- “给这张飞书表加几个页签”\n- “我就想分页，你想办法解决”\n\n## Output expectation\n\nWhen done, report:\n- which tabs were created/renamed\n- which tab ids were found\n- whether data filling was also completed\n- whether browser login / relay was required\n","topics":["Feishu","Spreadsheet"],"tags":{"latest":"0.1.0"},"stats":{"comments":0,"downloads":669,"installsAllTime":25,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1773428397892,"updatedAt":1778999168527},"latestVersion":{"version":"0.1.0","createdAt":1773428397892,"changelog":"Initial release","license":"MIT-0"},"metadata":null,"owner":{"handle":"g-hanasq","userId":"s17dx33mf4rej38btf8g4p4pr9885hpa","displayName":"G-Hanasq","image":"https://avatars.githubusercontent.com/u/74138794?v=4"},"moderation":null}