syntaur 0.7.1 → 0.8.0
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/.claude-plugin/plugin.json +23 -0
- package/README.md +64 -24
- package/dist/index.js +632 -254
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
- package/platforms/claude-code/.claude-plugin/plugin.json +15 -2
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/complete-assignment/SKILL.md +0 -2
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/grab-assignment/SKILL.md +2 -7
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/plan-assignment/SKILL.md +1 -3
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/syntaur-protocol/SKILL.md +4 -23
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/syntaur-protocol/references/file-ownership.md +1 -2
- package/{vendor/syntaur-skills → platforms/claude-code}/skills/syntaur-protocol/references/protocol-summary.md +1 -6
- package/platforms/claude-code/skills/track-server/SKILL.md +49 -0
- package/platforms/codex/.codex-plugin/plugin.json +2 -2
- package/platforms/codex/skills/clear-assignment/SKILL.md +111 -0
- package/platforms/codex/skills/complete-assignment/SKILL.md +146 -0
- package/platforms/codex/skills/create-assignment/SKILL.md +73 -0
- package/platforms/codex/skills/create-project/SKILL.md +56 -0
- package/platforms/codex/skills/grab-assignment/SKILL.md +158 -0
- package/platforms/codex/skills/manage-statuses/SKILL.md +72 -0
- package/platforms/codex/skills/plan-assignment/SKILL.md +137 -0
- package/platforms/codex/skills/save-session-summary/SKILL.md +113 -0
- package/platforms/codex/skills/syntaur-protocol/SKILL.md +119 -0
- package/platforms/codex/skills/syntaur-protocol/references/file-ownership.md +67 -0
- package/platforms/codex/skills/syntaur-protocol/references/protocol-summary.md +82 -0
- package/platforms/codex/skills/track-server/SKILL.md +49 -0
- package/platforms/codex/skills/track-session/SKILL.md +63 -26
- package/skills/clear-assignment/SKILL.md +111 -0
- package/skills/complete-assignment/SKILL.md +146 -0
- package/skills/create-assignment/SKILL.md +73 -0
- package/skills/create-project/SKILL.md +56 -0
- package/skills/grab-assignment/SKILL.md +158 -0
- package/skills/manage-statuses/SKILL.md +72 -0
- package/skills/plan-assignment/SKILL.md +137 -0
- package/skills/save-session-summary/SKILL.md +113 -0
- package/skills/syntaur-protocol/SKILL.md +119 -0
- package/skills/syntaur-protocol/references/file-ownership.md +67 -0
- package/skills/syntaur-protocol/references/protocol-summary.md +82 -0
- package/skills/track-server/SKILL.md +49 -0
- package/skills/track-session/SKILL.md +86 -0
- package/scripts/postinstall-submodules.mjs +0 -40
- package/vendor/syntaur-skills/LICENSE +0 -21
- package/vendor/syntaur-skills/README.md +0 -57
- /package/{vendor/syntaur-skills → platforms/claude-code}/skills/clear-assignment/SKILL.md +0 -0
- /package/{vendor/syntaur-skills → platforms/claude-code}/skills/create-assignment/SKILL.md +0 -0
- /package/{vendor/syntaur-skills → platforms/claude-code}/skills/create-project/SKILL.md +0 -0
- /package/{vendor/syntaur-skills → platforms/claude-code}/skills/manage-statuses/SKILL.md +0 -0
- /package/{vendor/syntaur-skills → platforms/claude-code}/skills/save-session-summary/SKILL.md +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# File Ownership Rules (protocol v2.0)
|
|
2
|
+
|
|
3
|
+
## Human-Authored (READ-ONLY for agents)
|
|
4
|
+
|
|
5
|
+
Agents must NEVER modify these files:
|
|
6
|
+
|
|
7
|
+
| File | Location |
|
|
8
|
+
|------|----------|
|
|
9
|
+
| `project.md` | `<project>/project.md` |
|
|
10
|
+
| `CLAUDE.md` / `AGENTS.md` | Repo root (live outside `~/.syntaur/`) |
|
|
11
|
+
| `<slug>.md` | `~/.syntaur/playbooks/<slug>.md` |
|
|
12
|
+
|
|
13
|
+
Per-project `agent.md` / `claude.md` were removed in protocol v2.0. Agent-level conventions live at the repo root in `CLAUDE.md` / `AGENTS.md`, and user-defined behavioral rules live in `~/.syntaur/playbooks/`.
|
|
14
|
+
|
|
15
|
+
## Agent-Writable (YOUR assignment folder ONLY)
|
|
16
|
+
|
|
17
|
+
You may only write to files inside your currently-claimed assignment folder:
|
|
18
|
+
|
|
19
|
+
| File | Purpose |
|
|
20
|
+
|------|---------|
|
|
21
|
+
| `assignment.md` | Assignment record; source of truth for state. Includes `## Todos` checklist. |
|
|
22
|
+
| `plan*.md` | Versioned implementation plans (`plan.md`, `plan-v2.md`, ...). When superseded, the old plan's todo is marked superseded but the file itself is never deleted. |
|
|
23
|
+
| `progress.md` | Append-only, timestamped progress log (newest first). |
|
|
24
|
+
| `scratchpad.md` | Working notes. |
|
|
25
|
+
| `handoff.md` | Append-only handoff log. |
|
|
26
|
+
| `decision-record.md` | Append-only decision log (Status / Context / Decision / Consequences). |
|
|
27
|
+
|
|
28
|
+
Path patterns:
|
|
29
|
+
- Project-nested: `~/.syntaur/projects/<project>/assignments/<your-assignment-slug>/`
|
|
30
|
+
- Standalone: `~/.syntaur/assignments/<your-assignment-uuid>/` (folder name is the UUID; `slug` is display-only)
|
|
31
|
+
|
|
32
|
+
## CLI-Mediated (any agent via the `syntaur` CLI)
|
|
33
|
+
|
|
34
|
+
These files are never edited directly — write to them only through the CLI so derived indexes and dashboards stay consistent.
|
|
35
|
+
|
|
36
|
+
| Target | Command |
|
|
37
|
+
|--------|---------|
|
|
38
|
+
| `comments.md` (any assignment) | `syntaur comment <slug-or-uuid> "body" --type question\|note\|feedback [--reply-to <id>]` |
|
|
39
|
+
| Another assignment's `## Todos` | `syntaur request <target> "text" [--from <source>]` |
|
|
40
|
+
|
|
41
|
+
## Shared-Writable (any agent or human)
|
|
42
|
+
|
|
43
|
+
| Location | Purpose |
|
|
44
|
+
|----------|---------|
|
|
45
|
+
| `<project>/resources/<slug>.md` | Reference material |
|
|
46
|
+
| `<project>/memories/<slug>.md` | Learnings and patterns |
|
|
47
|
+
|
|
48
|
+
## Derived (NEVER edit)
|
|
49
|
+
|
|
50
|
+
All files prefixed with `_` are derived and rebuilt by tooling:
|
|
51
|
+
|
|
52
|
+
- `manifest.md`
|
|
53
|
+
- `_index-assignments.md`
|
|
54
|
+
- `_index-plans.md`
|
|
55
|
+
- `_index-decisions.md`
|
|
56
|
+
- `_status.md`
|
|
57
|
+
- `resources/_index.md`
|
|
58
|
+
- `memories/_index.md`
|
|
59
|
+
- `~/.syntaur/playbooks/manifest.md`
|
|
60
|
+
|
|
61
|
+
## Workspace Files
|
|
62
|
+
|
|
63
|
+
When working on code (not protocol files), you may write to files within the workspace defined in your assignment frontmatter:
|
|
64
|
+
|
|
65
|
+
- `workspace.worktreePath` or `workspace.repository` defines your code root.
|
|
66
|
+
- You may create and edit source files within that workspace.
|
|
67
|
+
- The `.syntaur/context.json` context file in your working directory is also writable (merge, don't overwrite — the platform SessionStart hook may have populated `sessionId` and `transcriptPath`).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Syntaur Protocol Summary
|
|
2
|
+
|
|
3
|
+
Protocol version: **2.0**
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
~/.syntaur/
|
|
9
|
+
config.md
|
|
10
|
+
projects/
|
|
11
|
+
<project-slug>/
|
|
12
|
+
manifest.md # Derived: root navigation (read-only)
|
|
13
|
+
project.md # Human-authored: project overview (read-only)
|
|
14
|
+
_index-assignments.md # Derived (read-only)
|
|
15
|
+
_index-plans.md # Derived (read-only)
|
|
16
|
+
_index-decisions.md # Derived (read-only)
|
|
17
|
+
_status.md # Derived: status rollup (read-only)
|
|
18
|
+
assignments/
|
|
19
|
+
<assignment-slug>/
|
|
20
|
+
assignment.md # Agent-writable: source of truth for state (## Todos checklist)
|
|
21
|
+
plan*.md # Agent-writable: versioned plans (plan.md, plan-v2.md, ...)
|
|
22
|
+
progress.md # Agent-writable, append-only: timestamped progress log
|
|
23
|
+
comments.md # CLI-mediated: threaded questions/notes/feedback (via `syntaur comment`)
|
|
24
|
+
scratchpad.md # Agent-writable: working notes
|
|
25
|
+
handoff.md # Agent-writable, append-only: handoff log
|
|
26
|
+
decision-record.md # Agent-writable, append-only: decision log
|
|
27
|
+
resources/
|
|
28
|
+
_index.md # Derived (read-only)
|
|
29
|
+
<resource-slug>.md # Shared-writable
|
|
30
|
+
memories/
|
|
31
|
+
_index.md # Derived (read-only)
|
|
32
|
+
<memory-slug>.md # Shared-writable
|
|
33
|
+
assignments/
|
|
34
|
+
<assignment-uuid>/ # Standalone assignments: folder = UUID, `project: null`, slug display-only
|
|
35
|
+
assignment.md # Same schema as project-nested
|
|
36
|
+
plan*.md, progress.md, comments.md, scratchpad.md, handoff.md, decision-record.md
|
|
37
|
+
playbooks/
|
|
38
|
+
manifest.md # Derived: playbook listing (read-only)
|
|
39
|
+
<slug>.md # User-authored: behavioral rules for agents
|
|
40
|
+
syntaur.db # SQLite: agent session registry keyed on real session_id
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Assignment Lifecycle
|
|
44
|
+
|
|
45
|
+
| Status | Meaning |
|
|
46
|
+
|--------|---------|
|
|
47
|
+
| `pending` | Not yet started |
|
|
48
|
+
| `in_progress` | Actively being worked on |
|
|
49
|
+
| `blocked` | Manually blocked (requires `blockedReason`) |
|
|
50
|
+
| `review` | Work complete, awaiting review |
|
|
51
|
+
| `completed` | Done |
|
|
52
|
+
| `failed` | Could not be completed |
|
|
53
|
+
|
|
54
|
+
## Valid State Transitions
|
|
55
|
+
|
|
56
|
+
| From | Command | To |
|
|
57
|
+
|------|---------|-----|
|
|
58
|
+
| pending | start | in_progress |
|
|
59
|
+
| pending | block | blocked |
|
|
60
|
+
| in_progress | block | blocked |
|
|
61
|
+
| in_progress | review | review |
|
|
62
|
+
| in_progress | complete | completed |
|
|
63
|
+
| in_progress | fail | failed |
|
|
64
|
+
| blocked | unblock | in_progress |
|
|
65
|
+
| review | start | in_progress |
|
|
66
|
+
| review | complete | completed |
|
|
67
|
+
| review | fail | failed |
|
|
68
|
+
|
|
69
|
+
## Key Rules
|
|
70
|
+
|
|
71
|
+
1. **Assignment frontmatter is the single source of truth** for all assignment state.
|
|
72
|
+
2. **Project-nested assignments** live at `projects/<slug>/assignments/<aslug>/` (folder name = slug). **Standalone assignments** live at `assignments/<uuid>/` (folder name = UUID, `project: null`, slug display-only).
|
|
73
|
+
3. **Derived files** (underscore-prefixed, plus `manifest.md`) are never edited manually.
|
|
74
|
+
4. **Slugs** are lowercase, hyphen-separated.
|
|
75
|
+
5. **Dependencies** are declared via `dependsOn` in assignment frontmatter. Only valid within the same project — standalone assignments cannot declare `dependsOn`.
|
|
76
|
+
6. An assignment cannot transition from `pending` to `in_progress` while any dependency is not `completed`.
|
|
77
|
+
7. **Playbooks** in `~/.syntaur/playbooks/` define behavioral rules agents must follow. Read them before starting work.
|
|
78
|
+
8. **Todos** in `## Todos` of `assignment.md` is an informal markdown checklist. Items may be simple tasks or markdown links to plan files. When a plan is superseded, mark the old todo `- [x] ~~Execute [plan](./plan.md)~~ (superseded by plan-v2)` — never delete. `## Todos` is also the landing spot for cross-assignment `syntaur request` entries.
|
|
79
|
+
9. **Progress** is appended to `progress.md` as timestamped entries (newest first). Do NOT add a `## Progress` section to `assignment.md` — protocol v2.0 moved progress to its own file.
|
|
80
|
+
10. **Comments** are appended to `comments.md` via `syntaur comment <slug> "body" [--type question|note|feedback] [--reply-to <id>]`. Never edit `comments.md` directly. Questions carry a `resolved` flag toggled in the dashboard.
|
|
81
|
+
11. **Cross-assignment work** is requested via `syntaur request <target> "text"` — appends to the target's `## Todos` annotated `(from: <source>)`.
|
|
82
|
+
12. **Agent sessions** in `syntaur.db` must use real agent-runtime session IDs. Synthesized UUIDs are rejected. Plugins for Claude Code / Codex populate `.syntaur/context.json` with the real id via a SessionStart hook; other agents should source it from their runtime and pass `--session-id` explicitly.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: track-server
|
|
3
|
+
description: Use when the user wants to register, refresh, remove, or list tracked tmux dev-server sessions for the Syntaur dashboard. Triggers on "/track-server", "track this server", "register this dev server", or similar — distinct from /track-session which registers Claude Code agent sessions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Track Server
|
|
7
|
+
|
|
8
|
+
Track tmux sessions so their development servers show up in the Syntaur dashboard. Distinct from `/track-session`, which registers Claude Code agent sessions.
|
|
9
|
+
|
|
10
|
+
## Arguments
|
|
11
|
+
|
|
12
|
+
User arguments: `$ARGUMENTS`
|
|
13
|
+
|
|
14
|
+
Supported forms:
|
|
15
|
+
|
|
16
|
+
- `<session-name>`
|
|
17
|
+
- `--refresh [session-name]`
|
|
18
|
+
- `--remove <session-name>`
|
|
19
|
+
- `--list`
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
### Register
|
|
24
|
+
|
|
25
|
+
1. Verify the tmux session exists with `tmux has-session -t <name>`.
|
|
26
|
+
2. If it does not exist, list available sessions with `tmux list-sessions -F '#{session_name}'`.
|
|
27
|
+
3. Create `~/.syntaur/servers/<sanitized-name>.md` with frontmatter:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
---
|
|
31
|
+
session: <original-name>
|
|
32
|
+
registered: <ISO timestamp>
|
|
33
|
+
last_refreshed: <ISO timestamp>
|
|
34
|
+
---
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
4. Tell the user the session is now tracked.
|
|
38
|
+
|
|
39
|
+
### Refresh
|
|
40
|
+
|
|
41
|
+
1. Update `last_refreshed` for the named session, or for every file in `~/.syntaur/servers/` when no name was provided.
|
|
42
|
+
|
|
43
|
+
### Remove
|
|
44
|
+
|
|
45
|
+
1. Delete `~/.syntaur/servers/<sanitized-name>.md`.
|
|
46
|
+
|
|
47
|
+
### List
|
|
48
|
+
|
|
49
|
+
1. List all tracked session markdown files and show the `session` field from each.
|
|
@@ -1,49 +1,86 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: track-session
|
|
3
|
-
description: Use when the user
|
|
3
|
+
description: Use when the user asks to track, register, or log this Claude Code session in the Syntaur dashboard — standalone or linked to a project/assignment. Triggers on "/track-session", "track this session", "register this session in syntaur", or similar.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Track Session
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Register the current Claude Code session as an agent session in the Syntaur dashboard. Works standalone or linked to a project/assignment.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Only real Claude Code session IDs are accepted — no synthesis. The real id is written to `.syntaur/context.json` by the SessionStart hook, with `~/.claude/sessions/<pid>.json` as the fallback source.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Usage
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
User arguments: `$ARGUMENTS`
|
|
15
15
|
|
|
16
|
-
-
|
|
17
|
-
- `--
|
|
18
|
-
- `--
|
|
19
|
-
- `--
|
|
16
|
+
- (no args) — register a standalone session
|
|
17
|
+
- `--description "<text>"` — with a description
|
|
18
|
+
- `--project <slug> --assignment <slug>` — linked to a project
|
|
19
|
+
- `--description "<text>" --project <slug> --assignment <slug>` — both
|
|
20
20
|
|
|
21
21
|
## Workflow
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### Step 1: Parse arguments
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Extract optional flags from the argument string:
|
|
26
|
+
- `--description "<text>"` or `--description <text>` — session description
|
|
27
|
+
- `--project <slug>` — project to link to
|
|
28
|
+
- `--assignment <slug>` — assignment to link to
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
### Step 2: Source the real session id + transcript path
|
|
31
|
+
|
|
32
|
+
In priority order:
|
|
33
|
+
|
|
34
|
+
1. Read `.syntaur/context.json` if present. If it contains `sessionId`, use it. Also pick up `transcriptPath` if present.
|
|
35
|
+
2. Otherwise, read the most-recently-modified file under `~/.claude/sessions/*.json` whose `cwd` matches `$(pwd)` and use its `sessionId` field. The transcript path is conventionally `~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl`; include it if the file exists, otherwise omit.
|
|
36
|
+
3. If neither source yields an id, abort with: "Could not resolve a real Claude Code session id. Restart the Claude session so the SessionStart hook can populate `.syntaur/context.json`, or run `/rename <slug>` then try again."
|
|
37
|
+
|
|
38
|
+
DO NOT generate a UUID. `syntaur track-session` rejects missing session IDs.
|
|
39
|
+
|
|
40
|
+
### Step 3: Run the CLI command
|
|
41
|
+
|
|
42
|
+
Run the track-session CLI via Bash (use `dangerouslyDisableSandbox: true` since it writes to `~/.syntaur/`):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
syntaur track-session \
|
|
46
|
+
--agent claude \
|
|
47
|
+
--session-id "$SESSION_ID" \
|
|
48
|
+
--transcript-path "$TRANSCRIPT_PATH" \
|
|
49
|
+
--path "$(pwd)" \
|
|
50
|
+
[--description "<text>"] \
|
|
51
|
+
[--project <slug>] \
|
|
52
|
+
[--assignment <slug>]
|
|
35
53
|
```
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
Omit `--transcript-path` entirely (don't pass an empty string) if no transcript path could be resolved.
|
|
56
|
+
|
|
57
|
+
The CLI prints one of:
|
|
58
|
+
- `Registered standalone agent session <sessionId>.`
|
|
59
|
+
- `Registered agent session <sessionId> for <assignment> in <project>.`
|
|
38
60
|
|
|
39
|
-
|
|
61
|
+
Registration is idempotent — re-running the command with the same session id safely upserts project/assignment/description onto the existing row.
|
|
40
62
|
|
|
41
|
-
|
|
63
|
+
### Step 4: Merge context.json
|
|
42
64
|
|
|
43
|
-
|
|
65
|
+
Ensure `.syntaur/context.json` has the session fields (so SessionEnd and future `track-session` runs find them). Merge, don't overwrite:
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
```bash
|
|
68
|
+
mkdir -p .syntaur
|
|
69
|
+
if [ -f .syntaur/context.json ]; then
|
|
70
|
+
jq --arg sid "$SESSION_ID" --arg tp "$TRANSCRIPT_PATH" \
|
|
71
|
+
'. + {sessionId: $sid} + (if ($tp | length) > 0 then {transcriptPath: $tp} else {} end)' \
|
|
72
|
+
.syntaur/context.json > .syntaur/context.json.tmp \
|
|
73
|
+
&& mv .syntaur/context.json.tmp .syntaur/context.json
|
|
74
|
+
else
|
|
75
|
+
jq -n --arg sid "$SESSION_ID" --arg tp "$TRANSCRIPT_PATH" \
|
|
76
|
+
'{sessionId: $sid} + (if ($tp | length) > 0 then {transcriptPath: $tp} else {} end)' \
|
|
77
|
+
> .syntaur/context.json
|
|
78
|
+
fi
|
|
79
|
+
```
|
|
46
80
|
|
|
47
|
-
###
|
|
81
|
+
### Step 5: Confirm
|
|
48
82
|
|
|
49
|
-
|
|
83
|
+
Tell the user:
|
|
84
|
+
- The session was registered (include the short session id).
|
|
85
|
+
- It will be auto-stopped when this conversation ends via the SessionEnd hook.
|
|
86
|
+
- If linked to a project, mention which project/assignment.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clear-assignment
|
|
3
|
+
description: >-
|
|
4
|
+
Clear the active Syntaur assignment from the current session without
|
|
5
|
+
transitioning lifecycle state. Use when the user wants to drop, release,
|
|
6
|
+
unclaim, abandon, or clear assignment context — e.g., "clear my assignment",
|
|
7
|
+
"drop this assignment", "release context", "unclaim this", "I'm not actually
|
|
8
|
+
working on this anymore". Does not mark the assignment complete or failed.
|
|
9
|
+
license: MIT
|
|
10
|
+
metadata:
|
|
11
|
+
author: prong-horn
|
|
12
|
+
version: "1.0.0"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Clear Assignment
|
|
16
|
+
|
|
17
|
+
Drop the active assignment binding from the current workspace. The assignment itself is left untouched in `~/.syntaur/projects/.../assignments/` — only the local `.syntaur/context.json` pointer is cleared so the session is no longer scoped to it.
|
|
18
|
+
|
|
19
|
+
This is the inverse of `grab-assignment`. Unlike `complete-assignment`, it does **not** transition lifecycle state, write a handoff, or close out the work. Use it when:
|
|
20
|
+
|
|
21
|
+
- The user grabbed the wrong assignment.
|
|
22
|
+
- The user wants to switch focus without finishing or formally reviewing the current one.
|
|
23
|
+
- Session context was set up earlier and is now stale.
|
|
24
|
+
|
|
25
|
+
If the assignment is actually done, use `complete-assignment` instead so a handoff is recorded and the lifecycle state advances.
|
|
26
|
+
|
|
27
|
+
## Input
|
|
28
|
+
|
|
29
|
+
Optional flags from the user:
|
|
30
|
+
|
|
31
|
+
- `--keep-session` — preserve `sessionId` / `transcriptPath` fields in `context.json` (just strip the assignment fields). Default: full delete.
|
|
32
|
+
- `--unassign` — also run `syntaur unassign <slug> --project <project>` so the assignment is no longer claimed by this agent. Default: leave the claim in place (only the local context is cleared). Skip this flag if the CLI does not support `unassign` in the installed version — fall back to leaving the claim alone and tell the user.
|
|
33
|
+
|
|
34
|
+
## Step 1: Load Context
|
|
35
|
+
|
|
36
|
+
Read `.syntaur/context.json` from the current working directory.
|
|
37
|
+
|
|
38
|
+
- If the file does not exist, tell the user: "No active assignment context to clear." and stop.
|
|
39
|
+
- If the file exists but contains only session fields (`sessionId`, `transcriptPath`) and no `projectSlug` / `assignmentSlug`, tell the user: "No active assignment is bound — only a platform session record exists. Nothing to clear." and stop (unless they explicitly ask to wipe the session record too).
|
|
40
|
+
|
|
41
|
+
Otherwise extract: `projectSlug`, `assignmentSlug`, `assignmentDir`, `title`.
|
|
42
|
+
|
|
43
|
+
## Step 2: Confirm with the User
|
|
44
|
+
|
|
45
|
+
Show the user what is about to be cleared and confirm before touching anything:
|
|
46
|
+
|
|
47
|
+
> About to clear active assignment context:
|
|
48
|
+
> - Assignment: `<assignmentSlug>` — <title>
|
|
49
|
+
> - Project: `<projectSlug>` (or "standalone" if null)
|
|
50
|
+
> - The assignment itself will NOT be transitioned. Its lifecycle status stays as-is.
|
|
51
|
+
> - Proceed?
|
|
52
|
+
|
|
53
|
+
Stop if the user says no.
|
|
54
|
+
|
|
55
|
+
If lifecycle status is `in_progress` and the user has not passed `--complete-instead`, also note:
|
|
56
|
+
|
|
57
|
+
> Note: this assignment is currently `in_progress`. Clearing context does not change that. If you actually finished it, run `complete-assignment` instead so a handoff is recorded.
|
|
58
|
+
|
|
59
|
+
## Step 3 (optional): Unassign
|
|
60
|
+
|
|
61
|
+
If the user passed `--unassign`, run:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
syntaur unassign <assignment-slug> --project <project-slug>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For standalone assignments use the UUID (the folder name) in place of the slug, and omit `--project`.
|
|
68
|
+
|
|
69
|
+
If the CLI rejects the command (older versions may not implement `unassign`), report the error and continue — the local context clear in Step 4 still happens.
|
|
70
|
+
|
|
71
|
+
## Step 4: Clear the Context File
|
|
72
|
+
|
|
73
|
+
Default behavior — delete the file entirely:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
rm .syntaur/context.json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If the user passed `--keep-session`, preserve session fields and strip everything else instead:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
jq '{sessionId, transcriptPath} | with_entries(select(.value != null))' \
|
|
83
|
+
.syntaur/context.json > .syntaur/context.json.tmp \
|
|
84
|
+
&& mv .syntaur/context.json.tmp .syntaur/context.json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If the resulting file would be empty (`{}`), delete it instead of leaving an empty stub.
|
|
88
|
+
|
|
89
|
+
Do not delete the `.syntaur/` directory itself — other tooling may use it.
|
|
90
|
+
|
|
91
|
+
## Step 5: Close Session (optional)
|
|
92
|
+
|
|
93
|
+
If the original `context.json` included a `sessionId` and the Syntaur dashboard is running, mark the session as cleared so the dashboard does not keep showing it as active:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
curl -s -X PATCH "http://localhost:$(cat ~/.syntaur/dashboard-port 2>/dev/null || echo 4800)/api/agent-sessions/<session-id>/status" \
|
|
97
|
+
-H "Content-Type: application/json" \
|
|
98
|
+
-d '{"status":"cleared","projectSlug":"<project-slug>"}'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If this fails (e.g., dashboard not running, endpoint not present in the installed version), it is non-critical — silently continue.
|
|
102
|
+
|
|
103
|
+
Skip this step entirely when `--keep-session` is set.
|
|
104
|
+
|
|
105
|
+
## Step 6: Report to User
|
|
106
|
+
|
|
107
|
+
Summarize:
|
|
108
|
+
- Which assignment was cleared (slug + title).
|
|
109
|
+
- That its lifecycle status is unchanged (and what that status currently is, if known from frontmatter).
|
|
110
|
+
- Whether the assignment was unassigned via the CLI or the claim was left in place.
|
|
111
|
+
- Suggested next step: `grab-assignment` to claim a different one, or `complete-assignment` if the previous one was actually finished.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: complete-assignment
|
|
3
|
+
description: >-
|
|
4
|
+
Write a handoff and transition the current Syntaur assignment to review or completed.
|
|
5
|
+
Use when the user wants to finish an assignment, write a handoff, or submit work for review.
|
|
6
|
+
license: MIT
|
|
7
|
+
metadata:
|
|
8
|
+
author: prong-horn
|
|
9
|
+
version: "1.1.0"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Complete Assignment
|
|
13
|
+
|
|
14
|
+
Write a handoff for your current Syntaur assignment and transition it to `review` or `completed`.
|
|
15
|
+
|
|
16
|
+
## Input
|
|
17
|
+
|
|
18
|
+
Optional: the user may pass `--complete` to transition directly to `completed` instead of `review`. However, `--complete` is only allowed if ALL acceptance criteria are met AND every `## Todos` item is either checked or marked superseded. If any criterion or todo is unresolved, always transition to `review` regardless of the flag, and inform the user why.
|
|
19
|
+
|
|
20
|
+
## Step 1: Load Context
|
|
21
|
+
|
|
22
|
+
Read `.syntaur/context.json` from the current working directory.
|
|
23
|
+
|
|
24
|
+
If the file does not exist, tell the user: "No active assignment found. Run `grab-assignment` first."
|
|
25
|
+
|
|
26
|
+
Extract: `projectSlug`, `assignmentSlug`, `assignmentDir`, `projectDir`.
|
|
27
|
+
|
|
28
|
+
## Step 2: Load Playbooks
|
|
29
|
+
|
|
30
|
+
Read all playbook files from `~/.syntaur/playbooks/`:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ls ~/.syntaur/playbooks/*.md 2>/dev/null
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Verify your work complies with their rules. If any playbook has completion-related rules (e.g., "run tests before done"), follow them before proceeding.
|
|
37
|
+
|
|
38
|
+
## Step 3: Verify Acceptance Criteria and Todos
|
|
39
|
+
|
|
40
|
+
Read `<assignmentDir>/assignment.md` and find the `## Acceptance Criteria` and `## Todos` sections.
|
|
41
|
+
|
|
42
|
+
Review each acceptance criterion (checkbox item) AND each todo. Superseded todos marked `- [x] ~~Execute [...](./plan-v<N>.md)~~ (superseded by plan-v<N>)` count as resolved — they do not need to be done again.
|
|
43
|
+
|
|
44
|
+
For each:
|
|
45
|
+
- If you believe it is met / done, note why (what was implemented, where).
|
|
46
|
+
- If it is NOT met / done, flag it clearly.
|
|
47
|
+
|
|
48
|
+
If any acceptance criteria are unmet OR any todo is still `- [ ]` and not superseded, warn the user: "The following are not yet done: [list]. Do you want to proceed with the handoff anyway?" — stop if the user says no.
|
|
49
|
+
|
|
50
|
+
## Step 3.5: Append a Final Progress Entry
|
|
51
|
+
|
|
52
|
+
Before writing the handoff, append a final entry to `<assignmentDir>/progress.md` summarizing what was completed. The entry goes at the **top** of the body (reverse-chronological) under a new `## <ISO 8601 timestamp>` heading:
|
|
53
|
+
|
|
54
|
+
```markdown
|
|
55
|
+
## <ISO 8601 timestamp>
|
|
56
|
+
|
|
57
|
+
<One paragraph summarizing the final state of work: what was implemented, what verifications passed, and any deliberate scope exclusions.>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Bump `entryCount` and set `updated` to the current timestamp in `progress.md`'s frontmatter.
|
|
61
|
+
|
|
62
|
+
Do NOT add a `## Progress` section to `assignment.md` — progress entries live exclusively in `progress.md` as of protocol v2.0.
|
|
63
|
+
|
|
64
|
+
## Step 4: Write Handoff Entry
|
|
65
|
+
|
|
66
|
+
Read `<assignmentDir>/handoff.md` to see its current content and frontmatter.
|
|
67
|
+
|
|
68
|
+
Append a new handoff entry to the markdown body. Read the current `handoffCount` from the frontmatter and use `handoffCount + 1` as the entry number. The entry must follow this format:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
## Handoff <N>: <ISO 8601 timestamp>
|
|
72
|
+
|
|
73
|
+
**From:** <your-agent-name>
|
|
74
|
+
**To:** human
|
|
75
|
+
**Reason:** <Why this handoff is happening, e.g., "Assignment complete, handing off for review.">
|
|
76
|
+
|
|
77
|
+
### Summary
|
|
78
|
+
<One paragraph summarizing what was accomplished and what remains>
|
|
79
|
+
|
|
80
|
+
### Current State
|
|
81
|
+
- <What is working>
|
|
82
|
+
- <What is not working or partially done>
|
|
83
|
+
- <Acceptance criteria status: N of M met>
|
|
84
|
+
|
|
85
|
+
### Next Steps
|
|
86
|
+
- <Recommended next actions for the reviewer or next agent>
|
|
87
|
+
|
|
88
|
+
### Important Context
|
|
89
|
+
- <Anything the next agent/human needs that is not in the assignment or plan>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Also update the handoff.md frontmatter: set `updated` to the current timestamp and increment the `handoffCount` by 1.
|
|
93
|
+
|
|
94
|
+
## Step 5: Update Checkboxes (Criteria + Todos)
|
|
95
|
+
|
|
96
|
+
In `<assignmentDir>/assignment.md`, update checkboxes in both the `## Acceptance Criteria` and `## Todos` sections to reflect the current state. Check off items that were completed (change `- [ ]` to `- [x]`).
|
|
97
|
+
|
|
98
|
+
Ideally, these should have been checked off incrementally during implementation. If they are already checked, verify they are still accurate. If some were missed, check them off now and note which were verified at completion time vs. during development in the handoff.
|
|
99
|
+
|
|
100
|
+
Do NOT uncheck or rewrite superseded todo lines matching `- [x] ~~...~~ (superseded by ...)` — preserve that history intact.
|
|
101
|
+
|
|
102
|
+
## Step 6: Close Session (optional)
|
|
103
|
+
|
|
104
|
+
If `.syntaur/context.json` includes a `sessionId` and the Syntaur dashboard is running, mark the session as completed:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
curl -s -X PATCH "http://localhost:$(cat ~/.syntaur/dashboard-port 2>/dev/null || echo 4800)/api/agent-sessions/<session-id>/status" \
|
|
108
|
+
-H "Content-Type: application/json" \
|
|
109
|
+
-d '{"status":"completed","projectSlug":"<project-slug>"}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If this fails (e.g., dashboard not running), it is non-critical — the session will be reconciled automatically.
|
|
113
|
+
|
|
114
|
+
## Step 7: Transition Assignment State
|
|
115
|
+
|
|
116
|
+
If the user requested `--complete` and all criteria are met:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
syntaur complete <assignment-slug> --project <project-slug>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Otherwise, transition to review:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
syntaur review <assignment-slug> --project <project-slug>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If the command fails, report the error. Common failures:
|
|
129
|
+
- Assignment is not in `in_progress` status
|
|
130
|
+
- Project not found
|
|
131
|
+
|
|
132
|
+
## Step 8: Clean Up Context
|
|
133
|
+
|
|
134
|
+
Delete the context file:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
rm .syntaur/context.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Step 9: Report to User
|
|
141
|
+
|
|
142
|
+
Summarize:
|
|
143
|
+
- Assignment slug and title
|
|
144
|
+
- New status (review or completed)
|
|
145
|
+
- Number of acceptance criteria met vs total
|
|
146
|
+
- If transitioned to `review`, a human reviewer will check the work. If any criteria were unmet, they may send it back to `in_progress`.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-assignment
|
|
3
|
+
description: >-
|
|
4
|
+
Create a new Syntaur assignment within a project (or as a standalone one-off).
|
|
5
|
+
Use when the user wants to add a task, create an assignment, or break down
|
|
6
|
+
work within a Syntaur project.
|
|
7
|
+
license: MIT
|
|
8
|
+
metadata:
|
|
9
|
+
author: prong-horn
|
|
10
|
+
version: "1.2.0"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Create Assignment
|
|
14
|
+
|
|
15
|
+
Create a new assignment — project-nested or standalone.
|
|
16
|
+
|
|
17
|
+
## Input
|
|
18
|
+
|
|
19
|
+
Expects arguments from the user:
|
|
20
|
+
|
|
21
|
+
- First (required): the assignment title (e.g., `"Add login endpoint"`)
|
|
22
|
+
- `--project <slug>` (required unless `--one-off`): the project to add the assignment to
|
|
23
|
+
- `--one-off` (optional): create a **standalone** assignment at `~/.syntaur/assignments/<uuid>/` with `project: null`. The folder is named by UUID; `slug` is display-only. `--depends-on` is not permitted for standalone assignments.
|
|
24
|
+
- `--slug <slug>` (optional): override the auto-generated assignment slug
|
|
25
|
+
- `--priority <level>` (optional): `low`, `medium` (default), `high`, or `critical`
|
|
26
|
+
- `--type <type>` (optional): classification such as `feature`, `bug`, `refactor`, `research`, `chore`. Defaults to `feature`. When `~/.syntaur/config.md` defines `types.definitions`, the CLI validates against that list.
|
|
27
|
+
- `--depends-on <slug[,slug...]>` (optional, project-nested only): comma-separated list of assignment slugs this depends on
|
|
28
|
+
- `--dir <path>` (optional): override the default project directory
|
|
29
|
+
- `--with-todos` (optional): scaffold a `## Todos` section in `assignment.md`. **Omit unless the user explicitly asks for it.** Todos are normally a plan (added by `plan-assignment`) or populated during planning — not something to pre-create at assignment time. Pass this flag only if the user explicitly says something like "include todos", "with a todo list", "scaffold todos", etc.
|
|
30
|
+
|
|
31
|
+
If no title was provided, ask the user what the assignment should be called.
|
|
32
|
+
|
|
33
|
+
If neither `--project` nor `--one-off` was provided, check `.syntaur/context.json` for an active assignment. If present, default `--project` to that context's `projectSlug` and confirm with the user: "Add this assignment to project `<projectSlug>`?"
|
|
34
|
+
|
|
35
|
+
If no active context and no project flag, ask the user which project to add it to, or whether it should be a one-off.
|
|
36
|
+
|
|
37
|
+
## Step 1: Run the CLI
|
|
38
|
+
|
|
39
|
+
Build the command from the parsed arguments:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
syntaur create-assignment "<title>" --project <slug> [--slug <slug>] [--priority <level>] [--type <type>] [--depends-on <slugs>] [--dir <path>] [--with-todos]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or for a one-off (standalone at `~/.syntaur/assignments/<uuid>/`):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
syntaur create-assignment "<title>" --one-off [--slug <slug>] [--priority <level>] [--type <type>] [--dir <path>] [--with-todos]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If the command fails (e.g., project not found, slug collision, invalid type), report the error and suggest fixes.
|
|
52
|
+
|
|
53
|
+
## Step 2: Read the Created Assignment
|
|
54
|
+
|
|
55
|
+
After successful creation, extract the assignment slug (and for standalone, the UUID) and directory from the CLI output. Read the generated `assignment.md`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Project-nested:
|
|
59
|
+
cat ~/.syntaur/projects/<project-slug>/assignments/<assignment-slug>/assignment.md
|
|
60
|
+
|
|
61
|
+
# Standalone:
|
|
62
|
+
cat ~/.syntaur/assignments/<uuid>/assignment.md
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Step 3: Guide Next Steps
|
|
66
|
+
|
|
67
|
+
Tell the user:
|
|
68
|
+
- The assignment was created with its slug, priority, type, and location. For standalone assignments, note that the folder is named by UUID (not slug) — `slug` is display-only.
|
|
69
|
+
- Files created: `assignment.md`, `progress.md`, `comments.md`, `scratchpad.md`, `handoff.md`, `decision-record.md`. **`plan.md` is NOT scaffolded** — plan files are optional and created on demand by the `plan-assignment` skill.
|
|
70
|
+
- Remind the user: `progress.md` is where timestamped progress entries go (NOT `assignment.md`), and `comments.md` is CLI-mediated — write only via `syntaur comment <slug-or-uuid> "body" --type question|note|feedback [--reply-to <id>]`.
|
|
71
|
+
- Suggest editing `assignment.md` to fill in the objective, acceptance criteria, and context. A `## Todos` section is **not** scaffolded by default — it is added automatically by `plan-assignment` (linking the new plan file) or by `syntaur request` (cross-assignment requests). Only the `--with-todos` flag pre-scaffolds an empty `## Todos` section.
|
|
72
|
+
- If dependencies were set, note them. Standalone assignments cannot declare `dependsOn`.
|
|
73
|
+
- Suggest `grab-assignment <project-slug> <assignment-slug>` (or `grab-assignment --id <uuid>` for standalone) to claim and start working on it.
|