- Add PiOAuthProviderId literal type covering pi-ai's built-in OAuth
providers (anthropic, openai-codex, github-copilot, gemini-cli,
antigravity)
- Add optional ConnectorDefinition fields: provider (pi-ai provider id),
auth (ConnectorAuth with kind/type/provider/oauthId/envKey), and
onboardingFeatured
- Decorate built-in CONNECTORS (codex_local, claude_local, gemini_local,
claude-compat slots) with their pi-ai provider id, auth schema, and
onboarding flag so credential-resolver and oauth-login-service can
dispatch without changing execute/module wiring
- Re-export CONNECTORS, findConnectorDefinition, and
listFeaturedOnboardingConnectors from main/connectors so consumers
(including tests) import from a single module
- Add IPC_CHANNELS entries for credentials list/save/remove/test and
oauth start/cancel/prompt/manual-code
- Extend DesktopEvent union with oauth:*, credentials-changed, and
agent-event variants used by pi-mono runtime and settings UI
- Extend DesktopApi CredentialsApi with listCredentials / saveCredential
/ removeCredential / testCredential and OAuth submit helpers
Adds ~40 automation.ruleEditor.* and automation.workflowEditor.* keys
to en.ts + zh.ts (labels, placeholders, error messages, action labels).
RuleFormModal and WorkflowFormModal now route every hardcoded English
string through useT(), including validation errors and modal titles.
Closes remaining Z-B i18n work after the prompt-builder locale
dispatch (cf92e0c), dept-keywords typing (a78bdb9), and sidebar/
formatters/notification/skills i18n landed earlier.
Replaces Record<string, string[]> with Record<DepartmentId, string[]>
so future edits to the department taxonomy trigger TS errors for any
keyword map that drifts. Cast at the lookup site reflects the fact
that agent.department is a free-form string column that may hold
legacy or custom values.
Split each prompt section into parallel .en.md/.zh.md bundles (sops, api-docs,
ceo-modes, department-guidelines) and mirrored messages/{operating,system}-{en,zh}.ts
modules for the inline identity/culture/rules text that had stayed as hard-coded
English template literals. Every loader now resolves a locale via a single
shared helper so CEO and IC prompts come out fully Chinese when locale=zh and
fully English otherwise, removing the need for the trailing "请记住:全程使用中文"
language reminder.
- New src/main/prompt-builder/wake-reasons/en.ts: WAKE_REASONS record of
{ title, steps(vars) } entries + renderWakeReason() formatter that
numbers the steps and composes the final block
- buildTaskPrompt in prompt-builder/index.ts collapses 100-line inline
reasonMap into a single renderWakeReason call
- index.ts shrinks from 161 to 77 lines; each wake reason's semantic
content (title text + numbered action steps + embedded curl hints)
preserved verbatim
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.
- operating-instructions.ts buildDepartmentSection: replace 120-line
if/else chain with a department-to-markdown lookup table
- New src/main/prompt-builder/department-guidelines/ contains:
engineering, finance, hr, marketing, sales, customer_support, operations
- Each file uses {{companyId}} placeholder, substituted at render time
- operating-instructions.ts trimmed from 384 to 285 lines while
preserving every guideline verbatim
SkillsSection had nine hardcoded English strings (header, filter
placeholder/aria-label, empty-state copy, button labels). Move them to
skills.* keys in en.ts/zh.ts and swap the component to useT().
Moves skill, budget-enforcement, and session-management service
construction to the top of service-graph init(), so the three
getOrCreate* getters are pure readers that throw if called before
init. This also fixes a duplicate-allocation bug in the orchestration
listRuntimeSkillEntries closure, which was building a second
SkillService instance instead of reusing the shared one.
The outer getOrCreate* API surface stays intact for
main-runtime-support.ts callers. The teardown setTimeout(app.exit,
3000) is left in place because worker CLI child processes keep the
event loop alive; replacing it needs a full Disposable chain refactor
that conflicts with in-progress pi-runtime integration work.
The original tests/integration/autonomous-chain.spec.ts was ~1400 lines
and 50 KB, covering 19 describe blocks across 10 orthogonal scenarios.
Physically extract each describe (or closely related group) into its
own file inside tests/integration/autonomous-chain/ so each file stays
under the project's 500-line ceiling and failures point at the
scenario that regressed.
Shared beforeEach / afterEach / createAgent / buildCtx helpers move to
autonomous-chain/shared-setup.ts, which exposes installSharedSetup() as
a factory that each spec calls at module load. The tests themselves
are moved byte-for-byte; only module-level references (`db`,
`companyId`, `workspaceId`, `tempDirs`) are rewritten to go through
the shared handle. No assertions, it() calls, or behavior are changed.
Split layout:
role-detection.spec.ts — Step 1: CEO role detection
ceo-phased-prompts.spec.ts — Step 2: phased prompts + approvals
wakeup-queue.spec.ts — Step 3: deferred wake queue
approval-decisions.spec.ts — Step 4: hire approval decisions
task-propagation.spec.ts — Step 5: task/comment wake propagation
run-failure.spec.ts — Step 6: run failure escalation
crash-recovery.spec.ts — Step 7: worker crash recovery
wake-reason.spec.ts — Step 8: wake reason injection
e2e-flows.spec.ts — full-chain + review-fix regressions
automation-messages.spec.ts — automation/messages/assignment/workflows
Test count stays at 363 passing; typecheck stays at 156 errors.
- Split 366-line api-section.ts into 11 category markdown files under
src/main/prompt-builder/api-docs/ (header, agent-control, tasks,
goals-projects, approvals, messages, files, knowledge, meetings,
agents, sprints)
- api-section.ts reduced to ~45 lines: imports each section via ?raw,
substitutes {{apiUrl}}/{{companyId}}/{{agentId}}/{{runId}}/{{connectorIds}},
joins sections and appends social media addendum
- Every endpoint signature, body schema, and curl example preserved
verbatim so LLM instruction surface is unchanged
Splits the 391-line bootstrapApplication god function into a thin
orchestrator plus 7 focused modules under src/main/bootstrap/:
prepare-logger, prepare-database, prepare-services (service graph +
ipc wiring), wire-api-server (14-callback dictionary), recover-
scheduled-posts, run-startup-health-checks, recover-interrupted-tasks
(crash notification + clean-shutdown task resumption). Original
startup order, before-quit cleanup, and error handling are preserved;
the entry file drops to 153 lines.
BudgetBar and ConfirmDelete were only sitting in organization/helpers.tsx
but have no organization-specific behaviour. Move them under
components/ui/ and keep the old exports as re-exports so existing
importers continue to resolve. HeartbeatSection stays in helpers.tsx
because it owns agent-specific heartbeat IPC.
RunCenter had three useEffects juggling log-chunk loading, tailing, and
older-chunk fetches. Move the whole lifecycle into useRunLogs, which
uses a single effect + AbortController to scope every IPC call to the
current run and pauses polling while document.hidden.
Changes the AppDatabaseBase module slots (tasks, agents, runs, ...)
from protected to public readonly so new call sites can reach them
directly as db.tasks.x / db.agents.x. The 156 pass-through methods on
AppDatabase remain untouched, so all existing callers keep working;
this is the first step of a two-part migration to eventually drop
the pass-through layer.
P3-56 (renderer): the maximized-state button used a custom 3-rect SVG to
render the 'restored window' glyph while the minimize and close buttons
used Phosphor icons. Swap the SVG for Phosphor's Copy icon so all three
titlebar buttons share the same icon family and weight, and the visual
bundle no longer carries a one-off raster-like SVG block.
Split the flat 134-method DesktopApi interface into 12 domain
sub-interfaces (companies, agents, tasks, runs, approvals,
communication, threads, credentials, skills, budget, automation,
window) under src/shared/contracts/desktop-api/. desktop-api.ts
now intersects them to preserve the exact external flat shape;
window.agentCompany consumers and preload wiring are untouched.
Adds an inline comment partition and typed PROFILE_LEVEL_KEYS /
COMPANY_SCOPED_KEYS constants on ProfileSnapshot so callers can
reason about which fields survive a company switch. Shape is
unchanged; renderer consumption is unaffected.
Break the 281-line kitchen-sink schemas-misc.ts into 12 domain modules
(badges, automation, budget, wakeup, config-revisions, run-events,
agent-permissions, heartbeat, runtime-state, threads, participants,
subscriptions). schemas-misc.ts now re-exports the domain barrel so
existing imports keep working. Adds direct exports to contracts.ts for
new code to pull from the narrower modules.
P3-56: three call sites repeated the same 'lookup → fall back to
new → set if missing' dance for session stores. The duplication hid the
fact that the fallback allocation in the second and third sites could
be wasted when the entry already existed. Extract a single
getOrCreateStore helper that does one map lookup, one conditional
construction, and always returns the cached instance.
Introduce goal-form/ and project-form/ directories each holding a
single shared shell that handles both create and edit modes via a
discriminated mode prop. The existing GoalCreator/GoalEditor and
ProjectCreator/ProjectEditor become thin wrappers that forward props
to the shared shell, eliminating duplicated state, JSX, and save/
delete handlers across the four files.
- P3-52: replace 5-deep if-chain in deriveEscalationWakeTrigger with two
lookup maps (status takes precedence over rule trigger), which removes
the cognitive overhead of reading the chain and makes the two inputs'
roles explicit.
- P3-53: rewrite the Windows-only curl warning as platform-neutral
guidance that matches the surrounding examples. The old text said
'prefer fetch on Windows' while the doc showed curl POSTs everywhere;
the new text recommends fetch universally and explains when the curl
temp-file pattern is needed.
3 code paths in desktop.smoke.spec.ts used bare `return` when fixtures
were unavailable (runtime not configured, too few model toggles), which
caused the test to silently pass without exercising the real flow.
Replace with `test.skip(true, reason)` so Playwright reports the skip
and surfaces the missing precondition.
aria-label/title now use app.hideConsole/app.showConsole i18n keys; the
grid transition timing function moves from inline style into an
ease-[cubic-bezier(...)] utility.