Commit Graph
15 Commits
Author SHA1 Message Date
ZacharyZhang-NY 97033dfabd update 2026-04-21 12:44:33 -04:00
ZacharyZhang-NY 88a1f8b334 refactor(connectors): drop dead CLI command field after pi-mono migration
The CLI-adapter era `connector.command` field became vestigial once every
provider dispatch went through pi-ai. The schema still required a non-empty
command, so onboarding saveConnector silently rejected every Pi Mono row
(which carries an empty default). Remove the field from the payload chain
(renderer → IPC schema → DB CRUD → run dispatch → worker job), narrow
RunJob.taskId to match EnqueueRunPayload, and drop the dead helper plus
its test. Schema column stays NOT NULL for DB compatibility; seedConnectors
writes a literal empty string so no migration is needed.
2026-04-18 23:09:59 -04:00
ZacharyZhang-NY d75bfd5851 refactor(model-pool): scope disabled-models by company; cascade on delete (v42)
The per-connector "enabled/disabled model" settings lived under a
global key in the settings key-value table
(`disabled_models:${connectorId}`). No company dimension. Deleting a
company left the pool choices behind, and creating a new company
silently inherited them — the visible symptom was "onboarding's team-
model configuration survives company deletion and pollutes the next
company's CEO model list."

Root fix, not a cleanup hook: the storage becomes a real relational
table with `(company_id, connector_id)` primary key and an
`ON DELETE CASCADE` FK from `companies`. Company deletion wipes pool
config by construction; no cleanup step in `deleteCompany()` can
drift.

Schema (migration v42):
- CREATE TABLE connector_model_pool_settings (company_id, connector_id,
  disabled_models_json, updated_at), PK (company_id, connector_id),
  FK companies(id) ON DELETE CASCADE.
- Drop every `settings.disabled_models:*` key — these were the bug's
  residue; there is no right company to attribute them to, so the
  migration clears them. Users re-select on next onboarding.

API surgery — every reader/writer now takes companyId:
- db.getDisabledModels(companyId, connectorId)
- db.setDisabledModels(companyId, connectorId, models)
- db.hasModelPoolSettings(companyId, connectorId)
- connector-model-policy: getConnectorModelPolicy(deps, companyId,
  connectorId); validateConnectorModelSelection(deps, companyId,
  connectorId, model)
- model-dispatch: listEnabledModels(companyId, deps);
  pickModelForAgent resolves companyId from agent.companyId
- orchestration heartbeat/task-runner/turn-context/run-dispatch pass
  the agent's or run's companyId through to the policy deps
- IPC schema: connectorDisabledModelsSchema gains companyId; new
  connectorModelPoolQuerySchema pairs companyId+connectorId for reads

Onboarding becomes commit-on-launch:
- useConnectorModelSelection no longer persists via IPC during
  onboarding. Toggles mutate local state; it exposes `poolSelections`
  to the wizard.
- bootstrapOnboardingSchema gains connectorPoolSelections. The
  onboarding service saves the company first, then persists each
  per-connector disabled list scoped to the new company id — CEO
  model validation runs against the company's freshly-persisted pool,
  not some stale global.
- IPC setConnectorDisabledModels now requires companyId; the only
  consumer was onboarding, which no longer calls it at all.
- Main-side listConnectorModels returns the raw provider catalog
  (no pool filtering), since that IPC is used from onboarding where
  no company exists yet; pool filtering happens at dispatch time.

saveConnector IPC drops the per-company pool validation — connector
config is a global hint, company-scoped enforcement belongs at run
dispatch where the company is known.

Tests: 603/603 green. Typecheck clean. Integration tests rewritten
to set the pool via connectorPoolSelections on bootstrap input, not
a pre-bootstrap global setDisabledModels call.
2026-04-18 22:14:09 -04:00
ZacharyZhang-NY c83d670050 ui(onboarding): flat tab navigation + fix vertical-stacked button text
Onboarding was a 7-step linear wizard, same information hierarchy as
Settings but behaving like a modal. Replace with the SettingsShell tab
pattern: one row of six tabs (nodecheck / providers / company /
modelpool / executionmode / mission), free navigation, per-tab
completion ticks derived from the wizard's own validation rules.

Sub-fixes on the same pass:
- ActionButton: add whitespace-nowrap + shrink-0 so "选择" never
  stacks vertically on narrow containers. Global — every caller gets
  the correct behavior
