clawmini 0.0.1 → 0.0.2

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.
Files changed (56) hide show
  1. package/README.md +60 -77
  2. package/dist/adapter-discord/index.mjs +2 -2
  3. package/dist/{chats-Zd_HXDHx.mjs → chats-BcbxvPlj.mjs} +2 -2
  4. package/dist/{chats-Zd_HXDHx.mjs.map → chats-BcbxvPlj.mjs.map} +1 -1
  5. package/dist/{chats-DKgTeU7i.mjs → chats-CpRQrNHj.mjs} +2 -2
  6. package/dist/{chats-DKgTeU7i.mjs.map → chats-CpRQrNHj.mjs.map} +1 -1
  7. package/dist/cli/index.mjs +4 -3
  8. package/dist/cli/index.mjs.map +1 -1
  9. package/dist/cli/lite.mjs +48 -0
  10. package/dist/cli/lite.mjs.map +1 -1
  11. package/dist/daemon/index.mjs +311 -19
  12. package/dist/daemon/index.mjs.map +1 -1
  13. package/dist/{lite-Dl7WXyaH.mjs → lite-DBUuHsX0.mjs} +2 -2
  14. package/dist/{lite-Dl7WXyaH.mjs.map → lite-DBUuHsX0.mjs.map} +1 -1
  15. package/dist/policy-utils-BvfOK6Ih.mjs +114 -0
  16. package/dist/policy-utils-BvfOK6Ih.mjs.map +1 -0
  17. package/dist/web/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
  18. package/dist/web/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
  19. package/dist/web/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
  20. package/dist/web/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
  21. package/dist/web/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
  22. package/dist/web/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
  23. package/dist/web/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
  24. package/dist/web/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
  25. package/dist/web/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
  26. package/dist/web/_app/version.json +1 -1
  27. package/dist/web/index.html +6 -6
  28. package/dist/{workspace-CSgfo_2J.mjs → workspace-BC1ahx4R.mjs} +13 -2
  29. package/dist/workspace-BC1ahx4R.mjs.map +1 -0
  30. package/docs/CLI_REFERENCE.md +35 -0
  31. package/docs/guides/sandbox_policies.md +12 -5
  32. package/package.json +1 -1
  33. package/web/.svelte-kit/ambient.d.ts +2 -6
  34. package/web/.svelte-kit/generated/server/internal.js +1 -1
  35. package/web/.svelte-kit/output/client/.vite/manifest.json +25 -25
  36. package/web/.svelte-kit/output/client/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
  37. package/web/.svelte-kit/output/client/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
  38. package/web/.svelte-kit/output/client/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
  39. package/web/.svelte-kit/output/client/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
  40. package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
  41. package/web/.svelte-kit/output/client/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
  42. package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
  43. package/web/.svelte-kit/output/client/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
  44. package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
  45. package/web/.svelte-kit/output/client/_app/version.json +1 -1
  46. package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
  47. package/web/.svelte-kit/output/server/manifest-full.js +1 -1
  48. package/web/.svelte-kit/output/server/manifest.js +1 -1
  49. package/web/.svelte-kit/output/server/nodes/0.js +1 -1
  50. package/web/.svelte-kit/output/server/nodes/1.js +1 -1
  51. package/web/.svelte-kit/output/server/nodes/3.js +1 -1
  52. package/web/.svelte-kit/output/server/nodes/4.js +1 -1
  53. package/web/.svelte-kit/output/server/nodes/5.js +1 -1
  54. package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +0 -1
  55. package/dist/workspace-CSgfo_2J.mjs.map +0 -1
  56. package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +0 -1
package/README.md CHANGED
@@ -1,98 +1,91 @@
1
1
  # Clawmini
2
2
 
3
- Clawmini is an orchestration layer for command-line AI agents, providing a unified chat experience that can span multiple conversations and multiple agents. Ultimately, it aims to deliver a personal assistant experience built entirely on top of your local tools and agents.
3
+ **The secure, local-first orchestrator for your AI agents.**
4
4
 
5
- ## Features
5
+ Clawmini gives you the power of a proactive personal AI assistant, without compromising your system's security. Unlike other local agents that run with unrestricted access to your machine, Clawmini is built from the ground up with **sandboxing**, **human-in-the-loop approvals**, and **strict network isolation**.
6
6
 
