Files
inkreach-teable-cli/skills/inkreach-teable/SKILL.md
T
yeuimu 2530eea8b5 feat(skill): teach direct REST API usage — api-reference/rest-api.md
Comprehensive review found the skill taught CLI-only usage (just one
script-action callback snippet); nothing on calling the API directly.

New guide (verified against the live instance):
- base URL + Bearer PAT auth, Node v24 fetch header-drop warning
- full endpoint map mirrored from the CLI's HTTP layer (records/fields/
  tables/views/presets/workflow/secrets/executions/fire/sql/PAT/signup)
- canonical curl examples incl. typecast/fieldKeyType bodies, url-encoded
  filter, convert-for-options, workflow node PUT + activate, script-action
  callback via triggerInput._apiBaseUrl
- gotchas: typecast never creates choices (silent no-op), visibilityFilter
  400, PATCH field strips options, whole-graph node replace, search[] tuple

SKILL.md: module table row + routing rule wired to the new guide.
2026-09-23 05:20:14 +00:00

113 lines
10 KiB
Markdown

---
name: inkreach-teable
description: >-
Operate a deployed inkreach-teable instance (a Teable fork with a self-built
automation engine) via the inkreach-teable CLI: configure tables, fields,
records, views, and automations (8 triggers incl. recordCreated/Updated/
Condition, formSubmitted, scheduledTime, buttonClick, webhook; 7 actions),
inspect field constraints (select choices, visibilityFilter conditions),
manage secrets, execution history, plugins, and record subscriptions. Use
when the user references Teable-style IDs (bseXXX, tblXXX, fldXXX, recXXX,
viwXXX, wflXXX) or wants to configure tables/automations/plugins on the
deployed instance — even without saying "inkreach-teable". The official
teable CLI does NOT work here (different automation contract).
---
# inkreach-teable operations
Operate a deployed inkreach-teable instance via the `inkreach-teable` CLI.
Respond in the user's language. Keep answers concise and action-oriented.
> **Critical**: the automation engine is **self-built and differs from official
> teable** — the official `teable` CLI corrupts or 404s on automations here.
> Exact key-name differences are in [Key Constraints](#3-key-constraints).
## 1. Prerequisites
- Install the CLI if missing: `npm i -g git+https://gitea.inkreach.cc/inkreachhub/inkreach-teable-cli.git` (the `git+` prefix is REQUIRED for npm/npx; ad-hoc without installing: `npx git+https://gitea.inkreach.cc/inkreachhub/inkreach-teable-cli.git <cmd>`). Offline fallback: `bash scripts/install.sh` relative to this skill dir in a repo clone.
- **Configure once**: `inkreach-teable auth login --endpoint http://localhost:3003 --token <PAT> [--base-id bseXXX]`; verify with `auth status`. PAT comes from `auth token create --name x` (full token shown **once**) or the web UI (Settings → Personal Access Tokens).
- `--json` on any command returns raw JSON (for agent parsing). Fallback for unknown commands: `inkreach-teable <cmd> --help`.
- **Read on demand**: consult the guide linked for your module when doing non-trivial work — no need to read everything up front.
## 2. Module & Command Navigation
| 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) |
| 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 '<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 <PAT>` | [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) |
| Dev/Deploy | Build, restart, gotchas | systemd / pnpm | [development.md](guides/development.md) |
Full command syntax: [cli-reference.md](guides/cli-reference.md). Instance access & credentials: [instance-access.md](guides/instance-access.md).
### Routing rules
| User intent | Correct approach | Do NOT |
|-------------|------------------|--------|
| Configure an automation | `workflow create` → `trigger set` → `action add` → `activate` | Editing DB rows |
| React to new records / field changes | `recordCreated` / `recordUpdated --field-ids` | Polling in a script; `recordCondition` ignores fields |
| React to a condition matching | Trigger `recordCondition` (NOT recordMatchesConditions) | Official-teable key names |
| Button click starts a workflow | `buttonClick` trigger + Button field (`options.workflow` object) | Other trigger types |
| Receive external HTTP | `webhook`; test via `fire webhook` | Expecting auth (backend ignores it) |
| Schedule recurring job | `scheduledTime` (only `timing.type` + `interval` honored) | triggerTime/weekdays (ignored) |
| Per-row transformation | `script` action reading `triggerInput` | Row-by-row record API |
| Send notification | `sendNotification` (in-app) | `sendEmail` (needs SMTP) unless email required |
| **Inspect select-choice constraints** | `field list --with-options`, `field get <tbl> <name>`, `field visible-choices` | `--json` + manual filtering |
| Read records for later writes | `record get` (returns record IDs) | `sql` (no record IDs) |
| Analytics / JOIN | `sql` with GROUP BY | Fetch all records + compute |
| 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 <PAT>` + 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) |
## 3. Key Constraints
These differ from official teable and from the (stale) `docs/automation/triggers.md`.
1. **Filter key is `conditions`** (NOT `filter`): `trigger set --conditions '<json>'`, shape `{conjunction, filterSet:[{fieldId, operator, value}]}`.
2. **Watch-fields key is `fieldIds`** (NOT `watchFieldIds`); `[]` = watch all fields.
3. **Trigger category `recordCondition`** (NOT `recordMatchesConditions`).
4. **`scheduledTime` honors only `timing.type` + `timing.interval`** — triggerTime/weekdays/daysOfMonth/starting/ending/tz are ignored; `weeks` is hardcoded to Sunday.
5. **Webhook route is `/api/webhook/{baseId}/{workflowId}`** (no `/base/` segment); `authorization` config is UI-only, backend never validates. Fire: `fire webhook <baseId> <wfId>`.
6. **Node updates are whole-graph replacement** — `trigger set` / `action add/update/delete` do GET→modify→PUT internally; never hand-edit partial graphs.
7. **`activate` creates a snapshot** — node changes take effect only after re-activating. `hasDraft: true` = unactivated changes.
8. **`workflow delete` is soft** (cascades to nodes, tokens, trigger unregister); test workflows should be `deactivate`d.
9. **Secrets are write-only** — `secret list` never returns values; scripts read `process.env.<NAME>`.
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=<nvm-bin>:/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`.
## 4. Quick Syntax
```bash
inkreach-teable auth login --endpoint http://localhost:3003 --token <PAT> # once
inkreach-teable table create --name "Tasks" --fields '[{"name":"Title","type":"text"},{"name":"Status","type":"singleSelect","options":{"choices":["Todo","Done"]}}]'
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'
inkreach-teable workflow activate wflXXX
inkreach-teable fire button-click tblXXX recXXX fldXXX && inkreach-teable runs list wflXXX
```
## 5. Common Errors & Recovery
| Symptom | Cause | Fix |
|---------|-------|-----|
| `MISSING_BASE_ID` | No base id resolved | Pass `--base-id`, or `auth login --base-id` |
| `401` / access denied | Token invalid/expired or lacks scope | `auth status`; recreate PAT |
| `403` | Base role too low | Grant owner/creator role in web UI |
| Workflow never fires | Not activated / trigger misconfigured | `workflow get` → `isActive`; verify trigger type + tableId/fieldIds |
| `scheduledTime` wrong time | Backend ignores most timing fields | Only `timing.type`+`interval` work |
| button-click 400 "not active" | Workflow deactivated since field created | `workflow activate <id>` |
| `runs list` shows failed | Action error | `runs get <wfId> <execId>` → `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 |