mcpField
G
gstack

gstack

github.com/ivansamartinoAgent 工作流0101 次安装17 周前更新
代码仓库

关于 gstack

gstack 是一组面向 Claude Code 的技能,用于将规划、审查、QA、发布、调试、文档、安全和设计等请求路由到相应工作流。它还包含会话初始化、配置提示及技能路由设置等指引。

主要功能

  1. 01将请求路由到对应技能
  2. 02涵盖规划、审查与发布
  3. 03提供 QA、调试和安全流程
  4. 04管理会话初始化与配置提示
  5. 05可为项目设置技能路由规则

适用场景

  1. 01为开发任务选择合适的 gstack 技能
  2. 02按流程执行代码审查与发布
  3. 03在项目 CLAUDE.md 中配置技能路由

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ivansamartino/gstack --skill gstack

安装后在 Claude Code 中输入/gstack确认已加载。

详细介绍

何时调用此技能

将任何 gstack 请求发送到合适的技能 (规划、审查、QA、发布、调试、文档、安全、设计)。对于浏览器/QA 和亲自试用,它会引导你使用 /browse。没有指定技能就调用 gstack,或询问“哪个 gstack 技能适合这个任务?”时使用。

前置步骤(先运行)

_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
mkdir -p ~/.gstack/sessions
touch ~/.gstack/sessions/"$PPID"
_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
_SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false")
echo "PROACTIVE: $_PROACTIVE"
echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
echo "SKILL_PREFIX: $_SKILL_PREFIX"
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
_SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
echo "SESSION_KIND: $_SESSION_KIND"
# Conductor host: AskUserQuestion is unreliable here (native disabled, MCP
# variant flaky), so skills render decisions as prose instead of calling the
# tool. Gated on !headless so an eval/CI run INSIDE Conductor (GSTACK_HEADLESS)
# still BLOCKs rather than rendering prose to nobody.
if [ "$_SESSION_KIND" != "headless" ] && { [ -n "${CONDUCTOR_WORKSPACE_PATH:-}" ] || [ -n "${CONDUCTOR_PORT:-}" ]; }; then
  echo "CONDUCTOR_SESSION: true"
fi
_ACTIVATED=$([ -f ~/.gstack/.activated ] && echo "yes" || echo "no")
_FIRST_LOOP_SHOWN=$([ -f ~/.gstack/.first-loop-tip-shown ] && echo "yes" || echo "no")
echo "ACTIVATED: $_ACTIVATED"
echo "FIRST_LOOP_SHOWN: $_FIRST_LOOP_SHOWN"
# First-run project detection: run the detector ONLY on the first-ever skill run
# (ACTIVATED=no, interactive) so it stays off the hot path for every run after.
_FIRST_TASK=""
if [ "$_ACTIVATED" = "no" ] && [ "$_SESSION_KIND" != "headless" ]; then
  _FIRST_TASK=$(~/.claude/skills/gstack/bin/gstack-first-task-detect 2>/dev/null || true)
fi
echo "FIRST_TASK: $_FIRST_TASK"
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
_TEL_START=$(date +%s)
_SESSION_ID="$$-$(date +%s)"
echo "TELEMETRY: ${_TEL:-off}"
echo "TEL_PROMPTED: $_TEL_PROMPTED"
_EXPLAIN_LEVEL=$(~/.claude/skills/gstack/bin/gstack-config get explain_level 2>/dev/null || echo "default")
if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
_QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false")
echo "QUESTION_TUNING: $_QUESTION_TUNING"
mkdir -p ~/.gstack/analytics
if [ "$_TEL" != "off" ]; then
echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(_repo=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null | tr -cd 'a-zA-Z0-9._-'); echo "${_repo:-unknown}")'"}'  >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
fi
for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
  if [ -f "$_PF" ]; then
    if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
      ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true
    fi
    rm -f "$_PF" 2>/dev/null || true
  fi
  break
