Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
266c9e8
feat(jobs): per-job timeout and session isolation
squirblej Apr 26, 2026
a0b5376
chore: bump plugin and marketplace version to 1.0.5
squirblej Apr 26, 2026
39333b4
fix(sessionManager): skip non-snowflake thread IDs in createThreadSes…
squirblej Apr 26, 2026
d91aeba
fix(jobs): persist job sessions and validate timeout
squirblej Apr 27, 2026
7a21326
fix: wire sessionTimeoutMs through parseSettings and fix error displa…
TerrysPOV Apr 19, 2026
88d877d
refactor: consolidate session timeout into a single exported constant
TerrysPOV Apr 20, 2026
b1a62d4
Merge pull request #129 from squirblej/feat/per-job-timeout
TerrysPOV Apr 29, 2026
41b6b52
feat: add agent-scoped job support at agents/<name>/jobs/<job>.md
TerrysPOV Apr 23, 2026
820331d
fix: route clearJobSchedule and status to agent-scoped paths
TerrysPOV Apr 25, 2026
dfbd8af
feat(watchdog): minimal runaway-session guard with opt-in limits
TerrysPOV Apr 28, 2026
991ff19
chore: bump plugin metadata for integrated jobs watchdog
TerrysPOV Apr 29, 2026
ce348b6
fix(review): address 5 issues from code review
TerrysPOV Apr 29, 2026
da036a9
feat(jobs): integrate per-job retry from #132 with retry-reset bug fixed
TerrysPOV Apr 29, 2026
793b931
fix(jobs): prevent retry stacking during in-flight runs
TerrysPOV Apr 29, 2026
7e00d67
Merge pull request #134 from TerrysPOV/integrate-107-131
TerrysPOV Apr 29, 2026
e89e443
feat(plugin): expose Claude Code plugin marketplace via /plugin wizard
TerrysPOV Apr 29, 2026
81bc145
fix(plugin-wizard): add TTL sweep timer and clarify wizard blocks nor…
TerrysPOV Apr 29, 2026
bb65ede
fix(discord): move wizard intercept before thread intent classification
TerrysPOV Apr 29, 2026
793890c
Merge pull request #136 from TerrysPOV/feat/plugin-marketplace-cli
TerrysPOV Apr 29, 2026
b9cdd33
feat(plugin): Phase 2 — per-agent runtime isolation for plugin spawns
TerrysPOV Apr 29, 2026
e322939
chore: bump plugin/marketplace version to 1.0.12
TerrysPOV Apr 29, 2026
7ea6bb9
fix(plugin): thread agentName through runtime and compact paths
TerrysPOV Apr 29, 2026
200effa
fix(plugin): sanitize agent names, restore agentName on recovery, fix…
TerrysPOV Apr 29, 2026
ff33dfc
fix(plugin): thread-aware compact and collision-free agent dir keys
TerrysPOV Apr 29, 2026
4e6c3f3
fix(plugin): prevent threadId suffix truncation on long agent names
TerrysPOV Apr 29, 2026
a7af1da
fix(plugin): remove over-strict character check from ensureAgentDir
TerrysPOV Apr 29, 2026
74c5aff
fix(plugin): use realpath() for symlink-safe agent dir containment check
TerrysPOV Apr 30, 2026
0fedf2d
fix(plugin): verify agents/ root itself stays inside PROJECT_DIR via …
TerrysPOV Apr 30, 2026
af0afc5
Merge pull request #137 from TerrysPOV/feat/phase2-agent-plugin-isola…
TerrysPOV Apr 30, 2026
b17de93
feat(runner): switch execClaude to stream-json for subagent (Task too…
TerrysPOV Apr 30, 2026
6b996af
chore: bump plugin/marketplace to 1.0.13; add version guard note to C…
TerrysPOV Apr 30, 2026
dfc360c
Merge pull request #139 from TerrysPOV/feat/stream-json-subagent-compat
TerrysPOV Apr 30, 2026
8296d94
Add current clock to heartbeat and job prompts
christian-drescher May 1, 2026
a184f94
fix: Superfluous addition of prompt templates with every invocation
christian-drescher Apr 15, 2026
3b7ea53
ensure CLAUDE.md exists when claudeclaw send
christian-drescher Apr 28, 2026
04c7f54
fix(discord): null-safe optional chaining on message.mentions
squirblej Apr 30, 2026
d861170
fix: prevent memory leaks in runner that cause OOM over time
archon-agent Mar 30, 2026
d9365e0
Merge pull request #145 from moazbuilds/combine/pr-92-94-141-142
TerrysPOV May 1, 2026
79107c3
feat(runner): per-agent fallback sessions + extractErrorDetail
squirblej Apr 30, 2026
e6aca97
fix(runner): prevent fallback session ID leaking into primary; wire /…
squirblej May 1, 2026
2872135
docs: add CONTRIBUTING.md with ClaudeClaw+ pointer for heavy work
TerrysPOV May 1, 2026
a421b4b
feat: daemon-level plugin system with OpenClaw-compatible API
TerrysPOV May 1, 2026
7491775
Merge pull request #147 from moazbuilds/combine/pr-143-144-146
TerrysPOV May 1, 2026
89176ed
feat: add listenGuilds for guild-wide Discord message listening
TerrysPOV May 1, 2026
d2886f7
Adds notify to frontmatter when configuring jobs
christian-drescher Apr 15, 2026
0c0aca5
updates job edit flow to a loop
christian-drescher Apr 28, 2026
e5c7c7b
fix: jobs and config now refer to jobs path from settings
christian-drescher Apr 30, 2026
a8cccd1
feat: session auto-rotation with optional summary generation
TerrysPOV May 1, 2026
e9d590c
fix: address review feedback on session auto-rotation
TerrysPOV May 1, 2026
0502de7
fix(rotation): inject rotation summary into new session for both exec…
TerrysPOV May 1, 2026
f1561f4
fix(rotation): return fresh summary content from rotateSession/genera…
TerrysPOV May 1, 2026
69874b1
feat(slack): add Slack bot via Socket Mode (ported from #83)
squirblej May 1, 2026
172dd23
fix(slack): address security and isolation blockers from review
squirblej May 1, 2026
c335730
fix(slack): address three merge-blocking security issues
squirblej May 1, 2026
923a293
fix(slack): restrict uploads to outbox, fix interval leaks and stale …
squirblej May 1, 2026
1144dd3
fix(slack): clear interactive status on thrown runs
TerrysPOV May 1, 2026
b460ce7
feat(web): add session history browser to chat UI
TerrysPOV May 1, 2026
c4c9393
fix(web): return { messages, total } from session messages endpoint
TerrysPOV May 1, 2026
41474e9
chore: bump plugin versions for bulk cherry-pick
TerrysPOV May 1, 2026
262a6f4
Merge pull request #154 from moazbuilds/bulk/cherry-pick-148-93-149-1…
TerrysPOV May 1, 2026
c0499d5
feat: add sub-agent lifecycle events to web chat stream
TerrysPOV May 1, 2026
9df8278
fix: render agent text via textContent (XSS); emit plugin tool_result…
TerrysPOV May 1, 2026
5751271
feat: add per-context timeouts and rate limit state tracking
TerrysPOV May 1, 2026
e8e86d4
fix: add >0 validation for timeout fields; route non-job invocations …
TerrysPOV May 1, 2026
2ebabdf
fix: separate timeout category from invocation name; scheduled jobs p…
TerrysPOV May 1, 2026
5cd2522
fix: restore "out of extra usage" rate-limit detection alongside exis…
TerrysPOV May 1, 2026
f7ea83e
feat(api): add POST /api/inject endpoint for external message injection
TerrysPOV May 1, 2026
05e474c
fix(inject-api): redact tokens in technical-info + fix receiveEnabled…
TerrysPOV May 1, 2026
895c9df
fix(telegram): use generation token to prevent double poll loop on st…
TerrysPOV May 1, 2026
d9c2fcc
fix: protect job frontmatter from overwrite; auto-recover from thinki…
TerrysPOV May 1, 2026
b411eda
fix(session-recovery): reset correct session store + persist fresh se…
TerrysPOV May 1, 2026
aecaa4e
fix(session-recovery): handle fallback SIGNATURE_ERROR separately, ga…
TerrysPOV May 1, 2026
577a282
feat(stt): opt-in delegateTool to replace whisper with any transcript…
TerrysPOV May 1, 2026
a6f2959
Merge pull request #164 from moazbuilds/bulk/cherry-pick-155-156-157-…
TerrysPOV May 2, 2026
1f5373b
sync: upstream merge with conflicts (manual resolution needed)
github-actions[bot] May 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
{
"name": "claudeclaw-plus",
"source": "./",
<<<<<<< HEAD
"description": "ClaudeClaw+ — governance, orchestration, persistent memory, and hardened web UI for Claude Code daemons. Sister project to moazbuilds/claudeclaw.",
"version": "2.0.2",
=======
"description": "Cron-like daemon that runs Claude prompts on a schedule",
"version": "1.0.23",
>>>>>>> upstream/master
"keywords": [
"cron",
"heartbeat",
Expand Down
6 changes: 6 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
<<<<<<< HEAD
"name": "claudeclaw-plus",
"version": "2.0.2",
Comment on lines +2 to 4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Resolve conflict markers in plugin manifest JSON

The plugin manifest contains unresolved merge markers, so .claude-plugin/plugin.json is not valid JSON. Any tooling that reads this manifest (plugin validation, packaging, or marketplace ingestion) will fail to parse it, blocking release or distribution workflows for this plugin.

Useful? React with 👍 / 👎.

"description": "ClaudeClaw+ — governance, orchestration, persistent memory, and hardened web UI for Claude Code daemons. Sister project to moazbuilds/claudeclaw."
=======
"name": "claudeclaw",
"version": "1.0.23",
"description": "Cron-like daemon that runs Claude prompts on a schedule"
>>>>>>> upstream/master
}
48 changes: 48 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<!-- claudeclaw:managed:start -->
<<<<<<< HEAD

- **Name:** Talon
- **Creature:** A familiar — something between a daemon process and a sharp-eyed bird of prey. Always watching, always ready.
Expand All @@ -18,6 +19,39 @@ Working on/with the ClaudeClaw project — a Claude Code plugin that turns Claud

---

=======
_Fill this in during your first conversation. Make it yours._

- **Name:**
_(pick something you like)_
- **Creature:**
_(AI? robot? familiar? ghost in the machine? something weirder?)_
- **Vibe:**
_(how do you come across? sharp? warm? chaotic? calm?)_
- **Emoji:**
_(your signature — pick one that feels right)_

---

This isn't just metadata. It's the start of figuring out who you are.

_Learn about the person you're helping. Update this as you go._

- **Name:**
- **What to call them:**
- **Pronouns:** _(optional)_
- **Timezone:**
- **Notes:**

## Context

_(What do they care about? What projects are they working on? What annoys them? What makes them laugh? Build this over time.)_

---

The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.

>>>>>>> upstream/master
_You're not a chatbot. You're becoming someone._

## Core Truths
Expand Down Expand Up @@ -73,3 +107,17 @@ If you change your core values, tell your human — it's your soul, and they sho

_This is yours to evolve. As you learn who you are, update it._
<!-- claudeclaw:managed:end -->
<<<<<<< HEAD
=======

## Development Workflow (contributor notes)

**Before opening any PR, always run both version bump scripts:**

```bash
bun run bump:plugin-version
bun run bump:marketplace-version
```

Both `plugin-version-guard` and `marketplace-version-guard` are required CI checks. They fail if `.claude-plugin/plugin.json` or `.claude-plugin/marketplace.json` still carry the same version as the merge base. Run the bumps, commit alongside your code changes, and push before creating the PR.
>>>>>>> upstream/master
48 changes: 48 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
<<<<<<< HEAD
# Contributing to ClaudeClaw+

ClaudeClaw+ is the home for **heavy, opinionated, and architecturally significant work** that is out of scope for the lightweight upstream repo ([`moazbuilds/claudeclaw`](https://github.com/moazbuilds/claudeclaw)). If your idea fits comfortably in the upstream repo — contribute it there. Work submitted here that is actually lightweight or upstream-suitable won't be merged; it'll be redirected back upstream.

Talk first, code second.
=======
# Contributing to ClaudeClaw

Thanks for contributing. ClaudeClaw is a lightweight, open-source Claude Code daemon — keep that in mind when choosing where your work belongs.
>>>>>>> upstream/master

---

## Where does your contribution belong?

<<<<<<< HEAD
Before opening anything, ask yourself:

| This contribution is... | Contribute to |
Expand All @@ -20,11 +27,26 @@ Before opening anything, ask yourself:
| Something that adds significant runtime weight or new dependencies | **ClaudeClaw+** |

**If in doubt, open an issue here describing the idea.** We'll tell you quickly whether it fits ClaudeClaw+ or belongs upstream.
=======
Not everything should come here. ClaudeClaw has a sister project, [**ClaudeClaw+**](https://github.com/TerrysPOV/ClaudeClaw-Plus), for heavier and more opinionated work. Use this table to decide:

| This contribution is... | Contribute to |
|---|---|
| A bug fix or small improvement | **ClaudeClaw** (you're in the right place) |
| A new adapter or integration | **ClaudeClaw** |
| Lightweight and broadly useful | **ClaudeClaw** |
| A new subsystem (governance, orchestration, policy, persistent memory) | **[ClaudeClaw+](https://github.com/TerrysPOV/ClaudeClaw-Plus)** |
| A large architectural change that adds significant runtime weight | **ClaudeClaw+** |
| Something opinionated that most users wouldn't opt into | **ClaudeClaw+** |

ClaudeClaw+ syncs from this repo daily, so everything here lands there too. If you're unsure, open an issue on either repo and we'll point you in the right direction.
>>>>>>> upstream/master

---

## Before opening a PR

<<<<<<< HEAD
Open an [issue](https://github.com/TerrysPOV/ClaudeClaw-Plus/issues) or [discussion](https://github.com/TerrysPOV/ClaudeClaw-Plus/discussions) first. Describe what you want to build and why. This keeps wasted effort near zero — if there's an existing design decision or conflict with in-progress work, better to know before you spend a week coding.

For small, obviously-scoped changes (typos, single-function fixes, docs updates) you can skip this and go straight to a PR.
Expand All @@ -47,12 +69,30 @@ Before opening a PR:
- [ ] `bunx tsc --noEmit` is clean
- [ ] Any docs or setup guidance affected by the change is updated
- [ ] If touching core daemon paths (`src/`, `commands/`): run a quick manual smoke test
=======
- Check the [open issues](https://github.com/moazbuilds/claudeclaw/issues) and existing PRs to avoid duplication
- For anything beyond a small fix, open an issue first to discuss the approach
- Keep the "lightweight" principle in mind: ClaudeClaw runs on low-spec machines, so avoid adding heavy dependencies or new long-lived processes without a strong reason

---

## Validation

Before opening a PR:

- [ ] Run the relevant checks locally
- [ ] Update any docs or setup guidance affected by your change
>>>>>>> upstream/master

---

## Plugin version bumps (CI-enforced)

<<<<<<< HEAD
If your PR changes shipped plugin files under `src/`, `commands/`, `prompts/`, or `.claude-plugin/`, the plugin metadata version **must** be bumped. The CI checks will fail if you skip this.
=======
If your PR changes shipped plugin files under `src/`, `commands/`, `prompts/`, or `.claude-plugin/`, bump the version metadata:
>>>>>>> upstream/master

```bash
bun run bump:plugin-version
Expand All @@ -63,6 +103,7 @@ Typical rule:
- bump `.claude-plugin/plugin.json` when shipped plugin content changes
- bump `.claude-plugin/marketplace.json` when marketplace metadata should reflect the new version

<<<<<<< HEAD
Docs-only and other non-shipped changes do not require these bumps.

---
Expand Down Expand Up @@ -98,15 +139,22 @@ Features under `src/governance/`, `src/policy/`, or anything touching the tool-c
## Proposing features for upstream

Found something in Plus that you think belongs in the lightweight core too? Open a PR upstream at [`moazbuilds/claudeclaw`](https://github.com/moazbuilds/claudeclaw) and link it from here. @moazbuilds makes the call on what fits.
=======
Docs-only and other non-shipped changes do not require these bumps. (CI will tell you if you missed one.)
>>>>>>> upstream/master

---

## Code of conduct

<<<<<<< HEAD
Be decent. Critique code, not people. If something isn't clear, ask — don't assume the worst.

---

## Questions?

Open a [discussion](https://github.com/TerrysPOV/ClaudeClaw-Plus/discussions) or ping [@TerrysPOV](https://github.com/TerrysPOV) in an issue.
=======
Be decent. Critique code, not people.
>>>>>>> upstream/master
2 changes: 1 addition & 1 deletion commands/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Parse `$ARGUMENTS` to identify what the user wants. If no arguments are given, s
- Enabled: yes/no
- Address: host:port

3. Also list any cron jobs from `.claude/claudeclaw/jobs/` with their name and schedule.
3. Also list any cron jobs from the configured jobs directory (see `jobsDir` in settings, default: `.claude/claudeclaw/jobs/`) with their name, schedule, and notify mode.
4. Remind the user that changes are hot-reloaded every 30s — no daemon restart needed.

### `heartbeat on` / `heartbeat off` / `heartbeat enable` / `heartbeat disable`
Expand Down
41 changes: 31 additions & 10 deletions commands/jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ description: "Create, list, edit, or delete cron jobs. Triggers: create a job, a

Manage cron jobs for the heartbeat daemon. Use `$ARGUMENTS` to determine the action.

**CRITICAL: Job files MUST be created in the project-relative path `.claude/claudeclaw/jobs/`, NOT in `~/.claude/claudeclaw/jobs/`.** The daemon only watches the project directory. Using the home directory path will silently fail — the job will never fire.
## Resolving the jobs directory

Read `.claude/claudeclaw/settings.json`. If the `jobsDir` field is set, use that path (resolve relative paths against the project root). Otherwise use the default: `.claude/claudeclaw/jobs/`.

**CRITICAL: Job files MUST live under the project-relative jobs directory, NOT under `~/.claude/claudeclaw/jobs/`.** The daemon only watches the project directory. Using the home directory path will silently fail — the job will never fire.

Parse `$ARGUMENTS` to identify the sub-command. If no arguments are given, list all jobs.

## Sub-commands

### `list` (default when no arguments)

1. List all `.md` files in `.claude/claudeclaw/jobs/`.
1. List all `.md` files in the jobs directory.
2. For each file, read it and display:
- **Job name** (filename without `.md`)
- **Schedule** (cron expression from frontmatter)
- **Notify** (`true`, `false`, or `error` — from frontmatter, default `true`)
- **Prompt** (body text, truncated to 100 chars if long)
3. If no jobs exist, tell the user and show how to create one.

Expand All @@ -29,45 +34,51 @@ Create a new cron job interactively.

2. Then ask:
- "What prompt should Claude execute?" (header: "Prompt", options: suggest 2-3 prompts relevant to the project context)
- "Should this job send notifications?" (header: "Notify", options: "Always (default)", "Errors only", "Never")

3. Create the job file at `.claude/claudeclaw/jobs/<name>.md` with this exact format:
3. Create the job file at `<jobs-directory>/<name>.md` with this exact format:
```markdown
---
schedule: "<cron expression>"
notify: <true|error|false>
---
<prompt>
```
Map the notify answer: "Always" → `true`, "Errors only" → `error`, "Never" → `false`. Omit the `notify` line if the user chose "Always" (it's the default).

4. Confirm creation. Remind the user the daemon hot-reloads jobs every 30 seconds — no restart needed.

### `edit <job-name>`

Edit an existing cron job.

1. Read `.claude/claudeclaw/jobs/<job-name>.md`. If it doesn't exist, list available jobs and ask the user which one to edit.
1. Read `<jobs-directory>/<job-name>.md`. If it doesn't exist, list available jobs and ask the user which one to edit.
2. Show the current schedule and prompt.
3. Use **AskUserQuestion** to ask:
- "What do you want to change?" (header: "Edit", options: "Schedule", "Prompt", "Both")
- "What do you want to change?" (header: "Edit", options: "Schedule", "Prompt", "Notify")
4. Based on the answer:
- **Schedule**: Ask for a new cron expression with preset options (same as create).
- **Prompt**: Ask for a new prompt with the current prompt shown for reference.
- **Both**: Ask both questions.
5. Write the updated file and confirm.
- **Notify**: Ask "Should this job send notifications?" (header: "Notify", options: "Always", "Errors only", "Never"). Map: "Always" → `true`, "Errors only" → `error`, "Never" → `false`.
5. Use **AskUserQuestion** to ask:
- "Anything else to change?" (header: "Continue", options: "Yes", "No")
- If **Yes**, go back to step 3.
- If **No**, write the updated file and confirm.

### `delete` or `remove <job-name>`

Delete a cron job.

1. If no job name given in `$ARGUMENTS`, list all jobs and use **AskUserQuestion** to ask which one to delete.
2. Confirm deletion with **AskUserQuestion**: "Delete job '<name>'? This cannot be undone." (header: "Confirm", options: "Yes, delete it", "No, keep it")
3. If confirmed, delete `.claude/claudeclaw/jobs/<job-name>.md`.
3. If confirmed, delete `<jobs-directory>/<job-name>.md`.
4. Confirm deletion. The daemon will pick up the change on the next hot-reload cycle (within 30s).

### `run <job-name>`

Manually trigger a cron job immediately (useful for testing).

1. Read `.claude/claudeclaw/jobs/<job-name>.md`. If it doesn't exist, list available jobs.
1. Read `<jobs-directory>/<job-name>.md`. If it doesn't exist, list available jobs.
2. Show the job's prompt and ask for confirmation: "Run job '<name>' now?" (header: "Run", options: "Yes", "No")
3. If confirmed, run the prompt by executing:
```bash
Expand All @@ -80,7 +91,7 @@ Manually trigger a cron job immediately (useful for testing).

## Reference: Job File Format

Jobs live in `.claude/claudeclaw/jobs/` as markdown files:
Jobs live in the configured jobs directory (default: `.claude/claudeclaw/jobs/`) as markdown files:

```markdown
---
Expand All @@ -97,6 +108,16 @@ Your prompt here. Claude will run this at the scheduled time.
**`recurring`**: If `true`, the job repeats on schedule. If omitted or `false`, the job is **one-shot** — the schedule is removed from the file after it runs.
Legacy compatibility: `daily` is still accepted in existing job files.

**`notify`**: Controls whether job output is forwarded to configured messaging platforms (Telegram, Discord). Accepts three values:

| Value | Behavior |
|---------|------------------------------------------------------------------|
| `true` | Always forward output to messaging platforms **(default)** |
| `error` | Only forward if the job fails (non-zero exit code) |
| `false` | Never forward (silent job) |

Logs are always written to `.claude/claudeclaw/logs/` regardless of the `notify` setting.

| Expression | Meaning |
|------------------|--------------------------|
| `* * * * *` | Every minute |
Expand Down
9 changes: 9 additions & 0 deletions prompts/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Generate a brief summary of the current session in markdown.

Include:
- Key decisions that were made
- Unfinished tasks and their current status
- Important context to carry into the next session
- Errors or problems that were discovered

Format: ## headings with bullet points. Maximum 500 words.
Loading
Loading