Commit graph

967 commits

Author SHA1 Message Date
Jiayuan Zhang
606bcd31f4
Merge pull request #182 from multica-ai/forrestchang/speed-up-ci-build
ci: parallelize CI jobs and add turbo cache
2026-02-15 02:14:46 +08:00
Jiayuan Zhang
1a85cc104a fix(ci): use pnpm --filter for lint instead of turbo
turbo lint fails for all packages due to eslint binary resolution
issues. Fall back to pnpm --filter which handles node_modules/.bin
PATH correctly. Scope matches original CI (web + desktop).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:09:47 +08:00
Jiayuan Zhang
418282da15
Merge pull request #183 from multica-ai/forrestchang/optimize-office-skills
refactor(skills): deduplicate office module and merge PDF scripts
2026-02-15 02:05:04 +08:00
Jiayuan Zhang
97270de025 chore: add dependabot for automated dependency updates
Configure weekly npm and GitHub Actions dependency updates. Groups
dev and production dependencies separately for easier review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:03:35 +08:00
Jiayuan Zhang
8c51cf9f9a ci: add test step to CI pipeline
Add test task to turbo.json and include it in the build-and-typecheck
job. Turbo handles the dependency graph: builds deps first, then runs
typecheck and test in parallel for each package.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:03:33 +08:00
Jiayuan Zhang
1140f09632 refactor(skills): merge check_fillable_fields into extract_form_field_info
The 12-line check_fillable_fields.py was a subset of
extract_form_field_info.py. Add a --check flag to the latter and
remove the standalone script. Update forms.md reference accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:32:32 +08:00
Jiayuan Zhang
7fdd0dbd3d chore: add __pycache__ to gitignore and remove committed cache
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:32:24 +08:00
Jiayuan Zhang
2727ecd803 ci: parallelize jobs and add turbo cache persistence
Split single CI job into parallel lint + build-and-typecheck jobs.
Add turbo cache via actions/cache for faster subsequent runs.
Use single turbo invocation for build+typecheck to optimize task
scheduling. Add concurrency group to cancel stale PR runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:32:19 +08:00
Jiayuan Zhang
4caa038469 chore(turbo): remove ^lint dependency for parallel lint execution
Lint tasks don't need dependencies to be linted first. Removing the
^lint dependency lets turbo run all lint tasks in parallel. Also adds
eslint config files to inputs for correct cache invalidation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:32:13 +08:00
Jiayuan Zhang
6234ba6139 refactor(skills): deduplicate office/ module across docx, xlsx, pptx
Move the shared office/ directory (pack/unpack, validators, schemas,
soffice wrapper) to skills/_shared/office/ and replace the three
identical copies with symlinks. Update skill loader to dereference
symlinks during copy to managed directory, and skip _-prefixed
directories in the bundled skills scan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:31:53 +08:00
Jiayuan Zhang
e08a1e8e89
Merge pull request #181 from multica-ai/forrestchang/dev-config-isolation
feat(dev): isolate dev:local data and workspace directories
2026-02-15 01:27:31 +08:00
Jiayuan Zhang
1bfd206217
docs: add architecture and module diagram (draw.io) (#180)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:09:26 +08:00
Jiayuan Zhang
af7deb5a02 feat(scripts): add dev:local:archive to snapshot dev data for debugging
Archives ~/.super-multica-dev and ~/Documents/Multica-dev into
~/.super-multica-dev-archives/<timestamp>/ before cleaning, so the
state can be fed to AI for post-mortem analysis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:58:39 +08:00
Jiayuan Zhang
9e40e8ca76 chore: update reset scripts and docs for dev data directory
- dev:desktop:reset now cleans both ~/.super-multica and ~/.super-multica-dev
- reset-user-data.sh handles dev directory
- .env.example documents SMC_DATA_DIR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:39:25 +08:00
Jiayuan Zhang
ca8c8e5e9c feat(scripts): isolate dev:local data and workspace directories
Sets SMC_DATA_DIR=~/.super-multica-dev and
MULTICA_WORKSPACE_DIR=~/Documents/Multica-dev for gateway and
desktop processes in dev:local, preventing dev/prod data mixing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:39:19 +08:00
Jiayuan Zhang
40fb94e3c3 feat(utils): add SMC_DATA_DIR env var to override root data directory
Allows isolating dev and prod data by setting SMC_DATA_DIR (e.g.
~/.super-multica-dev). Also fixes cron/store.ts which bypassed
DATA_DIR with a hardcoded path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:39:13 +08:00
Jiayuan Zhang
b1d6a6ee9a
Merge pull request #179 from multica-ai/forrestchang/desktop-menubar
feat(desktop): add system tray menu for background operation
2026-02-14 23:38:45 +08:00
Jiayuan Zhang
9bfef7126b feat(desktop): add version, gateway, and update check to tray menu
Tray menu now shows:
- Agent status (Idle/Running/Streaming)
- Hub connection status
- Gateway URL
- Show Main Window
- Version number
- Check for Updates
- Quit Multica (⌘Q)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:27:10 +08:00
Jiayuan Zhang
c50bdd0f84 fix(desktop): reduce tray icon size to match menu bar conventions
Shrink asterisk glyph from 22x22 to 14x14 within the 22x22 canvas
(28x28 within 44x44 @2x), adding proper padding to align with
other macOS menu bar icons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:18:27 +08:00
Jiayuan Zhang
5e03b4d76b fix(desktop): use asterisk tray icon and show-only menu
- Replace resized app icon with dedicated tray icon matching MulticaIcon
- Remove click-to-toggle behavior, add "Show Main Window" menu item
- Include tray icon PNGs in electron-builder files config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:16:56 +08:00
Jiayuan Zhang
d2e22a6ec7 feat(desktop): add system tray for background agent status
When the main window is closed, the app now stays running with a
menu bar tray icon showing agent/hub status. Users can toggle the
window visibility and quit from the tray menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:40:28 +08:00
yushen
0b50400a45 fix(desktop): read error body instead of statusText for gateway errors
res.statusText is always empty under HTTP/2, causing "Gateway error: "
with no detail. Now reads the JSON response body to surface the
server's actual error message and always includes the status code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 08:51:46 +08:00
yushen
b3a179971e chore: bump version to 0.1.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 08:19:15 +08:00
yushen
1a9e915d49 fix(hub): skip text processing after MessageAggregator reset
Add an `active` flag so that message_update/message_end events are
ignored after reset() until the next message_start, preventing stale
accumulated text from being re-emitted as a block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 07:49:20 +08:00
LinYushen
733798f2a9
Merge pull request #178 from multica-ai/fix/api-url-env-bridge
fix(desktop): bridge MULTICA_API_URL for staging/test packaged builds
2026-02-14 07:40:29 +08:00
yushen
eb07f12c49 chore(desktop): add env files for dev/production and update dev scripts
- Track .env.development and .env.production for desktop app
- Add MAIN_VITE_API_URL to all env files
- Remove hardcoded GATEWAY_URL from dev scripts (now in .env.development)
- Update .env.example with full documentation of all env vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 07:30:54 +08:00
yushen
ef32078b3c fix(desktop): use RENDERER_VITE_API_URL for renderer API host
Read API host from import.meta.env.RENDERER_VITE_API_URL instead of
hardcoding it, so staging/dev builds point to the correct backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 07:30:48 +08:00
yushen
b7477cb646 feat(desktop): bridge MAIN_VITE_API_URL to process.env for packaged builds
In packaged Electron builds, @multica/core is externalized and .env
files are excluded. Bridge import.meta.env.MAIN_VITE_API_URL (injected
at build time by electron-vite) to process.env.MULTICA_API_URL so that
getApiBaseUrl() reads the correct value in staging/test environments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 07:30:42 +08:00
yushen
b8aa5ad7e6 refactor(core): convert MULTICA_API_URL constant to getApiBaseUrl() function
Lazy-read process.env at call time instead of module import time.
This ensures the env bridge in the Electron main process has time to
set process.env.MULTICA_API_URL before the first API request.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 07:30:36 +08:00
Jiayuan Zhang
87c03c1368
Merge pull request #177 from multica-ai/forrestchang/telegram-table-fmt
fix(telegram): improve Telegram bot UX — tables, tool narration, typing
2026-02-14 03:38:03 +08:00
Jiayuan Zhang
ef8b38899a fix(core): check for "toolCall" type in hasToolUse() to match pi-ai types
The hasToolUse() function was checking for "tool_use" (raw Anthropic format)
but pi-ai normalizes tool call blocks to type "toolCall". This made tool
narration non-functional in the ChannelManager (Desktop/embedded) path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 03:32:16 +08:00
Jiayuan Zhang
d1570698ac fix(telegram): fix tool narration detection and typing indicator during tool execution
- Detect both "tool_use" (Anthropic) and "toolCall" (Hub) content types
- Re-send typing indicator after sending/editing status message since
  Telegram clears typing state on any message send/edit
- Remove debug file logging (appendFileSync to /tmp)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 03:14:48 +08:00
Jiayuan Zhang
4c1365ff75 fix(telegram): strip existing bold markers in table conversion to prevent overlapping HTML tags
Table cells already containing **bold** markers got double-wrapped,
creating ****text**** which produced overlapping <b><i> tags rejected
by Telegram's HTML parser.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 03:14:41 +08:00
Jiayuan Zhang
3c911807e1 chore(channels): remove unused Desktop Telegram channel plugin
The Telegram bot is handled entirely by the Gateway
(apps/gateway/telegram/). The Desktop channel plugin was never
registered (commented out in initChannels) and is dead code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:28:00 +08:00
Jiayuan Zhang
dde8cc542a feat(telegram): show editable status message during tool execution
Instead of silently discarding tool narration or spamming separate
messages, send a single editable Telegram message that updates in-place
as the agent works. First tool narration sends a reply; subsequent
narrations edit the same message. The final answer is sent as a new
message.

- Add replyTextEditable/editText to ChannelOutboundAdapter interface
- Implement editFormatted + editable methods in Telegram plugin
- Track statusMessageId in ChannelManager, clear on agent_end/error
- Add sendOrEditStatus to Gateway TelegramService with same behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:14:42 +08:00
Jiayuan Zhang
81998e6309 fix(telegram): skip tool narration messages, only send final answer
When the agent uses tools (web search, etc.), it generates intermediate
narration text like "Let me search..." before each tool call. These were
being sent as separate Telegram messages, causing message spam. Now we
detect tool_use blocks in the message content and skip sending those
intermediate messages — only the final answer reaches the user.

Applied to both Desktop channel plugin and Gateway Telegram service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:04:17 +08:00
Jiayuan Zhang
8270762d66 feat(telegram): convert Markdown tables to vertical list format
Telegram doesn't support HTML tables, so pipe-delimited Markdown tables
were rendered as hard-to-read plain text on mobile. This converts tables
to a vertical "Header: Value" format with bold first column before
sending to Telegram.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:56:21 +08:00
Jiayuan Zhang
badcaa4a41
Merge pull request #176 from multica-ai/forrestchang/dev-local-run-log
chore(scripts): enable run log in dev:local script
2026-02-14 01:55:56 +08:00
Jiayuan Zhang
9c02ac7b91 chore(scripts): enable run log in dev:local script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:50:56 +08:00
Jiayuan Zhang
9189883710
Merge pull request #175 from multica-ai/forrestchang/telegram-arch
feat(gateway): Telegram QR-based connection flow with centralized bot
2026-02-14 01:45:46 +08:00
Jiayuan Zhang
eb274d5e0c fix(desktop): resolve lint warnings for react-refresh and unused import
- Extract useQRToken and useCountdown hooks to qr-hooks.ts so qr-code.tsx
  only exports components (fixes react-refresh/only-export-components)
- Remove unused useRef import from connect-step.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:38:04 +08:00
Jiayuan Zhang
d6393c6718 fix(gateway): remove cleanupPendingRequests that rejects all concurrent users
cleanupPendingRequests() iterated the service-wide pendingRequests Map
and rejected every entry. Since it was called from connectUser's catch
block (a per-user error path), one user's connection failure would
spuriously reject other users' in-flight verify RPCs.

The call was also redundant: sendVerifyRpc already cleans up its own
entry in all failure paths (timeout, RPC error, route failure).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:31:33 +08:00
Jiayuan Zhang
7af2a0d1b1 fix(desktop): auto-approve Telegram connection during onboarding
DeviceConfirmDialog only exists in the main Layout, so verify
requests were timing out during onboarding. Since the user is
actively generating the QR code, auto-approve and show a success
state instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:14:25 +08:00
Jiayuan Zhang
5531379bb0 chore: add OAuth login URL to local dev script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 01:05:24 +08:00
Jiayuan Zhang
088750326c fix(gateway): persist Telegram users to JSON file when no database
Replaces in-memory Map with file-backed store at
~/.super-multica/gateway/telegram-users.json so user bindings
survive gateway restarts during local development.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:48:17 +08:00
Jiayuan Zhang
24b70e6e25 fix(gateway): add in-memory fallback for TelegramUserStore when no database
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:45:05 +08:00
Jiayuan Zhang
a7629db01e fix(gateway): enable CORS for HTTP endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:42:29 +08:00
Jiayuan Zhang
005908710e chore: add local dev script for Gateway + Desktop with Telegram bot
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:39:43 +08:00
Jiayuan Zhang
b39a0dd2ac feat(desktop): add Telegram QR code to Clients page and Onboarding
- Create TelegramConnectQR component (fetches short code from Gateway)
- Export reusable hooks/components from qr-code.tsx
- Update ChannelsTab with Telegram QR card
- Rewrite ConnectStep for QR-based flow (replaces BotFather token input)
- Re-add ConnectStep to onboarding: Privacy → Provider → Channels → Start

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:30:10 +08:00
Jiayuan Zhang
d75a24714d feat(gateway): add Telegram QR deep link connection flow
Add short code store, bot commands (/start, /status, /help), and
POST /telegram/connect-code endpoint for Desktop to create QR codes.
Users scan a QR → Telegram opens → /start {code} → auto-connects.

- ShortCodeStore: in-memory Map with TTL for connection info
- Bot commands registered via setMyCommands
- Refactor handleConnectionLink into shared connectUser method
- Fetch bot username via getMe() for deep link URL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:30:01 +08:00