feinai 0.5.0 → 0.5.2

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 CHANGED
@@ -1,230 +1,174 @@
1
- # tasca — run agents in parallel. know exactly what each one is doing.
1
+ # feinai
2
2
 
3
- Working with AI agents on complex features is powerful — until the coordination overhead swallows the productivity. I was using markdown files (`QUEUE.md`, `SPECS-QUEUE.md`, plan checklists) to track specs and tasks across sessions. The files grew without bound. Agents had to read the whole thing to extract a handful of lines. Context windows filled with stale state. Keeping files current after each task required discipline I didn't always have, and the more agents worked in parallel, the more likely a file was to be inconsistent.
3
+ **Multi-agent development breaks down without coordination infrastructure.**
4
4
 
5
- So I built **tasca**: a dual-interface tool (CLI + HTTP API) that serves both humans and agents. Agents claim tasks atomically, get exactly the context they need, and report results all in single calls. Humans watch a live dashboard that shows which tasks exist, who's working on them, which files are being touched, and what the final outcome was. The underlying state lives in a local SQLite file and never leaves your machine.
5
+ Skills and prompts get agents started. They don't solve what happens when five agents run in parallel: stale state, token waste reading giant markdown files, tasks claimed twice, agents stepping on each other's work, no visibility into what's actually happening.
6
6
 
7
- It ships with a set of skills — `tasca-sdd`, `tasca-write-spec`, `tasca-write-tasks`, `tasca-dispatch` — that replace the markdown-file side-effects of the SDD workflow with atomic CLI calls. The skills are drop-in replacements: if a project has `.tasca/tasca.db`, Claude uses tasca; otherwise it falls back to regular superpowers markdown flow.
7
+ feinai is the missing layer.
8
+
9
+ ---
10
+
11
+ ## The problems it solves
12
+
13
+ **Token waste.** Agents reading `QUEUE.md` or `BACKLOG.md` to find their next task burn context on irrelevant state. A 200-line plan file costs tokens every time — most of it noise for any given agent. feinai gives each agent exactly what it needs in a single call.
14
+
15
+ **Inconsistent task state.** Two agents claim the same task. One overwrites the other's work. You find out when the merge fails. feinai's `take` is an atomic SQL operation — if two agents race, one wins and one gets rejected. No duplicates, no silent overwrites.
16
+
17
+ **No isolation.** Agents sharing a branch corrupt each other's work mid-task. feinai-dispatch puts every agent in its own git worktree, linked to a specific task, visible in the dashboard. Work is isolated until it's ready to merge.
18
+
19
+ **Zero visibility.** You don't know which agent is doing what, which files it touched, how long it's been running, or whether it's stuck. The feinai dashboard shows all of this live.
20
+
21
+ **Skill-based approaches hit a ceiling.** Skills and prompt instructions are probabilistic — the model can ignore them, misinterpret them, or hallucinate state. Deterministic coordination requires a tool, not a suggestion. feinai makes the workflow atomic, auditable, and race-free at the infrastructure level.
22
+
23
+ ---
24
+
25
+ ## What feinai is
26
+
27
+ A CLI + HTTP API + dashboard that serves as the single source of truth for multi-agent development workflows.
28
+
29
+ - **Specs** — what to build and why
30
+ - **Plans** — how to build it
31
+ - **Tasks** — atomic units of work, with dependencies, quality gates, and worktree links
32
+ - **Dashboard** — live view of every agent, every worktree, every file being touched
8
33
 
9
34
  ```bash
10
- tasca take TASK-121-A
35
+ feinai take TASK-121-A
11
36
  # → {id, subject, description, workplan, packages, quality_gates, worktree, ...}
12
- # One call. Everything the agent needs to start.
37
+ # One call. Everything the agent needs. Nothing it doesn't.
13
38
  ```
14
39
 
15
- ## Why tasca
40
+ State lives in a local SQLite file. No cloud, no server, no account.
16
41
 
17
- - **Atomic commands** — `take` returns the full task payload (subject + description + workplan + quality gates) in a single response.
18
- - **Concurrency-safe** — `take` is an atomic SQL UPDATE; two agents can't claim the same task.
19
- - **Queryable** — filter by status, owner, spec without parsing markdown.
20
- - **Auditable** — every operation is logged in an append-only events table.
21
- - **Local-first** — SQLite file at `.tasca/tasks.db`, no server, no cloud.
22
-
23
- ## Status
24
-
25
- Alpha. Built for use in real SDD workflows; API may change before 1.0.
42
+ ---
26
43
 
