feinai 0.6.4 → 0.6.6

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 CHANGED
@@ -12,23 +12,23 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
12
12
  ## [0.5.0] - 2026-06-10
13
13
 
14
14
  ### Added
15
- - `tasca git <cmd>` — safe git wrapper subcommand. Passes through to `opengit`, enforcing a worktree-only whitelist (blocks branch, merge, rebase, checkout, etc.)
16
- - `opengit` shipped as a binary alongside `tasca` — `bun install -g tasca` now installs both
17
- - `tasca unblock <TASK-ID> --dep <TASK-ID>` — remove a specific dependency from a task
18
- - `tasca edit --clear-blocked-by` — clear all dependencies from a task
19
- - Live Agents Monitor: working directory, repo name, and `.tasca` path shown per agent card
15
+ - `feinai git <cmd>` — safe git wrapper subcommand. Passes through to `opengit`, enforcing a worktree-only whitelist (blocks branch, merge, rebase, checkout, etc.)
16
+ - `opengit` shipped as a binary alongside `feinai` — `bun install -g feinai` now installs both
17
+ - `feinai unblock <TASK-ID> --dep <TASK-ID>` — remove a specific dependency from a task
18
+ - `feinai edit --clear-blocked-by` — clear all dependencies from a task
19
+ - Live Agents Monitor: working directory, repo name, and `.feinai` path shown per agent card
20
20
  - Live Agents Monitor: presence indicator — gray dot when idle, green dot with ripple animation when agents are active
21
21
  - Live Agents Monitor: elapsed time and spec ID per card
22
- - `tasca init` now auto-adds `.tasca/` to `.gitignore` if in a git repo
23
- - Skills: `tasca-implement` — claim one pending task, implement in isolated worktree, run quality gates, push to main
22
+ - `feinai init` now auto-adds `.feinai/` to `.gitignore` if in a git repo
23
+ - Skills: `feinai-implement` — claim one pending task, implement in isolated worktree, run quality gates, push to main
24
24
 
25
25
  ### Changed
26
26
  - Dashboard is now English-only — removed i18n/language selector
27
- - `tasca-implement` SKILL.md updated to use `tasca git` instead of `opengit` directly
27
+ - `feinai-implement` SKILL.md updated to use `feinai git` instead of `opengit` directly
28
28
  - `package.json`: added `repository`, `homepage`, `bugs` fields
29
29
 
30
30
  ### Skills included
31
- `tasca-sdd` · `tasca-write-spec` · `tasca-write-tasks` · `tasca-dispatch` · `tasca-implement`
31
+ `feinai-sdd` · `feinai-write-spec` · `feinai-write-tasks` · `feinai-dispatch` · `feinai-implement`
32
32
 
33
33
  ---
34
34
 
@@ -37,11 +37,11 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
37
37
  Initial public release. Core CLI with specs, plans, tasks, HTTP dashboard, and SDD skills.
38
38
 
39
39
  ### Features
40
- - `tasca init / status / list / add / show / take / done / fail / block / release / reopen / edit`
41
- - `tasca spec` — spec lifecycle (add, start, done, archive, set-content, edit)
42
- - `tasca plan` — plan revisions per spec
43
- - `tasca server` — HTTP dashboard + REST API + SSE live updates
40
+ - `feinai init / status / list / add / show / take / done / fail / block / release / reopen / edit`
41
+ - `feinai spec` — spec lifecycle (add, start, done, archive, set-content, edit)
42
+ - `feinai plan` — plan revisions per spec
43
+ - `feinai server` — HTTP dashboard + REST API + SSE live updates
44
44
  - Live Agents Monitor — real-time view of in-progress tasks with worktree state
45
45
  - Atomic `take` — SQL-level concurrency safety for parallel agents
46
46
  - Append-only events audit log
47
- - Skills: `tasca-sdd`, `tasca-write-spec`, `tasca-write-tasks`, `tasca-dispatch`
47
+ - Skills: `feinai-sdd`, `feinai-write-spec`, `feinai-write-tasks`, `feinai-dispatch`
package/README.md CHANGED
@@ -1,73 +1,134 @@
1
1
  # feinai
2
2
 
3
- **Multi-agent development breaks down without coordination infrastructure.**
3
+ Local coordination layer for multi‑agent coding workflows.
4
4
 
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.
5
+ When multiple coding agents work on the same repo, things break long before the model runs out of IQ: duplicated work, inconsistent task state, agents trampling each other's branches, and no clear visibility into what is happening where.
6
6
 
7
- feinai is the missing layer.
7
+ **feinai** focuses on one thing: make that coordination deterministic, auditable, and safe for your git repo – locally, without a cloud service.
8
8
 
9
9
  ---
10
10
 
11
- ## The problems it solves
11
+ ## Why feinai
12
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.
13
+ Multi‑agent development breaks down without coordination infrastructure. Skills and prompts get agents started, but they do not solve the ugly parts of running several agents in parallel:
14
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.
15
+ - **Token waste on shared Markdown.** 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.
16
+ - **Inconsistent task state.** Two agents claim the same task. One overwrites the other's work. You find out when the merge fails. `feinai take` is an atomic SQL operation – if two agents race, one wins and one gets rejected. No duplicates, no silent overwrites.
17
+ - **No isolation in git.** Agents sharing a branch corrupt each other's work midtask. `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
+ - **Zero visibility.** You don't know which agent is doing what, which files it touched, how long it has been running, or whether it's stuck. The feinai dashboard shows all of this live.
19
+ - **Skills 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
20
 
