@lunnoa/client 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -113,6 +113,8 @@ Most namespaces map to the Public API surface (`openapi.public.json`):
113
113
 
114
114
  `approvals` uses the authenticated **workspace** API (`/api/approvals/...`), not Public API v1. The inbox is filtered to requests where the current user is an eligible approver.
115
115
 
116
+ `scorecards` also uses the workspace API (`/api/scorecards/...`): `list`, `get`, and `recordValue(measureId, { value, period?, note? })` to push a measure value from your own system (API key needs `scorecard:record`).
117
+
116
118
  Errors are `LunnoaApiError` with `status`, `body`, and convenience flags (`isUnauthorized`, `isForbidden`, `isRateLimited`). Paginated lists have async iteration (`entities.iterate(...)`, `queueItems.iterate(...)`).
117
119
 
118
120
  ## Worked examples
@@ -266,7 +268,7 @@ Re-run codegen whenever entity types, workflows, or agents change on the deploym
266
268
 
267
269
  ## Define, run, and CLI deploy
268
270
 
269
- Author local definitions with `defineWorkflow` / `defineAgent` / `defineEntityType`, run linear chains with `lunnoa.runs.start`, and upsert with the CLI (prefer CLI over calling upsert from app code). Entity types are workspace-scoped (no `--project-id`); instance writes reject unknown attribute keys unless `allowUnknownAttributes` is true — use the reserved `extensions` object for flexible bags:
271
+ Author local definitions with `defineWorkflow` / `defineAgent` / `defineEntityType`, run linear chains with `lunnoa.runs.start`, and upsert with the CLI (prefer CLI over calling upsert from app code). An entity type slug is unique on the deployment. Deploy grants that type to the API key's workspace when the slug is new, and will not rewrite a type already granted to other workspaces (no `--project-id`). Instance writes reject unknown attribute keys unless `allowUnknownAttributes` is true — use the reserved `extensions` object for flexible bags:
270
272
 