27
44
  ## Install
28
45
 
29
46
  Requires [Bun](https://bun.sh) 1.3+.
30
47
 
31
48
  ```bash
32
- # From source (recommended during alpha)
33
- git clone https://github.com/mvisca/tasca
34
- cd tasca
35
- bun install
36
- bun link # registers `tasca` as global command
49
+ bun install -g feinai
37
50
  ```
38
51
 
39
- ### Activate the Claude Code skills
52
+ Installs two binaries: `feinai` and `opengit` (safe git wrapper for parallel worktrees).
53
+
54
+ ### PATH setup
40
55
 
41
- `tasca` ships four Claude Code skills that replace the markdown-file SDD workflow end to end. Link them into your global skills directory:
56
+ Works out of the box in interactive terminals and for local AI agents (Claude Code, opencode).
57
+
58
+ **Non-interactive SSH sessions only** (e.g. `ssh host 'feinai status'`) need a one-time fix:
42
59
 
43
60
  ```bash
44
- mkdir -p ~/.claude/skills
45
- ln -sfn "$(pwd)/skills/tasca-sdd" ~/.claude/skills/tasca-sdd
46
- ln -sfn "$(pwd)/skills/tasca-write-spec" ~/.claude/skills/tasca-write-spec
47
- ln -sfn "$(pwd)/skills/tasca-write-tasks" ~/.claude/skills/tasca-write-tasks
48
- ln -sfn "$(pwd)/skills/tasca-dispatch" ~/.claude/skills/tasca-dispatch
61
+ sudo ln -sf ~/.bun/bin/feinai /usr/local/bin/feinai
62
+ sudo ln -sf ~/.bun/bin/opengit /usr/local/bin/opengit
63
+ sudo ln -sf ~/.bun/bin/bun /usr/local/bin/bun
49
64
  ```
50
65
 
51
- Skills activate automatically in projects that have `.tasca/tasca.db`.
66
+ ### Activate Claude Code skills
52
67
 
53
- Future install paths (post-alpha):
54
- - `npm install -g tasca` (with Bun installed)
55
- - Pre-compiled binaries from GitHub Releases (with checksums)
56
- - Claude Code marketplace plugin (bundles CLI + skills)
68
+ ```bash
69
+ mkdir -p ~/.claude/skills
70
+ SKILLS="$(bun pm bin -g)/../lib/node_modules/feinai/skills"
71
+ for skill in feinai-sdd feinai-write-spec feinai-write-tasks feinai-dispatch feinai-implement; do
72
+ ln -sf "$SKILLS/$skill" ~/.claude/skills/$skill
73
+ done
74
+ ```
75
+
76
+ ---
57
77
 
58
78
  ## Quick start
59
79
 
60
80
  ```bash
61
- # 1. Initialize a tasca DB in your project
62
81
  cd my-project
63
- tasca init
64
- # → Creates .tasca/tasca.db
65
-
66
- # 2. Register a spec with its markdown content (typically done by brainstorming skill)
67
- tasca spec add SPEC-001 "User authentication" \
68
- --file specs/001-auth/spec.md
69
- # OR via stdin:
70
- cat specs/001-auth/spec.md | tasca spec add SPEC-001 "User authentication" --stdin
71
-
72
- # 3. Register the implementation plan (typically done by writing-plans skill)
73
- cat plan.md | tasca plan add SPEC-001 --stdin
74
-
75
- # 4. Add tasks (typically done by writing-plans skill)
76
- tasca add TASK-001-A "Create auth schema" \
77
- --spec SPEC-001 \
78
- --desc "Define Drizzle schema for users table..." \
79
- --package "@app/auth" \
80
- --gate "pnpm typecheck" \
81
- --gate "pnpm test -- --run"
82
-
83
- # 5. Agent takes the task (atomic — returns full task JSON in single call)
84
- tasca take TASK-001-A
85
- # Owner is auto-detected as "{parent_process}:{pid}:{username}"
86
- # Override via $TASCA_USER env var
87
-
88
- # 6. Agent marks done
89
- tasca done TASK-001-A --result "typecheck ✓ test ✓"
90
-
91
- # 7. Export content when needed
92
- tasca spec content SPEC-001 > /tmp/spec.md
93
- tasca plan show SPEC-001 > /tmp/plan.md
82
+ feinai init # creates .tasca/tasca.db, adds to .gitignore
83
+
84
+ feinai spec add SPEC-001 "User authentication" --content "..."
85
+ feinai plan add SPEC-001 --content "..."
86
+ feinai add TASK-001-A "Create auth schema" --spec SPEC-001 --gate "pnpm typecheck"
87
+
88
+ feinai take TASK-001-A # atomic claim — returns full task payload
89
+ feinai done TASK-001-A --result "typecheck "
90
+
91
+ feinai server # live dashboard at http://127.0.0.1:8272
94
92
  ```
95
93
 
96
- ## Commands
94
+ ---
97
95
 
98
- | Command | Purpose |
96
+ ## Skills
97
+
98
+ feinai ships five Claude Code skills covering the full development lifecycle:
99
+
100
+ | Skill | Purpose |
99
101
  |---|---|
100
- | `tasca init` | Create `.tasca/tasks.db` in cwd |
101
- | `tasca status` | Summary: pending / in_progress / completed counts |
102
- | `tasca list [filters]` | List tasks with optional filters |
103
- | `tasca add ID "subject"` | Create a new task |
104
- | `tasca show ID` | Show full task detail |
105
- | `tasca take ID` | Atomically claim a pending task |
106
- | `tasca done ID --result "..."` | Mark task completed |
107
- | `tasca fail ID --error "..."` | Mark task failed |
108
- | `tasca block ID --by BLOCKER` | Add a dependency |
109
- | `tasca spec add ID "title"` | Register a spec |
110
- | `tasca spec list` | List all specs |
111
- | `tasca spec show ID` | Spec details |
112
- | `tasca spec start ID` | Mark spec as in progress |
113
- | `tasca spec done ID --pr N` | Mark spec as completed |
114
- | `tasca server [--port N]` | Start HTTP dashboard + REST API |
115
-
116
- Run `tasca --help` for full flag reference.
117
-
118
- ## Dashboard & API
102
+ | `feinai-sdd` | Activates when `.tasca/tasca.db` exists teaches Claude the workflow |
103
+ | `feinai-write-spec` | Writes spec + plan into feinai from a design conversation |
104
+ | `feinai-write-tasks` | Decomposes plan into atomic tasks with parallelism analysis |
105
+ | `feinai-dispatch` | Orchestrates subagents in isolated git worktrees |
106
+ | `feinai-implement` | Claims and executes one task end-to-end |
119
107
 
120
- ```bash
121
- tasca server # starts on http://127.0.0.1:8272 (TASC on phone keypad)
122
- tasca server --port 8080 # custom port
108
+ Full lifecycle: design → spec → tasks → parallel execution → merge.
109
+
110
+ ---
111
+
112
+ ## Commands
113
+
114
+ ```
115
+ feinai init Create .tasca/tasca.db
116
+ feinai status Pending / in_progress / completed counts
117
+ feinai list [--pending] [--spec X] List tasks
118
+ feinai add ID "subject" Create task
119
+ feinai take ID Atomic claim — returns full task JSON
120
+ feinai done ID --result "..." Mark completed
121
+ feinai fail ID --error "..." Mark failed
122
+ feinai release ID Release back to pending
123
+ feinai spec add/list/show/done Spec lifecycle
124
+ feinai plan add/show Plan versions
125
+ feinai git <cmd> Safe git wrapper (blocks merge/rebase/checkout)
126
+ feinai server [--port N] [-d] Dashboard + REST API
123
127
  ```
124
128
 
125
- The dashboard is a single self-contained HTML page (no external assets, ships
126
- inside the compiled binary). Features:
127
-
128
- - **Real-time updates via SSE** — no polling; dashboard reacts instantly to CLI mutations from any process
129
- - **Markdown rendering** — spec content, plans, descriptions all render properly
130
- - **Action buttons** — take / done / fail tasks and start / done specs directly from the UI
131
- - **Create from UI** — new spec / new task forms with markdown editor
132
- - **Full-text search** — searches across specs (title + content) and tasks (subject + description)
133
- - **Live indicator** — green pulse = SSE connected, red = disconnected
134
-
135
- ### REST API
136
-
137
- #### Read endpoints
138
-
139
- | Method | Path | Returns |
140
- |---|---|---|
141
- | GET | `/api/status` | Stats: counts per status |
142
- | GET | `/api/specs` | Specs with task summary and latest plan version |
143
- | GET | `/api/specs/:id` | Spec + tasks + plans + latest plan content |
144
- | GET | `/api/specs/:id/content` | Raw markdown of the spec |
145
- | GET | `/api/specs/:id/plan` | Raw markdown of the latest plan |
146
- | GET | `/api/tasks?status=&spec=&owner=` | Filtered task list |
147
- | GET | `/api/tasks/:id` | Single task |
148
- | GET | `/api/events?limit=N` | Recent audit log entries |
149
- | GET | `/api/search?q=...` | Search specs and tasks |
150
- | GET | `/api/events/stream` | SSE stream of new events as they happen |
151
-
152
- #### Mutation endpoints (since v0.4)
153
-
154
- | Method | Path | Body |
155
- |---|---|---|
156
- | POST | `/api/specs` | `{id, title, content?}` |
157
- | POST | `/api/specs/:id/start` | `{}` |
158
- | POST | `/api/specs/:id/done` | `{pr?, merged_date?}` |
159
- | POST | `/api/specs/:id/content` | `{content}` (replace) |
160
- | POST | `/api/specs/:id/plans` | `{content}` (new version) |
161
- | POST | `/api/tasks` | `{id, subject, description?, spec_id?, packages?, quality_gates?, blocked_by?}` |
162
- | POST | `/api/tasks/:id/take` | `{owner?}` (atomic; rejects if not pending) |
163
- | POST | `/api/tasks/:id/done` | `{result}` |
164
- | POST | `/api/tasks/:id/fail` | `{error}` |
165
- | POST | `/api/tasks/:id/block` | `{by}` |
166
-
167
- Set the `X-Tasca-Actor` header to identify yourself in the audit log
168
- (e.g. `X-Tasca-Actor: dashboard`, `X-Tasca-Actor: ci-bot`). If unset, the
169
- server infers actor from the User-Agent.
170
-
171
- ### Security notes
172
-
173
- The server binds to `127.0.0.1` by default — no external access. There is no
174
- authentication built in; the model assumes the local machine is trusted (same
175
- as a dev server). If you bind to `0.0.0.0`, put it behind a reverse proxy with
176
- auth.
177
-
178
- ## Output formats
129
+ ---
130
+
131
+ ## Dashboard
179
132
 
180
133
  ```bash
181
- tasca list # auto: color if TTY, plain otherwise
182
- tasca list --plain # explicit plain (no ANSI codes)
183
- tasca list --json # JSON for agents and scripts
134
+ feinai server -d # background, port 8272
135
+ feinai server --port 9000 # custom port
184
136
  ```
185
137
 
186
- ## Claude Code skills
187
-
188
- `tasca` ships four skills that cover the full [Spec-Driven Development](https://github.com/anthropics/superpowers) cycle. They replace the markdown-file workflow entirely — no `docs/superpowers/` directory, no growing plan files, no token waste reading stale state.
138
+ Shows per agent: task ID, worktree path, repo, files being modified, elapsed time. Green ripple when agents are active, gray when idle. Real-time via SSE.
189
139
 
190
- | Skill | When Claude uses it | What it does |
191
- |---|---|---|
192
- | `tasca-sdd` | Always, when `.tasca/tasca.db` exists | Master skill — teaches Claude the tasca workflow; activates the others |
193
- | `tasca-write-spec` | Designing a new feature | Writes spec + implementation plan directly into tasca (`tasca spec add` + `tasca plan add`) |
194
- | `tasca-write-tasks` | After spec + plan exist | Decomposes the plan into atomic tasks with file-level parallelism analysis and `blocked_by` dependencies |
195
- | `tasca-dispatch` | Executing a spec | Dispatches subagents into git worktrees; each agent calls `tasca take`, works in isolation, reports via `tasca done` |
140
+ ---
196
141
 
197
- The skills are drop-in: in projects without tasca, Claude falls back to the regular superpowers markdown flow.
142
+ ## `feinai git`
198
143
 
199
- ## Architecture
144
+ Safe git wrapper that enforces worktree-only workflow. Blocks operations that break parallel work:
200
145
 
201
- ```
202
- ~/.tasca/ (future) global config
203
- <project>/.tasca/tasca.db local SQLite, auto-discovered like .git
204
-
205
- Tables:
206
- specs (id, numero, title, status, content TEXT, pr, merged_date, ...)
207
- plans (id, spec_id FK, content TEXT, version, created_at)
208
- indexed on spec_id for fast lookup; unique(spec_id, version)
209
- tasks (id, spec_id, subject, description, status, owner,
210
- blocked_by, packages, quality_gates, result, error, ...)
211
- events (append-only audit log of every operation, with actor)
146
+ ```bash
147
+ feinai git worktree add .worktrees/TASK-001 origin/main
148
+ feinai git add . && feinai git commit -m "feat: ..."
149
+ feinai git push origin HEAD:main
150
+ feinai git complete # sync main after push
212
151
  ```
213
152
 
214
- `tasca` walks up the directory tree from `cwd` looking for `.tasca/tasca.db`, the same way git locates `.git`. This means you can run `tasca` commands from any subdirectory of your project.
153
+ Blocked: `branch`, `checkout`, `merge`, `rebase`, `reset`, `fetch`, `pull`, `clone`.
215
154
 
216
- ### Why the content lives in the DB
155
+ ---
217
156
 
218
- `tasca` stores the actual markdown of specs and plans inside SQLite, not as paths to external files. This means:
219
- - `tasca` is the single source of truth — no risk of broken paths or moved files
220
- - Plans can have multiple versions tracked (revisions during refinement)
221
- - Export to markdown is trivial: `tasca spec content SPEC-X > spec.md`
222
- - An agent calling `tasca spec content SPEC-X` gets the same bytes the human gets, deterministically
157
+ ## Architecture
158
+
159
+ ```
160
+ <project>/.tasca/tasca.db local SQLite, walks up from cwd like .git
161
+
162
+ specs — what to build
163
+ plans — how to build it (versioned)
164
+ tasks — atomic work units with blocked_by, quality_gates, worktree
165
+ events — append-only audit log: {parent_process}:{pid}:{user}
166
+ ```
223
167
 
224
- ### Audit log
168
+ Every mutation is logged. Every agent is identified. Override identity with `$FEINA_USER`.
225
169
 
226
- Every mutation records an event in the `events` table with an `actor` identifier of the form `{parent_process}:{pid}:{username}` (e.g., `claude:12345:m`, `opencode:67890:m`, `bash:99999:m`). Override with `$TASCA_USER` for explicit agent identity.
170
+ ---
227
171
 
228
172
  ## License
229
173
 
230
- MIT
174
+ MIT — built with ❤️ in Barcelona. *Feina* means "work" in Catalan.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feinai",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Task & spec manager for AI agents — parallel worktrees, live dashboard, SDD skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,38 @@ Execute the pending tasks of a SPEC. One responsibility: dispatch subagents in w
9
9
 
10
10
  ## Preconditions
11
11
 
12
+ Before anything else, verify the environment:
13
+
14
+ ```bash
15
+ feinai --version 2>&1
16
+ feinai git status 2>&1
17
+ ```
18
+
19
+ **If `feinai: command not found` or `opengit: command not found`:**
20
+
21
+ This means `~/.bun/bin` is not on PATH in this shell context. This is a known issue with bun global installs in non-interactive sessions.
22
+
23
+ Tell the user:
24
+
25
+ > `feinai` (or `opengit`) is not on PATH in this shell context. This happens in non-interactive SSH sessions where `~/.bun/bin` is not loaded.
26
+ >
27
+ > Fix with a one-time symlink (requires sudo/root):
28
+ > ```bash
29
+ > sudo ln -sf ~/.bun/bin/feinai /usr/local/bin/feinai
30
+ > sudo ln -sf ~/.bun/bin/opengit /usr/local/bin/opengit
31
+ > sudo ln -sf ~/.bun/bin/bun /usr/local/bin/bun
32
+ > ```
33
+ > Or if root access is available via a different user (e.g. `do-hermes`):
34
+ > ```bash
35
+ > ssh do-hermes "ln -sf /home/martin/.bun/bin/feinai /usr/local/bin/feinai && ln -sf /home/martin/.bun/bin/opengit /usr/local/bin/opengit && ln -sf /home/martin/.bun/bin/bun /usr/local/bin/bun"
36
+ > ```
37
+ >
38
+ > Want me to run this fix now?
39
+
40
+ **Do not proceed until `feinai --version` returns a version number.**
41
+
42
+ Then verify:
43
+
12
44
  1. `feinai status` succeeds
13
45
  2. The SPEC has pending tasks: `feinai list --spec SPEC-NNN --pending --json` returns non-empty
14
46
  3. The current working directory is a clean git repo (no uncommitted changes blocking worktree creation)
package/src/cli.ts CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  type OutputFormat,
49
49
  } from "./format";
50
50
 
51
- const VERSION = "0.5.0";
51
+ const VERSION = "0.5.2";
52
52
 
53
53
  interface ParsedArgs {
54
54
  positional: string[];