@pome-sh/cli 0.21.15 → 0.21.17

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.
@@ -2,14 +2,14 @@ export { LINEAR_CHECKS } from './chunk-XBT6ZLBG.js';
2
2
  import { MCP_PAGE_MAX, defaultSeedState, linearSeedSchema, notFound, badUserInput, MCP_PAGE_DEFAULT, DEFAULT_LINEAR_EMAIL, RELAY_PAGE_MAX, RELAY_PAGE_DEFAULT, STATE_EXPORT_CAP, parseSeed, DEFAULT_LINEAR_CLOCK, LINEAR_PROVIDER_TOKEN_PREFIX, DEFAULT_LINEAR_SID, DEFAULT_SCOPES, linearErrorEnvelope, unauthorizedEnvelope, unsupportedEnvelope, assertWebhookUrl, ACCESS_TOKEN_TTL_SECONDS, OAUTH_CODE_TTL_SECONDS, TITLE_MAX_BYTES, BODY_MAX_BYTES, LinearTwinError, GRAPHQL_QUERY_MAX_BYTES, GRAPHQL_SELECTION_DEPTH_MAX } from './chunk-ZKID2HS3.js';
3
3
  export { DEFAULT_LINEAR_CLOCK, DEFAULT_LINEAR_EMAIL, DEFAULT_LINEAR_PORT, DEFAULT_LINEAR_SID, DEFAULT_LINEAR_TOKEN, LINEAR_PROVIDER_TOKEN_PREFIX, LinearTwinError, STATE_EXPORT_CAP, assertWebhookUrl, defaultSeedState, linearErrorEnvelope, linearSeedSchema, loadSeedFromEnv, parseSeed, unauthorizedEnvelope, unsupportedEnvelope, webhookUrlError } from './chunk-ZKID2HS3.js';
4
4
  import './chunk-JWJYNAWI.js';
5
- import { declareRouteInputs, mountDeclaredRoute, UndeclaredInputError } from './chunk-4MQULI7E.js';
5
+ import { routeInputDeclarer, mountDeclaredRoute, UndeclaredInputError } from './chunk-2Q3P45LK.js';
6
6
  import { loadMcpToolFixture, deriveMcpToolTable, openTwinDatabase, defineTwin, createApp } from './chunk-TV5S6WQV.js';
7
7
  import './chunk-VBATFCWR.js';
8
8
  import './chunk-SG6ZTIMT.js';
9
9
  import { createHmac, timingSafeEqual, createHash, randomBytes } from 'node:crypto';
10
+ import { z } from 'zod';
10
11
  import { isIP } from 'node:net';
11
12
  import { lookup } from 'node:dns/promises';
12
- import { z } from 'zod';
13
13
  import { Hono } from 'hono';
14
14
  import { buildSchema, graphql, parse, getOperationAST } from 'graphql';
15
15
 
