@turmind/halo 0.1.9 → 0.2.1-bc7cf2b
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 +1 -5
- package/admin-out/404.html +1 -1
- package/admin-out/_next/static/chunks/212-170855bed19f67f3.js +1 -0
- package/admin-out/_next/static/chunks/{503-7c6d9935df6e0cea.js → 307-d7a99f9a4a436ec3.js} +1 -1
- package/admin-out/_next/static/chunks/525.2c10a4fd329d0d24.js +1 -0
- package/admin-out/_next/static/chunks/app/layout-c2fa8035998e48d5.js +1 -0
- package/admin-out/_next/static/chunks/app/page-31317ef1fb0ba31f.js +1 -0
- package/admin-out/_next/static/chunks/{webpack-8bd7ef88a6527feb.js → webpack-47520cdc55be63e7.js} +1 -1
- package/admin-out/_next/static/css/66df341f99220f5c.css +3 -0
- package/admin-out/index.html +1 -1
- package/admin-out/index.txt +21 -20
- package/bundled-docs/design/agent.md +1 -1
- package/bundled-docs/design/evolution.md +11 -2
- package/bundled-docs/design/halo-city.md +31 -0
- package/bundled-docs/design/prompt-system.md +3 -3
- package/bundled-docs/design/session.md +26 -1
- package/bundled-docs/design/storage.md +13 -0
- package/bundled-docs/dev/acp-adapter.md +31 -4
- package/bundled-docs/dev/api.md +6 -4
- package/bundled-docs/dev/desktop-packaging.md +98 -8
- package/bundled-docs/dev/env.md +4 -2
- package/bundled-docs/dev/previews.md +3 -0
- package/bundled-docs/dev/tools.md +3 -1
- package/bundled-docs/guide/cli.md +40 -16
- package/bundled-docs/guide/getting-started.md +3 -2
- package/bundled-docs/requirements/editor.md +1 -1
- package/bundled-docs/requirements/explorer.md +11 -0
- package/dist/index.js +14102 -13249
- package/package.json +1 -2
- package/templates/INSTRUCTIONS.md +0 -4
- package/templates/agents/__apply_agent__/AGENT.md +41 -19
- package/templates/agents/__evo_agent__/AGENT.md +73 -45
- package/templates/agents/__evo_agent__/agent.yaml +9 -6
- package/templates/agents/__score__/AGENT.md +65 -33
- package/templates/agents/deep-executor/AGENT.md +23 -6
- package/templates/agents/deep-executor/agent.yaml +4 -1
- package/templates/agents/default/AGENT.md +32 -8
- package/templates/agents/executor/AGENT.md +19 -1
- package/templates/agents/executor/agent.yaml +6 -3
- package/templates/models/aws-bedrock-claude-invoke.yaml +53 -0
- package/templates/prompts/all/WORKSPACE_CONVENTIONS.md +5 -0
- package/templates/prompts/bootstrap/BOOTSTRAP.md +4 -0
- package/templates/prompts/root/WORKSPACE_MEMORY.md +2 -0
- package/templates/skills/acp/SKILL.md +8 -1
- package/templates/skills/acp/templates/SKILL.md.tmpl +2 -1
- package/templates/skills/acp/templates/ask.py +2 -1
- package/templates/skills/acp/templates/config.yaml.tmpl +5 -0
- package/admin-out/_next/static/chunks/298-d6b224b569da4de0.js +0 -1
- package/admin-out/_next/static/chunks/661.a4fe93f3f2a5e871.js +0 -1
- package/admin-out/_next/static/chunks/app/layout-58f773336e6fce61.js +0 -1
- package/admin-out/_next/static/chunks/app/page-cc8043335282d745.js +0 -1
- package/admin-out/_next/static/css/8fce4e1a54dac12a.css +0 -3
- package/bundled-docs/plans/cron-tasks.md +0 -362
- package/bundled-docs/plans/design-suggestions.md +0 -203
- package/bundled-docs/plans/issue-session-deep-nesting.md +0 -208
- package/bundled-docs/plans/launch-plan.md +0 -111
- package/bundled-docs/plans/md-and-agent-refactor.md +0 -197
- package/bundled-docs/plans/remote-mac-worker.md +0 -196
- package/bundled-docs/plans/roadmap.md +0 -40
- package/bundled-docs/plans/self-evolution.md +0 -1379
- package/bundled-docs/plans/todo.md +0 -32
- package/bundled-docs/plans/weixin-channel.md +0 -255
- package/bundled-docs/test/docs-seeding.md +0 -101
- package/bundled-docs/test/session.md +0 -374
- /package/admin-out/_next/static/{IBP_mwBDf-cPwZSZZGpi8 → iSrc6429pyTB0lK-EE5oH}/_buildManifest.js +0 -0
- /package/admin-out/_next/static/{IBP_mwBDf-cPwZSZZGpi8 → iSrc6429pyTB0lK-EE5oH}/_ssgManifest.js +0 -0
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
# Refactor plan: drop is_default + working_dir + MD-load simplification + externalise system prompts
|
|
2
|
-
|
|
3
|
-
**Status**: shipped (2026-04 / 2026-05). All phases A–F landed: `priority` field replaced `is_default`, `agent_sessions.working_dir` column added, MD-loader simplified (INDEX.md root-only, INSTRUCTIONS.md stacks per directory level), system prompts externalised under `prompts/{bootstrap,all,root}/`. This doc is kept as a design log — see the reference state in [design/prompt-system.md](../design/prompt-system.md).
|
|
4
|
-
**Filed**: 2026-04-27
|
|
5
|
-
|
|
6
|
-
This doc preserves every design decision, rationale, and trade-off so we can rapidly recover context if it's lost.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Background
|
|
11
|
-
|
|
12
|
-
Halo uses `is_default` as a synonym for "root agent", which has bad knock-on effects:
|
|
13
|
-
- Prompt injection logic, tool behaviour, and UI default selection all bind to this field
|
|
14
|
-
- User-defined "direct-chat agents" can't receive USER.md, PLATFORM_KNOWLEDGE, or other root-only prompts
|
|
15
|
-
- Hard-coded system prompts (BOOTSTRAP / TOOL_GUIDELINES / PLATFORM_KNOWLEDGE / ORCHESTRATOR_GUIDELINES) live in source — users wanting to customise must edit source
|
|
16
|
-
- INDEX.md reserves a subdirectory-loading interface but never calls it (dead code)
|
|
17
|
-
- INSTRUCTIONS.md only supports two layers (global + project); no subdirectory granularity
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Core decisions
|
|
22
|
-
|
|
23
|
-
### 1. Drop `is_default`
|
|
24
|
-
|
|
25
|
-
- The `is_default` field is deprecated. YAML uses `priority: number` instead — default 0, higher first.
|
|
26
|
-
- The `default` agent seed stays, `priority: 99` (remains the initial default selection).
|
|
27
|
-
- All `isDefault`-semantic branches become `!parentId` ("root agent") checks.
|
|
28
|
-
- `list_agents` no longer filters `default`; agents can spawn themselves (same agent_id, independent session instances).
|
|
29
|
-
- Delete protection: at least 1 agent in the global scope; workspace scope can be emptied.
|
|
30
|
-
- UI default selection: sort by `priority desc, name asc`, pick the first.
|
|
31
|
-
- Remove the "default" badge.
|
|
32
|
-
|
|
33
|
-
### 2. Add `working_dir`
|
|
34
|
-
|
|
35
|
-
- New `working_dir` argument on `start_session`
|
|
36
|
-
- Accepts absolute or workspace-relative paths
|
|
37
|
-
- Default: `workspaceRoot` (project root)
|
|
38
|
-
- Enforce resolved path within workspace (reject traversal)
|
|
39
|
-
- Non-existent directory → reject spawn
|
|
40
|
-
- `agent_sessions` gets a `workingDir TEXT` column (null = project root)
|
|
41
|
-
- On resume, DB → `buildAgentInstance`
|
|
42
|
-
|
|
43
|
-
### 3. INDEX.md — project-root-only
|
|
44
|
-
|
|
45
|
-
- `<ws>/.halo/INDEX.md` is the sole source, injected for every agent
|
|
46
|
-
- Sub-directory `INDEX.md` files are **not auto-loaded**; user / agent uses `file_read` on demand
|
|
47
|
-
- Drop `subDirIndex` logic in `resolveMdPaths` (dead code)
|
|
48
|
-
- Rationale: multi-level INDEX is an untested requirement; users reference sub-INDEX from the root INDEX and the agent reads on demand (progressive disclosure)
|
|
49
|
-
|
|
50
|
-
### 4. INSTRUCTIONS.md — stacked by level
|
|
51
|
-
|
|
52
|
-
- From global → workspaceRoot → every level of the workingDir path, load `.halo/INSTRUCTIONS.md`
|
|
53
|
-
- Injection order: outer → inner (global first, workingDir last)
|
|
54
|
-
- Each block labelled with its path relative to workspaceRoot (root itself uses `.`)
|
|
55
|
-
- Rationale: INSTRUCTIONS encode "how to work here"; directory depth is a natural scope, more specific wins
|
|
56
|
-
|
|
57
|
-
### 5. Externalise system prompts
|
|
58
|
-
|
|
59
|
-
The four hard-coded constants (BOOTSTRAP / TOOL_GUIDELINES / PLATFORM_KNOWLEDGE / ORCHESTRATOR_GUIDELINES) move to:
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
~/.halo/global/prompts/
|
|
63
|
-
├── bootstrap/ ← only injected for root agent + needsBootstrap
|
|
64
|
-
├── all/ ← injected for every agent
|
|
65
|
-
└── root/ ← only injected for root agent
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
- Subdirectory categorisation decides injection scope
|
|
69
|
-
- Inside each subdirectory, every `.md` is concatenated by filename ascending
|
|
70
|
-
- User extends by dropping MDs in the relevant directory (e.g. `prompts/all/my-style-guide.md`)
|
|
71
|
-
- Startup seed: first run writes four defaults; existing files preserved
|
|
72
|
-
- Live-read (every `buildAgentInstance`)
|
|
73
|
-
- Missing: warn + skip (don't break the server)
|
|
74
|
-
- `tool-guidelines.ts` remains the seed source + hard-coded fallback
|
|
75
|
-
- **Global only**; workspace doesn't override
|
|
76
|
-
- **Language**: seed content stays English (already is); UI copy stays English; section headers stay English; Chinese only in developer docs
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Target directory layout
|
|
81
|
-
|
|
82
|
-
### Global
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
~/.halo/global/
|
|
86
|
-
├── USER.md ← bootstrap-generated
|
|
87
|
-
├── INSTRUCTIONS.md ← user-global preferences
|
|
88
|
-
├── prompts/
|
|
89
|
-
│ ├── bootstrap/BOOTSTRAP.md
|
|
90
|
-
│ ├── all/TOOL_GUIDELINES.md
|
|
91
|
-
│ └── root/PLATFORM_KNOWLEDGE.md, ORCHESTRATOR_GUIDELINES.md
|
|
92
|
-
├── agents/<id>/{agent.yaml, AGENT.md}
|
|
93
|
-
└── skills/<id>/SKILL.md
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Workspace
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
<ws>/.halo/
|
|
100
|
-
├── USER.md ← optional, overrides global
|
|
101
|
-
├── INSTRUCTIONS.md ← project-root preferences
|
|
102
|
-
├── INDEX.md ← sole project index
|
|
103
|
-
├── <subdir>/.halo/INSTRUCTIONS.md ← per-subdir preferences, stacked
|
|
104
|
-
├── agents/<id>/{agent.yaml, AGENT.md}
|
|
105
|
-
└── skills/<id>/SKILL.md
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Root vs sub-agent behaviour matrix
|
|
111
|
-
|
|
112
|
-
| Injected content | Root (`!parentId`) | Sub-agent |
|
|
113
|
-
|---|---|---|
|
|
114
|
-
| USER.md | ✓ | ✗ |
|
|
115
|
-
| AGENT.md | ✓ | ✓ |
|
|
116
|
-
| INSTRUCTIONS.md (global + stacked) | ✓ | ✓ |
|
|
117
|
-
| INDEX.md (project root) | ✓ | ✓ |
|
|
118
|
-
| `prompts/all/` | ✓ | ✓ |
|
|
119
|
-
| `prompts/root/` | ✓ | ✗ |
|
|
120
|
-
| `prompts/bootstrap/` | ✓ (only when no USER.md) | ✗ |
|
|
121
|
-
| `"workspace at..."` | ✓ | ✓ |
|
|
122
|
-
| `"Working directory: ..."` | only when workingDir != root | always |
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Execution phases
|
|
127
|
-
|
|
128
|
-
Grouped into 6 todo buckets:
|
|
129
|
-
|
|
130
|
-
### A. is_default → priority (backend + frontend)
|
|
131
|
-
- session-manager.ts: drop isDefault; replace prompt branches with `!parentId`; merge tool order; drop `list_agents` filter
|
|
132
|
-
- agent-loader.ts: YAML gains priority; `scanAvailableAgents` returns priority
|
|
133
|
-
- agent-configs.ts: `parseAgentYaml` reads priority; sort by priority desc + name asc; seed template gains `priority: 99`; DELETE adds last-global guard
|
|
134
|
-
- frontend types.ts + api-client.ts: rename fields
|
|
135
|
-
- chat-panel.tsx: default-selection logic; remove "default" badge
|
|
136
|
-
- agent-management-main.tsx + agent-form.tsx: delete isDefault UI
|
|
137
|
-
|
|
138
|
-
### B. working_dir feature
|
|
139
|
-
- `start_session` schema adds `working_dir`
|
|
140
|
-
- `createSession` / `buildAgentInstance` pass it through
|
|
141
|
-
- DB migration: `agent_sessions` adds `workingDir` column
|
|
142
|
-
- Resume restores from DB
|
|
143
|
-
|
|
144
|
-
### C. md-loader simplification
|
|
145
|
-
- INDEX.md reads only `<ws>/.halo/INDEX.md`; drop `subDirIndex`
|
|
146
|
-
- INSTRUCTIONS.md becomes `workspaceInstructionsChain: Array<{rel, content}>`
|
|
147
|
-
- `composeMdPrompt` expands the chain as multiple sections, each header labelled with relative path (root = `.`)
|
|
148
|
-
- Implement `collectInstructionsChain(workspaceRoot, workingDir)`
|
|
149
|
-
|
|
150
|
-
### D. Externalise system prompts
|
|
151
|
-
- Create `~/.halo/global/prompts/{bootstrap,all,root}/`
|
|
152
|
-
- `init.ts` startup seeds four MD files (content from `tool-guidelines.ts`)
|
|
153
|
-
- New `loadSystemPrompts()` reads live per subdir, filename-ascending concat
|
|
154
|
-
- Replace `import { ... } from './tool-guidelines'` with `loadSystemPrompts()` calls
|
|
155
|
-
- Missing: warn + fall back to the hard-coded value (keep `tool-guidelines.ts`)
|
|
156
|
-
|
|
157
|
-
### E. Doc sync
|
|
158
|
-
- CLAUDE.md: describe the MD load flow, agent model
|
|
159
|
-
- `.halo/docs/backend/md-loading-flow.md` (already in target state)
|
|
160
|
-
- `.halo/docs/knowledge-system.md`: directory layout, injection rules
|
|
161
|
-
- `.halo/docs/data-storage-protocol.md`: agent YAML fields + new agent_sessions column
|
|
162
|
-
- `.halo/docs/session-tools-reference.md`: `start_session` schema
|
|
163
|
-
- `.halo/docs/test-case.md`: updated test cases
|
|
164
|
-
|
|
165
|
-
### F. Deployment smoke test
|
|
166
|
-
- `pnpm --filter core/server/web build`
|
|
167
|
-
- Kill 9527, restart with Node 22 (PATH=$HOME/.nvm/versions/node/v22.21.1/bin:$PATH)
|
|
168
|
-
- Smoke: /api/health, WS connect, send one message end-to-end
|
|
169
|
-
- Verify: root agent receives prompts/root, sub-agent doesn't; INSTRUCTIONS stacking works; working_dir wires through; deletion guard fires
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## Key constraints and risks
|
|
174
|
-
|
|
175
|
-
- **Node version**: must be v22+ (better-sqlite3 native binding bound to v22). Scripts must load nvm.
|
|
176
|
-
- **Compatibility**: legacy YAML's `is_default: true` stays readable but ignored; DB's `is_default` column stays untouched, just unread.
|
|
177
|
-
- **Backwards-compat seed**: `default` agent still auto-seeds with id `default`, but YAML uses `priority: 99`.
|
|
178
|
-
- **Path safety**: `working_dir` must be verified inside workspace (block `../` escapes).
|
|
179
|
-
- **Cache key**: with merged tool list, `cache_control` still goes on the last tool — stability unaffected.
|
|
180
|
-
- **Bootstrap idempotence**: once USER.md exists, `needsBootstrap` is false forever, `prompts/bootstrap/` no longer injects.
|
|
181
|
-
- **Self-spawn allowed**: `session_id` depth limit (`maxNestingDepth`) already guards against infinite recursion.
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Rollback plan
|
|
186
|
-
|
|
187
|
-
If something breaks in production:
|
|
188
|
-
- Git revert to pre-refactor commit
|
|
189
|
-
- `~/.halo/global/prompts/` directory is harmless to older versions (they don't read it)
|
|
190
|
-
- `agent_sessions.workingDir` column harmless (old code reads null → falls back to workspaceRoot)
|
|
191
|
-
- YAML `priority` harmless to older code (unknown field = default 0); `is_default: true` can be seeded back into the default agent's YAML
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Todo index
|
|
196
|
-
|
|
197
|
-
See the todo list. All 12 pending items run A → F; the last one is the smoke test.
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# Remote Mac Worker — Design Blueprint
|
|
2
|
-
|
|
3
|
-
**Status**: not started, design initially frozen
|
|
4
|
-
**Filed**: 2026-04-28
|
|
5
|
-
**Priority**: future work, not at the front of the roadmap
|
|
6
|
-
|
|
7
|
-
## Scope
|
|
8
|
-
|
|
9
|
-
Wire the user's Mac into Halo — **not** as a remote code workspace, but as a **capability provider**, letting server-side agents tap into native Mac capabilities (screenshot, camera, browser, WPS, iMessage, calendar, …).
|
|
10
|
-
|
|
11
|
-
The key contrast with openclaw / opencode / Claude Code:
|
|
12
|
-
- Those tools: agent loop on the local machine, LLM remote
|
|
13
|
-
- This plan: **agent loop + LLM both on the server, Mac is just a "capability execution environment"**
|
|
14
|
-
|
|
15
|
-
It's "Mac as a service", not "LLM as a service".
|
|
16
|
-
|
|
17
|
-
## Architecture choice: Swiss-army knife + skill accumulation
|
|
18
|
-
|
|
19
|
-
Rejected alternatives (discussed and dropped):
|
|
20
|
-
- **Static capability plugin** (a fixed preset tool set) → capability boundary is rigid; agents have no recourse for novel capabilities
|
|
21
|
-
- **Computer Use pixel-level** (screenshot + click coordinates) → unfriendly to the 2018 Intel Mac (slow + expensive); universality bought with token cost
|
|
22
|
-
|
|
23
|
-
Settled on **Swiss-army knife + skills**:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
Low-level primitives (registered by the Worker)
|
|
27
|
-
- mac_shell(cmd) → arbitrary shell commands
|
|
28
|
-
- mac_applescript(script) → arbitrary AppleScript
|
|
29
|
-
- mac_jxa(script) → JavaScript for Automation (AppleScript modernised)
|
|
30
|
-
- mac_filesystem → file_read/write/list etc.
|
|
31
|
-
|
|
32
|
-
Middle layer — skills (preset + user-written + agent-accumulated)
|
|
33
|
-
- mac_screenshot
|
|
34
|
-
- mac_take_photo
|
|
35
|
-
- mac_open_wps
|
|
36
|
-
- mac_safari_goto
|
|
37
|
-
- mac_read_imessage
|
|
38
|
-
- …(agent first explores new scenarios, then asks user to save them as skills after verification)
|
|
39
|
-
|
|
40
|
-
Surface / UI
|
|
41
|
-
- Settings shows the connected worker + its registered primitives
|
|
42
|
-
- Each skill can be enabled/disabled
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Why:
|
|
46
|
-
- Covers ~99% of Mac apps (mature AppleScript ecosystem)
|
|
47
|
-
- Friendly to old Intel Mac hardware (no continuous-screenshot + vision-inference load)
|
|
48
|
-
- Plays naturally with Halo's existing Skill system
|
|
49
|
-
- High capability ceiling (Turing-complete)
|
|
50
|
-
|
|
51
|
-
## Worker protocol outline
|
|
52
|
-
|
|
53
|
-
WebSocket-based reverse connection (Mac only needs outbound; no public IP needed):
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
Mac Halo Server (9527)
|
|
57
|
-
halo-worker ──── WSS ───▶ /worker endpoint
|
|
58
|
-
↕
|
|
59
|
-
worker-pool
|
|
60
|
-
↕
|
|
61
|
-
agent tool dispatch
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Worker registration payload:
|
|
65
|
-
|
|
66
|
-
```json
|
|
67
|
-
{
|
|
68
|
-
"type": "register",
|
|
69
|
-
"workerId": "peter-mac",
|
|
70
|
-
"primitives": ["shell", "applescript", "jxa", "filesystem"],
|
|
71
|
-
"os": "macos",
|
|
72
|
-
"osVersion": "14.x",
|
|
73
|
-
"arch": "x64",
|
|
74
|
-
"home": "/Users/peter"
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Server reads `primitives` and dynamically assembles the tool set it injects into the agent.
|
|
79
|
-
|
|
80
|
-
Protocol messages to support:
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
Worker → Server
|
|
84
|
-
- register
|
|
85
|
-
- tool_result (id, ok, result)
|
|
86
|
-
- tool_stream (id, chunk) // shell stdout streaming
|
|
87
|
-
- pong
|
|
88
|
-
|
|
89
|
-
Server → Worker
|
|
90
|
-
- tool_call (id, tool, args, dry_run?)
|
|
91
|
-
- tool_cancel (id)
|
|
92
|
-
- ping
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Tool results must support multiple shapes**: text / image (base64 PNG) / file (binary) / structured (JSON). No longer the "all-tool-results-are-strings" simplification.
|
|
96
|
-
|
|
97
|
-
## Security model (mandatory)
|
|
98
|
-
|
|
99
|
-
**Dynamic model + Swiss-army knife = high risk**. Required guards:
|
|
100
|
-
|
|
101
|
-
### 1. Frontend approval
|
|
102
|
-
|
|
103
|
-
Every `mac_shell` / `mac_applescript` execution pops a frontend confirmation:
|
|
104
|
-
- Show the command text
|
|
105
|
-
- Allow once / allow for this session / allow permanently for this command pattern
|
|
106
|
-
|
|
107
|
-
Like Claude Desktop / Cursor's tool approval UI.
|
|
108
|
-
|
|
109
|
-
### 2. Server-side dangerous-command blocking
|
|
110
|
-
|
|
111
|
-
Regex scan for:
|
|
112
|
-
- `rm -rf`, `sudo`, `curl|bash` pipes, `nc`, `mkfs`, `dd`
|
|
113
|
-
- AppleScript `delete file`, `empty trash`, `quit application`
|
|
114
|
-
→ Force popup, no "session allowlist"
|
|
115
|
-
|
|
116
|
-
### 3. Worker-side path validation
|
|
117
|
-
|
|
118
|
-
`mac_filesystem`-family tools still use the `validateWorkspacePath` approach from `workspace-tools.ts`; the worker validates itself, doesn't trust server-supplied absolute paths.
|
|
119
|
-
|
|
120
|
-
### 4. Capability switches
|
|
121
|
-
|
|
122
|
-
Settings lets the user:
|
|
123
|
-
- Disable `mac_shell` (keep only AppleScript)
|
|
124
|
-
- Block specific commands entirely (`rm` / `sudo` / `curl`)
|
|
125
|
-
- Disable an entire sensitive skill
|
|
126
|
-
|
|
127
|
-
## Hardware constraints (user's 2018 Intel Mac)
|
|
128
|
-
|
|
129
|
-
- Latest macOS (exact version unknown — will probe)
|
|
130
|
-
- **Computer Use pixel-vision unsuitable** — old GPU, slow image processing
|
|
131
|
-
- AppleScript / shell / osascript are native CLI — no perf issues
|
|
132
|
-
- `node-pty` needs to be built x64 (not arm64)
|
|
133
|
-
|
|
134
|
-
## Time estimate (revised)
|
|
135
|
-
|
|
136
|
-
The earlier "2-3 days" was wishful; realistic estimate:
|
|
137
|
-
|
|
138
|
-
| Phase | Time | Deliverable |
|
|
139
|
-
|---|---|---|
|
|
140
|
-
| MVP: protocol + shell + filesystem | 1 week | Agent can run commands / read files on Mac |
|
|
141
|
-
| + AppleScript + screenshot | 3 days | Agent controls any Mac app + screenshots |
|
|
142
|
-
| + Safari control, WPS control | 3 days | "Open this page and screenshot it" works end-to-end |
|
|
143
|
-
| + Camera, iMessage | 3-5 days | Take photos, read/send messages |
|
|
144
|
-
| UI: worker management + approvals | 1 week | Frontend can see worker status, approve tool calls |
|
|
145
|
-
| Polish + package CLI + deploy docs | 1-2 weeks | Shippable |
|
|
146
|
-
|
|
147
|
-
**Total: 4-6 full-time weeks.**
|
|
148
|
-
|
|
149
|
-
Suggested split:
|
|
150
|
-
- **First window (2 weekend days)**: MVP only. Get "agent executes `ls` on Mac and sees the result". Stop to evaluate whether to continue.
|
|
151
|
-
- **Second window (2-3 weeks)**: up to "screenshot + Safari + WPS control" — already a strong demo.
|
|
152
|
-
|
|
153
|
-
## MVP checklist
|
|
154
|
-
|
|
155
|
-
Start and stop here; do nothing else until it lands:
|
|
156
|
-
|
|
157
|
-
- [ ] New `packages/worker` workspace, add to pnpm
|
|
158
|
-
- [ ] New `packages/server/src/workers/` with worker-pool + `/worker` WS endpoint
|
|
159
|
-
- [ ] Protocol: register / tool_call / tool_result / ping-pong
|
|
160
|
-
- [ ] Worker CLI: WS connect, register, ping, one `mac_shell` primitive
|
|
161
|
-
- [ ] Server: Project table gains `execution_target` (local / worker:<id>)
|
|
162
|
-
- [ ] Agent tool dispatch abstraction: `LocalExecutor` vs `RemoteExecutor`
|
|
163
|
-
- [ ] Frontend: Settings hard-codes one worker entry + shows worker status
|
|
164
|
-
- [ ] End-to-end: agent runs `ls ~` on Mac successfully
|
|
165
|
-
|
|
166
|
-
Stop once these 8 are green. **Do not expand scope.**
|
|
167
|
-
|
|
168
|
-
## Decision log vs Anthropic Computer Use
|
|
169
|
-
|
|
170
|
-
We discussed Computer Use (Claude Sonnet 3.5+'s vision + coordinate-click capability) and decided not to go that route, because:
|
|
171
|
-
|
|
172
|
-
1. User's machine is 2018 Intel Mac; vision inference is slow
|
|
173
|
-
2. Each step's screenshot burns tokens → costly
|
|
174
|
-
3. Non-deterministic (potential misclicks)
|
|
175
|
-
4. Generic, but overkill for macOS's mature AppleScript ecosystem
|
|
176
|
-
5. Halo runs on Bedrock Claude; it's supported but latency/cost is worse than direct API
|
|
177
|
-
|
|
178
|
-
**Not opposed to adding it later** as another primitive ("vision fallback"), but not the main path.
|
|
179
|
-
|
|
180
|
-
## Reference projects
|
|
181
|
-
|
|
182
|
-
- **Anthropic computer-use-demo** (Docker demo, for protocol reference)
|
|
183
|
-
- **OpenInterpreter 01** (open-source local agent, primitive design)
|
|
184
|
-
- **Claude Desktop + MCP** (tool approval UX)
|
|
185
|
-
- **Self-Operating Computer** (coordinate-click fallback, if we ever add it)
|
|
186
|
-
- **Dagger** / **dstack.ai** (worker pool management)
|
|
187
|
-
|
|
188
|
-
## Questions to answer before starting
|
|
189
|
-
|
|
190
|
-
1. Mac's specific macOS version (gates which APIs are available)
|
|
191
|
-
2. Which three skills to prioritise packaging (pick 3 from screenshot / Safari / WPS / iMessage)
|
|
192
|
-
3. Approval UI granularity (session allowlist vs per-command pattern)
|
|
193
|
-
4. Worker auth (where to store tokens, rotation)
|
|
194
|
-
5. Multi-worker support (1 server to N workers)
|
|
195
|
-
|
|
196
|
-
Answer these first before any code.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Roadmap
|
|
2
|
-
|
|
3
|
-
## Model Providers
|
|
4
|
-
- [x] OpenAI (GPT series)
|
|
5
|
-
- [ ] Google Gemini
|
|
6
|
-
- [ ] OpenRouter (multi-model aggregator)
|
|
7
|
-
- [ ] Ollama (local models)
|
|
8
|
-
|
|
9
|
-
Extension interface is ready (`ModelRuntime`). Adding providers is integration work, not architecture work.
|
|
10
|
-
|
|
11
|
-
## Channels
|
|
12
|
-
- [ ] Discord
|
|
13
|
-
- [x] Slack
|
|
14
|
-
- [ ] Email
|
|
15
|
-
- [ ] SMS
|
|
16
|
-
|
|
17
|
-
Channel adapter pattern established (Web, WeChat, Telegram, Slack, Feishu already working). New channels follow the same `CommandContext` interface.
|
|
18
|
-
|
|
19
|
-
## CLI / TUI
|
|
20
|
-
- [x] CLI mode (headless, SSH-friendly)
|
|
21
|
-
- [x] TUI (terminal UI with interactive chat)
|
|
22
|
-
|
|
23
|
-
Enables usage without a browser. Important for SSH-into-server workflows.
|
|
24
|
-
|
|
25
|
-
## Deployment
|
|
26
|
-
- [ ] Dockerfile + docker-compose
|
|
27
|
-
- [ ] One-click deploy templates (Fly.io / Render / Railway)
|
|
28
|
-
|
|
29
|
-
Currently manual (`node dist/index.js`). Containerization needed for distribution.
|
|
30
|
-
|
|
31
|
-
## Shared Workspace
|
|
32
|
-
- [ ] Workspace templates (clone/fork a pre-configured workspace)
|
|
33
|
-
- [ ] Workspace marketplace or registry
|
|
34
|
-
- [ ] Readonly workspace sharing with token auth
|
|
35
|
-
|
|
36
|
-
Core differentiator. Share an entire configured workspace (agents + skills + context + docs), not just individual tools or skills.
|
|
37
|
-
|
|
38
|
-
## Quality
|
|
39
|
-
- [ ] Test suite (unit + integration)
|
|
40
|
-
- [ ] CI pipeline
|