refactor(coding-agent): narrowed over-exported internal symbols

- 28 symbols across discovery, mcp header policy, agent-hub projection and
  rendering, the agent registry, shell tokenizing and changelog comparison
  were exported but referenced only inside their own module; they are now
  module-private, shrinking the deep-import surface.
- Kept AGENT_PLUGIN_MANIFEST_SCHEMA, AGENT_PLUGIN_MCP_SCHEMA,
  parseAgentPluginManifest, clearAgentPluginRootCache and mergeMCPHeaders
  exported: each is a seam for tests that defend real parsing or header
  precedence behavior.
- Nothing reachable from an explicit exports entry or public barrel changed.
This commit is contained in:
can1357
2026-08-08 06:32:01 +02:00
parent cd4e04e8ee
commit 7cebe901b7
8 changed files with 19 additions and 26 deletions
@@ -74,13 +74,13 @@ export interface AgentPluginManifest {
* - `invalid` — the document targets Agent Plugins but violates the closed schema
* fatally; the plugin must be rejected and none of its components loaded (spec §5.2).
*/
export type AgentPluginManifestResult =
type AgentPluginManifestResult =
| { status: "none" }
| { status: "valid"; manifest: AgentPluginManifest; warnings: string[] }
| { status: "invalid"; reason: string };
/** Enforce the plugin `name` constraints from spec §5.5. */
export function isValidAgentPluginName(name: string): boolean {
function isValidAgentPluginName(name: string): boolean {
if (name.length < 1 || name.length > 64) return false;
if (!/^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/.test(name)) return false;
return !name.includes("--") && !name.includes("..");
@@ -240,14 +240,14 @@ export function parseAgentPluginManifest(raw: string): AgentPluginManifestResult
* (spec §9.2). Single non-recursive pass; replacement text is never rescanned,
* and no other placeholder or environment-variable expansion is performed.
*/
export function expandAgentPluginPlaceholders(value: string, pluginRoot: string, pluginData: string): string {
function expandAgentPluginPlaceholders(value: string, pluginRoot: string, pluginData: string): string {
return value.replace(/\$\{PLUGIN_(ROOT|DATA)\}/g, (_match, which: string) =>
which === "ROOT" ? pluginRoot : pluginData,
);
}
/** A validated `mcp.json` server entry, resolved to launch-ready values. */
export interface AgentPluginMcpServer {
interface AgentPluginMcpServer {
name: string;
transport: "stdio" | "http" | "sse";
/** Absolute path for `./`-relative commands; bare executable token otherwise. */
@@ -268,11 +268,11 @@ export interface AgentPluginMcpServer {
* - `ok` — the document is valid; individually invalid server entries are
* skipped with a warning (spec §7.2.2 rule 3).
*/
export type AgentPluginMcpResult =
type AgentPluginMcpResult =
| { status: "disabled"; reason: string }
| { status: "ok"; servers: AgentPluginMcpServer[]; warnings: string[] };
export interface AgentPluginMcpOptions {
interface AgentPluginMcpOptions {
/** Filesystem-resolved plugin root. */
pluginRoot: string;
/** Client-managed persistent data directory for this plugin (spec §9.1). */
@@ -488,7 +488,7 @@ export async function parseAgentPluginMcp(raw: string, options: AgentPluginMcpOp
* - `invalid` — the root claims Agent Plugins conformance but its manifest is
* fatally invalid; no component may be discovered or executed (spec §11.3).
*/
export type AgentPluginRootStatus =
type AgentPluginRootStatus =
| { kind: "none" }
| { kind: "standard"; manifest: AgentPluginManifest; warnings: string[]; realRoot: string }
| { kind: "invalid"; reason: string };
@@ -14,7 +14,7 @@ import * as fs from "node:fs";
import * as path from "node:path";
/** Lexical containment: `target` is `base` itself or a descendant of it. */
export function isContained(base: string, target: string): boolean {
function isContained(base: string, target: string): boolean {
const relative = path.relative(base, target);
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
}
@@ -29,10 +29,7 @@ export async function realpathIfExists(p: string): Promise<string | null> {
}
/** Outcome of resolving a fixed package path without reading it. */
export type ContainedPathResolution =
| { status: "missing" }
| { status: "outside" }
| { status: "ok"; realPath: string };
type ContainedPathResolution = { status: "missing" } | { status: "outside" } | { status: "ok"; realPath: string };
/**
* Resolve a fixed package path WITHOUT reading it: symlinks and equivalent
@@ -14,7 +14,7 @@
*/
/** Header buckets for one MCP HTTP request. */
export interface MCPHeaderSources {
interface MCPHeaderSources {
/** Client-generated HTTP/MCP/authorization headers; win case-insensitively. */
generated: Record<string, string>;
/** Configured headers from the server entry (package or user config). */
@@ -10,7 +10,7 @@ export interface AggregateMetrics extends AgentMetrics {
activeDurationAgents: number;
}
export interface AgentTreeProjection {
interface AgentTreeProjection {
rows: AgentRef[];
depthById: Map<string, number>;
parentById: Map<string, string>;
@@ -65,7 +65,7 @@ export function progressMetrics(observed: ObservableSession | undefined): AgentM
* usage embedded in completed `task` tool results, so using it for a parent
* row would double-count child rows in the aggregate.
*/
export function readSessionMetrics(session: NonNullable<AgentRef["session"]>): AgentMetrics | undefined {
function readSessionMetrics(session: NonNullable<AgentRef["session"]>): AgentMetrics | undefined {
try {
const stats = session.getSessionStats();
const messages = session.agent?.state?.messages;
@@ -16,7 +16,7 @@ export interface RosterRender {
}
/** Legacy progress snapshots may omit counters; snapshot absence remains distinct. */
export function metricNumber(value: number | undefined): number {
function metricNumber(value: number | undefined): number {
return typeof value === "number" && Number.isFinite(value) ? value : 0;
}
@@ -67,7 +67,7 @@ export function statusText(status: AgentRef["status"], text: string): string {
}
/** Model id + thinking level (`sonnet-4-6 ◒ high`), level colored per theme. */
export function formatModelBadge(modelId: string, level: ThinkingLevel | undefined): string {
function formatModelBadge(modelId: string, level: ThinkingLevel | undefined): string {
const model = theme.fg("muted", sanitizeDisplayText(modelId));
if (!level || level === ThinkingLevel.Off || level === ThinkingLevel.Inherit) return model;
const display = theme.thinking[level as keyof typeof theme.thinking] ?? level;
@@ -81,11 +81,7 @@ export function formatRoleBadge(role: string, settings: Settings): string {
}
/** Format a resolved selector, preserving provider identity when requested. */
export function formatResolvedModelBadge(
resolved: string,
preserveProvider = false,
fallbackLevel?: ThinkingLevel,
): string {
function formatResolvedModelBadge(resolved: string, preserveProvider = false, fallbackLevel?: ThinkingLevel): string {
const cleanResolved = sanitizeDisplayText(resolved);
// Model ids may themselves contain colons (`qwen3:14b`), so only treat the
// suffix as a thinking level when it parses as one.
@@ -15,7 +15,7 @@ import { oneLineLabel } from "../task/types";
export const MAIN_AGENT_ID = "Main";
/** Sidecar marker retained beside a child transcript after an explicit kill. */
export const AGENT_TOMBSTONE_SUFFIX = ".tombstone";
const AGENT_TOMBSTONE_SUFFIX = ".tombstone";
export function getAgentTombstonePath(sessionFile: string): string {
return `${sessionFile}${AGENT_TOMBSTONE_SUFFIX}`;
@@ -30,7 +30,7 @@ export function getAgentTombstonePath(sessionFile: string): string {
*/
export type AgentStatus = "running" | "idle" | "parked" | "aborted";
/** Provenance of a displayed duration: active runtime, transcript span, or unavailable. */
export type AgentDurationKind = "active" | "span" | "unknown";
type AgentDurationKind = "active" | "span" | "unknown";
/**
* - `main`/`sub`: the user-facing agent tree (driving agent + task subagents).
* - `advisor`: a passive review transcript persisted like a subagent for usage
@@ -87,7 +87,7 @@ export function tokenizeShellSegments(command: string): string[][] {
*
* @see extractFlatShellCommandSegments
*/
export interface FlatShellCommandSegment {
interface FlatShellCommandSegment {
/** Original segment text with quoting and escaping preserved. */
text: string;
/**
+1 -1
View File
@@ -201,7 +201,7 @@ function parseChangelogContent(content: string): ChangelogEntry[] {
* Compare changelog entries by their parsed version parts.
* Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
*/
export function compareChangelogEntries(v1: ChangelogEntry, v2: ChangelogEntry): number {
function compareChangelogEntries(v1: ChangelogEntry, v2: ChangelogEntry): number {
if (v1.major !== v2.major) return v1.major - v2.major;
if (v1.minor !== v2.minor) return v1.minor - v2.minor;
return v1.patch - v2.patch;