zidane 6.2.7 → 6.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/{acp-B_8CI9-1.js → acp-DuEMbOoQ.js} +4 -4
  2. package/dist/{acp-B_8CI9-1.js.map → acp-DuEMbOoQ.js.map} +1 -1
  3. package/dist/acp-cli.js +7 -7
  4. package/dist/acp.d.ts +1 -1
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-DPO6GKX5.js → agent-6iGNP46b.js} +5 -5
  7. package/dist/{agent-DPO6GKX5.js.map → agent-6iGNP46b.js.map} +1 -1
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +1 -1
  10. package/dist/{anthropic-J2tBjcSQ.js → anthropic-BD-lwEKp.js} +3 -3
  11. package/dist/{anthropic-J2tBjcSQ.js.map → anthropic-BD-lwEKp.js.map} +1 -1
  12. package/dist/{auth-Cexpxjfa.js → auth-BH6G59RL.js} +8 -8
  13. package/dist/auth-BH6G59RL.js.map +1 -0
  14. package/dist/chat/pure.d.ts +3 -3
  15. package/dist/chat.d.ts +14 -44
  16. package/dist/chat.d.ts.map +1 -1
  17. package/dist/chat.js +3 -3
  18. package/dist/contexts/daytona.d.ts +1 -1
  19. package/dist/contexts/e2b.d.ts +1 -1
  20. package/dist/eval.d.ts +1 -1
  21. package/dist/eval.js +1 -1
  22. package/dist/extensions.d.ts +1 -1
  23. package/dist/extensions.js +1 -1
  24. package/dist/headless.d.ts +1 -1
  25. package/dist/headless.js +3 -3
  26. package/dist/{index-CNyYEOy0.d.ts → index-BFNt9GAs.d.ts} +59 -7
  27. package/dist/index-BFNt9GAs.d.ts.map +1 -0
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +10 -10
  30. package/dist/{login-Bp_tRj_e.js → login-B5nMPF8w.js} +3 -3
  31. package/dist/{login-Bp_tRj_e.js.map → login-B5nMPF8w.js.map} +1 -1
  32. package/dist/{mcp-CkHUripi.js → mcp-BCaN_Gyg.js} +140 -29
  33. package/dist/mcp-BCaN_Gyg.js.map +1 -0
  34. package/dist/mcp.d.ts +1 -1
  35. package/dist/mcp.js +1 -1
  36. package/dist/{messages-DEPX32kc.js → messages-BDpXLFoe.js} +2 -2
  37. package/dist/{messages-DEPX32kc.js.map → messages-BDpXLFoe.js.map} +1 -1
  38. package/dist/{openai-compat-LGAsBush.js → openai-compat-J_JZ7qsw.js} +1 -19
  39. package/dist/openai-compat-J_JZ7qsw.js.map +1 -0
  40. package/dist/output/stream-json.d.ts +1 -1
  41. package/dist/output/terminal.d.ts +1 -1
  42. package/dist/presets.d.ts +1 -1
  43. package/dist/presets.js +1 -1
  44. package/dist/providers/anthropic.d.ts +1 -1
  45. package/dist/providers/anthropic.js +1 -1
  46. package/dist/providers/arcee.d.ts +1 -1
  47. package/dist/providers/arcee.js +1 -1
  48. package/dist/providers/baseten.d.ts +1 -1
  49. package/dist/providers/baseten.js +1 -1
  50. package/dist/providers/cerebras.d.ts +1 -1
  51. package/dist/providers/cerebras.js +1 -1
  52. package/dist/providers/local.d.ts +1 -1
  53. package/dist/providers/local.js +1 -1
  54. package/dist/providers/openai-compat.d.ts +1 -1
  55. package/dist/providers/openai-compat.js +1 -1
  56. package/dist/providers/openai.d.ts +1 -1
  57. package/dist/providers/openai.js +548 -1
  58. package/dist/providers/openai.js.map +1 -0
  59. package/dist/providers/openrouter.d.ts +1 -1
  60. package/dist/providers/openrouter.js +1 -1
  61. package/dist/providers/xai.d.ts +1 -1
  62. package/dist/providers/xai.js +1 -1
  63. package/dist/{providers-BM6VuE_i.js → providers-CclOzGxc.js} +3 -3
  64. package/dist/{providers-BM6VuE_i.js.map → providers-CclOzGxc.js.map} +1 -1
  65. package/dist/providers.d.ts +1 -1
  66. package/dist/providers.js +5 -5
  67. package/dist/restate.d.ts +1 -1
  68. package/dist/session/sqlite.d.ts +1 -1
  69. package/dist/{session-Dc1v4Otm.js → session-CIXE-Bzp.js} +2 -2
  70. package/dist/{session-Dc1v4Otm.js.map → session-CIXE-Bzp.js.map} +1 -1
  71. package/dist/session.d.ts +1 -1
  72. package/dist/session.js +2 -2
  73. package/dist/{skills-BlmY7QhV.js → skills-CDpejYOf.js} +168 -44
  74. package/dist/skills-CDpejYOf.js.map +1 -0
  75. package/dist/skills.d.ts +2 -2
  76. package/dist/skills.js +1 -1
  77. package/dist/{tool-formatters-B7oWiy5m.d.ts → tool-formatters-B_zQsYfa.d.ts} +2 -2
  78. package/dist/{tool-formatters-B7oWiy5m.d.ts.map → tool-formatters-B_zQsYfa.d.ts.map} +1 -1
  79. package/dist/tools/fetch-url.d.ts +1 -1
  80. package/dist/tools/web-search.d.ts +1 -1
  81. package/dist/tools.d.ts +1 -1
  82. package/dist/tools.js +1 -1
  83. package/dist/{transcript-anchors-DtOaKu4d.js → transcript-anchors-BUigMBQt.js} +227 -11
  84. package/dist/transcript-anchors-BUigMBQt.js.map +1 -0
  85. package/dist/{transcript-anchors-BUZ915pM.d.ts → transcript-anchors-C1Zqb8uS.d.ts} +49 -3
  86. package/dist/transcript-anchors-C1Zqb8uS.d.ts.map +1 -0
  87. package/dist/tui.d.ts +12 -7
  88. package/dist/tui.d.ts.map +1 -1
  89. package/dist/tui.js +391 -70
  90. package/dist/tui.js.map +1 -1
  91. package/dist/{turn-operations-2Ou_DkbC.d.ts → turn-operations-DVA52KMG.d.ts} +3 -3
  92. package/dist/{turn-operations-2Ou_DkbC.d.ts.map → turn-operations-DVA52KMG.d.ts.map} +1 -1
  93. package/dist/types.d.ts +1 -1
  94. package/dist/{xai-BYAyEPiJ.js → xai-D-wALLuZ.js} +2 -2
  95. package/dist/{xai-BYAyEPiJ.js.map → xai-D-wALLuZ.js.map} +1 -1
  96. package/package.json +2 -2
  97. package/dist/auth-Cexpxjfa.js.map +0 -1
  98. package/dist/index-CNyYEOy0.d.ts.map +0 -1
  99. package/dist/mcp-CkHUripi.js.map +0 -1
  100. package/dist/openai-BcmYm0t4.js +0 -579
  101. package/dist/openai-BcmYm0t4.js.map +0 -1
  102. package/dist/openai-compat-LGAsBush.js.map +0 -1
  103. package/dist/skills-BlmY7QhV.js.map +0 -1
  104. package/dist/transcript-anchors-BUZ915pM.d.ts.map +0 -1
  105. package/dist/transcript-anchors-DtOaKu4d.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as AgentProviderError, c as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, d as errorMessage, f as matchesContextExceeded, i as AgentContextExceededError, l as ClassifiedError, n as AgentAbortedError, o as AgentToolNotAllowedError, p as toTypedError, r as AgentBudgetExceededError, s as AgentToolPairingError, t as OperationTimeoutError, u as ClassifiedErrorKind } from "./timeout-8vSIRjzl.js";
