@intellectif/lk-core 1.5.0 → 1.7.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 (86) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/{ai-BYryFkF9.d.ts → ai-B1wYrqcB.d.cts} +83 -18
  3. package/dist/ai-B1wYrqcB.d.cts.map +1 -0
  4. package/dist/{ai-BYryFkF9.d.cts → ai-B1wYrqcB.d.ts} +83 -18
  5. package/dist/ai-B1wYrqcB.d.ts.map +1 -0
  6. package/dist/ai-check.cjs +13 -6
  7. package/dist/ai-check.cjs.map +1 -1
  8. package/dist/ai-check.d.cts +1 -5
  9. package/dist/ai-check.d.cts.map +1 -1
  10. package/dist/ai-check.d.ts +1 -5
  11. package/dist/ai-check.d.ts.map +1 -1
  12. package/dist/ai-check.js +13 -6
  13. package/dist/ai-check.js.map +1 -1
  14. package/dist/{ai-writing-D8PdhJJz.js → ai-writing-B7oMCt66.js} +311 -66
  15. package/dist/ai-writing-B7oMCt66.js.map +1 -0
  16. package/dist/{ai-writing-Cen7-3qs.cjs → ai-writing-DrPTV3R2.cjs} +313 -50
  17. package/dist/ai-writing-DrPTV3R2.cjs.map +1 -0
  18. package/dist/{index-DUaW1Tj5.d.ts → index-BM8LeDWn.d.cts} +2 -42
  19. package/dist/index-BM8LeDWn.d.cts.map +1 -0
  20. package/dist/{index-Bg0aeWtM.d.cts → index-BTkMQtws.d.ts} +2 -42
  21. package/dist/index-BTkMQtws.d.ts.map +1 -0
  22. package/dist/{index-wMc1E_aM.d.ts → index-BU99GFTl.d.ts} +2 -8
  23. package/dist/index-BU99GFTl.d.ts.map +1 -0
  24. package/dist/{index-CxpiWedW.d.ts → index-BdXs4-en.d.ts} +42 -20
  25. package/dist/index-BdXs4-en.d.ts.map +1 -0
  26. package/dist/{index-qMbxed1B.d.cts → index-DP9rvyOz.d.cts} +42 -20
  27. package/dist/index-DP9rvyOz.d.cts.map +1 -0
  28. package/dist/{index-D7R3Ll8R.d.cts → index-XCCoPoTU.d.cts} +2 -8
  29. package/dist/index-XCCoPoTU.d.cts.map +1 -0
  30. package/dist/index.cjs +70 -21
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +135 -69
  33. package/dist/index.d.cts.map +1 -1
  34. package/dist/index.d.ts +135 -69
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +65 -22
  37. package/dist/index.js.map +1 -1
  38. package/dist/{item-group-DEB7nLID.cjs → item-group-8P3WFuUK.cjs} +5 -6
  39. package/dist/item-group-8P3WFuUK.cjs.map +1 -0
  40. package/dist/{item-group-DdSUCUjM.js → item-group-CeDk7mfM.js} +5 -6
  41. package/dist/item-group-CeDk7mfM.js.map +1 -0
  42. package/dist/{registry-DaZRpqjW.js → registry-D92hz9iA.js} +124 -106
  43. package/dist/registry-D92hz9iA.js.map +1 -0
  44. package/dist/{registry-Ce00A_OW.cjs → registry-hzrkTeIT.cjs} +142 -107
  45. package/dist/registry-hzrkTeIT.cjs.map +1 -0
  46. package/dist/{schemas-DksueYsu.cjs → schemas-BWeskONy.cjs} +79 -18
  47. package/dist/schemas-BWeskONy.cjs.map +1 -0
  48. package/dist/{schemas-BioKFf3F.js → schemas-C7TViWCg.js} +74 -19
  49. package/dist/schemas-C7TViWCg.js.map +1 -0
  50. package/dist/schemas.cjs +5 -2
  51. package/dist/schemas.d.cts +2 -2
  52. package/dist/schemas.d.ts +2 -2
  53. package/dist/schemas.js +4 -3
  54. package/dist/{scoring-lKQVYsxy.cjs → scoring-CtkCFyFT.cjs} +22 -42
  55. package/dist/{scoring-lKQVYsxy.cjs.map → scoring-CtkCFyFT.cjs.map} +1 -1
  56. package/dist/{scoring-BKNNTz-s.js → scoring-DD1GHcLI.js} +22 -42
  57. package/dist/{scoring-BKNNTz-s.js.map → scoring-DD1GHcLI.js.map} +1 -1
  58. package/dist/scoring.cjs +2 -2
  59. package/dist/scoring.d.cts +2 -2
  60. package/dist/scoring.d.ts +2 -2
  61. package/dist/scoring.js +2 -2
  62. package/dist/{xapi-NYrTlpID.cjs → xapi-7btSpx6v.cjs} +5 -8
  63. package/dist/{xapi-NYrTlpID.cjs.map → xapi-7btSpx6v.cjs.map} +1 -1
  64. package/dist/{xapi-wR6gu4qS.js → xapi-Cgicg-zU.js} +5 -8
  65. package/dist/{xapi-wR6gu4qS.js.map → xapi-Cgicg-zU.js.map} +1 -1
  66. package/dist/xapi.cjs +1 -1
  67. package/dist/xapi.d.cts +1 -1
  68. package/dist/xapi.d.ts +1 -1
  69. package/dist/xapi.js +1 -1
  70. package/package.json +2 -2
  71. package/dist/ai-BYryFkF9.d.cts.map +0 -1
  72. package/dist/ai-BYryFkF9.d.ts.map +0 -1
  73. package/dist/ai-writing-Cen7-3qs.cjs.map +0 -1
  74. package/dist/ai-writing-D8PdhJJz.js.map +0 -1
  75. package/dist/index-Bg0aeWtM.d.cts.map +0 -1
  76. package/dist/index-CxpiWedW.d.ts.map +0 -1
  77. package/dist/index-D7R3Ll8R.d.cts.map +0 -1
  78. package/dist/index-DUaW1Tj5.d.ts.map +0 -1
  79. package/dist/index-qMbxed1B.d.cts.map +0 -1
  80. package/dist/index-wMc1E_aM.d.ts.map +0 -1
  81. package/dist/item-group-DEB7nLID.cjs.map +0 -1
  82. package/dist/item-group-DdSUCUjM.js.map +0 -1
  83. package/dist/registry-Ce00A_OW.cjs.map +0 -1
  84. package/dist/registry-DaZRpqjW.js.map +0 -1
  85. package/dist/schemas-BioKFf3F.js.map +0 -1
  86. package/dist/schemas-DksueYsu.cjs.map +0 -1
