- untrack dist/, add .gitignore, add pnpm-lock.yaml
- inline tsconfig.base.json options (no monorepo extends)
- install.sh: CLI now at repo root; install skill to ~/.zcode/skills (user scope)
- fix stale paths in skill docs; 7 actions in help text; README
Lands the view-preset / server-persisted personal-layer feature that has
been running in production, plus the hotfix for "the same preset shows
different filter configs to different users" (物流问题-已出轨迹 on
tblgsJTXhqwiDpsjeL5 / viwyszJmLQNOLhA9sh5).
Root cause of the divergence:
- usePersonalViewSync implicitly flushed any overlay edit by a
view|update user INTO the shared preset row (last-writer-wins). Overlays
are stale snapshots seeded at apply time, so one user's seed silently
erased colleagues' filter changes (2026-09-17 02:55 the preset lost the
流转角色=售后 condition), and active overlays never converged because
preset updates do not propagate.
Fix (semantics: presets are shared definitions, edits are personal):
- fork-on-edit: the first user edit strips the seed markers from the
overlay (toolbar switches to the personal config); edits only ever
write the user's personal row
- shared presets change ONLY through the new explicit, confirmed
"Update to current config" row action (canManage users)
- un-edited preset overlays auto-follow redefinitions: applyPreset stamps
a presetVersion (preset.lastModifiedTime); when the preset list
refetches with a newer row the overlay re-seeds. Edited overlays carry
no markers and are never clobbered. Legacy rows without a version
re-seed exactly once
- exits strip both seed markers from the persisted personal row
Also lands the pending WIP shipped with the deployed build: select-choice
visibility constraint, personal-view server sync + proxy, grid async
records scope/request tracking, CLI resource display, preset i18n (10
locales), view_preset migrations, docs/skill updates, .zcode gitignore.
Verified end-to-end on the live instance (headless chromium, real
session): apply -> edit flips toolbar to Personal with ZERO shared-row
PUTs; explicit update PUTs the shared row; API-side redefinition
auto-reseeds an un-edited overlay on the next list refetch.
The backend never compiles @teable/* sources — it loads packages/*/dist via
node_modules symlinks (@teable/v2-core is a webpack external, read at runtime
from packages/v2/core/dist/index.cjs). Editing a package's src and only
rebuilding apps/nestjs-backend ships nothing: no error, old behavior online.
Documented the correct build order + verification greps in AGENTS.md and the
skill's development guide (found while shipping the defaultValue cascade fix).
Wrapping --config in {"config":{...}} deploys a silent empty script
(succeeds in ~1ms, result {}). Document the trap + verification recipe
(workflow get --json, nodes[].config.code non-empty).
- cli-reference.md: field get/update/delete now <tableId> <fieldId>;
new field visible-choices command; note --options goes via convert API
- tables-fields.md: correct update/delete signatures; options-rewrite
semantics (convert API, whole-replace not merge); new section on
select-choice visibilityFilter dependency (read/write/evaluate,
backend 400 guards, write-time enforcement message)
- action add/update: new --dependencies <json> option
- parseDependencies accepts JSON, name@version shorthand, or bare names
- update is incremental; --dependencies replaces the whole array
- docs: deployment/systemd.md + skill SKILL/action-types/development
document the npm-deps feature and the service-PATH requirement
(spawn npm ENOENT without nvm bin dir on PATH)
Ran 4 end-to-end evals (skill-creator flow): all 23 assertions passed (100%).
The evals exposed 3 issues, now fixed:
1. CLI bug: getRecords/createRecord/updateRecord --target-table flag was
read as opts['target-table'] but commander stores it camelCase
(opts.targetTable). Added a pick() helper accepting both forms.
2. trigger-types.md: buttonClick output said record.fields.* implying all
fields; actually record.fields only contains the button field's count.
Documented the back-channel API fetch pattern for other fields.
3. automation-guide.md: documented that 'workflow test' uses mock input
with empty fields, so upstream outputs are absent in test mode — use
real fire for data-dependent validation.
Also: corrected button field options (workflow.id object, not workflowId).
Rename the skill directory and update all references (SKILL.md frontmatter
name, AGENTS.md, design doc, install.sh). Git tracks this as a rename so
history is preserved.