- CompanyStep: CEO Runtime Provider/Model go vertical (space-y-3
  instead of grid-cols-2) so long names like "Fireworks AI" /
  "Kimi K2.5 Turbo Preview 0911" stay readable; workspace-path Input
  wrapped in min-w-0 flex-1 container so it yields, not the button
- MarkdownBody: render react-markdown in chat bubbles (was plain text)

i18n: added onboarding.stepsAria for the tablist label.
2026-04-18 21:38:11 -04:00
ZacharyZhang-NY c71d033b0c refactor: prune dead IPC surface and orphaned modules
Drop code that nothing consumed. Verified by full renderer+shared grep:
every removed channel had zero callers via window.agentCompany.* and
zero references from desktop-api types. No backend internal use either —
the database/API-server layers keep their methods, only the IPC exposure
goes.

Removed IPC handlers (26 total):

  Thread CRUD surface (12) — writes happen inside the backend
    createThread, listThreads, addThreadEvent,
    setThreadWaitState, resolveThreadWaitState,
    addParticipant, removeParticipant, listParticipants,
    subscribeThread, unsubscribeThread,
    listSubscriptions, listSubscribedThreads
    (kept reads: getThread, listThreadEvents, listThreadWaitStates)

  Half-implemented features (13)
    saveSecret, listComments, getAgentMetrics, getApiPort,
    listWakeupRequests, listAgentMessages, autoAssignTask,
    listRunEvents, recoveryDismiss,
    getHeartbeatPolicy, setHeartbeatPolicy,
    getRuntimeState, setRuntimeState

  Whole vertical slice: openConnectorAuthTerminal
    IPC handler + channel + preload + DesktopApi type +
    connector-auth-service function + useConnectorCallbacks
    handleLoginConnector + OnboardingContext.onLoginConnector +
    OnboardingWizard wiring. Pi-mono has no CLI auth flow;
    the no-op that "returned false for legacy UI compatibility"
    had no legacy UI left.

Orphaned modules (zero importers in repo):
  src/main/runtime-env.ts
  src/main/database-stale-recovery.ts

Dead schema files (only referenced by their own barrel re-export):
  schemas-participants, schemas-subscriptions, schemas-heartbeat,
  schemas-run-events, schemas-runtime-state, schemas-wakeup

Renderer leftovers:
  .activity-row-enter CSS + its two unreferenced keyframes
  5 orphan i18n keys (app.console, app.refresh, app.expand,
  activity.timeline, auto.trigger) left over from earlier feature
  deletions

Also update two unit tests that mocked openConnectorAuthTerminal in
the RegisterCoreHandlersDependencies pick.
2026-04-17 22:38:10 -04:00
ZacharyZhang-NY 5547c29491 update 2026-04-17 14:03:56 -04:00
ZacharyZhang-NY 7fc707ab8c fix(onboarding): stabilize connector-model state so native <select> stays open
The CEO-runtime model dropdown (and the team-model pool) collapsed the
instant a user clicked to open it whenever the app received a background
snapshot refresh. Root cause:

  useEffect(executionReadyConnectors, ...)
    → loadModels() loads catalog for every ready connector
    → setConnectorModelsById(Object.fromEntries(entries))
      — always a brand-new object reference, even if the catalog
        returned from the IPC is byte-identical to the previous load
    → connectorModels useMemo picks up a new reference
    → modelOptions useMemo picks up a new reference
    → <Select> re-renders its options children
    → Chromium's native <select> treats DOM mutation of <option>
      children as "popup stale" and closes the dropdown.

Because snapshot refreshes fire on every domain-changed event
(credentials-changed, run-status, heartbeat-status, etc.), the user
effectively could not hold the dropdown open long enough to pick a
model.

Fix: structurally compare the freshly-loaded catalog against the
previous state and bail out of setState when the shape is identical
(same connector ids, same per-connector model lists in order, same
id/label/enabled flags). Same guard on the error-path reset so an
already-empty map does not trigger a re-render either.

typecheck 0 / lint 0-0 / test:unit 508/508 / build 0-0.
2026-04-17 10:28:19 -04:00
ZacharyZhang-NY 9b45b12508 fix(onboarding): drop "Default" sentinel from model picker; auto-select real model
The CEO-runtime model dropdown on the Company onboarding step rendered
a {value:"", label:"默认 / Default"} sentinel as the first option, a
holdover from the adapter era when "" meant "let the connector pick".
Under pi-mono every connector carries a defaultModel and every run
must bind a concrete model id, so the sentinel is now misleading —
picking it left selectedModel empty and the wizard would advance
without a valid model.

