- DB introspection tests: introduce local RawDb alias for casts
that poke into the private .db handle.
- IPC handler tests: introduce IpcHandler alias matching the
registerHandle signature (event + unknown args).
- selective-ipc / session-management: narrow handler and data
params to unknown or the minimum shape the code reads.
- App.tsx: replace per-field ui.navItems/ui.paletteQuery with the ui
object so the memo captures every accessed field.
- ConsoleView.tsx: add eslint-disable for the logRevision dep; it is
intentionally tracked to force ref re-evaluation.
The any type is load-bearing here: callers destructure arbitrary SQL
columns. Add an inline eslint-disable with justification instead of
propagating a typing change across all DB modules.
Migration 28 (add_snapshot_hot_path_indexes) referenced task_comments,
documents, meetings, sprints, agent_messages, activity — all tables
created by ensureOptionalColumns() which runs AFTER runMigrations() on
a fresh DB. Converted from sql-string migration to fn-based so each
index is gated by tableExists(); safe on both fresh and migrated DBs.
Also updated tests/unit/selective-ipc.test.ts exhaustive switch to
include the 7 new DesktopEvent variants added in ef90a58.
37a57d5 removed this file as an orphan, but 4 workspace packages
(adapter-utils/claude/codex/gemini) still extend it via
"extends": "../../tsconfig.base.json". Vite's esbuild transform
follows the chain at build time, so the file is load-bearing for
electron-vite build despite having no direct root tsconfig reference.
Adapt existing assertions to the current ConnectorDefinition shape:
`auth`, `provider`, and `defaultModel` are declared optional, and the
API-key envvar field is now `envKey`. Use optional chaining and coalesce
to keep the same behavioural checks passing under strict typing.
- Add required `roleLevel` to dashboard-charts and prompt-manager fixtures
so they satisfy the AgentRecord contract.
- Replace legacy "anthropic" connectorId with `claude_local` in
approval-hook fixture to match the current `ConnectorId` union.
- credential-resolver.resolve: throw explicit CREDENTIAL_INVALID when
the connector has no auth schema, and add a default branch so the
switch has a definitive return path for every auth kind
- credential-resolver api_key branch: guard definition.provider being
unset before calling pi-ai's getEnvApiKey
- cost-writer: only attempt cost lookup when definition.provider is
defined; adapter-only connectors still write an unattributed row
- oauth-login-service.start: require definition.auth to be present and
oauth kind before dispatching; captures oauthId in a local so the rest
of the flow does not re-assert the nullable chain
- ipc-credentials-handlers save: reject connectors without an auth
schema instead of crashing on property access
- ipc-credentials-handlers test: require provider and defaultModel to be
set before calling into pi-ai, returning a diagnostic result otherwise
- Expose buildSessionEntryMethods and buildCredentialMethods on
AppDatabaseBase as public readonly members so agent-runtime and
credential-store can access them via db.sessionEntries /
db.credentialsTable
- Add idempotent schema migration v32 creating session_entries and
credentials tables plus supporting indexes; uses CREATE TABLE IF NOT
EXISTS so existing profile DBs upgrade safely without destructive ops
- 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.