mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-09 14:38:59 +02:00
feat(bin): instruction-emission layer — onboarding text appears only when its gate fires
The 8 one-time onboarding flows (lake intro, telemetry opt-in, proactive opt-in, first-run/first-loop tips, routing injection, vendoring deprecation, writing-style migration, spawned-session rules), the upgrade-flow + feature discovery prose, and the privacy stop-gate (user-approved Q2) moved from every render into gated heredocs here. Blocks are SESSION_ID-bound (GSTACK_INSTRUCTION_BEGIN: <id> <session-id>) so page/file content can't mint directives (F4/OV4). Ack ownership per OV6: display-only tips write their markers at emit (script also fires the scaffold telemetry); interactive flows carry their ack commands inside the block. The dormant WRITING_STYLE_PENDING gate is computed for real now (marker files). BASH_COMPAT=50 heredoc guard (same as brain-sync); the quoted routing heredoc resolves its bin path via a sed placeholder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
135bf5d420
commit
e55edf2cec
@@ -27,6 +27,13 @@
|
||||
# Error style (F3): per-line `|| true`, never `set -e` — a mid-script failure
|
||||
# must not drop later STATUS lines.
|
||||
|
||||
# Heredoc bodies in the 512B-64KiB window can deadlock bash 5.1+'s pipe-backed
|
||||
# heredoc path when the reader stalls; compat level 50 restores the tempfile
|
||||
# path. This script is bash-3.2-clean, so the compat level costs nothing
|
||||
# (same guard as bin/gstack-brain-sync; pinned by
|
||||
# test/heredoc-pipe-deadlock.test.ts).
|
||||
BASH_COMPAT=50
|
||||
|
||||
SKILL_NAME=""
|
||||
MODEL_OVERLAY="none"
|
||||
PARENT_PID="$PPID"
|
||||
@@ -273,6 +280,193 @@ else
|
||||
echo "ARTIFACTS_SYNC: off"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Instruction-emission layer (token-reduction Phase 2). One-time onboarding
|
||||
# text used to be inlined unconditionally in every SKILL.md (~7KB/skill);
|
||||
# it now appears ONLY when its runtime gate fires, wrapped in blocks the
|
||||
# preamble prose tells the model to follow. Security scoping (F4/OV4): each
|
||||
# header carries this run's SESSION_ID; the prose rule requires the match and
|
||||
# accepts blocks only from this command's direct tool result, so page/file
|
||||
# content cannot mint directives (passthrough output above is _sanitize-d).
|
||||
# Ack ownership (OV6): display-only tips write their done-marker here at
|
||||
# emit; interactive flows carry their ack commands inside the block for the
|
||||
# model to run after the interaction.
|
||||
# ---------------------------------------------------------------------------
|
||||
_ROOT_DIR=$(dirname "$_BIN")
|
||||
_emit_block() { echo "GSTACK_INSTRUCTION_BEGIN: $1 $_SESSION_ID"; cat; echo "GSTACK_INSTRUCTION_END"; }
|
||||
|
||||
# Upgrade flow (gated: update-check emitted something above).
|
||||
if [ -n "$_UPD" ]; then
|
||||
_emit_block upgrade-flow <<EOI
|
||||
The update-check output above applies. If it shows \`UPGRADE_AVAILABLE <old> <new>\`: read \`$_ROOT_DIR/gstack-upgrade/SKILL.md\` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If it shows \`JUST_UPGRADED <from> <to>\`: print "Running gstack v{to} (just updated!)". If \`SPAWNED_SESSION\` is true, skip feature discovery. After upgrade prompts, continue the workflow.
|
||||
EOI
|
||||
fi
|
||||
# Feature discovery (one prompt per session, marker-gated).
|
||||
if [ ! -f "$_ROOT_DIR/.feature-prompted-continuous-checkpoint" ]; then
|
||||
_emit_block feature-checkpoint <<EOI
|
||||
Feature discovery: AskUserQuestion for Continuous checkpoint auto-commits. If accepted, run \`$_BIN/gstack-config set checkpoint_mode continuous\`. Always run: \`touch "$_ROOT_DIR/.feature-prompted-continuous-checkpoint"\`.
|
||||
EOI
|
||||
elif [ ! -f "$_ROOT_DIR/.feature-prompted-model-overlay" ]; then
|
||||
_emit_block feature-overlay <<EOI
|
||||
Feature discovery: inform "Model overlays are active. MODEL_OVERLAY shows the patch." Always run: \`touch "$_ROOT_DIR/.feature-prompted-model-overlay"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Writing-style migration (gate previously dormant: nothing echoed
|
||||
# WRITING_STYLE_PENDING; the script now computes it from the marker files).
|
||||
if [ -f "$_GH/.writing-style-prompt-pending" ] && [ ! -f "$_GH/.writing-style-prompted" ]; then
|
||||
_emit_block writing-style-migration <<EOI
|
||||
Ask once about writing style:
|
||||
|
||||
> v1 prompts are simpler: first-use jargon glosses, outcome-framed questions, shorter prose. Keep default or restore terse?
|
||||
|
||||
Options:
|
||||
- A) Keep the new default (recommended — good writing helps everyone)
|
||||
- B) Restore V0 prose — set \`explain_level: terse\`
|
||||
|
||||
If A: leave \`explain_level\` unset (defaults to \`default\`). If B: run \`$_BIN/gstack-config set explain_level terse\`.
|
||||
Always run (regardless of choice): \`rm -f "$_GH/.writing-style-prompt-pending" && touch "$_GH/.writing-style-prompted"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Lake intro (one-time; the offer is interactive, so the model acks).
|
||||
if [ "$_LAKE_SEEN" = "no" ]; then
|
||||
_emit_block lake-intro <<EOI
|
||||
Say: "gstack follows the **Boil the Ocean** principle — do the complete thing when AI makes marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" and offer to open it. Only run \`open https://garryslist.org/posts/boil-the-ocean\` if the user says yes. Always run: \`touch "$_GH/.completeness-intro-seen"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Telemetry opt-in (interactive; consent — the model acks after answering).
|
||||
if [ "$_TEL_PROMPTED" = "no" ] && [ "$_LAKE_SEEN" = "yes" ]; then
|
||||
_emit_block telemetry-prompt <<EOI
|
||||
Ask telemetry once via AskUserQuestion:
|
||||
|
||||
> Help gstack get better. Share usage data only: skill, duration, crashes, stable device ID. No code or file paths. Your repo name is recorded locally only and stripped before any upload.
|
||||
|
||||
Options:
|
||||
- A) Help gstack get better! (recommended)
|
||||
- B) No thanks
|
||||
|
||||
If A: run \`$_BIN/gstack-config set telemetry community\`. If B, ask the follow-up:
|
||||
|
||||
> Anonymous mode sends only aggregate usage, no unique ID.
|
||||
|
||||
Options: A) Sure, anonymous is fine B) No thanks, fully off
|
||||
If B→A: \`$_BIN/gstack-config set telemetry anonymous\`. If B→B: \`$_BIN/gstack-config set telemetry off\`.
|
||||
Always run: \`touch "$_GH/.telemetry-prompted"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Proactive-suggestions opt-in (interactive).
|
||||
if [ "$_PROACTIVE_PROMPTED" = "no" ] && [ "$_TEL_PROMPTED" = "yes" ]; then
|
||||
_emit_block proactive-prompt <<EOI
|
||||
Ask once:
|
||||
|
||||
> Let gstack proactively suggest skills, like /qa for "does this work?" or /investigate for bugs?
|
||||
|
||||
Options: A) Keep it on (recommended) B) Turn it off — I'll type /commands myself
|
||||
If A: \`$_BIN/gstack-config set proactive true\`. If B: \`$_BIN/gstack-config set proactive false\`.
|
||||
Always run: \`touch "$_GH/.proactive-prompted"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# First-run guidance (display-only tips: marker + scaffold telemetry written
|
||||
# HERE at emit, per OV6 — a lost tip is acceptable; a re-firing loop is not).
|
||||
if [ "$_ACTIVATED" = "no" ]; then
|
||||
_FT_TIP=""
|
||||
case "$_FIRST_TASK" in
|
||||
greenfield) _FT_TIP="Fresh repo — shape it first with \`/spec\` or \`/office-hours\`." ;;
|
||||
code_node|code_python|code_rust|code_go|code_ruby|code_ios) _FT_TIP="There's code here — \`/qa\` to see it work, or \`/investigate\` if something's off." ;;
|
||||
branch_ahead) _FT_TIP="Unshipped work on this branch — \`/review\` then \`/ship\`." ;;
|
||||
dirty_default) _FT_TIP="Uncommitted changes — \`/review\` before committing." ;;
|
||||
clean_default) _FT_TIP="Pick one: \`/spec\`, \`/investigate\`, or \`/qa\`." ;;
|
||||
esac
|
||||
if [ -n "$_FT_TIP" ]; then
|
||||
_emit_block first-run-tip <<EOI
|
||||
Show this one project-specific line as a heads-up, then CONTINUE with whatever the user actually asked — do NOT halt their task: $_FT_TIP
|
||||
EOI
|
||||
"$_BIN/gstack-telemetry-log" --event-type first_task_scaffold_shown --skill "$_FIRST_TASK" --outcome shown 2>/dev/null || true
|
||||
fi
|
||||
touch "$_GH/.activated" 2>/dev/null || true
|
||||
elif [ "$_FIRST_LOOP_SHOWN" = "no" ]; then
|
||||
_emit_block first-loop-tip <<EOI
|
||||
Say once as a heads-up (then continue): Tip: gstack pays off when you complete one loop — **plan → review → ship**. A common first loop: \`/office-hours\` or \`/spec\` to shape it, \`/plan-eng-review\` to lock it, then \`/ship\`.
|
||||
EOI
|
||||
touch "$_GH/.first-loop-tip-shown" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Routing injection (interactive: AUQ + CLAUDE.md append + commit). The body
|
||||
# is a quoted heredoc (markdown backticks must stay literal), so the resolved
|
||||
# bin path is substituted via sed on the __BIN__ placeholder.
|
||||
if [ "$_HAS_ROUTING" = "no" ] && [ "$_ROUTING_DECLINED" = "false" ] && [ "$_PROACTIVE_PROMPTED" = "yes" ]; then
|
||||
sed "s|__BIN__|$_BIN|g" <<'EOI' | _emit_block routing-injection
|
||||
gstack works best when the project CLAUDE.md includes skill routing rules. If no CLAUDE.md exists in the project root, create it. Use AskUserQuestion:
|
||||
|
||||
> gstack works best when your project's CLAUDE.md includes skill routing rules.
|
||||
|
||||
Options: A) Add routing rules to CLAUDE.md (recommended) B) No thanks, I'll invoke skills manually
|
||||
|
||||
If A: append this section to the end of CLAUDE.md, then commit it (`git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"`):
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.
|
||||
|
||||
Key routing rules:
|
||||
- Product ideas/brainstorming → invoke /office-hours
|
||||
- Strategy/scope → invoke /plan-ceo-review
|
||||
- Architecture → invoke /plan-eng-review
|
||||
- Design system/plan review → invoke /design-consultation or /plan-design-review
|
||||
- Full review pipeline → invoke /autoplan
|
||||
- Bugs/errors → invoke /investigate
|
||||
- QA/testing site behavior → invoke /qa or /qa-only
|
||||
- Code review/diff check → invoke /review
|
||||
- Visual polish → invoke /design-review
|
||||
- Ship/deploy/PR → invoke /ship or /land-and-deploy
|
||||
- Save progress → invoke /context-save
|
||||
- Resume context → invoke /context-restore
|
||||
- Author a backlog-ready spec/issue → invoke /spec
|
||||
|
||||
If B: run `__BIN__/gstack-config set routing_declined true` and say they can re-enable with `__BIN__/gstack-config set routing_declined false`. This only happens once per project.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Vendoring deprecation (interactive; slug-scoped marker).
|
||||
if [ "$_VENDORED" = "yes" ] && [ ! -f "$_GH/.vendoring-warned-${SLUG:-unknown}" ]; then
|
||||
_emit_block vendoring-deprecation <<EOI
|
||||
This project has gstack vendored in \`.claude/skills/gstack/\`. Vendoring is deprecated. Warn once via AskUserQuestion:
|
||||
|
||||
> Migrate to team mode?
|
||||
|
||||
Options: A) Yes, migrate to team mode now B) No, I'll handle it myself
|
||||
If A: 1) \`git rm -r .claude/skills/gstack/\` 2) \`echo '.claude/skills/gstack/' >> .gitignore\` 3) \`$_BIN/gstack-team-init required\` (or \`optional\`) 4) \`git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"\` 5) Tell the user: "Done. Each developer now runs: \`cd ~/.claude/skills/gstack && ./setup --team\`"
|
||||
If B: say "OK, you're on your own to keep the vendored copy up to date."
|
||||
Always run (regardless of choice): \`touch "$_GH/.vendoring-warned-${SLUG:-unknown}"\`.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Spawned-session rules (NOT one-time — every spawned session gets the full
|
||||
# behavioral instruction, per plan OV6 move-with-care).
|
||||
if [ -n "${OPENCLAW_SESSION:-}" ]; then
|
||||
_emit_block spawned-session <<EOI
|
||||
You are running inside a session spawned by an AI orchestrator (e.g., OpenClaw). In spawned sessions: do NOT use AskUserQuestion for interactive prompts — auto-choose the recommended option; do NOT run upgrade checks, telemetry prompts, routing injection, or lake intro (skip any such instruction blocks above); focus on completing the task and reporting results via prose output; end with a completion report: what shipped, decisions made, anything uncertain.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# Privacy stop-gate (Phase 2, user-approved Q2: consent question surfaces only
|
||||
# when consent is actually pending; still fired through AskUserQuestion).
|
||||
_ARTIFACTS_PROMPTED=$("$_BRAIN_CONFIG_BIN" get artifacts_sync_mode_prompted 2>/dev/null || echo "false")
|
||||
if [ "$_BRAIN_SYNC_MODE" = "off" ] && [ "$_ARTIFACTS_PROMPTED" != "true" ] && command -v gbrain >/dev/null 2>&1; then
|
||||
_emit_block privacy-stop-gate <<EOI
|
||||
Privacy stop-gate — ask once via AskUserQuestion:
|
||||
|
||||
> gstack can publish your artifacts (CEO plans, designs, reports) to a private GitHub repo that GBrain indexes across machines. How much should sync?
|
||||
|
||||
Options: A) Everything allowlisted (recommended) B) Only artifacts C) Decline, keep everything local
|
||||
After answer run: \`$_BIN/gstack-config set artifacts_sync_mode <full|artifacts-only|off>\` and \`$_BIN/gstack-config set artifacts_sync_mode_prompted true\`. If A/B and \`~/.gstack/.git\` is missing, ask whether to run \`gstack-artifacts-init\`. Do not block the skill.
|
||||
EOI
|
||||
fi
|
||||
|
||||
# BRAIN_HEALTH block: only for hosts whose render passes --brain-health
|
||||
# (gbrain/hermes) — gen-time host conditional preserved as a flag.
|
||||
if [ "$BRAIN_HEALTH" = "yes" ] && command -v gbrain >/dev/null 2>&1; then
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
// First-run guidance (P4 scaffold + P3 loop tip), unified into one section.
|
||||
// Branches on the persistent `.activated` lifecycle marker — NOT `_SESSIONS`,
|
||||
// which counts concurrent sessions in the last 120 min, not first-vs-returning.
|
||||
//
|
||||
// The FIRST_TASK enum is computed at runtime in generate-preamble-bash.ts (gated
|
||||
// so the detector only runs on the first run) and printed as `FIRST_TASK: <token>`.
|
||||
// This section maps the token the model SAW in that output to a one-line nudge
|
||||
// (no description string ever crosses an eval boundary) and sets markers:
|
||||
// ~/.gstack/.activated — set at the end of the first-ever skill run
|
||||
// ~/.gstack/.first-loop-tip-shown — set when the returning-session tip is shown
|
||||
//
|
||||
// Note: bash blocks run in separate shells, so the runtime token cannot be read
|
||||
// from a shell var here — the model substitutes the token it saw for TASK_TOKEN,
|
||||
// exactly like the Telemetry section substitutes SKILL_NAME/OUTCOME.
|
||||
export function generateFirstRunGuidance(ctx: TemplateContext): string {
|
||||
return `## First-run guidance (one-time)
|
||||
|
||||
If \`ACTIVATED\` is \`no\` (first skill run on this machine) AND the preamble printed a non-empty \`FIRST_TASK:\` value that is NOT \`nongit\`: show ONE short, project-specific line mapped from the token, as a heads-up, then CONTINUE with whatever the user actually asked — do NOT halt their task. Map the token: \`greenfield\` → "Fresh repo — shape it first with \`/spec\` or \`/office-hours\`." \`code_node\`/\`code_python\`/\`code_rust\`/\`code_go\`/\`code_ruby\`/\`code_ios\` → "There's code here — \`/qa\` to see it work, or \`/investigate\` if something's off." \`branch_ahead\` → "Unshipped work on this branch — \`/review\` then \`/ship\`." \`dirty_default\` → "Uncommitted changes — \`/review\` before committing." \`clean_default\` → "Pick one: \`/spec\`, \`/investigate\`, or \`/qa\`." Then substitute the token you saw for TASK_TOKEN and run (best-effort), and mark activated:
|
||||
\`\`\`bash
|
||||
${ctx.paths.binDir}/gstack-telemetry-log --event-type first_task_scaffold_shown --skill "TASK_TOKEN" --outcome shown 2>/dev/null || true
|
||||
touch ~/.gstack/.activated 2>/dev/null || true
|
||||
\`\`\`
|
||||
|
||||
If \`ACTIVATED\` is \`no\` but \`FIRST_TASK:\` is empty or \`nongit\` (headless, non-git, or nothing actionable): show nothing, just run \`touch ~/.gstack/.activated 2>/dev/null || true\`.
|
||||
|
||||
Else if \`ACTIVATED\` is \`yes\` AND \`FIRST_LOOP_SHOWN\` is \`no\`: say once as a heads-up (then continue):
|
||||
|
||||
> Tip: gstack pays off when you complete one loop — **plan → review → ship**. A common first loop: \`/office-hours\` or \`/spec\` to shape it, \`/plan-eng-review\` to lock it, then \`/ship\`.
|
||||
|
||||
Then run \`touch ~/.gstack/.first-loop-tip-shown 2>/dev/null || true\`.
|
||||
|
||||
Skip this section if \`ACTIVATED\` and \`FIRST_LOOP_SHOWN\` are both \`yes\`.`;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateLakeIntro(ctx: TemplateContext): string {
|
||||
if (ctx.model === 'gpt-5.6-sol') {
|
||||
return `If \`LAKE_INTRO\` is \`no\`: say "gstack follows the **Boil the Ocean** principle — do the complete thing within the user's explicit task boundary when AI makes marginal cost near-zero. Do not widen that boundary to adjacent cleanup or speculative hardening. Read more: https://garryslist.org/posts/boil-the-ocean" Offer to open:
|
||||
|
||||
\`\`\`bash
|
||||
open https://garryslist.org/posts/boil-the-ocean
|
||||
touch ~/.gstack/.completeness-intro-seen
|
||||
\`\`\`
|
||||
|
||||
Only run \`open\` if yes. Always run \`touch\`.`;
|
||||
}
|
||||
return `If \`LAKE_INTRO\` is \`no\`: say "gstack follows the **Boil the Ocean** principle — do the complete thing when AI makes marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" Offer to open:
|
||||
|
||||
\`\`\`bash
|
||||
open https://garryslist.org/posts/boil-the-ocean
|
||||
touch ~/.gstack/.completeness-intro-seen
|
||||
\`\`\`
|
||||
|
||||
Only run \`open\` if yes. Always run \`touch\`.`;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateProactivePrompt(ctx: TemplateContext): string {
|
||||
return `If \`PROACTIVE_PROMPTED\` is \`no\` AND \`TEL_PROMPTED\` is \`yes\`: ask once:
|
||||
|
||||
> Let gstack proactively suggest skills, like /qa for "does this work?" or /investigate for bugs?
|
||||
|
||||
Options:
|
||||
- A) Keep it on (recommended)
|
||||
- B) Turn it off — I'll type /commands myself
|
||||
|
||||
If A: run \`${ctx.paths.binDir}/gstack-config set proactive true\`
|
||||
If B: run \`${ctx.paths.binDir}/gstack-config set proactive false\`
|
||||
|
||||
Always run:
|
||||
\`\`\`bash
|
||||
touch ~/.gstack/.proactive-prompted
|
||||
\`\`\`
|
||||
|
||||
Skip if \`PROACTIVE_PROMPTED\` is \`yes\`.`;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateRoutingInjection(ctx: TemplateContext): string {
|
||||
return `If \`HAS_ROUTING\` is \`no\` AND \`ROUTING_DECLINED\` is \`false\` AND \`PROACTIVE_PROMPTED\` is \`yes\`:
|
||||
Check if a CLAUDE.md file exists in the project root. If it does not exist, create it.
|
||||
|
||||
Use AskUserQuestion:
|
||||
|
||||
> gstack works best when your project's CLAUDE.md includes skill routing rules.
|
||||
|
||||
Options:
|
||||
- A) Add routing rules to CLAUDE.md (recommended)
|
||||
- B) No thanks, I'll invoke skills manually
|
||||
|
||||
If A: Append this section to the end of CLAUDE.md:
|
||||
|
||||
\`\`\`markdown
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.
|
||||
|
||||
Key routing rules:
|
||||
- Product ideas/brainstorming → invoke /office-hours
|
||||
- Strategy/scope → invoke /plan-ceo-review
|
||||
- Architecture → invoke /plan-eng-review
|
||||
- Design system/plan review → invoke /design-consultation or /plan-design-review
|
||||
- Full review pipeline → invoke /autoplan
|
||||
- Bugs/errors → invoke /investigate
|
||||
- QA/testing site behavior → invoke /qa or /qa-only
|
||||
- Code review/diff check → invoke /review
|
||||
- Visual polish → invoke /design-review
|
||||
- Ship/deploy/PR → invoke /ship or /land-and-deploy
|
||||
- Save progress → invoke /context-save
|
||||
- Resume context → invoke /context-restore
|
||||
- Author a backlog-ready spec/issue → invoke /spec
|
||||
\`\`\`
|
||||
|
||||
Then commit the change: \`git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"\`
|
||||
|
||||
If B: run \`${ctx.paths.binDir}/gstack-config set routing_declined true\` and say they can re-enable with \`gstack-config set routing_declined false\`.
|
||||
|
||||
This only happens once per project. Skip if \`HAS_ROUTING\` is \`yes\` or \`ROUTING_DECLINED\` is \`true\`.`;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
export function generateSpawnedSessionCheck(): string {
|
||||
return `If \`SPAWNED_SESSION\` is \`"true"\`, you are running inside a session spawned by an
|
||||
AI orchestrator (e.g., OpenClaw). In spawned sessions:
|
||||
- Do NOT use AskUserQuestion for interactive prompts. Auto-choose the recommended option.
|
||||
- Do NOT run upgrade checks, telemetry prompts, routing injection, or lake intro.
|
||||
- Focus on completing the task and reporting results via prose output.
|
||||
- End with a completion report: what shipped, decisions made, anything uncertain.`;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateTelemetryPrompt(ctx: TemplateContext): string {
|
||||
return `If \`TEL_PROMPTED\` is \`no\` AND \`LAKE_INTRO\` is \`yes\`: ask telemetry once via AskUserQuestion:
|
||||
|
||||
> Help gstack get better. Share usage data only: skill, duration, crashes, stable device ID. No code or file paths. Your repo name is recorded locally only and stripped before any upload.
|
||||
|
||||
Options:
|
||||
- A) Help gstack get better! (recommended)
|
||||
- B) No thanks
|
||||
|
||||
If A: run \`${ctx.paths.binDir}/gstack-config set telemetry community\`
|
||||
|
||||
If B: ask follow-up:
|
||||
|
||||
> Anonymous mode sends only aggregate usage, no unique ID.
|
||||
|
||||
Options:
|
||||
- A) Sure, anonymous is fine
|
||||
- B) No thanks, fully off
|
||||
|
||||
If B→A: run \`${ctx.paths.binDir}/gstack-config set telemetry anonymous\`
|
||||
If B→B: run \`${ctx.paths.binDir}/gstack-config set telemetry off\`
|
||||
|
||||
Always run:
|
||||
\`\`\`bash
|
||||
touch ~/.gstack/.telemetry-prompted
|
||||
\`\`\`
|
||||
|
||||
Skip if \`TEL_PROMPTED\` is \`yes\`.`;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateVendoringDeprecation(ctx: TemplateContext): string {
|
||||
return `If \`VENDORED_GSTACK\` is \`yes\`, warn once via AskUserQuestion unless \`~/.gstack/.vendoring-warned-$SLUG\` exists:
|
||||
|
||||
> This project has gstack vendored in \`.claude/skills/gstack/\`. Vendoring is deprecated.
|
||||
> Migrate to team mode?
|
||||
|
||||
Options:
|
||||
- A) Yes, migrate to team mode now
|
||||
- B) No, I'll handle it myself
|
||||
|
||||
If A:
|
||||
1. Run \`git rm -r .claude/skills/gstack/\`
|
||||
2. Run \`echo '.claude/skills/gstack/' >> .gitignore\`
|
||||
3. Run \`${ctx.paths.binDir}/gstack-team-init required\` (or \`optional\`)
|
||||
4. Run \`git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"\`
|
||||
5. Tell the user: "Done. Each developer now runs: \`cd ~/.claude/skills/gstack && ./setup --team\`"
|
||||
|
||||
If B: say "OK, you're on your own to keep the vendored copy up to date."
|
||||
|
||||
Always run (regardless of choice):
|
||||
\`\`\`bash
|
||||
eval "$(${ctx.paths.binDir}/gstack-slug 2>/dev/null)" 2>/dev/null || true
|
||||
touch ~/.gstack/.vendoring-warned-\${SLUG:-unknown}
|
||||
\`\`\`
|
||||
|
||||
If marker exists, skip.`;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { TemplateContext } from '../types';
|
||||
|
||||
export function generateWritingStyleMigration(ctx: TemplateContext): string {
|
||||
return `If \`WRITING_STYLE_PENDING\` is \`yes\`: ask once about writing style:
|
||||
|
||||
> v1 prompts are simpler: first-use jargon glosses, outcome-framed questions, shorter prose. Keep default or restore terse?
|
||||
|
||||
Options:
|
||||
- A) Keep the new default (recommended — good writing helps everyone)
|
||||
- B) Restore V0 prose — set \`explain_level: terse\`
|
||||
|
||||
If A: leave \`explain_level\` unset (defaults to \`default\`).
|
||||
If B: run \`${ctx.paths.binDir}/gstack-config set explain_level terse\`.
|
||||
|
||||
Always run (regardless of choice):
|
||||
\`\`\`bash
|
||||
rm -f ~/.gstack/.writing-style-prompt-pending
|
||||
touch ~/.gstack/.writing-style-prompted
|
||||
\`\`\`
|
||||
|
||||
Skip if \`WRITING_STYLE_PENDING\` is \`no\`.`;
|
||||
}
|
||||
Reference in New Issue
Block a user