@cline/shared 0.0.69 → 0.0.70

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.
@@ -51,7 +51,18 @@ export type AiSdkMessage = {
51
51
  role: "system" | "user" | "assistant" | "tool";
52
52
  content: string | AiSdkMessagePart[];
53
53
  };
54
- export declare function toAiSdkToolResultOutput(output: unknown, isError?: boolean, mediaState?: MediaBudgetState): Record<string, unknown>;
54
+ export declare function toAiSdkToolResultOutput(output: unknown, isError?: boolean, mediaState?: MediaBudgetState, options?: {
55
+ supportsImages?: boolean;
56
+ }): Record<string, unknown>;
55
57
  export declare function formatMessagesForAiSdk(systemContent: string | AiSdkMessagePart[] | undefined, messages: readonly AiSdkFormatterMessage[], options?: {
56
58
  assistantToolCallArgKey?: "args" | "input";
59
+ /**
60
+ * Whether the target model advertises image input. When false, image
61
+ * parts (user-attached and inside tool results) are substituted with
62
+ * `IMAGE_UNSUPPORTED_PLACEHOLDER` text so the request stays valid for
63
+ * text-only models while the model still learns an image was there.
64
+ * Defaults to true. The substitution happens here at request-build
65
+ * time only — stored conversation history is never mutated.
66
+ */
67
+ supportsImages?: boolean;
57
68
  }): AiSdkMessage[];
@@ -10,7 +10,7 @@ export type GatewayModelCapability = "text" | "tools" | "reasoning" | "prompt-ca
10
10
  export type GatewayPromptCacheStrategy = "anthropic-automatic";
11
11
  export declare const USAGE_COST_DISPLAYS: readonly ["show", "hide", "subscription"];
12
12
  export type GatewayUsageCostDisplay = (typeof USAGE_COST_DISPLAYS)[number];
13
- export type GatewayPromptCacheFormat = "anthropic-cache-control";
13
+ export type GatewayPromptCacheFormat = "anthropic-cache-control" | "bedrock-cache-point";
14
14
  export type GatewayReasoningFormat = "anthropic-thinking" | "glm-thinking" | "minimax-thinking";