done
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
  _LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
  echo "LEARNINGS: $_LEARN_COUNT entries loaded"
  if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
    ~/.claude/skills/gstack/bin/gstack-learnings-search --limit 3 2>/dev/null || true
  fi
else
  echo "LEARNINGS: 0"
fi
~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"gstack","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null &
_HAS_ROUTING="no"
if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then
  _HAS_ROUTING="yes"
fi
_ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false")
echo "HAS_ROUTING: $_HAS_ROUTING"
echo "ROUTING_DECLINED: $_ROUTING_DECLINED"
_VENDORED="no"
if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
  if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then
    _VENDORED="yes"
  fi
fi
echo "VENDORED_GSTACK: $_VENDORED"
echo "MODEL_OVERLAY: claude"
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
# Plan-mode hint for skills like /spec that branch behavior on plan-mode state.
# Claude Code exposes plan mode via system reminders; we detect best-effort
# from CLAUDE_PLAN_FILE (set by the harness when plan mode is active) and
# fall back to "inactive". Codex hosts and Claude execution mode both end up
# inactive, which is the safe default (defaults to file+execute pipeline).
if [ -n "${CLAUDE_PLAN_FILE:-}${GSTACK_PLAN_MODE_FORCE:-}" ]; then
  export GSTACK_PLAN_MODE="active"
elif [ "${GSTACK_PLAN_MODE:-}" = "active" ]; then
  export GSTACK_PLAN_MODE="active"
else
  export GSTACK_PLAN_MODE="inactive"
fi
echo "GSTACK_PLAN_MODE: $GSTACK_PLAN_MODE"
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true

计划模式下的安全操作

在计划模式下,以下操作是允许的,因为它们有助于制定计划:$B、$D、codex exec/codex review、写入 ~/.gstack/、写入计划文件,以及使用 open 打开生成的产物。

在计划模式下调用技能

如果用户在计划模式下调用技能,则技能优先于通用计划模式行为。将技能文件视为可执行指令,而不是参考资料。 从步骤 0 开始逐步执行;第一次 AskUserQuestion 是进入计划模式的工作流,不违反计划模式。AskUserQuestion(任何变体——mcp__*__AskUserQuestion 或原生工具;参见“AskUserQuestion 格式 → 工具解析”)满足计划模式的回合结束要求。如果 AskUserQuestion 不可用或调用失败,请遵循 AskUserQuestion 格式中的失败回退:headless → 阻止;interactive → 使用文字回退方案(同样满足回合结束要求)。到达 STOP 点时,立即停止。不要继续工作流,也不要在那里调用 ExitPlanMode。标记为“计划模式例外——始终运行”的命令必须执行。只有在技能工作流完成后,或用户要求取消技能或退出计划模式时,才调用 ExitPlanMode。

如果 PROACTIVE 为 "false",不要自动调用或主动建议技能。如果某项技能似乎有帮助,请询问:“我觉得 /skillname 可能对这里有帮助——要我运行吗?”

如果 SKILL_PREFIX 为 "true",请建议/调用 /gstack-* 名称。磁盘路径保持为 ~/.claude/skills/gstack/[skill-name]/SKILL.md。

如果输出显示 UPGRADE_AVAILABLE <old> <new>:读取 ~/.claude/skills/gstack/gstack-upgrade/SKILL.md 并遵循“内联升级流程”(如果已配置则自动升级,否则通过 AskUserQuestion 提供 4 个选项;如果用户拒绝,则写入暂停提示状态)。

如果输出显示 JUST_UPGRADED <from> <to>:打印“正在运行 gstack v{to}(刚刚更新!)”。如果 SPAWNED_SESSION 为 true,则跳过功能发现。

功能发现,每个会话最多提示一次:

  • 如果缺少 ~/.claude/skills/gstack/.feature-prompted-continuous-checkpoint:通过 AskUserQuestion 询问是否启用持续检查点自动提交。如果用户接受,运行 ~/.claude/skills/gstack/bin/gstack-config set checkpoint_mode continuous。始终触碰标记文件。
  • 如果缺少 ~/.claude/skills/gstack/.feature-prompted-model-overlay:告知“模型叠加层已启用。MODEL_OVERLAY 显示补丁。”始终触碰标记文件。

