@cerebriline/core 4.100.251 → 4.100.253
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.
- package/dist/cloud/index.js +17 -17
- package/dist/document-reader-child.js +24 -24
- package/dist/extensions/context/capped-thinking.d.ts +57 -3
- package/dist/extensions/plugin-sandbox-bootstrap.js +1 -1
- package/dist/extensions/tools/delimiter-balance.d.ts +1 -1
- package/dist/extensions/tools/executors/apply-patch.d.ts +8 -0
- package/dist/extensions/tools/executors/bom.d.ts +18 -0
- package/dist/extensions/tools/executors/file-read.d.ts +11 -0
- package/dist/extensions/tools/executors/output-limits.d.ts +2 -0
- package/dist/extensions/tools/executors/read-receipts.d.ts +66 -1
- package/dist/extensions/tools/task-progress.d.ts +15 -0
- package/dist/hub/daemon/entry.js +794 -783
- package/dist/hub/index.js +783 -772
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1084 -1073
- package/dist/remote/remote-helper-entry.js +4 -4
- package/dist/remote/remote-helper.js +4 -4
- package/dist/runtime/atomic/transaction-controller.d.ts +25 -0
- package/dist/services/feature-flags/posthog.js +1 -1
- package/dist/services/llms/provider-settings.d.ts +20 -0
- package/dist/services/llms/session-budget.d.ts +10 -3
- package/dist/services/telemetry/index.js +1 -1
- package/dist/types/config.d.ts +9 -0
- package/package.json +4 -4
|
@@ -52,6 +52,37 @@ export declare function reasoningHitBudget(thinking: string, budgetMessage?: str
|
|
|
52
52
|
* repeating itself, which is why it stays a fixed number and not a share.
|
|
53
53
|
*/
|
|
54
54
|
export declare const CONDENSED_THINKING_NOTE_TOKENS = 2000;
|
|
55
|
+
/**
|
|
56
|
+
* The note's length target: a tenth of the think it replaces, kept between
|
|
57
|
+
* 1,000 and 2,000 tokens (user ruling, 2026-10-18: "1k-2k if there's enough
|
|
58
|
+
* context/output available").
|
|
59
|
+
*
|
|
60
|
+
* The floor is the point. A note is asked for only when a think ran to its
|
|
61
|
+
* budget, and the notes measured so far were 250 to 450 tokens -- a hundredth
|
|
62
|
+
* of what they replaced, too little to carry the calls, the findings and what
|
|
63
|
+
* was set aside, so the next pass re-derived them.
|
|
64
|
+
*/
|
|
65
|
+
export declare const CONDENSED_THINKING_NOTE_MIN_TOKENS = 1000;
|
|
66
|
+
/**
|
|
67
|
+
* How long a note to ask for, and the output cap that goes with it.
|
|
68
|
+
*
|
|
69
|
+
* The target comes from the think; the room only ever lowers it. With a
|
|
70
|
+
* window to fit, the condensation request and its cap must both be inside
|
|
71
|
+
* it, so the target steps down until they are -- to a short note rather than
|
|
72
|
+
* none, because a request that does not fit is refused either way. With no
|
|
73
|
+
* window known the target stands, and the server sizes the call as before.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveCondensedThinkingNoteTokens(options: {
|
|
76
|
+
thinkingChars: number;
|
|
77
|
+
/** The condensation request as it will be sent, in characters. */
|
|
78
|
+
requestChars: number;
|
|
79
|
+
/** The tokens the call has to fit in, when known. */
|
|
80
|
+
roomTokens?: number;
|
|
81
|
+
providerConfig: Partial<ProviderConfig>;
|
|
82
|
+
}): {
|
|
83
|
+
noteTokens: number;
|
|
84
|
+
maxTokens: number;
|
|
85
|
+
};
|
|
55
86
|
/**
|
|
56
87
|
* The cap the condensation request carries.
|
|
57
88
|
*
|
|
@@ -95,8 +126,26 @@ export declare function isDegenerateNote(note: string): boolean;
|
|
|
95
126
|
* user message: the same split the compaction summariser uses. It says what the
|
|
96
127
|
* note is for; `DEFAULT_CAPPED_THINKING_PROMPT` says what it must contain.
|
|
97
128
|
*/
|
|
98
|
-
export declare const CAPPED_THINKING_SYSTEM_PROMPT = "You are
|
|
99
|
-
|
|
129
|
+
export declare const CAPPED_THINKING_SYSTEM_PROMPT = "You are condensing a train of thought, in the voice of the person who is thinking it. What you write goes back into that same reasoning as the part of it already done, and is read as thinking, so write it the way thinking is written: first person, present continuous tense, plain prose, one thought after another. Keep every specific: paths, symbols, line numbers, error text, and what is set aside and why.";
|
|
130
|
+
/**
|
|
131
|
+
* What the note must contain, and the voice it is in.
|
|
132
|
+
*
|
|
133
|
+
* Built on the replay compaction prompt (`DEFAULT_REPLAY_COMPACTION_PROMPT`),
|
|
134
|
+
* the one that holds its voice: first person, present continuous, shapes to
|
|
135
|
+
* reuse, and its own labels in the tense it asks for. The version this
|
|
136
|
+
* replaces asked for "present tense" while framing everything in the past --
|
|
137
|
+
* "You were reasoning", "how far you got", "what you then called" -- forbade
|
|
138
|
+
* lists inside a bullet list, and ended on "Do not" lines. A prompt that
|
|
139
|
+
* disagrees with itself is read as an instruction that is optional, and a
|
|
140
|
+
* negative exemplar is still an exemplar. On pandorum the note it produced
|
|
141
|
+
* sent the next turn into a loop: re-reasoning the note rather than going on
|
|
142
|
+
* from it.
|
|
143
|
+
*
|
|
144
|
+
* The length is not in here. It is a target the request builder appends,
|
|
145
|
+
* sized to the think and the room (`resolveCondensedThinkingNoteTokens`), so a
|
|
146
|
+
* replacement prompt gets it too.
|
|
147
|
+
*/
|
|
148
|
+
export declare const DEFAULT_CAPPED_THINKING_PROMPT = "Your thinking on this turn has reached its budget, and the reasoning below is about to be replaced by what you write now. Write the reasoning that takes its place.\n\nIt goes back into **your own thinking channel**, as the thinking you are in the middle of. Your next pass reads it as its own train of thought and carries on from the end of it, so write it the way you think: in the **first person, present continuous tense**, in plain prose, one thought after another, the same voice as the reasoning it replaces.\n\nWrite every step as the step itself, then what is coming back. These are the shapes \u2014 reuse them:\n\n- \"I'm working out why the collision check misses the left wall.\"\n- \"I'm reading `game.js` around line 274, and the bounds test there compares against `width` where it needs `width - size`.\"\n- \"I'm running `check_file` on it, and it is reporting an unterminated regular expression at line 274.\"\n- \"I'm setting the loop rewrite aside: the fault is in the bounds test, and the loop is sound.\"\n- \"The bounds test is the cause, so what I'm doing next is editing line 274.\"\n\nEvery sentence holds that voice, the middle as much as the first and the last.\n\nCarry all of this:\n\n- **What you are being asked to do**, in a sentence.\n- **Every tool call in this turn**, by name, with the argument that matters and what it is returning: the file and what is at the line you are looking at, the edit and whether it is applying, the command and what it is printing. These results are not in front of your next pass any more, so this is the only place they survive.\n- **What you are treating as settled**, stated as settled.\n- **What you are setting aside, and why**, a clause each. This is what keeps the next pass off ground this one has already covered.\n- **Where you are**, ending on the one question still open and the single next action, stated concretely.\n\nName files and lines and say what you are concluding about them; the files themselves are on disk, and the next tool result is what shows their current state.\n\nBegin with the problem itself and end on the next action.";
|
|
100
149
|
interface ToolOutcome {
|
|
101
150
|
name: string;
|
|
102
151
|
input: string;
|
|
@@ -142,6 +191,8 @@ export declare function buildCappedThinkingRequest(options: {
|
|
|
142
191
|
promptTemplate?: string;
|
|
143
192
|
/** The reply the turn had begun writing before it was cut off. */
|
|
144
193
|
partialAnswer?: string;
|
|
194
|
+
/** The note's length target, in tokens (`resolveCondensedThinkingNoteTokens`). */
|
|
195
|
+
noteTokens?: number;
|
|
145
196
|
}): string;
|
|
146
197
|
export interface CappedThinkingCondenserConfig {
|
|
147
198
|
enabled?: boolean;
|
|
@@ -170,7 +221,10 @@ type PrepareTurnResult = {
|
|
|
170
221
|
} | undefined;
|
|
171
222
|
type PrepareTurn = (context: never) => PrepareTurnResult | Promise<PrepareTurnResult>;
|
|
172
223
|
/** A request answered by the conversation itself, or `undefined` to decline. */
|
|
173
|
-
type ConversationAsk = (systemPrompt: string, request: string, maxTokens: number, what: string) => Promise<string | undefined
|
|
224
|
+
type ConversationAsk = ((systemPrompt: string, request: string, maxTokens: number, what: string) => Promise<string | undefined>) & {
|
|
225
|
+
/** What the conversation's last request left of the window, when measured. */
|
|
226
|
+
roomTokens?: number;
|
|
227
|
+
};
|
|
174
228
|
/**
|
|
175
229
|
* The discarded turn's notes, asked of the conversation as its next turn
|
|
176
230
|
* where that can be done (`DiscardedTurnInput.continueConversation`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as XQ}from"node:module";var YQ=XQ(import.meta.url);import{normalizePluginManifest as DQ}from"@cerebriline/shared";function P(Q=process){Q.once("disconnect",()=>Q.exit(0))}import{existsSync as _,readFileSync as O}from"node:fs";import{builtinModules as ZQ,createRequire as R}from"node:module";import{dirname as J,extname as I,isAbsolute as $Q,resolve as q}from"node:path";import{fileURLToPath as m}from"node:url";import{PLUGIN_FILE_EXTENSIONS as GQ}from"@cerebriline/shared";var d=J(m(import.meta.url)),KQ=R(import.meta.url),qQ=q(d,"..","..","..","..",".."),T=wQ(qQ),WQ=["@cerebriline/sdk","@cerebriline/agents","@cerebriline/core","@cerebriline/core/hub","@cerebriline/core/hub/daemon-entry","@cerebriline/core/telemetry","@cerebriline/llms","@cerebriline/llms/browser","@cerebriline/shared","@cerebriline/shared/automation","@cerebriline/shared/browser","@cerebriline/shared/storage","@cerebriline/shared/db","@cerebriline/shared/types"],k=new Set(ZQ.flatMap((Q)=>[Q,Q.replace(/^node:/,"")])),B=new Set(GQ),_Q=["development","node","import","require","default"];function wQ(Q){let U={},X={"@cerebriline/sdk":q(Q,"packages/sdk/src/index.ts"),"@cerebriline/agents":q(Q,"packages/agents/src/index.ts"),"@cerebriline/core":q(Q,"packages/core/src/index.ts"),"@cerebriline/llms":q(Q,"packages/llms/src/index.ts"),"@cerebriline/shared":q(Q,"packages/shared/src/index.ts"),"@cerebriline/shared/storage":q(Q,"packages/shared/src/storage/index.ts"),"@cerebriline/shared/db":q(Q,"packages/shared/src/db/index.ts")};for(let[Z,$]of Object.entries(X))if(_($))U[Z]=$;for(let Z of["agents","core","llms","shared"]){let $=q(Q,"packages",Z),G=q($,"package.json");if(!_(G))continue;try{let Y=JSON.parse(O(G,"utf8"));if(typeof Y.name!=="string"||!Y.exports)continue;if(typeof Y.exports==="string"){let K=q($,Y.exports);if(_(K))U[Y.name]=K;continue}if(typeof Y.exports!=="object")continue;for(let[K,A]of Object.entries(Y.exports)){let L=AQ($,A);if(!L)continue;let w=K==="."?Y.name:`${Y.name}/${K.replace(/^\.\//,"")}`;U[w]=L}}catch{}}return U}function AQ(Q,U){let X=v(U);if(!X)return null;let Z=u(Q,X);for(let $ of Z)if(_($))return $;return null}function v(Q,U=new Set){if(typeof Q==="string")return Q;if(!Q||typeof Q!=="object")return null;if(U.has(Q))return null;U.add(Q);let X=Q;for(let Z of _Q){let $=v(X[Z],U);if($)return $}return null}function u(Q,U){let X=U.replace(/^\.\//,""),Z=[q(Q,U)];if(X.startsWith("dist/")){let $=X.replace(/^dist\//,"src/").replace(/\.(mjs|cjs|js)$/,"");return[q(Q,`${$}.ts`),q(Q,`${$}.tsx`),q(Q,`${$}.mts`),q(Q,`${$}.cts`),...Z]}return Z}function LQ(Q){return Object.fromEntries(Object.entries(Q).sort(([U],[X])=>X.length-U.length))}function N(Q){return!(Q.startsWith(".")||Q.startsWith("/")||Q.startsWith("file:")||Q.startsWith("data:")||Q.startsWith("http:")||Q.startsWith("https:"))}function C(Q){if(Q.startsWith("@")){let[U,X]=Q.split("/",3);return X?`${U}/${X}`:Q}return Q.split("/",1)[0]??Q}function FQ(Q){let U=C(Q);if(Q===U)return".";return`.${Q.slice(U.length)}`}function c(Q){return C(Q).startsWith("@cline/")}function y(Q,U){let X=C(U),Z=J(Q);while(!0){let $=q(Z,"node_modules",X);if(_($)||_(q($,"package.json")))return!0;let G=q(Z,"..");if(G===Z)return!1;Z=G}}function h(Q){return b(Q)!==null}function b(Q){try{return KQ.resolve(Q)}catch{}return JQ(Q)}function JQ(Q){let U=C(Q),X=l(U);if(!X)return null;let Z=q(X,"package.json");try{let $=JSON.parse(O(Z,"utf8")),G=FQ(Q),Y=G==="."&&typeof $.exports==="string"?$.exports:$.exports&&typeof $.exports==="object"&&Object.hasOwn($.exports,G)?$.exports[G]:void 0,K=v(Y)??(G==="."&&typeof $.main==="string"?$.main:null);if(!K)return null;let A=q(X,K),L=[A,...u(X,K).filter((w)=>w!==A)];for(let w of L)if(_(w))return w;return null}catch{return null}}function zQ(){let Q=[d],U=process.env.CLINE_WRAPPER_PATH?.trim();if(U)Q.push(J(J(U)));let X=process.execPath?.trim();if(X)Q.push(J(X));return[...new Set(Q.map((Z)=>q(Z)))]}function CQ(Q,U){let X=Q;while(!0){let Z=q(X,"package.json");if(_(Z))try{if(JSON.parse(O(Z,"utf8")).name===U)return X}catch{}let $=q(X,"node_modules",U,"package.json");if(_($))return J($);let G=q(X,"..");if(G===X)return null;X=G}}function l(Q){for(let U of zQ()){let X=CQ(U,Q);if(X)return X}return null}function OQ(Q){let X=J(Q);for(let Z=0;Z<4;Z++){let $=q(X,"package.json");if(_($))try{let Y=JSON.parse(O($,"utf8"));return Y!=null&&typeof Y==="object"&&"cline"in Y}catch{return!1}let G=q(X,"..");if(G===X)return!1;X=G}return!1}function g(Q,U){let X=U.startsWith("file:")?m(U):$Q(U)?U:q(J(Q),U);if(_(X)&&B.has(I(X)))return X;for(let Z of B){let $=`${X}${Z}`;if(_($))return $}for(let Z of B){let $=q(X,`index${Z}`);if(_($))return $}return null}function n(Q){let U=new Set,X=[/\bimport\s+(?:type\s+)?[^"'`]*?\bfrom\s*["'`]([^"'`]+)["'`]/g,/\bexport\s+[^"'`]*?\bfrom\s*["'`]([^"'`]+)["'`]/g,/\bimport\s*\(\s*["'`]([^"'`]+)["'`]\s*\)/g,/\brequire\s*\(\s*["'`]([^"'`]+)["'`]\s*\)/g];for(let Z of X)for(let $ of Q.matchAll(Z)){let G=$[1];if(G)U.add(G)}return[...U]}function jQ(Q){return I(Q)!==".ts"}function o(Q,U,X=new Set){if(X.has(Q)||!_(Q))return;if(X.add(Q),!B.has(I(Q)))return;let Z=O(Q,"utf8"),$=jQ(Q);for(let G of n(Z)){if(G.startsWith("node:")||k.has(G))continue;if(N(G)){if(!$)continue;if(Object.hasOwn(T,G)||Object.hasOwn(T,C(G))||y(Q,G)||c(G)&&h(G)||U&&h(G))continue;throw Error(`Cannot find module '${C(G)}'`)}let Y=g(Q,G);if(Y)o(Y,U,X)}}function p(Q,U=new Set,X=new Set){if(U.has(Q)||!_(Q))return X;if(U.add(Q),!B.has(I(Q)))return X;let Z=O(Q,"utf8");for(let $ of n(Z)){if(X.add($),N($))continue;let G=g(Q,$);if(G)p(G,U,X)}return X}function BQ(Q,U){let X=R(Q),Z={},$=p(Q),G=new Set(WQ);for(let[Y,K]of Object.entries(T)){try{X.resolve(Y);continue}catch{}Z[Y]=K}for(let Y of $)if(N(Y)&&(c(Y)||U))G.add(Y);for(let Y of G){if(Object.hasOwn(Z,Y)||y(Q,Y))continue;let K=b(Y);if(K)Z[Y]=K}if(!U)return Z;for(let Y of $){if(!N(Y)||Object.hasOwn(Z,Y)||y(Q,Y)||Y.startsWith("node:")||k.has(Y))continue;let K=b(Y);if(K)Z[Y]=K}return Z}function IQ(Q){let U=I(Q);return U===".ts"||U===".tsx"||U===".mts"||U===".cts"}var z;function HQ(){if(z!==void 0)return z;let Q=l("jiti");if(!Q)return z=null,null;let U=q(Q,"dist","babel.cjs");if(!_(U))return z=null,null;try{let Z=R(U)(U);z=typeof Z==="function"?Z:null}catch{z=null}return z}async function s(Q,U={}){let X=!OQ(Q);o(Q,X);let Z=BQ(Q,X),$=LQ(Z),G=await import("jiti"),Y=typeof G==="function"?G:typeof G.default==="function"?G.default:void 0;if(!Y)throw Error("Unable to load jiti");let K=Object.entries($).filter(([,W])=>IQ(W)).map(([W])=>W),A=HQ(),L=A?(W)=>A({...W,interopDefault:!0}):void 0;return await Y(Q,{alias:$,cache:U.useCache,requireCache:U.useCache,esmResolve:!0,interopDefault:!1,nativeModules:[...k],transformModules:K,tryNative:!1,...L?{transform:L}:{}}).import(Q,{})}function i(Q,U){if(!Q)return!0;if(Q.providerIds?.length){if(!U?.providerId||!Q.providerIds.includes(U.providerId))return!1}if(Q.modelIds?.length){if(!U?.modelId||!Q.modelIds.includes(U.modelId))return!1}return!0}function F(Q){return typeof Q==="object"&&Q!==null}function r(Q){return Array.isArray(Q)&&Q.every((U)=>typeof U==="string")}function NQ(Q,U){if(!F(Q))throw Error(`Invalid plugin module: ${U}`);if(typeof Q.name!=="string"||!Q.name)throw Error(`Invalid plugin name: ${U}`);if(!F(Q.manifest))throw Error(`Invalid plugin manifest: ${U}`);if(Object.hasOwn(Q.manifest,"providerIds")&&!r(Q.manifest.providerIds))throw Error(`Invalid plugin manifest.providerIds: ${U}`);if(Object.hasOwn(Q.manifest,"modelIds")&&!r(Q.manifest.modelIds))throw Error(`Invalid plugin manifest.modelIds: ${U}`)}function SQ(Q){if(!F(Q))throw Error("Plugin setup context must be an object");if(Q.session!==void 0&&!F(Q.session))throw Error("Plugin setup context session must be an object");if(Q.client!==void 0&&!F(Q.client))throw Error("Plugin setup context client must be an object");if(Q.user!==void 0&&!F(Q.user))throw Error("Plugin setup context user must be an object");if(Q.workspaceInfo!==void 0&&!F(Q.workspaceInfo))throw Error("Plugin setup context workspaceInfo must be an object");if(Q.automation!==void 0&&!F(Q.automation))throw Error("Plugin setup context automation must be an object");if(Q.automation!==void 0&&typeof Q.automation.ingestEvent!=="function")throw Error("Plugin setup context automation.ingestEvent must be a function");if(Q.logger!==void 0&&!F(Q.logger))throw Error("Plugin setup context logger must be an object")}var t=0,S=new Map,f=new Map;function MQ(Q){let U=Q instanceof Error?Q.message:String(Q),X=Q instanceof Error?Q.stack:void 0;return{message:U,stack:X}}function x(Q,U,X,Z){if(!process.send)return;process.send({type:"response",id:Q,ok:U,result:X,error:Z})}function V(Q,U){if(!process.send)return;process.send({type:"event",name:Q,payload:U})}globalThis.__clinePluginHost={emitEvent:V};globalThis.__clineSessionEnv={cwd:void 0,workspaceInfo:void 0};function a(Q){if(!Q||typeof Q!=="object")return{};return Q}function M(Q){if(!Q||typeof Q!=="object")return;let U={...Q};if(U.error instanceof Error)U.error={name:U.error.name,message:U.error.message,stack:U.error.stack};return U}function VQ(Q){let U=(X,Z,$)=>{V("plugin_log",{level:X,pluginName:Q,message:Z,metadata:M($)})};return{debug:(X,Z)=>U("debug",X,Z),log:(X,Z)=>U("log",X,Z),error:(X,Z)=>U("error",X,Z)}}function EQ(Q){let U=($)=>{V("plugin_telemetry",{pluginName:Q,...$})},X=($)=>(G,Y,K,A,L)=>{U({kind:"metric",metric:$,name:G,value:Y,attributes:M(K),description:A,required:L})},Z=()=>{};return{capture:($)=>{U({kind:"event",event:$?.event,properties:M($?.properties)})},captureRequired:($,G)=>{U({kind:"event",event:$,properties:M(G),required:!0})},recordCounter:X("counter"),recordHistogram:X("histogram"),recordGauge:X("gauge"),isEnabled:()=>!0,setDistinctId:Z,setMetadata:Z,updateMetadata:Z,setCommonProperties:Z,updateCommonProperties:Z,flush:async()=>{},dispose:async()=>{}}}function j(Q,U){let X=`${Q}:${U}`,Z=(f.get(X)??0)+1;return f.set(X,Z),`${Q}_${U}_${Z}`}function TQ(Q){let U=typeof Q.eventType==="string"?Q.eventType.trim():"",X=typeof Q.source==="string"?Q.source.trim():"";if(!U)throw Error("Automation event type contribution requires eventType");if(!X)throw Error("Automation event type contribution requires source");return{...Q,eventType:U,source:X,examples:Q.examples?[...Q.examples]:void 0,metadata:Q.metadata?a(Q.metadata):void 0}}function H(Q){let U=S.get(Q);if(!U)throw Error(`Unknown sandbox plugin id: ${Q}`);return U}async function yQ(Q){let U;try{let X=await s(Q.pluginPath);if(U=X.default??X[Q.exportName],NQ(U,Q.pluginPath),U.manifest=DQ(U.manifest),!i(U.manifest,Q.targeting))return{type:"skipped"};let Z={tools:[],commands:[],rules:[],messageBuilders:[],providers:[],automationEventTypes:[],mcpServers:[],shortcuts:[],flags:[]},$={tools:new Map,commands:new Map,rules:new Map,messageBuilders:new Map},G={registerTool:(Y)=>{let K=j(Q.pluginId,"tool");$.tools.set(K,Y.execute),Z.tools.push({id:K,name:Y.name,description:Y.description,inputSchema:Y.inputSchema,timeoutMs:Y.timeoutMs,retryable:Y.retryable})},registerCommand:(Y)=>{let K=j(Q.pluginId,"command");if(typeof Y.handler==="function")$.commands.set(K,Y.handler);Z.commands.push({id:K,name:Y.name,description:Y.description})},registerRule:(Y)=>{let K=j(Q.pluginId,"rule");if(typeof Y.content==="function"){$.rules.set(K,Y.content),Z.rules.push({id:K,ruleId:Y.id,source:Y.source,hasContentHandler:!0});return}Z.rules.push({id:K,ruleId:Y.id,content:Y.content,source:Y.source})},registerMessageBuilder:(Y)=>{let K=j(Q.pluginId,"builder");$.messageBuilders.set(K,Y.build),Z.messageBuilders.push({id:K,name:Y.name})},registerProvider:(Y)=>{Z.providers.push({id:j(Q.pluginId,"provider"),name:Y.name,description:Y.description,metadata:a(Y.metadata)})},registerAutomationEventType:(Y)=>{Z.automationEventTypes.push({id:j(Q.pluginId,"automation_event"),...TQ(Y)})},registerMcpServer:(Y)=>{Z.mcpServers.push(Y)}};if(typeof U.setup==="function")try{let Y={...Q.setupCtxBase,...Q.telemetryEnabled?{telemetry:EQ(U.name)}:{},...Q.loggerEnabled?{logger:VQ(U.name)}:{},...U.manifest.capabilities.includes("automationEvents")?{automation:{ingestEvent:(K)=>{V("automation_event",K)}}}:{}};SQ(Y),await U.setup(G,Y)}catch(Y){return{type:"failure",failure:{pluginPath:Q.pluginPath,pluginName:U.name,phase:"setup",message:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0}}}return{type:"loaded",state:{plugin:U,handlers:$},descriptor:{pluginId:Q.pluginId,pluginPath:Q.pluginPath,name:U.name,manifest:U.manifest,hooks:U.hooks?Object.entries(U.hooks).filter(([,Y])=>typeof Y==="function").map(([Y])=>Y):void 0,contributions:Z}}}catch(X){return{type:"failure",failure:{pluginPath:Q.pluginPath,pluginName:U?.name,phase:"load",message:X instanceof Error?X.message:String(X),stack:X instanceof Error?X.stack:void 0}}}}async function bQ(Q){if(S.clear(),t=0,f.clear(),Q.cwd)try{process.chdir(Q.cwd)}catch{}let U=globalThis.__clineSessionEnv;if(U)U.cwd=Q.cwd,U.workspaceInfo=Q.workspaceInfo;let X=[],Z=[],$=[],G=Q.exportName||"plugin",Y=new Map,K={providerId:Q.providerId,modelId:Q.modelId},A={session:Q.session,client:Q.client,user:Q.user,workspaceInfo:Q.workspaceInfo},L=await Promise.all((Q.pluginPaths||[]).map((w)=>{let W=`plugin_${++t}`;return yQ({pluginPath:w,pluginId:W,exportName:G,targeting:K,setupCtxBase:A,loggerEnabled:Q.loggerEnabled,telemetryEnabled:Q.telemetryEnabled})}));for(let w of L){if(w.type==="skipped")continue;if(w.type==="failure"){Z.push(w.failure);continue}let{descriptor:W,state:e}=w,E=Y.get(W.name);if(E!==void 0){let D=X[E];if(!D)Y.delete(W.name);else{$.push({type:"duplicate_plugin_override",pluginName:W.name,pluginPath:W.pluginPath,overriddenPluginPath:D.pluginPath,message:`Plugin "${W.name}" from ${W.pluginPath} overrides ${D.pluginPath}`}),S.delete(D.pluginId),X.splice(E,1),Y.clear();for(let[QQ,UQ]of X.entries())Y.set(UQ.name,QQ)}}S.set(W.pluginId,e),Y.set(W.name,X.length),X.push(W)}return{plugins:X,failures:Z,warnings:$}}async function RQ(Q){let X=H(Q.pluginId).plugin.hooks?.[Q.hookName];if(typeof X!=="function")return;return await X(Q.payload)}async function kQ(Q){let X=H(Q.pluginId).handlers.tools.get(Q.contributionId);if(typeof X!=="function")throw Error("Unknown sandbox tool contribution");return await X(Q.input,Q.context)}async function vQ(Q){let X=H(Q.pluginId).handlers.commands.get(Q.contributionId);if(typeof X!=="function")return"";return await X(Q.input)}async function xQ(Q){let X=H(Q.pluginId).handlers.messageBuilders.get(Q.contributionId);if(typeof X!=="function")return[];return await X(Q.messages)}async function fQ(Q){let X=H(Q.pluginId).handlers.rules.get(Q.contributionId);if(typeof X!=="function")return"";return await X()}var PQ={initialize:bQ,invokeHook:RQ,executeTool:kQ,executeCommand:vQ,buildMessages:xQ,resolveRuleContent:fQ};P();process.on("message",async(Q)=>{if(!Q||Q.type!=="call")return;let U=PQ[Q.method];if(!U){x(Q.id,!1,void 0,{message:`Unknown method: ${String(Q.method)}`});return}try{let X=await U(Q.args||{});x(Q.id,!0,X)}catch(X){x(Q.id,!1,void 0,MQ(X))}});
|
|
1
|
+
import{normalizePluginManifest as In}from"@cerebriline/shared";function B(n=process){n.once("disconnect",()=>n.exit(0))}import{existsSync as l,readFileSync as k}from"node:fs";import{builtinModules as rn,createRequire as _}from"node:module";import{dirname as m,extname as v,isAbsolute as on,resolve as u}from"node:path";import{fileURLToPath as z}from"node:url";import{PLUGIN_FILE_EXTENSIONS as sn}from"@cerebriline/shared";var J=m(z(import.meta.url)),an=_(import.meta.url),un=u(J,"..","..","..","..",".."),T=dn(un),cn=["@cerebriline/sdk","@cerebriline/agents","@cerebriline/core","@cerebriline/core/hub","@cerebriline/core/hub/daemon-entry","@cerebriline/core/telemetry","@cerebriline/llms","@cerebriline/llms/browser","@cerebriline/shared","@cerebriline/shared/automation","@cerebriline/shared/browser","@cerebriline/shared/storage","@cerebriline/shared/db","@cerebriline/shared/types"],O=new Set(rn.flatMap((n)=>[n,n.replace(/^node:/,"")])),b=new Set(sn),ln=["development","node","import","require","default"];function dn(n){let e={},t={"@cerebriline/sdk":u(n,"packages/sdk/src/index.ts"),"@cerebriline/agents":u(n,"packages/agents/src/index.ts"),"@cerebriline/core":u(n,"packages/core/src/index.ts"),"@cerebriline/llms":u(n,"packages/llms/src/index.ts"),"@cerebriline/shared":u(n,"packages/shared/src/index.ts"),"@cerebriline/shared/storage":u(n,"packages/shared/src/storage/index.ts"),"@cerebriline/shared/db":u(n,"packages/shared/src/db/index.ts")};for(let[i,o]of Object.entries(t))if(l(o))e[i]=o;for(let i of["agents","core","llms","shared"]){let o=u(n,"packages",i),s=u(o,"package.json");if(!l(s))continue;try{let r=JSON.parse(k(s,"utf8"));if(typeof r.name!=="string"||!r.exports)continue;if(typeof r.exports==="string"){let a=u(o,r.exports);if(l(a))e[r.name]=a;continue}if(typeof r.exports!=="object")continue;for(let[a,g]of Object.entries(r.exports)){let p=gn(o,g);if(!p)continue;let d=a==="."?r.name:`${r.name}/${a.replace(/^\.\//,"")}`;e[d]=p}}catch{}}return e}function gn(n,e){let t=A(e);if(!t)return null;let i=H(n,t);for(let o of i)if(l(o))return o;return null}function A(n,e=new Set){if(typeof n==="string")return n;if(!n||typeof n!=="object")return null;if(e.has(n))return null;e.add(n);let t=n;for(let i of ln){let o=A(t[i],e);if(o)return o}return null}function H(n,e){let t=e.replace(/^\.\//,""),i=[u(n,e)];if(t.startsWith("dist/")){let o=t.replace(/^dist\//,"src/").replace(/\.(mjs|cjs|js)$/,"");return[u(n,`${o}.ts`),u(n,`${o}.tsx`),u(n,`${o}.mts`),u(n,`${o}.cts`),...i]}return i}function pn(n){return Object.fromEntries(Object.entries(n).sort(([e],[t])=>t.length-e.length))}function E(n){return!(n.startsWith(".")||n.startsWith("/")||n.startsWith("file:")||n.startsWith("data:")||n.startsWith("http:")||n.startsWith("https:"))}function h(n){if(n.startsWith("@")){let[e,t]=n.split("/",3);return t?`${e}/${t}`:n}return n.split("/",1)[0]??n}function fn(n){let e=h(n);if(n===e)return".";return`.${n.slice(e.length)}`}function L(n){return h(n).startsWith("@cline/")}function C(n,e){let t=h(e),i=m(n);while(!0){let o=u(i,"node_modules",t);if(l(o)||l(u(o,"package.json")))return!0;let s=u(i,"..");if(s===i)return!1;i=s}}function W(n){return j(n)!==null}function j(n){try{return an.resolve(n)}catch{}return mn(n)}function mn(n){let e=h(n),t=q(e);if(!t)return null;let i=u(t,"package.json");try{let o=JSON.parse(k(i,"utf8")),s=fn(n),r=s==="."&&typeof o.exports==="string"?o.exports:o.exports&&typeof o.exports==="object"&&Object.hasOwn(o.exports,s)?o.exports[s]:void 0,a=A(r)??(s==="."&&typeof o.main==="string"?o.main:null);if(!a)return null;let g=u(t,a),p=[g,...H(t,a).filter((d)=>d!==g)];for(let d of p)if(l(d))return d;return null}catch{return null}}function wn(){let n=[J],e=process.env.CLINE_WRAPPER_PATH?.trim();if(e)n.push(m(m(e)));let t=process.execPath?.trim();if(t)n.push(m(t));return[...new Set(n.map((i)=>u(i)))]}function hn(n,e){let t=n;while(!0){let i=u(t,"package.json");if(l(i))try{if(JSON.parse(k(i,"utf8")).name===e)return t}catch{}let o=u(t,"node_modules",e,"package.json");if(l(o))return m(o);let s=u(t,"..");if(s===t)return null;t=s}}function q(n){for(let e of wn()){let t=hn(e,n);if(t)return t}return null}function kn(n){let t=m(n);for(let i=0;i<4;i++){let o=u(t,"package.json");if(l(o))try{let r=JSON.parse(k(o,"utf8"));return r!=null&&typeof r==="object"&&"cline"in r}catch{return!1}let s=u(t,"..");if(s===t)return!1;t=s}return!1}function F(n,e){let t=e.startsWith("file:")?z(e):on(e)?e:u(m(n),e);if(l(t)&&b.has(v(t)))return t;for(let i of b){let o=`${t}${i}`;if(l(o))return o}for(let i of b){let o=u(t,`index${i}`);if(l(o))return o}return null}function U(n){let e=new Set,t=[/\bimport\s+(?:type\s+)?[^"'`]*?\bfrom\s*["'`]([^"'`]+)["'`]/g,/\bexport\s+[^"'`]*?\bfrom\s*["'`]([^"'`]+)["'`]/g,/\bimport\s*\(\s*["'`]([^"'`]+)["'`]\s*\)/g,/\brequire\s*\(\s*["'`]([^"'`]+)["'`]\s*\)/g];for(let i of t)for(let o of n.matchAll(i)){let s=o[1];if(s)e.add(s)}return[...e]}function Pn(n){return v(n)!==".ts"}function X(n,e,t=new Set){if(t.has(n)||!l(n))return;if(t.add(n),!b.has(v(n)))return;let i=k(n,"utf8"),o=Pn(n);for(let s of U(i)){if(s.startsWith("node:")||O.has(s))continue;if(E(s)){if(!o)continue;if(Object.hasOwn(T,s)||Object.hasOwn(T,h(s))||C(n,s)||L(s)&&W(s)||e&&W(s))continue;throw Error(`Cannot find module '${h(s)}'`)}let r=F(n,s);if(r)X(r,e,t)}}function G(n,e=new Set,t=new Set){if(e.has(n)||!l(n))return t;if(e.add(n),!b.has(v(n)))return t;let i=k(n,"utf8");for(let o of U(i)){if(t.add(o),E(o))continue;let s=F(n,o);if(s)G(s,e,t)}return t}function bn(n,e){let t=_(n),i={},o=G(n),s=new Set(cn);for(let[r,a]of Object.entries(T)){try{t.resolve(r);continue}catch{}i[r]=a}for(let r of o)if(E(r)&&(L(r)||e))s.add(r);for(let r of s){if(Object.hasOwn(i,r)||C(n,r))continue;let a=j(r);if(a)i[r]=a}if(!e)return i;for(let r of o){if(!E(r)||Object.hasOwn(i,r)||C(n,r)||r.startsWith("node:")||O.has(r))continue;let a=j(r);if(a)i[r]=a}return i}function vn(n){let e=v(n);return e===".ts"||e===".tsx"||e===".mts"||e===".cts"}var w;function yn(){if(w!==void 0)return w;let n=q("jiti");if(!n)return w=null,null;let e=u(n,"dist","babel.cjs");if(!l(e))return w=null,null;try{let i=_(e)(e);w=typeof i==="function"?i:null}catch{w=null}return w}async function K(n,e={}){let t=!kn(n);X(n,t);let i=bn(n,t),o=pn(i),s=await import("jiti"),r=typeof s==="function"?s:typeof s.default==="function"?s.default:void 0;if(!r)throw Error("Unable to load jiti");let a=Object.entries(o).filter(([,c])=>vn(c)).map(([c])=>c),g=yn(),p=g?(c)=>g({...c,interopDefault:!0}):void 0;return await r(n,{alias:o,cache:e.useCache,requireCache:e.useCache,esmResolve:!0,interopDefault:!1,nativeModules:[...O],transformModules:a,tryNative:!1,...p?{transform:p}:{}}).import(n,{})}function Y(n,e){if(!n)return!0;if(n.providerIds?.length){if(!e?.providerId||!n.providerIds.includes(e.providerId))return!1}if(n.modelIds?.length){if(!e?.modelId||!n.modelIds.includes(e.modelId))return!1}return!0}function f(n){return typeof n==="object"&&n!==null}function Q(n){return Array.isArray(n)&&n.every((e)=>typeof e==="string")}function En(n,e){if(!f(n))throw Error(`Invalid plugin module: ${e}`);if(typeof n.name!=="string"||!n.name)throw Error(`Invalid plugin name: ${e}`);if(!f(n.manifest))throw Error(`Invalid plugin manifest: ${e}`);if(Object.hasOwn(n.manifest,"providerIds")&&!Q(n.manifest.providerIds))throw Error(`Invalid plugin manifest.providerIds: ${e}`);if(Object.hasOwn(n.manifest,"modelIds")&&!Q(n.manifest.modelIds))throw Error(`Invalid plugin manifest.modelIds: ${e}`)}function Rn(n){if(!f(n))throw Error("Plugin setup context must be an object");if(n.session!==void 0&&!f(n.session))throw Error("Plugin setup context session must be an object");if(n.client!==void 0&&!f(n.client))throw Error("Plugin setup context client must be an object");if(n.user!==void 0&&!f(n.user))throw Error("Plugin setup context user must be an object");if(n.workspaceInfo!==void 0&&!f(n.workspaceInfo))throw Error("Plugin setup context workspaceInfo must be an object");if(n.automation!==void 0&&!f(n.automation))throw Error("Plugin setup context automation must be an object");if(n.automation!==void 0&&typeof n.automation.ingestEvent!=="function")throw Error("Plugin setup context automation.ingestEvent must be a function");if(n.logger!==void 0&&!f(n.logger))throw Error("Plugin setup context logger must be an object")}var V=0,R=new Map,N=new Map;function Sn(n){let e=n instanceof Error?n.message:String(n),t=n instanceof Error?n.stack:void 0;return{message:e,stack:t}}function D(n,e,t,i){if(!process.send)return;process.send({type:"response",id:n,ok:e,result:t,error:i})}function x(n,e){if(!process.send)return;process.send({type:"event",name:n,payload:e})}globalThis.__clinePluginHost={emitEvent:x};globalThis.__clineSessionEnv={cwd:void 0,workspaceInfo:void 0};function Z(n){if(!n||typeof n!=="object")return{};return n}function S(n){if(!n||typeof n!=="object")return;let e={...n};if(e.error instanceof Error)e.error={name:e.error.name,message:e.error.message,stack:e.error.stack};return e}function xn(n){let e=(t,i,o)=>{x("plugin_log",{level:t,pluginName:n,message:i,metadata:S(o)})};return{debug:(t,i)=>e("debug",t,i),log:(t,i)=>e("log",t,i),error:(t,i)=>e("error",t,i)}}function Mn(n){let e=(o)=>{x("plugin_telemetry",{pluginName:n,...o})},t=(o)=>(s,r,a,g,p)=>{e({kind:"metric",metric:o,name:s,value:r,attributes:S(a),description:g,required:p})},i=()=>{};return{capture:(o)=>{e({kind:"event",event:o?.event,properties:S(o?.properties)})},captureRequired:(o,s)=>{e({kind:"event",event:o,properties:S(s),required:!0})},recordCounter:t("counter"),recordHistogram:t("histogram"),recordGauge:t("gauge"),isEnabled:()=>!0,setDistinctId:i,setMetadata:i,updateMetadata:i,setCommonProperties:i,updateCommonProperties:i,flush:async()=>{},dispose:async()=>{}}}function P(n,e){let t=`${n}:${e}`,i=(N.get(t)??0)+1;return N.set(t,i),`${n}_${e}_${i}`}function Tn(n){let e=typeof n.eventType==="string"?n.eventType.trim():"",t=typeof n.source==="string"?n.source.trim():"";if(!e)throw Error("Automation event type contribution requires eventType");if(!t)throw Error("Automation event type contribution requires source");return{...n,eventType:e,source:t,examples:n.examples?[...n.examples]:void 0,metadata:n.metadata?Z(n.metadata):void 0}}function y(n){let e=R.get(n);if(!e)throw Error(`Unknown sandbox plugin id: ${n}`);return e}async function Cn(n){let e;try{let t=await K(n.pluginPath);if(e=t.default??t[n.exportName],En(e,n.pluginPath),e.manifest=In(e.manifest),!Y(e.manifest,n.targeting))return{type:"skipped"};let i={tools:[],commands:[],rules:[],messageBuilders:[],providers:[],automationEventTypes:[],mcpServers:[],shortcuts:[],flags:[]},o={tools:new Map,commands:new Map,rules:new Map,messageBuilders:new Map},s={registerTool:(r)=>{let a=P(n.pluginId,"tool");o.tools.set(a,r.execute),i.tools.push({id:a,name:r.name,description:r.description,inputSchema:r.inputSchema,timeoutMs:r.timeoutMs,retryable:r.retryable})},registerCommand:(r)=>{let a=P(n.pluginId,"command");if(typeof r.handler==="function")o.commands.set(a,r.handler);i.commands.push({id:a,name:r.name,description:r.description})},registerRule:(r)=>{let a=P(n.pluginId,"rule");if(typeof r.content==="function"){o.rules.set(a,r.content),i.rules.push({id:a,ruleId:r.id,source:r.source,hasContentHandler:!0});return}i.rules.push({id:a,ruleId:r.id,content:r.content,source:r.source})},registerMessageBuilder:(r)=>{let a=P(n.pluginId,"builder");o.messageBuilders.set(a,r.build),i.messageBuilders.push({id:a,name:r.name})},registerProvider:(r)=>{i.providers.push({id:P(n.pluginId,"provider"),name:r.name,description:r.description,metadata:Z(r.metadata)})},registerAutomationEventType:(r)=>{i.automationEventTypes.push({id:P(n.pluginId,"automation_event"),...Tn(r)})},registerMcpServer:(r)=>{i.mcpServers.push(r)}};if(typeof e.setup==="function")try{let r={...n.setupCtxBase,...n.telemetryEnabled?{telemetry:Mn(e.name)}:{},...n.loggerEnabled?{logger:xn(e.name)}:{},...e.manifest.capabilities.includes("automationEvents")?{automation:{ingestEvent:(a)=>{x("automation_event",a)}}}:{}};Rn(r),await e.setup(s,r)}catch(r){return{type:"failure",failure:{pluginPath:n.pluginPath,pluginName:e.name,phase:"setup",message:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0}}}return{type:"loaded",state:{plugin:e,handlers:o},descriptor:{pluginId:n.pluginId,pluginPath:n.pluginPath,name:e.name,manifest:e.manifest,hooks:e.hooks?Object.entries(e.hooks).filter(([,r])=>typeof r==="function").map(([r])=>r):void 0,contributions:i}}}catch(t){return{type:"failure",failure:{pluginPath:n.pluginPath,pluginName:e?.name,phase:"load",message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0}}}}async function jn(n){if(R.clear(),V=0,N.clear(),n.cwd)try{process.chdir(n.cwd)}catch{}let e=globalThis.__clineSessionEnv;if(e)e.cwd=n.cwd,e.workspaceInfo=n.workspaceInfo;let t=[],i=[],o=[],s=n.exportName||"plugin",r=new Map,a={providerId:n.providerId,modelId:n.modelId},g={session:n.session,client:n.client,user:n.user,workspaceInfo:n.workspaceInfo},p=await Promise.all((n.pluginPaths||[]).map((d)=>{let c=`plugin_${++V}`;return Cn({pluginPath:d,pluginId:c,exportName:s,targeting:a,setupCtxBase:g,loggerEnabled:n.loggerEnabled,telemetryEnabled:n.telemetryEnabled})}));for(let d of p){if(d.type==="skipped")continue;if(d.type==="failure"){i.push(d.failure);continue}let{descriptor:c,state:nn}=d,M=r.get(c.name);if(M!==void 0){let I=t[M];if(!I)r.delete(c.name);else{o.push({type:"duplicate_plugin_override",pluginName:c.name,pluginPath:c.pluginPath,overriddenPluginPath:I.pluginPath,message:`Plugin "${c.name}" from ${c.pluginPath} overrides ${I.pluginPath}`}),R.delete(I.pluginId),t.splice(M,1),r.clear();for(let[en,tn]of t.entries())r.set(tn.name,en)}}R.set(c.pluginId,nn),r.set(c.name,t.length),t.push(c)}return{plugins:t,failures:i,warnings:o}}async function _n(n){let t=y(n.pluginId).plugin.hooks?.[n.hookName];if(typeof t!=="function")return;return await t(n.payload)}async function On(n){let t=y(n.pluginId).handlers.tools.get(n.contributionId);if(typeof t!=="function")throw Error("Unknown sandbox tool contribution");return await t(n.input,n.context)}async function An(n){let t=y(n.pluginId).handlers.commands.get(n.contributionId);if(typeof t!=="function")return"";return await t(n.input)}async function Dn(n){let t=y(n.pluginId).handlers.messageBuilders.get(n.contributionId);if(typeof t!=="function")return[];return await t(n.messages)}async function Nn(n){let t=y(n.pluginId).handlers.rules.get(n.contributionId);if(typeof t!=="function")return"";return await t()}var Bn={initialize:jn,invokeHook:_n,executeTool:On,executeCommand:An,buildMessages:Dn,resolveRuleContent:Nn};B();process.on("message",async(n)=>{if(!n||n.type!=="call")return;let e=Bn[n.method];if(!e){D(n.id,!1,void 0,{message:`Unknown method: ${String(n.method)}`});return}try{let t=await e(n.args||{});D(n.id,!0,t)}catch(t){D(n.id,!1,void 0,Sn(t))}});
|
|
@@ -117,5 +117,5 @@ export declare function findScriptSyntaxError(filePath: string, text: string): s
|
|
|
117
117
|
* useful to say — the file's language is not one this understands, or its
|
|
118
118
|
* delimiters match.
|
|
119
119
|
*/
|
|
120
|
-
export declare function describeDelimiterBalance(filePath: string,
|
|
120
|
+
export declare function describeDelimiterBalance(filePath: string, withBom: string): string | null;
|
|
121
121
|
export {};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { AgentOverlay } from "../../../runtime/sandbox/overlay-fs";
|
|
9
9
|
import type { ApplyPatchExecutor } from "../types";
|
|
10
10
|
import { PatchActionType } from "./apply-patch-parser";
|
|
11
|
+
import { type ReadReceipts } from "./read-receipts";
|
|
11
12
|
export interface PatchFileChange {
|
|
12
13
|
type: PatchActionType;
|
|
13
14
|
oldContent?: string;
|
|
@@ -31,6 +32,13 @@ export interface ApplyPatchExecutorOptions {
|
|
|
31
32
|
restrictToCwd?: boolean;
|
|
32
33
|
/** A delegated agent's overlay; the patch reads and writes the agent's copies. */
|
|
33
34
|
overlay?: AgentOverlay;
|
|
35
|
+
/**
|
|
36
|
+
* The registry `read_files` and `editor` share. A patch is this session's
|
|
37
|
+
* own write, and has to be recorded as one: without it the next read said
|
|
38
|
+
* the file "changed since you last looked at it, and not because of
|
|
39
|
+
* anything you did", and the next edit was refused with the same words.
|
|
40
|
+
*/
|
|
41
|
+
receipts?: ReadReceipts;
|
|
34
42
|
}
|
|
35
43
|
/**
|
|
36
44
|
* Parse a patch and compute the per-file changes it would apply, without
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A UTF-8 byte order mark at the start of a file, kept out of every column.
|
|
3
|
+
*
|
|
4
|
+
* VS Code drops the mark from a document's text, so the language server's
|
|
5
|
+
* diagnostics -- the line and column `check_file` reports -- number line 1
|
|
6
|
+
* without it, and the model never sees an invisible character it could count.
|
|
7
|
+
* The editor and the delimiter scan counted it as column 1, so on line 1 of
|
|
8
|
+
* such a file every column they named or accepted was one off from the
|
|
9
|
+
* checker's: "column 3" deleted the character before the one meant.
|
|
10
|
+
*
|
|
11
|
+
* Every tool that shows a file or addresses it by column strips the mark,
|
|
12
|
+
* and every tool that writes puts it back, so the file keeps its encoding.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BOM = "\uFEFF";
|
|
15
|
+
export declare function splitBom(text: string): {
|
|
16
|
+
bom: string;
|
|
17
|
+
body: string;
|
|
18
|
+
};
|
|
@@ -101,6 +101,17 @@ export interface ReadWindow {
|
|
|
101
101
|
text: string;
|
|
102
102
|
firstLine: number;
|
|
103
103
|
lastLine: number;
|
|
104
|
+
/**
|
|
105
|
+
* Lines longer than `grep` prints, and how much of each was shown: up to
|
|
106
|
+
* `shown` of their `length` characters, all of it unless cut here.
|
|
107
|
+
*/
|
|
108
|
+
cuts?: readonly {
|
|
109
|
+
line: number;
|
|
110
|
+
shown: number;
|
|
111
|
+
length: number;
|
|
112
|
+
}[];
|
|
113
|
+
/** The file holds no lines at all: seeing that is seeing all of it. */
|
|
114
|
+
empty?: true;
|
|
104
115
|
}
|
|
105
116
|
/**
|
|
106
117
|
* Create a file read executor using Node.js fs module
|
|
@@ -23,6 +23,8 @@ export declare function truncateCommandOutput(text: string, options?: {
|
|
|
23
23
|
export declare const MAX_READ_LINES = 2000;
|
|
24
24
|
/** Max characters kept per line in file reads (defangs minified files). */
|
|
25
25
|
export declare const MAX_LINE_CHARS = 2000;
|
|
26
|
+
/** The most of one line `grep` prints; a longer one is cut around its match. */
|
|
27
|
+
export declare const MAX_GREP_LINE_CHARS = 400;
|
|
26
28
|
/** Max characters returned per file read window. */
|
|
27
29
|
export declare const MAX_READ_OUTPUT_CHARS = 48000;
|
|
28
30
|
/**
|
|
@@ -79,6 +79,37 @@ export interface ReadReceipts {
|
|
|
79
79
|
retire(filePath: string): void;
|
|
80
80
|
/** Drop everything known about a file. */
|
|
81
81
|
forget(filePath: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Record that a read showed only the first `shown` of a line's `length`
|
|
84
|
+
* characters.
|
|
85
|
+
*
|
|
86
|
+
* A line span alone said the whole line was seen. `read_files` cuts a line
|
|
87
|
+
* at 2,000 characters, so an edit by column past the cut, or a replace of
|
|
88
|
+
* the whole line, landed on characters the model was never shown (csf-16).
|
|
89
|
+
* Optional so a registry that does not track it still compiles; one that
|
|
90
|
+
* does not answers "not cut" for every line.
|
|
91
|
+
*
|
|
92
|
+
* `from` is the first column shown, 1 unless the read showed a window from
|
|
93
|
+
* the middle of the line, as `grep` does. A record with `from` 1 and
|
|
94
|
+
* `shown` at `length` says the line was seen whole; it is kept, so a later
|
|
95
|
+
* window does not narrow what an earlier read showed. Each call replaces
|
|
96
|
+
* the line's record; {@link noteShown} merges a new read into it.
|
|
97
|
+
*/
|
|
98
|
+
noteCut?(filePath: string, line: number, shown: number, length: number, from?: number): void;
|
|
99
|
+
/**
|
|
100
|
+
* Move a file's stamp from `from` to `to`, if `from` is the one held.
|
|
101
|
+
*
|
|
102
|
+
* For a rewrite that puts back content the session had already seen: the
|
|
103
|
+
* change protocol's check against the base writes every edited file twice
|
|
104
|
+
* and ends where it started, but the mtime moves, and the next edit was
|
|
105
|
+
* refused as "changed since you last read it". Matching on `from` keeps an
|
|
106
|
+
* outside write made before the rewrite visible. Optional, like `noteCut`.
|
|
107
|
+
*/
|
|
108
|
+
carryStamp?(filePath: string, from: FileStamp, to: FileStamp): void;
|
|
109
|
+
/** How much of `line` the reads showed, when one of them cut it. */
|
|
110
|
+
cutAt?(filePath: string, line: number): LineCut | undefined;
|
|
111
|
+
/** The lines of a file a read cut short. */
|
|
112
|
+
cutLines?(filePath: string): number[];
|
|
82
113
|
/**
|
|
83
114
|
* Every file read in this session, in the form it was resolved to.
|
|
84
115
|
*
|
|
@@ -90,4 +121,38 @@ export interface ReadReceipts {
|
|
|
90
121
|
*/
|
|
91
122
|
paths(): string[];
|
|
92
123
|
}
|
|
93
|
-
|
|
124
|
+
/**
|
|
125
|
+
* What the reads have shown of one long line: columns `from` (1 when absent)
|
|
126
|
+
* to `shown` of `length`.
|
|
127
|
+
*/
|
|
128
|
+
export interface LineCut {
|
|
129
|
+
shown: number;
|
|
130
|
+
length: number;
|
|
131
|
+
from?: number;
|
|
132
|
+
}
|
|
133
|
+
/** Whether a cut leaves nothing of the line unseen. */
|
|
134
|
+
export declare function isWhole(cut: LineCut): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Record that a read showed columns `from` to `to` of a line of `length`.
|
|
137
|
+
*
|
|
138
|
+
* Merged with what the line's record already holds: a window that overlaps or
|
|
139
|
+
* touches it widens it, so `grep` printing 400 characters of a line
|
|
140
|
+
* `read_files` showed whole leaves it whole. A window apart from it replaces
|
|
141
|
+
* it, as the newer of two views the model holds.
|
|
142
|
+
*/
|
|
143
|
+
export declare function noteShown(receipts: ReadReceipts | undefined, filePath: string, line: number, from: number, to: number, length: number): void;
|
|
144
|
+
/**
|
|
145
|
+
* The registry as its owner holds it: everything a reader sees, plus the reset
|
|
146
|
+
* that only the owner may call. An agent's overlay view is a `ReadReceipts`
|
|
147
|
+
* and so cannot clear the lead's reads.
|
|
148
|
+
*/
|
|
149
|
+
export interface OwnedReadReceipts extends ReadReceipts {
|
|
150
|
+
/**
|
|
151
|
+
* Forget every read. For the owner of a registry that outlives one task:
|
|
152
|
+
* the next task has read nothing, and the last task's reads would tell its
|
|
153
|
+
* first read that the file "changed since you last looked at it" (pandorum,
|
|
154
|
+
* 2026-10-18, ptm1c) and credit edits to lines it never saw.
|
|
155
|
+
*/
|
|
156
|
+
clear(): void;
|
|
157
|
+
}
|
|
158
|
+
export declare function createReadReceipts(): OwnedReadReceipts;
|
|
@@ -229,6 +229,21 @@ export declare class TaskProgressTracker {
|
|
|
229
229
|
* can be missed, said on every edit it is noise the model learns to skip.
|
|
230
230
|
*/
|
|
231
231
|
private noteUntrackedEdit;
|
|
232
|
+
/**
|
|
233
|
+
* Take back what {@link recordToolCall} counted for a call that then failed.
|
|
234
|
+
*
|
|
235
|
+
* The call is recorded before the tool runs, because that is the only place
|
|
236
|
+
* its checklist is still visible, so "changed a file" was decided from the
|
|
237
|
+
* tool's name. An `editor` call refused with "Read before editing ... The
|
|
238
|
+
* file was not modified" was then followed by "You just changed
|
|
239
|
+
* `/workspace/answer.txt` and this task has no checklist" (automaticum,
|
|
240
|
+
* 2026-10-13, SDK 4.100.250): a statement about the file that the result
|
|
241
|
+
* one line above it contradicts.
|
|
242
|
+
*
|
|
243
|
+
* Only the nudge this call queued is withdrawn. One already waiting from an
|
|
244
|
+
* edit that did land names a path of its own and is kept.
|
|
245
|
+
*/
|
|
246
|
+
retractFailedWrite(input: unknown, toolName?: string): void;
|
|
232
247
|
/**
|
|
233
248
|
* Hold a reminder for delivery after the turn's tool calls.
|
|
234
249
|
*
|