@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 ADDED
@@ -0,0 +1,296 @@
1
+ # tq — Task Queue for Claude
2
+
3
+ A lightweight task queue runner that spawns Claude AI tasks as independent tmux sessions.
4
+
5
+ ## What It Does
6
+
7
+ `tq` lets you define a list of Claude prompts in a YAML file and run them all as independent background jobs. Each prompt gets its own named tmux session running the `claude` CLI — you can attach to any session to watch progress, and detach without interrupting the work.
8
+
9
+ Tasks are idempotent: running `tq queue.yaml` again skips tasks that are already `done` or have a live `running` session. Task identity is derived from a SHA-256 hash of the prompt content, so changing a prompt text treats it as a new task while re-running unchanged prompts is always a no-op.
10
+
11
+ The tool is designed for macOS with cron scheduling in mind: drop a queue YAML in `~/.tq/queues/`, add a crontab line, and tasks run automatically every morning (or on whatever schedule you choose). Run `tq --status` to reap dead sessions and print a status table.
12
+
13
+ ## Requirements
14
+
15
+ - macOS (uses `security` CLI for keychain access to Claude OAuth tokens)
16
+ - tmux (`brew install tmux`)
17
+ - `claude` CLI — [Claude Code](https://claude.ai/code) (`npm install -g @anthropic-ai/claude-code` or similar)
18
+ - python3 (macOS system Python is sufficient — stdlib only, no pip installs needed)
19
+ - Google Chrome with Claude Code extension installed
20
+ - `reattach-to-user-namespace` (optional, `brew install reattach-to-user-namespace` — fixes keychain access in tmux)
21
+
22
+ ## Installation
23
+
24
+ Run this in your terminal:
25
+
26
+ ```bash
27
+ curl -fsSL https://raw.githubusercontent.com/kevnk/tq/main/scripts/tq-install.sh | bash
28
+ ```
29
+
30
+ Here's exactly what that command does:
31
+
32
+ 1. **Downloads the install script** from this repo over HTTPS (`-fsSL` = fail on error, silent, follow redirects) and pipes it directly to `bash` — nothing is saved to disk.
33
+
34
+ 2. **Registers the tq marketplace** with Claude Code by running `claude plugin marketplace add kevnk/tq`. This clones the tq repo into `~/.claude/plugins/marketplaces/tq/` so Claude knows where to find it.
35
+
36
+ 3. **Installs the tq plugin** by running `claude plugin install tq@tq`. This caches the plugin files into `~/.claude/plugins/cache/tq/tq/<version>/` and registers the plugin's skills and slash commands with Claude Code. After this, Claude will recognize commands like `/todo`, `/schedule`, `/jobs`, and `/health`.
37
+
38
+ 4. **Symlinks `tq`** into `/opt/homebrew/bin` (Apple Silicon) or `/usr/local/bin` (Intel Mac) so the command is available in your shell and in cron jobs.
39
+
40
+ 5. **Creates `~/.tq/queues/` and `~/.tq/logs/`** — the default directories for queue files and log output.
41
+
42
+ If `claude` is not on your PATH, steps 2–3 are skipped with a warning and only the CLI tools are installed.
43
+
44
+ To install the CLI tools to a custom location instead:
45
+
46
+ ```bash
47
+ curl -fsSL https://raw.githubusercontent.com/kevnk/tq/main/scripts/tq-install.sh | TQ_INSTALL_DIR=/usr/local/bin bash
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ Create a queue file:
53
+
54
+ ```yaml
55
+ # ~/.tq/queues/morning.yaml
56
+ cwd: /Users/yourname/projects/myapp
57
+
58
+ tasks:
59
+ - prompt: fix the login bug in the auth service
60
+ - prompt: write unit tests for the payment module
61
+ - prompt: |
62
+ Review the README and update it to reflect
63
+ the current API endpoints and authentication flow
64
+ ```
65
+
66
+ Run it:
67
+
68
+ ```bash
69
+ tq ~/.tq/queues/morning.yaml
70
+ ```
71
+
72
+ Output:
73
+
74
+ ```
75
+ [spawned] tq-fix-the-login-451234 -- fix the login bug in the auth service
76
+ [spawned] tq-write-unit-test-451235 -- write unit tests for the payment module
77
+ [spawned] tq-review-the-readme-451236 -- Review the README and update it to reflect
78
+ ```
79
+
80
+ Check status:
81
+
82
+ ```bash
83
+ tq --status ~/.tq/queues/morning.yaml
84
+ ```
85
+
86
+ Output:
87
+
88
+ ```
89
+ STATUS SESSION STARTED PROMPT
90
+ ---------- ------------------------- ---------------------- ------
91
+ done tq-fix-the-login-451234 2026-03-06T09:01:02 fix the login bug in the auth service
92
+ running tq-write-unit-test-451235 2026-03-06T09:01:03 write unit tests for the payment module
93
+ running tq-review-the-readme-451236 2026-03-06T09:01:04 Review the README and update it to reflect
94
+ ```
95
+
96
+ ## Queue File Format
97
+
98
+ Queue files are standard YAML:
99
+
100
+ ```yaml
101
+ cwd: /path/to/working/directory # sets working directory for each claude task
102
+
103
+ tasks:
104
+ # Inline prompt (single line)
105
+ - prompt: fix the login bug in auth service
106
+
107
+ # Named task — human-readable label for tmux session naming
108
+ - name: write-tests
109
+ prompt: write unit tests for the payment module
110
+
111
+ # Block literal (|) — preserves line breaks exactly
112
+ - prompt: |
113
+ Write comprehensive unit tests for the payment module.
114
+ Cover happy path and all error cases.
115
+ Use jest and mock the Stripe API.
116
+
117
+ # Block folded (>) — newlines become spaces (like a paragraph)
118
+ - prompt: >
119
+ Refactor the authentication service to use JWT tokens
120
+ instead of session cookies, updating all dependent endpoints.
121
+
122
+ # Quoted inline
123
+ - prompt: "update the README's installation section"
124
+ ```
125
+
126
+ Queue files are **never modified** by `tq` — they are read-only inputs.
127
+
128
+ ### Notifications (optional)
129
+
130
+ Add a `message:` block to receive a notification when each task completes:
131
+
132
+ ```yaml
133
+ cwd: /Users/yourname/projects/myapp
134
+ message:
135
+ service: telegram # telegram | slack
136
+ content: summary # summary | status | details | log
137
+ tasks:
138
+ - prompt: refactor the auth module
139
+ ```
140
+
141
+ **Content types:**
142
+ - `summary` — Claude writes a 2–3 sentence digest of what it accomplished
143
+ - `status` — task name, done/failed, duration (no live Claude session needed)
144
+ - `details` — prompt first line, status, duration, hash
145
+ - `log` — last 200 lines of tmux pane scrollback
146
+
147
+ The `message:` block overrides the global config for that queue. Global credentials (bot tokens etc.) live in `~/.tq/config/message.yaml` — never in queue files. Run `/setup-telegram` to configure Telegram notifications interactively.
148
+
149
+ ## Commands
150
+
151
+ ### `tq <queue.yaml>`
152
+
153
+ Parses the queue file and spawns a new tmux session for each pending task.
154
+
155
+ - Skips tasks with `status=done`
156
+ - Skips tasks with `status=running` that have a live tmux session
157
+ - Flips tasks with `status=running` but a dead tmux session to `done`, then skips them
158
+ - Spawns all remaining (pending) tasks as new tmux sessions
159
+
160
+ ```bash
161
+ tq ~/.tq/queues/morning.yaml
162
+ ```
163
+
164
+ ### `tq --status <queue.yaml>`
165
+
166
+ Prints a formatted status table for all tasks in the queue. Also reaps any dead tmux sessions by flipping their state from `running` to `done`.
167
+
168
+ ```bash
169
+ tq --status ~/.tq/queues/morning.yaml
170
+ ```
171
+
172
+ Run this via cron every 30 minutes to keep state accurate even if sessions die unexpectedly.
173
+
174
+ ### `tq --prompt <text>`
175
+
176
+ Run a single ad-hoc prompt without a queue file. Useful for one-off tasks.
177
+
178
+ ```bash
179
+ tq --prompt "fix the login bug in auth service" --cwd ~/projects/myapp --name fix-login
180
+ ```
181
+
182
+ Options:
183
+ - `--prompt <text>` — the prompt to run (required for this mode)
184
+ - `--cwd <dir>` — working directory (defaults to `~/.tq/workspace`)
185
+ - `--name <name>` — label for tmux session naming (defaults to `adhoc`)
186
+ - `--notify <type>` — completion notification: `macos`, `bell`, or a path to a shell script
187
+
188
+ ## How It Works
189
+
190
+ **Step 1 — Parse**: `tq` runs an embedded Python script (written to a temp file) that reads the queue YAML and generates three files per task, all named by an 8-character SHA-256 hash of the prompt:
191
+
192
+ - `<hash>.prompt` — the raw prompt text
193
+ - `<hash>.launch.py` — a small Python launcher that `execvp`s into `claude` (replacing itself with the claude process so the tmux window ends up running claude directly)
194
+ - `~/.tq/sessions/<hash>/settings.json` — Claude settings registering a Stop hook
195
+
196
+ **Step 2 — Auth capture**: The Python parser reads the Claude OAuth token from the macOS keychain (`security find-generic-password -s 'Claude Code-credentials'`) and bakes it into the launcher script. This means each task has its credentials embedded and can run unattended even in a cron context.
197
+
198
+ **Step 3 — Spawn**: For each pending task, `tq` creates a named tmux session (`tq-<slug>-<epoch>`) and sends `python3 <hash>.launch.py` to it via `tmux send-keys`. The launcher runs inside the tmux window, then `execvp`s into `claude --dangerously-skip-permissions --chrome <prompt>`, replacing itself so the window ends up running a live `claude` session.
199
+
200
+ **Step 4 — Completion**: When `claude` finishes, the Stop hook (`on-stop.sh`) fires automatically and updates the task's state file: `status=running` → `status=done`. The next `tq` run will skip this task.
201
+
202
+ ## Claude Code Plugin
203
+
204
+ `tq` ships with a Claude skill definition at `skills/tq/SKILL.md`. Install it into Claude by copying or symlinking the `skills/tq/` directory into `~/.claude/skills/tq/`.
205
+
206
+ Once installed, Claude can manage your task queues via slash commands:
207
+
208
+ | Command | Purpose |
209
+ |---------|---------|
210
+ | `/init [dirs...]` | Scan workspace directories and build a project catalog for `cwd:` lookup |
211
+ | `/todo <natural language>` | Create or update a queue and optionally schedule it |
212
+ | `/schedule <natural language>` | Add or update a cron schedule for a queue |
213
+ | `/pause <queue>` | Remove the run cron line (keep status-check) |
214
+ | `/unschedule <queue>` | Remove all cron lines for a queue |
215
+ | `/jobs` | List all scheduled tq cron jobs |
216
+ | `/health` | System-wide diagnostics |
217
+ | `/setup-telegram` | Interactive wizard to configure Telegram notifications |
218
+ | `/install` | Symlink tq binaries to PATH |
219
+
220
+ Claude will infer the queue name from context: "every morning" → `morning.yaml`, "daily" → `daily.yaml`, or the current directory's basename if no schedule keyword is present.
221
+
222
+ ### `/init` — Workspace setup
223
+
224
+ Run `/init` once per machine to tell tq where your projects live:
225
+
226
+ ```
227
+ /init ~/Sites ~/Projects
228
+ ```
229
+
230
+ This scans the given directories for git repositories, writes `~/.tq/config/workspaces.yaml` (which directories to scan), and generates `~/.tq/workspace-map.md` (a catalog of every discovered project with its path and type). Re-run `/init` anytime to refresh after cloning new repos.
231
+
232
+ Once initialized, `/todo` uses the workspace map to resolve project names in natural language — e.g. "fix the login bug in myapp" will automatically set `cwd:` to myapp's full path.
233
+
234
+ ## State Files
235
+
236
+ State is stored in `.tq/` directories adjacent to the queue YAML file:
237
+
238
+ ```
239
+ ~/.tq/queues/
240
+ ├── morning.yaml ← your queue file
241
+ └── .tq/
242
+ └── morning/
243
+ ├── a1b2c3d4 ← task state file (key=value)
244
+ ├── a1b2c3d4.prompt ← raw prompt text
245
+ ├── a1b2c3d4.launch.py ← generated launcher (contains OAuth token)
246
+ └── ...
247
+ ```
248
+
249
+ Each state file looks like:
250
+
251
+ ```
252
+ status=done
253
+ session=tq-fix-the-login-451234
254
+ window=fix-the
255
+ prompt=fix the login bug in auth service
256
+ started=2026-03-06T09:01:02
257
+ ```
258
+
259
+ **Resetting tasks:**
260
+
261
+ ```bash
262
+ # Reset one task (tq will re-run it next time)
263
+ rm ~/.tq/queues/.tq/morning/a1b2c3d4
264
+
265
+ # Reset entire queue
266
+ rm -rf ~/.tq/queues/.tq/morning/
267
+ ```
268
+
269
+ ## Security Notes
270
+
271
+ The `.tq/` directories contain live OAuth tokens written in plaintext into `*.launch.py` launcher files at runtime. These files are ephemeral and local-only, but:
272
+
273
+ - **Never commit `.tq/` directories to git** — they contain your Claude auth tokens
274
+ - Add `.tq/` to your `.gitignore` if your queue files are inside a git repository
275
+
276
+ The `--dangerously-skip-permissions` flag is passed to every Claude session. This is required for unattended automation — without it, Claude would prompt for permission confirmations that no human is present to answer.
277
+
278
+ ## Scheduling
279
+
280
+ Add cron entries to run your queues automatically:
281
+
282
+ ```bash
283
+ crontab -e
284
+ ```
285
+
286
+ ```cron
287
+ # Run morning queue at 9am daily
288
+ 0 9 * * * /opt/homebrew/bin/tq ~/.tq/queues/morning.yaml >> ~/.tq/logs/tq.log 2>&1
289
+
290
+ # Sweep dead sessions every 30 minutes (keeps status accurate)
291
+ */30 * * * * /opt/homebrew/bin/tq --status ~/.tq/queues/morning.yaml >> ~/.tq/logs/tq.log 2>&1
292
+ ```
293
+
294
+ Logs accumulate in `~/.tq/logs/tq.log`.
295
+
296
+ See `skills/tq/references/cron-expressions.md` for a natural language → cron expression reference.
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@codefilabs/tq",
3
+ "version": "0.0.1",
4
+ "description": "A lightweight task queue runner that spawns Claude AI tasks as independent tmux sessions",
5
+ "keywords": [
6
+ "claude",
7
+ "ai",
8
+ "tmux",
9
+ "queue",
10
+ "automation",
11
+ "task-runner",
12
+ "cron"
13
+ ],
14
+ "homepage": "https://github.com/CodefiLabs/tq#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/CodefiLabs/tq/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/CodefiLabs/tq.git"
21
+ },
22
+ "license": "MIT",
23
+ "bin": {
24
+ "tq": "./scripts/tq",
25
+ "tq-message": "./scripts/tq-message",
26
+ "tq-setup": "./scripts/tq-setup",
27
+ "tq-telegram-poll": "./scripts/tq-telegram-poll",
28
+ "tq-telegram-watchdog": "./scripts/tq-telegram-watchdog"
29
+ },
30
+ "files": [
31
+ "scripts/",
32
+ "skills/",
33
+ "README.md"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }