diff --git a/docs/cli-skill-design.md b/docs/cli-skill-design.md index 828b528..31486e0 100644 --- a/docs/cli-skill-design.md +++ b/docs/cli-skill-design.md @@ -106,7 +106,7 @@ inkreach-teable [全局选项] <命令> fire webhook [--body ] 模拟 webhook SQL(只读): - sql POST /api/base/{baseId}/sql + ~~sql ~~ (removed in 0.1.5 — backend has no SQL query API) ``` ### 3.3 关键设计决策 @@ -170,7 +170,7 @@ YAML frontmatter(name + 极详细的 description 触发条件)+ 以下章节 2. **基础资源命令**:base/table/field/record/view(官方兼容端点,最简单)。 3. **workflow 命令**:list/get/create/update/delete/activate/deactivate/test。 4. **触发器/Action 便捷封装**:`trigger set` / `action add/update/delete`(内部 GET-modify-PUT 全图)。 -5. **secrets / runs / fire / sql**。 +5. **secrets / runs / fire**(sql 已在 0.1.5 移除:后端无 SQL 查询 API)。 6. **skill 文档**:SKILL.md + guides + api-reference + metadata + install.sh。 7. **端到端验证**:真实实例跑通全链路。 8. **注册**:在 AGENTS.md 添加 skill 说明。 diff --git a/package.json b/package.json index 586c041..366f9d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@inkreach/inkreach-teable", - "version": "0.1.4", + "version": "0.1.5", "description": "CLI (command: inkreach-teable) for operating inkreach-teable: tables, fields, records, views, and the self-built automation engine (8 triggers + 7 actions).", "license": "MIT", "type": "commonjs", diff --git a/skills/inkreach-teable-plugin/dynamic-plugins/dev-workflow.md b/skills/inkreach-teable-plugin/dynamic-plugins/dev-workflow.md index 80ee1bb..78ebcca 100644 --- a/skills/inkreach-teable-plugin/dynamic-plugins/dev-workflow.md +++ b/skills/inkreach-teable-plugin/dynamic-plugins/dev-workflow.md @@ -128,6 +128,40 @@ pnpm build # or: npm run build ``` +**Rebuilding without the scaffold — use this exact config** (agents hand-writing +webpack configs keep hitting `Error: Unsupported library type iife` — there is +NO `output.library` in a working plugin config; a default single-entry +production build is already IIFE, which is what the upload validator requires): + +```js +// webpack.config.js — known-good (from plugins/batch-edit-pro/) +const path = require('path'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +module.exports = { + mode: 'production', // default single-entry build emits an IIFE (!function / (()=>)) + entry: './src/index.tsx', + output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js', clean: true }, + // NO output.library — never add library.type: 'iife' (webpack rejects it) + externals: { + 'react': 'window.__TEABLE_HOST__.React', + 'react-dom': 'window.__TEABLE_HOST__.ReactDOM', + }, + resolve: { extensions: ['.tsx', '.ts', '.js', '.jsx'] }, + module: { + rules: [ + { test: /\.tsx?$/, loader: 'ts-loader', options: { transpileOnly: true }, exclude: /node_modules/ }, + { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }, + ], + }, + plugins: [new MiniCssExtractPlugin({ filename: 'styles.css' })], +}; +``` + +If you build outside the monorepo, drop the `resolve.alias` block (it exists +only so TS can type-check `import type` from `@teable/*` sources) and use +`import type` + `as unknown as` casts instead of runtime imports. + Outputs: `dist/main.js` (IIFE) + `dist/styles.css` (if styles exist). Verify the output: diff --git a/skills/inkreach-teable/SKILL.md b/skills/inkreach-teable/SKILL.md index 1b22ab4..dd55389 100644 --- a/skills/inkreach-teable/SKILL.md +++ b/skills/inkreach-teable/SKILL.md @@ -25,14 +25,13 @@ Respond in the user's language. Keep answers concise and action-oriented. | Module | What it solves | Entry commands | Detail doc | |--------|---------------|----------------|------------| | Tables & Fields | Create/modify structure; **inspect select-choice constraints** | `table create`, `field create`, `field list --with-options`, `field get` | [tables-fields.md](guides/tables-fields.md), [field-types.md](api-reference/field-types.md) | -| Records | Read/write row data | `record get`, `record create/update/delete` | [tables-fields.md § Records](guides/tables-fields.md) | +| Records | Read/write row data | `record get` (alias `record list`), `record create/update/delete` | [tables-fields.md § Records](guides/tables-fields.md) | | Views | Filtered/sorted perspectives | `view create/update` | [tables-fields.md § Views](guides/tables-fields.md) | | View presets | View-scoped shared filter/sort bundles + per-user personal config, applied via toolbar | `preset create/update/list/delete` | [tables-fields.md § View Presets](guides/tables-fields.md) | | Automation | Event-driven workflows | `workflow *`, `trigger set`, `action add` | [automation-guide.md](guides/automation-guide.md), [trigger-types.md](api-reference/trigger-types.md), [action-types.md](api-reference/action-types.md) | | Secrets | API keys for script actions | `secret set/list/delete` | [automation-guide.md § Secrets](guides/automation-guide.md) | | Execution History | Run results / rerun failures | `runs list/get/rerun` | [automation-guide.md § Testing](guides/automation-guide.md) | | Manual Trigger | Test button-click/webhook | `fire button-click`, `fire webhook` | [automation-guide.md § Testing](guides/automation-guide.md) | -| SQL | Read-only analytics, JOINs | `sql ''` | [cli-reference.md § sql](guides/cli-reference.md) | | Direct REST API | Integrate external scripts/services; endpoints the CLI lacks; script actions calling back | `curl` / `fetch` + `Authorization: Bearer ` | [rest-api.md](api-reference/rest-api.md) | | Plugins | Dynamic plugins, dev whitelist, CSP | `plugin *` | [cli-reference.md § plugin](guides/cli-reference.md) | | Subscriptions | Record digest/instant email | `subscription *` | [subscription.md](guides/subscription.md) | @@ -54,8 +53,8 @@ Full command syntax: [cli-reference.md](guides/cli-reference.md). Instance acces | Send notification | `sendNotification` (in-app) | `sendEmail` (needs SMTP) unless email required | | **Inspect select-choice constraints** | `field list --with-options`, `field get `, `field visible-choices` | `--json` + manual filtering | | **Write a select-field value** | Verify the value exists in choices first (`field list --with-options`); need a new value → `field update --options` to add the choice, then write | Blind `record update` (400, or typecast silently resolves to null / mutationApplied=false — it never creates choices) | -| Read records for later writes | `record get` (returns record IDs) | `sql` (no record IDs) | -| Analytics / JOIN | `sql` with GROUP BY | Fetch all records + compute | +| Read records for later writes | `record get` / `record list` (returns record IDs) | Official-teable SQL APIs (none here) | +| Analytics / aggregation | `record get --filter` + compute, script action, or grouped grid view | `sql` — this deployment has NO SQL query API (CLI 0.1.5 removed the dead command) | | Store an API key for scripts | `secret set` → `process.env.NAME` | Hardcoding | | Workflow didn't run | `runs list --status failed` → `runs get` | Blind re-activate | | Call the instance from external code / a route the CLI lacks | Direct REST: `Authorization: Bearer ` + routes in [rest-api.md](api-reference/rest-api.md); unknown route → run the nearest CLI command with `--debug` and copy its request | Official teable API docs (different automation contract) | @@ -76,12 +75,16 @@ These differ from official teable and from the (stale) `docs/automation/triggers 10. **Button field binding**: `options.workflow` is an **object** `{id, name?}`, not a bare id string. The field's `isActive` snapshot can go stale; the API validates the workflow's DB `isActive` at click time (deactivated → 400). 11. **Script sandbox** has NO `fs`/`eval`/`Function`, but has `triggerInput`, `console`, `fetch`, `process.env` (secrets + `AUTOMATION_TOKEN` + `PUBLIC_ORIGIN`), and a controlled `require`. Call back into the instance via `triggerInput._accessToken` + `triggerInput._apiBaseUrl`. **npm deps**: declare with `action add/update --dependencies '[{"name":"axios","version":"1.6.0"}]'` (or `axios@1.6.0,dayjs`). Requires `npm` on the backend **service** PATH — systemd user units default to a PATH that omits the nvm bin dir, so deps fail with `spawn npm ENOENT`; fix by adding `Environment=PATH=:/usr/local/sbin:...` to `teable-backend.service`. 12. **Field options updates go through the convert API** — `field update --options` handles this; the plain PATCH update API strips `options`. +13. **No SQL query API exists** — the backend has no SQL endpoint; the CLI `sql` command was removed in 0.1.5. Aggregate via `record get --filter` + a script action, or a grouped grid view. Also: `table get/update` are base-scoped (`--base-id`, defaults to the configured base) and `view get/update/delete` + `record get-one` are table-scoped (`--table-id`). ## 4. Quick Syntax ```bash inkreach-teable auth login --endpoint https://table.inkreach.cc --token # once inkreach-teable table create --name "Tasks" --fields '[{"name":"Title","type":"text"},{"name":"Status","type":"singleSelect","options":{"choices":["Todo","Done"]}}]' +inkreach-teable record create --table-id tblXXX --fields '{"Title":"a"}' # 单条;批量用 --records '[{"fields":{...}}]' +inkreach-teable record list --table-id tblXXX [--filter ''] # 查询/分页(= record get) +inkreach-teable record delete --table-id tblXXX recXXX [recYYY ...] # 也可 --record-ids 'recA,recB' inkreach-teable workflow create --name "On Go click" # → wflXXX inkreach-teable trigger set wflXXX --type buttonClick --table-id tblXXX --field-ids '["fldXXX"]' inkreach-teable action add wflXXX --type script --code 'return triggerInput.record.fields' @@ -103,4 +106,6 @@ inkreach-teable fire button-click tblXXX recXXX fldXXX && inkreach-teable runs l | `runs list` shows failed | Action error | `runs get ` → `nodeResults[].error` | | Script deps fail `spawn npm ENOENT` | `npm` not on service PATH | See Key Constraint 11 | | Record write 400 "does not meet the current row conditions" | Value violates choice `visibilityFilter` | `field visible-choices` to see allowed options | +| `sql: unknown command` / 404 on a SQL endpoint | No SQL query API on this deployment | Aggregate via script action or `record get --filter` | +| `record list` works like `record get` | Intentional alias (CLI ≥0.1.5) | — | | Select-field write "succeeds" but value unchanged (or becomes null) | Value not in choices — without typecast the API 400s; with typecast it resolves to null and no-ops (`mutationApplied=false`), never creates the choice | `field list --with-options` to confirm; `field update --options` to add the choice, then write | diff --git a/skills/inkreach-teable/api-reference/rest-api.md b/skills/inkreach-teable/api-reference/rest-api.md index 8c27f33..1fc413b 100644 --- a/skills/inkreach-teable/api-reference/rest-api.md +++ b/skills/inkreach-teable/api-reference/rest-api.md @@ -43,7 +43,7 @@ Verified route-for-route against `src/lib/client.ts` (the CLI's HTTP layer). List-query params (objects are passed **JSON-stringified**; repeated keys use `key[]`): `filter` (JSON), `projection` (JSON array), `search[]` (keyword — MUST be the `search[]` tuple form, plain `search=` is ignored), `skip` / `take` -(pagination; no `orderBy` on this fork — sort via view or `sql`). Response: +(pagination; no `orderBy` on this fork — sort via a view). Response: `{ records: [{id, fields}], total? }`. ### Fields @@ -83,7 +83,6 @@ MUST be the `search[]` tuple form, plain `search=` is ignored), `skip` / `take` | Method & route | Purpose | |---|---| -| `POST /api/base/{bid}/sql` | Read-only SQL (`{sql}`; JOIN/GROUP BY; no record ids) | | `GET /api/table/{tid}/aggregation/row-count` | Total row count (`{"rowCount":N}` — verified) | | `GET /api/table/{tid}/aggregation…` | Stats family (group-points, calendar-daily, search-count…) — see swagger for params | | `GET`/`POST` `/api/access-token`, `DELETE /api/access-token/{id}` | PAT management | diff --git a/skills/inkreach-teable/guides/cli-reference.md b/skills/inkreach-teable/guides/cli-reference.md index 0ab93aa..ea74bde 100644 --- a/skills/inkreach-teable/guides/cli-reference.md +++ b/skills/inkreach-teable/guides/cli-reference.md @@ -56,12 +56,13 @@ inkreach-teable field visible-choices inkreach-teable field delete # record -inkreach-teable record get --table-id [--filter ''] [--projection ''] [--page-size ] [--page ] [--search ] -inkreach-teable record get-one +inkreach-teable record get --table-id [--filter ''] [--projection ''] [--page-size ] [--page ] [--search ] [--record-id ] +inkreach-teable record list --table-id [...] # alias of record get +inkreach-teable record get-one --table-id inkreach-teable record create --table-id --fields '' # single inkreach-teable record create --table-id --records '' # batch inkreach-teable record update --table-id --records '' -inkreach-teable record delete --table-id --record-ids +inkreach-teable record delete --table-id [recordId ...] # or --record-ids # view inkreach-teable view list @@ -181,18 +182,6 @@ inkreach-teable subscription send Record digest/instant email subscriptions. Options (`--filter`, `--send-mode`, `--schedule-*`, `--trigger-on-enter`, …) and semantics: [subscription.md](subscription.md). -## sql - -```bash -inkreach-teable sql '