15
15
  export type GatewayModelRoute = {
16
16
  matcher: "anthropic-compatible";
@@ -1,4 +1,10 @@
1
1
  export declare const IMAGE_OMITTED_PLACEHOLDER = "[media omitted: invalid or exceeds size limit]";
2
+ /**
3
+ * Substituted for image content at request-build time when the target model
4
+ * does not advertise image input. The stored conversation history keeps the
5
+ * real image, so switching to an image-capable model restores it.
6
+ */
7
+ export declare const IMAGE_UNSUPPORTED_PLACEHOLDER = "[Image attached \u2014 this model cannot view images]";
2
8
  export declare const SUPPORTED_IMAGE_MEDIA_TYPES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp"];
3
9
  export declare const DEFAULT_MAX_IMAGE_BASE64_BYTES: number;
4
10
  export declare const DEFAULT_MAX_IMAGE_ENCODED_BYTES: number;
@@ -11,14 +11,14 @@ import type { WorkspaceInfo } from "../session/workspace";
11
11
  * mode.
12
12
  */
13
13
  export declare const MODE_TAG_INSTRUCTIONS = "# Plan / Act Modes\n\nUser messages arrive wrapped in a <user_input mode=\"...\"> tag. The mode attribute is the interaction mode the user was in when they sent that message: \"plan\" means plan-mode constraints applied (explore, analyze, and align on a plan -- no edits or state-changing commands), while \"act\" (or \"yolo\") means implementation was allowed. If the mode attribute changes between messages, the user switched modes -- the newest message's mode is what governs right now, regardless of what earlier messages allowed. A <mode_notice> block inside a message marks exactly when such a switch happened.";
14
+ export declare const PLAN_MODE_INSTRUCTIONS = "# Plan Mode\n\nYou are in Plan mode. Your role is to explore, analyze, and plan -- not to execute.\n\n- Read files, search the codebase, and gather context to understand the problem\n- Ask clarifying questions when requirements are ambiguous\n- Present your plan as a structured outline with clear steps\n- Explain tradeoffs between different approaches when they exist\n- Do NOT edit files, write code, run destructive commands, or make any changes\n- Do NOT implement anything -- focus on understanding and alignment first\n\nThe run_commands tool remains available in plan mode strictly for read-only inspection -- listing files, searching (grep), reading configs, inspecting git history and diffs, checking tool versions, and the like. Never use it to change anything: no creating, modifying, or deleting files, no writing scripts that make changes, and no state-changing commands (installs, migrations, database or schema changes, container commands that mutate state, etc.). File-editing commands (rm/mv/cp, in-place edits like sed -i, output redirection to files outside /tmp, git commands that change the working tree, package installs) are hard-blocked in plan mode: they are not executed and return a tool error instead, so do not attempt them. If the task requires a mutation, put it in the plan; it happens only after the user switches to act mode.\n\nOnce the user has reviewed your plan and explicitly approved it in a follow-up message, use the switch_to_act_mode tool to switch to act mode and begin implementation. Calling switch_to_act_mode immediately starts execution, so never call it in the same turn you present a plan and never treat the original task request as approval -- end your turn after presenting the plan and wait for the user's response.";
14
15
  /**
15
- * Plan-mode behavioral contract, appended when the session mode is "plan".
16
- * run_commands intentionally stays available in plan mode -- it is essential
17
- * for read-only investigation -- so the contract must spell out that it is
18
- * inspection-only there; the mitigation for plan-mode mutations is prompting
19
- * plus mode-switch notices, not tool removal.
16
+ * Plan-mode contract for hosts that do NOT expose the switch_to_act_mode tool
17
+ * (the VS Code extension, matching the legacy extension's behavior). The model
18
+ * must direct the user to flip the Plan/Act toggle instead of calling a tool
19
+ * that does not exist in its toolset.
20
20
  */
21
- export declare const PLAN_MODE_INSTRUCTIONS = "# Plan Mode\n\nYou are in Plan mode. Your role is to explore, analyze, and plan -- not to execute.\n\n- Read files, search the codebase, and gather context to understand the problem\n- Ask clarifying questions when requirements are ambiguous\n- Present your plan as a structured outline with clear steps\n- Explain tradeoffs between different approaches when they exist\n- Do NOT edit files, write code, run destructive commands, or make any changes\n- Do NOT implement anything -- focus on understanding and alignment first\n\nThe run_commands tool remains available in plan mode strictly for read-only inspection -- listing files, searching (grep), reading configs, inspecting git history and diffs, checking tool versions, and the like. Never use it to change anything: no creating, modifying, or deleting files, no writing scripts that make changes, and no state-changing commands (installs, migrations, database or schema changes, container commands that mutate state, etc.). If the task requires a mutation, put it in the plan; it happens only after the user switches to act mode.\n\nOnce the user has reviewed your plan and explicitly approved it in a follow-up message, use the switch_to_act_mode tool to switch to act mode and begin implementation. Calling switch_to_act_mode immediately starts execution, so never call it in the same turn you present a plan and never treat the original task request as approval -- end your turn after presenting the plan and wait for the user's response.";
21
+ export declare const PLAN_MODE_INSTRUCTIONS_MANUAL_SWITCH = "# Plan Mode\n\nYou are in Plan mode. Your role is to explore, analyze, and plan -- not to execute.\n\n- Read files, search the codebase, and gather context to understand the problem\n- Ask clarifying questions when requirements are ambiguous\n- Present your plan as a structured outline with clear steps\n- Explain tradeoffs between different approaches when they exist\n- Do NOT edit files, write code, run destructive commands, or make any changes\n- Do NOT implement anything -- focus on understanding and alignment first\n\nThe run_commands tool remains available in plan mode strictly for read-only inspection -- listing files, searching (grep), reading configs, inspecting git history and diffs, checking tool versions, and the like. Never use it to change anything: no creating, modifying, or deleting files, no writing scripts that make changes, and no state-changing commands (installs, migrations, database or schema changes, container commands that mutate state, etc.). File-editing commands (rm/mv/cp, in-place edits like sed -i, output redirection to files outside /tmp, git commands that change the working tree, package installs) are hard-blocked in plan mode: they are not executed and return a tool error instead, so do not attempt them. If the task requires a mutation, put it in the plan; it happens only after the user switches to act mode.\n\nOnce you have presented your plan, end your turn and wait for the user's response. You do NOT have the ability to switch to act mode yourself -- the user must do it manually with the Plan/Act toggle once they are satisfied with the plan. If the task requires tools that are only available in act mode, ask the user to \"toggle to Act mode\" (use those words).";
22
22
  export declare function processWorkspaceInfo(info: WorkspaceInfo): string;
23
23
  /**
24
24
  * Options for building the Cline system prompt.
@@ -39,5 +39,13 @@ export interface ClineSystemPromptOptions extends Omit<WorkspaceContext, "rootPa
39
39
  overridePrompt?: string;
40
40
  /** Provider ID — used to gate Cline-specific metadata injection */
41
41
  providerId?: string;
42
+ /**
43
+ * Whether the host exposes the switch_to_act_mode tool in plan mode.
44
+ * Defaults to true (CLI behavior). Hosts that require the user to flip the
45
+ * Plan/Act toggle themselves (the VS Code extension) set this to false so
46
+ * the plan-mode contract directs the model to ask the user instead of
47
+ * calling a tool that is not in its toolset.
48
+ */
49
+ planModeSwitchTool?: boolean;
42
50
  }
43
51
  export declare function buildClineSystemPrompt(options: ClineSystemPromptOptions): string;
