mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-07 05:56:41 +02:00
0926e4b994
Splits scripts/resolvers/preamble.ts (841 lines, 18 generator functions + composition root) into one file per generator under scripts/resolvers/preamble/. Root preamble.ts becomes a thin composition layer (~80 lines of imports + generatePreamble). Before: scripts/resolvers/preamble.ts 841 lines After: scripts/resolvers/preamble.ts 83 lines scripts/resolvers/preamble/generate-preamble-bash.ts 97 lines scripts/resolvers/preamble/generate-upgrade-check.ts 48 lines scripts/resolvers/preamble/generate-lake-intro.ts 16 lines scripts/resolvers/preamble/generate-telemetry-prompt.ts 37 lines scripts/resolvers/preamble/generate-proactive-prompt.ts 25 lines scripts/resolvers/preamble/generate-routing-injection.ts 49 lines scripts/resolvers/preamble/generate-vendoring-deprecation.ts 36 lines scripts/resolvers/preamble/generate-spawned-session-check.ts 11 lines scripts/resolvers/preamble/generate-ask-user-format.ts 16 lines scripts/resolvers/preamble/generate-completeness-section.ts 19 lines scripts/resolvers/preamble/generate-repo-mode-section.ts 12 lines scripts/resolvers/preamble/generate-test-failure-triage.ts 108 lines scripts/resolvers/preamble/generate-search-before-building.ts 14 lines scripts/resolvers/preamble/generate-completion-status.ts 161 lines scripts/resolvers/preamble/generate-voice-directive.ts 60 lines scripts/resolvers/preamble/generate-context-recovery.ts 51 lines scripts/resolvers/preamble/generate-continuous-checkpoint.ts 48 lines scripts/resolvers/preamble/generate-context-health.ts 31 lines Byte-identity verification (the real gate per Codex correction): - Before refactor: snapshotted 135 generated SKILL.md files via `find -name SKILL.md -type f | grep -v /gstack/` across all hosts. - After refactor: regenerated with `bun run gen:skill-docs --host all` and re-snapshotted. - `diff -r baseline after` returned zero differences and exit 0. The `--host all --dry-run` gate passes too. No template or host behavior changes — purely a code-organization refactor. Test fix: audit-compliance.test.ts's telemetry check previously grepped preamble.ts directly for `_TEL != "off"`. After the refactor that logic lives in preamble/generate-preamble-bash.ts. Test now concatenates all preamble submodule sources before asserting — tracks the semantic contract, not the file layout. Doing the minimum rewrite preserves the test's intent (conditional telemetry) without coupling it to file boundaries. Why now: we were in-session with full context. Codex had downgraded this from mandatory to optional, but the preamble had grown to 841 lines and was getting harder to navigate. User asked "why not?" given the context was hot. Shipping it as a clean bisectable commit while all the prior preamble.ts changes are fresh reduces rebase pain later. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
4.1 KiB
TypeScript
85 lines
4.1 KiB
TypeScript
/**
|
|
* Preamble composition root.
|
|
*
|
|
* Each generator lives in its own file under ./preamble/*.ts. This file only
|
|
* wires them together via generatePreamble(). Keep composition declarative —
|
|
* no inline logic beyond tier gating.
|
|
*
|
|
* Each skill runs independently via `claude -p` (or the host's equivalent).
|
|
* There is no shared loader. The preamble provides: update checks, session
|
|
* tracking, user preferences, repo mode detection, model overlays, and
|
|
* telemetry.
|
|
*
|
|
* Telemetry data flow:
|
|
* 1. Always: local JSONL append to ~/.gstack/analytics/ (inline, inspectable)
|
|
* 2. If _TEL != "off" AND binary exists: gstack-telemetry-log for remote reporting
|
|
*/
|
|
|
|
import type { TemplateContext } from './types';
|
|
import { generateModelOverlay } from './model-overlay';
|
|
|
|
// Core bootstrap
|
|
import { generatePreambleBash } from './preamble/generate-preamble-bash';
|
|
import { generateUpgradeCheck } from './preamble/generate-upgrade-check';
|
|
import { generateCompletionStatus } from './preamble/generate-completion-status';
|
|
|
|
// One-time onboarding prompts
|
|
import { generateLakeIntro } from './preamble/generate-lake-intro';
|
|
import { generateTelemetryPrompt } from './preamble/generate-telemetry-prompt';
|
|
import { generateProactivePrompt } from './preamble/generate-proactive-prompt';
|
|
import { generateRoutingInjection } from './preamble/generate-routing-injection';
|
|
import { generateVendoringDeprecation } from './preamble/generate-vendoring-deprecation';
|
|
import { generateSpawnedSessionCheck } from './preamble/generate-spawned-session-check';
|
|
|
|
// Behavioral / voice
|
|
import { generateVoiceDirective } from './preamble/generate-voice-directive';
|
|
|
|
// Tier 2+ context and interaction framework
|
|
import { generateContextRecovery } from './preamble/generate-context-recovery';
|
|
import { generateAskUserFormat } from './preamble/generate-ask-user-format';
|
|
import { generateCompletenessSection } from './preamble/generate-completeness-section';
|
|
import { generateContinuousCheckpoint } from './preamble/generate-continuous-checkpoint';
|
|
import { generateContextHealth } from './preamble/generate-context-health';
|
|
|
|
// Tier 3+ repo mode + search
|
|
import { generateRepoModeSection } from './preamble/generate-repo-mode-section';
|
|
import { generateSearchBeforeBuildingSection } from './preamble/generate-search-before-building';
|
|
|
|
// Standalone export used directly by the resolver registry
|
|
export { generateTestFailureTriage } from './preamble/generate-test-failure-triage';
|
|
|
|
// Preamble Composition (tier → sections)
|
|
// ─────────────────────────────────────────────
|
|
// T1: core + upgrade + lake + telemetry + voice(trimmed) + completion
|
|
// T2: T1 + voice(full) + ask + completeness + context-recovery
|
|
// T3: T2 + repo-mode + search
|
|
// T4: (same as T3 — TEST_FAILURE_TRIAGE is a separate {{}} placeholder, not preamble)
|
|
//
|
|
// Skills by tier:
|
|
// T1: browse, setup-cookies, benchmark
|
|
// T2: investigate, cso, retro, doc-release, setup-deploy, canary, checkpoint, health
|
|
// T3: autoplan, codex, design-consult, office-hours, ceo/design/eng-review
|
|
// T4: ship, review, qa, qa-only, design-review, land-deploy
|
|
export function generatePreamble(ctx: TemplateContext): string {
|
|
const tier = ctx.preambleTier ?? 4;
|
|
if (tier < 1 || tier > 4) {
|
|
throw new Error(`Invalid preamble-tier: ${tier} in ${ctx.tmplPath}. Must be 1-4.`);
|
|
}
|
|
const sections = [
|
|
generatePreambleBash(ctx),
|
|
generateUpgradeCheck(ctx),
|
|
generateLakeIntro(),
|
|
generateTelemetryPrompt(ctx),
|
|
generateProactivePrompt(ctx),
|
|
generateRoutingInjection(ctx),
|
|
generateVendoringDeprecation(ctx),
|
|
generateSpawnedSessionCheck(),
|
|
generateModelOverlay(ctx),
|
|
generateVoiceDirective(tier),
|
|
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection(), generateContinuousCheckpoint(), generateContextHealth()] : []),
|
|
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
|
generateCompletionStatus(ctx),
|
|
];
|
|
return sections.filter(s => s && s.trim().length > 0).join('\n\n');
|
|
}
|