@zhama/tego-plugin-sdk 1.37.1 → 1.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +48 -9
  2. package/agent/RULES.md +34 -11
  3. package/agent/guides/agent-templates.md +51 -0
  4. package/agent/guides/backend.md +8 -0
  5. package/agent/guides/host-api-versions.md +3 -0
  6. package/agent/reference/plugin-sdk-api.md +1 -0
  7. package/agent/rules.json +500 -0
  8. package/agent/skills/add-agent-template/SKILL.md +19 -0
  9. package/agent/skills/add-claw-tool/SKILL.md +21 -0
  10. package/agent/skills/add-i18n-strings/SKILL.md +19 -0
  11. package/agent/skills/add-migration/SKILL.md +22 -0
  12. package/agent/skills/add-route-with-access/SKILL.md +30 -0
  13. package/agent/skills/add-screen/SKILL.md +27 -0
  14. package/bin/tego-plugin.mjs +7 -3
  15. package/dist/access.d.cts +1 -0
  16. package/dist/access.d.ts +1 -0
  17. package/dist/{chunk-EIVA5BR6.js → chunk-2KXEYXM2.js} +1 -1
  18. package/dist/{chunk-I5Z3ECC4.js → chunk-44LPR67H.js} +1 -1
  19. package/dist/chunk-66LDWN4T.cjs +1 -0
  20. package/dist/{chunk-HZ4YWRYX.cjs → chunk-6EKQMOYT.cjs} +2 -2
  21. package/dist/{chunk-SKNPNPJP.cjs → chunk-H6GXDFLP.cjs} +1 -1
  22. package/dist/{chunk-6HNG5OZI.cjs → chunk-IOZFHJ4F.cjs} +1 -1
  23. package/dist/chunk-JV2G2Z33.js +1 -0
  24. package/dist/{chunk-4LKRXDYY.cjs → chunk-QQOUNXLC.cjs} +8 -8
  25. package/dist/{chunk-FCYAAOHC.js → chunk-UZBWS5AR.js} +2 -2
  26. package/dist/{chunk-56QOZQTY.js → chunk-XOXUS4VI.js} +1 -1
  27. package/dist/decision-card-IF2c4wvM.d.cts +161 -0
  28. package/dist/decision-card-IF2c4wvM.d.ts +161 -0
  29. package/dist/dev.cjs +8 -3
  30. package/dist/dev.d.cts +33 -2
  31. package/dist/dev.d.ts +33 -2
  32. package/dist/dev.js +13 -8
  33. package/dist/doctor.cjs +15 -8
  34. package/dist/doctor.d.cts +99 -2
  35. package/dist/doctor.d.ts +99 -2
  36. package/dist/doctor.js +15 -8
  37. package/dist/eslint.cjs +1 -0
  38. package/dist/eslint.d.cts +29 -0
  39. package/dist/eslint.d.ts +29 -0
  40. package/dist/eslint.js +1 -0
  41. package/dist/hono.d.cts +1 -0
  42. package/dist/hono.d.ts +1 -0
  43. package/dist/index.cjs +1 -1
  44. package/dist/index.d.cts +14 -1
  45. package/dist/index.d.ts +14 -1
  46. package/dist/index.js +1 -1
  47. package/dist/manifest.cjs +1 -1
  48. package/dist/manifest.js +1 -1
  49. package/dist/pack.cjs +1 -1
  50. package/dist/pack.d.cts +5 -0
  51. package/dist/pack.d.ts +5 -0
  52. package/dist/pack.js +1 -1
  53. package/dist/publish.cjs +1 -1
  54. package/dist/publish.js +1 -1
  55. package/dist/scaffold.cjs +53 -8
  56. package/dist/scaffold.js +59 -14
  57. package/dist/server-runtime.cjs +1 -1
  58. package/dist/server-runtime.d.cts +1 -0
  59. package/dist/server-runtime.d.ts +1 -0
  60. package/dist/server-runtime.js +1 -1
  61. package/dist/server.cjs +1 -1
  62. package/dist/server.d.cts +25 -0
  63. package/dist/server.d.ts +25 -0
  64. package/dist/server.js +1 -1
  65. package/dist/testing.d.cts +1 -0
  66. package/dist/testing.d.ts +1 -0
  67. package/dist/vite.cjs +1 -1
  68. package/dist/vite.js +1 -1
  69. package/package.json +8 -1
  70. /package/dist/{chunk-QKSPPMVN.js → chunk-CDJQ7OPA.js} +0 -0
  71. /package/dist/{chunk-BN6TGHSB.cjs → chunk-SR5V7ZC2.cjs} +0 -0
