agentfootprint 9.20.0 → 9.22.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 (181) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +1 -1
  3. package/README.md +1 -0
  4. package/ai-instructions/claude-code/SKILL.md +1 -1
  5. package/dist/artifacts/capability.js +131 -0
  6. package/dist/artifacts/capability.js.map +1 -0
  7. package/dist/artifacts/fileArtifacts.js +230 -0
  8. package/dist/artifacts/fileArtifacts.js.map +1 -0
  9. package/dist/artifacts/inMemoryArtifacts.js +165 -0
  10. package/dist/artifacts/inMemoryArtifacts.js.map +1 -0
  11. package/dist/artifacts/index.js +47 -0
  12. package/dist/artifacts/index.js.map +1 -0
  13. package/dist/artifacts/minting.js +79 -0
  14. package/dist/artifacts/minting.js.map +1 -0
  15. package/dist/artifacts/naming.js +64 -0
  16. package/dist/artifacts/naming.js.map +1 -0
  17. package/dist/artifacts/payload.js +113 -0
  18. package/dist/artifacts/payload.js.map +1 -0
  19. package/dist/artifacts/placement.js +86 -0
  20. package/dist/artifacts/placement.js.map +1 -0
  21. package/dist/artifacts/present.js +98 -0
  22. package/dist/artifacts/present.js.map +1 -0
  23. package/dist/artifacts/retention.js +121 -0
  24. package/dist/artifacts/retention.js.map +1 -0
  25. package/dist/artifacts/sqliteArtifacts.js +338 -0
  26. package/dist/artifacts/sqliteArtifacts.js.map +1 -0
  27. package/dist/artifacts/types.js +96 -0
  28. package/dist/artifacts/types.js.map +1 -0
  29. package/dist/artifacts/wants.js +240 -0
  30. package/dist/artifacts/wants.js.map +1 -0
  31. package/dist/core/Agent.js +73 -2
  32. package/dist/core/Agent.js.map +1 -1
  33. package/dist/core/agent/buildToolRegistry.js +30 -1
  34. package/dist/core/agent/buildToolRegistry.js.map +1 -1
  35. package/dist/core/agent/presentTool.js +59 -0
  36. package/dist/core/agent/presentTool.js.map +1 -0
  37. package/dist/core/agent/stages/toolCalls.js +347 -8
  38. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  39. package/dist/core/codeRunnerTool.js +89 -3
  40. package/dist/core/codeRunnerTool.js.map +1 -1
  41. package/dist/core/tools.js +7 -0
  42. package/dist/core/tools.js.map +1 -1
  43. package/dist/esm/adapters/types.d.ts +17 -1
  44. package/dist/esm/artifacts/capability.d.ts +93 -0
  45. package/dist/esm/artifacts/capability.js +126 -0
  46. package/dist/esm/artifacts/capability.js.map +1 -0
  47. package/dist/esm/artifacts/fileArtifacts.d.ts +58 -0
  48. package/dist/esm/artifacts/fileArtifacts.js +225 -0
  49. package/dist/esm/artifacts/fileArtifacts.js.map +1 -0
  50. package/dist/esm/artifacts/inMemoryArtifacts.d.ts +54 -0
  51. package/dist/esm/artifacts/inMemoryArtifacts.js +161 -0
  52. package/dist/esm/artifacts/inMemoryArtifacts.js.map +1 -0
  53. package/dist/esm/artifacts/index.d.ts +21 -0
  54. package/dist/esm/artifacts/index.js +21 -0
  55. package/dist/esm/artifacts/index.js.map +1 -0
  56. package/dist/esm/artifacts/minting.d.ts +29 -0
  57. package/dist/esm/artifacts/minting.js +75 -0
  58. package/dist/esm/artifacts/minting.js.map +1 -0
  59. package/dist/esm/artifacts/naming.d.ts +36 -0
  60. package/dist/esm/artifacts/naming.js +59 -0
  61. package/dist/esm/artifacts/naming.js.map +1 -0
  62. package/dist/esm/artifacts/payload.d.ts +43 -0
  63. package/dist/esm/artifacts/payload.js +105 -0
  64. package/dist/esm/artifacts/payload.js.map +1 -0
  65. package/dist/esm/artifacts/placement.d.ts +74 -0
  66. package/dist/esm/artifacts/placement.js +79 -0
  67. package/dist/esm/artifacts/placement.js.map +1 -0
  68. package/dist/esm/artifacts/present.d.ts +77 -0
  69. package/dist/esm/artifacts/present.js +94 -0
  70. package/dist/esm/artifacts/present.js.map +1 -0
  71. package/dist/esm/artifacts/retention.d.ts +72 -0
  72. package/dist/esm/artifacts/retention.js +115 -0
  73. package/dist/esm/artifacts/retention.js.map +1 -0
  74. package/dist/esm/artifacts/sqliteArtifacts.d.ts +90 -0
  75. package/dist/esm/artifacts/sqliteArtifacts.js +333 -0
  76. package/dist/esm/artifacts/sqliteArtifacts.js.map +1 -0
  77. package/dist/esm/artifacts/types.d.ts +220 -0
  78. package/dist/esm/artifacts/types.js +90 -0
  79. package/dist/esm/artifacts/types.js.map +1 -0
  80. package/dist/esm/artifacts/wants.d.ts +104 -0
  81. package/dist/esm/artifacts/wants.js +234 -0
  82. package/dist/esm/artifacts/wants.js.map +1 -0
  83. package/dist/esm/core/Agent.d.ts +8 -2
  84. package/dist/esm/core/Agent.js +73 -2
  85. package/dist/esm/core/Agent.js.map +1 -1
  86. package/dist/esm/core/agent/buildToolRegistry.d.ts +11 -1
  87. package/dist/esm/core/agent/buildToolRegistry.js +30 -1
  88. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
  89. package/dist/esm/core/agent/presentTool.d.ts +22 -0
  90. package/dist/esm/core/agent/presentTool.js +55 -0
  91. package/dist/esm/core/agent/presentTool.js.map +1 -0
  92. package/dist/esm/core/agent/stages/toolCalls.d.ts +22 -0
  93. package/dist/esm/core/agent/stages/toolCalls.js +347 -8
  94. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  95. package/dist/esm/core/agent/types.d.ts +46 -0
  96. package/dist/esm/core/codeRunnerTool.js +89 -3
  97. package/dist/esm/core/codeRunnerTool.js.map +1 -1
  98. package/dist/esm/core/tools.d.ts +49 -0
  99. package/dist/esm/core/tools.js +7 -0
  100. package/dist/esm/core/tools.js.map +1 -1
  101. package/dist/esm/events/dispatcher.d.ts +1 -1
  102. package/dist/esm/events/dispatcher.js.map +1 -1
  103. package/dist/esm/events/payloads.d.ts +83 -0
  104. package/dist/esm/events/registry.d.ts +13 -1
  105. package/dist/esm/events/registry.js +12 -0
  106. package/dist/esm/events/registry.js.map +1 -1
  107. package/dist/esm/index.d.ts +3 -1
  108. package/dist/esm/index.js +17 -0
  109. package/dist/esm/index.js.map +1 -1
  110. package/dist/esm/lib/mcp/mcpServe.js +16 -0
  111. package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
  112. package/dist/esm/lib/trace-toolpack/traceToolpack.js +4 -0
  113. package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
  114. package/dist/esm/recorders/core/ArtifactsRecorder.d.ts +22 -0
  115. package/dist/esm/recorders/core/ArtifactsRecorder.js +27 -0
  116. package/dist/esm/recorders/core/ArtifactsRecorder.js.map +1 -0
  117. package/dist/events/dispatcher.js.map +1 -1
  118. package/dist/events/registry.js +12 -0
  119. package/dist/events/registry.js.map +1 -1
  120. package/dist/index.js +43 -8
  121. package/dist/index.js.map +1 -1
  122. package/dist/lib/mcp/mcpServe.js +16 -0
  123. package/dist/lib/mcp/mcpServe.js.map +1 -1
  124. package/dist/lib/trace-toolpack/traceToolpack.js +4 -0
  125. package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
  126. package/dist/recorders/core/ArtifactsRecorder.js +31 -0
  127. package/dist/recorders/core/ArtifactsRecorder.js.map +1 -0
  128. package/dist/types/adapters/types.d.ts +17 -1
  129. package/dist/types/adapters/types.d.ts.map +1 -1
  130. package/dist/types/artifacts/capability.d.ts +94 -0
  131. package/dist/types/artifacts/capability.d.ts.map +1 -0
  132. package/dist/types/artifacts/fileArtifacts.d.ts +59 -0
  133. package/dist/types/artifacts/fileArtifacts.d.ts.map +1 -0
  134. package/dist/types/artifacts/inMemoryArtifacts.d.ts +55 -0
  135. package/dist/types/artifacts/inMemoryArtifacts.d.ts.map +1 -0
  136. package/dist/types/artifacts/index.d.ts +22 -0
  137. package/dist/types/artifacts/index.d.ts.map +1 -0
  138. package/dist/types/artifacts/minting.d.ts +30 -0
  139. package/dist/types/artifacts/minting.d.ts.map +1 -0
  140. package/dist/types/artifacts/naming.d.ts +37 -0
  141. package/dist/types/artifacts/naming.d.ts.map +1 -0
  142. package/dist/types/artifacts/payload.d.ts +44 -0
  143. package/dist/types/artifacts/payload.d.ts.map +1 -0
  144. package/dist/types/artifacts/placement.d.ts +75 -0
  145. package/dist/types/artifacts/placement.d.ts.map +1 -0
  146. package/dist/types/artifacts/present.d.ts +78 -0
  147. package/dist/types/artifacts/present.d.ts.map +1 -0
  148. package/dist/types/artifacts/retention.d.ts +73 -0
  149. package/dist/types/artifacts/retention.d.ts.map +1 -0
  150. package/dist/types/artifacts/sqliteArtifacts.d.ts +91 -0
  151. package/dist/types/artifacts/sqliteArtifacts.d.ts.map +1 -0
  152. package/dist/types/artifacts/types.d.ts +221 -0
  153. package/dist/types/artifacts/types.d.ts.map +1 -0
  154. package/dist/types/artifacts/wants.d.ts +105 -0
  155. package/dist/types/artifacts/wants.d.ts.map +1 -0
  156. package/dist/types/core/Agent.d.ts +8 -2
  157. package/dist/types/core/Agent.d.ts.map +1 -1
  158. package/dist/types/core/agent/buildToolRegistry.d.ts +11 -1
  159. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
  160. package/dist/types/core/agent/presentTool.d.ts +23 -0
  161. package/dist/types/core/agent/presentTool.d.ts.map +1 -0
  162. package/dist/types/core/agent/stages/toolCalls.d.ts +22 -0
  163. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  164. package/dist/types/core/agent/types.d.ts +46 -0
  165. package/dist/types/core/agent/types.d.ts.map +1 -1
  166. package/dist/types/core/codeRunnerTool.d.ts.map +1 -1
  167. package/dist/types/core/tools.d.ts +49 -0
  168. package/dist/types/core/tools.d.ts.map +1 -1
  169. package/dist/types/events/dispatcher.d.ts +1 -1
  170. package/dist/types/events/dispatcher.d.ts.map +1 -1
  171. package/dist/types/events/payloads.d.ts +83 -0
  172. package/dist/types/events/payloads.d.ts.map +1 -1
  173. package/dist/types/events/registry.d.ts +13 -1
  174. package/dist/types/events/registry.d.ts.map +1 -1
  175. package/dist/types/index.d.ts +3 -1
  176. package/dist/types/index.d.ts.map +1 -1
  177. package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
  178. package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
  179. package/dist/types/recorders/core/ArtifactsRecorder.d.ts +23 -0
  180. package/dist/types/recorders/core/ArtifactsRecorder.d.ts.map +1 -0
  181. package/package.json +1 -1
