@cerebriline/core 4.100.245 → 4.100.247
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 +2 -0
- package/assets/prompt-templates/deepseek.md +1 -0
- package/assets/prompt-templates/default.md +2 -1
- package/assets/prompt-templates/kimi-k3.md +1 -0
- package/assets/prompt-templates/kimi.md +1 -0
- package/assets/prompt-templates/minimax.md +2 -0
- package/assets/prompt-templates/nemotron.md +1 -0
- package/assets/skills/browser-automation/SKILL.md +113 -0
- package/dist/ClineCore.d.ts +9 -0
- package/dist/account/index.d.ts +1 -0
- package/dist/account/telemetry.d.ts +22 -0
- package/dist/cloud/api.d.ts +122 -0
- package/dist/cloud/controller.d.ts +172 -0
- package/dist/cloud/index.d.ts +9 -0
- package/dist/cloud/index.js +21 -0
- package/dist/cloud/models.d.ts +9 -0
- package/dist/cloud/repositories.d.ts +21 -0
- package/dist/cloud/snapshots.d.ts +22 -0
- package/dist/cloud/state.d.ts +13 -0
- package/dist/cloud/types.d.ts +84 -0
- package/dist/cron/events/cron-event-ingress.d.ts +4 -2
- package/dist/cron/runner/cron-runner.d.ts +5 -2
- package/dist/cron/service/cron-service.d.ts +2 -1
- package/dist/cron/service/schedule-service.d.ts +2 -1
- package/dist/cron/store/sqlite-cron-store.d.ts +7 -1
- package/dist/extensions/composio/composio-meta-tools.d.ts +39 -0
- package/dist/extensions/composio/composio-tools-extension.d.ts +13 -0
- package/dist/extensions/context/agentic-compaction.d.ts +1 -1
- package/dist/extensions/context/cap-thoughts.d.ts +39 -0
- package/dist/extensions/context/capped-thinking.d.ts +5 -0
- package/dist/extensions/context/compaction-shared.d.ts +76 -1
- package/dist/extensions/context/compaction.d.ts +81 -3
- package/dist/extensions/mcp/client.d.ts +1 -1
- package/dist/extensions/tools/code-search.d.ts +16 -0
- package/dist/extensions/tools/definitions.d.ts +5 -5
- package/dist/extensions/tools/executors/bash.d.ts +26 -0
- package/dist/extensions/tools/executors/index.d.ts +1 -1
- package/dist/extensions/tools/index.d.ts +1 -1
- package/dist/extensions/tools/library-tools.d.ts +14 -0
- package/dist/extensions/tools/schemas.d.ts +2 -11
- package/dist/extensions/tools/task-progress.d.ts +37 -0
- package/dist/extensions/tools/team/index.d.ts +1 -0
- package/dist/extensions/tools/team/multi-agent.d.ts +48 -0
- package/dist/extensions/tools/team/persistence-policy.d.ts +56 -0
- package/dist/extensions/tools/team/runtime.d.ts +1 -1
- package/dist/extensions/tools/team/sanitize-team-name.d.ts +5 -0
- package/dist/extensions/tools/team/team-tools.d.ts +1 -1
- package/dist/extensions/tools/types.d.ts +9 -1
- package/dist/extensions/tools/web-scrape-tool.d.ts +49 -0
- package/dist/extensions/tools/web-site-crawl.d.ts +96 -0
- package/dist/hooks/checkpoint-hooks.d.ts +23 -1
- package/dist/hooks/hook-file-hooks.d.ts +27 -0
- package/dist/hooks/subprocess-runner.d.ts +23 -0
- package/dist/hooks/subprocess.d.ts +10 -0
- package/dist/hub/client/index.d.ts +29 -3
- package/dist/hub/client/session-client.d.ts +0 -3
- package/dist/hub/daemon/bind-diagnostics.d.ts +16 -0
- package/dist/hub/daemon/entry.js +701 -652
- package/dist/hub/daemon/index.d.ts +17 -8
- package/dist/hub/discovery/index.d.ts +1 -0
- package/dist/hub/index.js +690 -642
- package/dist/hub/runtime-host/hub-runtime-host.d.ts +4 -2
- package/dist/hub/server/handlers/session-handlers.d.ts +6 -1
- package/dist/index.d.ts +24 -12
- package/dist/index.js +1137 -1062
- package/dist/remote/remote-environments.d.ts +155 -0
- package/dist/remote/remote-helper-entry.d.ts +1 -0
- package/dist/remote/remote-helper-entry.js +5 -0
- package/dist/remote/remote-helper.d.ts +29 -0
- package/dist/remote/remote-helper.js +4 -0
- package/dist/remote/shell-path.d.ts +88 -0
- package/dist/runtime/host/local-runtime-host.d.ts +4 -2
- package/dist/runtime/host/runtime-host.d.ts +13 -1
- package/dist/runtime/orchestration/oauth-refresh-lock.d.ts +6 -0
- package/dist/runtime/orchestration/session-runtime-orchestrator.d.ts +7 -0
- package/dist/runtime/orchestration/team-persistence-writer.d.ts +65 -0
- package/dist/runtime/safety/rules.d.ts +11 -0
- package/dist/runtime/turn-queue/pending-prompt-service.d.ts +1 -0
- package/dist/services/agent-events.d.ts +1 -0
- package/dist/services/cloud-handoff/git-preflight.d.ts +24 -0
- package/dist/services/cloud-handoff/index.d.ts +4 -0
- package/dist/services/cloud-handoff/metadata.d.ts +7 -0
- package/dist/services/cloud-handoff/transcript.d.ts +5 -0
- package/dist/services/cloud-handoff/types.d.ts +35 -0
- package/dist/services/feature-flags/FeatureFlagsService.d.ts +2 -0
- package/dist/services/feature-flags/cline-account-feature-flags.d.ts +5 -0
- package/dist/services/llms/cline-recommended-models.d.ts +1 -0
- package/dist/services/llms/handler-factory.d.ts +12 -0
- package/dist/services/llms/provider-defaults.d.ts +1 -1
- package/dist/services/llms/provider-settings.d.ts +19 -17
- package/dist/services/local-runtime-bootstrap.d.ts +7 -0
- package/dist/services/mcp-install.d.ts +9 -0
- package/dist/services/plugin-commands.d.ts +28 -0
- package/dist/services/providers/local-provider-registry.d.ts +8 -3
- package/dist/services/providers/local-provider-service.d.ts +20 -10
- package/dist/services/providers/model-source.d.ts +6 -1
- package/dist/services/providers/provider-config-fields.d.ts +11 -0
- package/dist/services/retrieval/code-index.d.ts +2 -0
- package/dist/services/retrieval/firecrawl.d.ts +15 -0
- package/dist/services/retrieval/web-mirror.d.ts +101 -0
- package/dist/services/session-import/claude-code.d.ts +1 -1
- package/dist/services/session-import/paths.d.ts +9 -0
- package/dist/services/storage/file-team-store.d.ts +10 -4
- package/dist/services/storage/sqlite-team-store.d.ts +48 -5
- package/dist/services/storage/team-store.d.ts +1 -0
- package/dist/services/telemetry/core-events.d.ts +97 -5
- package/dist/services/telemetry/index.d.ts +1 -0
- package/dist/services/telemetry/index.js +1 -1
- package/dist/services/telemetry/scoped-telemetry.d.ts +31 -0
- package/dist/services/workspace/workspace-manifest.d.ts +34 -0
- package/dist/services/workspace/workspace-telemetry.d.ts +5 -0
- package/dist/session/fork-metadata.d.ts +7 -0
- package/dist/session/models/session-compaction.d.ts +8 -1
- package/dist/session/services/message-builder.d.ts +8 -1
- package/dist/session/services/persistence-service.d.ts +4 -1
- package/dist/session/services/tool-result-cache.d.ts +30 -0
- package/dist/session/session-versioning-service.d.ts +8 -0
- package/dist/session/stores/session-manifest-store.d.ts +2 -4
- package/dist/session/team/team-session-coordinator.d.ts +3 -1
- package/dist/tasks/task-tool.d.ts +2 -2
- package/dist/types/provider-settings.d.ts +11 -0
- package/dist/types/session.d.ts +2 -0
- package/dist/types/storage.d.ts +22 -1
- package/package.json +16 -4
- package/dist/cron/runner/resource-limiter.d.ts +0 -8
- package/dist/services/storage/team-events-retention.d.ts +0 -25
|
@@ -6,6 +6,25 @@
|
|
|
6
6
|
import { type AgentConfig, type AgentEvent, type AgentResult, type AppendMissionLogInput, type AttachTeamOutcomeFragmentInput, type CreateTeamOutcomeInput, type CreateTeamTaskInput, type MissionLogEntry, type ReviewTeamOutcomeFragmentInput, type RouteToTeammateOptions, type TeamAgentSampling, type TeamMailboxMessage, type TeamMemberSnapshot, TeamMessageType, type TeammateLifecycleSpec, type TeamOutcome, type TeamOutcomeFragment, type TeamRunRecord, type TeamRunStatus, type TeamRuntimeSnapshot, type TeamRuntimeState, type TeamTask, type TeamTaskListItem, type TeamTaskStatus } from "@cerebriline/shared";
|
|
7
7
|
import { SessionRuntime } from "../../../runtime/orchestration/session-runtime-orchestrator";
|
|
8
8
|
import { type HandedRevision } from "./delegated-sandboxes";
|
|
9
|
+
/**
|
|
10
|
+
* Incremental change set produced by `AgentTeamsRuntime.drainStateDelta()`.
|
|
11
|
+
* Only entities mutated since the previous drain are included, so the cost of
|
|
12
|
+
* persisting it is proportional to what changed, not to team history.
|
|
13
|
+
*/
|
|
14
|
+
export interface TeamRuntimeStateDelta {
|
|
15
|
+
teamId: string;
|
|
16
|
+
teamName: string;
|
|
17
|
+
/** When true, the store must drop all persisted entities before applying. */
|
|
18
|
+
reset: boolean;
|
|
19
|
+
/** Members are few and cheap; always included in full. */
|
|
20
|
+
members: TeamMemberSnapshot[];
|
|
21
|
+
tasks: TeamTask[];
|
|
22
|
+
mailbox: TeamMailboxMessage[];
|
|
23
|
+
missionLog: MissionLogEntry[];
|
|
24
|
+
runs: TeamRunRecord[];
|
|
25
|
+
outcomes: TeamOutcome[];
|
|
26
|
+
outcomeFragments: TeamOutcomeFragment[];
|
|
27
|
+
}
|
|
9
28
|
export { type AppendMissionLogInput, type AttachTeamOutcomeFragmentInput, type CreateTeamOutcomeInput, type CreateTeamTaskInput, type MissionLogEntry, type MissionLogKind, type ReviewTeamOutcomeFragmentInput, type RouteToTeammateOptions, type TeamMailboxMessage, type TeamMemberSnapshot, TeamMessageType, type TeammateLifecycleSpec, type TeamOutcome, type TeamOutcomeFragment, type TeamOutcomeFragmentStatus, type TeamOutcomeStatus, type TeamRunRecord, type TeamRunStatus, type TeamRuntimeSnapshot, type TeamRuntimeState, type TeamTask, type TeamTaskListItem, type TeamTaskStatus, } from "@cerebriline/shared";
|
|
10
29
|
export interface TeamMemberConfig extends AgentConfig {
|
|
11
30
|
role?: string;
|
|
@@ -123,6 +142,11 @@ export interface AgentTeamsRuntimeOptions {
|
|
|
123
142
|
missionLogIntervalMs?: number;
|
|
124
143
|
maxConcurrentRuns?: number;
|
|
125
144
|
onTeamEvent?: (event: TeamEvent) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Called when persisted state changes without a team event (mailbox read
|
|
147
|
+
* receipts, cleanup), so a persistence writer can schedule a flush.
|
|
148
|
+
*/
|
|
149
|
+
onStateDirty?: () => void;
|
|
126
150
|
/**
|
|
127
151
|
* The teammates' private workspaces, when the host sandboxes them. A
|
|
128
152
|
* teammate's toolset opens its workspace when it is spawned; the runtime
|
|
@@ -199,6 +223,7 @@ export declare class AgentTeamsRuntime {
|
|
|
199
223
|
private readonly teamName;
|
|
200
224
|
private readonly sessionId?;
|
|
201
225
|
private readonly onTeamEvent?;
|
|
226
|
+
private readonly onStateDirty?;
|
|
202
227
|
private readonly members;
|
|
203
228
|
private readonly tasks;
|
|
204
229
|
private readonly missionLog;
|
|
@@ -211,6 +236,7 @@ export declare class AgentTeamsRuntime {
|
|
|
211
236
|
private outcomeCounter;
|
|
212
237
|
private outcomeFragmentCounter;
|
|
213
238
|
private readonly runs;
|
|
239
|
+
private dirty;
|
|
214
240
|
private readonly runQueue;
|
|
215
241
|
private queuedRunDispatchTimer;
|
|
216
242
|
private readonly outcomes;
|
|
@@ -360,5 +386,27 @@ export declare class AgentTeamsRuntime {
|
|
|
360
386
|
private formatProgressErrorActivity;
|
|
361
387
|
private recordProgressStep;
|
|
362
388
|
private buildMailboxNotification;
|
|
389
|
+
/**
|
|
390
|
+
* Record which persisted entity an event mutated. Every durable state
|
|
391
|
+
* change flows through `emitEvent`, so this is the single point that keeps
|
|
392
|
+
* the dirty set in sync with the in-memory maps.
|
|
393
|
+
*/
|
|
394
|
+
private markDirtyFromEvent;
|
|
395
|
+
/** True when there are unpersisted changes. */
|
|
396
|
+
hasPendingStateDelta(): boolean;
|
|
397
|
+
/**
|
|
398
|
+
* Return entities mutated since the last drain and clear the dirty set.
|
|
399
|
+
* Ids whose entity no longer exists are skipped (a `reset` covers removal).
|
|
400
|
+
*/
|
|
401
|
+
drainStateDelta(): TeamRuntimeStateDelta;
|
|
402
|
+
/**
|
|
403
|
+
* Put a drained delta back so a failed write is retried by the next flush.
|
|
404
|
+
* Entities are re-read at drain time, so only ids and the reset flag matter.
|
|
405
|
+
*/
|
|
406
|
+
requeueStateDelta(delta: TeamRuntimeStateDelta): void;
|
|
407
|
+
private notifyStateDirty;
|
|
408
|
+
/** Mark the whole state dirty (used after hydrate/cleanup or a migration). */
|
|
409
|
+
markAllStateDirty(reset?: boolean): void;
|
|
410
|
+
private exportMembers;
|
|
363
411
|
private emitEvent;
|
|
364
412
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type AgentResult, type LegacyAgentUsage } from "@cerebriline/shared";
|
|
2
|
+
import type { TeamEvent } from "./multi-agent";
|
|
3
|
+
/**
|
|
4
|
+
* Persistence policy for team events.
|
|
5
|
+
*
|
|
6
|
+
* Team events fall into two classes:
|
|
7
|
+
* - **durable**: they mutate team state that must survive a restart
|
|
8
|
+
* (tasks, mailbox, mission log, run lifecycle, outcomes, membership).
|
|
9
|
+
* - **telemetry**: high-frequency liveness signals (streamed agent chunks,
|
|
10
|
+
* run heartbeats/activity). These are forwarded to live UIs only and are
|
|
11
|
+
* never written to disk.
|
|
12
|
+
*
|
|
13
|
+
* The switch is exhaustive so adding a new `TeamMessageType` fails to compile
|
|
14
|
+
* until it is classified here.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isDurableTeamEvent(event: TeamEvent): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Durable events that should be flushed to storage immediately instead of
|
|
19
|
+
* waiting for the batch window: terminal run states and membership changes,
|
|
20
|
+
* where losing the write on a crash would leave recovery in a wrong state.
|
|
21
|
+
*/
|
|
22
|
+
export declare function shouldFlushTeamEventImmediately(event: TeamEvent): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Compact form of an `AgentResult` kept on team run records. Contains exactly
|
|
25
|
+
* the fields consumed by run summaries; the full transcript (messages, tool
|
|
26
|
+
* calls) already lives in the teammate's session storage.
|
|
27
|
+
*/
|
|
28
|
+
export interface TeamRunResultRecord {
|
|
29
|
+
text: string;
|
|
30
|
+
iterations: number;
|
|
31
|
+
finishReason: AgentResult["finishReason"];
|
|
32
|
+
durationMs: number;
|
|
33
|
+
usage: LegacyAgentUsage;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Upstream's upper bound for final text kept on a run record (4,000 there).
|
|
37
|
+
*
|
|
38
|
+
* Not applied on this fork: the run record is where a teammate's answer comes
|
|
39
|
+
* from when the lead awaits it, and a long one is filed whole as a report the
|
|
40
|
+
* lead reads with `read_agent_report`. Cut here, the report ended at
|
|
41
|
+
* character 4,000 with "..." and said it was "the end of the report". The
|
|
42
|
+
* record still drops the transcript and the tool calls, which is where the
|
|
43
|
+
* size was.
|
|
44
|
+
*/
|
|
45
|
+
export declare const TEAM_RUN_RESULT_TEXT_LIMIT: number;
|
|
46
|
+
/**
|
|
47
|
+
* Reduce a full (or legacy persisted) agent result to a `TeamRunResultRecord`.
|
|
48
|
+
* Accepts `unknown` because persisted rows written by older versions may hold
|
|
49
|
+
* a full `AgentResult` with dates serialized as strings.
|
|
50
|
+
*/
|
|
51
|
+
export declare function toTeamRunResultRecord(result: unknown): TeamRunResultRecord | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Strip heavy payloads (full transcripts, tool calls) from an event before it
|
|
54
|
+
* is appended to the durable event log.
|
|
55
|
+
*/
|
|
56
|
+
export declare function toPersistableTeamEvent(event: TeamEvent): unknown;
|
|
@@ -2,5 +2,5 @@ export { type AgentSlotGate, type AgentSlotGateRegistry, agentEndpointKey, agent
|
|
|
2
2
|
export { buildDelegatedAgentConfig, createDelegatedAgent, createDelegatedAgentConfigProvider, type DelegatedAgentConfigProvider, type DelegatedAgentConnectionConfig, type DelegatedAgentKind, type DelegatedAgentRuntimeConfig, type DelegatedPrepareTurnTarget, } from "./delegated-agent";
|
|
3
3
|
export { buildSubagentLayout, pinConversationHead, SUBAGENT_BASE_PROMPT, type SubagentKnowledge, type SubagentLayout, } from "./subagent-layout";
|
|
4
4
|
export { createSpawnAgentTool, type SpawnAgentInput, type SpawnAgentOutput, type SpawnAgentToolConfig, type SubAgentEndContext, type SubAgentStartContext, } from "./spawn-agent-tool";
|
|
5
|
-
export { type AgentTask, AgentTeam, AgentTeamsRuntime, type AgentTeamsRuntimeOptions, createAgentTeam, createWorkerReviewerTeam, type SpawnTeammateOptions, type TaskResult, type TeamEvent, type TeamMemberConfig, } from "./multi-agent";
|
|
5
|
+
export { type AgentTask, AgentTeam, AgentTeamsRuntime, type AgentTeamsRuntimeOptions, createAgentTeam, createWorkerReviewerTeam, type SpawnTeammateOptions, type TaskResult, type TeamEvent, type TeamMemberConfig, type TeamRuntimeStateDelta, } from "./multi-agent";
|
|
6
6
|
export { type BootstrapAgentTeamsOptions, type BootstrapAgentTeamsResult, bootstrapAgentTeams, type CreateAgentTeamsToolsOptions, createAgentTeamsTools, reviveTeamStateDates, sanitizeTeamName, type TeamTeammateRuntimeConfig, } from "./team-tools";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { sanitizeTeamName } from "./sanitize-team-name";
|
|
1
2
|
import { type AgentTool, type TeamTeammateSpec } from "@cerebriline/shared";
|
|
2
3
|
import { type DelegatedAgentConfigProvider, type DelegatedAgentRuntimeConfig } from "./delegated-agent";
|
|
3
4
|
import type { AgentTeamsRuntime } from "./multi-agent";
|
|
@@ -53,4 +54,3 @@ export declare const TEAMMATE_TEAM_TOOL_NAMES: ReadonlySet<string>;
|
|
|
53
54
|
export declare function bootstrapAgentTeams(options: BootstrapAgentTeamsOptions): BootstrapAgentTeamsResult;
|
|
54
55
|
export declare function createAgentTeamsTools(options: CreateAgentTeamsToolsOptions): AgentTool[];
|
|
55
56
|
export { reviveTeamStateDates } from "./team-state-dates";
|
|
56
|
-
export declare function sanitizeTeamName(name: string): string;
|
|
@@ -62,7 +62,15 @@ export interface SemanticSearchExecutor {
|
|
|
62
62
|
* indexed. One host serves many workspaces, so the answer is per folder.
|
|
63
63
|
*/
|
|
64
64
|
available(cwd: string): boolean;
|
|
65
|
-
search(query: string, cwd: string, context: AgentToolContext): Promise<string>;
|
|
65
|
+
search(query: string, cwd: string, context: AgentToolContext, options?: SemanticSearchOptions): Promise<string>;
|
|
66
|
+
}
|
|
67
|
+
export interface SemanticSearchOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Read a file of the folder as the caller sees it, by absolute path. A
|
|
70
|
+
* delegated agent works on its own copy: the lines a passage is on are the
|
|
71
|
+
* lines of that copy, not of the lead's file.
|
|
72
|
+
*/
|
|
73
|
+
readFile?: (absolutePath: string) => Promise<string | undefined>;
|
|
66
74
|
}
|
|
67
75
|
/**
|
|
68
76
|
* Per-call execution options for a shell executor.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `web_scrape`: the web through a Firecrawl endpoint.
|
|
3
|
+
*
|
|
4
|
+
* Two shapes of one tool. The librarian's looks at the web to choose what a
|
|
5
|
+
* book is made from: search, map, read. The general one is offered to any
|
|
6
|
+
* task when the user turns "Only for the librarian" off, and adds what a task
|
|
7
|
+
* outside the Library needs: a crawl that saves a site into the workspace.
|
|
8
|
+
* By default that is the site itself -- every page as it was served and as
|
|
9
|
+
* the browser rendered it, with the stylesheets, scripts, pictures and fonts
|
|
10
|
+
* it uses -- beside a markdown reading of each page; `content: "text"` keeps
|
|
11
|
+
* the markdown alone, for notes.
|
|
12
|
+
*
|
|
13
|
+
* The lead's only: it is not in `DELEGATED_HOST_TOOLS`, so a delegated agent,
|
|
14
|
+
* whose writes go through its overlay, is never handed a tool that writes to
|
|
15
|
+
* the workspace directly.
|
|
16
|
+
*/
|
|
17
|
+
import { type AgentTool } from "@cerebriline/shared";
|
|
18
|
+
import type { LibraryScrapeConfig } from "./library-tools";
|
|
19
|
+
export { cleanLink, linkCensus, pageFileName } from "./web-site-crawl";
|
|
20
|
+
export declare const WEB_SCRAPE_TOOL_NAME = "web_scrape";
|
|
21
|
+
export declare const NO_SCRAPER = "Web scraping is not set up for this session. The user sets the endpoint under Settings > Features and allows it in the API configuration; do not call this again in this task.";
|
|
22
|
+
export interface WebScrapeToolOptions {
|
|
23
|
+
/** The folder saved pages are written under. */
|
|
24
|
+
cwd: string;
|
|
25
|
+
/** The endpoint and its limits, read on every call. Undefined: not set up. */
|
|
26
|
+
getScrape: () => LibraryScrapeConfig | undefined;
|
|
27
|
+
/** What stops the tool before the endpoint is asked, said to the model. */
|
|
28
|
+
unavailable?: () => string | undefined;
|
|
29
|
+
/** The general tool: `crawl`, and `save_to`. @default false, the librarian's */
|
|
30
|
+
general?: boolean;
|
|
31
|
+
onError?: (message: string, error: unknown) => void;
|
|
32
|
+
/**
|
|
33
|
+
* A text file the tool wrote, by absolute path. The host forgets what it
|
|
34
|
+
* knew of the file, so a later read is not told that something outside the
|
|
35
|
+
* session changed it.
|
|
36
|
+
*/
|
|
37
|
+
onWrote?: (file: string) => void;
|
|
38
|
+
}
|
|
39
|
+
/** `target` under `cwd`, or nothing when it would leave the folder. */
|
|
40
|
+
export declare function workspacePath(cwd: string, target: string): string | undefined;
|
|
41
|
+
export declare function createWebScrapeTool(options: WebScrapeToolOptions): AgentTool;
|
|
42
|
+
/**
|
|
43
|
+
* The general tool, when scraping is set up, allowed, and not kept for the
|
|
44
|
+
* librarian. Decided at session start, like every other tool list; the
|
|
45
|
+
* endpoint itself is read again on every call.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createWebScrapeTools(options: Omit<WebScrapeToolOptions, "general"> & {
|
|
48
|
+
log?: (message: string) => void;
|
|
49
|
+
}): AgentTool[];
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A site crawled into a folder of the workspace, and continued later.
|
|
3
|
+
*
|
|
4
|
+
* The folder keeps a record of the crawl (`.scrape.json`): the pages read
|
|
5
|
+
* and where each was saved, the files fetched, the pages that are linked and
|
|
6
|
+
* were not read, and the files a limit left out. A later crawl into the same
|
|
7
|
+
* folder with `resume` reads only what is missing -- the pages from that
|
|
8
|
+
* list, one by one through the endpoint, and the files not yet on disk --
|
|
9
|
+
* and nothing that is already there.
|
|
10
|
+
*
|
|
11
|
+
* Every limit that stopped something is said at the top of the result, as an
|
|
12
|
+
* alert the model is told to pass on: the user set those limits, and only
|
|
13
|
+
* the user can raise them.
|
|
14
|
+
*/
|
|
15
|
+
import { type ScrapedPage } from "../../services/retrieval/firecrawl";
|
|
16
|
+
import type { LibraryScrapeConfig } from "./library-tools";
|
|
17
|
+
export declare function plural(count: number, one: string, many?: string): string;
|
|
18
|
+
/** An http(s) address without its fragment, or nothing. */
|
|
19
|
+
export declare function cleanLink(link: string): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* A page's file under the crawl's folder: its host and path, with what a
|
|
22
|
+
* file name cannot hold replaced, so two pages of a site never collide and
|
|
23
|
+
* the folder reads like the site.
|
|
24
|
+
*/
|
|
25
|
+
export declare function pageFileName(url: string, taken: Set<string>): string;
|
|
26
|
+
export declare function pageFile(page: ScrapedPage): string;
|
|
27
|
+
/**
|
|
28
|
+
* Where the links of the pages read lead: pages of the same site that were
|
|
29
|
+
* not read, and other sites. It is what tells "the site has no more pages"
|
|
30
|
+
* from "the crawl stopped short" -- the two read the same from a page count.
|
|
31
|
+
*/
|
|
32
|
+
export declare function linkCensus(pages: readonly ScrapedPage[], start: string): {
|
|
33
|
+
unread: string[];
|
|
34
|
+
elsewhere: string[];
|
|
35
|
+
};
|
|
36
|
+
export declare function sitesLine(hosts: readonly string[], most?: number): string;
|
|
37
|
+
/** The record a crawl leaves in its folder. */
|
|
38
|
+
export declare const SITE_RECORD_FILE = ".scrape.json";
|
|
39
|
+
export interface SiteRecord {
|
|
40
|
+
version: 1;
|
|
41
|
+
/** The address the crawl started from. */
|
|
42
|
+
url: string;
|
|
43
|
+
content: "site" | "text";
|
|
44
|
+
wholeSite: boolean;
|
|
45
|
+
include: string[];
|
|
46
|
+
exclude: string[];
|
|
47
|
+
/** Pages read, by address. */
|
|
48
|
+
pages: Record<string, {
|
|
49
|
+
title?: string;
|
|
50
|
+
markdown: string;
|
|
51
|
+
characters: number;
|
|
52
|
+
served?: string;
|
|
53
|
+
rendered?: string;
|
|
54
|
+
}>;
|
|
55
|
+
/** Files fetched, by address. */
|
|
56
|
+
assets: Record<string, {
|
|
57
|
+
file: string;
|
|
58
|
+
bytes: number;
|
|
59
|
+
}>;
|
|
60
|
+
/** Pages of the site that are linked and were not read. */
|
|
61
|
+
unread: string[];
|
|
62
|
+
/** Files a limit left out. */
|
|
63
|
+
assetsLeft: string[];
|
|
64
|
+
/** Files that could not be fetched, with the reason. */
|
|
65
|
+
failed: Record<string, string>;
|
|
66
|
+
/** Pages that could not be read, with the reason. */
|
|
67
|
+
failedPages: Record<string, string>;
|
|
68
|
+
}
|
|
69
|
+
export interface CrawlToFolderRequest {
|
|
70
|
+
scrape: LibraryScrapeConfig;
|
|
71
|
+
url: string;
|
|
72
|
+
/** The folder, absolute. */
|
|
73
|
+
target: string;
|
|
74
|
+
/** The folder as the model named it, for the result. */
|
|
75
|
+
folder: string;
|
|
76
|
+
limit?: number;
|
|
77
|
+
depth?: number;
|
|
78
|
+
include: string[];
|
|
79
|
+
exclude: string[];
|
|
80
|
+
wholeSite?: boolean;
|
|
81
|
+
content?: "site" | "text";
|
|
82
|
+
resume: boolean;
|
|
83
|
+
signal?: AbortSignal;
|
|
84
|
+
emit?: (status: string) => void;
|
|
85
|
+
/** A text file the crawl wrote or rewrote, by absolute path. */
|
|
86
|
+
wrote?: (file: string) => void;
|
|
87
|
+
/** The crawl stopped at a limit of the user's; see `reportStoppedForUser`. */
|
|
88
|
+
stopped?: (reason: string) => void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Whether a link is one this crawl reads: the same site, below the starting
|
|
92
|
+
* address unless the whole site was asked for, and through the path filters.
|
|
93
|
+
*/
|
|
94
|
+
export declare function inCrawlScope(link: string, record: Pick<SiteRecord, "url" | "wholeSite" | "include" | "exclude">): boolean;
|
|
95
|
+
/** Crawl a site into a folder, or continue the crawl that is there. */
|
|
96
|
+
export declare function crawlToFolder(request: CrawlToFolderRequest): Promise<string>;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
import type { AgentHooks, BasicLogger } from "@cerebriline/shared";
|
|
1
|
+
import type { AgentHooks, BasicLogger, ITelemetryService } from "@cerebriline/shared";
|
|
2
2
|
export declare function isCheckpointStashMessage(message: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Per-session scratch directory holding the persistent `GIT_INDEX_FILE` used
|
|
5
|
+
* to snapshot untracked files. Persisting the index across turns lets git's
|
|
6
|
+
* stat cache skip re-reading (and re-hashing) untracked files that have not
|
|
7
|
+
* changed since the previous checkpoint — without it, every turn re-hashes
|
|
8
|
+
* every untracked byte in the workspace.
|
|
9
|
+
*
|
|
10
|
+
* Lives under the user's Cline data dir (never the world-shared OS tmpdir:
|
|
11
|
+
* the index and pathspec files enumerate workspace paths) and is keyed by a
|
|
12
|
+
* hash of cwd + session id: hashing avoids sanitization collisions between
|
|
13
|
+
* distinct ids, and folding in cwd keeps a session restored against a
|
|
14
|
+
* different workspace from inheriting a foreign index. Removed by
|
|
15
|
+
* `deleteCheckpointRefs` and by the age-based reaper.
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkpointScratchDir(cwd: string, sessionId: string): string;
|
|
3
18
|
export interface CheckpointEntry {
|
|
4
19
|
ref: string;
|
|
5
20
|
createdAt: number;
|
|
@@ -26,6 +41,13 @@ type CreateCheckpointHooksOptions = {
|
|
|
26
41
|
sessionId: string;
|
|
27
42
|
runCount: number;
|
|
28
43
|
}) => Promise<CheckpointEntry | undefined> | CheckpointEntry | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Emits one `checkpoint.snapshot` event per built-in snapshot attempt so
|
|
46
|
+
* snapshot cost and degradations (HEAD fallbacks, skipped turns) are
|
|
47
|
+
* observable in the field, not only in local logs. Properties carry
|
|
48
|
+
* outcome and duration — never file paths or contents.
|
|
49
|
+
*/
|
|
50
|
+
telemetry?: Pick<ITelemetryService, "capture">;
|
|
29
51
|
};
|
|
30
52
|
/**
|
|
31
53
|
* Deletes all private git refs under refs/cline/checkpoints/{sessionId}/ that
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import type { AgentExtension, AgentHooks, BasicLogger, WorkspaceInfo } from "@cerebriline/shared";
|
|
2
|
+
import { type HookEventName } from "./subprocess";
|
|
3
|
+
/**
|
|
4
|
+
* Reports how long a fire-and-forget hook actually ran, once per hook. Hosts
|
|
5
|
+
* use it to learn the real runtime distribution of detached hooks —
|
|
6
|
+
* unmeasurable while nothing awaits them — before deciding to run any of them
|
|
7
|
+
* blocking. `exited: false` is a censored observation (the hook was still
|
|
8
|
+
* running after the observation window, so it ran at least `durationMs`),
|
|
9
|
+
* which is what keeps the sample from covering only hooks that finish.
|
|
10
|
+
*/
|
|
11
|
+
export type HookRuntimeObserver = (event: {
|
|
12
|
+
hookName: HookEventName;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
exitCode: number | null;
|
|
15
|
+
exited: boolean;
|
|
16
|
+
}) => void;
|
|
2
17
|
type HookRuntimeOptions = {
|
|
3
18
|
cwd: string;
|
|
4
19
|
workspacePath: string;
|
|
@@ -7,6 +22,18 @@ type HookRuntimeOptions = {
|
|
|
7
22
|
toolCallTimeoutMs?: number;
|
|
8
23
|
/** Keep asynchronous hooks attached until exit. Intended for deterministic tests. */
|
|
9
24
|
detachAsyncHooks?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Run agent_start/agent_resume hooks blocking, honoring their control
|
|
27
|
+
* output (cancel, contextModification). Off by default: these hooks have
|
|
28
|
+
* always been fire-and-forget with stdio ignored, so an existing
|
|
29
|
+
* long-running script would otherwise stall every run start until the
|
|
30
|
+
* timeout. A host that flips this on must tell hook authors that
|
|
31
|
+
* long-running run-start hooks need to background themselves (spawn a
|
|
32
|
+
* detached child and exit).
|
|
33
|
+
*/
|
|
34
|
+
blockingRunStartHooks?: boolean;
|
|
35
|
+
/** Observes how long detached hooks run. See {@link HookRuntimeObserver}. */
|
|
36
|
+
onHookRuntime?: HookRuntimeObserver;
|
|
10
37
|
/** Structured git + path metadata forwarded into every hook payload. */
|
|
11
38
|
workspaceInfo?: WorkspaceInfo;
|
|
12
39
|
};
|
|
@@ -9,6 +9,29 @@ export interface RunSubprocessEventOptions {
|
|
|
9
9
|
pid?: number;
|
|
10
10
|
detached: boolean;
|
|
11
11
|
}) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Reports a detached hook's runtime exactly once. The run never waits on
|
|
14
|
+
* this: detached hooks are fire-and-forget by contract, and this only
|
|
15
|
+
* observes them so hosts can measure how long they actually take.
|
|
16
|
+
*
|
|
17
|
+
* `exited: true` means the hook finished and `durationMs` is its runtime.
|
|
18
|
+
* `exited: false` is a censored observation: the hook was still running
|
|
19
|
+
* after the observation window, and `durationMs` is that window, so read
|
|
20
|
+
* it as "ran at least this long" and count these separately — the
|
|
21
|
+
* case that matters most, since those are the hooks that would stall a
|
|
22
|
+
* blocking run. Without it the sample would only contain hooks that
|
|
23
|
+
* finished.
|
|
24
|
+
*
|
|
25
|
+
* Nothing is reported if the parent exits before either happens.
|
|
26
|
+
*/
|
|
27
|
+
onDetachedSettled?: (event: {
|
|
28
|
+
command: string[];
|
|
29
|
+
durationMs: number;
|
|
30
|
+
exitCode: number | null;
|
|
31
|
+
exited: boolean;
|
|
32
|
+
}) => void;
|
|
33
|
+
/** Overrides the censoring window for `onDetachedSettled`. */
|
|
34
|
+
detachedObservationMs?: number;
|
|
12
35
|
}
|
|
13
36
|
export interface RunSubprocessEventResult {
|
|
14
37
|
exitCode: number | null;
|
|
@@ -49,6 +49,16 @@ export interface SubprocessHooksOptions {
|
|
|
49
49
|
workspaceInfo?: WorkspaceInfo;
|
|
50
50
|
env?: NodeJS.ProcessEnv;
|
|
51
51
|
timeoutMs?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Run agent_start/agent_resume hooks blocking, honoring their control
|
|
54
|
+
* output (cancel, contextModification). Off by default: these hooks have
|
|
55
|
+
* always been fire-and-forget with stdio ignored, so an existing
|
|
56
|
+
* long-running script would otherwise stall every run start until the
|
|
57
|
+
* timeout. A host that flips this on must tell hook authors that
|
|
58
|
+
* long-running run-start hooks need to background themselves (spawn a
|
|
59
|
+
* detached child and exit).
|
|
60
|
+
*/
|
|
61
|
+
blockingRunStartHooks?: boolean;
|
|
52
62
|
onDispatchError?: (error: Error, payload: HookEventPayload) => void;
|
|
53
63
|
onDispatch?: (event: {
|
|
54
64
|
payload: HookEventPayload;
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
import { type HubClientRegistration, type HubCommandEnvelope, type HubEventEnvelope, type HubReplyEnvelope } from "@cerebriline/shared";
|
|
2
2
|
import { type HubOwnerContext } from "../discovery";
|
|
3
|
+
type HubCommandOptions = {
|
|
4
|
+
timeoutMs?: number | null;
|
|
5
|
+
/** Synchronous local guard, checked after connection before each dispatch. */
|
|
6
|
+
beforeDispatch?: () => void;
|
|
7
|
+
/** Observes this attempt's correlation id after the local guard, before sending.
|
|
8
|
+
* Dispatch alone does not confirm that the server accepted the command. */
|
|
9
|
+
onDispatch?: (requestId: string) => void;
|
|
10
|
+
};
|
|
3
11
|
export interface HubClientOptions {
|
|
4
12
|
url: string;
|
|
5
13
|
clientId?: string;
|
|
6
14
|
clientType?: string;
|
|
7
15
|
displayName?: string;
|
|
16
|
+
/** Version reported to the hub; defaults to the @cline/core version. */
|
|
17
|
+
clientVersion?: string;
|
|
18
|
+
/** Additional registration metadata; version and pid are owned by the client. */
|
|
19
|
+
metadata?: Record<string, unknown>;
|
|
8
20
|
workspaceRoot?: string;
|
|
9
21
|
cwd?: string;
|
|
22
|
+
/** Hub token sent with the `cline-hub-auth.*` WebSocket subprotocol. */
|
|
10
23
|
authToken?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolves HTTP headers for each new WebSocket, including reconnects.
|
|
26
|
+
* This Node-only transport option is mutually exclusive with `authToken`.
|
|
27
|
+
* Resolver failures are surfaced by `connect()` and `getConnectionError()`;
|
|
28
|
+
* `Sec-WebSocket-Protocol` must be configured through `authToken` instead.
|
|
29
|
+
*/
|
|
30
|
+
resolveConnectionHeaders?: () => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>;
|
|
11
31
|
capabilities?: HubClientRegistration["capabilities"];
|
|
12
32
|
}
|
|
13
33
|
export interface LocalHubResolutionOptions {
|
|
@@ -15,6 +35,11 @@ export interface LocalHubResolutionOptions {
|
|
|
15
35
|
strategy?: "prefer-hub" | "require-hub";
|
|
16
36
|
workspaceRoot?: string;
|
|
17
37
|
cwd?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Called with the error when starting a detached Hub fails. The function
|
|
40
|
+
* still resolves `undefined` in that case; this lets a caller report why.
|
|
41
|
+
*/
|
|
42
|
+
onStartupError?: (error: unknown) => void;
|
|
18
43
|
}
|
|
19
44
|
export type HubTransportErrorCode = "hub_connect_timeout" | "hub_connect_failed" | "hub_connection_closed" | "hub_connection_not_open";
|
|
20
45
|
export declare class HubTransportError extends Error {
|
|
@@ -57,6 +82,7 @@ export declare class NodeHubClient {
|
|
|
57
82
|
private reconnectTimer;
|
|
58
83
|
private reconnectAttempt;
|
|
59
84
|
private closedByClient;
|
|
85
|
+
private connectGeneration;
|
|
60
86
|
private lastCloseError;
|
|
61
87
|
private sawSocketClose;
|
|
62
88
|
private registered;
|
|
@@ -68,12 +94,11 @@ export declare class NodeHubClient {
|
|
|
68
94
|
getConnectionError(): HubTransportError | null;
|
|
69
95
|
updateCapabilities(capabilities: NonNullable<HubClientRegistration["capabilities"]>): Promise<void>;
|
|
70
96
|
connect(): Promise<void>;
|
|
97
|
+
private openSocket;
|
|
71
98
|
subscribe(listener: (event: HubEventEnvelope) => void, options?: {
|
|
72
99
|
sessionId?: string;
|
|
73
100
|
}): () => void;
|
|
74
|
-
command(command: HubCommandEnvelope["command"], payload?: Record<string, unknown>, sessionId?: string, options?:
|
|
75
|
-
timeoutMs?: number | null;
|
|
76
|
-
}): Promise<HubReplyEnvelope>;
|
|
101
|
+
command(command: HubCommandEnvelope["command"], payload?: Record<string, unknown>, sessionId?: string, options?: HubCommandOptions): Promise<HubReplyEnvelope>;
|
|
77
102
|
private commandOnce;
|
|
78
103
|
private recoverLocalHubTransport;
|
|
79
104
|
private hasActiveSubscriptions;
|
|
@@ -144,3 +169,4 @@ export declare function restartLocalHubIfIdleAfterStartupTimeout(options: {
|
|
|
144
169
|
workspaceRoot?: string;
|
|
145
170
|
cwd?: string;
|
|
146
171
|
}): Promise<string | undefined>;
|
|
172
|
+
export {};
|
|
@@ -56,11 +56,8 @@ export interface HubTeamProgressHandlers {
|
|
|
56
56
|
onError?: (error: Error) => void;
|
|
57
57
|
}
|
|
58
58
|
export declare class HubSessionClient {
|
|
59
|
-
private readonly options;
|
|
60
59
|
private readonly client;
|
|
61
|
-
private metadataApplied;
|
|
62
60
|
constructor(options: HubSessionClientOptions);
|
|
63
|
-
private ensureMetadataApplied;
|
|
64
61
|
connect(): Promise<void>;
|
|
65
62
|
private taskCommand;
|
|
66
63
|
close(): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort description of who holds the Hub port when the daemon dies with
|
|
3
|
+
* `EADDRINUSE`. The daemon takes the owner instance lock before binding, so an
|
|
4
|
+
* occupant on the port is never a live Hub for this owner; these details tell
|
|
5
|
+
* us what it actually is (an older pre-lock Hub, a leaked handle, another
|
|
6
|
+
* owner context, or an unrelated program) so the fix can target that case.
|
|
7
|
+
*/
|
|
8
|
+
import type { TelemetryProperties } from "@cerebriline/shared";
|
|
9
|
+
/** `lsof -Fpc` emits `p<pid>` then `c<command>` per process. */
|
|
10
|
+
export declare function parseLsofOwners(output: string): string[];
|
|
11
|
+
/** Telemetry context for a `hub.daemon.startup` failure caused by `EADDRINUSE`. */
|
|
12
|
+
export declare function describeAddressInUse(error: unknown, endpoint: {
|
|
13
|
+
host: string;
|
|
14
|
+
port: number;
|
|
15
|
+
pathname: string;
|
|
16
|
+
}): Promise<TelemetryProperties>;
|