@corenel/harness 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approvals/service.d.ts.map +1 -1
- package/dist/approvals/service.js +4 -1
- package/dist/approvals/service.js.map +1 -1
- package/dist/audit/log.d.ts.map +1 -1
- package/dist/audit/log.js +12 -1
- package/dist/audit/log.js.map +1 -1
- package/dist/audit/recorder.d.ts +12 -1
- package/dist/audit/recorder.d.ts.map +1 -1
- package/dist/audit/recorder.js +36 -5
- package/dist/audit/recorder.js.map +1 -1
- package/dist/audit/runAudit.d.ts +2 -1
- package/dist/audit/runAudit.d.ts.map +1 -1
- package/dist/audit/runAudit.js +4 -0
- package/dist/audit/runAudit.js.map +1 -1
- package/dist/conversation.d.ts +33 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +44 -1
- package/dist/conversation.js.map +1 -1
- package/dist/core/compactHistory.d.ts +27 -18
- package/dist/core/compactHistory.d.ts.map +1 -1
- package/dist/core/compactHistory.js +106 -40
- package/dist/core/compactHistory.js.map +1 -1
- package/dist/core/dontsRecent.d.ts +5 -0
- package/dist/core/dontsRecent.d.ts.map +1 -0
- package/dist/core/dontsRecent.js +23 -0
- package/dist/core/dontsRecent.js.map +1 -0
- package/dist/core/foldBlocks.d.ts +43 -0
- package/dist/core/foldBlocks.d.ts.map +1 -0
- package/dist/core/foldBlocks.js +114 -0
- package/dist/core/foldBlocks.js.map +1 -0
- package/dist/core/foldTypes.d.ts +25 -0
- package/dist/core/foldTypes.d.ts.map +1 -0
- package/dist/core/foldTypes.js +2 -0
- package/dist/core/foldTypes.js.map +1 -0
- package/dist/core/loop.d.ts +26 -5
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +274 -74
- package/dist/core/loop.js.map +1 -1
- package/dist/core/recovery.d.ts +1 -0
- package/dist/core/recovery.d.ts.map +1 -1
- package/dist/core/recovery.js +12 -0
- package/dist/core/recovery.js.map +1 -1
- package/dist/core/spawn.d.ts +13 -1
- package/dist/core/spawn.d.ts.map +1 -1
- package/dist/core/spawn.js +10 -1
- package/dist/core/spawn.js.map +1 -1
- package/dist/core/summarize.d.ts +9 -3
- package/dist/core/summarize.d.ts.map +1 -1
- package/dist/core/summarize.js +97 -42
- package/dist/core/summarize.js.map +1 -1
- package/dist/dag/executeNode.d.ts +3 -1
- package/dist/dag/executeNode.d.ts.map +1 -1
- package/dist/dag/executeNode.js +1 -0
- package/dist/dag/executeNode.js.map +1 -1
- package/dist/guardrail/permission-service.d.ts.map +1 -1
- package/dist/guardrail/permission-service.js +31 -11
- package/dist/guardrail/permission-service.js.map +1 -1
- package/dist/guardrail/serialize.d.ts.map +1 -1
- package/dist/guardrail/serialize.js +5 -0
- package/dist/guardrail/serialize.js.map +1 -1
- package/dist/guardrail/validate.d.ts.map +1 -1
- package/dist/guardrail/validate.js +21 -6
- package/dist/guardrail/validate.js.map +1 -1
- package/dist/memory/store.d.ts +3 -0
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +16 -1
- package/dist/memory/store.js.map +1 -1
- package/dist/orchestrator/record.d.ts +7 -0
- package/dist/orchestrator/record.d.ts.map +1 -1
- package/dist/orchestrator/record.js +14 -2
- package/dist/orchestrator/record.js.map +1 -1
- package/dist/prompts/library/defaults.generated.d.ts +2 -0
- package/dist/prompts/library/defaults.generated.d.ts.map +1 -1
- package/dist/prompts/library/defaults.generated.js +6 -0
- package/dist/prompts/library/defaults.generated.js.map +1 -1
- package/dist/prompts/library/index.d.ts +3 -0
- package/dist/prompts/library/index.d.ts.map +1 -1
- package/dist/prompts/library/index.js +3 -0
- package/dist/prompts/library/index.js.map +1 -1
- package/dist/sessions/directivesStore.d.ts +9 -0
- package/dist/sessions/directivesStore.d.ts.map +1 -0
- package/dist/sessions/directivesStore.js +54 -0
- package/dist/sessions/directivesStore.js.map +1 -0
- package/dist/sessions/fileSessionStore.d.ts +3 -2
- package/dist/sessions/fileSessionStore.d.ts.map +1 -1
- package/dist/sessions/fileSessionStore.js +30 -9
- package/dist/sessions/fileSessionStore.js.map +1 -1
- package/dist/sessions/foldStorage.d.ts +15 -0
- package/dist/sessions/foldStorage.d.ts.map +1 -0
- package/dist/sessions/foldStorage.js +121 -0
- package/dist/sessions/foldStorage.js.map +1 -0
- package/dist/sessions/jsonl.d.ts +6 -0
- package/dist/sessions/jsonl.d.ts.map +1 -1
- package/dist/sessions/jsonl.js +15 -1
- package/dist/sessions/jsonl.js.map +1 -1
- package/dist/sidecar/accessTestRig.d.ts +32 -0
- package/dist/sidecar/accessTestRig.d.ts.map +1 -0
- package/dist/sidecar/accessTestRig.js +107 -0
- package/dist/sidecar/accessTestRig.js.map +1 -0
- package/dist/sidecar/askView.d.ts +20 -0
- package/dist/sidecar/askView.d.ts.map +1 -0
- package/dist/sidecar/askView.js +38 -0
- package/dist/sidecar/askView.js.map +1 -0
- package/dist/sidecar/host.d.ts +139 -11
- package/dist/sidecar/host.d.ts.map +1 -1
- package/dist/sidecar/host.js +394 -13
- package/dist/sidecar/host.js.map +1 -1
- package/dist/sidecar/hostCapability.d.ts +6 -0
- package/dist/sidecar/hostCapability.d.ts.map +1 -0
- package/dist/sidecar/hostCapability.js +7 -0
- package/dist/sidecar/hostCapability.js.map +1 -0
- package/dist/sidecar/identity.d.ts +5 -0
- package/dist/sidecar/identity.d.ts.map +1 -1
- package/dist/sidecar/memberGate.d.ts +5 -0
- package/dist/sidecar/memberGate.d.ts.map +1 -0
- package/dist/sidecar/memberGate.js +128 -0
- package/dist/sidecar/memberGate.js.map +1 -0
- package/dist/sidecar/server.d.ts +425 -11
- package/dist/sidecar/server.d.ts.map +1 -1
- package/dist/sidecar/server.js +1820 -53
- package/dist/sidecar/server.js.map +1 -1
- package/dist/skills.d.ts +7 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +18 -5
- package/dist/skills.js.map +1 -1
- package/dist/tools/builtins.d.ts +17 -0
- package/dist/tools/builtins.d.ts.map +1 -1
- package/dist/tools/builtins.js +22 -2
- package/dist/tools/builtins.js.map +1 -1
- package/dist/tools/callAgent.d.ts +14 -1
- package/dist/tools/callAgent.d.ts.map +1 -1
- package/dist/tools/callAgent.js +18 -2
- package/dist/tools/callAgent.js.map +1 -1
- package/dist/tools/createCrewAgent.d.ts +39 -0
- package/dist/tools/createCrewAgent.d.ts.map +1 -0
- package/dist/tools/createCrewAgent.js +121 -0
- package/dist/tools/createCrewAgent.js.map +1 -0
- package/dist/tools/foldTools.d.ts +5 -0
- package/dist/tools/foldTools.d.ts.map +1 -0
- package/dist/tools/foldTools.js +123 -0
- package/dist/tools/foldTools.js.map +1 -0
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +7 -2
- package/dist/tools/skillTool.js.map +1 -1
- package/package.json +2 -2
package/dist/sidecar/server.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AgentTool, AgentEvent, PermissionDecision, SidecarRoots, DaemonRunActivity, DaemonRegistration, AgentPause, HostSummary, SidecarProcs, SidecarSessions, RoomOpenRequest, RoomSummary, RoomFinding, RoomFindingEdit, ChecksState, WorkspaceLockRef, DaemonApprovalChoice, DaemonApprovalOffer, DaemonApprovalsState, CrewDeployCaller, CrewDeployReply, EcPublicJwk } from '@corenel/protocol';
|
|
1
|
+
import type { AgentTool, AgentEvent, PermissionDecision, SidecarRoots, DaemonRunActivity, DaemonRegistration, AgentPause, HostSummary, SidecarProcs, SidecarSessions, SidecarSpeech, RoomOpenRequest, RoomSummary, RoomFinding, RoomFindingEdit, ChecksState, WorkspaceLockRef, DaemonApprovalChoice, DaemonApprovalOffer, DaemonApprovalsState, CrewDeployCaller, CrewDeployReply, EcPublicJwk, CrewAgentRef, AccessReply, AccessRequestMsg, NodeEvent, McpBinding, MemberReply, MemberRequestMsg, MemberStatus, AccessOverviewRow, AgentCredStatusRow, InactiveDeployment, PersonInfo } from '@corenel/protocol';
|
|
2
|
+
import type { PeerReply, PeerRequestMsg } from '@corenel/protocol';
|
|
2
3
|
import { type SidecarChannel, type SidecarMsg, type SidecarInfo, type SidecarRunner, type SidecarHostSync, type SidecarConfig, type SidecarAcp, type WebPushSubscription } from '@corenel/protocol';
|
|
3
4
|
import type { ExplainingIdentityVerifier, SidecarAdmission } from './identity';
|
|
4
5
|
import { type KeySigner } from './deviceKeys';
|
|
@@ -70,6 +71,7 @@ export interface SidecarRunHub {
|
|
|
70
71
|
stopReason: string;
|
|
71
72
|
}): void;
|
|
72
73
|
error(message: string): void;
|
|
74
|
+
child?(e: NodeEvent): void;
|
|
73
75
|
}): {
|
|
74
76
|
replay: {
|
|
75
77
|
events: AgentEvent[];
|
|
@@ -132,6 +134,14 @@ export interface SidecarRooms {
|
|
|
132
134
|
* caller renders the reason. */
|
|
133
135
|
editFinding(roomId: string, participantId: string, edit: RoomFindingEdit): Promise<RoomFinding[]>;
|
|
134
136
|
subscribe(cb: (room: RoomSummary) => void): () => void;
|
|
137
|
+
/** Team agent access (Part B): may verified user `userId` run EVERY agent
|
|
138
|
+
* participant here, each judged where the daemon actually finds it (the
|
|
139
|
+
* same lookup a room turn runs)? An agent it cannot find is a no. Absent: a
|
|
140
|
+
* team-mode daemon with access wired refuses to open or drive any room. */
|
|
141
|
+
mayRun?(participants: readonly {
|
|
142
|
+
kind: 'agent' | 'human';
|
|
143
|
+
name: string;
|
|
144
|
+
}[], userId: string): Promise<boolean>;
|
|
135
145
|
}
|
|
136
146
|
/** The daemon's pause overrides, behind the `agent-pause-*` messages.
|
|
137
147
|
*
|
|
@@ -241,21 +251,38 @@ export interface SidecarDevices {
|
|
|
241
251
|
revoke(id: string, now: number): Promise<boolean>;
|
|
242
252
|
onRevoked(cb: (id: string) => void): () => void;
|
|
243
253
|
}
|
|
244
|
-
/** The daemon's
|
|
245
|
-
*
|
|
254
|
+
/** The daemon's standing approvals (plan 3), behind the `approvals-*`
|
|
255
|
+
* messages.
|
|
246
256
|
*
|
|
247
257
|
* Declared HERE for the same dependency-direction reason as `SidecarPauses`:
|
|
248
258
|
* packages/sidecar implements it (src/approvals/daemonApprovals.ts).
|
|
249
259
|
*
|
|
250
260
|
* `accept`'s `by` is the object THIS connection attached to the attendance
|
|
251
|
-
* registry
|
|
252
|
-
*
|
|
253
|
-
*
|
|
261
|
+
* registry. `userId` on every method is THIS connection's verified user id
|
|
262
|
+
* (spec 2026-10-01 Part C: a team agent's owner accepts and revokes its
|
|
263
|
+
* rules). Neither is ever taken from the message. `ref` is the message's
|
|
264
|
+
* agent reference, validated by the port. There is no method that adds a
|
|
265
|
+
* rule directly. Every method throws for a refusal; the reason is sent back.
|
|
266
|
+
* On a team daemon only an `ApprovalsRefusal`'s reason is: anything else is
|
|
267
|
+
* unexpected, is logged, and goes on the wire as APPROVALS_FAILED. */
|
|
254
268
|
export interface SidecarApprovals {
|
|
255
|
-
accept(by: unknown, suggestionId: string, choice: DaemonApprovalChoice): Promise<void>;
|
|
256
|
-
state(): Promise<DaemonApprovalsState>;
|
|
257
|
-
revoke(tool: string): Promise<DaemonApprovalsState>;
|
|
269
|
+
accept(by: unknown, suggestionId: string, choice: DaemonApprovalChoice, userId?: string): Promise<void>;
|
|
270
|
+
state(ref?: unknown, userId?: string): Promise<DaemonApprovalsState>;
|
|
271
|
+
revoke(tool: string, ref?: unknown, userId?: string): Promise<DaemonApprovalsState>;
|
|
272
|
+
}
|
|
273
|
+
/** A deliberate refusal from the approvals port, written for the person who
|
|
274
|
+
* asked: its message goes on the wire as is. Recognized by `name`, not by
|
|
275
|
+
* `instanceof`, so a second copy of this module (a test alias, a bundled
|
|
276
|
+
* build) cannot turn a refusal into APPROVALS_FAILED. */
|
|
277
|
+
export declare class ApprovalsRefusal extends Error {
|
|
278
|
+
constructor(message: string);
|
|
258
279
|
}
|
|
280
|
+
export declare function isApprovalsRefusal(e: unknown): e is ApprovalsRefusal;
|
|
281
|
+
/** Team-mode approvals refusals and the fixed text for an unexpected error
|
|
282
|
+
* (Part C). Exported for the tests. */
|
|
283
|
+
export declare const APPROVALS_FAILED = "Standing approvals could not be read or changed. The daemon log has the reason.";
|
|
284
|
+
export declare const APPROVALS_NO_USER = "In team mode standing approvals need a verified user on this connection.";
|
|
285
|
+
export declare const APPROVALS_NAME_AGENT = "Name the agent: in team mode standing approvals belong to one agent, and only its owner can revoke them.";
|
|
259
286
|
/** The daemon's orchestrator checks and workspace lock, behind `checks-get`,
|
|
260
287
|
* `checks-pin` and `workspace-release`. Declared HERE for the same
|
|
261
288
|
* dependency-direction reason as `SidecarPauses`: packages/sidecar implements
|
|
@@ -276,6 +303,36 @@ export interface SidecarChecks {
|
|
|
276
303
|
release(ref: WorkspaceLockRef): Promise<boolean>;
|
|
277
304
|
unavailable?(): string | null;
|
|
278
305
|
}
|
|
306
|
+
/** Team agent access refusals (Part B). Exported for the tests. */
|
|
307
|
+
export declare const WATCH_REFUSED = "You can watch only runs you started, or unattended runs of an agent you own.";
|
|
308
|
+
export declare const ACCESS_NO_ROLE = "NO_ACCESS: you have no role on this agent, or too low a role for this.";
|
|
309
|
+
export declare const ACCESS_NOT_OWNER = "NOT_OWNER: only this agent's owner or the daemon admin can change it.";
|
|
310
|
+
export declare const ACCESS_ADMIN_ONLY = "NOT_OWNER: only the daemon admin can change the crew folder itself.";
|
|
311
|
+
export declare const ACCESS_STORE_REFUSED = "The access store is never writable.";
|
|
312
|
+
export declare const ACCESS_CHECK_FAILED = "NOT_OWNER: could not check access.";
|
|
313
|
+
export declare const ACCESS_FAILED = "Access could not be checked or changed. The daemon log has the reason.";
|
|
314
|
+
/** An uncoded peer-* failure; the detail goes to the log. One source: the peer admin port reuses it. */
|
|
315
|
+
export declare const PEER_FAILED = "Your team daemon links could not be read or changed. The daemon log has the reason.";
|
|
316
|
+
/** Team run history (spec 2026-10-01 E5.6): an uncoded failure. Fixed text; the daemon log has the detail. */
|
|
317
|
+
export declare const AGENT_RUNS_FAILED = "Team runs could not be read. The daemon log has the reason.";
|
|
318
|
+
/** Part E: a member request the member list could not answer. Fixed text; the
|
|
319
|
+
* daemon log has the detail. */
|
|
320
|
+
export declare const MEMBER_FAILED = "The member request could not be answered. The daemon log has the reason.";
|
|
321
|
+
/** A device store failure. Fixed text; the daemon log has the detail. */
|
|
322
|
+
export declare const DEVICES_FAILED = "The paired devices could not be read or changed. The daemon log has the reason.";
|
|
323
|
+
/** Part D credential refusals (exported for the tests). A refusal with no
|
|
324
|
+
* reply code of its own goes out as fixed text; the daemon log has the detail. */
|
|
325
|
+
export declare const AGENT_CRED_FAILED = "Agent credentials could not be checked or changed. The daemon log has the reason.";
|
|
326
|
+
export declare const AGENT_CRED_LOGIN_FAILED = "The sign-in did not finish. The daemon log has the reason.";
|
|
327
|
+
export declare const AGENT_CRED_SOLO = "This daemon does not keep agent access.";
|
|
328
|
+
export declare const MCP_ADMIN_ONLY = "In team mode only the daemon admin can use or change this machine's MCP servers directly.";
|
|
329
|
+
export declare const SESSION_REFUSED = "In team mode a session is reachable only by the member who created it, or the daemon admin.";
|
|
330
|
+
export declare const SNAPSHOT_REFUSED = "In team mode you can restore only from a snapshot of a session you created.";
|
|
331
|
+
export declare const SNAPSHOT_NAME_REFUSED = "In team mode a snapshot name is chosen by the daemon; only the daemon admin can name one.";
|
|
332
|
+
export declare const SNAPSHOT_USAGE_ADMIN_ONLY = "In team mode only the daemon admin can see this machine's snapshot usage.";
|
|
333
|
+
/** Team mode: a room runs its agents for the person who opens or drives it. */
|
|
334
|
+
export declare const ROOM_RUN_REFUSED = "You need contributor or higher on every agent in this room to open or drive it.";
|
|
335
|
+
export declare const OUTPUT_REFUSED = "You can see the output only of runs you started, or of unattended runs of an agent you own.";
|
|
279
336
|
/** The daemon's web-push notifier, behind `push-subscribe`/`push-unsubscribe`
|
|
280
337
|
* (spec 2026-09-24-web-push-design). Declared HERE (harness-side), not
|
|
281
338
|
* imported from `@corenel/sidecar`, for the same dependency-direction reason
|
|
@@ -371,6 +428,43 @@ export interface SidecarMcpAdmin {
|
|
|
371
428
|
removeServer(name: string): Promise<void>;
|
|
372
429
|
setCredential(name: string, header: string, value: string): Promise<void>;
|
|
373
430
|
}
|
|
431
|
+
/** A team agent's MCP bindings and its own credentials (spec 2026-10-01 Part
|
|
432
|
+
* D), behind `access-bind` and the `agent-cred-*` messages. Declared here for
|
|
433
|
+
* the dependency-direction reason above; packages/sidecar implements it
|
|
434
|
+
* (mcp/agentCreds.ts). `caller` is ALWAYS the connection's verified user.
|
|
435
|
+
* `ref` crosses unvalidated: the implementation validates it, and decides
|
|
436
|
+
* whether `caller` is the agent's owner or the daemon admin. A refusal is a
|
|
437
|
+
* thrown error carrying one of AGENT_CRED_ERROR_CODES as `code`. */
|
|
438
|
+
export interface SidecarAgentCreds {
|
|
439
|
+
bind(ref: unknown, caller: string, server: string, binding: McpBinding | null): Promise<void>;
|
|
440
|
+
setHeaders(ref: unknown, caller: string, server: string, headers: readonly unknown[]): Promise<void>;
|
|
441
|
+
login(ref: unknown, caller: string, server: string, onAuthUrl: (url: string) => void): Promise<{
|
|
442
|
+
ok: true;
|
|
443
|
+
} | {
|
|
444
|
+
ok: false;
|
|
445
|
+
reason: 'no-oauth' | 'no-dcr' | 'failed';
|
|
446
|
+
message: string;
|
|
447
|
+
}>;
|
|
448
|
+
clear(ref: unknown, caller: string, server: string): Promise<void>;
|
|
449
|
+
/** Each MCP server's binding and whether an agent credential is SET (Part E,
|
|
450
|
+
* E2). Presence only. Optional: absent, `agent-cred-status` is UNAVAILABLE. */
|
|
451
|
+
status?(ref: unknown, caller: string): Promise<AgentCredStatusRow[]>;
|
|
452
|
+
}
|
|
453
|
+
/** A member's daemon connected to this (team) daemon, serving its own MCP
|
|
454
|
+
* servers (spec 2026-10-01 Part D). `userId` is the connection's VERIFIED
|
|
455
|
+
* user, never a claim; `urls` are as advertised (the implementation
|
|
456
|
+
* normalizes them). `call` is one `mcp` host-call on that connection and
|
|
457
|
+
* rejects with a HostCallError. */
|
|
458
|
+
export interface SidecarPeerConn {
|
|
459
|
+
userId: string;
|
|
460
|
+
urls: readonly string[];
|
|
461
|
+
call(method: 'list' | 'call', args: unknown[]): Promise<unknown>;
|
|
462
|
+
}
|
|
463
|
+
/** The team daemon's peer routes (packages/sidecar peer/routes.ts). ONE
|
|
464
|
+
* instance for the process, shared by every connection. */
|
|
465
|
+
export interface SidecarPeers {
|
|
466
|
+
attach(conn: SidecarPeerConn): () => void;
|
|
467
|
+
}
|
|
374
468
|
export interface SidecarMcp {
|
|
375
469
|
/** Every connected tool, address-ready. Empty when no server is configured
|
|
376
470
|
* -- that is a normal state, not an error (mirrors `SidecarProcs.list`'s /
|
|
@@ -398,7 +492,98 @@ export interface SidecarMcp {
|
|
|
398
492
|
isError: boolean;
|
|
399
493
|
}>;
|
|
400
494
|
}
|
|
495
|
+
/** What an access check is about. The same members as packages/sidecar's
|
|
496
|
+
* access/service.ts AgentAction, restated with no import for the same
|
|
497
|
+
* dependency-direction reason as `SidecarCrewDeploy`. */
|
|
498
|
+
export type SidecarAgentAction = 'see' | 'run' | 'own-runs' | 'run-list' | 'unattended-content' | 'cancel-any' | 'write-definition' | 'manage-access' | 'manage-credentials' | 'approvals' | 'deploy';
|
|
499
|
+
/** Where a mutating fs tool call lands, when that matters to access: inside
|
|
500
|
+
* one team agent's folder (`isNew`: it has no definition and no access record
|
|
501
|
+
* yet; `whole`: the target IS the agent's folder), on a folder that contains a
|
|
502
|
+
* crew folder, or in the access store itself. */
|
|
503
|
+
export type SidecarInvokeTarget = {
|
|
504
|
+
kind: 'agent';
|
|
505
|
+
ref: CrewAgentRef;
|
|
506
|
+
isNew: boolean;
|
|
507
|
+
whole: boolean;
|
|
508
|
+
} | {
|
|
509
|
+
kind: 'crew-parent';
|
|
510
|
+
} | {
|
|
511
|
+
kind: 'access-store';
|
|
512
|
+
};
|
|
513
|
+
/** The daemon's per-agent access (team agent access, spec 2026-10-01 Part B),
|
|
514
|
+
* behind the `access-*` messages and every access gate in this class.
|
|
515
|
+
*
|
|
516
|
+
* Declared HERE with protocol types only; packages/sidecar implements it
|
|
517
|
+
* (access/port.ts) over its access service, which this package must never
|
|
518
|
+
* import. Every `caller` / `userId` handed to it is THIS connection's verified
|
|
519
|
+
* user, never a message field. */
|
|
520
|
+
export interface SidecarAccess {
|
|
521
|
+
/** --mode team. The gates in this class apply only when true. */
|
|
522
|
+
readonly teamMode: boolean;
|
|
523
|
+
/** The verified user this daemon is signed in as, now; undefined when unknown. */
|
|
524
|
+
adminId(): string | undefined;
|
|
525
|
+
can(ref: CrewAgentRef, userId: string | undefined, action: SidecarAgentAction): Promise<boolean>;
|
|
526
|
+
/** Answer one access-* request. Its ref and fields arrive unvalidated. */
|
|
527
|
+
handle(caller: string | undefined, msg: AccessRequestMsg): Promise<AccessReply>;
|
|
528
|
+
/** The agent has no definition and no access record yet: a write may claim it. */
|
|
529
|
+
isNewAgent(ref: CrewAgentRef): Promise<boolean>;
|
|
530
|
+
onAgentCreated(ref: CrewAgentRef, creator: string | undefined): Promise<void>;
|
|
531
|
+
onAgentDeleted(ref: CrewAgentRef): Promise<void>;
|
|
532
|
+
/** For a mutating fs tool invoked over the wire: what its target touches, or null. */
|
|
533
|
+
invokeTarget(tool: string, args: unknown): Promise<SidecarInvokeTarget | null>;
|
|
534
|
+
/** Team access overview (Part E, E2): one row per team agent `caller` may
|
|
535
|
+
* see. Optional: absent, `access-overview` is refused as NOT_TEAM_AGENT. */
|
|
536
|
+
overview?(caller: string | undefined): Promise<AccessOverviewRow[]>;
|
|
537
|
+
/** Admin only (owner decision 2026-10-06): deployed agents still firing from
|
|
538
|
+
* a removed member's folder. Optional: absent, the reply carries []. */
|
|
539
|
+
inactiveDeployments?(caller: string | undefined): Promise<InactiveDeployment[]>;
|
|
540
|
+
}
|
|
541
|
+
/** Linking this daemon to team daemons (spec 2026-10-01 E5.5). The port
|
|
542
|
+
* decides who may (the daemon's own signed-in account) from the caller the
|
|
543
|
+
* harness hands it, the connection's verified user. */
|
|
544
|
+
export interface SidecarPeerAdmin {
|
|
545
|
+
handle(caller: string | undefined, msg: PeerRequestMsg): Promise<PeerReply>;
|
|
546
|
+
}
|
|
547
|
+
/** Team member status (spec 2026-10-01 Part E, E1), behind the member gate,
|
|
548
|
+
* first sight and the `member-*` messages.
|
|
549
|
+
*
|
|
550
|
+
* Declared HERE with protocol types only; packages/sidecar implements it
|
|
551
|
+
* (members/port.ts). `statusOf` is SYNCHRONOUS because the gate runs on every
|
|
552
|
+
* message: the implementation answers from memory. Every userId handed to it
|
|
553
|
+
* is THIS connection's verified user, never a message field. */
|
|
554
|
+
export interface SidecarMembers {
|
|
555
|
+
/** 'active' or 'pending'. The admin is always active; an unknown or missing
|
|
556
|
+
* user reads as pending (fail closed). */
|
|
557
|
+
statusOf(userId: string | undefined): MemberStatus;
|
|
558
|
+
/** First sight: record a verified user with no record as pending and tell
|
|
559
|
+
* the admin, once per user. Never throws for a known user. */
|
|
560
|
+
noteAdmitted(userId: string, label: string): Promise<void>;
|
|
561
|
+
/** Answer one member-* request. Fields arrive unvalidated. */
|
|
562
|
+
handle(caller: string | undefined, msg: MemberRequestMsg): Promise<MemberReply>;
|
|
563
|
+
/** Status changes: a user approved ('active') or removed ('removed'). */
|
|
564
|
+
subscribe(cb: (userId: string, event: MemberStatus | 'removed') => void): () => void;
|
|
565
|
+
}
|
|
566
|
+
/** Who a verified user IS, for display (spec 2026-10-07 member names). Told
|
|
567
|
+
* the assertion's cleaned name/email once per connection, before first sight.
|
|
568
|
+
* DISPLAY ONLY: the implementation stores it; nothing here decides on it. */
|
|
569
|
+
export interface SidecarPeople {
|
|
570
|
+
note(userId: string, person: PersonInfo): Promise<void>;
|
|
571
|
+
}
|
|
572
|
+
/** How long one run-activity item may take to be decided for one team-mode
|
|
573
|
+
* connection (Task 16b fix round 1). A store that hangs must not leave a
|
|
574
|
+
* client unwelcomed or stall every later item: a timed-out item is dropped
|
|
575
|
+
* for that connection (fail closed). */
|
|
576
|
+
export declare const RUN_ACTIVITY_DECIDE_MS = 3000;
|
|
577
|
+
/** How many per-item deadlines (RUN_ACTIVITY_DECIDE_MS, or its test
|
|
578
|
+
* override) the whole pre-welcome replay may hold the welcome in team mode
|
|
579
|
+
* (final review F14). A replay of many items that each hang would otherwise
|
|
580
|
+
* hold it for one deadline per item. What is not decided by then is dropped
|
|
581
|
+
* for this connection (fail closed). */
|
|
582
|
+
export declare const WELCOME_REPLAY_DEADLINES = 3;
|
|
583
|
+
export declare const WELCOME_REPLAY_MAX_MS: number;
|
|
401
584
|
export interface SidecarServerOptions {
|
|
585
|
+
/** Overrides RUN_ACTIVITY_DECIDE_MS (tests shorten it). */
|
|
586
|
+
runActivityDecideMs?: number;
|
|
402
587
|
channel: SidecarChannel;
|
|
403
588
|
/** The daemon's device store (spec 2026-09-29-device-enrollment-design).
|
|
404
589
|
* With `sidecarKey`, the ONLY way a connection authenticates: there is no
|
|
@@ -459,6 +644,10 @@ export interface SidecarServerOptions {
|
|
|
459
644
|
* operator declined shell. Absent means no 'procs' feature is advertised and
|
|
460
645
|
* every proc message is answered with an error rather than ignored. */
|
|
461
646
|
procs?: SidecarProcs;
|
|
647
|
+
/** The daemon's local speech model, behind `stt-*`. Present only on a daemon
|
|
648
|
+
* (solo or team) whose speech runtime loaded (packages/sidecar/src/speech). Absent:
|
|
649
|
+
* no 'speech' feature, and `stt-start` is answered with an error. */
|
|
650
|
+
speech?: SidecarSpeech;
|
|
462
651
|
/** The session layer behind `session-*`. Absent means the daemon runs no
|
|
463
652
|
* sessions: it advertises no 'sessions' feature and answers every session
|
|
464
653
|
* message with an error that says so, rather than ignoring them. */
|
|
@@ -524,6 +713,25 @@ export interface SidecarServerOptions {
|
|
|
524
713
|
* operator who never configured any), and `mcp-call` is refused. */
|
|
525
714
|
mcp?: SidecarMcp;
|
|
526
715
|
mcpAdmin?: SidecarMcpAdmin;
|
|
716
|
+
/** Team agents' bindings and credentials (spec 2026-10-01 Part D). Absent:
|
|
717
|
+
* every credential message is refused as UNAVAILABLE. Not in team mode
|
|
718
|
+
* (`access` absent or solo): refused as NOT_TEAM_AGENT. */
|
|
719
|
+
agentCreds?: SidecarAgentCreds;
|
|
720
|
+
/** Peer routes (team side of peer mode, spec 2026-10-01 Part D). */
|
|
721
|
+
peers?: SidecarPeers;
|
|
722
|
+
/** Per-agent access (team agent access, Part B). Absent, or not in team mode:
|
|
723
|
+
* no 'agent-access' feature, every access-* message is refused, and no access
|
|
724
|
+
* gate applies. */
|
|
725
|
+
access?: SidecarAccess;
|
|
726
|
+
/** Team member status (Part E). Wired only in team mode. Absent: no
|
|
727
|
+
* 'team-members' feature, no gate, and member-* is refused as UNAVAILABLE. */
|
|
728
|
+
members?: SidecarMembers;
|
|
729
|
+
/** The people directory (spec 2026-10-07). Absent: names are not recorded
|
|
730
|
+
* and labels stay on device names. Wired in solo and team mode alike. */
|
|
731
|
+
people?: SidecarPeople;
|
|
732
|
+
/** Peer links (spec 2026-10-01 E5.5). Absent: no 'peer-links' feature and
|
|
733
|
+
* every peer-* request is refused. */
|
|
734
|
+
peerAdmin?: SidecarPeerAdmin;
|
|
527
735
|
/**
|
|
528
736
|
* Map an authenticated connection to the DURABLE KEY it is filed under.
|
|
529
737
|
*
|
|
@@ -612,6 +820,10 @@ export interface SidecarServerOptions {
|
|
|
612
820
|
* (default HELLO_DEADLINE_MS). A socket that never pairs holds daemon
|
|
613
821
|
* resources for nothing. */
|
|
614
822
|
helloDeadlineMs?: number;
|
|
823
|
+
/** Deadline for one host-call, in ms (daemon.json `peerCallTimeoutMs`,
|
|
824
|
+
* default DEFAULT_HOST_CALL_TIMEOUT_MS). Not applied to `confirm`/`ask`,
|
|
825
|
+
* which wait on a person. */
|
|
826
|
+
hostCallTimeoutMs?: number;
|
|
615
827
|
}
|
|
616
828
|
/** Default pre-pairing deadline: a real client sends `hello` immediately.
|
|
617
829
|
* It covers the proof exchange AND the identity exchange (IDENTITY_TIMEOUT_MS),
|
|
@@ -630,6 +842,22 @@ export declare const IDENTITY_TIMEOUT_MS = 10000;
|
|
|
630
842
|
* (`SidecarAdmission.recheckMs`) before it is closed. Generous: the client is
|
|
631
843
|
* mid-session, and a slow answer is not a refusal. */
|
|
632
844
|
export declare const RECHECK_TIMEOUT_MS = 30000;
|
|
845
|
+
/** How a host-call failed to produce the host's answer.
|
|
846
|
+
* - `undelivered`: never sent (the connection was already closed, or the send
|
|
847
|
+
* threw). Safe to try on another route.
|
|
848
|
+
* - `timeout` / `closed`: sent, then no answer. The call may have run.
|
|
849
|
+
* - `remote`: the host answered with a refusal; the message is its words. */
|
|
850
|
+
export type HostCallFailure = 'undelivered' | 'timeout' | 'closed' | 'remote';
|
|
851
|
+
export declare class HostCallError extends Error {
|
|
852
|
+
readonly kind: HostCallFailure;
|
|
853
|
+
constructor(kind: HostCallFailure, message: string);
|
|
854
|
+
}
|
|
855
|
+
/** The kind of a host-call rejection, or null for any other error. Structural
|
|
856
|
+
* rather than `instanceof`, so a caller in another package does not depend on
|
|
857
|
+
* sharing this module's copy of the class. */
|
|
858
|
+
export declare function hostCallFailure(e: unknown): HostCallFailure | null;
|
|
859
|
+
/** Default deadline for one host-call (daemon.json `peerCallTimeoutMs`). */
|
|
860
|
+
export declare const DEFAULT_HOST_CALL_TIMEOUT_MS = 60000;
|
|
633
861
|
/** How long the daemon waits for `client-proof` after its `server-proof`.
|
|
634
862
|
* The hello deadline closes an unauthenticated socket anyway; this bounds the
|
|
635
863
|
* wait inside it. */
|
|
@@ -639,6 +867,8 @@ export declare class SidecarServer {
|
|
|
639
867
|
private readonly opts;
|
|
640
868
|
private readonly tools;
|
|
641
869
|
private authed;
|
|
870
|
+
/** This connection's one live dictation stream, if any. */
|
|
871
|
+
private stt;
|
|
642
872
|
/** Denied hellos on this connection (see MAX_FAILED_HELLOS). */
|
|
643
873
|
private failedHellos;
|
|
644
874
|
/** A hello's credential is being checked (the check awaits the device
|
|
@@ -691,6 +921,8 @@ export declare class SidecarServer {
|
|
|
691
921
|
* connection on a daemon with no `identity` verifier. The token itself is
|
|
692
922
|
* never kept. */
|
|
693
923
|
private verifiedUserId;
|
|
924
|
+
/** The verified person's display name/email, set with verifiedUserId. */
|
|
925
|
+
private verifiedPerson;
|
|
694
926
|
/** The verdict echoed on the welcome, when a verifier is wired. Dead by the
|
|
695
927
|
* time a welcome is ever sent -- `onHello`'s identity block always
|
|
696
928
|
* overwrites it with a real reason ('not requested', 'no daemon id', or the
|
|
@@ -721,6 +953,24 @@ export declare class SidecarServer {
|
|
|
721
953
|
* successful `hello` when `opts.attendance` is wired. Called once, on channel
|
|
722
954
|
* close, so a dead connection stops receiving/counting toward asks. */
|
|
723
955
|
private attendedDetach?;
|
|
956
|
+
/** Detach from the peer routes, when this connection serves MCP. */
|
|
957
|
+
private peersDetach?;
|
|
958
|
+
/** This connection's hello announced PEER_DAEMON_FEATURE. Set from the
|
|
959
|
+
* claim, before anything is verified: it only ever TAKES privileges away
|
|
960
|
+
* (no attendance, no broadcasts, only PEER_DAEMON_MESSAGES served, and a
|
|
961
|
+
* welcome with no tools and no root/roots), so a client that claims it
|
|
962
|
+
* falsely only loses its own. It never lifts the member gate's welcome
|
|
963
|
+
* strip (Part E): a pending user who claims it is still told nothing. */
|
|
964
|
+
private peerDaemon;
|
|
965
|
+
/** One log line per peer connection for refused messages, not one each. */
|
|
966
|
+
private peerRefusalLogged;
|
|
967
|
+
/** The tail of this connection's run-activity filter (team agent access,
|
|
968
|
+
* Task 16b). Items are decided one at a time so a run's start, updates and
|
|
969
|
+
* settle reach the client in the order the daemon sent them, however long
|
|
970
|
+
* each one's access check takes. */
|
|
971
|
+
private runActivityChain;
|
|
972
|
+
/** Bumped when the pre-welcome replay is cut off: items queued before it are dropped. */
|
|
973
|
+
private runActivityEpoch;
|
|
724
974
|
/** The synced directory THIS connection belongs to, once resolved -- the same
|
|
725
975
|
* value echoed in `welcome.dirName`. Retained so `hosts-list` can stamp
|
|
726
976
|
* `self` and `hosts-forget` can refuse the caller's own tree from the
|
|
@@ -873,8 +1123,11 @@ export declare class SidecarServer {
|
|
|
873
1123
|
* message id, so a client correlating by id sees its own stream.
|
|
874
1124
|
*/
|
|
875
1125
|
private onSubscribe;
|
|
876
|
-
/**
|
|
877
|
-
|
|
1126
|
+
/** Attach THIS connection to `hub` as a viewer of `m.runId`, replay first. */
|
|
1127
|
+
private watchRun;
|
|
1128
|
+
/** Stop a run. Solo mode: same trust as `run`, a connection that may start
|
|
1129
|
+
* runs on this daemon may stop them. Team mode with per-agent access
|
|
1130
|
+
* (Part B): the run's requester, or its agent's owner or the admin. */
|
|
878
1131
|
private onCancelRun;
|
|
879
1132
|
/**
|
|
880
1133
|
* What this caller's agent has actually done.
|
|
@@ -947,6 +1200,15 @@ export declare class SidecarServer {
|
|
|
947
1200
|
private onApprovalsAccept;
|
|
948
1201
|
private onApprovalsList;
|
|
949
1202
|
private onApprovalsRevoke;
|
|
1203
|
+
/** Team mode: every approvals message needs the user this connection
|
|
1204
|
+
* proved, since a team agent's rules are its owner's to change and its
|
|
1205
|
+
* members' to see. Null when the message may go on to the port. Solo mode
|
|
1206
|
+
* never refuses here. */
|
|
1207
|
+
private approvalsNoUser;
|
|
1208
|
+
/** What an approvals port error puts on the wire. Solo mode: its message,
|
|
1209
|
+
* as always. Team mode: an ApprovalsRefusal's reason, and for anything else
|
|
1210
|
+
* (a path, an errno) fixed text, the detail kept in the daemon log. */
|
|
1211
|
+
private approvalsError;
|
|
950
1212
|
/** Why the checks port cannot answer right now, or null when it can. */
|
|
951
1213
|
private checksRefusal;
|
|
952
1214
|
private onChecksGet;
|
|
@@ -965,6 +1227,17 @@ export declare class SidecarServer {
|
|
|
965
1227
|
private onRoomList;
|
|
966
1228
|
private onRoomRead;
|
|
967
1229
|
private onRoomResume;
|
|
1230
|
+
/** Team agent access (Part B, final review F1): a room runs every agent in
|
|
1231
|
+
* it as the person who opens or drives it, so each one needs `run` for THIS
|
|
1232
|
+
* connection's verified user, decided by the room service where the daemon
|
|
1233
|
+
* actually finds the agent. Null when allowed. Solo mode (or no access
|
|
1234
|
+
* port): null, unchanged. No verified user, no gate on the room service, or
|
|
1235
|
+
* a throw: refused. */
|
|
1236
|
+
private roomRunRefusal;
|
|
1237
|
+
/** `roomRunRefusal` for a room that already exists, by its recorded
|
|
1238
|
+
* participants: the verbs that drive its agents (resume, answer, interject). A room
|
|
1239
|
+
* that is not there is left to the room service's own "No room" answer. */
|
|
1240
|
+
private roomDriveRefusal;
|
|
968
1241
|
/** WHO THIS CONNECTION IS, INSIDE A ROOM.
|
|
969
1242
|
*
|
|
970
1243
|
* The user its pairing JWT proved (`verifiedUserId`: API-signed, aud = this
|
|
@@ -1001,13 +1274,151 @@ export declare class SidecarServer {
|
|
|
1001
1274
|
* would have produced for the identical address.
|
|
1002
1275
|
*/
|
|
1003
1276
|
private onMcpAdmin;
|
|
1277
|
+
/** Part D credential messages. The caller is this connection's VERIFIED
|
|
1278
|
+
* user and nothing the message says; the port decides whether that user is
|
|
1279
|
+
* the agent's owner or the admin. Solo mode refuses, as `onAccess` does. The
|
|
1280
|
+
* secret in `agent-cred-set` goes to the port and is never logged or echoed.
|
|
1281
|
+
* A refusal with no reply code goes out as fixed text (Part B's
|
|
1282
|
+
* ACCESS_FAILED rule) and its detail goes to the log. */
|
|
1283
|
+
private onAgentCred;
|
|
1004
1284
|
private onMcpCall;
|
|
1285
|
+
/** One access-* request, answered for THIS connection's verified user. Solo
|
|
1286
|
+
* mode (or no port) refuses without asking. A port that throws becomes a
|
|
1287
|
+
* refusal: it must never kill the connection or leave the request unanswered. */
|
|
1288
|
+
private onAccess;
|
|
1289
|
+
/** Team mode with a member list, and this connection's verified user is not
|
|
1290
|
+
* an active member right now. Read fresh on every call. Member status
|
|
1291
|
+
* ALONE: a peer daemon connection is exempted from the request gate in
|
|
1292
|
+
* onMessage (it is served only PEER_DAEMON_MESSAGES there), never here, so
|
|
1293
|
+
* a claimed peer cannot lift the welcome strip. A port that throws reads as
|
|
1294
|
+
* pending (fail closed): it runs inside onMessage and every broadcast. */
|
|
1295
|
+
private memberPending;
|
|
1296
|
+
/** One member-* request, answered for THIS connection's verified user. A
|
|
1297
|
+
* port that throws becomes a refusal with fixed text (the detail is
|
|
1298
|
+
* logged), never a dropped connection. */
|
|
1299
|
+
private onMember;
|
|
1300
|
+
/** Team access overview (Part E, E2), for THIS connection's verified user.
|
|
1301
|
+
* Solo mode (or no port) refuses without asking, like onAccess. A coded
|
|
1302
|
+
* refusal passes its code and authored text through; any other failure goes
|
|
1303
|
+
* out as fixed text, with the detail in the log. */
|
|
1304
|
+
private onAccessOverview;
|
|
1305
|
+
/** Each MCP server's binding and credential PRESENCE for one agent (Part E,
|
|
1306
|
+
* E2). The owner or admin only, decided by the port from the verified user.
|
|
1307
|
+
* Solo mode refuses without asking, like onAgentCred. Every row is rebuilt
|
|
1308
|
+
* from its three fields here, so a port that returned more (a header, a
|
|
1309
|
+
* token) could never put it on the wire. */
|
|
1310
|
+
private onAgentCredStatus;
|
|
1311
|
+
/** Team run history (spec 2026-10-01 E5.6): viewer or higher on the agent,
|
|
1312
|
+
* for THIS connection's verified user. The ref is validated before the
|
|
1313
|
+
* access port sees it. Each row is rebuilt from its own fields here
|
|
1314
|
+
* (agentRunRowOf), so a runner that returned more (a message, a
|
|
1315
|
+
* transcript) could never put it on the wire. An uncoded failure is fixed text; the detail stays in the log. */
|
|
1316
|
+
private onAgentRuns;
|
|
1317
|
+
/** peer-* (spec 2026-10-01 E5.5), for THIS connection's verified user. A
|
|
1318
|
+
* link is rebuilt from its five fields, so a port that returned more (a
|
|
1319
|
+
* device key) could never put it on the wire. An uncoded throw is fixed
|
|
1320
|
+
* text; the detail stays in the log. */
|
|
1321
|
+
private onPeer;
|
|
1322
|
+
/** Team mode with per-agent access wired. Every Part B gate keys on this,
|
|
1323
|
+
* so solo mode takes none of the new paths. */
|
|
1324
|
+
private teamAccess;
|
|
1325
|
+
/** Who asked for a run: this process's hub record, the runner's facts, or
|
|
1326
|
+
* the run's stored record (restarts included). */
|
|
1327
|
+
private runRequester;
|
|
1328
|
+
/** May THIS connection read run `runId`'s content (watch it, read its
|
|
1329
|
+
* output)? Decision D5, in this order: a run somebody asked for is theirs
|
|
1330
|
+
* alone, the owner and the admin included; a run nobody asked for (a
|
|
1331
|
+
* schedule, a trigger) is its agent owner's and the admin's. Anything
|
|
1332
|
+
* unknown, and anything that throws, is refused. */
|
|
1333
|
+
private mayReadRun;
|
|
1334
|
+
/** One run-activity item to THIS connection. Solo mode: as is, at once.
|
|
1335
|
+
* Team mode with per-agent access: only what `runActivityFor` lets
|
|
1336
|
+
* through, decided in arrival order. */
|
|
1337
|
+
private sendRunActivity;
|
|
1338
|
+
/** The pre-welcome replay drained, or cut off at its total cap (F14): past
|
|
1339
|
+
* the cap every item still undecided is dropped for this connection, and
|
|
1340
|
+
* the welcome goes out. Never rejects. */
|
|
1341
|
+
private replayDrained;
|
|
1342
|
+
/** `runActivityFor` under a deadline: past it the item is dropped. */
|
|
1343
|
+
private runActivityDecided;
|
|
1344
|
+
/** What THIS connection may hear of one run (team agent access, Part B,
|
|
1345
|
+
* Task 16b). Nothing unless it may list the agent's runs (viewer or higher)
|
|
1346
|
+
* or asked for the run itself. The failure message and the task only when
|
|
1347
|
+
* it may read the run's content (`mayReadRun`, decision D5: the requester,
|
|
1348
|
+
* or for an unattended run the agent's owner or the admin). The agent is
|
|
1349
|
+
* the run's own recorded facts, never the names the item carries. No facts,
|
|
1350
|
+
* facts for a different agent, or any throw: nothing. What gets through says
|
|
1351
|
+
* `mine` on the requester's own connection and `attended` when a person
|
|
1352
|
+
* asked for the run (E5.1); whatever the item claimed of either is dropped,
|
|
1353
|
+
* and no user id is added. */
|
|
1354
|
+
private runActivityFor;
|
|
1355
|
+
/** Team mode: THIS connection's verified user is the daemon admin. A throw
|
|
1356
|
+
* is "no". */
|
|
1357
|
+
private isSessionAdmin;
|
|
1358
|
+
/** The ids of the sessions whose recorded VERIFIED creator is THIS
|
|
1359
|
+
* connection's verified user. Never the claimed `owner`. A session with no
|
|
1360
|
+
* recorded creator is nobody's here. May throw (the caller refuses). */
|
|
1361
|
+
private ownSessionIds;
|
|
1362
|
+
/** May THIS connection act on session `sessionId` (pause, resume, destroy,
|
|
1363
|
+
* capture, watch, run)? Team mode (Task 16c): the admin, or the session's
|
|
1364
|
+
* recorded verified creator. A session with no recorded creator is the
|
|
1365
|
+
* admin's alone. A throw refuses. */
|
|
1366
|
+
private maySession;
|
|
1367
|
+
/** The sessions THIS connection is shown. Solo mode: every one, as before.
|
|
1368
|
+
* Team mode (Task 16c): the admin sees every one, anyone else only their
|
|
1369
|
+
* own. A throw shows none. */
|
|
1370
|
+
private visibleSessions;
|
|
1371
|
+
/** Team mode (Task 16c): why THIS connection may not send `m`, or null.
|
|
1372
|
+
* `session-unwatch` stops only this connection's own watch and is never
|
|
1373
|
+
* refused; `session-snapshots` is filtered where it is answered. */
|
|
1374
|
+
private sessionRefusal;
|
|
1375
|
+
/** May THIS connection stop run `runId`? Its requester may, and so may the
|
|
1376
|
+
* agent's owner or the admin, for any run of that agent. A throw refuses. */
|
|
1377
|
+
private mayCancelRun;
|
|
1378
|
+
/** Who may do this config call on the daemon's own crew (team mode):
|
|
1379
|
+
* - read a definition (or list an agent): any role; read anything else in
|
|
1380
|
+
* an agent's folder (its runs' memory, sessions, logs): owner or admin;
|
|
1381
|
+
* - write, append or delete in an agent's folder: owner or admin, except the
|
|
1382
|
+
* first write into a NEW agent, which claims it for the writer;
|
|
1383
|
+
* - change the crew folder itself or a crew-level file: the admin.
|
|
1384
|
+
* Answers a refusal, or what to record once the call has succeeded. Anything
|
|
1385
|
+
* that cannot be decided, or throws, is a refusal. */
|
|
1386
|
+
private configGate;
|
|
1387
|
+
/** The runner's per-run decision (D5) for one run's kept words on the
|
|
1388
|
+
* daemon crew. No runner decision available, or a throw: no. */
|
|
1389
|
+
private mayReadRunContent;
|
|
1390
|
+
/** A listing without the agents this connection has no role on (team mode),
|
|
1391
|
+
* or null when that cannot be decided. Only whole agents are left out:
|
|
1392
|
+
* dropping individual entries would read as deletions to a syncing client.
|
|
1393
|
+
* The one exception is a run's session folder (`sessions/<runId>`), which
|
|
1394
|
+
* is run content: only the runs this user may read are listed (D5). */
|
|
1395
|
+
private visibleConfigEntries;
|
|
1396
|
+
/** After a config write or delete went through: record a new agent's owner,
|
|
1397
|
+
* or drop a deleted agent's record. Never fails the call that succeeded. */
|
|
1398
|
+
private afterConfigChange;
|
|
1399
|
+
/** Why THIS connection may not run a mutating tool on `target`, or null.
|
|
1400
|
+
* The first write into a new agent claims it, which needs a verified user;
|
|
1401
|
+
* a delete never claims, so it goes through the ordinary check. */
|
|
1402
|
+
private invokeRefusal;
|
|
1403
|
+
/** Team mode: the daemon's MCP servers and credentials are the admin's
|
|
1404
|
+
* (Part B). Null when THIS connection may use or change them. Unknown admin
|
|
1405
|
+
* and any throw while deciding are refusals. */
|
|
1406
|
+
private mcpRefusal;
|
|
1005
1407
|
private onRoomFindings;
|
|
1006
1408
|
private onRoomFindingEdit;
|
|
1007
1409
|
/** One config-channel call. The allowlist is NOT applied here -- it is the
|
|
1008
1410
|
* service's, daemon-side, where the filesystem is -- so this stays a router
|
|
1009
1411
|
* and there is exactly one place a path is checked. */
|
|
1010
1412
|
private onConfig;
|
|
1413
|
+
/** The config path as the filesystem would reach it, for classification:
|
|
1414
|
+
* separators, `.`, empty and `..` segments resolved; the `crew` segment, the
|
|
1415
|
+
* agent folder (to its on-disk name, read from the service's own listing of
|
|
1416
|
+
* `crew`) and a definition file name matched case-insensitively, since the
|
|
1417
|
+
* filesystem under the state dir may be case-insensitive. Null means "cannot
|
|
1418
|
+
* be told" (two case variants exist and none is exact): the caller refuses.
|
|
1419
|
+
* A listing that throws propagates, and the caller refuses. A path outside
|
|
1420
|
+
* the crew comes back as is. */
|
|
1421
|
+
private canonicalConfigPath;
|
|
1011
1422
|
private onHostSyncPut;
|
|
1012
1423
|
private onHostSyncDelete;
|
|
1013
1424
|
/** A ToolContext whose capabilities proxy back to the host (persist-nothing).
|
|
@@ -1027,4 +1438,7 @@ export declare class SidecarServer {
|
|
|
1027
1438
|
private readonly confirm;
|
|
1028
1439
|
private readonly ask;
|
|
1029
1440
|
}
|
|
1441
|
+
/** Whether `user` is the daemon admin `admin`. Both must be non-empty
|
|
1442
|
+
* strings: an unknown admin, or an empty id on either side, is never a match. */
|
|
1443
|
+
export declare function sameAdmin(user: string | undefined, admin: string | undefined): boolean;
|
|
1030
1444
|
//# sourceMappingURL=server.d.ts.map
|