@ulysses-ai/create-workspace 0.14.0-beta.3 → 0.15.0-beta.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/lib/init.mjs +12 -25
- package/lib/scaffold.mjs +3 -2
- package/package.json +1 -1
- package/template/.claude/agents/reviewer.md +1 -1
- package/template/.claude/hooks/pre-compact.mjs +1 -1
- package/template/.claude/hooks/repo-write-detection.mjs +2 -2
- package/template/.claude/hooks/session-start.mjs +10 -7
- package/template/.claude/hooks/subagent-start.mjs +3 -3
- package/template/.claude/recipes/migrate-from-notion.md +6 -6
- package/template/.claude/rules/coherent-revisions.md +2 -2
- package/template/.claude/rules/local-dev-environment.md.skip +2 -2
- package/template/.claude/rules/memory-guidance.md +23 -14
- package/template/.claude/rules/token-economics.md.skip +2 -2
- package/template/.claude/rules/work-item-tracking.md +1 -1
- package/template/.claude/rules/workspace-structure.md +36 -15
- package/template/.claude/scripts/build-workspace-context.mjs +712 -0
- package/template/.claude/scripts/capture-context.mjs +217 -0
- package/template/.claude/scripts/generate-claude-local.mjs +104 -0
- package/template/.claude/scripts/migrate-canonical-priority.mjs +108 -0
- package/template/.claude/scripts/migrate-open-work.mjs +1 -1
- package/template/.claude/scripts/migrate-to-workspace-context.mjs +520 -0
- package/template/.claude/scripts/sweep-references.mjs +177 -0
- package/template/.claude/skills/aside/SKILL.md +49 -44
- package/template/.claude/skills/braindump/SKILL.md +25 -19
- package/template/.claude/skills/build-docs-site/SKILL.md +1 -1
- package/template/.claude/skills/build-docs-site/checklists/framing.md +1 -1
- package/template/.claude/skills/complete-work/SKILL.md +91 -3
- package/template/.claude/skills/handoff/SKILL.md +31 -30
- package/template/.claude/skills/maintenance/SKILL.md +90 -22
- package/template/.claude/skills/pause-work/SKILL.md +1 -1
- package/template/.claude/skills/promote/SKILL.md +18 -8
- package/template/.claude/skills/release/SKILL.md +20 -13
- package/template/.claude/skills/start-work/SKILL.md +1 -1
- package/template/.claude/skills/workspace-init/SKILL.md +12 -12
- package/template/.claude/skills/workspace-update/SKILL.md +7 -1
- package/template/CLAUDE.md.tmpl +4 -3
- package/template/_gitignore +1 -0
- package/template/workspace.json.tmpl +3 -2
- package/template/.claude/hooks/_bash-output-advisory.test.mjs +0 -88
- package/template/.claude/hooks/_utils.test.mjs +0 -99
- package/template/.claude/lib/freshness.test.mjs +0 -175
- package/template/.claude/lib/registry-check.test.mjs +0 -130
- package/template/.claude/lib/session-frontmatter.test.mjs +0 -242
- package/template/.claude/scripts/build-shared-context-index.mjs +0 -212
- package/template/.claude/scripts/build-shared-context-index.test.mjs +0 -318
- package/template/.claude/scripts/migrate-claude-md-freshness-include.test.mjs +0 -54
- package/template/.claude/scripts/migrate-session-layout.test.mjs +0 -144
- package/template/.claude/scripts/sync-tasks.test.mjs +0 -350
- package/template/.claude/scripts/trackers/github-issues.test.mjs +0 -190
- package/template/.claude/scripts/trackers/interface.test.mjs +0 -40
|
@@ -12,31 +12,34 @@ Capture a drive-by idea without interrupting the current conversation. By defaul
|
|
|
12
12
|
- `/aside <thought>` — researched mode (default). Background subagent explores the idea.
|
|
13
13
|
- `/aside --quick <thought>` — note only. No subagent, no research. Just park the thought.
|
|
14
14
|
|
|
15
|
-
Everything after `/aside` (or `/aside --quick`) is the user's thought. No name parameter — the
|
|
15
|
+
Everything after `/aside` (or `/aside --quick`) is the user's thought. No name parameter — the slug is generated from the content.
|
|
16
16
|
|
|
17
17
|
## Quick Mode (`--quick`)
|
|
18
18
|
|
|
19
19
|
No subagent. Execute these steps directly:
|
|
20
20
|
|
|
21
|
-
1. Parse the user's thought from the arguments (everything after `--quick`)
|
|
22
|
-
2. Generate a kebab-case slug from the content (3-5 words that capture the core idea)
|
|
23
|
-
3.
|
|
24
|
-
4.
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
1. Parse the user's thought from the arguments (everything after `--quick`).
|
|
22
|
+
2. Generate a kebab-case slug from the content (3-5 words that capture the core idea).
|
|
23
|
+
3. Compose the body using the Quick Mode template below (verbatim user thought + a Further Investigation section with 2-3 inferred threads).
|
|
24
|
+
4. Use the centralized helper to compute the path, apply the `braindump_` prefix, write the frontmatter (with `variant: aside`), and stay gitignored:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
echo "$BODY" | node .claude/scripts/capture-context.mjs \
|
|
28
|
+
--type braindump \
|
|
29
|
+
--topic {kebab-slug} \
|
|
30
|
+
--scope team-member \
|
|
31
|
+
--user {workspace.user} \
|
|
32
|
+
--variant aside \
|
|
33
|
+
--local-only
|
|
34
|
+
```
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
5. Report the printed path to the user: "Noted: `{path}`."
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
lifecycle: active
|
|
34
|
-
type: braindump
|
|
35
|
-
variant: aside
|
|
36
|
-
author: {user}
|
|
37
|
-
updated: {YYYY-MM-DD}
|
|
38
|
-
---
|
|
38
|
+
The helper handles collisions automatically by appending `-2`, `-3`, etc.
|
|
39
|
+
|
|
40
|
+
### Quick Mode Body Template
|
|
39
41
|
|
|
42
|
+
```markdown
|
|
40
43
|
## User's Original Thought
|
|
41
44
|
{Verbatim text from the user — copy exactly as provided}
|
|
42
45
|
|
|
@@ -47,37 +50,38 @@ related areas to check. Quick inference, not deep research.}
|
|
|
47
50
|
|
|
48
51
|
## Research Mode (default)
|
|
49
52
|
|
|
50
|
-
Dispatch the `aside-researcher` agent in the background
|
|
51
|
-
|
|
52
|
-
1. Parse the user's thought from the arguments (everything after `/aside`)
|
|
53
|
-
2. Generate a kebab-case slug from the content
|
|
54
|
-
3.
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
Dispatch the `aside-researcher` agent in the background. The full mode uses `--type research` so the file is named `local-only-research_{slug}.md`, distinguishing it from quick asides.
|
|
54
|
+
|
|
55
|
+
1. Parse the user's thought from the arguments (everything after `/aside`).
|
|
56
|
+
2. Generate a kebab-case slug from the content.
|
|
57
|
+
3. Compute the target path with `--print-only` so you can hand it to the subagent:
|
|
58
|
+
```bash
|
|
59
|
+
node .claude/scripts/capture-context.mjs \
|
|
60
|
+
--type research \
|
|
61
|
+
--topic {kebab-slug} \
|
|
62
|
+
--scope team-member \
|
|
63
|
+
--user {workspace.user} \
|
|
64
|
+
--variant aside \
|
|
65
|
+
--local-only \
|
|
66
|
+
--print-only
|
|
67
|
+
```
|
|
68
|
+
4. Dispatch the `aside-researcher` agent using the Agent tool:
|
|
57
69
|
- `subagent_type`: use the `aside-researcher` agent definition
|
|
58
70
|
- `run_in_background: true`
|
|
59
71
|
- Prompt must include:
|
|
60
72
|
- The user's verbatim thought
|
|
61
|
-
- The target file path
|
|
73
|
+
- The target file path (from step 3)
|
|
62
74
|
- The workspace root path
|
|
63
|
-
- The Research Mode template (below)
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
- The Research Mode body template (below)
|
|
76
|
+
- Tell the agent to write the body via `capture-context.mjs --update` so the same path is reused, and to pipe the rendered body on stdin.
|
|
77
|
+
5. Confirm dispatch to the user: "Researching in the background. I'll let you know when it's done."
|
|
78
|
+
6. When the agent completes, report: file path and a one-line summary of what was found.
|
|
66
79
|
|
|
67
|
-
### Research Mode Template
|
|
80
|
+
### Research Mode Body Template
|
|
68
81
|
|
|
69
82
|
Include this template in the agent's prompt so it writes the correct format:
|
|
70
83
|
|
|
71
|
-
```
|
|
72
|
-
---
|
|
73
|
-
state: ephemeral
|
|
74
|
-
lifecycle: active
|
|
75
|
-
type: braindump
|
|
76
|
-
variant: aside
|
|
77
|
-
author: {user}
|
|
78
|
-
updated: {YYYY-MM-DD}
|
|
79
|
-
---
|
|
80
|
-
|
|
84
|
+
```markdown
|
|
81
85
|
## User's Original Thought
|
|
82
86
|
{Verbatim text from the user — copy exactly as provided, never paraphrase}
|
|
83
87
|
|
|
@@ -98,15 +102,16 @@ Topics that would benefit from deeper exploration or user input.}
|
|
|
98
102
|
|
|
99
103
|
## File Naming
|
|
100
104
|
|
|
101
|
-
- **
|
|
102
|
-
- **
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
105
|
+
- **Quick mode:** `workspace-context/team-member/{user}/local-only-braindump_{slug}.md`
|
|
106
|
+
- **Research mode:** `workspace-context/team-member/{user}/local-only-research_{slug}.md`
|
|
107
|
+
- **Slug:** Kebab-case, 3-5 words. E.g., `refresh-token-caching`, `deploy-pipeline-idea`.
|
|
108
|
+
- **Collision handling:** Helper auto-appends `-2`, `-3`, …
|
|
109
|
+
- **Always `local-only-`** — gitignored, never auto-committed.
|
|
105
110
|
|
|
106
111
|
## Session Behavior
|
|
107
112
|
|
|
108
113
|
Asides are session-agnostic. Regardless of whether a work session is active:
|
|
109
|
-
- Files always go to `
|
|
114
|
+
- Files always go to `workspace-context/team-member/{user}/`
|
|
110
115
|
- No interaction with the session tracker
|
|
111
116
|
- No interaction with `/complete-work` synthesis
|
|
112
117
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: braindump
|
|
3
|
-
description: Capture discussion-heavy topics into
|
|
3
|
+
description: Capture discussion-heavy topics into workspace-context. Use when reasoning, exploration, or design rationale should be preserved. Accepts optional name parameter.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Braindump
|
|
7
7
|
|
|
8
|
-
Capture discussion reasoning, exploration results, and design rationale into
|
|
8
|
+
Capture discussion reasoning, exploration results, and design rationale into workspace-context. More freeform than /handoff — designed for "why we chose X" content. Per-user (`team-member/{user}/`) is the default scope.
|
|
9
9
|
|
|
10
10
|
## Parameters
|
|
11
11
|
- `/braindump {name}` — create or update a named braindump
|
|
@@ -27,25 +27,29 @@ When called within an active work session (the active-session pointer at `.claud
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
When called from the workspace root (no active session):
|
|
30
|
-
-
|
|
30
|
+
- Use `--local-only` so the captured file is gitignored (the root only allows local-only writes)
|
|
31
31
|
- Suggest starting a work session if the braindump is about actionable work
|
|
32
32
|
|
|
33
33
|
The flows below apply when NOT in an active work session, or when the user explicitly asks for a standalone braindump file.
|
|
34
34
|
|
|
35
35
|
## Flow: Named
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Use the centralized `capture-context.mjs` helper — it computes the path, applies the `braindump_` prefix, and writes the frontmatter so this skill doesn't have to:
|
|
38
38
|
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
---
|
|
39
|
+
```bash
|
|
40
|
+
echo "$BODY" | node .claude/scripts/capture-context.mjs \
|
|
41
|
+
--type braindump \
|
|
42
|
+
--topic {kebab-case-name} \
|
|
43
|
+
--scope team-member \
|
|
44
|
+
--user {workspace.user} \
|
|
45
|
+
--description "{one-line summary}"
|
|
46
|
+
```
|
|
48
47
|
|
|
48
|
+
Add `--scope shared` (and drop `--user`) to put the file in `workspace-context/shared/` for team visibility. Add `--local-only` to keep it gitignored. Add `--update` to overwrite an existing file with the same name; without it, the helper appends `-2`, `-3`, etc. on collision.
|
|
49
|
+
|
|
50
|
+
The body content sent on stdin should follow this template:
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
49
53
|
## Context
|
|
50
54
|
{What prompted this discussion}
|
|
51
55
|
|
|
@@ -59,6 +63,8 @@ updated: {YYYY-MM-DD}
|
|
|
59
63
|
{What this decision means for future work}
|
|
60
64
|
```
|
|
61
65
|
|
|
66
|
+
The helper writes the frontmatter (`state: ephemeral`, `lifecycle: active`, `type: braindump`, `topic`, `author`, `updated`) and prints the absolute path on stdout so the skill can `git add` and commit it.
|
|
67
|
+
|
|
62
68
|
## Flow: Side Braindump (deprecated)
|
|
63
69
|
|
|
64
70
|
`/braindump side` has been replaced by the `/aside` skill. If invoked:
|
|
@@ -74,7 +80,7 @@ updated: {YYYY-MM-DD}
|
|
|
74
80
|
|
|
75
81
|
## Include task snapshot
|
|
76
82
|
|
|
77
|
-
If an active session exists (detected via `.claude/.active-session.json`), include a `## Tasks at capture time` section in the braindump
|
|
83
|
+
If an active session exists (detected via `.claude/.active-session.json`), include a `## Tasks at capture time` section in the braindump body before piping it to `capture-context.mjs`:
|
|
78
84
|
|
|
79
85
|
```markdown
|
|
80
86
|
## Tasks at capture time
|
|
@@ -85,11 +91,11 @@ If an active session exists (detected via `.claude/.active-session.json`), inclu
|
|
|
85
91
|
- [ ] Complete work
|
|
86
92
|
```
|
|
87
93
|
|
|
88
|
-
Use the same GFM checkbox format as `session.md`'s `## Tasks` section (just `content` and `status` per task — no `activeForm` field, no blockquote line)
|
|
94
|
+
Use the same GFM checkbox format as `session.md`'s `## Tasks` section (just `content` and `status` per task — no `activeForm` field, no blockquote line). Do NOT call `sync-tasks.mjs --write` — braindumps are snapshots, not the canonical store.
|
|
89
95
|
|
|
90
96
|
## Updating Existing Braindumps
|
|
91
97
|
|
|
92
|
-
When updating, rewrite as a fresh snapshot (coherent-revisions rule). The updated braindump should read as if written in one pass.
|
|
98
|
+
When updating, rewrite as a fresh snapshot (coherent-revisions rule) and pass `--update` to `capture-context.mjs`. The updated braindump should read as if written in one pass.
|
|
93
99
|
|
|
94
100
|
## Key Differences from /handoff
|
|
95
101
|
- `/handoff` is structured around work state (branch, status, next steps)
|
|
@@ -98,14 +104,14 @@ When updating, rewrite as a fresh snapshot (coherent-revisions rule). The update
|
|
|
98
104
|
- Use `/braindump` when you're capturing a discussion or decision
|
|
99
105
|
|
|
100
106
|
## Auto-commit
|
|
101
|
-
|
|
107
|
+
Use the path that `capture-context.mjs` printed:
|
|
102
108
|
```bash
|
|
103
|
-
git add
|
|
109
|
+
git add {printed-path}
|
|
104
110
|
git commit -m "braindump: {name}"
|
|
105
111
|
```
|
|
106
112
|
|
|
107
113
|
## Notes
|
|
108
|
-
-
|
|
114
|
+
- Per-user (`team-member/{user}/`) is the default scope
|
|
109
115
|
- One topic, one file — don't mix unrelated ideas in one braindump
|
|
110
116
|
- Drive-by ideas now use `/aside` instead of `/braindump side`
|
|
111
117
|
- Auto-committing context files without user request is a workflow artifact — this intentionally bypasses the "do not commit unless asked" convention
|
|
@@ -96,7 +96,7 @@ For the codebase:
|
|
|
96
96
|
- Read actual implementations, not just existing docs about them
|
|
97
97
|
|
|
98
98
|
For shared context:
|
|
99
|
-
- Walk `
|
|
99
|
+
- Walk `workspace-context/` for handoffs, braindumps, locked team knowledge, release notes
|
|
100
100
|
|
|
101
101
|
For work-session history:
|
|
102
102
|
- Walk `work-sessions/*/workspace/session.md` for any currently-active session trackers — their bodies may contain decisions not yet consumed into release notes
|
|
@@ -52,7 +52,7 @@ For each selected option, **ask for specific paths**.
|
|
|
52
52
|
|
|
53
53
|
> What other sources should I pull from?
|
|
54
54
|
>
|
|
55
|
-
> -
|
|
55
|
+
> - Workspace-context files in the workspace
|
|
56
56
|
> - Claude chat history from prior sessions on this project
|
|
57
57
|
> - Notion export (zip)
|
|
58
58
|
> - Confluence / wiki export
|
|
@@ -60,9 +60,9 @@ Formally read ALL sources before synthesizing — do not write release notes fro
|
|
|
60
60
|
- `work-sessions/{session-name}/workspace/plan-*.md` files
|
|
61
61
|
- Read each one fully
|
|
62
62
|
|
|
63
|
-
3. **Handoffs** — any
|
|
63
|
+
3. **Handoffs** — any workspace-context entries referencing this branch:
|
|
64
64
|
```bash
|
|
65
|
-
grep -rl "branch: {branch}"
|
|
65
|
+
grep -rl "branch: {branch}" workspace-context/
|
|
66
66
|
```
|
|
67
67
|
Read each matching file.
|
|
68
68
|
|
|
@@ -249,6 +249,94 @@ cd repos/{repo} && git pull origin {repo-branch}
|
|
|
249
249
|
cd {main-workspace-root} && git pull origin main
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
+
**Step 10a.1: Tag the merge commit (release sessions only, project repos with `package.json`)**
|
|
253
|
+
|
|
254
|
+
The next three sub-substeps run only when the session branch starts with `release/` — the convention for release sessions (e.g., `release/v0.15.0-beta.0`). For feature, bugfix, and chore sessions, skip 10a.1, 10a.2, and 10a.3 entirely; non-release sessions don't trigger publishes. Detection is purely by branch prefix.
|
|
255
|
+
|
|
256
|
+
Derive the version tag from the branch name by stripping the `release/` prefix (so `release/v0.15.0-beta.0` yields `v0.15.0-beta.0`). For each project repo whose `package.json` declares a `version` field, verify that version matches the derived tag. The workspace repo is **never** tagged — only project repos with publishable `package.json` files get tagged, since the tag triggers `.github/workflows/publish.yml` in that project repo. If a project repo's `package.json` version doesn't match the release tag, skip that repo with a warning rather than failing the whole completion flow — the mismatch usually means `/release` was run against a different version than the branch name suggests, and the user needs to investigate before publishing.
|
|
257
|
+
|
|
258
|
+
Before tagging, preflight against origin: if `v{version}` already exists remotely, surface the conflict to the user with three explicit recovery options — **Reuse** (skip to 10a.2 if the existing tag points at the right commit), **Replace** (`git push origin --delete v{version}` then re-run 10a.1), or **Investigate** (`gh release view v{version}` to see what shipped). Do **not** silently force-push the tag; an existing tag means a published artifact, and overwriting it without confirmation can corrupt the npm registry's view of the release history.
|
|
259
|
+
|
|
260
|
+
If the tag is absent on origin, tag the merge commit (HEAD on `{default-branch}` after the prior `git pull origin {default-branch}`) and push the tag. The tag push triggers `.github/workflows/publish.yml`.
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Detect: only run for release sessions.
|
|
264
|
+
if [[ ! "$branch" =~ ^release/ ]]; then
|
|
265
|
+
# Not a release session — skip 10a.1, 10a.2, 10a.3.
|
|
266
|
+
return
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
# Extract the version from the branch name (release/v{X} → v{X}).
|
|
270
|
+
version_tag="${branch#release/}" # e.g. "v0.15.0-beta.0"
|
|
271
|
+
|
|
272
|
+
# For each project repo with a package.json containing a version field:
|
|
273
|
+
for repo in {project-repos-with-package-json}; do
|
|
274
|
+
cd repos/{repo}
|
|
275
|
+
|
|
276
|
+
# Verify package.json version matches the tag.
|
|
277
|
+
pkg_version=$(node -p "require('./package.json').version")
|
|
278
|
+
expected_version="${version_tag#v}"
|
|
279
|
+
if [ "$pkg_version" != "$expected_version" ]; then
|
|
280
|
+
echo "Skipping {repo}: package.json version ($pkg_version) does not match release tag ($expected_version)."
|
|
281
|
+
continue
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
# Preflight: does the tag already exist on origin?
|
|
285
|
+
if git ls-remote --exit-code origin "refs/tags/$version_tag" >/dev/null 2>&1; then
|
|
286
|
+
# Tag exists. Surface to user with three options:
|
|
287
|
+
# 1. Reuse — skip to 10a.2 if the existing tag points at the right commit.
|
|
288
|
+
# 2. Replace — `git push origin --delete $version_tag` then re-run 10a.1.
|
|
289
|
+
# 3. Investigate — `gh release view $version_tag` to see what shipped.
|
|
290
|
+
# Do NOT silently force-push.
|
|
291
|
+
echo "Tag $version_tag already exists on origin. Aborting with recovery options."
|
|
292
|
+
return 1
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# Tag the merge commit (HEAD on default branch after the prior `git pull`).
|
|
296
|
+
git tag "$version_tag"
|
|
297
|
+
git push origin "$version_tag" # Triggers .github/workflows/publish.yml
|
|
298
|
+
done
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Step 10a.2: Watch the publish workflow (release sessions only)**
|
|
302
|
+
|
|
303
|
+
For each project repo tagged in 10a.1, find and follow the `publish.yml` workflow run on GitHub. The workflow takes a moment to register against the new tag — poll `gh run list` up to 5 times with a 3-second backoff before giving up. Once the run is found, attach with `gh run watch` so the maintainer sees progress live alongside the unified summary. Append `|| true` to the watch command so a workflow failure does **not** abort the rest of `/complete-work`: the maintainer still needs to see the unified summary, including the failure URL, to decide whether to rerun, redo the release, or roll the tag back. If no run registers within the retry window, log a warning with the manual investigation command and continue.
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
# Retry up to 5 times with 3-second backoff — the run takes a moment to register.
|
|
307
|
+
for i in 1 2 3 4 5; do
|
|
308
|
+
run_id=$(gh run list \
|
|
309
|
+
--repo {org}/{repo} \
|
|
310
|
+
--workflow publish.yml \
|
|
311
|
+
--branch "$version_tag" \
|
|
312
|
+
--limit 1 \
|
|
313
|
+
--json databaseId \
|
|
314
|
+
--jq '.[0].databaseId')
|
|
315
|
+
if [ -n "$run_id" ]; then break; fi
|
|
316
|
+
sleep 3
|
|
317
|
+
done
|
|
318
|
+
|
|
319
|
+
if [ -z "$run_id" ]; then
|
|
320
|
+
echo "Warning: no publish workflow run found for $version_tag after 15s. Investigate via 'gh run list'."
|
|
321
|
+
else
|
|
322
|
+
gh run watch "$run_id" --exit-status --repo {org}/{repo} || true
|
|
323
|
+
fi
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Step 10a.3: Update the unified summary (release sessions only)**
|
|
327
|
+
|
|
328
|
+
The unified summary block presented earlier in Step 10a already has a section per project repo. For release sessions, append a `PUBLISH` section per tagged project repo to the same summary — this goes inside the existing summary, not in a new location, so the maintainer sees one consolidated report covering merges, tags, and npm publishes:
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
PUBLISH ({repo}):
|
|
332
|
+
Tag: v{version}
|
|
333
|
+
Workflow: {run-url}
|
|
334
|
+
Status: success | failure
|
|
335
|
+
Published: {dist-tag}@{version} on npm
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Pull `Status` from the `gh run watch` exit code (success when the watch returned 0, failure otherwise). Pull `Published: {dist-tag}@{version}` from the workflow's published-package output if available; if the workflow failed before publishing, omit the `Published:` line and rely on `Status: failure` plus the workflow URL to point the maintainer at the failure.
|
|
339
|
+
|
|
252
340
|
#### Step 10b: Local / bare / other remotes — local merge flow
|
|
253
341
|
|
|
254
342
|
No PRs are created — these remotes don't have a PR concept (or we don't have a client wired up for them). Present an adjusted summary:
|
|
@@ -349,7 +437,7 @@ If /complete-work is called but changes were made without a formal work session
|
|
|
349
437
|
Ask: "These changes weren't part of a formal work session. What do you want to do?"
|
|
350
438
|
- **Accept as work** — create a session retroactively, proceed with normal completion
|
|
351
439
|
- **Stash for later** — create a user-scoped handoff describing what was done, stash the changes
|
|
352
|
-
- **Hand off to someone** — create a team-visible handoff at root
|
|
440
|
+
- **Hand off to someone** — create a team-visible handoff at root workspace-context/ for another member to pick up
|
|
353
441
|
- **Revert** — undo the changes (with confirmation)
|
|
354
442
|
|
|
355
443
|
## Notes
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: handoff
|
|
3
|
-
description: Save workstream state as
|
|
3
|
+
description: Save workstream state as workspace-context. Use anytime during work to capture progress, decisions, and next steps. Accepts optional name parameter.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Handoff
|
|
7
7
|
|
|
8
|
-
Save structured workstream state to
|
|
8
|
+
Save structured workstream state to workspace-context. Usable anytime, any number of times. Per-user (`team-member/{user}/`) is the default scope.
|
|
9
9
|
|
|
10
10
|
## Parameters
|
|
11
11
|
- `/handoff {name}` — create or update a named handoff
|
|
@@ -28,34 +28,33 @@ When called within an active work session (the active-session pointer at `.claud
|
|
|
28
28
|
|
|
29
29
|
When called from the workspace root (no active session):
|
|
30
30
|
- Only `local-only-*` files are writable from the root
|
|
31
|
-
- Suggest starting a work session first, or
|
|
31
|
+
- Suggest starting a work session first, or use the helper with `--local-only`
|
|
32
32
|
|
|
33
33
|
The flows below apply when NOT in an active work session, or when the user explicitly asks for a standalone handoff file.
|
|
34
34
|
|
|
35
35
|
## Flow: Named
|
|
36
36
|
|
|
37
37
|
1. Read workspace user identity from `.claude/settings.local.json` (`workspace.user`)
|
|
38
|
-
2.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
repo: {current-repo-if-any}
|
|
55
|
-
author: {user}
|
|
56
|
-
updated: {YYYY-MM-DD}
|
|
57
|
-
---
|
|
38
|
+
2. Ask: "Should this be user-scoped (default), team-visible, or local-only?"
|
|
39
|
+
- User-scoped (default): `--scope team-member --user {user}`
|
|
40
|
+
- Team-visible: `--scope shared`
|
|
41
|
+
- Local-only: add `--local-only` to either scope
|
|
42
|
+
3. Use the centralized helper to compute the path, apply the `handoff_` prefix, and write the file with full frontmatter:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
echo "$BODY" | node .claude/scripts/capture-context.mjs \
|
|
46
|
+
--type handoff \
|
|
47
|
+
--topic {kebab-case-name} \
|
|
48
|
+
--scope team-member \
|
|
49
|
+
--user {workspace.user} \
|
|
50
|
+
--description "{one-line summary}"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Pass `--update` to overwrite an existing handoff with the same name (otherwise the helper appends `-2`, `-3`, … to avoid clobbering). The helper prints the absolute path of the written file on stdout — use that path for the commit step.
|
|
58
54
|
|
|
55
|
+
The body content sent on stdin should follow this template:
|
|
56
|
+
|
|
57
|
+
```markdown
|
|
59
58
|
## Status
|
|
60
59
|
{What was accomplished in this session}
|
|
61
60
|
|
|
@@ -69,9 +68,11 @@ updated: {YYYY-MM-DD}
|
|
|
69
68
|
{Unresolved questions, if any}
|
|
70
69
|
```
|
|
71
70
|
|
|
72
|
-
|
|
71
|
+
The helper writes the frontmatter (`state: ephemeral`, `lifecycle: active`, `type: handoff`, `topic`, `author`, `updated`). If you need extra fields like `branch:` or `repo:`, append them to the frontmatter after the helper writes (or include them inline in the body).
|
|
72
|
+
|
|
73
|
+
4. Auto-commit the handoff file alone:
|
|
73
74
|
```bash
|
|
74
|
-
git add
|
|
75
|
+
git add {printed-path}
|
|
75
76
|
git commit -m "handoff: {name}"
|
|
76
77
|
```
|
|
77
78
|
|
|
@@ -86,7 +87,7 @@ updated: {YYYY-MM-DD}
|
|
|
86
87
|
|
|
87
88
|
## Include task snapshot
|
|
88
89
|
|
|
89
|
-
If an active session exists (detected via `.claude/.active-session.json`), include a `## Tasks at capture time` section in the handoff
|
|
90
|
+
If an active session exists (detected via `.claude/.active-session.json`), include a `## Tasks at capture time` section in the handoff body before piping it to `capture-context.mjs`:
|
|
90
91
|
|
|
91
92
|
```markdown
|
|
92
93
|
## Tasks at capture time
|
|
@@ -97,16 +98,16 @@ If an active session exists (detected via `.claude/.active-session.json`), inclu
|
|
|
97
98
|
- [ ] Complete work
|
|
98
99
|
```
|
|
99
100
|
|
|
100
|
-
Use the same GFM checkbox format as `session.md`'s `## Tasks` section (just `content` and `status` per task — no `activeForm` field, no blockquote line)
|
|
101
|
+
Use the same GFM checkbox format as `session.md`'s `## Tasks` section (just `content` and `status` per task — no `activeForm` field, no blockquote line). Do NOT call `sync-tasks.mjs --write` — handoffs are snapshots, not the canonical store.
|
|
101
102
|
|
|
102
103
|
## Updating Existing Handoffs
|
|
103
104
|
|
|
104
|
-
When updating an existing handoff, rewrite it as a fresh snapshot of current understanding (coherent-revisions rule). Don't append below the old content. The updated handoff should read as if written in one pass reflecting the current state.
|
|
105
|
+
When updating an existing handoff, rewrite it as a fresh snapshot of current understanding (coherent-revisions rule) and pass `--update` to `capture-context.mjs`. Don't append below the old content. The updated handoff should read as if written in one pass reflecting the current state.
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
The helper updates the `updated` date in frontmatter automatically.
|
|
107
108
|
|
|
108
109
|
## Notes
|
|
109
|
-
-
|
|
110
|
+
- Per-user is the default — `--scope shared` is for content deliberately made team-visible
|
|
110
111
|
- Handoffs are always committed individually — never bundled with code commits
|
|
111
112
|
- One topic, one file — don't let handoffs become grab-bags
|
|
112
113
|
- Name before writing — the name forces you to identify the single topic
|