@marcopeg/hal 1.0.16 → 1.0.18
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 +125 -33
- package/dist/bot/commands/clear.d.ts +0 -3
- package/dist/bot/commands/clear.d.ts.map +1 -1
- package/dist/bot/commands/clear.js +5 -4
- package/dist/bot/commands/clear.js.map +1 -1
- package/dist/bot/commands/help.d.ts +2 -1
- package/dist/bot/commands/help.d.ts.map +1 -1
- package/dist/bot/commands/help.js +10 -14
- package/dist/bot/commands/help.js.map +1 -1
- package/dist/bot/commands/loader.d.ts +1 -0
- package/dist/bot/commands/loader.d.ts.map +1 -1
- package/dist/bot/commands/loader.js +9 -3
- package/dist/bot/commands/loader.js.map +1 -1
- package/dist/bot/commands/message.d.ts +8 -0
- package/dist/bot/commands/message.d.ts.map +1 -0
- package/dist/bot/commands/message.js +65 -0
- package/dist/bot/commands/message.js.map +1 -0
- package/dist/bot/commands/reset.d.ts +4 -0
- package/dist/bot/commands/reset.d.ts.map +1 -0
- package/dist/bot/commands/reset.js +24 -0
- package/dist/bot/commands/reset.js.map +1 -0
- package/dist/bot/commands/session.d.ts +15 -5
- package/dist/bot/commands/session.d.ts.map +1 -1
- package/dist/bot/commands/session.js +63 -48
- package/dist/bot/commands/session.js.map +1 -1
- package/dist/bot/commands/start.d.ts +2 -1
- package/dist/bot/commands/start.d.ts.map +1 -1
- package/dist/bot/commands/start.js +20 -8
- package/dist/bot/commands/start.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +8 -10
- package/dist/bot.js.map +1 -1
- package/dist/config.d.ts +131 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +74 -2
- package/dist/config.js.map +1 -1
- package/dist/context/resolver.d.ts +6 -0
- package/dist/context/resolver.d.ts.map +1 -1
- package/dist/context/resolver.js +11 -0
- package/dist/context/resolver.js.map +1 -1
- package/dist/engine/adapters/copilot.js +1 -1
- package/dist/engine/adapters/copilot.js.map +1 -1
- package/dist/engine/types.d.ts +1 -1
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/user/setup.d.ts +2 -2
- package/dist/user/setup.js +2 -2
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/marcopeg/hal/main/images/hal.jpg" alt="HAL 9000" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">HAL</h1>
|
|
2
6
|
|
|
3
7
|
A Telegram bot that provides access to AI coding agents as a personal assistant. Run multiple engines (Claude Code, GitHub Copilot, and more) across multiple projects simultaneously, each with its own dedicated Telegram bot.
|
|
4
8
|
|
|
@@ -132,10 +136,10 @@ Every field is optional. Project entries are matched to base projects by `name`
|
|
|
132
136
|
|
|
133
137
|
Any string value in `hal.config.json` or `hal.config.local.json` (except inside `context` blocks — see [Context Injection](#context-injection)) can reference an environment variable with `${VAR_NAME}` syntax. Variables are resolved at boot time from the following sources in priority order (first match wins):
|
|
134
138
|
|
|
135
|
-
1.
|
|
136
|
-
2.
|
|
137
|
-
3.
|
|
138
|
-
4.
|
|
139
|
+
1. `{config-dir}/.env.local` _(gitignored)_
|
|
140
|
+
2. `{config-dir}/.env`
|
|
141
|
+
3. `{project-cwd}/.env.local` _(gitignored)_
|
|
142
|
+
4. `{project-cwd}/.env`
|
|
139
143
|
5. Shell environment (`process.env`)
|
|
140
144
|
|
|
141
145
|
```bash
|
|
@@ -237,8 +241,8 @@ export default async (context) => ({
|
|
|
237
241
|
})
|
|
238
242
|
```
|
|
239
243
|
|
|
240
|
-
- **Input**: fully-resolved `Record
|
|
241
|
-
- **Output**: a `Record
|
|
244
|
+
- **Input**: fully-resolved `Record\<string, string\>` context
|
|
245
|
+
- **Output**: a `Record\<string, string\>` — the final context passed to the engine
|
|
242
246
|
- If a hook throws, the bot logs the error and falls back to the pre-hook context
|
|
243
247
|
|
|
244
248
|
#### Prompt format
|
|
@@ -265,7 +269,7 @@ Default settings applied to all projects. Any setting defined in a project overr
|
|
|
265
269
|
| `globals.engine.command` | Override the CLI command path | _(engine name)_ |
|
|
266
270
|
| `globals.engine.model` | Override the AI model | _(engine default)_ |
|
|
267
271
|
| `globals.engine.session` | Use persistent sessions (`--resume` / `--continue`) | `true` |
|
|
268
|
-
| `globals.engine.sessionMsg` | Message sent when renewing session (e.g. `/
|
|
272
|
+
| `globals.engine.sessionMsg` | Message sent when renewing session (e.g. `/clean`) | `"hi!"` |
|
|
269
273
|
| `globals.logging.level` | Log level: `debug`, `info`, `warn`, `error` | `"info"` |
|
|
270
274
|
| `globals.logging.flow` | Write logs to terminal | `true` |
|
|
271
275
|
| `globals.logging.persist` | Write logs to file | `false` |
|
|
@@ -275,6 +279,7 @@ Default settings applied to all projects. Any setting defined in a project overr
|
|
|
275
279
|
| `globals.dataDir` | Default user data directory | _(see below)_ |
|
|
276
280
|
| `globals.transcription.model` | Whisper model for voice | `"base.en"` |
|
|
277
281
|
| `globals.transcription.showTranscription` | Show transcribed text | `true` |
|
|
282
|
+
| `globals.commands` | Default `/start`, `/help`, `/reset`, `/clean` messages for all projects | _(see [`commands`](#commands))_ |
|
|
278
283
|
|
|
279
284
|
### `projects[]`
|
|
280
285
|
|
|
@@ -295,6 +300,94 @@ Each project entry creates one Telegram bot connected to one directory.
|
|
|
295
300
|
| `transcription.showTranscription` | No | Override transcription display |
|
|
296
301
|
| `dataDir` | No | Override user data directory (see below) |
|
|
297
302
|
| `context` | No | Per-project context overrides (see [Context Injection](#context-injection)) |
|
|
303
|
+
| `commands` | No | Customize `/start`, `/help`, `/reset`, `/clean` messages (see [`commands`](#commands)) |
|
|
304
|
+
|
|
305
|
+
### `commands`
|
|
306
|
+
|
|
307
|
+
Customize the built-in `/start`, `/help`, `/reset`, and `/clean` command messages. Can be set under `globals` (shared default for all projects) or per project (overrides globals). Project-level settings take precedence.
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"globals": {
|
|
312
|
+
"commands": {
|
|
313
|
+
"start": {
|
|
314
|
+
"session": { "reset": true },
|
|
315
|
+
"message": { "text": "Welcome, ${bot.firstName}!" }
|
|
316
|
+
},
|
|
317
|
+
"help": {
|
|
318
|
+
"message": { "from": "./HELP.md" }
|
|
319
|
+
},
|
|
320
|
+
"reset": {
|
|
321
|
+
"message": { "text": "All user data wiped. Starting fresh." }
|
|
322
|
+
},
|
|
323
|
+
"clean": {
|
|
324
|
+
"message": { "text": "Session reset. Ready for a new conversation." }
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Each command supports a `message` object with exactly one of:
|
|
332
|
+
|
|
333
|
+
| Field | Description |
|
|
334
|
+
|-------|-------------|
|
|
335
|
+
| `message.text` | Inline message string |
|
|
336
|
+
| `message.from` | Path to a file (relative to project `cwd`) whose content is used as the message |
|
|
337
|
+
|
|
338
|
+
Setting both `text` and `from`, or neither, is a configuration error.
|
|
339
|
+
|
|
340
|
+
The `/start` command additionally supports `session.reset` (boolean, default `false`). When `true`, the session is reset after sending the welcome message (same effect as `/clean`).
|
|
341
|
+
|
|
342
|
+
The `/reset` command always wipes all user data (uploads, downloads, session) regardless of configuration — the custom message only changes what the user sees afterward.
|
|
343
|
+
|
|
344
|
+
The `/clean` command always resets the LLM session regardless of configuration — user files (uploads, downloads) are preserved. The custom message only changes what the user sees afterward.
|
|
345
|
+
|
|
346
|
+
**Defaults** (when no `commands` config is set):
|
|
347
|
+
|
|
348
|
+
| Command | Default message |
|
|
349
|
+
|---------|-----------------|
|
|
350
|
+
| `/start` | `Welcome to ${project.name}!` followed by the command list |
|
|
351
|
+
| `/help` | The command list |
|
|
352
|
+
| `/reset` | `All user data wiped and session reset. Your next message starts fresh.` |
|
|
353
|
+
| `/clean` | `Session reset. Your next message starts a new conversation.` |
|
|
354
|
+
|
|
355
|
+
Messages are sent with Telegram's legacy Markdown formatting. Supported syntax: `*bold*`, `_italic_`, `` `inline code` ``, ` ```code blocks``` `, `[link text](url)`.
|
|
356
|
+
|
|
357
|
+
#### Variable substitution in command messages
|
|
358
|
+
|
|
359
|
+
All `message.text` values and file contents from `message.from` support the same placeholder patterns used elsewhere:
|
|
360
|
+
|
|
361
|
+
| Pattern | Description |
|
|
362
|
+
|---------|-------------|
|
|
363
|
+
| `${varName}` | Implicit context (`bot.firstName`, `sys.date`, `project.name`, etc.) and env vars |
|
|
364
|
+
| `@{cmd}` | Message-time shell command |
|
|
365
|
+
|
|
366
|
+
Additionally, the special `${HAL_COMMANDS}` placeholder expands to a formatted list of all available commands, divided into three sections:
|
|
367
|
+
|
|
368
|
+
- **Commands** — built-in commands (`/start`, `/help`, `/reset`, `/clean`)
|
|
369
|
+
- **Custom Commands** — programmatic `.mjs` commands from global and project directories
|
|
370
|
+
- **Skills** — engine skills marked with `public: true` in their `SKILL.md` frontmatter
|
|
371
|
+
|
|
372
|
+
Example `WELCOME.md`:
|
|
373
|
+
|
|
374
|
+
```markdown
|
|
375
|
+
Welcome to ${project.name}, ${bot.firstName}!
|
|
376
|
+
|
|
377
|
+
${HAL_COMMANDS}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
#### Making skills visible in the command list
|
|
381
|
+
|
|
382
|
+
By default, skills are not listed in `${HAL_COMMANDS}`. Add `public: true` to a skill's frontmatter to include it:
|
|
383
|
+
|
|
384
|
+
```yaml
|
|
385
|
+
---
|
|
386
|
+
name: crm
|
|
387
|
+
description: Manage your contacts
|
|
388
|
+
public: true
|
|
389
|
+
---
|
|
390
|
+
```
|
|
298
391
|
|
|
299
392
|
### Project Slug
|
|
300
393
|
|
|
@@ -306,16 +399,16 @@ The slug is used as a folder name for log and data paths. It is derived from:
|
|
|
306
399
|
|
|
307
400
|
| Value | Resolved Path |
|
|
308
401
|
|-------|---------------|
|
|
309
|
-
| _(empty)_ |
|
|
310
|
-
| `~` |
|
|
311
|
-
| Relative path (e.g. `.mydata`) |
|
|
402
|
+
| _(empty)_ | `{project-cwd}/.hal/users` |
|
|
403
|
+
| `~` | `{config-dir}/.hal/{slug}/data` |
|
|
404
|
+
| Relative path (e.g. `.mydata`) | `{project-cwd}/{value}` |
|
|
312
405
|
| Absolute path | Used as-is |
|
|
313
406
|
|
|
314
407
|
### Log Files
|
|
315
408
|
|
|
316
409
|
When `logging.persist: true`, logs are written to:
|
|
317
410
|
```
|
|
318
|
-
|
|
411
|
+
{config-dir}/.hal/logs/{project-slug}/YYYY-MM-DD.txt
|
|
319
412
|
```
|
|
320
413
|
|
|
321
414
|
### Engine Configuration
|
|
@@ -362,28 +455,28 @@ The `engine` object supports five fields:
|
|
|
362
455
|
| `command` | Custom path to the CLI binary | _(engine name)_ |
|
|
363
456
|
| `model` | AI model override (omit to use the engine's default) | _(engine default)_ |
|
|
364
457
|
| `session` | Use persistent sessions (`--resume` / `--continue`) | `true` |
|
|
365
|
-
| `sessionMsg` | Message sent when renewing session (e.g. `/
|
|
458
|
+
| `sessionMsg` | Message sent when renewing session (e.g. `/clean`) | `"hi!"` |
|
|
366
459
|
|
|
367
460
|
#### Claude Code
|
|
368
461
|
|
|
369
462
|
- **CLI:** `claude` — install and authenticate via [Claude Code CLI](https://github.com/anthropics/claude-code) (see [Prerequisites](#prerequisites)).
|
|
370
463
|
- **Project files:** `CLAUDE.md`, `.claude/settings.json` (see [How It Works](#how-it-works)).
|
|
371
464
|
- **Config:** `engine.name: "claude"`. Optional: `engine.command`, `engine.model` (passed as `--model`), `engine.session`, `engine.sessionMsg`.
|
|
372
|
-
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `--resume
|
|
465
|
+
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `--resume {sessionId}`. `/clean` clears the stored session and replies with a static message (no engine call).
|
|
373
466
|
|
|
374
467
|
#### GitHub Copilot
|
|
375
468
|
|
|
376
469
|
- **CLI:** `copilot` — install and authenticate via [GitHub Copilot CLI](https://docs.github.com/en/copilot/concepts/agents/copilot-cli) (see [Prerequisites](#prerequisites)).
|
|
377
470
|
- **Project file:** `AGENTS.md`.
|
|
378
471
|
- **Config:** `engine.name: "copilot"`. Optional: `engine.command`, `engine.model` (see table below), `engine.session`, `engine.sessionMsg`.
|
|
379
|
-
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `--continue`. `/
|
|
472
|
+
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `--continue`. `/clean` sends `engine.sessionMsg` to the engine without `--continue` to start a fresh session; the engine’s reply is sent to the user.
|
|
380
473
|
|
|
381
474
|
#### Codex
|
|
382
475
|
|
|
383
476
|
- **CLI:** `codex` — install and authenticate via [Codex CLI](https://github.com/openai/codex-cli) (see [Prerequisites](#prerequisites)).
|
|
384
477
|
- **Project file:** `AGENTS.md`.
|
|
385
478
|
- **Config:** `engine.name: "codex"`. Optional: `engine.command`, `engine.model` (e.g. `gpt-5.1-codex-mini`), `engine.session`, `engine.sessionMsg`.
|
|
386
|
-
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `codex exec resume --last` to continue the most recent session; otherwise `codex exec` starts a fresh run. `/
|
|
479
|
+
- **Sessions:** When `engine.session` is `true`, the CLI is invoked with `codex exec resume --last` to continue the most recent session; otherwise `codex exec` starts a fresh run. `/clean` sends `engine.sessionMsg` without resuming, so the engine starts a new session; the engine's reply is sent to the user (same behaviour as Copilot).
|
|
387
480
|
|
|
388
481
|
#### GitHub Copilot Models
|
|
389
482
|
|
|
@@ -471,13 +564,12 @@ npx @marcopeg/hal --cwd ./workspace
|
|
|
471
564
|
|
|
472
565
|
## Bot Commands
|
|
473
566
|
|
|
474
|
-
| Command | Description
|
|
475
|
-
|
|
476
|
-
| `/start` | Welcome message
|
|
477
|
-
| `/help` | Show help information
|
|
478
|
-
| `/
|
|
479
|
-
| `/
|
|
480
|
-
| `/clean` | Start a new session |
|
|
567
|
+
| Command | Description |
|
|
568
|
+
|----------|-------------------------------------------------------|
|
|
569
|
+
| `/start` | Welcome message |
|
|
570
|
+
| `/help` | Show help information |
|
|
571
|
+
| `/reset` | Wipes out all user data and resets the LLM session |
|
|
572
|
+
| `/clean` | Resets the LLM session |
|
|
481
573
|
|
|
482
574
|
## Custom Commands
|
|
483
575
|
|
|
@@ -487,8 +579,8 @@ You can add your own slash commands as `.mjs` files. When a user sends `/mycomma
|
|
|
487
579
|
|
|
488
580
|
| Location | Scope |
|
|
489
581
|
|----------|-------|
|
|
490
|
-
| `{project.cwd}/.hal/commands
|
|
491
|
-
| `{configDir}/.hal/commands
|
|
582
|
+
| `{project.cwd}/.hal/commands/{name}.mjs` | Project-specific |
|
|
583
|
+
| `{configDir}/.hal/commands/{name}.mjs` | Global — available to all projects |
|
|
492
584
|
|
|
493
585
|
Project-specific commands take precedence over global ones on name collision.
|
|
494
586
|
|
|
@@ -517,7 +609,7 @@ Tokens following the command name, split on whitespace.
|
|
|
517
609
|
/status → args = []
|
|
518
610
|
```
|
|
519
611
|
|
|
520
|
-
#### `ctx: Record
|
|
612
|
+
#### `ctx: Record\<string, string\>`
|
|
521
613
|
|
|
522
614
|
The fully-resolved context that would be sent to the AI for this message — identical to what the engine sees in its `# Context` header. Includes all implicit keys plus any config vars and hook results:
|
|
523
615
|
|
|
@@ -570,7 +662,7 @@ interface Agent {
|
|
|
570
662
|
call(
|
|
571
663
|
prompt: string,
|
|
572
664
|
options?: { onProgress?: (message: string) => void }
|
|
573
|
-
): Promise
|
|
665
|
+
): Promise\<string\>;
|
|
574
666
|
}
|
|
575
667
|
```
|
|
576
668
|
|
|
@@ -580,7 +672,7 @@ Unlike regular user messages, agent calls have no session history and no context
|
|
|
580
672
|
|--------|------|-------------|
|
|
581
673
|
| `onProgress` | `(message: string) => void` | Called during execution with activity updates (e.g. `"Reading: /path/to/file"`). Use it to keep the user informed while the agent is working. |
|
|
582
674
|
|
|
583
|
-
Returns the agent's final text output as a string. Throws on failure — the bot's command error handler will catch it and reply with `Command failed:
|
|
675
|
+
Returns the agent's final text output as a string. Throws on failure — the bot's command error handler will catch it and reply with `Command failed: {message}`.
|
|
584
676
|
|
|
585
677
|
```js
|
|
586
678
|
export default async function({ args, gram, agent }) {
|
|
@@ -612,7 +704,7 @@ The project-level context object. Useful fields:
|
|
|
612
704
|
| `projectCtx.config.cwd` | `string` | Absolute path to the project directory |
|
|
613
705
|
| `projectCtx.config.configDir` | `string` | Absolute path to the directory containing `hal.config.json` |
|
|
614
706
|
| `projectCtx.config.dataDir` | `string` | Absolute path to user data storage root |
|
|
615
|
-
| `projectCtx.config.context` | `Record
|
|
707
|
+
| `projectCtx.config.context` | `Record\<string, string\> \| undefined` | Raw config-level context values (pre-hook) |
|
|
616
708
|
| `projectCtx.logger` | Pino logger | Structured logger — use for debug output that ends up in log files |
|
|
617
709
|
|
|
618
710
|
### Examples
|
|
@@ -626,7 +718,7 @@ The project-level context object. Useful fields:
|
|
|
626
718
|
[Claude Code skills](https://docs.anthropic.com/en/docs/claude-code/skills) live in `.claude/skills/` inside the project directory (shared across all engines). Each skill is a folder containing a `SKILL.md` file with a YAML frontmatter block and a prompt body:
|
|
627
719
|
|
|
628
720
|
```
|
|
629
|
-
|
|
721
|
+
{project-cwd}/
|
|
630
722
|
└── .claude/
|
|
631
723
|
└── skills/
|
|
632
724
|
└── chuck/
|
|
@@ -646,16 +738,16 @@ At boot time (and whenever `SKILL.md` files change) the bot reads every skill fo
|
|
|
646
738
|
|
|
647
739
|
When a user invokes a skill command (e.g. `/chuck`) the bot:
|
|
648
740
|
1. Reads the `SKILL.md` prompt body
|
|
649
|
-
2. Appends any user arguments as `User input:
|
|
741
|
+
2. Appends any user arguments as `User input: {args}` if present
|
|
650
742
|
3. Calls the AI engine with that prompt via the engine-agnostic `agent.call()` interface
|
|
651
743
|
4. Sends the response back to the user
|
|
652
744
|
|
|
653
|
-
Skills can be **overridden per-project**: create a `.hal/commands
|
|
745
|
+
Skills can be **overridden per-project**: create a `.hal/commands/{name}.mjs` file with the same name as the skill and the `.mjs` handler takes full precedence.
|
|
654
746
|
|
|
655
747
|
**Command precedence** (highest wins):
|
|
656
748
|
|
|
657
749
|
```
|
|
658
|
-
project .hal/commands
|
|
750
|
+
project .hal/commands/{name}.mjs > global .hal/commands/{name}.mjs > .claude/skills/{name}/
|
|
659
751
|
```
|
|
660
752
|
|
|
661
753
|
See [`examples/obsidian/.claude/skills/chuck/`](examples/obsidian/.claude/skills/chuck/SKILL.md) and [`examples/obsidian/.claude/skills/weather/`](examples/obsidian/.claude/skills/weather/SKILL.md) for example skills.
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { Context } from "grammy";
|
|
2
2
|
import type { ProjectContext } from "../../types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Returns a handler for the /clear command.
|
|
5
|
-
*/
|
|
6
3
|
export declare function createClearHandler(ctx: ProjectContext): (gramCtx: Context) => Promise<void>;
|
|
7
4
|
//# sourceMappingURL=clear.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/clear.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/clear.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,IACtC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAsB/C"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { clearUserData } from "../../user/setup.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
3
|
+
import { resolveCommandMessage } from "./message.js";
|
|
4
|
+
const DEFAULT_TEMPLATE = "Conversation history cleared. Your next message will start a fresh conversation.";
|
|
6
5
|
export function createClearHandler(ctx) {
|
|
7
6
|
return async (gramCtx) => {
|
|
8
7
|
const userId = gramCtx.from?.id;
|
|
@@ -13,7 +12,9 @@ export function createClearHandler(ctx) {
|
|
|
13
12
|
const userDir = join(ctx.config.dataDir, String(userId));
|
|
14
13
|
try {
|
|
15
14
|
await clearUserData(userDir);
|
|
16
|
-
|
|
15
|
+
const template = ctx.config.commands.clear?.message ?? DEFAULT_TEMPLATE;
|
|
16
|
+
const message = await resolveCommandMessage(template, ctx, gramCtx);
|
|
17
|
+
await gramCtx.reply(message, { parse_mode: "Markdown" });
|
|
17
18
|
}
|
|
18
19
|
catch (_error) {
|
|
19
20
|
await gramCtx.reply("Failed to clear conversation history. Please try again.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/bot/commands/clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/bot/commands/clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,gBAAgB,GACpB,kFAAkF,CAAC;AAErF,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,OAAO,KAAK,EAAE,OAAgB,EAAiB,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAEhC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;YAE7B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,MAAM,OAAO,CAAC,KAAK,CACjB,yDAAyD,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Context } from "grammy";
|
|
2
|
-
|
|
2
|
+
import type { ProjectContext } from "../../types.js";
|
|
3
|
+
export declare function createHelpHandler(ctx: ProjectContext): (gramCtx: Context) => Promise<void>;
|
|
3
4
|
//# sourceMappingURL=help.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,IACrC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAO/C"}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`Use /clear to start a fresh conversation.\n\n` +
|
|
12
|
-
`*Configuration:*\n` +
|
|
13
|
-
`Claude reads configuration from your .claude folder.\n` +
|
|
14
|
-
`Edit CLAUDE.md for system prompts and .claude/settings.json for permissions.`, { parse_mode: "Markdown" });
|
|
1
|
+
import { resolveCommandMessage } from "./message.js";
|
|
2
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: HAL placeholder syntax, not JS template
|
|
3
|
+
const DEFAULT_TEMPLATE = "${HAL_COMMANDS}";
|
|
4
|
+
export function createHelpHandler(ctx) {
|
|
5
|
+
return async (gramCtx) => {
|
|
6
|
+
const helpCfg = ctx.config.commands.help;
|
|
7
|
+
const template = helpCfg?.message ?? DEFAULT_TEMPLATE;
|
|
8
|
+
const message = await resolveCommandMessage(template, ctx, gramCtx);
|
|
9
|
+
await gramCtx.reply(message, { parse_mode: "Markdown" });
|
|
10
|
+
};
|
|
15
11
|
}
|
|
16
12
|
//# sourceMappingURL=help.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/bot/commands/help.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/bot/commands/help.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,gGAAgG;AAChG,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAE3C,MAAM,UAAU,iBAAiB,CAAC,GAAmB;IACnD,OAAO,KAAK,EAAE,OAAgB,EAAiB,EAAE;QAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAEzC,MAAM,QAAQ,GAAG,OAAO,EAAE,OAAO,IAAI,gBAAgB,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAmOD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAAY,EAS1C,CAAC;AAIF;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BzB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,IAAI,CAAC,MAAM,GAClB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA4B9B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf"}
|
|
@@ -92,6 +92,7 @@ async function parseSkillMd(filePath, logger) {
|
|
|
92
92
|
const prompt = match[2].trim();
|
|
93
93
|
const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
|
|
94
94
|
const descMatch = frontmatter.match(/^description:\s*(.+)$/m);
|
|
95
|
+
const publicMatch = frontmatter.match(/^public:\s*(.+)$/m);
|
|
95
96
|
if (!nameMatch || !descMatch) {
|
|
96
97
|
logger.warn({ filePath }, "SKILL.md frontmatter missing name or description — skipping");
|
|
97
98
|
return null;
|
|
@@ -100,6 +101,7 @@ async function parseSkillMd(filePath, logger) {
|
|
|
100
101
|
name: nameMatch[1].trim(),
|
|
101
102
|
description: descMatch[1].trim(),
|
|
102
103
|
prompt,
|
|
104
|
+
public: publicMatch?.[1].trim().toLowerCase() === "true",
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
107
|
/**
|
|
@@ -144,6 +146,7 @@ async function scanSkillsDir(dir, logger) {
|
|
|
144
146
|
description: parsed.description,
|
|
145
147
|
filePath: "",
|
|
146
148
|
skillPrompt: parsed.prompt,
|
|
149
|
+
public: parsed.public,
|
|
147
150
|
});
|
|
148
151
|
}
|
|
149
152
|
return skills;
|
|
@@ -156,9 +159,12 @@ async function scanSkillsDir(dir, logger) {
|
|
|
156
159
|
export const BUILTIN_COMMANDS = [
|
|
157
160
|
{ command: "start", description: "Welcome message", filePath: "" },
|
|
158
161
|
{ command: "help", description: "Show help", filePath: "" },
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
+
{
|
|
163
|
+
command: "reset",
|
|
164
|
+
description: "Wipes out all user data and resets the LLM session",
|
|
165
|
+
filePath: "",
|
|
166
|
+
},
|
|
167
|
+
{ command: "clean", description: "Resets the LLM session", filePath: "" },
|
|
162
168
|
];
|
|
163
169
|
// ─── Public API ──────────────────────────────────────────────────────────────
|
|
164
170
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/bot/commands/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/bot/commands/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context } from "grammy";
|
|
2
|
+
import type { ProjectContext } from "../../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a message template with context variable substitution and
|
|
5
|
+
* the HAL_COMMANDS placeholder. Shared by /start, /help, /reset, and /clean.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveCommandMessage(template: string, ctx: ProjectContext, gramCtx: Context): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA6DrD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { resolveContext, substituteMessage } from "../../context/resolver.js";
|
|
2
|
+
import { BUILTIN_COMMANDS, loadCommands } from "./loader.js";
|
|
3
|
+
const BUILTIN_NAMES = new Set(BUILTIN_COMMANDS.map((c) => c.command));
|
|
4
|
+
function escapeMarkdown(text) {
|
|
5
|
+
return text.replace(/[_*`[]/g, "\\$&").replace(/@/g, "@\u200B");
|
|
6
|
+
}
|
|
7
|
+
function formatCommandList(entries) {
|
|
8
|
+
return entries
|
|
9
|
+
.map((e) => `• /${escapeMarkdown(e.command)} — ${escapeMarkdown(e.description)}`)
|
|
10
|
+
.join("\n");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build the HAL_COMMANDS formatted string divided into 3 sections:
|
|
14
|
+
* built-in commands, programmatic (.mjs) commands, and public skill commands.
|
|
15
|
+
*/
|
|
16
|
+
async function buildHalCommands(ctx) {
|
|
17
|
+
const { config, logger, engine } = ctx;
|
|
18
|
+
const skillsDir = engine.skillsDir(config.cwd);
|
|
19
|
+
const all = await loadCommands(config.cwd, config.configDir, logger, skillsDir);
|
|
20
|
+
const builtins = [];
|
|
21
|
+
const programmatic = [];
|
|
22
|
+
const skills = [];
|
|
23
|
+
for (const entry of all) {
|
|
24
|
+
if (BUILTIN_NAMES.has(entry.command)) {
|
|
25
|
+
builtins.push(entry);
|
|
26
|
+
}
|
|
27
|
+
else if (entry.skillPrompt && entry.public) {
|
|
28
|
+
skills.push(entry);
|
|
29
|
+
}
|
|
30
|
+
else if (!entry.skillPrompt) {
|
|
31
|
+
programmatic.push(entry);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const sections = [];
|
|
35
|
+
if (builtins.length > 0) {
|
|
36
|
+
sections.push(`*Commands:*\n${formatCommandList(builtins)}`);
|
|
37
|
+
}
|
|
38
|
+
if (programmatic.length > 0) {
|
|
39
|
+
sections.push(`*Custom Commands:*\n${formatCommandList(programmatic)}`);
|
|
40
|
+
}
|
|
41
|
+
if (skills.length > 0) {
|
|
42
|
+
sections.push(`*Skills:*\n${formatCommandList(skills)}`);
|
|
43
|
+
}
|
|
44
|
+
return sections.join("\n\n");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a message template with context variable substitution and
|
|
48
|
+
* the HAL_COMMANDS placeholder. Shared by /start, /help, /reset, and /clean.
|
|
49
|
+
*/
|
|
50
|
+
export async function resolveCommandMessage(template, ctx, gramCtx) {
|
|
51
|
+
const { config, logger, bootContext } = ctx;
|
|
52
|
+
const vars = await resolveContext({
|
|
53
|
+
gramCtx,
|
|
54
|
+
configContext: config.context,
|
|
55
|
+
bootContext,
|
|
56
|
+
configDir: config.configDir,
|
|
57
|
+
projectCwd: config.cwd,
|
|
58
|
+
projectName: config.name,
|
|
59
|
+
projectSlug: config.slug,
|
|
60
|
+
logger,
|
|
61
|
+
});
|
|
62
|
+
vars.HAL_COMMANDS = await buildHalCommands(ctx);
|
|
63
|
+
return substituteMessage(template, vars, logger);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/bot/commands/message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/reset.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,IACtC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAoB/C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { clearUserData } from "../../user/setup.js";
|
|
3
|
+
import { resolveCommandMessage } from "./message.js";
|
|
4
|
+
const DEFAULT_TEMPLATE = "All user data wiped and session reset. Your next message starts fresh.";
|
|
5
|
+
export function createResetHandler(ctx) {
|
|
6
|
+
return async (gramCtx) => {
|
|
7
|
+
const userId = gramCtx.from?.id;
|
|
8
|
+
if (!userId) {
|
|
9
|
+
await gramCtx.reply("Could not identify user.");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const userDir = join(ctx.config.dataDir, String(userId));
|
|
13
|
+
try {
|
|
14
|
+
await clearUserData(userDir);
|
|
15
|
+
const template = ctx.config.commands.reset?.message ?? DEFAULT_TEMPLATE;
|
|
16
|
+
const message = await resolveCommandMessage(template, ctx, gramCtx);
|
|
17
|
+
await gramCtx.reply(message, { parse_mode: "Markdown" });
|
|
18
|
+
}
|
|
19
|
+
catch (_error) {
|
|
20
|
+
await gramCtx.reply("Failed to reset. Please try again.");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=reset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/bot/commands/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,gBAAgB,GACpB,wEAAwE,CAAC;AAE3E,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,OAAO,KAAK,EAAE,OAAgB,EAAiB,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAEhC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;YAE7B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,MAAM,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|