升级提示后,继续工作流。

如果 WRITING_STYLE_PENDING 为 yes:询问一次写作风格:

v1 提示词更简单:首次出现的术语会附带解释、问题以结果为导向、文字更简短。保留默认设置,还是恢复简洁风格?

选项:

  • A) 保留新的默认设置(推荐——好的写作对每个人都有帮助)
  • B) 恢复 V0 文风——设置 explain_level: terse

如果选择 A:保持 explain_level 未设置(默认值为 default)。 如果选择 B:运行 ~/.claude/skills/gstack/bin/gstack-config set explain_level terse。

无论选择如何,都始终运行:

rm -f ~/.gstack/.writing-style-prompt-pending
touch ~/.gstack/.writing-style-prompted

如果 WRITING_STYLE_PENDING 为 no,则跳过。

如果 LAKE_INTRO 为 no:说“gstack 遵循 Boil the Ocean 原则——当 AI 使边际成本接近于零时,就把事情完整做好。了解更多:https://garryslist.org/posts/boil-the-ocean”并询问是否打开:

open https://garryslist.org/posts/boil-the-ocean
touch ~/.gstack/.completeness-intro-seen

只有在用户同意时才运行 open。始终运行 touch。

如果 TEL_PROMPTED 为 no 且 LAKE_INTRO 为 yes:通过 AskUserQuestion 询问一次是否同意遥测:

帮助 gstack 变得更好。仅分享使用数据:技能、耗时、崩溃情况、稳定的设备 ID。不包含代码或文件路径。你的仓库名称只在本地记录,并会在上传前删除。

选项:

  • A) 帮助 gstack 变得更好!(推荐)
  • B) 不用了

如果选择 A:运行 ~/.claude/skills/gstack/bin/gstack-config set telemetry community

如果选择 B:询问后续问题:

匿名模式仅发送汇总使用数据,不会发送唯一 ID。

选项:

  • A) 可以,匿名模式没问题
  • B) 不用了,完全关闭

如果 B→A:运行 ~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous 如果 B→B:运行 ~/.claude/skills/gstack/bin/gstack-config set telemetry off

始终运行:

touch ~/.gstack/.telemetry-prompted

如果 TEL_PROMPTED 的值为 yes,则跳过。

如果 PROACTIVE_PROMPTED 的值为 no,且 TEL_PROMPTED 的值为 yes:询问一次:

是否允许 gstack 主动推荐技能,例如针对“这能正常运行吗?”推荐 /qa,或针对错误推荐 /investigate?

选项:

  • A) 保持开启(推荐)
  • B) 关闭——我会自行输入 /commands

如果 A:运行 ~/.claude/skills/gstack/bin/gstack-config set proactive true 如果 B:运行 ~/.claude/skills/gstack/bin/gstack-config set proactive false

始终运行:

touch ~/.gstack/.proactive-prompted

如果 PROACTIVE_PROMPTED 的值为 yes,则跳过。

首次运行指引(一次性)

如果 ACTIVATED 为 no(这台机器上首次运行该技能),并且前言打印了非空的 FIRST_TASK: 值,且该值不是 nongit:根据令牌显示一条简短、针对项目的提示,然后继续处理用户实际提出的请求——不要中断任务。令牌映射:greenfield → “这是一个全新仓库——先用 /spec 或 /office-hours 梳理方向。” code_node/code_python/code_rust/code_go/code_ruby/code_ios → “这里已有代码——用 /qa 看看效果,或在有问题时用 /investigate。” branch_ahead → “此分支上有尚未发布的工作——先 /review,再 /ship。” dirty_default → “存在未提交的更改——提交前先 /review。” clean_default → “任选一个:/spec、/investigate 或 /qa。” 然后将你看到的令牌代入 TASK_TOKEN 并运行(尽力执行),再标记为已激活:

