Skip to content

feat: UX gap roadmap — notifications, Gen UI artifacts, diagnostics, voice input, IM destinations, marketplace index, bind auth - #599

Merged
gansx merged 17 commits into
mainfrom
feat/ux-gap-roadmap
Oct 27, 2026
Merged

gansx merged 17 commits into
mainfrom
feat/ux-gap-roadmap

Conversation

@gansx

@gansx gansx commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the UX gap roadmap produced by comparing Ling against Codex Desktop, MiniMax Code, ZCode, and WorkBuddy (docs/design/ux-gap-roadmap.md + 13 per-item design docs with compatibility analysis, upgrade paths, and phased implementation plans).

Two roadmap candidates were deliberately excluded at review: installer signing/auto-update (tracked in apps/desktop open gates) and hosted model access (contradicts the open-source BYOK position).

Implemented (design + code + tests)

  • Startup & diagnostics panel (Add image artifact actions in web #13, was a pending: true stub): daemon /diagnostics/doctor + redacted /diagnostics/logs routes, api-client methods, web DiagnosticsDoctorCard (checks, log tail, copy diagnostics bundle), CLI advertises the log path.
  • Voice dictation (Document media approvals and add CLI coverage #11): Web Speech dictation with a pure state machine, mic button + dictating badge on the composer; dictation only appends to the draft, never sends; closed error taxonomy with recovery copy.
  • Notifications (Add media job execution interface #3, automations P3): file-backed NotificationHub with quiet hours + per-kind tone semantics, /notifications + long-poll stream + preferences routes, automation run-completion hook, web toast bridge and a preferences card.
  • IM webhook destinations (Add media vendor adapter contract #4): Feishu/WeCom/DingTalk/Slack payload builders, ref-only secret storage, provider egress allowlist over https, HMAC signing, CRUD/test routes, fan-out sink on delivered notifications.
  • Interactive HTML artifacts / Gen UI (Add media job foundation #2): html_interactive preview kind with an offline-first safety scan (remote subresources and javascript: rejected, 2MB cap), sandboxed allow-scripts-only iframe in the preview drawer; core's duplicated preview types now delegate to the contract.
  • Non-loopback bind guard + bearer token (Add Seedream image generation HTTP adapter #9 Phase A): daemon refuses non-loopback binds without a token; /health stays open, everything else requires the token.
  • Skill marketplace index (Add media cost approval gate #10 slice): versioned index contract + parser and a bounded /skills/marketplace/inspect route; the index is untrusted — installs still flow through the review queue and verify sha256 integrity.

Design-complete, code as follow-up slices

01 (document deliverables), 05 (built-in browser), 06 (computer use hardening), 07 (memory citations), 08 (work board acceptance), 12 (pack export/import UI + browse surface).

Test evidence

  • New unit suites: contracts (notifications quiet-hours/tone, html scan, marketplace index), daemon (diagnostics API, notifications hub/API, html-interactive preview, bind/auth, IM destinations, marketplace route) — 39 new tests, all green.
  • New mock-daemon Playwright specs with screenshot evidence (LING_CAPTURE_UI2_EVIDENCE=1): diagnostics panel, interactive artifact (in-frame click-through proves the sandbox), voice dictation, notification toast + preferences card — all passing; screenshots under output/playwright/{diagnostics,gen-ui,notifications,voice-input}.
  • Updated the settings-shell/dark-mode/runtime specs for the section graduating from pending placeholder to first-class panel (46 tests green).
  • Full web unit suite: 599 pass; the 6 failures in execution-engine-manager-http.test.mjs are pre-existing on main (Windows platform gate). Daemon artifact/media failures were sampled and are byte-identical between main and this branch (45/23 on both), i.e. pre-existing environment issues, no regressions introduced.

Ling Test added 9 commits October 26, 2026 23:47
Competitive comparison vs Codex Desktop / MiniMax / ZCode / WorkBuddy.
Each doc covers compatibility analysis, upgrade paths, and a phased
implementation plan with acceptance criteria. Signing/auto-update and
hosted model access deliberately excluded at roadmap review.
Startup diagnostics (ux-gap-roadmap-13): daemon-side doctor checks route
(/diagnostics/doctor), redacted bounded log tail (/diagnostics/logs),
api-client methods, web DiagnosticsDoctorCard with copy bundle action,
pending flag removed from the settings section. CLI now advertises
LING_STACK_DAEMON_LOG_PATH to the daemon.

Voice input (ux-gap-roadmap-11): Web Speech dictation state machine,
useVoiceDictation hook, mic button + dictating badge on the normal
conversation composer. Dictation only appends to the draft, never sends.

Includes unit tests (daemon route + web view models/machine), mock-daemon
Playwright specs, and screenshot evidence wiring.
ux-gap-roadmap-03 slice: daemon NotificationHub (bounded file-backed
journal, persisted preferences with quiet hours, tone semantics),
/notifications + /notifications/preferences + long-poll stream routes,
automation run completion hook, api-client endpoints, web notification
bridge with toasts, and a Notifications preferences card in the startup
diagnostics settings section.

Includes contracts tone/quiet-hours tests, daemon hub + API tests, and a
mock-daemon Playwright spec with screenshot evidence.
ux-gap-roadmap-02 slice: html_interactive preview kind, shared safety
scan (offline-first: remote subresources and javascript: URLs rejected,
2MB cap), daemon preview builder emits sandboxed documents with
allow-scripts-only sandbox, and the web ArtifactPreview renders them in
an opaque-origin iframe. Core's duplicated preview types now delegate to
the contract so the surface cannot drift again.

Tests: contracts scan tests, daemon builder tests (interactive + fallback
paths), and a mock-daemon Playwright spec verifying sandbox attributes and
in-frame interactivity with screenshot evidence.
ux-gap-roadmap-09 Phase A slice: daemon refuses to start on non-loopback
hosts without an auth token; when LING_STACK_AUTH_TOKEN/config.authToken
is set, every route except /health requires a matching bearer token
(length-pinned comparison). Enables self-hosted always-on daemons.
ux-gap-roadmap-04 slice: ImDestination contract with per-provider payload
builders (Feishu card, WeCom markdown, DingTalk actionCard, Slack
attachments), file-backed registry storing webhook/secret refs only
(never raw URLs), provider egress allowlist over https, DingTalk/Feishu
HMAC signing, CRUD + test routes under /im-destinations, and a
notification deliver-sink that fans delivered records out to every
enabled destination.
…route

ux-gap-roadmap-10 slice: versioned marketplace index contract (v1-only
parser rejecting unknown versions, non-https pack URLs, malformed ids and
missing sha256 integrity), plus a daemon /skills/marketplace/inspect
route that fetches a user-configured index over https through the daemon
web fetch with size/timeout bounds. The index is untrusted by design —
installation still flows through the existing review-queue import, and
pack bytes verify against sha256 integrity at download time.
…ostics

The section graduated from a hidden pending placeholder to a real panel
(ux-gap-roadmap-13), so the shell/settings/dark-mode/runtime specs now
expect a visible, clickable nav entry, and openPendingStartupDiagnostics
clicks it directly. All 46 affected e2e tests pass.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-26T18:05:35.685132Z 7630deb PR opened
🔒 Security Review ⚠️ Failed 2026-10-27T06:08:11.790313Z
We couldn’t complete this review. Comment @codex security review to try again.
5587c41 New commits

Security findings

Advisory findings (2)

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread packages/daemon/test/im-destinations.test.mjs Fixed
…-daemon smoke

Real-daemon browser smoke (16/16) surfaced two bugs now fixed:
1. POST /im-destinations/:id/test always 404'd — the /test branch sat
   inside a regex match that excludes the /test suffix. Moved it ahead.
2. /skills/marketplace/inspect returned 503 when the runtime constructs
   no webFetch dependency; it now falls back to the global fetch while
   keeping https-only, timeout, and size-cap enforcement in the route.

scripts/real-daemon-smoke.mjs is a reusable no-mock smoke driver: with a
real daemon + 'ling ui --foreground' running, it clicks the diagnostics
panel, round-trips notification preferences, clicks the voice mic, and
exercises IM/marketplace APIs against the live daemon, with screenshots
under output/playwright/real-daemon-smoke/.
Comment thread packages/daemon/src/features/skills/marketplace-route.ts Dismissed
- Normalize five files from CRLF to LF and drop trailing whitespace so the
  pull-request whitespace gate passes.
- Sync and translate the new panel copy across all 55 locales.
- Guard the marketplace inspect route to public DNS hosts over https
  (direct-IP, loopback and internal suffixes rejected) and cover it with
  route tests; compare the full webhook URL in the IM destination test
  instead of a bare host substring.
@gansx
gansx force-pushed the feat/ux-gap-roadmap branch from 460cebe to 3cb2cd8 Compare October 27, 2026 03:30
Comment thread packages/daemon/test/im-destinations.test.mjs Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: 25ff4a9d4d

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread apps/web/src/shared/conversation/preview/ArtifactPreview.tsx
gansx and others added 3 commits October 27, 2026 12:20
…ine CSP

Interactive artifacts run scripts in an opaque-origin frame, but the frame
could still reach the loopback daemon and the network. Inject a meta CSP
(connect-src/form-action/base-uri 'none') into every previewed document at
the daemon boundary so artifact scripts stay offline, and cover the
injection in contracts and preview tests.
Comment thread packages/contracts/src/artifacts.ts Fixed
Comment thread packages/contracts/src/artifacts.ts Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: addaebfa20

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread packages/contracts/src/artifacts.ts Outdated
A substring self-check let a crafted document opt out of the offline policy.
Injection is unconditional now; repeated policies combine restrictively.
@gansx
gansx merged commit 77a2a85 into main Oct 27, 2026
15 checks passed
@gansx
gansx deleted the feat/ux-gap-roadmap branch October 27, 2026 06:27
gansx added a commit that referenced this pull request Oct 28, 2026
* feat(ci): automate translation catalogs for PRs and a daily main backstop

Source-string changes currently require authors to run the localization
pipeline by hand; skipping it fails the catalog completeness check late in
review (e.g. #599). Automate the two manual steps with the installed catalog
GitHub App:

- translate-pr-catalogs.yml: on PRs touching the en-US/zh-CN TS sources or
  additional JSON, import sources and incrementally translate all 53 target
  locales, committing catalog diffs back to the PR branch. Same-repository
  heads only (fork PRs skip), head SHA re-checked before push, and bot commits
  touch only catalogs/*.json so the workflow cannot retrigger itself.
- sync-translation-catalogs.yml: daily + dispatch backstop on main that opens
  or refreshes an automation/translation-catalogs PR and auto-merges it through
  the normal required checks, mirroring sync-provider-model-catalog.yml.
- scripts/ci/automation-pr.mjs: generalized sole-open-PR selector with
  fail-closed validation, plus workflow contract tests that execute the shell
  steps against simulated gh/git.

Design contract and plan: docs/design/translation-catalog-automation*.md

* fix(ci): install locked dependencies before importing translation sources

The importer resolves the workspace typescript dependency; fresh runners have
no node_modules. Install the pinned pnpm store (cached) in both translation
workflows ahead of the import step, and assert the ordering in the workflow
contract tests.

* fix(ci): provision pnpm before the setup-node cache and disable install scripts

setup-node's pnpm cache resolves pnpm store path, which fails before pnpm
exists; mirror ci.yml's pnpm/action-setup ordering. Lifecycle scripts from
checked-out code could persist shims through GITHUB_PATH, so install with
--ignore-scripts; the importer and translator only need module resolution.
Contract tests assert both orderings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants