@cat-factory/server 0.323.0 → 0.325.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.
Files changed (57) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +5 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/modules/publicApi/PublicApiController.d.ts.map +1 -1
  5. package/dist/modules/publicApi/PublicApiController.js +5 -292
  6. package/dist/modules/publicApi/PublicApiController.js.map +1 -1
  7. package/dist/modules/publicApi/PublicDecisionController.d.ts.map +1 -1
  8. package/dist/modules/publicApi/PublicDecisionController.js +2 -0
  9. package/dist/modules/publicApi/PublicDecisionController.js.map +1 -1
  10. package/dist/modules/publicApi/PublicFragmentController.d.ts +4 -0
  11. package/dist/modules/publicApi/PublicFragmentController.d.ts.map +1 -0
  12. package/dist/modules/publicApi/PublicFragmentController.js +61 -0
  13. package/dist/modules/publicApi/PublicFragmentController.js.map +1 -0
  14. package/dist/modules/publicApi/boardProjection.d.ts.map +1 -1
  15. package/dist/modules/publicApi/boardProjection.js +4 -0
  16. package/dist/modules/publicApi/boardProjection.js.map +1 -1
  17. package/dist/modules/publicApi/decisions/bugFishingProjection.d.ts +19 -0
  18. package/dist/modules/publicApi/decisions/bugFishingProjection.d.ts.map +1 -0
  19. package/dist/modules/publicApi/decisions/bugFishingProjection.js +130 -0
  20. package/dist/modules/publicApi/decisions/bugFishingProjection.js.map +1 -0
  21. package/dist/modules/publicApi/decisions/bugFishingRoutes.d.ts +4 -0
  22. package/dist/modules/publicApi/decisions/bugFishingRoutes.d.ts.map +1 -0
  23. package/dist/modules/publicApi/decisions/bugFishingRoutes.js +73 -0
  24. package/dist/modules/publicApi/decisions/bugFishingRoutes.js.map +1 -0
  25. package/dist/modules/publicApi/decisions/projection.d.ts +21 -0
  26. package/dist/modules/publicApi/decisions/projection.d.ts.map +1 -1
  27. package/dist/modules/publicApi/decisions/projection.js +65 -11
  28. package/dist/modules/publicApi/decisions/projection.js.map +1 -1
  29. package/dist/modules/publicApi/fragmentCatalog.d.ts +47 -0
  30. package/dist/modules/publicApi/fragmentCatalog.d.ts.map +1 -0
  31. package/dist/modules/publicApi/fragmentCatalog.js +106 -0
  32. package/dist/modules/publicApi/fragmentCatalog.js.map +1 -0
  33. package/dist/modules/publicApi/openapiDocument.generated.d.ts +1 -1
  34. package/dist/modules/publicApi/openapiDocument.generated.d.ts.map +1 -1
  35. package/dist/modules/publicApi/openapiDocument.generated.js +1 -1
  36. package/dist/modules/publicApi/openapiDocument.generated.js.map +1 -1
  37. package/dist/modules/publicApi/publicApiAdmission.d.ts +1 -1
  38. package/dist/modules/publicApi/publicApiAdmission.d.ts.map +1 -1
  39. package/dist/modules/publicApi/publicApiAdmission.js +5 -1
  40. package/dist/modules/publicApi/publicApiAdmission.js.map +1 -1
  41. package/dist/modules/publicApi/publicApiStream.d.ts +50 -1
  42. package/dist/modules/publicApi/publicApiStream.d.ts.map +1 -1
  43. package/dist/modules/publicApi/publicApiStream.js +83 -5
  44. package/dist/modules/publicApi/publicApiStream.js.map +1 -1
  45. package/dist/modules/publicApi/publicApiStreamRoutes.d.ts +30 -0
  46. package/dist/modules/publicApi/publicApiStreamRoutes.d.ts.map +1 -0
  47. package/dist/modules/publicApi/publicApiStreamRoutes.js +275 -0
  48. package/dist/modules/publicApi/publicApiStreamRoutes.js.map +1 -0
  49. package/dist/modules/publicApi/runProjection.d.ts +30 -0
  50. package/dist/modules/publicApi/runProjection.d.ts.map +1 -0
  51. package/dist/modules/publicApi/runProjection.js +127 -0
  52. package/dist/modules/publicApi/runProjection.js.map +1 -0
  53. package/dist/modules/publicApi/taskCreation.d.ts +2 -0
  54. package/dist/modules/publicApi/taskCreation.d.ts.map +1 -1
  55. package/dist/modules/publicApi/taskCreation.js +20 -12
  56. package/dist/modules/publicApi/taskCreation.js.map +1 -1
  57. package/package.json +8 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runProjection.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/runProjection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAe/C;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,iBAAiB,EAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,SAAS,CAwCX;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,SAAS,CA4CX;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,MAAM,EAClD,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAMnC"}
