Commit Graph
217 Commits
Author SHA1 Message Date
ZacharyZhang-NY a6d0a567a8 fix(ipc-credentials): use shared registerHandle and precise redactSecrets (I-02)
Two tightly-coupled hardening changes to the credential IPC module.

(1) Drop the self-built `DesktopOk/DesktopErr/ok/err/handle` helpers
that called `ipcMain.handle` directly, bypassing the trusted-renderer
check in `ipc-support.registerHandle` and the `ZodError ->
IPC_INVALID_PAYLOAD` sanitizer. The module now takes `registerHandle`
and `fail` as deps (wired from `createIpcSupport`) and imports `ok`
from `ipc-core-common`, mirroring the OAuth handler layout.

(2) Tighten `redactSecrets` to issuer-prefixed patterns only (Bearer,
`sk-`, `sk-ant-`, `sk-proj-`, AKIA access key IDs, three-segment JWTs).
The previous blanket `[A-Fa-f0-9]{40,}` and `[A-Za-z0-9+/]{48,}={0,2}`
rules were shredding legitimate diagnostic text — git SHAs, UUIDs,
Fireworks model identifiers like `accounts/fireworks/models/...`, and
any long opaque ID — into `[REDACTED-HEX]` / `[REDACTED-B64]`, which
made provider errors unreadable in the renderer.
2026-04-16 21:49:53 -04:00
ZacharyZhang-NY ff0c01fe87 fix(worker): claim workspace lock in main before enqueue (D-02)
The lock was previously claimed when the worker reported `running`, which
is after `agent.prompt` had already started streaming. Two concurrent
runs targeting the same workspace could both pass the main-side checks,
both get enqueued, and both read half-written state before one of them
lost the lock race and was cancelled mid-flight.

Move the `claimWorkspaceLock` call into `dispatchRunToWorker` so main
coordinates exclusivity authoritatively. If the lock is unavailable,
the run is finished as failed and never enqueued. The worker-side
lease-renewal path is preserved since it is a lease, not a lock.
2026-04-16 21:49:30 -04:00
ZacharyZhang-NY f86b3ddbac fix(ipc-oauth): use shared registerHandle for trust and error sanitization (I-01)
The self-built `ok/err/handle` helpers called `ipcMain.handle` directly,
which meant every OAuth IPC channel skipped the trusted-renderer check
in `ipc-support.registerHandle` and its `ZodError -> IPC_INVALID_PAYLOAD`
sanitizer. Any renderer origin could invoke these channels, and thrown
zod errors would leak the raw validator message.

Take `registerHandle` and `fail` as dependencies so callers wire in the
hardened variants from `createIpcSupport`, drop the local helpers, and
import `ok` from `ipc-core-common`. Zod inputs stay on `safeParse` to
preserve the explicit `INVALID_INPUT` code + message path.
2026-04-16 21:48:47 -04:00
ZacharyZhang-NY a1f021ff4a fix(worker): invert connector bypass default and gate on packaged build (S-01)
Previously `AGENTCOMPANY_ALLOW_UNSAFE_CONNECTOR_BYPASS !== "false"` meant
packaged builds defaulted to passing `dangerouslyBypassApprovalsAndSandbox`,
`dangerouslySkipPermissions`, `yolo`, and `--sandbox danger-full-access`
to CLI connectors, bypassing ApprovalService entirely.

Require both explicit opt-in (`AGENTCOMPANY_ALLOW_UNSAFE_CONNECTOR_BYPASS=true`)
and a non-packaged build. Packaged builds hard-refuse regardless of the env
var. Main process forks the worker with `AGENTCOMPANY_PACKAGED=<app.isPackaged>`
so the worker has an authoritative packaged signal.
2026-04-16 21:48:10 -04:00
ZacharyZhang-NY f8052c3741 refactor(scheduler): split 15s tick into 4 independent intervals
Split the single 15s setInterval in scheduler.ts (6 serial jobs) into 4
independent schedulers so a slow job no longer stalls the others:

- scheduler-heartbeat.ts (15s): wake eligible agents, CEO bootstrap,
  schedule automation trigger
- scheduler-lock-recovery.ts (60s): stale task-lock recovery and stale
  workspace-lock release
- scheduler-idle-automation.ts (60s): idle-agent automation dispatch
- scheduler-housekeeping.ts (300s): monthly budget reset, expired budget
  incident auto-close, stale review sweep, expired wakeup purge

