diff --git a/src/resources/extensions/ask-user-questions.ts b/src/resources/extensions/ask-user-questions.ts index 1a37b3cef..b14697667 100644 --- a/src/resources/extensions/ask-user-questions.ts +++ b/src/resources/extensions/ask-user-questions.ts @@ -18,7 +18,7 @@ import { type Question, type QuestionOption, type RoundResult, -} from "./shared/interview-ui.js"; +} from "./shared/mod.js"; // ─── Types ──────────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/bg-shell/utilities.ts b/src/resources/extensions/bg-shell/utilities.ts index 87249666a..9b17c130f 100644 --- a/src/resources/extensions/bg-shell/utilities.ts +++ b/src/resources/extensions/bg-shell/utilities.ts @@ -34,7 +34,7 @@ export function restoreWindowsVTInput(): void { // ── Time Formatting ──────────────────────────────────────────────────────── -import { formatDuration } from "../shared/format-utils.js"; +import { formatDuration } from "../shared/mod.js"; export const formatUptime = formatDuration; diff --git a/src/resources/extensions/get-secrets-from-user.ts b/src/resources/extensions/get-secrets-from-user.ts index e889a947d..9cb13c7ce 100644 --- a/src/resources/extensions/get-secrets-from-user.ts +++ b/src/resources/extensions/get-secrets-from-user.ts @@ -13,7 +13,7 @@ import { resolve } from "node:path"; import type { ExtensionAPI, Theme } from "@gsd/pi-coding-agent"; import { CURSOR_MARKER, Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth, wrapTextWithAnsi } from "@gsd/pi-tui"; import { Type } from "@sinclair/typebox"; -import { makeUI, type ProgressStatus } from "./shared/ui.js"; +import { makeUI, type ProgressStatus } from "./shared/mod.js"; import { parseSecretsManifest, formatSecretsManifest } from "./gsd/files.js"; import { resolveMilestoneFile } from "./gsd/paths.js"; import type { SecretsManifestEntry } from "./gsd/types.js"; diff --git a/src/resources/extensions/gsd/auto-dashboard.ts b/src/resources/extensions/gsd/auto-dashboard.ts index b759ea6d6..81134fcfd 100644 --- a/src/resources/extensions/gsd/auto-dashboard.ts +++ b/src/resources/extensions/gsd/auto-dashboard.ts @@ -18,7 +18,7 @@ import { import { parseRoadmap, parsePlan } from "./files.js"; import { readFileSync, existsSync } from "node:fs"; import { truncateToWidth, visibleWidth } from "@gsd/pi-tui"; -import { makeUI, GLYPH, INDENT } from "../shared/ui.js"; +import { makeUI, GLYPH, INDENT } from "../shared/mod.js"; // ─── Dashboard Data ─────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/auto.ts b/src/resources/extensions/gsd/auto.ts index 5dd5bd4b7..c830badd9 100644 --- a/src/resources/extensions/gsd/auto.ts +++ b/src/resources/extensions/gsd/auto.ts @@ -132,7 +132,7 @@ import { } from "./auto-worktree.js"; import { pruneQueueOrder } from "./queue-order.js"; import { consumeSignal } from "./session-status-io.js"; -import { showNextAction } from "../shared/next-action-ui.js"; +import { showNextAction } from "../shared/mod.js"; import { debugLog, debugTime, debugCount, debugPeak, enableDebug, isDebugEnabled, writeDebugSummary, getDebugLogPath } from "./debug-logger.js"; import { resolveExpectedArtifactPath, diff --git a/src/resources/extensions/gsd/commands.ts b/src/resources/extensions/gsd/commands.ts index 5884364b3..6ebd77367 100644 --- a/src/resources/extensions/gsd/commands.ts +++ b/src/resources/extensions/gsd/commands.ts @@ -37,7 +37,7 @@ import { } from "./doctor.js"; import { loadPrompt } from "./prompt-loader.js"; -import { handleRemote } from "../remote-questions/remote-command.js"; +import { handleRemote } from "../remote-questions/mod.js"; import { handleQuick } from "./quick.js"; import { handleHistory } from "./history.js"; import { handleUndo } from "./undo.js"; diff --git a/src/resources/extensions/gsd/dashboard-overlay.ts b/src/resources/extensions/gsd/dashboard-overlay.ts index 7ad348676..7402c313e 100644 --- a/src/resources/extensions/gsd/dashboard-overlay.ts +++ b/src/resources/extensions/gsd/dashboard-overlay.ts @@ -20,8 +20,7 @@ import { import { loadEffectiveGSDPreferences } from "./preferences.js"; import { getActiveWorktreeName } from "./worktree-command.js"; import { getWorkerBatches, hasActiveWorkers, type WorkerEntry } from "../subagent/worker-registry.js"; -import { formatDuration, padRight, joinColumns, centerLine, fitColumns } from "../shared/format-utils.js"; -import { STATUS_GLYPH, STATUS_COLOR } from "../shared/ui.js"; +import { formatDuration, padRight, joinColumns, centerLine, fitColumns, STATUS_GLYPH, STATUS_COLOR } from "../shared/mod.js"; import { estimateTimeRemaining } from "./auto-dashboard.js"; function unitLabel(type: string): string { diff --git a/src/resources/extensions/gsd/export.ts b/src/resources/extensions/gsd/export.ts index 5f28998cb..b87f25825 100644 --- a/src/resources/extensions/gsd/export.ts +++ b/src/resources/extensions/gsd/export.ts @@ -10,7 +10,7 @@ import { } from "./metrics.js"; import type { UnitMetrics } from "./metrics.js"; import { gsdRoot } from "./paths.js"; -import { formatDuration } from "../shared/format-utils.js"; +import { formatDuration } from "../shared/mod.js"; /** * Write an export file directly, without requiring an ExtensionCommandContext. diff --git a/src/resources/extensions/gsd/forensics.ts b/src/resources/extensions/gsd/forensics.ts index c3bd714d2..2bf83ebff 100644 --- a/src/resources/extensions/gsd/forensics.ts +++ b/src/resources/extensions/gsd/forensics.ts @@ -27,7 +27,7 @@ import { deriveState } from "./state.js"; import { isAutoActive } from "./auto.js"; import { loadPrompt } from "./prompt-loader.js"; import { gsdRoot } from "./paths.js"; -import { formatDuration } from "../shared/format-utils.js"; +import { formatDuration } from "../shared/mod.js"; import { getAutoWorktreePath } from "./auto-worktree.js"; // ─── Types ──────────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/guided-flow.ts b/src/resources/extensions/gsd/guided-flow.ts index 8255c0d4c..2e5cd261f 100644 --- a/src/resources/extensions/gsd/guided-flow.ts +++ b/src/resources/extensions/gsd/guided-flow.ts @@ -7,7 +7,7 @@ */ import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@gsd/pi-coding-agent"; -import { showNextAction } from "../shared/next-action-ui.js"; +import { showNextAction } from "../shared/mod.js"; import { loadFile, parseRoadmap } from "./files.js"; import { loadPrompt, inlineTemplate } from "./prompt-loader.js"; import { deriveState } from "./state.js"; @@ -29,7 +29,7 @@ import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitig import { loadEffectiveGSDPreferences } from "./preferences.js"; import { detectProjectState } from "./detection.js"; import { showProjectInit, offerMigration } from "./init-wizard.js"; -import { showConfirm } from "../shared/confirm-ui.js"; +import { showConfirm } from "../shared/mod.js"; import { loadQueueOrder, sortByQueueOrder, saveQueueOrder } from "./queue-order.js"; import { debugLog } from "./debug-logger.js"; diff --git a/src/resources/extensions/gsd/index.ts b/src/resources/extensions/gsd/index.ts index 454211125..f1af43a20 100644 --- a/src/resources/extensions/gsd/index.ts +++ b/src/resources/extensions/gsd/index.ts @@ -57,10 +57,10 @@ import { Key } from "@gsd/pi-tui"; import { join } from "node:path"; import { existsSync, readFileSync } from "node:fs"; import { homedir } from "node:os"; -import { shortcutDesc } from "../shared/terminal.js"; +import { shortcutDesc } from "../shared/mod.js"; import { Text } from "@gsd/pi-tui"; import { pauseAutoForProviderError, classifyProviderError } from "./provider-error-pause.js"; -import { toPosixPath } from "../shared/path-display.js"; +import { toPosixPath } from "../shared/mod.js"; import { isParallelActive, shutdownParallel } from "./parallel-orchestrator.js"; import { DEFAULT_BASH_TIMEOUT_SECS } from "./constants.js"; diff --git a/src/resources/extensions/gsd/init-wizard.ts b/src/resources/extensions/gsd/init-wizard.ts index d6e962130..f559b8dee 100644 --- a/src/resources/extensions/gsd/init-wizard.ts +++ b/src/resources/extensions/gsd/init-wizard.ts @@ -9,7 +9,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent"; import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs"; import { join } from "node:path"; -import { showNextAction } from "../shared/next-action-ui.js"; +import { showNextAction } from "../shared/mod.js"; import { nativeIsRepo, nativeInit, nativeAddPaths, nativeCommit } from "./native-git-bridge.js"; import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js"; import { gsdRoot } from "./paths.js"; diff --git a/src/resources/extensions/gsd/metrics.ts b/src/resources/extensions/gsd/metrics.ts index 09ff18b85..2965fd8b6 100644 --- a/src/resources/extensions/gsd/metrics.ts +++ b/src/resources/extensions/gsd/metrics.ts @@ -20,7 +20,7 @@ import { gsdRoot } from "./paths.js"; import { getAndClearSkills } from "./skill-telemetry.js"; // Re-export from shared — canonical implementation lives in format-utils. -export { formatTokenCount } from "../shared/format-utils.js"; +export { formatTokenCount } from "../shared/mod.js"; // ─── Types ──────────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/migrate/command.ts b/src/resources/extensions/gsd/migrate/command.ts index 60bbe1285..a13739535 100644 --- a/src/resources/extensions/gsd/migrate/command.ts +++ b/src/resources/extensions/gsd/migrate/command.ts @@ -13,7 +13,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent import { existsSync, readFileSync } from "node:fs"; import { resolve, join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; -import { showNextAction } from "../../shared/next-action-ui.js"; +import { showNextAction } from "../../shared/mod.js"; import { validatePlanningDirectory, parsePlanningDirectory, diff --git a/src/resources/extensions/gsd/migrate/parsers.ts b/src/resources/extensions/gsd/migrate/parsers.ts index 708f72a8f..4241b0079 100644 --- a/src/resources/extensions/gsd/migrate/parsers.ts +++ b/src/resources/extensions/gsd/migrate/parsers.ts @@ -3,7 +3,7 @@ // Zero Pi dependencies — uses only exported helpers from files.ts. import { splitFrontmatter, parseFrontmatterMap, extractBoldField } from '../files.js'; -import { normalizeStringArray } from '../../shared/format-utils.js'; +import { normalizeStringArray } from '../../shared/mod.js'; import type { PlanningRoadmap, diff --git a/src/resources/extensions/gsd/preferences.ts b/src/resources/extensions/gsd/preferences.ts index 7a9c911d2..d2bf0a72f 100644 --- a/src/resources/extensions/gsd/preferences.ts +++ b/src/resources/extensions/gsd/preferences.ts @@ -8,7 +8,7 @@ import type { PostUnitHookConfig, PreDispatchHookConfig, BudgetEnforcementMode, import type { DynamicRoutingConfig } from "./model-router.js"; import { defaultRoutingConfig } from "./model-router.js"; import { VALID_BRANCH_NAME } from "./git-service.js"; -import { normalizeStringArray } from "../shared/format-utils.js"; +import { normalizeStringArray } from "../shared/mod.js"; const GLOBAL_PREFERENCES_PATH = join(homedir(), ".gsd", "preferences.md"); const LEGACY_GLOBAL_PREFERENCES_PATH = join(homedir(), ".pi", "agent", "gsd-preferences.md"); diff --git a/src/resources/extensions/gsd/queue-reorder-ui.ts b/src/resources/extensions/gsd/queue-reorder-ui.ts index 1a1d2c293..b07fefa5f 100644 --- a/src/resources/extensions/gsd/queue-reorder-ui.ts +++ b/src/resources/extensions/gsd/queue-reorder-ui.ts @@ -11,7 +11,7 @@ import type { ExtensionContext } from "@gsd/pi-coding-agent"; import { type Theme } from "@gsd/pi-coding-agent"; import { Key, matchesKey, truncateToWidth, type TUI } from "@gsd/pi-tui"; -import { makeUI, GLYPH } from "../shared/ui.js"; +import { makeUI, GLYPH } from "../shared/mod.js"; import { validateQueueOrder, type DependencyValidation } from "./queue-order.js"; export interface ReorderItem { diff --git a/src/resources/extensions/gsd/tests/remote-status.test.ts b/src/resources/extensions/gsd/tests/remote-status.test.ts index 507c9cf35..2f767035a 100644 --- a/src/resources/extensions/gsd/tests/remote-status.test.ts +++ b/src/resources/extensions/gsd/tests/remote-status.test.ts @@ -3,8 +3,8 @@ import assert from "node:assert/strict"; import { mkdirSync, rmSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; -import { createPromptRecord, writePromptRecord } from "../../remote-questions/store.ts"; -import { getLatestPromptSummary } from "../../remote-questions/status.ts"; +import { createPromptRecord, writePromptRecord } from "../../remote-questions/mod.js"; +import { getLatestPromptSummary } from "../../remote-questions/mod.js"; function withTempHome(fn: (tempHome: string) => void | Promise) { return async () => { diff --git a/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts b/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts index 29ac6cb73..13baf07e4 100644 --- a/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +++ b/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts @@ -230,8 +230,8 @@ assertTrue( console.log("\n=== Overlay: Shared Imports ==="); assertTrue( - overlaySrc.includes('from "../shared/format-utils.js"'), - "imports from shared format-utils", + overlaySrc.includes('from "../shared/mod.js"'), + "imports from shared barrel", ); report(); diff --git a/src/resources/extensions/gsd/triage-ui.ts b/src/resources/extensions/gsd/triage-ui.ts index e713732ec..ebf73bc26 100644 --- a/src/resources/extensions/gsd/triage-ui.ts +++ b/src/resources/extensions/gsd/triage-ui.ts @@ -10,7 +10,7 @@ */ import type { ExtensionCommandContext } from "@gsd/pi-coding-agent"; -import { showNextAction } from "../shared/next-action-ui.js"; +import { showNextAction } from "../shared/mod.js"; import type { CaptureEntry, Classification, TriageResult } from "./captures.js"; import { markCaptureResolved } from "./captures.js"; diff --git a/src/resources/extensions/gsd/visualizer-overlay.ts b/src/resources/extensions/gsd/visualizer-overlay.ts index c24c939e3..196b2f8ec 100644 --- a/src/resources/extensions/gsd/visualizer-overlay.ts +++ b/src/resources/extensions/gsd/visualizer-overlay.ts @@ -15,7 +15,7 @@ import { type ProgressFilter, } from "./visualizer-views.js"; import { writeExportFile } from "./export.js"; -import { stripAnsi } from "../shared/format-utils.js"; +import { stripAnsi } from "../shared/mod.js"; const TAB_COUNT = 10; const TAB_LABELS = [ diff --git a/src/resources/extensions/gsd/visualizer-views.ts b/src/resources/extensions/gsd/visualizer-views.ts index c2d3600b5..5c58f4a92 100644 --- a/src/resources/extensions/gsd/visualizer-views.ts +++ b/src/resources/extensions/gsd/visualizer-views.ts @@ -4,8 +4,7 @@ import type { Theme } from "@gsd/pi-coding-agent"; import { truncateToWidth, visibleWidth } from "@gsd/pi-tui"; import type { VisualizerData, VisualizerMilestone, SliceVerification, VisualizerSliceActivity, VisualizerStats, VisualizerSliceRef } from "./visualizer-data.js"; import { formatCost, formatTokenCount, classifyUnitPhase } from "./metrics.js"; -import { formatDuration, padRight, joinColumns, sparkline } from "../shared/format-utils.js"; -import { STATUS_GLYPH, STATUS_COLOR } from "../shared/ui.js"; +import { formatDuration, padRight, joinColumns, sparkline, STATUS_GLYPH, STATUS_COLOR } from "../shared/mod.js"; function formatCompletionDate(input: string): string { if (!input) return "unknown"; diff --git a/src/resources/extensions/gsd/worktree-command.ts b/src/resources/extensions/gsd/worktree-command.ts index d2fd35fb1..4e3801149 100644 --- a/src/resources/extensions/gsd/worktree-command.ts +++ b/src/resources/extensions/gsd/worktree-command.ts @@ -14,7 +14,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent import { loadPrompt } from "./prompt-loader.js"; import { autoCommitCurrentBranch, getMainBranch, resolveGitHeadPath, nudgeGitBranchCache } from "./worktree.js"; import { runWorktreePostCreateHook } from "./auto-worktree.js"; -import { showConfirm } from "../shared/confirm-ui.js"; +import { showConfirm } from "../shared/mod.js"; import { gsdRoot, milestonesDir } from "./paths.js"; import { createWorktree, diff --git a/src/resources/extensions/remote-questions/mod.ts b/src/resources/extensions/remote-questions/mod.ts new file mode 100644 index 000000000..547f18098 --- /dev/null +++ b/src/resources/extensions/remote-questions/mod.ts @@ -0,0 +1,15 @@ +// Barrel file — re-exports consumed by external modules + +export { handleRemote } from "./remote-command.js"; +export { createPromptRecord, writePromptRecord } from "./store.js"; +export { getLatestPromptSummary } from "./status.js"; +export { + parseSlackReply, + parseDiscordResponse, + formatForDiscord, + formatForSlack, + parseSlackReactionResponse, + formatForTelegram, + parseTelegramResponse, +} from "./format.js"; +export { resolveRemoteConfig, isValidChannelId } from "./config.js"; diff --git a/src/resources/extensions/shared/mod.ts b/src/resources/extensions/shared/mod.ts new file mode 100644 index 000000000..5da977543 --- /dev/null +++ b/src/resources/extensions/shared/mod.ts @@ -0,0 +1,29 @@ +// Barrel file — re-exports consumed by external modules + +export { + makeUI, + GLYPH, + INDENT, + STATUS_GLYPH, + STATUS_COLOR, +} from "./ui.js"; +export type { ProgressStatus } from "./ui.js"; + +export { + stripAnsi, + formatTokenCount, + formatDuration, + padRight, + joinColumns, + centerLine, + fitColumns, + sparkline, + normalizeStringArray, +} from "./format-utils.js"; + +export { shortcutDesc } from "./terminal.js"; +export { toPosixPath } from "./path-display.js"; +export { showInterviewRound } from "./interview-ui.js"; +export type { Question, QuestionOption, RoundResult } from "./interview-ui.js"; +export { showNextAction } from "./next-action-ui.js"; +export { showConfirm } from "./confirm-ui.js"; diff --git a/src/resources/extensions/slash-commands/create-extension.ts b/src/resources/extensions/slash-commands/create-extension.ts index cbdb81c79..86a2cff3a 100644 --- a/src/resources/extensions/slash-commands/create-extension.ts +++ b/src/resources/extensions/slash-commands/create-extension.ts @@ -1,5 +1,5 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent"; -import { showInterviewRound, type Question, type RoundResult } from "../shared/interview-ui.js"; +import { showInterviewRound, type Question, type RoundResult } from "../shared/mod.js"; export default function createExtension(pi: ExtensionAPI) { pi.registerCommand("create-extension", { diff --git a/src/resources/extensions/slash-commands/create-slash-command.ts b/src/resources/extensions/slash-commands/create-slash-command.ts index 54bcb34d3..ef76dad44 100644 --- a/src/resources/extensions/slash-commands/create-slash-command.ts +++ b/src/resources/extensions/slash-commands/create-slash-command.ts @@ -1,5 +1,5 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent"; -import { showInterviewRound, type Question, type RoundResult } from "../shared/interview-ui.js"; +import { showInterviewRound, type Question, type RoundResult } from "../shared/mod.js"; export default function createSlashCommand(pi: ExtensionAPI) { pi.registerCommand("create-slash-command", { diff --git a/src/resources/extensions/ttsr/index.ts b/src/resources/extensions/ttsr/index.ts index fd168982e..64e25dd86 100644 --- a/src/resources/extensions/ttsr/index.ts +++ b/src/resources/extensions/ttsr/index.ts @@ -85,6 +85,11 @@ function extractDeltaContext( return null; } +// Re-exports for external consumers +export { TtsrManager } from "./ttsr-manager.js"; +export type { Rule, TtsrMatchContext } from "./ttsr-manager.js"; +export { loadRules } from "./rule-loader.js"; + export default function (pi: ExtensionAPI) { let manager: TtsrManager | null = null; let pendingViolation: PendingViolation | null = null; diff --git a/src/resources/extensions/voice/index.ts b/src/resources/extensions/voice/index.ts index 69b0069f3..d3dfcc430 100644 --- a/src/resources/extensions/voice/index.ts +++ b/src/resources/extensions/voice/index.ts @@ -1,5 +1,5 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent"; -import { shortcutDesc } from "../shared/terminal.js"; +import { shortcutDesc } from "../shared/mod.js"; import type { AssistantMessage } from "@gsd/pi-ai"; import { isKeyRelease, Key, matchesKey, truncateToWidth, visibleWidth } from "@gsd/pi-tui"; import { spawn, execSync, type ChildProcess } from "node:child_process"; diff --git a/src/tests/ttsr-manager.test.ts b/src/tests/ttsr-manager.test.ts index bf9923866..736c5a7d6 100644 --- a/src/tests/ttsr-manager.test.ts +++ b/src/tests/ttsr-manager.test.ts @@ -6,7 +6,7 @@ import test from 'node:test' import assert from 'node:assert/strict' -import { TtsrManager, type Rule, type TtsrMatchContext } from '../../src/resources/extensions/ttsr/ttsr-manager.ts' +import { TtsrManager, type Rule, type TtsrMatchContext } from '../../src/resources/extensions/ttsr/index.js' // ─── Helpers ───────────────────────────────────────────────────────────────── diff --git a/src/tests/ttsr-rule-loader.test.ts b/src/tests/ttsr-rule-loader.test.ts index 0dbcee95f..8ae300c21 100644 --- a/src/tests/ttsr-rule-loader.test.ts +++ b/src/tests/ttsr-rule-loader.test.ts @@ -9,7 +9,7 @@ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs' import { join } from 'node:path' import { tmpdir } from 'node:os' -import { loadRules } from '../../src/resources/extensions/ttsr/rule-loader.ts' +import { loadRules } from '../../src/resources/extensions/ttsr/index.js' // ─── Helpers ─────────────────────────────────────────────────────────────────