* chore: rename npm package + bin to @opengsd/gsd-core (functional) - package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core, bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs - package-lock.json: regenerated (npm install --package-lock-only) - tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**, get-shit-done/bin/**, get-shit-done/workflows/**: applied the 4-rule replacement (scoped npm ref, GitHub repo path, bin/clone invocations) per #505 single-source refactor Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: sweep live references to @opengsd/gsd-core Update all live documentation (README.md + translations, docs/**, CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md, docs/CANARY.md) to reflect the renamed package and repository. Rules applied: - @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name) - open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo) - GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org) - bare bin/clone refs → gsd-core CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**, and .changeset/** are preserved byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: add negative lookbehind to slash-command regex in bug-2954 test The extractSlashReferences regex matched /gsd-core inside npm package URLs (@opengsd/gsd-core), producing a false /gsd:core command reference. Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#518): add changeset for package rename Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(#518): update package-identity expectations to the renamed coordinates The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL package.json, so their expected literals must follow the rename. The drift-lint unit test is left as-is — its SEAM is a self-consistent fixture and its stale-literal detection cases would shift if altered; the live-repo scan in it already passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
200 lines
6.7 KiB
Markdown
200 lines
6.7 KiB
Markdown
# Ultraplan Phase Workflow [BETA]
|
|
|
|
Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
|
|
|
|
⚠ **BETA feature.** Ultraplan is in research preview and may change. This workflow is
|
|
intentionally isolated from /gsd:plan-phase so upstream changes to ultraplan cannot
|
|
affect the core planning pipeline.
|
|
|
|
---
|
|
|
|
<step name="banner">
|
|
|
|
Display the stage banner:
|
|
|
|
```text
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
GSD ► ULTRAPLAN PHASE ⚠ BETA
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
Ultraplan is in research preview (Claude Code v2.1.91+).
|
|
Use /gsd:plan-phase for stable local planning.
|
|
```
|
|
|
|
</step>
|
|
|
|
---
|
|
|
|
<step name="runtime_gate">
|
|
|
|
Check that the session is running inside Claude Code:
|
|
|
|
```bash
|
|
if [ "$CLAUDECODE" = "1" ] || [ -n "$CLAUDE_CODE_ENTRYPOINT" ]; then
|
|
CC_VERSION="$(claude --version 2>/dev/null | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
|
|
if [ -n "$CC_VERSION" ] && [ "$(printf '%s\n' "2.1.91" "$CC_VERSION" | sort -V | head -n1)" = "2.1.91" ]; then
|
|
echo "claude-code:${CC_VERSION}"
|
|
else
|
|
echo ""
|
|
fi
|
|
else
|
|
echo ""
|
|
fi
|
|
```
|
|
|
|
If the output is empty or unset, display the following error and exit:
|
|
|
|
```text
|
|
╔══════════════════════════════════════════════════════════════╗
|
|
║ RUNTIME ERROR ║
|
|
╚══════════════════════════════════════════════════════════════╝
|
|
|
|
/gsd:ultraplan-phase requires Claude Code.
|
|
ultraplan is not available in this runtime.
|
|
|
|
Use /gsd:plan-phase for local planning instead.
|
|
```
|
|
|
|
</step>
|
|
|
|
---
|
|
|
|
<step name="initialize">
|
|
|
|
Parse phase number from `$ARGUMENTS`. If no phase number is provided, detect the next
|
|
unplanned phase from the roadmap (same logic as /gsd:plan-phase).
|
|
|
|
Load GSD phase context:
|
|
|
|
```bash
|
|
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
INIT=$(gsd_run query init.plan-phase "$PHASE")
|
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
```
|
|
|
|
Parse JSON for: `phase_found`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`,
|
|
`phase_dir`, `roadmap_path`, `requirements_path`, `research_path`, `planning_exists`.
|
|
|
|
**If `planning_exists` is false:** Error and exit:
|
|
|
|
```text
|
|
No .planning directory found. Initialize the project first:
|
|
|
|
/gsd:new-project
|
|
```
|
|
|
|
**If `phase_found` is false:** Error with the phase number provided and exit.
|
|
|
|
Display detected phase:
|
|
|
|
```text
|
|
Phase {N}: {phase name}
|
|
```
|
|
|
|
</step>
|
|
|
|
---
|
|
|
|
<step name="build_prompt">
|
|
|
|
Build the ultraplan prompt from GSD context.
|
|
|
|
1. Read the phase scope from ROADMAP.md — extract the goal, deliverables, and scope for
|
|
the target phase.
|
|
|
|
2. Read REQUIREMENTS.md if it exists (`requirements_path` is not null) — extract a
|
|
concise summary (key requirements relevant to this phase, not the full document).
|
|
|
|
3. Read RESEARCH.md if it exists (`research_path` is not null) — extract a concise
|
|
summary of technical findings. Including this reduces redundant cloud research.
|
|
|
|
Construct the prompt:
|
|
|
|
```text
|
|
Plan phase {phase_number}: {phase_name}
|
|
|
|
## Phase Scope (from ROADMAP.md)
|
|
|
|
{phase scope block extracted from ROADMAP.md}
|
|
|
|
## Requirements Context
|
|
|
|
{requirements summary, or "No REQUIREMENTS.md found — infer from phase scope."}
|
|
|
|
## Existing Research
|
|
|
|
{research summary, or "No RESEARCH.md found — research from scratch."}
|
|
|
|
## Output Format
|
|
|
|
Produce a GSD PLAN.md with the following YAML frontmatter:
|
|
|
|
---
|
|
phase: "{padded_phase}-{phase_slug}"
|
|
plan: "{padded_phase}-01"
|
|
type: "feature"
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified: []
|
|
autonomous: true
|
|
must_haves:
|
|
truths: []
|
|
artifacts: []
|
|
---
|
|
|
|
Then a ## Plan section with numbered tasks. Each task should have:
|
|
- A clear imperative title
|
|
- Files to create or modify
|
|
- Specific implementation steps
|
|
|
|
Keep the plan focused and executable.
|
|
```
|
|
|
|
</step>
|
|
|
|
---
|
|
|
|
<step name="return_path_card">
|
|
|
|
Display the return-path instructions **before** triggering ultraplan so they are visible
|
|
in the terminal scroll-back after ultraplan launches:
|
|
|
|
```text
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
WHEN THE PLAN IS READY — WHAT TO DO
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
|
When ◆ ultraplan ready appears in your terminal:
|
|
|
|
1. Open the session link in your browser
|
|
2. Review the plan — use inline comments and emoji reactions to give feedback
|
|
3. Ask Claude to revise until you're satisfied
|
|
4. Click "Approve plan and teleport back to terminal"
|
|
5. At the terminal dialog, choose Cancel ← saves the plan to a file
|
|
6. Note the file path Claude prints
|
|
7. Run: /gsd:import --from <the file path>
|
|
|
|
/gsd:import will run conflict detection, convert to GSD format,
|
|
validate via plan-checker, update ROADMAP.md, and commit.
|
|
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
Launching ultraplan for Phase {N}: {phase_name}...
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
```
|
|
|
|
</step>
|
|
|
|
---
|
|
|
|
<step name="trigger">
|
|
|
|
Trigger ultraplan with the constructed prompt:
|
|
|
|
```text
|
|
/ultraplan {constructed prompt from build_prompt step}
|
|
```
|
|
|
|
Your terminal will show a `◇ ultraplan` status indicator while the remote session works.
|
|
Use `/tasks` to open the detail view with the session link, agent activity, and a stop action.
|
|
|
|
</step>
|