@ornncompute/cli 0.2.20 → 0.2.22

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.
@@ -153,12 +153,12 @@ export const forecastListingsCapability = defineCapability({
153
153
  roles: ["user"],
154
154
  description: "List the next 48 hourly availability buckets for customer-visible compute listings.",
155
155
  mutation: "read",
156
- http: { method: "GET", path: "/v1/cli/compute/listings/forecast" },
156
+ http: { method: "GET", path: "/v1/workflows/commerce/listings/forecast" },
157
157
  slack: false,
158
158
  input: listingForecastInput,
159
159
  execute: async (ctx, input) => {
160
160
  const parsed = listingForecastInput.parse(input);
161
- return ctx.fetch(queryPath("/v1/cli/compute/listings/forecast", {
161
+ return ctx.fetch(queryPath("/v1/workflows/commerce/listings/forecast", {
162
162
  limit: parsed.limit?.toString(),
163
163
  cursor: parsed.cursor,
164
164
  }), { method: "GET" });
@@ -18,36 +18,42 @@ export declare const gtmDealListInput: z.ZodObject<{
18
18
  }, z.core.$strip>;
19
19
  export declare const gtmDealListCapability: import("../capability.ts").Capability<unknown, unknown>;
20
20
  export declare const gtmDealWriteInput: z.ZodObject<{
21
- listingId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"">]>>;
22
- currentBid: z.ZodOptional<z.ZodString>;
23
- confirm: z.ZodOptional<z.ZodBoolean>;
24
- customer: z.ZodString;
25
- owner: z.ZodString;
26
- supplier: z.ZodString;
27
- gpuType: z.ZodString;
28
21
  dealId: z.ZodOptional<z.ZodNumber>;
22
+ listingId: z.ZodOptional<z.ZodString>;
23
+ customer: z.ZodOptional<z.ZodString>;
24
+ owner: z.ZodOptional<z.ZodString>;
25
+ confirm: z.ZodOptional<z.ZodBoolean>;
29
26
  }, z.core.$strip>;
30
27
  export declare const gtmDealWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
31
28
  export declare const gtmCommentListInput: z.ZodObject<{
32
29
  dealId: z.ZodOptional<z.ZodNumber>;
33
30
  companyId: z.ZodOptional<z.ZodNumber>;
31
+ taskId: z.ZodOptional<z.ZodNumber>;
32
+ field: z.ZodOptional<z.ZodEnum<{
33
+ name: "name";
34
+ notes: "notes";
35
+ owner_tags: "owner_tags";
36
+ tickets: "tickets";
37
+ }>>;
34
38
  }, z.core.$strip>;
35
39
  export declare const gtmCommentListCapability: import("../capability.ts").Capability<unknown, unknown>;
36
40
  export declare const gtmCommentWriteInput: z.ZodObject<{
37
- dealId: z.ZodOptional<z.ZodNumber>;
38
- companyId: z.ZodOptional<z.ZodNumber>;
39
41
  commentId: z.ZodOptional<z.ZodNumber>;
40
42
  parentId: z.ZodOptional<z.ZodNumber>;
41
43
  body: z.ZodString;
42
44
  bid: z.ZodDefault<z.ZodBoolean>;
43
45
  confirm: z.ZodOptional<z.ZodBoolean>;
46
+ dealId: z.ZodOptional<z.ZodNumber>;
47
+ companyId: z.ZodOptional<z.ZodNumber>;
48
+ taskId: z.ZodOptional<z.ZodNumber>;
49
+ field: z.ZodOptional<z.ZodEnum<{
50
+ name: "name";
51
+ notes: "notes";
52
+ owner_tags: "owner_tags";
53
+ tickets: "tickets";
54
+ }>>;
44
55
  }, z.core.$strip>;
45
56
  export declare const gtmCommentWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
46
- export declare const gtmMentionDismissInput: z.ZodObject<{
47
- commentId: z.ZodNumber;
48
- confirm: z.ZodOptional<z.ZodBoolean>;
49
- }, z.core.$strip>;
50
- export declare const gtmMentionDismissCapability: import("../capability.ts").Capability<unknown, unknown>;
51
57
  export declare const gtmWorkspaceShowInput: z.ZodObject<{}, z.core.$strip>;
52
58
  export declare const gtmWorkspaceShowCapability: import("../capability.ts").Capability<unknown, unknown>;
53
59
  export declare const gtmTaskListInput: z.ZodObject<{
@@ -74,11 +80,6 @@ export declare const gtmCompanyDeleteInput: z.ZodObject<{
74
80
  confirm: z.ZodOptional<z.ZodBoolean>;
75
81
  }, z.core.$strip>;
76
82
  export declare const gtmCompanyDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
77
- export declare const gtmDealDeleteInput: z.ZodObject<{
78
- [x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
79
- confirm: z.ZodOptional<z.ZodBoolean>;
80
- }, z.core.$strip>;
81
- export declare const gtmDealDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
82
83
  export declare const gtmCommentDeleteInput: z.ZodObject<{
83
84
  [x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
84
85
  confirm: z.ZodOptional<z.ZodBoolean>;
@@ -97,7 +98,13 @@ export declare const gtmTaskDeleteCapability: import("../capability.ts").Capabil
97
98
  */
98
99
  export declare const gtmListingListInput: z.ZodObject<{
99
100
  gpuType: z.ZodOptional<z.ZodString>;
101
+ state: z.ZodOptional<z.ZodEnum<{
102
+ delisted: "delisted";
103
+ available: "available";
104
+ internal: "internal";
105
+ }>>;
100
106
  limit: z.ZodOptional<z.ZodNumber>;
107
+ cursor: z.ZodOptional<z.ZodString>;
101
108
  }, z.core.$strip>;
102
109
  export declare const gtmListingListCapability: import("../capability.ts").Capability<unknown, unknown>;
103
110
  export declare const gtmListingUpdateInput: z.ZodObject<{
@@ -110,8 +117,8 @@ export declare const gtmListingUpdateInput: z.ZodObject<{
110
117
  capacityNodes: z.ZodOptional<z.ZodNumber>;
111
118
  state: z.ZodOptional<z.ZodEnum<{
112
119
  delisted: "delisted";
113
- draft: "draft";
114
- listed: "listed";
120
+ available: "available";
121
+ internal: "internal";
115
122
  }>>;
116
123
  confirm: z.ZodOptional<z.ZodBoolean>;
117
124
  }, z.core.$strip>;
@@ -120,42 +127,6 @@ export declare const gtmTaskActivityListInput: z.ZodObject<{
120
127
  taskId: z.ZodNumber;
121
128
  }, z.core.$strip>;
122
129
  export declare const gtmTaskActivityListCapability: import("../capability.ts").Capability<unknown, unknown>;
123
- export declare const gtmTaskActivityWriteInput: z.ZodObject<{
124
- taskId: z.ZodNumber;
125
- body: z.ZodString;
126
- parentId: z.ZodOptional<z.ZodNumber>;
127
- confirm: z.ZodOptional<z.ZodBoolean>;
128
- }, z.core.$strip>;
129
- export declare const gtmTaskActivityWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
130
- export declare const gtmCellCommentListInput: z.ZodObject<{
131
- companyId: z.ZodNumber;
132
- field: z.ZodEnum<{
133
- name: "name";
134
- notes: "notes";
135
- owner_tags: "owner_tags";
136
- tickets: "tickets";
137
- }>;
138
- }, z.core.$strip>;
139
- export declare const gtmCellCommentListCapability: import("../capability.ts").Capability<unknown, unknown>;
140
- export declare const gtmCellCommentWriteInput: z.ZodObject<{
141
- companyId: z.ZodOptional<z.ZodNumber>;
142
- field: z.ZodOptional<z.ZodEnum<{
143
- name: "name";
144
- notes: "notes";
145
- owner_tags: "owner_tags";
146
- tickets: "tickets";
147
- }>>;
148
- commentId: z.ZodOptional<z.ZodNumber>;
149
- parentId: z.ZodOptional<z.ZodNumber>;
150
- body: z.ZodString;
151
- confirm: z.ZodOptional<z.ZodBoolean>;
152
- }, z.core.$strip>;
153
- export declare const gtmCellCommentWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
154
- export declare const gtmCellCommentDeleteInput: z.ZodObject<{
155
- [x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
156
- confirm: z.ZodOptional<z.ZodBoolean>;
157
- }, z.core.$strip>;
158
- export declare const gtmCellCommentDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
159
130
  /**
160
131
  * Bulk owner-tag reassignment. This is the one GTM edit that is genuinely
161
132
  * N-at-a-time — a book of companies moving to a new owner — and doing it one
@@ -59,12 +59,6 @@ export const gtmCompanyWriteCapability = defineStaffMcpCapability({
59
59
  : "/internal/v1/gtm/companies", { method: parsed.companyId ? "PATCH" : "POST", body });
60
60
  },
61
61
  });
62
- const dealFields = {
63
- customer: z.string().min(1),
64
- owner: z.string().min(1),
65
- supplier: z.string().min(1),
66
- gpuType: z.string().min(1),
67
- };
68
62
  export const gtmDealListInput = z.object({ ...listFilterFields });
69
63
  export const gtmDealListCapability = defineStaffMcpCapability({
70
64
  id: "gtm.deal.list",
@@ -80,34 +74,40 @@ export const gtmDealListCapability = defineStaffMcpCapability({
80
74
  });
81
75
  export const gtmDealWriteInput = z.object({
82
76
  dealId: z.number().int().positive().optional(),
83
- ...dealFields,
84
- /** The negotiation's one link to Commerce. "" clears it. */
85
- listingId: z.union([z.string().uuid(), z.literal("")]).optional(),
86
- /** The negotiation's own bid. "" clears it. Never writes the listing. */
87
- currentBid: z.string().optional(),
77
+ /** Required to create: a deal is that Commerce listing's GTM record. Cannot change. */
78
+ listingId: z.string().uuid().optional(),
79
+ /** Optional extras, unspecified until filled in. "" clears one. */
80
+ customer: z.string().optional(),
81
+ owner: z.string().optional(),
88
82
  confirm: z.boolean().optional(),
89
83
  });
90
84
  export const gtmDealWriteCapability = defineStaffMcpCapability({
91
85
  id: "gtm.deal.write",
92
86
  domain: "gtm",
93
87
  roles: ["reviewer", "admin"],
94
- description: 'GTM staff only: create a negotiation, or replace it when dealId is supplied. The customer also associates it to that company. listingId links it to one Commerce listing and is the only connection between the two; currentBid records what the buyer offered and never writes the listing. Pass "" to clear either. Requires confirm: true.',
88
+ description: 'GTM staff only: a deal is the GTM record of one Commerce listing, and its comments hang off it. Create one with listingId (one deal per listing; a second is a conflict), or update one with dealId. customer and owner are optional; on update only the fields you pass change, and "" clears one. The listing cannot change. A bid is a comment with bid: true (see comment_write); the newest one is the current bid. Requires confirm: true.',
95
89
  mutation: "preview-confirm",
96
90
  http: { method: "POST", path: "/internal/v1/gtm/deals" },
97
91
  input: gtmDealWriteInput,
98
92
  execute: async (ctx, input) => {
99
93
  const parsed = gtmDealWriteInput.parse(input);
100
- const body = {
101
- customer: parsed.customer,
102
- owner: parsed.owner,
103
- supplier: parsed.supplier,
104
- gpu_type: parsed.gpuType,
105
- };
106
- // Omitted leaves the stored value alone; "" clears it.
107
- if (parsed.listingId !== undefined)
108
- body.listing_id = parsed.listingId;
109
- if (parsed.currentBid !== undefined)
110
- body.current_bid = parsed.currentBid;
94
+ if (parsed.dealId === undefined && parsed.listingId === undefined) {
95
+ throw new Error("listingId is required to create a deal");
96
+ }
97
+ if (parsed.dealId !== undefined && parsed.listingId !== undefined) {
98
+ throw new Error("a deal's listing cannot change; omit listingId when updating");
99
+ }
100
+ // Only what the caller passed is sent: omitted is unspecified on create
101
+ // and untouched on update; "" clears.
102
+ const body = {};
103
+ for (const [key, value] of [
104
+ ["listing_id", parsed.listingId],
105
+ ["customer", parsed.customer],
106
+ ["owner", parsed.owner],
107
+ ]) {
108
+ if (value !== undefined)
109
+ body[key] = value;
110
+ }
111
111
  if (!ctx.confirmed) {
112
112
  return preview("gtm.deal.write", { dealId: parsed.dealId, ...body });
113
113
  }
@@ -116,26 +116,33 @@ export const gtmDealWriteCapability = defineStaffMcpCapability({
116
116
  : "/internal/v1/gtm/deals", { method: parsed.dealId ? "PATCH" : "POST", body });
117
117
  },
118
118
  });
119
- export const gtmCommentListInput = z.object({
119
+ /** Company fields that carry their own side thread. */
120
+ const companyField = z.enum(["name", "owner_tags", "notes", "tickets"]);
121
+ /** A thread hangs off one deal, one company (or one of its fields), or one ticket. */
122
+ const commentThread = {
120
123
  dealId: z.number().int().positive().optional(),
121
124
  companyId: z.number().int().positive().optional(),
122
- });
125
+ taskId: z.number().int().positive().optional(),
126
+ /** With companyId: that field's side thread instead of the main one. */
127
+ field: companyField.optional(),
128
+ };
129
+ export const gtmCommentListInput = z.object(commentThread);
123
130
  export const gtmCommentListCapability = defineStaffMcpCapability({
124
131
  id: "gtm.comment.list",
125
132
  domain: "gtm",
126
133
  roles: ["reviewer", "admin"],
127
- description: "GTM staff only: list the plaintext comment thread for one deal or one company, replies included. A reply carries parent_id.",
134
+ description: "GTM staff only: list the plaintext comment thread for one deal, one company (or one company field with field), or one ticket (taskId), replies included. A reply carries parent_id.",
128
135
  mutation: "read",
129
136
  http: { method: "GET", path: "/internal/v1/gtm/deals/{dealId}/comments" },
130
137
  input: gtmCommentListInput,
131
138
  execute: (ctx, input) => {
132
139
  const parsed = gtmCommentListInput.parse(input);
133
- return ctx.fetch(commentThreadPath(parsed), { method: "GET" });
140
+ const query = parsed.field ? `?field=${encodeURIComponent(parsed.field)}` : "";
141
+ return ctx.fetch(commentThreadPath(parsed) + query, { method: "GET" });
134
142
  },
135
143
  });
136
144
  export const gtmCommentWriteInput = z.object({
137
- dealId: z.number().int().positive().optional(),
138
- companyId: z.number().int().positive().optional(),
145
+ ...commentThread,
139
146
  commentId: z.number().int().positive().optional(),
140
147
  /** Set to reply to an existing comment. Threads are one level deep. */
141
148
  parentId: z.number().int().positive().optional(),
@@ -147,14 +154,14 @@ export const gtmCommentWriteCapability = defineStaffMcpCapability({
147
154
  id: "gtm.comment.write",
148
155
  domain: "gtm",
149
156
  roles: ["reviewer", "admin"],
150
- description: "GTM staff only: append a plaintext comment to a deal or a company, reply to one with parentId, or replace one when commentId is supplied. bid=true adds only the BID tag and changes no other behavior. Mention a teammate by writing @name in the body. Requires confirm: true.",
157
+ description: "GTM staff only: append a plaintext comment to a deal, a company (or one company field with field), or a ticket (taskId); reply to one with parentId, or replace one when commentId is supplied. bid=true adds only the BID tag and changes no other behavior. Mention a teammate by writing @name in the body. Requires confirm: true.",
151
158
  mutation: "preview-confirm",
152
159
  http: { method: "POST", path: "/internal/v1/gtm/deals/{dealId}/comments" },
153
160
  input: gtmCommentWriteInput,
154
161
  execute: async (ctx, input) => {
155
162
  const parsed = gtmCommentWriteInput.parse(input);
156
- if (!parsed.commentId && !parsed.dealId && !parsed.companyId) {
157
- throw new Error("dealId or companyId is required when creating a comment");
163
+ if (!parsed.commentId && !parsed.dealId && !parsed.companyId && !parsed.taskId) {
164
+ throw new Error("dealId, companyId or taskId is required when creating a comment");
158
165
  }
159
166
  const body = {
160
167
  body: parsed.body,
@@ -163,10 +170,14 @@ export const gtmCommentWriteCapability = defineStaffMcpCapability({
163
170
  if (parsed.parentId) {
164
171
  body.parent_id = parsed.parentId;
165
172
  }
173
+ if (parsed.field) {
174
+ body.field = parsed.field;
175
+ }
166
176
  if (!ctx.confirmed) {
167
177
  return preview("gtm.comment.write", {
168
178
  dealId: parsed.dealId,
169
179
  companyId: parsed.companyId,
180
+ taskId: parsed.taskId,
170
181
  commentId: parsed.commentId,
171
182
  ...body,
172
183
  });
@@ -181,39 +192,20 @@ function commentThreadPath(parsed) {
181
192
  if (parsed.companyId) {
182
193
  return `/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/comments`;
183
194
  }
195
+ if (parsed.taskId) {
196
+ return `/internal/v1/gtm/tasks/${seg(String(parsed.taskId))}/comments`;
197
+ }
184
198
  if (parsed.dealId) {
185
199
  return `/internal/v1/gtm/deals/${seg(String(parsed.dealId))}/comments`;
186
200
  }
187
- throw new Error("dealId or companyId is required");
201
+ throw new Error("dealId, companyId or taskId is required");
188
202
  }
189
- export const gtmMentionDismissInput = z.object({
190
- commentId: z.number().int().positive(),
191
- confirm: z.boolean().optional(),
192
- });
193
- export const gtmMentionDismissCapability = defineStaffMcpCapability({
194
- id: "gtm.mention.dismiss",
195
- domain: "gtm",
196
- roles: ["reviewer", "admin"],
197
- description: "GTM staff only: dismiss one mention for the signed-in user. The comment is untouched and everyone else still sees it. Requires confirm: true.",
198
- mutation: "preview-confirm",
199
- http: { method: "POST", path: "/internal/v1/gtm/comments/{commentId}/dismiss" },
200
- input: gtmMentionDismissInput,
201
- execute: async (ctx, input) => {
202
- const parsed = gtmMentionDismissInput.parse(input);
203
- if (!ctx.confirmed) {
204
- return preview("gtm.mention.dismiss", { commentId: parsed.commentId });
205
- }
206
- return ctx.fetch(`/internal/v1/gtm/comments/${seg(String(parsed.commentId))}/dismiss`, {
207
- method: "POST",
208
- });
209
- },
210
- });
211
203
  export const gtmWorkspaceShowInput = z.object({});
212
204
  export const gtmWorkspaceShowCapability = defineStaffMcpCapability({
213
205
  id: "gtm.workspace.show",
214
206
  domain: "gtm",
215
207
  roles: ["reviewer", "admin"],
216
- description: "GTM staff only: show companies tagged to the signed-in user, deals they own, undismissed mentions of them, and tickets assigned to them.",
208
+ description: "GTM staff only: show companies tagged to the signed-in user, deals they own, mentions of them (answered once they comment in that thread), and tickets assigned to them.",
217
209
  mutation: "read",
218
210
  http: { method: "GET", path: "/internal/v1/gtm/me" },
219
211
  input: gtmWorkspaceShowInput,
@@ -308,9 +300,6 @@ function gtmDeleteCapability(entity, idKey, route, consequence) {
308
300
  const companyDelete = gtmDeleteCapability("company", "companyId", "/internal/v1/gtm/companies", "Refused while the company still has deals or tickets.");
309
301
  export const gtmCompanyDeleteInput = companyDelete.input;
310
302
  export const gtmCompanyDeleteCapability = companyDelete.capability;
311
- const dealDelete = gtmDeleteCapability("deal", "dealId", "/internal/v1/gtm/deals", "Its comments are deleted with it; tickets that referenced it are kept.");
312
- export const gtmDealDeleteInput = dealDelete.input;
313
- export const gtmDealDeleteCapability = dealDelete.capability;
314
303
  const commentDelete = gtmDeleteCapability("comment", "commentId", "/internal/v1/gtm/comments", "Removes only that comment.");
315
304
  export const gtmCommentDeleteInput = commentDelete.input;
316
305
  export const gtmCommentDeleteCapability = commentDelete.capability;
@@ -325,13 +314,16 @@ export const gtmTaskDeleteCapability = taskDelete.capability;
325
314
  */
326
315
  export const gtmListingListInput = z.object({
327
316
  gpuType: z.string().optional(),
328
- limit: z.number().int().positive().max(200).optional(),
317
+ state: z.enum(["available", "internal", "delisted"]).optional(),
318
+ /** Commerce serves at most 100 per page; pass nextCursor back for the rest. */
319
+ limit: z.number().int().positive().max(100).optional(),
320
+ cursor: z.string().optional(),
329
321
  });
330
322
  export const gtmListingListCapability = defineStaffMcpCapability({
331
323
  id: "gtm.listing.list",
332
324
  domain: "gtm",
333
325
  roles: ["reviewer", "admin"],
334
- description: "GTM staff only: list Commerce listings to apply a bid against, optionally filtered by GPU type. Read-only; this is Commerce's catalog, not CRM data.",
326
+ description: "GTM staff only: list Commerce listings (each can carry one GTM deal), optionally filtered by GPU type or state. Returns at most 100 per call with nextCursor; pass it back as cursor for the next page. Includes provider (staff-only). Read-only; this is Commerce's catalog, not CRM data.",
335
327
  mutation: "read",
336
328
  http: { method: "GET", path: "/internal/v1/listings" },
337
329
  input: gtmListingListInput,
@@ -340,10 +332,17 @@ export const gtmListingListCapability = defineStaffMcpCapability({
340
332
  const parts = [`limit=${encodeURIComponent(String(parsed.limit ?? 50))}`];
341
333
  if (parsed.gpuType)
342
334
  parts.push(`q=${encodeURIComponent(parsed.gpuType)}`);
335
+ if (parsed.state)
336
+ parts.push(`state=${encodeURIComponent(parsed.state)}`);
337
+ if (parsed.cursor)
338
+ parts.push(`cursor=${encodeURIComponent(parsed.cursor)}`);
343
339
  const page = (await ctx.fetch(`/internal/v1/listings?${parts.join("&")}`, {
344
340
  method: "GET",
345
341
  }));
346
- return { listings: (page.listings ?? []).map(publicListing) };
342
+ return {
343
+ listings: (page.listings ?? []).map(staffListing),
344
+ nextCursor: page.nextCursor ?? null,
345
+ };
347
346
  },
348
347
  });
349
348
  export const gtmListingUpdateInput = z.object({
@@ -355,7 +354,7 @@ export const gtmListingUpdateInput = z.object({
355
354
  allowsDepositPlan: z.boolean().optional(),
356
355
  downPaymentPct: z.string().optional(),
357
356
  capacityNodes: z.number().int().positive().optional(),
358
- state: z.enum(["draft", "listed", "delisted"]).optional(),
357
+ state: z.enum(["available", "internal", "delisted"]).optional(),
359
358
  confirm: z.boolean().optional(),
360
359
  });
361
360
  export const gtmListingUpdateCapability = defineStaffMcpCapability({
@@ -383,9 +382,14 @@ export const gtmListingUpdateCapability = defineStaffMcpCapability({
383
382
  * region are allowed; operator ids and provider names are not. Every listing
384
383
  * this module returns -- list, update, and the apply result -- goes through it.
385
384
  */
386
- function publicListing(raw) {
385
+ /**
386
+ * GTM tools are staff-only, behind the reviewer boundary, so they keep the
387
+ * listing's provider -- a deal's supplier is its listing's. The operator
388
+ * record's own id and legal name still stay out.
389
+ */
390
+ function staffListing(raw) {
387
391
  const listing = raw;
388
- const { operatorId: _operatorId, operatorName: _operatorName, provider: _provider, ...safe } = listing;
392
+ const { operatorId: _operatorId, operatorName: _operatorName, ...safe } = listing;
389
393
  return safe;
390
394
  }
391
395
  /**
@@ -404,7 +408,7 @@ async function patchListing(ctx, listingId, body) {
404
408
  method: "PATCH",
405
409
  body: { ...body, version: current.version },
406
410
  });
407
- return publicListing(updated);
411
+ return staffListing(updated);
408
412
  }
409
413
  function listingPatchBody(parsed) {
410
414
  const body = {};
@@ -434,7 +438,7 @@ export const gtmTaskActivityListCapability = defineStaffMcpCapability({
434
438
  id: "gtm.task.activity.list",
435
439
  domain: "gtm",
436
440
  roles: ["reviewer", "admin"],
437
- description: "GTM staff only: read one ticket's timeline — the comments left on it and the field changes recorded against it, oldest first.",
441
+ description: "GTM staff only: read one ticket's history — its creation and the field changes recorded against it, oldest first. Its comments are gtm.comment.list with taskId.",
438
442
  mutation: "read",
439
443
  http: { method: "GET", path: "/internal/v1/gtm/tasks/{taskId}/activity" },
440
444
  input: gtmTaskActivityListInput,
@@ -445,99 +449,6 @@ export const gtmTaskActivityListCapability = defineStaffMcpCapability({
445
449
  });
446
450
  },
447
451
  });
448
- export const gtmTaskActivityWriteInput = z.object({
449
- taskId: z.number().int().positive(),
450
- body: z.string().min(1),
451
- /** Set to reply to a comment on the same ticket. Threads are one level deep. */
452
- parentId: z.number().int().positive().optional(),
453
- confirm: z.boolean().optional(),
454
- });
455
- export const gtmTaskActivityWriteCapability = defineStaffMcpCapability({
456
- id: "gtm.task.activity.write",
457
- domain: "gtm",
458
- roles: ["reviewer", "admin"],
459
- description: "GTM staff only: add a plaintext comment to a ticket, or reply to one with parentId. Mention a teammate by writing @name in the body. Requires confirm: true.",
460
- mutation: "preview-confirm",
461
- http: { method: "POST", path: "/internal/v1/gtm/tasks/{taskId}/activity" },
462
- input: gtmTaskActivityWriteInput,
463
- execute: async (ctx, input) => {
464
- const parsed = gtmTaskActivityWriteInput.parse(input);
465
- const body = { body: parsed.body, parent_id: parsed.parentId ?? null };
466
- if (!ctx.confirmed) {
467
- return preview("gtm.task.activity.write", { taskId: parsed.taskId, ...body });
468
- }
469
- return ctx.fetch(`/internal/v1/gtm/tasks/${seg(String(parsed.taskId))}/activity`, {
470
- method: "POST",
471
- body,
472
- });
473
- },
474
- });
475
- /**
476
- * Company cell comments. These hang off one field of one company — the
477
- * discussion about a name, its owner tags, its summary, or its tickets —
478
- * rather than off the company's main thread.
479
- */
480
- const cellField = z.enum(["name", "owner_tags", "notes", "tickets"]);
481
- export const gtmCellCommentListInput = z.object({
482
- companyId: z.number().int().positive(),
483
- field: cellField,
484
- });
485
- export const gtmCellCommentListCapability = defineStaffMcpCapability({
486
- id: "gtm.cell.comment.list",
487
- domain: "gtm",
488
- roles: ["reviewer", "admin"],
489
- description: "GTM staff only: read the comments attached to one field of one company (name, owner_tags, notes or tickets), replies included.",
490
- mutation: "read",
491
- http: { method: "GET", path: "/internal/v1/gtm/companies/{companyId}/cells/{field}/comments" },
492
- input: gtmCellCommentListInput,
493
- execute: (ctx, input) => {
494
- const parsed = gtmCellCommentListInput.parse(input);
495
- return ctx.fetch(`/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/cells/${seg(parsed.field)}/comments`, { method: "GET" });
496
- },
497
- });
498
- export const gtmCellCommentWriteInput = z.object({
499
- companyId: z.number().int().positive().optional(),
500
- field: cellField.optional(),
501
- /** Set to replace an existing cell comment; companyId and field are then unused. */
502
- commentId: z.number().int().positive().optional(),
503
- parentId: z.number().int().positive().optional(),
504
- body: z.string().min(1),
505
- confirm: z.boolean().optional(),
506
- });
507
- export const gtmCellCommentWriteCapability = defineStaffMcpCapability({
508
- id: "gtm.cell.comment.write",
509
- domain: "gtm",
510
- roles: ["reviewer", "admin"],
511
- description: "GTM staff only: comment on one field of one company, reply to such a comment with parentId, or replace one when commentId is supplied. Requires confirm: true.",
512
- mutation: "preview-confirm",
513
- http: { method: "POST", path: "/internal/v1/gtm/companies/{companyId}/cells/{field}/comments" },
514
- input: gtmCellCommentWriteInput,
515
- execute: async (ctx, input) => {
516
- const parsed = gtmCellCommentWriteInput.parse(input);
517
- if (!parsed.commentId && (!parsed.companyId || !parsed.field)) {
518
- throw new Error("companyId and field are required unless commentId is supplied");
519
- }
520
- if (!ctx.confirmed) {
521
- return preview("gtm.cell.comment.write", {
522
- companyId: parsed.companyId,
523
- field: parsed.field,
524
- commentId: parsed.commentId,
525
- parentId: parsed.parentId,
526
- body: parsed.body,
527
- });
528
- }
529
- if (parsed.commentId) {
530
- return ctx.fetch(`/internal/v1/gtm/company-comments/${seg(String(parsed.commentId))}`, {
531
- method: "PATCH",
532
- body: { body: parsed.body },
533
- });
534
- }
535
- return ctx.fetch(`/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/cells/${seg(parsed.field)}/comments`, { method: "POST", body: { body: parsed.body, parent_id: parsed.parentId ?? null } });
536
- },
537
- });
538
- const cellCommentDelete = gtmDeleteCapability("cell.comment", "commentId", "/internal/v1/gtm/company-comments", "Removes that field comment and its replies.");
539
- export const gtmCellCommentDeleteInput = cellCommentDelete.input;
540
- export const gtmCellCommentDeleteCapability = cellCommentDelete.capability;
541
452
  /**
542
453
  * Bulk owner-tag reassignment. This is the one GTM edit that is genuinely
543
454
  * N-at-a-time — a book of companies moving to a new owner — and doing it one
@@ -597,20 +508,14 @@ export const staffGTMCapabilities = [
597
508
  gtmCompanyBulkRetagCapability,
598
509
  gtmDealListCapability,
599
510
  gtmDealWriteCapability,
600
- gtmDealDeleteCapability,
601
511
  gtmCommentListCapability,
602
512
  gtmCommentWriteCapability,
603
513
  gtmCommentDeleteCapability,
604
- gtmCellCommentListCapability,
605
- gtmCellCommentWriteCapability,
606
- gtmCellCommentDeleteCapability,
607
514
  gtmTaskListCapability,
608
515
  gtmTaskWriteCapability,
609
516
  gtmTaskDeleteCapability,
610
517
  gtmTaskActivityListCapability,
611
- gtmTaskActivityWriteCapability,
612
518
  gtmListingListCapability,
613
519
  gtmListingUpdateCapability,
614
- gtmMentionDismissCapability,
615
520
  gtmWorkspaceShowCapability,
616
521
  ];
@@ -47,10 +47,10 @@ export const tokensListCapability = defineCapability({
47
47
  roles: ["reviewer", "admin"],
48
48
  description: "List issued enrollment tokens (id, operator, status, expiry). Does not return plaintext secrets.",
49
49
  mutation: "read",
50
- http: { method: "GET", path: "/internal/enrollment-tokens" },
50
+ http: { method: "GET", path: "/enrollment-tokens" },
51
51
  slack: { parameters: { type: "object", properties: {} } },
52
52
  input: emptyInput,
53
- execute: async (ctx) => ctx.fetch("/internal/enrollment-tokens", { method: "GET" }),
53
+ execute: async (ctx) => ctx.fetch("/enrollment-tokens", { method: "GET" }),
54
54
  });
55
55
  export const tokensCreateCapability = defineCapability({
56
56
  id: "tokens.create",
@@ -58,7 +58,7 @@ export const tokensCreateCapability = defineCapability({
58
58
  roles: ["admin"],
59
59
  description: "Admin-only. Mint an enrollment token. Without a host this returns the curl installer. With host + private_key, orchestrator SSHs and runs that curl (same as Bulk Enroll). Never invent a command. CLI asks y/N. Slack waits for a human confirm. MCP requires confirm: true.",
60
60
  mutation: "preview-confirm",
61
- http: { method: "POST", path: "/internal/enrollment-tokens" },
61
+ http: { method: "POST", path: "/enrollment-tokens" },
62
62
  slack: {
63
63
  parameters: {
64
64
  type: "object",
@@ -105,7 +105,7 @@ export const tokensCreateCapability = defineCapability({
105
105
  if (!ctx.confirmed) {
106
106
  return preview("tokens.create", { ...payload, private_key: privateKey ? "[redacted]" : "" });
107
107
  }
108
- const minted = (await ctx.fetch("/internal/enrollment-tokens", {
108
+ const minted = (await ctx.fetch("/enrollment-tokens", {
109
109
  method: "POST",
110
110
  body: {
111
111
  operator_id: operatorId,
@@ -11,6 +11,6 @@ export { logsLatestCapability, logsTailCapability, observabilityCapabilities, te
11
11
  export { enrollmentTokenRevokeCapability, enrollmentTokenRevokeInput, facilityCreateCapability, facilityCreateInput, facilityUpdateCapability, facilityUpdateInput, nodeAdminKeyCapability, nodeAdminKeyInput, nodeBenchmarkCapability, nodeBenchmarkInput, nodeDeployCapability, nodeDeployInput, nodeDetailsUpdateCapability, nodeDetailsUpdateInput, nodeHardResetCapability, nodeHardResetInput, nodeOperatorTransferCapability, nodeOperatorTransferInput, nodeRebootCapability, nodeRebootInput, nodeShowCapability, nodeShowInput, nodeTestResultCapability, nodeTestResultInput, nodeTestTriggerCapability, nodeTestTriggerInput, nodeUpdateCapability, nodeUpdateInput, operatorCreateCapability, operatorCreateInput, operatorDeleteCapability, operatorDeleteInput, operatorUpdateCapability, operatorUpdateInput, staffFleetCapabilities, } from "./capabilities/staff-fleet.ts";
12
12
  export { bidShowCapability, bidShowInput, bidAcceptCapability, bidAcceptInput, bidRejectCapability, bidRejectInput, billingInvoicesListCapability, billingInvoicesListInput, inventoryDelistCapability, inventoryDelistInput, inventoryUpdateCapability, inventoryUpdateInput, reservationActivateCapability, reservationActivateInput, reservationCancelCapability, reservationCancelInput, reservationCompleteCapability, reservationCompleteInput, reservationDraftCreateCapability, reservationDraftCreateInput, reservationListCapability, reservationListInput, reservationMachinesListCapability, reservationMachinesListInput, reservationPublishCapability, reservationPublishInput, reservationShowCapability, reservationShowInput, reservationSshKeyAddCapability, reservationSshKeyAddInput, reservationSshKeyRemoveCapability, reservationSshKeyRemoveInput, reservationTransferCapability, reservationTransferInput, reservationUpdateCapability, reservationUpdateInput, staffCommerceCapabilities, tenantCreditProfileShowCapability, tenantCreditProfileShowInput, } from "./capabilities/staff-commerce.ts";
13
13
  export { sshKeyAddCapability, sshKeyAddInput, sshKeyPushCapability, sshKeyPushInput, sshKeyRevokeCapability, sshKeyRevokeInput, staffAccessCapabilities, } from "./capabilities/staff-access.ts";
14
- export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmCellCommentDeleteCapability, gtmCellCommentDeleteInput, gtmCellCommentListCapability, gtmCellCommentListInput, gtmCellCommentWriteCapability, gtmCellCommentWriteInput, gtmDealDeleteCapability, gtmDealDeleteInput, gtmDealListCapability, gtmDealListInput, gtmMentionDismissCapability, gtmMentionDismissInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmTaskActivityWriteCapability, gtmTaskActivityWriteInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.ts";
14
+ export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmDealListCapability, gtmDealListInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.ts";
15
15
  export { CLIENTS, parseRole, roleAtLeast, ROLES, type ClientKind, type Role } from "./role.ts";
16
16
  export { bindHardwareFields, HARDWARE_CATALOG_PATH, HARDWARE_KINDS, HARDWARE_LISTING_FIELDS, HARDWARE_LISTING_FILTERS, loadHardwareCatalog, looksLikeSpecDump, normalizeCatalogQuery, parseHardwareCatalog, projectCatalogTerms, proposeListingPayload, resolveCatalogTerm, UNRESOLVED_CATALOG_HINT, type CatalogBindResult, type CatalogTerm, type HardwareCatalog, type HardwareKind, type ResolvedCatalogTerm, } from "./spec-catalog.ts";
@@ -11,6 +11,6 @@ export { logsLatestCapability, logsTailCapability, observabilityCapabilities, te
11
11
  export { enrollmentTokenRevokeCapability, enrollmentTokenRevokeInput, facilityCreateCapability, facilityCreateInput, facilityUpdateCapability, facilityUpdateInput, nodeAdminKeyCapability, nodeAdminKeyInput, nodeBenchmarkCapability, nodeBenchmarkInput, nodeDeployCapability, nodeDeployInput, nodeDetailsUpdateCapability, nodeDetailsUpdateInput, nodeHardResetCapability, nodeHardResetInput, nodeOperatorTransferCapability, nodeOperatorTransferInput, nodeRebootCapability, nodeRebootInput, nodeShowCapability, nodeShowInput, nodeTestResultCapability, nodeTestResultInput, nodeTestTriggerCapability, nodeTestTriggerInput, nodeUpdateCapability, nodeUpdateInput, operatorCreateCapability, operatorCreateInput, operatorDeleteCapability, operatorDeleteInput, operatorUpdateCapability, operatorUpdateInput, staffFleetCapabilities, } from "./capabilities/staff-fleet.js";
12
12
  export { bidShowCapability, bidShowInput, bidAcceptCapability, bidAcceptInput, bidRejectCapability, bidRejectInput, billingInvoicesListCapability, billingInvoicesListInput, inventoryDelistCapability, inventoryDelistInput, inventoryUpdateCapability, inventoryUpdateInput, reservationActivateCapability, reservationActivateInput, reservationCancelCapability, reservationCancelInput, reservationCompleteCapability, reservationCompleteInput, reservationDraftCreateCapability, reservationDraftCreateInput, reservationListCapability, reservationListInput, reservationMachinesListCapability, reservationMachinesListInput, reservationPublishCapability, reservationPublishInput, reservationShowCapability, reservationShowInput, reservationSshKeyAddCapability, reservationSshKeyAddInput, reservationSshKeyRemoveCapability, reservationSshKeyRemoveInput, reservationTransferCapability, reservationTransferInput, reservationUpdateCapability, reservationUpdateInput, staffCommerceCapabilities, tenantCreditProfileShowCapability, tenantCreditProfileShowInput, } from "./capabilities/staff-commerce.js";
13
13
  export { sshKeyAddCapability, sshKeyAddInput, sshKeyPushCapability, sshKeyPushInput, sshKeyRevokeCapability, sshKeyRevokeInput, staffAccessCapabilities, } from "./capabilities/staff-access.js";
14
- export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmCellCommentDeleteCapability, gtmCellCommentDeleteInput, gtmCellCommentListCapability, gtmCellCommentListInput, gtmCellCommentWriteCapability, gtmCellCommentWriteInput, gtmDealDeleteCapability, gtmDealDeleteInput, gtmDealListCapability, gtmDealListInput, gtmMentionDismissCapability, gtmMentionDismissInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmTaskActivityWriteCapability, gtmTaskActivityWriteInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.js";
14
+ export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmDealListCapability, gtmDealListInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.js";
15
15
  export { CLIENTS, parseRole, roleAtLeast, ROLES } from "./role.js";
16
16
  export { bindHardwareFields, HARDWARE_CATALOG_PATH, HARDWARE_KINDS, HARDWARE_LISTING_FIELDS, HARDWARE_LISTING_FILTERS, loadHardwareCatalog, looksLikeSpecDump, normalizeCatalogQuery, parseHardwareCatalog, projectCatalogTerms, proposeListingPayload, resolveCatalogTerm, UNRESOLVED_CATALOG_HINT, } from "./spec-catalog.js";