23
21
  ---
24
22
 
25
23
  ## What feinai is
26
24
 
27
- A CLI + HTTP API + dashboard that serves as the single source of truth for multi-agent development workflows.
25
+ feinai is a **CLI + HTTP API + dashboard** that acts as the single source of truth for multiagent development workflows on a git repo.
26
+
27
+ It manages four core primitives:
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
+ - **Events** – append‑only audit log of every state change.
28
33
 
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
34
+ Agents never read raw Markdown queues. They ask feinai for work:
33
35
 
34
- ```bash
36
+ ```sh
35
37
  feinai take TASK-121-A
36
38
  # → {id, subject, description, workplan, packages, quality_gates, worktree, ...}
37
39
  # One call. Everything the agent needs. Nothing it doesn't.
38
40
  ```
39
41
 
40
- State lives in a local SQLite file. No cloud, no server, no account.
42
+ State lives in a local SQLite file. No cloud, no external service, no account.
41
43
 
42
44
  ---
43
45
 
44
- ## Install
46
+ ## Core concepts
45
47
 
46
- Requires [Bun](https://bun.sh) 1.3+.
48
+ - **Specs**
49
+ High‑level product requirements: why a feature exists and what "done" means. Specs link to plans and tasks.
47
50
 
48
- ```bash
49
- bun install -g feinai
50
- ```
51
+ - **Plans**
52
+ Versioned implementation plans for a spec. A plan explains how to build it – steps, trade‑offs, constraints.
51
53
 
52
- Installs two binaries: `feinai` and `opengit` (safe git wrapper for parallel worktrees).
54
+ - **Tasks**
55
+ Atomic units of work with:
56
+ - An ID (`TASK-001-A`)
57
+ - Subject and description
58
+ - Optional `blocked_by` dependencies
59
+ - `quality_gates` (commands/tests that must pass)
60
+ - A dedicated git worktree path
53
61
 
54
- ### PATH setup
62
+ - **Events**
63
+ Append‑only log of everything that happens: `{parent_process}:{pid}:{user}`, timestamps, transitions. Every mutation to specs, plans, tasks or worktrees is recorded.
55
64
 
56
- Works out of the box in interactive terminals and for local AI agents (Claude Code, opencode).
65
+ - **Worktrees**
66
+ Each task gets its own git worktree. Agents commit and push from there. The main branch stays clean until the work is ready to integrate.
57
67
 
58
- **Non-interactive SSH sessions only** (e.g. `ssh host 'feinai status'`) need a one-time fix:
68
+ ---
59
69
 
60
- ```bash
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
64
- ```
70
+ ## Runtime & footprint
71
+
72
+ - Implemented on top of **Bun 1.3+**.
73
+ - Installs two binaries:
74
+ - `feinai` – main CLI + embedded HTTP server and dashboard.
75
+ - `opengit` – safe git wrapper for parallel worktrees.
76
+ - Stores all state in a single SQLite file: `.feinai/feinai.db`, discovered by walking up from the current directory (like `.git`).
65
77
 
66
- ### Activate Claude Code skills
78
+ No background services are required beyond the optional dashboard server.
79
+
80
+ ---
67
81
 
68
- ```bash
82
+ ## Supply chain & safety
83
+
84
+ feinai is designed to be "boring" infrastructure:
85
+
86
+ - **Local‑only state.** All coordination lives in `.feinai/feinai.db` in your repo. There is no remote backend.
87
+ - **Explicit operations.** Every change to specs, plans, tasks and worktrees goes through the CLI or HTTP API and is logged in `events`.
88
+ - **Safe git workflow.** `feinai git` wraps git and blocks operations that can corrupt parallel worktrees (branch, checkout, merge, rebase, reset, fetch, pull, clone).
89
+ - **Auditability.** Every task has a clear chain: spec → plan → task → worktree → events. Every agent identity can be traced (`$FEINAI_USER` override supported).
90
+
91
+ ---
92
+
93
+ ## Using feinai with coding agents
94
+
95
+ feinai is built to sit **under** coding agents (Claude Code, pi‑style harnesses, etc.) as a coordination layer.
96
+
97
+ A typical pattern:
98
+
99
+ 1. Human or design agent writes a spec and plan.
100
+ 2. feinai decomposes the plan into tasks with dependencies and quality gates.
101
+ 3. Worker agents:
102
+ - Call `feinai take` to claim a task atomically.
103
+ - Work in the dedicated worktree for that task.
104
+ - Run quality gates (tests, linters, typechecks).
105
+ - Mark the task as `done` or `fail` with a structured result.
106
+ 4. A human (or integration agent) reviews and merges.
107
+
108
+ Agents don't parse `QUEUE.md`. They talk to a small local coordination service instead.
109
+
110
+ ---
111
+
112
+ ## Claude Code skills
113
+
114
+ feinai ships five Claude Code skills covering the full development loop. They activate automatically when `.feinai/feinai.db` is present:
115
+
116
+ | Skill | Purpose |
117
+ |---------------------|--------------------------------------------------------|
118
+ | `feinai-sdd` | Teaches Claude the feinai workflow and concepts |
119
+ | `feinai-write-spec` | Writes spec + plan into feinai from a design thread |
120
+ | `feinai-write-tasks`| Decomposes a plan into atomic tasks with parallelism |
121
+ | `feinai-dispatch` | Orchestrates subagents in isolated git worktrees |
122
+ | `feinai-implement` | Claims and executes one task end‑to‑end |
123
+
124
+ Together they cover: design → spec → plan → tasks → parallel execution → merge.
125
+
126
+ ### Activating skills in Claude Code
127
+
128
+ ```sh
69
129
  mkdir -p ~/.claude/skills
70
130
  SKILLS=~/.bun/install/global/node_modules/feinai/skills
131
+
71
132
  for skill in feinai-sdd feinai-write-spec feinai-write-tasks feinai-dispatch feinai-implement; do
72
133
  ln -sf "$SKILLS/$skill" ~/.claude/skills/$skill
73
134
  done
@@ -75,53 +136,79 @@ done
75
136
 
76
137
  ---
77
138
 
78
- ## Quick start
139
+ ## Installation
79
140
 
80
- ```bash
81
- cd my-project
82
- feinai init # creates .tasca/tasca.db, adds to .gitignore
141
+ Requires [Bun](https://bun.sh/) 1.3+.
83
142
 
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"
143
+ ```sh
144
+ bun install -g feinai
145
+ ```
87
146
 
88
- feinai take TASK-001-A # atomic claim — returns full task payload
89
- feinai done TASK-001-A --result "typecheck ✓"
147
+ This installs:
90
148
 
91
- feinai server # live dashboard at http://127.0.0.1:8272
149
+ - `feinai`
150
+ - `opengit` (safe git wrapper for parallel worktrees)
151
+
152
+ ### PATH setup (non‑interactive SSH)
153
+
154
+ In interactive shells and for local agents (Claude Code, opencode) it should work out of the box.
155
+
156
+ For non‑interactive SSH sessions (e.g. `ssh host 'feinai status'`), you may need a one‑time setup:
157
+
158
+ ```sh
159
+ sudo ln -sf ~/.bun/bin/feinai /usr/local/bin/feinai
160
+ sudo ln -sf ~/.bun/bin/opengit /usr/local/bin/opengit
161
+ sudo ln -sf ~/.bun/bin/bun /usr/local/bin/bun
92
162
  ```
93
163
 
94
164
  ---
95
165
 
96
- ## Skills
166
+ ## Quick start
167
+
168
+ ```sh
169
+ cd my-project
170
+
171
+ # Initialize local state
172
+ feinai init # creates .feinai/feinai.db, adds to .gitignore
173
+
174
+ # Add a spec and plan
175
+ feinai spec add SPEC-001 "User authentication" --content "..."
176
+ feinai plan add SPEC-001 --content "..."
177
+
178
+ # Create a task with a quality gate
179
+ feinai add TASK-001-A "Create auth schema" \
180
+ --spec SPEC-001 \
181
+ --gate "pnpm typecheck"
97
182
 
98
- feinai ships five Claude Code skills covering the full development lifecycle:
183
+ # Agent claims a task (atomic)
184
+ feinai take TASK-001-A # returns full task payload as JSON
99
185
 
100
- | Skill | Purpose |
101
- |---|---|
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 |
186
+ # Agent completes work
187
+ feinai done TASK-001-A --result "typecheck ✓"
107
188
 
108
- Full lifecycle: design → spec → tasks → parallel execution → merge.
189
+ # Start dashboard server
190
+ feinai server # live dashboard at http://127.0.0.1:8272
191
+ ```
109
192
 
110
193
  ---
111
194
 
112
195
  ## Commands
113
196
 
114
- ```
115
- feinai init Create .tasca/tasca.db
116
- feinai status Pending / in_progress / completed counts
197
+ High‑level CLI:
198
+
199
+ ```text
200
+ feinai init Create .feinai/feinai.db
201
+ feinai status Show counts: pending / in_progress / completed
117
202
  feinai list [--pending] [--spec X] List tasks
118
203
  feinai add ID "subject" Create task
119
204
  feinai take ID Atomic claim — returns full task JSON
120
205
  feinai done ID --result "..." Mark completed
121
206
  feinai fail ID --error "..." Mark failed
122
207
  feinai release ID Release back to pending
208
+
123
209
  feinai spec add/list/show/done Spec lifecycle
124
210
  feinai plan add/show Plan versions
211
+
125
212
  feinai git <cmd> Safe git wrapper (blocks merge/rebase/checkout)
126
213
  feinai server [--port N] [-d] Dashboard + REST API
127
214
  ```
@@ -130,34 +217,57 @@ feinai server [--port N] [-d] Dashboard + REST API
130
217
 
131
218
  ## Dashboard
132
219
 
133
- ```bash
220
+ Run:
221
+
222
+ ```sh
134
223
  feinai server -d # background, port 8272
135
224
  feinai server --port 9000 # custom port
136
225
  ```
137
226
 
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.
227
+ The dashboard shows per agent:
228
+
229
+ - Current task ID
230
+ - Worktree path and repo
231
+ - Files being modified
232
+ - Elapsed time
233
+
234
+ Active agents ripple in green, idle ones in gray. Updates stream in real time via SSE.
139
235
 
140
236
  ---
141
237
 
142
238
  ## `feinai git`
143
239
 
144
- Safe git wrapper that enforces worktree-only workflow. Blocks operations that break parallel work:
240
+ `feinai git` is a safety wrapper around git for parallel worktrees.
241
+
242
+ Allowed operations include:
145
243
 
146
- ```bash
244
+ ```sh
147
245
  feinai git worktree add .worktrees/TASK-001 origin/main
148
- feinai git add . && feinai git commit -m "feat: ..."
246
+ feinai git add .
247
+ feinai git commit -m "feat: ..."
149
248
  feinai git push origin HEAD:main
150
249
  feinai git complete # sync main after push
151
250
  ```
152
251
 
153
- Blocked: `branch`, `checkout`, `merge`, `rebase`, `reset`, `fetch`, `pull`, `clone`.
252
+ The following are blocked when they would break the parallel workflow:
253
+
254
+ - `branch`
255
+ - `checkout`
256
+ - `merge`
257
+ - `rebase`
258
+ - `reset`
259
+ - `fetch`
260
+ - `pull`
261
+ - `clone`
262
+
263
+ Use your normal git tooling inside each worktree; use `feinai git` when operating on shared branches.
154
264
 
155
265
  ---
156
266
 
157
267
  ## Architecture
158
268
 
159
- ```
160
- <project>/.tasca/tasca.db local SQLite, walks up from cwd like .git
269
+ ```text
270
+ <project>/.feinai/feinai.db # local SQLite database (discovered like .git)
161
271
 
162
272
  specs — what to build
163
273
  plans — how to build it (versioned)
@@ -165,10 +275,16 @@ tasks — atomic work units with blocked_by, quality_gates, worktree
165
275
  events — append-only audit log: {parent_process}:{pid}:{user}
166
276
  ```
167
277
 
168
- Every mutation is logged. Every agent is identified. Override identity with `$FEINAI_USER`.
278
+ Every mutation is logged. Every agent is identified. You can override identity using:
279
+
280
+ ```sh
281
+ export FEINAI_USER="ci-bot-01"
282
+ ```
169
283
 
170
284
  ---
171
285
 
172
286
  ## License
173
287
 
174
- MIT — built with ❤️ in Barcelona. *Feina* means "work" in Catalan.
288
+ MIT — built with ❤️ in Barcelona.
289
+
290
+ "Feina" means "work" in Catalan. feinai is a tiny piece of infrastructure to keep that work coordinated.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feinai",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Task & spec manager for AI agents — parallel worktrees, live dashboard, SDD skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -66,7 +66,7 @@ PATH issue in non-interactive SSH session. `~/.bun/bin` is not loaded. Tell the
66
66
 
67
67
  ---
68
68
 
69
- ### Failure: `feinai status` exits with code 2 (`no .tasca/tasca.db found`)
69
+ ### Failure: `feinai status` exits with code 2 (`no .feinai/feinai.db found`)
70
70
 
71
71
  feinai is installed but no DB in this project. Ask the user:
72
72
 
@@ -206,7 +206,7 @@ Spawn a subagent with this prompt template:
206
206
 
207
207
  ### Step E — Wait for results
208
208
 
209
- Each subagent returns `done` or `fail`. The tasca DB is the source of truth — re-query it:
209
+ Each subagent returns `done` or `fail`. The feinai DB is the source of truth — re-query it:
210
210
 
211
211
  ```bash
212
212
  feinai show TASK-X --json
@@ -1,17 +1,17 @@
1
1
  ---
2
2
  name: feinai-implement
3
- description: Use when a feinai task needs to be executed. Claims one pending task from tasca, implements it in an isolated worktree, runs quality gates, and pushes to main. Designed to be dispatched by feinai-dispatch or run standalone for a single task.
3
+ description: Use when a feinai task needs to be executed. Claims one pending task from feinai, implements it in an isolated worktree, runs quality gates, and pushes to main. Designed to be dispatched by feinai-dispatch or run standalone for a single task.
4
4
  ---
5
5
 
6
6
  # feinai-implement
7
7
 
8
- Claim one pending task from tasca, implement it in an isolated worktree, run quality gates, push to main.
8
+ Claim one pending task from feinai, implement it in an isolated worktree, run quality gates, push to main.
9
9
 
10
10
  ## Preconditions
11
11
 
12
12
  1. `feinai status` succeeds and there is at least one pending task
13
13
  2. Current working directory is a clean git repo
14
- 3. `feinai git status` works (feinai git is bundled with tasca — no separate setup needed)
14
+ 3. `feinai git status` works (feinai git is bundled with feinai — no separate setup needed)
15
15
 
16
16
  If any fails: stop and report. Do not improvise.
17
17
 
@@ -79,7 +79,7 @@ Gates fallan → seguí "Si algo falla".
79
79
  **Done = 3 hechos observables:**
80
80
  1. Quality gates pasan sin errores
81
81
  2. Los archivos de la tarea existen con contenido correcto
82
- 3. Commit limpio en `main` y tarea en estado `completed` en tasca
82
+ 3. Commit limpio en `main` y tarea en estado `completed` en feinai
83
83
 
84
84
  ---
85
85
 
@@ -102,7 +102,7 @@ Gates fallan, push falla, o error en cualquier paso:
102
102
 
103
103
  ## Git — `feinai git` exclusivamente
104
104
 
105
- `git` y `gh` están bloqueados. Usá `feinai git` para todo — es opengit bundleado con tasca.
105
+ `git` y `gh` están bloqueados. Usá `feinai git` para todo — es opengit bundleado con feinai.
106
106
 
107
107
  **Permitido:**
108
108
  - `feinai git worktree add/list/lock/unlock`
@@ -125,7 +125,7 @@ Si `feinai git` falla → **STOP**. No reintentes, no uses `git`. Reportá al us
125
125
  **No modifiques:**
126
126
  - `AGENTS.md`, `CLAUDE.md`
127
127
  - Archivos de configuración de CI/CD, infra, o secretos (`.env`, `.env.*`)
128
- - La DB de tasca directamente
128
+ - La DB de feinai directamente
129
129
 
130
130
  **Código:**
131
131
  - Sin `any` sin comentario justificado en la misma línea
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: feinai-sdd
3
- description: Use when working in spec-driven development (SDD) workflows that involve brainstorming, writing-plans, or subagent-driven-development AND the project has a `\.feinai/feinai.db` file. Replaces creating markdown files in `docs/superpowers/specs/` and `docs/superpowers/plans/` with atomic `feinai` CLI calls, keeping state queryable, race-free, and audit-logged. Also use when the user asks to create a spec, add a task, claim work, or mark progress, in a project that uses tasca.
3
+ description: Use when working in spec-driven development (SDD) workflows that involve brainstorming, writing-plans, or subagent-driven-development AND the project has a `\.feinai/feinai.db` file. Replaces creating markdown files in `docs/superpowers/specs/` and `docs/superpowers/plans/` with atomic `feinai` CLI calls, keeping state queryable, race-free, and audit-logged. Also use when the user asks to create a spec, add a task, claim work, or mark progress.
4
4
  ---
5
5
 
6
6
  # feinai SDD integration
@@ -21,7 +21,7 @@ Invoke when **all** of the following are true:
21
21
 
22
22
  1. The project has a `\.feinai/feinai.db` file (walk up the directory tree from
23
23
  the current working directory; feinai uses the same discovery pattern as git).
24
- Check with: `feinai status` (exit code 0 = tasca is set up).
24
+ Check with: `feinai status` (exit code 0 = feinai is set up).
25
25
  2. You are about to:
26
26
  - Write a spec via the `brainstorming` skill, OR
27
27
  - Write a plan via the `writing-plans` skill, OR
@@ -274,7 +274,7 @@ field will read `bun:<pid>:<user>` for everyone.
274
274
 
275
275
  | Need | Command |
276
276
  |---|---|
277
- | Is tasca set up here? | `feinai status` |
277
+ | Is feinai set up here? | `feinai status` |
278
278
  | Next pending task | `feinai list --pending --json` |
279
279
  | Claim a task atomically | `feinai take TASK-X` |
280
280
  | Read a spec | `feinai spec content SPEC-X` |
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  name: feinai-write-spec
3
- description: Use when the user wants to design a new feature, refactor, or change in a project that has `.tasca/tasca.db`. Writes a complete spec + plan into tasca in a single session. Replaces `brainstorming` + `writing-plans` from superpowers when feinai is active. Reads project context (CLAUDE.md, ARCHITECTURE.md, README.md), asks clarifying questions only when context has gaps, and produces spec+plan atomically with one `feinai spec add` + one `feinai plan add`.
3
+ description: Use when the user wants to design a new feature, refactor, or change in a project that has `.feinai/feinai.db`. Writes a complete spec + plan into feinai in a single session. Replaces `brainstorming` + `writing-plans` from superpowers when feinai is active. Reads project context (CLAUDE.md, ARCHITECTURE.md, README.md), asks clarifying questions only when context has gaps, and produces spec+plan atomically with one `feinai spec add` + one `feinai plan add`.
4
4
  ---
5
5
 
6
6
  # feinai-write-spec
7
7
 
8
- Write a spec + plan for a feature in one session. Output goes to tasca, not markdown files.
8
+ Write a spec + plan for a feature in one session. Output goes to feinai, not markdown files.
9
9
 
10
10
  ## Preconditions
11
11
 
12
- Run `feinai status` (exit 0 = tasca is active). If not active, stop and ask the
12
+ Run `feinai status` (exit 0 = feinai is active). If not active, stop and ask the
13
13
  user if they want `feinai init` or to fall back to vanilla superpowers.
14
14
 
15
15
  ## The flow — three entry modes
@@ -163,7 +163,7 @@ These come up mid-session. Ask them inline, one at a time, brief:
163
163
 
164
164
  If you delegate the spec drafting to a subagent (e.g. for parallel research),
165
165
  the subagent must NOT use this skill — it has no context. Hand it concrete
166
- findings and let it return text; you write to tasca yourself.
166
+ findings and let it return text; you write to feinai yourself.
167
167
 
168
168
  ---
169
169
 
@@ -5,7 +5,7 @@ description: Use when a spec + plan already exist in feinai (written by `feinai-
5
5
 
6
6
  # feinai-write-tasks
7
7
 
8
- Read an existing spec + plan from tasca, produce the executable task set.
8
+ Read an existing spec + plan from feinai, produce the executable task set.
9
9
 
10
10
  ## Preconditions
11
11
 
package/src/cli.ts CHANGED
@@ -381,9 +381,9 @@ async function cmdDestroy(args: ParsedArgs): Promise<void> {
381
381
  }
382
382
  }