2
- import { $ as maybePersistToolResult, $a as resolveExtensionConfig, $c as CompletionReference, $f as hydrateReadStateFromSession, $i as ExtensionInstallError, $l as InferSchemaOutput, $n as waitTask, $o as ExtensionHudWriter, $r as BASE_INSTRUCTIONS, $s as SkillInstallSpec, $t as TrajectoryStep, A as MetricsHookSet, Aa as ExtensionConfigActionItem, Ad as ContextCategoryId, Af as ToolOutcome, Ai as defaultRepeatGuardTracked, Ao as ExtensionSessionStateSurface, Ap as ORPHANED_TOOL_RESULT_MARKER, Ar as RunSummaryCollectorOptions, As as matchModelEntries, At as EvalRunMetricAggregate, B as loginMcpServer, Ba as ExtensionConfigNumberItem, Bc as InlineAutocompleteContext, Bf as TurnFinishReason, Bi as McpToolWrap, Bm as LocalParams, Bo as ExtensionToolRendererRegistration, Bp as ensureEndsWithUserMessage, Br as PostCompactRestoreOptions, Bs as validateResourcePathReal, Bt as EvalVariantSummary, C as normalizeProviders, Ca as scanExtensionDirectories, Cd as effectiveContextWindow, Cf as SessionMessage, Ci as CacheDimensionName, Cl as AnswerValue, Cn as llmJudge, Co as ExtensionPaths, Cp as RemoteStoreOptions, Cr as glob, Cs as SubagentOverride, Ct as EvalArtifacts, D as InstrumentOptions, Da as ExtensionPromptDelivery, Dd as ContextBreakdownContributor, Df as ThinkingLevel, Di as installCacheBreakLogger, Dn as runEvalCase, Do as ExtensionRegistry, Dp as FileMapStoreOptions, Dr as RunSummaryBudget, Ds as SpawnModelEntry, Dt as EvalDefinitionContext, E as Histogram, Ea as ExtensionPromptBridge, Ec as resultToString, Ed as ContextBreakdownContributionContext, Ef as StreamHookContext, Ei as fnv1a32, Em as classifyOpenAICompatError, En as relativeArtifactPath, Eo as ExtensionProviderMiddleware, Ep as FileMapAdapter, Er as RunSummaryBlock, Es as isSpawnTool, Et as EvalDefinition, F as OAuthCallbackOptions, Fa as ExtensionConfigChangeBehavior, Fd as ContextMcpGroup, Ff as ToolResultImageContent, Fi as AgentHookMap, Fl as PlanResponse, Fm as OpenAIParams, Fn as HeadlessResult, Fo as ExtensionToolCatalogTransform, Fp as TOOL_USE_INTERRUPTED_MARKER, Fr as createRunSummaryCollector, Fs as SkillValidationResult, Ft as EvalRunUsage, G as createMemoryMcpCredentialStore, Ga as ExtensionConfigValueItem, Gc as resolveInlineSuggestion, Gf as ToolContext, Gi as buildExtensionRegistry, Gm as cerebras, Gn as headlessEventToJsonl, Go as ExtensionTuiSurface, Gp as remintDuplicateToolCallIds, Gr as selectRecentFiles, Gs as interpolateShellCommands, Gt as MetricDirection, H as McpCredentialStore, Ha as ExtensionConfigStringItem, Hc as InlineGhost, Hd as AgentStats, Hf as toolOutputBudgetByteLength, Hi as BuildExtensionRegistryOptions, Ho as ExtensionToolResultPatch, Hp as filterUnresolvedToolUses, Hr as buildPostCompactAttachments, Hs as validateSkillName, Ht as EvalWorkspaceOptions, I as OAuthCallbackResult, Ia as ExtensionConfigEnumItem, Id as ContextSnapshot, If as ToolResultImageRefContent, Ii as AgentHooks, In as HeadlessStatus, Io as ExtensionToolPolicy, Ip as ToWireMessagesOptions, Ir as BYTES_PER_TOKEN, Is as isToolAllowedByUnion, It as EvalScore, J as PERSISTENCE_PREVIEW_BYTES, Ja as WireExtensionConfigSchema, Jd as CompactHookContext, Jf as HydrateReadStateOptions, Ji as filterExtensionRegistry, Jn as runHeadless, Jo as TuiContributions, Jp as toWireMessages, Jr as CompactResult, Js as SkillInstallCandidate, Jt as MetricSpecMap, K as hasAuthorizationHeader, Ka as StoredExtensionConfigItem, Kd as CompactEndHookContext, Kf as ToolDef, Ki as composeExtensionPreset, Km as BasetenParams, Ko as GuiContributions, Kp as toAnthropic, Kr as CompactEndEvent, Ks as stripShellInterpolations, Kt as MetricEmitter, L as startOAuthCallback, La as ExtensionConfigItem, Ld as ContextUsageSplit, Lf as ToolResultMetadata, Li as AgentOptions, Ll as Question, Ln as HeadlessUsage, Lo as ExtensionToolRenderProps, Lp as TurnInterruptionState, Lr as estimateTokens, Ls as matchesAllowedTool, Lt as EvalScorer, M as UpDownCounter, Ma as ExtensionConfigActionStatus, Md as ContextExtensionRow, Mf as ToolResultContent, Mi as stableStringify, Mn as HeadlessEvent, Mo as ExtensionSource, Mp as PairingRepairMode, Mr as RunSummaryRepeatGuard, Ms as writeSkillToDisk, Mt as EvalRunReporterOptions, N as createMetricsHooks, Na as ExtensionConfigBooleanItem, Nd as ContextExtensionSection, Nf as ToolResultDocumentContent, Ni as localReliabilityBehavior, Nl as PlanPayload, Nn as HeadlessOptions, No as ExtensionStorageScope, Np as RemintResult, Nr as RunSummaryTokens, Ns as writeSkillsToDisk, Nt as EvalRunSummary, O as Meter, Oa as createExtensionPromptBridge, Od as ContextBreakdownOptions, Oi as snapshotCacheDimensions, On as statusCompleted, Oo as ExtensionRunTransform, Op as createFileMapStore, Or as RunSummaryByModel, Os as createModelSearchTool, Ot as EvalMetric, P as OAuthCallbackHandle, Pa as ExtensionConfigCategory, Pd as ContextItem, Pf as ToolResultDocumentRefContent, Pi as Agent, Po as ExtensionStorageSurface, Pp as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, Pr as RunSummaryValidation, Ps as SkillValidationIssue, Pt as EvalRunSummaryCase, Q as cleanupPersistedSession, Qa as isValidExtensionConfigValue, Qc as CompletionProvider, Qd as DedupToolConfig, Qf as hashContent, Qi as ExtensionInstallCandidate, Qm as AnthropicParams, Qo as ExtensionHudStatus, Qp as StreamOptions, Qr as CompactPromptTooLongError, Qs as SkillInstallResult, Qt as Trajectory, R as LoginMcpServerOptions, Ra as ExtensionConfigItemBase, Rf as ToolResultTextContent, Ri as McpConnector, Rl as QuestionChoice, Rm as openai, Ro as ExtensionToolRenderer, Rp as autoDetectAndConvert, Rr as utf8ByteLength, Rs as parseAllowedToolPattern, Rt as EvalScorerContext, S as createMutationValidationHooks, Sa as parseExtensionScanPathEnv, Sc as connectMcpServers, Sd as OUTPUT_RESERVE_TOKENS, Sf as SessionHookContext, Si as CacheDimensionDiff, Sn as functionalityMetric, So as ExtensionOrderedContribution, Sr as grep, Ss as SubagentDef, St as EvalAgentStats, T as Counter, Ta as discoverAndBuildExtensionRegistry, Tc as normalizeMcpServers, Td as ContextBreakdown, Tf as SpawnHookContext, Ti as diffCacheDimensions, Tn as registerEvalTests, To as ExtensionPromptTransform, Tp as createMemoryStore, Tr as RunSummary, Ts as createSpawnTool, Tt as EvalCaseResult, U as McpOAuthProvider, Ua as ExtensionConfigSurface, Uc as createPathAutocompleteProvider, Ud as AutoCompact, Uf as toolOutputByteLength, Ui as ExtensionCatalogPartition, Ul as SelectQuestion, Uo as ExtensionToolResultTransform, Up as fromAnthropic, Ur as selectFilesFromReadState, Us as resolveSkills, Ut as EvalWorkspaceSnapshot, V as McpCredentialEntry, Va as ExtensionConfigScope, Vc as InlineAutocompleteProvider, Vd as AgentRunOptions, Vf as TurnUsage, Vi as createAgent, Vm as local, Vo as ExtensionToolResultMetadataRegistration, Vp as ensureToolResultPairing, Vr as RecentFile, Vs as validateSkillForWrite, Vt as EvalWorkspaceFile, W as McpOAuthProviderOptions, Wa as ExtensionConfigValue, Wc as patchInlineGhost, Wd as AutoCompactConfig, Wf as toolResultToText, Wi as buildExtensionPreset, Wl as TextQuestion, Wm as CerebrasParams, Wo as ExtensionToolVerdict, Wp as fromOpenAI, Wr as selectFilesFromSession, Ws as InterpolateShellCommandsOptions, Wt as LlmJudgeOptions, X as PersistOutcome, Xa as coerceExtensionConfigInput, Xc as CompletionContext, Xf as ReadStateMap, Xi as partitionExtensionCatalog, Xm as arcee, Xo as ExtensionHud, Xp as ProviderCapabilities, Xr as compactConversation, Xs as SkillInstallErrorCode, Xt as RegisterEvalTestsOptions, Y as PersistInput, Ya as clampExtensionConfigNumber, Yd as CompactStartHookContext, Yf as ReadStateEntry, Yi as mergeContributions, Ym as ArceeParams, Yn as transcriptToOpenAIMessages, Yo as ExtensionBannerOptions, Yp as Provider, Yr as CompactStartEvent, Ys as SkillInstallError, Yt as MetricStats, Z as buildPersistedStub, Za as isValidExtensionConfigItem, Zc as CompletionItem, Zd as DedupHasher, Zf as getReadState, Zi as ExtensionFetchResult, Zo as ExtensionHudState, Zp as StreamCallbacks, Zr as CompactInvalidInputError, Zs as SkillInstallOptions, Zt as ReusableExecutionContext, _ as MutationValidationFailure, _a as ExtensionScanEntry, _c as SkillActivationStateOptions, _f as ResolveContentRefBlock, _i as summaryToTurn, _l as CommandStepContext, _m as OpenAICompatAuthHeader, _n as fileExistsOneOf, _o as ExtensionKeybindingDispatchContext, _s as SpawnTaskInput, _t as EvalAgent, a as basicTools, aa as ExtensionInstallSource, ac as discoverSkills, af as OAuthRefreshHookContext, ai as buildCompactPrompt, al as resolveCompletionSubmit, am as xai, an as clearRegisteredEvals, ao as ExtensionBehaviorTransform, ap as SkillDiagnostic, as as ExtensionHostRuntimeBridge, at as TOOL_USE_SKIPPED_MESSAGE, au as ConsoleSinkOptions, b as MutationValidationResult, ba as inlineLoadedExtension, bc as McpConnection, bd as AutoCompactDecision, bf as SessionContentBlock, bi as generateStructuredData, bl as executeCommand, bn as formatEvalRunSummary, bo as ExtensionModal, bp as loadSession, br as InteractionToolOptions, bs as SpawnToolOptions, bt as EvalAgentRunResult, c as StartSpan, ca as fetchExtensionSource, cf as PromptAudioPart, ci as buildTailCompactPrompt, cl as CommandArgSuggestion, cm as SchemaSanitizeResult, cn as createEvalRunReporter, co as ExtensionContextTransform, cp as SkillsConfig, cr as createSkillsUseTool, cs as ExtensionRuntimeSurface, ct as ExtensionEditMarker, cu as LogSink, d as TracingHooksOptions, da as parseExtensionInstallSource, dc as IMPLICITLY_ALLOWED_SKILL_TOOLS, df as PromptPart, di as CompactScope, dl as CommandInteraction, dm as OpenRouterParams, dn as defineMetrics, do as ExtensionCustomRendererEntry, dp as SessionData, dr as SkillsReadToolOptions, ds as ExtensionWorkspacePair, dt as extensionDirForCwd, du as LoggingHooksOptions, ea as ExtensionInstallErrorCode, ec as installSkillFromSpec, ef as McpServerConfig, eh as anthropic, ei as CompactDirection, el as CompletionSubmitContext, em as ToolCall, en as TrajectoryStepKind, eo as resolveExtensionConfigValue, ep as hydrateReadStateFromSessionAsync, er as ValidationResult, es as ExtensionNotification, et as resolvePersistDir, eu as SchemaInput, f as createTracingHooks, fa as readExtensionInstallProvenance, fc as installAllowedToolsGate, ff as PromptTextPart, fi as CompactionSlice, fl as CommandInvocation, fn as efficiencyMetricValues, fo as ExtensionDefinition, fr as createSkillsReadTool, fs as ExtensionWorkspaceSurface, ft as extensionScaffold, g as MutationValidationBatch, ga as ENTRY_CANDIDATES, gc as SkillActivationState, gf as ResolveContentRef, gi as stripImagesFromTurns, gl as CommandStep, gn as fileExists, go as ExtensionKeybinding, gs as ExtensionSubagentDef, gt as EFFICIENCY_METRICS, gu as jsonSink, h as statsByModel, ha as registerExtensionHostModules, hc as DeactivationReason, hf as RepeatGuardToolMatcher, hi as sliceForCompaction, hl as CommandSpawnTask, hn as fileContentQuality, ho as ExtensionGuiSurface, hp as createSession, hr as createShellTool, hs as ChildAgent, ht as CreateEvalAgentOptions, hu as createLoggingHooks, i as _default, ia as ExtensionInstallScope, ic as SourcedScanPath, if as ModelTargetSpec, ii as TRAILER, im as XaiParams, in as buildTrajectory, io as ExtensionApiVersion, ip as SkillConfig, is as createExtensionHud, it as TOOL_USE_CANCELLED_MESSAGE, iu as zodToJsonSchema, j as MetricsHooksOptions, ja as ExtensionConfigActionResult, jd as ContextExactCounts, jf as ToolResultAudioContent, ji as normalizeShellCommand, jm as openaiCompat, jn as HeadlessErrorInfo, jo as ExtensionSkillPolicy, jp as PairingRepair, jr as RunSummaryError, js as defineSkill, jt as EvalRunReporter, k as MetricAttributes, ka as defineExtension, kd as ContextCategory, kf as ToolHookContext, ki as defaultRepeatGuardNormalize, km as mapOAIFinishReason, ko as ExtensionRuntimeEnv, kp as EnsureToolResultPairingOptions, kr as RunSummaryCollector, ks as formatModelLine, kt as EvalMetricError, l as TracingConventions, la as installExtensionFromSpec, lc as parseSkillFile, lf as PromptDocumentPart, li as buildUpToCompactPrompt, ll as CommandExecution, lm as sanitizeToolSchema, ln as createReusableExecutionContext, lo as ExtensionContributions, lp as CreateSessionOptions, lr as SkillsRunScriptToolOptions, ls as ExtensionSessionSummary, lt as ZIDANE_EXTENSION_SKILL_NAME, lu as Logger, m as flattenTurns, ma as updateInstalledExtension, mc as ActiveSkill, mf as RepeatGuardConfig, mi as anchorPreviewFor, ml as CommandSpawnResult, mn as fileContains, mo as ExtensionGuiPanel, mp as SessionStore, mr as CreateShellToolOptions, ms as createWorkspaceSurface, mt as withZidaneExtensionSkill, mu as createLogger, na as ExtensionInstallProvenance, nc as parseSkillInstallSpec, ni as CompactPromptOptions, nm as ToolSpec, nn as buildEvalRunSummary, no as toWireConfigSchema, np as resolveReadStateMap, ns as ExtensionNotifyTone, nt as INTERRUPT_MESSAGE_FOR_TOOL_USE, nu as isStandardSchema, o as GEN_AI_ATTRIBUTES, oa as InstallExtensionFromSpecOptions, of as ProgressNudgeKind, oi as buildFromCompactPrompt, ol as Command, om as SchemaSanitizeOptions, on as computeEvalTagScores, oo as ExtensionCapability, op as SkillResource, os as ExtensionHostRuntimeImpl, ot as applyCompactSummaryCutoff, ou as LogLevel, p as ModelUsage, pa as removeInstalledExtension, pc as ActivationVia, pf as PromptVideoPart, pi as SummaryToTurnInput, pl as CommandOutputBlock, pm as openrouter, pn as emitEfficiencyMetrics, po as ExtensionFooterHint, pp as SessionRun, ps as createExtensionHostRuntimeBridge, pt as resolveExtensionDocsDir, pu as consoleSink, q as PERSISTED_STUB_PREFIX, qa as WireExtensionConfigItem, qd as CompactFunction, qf as ToolMap, qi as disposeExtensionRegistry, qm as baseten, qo as LoadedExtension, qp as toOpenAI, qr as CompactOptions, qt as MetricSpec, r as definePreset, ra as ExtensionInstallResult, rc as readSkillProvenance, rf as ModelTarget, ri as NO_TOOLS_PREAMBLE, rm as TurnResult, rn as buildRegisteredEvals, ro as EMPTY_EXTENSION_REGISTRY, rp as ShellInterpolationApproval, rs as ExtensionStatusOptions, rt as SHELL_CASCADE_CANCEL_MESSAGE, ru as resolveSchemaInput, s as Span, sa as InstalledExtensionTargetOptions, sf as ProgressNudgeMessage, si as buildFullCompactPrompt, sl as CommandAgentResult, sm as SchemaSanitizeProfile, sn as createEvalAgent, so as ExtensionContext, sp as SkillSource, sr as SkillsUseToolOptions, ss as ExtensionModelEntry, st as EXTENSION_EDIT_METADATA_KEY, su as LogRecord, t as Preset, ta as ExtensionInstallIo, tc as listSkillCandidates, tf as McpToolHookContext, th as applyAnthropicCacheBreakpoints, ti as CompactPromptBuilder, tm as ToolResult, tn as artifactPath, to as sanitizeExtensionConfigActionPatch, tp as readStateKey, tr as validateToolArgs, ts as ExtensionNotifyOptions, tt as resolveTasksDir, tu as StandardSchemaLike, u as TracingHookSet, ua as listExtensionCandidates, uc as buildCatalog, uf as PromptImagePart, ui as ANCHOR_PREVIEW_MAX_CHARS, ul as CommandGenerateDataOptions, um as sanitizeToolSpecs, un as defineEval, uo as ExtensionCustomRenderer, up as Session, ur as createSkillsRunScriptTool, us as ExtensionSessionsSurface, ut as buildZidaneExtensionSkill, uu as LoggingHookSet, v as MutationValidationHooksOptions, va as defaultExtensionScanPaths, vc as createSkillActivationState, vf as RetryConfig, vi as truncateHeadForPtlRetry, vl as CommandStepFn, vm as OpenAICompatHttpError, vn as finalizeEvalMetrics, vo as ExtensionManifest, vr as multiEdit, vs as SpawnTaskOutcome, vt as EvalAgentMcpServers, w as resolveModelTargets, wa as DiscoverAndBuildExtensionRegistryOptions, wc as normalizeMcpBlocks, wd as shouldAutoCompact, wf as SessionTurn, wi as CacheDimensionSnapshot, wl as ConfirmQuestion, wn as normalizeMetric, wo as ExtensionPermission, wp as createRemoteStore, wr as edit, ws as SubagentRegistry, wt as EvalCaseOptions, x as SuccessfulMutationOutcome, xa as isExtensionDefinition, xd as AutoCompactInput, xf as SessionEndStatus, xi as CacheBreakLoggerOptions, xl as parseCommandInvocation, xn as formatTrajectoryLine, xo as ExtensionModalNode, xr as createInteractionTool, xs as SpawnToolState, xt as EvalAgentRunStats, y as MutationValidationMutation, ya as discoverExtensions, yc as ConnectMcpServersOptions, yd as AUTO_COMPACT_MIN_GROWTH_FRACTION, yf as RunHookMap, yi as GenerateStructuredDataOptions, yl as commandSteps, ym as OpenAICompatParams, yn as formatEvalCaseSummary, yo as ExtensionMcpConfigTransform, ys as SpawnTool, yt as EvalAgentRunOptions, z as LoginMcpServerResult, za as ExtensionConfigModelItem, zd as AgentBehavior, zf as ToolResultVideoContent, zi as McpToolMeta, zl as QuestionPayload, zn as OpenAIChatMessage, zo as ExtensionToolRendererEntry, zp as detectTurnInterruption, zr as PostCompactAttachments, zs as validateResourcePath, zt as EvalTestRunner } from "./index-CNyYEOy0.js";
2
+ import { $ as maybePersistToolResult, $a as resolveExtensionConfig, $c as CompletionProvider, $d as DedupToolConfig, $f as hashContent, $i as ExtensionInstallError, $m as AnthropicParams, $n as waitTask, $o as ExtensionHudWriter, $p as StreamOptions, $r as BASE_INSTRUCTIONS, $s as SkillInstallResult, $t as TrajectoryStep, A as MetricsHookSet, Aa as ExtensionConfigActionItem, Ad as ContextCategory, Af as ToolHookContext, Ai as defaultRepeatGuardTracked, Am as mapOAIFinishReason, Ao as ExtensionSessionStateSurface, Ap as EnsureToolResultPairingOptions, Ar as RunSummaryCollectorOptions, As as matchModelEntries, At as EvalRunMetricAggregate, B as loginMcpServer, Ba as ExtensionConfigNumberItem, Bd as AgentBehavior, Bf as ToolResultVideoContent, Bi as McpToolWrap, Bl as QuestionPayload, Bo as ExtensionToolRendererRegistration, Bp as detectTurnInterruption, Br as PostCompactRestoreOptions, Bs as validateResourcePathReal, Bt as EvalVariantSummary, C as normalizeProviders, Ca as scanExtensionDirectories, Cc as connectMcpServers, Cd as OUTPUT_RESERVE_TOKENS, Cf as SessionHookContext, Ci as CacheDimensionName, Cn as llmJudge, Co as ExtensionPaths, Cr as glob, Cs as SubagentOverride, Ct as EvalArtifacts, D as InstrumentOptions, Da as ExtensionPromptDelivery, Dc as resultToString, Dd as ContextBreakdownContributionContext, Df as StreamHookContext, Di as installCacheBreakLogger, Dm as classifyOpenAICompatError, Dn as runEvalCase, Do as ExtensionRegistry, Dp as FileMapAdapter, Dr as RunSummaryBudget, Ds as SpawnModelEntry, Dt as EvalDefinitionContext, E as Histogram, Ea as ExtensionPromptBridge, Ec as normalizeMcpServers, Ed as ContextBreakdown, Ef as SpawnHookContext, Ei as fnv1a32, En as relativeArtifactPath, Eo as ExtensionProviderMiddleware, Ep as createMemoryStore, Er as RunSummaryBlock, Es as isSpawnTool, Et as EvalDefinition, F as OAuthCallbackOptions, Fa as ExtensionConfigChangeBehavior, Fd as ContextItem, Ff as ToolResultDocumentRefContent, Fi as AgentHookMap, Fn as HeadlessResult, Fo as ExtensionToolCatalogTransform, Fp as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, Fr as createRunSummaryCollector, Fs as SkillValidationResult, Ft as EvalRunUsage, G as createMemoryMcpCredentialStore, Ga as ExtensionConfigValueItem, Gc as patchInlineGhost, Gd as AutoCompactConfig, Gf as toolResultToText, Gi as buildExtensionRegistry, Gl as TextQuestion, Gm as CerebrasParams, Gn as headlessEventToJsonl, Go as ExtensionTuiSurface, Gp as fromOpenAI, Gr as selectRecentFiles, Gs as interpolateShellCommands, Gt as MetricDirection, H as McpCredentialStore, Ha as ExtensionConfigStringItem, Hc as InlineAutocompleteProvider, Hd as AgentRunOptions, Hf as TurnUsage, Hi as BuildExtensionRegistryOptions, Hm as local, Ho as ExtensionToolResultPatch, Hp as ensureToolResultPairing, Hr as buildPostCompactAttachments, Hs as validateSkillName, Ht as EvalWorkspaceOptions, I as OAuthCallbackResult, Ia as ExtensionConfigEnumItem, Id as ContextMcpGroup, If as ToolResultImageContent, Ii as AgentHooks, Il as PlanResponse, Im as OpenAIParams, In as HeadlessStatus, Io as ExtensionToolPolicy, Ip as TOOL_USE_INTERRUPTED_MARKER, Ir as BYTES_PER_TOKEN, Is as isToolAllowedByUnion, It as EvalScore, J as PERSISTENCE_PREVIEW_BYTES, Ja as WireExtensionConfigSchema, Jd as CompactFunction, Jf as ToolMap, Ji as filterExtensionRegistry, Jm as baseten, Jn as runHeadless, Jo as TuiContributions, Jp as toOpenAI, Jr as CompactResult, Jt as MetricSpecMap, K as hasAuthorizationHeader, Ka as StoredExtensionConfigItem, Kc as resolveInlineSuggestion, Kf as ToolContext, Ki as composeExtensionPreset, Km as cerebras, Ko as GuiContributions, Kp as remintDuplicateToolCallIds, Kr as CompactEndEvent, Ks as stripShellInterpolations, Kt as MetricEmitter, L as startOAuthCallback, La as ExtensionConfigItem, Ld as ContextSnapshot, Lf as ToolResultImageRefContent, Li as AgentOptions, Ln as HeadlessUsage, Lo as ExtensionToolRenderProps, Lp as ToWireMessagesOptions, Lr as estimateTokens, Ls as matchesAllowedTool, Lt as EvalScorer, M as UpDownCounter, Ma as ExtensionConfigActionStatus, Md as ContextExactCounts, Mf as ToolResultAudioContent, Mi as stableStringify, Mm as openaiCompat, Mn as HeadlessEvent, Mo as ExtensionSource, Mp as PairingRepair, Mr as RunSummaryRepeatGuard, Ms as writeSkillToDisk, Mt as EvalRunReporterOptions, N as createMetricsHooks, Na as ExtensionConfigBooleanItem, Nd as ContextExtensionRow, Nf as ToolResultContent, Ni as localReliabilityBehavior, Nn as HeadlessOptions, No as ExtensionStorageScope, Np as PairingRepairMode, Nr as RunSummaryTokens, Ns as writeSkillsToDisk, Nt as EvalRunSummary, O as Meter, Oa as createExtensionPromptBridge, Od as ContextBreakdownContributor, Of as ThinkingLevel, Oi as snapshotCacheDimensions, On as statusCompleted, Oo as ExtensionRunTransform, Op as FileMapStoreOptions, Or as RunSummaryByModel, Os as createModelSearchTool, Ot as EvalMetric, P as OAuthCallbackHandle, Pa as ExtensionConfigCategory, Pd as ContextExtensionSection, Pf as ToolResultDocumentContent, Pi as Agent, Pl as PlanPayload, Po as ExtensionStorageSurface, Pp as RemintResult, Pr as RunSummaryValidation, Ps as SkillValidationIssue, Pt as EvalRunSummaryCase, Q as cleanupPersistedSession, Qa as isValidExtensionConfigValue, Qc as CompletionItem, Qd as DedupHasher, Qf as getReadState, Qi as ExtensionInstallCandidate, Qo as ExtensionHudStatus, Qp as StreamCallbacks, Qr as CompactPromptTooLongError, Qs as SkillInstallOptions, Qt as Trajectory, R as LoginMcpServerOptions, Ra as ExtensionConfigItemBase, Rd as ContextUsageSplit, Rf as ToolResultMetadata, Ri as McpConnector, Rl as Question, Ro as ExtensionToolRenderer, Rp as TurnInterruptionState, Rr as utf8ByteLength, Rs as parseAllowedToolPattern, Rt as EvalScorerContext, S as createMutationValidationHooks, Sa as parseExtensionScanPathEnv, Sd as AutoCompactInput, Sf as SessionEndStatus, Si as CacheDimensionDiff, Sl as parseCommandInvocation, Sn as functionalityMetric, So as ExtensionOrderedContribution, Sr as grep, Ss as SubagentDef, St as EvalAgentStats, T as Counter, Ta as discoverAndBuildExtensionRegistry, Tc as normalizeMcpBlocks, Td as shouldAutoCompact, Tf as SessionTurn, Ti as diffCacheDimensions, Tl as ConfirmQuestion, Tn as registerEvalTests, To as ExtensionPromptTransform, Tp as createRemoteStore, Tr as RunSummary, Ts as createSpawnTool, Tt as EvalCaseResult, U as McpOAuthProvider, Ua as ExtensionConfigSurface, Uc as InlineGhost, Ud as AgentStats, Uf as toolOutputBudgetByteLength, Ui as ExtensionCatalogPartition, Uo as ExtensionToolResultTransform, Up as filterUnresolvedToolUses, Ur as selectFilesFromReadState, Us as resolveSkills, Ut as EvalWorkspaceSnapshot, V as McpCredentialEntry, Va as ExtensionConfigScope, Vc as InlineAutocompleteContext, Vf as TurnFinishReason, Vi as createAgent, Vm as LocalParams, Vo as ExtensionToolResultMetadataRegistration, Vp as ensureEndsWithUserMessage, Vr as RecentFile, Vs as validateSkillForWrite, Vt as EvalWorkspaceFile, W as McpOAuthProviderOptions, Wa as ExtensionConfigValue, Wc as createPathAutocompleteProvider, Wd as AutoCompact, Wf as toolOutputByteLength, Wi as buildExtensionPreset, Wl as SelectQuestion, Wo as ExtensionToolVerdict, Wp as fromAnthropic, Wr as selectFilesFromSession, Ws as InterpolateShellCommandsOptions, Wt as LlmJudgeOptions, X as PersistOutcome, Xa as coerceExtensionConfigInput, Xd as CompactStartHookContext, Xf as ReadStateEntry, Xi as partitionExtensionCatalog, Xm as ArceeParams, Xo as ExtensionHud, Xp as Provider, Xr as compactConversation, Xs as SkillInstallError, Xt as RegisterEvalTestsOptions, Y as PersistInput, Ya as clampExtensionConfigNumber, Yd as CompactHookContext, Yf as HydrateReadStateOptions, Yi as mergeContributions, Yn as transcriptToOpenAIMessages, Yo as ExtensionBannerOptions, Yp as toWireMessages, Yr as CompactStartEvent, Ys as SkillInstallCandidate, Yt as MetricStats, Z as buildPersistedStub, Za as isValidExtensionConfigItem, Zc as CompletionContext, Zf as ReadStateMap, Zi as ExtensionFetchResult, Zm as arcee, Zo as ExtensionHudState, Zp as ProviderCapabilities, Zr as CompactInvalidInputError, Zs as SkillInstallErrorCode, Zt as ReusableExecutionContext, _ as MutationValidationFailure, _a as ExtensionScanEntry, _c as SkillActivationState, _f as ResolveContentRef, _i as summaryToTurn, _l as CommandStep, _n as fileExistsOneOf, _o as ExtensionKeybindingDispatchContext, _s as SpawnTaskInput, _t as EvalAgent, _u as jsonSink, a as basicTools, aa as ExtensionInstallSource, ac as SourcedScanPath, af as ModelTargetSpec, ai as buildCompactPrompt, am as XaiParams, an as clearRegisteredEvals, ao as ExtensionBehaviorTransform, ap as SkillConfig, as as ExtensionHostRuntimeBridge, at as TOOL_USE_SKIPPED_MESSAGE, au as zodToJsonSchema, b as MutationValidationResult, ba as inlineLoadedExtension, bc as ConnectMcpServersOptions, bd as AUTO_COMPACT_MIN_GROWTH_FRACTION, bf as RunHookMap, bi as generateStructuredData, bl as commandSteps, bm as OpenAICompatParams, bn as formatEvalRunSummary, bo as ExtensionModal, br as InteractionToolOptions, bs as SpawnToolOptions, bt as EvalAgentRunResult, c as StartSpan, ca as fetchExtensionSource, cf as ProgressNudgeMessage, ci as buildTailCompactPrompt, cl as CommandAgentResult, cm as SchemaSanitizeProfile, cn as createEvalRunReporter, co as ExtensionContextTransform, cp as SkillSource, cr as createSkillsUseTool, cs as ExtensionRuntimeSurface, ct as ExtensionEditMarker, cu as LogRecord, d as TracingHooksOptions, da as parseExtensionInstallSource, dc as buildCatalog, df as PromptImagePart, di as CompactScope, dl as CommandGenerateDataOptions, dm as sanitizeToolSpecs, dn as defineMetrics, do as ExtensionCustomRendererEntry, dp as Session, dr as SkillsReadToolOptions, ds as ExtensionWorkspacePair, dt as extensionDirForCwd, du as LoggingHookSet, ea as ExtensionInstallErrorCode, ec as SkillInstallSpec, ei as CompactDirection, el as CompletionReference, en as TrajectoryStepKind, eo as resolveExtensionConfigValue, ep as hydrateReadStateFromSession, er as ValidationResult, es as ExtensionNotification, et as resolvePersistDir, eu as InferSchemaOutput, f as createTracingHooks, fa as readExtensionInstallProvenance, fc as IMPLICITLY_ALLOWED_SKILL_TOOLS, ff as PromptPart, fi as CompactionSlice, fl as CommandInteraction, fm as OpenRouterParams, fn as efficiencyMetricValues, fo as ExtensionDefinition, fp as SessionData, fr as createSkillsReadTool, fs as ExtensionWorkspaceSurface, ft as extensionScaffold, fu as LoggingHooksOptions, g as MutationValidationBatch, ga as ENTRY_CANDIDATES, gc as DeactivationReason, gf as RepeatGuardToolMatcher, gi as stripImagesFromTurns, gl as CommandSpawnTask, gn as fileExists, go as ExtensionKeybinding, gp as createSession, gs as ExtensionSubagentDef, gt as EFFICIENCY_METRICS, gu as createLoggingHooks, h as statsByModel, ha as registerExtensionHostModules, hc as ActiveSkill, hf as RepeatGuardConfig, hi as sliceForCompaction, hl as CommandSpawnResult, hn as fileContentQuality, ho as ExtensionGuiSurface, hp as SessionStore, hr as createShellTool, hs as ChildAgent, ht as CreateEvalAgentOptions, hu as createLogger, i as _default, ia as ExtensionInstallScope, ic as readSkillProvenance, if as ModelTarget, ii as TRAILER, im as TurnResult, in as buildTrajectory, io as ExtensionApiVersion, ip as ShellInterpolationApproval, is as createExtensionHud, it as TOOL_USE_CANCELLED_MESSAGE, iu as resolveSchemaInput, j as MetricsHooksOptions, ja as ExtensionConfigActionResult, jd as ContextCategoryId, jf as ToolOutcome, ji as normalizeShellCommand, jn as HeadlessErrorInfo, jo as ExtensionSkillPolicy, jp as ORPHANED_TOOL_RESULT_MARKER, jr as RunSummaryError, js as defineSkill, jt as EvalRunReporter, k as MetricAttributes, ka as defineExtension, kd as ContextBreakdownOptions, ki as defaultRepeatGuardNormalize, ko as ExtensionRuntimeEnv, kp as createFileMapStore, kr as RunSummaryCollector, ks as formatModelLine, kt as EvalMetricError, l as TracingConventions, la as installExtensionFromSpec, lf as PromptAudioPart, li as buildUpToCompactPrompt, ll as CommandArgSuggestion, lm as SchemaSanitizeResult, ln as createReusableExecutionContext, lo as ExtensionContributions, lp as SkillsConfig, lr as SkillsRunScriptToolOptions, ls as ExtensionSessionSummary, lt as ZIDANE_EXTENSION_SKILL_NAME, lu as LogSink, m as flattenTurns, ma as updateInstalledExtension, mc as ActivationVia, mf as PromptVideoPart, mi as anchorPreviewFor, ml as CommandOutputBlock, mm as openrouter, mn as fileContains, mo as ExtensionGuiPanel, mp as SessionRun, mr as CreateShellToolOptions, ms as createWorkspaceSurface, mt as withZidaneExtensionSkill, mu as consoleSink, na as ExtensionInstallProvenance, nc as listSkillCandidates, nf as McpToolHookContext, nh as applyAnthropicCacheBreakpoints, ni as CompactPromptOptions, nm as ToolResult, nn as buildEvalRunSummary, no as toWireConfigSchema, np as readStateKey, ns as ExtensionNotifyTone, nt as INTERRUPT_MESSAGE_FOR_TOOL_USE, nu as StandardSchemaLike, o as GEN_AI_ATTRIBUTES, oa as InstallExtensionFromSpecOptions, oc as discoverSkills, of as OAuthRefreshHookContext, oi as buildFromCompactPrompt, ol as resolveCompletionSubmit, om as xai, on as computeEvalTagScores, oo as ExtensionCapability, op as SkillDiagnostic, os as ExtensionHostRuntimeImpl, ot as applyCompactSummaryCutoff, ou as ConsoleSinkOptions, p as ModelUsage, pa as removeInstalledExtension, pc as installAllowedToolsGate, pf as PromptTextPart, pi as SummaryToTurnInput, pl as CommandInvocation, pn as emitEfficiencyMetrics, po as ExtensionFooterHint, ps as createExtensionHostRuntimeBridge, pt as resolveExtensionDocsDir, q as PERSISTED_STUB_PREFIX, qa as WireExtensionConfigItem, qd as CompactEndHookContext, qf as ToolDef, qi as disposeExtensionRegistry, qm as BasetenParams, qo as LoadedExtension, qp as toAnthropic, qr as CompactOptions, qt as MetricSpec, r as definePreset, ra as ExtensionInstallResult, rc as parseSkillInstallSpec, ri as NO_TOOLS_PREAMBLE, rm as ToolSpec, rn as buildRegisteredEvals, ro as EMPTY_EXTENSION_REGISTRY, rp as resolveReadStateMap, rs as ExtensionStatusOptions, rt as SHELL_CASCADE_CANCEL_MESSAGE, ru as isStandardSchema, s as Span, sa as InstalledExtensionTargetOptions, sf as ProgressNudgeKind, si as buildFullCompactPrompt, sl as Command, sm as SchemaSanitizeOptions, sn as createEvalAgent, so as ExtensionContext, sp as SkillResource, sr as SkillsUseToolOptions, ss as ExtensionModelEntry, st as EXTENSION_EDIT_METADATA_KEY, su as LogLevel, t as Preset, ta as ExtensionInstallIo, tc as installSkillFromSpec, tf as McpServerConfig, th as anthropic, ti as CompactPromptBuilder, tl as CompletionSubmitContext, tm as ToolCall, tn as artifactPath, to as sanitizeExtensionConfigActionPatch, tp as hydrateReadStateFromSessionAsync, tr as validateToolArgs, ts as ExtensionNotifyOptions, tt as resolveTasksDir, tu as SchemaInput, u as TracingHookSet, ua as listExtensionCandidates, uc as parseSkillFile, uf as PromptDocumentPart, ui as ANCHOR_PREVIEW_MAX_CHARS, ul as CommandExecution, um as sanitizeToolSchema, un as defineEval, uo as ExtensionCustomRenderer, up as CreateSessionOptions, ur as createSkillsRunScriptTool, us as ExtensionSessionsSurface, ut as buildZidaneExtensionSkill, uu as Logger, v as MutationValidationHooksOptions, va as defaultExtensionScanPaths, vc as SkillActivationStateOptions, vf as ResolveContentRefBlock, vi as truncateHeadForPtlRetry, vl as CommandStepContext, vm as OpenAICompatAuthHeader, vn as finalizeEvalMetrics, vo as ExtensionManifest, vr as multiEdit, vs as SpawnTaskOutcome, vt as EvalAgentMcpServers, w as resolveModelTargets, wa as DiscoverAndBuildExtensionRegistryOptions, wd as effectiveContextWindow, wf as SessionMessage, wi as CacheDimensionSnapshot, wl as AnswerValue, wn as normalizeMetric, wo as ExtensionPermission, wp as RemoteStoreOptions, wr as edit, ws as SubagentRegistry, wt as EvalCaseOptions, x as SuccessfulMutationOutcome, xa as isExtensionDefinition, xc as McpConnection, xd as AutoCompactDecision, xf as SessionContentBlock, xi as CacheBreakLoggerOptions, xl as executeCommand, xn as formatTrajectoryLine, xo as ExtensionModalNode, xp as loadSession, xr as createInteractionTool, xs as SpawnToolState, xt as EvalAgentRunStats, y as MutationValidationMutation, ya as discoverExtensions, yc as createSkillActivationState, yf as RetryConfig, yi as GenerateStructuredDataOptions, yl as CommandStepFn, ym as OpenAICompatHttpError, yn as formatEvalCaseSummary, yo as ExtensionMcpConfigTransform, ys as SpawnTool, yt as EvalAgentRunOptions, z as LoginMcpServerResult, za as ExtensionConfigModelItem, zf as ToolResultTextContent, zi as McpToolMeta, zl as QuestionChoice, zm as openai, zn as OpenAIChatMessage, zo as ExtensionToolRendererEntry, zp as autoDetectAndConvert, zr as PostCompactAttachments, zs as validateResourcePath, zt as EvalTestRunner } from "./index-BFNt9GAs.js";
3
3
  import { _ as TaskStallInfo, a as ContextType, c as ExecutionContext, d as ListFilesEntry, f as ListFilesOptions, g as TaskHandle, h as TaskExitInfo, i as ContextMount, l as ExecutionHandle, m as TaskEntry, n as ContextCapabilities, o as DetachedTasksCapability, p as SpawnConfig, r as ContextHardening, s as ExecResult, t as BackgroundTaskStatus, u as ListFileMetadata, v as resolveDetachedTasksCapability } from "./types-BDccavwj.js";