@@ -0,0 +1,127 @@
1
+ import { jobSortKey, mapStatus } from './publicApiPaging.js';
2
+ import { viewRunIdentity } from './runIdentityVisibility.js';
3
+ // The two RUN projections the public surface serves, plus the scoped load behind the job half.
4
+ //
5
+ // Extracted from `PublicApiController` because they have three consumers rather than one: the
6
+ // point reads in that controller, the two SSE loops in `publicApiStreamRoutes.ts`, and (through
7
+ // the stream) the decision channel. Keeping them there would have made the stream file import the
8
+ // controller that registers it.
9
+ //
10
+ // Both are PURE functions of the run plus the reading key's identity, which is what lets an SSE
11
+ // loop render frame after frame without a second read: see `runIdentityVisibility.ts` for why the
12
+ // reader is a parameter rather than something looked up in here.
13
+ /**
14
+ * Project a persisted execution onto the external job resource (no block/board internals).
15
+ *
16
+ * Takes the READING key's own identity because the run's pinned one is not visible to every key
17
+ * (`runIdentityVisibility.ts` holds the rule and why there is one). Passed as a parameter rather
18
+ * than read off the context here, so the projection stays a pure function of the run plus the
19
+ * caller and the SSE loops can render frame after frame without re-reading anything.
20
+ */
21
+ export function toPublicJob(execution, readerIdentity) {
22
+ const status = mapStatus(execution.status);
23
+ const identity = viewRunIdentity(execution.initiatedByExternalIdentity, readerIdentity);
24
+ // The deliverable is the LAST step that actually produced output, normally the terminal step,
25
+ // but scanning from the end keeps the result meaningful for a multi-step public pipeline whose
26
+ // final step is a side-effect-only tail that emits nothing (the built-in initiative pipeline is
27
+ // single-step, so this simply picks that step). Fall back to the terminal step so a `succeeded`
28
+ // run always carries a (possibly empty) result rather than null.
29
+ const withOutput = [...execution.steps]
30
+ .reverse()
31
+ .find((s) => (s.output ?? '') !== '' || s.custom != null);
32
+ const deliverable = withOutput ?? execution.steps[execution.steps.length - 1];
33
+ const result = status === 'succeeded' && deliverable
34
+ ? { output: deliverable.output ?? '', data: deliverable.custom ?? null }
35
+ : null;
36
+ const error = status === 'failed'
37
+ ? execution.failure
38
+ ? { code: execution.failure.kind, message: execution.failure.message }
39
+ : { code: 'run_failed', message: 'The run failed' }
40
+ : null;
41
+ return {
42
+ jobId: execution.id,
43
+ status,
44
+ pipelineId: execution.pipelineId,
45
+ // Pinned at admission from the starting key, so it survives that key's revocation and costs
46
+ // this projection no lookup (`toPublicJob` also renders every row of a paged list). Withheld
47
+ // from a key that acts for someone else, which the flag STATES rather than blanking to a
48
+ // `null` that already means "this run names nobody". Named field by field rather than spread,
49
+ // for the reason `keyProjection.ts` gives: a spread is exempt from excess-property checking,
50
+ // so a member added to the view type later would reach the wire with nothing to stop it.
51
+ externalIdentity: identity.externalIdentity,
52
+ externalIdentityWithheld: identity.externalIdentityWithheld,
53
+ // The run's own creation stamp: the SAME value the list's keyset cursor is minted from
54
+ // (`jobSortKey`), so a caller can page and correlate on one consistent number.
55
+ createdAt: jobSortKey(execution),
56
+ result,
57
+ error,
58
+ };
59
+ }
60
+ /**
61
+ * Project a task's persisted run + its block onto the RICH external run resource: per-step
62
+ * state/progress/subtasks, the failure kind+message, and the PR (url + branch). The run's
63
+ * `status` is the raw execution status (`running`/`blocked`/`paused`/`done`/`failed`): the
64
+ * public run view deliberately surfaces the parked states (unlike the coarse `publicJob`), so
65
+ * a caller can tell an awaiting-a-human `blocked` from a still-`running` step. The PR branch
66
+ * lives on the BLOCK (`block.pullRequest`), not the run, so both are joined here.
67
+ */
68
+ export function toPublicRun(execution, block, readerIdentity) {
69
+ const pr = block.pullRequest;
70
+ const identity = viewRunIdentity(execution.initiatedByExternalIdentity, readerIdentity);
71
+ return {
72
+ runId: execution.id,
73
+ taskId: block.id,
74
+ status: execution.status,
75
+ createdAt: jobSortKey(execution),
76
+ currentStep: execution.currentStep,
77
+ steps: execution.steps.map((s) => ({
78
+ agentKind: s.agentKind,
79
+ state: s.state,
80
+ progress: s.progress,
81
+ subtasks: s.subtasks
82
+ ? {
83
+ completed: s.subtasks.completed,
84
+ inProgress: s.subtasks.inProgress,
85
+ total: s.subtasks.total,
86
+ }
87
+ : null,
88
+ // The step's deliverable. An EMPTY output is projected as null, matching the way
89
+ // `toPublicJob` reads "produced something": a step that ran and wrote nothing and a step
90
+ // that has not run yet are the same fact to a caller reading for a result, and the step's
91
+ // own `state` is what distinguishes them.
92
+ output: (s.output ?? '') === '' ? null : (s.output ?? null),
93
+ data: s.custom ?? null,
94
+ // Only when true: a step that RAN carries no flag at all, so the field never has to be read
95
+ // as "false, and also this run is old enough to predate the projection".
96
+ ...(s.skipped ? { skipped: true } : {}),
97
+ })),
98
+ // Who the run was started for, as pinned at admission; null for a run the app, a schedule or
99
+ // an identity-less key started, and withheld (flagged, not blanked) from a key that acts for
100
+ // someone else. See `runIdentityVisibility.ts`, and `toPublicJob` for why both members are
101
+ // named rather than spread.
102
+ externalIdentity: identity.externalIdentity,
103
+ externalIdentityWithheld: identity.externalIdentityWithheld,
104
+ pullRequest: pr ? { url: pr.url, branch: pr.branch ?? null } : null,
105
+ error: execution.status === 'failed'
106
+ ? execution.failure
107
+ ? { code: execution.failure.kind, message: execution.failure.message }
108
+ : { code: 'run_failed', message: 'The run failed' }
109
+ : null,
110
+ };
111
+ }
112
+ /**
113
+ * Load a public JOB by id for an authenticated key: the persisted execution, but ONLY when it is
114
+ * anchored on a HEADLESS internal block (a run this public surface created). Returns null when no
115
+ * such run exists in the key's workspace OR the id points at a normal board execution, so an
116
+ * external key can never read an arbitrary in-workspace run's output, only its own headless jobs.
117
+ * Runtime-symmetric: one `executionRepository.get` + one `boardService.getInternalTask` point-read.
118
+ */
119
+ export async function loadPublicJob(c, workspaceId, id) {
120
+ const container = c.get('container');
121
+ const execution = await container.executionRepository.get(workspaceId, id);
122
+ if (!execution)
123
+ return null;
124
+ const anchor = await container.boardService.getInternalTask(workspaceId, execution.blockId);
125
+ return anchor ? execution : null;
126
+ }
127
+ //# sourceMappingURL=runProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runProjection.js","sourceRoot":"","sources":["../../../src/modules/publicApi/runProjection.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export interface PublicTaskCreationDeps {
8
8
  taskTypeRegistry: ServerContainer['taskTypeRegistry'];
