@roackb2/heddle 0.0.18 → 0.0.20
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 +140 -614
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +13 -1
- package/dist/src/server/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,741 +1,267 @@
|
|
|
1
1
|
# Heddle
|
|
2
2
|
|
|
3
|
-
Heddle is
|
|
4
|
-
|
|
5
|
-
It is built to feel like a terminal partner that understands your project, keeps continuity across real work, and becomes more useful over time.
|
|
6
|
-
|
|
7
|
-
It is open source, provider-agnostic, supports OpenAI and Anthropic models, and can build memory across sessions. For agentic-system builders, Heddle also exposes heartbeat primitives for autonomous wake cycles, checkpointing, and long-running background work.
|
|
8
|
-
|
|
9
|
-
Heddle is designed to make live agent runs more observable, not just easier to launch. With CyberLoop installed, Heddle can show whether the agent's outputs are moving away from the recent response trajectory, surface `drift=unknown|low|medium|high` in chat, and write drift annotations into saved traces instead of leaving you to infer that only from token usage and tool calls.
|
|
10
|
-
|
|
11
|
-
If you are interested in the underlying methodology, Heddle's drift telemetry is powered by [CyberLoop on npm](https://www.npmjs.com/package/cyberloop). See the [CyberLoop repository](https://github.com/roackb2/cyberloop) and [paper](https://zenodo.org/records/18138161) for the geometric-control and trajectory-based details.
|
|
12
|
-
|
|
13
|
-
## Agenda
|
|
14
|
-
|
|
15
|
-
- [Chat And CLI Usage](#chat-and-cli-usage)
|
|
16
|
-
- [Control Plane](#control-plane)
|
|
17
|
-
- [Knowledge Persistence](#knowledge-persistence)
|
|
18
|
-
- [Semantic Drift](#semantic-drift)
|
|
19
|
-
- [Heartbeat](#heartbeat)
|
|
20
|
-
- [Programmatic Use](#programmatic-use)
|
|
21
|
-
- [Capability Details](#capability-details)
|
|
22
|
-
- [Supported Providers And Models](#supported-providers-and-models)
|
|
23
|
-
- [Project Config](#project-config)
|
|
24
|
-
- [Design Direction](#design-direction)
|
|
25
|
-
|
|
26
|
-
## How Heddle Helps
|
|
27
|
-
|
|
28
|
-
- daily development work in real coding projects
|
|
29
|
-
- understanding unfamiliar repositories and carrying fixes through inspection, edits, and verification
|
|
30
|
-
- infrastructure and environment inspection through approval-gated shell commands
|
|
31
|
-
- broader terminal-based agent workflows whenever the needed CLI tools already exist in the environment
|
|
32
|
-
- tasks such as image, media, or document processing through existing command-line tools like `ffmpeg`, ImageMagick, or project-specific scripts
|
|
33
|
-
- long-running multi-step work that benefits from chat continuity, short plans, and explicit operator control
|
|
34
|
-
|
|
35
|
-
## Advanced Capabilities
|
|
36
|
-
|
|
37
|
-
- provider-agnostic model support across OpenAI and Anthropic
|
|
38
|
-
- embeddable `runAgentLoop` API for building non-CLI agent hosts
|
|
39
|
-
- `runAgentHeartbeat` for scheduler-driven autonomous wake cycles without chat by default
|
|
40
|
-
- reorganized core runtime modules under `src/core` for agent, runtime, llm, tools, prompts, trace, and shared utilities
|
|
41
|
-
- native React/Vite control plane served by `heddle daemon` for local browser-based oversight
|
|
42
|
-
- serializable checkpoints for resume, background execution, and hosted workers
|
|
43
|
-
- host-facing heartbeat task/run views plus websocket-friendly status/progress/response adapters
|
|
44
|
-
- provider-backed hosted web search through `web_search`
|
|
45
|
-
- local image viewing from referenced file paths through `view_image`
|
|
46
|
-
- inline `@file` mentions that tell the agent which workspace files to inspect first
|
|
47
|
-
- multi-turn sessions with save, switch, continue, rename, and close flows
|
|
48
|
-
- automatic conversation compaction for longer chats, plus manual `/compact` when needed
|
|
49
|
-
- persistent workspace knowledge through `.heddle/memory/`
|
|
50
|
-
- lightweight working-plan tracking through `update_plan`
|
|
51
|
-
- approval-gated shell execution with remembered per-project approvals
|
|
52
|
-
- trace logs, persistent chat state, and project instruction loading under `.heddle/`
|
|
3
|
+
Heddle is an open-source terminal coding agent runtime and CLI for real project work.
|
|
53
4
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Global install:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
npm install -g @roackb2/heddle
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Run without a global install:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npx @roackb2/heddle
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The installed CLI command remains `heddle`.
|
|
69
|
-
|
|
70
|
-
If you want CyberLoop drift telemetry in chat, or you want to import `cyberloop/advanced` in your own host, install `cyberloop` in the same environment as Heddle:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
npm install -g cyberloop
|
|
74
|
-
# or for project-local usage
|
|
75
|
-
npm install cyberloop
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The plain `npx @roackb2/heddle` path does not include optional peer dependencies. For one-off drift-enabled usage, install both packages locally or run:
|
|
5
|
+
It is designed for workflows where an agent needs to inspect a live repository, make bounded changes, verify results, keep continuity across sessions, and stay observable to the operator. Heddle supports OpenAI and Anthropic models, stores local workspace state under `.heddle/`, and includes both a terminal chat experience and a browser control plane.
|
|
79
6
|
|
|
80
|
-
|
|
81
|
-
npx -p @roackb2/heddle -p cyberloop heddle
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
If you are developing inside the Heddle repo itself, `yarn install` also installs `cyberloop` through `devDependencies`, so `yarn chat:dev` can use the published package path without extra setup.
|
|
85
|
-
|
|
86
|
-
For local development against the full CLI entrypoint, use `yarn cli:dev`. The `chat:dev` scripts intentionally start chat mode directly and do not route subcommands such as `heartbeat`.
|
|
87
|
-
|
|
88
|
-
## Chat And CLI Usage
|
|
89
|
-
|
|
90
|
-
### Quick Start
|
|
91
|
-
|
|
92
|
-
1. Set an API key for a supported provider.
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
export OPENAI_API_KEY=your_key_here
|
|
96
|
-
# or
|
|
97
|
-
export ANTHROPIC_API_KEY=your_key_here
|
|
98
|
-
```
|
|
7
|
+
In plain terms: Heddle is for people who want an agent that can work inside an actual project, not just answer isolated prompts.
|
|
99
8
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
cd /path/to/project
|
|
104
|
-
```
|
|
9
|
+
## What Heddle Does
|
|
105
10
|
|
|
106
|
-
|
|
11
|
+
At a high level, Heddle helps with:
|
|
107
12
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
13
|
+
- understanding unfamiliar repositories
|
|
14
|
+
- making code or doc changes inside a real workspace
|
|
15
|
+
- running bounded verification like builds, tests, and repo review
|
|
16
|
+
- keeping multi-step work going across sessions instead of starting from scratch each time
|
|
17
|
+
- exposing more operator visibility than a black-box chat tool
|
|
111
18
|
|
|
112
|
-
|
|
19
|
+
If you want a terminal-first coding agent with local state, review traces, and a path toward longer-running workflows, that is the problem Heddle is trying to solve.
|
|
113
20
|
|
|
114
|
-
|
|
21
|
+
## Major Features
|
|
115
22
|
|
|
116
|
-
###
|
|
23
|
+
### Terminal chat for real coding work
|
|
117
24
|
|
|
118
|
-
|
|
25
|
+
The main way to use Heddle is interactive chat in a repository:
|
|
119
26
|
|
|
120
27
|
```bash
|
|
121
28
|
heddle
|
|
122
|
-
heddle chat
|
|
123
|
-
heddle --cwd /path/to/project
|
|
124
|
-
heddle chat --model gpt-5.4-mini --max-steps 20
|
|
125
29
|
```
|
|
126
30
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
- ask Heddle to explain architecture, code paths, tests, or build setup
|
|
130
|
-
- iterate on a fix over multiple prompts instead of fitting everything into one request
|
|
131
|
-
- inspect files, search the repo, and edit code inside one persistent session
|
|
132
|
-
- keep a long coding conversation usable through saved sessions, `/continue`, automatic history compaction, and manual `/compact`
|
|
133
|
-
- let the agent create and update a short working plan for a multi-step implementation
|
|
134
|
-
- search official docs or other current external references with provider-backed `web_search`
|
|
135
|
-
- mention important repo files with `@path/to/file` so the agent treats them as first-pass context
|
|
136
|
-
- reference a local screenshot path and have the agent inspect it with `view_image`
|
|
137
|
-
- run direct shell commands from chat with `!<command>`
|
|
138
|
-
- pause and later resume earlier sessions
|
|
139
|
-
|
|
140
|
-
Useful chat commands:
|
|
141
|
-
|
|
142
|
-
- `/help`: show local chat commands
|
|
143
|
-
- `/continue`: resume the current session from its last interrupted or prior run
|
|
144
|
-
- `/model`: show the active model
|
|
145
|
-
- `/model list`: show the built-in shortlist
|
|
146
|
-
- `/model set <query>`: open the interactive model picker
|
|
147
|
-
- `/model <name>`: switch models directly
|
|
148
|
-
- `/session list`: list recent saved sessions
|
|
149
|
-
- `/session choose <query>`: choose a recent session interactively
|
|
150
|
-
- `/session new [name]`: create a new session
|
|
151
|
-
- `/session switch <id>`: switch to another session
|
|
152
|
-
- `/session continue <id>`: switch and immediately continue that session
|
|
153
|
-
- `/session rename <name>`: rename the current session
|
|
154
|
-
- `/session close <id>`: remove a saved session
|
|
155
|
-
- `/clear`: clear the current transcript
|
|
156
|
-
- `/compact`: compact older session history immediately
|
|
157
|
-
- `/drift`: show CyberLoop semantic drift detection status
|
|
158
|
-
- `/drift on`: re-enable observe-only CyberLoop kinematics telemetry for chat runs
|
|
159
|
-
- `/drift off`: disable CyberLoop semantic drift detection
|
|
160
|
-
- `!<command>`: run a shell command directly in chat
|
|
161
|
-
|
|
162
|
-
Direct shell in chat:
|
|
31
|
+
From there, Heddle can inspect files, explain code, make edits, run shell commands with the right approval model, and carry a task through multiple turns.
|
|
163
32
|
|
|
164
|
-
|
|
165
|
-
!pwd
|
|
166
|
-
!git status
|
|
167
|
-
!yarn test
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Read-oriented commands stay in inspect mode when possible. Workspace-changing or unclassified commands fall back to approval-gated execution.
|
|
171
|
-
|
|
172
|
-
Chat state is stored under `.heddle/`, including saved sessions, traces, approvals, and memory notes. The footer context indicator is an estimate of total request input against the active model's context window, not only the raw chat history length.
|
|
173
|
-
|
|
174
|
-
For local development against the sibling CyberLoop repo, run chat with the middleware module path:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
HEDDLE_CYBERLOOP_ADVANCED_MODULE=/Users/roackb2/Studio/projects/CyberLoop/src/advanced/kinematics-middleware.ts yarn chat:dev:openai
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Drift telemetry is enabled by default for new sessions. For installed usage, install the optional `cyberloop` peer dependency in the same environment as Heddle so it can dynamically import `cyberloop/advanced`.
|
|
181
|
-
|
|
182
|
-
### CLI Commands
|
|
183
|
-
|
|
184
|
-
Supported commands:
|
|
33
|
+
This is the core feature. If you only use Heddle as a coding agent in the terminal, this is the part you care about.
|
|
185
34
|
|
|
186
|
-
|
|
187
|
-
- `heddle ask "<goal>"`: run a single prompt and exit
|
|
188
|
-
- `heddle heartbeat start [--every 30m] [--task "<durable task>"]`: create or enable the default heartbeat task and run the foreground scheduler
|
|
189
|
-
- `heddle heartbeat task add --id <id> --task "<durable task>" [--every 15m]`: create or update a scheduled heartbeat task
|
|
190
|
-
- `heddle heartbeat task list`: list local heartbeat tasks
|
|
191
|
-
- `heddle heartbeat task show <id>`: show a task's schedule, last decision, and last run summary
|
|
192
|
-
- `heddle heartbeat task enable <id>` / `heddle heartbeat task disable <id>`: toggle a heartbeat task
|
|
193
|
-
- `heddle heartbeat run --once`: run due heartbeat tasks once
|
|
194
|
-
- `heddle heartbeat run [--poll 60s]`: run the foreground heartbeat scheduler until interrupted; heartbeat runs print scheduler, agent, tool, decision, and checkpoint progress events
|
|
195
|
-
- `heddle heartbeat runs list [--task <id>] [--limit 10]`: list saved heartbeat run records
|
|
196
|
-
- `heddle heartbeat runs show <run-id|latest> [--task <id>]`: show the final agent output for a saved heartbeat run
|
|
197
|
-
- `heddle init`: create a `heddle.config.json` template in the current project
|
|
35
|
+
More: [Chat and sessions guide](docs/guides/chat-and-sessions.md)
|
|
198
36
|
|
|
199
|
-
|
|
37
|
+
### Sessions and continuity
|
|
200
38
|
|
|
201
|
-
|
|
202
|
-
- `--model <name>`: choose the active model
|
|
203
|
-
- `--max-steps <n>`: limit the agent loop length
|
|
39
|
+
Heddle keeps saved sessions under `.heddle/` so longer work does not have to reset every time. That means you can come back to an interrupted task, continue a previous debugging thread, or preserve project-specific context across runs.
|
|
204
40
|
|
|
205
|
-
|
|
41
|
+
This matters if you are doing real multi-step work rather than one-shot prompts.
|
|
206
42
|
|
|
207
|
-
|
|
43
|
+
Typical session commands include:
|
|
208
44
|
|
|
209
|
-
|
|
45
|
+
- `/session list`
|
|
46
|
+
- `/session switch <id>`
|
|
47
|
+
- `/continue`
|
|
48
|
+
- `/compact`
|
|
210
49
|
|
|
211
|
-
|
|
50
|
+
More: [Chat and sessions guide](docs/guides/chat-and-sessions.md)
|
|
212
51
|
|
|
213
|
-
|
|
214
|
-
- `src/web`: React/Vite web client
|
|
215
|
-
- `src/server/features/control-plane`: control-plane-specific server feature logic
|
|
216
|
-
- pino logs written locally for debugging
|
|
52
|
+
### Control plane
|
|
217
53
|
|
|
218
|
-
|
|
54
|
+
The control plane is Heddle's local browser UI:
|
|
219
55
|
|
|
220
56
|
```bash
|
|
221
57
|
heddle daemon
|
|
222
58
|
```
|
|
223
59
|
|
|
224
|
-
|
|
60
|
+
It gives you a browser-based view into sessions, run state, heartbeat tasks, and review-oriented details. The purpose is operator oversight: seeing what the agent is doing, reviewing history more comfortably, and managing local runs from a UI instead of only from the terminal.
|
|
225
61
|
|
|
226
|
-
|
|
227
|
-
- saved chat sessions with sidebar navigation, resizable desktop panels, conversation view, and review-oriented detail inspection
|
|
228
|
-
- browser-side session actions for new session, send, continue, cancel, and pending approval resolution
|
|
229
|
-
- live per-session updates over SSE for run status, tool progress, assistant streaming text, and saved-session changes
|
|
230
|
-
- a model selector backed by the server-side built-in model catalog, plus a drift toggle and latest trace-derived drift level
|
|
231
|
-
- debounced `@file` mention suggestions in the composer, backed by a capped workspace file search endpoint
|
|
232
|
-
- compact tool-result cards for saved tool outputs such as `list_files: {...}`
|
|
233
|
-
- lightweight toast notifications for session/action success and failure
|
|
234
|
-
- heartbeat task status, scheduling state, selected task detail, and run history
|
|
235
|
-
- recent heartbeat run summaries and usage data
|
|
62
|
+
If terminal chat is the execution surface, the control plane is the oversight surface.
|
|
236
63
|
|
|
237
|
-
|
|
64
|
+
This is useful if you want a more inspectable and operator-friendly workflow than a plain CLI transcript.
|
|
238
65
|
|
|
239
|
-
|
|
240
|
-
heddle daemon --host 127.0.0.1 --port 8765
|
|
241
|
-
```
|
|
66
|
+
More: [Control plane guide](docs/guides/control-plane.md)
|
|
242
67
|
|
|
243
|
-
|
|
68
|
+
### Knowledge persistence
|
|
244
69
|
|
|
245
|
-
|
|
246
|
-
yarn server:dev
|
|
247
|
-
yarn client:dev
|
|
248
|
-
```
|
|
70
|
+
Heddle can keep durable project knowledge in markdown notes under `.heddle/memory/`.
|
|
249
71
|
|
|
250
|
-
|
|
72
|
+
The idea is simple: if the agent learns a stable fact about your repo — architecture notes, command quirks, recurring build issues, conventions — it can save that knowledge so future sessions do not have to rediscover it.
|
|
251
73
|
|
|
252
|
-
|
|
74
|
+
This is not meant to be a hidden vector database or magical long-term memory. It is readable, local, workspace-scoped memory that both the agent and the human can inspect.
|
|
253
75
|
|
|
254
|
-
|
|
76
|
+
This matters if you want the agent to become more useful over time in a specific project.
|
|
255
77
|
|
|
256
|
-
|
|
257
|
-
- backend API on `8765`
|
|
258
|
-
- Vite frontend on `5173`
|
|
259
|
-
- built daemon mode uses one service:
|
|
260
|
-
- `heddle daemon` serves both the built web client and the backend API on the same port
|
|
78
|
+
More: [Knowledge persistence](docs/guides/knowledge-persistence.md)
|
|
261
79
|
|
|
262
|
-
|
|
80
|
+
### Heartbeat
|
|
263
81
|
|
|
264
|
-
|
|
265
|
-
yarn build
|
|
266
|
-
heddle daemon
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
That path serves the built control-plane frontend from `dist/src/web` and mounts the backend API and session-event endpoints from the same daemon process. If you open the backend dev server port directly while only `yarn server:dev` is running, you may see `Cannot GET /`, because that dev path is API-only.
|
|
82
|
+
Heartbeat is Heddle's model for bounded autonomous wake cycles.
|
|
270
83
|
|
|
271
|
-
|
|
84
|
+
Instead of only running when a human types a prompt, a heartbeat task lets Heddle wake up on a schedule, do a limited amount of work, checkpoint the result, and decide whether to continue, pause, complete, or escalate.
|
|
272
85
|
|
|
273
|
-
|
|
86
|
+
Example commands:
|
|
274
87
|
|
|
275
88
|
```bash
|
|
276
|
-
|
|
89
|
+
heddle heartbeat start --every 30m
|
|
90
|
+
heddle heartbeat task add --id repo-gardener --task "Check for safe maintenance work" --every 1h
|
|
91
|
+
heddle heartbeat task list
|
|
277
92
|
```
|
|
278
93
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
## Knowledge Persistence
|
|
282
|
-
|
|
283
|
-
Heddle can maintain durable workspace knowledge under `.heddle/memory/`.
|
|
284
|
-
|
|
285
|
-
The goal is to help Heddle learn from real project work over time instead of rediscovering the same stable facts every session.
|
|
286
|
-
|
|
287
|
-
Typical examples:
|
|
288
|
-
|
|
289
|
-
- architecture notes that future sessions should reuse
|
|
290
|
-
- recurring build, test, or environment quirks
|
|
291
|
-
- important repo conventions and command patterns
|
|
292
|
-
- durable findings from completed implementation work
|
|
94
|
+
Why this exists: some agent work is not a single interactive chat. You may want periodic repo inspection, recurring maintenance checks, scheduled summaries, or a host that can resume work in bounded steps.
|
|
293
95
|
|
|
294
|
-
|
|
96
|
+
If you do not need scheduled or semi-autonomous workflows, you can ignore heartbeat entirely and just use chat.
|
|
295
97
|
|
|
296
|
-
|
|
297
|
-
- Heddle can list, read, search, and edit those notes
|
|
298
|
-
- shell tools are still available when flexible retrieval or editing is needed
|
|
299
|
-
- memory is meant for stable, reusable knowledge, not scratch notes or speculative plans
|
|
98
|
+
More: [Heartbeat guide](docs/guides/heartbeat.md)
|
|
300
99
|
|
|
301
|
-
|
|
100
|
+
### Semantic drift
|
|
302
101
|
|
|
303
|
-
|
|
102
|
+
Semantic drift is optional telemetry that helps you see whether the assistant's responses appear to be moving away from the recent semantic trajectory of the conversation.
|
|
304
103
|
|
|
305
|
-
|
|
104
|
+
With optional [CyberLoop](https://www.npmjs.com/package/cyberloop) integration installed, Heddle can surface drift levels such as:
|
|
306
105
|
|
|
307
|
-
|
|
106
|
+
- `drift=unknown`
|
|
107
|
+
- `drift=low`
|
|
108
|
+
- `drift=medium`
|
|
109
|
+
- `drift=high`
|
|
308
110
|
|
|
309
|
-
|
|
111
|
+
This is an observability feature, not a magic correctness guarantee. It is meant to help operators notice when a run may be getting less aligned with its recent direction.
|
|
310
112
|
|
|
311
|
-
|
|
113
|
+
If you are just looking for a coding agent, you do not need to care about this on day one. If you care about agent observability and runtime behavior, it is one of Heddle's more distinctive features.
|
|
312
114
|
|
|
313
|
-
|
|
115
|
+
More: [Semantic drift](docs/guides/semantic-drift.md)
|
|
314
116
|
|
|
315
|
-
|
|
117
|
+
### Programmatic runtime APIs
|
|
316
118
|
|
|
317
|
-
|
|
119
|
+
Heddle is not only a CLI. The npm package also exposes runtime primitives such as `runAgentLoop` and `runAgentHeartbeat` so other hosts can build on top of it.
|
|
318
120
|
|
|
319
|
-
|
|
121
|
+
This is for people building their own agent hosts, schedulers, or control surfaces rather than only using the packaged CLI.
|
|
320
122
|
|
|
321
|
-
|
|
322
|
-
- resumes prior transcript state if available
|
|
323
|
-
- lets the agent do bounded useful work without a human prompt
|
|
324
|
-
- checkpoints the new state
|
|
325
|
-
- returns a decision: `continue`, `pause`, `complete`, or `escalate`
|
|
123
|
+
More: [Programmatic use](docs/guides/programmatic-use.md)
|
|
326
124
|
|
|
327
|
-
|
|
125
|
+
## Why Someone Might Choose Heddle
|
|
328
126
|
|
|
329
|
-
|
|
127
|
+
Heddle is a good fit if you want:
|
|
330
128
|
|
|
331
|
-
|
|
129
|
+
- a terminal-first coding agent that works in a real repository
|
|
130
|
+
- local state and durable project memory
|
|
131
|
+
- explicit traces, approvals, and reviewable workflow artifacts
|
|
132
|
+
- a browser control plane for local oversight
|
|
133
|
+
- a path from interactive use to programmatic and scheduled agent workflows
|
|
332
134
|
|
|
333
|
-
|
|
135
|
+
Heddle is probably not the right fit if you only want a very simple one-shot chat wrapper and do not care about sessions, persistence, observability, or operator control.
|
|
334
136
|
|
|
335
|
-
|
|
336
|
-
- `runHeartbeatScheduler`: run the same scan loop until an `AbortSignal` stops it
|
|
337
|
-
- `createFileHeartbeatTaskStore`: store task definitions and checkpoints under `.heddle/heartbeat/`-style directories
|
|
338
|
-
|
|
339
|
-
Cron, launchd, systemd, hosted queues, and Lucid-style services should be treated as hosts around this API, not as Heddle's internal scheduler model.
|
|
137
|
+
## Install
|
|
340
138
|
|
|
341
|
-
|
|
139
|
+
Global install:
|
|
342
140
|
|
|
343
141
|
```bash
|
|
344
|
-
|
|
345
|
-
yarn example:heartbeat
|
|
142
|
+
npm install -g @roackb2/heddle
|
|
346
143
|
```
|
|
347
144
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
Try the local scheduler API with a real LLM:
|
|
145
|
+
Run without a global install:
|
|
351
146
|
|
|
352
147
|
```bash
|
|
353
|
-
|
|
354
|
-
yarn example:heartbeat-scheduler
|
|
148
|
+
npx @roackb2/heddle
|
|
355
149
|
```
|
|
356
150
|
|
|
357
|
-
The
|
|
151
|
+
The installed CLI command is `heddle`.
|
|
358
152
|
|
|
359
|
-
|
|
153
|
+
## Requirements
|
|
360
154
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
heddle heartbeat task show repo-gardener
|
|
366
|
-
heddle heartbeat run --once
|
|
367
|
-
heddle heartbeat run --poll 60s
|
|
368
|
-
heddle heartbeat runs list --task repo-gardener
|
|
369
|
-
heddle heartbeat runs show latest --task repo-gardener
|
|
370
|
-
```
|
|
155
|
+
- Node.js 20+
|
|
156
|
+
- an API key for at least one supported provider:
|
|
157
|
+
- `OPENAI_API_KEY`
|
|
158
|
+
- `ANTHROPIC_API_KEY`
|
|
371
159
|
|
|
372
|
-
|
|
160
|
+
## Quick Start
|
|
373
161
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
Inside this repository, use the dev CLI entrypoint instead:
|
|
162
|
+
1. Set a provider API key.
|
|
377
163
|
|
|
378
164
|
```bash
|
|
379
|
-
|
|
165
|
+
export OPENAI_API_KEY=your_key_here
|
|
166
|
+
# or
|
|
167
|
+
export ANTHROPIC_API_KEY=your_key_here
|
|
380
168
|
```
|
|
381
169
|
|
|
382
|
-
|
|
170
|
+
2. Move into the project you want Heddle to operate on.
|
|
383
171
|
|
|
384
172
|
```bash
|
|
385
|
-
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
For hosts that want storage handled by Heddle, use `runStoredHeartbeat` with a checkpoint store:
|
|
389
|
-
|
|
390
|
-
```ts
|
|
391
|
-
import { createFileHeartbeatCheckpointStore, runStoredHeartbeat } from '@roackb2/heddle'
|
|
392
|
-
|
|
393
|
-
const result = await runStoredHeartbeat({
|
|
394
|
-
task: 'Keep this project moving when safe autonomous progress is available',
|
|
395
|
-
store: createFileHeartbeatCheckpointStore({
|
|
396
|
-
path: '.heddle/heartbeat/project-maintenance.json',
|
|
397
|
-
}),
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
// result.nextDelayMs is a scheduling hint. The host still owns the timer,
|
|
401
|
-
// cron job, queue, worker, or hosted scheduler that wakes the agent again.
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
For hosts that want task scheduling handled by Heddle, use the scheduler API:
|
|
405
|
-
|
|
406
|
-
```ts
|
|
407
|
-
import { createFileHeartbeatTaskStore, runHeartbeatScheduler } from '@roackb2/heddle'
|
|
408
|
-
|
|
409
|
-
const controller = new AbortController()
|
|
410
|
-
|
|
411
|
-
await runHeartbeatScheduler({
|
|
412
|
-
store: createFileHeartbeatTaskStore({ dir: '.heddle/heartbeat' }),
|
|
413
|
-
pollIntervalMs: 60_000,
|
|
414
|
-
signal: controller.signal,
|
|
415
|
-
})
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
To read compact task/run state back out for dashboards or hosted controllers:
|
|
419
|
-
|
|
420
|
-
```ts
|
|
421
|
-
import {
|
|
422
|
-
createFileHeartbeatTaskStore,
|
|
423
|
-
listHeartbeatTaskViews,
|
|
424
|
-
listHeartbeatRunViews,
|
|
425
|
-
} from '@roackb2/heddle'
|
|
426
|
-
|
|
427
|
-
const store = createFileHeartbeatTaskStore({ dir: '.heddle/heartbeat' })
|
|
428
|
-
|
|
429
|
-
const tasks = await listHeartbeatTaskViews(store)
|
|
430
|
-
const runs = await listHeartbeatRunViews(store, { taskId: 'repo-gardener', limit: 5 })
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
Those views are intentionally smaller than full checkpoints or traces. They expose stable operator-facing fields such as task ID, status, progress, decision, outcome, resumability, usage, and latest summary.
|
|
434
|
-
|
|
435
|
-
## Programmatic Use
|
|
436
|
-
|
|
437
|
-
The npm package exports a programmatic execution loop for building other agent hosts on top of Heddle.
|
|
438
|
-
|
|
439
|
-
Use `runAgentLoop` when you want Heddle to assemble the model adapter, default tool bundle, memory tools, and event stream:
|
|
440
|
-
|
|
441
|
-
```ts
|
|
442
|
-
import { runAgentLoop } from '@roackb2/heddle'
|
|
443
|
-
|
|
444
|
-
const result = await runAgentLoop({
|
|
445
|
-
goal: 'Inspect this repo and summarize the main architecture',
|
|
446
|
-
model: 'gpt-5.1-codex',
|
|
447
|
-
workspaceRoot: process.cwd(),
|
|
448
|
-
onEvent(event) {
|
|
449
|
-
// Render progress, persist traces, feed middleware, or bridge into another app.
|
|
450
|
-
console.log(event.type)
|
|
451
|
-
},
|
|
452
|
-
})
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
Persist `result.state` or wrap it with `createAgentLoopCheckpoint(result.state)` when another host needs to continue later:
|
|
456
|
-
|
|
457
|
-
```ts
|
|
458
|
-
import { createAgentLoopCheckpoint, runAgentLoop } from '@roackb2/heddle'
|
|
459
|
-
|
|
460
|
-
const checkpoint = createAgentLoopCheckpoint(result.state)
|
|
461
|
-
|
|
462
|
-
await runAgentLoop({
|
|
463
|
-
goal: 'Continue from the prior run and identify the next action',
|
|
464
|
-
resumeFrom: checkpoint,
|
|
465
|
-
})
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
The loop emits structured events for:
|
|
469
|
-
|
|
470
|
-
- loop start and finish
|
|
471
|
-
- assistant streaming updates
|
|
472
|
-
- trace events such as tool calls, tool results, approvals, and final outcome
|
|
473
|
-
|
|
474
|
-
The returned result also includes a serializable `state` object with the model, provider, workspace root, outcome, transcript, trace, usage, and timestamps. This is the boundary future hosts can persist for background execution, dashboards, middleware, or heartbeat-style continuation.
|
|
475
|
-
|
|
476
|
-
For host UIs or controllers that do not want to understand Heddle's full trace/event model, the package also exports compact heartbeat views plus a thin status/progress/response adapter layer:
|
|
477
|
-
|
|
478
|
-
```ts
|
|
479
|
-
import {
|
|
480
|
-
createFileHeartbeatTaskStore,
|
|
481
|
-
heartbeatSchedulerEventToLucidMessages,
|
|
482
|
-
heartbeatTaskViewToLucidMessages,
|
|
483
|
-
listHeartbeatTaskViews,
|
|
484
|
-
} from '@roackb2/heddle'
|
|
485
|
-
|
|
486
|
-
const store = createFileHeartbeatTaskStore({ dir: '.heddle/heartbeat' })
|
|
487
|
-
const tasks = await listHeartbeatTaskViews(store)
|
|
488
|
-
|
|
489
|
-
for (const task of tasks) {
|
|
490
|
-
const messages = heartbeatTaskViewToLucidMessages(task)
|
|
491
|
-
console.log(messages)
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
const schedulerMessages = heartbeatSchedulerEventToLucidMessages({
|
|
495
|
-
type: 'heartbeat.task.started',
|
|
496
|
-
taskId: 'repo-gardener',
|
|
497
|
-
loadedCheckpoint: true,
|
|
498
|
-
status: 'running',
|
|
499
|
-
progress: 'Resuming heartbeat wake from the last checkpoint.',
|
|
500
|
-
timestamp: new Date().toISOString(),
|
|
501
|
-
})
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
The adapter names are Lucid-oriented because that is one target host, but the payload shape is generic: compact status, progress, and response messages that another app can publish over websockets, SSE, or logs.
|
|
505
|
-
|
|
506
|
-
For passive semantic-drift experiments, `createCyberLoopObserver` can consume Heddle's event stream and run CyberLoop-compatible middleware over normalized runtime frames:
|
|
507
|
-
|
|
508
|
-
```ts
|
|
509
|
-
import {
|
|
510
|
-
createCyberLoopObserver,
|
|
511
|
-
createRuntimeFrameEmbedder,
|
|
512
|
-
runAgentLoop,
|
|
513
|
-
} from '@roackb2/heddle'
|
|
514
|
-
import { kinematicsMiddleware } from 'cyberloop/advanced'
|
|
515
|
-
|
|
516
|
-
const frameEmbedder = createRuntimeFrameEmbedder({
|
|
517
|
-
async embedText(text) {
|
|
518
|
-
return embedWithYourProvider(text)
|
|
519
|
-
},
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
const observer = createCyberLoopObserver({
|
|
523
|
-
middleware: [
|
|
524
|
-
kinematicsMiddleware({
|
|
525
|
-
embedder: frameEmbedder,
|
|
526
|
-
goalEmbedding: await embedWithYourProvider('Investigate this repo'),
|
|
527
|
-
}),
|
|
528
|
-
],
|
|
529
|
-
onAnnotation(annotation) {
|
|
530
|
-
console.log(annotation.driftLevel, annotation.frame.kind)
|
|
531
|
-
},
|
|
532
|
-
})
|
|
533
|
-
|
|
534
|
-
await runAgentLoop({
|
|
535
|
-
goal: 'Investigate this repo',
|
|
536
|
-
onEvent: observer.handleEvent,
|
|
537
|
-
})
|
|
538
|
-
await observer.flush()
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
This is intentionally observe-only. Heddle still owns execution, tools, approvals, and checkpoints; CyberLoop-style middleware can annotate the run without steering or halting it. Heddle does not calculate semantic drift itself; actual drift signals should come from CyberLoop metadata such as kinematics, manifold, or Grassmannian channels.
|
|
542
|
-
|
|
543
|
-
For autonomous background work, `runAgentHeartbeat` runs one wake cycle from a durable task and optional checkpoint:
|
|
544
|
-
|
|
545
|
-
```ts
|
|
546
|
-
import { runAgentHeartbeat } from '@roackb2/heddle'
|
|
547
|
-
|
|
548
|
-
const heartbeat = await runAgentHeartbeat({
|
|
549
|
-
task: 'Check whether there is safe maintenance work to do for this project',
|
|
550
|
-
checkpoint,
|
|
551
|
-
maxSteps: 8,
|
|
552
|
-
})
|
|
553
|
-
|
|
554
|
-
// Persist heartbeat.checkpoint, then schedule the next wake based on heartbeat.decision.
|
|
173
|
+
cd /path/to/project
|
|
555
174
|
```
|
|
556
175
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
For repeated local or hosted wake cycles, `runDueHeartbeatTasks`, `runHeartbeatScheduler`, and `createFileHeartbeatTaskStore` provide the scheduler layer above one-shot heartbeat runs.
|
|
560
|
-
|
|
561
|
-
Lower-level pieces are still exported for custom hosts, including:
|
|
562
|
-
|
|
563
|
-
- `runAgent`
|
|
564
|
-
- `runAgentLoop`
|
|
565
|
-
- `runAgentHeartbeat`
|
|
566
|
-
- `runHeartbeatScheduler`
|
|
567
|
-
- `createFileHeartbeatTaskStore`
|
|
568
|
-
- `createDefaultAgentTools`
|
|
569
|
-
- LLM adapter helpers
|
|
570
|
-
- built-in tools
|
|
571
|
-
- trace utilities
|
|
572
|
-
|
|
573
|
-
Install as a dependency with:
|
|
176
|
+
3. Start interactive chat.
|
|
574
177
|
|
|
575
178
|
```bash
|
|
576
|
-
|
|
179
|
+
heddle
|
|
577
180
|
```
|
|
578
181
|
|
|
579
|
-
|
|
182
|
+
4. Ask for something concrete, for example:
|
|
580
183
|
|
|
581
|
-
```
|
|
582
|
-
|
|
184
|
+
```text
|
|
185
|
+
Summarize this repository and point out the main build and test commands.
|
|
583
186
|
```
|
|
584
187
|
|
|
585
|
-
|
|
188
|
+
5. If you want the browser oversight UI, run:
|
|
586
189
|
|
|
587
190
|
```bash
|
|
588
|
-
|
|
589
|
-
yarn example:programmatic
|
|
191
|
+
heddle daemon
|
|
590
192
|
```
|
|
591
193
|
|
|
592
|
-
|
|
194
|
+
By default, Heddle uses the current directory as the workspace root unless you pass `--cwd`.
|
|
593
195
|
|
|
594
|
-
|
|
595
|
-
export ANTHROPIC_API_KEY=your_key_here
|
|
596
|
-
HEDDLE_EXAMPLE_MODEL=claude-3-5-haiku-latest yarn example:programmatic
|
|
597
|
-
```
|
|
196
|
+
## Optional CyberLoop Integration
|
|
598
197
|
|
|
599
|
-
|
|
198
|
+
If you want semantic drift telemetry in chat, install `cyberloop` in the same environment as Heddle:
|
|
600
199
|
|
|
601
200
|
```bash
|
|
602
|
-
|
|
201
|
+
npm install -g cyberloop
|
|
202
|
+
# or for project-local usage
|
|
203
|
+
npm install cyberloop
|
|
603
204
|
```
|
|
604
205
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
## Capability Details
|
|
608
|
-
|
|
609
|
-
Heddle currently supports:
|
|
610
|
-
|
|
611
|
-
- repository inspection with `list_files`, `read_file`, and `search_files`
|
|
612
|
-
- code and doc changes with `edit_file`
|
|
613
|
-
- provider-backed hosted web search through `web_search`
|
|
614
|
-
- local screenshot and image inspection through `view_image`
|
|
615
|
-
- native browser control plane through `heddle daemon`
|
|
616
|
-
- inline `@file` mentions for file-priority context without pasting file contents into the prompt
|
|
617
|
-
- browser composer `@file` suggestions in the control plane, backed by workspace file search
|
|
618
|
-
- shell execution with inspect vs approval-gated mutate behavior
|
|
619
|
-
- multi-turn chat sessions with saved history under `.heddle/`
|
|
620
|
-
- session management with create, switch, continue, rename, and close flows
|
|
621
|
-
- automatic conversation compaction so longer chats preserve context instead of growing unbounded
|
|
622
|
-
- manual `/compact` to shrink the current session transcript on demand
|
|
623
|
-
- persistent workspace memory notes under `.heddle/memory/`
|
|
624
|
-
- serializable run checkpoints for programmatic hosts and later continuation
|
|
625
|
-
- short working-plan support through `update_plan` for substantial multi-step tasks
|
|
626
|
-
- remembered per-project approvals for repeated commands and edits
|
|
627
|
-
- interrupt and resume support for longer-running coding workflows
|
|
628
|
-
- request-size aware context tracking in chat so the footer reflects model input usage, not only raw history size
|
|
206
|
+
For one-off usage without a global install:
|
|
629
207
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
The file-mention workflow is also intentionally lightweight: `@path/to/file` tells Heddle that the file is important context and should be inspected before answering, but it does not automatically inline the file contents into the prompt.
|
|
633
|
-
|
|
634
|
-
The planning workflow is also intentionally lightweight: Heddle does not force a heavyweight planner or a separate "plan mode," but it can automatically record and update a short plan when a task is substantial enough to benefit from visible progress tracking.
|
|
635
|
-
|
|
636
|
-
The web-search workflow is provider-backed rather than crawler-backed: OpenAI models use OpenAI-hosted web search, and Anthropic models use Anthropic-hosted web search when available through the selected model/tool path.
|
|
637
|
-
|
|
638
|
-
## What Heddle Does
|
|
639
|
-
|
|
640
|
-
Heddle runs an agent loop against your workspace:
|
|
641
|
-
|
|
642
|
-
```text
|
|
643
|
-
goal
|
|
644
|
-
-> send transcript + tool definitions to the model
|
|
645
|
-
-> model answers or requests tool calls
|
|
646
|
-
-> execute tools in the workspace
|
|
647
|
-
-> append results to the transcript
|
|
648
|
-
-> continue until done / max steps / error
|
|
208
|
+
```bash
|
|
209
|
+
npx -p @roackb2/heddle -p cyberloop heddle
|
|
649
210
|
```
|
|
650
211
|
|
|
651
|
-
|
|
212
|
+
## Documentation
|
|
652
213
|
|
|
653
|
-
|
|
654
|
-
- minimal runtime behavior instead of a large framework surface
|
|
655
|
-
- traceability and operator control over hidden orchestration
|
|
214
|
+
### Start here
|
|
656
215
|
|
|
657
|
-
|
|
216
|
+
- [Documentation hub](docs/README.md)
|
|
217
|
+
- [Chat and sessions guide](docs/guides/chat-and-sessions.md)
|
|
218
|
+
- [CLI reference](docs/reference/cli.md)
|
|
658
219
|
|
|
659
|
-
|
|
220
|
+
### Feature guides
|
|
660
221
|
|
|
661
|
-
-
|
|
662
|
-
-
|
|
222
|
+
- [Control plane](docs/guides/control-plane.md)
|
|
223
|
+
- [Heartbeat](docs/guides/heartbeat.md)
|
|
224
|
+
- [Knowledge persistence](docs/guides/knowledge-persistence.md)
|
|
225
|
+
- [Semantic drift](docs/guides/semantic-drift.md)
|
|
226
|
+
- [Programmatic use](docs/guides/programmatic-use.md)
|
|
663
227
|
|
|
664
|
-
|
|
228
|
+
### Contributors
|
|
665
229
|
|
|
666
|
-
-
|
|
667
|
-
-
|
|
668
|
-
-
|
|
230
|
+
- [Development and contributing](docs/guides/development.md)
|
|
231
|
+
- [Framework Vision](docs/framework-vision.md)
|
|
232
|
+
- [Coding Agent Roadmap](docs/coding-agent-roadmap.md)
|
|
669
233
|
|
|
670
|
-
|
|
234
|
+
## Project Status
|
|
671
235
|
|
|
672
|
-
-
|
|
673
|
-
- Anthropic: `claude-sonnet-4-6`
|
|
236
|
+
Heddle is already useful for real coding-agent workflows, but it is still evolving.
|
|
674
237
|
|
|
675
|
-
|
|
238
|
+
Current strengths include:
|
|
676
239
|
|
|
677
|
-
-
|
|
678
|
-
-
|
|
679
|
-
-
|
|
680
|
-
-
|
|
681
|
-
-
|
|
682
|
-
- OpenAI coding models: `gpt-5.1-codex`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`
|
|
683
|
-
- Anthropic: `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-haiku-4-5`
|
|
684
|
-
- Anthropic: `claude-opus-4-1`, `claude-opus-4-0`, `claude-sonnet-4-0`
|
|
685
|
-
- Anthropic: `claude-3-7-sonnet-latest`
|
|
686
|
-
- Anthropic: `claude-3-5-sonnet-latest`, `claude-3-5-haiku-latest`
|
|
240
|
+
- terminal-first coding and repository workflows
|
|
241
|
+
- explicit traces, approvals, and local workspace state
|
|
242
|
+
- browser-based oversight through the control plane
|
|
243
|
+
- local-first heartbeat primitives for scheduled agent work
|
|
244
|
+
- practical programmatic hooks for custom hosts
|
|
687
245
|
|
|
688
|
-
|
|
246
|
+
Current limitations include:
|
|
689
247
|
|
|
690
|
-
-
|
|
691
|
-
-
|
|
692
|
-
-
|
|
248
|
+
- the browser control plane is still early compared with a full IDE-like environment
|
|
249
|
+
- some advanced workflows remain better documented in source and examples than in polished product UX
|
|
250
|
+
- the project surface is still changing as the runtime matures
|
|
693
251
|
|
|
694
|
-
##
|
|
252
|
+
## Development
|
|
695
253
|
|
|
696
|
-
|
|
254
|
+
If you want to work on Heddle itself:
|
|
697
255
|
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
"searchIgnoreDirs": [".git", "dist", "node_modules", ".heddle"],
|
|
705
|
-
"agentContextPaths": ["AGENTS.md"]
|
|
706
|
-
}
|
|
256
|
+
```bash
|
|
257
|
+
git clone https://github.com/roackb2/heddle.git
|
|
258
|
+
cd heddle
|
|
259
|
+
yarn install
|
|
260
|
+
yarn build
|
|
261
|
+
yarn test
|
|
707
262
|
```
|
|
708
263
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
- CLI flags override `heddle.config.json`
|
|
712
|
-
- `heddle.config.json` overrides environment-driven defaults
|
|
713
|
-
|
|
714
|
-
Field notes:
|
|
715
|
-
|
|
716
|
-
- `stateDir`: where traces, logs, approvals, and chat state are stored
|
|
717
|
-
- `directShellApproval`: whether explicit `!command` input in chat still asks for approval
|
|
718
|
-
- `searchIgnoreDirs`: directories excluded from `search_files`
|
|
719
|
-
- `agentContextPaths`: project instruction files injected into the system prompt
|
|
720
|
-
|
|
721
|
-
## Design Direction
|
|
722
|
-
|
|
723
|
-
Heddle is currently optimized for coding and terminal workflows, but the long-term goal is broader: an open, provider-agnostic runtime for tool-using agents in real working environments.
|
|
724
|
-
|
|
725
|
-
The current CLI is the proving ground, not the endpoint. The coding-agent workflow matters because it is a demanding, evidence-heavy environment with real files, shell tools, long-running context, and operator oversight. If the runtime holds up there, it can later support wider agentic workflows beyond software projects.
|
|
726
|
-
|
|
727
|
-
The design direction stays intentionally behavior-first:
|
|
728
|
-
|
|
729
|
-
- start from real agent loops, traces, approvals, and recovery behavior
|
|
730
|
-
- keep the current surface small until abstractions are justified by actual usage
|
|
731
|
-
- stay usable as a coding agent while growing toward a more general agent runtime
|
|
732
|
-
- support richer workspace tasks, not just code editing, whenever the environment already provides the right tools
|
|
733
|
-
|
|
734
|
-
More project context:
|
|
735
|
-
|
|
736
|
-
- [Framework Vision](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/framework-vision.md)
|
|
737
|
-
- [Project Purpose](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/project-purpose.md)
|
|
738
|
-
- [Coding Agent Roadmap](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/coding-agent-roadmap.md)
|
|
264
|
+
See [Development and contributing](docs/guides/development.md) for the fuller contributor workflow.
|
|
739
265
|
|
|
740
266
|
## License
|
|
741
267
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,YAAY,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oDAAoD,CAAC;AAE5F,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F;AAED,eAAO,MAAM,kBAAkB,2BAAqB,CAAC"}
|
package/dist/src/server/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
1
2
|
import { dirname, resolve } from 'node:path';
|
|
2
3
|
import { fileURLToPath } from 'node:url';
|
|
3
4
|
import { createHeddleServerApp } from './app.js';
|
|
@@ -38,6 +39,17 @@ function resolveDefaultAssetsDir() {
|
|
|
38
39
|
return resolve(process.env.HEDDLE_WEB_DIST);
|
|
39
40
|
}
|
|
40
41
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
41
|
-
|
|
42
|
+
const candidates = [
|
|
43
|
+
resolve(moduleDir, '../web'),
|
|
44
|
+
resolve(moduleDir, '../../web'),
|
|
45
|
+
resolve(moduleDir, '../../../src/web'),
|
|
46
|
+
];
|
|
47
|
+
for (const candidate of candidates) {
|
|
48
|
+
const indexPath = resolve(candidate, 'index.html');
|
|
49
|
+
if (existsSync(indexPath)) {
|
|
50
|
+
return candidate;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return candidates[0];
|
|
42
54
|
}
|
|
43
55
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAInD,OAAO,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oDAAoD,CAAC;AAE5F,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACzE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,uBAAuB,EAAE,CAAC;IACjE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,qBAAqB,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAErE,MAAM,IAAI,OAAO,CAAO,CAAC,aAAa,EAAE,YAAY,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE;YACzD,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS;aACV,EAAE,uBAAuB,CAAC,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;YAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;YAC7D,aAAa,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC7B,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAChD,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAErD,SAAS,uBAAuB;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED