agent-relay-server 0.62.2 → 0.63.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/docs/openapi.json +1 -1
- package/package.json +2 -2
- package/public/assets/{MessageBubble-DRrxfjyT.js → MessageBubble-Cl6ufPHw.js} +2 -2
- package/public/assets/MessageBubble-Cl6ufPHw.js.map +1 -0
- package/public/assets/{PlanGraphPanel-Dp2eYazz.js → PlanGraphPanel-BnfjmkQ8.js} +2 -2
- package/public/assets/{PlanGraphPanel-Dp2eYazz.js.map → PlanGraphPanel-BnfjmkQ8.js.map} +1 -1
- package/public/assets/{activity--t0U2yzq.js → activity-aFxvGLtd.js} +2 -2
- package/public/assets/{activity--t0U2yzq.js.map → activity-aFxvGLtd.js.map} +1 -1
- package/public/assets/{agent-profiles-BMtJYzxn.js → agent-profiles-B4mleUDz.js} +2 -2
- package/public/assets/{agent-profiles-BMtJYzxn.js.map → agent-profiles-B4mleUDz.js.map} +1 -1
- package/public/assets/{agents-Ck9AePlc.js → agents-DW5djToQ.js} +2 -2
- package/public/assets/{agents-Ck9AePlc.js.map → agents-DW5djToQ.js.map} +1 -1
- package/public/assets/{analytics-CzfK387L.js → analytics-CRi6thtg.js} +2 -2
- package/public/assets/{analytics-CzfK387L.js.map → analytics-CRi6thtg.js.map} +1 -1
- package/public/assets/{automation-Cgw8vtE8.js → automation-Do4OpauI.js} +2 -2
- package/public/assets/{automation-Cgw8vtE8.js.map → automation-Do4OpauI.js.map} +1 -1
- package/public/assets/{branch-state-badge-DnEEPtOP.js → branch-state-badge-D3W3w7zz.js} +2 -2
- package/public/assets/{branch-state-badge-DnEEPtOP.js.map → branch-state-badge-D3W3w7zz.js.map} +1 -1
- package/public/assets/{channels-Dc3L2MQs.js → channels-BytdR9NS.js} +2 -2
- package/public/assets/{channels-Dc3L2MQs.js.map → channels-BytdR9NS.js.map} +1 -1
- package/public/assets/{chat-Fc6iJ7sa.js → chat-CvaQ2czL.js} +2 -2
- package/public/assets/{chat-Fc6iJ7sa.js.map → chat-CvaQ2czL.js.map} +1 -1
- package/public/assets/{connectors-Dc2ttGWs.js → connectors-BLQDp8Bc.js} +2 -2
- package/public/assets/{connectors-Dc2ttGWs.js.map → connectors-BLQDp8Bc.js.map} +1 -1
- package/public/assets/{display-DzNvOu1j.js → display-B06I5sqa.js} +3 -3
- package/public/assets/display-B06I5sqa.js.map +1 -0
- package/public/assets/{formatted-body-impl-Bg-gx7rG.js → formatted-body-impl-0Lf8e1Ic.js} +2 -2
- package/public/assets/{formatted-body-impl-Bg-gx7rG.js.map → formatted-body-impl-0Lf8e1Ic.js.map} +1 -1
- package/public/assets/{index-BeDncjN4.js → index-C3su8ezq.js} +6 -6
- package/public/assets/{index-BeDncjN4.js.map → index-C3su8ezq.js.map} +1 -1
- package/public/assets/{insights-c08aW-7n.js → insights-64uExH1E.js} +2 -2
- package/public/assets/{insights-c08aW-7n.js.map → insights-64uExH1E.js.map} +1 -1
- package/public/assets/{integrations-BwpgcqnF.js → integrations-HyC1EaIp.js} +2 -2
- package/public/assets/{integrations-BwpgcqnF.js.map → integrations-HyC1EaIp.js.map} +1 -1
- package/public/assets/{maintenance-CTKP0kWB.js → maintenance-EVBpKH07.js} +2 -2
- package/public/assets/{maintenance-CTKP0kWB.js.map → maintenance-EVBpKH07.js.map} +1 -1
- package/public/assets/{managed-agents-BofCxo8d.js → managed-agents-BLZPxGuw.js} +2 -2
- package/public/assets/{managed-agents-BofCxo8d.js.map → managed-agents-BLZPxGuw.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-CQ-6BIb8.js → markdown-preview-impl-Bg6rCWYN.js} +2 -2
- package/public/assets/{markdown-preview-impl-CQ-6BIb8.js.map → markdown-preview-impl-Bg6rCWYN.js.map} +1 -1
- package/public/assets/{memory-DvfXjMoi.js → memory-Bjr8bgjj.js} +2 -2
- package/public/assets/{memory-DvfXjMoi.js.map → memory-Bjr8bgjj.js.map} +1 -1
- package/public/assets/{messages-C9VsPzZ_.js → messages-CRYw1F4z.js} +2 -2
- package/public/assets/{messages-C9VsPzZ_.js.map → messages-CRYw1F4z.js.map} +1 -1
- package/public/assets/{orchestrators-MffVueeE.js → orchestrators-D-co1vdp.js} +2 -2
- package/public/assets/{orchestrators-MffVueeE.js.map → orchestrators-D-co1vdp.js.map} +1 -1
- package/public/assets/{overview-BSVajefM.js → overview-Ddy5czri.js} +2 -2
- package/public/assets/{overview-BSVajefM.js.map → overview-Ddy5czri.js.map} +1 -1
- package/public/assets/{pairs-B5711-Cs.js → pairs-CFVM8uHL.js} +2 -2
- package/public/assets/{pairs-B5711-Cs.js.map → pairs-CFVM8uHL.js.map} +1 -1
- package/public/assets/{security-DkUwK9Vj.js → security-Df4_76bh.js} +2 -2
- package/public/assets/{security-DkUwK9Vj.js.map → security-Df4_76bh.js.map} +1 -1
- package/public/assets/{select-DrM2RRiT.js → select-Cq3BBnL9.js} +2 -2
- package/public/assets/{select-DrM2RRiT.js.map → select-Cq3BBnL9.js.map} +1 -1
- package/public/assets/{settings-DdKCb-vy.js → settings-DOLEYXZL.js} +2 -2
- package/public/assets/{settings-DdKCb-vy.js.map → settings-DOLEYXZL.js.map} +1 -1
- package/public/assets/{store-iTiheuTD.js → store-C1E8jmNE.js} +4 -4
- package/public/assets/store-C1E8jmNE.js.map +1 -0
- package/public/assets/{tasks-e1y1PFfO.js → tasks-BcsmPi9_.js} +2 -2
- package/public/assets/{tasks-e1y1PFfO.js.map → tasks-BcsmPi9_.js.map} +1 -1
- package/public/assets/{teams-BUcxoGC_.js → teams-BQrV3eKI.js} +2 -2
- package/public/assets/{teams-BUcxoGC_.js.map → teams-BQrV3eKI.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-CmZjQOB2.js → terminal-viewer-impl-Dle04qpH.js} +2 -2
- package/public/assets/{terminal-viewer-impl-CmZjQOB2.js.map → terminal-viewer-impl-Dle04qpH.js.map} +1 -1
- package/public/assets/{work-queue-CXBQx43n.js → work-queue-BLhTLg4o.js} +2 -2
- package/public/assets/{work-queue-CXBQx43n.js.map → work-queue-BLhTLg4o.js.map} +1 -1
- package/public/assets/{workspaces-D2EfZh9a.js → workspaces-4NCNTmRQ.js} +3 -3
- package/public/assets/{workspaces-D2EfZh9a.js.map → workspaces-4NCNTmRQ.js.map} +1 -1
- package/public/index.html +3 -3
- package/scripts/orchestrator-spawn-smoke.ts +87 -67
- package/src/agent-ref.ts +8 -6
- package/src/automations/constants.ts +12 -0
- package/src/automations/cron.ts +129 -0
- package/src/automations/crud.ts +84 -0
- package/src/automations/dispatch.ts +275 -0
- package/src/automations/index.ts +5 -0
- package/src/automations/reconcile.ts +245 -0
- package/src/automations/storage.ts +181 -0
- package/src/automations/types.ts +16 -0
- package/src/automations/validation.ts +140 -0
- package/src/automations.ts +1 -1045
- package/src/db/activity.ts +1 -1
- package/src/db/agent-predicates.ts +9 -0
- package/src/db/agent-search.ts +2 -2
- package/src/db/agents.ts +13 -41
- package/src/db/artifacts.ts +8 -8
- package/src/db/channel-identity.ts +38 -0
- package/src/db/channels.ts +37 -61
- package/src/db/continuation-archives.ts +4 -4
- package/src/db/delivery.ts +75 -30
- package/src/db/inbox.ts +1 -1
- package/src/db/integrations.ts +4 -4
- package/src/db/issue-lifecycle.ts +6 -6
- package/src/db/mappers.ts +1 -2
- package/src/db/merge-lease.ts +3 -3
- package/src/db/message-claims.ts +16 -0
- package/src/db/message-queries.ts +8 -0
- package/src/db/message-reads.ts +157 -18
- package/src/db/messages.ts +23 -48
- package/src/db/notification-subscriptions.ts +2 -2
- package/src/db/orchestrators.ts +4 -4
- package/src/db/pair-maintenance.ts +9 -0
- package/src/db/pairs.ts +10 -18
- package/src/db/plans.ts +1 -1
- package/src/db/policy-runtime.ts +14 -0
- package/src/db/project-entries.ts +1 -1
- package/src/db/projects.ts +2 -2
- package/src/db/shared.ts +7 -0
- package/src/db/stats.ts +2 -2
- package/src/db/task-core.ts +18 -0
- package/src/db/task-maintenance.ts +24 -0
- package/src/db/tasks.ts +5 -17
- package/src/db/teams.ts +3 -3
- package/src/db/workspaces.ts +6 -6
- package/src/issue-tracker/github.ts +3 -3
- package/src/maintenance/constants.ts +35 -0
- package/src/maintenance/events.ts +32 -0
- package/src/maintenance/index.ts +7 -0
- package/src/maintenance/jobs.ts +340 -0
- package/src/maintenance/orphaned-sessions.ts +86 -0
- package/src/maintenance/scheduler.ts +231 -0
- package/src/maintenance/teams.ts +65 -0
- package/src/maintenance/types.ts +31 -0
- package/src/maintenance/workspaces.ts +251 -0
- package/src/maintenance.ts +1 -1099
- package/src/mcp/identity.ts +131 -0
- package/src/mcp/index.ts +208 -0
- package/src/mcp/tools-messaging.ts +459 -0
- package/src/mcp/tools-spawn.ts +145 -0
- package/src/mcp/tools-workspace.ts +227 -0
- package/src/mcp/types.ts +24 -0
- package/src/mcp/validation.ts +104 -0
- package/src/mcp.ts +1 -1319
- package/src/notification-router.ts +2 -2
- package/src/notification-rules.ts +2 -2
- package/src/project-ingest.ts +3 -3
- package/src/project-instructions.ts +1 -1
- package/src/provider-config-store.ts +3 -3
- package/src/provider-state.ts +1 -1
- package/src/reviewer-pipeline.ts +1 -1
- package/src/self-resume.ts +3 -7
- package/src/services/agent-action.ts +2 -2
- package/src/services/issue-activity.ts +0 -4
- package/src/services/issue-associations.ts +2 -2
- package/src/services/issue-lifecycle.ts +7 -7
- package/src/services/managed-running.ts +1 -1
- package/src/services/parity-harness.ts +3 -3
- package/src/services/plan-graph.ts +3 -3
- package/src/services/send-message.ts +16 -12
- package/src/services/shutdown-agent.ts +2 -2
- package/src/services/team-templates.ts +2 -2
- package/src/services/team.ts +2 -2
- package/src/settings/modules.ts +1 -1
- package/src/settings/registry.ts +3 -3
- package/src/spawn-command.ts +1 -1
- package/src/sse.ts +0 -4
- package/src/workspace-actions.ts +1 -1
- package/src/workspace-probe.ts +3 -7
- package/public/assets/MessageBubble-DRrxfjyT.js.map +0 -1
- package/public/assets/display-DzNvOu1j.js.map +0 -1
- package/public/assets/store-iTiheuTD.js.map +0 -1
|
@@ -57,7 +57,7 @@ export interface NotificationScope {
|
|
|
57
57
|
paths?: string[];
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
interface NotificationMessage {
|
|
61
61
|
subject?: string;
|
|
62
62
|
body: string;
|
|
63
63
|
payload?: Record<string, unknown>;
|
|
@@ -67,7 +67,7 @@ export interface NotificationMessage {
|
|
|
67
67
|
replyExpected?: boolean;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
interface RouteNotificationInput {
|
|
71
71
|
type: NotificationType;
|
|
72
72
|
scope: NotificationScope;
|
|
73
73
|
/**
|
|
@@ -33,7 +33,7 @@ export interface NotificationRule {
|
|
|
33
33
|
evaluate(agent: AgentCard, ctx: NotificationRuleContext): RuleDecision;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
interface AudienceMember {
|
|
37
37
|
agentId: string;
|
|
38
38
|
/** The rule whose decision was decisive (last non-abstain wins) — carried for explainability (#446). */
|
|
39
39
|
matchedRule: string;
|
|
@@ -161,7 +161,7 @@ export function setSubscriptionRules(rules: NotificationRule[]): void {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/** The effective ordered rule list for a type: its registered defaults, then subscription overrides. */
|
|
164
|
-
|
|
164
|
+
function audienceRulesFor(type: NotificationType): NotificationRule[] {
|
|
165
165
|
const defaults = audienceRegistry.get(type);
|
|
166
166
|
if (!defaults) return [];
|
|
167
167
|
return subscriptionRules.length === 0 ? defaults : [...defaults, ...subscriptionRules];
|
package/src/project-ingest.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { ProjectEntry } from "./types";
|
|
|
16
16
|
|
|
17
17
|
const INGEST_FILENAME = "CLAUDE.md";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
interface ParsedSection {
|
|
20
20
|
/** Heading text (the entry title). For pre-heading preamble content: "(preamble)". */
|
|
21
21
|
title: string;
|
|
22
22
|
/** Section body — lines under the heading up to the next heading, trimmed. May be "". */
|
|
@@ -25,14 +25,14 @@ export interface ParsedSection {
|
|
|
25
25
|
anchor: string;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
interface IngestRootResult {
|
|
29
29
|
rootPath: string;
|
|
30
30
|
filePath: string;
|
|
31
31
|
found: boolean;
|
|
32
32
|
sections: number;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
interface IngestResult {
|
|
36
36
|
projectId: string;
|
|
37
37
|
created: number;
|
|
38
38
|
updated: number;
|
|
@@ -31,7 +31,7 @@ export interface ProjectInstructionPolicy {
|
|
|
31
31
|
policy?: ProjectInstructionPolicyName;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
interface ComposeProjectInstructionsOptions {
|
|
35
35
|
/** Named policy selecting the included source set. Default `all`. */
|
|
36
36
|
policy?: ProjectInstructionPolicyName;
|
|
37
37
|
/** Explicit source set; overrides `policy` when given (the low-level lever). */
|
|
@@ -24,15 +24,15 @@ export const VALID_PROVIDER_CONFIGS = SPAWN_PROVIDERS;
|
|
|
24
24
|
type ProviderConfigProvider = string;
|
|
25
25
|
type ProviderConfigEntry = ConfigEntry<ProviderConfig>;
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
function defaultProviderConfigHost(): string {
|
|
28
28
|
return hostname();
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
function providerConfigKey(host: string, provider: string): string {
|
|
32
32
|
return `${normalizeProviderConfigHost(host)}/${normalizeProviderConfigProvider(provider)}`;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
function parseProviderConfigKey(key: string): { host: string; provider: ProviderConfigProvider } | null {
|
|
36
36
|
const slash = key.lastIndexOf("/");
|
|
37
37
|
if (slash <= 0 || slash === key.length - 1) return null;
|
|
38
38
|
const host = cleanString(key.slice(0, slash), "host", { required: true, max: 120 })!;
|
package/src/provider-state.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { isRecord } from "agent-relay-sdk";
|
|
|
6
6
|
// the transient-agent reaper (don't reap a held agent), and the rate-limit
|
|
7
7
|
// resume sweep. The dashboard has its own client-side copy in display.ts.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
interface ProviderStateView {
|
|
10
10
|
state: string;
|
|
11
11
|
reason?: string;
|
|
12
12
|
label?: string;
|
package/src/reviewer-pipeline.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { Command, WorkspaceMergePreview, WorkspaceRecord } from "./types";
|
|
|
9
9
|
|
|
10
10
|
type ReviewDecision = "APPROVED" | "CHANGES_REQUESTED" | "REVIEW_REQUIRED";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
function parsePrNumber(prUrl: string | undefined): number | undefined {
|
|
13
13
|
if (!prUrl) return undefined;
|
|
14
14
|
const match = prUrl.match(/\/pull\/(\d+)(?:\D|$)/);
|
|
15
15
|
if (!match) return undefined;
|
package/src/self-resume.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { emitRelayEvent } from "./events";
|
|
|
14
14
|
import { routeNotification } from "./notification-router";
|
|
15
15
|
import type { AgentCard, Command, ContinuationEnvelope, ContinuationLedgerEntry, SelfResumeMode } from "./types";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
interface CompactAndResumeInput {
|
|
18
18
|
agentId: string;
|
|
19
19
|
workingState: string;
|
|
20
20
|
ruledOut?: unknown;
|
|
@@ -22,7 +22,7 @@ export interface CompactAndResumeInput {
|
|
|
22
22
|
objective?: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
interface CompactAndResumeResult {
|
|
26
26
|
ok: boolean;
|
|
27
27
|
mode: SelfResumeMode;
|
|
28
28
|
envelope: ContinuationEnvelope;
|
|
@@ -110,7 +110,7 @@ export function enqueueContinuationInjectionAfterClear(command: Command): Comman
|
|
|
110
110
|
return inject;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
function renderContinuation(envelope: ContinuationEnvelope): string {
|
|
114
114
|
const ledger = envelope.ledger.length
|
|
115
115
|
? envelope.ledger.map((entry) => `- gen ${entry.gen} @ ${new Date(entry.at).toISOString()}: ${entry.ruledOut}${entry.why ? `; why: ${entry.why}` : ""}`).join("\n")
|
|
116
116
|
: "- none";
|
|
@@ -231,7 +231,3 @@ function ledgerEntry(ruledOut: string, why: string, generation: number, now: num
|
|
|
231
231
|
if (!cleaned) throw new ValidationError("ruledOut entries cannot be blank");
|
|
232
232
|
return { gen: generation, ruledOut: cleaned, why, at: now };
|
|
233
233
|
}
|
|
234
|
-
|
|
235
|
-
export function continuationForAgent(agentId: string): ContinuationEnvelope | null {
|
|
236
|
-
return getContinuationEnvelope(agentId);
|
|
237
|
-
}
|
|
@@ -8,7 +8,7 @@ import type { AgentCard, Command } from "../types";
|
|
|
8
8
|
|
|
9
9
|
export type AgentAction = "compact" | "clearContext" | "inject";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface AgentActionInput {
|
|
12
12
|
agentId: string;
|
|
13
13
|
action: AgentAction;
|
|
14
14
|
message?: string;
|
|
@@ -16,7 +16,7 @@ export interface AgentActionInput {
|
|
|
16
16
|
requestedBy?: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
interface AgentActionResult {
|
|
20
20
|
action: AgentAction;
|
|
21
21
|
command: Command;
|
|
22
22
|
}
|
|
@@ -24,7 +24,3 @@ export function recordAndEmitIssueActivity(input: RecordIssueActivityInput) {
|
|
|
24
24
|
emitActivityEvent(event);
|
|
25
25
|
return event;
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
export function resolveIssueActivityMapping(input: { issueRefId?: string; issueRef?: string; defaultRepo?: string; provider?: IssueProvider }) {
|
|
29
|
-
return resolveIssueActivityRef(input);
|
|
30
|
-
}
|
|
@@ -8,7 +8,7 @@ import { getIssueRef, resolveIssueRefByExternalKey, resolveIssueRefFromString }
|
|
|
8
8
|
import type { IssueAssociationEntityType, IssueAssociationIssue, IssueProvider } from "../types";
|
|
9
9
|
import { ValidationError } from "../db/connection";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface ResolveAssociationIssueInput {
|
|
12
12
|
issueRefId?: string;
|
|
13
13
|
ref?: string;
|
|
14
14
|
defaultRepo?: string;
|
|
@@ -19,7 +19,7 @@ export interface ResolveAssociationIssueInput {
|
|
|
19
19
|
title?: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
interface AssociateIssueInput extends ResolveAssociationIssueInput {
|
|
23
23
|
entityType: IssueAssociationEntityType;
|
|
24
24
|
entityId: string;
|
|
25
25
|
}
|
|
@@ -17,7 +17,7 @@ type LifecycleWorkspace = Pick<WorkspaceRecord, "id" | "repoRoot" | "branch" | "
|
|
|
17
17
|
type AdapterResolver = (ref: IssueRef) => IssueTrackerAdapter;
|
|
18
18
|
type LogFn = (message: string) => void;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
interface LandedIssueLifecycleInput {
|
|
21
21
|
workspace: LifecycleWorkspace;
|
|
22
22
|
mergedSha?: string;
|
|
23
23
|
subject?: string;
|
|
@@ -31,7 +31,7 @@ export interface LandedIssueLifecycleInput {
|
|
|
31
31
|
prLand?: boolean;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
interface ReopenIssueLifecycleInput {
|
|
35
35
|
issueRefId?: string;
|
|
36
36
|
ref?: string;
|
|
37
37
|
defaultRepo?: string;
|
|
@@ -46,19 +46,19 @@ export interface ReopenIssueLifecycleInput {
|
|
|
46
46
|
entityId?: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
interface IssueLifecycleOptions {
|
|
50
50
|
adapterResolver?: AdapterResolver;
|
|
51
51
|
log?: LogFn;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
type LandIssueRefSource = "association" | "commit" | "backlink";
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
type CloseIssueLifecycleResult =
|
|
57
57
|
| { issueRef: IssueRef; action: "closed"; source: LandIssueRefSource; landKey: string }
|
|
58
58
|
| { issueRef: IssueRef; action: "skipped"; reason: "already-closed" | "already-processed"; landKey: string }
|
|
59
59
|
| { issueRef: IssueRef; action: "failed"; error: string; landKey: string };
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
type ReopenIssueLifecycleResult =
|
|
62
62
|
| { issueRef: IssueRef; action: "reopened"; landKey: string }
|
|
63
63
|
| { issueRef: IssueRef; action: "skipped"; reason: "already-open"; landKey: string }
|
|
64
64
|
| { issueRef: IssueRef; action: "failed"; error: string; landKey: string };
|
|
@@ -210,7 +210,7 @@ export function parseBacklinkIssueRefs(text: string | undefined, fallbackDefault
|
|
|
210
210
|
return issueRefMap(refs);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
function resolveIssueRefsForLand(input: LandedIssueLifecycleInput): { source: LandIssueRefSource; refs: IssueRef[] } {
|
|
214
214
|
const associated = associatedIssueRefs(input.workspace);
|
|
215
215
|
if (associated.length > 0) return { source: "association", refs: associated };
|
|
216
216
|
const fallbackDefaultRepo = landDefaultRepo(input.workspace);
|
|
@@ -19,7 +19,7 @@ import { emitMessageAvailable, emitMessageDeliveryUpdated, emitNewMessage } from
|
|
|
19
19
|
import type { AuthContext } from "./auth-context";
|
|
20
20
|
import type { ManagedAgentState } from "../types";
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
interface ManagedRunningInput {
|
|
23
23
|
policyName?: string;
|
|
24
24
|
spawnRequestId?: string;
|
|
25
25
|
agentId: string;
|
|
@@ -15,7 +15,7 @@ import { subscribeRelayEvents } from "../events";
|
|
|
15
15
|
/** An emitted relay event, normalized to the fields parity compares — volatile
|
|
16
16
|
* `seq`/`timestamp` are deliberately dropped so only behavior, not ordering noise,
|
|
17
17
|
* is asserted. */
|
|
18
|
-
|
|
18
|
+
interface CapturedEvent {
|
|
19
19
|
type: string;
|
|
20
20
|
source: string;
|
|
21
21
|
subject?: string;
|
|
@@ -36,7 +36,7 @@ export interface Capture<S> {
|
|
|
36
36
|
* settled so the harness can snapshot. Keep the abstraction swappable: a later slice
|
|
37
37
|
* can replace a direct-call transport with an end-to-end HTTP one without reshaping
|
|
38
38
|
* the harness. */
|
|
39
|
-
|
|
39
|
+
interface ParityTransport<C> {
|
|
40
40
|
id: string;
|
|
41
41
|
invoke(ctx: C): Promise<void>;
|
|
42
42
|
}
|
|
@@ -57,7 +57,7 @@ export interface ParityOp<C, S> {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/** Drive one transport in isolation and capture everything it produced. */
|
|
60
|
-
|
|
60
|
+
async function captureTransport<C, S>(
|
|
61
61
|
op: ParityOp<C, S>,
|
|
62
62
|
transportId: string,
|
|
63
63
|
ctx: C,
|
|
@@ -9,7 +9,7 @@ import type { AgentCard, Plan, PlanEdge, PlanNode, PlanOwnerRef, PlanStatus } fr
|
|
|
9
9
|
|
|
10
10
|
export const PLAN_STATUSES = ["pending", "in-progress", "landed", "blocked"] as const;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
interface PlanNodeInput {
|
|
13
13
|
id?: unknown;
|
|
14
14
|
label?: unknown;
|
|
15
15
|
scopeBlurb?: unknown;
|
|
@@ -21,7 +21,7 @@ export interface PlanNodeInput {
|
|
|
21
21
|
blackboardRefs?: unknown;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
interface PlanNodePatch {
|
|
25
25
|
label?: unknown;
|
|
26
26
|
scopeBlurb?: unknown;
|
|
27
27
|
ownerRef?: unknown;
|
|
@@ -32,7 +32,7 @@ export interface PlanNodePatch {
|
|
|
32
32
|
blackboardRefs?: unknown;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
interface PlanCreateInput {
|
|
36
36
|
threadId: unknown;
|
|
37
37
|
teamId?: unknown;
|
|
38
38
|
channel?: unknown;
|
|
@@ -22,7 +22,14 @@
|
|
|
22
22
|
// OUT OF SCOPE (transport-edge, excluded from the parity facet): automatic memory injection
|
|
23
23
|
// (needs request-derived context) and per-transport audit (HTTP domain row vs MCP tool-call row).
|
|
24
24
|
import { isMechanicalMessageKind, isRecord, isReservedAgentId } from "agent-relay-sdk";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
ValidationError,
|
|
27
|
+
getMessage,
|
|
28
|
+
listAgents,
|
|
29
|
+
sendMessageWithResult,
|
|
30
|
+
channelObligationAnsweredBy,
|
|
31
|
+
spawnObligationAnsweredBy,
|
|
32
|
+
} from "../db";
|
|
26
33
|
import { planSend, type DeliveryReceipt } from "../agent-ref";
|
|
27
34
|
import { emitMessageQueued, emitNewMessage } from "../sse";
|
|
28
35
|
import { getLifecycleManager } from "../lifecycle-manager";
|
|
@@ -32,14 +39,14 @@ import type { AuthContext } from "./auth-context";
|
|
|
32
39
|
import type { IntegrationTokenConfig } from "../config";
|
|
33
40
|
import type { Message, SendMessageInput } from "../types";
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
interface SendMessageResult {
|
|
36
43
|
message: Message;
|
|
37
44
|
created: boolean;
|
|
38
45
|
/** Synchronous delivery receipt (live recipients / queued / store-ahead). */
|
|
39
46
|
receipt: DeliveryReceipt;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
interface SendMessageOptions {
|
|
43
50
|
/** The integration token when the MCP caller authenticated with one. AuthContext stays lean
|
|
44
51
|
* (foundation contract) — the integration-specific target policy rides here, not on the ctx. */
|
|
45
52
|
integration?: IntegrationTokenConfig | null;
|
|
@@ -159,16 +166,13 @@ export function sendMessageService(
|
|
|
159
166
|
// Resolve BEFORE authorize so both run against the canonical id (kills the HTTP-authorizes-raw
|
|
160
167
|
// vs MCP-authorizes-resolved drift).
|
|
161
168
|
const receipt = resolveSendTarget(input, input.from);
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
// exactly ONE open obligation on that channel this send is unambiguously the answer — link it here,
|
|
167
|
-
// at send time, so the obligation clears with no extra message. (`channelObligationAnsweredBy` is a
|
|
168
|
-
// no-op unless `to` resolved to a channel agent with a single open obligation; deciding at send time
|
|
169
|
-
// — not query time — keeps a later sibling conversation from retroactively mis-attributing it.)
|
|
169
|
+
// Reply-obligation linking: some real answers are ordinary sends without replyTo/thread linkage.
|
|
170
|
+
// Channel bridge replies and spawn report-backs both have a single unambiguous open obligation case;
|
|
171
|
+
// link those at send time so the obligation clears with one message and the Stop hook does not nag
|
|
172
|
+
// the agent into a redundant `/reply`.
|
|
170
173
|
if (!input.replyTo && !isMechanicalMessageKind(input.kind)) {
|
|
171
|
-
const answered = channelObligationAnsweredBy(input.from, input.to)
|
|
174
|
+
const answered = channelObligationAnsweredBy(input.from, input.to)
|
|
175
|
+
?? spawnObligationAnsweredBy(input.from, input.to);
|
|
172
176
|
if (answered !== null) input.replyTo = answered;
|
|
173
177
|
}
|
|
174
178
|
authorizeSend(input, ctx, opts, reservedSink);
|
|
@@ -50,7 +50,7 @@ export class ShutdownTargetError extends Error {}
|
|
|
50
50
|
|
|
51
51
|
type OnlineOrchestrator = NonNullable<ReturnType<typeof getOrchestrator>>;
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
interface ShutdownAgentInput {
|
|
54
54
|
agentId?: string;
|
|
55
55
|
policyName?: string;
|
|
56
56
|
spawnRequestId?: string;
|
|
@@ -69,7 +69,7 @@ export interface ShutdownAgentInput {
|
|
|
69
69
|
auditMetadata?: Record<string, unknown>;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
interface ShutdownAgentResult {
|
|
73
73
|
command: Command;
|
|
74
74
|
orchestratorId: string;
|
|
75
75
|
agent: AgentCard | null;
|
|
@@ -8,7 +8,7 @@ import { setCallerTeamBrief } from "./team";
|
|
|
8
8
|
import { spawnAgent, type SpawnAgentInput, type SpawnAgentResult } from "./spawn-agent";
|
|
9
9
|
import type { AgentLifecycle, SpawnApprovalMode, SpawnProvider, TeamTemplate, TeamTemplateCompositionEntry, WorkspaceMode } from "../types";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface TeamTemplateInstantiateInput {
|
|
12
12
|
slug: string;
|
|
13
13
|
orchestratorId?: unknown;
|
|
14
14
|
cwd?: unknown;
|
|
@@ -19,7 +19,7 @@ export interface TeamTemplateInstantiateInput {
|
|
|
19
19
|
waitForRegistrationMs?: unknown;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
interface TeamTemplateInstantiateResult {
|
|
23
23
|
template: TeamTemplate;
|
|
24
24
|
team: ReturnType<typeof setCallerTeamBrief>["team"];
|
|
25
25
|
spawned: SpawnAgentResult[];
|
package/src/services/team.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { Team } from "../types";
|
|
|
7
7
|
export class TeamAuthError extends Error {}
|
|
8
8
|
export class TeamNotFoundError extends Error {}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface TeamPayload {
|
|
11
11
|
team: Team;
|
|
12
12
|
roster: ReturnType<typeof getTeamRoster>;
|
|
13
13
|
brief: string | null;
|
|
@@ -16,7 +16,7 @@ export interface TeamPayload {
|
|
|
16
16
|
issues: ReturnType<typeof listIssueRefsForEntity>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
interface TeamBriefInput {
|
|
20
20
|
title?: string;
|
|
21
21
|
brief?: string;
|
|
22
22
|
definitionOfDone?: string;
|
package/src/settings/modules.ts
CHANGED
package/src/settings/registry.ts
CHANGED
|
@@ -41,7 +41,7 @@ const ajv = new Ajv({ allErrors: true, strict: false });
|
|
|
41
41
|
* The registry resolves any omitted read/write scope to the fail-closed admin
|
|
42
42
|
* default and returns a fully-populated `SettingDescriptor`.
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
type SettingRegistration<T = unknown> = Omit<SettingDescriptor<T>, "scope"> & {
|
|
45
45
|
scope?: Partial<SettingScope>;
|
|
46
46
|
};
|
|
47
47
|
|
|
@@ -236,7 +236,7 @@ const PROVIDER_REASONING_CAPTURE_SCHEMA: JSONSchema = {
|
|
|
236
236
|
};
|
|
237
237
|
|
|
238
238
|
export const PROVIDER_CONFIG_NAMESPACE = "provider-config";
|
|
239
|
-
|
|
239
|
+
const PROVIDER_CONFIG_SCHEMA: JSONSchema = {
|
|
240
240
|
type: "object",
|
|
241
241
|
additionalProperties: false,
|
|
242
242
|
required: [
|
|
@@ -280,7 +280,7 @@ let seeded = false;
|
|
|
280
280
|
* called lazily by the read accessors). #386 adds module-contributed descriptors
|
|
281
281
|
* on top via `registerSetting`.
|
|
282
282
|
*/
|
|
283
|
-
|
|
283
|
+
function seedBuiltInSettings(): void {
|
|
284
284
|
if (seeded) return;
|
|
285
285
|
seeded = true;
|
|
286
286
|
|
package/src/spawn-command.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { ValidationError } from "./db";
|
|
|
7
7
|
import { effectiveProviderCatalogList } from "./provider-catalog-store";
|
|
8
8
|
|
|
9
9
|
/** Resolved provider/model/effort triple — the output shape of every model-resolution wrapper. */
|
|
10
|
-
|
|
10
|
+
interface SpawnModelParams {
|
|
11
11
|
model?: string;
|
|
12
12
|
providerModel?: string;
|
|
13
13
|
effort?: string;
|
package/src/sse.ts
CHANGED
|
@@ -198,10 +198,6 @@ export function emitOrchestratorStatus(orchestratorId: string) {
|
|
|
198
198
|
emitRelayEvent({ type: "orchestrator.status", source: "server", subject: orchestratorId, data: data as unknown as Record<string, unknown> });
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
export function emitOrchestratorRemoved(orchestratorId: string) {
|
|
202
|
-
emitRelayEvent({ type: "orchestrator.removed", source: "server", subject: orchestratorId, data: { id: orchestratorId } });
|
|
203
|
-
}
|
|
204
|
-
|
|
205
201
|
export function emitPoolBindingChanged(bindingId: string, channelId: string, previousAgentId: string | null, newAgentId: string | null) {
|
|
206
202
|
emitRelayEvent({ type: "channel.pool.changed", source: "server", subject: bindingId, data: { bindingId, channelId, previousAgentId, newAgentId, at: Date.now() } });
|
|
207
203
|
}
|
package/src/workspace-actions.ts
CHANGED
|
@@ -310,7 +310,7 @@ export function buildWorkspaceCleanupCommand(
|
|
|
310
310
|
|
|
311
311
|
// Build a `workspace.deps-refresh` command for a worktree's owning orchestrator
|
|
312
312
|
// (issue #51). checkOnly just reports staleness. Same owner-resolution as cleanup.
|
|
313
|
-
|
|
313
|
+
function buildWorkspaceDepsRefreshCommand(
|
|
314
314
|
workspace: WorkspaceRecord,
|
|
315
315
|
requestedBy: string,
|
|
316
316
|
checkOnly: boolean,
|
package/src/workspace-probe.ts
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
// Both funnel the "apply the host's ahead/dirty counts to the row + emit on flip"
|
|
10
10
|
// rule through `applyBranchFreshness` so it can't drift between the two surfaces.
|
|
11
11
|
|
|
12
|
-
import { isAbsolute, relative, resolve } from "node:path";
|
|
13
12
|
import { RELAY_TOKEN_HEADER } from "agent-relay-sdk";
|
|
14
13
|
import {
|
|
15
14
|
emitWorkspaceChange,
|
|
@@ -17,16 +16,13 @@ import {
|
|
|
17
16
|
ownedIsolatedWorkspace,
|
|
18
17
|
patchWorkspaceMetadata,
|
|
19
18
|
} from "./db";
|
|
19
|
+
import { isPathWithinBase } from "./utils";
|
|
20
20
|
import { deriveBranchState } from "./workspace-phase";
|
|
21
21
|
import type { AgentCard, WorkspaceMergePreview, WorkspaceRecord } from "./types";
|
|
22
22
|
|
|
23
23
|
/** True when `path` is the base dir itself or nested inside it (containment via
|
|
24
24
|
* resolve+relative, never string startsWith — see CLAUDE.md path-containment rule). */
|
|
25
|
-
export
|
|
26
|
-
if (!path || !baseDir) return false;
|
|
27
|
-
const rel = relative(resolve(baseDir), resolve(path));
|
|
28
|
-
return rel === "" || (!!rel && !rel.startsWith("..") && !isAbsolute(rel));
|
|
29
|
-
}
|
|
25
|
+
export const workspacePathWithinBase = isPathWithinBase;
|
|
30
26
|
|
|
31
27
|
/** Ask the owning host whether a worktree can still merge cleanly (+ ahead/dirty/PR
|
|
32
28
|
* state). Returns null on any transport/host failure — callers skip rather than act
|
|
@@ -75,7 +71,7 @@ export function applyBranchFreshness(
|
|
|
75
71
|
return false;
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
|
|
74
|
+
interface ProbeResult {
|
|
79
75
|
/** True when the host preview came back and freshness was applied. */
|
|
80
76
|
probed: boolean;
|
|
81
77
|
/** True when the derived branch-state badge flipped (⚪↔🟡). */
|