@ulysses-ai/create-workspace 0.16.0-beta.1 → 0.18.0-beta.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.
Files changed (53) hide show
  1. package/README.md +5 -5
  2. package/lib/init.mjs +19 -0
  3. package/package.json +1 -1
  4. package/template/.claude/hooks/_utils.mjs +1 -1
  5. package/template/.claude/hooks/repo-write-detection.mjs +161 -64
  6. package/template/.claude/hooks/session-end.mjs +68 -2
  7. package/template/.claude/hooks/session-start.mjs +35 -1
  8. package/template/.claude/hooks/subagent-start.mjs +89 -22
  9. package/template/.claude/lib/session-frontmatter.mjs +28 -0
  10. package/template/.claude/rules/coherent-revisions.md +1 -1
  11. package/template/.claude/rules/config-review.md.skip +29 -0
  12. package/template/.claude/rules/forge-operations.md +51 -0
  13. package/template/.claude/rules/git-conventions.md +16 -11
  14. package/template/.claude/rules/goal-driven-work.md +8 -403
  15. package/template/.claude/rules/honest-pushback.md +37 -37
  16. package/template/.claude/rules/memory-guidance.md +43 -90
  17. package/template/.claude/rules/superpowers-workflow.md.skip +1 -1
  18. package/template/.claude/rules/work-item-tracking.md +30 -72
  19. package/template/.claude/rules/workspace-structure.md +49 -69
  20. package/template/.claude/scripts/build-workspace-context.mjs +61 -16
  21. package/template/.claude/scripts/chat-record.mjs +282 -0
  22. package/template/.claude/scripts/cleanup-work-session.mjs +363 -36
  23. package/template/.claude/scripts/context-footprint.mjs +282 -0
  24. package/template/.claude/scripts/forges/github.mjs +255 -0
  25. package/template/.claude/scripts/forges/gitlab.mjs +20 -0
  26. package/template/.claude/scripts/forges/interface.mjs +125 -0
  27. package/template/.claude/scripts/generate-claude-local.mjs +21 -2
  28. package/template/.claude/scripts/migrate-sessions.mjs +1571 -0
  29. package/template/.claude/scripts/migrate-to-workspace-context.mjs +7 -2
  30. package/template/.claude/scripts/task-worktree.mjs +525 -0
  31. package/template/.claude/scripts/workspace-diagnostics.mjs +654 -0
  32. package/template/.claude/settings.json +5 -13
  33. package/template/.claude/skills/braindump/SKILL.md +11 -4
  34. package/template/.claude/skills/build-docs-site/SKILL.md +5 -5
  35. package/template/.claude/skills/build-docs-site/templates/spec.md.tmpl +1 -1
  36. package/template/.claude/skills/complete-work/SKILL.md +255 -215
  37. package/template/.claude/skills/context-placement/SKILL.md +199 -0
  38. package/template/.claude/skills/goal-driven-work/SKILL.md +459 -0
  39. package/template/.claude/skills/handoff/SKILL.md +11 -4
  40. package/template/.claude/skills/maintenance/SKILL.md +39 -6
  41. package/template/.claude/skills/migrate-sessions/SKILL.md +70 -0
  42. package/template/.claude/skills/pause-work/SKILL.md +33 -8
  43. package/template/.claude/skills/release/SKILL.md +44 -108
  44. package/template/.claude/skills/start-work/SKILL.md +89 -7
  45. package/template/.claude/skills/workspace-init/SKILL.md +34 -0
  46. package/template/.claude/skills/workspace-update/SKILL.md +4 -0
  47. package/template/.claudeignore +3 -0
  48. package/template/CLAUDE.md.tmpl +20 -2
  49. package/template/CODEBASE.md.tmpl +13 -0
  50. package/template/_gitignore +9 -0
  51. package/template/repo-claude.md.tmpl +10 -0
  52. package/template/workspace.json.tmpl +5 -3
  53. package/template/.claude/hooks/worktree-create.mjs +0 -53
@@ -1,6 +1,9 @@
1
1
  ---
2
2
  name: workspace-init
3
3
  description: First-time workspace initialization. Clones repos, installs template components, extracts team knowledge from documentation sources and Claude chat history, activates rules, configures user identity. Run once after scaffolding with --init.
4
+
5
+ # scope example (remove # to activate path-scoped loading):
6
+ # scope: repos/my-api/
4
7
  ---
5
8
 
6
9
  # Workspace Init
@@ -53,6 +56,8 @@ For each repo in `workspace.json`:
53
56
  - If confirmed: `git clone {remote} repos/{name}`
54
57
  - If exists: report "repos/{name} already present"
55
58
 
