@agent-compose/sdk 0.8.5 → 0.8.6
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 +4 -5
- package/dist/agent/perf-sampler.d.ts +27 -2
- package/dist/agent/run-agent.d.ts +1 -1
- package/dist/client.d.ts +105 -52
- 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 +716 -203
- package/dist/request-context/request-context.d.ts +1 -1
- package/dist/runtimes/_cli-agent.d.ts +182 -68
- 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/openai-desktop.js +686 -199
- 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 +78 -8
- package/dist/types/api-projects.d.ts +480 -0
- package/dist/types/api-runs.d.ts +8 -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 +65 -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 +5 -4
- package/src/agent/perf-sampler.ts +54 -3
- package/src/agent/run-agent.ts +1 -1
- package/src/client.ts +191 -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 +54 -21
- package/src/pause/pause-core.ts +2 -1
- package/src/request-context/request-context.ts +1 -1
- package/src/runtimes/_cli-agent.ts +306 -122
- package/src/runtimes/claude-code.ts +179 -9
- package/src/runtimes/claude.ts +1 -1
- 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 +74 -8
- package/src/types/api-projects.ts +443 -0
- package/src/types/api-runs.ts +5 -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 +67 -1
- 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
|
*
|
|
@@ -34,11 +34,12 @@ import type {
|
|
|
34
34
|
CreateCloudSessionInput, CloudSessionCreated,
|
|
35
35
|
SessionPreview, PreviewOpened, OpenPreviewInput, SessionForked, BackgroundWorkHeld,
|
|
36
36
|
BackgroundWorkChildDecl, BackgroundWorkStatus, MachineUpsizeOutcome,
|
|
37
|
-
|
|
37
|
+
CreateSessionWaitInput, SessionWait, SessionWaitCreated, SessionWaitList,
|
|
38
|
+
SessionChangeSet, SessionFilePlane, SessionMergeGated, SessionMergeReport, SessionDiscardReport,
|
|
38
39
|
SessionChangePreflight, SessionRebaseReport,
|
|
39
40
|
ReviewSuggestionInput, ReviewNotesPublished, ReviewGitCredential,
|
|
40
41
|
SendConversationMessageInput, SendConversationMessageResult,
|
|
41
|
-
ChannelSessionRow, ChannelSessionsResponse,
|
|
42
|
+
ChannelSessionRow, ChannelSessionsResponse,
|
|
42
43
|
SessionDirectMessageSent, BranchClaimGranted, BranchClaimsReleased, BranchClaimState,
|
|
43
44
|
ConversationPresenceSnapshot, StreamConversationOptions, AgentListRow,
|
|
44
45
|
SessionPerfHistoryPage,
|
|
@@ -48,9 +49,9 @@ import type {
|
|
|
48
49
|
SetScopeGrantsInput, SetTemplateScopeInput,
|
|
49
50
|
} from "./types/api-scopes.js";
|
|
50
51
|
import type {
|
|
51
|
-
Project, ProjectsPage, ProjectRole, ProjectMember,
|
|
52
|
-
ProjectObjectsPage, ProjectAddPreview,
|
|
53
|
-
AddProjectObjectInput, AddProjectObjectResult, RefreshProjectObjectResult,
|
|
52
|
+
Project, ProjectUpdate, ProjectsPage, ProjectRole, ProjectMember,
|
|
53
|
+
ProjectObject, ProjectObjectsPage, ProjectObjectCounts, ProjectAddPreview,
|
|
54
|
+
AddProjectObjectInput, AddProjectObjectResult, RefreshProjectObjectResult, ProjectStatus, ThreadStatus, MeStatus,
|
|
54
55
|
} from "./types/api-projects.js";
|
|
55
56
|
import type {
|
|
56
57
|
RegisterResult, RegisterWorkflowInput, TemplateRow, TemplateDetail, ListTemplatesOptions,
|
|
@@ -58,7 +59,7 @@ import type {
|
|
|
58
59
|
FactoryFileListRow, ListFactoryFilesOptions, FactoryFileListPage, FactoryFileConflict, FactoryFileConflictList, ProjectSecretMeta, ProjectSecretList,
|
|
59
60
|
FactoryRow, CreateFactoryInput, UpdateFactoryInput, FactoryPerfSummary,
|
|
60
61
|
ScheduleRow, CreateScheduleInput,
|
|
61
|
-
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultCatalogEntry,
|
|
62
|
+
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultKeyShape, VaultCatalogEntry, RequestedVaultEntry, VaultCardHint,
|
|
62
63
|
CreateApiKeyInput, ApiKey, ApiKeyCreated, ListApiKeysOptions, ApiKeyPage, UsageResponse,
|
|
63
64
|
DriveRepoLink, CreateDriveRepoLinkInput, CreateNativeRepoInput, CreateNativeRepoResult,
|
|
64
65
|
DriveMountSession, CreateDriveMountSessionInput,
|
|
@@ -88,20 +89,25 @@ export type {
|
|
|
88
89
|
} from "./types/api-runs.js";
|
|
89
90
|
export type {
|
|
90
91
|
TeamMember, Mention, CreateMentionsInput,
|
|
91
|
-
CreateChatInput, ChannelIvyState,
|
|
92
|
-
|
|
92
|
+
CreateChatInput, ChannelIvyState, IvyConnection, HiddenIvyConnection, IvyConnectionsView, IvyConnectionScope, ListingPage,
|
|
93
|
+
DriveShareItem, DriveShare, HiddenDriveShare, DriveSharesView,
|
|
94
|
+
WorkspaceConnection, WorkspaceConnectionAudienceEntry, WorkspaceConnectionsScopeView,
|
|
95
|
+
ConversationMessagePart, ConversationRow, ConversationProject, ConversationMessageRow,
|
|
93
96
|
ConversationsPage, SessionsPage, ConversationDetail,
|
|
94
97
|
CreateCloudSessionInput, CloudSessionCreated, ConversationThread,
|
|
98
|
+
ConversationUnreadSummary, ConversationUnreadThreads, ConversationReadInput, ConversationReadResult,
|
|
95
99
|
SessionPreview, PreviewOpened, OpenPreviewInput, SessionForked, BackgroundWorkHeld,
|
|
96
100
|
BackgroundWorkChildDecl, BackgroundWorkStatus, MachineUpsizeOutcome,
|
|
101
|
+
SessionWaitKind, SessionWaitState, CreateSessionWaitInput, SessionWait, SessionWaitCheck, SessionWaitCheckResult, SessionWaitCheckReview, SessionWaitCreated, SessionWaitList,
|
|
97
102
|
SessionFileChange, SessionChangeSet, SessionChangeStats, SessionDiffReviewBound, ReviewSuggestion,
|
|
103
|
+
SessionFileHold, SessionFilePlane,
|
|
98
104
|
ReviewSuggestionInput, ReviewNotesPublished, ReviewGitCredential, SessionReviewDocument,
|
|
99
105
|
ReviewSuggestionDecision, ReviewSuggestionDecisions,
|
|
100
106
|
SessionMergeReportDetail, SessionMergeReport, SessionMergeGated, SessionDiscardReport,
|
|
101
107
|
SessionPreflightFileRow, SessionChangePreflight, SessionRebaseReport,
|
|
102
108
|
ConversationPageContext, SendConversationMessageInput, ConversationTurnState,
|
|
103
109
|
SendConversationMessageResult, UnnotifiedMention, ConversationPresenceSnapshot, AgentListRow, StreamConversationOptions,
|
|
104
|
-
ChannelSessionStatus, ChannelSessionRow,
|
|
110
|
+
ChannelSessionStatus, ChannelSessionRow, ChannelWorkerFacts, ChannelSessionsResponse,
|
|
105
111
|
SessionDirectMessageSent, BranchClaimInfo, BranchClaimGranted, BranchClaimsReleased, BranchClaimState,
|
|
106
112
|
SessionPerfBucket, SessionPerfHistoryPage,
|
|
107
113
|
} from "./types/api-conversations.js";
|
|
@@ -111,10 +117,15 @@ export type {
|
|
|
111
117
|
RunContext, SetScopeGrantsInput, SetTemplateScopeInput,
|
|
112
118
|
} from "./types/api-scopes.js";
|
|
113
119
|
export type {
|
|
114
|
-
Project, ProjectsPage, ProjectRole, ProjectMember,
|
|
115
|
-
ProjectObject, ProjectObjectsPage, ProjectSkippedFile, ProjectPreviewFile,
|
|
120
|
+
Project, ProjectUpdate, ProjectsPage, ProjectRole, ProjectMember,
|
|
121
|
+
ProjectObject, ProjectObjectsPage, ProjectObjectCounts, ProjectSkippedFile, ProjectPreviewFile,
|
|
116
122
|
ProjectAddPreview, AddProjectObjectInput, AddProjectObjectResult,
|
|
117
123
|
RefreshProjectObjectResult,
|
|
124
|
+
ProjectStatus, ProjectStatusThread, ProjectStatusTask, ProjectStatusPerson, ProjectStatusWorker, ProjectStatusActivity,
|
|
125
|
+
ProjectStatusActivityKind, ProjectStatusWaitingOn, ProjectStatusWaitingCount, ProjectStatusCounts,
|
|
126
|
+
ThreadStatus, ThreadStatusWorker, ThreadStatusWorkerState, ThreadStatusWorkerEffort, ThreadStatusTodo, ThreadStatusDirector, ThreadStatusOutput, ThreadStatusEvent, ChatWork, ChatWorkThread,
|
|
127
|
+
ThreadStatusWaitingOn, ThreadStatusAssignee, ThreadStatusTodoActivity, ChatTodoPatch, ChatTodoComment,
|
|
128
|
+
MeStatus, MeStatusCounts,
|
|
118
129
|
} from "./types/api-projects.js";
|
|
119
130
|
export type {
|
|
120
131
|
RegisterResult, RegisteredRuntime, RuntimeSourceInput, TemplateSourceRef, RegisterWorkflowInput,
|
|
@@ -124,7 +135,7 @@ export type {
|
|
|
124
135
|
PublicFileLinkState,
|
|
125
136
|
FactoryRow, CreateFactoryInput, UpdateFactoryInput, FactoryPerfSummary,
|
|
126
137
|
ScheduleRow, CreateScheduleInput,
|
|
127
|
-
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultCatalogEntry,
|
|
138
|
+
SecretOptions, SetSecretResult, SecretListEntry, SessionSecretEntry, SessionSecretInput, SessionSecretRequestCreated, SessionSecretRequestStatus, SessionSecretRequestSummary, VaultRequestKind, VaultKeyShape, VaultCatalogEntry, RequestedVaultEntry, VaultCardHint,
|
|
128
139
|
CreateApiKeyInput, ApiKey, ApiKeyCreated, ListApiKeysOptions, ApiKeyPage,
|
|
129
140
|
UsageRollupRow, UsageResponse,
|
|
130
141
|
DriveRepoLink, CreateDriveRepoLinkInput, CreateNativeRepoInput, CreateNativeRepoResult,
|
|
@@ -157,6 +168,16 @@ function detectAmbientParentRunId(): string | null {
|
|
|
157
168
|
* URL-encoded as defense-in-depth: today's server-side patterns
|
|
158
169
|
* (`^[a-z][a-z0-9-]*$`) can't produce reserved characters, but a future
|
|
159
170
|
* relaxation would otherwise quietly become an injection vector. */
|
|
171
|
+
/** The query string of one page of a scope listing (`cursor`: the previous
|
|
172
|
+
* page's `nextCursor`; `limit`: 1..200). Empty for the first page at the
|
|
173
|
+
* server's size. */
|
|
174
|
+
function listingPageQuery(page: ListingPage = {}): string {
|
|
175
|
+
const q = new URLSearchParams();
|
|
176
|
+
if (page.cursor) q.set("cursor", page.cursor);
|
|
177
|
+
if (page.limit !== undefined) q.set("limit", String(page.limit));
|
|
178
|
+
return q.toString() ? `?${q}` : "";
|
|
179
|
+
}
|
|
180
|
+
|
|
160
181
|
function templatePath(factorySlug: string, ...rest: string[]): string {
|
|
161
182
|
const tail = rest.length > 0
|
|
162
183
|
? "/" + rest.map(encodeURIComponent).join("/")
|
|
@@ -867,7 +888,7 @@ export class AgentComposeClient {
|
|
|
867
888
|
// ── User drive mounts ──────────────────────────────────────────────────────
|
|
868
889
|
// `agentc files mount` on a human's own machine: the server forks a user
|
|
869
890
|
// branch, backs it with a mount session (the review surface), and mints a
|
|
870
|
-
// user-principal gateway token.
|
|
891
|
+
// user-principal gateway token. Own-device credentials only (sign-in
|
|
871
892
|
// cookie or a device-flow bridge key) — sandbox session keys are refused.
|
|
872
893
|
|
|
873
894
|
/** Create a local drive mount (or re-mint an existing one's token by
|
|
@@ -922,8 +943,18 @@ export class AgentComposeClient {
|
|
|
922
943
|
getChannelIvy(id: string): Promise<ChannelIvyState> {
|
|
923
944
|
return this.fetch(`/api/v1/conversations/${encodeURIComponent(id)}/ivy`);
|
|
924
945
|
}
|
|
925
|
-
|
|
926
|
-
|
|
946
|
+
/** A project's GitHub grants: its own, and the workspace's it inherits,
|
|
947
|
+
* one page at a time (pass the previous page's `nextCursor`). A
|
|
948
|
+
* project's access is its members' (and the workspace admins'): a
|
|
949
|
+
* member of the workspace who can see a public project without being in
|
|
950
|
+
* it gets a 403 `project_member_required`. */
|
|
951
|
+
listProjectIvyConnections(id: string, page?: ListingPage): Promise<IvyConnectionsView> {
|
|
952
|
+
return this.fetch(`/api/v1/projects/${encodeURIComponent(id)}/ivy-connections${listingPageQuery(page)}`);
|
|
953
|
+
}
|
|
954
|
+
/** A project's Drive shares: its own, and the workspace's it inherits,
|
|
955
|
+
* one page at a time. Members only, as listProjectIvyConnections. */
|
|
956
|
+
listProjectDriveShares(id: string, page?: ListingPage): Promise<DriveSharesView> {
|
|
957
|
+
return this.fetch(`/api/v1/projects/${encodeURIComponent(id)}/drive-shares${listingPageQuery(page)}`);
|
|
927
958
|
}
|
|
928
959
|
|
|
929
960
|
/** List conversations the caller can access, newest-activity first.
|
|
@@ -1053,25 +1084,6 @@ export class AgentComposeClient {
|
|
|
1053
1084
|
);
|
|
1054
1085
|
}
|
|
1055
1086
|
|
|
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
1087
|
/** Message ANOTHER session's conversation AS the calling session
|
|
1076
1088
|
* (`agentc session message @alias`). Session toolbelt credential ONLY —
|
|
1077
1089
|
* the sender resolves from the key. `target` is an @alias (team-scoped)
|
|
@@ -1178,6 +1190,32 @@ export class AgentComposeClient {
|
|
|
1178
1190
|
);
|
|
1179
1191
|
}
|
|
1180
1192
|
|
|
1193
|
+
// ── Session waits (owner ruling 2026-09-23: no watch runs inside a session
|
|
1194
|
+
// sandbox). The session declares what it waits for and ends its turn; the
|
|
1195
|
+
// platform senses the arrival and wakes it. Own-session key posture. ─────
|
|
1196
|
+
|
|
1197
|
+
/** Declare one wait (`agentc wait`): `POST /sessions/:id/waits`. */
|
|
1198
|
+
createSessionWait(conversationId: string, input: CreateSessionWaitInput): Promise<SessionWaitCreated> {
|
|
1199
|
+
return this.fetch<SessionWaitCreated>(
|
|
1200
|
+
`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits`,
|
|
1201
|
+
{ method: "POST", body: input },
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/** This session's waits, newest first; open only unless `all`. */
|
|
1206
|
+
listSessionWaits(conversationId: string, opts: { all?: boolean } = {}): Promise<SessionWaitList> {
|
|
1207
|
+
const q = opts.all ? "?all=1" : "";
|
|
1208
|
+
return this.fetch<SessionWaitList>(`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits${q}`);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/** Cancel an open wait (`agentc wait cancel`): open -> cancelled. */
|
|
1212
|
+
cancelSessionWait(conversationId: string, waitId: string): Promise<SessionWait> {
|
|
1213
|
+
return this.fetch<SessionWait>(
|
|
1214
|
+
`/api/v1/sessions/${encodeURIComponent(conversationId)}/waits/${encodeURIComponent(waitId)}`,
|
|
1215
|
+
{ method: "DELETE" },
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1181
1219
|
/** Request ONE machine size up for a cloud session (task #110 — the
|
|
1182
1220
|
* auto-resize policy's agent door). The platform arbitrates: within the
|
|
1183
1221
|
* team's daily cap the upsize is auto-granted (and executes the moment
|
|
@@ -1277,17 +1315,30 @@ export class AgentComposeClient {
|
|
|
1277
1315
|
return new Uint8Array(buf);
|
|
1278
1316
|
}
|
|
1279
1317
|
|
|
1318
|
+
/** Where ONE path's current version lives for a session
|
|
1319
|
+
* (`GET /conversations/:id/changes/file`): `main` when the main drive
|
|
1320
|
+
* holds the session branch's version (landed, or never changed on the
|
|
1321
|
+
* branch), else `branch` with `why` naming what keeps it off main. The
|
|
1322
|
+
* answer a `file:<path>?session=<id>` link resolves when it is opened.
|
|
1323
|
+
* 404 = missing path or no access (uniform, no existence oracle). */
|
|
1324
|
+
getSessionFilePlane(conversationId: string, path: string): Promise<SessionFilePlane> {
|
|
1325
|
+
const q = new URLSearchParams({ path });
|
|
1326
|
+
return this.fetch<SessionFilePlane>(
|
|
1327
|
+
`/api/v1/conversations/${encodeURIComponent(conversationId)}/changes/file?${q}`,
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1280
1331
|
/** Publish a diff review's WHOLE document — prose notes plus structured
|
|
1281
1332
|
* suggestions, FULL REPLACE on every call (`POST
|
|
1282
1333
|
* /conversations/:id/review-notes`; `agentc review publish`). Callable
|
|
1283
|
-
* ONLY with the
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1334
|
+
* ONLY with the toolbelt credential of a review session spawned for this
|
|
1335
|
+
* diff, which replaces its own document — any other key (another
|
|
1336
|
+
* session, a human cookie, a plain API key) refuses 403.
|
|
1337
|
+
* `conversationId` is the REVIEWED session's conversation (in a review
|
|
1338
|
+
* sandbox: `AGENT_COMPOSE_REVIEW_OF_CONVERSATION_ID`).
|
|
1287
1339
|
*
|
|
1288
|
-
* Failures: 403 `session_credential_required` | `not_review_session
|
|
1289
|
-
* `
|
|
1290
|
-
* `suggestion_path_not_in_change_set` (naming the offenders); 409
|
|
1340
|
+
* Failures: 403 `session_credential_required` | `not_review_session`;
|
|
1341
|
+
* 400 `suggestion_path_not_in_change_set` (naming the offenders); 409
|
|
1291
1342
|
* `review_disabled`. */
|
|
1292
1343
|
publishReviewNotes(
|
|
1293
1344
|
conversationId: string,
|
|
@@ -1323,22 +1374,6 @@ export class AgentComposeClient {
|
|
|
1323
1374
|
);
|
|
1324
1375
|
}
|
|
1325
1376
|
|
|
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
1377
|
/** Mint a short-lived native-git credential for a linked repo's MIRROR
|
|
1343
1378
|
* namespace (`POST /:slug/repo-links/:id/git-credential`, git-door
|
|
1344
1379
|
* slice 4). mode "fetch" (default) reads the mirror — gated on link
|
|
@@ -1485,8 +1520,10 @@ export class AgentComposeClient {
|
|
|
1485
1520
|
return body.members;
|
|
1486
1521
|
}
|
|
1487
1522
|
|
|
1488
|
-
/** Remove a member (conversation `owner` or team admin
|
|
1489
|
-
*
|
|
1523
|
+
/** Remove a member (conversation `owner` or team admin), or leave the
|
|
1524
|
+
* chat yourself: `userId` "me" (or your own id) is the self-leave door.
|
|
1525
|
+
* Throws 400 `last_owner` when the target is the roster's last owner and
|
|
1526
|
+
* 400 `creator_cannot_leave` when the chat's creator tries to leave it. */
|
|
1490
1527
|
async removeConversationMember(conversationId: string, userId: string): Promise<ConversationMember[]> {
|
|
1491
1528
|
const body = await this.fetch<{ members: ConversationMember[] }>(
|
|
1492
1529
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/members/${encodeURIComponent(userId)}`,
|
|
@@ -1838,9 +1875,16 @@ export class AgentComposeClient {
|
|
|
1838
1875
|
|
|
1839
1876
|
/** Rename a project (requires `write` role). */
|
|
1840
1877
|
async renameProject(id: string, name: string): Promise<Project> {
|
|
1878
|
+
return this.updateProject(id, { name });
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
/** Change a project's name, tier, description or dates (one PATCH; see
|
|
1882
|
+
* ProjectUpdate for who may set what). 400 `date_order` when the target
|
|
1883
|
+
* date would come before the start date. */
|
|
1884
|
+
async updateProject(id: string, patch: ProjectUpdate): Promise<Project> {
|
|
1841
1885
|
const body = await this.fetch<{ project: Project }>(
|
|
1842
1886
|
`/api/v1/projects/${encodeURIComponent(id)}`,
|
|
1843
|
-
{ method: "PATCH", body:
|
|
1887
|
+
{ method: "PATCH", body: patch },
|
|
1844
1888
|
);
|
|
1845
1889
|
return body.project;
|
|
1846
1890
|
}
|
|
@@ -1874,7 +1918,11 @@ export class AgentComposeClient {
|
|
|
1874
1918
|
return body.members;
|
|
1875
1919
|
}
|
|
1876
1920
|
|
|
1877
|
-
/** Remove a member — project owner/team admin, or self-leave.
|
|
1921
|
+
/** Remove a member — project owner/team admin, or self-leave (`me`).
|
|
1922
|
+
* Leaving a project takes its chats with it: the person loses their row
|
|
1923
|
+
* in every chat filed in the project, public and private, except a chat
|
|
1924
|
+
* they reach through another project they remain in, the home room, a
|
|
1925
|
+
* chat they created, and a chat they are the last owner of. Throws 400
|
|
1878
1926
|
* `last_owner` when the target is the roster's last owner. */
|
|
1879
1927
|
async removeProjectMember(id: string, userId: string): Promise<ProjectMember[]> {
|
|
1880
1928
|
const body = await this.fetch<{ members: ProjectMember[] }>(
|
|
@@ -1884,6 +1932,14 @@ export class AgentComposeClient {
|
|
|
1884
1932
|
return body.members;
|
|
1885
1933
|
}
|
|
1886
1934
|
|
|
1935
|
+
/** What leaving the project would take from the caller: the chats they
|
|
1936
|
+
* lose with it, and the project's shared files and folders. */
|
|
1937
|
+
async leaveProjectPreview(id: string): Promise<{ chats: number; files: number }> {
|
|
1938
|
+
return this.fetch<{ chats: number; files: number }>(
|
|
1939
|
+
`/api/v1/projects/${encodeURIComponent(id)}/leave-preview`,
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1887
1943
|
/** Change a member's role (project owner or team admin). Throws 400
|
|
1888
1944
|
* `last_owner` when demoting the roster's last owner. */
|
|
1889
1945
|
async setProjectMemberRole(
|
|
@@ -1898,15 +1954,56 @@ export class AgentComposeClient {
|
|
|
1898
1954
|
return body.members;
|
|
1899
1955
|
}
|
|
1900
1956
|
|
|
1901
|
-
/** List a project's objects (member only), newest first. Cursor-paginated.
|
|
1902
|
-
|
|
1957
|
+
/** List a project's objects (member only), newest first. Cursor-paginated.
|
|
1958
|
+
* `type` narrows to one object kind at the server, under the same
|
|
1959
|
+
* cursor — `"conversation"` is a project's chats alone, however many
|
|
1960
|
+
* files it holds. */
|
|
1961
|
+
listProjectObjects(id: string, opts?: { cursor?: string; type?: ProjectObject["type"] }): Promise<ProjectObjectsPage> {
|
|
1903
1962
|
const q = new URLSearchParams();
|
|
1904
1963
|
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
1964
|
+
if (opts?.type) q.set("type", opts.type);
|
|
1905
1965
|
return this.fetch<ProjectObjectsPage>(
|
|
1906
1966
|
`/api/v1/projects/${encodeURIComponent(id)}/objects${q.toString() ? `?${q}` : ""}`,
|
|
1907
1967
|
);
|
|
1908
1968
|
}
|
|
1909
1969
|
|
|
1970
|
+
/** How many objects of each kind the project holds for the caller
|
|
1971
|
+
* (member only): the whole project's counts, where a page of
|
|
1972
|
+
* `listProjectObjects` holds at most fifty. */
|
|
1973
|
+
getProjectObjectCounts(id: string): Promise<ProjectObjectCounts> {
|
|
1974
|
+
return this.fetch<ProjectObjectCounts>(`/api/v1/projects/${encodeURIComponent(id)}/objects/counts`);
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
/** The project status view (member only): its outcome threads with their
|
|
1978
|
+
* plans, workers, people and next dates, the project's progress, finish
|
|
1979
|
+
* line and next check-in, and what moved lately. `threads` is
|
|
1980
|
+
* cursor-paginated; `recentlyClosed` rides the first page. */
|
|
1981
|
+
getProjectStatus(id: string, opts?: { cursor?: string; limit?: number }): Promise<ProjectStatus> {
|
|
1982
|
+
const q = new URLSearchParams();
|
|
1983
|
+
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
1984
|
+
if (opts?.limit) q.set("limit", String(opts.limit));
|
|
1985
|
+
return this.fetch<ProjectStatus>(
|
|
1986
|
+
`/api/v1/projects/${encodeURIComponent(id)}/status${q.toString() ? `?${q}` : ""}`,
|
|
1987
|
+
);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/** One thread's status for the inline expansion of a status row: its
|
|
1991
|
+
* summary, workers by state, to-dos and last events. 404 for a thread
|
|
1992
|
+
* the caller cannot read. */
|
|
1993
|
+
getThreadStatus(threadId: string): Promise<ThreadStatus> {
|
|
1994
|
+
return this.fetch<ThreadStatus>(`/api/v1/threads/${encodeURIComponent(threadId)}/status`);
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
/** The caller's personal status in the current workspace: the threads
|
|
1998
|
+
* relevant to them (posted, mentioned, asked, a to-do, or in the chat),
|
|
1999
|
+
* grouped client-side by project. `threads` is cursor-paginated. */
|
|
2000
|
+
getMeStatus(opts?: { cursor?: string; limit?: number }): Promise<MeStatus> {
|
|
2001
|
+
const q = new URLSearchParams();
|
|
2002
|
+
if (opts?.cursor) q.set("cursor", opts.cursor);
|
|
2003
|
+
if (opts?.limit) q.set("limit", String(opts.limit));
|
|
2004
|
+
return this.fetch<MeStatus>(`/api/v1/me/status${q.toString() ? `?${q}` : ""}`);
|
|
2005
|
+
}
|
|
2006
|
+
|
|
1910
2007
|
/** DRY-RUN preview of a session add: the files that WOULD be shared (from
|
|
1911
2008
|
* the caller's owned scopes) + any owned-but-skipped entries (paths
|
|
1912
2009
|
* concealed from the caller are omitted). Powers the consent dialog. Same
|
|
@@ -2083,9 +2180,10 @@ export class AgentComposeClient {
|
|
|
2083
2180
|
{ method: "POST", body: input });
|
|
2084
2181
|
}
|
|
2085
2182
|
|
|
2086
|
-
/** The
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2183
|
+
/** The caller's own connector grants and the workspace's GitHub
|
|
2184
|
+
* installations (metadata only — never tokens; a teammate's other
|
|
2185
|
+
* accounts never come back). Used by `agentc repos link` to default
|
|
2186
|
+
* `--grant` when the team holds exactly one active GitHub grant. */
|
|
2089
2187
|
async listConnectorGrants(): Promise<ConnectorGrantSummary[]> {
|
|
2090
2188
|
const body = await this.fetch<{ data: ConnectorGrantSummary[] }>("/api/v1/connectors");
|
|
2091
2189
|
return body.data;
|
|
@@ -2164,7 +2262,16 @@ export class AgentComposeClient {
|
|
|
2164
2262
|
* writer. */
|
|
2165
2263
|
requestSessionSecrets(
|
|
2166
2264
|
conversationId: string, keys: string[],
|
|
2167
|
-
opts?: {
|
|
2265
|
+
opts?: {
|
|
2266
|
+
reason?: string; setLabel?: string; kind?: VaultRequestKind; shapes?: Record<string, VaultKeyShape>;
|
|
2267
|
+
savedEntry?: RequestedVaultEntry;
|
|
2268
|
+
/** A REPLACEMENT: the keys are held already and did not work; the card
|
|
2269
|
+
* asks for a new value of the same key. */
|
|
2270
|
+
replace?: boolean;
|
|
2271
|
+
/** A different credential of a kind the work already holds under
|
|
2272
|
+
* another name (the server refuses such an ask without it). */
|
|
2273
|
+
distinct?: boolean;
|
|
2274
|
+
},
|
|
2168
2275
|
): Promise<SessionSecretRequestCreated> {
|
|
2169
2276
|
return this.fetch(
|
|
2170
2277
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/secret-requests`,
|
|
@@ -2176,6 +2283,14 @@ export class AgentComposeClient {
|
|
|
2176
2283
|
// WHAT KIND of credential — the vault page leads with the user's
|
|
2177
2284
|
// matching STANDING entries (personal-vault reuse, 2026-08-31).
|
|
2178
2285
|
...(opts?.kind ? { kind: opts.kind } : {}),
|
|
2286
|
+
// WHICH standing entry — by label and/or a card's last four — so the
|
|
2287
|
+
// card and the vault page lead with that exact one.
|
|
2288
|
+
...(opts?.savedEntry ? { savedEntry: opts.savedEntry } : {}),
|
|
2289
|
+
// Per-key DELIVERY (brokered onto a host, or injected) — required
|
|
2290
|
+
// for every key of an api_key ask.
|
|
2291
|
+
...(opts?.shapes ? { shapes: opts.shapes } : {}),
|
|
2292
|
+
...(opts?.replace ? { replace: true } : {}),
|
|
2293
|
+
...(opts?.distinct ? { distinct: true } : {}),
|
|
2179
2294
|
} });
|
|
2180
2295
|
}
|
|
2181
2296
|
|
|
@@ -2183,8 +2298,11 @@ export class AgentComposeClient {
|
|
|
2183
2298
|
* could grant to this session — labels, kinds, field NAMES, last-used.
|
|
2184
2299
|
* Values are write-only and never on this wire. Query it BEFORE asking
|
|
2185
2300
|
* 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
|
-
|
|
2301
|
+
* ask naming it, never a blank re-entry form. For the session's own key
|
|
2302
|
+
* it also carries `reaches`: what the session already reaches with no
|
|
2303
|
+
* credential asked for (`agentc access`), so a need met there is never
|
|
2304
|
+
* a vault ask. */
|
|
2305
|
+
getSessionVaultCatalog(conversationId: string): Promise<{ entries: VaultCatalogEntry[]; note?: string; reaches?: string }> {
|
|
2188
2306
|
return this.fetch(
|
|
2189
2307
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/vault-catalog`);
|
|
2190
2308
|
}
|
|
@@ -2192,7 +2310,7 @@ export class AgentComposeClient {
|
|
|
2192
2310
|
/** Poll a vault link's status (`pending` → `fulfilled`; `expired` when the
|
|
2193
2311
|
* clock ran out; `cancelled` when the human denied it or the requester
|
|
2194
2312
|
* withdrew it — attribution rides the answer). The in-sandbox
|
|
2195
|
-
* `agentc secrets request --wait` loop. */
|
|
2313
|
+
* `agentc secrets session request --wait` loop. */
|
|
2196
2314
|
getSessionSecretRequest(conversationId: string, requestId: string): Promise<SessionSecretRequestStatus> {
|
|
2197
2315
|
return this.fetch(
|
|
2198
2316
|
`/api/v1/conversations/${encodeURIComponent(conversationId)}/secret-requests/${encodeURIComponent(requestId)}`);
|
|
@@ -2224,6 +2342,8 @@ export class AgentComposeClient {
|
|
|
2224
2342
|
/** Create a new API key on the caller's team. The plaintext `key` is
|
|
2225
2343
|
* returned once — it cannot be retrieved later.
|
|
2226
2344
|
*
|
|
2345
|
+
* `scopes` omitted mints `read` alone; every scope asked for must be one
|
|
2346
|
+
* the caller holds (a key carries no more than whoever mints it).
|
|
2227
2347
|
* When `factorySlug` is set, the new key is restricted to that factory.
|
|
2228
2348
|
* Factory-scoped keys can only mint other keys bound to the same factory. */
|
|
2229
2349
|
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
|
|