adam-agent-server 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,14 +22,14 @@
22
22
  <a href="https://www.npmjs.com/package/adam-agent-server"><img src="https://img.shields.io/npm/v/adam-agent-server" alt="npm" /></a>
23
23
  <img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node.js" />
24
24
  <img src="https://img.shields.io/badge/typescript-5.x-blue" alt="TypeScript" />
25
- <img src="https://img.shields.io/badge/tests-987%20passed-brightgreen" alt="Tests" />
26
- <img src="https://img.shields.io/badge/API-72%20endpoints-blue" alt="API" />
25
+ <img src="https://img.shields.io/badge/tests-2102%20passed-brightgreen" alt="Tests" />
26
+ <img src="https://img.shields.io/badge/API-80%20endpoints-blue" alt="API" />
27
27
  <img src="https://img.shields.io/badge/license-MIT-blue" alt="License" />
28
28
  </p>
29
29
 
30
30
  ---
31
31
 
32
- Manages task lifecycle, multi-worker process isolation, real-time streaming, remote human approval, goal-driven orchestration, and self-evolving agent strategies.
32
+ Manages task lifecycle, concurrent execution pool, real-time streaming, remote human approval, goal-driven orchestration, and self-evolving agent strategies.
33
33
 
34
34
  ## Architecture
35
35
 
@@ -46,17 +46,19 @@ Manages task lifecycle, multi-worker process isolation, real-time streaming, rem
46
46
  | +-----+------+ |
47
47
  | | |
48
48
  | +-------v--------+ |
49
- | | Manager Agent | | LLM-driven task dispatch
49
+ | | ChatManager | | Persistent SDK session, LLM dispatch
50
50
  | +-------+--------+ |
51
51
  +---------|-----------+
52
- | IPC
52
+ | serverBus events
53
53
  +----------+----------+
54
54
  v v v
55
- Worker 1 Worker 2 Worker N
56
- | | |
57
- SDK query SDK query SDK query
58
- | | |
59
- (plugins, MCP, fileAccess)
55
+ Chat sessions Execution Delivery
56
+ + Pool (N) Engine
57
+ | |
58
+ Execution OutboundGateway
59
+ Manager (retry, dedup,
60
+ (fresh rate limit)
61
+ query, RBAC)
60
62
  ```
61
63
 
62
64
  ## Features
@@ -64,14 +66,14 @@ Manages task lifecycle, multi-worker process isolation, real-time streaming, rem
64
66
  | Category | Capabilities |
65
67
  |----------|-------------|
66
68
  | **Task Management** | Submit, queue, run, cancel; full status tracking; cost and token accounting |
67
- | **Multi-Worker Pool** | Configurable process pool; crash recovery; auto-recycling; session resume |
69
+ | **Execution Pool** | Configurable concurrent slot pool; event-driven task pickup; poll-based fallback; crash resilience |
68
70
  | **Scheduling** | Cron expressions (5-field); event-driven triggers (`template_complete:<id>`); multi-step workflows with dependency DAGs |
69
71
  | **Goal System** | Natural language SMART goals; metric trees; Thompson Sampling strategy selection |
70
- | **Role + Skill Model** | Role (identity/personality) + Skill (capability/permissions); learned rules; memory with hybrid search |
72
+ | **Role Model** | Role (identity/personality) with allowedTools/disallowedTools; learned rules; memory with hybrid search |
71
73
  | **Real-time Streaming** | WebSocket per-task stream + global event bus; structured pino logging |
72
74
  | **Security** | 5-layer model: disallowed tools, allowed tools, file path checks, human approval, secret redaction |
73
75
  | **Plugin Support** | Plugin registry (global + project); MCP server passthrough |
74
- | **Web UI** | React SPA with 19 pages; real-time WebSocket updates; mobile responsive (shadcn/ui + Tailwind) |
76
+ | **Web UI** | React SPA with 20 pages; real-time WebSocket updates; mobile responsive (shadcn/ui + Tailwind) |
75
77
  | **TUI** | Ink-based terminal UI; live streaming; approval prompts; 11 slash commands |
76
78
  | **CLI** | `adam run "prompt"`; JSON output; daemon management |
77
79
  | **API Docs** | OpenAPI 3.0 via Swagger UI at `/docs`; AI-optimized reference at `docs/CLAUDE-API.md` |
@@ -140,7 +142,7 @@ curl -X POST http://localhost:7100/tasks \
140
142
 
141
143
  Full React SPA served at `http://localhost:7100/ui`. Mobile responsive.
142
144
 
143
- **Pages**: Dashboard, Tasks, Templates, Goals, Roles, Strategies, Memories, Evolution, Plugins, Channels, Chat, Webhooks, Work, Logs, Settings
145
+ **Pages**: Dashboard, Tasks, Templates, Goals, GoalDetail, Roles, RoleDetail, Strategies, Memories, Evolution, Plugins, Channels, ChannelDetail, Chat, Webhooks, Work, Logs, Settings, TaskDetail, NotFound
144
146
 
145
147
  Built with: Vite + React 19 + TypeScript + Zustand + shadcn/ui + Tailwind CSS
146
148
 
@@ -148,7 +150,7 @@ Built with: Vite + React 19 + TypeScript + Zustand + shadcn/ui + Tailwind CSS
148
150
 
149
151
  ```bash
150
152
  # Server
151
- adam server start|stop|status|logs [-f]
153
+ adam server start|stop|restart|status|logs [-f]
152
154
 
153
155
  # Tasks
154
156
  adam run "prompt" [--model M] [--timeout N] [--budget N] [--json] [--no-approval]
@@ -157,9 +159,9 @@ adam tasks show <id>
157
159
  adam tasks cancel <id>
158
160
 
159
161
  # Info
160
- adam workers
161
162
  adam config [--json]
162
163
  adam evolution [-l limit]
164
+ adam register-ai-digest
163
165
  ```
164
166
 
165
167
  ### TUI Slash Commands
@@ -168,7 +170,9 @@ adam evolution [-l limit]
168
170
 
169
171
  ## Configuration
170
172
 
171
- Adam loads from `adam.config.yaml` with precedence: **CLI flags > Env vars > Config file > Defaults**
173
+ Adam stores config in SQLite DB. The Settings UI (Web UI `/ui/settings`) is the primary editing interface — changes take effect on server restart. CLI flags and environment variables override DB values at startup.
174
+
175
+ > Note: `adam.config.yaml` is deprecated. On first boot, `.env` seeds the DB; after that DB is authoritative.
172
176
 
173
177
  ```yaml
174
178
  defaults:
@@ -184,10 +188,10 @@ defaults:
184
188
  approvalRequired: ["rm -rf", "git push", "git reset"]
185
189
  approvalTimeout: 300
186
190
 
187
- workers:
188
- count: 3
189
- maxTasksBeforeRecycle: 50
190
- maxMemoryMB: 512
191
+ execution:
192
+ maxConcurrent: 5
193
+ maxBudgetPerTaskUsd: 5.0
194
+ pollIntervalMs: 30000
191
195
 
192
196
  server:
193
197
  port: 7100
@@ -203,7 +207,6 @@ logging:
203
207
  |----------|-------------|
204
208
  | `ANTHROPIC_API_KEY` | Claude API key (required) |
205
209
  | `ADAM_PORT` | Server port (default: 7100) |
206
- | `ADAM_WORKERS_COUNT` | Worker pool size (default: 3) |
207
210
  | `ADAM_LOG_LEVEL` | Log level (default: info) |
208
211
  | `ADAM_WEBHOOK_API_KEY` | Webhook authentication key |
209
212
  | `ANTHROPIC_MODEL` | Default model |
@@ -222,21 +225,20 @@ WebSocket events: [docs/websocket-events.md](docs/websocket-events.md)
222
225
  | Resource | Endpoints | Description |
223
226
  |----------|-----------|-------------|
224
227
  | **Tasks** | `POST` `GET` `GET/:id` `POST/:id/cancel` `POST/:id/approve` `POST/:id/reject` `POST/:id/approve-plan` `GET/:id/plan` `GET/:id/logs` `POST /batch-cancel` | Full task lifecycle + batch ops |
225
- | **Roles** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` | Role management (was Agents) |
226
- | **Skills** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` `POST /:id/bind` `POST /:id/unbind` | Skill CRUD + role binding |
227
- | **Memories** | `GET/:roleId` `POST/query` | Role memory with hybrid search |
228
- | **Goals** | `POST` `GET` `GET/:id` | Natural language SMART goals |
229
- | **Strategies** | `GET` `GET/:role/:taskType/probabilities` | Thompson Sampling |
228
+ | **Roles** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` `GET /:id/scores` `GET /:id/presets` | Role CRUD + scores + workspace management |
229
+ | **Memories** | `GET/:roleId` `POST/query` `GET /stats` `GET /:roleId/:memoryId` `DELETE /:roleId/:memoryId` | Role memory with hybrid search |
230
+ | **Goals** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` | Natural language SMART goals |
231
+ | **Strategies** | `GET` `GET /:role/:taskType/probabilities` | Thompson Sampling |
230
232
  | **Templates** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` `POST/:id/run` | Task template CRUD + trigger |
231
233
  | **Webhooks** | `POST/:name` `GET` | External trigger with API key auth |
232
- | **Channels** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` | Channel adapters (WeChat, Telegram, etc.) |
233
- | **Delivery Rules** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` | Event-driven delivery routing |
234
- | **Plugins** | `GET` `GET/:id` `POST` `DELETE/:id` `POST /:id/sync` | Plugin registry |
235
- | **Chat** | `POST /messages` `GET /sessions` `GET /sessions/:id` | Chat sessions + messaging |
236
- | **Evolution** | `GET` `GET/:roleId` | Role evolution audit trail |
237
- | **Config** | `GET` `PATCH` | Runtime configuration |
234
+ | **Channels** | `POST` `GET` `GET/:id` `PATCH/:id` `DELETE/:id` `GET /:id/events` `GET /:id/test` `POST /:id/send` `POST /:id/setup` `GET /platforms` | Channel adapters (WeChat, Telegram, etc.) |
235
+ | **Delivery Rules** | `POST` `GET` `GET /:id` `PATCH/:id` `DELETE/:id` `GET /:id/test` | Event-driven delivery routing |
236
+ | **Plugins** | `GET` `GET /:id` `POST` `DELETE/:id` `POST /:id/sync` `GET /installed` `GET /available` `POST /scan-directory` `POST /register` | Plugin registry + discovery |
237
+ | **Chat** | `POST /messages` `GET /sessions` `GET /sessions/:id` `POST /sessions/:id/restore` `GET /sessions/:id/messages` `DELETE /sessions/:id` `POST /sessions/:id/archive` `POST /sessions` | Chat sessions + messaging + restore |
238
+ | **Evolution** | `GET` `GET /:roleId` | Role evolution audit trail |
239
+ | **Config** | `GET` `PATCH` `GET /diff` `PATCH /override` `POST /reset` | Runtime configuration |
238
240
  | **FS** | `GET /read` `GET /list` `POST /write` `POST /mkdir` | File system operations |
239
- | **Health** | `GET /healthz` `GET /readyz` | Liveness + readiness |
241
+ | **Health** | `GET /healthz` `GET /readyz` `GET /metrics` | Liveness + readiness + metrics |
240
242
  | **WebSocket** | `WS /tasks/:id/stream` `WS /events` `WS /chat/:sessionId` | Real-time streaming |
241
243
 
242
244
  For full request/response examples, see [docs/CLAUDE-API.md](docs/CLAUDE-API.md).
@@ -257,38 +259,83 @@ For full request/response examples, see [docs/CLAUDE-API.md](docs/CLAUDE-API.md)
257
259
  adam/
258
260
  ├── src/
259
261
  │ ├── index.ts # Server entry
260
- │ ├── lib/logger.ts # Pino structured logging
261
262
  │ ├── cli/
262
263
  │ │ ├── index.ts # CLI entry (commander)
263
- │ │ ├── tui/ # Ink terminal UI
264
- │ │ ├── App.tsx
265
- │ │ │ └── components/ # 21 components
266
- │ │ └── commands/ # CLI command handlers
264
+ │ │ ├── daemon.ts # Daemon process management
265
+ │ │ ├── client.ts # HTTP client for daemon
266
+ │ │ ├── commands/ # config, evolution, logs, run, tasks, register-ai-digest
267
+ │ │ └── tui/ # Ink terminal UI (21 components, 11 slash commands)
267
268
  │ ├── server/
268
269
  │ │ ├── app.ts # Fastify + Swagger + static files
269
- │ │ ├── routes/ # 16 route modules (72 endpoints)
270
- │ │ ├── ws/ # WebSocket streaming
271
- │ │ └── events/ # Server event bus
272
- │ ├── scheduler/
273
- │ │ ├── bree-engine.ts # Cron + event trigger scheduling
274
- │ │ └── workflow-executor.ts # Multi-step DAG execution
270
+ │ │ ├── routes/ # 15 route modules (80 endpoints)
271
+ │ │ ├── ws/ # stream, global-events, chat-stream
272
+ │ │ └── events/ # ServerBus typed event emitter
275
273
  │ ├── manager/
