@goodtek/vibeops 0.7.22 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/README.md +51 -380
- package/dist/bootstrap/installer.js +42 -20
- package/dist/bootstrap/manifest.js +23 -3
- package/dist/cli.js +69 -154
- package/dist/commands/init.js +279 -114
- package/dist/commands/llm.js +177 -0
- package/dist/commands/status.js +181 -8
- package/dist/commands/task-add.js +89 -162
- package/dist/commands/task-done.js +112 -73
- package/dist/lib/config.js +77 -113
- package/dist/lib/env.js +32 -0
- package/dist/lib/git-config.js +21 -0
- package/dist/lib/git-host.js +12 -0
- package/dist/lib/git-policy.js +67 -0
- package/dist/lib/git-remote.js +108 -0
- package/dist/lib/git.js +44 -1
- package/dist/lib/init-clients.js +55 -0
- package/dist/lib/llm-complete.js +18 -19
- package/dist/lib/llm-connect.js +150 -0
- package/dist/lib/llm-preference.js +102 -0
- package/dist/lib/llm-status.js +19 -0
- package/dist/lib/paths.js +7 -3
- package/dist/lib/plan-llm-openai.js +0 -63
- package/dist/lib/pr-create.js +66 -0
- package/dist/lib/resolve-task.js +34 -0
- package/dist/lib/task-add-llm.js +53 -233
- package/dist/lib/task-context.js +68 -0
- package/dist/lib/task-done-llm.js +155 -0
- package/dist/lib/task-pr-llm.js +50 -0
- package/dist/lib/task-push-pr.js +131 -0
- package/dist/lib/task-scaffold.js +39 -43
- package/dist/lib/task-start.js +100 -0
- package/dist/lib/task-summary.js +12 -239
- package/dist/lib/task.js +30 -24
- package/dist/types/config.js +0 -16
- package/package.json +14 -14
- package/templates/.cursor/rules/02-git-safety.mdc +12 -0
- package/templates/AGENTS.md +27 -87
- package/templates/clients/claude/CLAUDE.md +28 -0
- package/templates/clients/cursor/.cursor/rules/01-task-source-of-truth.mdc +12 -0
- package/templates/clients/cursor/.cursor/rules/02-git-safety.mdc +11 -0
- package/templates/clients/cursor/.cursor/rules/03-docs-on-done.mdc +13 -0
- package/templates/core/AGENTS.md +44 -0
- package/templates/core/docs/logs/README.md +7 -0
- package/templates/core/docs/project/03-architecture.md +15 -0
- package/templates/core/docs/project/05-current-state.md +15 -0
- package/templates/core/docs/project/06-decisions.md +9 -0
- package/templates/core/docs/tasks/TASK-000-template.md +37 -0
- package/templates/skills-shared/implement-task/SKILL.md +22 -0
- package/templates/skills-shared/plan-task/SKILL.md +19 -0
- package/dist/agent/loader.js +0 -71
- package/dist/agent/prompt.js +0 -66
- package/dist/commands/agent-list.js +0 -32
- package/dist/commands/agent-prompt.js +0 -59
- package/dist/commands/agent-show.js +0 -26
- package/dist/commands/done.js +0 -160
- package/dist/commands/github-init.js +0 -554
- package/dist/commands/github-status.js +0 -164
- package/dist/commands/next.js +0 -283
- package/dist/commands/notion-init.js +0 -764
- package/dist/commands/notion-sync.js +0 -405
- package/dist/commands/notion-test.js +0 -595
- package/dist/commands/plan.js +0 -146
- package/dist/commands/rollback.js +0 -126
- package/dist/commands/start.js +0 -129
- package/dist/commands/task-check.js +0 -155
- package/dist/commands/task-generate.js +0 -206
- package/dist/commands/task-pull.js +0 -277
- package/dist/commands/task-rollback.js +0 -174
- package/dist/commands/task-start.js +0 -102
- package/dist/commands/task-status.js +0 -122
- package/dist/lib/brief.js +0 -356
- package/dist/lib/cursor-task-prompt.js +0 -60
- package/dist/lib/done-follow-up.js +0 -308
- package/dist/lib/github-cli.js +0 -247
- package/dist/lib/guide-state.js +0 -69
- package/dist/lib/mvp-artifacts.js +0 -204
- package/dist/lib/mvp-constants.js +0 -15
- package/dist/lib/mvp-diff-summary.js +0 -43
- package/dist/lib/mvp-done-summary.js +0 -335
- package/dist/lib/notion-client.js +0 -459
- package/dist/lib/notion-discovery.js +0 -671
- package/dist/lib/notion-env.js +0 -140
- package/dist/lib/notion-mappers.js +0 -148
- package/dist/lib/notion-schema.js +0 -272
- package/dist/lib/notion-sync.js +0 -337
- package/dist/lib/notion-target.js +0 -247
- package/dist/lib/package-json.js +0 -133
- package/dist/lib/plan-apply-planner.js +0 -131
- package/dist/lib/plan-codex-pkce.js +0 -234
- package/dist/lib/plan-llm-models.js +0 -237
- package/dist/lib/plan-llm-normalize.js +0 -146
- package/dist/lib/plan-llm-session.js +0 -682
- package/dist/lib/plan-post-apply-setup.js +0 -116
- package/dist/lib/project-docs.js +0 -95
- package/dist/lib/prompt-builder.js +0 -135
- package/dist/lib/resolve-command-task.js +0 -40
- package/dist/lib/task-add-build-prompt.js +0 -39
- package/dist/lib/task-add-cursor.js +0 -81
- package/dist/lib/task-generator.js +0 -183
- package/dist/lib/task-merge.js +0 -220
- package/dist/lib/task-prompt.js +0 -23
- package/dist/lib/task-pull.js +0 -354
- package/dist/lib/task-status-brief.js +0 -132
- package/dist/lib/workflow-guide.js +0 -485
- package/dist/status/collector.js +0 -103
- package/dist/status/format.js +0 -181
- package/dist/types/brief.js +0 -126
- package/templates/.cursor/rules/00-project-governance.mdc +0 -28
- package/templates/.cursor/rules/01-agent-orchestration.mdc +0 -48
- package/templates/.cursor/rules/02-task-workflow.mdc +0 -38
- package/templates/.cursor/rules/03-git-safety.mdc +0 -30
- package/templates/.cursor/rules/04-docs-update.mdc +0 -22
- package/templates/.vibeops/agents/architect.md +0 -47
- package/templates/.vibeops/agents/builder.md +0 -38
- package/templates/.vibeops/agents/docs.md +0 -54
- package/templates/.vibeops/agents/orchestrator.md +0 -40
- package/templates/.vibeops/agents/planner.md +0 -60
- package/templates/.vibeops/agents/recovery.md +0 -49
- package/templates/.vibeops/agents/reviewer.md +0 -47
- package/templates/.vibeops/agents/tester.md +0 -43
- package/templates/.vibeops/prompts/create-plan.md +0 -33
- package/templates/.vibeops/prompts/generate-tasks.md +0 -41
- package/templates/.vibeops/prompts/implement-task.md +0 -39
- package/templates/.vibeops/prompts/review-task.md +0 -34
- package/templates/.vibeops/prompts/rollback.md +0 -32
- package/templates/.vibeops/prompts/start-project.md +0 -39
- package/templates/.vibeops/workflows/notion-sync.md +0 -53
- package/templates/.vibeops/workflows/project-start.md +0 -73
- package/templates/.vibeops/workflows/rollback.md +0 -45
- package/templates/.vibeops/workflows/task-lifecycle.md +0 -71
- package/templates/docs/logs/README.md +0 -38
- package/templates/docs/project/00-overview.md +0 -27
- package/templates/docs/project/01-requirements.md +0 -30
- package/templates/docs/project/02-mvp-scope.md +0 -36
- package/templates/docs/project/03-architecture.md +0 -34
- package/templates/docs/project/04-tech-stack.md +0 -29
- package/templates/docs/project/05-current-state.md +0 -35
- package/templates/docs/project/06-decisions.md +0 -20
- package/templates/docs/project/07-backlog.md +0 -23
- package/templates/docs/project/08-env.md +0 -29
- package/templates/docs/project/09-deployment.md +0 -28
- package/templates/docs/tasks/TASK-000-template.md +0 -72
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,57 @@ All notable changes to VibeOps are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Removed dead `task-merge.ts` (local merge no longer used).
|
|
10
|
+
- `task add` checks out integration branch from `origin/<branch>` when only remote exists.
|
|
11
|
+
- `task done` sets Status **Done** only after push/MR succeed; skips duplicate PR when URL exists.
|
|
12
|
+
- Re-init creates missing integration branch on existing repos.
|
|
13
|
+
- `status` shows branch policy and MR/PR URL.
|
|
14
|
+
|
|
15
|
+
## 1.1.0 - 2026-05-27
|
|
16
|
+
|
|
17
|
+
### Breaking
|
|
18
|
+
|
|
19
|
+
- **`task done` no longer merges locally.** It pushes the task branch and opens a **pull/merge request** to the integration branch (`gh` / `glab`). Merge and deploy happen on the host (CI).
|
|
20
|
+
- **`init` requires a git remote** (`origin`) unless `--allow-no-remote` (smoke/CI).
|
|
21
|
+
- **`.vibeops.json` gains a `git` block** (integration/production branches, host). Re-run `vibeops init` on older projects.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Branch policy at init:** GitFlow lite (`develop` + `main`) or trunk (`main` only); `--git-policy`, `--integration-branch`, `--production-branch`.
|
|
26
|
+
- **`task add`** branches from the configured **integration** branch, not arbitrary HEAD.
|
|
27
|
+
- **LLM-generated MR/PR** title and body on `task done`; URL stored in TASK **Git Context**.
|
|
28
|
+
- **`--no-pr`** on `task done` to push only.
|
|
29
|
+
|
|
30
|
+
## 1.0.0 - 2026-05-27
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **`vibeops init --clients`**: choose **cursor**, **claude**, **codex** (≥1 required). Installs core + per-client rules/skills (`CLAUDE.md`, `.agents/skills/`, etc.).
|
|
35
|
+
- **Re-init guard**: existing projects prompt before overwriting templates; `docs/tasks/TASK-*.md` are preserved. Use `--yes` for non-interactive re-init.
|
|
36
|
+
- **`vibeops llm`**: `connect`, `status`, `use` for task add/done LLM providers.
|
|
37
|
+
|
|
38
|
+
### Breaking
|
|
39
|
+
|
|
40
|
+
- **Four commands only:** `init`, `task add`, `task done`, `status`.
|
|
41
|
+
- **Removed:** `plan`, `start`, `next`, `rollback`, `notion`, `github`, `task generate`, `task check`, `task prompt`, `task pull`, `agent`, and separate `task status`.
|
|
42
|
+
- **Removed Notion:** no `@notionhq/client`, no Notion config in `.vibeops.json`.
|
|
43
|
+
- **Single TASK model:** `TASK-NNN-<slug>.md` only (no `TASK-mvp` workflow).
|
|
44
|
+
- **`task add`:** if a TASK is In Progress, **guide only** and exit 1 — no auto `task done`.
|
|
45
|
+
- **Templates:** no `.vibeops/agents`, workflows, or prompts; slim `docs/project/` set.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- **`task add`** creates TASK file, task branch, and In Progress status in one step (replaces `start`).
|
|
50
|
+
- **`task done`** LLM assist for Result/Test Result and patches to `05-current-state`, `06-decisions`, `03-architecture`, daily log.
|
|
51
|
+
- **Unified `status`** briefing without Notion/GitHub sections.
|
|
52
|
+
- v3 Cursor rules (3) and optional skills (`plan-task`, `implement-task`).
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- Governance stash **pop** after branch switch so new TASK files stay on disk.
|
|
57
|
+
|
|
7
58
|
## 0.7.22 - 2026-05-16
|
|
8
59
|
|
|
9
60
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,425 +1,96 @@
|
|
|
1
1
|
# VibeOps
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Minimal CLI rails for TASK-driven vibe coding (Cursor, Claude Code, Codex).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@goodtek/vibeops)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
VibeOps
|
|
8
|
+
VibeOps bootstraps an **agent-friendly repo**, starts numbered **TASK** files on Git branches, and closes them while updating **project memory** in Git. You plan and implement in your chosen agent; the CLI handles files, Git, and short LLM assists.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Commands
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
| Command | Purpose |
|
|
13
|
+
|---------|---------|
|
|
14
|
+
| `vibeops init` | Core docs + agent packs (cursor / claude / codex) |
|
|
15
|
+
| `vibeops task add` | New `TASK-NNN` file + task branch |
|
|
16
|
+
| `vibeops task done` | LLM summary, push branch, open MR/PR (no local merge) |
|
|
17
|
+
| `vibeops status` | Briefing: TASK, Git, LLM, clients |
|
|
18
|
+
| `vibeops llm` | Connect LLM providers (`connect` · `status` · `use`) |
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
It gives a project:
|
|
17
|
-
|
|
18
|
-
- `docs/project/*` for product and architecture context.
|
|
19
|
-
- `docs/tasks/TASK-*.md` as the AI execution source of truth.
|
|
20
|
-
- `.cursor/rules/*` and `AGENTS.md` so Cursor knows how to behave.
|
|
21
|
-
- `.vibeops/agents`, `.vibeops/prompts`, `.vibeops/workflows` for reusable agent instructions.
|
|
22
|
-
- MVP workflow: `plan` → `start` → build in Cursor → `done` (Git merge included).
|
|
23
|
-
- Notion metadata sync for a human dashboard.
|
|
24
|
-
|
|
25
|
-
## Why It Exists
|
|
26
|
-
|
|
27
|
-
Vibe coding is fast, but chat history is a weak source of truth. Without a durable workflow, agents repeat work, drift outside scope, lose decision history, and leave teammates without a dashboard. VibeOps moves the durable context into Git files and uses CLI commands to keep each TASK bounded.
|
|
28
|
-
|
|
29
|
-
## Core Philosophy
|
|
30
|
-
|
|
31
|
-
- **VibeOps = workflow rail**: it structures the work, validates state, and prints prompts.
|
|
32
|
-
- **Cursor = builder**: Cursor reads the docs/TASKs and writes application code.
|
|
33
|
-
- **Git `docs/tasks` = AI execution source of truth**: TASK markdown beats chat memory.
|
|
34
|
-
- **Notion = human dashboard**: Notion shows metadata and progress, not canonical task bodies.
|
|
35
|
-
|
|
36
|
-
| What | Source of truth |
|
|
37
|
-
| --- | --- |
|
|
38
|
-
| AI execution input | Git `docs/tasks/*.md` |
|
|
39
|
-
| Project design/status | Git `docs/project/*.md` |
|
|
40
|
-
| Change and rollback evidence | Git commits/branches |
|
|
41
|
-
| Human dashboard | Notion Projects/Tasks DB |
|
|
42
|
-
| Not a source of truth | Cursor chat, Slack, memory |
|
|
43
|
-
|
|
44
|
-
## Installation
|
|
45
|
-
|
|
46
|
-
VibeOps requires Node.js 20+.
|
|
20
|
+
## Init
|
|
47
21
|
|
|
48
22
|
```bash
|
|
49
|
-
|
|
50
|
-
vibeops --help
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The published package is `@goodtek/vibeops`. The installed CLI command is `vibeops`.
|
|
54
|
-
|
|
55
|
-
For local development from this repository:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
pnpm install
|
|
59
|
-
pnpm build
|
|
60
|
-
node dist/cli.js --help
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Quick Start
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
# 1. Install VibeOps workflow files into the current project.
|
|
67
|
-
# Interactive mode can also initialize Git and create the first commit.
|
|
23
|
+
# Interactive: pick agents (≥1), then Git
|
|
68
24
|
vibeops init
|
|
69
25
|
|
|
70
|
-
# Non-interactive
|
|
71
|
-
vibeops init --git --initial-commit
|
|
72
|
-
|
|
73
|
-
# 2. LLM planning → brief + TASK-mvp + mvp-build.md (OpenAI, Codex OAuth, or Cursor agent CLI).
|
|
74
|
-
vibeops plan
|
|
26
|
+
# Non-interactive (GitFlow: develop + main, origin required unless CI)
|
|
27
|
+
vibeops init --clients cursor,claude,codex --git --initial-commit --git-policy gitflow
|
|
75
28
|
|
|
76
|
-
#
|
|
77
|
-
vibeops
|
|
78
|
-
|
|
79
|
-
# 4. Drag .vibeops/generated/mvp-build.md into a new Cursor chat and implement.
|
|
80
|
-
|
|
81
|
-
# 5. Finish: verify Result/Test Result, merge to main, delete task branch.
|
|
82
|
-
vibeops done
|
|
83
|
-
|
|
84
|
-
# 6. Optional: interactive nudge
|
|
85
|
-
vibeops next
|
|
86
|
-
|
|
87
|
-
# 7. Optional Notion dashboard sync.
|
|
88
|
-
vibeops notion init
|
|
89
|
-
vibeops notion test
|
|
90
|
-
vibeops notion sync --dry-run
|
|
29
|
+
# Re-init templates on an existing project
|
|
30
|
+
vibeops init --clients cursor --yes
|
|
91
31
|
```
|
|
92
32
|
|
|
93
|
-
|
|
33
|
+
| Pack | Installed |
|
|
34
|
+
|------|-----------|
|
|
35
|
+
| **core** (always) | `AGENTS.md`, `docs/tasks`, `docs/project`, `docs/logs` |
|
|
36
|
+
| **cursor** | `.cursor/rules/`, `.cursor/skills/` |
|
|
37
|
+
| **claude** | `CLAUDE.md`, `.claude/skills/` |
|
|
38
|
+
| **codex** | `.agents/skills/` |
|
|
94
39
|
|
|
95
|
-
|
|
40
|
+
Re-init **overwrites** templates (rules, skills, doc stubs). **`docs/tasks/TASK-*.md` are kept.**
|
|
96
41
|
|
|
97
|
-
|
|
98
|
-
mkdir acme-automator
|
|
99
|
-
cd acme-automator
|
|
100
|
-
|
|
101
|
-
vibeops init --name "Acme Automator" --git --initial-commit
|
|
102
|
-
vibeops plan --idea "Acme Automator: schedule and run browser automation jobs for marketing teams"
|
|
103
|
-
vibeops start
|
|
104
|
-
# Drag .vibeops/generated/mvp-build.md into Cursor and build the MVP.
|
|
105
|
-
vibeops done
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
If a Notion dashboard is enabled:
|
|
42
|
+
## Workflow
|
|
109
43
|
|
|
110
44
|
```bash
|
|
111
|
-
vibeops
|
|
112
|
-
vibeops notion test
|
|
113
|
-
vibeops notion sync --dry-run
|
|
114
|
-
vibeops notion sync
|
|
115
|
-
```
|
|
45
|
+
vibeops init --clients cursor --git --initial-commit
|
|
116
46
|
|
|
117
|
-
|
|
47
|
+
vibeops task add
|
|
48
|
+
# Plan / build using your agent and the current TASK file
|
|
118
49
|
|
|
119
|
-
|
|
120
|
-
vibeops
|
|
121
|
-
├─ init
|
|
122
|
-
├─ plan
|
|
123
|
-
├─ start [mvp]
|
|
124
|
-
├─ done [mvp]
|
|
125
|
-
├─ next
|
|
126
|
-
├─ status
|
|
127
|
-
├─ rollback [mvp]
|
|
128
|
-
├─ notion { init | test | sync }
|
|
129
|
-
└─ github { status | init }
|
|
50
|
+
vibeops task done
|
|
51
|
+
vibeops status
|
|
130
52
|
```
|
|
131
53
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
## Features
|
|
135
|
-
|
|
136
|
-
### Project Bootstrapper
|
|
137
|
-
|
|
138
|
-
`vibeops init` installs a project operating system: `AGENTS.md`, `.cursor/rules`, `docs/project`, `docs/tasks`, `.vibeops/agents`, `.vibeops/prompts`, `.vibeops/workflows`, `.vibeops.json`, and `.vibeops.env.example`. It is idempotent by default and only overwrites when `--force` is used.
|
|
139
|
-
|
|
140
|
-
### Interactive Planner
|
|
141
|
-
|
|
142
|
-
`vibeops plan` (requires `.vibeops.json`) runs an LLM discovery session (OpenAI, Codex OAuth, or Cursor Agent CLI), then writes:
|
|
143
|
-
|
|
144
|
-
- `.vibeops/brief/project-brief.md`
|
|
145
|
-
- `docs/tasks/TASK-mvp-*.md`
|
|
146
|
-
- `.vibeops/generated/mvp-build.md` — **drag this file into Cursor** to implement the MVP
|
|
147
|
-
|
|
148
|
-
Use `--from` to regenerate MVP artifacts from an edited brief. Use `--non-interactive` in CI (placeholders only).
|
|
149
|
-
|
|
150
|
-
### MVP Git Rails
|
|
151
|
-
|
|
152
|
-
- `vibeops start` — task branch + Git Context on **TASK-mvp**
|
|
153
|
-
- `vibeops done` — verify Result/Test Result, mark Done, merge, **Notion sync** (when enabled), post-MVP dirty-tree cleanup, next-task LLM suggestion
|
|
154
|
-
- `vibeops next` — interactive guide (start → build → finish)
|
|
155
|
-
- `vibeops rollback` — advisory by default; `--confirm` / `--confirm-destructive` to execute
|
|
156
|
-
|
|
157
|
-
### Notion Dashboard Sync
|
|
158
|
-
|
|
159
|
-
`notion init/test/sync` pushes project + TASK **metadata** only (not markdown bodies).
|
|
160
|
-
|
|
161
|
-
## Runner Modes
|
|
162
|
-
|
|
163
|
-
- **Prompt mode (default)**: VibeOps prints Cursor-ready prompts. Cursor executes the code changes.
|
|
164
|
-
- VibeOps does not call LLM APIs and does not invoke Cursor CLI directly today; it works as a workflow rail around the human + Cursor loop.
|
|
165
|
-
|
|
166
|
-
## Notion Setup
|
|
167
|
-
|
|
168
|
-
Notion is optional. If enabled:
|
|
169
|
-
|
|
170
|
-
- `NOTION_TOKEN` is the **only** environment variable VibeOps reads. It lives in `.vibeops.env` (gitignored) or in `process.env`.
|
|
171
|
-
- Target IDs live in `.vibeops.json`, not in `.vibeops.env`.
|
|
172
|
-
- `projectsTargetId` / `tasksTargetId` are preferred resolved **data_source** IDs.
|
|
173
|
-
- `projectsDatabaseId` / `tasksDatabaseId` remain legacy/container fallbacks.
|
|
174
|
-
- `notion init` uses data_source-first discovery. If no data sources are found, it can search accessible pages, scan 1-depth inline database blocks, then resolve child databases to data source IDs.
|
|
175
|
-
- Legacy `NOTION_API_KEY` / `NOTION_PROJECT_DB` / `NOTION_TASK_DB` environment variables are no longer used. The `.vibeops.env.example` that `vibeops init` writes contains only `NOTION_TOKEN=`.
|
|
176
|
-
|
|
177
|
-
Required Projects DB properties:
|
|
178
|
-
|
|
179
|
-
| Property | Type |
|
|
180
|
-
| --- | --- |
|
|
181
|
-
| `Name` | `title` |
|
|
182
|
-
| `Project ID` | `rich_text` |
|
|
183
|
-
| `Status` | `status` |
|
|
184
|
-
| `Local Path` | `rich_text` |
|
|
185
|
-
| `Git Repo` | `rich_text` or `url` |
|
|
186
|
-
| `Current Phase` | `select` |
|
|
187
|
-
| `Docs Path` | `rich_text` |
|
|
188
|
-
| `Summary` | `rich_text` |
|
|
189
|
-
|
|
190
|
-
Required Tasks DB properties:
|
|
191
|
-
|
|
192
|
-
| Property | Type |
|
|
193
|
-
| --- | --- |
|
|
194
|
-
| `Name` | `title` |
|
|
195
|
-
| `Task ID` | `rich_text` |
|
|
196
|
-
| `Project ID` | `rich_text` |
|
|
197
|
-
| `Status` | `status` |
|
|
198
|
-
| `Priority` | `select` |
|
|
199
|
-
| `MVP Phase` | `select` |
|
|
200
|
-
| `Git Branch` | `rich_text` |
|
|
201
|
-
| `Docs Path` | `rich_text` |
|
|
202
|
-
| `Summary` | `rich_text` |
|
|
203
|
-
| `Result Summary` | `rich_text` |
|
|
204
|
-
|
|
205
|
-
> `MVP Phase` here is a Notion property name kept for compatibility with existing dashboards. It is a free-form label column and is not an internal release-phase tag.
|
|
206
|
-
|
|
207
|
-
Required Status options:
|
|
208
|
-
|
|
209
|
-
- Projects DB: `Building`, `Planning`, `Paused`, `Done`, `Archived`
|
|
210
|
-
- Tasks DB: `Planned`, `In Progress`, `Review`, `Done`, `Blocked`
|
|
54
|
+
If a TASK is **In Progress**, `task add` exits with a guide — it does not auto-run `task done`.
|
|
211
55
|
|
|
212
|
-
|
|
56
|
+
## LLM (optional)
|
|
213
57
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
GitHub integration runs on top of the GitHub CLI (`gh`). VibeOps never stores `GITHUB_TOKEN` — authentication is owned by `gh auth login`.
|
|
217
|
-
|
|
218
|
-
1. Install `gh`:
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
brew install gh
|
|
222
|
-
# or follow https://cli.github.com/
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
2. Authenticate:
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
gh auth login
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
3. Probe state:
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
vibeops github status
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
4. Connect or create a repo interactively:
|
|
238
|
-
|
|
239
|
-
```bash
|
|
240
|
-
# plan only — no gh / git / file mutation
|
|
241
|
-
vibeops github init --dry-run
|
|
242
|
-
|
|
243
|
-
# plan a new public repo
|
|
244
|
-
vibeops github init --dry-run --owner <user> --repo <name> --public
|
|
245
|
-
|
|
246
|
-
# connect to an existing repo by slug or URL
|
|
247
|
-
vibeops github init --dry-run --connect <owner>/<repo>
|
|
248
|
-
vibeops github init --dry-run --connect https://github.com/<owner>/<repo>.git
|
|
249
|
-
vibeops github init --dry-run --connect git@github.com:<owner>/<repo>.git
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
`vibeops github init` applies four things in sequence:
|
|
253
|
-
|
|
254
|
-
- (optional) `gh repo create <owner>/<repo> --public|--private --source=. --remote=origin` for new repos.
|
|
255
|
-
- `git remote add origin <url>` (or `git remote set-url`) for the `--connect` path. Existing remotes are never silently overwritten — VibeOps asks first and defaults to No.
|
|
256
|
-
- Updates `package.json` `repository.url`, `homepage`, `bugs.url` (skip with `--no-package-update`).
|
|
257
|
-
- Writes the `github` section of `.vibeops.json`: `enabled`, `mode = "gh-cli"`, `owner`, `repo`, `remote`, `visibility`, `url`.
|
|
258
|
-
|
|
259
|
-
VibeOps never runs `git push`. Push your branch manually with `git push -u <remote> <branch>`.
|
|
260
|
-
|
|
261
|
-
## Init Git Bootstrap
|
|
262
|
-
|
|
263
|
-
`vibeops init` can optionally do the first local Git setup while installing the workflow files. In interactive mode it asks:
|
|
264
|
-
|
|
265
|
-
- Initialize Git repository?
|
|
266
|
-
- Use `main` as default branch?
|
|
267
|
-
- Create initial commit?
|
|
268
|
-
- Initial commit message
|
|
269
|
-
|
|
270
|
-
For non-interactive setup:
|
|
58
|
+
For **`task add`** / **`task done`** only (not for coding in the IDE):
|
|
271
59
|
|
|
272
60
|
```bash
|
|
273
|
-
vibeops
|
|
274
|
-
vibeops
|
|
275
|
-
vibeops init --git --default-branch main --commit-message "chore: initialize vibeops project"
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Safety rules:
|
|
279
|
-
|
|
280
|
-
- Existing Git repositories skip `git init`.
|
|
281
|
-
- Existing repositories with commits skip the initial commit path.
|
|
282
|
-
- `--dry-run` runs no Git commands.
|
|
283
|
-
- VibeOps never pushes and never changes remotes during `init`.
|
|
284
|
-
- Before the initial commit, VibeOps prints how many files will be included.
|
|
285
|
-
|
|
286
|
-
Before the first commit, `vibeops status` distinguishes an unborn branch from a detached HEAD:
|
|
287
|
-
|
|
288
|
-
```text
|
|
289
|
-
Git
|
|
290
|
-
branch main (unborn, no commits yet)
|
|
291
|
-
status dirty
|
|
292
|
-
hint create the first commit or run `vibeops init --git --initial-commit`
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## Status Output
|
|
296
|
-
|
|
297
|
-
`vibeops status` summarizes the local project surface only. It never calls the Notion API and never spawns `gh`. The Notion section reads from `.vibeops.env` / `process.env` (for `NOTION_TOKEN` presence) and `.vibeops.json` (for target IDs). The GitHub section reads from `.vibeops.json`. The Package section reads from `package.json`.
|
|
298
|
-
|
|
299
|
-
Example output for a fully-configured project:
|
|
300
|
-
|
|
301
|
-
```text
|
|
302
|
-
Git
|
|
303
|
-
branch main
|
|
304
|
-
status clean
|
|
305
|
-
|
|
306
|
-
Notion
|
|
307
|
-
enabled yes
|
|
308
|
-
token configured (.vibeops.env)
|
|
309
|
-
projects target configured
|
|
310
|
-
tasks target configured
|
|
311
|
-
hint run `vibeops notion test`
|
|
312
|
-
|
|
313
|
-
GitHub
|
|
314
|
-
enabled yes
|
|
315
|
-
mode gh-cli
|
|
316
|
-
owner/repo goodtekxyz/vibeops
|
|
317
|
-
remote origin
|
|
318
|
-
url https://github.com/goodtekxyz/vibeops
|
|
319
|
-
|
|
320
|
-
Package
|
|
321
|
-
name @goodtek/vibeops
|
|
322
|
-
version 0.2.0
|
|
323
|
-
bin vibeops
|
|
61
|
+
vibeops llm connect
|
|
62
|
+
vibeops llm use auto # auto | codex-oauth | cursor-agent | openai
|
|
324
63
|
```
|
|
325
64
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
```text
|
|
329
|
-
Notion
|
|
330
|
-
enabled no
|
|
331
|
-
token missing
|
|
332
|
-
projects target missing
|
|
333
|
-
tasks target missing
|
|
334
|
-
hint run `vibeops notion init`
|
|
335
|
-
|
|
336
|
-
GitHub
|
|
337
|
-
enabled no
|
|
338
|
-
hint run `vibeops github init`
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
If the project has no `package.json`, the Package section degrades gracefully:
|
|
342
|
-
|
|
343
|
-
```text
|
|
344
|
-
Package
|
|
345
|
-
package.json missing
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
`vibeops status --json` exposes the same surface programmatically, including `notion.tokenSource`, `notion.hasProjectsTarget`, `notion.hasTasksTarget`, the entire `github` object, and the entire `package` object. Legacy environment variables (`NOTION_API_KEY`, `NOTION_PROJECT_DB`, `NOTION_TASK_DB`) are no longer surfaced — VibeOps only uses `NOTION_TOKEN`.
|
|
349
|
-
|
|
350
|
-
## Git Rollback Safety
|
|
351
|
-
|
|
352
|
-
- `task start` records base branch, base commit, and task branch in task state.
|
|
353
|
-
- `task check` is read-only and reports working tree + committed changes.
|
|
354
|
-
- `task done` validates TASK Result/Test Result and moves to Review by default.
|
|
355
|
-
- `task rollback` is advisory unless explicit confirmation flags are supplied.
|
|
356
|
-
|
|
357
|
-
## Agent Workflow
|
|
65
|
+
## Installation
|
|
358
66
|
|
|
359
|
-
|
|
67
|
+
Node.js 20+.
|
|
360
68
|
|
|
361
69
|
```bash
|
|
362
|
-
|
|
363
|
-
vibeops agent show builder
|
|
364
|
-
vibeops task prompt TASK-001 --agent builder
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
The default project template includes agents such as `orchestrator`, `planner`, `architect`, `builder`, `reviewer`, `tester`, `docs`, and `recovery`.
|
|
368
|
-
|
|
369
|
-
## Packaging / npm Usage
|
|
370
|
-
|
|
371
|
-
This package exposes the `vibeops` binary:
|
|
372
|
-
|
|
373
|
-
```json
|
|
374
|
-
{
|
|
375
|
-
"bin": {
|
|
376
|
-
"vibeops": "dist/cli.js"
|
|
377
|
-
}
|
|
378
|
-
}
|
|
70
|
+
npm install -g @goodtek/vibeops
|
|
379
71
|
```
|
|
380
72
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
Useful maintainer commands:
|
|
73
|
+
Development:
|
|
384
74
|
|
|
385
75
|
```bash
|
|
386
|
-
pnpm
|
|
387
|
-
pnpm build
|
|
388
|
-
pnpm smoke
|
|
389
|
-
pnpm pack
|
|
390
|
-
pnpm publish --dry-run --access public --no-git-checks
|
|
76
|
+
pnpm install && pnpm build && pnpm smoke
|
|
391
77
|
```
|
|
392
78
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
## Security Notes
|
|
396
|
-
|
|
397
|
-
- `.vibeops.env` is gitignored and must contain secrets such as `NOTION_TOKEN`.
|
|
398
|
-
- VibeOps masks tokens in CLI output.
|
|
399
|
-
- Notion test/debug output is token-safe.
|
|
400
|
-
- `notion sync --dry-run` performs no mutation.
|
|
401
|
-
- `task pull --dry-run` performs no file or Notion mutation.
|
|
402
|
-
- Notion page bodies are never synced.
|
|
403
|
-
- Git destructive rollback paths require explicit confirmation.
|
|
404
|
-
- `github init` uses `gh` CLI auth — VibeOps never stores `GITHUB_TOKEN`.
|
|
405
|
-
- `github init --dry-run` runs zero `gh` / `git remote` / file mutations and produces only a plan.
|
|
406
|
-
|
|
407
|
-
## Support
|
|
79
|
+
## Flags (common)
|
|
408
80
|
|
|
409
|
-
-
|
|
410
|
-
-
|
|
411
|
-
-
|
|
81
|
+
- **`init`**: `--clients`, `--yes`, `--dry-run`, `--force`, `--git`, `--initial-commit`, `--git-policy gitflow|trunk`, `--integration-branch`, `--production-branch`, `--allow-no-remote`, `--cwd`
|
|
82
|
+
- **`task add`**: `--dry-run`, `--non-interactive --idea "…"`
|
|
83
|
+
- **`task done`**: `--dry-run`, `--no-pr` (push only)
|
|
84
|
+
- **`status`**: `--json`
|
|
412
85
|
|
|
413
|
-
##
|
|
86
|
+
## Git
|
|
414
87
|
|
|
415
|
-
-
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
420
|
-
- [`docs/project/05-backlog.md`](docs/project/05-backlog.md) — task order.
|
|
421
|
-
- [`docs/tasks/`](docs/tasks/) — TASK files used by Cursor.
|
|
88
|
+
- **Init** records branch policy in `.vibeops.json` (`integrationBranch`, `productionBranch`, `host`).
|
|
89
|
+
- **`task add`**: branch `task/<slug>` from the **integration** branch (e.g. `develop`).
|
|
90
|
+
- **`task done`**: commit if needed → `git push` → `gh pr create` / `glab mr create` (LLM title/body). **You merge on GitHub/GitLab**; CI deploys.
|
|
91
|
+
- Commit messages: `feat(task-nnn): …`
|
|
92
|
+
- No force-push to shared branches
|
|
422
93
|
|
|
423
94
|
## License
|
|
424
95
|
|
|
425
|
-
MIT
|
|
96
|
+
MIT
|
|
@@ -1,29 +1,19 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
1
2
|
import { join } from "node:path";
|
|
2
|
-
import { ensureDir, pathExists, readText, readTextOrNull, writeText } from "../lib/filesystem.js";
|
|
3
|
+
import { ensureDir, pathExists, readText, readTextOrNull, writeText, } from "../lib/filesystem.js";
|
|
4
|
+
import { CLIENT_SKILL_ROOT } from "../lib/init-clients.js";
|
|
3
5
|
import { dim, green, log, yellow } from "../lib/logger.js";
|
|
4
|
-
import { projectPaths, VIBEOPS_ENV_FILE } from "../lib/paths.js";
|
|
5
|
-
import {
|
|
6
|
+
import { projectPaths, TEMPLATES_ROOT, VIBEOPS_ENV_FILE } from "../lib/paths.js";
|
|
7
|
+
import { loadInstallManifest, resolveDestination } from "./manifest.js";
|
|
6
8
|
import { applySubstitutions, buildSubstitutions, isTextPath, } from "./substitute.js";
|
|
7
9
|
import { configToJson } from "../lib/config.js";
|
|
8
10
|
function envExampleContents() {
|
|
9
|
-
// Modern VibeOps reads exactly one Notion secret: NOTION_TOKEN.
|
|
10
|
-
// Notion Projects / Tasks target IDs live in `.vibeops.json` under
|
|
11
|
-
// `notion.projectsTargetId` / `notion.tasksTargetId` (configured by
|
|
12
|
-
// `vibeops notion init`), so they are NOT environment variables.
|
|
13
|
-
//
|
|
14
|
-
// We intentionally do NOT seed GITHUB_TOKEN / OPENAI_* here:
|
|
15
|
-
// - GitHub integration uses `gh` CLI auth.
|
|
16
|
-
// - VibeOps' default runner is prompt mode and does not call LLM APIs.
|
|
17
11
|
return [
|
|
18
|
-
"# VibeOps · environment
|
|
19
|
-
"# Copy
|
|
20
|
-
"# Never commit .vibeops.env — it is added to .gitignore by `vibeops init`.",
|
|
12
|
+
"# VibeOps · optional environment",
|
|
13
|
+
"# Copy to .vibeops.env (gitignored). Never commit secrets.",
|
|
21
14
|
"#",
|
|
22
|
-
"#
|
|
23
|
-
"#
|
|
24
|
-
"# integration and sharing the target databases with it.",
|
|
25
|
-
"",
|
|
26
|
-
"NOTION_TOKEN=",
|
|
15
|
+
"# LLM for task add / task done (optional — Codex OAuth and Cursor Agent CLI also work):",
|
|
16
|
+
"# OPENAI_API_KEY=",
|
|
27
17
|
"",
|
|
28
18
|
].join("\n");
|
|
29
19
|
}
|
|
@@ -86,19 +76,51 @@ async function ensureGitignoreEntry(projectRoot, dryRun) {
|
|
|
86
76
|
relativePath: ".gitignore",
|
|
87
77
|
};
|
|
88
78
|
}
|
|
79
|
+
async function listSharedSkillNames() {
|
|
80
|
+
const sharedRoot = join(TEMPLATES_ROOT, "skills-shared");
|
|
81
|
+
if (!(await pathExists(sharedRoot)))
|
|
82
|
+
return [];
|
|
83
|
+
const entries = await readdir(sharedRoot, { withFileTypes: true });
|
|
84
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
85
|
+
}
|
|
86
|
+
async function installSharedSkills(options, subs) {
|
|
87
|
+
const outcomes = [];
|
|
88
|
+
const skillNames = await listSharedSkillNames();
|
|
89
|
+
const sharedRoot = join(TEMPLATES_ROOT, "skills-shared");
|
|
90
|
+
for (const client of options.clients) {
|
|
91
|
+
const skillRoot = CLIENT_SKILL_ROOT[client];
|
|
92
|
+
for (const skillName of skillNames) {
|
|
93
|
+
const sourceAbs = join(sharedRoot, skillName, "SKILL.md");
|
|
94
|
+
if (!(await pathExists(sourceAbs)))
|
|
95
|
+
continue;
|
|
96
|
+
const relativePath = join(skillRoot, skillName, "SKILL.md");
|
|
97
|
+
const dest = join(options.projectRoot, relativePath);
|
|
98
|
+
const entry = { relativePath, sourceAbs };
|
|
99
|
+
if (!options.dryRun) {
|
|
100
|
+
await ensureDir(join(dest, ".."));
|
|
101
|
+
}
|
|
102
|
+
outcomes.push(await copyOne(entry, dest, subs, options));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return outcomes;
|
|
106
|
+
}
|
|
89
107
|
export async function install(options) {
|
|
90
108
|
const paths = projectPaths(options.projectRoot);
|
|
91
109
|
const subs = buildSubstitutions(options.config);
|
|
92
110
|
if (!options.dryRun) {
|
|
93
111
|
await ensureDir(paths.root);
|
|
94
112
|
}
|
|
95
|
-
const manifest = await
|
|
113
|
+
const manifest = await loadInstallManifest(options.clients);
|
|
96
114
|
const outcomes = [];
|
|
97
115
|
for (const entry of manifest) {
|
|
98
116
|
const dest = resolveDestination(entry, paths.root);
|
|
117
|
+
if (!options.dryRun) {
|
|
118
|
+
await ensureDir(join(dest, ".."));
|
|
119
|
+
}
|
|
99
120
|
const outcome = await copyOne(entry, dest, subs, options);
|
|
100
121
|
outcomes.push(outcome);
|
|
101
122
|
}
|
|
123
|
+
outcomes.push(...(await installSharedSkills(options, subs)));
|
|
102
124
|
const configOutcome = await writeBlobIfNeeded(paths.config, ".vibeops.json", configToJson(options.config), options);
|
|
103
125
|
outcomes.push(configOutcome);
|
|
104
126
|
const envExampleOutcome = await writeBlobIfNeeded(paths.envExample, ".vibeops.env.example", envExampleContents(), options);
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import { join, relative } from "node:path";
|
|
2
2
|
import { walk } from "../lib/filesystem.js";
|
|
3
|
+
import { pathExists } from "../lib/filesystem.js";
|
|
3
4
|
import { TEMPLATES_ROOT } from "../lib/paths.js";
|
|
5
|
+
async function loadManifestFromDirectory(rootDir) {
|
|
6
|
+
if (!(await pathExists(rootDir)))
|
|
7
|
+
return [];
|
|
8
|
+
const files = await walk(rootDir);
|
|
9
|
+
return files.map((abs) => ({
|
|
10
|
+
relativePath: relative(rootDir, abs),
|
|
11
|
+
sourceAbs: abs,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
/** Core tree + selected client packs (not shared skills — those are copied separately). */
|
|
15
|
+
export async function loadInstallManifest(clients) {
|
|
16
|
+
const entries = [];
|
|
17
|
+
entries.push(...(await loadManifestFromDirectory(join(TEMPLATES_ROOT, "core"))));
|
|
18
|
+
for (const id of clients) {
|
|
19
|
+
entries.push(...(await loadManifestFromDirectory(join(TEMPLATES_ROOT, "clients", id))));
|
|
20
|
+
}
|
|
21
|
+
return entries.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
22
|
+
}
|
|
23
|
+
export function resolveDestination(entry, projectRoot) {
|
|
24
|
+
return join(projectRoot, entry.relativePath);
|
|
25
|
+
}
|
|
26
|
+
/** @deprecated Use loadInstallManifest — walks entire templates/ (legacy). */
|
|
4
27
|
export async function loadManifest() {
|
|
5
28
|
const files = await walk(TEMPLATES_ROOT);
|
|
6
29
|
return files
|
|
@@ -10,6 +33,3 @@ export async function loadManifest() {
|
|
|
10
33
|
}))
|
|
11
34
|
.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
12
35
|
}
|
|
13
|
-
export function resolveDestination(entry, projectRoot) {
|
|
14
|
-
return join(projectRoot, entry.relativePath);
|
|
15
|
-
}
|