7
- - **Persistent, Multi-Agent Chat Sessions:** Maintain separate chats for different tasks, allowing you to converse with multiple agents across multiple conversations.
8
- - **Safe Concurrency:** Automatically manages state and handles race conditions, queuing background commands safely to prevent file lock issues.
9
- - **Built-in & Bring-Your-Own UI:** Includes a fast, beautifully designed SvelteKit Web UI to visually manage agents, chats, and monitor real-time execution. Alternatively, easily build and connect your own interfaces to its local API.
10
- - **Agent Templates:** Quickly scaffold new agents using built-in or custom templates (e.g. `gemini`), automatically merging configuration settings.
11
- - **Routers & Middleware Pipeline:** Process user messages through an extensible pipeline to dynamically alter content, target specific agents or sessions, and expand slash commands before they reach an agent.
12
- - **Local File System Storage:** Everything is stored completely locally in `.clawmini/` within your workspace as transparent JSON/JSONL files. No cloud syncing required.
13
- - **Sandboxed Agent API:** The daemon can optionally expose a secure HTTP server configured via the `api` setting in `.clawmini/settings.json`, allowing remote or containerized access. Give agents a minimal zero-dependency standalone client exported via `clawmini export-lite`. It securely authenticates with the Agent API using dynamically generated HMAC tokens (`CLAW_API_TOKEN`) to allow sandboxed agents to log messages and manage cron jobs without needing direct access to the host's Unix socket.
14
- - **Proactivity:** Incoming messages or events from various external sources can be proactively routed back to the user or directly to the agent for autonomous handling.
7
+ Bring your favorite CLI agents (Gemini CLI, Claude Code, OpenAI Codex, etc.), and Clawmini provides the memory, the chat support, and the security boundaries.
15
8
 
16
- ### Coming Soon
9
+ ## Why Clawmini?
17
10
 
18
- - **Human Approval Requests:** When an agent needs permission to execute a sensitive action or requires input, it will pause and ask the user for approval via a dedicated UI or dashboard.
11
+ 🛡️ **Zero-Trust Security by Default**
12
+ Run agents safely. Clawmini uses built-in sandboxing (macOS seatbelt or containerized environments) to restrict what your AI can touch. Sensitive actions require your explicit approval before execution.
19
13
 
20
- ## Quick Start
14
+ 🧠 **Persistent Memory & Proactivity**
15
+ Your agents don't just react; they act. Clawmini allows agents to schedule recurring tasks (cron jobs), maintain long-term context across sessions, and proactively notify you of updates or route messages from external sources.
21
16
 
22
- Assuming you have built and linked the package globally:
17
+ 💻 **Beautiful Web UI & Chat App Extensibility**
18
+ No need to stay in the terminal. Manage your agents and chat with them through a fast, built-in Web interface running entirely on `localhost`. Hook up Discord to chat on-the-go, or easily build your adapters against the local API.
23
19
 
24
- ```bash
25
- # Initialize a new .clawmini settings folder, create an agent named 'coder' with the 'gemini-cladding' template, and set it as the default chat
26
- clawmini init --agent coder --agent-template gemini-cladding
27
-
28
- # Start the local web interface on http://localhost:8080
29
- clawmini web
30
- ```
20
+ 🔌 **Bring Your Own Agent**
21
+ Clawmini isn't tied to one model. It orchestrates _any_ CLI-based agent, acting as the secure bridge between the AI and your filesystem.
31
22
 
32
- ## Command Reference
23
+ ## Quick Start: Meet Jeeves
33
24
 
34
- ### Initialization & Daemon
25
+ Let's set up a secure, sandboxed agent named Jeeves using the Gemini CLI template.
35
26
 
36
- - `clawmini init`: Initialize a new `.clawmini` configuration folder.
37
- - `clawmini up`: Start the local daemon server in the background.
38
- - `clawmini down`: Stop the local daemon server.
39
- - `clawmini export-lite [--out <path>] [--stdout]`: Export the standalone `clawmini-lite` client script for use in sandboxed environments.
27
+ ```bash
28
+ # 1. Install globally
29
+ npm install -g clawmini
40
30
 
41
- ### Chat Management
31
+ # 2. Initialize a workspace and create your first sandboxed agent
32
+ # For a more OpenClaw-like experience, try the gemini-claw template
33
+ mkdir my-workspace && cd my-workspace
34
+ clawmini init --agent jeeves --agent-template gemini --environment macos
42
35
 
43
- - `clawmini chats list`: Display all existing chats in the workspace.
44
- - `clawmini chats add <id>`: Create a new chat with the specified identifier.
45
- - `clawmini chats delete <id>`: Remove a chat and its associated history.
46
- - `clawmini chats set-default <id>`: Update the globally configured default chat for the workspace.
36
+ # 3. Start the background daemon
37
+ clawmini up
47
38
 
48
- ### Messaging
39
+ # 4. Open the Web UI to start chatting!
40
+ clawmini web
41
+ ```
49
42
 