~/.claude/skills/gstack/bin/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

如果 ACTIVATED 为 no,但 FIRST_TASK: 为空或为 nongit(无头、非 git,或没有可执行的事项):不显示任何内容,只运行 touch ~/.gstack/.activated 2>/dev/null || true。

否则,如果 ACTIVATED 为 yes 且 FIRST_LOOP_SHOWN 为 no:提示一次(然后继续):

提示:完成一个完整循环,才能充分发挥 gstack 的价值——规划 → 评审 → 发布。常见的第一个循环是:用 /office-hours 或 /spec 梳理方向,用 /plan-eng-review 敲定方案,然后用 /ship 发布。

然后运行 touch ~/.gstack/.first-loop-tip-shown 2>/dev/null || true。

如果 ACTIVATED 和 FIRST_LOOP_SHOWN 均为 yes,则跳过此部分。

如果 HAS_ROUTING 为 no、ROUTING_DECLINED 为 false 且 PROACTIVE_PROMPTED 为 yes: 检查项目根目录中是否存在 CLAUDE.md 文件。如果不存在,则创建该文件。

使用 AskUserQuestion:

如果项目的 CLAUDE.md 包含技能路由规则,gstack 的效果会更好。

选项:

  • A) 将路由规则添加到 CLAUDE.md(推荐)
  • B) 不用了,我会手动调用技能

如果选择 A:将以下部分追加到 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

然后提交更改:git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"

如果选择 B:运行 ~/.claude/skills/gstack/bin/gstack-config set routing_declined true,并说明可以运行 gstack-config set routing_declined false 重新启用。

每个项目只会执行一次。若 HAS_ROUTING 为 yes 或 ROUTING_DECLINED 为 true,则跳过。

如果 VENDORED_GSTACK 为 yes,且 ~/.gstack/.vendoring-warned-$SLUG 不存在,则通过 AskUserQuestion 警告一次:

此项目在 .claude/skills/gstack/ 中包含 vendored 版本的 gstack。Vendoring 已弃用。 迁移到团队模式?

选项:

  • A) 是,现在迁移到团队模式
  • B) 不用了,我会自行处理

如果选择 A:

  1. 运行 git rm -r .claude/skills/gstack/
  2. 运行 echo '.claude/skills/gstack/' >> .gitignore
  3. 运行 ~/.claude/skills/gstack/bin/gstack-team-init required(或 optional)
  4. 运行 git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"
  5. 告知用户:“完成。现在每位开发者都需要运行:cd ~/.claude/skills/gstack && ./setup --team”

如果选择 B:说“好的,vendored 副本的更新由你自行维护。”

无论选择如何,都要运行:

eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}

如果标记文件存在,则跳过。

如果 SPAWNED_SESSION 为 "true",则表示你正在由 AI 编排器(例如 OpenClaw)启动的会话中运行。在这类会话中:

  • 不要使用 AskUserQuestion 发起交互式提问。自动选择推荐选项。
  • 不要执行升级检查、遥测提示、路由注入或 lake 介绍。
  • 专注于完成任务,并通过文字输出报告结果。
  • 最后提供完成报告:说明已交付的内容、作出的决定,以及任何不确定之处。

Artifacts Sync(技能开始)

_GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
# Prefer the v1.27.0.0 artifacts file; fall back to brain file for users
# upgrading mid-stream before the migration script runs.
if [ -f "$HOME/.gstack-artifacts-remote.txt" ]; then
  _BRAIN_REMOTE_FILE="$HOME/.gstack-artifacts-remote.txt"
else
  _BRAIN_REMOTE_FILE="$HOME/.gstack-brain-remote.txt"
fi
_BRAIN_SYNC_BIN="~/.claude/skills/gstack/bin/gstack-brain-sync"
_BRAIN_CONFIG_BIN="~/.claude/skills/gstack/bin/gstack-config"

