@stigmer/sdk 3.12.4 → 3.12.5

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.
Files changed (59) hide show
  1. package/__tests__/mcpserver-connect.test.d.ts +2 -0
  2. package/__tests__/mcpserver-connect.test.d.ts.map +1 -0
  3. package/__tests__/mcpserver-connect.test.js +146 -0
  4. package/__tests__/mcpserver-connect.test.js.map +1 -0
  5. package/__tests__/update-input.test.d.ts +2 -0
  6. package/__tests__/update-input.test.d.ts.map +1 -0
  7. package/__tests__/update-input.test.js +169 -0
  8. package/__tests__/update-input.test.js.map +1 -0
  9. package/gen/agentexecution.d.ts +6 -0
  10. package/gen/agentexecution.d.ts.map +1 -1
  11. package/gen/agentexecution.js +9 -1
  12. package/gen/agentexecution.js.map +1 -1
  13. package/gen/client.d.ts +3 -3
  14. package/gen/client.d.ts.map +1 -1
  15. package/gen/identityaccount.d.ts +8 -0
  16. package/gen/identityaccount.d.ts.map +1 -1
  17. package/gen/identityaccount.js +11 -1
  18. package/gen/identityaccount.js.map +1 -1
  19. package/gen/mcpserver.d.ts +1 -0
  20. package/gen/mcpserver.d.ts.map +1 -1
  21. package/gen/mcpserver.js +8 -0
  22. package/gen/mcpserver.js.map +1 -1
  23. package/gen/oauthapp.d.ts +2 -1
  24. package/gen/oauthapp.d.ts.map +1 -1
  25. package/gen/oauthapp.js +1 -0
  26. package/gen/oauthapp.js.map +1 -1
  27. package/gen/organization.d.ts +5 -0
  28. package/gen/organization.d.ts.map +1 -1
  29. package/gen/organization.js +8 -1
  30. package/gen/organization.js.map +1 -1
  31. package/gen/platformclient.d.ts +1 -0
  32. package/gen/platformclient.d.ts.map +1 -1
  33. package/gen/platformclient.js +2 -0
  34. package/gen/platformclient.js.map +1 -1
  35. package/index.d.ts +2 -0
  36. package/index.d.ts.map +1 -1
  37. package/index.js +3 -0
  38. package/index.js.map +1 -1
  39. package/mcpserver-connect.d.ts +79 -0
  40. package/mcpserver-connect.d.ts.map +1 -0
  41. package/mcpserver-connect.js +114 -0
  42. package/mcpserver-connect.js.map +1 -0
  43. package/package.json +2 -2
  44. package/src/__tests__/mcpserver-connect.test.ts +181 -0
  45. package/src/__tests__/update-input.test.ts +219 -0
  46. package/src/gen/agentexecution.ts +17 -1
  47. package/src/gen/client.ts +3 -3
  48. package/src/gen/identityaccount.ts +21 -1
  49. package/src/gen/mcpserver.ts +6 -0
  50. package/src/gen/oauthapp.ts +3 -1
  51. package/src/gen/organization.ts +15 -1
  52. package/src/gen/platformclient.ts +3 -0
  53. package/src/index.ts +14 -0
  54. package/src/mcpserver-connect.ts +159 -0
  55. package/src/update-input.ts +168 -0
  56. package/update-input.d.ts +24 -0
  57. package/update-input.d.ts.map +1 -0
  58. package/update-input.js +126 -0
  59. package/update-input.js.map +1 -0
