@hybridaione/hybridclaw 0.2.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/README.md +23 -354
- package/config.example.json +9 -3
- package/container/.dockerignore +16 -0
- package/container/dist/approval-policy.js +1183 -0
- package/container/dist/approval-policy.js.map +1 -0
- package/container/dist/browser-tools.js +1523 -0
- package/container/dist/browser-tools.js.map +1 -0
- package/container/dist/extensions.js +114 -0
- package/container/dist/extensions.js.map +1 -0
- package/container/dist/hybridai-client.js +256 -0
- package/container/dist/hybridai-client.js.map +1 -0
- package/container/dist/index.js +866 -0
- package/container/dist/index.js.map +1 -0
- package/container/dist/ipc.js +32 -0
- package/container/dist/ipc.js.map +1 -0
- package/container/dist/model-retry.js +18 -0
- package/container/dist/model-retry.js.map +1 -0
- package/container/dist/runtime-paths.js +79 -0
- package/container/dist/runtime-paths.js.map +1 -0
- package/container/dist/token-usage.js +168 -0
- package/container/dist/token-usage.js.map +1 -0
- package/container/dist/tools.js +2265 -0
- package/container/dist/tools.js.map +1 -0
- package/container/dist/types.js +2 -0
- package/container/dist/types.js.map +1 -0
- package/container/dist/web-fetch.js +396 -0
- package/container/dist/web-fetch.js.map +1 -0
- package/container/package-lock.json +2 -2
- package/container/package.json +1 -1
- package/container/src/browser-tools.ts +20 -23
- package/container/src/index.ts +19 -29
- package/container/src/ipc.ts +1 -1
- package/container/src/runtime-paths.ts +116 -0
- package/container/src/tools.ts +80 -63
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +20 -8
- package/dist/agent.js.map +1 -1
- package/dist/audit-cli.d.ts.map +1 -1
- package/dist/audit-cli.js +25 -31
- package/dist/audit-cli.js.map +1 -1
- package/dist/channels/discord/runtime.d.ts.map +1 -1
- package/dist/channels/discord/runtime.js +81 -16
- package/dist/channels/discord/runtime.js.map +1 -1
- package/dist/cli-flags.d.ts +9 -0
- package/dist/cli-flags.d.ts.map +1 -0
- package/dist/cli-flags.js +53 -0
- package/dist/cli-flags.js.map +1 -0
- package/dist/cli.js +86 -53
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +65 -3
- package/dist/config.js.map +1 -1
- package/dist/container-runner.d.ts +25 -0
- package/dist/container-runner.d.ts.map +1 -1
- package/dist/container-runner.js +31 -6
- package/dist/container-runner.js.map +1 -1
- package/dist/container-setup.d.ts.map +1 -1
- package/dist/container-setup.js +109 -12
- package/dist/container-setup.js.map +1 -1
- package/dist/db.d.ts +1 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +20 -1
- package/dist/db.js.map +1 -1
- package/dist/executor.d.ts +45 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +87 -0
- package/dist/executor.js.map +1 -0
- package/dist/gateway-client.d.ts +3 -2
- package/dist/gateway-client.d.ts.map +1 -1
- package/dist/gateway-client.js +10 -0
- package/dist/gateway-client.js.map +1 -1
- package/dist/gateway-service.d.ts.map +1 -1
- package/dist/gateway-service.js +32 -7
- package/dist/gateway-service.js.map +1 -1
- package/dist/gateway-types.d.ts +26 -0
- package/dist/gateway-types.d.ts.map +1 -1
- package/dist/gateway-types.js.map +1 -1
- package/dist/gateway.js +25 -4
- package/dist/gateway.js.map +1 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +91 -4
- package/dist/health.js.map +1 -1
- package/dist/host-runner.d.ts +43 -0
- package/dist/host-runner.d.ts.map +1 -0
- package/dist/host-runner.js +284 -0
- package/dist/host-runner.js.map +1 -0
- package/dist/install-root.d.ts +4 -0
- package/dist/install-root.d.ts.map +1 -0
- package/dist/install-root.js +74 -0
- package/dist/install-root.js.map +1 -0
- package/dist/instruction-approval-audit.d.ts.map +1 -1
- package/dist/instruction-approval-audit.js +3 -3
- package/dist/instruction-approval-audit.js.map +1 -1
- package/dist/instruction-integrity.d.ts +27 -16
- package/dist/instruction-integrity.d.ts.map +1 -1
- package/dist/instruction-integrity.js +74 -93
- package/dist/instruction-integrity.js.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/onboarding.d.ts.map +1 -1
- package/dist/onboarding.js +12 -8
- package/dist/onboarding.js.map +1 -1
- package/dist/prompt-hooks.d.ts.map +1 -1
- package/dist/prompt-hooks.js +13 -4
- package/dist/prompt-hooks.js.map +1 -1
- package/dist/runtime-config.d.ts +6 -1
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +280 -14
- package/dist/runtime-config.js.map +1 -1
- package/dist/scheduled-task-runner.d.ts.map +1 -1
- package/dist/scheduled-task-runner.js +1 -1
- package/dist/scheduled-task-runner.js.map +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +19 -11
- package/dist/scheduler.js.map +1 -1
- package/dist/tui.js +160 -7
- package/dist/tui.js.map +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +3 -2
- package/dist/workspace.js.map +1 -1
- package/docs/index.html +26 -26
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.3.0](https://github.com/HybridAIOne/hybridclaw/tree/v0.3.0)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Configurable sandbox modes**: Gateway start/restart now accept `--sandbox=container|host`, runtime config adds `container.sandboxMode`, and gateway/TUI status surfaces show the active sandbox mode so operators can avoid Docker-in-Docker when HybridClaw itself already runs inside a container.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Container runtime hardening**: Container execution now drops Linux capabilities, disables privilege escalation, enforces a PID limit, uses a sized `/tmp` tmpfs, and adds `container.memorySwap` / `container.network` tuning alongside GHCR-first image pulls before the optional Docker Hub mirror.
|
|
14
|
+
- **Packaged host runtime**: Root builds now compile and ship `container/dist/` so host sandbox mode can launch the bundled agent runtime from installed npm packages.
|
|
15
|
+
- **Instruction sync workflow**: `hybridclaw audit instructions` now compares runtime copies in `~/.hybridclaw/instructions/` to installed package sources and uses `--sync` to restore shipped defaults instead of maintaining a local approval-hash baseline.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Release container publishing resilience**: Release-tag container publishing now always publishes GHCR even when Docker Hub credentials are absent, instead of failing before any registry push occurs.
|
|
20
|
+
- **Install-root asset resolution**: Runtime docs/templates/instructions now resolve from the actual install root, so onboarding, prompt guardrails, workspace bootstrap files, and the built-in site no longer depend on `process.cwd()`.
|
|
21
|
+
|
|
22
|
+
## [0.2.12](https://github.com/HybridAIOne/hybridclaw/tree/v0.2.12)
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **Automatic container publishing**: Added release-tag GitHub Actions publishing to Docker Hub (`hybridaione/hybridclaw-agent`) plus GHCR mirror (`ghcr.io/<org>/hybridclaw-agent`) with versioned tags (`vX.Y.Z`) and stable `latest` updates.
|
|
27
|
+
- **Container build context guardrails**: Added `container/.dockerignore` and included it in npm package files so local secrets/artifacts are excluded from image build context.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- **Runtime data default location**: Runtime config and data now default to `~/.hybridclaw` (`config.json`, `data/hybridclaw.db`, audit/session artifacts) to match home-directory workspace best practices.
|
|
32
|
+
- **Container bootstrap pull order**: Container readiness now pulls prebuilt images from Docker Hub first (`v<app-version>`, then `latest`) with GHCR fallback before local build.
|
|
33
|
+
- **README scope cleanup**: Reduced README to user-facing install/runtime guidance and moved maintainer/developer internals to `CONTRIBUTING.md`.
|
|
34
|
+
- **Container build script behavior**: `npm run build:container` now runs `docker build` directly without requiring host TypeScript tooling.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **First-run migration completeness**: Startup now migrates legacy `./config.json` and `./data` into `~/.hybridclaw`, archives legacy files, and stores migration backups under `~/.hybridclaw/migration-backups/` on conflicts.
|
|
39
|
+
- **Install-root write issues**: Container image fingerprint state now persists under `~/.hybridclaw/container-image-state` (with legacy state fallback) instead of package install directories.
|
|
40
|
+
- **Duplicate Discord `/status` slash entries**: Slash command registration now keeps `status`/`approve` global-only and removes stale guild-scoped duplicates to avoid duplicate command entries in guild channels.
|
|
41
|
+
|
|
42
|
+
## [0.2.11](https://github.com/HybridAIOne/hybridclaw/tree/v0.2.11)
|
|
43
|
+
|
|
5
44
|
### Added
|
|
6
45
|
|
|
46
|
+
- **Model default controls across TUI/Discord**: Added `model default [name]` command support in gateway/TUI plus a Discord `/model` slash command (`info`, `default`) with configured model choices.
|
|
47
|
+
- **Local proactive reminder delivery path**: Added queued proactive pull API (`GET /api/proactive/pull`) and TUI polling so scheduler/heartbeat reminders reliably surface in `tui` channels.
|
|
48
|
+
- **Scheduler timestamp regression test**: Added coverage for legacy SQLite second-precision timestamps and interval due-time regression handling.
|
|
49
|
+
|
|
7
50
|
### Changed
|
|
8
51
|
|
|
52
|
+
- **Cron tool reminder contract**: Cron `add` now accepts prompt aliases (`prompt`/`message`/`text`), supports relative one-shot scheduling via `at_seconds`, and documents prompt-as-instruction semantics for future model runs.
|
|
53
|
+
- **Scheduler prompt framing**: Scheduled model turns now explicitly instruct execution of the provided instruction without follow-up questions.
|
|
54
|
+
|
|
9
55
|
### Fixed
|
|
10
56
|
|
|
57
|
+
- **SQLite timestamp interpretation drift**: Scheduler now normalizes legacy `YYYY-MM-DD HH:MM:SS` task timestamps as UTC, preventing immediate re-fire bugs on interval tasks after timezone conversion.
|
|
58
|
+
- **Silent reply normalization edge case**: API/stream silent-token replacement now emits `Message sent.` only for real `message` send actions and otherwise falls back to the latest successful tool result.
|
|
59
|
+
|
|
11
60
|
## [0.2.10](https://github.com/HybridAIOne/hybridclaw/tree/v0.2.10)
|
|
12
61
|
|
|
13
62
|
### Added
|
package/README.md
CHANGED
|
@@ -11,13 +11,14 @@ npm install -g @hybridaione/hybridclaw
|
|
|
11
11
|
hybridclaw onboarding
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
Latest release: [v0.
|
|
14
|
+
Latest release: [v0.3.0](https://github.com/HybridAIOne/hybridclaw/releases/tag/v0.3.0)
|
|
15
15
|
|
|
16
|
-
## Release highlights (v0.
|
|
16
|
+
## Release highlights (v0.3.0)
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
18
|
+
- Gateway start/restart now support `--sandbox=container|host`, runtime config adds `container.sandboxMode`, and gateway/TUI status surfaces show the active mode.
|
|
19
|
+
- Container execution is hardened with dropped capabilities, `no-new-privileges`, PID limits, configurable network/memory-swap controls, and better GHCR-first image handling.
|
|
20
|
+
- Root builds now package `container/dist/` so host sandbox mode can launch the bundled agent runtime from installed npm packages.
|
|
21
|
+
- Runtime docs/templates/instructions now resolve from the actual install root, and `hybridclaw audit instructions --sync` restores shipped instruction copies under `~/.hybridclaw/instructions/`.
|
|
21
22
|
|
|
22
23
|
## HybridAI Advantage
|
|
23
24
|
|
|
@@ -51,7 +52,7 @@ hybridclaw onboarding
|
|
|
51
52
|
# 3) open /register in browser (optional) and confirm in terminal
|
|
52
53
|
# 4) open /login?next=/admin_api_keys in browser and get an API key
|
|
53
54
|
# 5) paste API key (or URL containing it) back into the CLI
|
|
54
|
-
# 6) choose the default bot (saved to config.json) and save secrets to `.env`
|
|
55
|
+
# 6) choose the default bot (saved to ~/.hybridclaw/config.json) and save secrets to `.env`
|
|
55
56
|
|
|
56
57
|
# Start gateway backend (default)
|
|
57
58
|
hybridclaw gateway
|
|
@@ -74,349 +75,31 @@ Runtime model:
|
|
|
74
75
|
- If `DISCORD_TOKEN` is set, Discord runs inside gateway automatically.
|
|
75
76
|
- `hybridclaw tui` is a thin client that connects to the gateway.
|
|
76
77
|
- `hybridclaw gateway` and `hybridclaw tui` validate the container image at startup.
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
|
|
81
|
-
HybridClaw best-in-class capabilities:
|
|
82
|
-
|
|
83
|
-
- explicit trust-model acceptance during onboarding (recorded in `config.json`)
|
|
84
|
-
- typed `config.json` runtime settings with defaults, validation, and hot reload
|
|
85
|
-
- formal prompt hook orchestration (`bootstrap`, `memory`, `safety`, `proactivity`)
|
|
86
|
-
- layered memory substrate: structured KV, semantic memory, typed knowledge graph entities/relations, canonical cross-channel sessions, and usage event persistence
|
|
87
|
-
- lightweight DB evolution and concurrency hardening via `PRAGMA user_version` migrations, `journal_mode=WAL`, and `busy_timeout=5000`
|
|
88
|
-
- Discord conversational UX: edit-in-place streaming responses, fence-safe chunking beyond Discord's 2000-char limit, phase-aware typing/reactions, adaptive debounce batching, per-user rate limits, health-driven self-presence, reply-chain-aware context, concise attachment-first screenshot replies, and humanized pacing (time-of-day slowdown, cooldown scaling, selective silence, read-without-reply, startup staggering)
|
|
89
|
-
- token-efficient context assembly: per-message history truncation, hard history budgets with head/tail preservation, and head/tail truncation for oversized bootstrap files
|
|
90
|
-
- runtime self-awareness in prompts: exact HybridClaw version/date, model, and runtime host metadata injected each turn for reliable "what version/model are you?" answers
|
|
91
|
-
- proactive runtime layer with active-hours gating, push delegation (`single`/`parallel`/`chain`), depth-aware tool policy, and retry controls
|
|
92
|
-
- trusted-coworker approval model for tool execution: Green (`just run`), Yellow (`narrate + 5s interrupt window`), Red (`explicit approval`) with `yes` (once), `yes for session`, `yes for agent`, and explicit deny (`no`, also `4`) plus pinned-red protections
|
|
93
|
-
- structured audit trail: append-only hash-chained wire logs (`data/audit/<session>/wire.jsonl`) with tamper-evident immutability, normalized SQLite audit tables, and verification/search CLI commands
|
|
94
|
-
- observability export: incremental `events:batch` forwarding with durable cursor tracking and bot-scoped ingest token lifecycle via `ingest-token:ensure`
|
|
95
|
-
- model token telemetry in audit/observability events (`model.usage`) with API usage + deterministic fallback estimates
|
|
96
|
-
- built-in usage aggregation (`usage summary|daily|monthly|model`) plus JSONL session exports (`export session [sessionId]`) for cost/debug visibility
|
|
97
|
-
- gateway lifecycle controls: managed + unmanaged restart/stop flows with graceful shutdown fallback paths
|
|
98
|
-
- instruction-integrity approval flow: core instruction docs (`AGENTS.md`, `SECURITY.md`, `TRUST_MODEL.md`) are hash-verified against a local approved baseline before TUI start
|
|
78
|
+
- `container.sandboxMode` defaults to `container`, but if HybridClaw is already running inside a container and the setting is not explicitly pinned, the gateway auto-switches to `host` to avoid Docker-in-Docker.
|
|
79
|
+
- Use `hybridclaw gateway start --sandbox=host` or `hybridclaw gateway restart --sandbox=host` to force host execution for a given launch.
|
|
80
|
+
- On first run, HybridClaw automatically prepares that image (pulls a prebuilt image first, then falls back to local build if needed).
|
|
81
|
+
- If container setup fails, run `npm run build:container` in the project root and retry.
|
|
99
82
|
|
|
100
83
|
## Configuration
|
|
101
84
|
|
|
102
|
-
HybridClaw
|
|
103
|
-
|
|
104
|
-
- Start from `config.example.json` (reference)
|
|
105
|
-
- Runtime watches `config.json` and hot-reloads most settings (model defaults, heartbeat, prompt hooks, limits, etc.)
|
|
106
|
-
- `discord.guildMembersIntent` enables richer guild member context and better `@name` mention resolution in replies (requires enabling **Server Members Intent** in Discord Developer Portal)
|
|
107
|
-
- `discord.presenceIntent` enables Discord presence events (requires enabling **Presence Intent** in Discord Developer Portal)
|
|
108
|
-
- `discord.respondToAllMessages` is a global fallback for open-policy guild channels without explicit mode config (`false` mention-gated, `true` free-response)
|
|
109
|
-
- `discord.commandMode` controls command access: `public` (any user can run slash/`!claw` commands) or `restricted` (only allowlisted users can run slash/`!claw` commands)
|
|
110
|
-
- `discord.commandAllowedUserIds` is the allowlist used when `discord.commandMode` is `restricted`
|
|
111
|
-
- `discord.commandUserId` is a legacy single-user allowlist alias; when set without `commandMode`, runtime treats command access as `restricted` for backward compatibility
|
|
112
|
-
- `discord.commandsOnly` optional hard mode: if `true`, the bot ignores non-`!claw` messages and only accepts prefixed commands (still subject to `discord.commandMode`)
|
|
113
|
-
- `discord.groupPolicy` controls guild channel scope: `open` (default, mention-first unless a channel is set to `free`), `allowlist`, or `disabled`
|
|
114
|
-
- `discord.freeResponseChannels` is a Hermes-style channel ID list that gets free-response behavior while other channels remain mention-gated
|
|
115
|
-
- `discord.textChunkLimit` controls Discord message chunk size (default `2000`)
|
|
116
|
-
- `discord.maxLinesPerMessage` controls max lines per Discord chunk (default `17`)
|
|
117
|
-
- `discord.humanDelay` controls natural delays between multi-part messages (`off|natural|custom`)
|
|
118
|
-
- `discord.typingMode` controls typing indicator lifecycle (`instant|thinking|streaming|never`)
|
|
119
|
-
- `discord.presence.*` enables dynamic self-presence health states (healthy/degraded/exhausted mapped to `online|idle|dnd`, plus maintenance `invisible` during shutdown)
|
|
120
|
-
- `discord.lifecycleReactions.*` enables phase emoji transitions (`queued|thinking|toolUse|streaming|done|error`)
|
|
121
|
-
- approval policy layer is configured via `.hybridclaw/policy.yaml` (`approval.pinned_red`, `workspace_fence`, pending/timeout controls, audit toggles)
|
|
122
|
-
- `discord.ackReaction`, `discord.ackReactionScope`, and `discord.removeAckAfterReply` control acknowledgment reaction behavior
|
|
123
|
-
- `discord.debounceMs` controls default inbound debounce; channel overrides can tune noisy channels
|
|
124
|
-
- `discord.rateLimitPerUser` and `discord.rateLimitExemptRoles` enforce per-user sliding-window limits
|
|
125
|
-
- `discord.suppressPatterns` blocks auto-reply triggers for suppression terms (case-insensitive)
|
|
126
|
-
- `discord.maxConcurrentPerChannel` limits concurrent in-flight runs per channel
|
|
127
|
-
- `discord.guilds.<guildId>.defaultMode` sets that guild's fallback mode in `open` policy (`mention` recommended)
|
|
128
|
-
- `discord.guilds.<guildId>.channels.<channelId>.*` supports per-channel mode and behavior overrides (`mode`, `typingMode`, `debounceMs`, `ackReaction*`, `humanDelay`, `rateLimitPerUser`, `suppressPatterns`, `maxConcurrentPerChannel`)
|
|
129
|
-
- `scheduler.jobs[]` defines config-backed proactive jobs with `schedule.kind` (`cron|every|at`), `action.kind` (`agent_turn|system_event`), and delivery targets (`channel|last-channel|webhook`)
|
|
130
|
-
- `scheduler.jobs[].name` / `scheduler.jobs[].description` add optional human-readable labels for status/log output; runtime status persists `nextRunAt`
|
|
131
|
-
- Config scheduler job metadata (last status, consecutive errors, one-shot completion) persists atomically in `data/scheduler-jobs-state.json`
|
|
132
|
-
- Config scheduler jobs auto-disable after repeated failures (5 consecutive errors) and one-shot jobs retry on a bounded interval until successful
|
|
133
|
-
- `memory.decayRate` and `memory.consolidationIntervalHours` control semantic-memory consolidation intensity/cadence
|
|
134
|
-
- `sessionCompaction.tokenBudget` and `sessionCompaction.budgetRatio` tune compaction token budgeting behavior
|
|
135
|
-
- Built-in Discord humanization behaviors include night/weekend pacing, post-exchange cooldown scaling (after 5+ exchanges, reset after 20 minutes idle), selective silence in active free-mode channels, short-ack read reactions, and reconnect staggered dequeue
|
|
136
|
-
- Per-guild/per-channel mode takes precedence over `discord.respondToAllMessages`
|
|
137
|
-
- Discord slash commands: `/status`, `/approve [view|yes|session|agent|no] [approval_id]`, `/channel-mode <off|mention|free>`, and `/channel-policy <open|allowlist|disabled>` (ephemeral replies)
|
|
138
|
-
- `skills.extraDirs` adds additional enterprise/shared skill roots (lowest precedence tier)
|
|
139
|
-
- `proactive.*` controls autonomous behavior (`activeHours`, `delegation`, `autoRetry`, `ralph`)
|
|
140
|
-
- `proactive.ralph.maxIterations` enables Ralph loop (`0` off, `-1` unlimited, `>0` extra autonomous iterations before forcing completion)
|
|
141
|
-
- TUI/Gateway command: `ralph on|off|set <n>|info` (`0` off, `-1` unlimited, `1-64` extra iterations)
|
|
142
|
-
- `observability.*` controls push ingest into HybridAI (`events:batch` endpoint, batching, identity metadata)
|
|
143
|
-
- Some settings require restart to fully apply (for example HTTP bind host/port)
|
|
144
|
-
- Default bot is configured via `hybridai.defaultChatbotId` in `config.json`
|
|
145
|
-
- `hybridai.maxTokens` sets the default completion budget per model call (default `4096`)
|
|
146
|
-
|
|
147
|
-
Secrets remain in `.env`:
|
|
148
|
-
|
|
149
|
-
- `HYBRIDAI_API_KEY` (required)
|
|
150
|
-
- `DISCORD_TOKEN` (optional)
|
|
151
|
-
- `WEB_API_TOKEN` and `GATEWAY_API_TOKEN` (optional API auth hardening)
|
|
152
|
-
- observability ingest token is auto-managed via `POST /api/v1/agent-observability/ingest-token:ensure` and cached locally
|
|
153
|
-
|
|
154
|
-
Trust-model acceptance is stored in `config.json` under `security.*` and is required before runtime starts.
|
|
155
|
-
|
|
156
|
-
See [TRUST_MODEL.md](./TRUST_MODEL.md) for onboarding acceptance policy and [SECURITY.md](./SECURITY.md) for technical security guidelines.
|
|
157
|
-
|
|
158
|
-
## Audit Trail
|
|
159
|
-
|
|
160
|
-
HybridClaw records a forensic audit trail by default:
|
|
161
|
-
|
|
162
|
-
- append-only per-session wire logs in `data/audit/<session>/wire.jsonl`
|
|
163
|
-
- SHA-256 hash chaining (`_prevHash` -> `_hash`) for tamper-evident immutability
|
|
164
|
-
- normalized query tables in SQLite (`audit_events`, `approvals`)
|
|
165
|
-
- policy denials captured as approval/authorization events (for example blocked commands)
|
|
166
|
-
|
|
167
|
-
Useful commands:
|
|
168
|
-
|
|
169
|
-
- `hybridclaw audit recent 50`
|
|
170
|
-
- `hybridclaw audit search "tool.call" 50`
|
|
171
|
-
- `hybridclaw audit approvals 50 --denied`
|
|
172
|
-
- `hybridclaw audit verify <sessionId>`
|
|
173
|
-
- `hybridclaw audit instructions`
|
|
174
|
-
- `hybridclaw audit instructions --approve`
|
|
175
|
-
|
|
176
|
-
Instruction approval notes:
|
|
177
|
-
|
|
178
|
-
- local baseline file: `data/audit/instruction-hashes.json`
|
|
179
|
-
- `hybridclaw audit instructions` fails when instruction files differ from the approved baseline
|
|
180
|
-
- `hybridclaw audit instructions --approve` updates the local approved baseline
|
|
181
|
-
- `hybridclaw tui` performs this check before startup and prompts for approval when files changed
|
|
182
|
-
- instruction approval actions are audit logged (`approval.request` / `approval.response`, action `instruction:approve`)
|
|
183
|
-
|
|
184
|
-
## Observability Push
|
|
185
|
-
|
|
186
|
-
HybridClaw can forward structured audit records to HybridAI's ingest API:
|
|
187
|
-
|
|
188
|
-
- endpoint: `POST /api/v1/agent-observability/events:batch`
|
|
189
|
-
- source: local `audit_events` table (ordered by `id`)
|
|
190
|
-
- transport: bearer ingest token auto-fetched via `POST /api/v1/agent-observability/ingest-token:ensure` using `HYBRIDAI_API_KEY`
|
|
191
|
-
- delivery: incremental batches with persisted cursor (`observability_offsets` table), max 1000 events and max 2,000,000-byte payload per request
|
|
192
|
-
- token handling: token cache is stored locally in SQLite (`observability_ingest_tokens`) and automatically refreshed on ingest auth failures
|
|
193
|
-
- token visibility: `model.usage` payloads include `promptTokens`, `completionTokens`, `totalTokens`, plus estimated and API-native counters for accuracy/coverage
|
|
194
|
-
|
|
195
|
-
Config keys (in `config.json`):
|
|
196
|
-
|
|
197
|
-
- `observability.enabled` (`true` by default)
|
|
198
|
-
- `observability.baseUrl` (for example `https://hybridai.one`)
|
|
199
|
-
- `observability.ingestPath` (`/api/v1/agent-observability/events:batch`)
|
|
200
|
-
- `observability.botId` (defaults to `hybridai.defaultChatbotId` when empty)
|
|
201
|
-
- `observability.agentId`, `observability.label`, `observability.environment`
|
|
202
|
-
- `observability.flushIntervalMs`, `observability.batchMaxEvents`
|
|
203
|
-
|
|
204
|
-
Runtime diagnostics:
|
|
205
|
-
|
|
206
|
-
- local status endpoint `GET /api/status` includes an `observability` block (enabled/running/paused, cursor, last success/failure timestamps)
|
|
207
|
-
|
|
208
|
-
## Agent workspace
|
|
209
|
-
|
|
210
|
-
Each agent gets a persistent workspace with markdown files that shape its personality and memory:
|
|
211
|
-
|
|
212
|
-
| File | Purpose |
|
|
213
|
-
|------|---------|
|
|
214
|
-
| `SOUL.md` | Personality, tone, identity |
|
|
215
|
-
| `IDENTITY.md` | Name, avatar, emoji |
|
|
216
|
-
| `USER.md` | Info about the human |
|
|
217
|
-
| `MEMORY.md` | Persistent memory across sessions |
|
|
218
|
-
| `AGENTS.md` | Workspace conventions and rules |
|
|
219
|
-
| `TOOLS.md` | Environment-specific notes |
|
|
220
|
-
| `HEARTBEAT.md` | Periodic tasks |
|
|
221
|
-
| `BOOT.md` | Startup instructions |
|
|
222
|
-
|
|
223
|
-
Templates in `templates/` are copied to new agent workspaces on first run.
|
|
224
|
-
Historical turn logs are mirrored into `<workspace>/.session-transcripts/*.jsonl` for `session_search`.
|
|
225
|
-
|
|
226
|
-
## Skills
|
|
227
|
-
|
|
228
|
-
HybridClaw supports `SKILL.md`-based skills (`<skill-name>/SKILL.md`).
|
|
229
|
-
|
|
230
|
-
### Where to put skills
|
|
231
|
-
|
|
232
|
-
You can place skills in:
|
|
233
|
-
|
|
234
|
-
- any directory listed in `config.skills.extraDirs[]` (enterprise/shared)
|
|
235
|
-
- bundled package skills (`<hybridclaw install>/skills/<skill-name>/SKILL.md`)
|
|
236
|
-
- `$CODEX_HOME/skills/<skill-name>/SKILL.md` or `~/.codex/skills/<skill-name>/SKILL.md`
|
|
237
|
-
- `~/.claude/skills/<skill-name>/SKILL.md`
|
|
238
|
-
- `~/.agents/skills/<skill-name>/SKILL.md`
|
|
239
|
-
- `./.agents/skills/<skill-name>/SKILL.md` (project)
|
|
240
|
-
- `./skills/<skill-name>/SKILL.md` (workspace)
|
|
241
|
-
|
|
242
|
-
Load precedence is:
|
|
243
|
-
|
|
244
|
-
- `extra < bundled < codex < claude < agents-personal < agents-project < workspace`
|
|
245
|
-
- skills are merged by `name`; higher-precedence sources override lower-precedence ones
|
|
246
|
-
|
|
247
|
-
Security scanning is trust-aware:
|
|
248
|
-
|
|
249
|
-
- `bundled` sources are treated as `builtin` and not scanned
|
|
250
|
-
- `workspace` sources (`./skills/`, `./.agents/skills/`) are scanned; `caution` is allowed, `dangerous` is blocked
|
|
251
|
-
- `personal` sources (`~/.codex/skills/`, `~/.claude/skills/`, `~/.agents/skills/`) are scanned and blocked on `caution`/`dangerous`
|
|
252
|
-
- scanner includes Hermes-derived regex checks, structural limits (50 files, 1MB total, 256KB/file, binary/symlink checks), invisible-unicode detection, and mtime+content-hash cache reuse
|
|
253
|
-
|
|
254
|
-
### Required format
|
|
255
|
-
|
|
256
|
-
Each skill must be a folder with a `SKILL.md` file and frontmatter:
|
|
257
|
-
|
|
258
|
-
```markdown
|
|
259
|
-
---
|
|
260
|
-
name: repo-orientation
|
|
261
|
-
description: Quickly map an unfamiliar repository and identify where a requested feature should be implemented.
|
|
262
|
-
user-invocable: true
|
|
263
|
-
disable-model-invocation: false
|
|
264
|
-
always: false
|
|
265
|
-
requires:
|
|
266
|
-
bins: [docker, git]
|
|
267
|
-
env: [GITHUB_TOKEN]
|
|
268
|
-
metadata:
|
|
269
|
-
hybridclaw:
|
|
270
|
-
tags: [devops, docker]
|
|
271
|
-
related_skills: [kubernetes]
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
# Repo Orientation
|
|
275
|
-
...instructions...
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Supported frontmatter keys:
|
|
279
|
-
|
|
280
|
-
- `name` (required)
|
|
281
|
-
- `description` (required)
|
|
282
|
-
- `user-invocable` (optional, default `true`)
|
|
283
|
-
- `disable-model-invocation` (optional, default `false`)
|
|
284
|
-
- `always` (optional, default `false`; embeds full skill body in the system prompt up to `maxAlwaysChars=10000`, then demotes to summary)
|
|
285
|
-
- `requires.bins` / `requires.env` (optional; skill is excluded unless requirements are met)
|
|
286
|
-
- `metadata.hybridclaw.tags` / `metadata.hybridclaw.related_skills` (optional metadata namespace)
|
|
85
|
+
HybridClaw creates `~/.hybridclaw/config.json` on first run and hot-reloads most runtime settings.
|
|
287
86
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
-
|
|
295
|
-
-
|
|
296
|
-
- `Hidden`: `disable-model-invocation: true` excludes the skill from model prompt metadata (still invocable by slash command when `user-invocable: true`)
|
|
297
|
-
|
|
298
|
-
Explicit invocation is supported via:
|
|
299
|
-
|
|
300
|
-
- `/skill <name> [input]`
|
|
301
|
-
- `/skill:<name> [input]`
|
|
302
|
-
- `/<name> [input]` (when `user-invocable: true`; command names are sanitized to lowercase `a-z0-9-`, max 32 chars, with `-2`/`-3` dedup and built-in command-name blocking)
|
|
303
|
-
|
|
304
|
-
Example skill in this repo:
|
|
305
|
-
|
|
306
|
-
- `skills/repo-orientation/SKILL.md`
|
|
307
|
-
- `skills/current-time/SKILL.md`
|
|
308
|
-
- `skills/personality/SKILL.md`
|
|
309
|
-
- `skills/skill-creator/SKILL.md`
|
|
310
|
-
|
|
311
|
-
### Personality switching skill
|
|
312
|
-
|
|
313
|
-
HybridClaw includes a command-only personality skill that updates the active persona contract in `SOUL.md`.
|
|
314
|
-
|
|
315
|
-
- List current/available persona: `/personality` (or `/personality list`)
|
|
316
|
-
- Activate persona: `/personality <name>`
|
|
317
|
-
- Reset to default persona: `/personality reset`
|
|
318
|
-
|
|
319
|
-
The skill writes/updates a managed block in `SOUL.md`:
|
|
320
|
-
|
|
321
|
-
- `## Active personality`
|
|
322
|
-
- `Name: ...`
|
|
323
|
-
- `Definition: ...` (copied from the selected profile in `skills/personality/SKILL.md`)
|
|
324
|
-
- `Rules: ...` (runtime style/behavior constraints)
|
|
325
|
-
|
|
326
|
-
Notes:
|
|
327
|
-
|
|
328
|
-
- The personality skill is intentionally command-only (`always: false`, `disable-model-invocation: true`) to avoid adding per-turn prompt overhead.
|
|
329
|
-
- Profiles are defined in `skills/personality/SKILL.md` and currently include 25 switchable personas (expert, style, and role personas).
|
|
330
|
-
|
|
331
|
-
## Agent tools
|
|
332
|
-
|
|
333
|
-
The agent has access to these sandboxed tools inside the container:
|
|
334
|
-
|
|
335
|
-
- `read` / `write` / `edit` / `delete` — file operations
|
|
336
|
-
- `glob` / `grep` — file search
|
|
337
|
-
- `bash` — shell command execution
|
|
338
|
-
- `memory` — durable memory files (`MEMORY.md`, `USER.md`, `memory/YYYY-MM-DD.md`)
|
|
339
|
-
- `session_search` — search/summarize historical sessions from transcript archives
|
|
340
|
-
- `delegate` — push-based background subagent tasks (`single`, `parallel`, `chain`) with auto-announced completion (no polling)
|
|
341
|
-
- `web_fetch` — plain HTTP fetch + extraction for static/read-only content (docs, articles, READMEs, JSON/text APIs, direct files)
|
|
342
|
-
- `browser_*` (optional) — full browser automation for JS-rendered or interactive pages (`navigate`, `snapshot`, `click`, `type`, `upload`, `press`, `scroll`, `back`, `screenshot`, `pdf`, `close`)
|
|
343
|
-
|
|
344
|
-
`delegate` mode examples:
|
|
345
|
-
|
|
346
|
-
- single: `{ "prompt": "Audit auth middleware and list risks", "label": "auth-audit" }`
|
|
347
|
-
- parallel: `{ "mode": "parallel", "label": "module-audit", "tasks": [{ "prompt": "Scan api/" }, { "prompt": "Scan ui/" }] }`
|
|
348
|
-
- chain: `{ "mode": "chain", "label": "implement-flow", "chain": [{ "prompt": "Scout the payment module" }, { "prompt": "Plan changes from: {previous}" }, { "prompt": "Implement based on: {previous}" }] }`
|
|
349
|
-
|
|
350
|
-
Browser tooling notes:
|
|
351
|
-
|
|
352
|
-
- Routing default: prefer `web_fetch` first for read-only retrieval.
|
|
353
|
-
- Use browser tools for SPAs/web apps/auth flows/interaction tasks, or when `web_fetch` returns escalation hints (`javascript_required`, `spa_shell_only`, `empty_extraction`, `boilerplate_only`, `bot_blocked`).
|
|
354
|
-
- Cost profile: browser calls are typically ~10-100x slower/more expensive than `web_fetch`.
|
|
355
|
-
- Browser read flow: after `browser_navigate`, use `browser_snapshot` with `mode="full"` to extract content, then `browser_scroll` + `browser_snapshot` for additional lazy-loaded sections.
|
|
356
|
-
- `browser_pdf` is for export artifacts, not text extraction.
|
|
357
|
-
|
|
358
|
-
- The shipped container image preinstalls `agent-browser` and Chromium (Playwright).
|
|
359
|
-
- You can override the binary via `AGENT_BROWSER_BIN` if needed.
|
|
360
|
-
- User-directed authenticated browser-flow testing is supported (including filling/submitting login forms on the requested site).
|
|
361
|
-
- Browser auth/session state now persists per HybridClaw session by default via a dedicated profile directory under `/workspace/.hybridclaw-runtime/browser-profiles`.
|
|
362
|
-
- Session cookies/localStorage are also auto-saved/restored via `agent-browser` session-state files.
|
|
363
|
-
- Optional overrides: `BROWSER_PERSIST_PROFILE=false` (disable profile persistence), `BROWSER_PERSIST_SESSION_STATE=false` (disable state file persistence), `BROWSER_PROFILE_ROOT=/path` (custom profile root), `BROWSER_CDP_URL=ws://...` (force CDP attachment to an existing browser).
|
|
364
|
-
- Structured audit logs redact sensitive browser/tool arguments (password/token/secret fields and typed form text).
|
|
365
|
-
- Navigation to private/loopback hosts is blocked by default (set `BROWSER_ALLOW_PRIVATE_NETWORK=true` to override).
|
|
366
|
-
- Screenshot/PDF outputs are constrained to `/workspace/.browser-artifacts`.
|
|
367
|
-
|
|
368
|
-
HybridClaw also supports automatic session compaction with pre-compaction memory flush:
|
|
369
|
-
|
|
370
|
-
- when a session gets long, old turns are summarized into `session_summary`
|
|
371
|
-
- before compaction, the agent gets a `memory`-only flush turn to persist durable notes
|
|
372
|
-
- each `(agent_id, user_id)` pair also maintains a canonical cross-channel session for continuity across channels
|
|
373
|
-
- canonical context injection includes compacted summary + recent cross-channel messages (excluding the current live session)
|
|
374
|
-
- compaction writes JSONL exports to `<workspace>/.session-exports/` for human-readable debugging
|
|
375
|
-
|
|
376
|
-
System prompt assembly is handled by a formal hook pipeline:
|
|
377
|
-
|
|
378
|
-
- `bootstrap` hook (workspace bootstrap + skills metadata)
|
|
379
|
-
- `memory` hook (session summary)
|
|
380
|
-
- `safety` hook (runtime guardrails / trust-model constraints)
|
|
381
|
-
- `proactivity` hook (memory capture, session recall, delegation behavior)
|
|
382
|
-
|
|
383
|
-
Hook toggles live in `config.json` under `promptHooks`.
|
|
384
|
-
|
|
385
|
-
## Testing
|
|
386
|
-
|
|
387
|
-
Run checks locally:
|
|
388
|
-
|
|
389
|
-
```bash
|
|
390
|
-
# Typecheck only (no emit)
|
|
391
|
-
npm run typecheck
|
|
392
|
-
|
|
393
|
-
# Strict TS lint gate (unused locals/params)
|
|
394
|
-
npm run lint
|
|
395
|
-
|
|
396
|
-
# Unit tests (default `npm test`)
|
|
397
|
-
npm run test:unit
|
|
398
|
-
|
|
399
|
-
# Scoped suites (ready for dedicated tests)
|
|
400
|
-
npm run test:integration
|
|
401
|
-
npm run test:e2e
|
|
402
|
-
npm run test:live
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
Test layout and scopes:
|
|
406
|
-
|
|
407
|
-
- tests live under `tests/` (not `src/`)
|
|
408
|
-
- unit tests: `tests/**/*.test.ts` (excluding `*.integration|*.e2e|*.live`)
|
|
409
|
-
- integration tests: `tests/**/*.integration.test.ts`
|
|
410
|
-
- e2e tests: `tests/**/*.e2e.test.ts`
|
|
411
|
-
- live tests: `tests/**/*.live.test.ts`
|
|
87
|
+
- Start from `config.example.json` (reference).
|
|
88
|
+
- Runtime data is stored in `~/.hybridclaw/` by default (`config.json`, `data/hybridclaw.db`, audit/session files).
|
|
89
|
+
- On upgrade, legacy `./config.json` and `./data` are migrated to `~/.hybridclaw` automatically; backups are kept in `~/.hybridclaw/migration-backups/` when needed.
|
|
90
|
+
- `container.*` controls execution isolation, including `sandboxMode`, `memory`, `memorySwap`, `cpus`, `network`, and additional mounts.
|
|
91
|
+
- Keep secrets in `.env` (`HYBRIDAI_API_KEY` required, `DISCORD_TOKEN` optional).
|
|
92
|
+
- Trust-model acceptance is stored in `~/.hybridclaw/config.json` under `security.*` and is required before runtime starts.
|
|
93
|
+
- See [TRUST_MODEL.md](./TRUST_MODEL.md) for onboarding acceptance policy and [SECURITY.md](./SECURITY.md) for technical security guidelines.
|
|
94
|
+
- For advanced configuration, audit/observability details, skills internals, agent tools, and developer docs, see [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
412
95
|
|
|
413
96
|
## Commands
|
|
414
97
|
|
|
415
98
|
CLI runtime commands:
|
|
416
99
|
|
|
417
100
|
- `hybridclaw --version` / `-v` — Print installed HybridClaw version
|
|
418
|
-
- `hybridclaw gateway start [--foreground]` — Start gateway (backend by default; foreground with flag)
|
|
419
|
-
- `hybridclaw gateway restart [--foreground]` — Restart managed gateway backend process
|
|
101
|
+
- `hybridclaw gateway start [--foreground] [--sandbox=container|host]` — Start gateway (backend by default; foreground with flag)
|
|
102
|
+
- `hybridclaw gateway restart [--foreground] [--sandbox=container|host]` — Restart managed gateway backend process
|
|
420
103
|
- `hybridclaw gateway stop` — Stop managed gateway backend process
|
|
421
104
|
- `hybridclaw gateway status` — Show lifecycle/API status
|
|
422
105
|
- `hybridclaw gateway <command...>` — Send a command to a running gateway (for example `sessions`, `bot info`)
|
|
@@ -424,6 +107,7 @@ CLI runtime commands:
|
|
|
424
107
|
- `hybridclaw onboarding` — Run HybridAI account/API key onboarding
|
|
425
108
|
- `hybridclaw update [status|--check] [--yes]` — Check for updates and upgrade global npm installs (source checkouts get git-based update instructions)
|
|
426
109
|
- `hybridclaw audit ...` — Verify and inspect structured audit trail (`recent`, `search`, `approvals`, `verify`, `instructions`)
|
|
110
|
+
- `hybridclaw audit instructions [--sync]` — Compare runtime instruction copies under `~/.hybridclaw/instructions/` against installed sources and restore shipped defaults when needed
|
|
427
111
|
|
|
428
112
|
In Discord, use `!claw help` to see all commands. Key ones:
|
|
429
113
|
|
|
@@ -441,18 +125,3 @@ In Discord, use `!claw help` to see all commands. Key ones:
|
|
|
441
125
|
- `!claw schedule add "<cron>" <prompt>` — Add cron scheduled task
|
|
442
126
|
- `!claw schedule add at "<ISO time>" <prompt>` — Add one-shot task
|
|
443
127
|
- `!claw schedule add every <ms> <prompt>` — Add interval task
|
|
444
|
-
|
|
445
|
-
## Project structure
|
|
446
|
-
|
|
447
|
-
```
|
|
448
|
-
src/gateway.ts Core runtime entrypoint (DB, scheduler, heartbeat, HTTP API)
|
|
449
|
-
src/tui.ts Terminal adapter (thin client to gateway)
|
|
450
|
-
src/channels/discord/runtime.ts Discord runtime integration and message transport
|
|
451
|
-
src/channels/discord/*.ts Discord responsibility modules (inbound, delivery, mentions, attachments, tools, stream)
|
|
452
|
-
src/gateway-service.ts Core shared agent/session logic used by gateway API
|
|
453
|
-
src/gateway-client.ts HTTP client used by thin clients (e.g. TUI)
|
|
454
|
-
tests/ Vitest suites (unit/integration/e2e/live scopes)
|
|
455
|
-
container/src/ Agent code (tools, HybridAI client, IPC)
|
|
456
|
-
templates/ Workspace bootstrap files
|
|
457
|
-
data/ Runtime data (gitignored): SQLite DB, sessions, agent workspaces
|
|
458
|
-
```
|
package/config.example.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 6,
|
|
3
3
|
"security": {
|
|
4
4
|
"trustModelAccepted": false,
|
|
5
5
|
"trustModelAcceptedAt": "",
|
|
@@ -69,9 +69,12 @@
|
|
|
69
69
|
"models": ["gpt-5-nano", "gpt-5-mini", "gpt-5"]
|
|
70
70
|
},
|
|
71
71
|
"container": {
|
|
72
|
+
"sandboxMode": "container",
|
|
72
73
|
"image": "hybridclaw-agent",
|
|
73
74
|
"memory": "512m",
|
|
75
|
+
"memorySwap": "",
|
|
74
76
|
"cpus": "1",
|
|
77
|
+
"network": "bridge",
|
|
75
78
|
"timeoutMs": 300000,
|
|
76
79
|
"additionalMounts": "",
|
|
77
80
|
"maxOutputBytes": 10485760,
|
|
@@ -92,7 +95,7 @@
|
|
|
92
95
|
"webApiToken": "",
|
|
93
96
|
"gatewayBaseUrl": "http://127.0.0.1:9090",
|
|
94
97
|
"gatewayApiToken": "",
|
|
95
|
-
"dbPath": "data/hybridclaw.db",
|
|
98
|
+
"dbPath": "~/.hybridclaw/data/hybridclaw.db",
|
|
96
99
|
"logLevel": "info"
|
|
97
100
|
},
|
|
98
101
|
"observability": {
|
|
@@ -158,6 +161,8 @@
|
|
|
158
161
|
"description": "Runs standup summary every weekday at 9am.",
|
|
159
162
|
"schedule": {
|
|
160
163
|
"kind": "cron",
|
|
164
|
+
"at": null,
|
|
165
|
+
"everyMs": null,
|
|
161
166
|
"expr": "0 9 * * 1-5",
|
|
162
167
|
"tz": "America/New_York"
|
|
163
168
|
},
|
|
@@ -168,7 +173,8 @@
|
|
|
168
173
|
"delivery": {
|
|
169
174
|
"kind": "channel",
|
|
170
175
|
"channel": "discord",
|
|
171
|
-
"to": "123456789012345678"
|
|
176
|
+
"to": "123456789012345678",
|
|
177
|
+
"webhookUrl": ""
|
|
172
178
|
},
|
|
173
179
|
"enabled": false
|
|
174
180
|
}
|