50
- - `clawmini messages send <message> [--chat <id>] [--agent <name>]`: Send a message to a specific chat (defaults to the workspace default chat). Use `--agent` to assign a specific agent to handle the message.
51
- - `clawmini messages tail [-n NUM] [--json] [--chat <id>]`: Display the most recent messages and command logs in a chat.
43
+ **Try asking Jeeves:** _"Summarize the recent changes in my git repository."_ Jeeves will run securely in its sandbox, read the diffs, and report back.
52
44
 
53
- ### Agents
45
+ ### Common Slash Commands
54
46
 
55
- - `clawmini agents list`: Display all existing agents.
56
- - `clawmini agents add <id> [-d, --directory <dir>] [-t, --template <name>] [-e, --env <KEY=VALUE>...]`: Create a new agent, optionally setting its working directory, applying a template, and environment variables.
57
- - `clawmini agents update <id> [-d, --directory <dir>] [-e, --env <KEY=VALUE>...]`: Update an existing agent's configuration.
58
- - `clawmini agents delete <id>`: Remove an agent.
47
+ You can use these built-in slash commands in your chat interfaces:
59
48
 
60
- ### Cron Jobs
49
+ - `/new`: Clear previous context and start a new conversation thread.
50
+ - `/stop`: Stop all running commands and drop any queued messages.
51
+ - `/interrupt [message]`: Interrupt the current thinking, batching together all queued messages and sending them immediately.
52
+ - `/pending`: View any pending permission requests from your agent.
53
+ - `/approve [id]`: Approve a specific pending agent request.
54
+ - `/reject [id]`: Reject a specific pending agent request.
61
55
 
62
- - `clawmini cron list [--chat <id>]`: Display all cron jobs configured for a chat.
63
- - `clawmini cron add <name> [--cron <expr> | --every <duration> | --at <iso-time>] [-m, --message <text>]`: Create a new scheduled job. Supports standard cron expressions, recurring intervals (e.g., `10m`), or one-off executions at a specific time.
64
- - `clawmini cron delete <name> [--chat <id>]`: Remove an existing scheduled job.
56
+ ### Guides & Integrations
65
57
 
66
- ### Web Interface
58
+ - [Discord Integration Setup](./docs/guides/discord_adapter_setup.md)
59
+ - [Configuring Permission Requests](./docs/guides/sandbox_policies.md)
67
60
 
68
- - `clawmini web [-p, --port <number>]`: Start the local web interface (default port: 8080).
61
+ ## How It Works
69
62
 
70
- ## Configuration
63
+ **User** ↔️ **Web UI / CLI** ↔️ **Daemon** ↔️ **Sandbox / Environment** ↔️ **Agent**
71
64
 
72
- ## Global settings
65
+ The daemon securely authenticates with the Agent API using dynamically generated HMAC tokens (`CLAW_API_TOKEN`), allowing sandboxed agents to operate safely without direct access to the host's Unix socket.
73
66
 
74
- **TODO**
67
+ ### Built-in Environments
75
68
 
