@codefilabs/tq 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -0
- package/package.json +41 -0
- package/scripts/tq +419 -0
- package/scripts/tq-install.sh +78 -0
- package/scripts/tq-message +318 -0
- package/scripts/tq-setup +147 -0
- package/scripts/tq-telegram-poll +129 -0
- package/scripts/tq-telegram-watchdog +23 -0
- package/skills/tq/SKILL.md +108 -0
- package/skills/tq/references/cron-expressions.md +67 -0
- package/skills/tq/references/session-naming.md +50 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tq
|
|
3
|
+
description: >
|
|
4
|
+
This skill should be used when the user asks to "add to queue", "run queue", "queue these tasks",
|
|
5
|
+
"schedule with tq", "tq status", "check task queue", "create a tq queue", "set up cron for tq",
|
|
6
|
+
"run claude in background", "batch prompts in tmux", or wants to manage Claude prompts running
|
|
7
|
+
in tmux sessions via the tq CLI tool. Triggers on phrases like "queue", "tq", "task queue",
|
|
8
|
+
"tmux queue", "scheduled claude tasks".
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# tq — Claude Task Queue Runner
|
|
13
|
+
|
|
14
|
+
Script: `${CLAUDE_PLUGIN_ROOT}/scripts/tq`
|
|
15
|
+
|
|
16
|
+
Installed to PATH via `/install`: `/opt/homebrew/bin/tq`
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
tq batches Claude prompts into YAML queue files and spawns each as an independent tmux session.
|
|
21
|
+
Tasks are idempotent — running `tq` again skips `done` and live `running` tasks.
|
|
22
|
+
|
|
23
|
+
## Queue File Format
|
|
24
|
+
|
|
25
|
+
Location: `~/.tq/queues/<name>.yaml`
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
cwd: /path/to/working/directory # optional — where claude runs for each task
|
|
29
|
+
tasks:
|
|
30
|
+
- prompt: fix the login bug in auth service
|
|
31
|
+
- prompt: write unit tests for payment module
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Queue files are **read-only** — tq never modifies them.
|
|
35
|
+
|
|
36
|
+
## State
|
|
37
|
+
|
|
38
|
+
State dir: `~/.tq/queues/.tq/<queue-basename>/`
|
|
39
|
+
One file per task, named by 8-char shasum of the prompt:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
status=running
|
|
43
|
+
session=fix-the-login-23451
|
|
44
|
+
window=fix-the
|
|
45
|
+
prompt=fix the login bug in auth service
|
|
46
|
+
started=2026-03-05T10:00:00
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Statuses: `pending` → `running` → `done`
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
| Command | Purpose |
|
|
54
|
+
|---------|---------|
|
|
55
|
+
| `/todo <natural language>` | Create/update queue + optionally schedule |
|
|
56
|
+
| `/schedule <natural language>` | Add/update cron schedule for a queue |
|
|
57
|
+
| `/pause <queue>` | Remove run line, keep status-check (resume with `/schedule`) |
|
|
58
|
+
| `/unschedule <queue>` | Remove all cron lines for a queue |
|
|
59
|
+
| `/jobs [filter]` | List all scheduled tq cron jobs |
|
|
60
|
+
| `/health [queue]` | System-wide diagnostics |
|
|
61
|
+
| `/install` | Symlink tq binaries to PATH |
|
|
62
|
+
|
|
63
|
+
## CLI Usage
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
tq <queue.yaml> # spawn pending tasks in tmux; skip running/done
|
|
67
|
+
tq --status <queue.yaml> # print status table; flip dead sessions to done
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Crontab Pattern
|
|
71
|
+
|
|
72
|
+
```cron
|
|
73
|
+
0 9 * * * /opt/homebrew/bin/tq ~/.tq/queues/morning.yaml >> ~/.tq/logs/tq.log 2>&1
|
|
74
|
+
*/30 * * * * /opt/homebrew/bin/tq --status ~/.tq/queues/morning.yaml >> ~/.tq/logs/tq.log 2>&1
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The `tq --status` cron runs every 30 min to reap dead sessions and flip their state to `done`.
|
|
78
|
+
|
|
79
|
+
## Queue Name Inference
|
|
80
|
+
|
|
81
|
+
When using `/todo` without an explicit queue name:
|
|
82
|
+
|
|
83
|
+
- Schedule keyword present → use it: "every morning" → `morning`, "daily" → `daily`, "weekly" → `weekly`
|
|
84
|
+
- No schedule → use `basename` of current working directory
|
|
85
|
+
|
|
86
|
+
## Reset
|
|
87
|
+
|
|
88
|
+
- One task: delete its state file from `.tq/<queue-basename>/`
|
|
89
|
+
- Entire queue: `rm -rf ~/.tq/queues/.tq/<queue-basename>/`
|
|
90
|
+
|
|
91
|
+
## Chrome Integration
|
|
92
|
+
|
|
93
|
+
tq launches claude with `--chrome` and opens **Chrome Profile 5** (halbotkirchner@gmail.com) automatically before connecting.
|
|
94
|
+
|
|
95
|
+
### Multiple Chrome profiles / extensions
|
|
96
|
+
|
|
97
|
+
If you need to interact with a Chrome profile that has a different Claude extension instance (e.g. different account), use the `chrome-devtools` MCP with the `--isolated` flag to run isolated browser extension sessions that don't conflict across profiles.
|
|
98
|
+
|
|
99
|
+
### Setting the browser display name
|
|
100
|
+
|
|
101
|
+
The Claude extension stores the browser name as `bridgeDisplayName` in the extension's `chrome.storage.local`. To set it for the first time on a profile:
|
|
102
|
+
- Right-click the Claude extension icon in the Chrome toolbar → **Options**
|
|
103
|
+
- Or open the sidepanel and look for a settings/gear icon with a name field
|
|
104
|
+
|
|
105
|
+
## Additional Resources
|
|
106
|
+
|
|
107
|
+
- **`references/session-naming.md`** — Session/window name generation algorithm and examples
|
|
108
|
+
- **`references/cron-expressions.md`** — Natural language → cron expression mapping table
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# tq Cron Expression Reference
|
|
2
|
+
|
|
3
|
+
## Natural Language → Cron Mapping
|
|
4
|
+
|
|
5
|
+
| Natural Language | Cron Expression | Notes |
|
|
6
|
+
|-----------------|-----------------|-------|
|
|
7
|
+
| "every morning" / "daily at 9am" | `0 9 * * *` | Default morning time |
|
|
8
|
+
| "every night" / "nightly" | `0 22 * * *` | 10pm |
|
|
9
|
+
| "every weekday" | `0 9 * * 1-5` | Mon–Fri at 9am |
|
|
10
|
+
| "every weekday at 6pm" | `0 18 * * 1-5` | Mon–Fri at 6pm |
|
|
11
|
+
| "every monday" / "weekly on mondays" | `0 9 * * 1` | 9am Monday |
|
|
12
|
+
| "every monday at 8am" | `0 8 * * 1` | 8am Monday |
|
|
13
|
+
| "every hour" / "hourly" | `0 * * * *` | Top of each hour |
|
|
14
|
+
| "every 4 hours" | `0 */4 * * *` | Every 4 hours |
|
|
15
|
+
| "every 30 minutes" | `*/30 * * * *` | Every 30 min |
|
|
16
|
+
| "daily" | `0 9 * * *` | Default to 9am |
|
|
17
|
+
| "weekly" | `0 9 * * 1` | Default to Monday 9am |
|
|
18
|
+
|
|
19
|
+
## Day-of-Week Numbers
|
|
20
|
+
|
|
21
|
+
| Number | Day |
|
|
22
|
+
|--------|-----|
|
|
23
|
+
| 0 or 7 | Sunday |
|
|
24
|
+
| 1 | Monday |
|
|
25
|
+
| 2 | Tuesday |
|
|
26
|
+
| 3 | Wednesday |
|
|
27
|
+
| 4 | Thursday |
|
|
28
|
+
| 5 | Friday |
|
|
29
|
+
| 6 | Saturday |
|
|
30
|
+
|
|
31
|
+
## Standard tq Crontab Block
|
|
32
|
+
|
|
33
|
+
Every scheduled queue gets two cron lines:
|
|
34
|
+
|
|
35
|
+
```cron
|
|
36
|
+
# Run queue (spawn pending tasks)
|
|
37
|
+
<cron> /opt/homebrew/bin/tq ~/.tq/queues/<name>.yaml >> ~/.tq/logs/tq.log 2>&1
|
|
38
|
+
|
|
39
|
+
# Status sweep (reap dead sessions every 30 min)
|
|
40
|
+
*/30 * * * * /opt/homebrew/bin/tq --status ~/.tq/queues/<name>.yaml >> ~/.tq/logs/tq.log 2>&1
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Updating Crontab
|
|
44
|
+
|
|
45
|
+
Replace existing lines for the same queue:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
(crontab -l 2>/dev/null | grep -v "tq.*<name>.yaml"; \
|
|
49
|
+
echo "<cron> /opt/homebrew/bin/tq ~/.tq/queues/<name>.yaml >> ~/.tq/logs/tq.log 2>&1"; \
|
|
50
|
+
echo "*/30 * * * * /opt/homebrew/bin/tq --status ~/.tq/queues/<name>.yaml >> ~/.tq/logs/tq.log 2>&1") | crontab -
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The `grep -v` removes all existing lines referencing this queue before appending the new ones, ensuring no duplicates.
|
|
54
|
+
|
|
55
|
+
## Queue Name → Schedule Name Inference
|
|
56
|
+
|
|
57
|
+
When no queue name is given, infer from the schedule keyword:
|
|
58
|
+
|
|
59
|
+
| Schedule keyword | Queue name |
|
|
60
|
+
|-----------------|------------|
|
|
61
|
+
| "morning" / "9am" | `morning` |
|
|
62
|
+
| "daily" | `daily` |
|
|
63
|
+
| "weekday" / "weekdays" | `weekday` |
|
|
64
|
+
| "weekly" / "monday" | `weekly` |
|
|
65
|
+
| "hourly" / "every hour" | `hourly` |
|
|
66
|
+
| "nightly" / "night" | `nightly` |
|
|
67
|
+
| no schedule | `basename` of current working directory |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# tq Session Naming Reference
|
|
2
|
+
|
|
3
|
+
## Algorithm
|
|
4
|
+
|
|
5
|
+
Given a prompt string, derive a tmux session name and window name as follows:
|
|
6
|
+
|
|
7
|
+
### Session Name
|
|
8
|
+
1. Take the first 3 words of the prompt
|
|
9
|
+
2. Lowercase everything
|
|
10
|
+
3. Replace any non-`[a-z0-9]` character with `-`
|
|
11
|
+
4. Strip trailing `-` characters
|
|
12
|
+
5. Truncate to 20 characters
|
|
13
|
+
6. Append `-<epoch-suffix>` (last 6 digits of Unix epoch)
|
|
14
|
+
|
|
15
|
+
### Window Name
|
|
16
|
+
1. Take the first 2 words of the prompt
|
|
17
|
+
2. Same lowercasing and character replacement as above
|
|
18
|
+
3. Truncate to 15 characters (no epoch suffix)
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
| Prompt | Session | Window |
|
|
23
|
+
|--------|---------|--------|
|
|
24
|
+
| `fix the login bug in auth service` | `fix-the-login-<epoch>` | `fix-the` |
|
|
25
|
+
| `write unit tests for payment module` | `write-unit-tests-<epoch>` | `write-unit` |
|
|
26
|
+
| `Refactor Auth Module` | `refactor-auth-module-<epoch>` | `refactor-auth` |
|
|
27
|
+
| `check LinkedIn saved posts` | `check-linkedin-saved-<epoch>` | `check-linkedin` |
|
|
28
|
+
|
|
29
|
+
## Bash Implementation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
EPOCH_SUFFIX="$(date +%s | tail -c 6)"
|
|
33
|
+
SESSION_BASE="$(echo "$PROMPT" | awk '{print $1" "$2" "$3}' \
|
|
34
|
+
| tr '[:upper:]' '[:lower:]' \
|
|
35
|
+
| tr -cs 'a-z0-9' '-' \
|
|
36
|
+
| sed 's/-*$//' \
|
|
37
|
+
| cut -c1-20)"
|
|
38
|
+
SESSION="${SESSION_BASE}-${EPOCH_SUFFIX}"
|
|
39
|
+
WINDOW="$(echo "$PROMPT" | awk '{print $1" "$2}' \
|
|
40
|
+
| tr '[:upper:]' '[:lower:]' \
|
|
41
|
+
| tr -cs 'a-z0-9' '-' \
|
|
42
|
+
| sed 's/-*$//' \
|
|
43
|
+
| cut -c1-15)"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Notes
|
|
47
|
+
|
|
48
|
+
- Epoch suffix prevents collision when the same prompt is re-queued after a reset
|
|
49
|
+
- tmux session names must not contain `.` or `:` — the character replacement handles this
|
|
50
|
+
- The `-` separator between base and epoch is always present; if the base ends with `-`, it gets stripped first to avoid `--`
|