4
4
  import { t as createProcessContext } from "./index-DsPQbyUn.js";
5
5
  import { n as createSandboxContext, t as SandboxProvider } from "./sandbox-CgjG2VvQ.js";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as hydrateReadStateFromSessionAsync, c as resolveReadStateMap, i as hydrateReadStateFromSession, r as hashContent, s as readStateKey, t as getReadState } from "./read-state-Dq_TXUX1.js";
2
2
  import { c as toolOutputByteLength, l as toolResultToText, s as toolOutputBudgetByteLength } from "./types-BIarq1qE.js";
3
- import { $ as composeExtensionPreset, $t as discoverExtensions, A as ANCHOR_PREVIEW_MAX_CHARS, At as createInteractionTool, B as ExtensionInstallError, C as NO_TOOLS_PREAMBLE, D as buildFullCompactPrompt, Dt as formatModelLine, E as buildFromCompactPrompt, Et as createModelSearchTool, F as truncateHeadForPtlRetry, G as readExtensionInstallProvenance, H as installExtensionFromSpec, I as CompactInvalidInputError, J as createExtensionHud, K as removeInstalledExtension, L as CompactPromptTooLongError, M as sliceForCompaction, Mt as glob, N as stripImagesFromTurns, Nt as edit, O as buildTailCompactPrompt, Ot as matchModelEntries, P as summaryToTurn, Pt as validateToolArgs, Q as buildExtensionRegistry, Qt as defaultExtensionScanPaths, R as EMPTY_EXTENSION_REGISTRY, S as BASE_INSTRUCTIONS, T as buildCompactPrompt, Tt as multiEdit, U as listExtensionCandidates, V as fetchExtensionSource, W as parseExtensionInstallSource, X as discoverAndBuildExtensionRegistry, Y as registerExtensionHostModules, Z as buildExtensionPreset, Zt as ENTRY_CANDIDATES, _ as buildPostCompactAttachments, _n as defaultRepeatGuardNormalize, _t as createSkillsRunScriptTool, a as SHELL_CASCADE_CANCEL_MESSAGE, an as clampExtensionConfigNumber, at as createWorkspaceSurface, b as selectRecentFiles, bn as stableStringify, bt as createShellTool, c as applyCompactSummaryCutoff, cn as isValidExtensionConfigValue, ct as basicTools, d as buildPersistedStub, dn as sanitizeExtensionConfigActionPatch, en as inlineLoadedExtension, et as disposeExtensionRegistry, f as cleanupPersistedSession, fn as toWireConfigSchema, ft as waitTask, g as resolveTasksDir, gn as shouldAutoCompact, gt as createSkillsUseTool, h as resolvePersistDir, hn as effectiveContextWindow, ht as isSpawnTool, i as INTERRUPT_MESSAGE_FOR_TOOL_USE, in as defineExtension, it as createExtensionHostRuntimeBridge, j as anchorPreviewFor, jt as grep, k as buildUpToCompactPrompt, l as PERSISTED_STUB_PREFIX, ln as resolveExtensionConfig, lt as basic_default, mn as OUTPUT_RESERVE_TOKENS, mt as createSpawnTool, n as normalizeProviders, nn as parseExtensionScanPathEnv, nt as mergeContributions, o as TOOL_USE_CANCELLED_MESSAGE, on as coerceExtensionConfigInput, p as maybePersistToolResult, pn as AUTO_COMPACT_MIN_GROWTH_FRACTION, q as updateInstalledExtension, r as resolveModelTargets, rn as scanExtensionDirectories, rt as partitionExtensionCatalog, s as TOOL_USE_SKIPPED_MESSAGE, sn as isValidExtensionConfigItem, st as definePreset, t as createAgent, tn as isExtensionDefinition, tt as filterExtensionRegistry, u as PERSISTENCE_PREVIEW_BYTES, un as resolveExtensionConfigValue, v as selectFilesFromReadState, vn as defaultRepeatGuardTracked, vt as createSkillsReadTool, w as TRAILER, x as compactConversation, y as selectFilesFromSession, yn as normalizeShellCommand, z as createExtensionPromptBridge } from "./agent-DPO6GKX5.js";
3
+ import { $ as composeExtensionPreset, $t as discoverExtensions, A as ANCHOR_PREVIEW_MAX_CHARS, At as createInteractionTool, B as ExtensionInstallError, C as NO_TOOLS_PREAMBLE, D as buildFullCompactPrompt, Dt as formatModelLine, E as buildFromCompactPrompt, Et as createModelSearchTool, F as truncateHeadForPtlRetry, G as readExtensionInstallProvenance, H as installExtensionFromSpec, I as CompactInvalidInputError, J as createExtensionHud, K as removeInstalledExtension, L as CompactPromptTooLongError, M as sliceForCompaction, Mt as glob, N as stripImagesFromTurns, Nt as edit, O as buildTailCompactPrompt, Ot as matchModelEntries, P as summaryToTurn, Pt as validateToolArgs, Q as buildExtensionRegistry, Qt as defaultExtensionScanPaths, R as EMPTY_EXTENSION_REGISTRY, S as BASE_INSTRUCTIONS, T as buildCompactPrompt, Tt as multiEdit, U as listExtensionCandidates, V as fetchExtensionSource, W as parseExtensionInstallSource, X as discoverAndBuildExtensionRegistry, Y as registerExtensionHostModules, Z as buildExtensionPreset, Zt as ENTRY_CANDIDATES, _ as buildPostCompactAttachments, _n as defaultRepeatGuardNormalize, _t as createSkillsRunScriptTool, a as SHELL_CASCADE_CANCEL_MESSAGE, an as clampExtensionConfigNumber, at as createWorkspaceSurface, b as selectRecentFiles, bn as stableStringify, bt as createShellTool, c as applyCompactSummaryCutoff, cn as isValidExtensionConfigValue, ct as basicTools, d as buildPersistedStub, dn as sanitizeExtensionConfigActionPatch, en as inlineLoadedExtension, et as disposeExtensionRegistry, f as cleanupPersistedSession, fn as toWireConfigSchema, ft as waitTask, g as resolveTasksDir, gn as shouldAutoCompact, gt as createSkillsUseTool, h as resolvePersistDir, hn as effectiveContextWindow, ht as isSpawnTool, i as INTERRUPT_MESSAGE_FOR_TOOL_USE, in as defineExtension, it as createExtensionHostRuntimeBridge, j as anchorPreviewFor, jt as grep, k as buildUpToCompactPrompt, l as PERSISTED_STUB_PREFIX, ln as resolveExtensionConfig, lt as basic_default, mn as OUTPUT_RESERVE_TOKENS, mt as createSpawnTool, n as normalizeProviders, nn as parseExtensionScanPathEnv, nt as mergeContributions, o as TOOL_USE_CANCELLED_MESSAGE, on as coerceExtensionConfigInput, p as maybePersistToolResult, pn as AUTO_COMPACT_MIN_GROWTH_FRACTION, q as updateInstalledExtension, r as resolveModelTargets, rn as scanExtensionDirectories, rt as partitionExtensionCatalog, s as TOOL_USE_SKIPPED_MESSAGE, sn as isValidExtensionConfigItem, st as definePreset, t as createAgent, tn as isExtensionDefinition, tt as filterExtensionRegistry, u as PERSISTENCE_PREVIEW_BYTES, un as resolveExtensionConfigValue, v as selectFilesFromReadState, vn as defaultRepeatGuardTracked, vt as createSkillsReadTool, w as TRAILER, x as compactConversation, y as selectFilesFromSession, yn as normalizeShellCommand, z as createExtensionPromptBridge } from "./agent-6iGNP46b.js";
4
4
  import { n as estimateTokens, r as utf8ByteLength, t as BYTES_PER_TOKEN } from "./utils-ngQzYzZD.js";