76
- ## Routers
69
+ - `cladding` (most secure): A container-based sandbox using [cladding](https://github.com/dstoc/cladding)
70
+ - `macos`: A macOS sandbox environment that restricts write-access to the workspace.
71
+ - `macos-proxy`: A more constrained macOS sandbox that limits network access to an allowlist.
77
72
 
78
- Clawmini provides an extensible pipeline for processing user messages before they reach an agent using **Routers**. By defining a sequence of routers in your `.clawmini/settings.json` (global) or per-chat settings, you can dynamically alter message content, target specific agents or sessions, inject environment variables, and add automated replies.
73
+ ### Extensible Pipeline (Routers)
79
74
 
80
- Built-in routers include:
75
+ Process user messages before they reach an agent. Dynamically alter content, target specific agents, or expand slash commands (e.g., `/new` to clear context, `/foo` to expand a command script).
81
76
 
82
- - `@clawmini/slash-new`: Creates a new session ID when a message starts with `/new`, effectively clearing the context window for the agent.
83
- - `@clawmini/slash-command`: Expands slash commands (e.g., `/foo`) with the contents of matching files in your `.clawmini/commands/` directory.
77
+ ## Next Steps: Build Autonomous Workflows
84
78
 
85
- You can also write custom shell script routers that accept the current state via `stdin` and output JSON to dynamically control the routing logic. See the [`RouterState` interface](src/daemon/routers/types.ts) for the exact input and output schema.
79
+ Once you're comfortable, Clawmini offers powerful tools for advanced users:
86
80
 
87
- ## Agent Templates
81
+ - **The `gemini-claw` Template:** Scaffold a complete autonomous assistant with built-in memory management (`MEMORY.md`), identity (`SOUL.md`), and heartbeat checks (`HEARTBEAT.md`) for proactive tasking.
82
+ - **`clawmini-lite`:** Deploy agents into heavily restricted containers. Export the minimal, zero-dependency client (`clawmini export-lite`) to securely authenticate with the daemon, allowing the agent to log actions and request permissions without host access.
88
83
 
89
- Clawmini provides built-in templates to help you quickly scaffold new agents with pre-configured settings and files. When you run `clawmini agents add <id> --template <name>`, it copies the template's files into the agent's working directory and merges any provided environment variables or directory options with the template's `settings.json`.
84
+ ---
90
85
 
91
- The currently available built-in templates are:
86
+ ## Documentation & References
92
87
 
93
- - `gemini`: A basic template configured to use the `gemini` CLI as the agent's backend.
94
- - `gemini-cladding`: A template configured to run the `gemini` CLI wrapped inside `cladding` for enhanced security.
95
- - `gemini-claw-cladding`: A comprehensive template that sets up an autonomous personal assistant workspace (OpenClaw). It includes the `gemini-cladding` setup plus a full suite of scaffolding files like `GEMINI.md`, `SOUL.md`, `MEMORY.md`, and `HEARTBEAT.md` to establish the agent's identity, memory, and proactive capabilities.
88
+ For a full list of commands for managing chats, messages, agents, background jobs, and environments, please see the [CLI Command Reference](./docs/CLI_REFERENCE.md).
96
89
 
97
90
  ## Development Setup
98
91
 
@@ -103,35 +96,25 @@ Clawmini is a monorepo consisting of a Node.js TypeScript CLI/Daemon and an embe
103
96
  - Node.js (v18+)
104
97
  - npm
105
98
 
106
- ### Setup
99
+ ### Setup & Scripts
107
100
 
108
101
  ```bash
109
- # Install dependencies for both the root CLI and the web workspace
102
+ # Install dependencies and build the project
110
103
  npm install
111
-
112
- # Build the CLI, Daemon, and statically compile the Web UI
113
104
  npm run build
114
- ```
115
-
116
- ### Development Scripts
117
105
 
118
- During development, you can run the following commands from the root:
119
-
120
- ```bash
121
- # Watch mode for the CLI
106
+ # Development Watch Modes
122
107
  npm run dev:cli
123
-
124
- # Watch mode for the Daemon
125
108
  npm run dev:daemon
126
109
 
127
- # Run formatting, linting, type-checking, and tests
110
+ # Linting & Testing
128
111
  npm run format
129
112
  npm run lint
130
113
  npm run check
131
114
  npm run test
132
115
  ```
133
116
 
134
- ## Architecture Notes
117
+ **Architecture Notes:**
135
118
 
136
119
  - **Separation of Concerns:** The daemon (`src/daemon`) acts as the stateful orchestrator and queue manager, while the CLI (`src/cli`) is simply a thin TRPC client connecting via a UNIX socket.
137
- - **Web UI:** The `web/` directory is a SvelteKit application built with `@sveltejs/adapter-static`. Running `npm run build` bundles the web UI into `dist/web`, which is then served statically by the `clawmini web` Node.js server. Real-time updates to the web UI are powered by Server-Sent Events (SSE) tailing the local `.clawmini/chats/:id/chat.jsonl` files.
120
+ - **Web UI:** The `web/` directory is a SvelteKit application built with `@sveltejs/adapter-static`. Running `npm run build` bundles the web UI into `dist/web`, which is served statically by the `clawmini web` Node.js server. Real-time updates use Server-Sent Events (SSE) tailing local `.clawmini/chats/:id/chat.jsonl` files.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { l as getSocketPath, o as getClawminiDir, u as getWorkspaceRoot } from "../workspace-CSgfo_2J.mjs";
2
+ import { l as getSocketPath, o as getClawminiDir, u as getWorkspaceRoot } from "../workspace-BC1ahx4R.mjs";
3
3
  import { t as createUnixSocketFetch } from "../fetch-BjZVyU3Z.mjs";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
@@ -387,7 +387,7 @@ async function main() {
387
387
  console.log(`Received message from ${message.author.tag}: ${message.content}`);
388
388
  const downloadedFiles = [];
389
389
  if (message.attachments.size > 0) {
390
- const { getClawminiDir } = await import("../workspace-CSgfo_2J.mjs").then((n) => n._);
390
+ const { getClawminiDir } = await import("../workspace-BC1ahx4R.mjs").then((n) => n.v);
391
391
  const tmpDir = path.join(getClawminiDir(process.cwd()), "tmp", "discord");
392
392
  await fs$1.mkdir(tmpDir, { recursive: true });
393
393
  const maxSizeMB = config.maxAttachmentSizeMB ?? 25;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs";
2
- import { n as appendMessage$1 } from "./chats-DKgTeU7i.mjs";
2
+ import { n as appendMessage$1 } from "./chats-CpRQrNHj.mjs";
3
3
  import { EventEmitter } from "node:events";
4
4
 
5
5
  //#region src/daemon/events.ts
@@ -26,4 +26,4 @@ async function appendMessage(id, message, startDir = process.cwd()) {
26
26
 
27
27
  //#endregion
28
28
  export { daemonEvents as a, DAEMON_EVENT_TYPING as i, chats_exports as n, emitTyping as o, DAEMON_EVENT_MESSAGE_APPENDED as r, appendMessage as t };
29
- //# sourceMappingURL=chats-Zd_HXDHx.mjs.map
29
+ //# sourceMappingURL=chats-BcbxvPlj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chats-Zd_HXDHx.mjs","names":["shared.appendMessage"],"sources":["../src/daemon/events.ts","../src/daemon/chats.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { ChatMessage } from '../shared/chats.js';\n\nexport const daemonEvents = new EventEmitter();\n\nexport const DAEMON_EVENT_MESSAGE_APPENDED = 'message-appended';\nexport const DAEMON_EVENT_TYPING = 'typing';\n\nexport function emitMessageAppended(chatId: string, message: ChatMessage) {\n daemonEvents.emit(DAEMON_EVENT_MESSAGE_APPENDED, { chatId, message });\n}\n\nexport function emitTyping(chatId: string) {\n daemonEvents.emit(DAEMON_EVENT_TYPING, { chatId });\n}\n","import * as shared from '../shared/chats.js';\nimport { emitMessageAppended } from './events.js';\n\nexport async function appendMessage(\n id: string,\n message: shared.ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n await shared.appendMessage(id, message, startDir);\n emitMessageAppended(id, message);\n}\n\nexport {\n type ChatMessage,\n type UserMessage,\n type CommandLogMessage,\n getChatsDir,\n isValidChatId,\n createChat,\n listChats,\n deleteChat,\n getMessages,\n getDefaultChatId,\n setDefaultChatId,\n DEFAULT_CHAT_ID,\n} from '../shared/chats.js';\n"],"mappings":";;;;;AAGA,MAAa,eAAe,IAAI,cAAc;AAE9C,MAAa,gCAAgC;AAC7C,MAAa,sBAAsB;AAEnC,SAAgB,oBAAoB,QAAgB,SAAsB;AACxE,cAAa,KAAK,+BAA+B;EAAE;EAAQ;EAAS,CAAC;;AAGvE,SAAgB,WAAW,QAAgB;AACzC,cAAa,KAAK,qBAAqB,EAAE,QAAQ,CAAC;;;;;;ACVpD,eAAsB,cACpB,IACA,SACA,WAAW,QAAQ,KAAK,EACT;AACf,OAAMA,gBAAqB,IAAI,SAAS,SAAS;AACjD,qBAAoB,IAAI,QAAQ"}
1
+ {"version":3,"file":"chats-BcbxvPlj.mjs","names":["shared.appendMessage"],"sources":["../src/daemon/events.ts","../src/daemon/chats.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { ChatMessage } from '../shared/chats.js';\n\nexport const daemonEvents = new EventEmitter();\n\nexport const DAEMON_EVENT_MESSAGE_APPENDED = 'message-appended';\nexport const DAEMON_EVENT_TYPING = 'typing';\n\nexport function emitMessageAppended(chatId: string, message: ChatMessage) {\n daemonEvents.emit(DAEMON_EVENT_MESSAGE_APPENDED, { chatId, message });\n}\n\nexport function emitTyping(chatId: string) {\n daemonEvents.emit(DAEMON_EVENT_TYPING, { chatId });\n}\n","import * as shared from '../shared/chats.js';\nimport { emitMessageAppended } from './events.js';\n\nexport async function appendMessage(\n id: string,\n message: shared.ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n await shared.appendMessage(id, message, startDir);\n emitMessageAppended(id, message);\n}\n\nexport {\n type ChatMessage,\n type UserMessage,\n type CommandLogMessage,\n getChatsDir,\n isValidChatId,\n createChat,\n listChats,\n deleteChat,\n getMessages,\n getDefaultChatId,\n setDefaultChatId,\n DEFAULT_CHAT_ID,\n} from '../shared/chats.js';\n"],"mappings":";;;;;AAGA,MAAa,eAAe,IAAI,cAAc;AAE9C,MAAa,gCAAgC;AAC7C,MAAa,sBAAsB;AAEnC,SAAgB,oBAAoB,QAAgB,SAAsB;AACxE,cAAa,KAAK,+BAA+B;EAAE;EAAQ;EAAS,CAAC;;AAGvE,SAAgB,WAAW,QAAgB;AACzC,cAAa,KAAK,qBAAqB,EAAE,QAAQ,CAAC;;;;;;ACVpD,eAAsB,cACpB,IACA,SACA,WAAW,QAAQ,KAAK,EACT;AACf,OAAMA,gBAAqB,IAAI,SAAS,SAAS;AACjD,qBAAoB,IAAI,QAAQ"}
@@ -1,4 +1,4 @@
1
- import { c as getSettingsPath, o as getClawminiDir } from "./workspace-CSgfo_2J.mjs";
1
+ import { c as getSettingsPath, o as getClawminiDir } from "./workspace-BC1ahx4R.mjs";
2
2
  import { n as pathIsInsideDir } from "./fs-B5wW0oaH.mjs";
3
3
  import { existsSync } from "node:fs";
4
4
  import path from "node:path";
@@ -88,4 +88,4 @@ async function setDefaultChatId(id, startDir = process.cwd()) {
88
88
 
89
89
  //#endregion
90
90
  export { getChatsDir as a, isValidChatId as c, deleteChat as i, listChats as l, appendMessage as n, getDefaultChatId as o, createChat as r, getMessages as s, DEFAULT_CHAT_ID as t, setDefaultChatId as u };
91
- //# sourceMappingURL=chats-DKgTeU7i.mjs.map
91
+ //# sourceMappingURL=chats-CpRQrNHj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chats-DKgTeU7i.mjs","names":["fs"],"sources":["../src/shared/chats.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { getClawminiDir, getSettingsPath } from './workspace.js';\nimport { pathIsInsideDir } from './utils/fs.js';\n\nexport const DEFAULT_CHAT_ID = 'default';\n\nexport interface UserMessage {\n id: string;\n role: 'user';\n content: string;\n timestamp: string;\n}\n\nexport interface CommandLogMessage {\n id: string;\n messageId: string;\n role: 'log';\n source?: 'router';\n content: string;\n stderr: string;\n timestamp: string;\n command: string;\n cwd: string;\n exitCode: number;\n stdout?: string;\n files?: string[];\n level?: 'default' | 'debug' | 'verbose';\n}\n\nexport type ChatMessage = UserMessage | CommandLogMessage;\n\nexport async function getChatsDir(startDir = process.cwd()): Promise<string> {\n const dir = path.join(getClawminiDir(startDir), 'chats');\n if (!existsSync(dir)) {\n await fs.mkdir(dir, { recursive: true });\n }\n return dir;\n}\n\nexport function isValidChatId(chatId: string): boolean {\n if (!chatId || chatId.length === 0) return false;\n return /^[a-zA-Z0-9_-]+$/.test(chatId);\n}\n\nfunction assertValidChatId(id: string): void {\n if (!isValidChatId(id)) {\n throw new Error(`Invalid chat ID: ${id}`);\n }\n}\n\nexport async function createChat(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n if (!existsSync(chatDir)) {\n await fs.mkdir(chatDir, { recursive: true });\n }\n const chatFile = path.join(chatDir, 'chat.jsonl');\n if (!existsSync(chatFile)) {\n await fs.writeFile(chatFile, '');\n }\n}\n\nexport async function listChats(startDir = process.cwd()): Promise<string[]> {\n const chatsDir = await getChatsDir(startDir);\n try {\n const entries = await fs.readdir(chatsDir, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nexport async function deleteChat(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n\n if (!pathIsInsideDir(chatDir, chatsDir)) {\n throw new Error(`Security Error: Cannot delete chat directory outside of ${chatsDir}`);\n }\n\n if (existsSync(chatDir)) {\n await fs.rm(chatDir, { recursive: true, force: true });\n }\n}\n\nexport async function appendMessage(\n id: string,\n message: ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n if (!existsSync(chatDir)) {\n await createChat(id, startDir);\n }\n const chatFile = path.join(chatDir, 'chat.jsonl');\n await fs.appendFile(chatFile, JSON.stringify(message) + '\\n');\n}\n\nexport async function getMessages(\n id: string,\n limit?: number,\n startDir = process.cwd()\n): Promise<ChatMessage[]> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatFile = path.join(chatsDir, id, 'chat.jsonl');\n if (!existsSync(chatFile)) {\n throw new Error(`Chat directory or file for '${id}' not found.`);\n }\n const content = await fs.readFile(chatFile, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n const messages = lines.map((line) => JSON.parse(line) as ChatMessage);\n\n if (limit !== undefined && limit > 0) {\n return messages.slice(-limit);\n }\n return messages;\n}\n\nexport async function getDefaultChatId(startDir = process.cwd()): Promise<string> {\n const settingsPath = getSettingsPath(startDir);\n if (!existsSync(settingsPath)) return DEFAULT_CHAT_ID;\n\n try {\n const content = await fs.readFile(settingsPath, 'utf8');\n const settings = JSON.parse(content);\n return settings.chats?.defaultId || DEFAULT_CHAT_ID;\n } catch {\n return DEFAULT_CHAT_ID;\n }\n}\n\nexport async function setDefaultChatId(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const settingsPath = getSettingsPath(startDir);\n let settings: { chats?: { defaultId?: string; [key: string]: unknown }; [key: string]: unknown } =\n {};\n if (existsSync(settingsPath)) {\n try {\n const content = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(content);\n } catch {\n // Ignore invalid JSON\n }\n }\n\n if (!settings.chats) {\n settings.chats = {};\n }\n settings.chats.defaultId = id;\n\n const clawminiDir = getClawminiDir(startDir);\n if (!existsSync(clawminiDir)) {\n await fs.mkdir(clawminiDir, { recursive: true });\n }\n\n await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chats-CpRQrNHj.mjs","names":["fs"],"sources":["../src/shared/chats.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { getClawminiDir, getSettingsPath } from './workspace.js';\nimport { pathIsInsideDir } from './utils/fs.js';\n\nexport const DEFAULT_CHAT_ID = 'default';\n\nexport interface UserMessage {\n id: string;\n role: 'user';\n content: string;\n timestamp: string;\n}\n\nexport interface CommandLogMessage {\n id: string;\n messageId: string;\n role: 'log';\n source?: 'router';\n content: string;\n stderr: string;\n timestamp: string;\n command: string;\n cwd: string;\n exitCode: number;\n stdout?: string;\n files?: string[];\n level?: 'default' | 'debug' | 'verbose';\n}\n\nexport type ChatMessage = UserMessage | CommandLogMessage;\n\nexport async function getChatsDir(startDir = process.cwd()): Promise<string> {\n const dir = path.join(getClawminiDir(startDir), 'chats');\n if (!existsSync(dir)) {\n await fs.mkdir(dir, { recursive: true });\n }\n return dir;\n}\n\nexport function isValidChatId(chatId: string): boolean {\n if (!chatId || chatId.length === 0) return false;\n return /^[a-zA-Z0-9_-]+$/.test(chatId);\n}\n\nfunction assertValidChatId(id: string): void {\n if (!isValidChatId(id)) {\n throw new Error(`Invalid chat ID: ${id}`);\n }\n}\n\nexport async function createChat(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n if (!existsSync(chatDir)) {\n await fs.mkdir(chatDir, { recursive: true });\n }\n const chatFile = path.join(chatDir, 'chat.jsonl');\n if (!existsSync(chatFile)) {\n await fs.writeFile(chatFile, '');\n }\n}\n\nexport async function listChats(startDir = process.cwd()): Promise<string[]> {\n const chatsDir = await getChatsDir(startDir);\n try {\n const entries = await fs.readdir(chatsDir, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nexport async function deleteChat(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n\n if (!pathIsInsideDir(chatDir, chatsDir)) {\n throw new Error(`Security Error: Cannot delete chat directory outside of ${chatsDir}`);\n }\n\n if (existsSync(chatDir)) {\n await fs.rm(chatDir, { recursive: true, force: true });\n }\n}\n\nexport async function appendMessage(\n id: string,\n message: ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatDir = path.join(chatsDir, id);\n if (!existsSync(chatDir)) {\n await createChat(id, startDir);\n }\n const chatFile = path.join(chatDir, 'chat.jsonl');\n await fs.appendFile(chatFile, JSON.stringify(message) + '\\n');\n}\n\nexport async function getMessages(\n id: string,\n limit?: number,\n startDir = process.cwd()\n): Promise<ChatMessage[]> {\n assertValidChatId(id);\n const chatsDir = await getChatsDir(startDir);\n const chatFile = path.join(chatsDir, id, 'chat.jsonl');\n if (!existsSync(chatFile)) {\n throw new Error(`Chat directory or file for '${id}' not found.`);\n }\n const content = await fs.readFile(chatFile, 'utf8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n const messages = lines.map((line) => JSON.parse(line) as ChatMessage);\n\n if (limit !== undefined && limit > 0) {\n return messages.slice(-limit);\n }\n return messages;\n}\n\nexport async function getDefaultChatId(startDir = process.cwd()): Promise<string> {\n const settingsPath = getSettingsPath(startDir);\n if (!existsSync(settingsPath)) return DEFAULT_CHAT_ID;\n\n try {\n const content = await fs.readFile(settingsPath, 'utf8');\n const settings = JSON.parse(content);\n return settings.chats?.defaultId || DEFAULT_CHAT_ID;\n } catch {\n return DEFAULT_CHAT_ID;\n }\n}\n\nexport async function setDefaultChatId(id: string, startDir = process.cwd()): Promise<void> {\n assertValidChatId(id);\n const settingsPath = getSettingsPath(startDir);\n let settings: { chats?: { defaultId?: string; [key: string]: unknown }; [key: string]: unknown } =\n {};\n if (existsSync(settingsPath)) {\n try {\n const content = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(content);\n } catch {\n // Ignore invalid JSON\n }\n }\n\n if (!settings.chats) {\n settings.chats = {};\n }\n settings.chats.defaultId = id;\n\n const clawminiDir = getClawminiDir(startDir);\n if (!existsSync(clawminiDir)) {\n await fs.mkdir(clawminiDir, { recursive: true });\n }\n\n await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { a as getAgent, b as writeChatSettings, d as isValidAgentId, f as listAgents, g as readSettings, l as getSocketPath, m as readChatSettings, n as deleteAgent, o as getClawminiDir, r as enableEnvironment, t as applyTemplateToAgent, x as writeSettings, y as writeAgentSettings } from "../workspace-CSgfo_2J.mjs";
2
+ import { S as writeSettings, _ as readSettings, a as getAgent, b as writeAgentSettings, d as isValidAgentId, f as listAgents, l as getSocketPath, m as readChatSettings, n as deleteAgent, o as getClawminiDir, r as enableEnvironment, t as applyTemplateToAgent, x as writeChatSettings } from "../workspace-BC1ahx4R.mjs";
3
3
  import { n as pathIsInsideDir } from "../fs-B5wW0oaH.mjs";
4
- import { a as getChatsDir, c as isValidChatId, i as deleteChat, l as listChats, o as getDefaultChatId, r as createChat, s as getMessages, t as DEFAULT_CHAT_ID, u as setDefaultChatId } from "../chats-DKgTeU7i.mjs";
4
+ import { a as getChatsDir, c as isValidChatId, i as deleteChat, l as listChats, o as getDefaultChatId, r as createChat, s as getMessages, t as DEFAULT_CHAT_ID, u as setDefaultChatId } from "../chats-CpRQrNHj.mjs";
5
5
  import { t as createUnixSocketFetch } from "../fetch-BjZVyU3Z.mjs";
6
- import { i as writeLiteScript, r as getLiteScriptContent, t as exportLiteToAllEnvironments } from "../lite-Dl7WXyaH.mjs";
6
+ import { i as writeLiteScript, r as getLiteScriptContent, t as exportLiteToAllEnvironments } from "../lite-DBUuHsX0.mjs";
7
7
  import { Command } from "commander";
8
8
  import fs from "node:fs";
9
9
  import path from "node:path";
@@ -56,6 +56,7 @@ const initCmd = new Command("init").description("Initialize a new .clawmini sett
56
56
  "@clawmini/slash-new",
57
57
  "@clawmini/slash-stop",
58
58
  "@clawmini/slash-interrupt",
59
+ "@clawmini/slash-policies",
59
60
  "@clawmini/slash-command"
60
61
  ],
61
62
  api: true