@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.
- package/README.md +5 -5
- package/lib/init.mjs +19 -0
- package/package.json +1 -1
- package/template/.claude/hooks/_utils.mjs +1 -1
- package/template/.claude/hooks/repo-write-detection.mjs +161 -64
- package/template/.claude/hooks/session-end.mjs +68 -2
- package/template/.claude/hooks/session-start.mjs +35 -1
- package/template/.claude/hooks/subagent-start.mjs +89 -22
- package/template/.claude/lib/session-frontmatter.mjs +28 -0
- package/template/.claude/rules/coherent-revisions.md +1 -1
- package/template/.claude/rules/config-review.md.skip +29 -0
- package/template/.claude/rules/forge-operations.md +51 -0
- package/template/.claude/rules/git-conventions.md +16 -11
- package/template/.claude/rules/goal-driven-work.md +8 -403
- package/template/.claude/rules/honest-pushback.md +37 -37
- package/template/.claude/rules/memory-guidance.md +43 -90
- package/template/.claude/rules/superpowers-workflow.md.skip +1 -1
- package/template/.claude/rules/work-item-tracking.md +30 -72
- package/template/.claude/rules/workspace-structure.md +49 -69
- package/template/.claude/scripts/build-workspace-context.mjs +61 -16
- package/template/.claude/scripts/chat-record.mjs +282 -0
- package/template/.claude/scripts/cleanup-work-session.mjs +363 -36
- package/template/.claude/scripts/context-footprint.mjs +282 -0
- package/template/.claude/scripts/forges/github.mjs +255 -0
- package/template/.claude/scripts/forges/gitlab.mjs +20 -0
- package/template/.claude/scripts/forges/interface.mjs +125 -0
- package/template/.claude/scripts/generate-claude-local.mjs +21 -2
- package/template/.claude/scripts/migrate-sessions.mjs +1571 -0
- package/template/.claude/scripts/migrate-to-workspace-context.mjs +7 -2
- package/template/.claude/scripts/task-worktree.mjs +525 -0
- package/template/.claude/scripts/workspace-diagnostics.mjs +654 -0
- package/template/.claude/settings.json +5 -13
- package/template/.claude/skills/braindump/SKILL.md +11 -4
- package/template/.claude/skills/build-docs-site/SKILL.md +5 -5
- package/template/.claude/skills/build-docs-site/templates/spec.md.tmpl +1 -1
- package/template/.claude/skills/complete-work/SKILL.md +255 -215
- package/template/.claude/skills/context-placement/SKILL.md +199 -0
- package/template/.claude/skills/goal-driven-work/SKILL.md +459 -0
- package/template/.claude/skills/handoff/SKILL.md +11 -4
- package/template/.claude/skills/maintenance/SKILL.md +39 -6
- package/template/.claude/skills/migrate-sessions/SKILL.md +70 -0
- package/template/.claude/skills/pause-work/SKILL.md +33 -8
- package/template/.claude/skills/release/SKILL.md +44 -108
- package/template/.claude/skills/start-work/SKILL.md +89 -7
- package/template/.claude/skills/workspace-init/SKILL.md +34 -0
- package/template/.claude/skills/workspace-update/SKILL.md +4 -0
- package/template/.claudeignore +3 -0
- package/template/CLAUDE.md.tmpl +20 -2
- package/template/CODEBASE.md.tmpl +13 -0
- package/template/_gitignore +9 -0
- package/template/repo-claude.md.tmpl +10 -0
- package/template/workspace.json.tmpl +5 -3
- 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.
|
package/template/CLAUDE.md.tmpl
CHANGED
|
@@ -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
|
|
29
|
+
- `/complete-work` — finalize the work — rebase, PR, merge, close the issue
|
|
28
30
|
- `/promote` — move personal memory to shared context
|
|
29
|
-
- `/release [version]` —
|
|
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.
|
package/template/_gitignore
CHANGED
|
@@ -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
|
|
@@ -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":
|
|
10
|
+
"subagentContextMaxBytes": 32768,
|
|
11
|
+
"subagentInlineMaxBytes": 8192,
|
|
12
12
|
"greeting": "Welcome back to {{project-name}}.",
|
|
13
13
|
"releaseMode": "per-repo",
|
|
14
|
-
"
|
|
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
|
-
}
|