diff --git a/README.md b/README.md index 2f4bd5e..ac6587e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,82 @@ -# queue +# mosaic-queue +Valkey/Redis-backed task queue with: + +- Atomic task lifecycle operations (`claim`, `release`, `heartbeat`, `complete`, `fail`) +- CLI commands for queue management +- MCP server tools for agent integrations + +## Requirements + +- Node.js `>=20` +- pnpm `10.x` +- Valkey/Redis URL in one of: + - `VALKEY_URL` + - `REDIS_URL` + +No default Redis URL is hardcoded. Startup fails loudly when neither env var exists. + +## Install + +```bash +pnpm install +pnpm build +``` + +## CLI Usage + +The package ships a `mosaic` binary. + +```bash +mosaic queue create --title "..." [--priority high] [--lane coding] +mosaic queue list [--project X] [--mission Y] [--status pending] +mosaic queue show +mosaic queue claim --agent --ttl 3600 +mosaic queue release [--agent ] +mosaic queue complete [--agent ] [--summary "..."] +``` + +Example: + +```bash +export VALKEY_URL="redis://localhost:6379" +mosaic queue create queue phase1 MQ-001 --title "Implement core queue" +mosaic queue claim MQ-001 --agent codex --ttl 3600 +``` + +## MCP Server + +The package also ships a `mosaic-queue-mcp` binary exposing: + +- `queue_list` +- `queue_get` +- `queue_claim` +- `queue_heartbeat` +- `queue_release` +- `queue_complete` +- `queue_fail` +- `queue_status` + +Run over stdio: + +```bash +export VALKEY_URL="redis://localhost:6379" +mosaic-queue-mcp +``` + +## Development + +```bash +pnpm lint +pnpm test +pnpm build +``` + +## Publish Prep + +`packages/queue/package.json` includes: + +- `bin` entries for `mosaic` and `mosaic-queue-mcp` +- `exports` + `types` for ESM package consumption +- `prepublishOnly` quality gate (`lint`, `test`, `build`) +- `publishConfig.access = public` diff --git a/docs/TASKS.md b/docs/TASKS.md index 9368f80..a4dfc3f 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -2,11 +2,11 @@ | id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | notes | |---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| MQ-001 | not-started | Init: pnpm monorepo, TypeScript strict, ESLint, vitest | TASKS:P1 | queue | feat/core-queue | | MQ-002 | | | | 8K | | | -| MQ-002 | not-started | Valkey/Redis connection module with health check | TASKS:P1 | queue | feat/core-queue | MQ-001 | MQ-003 | | | | 5K | | | -| MQ-003 | not-started | Task CRUD: create, get, list, update (ioredis + JSON serialization) | TASKS:P1 | queue | feat/core-queue | MQ-002 | MQ-004 | | | | 12K | | | -| MQ-004 | not-started | Atomic claim/release/heartbeat/complete/fail operations | TASKS:P1 | queue | feat/core-queue | MQ-003 | MQ-005 | | | | 15K | | | -| MQ-005 | not-started | CLI: commander wiring for create/list/show/claim/release/complete | TASKS:P1 | queue | feat/core-queue | MQ-004 | MQ-006 | | | | 10K | | | -| MQ-006 | not-started | MCP server: queue_list/get/claim/heartbeat/release/complete/fail/status tools | TASKS:P1 | queue | feat/core-queue | MQ-005 | MQ-007 | | | | 15K | | | -| MQ-007 | not-started | Unit tests for claim atomicity + state transitions + MCP tool schemas | TASKS:P1 | queue | feat/core-queue | MQ-006 | MQ-008 | | | | 15K | | | -| MQ-008 | not-started | README, package.json bin entry, npm publish prep | TASKS:P1 | queue | feat/core-queue | MQ-007 | | | | | 5K | | | +| MQ-001 | done | Init: pnpm monorepo, TypeScript strict, ESLint, vitest | TASKS:P1 | queue | feat/core-queue | | MQ-002 | | | | 8K | | | +| MQ-002 | done | Valkey/Redis connection module with health check | TASKS:P1 | queue | feat/core-queue | MQ-001 | MQ-003 | | | | 5K | | | +| MQ-003 | done | Task CRUD: create, get, list, update (ioredis + JSON serialization) | TASKS:P1 | queue | feat/core-queue | MQ-002 | MQ-004 | | | | 12K | | | +| MQ-004 | done | Atomic claim/release/heartbeat/complete/fail operations | TASKS:P1 | queue | feat/core-queue | MQ-003 | MQ-005 | | | | 15K | | | +| MQ-005 | done | CLI: commander wiring for create/list/show/claim/release/complete | TASKS:P1 | queue | feat/core-queue | MQ-004 | MQ-006 | | | | 10K | | | +| MQ-006 | done | MCP server: queue_list/get/claim/heartbeat/release/complete/fail/status tools | TASKS:P1 | queue | feat/core-queue | MQ-005 | MQ-007 | | | | 15K | | | +| MQ-007 | done | Unit tests for claim atomicity + state transitions + MCP tool schemas | TASKS:P1 | queue | feat/core-queue | MQ-006 | MQ-008 | | | | 15K | | | +| MQ-008 | done | README, package.json bin entry, npm publish prep | TASKS:P1 | queue | feat/core-queue | MQ-007 | | | | | 5K | | | diff --git a/packages/queue/package.json b/packages/queue/package.json index 3fa4860..3b32005 100644 --- a/packages/queue/package.json +++ b/packages/queue/package.json @@ -2,16 +2,34 @@ "name": "@mosaic/queue", "version": "0.0.1", "description": "Valkey-backed task queue exposed via CLI and MCP", + "license": "MIT", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "bin": { + "mosaic": "dist/bin/mosaic.js", + "mosaic-queue-mcp": "dist/bin/mosaic-queue-mcp.js" + }, "files": [ "dist" ], "scripts": { "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"vitest.config.ts\"", "build": "tsc -p tsconfig.build.json", - "test": "vitest run" + "test": "vitest run", + "prepublishOnly": "pnpm lint && pnpm test && pnpm build" + }, + "engines": { + "node": ">=20.0.0" + }, + "publishConfig": { + "access": "public" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.27.1", diff --git a/packages/queue/src/bin/mosaic-queue-mcp.ts b/packages/queue/src/bin/mosaic-queue-mcp.ts new file mode 100644 index 0000000..f7514ec --- /dev/null +++ b/packages/queue/src/bin/mosaic-queue-mcp.ts @@ -0,0 +1,11 @@ +#!/usr/bin/env node + +import { startQueueMcpServer } from '../mcp-server.js'; + +try { + await startQueueMcpServer(); +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(message); + process.exitCode = 1; +} diff --git a/packages/queue/src/bin/mosaic.ts b/packages/queue/src/bin/mosaic.ts new file mode 100644 index 0000000..ca849cf --- /dev/null +++ b/packages/queue/src/bin/mosaic.ts @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +import { runQueueCli } from '../cli.js'; + +const exitCode = await runQueueCli(process.argv); +process.exitCode = exitCode;