@@ -0,0 +1,181 @@
1
+ // Pins the shared async-connect protocol (stigmer/stigmer#425): start + poll,
2
+ // terminal-failure rehydration, the UNIMPLEMENTED blocking fallback, and the
3
+ // still-running bound. Every SDK surface (CLI, React hooks, host apps) rides
4
+ // this one implementation, so its contract is pinned here rather than
5
+ // re-tested per consumer.
6
+
7
+ import { describe, expect, it } from "vitest";
8
+ import { create } from "@bufbuild/protobuf";
9
+ import { Code, ConnectError } from "@connectrpc/connect";
10
+ import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
11
+ import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
12
+ import { ConnectInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
13
+ import { ConnectPhase } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/status_pb";
14
+ import { StigmerError, wrapError } from "../gen/errors.js";
15
+ import {
16
+ connectAndWait,
17
+ ConnectStillRunningError,
18
+ type McpServerConnectLane,
19
+ } from "../mcpserver-connect.js";
20
+
21
+ const INPUT = create(ConnectInputSchema, { mcpServerId: "mcp-1", org: "test-org" });
22
+
23
+ function server(overrides?: {
24
+ phase?: ConnectPhase;
25
+ failureCode?: string;
26
+ failureMessage?: string;
27
+ warning?: string;
28
+ toolName?: string;
29
+ }): McpServer {
30
+ return create(McpServerSchema, {
31
+ metadata: { id: "mcp-1", name: "Test Server" },
32
+ status: {
33
+ ...(overrides?.toolName !== undefined
34
+ ? { discoveredCapabilities: { tools: [{ name: overrides.toolName }] } }
35
+ : {}),
36
+ connectStatus: {
37
+ phase: overrides?.phase ?? ConnectPhase.connecting,
38
+ workflowId: "stigmer/mcp-server/connect/mcp-1",
39
+ failureCode: overrides?.failureCode ?? "",
40
+ failureMessage: overrides?.failureMessage ?? "",
41
+ warning: overrides?.warning ?? "",
42
+ },
43
+ },
44
+ });
45
+ }
46
+
47
+ function unimplemented(): StigmerError {
48
+ return wrapError(new ConnectError("startConnect is not implemented", Code.Unimplemented));
49
+ }
50
+
51
+ const NEVER = () => new Promise<McpServer>(() => {});
52
+
53
+ describe("connectAndWait", () => {
54
+ it("resolves with the settled resource once connect_status reports success", async () => {
55
+ const polled = [
56
+ server({ phase: ConnectPhase.connecting }),
57
+ server({ phase: ConnectPhase.succeeded, toolName: "search_code" }),
58
+ ];
59
+ const lane: McpServerConnectLane = {
60
+ startConnect: async () => server(),
61
+ connect: NEVER,
62
+ get: async () => polled.shift() ?? server({ phase: ConnectPhase.succeeded }),
63
+ };
64
+
65
+ const settled = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 });
66
+ expect(settled.status?.connectStatus?.phase).toBe(ConnectPhase.succeeded);
67
+ expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
68
+ });
69
+
70
+ it("surfaces the CONNECTING snapshot (dead-runner warning) via onStarted", async () => {
71
+ const lane: McpServerConnectLane = {
72
+ startConnect: async () => server({ warning: "no runner appears to be polling the task queue" }),
73
+ connect: NEVER,
74
+ get: async () => server({ phase: ConnectPhase.succeeded }),
75
+ };
76
+
77
+ let warning = "";
78
+ await connectAndWait(lane, INPUT, {
79
+ pollIntervalMs: 1,
80
+ onStarted: (started) => {
81
+ warning = started.status?.connectStatus?.warning ?? "";
82
+ },
83
+ });
84
+ expect(warning).toContain("no runner");
85
+ });
86
+
87
+ it("rehydrates a failed operation into the classification the blocking RPC would have thrown", async () => {
88
+ const lane: McpServerConnectLane = {
89
+ startConnect: async () => server(),
90
+ connect: NEVER,
91
+ get: async () =>
92
+ server({
93
+ phase: ConnectPhase.failed,
94
+ failureCode: "FailedPrecondition",
95
+ failureMessage: "connect failed for MCP server 'Test Server': missing credentials",
96
+ }),
97
+ };
98
+
99
+ const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 }).catch((e: unknown) => e);
100
+ expect(err).toBeInstanceOf(StigmerError);
101
+ const stigmerErr = err as StigmerError;
102
+ // Byte-parity with the blocking lane: same code mapping, same raw message.
103
+ expect(stigmerErr.code).toBe("failed-precondition");
104
+ expect(stigmerErr.message).toBe("connect failed for MCP server 'Test Server': missing credentials");
105
+ });
106
+
107
+ it("maps an unknown failure_code to the unknown classification instead of crashing", async () => {
108
+ const lane: McpServerConnectLane = {
109
+ startConnect: async () => server(),
110
+ connect: NEVER,
111
+ get: async () =>
112
+ server({
113
+ phase: ConnectPhase.failed,
114
+ failureCode: "SomeFutureCode",
115
+ failureMessage: "boom",
116
+ }),
117
+ };
118
+
119
+ const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 }).catch((e: unknown) => e);
120
+ expect((err as StigmerError).code).toBe("unknown");
121
+ expect((err as StigmerError).message).toBe("boom");
122
+ });
123
+
124
+ it("falls back to the blocking connect when the backend answers UNIMPLEMENTED", async () => {
125
+ let blockingCalled = false;
126
+ const lane: McpServerConnectLane = {
127
+ startConnect: async () => {
128
+ throw unimplemented();
129
+ },
130
+ connect: async () => {
131
+ blockingCalled = true;
132
+ return server({ phase: ConnectPhase.succeeded, toolName: "search_code" });
133
+ },
134
+ get: NEVER,
135
+ };
136
+
137
+ const settled = await connectAndWait(lane, INPUT);
138
+ expect(blockingCalled).toBe(true);
139
+ expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
140
+ });
141
+
142
+ it("propagates non-UNIMPLEMENTED start failures untouched", async () => {
143
+ const startFailure = wrapError(new ConnectError("no such server", Code.NotFound));
144
+ const lane: McpServerConnectLane = {
145
+ startConnect: async () => {
146
+ throw startFailure;
147
+ },
148
+ connect: NEVER,
149
+ get: NEVER,
150
+ };
151
+
152
+ await expect(connectAndWait(lane, INPUT)).rejects.toBe(startFailure);
153
+ });
154
+
155
+ it("throws ConnectStillRunningError when the deadline elapses while CONNECTING", async () => {
156
+ const lane: McpServerConnectLane = {
157
+ startConnect: async () => server(),
158
+ connect: NEVER,
159
+ get: async () => server({ phase: ConnectPhase.connecting }),
160
+ };
161
+
162
+ const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1, deadlineMs: 20 }).catch(
163
+ (e: unknown) => e,
164
+ );
165
+ expect(err).toBeInstanceOf(ConnectStillRunningError);
166
+ expect((err as ConnectStillRunningError).mcpServerId).toBe("mcp-1");
167
+ });
168
+
169
+ it("bounds the blocking fallback with the same still-running semantics (soft, non-cancelling)", async () => {
170
+ const lane: McpServerConnectLane = {
171
+ startConnect: async () => {
172
+ throw unimplemented();
173
+ },
174
+ connect: NEVER,
175
+ get: NEVER,
176
+ };
177
+
178
+ const err = await connectAndWait(lane, INPUT, { deadlineMs: 20 }).catch((e: unknown) => e);
179
+ expect(err).toBeInstanceOf(ConnectStillRunningError);
180
+ });
181
+ });
@@ -0,0 +1,219 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { create, toJson } from "@bufbuild/protobuf";
3
+ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
4
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
+ import {
6
+ OrganizationSchema,
7
+ type Organization,
8
+ } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
9
+ import { OrganizationSpecSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/spec_pb";
10
+ import { ManagementMode } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/enum_pb";
11
+ import {
12
+ IdentityAccountSchema,
13
+ type IdentityAccount,
14
+ } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
15
+ import { IdentityAccountSpecSchema } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/spec_pb";
16
+ import { IdentityAccountProvisioningMode } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/enum_pb";
17
+ import { buildOrganizationProto } from "../gen/organization";
18
+ import { buildIdentityAccountProto } from "../gen/identityaccount";
19
+ import {
20
+ toOrganizationUpdateInput,
21
+ toIdentityAccountUpdateInput,
22
+ } from "../update-input";
23
+
24
+ /**
25
+ * Update RPCs are full-spec replacements, so a complete mapper must
26
+ * round-trip EVERY mutable field of a loaded resource through the generated
27
+ * builder without loss. These tests pin that contract: fully-populated
28
+ * resource → mapper → builder → spec (as JSON, defaults omitted) deep-equals
29
+ * the original. If a mapper drops a field, the wipe-bug class is back.
30
+ */
31
+
32
+ function fullOrganization(): Organization {
33
+ return create(OrganizationSchema, {
34
+ apiVersion: "tenancy.stigmer.ai/v1",
35
+ kind: "Organization",
36
+ metadata: {
37
+ id: "acme",
38
+ name: "Acme Corp",
39
+ slug: "acme",
40
+ org: "acme",
41
+ labels: { tier: "gold" },
42
+ visibility: ApiResourceVisibility.visibility_private,
43
+ },
44
+ spec: {
45
+ description: "We make everything.",
46
+ logoUrl: "https://acme.example/logo.png",
47
+ managementMode: ManagementMode.self_managed,
48
+ identityProviderRef: {
49
+ org: "acme",
50
+ slug: "acme-okta",
51
+ kind: ApiResourceKind.identity_provider,
52
+ },
53
+ externalOrgId: "ext-org-1",
54
+ isPersonal: true,
55
+ preferences: { standingContext: "We deploy to us-east-1." },
56
+ },
57
+ });
58
+ }
59
+
60
+ function fullIdentityAccount(): IdentityAccount {
61
+ return create(IdentityAccountSchema, {
62
+ apiVersion: "iam.stigmer.ai/v1",
63
+ kind: "IdentityAccount",
64
+ metadata: {
65
+ id: "ia-123",
66
+ name: "Ada Lovelace",
67
+ slug: "ada-lovelace",
68
+ org: "acme",
69
+ labels: { team: "platform" },
70
+ visibility: ApiResourceVisibility.visibility_private,
71
+ },
72
+ spec: {
73
+ idpId: "auth0|abc123",
74
+ email: "ada@acme.example",
75
+ firstName: "Ada",
76
+ lastName: "Lovelace",
77
+ pictureUrl: "https://acme.example/ada.png",
78
+ isMachineAccount: true,
79
+ provisioningMode: IdentityAccountProvisioningMode.federated,
80
+ identityProviderRef: { org: "acme", slug: "acme-okta" },
81
+ preferences: {
82
+ standingContext: "Keep answers terse.",
83
+ defaultHarness: "cursor",
84
+ defaultNativeModel: "claude-sonnet-4.6",
85
+ defaultCursorModel: "composer-2.5",
86
+ },
87
+ },
88
+ });
89
+ }
90
+
91
+ describe("toOrganizationUpdateInput", () => {
92
+ it("round-trips a fully-populated organization spec through the builder", () => {
93
+ const org = fullOrganization();
94
+
95
+ const built = buildOrganizationProto(toOrganizationUpdateInput(org));
96
+
97
+ expect(toJson(OrganizationSpecSchema, built.spec!)).toEqual(
98
+ toJson(OrganizationSpecSchema, org.spec!),
99
+ );
100
+ expect(built.metadata?.name).toBe("Acme Corp");
101
+ expect(built.metadata?.slug).toBe("acme");
102
+ expect(built.metadata?.org).toBe("acme");
103
+ expect(built.metadata?.labels).toEqual({ tier: "gold" });
104
+ expect(built.metadata?.visibility).toBe(
105
+ ApiResourceVisibility.visibility_private,
106
+ );
107
+ });
108
+
109
+ it("preserves preferences when a caller overrides only profile fields (the wipe-bug class)", () => {
110
+ const org = fullOrganization();
111
+
112
+ const built = buildOrganizationProto({
113
+ ...toOrganizationUpdateInput(org),
114
+ description: "New description",
115
+ });
116
+
117
+ expect(built.spec?.preferences?.standingContext).toBe(
118
+ "We deploy to us-east-1.",
119
+ );
120
+ expect(built.spec?.description).toBe("New description");
121
+ expect(built.spec?.logoUrl).toBe("https://acme.example/logo.png");
122
+ });
123
+
124
+ it("maps an empty spec without inventing values", () => {
125
+ const org = create(OrganizationSchema, {
126
+ metadata: { name: "Bare", slug: "bare", org: "bare" },
127
+ spec: {},
128
+ });
129
+
130
+ const built = buildOrganizationProto(toOrganizationUpdateInput(org));
131
+
132
+ expect(toJson(OrganizationSpecSchema, built.spec!)).toEqual({});
133
+ });
134
+
135
+ it("falls back to the slug when metadata.org is empty", () => {
136
+ const org = create(OrganizationSchema, {
137
+ metadata: { name: "Bare", slug: "bare" },
138
+ });
139
+
140
+ expect(toOrganizationUpdateInput(org).org).toBe("bare");
141
+ });
142
+ });
143
+
144
+ describe("toIdentityAccountUpdateInput", () => {
145
+ it("round-trips a fully-populated identity account spec through the builder", () => {
146
+ const account = fullIdentityAccount();
147
+
148
+ const built = buildIdentityAccountProto(
149
+ toIdentityAccountUpdateInput(account),
150
+ );
151
+
152
+ expect(toJson(IdentityAccountSpecSchema, built.spec!)).toEqual(
153
+ toJson(IdentityAccountSpecSchema, account.spec!),
154
+ );
155
+ expect(built.metadata?.name).toBe("Ada Lovelace");
156
+ expect(built.metadata?.labels).toEqual({ team: "platform" });
157
+ });
158
+
159
+ it("carries org and slug — the update pipeline's fallback address", () => {
160
+ const input = toIdentityAccountUpdateInput(fullIdentityAccount());
161
+
162
+ expect(input.org).toBe("acme");
163
+ expect(input.slug).toBe("ada-lovelace");
164
+ });
165
+
166
+ it("preserves the rest of the spec when a caller overrides only preferences", () => {
167
+ const account = fullIdentityAccount();
168
+ const mapped = toIdentityAccountUpdateInput(account);
169
+
170
+ const built = buildIdentityAccountProto({
171
+ ...mapped,
172
+ preferences: { ...mapped.preferences, standingContext: "Prefer bullet points." },
173
+ });
174
+
175
+ expect(built.spec?.preferences?.standingContext).toBe(
176
+ "Prefer bullet points.",
177
+ );
178
+ expect(built.spec?.email).toBe("ada@acme.example");
179
+ expect(built.spec?.idpId).toBe("auth0|abc123");
180
+ expect(built.spec?.provisioningMode).toBe(
181
+ IdentityAccountProvisioningMode.federated,
182
+ );
183
+ });
184
+
185
+ it("preserves structured defaults when only standing context is edited (nested wipe-bug class)", () => {
186
+ const account = fullIdentityAccount();
187
+ const mapped = toIdentityAccountUpdateInput(account);
188
+
189
+ // The correct editor pattern for a nested message: spread the mapper's
190
+ // COMPLETE preferences and override only the edited field. A bare
191
+ // `preferences: { standingContext }` literal would wipe the structured
192
+ // defaults — the session-4 wipe bug recurring one level down.
193
+ const built = buildIdentityAccountProto({
194
+ ...mapped,
195
+ preferences: { ...mapped.preferences, standingContext: "Terser still." },
196
+ });
197
+
198
+ expect(built.spec?.preferences?.standingContext).toBe("Terser still.");
199
+ expect(built.spec?.preferences?.defaultHarness).toBe("cursor");
200
+ expect(built.spec?.preferences?.defaultNativeModel).toBe("claude-sonnet-4.6");
201
+ expect(built.spec?.preferences?.defaultCursorModel).toBe("composer-2.5");
202
+ });
203
+
204
+ it("clears standing context to wire-absent when the text is emptied", () => {
205
+ const account = fullIdentityAccount();
206
+ const mapped = toIdentityAccountUpdateInput(account);
207
+
208
+ const built = buildIdentityAccountProto({
209
+ ...mapped,
210
+ preferences: { ...mapped.preferences, standingContext: "" },
211
+ });
212
+
213
+ // Proto3 empty string is the field default — wire-identical to absent,
214
+ // which the server compose steps treat as "no preference declared".
215
+ expect(built.spec?.preferences?.standingContext ?? "").toBe("");
216
+ // Clearing one field never disturbs its siblings.
217
+ expect(built.spec?.preferences?.defaultHarness).toBe("cursor");
218
+ });
219
+ });
@@ -11,7 +11,7 @@ import { AgentExecutionCommandController } from "@stigmer/protos/ai/stigmer/agen
11
11
  import { InteractionMode, ApprovalMode, ServiceTier } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
12
12
  import { AgentExecutionIdSchema, AgentExecutionUpdateStatusInputSchema, UpdateStatusResponseSchema, SubmitApprovalInputSchema, SubmitFileDecisionInputSchema, CancelAgentExecutionInputSchema, TerminateAgentExecutionInputSchema, RecoverAgentExecutionInputSchema, PauseAgentExecutionInputSchema, ResumeAgentExecutionInputSchema, UploadAttachmentRequestSchema, UploadAttachmentResponseSchema, ListAgentExecutionsRequestSchema, AgentExecutionListSchema, ListAgentExecutionsBySessionRequestSchema, GetArtifactDownloadUrlRequestSchema, GetArtifactDownloadUrlResponseSchema, GetArtifactContentRequestSchema, GetArtifactContentResponseSchema, GetExecutionUsageReportInputSchema, GetExecutionUsageReportOutputSchema, GetSessionUsageReportInputSchema, GetSessionUsageReportOutputSchema, GetAgentUsageReportInputSchema, GetAgentUsageReportOutputSchema, GetOrgUsageReportInputSchema, GetOrgUsageReportOutputSchema, GetAgentExecutionSummaryRequestSchema, AgentExecutionSummarySchema, type AgentExecutionUpdateStatusInput, type UpdateStatusResponse, type SubmitApprovalInput, type SubmitFileDecisionInput, type CancelAgentExecutionInput, type TerminateAgentExecutionInput, type RecoverAgentExecutionInput, type PauseAgentExecutionInput, type ResumeAgentExecutionInput, type UploadAttachmentRequest, type UploadAttachmentResponse, type ListAgentExecutionsRequest, type AgentExecutionList, type ListAgentExecutionsBySessionRequest, type GetArtifactDownloadUrlRequest, type GetArtifactDownloadUrlResponse, type GetArtifactContentRequest, type GetArtifactContentResponse, type GetExecutionUsageReportInput, type GetExecutionUsageReportOutput, type GetSessionUsageReportInput, type GetSessionUsageReportOutput, type GetAgentUsageReportInput, type GetAgentUsageReportOutput, type GetOrgUsageReportInput, type GetOrgUsageReportOutput, type GetAgentExecutionSummaryRequest, type AgentExecutionSummary } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
13
13
  import { AgentExecutionQueryController } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/query_pb";
14
- import { AgentExecutionSpecSchema, ContextManagementConfigSchema, ExecutionConfigSchema, AttachmentSchema, ConversationCatchupSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
14
+ import { AgentExecutionSpecSchema, ContextManagementConfigSchema, ExecutionConfigSchema, AttachmentSchema, ConversationCatchupSchema, DeclaredPreferencesSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
15
15
  import { ExecutionValueSchema } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/spec_pb";
16
16
  import { Harness, CursorMode, ExecutionTarget, GitWriteBackMode } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
17
17
  import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
@@ -192,6 +192,7 @@ export interface AgentExecutionInput {
192
192
  activityTaskQueue?: string;
193
193
  supersedesExecutionId?: string;
194
194
  conversationCatchup?: ConversationCatchupInput;
195
+ declaredPreferences?: DeclaredPreferencesInput;
195
196
  }
196
197
 
197
198
  /** SDK input type for SessionSpec. */
@@ -286,6 +287,12 @@ export interface ConversationCatchupInput {
286
287
  windowEnd?: Date | string;
287
288
  }
288
289
 
290
+ /** SDK input type for DeclaredPreferences. */
291
+ export interface DeclaredPreferencesInput {
292
+ orgContext?: string;
293
+ userContext?: string;
294
+ }
295
+
289
296
  function buildGitRepoSourceProto(input: GitRepoSourceInput) {
290
297
  return Object.assign(create(GitRepoSourceSchema), stripUndefined({
291
298
  url: input.url,
@@ -392,6 +399,13 @@ function buildConversationCatchupProto(input: ConversationCatchupInput) {
392
399
  return msg;
393
400
  }
394
401
 
402
+ function buildDeclaredPreferencesProto(input: DeclaredPreferencesInput) {
403
+ return Object.assign(create(DeclaredPreferencesSchema), stripUndefined({
404
+ orgContext: input.orgContext,
405
+ userContext: input.userContext,
406
+ }));
407
+ }
408
+
395
409
  export function buildAgentExecutionProto(input: AgentExecutionInput): AgentExecution {
396
410
  const sessionSpec = input.sessionSpec ? buildSessionSpecProto(input.sessionSpec) : undefined;
397
411
  const executionConfig = input.executionConfig ? buildExecutionConfigProto(input.executionConfig) : undefined;
@@ -402,6 +416,7 @@ export function buildAgentExecutionProto(input: AgentExecutionInput): AgentExecu
402
416
  }
403
417
  const attachments = input.attachments?.map(buildAttachmentProto);
404
418
  const conversationCatchup = input.conversationCatchup ? buildConversationCatchupProto(input.conversationCatchup) : undefined;
419
+ const declaredPreferences = input.declaredPreferences ? buildDeclaredPreferencesProto(input.declaredPreferences) : undefined;
405
420
  return Object.assign(create(AgentExecutionSchema), {
406
421
  apiVersion: "agentic.stigmer.ai/v1",
407
422
  kind: "AgentExecution",
@@ -427,6 +442,7 @@ export function buildAgentExecutionProto(input: AgentExecutionInput): AgentExecu
427
442
  activityTaskQueue: input.activityTaskQueue,
428
443
  supersedesExecutionId: input.supersedesExecutionId,
429
444
  conversationCatchup,
445
+ declaredPreferences,
430
446
  })),
431
447
  }) as AgentExecution;
432
448
  }
package/src/gen/client.ts CHANGED
@@ -90,7 +90,7 @@ export { type AgentInput, type McpServerUsageInput, type ToolApprovalOverrideInp
90
90
  export { AgentChannelClient } from "./agentchannel.js";
91
91
  export { type AgentChannelInput, type SlackChannelConfigInput, type WhatsAppChannelConfigInput, type RunConfigInput } from "./agentchannel.js";
92
92
  export { AgentExecutionClient } from "./agentexecution.js";
93
- export { type AgentExecutionInput, type SessionSpecInput, type WorkspaceEntryInput, type WorkspaceSourceInput, type GitRepoSourceInput, type LocalPathSourceInput, type ExecutionConfigInput, type ContextManagementConfigInput, type AttachmentInput, type ConversationCatchupInput } from "./agentexecution.js";
93
+ export { type AgentExecutionInput, type SessionSpecInput, type WorkspaceEntryInput, type WorkspaceSourceInput, type GitRepoSourceInput, type LocalPathSourceInput, type ExecutionConfigInput, type ContextManagementConfigInput, type AttachmentInput, type ConversationCatchupInput, type DeclaredPreferencesInput } from "./agentexecution.js";
94
94
  export { AgentInstanceClient } from "./agentinstance.js";
95
95
  export { type AgentInstanceInput } from "./agentinstance.js";
96
96
  export { AgentShareClient } from "./agentshare.js";
@@ -108,7 +108,7 @@ export { type ExecutionContextInput } from "./executioncontext.js";
108
108
  export { IamPolicyClient } from "./iampolicy.js";
109
109
  export { type IamPolicyInput, type ApiResourceRefInput } from "./iampolicy.js";
110
110
  export { IdentityAccountClient } from "./identityaccount.js";
111
- export { type IdentityAccountInput } from "./identityaccount.js";
111
+ export { type IdentityAccountInput, type IdentityAccountPreferencesInput } from "./identityaccount.js";
112
112
  export { IdentityProviderClient } from "./identityprovider.js";
113
113
  export { type IdentityProviderInput } from "./identityprovider.js";
114
114
  export { InvitationClient } from "./invitation.js";
@@ -118,7 +118,7 @@ export { type McpServerInput, type StdioServerConfigInput, type HttpServerConfig
118
118
  export { OAuthAppClient } from "./oauthapp.js";
119
119
  export { type OAuthAppInput } from "./oauthapp.js";
120
120
  export { OrganizationClient } from "./organization.js";
121
- export { type OrganizationInput } from "./organization.js";
121
+ export { type OrganizationInput, type OrganizationPreferencesInput } from "./organization.js";
122
122
  export { PlatformClientClient } from "./platformclient.js";
123
123
  export { type PlatformClientInput } from "./platformclient.js";
124
124
  export { ProjectClient } from "./project.js";
@@ -15,7 +15,7 @@ import { IdentityAccountCommandController } from "@stigmer/protos/ai/stigmer/iam
15
15
  import { IdentityAccountProvisioningMode } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/enum_pb";
16
16
  import { IdentityAccountIdSchema, CreateFederatedAccountInputSchema, UpdateFederatedAccountInputSchema, DeprovisionFederatedAccountInputSchema, IdentityAccountEmailSchema, IdpIdSchema, ExternalSubLookupSchema, type CreateFederatedAccountInput, type UpdateFederatedAccountInput, type DeprovisionFederatedAccountInput, type IdentityAccountEmail, type ExternalSubLookup } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/io_pb";
17
17
  import { IdentityAccountQueryController } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/query_pb";
18
- import { IdentityAccountSpecSchema } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/spec_pb";
18
+ import { IdentityAccountSpecSchema, IdentityAccountPreferencesSchema } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/spec_pb";
19
19
 
20
20
  /** Provides operations on identityaccount resources. */
21
21
  export class IdentityAccountClient {
@@ -121,10 +121,29 @@ export interface IdentityAccountInput {
121
121
  isMachineAccount?: boolean;
122
122
  provisioningMode?: IdentityAccountProvisioningMode;
123
123
  identityProviderRef?: ResourceRef;
124
+ preferences?: IdentityAccountPreferencesInput;
125
+ }
126
+
127
+ /** SDK input type for IdentityAccountPreferences. */
128
+ export interface IdentityAccountPreferencesInput {
129
+ standingContext?: string;
130
+ defaultHarness?: string;
131
+ defaultNativeModel?: string;
132
+ defaultCursorModel?: string;
133
+ }
134
+
135
+ function buildIdentityAccountPreferencesProto(input: IdentityAccountPreferencesInput) {
136
+ return Object.assign(create(IdentityAccountPreferencesSchema), stripUndefined({
137
+ standingContext: input.standingContext,
138
+ defaultHarness: input.defaultHarness,
139
+ defaultNativeModel: input.defaultNativeModel,
140
+ defaultCursorModel: input.defaultCursorModel,
141
+ }));
124
142
  }
125
143
 
126
144
  export function buildIdentityAccountProto(input: IdentityAccountInput): IdentityAccount {
127
145
  const identityProviderRef = (input.identityProviderRef?.slug || input.identityProviderRef?.org) ? create(ApiResourceReferenceSchema, input.identityProviderRef) : undefined;
146
+ const preferences = input.preferences ? buildIdentityAccountPreferencesProto(input.preferences) : undefined;
128
147
  return Object.assign(create(IdentityAccountSchema), {
129
148
  apiVersion: "iam.stigmer.ai/v1",
130
149
  kind: "IdentityAccount",
@@ -144,6 +163,7 @@ export function buildIdentityAccountProto(input: IdentityAccountInput): Identity
144
163
  isMachineAccount: input.isMachineAccount,
145
164
  provisioningMode: input.provisioningMode,
146
165
  identityProviderRef,
166
+ preferences,
147
167
  })),
148
168
  }) as IdentityAccount;
149
169
  }
@@ -71,6 +71,12 @@ export class McpServerClient {
71
71
  } catch (e) { throw wrapError(e); }
72
72
  }
73
73
 
74
+ async startConnect(input: ConnectInput): Promise<McpServer> {
75
+ try {
76
+ return await this.command.startConnect(input);
77
+ } catch (e) { throw wrapError(e); }
78
+ }
79
+
74
80
  async initiateOAuthConnect(input: InitiateOAuthConnectInput): Promise<InitiateOAuthConnectOutput> {
75
81
  try {
76
82
  return await this.command.initiateOAuthConnect(input);
@@ -13,7 +13,7 @@ import { OAuthAppSchema, type OAuthApp } from "@stigmer/protos/ai/stigmer/iam/oa
13
13
  import { OAuthAppCommandController } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/command_pb";
14
14
  import { ListOAuthAppsByOrgInputSchema, OAuthAppsSchema, type ListOAuthAppsByOrgInput, type OAuthApps } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/io_pb";
15
15
  import { OAuthAppQueryController } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/query_pb";
16
- import { OAuthAppSpecSchema, VendorApprovalStatus } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
16
+ import { OAuthAppSpecSchema, VendorApprovalStatus, TokenEndpointAuthMethod } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
17
17
 
18
18
  /** Provides operations on oauthapp resources. */
19
19
  export class OAuthAppClient {
@@ -89,6 +89,7 @@ export interface OAuthAppInput {
89
89
  scopeParameterName?: string;
90
90
  vendorApprovalStatus?: VendorApprovalStatus;
91
91
  vendorApprovalDocsUrl?: string;
92
+ tokenEndpointAuthMethod?: TokenEndpointAuthMethod;
92
93
  }
93
94
 
94
95
  export function buildOAuthAppProto(input: OAuthAppInput): OAuthApp {
@@ -113,6 +114,7 @@ export function buildOAuthAppProto(input: OAuthAppInput): OAuthApp {
113
114
  scopeParameterName: input.scopeParameterName,
114
115
  vendorApprovalStatus: input.vendorApprovalStatus,
115
116
  vendorApprovalDocsUrl: input.vendorApprovalDocsUrl,
117
+ tokenEndpointAuthMethod: input.tokenEndpointAuthMethod,
116
118
  })),
117
119
  }) as OAuthApp;
118
120
  }
@@ -14,7 +14,7 @@ import { OrganizationCommandController } from "@stigmer/protos/ai/stigmer/tenanc
14
14
  import { ManagementMode } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/enum_pb";
15
15
  import { OrganizationIdSchema, OrganizationListSchema, OrganizationsSchema, OrganizationExternalLookupSchema, type OrganizationList, type Organizations, type OrganizationExternalLookup } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/io_pb";
16
16
  import { OrganizationQueryController } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/query_pb";
17
- import { OrganizationSpecSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/spec_pb";
17
+ import { OrganizationSpecSchema, OrganizationPreferencesSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/spec_pb";
18
18
 
19
19
  /** Provides operations on organization resources. */
20
20
  export class OrganizationClient {
@@ -88,10 +88,23 @@ export interface OrganizationInput {
88
88
  identityProviderRef?: ResourceRef;
89
89
  externalOrgId?: string;
90
90
  isPersonal?: boolean;
91
+ preferences?: OrganizationPreferencesInput;
92
+ }
93
+
94
+ /** SDK input type for OrganizationPreferences. */
95
+ export interface OrganizationPreferencesInput {
96
+ standingContext?: string;
97
+ }
98
+
99
+ function buildOrganizationPreferencesProto(input: OrganizationPreferencesInput) {
100
+ return Object.assign(create(OrganizationPreferencesSchema), stripUndefined({
101
+ standingContext: input.standingContext,
102
+ }));
91
103
  }
92
104
 
93
105
  export function buildOrganizationProto(input: OrganizationInput): Organization {
94
106
  const identityProviderRef = (input.identityProviderRef?.slug || input.identityProviderRef?.org) ? create(ApiResourceReferenceSchema, input.identityProviderRef) : undefined;
107
+ const preferences = input.preferences ? buildOrganizationPreferencesProto(input.preferences) : undefined;
95
108
  return Object.assign(create(OrganizationSchema), {
96
109
  apiVersion: "tenancy.stigmer.ai/v1",
97
110
  kind: "Organization",
@@ -109,6 +122,7 @@ export function buildOrganizationProto(input: OrganizationInput): Organization {
109
122
  identityProviderRef,
110
123
  externalOrgId: input.externalOrgId,
111
124
  isPersonal: input.isPersonal,
125
+ preferences,
112
126
  })),
113
127
  }) as Organization;
114
128
  }
@@ -104,10 +104,12 @@ export interface PlatformClientInput {
104
104
  autoGrantOnOrg?: boolean;
105
105
  autoGrantRole?: IamRole;
106
106
  allowedOrigins?: string[];
107
+ environmentRefs?: ResourceRef[];
107
108
  }
108
109
 
109
110
  export function buildPlatformClientProto(input: PlatformClientInput): PlatformClient {
110
111
  const expiresAt = input.expiresAt !== undefined ? toTimestamp(input.expiresAt) : undefined;
112
+ const environmentRefs = input.environmentRefs?.map(r => create(ApiResourceReferenceSchema, { ...r, kind: 53 }));
111
113
  return Object.assign(create(PlatformClientSchema), {
112
114
  apiVersion: "iam.stigmer.ai/v1",
113
115
  kind: "PlatformClient",
@@ -128,6 +130,7 @@ export function buildPlatformClientProto(input: PlatformClientInput): PlatformCl
128
130
  autoGrantOnOrg: input.autoGrantOnOrg,
129
131
  autoGrantRole: input.autoGrantRole,
130
132
  allowedOrigins: input.allowedOrigins,
133
+ environmentRefs,
131
134
  })),
132
135
  }) as PlatformClient;
133
136
  }
package/src/index.ts CHANGED
@@ -61,6 +61,12 @@ export {
61
61
  isResourceAvailable,
62
62
  } from "./resource-availability.js";
63
63
 
64
+ // Complete update-input mappers (full-spec-replace round-trip safety)
65
+ export {
66
+ toOrganizationUpdateInput,
67
+ toIdentityAccountUpdateInput,
68
+ } from "./update-input.js";
69
+
64
70
  // Authorization config and IAM role utilities
65
71
  export {
66
72
  getGrantableRoles,
@@ -235,6 +241,14 @@ export {
235
241
  type HttpServerConfigInput,
236
242
  type ToolApprovalPolicyInput,
237
243
  } from "./gen/mcpserver.js";
244
+ export {
245
+ connectAndWait,
246
+ ConnectStillRunningError,
247
+ CONNECT_POLL_INTERVAL_MS,
248
+ CONNECT_SETTLE_BOUND_MS,
249
+ type ConnectAndWaitOptions,
250
+ type McpServerConnectLane,
251
+ } from "./mcpserver-connect.js";
238
252
  export {
239
253
  OrganizationClient,
240
254
  type OrganizationInput,