271
273
  ```bash
272
274
  npx @lunnoa/client entity-types deploy ./human.ts --url https://lunnoa.example --api-key lna_...
@@ -320,7 +322,9 @@ Two Cursor / Claude Code skills ship in the published package under `skills/`:
320
322
  | **lunnoa-solution-design** | [`skills/lunnoa-solution-design/SKILL.md`](./skills/lunnoa-solution-design/SKILL.md) | Interview the human, map intent to Lunnoa primitives, produce a build brief |
321
323
  | **lunnoa-client** | [`skills/lunnoa-client/SKILL.md`](./skills/lunnoa-client/SKILL.md) | Implement with auth, discovery, codegen, `define*` / `runs` / CLI deploy, React hooks |
322
324
 
323
- After install, copy or enable them from `node_modules/@lunnoa/client/skills/` into your app’s `.cursor/skills/` (or Claude Code skills directory). Prefer **solution-design** first when requirements are unclear, then **lunnoa-client**.
325
+ Install them into your app with `npx @lunnoa/client skills install`. It copies the skills of the installed SDK version into `.claude/skills/` and `.cursor/skills/`. Add it as a `postinstall` script and gitignore both folders so the skills stay in step with the SDK. Prefer **solution-design** first when requirements are unclear, then **lunnoa-client**.
326
+
327
+ In this repo, edit `skills/` only; `pnpm install` copies it into the local `.cursor/skills/` and `.claude/skills/`.
324
328
 
325
329
  Partner paste block:
326
330
 
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli/index.ts
4
4
  import { mkdir, writeFile } from "fs/promises";
5
- import { resolve as resolve2 } from "path";
5
+ import { resolve as resolve3 } from "path";
6
6
 
7
7
  // src/core/auth.ts
8
8
  var API_KEY_PREFIX = "lna_";
@@ -430,10 +430,7 @@ var AgentChatClient = class {
430
430
  raw: true,
431
431
  signal: options.signal,
432
432
  headers: { Accept: "text/event-stream" },
433
- body: {
434
- messages: [uiMessage],
435
- ...options.chatMode ? { chatMode: options.chatMode } : {}
436
- }
433
+ body: messageTaskBody(uiMessage, options)
437
434
  }
438
435
  );
439
436
  return new AgentChatStream(response, { signal: options.signal });
@@ -472,6 +469,14 @@ var AgentChatClient = class {
472
469
  );
473
470
  }
474
471
  };
472
+ function messageTaskBody(message, options = {}) {
473
+ return {
474
+ messages: [message],
475
+ ...options.chatMode ? { chatMode: options.chatMode } : {},
476
+ ...options.data ? { data: options.data } : {},
477
+ ...options.piiResolution ? { piiResolution: options.piiResolution } : {}
478
+ };
479
+ }
475
480
  function generateMessageId() {
476
481
  const cryptoObj = globalThis.crypto;
477
482
  if (cryptoObj?.randomUUID) {
@@ -1005,7 +1010,6 @@ var EntitiesResource = class {
1005
1010
  objectTypeSlug: options.objectTypeSlug,
1006
1011
  state: options.state,
1007
1012
  states: options.states?.join(","),
1008
- ownerId: options.ownerId,
1009
1013
  search: options.search,
1010
1014
  sortBy: options.sortBy,
1011
1015
  sortOrder: options.sortOrder,
@@ -1038,7 +1042,7 @@ var EntityTypesResource = class {
1038
1042
  }
1039
1043
  http;
1040
1044
  /**
1041
- * Lists entity types in the workspace. Request
1045
+ * Lists entity types granted to the API key's workspace. Request
1042
1046
  * `expansion: ['attributeSchema', 'stateSchema']` for the field and state
1043
1047
  * machine definitions the codegen CLI builds types from.
1044
1048
  */
@@ -1063,7 +1067,9 @@ var EntityTypesResource = class {
1063
1067
  });
1064
1068
  }
1065
1069
  /**
1066
- * Creates or updates an entity type by workspace-scoped slug.
1070
+ * Creates or updates an entity type by deployment-wide slug.
1071
+ * A new slug is granted to the API key's workspace. A slug already shared
1072
+ * with another workspace is rejected unless the key belongs to a platform admin.
1067
1073
  * Prefer the CLI (`npx @lunnoa/client entity-types deploy`) for happy-path deploy.
1068
1074
  */
1069
1075
  upsertBySlug(definition) {
@@ -1416,7 +1422,7 @@ function computeDurationMs(start, end) {
1416
1422
  return b - a;
1417
1423
  }
1418
1424
  function defaultSleep(ms) {
1419
- return new Promise((resolve3) => setTimeout(resolve3, ms));
1425
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
1420
1426
  }
1421
1427
 
1422
1428
  // src/resources/knowledge.ts
@@ -1601,10 +1607,11 @@ var QueueItemsResource = class {
1601
1607
  listRetryable(queueId) {
1602
1608
  return this.http.get(`/api/queues/${queueId}/items/retry`);
1603
1609
  }
1604
- /** Returns items with the given status. */
1605
- listByStatus(queueId, status) {
1610
+ /** Returns a page of items with the given status. */
1611
+ listByStatus(queueId, status, options = {}) {
1606
1612
  return this.http.get(
1607
- `/api/queues/${queueId}/items/status/${status}`
1613
+ `/api/queues/${queueId}/items/status/${status}`,
1614
+ { query: { limit: options.limit, offset: options.offset } }
1608
1615
  );
1609
1616
  }
1610
1617
  /** Looks an item up by the external ID your system supplied. */
@@ -1613,11 +1620,22 @@ var QueueItemsResource = class {
1613
1620
  `/api/queues/${queueId}/items/external/${externalId}`
1614
1621
  );
1615
1622
  }
1616
- /** Searches items in the queue. */
1617
- search(queueId, query) {
1618
- return this.http.get(`/api/queues/${queueId}/items/search`, {
1619
- query: { q: query }
1620
- });
1623
+ /**
1624
+ * Searches items by external id, item data, and metadata.
1625
+ * Returns one page, same shape as `list`.
1626
+ */
1627
+ search(queueId, query, options = {}) {
1628
+ return this.http.get(
1629
+ `/api/queues/${queueId}/items/search`,
1630
+ {
1631
+ query: {
1632
+ limit: options.limit,
1633
+ offset: options.offset,
1634
+ expansion: serializeCsv(options.expansion),
1635
+ filterBy: serializeFilterBy({ search: query })
1636
+ }
1637
+ }
1638
+ );
1621
1639
  }
1622
1640
  /** Returns per-status and per-priority counts for the queue. */
1623
1641
  stats(queueId) {
@@ -1653,10 +1671,21 @@ var QueueItemsResource = class {
1653
1671
  addError(queueId, itemId, error) {
1654
1672
  return this.http.post(
1655
1673
  `/api/queues/${queueId}/items/${itemId}/error`,
1656
- { body: error }
1674
+ {
1675
+ body: {
1676
+ error: error.error,
1677
+ errorDetails: serializeErrorDetails(error.errorDetails)
1678
+ }
1679
+ }
1657
1680
  );
1658
1681
  }
1659
1682
  };
1683
+ function serializeErrorDetails(value) {
1684
+ if (value === void 0) {
1685
+ return void 0;
1686
+ }
1687
+ return typeof value === "string" ? value : JSON.stringify(value);
1688
+ }
1660
1689
 
1661
1690
  // src/resources/queues.ts
1662
1691
  var QueuesResource = class {
@@ -1783,6 +1812,32 @@ var RunsResource = class {
1783
1812
  }
1784
1813
  };
1785
1814
 
1815
+ // src/resources/scorecards.ts
1816
+ var ScorecardsResource = class {
1817
+ constructor(http) {
1818
+ this.http = http;
1819
+ }
1820
+ http;
1821
+ /** Lists scorecards in the workspace. */
1822
+ list() {
1823
+ return this.http.get("/api/scorecards");
1824
+ }
1825
+ /** Returns a scorecard with objectives, measures, latest values and status. */
1826
+ get(scorecardId) {
1827
+ return this.http.get(`/api/scorecards/${scorecardId}`);
1828
+ }
1829
+ /**
1830
+ * Records a measure value. A value for the same period replaces the current
1831
+ * one; the old value is kept as superseded history.
1832
+ */
1833
+ recordValue(measureId, data) {
1834
+ return this.http.post(
1835
+ `/api/scorecards/measures/${measureId}/values`,
1836
+ { body: data }
1837
+ );
1838
+ }
1839
+ };
1840
+
1786
1841
  // src/resources/tasks.ts
1787
1842
  var TasksResource = class {
1788
1843
  constructor(http) {
@@ -1833,12 +1888,7 @@ var TasksResource = class {
1833
1888
  } : message;
1834
1889
  return this.http.post(
1835
1890
  `/api/agents/${agentId}/tasks/${taskId}/message`,
1836
- {
1837
- body: {
1838
- messages: [uiMessage],
1839
- ...options.chatMode ? { chatMode: options.chatMode } : {}
1840
- }
1841
- }
1891
+ { body: messageTaskBody(uiMessage, options) }
1842
1892
  );
1843
1893
  }
1844
1894
  };
@@ -2021,6 +2071,7 @@ var LunnoaClient = class {
2021
2071
  queues;
2022
2072
  queueItems;
2023
2073
  variables;
2074
+ scorecards;
2024
2075
  connections;
2025
2076
  projects;
2026
2077
  workflowApps;
@@ -2043,6 +2094,7 @@ var LunnoaClient = class {
2043
2094
  this.queues = new QueuesResource(this.http);
2044
2095
  this.queueItems = new QueueItemsResource(this.http);
2045
2096
  this.variables = new VariablesResource(this.http);
2097
+ this.scorecards = new ScorecardsResource(this.http);
2046
2098
  this.connections = new ConnectionsResource(this.http);
2047
2099
  this.projects = new ProjectsResource(this.http);
2048
2100
  this.discovery = new DiscoveryResource(this.http);
@@ -2057,7 +2109,8 @@ var GROUPS_WITH_SUBCOMMAND = /* @__PURE__ */ new Set([
2057
2109
  "tools",
2058
2110
  "apps",
2059
2111
  "connections",
2060
- "projects"
2112
+ "projects",
2113
+ "skills"
2061
2114
  ]);
2062
2115
  var VALUE_FLAGS = /* @__PURE__ */ new Set([
2063
2116
  "--url",
@@ -2164,6 +2217,9 @@ var USAGE = `Usage:
2164
2217
  npx @lunnoa/client agents deploy <path> --url <url> --api-key <key> --project-id <uuid>