@@ -123,6 +123,7 @@ export type EnterpriseStatusResponse = EnterpriseSyncResponse;
123
123
  export interface ProviderModel {
124
124
  id: string;
125
125
  name: string;
126
+ contextWindow?: number;
126
127
  supportsAttachments?: boolean;
127
128
  supportsVision?: boolean;
128
129
  supportsReasoning?: boolean;
@@ -1,10 +1,83 @@
1
1
  export declare const CLINE_RUN_AS_HUB_DAEMON_ENV = "CLINE_RUN_AS_HUB_DAEMON";
2
2
  export declare const CLINE_CONNECTOR_CLI_LAUNCH_ENV = "CLINE_CONNECTOR_CLI_LAUNCH";
3
+ export declare const CLINE_CONNECTOR_STARTING_INSTANCE_ENV = "CLINE_CONNECTOR_STARTING_INSTANCE";
4
+ export declare const CLINE_CONNECTOR_SUPERVISED_ENV = "CLINE_CONNECTOR_SUPERVISED";
3
5
  export interface ConnectorCliLaunchSpec {
4
6
  launcher: string;
5
7
  connectArgsPrefix: string[];
6
8
  cwd: string;
7
9
  }
10
+ /** Identifies one connector instance: an adapter channel plus its instance id. */
11
+ export interface ConnectorInstanceRef {
12
+ channel: string;
13
+ instanceId: string;
14
+ }
15
+ /**
16
+ * Take the daemon sentinel out of the environment, remembering its value.
17
+ *
18
+ * The sentinel selects which personality the shared CLI binary boots, so it must
19
+ * not outlive that decision: the hub daemon hosts session runtimes, and every
20
+ * process a session spawns - agent shell commands, MCP servers, hooks, plugin
21
+ * sandboxes - inherits its environment. An inherited sentinel makes each of
22
+ * those try to become a hub daemon instead of running the command, and they die
23
+ * on EADDRINUSE against the real hub. Observed as every `cline` invocation from
24
+ * a Slack connector agent failing, `cline --help` included, because the
25
+ * personality is chosen before any argument parsing.
26
+ *
27
+ * Call this once from an entrypoint, in place of {@link isHubDaemonProcess}.
28
+ * Spawn paths that deliberately start a daemon set the variable explicitly on
29
+ * the child environment, so they are unaffected.
30
+ */
31
+ export declare function claimHubDaemonProcess(env?: Record<string, string | undefined>): boolean;
32
+ /**
33
+ * Whether this process is the hub daemon.
34
+ *
35
+ * Reads the latch first so callers still get the right answer after
36
+ * {@link claimHubDaemonProcess} has scrubbed the environment - notably the
37
+ * guards that stop a daemon from spawning another daemon. An explicitly passed
38
+ * environment is always read verbatim.
39
+ */
8
40
  export declare function isHubDaemonProcess(env?: Record<string, string | undefined>): boolean;
9
41
  export declare function setConnectorCliLaunchSpec(spec: ConnectorCliLaunchSpec, env?: Record<string, string | undefined>): void;
42
+ /**
43
+ * Take the supervised-connector marker out of the environment, remembering it.
44
+ *
45
+ * Same hazard as {@link claimHubDaemonProcess}: a supervised connector hosts
46
+ * agent sessions, and everything they spawn — shell commands, MCP servers, hooks
47
+ * — inherits its environment. An inherited marker makes a nested `cline connect`
48
+ * think it is the process the hub is tracking, so it runs the connector in the
49
+ * foreground of that shell command instead of handing it to the hub.
50
+ *
51
+ * Call once from an entrypoint, in place of
52
+ * {@link isSupervisedConnectorProcess}. The supervisor sets the marker
53
+ * explicitly on the child environment, so it is unaffected.
54
+ */
55
+ export declare function claimSupervisedConnectorProcess(env?: Record<string, string | undefined>): boolean;
56
+ /**
57
+ * True in a connector process the hub supervisor launched.
58
+ *
59
+ * Such a process must run the connector itself rather than doing what a
60
+ * user-invoked background `connect` does — asking the hub to start it (which
61
+ * would loop straight back here) or spawning its own detached child and exiting
62
+ * (which would leave the supervisor holding a handle to a process that is
63
+ * already gone).
64
+ *
65
+ * Reads the latch first so callers still get the right answer after
66
+ * {@link claimSupervisedConnectorProcess} has scrubbed the environment. An
67
+ * explicitly passed environment is always read verbatim.
68
+ */
69
+ export declare function isSupervisedConnectorProcess(env?: Record<string, string | undefined>): boolean;
70
+ /**
71
+ * Announce the connector instance this process is in the middle of starting.
72
+ *
73
+ * A connector starts its own hub daemon, and the daemon then reconnects every
74
+ * persisted connector. The instance doing the starting is not yet registered as
75
+ * active when the daemon boots, so without this marker the daemon launches a
76
+ * second copy of it - two processes holding the same bot token. The daemon
77
+ * inherits this variable from the connector that spawned it, so it can tell
78
+ * "the connector that is bringing me up" apart from "a connector left over from
79
+ * a previous hub session", which genuinely does need restarting.
80
+ */
81
+ export declare function setStartingConnectorInstance(ref: ConnectorInstanceRef, env?: Record<string, string | undefined>): void;
82
+ export declare function readStartingConnectorInstance(env?: Record<string, string | undefined>): ConnectorInstanceRef | undefined;
10
83
  export declare function readConnectorCliLaunchSpec(env?: Record<string, string | undefined>): ConnectorCliLaunchSpec | undefined;
@@ -52,6 +52,11 @@ export interface CaptureTaskLifecycleEventInput {
52
52
  durationMs?: number;
53
53
  eventType?: string;
54
54
  error?: unknown;
55
+ /**
56
+ * Classification of `error` (e.g. context_window_exceeded), emitted as
57
+ * `error_class` alongside the normalized error fields.
58
+ */
59
+ errorClass?: string;
55
60
  messageLimit?: number;
56
61
  }
57
62
  export interface TelemetryMetadata {
@@ -89,9 +94,31 @@ export interface ITelemetryService {
89
94
  dispose(): Promise<void>;
90
95
  }
91
96
  export declare const SDK_ERROR_TELEMETRY_EVENT = "sdk.error";
97
+ /** Identical `sdk.error` emissions allowed per key per window. */
98
+ export declare const SDK_ERROR_RATE_LIMIT_MAX_PER_WINDOW = 5;
99
+ /** Suppression window for identical `sdk.error` emissions. */
100
+ export declare const SDK_ERROR_RATE_LIMIT_WINDOW_MS: number;
101
+ /**
102
+ * Clear per-process `sdk.error` rate-limit state (test isolation).
103
+ *
104
+ * @internal Exported only so package test suites can isolate the
105
+ * process-wide suppression state between tests; not a supported runtime API.
106
+ */
107
+ export declare function resetSdkErrorRateLimiterForTests(): void;
92
108
  export declare function captureAgentUnexpectedReasoningTokens(telemetry: ITelemetryService | undefined, input: CaptureAgentUnexpectedReasoningTokensInput): void;
93
109
  export declare function captureTaskLifecycleEvent(telemetry: ITelemetryService | undefined, input: CaptureTaskLifecycleEventInput): void;
94
- export declare function captureSdkError(telemetry: ITelemetryService | undefined, input: CaptureSdkErrorInput): void;
110
+ /**
111
+ * Report an SDK error, subject to the per-process volume cap on identical
112
+ * failures described above.
113
+ *
114
+ * Returns `true` when the failure is recorded — emitted, or counted toward
115
+ * `suppressed_count` by the volume cap — and `false` when telemetry is
116
+ * unavailable. Reporters that sit on a layer boundary forward the return
117
+ * value (see `errorReported` on the model stream's `finish` event) so outer
118
+ * layers know the failure is already accounted for and one underlying
119
+ * failure produces one event, not one per layer it propagates through.
120
+ */
121
+ export declare function captureSdkError(telemetry: ITelemetryService | undefined, input: CaptureSdkErrorInput): boolean;
95
122
  export declare function buildSdkErrorProperties(input: CaptureSdkErrorInput): TelemetryProperties;
96
123
  export declare function normalizeSdkError(error: unknown, messageLimit?: number, errorMessage?: string): TelemetryProperties;
97
124
  export interface OpenTelemetryClientConfig {
@@ -1,2 +1,2 @@
1
1
  export { resolveExistingFilePath } from "./path-resolution";
2
- export { AGENT_CONFIG_DIRECTORY_NAME, AGENTS_RULES_FILE_NAME, CLINE_CHAT_WORKSPACE_DIRECTORY_NAME, CLINE_CONNECTOR_SETTINGS_FILE_NAME, CLINE_MCP_SETTINGS_FILE_NAME, CLINE_WORKSPACES_DIRECTORY_NAME, type CronSpecsScope, discoverPluginModulePaths, ensureFileExists, ensureHookLogDir, ensureParentDir, HOOKS_CONFIG_DIRECTORY_NAME, isChatWorkspacePath, isPluginModulePath, type ResolveCronSpecsDirOptions, RULES_CONFIG_DIRECTORY_NAME, resolveAgentConfigSearchPaths, resolveAgentsConfigDirPath, resolveChatWorkspacePath, resolveClineDataDir, resolveClineDir, resolveConfiguredPluginModulePaths, resolveConnectorDataDir, resolveConnectorSettingsPath, resolveConnectorsDbPath, resolveCronDbPath, resolveCronEventsDir, resolveCronReportsDir, resolveCronSpecsDir, resolveDbDataDir, resolveDocumentsClineDirectoryPath, resolveDocumentsExtensionPath, resolveGlobalAgentsRulesPath, resolveGlobalCronSpecsDir, resolveGlobalSettingsPath, resolveHooksConfigSearchPaths, resolveMcpSettingsPath, resolvePluginConfigSearchPaths, resolvePluginModuleEntries, resolveProviderSettingsPath, resolveRulesConfigSearchPaths, resolveSessionDataDir, resolveSkillsConfigSearchPaths, resolveTeamDataDir, resolveWorkflowsConfigSearchPaths, resolveWorkspaceCronSpecsDir, SKILLS_CONFIG_DIRECTORY_NAME, setClineDir, setClineDirIfUnset, setHomeDir, setHomeDirIfUnset, WORKFLOWS_CONFIG_DIRECTORY_NAME, } from "./paths";
2
+ export { AGENT_CONFIG_DIRECTORY_NAME, AGENTS_RULES_FILE_NAME, CLINE_CHAT_WORKSPACE_DIRECTORY_NAME, CLINE_CONNECTOR_SETTINGS_FILE_NAME, CLINE_MCP_SETTINGS_FILE_NAME, CLINE_WORKSPACES_DIRECTORY_NAME, type CronSpecsScope, discoverPluginModulePaths, ensureFileExists, ensureHookLogDir, ensureParentDir, getPluginDisplayName, HOOKS_CONFIG_DIRECTORY_NAME, isChatWorkspacePath, isPluginModulePath, type ResolveCronSpecsDirOptions, RULES_CONFIG_DIRECTORY_NAME, resolveAgentConfigSearchPaths, resolveAgentsConfigDirPath, resolveChatWorkspacePath, resolveClineDataDir, resolveClineDir, resolveConfiguredPluginModulePaths, resolveConnectorDataDir, resolveConnectorLogPath, resolveConnectorSettingsPath, resolveConnectorsDbPath, resolveCronDbPath, resolveCronEventsDir, resolveCronReportsDir, resolveCronSpecsDir, resolveDbDataDir, resolveDocumentsClineDirectoryPath, resolveDocumentsExtensionPath, resolveGlobalAgentsRulesPath, resolveGlobalCronSpecsDir, resolveGlobalSettingsPath, resolveHooksConfigSearchPaths, resolveMcpSettingsPath, resolvePluginConfigSearchPaths, resolvePluginModuleEntries, resolveProviderSettingsPath, resolveRulesConfigSearchPaths, resolveSessionDataDir, resolveSkillsConfigSearchPaths, resolveTeamDataDir, resolveWorkflowsConfigSearchPaths, resolveWorkspaceCronSpecsDir, SKILLS_CONFIG_DIRECTORY_NAME, setClineDir, setClineDirIfUnset, setHomeDir, setHomeDirIfUnset, WORKFLOWS_CONFIG_DIRECTORY_NAME, } from "./paths";
@@ -1 +1 @@
1
- var KC=Object.defineProperty;var LC=(C)=>C;function MC(C,S){this[C]=LC.bind(null,S)}var iC=(C,S)=>{for(var _ in S)KC(C,_,{get:S[_],enumerable:!0,configurable:!0,set:MC.bind(S,_)})};import{existsSync as Y,readdirSync as vC}from"node:fs";import{basename as d,dirname as o,join as p}from"node:path";var FC=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g,WC=" ";function m(C){return C.normalize("NFC").replace(FC," ")}function YC(C){let S=d(C),_=S.replace(/ (AM|PM)\./gi,`${WC}$1.`);return _===S?C:p(o(C),_)}function DC(C){return C.normalize("NFD")}function l(C){return C.replace(/'/g,"’")}function RC(C){let S=o(C),_=m(d(C));try{for(let I of vC(S))if(m(I)===_)return p(S,I)}catch{}return}function qC(C){if(Y(C))return C;let S=YC(C);if(S!==C&&Y(S))return S;let _=DC(C);if(_!==C&&Y(_))return _;let I=l(C);if(I!==C&&Y(I))return I;let G=l(_);if(G!==_&&G!==I&&Y(G))return G;return RC(C)}import{appendFileSync as QC,existsSync as T,mkdirSync as J,readdirSync as ZC,readFileSync as $C,statSync as D}from"node:fs";import{homedir as AC}from"node:os";import{dirname as b,join as E,resolve as R}from"node:path";var Z="workspaces",$="chat";function s(C){let S=C.trim(),_=/^[A-Za-z]:[\\/]/.test(S)||S.startsWith("\\\\"),I=S.startsWith("/");if(!_&&!I)return!1;let G=S.split(_?/[\\/]+/:/\/+/).filter(Boolean),O=G.at(-1)??"",M=G.at(-2)??"",N=G.at(-3)??"";return(G.at(-4)??"")===".cline"&&N==="data"&&M==="workspaces"&&O==="chat"}var V=".clinerules",U=".cline",x=".agents",u="agents",A="hooks",X="skills",z="rules",B="workflows",P="plugins",k="AGENTS.md";function BC(){return E(K(),Z,$)}var c="cline_mcp_settings.json",n="settings.json";function XC(){let C=process?.env?.HOME?.trim();if(C&&C!=="~")return C;let S=process?.env?.USERPROFILE?.trim();if(S)return S;let _=process?.env?.HOMEDRIVE?.trim(),I=process?.env?.HOMEPATH?.trim();if(_&&I)return`${_}${I}`;let G=AC().trim();if(G&&G!=="~")return G;return"~"}var v=XC(),h=!1;function jC(C){let S=C.trim();if(!S)return;v=S,h=!0}function UC(C){if(h)return;let S=C.trim();if(!S)return;v=S}var j,r=!1;function gC(C){let S=C.trim();if(!S)return;j=S,r=!0}function zC(C){if(r)return;let S=C.trim();if(!S)return;j=S}function L(){if(j)return j;let C=process.env.CLINE_DIR?.trim();if(C)return C;return E(v,".cline")}function i(){return E(v,"Documents","Cline")}function Q(C){return E(i(),C)}function K(){let C=process.env.CLINE_DATA_DIR?.trim();if(C)return C;return E(L(),"data")}function HC(){let C=process.env.CLINE_SESSION_DATA_DIR?.trim();if(C)return C;return E(K(),"sessions")}function JC(){let C=process.env.CLINE_TEAM_DATA_DIR?.trim();if(C)return C;return E(K(),"teams")}function e(){let C=process.env.CLINE_CONNECTOR_DATA_DIR?.trim();if(C)return C;return E(K(),"connectors")}function bC(){let C=process.env.CLINE_CONNECTOR_SETTINGS_PATH?.trim();if(C)return C;return E(e(),n)}function y(){let C=process.env.CLINE_DB_DATA_DIR?.trim();if(C)return C;return E(K(),"db")}function VC(){let C=process.env.CLINE_CONNECTORS_DB_PATH?.trim();if(C)return C;return E(y(),"connectors.db")}function xC(){let C=process.env.CLINE_CRON_DB_PATH?.trim();if(C)return C;return E(y(),"cron.db")}function t(){return E(L(),"cron")}function H(C){return E(C,".cline","cron")}function w(C){if(typeof C==="string")return H(C);if(C?.cronSpecsDir?.trim())return C.cronSpecsDir.trim();if(C?.scope==="workspace"){let S=C.workspaceRoot?.trim();if(!S)throw Error("workspaceRoot is required for workspace cron scope");return H(S)}return t()}function uC(C){return E(w(C),"reports")}function kC(C){return E(w(C),"events")}function yC(){let C=process.env.CLINE_PROVIDER_SETTINGS_PATH?.trim();if(C)return C;return E(K(),"settings","providers.json")}function wC(){let C=process.env.CLINE_GLOBAL_SETTINGS_PATH?.trim();if(C)return C;return E(K(),"settings","global-settings.json")}function fC(){let C=process.env.CLINE_MCP_SETTINGS_PATH?.trim();if(C)return C;return E(K(),"settings",c)}function F(C){let S=new Set,_=[];for(let I of C){if(!I||S.has(I))continue;S.add(I),_.push(I)}return _}function mC(C){if(!C)return[];return[V,U,x].map((S)=>E(C,S,X))}function a(){return E(L(),u)}function lC(C){return F([C?E(C,U,u):"",a()])}function dC(C){let S=[Q("Hooks"),E(L(),A)];if(C)S.push(E(C,V,A),E(C,U,A));return F(S)}function oC(C){return F([...mC(C),E(L(),X),E(v,x,X)])}function CC(){return E(v,x,k)}function pC(C){let S=C?[E(C,V),E(C,U,z)]:[],_=C?[E(C,k)]:[];return F([..._,...S,CC(),E(L(),z),Q("Rules")])}function sC(C){return F([C?E(C,".clinerules",B):"",Q("Workflows"),E(L(),B),C?E(C,".cline",B):""])}function PC(C){return F([C?E(C,".cline",P):"",E(L(),P),Q("Plugins")])}var SC=new Set([".js",".ts"]),EC="package.json",cC=["index.ts","index.js"];function q(C){let S=C.lastIndexOf(".");if(S===-1)return!1;return SC.has(C.slice(S))}function _C(C){try{let S=JSON.parse($C(C,"utf8"));if(!S.cline||typeof S.cline!=="object")return null;return S.cline}catch{return null}}function GC(C){let S=C?.plugins;if(!Array.isArray(S))return[];return S.flatMap((_)=>_.paths??[])}function IC(C){let S=R(C);if(!T(S)||!D(S).isDirectory())return null;let _=E(S,EC);if(T(_)){let I=_C(_),G=GC(I).map((O)=>R(S,O)).filter((O)=>T(O)&&D(O).isFile()&&q(O));if(G.length>0)return G}for(let I of cC){let G=E(S,I);if(T(G)&&D(G).isFile())return[G]}return null}function OC(C){let S=R(C);if(!T(S))return[];let _=[],I=[S];while(I.length>0){let G=I.pop();if(!G)continue;let O;try{O=ZC(G,{withFileTypes:!0})}catch{continue}for(let M of O){let N=E(G,M.name);if(M.isDirectory()){let g=E(N,EC);if(T(g)){let TC=_C(g),f=GC(TC).map((W)=>R(N,W)).filter((W)=>T(W)&&D(W).isFile()&&q(W));if(f.length>0){_.push(...f);continue}}I.push(N);continue}if(M.name.startsWith("."))continue;if(M.isFile()&&q(N))_.push(N)}}return _.sort((G,O)=>G.localeCompare(O))}function nC(C,S){let _=[];for(let I of C){let G=I.trim();if(!G)continue;let O=R(S,G);if(!T(O))throw Error(`Plugin path does not exist: ${O}`);if(D(O).isDirectory()){let N=IC(O);if(N){_.push(...N);continue}_.push(...OC(O));continue}if(!q(O))throw Error(`Plugin file must use a supported extension (${[...SC].join(", ")}): ${O}`);_.push(O)}return _}function NC(C){let S=b(C);if(!T(S))J(S,{recursive:!0})}function hC(C){J(b(C),{recursive:!0}),QC(C,"")}function rC(C){if(C?.trim())return NC(C),b(C);let S=E(K(),"logs");if(!T(S))J(S,{recursive:!0});return S}export{UC as setHomeDirIfUnset,jC as setHomeDir,zC as setClineDirIfUnset,gC as setClineDir,H as resolveWorkspaceCronSpecsDir,sC as resolveWorkflowsConfigSearchPaths,JC as resolveTeamDataDir,oC as resolveSkillsConfigSearchPaths,HC as resolveSessionDataDir,pC as resolveRulesConfigSearchPaths,yC as resolveProviderSettingsPath,IC as resolvePluginModuleEntries,PC as resolvePluginConfigSearchPaths,fC as resolveMcpSettingsPath,dC as resolveHooksConfigSearchPaths,wC as resolveGlobalSettingsPath,t as resolveGlobalCronSpecsDir,CC as resolveGlobalAgentsRulesPath,qC as resolveExistingFilePath,Q as resolveDocumentsExtensionPath,i as resolveDocumentsClineDirectoryPath,y as resolveDbDataDir,w as resolveCronSpecsDir,uC as resolveCronReportsDir,kC as resolveCronEventsDir,xC as resolveCronDbPath,VC as resolveConnectorsDbPath,bC as resolveConnectorSettingsPath,e as resolveConnectorDataDir,nC as resolveConfiguredPluginModulePaths,L as resolveClineDir,K as resolveClineDataDir,BC as resolveChatWorkspacePath,a as resolveAgentsConfigDirPath,lC as resolveAgentConfigSearchPaths,q as isPluginModulePath,s as isChatWorkspacePath,NC as ensureParentDir,rC as ensureHookLogDir,hC as ensureFileExists,OC as discoverPluginModulePaths,B as WORKFLOWS_CONFIG_DIRECTORY_NAME,X as SKILLS_CONFIG_DIRECTORY_NAME,z as RULES_CONFIG_DIRECTORY_NAME,A as HOOKS_CONFIG_DIRECTORY_NAME,Z as CLINE_WORKSPACES_DIRECTORY_NAME,c as CLINE_MCP_SETTINGS_FILE_NAME,n as CLINE_CONNECTOR_SETTINGS_FILE_NAME,$ as CLINE_CHAT_WORKSPACE_DIRECTORY_NAME,u as AGENT_CONFIG_DIRECTORY_NAME,k as AGENTS_RULES_FILE_NAME};
1
+ var MC=Object.defineProperty;var DC=(C)=>C;function FC(C,S){this[C]=DC.bind(null,S)}var GS=(C,S)=>{for(var E in S)MC(C,E,{get:S[E],enumerable:!0,configurable:!0,set:FC.bind(S,E)})};import{existsSync as K,readdirSync as WC}from"node:fs";import{basename as o,dirname as p,join as s}from"node:path";var YC=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g,vC=" ";function l(C){return C.normalize("NFC").replace(YC," ")}function KC(C){let S=o(C),E=S.replace(/ (AM|PM)\./gi,`${vC}$1.`);return E===S?C:s(p(C),E)}function qC(C){return C.normalize("NFD")}function d(C){return C.replace(/'/g,"’")}function QC(C){let S=p(C),E=l(o(C));try{for(let I of WC(S))if(l(I)===E)return s(S,I)}catch{}return}function RC(C){if(K(C))return C;let S=KC(C);if(S!==C&&K(S))return S;let E=qC(C);if(E!==C&&K(E))return E;let I=d(C);if(I!==C&&K(I))return I;let G=d(E);if(G!==E&&G!==I&&K(G))return G;return QC(C)}import{appendFileSync as ZC,existsSync as T,mkdirSync as b,readdirSync as $C,readFileSync as n,statSync as q}from"node:fs";import{homedir as AC}from"node:os";import{basename as BC,dirname as U,extname as XC,isAbsolute as jC,join as _,relative as UC,resolve as D}from"node:path";var Z="workspaces",$="chat";function P(C){let S=C.trim(),E=/^[A-Za-z]:[\\/]/.test(S)||S.startsWith("\\\\"),I=S.startsWith("/");if(!E&&!I)return!1;let G=S.split(E?/[\\/]+/:/\/+/).filter(Boolean),O=G.at(-1)??"",N=G.at(-2)??"",M=G.at(-3)??"";return(G.at(-4)??"")===".cline"&&M==="data"&&N==="workspaces"&&O==="chat"}var V=".clinerules",z=".cline",x=".agents",u="agents",A="hooks",X="skills",g="rules",B="workflows",c="plugins",w="AGENTS.md";function zC(){return _(L(),Z,$)}var h="cline_mcp_settings.json",r="settings.json";function HC(){let C=process?.env?.HOME?.trim();if(C&&C!=="~")return C;let S=process?.env?.USERPROFILE?.trim();if(S)return S;let E=process?.env?.HOMEDRIVE?.trim(),I=process?.env?.HOMEPATH?.trim();if(E&&I)return`${E}${I}`;let G=AC().trim();if(G&&G!=="~")return G;return"~"}var W=HC(),i=!1;function gC(C){let S=C.trim();if(!S)return;W=S,i=!0}function JC(C){if(i)return;let S=C.trim();if(!S)return;W=S}var j,e=!1;function bC(C){let S=C.trim();if(!S)return;j=S,e=!0}function VC(C){if(e)return;let S=C.trim();if(!S)return;j=S}function F(){if(j)return j;let C=process.env.CLINE_DIR?.trim();if(C)return C;return _(W,".cline")}function t(){return _(W,"Documents","Cline")}function R(C){return _(t(),C)}function L(){let C=process.env.CLINE_DATA_DIR?.trim();if(C)return C;return _(F(),"data")}function xC(){let C=process.env.CLINE_SESSION_DATA_DIR?.trim();if(C)return C;return _(L(),"sessions")}function uC(){let C=process.env.CLINE_TEAM_DATA_DIR?.trim();if(C)return C;return _(L(),"teams")}function a(){let C=process.env.CLINE_CONNECTOR_DATA_DIR?.trim();if(C)return C;return _(L(),"connectors")}function wC(C,S){let E=C.replace(/[^a-zA-Z0-9._-]+/g,"_"),I=S.replace(/[^a-zA-Z0-9._-]+/g,"_");return _(L(),"logs","connectors",E,`${I}.log`)}function yC(){let C=process.env.CLINE_CONNECTOR_SETTINGS_PATH?.trim();if(C)return C;return _(a(),r)}function y(){let C=process.env.CLINE_DB_DATA_DIR?.trim();if(C)return C;return _(L(),"db")}function kC(){let C=process.env.CLINE_CONNECTORS_DB_PATH?.trim();if(C)return C;return _(y(),"connectors.db")}function mC(){let C=process.env.CLINE_CRON_DB_PATH?.trim();if(C)return C;return _(y(),"cron.db")}function CC(){return _(F(),"cron")}function J(C){return _(C,".cline","cron")}function k(C){if(typeof C==="string")return J(C);if(C?.cronSpecsDir?.trim())return C.cronSpecsDir.trim();if(C?.scope==="workspace"){let S=C.workspaceRoot?.trim();if(!S)throw Error("workspaceRoot is required for workspace cron scope");return J(S)}return CC()}function fC(C){return _(k(C),"reports")}function lC(C){return _(k(C),"events")}function dC(){let C=process.env.CLINE_PROVIDER_SETTINGS_PATH?.trim();if(C)return C;return _(L(),"settings","providers.json")}function oC(){let C=process.env.CLINE_GLOBAL_SETTINGS_PATH?.trim();if(C)return C;return _(L(),"settings","global-settings.json")}function pC(){let C=process.env.CLINE_MCP_SETTINGS_PATH?.trim();if(C)return C;return _(L(),"settings",h)}function Y(C){let S=new Set,E=[];for(let I of C){if(!I||S.has(I))continue;S.add(I),E.push(I)}return E}function sC(C){if(!C)return[];return[V,z,x].map((S)=>_(C,S,X))}function SC(){return _(F(),u)}function PC(C){return Y([C?_(C,z,u):"",SC()])}function cC(C){let S=[R("Hooks"),_(F(),A)];if(C)S.push(_(C,V,A),_(C,z,A));return Y(S)}function nC(C){return Y([...sC(C),_(F(),X),_(W,x,X)])}function EC(){return _(W,x,w)}function hC(C){let S=C?[_(C,V),_(C,z,g)]:[],E=C?[_(C,w)]:[];return Y([...E,...S,EC(),_(F(),g),R("Rules")])}function rC(C){return Y([C?_(C,".clinerules",B):"",R("Workflows"),_(F(),B),C?_(C,".cline",B):""])}function iC(C){return Y([C?_(C,".cline",c):"",_(F(),c),R("Plugins")])}var _C=new Set([".js",".ts"]),m="package.json",eC=["index.ts","index.js"];function Q(C){let S=C.lastIndexOf(".");if(S===-1)return!1;return _C.has(C.slice(S))}function GC(C){try{let S=JSON.parse(n(C,"utf8"));if(!S.cline||typeof S.cline!=="object")return null;return S.cline}catch{return null}}function IC(C){let S=C?.plugins;if(!Array.isArray(S))return[];return S.flatMap((E)=>E.paths??[])}function OC(C){let S=D(C);if(!T(S)||!q(S).isDirectory())return null;let E=_(S,m);if(T(E)){let I=GC(E),G=IC(I).map((O)=>D(S,O)).filter((O)=>T(O)&&q(O).isFile()&&Q(O));if(G.length>0)return G}for(let I of eC){let G=_(S,I);if(T(G)&&q(G).isFile())return[G]}return null}function tC(C){try{let S=JSON.parse(n(C,"utf8"));return typeof S.name==="string"&&S.name.trim()?S.name.trim():void 0}catch{return}}function aC(C,S){let E=UC(D(C),D(S));return E===""||!E.startsWith("..")&&!jC(E)}function CS(C,S){let E=U(C),I=D(S);while(aC(I,E)){let G=_(E,m);if(T(G)){let N=tC(G);if(N)return N;break}let O=D(E,"..");if(O===E)break;E=O}return BC(C,XC(C))}function TC(C){let S=D(C);if(!T(S))return[];let E=[],I=[S];while(I.length>0){let G=I.pop();if(!G)continue;let O;try{O=$C(G,{withFileTypes:!0})}catch{continue}for(let N of O){let M=_(G,N.name);if(N.isDirectory()){let H=_(M,m);if(T(H)){let NC=GC(H),f=IC(NC).map((v)=>D(M,v)).filter((v)=>T(v)&&q(v).isFile()&&Q(v));if(f.length>0){E.push(...f);continue}}I.push(M);continue}if(N.name.startsWith("."))continue;if(N.isFile()&&Q(M))E.push(M)}}return E.sort((G,O)=>G.localeCompare(O))}function SS(C,S){let E=[];for(let I of C){let G=I.trim();if(!G)continue;let O=D(S,G);if(!T(O))throw Error(`Plugin path does not exist: ${O}`);if(q(O).isDirectory()){let M=OC(O);if(M){E.push(...M);continue}E.push(...TC(O));continue}if(!Q(O))throw Error(`Plugin file must use a supported extension (${[..._C].join(", ")}): ${O}`);E.push(O)}return E}function LC(C){let S=U(C);if(!T(S))b(S,{recursive:!0})}function ES(C){b(U(C),{recursive:!0}),ZC(C,"")}function _S(C){if(C?.trim())return LC(C),U(C);let S=_(L(),"logs");if(!T(S))b(S,{recursive:!0});return S}export{JC as setHomeDirIfUnset,gC as setHomeDir,VC as setClineDirIfUnset,bC as setClineDir,J as resolveWorkspaceCronSpecsDir,rC as resolveWorkflowsConfigSearchPaths,uC as resolveTeamDataDir,nC as resolveSkillsConfigSearchPaths,xC as resolveSessionDataDir,hC as resolveRulesConfigSearchPaths,dC as resolveProviderSettingsPath,OC as resolvePluginModuleEntries,iC as resolvePluginConfigSearchPaths,pC as resolveMcpSettingsPath,cC as resolveHooksConfigSearchPaths,oC as resolveGlobalSettingsPath,CC as resolveGlobalCronSpecsDir,EC as resolveGlobalAgentsRulesPath,RC as resolveExistingFilePath,R as resolveDocumentsExtensionPath,t as resolveDocumentsClineDirectoryPath,y as resolveDbDataDir,k as resolveCronSpecsDir,fC as resolveCronReportsDir,lC as resolveCronEventsDir,mC as resolveCronDbPath,kC as resolveConnectorsDbPath,yC as resolveConnectorSettingsPath,wC as resolveConnectorLogPath,a as resolveConnectorDataDir,SS as resolveConfiguredPluginModulePaths,F as resolveClineDir,L as resolveClineDataDir,zC as resolveChatWorkspacePath,SC as resolveAgentsConfigDirPath,PC as resolveAgentConfigSearchPaths,Q as isPluginModulePath,P as isChatWorkspacePath,CS as getPluginDisplayName,LC as ensureParentDir,_S as ensureHookLogDir,ES as ensureFileExists,TC as discoverPluginModulePaths,B as WORKFLOWS_CONFIG_DIRECTORY_NAME,X as SKILLS_CONFIG_DIRECTORY_NAME,g as RULES_CONFIG_DIRECTORY_NAME,A as HOOKS_CONFIG_DIRECTORY_NAME,Z as CLINE_WORKSPACES_DIRECTORY_NAME,h as CLINE_MCP_SETTINGS_FILE_NAME,r as CLINE_CONNECTOR_SETTINGS_FILE_NAME,$ as CLINE_CHAT_WORKSPACE_DIRECTORY_NAME,u as AGENT_CONFIG_DIRECTORY_NAME,w as AGENTS_RULES_FILE_NAME};
@@ -27,6 +27,13 @@ export declare function resolveClineDataDir(): string;
27
27
  export declare function resolveSessionDataDir(): string;
28
28
  export declare function resolveTeamDataDir(): string;
29
29
  export declare function resolveConnectorDataDir(): string;
30
+ /**
31
+ * Where a connector instance's stdout/stderr is captured. Both the CLI (which
32
+ * spawns detached connectors directly) and the hub supervisor (which spawns and
33
+ * reaps them) need to agree on this path, so it lives here rather than in
34
+ * either one.
35
+ */
36
+ export declare function resolveConnectorLogPath(channel: string, instanceKey: string): string;
30
37
  export declare function resolveConnectorSettingsPath(): string;
31
38
  export declare function resolveDbDataDir(): string;
32
39
  /**
@@ -97,6 +104,14 @@ export declare function resolveWorkflowsConfigSearchPaths(workspacePath?: string
97
104
  export declare function resolvePluginConfigSearchPaths(workspacePath?: string): string[];
98
105
  export declare function isPluginModulePath(path: string): boolean;
99
106
  export declare function resolvePluginModuleEntries(directoryPath: string): string[] | null;
107
+ /**
108
+ * Human-readable name for a plugin module entry. Package-backed plugins
109
+ * (e.g. `~/.cline/plugins/_installed/<id>/package/index.ts`) are named after
110
+ * the `name` in the nearest ancestor `package.json` within `searchRoot`, so
111
+ * every install doesn't surface as "index". Bare module files fall back to
112
+ * the file basename.
113
+ */
114
+ export declare function getPluginDisplayName(filePath: string, searchRoot: string): string;
100
115
  export declare function discoverPluginModulePaths(directoryPath: string): string[];
101
116
  export declare function resolveConfiguredPluginModulePaths(pluginPaths: ReadonlyArray<string>, cwd: string): string[];
102
117
  export declare function ensureParentDir(filePath: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cline/shared",
3
- "version": "0.0.69",
3
+ "version": "0.0.70",
4
4
  "description": "Shared utilities, types, and schemas for Cline packages",
5
5
  "repository": {
6
6
  "type": "git",