383
383
 
384
- const tascaDir = dbPath.replace(/\/tasca\.db$/, "");
385
- rmSync(tascaDir, { recursive: true, force: true });
386
- console.log(`Destroyed ${tascaDir}`);
384
+ const feinaiDir = dbPath.replace(/\/feinai\.db$/, "");
385
+ rmSync(feinaiDir, { recursive: true, force: true });
386
+ console.log(`Destroyed ${feinaiDir}`);
387
387
  }
388
388
 
389
389
  function cmdInit(args: ParsedArgs): void {
@@ -770,7 +770,7 @@ function cmdSpec(rest: string[], args: ParsedArgs, format: OutputFormat): void {
770
770
  async function cmdServer(args: ParsedArgs): Promise<void> {
771
771
  const port = Number(args.options.port ?? "8272");
772
772
 
773
- // --down: kill whatever is listening on the tasca port
773
+ // --down: kill whatever is listening on the feinai port
774
774
  if (args.flags["down"]) {
775
775
  if (Number.isNaN(port) || port < 1 || port > 65535) {
776
776
  console.error("Error: --port must be a valid port number");
@@ -785,7 +785,7 @@ async function cmdServer(args: ParsedArgs): Promise<void> {
785
785
  for (const pid of pids) {
786
786
  try {
787
787
  process.kill(Number(pid), "SIGTERM");
788
- console.log(`Stopped tasca server (PID ${pid}).`);
788
+ console.log(`Stopped feinai server (PID ${pid}).`);
789
789
  } catch {
790
790
  console.error(`Failed to kill PID ${pid}.`);
791
791
  }
@@ -812,8 +812,8 @@ async function cmdServer(args: ParsedArgs): Promise<void> {
812
812
  : [process.execPath, ...process.argv.slice(1).filter(noDaemon)];
813
813
  const child = Bun.spawn(childArgs, { detached: true, stdio: ["ignore", "ignore", "ignore"] });
814
814
  child.unref();
815
- console.log(`tasca dashboard → http://${host}:${port}`);
816
- console.log(`Stop with: tasca server --down`);
815
+ console.log(`feinai dashboard → http://${host}:${port}`);
816
+ console.log(`Stop with: feinai server --down`);
817
817
  return;
818
818
  }
819
819
 
@@ -821,8 +821,8 @@ async function cmdServer(args: ParsedArgs): Promise<void> {
821
821
  const { startServer } = await import("./server");
822
822
  const server = startServer({ port, host });
823
823
 
824
- console.log(`tasca dashboard listening at ${server.url}`);
825
- console.log(`Stop with: tasca server --down`);
824
+ console.log(`feinai dashboard listening at ${server.url}`);
825
+ console.log(`Stop with: feinai server --down`);
826
826
 
827
827
  // Keep process alive until SIGINT
828
828
  process.on("SIGINT", () => {
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>tasca dashboard</title>
6
+ <title>feinai dashboard</title>
7
7
  <style>
8
8
  :root {
9
9
  --bg: #0f1117;
@@ -672,7 +672,7 @@
672
672
  <header>
673
673
  <h1>
674
674
  <span class="live-indicator" id="live"></span>
675
- tasca
675
+ feinai
676
676
  </h1>
677
677
  <div class="stats" id="stats"></div>
678
678
  <div class="header-actions">
@@ -723,7 +723,7 @@
723
723
  </section>
724
724
  </main>
725
725
 
726
- <footer>tasca · streaming live · click any item for details &amp; actions · <span id="dash-version">v—</span></footer>
726
+ <footer>feinai · streaming live · click any item for details &amp; actions · <span id="dash-version">v—</span></footer>
727
727
 
728
728
  <div class="modal-bg" id="modal-bg">
729
729
  <div class="modal" id="modal">
@@ -784,7 +784,7 @@
784
784
  // -------- Confirm modal --------
785
785
  function confirm(message, skipKey) {
786
786
  return new Promise((resolve) => {
787
- if (localStorage.getItem("tasca-skip-" + skipKey) === "1") { resolve(true); return; }
787
+ if (localStorage.getItem("feinai-skip-" + skipKey) === "1") { resolve(true); return; }
788
788
  const overlay = document.createElement("div");
789
789
  overlay.style.cssText = "position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:9999;display:flex;align-items:center;justify-content:center;";
790
790
  overlay.innerHTML = `
@@ -800,7 +800,7 @@
800
800
  </div>`;
801
801
  document.body.appendChild(overlay);
802
802
  overlay.querySelector("#confirm-ok").onclick = () => {
803
- if (overlay.querySelector("#skip-cb").checked) localStorage.setItem("tasca-skip-" + skipKey, "1");
803
+ if (overlay.querySelector("#skip-cb").checked) localStorage.setItem("feinai-skip-" + skipKey, "1");
804
804
  document.body.removeChild(overlay); resolve(true);
805
805
  };
806
806
  overlay.querySelector("#confirm-cancel").onclick = () => { document.body.removeChild(overlay); resolve(false); };
@@ -827,7 +827,7 @@
827
827
  async function api(method, path, body) {
828
828
  const res = await fetch(path, {
829
829
  method,
830
- headers: body ? { "Content-Type": "application/json", "X-Tasca-Actor": "dashboard" } : { "X-Tasca-Actor": "dashboard" },
830
+ headers: body ? { "Content-Type": "application/json", "X-Feinai-Actor": "dashboard" } : { "X-Feinai-Actor": "dashboard" },
831
831
  body: body ? JSON.stringify(body) : undefined,
832
832
  });
833
833
  if (!res.ok) {
@@ -1456,7 +1456,7 @@
1456
1456
  : '';
1457
1457
  const workingDir = task.worktree || appContext.repoRoot || "—";
1458
1458
  const repoName = appContext.repoName || "—";
1459
- const tascaLoc = appContext.tascaPath || "—";
1459
+ const feinaiLoc = appContext.feinaiPath || "—";
1460
1460
  const card = document.createElement('div');
1461
1461
  card.className = 'worktree-card';
1462
1462
  card.setAttribute('data-worktree-task', task.id);
@@ -1469,7 +1469,7 @@
1469
1469
  <div class="worktree-context">
1470
1470
  <div class="context-row"><span class="context-label">Working directory</span><span class="context-value">${escapeHtml(workingDir)}</span></div>
1471
1471
  <div class="context-row"><span class="context-label">Repo</span><span class="context-value">${escapeHtml(repoName)}</span></div>
1472
- <div class="context-row"><span class="context-label">.feinai</span><span class="context-value">${escapeHtml(tascaLoc)}</span></div>
1472
+ <div class="context-row"><span class="context-label">.feinai</span><span class="context-value">${escapeHtml(feinaiLoc)}</span></div>
1473
1473
  </div>
1474
1474
  <span class="elapsed-time" data-elapsed="${escapeHtml(task.taken_at ?? '')}"></span>
1475
1475
  </div>
package/src/db.ts CHANGED
@@ -1,47 +1,10 @@
1
- import { existsSync, mkdirSync, renameSync } from "node:fs";
1
+ import { existsSync, mkdirSync } from "node:fs";
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { openSqlite, type DbAdapter } from "./sqlite-adapter";
4
4
 
5
5
  const DB_DIR = ".feinai";
6
6
  const DB_FILE = "feinai.db";
7
7
 
8
- // v0.5.x migration: rename .tasca/tasca.db → .feinai/feinai.db
9
- // TODO: remove in v0.7
10
- function migrateLegacyDir(dir: string): void {
11
- const legacyDir = join(dir, ".tasca");
12
- const legacyDb = join(legacyDir, "tasca.db");
13
- const newDir = join(dir, ".feinai");
14
- const newDb = join(newDir, "feinai.db");
15
- if (!existsSync(legacyDb) || existsSync(newDb)) return;
16
-
17
- // Prompt user — only works in TTY contexts
18
- if (process.stdout.isTTY) {
19
- process.stdout.write(
20
- `\n⚠ Found legacy .tasca/tasca.db at ${legacyDir}\n` +
21
- ` Rename to .feinai/feinai.db? [Y/n] `
22
- );
23
- const buf = Buffer.alloc(4);
24
- let answer = "y";
25
- try {
26
- const n = require("node:fs").readSync(0, buf, 0, 4, null);
27
- answer = buf.slice(0, n).toString().trim().toLowerCase() || "y";
28
- } catch {}
29
- if (answer !== "y" && answer !== "") {
30
- process.stdout.write("Skipped. Run 'feinai init' to create a new DB.\n\n");
31
- return;
32
- }
33
- } else {
34
- // Non-interactive (agent/CI): migrate silently
35
- }
36
-
37
- if (!existsSync(newDir)) mkdirSync(newDir, { recursive: true });
38
- renameSync(legacyDb, newDb);
39
- try { require("node:fs").rmdirSync(legacyDir); } catch {}
40
- if (process.stdout.isTTY) {
41
- process.stdout.write(`✓ Migrated to .feinai/feinai.db\n\n`);
42
- }
43
- }
44
-
45
8
  export type DbInstance = DbAdapter;
46
9
 
47
10
  /**
@@ -189,8 +152,6 @@ function applySchema(db: DbInstance): void {
189
152
  export function findDbPath(startDir: string = process.cwd()): string | null {
190
153
  let current = resolve(startDir);
191
154
  while (true) {
192
- // migrate legacy .tasca/tasca.db → .feinai/feinai.db if found
193
- migrateLegacyDir(current);
194
155
  const candidate = join(current, DB_DIR, DB_FILE);
195
156
  if (existsSync(candidate)) return candidate;
196
157
  const parent = dirname(current);
@@ -204,11 +165,11 @@ export function findDbPath(startDir: string = process.cwd()): string | null {
204
165
  * Returns the absolute path of the created DB file.
205
166
  */
206
167
  export function initDb(dir: string = process.cwd()): string {
207
- const tascaDir = join(dir, DB_DIR);
208
- const dbPath = join(tascaDir, DB_FILE);
168
+ const feinaiDir = join(dir, DB_DIR);
169
+ const dbPath = join(feinaiDir, DB_FILE);
209
170
 
210
- if (!existsSync(tascaDir)) {
211
- mkdirSync(tascaDir, { recursive: true });
171
+ if (!existsSync(feinaiDir)) {
172
+ mkdirSync(feinaiDir, { recursive: true });
212
173
  }
213
174
 
214
175
  const db = openSqlite(dbPath, { create: true });
package/src/format.ts CHANGED
@@ -96,7 +96,7 @@ export function formatSpec(
96
96
  if (opts.includeContent) {
97
97
  for (const line of spec.content.split("\n")) lines.push(` ${line}`);
98
98
  } else {
99
- lines.push(` ${c(format, "dim", "(use --full to view; tasca spec content " + spec.id + " to export)")}`);
99
+ lines.push(` ${c(format, "dim", "(use --full to view; feinai spec content " + spec.id + " to export)")}`);
100
100
  }
101
101
  }
102
102
  if (opts.plan) {
@@ -104,7 +104,7 @@ export function formatSpec(
104
104
  if (opts.includeContent) {
105
105
  for (const line of opts.plan.content.split("\n")) lines.push(` ${line}`);
106
106
  } else {
107
- lines.push(` ${c(format, "dim", "(use --full to view; tasca plan show " + spec.id + " to export)")}`);
107
+ lines.push(` ${c(format, "dim", "(use --full to view; feinai plan show " + spec.id + " to export)")}`);
108
108
  }
109
109
  }
110
110
  return lines.join("\n");
@@ -154,7 +154,7 @@ export function formatStatus(
154
154
  if (format === "json") return JSON.stringify(stats, null, 2);
155
155
  const serverLine = stats.serverRunning
156
156
  ? c(format, "green", `server: running → http://127.0.0.1:${stats.serverPort}`)
157
- : c(format, "dim", `server: stopped (tasca server -d to start)`);
157
+ : c(format, "dim", `server: stopped (feinai server -d to start)`);
158
158
  return [
159
159
  `${c(format, "yellow", `pending: ${stats.pending}`)}`,
160
160
  `${c(format, "blue", `in_progress: ${stats.in_progress}`)}`,
package/src/server.ts CHANGED
@@ -250,7 +250,7 @@ function serverError(err: unknown): Response {
250
250
 
251
251
  /**
252
252
  * Determine actor for an inbound HTTP mutation. Priority:
253
- * 1. X-Tasca-Actor header (explicit)
253
+ * 1. X-Feinai-Actor header (explicit)
254
254
  * 2. derived from request: "dashboard:<host>" or "api:<user-agent>"
255
255
  */
256
256
  function actorFromRequest(req: Request): string {
@@ -258,7 +258,7 @@ function actorFromRequest(req: Request): string {
258
258
  // iterate manually to be safe.
259
259
  let explicit: string | undefined;
260
260
  for (const [k, v] of req.headers.entries()) {
261
- if (k.toLowerCase() === "x-tasca-actor") {
261
+ if (k.toLowerCase() === "x-feinai-actor") {
262
262
  explicit = v;
263
263
  break;
264
264
  }
@@ -294,9 +294,9 @@ async function resolveDashboardVersion(): Promise<string> {
294
294
  const root = findRepoRoot();
295
295
  if (!root) return "";
296
296
  try {
297
- const countResult = await Bun.$`git log --oneline -- tools/tasca/src/dashboard.html | wc -l`.cwd(root).text();
297
+ const countResult = await Bun.$`git log --oneline -- src/dashboard.html | wc -l`.cwd(root).text();
298
298
  const count = parseInt(countResult.trim(), 10);
299
- const hashResult = await Bun.$`git log -1 --format=%h -- tools/tasca/src/dashboard.html`.cwd(root).text();
299
+ const hashResult = await Bun.$`git log -1 --format=%h -- src/dashboard.html`.cwd(root).text();
300
300
  const hash = hashResult.trim();
301
301
  cachedDashboardVersion = `dashboard-v${count} (${hash})`;
302
302
  } catch {
@@ -325,7 +325,7 @@ export function startServer(opts: ServerOptions): { url: string; stop: () => voi
325
325
  headers: {
326
326
  "Access-Control-Allow-Origin": "*",
327
327
  "Access-Control-Allow-Methods": "GET, POST, DELETE, PATCH, OPTIONS",
328
- "Access-Control-Allow-Headers": "Content-Type, X-Tasca-Actor",
328
+ "Access-Control-Allow-Headers": "Content-Type, X-Feinai-Actor",
329
329
  },
330
330
  });
331
331
  }
@@ -441,18 +441,18 @@ export function startServer(opts: ServerOptions): { url: string; stop: () => voi
441
441
  return json(agents);
442
442
  }
443
443
 
444
- // GET /api/context — repo and tasca DB context info for dashboard
444
+ // GET /api/context — repo and feinai DB context info for dashboard
445
445
  if (path === "/api/context" && method === "GET") {
446
446
  const repoRoot = findRepoRoot();
447
447
  const dbPath = findDbPath();
448
448
  const home = homedir();
449
- const tascaPath = dbPath?.startsWith(home)
449
+ const feinaiPath = dbPath?.startsWith(home)
450
450
  ? `~${dbPath.slice(home.length)}`
451
451
  : (dbPath ?? null);
452
452
  return json({
453
453
  repoRoot: repoRoot ?? null,
454
454
  repoName: repoRoot ? basename(repoRoot) : null,
455
- tascaPath,
455
+ feinaiPath,
456
456
  });
457
457
  }
458
458
 
@@ -114,7 +114,7 @@ export function getSqliteConstructor(): DbConstructor {
114
114
 
115
115
  if (!_constructor) {
116
116
  console.error(`
117
- Error: No SQLite backend found. tasca requires one of:
117
+ Error: No SQLite backend found. feinai requires one of:
118
118
  • Bun 1.0+ (current runtime)
119
119
  • Node.js 22.5+ (built-in node:sqlite)
120
120
  • better-sqlite3 (npm install -g better-sqlite3)