mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-19 19:02:29 +08:00
feat: preamble context recovery + timeline events + predictive suggestions
Layers 1-3 of the Session Intelligence Layer: - Timeline start/complete events injected into every skill via preamble - Context recovery (tier 2+): lists recent CEO plans, checkpoints, reviews - Cross-session injection: LAST_SESSION and LATEST_CHECKPOINT for branch - Predictive skill suggestion from recent timeline patterns - Welcome back message synthesis - Routing rules for /checkpoint and /health Timeline writes are NOT gated by telemetry (local project intelligence). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,8 @@ if [ -f "$_LEARN_FILE" ]; then
|
|||||||
else
|
else
|
||||||
echo "LEARNINGS: 0"
|
echo "LEARNINGS: 0"
|
||||||
fi
|
fi
|
||||||
|
# Session timeline: record skill start (local-only, never sent anywhere)
|
||||||
|
${ctx.paths.binDir}/gstack-timeline-log '{"skill":"${ctx.skillName}","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null &
|
||||||
# Check if CLAUDE.md has routing rules
|
# Check if CLAUDE.md has routing rules
|
||||||
_HAS_ROUTING="no"
|
_HAS_ROUTING="no"
|
||||||
if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then
|
if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then
|
||||||
@@ -210,6 +212,8 @@ Key routing rules:
|
|||||||
- Design system, brand → invoke design-consultation
|
- Design system, brand → invoke design-consultation
|
||||||
- Visual audit, design polish → invoke design-review
|
- Visual audit, design polish → invoke design-review
|
||||||
- Architecture review → invoke plan-eng-review
|
- Architecture review → invoke plan-eng-review
|
||||||
|
- Save progress, checkpoint, resume → invoke checkpoint
|
||||||
|
- Code quality, health check → invoke health
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
Then commit the change: \`git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"\`
|
Then commit the change: \`git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"\`
|
||||||
@@ -443,6 +447,8 @@ Run this bash:
|
|||||||
_TEL_END=$(date +%s)
|
_TEL_END=$(date +%s)
|
||||||
_TEL_DUR=$(( _TEL_END - _TEL_START ))
|
_TEL_DUR=$(( _TEL_END - _TEL_START ))
|
||||||
rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
|
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 + remote telemetry (both gated by _TEL setting)
|
# Local + remote telemetry (both gated by _TEL setting)
|
||||||
if [ "$_TEL" != "off" ]; then
|
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
|
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
|
||||||
@@ -570,16 +576,65 @@ Avoid filler, throat-clearing, generic optimism, founder cosplay, and unsupporte
|
|||||||
**Final test:** does this sound like a real cross-functional builder who wants to help someone make something people want, ship it, and make it actually work?`;
|
**Final test:** does this sound like a real cross-functional builder who wants to help someone make something people want, ship it, and make it actually work?`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateContextRecovery(ctx: TemplateContext): string {
|
||||||
|
const binDir = ctx.host === 'codex' ? '$GSTACK_BIN' : ctx.paths.binDir;
|
||||||
|
|
||||||
|
return `## Context Recovery
|
||||||
|
|
||||||
|
After compaction or at session start, check for recent project artifacts.
|
||||||
|
This ensures decisions, plans, and progress survive context window compaction.
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
eval "$(${binDir}/gstack-slug 2>/dev/null)"
|
||||||
|
_PROJ="\${GSTACK_HOME:-$HOME/.gstack}/projects/\${SLUG:-unknown}"
|
||||||
|
if [ -d "$_PROJ" ]; then
|
||||||
|
echo "--- RECENT ARTIFACTS ---"
|
||||||
|
# Last 3 artifacts across ceo-plans/ and checkpoints/
|
||||||
|
find "$_PROJ/ceo-plans" "$_PROJ/checkpoints" -type f -name "*.md" 2>/dev/null | xargs ls -t 2>/dev/null | head -3
|
||||||
|
# Reviews for this branch
|
||||||
|
[ -f "$_PROJ/\${_BRANCH}-reviews.jsonl" ] && echo "REVIEWS: $(wc -l < "$_PROJ/\${_BRANCH}-reviews.jsonl" | tr -d ' ') entries"
|
||||||
|
# Timeline summary (last 5 events)
|
||||||
|
[ -f "$_PROJ/timeline.jsonl" ] && tail -5 "$_PROJ/timeline.jsonl"
|
||||||
|
# Cross-session injection
|
||||||
|
if [ -f "$_PROJ/timeline.jsonl" ]; then
|
||||||
|
_LAST=$(grep "\\"branch\\":\\"\${_BRANCH}\\"" "$_PROJ/timeline.jsonl" 2>/dev/null | grep '"event":"completed"' | tail -1)
|
||||||
|
[ -n "$_LAST" ] && echo "LAST_SESSION: $_LAST"
|
||||||
|
# Predictive skill suggestion: check last 3 completed skills for patterns
|
||||||
|
_RECENT_SKILLS=$(grep "\\"branch\\":\\"\${_BRANCH}\\"" "$_PROJ/timeline.jsonl" 2>/dev/null | grep '"event":"completed"' | tail -3 | grep -o '"skill":"[^"]*"' | sed 's/"skill":"//;s/"//' | tr '\\n' ',')
|
||||||
|
[ -n "$_RECENT_SKILLS" ] && echo "RECENT_PATTERN: $_RECENT_SKILLS"
|
||||||
|
fi
|
||||||
|
_LATEST_CP=$(find "$_PROJ/checkpoints" -name "*.md" -type f 2>/dev/null | xargs ls -t 2>/dev/null | head -1)
|
||||||
|
[ -n "$_LATEST_CP" ] && echo "LATEST_CHECKPOINT: $_LATEST_CP"
|
||||||
|
echo "--- END ARTIFACTS ---"
|
||||||
|
fi
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
If artifacts are listed, read the most recent one to recover context.
|
||||||
|
|
||||||
|
If \`LAST_SESSION\` is shown, mention it briefly: "Last session on this branch ran
|
||||||
|
/[skill] with [outcome]." If \`LATEST_CHECKPOINT\` exists, read it for full context
|
||||||
|
on where work left off.
|
||||||
|
|
||||||
|
If \`RECENT_PATTERN\` is shown, look at the skill sequence. If a pattern repeats
|
||||||
|
(e.g., review,ship,review), suggest: "Based on your recent pattern, you probably
|
||||||
|
want /[next skill]."
|
||||||
|
|
||||||
|
**Welcome back message:** If any of LAST_SESSION, LATEST_CHECKPOINT, or RECENT ARTIFACTS
|
||||||
|
are shown, synthesize a one-paragraph welcome briefing before proceeding:
|
||||||
|
"Welcome back to {branch}. Last session: /{skill} ({outcome}). [Checkpoint summary if
|
||||||
|
available]. [Health score if available]." Keep it to 2-3 sentences.`;
|
||||||
|
}
|
||||||
|
|
||||||
// Preamble Composition (tier → sections)
|
// Preamble Composition (tier → sections)
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
// T1: core + upgrade + lake + telemetry + voice(trimmed) + contributor + completion
|
// T1: core + upgrade + lake + telemetry + voice(trimmed) + contributor + completion
|
||||||
// T2: T1 + voice(full) + ask + completeness
|
// T2: T1 + voice(full) + ask + completeness + context-recovery
|
||||||
// T3: T2 + repo-mode + search
|
// T3: T2 + repo-mode + search
|
||||||
// T4: (same as T3 — TEST_FAILURE_TRIAGE is a separate {{}} placeholder, not preamble)
|
// T4: (same as T3 — TEST_FAILURE_TRIAGE is a separate {{}} placeholder, not preamble)
|
||||||
//
|
//
|
||||||
// Skills by tier:
|
// Skills by tier:
|
||||||
// T1: browse, setup-cookies, benchmark
|
// T1: browse, setup-cookies, benchmark
|
||||||
// T2: investigate, cso, retro, doc-release, setup-deploy, canary
|
// T2: investigate, cso, retro, doc-release, setup-deploy, canary, checkpoint, health
|
||||||
// T3: autoplan, codex, design-consult, office-hours, ceo/design/eng-review
|
// T3: autoplan, codex, design-consult, office-hours, ceo/design/eng-review
|
||||||
// T4: ship, review, qa, qa-only, design-review, land-deploy
|
// T4: ship, review, qa, qa-only, design-review, land-deploy
|
||||||
export function generatePreamble(ctx: TemplateContext): string {
|
export function generatePreamble(ctx: TemplateContext): string {
|
||||||
@@ -595,7 +650,7 @@ export function generatePreamble(ctx: TemplateContext): string {
|
|||||||
generateProactivePrompt(ctx),
|
generateProactivePrompt(ctx),
|
||||||
generateRoutingInjection(ctx),
|
generateRoutingInjection(ctx),
|
||||||
generateVoiceDirective(tier),
|
generateVoiceDirective(tier),
|
||||||
...(tier >= 2 ? [generateAskUserFormat(ctx), generateCompletenessSection()] : []),
|
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection()] : []),
|
||||||
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
||||||
generateContributorMode(),
|
generateContributorMode(),
|
||||||
generateCompletionStatus(),
|
generateCompletionStatus(),
|
||||||
|
|||||||
Reference in New Issue
Block a user