Commit Graph
130 Commits
Author SHA1 Message Date
Haoqing WangandGitHub 9a48d5af3a fix(hub,web): extend JWT expiration and harden visibility refresh (#442)
- Extend JWT expiration from 15 minutes to 4 hours in both auth and
  bind endpoints. 15 minutes was too short — browser timer throttling
  in background tabs prevented the scheduled refresh from firing
  before expiration, causing unexpected logouts.

- Change the visibility/focus refresh from conditional (minTtlMs) to
  forced, so returning to a backgrounded tab always re-authenticates
  regardless of remaining token TTL. This eliminates the race between
  timer throttling and token expiration.

HAPI is a self-hosted tool, so the longer token lifetime is an
acceptable security tradeoff. The auth source (Telegram initData or
CLI access token) is still validated on every refresh.

Closes #412
2026-04-11 22:03:50 +08:00
Haoqing WangandGitHub 92d368599b fix(hub): allow terminal re-registration after socket reconnect (#434)
* fix(hub): allow terminal re-registration after socket reconnect

When a web client reconnects (common in PWAs and after network
hiccups), it retains the same terminal ID but gets a new socket ID.
The previous code rejected the registration because the old entry
still existed, producing "Terminal ID is already in use".

Now the registry treats a different-socket registration for the same
terminal ID as a stale entry and cleans it up before re-registering.
Same-socket re-registration returns the existing entry (idempotent).
Terminal IDs are client-generated UUIDs so cross-client collisions
are not a realistic concern.

Closes #345

* fix(hub): skip terminal quota check on reconnect

When a stale terminal entry still occupies a slot, the per-session
and per-socket quota checks reject the reconnecting client before
register() can clean up the stale entry. Detect reconnects (same
terminalId + sessionId already registered) and bypass quota checks
so the stale entry is properly replaced in register().

* fix(hub): reject cross-session terminal ID reuse

Only allow stale-entry replacement when the existing entry belongs
to the same session. If a different session happens to present the
same terminal ID, reject it as before to prevent one session from
evicting another session's active terminal.
2026-04-11 17:40:56 +08:00
Haoqing WangandGitHub c62a1eb151 fix(cli,hub): resolve typecheck errors in codex reasoning effort (#432)
* fix(cli,hub): resolve typecheck errors in codex reasoning effort and notification test

- Cast `getModelReasoningEffort()` return (string | null) to
  `ReasoningEffort | undefined` at three call sites in
  codexLocalLauncher.ts and runCodex.ts where the narrower type is
  expected.
- Add missing `modelReasoningEffort: null` default in
  notificationHub.test.ts to satisfy the Session type contract.

These errors were introduced in 79a13d2 and have been failing CI on
main since 2026-04-10.

* fix(cli): add missing getModelReasoningEffort to test mock session

The test stub in codexLocalLauncher.test.ts was missing the
getModelReasoningEffort method added in 79a13d2, causing runtime
TypeError in CI.
2026-04-11 16:44:06 +08:00
weishu 79a13d26c6 Fix Codex reasoning effort resume and updates 2026-04-10 11:50:03 +08:00
MimoandGitHub 0e1b653d43 feat: display background task count in status bar (#421) 2026-04-09 20:17:12 +08:00
Junmo KimandGitHub ea09663cdc refactor: organize model definitions and flavor capabilities into dedicated modules (#400) 2026-04-05 22:49:29 +08:00
4ffcb4cfdb fix(hub): raise maxRequestBodySize so file uploads work (#397)
* fix(hub): raise maxRequestBodySize so file uploads work

The Bun server inherited maxRequestBodySize from Socket.IO's default
maxHttpBufferSize (1 MB).  The upload endpoint sends files as base64
in JSON, so any image > ~750 KB was silently rejected before reaching
the route handler.  The frontend allows 50 MB uploads.

Raise the limit to at least 100 MB to accommodate 50 MB files with
base64 encoding overhead (~33%).

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix(hub,web): fix file uploads — raise body limit, lower max size, show errors

Three changes:

1. hub/server.ts: Bun's maxRequestBodySize inherited Socket.IO's 1 MB
   default, silently rejecting any upload. Raise to 10 MB.

2. hub/routes + web/attachmentAdapter: lower MAX_UPLOAD_BYTES from
   50 MB to 5 MB (realistic for images; 5 MB base64 ≈ 6.7 MB body,
   fits within the 10 MB server limit).

3. web/AttachmentItem: show "Upload failed" text and strike-through
   filename on error, instead of just a tiny icon.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix(hub): keep 50MB upload limit, size maxRequestBodySize to match

Bot review correctly flagged that lowering MAX_UPLOAD_BYTES to 5 MB
regresses the documented 50 MB limit. Revert to 50 MB and calculate
maxRequestBodySize properly: 50 MB × 4/3 (base64) + 1 MB (JSON
overhead) ≈ 68 MB.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

---------

Co-authored-by: HAPI <noreply@hapi.run>
2026-04-05 13:21:31 +08:00
f970072f66 fix(hub): add PATCH to CORS allowMethods so session rename works (#391)
The rename endpoint uses PATCH /api/sessions/:id, but the CORS
middleware only allowed GET, POST, DELETE, OPTIONS. Browsers send a
preflight OPTIONS request for PATCH; without it in allowMethods the
preflight fails and the request never reaches the handler, causing
"Failed to rename" in the web UI every time.

via [HAPI](https://hapi.run)

Co-authored-by: HAPI <noreply@hapi.run>
2026-04-05 12:32:53 +08:00
Junmo KimandGitHub 4eb88c5d7e feat(gemini): support mid-session model change (#379) 2026-04-01 11:15:11 +08:00
godot42xandGitHub cbd1f78d2d fix: 修复Windows下路径解析导致mkdir权限错误 (#369) 2026-03-27 05:32:51 +08:00
a200fe9628 feat(claude): add effort setting parity with model across stack (#353)
Co-authored-by: Xiaoyi <xiaoyizhang@microsoft.com>
2026-03-24 21:15:48 +08:00
Haoqing WangandGitHub 24834fbef4 fix(hub): handle Telegram bot polling errors instead of silently swallowing them (#350) 2026-03-24 17:56:50 +08:00
xyzhang626andGitHub b6ecdc7b44 fix(hub): pass resumeSessionId when resuming session (#337) 2026-03-22 06:49:14 +08:00
lifu963andGitHub 895654ddf6 fix(terminal): prevent infinite reconnect loop on Windows hosts (#336) 2026-03-21 21:45:40 +08:00
Junmo KimandGitHub d76b1a6ac0 refactor: introduce model-agnostic agent interfaces (#323) 2026-03-20 08:45:32 +08:00
ROOOOandGitHub cb09f0b898 feat: add codex reasoning effort option (#297) 2026-03-17 22:55:55 +08:00
weishu 34f931ef59 remove codex mcp backend 2026-03-16 21:50:09 +08:00
weishu 16829b7c78 Add support for codex plan mode 2026-03-16 20:48:39 +08:00
weishu 329d28a93c remove , using instead 2026-03-16 18:29:09 +08:00
weishu 02c8e12e80 unify model selection 2026-03-16 18:29:09 +08:00
4716d315b7 feat: improve spawn error handling and reporting across full stack (#249)
* feat: improve spawn error handling and reporting across full stack

- Return error result instead of throwing in apiMachine spawn handler
- Add lastSpawnError field to RunnerState for persistent error tracking
- Add error awaiter system for early process exit/error detection before webhook
- Build detailed webhook failure messages with exit code, signal, and stderr tail
- Report spawn outcomes to hub via runner state updates
- Handle more spawn result types in rpcGateway with better error messages
- Display runner last spawn error in web UI (NewSession & SpawnSession)
- Extract shared formatRunnerSpawnError utility to avoid duplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): narrow spawnResult type check to fix TS2339 error

Use `type === 'error'` instead of `type !== 'success'` to properly
narrow the discriminated union, allowing TypeScript to infer errorMessage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:55:50 +08:00
06b71dbe98 feat: Add Claude Code Agent Teams support (#258)
* feat: Add Claude Code Agent Teams support

- Add TeamState schemas and types for team collaboration
- Extract team state from TeamCreate, SendMessage, Task tools
- Add database migration V3→V4 for team_state storage
- Add TeamPanel component to display team members, tasks, messages
- Add team tool icons and presentation rules
- Support vite proxy configuration via VITE_HUB_PROXY env var

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix: Add timestamp protection for team_state updates

Prevent old messages from overwriting newer team state by checking
team_state_updated_at before updating.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix: Extract team tasks from Task/TaskCreate/TaskUpdate tools

- Enhance processTaskToolWithTeam to also generate task entries from
  the Task tool's description field when spawning teammates
- Add processTaskCreate handler for TaskCreate tool calls
- Add processTaskUpdate handler for TaskUpdate tool calls
- Register both new tools in the extraction switch statement

This fixes the gap where the Tasks section in TeamPanel could never
populate because team task data was not being extracted from the
message stream.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix: Skip orphan TaskUpdate without title to prevent schema validation failure

When TaskUpdate arrives before TaskCreate (message ordering), skip inserting
incomplete tasks that lack required title field, preventing entire teamState
from being dropped by schema validation.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* test: Add unit tests for orphan TaskUpdate handling

Verify that applyTeamStateDelta correctly skips inserting tasks without
title field (orphan TaskUpdate) while still allowing normal task creation
and updates to existing tasks.

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

---------

Co-authored-by: tfq <tfq@gmail.com>
Co-authored-by: HAPI <noreply@hapi.run>
2026-03-08 11:26:11 +08:00
JlovecandGitHub ef3328f48f fix(cli): support project slash command completion (#245)
Add project-level slash command discovery with recursive nested command scanning, pass workingDirectory through slash-command handlers, and align hub/web source unions to include project commands.
2026-03-05 12:50:59 +08:00
Mao MrandGitHub c9be2894ac feat(cursor): add support for Cursor Agent CLI integration (#236)
* feat(cursor): add support for Cursor Agent CLI integration

- Introduced new command `hapi cursor` to start Cursor Agent sessions.
- Added functionality for resuming sessions and managing permission modes.
- Updated documentation to include Cursor Agent usage and installation instructions.
- Enhanced existing codebase to accommodate Cursor as a recognized agent flavor.
- Implemented local and remote session handling for Cursor Agent.

This update expands HAPI's capabilities by integrating support for the Cursor Agent, allowing users to leverage its features alongside existing agents.

* Remove TODO.md file as it is no longer needed following the integration of Cursor Agent CLI support. This cleanup helps streamline project documentation and reflects the completion of the associated tasks.

* feat(cursor): implement remote mode and fix --hapi-starting-mode

- Consume --hapi-starting-mode in cursor command (do not forward to agent)
- Implement cursorRemoteLauncher: spawn agent -p with stream-json, --trust
- Add cursorEventConverter for NDJSON parsing (system/assistant/tool_call/result)
- Multi-turn via --resume session_id
- Update docs: cursor supports both local and remote modes

Made-with: Cursor

* fix: type error

* fix(cursor): address PR review - model UI, sessionId metadata, duplicate flags

- HappyComposer: use isClaudeFlavor for model mode (cursor has no model modes)
- cursorLocalLauncher: call onSessionFound for resume so cursorSessionId in metadata
- cursorCommand: do not forward parsed flags to cursorArgs (avoid duplicates)

Made-with: Cursor
2026-03-03 10:02:47 +08:00
LihengwannaflyandGitHub 1942f088ff fix(sync): add SSE heartbeat and alive status (#223) 2026-02-28 01:46:21 +08:00
weishu fb9abc18d4 feat: Add directory tree tab to session files 2026-02-06 20:18:46 +08:00
weishu 0ceda16160 refactor: extract access type definitions into shared module 2026-01-29 15:54:59 +08:00
weishu 70b5c22c8f feat: support opencode 2026-01-29 10:34:57 +08:00
weishu aef4da9ea9 docs: update cli, hub, and web README files with new features and configuration
- cli/README.md: Remove non-existent runner commands, add codex resume and worktree config
- hub/README.md: Document auto-generated CLI_API_TOKEN, add session/machines/events endpoints and push notifications
- web/README.md: Add settings and terminal routes, terminal and voice assistant sections
- docs/guide: Fix broken anchor link and add terminal FAQ entry
- AGENTS.md: Add new source directory references
2026-01-27 20:46:39 +08:00
weishu 37e10a831b feat: rename server package to hub
Rename the `server/` directory to `hub/` and update all references
across CLI, docs, web, and workspace configuration.
2026-01-27 19:51:21 +08:00