2165
2218
  npx @lunnoa/client entity-types deploy <path> --url <url> --api-key <key>
2166
2219
 
2220
+ Agent skills (copies this version's skills into .claude/skills and .cursor/skills):
2221
+ npx @lunnoa/client skills install [projectDir]
2222
+
2167
2223
  Options:
2168
2224
  --url Base URL of the Lunnoa Automate deployment
2169
2225
  --api-key Machine API key (lna_...)
@@ -2179,8 +2235,9 @@ Environment: LUNNOA_URL, LUNNOA_API_KEY, LUNNOA_PROJECT_ID
2179
2235
  Optional config file: lunnoa.config.ts | .mjs | .js | .json
2180
2236
 
2181
2237
  tools get prints inputConfig and a defineAction() sketch. tools list is compact;
2182
- run tools get for the schema. Entity-type deploy is workspace-scoped (no
2183
- --project-id). Unknown instance attributes are rejected unless
2238
+ run tools get for the schema. Entity-type deploy uses a deployment-wide slug
2239
+ and grants the API key's workspace when the slug is new (no --project-id).
2240
+ A slug already granted to other workspaces is not rewritten. Unknown instance attributes are rejected unless
2184
2241
  allowUnknownAttributes is true; use extensions.
2185
2242
  `;
2186
2243
 
@@ -2831,7 +2888,7 @@ function generateDeploymentModule(definitions) {
2831
2888
  *
2832
2889
  * Schema fingerprint: ${schemaFingerprint}
2833
2890
  */
2834
- import type { LunnoaClient, Entity, Execution, ExecuteWorkflowResult, PaginatedEntities, Task, AgentChatStream, WaitUntilFinishedOptions, ListEntitiesOptions, UIMessage } from '@lunnoa/client';
2891
+ import type { LunnoaClient, Entity, Execution, ExecuteWorkflowResult, PaginatedEntities, Task, AgentChatStream, WaitUntilFinishedOptions, ListEntitiesOptions, StreamMessageOptions, UIMessage } from '@lunnoa/client';
2835
2892
 
2836
2893
  /** Fingerprint of entity-type schemas at codegen time (slug:revision:allowUnknown). */
2837
2894
  export const DEPLOYMENT_SCHEMA_FINGERPRINT = ${JSON.stringify(schemaFingerprint)};
@@ -3019,7 +3076,7 @@ function typedEntityAccessor<A, S extends string>(
3019
3076
  })) as Typed;
3020
3077
  },
3021
3078
  /** Creates an entity of this type with compile-time checked attributes. */
3022
- async create(data: { name: string; attributes?: A; state?: S; ownerId?: string }): Promise<Typed> {
3079
+ async create(data: { name: string; attributes?: A; state?: S }): Promise<Typed> {
3023
3080
  return (await client.entities.create(
3024
3081
  { ...data, objectTypeId } as never,
3025
3082
  { expansion: ['attributes'] },
@@ -3028,7 +3085,7 @@ function typedEntityAccessor<A, S extends string>(
3028
3085
  /** Partially updates an entity of this type. */
3029
3086
  async update(
3030
3087
  entityId: string,
3031
- data: { name?: string; attributes?: Partial<A>; ownerId?: string },
3088
+ data: { name?: string; attributes?: Partial<A> },
3032
3089
  ): Promise<Typed> {
3033
3090
  return (await client.entities.update(entityId, data as never, {
3034
3091
  expansion: ['attributes'],
@@ -3074,13 +3131,17 @@ function typedAgentAccessor(client: LunnoaClient, agentId: string) {
3074
3131
  streamMessage(
3075
3132
  taskId: string,
3076
3133
  message: string | UIMessage,
3077
- options?: { chatMode?: 'builder' | 'preview'; signal?: AbortSignal },
3134
+ options?: StreamMessageOptions,
3078
3135
  ): Promise<AgentChatStream> {
3079
3136
  return client.agentChat.streamMessage(agentId, taskId, message, options);
3080
3137
  },
3081
3138
  /** Sends a message and waits for the full turn (non-streaming). */
3082
- message(taskId: string, message: string | UIMessage) {
3083
- return client.tasks.message(agentId, taskId, message);
3139
+ message(
3140
+ taskId: string,
3141
+ message: string | UIMessage,
3142
+ options?: Omit<StreamMessageOptions, 'signal'>,
3143
+ ) {
3144
+ return client.tasks.message(agentId, taskId, message, options);
3084
3145
  },
3085
3146
  };
3086
3147
  }
@@ -3176,6 +3237,26 @@ async function loadOptionalConfig() {
3176
3237
  return {};
3177
3238
  }
3178
3239
 
3240
+ // src/cli/skills.ts
3241
+ import { cp } from "fs/promises";
3242
+ import { dirname, resolve as resolve2 } from "path";
3243
+ import { fileURLToPath } from "url";
3244
+ var SKILL_TARGETS = [".claude/skills", ".cursor/skills"];
3245
+ var BUNDLED_SKILLS_DIR = resolve2(
3246
+ dirname(fileURLToPath(import.meta.url)),
3247
+ "..",
3248
+ "skills"
3249
+ );
3250
+ async function installSkills(projectDir, sourceDir = BUNDLED_SKILLS_DIR) {
3251
+ const written = [];
3252
+ for (const target of SKILL_TARGETS) {
3253
+ const dest = resolve2(projectDir, target);
3254
+ await cp(sourceDir, dest, { recursive: true, force: true });
3255
+ written.push(dest);
3256
+ }
3257
+ return written;
3258
+ }
3259
+
3179
3260
  // src/cli/index.ts
3180
3261
  async function bindClient(args) {
3181
3262
  const fileConfig = await loadOptionalConfig();
@@ -3231,9 +3312,9 @@ async function runCodegen(args) {
3231
3312
  `Found ${definitions.entityTypes.length} entity type(s), ${definitions.workflows.length} workflow(s), ${definitions.agents.length} agent(s).`
3232
3313
  );
3233
3314
  const moduleSource = generateDeploymentModule(definitions);
3234
- const outDir = resolve2(process.cwd(), args.out);
3315
+ const outDir = resolve3(process.cwd(), args.out);
3235
3316
  await mkdir(outDir, { recursive: true });
3236
- const outFile = resolve2(outDir, "lunnoa.generated.ts");
3317
+ const outFile = resolve3(outDir, "lunnoa.generated.ts");
3237
3318
  await writeFile(outFile, moduleSource, "utf8");
3238
3319
  console.log(`Wrote ${outFile}`);
3239
3320
  }
@@ -3405,6 +3486,13 @@ async function main() {
3405
3486
  console.log(USAGE);
3406
3487
  return;
3407
3488
  }
3489
+ if (args.command === "skills" && args.subcommand === "install") {
3490
+ const written = await installSkills(resolve3(process.cwd(), args.path ?? "."));
3491
+ for (const dest of written) {
3492
+ console.log(`Installed Lunnoa skills into ${dest}`);
3493
+ }
3494
+ return;
3495
+ }
3408
3496
  if (args.command === "codegen") {
3409
3497
  await runCodegen(args);
3410
3498
  return;
package/dist/index.cjs CHANGED
@@ -426,10 +426,7 @@ var AgentChatClient = class {
426
426
  raw: true,
427
427
  signal: options.signal,
428
428
  headers: { Accept: "text/event-stream" },
429
- body: {
430
- messages: [uiMessage],
431
- ...options.chatMode ? { chatMode: options.chatMode } : {}
432
- }
429
+ body: messageTaskBody(uiMessage, options)
433
430
  }
434
431
  );
435
432
  return new AgentChatStream(response, { signal: options.signal });
@@ -468,6 +465,14 @@ var AgentChatClient = class {
468
465
  );
469
466
  }
470
467
  };
468
+ function messageTaskBody(message, options = {}) {
469
+ return {
470
+ messages: [message],
471
+ ...options.chatMode ? { chatMode: options.chatMode } : {},
472
+ ...options.data ? { data: options.data } : {},
473
+ ...options.piiResolution ? { piiResolution: options.piiResolution } : {}
474
+ };
475
+ }
471
476
  function generateMessageId() {
472
477
  const cryptoObj = globalThis.crypto;
473
478
  if (cryptoObj?.randomUUID) {
@@ -1047,7 +1052,6 @@ var EntitiesResource = class {
1047
1052
  objectTypeSlug: options.objectTypeSlug,
1048
1053
  state: options.state,
1049
1054
  states: options.states?.join(","),
1050
- ownerId: options.ownerId,
1051
1055
  search: options.search,
1052
1056
  sortBy: options.sortBy,
1053
1057
  sortOrder: options.sortOrder,
@@ -1080,7 +1084,7 @@ var EntityTypesResource = class {
1080
1084
  }
1081
1085
  http;
1082
1086
  /**
1083
- * Lists entity types in the workspace. Request
1087
+ * Lists entity types granted to the API key's workspace. Request
1084
1088
  * `expansion: ['attributeSchema', 'stateSchema']` for the field and state
1085
1089
  * machine definitions the codegen CLI builds types from.
1086
1090
  */
@@ -1105,7 +1109,9 @@ var EntityTypesResource = class {
1105
1109
  });
1106
1110
  }
1107
1111
  /**
1108
- * Creates or updates an entity type by workspace-scoped slug.
1112
+ * Creates or updates an entity type by deployment-wide slug.
1113
+ * A new slug is granted to the API key's workspace. A slug already shared
1114
+ * with another workspace is rejected unless the key belongs to a platform admin.
1109
1115
  * Prefer the CLI (`npx @lunnoa/client entity-types deploy`) for happy-path deploy.
1110
1116
  */
1111
1117
  upsertBySlug(definition) {
@@ -1643,10 +1649,11 @@ var QueueItemsResource = class {
1643
1649
  listRetryable(queueId) {
1644
1650
  return this.http.get(`/api/queues/${queueId}/items/retry`);
1645
1651
  }
1646
- /** Returns items with the given status. */
1647
- listByStatus(queueId, status) {
1652
+ /** Returns a page of items with the given status. */
1653
+ listByStatus(queueId, status, options = {}) {
1648
1654
  return this.http.get(
1649
- `/api/queues/${queueId}/items/status/${status}`
1655
+ `/api/queues/${queueId}/items/status/${status}`,
1656
+ { query: { limit: options.limit, offset: options.offset } }
1650
1657
  );
1651
1658
  }
1652
1659
  /** Looks an item up by the external ID your system supplied. */
@@ -1655,11 +1662,22 @@ var QueueItemsResource = class {
1655
1662
  `/api/queues/${queueId}/items/external/${externalId}`
1656
1663
  );
1657
1664
  }
1658
- /** Searches items in the queue. */
1659
- search(queueId, query) {
1660
- return this.http.get(`/api/queues/${queueId}/items/search`, {
1661
- query: { q: query }
1662
- });
1665
+ /**
1666
+ * Searches items by external id, item data, and metadata.
1667
+ * Returns one page, same shape as `list`.
1668
+ */
1669
+ search(queueId, query, options = {}) {
1670
+ return this.http.get(
1671
+ `/api/queues/${queueId}/items/search`,
1672
+ {
1673
+ query: {
1674
+ limit: options.limit,
1675
+ offset: options.offset,
1676
+ expansion: serializeCsv(options.expansion),
1677
+ filterBy: serializeFilterBy({ search: query })
1678
+ }
1679
+ }
1680
+ );
1663
1681
  }
1664
1682
  /** Returns per-status and per-priority counts for the queue. */
1665
1683
  stats(queueId) {
@@ -1695,10 +1713,21 @@ var QueueItemsResource = class {
1695
1713
  addError(queueId, itemId, error) {
1696
1714
  return this.http.post(
1697
1715
  `/api/queues/${queueId}/items/${itemId}/error`,
1698
- { body: error }
1716
+ {
1717
+ body: {
1718
+ error: error.error,
1719
+ errorDetails: serializeErrorDetails(error.errorDetails)
1720
+ }
1721
+ }
1699
1722
  );
1700
1723
  }
1701
1724
  };
1725
+ function serializeErrorDetails(value) {
1726
+ if (value === void 0) {
1727
+ return void 0;
1728
+ }
1729
+ return typeof value === "string" ? value : JSON.stringify(value);
1730
+ }
1702
1731
 
1703
1732
  // src/resources/queues.ts
1704
1733
  var QueuesResource = class {
@@ -1825,6 +1854,32 @@ var RunsResource = class {
1825
1854
  }
1826
1855
  };
1827
1856
 
1857
+ // src/resources/scorecards.ts
1858
+ var ScorecardsResource = class {
1859
+ constructor(http) {
1860
+ this.http = http;
1861
+ }
1862
+ http;
1863
+ /** Lists scorecards in the workspace. */
1864
+ list() {
1865
+ return this.http.get("/api/scorecards");
1866
+ }
1867
+ /** Returns a scorecard with objectives, measures, latest values and status. */
1868
+ get(scorecardId) {
1869
+ return this.http.get(`/api/scorecards/${scorecardId}`);
1870
+ }
1871
+ /**
1872
+ * Records a measure value. A value for the same period replaces the current
1873
+ * one; the old value is kept as superseded history.
1874
+ */
1875
+ recordValue(measureId, data) {
1876
+ return this.http.post(
1877
+ `/api/scorecards/measures/${measureId}/values`,
1878
+ { body: data }
1879
+ );
1880
+ }
1881
+ };
1882
+
1828
1883
  // src/resources/tasks.ts
1829
1884
  var TasksResource = class {
1830
1885
  constructor(http) {
@@ -1875,12 +1930,7 @@ var TasksResource = class {
1875
1930
  } : message;
1876
1931
  return this.http.post(
1877
1932
  `/api/agents/${agentId}/tasks/${taskId}/message`,
1878
- {
1879
- body: {
1880
- messages: [uiMessage],
1881
- ...options.chatMode ? { chatMode: options.chatMode } : {}
1882
- }
1883
- }
1933
+ { body: messageTaskBody(uiMessage, options) }
1884
1934
  );
1885
1935
  }
1886
1936
  };
@@ -2063,6 +2113,7 @@ var LunnoaClient = class {
2063
2113
  queues;
2064
2114
  queueItems;
2065
2115
  variables;
2116
+ scorecards;
2066
2117
  connections;
2067
2118
  projects;
2068
2119
  workflowApps;
@@ -2085,6 +2136,7 @@ var LunnoaClient = class {
2085
2136
  this.queues = new QueuesResource(this.http);
2086
2137
  this.queueItems = new QueueItemsResource(this.http);
2087
2138
  this.variables = new VariablesResource(this.http);
2139
+ this.scorecards = new ScorecardsResource(this.http);
2088
2140
  this.connections = new ConnectionsResource(this.http);
2089
2141
  this.projects = new ProjectsResource(this.http);
2090
2142
  this.discovery = new DiscoveryResource(this.http);
@@ -2186,6 +2238,7 @@ exports.ProjectsResource = ProjectsResource;
2186
2238
  exports.QueueItemsResource = QueueItemsResource;
2187
2239
  exports.QueuesResource = QueuesResource;
2188
2240
  exports.RunsResource = RunsResource;
2241
+ exports.ScorecardsResource = ScorecardsResource;
2189
2242
  exports.SsoAuthResource = SsoAuthResource;
2190
2243
  exports.TasksResource = TasksResource;
2191
2244
  exports.VariablesResource = VariablesResource;