# /sync-gbrain context-load: teach the agent to use gbrain when it's available.
# Per-worktree pin: post-spike redesign uses kubectl-style `.gbrain-source` in the
# git toplevel to scope queries. Look for the pin in the worktree (not a global
# state file) so that opening worktree B without a pin doesn't claim "indexed"
# just because worktree A was synced. Empty string when gbrain is not
# configured (zero context cost for non-gbrain users).
_GBRAIN_CONFIG="$HOME/.gbrain/config.json"
if [ -f "$_GBRAIN_CONFIG" ] && command -v gbrain >/dev/null 2>&1; then
  _GBRAIN_VERSION_OK=$(gbrain --version 2>/dev/null | grep -c '^gbrain ' || echo 0)
  if [ "$_GBRAIN_VERSION_OK" -gt 0 ] 2>/dev/null; then
    _GBRAIN_PIN_PATH=""
    _REPO_TOP=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
    if [ -n "$_REPO_TOP" ] && [ -f "$_REPO_TOP/.gbrain-source" ]; then
      _GBRAIN_PIN_PATH="$_REPO_TOP/.gbrain-source"
    fi
    if [ -n "$_GBRAIN_PIN_PATH" ]; then
      echo "GBrain configured. Prefer \`gbrain search\`/\`gbrain query\` over Grep for"
      echo "semantic questions; use \`gbrain code-def\`/\`code-refs\`/\`code-callers\` for"
      echo "symbol-aware code lookup. See \"## GBrain Search Guidance\" in CLAUDE.md."
      echo "Run /sync-gbrain to refresh."
    else
      echo "GBrain configured but this worktree isn't pinned yet. Run \`/sync-gbrain --full\`"
      echo "before relying on \`gbrain search\` for code questions in this worktree."
      echo "Falls back to Grep until pinned."
    fi
  fi
fi

_BRAIN_SYNC_MODE=$("$_BRAIN_CONFIG_BIN" get artifacts_sync_mode 2>/dev/null || echo off)

# Detect remote-MCP mode (Path 4 of /setup-gbrain). Local artifacts sync is
# a no-op in remote mode; the brain server pulls from GitHub/GitLab on its
# own cadence. Read claude.json directly to keep this preamble fast (no
# subprocess to claude CLI on every skill start).
_GBRAIN_MCP_MODE="none"
if command -v jq >/dev/null 2>&1 && [ -f "$HOME/.claude.json" ]; then
  _GBRAIN_MCP_TYPE=$(jq -r '.mcpServers.gbrain.type // .mcpServers.gbrain.transport // empty' "$HOME/.claude.json" 2>/dev/null)
  case "$_GBRAIN_MCP_TYPE" in
    url|http|sse) _GBRAIN_MCP_MODE="remote-http" ;;
    stdio) _GBRAIN_MCP_MODE="local-stdio" ;;
  esac
fi

