@openthink/team 0.0.1 → 0.0.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 +95 -19
- package/dist/assign-ticket.md +2 -2
- package/dist/index.js +574 -130
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,35 +24,60 @@ npm link
|
|
|
24
24
|
|
|
25
25
|
`v0` is **private and not yet published to npm** (`package.json` has `"private": true`). Flip when the source repo goes public.
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Quick start
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
```sh
|
|
30
|
+
oteam init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Creates `~/openteam/` with the workspace tree below, drops a `.oteam-workspace` sentinel, registers it in `~/.open-team/config.json` (promoting it to default if no default is set), seeds per-phase model defaults (see [Per-phase model selection](#per-phase-model-selection) for the table), and writes the oteam guidance block to `~/AGENTS.md` and `~/CLAUDE.md`. Re-running `oteam init` against an already-initialised path is a clean no-op; running against a non-empty unmarked directory exits non-zero rather than silently merging. Existing per-phase model customisation is preserved across re-runs — defaults are only seeded when the `models` block is absent or empty (run `oteam config models show` to see the current state).
|
|
34
|
+
|
|
35
|
+
Flags:
|
|
36
|
+
|
|
37
|
+
- `oteam init --dir <path>` (or `-w, --workspace <path>`) — workspace location, default `~/openteam/`.
|
|
38
|
+
- `oteam init --docs-dir <path>` — where to write `AGENTS.md` / `CLAUDE.md`, default `$HOME`.
|
|
39
|
+
- `oteam init -y` — skip the interactive workspace-path prompt.
|
|
40
|
+
|
|
41
|
+
> **Breaking change vs. earlier `oteam` builds:** `--dir` used to mean "where to write `AGENTS.md`/`CLAUDE.md`". It now means the workspace location. Use the new `--docs-dir` flag for the previous behaviour.
|
|
42
|
+
|
|
43
|
+
## Workspace setup
|
|
44
|
+
|
|
45
|
+
`open-team` reads from a workspace directory ("vault" is Obsidian's word; oteam doesn't depend on Obsidian). Layout:
|
|
30
46
|
|
|
31
47
|
```
|
|
32
|
-
|
|
33
|
-
├──
|
|
48
|
+
openteam/
|
|
49
|
+
├── .oteam-workspace # sentinel — written by `oteam init`
|
|
50
|
+
├── 00-meta/README.md
|
|
34
51
|
├── tickets/
|
|
35
52
|
│ ├── triage/ refined/ in-progress/ qa/ blocked/
|
|
53
|
+
├── projects/
|
|
36
54
|
└── archive/<YYYY-MM>/
|
|
37
55
|
```
|
|
38
56
|
|
|
39
57
|
A ticket's `state:` frontmatter must always match its containing folder under `tickets/`.
|
|
40
58
|
|
|
41
|
-
For the simplest single-
|
|
59
|
+
For the simplest single-workspace setup, run `oteam init` (creates and registers `~/openteam/`). To use an existing tree, register it via `oteam config vault add <path>` or set `PRODUCT_VAULT_PATH`. For multiple workspaces (personal + work, etc.) see [Config & multiple vaults](#config--multiple-vaults).
|
|
42
60
|
|
|
43
61
|
## Subcommands
|
|
44
62
|
|
|
45
63
|
```sh
|
|
46
|
-
oteam pull <source> <ref>
|
|
47
|
-
oteam pull --project <name> ...
|
|
48
|
-
oteam assign <ticket-or-id>
|
|
49
|
-
oteam assign --inline <path>
|
|
50
|
-
oteam assign --no-stamp <id>
|
|
51
|
-
oteam list [--state <state>]
|
|
52
|
-
oteam list --project <name>
|
|
53
|
-
oteam archive <ticket-id>
|
|
54
|
-
oteam config vault add <path>
|
|
55
|
-
oteam config vault list
|
|
64
|
+
oteam pull <source> <ref> # ingest external item → tickets/triage/
|
|
65
|
+
oteam pull --project <name> ... # tag the new ticket with a project
|
|
66
|
+
oteam assign <ticket-or-id> # drive role pipeline (full path or AGT-NNN)
|
|
67
|
+
oteam assign --inline <path> # … or run inline in current terminal
|
|
68
|
+
oteam assign --no-stamp <id> # one-shot override of stamp.enforce (clones from GitHub)
|
|
69
|
+
oteam list [--state <state>] # list active tickets
|
|
70
|
+
oteam list --project <name> # filter by project frontmatter
|
|
71
|
+
oteam archive <ticket-id> # move done ticket to archive/YYYY-MM/
|
|
72
|
+
oteam config vault add <path> # register a vault under a name
|
|
73
|
+
oteam config vault list # show registered vaults + default
|
|
74
|
+
oteam config stamp set --host <url> # configure stamp host post-init
|
|
75
|
+
oteam config stamp set --enforce on # require repos be stamp-registered
|
|
76
|
+
oteam config stamp clear # remove the stamp block
|
|
77
|
+
oteam config stamp show # print current stamp config
|
|
78
|
+
oteam config models set <phase> <id> # pin a model per role-pipeline phase
|
|
79
|
+
oteam config models clear <phase> # remove a per-phase override
|
|
80
|
+
oteam config models show # print current per-phase overrides
|
|
56
81
|
```
|
|
57
82
|
|
|
58
83
|
Most commands accept `--vault <name-or-path>` to operate on a specific vault.
|
|
@@ -104,16 +129,67 @@ claude --dangerously-skip-permissions --model claude-opus-4-7 "/assign-ticket <p
|
|
|
104
129
|
|
|
105
130
|
Requires the `claude` CLI on PATH (https://claude.com/claude-code).
|
|
106
131
|
|
|
107
|
-
### Spawn-time stamp
|
|
132
|
+
### Spawn-time clone modes (stamp integration)
|
|
133
|
+
|
|
134
|
+
For repo-bound tickets (`repo:` frontmatter set), `oteam assign` clones an isolated agent worktree before spawning and points the spawned session's cwd at it. The cloned worktree has exactly one remote — `origin` — and shares no `.git/objects` with any clone you keep elsewhere on disk, so the agent can never push back into your daily checkout by accident.
|
|
135
|
+
|
|
136
|
+
Where the clone comes from is governed by oteam config (`~/.open-team/config.json`, `stamp` block):
|
|
108
137
|
|
|
109
|
-
|
|
138
|
+
| `stamp` config | Mode | Clone source | Behaviour |
|
|
139
|
+
|------------------------------------------------|-----------|--------------------------------------------------------|-------------------------------------------------------------------------------------------------|
|
|
140
|
+
| absent / `null` | no-stamp | `git@github.com:<repo>.git` | Default. No stamp config files are read. `oteam` works against any git repo. |
|
|
141
|
+
| `{ host, enforce: false }` | soft | `git@github.com:<repo>.git` | Stamp host is recorded for tooling that asks for it; `oteam assign` does not gate. |
|
|
142
|
+
| `{ host, enforce: true }` | enforce | `<host>/srv/git/<basename>.git` (the stamp server) | The clone IS the gate: clone failure exits non-zero before any spawn. AGT-050 behaviour. |
|
|
110
143
|
|
|
111
|
-
|
|
144
|
+
`oteam init` walks you through setting `stamp.host` and `stamp.enforce` interactively. Re-running `oteam init` pre-fills the prompts; press enter to keep current values. Pass `oteam init --skip-stamp` to skip the prompts on a re-run when you only want to refresh the workspace tree or docs blocks.
|
|
112
145
|
|
|
113
|
-
|
|
146
|
+
You can edit the stamp config any time after init:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
oteam config stamp show # print current host + enforce
|
|
150
|
+
oteam config stamp set --host <url> # set or update the stamp host
|
|
151
|
+
oteam config stamp set --enforce on # turn the per-repo gate on (host required)
|
|
152
|
+
oteam config stamp set --enforce off # … or back off
|
|
153
|
+
oteam config stamp clear # remove the stamp block entirely
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`oteam assign --no-stamp` is a per-run override: it forces the github clone path even when `stamp.enforce: true` is set. The persistent setting is `oteam config stamp set --enforce off`; `--no-stamp` is convenient when you want to spawn a one-off agent without touching config.
|
|
157
|
+
|
|
158
|
+
> **Migration note.** Earlier `oteam` builds read `~/.stamp/server.yml` directly. This version does not — to keep the AGT-050 stamp gate in place after upgrade, run `oteam init` and paste the host (or `oteam config stamp set --host <url> --enforce on`).
|
|
114
159
|
|
|
115
160
|
Stale workspaces from prior assigns are GC'd at spawn time: any `/tmp/open-team-issues/agt-N/` directory whose ticket id has no matching ticket in the active vault is `rm -rf`'d before the new clone. The current run's workspace is also `rm -rf`'d before its clone, so re-assigns are hermetic.
|
|
116
161
|
|
|
162
|
+
## Per-phase model selection
|
|
163
|
+
|
|
164
|
+
Each role-pipeline phase can run on a different Claude model. The runner reads `models[phase]` from `~/.open-team/config.json` before each spawn and passes it as `claude --model <id>`. Phase resolution from the ticket's `state:`:
|
|
165
|
+
|
|
166
|
+
| ticket state | phase |
|
|
167
|
+
|----------------|------------------|
|
|
168
|
+
| `triage` | `product` |
|
|
169
|
+
| `refined` | `spike` |
|
|
170
|
+
| `in-progress` | `implementation` |
|
|
171
|
+
| `qa` | `qa` |
|
|
172
|
+
|
|
173
|
+
`oteam init` seeds these defaults if no `models` block exists yet:
|
|
174
|
+
|
|
175
|
+
| phase | default model | rationale |
|
|
176
|
+
|------------------|----------------------|-----------------------------------------------------------------|
|
|
177
|
+
| `product` | `claude-sonnet-4-6` | synthesis when the input is rough; cheaper than Opus |
|
|
178
|
+
| `spike` | `claude-opus-4-7` | design judgment, gap-spotting, scope rating |
|
|
179
|
+
| `implementation` | `claude-sonnet-4-6` | multi-file edits + stamp round-trips |
|
|
180
|
+
| `qa` | `claude-sonnet-4-6` | catching AC mismatches against the running system |
|
|
181
|
+
|
|
182
|
+
Inspect the current state with `oteam config models show`. Override with:
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
oteam config models set spike claude-opus-4-7
|
|
186
|
+
oteam config models set implementation claude-sonnet-4-6
|
|
187
|
+
oteam config models show # one phase per line; "(unset)" for unpinned phases
|
|
188
|
+
oteam config models clear spike # falls back to the role-pipeline default
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Each field is independent. Unset phases fall back to the role-pipeline default (currently `claude-opus-4-7`); validation is "non-empty string", and the SDK rejects unknown ids at spawn time. Re-running `oteam init` against a config that already has any per-phase model set leaves the entire `models` block alone — your customisation wins. A spike that auto-proceeds to implementation in the same session keeps the spike-phase model (one model per spawn).
|
|
192
|
+
|
|
117
193
|
## Config & multiple vaults
|
|
118
194
|
|
|
119
195
|
`open-team` supports any number of named vaults via `~/.open-team/config.json`. Register them with:
|
package/dist/assign-ticket.md
CHANGED
|
@@ -13,7 +13,7 @@ You are working a `product-vault` ticket. The user invoked `oteam assign <path>`
|
|
|
13
13
|
3. **No commits, no PRs, no Linear.** Vault tickets do not necessarily map to a code repo. Only act on code if the ticket's `repo:` field is set AND the work demands it.
|
|
14
14
|
4. **STOP at every role-handoff boundary.** When your role is done, write a STOP marker (visual banner per Output discipline below) and let the human decide whether to continue.
|
|
15
15
|
5. **3-attempt cap on any failing operation.** If a step fails (e.g., file mv fails, frontmatter parse fails, build/test fails), you get 3 tries before STOPPing.
|
|
16
|
-
6. **Never read or write inside `$HOME/Development/<repo>`.** That tree may have uncommitted in-flight work; entangling with it is a sterile-field violation. For repo-bound tickets, the `oteam` runner has already prepared an isolated agent worktree at `/tmp/open-team-issues/<ticket-id-lowercased>/repo` and spawned you cd'd into it — that's your only valid working directory. The runner clones from the stamp server
|
|
16
|
+
6. **Never read or write inside `$HOME/Development/<repo>`.** That tree may have uncommitted in-flight work; entangling with it is a sterile-field violation. For repo-bound tickets, the `oteam` runner has already prepared an isolated agent worktree at `/tmp/open-team-issues/<ticket-id-lowercased>/repo` and spawned you cd'd into it — that's your only valid working directory. The runner clones from the stamp server when `stamp.enforce: true` is set in `~/.open-team/config.json`, otherwise from GitHub directly; either way, the worktree is isolated from your primary, so AC-shaped requirements like "primary's `git remote -v` is byte-equal before/after a spawn" are satisfied by construction. If your `$PWD` is not the prepared workspace (e.g. you invoked the slash command by hand outside of `oteam assign`), set up the workspace yourself before reading any repo file — see Phase 3 Step 0.
|
|
17
17
|
|
|
18
18
|
## Phase 0 — Read the ticket
|
|
19
19
|
|
|
@@ -63,7 +63,7 @@ Write the comment in this shape:
|
|
|
63
63
|
|
|
64
64
|
## Phase 3 — Engineering agent (state: refined → spike phase)
|
|
65
65
|
|
|
66
|
-
**Step 0 — Workspace is already prepared.** When `oteam assign` spawned you against a repo-bound ticket, it already cloned `/tmp/open-team-issues/<ticket-id-lowercased>/repo` (from the stamp server
|
|
66
|
+
**Step 0 — Workspace is already prepared.** When `oteam assign` spawned you against a repo-bound ticket, it already cloned `/tmp/open-team-issues/<ticket-id-lowercased>/repo` (from the stamp server when `stamp.enforce: true` is set in `~/.open-team/config.json`; from GitHub otherwise, or when `--no-stamp` was passed) and set your cwd to it. Confirm with `pwd` and `git remote -v`; for stamp-governed repos you should see exactly one remote, `origin`, pointing at `ssh://git@<stamp-host>:<port>/srv/git/<basename>.git`.
|
|
67
67
|
|
|
68
68
|
Cost trade: a fresh stamp clone adds a few seconds vs. the older `git worktree add` fast path. That's an intentional trade for AC-grade isolation — the agent worktree shares no `.git/objects` and no remotes with your primary, and removing or renaming any remote inside the worktree cannot leak back to your daily flow.
|
|
69
69
|
|