@agent-compose/sdk 0.8.5 → 0.8.7
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/README.md +213 -189
- package/dist/agent/agent-context.d.ts +3 -3
- package/dist/agent/agent-loop.d.ts +6 -5
- package/dist/agent/perf-sampler.d.ts +27 -2
- package/dist/agent/run-agent.d.ts +1 -1
- package/dist/client.d.ts +119 -54
- package/dist/directives.d.ts +3 -3
- package/dist/display.d.ts +7 -0
- package/dist/errors.d.ts +1 -1
- package/dist/generated/agentc-commands.d.ts +34 -0
- package/dist/index.d.ts +12 -12
- package/dist/index.js +771 -204
- package/dist/request-context/request-context.d.ts +1 -1
- package/dist/runtimes/_cli-agent.d.ts +185 -68
- package/dist/runtimes/_reported-model.d.ts +16 -0
- package/dist/runtimes/claude-code.d.ts +60 -1
- package/dist/runtimes/claude.d.ts +1 -1
- package/dist/runtimes/codex.d.ts +94 -6
- package/dist/runtimes/codex.mid-turn-hook.test.d.ts +10 -0
- package/dist/runtimes/model-report.test.d.ts +14 -0
- package/dist/runtimes/openai-desktop.js +741 -200
- package/dist/runtimes/opencode.d.ts +48 -11
- package/dist/runtimes/opencode.test.d.ts +14 -0
- package/dist/sandbox/baked-clis.d.ts +75 -0
- package/dist/sandbox/exec-stream.d.ts +1 -2
- package/dist/sandbox/network-policy.d.ts +23 -5
- package/dist/sandbox.d.ts +4 -2
- package/dist/step-invocation/protocol.d.ts +3 -4
- package/dist/step-invocation/server.d.ts +2 -2
- package/dist/step-invocation/types.d.ts +1 -1
- package/dist/types/api-conversations.d.ts +442 -29
- package/dist/types/api-factory.d.ts +99 -10
- package/dist/types/api-projects.d.ts +521 -0
- package/dist/types/api-runs.d.ts +83 -0
- package/dist/types/api-scopes.d.ts +32 -3
- package/dist/types/conversation-stream.d.ts +5 -0
- package/dist/types/execution-context.d.ts +1 -1
- package/dist/types/protocol.d.ts +86 -2
- package/dist/types/runtime.d.ts +9 -2
- package/dist/types/workflow-metadata.d.ts +2 -4
- package/dist/types/workflow-plan.d.ts +1 -3
- package/dist/utils/bundler.d.ts +23 -0
- package/dist/workflow-steps/observability.d.ts +2 -3
- package/dist/workflow-steps/runner.d.ts +5 -8
- package/dist/workflow-steps/types.d.ts +8 -10
- package/dist/workflow-steps/workflow.d.ts +2 -1
- package/dist/workflows/engine.d.ts +3 -5
- package/dist/workflows/invoke-child.d.ts +2 -2
- package/package.json +2 -2
- package/src/agent/agent-context.ts +168 -125
- package/src/agent/agent-loop.ts +7 -6
- package/src/agent/perf-sampler.ts +54 -3
- package/src/agent/run-agent.ts +1 -1
- package/src/client.ts +226 -71
- package/src/directives.ts +3 -3
- package/src/display.ts +12 -0
- package/src/errors.ts +1 -0
- package/src/generated/agentc-commands.ts +571 -0
- package/src/index.ts +57 -21
- package/src/pause/pause-core.ts +2 -1
- package/src/request-context/request-context.ts +1 -1
- package/src/runtimes/_cli-agent.ts +318 -122
- package/src/runtimes/_reported-model.ts +24 -0
- package/src/runtimes/claude-code.ts +195 -12
- package/src/runtimes/claude.ts +9 -2
- package/src/runtimes/codex.ts +188 -19
- package/src/runtimes/opencode.ts +195 -26
- package/src/sandbox/baked-clis.ts +86 -0
- package/src/sandbox/exec-stream.ts +1 -2
- package/src/sandbox/network-policy.ts +51 -7
- package/src/sandbox/providers/e2b.ts +3 -3
- package/src/sandbox/providers/vercel.ts +6 -6
- package/src/sandbox.ts +8 -2
- package/src/step-invocation/invoker.ts +2 -6
- package/src/step-invocation/protocol.ts +3 -4
- package/src/step-invocation/server.ts +2 -2
- package/src/types/api-conversations.ts +366 -23
- package/src/types/api-factory.ts +95 -10
- package/src/types/api-projects.ts +477 -0
- package/src/types/api-runs.ts +73 -0
- package/src/types/api-scopes.ts +32 -3
- package/src/types/conversation-stream.ts +5 -0
- package/src/types/execution-context.ts +1 -1
- package/src/types/protocol.ts +91 -2
- package/src/types/runtime.ts +8 -2
- package/src/types/sandbox-environment.ts +1 -2
- package/src/types/workflow-metadata.ts +2 -4
- package/src/types/workflow-plan.ts +1 -3
- package/src/utils/bundler.ts +88 -19
- package/src/workflow-steps/observability.ts +2 -3
- package/src/workflow-steps/runner.ts +5 -8
- package/src/workflow-steps/types.ts +8 -10
- package/src/workflow-steps/workflow.ts +2 -1
- package/src/workflows/engine.ts +3 -5
- package/src/workflows/invoke-child.ts +2 -2
- package/dist/generated/verb-synopsis.d.ts +0 -34
- package/dist/pause/__tests__/errors.test.d.ts +0 -1
- package/dist/pause/__tests__/wrappers.test.d.ts +0 -1
- package/dist/step-invocation/__tests__/protocol.test.d.ts +0 -1
- package/src/generated/verb-synopsis.ts +0 -544
|
@@ -47,8 +47,32 @@ export const PERF_PROBE_WINDOW_SECONDS = 2;
|
|
|
47
47
|
/** The standalone probe's output line leads with this prefix. */
|
|
48
48
|
export const PERF_PROBE_LINE_PREFIX = "perf ";
|
|
49
49
|
|
|
50
|
-
/** Longest token the parsers accept — anything bigger is garbage.
|
|
51
|
-
|
|
50
|
+
/** Longest token the parsers accept — anything bigger is garbage. The
|
|
51
|
+
* `top` field (three process names of up to 20 chars with their RSS) is
|
|
52
|
+
* what moved this up from 200. */
|
|
53
|
+
export const PERF_TOKEN_MAX_CHARS = 320;
|
|
54
|
+
|
|
55
|
+
/** THE TOP PROCESSES BY RESIDENT MEMORY ("why was it at 99%?", the
|
|
56
|
+
* 2026-10-03 flight incident: a 4 vCPU / 8 GB machine sat at 99% memory
|
|
57
|
+
* for twelve minutes and nothing recorded what held it): at most this many
|
|
58
|
+
* entries ride the token, name and resident MB each. A machine fact, read
|
|
59
|
+
* by the same /proc burst; never a judgment. */
|
|
60
|
+
export const PERF_TOP_PROCESSES = 3;
|
|
61
|
+
/** A process name as the token carries it: `comm`, sanitized on the guest
|
|
62
|
+
* to this alphabet and length, so it can ride a comma-separated token. */
|
|
63
|
+
export const PERF_TOP_NAME_MAX = 20;
|
|
64
|
+
const TOP_NAME_RE = /^[A-Za-z0-9._-]{1,20}$/;
|
|
65
|
+
/** A process resident set the clamp believes, in MB (a 64 GB machine is
|
|
66
|
+
* past every sandbox we run). */
|
|
67
|
+
const TOP_RSS_MAX_MB = 65_536;
|
|
68
|
+
|
|
69
|
+
/** One process by resident memory. */
|
|
70
|
+
export interface GuestTopProcess {
|
|
71
|
+
/** Its `comm` (the executable's short name), sanitized. */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Resident set in MB, whole. */
|
|
74
|
+
rssMb: number;
|
|
75
|
+
}
|
|
52
76
|
|
|
53
77
|
/** One clamped guest perf sample. Null fields = unreadable/absent on the
|
|
54
78
|
* guest — never zero-filled (a zero is a claim; null is honesty). */
|
|
@@ -67,6 +91,9 @@ export interface GuestPerfSample {
|
|
|
67
91
|
ramMb: number | null;
|
|
68
92
|
/** Guest clock at sample time, epoch seconds. Dedupe only. */
|
|
69
93
|
sampledAtS: number | null;
|
|
94
|
+
/** The processes holding the most memory, biggest first (`top`); null
|
|
95
|
+
* when the guest did not report them (an older image, no `ps`). */
|
|
96
|
+
topProcesses: GuestTopProcess[] | null;
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
export interface PerfSamplerPaths {
|
|
@@ -113,7 +140,13 @@ function perfReadFunctionFragment(procRoot: string, diskPath: string): string {
|
|
|
113
140
|
+ `if [ "\${ac_pmt:-0}" -gt 0 ] && [ -n "\${ac_pma:-}" ]; then ac_pmem=$(( 100 * (ac_pmt - ac_pma) / ac_pmt )); fi; `
|
|
114
141
|
+ `[ "$ac_pmem" -gt 100 ] && ac_pmem=100; [ "$ac_pmem" -lt -1 ] && ac_pmem=-1; `
|
|
115
142
|
+ `ac_pdsk=$(df -kP ${disk} 2>/dev/null | awk 'NR==2 && $2>0 {print int(100*$3/$2)}'); `
|
|
116
|
-
|
|
143
|
+
// The top processes by resident memory (the "why 99%?" fact): three
|
|
144
|
+
// `comm` names with their RSS in MB, each name sanitized to the token's
|
|
145
|
+
// alphabet, `;`-joined so the field stays one comma-free word. A guest
|
|
146
|
+
// whose `ps` lacks `--sort` (not procps) prints nothing and the field is
|
|
147
|
+
// absent — the parser reads that as "not reported", never as zero.
|
|
148
|
+
+ `ac_ptop=$(ps -eo rss=,comm= --sort=-rss 2>/dev/null | head -${PERF_TOP_PROCESSES} | awk '{ n=$2; gsub(/[^A-Za-z0-9._-]/, "_", n); if (length(n) > ${PERF_TOP_NAME_MAX}) n=substr(n, 1, ${PERF_TOP_NAME_MAX}); if (n == "") n="_"; printf "%s%s:%d", (NR > 1 ? ";" : ""), n, int($1 / 1024) }' 2>/dev/null); `
|
|
149
|
+
+ `ac_tok="v=1,cpu=$ac_pcpu,l1=\${ac_pl1:--1},mem=$ac_pmem,dsk=\${ac_pdsk:--1},vc=\${ac_pvc:-0},ram=$(( \${ac_pmt:-0} / 1024 )),ts=$(date +%s)\${ac_ptop:+,top=$ac_ptop}"; `
|
|
117
150
|
+ `}; `;
|
|
118
151
|
}
|
|
119
152
|
|
|
@@ -184,12 +217,30 @@ export function parsePerfToken(token: string): GuestPerfSample | null {
|
|
|
184
217
|
ramMb: bounded("ram", 1, 16 * 1024 * 1024),
|
|
185
218
|
// Bounded to [2020, 2100) in epoch seconds — dedupe-grade only.
|
|
186
219
|
sampledAtS: bounded("ts", 1_577_836_800, 4_102_444_800),
|
|
220
|
+
topProcesses: parseTopProcesses(kv.get("top")),
|
|
187
221
|
};
|
|
188
222
|
if (sample.cpuBusyPct === null && sample.load1 === null
|
|
189
223
|
&& sample.memUsedPct === null && sample.diskUsedPct === null) return null;
|
|
190
224
|
return sample;
|
|
191
225
|
}
|
|
192
226
|
|
|
227
|
+
/** The `top` field, clamped entry by entry: a name outside the alphabet or
|
|
228
|
+
* an RSS outside [0, 64 GB] drops THAT entry; more than the cap is cut;
|
|
229
|
+
* an absent or empty field is null (not reported). */
|
|
230
|
+
export function parseTopProcesses(raw: string | undefined): GuestTopProcess[] | null {
|
|
231
|
+
if (raw === undefined || raw.length === 0) return null;
|
|
232
|
+
const out: GuestTopProcess[] = [];
|
|
233
|
+
for (const entry of raw.split(";").slice(0, PERF_TOP_PROCESSES)) {
|
|
234
|
+
const i = entry.lastIndexOf(":");
|
|
235
|
+
if (i <= 0) continue;
|
|
236
|
+
const name = entry.slice(0, i);
|
|
237
|
+
const rssMb = Number(entry.slice(i + 1));
|
|
238
|
+
if (!TOP_NAME_RE.test(name) || !Number.isInteger(rssMb) || rssMb < 0 || rssMb > TOP_RSS_MAX_MB) continue;
|
|
239
|
+
out.push({ name, rssMb });
|
|
240
|
+
}
|
|
241
|
+
return out.length > 0 ? out : null;
|
|
242
|
+
}
|
|
243
|
+
|
|
193
244
|
/** Parse the standalone probe's stdout (the LAST `perf ` line wins — envd
|
|
194
245
|
* occasionally prepends shell noise). */
|
|
195
246
|
export function parsePerfProbeOutput(stdout: string): GuestPerfSample | null {
|
package/src/agent/run-agent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* agent — canonical entry point for embedding an LLM agent inside a
|
|
3
|
-
* workflow.
|
|
3
|
+
* workflow. A step's `run()` body calls it; the loop executes
|
|
4
4
|
* against the runner's own VM.
|
|
5
5
|
*
|
|
6
6
|
* Glue packaged so workflows don't duplicate it:
|
package/src/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConversationRow, CreateChatInput, ChannelIvyState,
|
|
1
|
+
import type { ConversationRow, CreateChatInput, ChannelIvyState, DriveSharesView, IvyConnectionsView, ListingPage } from "./types/api-conversations.js";
|
|
2
2
|
/**
|
|
3
3
|
* AgentComposeClient — HTTP client for the agent-compose server API.
|
|
4
4
|
*
|
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
RequestAgentPauseOptions, RequestAgentPauseResponse,
|
|
26
26
|
SendAgentMessageOptions, SendAgentMessageResponse,
|
|
27
27
|
RunDetail, RunListEntry, ListRunsOptions, TimelineEvent, RunFundingResponse, RunStepUsageResponse, EventRow, ReportEventInput,
|
|
28
|
+
ListWorkflowActivityOptions, ListWorkflowRunsOptions, WorkflowActivityPage, WorkflowRunsPage, WorkflowActivityHead, WorkflowActivityRun,
|
|
28
29
|
ListEventsOptions, ListEventsResult, RunArtifactRow, RunLogLine, ListRunLogsOptions,
|
|
29
30
|
CancelRunResponse, ListSnapshotsOptions, SnapshotListResponse, SnapshotListEntry, RunSnapshotEntry,
|
|
30
31
|
} from "./types/api-runs.js";
|
|
@@ -34,11 +35,12 @@ import type {
|
|
|
34
35
|
CreateCloudSessionInput, CloudSessionCreated,
|
|
35
36
|
SessionPreview, PreviewOpened, OpenPreviewInput, SessionForked, BackgroundWorkHeld,
|
|
36
37
|
BackgroundWorkChildDecl, BackgroundWorkStatus, MachineUpsizeOutcome,
|
|
37
|
-
|
|
38
|
+
CreateSessionWaitInput, SessionWait, SessionWaitCreated, SessionWaitList,
|
|
39
|
+
SessionChangeSet, SessionFilePlane, SessionMergeGated, SessionMergeReport, SessionDiscardReport,
|
|
38
40
|
SessionChangePreflight, SessionRebaseReport,
|
|
39
41
|
ReviewSuggestionInput, ReviewNotesPublished, ReviewGitCredential,
|
|
40
42
|
SendConversationMessageInput, SendConversationMessageResult,
|
|
41
|
-
ChannelSessionRow, ChannelSessionsResponse,
|
|
43
|
+
ChannelSessionRow, ChannelSessionsResponse,
|
|
42
44
|
SessionDirectMessageSent, BranchClaimGranted, BranchClaimsReleased, BranchClaimState,
|
|
43
45
|
ConversationPresenceSnapshot, StreamConversationOptions, AgentListRow,
|
|
44
46
|
SessionPerfHistoryPage,
|
|
@@ -48,9 +50,9 @@ import type {
|
|
|
48
50
|
SetScopeGrantsInput, SetTemplateScopeInput,
|
|
49
51
|
} from "./types/api-scopes.js";
|
|
50
52
|
import type {
|
|
51
|
-
Project, ProjectsPage, ProjectRole, ProjectMember,
|
|
52
|
-
ProjectObjectsPage, ProjectAddPreview,
|
|
53
|
-
AddProjectObjectInput, AddProjectObjectResult, RefreshProjectObjectResult,
|
|
53
|
+
Project, ProjectUpdate, ProjectsPage, ProjectRole, ProjectMember,
|
|
54
|
+
ProjectObject, ProjectObjectsPage, ProjectObjectCounts, ProjectAddPreview,
|
|
55
|
+
AddProjectObjectInput, AddProjectObjectResult, RefreshProjectObjectResult, ProjectStatus, ThreadStatus, MeStatus,
|
|
54
56
|
} from "./types/api-projects.js";
|
|
55
57
|
import type {
|
|
56
58
|
RegisterResult, RegisterWorkflowInput, TemplateRow, TemplateDetail, ListTemplatesOptions,
|
|
@@ -58,7 +60,7 @@ import type {
|
|
|
58
60
|
FactoryFileListRow, ListFactoryFilesOptions, FactoryFileListPage, FactoryFileConflict, FactoryFileConflictList, ProjectSecretMeta, ProjectSecretList,
|
|
59
61
|
FactoryRow, CreateFactoryInput, UpdateFactoryInput, FactoryPerfSummary,
|
|
60
62
|
ScheduleRow, CreateScheduleInput,
|
|
61
|
-
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultCatalogEntry,
|
|
63
|
+
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultKeyShape, VaultCatalogEntry, RequestedVaultEntry, VaultCardHint,
|
|
62
64
|
CreateApiKeyInput, ApiKey, ApiKeyCreated, ListApiKeysOptions, ApiKeyPage, UsageResponse,
|
|
63
65
|
DriveRepoLink, CreateDriveRepoLinkInput, CreateNativeRepoInput, CreateNativeRepoResult,
|
|
64
66
|
DriveMountSession, CreateDriveMountSessionInput,
|
|
@@ -80,6 +82,8 @@ export type {
|
|
|
80
82
|
ResumePauseOptions, RequestAgentPauseOptions, AnswerSteerOptions, RequestAgentPauseResponse,
|
|
81
83
|
SendAgentMessageOptions, SendAgentMessageResponse,
|
|
82
84
|
RunDetail, RunListEntry, ListRunsOptions, TimelineEvent,
|
|
85
|
+
RunStartedBy, WorkflowActivityRun, WorkflowActivityHead, ListWorkflowActivityOptions, ListWorkflowRunsOptions,
|
|
86
|
+
WorkflowActivityPage, WorkflowRunsPage,
|
|
83
87
|
FundingLane, RunFundingStamp, RunFundingUsageRow, RunFundingResponse,
|
|
84
88
|
RunStepUsage, RunStepUsageResponse,
|
|
85
89
|
EventSubjectType, EventRow, RunArtifactRow, ReportEventInput, ListEventsOptions, ListEventsResult,
|
|
@@ -88,20 +92,25 @@ export type {
|
|
|
88
92
|
} from "./types/api-runs.js";
|
|
89
93
|
export type {
|
|
90
94
|
TeamMember, Mention, CreateMentionsInput,
|
|
91
|
-
CreateChatInput, ChannelIvyState,
|
|
92
|
-
|
|
95
|
+
CreateChatInput, ChannelIvyState, IvyConnection, HiddenIvyConnection, IvyConnectionsView, IvyConnectionScope, ListingPage,
|
|
96
|
+
DriveShareItem, DriveShare, HiddenDriveShare, DriveSharesView,
|
|
97
|
+
WorkspaceConnection, WorkspaceConnectionAudienceEntry, WorkspaceConnectionsScopeView,
|
|
98
|
+
ConversationMessagePart, ConversationRow, ConversationProject, ConversationMessageRow,
|
|
93
99
|
ConversationsPage, SessionsPage, ConversationDetail,
|
|
94
100
|
CreateCloudSessionInput, CloudSessionCreated, ConversationThread,
|
|
101
|
+
ConversationUnreadSummary, ConversationUnreadThreads, ConversationReadInput, ConversationReadResult,
|
|
95
102
|
SessionPreview, PreviewOpened, OpenPreviewInput, SessionForked, BackgroundWorkHeld,
|
|
96
103
|
BackgroundWorkChildDecl, BackgroundWorkStatus, MachineUpsizeOutcome,
|
|
104
|
+
SessionWaitKind, SessionWaitState, CreateSessionWaitInput, SessionWait, SessionWaitCheck, SessionWaitCheckResult, SessionWaitCheckReview, SessionWaitCreated, SessionWaitList,
|
|
97
105
|
SessionFileChange, SessionChangeSet, SessionChangeStats, SessionDiffReviewBound, ReviewSuggestion,
|
|
106
|
+
SessionFileHold, SessionFilePlane,
|
|
98
107
|
ReviewSuggestionInput, ReviewNotesPublished, ReviewGitCredential, SessionReviewDocument,
|
|
99
108
|
ReviewSuggestionDecision, ReviewSuggestionDecisions,
|
|
100
109
|
SessionMergeReportDetail, SessionMergeReport, SessionMergeGated, SessionDiscardReport,
|
|
101
110
|
SessionPreflightFileRow, SessionChangePreflight, SessionRebaseReport,
|
|
102
111
|
ConversationPageContext, SendConversationMessageInput, ConversationTurnState,
|
|
103
112
|
SendConversationMessageResult, UnnotifiedMention, ConversationPresenceSnapshot, AgentListRow, StreamConversationOptions,
|
|
104
|
-
ChannelSessionStatus, ChannelSessionRow,
|
|
113
|
+
ChannelSessionStatus, ChannelSessionRow, ChannelWorkerFacts, ChannelSessionsResponse,
|
|
105
114
|
SessionDirectMessageSent, BranchClaimInfo, BranchClaimGranted, BranchClaimsReleased, BranchClaimState,
|
|
106
115
|
SessionPerfBucket, SessionPerfHistoryPage,
|
|
107
116
|
} from "./types/api-conversations.js";
|
|
@@ -111,10 +120,15 @@ export type {
|
|
|
111
120
|
RunContext, SetScopeGrantsInput, SetTemplateScopeInput,
|
|
112
121
|
} from "./types/api-scopes.js";
|
|
113
122
|
export type {
|
|
114
|
-
Project, ProjectsPage, ProjectRole, ProjectMember,
|
|
115
|
-
ProjectObject, ProjectObjectsPage, ProjectSkippedFile, ProjectPreviewFile,
|
|
123
|
+
Project, ProjectUpdate, ProjectsPage, ProjectRole, ProjectMember,
|
|
124
|
+
ProjectObject, ProjectObjectsPage, ProjectObjectCounts, ProjectSkippedFile, ProjectPreviewFile,
|
|
116
125
|
ProjectAddPreview, AddProjectObjectInput, AddProjectObjectResult,
|
|
117
126
|
RefreshProjectObjectResult,
|
|
127
|
+
ProjectStatus, ProjectStatusThread, ProjectStatusTask, ProjectStatusPerson, ProjectStatusWorker, ProjectStatusActivity,
|
|
128
|
+
ProjectStatusActivityKind, ProjectStatusWaitingOn, ProjectStatusWaitingCount, ProjectStatusCounts,
|
|
129
|
+
ThreadStatus, ThreadStatusWorker, ThreadStatusWorkerState, ThreadStatusWorkerEffort, WorkerFunding, ThreadStatusTodo, ThreadStatusDirector, ThreadStatusOutput, ThreadStatusEvent, ChatWork, ChatWorkThread,
|
|
130
|
+
ThreadStatusWaitingOn, ThreadStatusAssignee, ThreadStatusTodoActivity, ChatTodoPatch, ChatTodoComment,
|
|
131
|
+
MeStatus, MeStatusCounts,
|
|
118
132
|
} from "./types/api-projects.js";
|
|
119
133
|
export type {
|
|
120
134
|
RegisterResult, RegisteredRuntime, RuntimeSourceInput, TemplateSourceRef, RegisterWorkflowInput,
|
|
@@ -124,7 +138,7 @@ export type {
|
|
|
124
138
|
PublicFileLinkState,
|
|
125
139
|
FactoryRow, CreateFactoryInput, UpdateFactoryInput, FactoryPerfSummary,
|
|
126
140
|
ScheduleRow, CreateScheduleInput,
|
|
127
|
-
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultCatalogEntry,
|
|
141
|
+
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultKeyShape, VaultCatalogEntry, RequestedVaultEntry, VaultCardHint,
|
|
128
142
|
CreateApiKeyInput, ApiKey, ApiKeyCreated, ListApiKeysOptions, ApiKeyPage,
|
|
129
143
|
UsageRollupRow, UsageResponse,
|
|
130
144
|
DriveRepoLink, CreateDriveRepoLinkInput, CreateNativeRepoInput, CreateNativeRepoResult,
|
|
@@ -157,6 +171,16 @@ function detectAmbientParentRunId(): string | null {
|
|
|
157
171
|
* URL-encoded as defense-in-depth: today's server-side patterns
|
|
158
172
|
* (`^[a-z][a-z0-9-]*$`) can't produce reserved characters, but a future
|
|
159
173
|
* relaxation would otherwise quietly become an injection vector. */
|
|
174
|
+
/** The query string of one page of a scope listing (`cursor`: the previous
|
|
175
|
+
* page's `nextCursor`; `limit`: 1..200). Empty for the first page at the
|
|
176
|
+
* server's size. */
|
|
177
|
+
function listingPageQuery(page: ListingPage = {}): string {
|
|
178
|
+
const q = new URLSearchParams();
|
|
179
|
+
if (page.cursor) q.set("cursor", page.cursor);
|
|
180
|
+
if (page.limit !== undefined) q.set("limit", String(page.limit));
|
|
181
|
+
return q.toString() ? `?${q}` : "";
|
|
182
|
+
}
|
|
183
|
+
|
|
160
184
|
function templatePath(factorySlug: string, ...rest: string[]): string {
|
|
161
185
|
const tail = rest.length > 0
|
|
162
186
|
? "/" + rest.map(encodeURIComponent).join("/")
|
|
@@ -660,6 +684,38 @@ export class AgentComposeClient {
|
|
|
660
684
|
return body.workflows;
|
|
661
685
|
}
|
|
662
686
|
|
|
687
|
+
/** A space's workflow activity: one stack per workflow of the space's own
|
|
688
|
+
* that has run there in the last 90 days — or, with `q`, that has a run
|
|
689
|
+
* matching the search, however old — the most recently run first, each
|
|
690
|
+
* with its latest (matching) run and what started it. The platform's
|
|
691
|
+
* default workflows (dynamic-task, repo-ingest, …) are left out, the
|
|
692
|
+
* search included. Paged by `cursor`. */
|
|
693
|
+
async listWorkflowActivity(opts: ListWorkflowActivityOptions = {}): Promise<WorkflowActivityPage> {
|
|
694
|
+
const q = new URLSearchParams();
|
|
695
|
+
if (opts.limit !== undefined) q.set("limit", String(opts.limit));
|
|
696
|
+
if (opts.cursor) q.set("cursor", opts.cursor);
|
|
697
|
+
if (opts.q) q.set("q", opts.q);
|
|
698
|
+
const slug = encodeURIComponent(opts.factorySlug ?? "default");
|
|
699
|
+
const body = await this.fetch<{ workflows: WorkflowActivityHead[]; has_more: boolean; next_cursor: string | null }>(
|
|
700
|
+
`/api/v1/factories/${slug}/workflow-activity${q.toString() ? `?${q}` : ""}`);
|
|
701
|
+
return { workflows: body.workflows, hasMore: body.has_more, nextCursor: body.next_cursor };
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/** One workflow's runs in a space, newest first, by its exact registered
|
|
705
|
+
* name (`listRuns`' `workflow` is a substring match): the last 90 days,
|
|
706
|
+
* or with `q` every run matching the search; a platform default's name
|
|
707
|
+
* answers with no runs. Paged by `cursor`. */
|
|
708
|
+
async listWorkflowRuns(opts: ListWorkflowRunsOptions): Promise<WorkflowRunsPage> {
|
|
709
|
+
const q = new URLSearchParams({ workflow: opts.workflow });
|
|
710
|
+
if (opts.limit !== undefined) q.set("limit", String(opts.limit));
|
|
711
|
+
if (opts.cursor) q.set("cursor", opts.cursor);
|
|
712
|
+
if (opts.q) q.set("q", opts.q);
|
|
713
|
+
const slug = encodeURIComponent(opts.factorySlug ?? "default");
|
|
714
|
+
const body = await this.fetch<{ runs: WorkflowActivityRun[]; has_more: boolean; next_cursor: string | null }>(
|
|
715
|
+
`/api/v1/factories/${slug}/workflow-activity/runs?${q}`);
|
|
716
|
+
return { runs: body.runs, hasMore: body.has_more, nextCursor: body.next_cursor };
|
|
717
|
+
}
|
|
718
|
+
|
|
663
719
|
/** Ordered lifecycle timeline for one run. */
|
|
664
720
|
async getRunTimeline(runId: string, opts?: { limit?: number; offset?: number }): Promise<TimelineEvent[]> {
|
|
665
721
|
const q = new URLSearchParams();
|
|
@@ -867,7 +923,7 @@ export class AgentComposeClient {
|
|
|
867
923
|
// ── User drive mounts ──────────────────────────────────────────────────────
|
|
868
924
|
// `agentc files mount` on a human's own machine: the server forks a user
|
|
869
925
|
// branch, backs it with a mount session (the review surface), and mints a
|
|
870
|
-
// user-principal gateway token.
|
|
926
|
+
// user-principal gateway token. Own-device credentials only (sign-in
|
|
871
927
|
// cookie or a device-flow bridge key) — sandbox session keys are refused.
|
|
872
928
|
|
|
873
929
|
/** Create a local drive mount (or re-mint an existing one's token by
|
|
@@ -922,8 +978,18 @@ export class AgentComposeClient {
|
|
|
922
978
|
getChannelIvy(id: string): Promise<ChannelIvyState> {
|
|
923
979
|
return this.fetch(`/api/v1/conversations/${encodeURIComponent(id)}/ivy`);
|
|
924
980
|
}
|
|
925
|
-
|
|
926
|
-
|
|
981
|
+
/** A project's GitHub grants: its own, and the workspace's it inherits,
|
|
982
|
+
* one page at a time (pass the previous page's `nextCursor`). A
|
|
983
|
+
* project's access is its members' (and the workspace admins'): a
|
|
984
|
+
* member of the workspace who can see a public project without being in
|
|
985
|
+
* it gets a 403 `project_member_required`. */
|
|
986
|
+
listProjectIvyConnections(id: string, page?: ListingPage): Promise<IvyConnectionsView> {
|
|
987
|
+
return this.fetch(`/api/v1/projects/${encodeURIComponent(id)}/ivy-connections${listingPageQuery(page)}`);
|
|
988
|
+
}
|
|
989
|
+
/** A project's Drive shares: its own, and the workspace's it inherits,
|
|
990
|
+
* one page at a time. Members only, as listProjectIvyConnections. */
|
|
991
|
+
listProjectDriveShares(id: string, page?: ListingPage): Promise<DriveSharesView> {
|
|
992
|
+
return this.fetch(`/api/v1/projects/${encodeURIComponent(id)}/drive-shares${listingPageQuery(page)}`);
|
|
927
993
|
}
|
|
928
994
|
|
|
929
995
|
/** List conversations the caller can access, newest-activity first.
|
|
@@ -1053,25 +1119,6 @@ export class AgentComposeClient {
|
|
|
1053
1119
|
);
|
|
1054
1120
|
}
|
|
1055
1121
|
|
|
1056
|
-
/** Post one message into a channel AS the calling session (ADR-0057 Seam
|
|
1057
|
-
* 4) — progress, results, questions, attributed to the session (title +
|
|
1058
|
-
* runtime mark). Session toolbelt credential ONLY (the calling session
|
|
1059
|
-
* resolves from the key server-side — 403 `session_credential_required`
|
|
1060
|
-
* otherwise); the session must be attached (409 `not_attached`). By
|
|
1061
|
-
* default the post lands in the thread of the message that last
|
|
1062
|
-
* addressed the session from that channel (the room when none);
|
|
1063
|
-
* `threadRootId` overrides it — must be a root message in the channel
|
|
1064
|
-
* (400 `invalid_thread_root`). The post never triggers any turn. */
|
|
1065
|
-
postSessionChannelMessage(
|
|
1066
|
-
channelId: string,
|
|
1067
|
-
input: { text: string; threadRootId?: string },
|
|
1068
|
-
): Promise<SessionChannelMessagePosted> {
|
|
1069
|
-
return this.fetch<SessionChannelMessagePosted>(
|
|
1070
|
-
`/api/v1/conversations/${encodeURIComponent(channelId)}/session-messages`,
|
|
1071
|
-
{ method: "POST", body: { text: input.text, ...(input.threadRootId ? { threadRootId: input.threadRootId } : {}) } },
|
|
1072
|
-
);
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
1122
|
/** Message ANOTHER session's conversation AS the calling session
|
|
1076
1123
|
* (`agentc session message @alias`). Session toolbelt credential ONLY —
|
|
1077
1124
|
* the sender resolves from the key. `target` is an @alias (team-scoped)
|
|
@@ -1178,6 +1225,32 @@ export class AgentComposeClient {
|
|
|
1178
1225
|
);
|
|
1179
1226
|
}
|
|
1180
1227
|
|
|
1228
|
+
// ── Session waits (owner ruling 2026-09-23: no watch runs inside a session
|
|
1229
|
+
// sandbox). The session declares what it waits for and ends its turn; the
|
|
1230
|
+
// platform senses the arrival and wakes it. Own-session key posture. ─────
|
|
1231
|
+
|
|
1232
|
+
/** Declare one wait (`agentc wait`): `POST /sessions/:id/waits`. */
|
|
1233
|
+
createSessionWait(conversationId: string, input: CreateSessionWaitInput): Promise<SessionWaitCreated> {
|
|
1234
|
+
return this.fetch<SessionWaitCreated>(
|
|
1235
|
+
`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits`,
|
|
1236
|
+
{ method: "POST", body: input },
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/** This session's waits, newest first; open only unless `all`. */
|
|
1241
|
+
listSessionWaits(conversationId: string, opts: { all?: boolean } = {}): Promise<SessionWaitList> {
|
|
1242
|
+
const q = opts.all ? "?all=1" : "";
|
|
1243
|
+
return this.fetch<SessionWaitList>(`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits${q}`);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/** Cancel an open wait (`agentc wait cancel`): open -> cancelled. */
|
|
1247
|
+
cancelSessionWait(conversationId: string, waitId: string): Promise<SessionWait> {
|
|
1248
|
+
return this.fetch<SessionWait>(
|
|
1249
|
+
`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits/${encodeURIComponent(waitId)}`,
|
|
1250
|
+
{ method: "DELETE" },
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1181
1254
|
/** Request ONE machine size up for a cloud session (task #110 — the
|
|
1182
1255
|
* auto-resize policy's agent door). The platform arbitrates: within the
|
|
1183
1256
|
* team's daily cap the upsize is auto-granted (and executes the moment
|
|
@@ -1277,17 +1350,30 @@ export class AgentComposeClient {
|
|
|
1277
1350
|
return new Uint8Array(buf);
|
|
1278
1351
|
}
|
|
1279
1352
|
|
|
1353
|
+
/** Where ONE path's current version lives for a session
|
|
1354
|
+
* (`GET /conversations/:id/changes/file`): `main` when the main drive
|
|
1355
|
+
* holds the session branch's version (landed, or never changed on the
|
|
1356
|
+
* branch), else `branch` with `why` naming what keeps it off main. The
|
|
1357
|
+
* answer a `file:<path>?session=<id>` link resolves when it is opened.
|
|
1358
|
+
* 404 = missing path or no access (uniform, no existence oracle). */
|
|
1359
|
+
getSessionFilePlane(conversationId: string, path: string): Promise<SessionFilePlane> {
|
|
1360
|
+
const q = new URLSearchParams({ path });
|
|
1361
|
+
return this.fetch<SessionFilePlane>(
|
|
1362
|
+
`/api/v1/conversations/${encodeURIComponent(conversationId)}/changes/file?${q}`,
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1280
1366
|
/** Publish a diff review's WHOLE document — prose notes plus structured
|
|
1281
1367
|
* suggestions, FULL REPLACE on every call (`POST
|
|
1282
1368
|
* /conversations/:id/review-notes`; `agentc review publish`). Callable
|
|
1283
|
-
* ONLY with the
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1369
|
+
* ONLY with the toolbelt credential of a review session spawned for this
|
|
1370
|
+
* diff, which replaces its own document — any other key (another
|
|
1371
|
+
* session, a human cookie, a plain API key) refuses 403.
|
|
1372
|
+
* `conversationId` is the REVIEWED session's conversation (in a review
|
|
1373
|
+
* sandbox: `AGENT_COMPOSE_REVIEW_OF_CONVERSATION_ID`).
|
|
1287
1374
|
*
|
|
1288
|
-
* Failures: 403 `session_credential_required` | `not_review_session
|
|
1289
|
-
* `
|
|
1290
|
-
* `suggestion_path_not_in_change_set` (naming the offenders); 409
|
|
1375
|
+
* Failures: 403 `session_credential_required` | `not_review_session`;
|
|
1376
|
+
* 400 `suggestion_path_not_in_change_set` (naming the offenders); 409
|
|
1291
1377
|
* `review_disabled`. */
|
|
1292
1378
|
publishReviewNotes(
|
|
1293
1379
|
conversationId: string,
|
|
@@ -1323,22 +1409,6 @@ export class AgentComposeClient {
|
|
|
1323
1409
|
);
|
|
1324
1410
|
}
|
|
1325
1411
|
|
|
1326
|
-
/** Mint ONE fresh short-lived WIP-push credential for the CALLING
|
|
1327
|
-
* session's git namespace (`POST /sessions/self/wip-git-credential`,
|
|
1328
|
-
* git-door slice 2) — the server half of `agentc repos clone` and its
|
|
1329
|
-
* git credential helper. The token's Push grant is exactly
|
|
1330
|
-
* `refs/sessions/<sessionId>/`; the door refuses everything else.
|
|
1331
|
-
* Callable only with a session's own toolbelt credential.
|
|
1332
|
-
*
|
|
1333
|
-
* Failures: 403 `session_credential_required` | `not_a_session`;
|
|
1334
|
-
* 409 `git_remote_unavailable` (unbranched / legacy plane / fsgw off). */
|
|
1335
|
-
getSessionWipGitCredential(): Promise<ReviewGitCredential & { pushNamespace: string }> {
|
|
1336
|
-
return this.fetch<ReviewGitCredential & { pushNamespace: string }>(
|
|
1337
|
-
"/api/v1/sessions/self/wip-git-credential",
|
|
1338
|
-
{ method: "POST" },
|
|
1339
|
-
);
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
1412
|
/** Mint a short-lived native-git credential for a linked repo's MIRROR
|
|
1343
1413
|
* namespace (`POST /:slug/repo-links/:id/git-credential`, git-door
|
|
1344
1414
|
* slice 4). mode "fetch" (default) reads the mirror — gated on link
|
|
@@ -1485,8 +1555,10 @@ export class AgentComposeClient {
|
|
|
1485
1555
|
return body.members;
|
|
1486
1556
|
}
|
|
1487
1557
|
|
|
1488
|
-
/** Remove a member (conversation `owner` or team admin
|
|
1489
|
-
*
|
|
1558
|
+
/** Remove a member (conversation `owner` or team admin), or leave the
|
|
1559
|
+
* chat yourself: `userId` "me" (or your own id) is the self-leave door.
|
|
1560
|
+
* Throws 400 `last_owner` when the target is the roster's last owner and
|
|
1561
|
+
* 400 `creator_cannot_leave` when the chat's creator tries to leave it. */
|
|
1490
1562
|
async removeConversationMember(conversationId: string, userId: string): Promise<ConversationMember[]> {
|
|
1491
1563
|
const body = await this.fetch<{ members: ConversationMember[] }>(
|
|
1492
1564
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/members/${encodeURIComponent(userId)}`,
|
|
@@ -1838,9 +1910,16 @@ export class AgentComposeClient {
|
|
|
1838
1910
|
|
|
1839
1911
|
/** Rename a project (requires `write` role). */
|
|
1840
1912
|
async renameProject(id: string, name: string): Promise<Project> {
|
|
1913
|
+
return this.updateProject(id, { name });
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
/** Change a project's name, tier, description or dates (one PATCH; see
|
|
1917
|
+
* ProjectUpdate for who may set what). 400 `date_order` when the target
|
|
1918
|
+
* date would come before the start date. */
|
|
1919
|
+
async updateProject(id: string, patch: ProjectUpdate): Promise<Project> {
|
|
1841
1920
|
const body = await this.fetch<{ project: Project }>(
|
|
1842
1921
|
`/api/v1/projects/${encodeURIComponent(id)}`,
|
|
1843
|
-
{ method: "PATCH", body:
|
|
1922
|
+
{ method: "PATCH", body: patch },
|
|
1844
1923
|
);
|
|
1845
1924
|
return body.project;
|
|
1846
1925
|
}
|
|
@@ -1874,7 +1953,11 @@ export class AgentComposeClient {
|
|
|
1874
1953
|
return body.members;
|
|
1875
1954
|
}
|
|
1876
1955
|
|
|
1877
|
-
/** Remove a member — project owner/team admin, or self-leave.
|
|
1956
|
+
/** Remove a member — project owner/team admin, or self-leave (`me`).
|
|
1957
|
+
* Leaving a project takes its chats with it: the person loses their row
|
|
1958
|
+
* in every chat filed in the project, public and private, except a chat
|
|
1959
|
+
* they reach through another project they remain in, the home room, a
|
|
1960
|
+
* chat they created, and a chat they are the last owner of. Throws 400
|
|
1878
1961
|
* `last_owner` when the target is the roster's last owner. */
|
|
1879
1962
|
async removeProjectMember(id: string, userId: string): Promise<ProjectMember[]> {
|
|
1880
1963
|
const body = await this.fetch<{ members: ProjectMember[] }>(
|
|
@@ -1884,6 +1967,14 @@ export class AgentComposeClient {
|
|
|
1884
1967
|
return body.members;
|
|
1885
1968
|
}
|
|
1886
1969
|
|
|
1970
|
+
/** What leaving the project would take from the caller: the chats they
|
|
1971
|
+
* lose with it, and the project's shared files and folders. */
|
|
1972
|
+
async leaveProjectPreview(id: string): Promise<{ chats: number; files: number }> {
|
|
1973
|
+
return this.fetch<{ chats: number; files: number }>(
|
|
1974
|
+
`/api/v1/projects/${encodeURIComponent(id)}/leave-preview`,
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1887
1978
|
/** Change a member's role (project owner or team admin). Throws 400
|
|
1888
1979
|
* `last_owner` when demoting the roster's last owner. */
|
|
1889
1980
|
async setProjectMemberRole(
|
|
@@ -1898,15 +1989,56 @@ export class AgentComposeClient {
|
|
|
1898
1989
|
return body.members;
|
|
1899
1990
|
}
|
|
1900
1991
|
|
|
1901
|
-
/** List a project's objects (member only), newest first. Cursor-paginated.
|
|
1902
|
-
|
|
1992
|
+
/** List a project's objects (member only), newest first. Cursor-paginated.
|
|
1993
|
+
* `type` narrows to one object kind at the server, under the same
|
|
1994
|
+
* cursor — `"conversation"` is a project's chats alone, however many
|
|
1995
|
+
* files it holds. */
|
|
1996
|
+
listProjectObjects(id: string, opts?: { cursor?: string; type?: ProjectObject["type"] }): Promise<ProjectObjectsPage> {
|
|
1903
1997
|
const q = new URLSearchParams();
|
|
1904
1998
|
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
1999
|
+
if (opts?.type) q.set("type", opts.type);
|
|
1905
2000
|
return this.fetch<ProjectObjectsPage>(
|
|
1906
2001
|
`/api/v1/projects/${encodeURIComponent(id)}/objects${q.toString() ? `?${q}` : ""}`,
|
|
1907
2002
|
);
|
|
1908
2003
|
}
|
|
1909
2004
|
|
|
2005
|
+
/** How many objects of each kind the project holds for the caller
|
|
2006
|
+
* (member only): the whole project's counts, where a page of
|
|
2007
|
+
* `listProjectObjects` holds at most fifty. */
|
|
2008
|
+
getProjectObjectCounts(id: string): Promise<ProjectObjectCounts> {
|
|
2009
|
+
return this.fetch<ProjectObjectCounts>(`/api/v1/projects/${encodeURIComponent(id)}/objects/counts`);
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
/** The project status view (member only): its outcome threads with their
|
|
2013
|
+
* plans, workers, people and next dates, the project's progress, finish
|
|
2014
|
+
* line and next check-in, and what moved lately. `threads` is
|
|
2015
|
+
* cursor-paginated; `recentlyClosed` rides the first page. */
|
|
2016
|
+
getProjectStatus(id: string, opts?: { cursor?: string; limit?: number }): Promise<ProjectStatus> {
|
|
2017
|
+
const q = new URLSearchParams();
|
|
2018
|
+
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
2019
|
+
if (opts?.limit) q.set("limit", String(opts.limit));
|
|
2020
|
+
return this.fetch<ProjectStatus>(
|
|
2021
|
+
`/api/v1/projects/${encodeURIComponent(id)}/status${q.toString() ? `?${q}` : ""}`,
|
|
2022
|
+
);
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
/** One thread's status for the inline expansion of a status row: its
|
|
2026
|
+
* summary, workers by state, to-dos and last events. 404 for a thread
|
|
2027
|
+
* the caller cannot read. */
|
|
2028
|
+
getThreadStatus(threadId: string): Promise<ThreadStatus> {
|
|
2029
|
+
return this.fetch<ThreadStatus>(`/api/v1/threads/${encodeURIComponent(threadId)}/status`);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
/** The caller's personal status in the current workspace: the threads
|
|
2033
|
+
* relevant to them (posted, mentioned, asked, a to-do, or in the chat),
|
|
2034
|
+
* grouped client-side by project. `threads` is cursor-paginated. */
|
|
2035
|
+
getMeStatus(opts?: { cursor?: string; limit?: number }): Promise<MeStatus> {
|
|
2036
|
+
const q = new URLSearchParams();
|
|
2037
|
+
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
2038
|
+
if (opts?.limit) q.set("limit", String(opts.limit));
|
|
2039
|
+
return this.fetch<MeStatus>(`/api/v1/me/status${q.toString() ? `?${q}` : ""}`);
|
|
2040
|
+
}
|
|
2041
|
+
|
|
1910
2042
|
/** DRY-RUN preview of a session add: the files that WOULD be shared (from
|
|
1911
2043
|
* the caller's owned scopes) + any owned-but-skipped entries (paths
|
|
1912
2044
|
* concealed from the caller are omitted). Powers the consent dialog. Same
|
|
@@ -2083,9 +2215,10 @@ export class AgentComposeClient {
|
|
|
2083
2215
|
{ method: "POST", body: input });
|
|
2084
2216
|
}
|
|
2085
2217
|
|
|
2086
|
-
/** The
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2218
|
+
/** The caller's own connector grants and the workspace's GitHub
|
|
2219
|
+
* installations (metadata only — never tokens; a teammate's other
|
|
2220
|
+
* accounts never come back). Used by `agentc repos link` to default
|
|
2221
|
+
* `--grant` when the team holds exactly one active GitHub grant. */
|
|
2089
2222
|
async listConnectorGrants(): Promise<ConnectorGrantSummary[]> {
|
|
2090
2223
|
const body = await this.fetch<{ data: ConnectorGrantSummary[] }>("/api/v1/connectors");
|
|
2091
2224
|
return body.data;
|
|
@@ -2164,7 +2297,16 @@ export class AgentComposeClient {
|
|
|
2164
2297
|
* writer. */
|
|
2165
2298
|
requestSessionSecrets(
|
|
2166
2299
|
conversationId: string, keys: string[],
|
|
2167
|
-
opts?: {
|
|
2300
|
+
opts?: {
|
|
2301
|
+
reason?: string; setLabel?: string; kind?: VaultRequestKind; shapes?: Record<string, VaultKeyShape>;
|
|
2302
|
+
savedEntry?: RequestedVaultEntry;
|
|
2303
|
+
/** A REPLACEMENT: the keys are held already and did not work; the card
|
|
2304
|
+
* asks for a new value of the same key. */
|
|
2305
|
+
replace?: boolean;
|
|
2306
|
+
/** A different credential of a kind the work already holds under
|
|
2307
|
+
* another name (the server refuses such an ask without it). */
|
|
2308
|
+
distinct?: boolean;
|
|
2309
|
+
},
|
|
2168
2310
|
): Promise<SessionSecretRequestCreated> {
|
|
2169
2311
|
return this.fetch(
|
|
2170
2312
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/secret-requests`,
|
|
@@ -2176,6 +2318,14 @@ export class AgentComposeClient {
|
|
|
2176
2318
|
// WHAT KIND of credential — the vault page leads with the user's
|
|
2177
2319
|
// matching STANDING entries (personal-vault reuse, 2026-08-31).
|
|
2178
2320
|
...(opts?.kind ? { kind: opts.kind } : {}),
|
|
2321
|
+
// WHICH standing entry — by label and/or a card's last four — so the
|
|
2322
|
+
// card and the vault page lead with that exact one.
|
|
2323
|
+
...(opts?.savedEntry ? { savedEntry: opts.savedEntry } : {}),
|
|
2324
|
+
// Per-key DELIVERY (brokered onto a host, or injected) — required
|
|
2325
|
+
// for every key of an api_key ask.
|
|
2326
|
+
...(opts?.shapes ? { shapes: opts.shapes } : {}),
|
|
2327
|
+
...(opts?.replace ? { replace: true } : {}),
|
|
2328
|
+
...(opts?.distinct ? { distinct: true } : {}),
|
|
2179
2329
|
} });
|
|
2180
2330
|
}
|
|
2181
2331
|
|
|
@@ -2183,8 +2333,11 @@ export class AgentComposeClient {
|
|
|
2183
2333
|
* could grant to this session — labels, kinds, field NAMES, last-used.
|
|
2184
2334
|
* Values are write-only and never on this wire. Query it BEFORE asking
|
|
2185
2335
|
* the human for a credential: a matching entry means the ask is a GRANT
|
|
2186
|
-
* ask naming it, never a blank re-entry form.
|
|
2187
|
-
|
|
2336
|
+
* ask naming it, never a blank re-entry form. For the session's own key
|
|
2337
|
+
* it also carries `reaches`: what the session already reaches with no
|
|
2338
|
+
* credential asked for (`agentc access`), so a need met there is never
|
|
2339
|
+
* a vault ask. */
|
|
2340
|
+
getSessionVaultCatalog(conversationId: string): Promise<{ entries: VaultCatalogEntry[]; note?: string; reaches?: string }> {
|
|
2188
2341
|
return this.fetch(
|
|
2189
2342
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/vault-catalog`);
|
|
2190
2343
|
}
|
|
@@ -2192,7 +2345,7 @@ export class AgentComposeClient {
|
|
|
2192
2345
|
/** Poll a vault link's status (`pending` → `fulfilled`; `expired` when the
|
|
2193
2346
|
* clock ran out; `cancelled` when the human denied it or the requester
|
|
2194
2347
|
* withdrew it — attribution rides the answer). The in-sandbox
|
|
2195
|
-
* `agentc secrets request --wait` loop. */
|
|
2348
|
+
* `agentc secrets session request --wait` loop. */
|
|
2196
2349
|
getSessionSecretRequest(conversationId: string, requestId: string): Promise<SessionSecretRequestStatus> {
|
|
2197
2350
|
return this.fetch(
|
|
2198
2351
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/secret-requests/${encodeURIComponent(requestId)}`);
|
|
@@ -2224,6 +2377,8 @@ export class AgentComposeClient {
|
|
|
2224
2377
|
/** Create a new API key on the caller's team. The plaintext `key` is
|
|
2225
2378
|
* returned once — it cannot be retrieved later.
|
|
2226
2379
|
*
|
|
2380
|
+
* `scopes` omitted mints `read` alone; every scope asked for must be one
|
|
2381
|
+
* the caller holds (a key carries no more than whoever mints it).
|
|
2227
2382
|
* When `factorySlug` is set, the new key is restricted to that factory.
|
|
2228
2383
|
* Factory-scoped keys can only mint other keys bound to the same factory. */
|
|
2229
2384
|
createApiKey(input: CreateApiKeyInput): Promise<ApiKeyCreated> {
|
package/src/directives.ts
CHANGED
|
@@ -62,9 +62,9 @@ export type CloudDirective =
|
|
|
62
62
|
* the mentions ping are server-authoritative (`display_ask` shape). The
|
|
63
63
|
* one write-bearing directive (see the module header). */
|
|
64
64
|
| { kind: "ask"; prompt: string; approver: string; options?: Array<{ id: string; label: string }> }
|
|
65
|
-
/** Offer the human the desktop takeover door (`
|
|
66
|
-
*
|
|
67
|
-
* signed takeover link — "You can take over from here." Grants nothing
|
|
65
|
+
/** Offer the human the desktop takeover door (`show_computer` handing the
|
|
66
|
+
* screen over): the server captures the current screen and posts a card
|
|
67
|
+
* with a signed takeover link — "You can take over from here." Grants nothing
|
|
68
68
|
* by itself: the link's viewer must still be a signed-in member with
|
|
69
69
|
* write access to THIS session (the server re-checks on every resolve).
|
|
70
70
|
* ONLY for structurally-human walls (a CAPTCHA, human-only verification)
|
package/src/display.ts
CHANGED
|
@@ -681,6 +681,18 @@ function runIdIn(text: string): { runId: string; parsed: Record<string, unknown>
|
|
|
681
681
|
return m ? { runId: m[1], parsed: null } : null;
|
|
682
682
|
}
|
|
683
683
|
|
|
684
|
+
/** Every platform tool name `createDisplayPromoter` can put on a promoted
|
|
685
|
+
* `tool_call` — the closed set a local bridge daemon may legitimately post
|
|
686
|
+
* under a platform-owned name. The server's part-POST door
|
|
687
|
+
* (routes/bridge.ts) refuses every other platform tool name from a daemon,
|
|
688
|
+
* so a local agent cannot forge an approval, vault or takeover card. Kept
|
|
689
|
+
* beside the promoter so the two cannot drift. */
|
|
690
|
+
export const DISPLAY_PROMOTED_TOOL_NAMES: ReadonlySet<string> = new Set([
|
|
691
|
+
"display_run", "display_changes", "display_document", "display_plan", "display_image",
|
|
692
|
+
"display_desktop", "display_preview", "display_table", "display_chart", "display_diff",
|
|
693
|
+
"display_ask", "dispatch_workflow",
|
|
694
|
+
]);
|
|
695
|
+
|
|
684
696
|
export function createDisplayPromoter(ctx: DisplayPromoterContext = {}): DisplayPromoter {
|
|
685
697
|
const pending = new Map<string, PendingPromotion>();
|
|
686
698
|
|