- CompanyStep: drop the sentinel from the options array; the dropdown
  now shows only real models (or a single "Loading..." entry while
  the per-connector fetch is in flight).
- useConnectorModelSelection: when the connector's current model is
  not enabled, auto-select the connector's defaultModel if enabled,
  otherwise the first enabled model. An empty enabled list still
  falls back to "" so the CompanyStep hint UI behaves correctly.

Result: Fire Pass now shows "Kimi K2.5 Turbo (Fire Pass)" as the
sole option (pre-selected). Every other connector picks its catalog
default up-front.

typecheck 0 / lint 0-0 / build 0-0 / test:unit 508/508.
2026-04-17 09:54:46 -04:00
ZacharyZhang-NY 7fdd3c16bf feat(renderer): rewrite providers UI on pi-mono catalog shape
Onboarding ProvidersStep now reads the 26-entry CONNECTOR_CATALOG and
renders featured connectors (claude-pro, openai-codex, anthropic, openai,
amazon-bedrock) up front with a collapsible advanced list for the
remaining 21. Each auth kind gets a dedicated card component: OAuth
button flow, inline API-key form, and a cloud deep-link to Settings.
Delete legacy Claude/Codex/Gemini hardcoded cards and the compatible-API
slot rotation. Swap ModelManagement Settings panel for the new
ProvidersPanel driven by credentialsList IPC.
2026-04-17 02:16:35 -04:00
ZacharyZhang-NY 75022f82c5 refactor(renderer): route all Phosphor icon imports through ui/icons barrel
Create src/renderer/components/ui/icons.ts as the single re-export point
for every Phosphor icon the renderer touches, then rewrite the 95 files
that previously imported directly from "@phosphor-icons/react" to pull
from the relative-path-to-barrel instead. The TitleBar commit earlier
in this series already used ui/icons; this commit extends the pattern
to the rest of the renderer.

Benefits now wired in:
  - one location where bundle tree-shaking can be reasoned about,
  - typos like Briefcase vs BriefCase show up against a finite list,
  - re-theming or swapping icon sets is a one-file edit,
  - a lint rule that flags raw @phosphor-icons/react imports can be
    added later without mass-rewriting call sites.

The barrel also re-exports the `Icon` type so call sites that type
icon props against the Phosphor component type work unchanged.

Test count stays at 363 passing; typecheck stays at 156 errors.
2026-04-16 23:37:35 -04:00
ZacharyZhang-NY f1dd9786e5 onboarding: remove AsciiAnimation decoration and 'by ELYDORA' signatures (P1-17, P1-18); move hero-drift keyframes to global CSS (P3-60) 2026-04-16 23:01:11 -04:00
ZacharyZhang-NY 1b11b53f84 onboarding: extract OnboardingStep shell (P1-11); eliminate 6 copies of motion+header chrome 2026-04-16 23:00:01 -04:00
ZacharyZhang-NY de77f5f38e refactor(onboarding): replace 50-prop drilling with OnboardingContext
OnboardingStepPanel previously forwarded ~50 props to seven step
components, so adding a single wizard field meant touching four layers.
Introduce a renderer-local React Context (OnboardingProvider /
useOnboarding) that carries all wizard state and actions (connectors,
node status, company inputs, model selection, execution mode, mission,
launch summary, locale, t, error/loading). Step panels now receive only
their navigation callbacks (onContinue / onBack / onLaunch / onFinish)
and read everything else via useOnboarding(). CompanyOnboarding wraps
the step panel tree in OnboardingProvider with a memoised value.

Business logic is unchanged: each onContinueFrom* transition, the
bootstrap call, and the welcome-step branch remain exactly as before;
this refactor only moves the data-passing mechanism.
2026-04-16 22:11:45 -04:00
ZacharyZhang-NY 183f22e922 fix(onboarding): derive step counter from STEP_ORDER
All six step panels previously hard-coded "X / 5" or "X / 6" in their
header captions, which drifted out of sync with the 7-step STEP_ORDER in
OnboardingHero. Export STEP_ORDER / TOTAL_STEPS / getStepNumber from
OnboardingHero and consume them in every step so the counter is always
the single source of truth.
2026-04-16 22:03:57 -04:00
ZacharyZhang-NY 9145572422 update 2026-04-05 20:14:48 -04:00