Repository navigation
Commit 78eb352
feat(console): put Connect an AI Assistant where each person looks, and call it that (#30935)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoGdsEvvwWcprHpSwjPsjxFN)_
Part of #30895: Expected 1 (avatar menu item), 4 (Account group of its
own, Setup top group) and 5 (rename). Expected 2 (Home card) and 3
(first-run checklist row) need "has this person connected anything",
which #30894 provides; they follow in a second PR.
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:「连接智能体」改名为「连接 AI
助手」(英/中/日/西四种语言的页面标题、页头和两个菜单入口);头像菜单在「个人资料」下新增「连接 AI
助手」,每个登录用户都能看到;账户应用里它不再藏在默认折叠的「开发者」组,而是独立成「AI
助手」组并默认展开;系统设置里从倒数第二组「集成」移到最上面的「总览」组、系统概览之下。
- 为什么改:这是每个人自己把 Claude、豆包、Cursor 等 AI
助手接入系统的入口,原来成员找不到、管理员要翻到数据源和连接器之间;「智能体」又和 Studio 里自建的智能体撞名。
- 风险与回滚:只改菜单位置、名称和头像菜单一项,页面地址 `page/connect_agent` 与菜单项 id
不变,书签照用;可见范围不变(系统设置两组都要 `manage_platform_settings`);关闭 MCP 时三个入口都不出现。回滚即
revert 本 PR。
-
先看:`packages/mcp/src/connect-ui.ts`(两个菜单贡献的目标组),`packages/platform-objects/src/apps/account.app.ts`(新的「AI
助手」空槽组),`ui/packages/app-shell/src/layout/AppHeader.tsx`(头像菜单项及其按页面是否下发的门控)。
- 两分钟验证:以普通成员登录控制台,点右上角头像,应看到「连接 AI 助手」,点开即连接页;进入账户应用,侧栏「收件箱」下方是展开的「AI
助手」组。
- 需要你做的:无,席位落地。
- **席位意见**:ui 席 2 对照 head `34e84800` 的 diff 复核:38 个文件、+299 /
−104,无受治理路径。改名只动标签与页头,页面地址 `page/connect_agent` 与菜单项 id 不变;账户应用新增空槽组
`grp_account_ai_assistant`(默认展开),系统设置入口移入 `group_overview`(同一
`manage_platform_settings` 门槛,可见范围不变);头像菜单项仅在下发的账户应用导航里有该页时出现,关闭 MCP
时三个入口都不出现。席位核对时发现新增声明把 `isTypingTarget` 的文档注释隔开,已在 `34e84800`
改回,此外无改动。席位授权的文案扩面(mcp、runtime、五个文档页)只改名称与路径字样。CI 65 项全绿,Clause-② no,未改
`packages/spec/src`,不欠契约复审。同意落地。
Surface extended by the seat (wording only, the path and name words this
move made false): `packages/mcp/src/plugin.ts`,
`packages/runtime/src/domains/keys.ts`, `packages/mcp/server.json`,
`content/docs/ai/connect-mcp.mdx`, `content/docs/api/index.mdx`,
`content/docs/getting-started/build-with-claude-code.mdx`,
`content/docs/ai/agents.mdx`,
`content/docs/deployment/environment-variables.mdx`,
`packages/mcp/README.md`. Also comment-only:
`packages/cloud-connection/src/cloud-connection-ui.ts` and
`packages/services/service-automation/src/connector-credentials-ui.ts`
list the Integrations group's other priorities in their headers and no
longer name Connect an AI Assistant there.
## What changes
- **Name.** The `connect_agent` page, its `page:header` title and both
nav entries are called Connect an AI Assistant. The platform-objects
bundles carry it in all four locales (`连接 AI 助手`, `AI アシスタントを接続`,
`Conectar un asistente de IA`):
`apps.account.navigation.nav_connect_agent`,
`apps.setup.navigation.nav_connect_agent` and
`pages.connect_agent.label`. The three re-translated leaves record their
new source digests in each locale's `source-hashes.ts`, so none is
served as stale.
- **Account.** `ACCOUNT_APP` declares `grp_account_ai_assistant` (AI
Assistant, `expanded: true`, `children: []`) between Inbox and Security,
and the MCP bundle's account contribution targets it instead of
`grp_account_developer`. The group label is translated in all four
locales. The slot is empty in the app definition, so with MCP off the
nav filter drops it, as it drops Setup's empty slots.
- **Setup.** The MCP bundle's setup contribution targets
`group_overview` (priority 110, behind System Overview at 100) instead
of `group_integrations`. Both groups carry `manage_platform_settings`,
so who sees the entry is unchanged.
- **Avatar menu.** `AppHeader` draws a Connect an AI Assistant item
under Profile. It opens `/apps/ACCOUNT_ADDRESS/page/connect_agent`,
where the segment is the Account app's one address
(`appAddressSegment`). The item is drawn only while the served Account
app's navigation carries a `page` entry for `connect_agent`, so it lives
and dies with the MCP bundle like the two menu entries. The label is
`user.connectAiAssistant`, added to all ten console locales.
- **Path text.** The stdio refusal (`plugin.ts`), the API-key session
refusal (`keys.ts`), `server.json`, the mcp README and five docs pages
name the new page and paths. Nothing else on those pages changes.
- Nothing in the top bar. The page address and the nav item id are
unchanged.
## Why
Connecting an AI client is something every person does for themselves
(each call runs as the caller), and the maintainer called it the
platform's most central feature. On `main` a member had to open the
collapsed Developer group in Account to find it, and an administrator
found it near the bottom of Setup among datasource and connector
screens. "Agent" also reads as one of the agents built in Studio.
## Tests
- `packages/mcp/src/connect-agent-account-nav.test.ts`: the account
contribution targets `grp_account_ai_assistant`; the setup contribution
targets `group_overview` at priority 110; new case: the page label, the
`page:header` title and both entries are Connect an AI Assistant.
- `packages/cli/test/connect-agent-both-halves-wire.pin.test.ts` (the
composed wire pin): a permissionless caller gets
`grp_account_ai_assistant` = `['nav_connect_agent']` and Developer back
to its two authored entries, 13 account nav ids; the admin's Setup has
`group_overview` = `['nav_system_overview', 'nav_connect_agent']`. The
Setup count moves 32 to 31 because `group_integrations` held only this
entry in that composition and is now dropped as empty; the anti-widening
control still compares the admin tree with and without the account half.
- `packages/cli/test/setup-integrations-order.pin.test.ts`: the
Integrations tiers drop `nav_connect_agent`. The MCP bundle is still
read, so the "nothing contributes into the group that this pin does not
order" check reds if the entry moves back.
- `AppHeader.hiddenAppAddress-29024.test.tsx` (the avatar-menu harness
with a settable app list), new top-level describe, 4 cases: opens
`/apps/com.objectstack.account/page/connect_agent`; is labelled Connect
an AI Assistant; draws nothing when the served Account app lacks the
page; draws nothing when no Account app is served.
<details><summary>Ablation (head 0264ecd)</summary>
`node scripts/ablation-replace.mjs` on `AppHeader.tsx`, anchor
`accountApp && navCarriesPage((accountApp as any).navigation,
CONNECT_ASSISTANT_PAGE)` replaced by `accountApp && /* ABLATED */ true`
(the page gate removed), against
`AppHeader.hiddenAppAddress-29024.test.tsx`: anchor 1 to 0, `1 failed |
7 passed` (the MCP-off case red), then `ok restored: blob == HEAD`.
</details>
## Acceptance notes
- Measured live on `main` `7d9682ff` and on this branch (showcase,
`objectstack dev --fresh`, Console from `ui/` src via Vite), as
`admin@objectos.ai` and as a member created by the admin
(`chen@example.test`, no Setup access):
| Who | Path | Before | After |
|:--|:--|:--|:--|
| Admin | Setup | Integrations (8th of 9 groups), entry 42 of 45 |
Overview (1st group), entry 2 of 45, under System Overview |
| Admin, member | Account | inside Developer, collapsed by default | AI
Assistant group, expanded, right after Inbox |
| Admin, member | Avatar menu | Profile, My Organizations, Log out |
Profile, Connect an AI Assistant, My Organizations, Log out; it opens
the page, header "Connect an AI Assistant" |
| Member | Setup | "You don't have access to this app" | unchanged |
In zh the avatar item, the Account group and entry, the Setup entry and
the page header all read 连接 AI 助手 / AI 助手. The showcase item count (45)
differs from the card's 40 because the showcase composes more Setup
entries.
- The Console's widget registry label in `ConnectAgentWidget.tsx`
(`label: 'Connect an Agent'`, a palette label for the
`mcp:connect-agent` type) is left as it is: the order puts that file off
limits while #30894 works there. The Integrations page's own "Connect an
AI agent (MCP)" card (`AgentConnectSection`, console i18n
`connectSection` and friends) is a different page and keeps its copy.
- Resolver and extractor test fixtures that use "Connect an Agent" /
连接智能体 as sample data (`packages/spec` i18n-resolver tests,
`packages/rest` tests, `packages/cli` i18n-extract test, the
`check-app-nav-i18n` self-test fixture) are left unchanged: they test
the mechanism, not the shipped label.
- Released `CHANGELOG.md` entries and `content/docs/releases/` keep the
old name, as release-owned history.
## Verification
<details><summary>Local gates and tests (head 0264ecd)</summary>
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` against this diff, each run with stdin
closed; reconciled with `--ran`: 100 derived, 100 run, 0 NOT-MEASURED, 0
UNRUN. `check-plugin-teardown-shape.mjs --self-test` first exited 3
because the shallow clone lacked its pinned commit; after `git fetch
origin 621a487 --depth=1` it exits 0
(48 cases). Outside the derived list: `pnpm check:app-nav-i18n` (its
script's comments changed) exit 0, `setup: 56 merged nav id(s), account:
13`; `pnpm check:changeset-fixed` exit 0; `ui`
`check:new-line-citations` 0 new.
```text
node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-adr-links.mjs :: exit 0
node scripts/check-adr-links.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-doc-route-spelling.mjs --advisory :: exit 0
node scripts/check-doc-route-spelling.mjs --self-test :: exit 0
node scripts/check-docs-section-name.mjs :: exit 0
node scripts/check-docs-section-name.mjs --self-test :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0
node scripts/check-sdui-manifest.mjs :: exit 0
node scripts/check-sdui-manifest.mjs --self-test :: exit 0
node scripts/check-section-landing-index.mjs :: exit 0
node scripts/check-section-landing-index.mjs --self-test :: exit 0
node scripts/check-tenant-audit-census.mjs :: exit 0
node scripts/check-tenant-audit-census.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/ci/snapshot-next.mjs --self-test :: exit 0
node scripts/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --dir ui exec vitest run scripts/ :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
pnpm --filter @objectstack/lint run check:doc-security-posture :: exit 0
pnpm --filter @objectstack/spec run check:docs :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm --filter @objectstack/spec run check:empty-state :: exit 0
pnpm --filter @objectstack/spec run check:liveness :: exit 0
pnpm --filter @objectstack/spec run check:skill-examples :: exit 0
pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0
pnpm --filter @objectstack/spec run check:variant-docs :: exit 0
pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0
pnpm check:changeset-gate-self-tests :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:cli-test-child-env :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:corpus-claim-drift :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:dispatcher-error-vocabulary :: exit 0
pnpm check:doc-anchors :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:doc-frontmatter :: exit 0
pnpm check:docs-audit-scope :: exit 0
pnpm check:docs-redirects :: exit 0
pnpm check:docs-single-h1 :: exit 0
pnpm check:docs-spec-enumerations :: exit 0
pnpm check:docs-transcript-drift :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:error-status-conformance :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:i18n :: exit 0
pnpm check:i18n-stale-fill :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:package-naming :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:published-files :: exit 0
pnpm check:published-readme-links :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:react-page-adapter-contract :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:role-word :: exit 0
pnpm check:route-envelope :: exit 0
pnpm check:skill-identifier-liveness :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:vendor-version-stamps :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
```
Tests (on 0264ecd):
- `pnpm --filter @objectstack/mcp --filter @objectstack/platform-objects
test`: mcp 56 files / 681 tests passed; platform-objects 117 files /
1591 tests passed.
- `pnpm --dir ui exec vitest run packages/i18n/
packages/app-shell/src/layout/`: 237 files passed, 2431 tests passed, 13
skipped.
- `packages/cli`: `connect-agent-both-halves-wire.pin.test.ts`,
`setup-integrations-order.pin.test.ts`,
`platform-page-i18n-parity.test.ts`, `i18n-extract.test.ts`: 4 files
passed.
- `packages/runtime`: `keys-mint-interactive-session.pin.test.ts`,
`keys-actions-method-not-allowed-allow.test.ts`: 21 tests passed.
- Type checks: `typecheck` for `@objectstack/mcp`, `platform-objects`,
`runtime`, `cloud-connection`, `service-automation`, `cli`, and
`type-check` for `@object-ui/i18n`, `@object-ui/app-shell`: all exit 0.
</details>
<!-- signed: domain:ui#2 · os-tesla · session_01L9qibw7DekEe3wx5f3zphf
-->
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 616311c commit 78eb352
38 files changed
Lines changed: 299 additions & 104 deletions
File tree
- .changeset
- content/docs
- ai
- api
- deployment
- getting-started
- packages
- cli
- scripts
- test
- cloud-connection/src
- mcp
- src
- platform-objects/src/apps
- translations
- runtime/src/domains
- services/service-automation/src
- ui/packages
- app-shell/src/layout
- __tests__
- i18n/src/locales
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
98 | | - | |
| 98 | + | |
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
121 | | - | |
| 121 | + | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
125 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
126 | 127 | | |
127 | | - | |
| 128 | + | |
128 | 129 | | |
129 | 130 | | |
130 | 131 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
69 | | - | |
70 | | - | |
71 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
295 | | - | |
| 295 | + | |
296 | 296 | | |
297 | 297 | | |
298 | 298 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
487 | 487 | | |
488 | 488 | | |
489 | 489 | | |
490 | | - | |
491 | | - | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
492 | 493 | | |
493 | 494 | | |
494 | 495 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | | - | |
| 148 | + | |
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| |||
407 | 407 | | |
408 | 408 | | |
409 | 409 | | |
410 | | - | |
411 | | - | |
| 410 | + | |
| 411 | + | |
412 | 412 | | |
413 | 413 | | |
414 | 414 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
215 | 215 | | |
216 | 216 | | |
217 | 217 | | |
218 | | - | |
219 | | - | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
220 | 223 | | |
221 | | - | |
222 | | - | |
223 | | - | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
224 | 228 | | |
225 | 229 | | |
226 | 230 | | |
| |||
250 | 254 | | |
251 | 255 | | |
252 | 256 | | |
253 | | - | |
254 | | - | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
255 | 260 | | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
261 | 268 | | |
262 | 269 | | |
263 | 270 | | |
264 | 271 | | |
265 | 272 | | |
266 | | - | |
| 273 | + | |
267 | 274 | | |
268 | 275 | | |
269 | 276 | | |
| |||
286 | 293 | | |
287 | 294 | | |
288 | 295 | | |
289 | | - | |
290 | | - | |
| 296 | + | |
| 297 | + | |
291 | 298 | | |
292 | 299 | | |
293 | 300 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | 15 | | |
17 | 16 | | |
18 | 17 | | |
19 | 18 | | |
20 | 19 | | |
21 | 20 | | |
22 | | - | |
| 21 | + | |
23 | 22 | | |
24 | 23 | | |
25 | 24 | | |
| |||
66 | 65 | | |
67 | 66 | | |
68 | 67 | | |
69 | | - | |
70 | 68 | | |
71 | 69 | | |
72 | 70 | | |
| |||
101 | 99 | | |
102 | 100 | | |
103 | 101 | | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
104 | 106 | | |
105 | 107 | | |
106 | 108 | | |
| |||
126 | 128 | | |
127 | 129 | | |
128 | 130 | | |
129 | | - | |
| 131 | + | |
130 | 132 | | |
131 | 133 | | |
132 | 134 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | | - | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
| |||
0 commit comments