@cerebriline/core 4.100.274 → 4.100.276
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/assets/prompt-templates/claude.md +7 -7
- package/assets/prompt-templates/deepseek.md +8 -8
- package/assets/prompt-templates/default.md +13 -13
- package/assets/prompt-templates/gemma.md +5 -5
- package/assets/prompt-templates/glm.md +9 -9
- package/assets/prompt-templates/kimi-k3.md +8 -8
- package/assets/prompt-templates/kimi.md +10 -10
- package/assets/prompt-templates/minimax-m3.1-flash.md +9 -8
- package/assets/prompt-templates/minimax.md +12 -10
- package/assets/prompt-templates/nemotron.md +9 -9
- package/assets/prompt-templates/qwen.md +9 -9
- package/dist/cloud/index.js +1 -1
- package/dist/document-reader-child.js +20 -20
- package/dist/extensions/config/prompt-template-review.d.ts +1 -1
- package/dist/extensions/tools/ask-lsp.d.ts +1 -1
- package/dist/extensions/tools/browser.d.ts +1 -1
- package/dist/extensions/tools/check-file.d.ts +18 -3
- package/dist/extensions/tools/command-guard.d.ts +4 -3
- package/dist/extensions/tools/delimiter-balance.d.ts +50 -0
- package/dist/extensions/tools/edit-verification.d.ts +13 -4
- package/dist/extensions/tools/error-locations.d.ts +1 -1
- package/dist/extensions/tools/executors/awk-parser.d.ts +5 -0
- package/dist/extensions/tools/executors/awk.d.ts +14 -2
- package/dist/extensions/tools/executors/bash.d.ts +2 -0
- package/dist/extensions/tools/executors/document/formats.d.ts +4 -0
- package/dist/extensions/tools/executors/document/images.d.ts +6 -1
- package/dist/extensions/tools/executors/document/legacy.d.ts +9 -0
- package/dist/extensions/tools/executors/file-read.d.ts +15 -0
- package/dist/extensions/tools/executors/read-receipts.d.ts +10 -0
- package/dist/extensions/tools/executors/search.d.ts +2 -2
- package/dist/extensions/tools/executors/sed.d.ts +40 -0
- package/dist/extensions/tools/executors/unchanged-reads.d.ts +6 -0
- package/dist/extensions/tools/executors/web-fetch.d.ts +12 -0
- package/dist/extensions/tools/executors/whole-file.d.ts +7 -2
- package/dist/extensions/tools/helpers.d.ts +15 -1
- package/dist/extensions/tools/jev.d.ts +1 -1
- package/dist/extensions/tools/list-files.d.ts +17 -1
- package/dist/extensions/tools/media-endpoint.d.ts +16 -0
- package/dist/extensions/tools/model-tool-routing.d.ts +6 -0
- package/dist/extensions/tools/task-progress.d.ts +2 -0
- package/dist/extensions/tools/team/agent-check.d.ts +15 -2
- package/dist/extensions/tools/team/agent-controls.d.ts +1 -1
- package/dist/extensions/tools/team/batch-report.d.ts +8 -0
- package/dist/extensions/tools/team/lead-agent-tools.d.ts +2 -2
- package/dist/hub/daemon/entry.js +718 -635
- package/dist/hub/index.js +703 -620
- package/dist/index.d.ts +1 -1
- package/dist/index.js +924 -838
- package/dist/remote/remote-helper-entry.js +1 -1
- package/dist/remote/remote-helper.js +1 -1
- package/dist/runtime/atomic/check-progress.d.ts +13 -0
- package/dist/runtime/atomic/file-revisions.d.ts +15 -1
- package/dist/runtime/atomic/oracle.d.ts +14 -0
- package/dist/runtime/atomic/page-check.d.ts +12 -2
- package/dist/runtime/atomic/plan-tool.d.ts +14 -2
- package/dist/runtime/atomic/protocol.d.ts +2 -0
- package/dist/runtime/atomic/restore-file-tool.d.ts +3 -3
- package/dist/runtime/atomic/snapshot.d.ts +15 -0
- package/dist/runtime/atomic/stalled-checks.d.ts +12 -4
- package/dist/runtime/atomic/transaction-controller.d.ts +10 -0
- package/dist/runtime/atomic/unparseable-change.d.ts +3 -1
- package/dist/runtime/safety/loop-detection.d.ts +15 -1
- package/dist/services/retrieval/memory.d.ts +9 -0
- package/dist/services/sdd/sdd-engine.d.ts +14 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{homedir as $n}from"node:os";import{claimHubDaemonProcess as jn}from"@cerebriline/shared";import{setHomeDirIfUnset as Gn}from"@cerebriline/shared/storage";import{createSessionId as gn,ensureLoopbackProxyBypass as Ue,isHubProtocolCompatible as bn,resolveClineBuildEnv as yn,resolveHubCommandTimeoutMs as wn}from"@cerebriline/shared";import vn from"ws";var P={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var ie="session_not_found";class F extends Error{sessionId;code="session_not_found";constructor(e,t){super(t??(e?`session not found: ${e}`:"session not found"));this.sessionId=e;this.name="SessionNotFoundError"}}import{spawn as Lt}from"node:child_process";import{closeSync as Ot,mkdirSync as Ut,openSync as Mt,readFileSync as Bt,unlinkSync as Nt}from"node:fs";import{basename as Vt,dirname as Ft,join as Wt}from"node:path";import{fileURLToPath as $t}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as jt,isBunEmbeddedModulePath as Gt,isHubDaemonProcess as qt,resolveClineBuildEnv as Ee,withResolvedClineBuildEnv as Kt}from"@cerebriline/shared";import{createHash as Xe,randomBytes as Ze}from"node:crypto";import{mkdir as j,open as se,readFile as le,rename as Qe,rm as I,writeFile as et}from"node:fs/promises";import{dirname as pe,join as G}from"node:path";import{ensureLoopbackProxyBypass as tt,isHubProtocolCompatible as nt}from"@cerebriline/shared";import{resolveClineDataDir as H,resolveClineDir as eo}from"@cerebriline/shared/storage";var ot="CLINE_HUB_DISCOVERY_PATH",rt="CLINE_HUB_BUILD_ID",it="CLINE_HUB_BUILD_EPOCH_MS",st=30000,at=15000,ae=100;function ct(e){return e.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function ut(e){return Xe("sha256").update(e).digest("hex").slice(0,12)}function dt(e){if(!Number.isInteger(e)||!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t instanceof Error&&"code"in t?String(t.code)==="EPERM":!1}}function ce(e){return new Promise((t)=>setTimeout(t,e))}function lt(e){return`${e}.lock`}async function pt(e){try{let t=JSON.parse(await le(G(e,"owner.json"),"utf8"));if(typeof t.pid!=="number"||typeof t.acquiredAt!=="string")return;return{pid:t.pid,acquiredAt:t.acquiredAt}}catch{return}}async function W(e){await I(e,{recursive:!0,force:!0}).catch(()=>{return})}function k(){let e=process.env[rt]?.trim();if(e)return e;return"sdk-v1-
|
|
1
|
+
import{homedir as $n}from"node:os";import{claimHubDaemonProcess as jn}from"@cerebriline/shared";import{setHomeDirIfUnset as Gn}from"@cerebriline/shared/storage";import{createSessionId as gn,ensureLoopbackProxyBypass as Ue,isHubProtocolCompatible as bn,resolveClineBuildEnv as yn,resolveHubCommandTimeoutMs as wn}from"@cerebriline/shared";import vn from"ws";var P={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var ie="session_not_found";class F extends Error{sessionId;code="session_not_found";constructor(e,t){super(t??(e?`session not found: ${e}`:"session not found"));this.sessionId=e;this.name="SessionNotFoundError"}}import{spawn as Lt}from"node:child_process";import{closeSync as Ot,mkdirSync as Ut,openSync as Mt,readFileSync as Bt,unlinkSync as Nt}from"node:fs";import{basename as Vt,dirname as Ft,join as Wt}from"node:path";import{fileURLToPath as $t}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as jt,isBunEmbeddedModulePath as Gt,isHubDaemonProcess as qt,resolveClineBuildEnv as Ee,withResolvedClineBuildEnv as Kt}from"@cerebriline/shared";import{createHash as Xe,randomBytes as Ze}from"node:crypto";import{mkdir as j,open as se,readFile as le,rename as Qe,rm as I,writeFile as et}from"node:fs/promises";import{dirname as pe,join as G}from"node:path";import{ensureLoopbackProxyBypass as tt,isHubProtocolCompatible as nt}from"@cerebriline/shared";import{resolveClineDataDir as H,resolveClineDir as eo}from"@cerebriline/shared/storage";var ot="CLINE_HUB_DISCOVERY_PATH",rt="CLINE_HUB_BUILD_ID",it="CLINE_HUB_BUILD_EPOCH_MS",st=30000,at=15000,ae=100;function ct(e){return e.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function ut(e){return Xe("sha256").update(e).digest("hex").slice(0,12)}function dt(e){if(!Number.isInteger(e)||!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t instanceof Error&&"code"in t?String(t.code)==="EPERM":!1}}function ce(e){return new Promise((t)=>setTimeout(t,e))}function lt(e){return`${e}.lock`}async function pt(e){try{let t=JSON.parse(await le(G(e,"owner.json"),"utf8"));if(typeof t.pid!=="number"||typeof t.acquiredAt!=="string")return;return{pid:t.pid,acquiredAt:t.acquiredAt}}catch{return}}async function W(e){await I(e,{recursive:!0,force:!0}).catch(()=>{return})}function k(){let e=process.env[rt]?.trim();if(e)return e;return"sdk-v1-d70a53e60a51848baa4d382e98c5b4d9802a03a57d2bbb1c948887ac3e4ee94b".trim()||`source-${String(P.version)}`}function ft(){let e=Number(process.env[it]);if(Number.isFinite(e)&&e>0)return e;return Number.isFinite(1794145572502)?1794145572502:void 0}function x(e,t=k()){let n=nt(e);if(!n.compatible)return n;let o=e.buildId?.trim();if(!o)return{compatible:!1,reason:"missing_build"};if(o!==t)return{compatible:!1,reason:"build_mismatch"};return{compatible:!0}}function ue(e){return typeof e==="number"&&Number.isFinite(e)&&e>0?e:void 0}function de(e){let t=e?.trim().split(/[-+]/,1)[0];if(!t)return;let n=t.split(".").map((o)=>Number(o));if(n.length===0||n.some((o)=>!Number.isInteger(o)||o<0))return;return n}function mt(e,t){for(let n=0;n<Math.max(e.length,t.length);n++){let o=e[n]??0,r=t[n]??0;if(o!==r)return o<r?-1:1}return 0}function fe(e,t){let n=e.buildId?.trim(),o=t.buildId?.trim();if(n&&o&&n===o)return 0;let r=ue(e.buildEpochMs),i=ue(t.buildEpochMs);if(r!==void 0&&i!==void 0&&r!==i)return r<i?-1:1;let s=de(e.coreVersion),u=de(t.coreVersion);if(s&&u){let c=mt(s,u);if(c!==0)return c}if(n&&o&&n!==o)return n<o?-1:1;return 0}function me(){return{buildId:k(),buildEpochMs:ft(),coreVersion:String(P.version)}}function D(e,t){let n=t?.self??me(),o=x(e,n.buildId??"");if(o.compatible)return!0;if(o.reason!=="build_mismatch"&&o.reason!=="missing_build")return!1;return fe(n,e)<=0}function he(e=process.argv[1]?.trim()||process.cwd()){let t=`hub-${ut(e)}`,n=process.env[ot]?.trim()||G(H(),"locks","hub","owners",`${ct(t)}.json`);return{ownerId:t,discoveryPath:n}}async function b(e){try{let t=JSON.parse(await le(e,"utf8"));if(typeof t.hubId!=="string"||typeof t.protocolVersion!=="string"||typeof t.authToken!=="string"||typeof t.host!=="string"||typeof t.port!=="number"||typeof t.url!=="string"||typeof t.startedAt!=="string"||typeof t.updatedAt!=="string")return;return{hubId:t.hubId,protocolVersion:t.protocolVersion,minClientProtocolVersion:typeof t.minClientProtocolVersion==="string"?t.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof t.maxClientProtocolVersion==="string"?t.maxClientProtocolVersion:void 0,capabilities:Array.isArray(t.capabilities)?t.capabilities.filter((n)=>typeof n==="string"):void 0,coreVersion:typeof t.coreVersion==="string"?t.coreVersion:void 0,buildId:typeof t.buildId==="string"?t.buildId:void 0,buildEpochMs:typeof t.buildEpochMs==="number"?t.buildEpochMs:void 0,authToken:t.authToken,host:t.host,port:t.port,url:t.url,pid:typeof t.pid==="number"?t.pid:void 0,startedAt:t.startedAt,updatedAt:t.updatedAt}}catch{return}}async function ge(e,t,n){await q(e,async()=>{let o=pe(e);await j(o,{recursive:!0});let r=`${e}.${process.pid}.${Ze(6).toString("hex")}.tmp`,i;try{i=await se(r,"wx",384),await i.writeFile(`${JSON.stringify(t,null,2)}
|
|
2
2
|
`,{encoding:"utf8"}),await i.sync(),await i.close(),i=void 0,n?.beforePublish?.(),await Qe(r,e);let s;try{s=await se(o,"r"),await s.sync()}catch{}finally{await s?.close().catch(()=>{return})}}catch(s){throw await i?.close().catch(()=>{return}),await I(r,{force:!0}).catch(()=>{return}),s}})}async function C(e){await q(e,async()=>{await I(e,{force:!0}).catch(()=>{return})})}async function be(e,t){return await q(e,async()=>{if((await b(e))?.hubId!==t)return!1;return await I(e,{force:!0}),!0})}async function ye(e,t,n){let o=lt(e);await j(pe(o),{recursive:!0});let r=Date.now()+at;while(!0){try{await j(o,{recursive:!1})}catch(i){if((i instanceof Error&&"code"in i?String(i.code):"")!=="EEXIST")throw i;let u=await pt(o);if(!u){if(Date.now()>=r){await W(o);continue}await ce(ae);continue}let c=Date.now()-Date.parse(u.acquiredAt);if(!dt(u.pid)||c>st){await W(o);continue}if(Date.now()>=r)throw Error(`Timed out waiting for hub ${t} lock ${o}`);await ce(ae);continue}try{return await et(G(o,"owner.json"),`${JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()},null,2)}
|
|
3
3
|
`,"utf8"),await n()}finally{await W(o)}}}function q(e,t){return ye(`${e}.mutation`,"discovery mutation",t)}function we(e,t){return ye(e,"startup",t)}async function A(e,t){tt();try{let n=await fetch(t?.authToken?ht(e):Se(e),{headers:t?.authToken?{authorization:`Bearer ${t.authToken}`}:void 0,signal:t?.signal});if(!n.ok)return;let o=await n.json();if(typeof o.protocolVersion!=="string"||typeof o.host!=="string"||typeof o.port!=="number"||typeof o.url!=="string")return;return{protocolVersion:o.protocolVersion,minClientProtocolVersion:typeof o.minClientProtocolVersion==="string"?o.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof o.maxClientProtocolVersion==="string"?o.maxClientProtocolVersion:void 0,capabilities:Array.isArray(o.capabilities)?o.capabilities.filter((r)=>typeof r==="string"):void 0,coreVersion:typeof o.coreVersion==="string"?o.coreVersion:void 0,buildId:typeof o.buildId==="string"?o.buildId:void 0,buildEpochMs:typeof o.buildEpochMs==="number"?o.buildEpochMs:void 0,host:o.host,port:o.port,url:o.url,hubId:typeof o.hubId==="string"?o.hubId:void 0,authToken:typeof o.authToken==="string"?o.authToken:void 0,pid:typeof o.pid==="number"?o.pid:void 0,startedAt:typeof o.startedAt==="string"?o.startedAt:void 0,updatedAt:typeof o.updatedAt==="string"?o.updatedAt:void 0}}catch{return}}function ve(e,t,n="/hub"){return new URL(`ws://${e}:${t}${n}`).toString()}function Se(e){let t=new URL(e);return t.protocol=t.protocol==="wss:"?"https:":"http:",t.pathname="/health",t.search="",t.toString()}function ht(e){let t=new URL(Se(e));return t.pathname="/status",t.toString()}import{CLINE_HUB_DEV_PORT as gt,CLINE_HUB_PORT as bt,resolveClineBuildEnv as yt}from"@cerebriline/shared";var wt="CLINE_HUB_HOST",vt="CLINE_HUB_PORT",St="CLINE_HUB_PATHNAME",kt="127.0.0.1",Ct=bt,Pt="/hub";function ke(e){return yt(e)==="development"?gt:Ct}function Ht(e={}){return(e.env??process.env)[wt]?.trim()||kt}function Rt(e={}){let n=(e.env??process.env)[vt]?.trim();if(!n)return ke(e);let o=Number.parseInt(n,10);if(!Number.isInteger(o)||o<1||o>65535)return ke(e);return o}function _t(e={}){return(e.env??process.env)[St]?.trim()||Pt}function Ce(e={},t={}){return{host:e.host??Ht(t),port:e.port??Rt(t),pathname:e.pathname??_t(t)}}import{join as It}from"node:path";import{execFile as Tt}from"node:child_process";import{promisify as Et}from"node:util";import{processWorkspaceInfo as co}from"@cerebriline/shared";import lo from"simple-git";var po=Et(Tt);var xt="shared:cline",Dt="CLINE_HUB_DISCOVERY_PATH",At="hub-production";function R(e=xt){return he(`${e}@${k()}`)}function L(){return{ownerId:At,discoveryPath:process.env[Dt]?.trim()||It(H(),"locks","hub","production.json")}}var Pe=15000,Jt=200,He=3000,zt=100,Yt=[100,250,500,1000,2000],Xt="--cline-hub-daemon",Zt=3,Qt=60000,Re=new Map;function en(e,t=Date.now()){let n=Re.get(e);if(!n||t-n.windowStartedAt>Qt)return Re.set(e,{count:1,windowStartedAt:t}),!0;return n.count+=1,n.count<=Zt}function tn(e){return[...e.host?["--host",e.host]:[],...typeof e.port==="number"?["--port",String(e.port)]:[],...e.pathname?["--pathname",e.pathname]:[]]}function nn(){try{let e=Wt(H(),"logs","hub-daemon.log");return Ut(Ft(e),{recursive:!0}),{fd:Mt(e,"a"),logPath:e}}catch{return}}function on(){return Ee()==="production"?L():R()}function _(e){return D(e)}function rn(e){try{let t=JSON.parse(Bt(`${e}.superseded`,"utf8"));return{url:typeof t.url==="string"?t.url:void 0,authToken:typeof t.authToken==="string"?t.authToken:void 0,pid:typeof t.pid==="number"?t.pid:void 0}}catch{return}}function K(e){try{Nt(`${e}.superseded`)}catch{}}function _e(e,t,n){if(!t||t.url!==n)return e;return{...e,authToken:e.authToken??t.authToken,pid:e.pid??t.pid}}async function T(e,t){try{return await A(e,{authToken:t})}catch{return}}async function Te(e,t){let n=Date.now()+t;while(Date.now()<n){if(!(await T(e))?.url)return!0;await new Promise((r)=>setTimeout(r,zt))}return!1}async function z(e,t){if(!en(e.url))return!1;await E(e.url,e.authToken,"retired by newer install").catch(()=>!1),await M(e.url,e.authToken).catch(()=>!1);let n=await Te(e.url,He);if(!n&&e.pid&&sn(e.pid)){try{process.kill(e.pid,"SIGTERM")}catch{}n=await Te(e.url,He)}if(n)await C(t).catch(()=>{return});return n}function sn(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function an(e){try{return(await Y(e.url,e.authToken)).activeSessionCount>0}catch{return!1}}async function J(e,t){if(_(e))return"reusable";let n=await E(e.url,e.authToken,"retired by newer install").catch(()=>!1);if(await an(e)){if(n)await E(e.url,e.authToken,"hub retirement deferred",{off:!0}).catch(()=>!1);return"deferred_busy"}let o=await z(e,t);if(!o&&n)await E(e.url,e.authToken,"hub retirement failed",{off:!0}).catch(()=>!1);return o?"retired":"failed"}async function cn(e){if(Ee()!=="production")return;let t=R();if(t.discoveryPath===e.discoveryPath)return;let n=await b(t.discoveryPath);if(n?.url)await z(n,t.discoveryPath);else await C(t.discoveryPath).catch(()=>{return})}function un(){let e=import.meta.url.endsWith(".ts")?"ts":"js";return $t(new URL(`./entry.${e}`,import.meta.url))}function dn(e,t){if(Gt(e))return[Xt];return[...t&&e.toLowerCase().endsWith(".ts")?["--conditions=development"]:[],e]}function ln(e,t){let n=un(),o=process.execPath?.trim();if(!o)throw Error("unable to resolve runtime executable for hub daemon");let r=Vt(o).toLowerCase().includes("bun"),i=dn(n,r);return{launcher:o,args:[...i,"--cwd",e,...tn(t),...t.manageConnectors===!1?["--no-connectors"]:[]],cwd:e,env:{...Kt(process.env),CLINE_NO_INTERACTIVE:"1",[jt]:"1"}}}function pn(e){if(!e||typeof e!=="object")return!1;if(("code"in e?e.code:void 0)==="ETXTBSY")return!0;let n="message"in e?e.message:void 0;return typeof n==="string"&&n.includes("ETXTBSY")}function fn(e,t={}){if(qt())return;let n=ln(e,t),o=nn();try{Lt(n.launcher,n.args,{detached:!0,stdio:o?["ignore",o.fd,o.fd]:"ignore",env:n.env,cwd:n.cwd,windowsHide:!0}).unref()}finally{if(o)Ot(o.fd)}}async function mn(e,t={}){for(let n=0;;n++)try{fn(e,t);return}catch(o){let r=Yt[n];if(!pn(o)||r===void 0)throw o;await new Promise((i)=>setTimeout(i,r))}}async function hn(e,t,n={}){let o=n.host!==void 0||n.port!==void 0||n.pathname!==void 0||!!process.env.CLINE_HUB_PORT?.trim(),r=Ce(n),i=ve(r.host,r.port,r.pathname),s=(l)=>{if(!o)U(l.url,l.authToken);else Ie(l.url,l.authToken);return l};await cn(e).catch(()=>{return});let u=await b(e.discoveryPath),c=u?.url?void 0:rn(e.discoveryPath),d=!1;if(u?.url){let l=u.authToken;if(!l)d=!0,await z(u,e.discoveryPath);else{let p=await T(u.url,l);if(p?.url&&_(p)&&await y(p.url,{authToken:l}))return K(e.discoveryPath),s({url:p.url,authToken:l});if(p?.url){if(await J({...p,authToken:l},e.discoveryPath)==="deferred_busy"&&await y(p.url,{authToken:l}))return s({url:p.url,authToken:l})}else await C(e.discoveryPath).catch(()=>{return})}}let a=await T(i);if(a?.url){let l=_e(a,u??c,i);if(_(a)){let h=[a.authToken,u?.authToken,c?.authToken].filter((S)=>typeof S==="string"&&S.trim().length>0);for(let S of h){if(!await y(a.url,{authToken:S}))continue;let ze={hubId:a.hubId??`repaired-${a.port}`,protocolVersion:a.protocolVersion,minClientProtocolVersion:a.minClientProtocolVersion,maxClientProtocolVersion:a.maxClientProtocolVersion,capabilities:a.capabilities,coreVersion:a.coreVersion,buildId:a.buildId,authToken:S,host:a.host,port:a.port,url:a.url,pid:a.pid??u?.pid??c?.pid,startedAt:a.startedAt??new Date().toISOString(),updatedAt:new Date().toISOString()};try{await ge(e.discoveryPath,ze)}catch{}return K(e.discoveryPath),s({url:a.url,authToken:S})}throw Error(`A compatible Cline Hub is already running at ${i}, but its discovery record is missing or unreadable and no usable auth token is available. Run 'cline doctor fix' to repair local hub discovery.${d?" This can happen immediately after upgrading from a build that wrote an empty hub auth token; run 'cline doctor fix' to stop the old daemon and repair local hub discovery.":""}`)}let p=await J(l,e.discoveryPath);if(p==="deferred_busy"){for(let h of[l.authToken,u?.authToken].filter((v)=>typeof v==="string"&&v.trim().length>0))if(await y(a.url,{authToken:h}))return s({url:a.url,authToken:h});if(n.allowPortFallback!==!0&&r.port!==0)throw Error(`An older Cline Hub is running at ${i} and is still serving active sessions, so it was not replaced, but no usable auth token is available to attach to it. Finish those sessions, or run 'cline doctor fix' to stop the hub.`)}if(p==="failed"&&n.allowPortFallback!==!0&&r.port!==0)throw Error(`An incompatible Cline Hub is already running at ${i} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}let g=n.allowPortFallback===!0&&r.port!==0?{...r,port:0}:r;await mn(t,{...g,manageConnectors:n.manageConnectors});let w=Date.now()+Pe;while(Date.now()<w){let l=await b(e.discoveryPath);if(l?.url&&l.authToken){let h=await T(l.url,l.authToken);if(h?.url&&_(h)&&await y(h.url,{authToken:l.authToken}))return K(e.discoveryPath),s({url:h.url,authToken:l.authToken})}let p=await T(i);if(p?.url&&!_(p)){let h=_e(p,l??c,i),v=await J(h,e.discoveryPath);if(v==="deferred_busy"&&l?.authToken&&await y(p.url,{authToken:l.authToken}))return s({url:p.url,authToken:l.authToken});if(v==="failed"&&n.allowPortFallback!==!0&&r.port!==0)throw Error(`An incompatible Cline Hub is still running at ${i} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}await new Promise((h)=>setTimeout(h,Jt))}throw Error(`Timed out after ${Pe}ms waiting for detached hub startup.`)}async function O(e,t={}){let n=on();return await we(n.discoveryPath,async()=>hn(n,e,t))}function Sn(){return yn()==="production"?L():R()}function kn(){let e=globalThis.WebSocket;if(!e)throw Error("Global WebSocket is not available in this runtime. Node 22+ is required for hub mode.");return e}function Me(e){if(typeof e==="string")return e;if(e instanceof Uint8Array)return Buffer.from(e).toString();if(e instanceof ArrayBuffer)return Buffer.from(e).toString();if(Array.isArray(e))return Buffer.concat(e.map((t)=>Buffer.from(t))).toString();if(e&&typeof e==="object"&&"data"in e&&typeof e.data<"u")return Me(e.data);return String(e)}function Cn(e){if(typeof e==="string")return e;if(e instanceof Uint8Array)return Buffer.from(e).toString("utf8");if(e instanceof ArrayBuffer)return Buffer.from(e).toString("utf8");return""}function xe(e){let t=e,n=Cn(t.reason);return new f("hub_connection_closed",t.code||n?`Hub connection closed (code=${t.code??0}${n?`, reason=${n}`:""})`:Z,{closeCode:t.code,closeReason:n||void 0})}function De(e,t){if(e instanceof f)return e;if(e instanceof Error)return new f("hub_connect_failed",e.message);if(e&&typeof e==="object"&&"error"in e&&e.error instanceof Error)return new f("hub_connect_failed",e.error.message);let n=e&&typeof e==="object"&&"message"in e&&typeof e.message==="string"?e.message.trim():"";if(n)return new f("hub_connect_failed",n);let o=e&&typeof e==="object"&&"type"in e&&typeof e.type==="string"?e.type.trim():"";return new f("hub_connect_failed",o?`Failed to connect to hub at ${t.toString()} (${o} event before socket open).`:`Failed to connect to hub at ${t.toString()}.`)}var X="*",B=8000,Pn="cline-hub-auth.",te=new Map,Be=new Set,Hn=3000;var Z="Hub connection closed",Rn=250,_n=5000,Ae=0.5;class f extends Error{code;details;constructor(e,t,n){super(t);this.code=e;this.details=n;this.name="HubTransportError"}}function Tn(e){return e instanceof f}class Q extends Error{command;code;constructor(e,t,n){super(n);this.command=e;this.code=t;this.name="HubCommandError"}}function ne(e,t={}){let n=e.searchParams.get("authToken")?.trim();if(e.searchParams.delete("authToken"),n)return n;if(t.skipRegistry)return;let o=N(e.toString());return o?te.get(o):void 0}function En(e){try{let n=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"");return n==="localhost"||n==="127.0.0.1"||n==="::1"}catch{return!1}}function N(e){if(!En(e))return;let t=new URL(Ne(e));return t.search="",t.hash="",t.toString()}function Le(e){let t=N(e);return!!t&&Be.has(t)}function U(e,t){let n=N(e);if(n){if(Be.add(n),t?.trim())te.set(n,t)}return e}function Ie(e,t){let n=N(e);if(n&&t?.trim())te.set(n,t)}class oe{options;socket;connectPromise;clientId;currentUrl;recoveryPromise;pendingReplies=new Map;listeners=new Set;subscriptionCounts=new Map;lastEventSequenceByKey=new Map;reconnectTimer;reconnectAttempt=0;closedByClient=!1;connectGeneration=0;lastCloseError=new f("hub_connection_closed",Z);sawSocketClose=!1;registered=!1;capabilities;constructor(e){this.options=e;if(e.authToken?.trim()&&e.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");this.clientId=e.clientId??`core-${Math.random().toString(36).slice(2,10)}-${Date.now().toString(36)}`,this.currentUrl=e.url,this.capabilities=[...e.capabilities??[]]}getClientId(){return this.clientId}getUrl(){return this.currentUrl}isConnected(){return this.socket?.readyState===1&&this.registered}getConnectionError(){return this.isConnected()?null:this.lastCloseError}async updateCapabilities(e){if(this.capabilities=e.map((t)=>({...t})),!this.registered)return;await this.command("client.update",{capabilities:this.capabilities})}async connect(){if(this.connectPromise)return this.connectPromise;if(this.socket&&(this.socket.readyState===1||this.socket.readyState===0))return this.connectPromise??Promise.resolve();this.closedByClient=!1,this.clearReconnectTimer();let e=new URL(this.currentUrl),t=this.options.authToken?.trim()||ne(e,{skipRegistry:Boolean(this.options.resolveConnectionHeaders)});if(e.hash="",t&&this.options.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");let n=++this.connectGeneration,o=this.openSocket(e,t,n),r;this.connectPromise=o.then(async(s)=>{if(r=s,await this.commandOnce("client.register",{clientId:this.clientId,clientType:this.options.clientType??"core",displayName:this.options.displayName??"core",transport:"native",actorKind:"client",capabilities:this.capabilities,metadata:{...this.options.metadata,version:this.options.clientVersion??String(P.version),pid:process.pid},workspaceContext:{workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}},void 0,void 0,!1),n!==this.connectGeneration||this.closedByClient){try{s.close()}catch{}throw this.lastCloseError}this.registered=!0;for(let u of this.subscriptionCounts.keys())this.sendSubscriptionFrame("stream.subscribe",this.subscriptionSessionIdFromKey(u));this.reconnectAttempt=0});let i=this.connectPromise;try{await i}catch(s){if(this.connectPromise===i)this.connectPromise=void 0;if(r&&this.socket===r){this.lastCloseError=De(s,e),this.registered=!1,this.sawSocketClose=!1,this.socket=void 0;try{r.close()}catch{}}if(!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect();throw s}}async openSocket(e,t,n){let o=this.options.resolveConnectionHeaders,r;if(o){let c;try{r=await Promise.race([Promise.resolve().then(()=>o()),new Promise((d,a)=>{c=setTimeout(()=>{a(new f("hub_connect_timeout",`Timed out resolving hub connection headers after ${B}ms`))},B)})])}catch(d){let a=d instanceof f?d:new f("hub_connect_failed",d instanceof Error?d.message:String(d));if(n===this.connectGeneration)this.lastCloseError=a;throw a}finally{clearTimeout(c)}}if(n!==this.connectGeneration||this.closedByClient)throw this.lastCloseError;if(r&&Object.keys(r).some((c)=>c.toLowerCase()==="sec-websocket-protocol")){let c=new f("hub_connect_failed","Hub connection headers cannot set Sec-WebSocket-Protocol.");if(n===this.connectGeneration)this.lastCloseError=c;throw c}let i=r?new vn(e.toString(),{headers:{...r}}):new(kn())(e.toString(),t?[`${Pn}${t}`]:void 0);this.socket=i;let s=!1,u=new Promise((c,d)=>{let a=!1,m=setTimeout(()=>{if(a)return;a=!0,s=!0;let g=new f("hub_connect_timeout",`Timed out connecting to hub after ${B}ms`);if(this.socket===i)this.lastCloseError=g,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;try{i.close()}catch{}d(g)},B);i.addEventListener("open",()=>{if(a)return;a=!0,clearTimeout(m),c()}),i.addEventListener("error",(g)=>{if(a)return;a=!0,clearTimeout(m);let w=De(g,e);if(this.socket===i)this.lastCloseError=w,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;d(w)}),i.addEventListener("close",(g)=>{if(a)return;a=!0,clearTimeout(m);let w=s?this.lastCloseError:xe(g);if(this.socket===i){if(!s)this.lastCloseError=w,this.sawSocketClose=!0;this.connectPromise=void 0,this.socket=void 0}d(w)})});return i.addEventListener("message",(c)=>{this.handleFrame(JSON.parse(Me(c)))}),i.addEventListener("close",(c)=>{if(this.socket!==i)return;if(!s)this.lastCloseError=xe(c),this.sawSocketClose=!0;this.registered=!1;for(let d of this.pendingReplies.values())d.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,this.socket=void 0,!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect()}),await u,i}subscribe(e,t){let n=t?.sessionId?.trim()||void 0,o={listener:e,sessionId:n};return this.listeners.add(o),this.adjustSubscriptionCount(n,1),()=>{if(!this.listeners.delete(o))return;this.adjustSubscriptionCount(n,-1)}}async command(e,t,n,o){let r=0,i=e!=="client.register"&&e!=="client.unregister";while(!0)try{return await this.commandOnce(e,t,n,o)}catch(s){if(!i||r>=1||!await this.recoverLocalHubTransport(s))throw s;r+=1}}async commandOnce(e,t,n,o,r=!0){if(r)await this.connect();o?.beforeDispatch?.();let i=gn("hubreq_");o?.onDispatch?.(i);let s=wn(e,o?.timeoutMs),u=new Promise((d,a)=>{let m=s===null?void 0:setTimeout(()=>{if(!this.pendingReplies.delete(i))return;a(new Q(e,"hub_command_timeout",`Hub command ${e} timed out after ${s}ms (hub=${this.currentUrl}, requestId=${i}, clientId=${this.clientId}). Check hub-daemon.log for matching command.start/command.slow entries, or run 'cline doctor fix' to restart the hub.`))},s);this.pendingReplies.set(i,{resolve:(g)=>{if(m)clearTimeout(m);d(g)},reject:(g)=>{if(m)clearTimeout(m);a(g)}})});try{this.sendFrame({kind:"command",envelope:{version:"v1",command:e,requestId:i,clientId:this.clientId,sessionId:n,timeoutMs:s,payload:t}})}catch(d){throw this.pendingReplies.delete(i),d}let c=await u;if(!c.ok){if(c.error?.code===ie){let d=n??(typeof t?.sessionId==="string"?t.sessionId:void 0);throw new F(d,c.error.message)}throw new Q(e,c.error?.code,c.error?.message??`Hub command ${e} failed`)}return c}async recoverLocalHubTransport(e){if(!Le(this.currentUrl)||!Tn(e))return!1;if(this.recoveryPromise)return await this.recoveryPromise;return this.recoveryPromise=(async()=>{let t=await Oe({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}).catch(()=>{return});if(!t)return!1;return this.currentUrl=t,this.close(),!0})().finally(()=>{this.recoveryPromise=void 0}),await this.recoveryPromise}hasActiveSubscriptions(){return this.subscriptionCounts.size>0}clearReconnectTimer(){if(!this.reconnectTimer)return;clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0}scheduleReconnect(){if(this.reconnectTimer||this.closedByClient||!this.hasActiveSubscriptions())return;let e=Math.min(Rn*2**this.reconnectAttempt,_n),t=Math.round(e*(1-Ae)+Math.random()*e*Ae);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.reconnectSubscribedTransport()},t)}async reconnectSubscribedTransport(){if(this.closedByClient||!this.hasActiveSubscriptions())return;try{await this.connect(),this.reconnectAttempt=0}catch{if(!Le(this.currentUrl)){this.reconnectAttempt+=1,this.scheduleReconnect();return}try{let e=await Oe({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd});if(e){this.currentUrl=e,await this.connect(),this.reconnectAttempt=0;return}}catch{}this.reconnectAttempt+=1,this.scheduleReconnect()}}close(){let e=this.socket;if(this.closedByClient=!0,this.connectGeneration+=1,this.clearReconnectTimer(),this.registered=!1,e)this.lastCloseError=new f("hub_connection_closed",Z);for(let t of this.pendingReplies.values())t.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,!e)return;this.sawSocketClose=!1,this.socket=void 0;try{e.close()}catch{}}async dispose(){if(this.socket?.readyState===1&&this.registered)try{await this.command("client.unregister",void 0,void 0,{timeoutMs:2000})}catch{}this.close()}sendFrame(e){if(!this.socket||this.socket.readyState!==1){if(this.lastCloseError.code==="hub_connection_closed"&&!this.sawSocketClose)throw new f("hub_connection_not_open","Hub connection is not open.");throw this.lastCloseError}this.socket.send(JSON.stringify(e))}sendSubscriptionFrame(e,t){let n=e==="stream.subscribe"?this.lastEventSequenceByKey.get(this.subscriptionKeyForSessionId(t)):void 0;this.sendFrame({kind:e,clientId:this.clientId,...t?{sessionId:t}:{},...n!==void 0?{sinceSequence:n}:{}})}adjustSubscriptionCount(e,t){let n=this.subscriptionKeyForSessionId(e),o=(this.subscriptionCounts.get(n)??0)+t;if(o<=0){if(this.subscriptionCounts.delete(n),!this.hasActiveSubscriptions())this.clearReconnectTimer();if(t<0&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.unsubscribe",e);return}if(this.subscriptionCounts.set(n,o),t>0&&o===1&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.subscribe",e)}subscriptionKeyForSessionId(e){return e??X}subscriptionSessionIdFromKey(e){return e===X?void 0:e}handleFrame(e){switch(e.kind){case"reply":{let t=e.envelope.requestId;if(!t)return;let n=this.pendingReplies.get(t);if(!n)return;this.pendingReplies.delete(t),n.resolve(e.envelope);return}case"event":{let t=e.envelope.sequence;if(typeof t==="number"){let n=e.envelope.sessionId?.trim();for(let o of[X,n]){if(!o||!this.subscriptionCounts.has(o))continue;let r=this.lastEventSequenceByKey.get(o)??0;if(t>r)this.lastEventSequenceByKey.set(o,t)}}for(let n of this.listeners){if(n.sessionId&&n.sessionId!==e.envelope.sessionId?.trim())continue;n.listener(e.envelope)}return}case"command":case"stream.subscribe":case"stream.unsubscribe":return}}}function Ne(e){let t=new URL(e);if(t.protocol==="http:")t.protocol="ws:";else if(t.protocol==="https:")t.protocol="wss:";return t.toString()}async function y(e,t){let n=new oe({url:e,authToken:t?.authToken,clientType:"hub-healthcheck",displayName:"hub healthcheck",workspaceRoot:t?.workspaceRoot,cwd:t?.cwd});try{return await n.connect(),!0}catch{return!1}finally{n.close()}}async function ee(e,t){let n=Ne(e),o=await A(n,{authToken:t?.authToken});if(!o)return{status:"unreachable",url:n};if(t?.requireCurrentBuild){let r=k(),i=x(o,r);if(!i.compatible&&!D(o))return{status:i.reason==="unsupported_protocol"?"protocol_mismatch":"build_mismatch",url:n}}else if(!bn(o).compatible)return{status:"protocol_mismatch",url:n};if(t?.verifyConnection===!0&&!await y(n,{workspaceRoot:t.workspaceRoot,cwd:t.cwd,authToken:t.authToken}))return{status:"unreachable",url:n};return{status:"compatible",url:n}}function In(e){let t=e&&typeof e==="object"&&Array.isArray(e.sessions)?e.sessions:[],n=0,o=new Set;for(let r of t){if(!r||typeof r!=="object")continue;let i=r.participants;if(!Array.isArray(i)||i.length===0)continue;n+=1;for(let s of i){let u=s&&typeof s==="object"?s.clientId:void 0;if(typeof u==="string"&&u.trim())o.add(u)}}return{activeSessionCount:n,participantClientCount:o.size}}async function Y(e,t,n){let o=new oe({url:e,authToken:t,clientType:"hub-recovery-check",displayName:"hub recovery check",workspaceRoot:n?.workspaceRoot,cwd:n?.cwd});try{let r=await o.command("session.list",{limit:500},void 0,{timeoutMs:Hn});return In(r.payload)}finally{await o.dispose().catch(()=>{return})}}async function xn(e,t,n){try{return(await Y(e,t,n)).activeSessionCount===0}catch{return!1}}async function Dn(e,t){let n=`${e.discoveryPath}.superseded`,o=await b(n);if(!o?.url||!o.authToken)return;let r=await ee(o.url,{authToken:o.authToken});if(r.status!=="compatible")return;if(await xn(r.url,o.authToken,t))return;return U(r.url,o.authToken)}async function An(e={}){if(e.endpoint?.trim()){let r=await ee(e.endpoint);return r.status==="compatible"?r.url:void 0}let t=Sn(),n=await b(t.discoveryPath);if(!n?.url)return await Dn(t,e);let o=await ee(n.url,{authToken:n.authToken,requireCurrentBuild:!0});if(o.status==="compatible")return U(o.url,n.authToken);if(o.status==="protocol_mismatch")await C(t.discoveryPath).catch(()=>{return});return}async function Oe(e={}){let t=await An(e);if(t&&await y(t,{workspaceRoot:e.workspaceRoot,cwd:e.cwd}))return t;if(e.endpoint?.trim())return;try{return(await O(e.workspaceRoot??process.cwd())).url}catch(n){e.onStartupError?.(n);return}}async function E(e,t,n,o){Ue();let r=new URL(e),i=t?.trim()||ne(r);if(r.protocol==="ws:")r.protocol="http:";else if(r.protocol==="wss:")r.protocol="https:";if(r.pathname="/drain",r.hash="",n)r.searchParams.set("reason",n);if(o?.off)r.searchParams.set("off","1");return(await fetch(r,{method:"POST",headers:i?{authorization:`Bearer ${i}`}:void 0})).ok}async function M(e,t){Ue();let n=new URL(e),o=t?.trim()||ne(n);if(n.protocol==="ws:")n.protocol="http:";else if(n.protocol==="wss:")n.protocol="https:";return n.pathname="/shutdown",n.hash="",(await fetch(n,{method:"POST",headers:o?{authorization:`Bearer ${o}`}:void 0})).ok}import{spawn as Ln}from"node:child_process";import{userInfo as On}from"node:os";import{basename as Un,delimiter as V}from"node:path";var re="__CLINE_SIDECAR_PATH_START__",Fe="__CLINE_SIDECAR_PATH_END__",We=5000,Mn=`/bin/sh -c 'printf "%s%s%s" "${re}" "$PATH" "${Fe}"'`,Ve="CLINE_SIDECAR_SKIP_SHELL_PATH";function $e(e){return e==="darwin"?"/bin/zsh":"/bin/bash"}function Bn(e,t){try{let n=On().shell?.trim();if(n)return n}catch{}return t.SHELL?.trim()||$e(e)}function Nn(e,t){let n=Un(e);if(n==="csh"||n==="tcsh")return{args:["-c",t],argv0:`-${n}`};return{args:["-i","-l","-c",t]}}function Vn(e){let t=e.indexOf(re);if(t===-1)return;let n=e.indexOf(Fe,t);if(n===-1)return;let o=e.slice(t+re.length,n).trim();return o.length>0?o:void 0}function Fn(e,t){let n=[...e.split(V),...t.split(V)].map((o)=>o.trim()).filter((o)=>o.length>0);return Array.from(new Set(n)).join(V)}function Wn(e,t=We){return new Promise((n)=>{let o=Nn(e,Mn),r=Ln(e,o.args,{argv0:o.argv0,stdio:["ignore","pipe","ignore"],detached:!0}),i="",s=0,u=()=>{try{if(r.pid)process.kill(-r.pid,"SIGKILL")}catch{r.kill("SIGKILL")}},c=!1,d=(m)=>{if(c)return;c=!0,clearTimeout(a),r.stdout?.destroy(),u(),n(m)},a=setTimeout(()=>{try{if(r.pid)process.kill(-r.pid,"SIGKILL")}catch{r.kill("SIGKILL")}d(void 0)},t);r.stdout?.on("data",(m)=>{if(c)return;if(s+=m.length,s>65536){d(void 0);return}i+=m.toString("utf8")}),r.on("error",()=>d(void 0)),r.on("close",()=>d(Vn(i)))})}async function je(e){let t=e?.platform??process.platform,n=e?.env??process.env;if(t==="win32")return{status:"skipped",reason:"windows"};if(n[Ve]?.trim())return{status:"skipped",reason:Ve};let o=e?.userShell??Bn(t,n),r=e?.fallbackShell??$e(t),i=e?.timeoutMs??We,s=o===r?[[o,i]]:[[o,i],[r,i/2]];for(let[u,c]of s){let d=await Wn(u,c);if(!d)continue;let a=Fn(d,n.PATH??"");return n.PATH=a,{status:"applied",pathEntries:a.split(V).length,shell:u}}return{status:"failed",shell:o}}var Ge={readHubDiscovery:b,clearHubDiscoveryIfOwned:be,probeProcess:(e)=>{process.kill(e,0)},requestHubShutdown:M,ensureDetachedHubServer:O,claimHubDaemonProcess:jn,loadHubDaemon:()=>import("@cerebriline/core/hub/daemon-entry"),ensureLoginShellPath:je,setHomeDirIfUnset:Gn,homeDir:$n,cwd:()=>process.cwd(),env:process.env,writeOutput:(e)=>process.stdout.write(e)};function qe(e,t){let n=e.indexOf(t);return(n>=0?e[n+1]:void 0)?.trim()||void 0}function Ke(e,t){let n=qe(e,"--discovery-path");if(!n)throw Error("--discovery-path is required for remote Hub management");return t.env.CLINE_HUB_DISCOVERY_PATH=n,n}async function qn(e=process.argv,t=Ge){t.setHomeDirIfUnset(t.homeDir()),await t.ensureLoginShellPath();let n=qe(e,"--cwd")??t.cwd();Ke(e,t);let o=await t.ensureDetachedHubServer(n,{host:"127.0.0.1",port:0,pathname:"/hub",allowPortFallback:!0,manageConnectors:!1});t.writeOutput(`${JSON.stringify({...o,cwd:n,platform:process.platform,arch:process.arch})}
|
|
4
4
|
`)}async function Je(e=process.argv,t=Ge){if(e.includes("--remote-hub-stop")){let n=Ke(e,t),o=await t.readHubDiscovery(n);if(o&&typeof o.pid==="number"&&Number.isInteger(o.pid)&&o.pid>0)try{t.probeProcess(o.pid)}catch(r){if(r?.code==="ESRCH")return await t.clearHubDiscoveryIfOwned(n,o.hubId),!0}if(o&&!await t.requestHubShutdown(o.url,o.authToken))throw Error("Remote Hub shutdown failed");return!0}if(e.includes("--remote-hub-ensure"))return await qn(e,t),!0;if(t.claimHubDaemonProcess())return await t.loadHubDaemon(),!0;return!1}(async()=>{if(!await Je())throw Error("A remote helper command is required")})().catch((e)=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{homedir as Wn}from"node:os";import{claimHubDaemonProcess as $n}from"@cerebriline/shared";import{setHomeDirIfUnset as jn}from"@cerebriline/shared/storage";import{createSessionId as hn,ensureLoopbackProxyBypass as Ue,isHubProtocolCompatible as gn,resolveClineBuildEnv as bn,resolveHubCommandTimeoutMs as yn}from"@cerebriline/shared";import wn from"ws";var P={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var ie="session_not_found";class F extends Error{sessionId;code="session_not_found";constructor(e,t){super(t??(e?`session not found: ${e}`:"session not found"));this.sessionId=e;this.name="SessionNotFoundError"}}import{spawn as At}from"node:child_process";import{closeSync as Lt,mkdirSync as Ot,openSync as Ut,readFileSync as Mt,unlinkSync as Bt}from"node:fs";import{basename as Nt,dirname as Vt,join as Ft}from"node:path";import{fileURLToPath as Wt}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as $t,isBunEmbeddedModulePath as jt,isHubDaemonProcess as Gt,resolveClineBuildEnv as Ee,withResolvedClineBuildEnv as qt}from"@cerebriline/shared";import{createHash as Ye,randomBytes as Xe}from"node:crypto";import{mkdir as j,open as se,readFile as le,rename as Ze,rm as I,writeFile as Qe}from"node:fs/promises";import{dirname as pe,join as G}from"node:path";import{ensureLoopbackProxyBypass as et,isHubProtocolCompatible as tt}from"@cerebriline/shared";import{resolveClineDataDir as H,resolveClineDir as Qn}from"@cerebriline/shared/storage";var nt="CLINE_HUB_DISCOVERY_PATH",ot="CLINE_HUB_BUILD_ID",rt="CLINE_HUB_BUILD_EPOCH_MS",it=30000,st=15000,ae=100;function at(e){return e.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function ct(e){return Ye("sha256").update(e).digest("hex").slice(0,12)}function ut(e){if(!Number.isInteger(e)||!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t instanceof Error&&"code"in t?String(t.code)==="EPERM":!1}}function ce(e){return new Promise((t)=>setTimeout(t,e))}function dt(e){return`${e}.lock`}async function lt(e){try{let t=JSON.parse(await le(G(e,"owner.json"),"utf8"));if(typeof t.pid!=="number"||typeof t.acquiredAt!=="string")return;return{pid:t.pid,acquiredAt:t.acquiredAt}}catch{return}}async function W(e){await I(e,{recursive:!0,force:!0}).catch(()=>{return})}function k(){let e=process.env[ot]?.trim();if(e)return e;return"sdk-v1-
|
|
1
|
+
import{homedir as Wn}from"node:os";import{claimHubDaemonProcess as $n}from"@cerebriline/shared";import{setHomeDirIfUnset as jn}from"@cerebriline/shared/storage";import{createSessionId as hn,ensureLoopbackProxyBypass as Ue,isHubProtocolCompatible as gn,resolveClineBuildEnv as bn,resolveHubCommandTimeoutMs as yn}from"@cerebriline/shared";import wn from"ws";var P={name:"@cerebriline/core",description:"Cline Core SDK for Node Runtime",version:"0.0.92",repository:{type:"git",url:"https://github.com/cline/cline",directory:"sdk/packages/core"},type:"module",types:"./dist/index.d.ts",main:"./dist/index.js",private:!1,publishConfig:{access:"public"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./hub":{types:"./dist/hub/index.d.ts",import:"./dist/hub/index.js"},"./hub/daemon-entry":{types:"./dist/hub/daemon/entry.d.ts",import:"./dist/hub/daemon/entry.js"},"./telemetry":{types:"./dist/services/telemetry/index.d.ts",import:"./dist/services/telemetry/index.js"},"./services/feature-flags/posthog":{types:"./dist/services/feature-flags/posthog.d.ts",import:"./dist/services/feature-flags/posthog.js"},"./remote/helper-entry":{types:"./dist/remote/remote-helper-entry.d.ts",import:"./dist/remote/remote-helper-entry.js"},"./cloud":{types:"./dist/cloud/index.d.ts",import:"./dist/cloud/index.js"},"./remote/helper":{types:"./dist/remote/remote-helper.d.ts",import:"./dist/remote/remote-helper.js"}},scripts:{build:"bun run ./bun.mts && bun tsc -p tsconfig.build.json && bun run ./scripts/verify-runtime-build-id.ts",typecheck:"bun tsc -p tsconfig.dev.json --noEmit && bun run typecheck:smoke","typecheck:smoke":"bun tsc -p tsconfig.smoke.json --noEmit",test:"bun run test:unit && bun run test:e2e","test:live":"vitest run --config vitest.config.ts src/extensions/context/compaction.live.test.ts","test:compaction":"bun --conditions=development run scripts/compact-session.ts","test:unit":"vitest run --config vitest.config.ts","test:e2e":"vitest run --config vitest.e2e.config.ts","verify:routines":"zsh -lc 'bunx vitest run src/cron/schedule-service.test.ts --config vitest.config.ts'","test:watch":"vitest --config vitest.config.ts"},dependencies:{"@cerebriline/agents":"workspace:*","@cerebriline/llms":"workspace:*","@cerebriline/shared":"workspace:*","@joplin/turndown-plugin-gfm":"1.0.68","@lingo-reader/epub-parser":"0.4.6","@lingo-reader/fb2-parser":"0.4.6","@lingo-reader/mobi-parser":"0.4.6","@modelcontextprotocol/sdk":"^1.29.0","@opentelemetry/api":"^1.9.0","@opentelemetry/api-logs":"^0.214.0","@opentelemetry/exporter-logs-otlp-http":"^0.214.0","@opentelemetry/exporter-metrics-otlp-http":"^0.214.0","@opentelemetry/exporter-trace-otlp-http":"^0.214.0","@opentelemetry/resources":"^2.6.1","@opentelemetry/sdk-logs":"^0.214.0","@opentelemetry/sdk-metrics":"^2.6.1","@opentelemetry/sdk-trace-base":"^2.6.1","@opentelemetry/sdk-trace-node":"^2.6.1","@opentelemetry/semantic-conventions":"^1.40.0","@tesseract.js-data/eng":"1.0.0",cfb:"1.2.2","fast-png":"8.0.0",jiti:"^2.7.0",nanoid:"^5.1.7","node-machine-id":"^1.1.12",officeparser:"8.0.0","pdfjs-dist":"6.2.108","simple-git":"3.36.0","tesseract.js":"7.0.0","tree-sitter-wasms":"^0.1.12",turndown:"7.2.0","web-tree-sitter":"^0.25.0",ws:"^8.20.0",yaml:"^2.8.2",zod:"^4.3.6"},peerDependencies:{"posthog-node":"^5.8.0"},peerDependenciesMeta:{"posthog-node":{optional:!0}},devDependencies:{"@types/turndown":"^5.0.6","@types/ws":"^8.18.1","posthog-node":"^5.8.0"},engines:{node:">=22"},files:["assets","dist","scripts/document-reader-assets.mjs","!dist/**/*.d.ts.map"]};var ie="session_not_found";class F extends Error{sessionId;code="session_not_found";constructor(e,t){super(t??(e?`session not found: ${e}`:"session not found"));this.sessionId=e;this.name="SessionNotFoundError"}}import{spawn as At}from"node:child_process";import{closeSync as Lt,mkdirSync as Ot,openSync as Ut,readFileSync as Mt,unlinkSync as Bt}from"node:fs";import{basename as Nt,dirname as Vt,join as Ft}from"node:path";import{fileURLToPath as Wt}from"node:url";import{CLINE_RUN_AS_HUB_DAEMON_ENV as $t,isBunEmbeddedModulePath as jt,isHubDaemonProcess as Gt,resolveClineBuildEnv as Ee,withResolvedClineBuildEnv as qt}from"@cerebriline/shared";import{createHash as Ye,randomBytes as Xe}from"node:crypto";import{mkdir as j,open as se,readFile as le,rename as Ze,rm as I,writeFile as Qe}from"node:fs/promises";import{dirname as pe,join as G}from"node:path";import{ensureLoopbackProxyBypass as et,isHubProtocolCompatible as tt}from"@cerebriline/shared";import{resolveClineDataDir as H,resolveClineDir as Qn}from"@cerebriline/shared/storage";var nt="CLINE_HUB_DISCOVERY_PATH",ot="CLINE_HUB_BUILD_ID",rt="CLINE_HUB_BUILD_EPOCH_MS",it=30000,st=15000,ae=100;function at(e){return e.replace(/[^a-zA-Z0-9_.-]+/g,"_")}function ct(e){return Ye("sha256").update(e).digest("hex").slice(0,12)}function ut(e){if(!Number.isInteger(e)||!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t instanceof Error&&"code"in t?String(t.code)==="EPERM":!1}}function ce(e){return new Promise((t)=>setTimeout(t,e))}function dt(e){return`${e}.lock`}async function lt(e){try{let t=JSON.parse(await le(G(e,"owner.json"),"utf8"));if(typeof t.pid!=="number"||typeof t.acquiredAt!=="string")return;return{pid:t.pid,acquiredAt:t.acquiredAt}}catch{return}}async function W(e){await I(e,{recursive:!0,force:!0}).catch(()=>{return})}function k(){let e=process.env[ot]?.trim();if(e)return e;return"sdk-v1-d70a53e60a51848baa4d382e98c5b4d9802a03a57d2bbb1c948887ac3e4ee94b".trim()||`source-${String(P.version)}`}function pt(){let e=Number(process.env[rt]);if(Number.isFinite(e)&&e>0)return e;return Number.isFinite(1794145572502)?1794145572502:void 0}function x(e,t=k()){let n=tt(e);if(!n.compatible)return n;let o=e.buildId?.trim();if(!o)return{compatible:!1,reason:"missing_build"};if(o!==t)return{compatible:!1,reason:"build_mismatch"};return{compatible:!0}}function ue(e){return typeof e==="number"&&Number.isFinite(e)&&e>0?e:void 0}function de(e){let t=e?.trim().split(/[-+]/,1)[0];if(!t)return;let n=t.split(".").map((o)=>Number(o));if(n.length===0||n.some((o)=>!Number.isInteger(o)||o<0))return;return n}function ft(e,t){for(let n=0;n<Math.max(e.length,t.length);n++){let o=e[n]??0,r=t[n]??0;if(o!==r)return o<r?-1:1}return 0}function fe(e,t){let n=e.buildId?.trim(),o=t.buildId?.trim();if(n&&o&&n===o)return 0;let r=ue(e.buildEpochMs),i=ue(t.buildEpochMs);if(r!==void 0&&i!==void 0&&r!==i)return r<i?-1:1;let s=de(e.coreVersion),u=de(t.coreVersion);if(s&&u){let c=ft(s,u);if(c!==0)return c}if(n&&o&&n!==o)return n<o?-1:1;return 0}function me(){return{buildId:k(),buildEpochMs:pt(),coreVersion:String(P.version)}}function D(e,t){let n=t?.self??me(),o=x(e,n.buildId??"");if(o.compatible)return!0;if(o.reason!=="build_mismatch"&&o.reason!=="missing_build")return!1;return fe(n,e)<=0}function he(e=process.argv[1]?.trim()||process.cwd()){let t=`hub-${ct(e)}`,n=process.env[nt]?.trim()||G(H(),"locks","hub","owners",`${at(t)}.json`);return{ownerId:t,discoveryPath:n}}async function b(e){try{let t=JSON.parse(await le(e,"utf8"));if(typeof t.hubId!=="string"||typeof t.protocolVersion!=="string"||typeof t.authToken!=="string"||typeof t.host!=="string"||typeof t.port!=="number"||typeof t.url!=="string"||typeof t.startedAt!=="string"||typeof t.updatedAt!=="string")return;return{hubId:t.hubId,protocolVersion:t.protocolVersion,minClientProtocolVersion:typeof t.minClientProtocolVersion==="string"?t.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof t.maxClientProtocolVersion==="string"?t.maxClientProtocolVersion:void 0,capabilities:Array.isArray(t.capabilities)?t.capabilities.filter((n)=>typeof n==="string"):void 0,coreVersion:typeof t.coreVersion==="string"?t.coreVersion:void 0,buildId:typeof t.buildId==="string"?t.buildId:void 0,buildEpochMs:typeof t.buildEpochMs==="number"?t.buildEpochMs:void 0,authToken:t.authToken,host:t.host,port:t.port,url:t.url,pid:typeof t.pid==="number"?t.pid:void 0,startedAt:t.startedAt,updatedAt:t.updatedAt}}catch{return}}async function ge(e,t,n){await q(e,async()=>{let o=pe(e);await j(o,{recursive:!0});let r=`${e}.${process.pid}.${Xe(6).toString("hex")}.tmp`,i;try{i=await se(r,"wx",384),await i.writeFile(`${JSON.stringify(t,null,2)}
|
|
2
2
|
`,{encoding:"utf8"}),await i.sync(),await i.close(),i=void 0,n?.beforePublish?.(),await Ze(r,e);let s;try{s=await se(o,"r"),await s.sync()}catch{}finally{await s?.close().catch(()=>{return})}}catch(s){throw await i?.close().catch(()=>{return}),await I(r,{force:!0}).catch(()=>{return}),s}})}async function C(e){await q(e,async()=>{await I(e,{force:!0}).catch(()=>{return})})}async function be(e,t){return await q(e,async()=>{if((await b(e))?.hubId!==t)return!1;return await I(e,{force:!0}),!0})}async function ye(e,t,n){let o=dt(e);await j(pe(o),{recursive:!0});let r=Date.now()+st;while(!0){try{await j(o,{recursive:!1})}catch(i){if((i instanceof Error&&"code"in i?String(i.code):"")!=="EEXIST")throw i;let u=await lt(o);if(!u){if(Date.now()>=r){await W(o);continue}await ce(ae);continue}let c=Date.now()-Date.parse(u.acquiredAt);if(!ut(u.pid)||c>it){await W(o);continue}if(Date.now()>=r)throw Error(`Timed out waiting for hub ${t} lock ${o}`);await ce(ae);continue}try{return await Qe(G(o,"owner.json"),`${JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()},null,2)}
|
|
3
3
|
`,"utf8"),await n()}finally{await W(o)}}}function q(e,t){return ye(`${e}.mutation`,"discovery mutation",t)}function we(e,t){return ye(e,"startup",t)}async function A(e,t){et();try{let n=await fetch(t?.authToken?mt(e):Se(e),{headers:t?.authToken?{authorization:`Bearer ${t.authToken}`}:void 0,signal:t?.signal});if(!n.ok)return;let o=await n.json();if(typeof o.protocolVersion!=="string"||typeof o.host!=="string"||typeof o.port!=="number"||typeof o.url!=="string")return;return{protocolVersion:o.protocolVersion,minClientProtocolVersion:typeof o.minClientProtocolVersion==="string"?o.minClientProtocolVersion:void 0,maxClientProtocolVersion:typeof o.maxClientProtocolVersion==="string"?o.maxClientProtocolVersion:void 0,capabilities:Array.isArray(o.capabilities)?o.capabilities.filter((r)=>typeof r==="string"):void 0,coreVersion:typeof o.coreVersion==="string"?o.coreVersion:void 0,buildId:typeof o.buildId==="string"?o.buildId:void 0,buildEpochMs:typeof o.buildEpochMs==="number"?o.buildEpochMs:void 0,host:o.host,port:o.port,url:o.url,hubId:typeof o.hubId==="string"?o.hubId:void 0,authToken:typeof o.authToken==="string"?o.authToken:void 0,pid:typeof o.pid==="number"?o.pid:void 0,startedAt:typeof o.startedAt==="string"?o.startedAt:void 0,updatedAt:typeof o.updatedAt==="string"?o.updatedAt:void 0}}catch{return}}function ve(e,t,n="/hub"){return new URL(`ws://${e}:${t}${n}`).toString()}function Se(e){let t=new URL(e);return t.protocol=t.protocol==="wss:"?"https:":"http:",t.pathname="/health",t.search="",t.toString()}function mt(e){let t=new URL(Se(e));return t.pathname="/status",t.toString()}import{CLINE_HUB_DEV_PORT as ht,CLINE_HUB_PORT as gt,resolveClineBuildEnv as bt}from"@cerebriline/shared";var yt="CLINE_HUB_HOST",wt="CLINE_HUB_PORT",vt="CLINE_HUB_PATHNAME",St="127.0.0.1",kt=gt,Ct="/hub";function ke(e){return bt(e)==="development"?ht:kt}function Pt(e={}){return(e.env??process.env)[yt]?.trim()||St}function Ht(e={}){let n=(e.env??process.env)[wt]?.trim();if(!n)return ke(e);let o=Number.parseInt(n,10);if(!Number.isInteger(o)||o<1||o>65535)return ke(e);return o}function Rt(e={}){return(e.env??process.env)[vt]?.trim()||Ct}function Ce(e={},t={}){return{host:e.host??Pt(t),port:e.port??Ht(t),pathname:e.pathname??Rt(t)}}import{join as Et}from"node:path";import{execFile as _t}from"node:child_process";import{promisify as Tt}from"node:util";import{processWorkspaceInfo as ao}from"@cerebriline/shared";import uo from"simple-git";var lo=Tt(_t);var It="shared:cline",xt="CLINE_HUB_DISCOVERY_PATH",Dt="hub-production";function R(e=It){return he(`${e}@${k()}`)}function L(){return{ownerId:Dt,discoveryPath:process.env[xt]?.trim()||Et(H(),"locks","hub","production.json")}}var Pe=15000,Kt=200,He=3000,Jt=100,zt=[100,250,500,1000,2000],Yt="--cline-hub-daemon",Xt=3,Zt=60000,Re=new Map;function Qt(e,t=Date.now()){let n=Re.get(e);if(!n||t-n.windowStartedAt>Zt)return Re.set(e,{count:1,windowStartedAt:t}),!0;return n.count+=1,n.count<=Xt}function en(e){return[...e.host?["--host",e.host]:[],...typeof e.port==="number"?["--port",String(e.port)]:[],...e.pathname?["--pathname",e.pathname]:[]]}function tn(){try{let e=Ft(H(),"logs","hub-daemon.log");return Ot(Vt(e),{recursive:!0}),{fd:Ut(e,"a"),logPath:e}}catch{return}}function nn(){return Ee()==="production"?L():R()}function _(e){return D(e)}function on(e){try{let t=JSON.parse(Mt(`${e}.superseded`,"utf8"));return{url:typeof t.url==="string"?t.url:void 0,authToken:typeof t.authToken==="string"?t.authToken:void 0,pid:typeof t.pid==="number"?t.pid:void 0}}catch{return}}function K(e){try{Bt(`${e}.superseded`)}catch{}}function _e(e,t,n){if(!t||t.url!==n)return e;return{...e,authToken:e.authToken??t.authToken,pid:e.pid??t.pid}}async function T(e,t){try{return await A(e,{authToken:t})}catch{return}}async function Te(e,t){let n=Date.now()+t;while(Date.now()<n){if(!(await T(e))?.url)return!0;await new Promise((r)=>setTimeout(r,Jt))}return!1}async function z(e,t){if(!Qt(e.url))return!1;await E(e.url,e.authToken,"retired by newer install").catch(()=>!1),await M(e.url,e.authToken).catch(()=>!1);let n=await Te(e.url,He);if(!n&&e.pid&&rn(e.pid)){try{process.kill(e.pid,"SIGTERM")}catch{}n=await Te(e.url,He)}if(n)await C(t).catch(()=>{return});return n}function rn(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function sn(e){try{return(await Y(e.url,e.authToken)).activeSessionCount>0}catch{return!1}}async function J(e,t){if(_(e))return"reusable";let n=await E(e.url,e.authToken,"retired by newer install").catch(()=>!1);if(await sn(e)){if(n)await E(e.url,e.authToken,"hub retirement deferred",{off:!0}).catch(()=>!1);return"deferred_busy"}let o=await z(e,t);if(!o&&n)await E(e.url,e.authToken,"hub retirement failed",{off:!0}).catch(()=>!1);return o?"retired":"failed"}async function an(e){if(Ee()!=="production")return;let t=R();if(t.discoveryPath===e.discoveryPath)return;let n=await b(t.discoveryPath);if(n?.url)await z(n,t.discoveryPath);else await C(t.discoveryPath).catch(()=>{return})}function cn(){let e=import.meta.url.endsWith(".ts")?"ts":"js";return Wt(new URL(`./entry.${e}`,import.meta.url))}function un(e,t){if(jt(e))return[Yt];return[...t&&e.toLowerCase().endsWith(".ts")?["--conditions=development"]:[],e]}function dn(e,t){let n=cn(),o=process.execPath?.trim();if(!o)throw Error("unable to resolve runtime executable for hub daemon");let r=Nt(o).toLowerCase().includes("bun"),i=un(n,r);return{launcher:o,args:[...i,"--cwd",e,...en(t),...t.manageConnectors===!1?["--no-connectors"]:[]],cwd:e,env:{...qt(process.env),CLINE_NO_INTERACTIVE:"1",[$t]:"1"}}}function ln(e){if(!e||typeof e!=="object")return!1;if(("code"in e?e.code:void 0)==="ETXTBSY")return!0;let n="message"in e?e.message:void 0;return typeof n==="string"&&n.includes("ETXTBSY")}function pn(e,t={}){if(Gt())return;let n=dn(e,t),o=tn();try{At(n.launcher,n.args,{detached:!0,stdio:o?["ignore",o.fd,o.fd]:"ignore",env:n.env,cwd:n.cwd,windowsHide:!0}).unref()}finally{if(o)Lt(o.fd)}}async function fn(e,t={}){for(let n=0;;n++)try{pn(e,t);return}catch(o){let r=zt[n];if(!ln(o)||r===void 0)throw o;await new Promise((i)=>setTimeout(i,r))}}async function mn(e,t,n={}){let o=n.host!==void 0||n.port!==void 0||n.pathname!==void 0||!!process.env.CLINE_HUB_PORT?.trim(),r=Ce(n),i=ve(r.host,r.port,r.pathname),s=(l)=>{if(!o)U(l.url,l.authToken);else Ie(l.url,l.authToken);return l};await an(e).catch(()=>{return});let u=await b(e.discoveryPath),c=u?.url?void 0:on(e.discoveryPath),d=!1;if(u?.url){let l=u.authToken;if(!l)d=!0,await z(u,e.discoveryPath);else{let p=await T(u.url,l);if(p?.url&&_(p)&&await y(p.url,{authToken:l}))return K(e.discoveryPath),s({url:p.url,authToken:l});if(p?.url){if(await J({...p,authToken:l},e.discoveryPath)==="deferred_busy"&&await y(p.url,{authToken:l}))return s({url:p.url,authToken:l})}else await C(e.discoveryPath).catch(()=>{return})}}let a=await T(i);if(a?.url){let l=_e(a,u??c,i);if(_(a)){let h=[a.authToken,u?.authToken,c?.authToken].filter((S)=>typeof S==="string"&&S.trim().length>0);for(let S of h){if(!await y(a.url,{authToken:S}))continue;let Je={hubId:a.hubId??`repaired-${a.port}`,protocolVersion:a.protocolVersion,minClientProtocolVersion:a.minClientProtocolVersion,maxClientProtocolVersion:a.maxClientProtocolVersion,capabilities:a.capabilities,coreVersion:a.coreVersion,buildId:a.buildId,authToken:S,host:a.host,port:a.port,url:a.url,pid:a.pid??u?.pid??c?.pid,startedAt:a.startedAt??new Date().toISOString(),updatedAt:new Date().toISOString()};try{await ge(e.discoveryPath,Je)}catch{}return K(e.discoveryPath),s({url:a.url,authToken:S})}throw Error(`A compatible Cline Hub is already running at ${i}, but its discovery record is missing or unreadable and no usable auth token is available. Run 'cline doctor fix' to repair local hub discovery.${d?" This can happen immediately after upgrading from a build that wrote an empty hub auth token; run 'cline doctor fix' to stop the old daemon and repair local hub discovery.":""}`)}let p=await J(l,e.discoveryPath);if(p==="deferred_busy"){for(let h of[l.authToken,u?.authToken].filter((v)=>typeof v==="string"&&v.trim().length>0))if(await y(a.url,{authToken:h}))return s({url:a.url,authToken:h});if(n.allowPortFallback!==!0&&r.port!==0)throw Error(`An older Cline Hub is running at ${i} and is still serving active sessions, so it was not replaced, but no usable auth token is available to attach to it. Finish those sessions, or run 'cline doctor fix' to stop the hub.`)}if(p==="failed"&&n.allowPortFallback!==!0&&r.port!==0)throw Error(`An incompatible Cline Hub is already running at ${i} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}let g=n.allowPortFallback===!0&&r.port!==0?{...r,port:0}:r;await fn(t,{...g,manageConnectors:n.manageConnectors});let w=Date.now()+Pe;while(Date.now()<w){let l=await b(e.discoveryPath);if(l?.url&&l.authToken){let h=await T(l.url,l.authToken);if(h?.url&&_(h)&&await y(h.url,{authToken:l.authToken}))return K(e.discoveryPath),s({url:h.url,authToken:l.authToken})}let p=await T(i);if(p?.url&&!_(p)){let h=_e(p,l??c,i),v=await J(h,e.discoveryPath);if(v==="deferred_busy"&&l?.authToken&&await y(p.url,{authToken:l.authToken}))return s({url:p.url,authToken:l.authToken});if(v==="failed"&&n.allowPortFallback!==!0&&r.port!==0)throw Error(`An incompatible Cline Hub is still running at ${i} and could not be retired automatically. Run 'cline doctor fix' to stop stale hub daemons before starting a new hub.`)}await new Promise((h)=>setTimeout(h,Kt))}throw Error(`Timed out after ${Pe}ms waiting for detached hub startup.`)}async function O(e,t={}){let n=nn();return await we(n.discoveryPath,async()=>mn(n,e,t))}function vn(){return bn()==="production"?L():R()}function Sn(){let e=globalThis.WebSocket;if(!e)throw Error("Global WebSocket is not available in this runtime. Node 22+ is required for hub mode.");return e}function Me(e){if(typeof e==="string")return e;if(e instanceof Uint8Array)return Buffer.from(e).toString();if(e instanceof ArrayBuffer)return Buffer.from(e).toString();if(Array.isArray(e))return Buffer.concat(e.map((t)=>Buffer.from(t))).toString();if(e&&typeof e==="object"&&"data"in e&&typeof e.data<"u")return Me(e.data);return String(e)}function kn(e){if(typeof e==="string")return e;if(e instanceof Uint8Array)return Buffer.from(e).toString("utf8");if(e instanceof ArrayBuffer)return Buffer.from(e).toString("utf8");return""}function xe(e){let t=e,n=kn(t.reason);return new f("hub_connection_closed",t.code||n?`Hub connection closed (code=${t.code??0}${n?`, reason=${n}`:""})`:Z,{closeCode:t.code,closeReason:n||void 0})}function De(e,t){if(e instanceof f)return e;if(e instanceof Error)return new f("hub_connect_failed",e.message);if(e&&typeof e==="object"&&"error"in e&&e.error instanceof Error)return new f("hub_connect_failed",e.error.message);let n=e&&typeof e==="object"&&"message"in e&&typeof e.message==="string"?e.message.trim():"";if(n)return new f("hub_connect_failed",n);let o=e&&typeof e==="object"&&"type"in e&&typeof e.type==="string"?e.type.trim():"";return new f("hub_connect_failed",o?`Failed to connect to hub at ${t.toString()} (${o} event before socket open).`:`Failed to connect to hub at ${t.toString()}.`)}var X="*",B=8000,Cn="cline-hub-auth.",te=new Map,Be=new Set,Pn=3000;var Z="Hub connection closed",Hn=250,Rn=5000,Ae=0.5;class f extends Error{code;details;constructor(e,t,n){super(t);this.code=e;this.details=n;this.name="HubTransportError"}}function _n(e){return e instanceof f}class Q extends Error{command;code;constructor(e,t,n){super(n);this.command=e;this.code=t;this.name="HubCommandError"}}function ne(e,t={}){let n=e.searchParams.get("authToken")?.trim();if(e.searchParams.delete("authToken"),n)return n;if(t.skipRegistry)return;let o=N(e.toString());return o?te.get(o):void 0}function Tn(e){try{let n=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"");return n==="localhost"||n==="127.0.0.1"||n==="::1"}catch{return!1}}function N(e){if(!Tn(e))return;let t=new URL(Ne(e));return t.search="",t.hash="",t.toString()}function Le(e){let t=N(e);return!!t&&Be.has(t)}function U(e,t){let n=N(e);if(n){if(Be.add(n),t?.trim())te.set(n,t)}return e}function Ie(e,t){let n=N(e);if(n&&t?.trim())te.set(n,t)}class oe{options;socket;connectPromise;clientId;currentUrl;recoveryPromise;pendingReplies=new Map;listeners=new Set;subscriptionCounts=new Map;lastEventSequenceByKey=new Map;reconnectTimer;reconnectAttempt=0;closedByClient=!1;connectGeneration=0;lastCloseError=new f("hub_connection_closed",Z);sawSocketClose=!1;registered=!1;capabilities;constructor(e){this.options=e;if(e.authToken?.trim()&&e.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");this.clientId=e.clientId??`core-${Math.random().toString(36).slice(2,10)}-${Date.now().toString(36)}`,this.currentUrl=e.url,this.capabilities=[...e.capabilities??[]]}getClientId(){return this.clientId}getUrl(){return this.currentUrl}isConnected(){return this.socket?.readyState===1&&this.registered}getConnectionError(){return this.isConnected()?null:this.lastCloseError}async updateCapabilities(e){if(this.capabilities=e.map((t)=>({...t})),!this.registered)return;await this.command("client.update",{capabilities:this.capabilities})}async connect(){if(this.connectPromise)return this.connectPromise;if(this.socket&&(this.socket.readyState===1||this.socket.readyState===0))return this.connectPromise??Promise.resolve();this.closedByClient=!1,this.clearReconnectTimer();let e=new URL(this.currentUrl),t=this.options.authToken?.trim()||ne(e,{skipRegistry:Boolean(this.options.resolveConnectionHeaders)});if(e.hash="",t&&this.options.resolveConnectionHeaders)throw Error("Hub connection headers cannot be combined with authToken authentication.");let n=++this.connectGeneration,o=this.openSocket(e,t,n),r;this.connectPromise=o.then(async(s)=>{if(r=s,await this.commandOnce("client.register",{clientId:this.clientId,clientType:this.options.clientType??"core",displayName:this.options.displayName??"core",transport:"native",actorKind:"client",capabilities:this.capabilities,metadata:{...this.options.metadata,version:this.options.clientVersion??String(P.version),pid:process.pid},workspaceContext:{workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}},void 0,void 0,!1),n!==this.connectGeneration||this.closedByClient){try{s.close()}catch{}throw this.lastCloseError}this.registered=!0;for(let u of this.subscriptionCounts.keys())this.sendSubscriptionFrame("stream.subscribe",this.subscriptionSessionIdFromKey(u));this.reconnectAttempt=0});let i=this.connectPromise;try{await i}catch(s){if(this.connectPromise===i)this.connectPromise=void 0;if(r&&this.socket===r){this.lastCloseError=De(s,e),this.registered=!1,this.sawSocketClose=!1,this.socket=void 0;try{r.close()}catch{}}if(!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect();throw s}}async openSocket(e,t,n){let o=this.options.resolveConnectionHeaders,r;if(o){let c;try{r=await Promise.race([Promise.resolve().then(()=>o()),new Promise((d,a)=>{c=setTimeout(()=>{a(new f("hub_connect_timeout",`Timed out resolving hub connection headers after ${B}ms`))},B)})])}catch(d){let a=d instanceof f?d:new f("hub_connect_failed",d instanceof Error?d.message:String(d));if(n===this.connectGeneration)this.lastCloseError=a;throw a}finally{clearTimeout(c)}}if(n!==this.connectGeneration||this.closedByClient)throw this.lastCloseError;if(r&&Object.keys(r).some((c)=>c.toLowerCase()==="sec-websocket-protocol")){let c=new f("hub_connect_failed","Hub connection headers cannot set Sec-WebSocket-Protocol.");if(n===this.connectGeneration)this.lastCloseError=c;throw c}let i=r?new wn(e.toString(),{headers:{...r}}):new(Sn())(e.toString(),t?[`${Cn}${t}`]:void 0);this.socket=i;let s=!1,u=new Promise((c,d)=>{let a=!1,m=setTimeout(()=>{if(a)return;a=!0,s=!0;let g=new f("hub_connect_timeout",`Timed out connecting to hub after ${B}ms`);if(this.socket===i)this.lastCloseError=g,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;try{i.close()}catch{}d(g)},B);i.addEventListener("open",()=>{if(a)return;a=!0,clearTimeout(m),c()}),i.addEventListener("error",(g)=>{if(a)return;a=!0,clearTimeout(m);let w=De(g,e);if(this.socket===i)this.lastCloseError=w,this.sawSocketClose=!1,this.connectPromise=void 0,this.socket=void 0;d(w)}),i.addEventListener("close",(g)=>{if(a)return;a=!0,clearTimeout(m);let w=s?this.lastCloseError:xe(g);if(this.socket===i){if(!s)this.lastCloseError=w,this.sawSocketClose=!0;this.connectPromise=void 0,this.socket=void 0}d(w)})});return i.addEventListener("message",(c)=>{this.handleFrame(JSON.parse(Me(c)))}),i.addEventListener("close",(c)=>{if(this.socket!==i)return;if(!s)this.lastCloseError=xe(c),this.sawSocketClose=!0;this.registered=!1;for(let d of this.pendingReplies.values())d.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,this.socket=void 0,!this.closedByClient&&this.hasActiveSubscriptions())this.scheduleReconnect()}),await u,i}subscribe(e,t){let n=t?.sessionId?.trim()||void 0,o={listener:e,sessionId:n};return this.listeners.add(o),this.adjustSubscriptionCount(n,1),()=>{if(!this.listeners.delete(o))return;this.adjustSubscriptionCount(n,-1)}}async command(e,t,n,o){let r=0,i=e!=="client.register"&&e!=="client.unregister";while(!0)try{return await this.commandOnce(e,t,n,o)}catch(s){if(!i||r>=1||!await this.recoverLocalHubTransport(s))throw s;r+=1}}async commandOnce(e,t,n,o,r=!0){if(r)await this.connect();o?.beforeDispatch?.();let i=hn("hubreq_");o?.onDispatch?.(i);let s=yn(e,o?.timeoutMs),u=new Promise((d,a)=>{let m=s===null?void 0:setTimeout(()=>{if(!this.pendingReplies.delete(i))return;a(new Q(e,"hub_command_timeout",`Hub command ${e} timed out after ${s}ms (hub=${this.currentUrl}, requestId=${i}, clientId=${this.clientId}). Check hub-daemon.log for matching command.start/command.slow entries, or run 'cline doctor fix' to restart the hub.`))},s);this.pendingReplies.set(i,{resolve:(g)=>{if(m)clearTimeout(m);d(g)},reject:(g)=>{if(m)clearTimeout(m);a(g)}})});try{this.sendFrame({kind:"command",envelope:{version:"v1",command:e,requestId:i,clientId:this.clientId,sessionId:n,timeoutMs:s,payload:t}})}catch(d){throw this.pendingReplies.delete(i),d}let c=await u;if(!c.ok){if(c.error?.code===ie){let d=n??(typeof t?.sessionId==="string"?t.sessionId:void 0);throw new F(d,c.error.message)}throw new Q(e,c.error?.code,c.error?.message??`Hub command ${e} failed`)}return c}async recoverLocalHubTransport(e){if(!Le(this.currentUrl)||!_n(e))return!1;if(this.recoveryPromise)return await this.recoveryPromise;return this.recoveryPromise=(async()=>{let t=await Oe({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd}).catch(()=>{return});if(!t)return!1;return this.currentUrl=t,this.close(),!0})().finally(()=>{this.recoveryPromise=void 0}),await this.recoveryPromise}hasActiveSubscriptions(){return this.subscriptionCounts.size>0}clearReconnectTimer(){if(!this.reconnectTimer)return;clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0}scheduleReconnect(){if(this.reconnectTimer||this.closedByClient||!this.hasActiveSubscriptions())return;let e=Math.min(Hn*2**this.reconnectAttempt,Rn),t=Math.round(e*(1-Ae)+Math.random()*e*Ae);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.reconnectSubscribedTransport()},t)}async reconnectSubscribedTransport(){if(this.closedByClient||!this.hasActiveSubscriptions())return;try{await this.connect(),this.reconnectAttempt=0}catch{if(!Le(this.currentUrl)){this.reconnectAttempt+=1,this.scheduleReconnect();return}try{let e=await Oe({workspaceRoot:this.options.workspaceRoot,cwd:this.options.cwd});if(e){this.currentUrl=e,await this.connect(),this.reconnectAttempt=0;return}}catch{}this.reconnectAttempt+=1,this.scheduleReconnect()}}close(){let e=this.socket;if(this.closedByClient=!0,this.connectGeneration+=1,this.clearReconnectTimer(),this.registered=!1,e)this.lastCloseError=new f("hub_connection_closed",Z);for(let t of this.pendingReplies.values())t.reject(this.lastCloseError);if(this.pendingReplies.clear(),this.connectPromise=void 0,!e)return;this.sawSocketClose=!1,this.socket=void 0;try{e.close()}catch{}}async dispose(){if(this.socket?.readyState===1&&this.registered)try{await this.command("client.unregister",void 0,void 0,{timeoutMs:2000})}catch{}this.close()}sendFrame(e){if(!this.socket||this.socket.readyState!==1){if(this.lastCloseError.code==="hub_connection_closed"&&!this.sawSocketClose)throw new f("hub_connection_not_open","Hub connection is not open.");throw this.lastCloseError}this.socket.send(JSON.stringify(e))}sendSubscriptionFrame(e,t){let n=e==="stream.subscribe"?this.lastEventSequenceByKey.get(this.subscriptionKeyForSessionId(t)):void 0;this.sendFrame({kind:e,clientId:this.clientId,...t?{sessionId:t}:{},...n!==void 0?{sinceSequence:n}:{}})}adjustSubscriptionCount(e,t){let n=this.subscriptionKeyForSessionId(e),o=(this.subscriptionCounts.get(n)??0)+t;if(o<=0){if(this.subscriptionCounts.delete(n),!this.hasActiveSubscriptions())this.clearReconnectTimer();if(t<0&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.unsubscribe",e);return}if(this.subscriptionCounts.set(n,o),t>0&&o===1&&this.socket?.readyState===1)this.sendSubscriptionFrame("stream.subscribe",e)}subscriptionKeyForSessionId(e){return e??X}subscriptionSessionIdFromKey(e){return e===X?void 0:e}handleFrame(e){switch(e.kind){case"reply":{let t=e.envelope.requestId;if(!t)return;let n=this.pendingReplies.get(t);if(!n)return;this.pendingReplies.delete(t),n.resolve(e.envelope);return}case"event":{let t=e.envelope.sequence;if(typeof t==="number"){let n=e.envelope.sessionId?.trim();for(let o of[X,n]){if(!o||!this.subscriptionCounts.has(o))continue;let r=this.lastEventSequenceByKey.get(o)??0;if(t>r)this.lastEventSequenceByKey.set(o,t)}}for(let n of this.listeners){if(n.sessionId&&n.sessionId!==e.envelope.sessionId?.trim())continue;n.listener(e.envelope)}return}case"command":case"stream.subscribe":case"stream.unsubscribe":return}}}function Ne(e){let t=new URL(e);if(t.protocol==="http:")t.protocol="ws:";else if(t.protocol==="https:")t.protocol="wss:";return t.toString()}async function y(e,t){let n=new oe({url:e,authToken:t?.authToken,clientType:"hub-healthcheck",displayName:"hub healthcheck",workspaceRoot:t?.workspaceRoot,cwd:t?.cwd});try{return await n.connect(),!0}catch{return!1}finally{n.close()}}async function ee(e,t){let n=Ne(e),o=await A(n,{authToken:t?.authToken});if(!o)return{status:"unreachable",url:n};if(t?.requireCurrentBuild){let r=k(),i=x(o,r);if(!i.compatible&&!D(o))return{status:i.reason==="unsupported_protocol"?"protocol_mismatch":"build_mismatch",url:n}}else if(!gn(o).compatible)return{status:"protocol_mismatch",url:n};if(t?.verifyConnection===!0&&!await y(n,{workspaceRoot:t.workspaceRoot,cwd:t.cwd,authToken:t.authToken}))return{status:"unreachable",url:n};return{status:"compatible",url:n}}function En(e){let t=e&&typeof e==="object"&&Array.isArray(e.sessions)?e.sessions:[],n=0,o=new Set;for(let r of t){if(!r||typeof r!=="object")continue;let i=r.participants;if(!Array.isArray(i)||i.length===0)continue;n+=1;for(let s of i){let u=s&&typeof s==="object"?s.clientId:void 0;if(typeof u==="string"&&u.trim())o.add(u)}}return{activeSessionCount:n,participantClientCount:o.size}}async function Y(e,t,n){let o=new oe({url:e,authToken:t,clientType:"hub-recovery-check",displayName:"hub recovery check",workspaceRoot:n?.workspaceRoot,cwd:n?.cwd});try{let r=await o.command("session.list",{limit:500},void 0,{timeoutMs:Pn});return En(r.payload)}finally{await o.dispose().catch(()=>{return})}}async function In(e,t,n){try{return(await Y(e,t,n)).activeSessionCount===0}catch{return!1}}async function xn(e,t){let n=`${e.discoveryPath}.superseded`,o=await b(n);if(!o?.url||!o.authToken)return;let r=await ee(o.url,{authToken:o.authToken});if(r.status!=="compatible")return;if(await In(r.url,o.authToken,t))return;return U(r.url,o.authToken)}async function Dn(e={}){if(e.endpoint?.trim()){let r=await ee(e.endpoint);return r.status==="compatible"?r.url:void 0}let t=vn(),n=await b(t.discoveryPath);if(!n?.url)return await xn(t,e);let o=await ee(n.url,{authToken:n.authToken,requireCurrentBuild:!0});if(o.status==="compatible")return U(o.url,n.authToken);if(o.status==="protocol_mismatch")await C(t.discoveryPath).catch(()=>{return});return}async function Oe(e={}){let t=await Dn(e);if(t&&await y(t,{workspaceRoot:e.workspaceRoot,cwd:e.cwd}))return t;if(e.endpoint?.trim())return;try{return(await O(e.workspaceRoot??process.cwd())).url}catch(n){e.onStartupError?.(n);return}}async function E(e,t,n,o){Ue();let r=new URL(e),i=t?.trim()||ne(r);if(r.protocol==="ws:")r.protocol="http:";else if(r.protocol==="wss:")r.protocol="https:";if(r.pathname="/drain",r.hash="",n)r.searchParams.set("reason",n);if(o?.off)r.searchParams.set("off","1");return(await fetch(r,{method:"POST",headers:i?{authorization:`Bearer ${i}`}:void 0})).ok}async function M(e,t){Ue();let n=new URL(e),o=t?.trim()||ne(n);if(n.protocol==="ws:")n.protocol="http:";else if(n.protocol==="wss:")n.protocol="https:";return n.pathname="/shutdown",n.hash="",(await fetch(n,{method:"POST",headers:o?{authorization:`Bearer ${o}`}:void 0})).ok}import{spawn as An}from"node:child_process";import{userInfo as Ln}from"node:os";import{basename as On,delimiter as V}from"node:path";var re="__CLINE_SIDECAR_PATH_START__",Fe="__CLINE_SIDECAR_PATH_END__",We=5000,Un=`/bin/sh -c 'printf "%s%s%s" "${re}" "$PATH" "${Fe}"'`,Ve="CLINE_SIDECAR_SKIP_SHELL_PATH";function $e(e){return e==="darwin"?"/bin/zsh":"/bin/bash"}function Mn(e,t){try{let n=Ln().shell?.trim();if(n)return n}catch{}return t.SHELL?.trim()||$e(e)}function Bn(e,t){let n=On(e);if(n==="csh"||n==="tcsh")return{args:["-c",t],argv0:`-${n}`};return{args:["-i","-l","-c",t]}}function Nn(e){let t=e.indexOf(re);if(t===-1)return;let n=e.indexOf(Fe,t);if(n===-1)return;let o=e.slice(t+re.length,n).trim();return o.length>0?o:void 0}function Vn(e,t){let n=[...e.split(V),...t.split(V)].map((o)=>o.trim()).filter((o)=>o.length>0);return Array.from(new Set(n)).join(V)}function Fn(e,t=We){return new Promise((n)=>{let o=Bn(e,Un),r=An(e,o.args,{argv0:o.argv0,stdio:["ignore","pipe","ignore"],detached:!0}),i="",s=0,u=()=>{try{if(r.pid)process.kill(-r.pid,"SIGKILL")}catch{r.kill("SIGKILL")}},c=!1,d=(m)=>{if(c)return;c=!0,clearTimeout(a),r.stdout?.destroy(),u(),n(m)},a=setTimeout(()=>{try{if(r.pid)process.kill(-r.pid,"SIGKILL")}catch{r.kill("SIGKILL")}d(void 0)},t);r.stdout?.on("data",(m)=>{if(c)return;if(s+=m.length,s>65536){d(void 0);return}i+=m.toString("utf8")}),r.on("error",()=>d(void 0)),r.on("close",()=>d(Nn(i)))})}async function je(e){let t=e?.platform??process.platform,n=e?.env??process.env;if(t==="win32")return{status:"skipped",reason:"windows"};if(n[Ve]?.trim())return{status:"skipped",reason:Ve};let o=e?.userShell??Mn(t,n),r=e?.fallbackShell??$e(t),i=e?.timeoutMs??We,s=o===r?[[o,i]]:[[o,i],[r,i/2]];for(let[u,c]of s){let d=await Fn(u,c);if(!d)continue;let a=Vn(d,n.PATH??"");return n.PATH=a,{status:"applied",pathEntries:a.split(V).length,shell:u}}return{status:"failed",shell:o}}var Ge={readHubDiscovery:b,clearHubDiscoveryIfOwned:be,probeProcess:(e)=>{process.kill(e,0)},requestHubShutdown:M,ensureDetachedHubServer:O,claimHubDaemonProcess:$n,loadHubDaemon:()=>import("@cerebriline/core/hub/daemon-entry"),ensureLoginShellPath:je,setHomeDirIfUnset:jn,homeDir:Wn,cwd:()=>process.cwd(),env:process.env,writeOutput:(e)=>process.stdout.write(e)};function qe(e,t){let n=e.indexOf(t);return(n>=0?e[n+1]:void 0)?.trim()||void 0}function Ke(e,t){let n=qe(e,"--discovery-path");if(!n)throw Error("--discovery-path is required for remote Hub management");return t.env.CLINE_HUB_DISCOVERY_PATH=n,n}async function Gn(e=process.argv,t=Ge){t.setHomeDirIfUnset(t.homeDir()),await t.ensureLoginShellPath();let n=qe(e,"--cwd")??t.cwd();Ke(e,t);let o=await t.ensureDetachedHubServer(n,{host:"127.0.0.1",port:0,pathname:"/hub",allowPortFallback:!0,manageConnectors:!1});t.writeOutput(`${JSON.stringify({...o,cwd:n,platform:process.platform,arch:process.arch})}
|
|
4
4
|
`)}async function Ko(e=process.argv,t=Ge){if(e.includes("--remote-hub-stop")){let n=Ke(e,t),o=await t.readHubDiscovery(n);if(o&&typeof o.pid==="number"&&Number.isInteger(o.pid)&&o.pid>0)try{t.probeProcess(o.pid)}catch(r){if(r?.code==="ESRCH")return await t.clearHubDiscoveryIfOwned(n,o.hubId),!0}if(o&&!await t.requestHubShutdown(o.url,o.authToken))throw Error("Remote Hub shutdown failed");return!0}if(e.includes("--remote-hub-ensure"))return await Gn(e,t),!0;if(t.claimHubDaemonProcess())return await t.loadHubDaemon(),!0;return!1}export{Ko as runRemoteHelperEntrypoint,Gn as runRemoteHubEnsure};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a check's new answer is further along than its last one.
|
|
3
|
+
*
|
|
4
|
+
* A carry keeps a failed transaction's files because the check said something
|
|
5
|
+
* new, on the reading that a moving answer is a fix in several parts landing.
|
|
6
|
+
* Any new text counted, so a change that broke something else -- a new error,
|
|
7
|
+
* earlier in the file -- was carried as progress (automaticum audit
|
|
8
|
+
* 2026-11-08, B22). This reads what can be compared between two outputs and
|
|
9
|
+
* says which way they moved; where nothing can be compared it says so, and
|
|
10
|
+
* the carry rule is left as it was.
|
|
11
|
+
*/
|
|
12
|
+
export type CheckProgress = "better" | "worse" | "unknown";
|
|
13
|
+
export declare function compareCheckProgress(before: string, after: string): CheckProgress;
|
|
@@ -70,6 +70,8 @@ export interface FileRevision {
|
|
|
70
70
|
* of what it has been doing.
|
|
71
71
|
*/
|
|
72
72
|
readonly sameAs?: number;
|
|
73
|
+
/** The revision this one put back, when a restore made it. */
|
|
74
|
+
readonly restores?: number;
|
|
73
75
|
}
|
|
74
76
|
export type RevisionLookup = {
|
|
75
77
|
kind: "found";
|
|
@@ -129,7 +131,11 @@ export interface RevisionNote {
|
|
|
129
131
|
readonly intent?: string;
|
|
130
132
|
/** What the writing tool reported doing, e.g. "Replaced line 90". */
|
|
131
133
|
readonly summary?: string;
|
|
132
|
-
/**
|
|
134
|
+
/**
|
|
135
|
+
* What the checker last said when this revision was made. It ran before
|
|
136
|
+
* the write, so it is labelled as such: shown bare, it read as the verdict
|
|
137
|
+
* on content it never saw (automaticum audit 2026-11-08).
|
|
138
|
+
*/
|
|
133
139
|
readonly check?: string;
|
|
134
140
|
/**
|
|
135
141
|
* The content was never written to this workspace: a delegated agent's
|
|
@@ -137,6 +143,12 @@ export interface RevisionNote {
|
|
|
137
143
|
* still the newest revision that is not held.
|
|
138
144
|
*/
|
|
139
145
|
readonly held?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* The revision a restore put back. `last` follows it: undoing a restore
|
|
148
|
+
* with `last` used to land on the state the restore had just discarded,
|
|
149
|
+
* so a second `last` undid the first (automaticum audit 2026-11-08, B24).
|
|
150
|
+
*/
|
|
151
|
+
readonly restores?: number;
|
|
140
152
|
}
|
|
141
153
|
/** How a revision's content is identified, for matching a file against it. */
|
|
142
154
|
export declare function hashOf(body: Buffer | undefined): string;
|
|
@@ -185,6 +197,8 @@ export interface RevisionLog {
|
|
|
185
197
|
heldBytes(absolutePath: string): number;
|
|
186
198
|
/** Forget everything. A discard puts the tree back, so the history goes too. */
|
|
187
199
|
reset(): void;
|
|
200
|
+
/** Whether a compaction released this file's whole history. */
|
|
201
|
+
released(absolutePath: string): boolean;
|
|
188
202
|
/**
|
|
189
203
|
* Close the current compaction span and release what the next one cannot use.
|
|
190
204
|
*
|
|
@@ -89,6 +89,8 @@ export interface OracleVerdict {
|
|
|
89
89
|
output: string;
|
|
90
90
|
/** Set when the oracle exceeded its budget: an unfinished run is not a pass. */
|
|
91
91
|
timedOut: boolean;
|
|
92
|
+
/** The signal that stopped it, when that was not the timeout. */
|
|
93
|
+
signal?: string;
|
|
92
94
|
/**
|
|
93
95
|
* Set when the command succeeded but its output did not say the change did.
|
|
94
96
|
* A different failure from a non-zero exit and reported as one, because "it
|
|
@@ -175,4 +177,16 @@ export declare function runOracle(oracle: Oracle, options?: {
|
|
|
175
177
|
*/
|
|
176
178
|
wrapSpawn?: OracleSpawnWrapper;
|
|
177
179
|
}): Promise<OracleVerdict>;
|
|
180
|
+
/**
|
|
181
|
+
* Why a check produced no verdict about the code, or nothing when it ran.
|
|
182
|
+
*
|
|
183
|
+
* A command that was not found (127) or could not be executed (126), one that
|
|
184
|
+
* never started, or one a signal stopped has said nothing about the change,
|
|
185
|
+
* and reporting it as "it FAILED, the defect is still there" sent the model
|
|
186
|
+
* after a defect the check never looked for (automaticum audit 2026-11-08,
|
|
187
|
+
* B20/B23).
|
|
188
|
+
*/
|
|
189
|
+
export declare function checkDidNotRun(verdict: OracleVerdict): string | undefined;
|
|
190
|
+
/** Why a check's pattern cannot be used, or nothing when it compiles. */
|
|
191
|
+
export declare function invalidExpectPattern(expect: string | undefined): string | undefined;
|
|
178
192
|
export {};
|
|
@@ -16,15 +16,25 @@
|
|
|
16
16
|
* Ported from the harness oracle the atomic campaign was measured with, where
|
|
17
17
|
* it decided every verdict across ~90 runs.
|
|
18
18
|
*/
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Frames pumped by default: ten seconds of a 60 fps loop.
|
|
21
|
+
*
|
|
22
|
+
* Thirty passed a game that threw on frame 31 (automaticum audit 2026-11-08,
|
|
23
|
+
* B8). No bound catches everything; this one costs milliseconds and reaches
|
|
24
|
+
* well past a game's first second.
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_PAGE_FRAMES = 600;
|
|
21
27
|
export interface PageCheckResult {
|
|
22
28
|
ok: boolean;
|
|
23
29
|
/** Why it failed, in the form the transaction's message quotes. */
|
|
24
30
|
error?: string;
|
|
25
31
|
framesRun: number;
|
|
32
|
+
/** Timeout callbacks run, which are not frames but can drive a loop. */
|
|
33
|
+
timeoutsRun?: number;
|
|
26
34
|
/** Whether the page had to be told to start rather than starting itself. */
|
|
27
35
|
started: boolean;
|
|
36
|
+
/** The page was not run at all, so `ok: false` judges nothing about it. */
|
|
37
|
+
unchecked?: boolean;
|
|
28
38
|
}
|
|
29
39
|
/**
|
|
30
40
|
* Load a page the way a browser would, and say whether it ran.
|
|
@@ -84,7 +84,7 @@ export interface PlanItem {
|
|
|
84
84
|
}
|
|
85
85
|
/** Declarations allowed per transaction, so re-planning is bounded. */
|
|
86
86
|
export declare const MAX_DECLARATIONS_PER_TRANSACTION = 3;
|
|
87
|
-
export declare const PLAN_TOOL_DESCRIPTION = "Keep the plan for this task: what you intend to change, and which of those changes have landed.\n\nCall it three ways.\n\nTo state the plan, send `changes`: a list, each entry naming WHERE (the function, or the exact text you will match on), WHAT (the single concrete edit) and WHY (the symptom it removes). Numbering is done for you \u2014 send the list, not a count.\n\nTo record that an item landed, send `done` with its number, and optionally `note`. Do this the moment the edit applies, not at the end. An item you do not mark is an item you will plan again.\n\nTo record that an item did not work, send `failed` with its number and a `note` saying what happened.\n\nEvery call returns the whole plan with its current state, so you never have to remember it or scroll back for it. Read what comes back before deciding what to do next.\n\nThe plan survives a discarded transaction. An item that landed and was then rolled back comes back as work still to do, but it is still on the record as something that once
|
|
87
|
+
export declare const PLAN_TOOL_DESCRIPTION = "Keep the plan for this task: what you intend to change, and which of those changes have landed.\n\nCall it three ways.\n\nTo state the plan, send `changes`: a list, each entry naming WHERE (the function, or the exact text you will match on), WHAT (the single concrete edit) and WHY (the symptom it removes). Numbering is done for you \u2014 send the list, not a count.\n\nTo record that an item landed, send `done` with its number, and optionally `note`. Do this the moment the edit applies, not at the end. An item you do not mark is an item you will plan again.\n\nTo record that an item did not work, send `failed` with its number and a `note` saying what happened.\n\nEvery call returns the whole plan with its current state, so you never have to remember it or scroll back for it. Read what comes back before deciding what to do next.\n\nThe plan survives a discarded transaction. An item that landed and was then rolled back comes back as work still to do, but it is still on the record as something that once applied \u2014 which is the fastest route back to a working file. When a transaction is carried instead, its files and its landed items stay as they are.";
|
|
88
88
|
export declare const PLAN_TOOL_INPUT_SCHEMA: {
|
|
89
89
|
readonly type: "object";
|
|
90
90
|
readonly properties: {
|
|
@@ -135,7 +135,19 @@ export declare const PLAN_TOOL_INPUT_SCHEMA: {
|
|
|
135
135
|
export interface PlanTransactionSource {
|
|
136
136
|
/** Which transaction is open. A change here means the last one closed. */
|
|
137
137
|
readonly transaction: number;
|
|
138
|
+
/**
|
|
139
|
+
* How each closed transaction ended, when the host can say. A kept or
|
|
140
|
+
* carried transaction's edits are still in the files, and its landed items
|
|
141
|
+
* stay landed.
|
|
142
|
+
*/
|
|
143
|
+
readonly outcomes?: readonly {
|
|
144
|
+
readonly transaction: number;
|
|
145
|
+
readonly kept: boolean;
|
|
146
|
+
readonly carried?: boolean;
|
|
147
|
+
}[];
|
|
138
148
|
}
|
|
149
|
+
/** How a closed transaction ended, for what is said about its edits. */
|
|
150
|
+
type ClosedAs = "discarded" | "carried" | "kept";
|
|
139
151
|
export interface PlanToolOptions {
|
|
140
152
|
controller: PlanTransactionSource;
|
|
141
153
|
/** The protocol's change budget, which bounds the list. */
|
|
@@ -152,7 +164,7 @@ export interface PlanToolOptions {
|
|
|
152
164
|
* the edits do not. DIFFERENT is left blank on purpose: it is the new plan, and
|
|
153
165
|
* asking for it is the point.
|
|
154
166
|
*/
|
|
155
|
-
export declare function renderRetrospective(items: readonly PlanItem[], closed: number): string;
|
|
167
|
+
export declare function renderRetrospective(items: readonly PlanItem[], closed: number, closedAs?: ClosedAs): string;
|
|
156
168
|
/** The whole plan as the model reads it back. */
|
|
157
169
|
export declare function renderPlan(items: readonly PlanItem[], transaction: number): string;
|
|
158
170
|
export declare function createPlanTool(options: PlanToolOptions): AgentTool;
|
|
@@ -128,6 +128,7 @@ export declare function buildEmptyAttemptPrompt(input: {
|
|
|
128
128
|
check?: {
|
|
129
129
|
label: string;
|
|
130
130
|
output?: string;
|
|
131
|
+
notRun?: string;
|
|
131
132
|
};
|
|
132
133
|
/**
|
|
133
134
|
* No tool was called in this transaction at all. Worth saying, because the
|
|
@@ -170,6 +171,7 @@ export declare function describeSilentTurn(input: {
|
|
|
170
171
|
check?: {
|
|
171
172
|
label: string;
|
|
172
173
|
output?: string;
|
|
174
|
+
notRun?: string;
|
|
173
175
|
};
|
|
174
176
|
}): string;
|
|
175
177
|
/**
|
|
@@ -92,7 +92,7 @@ export declare const MAX_RESTORES_PER_TRANSACTION = 27;
|
|
|
92
92
|
* without leaving the door open on a hundred.
|
|
93
93
|
*/
|
|
94
94
|
export declare const MAX_NOOP_RESTORES_PER_TRANSACTION = 3;
|
|
95
|
-
export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly as it was when this transaction opened, discarding every change you have made to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you have rewritten the same line four times and it is further from working than when you started. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nIt affects one file. Anything you changed in other files this transaction stays. If the file did not exist when the transaction opened, restoring it deletes it.\n\n**You do not have to go all the way back.** Every time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as this transaction opened, which is what you get if you say nothing.\n\nGoing back one step is not the same as starting again. If you have fixed three things and broken the fourth, `last` keeps the three.\n\nThis is not the end of the transaction and it does not spend one \u2014 you carry on, from the file as it was. Read the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"base\"` and it is shown to you with the file left alone.";
|
|
95
|
+
export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly as it was when this transaction opened, discarding every change you have made to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you have rewritten the same line four times and it is further from working than when you started. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nIt affects one file. Anything you changed in other files this transaction stays. If the file did not exist when the transaction opened, restoring it deletes it.\n\n**You do not have to go all the way back.** Every time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong. Asking for it again goes one more step back; it does not undo the restore you just made.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as this transaction opened, which is what you get if you say nothing.\n\nGoing back one step is not the same as starting again. If you have fixed three things and broken the fourth, `last` keeps the three.\n\nThis is not the end of the transaction and it does not spend one \u2014 you carry on, from the file as it was. Read the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"base\"` and it is shown to you with the file left alone.";
|
|
96
96
|
/**
|
|
97
97
|
* The same tool, described for a session that has no transactions.
|
|
98
98
|
*
|
|
@@ -103,7 +103,7 @@ export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly
|
|
|
103
103
|
* carries over unchanged is the part that matters — going back is exact and
|
|
104
104
|
* retyping from memory is not.
|
|
105
105
|
*/
|
|
106
|
-
export declare const RESTORE_FILE_TOOL_SESSION_DESCRIPTION = "Put one file back to a version of it you had earlier, discarding what you have written to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you replaced the file with something that was never meant to be its contents. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nEvery time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as it stood before this session first wrote to it, which is what you get if you say nothing.\n\nIt affects one file, and only files this session has written: a file nothing has touched has no earlier version held, and this will say so rather than guess.\n\nRead the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"original\"` (or a number) and it is shown to you with the file left alone.";
|
|
106
|
+
export declare const RESTORE_FILE_TOOL_SESSION_DESCRIPTION = "Put one file back to a version of it you had earlier, discarding what you have written to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you replaced the file with something that was never meant to be its contents. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nEvery time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong. Asking for it again goes one more step back; it does not undo the restore you just made.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as it stood before this session first wrote to it, which is what you get if you say nothing.\n\nIt affects one file, and only files this session has written: a file nothing has touched has no earlier version held, and this will say so rather than guess.\n\nRead the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"original\"` (or a number) and it is shown to you with the file left alone.";
|
|
107
107
|
export declare const RESTORE_FILE_TOOL_INPUT_SCHEMA: {
|
|
108
108
|
readonly type: "object";
|
|
109
109
|
readonly properties: {
|
|
@@ -113,7 +113,7 @@ export declare const RESTORE_FILE_TOOL_INPUT_SCHEMA: {
|
|
|
113
113
|
};
|
|
114
114
|
readonly revision: {
|
|
115
115
|
readonly type: "string";
|
|
116
|
-
readonly description: "Which version to return to: \"last\" to undo only your most recent change to this file, a number such as \"#3\" for that version, or \"original\" for the
|
|
116
|
+
readonly description: "Which version to return to: \"last\" to undo only your most recent change to this file (again, to go one more step back), a number such as \"#3\" for that version, or \"original\" for the earliest version held. Defaults to \"original\".";
|
|
117
117
|
};
|
|
118
118
|
readonly find: {
|
|
119
119
|
readonly type: "string";
|
|
@@ -23,6 +23,16 @@ export interface Snapshot {
|
|
|
23
23
|
readonly root: string;
|
|
24
24
|
/** Files that existed but were too large to hold; never rolled back. */
|
|
25
25
|
readonly skipped: readonly string[];
|
|
26
|
+
/**
|
|
27
|
+
* Size and modification time of each skipped file that could be statted,
|
|
28
|
+
* so a restore can say which of them the transaction changed.
|
|
29
|
+
*/
|
|
30
|
+
readonly skippedStats: ReadonlyMap<string, SkippedStamp>;
|
|
31
|
+
}
|
|
32
|
+
/** Enough of a file's stat to tell that it changed. */
|
|
33
|
+
export interface SkippedStamp {
|
|
34
|
+
readonly size: number;
|
|
35
|
+
readonly mtimeMs: number;
|
|
26
36
|
}
|
|
27
37
|
export interface SnapshotLimits {
|
|
28
38
|
/** Most files a snapshot will hold before it gives up on covering the tree. */
|
|
@@ -49,6 +59,11 @@ export interface RestoreReport {
|
|
|
49
59
|
recreated: string[];
|
|
50
60
|
/** Paths the snapshot never held, listed so nobody assumes they reverted. */
|
|
51
61
|
uncovered: string[];
|
|
62
|
+
/**
|
|
63
|
+
* Of `uncovered`, the files the transaction changed or deleted: left as the
|
|
64
|
+
* transaction left them, because there was nothing to put back.
|
|
65
|
+
*/
|
|
66
|
+
unrestored: string[];
|
|
52
67
|
}
|
|
53
68
|
/**
|
|
54
69
|
* Put the tree back exactly as the snapshot found it.
|
|
@@ -70,8 +70,16 @@ export interface StalledCheckSource {
|
|
|
70
70
|
*/
|
|
71
71
|
export type StalledCheckVerdict = "ok" | "nudge" | "settle";
|
|
72
72
|
export interface StalledChecks {
|
|
73
|
-
/**
|
|
74
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Record a check that has just run, and say what it has earned.
|
|
75
|
+
*
|
|
76
|
+
* `fingerprint` is what the files held when it ran, when the host can say.
|
|
77
|
+
* A fingerprint that moved since the last check is a change, whatever made
|
|
78
|
+
* it: counting only the editing tools let a file rewritten by a shell
|
|
79
|
+
* command run up the count, and the guard rolled back work that was moving
|
|
80
|
+
* (automaticum audit 2026-11-08, B10).
|
|
81
|
+
*/
|
|
82
|
+
checked(passed: boolean, fingerprint?: string): StalledCheckVerdict;
|
|
75
83
|
/** Record a change: whatever the next check says, it is judging new bytes. */
|
|
76
84
|
changed(): void;
|
|
77
85
|
/** The current run of checks over untouched files. */
|
|
@@ -98,8 +106,8 @@ export declare function withChangeSignal<T extends AgentToolDefinition>(tools: r
|
|
|
98
106
|
*
|
|
99
107
|
* It judges nothing and puts nothing back -- saying otherwise would have the
|
|
100
108
|
* model report a transaction that is still open. What it adds is the thing the
|
|
101
|
-
* re-run cannot give it:
|
|
102
|
-
*
|
|
109
|
+
* re-run cannot give it: a reading of the whole file rather than the check's
|
|
110
|
+
* first complaint.
|
|
103
111
|
*/
|
|
104
112
|
export declare function describeStalledCheckNudge(runs: number, label: string): string;
|
|
105
113
|
/** What the model is told when the check is closed out from under it. */
|
|
@@ -236,6 +236,9 @@ export declare class TransactionController {
|
|
|
236
236
|
* files rather than about the clock.
|
|
237
237
|
*/
|
|
238
238
|
private readonly checkOutputs;
|
|
239
|
+
/** The check's most recent output, and the one before it. */
|
|
240
|
+
private lastCheckOutput?;
|
|
241
|
+
private previousCheckOutput?;
|
|
239
242
|
private checkHasRepeated;
|
|
240
243
|
/** Set by a carried settlement, so the next `open` keeps the older base. */
|
|
241
244
|
private carrying;
|
|
@@ -331,6 +334,13 @@ export declare class TransactionController {
|
|
|
331
334
|
get pending(): Snapshot | undefined;
|
|
332
335
|
/** The open transaction's per-file history. Empty before the first write. */
|
|
333
336
|
get revisions(): RevisionLog;
|
|
337
|
+
/**
|
|
338
|
+
* What the files under the open transaction's root hold right now, as one
|
|
339
|
+
* string, or nothing when no transaction is open. Two equal fingerprints
|
|
340
|
+
* mean nothing changed in between, by whatever means -- an edit, a shell
|
|
341
|
+
* command, another agent.
|
|
342
|
+
*/
|
|
343
|
+
fingerprint(): Promise<string | undefined>;
|
|
334
344
|
/** Whether the open transaction has changed anything on disk. */
|
|
335
345
|
isUntouched(): Promise<boolean>;
|
|
336
346
|
/**
|
|
@@ -32,4 +32,6 @@ export interface ChangedFile {
|
|
|
32
32
|
* reasons far more often than for a bracket, and a verdict that guessed would
|
|
33
33
|
* be worse than one that stayed quiet.
|
|
34
34
|
*/
|
|
35
|
-
export declare function describeUnparseableChange(changed: readonly ChangedFile[], root: string
|
|
35
|
+
export declare function describeUnparseableChange(changed: readonly ChangedFile[], root: string,
|
|
36
|
+
/** The work is carried into the next transaction rather than put back. */
|
|
37
|
+
carried?: boolean): string | null;
|
|
@@ -180,7 +180,21 @@ export interface LoopDetectionCall {
|
|
|
180
180
|
export declare class LoopDetectionTracker {
|
|
181
181
|
private readonly config;
|
|
182
182
|
private readonly state;
|
|
183
|
-
|
|
183
|
+
/** Where relative paths in a call resolve, to see whether they changed. */
|
|
184
|
+
private readonly root;
|
|
185
|
+
/**
|
|
186
|
+
* The files a failed or no-op call named, as they were when it was judged.
|
|
187
|
+
* The verdicts said "nothing has changed, so neither will the result"; a
|
|
188
|
+
* write the tracker never sees -- a shell `sed -i`, a rollback, the user --
|
|
189
|
+
* made that false, and the call that would now work was stopped.
|
|
190
|
+
*/
|
|
191
|
+
private readonly stamps;
|
|
192
|
+
private pendingSpelled;
|
|
193
|
+
constructor(config?: Partial<LoopDetectionConfig>, options?: {
|
|
194
|
+
root?: string;
|
|
195
|
+
});
|
|
196
|
+
/** Drop what was concluded about one call, so it is judged afresh. */
|
|
197
|
+
private forgetVerdicts;
|
|
184
198
|
inspect(call: LoopDetectionCall): LoopDetectionVerdict;
|
|
185
199
|
/**
|
|
186
200
|
* Attribute an outcome to the call `inspect()` last saw.
|
|
@@ -47,6 +47,15 @@ export type RememberOutcome =
|
|
|
47
47
|
export declare const NEAR_DUPLICATE_SIMILARITY = 0.85;
|
|
48
48
|
/** How alike two notes read, 0 to 1: the share of letter pairs they have in common. */
|
|
49
49
|
export declare function noteSimilarity(a: string, b: string): number;
|
|
50
|
+
/**
|
|
51
|
+
* Whether one note negates what the other says: their negations differ.
|
|
52
|
+
*
|
|
53
|
+
* {@link noteSimilarity} counts letter pairs, so "the cache is enabled" and
|
|
54
|
+
* "the cache is not enabled" score far above the duplicate bar, and the
|
|
55
|
+
* correction was refused as saying "nearly the same" (automaticum audit
|
|
56
|
+
* 2026-11-08, rest N6). A pair that differs here is never a duplicate.
|
|
57
|
+
*/
|
|
58
|
+
export declare function negationDiffers(a: string, b: string): boolean;
|
|
50
59
|
export interface RecalledMemory extends MemoryItem {
|
|
51
60
|
/** The reranker's score, 0 to 1, when there was one. */
|
|
52
61
|
relevance?: number;
|