primitive-admin 1.1.0-alpha.82 → 1.1.0-alpha.83

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 (86) hide show
  1. package/dist/src/commands/documents.js +333 -42
  2. package/dist/src/commands/documents.js.map +1 -1
  3. package/dist/src/commands/functions.js +302 -120
  4. package/dist/src/commands/functions.js.map +1 -1
  5. package/dist/src/commands/locks.js +15 -1
  6. package/dist/src/commands/locks.js.map +1 -1
  7. package/dist/src/commands/sync.d.ts +50 -0
  8. package/dist/src/commands/sync.js +560 -312
  9. package/dist/src/commands/sync.js.map +1 -1
  10. package/dist/src/lib/api-client.d.ts +75 -2
  11. package/dist/src/lib/api-client.js +122 -7
  12. package/dist/src/lib/api-client.js.map +1 -1
  13. package/dist/src/lib/config-object-descriptor.js +5 -5
  14. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  15. package/dist/src/lib/document-ingest-artifact.d.ts +120 -0
  16. package/dist/src/lib/document-ingest-artifact.js +505 -0
  17. package/dist/src/lib/document-ingest-artifact.js.map +1 -0
  18. package/dist/src/lib/document-ingest-input.d.ts +51 -0
  19. package/dist/src/lib/document-ingest-input.js +132 -0
  20. package/dist/src/lib/document-ingest-input.js.map +1 -0
  21. package/dist/src/lib/document-ingest.d.ts +78 -0
  22. package/dist/src/lib/document-ingest.js +231 -0
  23. package/dist/src/lib/document-ingest.js.map +1 -0
  24. package/dist/src/lib/function-bundle.d.ts +6 -0
  25. package/dist/src/lib/function-bundle.js +8 -0
  26. package/dist/src/lib/function-bundle.js.map +1 -1
  27. package/dist/src/lib/function-collect.d.ts +1 -1
  28. package/dist/src/lib/function-collect.js +16 -0
  29. package/dist/src/lib/function-collect.js.map +1 -1
  30. package/dist/src/lib/function-db-types.d.ts +4 -0
  31. package/dist/src/lib/function-db-types.js +31 -2
  32. package/dist/src/lib/function-db-types.js.map +1 -1
  33. package/dist/src/lib/function-document-types.d.ts +83 -0
  34. package/dist/src/lib/function-document-types.js +133 -0
  35. package/dist/src/lib/function-document-types.js.map +1 -1
  36. package/dist/src/lib/function-grants-preflight.js +5 -0
  37. package/dist/src/lib/function-grants-preflight.js.map +1 -1
  38. package/dist/src/lib/function-log-lines.d.ts +76 -0
  39. package/dist/src/lib/function-log-lines.js +160 -0
  40. package/dist/src/lib/function-log-lines.js.map +1 -0
  41. package/dist/src/lib/function-log-row.d.ts +29 -0
  42. package/dist/src/lib/function-log-row.js +73 -0
  43. package/dist/src/lib/function-log-row.js.map +1 -0
  44. package/dist/src/lib/function-run.d.ts +53 -35
  45. package/dist/src/lib/function-run.js +55 -44
  46. package/dist/src/lib/function-run.js.map +1 -1
  47. package/dist/src/lib/function-schema-codegen.d.ts +6 -9
  48. package/dist/src/lib/function-schema-codegen.js +22 -35
  49. package/dist/src/lib/function-schema-codegen.js.map +1 -1
  50. package/dist/src/lib/function-sync.d.ts +226 -35
  51. package/dist/src/lib/function-sync.js +731 -99
  52. package/dist/src/lib/function-sync.js.map +1 -1
  53. package/dist/src/lib/function-versions.d.ts +122 -0
  54. package/dist/src/lib/function-versions.js +182 -0
  55. package/dist/src/lib/function-versions.js.map +1 -0
  56. package/dist/src/lib/generated-config-surfaces.d.ts +390 -146
  57. package/dist/src/lib/generated-config-surfaces.js +1207 -401
  58. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  59. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  60. package/dist/src/lib/generated-sdk-types.js +1 -1
  61. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  62. package/dist/src/lib/log-inspection.d.ts +2 -0
  63. package/dist/src/lib/log-inspection.js +4 -0
  64. package/dist/src/lib/log-inspection.js.map +1 -1
  65. package/dist/src/lib/output.d.ts +15 -0
  66. package/dist/src/lib/output.js +28 -0
  67. package/dist/src/lib/output.js.map +1 -1
  68. package/dist/src/lib/snapshot-audit-source.d.ts +45 -0
  69. package/dist/src/lib/snapshot-audit-source.js +58 -0
  70. package/dist/src/lib/snapshot-audit-source.js.map +1 -0
  71. package/dist/src/lib/snapshot-audit-store.d.ts +52 -0
  72. package/dist/src/lib/snapshot-audit-store.js +196 -0
  73. package/dist/src/lib/snapshot-audit-store.js.map +1 -0
  74. package/dist/src/lib/snapshot-audit.d.ts +207 -0
  75. package/dist/src/lib/snapshot-audit.js +431 -0
  76. package/dist/src/lib/snapshot-audit.js.map +1 -0
  77. package/dist/src/lib/snapshot-build-rows.d.ts +60 -0
  78. package/dist/src/lib/snapshot-build-rows.js +87 -0
  79. package/dist/src/lib/snapshot-build-rows.js.map +1 -0
  80. package/dist/src/lib/swift-codegen/functionGenerator.d.ts +23 -16
  81. package/dist/src/lib/swift-codegen/functionGenerator.js +34 -33
  82. package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -1
  83. package/dist/src/lib/sync-selectors.d.ts +45 -2
  84. package/dist/src/lib/sync-selectors.js +66 -5
  85. package/dist/src/lib/sync-selectors.js.map +1 -1
  86. package/package.json +2 -2