@@ -0,0 +1,161 @@
1
+ /**
2
+ * artifacts/inMemoryArtifacts — the claim-check store in a Map.
3
+ *
4
+ * For tests, local development, and single-process agents whose artifacts may
5
+ * die with the process. Exactly as durable as the process — which is the
6
+ * point of the port: swap the one argument for `fileArtifacts` or
7
+ * `sqliteArtifacts` and nothing else changes.
8
+ *
9
+ * ── Bounded, and counting its drops (the innerRunRecords laws) ─────────────
10
+ * A retained payload is retained memory, and an agent minting a dataset per
11
+ * turn for a week would otherwise pin every one of them — the failure would
12
+ * look like a leak rather than like a feature. So this adapter is ALWAYS
13
+ * bounded: it has a default byte budget and row budget per scope, an explicit
14
+ * retention only replaces those dials, and there is deliberately no spelling
15
+ * for "unbounded" here — a memory store without a ceiling is a leak wearing
16
+ * configuration. When the budget forces an eviction the least-recently-USED
17
+ * artifact leaves first (reading refreshes recency, so the dataset a chart is
18
+ * actively rendered from is not the next casualty), every eviction is
19
+ * reported by the `put` that caused it, and `dropped` COUNTS them — "we kept
20
+ * the last 200 of 340" is an answer a debugging session can act on; a
21
+ * silently missing ref is not.
22
+ */
23
+ import { identityNamespace } from '../memory/identity/index.js';
24
+ import { prepareArtifact } from './minting.js';
25
+ import { isArtifactRef } from './naming.js';
26
+ import { computeArtifactDigest, decodeArtifactData, encodeArtifactData, } from './payload.js';
27
+ import { assertRetention, planRetention, } from './retention.js';
28
+ import { ArtifactIntegrityError, InvalidArtifactError, } from './types.js';
29
+ /** The always-on bounds. Override dials via `retention`; there is no "off". */
30
+ export const DEFAULT_IN_MEMORY_ARTIFACT_RETENTION = {
31
+ /** 32 MiB per scope — a working set, not an archive. */
32
+ maxBytesPerScope: 32 * 1024 * 1024,
33
+ /** 256 artifacts per scope. */
34
+ maxCountPerScope: 256,
35
+ };
36
+ /**
37
+ * A bounded, drop-counting, per-scope-isolated artifact store in process
38
+ * memory.
39
+ *
40
+ * @example
41
+ * const store = inMemoryArtifacts({ retention: { ttlMs: 15 * 60_000 } });
42
+ * const agent = Agent.create({ provider, artifacts: store });
43
+ */
44
+ export function inMemoryArtifacts(options = {}) {
45
+ assertRetention('inMemoryArtifacts', options.retention);
46
+ const retention = {
47
+ ...DEFAULT_IN_MEMORY_ARTIFACT_RETENTION,
48
+ ...options.retention,
49
+ };
50
+ const now = options._now ?? Date.now;
51
+ /** namespace → (ref → row). Insertion order is NOT recency; rows carry it. */
52
+ const scopes = new Map();
53
+ let dropped = 0;
54
+ const shelf = (scope) => {
55
+ const ns = identityNamespace(scope);
56
+ let held = scopes.get(ns);
57
+ if (held === undefined) {
58
+ held = new Map();
59
+ scopes.set(ns, held);
60
+ }
61
+ return held;
62
+ };
63
+ /** Resolve a live row, sweeping it when the calendar says it is gone. */
64
+ const liveRow = (scope, ref) => {
65
+ if (!isArtifactRef(ref))
66
+ return undefined;
67
+ const held = shelf(scope);
68
+ const row = held.get(ref);
69
+ if (row === undefined)
70
+ return undefined;
71
+ if (row.meta.expiresAt !== undefined && row.meta.expiresAt <= now()) {
72
+ held.delete(ref);
73
+ return undefined;
74
+ }
75
+ return row;
76
+ };
77
+ return {
78
+ get dropped() {
79
+ return dropped;
80
+ },
81
+ retention,
82
+ async put(scope, input) {
83
+ const held = shelf(scope);
84
+ const at = now();
85
+ const { meta } = await prepareArtifact(input, (parent) => liveRow(scope, parent) !== undefined, retention, at);
86
+ const rows = [...held.values()].map((row) => ({
87
+ ref: row.meta.ref,
88
+ kind: row.meta.kind,
89
+ bytes: row.meta.bytes,
90
+ ...(row.meta.expiresAt !== undefined && { expiresAt: row.meta.expiresAt }),
91
+ lastAccessedAt: row.lastAccessedAt,
92
+ }));
93
+ const plan = planRetention(rows, meta.bytes, retention, at);
94
+ if (plan.refusal !== undefined)
95
+ throw new InvalidArtifactError(plan.refusal);
96
+ for (const swept of plan.swept) {
97
+ held.delete(swept.ref);
98
+ if (swept.reason !== 'ttl')
99
+ dropped++;
100
+ }
101
+ held.set(meta.ref, { meta, payload: encodeArtifactData(input.data), lastAccessedAt: at });
102
+ return { meta, swept: plan.swept };
103
+ },
104
+ // eslint-disable-next-line @typescript-eslint/require-await
105
+ async head(scope, ref) {
106
+ const row = liveRow(scope, ref);
107
+ if (row === undefined)
108
+ return null;
109
+ row.lastAccessedAt = now();
110
+ return row.meta;
111
+ },
112
+ async get(scope, ref) {
113
+ const row = liveRow(scope, ref);
114
+ if (row === undefined)
115
+ return null;
116
+ row.lastAccessedAt = now();
117
+ const data = decodeArtifactData(row.payload);
118
+ if (row.meta.digest !== undefined) {
119
+ const actual = await computeArtifactDigest(data);
120
+ if (actual !== row.meta.digest) {
121
+ throw new ArtifactIntegrityError(row.meta.ref, row.meta.digest, actual);
122
+ }
123
+ }
124
+ return { meta: row.meta, data };
125
+ },
126
+ // eslint-disable-next-line @typescript-eslint/require-await
127
+ async delete(scope, ref) {
128
+ if (!isArtifactRef(ref))
129
+ return;
130
+ shelf(scope).delete(ref);
131
+ },
132
+ // eslint-disable-next-line @typescript-eslint/require-await
133
+ async list(scope, listOptions) {
134
+ const at = now();
135
+ const held = shelf(scope);
136
+ // Sweep-on-access: an expired row is "no data" everywhere, lists included.
137
+ for (const [ref, row] of held) {
138
+ if (row.meta.expiresAt !== undefined && row.meta.expiresAt <= at)
139
+ held.delete(ref);
140
+ }
141
+ const all = [...held.values()]
142
+ .map((row) => row.meta)
143
+ .sort((a, b) => b.createdAt - a.createdAt || (a.ref < b.ref ? -1 : 1));
144
+ const offset = decodeCursor(listOptions?.cursor);
145
+ const limit = Math.max(1, Math.floor(listOptions?.limit ?? 50));
146
+ const page = all.slice(offset, offset + limit);
147
+ const nextOffset = offset + page.length;
148
+ return {
149
+ artifacts: page,
150
+ ...(nextOffset < all.length && { cursor: String(nextOffset) }),
151
+ };
152
+ },
153
+ };
154
+ }
155
+ function decodeCursor(cursor) {
156
+ if (cursor === undefined)
157
+ return 0;
158
+ const parsed = Number(cursor);
159
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : 0;
160
+ }
161
+ //# sourceMappingURL=inMemoryArtifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryArtifacts.js","sourceRoot":"","sources":["../../../src/artifacts/inMemoryArtifacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * artifacts — barrel.
3
+ *
4
+ * The claim-check store: shapes + the five-verb port (`types`), the ref
5
+ * grammar (`naming`), the payload laws (`payload`), the eviction law
6
+ * (`retention`), the shared put pipeline (`minting`), three adapters, the
7
+ * `ctx.artifacts` capability (`capability`) — and the Phase-2 data legs:
8
+ * ref arguments at dispatch (`wants`), the hand-to-the-screen verb
9
+ * (`present`), and the placement threshold (`placement`). See README.md in
10
+ * this folder for the one-job map and the import direction.
11
+ */
12
+ export { ArtifactIntegrityError, InvalidArtifactError, UnknownParentRefError, type ArtifactListOptions, type ArtifactListResult, type ArtifactMeta, type ArtifactOrigin, type ArtifactPutResult, type ArtifactRecord, type ArtifactRef, type ArtifactScope, type ArtifactStore, type ArtifactSweepReason, type PutArtifactInput, type SweptArtifact, } from './types.js';
13
+ export { ARTIFACT_REF_PREFIX, isArtifactRef, mintArtifactRef } from './naming.js';
14
+ export { type ArtifactRetention } from './retention.js';
15
+ export { inMemoryArtifacts, DEFAULT_IN_MEMORY_ARTIFACT_RETENTION, type InMemoryArtifacts, type InMemoryArtifactsOptions, } from './inMemoryArtifacts.js';
16
+ export { fileArtifacts, UnreadableArtifactFileError, type FileArtifactsOptions, } from './fileArtifacts.js';
17
+ export { sqliteArtifacts, UnreadableArtifactStoreError, type SqliteArtifacts, type SqliteArtifactsOptions, } from './sqliteArtifacts.js';
18
+ export { bindArtifacts, unconfiguredArtifacts, type ArtifactEventFact, type ArtifactEventSink, type ArtifactOp, type ArtifactRefusalReason, type BindArtifactsOptions, type ToolArtifactPutInput, type ToolArtifacts, } from './capability.js';
19
+ export { assertToolWants, resolveToolWants, wantsNeedsStoreRefusal, type ToolWants, type WantsRefusal, type WantsResolution, } from './wants.js';
20
+ export { PRESENT_TOOL_NAME, presentArtifact, type PresentOutcome, type PresentSnapshot, type PresentedResult, } from './present.js';
21
+ export { assertArtifactPlacement, isPlacedToolResult, placedResultKind, placedToolResult, type ArtifactPlacement, type PlacedToolResult, } from './placement.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * artifacts — barrel.
3
+ *
4
+ * The claim-check store: shapes + the five-verb port (`types`), the ref
5
+ * grammar (`naming`), the payload laws (`payload`), the eviction law
6
+ * (`retention`), the shared put pipeline (`minting`), three adapters, the
7
+ * `ctx.artifacts` capability (`capability`) — and the Phase-2 data legs:
8
+ * ref arguments at dispatch (`wants`), the hand-to-the-screen verb
9
+ * (`present`), and the placement threshold (`placement`). See README.md in
10
+ * this folder for the one-job map and the import direction.
11
+ */
12
+ export { ArtifactIntegrityError, InvalidArtifactError, UnknownParentRefError, } from './types.js';
13
+ export { ARTIFACT_REF_PREFIX, isArtifactRef, mintArtifactRef } from './naming.js';
14
+ export { inMemoryArtifacts, DEFAULT_IN_MEMORY_ARTIFACT_RETENTION, } from './inMemoryArtifacts.js';
15
+ export { fileArtifacts, UnreadableArtifactFileError, } from './fileArtifacts.js';
16
+ export { sqliteArtifacts, UnreadableArtifactStoreError, } from './sqliteArtifacts.js';
17
+ export { bindArtifacts, unconfiguredArtifacts, } from './capability.js';
18
+ export { assertToolWants, resolveToolWants, wantsNeedsStoreRefusal, } from './wants.js';
19
+ export { PRESENT_TOOL_NAME, presentArtifact, } from './present.js';
20
+ export { assertArtifactPlacement, isPlacedToolResult, placedResultKind, placedToolResult, } from './placement.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/artifacts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,GAatB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EACL,iBAAiB,EACjB,oCAAoC,GAGrC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,2BAA2B,GAE5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,4BAA4B,GAG7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,aAAa,EACb,qBAAqB,GAQtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GAIvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,eAAe,GAIhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * artifacts/minting — the shared half of every adapter's `put`.
3
+ *
4
+ * Validate the input, prove the parents, measure the bytes, compute the
5
+ * digest when asked, mint the ref, stamp the meta. Three adapters call this
6
+ * one pipeline so a put refused by `inMemoryArtifacts` is refused in the same
7
+ * words by `sqliteArtifacts` — one law, three storage mechanics.
8
+ *
9
+ * What stays with the adapter: holding the bytes, applying the retention
10
+ * plan, answering the other four verbs.
11
+ */
12
+ import { type ArtifactRetention } from './retention.js';
13
+ import { type ArtifactMeta, type ArtifactRef, type PutArtifactInput } from './types.js';
14
+ /** What an adapter lends the pipeline: "does this ref resolve, in THIS scope?" */
15
+ export type ParentResolver = (ref: ArtifactRef) => boolean | Promise<boolean>;
16
+ /**
17
+ * Validate a put and build the meta it mints.
18
+ *
19
+ * @param input the caller's put.
20
+ * @param resolveParent scope-bound existence check for parent validation.
21
+ * @param retention the adapter's policy — stamps `expiresAt` (stated, never sprung).
22
+ * @param now the adapter's clock, injected so tests own time.
23
+ * @throws InvalidArtifactError for input this library cannot store faithfully.
24
+ * @throws UnknownParentRefError for a parent that does not resolve in scope.
25
+ */
26
+ export declare function prepareArtifact(input: PutArtifactInput, resolveParent: ParentResolver, retention: ArtifactRetention | undefined, now: number): Promise<{
27
+ meta: ArtifactMeta;
28
+ bytes: number;
29
+ }>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * artifacts/minting — the shared half of every adapter's `put`.
3
+ *
4
+ * Validate the input, prove the parents, measure the bytes, compute the
5
+ * digest when asked, mint the ref, stamp the meta. Three adapters call this
6
+ * one pipeline so a put refused by `inMemoryArtifacts` is refused in the same
7
+ * words by `sqliteArtifacts` — one law, three storage mechanics.
8
+ *
9
+ * What stays with the adapter: holding the bytes, applying the retention
10
+ * plan, answering the other four verbs.
11
+ */
12
+ import { isArtifactRef, mintArtifactRef } from './naming.js';
13
+ import { computeArtifactDigest, measureArtifactBytes } from './payload.js';
14
+ import { resolveExpiresAt } from './retention.js';
15
+ import { InvalidArtifactError, UnknownParentRefError, } from './types.js';
16
+ /**
17
+ * Validate a put and build the meta it mints.
18
+ *
19
+ * @param input the caller's put.
20
+ * @param resolveParent scope-bound existence check for parent validation.
21
+ * @param retention the adapter's policy — stamps `expiresAt` (stated, never sprung).
22
+ * @param now the adapter's clock, injected so tests own time.
23
+ * @throws InvalidArtifactError for input this library cannot store faithfully.
24
+ * @throws UnknownParentRefError for a parent that does not resolve in scope.
25
+ */
26
+ export async function prepareArtifact(input, resolveParent, retention, now) {
27
+ if (typeof input.kind !== 'string' || input.kind.trim() === '') {
28
+ throw new InvalidArtifactError(`kind is ${JSON.stringify(input.kind)}. kind is the consumer vocabulary a redeemer ` +
29
+ `decides from ('dataset/rows', 'chart/spec') — a blank one makes every head() useless. ` +
30
+ `Name what this artifact IS.`);
31
+ }
32
+ if (typeof input.mediaType !== 'string' || input.mediaType.trim() === '') {
33
+ throw new InvalidArtifactError(`mediaType is ${JSON.stringify(input.mediaType)}. Name the payload's MIME type ` +
34
+ `('application/json', 'text/csv', …) so a consumer can decode without guessing.`);
35
+ }
36
+ if (input.expiresAt !== undefined &&
37
+ (!Number.isFinite(input.expiresAt) || input.expiresAt <= now)) {
38
+ throw new InvalidArtifactError(`expiresAt = ${String(input.expiresAt)} is not a future unix-ms timestamp. An artifact ` +
39
+ `born expired would resolve for nobody; state a future time, or omit the field.`);
40
+ }
41
+ if (input.digest !== undefined && input.digest !== 'sha-256') {
42
+ throw new InvalidArtifactError(`digest = ${JSON.stringify(input.digest)} is not an algorithm this store computes. ` +
43
+ `'sha-256' is the one shipped; omit the field for no digest.`);
44
+ }
45
+ // Parents are FACTS, proven at birth — a foreign key that cannot dangle.
46
+ if (input.parentRefs !== undefined && input.parentRefs.length > 0) {
47
+ const unresolved = [];
48
+ for (const parent of input.parentRefs) {
49
+ if (!isArtifactRef(parent) || !(await resolveParent(parent)))
50
+ unresolved.push(parent);
51
+ }
52
+ if (unresolved.length > 0)
53
+ throw new UnknownParentRefError(unresolved);
54
+ }
55
+ // Measure (and refuse the unserializable) BEFORE minting, so a refused put
56
+ // never burns a ref.
57
+ const bytes = measureArtifactBytes(input.data);
58
+ const digest = input.digest === 'sha-256' ? await computeArtifactDigest(input.data) : undefined;
59
+ const expiresAt = resolveExpiresAt(input.expiresAt, retention, now);
60
+ const meta = {
61
+ ref: mintArtifactRef(),
62
+ kind: input.kind,
63
+ mediaType: input.mediaType,
64
+ bytes,
65
+ createdAt: now,
66
+ ...(input.label !== undefined && { label: input.label }),
67
+ ...(digest !== undefined && { digest }),
68
+ ...(expiresAt !== undefined && { expiresAt }),
69
+ ...(input.origin !== undefined && { origin: input.origin }),
70
+ ...(input.parentRefs !== undefined &&
71
+ input.parentRefs.length > 0 && { parentRefs: [...input.parentRefs] }),
72
+ };
73
+ return { meta, bytes };
74
+ }
75
+ //# sourceMappingURL=minting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minting.js","sourceRoot":"","sources":["../../../src/artifacts/minting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * artifacts/naming — the ONE owner of the ref grammar.
3
+ *
4
+ * `art_` + 22 crypto-random base62 chars = 26 chars the model can speak
5
+ * cheaply and copy reliably. The grammar lives in exactly one module (the
6
+ * `branchSegment.ts` precedent upstream): mint here, recognize here, and
7
+ * nowhere else — an adapter that parses refs with its own regex is a design
8
+ * smell this header exists to refuse.
9
+ *
10
+ * NEVER content-addressed. The digest is metadata on {@link ArtifactMeta};
11
+ * making content the key would collide two tenants' identical bytes into one
12
+ * object (an isolation bug wearing a dedup win) and could never name two
13
+ * generations of "the current dataset". Randomness comes from
14
+ * `globalThis.crypto` — present in every supported Node and every browser —
15
+ * so minting works wherever the in-memory adapter does.
16
+ */
17
+ import type { ArtifactRef } from './types.js';
18
+ /** The prefix every minted ref carries. */
19
+ export declare const ARTIFACT_REF_PREFIX = "art_";
20
+ /**
21
+ * Mint a fresh, opaque, never-content-derived ref.
22
+ *
23
+ * Rejection sampling keeps the distribution uniform (256 % 62 ≠ 0, so a bare
24
+ * modulo would bias the low end of the alphabet — cosmetically fine,
25
+ * cryptographically sloppy, and cheap to do right).
26
+ */
27
+ export declare function mintArtifactRef(): ArtifactRef;
28
+ /**
29
+ * Is this string a well-formed artifact ref?
30
+ *
31
+ * Structural, total, and the ONLY recognizer. Adapters call it before any
32
+ * ref touches a filesystem path or a SQL parameter: refs are minted so a
33
+ * traversal payload cannot arrive by construction — and this asserts it
34
+ * anyway, because "cannot happen" is a claim, not a defence.
35
+ */
36
+ export declare function isArtifactRef(candidate: unknown): candidate is ArtifactRef;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * artifacts/naming — the ONE owner of the ref grammar.
3
+ *
4
+ * `art_` + 22 crypto-random base62 chars = 26 chars the model can speak
5
+ * cheaply and copy reliably. The grammar lives in exactly one module (the
6
+ * `branchSegment.ts` precedent upstream): mint here, recognize here, and
7
+ * nowhere else — an adapter that parses refs with its own regex is a design
8
+ * smell this header exists to refuse.
9
+ *
10
+ * NEVER content-addressed. The digest is metadata on {@link ArtifactMeta};
11
+ * making content the key would collide two tenants' identical bytes into one
12
+ * object (an isolation bug wearing a dedup win) and could never name two
13
+ * generations of "the current dataset". Randomness comes from
14
+ * `globalThis.crypto` — present in every supported Node and every browser —
15
+ * so minting works wherever the in-memory adapter does.
16
+ */
17
+ /** The prefix every minted ref carries. */
18
+ export const ARTIFACT_REF_PREFIX = 'art_';
19
+ /** Random chars after the prefix. 62^22 ≈ 2^131 — collision is not a case. */
20
+ const RANDOM_LENGTH = 22;
21
+ const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
22
+ /** The full shape, anchored: `art_` + exactly 22 base62 chars. */
23
+ const REF_PATTERN = /^art_[A-Za-z0-9]{22}$/;
24
+ /**
25
+ * Mint a fresh, opaque, never-content-derived ref.
26
+ *
27
+ * Rejection sampling keeps the distribution uniform (256 % 62 ≠ 0, so a bare
28
+ * modulo would bias the low end of the alphabet — cosmetically fine,
29
+ * cryptographically sloppy, and cheap to do right).
30
+ */
31
+ export function mintArtifactRef() {
32
+ const out = [];
33
+ const bytes = new Uint8Array(RANDOM_LENGTH * 2);
34
+ while (out.length < RANDOM_LENGTH) {
35
+ globalThis.crypto.getRandomValues(bytes);
36
+ for (const b of bytes) {
37
+ // 248 = 4 * 62: the largest multiple of 62 below 256. Values at or
38
+ // above it are re-drawn instead of folded onto the alphabet unevenly.
39
+ if (b >= 248)
40
+ continue;
41
+ out.push(ALPHABET[b % ALPHABET.length]);
42
+ if (out.length === RANDOM_LENGTH)
43
+ break;
44
+ }
45
+ }
46
+ return `${ARTIFACT_REF_PREFIX}${out.join('')}`;
47
+ }
48
+ /**
49
+ * Is this string a well-formed artifact ref?
50
+ *
51
+ * Structural, total, and the ONLY recognizer. Adapters call it before any
52
+ * ref touches a filesystem path or a SQL parameter: refs are minted so a
53
+ * traversal payload cannot arrive by construction — and this asserts it
54
+ * anyway, because "cannot happen" is a claim, not a defence.
55
+ */
56
+ export function isArtifactRef(candidate) {
57
+ return typeof candidate === 'string' && REF_PATTERN.test(candidate);
58
+ }
59
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/artifacts/naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C,8EAA8E;AAC9E,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,QAAQ,GAAG,gEAAgE,CAAC;AAElF,kEAAkE;AAClE,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QAClC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,mEAAmE;YACnE,sEAAsE;YACtE,IAAI,CAAC,IAAI,GAAG;gBAAE,SAAS;YACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,IAAI,GAAG,CAAC,MAAM,KAAK,aAAa;gBAAE,MAAM;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,mBAAmB,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,SAAkB;IAC9C,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * artifacts/payload — one owner for how a payload is measured, carried and
3
+ * digested.
4
+ *
5
+ * Three adapters store the same three payload shapes (string, `Uint8Array`,
6
+ * JSON value). If each measured or serialized on its own, `bytes` on the meta
7
+ * could disagree with what a digest was computed over, and a digest written by
8
+ * one adapter would not verify in another. So the laws live once, here:
9
+ *
10
+ * • `measure` — `bytes` is the UTF-8 length of text/JSON, the byteLength of
11
+ * binary. The number a consumer decides from, computed one way.
12
+ * • `encode/decode` — the durable adapters persist ONE envelope
13
+ * (`text` / `binary` base64 / `json`), so a file written by
14
+ * `fileArtifacts` is legible to a debugging human and identical in law to
15
+ * a row written by `sqliteArtifacts`.
16
+ * • `digest` — sha-256 over the SAME canonical bytes `measure` counts, via
17
+ * `globalThis.crypto.subtle` (browser + Node, zero dependencies).
18
+ *
19
+ * A payload JSON cannot carry (a function, a bigint, `undefined`, a cyclic
20
+ * object) is refused BY NAME at put — storing an approximation and returning
21
+ * it later as the real thing is the exact accepted-and-silently-wrong failure
22
+ * a claim check exists to prevent.
23
+ */
24
+ /**
25
+ * The canonical bytes of a payload — what `bytes` counts and what a digest
26
+ * is computed over. Throws {@link InvalidArtifactError} for a value that
27
+ * cannot be carried faithfully.
28
+ */
29
+ export declare function canonicalPayloadBytes(data: unknown): Uint8Array;
30
+ /** Payload size in bytes — UTF-8 for text/JSON, byteLength for binary. */
31
+ export declare function measureArtifactBytes(data: unknown): number;
32
+ /** `sha-256:<hex>` over the canonical bytes. */
33
+ export declare function computeArtifactDigest(data: unknown): Promise<string>;
34
+ /** How a payload rides a file or a SQL TEXT column. One shape, two adapters. */
35
+ export interface EncodedPayload {
36
+ readonly shape: 'text' | 'binary' | 'json';
37
+ /** `text`: the string. `binary`: base64. `json`: the JSON serialization. */
38
+ readonly value: string;
39
+ }
40
+ /** Encode for durable storage. Validates exactly as `measure` does. */
41
+ export declare function encodeArtifactData(data: unknown): EncodedPayload;
42
+ /** Decode what {@link encodeArtifactData} wrote. Total over its own output. */
43
+ export declare function decodeArtifactData(encoded: EncodedPayload): unknown;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * artifacts/payload — one owner for how a payload is measured, carried and
3
+ * digested.
4
+ *
5
+ * Three adapters store the same three payload shapes (string, `Uint8Array`,
6
+ * JSON value). If each measured or serialized on its own, `bytes` on the meta
7
+ * could disagree with what a digest was computed over, and a digest written by
8
+ * one adapter would not verify in another. So the laws live once, here:
9
+ *
10
+ * • `measure` — `bytes` is the UTF-8 length of text/JSON, the byteLength of
11
+ * binary. The number a consumer decides from, computed one way.
12
+ * • `encode/decode` — the durable adapters persist ONE envelope
13
+ * (`text` / `binary` base64 / `json`), so a file written by
14
+ * `fileArtifacts` is legible to a debugging human and identical in law to
15
+ * a row written by `sqliteArtifacts`.
16
+ * • `digest` — sha-256 over the SAME canonical bytes `measure` counts, via
17
+ * `globalThis.crypto.subtle` (browser + Node, zero dependencies).
18
+ *
19
+ * A payload JSON cannot carry (a function, a bigint, `undefined`, a cyclic
20
+ * object) is refused BY NAME at put — storing an approximation and returning
21
+ * it later as the real thing is the exact accepted-and-silently-wrong failure
22
+ * a claim check exists to prevent.
23
+ */
24
+ import { InvalidArtifactError } from './types.js';
25
+ const textEncoder = new TextEncoder();
26
+ const textDecoder = new TextDecoder();
27
+ /**
28
+ * The canonical bytes of a payload — what `bytes` counts and what a digest
29
+ * is computed over. Throws {@link InvalidArtifactError} for a value that
30
+ * cannot be carried faithfully.
31
+ */
32
+ export function canonicalPayloadBytes(data) {
33
+ if (data instanceof Uint8Array)
34
+ return data;
35
+ if (typeof data === 'string')
36
+ return textEncoder.encode(data);
37
+ let serialized;
38
+ try {
39
+ serialized = JSON.stringify(data);
40
+ }
41
+ catch (err) {
42
+ throw new InvalidArtifactError(`the payload cannot be JSON-serialized (${err instanceof Error ? err.message : String(err)}). ` +
43
+ `Store a string, a Uint8Array, or a JSON-serializable value — an approximation of ` +
44
+ `anything else would be returned later as if it were the real thing.`);
45
+ }
46
+ if (serialized === undefined) {
47
+ throw new InvalidArtifactError(`the payload serializes to nothing (undefined, a function, or a symbol). ` +
48
+ `JSON cannot carry it, so the store will not pretend to. Store a string, a ` +
49
+ `Uint8Array, or a JSON-serializable value.`);
50
+ }
51
+ return textEncoder.encode(serialized);
52
+ }
53
+ /** Payload size in bytes — UTF-8 for text/JSON, byteLength for binary. */
54
+ export function measureArtifactBytes(data) {
55
+ return canonicalPayloadBytes(data).byteLength;
56
+ }
57
+ /** `sha-256:<hex>` over the canonical bytes. */
58
+ export async function computeArtifactDigest(data) {
59
+ const bytes = canonicalPayloadBytes(data);
60
+ // `subtle.digest` wants an ArrayBuffer-backed view; copy defensively so a
61
+ // Uint8Array over a SharedArrayBuffer cannot reach it.
62
+ const buffer = new Uint8Array(bytes).buffer;
63
+ const hash = new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', buffer));
64
+ let hex = '';
65
+ for (const b of hash)
66
+ hex += b.toString(16).padStart(2, '0');
67
+ return `sha-256:${hex}`;
68
+ }
69
+ /** Encode for durable storage. Validates exactly as `measure` does. */
70
+ export function encodeArtifactData(data) {
71
+ if (data instanceof Uint8Array)
72
+ return { shape: 'binary', value: toBase64(data) };
73
+ if (typeof data === 'string')
74
+ return { shape: 'text', value: data };
75
+ // canonicalPayloadBytes carries the refusal for unserializable values.
76
+ return { shape: 'json', value: textDecoder.decode(canonicalPayloadBytes(data)) };
77
+ }
78
+ /** Decode what {@link encodeArtifactData} wrote. Total over its own output. */
79
+ export function decodeArtifactData(encoded) {
80
+ switch (encoded.shape) {
81
+ case 'text':
82
+ return encoded.value;
83
+ case 'binary':
84
+ return fromBase64(encoded.value);
85
+ case 'json':
86
+ return JSON.parse(encoded.value);
87
+ }
88
+ }
89
+ // Buffer-free base64, so the in-file law works in a browser bundle too.
90
+ function toBase64(bytes) {
91
+ let binary = '';
92
+ const CHUNK = 0x8000;
93
+ for (let i = 0; i < bytes.length; i += CHUNK) {
94
+ binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
95
+ }
96
+ return btoa(binary);
97
+ }
98
+ function fromBase64(value) {
99
+ const binary = atob(value);
100
+ const bytes = new Uint8Array(binary.length);
101
+ for (let i = 0; i < binary.length; i++)
102
+ bytes[i] = binary.charCodeAt(i);
103
+ return bytes;
104
+ }
105
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/artifacts/payload.ts"],"names":[],"mappings":"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"}