scheduler.ts is now a thin composer exposing startAllSchedulers /
stopAllSchedulers. Bootstrap and service-graph updated accordingly.
Business logic, error isolation, and atomic actions preserved.
2026-04-16 21:47:09 -04:00
ZacharyZhang-NY 2676400e0c fix(ipc-credentials): serialize testCredential env mutations (S-03)
Pi-ai's `streamSimple`/`SimpleStreamOptions` has no per-request env
escape hatch; its Azure/AWS/GCP ADC providers read `process.env`
directly. The previous implementation wrote `extraEnv` into
`process.env` globally and relied on a `finally` after
`stream.result()` to clean up, so two concurrent `testCredential`
calls would clobber each other's env, expose the wrong credential
to in-flight streams, and on error paths fail to restore
previously-set values.

Wrap the env-mutating branch in a module-level promise chain so at
most one `extraEnv` test runs at a time, snapshot the prior value
of every key we overwrite, and restore (or delete when unset) in
`finally`. Tests that resolve to `extraEnv: undefined` bypass the
mutex entirely.
2026-04-16 21:43:44 -04:00
ZacharyZhang-NY ff08ab3e35 fix(desktop-shell-window): stop blocking main process on untrusted-link dialog
showMessageBoxSync froze the main-process event loop while the user
decided whether to open an external link, stalling agent-event workers,
IPC, and the scheduler for the duration of the dialog. setWindowOpenHandler
still returns synchronously with action: "deny"; the confirmation dialog
runs in an async continuation that only reaches shell.openExternal when
the user approves.
2026-04-16 21:42:29 -04:00
ZacharyZhang-NY f803b0b826 fix(api-server): require Origin header when no bearer token
Origin-less requests previously skipped the allowlist entirely, meaning
any process that omitted the Origin header (trivial for a non-browser
attacker) could reach the auth layer. Browsers always send Origin, so
rejecting Origin-less browser-style requests closes the bypass without
breaking agent CLIs, which authenticate with a bearer token instead.

New policy:
 - Requests with a Bearer Authorization header: Origin optional; if
   present it must be in the allowlist.
 - All other requests (including CORS preflight): Origin required and
   must be in the allowlist.
2026-04-16 21:42:04 -04:00
ZacharyZhang-NY 61caeb5f37 test(database): align with vault insecure-fallback opt-in convention
Aligns tests/unit/database.test.ts with the existing convention in
oauth-login-service/credential-resolver/credential-store tests: set
AGENTCOMPANY_ALLOW_INSECURE_VAULT=true in beforeAll so the in-memory
database test can call saveSecret without a real OS keychain.

