Merge remote-tracking branch 'origin/main' into garrytan/askuser-one-at-a-time

Resolved conflicts:
- VERSION: take main's 0.11.17.0 (newer)
- CHANGELOG.md: keep main's 0.11.17.0 entry, drop our stale 0.11.16.2 entry
- SKILL.md, benchmark/SKILL.md, browse/SKILL.md, setup-browser-cookies/SKILL.md:
  regenerated from templates via bun run gen:skill-docs
This commit is contained in:
Garry Tan
2026-03-24 18:08:54 -07:00
44 changed files with 485 additions and 206 deletions
-11
View File
@@ -3012,17 +3012,6 @@ function processTemplate(tmplPath: string, host: Host = 'claude'): { outputPath:
throw new Error(`Unresolved placeholders in ${relTmplPath}: ${remaining.join(', ')}`);
}
// Inject auto-trigger guard into skill descriptions.
// Adds explicit trigger criteria so Claude Code doesn't auto-fire skills
// based on semantic similarity. Preserves existing "Use when" and
// "Proactively suggest" text (both are tested in skill-validation.test.ts).
const triggerGuard = ` MANUAL TRIGGER ONLY: invoke only when user types /${skillName}.\n`;
const descMatch = content.match(/^(description:\s*\|?\s*\n)/m);
if (descMatch && descMatch.index !== undefined) {
const insertAt = descMatch.index + descMatch[0].length;
content = content.slice(0, insertAt) + triggerGuard + content.slice(insertAt);
}
// For codex host: transform frontmatter and replace Claude-specific paths
if (host === 'codex') {
// Extract hook safety prose BEFORE transforming frontmatter (which strips hooks)
+31 -2
View File
@@ -21,9 +21,11 @@ _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr
find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true
_CONTRIB=$(${ctx.paths.binDir}/gstack-config get gstack_contributor 2>/dev/null || true)
_PROACTIVE=$(${ctx.paths.binDir}/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"
echo "PROACTIVE: $_PROACTIVE"
echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
source <(${ctx.paths.binDir}/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=\${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
@@ -43,8 +45,11 @@ for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null
}
function generateUpgradeCheck(ctx: TemplateContext): string {
return `If \`PROACTIVE\` is \`"false"\`, do not proactively suggest gstack skills — only invoke
them when the user explicitly asks. The user opted out of proactive suggestions.
return `If \`PROACTIVE\` is \`"false"\`, do not proactively suggest gstack skills AND do not
auto-invoke skills based on conversation context. Only run skills the user explicitly
types (e.g., /qa, /ship). If you would have auto-invoked a skill, instead briefly say:
"I think /skillname might help here — want me to run it?" and wait for confirmation.
The user opted out of proactive behavior.
If output shows \`UPGRADE_AVAILABLE <old> <new>\`: read \`${ctx.paths.skillRoot}/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 \`JUST_UPGRADED <from> <to>\`: tell user "Running gstack v{to} (just updated!)" and continue.`;
}
@@ -98,6 +103,29 @@ touch ~/.gstack/.telemetry-prompted
This only happens once. If \`TEL_PROMPTED\` is \`yes\`, skip this entirely.`;
}
function generateProactivePrompt(ctx: TemplateContext): string {
return `If \`PROACTIVE_PROMPTED\` is \`no\` AND \`TEL_PROMPTED\` is \`yes\`: After telemetry is handled,
ask the user about proactive behavior. Use AskUserQuestion:
> gstack can proactively figure out when you might need a skill while you work —
> like suggesting /qa when you say "does this work?" or /investigate when you hit
> a bug. We recommend keeping this on — it speeds up every part of your workflow.
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
\`\`\`
This only happens once. If \`PROACTIVE_PROMPTED\` is \`yes\`, skip this entirely.`;
}
function generateAskUserFormat(_ctx: TemplateContext): string {
return `## AskUserQuestion Format
@@ -382,6 +410,7 @@ export function generatePreamble(ctx: TemplateContext): string {
generateUpgradeCheck(ctx),
generateLakeIntro(),
generateTelemetryPrompt(ctx),
generateProactivePrompt(ctx),
...(tier >= 2 ? [generateAskUserFormat(ctx), generateCompletenessSection()] : []),
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
generateContributorMode(),