@@ -271,8 +271,8 @@ CREATE TABLE IF NOT EXISTS agent_activities (
271
271
  id TEXT PRIMARY KEY,
272
272
  session_id TEXT NOT NULL,
273
273
  user_id TEXT,
274
- type TEXT NOT NULL,
275
- body TEXT NOT NULL,
274
+ content_json TEXT NOT NULL DEFAULT '{}',
275
+ signal TEXT,
276
276
  ephemeral INTEGER NOT NULL DEFAULT 0,
277
277
  created_at TEXT NOT NULL,
278
278
  updated_at TEXT NOT NULL,
@@ -340,6 +340,27 @@ function migrate(db) {
340
340
  ensureColumn(db, "issues", "parent_id", "TEXT");
341
341
  ensureColumn(db, "comments", "parent_id", "TEXT");
342
342
  migrateAgentSessions(db);
343
+ migrateAgentActivities(db);
344
+ }
345
+ function migrateAgentActivities(db) {
346
+ const columns = db.prepare("PRAGMA table_info(agent_activities)").all().map((column) => column.name);
347
+ if (!columns.includes("content_json")) {
348
+ db.exec("ALTER TABLE agent_activities ADD COLUMN content_json TEXT NOT NULL DEFAULT '{}'");
349
+ }
350
+ if (!columns.includes("signal"))
351
+ db.exec("ALTER TABLE agent_activities ADD COLUMN signal TEXT");
352
+ if (columns.includes("type") && columns.includes("body")) {
353
+ db.exec(`UPDATE agent_activities
354
+ SET content_json = json_object('type', type, 'body', body)
355
+ WHERE content_json = '{}'`);
356
+ }
357
+ if (columns.includes("type"))
358
+ db.exec("ALTER TABLE agent_activities DROP COLUMN type");
359
+ if (columns.includes("body"))
360
+ db.exec("ALTER TABLE agent_activities DROP COLUMN body");
361
+ db.exec(`UPDATE agent_activities
362
+ SET user_id = (SELECT app_user_id FROM agent_sessions WHERE agent_sessions.id = session_id)
363
+ WHERE user_id IS NULL`);
343
364
  }
344
365
  function migrateAgentSessions(db) {
345
366
  const columnNames = () => db.prepare("PRAGMA table_info(agent_sessions)").all().map((column) => column.name);
@@ -444,8 +465,6 @@ function assertNoParentCycle(domain, issueId, parentId) {
444
465
  cursor = row?.parentId ?? null;
445
466
  }
446
467
  }
447
-
448
- // ../packages/twin-linear/dist/src/domain/normalize.js
449
468
  function assertTitle(title) {
450
469
  if (byteLength(title) > TITLE_MAX_BYTES)
451
470
  badUserInput(`Issue title exceeds ${TITLE_MAX_BYTES} bytes`);
@@ -494,23 +513,51 @@ function readSessionStatus(value) {
494
513
  }
495
514
  return value;
496
515
  }
497
- function normalizeSessionStatus(value) {
498
- if (!AGENT_SESSION_STATUSES.includes(value)) {
499
- badUserInput(`Invalid agent session status: ${value}`);
516
+ function readActivityUserId(activityId, value) {
517
+ if (!value) {
518
+ throw new LinearTwinError(500, "INTERNAL_SERVER_ERROR", `Agent activity "${activityId}" has no user. Linear declares AgentActivity.user as non-null; this row's author was cleared, which no code path in this twin does.`);
500
519
  }
501
520
  return value;
502
521
  }
503
- function normalizeActivityType(value) {
504
- const allowed = [
505
- "thought",
506
- "elicitation",
507
- "action",
508
- "response",
509
- "error",
510
- "prompt"
511
- ];
512
- if (!allowed.includes(value))
513
- badUserInput(`Invalid agent activity type: ${value}`);
522
+ var AGENT_ACTIVITY_SIGNALS = ["stop", "continue", "auth", "select"];
523
+ var AGENT_ACTIVITY_SESSION_STATUS = {
524
+ thought: "active",
525
+ action: "active",
526
+ elicitation: "awaitingInput",
527
+ response: "complete",
528
+ error: "error",
529
+ prompt: "pending"
530
+ };
531
+ var bodyContent = { body: z.string().min(1), bodyData: z.unknown().optional() };
532
+ var agentActivityContentSchema = z.discriminatedUnion("type", [
533
+ z.object({ type: z.literal("thought"), ...bodyContent }).strict(),
534
+ z.object({ type: z.literal("response"), ...bodyContent }).strict(),
535
+ z.object({ type: z.literal("elicitation"), ...bodyContent }).strict(),
536
+ z.object({ type: z.literal("prompt"), ...bodyContent, title: z.string().nullish() }).strict(),
537
+ z.object({ type: z.literal("error"), ...bodyContent, reasonCode: z.string().nullish() }).strict(),
538
+ z.object({
539
+ type: z.literal("action"),
540
+ action: z.string().min(1),
541
+ parameter: z.string().min(1),
542
+ result: z.string().nullish(),
543
+ resultData: z.unknown().optional()
544
+ }).strict()
545
+ ]);
546
+ function normalizeActivityContent(value) {
547
+ const parsed = agentActivityContentSchema.safeParse(value);
548
+ if (!parsed.success) {
549
+ const issue = parsed.error.issues[0];
550
+ badUserInput(`Invalid agent activity content${issue ? `: ${issue.path.join(".") || "type"} \u2014 ${issue.message}` : ""}`);
551
+ }
552
+ const content = parsed.data;
553
+ if ("body" in content)
554
+ assertBody(content.body);
555
+ return content;
556
+ }
557
+ function normalizeActivitySignal(value) {
558
+ if (!AGENT_ACTIVITY_SIGNALS.includes(value)) {
559
+ badUserInput(`Invalid agent activity signal: ${value}`);
560
+ }
514
561
  return value;
515
562
  }
516
563
 
@@ -690,10 +737,10 @@ function mapAgentSession(row) {
690
737
  function mapAgentActivity(row) {
691
738
  return {
692
739
  id: row.id,
693
- sessionId: row.session_id,
694
- userId: row.user_id,
695
- type: row.type,
696
- body: row.body,
740
+ agentSessionId: row.session_id,
741
+ userId: readActivityUserId(row.id, row.user_id),
742
+ content: JSON.parse(row.content_json),
743
+ signal: row.signal,
697
744
  ephemeral: !!row.ephemeral,
698
745
  createdAt: row.created_at,
699
746
  updatedAt: row.updated_at
@@ -1598,8 +1645,9 @@ function exportLinearState(db) {
1598
1645
  payload: parseJson(row.payload),
1599
1646
  headers: redactHeaders(parseJson(row.headers))
1600
1647
  })), "webhookDeliveries", truncatedCollections, true);
1601
- const agentActivities = capped(db.prepare(`SELECT id, session_id AS sessionId, user_id AS userId, type, body, ephemeral,
1602
- created_at AS createdAt FROM agent_activities ORDER BY created_at DESC, id DESC`).all(), "agentActivities", truncatedCollections, true);
1648
+ const agentActivities = capped(db.prepare(`SELECT id, session_id AS agentSessionId, user_id AS userId, content_json AS content,
1649
+ signal, ephemeral, created_at AS createdAt
1650
+ FROM agent_activities ORDER BY created_at DESC, id DESC`).all().map((row) => ({ ...row, content: parseJson(row.content) })), "agentActivities", truncatedCollections, true);
1603
1651
  return {
1604
1652
  schemaVersion: 1,
1605
1653
  clock,
@@ -1755,7 +1803,7 @@ async function createAgentSessionOnIssue(domain, input, actor = {}) {
1755
1803
  const now = domain.tick();
1756
1804
  const id = domain.nextId("agent_session");
1757
1805
  domain.db.prepare(`INSERT INTO agent_sessions(id, issue_id, comment_id, app_user_id, status, plan, external_urls_json, created_at, updated_at)
1758
- VALUES (?,?,?,?,?,?,?,?,?)`).run(id, issue.id, null, agent.id, "pending", input.plan ?? null, JSON.stringify(input.externalUrls ?? []), now, now);
1806
+ VALUES (?,?,?,?,?,?,?,?,?)`).run(id, issue.id, null, agent.id, "pending", null, JSON.stringify(input.externalUrls ?? []), now, now);
1759
1807
  const session = domain.requireAgentSession(id);
1760
1808
  await emitWebhook(domain, {
1761
1809
  type: "AgentSessionEvent",
@@ -1775,7 +1823,7 @@ async function createAgentSessionOnComment(domain, input, actor = {}) {
1775
1823
  const now = domain.tick();
1776
1824
  const id = domain.nextId("agent_session");
1777
1825
  domain.db.prepare(`INSERT INTO agent_sessions(id, issue_id, comment_id, app_user_id, status, plan, external_urls_json, created_at, updated_at)
1778
- VALUES (?,?,?,?,?,?,?,?,?)`).run(id, issue.id, comment.id, agent.id, "pending", input.plan ?? null, JSON.stringify(input.externalUrls ?? []), now, now);
1826
+ VALUES (?,?,?,?,?,?,?,?,?)`).run(id, issue.id, comment.id, agent.id, "pending", null, JSON.stringify(input.externalUrls ?? []), now, now);
1779
1827
  return domain.requireAgentSession(id);
1780
1828
  }
1781
1829
  function updateAgentSession(domain, id, input, actor = {}) {
@@ -1783,29 +1831,31 @@ function updateAgentSession(domain, id, input, actor = {}) {
1783
1831
  const session = domain.requireAgentSession(id);
1784
1832
  const now = domain.tick();
1785
1833
  domain.db.prepare(`UPDATE agent_sessions SET
1786
- status = COALESCE(?, status),
1787
1834
  plan = CASE WHEN ? THEN ? ELSE plan END,
1788
1835
  external_urls_json = CASE WHEN ? THEN ? ELSE external_urls_json END,
1789
1836
  updated_at = ?
1790
- WHERE id = ?`).run(input.status ? normalizeSessionStatus(input.status) : null, input.plan !== void 0 ? 1 : 0, input.plan ?? null, input.externalUrls !== void 0 ? 1 : 0, JSON.stringify(input.externalUrls ?? []), now, session.id);
1837
+ WHERE id = ?`).run(input.plan !== void 0 ? 1 : 0, input.plan ?? null, input.externalUrls !== void 0 ? 1 : 0, JSON.stringify(input.externalUrls ?? []), now, session.id);
1791
1838
  return domain.requireAgentSession(session.id);
1792
1839
  }
1793
1840
  async function createAgentActivity(domain, input, actor = {}) {
1794
1841
  domain.requireScopes(actor, ["write"]);
1795
- assertBody(input.body);
1796
- const session = domain.requireAgentSession(input.sessionId);
1842
+ const session = domain.requireAgentSession(input.agentSessionId);
1797
1843
  const viewer = domain.resolveViewer(actor);
1798
- const type = normalizeActivityType(input.type);
1844
+ const content = normalizeActivityContent(input.content);
1845
+ const signal = input.signal ? normalizeActivitySignal(input.signal) : null;
1799
1846
  const now = domain.tick();
1800
1847
  const id = domain.nextId("agent_activity");
1801
- const ephemeral = typeof input.ephemeral === "boolean" ? input.ephemeral : type === "thought" || type === "action";
1802
- domain.db.prepare(`INSERT INTO agent_activities(id, session_id, user_id, type, body, ephemeral, created_at, updated_at)
1803
- VALUES (?,?,?,?,?,?,?,?)`).run(id, session.id, viewer.id, type, input.body, ephemeral ? 1 : 0, now, now);
1804
- if (type === "prompt") {
1848
+ const ephemeral = typeof input.ephemeral === "boolean" ? input.ephemeral : content.type === "thought" || content.type === "action";
1849
+ domain.db.prepare(`INSERT INTO agent_activities(id, session_id, user_id, content_json, signal, ephemeral, created_at, updated_at)
1850
+ VALUES (?,?,?,?,?,?,?,?)`).run(id, session.id, viewer.id, JSON.stringify(content), signal, ephemeral ? 1 : 0, now, now);
1851
+ const status = AGENT_ACTIVITY_SESSION_STATUS[content.type];
1852
+ domain.db.prepare("UPDATE agent_sessions SET status = ?, updated_at = ? WHERE id = ?").run(status, now, session.id);
1853
+ if (content.type === "prompt") {
1805
1854
  await emitWebhook(domain, {
1806
1855
  type: "AgentSessionEvent",
1807
1856
  action: "prompted",
1808
- data: { id: session.id, status: session.status },
1857
+ // The status the activity just produced, not the one it replaced.
1858
+ data: { id: session.id, status },
1809
1859
  actor: viewer,
1810
1860
  teamId: session.issueId ? domain.requireIssue(session.issueId).teamId : null
1811
1861
  });
@@ -1819,8 +1869,8 @@ function getAgentActivity(domain, ref) {
1819
1869
  const row = domain.db.prepare("SELECT * FROM agent_activities WHERE id = ?").get(ref);
1820
1870
  return row ? mapAgentActivity(row) : null;
1821
1871
  }
1822
- function listAgentActivities(domain, sessionId) {
1823
- return domain.db.prepare("SELECT * FROM agent_activities WHERE session_id = ? ORDER BY created_at, id").all(sessionId).map(mapAgentActivity);
1872
+ function listAgentActivities(domain, agentSessionId) {
1873
+ return domain.db.prepare("SELECT * FROM agent_activities WHERE session_id = ? ORDER BY created_at, id").all(agentSessionId).map(mapAgentActivity);
1824
1874
  }
1825
1875
 
1826
1876
  // ../packages/twin-linear/dist/src/domain/catalog.js
@@ -2533,8 +2583,8 @@ var LinearDomain = class {
2533
2583
  getAgentActivity(ref) {
2534
2584
  return getAgentActivity(this, ref);
2535
2585
  }
2536
- listAgentActivities(sessionId) {
2537
- return listAgentActivities(this, sessionId);
2586
+ listAgentActivities(agentSessionId) {
2587
+ return listAgentActivities(this, agentSessionId);
2538
2588
  }
2539
2589
  listOAuthApps() {
2540
2590
  return listOAuthApps(this);
@@ -3359,6 +3409,7 @@ function shouldRedact(key) {
3359
3409
  return true;
3360
3410
  return false;
3361
3411
  }
3412
+ var declareInputs = routeInputDeclarer("ignore");
3362
3413
  var VARIABLES_STRING = z.string().optional();
3363
3414
  var VARIABLES_OBJECT = z.union([z.record(z.string(), z.unknown()), z.string()]).optional();
3364
3415
  var AUTHORIZE_PARAMS = {
@@ -3371,7 +3422,7 @@ var AUTHORIZE_PARAMS = {
3371
3422
  code_challenge_method: z.string().optional()
3372
3423
  };
3373
3424
  var LINEAR_ROUTES = {
3374
- graphqlGet: declareRouteInputs({
3425
+ graphqlGet: declareInputs({
3375
3426
  method: "GET",
3376
3427
  path: "/graphql",
3377
3428
  query: {
@@ -3380,7 +3431,7 @@ var LINEAR_ROUTES = {
3380
3431
  operationName: z.string().optional()
3381
3432
  }
3382
3433
  }),
3383
- graphqlPost: declareRouteInputs({
3434
+ graphqlPost: declareInputs({
3384
3435
  method: "POST",
3385
3436
  path: "/graphql",
3386
3437
  bodyEncoding: "form",
@@ -3390,12 +3441,12 @@ var LINEAR_ROUTES = {
3390
3441
  operationName: z.string().optional()
3391
3442
  }
3392
3443
  }),
3393
- oauthAuthorize: declareRouteInputs({
3444
+ oauthAuthorize: declareInputs({
3394
3445
  method: "GET",
3395
3446
  path: "/oauth/authorize",
3396
3447
  query: { ...AUTHORIZE_PARAMS, response_type: z.string().optional() }
3397
3448
  }),
3398
- oauthAuthorizeCallback: declareRouteInputs({
3449
+ oauthAuthorizeCallback: declareInputs({
3399
3450
  method: "POST",
3400
3451
  path: "/oauth/authorize/callback",
3401
3452
  bodyEncoding: "form",
@@ -3404,7 +3455,7 @@ var LINEAR_ROUTES = {
3404
3455
  // equivalent, and declaring it says so out loud.
3405
3456
  body: { ...AUTHORIZE_PARAMS, user_ref: z.string().optional() }
3406
3457
  }),
3407
- oauthToken: declareRouteInputs({
3458
+ oauthToken: declareInputs({
3408
3459
  method: "POST",
3409
3460
  path: "/oauth/token",
3410
3461
  bodyEncoding: "form",
@@ -3422,7 +3473,7 @@ var LINEAR_ROUTES = {
3422
3473
  scope: z.string().optional()
3423
3474
  }
3424
3475
  }),
3425
- oauthRevoke: declareRouteInputs({
3476
+ oauthRevoke: declareInputs({
3426
3477
  method: "POST",
3427
3478
  path: "/oauth/revoke",
3428
3479
  bodyEncoding: "form",
@@ -3981,13 +4032,13 @@ function createFormatters(commands, actor) {
3981
4032
  });
3982
4033
  const formatAgentActivity = (activity) => ({
3983
4034
  id: activity.id,
3984
- type: activity.type,
3985
- body: activity.body,
4035
+ content: activity.content,
4036
+ signal: activity.signal,
3986
4037
  ephemeral: activity.ephemeral,
3987
4038
  createdAt: activity.createdAt,
3988
4039
  updatedAt: activity.updatedAt,
3989
- session: () => formatAgentSession(commands.requireAgentSession(activity.sessionId)),
3990
- user: () => activity.userId ? formatUser(commands.requireUser(activity.userId)) : null
4040
+ agentSession: () => formatAgentSession(commands.requireAgentSession(activity.agentSessionId)),
4041
+ user: () => formatUser(commands.requireUser(activity.userId))
3991
4042
  });
3992
4043
  function formatIssue(issue) {
3993
4044
  return {
@@ -4206,26 +4257,25 @@ var agentSessionExternalUrlSchema = z.object({ url: z.string().min(1), label: z.
4206
4257
  var optionalExternalUrls = z.array(agentSessionExternalUrlSchema).nullish();
4207
4258
  var agentSessionOnIssueInputSchema = z.object({
4208
4259
  issueId: z.string().min(1),
4209
- appUserId: z.string().optional(),
4210
- plan: optionalString,
4211
4260
  externalUrls: optionalExternalUrls
4212
4261
  }).strict();
4213
4262
  var agentSessionOnCommentInputSchema = z.object({
4214
4263
  commentId: z.string().min(1),
4215
- appUserId: z.string().optional(),
4216
- plan: optionalString,
4217
4264
  externalUrls: optionalExternalUrls
4218
4265
  }).strict();
4219
4266
  var agentSessionUpdateInputSchema = z.object({
4220
- id: z.string().min(1).optional(),
4221
- status: z.string().optional(),
4222
4267
  plan: optionalString,
4223
4268
  externalUrls: optionalExternalUrls
4224
4269
  }).strict();
4225
4270
  var agentActivityCreateInputSchema = z.object({
4226
- sessionId: z.string().min(1),
4227
- type: z.string().min(1),
4228
- body: z.string().min(1),
4271
+ agentSessionId: z.string().min(1),
4272
+ // `JSONObject!` upstream. The envelope is checked here; which of Linear's
4273
+ // six `AgentActivityContent` members it is, and whether it is well formed,
4274
+ // is the domain's `normalizeActivityContent` — the same split as
4275
+ // `priority` and `normalizePriority`, and the reason a bad content names
4276
+ // itself rather than surfacing as a stray "expected string".
4277
+ content: z.record(z.string(), z.unknown()),
4278
+ signal: z.enum(AGENT_ACTIVITY_SIGNALS).nullish(),
4229
4279
  ephemeral: z.boolean().optional()
4230
4280
  }).strict();
4231
4281
  function parseOrBadUserInput(schema, input, label) {
@@ -4332,37 +4382,22 @@ function parseWebhookCreateInput(input) {
4332
4382
  }
4333
4383
  function parseAgentSessionOnIssueInput(input) {
4334
4384
  const raw = parseOrBadUserInput(agentSessionOnIssueInputSchema, input, "agentSessionCreateOnIssue input");
4335
- return {
4336
- issueId: raw.issueId,
4337
- appUserId: raw.appUserId,
4338
- plan: raw.plan ?? null,
4339
- externalUrls: raw.externalUrls ?? null
4340
- };
4385
+ return { issueId: raw.issueId, externalUrls: raw.externalUrls ?? null };
4341
4386
  }
4342
4387
  function parseAgentSessionOnCommentInput(input) {
4343
4388
  const raw = parseOrBadUserInput(agentSessionOnCommentInputSchema, input, "agentSessionCreateOnComment input");
4344
- return {
4345
- commentId: raw.commentId,
4346
- appUserId: raw.appUserId,
4347
- plan: raw.plan ?? null,
4348
- externalUrls: raw.externalUrls ?? null
4349
- };
4389
+ return { commentId: raw.commentId, externalUrls: raw.externalUrls ?? null };
4350
4390
  }
4351
4391
  function parseAgentSessionUpdateInput(input) {
4352
4392
  const raw = parseOrBadUserInput(agentSessionUpdateInputSchema, input, "agentSessionUpdate input");
4353
- return {
4354
- id: raw.id,
4355
- status: raw.status,
4356
- plan: raw.plan,
4357
- externalUrls: raw.externalUrls
4358
- };
4393
+ return { plan: raw.plan, externalUrls: raw.externalUrls };
4359
4394
  }
4360
4395
  function parseAgentActivityCreateInput(input) {
4361
4396
  const raw = parseOrBadUserInput(agentActivityCreateInputSchema, input, "agentActivityCreate input");
4362
4397
  return {
4363
- sessionId: raw.sessionId,
4364
- type: raw.type,
4365
- body: raw.body,
4398
+ agentSessionId: raw.agentSessionId,
4399
+ content: raw.content,
4400
+ signal: raw.signal ?? null,
4366
4401
  ephemeral: raw.ephemeral
4367
4402
  };
4368
4403
  }
@@ -4518,13 +4553,10 @@ function createRootValue(ctx) {
4518
4553
  const session = await commands.createAgentSessionOnComment(parseAgentSessionOnCommentInput(input), actor);
4519
4554
  return payload({ agentSession: formatAgentSession(session) });
4520
4555
  },
4556
+ // `id` is non-null on the schema, as it is upstream — there is no longer an
4557
+ // `input.id` to fall back to (F-1176).
4521
4558
  agentSessionUpdate: ({ id, input }) => {
4522
- const parsed = parseAgentSessionUpdateInput(input);
4523
- const session = commands.updateAgentSession(String(id ?? parsed.id), {
4524
- status: parsed.status,
4525
- plan: parsed.plan,
4526
- externalUrls: parsed.externalUrls
4527
- }, actor);
4559
+ const session = commands.updateAgentSession(id, parseAgentSessionUpdateInput(input), actor);
4528
4560
  return payload({ agentSession: formatAgentSession(session) });
4529
4561
  },
4530
4562
  agentActivityCreate: async ({ input }) => {
@@ -4538,6 +4570,7 @@ var linearGraphQLSchema = buildSchema(`
4538
4570
  scalar PaginationOrderBy
4539
4571
  scalar DateTime
4540
4572
  scalar JSON
4573
+ scalar JSONObject
4541
4574
 
4542
4575
  type Query {
4543
4576
  viewer: User!
@@ -4590,7 +4623,7 @@ var linearGraphQLSchema = buildSchema(`
4590
4623
  webhookDelete(id: String!): DeletePayload!
4591
4624
  agentSessionCreateOnIssue(input: AgentSessionCreateOnIssue!): AgentSessionPayload!
4592
4625
  agentSessionCreateOnComment(input: AgentSessionCreateOnComment!): AgentSessionPayload!
4593
- agentSessionUpdate(id: String, input: AgentSessionUpdateInput!): AgentSessionPayload!
4626
+ agentSessionUpdate(id: String!, input: AgentSessionUpdateInput!): AgentSessionPayload!
4594
4627
  agentActivityCreate(input: AgentActivityCreateInput!): AgentActivityPayload!
4595
4628
  }
4596
4629
 
@@ -4853,15 +4886,29 @@ var linearGraphQLSchema = buildSchema(`
4853
4886
  activities(first: Int, after: String, last: Int, before: String): AgentActivityConnection!
4854
4887
  }
4855
4888
 
4889
+ """Linear's AgentActivitySignal, member-for-member (F-1176)."""
4890
+ enum AgentActivitySignal {
4891
+ stop
4892
+ continue
4893
+ auth
4894
+ select
4895
+ }
4896
+
4856
4897
  type AgentActivity {
4857
- id: String!
4858
- type: String!
4859
- body: String!
4898
+ id: ID!
4899
+ """
4900
+ Linear's AgentActivityContent union, carried as an opaque payload: a
4901
+ {type, body} object for five of the six members, {type, action, parameter}
4902
+ for the action member. The union itself is a scalar-level divergence,
4903
+ written up in REFERENCE-DIVERGENCES.md (F-1176).
4904
+ """
4905
+ content: JSON!
4906
+ signal: AgentActivitySignal
4860
4907
  ephemeral: Boolean!
4861
- createdAt: String!
4862
- updatedAt: String!
4863
- session: AgentSession!
4864
- user: User
4908
+ createdAt: DateTime!
4909
+ updatedAt: DateTime!
4910
+ agentSession: AgentSession!
4911
+ user: User!
4865
4912
  }
4866
4913
 
4867
4914
  type NodeRef {
@@ -5021,31 +5068,30 @@ var linearGraphQLSchema = buildSchema(`
5021
5068
  label: String!
5022
5069
  }
5023
5070
 
5071
+ """Linear's AgentSessionCreateOnIssue, minus the fields the twin does not model (F-1176)."""
5024
5072
  input AgentSessionCreateOnIssue {
5025
5073
  issueId: String!
5026
- appUserId: String
5027
- plan: String
5028
5074
  externalUrls: [AgentSessionExternalUrlInput!]
5029
5075
  }
5030
5076
 
5031
5077
  input AgentSessionCreateOnComment {
5032
5078
  commentId: String!
5033
- appUserId: String
5034
- plan: String
5035
5079
  externalUrls: [AgentSessionExternalUrlInput!]
5036
5080
  }
5037
5081
 
5082
+ """
5083
+ Linear declares no status and no id field here (F-1176). Status follows the
5084
+ agent's activities; id is the mutation's own non-null argument.
5085
+ """
5038
5086
  input AgentSessionUpdateInput {
5039
- id: String
5040
- status: AgentSessionStatus
5041
5087
  plan: String
5042
5088
  externalUrls: [AgentSessionExternalUrlInput!]
5043
5089
  }
5044
5090
 
5045
5091
  input AgentActivityCreateInput {
5046
- sessionId: String!
5047
- type: String!
5048
- body: String!
5092
+ agentSessionId: String!
5093
+ content: JSONObject!
5094
+ signal: AgentActivitySignal
5049
5095
  ephemeral: Boolean
5050
5096
  }
5051
5097
  `);
@@ -0,0 +1,5 @@
1
+ export { UnsupportedTwinError, bootTwin } from './chunk-IWTB3NN5.js';
2
+ export { STRIPE_LOCAL_ACCOUNT_ID } from './chunk-3JUWDIJ2.js';
3
+ import './chunk-TV5S6WQV.js';
4
+ import './chunk-VBATFCWR.js';
5
+ import './chunk-SG6ZTIMT.js';
@@ -1,5 +1,5 @@
1
- import { bootTwin } from './chunk-IYDTDANH.js';
2
- import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-BA4N7AOZ.js';
1
+ import { bootTwin } from './chunk-IWTB3NN5.js';
2
+ import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-3JUWDIJ2.js';
3
3
  import './chunk-TV5S6WQV.js';
4
4
  import './chunk-VBATFCWR.js';
5
5
  import './chunk-SG6ZTIMT.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pome-sh/cli",
3
- "version": "0.21.15",
4
- "description": "Digital-twin testing for AI agents \u2014 run tasks against resettable local or hosted twins and record tool-call traces for evaluation on pome.sh.",
3
+ "version": "0.21.17",
4
+ "description": "Digital-twin testing for AI agents run tasks against resettable local or hosted twins and record tool-call traces for evaluation on pome.sh.",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "agents",
@@ -1,5 +0,0 @@
1
- export { UnsupportedTwinError, bootTwin } from './chunk-IYDTDANH.js';
2
- export { STRIPE_LOCAL_ACCOUNT_ID } from './chunk-BA4N7AOZ.js';
3
- import './chunk-TV5S6WQV.js';
4
- import './chunk-VBATFCWR.js';
5
- import './chunk-SG6ZTIMT.js';