276
- │ │ └── manager.ts # LLM-driven task dispatch
277
- │ ├── worker/
278
- │ │ ├── manager.ts # Process fork/monitor/recover
279
- │ │ ├── worker-entry.ts # SDK query() with plugins + MCP
280
- │ │ └── hooks.ts # File access + secret redaction
281
- │ ├── store/ # SQLite persistence (WAL mode)
282
- │ ├── config/ # YAML + env + defaults
283
- │ └── shared/types.ts # Type definitions
284
- ├── web/ # React SPA (Vite + shadcn/ui)
285
- │ ├── src/pages/ # 19 pages
286
- │ ├── src/components/ # UI components
287
- └── src/store/ # Zustand state
274
+ │ │ ├── chat-manager.ts # Persistent SDK session, message routing
275
+ ├── execution-manager.ts # Fresh query() per task, RBAC via canUseTool
276
+ │ │ ├── execution-pool.ts # N-slot semaphore, event-driven + poll pickup
277
+ │ │ ├── adam-tools.ts # MCP server (53 tools)
278
+ │ │ ├── hooks.ts # SDK hooks (SubagentStart/Stop, PostToolUse, PreCompact)
279
+ ├── chat-system-prompt.ts
280
+ ├── execution-system-prompt.ts
281
+ └── execution-tools.ts
282
+ ├── agent/
283
+ ├── learner.ts # Deviation → learnedRules
284
+ ├── memory-extractor.ts # Step log → role memories
285
+ │ ├── session-memory-extractor.ts
286
+ │ │ ├── memory-service.ts
287
+ │ │ ├── reflection.ts # Importance counter → insight generation
288
+ │ │ └── review.ts
289
+ │ ├── strategy/
290
+ │ │ ├── engine.ts # Thompson Sampling controller
291
+ │ │ ├── sampler.ts
292
+ │ │ ├── generator.ts
293
+ │ │ ├── reflexion.ts
294
+ │ │ └── evaluator/ # L0-L3 collectors, llm-judge, calibration
295
+ │ ├── scheduler/
296
+ │ │ ├── bree-engine.ts # Cron + event trigger scheduling
297
+ │ │ └── workflow-executor.ts # Multi-step DAG execution
298
+ │ ├── delivery/
299
+ │ │ ├── engine.ts # Event subscription, rule matching
300
+ │ │ └── outbound-gateway.ts # Dedup, format, anti-loop, retry, rate limit
301
+ │ ├── goal-manager/
302
+ │ │ ├── goal-manager.ts
303
+ │ │ └── types.ts
304
+ │ ├── platform/
305
+ │ │ └── watchdog.ts # Independent health timer
306
+ │ ├── monitor/
307
+ │ │ ├── monitor.ts # EMA quality scores, retirement/reinstatement
308
+ │ │ ├── score.ts
309
+ │ │ ├── retirement.ts
310
+ │ │ └── diagnostic.ts
311
+ │ ├── channels/
312
+ │ │ ├── manager.ts
313
+ │ │ ├── adapter.ts
314
+ │ │ ├── approval-handler.ts
315
+ │ │ └── adapters/ # WeChat, Telegram, Slack, Discord, Openclaw
316
+ │ ├── chat/
317
+ │ │ ├── context-builder.ts
318
+ │ │ ├── message-handler.ts
319
+ │ │ └── session-manager.ts
320
+ │ ├── store/ # SQLite persistence (22 .ts files)
321
+ │ ├── config/ # YAML + env + runtime config (6 files)
322
+ │ ├── lib/ # Logger, permissions, embedding, token estimation
323
+ │ ├── shared/ # types.ts, constants.ts
324
+ │ ├── admin/
325
+ │ │ └── admin-tools.ts
326
+ │ └── plugins/
327
+ │ └── playwright/ # Browser automation tools
328
+ ├── web/
329
+ │ ├── src/
330
+ │ │ ├── pages/ # 20 pages
331
+ │ │ ├── components/ # Chat, Layout, Plan, UI components
332
+ │ │ ├── store/ # Zustand stores
333
+ │ │ └── lib/ # API client, types, utils
334
+ │ └── public/
288
335
  ├── docs/
289
- │ ├── CLAUDE-API.md # AI-optimized API reference
290
- │ └── websocket-events.md # WebSocket protocol docs
291
- ├── adam.config.yaml
336
+ │ ├── CLAUDE-API.md
337
+ │ └── websocket-events.md
338
+ ├── .env.example
292
339
  └── package.json