@@ -0,0 +1,76 @@
1
+ /**
2
+ * One invocation's captured console output, in the order it was printed —
3
+ * #3453 (D3453-005).
4
+ *
5
+ * `primitive functions logs --run <run-id>` used to print the same one-row-per
6
+ * record table the listing prints, so the LINES — the thing an operator opened
7
+ * the logs for — were only reachable through `--json`. This renders them, under
8
+ * the step that wrote them.
9
+ *
10
+ * Pure, and separate from the command, for the reason `function-log-row.ts`
11
+ * gives: a rendering rule that lives inside an action can only be tested by
12
+ * spawning the CLI, and this one has enough cases (two orderings, a header that
13
+ * changes, a throw, a pre-change record) that spawning for each would be the
14
+ * wrong trade.
15
+ */
16
+ /** The marker a truncated record ends with, so loss is never silent. */
17
+ export declare const TRUNCATION_MARKER = "\u2026 truncated: the platform's per-record cap dropped later lines";
18
+ /**
19
+ * What an EMPTY record whose attempt ended in the engine says — #3564,
20
+ * criterion 2 (D3564-007).
21
+ *
22
+ * The filing's own complaint: the invocation log held no console output for
23
+ * these attempts, with `truncated`, `logsUnavailable` and `contentSuppressed`
24
+ * all unset, so the silence read as "logs lost" when it meant "the handler
25
+ * printed nothing before the engine took the isolate away". This renderer
26
+ * printed nothing at all for such a record, which is the reading the filing
27
+ * asks to be able to make.
28
+ *
29
+ * Two facts, never collapsed into one: the first half says the attempt ended
30
+ * in the engine, and the SECOND half is chosen by the drain's own flags. A
31
+ * drain that failed — which `DrainedLogs.unavailable` names isolate eviction
32
+ * as a cause of — is reported as unavailable rather than as an empty handler,
33
+ * because those are opposite statements and this is precisely the case where
34
+ * guessing would be wrong.
35
+ */
36
+ export declare const ENGINE_END_PREFIX = "ended in the engine";
37
+ /**
38
+ * One record's console output, ready to print under its `functionLogLine`.
39
+ *
40
+ * A header is emitted whenever the label CHANGES, so two lines from one body
41
+ * sit under one header and a body re-entered after another step gets its own.
42
+ * A `thrown` entry — the wrapper's own record of a body that failed — takes a
43
+ * `!` in the gutter rather than an extra column, so the columns stay aligned.
44
+ *
45
+ * A record with NO lines whose attempt ended in the engine says so instead of
46
+ * printing nothing (#3564, {@link ENGINE_END_PREFIX}). The derivation is by
47
+ * the record's own `endedIn`, which the platform derived from its stored code
48
+ * — never by re-reading its message here, so a record written before this
49
+ * child renders exactly as it rendered then (edge 32).
50
+ */
51
+ export declare function renderInvocationLines(record: any): string[];
52
+ /** What `logs --run` was able to read before it renders anything. */
53
+ export interface RunLogsInput {
54
+ /** The filtered page, NEWEST first, as the listing route answers it. */
55
+ records: any[];
56
+ /** The run's step rows, or null when the read failed. */
57
+ trace: any[] | null;
58
+ /** The trace read's failure, if it had one. */
59
+ traceError?: string | null;
60
+ }
61
+ /**
62
+ * The whole of `logs --run`'s human output — #3453 (D3453-005).
63
+ *
64
+ * Returned rather than printed so every one of its rules is decidable without
65
+ * a server (#3187's lesson): which runs get a table, what a failed trace read
66
+ * costs, and the order the records come out in. The command does the two I/O
67
+ * reads and prints what comes back.
68
+ *
69
+ * Records are reversed because the listing answers newest first and a run is
70
+ * read forwards — an operator following what happened wants the first
71
+ * invocation at the top.
72
+ */
73
+ export declare function renderRunLogs(input: RunLogsInput): {
74
+ lines: string[];
75
+ warning: string | null;
76
+ };
@@ -0,0 +1,160 @@
1
+ /**
2
+ * One invocation's captured console output, in the order it was printed —
3
+ * #3453 (D3453-005).
4
+ *
5
+ * `primitive functions logs --run <run-id>` used to print the same one-row-per
6
+ * record table the listing prints, so the LINES — the thing an operator opened
7
+ * the logs for — were only reachable through `--json`. This renders them, under
8
+ * the step that wrote them.
9
+ *
10
+ * Pure, and separate from the command, for the reason `function-log-row.ts`
11
+ * gives: a rendering rule that lives inside an action can only be tested by
12
+ * spawning the CLI, and this one has enough cases (two orderings, a header that
13
+ * changes, a throw, a pre-change record) that spawning for each would be the
14
+ * wrong trade.
15
+ */
16
+ import { functionLogLine } from "./function-log-row.js";
17
+ import { renderStepRunTable } from "./step-run-table.js";
18
+ /** The marker a truncated record ends with, so loss is never silent. */
19
+ export const TRUNCATION_MARKER = "… truncated: the platform's per-record cap dropped later lines";
20
+ /**
21
+ * What an EMPTY record whose attempt ended in the engine says — #3564,
22
+ * criterion 2 (D3564-007).
23
+ *
24
+ * The filing's own complaint: the invocation log held no console output for
25
+ * these attempts, with `truncated`, `logsUnavailable` and `contentSuppressed`
26
+ * all unset, so the silence read as "logs lost" when it meant "the handler
27
+ * printed nothing before the engine took the isolate away". This renderer
28
+ * printed nothing at all for such a record, which is the reading the filing
29
+ * asks to be able to make.
30
+ *
31
+ * Two facts, never collapsed into one: the first half says the attempt ended
32
+ * in the engine, and the SECOND half is chosen by the drain's own flags. A
33
+ * drain that failed — which `DrainedLogs.unavailable` names isolate eviction
34
+ * as a cause of — is reported as unavailable rather than as an empty handler,
35
+ * because those are opposite statements and this is precisely the case where
36
+ * guessing would be wrong.
37
+ */
38
+ export const ENGINE_END_PREFIX = "ended in the engine";
39
+ function engineEndLine(record) {
40
+ const why = record?.logsUnavailable === true
41
+ ? "logs unavailable"
42
+ : record?.contentSuppressed === true
43
+ ? "output suppressed"
44
+ : "no handler output";
45
+ return `${ENGINE_END_PREFIX} — ${why}`;
46
+ }
47
+ const INDENT = " ";
48
+ /**
49
+ * Put one record's two arrays back into CAPTURE order.
50
+ *
51
+ * The writer persists `stdout` and `stderr` as two arrays filtered by stream
52
+ * and `t` is a millisecond offset, so `console.error("first")` followed by
53
+ * `console.log("second")` in the same millisecond has no surviving order in
54
+ * the record itself: merging by `t` prints them backwards. `n` is stamped at
55
+ * capture, in one buffer, and is what restores it.
56
+ *
57
+ * A record written before #3453 carries no `n` at all, and one entry having it
58
+ * while another does not is not a state any writer produces — so the fallback
59
+ * is chosen for the WHOLE record rather than per entry. Interleaving two
60
+ * orders would put entries in an order neither of them claims.
61
+ *
62
+ * The `t` fallback sorts stably with stdout first on a tie, which is the order
63
+ * the two arrays already sit in.
64
+ */
65
+ function inCaptureOrder(record) {
66
+ const stdout = Array.isArray(record?.stdout) ? record.stdout : [];
67
+ const stderr = Array.isArray(record?.stderr) ? record.stderr : [];
68
+ const merged = [...stdout, ...stderr];
69
+ const everyEntryNumbered = merged.length > 0 && merged.every((entry) => Number.isFinite(entry?.n));
70
+ const key = everyEntryNumbered
71
+ ? (entry) => Number(entry.n)
72
+ : (entry) => Number(entry.t ?? 0);
73
+ // `Array.prototype.sort` is stable, so equal keys keep the order above —
74
+ // stdout before stderr.
75
+ return merged.slice().sort((a, b) => key(a) - key(b));
76
+ }
77
+ /** `step <name> #<occurrence> attempt <n>`, or null between steps. */
78
+ function headerFor(entry) {
79
+ if (!entry?.step || typeof entry.step.name !== "string")
80
+ return null;
81
+ return `step ${entry.step.name} #${entry.step.occurrence ?? 0} attempt ${entry.attempt ?? 1}`;
82
+ }
83
+ /**
84
+ * One record's console output, ready to print under its `functionLogLine`.
85
+ *
86
+ * A header is emitted whenever the label CHANGES, so two lines from one body
87
+ * sit under one header and a body re-entered after another step gets its own.
88
+ * A `thrown` entry — the wrapper's own record of a body that failed — takes a
89
+ * `!` in the gutter rather than an extra column, so the columns stay aligned.
90
+ *
91
+ * A record with NO lines whose attempt ended in the engine says so instead of
92
+ * printing nothing (#3564, {@link ENGINE_END_PREFIX}). The derivation is by
93
+ * the record's own `endedIn`, which the platform derived from its stored code
94
+ * — never by re-reading its message here, so a record written before this
95
+ * child renders exactly as it rendered then (edge 32).
96
+ */
97
+ export function renderInvocationLines(record) {
98
+ const out = [];
99
+ let currentHeader = null;
100
+ let headerEmitted = false;
101
+ const entries = inCaptureOrder(record);
102
+ for (const entry of entries) {
103
+ const header = headerFor(entry);
104
+ if (header !== currentHeader) {
105
+ currentHeader = header;
106
+ headerEmitted = false;
107
+ }
108
+ if (header && !headerEmitted) {
109
+ out.push(`${INDENT}${header}`);
110
+ headerEmitted = true;
111
+ }
112
+ const indent = header ? INDENT.repeat(2) : INDENT;
113
+ const gutter = entry?.thrown === true ? `${indent.slice(0, -2)}! ` : indent;
114
+ const stream = entry?.s === "err" ? "err" : "out";
115
+ out.push(`${gutter}+${Number(entry?.t ?? 0)}ms ${stream} ${String(entry?.line ?? "")}`);
116
+ }
117
+ // #3564 — the empty record, explained. Only when the record really has no
118
+ // lines: one that printed something says more than the sentence does, and a
119
+ // reader who can see the output does not need to be told there is some.
120
+ if (entries.length === 0 && record?.endedIn === "engine") {
121
+ out.push(`${INDENT}${engineEndLine(record)}`);
122
+ }
123
+ // Said out loud, because the alternative is output that looks complete after
124
+ // the cap dropped the later lines or the throw entry. The record persists the
125
+ // boolean and not the count (F-3453-009), so the marker cannot name one.
126
+ if (record?.truncated === true)
127
+ out.push(`${INDENT}${TRUNCATION_MARKER}`);
128
+ return out;
129
+ }
130
+ /**
131
+ * The whole of `logs --run`'s human output — #3453 (D3453-005).
132
+ *
133
+ * Returned rather than printed so every one of its rules is decidable without
134
+ * a server (#3187's lesson): which runs get a table, what a failed trace read
135
+ * costs, and the order the records come out in. The command does the two I/O
136
+ * reads and prints what comes back.
137
+ *
138
+ * Records are reversed because the listing answers newest first and a run is
139
+ * read forwards — an operator following what happened wants the first
140
+ * invocation at the top.
141
+ */
142
+ export function renderRunLogs(input) {
143
+ const lines = [];
144
+ // A trace this reader could not fetch is not a reason to withhold the
145
+ // output: the lines say more than the failure does.
146
+ const warning = input.traceError
147
+ ? `Could not read the step trace: ${input.traceError}`
148
+ : null;
149
+ // A request invocation has no step rows at all, and an empty table would
150
+ // say there were steps and none ran.
151
+ if (input.trace && input.trace.length > 0) {
152
+ lines.push(renderStepRunTable(input.trace), "");
153
+ }
154
+ for (const record of [...(input.records ?? [])].reverse()) {
155
+ lines.push(functionLogLine(record));
156
+ lines.push(...renderInvocationLines(record));
157
+ }
158
+ return { lines, warning };
159
+ }
160
+ //# sourceMappingURL=function-log-lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-log-lines.js","sourceRoot":"","sources":["../../../src/lib/function-log-lines.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * One invocation, as a human reads it — the columns and the tail line.
3
+ *
4
+ * Extracted from `commands/functions.ts` by #3462 so the VERSION it added has
5
+ * somewhere to be tested. The one-shot table, the `--invocation` point read and
6
+ * the `--follow` tail all render the same facts in the same order, and three
7
+ * copies of that order in one command file is three chances for them to drift;
8
+ * a tail line that dropped a column would be a difference nobody could see
9
+ * without two terminals.
10
+ */
11
+ /** The columns the one-shot and `--invocation` tables share, in order. */
12
+ export declare const FUNCTION_LOG_COLUMNS: readonly ["TIME", "STATUS", "TRIGGER", "RUNTIME", "VERSION", "RUN/INVOCATION ID", "CODE", "ERROR"];
13
+ /**
14
+ * The FIRST error line only — #3287.
15
+ *
16
+ * A stack is eight kilobytes and a table row is one line, so the row says what
17
+ * happened and `--json` carries the rest.
18
+ */
19
+ export declare function firstErrorLine(row: any): string;
20
+ /** The cells one record contributes to a table row. */
21
+ export declare function functionLogCells(row: any): Record<string, string>;
22
+ /**
23
+ * The same record as one line, for `--follow`.
24
+ *
25
+ * Same facts in the same order as the table's columns, so a reader who switches
26
+ * between them is reading the same thing. An absent value contributes nothing
27
+ * rather than an empty gap, because a tail line has no columns to keep aligned.
28
+ */
29
+ export declare function functionLogLine(row: any): string;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * One invocation, as a human reads it — the columns and the tail line.
3
+ *
4
+ * Extracted from `commands/functions.ts` by #3462 so the VERSION it added has
5
+ * somewhere to be tested. The one-shot table, the `--invocation` point read and
6
+ * the `--follow` tail all render the same facts in the same order, and three
7
+ * copies of that order in one command file is three chances for them to drift;
8
+ * a tail line that dropped a column would be a difference nobody could see
9
+ * without two terminals.
10
+ */
11
+ /** The columns the one-shot and `--invocation` tables share, in order. */
12
+ export const FUNCTION_LOG_COLUMNS = [
13
+ "TIME",
14
+ "STATUS",
15
+ "TRIGGER",
16
+ // #3482 — which RUNTIME the platform ran this invocation under, beside the
17
+ // DOOR that fired it. `ctx.trigger.kind` says which door; this says whether
18
+ // the platform ran the code inside the request or as a task run, which is
19
+ // what `assertRuntime` tests for and what the two budgets differ by. Blank
20
+ // for a record written before the column existed.
21
+ "RUNTIME",
22
+ // #3462 — WHICH version this invocation executed. The record has carried
23
+ // `configId` since #3287 and nothing rendered it.
24
+ "VERSION",
25
+ "RUN/INVOCATION ID",
26
+ "CODE",
27
+ "ERROR",
28
+ ];
29
+ /**
30
+ * The FIRST error line only — #3287.
31
+ *
32
+ * A stack is eight kilobytes and a table row is one line, so the row says what
33
+ * happened and `--json` carries the rest.
34
+ */
35
+ export function firstErrorLine(row) {
36
+ const message = String(row?.errorMessage ?? "").trim();
37
+ if (message)
38
+ return message.split("\n")[0];
39
+ const stderr = Array.isArray(row?.stderr) ? row.stderr : [];
40
+ return stderr.length > 0 ? String(stderr[0].line ?? "") : "";
41
+ }
42
+ /** The cells one record contributes to a table row. */
43
+ export function functionLogCells(row) {
44
+ return {
45
+ startedAt: row?.startedAt ?? "",
46
+ status: row?.status ?? "",
47
+ trigger: row?.trigger?.kind ?? "",
48
+ runtime: row?.runtime ?? "",
49
+ configId: row?.configId ?? "",
50
+ // A trigger fire and a task run name their run; a request invocation's key
51
+ // is its own id.
52
+ runOrInvocation: row?.runId || row?.invocationId || "",
53
+ errorCode: row?.errorCode ?? "",
54
+ firstError: firstErrorLine(row),
55
+ };
56
+ }
57
+ /**
58
+ * The same record as one line, for `--follow`.
59
+ *
60
+ * Same facts in the same order as the table's columns, so a reader who switches
61
+ * between them is reading the same thing. An absent value contributes nothing
62
+ * rather than an empty gap, because a tail line has no columns to keep aligned.
63
+ */
64
+ export function functionLogLine(row) {
65
+ const cells = functionLogCells(row);
66
+ const runtime = cells.runtime ? ` ${cells.runtime}` : "";
67
+ const version = cells.configId ? ` ${cells.configId}` : "";
68
+ const code = cells.errorCode ? ` ${cells.errorCode}` : "";
69
+ const detail = cells.firstError ? ` ${cells.firstError}` : "";
70
+ return (`${cells.startedAt} ${cells.status} ${cells.trigger}${runtime}${version} ` +
71
+ `${cells.runOrInvocation}${code}${detail}`);
72
+ }
73
+ //# sourceMappingURL=function-log-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-log-row.js","sourceRoot":"","sources":["../../../src/lib/function-log-row.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM;IACN,QAAQ;IACR,SAAS;IACT,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,2EAA2E;IAC3E,kDAAkD;IAClD,SAAS;IACT,yEAAyE;IACzE,kDAAkD;IAClD,SAAS;IACT,mBAAmB;IACnB,MAAM;IACN,OAAO;CACC,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAQ;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,gBAAgB,CAAC,GAAQ;IACvC,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,EAAE;QAC/B,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,EAAE;QACzB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;QACjC,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE;QAC3B,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE;QAC7B,2EAA2E;QAC3E,iBAAiB;QACjB,eAAe,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,YAAY,IAAI,EAAE;QACtD,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,EAAE;QAC/B,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC;KAChC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,GAAQ;IACtC,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,OAAO,CACL,GAAG,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,IAAI;QAC7E,GAAG,KAAK,CAAC,eAAe,GAAG,IAAI,GAAG,MAAM,EAAE,CAC3C,CAAC;AACJ,CAAC"}
@@ -59,42 +59,61 @@ export type IdentityPlan = {
59
59
  * that had already run.
60
60
  */
61
61
  export declare function resolveRunFlags(flags: RunFlags): FlagResolution;
62
+ /** The two runtimes the platform runs a function under (#3482). */
63
+ export type FunctionRuntime = "request" | "task";
62
64
  /**
63
- * The three words a VERSION's mode may be (#3281, widened by #3454) and the
64
- * two a CALL may name. Spelled here rather than imported so this module stays
65
- * the thin decision layer the CLI's verbs read; the vendored grammar in
66
- * `generated-config-surfaces.ts` is where the words are defined.
65
+ * The runtime a function run used, read from the run row — #3482, C-6.
66
+ *
67
+ * `WorkflowRun.executionMode` is the runtime under the old word, and #3482
68
+ * does not rename a stored column (D3482-009; phase 7 owns the rename), so the
69
+ * mapping lives here, once, and every surface that says "runtime" says it the
70
+ * same way. `sync` is the request runtime — a webhook delivery, a
71
+ * `workflow.call` leaf — and `durable` is the task runtime.
72
+ *
73
+ * ABSENT means the task runtime, not "unknown": every writer of a durable row
74
+ * has written `durable` since #3186, and the rows that predate the column are
75
+ * durable runs. A row that says something else entirely is not a runtime this
76
+ * platform has, and answering null is how a reader learns that rather than
77
+ * being told a word that was never true.
67
78
  */
68
- export type FunctionMode = "request" | "task" | "any";
69
- export type FunctionRunner = "request" | "task";
70
- export type ModePrecheck = {
71
- ok: true;
72
- } | {
73
- ok: false;
74
- error: string;
75
- errorCode: "FUNCTION_MODE_MISMATCH";
76
- };
79
+ export declare function runtimeForExecutionMode(executionMode: unknown): FunctionRuntime | null;
77
80
  /**
78
- * Refuse the wrong verb before any request — D3448-008.
79
- *
80
- * A COURTESY that saves a round trip, and it says so: the authoritative
81
- * refusal is the server's `mode` precondition, which the CLI always sends, so
82
- * a version repointed between this read and the call is refused by the server
83
- * with nothing executed (D3448-SO-002).
81
+ * The RUNTIME cell of one `functions runs` row.
84
82
  *
85
- * A function with NO pushed version is not pre-judged: it has no mode to
86
- * disagree with, and the server's `FUNCTION_NOT_PUSHED` is the honest answer
87
- * (edge 30).
83
+ * Blank rather than guessed for a row this reader cannot place: `runs` pages
84
+ * one function's own runs, but the same shape reaches the CLI from surfaces
85
+ * that carry DSL rows too, and printing `task` for one would be a word about
86
+ * something that has no runtime at all.
88
87
  */
89
- export declare function precheckMode(verb: RunVerb, activeMode: FunctionMode | null | undefined, functionKey: string): ModePrecheck;
88
+ export declare function runRuntimeCell(run: {
89
+ executionMode?: unknown;
90
+ } | null | undefined): string;
90
91
  /**
91
- * The RUNNER a verb states on the wire.
92
+ * The two slice cells of one `functions runs` row — REFRESHES and RESETS.
93
+ *
94
+ * One rule for both, because they are two facts about the same record and the
95
+ * distinction that matters is the same for each: a row with NO slice record
96
+ * gets a BLANK cell, and a record that carries no count gets `0`.
92
97
  *
93
- * A verb always names one of the two: `any` is a mode a version may have, and
94
- * saying it here would be asking the server to pick, which #3454 refuses at
95
- * the boundary by name.
98
+ * - blank means "there is no record" — a request invocation opens no lease,
99
+ * and neither did any run that predates the record's own child;
100
+ * - `0` means "the record says nothing happened", which for #3566 is the
101
+ * answer an operator needs: a fabricated zero on a row with no record would
102
+ * read as "the platform never reset this run", and the row cannot know that.
103
+ *
104
+ * A value that is not a whole number reads `0` rather than reaching the table:
105
+ * the cell is a count, and printing `NaN` or `two` in a column of numbers
106
+ * teaches an operator nothing.
96
107
  */
97
- export declare function modeFor(verb: RunVerb): FunctionRunner;
108
+ export declare function runSliceCells(run: {
109
+ slice?: {
110
+ refreshCount?: unknown;
111
+ resets?: unknown;
112
+ } | null;
113
+ } | null | undefined): {
114
+ refreshes: string;
115
+ resets: string;
116
+ };
98
117
  /** The JS client's schedule: 400 ms doubling to a 5 s ceiling. */
99
118
  export declare const WAIT_INITIAL_DELAY_MS = 400;
100
119
  export declare const WAIT_MAX_DELAY_MS = 5000;
@@ -259,13 +278,12 @@ export interface RefusalLines {
259
278
  /**
260
279
  * Turn a refusal envelope into the lines an operator reads — #3448 D3448-010.
261
280
  *
262
- * Pure, because it carries the two facts that make handing the envelope back
263
- * worth anything instead of throwing: a 429's `Retry-After`, and the VERSION'S
264
- * REAL MODE on a 409 mode mismatch. Both are things the server already worked
265
- * out, and both would be re-derived badly from an exception message.
281
+ * Pure, because it carries the fact that makes handing the envelope back
282
+ * worth anything instead of throwing: a 429's `Retry-After`, which the server
283
+ * already worked out and which would be re-derived badly from an exception
284
+ * message.
266
285
  *
267
- * The mode line is also the CLI half of edge 31: the pre-check is a courtesy,
268
- * and a version repointed between it and the call is refused by the SERVER —
269
- * so what an operator sees in that race is this.
286
+ * #3482 — there is no "Version mode" line any more. It named the mode a
287
+ * refused call's version was locked to, and no version is locked to anything.
270
288
  */
271
289
  export declare function refusalLines(answer: RefusalAnswer): RefusalLines;
@@ -75,46 +75,62 @@ export function resolveRunFlags(flags) {
75
75
  return { ok: true, input, identity, timeoutSeconds };
76
76
  }
77
77
  /**
78
- * Refuse the wrong verb before any request — D3448-008.
78
+ * The runtime a function run used, read from the run row — #3482, C-6.
79
79
  *
80
- * A COURTESY that saves a round trip, and it says so: the authoritative
81
- * refusal is the server's `mode` precondition, which the CLI always sends, so
82
- * a version repointed between this read and the call is refused by the server
83
- * with nothing executed (D3448-SO-002).
80
+ * `WorkflowRun.executionMode` is the runtime under the old word, and #3482
81
+ * does not rename a stored column (D3482-009; phase 7 owns the rename), so the
82
+ * mapping lives here, once, and every surface that says "runtime" says it the
83
+ * same way. `sync` is the request runtime — a webhook delivery, a
84
+ * `workflow.call` leaf — and `durable` is the task runtime.
84
85
  *
85
- * A function with NO pushed version is not pre-judged: it has no mode to
86
- * disagree with, and the server's `FUNCTION_NOT_PUSHED` is the honest answer
87
- * (edge 30).
86
+ * ABSENT means the task runtime, not "unknown": every writer of a durable row
87
+ * has written `durable` since #3186, and the rows that predate the column are
88
+ * durable runs. A row that says something else entirely is not a runtime this
89
+ * platform has, and answering null is how a reader learns that rather than
90
+ * being told a word that was never true.
88
91
  */
89
- export function precheckMode(verb, activeMode, functionKey) {
90
- if (!activeMode)
91
- return { ok: true };
92
- // #3454 — an `any` function takes either runner, so neither verb is the
93
- // wrong one and there is no other door to refuse at. The pre-check is a
94
- // courtesy that saves a round trip on a LOCK; the server is the authority.
95
- if (activeMode === "any")
96
- return { ok: true };
97
- const wanted = modeFor(verb);
98
- if (activeMode === wanted)
99
- return { ok: true };
100
- const other = activeMode === "task" ? "start" : "invoke";
101
- return {
102
- ok: false,
103
- errorCode: "FUNCTION_MODE_MISMATCH",
104
- error: `Function '${functionKey}' is a ${activeMode} function: ` +
105
- `'functions ${verb}' runs the ${wanted} runner. ` +
106
- `Use 'primitive functions ${other} ${functionKey}'.`,
107
- };
92
+ export function runtimeForExecutionMode(executionMode) {
93
+ if (executionMode === "sync")
94
+ return "request";
95
+ if (executionMode === "durable" || executionMode === undefined || executionMode === null) {
96
+ return "task";
97
+ }
98
+ return null;
99
+ }
100
+ /**
101
+ * The RUNTIME cell of one `functions runs` row.
102
+ *
103
+ * Blank rather than guessed for a row this reader cannot place: `runs` pages
104
+ * one function's own runs, but the same shape reaches the CLI from surfaces
105
+ * that carry DSL rows too, and printing `task` for one would be a word about
106
+ * something that has no runtime at all.
107
+ */
108
+ export function runRuntimeCell(run) {
109
+ return runtimeForExecutionMode(run?.executionMode) ?? "";
108
110
  }
109
111
  /**
110
- * The RUNNER a verb states on the wire.
112
+ * The two slice cells of one `functions runs` row — REFRESHES and RESETS.
113
+ *
114
+ * One rule for both, because they are two facts about the same record and the
115
+ * distinction that matters is the same for each: a row with NO slice record
116
+ * gets a BLANK cell, and a record that carries no count gets `0`.
117
+ *
118
+ * - blank means "there is no record" — a request invocation opens no lease,
119
+ * and neither did any run that predates the record's own child;
120
+ * - `0` means "the record says nothing happened", which for #3566 is the
121
+ * answer an operator needs: a fabricated zero on a row with no record would
122
+ * read as "the platform never reset this run", and the row cannot know that.
111
123
  *
112
- * A verb always names one of the two: `any` is a mode a version may have, and
113
- * saying it here would be asking the server to pick, which #3454 refuses at
114
- * the boundary by name.
124
+ * A value that is not a whole number reads `0` rather than reaching the table:
125
+ * the cell is a count, and printing `NaN` or `two` in a column of numbers
126
+ * teaches an operator nothing.
115
127
  */
116
- export function modeFor(verb) {
117
- return verb === "start" ? "task" : "request";
128
+ export function runSliceCells(run) {
129
+ const slice = run?.slice;
130
+ if (!slice || typeof slice !== "object")
131
+ return { refreshes: "", resets: "" };
132
+ const count = (value) => String(Number.isInteger(Number(value)) ? Number(value) : 0);
133
+ return { refreshes: count(slice.refreshCount), resets: count(slice.resets) };
118
134
  }
119
135
  // ─── waiting ────────────────────────────────────────────────────────
120
136
  /** The JS client's schedule: 400 ms doubling to a 5 s ceiling. */
@@ -347,14 +363,13 @@ export async function withMintedToken(effects, use) {
347
363
  /**
348
364
  * Turn a refusal envelope into the lines an operator reads — #3448 D3448-010.
349
365
  *
350
- * Pure, because it carries the two facts that make handing the envelope back
351
- * worth anything instead of throwing: a 429's `Retry-After`, and the VERSION'S
352
- * REAL MODE on a 409 mode mismatch. Both are things the server already worked
353
- * out, and both would be re-derived badly from an exception message.
366
+ * Pure, because it carries the fact that makes handing the envelope back
367
+ * worth anything instead of throwing: a 429's `Retry-After`, which the server
368
+ * already worked out and which would be re-derived badly from an exception
369
+ * message.
354
370
  *
355
- * The mode line is also the CLI half of edge 31: the pre-check is a courtesy,
356
- * and a version repointed between it and the call is refused by the SERVER —
357
- * so what an operator sees in that race is this.
371
+ * #3482 — there is no "Version mode" line any more. It named the mode a
372
+ * refused call's version was locked to, and no version is locked to anything.
358
373
  */
359
374
  export function refusalLines(answer) {
360
375
  const body = answer.body ?? {};
@@ -362,10 +377,6 @@ export function refusalLines(answer) {
362
377
  const fields = [];
363
378
  if (body.errorCode)
364
379
  fields.push({ label: "Code", value: String(body.errorCode) });
365
- // The version's own mode, so a caller learns what the code is registered for
366
- // rather than only that they asked for the wrong thing.
367
- if (body.mode)
368
- fields.push({ label: "Version mode", value: String(body.mode) });
369
380
  const details = Array.isArray(body.details)
370
381
  ? body.details.map((detail) => typeof detail === "string" ? detail : JSON.stringify(detail))
371
382
  : [];