59
+ While workspace.json is open, confirm the work lifecycle. `workspace.sessionModel` selects where `/start-work` routes new work: `"task"` (one tracker issue + one branch + one worktree per touched repo; recommended for new workspaces) or `"session"` (self-contained `work-sessions/{name}/` folders; the template default — keep it for teams already mid-flight on sessions). Ask: "Which lifecycle should new work use — task (recommended for a new workspace) or session (default)?" and write the answer to `workspace.sessionModel` only if it differs from the current value. Never flip an existing non-default value silently.
60
+
56
61
  ### Step 3: Identify documentation sources
57
62
 
58
63
  Ask the user:
@@ -117,6 +122,9 @@ Also install these top-level files from the payload:
117
122
  - **`.claude/settings.json`** — Merge payload settings into existing file. Preserve user-added settings, add missing entries.
118
123
  - **`.gitignore`** — Merge: add lines from payload not already present.
119
124
  - **`CLAUDE.md`** — Generate from `.workspace-update/CLAUDE.md.tmpl`, substituting `{{project-name}}` with the workspace name. If the existing CLAUDE.md has user-added content beyond the bootstrap template, preserve it.
125
+ - **`CODEBASE.md` (optional)** — Ask: "Generate CODEBASE.md? This produces a lightweight file-tree map that helps Claude navigate the codebase without exhaustive exploration. [Y/n]". If yes: scaffold `CODEBASE.md` from `.workspace-update/CODEBASE.md.tmpl`, substitute `{{project-name}}`, then pre-populate `## Top-level layout` by listing the top-level entries of each `repos/{repo}/` directory using `fs.readdirSync` (Node.js, no network calls). If no: skip — `CODEBASE.md` can always be created manually later by copying and filling the template.
126
+
127
+ **Per-repo CLAUDE.md stubs:** For each repo in `workspace.json`, check if `repos/{repo}/CLAUDE.md` exists. If not, ask "Scaffold a CLAUDE.md for {repo}? [Y/n]". If yes, write a blank stub from `.workspace-update/repo-claude.md.tmpl`, substituting `{{repo-name}}` with the repo name. The stub body is comment text only — no workspace-specific content — and its `## Commands` section is where you will add repo-specific test, lint, and build commands.
120
128
 
121
129
  **Commit:** `git commit -m "feat: install template components from payload"`
122
130
 