293
340
  ```
294
341
 
@@ -318,19 +365,19 @@ Licensed under the [MIT License](LICENSE).
318
365
 
319
366
  ## 简介
320
367
 
321
- Adam 是一个基于 [Claude Agent SDK](https://docs.anthropic.com/en/docs/agents-sdk) 的 AI Agent 编排服务器。管理任务生命周期、多 Worker 进程隔离、实时流式输出、远程人工审批、目标驱动编排和自进化策略。
368
+ Adam 是一个基于 [Claude Agent SDK](https://docs.anthropic.com/en/docs/agents-sdk) 的 AI Agent 编排服务器。管理任务生命周期、并发执行池、实时流式输出、远程人工审批、目标驱动编排和自进化策略。
322
369
 
323
370
  ## 核心能力
324
371
 
325
372
  - **任务管理**: 提交、队列、执行、取消,完整状态追踪和成本核算
326
- - **多 Worker 进程池**: 可配置大小、崩溃恢复、自动回收、会话恢复
373
+ - **并发执行池**: 可配置 slot 数、事件驱动任务拾取、poll 兜底、崩溃恢复
327
374
  - **定时调度**: 5 字段 Cron 表达式、事件驱动触发(`template_complete:<id>`)、多步工作流(依赖 DAG)
328
375
  - **目标系统**: 自然语言 SMART 目标、指标树、Thompson Sampling 策略选择
329
- - **Role + Skill 模型**: Role(人格/身份)+ Skill(工具/权限);学习规则、混合搜索记忆
376
+ - **Role 模型**: Role(人格/身份),含 allowedTools/disallowedTools;学习规则、混合搜索记忆
330
377
  - **实时流**: WebSocket 任务流 + 全局事件总线、pino 结构化日志
331
378
  - **5 层安全**: 工具禁用、工具白名单、文件路径检查、人工审批、敏感信息脱敏
332
379
  - **插件支持**: 通过 `plugins` 配置加载 Claude Code 插件、MCP Server 透传
333
- - **Web UI**: React SPA,19 个页面,WebSocket 实时更新,移动端响应式(shadcn/ui + Tailwind)
380
+ - **Web UI**: React SPA,20 个页面,WebSocket 实时更新,移动端响应式(shadcn/ui + Tailwind)
334
381
  - **终端 UI**: 基于 Ink 的 TUI,实时流、审批提示、11 个斜杠命令
335
382
  - **CLI**: `adam run "prompt"`,JSON 输出,后台进程管理
336
383
  - **API 文档**: OpenAPI 3.0(Swagger UI `/docs`),AI 优化版 `docs/CLAUDE-API.md`
@@ -381,36 +428,37 @@ curl -X POST http://localhost:7100/tasks \
381
428
 
382
429
  ## 配置
383
430
 
384
- 配置优先级: **CLI 参数 > 环境变量 > adam.config.yaml > 默认值**
431
+ 配置优先级: **CLI 参数 > 环境变量 > .env 文件 > DB(Settings UI)> 默认值**
432
+
433
+ > 注意:`adam.config.yaml` 已废弃。配置数据存储在 DB 中,Settings UI 为主要编辑界面(重启生效)。`.env` 仅用于首次启动时的初始种子。
385
434
 
386
435
  | 环境变量 | 说明 |
387
436
  |---------|------|
388
437
  | `ANTHROPIC_API_KEY` | Claude API 密钥(必需) |
389
438
  | `ADAM_PORT` | 服务端口(默认 7100) |
390
- | `ADAM_WORKERS_COUNT` | Worker 进程数(默认 3) |
391
439
  | `ADAM_LOG_LEVEL` | 日志级别(默认 info) |
392
440
  | `ADAM_WEBHOOK_API_KEY` | Webhook 认证密钥 |
441
+ | `ANTHROPIC_MODEL` | 默认模型 |
393
442
 
394
443
  ## API 概览
395
444
 
396
- 72 REST 端点 + 3 WebSocket 端点。完整文档见 `/docs`(Swagger UI)。
445
+ 80 REST 端点 + 3 WebSocket 端点。完整文档见 `/docs`(Swagger UI)。
397
446
 
398
447
  | 资源 | 端点 | 说明 |
399
448
  |------|------|------|
400
- | 任务 | 10 个 | 创建、列表、详情、取消、审批、拒绝、批量取消、执行计划、日志 |
401
- | Role | 4 个 | CRUD + 身份管理 |
402
- | Skill | 6 个 | CRUD + 角色绑定 |
403
- | 记忆 | 2 个 | 列表 + 混合搜索 |
404
- | 目标 | 3 个 | 自然语言目标管理 |
405
- | 策略 | 2 个 | Thompson Sampling |
449
+ | 任务 | 11 个 | 创建、列表、详情、取消、审批、拒绝、批量取消、执行计划、日志 |
450
+ | Role | 7 个 | CRUD + 工作区管理 + 插件绑定 |
451
+ | 记忆 | 5 个 | 列表、搜索、详情、统计 |
452
+ | 目标 | 5 个 | CRUD + 列表 |
453
+ | 策略 | 1 个 | Thompson Sampling |
406
454
  | 模板 | 6 个 | 定时任务 CRUD + 触发 |
407
455
  | Webhook | 2 个 | 外部触发 + API Key 认证 |
408
- | Channel | 4 个 | 渠道适配器(微信、Telegram 等) |
409
- | Delivery Rule | 4 个 | 事件驱动投递路由 |
410
- | Plugin | 5 个 | 插件注册表 + 同步 |
411
- | Chat | 3 个 | 会话 + 消息 |
412
- | Evolution | 2 个 | Role 进化审计 |
413
- | Config | 2 个 | 运行时配置 |
414
- | FS | 5 个 | 文件读写操作 |
415
- | 健康检查 | 2 个 | 存活 + 就绪 |
456
+ | Channel | 10 个 | CRUD + 列表 + 详情 |
457
+ | Delivery Rule | 6 个 | CRUD + 列表 + 详情 |
458
+ | Plugin | 10 个 | CRUD + 同步 + 列表 + 扫描 |
459
+ | Chat | 8 个 | 消息、会话、恢复 |
460
+ | Evolution | 1 个 | Role 进化审计 |
461
+ | Config | 5 个 | 读写、覆盖、重置 |
462
+ | FS | 1 个 | 文件操作 |
463
+ | 健康检查 | 3 个 | 存活、就绪、指标 |
416
464
  | WebSocket | 3 个 | 任务流 + 全局事件 + Chat 流 |
@@ -0,0 +1,9 @@
1
+ import{b as T,d as Dt,e as mo}from"./chunk-NSJAV7IH.js";import{a as At,e as co,g as uo}from"./chunk-SFUS33SO.js";import"./chunk-3DAK2XWP.js";import"./chunk-FCV2DPZQ.js";import{Box as kt,Text as xt,useInput as Fn}from"ink";import{useState as Wn,useEffect as Ht,useRef as lo}from"react";import{createContext as dr,useContext as ur,useReducer as mr}from"react";import{jsx as pr}from"react/jsx-runtime";var gr={connected:!1,serverInfo:null,activeTasks:0,queuedTasks:0,costToday:0,activeTaskId:null,activeTaskSubmitted:!1,pendingApproval:null,pendingPlanApproval:null,planTimeoutNotice:null,serverUnreachable:!1,view:"chat",configVersion:0,session:null,version:null};function fr(e,t){switch(t.type){case"SET_CONNECTED":return{...e,connected:t.connected};case"SET_SERVER_INFO":return{...e,serverInfo:t.info};case"UPDATE_STATS":return{...e,activeTasks:t.activeTasks,queuedTasks:t.queuedTasks,costToday:t.costToday};case"SET_ACTIVE_TASK":return{...e,activeTaskId:t.taskId,activeTaskSubmitted:!1};case"TASK_SUBMITTED":return{...e,activeTaskSubmitted:!0};case"SET_PENDING_APPROVAL":return{...e,pendingApproval:t.approval};case"SET_SERVER_UNREACHABLE":return{...e,serverUnreachable:t.unreachable};case"SET_VIEW":return{...e,view:t.view};case"CONFIG_CHANGED":return{...e,configVersion:e.configVersion+1};case"SET_SESSION":return{...e,session:t.session};case"SET_PENDING_PLAN_APPROVAL":return{...e,pendingPlanApproval:t.approval};case"SET_PLAN_TIMEOUT_NOTICE":return{...e,pendingPlanApproval:null,planTimeoutNotice:t.planId?{planId:t.planId}:null};case"SET_VERSION":return{...e,version:t.version};default:return e}}var go=dr(null);function fo({children:e}){let[t,o]=mr(fr,gr);return pr(go.Provider,{value:{state:t,dispatch:o},children:e})}function Xe(){let e=ur(go);if(!e)throw new Error("useTuiState must be used within TuiProvider");return e}import{useEffect as po,useRef as xo}from"react";var xr=15e3;function To(){let{state:e,dispatch:t}=Xe(),o=xo(null),d=xo(null);po(()=>{d.current=e.session?.id??null},[e.session?.id]),po(()=>{let u=!0,m=null,l=()=>{o.current&&(clearTimeout(o.current),o.current=null)},i=()=>{l(),o.current=setTimeout(()=>{u&&t({type:"SET_SERVER_UNREACHABLE",unreachable:!0})},xr)};return(()=>{try{m=new Dt("/events"),m.on("task_status_change",()=>{}),m.on("approval_request",r=>{if(!u)return;let a=r;t({type:"SET_PENDING_APPROVAL",approval:{taskId:a.taskId,approvalId:a.approvalId,toolName:a.toolName,toolInput:a.toolInput,matchedPattern:a.matchedPattern}})}),m.on("plan_approval_request",r=>{if(!u)return;let a=r;t({type:"SET_PENDING_PLAN_APPROVAL",approval:{taskId:a.taskId,planId:a.planId,roleId:a.roleId,plan:a.plan}})}),m.on("plan_approval_decision",()=>{u&&t({type:"SET_PENDING_PLAN_APPROVAL",approval:null})}),m.on("config_changed",()=>{u&&t({type:"CONFIG_CHANGED"})}),m.on("execution_task_start",r=>{if(!u)return;let a=r,c=d.current;c&&(async()=>{try{let h=await T(`/tasks/${a.taskId}`);u&&h.sourceSessionId===c&&t({type:"SET_ACTIVE_TASK",taskId:a.taskId})}catch{}})()}),m.on("stats_update",r=>{if(!u)return;let a=r;t({type:"UPDATE_STATS",activeTasks:a.activeTasks,queuedTasks:a.queuedTasks,costToday:a.totalCostToday})}),m.connect().then(async()=>{if(u){l(),t({type:"SET_CONNECTED",connected:!0}),t({type:"SET_SERVER_UNREACHABLE",unreachable:!1});try{let r=await T("/version");t({type:"SET_VERSION",version:r.version})}catch{t({type:"SET_VERSION",version:null})}}}).catch(()=>{u&&(t({type:"SET_CONNECTED",connected:!1}),i())})}catch{u&&(t({type:"SET_CONNECTED",connected:!1}),i())}})(),()=>{u=!1,l(),m?.close()}},[t])}import{useEffect as Tr,useRef as hr,useState as ho,useCallback as yr}from"react";function yo(e){let[t,o]=ho([]),[d,u]=ho(!1),m=hr(null),l=yr(()=>{o([]),u(!1)},[]);return Tr(()=>{if(!e)return;let i=!0;o([]),u(!0);try{let s=new mo(e);return m.current=s,s.on("reasoning",r=>{if(!i)return;let c=r.content??"";o(h=>{let f=h[h.length-1];if(f?.type==="reasoning"){let x=[...h];return x[x.length-1]={...f,content:f.content+c},x}return[...h,{type:"reasoning",content:c,timestamp:Date.now()}]})}),s.on("tool_call",r=>{if(!i)return;let a=r;o(c=>[...c,{type:"tool_call",content:a.toolName??"unknown tool",timestamp:Date.now(),metadata:{toolName:a.toolName}}])}),s.on("tool_result",r=>{if(!i)return;let a=r;o(c=>[...c,{type:"tool_result",content:a.content??"",timestamp:Date.now()}])}),s.on("error",r=>{if(!i)return;let a=r;o(c=>[...c,{type:"error",content:a.error??"unknown error",timestamp:Date.now()}])}),s.on("complete",r=>{if(!i)return;let a=r;o(c=>[...c,{type:"complete",content:a.result??"",timestamp:Date.now(),metadata:{cost:a.costUsd,turns:a.numTurns,duration:a.totalDurationMs}}]),u(!1)}),s.connect().catch(()=>{i&&(o(r=>[...r,{type:"error",content:"Failed to connect to task stream",timestamp:Date.now()}]),u(!1))}),()=>{i=!1,s.close()}}catch{u(!1)}},[e]),{events:t,isStreaming:d,clearEvents:l}}import{useState as Kt,useEffect as br,useCallback as ht}from"react";function jt(e){return{id:e.id,status:e.status,messageCount:e.messageCount,createdAt:e.createdAt,lastActiveAt:e.lastActiveAt,title:e.title}}function bo(){let[e,t]=Kt(null),[o,d]=Kt(!0),[u,m]=Kt(null),l=ht(async()=>{try{let h=(await T("/chat/sessions?status=active")).sessions.find(f=>f.source.type==="tui");return h?jt(h):null}catch{return null}},[]),i=ht(async()=>{try{let c=await T("/chat/sessions",{method:"POST",body:{source:{type:"tui"}}}),h=jt(c.session);return t(h),h}catch{return m("Failed to create session"),null}},[]),s=ht(async c=>{try{let h=await T("/chat/messages",{method:"POST",body:{content:c,source:{type:"tui"}}});return t(f=>f&&{...f,messageCount:f.messageCount+1,lastActiveAt:Date.now()}),h}catch{return null}},[]),r=ht(async()=>{if(!e)return!1;try{return await T(`/chat/sessions/${e.id}/archive`,{method:"POST"}),t(null),!0}catch{return!1}},[e]),a=ht(async()=>{if(e)try{let c=await T(`/chat/sessions/${e.id}`);t(jt(c.session))}catch{t(null)}},[e]);return br(()=>{let c=!1;async function h(){d(!0);let f=await l();c||(f?t(f):await i(),c||d(!1))}return h(),()=>{c=!0}},[]),{session:e,loading:o,error:u,sendMessage:s,createNewSession:i,archiveCurrentSession:r,refreshSession:a,setSession:t}}import{useEffect as So,useRef as Sr,useState as Cr}from"react";function Co(e){let[t,o]=Cr(null),d=Sr(new Set);return So(()=>{if(!e)return;let u=!0,m=null;try{m=new Dt("/chat/stream"),m.on("chat_message",l=>{if(!u)return;let s=l.message;s&&s.sessionId===e&&s.role==="assistant"&&(d.current.has(s.id)||(d.current.add(s.id),o(s)))}),m.connect().catch(()=>{})}catch{}return()=>{u=!1,m?.close()}},[e]),So(()=>{d.current.clear(),o(null)},[e]),{latestMessage:t}}import{Box as Xt,Text as ve}from"ink";import Ce from"chalk";var Qt={connected:Ce.green,disconnected:Ce.red,warning:Ce.yellow,reasoning:Ce.gray,toolCall:Ce.blue,toolResult:Ce.green,error:Ce.red,dim:Ce.dim,bold:Ce.bold,statusUp:Ce.green("\u25CF"),statusDown:Ce.red("\u25CF")};import{Fragment as vr,jsx as tt,jsxs as ze}from"react/jsx-runtime";function vo(){let{state:e}=Xe(),t=e.connected?`${Qt.statusUp} Server: up`:`${Qt.statusDown} Disconnected`,o=e.activeTasks>0?`${e.activeTasks} running, ${e.queuedTasks} queued`:"No active tasks",d=e.session,m=(d?Math.floor((Date.now()-d.lastActiveAt)/6e4):1/0)>=25;return ze(Xt,{flexDirection:"column",borderStyle:"round",borderDimColor:!0,children:[ze(Xt,{children:[tt(ve,{bold:!0,children:e.version?`Adam v${e.version}`:"Adam"}),tt(ve,{children:" \u2502 "}),tt(ve,{children:t}),tt(ve,{children:" \u2502 "}),ze(ve,{children:["Tasks: ",e.activeTasks," active"]}),e.view==="chat"&&d&&ze(vr,{children:[tt(ve,{children:" \u2502 "}),ze(ve,{children:["Session: ",d.messageCount===0?"(new)":`${d.id.slice(0,8)} (${d.messageCount} turns)`]}),m&&tt(ve,{color:"yellow",children:" timeout soon"})]})]}),ze(Xt,{children:[ze(ve,{children:["Tasks: ",o]}),tt(ve,{children:" \u2502 "}),ze(ve,{children:["Cost: $",e.costToday.toFixed(2)," today"]})]})]})}import{Box as Rt,Text as Mt,useInput as wr}from"ink";import{useState as Yt,useMemo as Br}from"react";import Ir from"ink-text-input";var Er=[{name:"work",description:"Tasks, Automations & Goals"},{name:"config",description:"Configuration"},{name:"evolution",description:"Evolution audit"},{name:"webhooks",description:"Webhook triggers"},{name:"memories",description:"Memory browser"},{name:"strategies",description:"Strategy lab"},{name:"plugins",description:"Plugin management"},{name:"roles",description:"Role management"},{name:"settings",description:"Runtime settings"},{name:"back",description:"Return to chat"},{name:"quit",description:"Exit TUI"}];function zt(e){let t=e.toLowerCase();return Er.filter(o=>o.name.startsWith(t))}function Eo(e){let t=zt(e.toLowerCase());return t.length===1?t[0]:void 0}import{jsx as Nt,jsxs as yt}from"react/jsx-runtime";function wo({onSubmit:e}){let[t,o]=Yt(""),[d,u]=Yt(0),[m,l]=Yt(!1),i=t.startsWith("/")&&t.length>=1,s=t.slice(1),r=Br(()=>i?zt(s):[],[i,s]),a=f=>{o(f),f.startsWith("/")?(l(!0),u(0)):l(!1)},c=()=>{let f=t.trim();if(f){if(f.startsWith("/")){let x=f.slice(1),n=Eo(x);e(n?`/${n.name}`:f)}else e(f);o(""),l(!1)}},h=f=>{e(`/${f.name}`),o(""),l(!1)};return wr((f,x)=>{if(!(!m||!i||r.length===0)){if(x.upArrow){u(n=>n<=0?r.length-1:n-1);return}if(x.downArrow){u(n=>n>=r.length-1?0:n+1);return}if(x.tab){let n=r[d];n&&h(n);return}if(x.escape){l(!1),o("");return}}},{isActive:m&&i&&r.length>0}),yt(Rt,{flexDirection:"column",children:[m&&i&&r.length>0&&Nt(Rt,{flexDirection:"column",marginBottom:0,paddingX:1,children:r.map((f,x)=>{let n=x===d;return yt(Rt,{children:[Nt(Mt,{color:n?"cyan":"gray",bold:n,children:n?"\u25B8 ":" "}),yt(Mt,{color:n?"cyan":"white",bold:n,children:["/",f.name]}),yt(Mt,{dimColor:!0,children:[" \u2014 ",f.description]})]},f.name)})}),yt(Rt,{borderStyle:"round",borderDimColor:!0,children:[Nt(Mt,{bold:!0,children:"\u25B8 "}),Nt(Ir,{value:t,onChange:a,onSubmit:c,placeholder:"Type a message or / for commands..."})]})]})}import{Box as it,Text as ge}from"ink";import{useState as kr}from"react";import{jsx as ye,jsxs as Ae}from"react/jsx-runtime";function Pr({content:e}){let[t,o]=kr(!1),d=e.split(`
2
+ `);return d.length<=5?ye(ge,{color:"green",children:e}):t?ye(ge,{color:"green",children:e}):Ae(ge,{color:"green",children:[d.slice(0,3).join(`
3
+ `),`
4
+ `,Ae(ge,{dimColor:!0,children:["(",d.length," lines) \u25B8 \u5C55\u5F00"]})]})}function Ar({event:e}){switch(e.type){case"reasoning":return ye(it,{children:ye(ge,{color:"gray",children:e.content})});case"tool_call":return ye(it,{children:Ae(ge,{color:"blue",children:["[tool] ",e.metadata?.toolName??e.content]})});case"tool_result":return Ae(it,{flexDirection:"column",children:[ye(ge,{color:"blue",dimColor:!0,children:"[result]"}),ye(Pr,{content:e.content})]});case"error":return ye(it,{children:Ae(ge,{color:"red",children:["[error] ",e.content]})});case"complete":return Ae(it,{flexDirection:"column",marginTop:1,children:[e.content&&ye(ge,{children:e.content}),ye(ge,{dimColor:!0,children:"\u2500\u2500\u2500 Task complete \u2500\u2500\u2500"}),e.metadata?.cost!==void 0&&Ae(ge,{dimColor:!0,children:["Cost: $",e.metadata.cost.toFixed(4)]}),e.metadata?.turns!==void 0&&Ae(ge,{dimColor:!0,children:["Turns: ",e.metadata.turns]}),e.metadata?.duration!==void 0&&Ae(ge,{dimColor:!0,children:["Duration: ",(e.metadata.duration/1e3).toFixed(1),"s"]})]});default:return null}}function Bo({events:e,isStreaming:t}){return e.length===0&&!t?null:Ae(it,{flexDirection:"column",children:[t&&e.length===0&&ye(ge,{dimColor:!0,children:"Waiting for response..."}),e.map((o,d)=>ye(Ar,{event:o},d))]})}import{Box as Io,Text as ko}from"ink";import{jsx as Jt,jsxs as Dr}from"react/jsx-runtime";function Po({messages:e}){return e.length===0?null:Jt(Io,{flexDirection:"column",children:e.map((t,o)=>Dr(Io,{flexDirection:"column",marginBottom:1,children:[Jt(ko,{dimColor:!0,bold:!0,children:t.role==="user"?"You:":"Adam:"}),Jt(ko,{children:t.content})]},o))})}import{Box as bt,Text as De,useInput as Rr}from"ink";import{jsx as Re,jsxs as St}from"react/jsx-runtime";function Ao({approval:e,onResolved:t}){return Rr(o=>{o==="a"?T(`/tasks/${e.taskId}/approve`,{method:"POST",body:{approvalId:e.approvalId}}).then(()=>t()).catch(()=>t()):o==="r"&&T(`/tasks/${e.taskId}/reject`,{method:"POST",body:{approvalId:e.approvalId,reason:"rejected by user"}}).then(()=>t()).catch(()=>t())}),St(bt,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1,children:[Re(De,{bold:!0,color:"yellow",children:"\u26A0 APPROVAL REQUIRED"}),St(bt,{marginTop:1,children:[Re(De,{children:"Tool: "}),Re(De,{bold:!0,children:e.toolName})]}),St(bt,{children:[Re(De,{children:"Input: "}),Re(De,{children:JSON.stringify(e.toolInput)})]}),St(bt,{children:[Re(De,{children:"Pattern: "}),Re(De,{dimColor:!0,children:e.matchedPattern})]}),St(bt,{marginTop:1,children:[Re(De,{color:"green",children:"[a] Approve"}),Re(De,{children:" "}),Re(De,{color:"red",children:"[r] Reject"})]})]})}import{Box as Ct,Text as le,useInput as Mr}from"ink";import{useState as Nr,useEffect as Lr}from"react";import{jsx as Oe,jsxs as Ee}from"react/jsx-runtime";var _r=300;function Do({approval:e,onResolved:t,onTimeout:o}){let[d,u]=Nr(_r);Lr(()=>{let l=setInterval(()=>{u(i=>i<=1?(clearInterval(l),o(),0):i-1)},1e3);return()=>clearInterval(l)},[o]),Mr(l=>{l==="a"?T(`/tasks/${e.taskId}/approve-plan`,{method:"POST",body:{planId:e.planId,decision:"allow",approvalType:"once"}}).then(()=>t()).catch(()=>t()):l==="r"?T(`/tasks/${e.taskId}/approve-plan`,{method:"POST",body:{planId:e.planId,decision:"deny",reason:"rejected by user"}}).then(()=>t()).catch(()=>t()):l==="p"&&T(`/tasks/${e.taskId}/approve-plan`,{method:"POST",body:{planId:e.planId,decision:"allow",approvalType:"permanent"}}).then(()=>t()).catch(()=>t())});let m=e.plan.overallRisk==="high"?"red":e.plan.overallRisk==="medium"?"yellow":"green";return Ee(Ct,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",paddingX:1,children:[Oe(le,{bold:!0,color:"cyan",children:"EXECUTION PLAN \u2014 APPROVAL REQUIRED"}),Ee(le,{dimColor:!0,children:["Plan ID: ",e.planId]}),Ee(le,{dimColor:!0,children:["Time remaining: ",d,"s"]}),Ee(Ct,{marginTop:1,children:[Oe(le,{children:"Overall Risk: "}),Oe(le,{bold:!0,color:m,children:e.plan.overallRisk.toUpperCase()})]}),Ee(le,{bold:!0,children:["Steps (",e.plan.steps.length,"):"]}),e.plan.steps.map(l=>{let i=l.riskLevel==="high"?"red":l.riskLevel==="medium"?"yellow":"green";return Ee(Ct,{paddingLeft:2,children:[Ee(le,{children:["[",l.index,"] "]}),Oe(le,{children:l.description}),Ee(le,{dimColor:!0,children:[" (",l.toolsNeeded.join(", "),")"]}),Ee(le,{color:i,children:[" [",l.riskLevel,"]"]})]},l.index)}),Ee(Ct,{marginTop:1,children:[Oe(le,{dimColor:!0,children:"Permissions: "}),Oe(le,{children:Object.keys(e.plan.requiredPermissions).join(", ")||"none"})]}),Ee(Ct,{marginTop:1,children:[Oe(le,{color:"green",children:"[a] Allow once "}),Oe(le,{color:"green",children:"[p] Allow permanent "}),Oe(le,{color:"red",children:"[r] Deny"})]})]})}import{Box as ot,Text as J,useInput as Vr}from"ink";import{useEffect as qr,useState as Ve,useCallback as Mo}from"react";import{Box as Q,Text as D,useInput as $r}from"ink";import{useState as Zt,useEffect as Or}from"react";import{jsx as $,jsxs as U}from"react/jsx-runtime";function Ro({taskId:e,onBack:t}){let[o,d]=Zt(null),[u,m]=Zt([]),[l,i]=Zt(null);if(Or(()=>{T(`/tasks/${e}`).then(r=>d(r)).catch(r=>i(r instanceof Error?r.message:String(r))),T(`/tasks/${e}/plan`).then(r=>m(r.plans)).catch(()=>m([]))},[e]),$r((r,a)=>{(r==="b"||a.escape)&&t()}),l)return U(Q,{flexDirection:"column",children:[U(D,{color:"red",children:["Error: ",l]}),$(D,{dimColor:!0,children:"[b] Back"})]});if(!o)return U(D,{dimColor:!0,children:["Loading task ",e,"..."]});let s=u[0];return U(Q,{flexDirection:"column",children:[$(D,{bold:!0,color:"cyan",children:"Task Detail"}),U(Q,{marginTop:1,flexDirection:"column",children:[U(Q,{children:[$(D,{children:"ID: "}),$(D,{dimColor:!0,children:String(o.id)})]}),U(Q,{children:[$(D,{children:"Status: "}),$(D,{bold:!0,children:String(o.status)})]}),U(Q,{children:[$(D,{children:"Prompt: "}),$(D,{children:String(o.prompt)})]}),o.result?U(Q,{children:[$(D,{children:"Result: "}),$(D,{children:String(o.result).slice(0,200)})]}):null,o.error?U(Q,{children:[$(D,{color:"red",children:"Error: "}),$(D,{children:String(o.error)})]}):null,o.deliverTo?.length?U(Q,{children:[$(D,{children:"DeliverTo: "}),$(D,{dimColor:!0,children:o.deliverTo.map(r=>r.type==="channel"?`channel ${r.channelId?.slice(0,8)}`:`session ${r.sessionId?.slice(0,8)}`).join(", ")})]}):null,o.reportTo?.length?U(Q,{children:[$(D,{children:"ReportTo: "}),$(D,{dimColor:!0,children:o.reportTo.map(r=>r.type==="channel"?`channel ${r.channelId?.slice(0,8)}`:`session ${r.sessionId?.slice(0,8)}`).join(", ")})]}):null]}),s&&U(Q,{marginTop:1,flexDirection:"column",children:[$(D,{bold:!0,color:"cyan",children:"Execution Plan"}),U(Q,{children:[$(D,{children:"Plan ID: "}),$(D,{dimColor:!0,children:s.id})]}),U(Q,{children:[$(D,{children:"Status: "}),$(D,{children:s.status})]}),s.plan.overallRisk&&U(Q,{children:[$(D,{children:"Overall Risk: "}),$(D,{bold:!0,color:s.plan.overallRisk==="high"?"red":s.plan.overallRisk==="medium"?"yellow":"green",children:s.plan.overallRisk.toUpperCase()})]}),U(D,{bold:!0,children:["Steps (",s.plan.steps.length,"):"]}),s.plan.steps.map(r=>{let a=r.riskLevel==="high"?"red":r.riskLevel==="medium"?"yellow":"green";return U(Q,{paddingLeft:2,children:[U(D,{children:["[",r.index,"] ",r.description]}),U(D,{color:a,children:[" [",r.riskLevel,"]"]})]},r.index)}),s.deviationReport&&U(Q,{marginTop:1,flexDirection:"column",children:[$(D,{bold:!0,color:"yellow",children:"Deviation Report"}),U(D,{children:["Planned: ",s.deviationReport.stepsPlanned," | Executed: ",s.deviationReport.stepsExecuted," | Accuracy: ",(s.deviationReport.overallAccuracy*100).toFixed(0),"%"]}),s.deviationReport.deviations.map((r,a)=>U(Q,{paddingLeft:2,children:[U(D,{color:"yellow",children:["[",r.deviationType,"] "]}),U(D,{children:["Step ",r.stepIndex,": ",r.actual]})]},a))]}),s.learnedRules&&s.learnedRules.length>0&&U(Q,{marginTop:1,flexDirection:"column",children:[$(D,{bold:!0,color:"blue",children:"Learned Rules"}),s.learnedRules.map((r,a)=>$(Q,{paddingLeft:2,children:U(D,{children:["* ",r]})},a))]})]}),!s&&u.length===0&&$(Q,{marginTop:1,children:$(D,{dimColor:!0,children:"No execution plan for this task."})}),$(Q,{marginTop:1,children:$(D,{dimColor:!0,children:"[b] Back"})})]})}import{Fragment as Wr,jsx as ce,jsxs as pe}from"react/jsx-runtime";var Ur={pending:"gray",queued:"gray",running:"yellow",paused:"yellow",completed:"green",failed:"red",cancelled:"gray"},Lt=["all","pending","queued","running","completed","failed","cancelled"],eo=15;function _t({onBack:e}){let[t,o]=Ve([]),[d,u]=Ve(!0),[m,l]=Ve("list"),[i,s]=Ve(0),[r,a]=Ve("all"),[c,h]=Ve(0),[f,x]=Ve(0),[n,g]=Ve(null),[R,k]=Ve([]),H=Mo(async()=>{u(!0);try{let B=new URLSearchParams({limit:"100"});r!=="all"&&B.set("status",r);let S=await T(`/tasks?${B}`);o(S.tasks)}catch{o([])}finally{u(!1)}},[r]);qr(()=>{H()},[H]);let W=Math.max(1,Math.ceil(t.length/eo)),I=t.slice(f*eo,(f+1)*eo),te=Mo(async()=>{let B=I[i];if(B)try{await T(`/tasks/${B.id}/cancel`,{method:"POST"}),g(`Cancelled: ${B.id.slice(0,8)}`),l("list"),H()}catch(S){g(`Failed: ${S instanceof Error?S.message:String(S)}`),l("list")}},[I,i,H]);return Vr((B,S)=>{if(m==="detail"){(S.escape||S.return||B==="q")&&l("list");return}if(m==="cancelling"){B==="y"?te():l("list");return}if(m==="filter"){if(S.escape){l("list");return}S.upArrow&&c>0&&h(p=>p-1),S.downArrow&&c<Lt.length-1&&h(p=>p+1),S.return&&(a(Lt[c]),x(0),s(0),l("list"));return}if(S.escape||B==="q"){e();return}if(S.upArrow&&i>0&&s(p=>p-1),S.downArrow&&i<I.length-1&&s(p=>p+1),S.return){let p=I[i];p&&(k([]),l("detail"),T(`/tasks/${p.id}/logs?limit=20`).then(({logs:P})=>k(P)).catch(()=>k([])))}if(B==="x"&&I[i]){let p=I[i];["running","pending","queued","paused"].includes(p.status)?(l("cancelling"),g(null)):g(`Cannot cancel task in status: ${p.status}`)}B==="f"&&(h(Lt.indexOf(r)),l("filter")),B==="r"&&H(),(S.pageDown||B==="n")&&f<W-1&&(x(p=>p+1),s(0)),(S.pageUp||B==="p")&&f>0&&(x(p=>p-1),s(0))}),d?ce(J,{dimColor:!0,children:"Loading tasks..."}):m==="filter"?pe(ot,{flexDirection:"column",children:[ce(J,{bold:!0,children:"Filter by status:"}),Lt.map((B,S)=>ce(ot,{children:pe(J,{color:S===c?"cyan":"white",children:[S===c?"> ":" ",B,B===r?" (current)":""]})},B)),ce(J,{dimColor:!0,children:"Enter: select Esc: cancel"})]}):m==="detail"&&I[i]?ce(Ro,{taskId:I[i].id,onBack:()=>l("list")}):m==="cancelling"&&I[i]?pe(ot,{flexDirection:"column",children:[pe(J,{color:"red",children:['Cancel task "',I[i].id.slice(0,8),'"? (y/n)']}),n&&ce(J,{color:"red",children:n})]}):pe(ot,{flexDirection:"column",children:[pe(ot,{children:[pe(J,{bold:!0,children:["Tasks (",t.length,")"]}),r!=="all"&&pe(J,{dimColor:!0,children:[" [filter: ",r,"]"]}),pe(J,{dimColor:!0,children:[" \u2014 Page ",f+1,"/",W]})]}),n&&ce(J,{color:n.startsWith("Failed")||n.startsWith("Cannot")?"red":"green",children:n}),t.length===0?pe(J,{dimColor:!0,children:["No tasks found",r!=="all"?` with status "${r}"`:"","."]}):pe(Wr,{children:[ce(ot,{marginTop:1,children:pe(J,{bold:!0,children:[" ",Ye("ID",10),Ye("STATUS",12),Ye("PROMPT",40),Ye("DURATION",10),"COST"]})}),I.map((B,S)=>{let p=S===i,P=B.totalDurationMs?`${(B.totalDurationMs/1e3).toFixed(0)}s`:"\u2014",N=B.costUsd!==void 0?`$${B.costUsd.toFixed(4)}`:"\u2014",_e=Ur[B.status]??"white";return pe(ot,{children:[ce(J,{color:p?"cyan":"white",children:p?"> ":" "}),ce(J,{dimColor:!0,children:Ye(B.id.slice(0,8),10)}),ce(J,{color:_e,children:Ye(B.status,12)}),ce(J,{children:Ye(Fr(B.prompt,38),40)}),ce(J,{dimColor:!0,children:Ye(P,10)}),ce(J,{dimColor:!0,children:N})]},B.id)})]}),ce(J,{dimColor:!0,children:"Enter:detail x:cancel f:filter n/p:page r:refresh Esc/q:back"})]})}function Ye(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}function Fr(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}uo();import{Box as vt,Text as we,useInput as Gr}from"ink";import{useEffect as Hr,useState as No}from"react";import{readFileSync as Kr,existsSync as jr}from"fs";import{parse as Qr}from"yaml";import{Fragment as Xr,jsx as Be,jsxs as Je}from"react/jsx-runtime";function _o({onBack:e}){let[t,o]=No(null),[d,u]=No(null);return Gr((m,l)=>{(l.escape||m==="q")&&e()}),Hr(()=>{try{let m=co;if(!jr(m)){u(`Config file not found: ${m}`);return}let l=Kr(m,"utf-8");o(Qr(l))}catch(m){u(m.message)}},[]),d?Je(vt,{flexDirection:"column",children:[Be(we,{color:"red",children:d}),Be(we,{dimColor:!0,children:"Press Esc to go back"})]}):t?Je(vt,{flexDirection:"column",children:[Be(we,{bold:!0,children:"Configuration (Esc to go back)"}),Be(vt,{marginTop:1,flexDirection:"column",children:Be($o,{obj:t,indent:0})})]}):Be(we,{dimColor:!0,children:"Loading config..."})}function $o({obj:e,indent:t}){let o=" ".repeat(t);return Be(Xr,{children:Object.entries(e).map(([d,u])=>u&&typeof u=="object"&&!Array.isArray(u)?Je(vt,{flexDirection:"column",children:[Je(we,{children:[o,Be(we,{color:"cyan",children:d}),":"]}),Be($o,{obj:u,indent:t+1})]},d):Array.isArray(u)?Je(vt,{flexDirection:"column",children:[Je(we,{children:[o,Be(we,{color:"cyan",children:d}),":"]}),u.map((m,l)=>Je(we,{children:[o," - ",Lo(d,String(m))]},l))]},d):Je(we,{children:[o,Be(we,{color:"cyan",children:d}),": ",Lo(d,String(u))]},d))})}function Lo(e,t){return e.toLowerCase().includes("key")||e.toLowerCase().includes("token")?!t||t.length<8?"****":t.slice(0,4)+"****":t}import{Box as $t,Text as Ie,useInput as zr}from"ink";import{useEffect as Yr,useState as to}from"react";import{jsx as Et,jsxs as Me}from"react/jsx-runtime";function Oo({onBack:e}){let[t,o]=to([]),[d,u]=to(!0),[m,l]=to(null);return zr((i,s)=>{(s.escape||i==="q")&&e()}),Yr(()=>{T("/evolution-audit?limit=20").then(i=>{o(i),u(!1)}).catch(i=>{l(i.message),u(!1)})},[]),d?Et(Ie,{dimColor:!0,children:"Loading evolution log..."}):m?Me($t,{flexDirection:"column",children:[Et(Ie,{color:"red",children:m}),Et(Ie,{dimColor:!0,children:"Press Esc to go back"})]}):t.length===0?Me($t,{flexDirection:"column",children:[Et(Ie,{dimColor:!0,children:"No evolution records yet"}),Et(Ie,{dimColor:!0,children:"Press Esc to go back"})]}):Me($t,{flexDirection:"column",children:[Me(Ie,{bold:!0,children:["Evolution Audit Log (",t.length," records) \u2014 Esc to go back"]}),t.map(i=>Me($t,{flexDirection:"column",marginTop:1,children:[Me(Ie,{bold:!0,children:["[",new Date(i.timestamp).toLocaleString(),"]"]}),i.triggerTaskId&&Me(Ie,{dimColor:!0,children:[" Task: ",i.triggerTaskId.slice(0,8)]}),i.diff.split(`
5
+ `).map((s,r)=>s.startsWith("+")?Me(Ie,{color:"green",children:[" ",s]},r):s.startsWith("-")?Me(Ie,{color:"red",children:[" ",s]},r):Me(Ie,{dimColor:!0,children:[" ",s]},r))]},i.id))]})}import{Box as qe,Text as X,useInput as Jr}from"ink";import Zr from"ink-text-input";import{useEffect as en,useState as at}from"react";import{jsx as fe,jsxs as oe}from"react/jsx-runtime";var tn={pending:"gray",planning:"cyan",executing:"yellow",evaluating:"blue",replanning:"magenta",completed:"green",failed:"red",paused:"gray"};function on(e,t=20){let o=Math.round(e*t),d=t-o;return"\u2588".repeat(o)+"\u2591".repeat(d)}function rn(e){let t=Math.max(0,Math.floor((e-Date.now())/864e5));return t===0?"< 1d":`${t}d`}function Ot({onBack:e}){let[t,o]=at([]),[d,u]=at(null),[m,l]=at("list"),[i,s]=at(""),[r,a]=at(!1),[c,h]=at(null);Jr((n,g)=>{if(m==="create"){g.escape&&(l("list"),s(""),h(null));return}(g.escape||n==="q")&&e(),n==="c"&&(l("create"),h(null)),n==="r"&&f()});let f=()=>{T("/goals?limit=20").then(({goals:n})=>o(n)).catch(n=>u(n.message))};en(()=>{f()},[]);let x=async n=>{if(n.trim()){a(!0),h(null);try{let g=await T("/goals",{method:"POST",body:{input:n.trim()}});h(`Goal created: ${g.goal.name}`),s(""),l("list"),f()}catch(g){h(`Failed: ${g instanceof Error?g.message:String(g)}`)}finally{a(!1)}}};return d?oe(qe,{flexDirection:"column",children:[oe(X,{color:"red",children:["Failed to load goals: ",d]}),fe(X,{dimColor:!0,children:"Press Esc or q to return"})]}):m==="create"?oe(qe,{flexDirection:"column",children:[fe(X,{bold:!0,children:"Create Goal"}),fe(X,{dimColor:!0,children:"Describe your SMART goal in natural language:"}),oe(qe,{marginTop:1,children:[fe(X,{color:"cyan",children:"> "}),fe(Zr,{value:i,onChange:s,onSubmit:x})]}),r&&fe(X,{color:"yellow",children:"Creating goal..."}),c&&fe(X,{color:c.startsWith("Failed")?"red":"green",children:c}),fe(X,{dimColor:!0,children:"Press Esc to cancel"})]}):oe(qe,{flexDirection:"column",children:[oe(X,{bold:!0,children:["Goal Dashboard (",t.length,")"]}),t.length===0?fe(X,{dimColor:!0,children:"No goals found. Press c to create one."}):fe(qe,{marginTop:1,flexDirection:"column",children:t.map(n=>{let g=n.targetValue>0?n.currentValue/n.targetValue:0,R=tn[n.status]??"white";return oe(qe,{marginBottom:1,flexDirection:"column",children:[oe(qe,{children:[fe(X,{bold:!0,color:R,children:n.name}),oe(X,{dimColor:!0,children:[" (",n.role,")"]}),fe(X,{dimColor:!0,children:" \u2014 "}),fe(X,{color:R,children:n.status})]}),oe(qe,{children:[oe(X,{dimColor:!0,children:[" ",on(g)," "]}),oe(X,{color:g>=1?"green":"white",children:[Math.round(g*100),"%"]}),oe(X,{dimColor:!0,children:[" (",n.currentValue,"/",n.targetValue," ",n.metricType,")"]})]}),oe(qe,{children:[oe(X,{dimColor:!0,children:[" \u23F0 ",rn(n.deadline)," left"]}),oe(X,{dimColor:!0,children:[" | \u{1F4B0} $",n.budgetUsd]}),oe(X,{dimColor:!0,children:[" | ID: ",n.id.slice(0,8)]})]})]},n.id)})}),fe(X,{dimColor:!0,children:"c:create r:refresh Esc/q:back"})]})}import{Box as lt,Text as be,useInput as nn}from"ink";import{useEffect as sn,useState as Vo}from"react";import{jsx as Fe,jsxs as Ue}from"react/jsx-runtime";function an(e,t,o=15){let d=e/(e+t),u=Math.round(d*o);return"\u2593".repeat(u)+"\u2591".repeat(o-u)}function qo({onBack:e}){let[t,o]=Vo([]),[d,u]=Vo(null);if(nn((l,i)=>{(i.escape||l==="q")&&e()}),sn(()=>{T("/strategies?limit=50").then(l=>o(l.strategies??[])).catch(l=>u(l.message))},[]),d)return Ue(lt,{flexDirection:"column",children:[Ue(be,{color:"red",children:["Failed to load strategies: ",d]}),Fe(be,{dimColor:!0,children:"Press Esc or q to return"})]});if(t.length===0)return Ue(lt,{flexDirection:"column",children:[Fe(be,{dimColor:!0,children:"No strategies yet. Strategies are created when goals are executed."}),Fe(be,{dimColor:!0,children:"Press Esc or q to return"})]});let m=new Map;for(let l of t){let i=`${l.role}/${l.taskType}`,s=m.get(i)??[];s.push(l),m.set(i,s)}return Ue(lt,{flexDirection:"column",children:[Fe(be,{bold:!0,children:"Strategy Lab"}),Fe(be,{dimColor:!0,children:"Thompson Sampling populations \u2014 higher bar = higher selection probability"}),Fe(lt,{marginTop:1,flexDirection:"column",children:Array.from(m.entries()).map(([l,i])=>Ue(lt,{marginBottom:1,flexDirection:"column",children:[Fe(be,{bold:!0,color:"cyan",children:l}),i.sort((s,r)=>{let a=s.alpha/(s.alpha+s.beta);return r.alpha/(r.alpha+r.beta)-a}).map(s=>{let r=s.alpha/(s.alpha+s.beta);return Ue(lt,{children:[Fe(be,{dimColor:!0,children:" "}),Ue(be,{children:[an(s.alpha,s.beta)," "]}),Ue(be,{color:r>.6?"green":r>.4?"yellow":"red",children:[(r*100).toFixed(0),"%"]}),Ue(be,{dimColor:!0,children:[" ",s.name," (\u03B1=",s.alpha.toFixed(1)," \u03B2=",s.beta.toFixed(1)," trials=",s.totalTrials,")"]})]},s.id)})]},l))}),Fe(be,{dimColor:!0,children:"Press Esc or q to return"})]})}import{Box as xe,Text as K,useInput as mn}from"ink";import oo from"ink-text-input";import{useEffect as gn,useState as We,useCallback as ct}from"react";import{CronExpressionParser as fn}from"cron-parser";import{useState as ln,useEffect as cn,useCallback as Uo,useRef as dn}from"react";var un=3e3;function Ze(){let[e,t]=ln(null),o=dn(null),d=Uo(()=>{o.current&&(clearTimeout(o.current),o.current=null),t(null)},[]),u=Uo((m,l)=>{o.current&&(clearTimeout(o.current),o.current=null),t({text:m,type:l}),l==="success"&&(o.current=setTimeout(()=>{t(null),o.current=null},un))},[]);return cn(()=>()=>{o.current&&clearTimeout(o.current)},[]),{message:e,setMessage:u,clearMessage:d}}import{jsx as j,jsxs as se}from"react/jsx-runtime";var ro=["manual","cron","event"],Vt={name:"",triggerType:"manual",cron:"",stepPrompt:""};function pn(e){try{return fn.parse(e).next().toDate().toLocaleString()}catch{return"invalid"}}function Ut({onBack:e}){let[t,o]=We([]),[d,u]=We(!0),[m,l]=We(0),[i,s]=We("list"),[r,a]=We({...Vt}),[c,h]=We("name"),[f,x]=We(null),{message:n,setMessage:g,clearMessage:R}=Ze(),[k,H]=We(!1),[W,I]=We(!1),te=ct(()=>{u(!0),T("/task-templates").then(({templates:b})=>{o(b),u(!1)}).catch(()=>u(!1))},[]);gn(()=>{te()},[te]);let B=i==="create"||i==="edit",S=ct(async()=>{let b=t[m];if(!(!b||k)){H(!0),g(`Triggering ${b.name}...`,"loading");try{let w=await T(`/task-templates/${b.id}/run`,{method:"POST"});g(`Triggered: ${b.name} (${w.executionId})`,"success")}catch(w){g(`Trigger failed: ${w instanceof Error?w.message:String(w)}`,"error")}finally{H(!1)}}},[t,m,k,g]),p=ct(async()=>{let b=t[m];if(!b||W)return;if(b.trigger?.type!=="cron"&&b.trigger?.type!=="event"){g("Toggle not applicable for manual triggers","error");return}let w=!b.enabled;I(!0),g(`${b.name} \u2192 ${w?"enabling":"disabling"}...`,"loading");try{await T(`/task-templates/${b.id}`,{method:"PATCH",body:{enabled:w}}),o(_=>_.map(ne=>ne.id===b.id?{...ne,enabled:w}:ne)),g(`${b.name} ${w?"enabled":"disabled"}`,"success")}catch(_){g(`Toggle failed: ${_ instanceof Error?_.message:String(_)}`,"error")}finally{I(!1)}},[t,m,W,g]),P=ct(async()=>{let b=t[m];if(b)try{await T(`/task-templates/${b.id}`,{method:"DELETE"}),g(`Deleted: ${b.name}`,"success"),te(),l(w=>Math.max(0,Math.min(w,t.length-2)))}catch(w){g(`Delete failed: ${w instanceof Error?w.message:String(w)}`,"error")}},[t,m,te]),N=ct(()=>{let b=t[m];b&&(x(b.id),a({name:b.name,triggerType:b.trigger?.type??"manual",cron:b.trigger?.cron??"",stepPrompt:b.steps?.[0]?.prompt??""}),h("name"),s("edit"))},[t,m]),_e=ct(async()=>{let b={name:r.name,trigger:{type:r.triggerType,...r.triggerType==="cron"?{cron:r.cron}:{}},steps:[{id:"step-1",prompt:r.stepPrompt}],enabled:!0};try{i==="create"?(await T("/task-templates",{method:"POST",body:b}),g(`Created: ${r.name}`,"success")):i==="edit"&&f&&(await T(`/task-templates/${f}`,{method:"PATCH",body:b}),g(`Updated: ${r.name}`,"success"))}catch(w){g(`Save failed: ${w instanceof Error?w.message:String(w)}`,"error")}s("list"),a({...Vt}),x(null),te()},[r,i,f,te]);return mn((b,w)=>{if(B){if(w.escape){s("list"),a({...Vt}),x(null);return}if(w.return){let _=["name","triggerType","cron","stepPrompt"],ne=_.indexOf(c);if(ne<_.length-1){let je=ne+1;if(_[je]==="cron"&&r.triggerType!=="cron"&&je++,je<_.length){h(_[je]);return}}_e();return}if(w.tab&&c==="triggerType"){a(_=>{let ne=ro.indexOf(_.triggerType);return{..._,triggerType:ro[(ne+1)%ro.length]}});return}return}if(w.escape||b==="q"){e();return}if(w.upArrow){l(_=>Math.max(0,_-1));return}if(w.downArrow){l(_=>Math.min(t.length-1,_+1));return}if(b==="t"){S();return}if(b==="d"){P();return}if(b==="e"){N();return}if(b==="c"){a({...Vt}),h("name"),s("create");return}if(b==="s"||b===" "){p();return}b==="r"&&(te(),R())}),d?j(K,{dimColor:!0,children:"Loading templates..."}):B?se(xe,{flexDirection:"column",children:[se(K,{bold:!0,children:[i==="create"?"Create Template":"Edit Template"," (Esc to cancel)"]}),se(xe,{marginTop:1,flexDirection:"column",children:[se(xe,{children:[se(K,{bold:c==="name",color:c==="name"?"cyan":void 0,children:["Name:"," "]}),c==="name"?j(oo,{value:r.name,onChange:b=>a(w=>({...w,name:b})),placeholder:"template name"}):j(K,{children:r.name||"(empty)"})]}),se(xe,{children:[se(K,{bold:c==="triggerType",color:c==="triggerType"?"cyan":void 0,children:["Trigger:"," "]}),j(K,{children:r.triggerType}),c==="triggerType"&&j(K,{dimColor:!0,children:" (Tab to cycle, Enter to continue)"})]}),r.triggerType==="cron"&&se(xe,{children:[se(K,{bold:c==="cron",color:c==="cron"?"cyan":void 0,children:["Cron:"," "]}),c==="cron"?j(oo,{value:r.cron,onChange:b=>a(w=>({...w,cron:b})),placeholder:"*/5 * * * *"}):j(K,{children:r.cron||"(empty)"})]}),se(xe,{children:[se(K,{bold:c==="stepPrompt",color:c==="stepPrompt"?"cyan":void 0,children:["Step Prompt:"," "]}),c==="stepPrompt"?j(oo,{value:r.stepPrompt,onChange:b=>a(w=>({...w,stepPrompt:b})),placeholder:"What should this template do?"}):j(K,{children:r.stepPrompt||"(empty)"})]})]}),j(xe,{marginTop:1,children:j(K,{dimColor:!0,children:"Enter: next field / submit | Esc: cancel"})})]}):se(xe,{flexDirection:"column",children:[se(K,{bold:!0,children:["Automations (",t.length,") (Esc to go back)"]}),n&&j(xe,{marginTop:1,children:se(K,{color:n.type==="success"?"green":n.type==="error"?"red":"gray",children:[n.type==="success"?"\u2713 ":n.type==="error"?"\u2717 ":"\u2192 ",n.text]})}),t.length===0?j(xe,{marginTop:1,children:j(K,{dimColor:!0,children:"No templates found. Press c to create one."})}):j(xe,{marginTop:1,flexDirection:"column",children:t.map((b,w)=>{let _=w===m,ne=b.trigger?.type==="cron"&&b.trigger?.cron?pn(b.trigger.cron):"";return se(xe,{children:[j(K,{color:_?"cyan":void 0,bold:_,children:_?"> ":" "}),j(K,{color:_?"cyan":void 0,bold:_,children:qt(b.name,24)}),j(K,{dimColor:!0,children:qt(b.trigger?.type,10)}),b.trigger?.type!=="cron"&&b.trigger?.type!=="event"?j(K,{dimColor:!0,children:qt("\u2014",6)}):j(K,{color:b.enabled?"green":"gray",children:qt(b.enabled?"on":"off",6)}),ne&&se(K,{dimColor:!0,children:["next: ",ne]})]},b.id)})}),j(xe,{marginTop:1,children:j(K,{dimColor:!0,children:"t:trigger s:toggle d:delete e:edit c:create r:refresh"})})]})}function qt(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}import{Box as et,Text as Te,useInput as xn}from"ink";import Tn from"ink-text-input";import{useEffect as hn,useState as dt,useCallback as Fo}from"react";import{jsx as de,jsxs as rt}from"react/jsx-runtime";function Wo({onBack:e}){let[t,o]=dt([]),[d,u]=dt(""),[m,l]=dt(!0),[i,s]=dt(!1),[r,a]=dt(""),[c,h]=dt(null),f=Fo(()=>{l(!0),T("/webhooks").then(({webhooks:n,auth:g})=>{o(n),u(g),l(!1)}).catch(()=>l(!1))},[]);hn(()=>{f()},[f]);let x=Fo(async n=>{if(n.trim())try{let g=await T(`/webhooks/${encodeURIComponent(n.trim())}`,{method:"POST"});h(`Triggered: ${g.executionId}`)}catch(g){h(`Trigger failed: ${g instanceof Error?g.message:String(g)}`)}},[]);return xn((n,g)=>{if(i){if(g.escape){s(!1),a("");return}if(g.return){x(r),s(!1),a("");return}return}if(g.escape||n==="q"){e();return}if(n==="t"){s(!0),a(""),h(null);return}n==="r"&&(f(),h(null))}),m?de(Te,{dimColor:!0,children:"Loading webhooks..."}):rt(et,{flexDirection:"column",children:[rt(Te,{bold:!0,children:["Webhooks (",t.length,") (Esc to go back)"]}),rt(Te,{dimColor:!0,children:["Auth: ",d]}),c&&de(et,{marginTop:1,children:de(Te,{color:"yellow",children:c})}),i&&rt(et,{marginTop:1,children:[de(Te,{bold:!0,color:"cyan",children:"Trigger webhook: "}),de(Tn,{value:r,onChange:a,placeholder:"webhook name or ID"}),de(Te,{dimColor:!0,children:" (Enter to trigger, Esc to cancel)"})]}),t.length===0?de(et,{marginTop:1,children:de(Te,{dimColor:!0,children:"No webhooks available. Create templates with triggers to expose webhooks."})}):rt(et,{marginTop:1,flexDirection:"column",children:[de(et,{children:rt(Te,{bold:!0,children:[ut("NAME",24),ut("DESCRIPTION",36),ut("TRIGGER",28),"TAGS"]})}),t.map(n=>rt(et,{children:[de(Te,{children:ut(n.displayName,24)}),de(Te,{dimColor:!0,children:ut(yn(n.description??"",34),36)}),de(Te,{dimColor:!0,children:ut(n.trigger,28)}),de(Te,{dimColor:!0,children:n.tags?.join(", ")??""})]},n.name))]}),de(et,{marginTop:1,children:de(Te,{dimColor:!0,children:"t:trigger r:refresh"})})]})}function ut(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}function yn(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}import{Box as Ne,Text as Z,useInput as bn}from"ink";import Sn from"ink-text-input";import{useEffect as Go,useState as Ge,useCallback as no}from"react";import{jsx as ee,jsxs as ke}from"react/jsx-runtime";function Cn(e){return e>=4?"red":e===3?"yellow":"gray"}function vn(e){return e>=4?"HIGH":e===3?"MED ":"LOW "}function En(e){return new Date(e).toLocaleDateString()}function Ko({onBack:e}){let[t,o]=Ge([]),[d,u]=Ge(0),[m,l]=Ge([]),[i,s]=Ge(!0),[r,a]=Ge(!1),[c,h]=Ge(""),[f,x]=Ge("all"),[n,g]=Ge(null),[R,k]=Ge(!1),H=no(()=>{T("/agents").then(({agents:p})=>{o(p),s(!1)}).catch(()=>s(!1))},[]);Go(()=>{H()},[H]);let W=t[d],I=no(()=>{W&&(k(!1),T(`/memories/${W.id}`).then(({memories:p})=>{l(p),g(null)}).catch(p=>g(`Failed: ${p instanceof Error?p.message:String(p)}`)))},[W]);Go(()=>{W&&I()},[W,I]);let te=no(async p=>{if(!(!W||!p.trim()))try{let P=await T("/memories/query",{method:"POST",body:{agentId:W.id,prompt:p.trim()}});l(P.memories),k(!0),g(`Search: ${P.count} results`)}catch(P){g(`Search failed: ${P instanceof Error?P.message:String(P)}`)}},[W]),B=r,S=m.filter(p=>f==="all"?!0:f==="high"?p.importance>3:f==="medium"?p.importance===3:p.importance<3);return bn((p,P)=>{if(B){if(P.escape){a(!1),h("");return}if(P.return){te(c),a(!1),h("");return}return}if(P.escape||p==="q"){e();return}if(p==="a"){u(N=>(N+1)%Math.max(1,t.length));return}if(P.leftArrow){u(N=>(N-1+t.length)%Math.max(1,t.length));return}if(P.rightArrow){u(N=>(N+1)%Math.max(1,t.length));return}if(p==="s"){a(!0),h(""),g(null);return}if(p==="h"){x(N=>N==="high"?"all":"high");return}if(p==="m"){x(N=>N==="medium"?"all":"medium");return}if(p==="l"){x(N=>N==="low"?"all":"low");return}p==="r"&&I()}),i?ee(Z,{dimColor:!0,children:"Loading agents..."}):t.length===0?ke(Ne,{flexDirection:"column",children:[ee(Z,{dimColor:!0,children:"No agents found"}),ee(Z,{dimColor:!0,children:"Press Esc to go back"})]}):ke(Ne,{flexDirection:"column",children:[ee(Z,{bold:!0,children:"Memories (Esc to go back)"}),ke(Ne,{marginTop:1,children:[ee(Z,{children:"Agent: "}),ee(Z,{bold:!0,color:"cyan",children:W?.name??"?"}),ke(Z,{dimColor:!0,children:[" (",d+1,"/",t.length,") [a/arrows to switch]"]})]}),ee(Ne,{children:ke(Z,{dimColor:!0,children:["Filter: ",f==="all"?"all":f," | ",R?"search results":"all memories"," (",S.length,")"]})}),n&&ee(Ne,{children:ee(Z,{color:"yellow",children:n})}),r&&ke(Ne,{marginTop:1,children:[ee(Z,{bold:!0,color:"cyan",children:"Search: "}),ee(Sn,{value:c,onChange:h,placeholder:"search query..."}),ee(Z,{dimColor:!0,children:" (Enter to search, Esc to cancel)"})]}),S.length===0?ee(Ne,{marginTop:1,children:ke(Z,{dimColor:!0,children:["No memories",f!=="all"?` matching filter '${f}'`:""]})}):ee(Ne,{marginTop:1,flexDirection:"column",children:S.map(p=>ke(Ne,{marginBottom:0,children:[ke(Z,{color:Cn(p.importance),bold:!0,children:[vn(p.importance)," "]}),ee(Z,{dimColor:!0,children:Ho(p.type??"?",12)}),ee(Z,{dimColor:!0,children:Ho(`\xD7${p.retrievedCount??0}`,5)}),ke(Z,{children:[wn(p.content,55)," "]}),ee(Z,{dimColor:!0,children:En(p.createdAt)}),p.score!==void 0&&ke(Z,{dimColor:!0,children:[" (",p.score.toFixed(2),")"]})]},p.id))}),ee(Ne,{marginTop:1,children:ee(Z,{dimColor:!0,children:"s:search h:high m:medium l:low a:agent r:refresh"})})]})}function Ho(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}function wn(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}import{Box as nt,Text as he,useInput as Bn}from"ink";import In from"ink-text-input";import{useState as He,useEffect as jo,useCallback as Qo}from"react";import{jsx as Pe,jsxs as Le}from"react/jsx-runtime";var Xo={Anthropic:["anthropic.apiKey","anthropic.baseUrl","anthropic.model","anthropic.defaultOpusModel","anthropic.defaultSonnetModel","anthropic.defaultHaikuModel","anthropic.smallFastModel"],Defaults:["defaults.model","defaults.effort","defaults.maxTurns","defaults.maxBudgetUsd","defaults.timeout"],Server:["server.port","server.host","server.apiKey","server.timezone"],Logging:["logging.level"],Evolution:["roles.evolution.triggerEvery","roles.evolution.reflectionThreshold"],Chat:["chat.sessionTimeoutMinutes","chat.maxSessionTurns","chat.autoTitle","chat.archiveExtractMemory"]},kn={"anthropic.apiKey":"API Key","anthropic.baseUrl":"Base URL","anthropic.model":"Model","anthropic.defaultOpusModel":"Default Opus","anthropic.defaultSonnetModel":"Default Sonnet","anthropic.defaultHaikuModel":"Default Haiku","anthropic.smallFastModel":"Small Fast","defaults.model":"Default Model","defaults.effort":"Effort","defaults.maxTurns":"Max Turns","defaults.maxBudgetUsd":"Max Budget (USD)","defaults.timeout":"Timeout (sec)","server.port":"Port","server.host":"Host","server.apiKey":"API Key","server.timezone":"Timezone","logging.level":"Log Level","roles.evolution.triggerEvery":"Evolution Trigger Every","chat.sessionTimeoutMinutes":"Session Timeout (min)","chat.maxSessionTurns":"Max Session Turns","chat.autoTitle":"Auto Title","chat.archiveExtractMemory":"Archive Extract Memory","roles.evolution.reflectionThreshold":"Reflection Threshold"};function zo({onBack:e}){let{state:t}=Xe(),[o,d]=He({}),[u,m]=He([]),[l,i]=He(null),[s,r]=He("view"),[a,c]=He(0),[h,f]=He(""),[x,n]=He(null),[g,R]=He(!1),[k,H]=He([]),W=Object.values(Xo).flat(),I=Qo(()=>{T("/config").then(S=>{d(S.config),m(S.mutable)}).catch(S=>i(S.message)),T("/config/env-diff").then(S=>{H(S.diffs)}).catch(()=>{})},[]);jo(()=>{I()},[I]),jo(()=>{t.configVersion>0&&I()},[t.configVersion,I]);let te=Qo(async()=>{let S=W[a];if(S){R(!0),n(null);try{let p=h,P=o[S];if(P&&typeof P.value=="number"&&(p=Number(h),isNaN(p))){n("Invalid number"),R(!1);return}let N=await T("/config",{method:"PATCH",body:{[S]:p}});N.updated.length>0&&(n(`Updated: ${S}`),I()),N.errors.length>0&&n(N.errors[0]),r("view")}catch(p){n(`Failed: ${p instanceof Error?p.message:String(p)}`)}finally{R(!1)}}},[W,a,h,o,I]);if(Bn((S,p)=>{if(s==="edit"){if(p.escape){r("view");return}return}if(p.escape||S==="q"){e();return}if(p.upArrow&&a>0&&c(P=>P-1),p.downArrow&&a<W.length-1&&c(P=>P+1),p.return||S==="e"){let P=W[a],N=o[P];N&&N.mutable?(f(String(N.value??"")),r("edit"),n(null)):N&&!N.mutable&&n("This setting requires a restart to change")}S==="r"&&(I(),n("Refreshed")),S==="s"&&k.length>0&&T("/config/sync-to-env",{method:"POST"}).then(()=>{n("Synced to .env"),H([]),I()}),S==="l"&&k.length>0&&T("/config/load-from-env",{method:"POST"}).then(()=>{n("Loaded from .env"),I()})}),l)return Le(nt,{flexDirection:"column",children:[Le(he,{color:"red",children:["Failed to load config: ",l]}),Pe(he,{dimColor:!0,children:"Press Esc or q to return"})]});let B=0;return Le(nt,{flexDirection:"column",children:[Pe(he,{bold:!0,children:"Settings"}),x&&Pe(he,{color:x.startsWith("Failed")||x.startsWith("This setting")?"yellow":"green",children:x}),k&&k.length>0&&Le(nt,{flexDirection:"column",marginBottom:1,children:[Le(he,{color:"yellow",children:[".env differs from DB (",k.length," key(s)): ",k.map(S=>S.envKey).join(", ")]}),Pe(he,{dimColor:!0,children:"s:sync DB\u2192.env l:load .env\u2192DB"})]}),Pe(nt,{marginTop:1,flexDirection:"column",children:Object.entries(Xo).map(([S,p])=>Le(nt,{marginBottom:1,flexDirection:"column",children:[Pe(he,{bold:!0,color:"cyan",children:S}),p.map(P=>{let N=o[P],b=B++===a,w=u.includes(P),_=kn[P]??P,ne=N?String(N.value??""):"...";return s==="edit"&&b?Le(nt,{children:[Le(he,{color:"cyan",children:["> ",_,": "]}),Pe(In,{value:h,onChange:f,onSubmit:()=>{te()}}),g&&Pe(he,{color:"yellow",children:" saving..."})]},P):Le(nt,{children:[Le(he,{color:b?"cyan":"white",children:[b?"> ":" ",w?" ":"\u{1F512} ",_,": "," "]}),Pe(he,{color:w?"white":"gray",children:ne}),!w&&Pe(he,{dimColor:!0,children:" (restart required)"})]},P)})]},S))}),Pe(he,{dimColor:!0,children:"Enter/e:edit r:refresh Esc/q:back"})]})}import{Box as st,Text as ue,useInput as Pn}from"ink";import{useEffect as An,useState as so,useCallback as Dn}from"react";import{jsx as ie,jsxs as gt}from"react/jsx-runtime";function Yo({onBack:e}){let[t,o]=so([]),[d,u]=so(!0),[m,l]=so(0),{message:i,setMessage:s,clearMessage:r}=Ze(),a=Dn(()=>{u(!0),T("/plugins").then(({plugins:c})=>{o(c),u(!1)}).catch(()=>u(!1))},[]);return An(()=>{a()},[a]),Pn((c,h)=>{if(h.escape||c==="q"){e();return}if(h.upArrow){l(f=>Math.max(0,f-1));return}if(h.downArrow){l(f=>Math.min(t.length-1,f+1));return}c==="r"&&(a(),r())}),d?ie(ue,{dimColor:!0,children:"Loading plugins..."}):gt(st,{flexDirection:"column",children:[gt(ue,{bold:!0,children:["Plugins (",t.length,") (Esc to go back)"]}),i&&ie(st,{marginTop:1,children:gt(ue,{color:i.type==="success"?"green":i.type==="error"?"red":"gray",children:[i.type==="success"?"\u2713 ":i.type==="error"?"\u2717 ":"\u2192 ",i.text]})}),t.length===0?ie(st,{marginTop:1,children:ie(ue,{dimColor:!0,children:"No plugins installed."})}):gt(st,{marginTop:1,flexDirection:"column",children:[gt(st,{children:[ie(ue,{dimColor:!0,children:" "}),ie(ue,{dimColor:!0,children:mt("Name",24)}),ie(ue,{dimColor:!0,children:mt("Scope",8)}),ie(ue,{dimColor:!0,children:mt("User",6)}),ie(ue,{dimColor:!0,children:"Path"})]}),t.map((c,h)=>{let f=h===m,x=c.id.split("@")[0];return gt(st,{children:[ie(ue,{color:f?"cyan":void 0,bold:f,children:f?"> ":" "}),ie(ue,{color:f?"cyan":void 0,bold:f,children:mt(x,24)}),ie(ue,{color:f?"cyan":void 0,bold:f,children:mt(c.scope,8)}),ie(ue,{color:c.globalEnabled?"green":"gray",children:mt(c.globalEnabled?"on":"off",6)}),ie(ue,{dimColor:!0,children:c.installPath})]},c.id)})]}),ie(st,{marginTop:1,children:ie(ue,{dimColor:!0,children:"r:refresh"})})]})}function mt(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}import{Box as Ft,Text as Jo,useInput as Rn}from"ink";import{useState as Mn}from"react";import{jsx as ft,jsxs as io}from"react/jsx-runtime";var Nn=[{key:"1",id:"tasks",label:"Tasks"},{key:"2",id:"automations",label:"Automations"},{key:"3",id:"goals",label:"Goals"}];function Zo({onBack:e}){let[t,o]=Mn("tasks");return Rn((d,u)=>{if(u.escape||d==="q"){e();return}if(d==="1"){o("tasks");return}if(d==="2"){o("automations");return}if(d==="3"){o("goals");return}}),io(Ft,{flexDirection:"column",children:[io(Ft,{gap:1,marginBottom:1,children:[Nn.map(d=>{let u=t===d.id;return ft(Ft,{children:io(Jo,{color:u?"cyan":"gray",bold:u,underline:u,children:["[",d.key,":",d.label,"]"]})},d.id)}),ft(Ft,{flexGrow:1}),ft(Jo,{dimColor:!0,children:"Esc: back"})]}),t==="tasks"&&ft(_t,{onBack:e}),t==="automations"&&ft(Ut,{onBack:e}),t==="goals"&&ft(Ot,{onBack:e})]})}import{Box as G,Text as O,useInput as Ln}from"ink";import{useEffect as _n,useState as wt}from"react";import{jsx as A,jsxs as re}from"react/jsx-runtime";var er={connected:"green",connecting:"yellow",disconnected:"gray",error:"red"};function tr({onBack:e}){let[t,o]=wt([]),[d,u]=wt(!0),[m,l]=wt(0),[i,s]=wt(null),[r,a]=wt("");_n(()=>{c()},[]);async function c(){try{let x=await T("/channels");o(x.channels)}catch{}u(!1)}async function h(x){if(t.find(g=>g.id===x)?.platform==="wechat")try{a("Starting WeChat QR login...");let g=await T(`/channels/${x}/wechat/qr-start`,{method:"POST"});if(g.qrcodeUrl){a(`Scan QR: ${g.qrcodeUrl}
6
+ Waiting for scan...`);let R=await T(`/channels/${x}/wechat/qr-wait`,{method:"POST",body:{sessionKey:g.sessionKey,timeoutMs:12e4}});a(R.message)}else a(g.message);c()}catch{a("WeChat connect failed")}else try{await T(`/channels/${x}/connect`,{method:"POST"}),a("Connecting..."),c()}catch{a("Connect failed")}}async function f(x){try{await T(`/channels/${x}/disconnect`,{method:"POST"}),a("Disconnected"),c()}catch{a("Disconnect failed")}}return Ln((x,n)=>{if(i){if(n.escape||x==="q"){s(null);return}if(x==="c"){h(i.id);return}if(x==="d"){f(i.id);return}return}if(n.escape){e();return}if(n.upArrow){l(g=>Math.max(0,g-1));return}if(n.downArrow){l(g=>Math.min(t.length-1,g+1));return}if(n.return&&t[m]){s(t[m]),a("");return}}),d?A(G,{flexDirection:"column",children:A(O,{dimColor:!0,children:"Loading channels..."})}):i?re(G,{flexDirection:"column",children:[re(G,{marginBottom:1,children:[re(O,{bold:!0,children:["Channel: ",i.name]}),A(O,{dimColor:!0,children:" (Esc to go back)"})]}),re(G,{flexDirection:"column",gap:0,children:[re(O,{children:["ID: ",i.id]}),re(O,{children:["Platform: ",i.platform]}),re(O,{children:["Status: ",A(O,{color:er[i.status]??"white",children:i.status})]}),re(O,{children:["Enabled: ",i.enabled?"yes":"no"]}),re(O,{children:["Messages: ",i.messageCount]}),re(O,{children:["Config: ",JSON.stringify(i.config)]})]}),A(G,{marginTop:1,children:A(O,{dimColor:!0,children:"[c] Connect [d] Disconnect [Esc] Back"})}),r&&A(O,{color:"yellow",children:r})]}):re(G,{flexDirection:"column",children:[re(G,{marginBottom:1,children:[A(O,{bold:!0,children:"Channels"}),re(O,{dimColor:!0,children:[" (",t.length," total) "]}),A(O,{dimColor:!0,children:"Arrow keys to select, Enter for detail, Esc to return"})]}),t.length===0?A(O,{dimColor:!0,children:"No channels configured. Add channels via API or config."}):re(G,{flexDirection:"column",children:[re(G,{children:[A(G,{width:3,children:A(O,{dimColor:!0,children:" "})}),A(G,{width:12,children:A(O,{bold:!0,dimColor:!0,children:"ID"})}),A(G,{width:16,children:A(O,{bold:!0,dimColor:!0,children:"Name"})}),A(G,{width:12,children:A(O,{bold:!0,dimColor:!0,children:"Platform"})}),A(G,{width:14,children:A(O,{bold:!0,dimColor:!0,children:"Status"})}),A(G,{width:10,children:A(O,{bold:!0,dimColor:!0,children:"Enabled"})}),A(G,{width:10,children:A(O,{bold:!0,dimColor:!0,children:"Messages"})})]}),t.map((x,n)=>re(G,{children:[A(G,{width:3,children:A(O,{children:n===m?">":" "})}),A(G,{width:12,children:A(O,{inverse:n===m,children:x.id.slice(0,8)})}),A(G,{width:16,children:A(O,{children:x.name})}),A(G,{width:12,children:A(O,{children:x.platform})}),A(G,{width:14,children:re(O,{color:er[x.status]??"white",children:[x.status==="connected"?"\u25CF":x.status==="error"?"\u2717":"\u25CB"," ",x.status]})}),A(G,{width:10,children:A(O,{color:x.enabled?"green":"gray",children:x.enabled?"yes":"no"})}),A(G,{width:10,children:A(O,{children:x.messageCount})})]},x.id))]})]})}import{Box as pt,Text as Ke,useInput as On}from"ink";import{useEffect as Vn,useState as It,useCallback as qn}from"react";import{Box as V,Text as E,useInput as $n}from"ink";import Wt from"ink-text-input";import{useEffect as or,useState as ae,useCallback as Bt}from"react";uo();import{Fragment as rr,jsx as v,jsxs as M}from"react/jsx-runtime";function nr({roleId:e,onBack:t}){let[o,d]=ae(null),[u,m]=ae([]),[l,i]=ae(!0),[s,r]=ae("view"),[a,c]=ae(""),[h,f]=ae(0),[x,n]=ae(""),[g,R]=ae([]),[k,H]=ae(0),[W,I]=ae(new Set),[te,B]=ae("inline"),[S,p]=ae(""),[P,N]=ae(""),[_e,b]=ae([]),[w,_]=ae(new Set),[ne,je]=ae(0),{message:F,setMessage:z}=Ze(),me=Bt(()=>{i(!0),T(`/roles/${e}`).then(({role:y,boundPlugins:L})=>{d(y),m(L??[]),c(y.cagPrompt??""),I(new Set(y.allowedTools??[])),B(y.executionMode??"inline"),p(y.model??""),N(y.maxBudgetUsd!=null?String(y.maxBudgetUsd):""),i(!1)}).catch(()=>i(!1))},[e]);or(()=>{me()},[me]),or(()=>{B(o?.executionMode??"inline"),p(o?.model??""),N(o?.maxBudgetUsd!=null?String(o?.maxBudgetUsd):"")},[o?.id,o?.executionMode,o?.model,o?.maxBudgetUsd]);let ir=Bt(async()=>{if(o)try{await T(`/roles/${o.id}`,{method:"PATCH",body:{cagPrompt:a}}),z("CAG prompt saved","success"),r("view"),me()}catch(y){z(`Save failed: ${y instanceof Error?y.message:String(y)}`,"error")}},[o,a,me,z]),ar=Bt(async()=>{if(o)try{await T(`/roles/${o.id}`,{method:"PATCH",body:{additionalDirectories:$e}}),z("Directories saved","success"),r("view"),me()}catch(y){z(`Save failed: ${y instanceof Error?y.message:String(y)}`,"error")}},[o,me,z]),lr=Bt(async()=>{if(o)try{await T(`/roles/${o.id}`,{method:"PATCH",body:{allowedTools:Array.from(W)}}),z("Tool permissions saved","success"),r("view"),me()}catch(y){z(`Save failed: ${y instanceof Error?y.message:String(y)}`,"error")}},[o,W,me,z]),cr=Bt(async()=>{if(!o)return;let y={executionMode:te};S!==void 0&&(y.model=S);let L=parseFloat(P);isNaN(L)||(y.maxBudgetUsd=L);try{await T(`/roles/${o.id}`,{method:"PATCH",body:y}),z("Execution config saved","success"),r("view"),me()}catch(C){z(`Save failed: ${C instanceof Error?C.message:String(C)}`,"error")}},[o,te,S,P,me,z]),$e=o?.additionalDirectories??[];return $n((y,L)=>{if(L.escape){r("view");return}if(y==="r"){me();return}switch(s){case"view":{if(y==="c"){r("edit-cag");return}if(y==="d"){r("edit-dirs"),f(0),n("");return}if(y==="t"){r("edit-tools");return}if(y==="x"){r("edit-exec");return}if(y==="h"){T("/channels?enabled=true").then(({channels:C})=>{b(C.map(Y=>({name:Y.name,id:Y.id}))),_(new Set(o?.allowedChannels??[])),je(0),r("edit-channels")}).catch(()=>z("Failed to load channels","error"));return}if(y==="i"){if(!o)return;let C=!o.inheritUserSettings;T(`/roles/${o.id}`,{method:"PATCH",body:{inheritUserSettings:C}}).then(()=>{z(`Inherit user settings: ${C?"ON":"OFF"}`,"success"),me()}).catch(()=>z("Failed to toggle","error"));return}break}case"edit-cag":{if(L.ctrl&&y==="s"){ir();return}break}case"edit-dirs":{if(y==="s"){ar();return}if(y==="a"){r("edit-dirs-add");return}if(y==="x"&&$e.length>0){d(C=>C&&{...C,additionalDirectories:$e.filter((Y,Qe)=>Qe!==h)}),f(C=>Math.max(0,Math.min(C,$e.length-2)));return}if(L.upArrow){f(C=>Math.max(0,C-1));return}if(L.downArrow){f(C=>Math.min($e.length-1,C+1));return}break}case"edit-dirs-add":{if(L.escape){r("edit-dirs"),n(""),R([]);return}if(L.return&&g.length>0){let C=g[k];C&&(n(C.endsWith("/")?C:C+"/"),R([]));return}if(L.return){let C=x.trim();C&&C.startsWith("/")?(d(Y=>Y&&{...Y,additionalDirectories:[...Y.additionalDirectories??[],{path:C}]}),n(""),R([]),r("edit-dirs")):z("Path must be absolute (must start with /)","error");return}if(L.tab){let C=x.trim();if(!C||!C.startsWith("/"))return;T(`/fs/suggest-dirs?prefix=${encodeURIComponent(C)}`).then(({suggestions:Y})=>{Y.length===1?(n(Y[0]+"/"),R([])):Y.length>1&&(R(Y),H(0))}).catch(()=>{R([])});return}if(L.upArrow&&g.length>0){H(C=>Math.max(0,C-1));return}if(L.downArrow&&g.length>0){H(C=>Math.min(g.length-1,C+1));return}break}case"edit-tools":{if(y==="s"){lr();return}let C=parseInt(y,10)-1;if(!isNaN(C)&&C>=0&&C<At.length){let Y=At[C];I(Qe=>{let Pt=new Set(Qe);return Pt.has(Y)?Pt.delete(Y):Pt.add(Y),Pt});return}break}case"edit-exec":{if(y==="s"){cr();return}if(L.tab){B(C=>C==="inline"?"isolated":"inline");return}break}case"edit-channels":{if(y==="s"){if(!o)return;let C=w.size>0?Array.from(w):[];T(`/roles/${o.id}`,{method:"PATCH",body:{allowedChannels:C}}).then(()=>{z("Channels saved","success"),r("view"),me()}).catch(()=>z("Save failed","error"));return}if(y==="u"){if(!o)return;T(`/roles/${o.id}`,{method:"PATCH",body:{allowedChannels:null}}).then(()=>{z("Channels: unrestricted","success"),r("view"),me()}).catch(()=>z("Save failed","error"));return}if(y===" "){let C=_e[ne];C&&_(Y=>{let Qe=new Set(Y);return Qe.has(C.name)?Qe.delete(C.name):Qe.add(C.name),Qe});return}if(L.upArrow){je(C=>Math.max(0,C-1));return}if(L.downArrow){je(C=>Math.min(_e.length-1,C+1));return}break}}}),l?v(E,{dimColor:!0,children:"Loading role..."}):o?s==="edit-cag"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"CAG Prompt \u2014 Edit (Esc cancel, Ctrl+S save)"}),v(Wt,{value:a,onChange:c,placeholder:"Character And Guidance prompt..."}),F&&v(V,{marginTop:1,children:v(E,{color:F.type==="error"?"red":"green",children:F.text})})]}):s==="edit-dirs-add"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"Add Directory (Enter confirm, Esc cancel, Tab:complete)"}),v(Wt,{value:x,onChange:y=>{n(y),R([])},placeholder:"/absolute/path/to/directory"}),g.length>0&&M(V,{flexDirection:"column",marginTop:1,children:[g.map((y,L)=>M(E,{color:L===k?"cyan":void 0,dimColor:L!==k,children:[L===k?"> ":" ",y,"/"]},y)),v(E,{dimColor:!0,children:"\u2191\u2193 navigate, Enter select, Tab:confirm"})]}),F&&v(V,{marginTop:1,children:v(E,{color:F.type==="error"?"red":"green",children:F.text})})]}):s==="edit-dirs"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"Additional Directories (\u2191\u2193 navigate, a:add x:remove s:save Esc:cancel)"}),F&&v(V,{children:v(E,{color:F.type==="error"?"red":F.type==="success"?"green":"gray",children:F.text})}),$e.length===0?v(E,{dimColor:!0,children:"No directories. Press a to add one."}):$e.map((y,L)=>M(V,{children:[v(E,{color:L===h?"cyan":void 0,bold:L===h,children:L===h?"> ":" "}),v(E,{color:L===h?"cyan":void 0,children:y.path})]},y.path))]}):s==="edit-tools"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"Tool Permissions \u2014 toggle with number key (s:save Esc:cancel)"}),F&&v(V,{children:v(E,{color:F.type==="error"?"red":F.type==="success"?"green":"gray",children:F.text})}),At.map((y,L)=>{let C=W.has(y);return M(V,{children:[M(E,{dimColor:!0,children:[L+1,". "]}),v(E,{color:C?"green":"red",children:C?"[ON] ":"[OFF] "}),v(E,{children:y})]},y)})]}):s==="edit-exec"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"Execution Config (Tab:cycle mode, Enter on field, s:save Esc:cancel)"}),M(V,{children:[v(E,{bold:!0,children:" Mode: "}),v(E,{color:"cyan",children:te}),v(E,{dimColor:!0,children:" (Tab to toggle)"})]}),M(V,{children:[v(E,{bold:!0,children:" Model: "}),v(Wt,{value:S,onChange:p,placeholder:"sonnet, opus, haiku, or blank"})]}),M(V,{children:[v(E,{bold:!0,children:" Max Budget (USD): "}),v(Wt,{value:P,onChange:N,placeholder:"0 = unlimited"})]}),F&&v(V,{children:v(E,{color:F.type==="error"?"red":F.type==="success"?"green":"gray",children:F.text})})]}):s==="edit-channels"?M(V,{flexDirection:"column",children:[v(E,{bold:!0,children:"Allowed Channels (Space:toggle, u:unrestricted, s:save, Esc:cancel)"}),_e.length===0?v(E,{dimColor:!0,children:"No channels available"}):_e.map((y,L)=>M(V,{children:[M(E,{children:[L===ne?">":" "," "]}),M(E,{color:w.has(y.name)?"green":"gray",children:["[",w.has(y.name)?"x":" ","] ",y.name]})]},y.id)),M(E,{dimColor:!0,children:["Selected: ",w.size>0?Array.from(w).join(", "):"none (= block all)"]}),F&&v(V,{children:v(E,{color:F.type==="error"?"red":F.type==="success"?"green":"gray",children:F.text})})]}):M(V,{flexDirection:"column",children:[M(E,{bold:!0,children:["Role: ",o.name]}),M(V,{children:[v(E,{dimColor:!0,children:"ID: "}),v(E,{children:o.id})]}),M(V,{children:[v(E,{dimColor:!0,children:"Status: "}),v(E,{color:o.status==="active"?"green":o.status==="probation"?"yellow":"red",children:o.status})]}),o.performanceScore!=null&&M(V,{children:[v(E,{dimColor:!0,children:"Score: "}),M(E,{children:[(o.performanceScore*100).toFixed(0),"%"]})]}),M(V,{children:[v(E,{dimColor:!0,children:"Created: "}),v(E,{children:new Date(o.createdAt).toLocaleString()})]}),M(V,{children:[v(E,{dimColor:!0,children:"Execution: "}),M(E,{children:[o.executionMode??"inline"," / ",o.model??"inherit"," / ",o.maxBudgetUsd!=null?`$${o.maxBudgetUsd}`:"no limit"]})]}),$e.length>0&&M(rr,{children:[v(E,{bold:!0,children:"Additional Directories:"}),$e.map(y=>M(E,{dimColor:!0,children:[" ",y.path]},y.path))]}),M(V,{children:[v(E,{dimColor:!0,children:"Channels: "}),v(E,{children:o.allowedChannels===void 0?"Unrestricted":o.allowedChannels.length===0?"Blocked":o.allowedChannels.join(", ")})]}),M(V,{children:[v(E,{dimColor:!0,children:"Inherit User Settings: "}),v(E,{color:o.inheritUserSettings?"green":"gray",children:o.inheritUserSettings?"Yes":"No"})]}),o.learnedRules.length>0&&M(rr,{children:[v(E,{bold:!0,children:"Learned Rules:"}),o.learnedRules.map(y=>M(E,{dimColor:!0,children:[" - ",y]},y))]}),F&&v(V,{children:v(E,{color:F.type==="error"?"red":F.type==="success"?"green":"gray",children:F.text})}),v(V,{marginTop:1,children:v(E,{dimColor:!0,children:"c:CAG d:dirs t:tools x:exec h:channels i:inherit r:refresh Esc:back"})})]}):v(E,{dimColor:!0,children:"Role not found."})}import{jsx as Se,jsxs as Gt}from"react/jsx-runtime";function sr({onBack:e}){let[t,o]=It([]),[d,u]=It(!0),[m,l]=It(0),[i,s]=It("list"),[r,a]=It(null),{message:c,setMessage:h,clearMessage:f}=Ze(),x=qn(()=>{u(!0),T("/roles").then(({roles:n})=>{o(n.map(g=>({id:g.id,name:g.name,status:g.status,performanceScore:g.performanceScore,createdAt:g.createdAt}))),u(!1)}).catch(()=>u(!1))},[]);return Vn(()=>{x()},[x]),On((n,g)=>{if(g.escape||n==="q"){e();return}if(g.upArrow){l(R=>Math.max(0,R-1));return}if(g.downArrow){l(R=>Math.min(t.length-1,R+1));return}if(n==="r"&&(x(),f()),n===`
7
+ `||n==="o"||n==="e"){t.length>0&&(a(t[m].id),s("detail"));return}}),d?Se(Ke,{dimColor:!0,children:"Loading roles..."}):i==="detail"&&r?Se(nr,{roleId:r,onBack:()=>s("list")}):Gt(pt,{flexDirection:"column",children:[Gt(Ke,{bold:!0,children:["Roles (",t.length,") (Esc to go back)"]}),c&&Se(pt,{marginTop:1,children:Gt(Ke,{color:c.type==="success"?"green":c.type==="error"?"red":"gray",children:[c.type==="success"?"\u2713 ":c.type==="error"?"\u2717 ":"\u2192 ",c.text]})}),t.length===0?Se(pt,{marginTop:1,children:Se(Ke,{dimColor:!0,children:"No roles found. Roles define agent behavior and bind plugins."})}):Se(pt,{marginTop:1,flexDirection:"column",children:t.map((n,g)=>{let R=g===m,k=n.performanceScore!=null?`${(n.performanceScore*100).toFixed(0)}%`:"\u2014";return Gt(pt,{children:[Se(Ke,{color:R?"cyan":void 0,bold:R,children:R?"> ":" "}),Se(Ke,{color:R?"cyan":void 0,bold:R,children:ao(n.name,24)}),Se(Ke,{color:Un(n.status),children:ao(n.status,12)}),Se(Ke,{dimColor:!0,children:ao(k,8)})]},n.id)})}),Se(pt,{marginTop:1,children:Se(Ke,{dimColor:!0,children:"Enter/O/E:open Esc:back r:refresh"})})]})}function Un(e){return e==="active"?"green":e==="probation"?"yellow":e==="retired"||e==="dead"?"red":"gray"}function ao(e,t){return e?e.length>=t?e:e+" ".repeat(t-e.length):" ".repeat(t)}import{Fragment as jn,jsx as q,jsxs as Tt}from"react/jsx-runtime";function Gn(){let{state:e,dispatch:t}=Xe(),{session:o,sendMessage:d,createNewSession:u,archiveCurrentSession:m}=bo(),[l,i]=Wn([]);Ht(()=>{t({type:"SET_SESSION",session:o})},[o,t]),To();let{latestMessage:s}=Co(o?.id??null),r=lo(null);Ht(()=>{s&&s.id!==r.current&&(r.current=s.id,i(k=>[...k,{role:"assistant",content:s.content}]))},[s]);let{events:a,isStreaming:c,clearEvents:h}=yo(e.activeTaskId),f=a[a.length-1],x=f?.type==="complete"&&!c,n=lo(null),g=lo("");Ht(()=>{g.current=a.filter(k=>k.type==="reasoning").map(k=>k.content).join("")},[a]),Ht(()=>{if(x&&e.activeTaskId!==n.current){n.current=e.activeTaskId;let k=f?.content||g.current;k&&i(H=>[...H,{role:"assistant",content:k}])}},[x,f,e.activeTaskId]);let R=async k=>{let H=k.trim().toLowerCase();if(["quit","exit","/quit","/exit"].includes(H)&&process.exit(0),k.startsWith("/")){let I=k.slice(1),B={work:"work",tasks:"tasks",config:"config",evolution:"evolution",templates:"templates",memories:"memories",goals:"goals",strategies:"strategies",roles:"roles",settings:"settings",channels:"channels",plugins:"plugins",back:"chat"}[I];if(B){t({type:"SET_VIEW",view:B});return}if(I==="new"){if(await m()){let p=await u();i([]),h(),p&&i([{role:"assistant",content:`Session archived. New session started: ${p.id.slice(0,8)}`}])}return}if(I==="session"){let S=o?`Session: ${o.id}
8
+ Turns: ${o.messageCount}
9
+ Last active: ${new Date(o.lastActiveAt).toLocaleString()}`:"No active session";i(p=>[...p,{role:"assistant",content:S}]);return}}if(i(I=>[...I,{role:"user",content:k}]),h(),!await d(k)){i(I=>[...I,{role:"assistant",content:"Failed to send message. Server may be disconnected."}]);return}};return Tt(kt,{flexDirection:"column",paddingX:1,children:[q(vo,{}),Tt(kt,{flexGrow:1,flexDirection:"column",paddingY:1,children:[e.view==="chat"&&Tt(jn,{children:[q(Po,{messages:l}),q(Bo,{events:a,isStreaming:c}),!e.connected&&!e.serverUnreachable&&q(kt,{children:q(xt,{color:"red",children:"Server disconnected. Attempting to reconnect..."})}),e.serverUnreachable&&Tt(kt,{flexDirection:"column",children:[q(xt,{color:"red",bold:!0,children:"Server unreachable after 15s."}),q(xt,{dimColor:!0,children:"Check: adam server logs"}),q(xt,{dimColor:!0,children:"Type /quit to exit."})]})]}),e.view==="work"&&q(Zo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="tasks"&&q(_t,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="config"&&q(_o,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="evolution"&&q(Oo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="goals"&&q(Ot,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="strategies"&&q(qo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="templates"&&q(Ut,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="webhooks"&&q(Wo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="memories"&&q(Ko,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="plugins"&&q(Yo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="roles"&&q(sr,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="settings"&&q(zo,{onBack:()=>t({type:"SET_VIEW",view:"chat"})}),e.view==="channels"&&q(tr,{onBack:()=>t({type:"SET_VIEW",view:"chat"})})]}),e.pendingPlanApproval?q(Do,{approval:e.pendingPlanApproval,onResolved:()=>t({type:"SET_PENDING_PLAN_APPROVAL",approval:null}),onTimeout:()=>t({type:"SET_PLAN_TIMEOUT_NOTICE",planId:e.pendingPlanApproval.planId})}):e.pendingApproval?q(Ao,{approval:e.pendingApproval,onResolved:()=>t({type:"SET_PENDING_APPROVAL",approval:null})}):q(wo,{onSubmit:R}),e.planTimeoutNotice&&q(Hn,{planId:e.planTimeoutNotice.planId,onDismiss:()=>t({type:"SET_PLAN_TIMEOUT_NOTICE",planId:null})})]})}function Hn({planId:e,onDismiss:t}){return Fn(o=>{o==="d"&&t()}),Tt(kt,{borderStyle:"round",borderColor:"yellow",paddingX:1,children:[Tt(xt,{color:"yellow",children:["Plan ",e," was auto-denied after 300s timeout."]}),q(xt,{dimColor:!0,children:" [d] Dismiss"})]})}function Kn(){return q(fo,{children:q(Gn,{})})}export{Kn as default};
@@ -1 +1 @@
1
- import{x as a,y as b}from"./chunk-2VKE7ONM.js";import"./chunk-5JLMSNIW.js";import"./chunk-IXF3XBGX.js";import"./chunk-AXMXXUPO.js";import"./chunk-KICPHTI2.js";import"./chunk-FUGJMHY4.js";import"./chunk-5ASEAZCR.js";import"./chunk-742NWPTQ.js";import"./chunk-PQ7KPALO.js";import"./chunk-2GXYBWLS.js";import"./chunk-WZOMGJSY.js";import"./chunk-WXN3PSVX.js";import"./chunk-L7426WNY.js";import"./chunk-L7JP7DUO.js";import"./chunk-HAWA62R2.js";import"./chunk-VF6GJGD6.js";import"./chunk-T25NLVMY.js";import"./chunk-ETQ7KC73.js";import"./chunk-FYDFMYUP.js";import"./chunk-U36NBCR3.js";import"./chunk-XNWZZYAV.js";import"./chunk-PCSZW2PE.js";import"./chunk-SFUS33SO.js";import"./chunk-3DAK2XWP.js";import"./chunk-FCV2DPZQ.js";export{b as createAdamTools,a as getToolsFingerprint};
1
+ import{x as a,y as b}from"./chunk-BQE7XAMQ.js";import"./chunk-5JLMSNIW.js";import"./chunk-IXF3XBGX.js";import"./chunk-AXMXXUPO.js";import"./chunk-KICPHTI2.js";import"./chunk-FUGJMHY4.js";import"./chunk-5ASEAZCR.js";import"./chunk-742NWPTQ.js";import"./chunk-PQ7KPALO.js";import"./chunk-2GXYBWLS.js";import"./chunk-WZOMGJSY.js";import"./chunk-WXN3PSVX.js";import"./chunk-L7426WNY.js";import"./chunk-L7JP7DUO.js";import"./chunk-HAWA62R2.js";import"./chunk-VF6GJGD6.js";import"./chunk-T25NLVMY.js";import"./chunk-ETQ7KC73.js";import"./chunk-FYDFMYUP.js";import"./chunk-U36NBCR3.js";import"./chunk-XNWZZYAV.js";import"./chunk-PCSZW2PE.js";import"./chunk-SFUS33SO.js";import"./chunk-3DAK2XWP.js";import"./chunk-FCV2DPZQ.js";export{b as createAdamTools,a as getToolsFingerprint};
@@ -1,4 +1,4 @@
1
- import{b as y}from"./chunk-UOTDT2KY.js";import{b as m}from"./chunk-PQ7KPALO.js";import"./chunk-FDWW245P.js";import"./chunk-L7JP7DUO.js";import"./chunk-PCSZW2PE.js";import"./chunk-SFUS33SO.js";import{c as f}from"./chunk-3DAK2XWP.js";import"./chunk-FCV2DPZQ.js";var s=f("channels"),c=new Map,h=3e5,v=new Set(["telegram"]);function A(n){let a=n.trim().toLowerCase().match(/^(yes|y|是|允许|no|n|否|拒绝)\s+(\S+)$/);if(!a)return null;let[,p,d]=a,i=["yes","y","\u662F","\u5141\u8BB8"].includes(p);return{requestId:d,decision:i?"allow":"deny"}}function I(n){let r=m(n);return r?v.has(r.platform):!1}async function b(n,r,a,p,d,i=h){let e=a;c.set(e,{planId:a,taskId:p,channelId:n,chatId:r,requestId:e,timestamp:Date.now(),timeoutMs:i});let l=y(),o=I(n);if(o){let t=`\u{1F510} Plan approval requested
1
+ import{b as y}from"./chunk-LBLERTM4.js";import{b as m}from"./chunk-PQ7KPALO.js";import"./chunk-FDWW245P.js";import"./chunk-L7JP7DUO.js";import"./chunk-PCSZW2PE.js";import"./chunk-SFUS33SO.js";import{c as f}from"./chunk-3DAK2XWP.js";import"./chunk-FCV2DPZQ.js";var s=f("channels"),c=new Map,h=3e5,v=new Set(["telegram"]);function A(n){let a=n.trim().toLowerCase().match(/^(yes|y|是|允许|no|n|否|拒绝)\s+(\S+)$/);if(!a)return null;let[,p,d]=a,i=["yes","y","\u662F","\u5141\u8BB8"].includes(p);return{requestId:d,decision:i?"allow":"deny"}}function I(n){let r=m(n);return r?v.has(r.platform):!1}async function b(n,r,a,p,d,i=h){let e=a;c.set(e,{planId:a,taskId:p,channelId:n,chatId:r,requestId:e,timestamp:Date.now(),timeoutMs:i});let l=y(),o=I(n);if(o){let t=`\u{1F510} Plan approval requested
2
2
 
3
3
  ${d.slice(0,200)}`;await l.send({channelId:n,chatId:r,content:t,messageType:"approval",replyMarkup:{inlineKeyboard:[[{text:"\u2705 Allow",callbackData:`yes ${e}`},{text:"\u274C Deny",callbackData:`no ${e}`}]]}})}else{let t=["\u{1F510} Plan approval requested",d.slice(0,200),"",`Reply 'yes ${e}' or 'no ${e}'`].join(`
4
4
  `);await l.send({channelId:n,chatId:r,content:t,messageType:"approval"})}setTimeout(()=>{let t=c.get(e);if(t&&Date.now()-t.timestamp>=t.timeoutMs){c.delete(e),s.warn({requestId:e,taskId:p},"Approval timed out, auto-denying"),l.send({channelId:t.channelId,chatId:t.chatId,content:`\u23F0 Approval ${e} timed out (5 min). Plan denied.`,messageType:"approval"}).catch(u=>s.error({requestId:e,error:u},"Failed to notify timeout"));let g=process.env.ADAM_PORT??"7100";fetch(`http://localhost:${g}/tasks/${t.taskId}/approve-plan`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({planId:t.planId,decision:"deny"})}).catch(u=>s.error({requestId:e,error:u},"Failed to auto-deny"))}},i+1e3),s.info({channelId:n,chatId:r,planId:a,requestId:e,interactive:o},"Interactive approval sent to channel")}async function C(n,r,a,p){let i=A(p??a);if(!i)return!1;let{requestId:e,decision:l}=i,o=c.get(e);if(!o)return!1;if(o.channelId!==n||o.chatId!==r)return s.debug({requestId:e,expectedChannel:o.channelId,gotChannel:n},"Approval reply from different channel"),!1;c.delete(e),s.info({requestId:e,decision:l},"Channel approval reply received");try{let t=process.env.ADAM_PORT??"7100",g=await fetch(`http://localhost:${t}/tasks/${o.taskId}/approve-plan`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({planId:o.planId,decision:l}),signal:AbortSignal.timeout(1e4)});g.ok||s.error({requestId:e,status:g.status},"Failed to forward approval to API")}catch(t){s.error({requestId:e,error:t},"Error forwarding approval to API")}return!0}function $(){return[...c.keys()]}export{$ as getPendingApprovalRequestIds,C as handleInboundForApproval,A as parseApprovalReply,b as sendApprovalToChannel};