package/README.md CHANGED
@@ -606,12 +606,18 @@ install and a refresh.
606
606
  ### Preview without a Tego server: `tego-plugin dev`
607
607
 
608
608
  ```bash
609
- pnpm run dev # scaffolded plugins have "dev": "tego-plugin dev"
610
- DATABASE_URL=postgres://me:pw@localhost:5432/dev pnpm run dev # with the backend
609
+ DATABASE_URL=postgres://me:pw@localhost:5432/dev pnpm run dev # scaffolded plugins have "dev": "tego-plugin dev"
610
+ DATABASE_URL=… pnpm run dev -- --inspect # the backend under the Node inspector (9229)
611
+ pnpm run dev -- --no-backend # the frontend alone
611
612
  ```
612
613
 
613
- It prints the address (`http://127.0.0.1:5280/p/<id>/`, or the next free port;
614
- `--port 0` takes any) and a machine-readable `TEGO_DEV_READY {"url":…}` line.
614
+ The backend runs for real, as in any development loop; only tego-os around it
615
+ (the host API and the gateway's signature) is a stand-in. A plugin with a
616
+ backend therefore needs `DATABASE_URL`: without it, or when the database cannot
617
+ be reached, the preview stops at once and says why instead of serving a page
618
+ whose API calls fail. It prints the address (`http://127.0.0.1:5280/p/<id>/`,
619
+ or the next free port; `--port 0` takes any) and a machine-readable
620
+ `TEGO_DEV_READY {"url":…}` line once the backend answers its health path.
615
621
  Everything is served from that one origin:
616
622
 
617
623
  - **Frontend**: a stand-in for the shell's plugin page mounts your entry from
@@ -622,22 +628,31 @@ Everything is served from that one origin:
622
628
  (your locale files, the access UI's strings merged in), light/dark, and the
623
629
  user and roles the API calls are made as (`ctx.can` answers for any nav key
624
630
  the manifest declares).
625
- - **Backend** (with `DATABASE_URL`, unless `--no-backend`): built with the
626
- packer's own settings and started with the environment `serveBackend` reads.
631
+ - **Backend** (unless `--no-backend`): built with the packer's own settings
632
+ plus inline source maps and started as `node --enable-source-maps` with the
633
+ environment `serveBackend` reads; its output is printed line by line after
634
+ `[backend]`. With `--inspect[=<port>]` (or `TEGO_DEV_INSPECT`) it runs under
635
+ the Node inspector on 127.0.0.1, the same port after every restart.
627
636
  Requests carry the same signed identity headers the gateway adds. Migrations
628
637
  run first, each file in its own transaction with `search_path` set to
629
638
  `tego_dev_<id>` alone, recorded in a `tego_dev_migrations` table in that
630
639
  schema so each file runs once; the backend's connection is pinned to the
631
640
  schema too. Saving under `backend/` or `shared/` rebuilds, migrates and
632
- restarts it. The database is yours to provide; any PostgreSQL works.
641
+ restarts it; if it crashes it waits for the next save. The database is yours
642
+ to provide; any PostgreSQL works (in a tego-os checkout, `pnpm infra:up`).
633
643
  - **Host API stand-in**: `config` (the backend section's defaults), `log`,
634
644
  `storage` (files under `.tego-dev/storage/`), `events` and `notifications`
635
645
  (printed), and a `directory` that knows the users you previewed as. Anything
636
646
  else — mail, knowledge, accounts, delegations, AI, Office, live events —
637
647
  answers 501 naming the path; test those on a real server.
638
648
 
639
- Without `DATABASE_URL` the page still works and API calls answer 503 saying
640
- why. `.tego-dev/` holds the generated shell, the backend build and local
649
+ Saves are picked up through file events; on a machine out of them (macOS
650
+ reports EMFILE when editors, Docker and other dev servers hold every FSEvents
651
+ stream) the preview polls instead and says so, and `TEGO_DEV_POLL=1` forces
652
+ polling.
653
+
654
+ With `--no-backend` the page still works and API calls answer 503 saying why.
655
+ `.tego-dev/` holds the generated shell, the backend build and local
641
656
  storage; keep it out of git. Python backends run on a server only.
642
657
 
643
658
  ### Inside the shell
@@ -701,6 +716,30 @@ let that pass.
701
716
  `harness.failPublish()` makes `events.publish` throw, which is the only way to
702
717
  reach the case where a failed announcement undoes a committed write.
703
718
 
719
+ ## The platform's rules, for people and agents
720
+
721
+ The SDK ships the rules a plugin must follow, in the version it builds against:
722
+
723
+ - `agent/RULES.md` lists every rule; `agent/guides/*.md` explains each area;
724
+ `agent/skills/*/SKILL.md` are step-by-step playbooks for common changes (a
725
+ route with access control, a screen, a migration, strings, a claw tool, an
726
+ agent template). A new plugin's `AGENTS.md` points coding agents at them.
727
+ - `tego-plugin doctor` checks the rules that can be checked (`--json` for
728
+ tools; every finding carries a rule id, the guide and a line-independent
729
+ `fingerprint`).
730
+ - `tego-plugin check` runs doctor, then the plugin's own lint, type-check and
731
+ test (`--build` adds build) as one report; the scaffold's `check` script
732
+ calls it. `--json --files a,b` is what editors and agents use.
733
+ - `tego-plugin rules --json` (and the built `agent/rules.json`) lists every rule
734
+ with the files it applies to, resolved to the plugin's part folders.
735
+ - `@tego/plugin-sdk/eslint` turns the line-level rules into ESLint core-rule
736
+ configuration, so the editor flags them while you type:
737
+
738
+ ```js
739
+ import { tegoPluginEslint } from '@tego/plugin-sdk/eslint';
740
+ export default [...yourConfig, ...tegoPluginEslint()];
741
+ ```
742
+
704
743
  ## Developing outside this repository
705
744
 
706
745
  Three SDK packages are published to npm under `@zhama/tego-*` and installed
package/agent/RULES.md CHANGED
@@ -7,14 +7,18 @@ in both shells. Read the guide named in each section before writing that kind of
7
7
 
8
8
  Rules with an id are checked by `tego-plugin doctor` (`--json` for tools). A line can opt out with
9
9
  `tego-doctor-ignore <RULE-ID>: <reason>` on it or on the line above; give a real reason.
10
+ `tego-plugin check` runs doctor and the plugin's lint, type-check and test as one report;
11
+ `agent/rules.json` (or `tego-plugin rules --json`) lists every rule with the files it applies to;
12
+ `agent/skills/` holds step-by-step playbooks for common changes.
10
13
 
11
14
  ## Working loop
12
15
 
13
- 1. Read the relevant guide (`agent/guides/*.md`) and the code you change.
16
+ 1. Read the relevant guide (`agent/guides/*.md`) or playbook (`agent/skills/*/SKILL.md`) and the
17
+ code you change.
14
18
  2. Make focused changes; reuse the SDK's helpers (`@tego/plugin-sdk/react`, `/hono`, `/testing`)
15
19
  instead of writing your own versions.
16
- 3. Run the gates: `tego-plugin doctor`, then lint, type-check, test, build. Fix everything they
17
- report; never weaken a check or a test to make it pass.
20
+ 3. Run the gates: `tego-plugin check` (doctor, lint, type-check, test), and build before you
21
+ hand the plugin over. Fix everything they report; never weaken a check or a test to make it pass.
18
22
  4. Every new user-visible string goes into all ten locales.
19
23
 
20
24
  ## Manifest and packaging — guides/manifest.md, guides/host-api-versions.md
@@ -30,7 +34,7 @@ Rules with an id are checked by `tego-plugin doctor` (`--json` for tools). A lin
30
34
  or workspace links. On npm, a plain `@tego/*` name belongs to another project.
31
35
  - **TP-PKG-002** `package.json` has the four gates: `lint`, `type-check` (tsgo), `test` (vitest),
32
36
  `build` (`tego-plugin-pack`).
33
- - Never import `@tego/shared`, host app code, or anything not published to plugins.
37
+ - **TP-PKG-003** Never import `@tego/shared`, host app code, or anything not published to plugins.
34
38
 
35
39
  ## Running in the web app and the desktop app — guides/desktop-web.md
36
40
 
@@ -49,7 +53,8 @@ that works in a browser tab can fail on desktop, and the reverse.
49
53
  - **TP-WEB-001** The frontend calls no third-party URL (the web CSP only allows the platform). The
50
54
  backend calls it, with the host declared in `parts.backend.egress`.
51
55
  - **TP-WEB-002** No remote or injected scripts; all code ships in the bundle.
52
- - No cookie-based auth: `ctx.api` carries the credentials in both shells.
56
+ - **TP-WEB-004** No cookie-based auth (`document.cookie`, `hono/cookie`): `ctx.api` carries the
57
+ credentials in both shells.
53
58
 
54
59
  ## Frontend — guides/frontend.md
55
60
 
@@ -59,7 +64,8 @@ that works in a browser tab can fail on desktop, and the reverse.
59
64
  `AccessProvider` (with access) → `HostProvider`; the root element carries the scope class.
60
65
  - Route with `ctx.route` / `ctx.navigate` under `ctx.basePath`; the page is not remounted when the
61
66
  in-plugin path changes.
62
- - Call your backend only through `ctx.api` (via `createApiClient`), keeping the error body.
67
+ - **TP-WEB-003** Call your backend only through `ctx.api` (via `createApiClient`), keeping the
68
+ error body; never a raw `fetch('/…')`.
63
69
 
64
70
  ## UI and design — guides/ui.md
65
71
 
@@ -70,6 +76,9 @@ that works in a browser tab can fail on desktop, and the reverse.
70
76
  `tegoPluginScopeRoot`) carries `className="<pluginId>"`, or none of your utilities apply.
71
77
  - Status uses text or an icon, not color alone; machine data (ids, numbers, times) uses
72
78
  `font-mono tabular-nums`.
79
+ - **TP-UI-005** Copy stays short (zh-CN): an explanation (`*Help`, `*Hint`, `*description`,
80
+ `*subtitle`, `*intro`) at most 24 characters, any string at most 40; longer explanations go into
81
+ an `InfoTip`. An empty state is one sentence and one action.
73
82
 
74
83
  ## i18n — guides/i18n.md
75
84
 
@@ -78,17 +87,19 @@ that works in a browser tab can fail on desktop, and the reverse.
78
87
  - **TP-I18N-002** Every value keeps the `{{placeholders}}` of `zh-CN` and is not empty.
79
88
  - **TP-I18N-003** Every literal `t('…')` key exists.
80
89
  - **TP-I18N-004** Say 数字员工 / Employee through `{{avatarTerm}}`; never 数字分身 / digital avatar.
81
- - Keys live under one root named after the plugin (`notes.home.title`); don't copy `tegoAccess.*`.
90
+ - Keys live under one root named after the plugin (`notes.home.title`).
91
+ - **TP-I18N-005** Don't copy `tegoAccess.*` into the plugin's locales; pack merges them.
82
92
 
83
93
  ## Backend — guides/backend.md, guides/storage.md
84
94
 
85
95
  - **TP-BE-001** The caller is the verified `ctx` that `serveBackend` hands you. Never read the raw
86
96
  `x-tego-plugin-*` headers; a user id in a path or body names a target, never the caller.
87
97
  - **TP-BE-005** Log through `host.log`, never `console`.
88
- - Every error becomes JSON (`pluginErrorHandler`): coded 4xx for the caller's mistakes, a generic
89
- 500 that never echoes SQL; host 429s pass through with `Retry-After`.
98
+ - **TP-BE-007** Every error becomes JSON (`app.onError(pluginErrorHandler())`): coded 4xx for the
99
+ caller's mistakes, a generic 500 that never echoes SQL; host 429s pass through with `Retry-After`.
90
100
  - Validate every body and query with zod (`readBody` / `readQuery`).
91
- - Data lives in your schema only (`host.db`); configuration in `host.config.current()`, never env.
101
+ - **TP-BE-006** Data lives in your schema only (`host.db`); configuration in
102
+ `host.config.current()`, never `process.env`.
92
103
  - Storage: `put` up to 25 MiB; larger files upload from the browser to `uploadPath` and are
93
104
  verified with `head`. Download paths are `signedPath` / `managedPath`, opened via `ctx.hostUrl`.
94
105
  - Background work in `start()` never acts as a user.
@@ -120,4 +131,16 @@ that works in a browser tab can fail on desktop, and the reverse.
120
131
 
121
132
  - **TP-TEST-001** The plugin has tests: backend routes against a real database
122
133
  (`createTestPluginHost`), pure frontend logic in `.ts` files. No component tests.
123
- - Each test file starts with a Business Cases list; each `it` title starts with its case id.
134
+ - **TP-TEST-002** Each test file starts with a Business Cases list; each `it` title starts with its
135
+ case id.
136
+
137
+ ## Agent templates — guides/agent-templates.md
138
+
139
+ - Templates live in `templates/<key>/` (`template.config.json`, `workspace/*.md`, `experts/<id>/`)
140
+ and are declared in `agentTemplates`; `template.json` is built by `tego-plugin-pack`, never by
141
+ your own script.
142
+ - **TP-TPL-001** When a template's content, `usageGuide` or `quickPrompts` change, raise its
143
+ `version`: existing employees only see the update through it.
144
+ - **TP-TPL-002** `usageGuide.summary` is at most 30 characters; `quickPrompts` offers 3–4 prompts.
145
+ - `setup` lists only what the host can check (`envVar`, `knowledgeBase`, `plugin`); plugin-specific
146
+ readiness comes from the manifest's `agentReadiness`.
@@ -0,0 +1,51 @@
1
+ # Agent templates
2
+
3
+ A plugin can ship 数字员工 templates that depend on it: its tools, pages and data. They are
4
+ installed with the plugin and appear in the template catalog while the plugin is installed and
5
+ enabled.
6
+
7
+ ## Layout
8
+
9
+ ```
10
+ templates/<key>/
11
+ ├── template.config.json # everything except the workspace documents; `agents` for experts (main first)
12
+ ├── workspace/*.md # the main agent's root files: IDENTITY, SOUL, AGENTS, TOOLS, …
13
+ ├── workspace/<dir>/… # other workspace files, shipped under their path
14
+ ├── experts/<id>/*.md # one folder per expert, matching `agents`
15
+ └── avatar.png
16
+ ```
17
+
18
+ Declare each template in `tego.plugin.json`:
19
+
20
+ ```json
21
+ "agentTemplates": [
22
+ { "key": "notes-assistant", "entry": "templates/notes-assistant/template.json", "icon": "templates/notes-assistant/avatar.png" }
23
+ ]
24
+ ```
25
+
26
+ `template.json` is a build output: `tego-plugin-pack` rebuilds it before packing, and
27
+ `tego-plugin-pack templates` rebuilds it when only documents changed. Commit it for review; never
28
+ write your own build script.
29
+
30
+ ## Versions (TP-TPL-001)
31
+
32
+ Employees created from a template keep a copy. They only see changes through "check template
33
+ updates", which compares by `version`. Raise `version` in `template.config.json` whenever the
34
+ content, `usageGuide` or `quickPrompts` change; doctor reports a changed template whose version
35
+ did not move.
36
+
37
+ ## Usage guide and quick prompts (TP-TPL-002)
38
+
39
+ - `content.usageGuide.summary`: at most 30 characters, saying what the employee does for the user.
40
+ - `content.usageGuide.setup`: only items the host can check (`envVar`, `knowledgeBase`, `plugin`).
41
+ Business readiness (a sales target, a bound person) comes from the manifest's
42
+ `agentReadiness: { "path": "…" }`, answered by your backend for the current user.
43
+ - `content.quickPrompts`: 3–4 prompts a user can click, each with a unique `key`; `requires` may
44
+ name a `setup[].id` or `plugin:<pluginId>:<itemId>`.
45
+ - In a multi-user tenant the conversation guidance goes into `workspace/AGENTS.md`, not a
46
+ `BOOTSTRAP.md` ritual.
47
+
48
+ ## Retiring a template
49
+
50
+ Remove it from `agentTemplates` and publish a new version; the platform archives it. Never write a
51
+ data migration for templates.
@@ -73,4 +73,12 @@ export const backend = definePluginBackend({
73
73
  (`createMaintenance` from `@tego/plugin-sdk/server-runtime`).
74
74
  - Outbound HTTP only to hosts in `parts.backend.egress`.
75
75
 
76
+ ## Running it locally
77
+
78
+ `pnpm dev` (`tego-plugin dev`) runs this backend for real — built with source maps, started with
79
+ `node`, restarted on every save — against the PostgreSQL in `DATABASE_URL`; only the tego-os host API
80
+ and the gateway's identity are stand-ins (unsupported host calls answer 501). Without a database the
81
+ preview refuses to start, so never "fix" a 503 or a missing permission in the frontend: the backend is
82
+ not running. Read its `[backend]` lines in the output first; `pnpm dev -- --inspect` attaches a debugger.
83
+
76
84
  See storage.md for files and access.md for permissions.
@@ -28,6 +28,9 @@ and upload refuses a manifest field newer than the range (TP-MAN-001), as does d
28
28
  | 1.33.0 | `workDelegation` |
29
29
  | 1.34.0 | `attention.request` |
30
30
  | 1.37.0 | `ctx.platform`, `ctx.openExternal`, `ctx.download`, `ctx.copyText` |
31
+ | 1.38.0 | decision cards (`DecisionCardBlock`, `DecisionCardSurface`) |
32
+ | 1.39.0 | `sources.latestUserMessage`, needs `messages.latest_user` |
33
+ | 1.40.0 | `recipientUserId` on `attention.get` |
31
34
 
32
35
  Optional members (`ctx.office`, `ctx.ai`, `ctx.delegation`, `ctx.download` before 1.37) must be
33
36
  feature-detected when the range admits an older shell. The full API is in
@@ -309,6 +309,7 @@ await ctx.office?.open({
309
309
  | API | 输入 | 返回值与约束 |
310
310
  | -------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------- |
311
311
  | `host.sources?.read(id, actor)` | `actor: { userId, avatarId, metadataOnly? }` | `{ source: unknown }`;宿主复核来源归属、源数据是否存在、捕获授权 |
312
+ | `host.sources?.latestUserMessage(input)` | `{ topicId, userId, avatarId }`,需在 manifest 声明 `messages.latest_user` | `{ message: { id, topicId, origin, content, createdAt } \| null }`;只返回此人在该话题的最新一条。`origin` 由宿主写入,只有 `typed`、`voice` 是本人原话,其他值或 `null` 都不是;超过 200 字时 `content` 为空 |
312
313
  | `host.delegations?.list(userId)` | 用户 ID | `{ delegations: [{ avatarId, enabled, actions }] }`;当前安装的工作委托,用于转交工作前复核 |
313
314
 
314
315
  `sources.read` 读取平台已授权捕获的来源,不是任意会话查询接口。`delegations.list` 只查询,不能创建或扩张委托;来源捕获、会话绑定和委托管理的其他平台 REST 接口不在 `PluginHostApi` 方法列表中。