@@ -255,6 +263,29 @@ If you discovered candidate work items during earlier steps (bugs in braindumps,
255
263
 
256
264
  Do NOT batch-create issues automatically — the user should review and prune the list.
257
265
 
266
+ ### Step 12.5: Configure MCP servers
267
+
268
+ MCP (Model Context Protocol) servers extend what Claude can do inside the workspace. The template ships with a Playwright MCP server entry in `.mcp.json` for browser automation and visual testing. Additional servers open up two particularly useful capabilities:
269
+
270
+ - **LSP symbol navigation** — a Language Server Protocol server gives Claude go-to-definition, find-all-references, and call-graph queries without false positives from text search. The right server depends on your language stack:
271
+ - TypeScript / JavaScript: `typescript-language-server` (via `npx typescript-language-server --stdio`)
272
+ - Python: `pylsp` (via `pip install python-lsp-server`)
273
+ - Go, Rust, Java, and others: consult your language's LSP documentation.
274
+ - **Internal tool access** — if your team has internal APIs, databases, or services, an MCP server can expose them as tools Claude can call directly. The shape of an `mcpServers` entry in `.mcp.json`:
275
+
276
+ ```json
277
+ {
278
+ "mcpServers": {
279
+ "my-lsp": {
280
+ "command": "npx",
281
+ "args": ["typescript-language-server", "--stdio"]
282
+ }
283
+ }
284
+ }
285
+ ```
286
+
287
+ **This step is guidance only.** The right LSP server depends on your language; the right internal-tool server depends on what your team builds. Configure `.mcp.json` after init when you know what you need — there is no pressure to choose now. The Playwright entry already present in `.mcp.json` satisfies the template's audit assertion; additional servers are additive.
288
+
258
289
  ### Step 13: Configure user identity
259
290
 
260
291
  Ask: "What name should be used for your user-scoped context? [{system-username}]"
@@ -418,3 +449,6 @@ This session is done. Start a fresh Claude Code session and run /start-work to b
418
449
  - Documentation sources are first-class — always ask, always confirm access, always report failures
419
450
  - Chat history scanning uses a manifest to survive auto-compaction
420
451
  - Existing worktrees are formalized with session markers, trackers, and linked chat history
452
+ - **Launch point:** Launch `claude` from the workspace root. A worktree is a context boundary — `CLAUDE.md` discovery stops at its root and gitignored content is absent — so a chat started inside a project worktree (a session's `work-sessions/{name}/workspace/repos/{repo}/` or a task's `repos/{repo}/.claude/worktrees/{slug}/`) loads only that repo's own `CLAUDE.md`, without the workspace conventions or hooks. That is occasionally what you want for isolated, repo-only work; for normal work, stay at the root and reach worktrees by path.
453
+ - **Skills are on-demand, not pre-loaded:** Skills are invoked explicitly by name (`/skill-name`) when needed; they are not loaded at session start. The `.skip` mechanism in `.claude/rules/` provides the analogous progressive-disclosure pattern for rules — a `.md.skip` file is present but inactive; rename it to `.md` to activate, rename it back to deactivate. Step 6 of this skill walks through the activation choices.
454
+ - **`scope:` for path-scoped skills:** The `scope:` frontmatter field (shown as a commented-out example at the top of this file) restricts a skill so it activates only when the working directory is inside the declared path. Removing the `#` prefix from the example line turns this skill into a path-scoped skill — useful when you want a repo-specific skill available only from inside that repo's worktree.
@@ -119,6 +119,10 @@ git commit -m "chore: update workspace from template v{fromVersion} to v{toVersi
119
119
 
120
120
  Report: "Workspace updated to v{toVersion}. Restart Claude Code if rules or hooks changed."
121
121
 
122
+ ### Step 8: Session-model migration nudge
123
+
124
+ After the update is applied, if the sessions directory (`workspace.workSessionsDir`, default `work-sessions/`) has entries and `workspace.sessionModel` is not `"task"`, append one line to the report: "This workspace still has {N} session(s) under the session model — `/migrate-sessions` can inventory and drain them and switch to the task model whenever you're ready." Suggest only; the operator decides whether and when.
125
+
122
126
  ## Notes
123
127
 
124
128
  - The CLI (`npx @ulysses-ai/create-workspace --upgrade`) stages the payload. This skill processes it.
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ dist/
3
+ .build/
@@ -8,12 +8,14 @@ This is a claude-workspace. All conventions are defined in .claude/rules/.
8
8
  - Each session is a self-contained folder at `work-sessions/{name}/` containing the worktree, nested project worktrees, and the session tracker
9
9
  - From root: only `local-only-*` and `workspace-scratchpad/` are writable
10
10
  - Team knowledge lives in `workspace-context/`
11
+ - Run `/rename` to label this chat before `/clear` — keeps the chat findable in your CLI history after the context is wiped
11
12
 
12
13
  ## Workspace Config
13
14
  @workspace.json
14
15
  @local-only-template-freshness.md
15
16
 
16
17
  ## Team Knowledge
18
+ @CODEBASE.md
17
19
  @workspace-context/canonical.md
18
20
  @workspace-context/index.md
19
21
 
@@ -24,11 +26,27 @@ This is a claude-workspace. All conventions are defined in .claude/rules/.
24
26
  - `/braindump [name]` — capture discussion/reasoning
25
27
  - `/aside [--quick] <thought>` — capture a drive-by idea without interrupting current work
26
28
  - `/pause-work` — suspend work, push, draft PR
27
- - `/complete-work` — finalize branch, release notes, real PR
29
+ - `/complete-work` — finalize the work — rebase, PR, merge, close the issue
28
30
  - `/promote` — move personal memory to shared context
29
- - `/release [version]` — combine unreleased notes into versioned doc
31
+ - `/release [version]` — cut a versioned release: bump, tag, forge release with generated notes
30
32
  - `/sync-work` — push branches without ceremony
31
33
  - `/workspace-update` — apply template updates (runs maintenance before/after)
32
34
  - `/setup-tracker` — wire this workspace to an issue tracker (GitHub Issues shipped; others pluggable)
33
35
  - `/maintenance [audit|cleanup]` — workspace health checks and cleanup
34
36
  - `/build-docs-site` — build a comprehensive Docusaurus documentation site for a project
37
+
38
+ ## Compact Instructions
39
+
40
+ When auto-compacting context, preserve in the summary:
41
+ - Decisions made in this session and their rationale
42
+ - Constraints and conventions established or confirmed
43
+ - Active task list state and the next concrete step
44
+ - File paths touched and the nature of the change
45
+ - Errors hit and what was tried
46
+
47
+ Drop from the summary:
48
+ - Verbose tool output already reflected in committed code
49
+ - Exploratory reads that did not lead to a change
50
+ - Conversational asides
51
+
52
+ Files in `workspace-context/`, the session tracker (`session.md`) or chat drawer (`workspace-scratchpad/chats/{chat}/`), and any `design-*.md`/`plan-*.md` survive compaction — they're on disk. Re-read them on demand instead of trying to keep their contents in summary.
@@ -0,0 +1,13 @@
1
+ # {{project-name}} Codebase Map
2
+
3
+ ## Top-level layout
4
+ <!-- fill in -->
5
+
6
+ ## Key entry points
7
+ <!-- fill in -->
8
+
9
+ ## Conventions
10
+ <!-- fill in -->
11
+
12
+ ## External dependencies
13
+ <!-- fill in -->
@@ -17,6 +17,10 @@ workspace-scratchpad/
17
17
  .claude/.active-session.json
18
18
  CLAUDE.local.md
19
19
 
20
+ # Worktrees of the workspace repo itself — task worktrees (repo ".") and
21
+ # Claude Code's native worktrees both live under .claude/worktrees/
22
+ .claude/worktrees/
23
+
20
24
  # Local-only convention — machine-local state, any depth
21
25
  local-only-*
22
26
 
@@ -26,3 +30,8 @@ local-only-*
26
30
  # OS
27
31
  .DS_Store
28
32
  Thumbs.db
33
+
34
+ # Per-user workspace-context indexes are generated per machine and read only
35
+ # through CLAUDE.local.md, which is itself gitignored — no mechanism reads
36
+ # another user's index. Regenerated by build-workspace-context.mjs on demand.
37
+ workspace-context/team-member/*/index.md
@@ -0,0 +1,10 @@
1
+ # {{repo-name}}
2
+
3
+ ## Purpose
4
+ <!-- fill in -->
5
+
6
+ ## Conventions
7
+ <!-- fill in -->
8
+
9
+ ## Commands
10
+ <!-- fill in: test, lint, build commands for this repo -->
@@ -6,12 +6,14 @@
6
6
  "scratchpadDir": "workspace-scratchpad",
7
7
  "workSessionsDir": "work-sessions",
8
8
  "workspaceContextDir": "workspace-context",
9
- "releaseNotesDir": "workspace-context/release-notes",
10
9
  "canonicalBudgetBytes": 40960,
11
- "subagentContextMaxBytes": 10240,
10
+ "subagentContextMaxBytes": 32768,
11
+ "subagentInlineMaxBytes": 8192,
12
12
  "greeting": "Welcome back to {{project-name}}.",
13
13
  "releaseMode": "per-repo",
14
- "tracker": null
14
+ "sessionModel": "session",
15
+ "tracker": null,
16
+ "forge": { "type": "github" }
15
17
  },
16
18
  "repos": {}
17
19
  }
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- // WorktreeCreate hook — scan for stale worktrees across project repos and
3
- // flag them. Project worktrees live inside work-sessions/{name}/workspace/repos/
4
- // in the new layout. The scan walks each project repo's worktree admin list
5
- // rather than a filesystem pattern, so it keeps working regardless of where
6
- // worktrees are physically located.
7
- import { readdirSync, existsSync } from 'fs';
8
- import { join, basename } from 'path';
9
- import { execSync } from 'child_process';
10
- import { getWorkspaceRoot, respond } from './_utils.mjs';
11
-
12
- const root = getWorkspaceRoot(import.meta.url);
13
- const reposDir = join(root, 'repos');
14
- const stale = [];
15
-
16
- if (!existsSync(reposDir)) {
17
- respond();
18
- process.exit(0);
19
- }
20
-
21
- for (const entry of readdirSync(reposDir)) {
22
- const repoPath = join(reposDir, entry);
23
- if (!existsSync(join(repoPath, '.git'))) continue;
24
-
25
- let worktreeOutput;
26
- try {
27
- worktreeOutput = execSync('git worktree list', { cwd: repoPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
28
- } catch { continue; }
29
-
30
- for (const line of worktreeOutput.trim().split('\n')) {
31
- const parts = line.trim().split(/\s+/);
32
- const wtPath = parts[0];
33
- if (!wtPath || wtPath === repoPath) continue;
34
- if (!existsSync(wtPath)) continue;
35
-
36
- const branchMatch = line.match(/\[(.+?)\]/);
37
- const branch = branchMatch ? branchMatch[1] : 'unknown';
38
-
39
- try {
40
- const lastCommit = execSync('git log -1 --format=%ci', { cwd: wtPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
41
- const daysAgo = Math.floor((Date.now() - new Date(lastCommit).getTime()) / 86400000);
42
- if (daysAgo > 3) {
43
- stale.push(`- ${basename(wtPath)} (${branch}): no commits in ${daysAgo} days`);
44
- }
45
- } catch {}
46
- }
47
- }
48
-
49
- if (stale.length > 0) {
50
- respond(`Stale worktrees found:\n${stale.join('\n')}\n\nConsider cleaning up with: git worktree remove {path}`);
51
- } else {
52
- respond();
53
- }