9
9
  tasks: ServerContainer['tasks'];
10
10
  documents: ServerContainer['documents'];
11
+ /** The merged best-practice catalog a named `fragmentIds` is checked against; absent ⇒ a 503. */
12
+ fragmentLibrary: ServerContainer['fragmentLibrary'];
11
13
  logger: Logger;
12
14
  }
13
15
  /** Read the collaborators this module drives off the request's container. */
@@ -1 +1 @@
1
- {"version":3,"file":"taskCreation.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/taskCreation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAyBxD,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IAC7C,iGAAiG;IACjG,gBAAgB,EAAE,eAAe,CAAC,kBAAkB,CAAC,CAAA;IACrD,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAA;IAC/B,SAAS,EAAE,eAAe,CAAC,WAAW,CAAC,CAAA;IACvC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,sBAAsB,CAQnF;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,sBAAsB,EAC5B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,KAAK,CAAC,CAgDhB"}
1
+ {"version":3,"file":"taskCreation.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/taskCreation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAsCxD,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IAC7C,iGAAiG;IACjG,gBAAgB,EAAE,eAAe,CAAC,kBAAkB,CAAC,CAAA;IACrD,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAA;IAC/B,SAAS,EAAE,eAAe,CAAC,WAAW,CAAC,CAAA;IACvC,iGAAiG;IACjG,eAAe,EAAE,eAAe,CAAC,iBAAiB,CAAC,CAAA;IACnD,MAAM,EAAE,MAAM,CAAA;CACf;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,sBAAsB,CASnF;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,sBAAsB,EAC5B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,KAAK,CAAC,CAsDhB"}
@@ -1,5 +1,6 @@
1
1
  import { UNATTRIBUTED_BLOCK_EDIT_AUTHORITY } from '@cat-factory/contracts';