@@ -1,5 +1,4 @@
1
- import { At as ActivityType, Et as ActivityDataMap, Ot as ActivityMedia, hn as ValidationResult, nn as MultipleChoiceOptionMedia, st as ItemGroup } from "./ai-BYryFkF9.cjs";
2
- //#region src/types/redacted.d.ts
1
+ import { At as ActivityType, Et as ActivityDataMap, Ot as ActivityMedia, gn as ValidationResult, nn as MultipleChoiceOptionMedia, st as ItemGroup } from "./ai-B1wYrqcB.cjs";
3
2
  /**
4
3
  * The learner-safe SHAPE of each built-in type.
5
4
  *
@@ -78,6 +77,7 @@ interface RedactedMultipleChoiceOption {
78
77
  /** A Multiple Choice item with the answer key, feedback and strategy removed. */
79
78
  interface RedactedMultipleChoiceData extends RedactedItem {
80
79
  type: 'multiple-choice';
80
+ instructions?: string | undefined;
81
81
  question: string;
82
82
  questionHtml?: string | undefined;
83
83
  mode: 'single' | 'multi';
@@ -93,6 +93,7 @@ interface RedactedBlankConfig {
93
93
  /** A Fill-in-the-Blanks item with every accepted answer removed. */
94
94
  interface RedactedFillInTheBlanksData extends RedactedItem {
95
95
  type: 'fill-in-the-blanks';
96
+ instructions?: string | undefined;
96
97
  passage: string;
97
98
  passageHtml?: string | undefined;
98
99
  blanks: RedactedBlankConfig[];
@@ -139,6 +140,7 @@ interface RedactedGapSelectGap {
139
140
  /** A Gap Select item the learner can still answer: choices intact, answer key gone. */
140
141
  interface RedactedGapSelectData extends RedactedItem {
141
142
  type: 'gap-select';
143
+ instructions?: string | undefined;
142
144
  passage: string;
143
145
  passageHtml?: string | undefined;
144
146
  gaps: RedactedGapSelectGap[];
@@ -209,8 +211,6 @@ interface RedactedStimulus {
209
211
  * ```
210
212
  */
211
213
  type RedactedActivity = RedactedMultipleChoiceData | RedactedFillInTheBlanksData | RedactedWrittenResponseData | RedactedGapSelectData | RedactedDictationData | RedactedReadAloudData;
212
- //#endregion
213
- //#region src/schemas/item-group.d.ts
214
214
  /**
215
215
  * Validates an item group in full: the container and stimulus against
216
216
  * {@link ItemGroupSchema}, then every item against the schema registered for
@@ -222,8 +222,6 @@ type RedactedActivity = RedactedMultipleChoiceData | RedactedFillInTheBlanksData
222
222
  * not the first one that happened to throw.
223
223
  */
224
224
  declare function validateItemGroup(data: unknown): ValidationResult<ItemGroup>;
225
- //#endregion
226
- //#region src/schemas/json-schema.d.ts
227
225
  /**
228
226
  * JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the
229
227
  * kind/media/body consistency guards are Zod-only.
@@ -288,24 +286,49 @@ declare const fillInTheBlanksJsonSchema: Record<string, unknown>;
288
286
  * contract. Structural contract only.
289
287
  */
290
288
  declare const writtenResponseJsonSchema: Record<string, unknown>;
289
+ /** The JSON Schema drafts the SDK writes. */
290
+ type JsonSchemaTarget = 'draft-2020-12' | 'draft-7';
291
291
  /**
292
- * Derives the JSON Schema (Draft 7) for any REGISTERED activity type — the
293
- * live, registry-backed replacement for the static per-type exports above,
294
- * and the building block for AI generation pipelines (R6.1): pass the result
295
- * as a structured-output schema so a model can only emit valid items.
292
+ * Derives the JSON Schema for any REGISTERED activity type — the live,
293
+ * registry-backed replacement for the static per-type exports above, and the
294
+ * building block for AI generation pipelines (R6.1): pass the result as a
295
+ * structured-output schema so a model can only emit valid items.
296
296
  *
297
- * For a type you registered, it is the descriptor's `jsonSchema` when you gave
298
- * one, or else what the schema produces through the Standard JSON Schema
299
- * converter (`'~standard'.jsonSchema`) — a zod 4.6 schema has one. A fresh copy
300
- * every call.
297
+ * Draft 7 unless `target` says `'draft-2020-12'`. For a type you registered,
298
+ * it is the descriptor's `jsonSchema` when you gave one, in whatever draft you
299
+ * wrote it, or else what the schema produces through the Standard JSON Schema
300
+ * converter (`'~standard'.jsonSchema`) in the draft asked for — a zod 4.6
301
+ * schema has one. A fresh copy every call.
301
302
  *
302
303
  * @throws UnknownActivityTypeError when `type` has no registered descriptor.
303
304
  * @throws Error when a registered type has neither a `jsonSchema` nor a schema
304
305
  * that can produce one.
305
306
  */
306
- declare function jsonSchemaFor(type: string): Record<string, unknown>;
307
- //#endregion
308
- //#region src/schemas/index.d.ts
307
+ declare function jsonSchemaFor(type: string, options?: {
308
+ target?: JsonSchemaTarget;
309
+ }): Record<string, unknown>;
310
+ /**
311
+ * One JSON Schema document for content an outside tool writes: the root is a
312
+ * `SequenceEntry` — an activity of any registered type, or an item group whose
313
+ * items are typed too. Each type, the stimulus and the item group sit under
314
+ * `$defs` (`definitions` in draft 7), so a tool can also point at one of them.
315
+ * Draft 2020-12 unless `target` says `'draft-7'`.
316
+ *
317
+ * Structural, as every exported schema is: rules that span fields (one key in
318
+ * a single-answer question, a blank for each marker, a slow recording that is
319
+ * another file) cannot be written in JSON Schema. On import, `validateDraft`
320
+ * and `validateItemGroupDraft` decide. It includes the author-only fields
321
+ * (`transcript`, `script`), so a tool can write them.
322
+ *
323
+ * ```ts
324
+ * writeFileSync('schema.json', JSON.stringify(contentJsonSchema(), null, 2));
325
+ * ```
326
+ */
327
+ declare function contentJsonSchema(options?: {
328
+ target?: JsonSchemaTarget;
329
+ }): Record<string, unknown>;
330
+ /** The most turns a recording's `script` may hold. */
331
+ declare const SCRIPT_MAX_TURNS = 500;
309
332
  /**
310
333
  * Checks a piece of activity media — an item's `media`, a stimulus's, a
311
334
  * dictation's `slowMedia` — on its own, the way `validateActivity` checks it
@@ -338,6 +361,5 @@ declare function validateOptionMedia(value: unknown): ValidationResult<MultipleC
338
361
  * @throws UnknownActivityTypeError when `type` has no registered descriptor.
339
362
  */
340
363
  declare function validateActivity<T extends ActivityType>(type: T, data: unknown): ValidationResult<ActivityDataMap[T]>;
341
- //#endregion
342
- export { RedactedMultipleChoiceData as C, RedactedStimulus as D, RedactedReadAloudData as E, RedactedWrittenResponseData as O, RedactedGapSelectGap as S, RedactedMultipleChoiceOptionMedia as T, RedactedDictationSlowMedia as _, fillInTheBlanksJsonSchema as a, RedactedGapSelectChoice as b, jsonSchemaFor as c, stimulusJsonSchema as d, writtenResponseJsonSchema as f, RedactedDictationData as g, RedactedBlankConfig as h, dictationJsonSchema as i, multipleChoiceJsonSchema as l, RedactedActivity as m, validateMedia as n, gapSelectJsonSchema as o, validateItemGroup as p, validateOptionMedia as r, itemGroupJsonSchema as s, validateActivity as t, readAloudJsonSchema as u, RedactedFillInTheBlanksData as v, RedactedMultipleChoiceOption as w, RedactedGapSelectData as x, RedactedGapSelectBank as y };
343
- //# sourceMappingURL=index-qMbxed1B.d.cts.map
364
+ export { RedactedStimulus as A, RedactedGapSelectChoice as C, RedactedMultipleChoiceOption as D, RedactedMultipleChoiceData as E, RedactedMultipleChoiceOptionMedia as O, RedactedGapSelectBank as S, RedactedGapSelectGap as T, RedactedActivity as _, JsonSchemaTarget as a, RedactedDictationSlowMedia as b, fillInTheBlanksJsonSchema as c, jsonSchemaFor as d, multipleChoiceJsonSchema as f, validateItemGroup as g, writtenResponseJsonSchema as h, SCRIPT_MAX_TURNS as i, RedactedWrittenResponseData as j, RedactedReadAloudData as k, gapSelectJsonSchema as l, stimulusJsonSchema as m, validateMedia as n, contentJsonSchema as o, readAloudJsonSchema as p, validateOptionMedia as r, dictationJsonSchema as s, validateActivity as t, itemGroupJsonSchema as u, RedactedBlankConfig as v, RedactedGapSelectData as w, RedactedFillInTheBlanksData as x, RedactedDictationData as y };
365
+ //# sourceMappingURL=index-DP9rvyOz.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DP9rvyOz.d.cts","names":[],"sources":["../src/types/redacted.ts","../src/schemas/item-group.ts","../src/schemas/json-schema.ts","../src/schemas/media.ts","../src/schemas/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;UAoBU;EACR;EACA;EACA;EACA;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA,SAAS;EACT;EACA,WAAW;;;UAIH;EACR;EACA;;;UAIQ;EACR;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA,KAAK;;;UAIU;EACf;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA,QAAQ;;;UAIO,mCAAmC;EAClD;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;;;UAIe;EACf;EACA;;;UAIe,oCAAoC;EACnD;EACA;EACA;EACA;EACA,QAAQ;EACR;;;UAIe,oCAAoC;EACnD;EACA;EACA;EACA;EACA;EACA;IAEM;MACE;MACA;MACA;MACA;QAAW;QAAe;;;IAE5B;;EAGN;EACA;;;UAIe;EACf;EACA;;;UAIe;EACf;EACA,SAAS;;;UAIM;EACf;EACA,UAAU;EACV;;;UAIe,8BAA8B;EAC7C;EACA;EACA;EACA;EACA,MAAM;EACN,QAAQ;EACR;EACA;EACA;;;UAIe;EACf;EACA;EACA;;;UAIe,8BAA8B;EAC7C;EACA,YAAY;EACZ;IAAU;;EACV;;;;;;;UAQe,8BAA8B;EAC7C;EACA;EACA;EACA;EACA,YAAY;EACZ;IACE;IACA;IACA;;EAEF;IACE;MACE;MACA;;;;;UAMW;EACf;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;;;;;;;;;;;;;;KAeU,mBACR,6BACA,8BACA,8BACA,wBACA,wBACA;;;;;;;;;;;iBCyMY,kBAAkB,gBAAgB,iBAAiB;;;;;cCnatD,oBAAoB;;;;;;;;cAWpB,qBAAqB;;;;;;;;;;;;;;;;;;cAqBrB,qBAAqB;;;;;;;;;;;cAcrB,qBAAqB;;;;;;;;;;cAarB,qBAAqB;cAIrB,0BAA0B;;;;;;cAY1B,2BAA2B;;;;;cAW3B,2BAA2B;;KAQ5B;;;;;;;;;;;;;;;;;iBAqBI,cACd,cACA;EAAW,SAAS;IACnB;;;;;;;;;;;;;;;;;;iBA4Ca,kBACd;EAAW,SAAS;IACnB;;cCzEU;;;;;;;;;;;iBCnDG,cAAc,iBAAiB,iBAAiB;;;;;;;;iBAWhD,oBAAoB,iBAAiB,iBAAiB;;;;;;;;;;;;;iBA8BtD,iBAAiB,UAAU,cACzC,MAAM,GACN,gBACC,iBAAiB,gBAAgB"}
@@ -1,5 +1,4 @@
1
- import { Cn as XAPIContext, Dn as XAPIResult, kn as XAPIStatement, pn as ScoringResult, xn as XAPIActor } from "./ai-BYryFkF9.cjs";
2
- //#region src/xapi/verbs.d.ts
1
+ import { An as XAPIStatement, On as XAPIResult, Sn as XAPIActor, pn as ScoringResult, wn as XAPIContext } from "./ai-B1wYrqcB.cjs";
3
2
  /**
4
3
  * The set of xAPI verbs emitted by SDK activities, keyed by a stable
5
4
  * identifier mapped to its canonical xAPI verb IRI (xAPI 1.0.3 / ADL registry).
@@ -36,8 +35,6 @@ type XAPIVerbKey = keyof typeof XAPIVerb;
36
35
  * `XAPIVerbObject.display` when the builder resolves a verb key.
37
36
  */
38
37
  declare const XAPI_VERB_DISPLAY: Record<XAPIVerbKey, Record<string, string>>;
39
- //#endregion
40
- //#region src/xapi/builder.d.ts
41
38
  /** Caller-supplied activity object descriptor (mapped to an xAPI Activity). */
42
39
  interface XAPIObjectParams {
43
40
  /** Activity IRI. */
@@ -132,8 +129,6 @@ declare const xAPIBuilder: {
132
129
  declare function xapiDefinitionFor(data: {
133
130
  type: string;
134
131
  }): Partial<XAPIObjectParams>;
135
- //#endregion
136
- //#region src/xapi/validators.d.ts
137
132
  /**
138
133
  * Validates a constructed {@link XAPIStatement} against the xAPI 1.0.3
139
134
  * structural contract.
@@ -148,6 +143,5 @@ declare function xapiDefinitionFor(data: {
148
143
  * `XAPIValidationError` would be semantically cleaner — flagged for review.
149
144
  */
150
145
  declare function validateXAPIStatement(statement: XAPIStatement): void;
151
- //#endregion
152
146
  export { XAPIObjectParams as a, xapiDefinitionFor as c, XAPI_VERB_DISPLAY as d, SubmittedStatementParams as i, XAPIVerb as l, AnsweredStatementParams as n, XAPIStatementParams as o, CompletedStatementParams as r, xAPIBuilder as s, validateXAPIStatement as t, XAPIVerbKey as u };
153
- //# sourceMappingURL=index-D7R3Ll8R.d.cts.map
147
+ //# sourceMappingURL=index-XCCoPoTU.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-XCCoPoTU.d.cts","names":[],"sources":["../src/xapi/verbs.ts","../src/xapi/builder.ts","../src/xapi/validators.ts"],"mappings":";;;;;cAIa;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BD,2BAA2B;;;;;cAM1B,mBAAmB,OAAO,aAAa;;UCxBnC;;EAEf;EACA,OAAO;EACP,cAAc;;EAEd;;EAEA;;EAEA;;EAEA,UAAU;IAAQ;IAAY,cAAc;;;;UAI7B;EACf,OAAO;EACP,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;;;UAIK;EACf,OAAO;EACP,QAAQ;EACR,eAAe;EACf;;EAEA;EACA,UAAU;EACV,mBAAmB;;;;;;;UAQJ;EACf,OAAO;EACP,QAAQ;EACR;;EAEA;EACA,UAAU;EACV,mBAAmB;;;UAIJ;EACf,OAAO;EACP,QAAQ;EACR,gBAAgB;EAChB;EACA,UAAU;EACV,mBAAmB;;;;;;;cAiGR;EACY,eAAA,QAAA,sBAAsB;EAoBd,uBAAA,QAAA,0BAA0B;;;;;;;EAqBzB,wBAAA,QAAA,2BAA2B;EAc3B,wBAAA,QAAA,2BAA2B;;;;;;;;;;;;;;;;iBA8B7C,kBAAkB;EAAQ;IAAiB,QAAQ;;;;;;;;;;;;;;iBClHnD,sBAAsB,WAAW"}
package/dist/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_registry = require("./registry-Ce00A_OW.cjs");
3
- const require_ai_writing = require("./ai-writing-Cen7-3qs.cjs");
4
- const require_scoring = require("./scoring-lKQVYsxy.cjs");
5
- const require_item_group = require("./item-group-DEB7nLID.cjs");
6
- const require_schemas = require("./schemas-DksueYsu.cjs");
7
- const require_xapi = require("./xapi-NYrTlpID.cjs");
8
- //#region src/delivery.ts
2
+ const require_registry = require("./registry-hzrkTeIT.cjs");
3
+ const require_ai_writing = require("./ai-writing-DrPTV3R2.cjs");
4
+ const require_scoring = require("./scoring-CtkCFyFT.cjs");
5
+ const require_item_group = require("./item-group-8P3WFuUK.cjs");
6
+ const require_schemas = require("./schemas-BWeskONy.cjs");
7
+ const require_xapi = require("./xapi-7btSpx6v.cjs");
8
+ // src/delivery.ts
9
9
  /**
10
10
  * The policy that restricts nothing: every setting `true`. It is what an absent
11
11
  * policy resolves to, and it is exactly the behaviour the SDK had before
@@ -159,8 +159,7 @@ function validateDeliveryPolicy(policy) {
159
159
  data: given
160
160
  };
161
161
  }
162
- //#endregion
163
- //#region src/item-group.ts
162
+ // src/item-group.ts
164
163
  /** Narrows a sequence entry to an item group. */
165
164
  function isItemGroup(entry) {
166
165
  return entry.type === "item-group";
@@ -284,8 +283,7 @@ function flattenSequence(entries, options = {}) {
284
283
  }
285
284
  return slots;
286
285
  }
287
- //#endregion
288
- //#region src/media-budget.ts
286
+ // src/media-budget.ts
289
287
  /**
290
288
  * The authored-entry prefix of a slot id: `"3"` for both `"3"` and `"3.1"`.
291
289
  *
@@ -399,8 +397,7 @@ function restoreMediaPlayLedger(plan, stored) {
399
397
  if (stored.planHash !== plan.planHash) throw new Error(`restoreMediaPlayLedger: this ledger belongs to a different paper (ledger ${stored.planHash}, plan ${plan.planHash}). Restoring it would hold the learner to a play budget from an exam they never sat.`);
400
398
  return serializeMediaPlayLedger(plan, stored.entries, { ...stored.savedAt !== void 0 ? { savedAt: stored.savedAt } : {} });
401
399
  }
402
- //#endregion
403
- //#region src/attempt-plan.ts
400
+ // src/attempt-plan.ts
404
401
  /**
405
402
  * The activity as CONTENT, with its slot key removed.
406
403
  *
@@ -651,8 +648,7 @@ function scoredItemsFromPlan(plan, outcomes, options = {}) {
651
648
  outcome: Object.hasOwn(outcomes, slot.slotId) ? outcomes[slot.slotId] : missingOutcome(slot, policy)
652
649
  }));
653
650
  }
654
- //#endregion
655
- //#region src/attempt-state.ts
651
+ // src/attempt-state.ts
656
652
  /**
657
653
  * A DEEP copy of the responses.
658
654
  *
@@ -776,8 +772,7 @@ function diffResponses(before, after) {
776
772
  }
777
773
  return entries;
778
774
  }
779
- //#endregion
780
- //#region src/redact.ts
775
+ // src/redact.ts
781
776
  /** Merges per-call overrides over a registered policy, one level deep. */
782
777
  function mergePolicy(base, overrides) {
783
778
  if (overrides === void 0) return base;
@@ -907,7 +902,8 @@ const ITEM_GROUP_FIELD_POLICY = {
907
902
  media: require_registry.MEDIA_FIELD_POLICY,
908
903
  locale: "public",
909
904
  attribution: "public",
910
- transcript: "author-only"
905
+ transcript: "author-only",
906
+ script: "author-only"
911
907
  },
912
908
  timeline: {
913
909
  cues: {
@@ -994,8 +990,56 @@ function assertRedactedItemGroup(data) {
994
990
  }
995
991
  });
996
992
  }
997
- //#endregion
998
- //#region src/timeline.ts
993
+ /** A deep copy of plain data with every field its policy calls `author-only` left out. */
994
+ function withoutAuthorOnlyValue(value, policy) {
995
+ if (Array.isArray(value)) return value.map((element) => withoutAuthorOnlyValue(element, policy));
996
+ if (value === null || typeof value !== "object") return value;
997
+ const output = {};
998
+ for (const [key, field] of Object.entries(value)) {
999
+ const classification = policy?.[key];
1000
+ if (classification === "author-only") continue;
1001
+ output[key] = withoutAuthorOnlyValue(field, classification === void 0 || isSensitivity(classification) ? void 0 : classification);
1002
+ }
1003
+ return output;
1004
+ }
1005
+ /** The policy an activity is stripped under; the same one `redact()` reads. */
1006
+ function policyOf(type) {
1007
+ const descriptor = typeof type === "string" ? require_registry.getActivityTypeDescriptor(type) : void 0;
1008
+ if (descriptor === void 0) throw new require_registry.UnknownActivityTypeError(String(type));
1009
+ if (descriptor.fieldPolicy === void 0) throw new Error(`Activity type "${descriptor.type}" has no fieldPolicy; withoutAuthorOnly() cannot tell which of its fields are author-only.`);
1010
+ return descriptor.fieldPolicy;
1011
+ }
1012
+ /**
1013
+ * A copy of an activity or an item group without its `author-only` fields:
1014
+ * a recording's `transcript` and `script`, on an item's media, a
1015
+ * multiple-choice option's recording, a stimulus or its media. Everything
1016
+ * else is kept as stored, the answer key and your own fields included, and
1017
+ * the copy is not marked redacted, so it scores exactly as the stored item.
1018
+ *
1019
+ * For practice an app scores in the browser, where the learner may hold the
1020
+ * key but not the author's material. It is NOT a learner-safe projection: an
1021
+ * exam, or anything a learner must not be able to answer from the payload,
1022
+ * goes through {@link redact} / {@link redactItemGroup}, whose output a scorer
1023
+ * refuses.
1024
+ *
1025
+ * ```ts
1026
+ * res.json(withoutAuthorOnly(practiceItem));
1027
+ * ```
1028
+ *
1029
+ * @throws UnknownActivityTypeError when an activity's type is not registered,
1030
+ * and Error when it declares no `fieldPolicy`.
1031
+ */
1032
+ function withoutAuthorOnly(entry) {
1033
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) throw new TypeError("withoutAuthorOnly: expects an activity or an item group.");
1034
+ const record = entry;
1035
+ if (record.type !== "item-group") return withoutAuthorOnlyValue(entry, policyOf(record.type));
1036
+ const { items, ...container } = record;
1037
+ return {
1038
+ ...withoutAuthorOnlyValue(container, ITEM_GROUP_FIELD_POLICY),
1039
+ ...Array.isArray(items) ? { items: items.map((item) => withoutAuthorOnlyValue(item, policyOf(item?.type))) } : items !== void 0 ? { items } : {}
1040
+ };
1041
+ }
1042
+ // src/timeline.ts
999
1043
  /**
1000
1044
  * Reads a stored {@link MediaProgress}. Never throws: anything that is not one
1001
1045
  * — a string, a stale shape, an object whose getters throw — answers `null`,
@@ -1049,7 +1093,6 @@ function composeTimelineScore(entryKey, items, policy) {
1049
1093
  items: own
1050
1094
  }], policy);
1051
1095
  }
1052
- //#endregion
1053
1096
  exports.AI_COACHING_MAX_TIP_LENGTH = require_ai_writing.AI_COACHING_MAX_TIP_LENGTH;
1054
1097
  exports.AI_COACHING_MAX_WORDS = require_ai_writing.AI_COACHING_MAX_WORDS;
1055
1098
  exports.AI_CRITIQUE_MAX_FIELD_LENGTH = require_ai_writing.AI_CRITIQUE_MAX_FIELD_LENGTH;
@@ -1081,6 +1124,7 @@ exports.READ_ALOUD_MAX_REFERENCE_LENGTH = require_registry.READ_ALOUD_MAX_REFERE
1081
1124
  exports.READ_ALOUD_MAX_SECONDS = require_registry.READ_ALOUD_MAX_SECONDS;
1082
1125
  exports.READ_ALOUD_MAX_TAKES = require_registry.READ_ALOUD_MAX_TAKES;
1083
1126
  exports.RedactedScoringError = require_registry.RedactedScoringError;
1127
+ exports.SCRIPT_MAX_TURNS = require_registry.SCRIPT_MAX_TURNS;
1084
1128
  exports.SPEECH_ASSESSMENT_MAX_WORDS = require_registry.SPEECH_ASSESSMENT_MAX_WORDS;
1085
1129
  exports.TIMELINE_MAX_CHAPTERS = require_item_group.TIMELINE_MAX_CHAPTERS;
1086
1130
  exports.TIMELINE_MAX_ITEMS = require_item_group.TIMELINE_MAX_ITEMS;
@@ -1120,6 +1164,7 @@ exports.composeAssessmentScore = require_scoring.composeAssessmentScore;
1120
1164
  exports.composeTimelineScore = composeTimelineScore;
1121
1165
  exports.computePassThreshold = require_scoring.computePassThreshold;
1122
1166
  exports.contentHash = require_scoring.contentHash;
1167
+ exports.contentJsonSchema = require_schemas.contentJsonSchema;
1123
1168
  exports.countWords = require_registry.countWords;
1124
1169
  exports.createDraft = require_ai_writing.createDraft;
1125
1170
  exports.createInteractiveVideoDraft = require_ai_writing.createInteractiveVideoDraft;
@@ -1161,6 +1206,8 @@ exports.isItemGroup = isItemGroup;
1161
1206
  exports.itemGroupJsonSchema = require_schemas.itemGroupJsonSchema;
1162
1207
  exports.jsonSchemaFor = require_schemas.jsonSchemaFor;
1163
1208
  exports.levenshteinDistance = require_registry.levenshteinDistance;
1209
+ exports.listMediaRefs = require_ai_writing.listMediaRefs;
1210
+ exports.mapMediaRefs = require_ai_writing.mapMediaRefs;
1164
1211
  exports.matchText = require_registry.matchText;
1165
1212
  exports.multipleChoiceJsonSchema = require_schemas.multipleChoiceJsonSchema;
1166
1213
  exports.multipleChoiceType = require_registry.multipleChoiceType;
@@ -1193,6 +1240,7 @@ exports.serializeMediaPlayLedger = serializeMediaPlayLedger;
1193
1240
  exports.slotMediaKey = slotMediaKey;
1194
1241
  exports.stimulusJsonSchema = require_schemas.stimulusJsonSchema;
1195
1242
  exports.stimulusMediaKey = stimulusMediaKey;
1243
+ exports.transcriptOf = require_ai_writing.transcriptOf;
1196
1244
  exports.validateActivity = require_schemas.validateActivity;
1197
1245
  exports.validateDeliveryPolicy = validateDeliveryPolicy;
1198
1246
  exports.validateDraft = require_ai_writing.validateDraft;
@@ -1204,6 +1252,7 @@ exports.validateOptionMedia = require_schemas.validateOptionMedia;
1204
1252
  exports.validateSpeechAssessment = require_scoring.validateSpeechAssessment;
1205
1253
  exports.validateXAPIStatement = require_xapi.validateXAPIStatement;
1206
1254
  exports.verifyAttemptPlan = verifyAttemptPlan;
1255
+ exports.withoutAuthorOnly = withoutAuthorOnly;
1207
1256
  exports.writtenResponseJsonSchema = require_schemas.writtenResponseJsonSchema;
1208
1257
  exports.writtenResponseType = require_registry.writtenResponseType;
1209
1258
  exports.xAPIBuilder = require_xapi.xAPIBuilder;