Follow-up to aa1afd0 which removed the NODE_ENV=test/VITEST auto-enable.
2026-04-16 21:39:37 -04:00
ZacharyZhang-NY deb980448c fix(ipc-thread-handlers): drop redundant try/catch wrappers and duplicate emit
Every handler was wrapping its body in try/catch and returning fail(code,
error.message), leaking raw DB messages to the renderer and bypassing the
sanitizer in registerHandle. Removed the 14 inner try/catch shells so
errors surface through ipc-support's IPC_HANDLER_FAILED / IPC_INVALID_PAYLOAD
path. Also removed the duplicate emitEvent({ type: 'domain-changed' }) in
addThreadEvent — publishDomainChanged already emits the same event.
2026-04-16 21:37:58 -04:00
ZacharyZhang-NY 6c6cc96060 fix(agent-permissions): propagate DB errors instead of silently denying
safeGetAgent was catching all errors and returning null, causing every
permission check (canControlAgent / canManageOrganization / canRequestHire)
to silently deny when the database threw. Only swallow the 'Agent not found'
case and let real DB errors propagate up to registerHandle's sanitizer.
2026-04-16 21:37:16 -04:00
ZacharyZhang-NY 893a0ddec1 chore(preload): drop stale @planned notes on delete{Task,Goal,Project,Workspace}
Handlers for deleteTask/deleteGoal/deleteProject live in
ipc-core-task-graph-handlers.ts:166-168 (backed by
database/tasks-crud.ts and database/entity-crud.ts), and
deleteWorkspace lives at line 169 (backed by database/workspaces.ts).
The four @planned comments were misleading.
2026-04-16 21:36:55 -04:00
ZacharyZhang-NY 49df7e528e fix(release): exit after printing --help in release-cloudflare wrapper 2026-04-16 21:36:46 -04:00
ZacharyZhang-NY 734c789f50 fix(orchestration): remove one-time heartbeat cleanup from scheduler startup 2026-04-16 21:36:43 -04:00
ZacharyZhang-NY 1a57622849 fix(automation): remove silent JSON.parse fallback in executeAutomationAction 2026-04-16 21:36:41 -04:00
ZacharyZhang-NY a612ea7bea fix(communication): set searchLoading=true in setSearchQuery
setSearchQuery only incremented searchRequestId without flipping
searchLoading, so the UI could not distinguish "searching" from "no
results". Now loading flips true on non-empty query and clears
(results + loading) on empty query. setSearchResults keeps the
existing id-match logic to flip loading false on arrival.
2026-04-16 21:36:37 -04:00
ZacharyZhang-NY aa1afd0db2 fix(vault): remove NODE_ENV=test and VITEST auto-enable of insecure fallback so only explicit opt-in unlocks it 2026-04-16 21:36:29 -04:00
ZacharyZhang-NY cfe5f9ff73 fix(oauth): scope failPending to matching connectorId so cancelling one OAuth does not reject others 2026-04-16 21:36:22 -04:00
ZacharyZhang-NY d8904c88e5 docs: map existing codebase 2026-04-16 15:07:32 -04:00
ZacharyZhang-NY 1b578c111a update 2026-04-16 14:48:51 -04:00
ZacharyZhang-NY 9779c4d1ca update 2026-04-07 20:18:47 -04:00
ZacharyZhang-NY f5d4f8b705 update 2026-04-06 00:35:27 -04:00
ZacharyZhang-NY 13166fd860 Merge branch 'main' of github.com:ZacharyZhang-NY/AgentCompany 2026-04-05 23:47:58 -04:00
ZacharyZhang-NY 72157f0703 update 2026-04-05 23:47:56 -04:00
ZacharyZhang-NY 69a1139eb3 Add remote Boss workflow used by automated release script 2026-04-05 21:23:18 -04:00
ZacharyZhang-NY 9145572422 update 2026-04-05 20:14:48 -04:00
ZacharyZhang-NY 09971cabc2 Merge branch 'main' of github.com:ZacharyZhang-NY/AgentCompany 2026-04-04 17:01:28 -04:00
ZacharyZhang-NY b8dda3c8d0 update 2026-04-04 17:01:26 -04:00
ZacharyZhang-NY 42bb2f196f Tighten Linux x64 upload globs in the remote release workflow
Constraint: Linux arm64 assets and x64 assets share the same draft release transport bucket
Rejected: Broad *.AppImage/*.deb/*.rpm globs | x64 upload step collided with arm64 assets and failed the workflow
Confidence: high
Scope-risk: narrow
Directive: Keep per-architecture upload globs disjoint whenever multiple jobs share one draft release
Tested: Prior run proved packaging succeeded and isolated the failure to the x64 upload selection
Not-tested: Updated workflow dispatch before rerun
2026-04-04 16:19:37 -04:00
ZacharyZhang-NY bc878c8f93 Add remote workflow used by automated Cloudflare release script 2026-04-04 15:47:50 -04:00
ZacharyZhang-NY 67c757f481 update 2026-04-04 12:03:50 -04:00
ZacharyZhang-NYandClaude Sonnet 4.6 66158e222e update
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:02:28 -04:00
ZacharyZhang-NY 16d8426119 update 2026-03-30 21:48:44 -04:00
ZacharyZhang-NY aed312124b update 2026-03-30 16:24:29 -04:00
ZacharyZhang-NY 400417a6af Update .gitignore 2026-03-30 10:50:25 -04:00
ZacharyZhang-NY 28740faf27 update 2026-03-30 10:45:53 -04:00
ZacharyZhang-NY 6f1de8047e update 2026-03-30 00:15:21 -04:00
ZacharyZhang-NY 65e85135c1 large update 2026-03-29 14:08:15 -04:00
ZacharyZhang-NY 2ed952f19c Merge branch 'worktree-agent-afbb9437' 2026-03-28 03:26:56 -04:00
ZacharyZhang-NY 29e4f9f430 Merge branch 'worktree-agent-a8526086'
# Conflicts:
#	.planning/STATE.md
2026-03-28 03:19:28 -04:00
ZacharyZhang-NYandClaude Opus 4.6 758bc077ff fix(quick-260328-48g): fix heartbeat task duplication with Paperclip-style coalescing
- Remove self-defeating heartbeat task filter that excluded heartbeat tasks from candidates
- Add Paperclip-style task reuse: recycle existing done/in_review heartbeat tasks instead of creating new ones
- Fix status bug: new heartbeat tasks created as "todo" instead of "in_progress" so CAS checkout succeeds
- Wire one-time duplicate cleanup sweep into heartbeat scheduler startup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 03:17:17 -04:00
ZacharyZhang-NYandClaude Opus 4.6 4b5492ea34 feat(quick-260328-48g): add database methods for heartbeat task reuse and cleanup
- Add findReusableHeartbeatTask() to find most recent done/in_review heartbeat task per agent
- Add cleanupDuplicateHeartbeatTasks() to cancel old duplicates using ROW_NUMBER window function
- Add 12 unit tests covering coalescing behavior, cross-agent isolation, status filtering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 03:14:40 -04:00
ZacharyZhang-NY bc1c7aefe5 feat(quick-260327-x64): implement listSkills/syncSkills on Claude, Codex, and Gemini adapters
- Add skills.ts to Claude adapter: ephemeral mode, listClaudeSkills/syncClaudeSkills
- Add skills.ts to Codex adapter: ephemeral mode, listCodexSkills/syncCodexSkills
- Add skills.ts to Gemini adapter: persistent mode with symlink sync, listGeminiSkills/syncGeminiSkills
- Re-export skill functions from each adapter's server/index.ts
2026-03-28 00:01:39 -04:00
ZacharyZhang-NY ed4988c5aa feat(quick-260327-x64): add skill sync types and resolution utilities to adapter-utils
- Add AdapterSkillSyncMode, AdapterSkillState, AdapterSkillOrigin, AdapterSkillEntry, AdapterSkillSnapshot, AdapterSkillContext types to types.ts
- Add optional listSkills/syncSkills methods to ServerAdapterModule interface
- Export new skill types from index.ts
- Add skill resolution helpers to server-utils.ts: resolveAgentCompanySkillsDir, listAgentCompanySkillEntries, readInstalledSkillTargets, buildPersistentSkillSnapshot, readAgentCompanyRuntimeSkillEntries, readAgentCompanySkillSyncPreference, resolveAgentCompanyDesiredSkillNames, writeAgentCompanySkillSyncPreference, ensureAgentCompanySkillSymlink, removeMaintainerOnlySkillSymlinks
2026-03-27 23:59:28 -04:00
ZacharyZhang-NY 80fa4221dc feat(260327-w3o): add CEO skill instructions to prompt-builder
- Step 1: review available skills before designing org structure
- Step 3: assign skills to agents after each hire is approved
- Priority 3: check/assign agent skills before delegating tasks
2026-03-27 23:11:16 -04:00
ZacharyZhang-NY 74d31f8365 feat(260327-w3o): add 5 skill REST API endpoints for agent access
- GET /api/companies/:companyId/skills (list company skills)
- GET /api/skills/:skillId (skill detail with markdown)
- POST /api/agents/:agentId/skills (assign skill to agent)
- DELETE /api/agents/:agentId/skills/:skillId (remove skill)
- GET /api/agents/:agentId/skills (list agent's skills)
2026-03-27 23:10:31 -04:00
ZacharyZhang-NYandClaude Opus 4.6 702f560b87 feat(260327-vvv): expand CEO Team Building Phase Step 1 with workspace exploration
- Step 1 now instructs codebase exploration (ls, read key files, understand structure)
- Added company identity consideration guidance for org design decisions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 23:00:06 -04:00
ZacharyZhang-NYandClaude Opus 4.6 4bb9c5ce9f feat(260327-vvv): add codebase scan and company context to CEO kickoff task
- Kickoff task now instructs CEO to explore workspace codebase before planning
- Company name and description interpolated into both activeGoal and fallback branches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:59:45 -04:00
ZacharyZhang-NY 72848fcb00 feat(11): scan ~/.agents/skills/ and ~/.claude/skills/ for auto-import
Skills from user home directories are now auto-imported when listing
company skills. Deduplication handled by canonical key uniqueness.
Scans: ~/.agents/skills/, ~/.claude/skills/, and workspace .agents/skills/.
Cross-platform: uses HOME or USERPROFILE env var.
2026-03-27 22:49:44 -04:00
ZacharyZhang-NY 6480b7f49f fix(11): repair broken color patterns from CSS variable migration
- ChannelSidebar: replace inline color-mix style with Tailwind classes for task discussion icons
- MessageItem: replace broken priority config (color-mix inline) with Tailwind utility classes
- MessageItem: replace broken department badge hex-alpha pattern with Tailwind classes
- automation-config: restore ACCENT/LINE as hex values (used in template literal alpha suffixes)
- desktop-shell-service: set nativeTheme.themeSource to sync Windows title bar with app theme
2026-03-27 22:44:14 -04:00