5
5
  import { r as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-A4ep-iJs.js";
6
6
  import { createSandboxContext } from "./contexts/sandbox.js";
@@ -8,27 +8,27 @@ import { a as AgentToolNotAllowedError, f as matchesContextExceeded, i as AgentP
8
8
  import { A as validateSkillName, C as stripShellInterpolations, D as validateResourcePath, E as parseAllowedToolPattern, O as validateResourcePathReal, S as interpolateShellCommands, T as matchesAllowedTool, c as parseSkillFile, d as installAllowedToolsGate, f as createSkillActivationState, i as discoverSkills, k as validateSkillForWrite, l as buildCatalog, n as writeSkillToDisk, r as writeSkillsToDisk, t as resolveSkills, u as IMPLICITLY_ALLOWED_SKILL_TOOLS, w as isToolAllowedByUnion } from "./resolve-HtxmBWs9.js";
9
9
  import { c as jsonSink, i as createLoggingHooks, r as createLogger, t as consoleSink } from "./logger-DBX9uYOw.js";
10
10
  import { i as statsByModel, n as flattenTurns } from "./stats-DAKBEKjc.js";
11
- import { f as mapOAIFinishReason, l as classifyOpenAICompatError, m as openaiCompat, n as OpenAICompatHttpError, v as sanitizeToolSchema, y as sanitizeToolSpecs } from "./openai-compat-LGAsBush.js";
11
+ import { f as mapOAIFinishReason, l as classifyOpenAICompatError, m as openaiCompat, n as OpenAICompatHttpError, v as sanitizeToolSchema, y as sanitizeToolSpecs } from "./openai-compat-J_JZ7qsw.js";
12
12
  import { SYSTEM_PROMPT_BOUNDARY, appendDynamicSection, appendStaticSection, hasSystemPromptBoundary, joinSystemPrompt, renderSystemForWire, replaceDynamicSection, splitSystemPrompt } from "./prompt.js";
13
- import { a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, h as toWireMessages, i as autoDetectAndConvert, l as fromAnthropic, m as toOpenAI, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, p as toAnthropic, r as TOOL_USE_INTERRUPTED_MARKER, s as ensureToolResultPairing, t as ORPHANED_TOOL_RESULT_MARKER, u as fromOpenAI } from "./messages-DEPX32kc.js";
14
- import { d as createFileMapStore, l as createRemoteStore, o as loadSession, t as createSession, u as createMemoryStore } from "./session-Dc1v4Otm.js";
13
+ import { a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, h as toWireMessages, i as autoDetectAndConvert, l as fromAnthropic, m as toOpenAI, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, p as toAnthropic, r as TOOL_USE_INTERRUPTED_MARKER, s as ensureToolResultPairing, t as ORPHANED_TOOL_RESULT_MARKER, u as fromOpenAI } from "./messages-BDpXLFoe.js";
14
+ import { d as createFileMapStore, l as createRemoteStore, o as loadSession, t as createSession, u as createMemoryStore } from "./session-CIXE-Bzp.js";
15
15
  import { t as OperationTimeoutError } from "./timeout-BDetbuN6.js";
16
- import { a as normalizeMcpServers, d as createMemoryMcpCredentialStore, f as hasAuthorizationHeader, i as normalizeMcpBlocks, n as connectMcpServers, o as resultToString, u as McpOAuthProvider } from "./mcp-CkHUripi.js";
16
+ import { a as normalizeMcpServers, d as createMemoryMcpCredentialStore, f as hasAuthorizationHeader, i as normalizeMcpBlocks, n as connectMcpServers, o as resultToString, u as McpOAuthProvider } from "./mcp-BCaN_Gyg.js";
17
17
  import { i as snapshotCacheDimensions, n as fnv1a32, r as installCacheBreakLogger, t as diffCacheDimensions } from "./cache-telemetry-KJ7B-_Gh.js";
18
18
  import { a as generateStructuredData, d as zodToJsonSchema, g as parseCommandInvocation, h as executeCommand, l as isStandardSchema, m as commandSteps, n as patchInlineGhost, r as resolveInlineSuggestion, t as createPathAutocompleteProvider, u as resolveSchemaInput } from "./inline-autocomplete-BAwBcZtD.js";
19
19
  import { s as resolveCompletionSubmit } from "./completion-core-BRo86R_L.js";
20
20
  import { t as createRunSummaryCollector } from "./run-summary-nD3IQ4ZQ.js";
21
21
  import { headlessEventToJsonl, runHeadless, transcriptToOpenAIMessages } from "./headless.js";
22
22
  import { EFFICIENCY_METRICS, EvalMetricError, artifactPath, buildEvalRunSummary, buildRegisteredEvals, buildTrajectory, clearRegisteredEvals, computeEvalTagScores, createEvalAgent, createEvalRunReporter, createReusableExecutionContext, defineEval, defineMetrics, efficiencyMetricValues, emitEfficiencyMetrics, fileContains, fileContentQuality, fileExists, fileExistsOneOf, finalizeEvalMetrics, formatEvalCaseSummary, formatEvalRunSummary, formatTrajectoryLine, functionalityMetric, llmJudge, normalizeMetric, registerEvalTests, relativeArtifactPath, runEvalCase, statusCompleted } from "./eval.js";
23
- import { a as listSkillCandidates, i as installSkillFromSpec, o as parseSkillInstallSpec, r as SkillInstallError, s as readSkillProvenance, t as defineSkill } from "./skills-BlmY7QhV.js";
24
- import { a as buildZidaneExtensionSkill, c as resolveExtensionDocsDir, i as ZIDANE_EXTENSION_SKILL_NAME, l as withZidaneExtensionSkill, n as startOAuthCallback, o as extensionDirForCwd, r as EXTENSION_EDIT_METADATA_KEY, s as extensionScaffold, t as loginMcpServer } from "./login-Bp_tRj_e.js";
25
- import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-J2tBjcSQ.js";
23
+ import { a as listSkillCandidates, i as installSkillFromSpec, o as parseSkillInstallSpec, r as SkillInstallError, s as readSkillProvenance, t as defineSkill } from "./skills-CDpejYOf.js";
24
+ import { a as buildZidaneExtensionSkill, c as resolveExtensionDocsDir, i as ZIDANE_EXTENSION_SKILL_NAME, l as withZidaneExtensionSkill, n as startOAuthCallback, o as extensionDirForCwd, r as EXTENSION_EDIT_METADATA_KEY, s as extensionScaffold, t as loginMcpServer } from "./login-B5nMPF8w.js";
25
+ import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-BD-lwEKp.js";
26
26
  import { arcee } from "./providers/arcee.js";
27
27
  import { baseten } from "./providers/baseten.js";
28
28
  import { cerebras } from "./providers/cerebras.js";
29
- import { t as xai } from "./xai-BYAyEPiJ.js";
29
+ import { t as xai } from "./xai-D-wALLuZ.js";
30
30
  import { local } from "./providers/local.js";
31
- import { r as openai } from "./openai-BcmYm0t4.js";
31
+ import { openai } from "./providers/openai.js";
32
32
  import { openrouter } from "./providers/openrouter.js";
33
33
  //#region src/behaviors/local-reliability.ts
34
34
  const DEFAULT_LOCAL_RELIABILITY = {
@@ -1,5 +1,5 @@
1
- import { c as createTolerantClient, l as sseToJsonFetchIfNeeded, p as isOAuthTokenRejectionError, u as McpOAuthProvider } from "./mcp-CkHUripi.js";
2
- import { t as defineSkill } from "./skills-BlmY7QhV.js";
1
+ import { c as createTolerantClient, l as sseToJsonFetchIfNeeded, p as isOAuthTokenRejectionError, u as McpOAuthProvider } from "./mcp-BCaN_Gyg.js";
2
+ import { t as defineSkill } from "./skills-CDpejYOf.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { basename, dirname, join, resolve } from "node:path";
5
5
  import { existsSync } from "node:fs";
@@ -545,4 +545,4 @@ async function raceLoginCallback(handle, timeoutMs, signal) {
545
545
  //#endregion
546
546
  export { buildZidaneExtensionSkill as a, resolveExtensionDocsDir as c, ZIDANE_EXTENSION_SKILL_NAME as i, withZidaneExtensionSkill as l, startOAuthCallback as n, extensionDirForCwd as o, EXTENSION_EDIT_METADATA_KEY as r, extensionScaffold as s, loginMcpServer as t };
547
547
 
548
- //# sourceMappingURL=login-Bp_tRj_e.js.map
548
+ //# sourceMappingURL=login-B5nMPF8w.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login-Bp_tRj_e.js","names":[],"sources":["../src/extension-authoring.ts","../src/mcp/oauth-callback.ts","../src/mcp/login.ts"],"sourcesContent":["/**\n * Host glue for the \"edit / create extension\" authoring flow (TUI + GUI).\n *\n * Pure, renderer-neutral helpers consumed by the hosts — deliberately kept OUT\n * of `src/extensions/**` (the extension loader / registry core) so the\n * authoring UX can never entangle with discovery / registration. Imports only\n * the skills lib and node builtins.\n *\n * - {@link extensionScaffold} — minimal `index.ts` for a new extension.\n * - {@link resolveExtensionDocsDir} — locate the shipped `docs/` directory.\n * - {@link buildZidaneExtensionSkill} — the inline docs skill.\n * - {@link withZidaneExtensionSkill} — inject it into a `SkillsConfig`.\n * - {@link EXTENSION_EDIT_METADATA_KEY} / {@link ZIDANE_EXTENSION_SKILL_NAME}\n * — constants shared by both hosts.\n */\nimport type { SkillConfig, SkillsConfig } from './skills'\nimport { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { defineSkill } from './skills'\n\n/**\n * Session-metadata key marking an \"edit / create extension\" session. The value\n * is an {@link ExtensionEditMarker}. Both hosts stamp it at session creation so\n * the agent build can scope the docs skill to exactly these sessions (and it\n * survives reload because metadata is persisted).\n */\nexport const EXTENSION_EDIT_METADATA_KEY = 'zidane.extensionEdit'\n\n/** Name of the inline docs skill auto-activated in extension edit sessions. */\nexport const ZIDANE_EXTENSION_SKILL_NAME = 'zidane-extension'\n\n/** Per-edit-session marker persisted on `session.metadata[EXTENSION_EDIT_METADATA_KEY]`. */\nexport interface ExtensionEditMarker {\n /** Absolute path to the extension's directory (the session's cwd). */\n dir: string\n}\n\n/**\n * Minimal valid extension module for a freshly-created extension. `name` MUST\n * equal the folder name or the loader rejects it (see `src/extensions/discovery`).\n * Does nothing by default — the author registers contributions via `ctx.*`\n * inside `setup`; the auto-activated docs skill guides them from there.\n */\nexport function extensionScaffold(name: string): string {\n return `import { defineExtension } from 'zidane'\n\n/**\n * ${name} — a zidane extension.\n *\n * Register tools / hooks / skills / MCP servers / subagents / config / themes /\n * agents / keybindings via the \\`ctx\\` surface inside \\`setup\\`.\n *\n * Authoring reference: activate the \\`${ZIDANE_EXTENSION_SKILL_NAME}\\` skill — it carries\n * the full \\`ctx\\` API + invariants and is available whenever you open this\n * folder in zidane (or run \\`zidane\\` from inside it).\n */\nexport default defineExtension({\n name: '${name}',\n setup(ctx) {\n // e.g. ctx.registerTool('${name}_hello', {\n // spec: { name: '${name}_hello', description: 'say hi', inputSchema: { type: 'object', properties: {} } },\n // isConcurrencySafe: true,\n // async execute() { return 'hello from ${name}' },\n // })\n },\n})\n`\n}\n\n/**\n * Locate the shipped `docs/` directory (`docs/EXTENSIONS.md` + siblings).\n *\n * The docs ship via `package.json` `files`, so an installed consumer has\n * `<root>/node_modules/zidane/docs` and the repo itself has `<repo>/docs`.\n * Returns the first existing candidate, or `null` (the skill then falls back to\n * the literal `node_modules/zidane/docs` hint, which the model's file tools can\n * still attempt from cwd).\n */\nexport function resolveExtensionDocsDir(cwd: string = process.cwd()): string | null {\n const candidates: string[] = []\n\n // 1) The installed (or self-linked) zidane package, via its package.json\n // (exposed through `exports[\"./package.json\"]`).\n try {\n const req = createRequire(import.meta.url)\n candidates.push(join(dirname(req.resolve('zidane/package.json')), 'docs'))\n }\n catch {\n // No resolvable package (compiled binary / odd layout) — fall through.\n }\n\n // 2) Relative to this module: `dist/extension-authoring.js` -> `../docs`, or\n // walking up from `src/` when running from source.\n try {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 6; i++) {\n if (existsSync(join(dir, 'docs', 'EXTENSIONS.md'))) {\n candidates.push(join(dir, 'docs'))\n break\n }\n dir = dirname(dir)\n }\n }\n catch {\n // `import.meta.url` is virtual under `bun build --compile` — fall through.\n }\n\n // 3) cwd-relative — the project the author is actually editing.\n candidates.push(join(cwd, 'node_modules', 'zidane', 'docs'))\n\n for (const candidate of candidates) {\n if (existsSync(join(candidate, 'EXTENSIONS.md')))\n return candidate\n }\n return null\n}\n\n/** Entry-file probe order for an extension dir (mirrors the loader's discovery). */\nconst EXTENSION_ENTRY_FILES = ['index.ts', 'index.tsx', 'index.mjs', 'index.js'] as const\n\n/**\n * If `cwd` sits inside a zidane extension, return that extension's root dir,\n * else `null`. Mirrors the discovery layout\n * `<scope>/.{agents,zidane}/extensions/<name>/` — the root is the `<name>` dir\n * (parent `extensions`, grandparent `.agents` / `.zidane`) holding an entry\n * file. Walks up from `cwd`, so the nearest enclosing extension wins. Lets the\n * hosts surface the authoring skill for a plain `zidane` launched from an\n * extension folder, not just sessions opened through the edit/create flow.\n */\nexport function extensionDirForCwd(cwd: string = process.cwd()): string | null {\n let dir = resolve(cwd)\n // Bounded walk to the filesystem root (the `parent === dir` guard is the real\n // terminator; the cap is just belt-and-braces against pathological inputs).\n for (let i = 0; i < 64; i++) {\n const parent = dirname(dir)\n if (\n basename(parent) === 'extensions'\n && (basename(dirname(parent)) === '.agents' || basename(dirname(parent)) === '.zidane')\n && EXTENSION_ENTRY_FILES.some(f => existsSync(join(dir, f)))\n ) {\n return dir\n }\n if (parent === dir)\n break\n dir = parent\n }\n return null\n}\n\n/**\n * The authoring reference embedded into the skill body. Kept INLINE (not a\n * filesystem path) on purpose: a `bun build --compile` TUI binary has no\n * resolvable `node_modules/zidane/docs`, no real `import.meta.url`, and the\n * edited extension's own cwd has no `node_modules` — so a path reference dead-\n * ends there. The model gets the API verbatim on activation regardless of host.\n *\n * Mirrors `ExtensionContext` (src/extensions/types.ts) — keep in sync when the\n * `ctx.*` surface changes.\n */\nconst EXTENSION_AUTHORING_CHEATSHEET = `## defineExtension\n\nA zidane extension is a module at \\`<scope>/.{agents,zidane}/extensions/<name>/index.{ts,tsx,mjs,js}\\`\nthat default-exports \\`defineExtension({ ... })\\`. It runs in-process in the host (TUI / GUI / SDK).\n\n\\`\\`\\`ts\nimport { defineExtension } from 'zidane'\n\nexport default defineExtension({\n name: 'my-ext', // MUST equal the folder name\n apiVersion: 1, // optional; omitted means v1\n version: '0.1.0', // optional — shown in Settings → Extensions\n displayName: 'My Ext', // optional UI label\n description: 'what it does',\n capabilities: ['tools'], // optional descriptive manifest labels\n permissions: [], // optional descriptive labels; not a sandbox\n setup(ctx) { /* register everything here; may be async */ },\n teardown() {}, // optional, reserved (no hot-reload yet)\n})\n\\`\\`\\`\n\nZero-import form — required INSIDE compiled binaries, which can't \\`import 'zidane'\\` at runtime:\n\\`\\`\\`ts\nimport type { ExtensionContext } from 'zidane' // type-only: erased at runtime\nexport default {\n name: 'my-ext',\n setup(ctx: ExtensionContext) { /* ... */ },\n}\n\\`\\`\\`\n\n## ctx surface (call everything inside setup)\n\nIdentity / utilities:\n- ctx.name / ctx.version / ctx.dir / ctx.scope ('project' | 'user' | 'inline' | 'builtin')\n- ctx.logger — Logger namespaced \\`extension:<name>\\`\n- ctx.config — read THIS extension's config, default-first: \\`ctx.config.get(key)\\`\n- ctx.paths — cwd/projectRoot/dataDir/cacheDir/configDir/stateDir\n- ctx.storage.path(scope, ...segments) — extension-scoped storage path\n- ctx.session — JSON-only per-session state: get / set / delete\n\nRenderer-agnostic registration:\n- ctx.registerTool(name, toolDef)\n- ctx.registerHook(event, handler) — an AgentHooks event; fires on the PARENT agent (use child:* for subagents)\n- ctx.registerMcpServer(config)\n- ctx.registerSkill(skillConfig) — a defineSkill() shape\n- ctx.registerCompletionProvider(provider) — single-char '/' '@' '!' trigger\n- ctx.tui.notify(text, { tone? }) — one-shot transcript line (info/warn/error); buffered pre-mount\n- ctx.tui.setStatus(text | null, { loader?, timeout? }) — single dim status line (transcript-tail slot); loader glyph, auto-clear ms\n- ctx.tui.setBanner(lines | null, { timeout? }) — short block above the prompt (stacked with the todo indicator); auto-clear ms\n- ctx.submitPrompt(text, { delivery? }) — submit as the user: 'auto' (run-or-queue), 'steer', 'followUp'; false when detached\n- ctx.registerToolPolicy({ tools?, decide }) — gate tool calls: allow / { block } / { patch } (patches re-validated by the loop)\n- ctx.registerToolResultTransform(fn) — middleware over finished tool results (chained)\n- ctx.registerContextTransform(fn) — rewrite wire messages before each provider call\n- ctx.registerPromptTransform(fn) — transform or consume submitted prompts (after / commands, before skills)\n- ctx.runtime / ctx.sessions — late-bound host controls: model()/thinking()/setThinking(), sessions list/switch/create\n- ctx.appendNote(blocks) — durable display-only transcript note (command-output block vocabulary)\n- ctx.workspace.exec/readFile/writeFile/listFiles/fileSize — shell + files through the SESSION'S execution context (sandbox-correct; host child_process silently targets the wrong filesystem under docker/e2b). Detached ⇒ rejects; guard with \\`await ctx.workspace.available()\\`.\n- ctx.tui.registerToolRenderer({ tools?, render }) — custom view for tool-result rows; return null to fall through to the default. View-layer only: never persisted, error-bounded per row, TUI-scoped.\n- ctx.tui.registerRenderer(id, render) + emit/appendNote \\`custom: { renderer, data }\\` blocks — custom components in the transcript. \\`data\\` must be JSON-safe (it persists); the block's \\`text\\` is the MANDATORY markdown fallback (disabled extension, headless host, GUI, renderer throw). appendNote auto-prefixes bare ids; command emit needs \\`<ext>/<id>\\`.\n- Renderer components: import \\`react\\` / \\`@opentui/react\\` BARE (never as your own dependency) — the host maps them to its live instances at load time, so hooks work. Async data: render() stays sync; return a component that fetches with useState/useEffect.\n- Renderer async caching: \\`useSessionState(id, initial)\\` (per-row, session-persisted — rehydrates on reload) + \\`useRowVisible()\\` (latched viewport gate) from \\`zidane/tui\\` — fetch once, only when scrolled in.\n- ctx.registerCommand(command) — a '/<name>' workflow (handler or steps[]); step ctx: emit (local output),\n runAgent (interactive sub-run), generateData (silent zod/JSON-Schema JSON),\n session? (read-only turns/runs view), interaction? (confirm / askUser forms /\n presentPlan approval — both optional; guard for bare hosts)\n- ctx.registerTheme(theme)\n- ctx.registerAgent(profile) — extra agent profile in the picker\n- ctx.registerSubagent(def) — spawnable subagent (the spawn tool's subagent_type)\n- ctx.registerSubagentOverride(name, fn) — edit/delete an existing subagent\n- ctx.registerProvider(descriptor)\n- ctx.registerSystemPromptFragment(text)\n- ctx.registerContextBreakdownSection(fn) — render extension-owned rows in the context panel\n- ctx.registerContextPanelSection(section) — richer context panel section with rows/load\n- ctx.registerToolResultMetadata(registration) — project namespaced tool-result metadata into context\n- ctx.registerRunTransform(fn) — sync rewrite of agent.run options\n- ctx.registerBehaviorTransform(fn) — sync rewrite of resolved behavior\n- ctx.registerProviderMiddleware(fn) — wrap provider instances\n- ctx.registerToolCatalogTransform(fn) — shape/hide/rename tools before disclosure/execution\n- ctx.registerMcpConfigTransform(fn) — rewrite MCP server configs before connect\n- ctx.registerSkillPolicy(policy) — auto-activate skills by run context\n- ctx.registerConfigCategory(category)\n- ctx.registerConfigItem([categoryId,] item) — typed setting; supports scope/onChange metadata\n\nTUI-only (ctx.tui.* — silently ignored on non-TUI hosts):\n- ctx.tui.registerKeybinding(binding)\n- ctx.tui.registerFooterHint(hint)\n- ctx.tui.registerModal(modal) — keep UI lazy: \\`node: () => import('./panel')\\`\n\nGUI-only:\n- ctx.gui.registerPanel(panel) — collected, not rendered yet\n\nCompletion providers may also implement submit hooks:\n- resolveReferences(refs, ctx, signal)\n- onSubmit({ text, cursor, references }, signal)\nBoth TUI and GUI call these before dispatching a submitted prompt.\n\n## ToolDef shape\n\\`\\`\\`ts\nctx.registerTool('my_tool', {\n spec: { name: 'my_tool', description: '...', inputSchema: { type: 'object', properties: {} } },\n isConcurrencySafe: true, // default false (barrier/write); true = read-only, fans out in parallel\n async execute(args) { return 'result' },\n})\n\\`\\`\\`\n\n## Invariants\n- The folder name MUST equal \\`name\\`, or the loader rejects the extension.\n- Optional metadata lives in \\`extension.json\\` or \\`package.json#zidane\\`; unsupported \\`apiVersion\\` is rejected.\n- Export as \\`default\\` (or a named \\`extension\\` export).\n- Register ONLY inside \\`setup\\` — calls after it resolves are dropped (logger.warn).\n- A throw in \\`setup\\` is caught and shown on the extension's Settings row; the rest of boot continues.\n- Discovery order, first per name wins: project \\`.agents\\` → project \\`.zidane\\` → \\`~/.agents\\` → \\`~/.zidane\\`.\n- \\`/reload\\` is a TRUE hot-reload: re-discover + re-run setup, and each extension's module graph is re-imported fresh — code edits (deep imports included) apply live. Module-level state resets; clean up external resources in \\`teardown\\`.\n\n## Distribution\n- Users install via Settings → Extensions → \\`ctrl+g\\` (source input + scope picker) — GitHub (\\`owner/repo[#ref][:sub/dir]\\`, tree URLs) or npm (\\`pkg[@version]\\`, exact versions / dist-tags).\n- Update / remove: Settings → Extensions, \\`ctrl+u\\` / \\`ctrl+x\\` on the focused row (update replays the recorded \\`.install.json\\` provenance in place, skipping when the recorded commit/version still matches the remote).\n- Shape your repo/package as a root \\`index.ts\\` (single extension) or \\`extensions/<name>/index.*\\` dirs (collection).\n- Reference packages to copy: \\`extensions/git-flow\\` in the zidane repo (zero-dep \\`/commit\\` command) and \\`extensions/headroom\\` (hooks + tool + config).\n- Declare runtime deps in \\`package.json#dependencies\\` — installed with bun/npm/… WITHOUT lifecycle scripts; don't rely on postinstall.\n- The installed folder is named from your exported \\`definition.name\\` — pick it to be folder-safe ([A-Za-z0-9_.-]).`\n\n/**\n * The inline `zidane-extension` skill. Carries the authoring reference IN its\n * body ({@link EXTENSION_AUTHORING_CHEATSHEET}) so it works in every host —\n * incl. compiled binaries where the on-disk docs aren't resolvable. The shipped\n * `EXTENSIONS.md` (prose long-form) is appended as a \"see also\" only when found\n * on disk. `source: 'inline'` (the `defineSkill` default) survives the\n * project-trust gate.\n */\nexport function buildZidaneExtensionSkill(opts: { cwd?: string } = {}): SkillConfig {\n const docsDir = resolveExtensionDocsDir(opts.cwd)\n const seeAlso = docsDir\n ? `\\n\\n---\\nFull prose reference on disk: ${join(docsDir, 'EXTENSIONS.md')}\\n`\n + 'Sibling docs cover related surfaces (ARCHITECTURE.md, CHAT.md, TUI.md, SKILL.md, HEADLESS.md, …).'\n : '\\n\\n---\\nFuller prose reference, when present: node_modules/zidane/docs/EXTENSIONS.md '\n + '(often absent in compiled binaries — the API above is authoritative).'\n return defineSkill({\n name: ZIDANE_EXTENSION_SKILL_NAME,\n description:\n 'Authoring or editing a zidane extension (a module calling defineExtension, under '\n + '.zidane/extensions/** or .agents/extensions/**). Carries the extension authoring reference.',\n instructions:\n `You are authoring / editing a zidane extension. Authoritative API reference:\\n\\n${\n EXTENSION_AUTHORING_CHEATSHEET\n }${seeAlso}`,\n })\n}\n\n/**\n * Inject the `zidane-extension` skill into an already-merged {@link SkillsConfig}.\n *\n * Call this on the FINAL merged skills object (after folding extension / preset\n * skills): `composePresets` is last-wins on `catalog`, so injecting earlier\n * would be silently dropped whenever an extension also contributes skills.\n *\n * Adds the skill to the catalog and, when an `enabled` allowlist is in force,\n * force-includes the name so the allowlist filter can't hide it (mirrors how\n * extension-contributed skill names are force-included). When skills are fully\n * disabled (`enabled === false`), the edit session still gets just this skill.\n */\nexport function withZidaneExtensionSkill(skills: SkillsConfig, opts: { cwd?: string } = {}): SkillsConfig {\n const skill = buildZidaneExtensionSkill(opts)\n const catalog = [...(skills.catalog ?? []), skill]\n const enabled = skills.enabled\n const nextEnabled: SkillsConfig['enabled']\n = enabled === undefined\n ? undefined\n : Array.isArray(enabled)\n ? (enabled.includes(ZIDANE_EXTENSION_SKILL_NAME) ? enabled : [...enabled, ZIDANE_EXTENSION_SKILL_NAME])\n : [ZIDANE_EXTENSION_SKILL_NAME]\n return {\n ...skills,\n catalog,\n ...(nextEnabled !== undefined ? { enabled: nextEnabled } : {}),\n }\n}\n","/**\n * Local loopback HTTP callback for OAuth 2.0 authorization code flows.\n *\n * Stands up a one-shot server on `127.0.0.1:<random>` that captures the\n * `?code=...` redirect from a browser-driven OAuth flow and resolves a\n * promise with the code. Used as the `redirectUrl` half of the MCP SDK's\n * `OAuthClientProvider` (the persistence half lives separately).\n *\n * Design:\n * - Loopback-only (`127.0.0.1`) — the OAuth spec treats `http://127.0.0.1:<port>`\n * as a public-client redirect URI per RFC 8252 §7.3. Browsers do NOT block it,\n * and Anthropic / OpenAI / Linear / GitHub all accept it.\n * - Random port (`port = 0`) — the OS picks an unused one. We read the actual\n * port back from `server.address()` after `listen()`.\n * - Single-shot — the first GET to `path` with a `code` (or `error`) wins;\n * subsequent requests get 404. The server keeps listening (in case the user\n * hits \"back\" and re-authorizes), so callers must `close()` once they have\n * the code or have given up.\n * - Abort-aware — wiring an external `AbortSignal` rejects the promise and\n * closes the server immediately. Required for the TUI's \"esc cancels login\"\n * UX.\n * - No HTML framework — a single inline `<html>` string keeps this isolated\n * from any UI dependency.\n */\n\nimport type { AddressInfo } from 'node:net'\nimport { createServer } from 'node:http'\n\n/**\n * Result of a successful callback. `state` is forwarded verbatim from the\n * query string — callers verify it against their pre-flight value to defend\n * against CSRF (the MCP SDK does this internally when it controls `state`).\n */\nexport interface OAuthCallbackResult {\n code: string\n state?: string\n}\n\nexport interface OAuthCallbackHandle {\n /**\n * Full URI to register with the authorization server, e.g.\n * `http://127.0.0.1:51823/callback`. Stable for the lifetime of the\n * handle.\n */\n redirectUri: string\n /**\n * Resolves with `{ code, state }` on a successful callback. Rejects with:\n * - The OAuth-spec `error` field (`access_denied`, `server_error`, ...)\n * when the authorization server redirects with `?error=...`.\n * - `'OAuth callback aborted'` when the external `AbortSignal` fires.\n * - `'OAuth callback server closed'` when `close()` is called before any\n * callback arrives.\n *\n * Single-shot — only the first matching request resolves the promise.\n */\n promise: Promise<OAuthCallbackResult>\n /**\n * Idempotent shutdown. Safe to call from a `finally` block whether the\n * flow succeeded, failed, or was aborted. Resolves once the server stops\n * accepting connections.\n */\n close: () => Promise<void>\n}\n\nexport interface OAuthCallbackOptions {\n /** Cancels the flow — rejects `promise` and closes the server. */\n signal?: AbortSignal\n /**\n * Path component the authorization server should redirect to. Defaults\n * to `/callback`. Useful when matching a pre-registered URI that uses a\n * different path.\n */\n path?: string\n /**\n * Override the loopback host. Defaults to `127.0.0.1`. Don't bind to\n * `0.0.0.0` here — the OAuth code is a one-time secret and the server\n * would otherwise accept it from any host on the LAN.\n */\n host?: string\n /**\n * Override the port. Defaults to `0` (OS-assigned). Pin to a fixed port\n * only when the authorization server requires a pre-registered redirect\n * URI; the random-port path is preferred so concurrent flows don't clash.\n */\n port?: number\n}\n\nconst DEFAULT_PATH = '/callback'\nconst DEFAULT_HOST = '127.0.0.1'\n\nconst SUCCESS_HTML = `<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Logged in</title>\n<style>body{font:14px/1.5 -apple-system,system-ui,sans-serif;margin:6rem auto;max-width:28rem;text-align:center;color:#1d1d1f}.ok{color:#1f8a4c;font-weight:600}</style>\n</head><body>\n<p class=\"ok\">Logged in.</p>\n<p>You can close this tab and return to the terminal.</p>\n</body></html>`\n\nfunction errorHtml(message: string): string {\n // No interpolation into HTML attributes — message goes only inside <p> text\n // where the SAMEORIGIN browser context is rendering. Escape angle brackets\n // and ampersands defensively anyway: a malicious authorization server could\n // theoretically craft an `error_description` containing markup, and we\n // don't want stored XSS even in a one-shot loopback page.\n const escaped = message\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n return `<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Login failed</title>\n<style>body{font:14px/1.5 -apple-system,system-ui,sans-serif;margin:6rem auto;max-width:28rem;text-align:center;color:#1d1d1f}.err{color:#c43c2c;font-weight:600}</style>\n</head><body>\n<p class=\"err\">Login failed.</p>\n<p>${escaped}</p>\n<p>You can close this tab and return to the terminal.</p>\n</body></html>`\n}\n\n/**\n * Start a one-shot OAuth callback server. The returned handle's `redirectUri`\n * should be passed to the authorization server as the `redirect_uri` query\n * parameter; `promise` resolves once the user finishes the browser flow.\n *\n * Always `await handle.close()` in a `finally` block — even on success, the\n * server stays open until told to shut down (so it can serve the\n * \"you can close this tab\" page).\n */\nexport async function startOAuthCallback(\n opts: OAuthCallbackOptions = {},\n): Promise<OAuthCallbackHandle> {\n const path = opts.path ?? DEFAULT_PATH\n const host = opts.host ?? DEFAULT_HOST\n const port = opts.port ?? 0\n\n if (!path.startsWith('/'))\n throw new Error(`OAuth callback path must start with \"/\" (got: ${JSON.stringify(path)})`)\n\n if (opts.signal?.aborted)\n throw new Error('OAuth callback aborted')\n\n let resolveResult: (value: OAuthCallbackResult) => void\n let rejectResult: (error: Error) => void\n const promise = new Promise<OAuthCallbackResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n // Attach a default no-op catch so a rejection without a consumer doesn't\n // raise an unhandled-rejection warning. Callers that DO `await promise`\n // still receive the rejection — Promises fan out to all listeners.\n promise.catch(() => {})\n\n let settled = false\n const resolveOnce = (value: OAuthCallbackResult) => {\n if (settled)\n return\n settled = true\n resolveResult(value)\n }\n const rejectOnce = (error: Error) => {\n if (settled)\n return\n settled = true\n rejectResult(error)\n }\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${host}`)\n if (url.pathname !== path) {\n res.writeHead(404, { 'content-type': 'text/plain' })\n res.end('Not Found')\n return\n }\n\n // `no-store` prevents the browser from replaying the page (with the\n // now-spent code in its URL bar) when the user hits back, refreshes,\n // or restores the tab from history. The code is a one-time secret.\n const htmlHeaders = {\n 'content-type': 'text/html; charset=utf-8',\n 'cache-control': 'no-store',\n }\n\n const error = url.searchParams.get('error')\n if (error) {\n const desc = url.searchParams.get('error_description') ?? error\n res.writeHead(400, htmlHeaders)\n res.end(errorHtml(desc))\n rejectOnce(new Error(`OAuth authorization failed: ${desc}`))\n return\n }\n\n const code = url.searchParams.get('code')\n if (!code) {\n // No code, no error — likely a stray probe. Serve a minimal page,\n // don't resolve. The browser will eventually arrive with the real\n // redirect, or the caller will time out via signal.\n res.writeHead(400, { 'content-type': 'text/plain' })\n res.end('Missing \"code\" query parameter.')\n return\n }\n\n const state = url.searchParams.get('state') ?? undefined\n res.writeHead(200, htmlHeaders)\n res.end(SUCCESS_HTML)\n resolveOnce({ code, state })\n })\n\n // Surface socket errors that arrive before the request handler — e.g. EADDRINUSE\n // on a pinned port, or an early TLS-style probe that the parser rejects.\n server.on('error', (err) => {\n rejectOnce(err instanceof Error ? err : new Error(String(err)))\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n server.off('error', reject)\n resolve()\n })\n })\n\n const addr = server.address() as AddressInfo | null\n if (!addr || typeof addr === 'string') {\n server.close()\n throw new Error('OAuth callback server did not bind to a TCP port')\n }\n\n // `closeServer` and `onAbort` reference each other — pre-declare both so\n // either ordering reads cleanly and the lint doesn't trip on the cycle.\n let closing: Promise<void> | undefined\n let closeServer: () => Promise<void>\n const onAbort = () => {\n rejectOnce(new Error('OAuth callback aborted'))\n void closeServer()\n }\n closeServer = (): Promise<void> => {\n if (closing)\n return closing\n closing = new Promise<void>((resolve) => {\n // `close()` on a Node http server waits for in-flight requests to drain.\n // The flow has already settled (or is being aborted), so we also call\n // `closeAllConnections()` to drop keep-alive sockets immediately — a\n // browser keeps the connection open after the success page, which would\n // otherwise hang the close for the keep-alive timeout (~5s).\n const anyServer = server as { closeAllConnections?: () => void }\n anyServer.closeAllConnections?.()\n server.close(() => {\n opts.signal?.removeEventListener('abort', onAbort)\n // If neither a callback nor an abort happened before close(), reject\n // pending awaits so callers don't hang. Tag the rejection as\n // 'aborted' when the signal already fired — Bun fires the abort\n // listener via a microtask, so server.close() may resolve first\n // even though semantically the abort came first.\n if (opts.signal?.aborted)\n rejectOnce(new Error('OAuth callback aborted'))\n else\n rejectOnce(new Error('OAuth callback server closed'))\n resolve()\n })\n })\n return closing\n }\n opts.signal?.addEventListener('abort', onAbort, { once: true })\n\n return {\n redirectUri: `http://${host}:${addr.port}${path}`,\n promise,\n close: closeServer,\n }\n}\n","/**\n * Interactive OAuth login orchestrator for one MCP server.\n *\n * Composes the three pieces shipped separately:\n * - `startOAuthCallback` (`./oauth-callback`) — local loopback HTTP\n * listener that catches the `?code=...` redirect.\n * - `McpOAuthProvider` (`./oauth-provider`) — SDK adapter that persists\n * tokens / client info via an injected `McpCredentialStore`.\n * - The MCP SDK's transport `authProvider` + `finishAuth` plumbing —\n * `client.connect()` triggers the SDK to call `redirectToAuthorization`\n * (which opens the browser); we wait for the loopback callback to\n * deliver the code, hand it to `transport.finishAuth`, and reconnect.\n *\n * Returns once tokens are persisted. Caller decides whether to immediately\n * reconnect the server (re-run `connectMcpServers` / `agent.warmup()`) or\n * defer to the next session activation. The returned `tools` array is\n * provided as a convenience — callers that want the connection live in\n * this call rather than rebuilding can wire them in directly.\n */\n\nimport type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js'\nimport type { Hookable } from 'hookable'\nimport type { AgentHooks } from '../agent'\nimport type { McpServerConfig } from '../types'\nimport type { OAuthCallbackHandle } from './oauth-callback'\nimport type { McpCredentialStore } from './oauth-provider'\nimport { startOAuthCallback } from './oauth-callback'\nimport { isOAuthTokenRejectionError, McpOAuthProvider } from './oauth-provider'\nimport { sseToJsonFetchIfNeeded } from './sse-to-json-fetch'\nimport { createTolerantClient } from './tolerant-client'\n\nexport interface LoginMcpServerOptions {\n /** Persistence — same store the bootstrap path reads from. */\n store: McpCredentialStore\n /**\n * Invoked with the authorization URL once it's ready. Hosts typically\n * (a) emit `mcp:auth:url` for the TUI, and (b) call `tryOpenBrowser`.\n * The URL is identical to the one passed to the `mcp:auth:url` hook\n * fired automatically — this callback is a synchronous hook for callers\n * that don't want to wire the agent hook machinery.\n */\n onAuthorizationUrl?: (url: URL) => void | Promise<void>\n /** Cancels the flow (esc / close modal / SIGINT). */\n signal?: AbortSignal\n /** Agent hooks. The flow emits `mcp:auth:url`/`success`/`error` when wired. */\n hooks?: Hookable<AgentHooks>\n /** Override `client_name` shown on consent screens. Default: 'zidane'. */\n clientName?: string\n /** Override the requested OAuth scope. */\n scope?: string\n /**\n * Override the loopback callback path. Default: `/callback`. Useful only\n * for servers that pinned a different path during registration.\n */\n callbackPath?: string\n /**\n * Maximum time to wait for the user to complete the browser flow, in ms.\n * The user can also cancel via `signal`. Default: 5 minutes.\n */\n timeoutMs?: number\n}\n\nexport interface LoginMcpServerResult {\n /** Stored OAuth tokens after a successful exchange. */\n tokens: NonNullable<ReturnType<McpOAuthProvider['tokens']>>\n /**\n * Upstream tool descriptors discovered after re-connecting with the new\n * tokens. Already filtered by the server's `enabledTools` / `disabledTools`\n * is NOT applied here — that's a bootstrap concern. Hosts that want filtering\n * should pass the result through `connectMcpServers` rebuild on the next\n * session activation rather than reusing this list verbatim.\n */\n tools: Array<{ name: string, description?: string | null, inputSchema?: unknown }>\n}\n\nconst DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60_000\n\n/**\n * Run the full interactive OAuth flow for `config`. Only supports `sse` and\n * `streamable-http` transports — `stdio` MCP servers don't speak OAuth.\n *\n * Throws on:\n * - Wrong transport.\n * - Abort signal.\n * - Browser-side error (user denied, server rejected, etc.).\n * - Code exchange failure.\n * - Post-exchange connect failure.\n *\n * Always closes the loopback callback server before returning, success or\n * failure.\n */\nexport async function loginMcpServer(\n config: McpServerConfig,\n options: LoginMcpServerOptions,\n): Promise<LoginMcpServerResult> {\n if (config.transport !== 'sse' && config.transport !== 'streamable-http')\n throw new Error(`MCP OAuth: cannot login for transport \"${config.transport}\" — only sse / streamable-http are supported`)\n if (!config.url)\n throw new Error(`MCP OAuth: server \"${config.name}\" is missing a url`)\n\n const hooks = options.hooks\n\n let callback: OAuthCallbackHandle | undefined\n try {\n callback = await startOAuthCallback({\n signal: options.signal,\n path: options.callbackPath,\n })\n\n const handle = callback\n const provider = new McpOAuthProvider({\n name: config.name,\n store: options.store,\n redirectUri: handle.redirectUri,\n clientName: options.clientName,\n scope: options.scope,\n onAuthorizationUrl: async (url) => {\n await hooks?.callHook('mcp:auth:url', { name: config.name, url: url.toString() })\n await options.onAuthorizationUrl?.(url)\n },\n })\n\n let transport = await createInteractiveTransport(config, provider)\n const client = await createTolerantClient({ name: 'zidane', version: '1.0.0' })\n\n // First connect → SDK has no tokens, so it calls\n // `provider.redirectToAuthorization(url)` (which routes to our\n // `onAuthorizationUrl`), then throws `UnauthorizedError`. This is the\n // expected path — we catch and wait on the loopback for the code.\n //\n // With STALE tokens stored, the SDK first attempts a refresh instead —\n // and when the refresh token itself is dead, `auth()` rethrows the\n // token-endpoint rejection (`InvalidGrantError`) WITHOUT opening the\n // browser. Wipe the dead tokens and retry once: the tokenless retry\n // routes straight to the authorization redirect. Without this, a\n // revoked refresh token made the panel re-login itself fail — the one\n // flow that's supposed to recover from dead credentials.\n let needsAuth = false\n for (let attempt = 0; ; attempt++) {\n try {\n await client.connect(transport)\n break\n }\n catch (err) {\n if (isUnauthorizedError(err)) {\n needsAuth = true\n break\n }\n if (attempt === 0 && isOAuthTokenRejectionError(err)) {\n await provider.invalidateCredentials('tokens')\n await transport.close().catch(() => {})\n transport = await createInteractiveTransport(config, provider)\n continue\n }\n await client.close().catch(() => {})\n throw err\n }\n }\n\n if (needsAuth) {\n const { code } = await raceLoginCallback(handle, options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS, options.signal)\n // SDK exchanges code → tokens; provider.saveTokens persists them.\n await (transport as { finishAuth: (code: string) => Promise<void> }).finishAuth(code)\n // Reconnect with a FRESH transport. The previous one is already in\n // the \"started\" state from the failed connect — reusing it throws\n // \"StreamableHTTPClientTransport already started!\" inside\n // `transport.start()`. The SDK's canonical example\n // (`simpleOAuthClient.js`) uses the same pattern: recurse with a\n // new transport, reuse the client. Close the stale transport\n // first so its abort controllers + sockets don't leak.\n await transport.close().catch(() => {})\n const freshTransport = await createInteractiveTransport(config, provider)\n await client.connect(freshTransport)\n }\n\n const { tools } = await client.listTools()\n await client.close()\n\n const tokens = provider.tokens()\n if (!tokens)\n throw new Error(`MCP OAuth: login for \"${config.name}\" returned no tokens (server may have rejected the exchange silently)`)\n\n await hooks?.callHook('mcp:auth:success', { name: config.name })\n return { tokens, tools }\n }\n catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n await hooks?.callHook('mcp:auth:error', { name: config.name, error })\n throw error\n }\n finally {\n await callback?.close()\n }\n}\n\n/**\n * Build an `sse` / `streamable-http` transport pre-wired with `authProvider`.\n * Mirrors the bootstrap-side `createTransport` shape but inlined here so the\n * login flow doesn't depend on the bootstrap module's private export.\n */\nasync function createInteractiveTransport(config: McpServerConfig, authProvider: OAuthClientProvider) {\n if (config.transport === 'sse') {\n const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js')\n return new SSEClientTransport(new URL(config.url!), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n authProvider,\n })\n }\n // streamable-http\n const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js')\n return new StreamableHTTPClientTransport(new URL(config.url!), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n fetch: sseToJsonFetchIfNeeded(),\n authProvider,\n })\n}\n\nfunction isUnauthorizedError(err: unknown): boolean {\n if (!err || typeof err !== 'object')\n return false\n const e = err as { name?: string, message?: string, constructor?: { name?: string } }\n if (e.name === 'UnauthorizedError' || e.constructor?.name === 'UnauthorizedError')\n return true\n return typeof e.message === 'string' && e.message.toLowerCase().startsWith('unauthorized')\n}\n\n/**\n * Wait on the callback handle, with a hard timeout AND honor the external\n * abort signal. Unlike `callback.promise` alone, this provides a deterministic\n * failure mode for \"user opened the browser then walked away\" — the modal\n * doesn't hang forever waiting for a redirect that may never come.\n */\nasync function raceLoginCallback(\n handle: OAuthCallbackHandle,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): Promise<{ code: string, state?: string }> {\n if (signal?.aborted)\n throw new Error('OAuth login aborted')\n let timer: ReturnType<typeof setTimeout> | undefined\n let onAbort: (() => void) | undefined\n try {\n return await new Promise<{ code: string, state?: string }>((resolve, reject) => {\n timer = setTimeout(\n () => reject(new Error(`OAuth login timed out after ${timeoutMs}ms`)),\n timeoutMs,\n )\n if (signal) {\n onAbort = () => reject(new Error('OAuth login aborted'))\n signal.addEventListener('abort', onAbort, { once: true })\n }\n handle.promise.then(resolve, reject)\n })\n }\n finally {\n if (timer)\n clearTimeout(timer)\n if (signal && onAbort)\n signal.removeEventListener('abort', onAbort)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"login-B5nMPF8w.js","names":[],"sources":["../src/extension-authoring.ts","../src/mcp/oauth-callback.ts","../src/mcp/login.ts"],"sourcesContent":["/**\n * Host glue for the \"edit / create extension\" authoring flow (TUI + GUI).\n *\n * Pure, renderer-neutral helpers consumed by the hosts — deliberately kept OUT\n * of `src/extensions/**` (the extension loader / registry core) so the\n * authoring UX can never entangle with discovery / registration. Imports only\n * the skills lib and node builtins.\n *\n * - {@link extensionScaffold} — minimal `index.ts` for a new extension.\n * - {@link resolveExtensionDocsDir} — locate the shipped `docs/` directory.\n * - {@link buildZidaneExtensionSkill} — the inline docs skill.\n * - {@link withZidaneExtensionSkill} — inject it into a `SkillsConfig`.\n * - {@link EXTENSION_EDIT_METADATA_KEY} / {@link ZIDANE_EXTENSION_SKILL_NAME}\n * — constants shared by both hosts.\n */\nimport type { SkillConfig, SkillsConfig } from './skills'\nimport { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { defineSkill } from './skills'\n\n/**\n * Session-metadata key marking an \"edit / create extension\" session. The value\n * is an {@link ExtensionEditMarker}. Both hosts stamp it at session creation so\n * the agent build can scope the docs skill to exactly these sessions (and it\n * survives reload because metadata is persisted).\n */\nexport const EXTENSION_EDIT_METADATA_KEY = 'zidane.extensionEdit'\n\n/** Name of the inline docs skill auto-activated in extension edit sessions. */\nexport const ZIDANE_EXTENSION_SKILL_NAME = 'zidane-extension'\n\n/** Per-edit-session marker persisted on `session.metadata[EXTENSION_EDIT_METADATA_KEY]`. */\nexport interface ExtensionEditMarker {\n /** Absolute path to the extension's directory (the session's cwd). */\n dir: string\n}\n\n/**\n * Minimal valid extension module for a freshly-created extension. `name` MUST\n * equal the folder name or the loader rejects it (see `src/extensions/discovery`).\n * Does nothing by default — the author registers contributions via `ctx.*`\n * inside `setup`; the auto-activated docs skill guides them from there.\n */\nexport function extensionScaffold(name: string): string {\n return `import { defineExtension } from 'zidane'\n\n/**\n * ${name} — a zidane extension.\n *\n * Register tools / hooks / skills / MCP servers / subagents / config / themes /\n * agents / keybindings via the \\`ctx\\` surface inside \\`setup\\`.\n *\n * Authoring reference: activate the \\`${ZIDANE_EXTENSION_SKILL_NAME}\\` skill — it carries\n * the full \\`ctx\\` API + invariants and is available whenever you open this\n * folder in zidane (or run \\`zidane\\` from inside it).\n */\nexport default defineExtension({\n name: '${name}',\n setup(ctx) {\n // e.g. ctx.registerTool('${name}_hello', {\n // spec: { name: '${name}_hello', description: 'say hi', inputSchema: { type: 'object', properties: {} } },\n // isConcurrencySafe: true,\n // async execute() { return 'hello from ${name}' },\n // })\n },\n})\n`\n}\n\n/**\n * Locate the shipped `docs/` directory (`docs/EXTENSIONS.md` + siblings).\n *\n * The docs ship via `package.json` `files`, so an installed consumer has\n * `<root>/node_modules/zidane/docs` and the repo itself has `<repo>/docs`.\n * Returns the first existing candidate, or `null` (the skill then falls back to\n * the literal `node_modules/zidane/docs` hint, which the model's file tools can\n * still attempt from cwd).\n */\nexport function resolveExtensionDocsDir(cwd: string = process.cwd()): string | null {\n const candidates: string[] = []\n\n // 1) The installed (or self-linked) zidane package, via its package.json\n // (exposed through `exports[\"./package.json\"]`).\n try {\n const req = createRequire(import.meta.url)\n candidates.push(join(dirname(req.resolve('zidane/package.json')), 'docs'))\n }\n catch {\n // No resolvable package (compiled binary / odd layout) — fall through.\n }\n\n // 2) Relative to this module: `dist/extension-authoring.js` -> `../docs`, or\n // walking up from `src/` when running from source.\n try {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 6; i++) {\n if (existsSync(join(dir, 'docs', 'EXTENSIONS.md'))) {\n candidates.push(join(dir, 'docs'))\n break\n }\n dir = dirname(dir)\n }\n }\n catch {\n // `import.meta.url` is virtual under `bun build --compile` — fall through.\n }\n\n // 3) cwd-relative — the project the author is actually editing.\n candidates.push(join(cwd, 'node_modules', 'zidane', 'docs'))\n\n for (const candidate of candidates) {\n if (existsSync(join(candidate, 'EXTENSIONS.md')))\n return candidate\n }\n return null\n}\n\n/** Entry-file probe order for an extension dir (mirrors the loader's discovery). */\nconst EXTENSION_ENTRY_FILES = ['index.ts', 'index.tsx', 'index.mjs', 'index.js'] as const\n\n/**\n * If `cwd` sits inside a zidane extension, return that extension's root dir,\n * else `null`. Mirrors the discovery layout\n * `<scope>/.{agents,zidane}/extensions/<name>/` — the root is the `<name>` dir\n * (parent `extensions`, grandparent `.agents` / `.zidane`) holding an entry\n * file. Walks up from `cwd`, so the nearest enclosing extension wins. Lets the\n * hosts surface the authoring skill for a plain `zidane` launched from an\n * extension folder, not just sessions opened through the edit/create flow.\n */\nexport function extensionDirForCwd(cwd: string = process.cwd()): string | null {\n let dir = resolve(cwd)\n // Bounded walk to the filesystem root (the `parent === dir` guard is the real\n // terminator; the cap is just belt-and-braces against pathological inputs).\n for (let i = 0; i < 64; i++) {\n const parent = dirname(dir)\n if (\n basename(parent) === 'extensions'\n && (basename(dirname(parent)) === '.agents' || basename(dirname(parent)) === '.zidane')\n && EXTENSION_ENTRY_FILES.some(f => existsSync(join(dir, f)))\n ) {\n return dir\n }\n if (parent === dir)\n break\n dir = parent\n }\n return null\n}\n\n/**\n * The authoring reference embedded into the skill body. Kept INLINE (not a\n * filesystem path) on purpose: a `bun build --compile` TUI binary has no\n * resolvable `node_modules/zidane/docs`, no real `import.meta.url`, and the\n * edited extension's own cwd has no `node_modules` — so a path reference dead-\n * ends there. The model gets the API verbatim on activation regardless of host.\n *\n * Mirrors `ExtensionContext` (src/extensions/types.ts) — keep in sync when the\n * `ctx.*` surface changes.\n */\nconst EXTENSION_AUTHORING_CHEATSHEET = `## defineExtension\n\nA zidane extension is a module at \\`<scope>/.{agents,zidane}/extensions/<name>/index.{ts,tsx,mjs,js}\\`\nthat default-exports \\`defineExtension({ ... })\\`. It runs in-process in the host (TUI / GUI / SDK).\n\n\\`\\`\\`ts\nimport { defineExtension } from 'zidane'\n\nexport default defineExtension({\n name: 'my-ext', // MUST equal the folder name\n apiVersion: 1, // optional; omitted means v1\n version: '0.1.0', // optional — shown in Settings → Extensions\n displayName: 'My Ext', // optional UI label\n description: 'what it does',\n capabilities: ['tools'], // optional descriptive manifest labels\n permissions: [], // optional descriptive labels; not a sandbox\n setup(ctx) { /* register everything here; may be async */ },\n teardown() {}, // optional, reserved (no hot-reload yet)\n})\n\\`\\`\\`\n\nZero-import form — required INSIDE compiled binaries, which can't \\`import 'zidane'\\` at runtime:\n\\`\\`\\`ts\nimport type { ExtensionContext } from 'zidane' // type-only: erased at runtime\nexport default {\n name: 'my-ext',\n setup(ctx: ExtensionContext) { /* ... */ },\n}\n\\`\\`\\`\n\n## ctx surface (call everything inside setup)\n\nIdentity / utilities:\n- ctx.name / ctx.version / ctx.dir / ctx.scope ('project' | 'user' | 'inline' | 'builtin')\n- ctx.logger — Logger namespaced \\`extension:<name>\\`\n- ctx.config — read THIS extension's config, default-first: \\`ctx.config.get(key)\\`\n- ctx.paths — cwd/projectRoot/dataDir/cacheDir/configDir/stateDir\n- ctx.storage.path(scope, ...segments) — extension-scoped storage path\n- ctx.session — JSON-only per-session state: get / set / delete\n\nRenderer-agnostic registration:\n- ctx.registerTool(name, toolDef)\n- ctx.registerHook(event, handler) — an AgentHooks event; fires on the PARENT agent (use child:* for subagents)\n- ctx.registerMcpServer(config)\n- ctx.registerSkill(skillConfig) — a defineSkill() shape\n- ctx.registerCompletionProvider(provider) — single-char '/' '@' '!' trigger\n- ctx.tui.notify(text, { tone? }) — one-shot transcript line (info/warn/error); buffered pre-mount\n- ctx.tui.setStatus(text | null, { loader?, timeout? }) — single dim status line (transcript-tail slot); loader glyph, auto-clear ms\n- ctx.tui.setBanner(lines | null, { timeout? }) — short block above the prompt (stacked with the todo indicator); auto-clear ms\n- ctx.submitPrompt(text, { delivery? }) — submit as the user: 'auto' (run-or-queue), 'steer', 'followUp'; false when detached\n- ctx.registerToolPolicy({ tools?, decide }) — gate tool calls: allow / { block } / { patch } (patches re-validated by the loop)\n- ctx.registerToolResultTransform(fn) — middleware over finished tool results (chained)\n- ctx.registerContextTransform(fn) — rewrite wire messages before each provider call\n- ctx.registerPromptTransform(fn) — transform or consume submitted prompts (after / commands, before skills)\n- ctx.runtime / ctx.sessions — late-bound host controls: model()/thinking()/setThinking(), sessions list/switch/create\n- ctx.appendNote(blocks) — durable display-only transcript note (command-output block vocabulary)\n- ctx.workspace.exec/readFile/writeFile/listFiles/fileSize — shell + files through the SESSION'S execution context (sandbox-correct; host child_process silently targets the wrong filesystem under docker/e2b). Detached ⇒ rejects; guard with \\`await ctx.workspace.available()\\`.\n- ctx.tui.registerToolRenderer({ tools?, render }) — custom view for tool-result rows; return null to fall through to the default. View-layer only: never persisted, error-bounded per row, TUI-scoped.\n- ctx.tui.registerRenderer(id, render) + emit/appendNote \\`custom: { renderer, data }\\` blocks — custom components in the transcript. \\`data\\` must be JSON-safe (it persists); the block's \\`text\\` is the MANDATORY markdown fallback (disabled extension, headless host, GUI, renderer throw). appendNote auto-prefixes bare ids; command emit needs \\`<ext>/<id>\\`.\n- Renderer components: import \\`react\\` / \\`@opentui/react\\` BARE (never as your own dependency) — the host maps them to its live instances at load time, so hooks work. Async data: render() stays sync; return a component that fetches with useState/useEffect.\n- Renderer async caching: \\`useSessionState(id, initial)\\` (per-row, session-persisted — rehydrates on reload) + \\`useRowVisible()\\` (latched viewport gate) from \\`zidane/tui\\` — fetch once, only when scrolled in.\n- ctx.registerCommand(command) — a '/<name>' workflow (handler or steps[]); step ctx: emit (local output),\n runAgent (interactive sub-run), generateData (silent zod/JSON-Schema JSON),\n session? (read-only turns/runs view), interaction? (confirm / askUser forms /\n presentPlan approval — both optional; guard for bare hosts)\n- ctx.registerTheme(theme)\n- ctx.registerAgent(profile) — extra agent profile in the picker\n- ctx.registerSubagent(def) — spawnable subagent (the spawn tool's subagent_type)\n- ctx.registerSubagentOverride(name, fn) — edit/delete an existing subagent\n- ctx.registerProvider(descriptor)\n- ctx.registerSystemPromptFragment(text)\n- ctx.registerContextBreakdownSection(fn) — render extension-owned rows in the context panel\n- ctx.registerContextPanelSection(section) — richer context panel section with rows/load\n- ctx.registerToolResultMetadata(registration) — project namespaced tool-result metadata into context\n- ctx.registerRunTransform(fn) — sync rewrite of agent.run options\n- ctx.registerBehaviorTransform(fn) — sync rewrite of resolved behavior\n- ctx.registerProviderMiddleware(fn) — wrap provider instances\n- ctx.registerToolCatalogTransform(fn) — shape/hide/rename tools before disclosure/execution\n- ctx.registerMcpConfigTransform(fn) — rewrite MCP server configs before connect\n- ctx.registerSkillPolicy(policy) — auto-activate skills by run context\n- ctx.registerConfigCategory(category)\n- ctx.registerConfigItem([categoryId,] item) — typed setting; supports scope/onChange metadata\n\nTUI-only (ctx.tui.* — silently ignored on non-TUI hosts):\n- ctx.tui.registerKeybinding(binding)\n- ctx.tui.registerFooterHint(hint)\n- ctx.tui.registerModal(modal) — keep UI lazy: \\`node: () => import('./panel')\\`\n\nGUI-only:\n- ctx.gui.registerPanel(panel) — collected, not rendered yet\n\nCompletion providers may also implement submit hooks:\n- resolveReferences(refs, ctx, signal)\n- onSubmit({ text, cursor, references }, signal)\nBoth TUI and GUI call these before dispatching a submitted prompt.\n\n## ToolDef shape\n\\`\\`\\`ts\nctx.registerTool('my_tool', {\n spec: { name: 'my_tool', description: '...', inputSchema: { type: 'object', properties: {} } },\n isConcurrencySafe: true, // default false (barrier/write); true = read-only, fans out in parallel\n async execute(args) { return 'result' },\n})\n\\`\\`\\`\n\n## Invariants\n- The folder name MUST equal \\`name\\`, or the loader rejects the extension.\n- Optional metadata lives in \\`extension.json\\` or \\`package.json#zidane\\`; unsupported \\`apiVersion\\` is rejected.\n- Export as \\`default\\` (or a named \\`extension\\` export).\n- Register ONLY inside \\`setup\\` — calls after it resolves are dropped (logger.warn).\n- A throw in \\`setup\\` is caught and shown on the extension's Settings row; the rest of boot continues.\n- Discovery order, first per name wins: project \\`.agents\\` → project \\`.zidane\\` → \\`~/.agents\\` → \\`~/.zidane\\`.\n- \\`/reload\\` is a TRUE hot-reload: re-discover + re-run setup, and each extension's module graph is re-imported fresh — code edits (deep imports included) apply live. Module-level state resets; clean up external resources in \\`teardown\\`.\n\n## Distribution\n- Users install via Settings → Extensions → \\`ctrl+g\\` (source input + scope picker) — GitHub (\\`owner/repo[#ref][:sub/dir]\\`, tree URLs) or npm (\\`pkg[@version]\\`, exact versions / dist-tags).\n- Update / remove: Settings → Extensions, \\`ctrl+u\\` / \\`ctrl+x\\` on the focused row (update replays the recorded \\`.install.json\\` provenance in place, skipping when the recorded commit/version still matches the remote).\n- Shape your repo/package as a root \\`index.ts\\` (single extension) or \\`extensions/<name>/index.*\\` dirs (collection).\n- Reference packages to copy: \\`extensions/git-flow\\` in the zidane repo (zero-dep \\`/commit\\` command) and \\`extensions/headroom\\` (hooks + tool + config).\n- Declare runtime deps in \\`package.json#dependencies\\` — installed with bun/npm/… WITHOUT lifecycle scripts; don't rely on postinstall.\n- The installed folder is named from your exported \\`definition.name\\` — pick it to be folder-safe ([A-Za-z0-9_.-]).`\n\n/**\n * The inline `zidane-extension` skill. Carries the authoring reference IN its\n * body ({@link EXTENSION_AUTHORING_CHEATSHEET}) so it works in every host —\n * incl. compiled binaries where the on-disk docs aren't resolvable. The shipped\n * `EXTENSIONS.md` (prose long-form) is appended as a \"see also\" only when found\n * on disk. `source: 'inline'` (the `defineSkill` default) survives the\n * project-trust gate.\n */\nexport function buildZidaneExtensionSkill(opts: { cwd?: string } = {}): SkillConfig {\n const docsDir = resolveExtensionDocsDir(opts.cwd)\n const seeAlso = docsDir\n ? `\\n\\n---\\nFull prose reference on disk: ${join(docsDir, 'EXTENSIONS.md')}\\n`\n + 'Sibling docs cover related surfaces (ARCHITECTURE.md, CHAT.md, TUI.md, SKILL.md, HEADLESS.md, …).'\n : '\\n\\n---\\nFuller prose reference, when present: node_modules/zidane/docs/EXTENSIONS.md '\n + '(often absent in compiled binaries — the API above is authoritative).'\n return defineSkill({\n name: ZIDANE_EXTENSION_SKILL_NAME,\n description:\n 'Authoring or editing a zidane extension (a module calling defineExtension, under '\n + '.zidane/extensions/** or .agents/extensions/**). Carries the extension authoring reference.',\n instructions:\n `You are authoring / editing a zidane extension. Authoritative API reference:\\n\\n${\n EXTENSION_AUTHORING_CHEATSHEET\n }${seeAlso}`,\n })\n}\n\n/**\n * Inject the `zidane-extension` skill into an already-merged {@link SkillsConfig}.\n *\n * Call this on the FINAL merged skills object (after folding extension / preset\n * skills): `composePresets` is last-wins on `catalog`, so injecting earlier\n * would be silently dropped whenever an extension also contributes skills.\n *\n * Adds the skill to the catalog and, when an `enabled` allowlist is in force,\n * force-includes the name so the allowlist filter can't hide it (mirrors how\n * extension-contributed skill names are force-included). When skills are fully\n * disabled (`enabled === false`), the edit session still gets just this skill.\n */\nexport function withZidaneExtensionSkill(skills: SkillsConfig, opts: { cwd?: string } = {}): SkillsConfig {\n const skill = buildZidaneExtensionSkill(opts)\n const catalog = [...(skills.catalog ?? []), skill]\n const enabled = skills.enabled\n const nextEnabled: SkillsConfig['enabled']\n = enabled === undefined\n ? undefined\n : Array.isArray(enabled)\n ? (enabled.includes(ZIDANE_EXTENSION_SKILL_NAME) ? enabled : [...enabled, ZIDANE_EXTENSION_SKILL_NAME])\n : [ZIDANE_EXTENSION_SKILL_NAME]\n return {\n ...skills,\n catalog,\n ...(nextEnabled !== undefined ? { enabled: nextEnabled } : {}),\n }\n}\n","/**\n * Local loopback HTTP callback for OAuth 2.0 authorization code flows.\n *\n * Stands up a one-shot server on `127.0.0.1:<random>` that captures the\n * `?code=...` redirect from a browser-driven OAuth flow and resolves a\n * promise with the code. Used as the `redirectUrl` half of the MCP SDK's\n * `OAuthClientProvider` (the persistence half lives separately).\n *\n * Design:\n * - Loopback-only (`127.0.0.1`) — the OAuth spec treats `http://127.0.0.1:<port>`\n * as a public-client redirect URI per RFC 8252 §7.3. Browsers do NOT block it,\n * and Anthropic / OpenAI / Linear / GitHub all accept it.\n * - Random port (`port = 0`) — the OS picks an unused one. We read the actual\n * port back from `server.address()` after `listen()`.\n * - Single-shot — the first GET to `path` with a `code` (or `error`) wins;\n * subsequent requests get 404. The server keeps listening (in case the user\n * hits \"back\" and re-authorizes), so callers must `close()` once they have\n * the code or have given up.\n * - Abort-aware — wiring an external `AbortSignal` rejects the promise and\n * closes the server immediately. Required for the TUI's \"esc cancels login\"\n * UX.\n * - No HTML framework — a single inline `<html>` string keeps this isolated\n * from any UI dependency.\n */\n\nimport type { AddressInfo } from 'node:net'\nimport { createServer } from 'node:http'\n\n/**\n * Result of a successful callback. `state` is forwarded verbatim from the\n * query string — callers verify it against their pre-flight value to defend\n * against CSRF (the MCP SDK does this internally when it controls `state`).\n */\nexport interface OAuthCallbackResult {\n code: string\n state?: string\n}\n\nexport interface OAuthCallbackHandle {\n /**\n * Full URI to register with the authorization server, e.g.\n * `http://127.0.0.1:51823/callback`. Stable for the lifetime of the\n * handle.\n */\n redirectUri: string\n /**\n * Resolves with `{ code, state }` on a successful callback. Rejects with:\n * - The OAuth-spec `error` field (`access_denied`, `server_error`, ...)\n * when the authorization server redirects with `?error=...`.\n * - `'OAuth callback aborted'` when the external `AbortSignal` fires.\n * - `'OAuth callback server closed'` when `close()` is called before any\n * callback arrives.\n *\n * Single-shot — only the first matching request resolves the promise.\n */\n promise: Promise<OAuthCallbackResult>\n /**\n * Idempotent shutdown. Safe to call from a `finally` block whether the\n * flow succeeded, failed, or was aborted. Resolves once the server stops\n * accepting connections.\n */\n close: () => Promise<void>\n}\n\nexport interface OAuthCallbackOptions {\n /** Cancels the flow — rejects `promise` and closes the server. */\n signal?: AbortSignal\n /**\n * Path component the authorization server should redirect to. Defaults\n * to `/callback`. Useful when matching a pre-registered URI that uses a\n * different path.\n */\n path?: string\n /**\n * Override the loopback host. Defaults to `127.0.0.1`. Don't bind to\n * `0.0.0.0` here — the OAuth code is a one-time secret and the server\n * would otherwise accept it from any host on the LAN.\n */\n host?: string\n /**\n * Override the port. Defaults to `0` (OS-assigned). Pin to a fixed port\n * only when the authorization server requires a pre-registered redirect\n * URI; the random-port path is preferred so concurrent flows don't clash.\n */\n port?: number\n}\n\nconst DEFAULT_PATH = '/callback'\nconst DEFAULT_HOST = '127.0.0.1'\n\nconst SUCCESS_HTML = `<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Logged in</title>\n<style>body{font:14px/1.5 -apple-system,system-ui,sans-serif;margin:6rem auto;max-width:28rem;text-align:center;color:#1d1d1f}.ok{color:#1f8a4c;font-weight:600}</style>\n</head><body>\n<p class=\"ok\">Logged in.</p>\n<p>You can close this tab and return to the terminal.</p>\n</body></html>`\n\nfunction errorHtml(message: string): string {\n // No interpolation into HTML attributes — message goes only inside <p> text\n // where the SAMEORIGIN browser context is rendering. Escape angle brackets\n // and ampersands defensively anyway: a malicious authorization server could\n // theoretically craft an `error_description` containing markup, and we\n // don't want stored XSS even in a one-shot loopback page.\n const escaped = message\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n return `<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Login failed</title>\n<style>body{font:14px/1.5 -apple-system,system-ui,sans-serif;margin:6rem auto;max-width:28rem;text-align:center;color:#1d1d1f}.err{color:#c43c2c;font-weight:600}</style>\n</head><body>\n<p class=\"err\">Login failed.</p>\n<p>${escaped}</p>\n<p>You can close this tab and return to the terminal.</p>\n</body></html>`\n}\n\n/**\n * Start a one-shot OAuth callback server. The returned handle's `redirectUri`\n * should be passed to the authorization server as the `redirect_uri` query\n * parameter; `promise` resolves once the user finishes the browser flow.\n *\n * Always `await handle.close()` in a `finally` block — even on success, the\n * server stays open until told to shut down (so it can serve the\n * \"you can close this tab\" page).\n */\nexport async function startOAuthCallback(\n opts: OAuthCallbackOptions = {},\n): Promise<OAuthCallbackHandle> {\n const path = opts.path ?? DEFAULT_PATH\n const host = opts.host ?? DEFAULT_HOST\n const port = opts.port ?? 0\n\n if (!path.startsWith('/'))\n throw new Error(`OAuth callback path must start with \"/\" (got: ${JSON.stringify(path)})`)\n\n if (opts.signal?.aborted)\n throw new Error('OAuth callback aborted')\n\n let resolveResult: (value: OAuthCallbackResult) => void\n let rejectResult: (error: Error) => void\n const promise = new Promise<OAuthCallbackResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n // Attach a default no-op catch so a rejection without a consumer doesn't\n // raise an unhandled-rejection warning. Callers that DO `await promise`\n // still receive the rejection — Promises fan out to all listeners.\n promise.catch(() => {})\n\n let settled = false\n const resolveOnce = (value: OAuthCallbackResult) => {\n if (settled)\n return\n settled = true\n resolveResult(value)\n }\n const rejectOnce = (error: Error) => {\n if (settled)\n return\n settled = true\n rejectResult(error)\n }\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${host}`)\n if (url.pathname !== path) {\n res.writeHead(404, { 'content-type': 'text/plain' })\n res.end('Not Found')\n return\n }\n\n // `no-store` prevents the browser from replaying the page (with the\n // now-spent code in its URL bar) when the user hits back, refreshes,\n // or restores the tab from history. The code is a one-time secret.\n const htmlHeaders = {\n 'content-type': 'text/html; charset=utf-8',\n 'cache-control': 'no-store',\n }\n\n const error = url.searchParams.get('error')\n if (error) {\n const desc = url.searchParams.get('error_description') ?? error\n res.writeHead(400, htmlHeaders)\n res.end(errorHtml(desc))\n rejectOnce(new Error(`OAuth authorization failed: ${desc}`))\n return\n }\n\n const code = url.searchParams.get('code')\n if (!code) {\n // No code, no error — likely a stray probe. Serve a minimal page,\n // don't resolve. The browser will eventually arrive with the real\n // redirect, or the caller will time out via signal.\n res.writeHead(400, { 'content-type': 'text/plain' })\n res.end('Missing \"code\" query parameter.')\n return\n }\n\n const state = url.searchParams.get('state') ?? undefined\n res.writeHead(200, htmlHeaders)\n res.end(SUCCESS_HTML)\n resolveOnce({ code, state })\n })\n\n // Surface socket errors that arrive before the request handler — e.g. EADDRINUSE\n // on a pinned port, or an early TLS-style probe that the parser rejects.\n server.on('error', (err) => {\n rejectOnce(err instanceof Error ? err : new Error(String(err)))\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n server.off('error', reject)\n resolve()\n })\n })\n\n const addr = server.address() as AddressInfo | null\n if (!addr || typeof addr === 'string') {\n server.close()\n throw new Error('OAuth callback server did not bind to a TCP port')\n }\n\n // `closeServer` and `onAbort` reference each other — pre-declare both so\n // either ordering reads cleanly and the lint doesn't trip on the cycle.\n let closing: Promise<void> | undefined\n let closeServer: () => Promise<void>\n const onAbort = () => {\n rejectOnce(new Error('OAuth callback aborted'))\n void closeServer()\n }\n closeServer = (): Promise<void> => {\n if (closing)\n return closing\n closing = new Promise<void>((resolve) => {\n // `close()` on a Node http server waits for in-flight requests to drain.\n // The flow has already settled (or is being aborted), so we also call\n // `closeAllConnections()` to drop keep-alive sockets immediately — a\n // browser keeps the connection open after the success page, which would\n // otherwise hang the close for the keep-alive timeout (~5s).\n const anyServer = server as { closeAllConnections?: () => void }\n anyServer.closeAllConnections?.()\n server.close(() => {\n opts.signal?.removeEventListener('abort', onAbort)\n // If neither a callback nor an abort happened before close(), reject\n // pending awaits so callers don't hang. Tag the rejection as\n // 'aborted' when the signal already fired — Bun fires the abort\n // listener via a microtask, so server.close() may resolve first\n // even though semantically the abort came first.\n if (opts.signal?.aborted)\n rejectOnce(new Error('OAuth callback aborted'))\n else\n rejectOnce(new Error('OAuth callback server closed'))\n resolve()\n })\n })\n return closing\n }\n opts.signal?.addEventListener('abort', onAbort, { once: true })\n\n return {\n redirectUri: `http://${host}:${addr.port}${path}`,\n promise,\n close: closeServer,\n }\n}\n","/**\n * Interactive OAuth login orchestrator for one MCP server.\n *\n * Composes the three pieces shipped separately:\n * - `startOAuthCallback` (`./oauth-callback`) — local loopback HTTP\n * listener that catches the `?code=...` redirect.\n * - `McpOAuthProvider` (`./oauth-provider`) — SDK adapter that persists\n * tokens / client info via an injected `McpCredentialStore`.\n * - The MCP SDK's transport `authProvider` + `finishAuth` plumbing —\n * `client.connect()` triggers the SDK to call `redirectToAuthorization`\n * (which opens the browser); we wait for the loopback callback to\n * deliver the code, hand it to `transport.finishAuth`, and reconnect.\n *\n * Returns once tokens are persisted. Caller decides whether to immediately\n * reconnect the server (re-run `connectMcpServers` / `agent.warmup()`) or\n * defer to the next session activation. The returned `tools` array is\n * provided as a convenience — callers that want the connection live in\n * this call rather than rebuilding can wire them in directly.\n */\n\nimport type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js'\nimport type { Hookable } from 'hookable'\nimport type { AgentHooks } from '../agent'\nimport type { McpServerConfig } from '../types'\nimport type { OAuthCallbackHandle } from './oauth-callback'\nimport type { McpCredentialStore } from './oauth-provider'\nimport { startOAuthCallback } from './oauth-callback'\nimport { isOAuthTokenRejectionError, McpOAuthProvider } from './oauth-provider'\nimport { sseToJsonFetchIfNeeded } from './sse-to-json-fetch'\nimport { createTolerantClient } from './tolerant-client'\n\nexport interface LoginMcpServerOptions {\n /** Persistence — same store the bootstrap path reads from. */\n store: McpCredentialStore\n /**\n * Invoked with the authorization URL once it's ready. Hosts typically\n * (a) emit `mcp:auth:url` for the TUI, and (b) call `tryOpenBrowser`.\n * The URL is identical to the one passed to the `mcp:auth:url` hook\n * fired automatically — this callback is a synchronous hook for callers\n * that don't want to wire the agent hook machinery.\n */\n onAuthorizationUrl?: (url: URL) => void | Promise<void>\n /** Cancels the flow (esc / close modal / SIGINT). */\n signal?: AbortSignal\n /** Agent hooks. The flow emits `mcp:auth:url`/`success`/`error` when wired. */\n hooks?: Hookable<AgentHooks>\n /** Override `client_name` shown on consent screens. Default: 'zidane'. */\n clientName?: string\n /** Override the requested OAuth scope. */\n scope?: string\n /**\n * Override the loopback callback path. Default: `/callback`. Useful only\n * for servers that pinned a different path during registration.\n */\n callbackPath?: string\n /**\n * Maximum time to wait for the user to complete the browser flow, in ms.\n * The user can also cancel via `signal`. Default: 5 minutes.\n */\n timeoutMs?: number\n}\n\nexport interface LoginMcpServerResult {\n /** Stored OAuth tokens after a successful exchange. */\n tokens: NonNullable<ReturnType<McpOAuthProvider['tokens']>>\n /**\n * Upstream tool descriptors discovered after re-connecting with the new\n * tokens. Already filtered by the server's `enabledTools` / `disabledTools`\n * is NOT applied here — that's a bootstrap concern. Hosts that want filtering\n * should pass the result through `connectMcpServers` rebuild on the next\n * session activation rather than reusing this list verbatim.\n */\n tools: Array<{ name: string, description?: string | null, inputSchema?: unknown }>\n}\n\nconst DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60_000\n\n/**\n * Run the full interactive OAuth flow for `config`. Only supports `sse` and\n * `streamable-http` transports — `stdio` MCP servers don't speak OAuth.\n *\n * Throws on:\n * - Wrong transport.\n * - Abort signal.\n * - Browser-side error (user denied, server rejected, etc.).\n * - Code exchange failure.\n * - Post-exchange connect failure.\n *\n * Always closes the loopback callback server before returning, success or\n * failure.\n */\nexport async function loginMcpServer(\n config: McpServerConfig,\n options: LoginMcpServerOptions,\n): Promise<LoginMcpServerResult> {\n if (config.transport !== 'sse' && config.transport !== 'streamable-http')\n throw new Error(`MCP OAuth: cannot login for transport \"${config.transport}\" — only sse / streamable-http are supported`)\n if (!config.url)\n throw new Error(`MCP OAuth: server \"${config.name}\" is missing a url`)\n\n const hooks = options.hooks\n\n let callback: OAuthCallbackHandle | undefined\n try {\n callback = await startOAuthCallback({\n signal: options.signal,\n path: options.callbackPath,\n })\n\n const handle = callback\n const provider = new McpOAuthProvider({\n name: config.name,\n store: options.store,\n redirectUri: handle.redirectUri,\n clientName: options.clientName,\n scope: options.scope,\n onAuthorizationUrl: async (url) => {\n await hooks?.callHook('mcp:auth:url', { name: config.name, url: url.toString() })\n await options.onAuthorizationUrl?.(url)\n },\n })\n\n let transport = await createInteractiveTransport(config, provider)\n const client = await createTolerantClient({ name: 'zidane', version: '1.0.0' })\n\n // First connect → SDK has no tokens, so it calls\n // `provider.redirectToAuthorization(url)` (which routes to our\n // `onAuthorizationUrl`), then throws `UnauthorizedError`. This is the\n // expected path — we catch and wait on the loopback for the code.\n //\n // With STALE tokens stored, the SDK first attempts a refresh instead —\n // and when the refresh token itself is dead, `auth()` rethrows the\n // token-endpoint rejection (`InvalidGrantError`) WITHOUT opening the\n // browser. Wipe the dead tokens and retry once: the tokenless retry\n // routes straight to the authorization redirect. Without this, a\n // revoked refresh token made the panel re-login itself fail — the one\n // flow that's supposed to recover from dead credentials.\n let needsAuth = false\n for (let attempt = 0; ; attempt++) {\n try {\n await client.connect(transport)\n break\n }\n catch (err) {\n if (isUnauthorizedError(err)) {\n needsAuth = true\n break\n }\n if (attempt === 0 && isOAuthTokenRejectionError(err)) {\n await provider.invalidateCredentials('tokens')\n await transport.close().catch(() => {})\n transport = await createInteractiveTransport(config, provider)\n continue\n }\n await client.close().catch(() => {})\n throw err\n }\n }\n\n if (needsAuth) {\n const { code } = await raceLoginCallback(handle, options.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS, options.signal)\n // SDK exchanges code → tokens; provider.saveTokens persists them.\n await (transport as { finishAuth: (code: string) => Promise<void> }).finishAuth(code)\n // Reconnect with a FRESH transport. The previous one is already in\n // the \"started\" state from the failed connect — reusing it throws\n // \"StreamableHTTPClientTransport already started!\" inside\n // `transport.start()`. The SDK's canonical example\n // (`simpleOAuthClient.js`) uses the same pattern: recurse with a\n // new transport, reuse the client. Close the stale transport\n // first so its abort controllers + sockets don't leak.\n await transport.close().catch(() => {})\n const freshTransport = await createInteractiveTransport(config, provider)\n await client.connect(freshTransport)\n }\n\n const { tools } = await client.listTools()\n await client.close()\n\n const tokens = provider.tokens()\n if (!tokens)\n throw new Error(`MCP OAuth: login for \"${config.name}\" returned no tokens (server may have rejected the exchange silently)`)\n\n await hooks?.callHook('mcp:auth:success', { name: config.name })\n return { tokens, tools }\n }\n catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n await hooks?.callHook('mcp:auth:error', { name: config.name, error })\n throw error\n }\n finally {\n await callback?.close()\n }\n}\n\n/**\n * Build an `sse` / `streamable-http` transport pre-wired with `authProvider`.\n * Mirrors the bootstrap-side `createTransport` shape but inlined here so the\n * login flow doesn't depend on the bootstrap module's private export.\n */\nasync function createInteractiveTransport(config: McpServerConfig, authProvider: OAuthClientProvider) {\n if (config.transport === 'sse') {\n const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js')\n return new SSEClientTransport(new URL(config.url!), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n authProvider,\n })\n }\n // streamable-http\n const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js')\n return new StreamableHTTPClientTransport(new URL(config.url!), {\n requestInit: config.headers ? { headers: config.headers } : undefined,\n fetch: sseToJsonFetchIfNeeded(),\n authProvider,\n })\n}\n\nfunction isUnauthorizedError(err: unknown): boolean {\n if (!err || typeof err !== 'object')\n return false\n const e = err as { name?: string, message?: string, constructor?: { name?: string } }\n if (e.name === 'UnauthorizedError' || e.constructor?.name === 'UnauthorizedError')\n return true\n return typeof e.message === 'string' && e.message.toLowerCase().startsWith('unauthorized')\n}\n\n/**\n * Wait on the callback handle, with a hard timeout AND honor the external\n * abort signal. Unlike `callback.promise` alone, this provides a deterministic\n * failure mode for \"user opened the browser then walked away\" — the modal\n * doesn't hang forever waiting for a redirect that may never come.\n */\nasync function raceLoginCallback(\n handle: OAuthCallbackHandle,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): Promise<{ code: string, state?: string }> {\n if (signal?.aborted)\n throw new Error('OAuth login aborted')\n let timer: ReturnType<typeof setTimeout> | undefined\n let onAbort: (() => void) | undefined\n try {\n return await new Promise<{ code: string, state?: string }>((resolve, reject) => {\n timer = setTimeout(\n () => reject(new Error(`OAuth login timed out after ${timeoutMs}ms`)),\n timeoutMs,\n )\n if (signal) {\n onAbort = () => reject(new Error('OAuth login aborted'))\n signal.addEventListener('abort', onAbort, { once: true })\n }\n handle.promise.then(resolve, reject)\n })\n }\n finally {\n if (timer)\n clearTimeout(timer)\n if (signal && onAbort)\n signal.removeEventListener('abort', onAbort)\n }\n}\n"],"mappings":"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"}