if [ -f "$_BRAIN_REMOTE_FILE" ] && [ ! -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" = "off" ]; then
  _BRAIN_NEW_URL=$(head -1 "$_BRAIN_REMOTE_FILE" 2>/dev/null | tr -d '[:space:]')
  if [ -n "$_BRAIN_NEW_URL" ]; then
    echo "ARTIFACTS_SYNC: artifacts repo detected: $_BRAIN_NEW_URL"
    echo "ARTIFACTS_SYNC: run 'gstack-brain-restore' to pull your cross-machine artifacts (or 'gstack-config set artifacts_sync_mode off' to dismiss forever)"
  fi
fi

if [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
  _BRAIN_LAST_PULL_FILE="$_GSTACK_HOME/.brain-last-pull"
  _BRAIN_NOW=$(date +%s)
  _BRAIN_DO_PULL=1
  if [ -f "$_BRAIN_LAST_PULL_FILE" ]; then
    _BRAIN_LAST=$(cat "$_BRAIN_LAST_PULL_FILE" 2>/dev/null || echo 0)
    _BRAIN_AGE=$(( _BRAIN_NOW - _BRAIN_LAST ))
    [ "$_BRAIN_AGE" -lt 86400 ] && _BRAIN_DO_PULL=0
  fi
  if [ "$_BRAIN_DO_PULL" = "1" ]; then
    ( cd "$_GSTACK_HOME" && git fetch origin >/dev/null 2>&1 && git merge --ff-only "origin/$(git rev-parse --abbrev-ref HEAD)" >/dev/null 2>&1 ) || true
    echo "$_BRAIN_NOW" > "$_BRAIN_LAST_PULL_FILE"
  fi
  "$_BRAIN_SYNC_BIN" --once 2>/dev/null || true
fi

if [ "$_GBRAIN_MCP_MODE" = "remote-http" ]; then
  # Remote-MCP mode: local artifacts sync is a no-op (brain admin's server
  # pulls from GitHub/GitLab). Show the user this is by design, not broken.
  _GBRAIN_HOST=$(jq -r '.mcpServers.gbrain.url // empty' "$HOME/.claude.json" 2>/dev/null | sed -E 's|^https?://([^/:]+).*|\1|')
  echo "ARTIFACTS_SYNC: remote-mode (managed by brain server ${_GBRAIN_HOST:-remote})"
elif [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
  _BRAIN_QUEUE_DEPTH=0
  [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ')
  _BRAIN_LAST_PUSH="never"
  [ -f "$_GSTACK_HOME/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(cat "$_GSTACK_HOME/.brain-last-push" 2>/dev/null || echo never)
  echo "ARTIFACTS_SYNC: mode=$_BRAIN_SYNC_MODE | last_push=$_BRAIN_LAST_PUSH | queue=$_BRAIN_QUEUE_DEPTH"
else
  echo "ARTIFACTS_SYNC: off"
fi

隐私停止门:如果输出显示 ARTIFACTS_SYNC: off,artifacts_sync_mode_prompted 为 false,且 gbrain 在 PATH 中,或 gbrain doctor --fast --json 可以运行,则询问一次:

gstack 可以将你的制品(CEO 计划、设计、报告)发布到一个由 GBrain 跨设备索引的私有 GitHub 仓库。你希望同步哪些内容?

选项:

  • A) 所有允许列表中的内容(推荐)
  • B) 仅制品
  • C) 拒绝,所有内容保留在本地

收到回答后:

# Chosen mode: full | artifacts-only | off
"$_BRAIN_CONFIG_BIN" set artifacts_sync_mode <choice>
"$_BRAIN_CONFIG_BIN" set artifacts_sync_mode_prompted true

如果选择 A/B,且缺少 ~/.gstack/.git,询问是否运行 gstack-artifacts-init。不要阻止技能继续执行。

技能结束时,在遥测之前:

"~/.claude/skills/gstack/bin/gstack-brain-sync" --discover-new 2>/dev/null || true
"~/.claude/skills/gstack/bin/gstack-brain-sync" --once 2>/dev/null || true

特定模型行为补丁(claude)

以下建议针对 claude 模型系列进行了调整。它们 从属于技能工作流、STOP 节点、AskUserQuestion 门、计划模式安全要求 以及 /ship 审查门。如果以下建议与技能指令冲突,以技能指令为准。 请将这些视为偏好,而非规则。

待办列表纪律。 执行多步骤计划时,每完成一项任务就单独将其标记为 已完成。不要在最后批量标记。如果发现某项任务没有必要,将其标记为跳过, 并用一句话说明原因。

执行重大操作前先思考。 对于复杂操作(重构、迁移、 重要的新功能),执行前简要说明你的方案。这样用户可以在操作中途之前, 以较低成本纠正方向。

优先使用专用工具,而非 Bash。 优先使用 Read、Edit、Write、Glob、Grep, 而不是对应的 shell 命令(cat、sed、find、grep)。专用工具更省资源,也更清晰。

表达风格

直接、具体,像开发者之间交流。说清文件、函数、命令和对用户可见的影响。不说废话。

不要使用 em dash。不要使用 AI 术语:delve、crucial、robust、comprehensive、nuanced、multifaceted。避免企业化或学术化表达。段落简短。以接下来要做的事收尾。

用户掌握你不知道的上下文。跨模型的一致意见只是建议,不是决策。由用户决定。

完成状态协议

完成技能工作流时,使用以下状态之一报告:

  • DONE — 已完成,并有证据。
  • DONE_WITH_CONCERNS — 已完成,但需列出顾虑。
  • BLOCKED — 无法继续;说明阻碍和已尝试的操作。
  • NEEDS_CONTEXT — 缺少信息;准确说明需要什么。

连续失败 3 次、遇到不确定的安全敏感变更,或无法验证范围时,应升级处理。格式:STATUS、REASON、ATTEMPTED、RECOMMENDATION。

操作改进

完成前,如果发现了能在下次节省 5 分钟以上的持久项目特性或命令修正,请记录:

~/.claude/skills/gstack/bin/gstack-learnings-log '{"skill":"SKILL_NAME","type":"operational","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"observed"}'

不要记录显而易见的事实或一次性的临时错误。

遥测(最后运行)

工作流完成后,记录遥测。使用 frontmatter 中的技能 name:。OUTCOME 为 success/error/abort/unknown。

计划模式例外情况:始终运行。 此命令会将遥测写入 ~/.gstack/analytics/,与序言中的分析数据写入位置一致。

运行此 bash:

_TEL_END=$(date +%s)
_TEL_DUR=$(( _TEL_END - _TEL_START ))
rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
# Session timeline: record skill completion (local-only, never sent anywhere)
~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true
# Local analytics (gated on telemetry setting)
if [ "$_TEL" != "off" ]; then
echo '{"skill":"SKILL_NAME","duration_s":"'"$_TEL_DUR"'","outcome":"OUTCOME","browse":"USED_BROWSE","session":"'"$_SESSION_ID"'","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
fi
# Remote telemetry (opt-in, requires binary)
if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then
  ~/.claude/skills/gstack/bin/gstack-telemetry-log \
    --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \
    --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null &
fi

运行前替换 SKILL_NAME、OUTCOME 和 USED_BROWSE。

计划状态页脚

运行计划审查的技能(/plan-*-review、/codex review)会在技能末尾包含 EXIT PLAN MODE GATE 阻止清单,用于验证计划文件以 ## GSTACK REVIEW REPORT 结尾,然后才调用 ExitPlanMode。不运行计划审查的技能(如 /ship、/qa、/review 等操作型技能)通常不使用计划模式,也无需验证审查报告;此页脚对它们不起作用。在计划模式下,唯一允许的编辑是编写计划文件。

先路由

这是 gstack 路由器。它唯一的职责是将请求发送到正确的技能。

  1. 如果请求与浏览器、QA、试用体验、截图或检查页面有关 (打开网站、测试部署、截图、直观检查流程)→ 调用 /browse。
  2. 否则,根据以下规则进行路由。如果没有匹配项,直接回答。 尽力记录你采用的路由方式(绝不因此阻塞)。将 ROUTE_OUTCOME 设为 browse(发送到 /browse)、routed(发送到其他技能)或 direct(直接回答, 没有匹配的技能):
~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type route --skill gstack --outcome ROUTE_OUTCOME --session-id "$_SESSION_ID" 2>/dev/null || true

如果 PROACTIVE 为 false:在本次会话中,不要主动调用或建议使用其他 gstack 技能。只运行用户明确调用的技能。此偏好会通过 gstack-config 在会话之间保留。

如果 PROACTIVE 为 true(默认值):当用户的请求符合某项技能的用途时,调用 Skill 工具。如果存在适用于该任务的技能,不要直接回答。使用 Skill 工具调用该技能。该技能包含专门的工作流、检查清单和质量关卡,能比直接回答提供更好的结果。

路由规则——遇到以下情况时,通过 Skill 工具调用相应技能:

  • 用户提出新想法,询问“值不值得开发”,进行头脑风暴或推介概念 → 调用 /office-hours
  • 用户要求细化规格、提交 issue、撰写工单、“把这个整理成 GitHub issue”或“待办事项” → 调用 /spec
  • 用户询问策略、范围、雄心、“再想远一点”或“我们应该开发什么” → 调用 /plan-ceo-review
  • 用户要求审查架构、敲定计划或询问“这个设计合理吗” → 调用 /plan-eng-review
  • 用户询问设计系统、品牌、视觉形象或“这个应该是什么样子” → 调用 /design-consultation
  • 用户要求审查计划的设计 → 调用 /plan-design-review
  • 用户询问计划的开发者体验或 API/CLI/SDK 设计 → 调用 /plan-devex-review
  • 用户希望自动完成所有审查,或说“全面审查” → 调用 /autoplan
  • 用户报告 Bug、错误或行为异常,询问“为什么坏了”“这不工作”“怎么回事”或“出问题了” → 调用 /investigate
  • 用户要求测试网站、查找 Bug、进行 QA,询问“这能用吗”或“检查部署情况” → 调用 /qa
  • 用户只要求报告 Bug,不要求修复 → 调用 /qa-only
  • 用户要求审查代码、检查差异、在合并前进行审查,或说“看看我的改动” → 调用 /review
  • 用户询问视觉润色、要求审查线上网站的设计,或说“看起来不太对” → 调用 /design-review
  • 用户要求审查线上开发者体验、衡量从开始到运行示例所需的时间 → 调用 /devex-review
  • 用户要求发布、部署、推送、创建 PR,或说“合并吧”“发出去” → 调用 /ship
  • 用户要求一站式完成合并、部署和验证 → 调用 /land-and-deploy
  • 用户要求为项目配置部署 → 调用 /setup-deploy
  • 用户要求发布后监控生产环境、进行部署后检查 → 调用 /canary
  • 用户要求发布后更新文档 → 调用 /document-release
  • 用户要求从头撰写文档、生成文档,或“为这个功能/模块编写文档” → 调用 /document-generate
  • 用户要求进行每周回顾,询问本周发布了什么或“我们做得怎么样” → 调用 /retro
  • 用户要求征求第二意见或进行 Codex 审查 → 调用 /codex
  • 用户要求安全模式或谨慎模式 → 调用 /careful 或 /guard
  • 用户要求将编辑限制在某个目录 → 调用 /freeze 或 /unfreeze
  • 用户要求升级 gstack → 调用 /gstack-upgrade
  • 用户要求保存进度、创建检查点或“保存我的工作” → 调用 /context-save
  • 用户要求继续、恢复进度或询问“我上次做到哪儿了” → 调用 /context-restore
  • 用户询问安全、OWASP、漏洞或“这安全吗” → 调用 /cso
  • 用户要求制作 PDF、文档或出版物 → 调用 /make-pdf
  • 用户要求启动真实浏览器进行 QA,或“打开浏览器” → 调用 /open-gstack-browser
  • 用户要求导入 Cookie 以进行身份验证测试 → 调用 /setup-browser-cookies
  • 用户询问页面速度、性能回退或基准测试 → 调用 /benchmark
  • 用户询问 gstack 有哪些经验,或要求“展示经验总结” → 调用 /learn
  • 用户要求调整提问敏感度,或说“别再问我这个了” → 调用 /plan-tune
  • 用户要求提供代码质量仪表板或“健康检查” → 调用 /health 拿不准时,就调用技能。 误报(调用了不需要的技能)的代价,比漏报(在存在结构化工作流时临时回答)更低。技能提供多步骤工作流、检查清单和质量关卡,始终能产出比临时回答更好的结果。如果没有匹配的技能,就像往常一样直接回答。

如果用户选择不接收建议,请运行 gstack-config set proactive false。 如果用户重新选择接收建议,请运行 gstack-config set proactive true。

评论

支持 Markdown