loopwork 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 +52 -0
- package/README.md +528 -0
- package/bin/loopwork +0 -0
- package/examples/README.md +70 -0
- package/examples/basic-json-backend/.specs/tasks/TASK-001.md +22 -0
- package/examples/basic-json-backend/.specs/tasks/TASK-002.md +23 -0
- package/examples/basic-json-backend/.specs/tasks/TASK-003.md +37 -0
- package/examples/basic-json-backend/.specs/tasks/tasks.json +19 -0
- package/examples/basic-json-backend/README.md +32 -0
- package/examples/basic-json-backend/TESTING.md +184 -0
- package/examples/basic-json-backend/hello.test.ts +9 -0
- package/examples/basic-json-backend/hello.ts +3 -0
- package/examples/basic-json-backend/loopwork.config.js +35 -0
- package/examples/basic-json-backend/math.test.ts +29 -0
- package/examples/basic-json-backend/math.ts +3 -0
- package/examples/basic-json-backend/package.json +15 -0
- package/examples/basic-json-backend/quick-start.sh +80 -0
- package/loopwork.config.ts +164 -0
- package/package.json +26 -0
- package/src/backends/github.ts +426 -0
- package/src/backends/index.ts +86 -0
- package/src/backends/json.ts +598 -0
- package/src/backends/plugin.ts +317 -0
- package/src/backends/types.ts +19 -0
- package/src/commands/init.ts +100 -0
- package/src/commands/run.ts +365 -0
- package/src/contracts/backend.ts +127 -0
- package/src/contracts/config.ts +129 -0
- package/src/contracts/index.ts +43 -0
- package/src/contracts/plugin.ts +82 -0
- package/src/contracts/task.ts +78 -0
- package/src/core/cli.ts +275 -0
- package/src/core/config.ts +165 -0
- package/src/core/state.ts +154 -0
- package/src/core/utils.ts +125 -0
- package/src/dashboard/cli.ts +449 -0
- package/src/dashboard/index.ts +6 -0
- package/src/dashboard/kanban.tsx +226 -0
- package/src/dashboard/tui.tsx +372 -0
- package/src/index.ts +19 -0
- package/src/mcp/server.ts +451 -0
- package/src/monitor/index.ts +420 -0
- package/src/plugins/asana.ts +192 -0
- package/src/plugins/cost-tracking.ts +402 -0
- package/src/plugins/discord.ts +269 -0
- package/src/plugins/everhour.ts +335 -0
- package/src/plugins/index.ts +253 -0
- package/src/plugins/telegram/bot.ts +517 -0
- package/src/plugins/telegram/index.ts +6 -0
- package/src/plugins/telegram/notifications.ts +198 -0
- package/src/plugins/todoist.ts +261 -0
- package/test/backends.test.ts +929 -0
- package/test/cli.test.ts +145 -0
- package/test/config.test.ts +90 -0
- package/test/e2e.test.ts +458 -0
- package/test/github-tasks.test.ts +191 -0
- package/test/loopwork-config-types.test.ts +288 -0
- package/test/monitor.test.ts +123 -0
- package/test/plugins.test.ts +1175 -0
- package/test/state.test.ts +295 -0
- package/test/utils.test.ts +60 -0
- package/tsconfig.json +20 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.2.0] - 2026-01-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **New `init` command**: Interactive scaffolding for new projects (`loopwork init`).
|
|
9
|
+
- Supports GitHub and JSON backends.
|
|
10
|
+
- Generates `loopwork.config.ts`.
|
|
11
|
+
- Creates sample tasks and PRDs for JSON backend.
|
|
12
|
+
- CLI architecture refactor:
|
|
13
|
+
- Split main logic into `src/commands/run.ts` and `src/commands/init.ts`.
|
|
14
|
+
- `src/index.ts` now acts as a command dispatcher.
|
|
15
|
+
- Comprehensive E2E test suite for JSON backend (`test/e2e.test.ts`)
|
|
16
|
+
- Tests for complete task workflow
|
|
17
|
+
- Task failure and retry scenarios
|
|
18
|
+
- Priority ordering
|
|
19
|
+
- Dependencies and sub-tasks
|
|
20
|
+
- Feature filtering
|
|
21
|
+
- State management
|
|
22
|
+
- Example directory structure for testing (`examples/basic-json-backend/`)
|
|
23
|
+
- Simple tasks for learning
|
|
24
|
+
- Interactive quick-start script
|
|
25
|
+
- Complete documentation
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **BREAKING**: CLI command options no longer have default values
|
|
29
|
+
- Allows config file values to take precedence
|
|
30
|
+
- Priority is now: CLI args > env vars > config file > defaults
|
|
31
|
+
- CLI executor now shows the command being executed
|
|
32
|
+
- Debug mode shows full command
|
|
33
|
+
- Info mode shows model and timeout
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- Config file loading now works properly
|
|
37
|
+
- Removed default values from commander options
|
|
38
|
+
- Config file values are now respected when no CLI args provided
|
|
39
|
+
- Command execution visibility improved
|
|
40
|
+
- Shows what command is being run
|
|
41
|
+
- Shows model and timeout information
|
|
42
|
+
|
|
43
|
+
## [0.1.0] - Initial Release
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- Multiple backend support (GitHub Issues, JSON files)
|
|
47
|
+
- Plugin architecture with composable config
|
|
48
|
+
- Built-in plugins: Telegram, Discord, Asana, Everhour, Todoist, Cost Tracking
|
|
49
|
+
- Task dependencies and sub-tasks
|
|
50
|
+
- MCP server integration
|
|
51
|
+
- Background execution monitor
|
|
52
|
+
- TUI dashboard
|
package/README.md
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# Loopwork
|
|
2
|
+
|
|
3
|
+
An extensible task automation framework that runs AI CLI tools against task backlogs. Features a plugin architecture for integrations with time tracking, notifications, and project management tools.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multiple Backends** - GitHub Issues, JSON files, with plugin support for custom backends
|
|
8
|
+
- **Plugin Architecture** - Next.js-style config with composable plugins
|
|
9
|
+
- **Time Tracking** - Everhour integration with daily limits
|
|
10
|
+
- **Project Management** - Asana, Todoist sync
|
|
11
|
+
- **Notifications** - Telegram, Discord webhooks
|
|
12
|
+
- **Cost Tracking** - Token usage and cost monitoring
|
|
13
|
+
- **Sub-tasks & Dependencies** - Hierarchical task structures
|
|
14
|
+
- **MCP Server** - Model Context Protocol for AI tool integration
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Try the Example
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Install dependencies
|
|
22
|
+
bun install
|
|
23
|
+
|
|
24
|
+
# Run the basic example
|
|
25
|
+
cd examples/basic-json-backend
|
|
26
|
+
./quick-start.sh # Interactive menu
|
|
27
|
+
# OR
|
|
28
|
+
bun run start --dry-run # Preview tasks
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
See [examples/](./examples/) for more.
|
|
32
|
+
|
|
33
|
+
### From Scratch
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Install
|
|
37
|
+
bun install
|
|
38
|
+
|
|
39
|
+
# Create config file
|
|
40
|
+
cat > loopwork.config.ts << 'EOF'
|
|
41
|
+
import { defineConfig, compose, withTelegram, withCostTracking } from './src/loopwork-config-types'
|
|
42
|
+
import { withJSONBackend } from './src/backend-plugin'
|
|
43
|
+
|
|
44
|
+
export default compose(
|
|
45
|
+
withJSONBackend({ tasksFile: '.specs/tasks/tasks.json' }),
|
|
46
|
+
withCostTracking({ dailyBudget: 10.00 }),
|
|
47
|
+
)(defineConfig({
|
|
48
|
+
cli: 'claude',
|
|
49
|
+
maxIterations: 50,
|
|
50
|
+
}))
|
|
51
|
+
EOF
|
|
52
|
+
|
|
53
|
+
# Run
|
|
54
|
+
bun run src/index.ts
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
### Config File (`loopwork.config.ts`)
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import {
|
|
63
|
+
defineConfig,
|
|
64
|
+
compose,
|
|
65
|
+
withTelegram,
|
|
66
|
+
withDiscord,
|
|
67
|
+
withAsana,
|
|
68
|
+
withEverhour,
|
|
69
|
+
withTodoist,
|
|
70
|
+
withCostTracking,
|
|
71
|
+
} from './src/loopwork-config-types'
|
|
72
|
+
import { withJSONBackend, withGitHubBackend } from './src/backend-plugin'
|
|
73
|
+
|
|
74
|
+
export default compose(
|
|
75
|
+
// Backend (pick one)
|
|
76
|
+
withJSONBackend({ tasksFile: '.specs/tasks/tasks.json' }),
|
|
77
|
+
// withGitHubBackend({ repo: 'owner/repo' }),
|
|
78
|
+
|
|
79
|
+
// Notifications
|
|
80
|
+
withTelegram({
|
|
81
|
+
botToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
82
|
+
chatId: process.env.TELEGRAM_CHAT_ID,
|
|
83
|
+
notifyOnStart: true,
|
|
84
|
+
notifyOnComplete: true,
|
|
85
|
+
notifyOnFail: true,
|
|
86
|
+
}),
|
|
87
|
+
|
|
88
|
+
withDiscord({
|
|
89
|
+
webhookUrl: process.env.DISCORD_WEBHOOK_URL,
|
|
90
|
+
mentionOnFail: '<@123456789>', // User/role to ping on failures
|
|
91
|
+
}),
|
|
92
|
+
|
|
93
|
+
// Project Management
|
|
94
|
+
withAsana({
|
|
95
|
+
accessToken: process.env.ASANA_ACCESS_TOKEN,
|
|
96
|
+
workspaceId: process.env.ASANA_WORKSPACE_ID,
|
|
97
|
+
projectId: process.env.ASANA_PROJECT_ID,
|
|
98
|
+
syncComments: true,
|
|
99
|
+
}),
|
|
100
|
+
|
|
101
|
+
withTodoist({
|
|
102
|
+
apiToken: process.env.TODOIST_API_TOKEN,
|
|
103
|
+
projectId: process.env.TODOIST_PROJECT_ID,
|
|
104
|
+
}),
|
|
105
|
+
|
|
106
|
+
// Time Tracking
|
|
107
|
+
withEverhour({
|
|
108
|
+
apiKey: process.env.EVERHOUR_API_KEY,
|
|
109
|
+
dailyLimit: 8, // Max hours per day
|
|
110
|
+
}),
|
|
111
|
+
|
|
112
|
+
// Cost Tracking
|
|
113
|
+
withCostTracking({
|
|
114
|
+
dailyBudget: 10.00,
|
|
115
|
+
alertThreshold: 0.8,
|
|
116
|
+
}),
|
|
117
|
+
)(defineConfig({
|
|
118
|
+
cli: 'claude', // AI CLI: claude, opencode, gemini
|
|
119
|
+
model: 'claude-sonnet-4-20250514',
|
|
120
|
+
maxIterations: 50,
|
|
121
|
+
taskTimeout: 600, // seconds
|
|
122
|
+
nonInteractive: true,
|
|
123
|
+
}))
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Environment Variables
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Core
|
|
130
|
+
LOOPWORK_DEBUG=true
|
|
131
|
+
LOOPWORK_NAMESPACE=default
|
|
132
|
+
LOOPWORK_NON_INTERACTIVE=true
|
|
133
|
+
|
|
134
|
+
# Backends
|
|
135
|
+
LOOPWORK_BACKEND=json|github
|
|
136
|
+
LOOPWORK_TASKS_FILE=.specs/tasks/tasks.json
|
|
137
|
+
LOOPWORK_REPO=owner/repo
|
|
138
|
+
|
|
139
|
+
# Telegram
|
|
140
|
+
TELEGRAM_BOT_TOKEN=123456:ABC...
|
|
141
|
+
TELEGRAM_CHAT_ID=123456789
|
|
142
|
+
|
|
143
|
+
# Discord
|
|
144
|
+
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
|
|
145
|
+
|
|
146
|
+
# Asana
|
|
147
|
+
ASANA_ACCESS_TOKEN=...
|
|
148
|
+
ASANA_WORKSPACE_ID=...
|
|
149
|
+
ASANA_PROJECT_ID=...
|
|
150
|
+
|
|
151
|
+
# Everhour
|
|
152
|
+
EVERHOUR_API_KEY=...
|
|
153
|
+
|
|
154
|
+
# Todoist
|
|
155
|
+
TODOIST_API_TOKEN=...
|
|
156
|
+
TODOIST_PROJECT_ID=...
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Plugin System
|
|
160
|
+
|
|
161
|
+
### Built-in Plugins
|
|
162
|
+
|
|
163
|
+
| Plugin | Purpose | Config Wrapper |
|
|
164
|
+
|--------|---------|----------------|
|
|
165
|
+
| Telegram | Notifications & bot commands | `withTelegram()` |
|
|
166
|
+
| Discord | Webhook notifications | `withDiscord()` |
|
|
167
|
+
| Asana | Task sync & comments | `withAsana()` |
|
|
168
|
+
| Everhour | Time tracking | `withEverhour()` |
|
|
169
|
+
| Todoist | Task sync | `withTodoist()` |
|
|
170
|
+
| Cost Tracking | Token/cost monitoring | `withCostTracking()` |
|
|
171
|
+
|
|
172
|
+
### Creating Custom Plugins
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import type { LoopworkPlugin, PluginContext, TaskResult } from './src/loopwork-config-types'
|
|
176
|
+
|
|
177
|
+
const myPlugin: LoopworkPlugin = {
|
|
178
|
+
name: 'my-plugin',
|
|
179
|
+
|
|
180
|
+
async onLoopStart(config) {
|
|
181
|
+
console.log('Loop starting with', config.maxIterations, 'max iterations')
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
async onTaskStart(context: PluginContext) {
|
|
185
|
+
console.log('Starting task:', context.task.id)
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
async onTaskComplete(context: PluginContext, result: TaskResult) {
|
|
189
|
+
console.log('Completed:', context.task.id, 'in', result.duration, 'ms')
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
async onTaskFailed(context: PluginContext, error: string) {
|
|
193
|
+
console.error('Failed:', context.task.id, error)
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
async onLoopEnd(stats) {
|
|
197
|
+
console.log('Loop complete:', stats.completed, 'tasks done')
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Register with withPlugin()
|
|
202
|
+
import { withPlugin } from './src/loopwork-config-types'
|
|
203
|
+
|
|
204
|
+
export default compose(
|
|
205
|
+
withPlugin(myPlugin),
|
|
206
|
+
// ... other plugins
|
|
207
|
+
)(defineConfig({ cli: 'claude' }))
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Task Metadata
|
|
211
|
+
|
|
212
|
+
Plugins can read external IDs from task metadata:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
interface TaskMetadata {
|
|
216
|
+
asanaGid?: string // Asana task ID
|
|
217
|
+
everhourId?: string // Everhour task ID
|
|
218
|
+
todoistId?: string // Todoist task ID
|
|
219
|
+
[key: string]: unknown
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// In JSON tasks file
|
|
223
|
+
{
|
|
224
|
+
"tasks": [{
|
|
225
|
+
"id": "TASK-001",
|
|
226
|
+
"title": "Implement feature",
|
|
227
|
+
"metadata": {
|
|
228
|
+
"asanaGid": "1234567890",
|
|
229
|
+
"todoistId": "9876543210"
|
|
230
|
+
}
|
|
231
|
+
}]
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Backend Plugins
|
|
236
|
+
|
|
237
|
+
Backends are also plugins, providing both task operations and lifecycle hooks:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { withJSONBackend, withGitHubBackend } from './src/backend-plugin'
|
|
241
|
+
|
|
242
|
+
// JSON Backend
|
|
243
|
+
withJSONBackend({
|
|
244
|
+
tasksFile: '.specs/tasks/tasks.json',
|
|
245
|
+
prdDirectory: '.specs/tasks',
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
// GitHub Backend
|
|
249
|
+
withGitHubBackend({
|
|
250
|
+
repo: 'owner/repo',
|
|
251
|
+
labels: {
|
|
252
|
+
task: 'loopwork-task',
|
|
253
|
+
pending: 'loopwork:pending',
|
|
254
|
+
},
|
|
255
|
+
})
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Backend Interface
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
interface BackendPlugin extends LoopworkPlugin {
|
|
262
|
+
readonly backendType: 'json' | 'github' | string
|
|
263
|
+
|
|
264
|
+
findNextTask(options?: FindTaskOptions): Promise<Task | null>
|
|
265
|
+
getTask(taskId: string): Promise<Task | null>
|
|
266
|
+
listPendingTasks(options?: FindTaskOptions): Promise<Task[]>
|
|
267
|
+
|
|
268
|
+
markInProgress(taskId: string): Promise<UpdateResult>
|
|
269
|
+
markCompleted(taskId: string, comment?: string): Promise<UpdateResult>
|
|
270
|
+
markFailed(taskId: string, error: string): Promise<UpdateResult>
|
|
271
|
+
resetToPending(taskId: string): Promise<UpdateResult>
|
|
272
|
+
|
|
273
|
+
getSubTasks(taskId: string): Promise<Task[]>
|
|
274
|
+
getDependencies(taskId: string): Promise<Task[]>
|
|
275
|
+
areDependenciesMet(taskId: string): Promise<boolean>
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Task Formats
|
|
280
|
+
|
|
281
|
+
### JSON Backend
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
// .specs/tasks/tasks.json
|
|
285
|
+
{
|
|
286
|
+
"tasks": [
|
|
287
|
+
{
|
|
288
|
+
"id": "TASK-001",
|
|
289
|
+
"status": "pending",
|
|
290
|
+
"priority": "high",
|
|
291
|
+
"feature": "auth",
|
|
292
|
+
"metadata": { "asanaGid": "123" }
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"id": "TASK-002",
|
|
296
|
+
"status": "pending",
|
|
297
|
+
"priority": "medium",
|
|
298
|
+
"parentId": "TASK-001",
|
|
299
|
+
"dependsOn": ["TASK-001"]
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
PRD files in `.specs/tasks/TASK-001.md`:
|
|
306
|
+
|
|
307
|
+
```markdown
|
|
308
|
+
# TASK-001: Implement login
|
|
309
|
+
|
|
310
|
+
## Goal
|
|
311
|
+
Add user authentication
|
|
312
|
+
|
|
313
|
+
## Requirements
|
|
314
|
+
- Login form with validation
|
|
315
|
+
- JWT token handling
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### GitHub Issues
|
|
319
|
+
|
|
320
|
+
Create issues with labels:
|
|
321
|
+
- `loopwork-task` - Identifies managed tasks
|
|
322
|
+
- `loopwork:pending` - Pending status
|
|
323
|
+
- `priority:high` - Priority level
|
|
324
|
+
|
|
325
|
+
Add to issue body for relationships:
|
|
326
|
+
```markdown
|
|
327
|
+
Parent: #123
|
|
328
|
+
Depends on: #100, #101
|
|
329
|
+
|
|
330
|
+
## Description
|
|
331
|
+
Task description here
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## CLI Usage
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# Basic run
|
|
338
|
+
bun run src/index.ts
|
|
339
|
+
|
|
340
|
+
# With options
|
|
341
|
+
bun run src/index.ts \
|
|
342
|
+
--cli claude \
|
|
343
|
+
--backend json \
|
|
344
|
+
--tasks-file .specs/tasks/tasks.json \
|
|
345
|
+
--max 10 \
|
|
346
|
+
--timeout 300 \
|
|
347
|
+
-y # non-interactive
|
|
348
|
+
|
|
349
|
+
# Resume from state
|
|
350
|
+
bun run src/index.ts --resume
|
|
351
|
+
|
|
352
|
+
# Filter by feature
|
|
353
|
+
bun run src/index.ts --feature auth
|
|
354
|
+
|
|
355
|
+
# Dry run
|
|
356
|
+
bun run src/index.ts --dry-run
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### CLI Options
|
|
360
|
+
|
|
361
|
+
| Option | Description | Default |
|
|
362
|
+
|--------|-------------|---------|
|
|
363
|
+
| `--cli <tool>` | AI CLI tool (claude, opencode, gemini) | opencode |
|
|
364
|
+
| `--model <model>` | Model override | - |
|
|
365
|
+
| `--backend <type>` | Backend (github, json) | auto-detect |
|
|
366
|
+
| `--tasks-file <path>` | JSON tasks file | .specs/tasks/tasks.json |
|
|
367
|
+
| `--feature <name>` | Filter by feature label | - |
|
|
368
|
+
| `--start <id>` | Start from task ID | - |
|
|
369
|
+
| `--max <n>` | Max iterations | 50 |
|
|
370
|
+
| `--timeout <s>` | Task timeout (seconds) | 600 |
|
|
371
|
+
| `--namespace <name>` | Namespace for isolation | default |
|
|
372
|
+
| `--resume` | Resume from saved state | false |
|
|
373
|
+
| `-y, --yes` | Non-interactive mode | false |
|
|
374
|
+
| `--dry-run` | Show without executing | false |
|
|
375
|
+
| `--debug` | Debug logging | false |
|
|
376
|
+
|
|
377
|
+
## Background Execution
|
|
378
|
+
|
|
379
|
+
### Monitor
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# Start in background
|
|
383
|
+
bun run src/monitor.ts start default
|
|
384
|
+
bun run src/monitor.ts start feature-auth --feature auth
|
|
385
|
+
|
|
386
|
+
# Status
|
|
387
|
+
bun run src/monitor.ts status
|
|
388
|
+
|
|
389
|
+
# Logs
|
|
390
|
+
bun run src/monitor.ts logs default
|
|
391
|
+
bun run src/monitor.ts tail default
|
|
392
|
+
|
|
393
|
+
# Stop
|
|
394
|
+
bun run src/monitor.ts stop default
|
|
395
|
+
bun run src/monitor.ts stop --all
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Dashboard
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# One-time status
|
|
402
|
+
bun run src/dashboard.ts
|
|
403
|
+
|
|
404
|
+
# Watch mode
|
|
405
|
+
bun run src/dashboard.ts watch
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## MCP Server
|
|
409
|
+
|
|
410
|
+
For integration with Claude Desktop or other MCP clients:
|
|
411
|
+
|
|
412
|
+
```json
|
|
413
|
+
// claude_desktop_config.json
|
|
414
|
+
{
|
|
415
|
+
"mcpServers": {
|
|
416
|
+
"loopwork-tasks": {
|
|
417
|
+
"command": "bun",
|
|
418
|
+
"args": ["run", "/path/to/loopwork/src/mcp-server.ts"],
|
|
419
|
+
"env": {
|
|
420
|
+
"LOOPWORK_BACKEND": "json",
|
|
421
|
+
"LOOPWORK_TASKS_FILE": ".specs/tasks/tasks.json"
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### MCP Tools
|
|
429
|
+
|
|
430
|
+
| Tool | Description |
|
|
431
|
+
|------|-------------|
|
|
432
|
+
| `loopwork_list_tasks` | List pending tasks |
|
|
433
|
+
| `loopwork_get_task` | Get task details |
|
|
434
|
+
| `loopwork_mark_complete` | Mark completed |
|
|
435
|
+
| `loopwork_mark_failed` | Mark failed |
|
|
436
|
+
| `loopwork_mark_in_progress` | Mark in-progress |
|
|
437
|
+
| `loopwork_reset_task` | Reset to pending |
|
|
438
|
+
| `loopwork_get_subtasks` | Get sub-tasks |
|
|
439
|
+
| `loopwork_get_dependencies` | Get dependencies |
|
|
440
|
+
| `loopwork_check_dependencies` | Check if deps met |
|
|
441
|
+
| `loopwork_count_pending` | Count pending |
|
|
442
|
+
| `loopwork_backend_status` | Health check |
|
|
443
|
+
|
|
444
|
+
## Telegram Bot
|
|
445
|
+
|
|
446
|
+
Interactive task management via Telegram:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
bun run src/telegram-bot.ts
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Commands:
|
|
453
|
+
- `/tasks` - List pending tasks
|
|
454
|
+
- `/task <id>` - Get task details
|
|
455
|
+
- `/complete <id>` - Mark completed
|
|
456
|
+
- `/fail <id> [reason]` - Mark failed
|
|
457
|
+
- `/reset <id>` - Reset to pending
|
|
458
|
+
- `/status` - Backend status
|
|
459
|
+
- `/help` - Show commands
|
|
460
|
+
|
|
461
|
+
## GitHub Labels
|
|
462
|
+
|
|
463
|
+
Setup labels in your repo:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
bun run src/setup-labels.ts
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Creates:
|
|
470
|
+
| Label | Description |
|
|
471
|
+
|-------|-------------|
|
|
472
|
+
| `loopwork-task` | Managed task |
|
|
473
|
+
| `loopwork:pending` | Pending |
|
|
474
|
+
| `loopwork:in-progress` | In progress |
|
|
475
|
+
| `loopwork:failed` | Failed |
|
|
476
|
+
| `loopwork:sub-task` | Sub-task |
|
|
477
|
+
| `loopwork:blocked` | Blocked |
|
|
478
|
+
| `priority:high/medium/low` | Priority |
|
|
479
|
+
|
|
480
|
+
## Testing
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# All tests
|
|
484
|
+
bun test
|
|
485
|
+
|
|
486
|
+
# Specific file
|
|
487
|
+
bun test test/backends.test.ts
|
|
488
|
+
|
|
489
|
+
# With coverage
|
|
490
|
+
bun test --coverage
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Architecture
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
loopwork/
|
|
497
|
+
├── src/
|
|
498
|
+
│ ├── index.ts # Main entry
|
|
499
|
+
│ ├── loopwork-config-types.ts # Config & plugin types
|
|
500
|
+
│ ├── backend-plugin.ts # Backend plugin system
|
|
501
|
+
│ ├── plugins.ts # Plugin registry
|
|
502
|
+
│ ├── config.ts # Config loading
|
|
503
|
+
│ ├── state.ts # State management
|
|
504
|
+
│ ├── cli.ts # CLI executor
|
|
505
|
+
│ ├── monitor.ts # Background manager
|
|
506
|
+
│ ├── dashboard.ts # Status dashboard
|
|
507
|
+
│ ├── dashboard.tsx # React/ink TUI
|
|
508
|
+
│ ├── cost-tracking.ts # Cost tracking
|
|
509
|
+
│ ├── telegram-plugin.ts # Telegram notifications
|
|
510
|
+
│ ├── telegram-bot.ts # Telegram bot
|
|
511
|
+
│ ├── discord-plugin.ts # Discord notifications
|
|
512
|
+
│ ├── asana-plugin.ts # Asana integration
|
|
513
|
+
│ ├── everhour-plugin.ts # Everhour time tracking
|
|
514
|
+
│ ├── todoist-plugin.ts # Todoist integration
|
|
515
|
+
│ ├── mcp-server.ts # MCP server
|
|
516
|
+
│ └── backends/
|
|
517
|
+
│ ├── types.ts # Backend interface
|
|
518
|
+
│ ├── index.ts # Backend factory
|
|
519
|
+
│ ├── github-adapter.ts # GitHub backend
|
|
520
|
+
│ └── json-adapter.ts # JSON backend
|
|
521
|
+
├── test/ # Tests
|
|
522
|
+
├── loopwork.config.ts # Config file
|
|
523
|
+
└── package.json
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
## License
|
|
527
|
+
|
|
528
|
+
MIT
|
package/bin/loopwork
ADDED
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Loopwork Examples
|
|
2
|
+
|
|
3
|
+
This directory contains example projects demonstrating different ways to use Loopwork.
|
|
4
|
+
|
|
5
|
+
## Available Examples
|
|
6
|
+
|
|
7
|
+
### 1. Basic JSON Backend
|
|
8
|
+
**Directory**: `basic-json-backend/`
|
|
9
|
+
|
|
10
|
+
A simple example using the JSON backend with 3 basic coding tasks:
|
|
11
|
+
- Create a Hello World function
|
|
12
|
+
- Add a sum function
|
|
13
|
+
- Write README documentation
|
|
14
|
+
|
|
15
|
+
**Best for**: Learning the basics, local development, small projects
|
|
16
|
+
|
|
17
|
+
**Key Features**:
|
|
18
|
+
- Simple task structure
|
|
19
|
+
- Local file-based task management
|
|
20
|
+
- Easy to understand and modify
|
|
21
|
+
|
|
22
|
+
[View Example →](./basic-json-backend/)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Coming Soon
|
|
27
|
+
|
|
28
|
+
### GitHub Backend Example
|
|
29
|
+
Using GitHub Issues as a task backend with labels and milestones.
|
|
30
|
+
|
|
31
|
+
### Advanced Plugins Example
|
|
32
|
+
Demonstrating Telegram notifications, cost tracking, and custom plugins.
|
|
33
|
+
|
|
34
|
+
### Multi-Feature Project
|
|
35
|
+
Complex project with multiple features, sub-tasks, and dependencies.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
1. Choose an example directory
|
|
42
|
+
2. Read the README in that directory
|
|
43
|
+
3. Run the example:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd basic-json-backend
|
|
47
|
+
bun run start
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Example Structure
|
|
51
|
+
|
|
52
|
+
Each example includes:
|
|
53
|
+
- `README.md` - Detailed instructions
|
|
54
|
+
- `loopwork.config.ts` - Configuration file
|
|
55
|
+
- `.specs/tasks/` - Task definitions (for JSON backend)
|
|
56
|
+
- Sample tasks and PRDs
|
|
57
|
+
|
|
58
|
+
## Learning Path
|
|
59
|
+
|
|
60
|
+
We recommend following this order:
|
|
61
|
+
|
|
62
|
+
1. **Start here**: `basic-json-backend/` - Learn core concepts
|
|
63
|
+
2. **Next**: GitHub backend example - Learn backend integration
|
|
64
|
+
3. **Advanced**: Plugins example - Learn extensibility
|
|
65
|
+
|
|
66
|
+
## Need Help?
|
|
67
|
+
|
|
68
|
+
- Read the [main documentation](../README.md)
|
|
69
|
+
- Check [troubleshooting guide](../docs/troubleshooting.md)
|
|
70
|
+
- Open an issue on GitHub
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TASK-001: Create Hello World Function
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Create a simple function that returns "Hello, World!"
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
- Create a file called `hello.ts`
|
|
8
|
+
- Export a function named `sayHello`
|
|
9
|
+
- The function should return the string "Hello, World!"
|
|
10
|
+
- Add a simple test to verify it works
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
```typescript
|
|
14
|
+
export function sayHello(): string {
|
|
15
|
+
return "Hello, World!"
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Success Criteria
|
|
20
|
+
- File `hello.ts` exists
|
|
21
|
+
- Function returns correct string
|
|
22
|
+
- Test passes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# TASK-002: Add a Sum Function
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Create a function that adds two numbers together
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
- Create a file called `math.ts`
|
|
8
|
+
- Export a function named `sum`
|
|
9
|
+
- The function should take two numbers and return their sum
|
|
10
|
+
- Add tests for the function
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
```typescript
|
|
14
|
+
export function sum(a: number, b: number): number {
|
|
15
|
+
return a + b
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Success Criteria
|
|
20
|
+
- File `math.ts` exists
|
|
21
|
+
- Function correctly adds two numbers
|
|
22
|
+
- Tests pass
|
|
23
|
+
- Function handles decimal numbers
|