2
2
  import { releaseUnattachedTask, resolveDocuments } from './documentAttachment.js';
3
+ import { assertFragmentsResolvable } from './fragmentCatalog.js';
3
4
  import { resolveTaskTypeFields } from './taskTypeFields.js';
4
5
  import { resolveTicket } from './ticketLinkage.js';
5
6
  /** Read the collaborators this module drives off the request's container. */
@@ -9,6 +10,7 @@ export function taskCreationDeps(container) {
9
10
  taskTypeRegistry: container.taskTypeRegistry,
10
11
  tasks: container.tasks,
11
12
  documents: container.documents,
13
+ fragmentLibrary: container.fragmentLibrary,
12
14
  logger: container.logger,
13
15
  };
14
16
  }
@@ -26,19 +28,25 @@ export async function createTaskWithAttachments(deps, workspaceId, serviceId, bo
26
28
  // is a pure, deterministic refusal, so it must land ahead of the outbound ticket/document
27
29
  // fetches, exactly like the container check below.
28
30
  const taskTypeFields = resolveTaskTypeFields(body, deps.taskTypeRegistry);
29
- // `modelPresetId` and `riskPolicyId` ride the spread because the public surface spells them
30
- // exactly as `AddTaskInput` does, which is the ONE reason a spread is safe here and is pinned by
31
- // `blockEditAuthority.coverage.spec.ts`. Whether either id names a real row is `addServiceTask`'s
32
- // to refuse, on the service where every other door reaches it too (`presetPinGuard.ts`).
31
+ // The container is checked before anything is fetched, read per workspace, or written, and
32
+ // UNCONDITIONALLY, not only when there is an outbound fetch to save. A `serviceId` that names
33
+ // nothing is the caller's most basic mistake, and every refusal that runs ahead of it answers a
34
+ // request about a service that does not exist by complaining about something else: a typo'd
35
+ // path carrying an unknown standard would come back `422 prompt_fragment_not_found`, telling the
36
+ // integrator its service was fine and sending it to fix the wrong end. `addServiceTask`
37
+ // re-applies the same rule (it is the one that must hold at the moment of the write); this moves
38
+ // the cheap, deterministic half of it in front of everything.
39
+ await deps.boardService.assertTaskContainer(workspaceId, serviceId);
40
+ // Then the standards: one the workspace does not resolve is refused before anything is fetched
41
+ // or written. See `fragmentCatalog.ts` for why the run path's "drop a stale id" is the wrong
42
+ // disposition for a list a caller just named.
43
+ await assertFragmentsResolvable(deps.fragmentLibrary, workspaceId, body.fragmentIds);
44
+ // `modelPresetId`, `riskPolicyId` and `fragmentIds` ride the spread because the public surface
45
+ // spells each exactly as `AddTaskInput` does, which is the ONE reason a spread is safe here and
46
+ // is pinned by `blockEditAuthority.coverage.spec.ts`. Whether the two PINS name a real row is
47
+ // `addServiceTask`'s to refuse, on the service where every other door reaches it too
48
+ // (`presetPinGuard.ts`); the standards were settled a few lines up, at this door.
33
49
  const input = { ...rest, ...(taskTypeFields ? { taskTypeFields } : {}) };
34
- if (ticket || documents?.length) {
35
- // The container is checked FIRST because resolving a ticket or a source document is an
36
- // outbound call to the workspace's own tracker/wiki: a bad `serviceId` should be answered by
37
- // the 404 it could have had for free, not paid for with a live third-party fetch.
38
- // `addServiceTask` re-applies the same rule (it is the one that must hold at the moment of the
39
- // write); this only moves the cheap, deterministic half of it in front of the expensive work.
40
- await deps.boardService.assertTaskContainer(workspaceId, serviceId);
41
- }
42
50
  const linkage = ticket ? await resolveTicket(deps, workspaceId, ticket) : null;
43
51
  const attachment = documents?.length ? await resolveDocuments(deps, workspaceId, documents) : null;
44
52
  // Unattributed by the same reading the headless RUN start gets (ADR 0037): an API key holds
@@ -1 +1 @@
1
- {"version":3,"file":"taskCreation.js","sourceRoot":"","sources":["../../../src/modules/publicApi/taskCreation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,wBAAwB,CAAA;AAI1E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAgClD,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,SAA0B;IACzD,OAAO;QACL,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;QAC5C,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;KACzB,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAA4B,EAC5B,WAAmB,EACnB,SAAiB,EACjB,IAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;IAC5D,gGAAgG;IAChG,0FAA0F;IAC1F,mDAAmD;IACnD,MAAM,cAAc,GAAG,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;IACzE,4FAA4F;IAC5F,iGAAiG;IACjG,kGAAkG;IAClG,yFAAyF;IACzF,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;IACxE,IAAI,MAAM,IAAI,SAAS,EAAE,MAAM,EAAE,CAAC;QAChC,uFAAuF;QACvF,6FAA6F;QAC7F,kFAAkF;QAClF,+FAA+F;QAC/F,8FAA8F;QAC9F,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,MAAM,UAAU,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAElG,4FAA4F;IAC5F,+FAA+F;IAC/F,qFAAqF;IACrF,qFAAqF;IACrF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAClD,WAAW,EACX,SAAS,EACT,KAAK,EACL,iCAAiC,CAClC,CAAA;IAED,IAAI,UAAU,EAAE,CAAC;QACf,0FAA0F;QAC1F,8FAA8F;QAC9F,gEAAgE;QAChE,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;YACxD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IACD,+FAA+F;IAC/F,wEAAwE;IACxE,IAAI,OAAO;QAAE,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC1C,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"taskCreation.js","sourceRoot":"","sources":["../../../src/modules/publicApi/taskCreation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/server",
3
- "version": "0.323.0",
3
+ "version": "0.325.0",
4
4
  "description": "Runtime-neutral HTTP layer for the Agent Architecture Board: the Hono controllers, middleware (auth/authz/CORS/error), request helpers and the gateway seams shared by every deployment facade (Cloudflare Worker, Node service).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,13 +24,13 @@
24
24
  "access": "public"
25
25
  },
26
26
  "dependencies": {
27
- "@cat-factory/agents": "0.165.0",
28
- "@cat-factory/contracts": "0.353.0",
29
- "@cat-factory/integrations": "0.173.1",
30
- "@cat-factory/kernel": "0.346.1",
31
- "@cat-factory/mcp-server": "0.50.0",
32
- "@cat-factory/orchestration": "0.311.0",
33
- "@cat-factory/spend": "0.21.7",
27
+ "@cat-factory/agents": "0.166.1",
28
+ "@cat-factory/contracts": "0.355.0",
29
+ "@cat-factory/integrations": "0.174.0",
30
+ "@cat-factory/kernel": "0.347.0",
31
+ "@cat-factory/mcp-server": "0.52.0",
32
+ "@cat-factory/orchestration": "0.313.0",
33
+ "@cat-factory/spend": "0.21.9",
34
34
  "@toad-contracts/core": "0.4.0",
35
35
  "@toad-contracts/hono": "0.3.2",
36
36
  "@toad-contracts/valibot": "0.5.0",