systemoneprompts 0.1.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 (147) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +214 -0
  4. package/dist/answers.d.ts +21 -0
  5. package/dist/answers.d.ts.map +1 -0
  6. package/dist/answers.js +104 -0
  7. package/dist/answers.js.map +1 -0
  8. package/dist/cli/cache.d.ts +2 -0
  9. package/dist/cli/cache.d.ts.map +1 -0
  10. package/dist/cli/cache.js +26 -0
  11. package/dist/cli/cache.js.map +1 -0
  12. package/dist/cli/check.d.ts +2 -0
  13. package/dist/cli/check.d.ts.map +1 -0
  14. package/dist/cli/check.js +28 -0
  15. package/dist/cli/check.js.map +1 -0
  16. package/dist/cli/env.d.ts +2 -0
  17. package/dist/cli/env.d.ts.map +1 -0
  18. package/dist/cli/env.js +29 -0
  19. package/dist/cli/env.js.map +1 -0
  20. package/dist/cli/eval.d.ts +18 -0
  21. package/dist/cli/eval.d.ts.map +1 -0
  22. package/dist/cli/eval.js +314 -0
  23. package/dist/cli/eval.js.map +1 -0
  24. package/dist/cli/generate.d.ts +5 -0
  25. package/dist/cli/generate.d.ts.map +1 -0
  26. package/dist/cli/generate.js +93 -0
  27. package/dist/cli/generate.js.map +1 -0
  28. package/dist/cli/index.d.ts +3 -0
  29. package/dist/cli/index.d.ts.map +1 -0
  30. package/dist/cli/index.js +76 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/io.d.ts +28 -0
  33. package/dist/cli/io.d.ts.map +1 -0
  34. package/dist/cli/io.js +88 -0
  35. package/dist/cli/io.js.map +1 -0
  36. package/dist/cli/run.d.ts +7 -0
  37. package/dist/cli/run.d.ts.map +1 -0
  38. package/dist/cli/run.js +63 -0
  39. package/dist/cli/run.js.map +1 -0
  40. package/dist/client.d.ts +65 -0
  41. package/dist/client.d.ts.map +1 -0
  42. package/dist/client.js +301 -0
  43. package/dist/client.js.map +1 -0
  44. package/dist/cloudflare.d.ts +29 -0
  45. package/dist/cloudflare.d.ts.map +1 -0
  46. package/dist/cloudflare.js +159 -0
  47. package/dist/cloudflare.js.map +1 -0
  48. package/dist/definition/check.d.ts +9 -0
  49. package/dist/definition/check.d.ts.map +1 -0
  50. package/dist/definition/check.js +26 -0
  51. package/dist/definition/check.js.map +1 -0
  52. package/dist/definition/diagnostics.d.ts +29 -0
  53. package/dist/definition/diagnostics.d.ts.map +1 -0
  54. package/dist/definition/diagnostics.js +74 -0
  55. package/dist/definition/diagnostics.js.map +1 -0
  56. package/dist/definition/locate.d.ts +23 -0
  57. package/dist/definition/locate.d.ts.map +1 -0
  58. package/dist/definition/locate.js +211 -0
  59. package/dist/definition/locate.js.map +1 -0
  60. package/dist/definition/parse.d.ts +15 -0
  61. package/dist/definition/parse.d.ts.map +1 -0
  62. package/dist/definition/parse.js +170 -0
  63. package/dist/definition/parse.js.map +1 -0
  64. package/dist/definition/schema.d.ts +39 -0
  65. package/dist/definition/schema.d.ts.map +1 -0
  66. package/dist/definition/schema.js +11 -0
  67. package/dist/definition/schema.js.map +1 -0
  68. package/dist/dev/cache.d.ts +58 -0
  69. package/dist/dev/cache.d.ts.map +1 -0
  70. package/dist/dev/cache.js +287 -0
  71. package/dist/dev/cache.js.map +1 -0
  72. package/dist/dev/index.d.ts +2 -0
  73. package/dist/dev/index.d.ts.map +1 -0
  74. package/dist/dev/index.js +3 -0
  75. package/dist/dev/index.js.map +1 -0
  76. package/dist/factors/evaluate.d.ts +21 -0
  77. package/dist/factors/evaluate.d.ts.map +1 -0
  78. package/dist/factors/evaluate.js +199 -0
  79. package/dist/factors/evaluate.js.map +1 -0
  80. package/dist/factors/graph.d.ts +7 -0
  81. package/dist/factors/graph.d.ts.map +1 -0
  82. package/dist/factors/graph.js +39 -0
  83. package/dist/factors/graph.js.map +1 -0
  84. package/dist/factors/schema.d.ts +54 -0
  85. package/dist/factors/schema.d.ts.map +1 -0
  86. package/dist/factors/schema.js +235 -0
  87. package/dist/factors/schema.js.map +1 -0
  88. package/dist/generate/generate.d.ts +16 -0
  89. package/dist/generate/generate.d.ts.map +1 -0
  90. package/dist/generate/generate.js +100 -0
  91. package/dist/generate/generate.js.map +1 -0
  92. package/dist/generate/types.d.ts +10 -0
  93. package/dist/generate/types.d.ts.map +1 -0
  94. package/dist/generate/types.js +126 -0
  95. package/dist/generate/types.js.map +1 -0
  96. package/dist/index.d.ts +15 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +13 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/json.d.ts +6 -0
  101. package/dist/json.d.ts.map +1 -0
  102. package/dist/json.js +52 -0
  103. package/dist/json.js.map +1 -0
  104. package/dist/model.d.ts +9 -0
  105. package/dist/model.d.ts.map +1 -0
  106. package/dist/model.js +22 -0
  107. package/dist/model.js.map +1 -0
  108. package/dist/native.d.ts +97 -0
  109. package/dist/native.d.ts.map +1 -0
  110. package/dist/native.js +2 -0
  111. package/dist/native.js.map +1 -0
  112. package/dist/patterns/index.d.ts +3 -0
  113. package/dist/patterns/index.d.ts.map +1 -0
  114. package/dist/patterns/index.js +3 -0
  115. package/dist/patterns/index.js.map +1 -0
  116. package/dist/patterns/options.d.ts +2 -0
  117. package/dist/patterns/options.d.ts.map +1 -0
  118. package/dist/patterns/options.js +7 -0
  119. package/dist/patterns/options.js.map +1 -0
  120. package/dist/patterns/run-many.d.ts +41 -0
  121. package/dist/patterns/run-many.d.ts.map +1 -0
  122. package/dist/patterns/run-many.js +51 -0
  123. package/dist/patterns/run-many.js.map +1 -0
  124. package/dist/patterns/walk-taxonomy.d.ts +37 -0
  125. package/dist/patterns/walk-taxonomy.d.ts.map +1 -0
  126. package/dist/patterns/walk-taxonomy.js +81 -0
  127. package/dist/patterns/walk-taxonomy.js.map +1 -0
  128. package/dist/questions/references.d.ts +12 -0
  129. package/dist/questions/references.d.ts.map +1 -0
  130. package/dist/questions/references.js +76 -0
  131. package/dist/questions/references.js.map +1 -0
  132. package/dist/questions/schema.d.ts +18 -0
  133. package/dist/questions/schema.d.ts.map +1 -0
  134. package/dist/questions/schema.js +169 -0
  135. package/dist/questions/schema.js.map +1 -0
  136. package/dist/state/paths.d.ts +13 -0
  137. package/dist/state/paths.d.ts.map +1 -0
  138. package/dist/state/paths.js +70 -0
  139. package/dist/state/paths.js.map +1 -0
  140. package/dist/state/requirements.d.ts +25 -0
  141. package/dist/state/requirements.d.ts.map +1 -0
  142. package/dist/state/requirements.js +189 -0
  143. package/dist/state/requirements.js.map +1 -0
  144. package/docs/SPEC.html +57 -0
  145. package/docs/skills/systemoneprompts/SKILL.md +239 -0
  146. package/docs/skills/systemoneprompts/references/application-data.md +79 -0
  147. package/package.json +94 -0
@@ -0,0 +1,189 @@
1
+ import { diagnostic, SystemOnePromptsError } from "../definition/diagnostics.js";
2
+ import { locate } from "../definition/locate.js";
3
+ import { isJsonValue, isPlainObject, typeName } from "../json.js";
4
+ import { formatPath, getAtPath, parsePath } from "./paths.js";
5
+ export const REQUIREMENT_TYPES = [
6
+ "string",
7
+ "number",
8
+ "boolean",
9
+ "array",
10
+ "object",
11
+ "null",
12
+ "exists",
13
+ ];
14
+ export function parseRequirements(raw, index) {
15
+ const diagnostics = [];
16
+ const requires = Object.create(null);
17
+ if (raw == null)
18
+ return { requires, diagnostics };
19
+ if (!isPlainObject(raw)) {
20
+ diagnostics.push(diagnostic("error", "requires-not-table", "[requires] must be a table of path = type entries", locate(index, { table: "requires" })));
21
+ return { requires, diagnostics };
22
+ }
23
+ for (const [path, type] of Object.entries(raw)) {
24
+ const loc = locate(index, { section: "requires", key: path, table: "requires" });
25
+ const segments = parsePath(path);
26
+ if (segments == null) {
27
+ diagnostics.push(diagnostic("error", "invalid-require-path", `invalid [requires] path \`${path}\``, loc, "use dotted identifiers and [n], [-n], or [] indexes, e.g. ticket.message or messages[-1].text"));
28
+ continue;
29
+ }
30
+ if (!isRequirementType(type)) {
31
+ diagnostics.push(diagnostic("error", "invalid-require-type", `[requires] \`${path}\` has unknown type ${type == null ? "undefined" : `\`${String(type)}\``}`, loc, `expected ${REQUIREMENT_TYPES.join(" | ")}`));
32
+ continue;
33
+ }
34
+ requires[path] = type;
35
+ }
36
+ return { requires, diagnostics };
37
+ }
38
+ /**
39
+ * Check both explicit types and containers implied by dotted/indexed descendants.
40
+ * Compare parsed segments so spellings such as [0] and [00] refer to the same index.
41
+ */
42
+ export function checkRequirementConflicts(requires, index) {
43
+ const diagnostics = [];
44
+ const entries = Object.entries(requires).flatMap(([path, type]) => {
45
+ const segments = parsePath(path);
46
+ return segments ? [{ path, canonicalPath: formatPath(segments), type, segments }] : [];
47
+ });
48
+ const explicitTypes = new Set(entries.filter((entry) => entry.type !== "exists").map((entry) => entry.canonicalPath));
49
+ const reportedMixed = new Set();
50
+ for (let leftIndex = 0; leftIndex < entries.length; leftIndex += 1) {
51
+ const left = entries[leftIndex];
52
+ for (let rightIndex = leftIndex + 1; rightIndex < entries.length; rightIndex += 1) {
53
+ const right = entries[rightIndex];
54
+ const common = commonPrefixLength(left.segments, right.segments);
55
+ const leftEnds = common === left.segments.length;
56
+ const rightEnds = common === right.segments.length;
57
+ if (leftEnds || rightEnds) {
58
+ if (leftEnds && rightEnds) {
59
+ if (!compatibleAtSamePath(left.type, right.type)) {
60
+ diagnostics.push(diagnostic("error", "require-conflict", `[requires] \`${left.path}\` is required as both \`${left.type}\` and \`${right.type}\``, locate(index, { section: "requires", key: left.path, table: "requires" }), "keep one compatible requirement for this path"));
61
+ }
62
+ continue;
63
+ }
64
+ const parent = leftEnds ? left : right;
65
+ const child = leftEnds ? right : left;
66
+ reportParentConflict(parent, child, child.segments[common], diagnostics, index);
67
+ continue;
68
+ }
69
+ const leftNext = left.segments[common];
70
+ const rightNext = right.segments[common];
71
+ if (leftNext.kind === rightNext.kind)
72
+ continue;
73
+ const prefix = formatPath(left.segments.slice(0, common));
74
+ // Explicit types are checked against each descendant by reportParentConflict.
75
+ if (explicitTypes.has(prefix) || reportedMixed.has(prefix))
76
+ continue;
77
+ reportedMixed.add(prefix);
78
+ diagnostics.push(diagnostic("error", "require-conflict", `[requires] \`${left.path}\` and \`${right.path}\` require \`${prefix}\` to be both an array and an object`, locate(index, { section: "requires", key: left.path, table: "requires" }), `use either dotted keys or [n] indexes under \`${prefix}\``));
79
+ }
80
+ }
81
+ return diagnostics;
82
+ }
83
+ function commonPrefixLength(left, right) {
84
+ let length = 0;
85
+ while (length < left.length &&
86
+ length < right.length &&
87
+ conflictSameSegment(left[length], right[length])) {
88
+ length += 1;
89
+ }
90
+ return length;
91
+ }
92
+ function sameSegment(left, right) {
93
+ if (left.kind === "key" && right.kind === "key")
94
+ return left.name === right.name;
95
+ if (left.kind === "index" && right.kind === "index")
96
+ return left.index === right.index;
97
+ return left.kind === "all" && right.kind === "all";
98
+ }
99
+ /** `[]` covers `[n]` for conflict analysis; distinct `[n]` indexes stay distinct. */
100
+ function conflictSameSegment(left, right) {
101
+ if (sameSegment(left, right))
102
+ return true;
103
+ return impliesArray(left) && impliesArray(right) && (left.kind === "all" || right.kind === "all");
104
+ }
105
+ function impliesArray(segment) {
106
+ return segment.kind === "index" || segment.kind === "all";
107
+ }
108
+ function compatibleAtSamePath(left, right) {
109
+ return left === right || left === "exists" || right === "exists";
110
+ }
111
+ function reportParentConflict(parent, child, next, diagnostics, index) {
112
+ if (parent.type === "exists")
113
+ return;
114
+ const container = impliesArray(next) ? "array" : "object";
115
+ if (parent.type === container)
116
+ return;
117
+ const detail = parent.type === "object" || parent.type === "array"
118
+ ? `requires it to be an ${container}`
119
+ : "requires it to be a container";
120
+ diagnostics.push(diagnostic("error", "require-conflict", `[requires] \`${parent.path}\` is \`${parent.type}\` but \`${child.path}\` ${detail}`, locate(index, { section: "requires", key: parent.path, table: "requires" }), `change \`${parent.path}\` to "${container}" or "exists", or drop it`));
121
+ }
122
+ export function isRequirementType(value) {
123
+ return typeof value === "string" && REQUIREMENT_TYPES.includes(value);
124
+ }
125
+ /**
126
+ * Build an assertion that every `[requires]` path exists with the expected type.
127
+ * The assertion narrows and throws; it never copies or reshapes the state.
128
+ * Invalid paths fail here, at construction, rather than on first use.
129
+ */
130
+ export function createStateAssert(requires) {
131
+ const compiled = [];
132
+ for (const [path, expected] of Object.entries(requires)) {
133
+ const segments = parsePath(path);
134
+ if (!segments) {
135
+ throw new SystemOnePromptsError(diagnostic("error", "invalid-require-path", `invalid [requires] path \`${path}\``));
136
+ }
137
+ compiled.push({ path: formatPath(segments), expected, segments });
138
+ }
139
+ return (state) => {
140
+ for (const { path, expected, segments } of compiled) {
141
+ const error = assertSegments(state, segments, 0, path, expected);
142
+ if (error)
143
+ throw new SystemOnePromptsError(error);
144
+ }
145
+ };
146
+ }
147
+ /** Walk `segments` from `index`; `[]` checks every element and reports a non-array container. */
148
+ function assertSegments(current, segments, index, path, expected) {
149
+ if (index === segments.length)
150
+ return checkRequirement(path, expected, current);
151
+ const head = segments[index];
152
+ if (head.kind === "all") {
153
+ if (!Array.isArray(current)) {
154
+ return checkRequirement(formatPath(segments.slice(0, index)), "array", current);
155
+ }
156
+ for (const element of current) {
157
+ const error = assertSegments(element, segments, index + 1, path, expected);
158
+ if (error)
159
+ return error;
160
+ }
161
+ return undefined;
162
+ }
163
+ return assertSegments(getAtPath(current, [head]), segments, index + 1, path, expected);
164
+ }
165
+ export function checkRequirement(path, expected, actual) {
166
+ if (matchesType(expected, actual))
167
+ return undefined;
168
+ const got = actual === undefined ? "undefined" : typeName(actual);
169
+ return diagnostic("error", "state-requirement", `${path}: expected ${expected}, got ${got}`);
170
+ }
171
+ function matchesType(expected, actual) {
172
+ switch (expected) {
173
+ case "string":
174
+ return typeof actual === "string";
175
+ case "number":
176
+ return typeof actual === "number" && Number.isFinite(actual);
177
+ case "boolean":
178
+ return typeof actual === "boolean";
179
+ case "array":
180
+ return Array.isArray(actual) && isJsonValue(actual);
181
+ case "object":
182
+ return isPlainObject(actual) && isJsonValue(actual);
183
+ case "null":
184
+ return actual === null;
185
+ case "exists":
186
+ return actual !== undefined;
187
+ }
188
+ }
189
+ //# sourceMappingURL=requirements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/state/requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,UAAU,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAClG,OAAO,EAAE,MAAM,EAAoB,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAoB,SAAS,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,QAAQ;IACR,MAAM;IACN,QAAQ;CACA,CAAC;AASX,MAAM,UAAU,iBAAiB,CAC/B,GAAY,EACZ,KAAkB;IAElB,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAiB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAClD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,oBAAoB,EACpB,mDAAmD,EACnD,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CACrC,CACF,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC,EAAE,CAAC;QAC1E,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,sBAAsB,EACtB,6BAA6B,IAAI,IAAI,EACrC,GAAG,EACH,+FAA+F,CAChG,CACF,CAAC;YACF,SAAS;QACX,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,sBAAsB,EACtB,gBAAgB,IAAI,uBAAuB,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAC/F,GAAG,EACH,YAAY,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAC5C,CACF,CAAC;YACF,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAsB,EACtB,KAAkB;IAElB,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CACvF,CAAC;IACF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAExC,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAE,CAAC;QACjC,KAAK,IAAI,UAAU,GAAG,SAAS,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;YAClF,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAE,CAAC;YACnC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACjD,MAAM,SAAS,GAAG,MAAM,KAAK,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAEnD,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAC1B,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBACjD,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,kBAAkB,EAClB,gBAAgB,IAAI,CAAC,IAAI,4BAA4B,IAAI,CAAC,IAAI,YAAY,KAAK,CAAC,IAAI,IAAI,EACxF,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EACzE,+CAA+C,CAChD,CACF,CAAC;oBACJ,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;gBACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtC,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAE,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBACjF,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAE,CAAC;YACxC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAE,CAAC;YAC1C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;gBAAE,SAAS;YAE/C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1D,8EAA8E;YAC9E,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YACrE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1B,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,kBAAkB,EAClB,gBAAgB,IAAI,CAAC,IAAI,YAAY,KAAK,CAAC,IAAI,gBAAgB,MAAM,sCAAsC,EAC3G,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EACzE,iDAAiD,MAAM,IAAI,CAC5D,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,kBAAkB,CAAC,IAA4B,EAAE,KAA6B;IACrF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OACE,MAAM,GAAG,IAAI,CAAC,MAAM;QACpB,MAAM,GAAG,KAAK,CAAC,MAAM;QACrB,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAE,EAAE,KAAK,CAAC,MAAM,CAAE,CAAC,EAClD,CAAC;QACD,MAAM,IAAI,CAAC,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,IAAiB,EAAE,KAAkB;IACxD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;IACjF,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC;IACvF,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;AACrD,CAAC;AAED,qFAAqF;AACrF,SAAS,mBAAmB,CAAC,IAAiB,EAAE,KAAkB;IAChE,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,YAAY,CAAC,OAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC;AAC5D,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAqB,EAAE,KAAsB;IACzE,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC;AACnE,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAA+C,EAC/C,KAAuB,EACvB,IAAiB,EACjB,WAAyB,EACzB,KAAkB;IAElB,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO;IACrC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1D,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO;IAEtC,MAAM,MAAM,GACV,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QACjD,CAAC,CAAC,wBAAwB,SAAS,EAAE;QACrC,CAAC,CAAC,+BAA+B,CAAC;IACtC,WAAW,CAAC,IAAI,CACd,UAAU,CACR,OAAO,EACP,kBAAkB,EAClB,gBAAgB,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,IAAI,YAAY,KAAK,CAAC,IAAI,MAAM,MAAM,EAAE,EACrF,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAC3E,YAAY,MAAM,CAAC,IAAI,UAAU,SAAS,2BAA2B,CACtE,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,iBAAuC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC/F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsB;IAEtB,MAAM,QAAQ,GAAgF,EAAE,CAAC;IACjG,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,IAAI,IAAI,CAAC,CACnF,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,CAAC,KAAc,EAAsB,EAAE;QAC5C,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,QAAQ,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACjE,IAAI,KAAK;gBAAE,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,SAAS,cAAc,CACrB,OAAgB,EAChB,QAAgC,EAChC,KAAa,EACb,IAAY,EACZ,QAAyB;IAEzB,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,gBAAgB,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAClF,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3E,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,QAAyB,EACzB,MAAe;IAEf,IAAI,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,IAAI,cAAc,QAAQ,SAAS,GAAG,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,WAAW,CAAC,QAAyB,EAAE,MAAe;IAC7D,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC;QACpC,KAAK,QAAQ;YACX,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/D,KAAK,SAAS;YACZ,OAAO,OAAO,MAAM,KAAK,SAAS,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACtD,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACtD,KAAK,MAAM;YACT,OAAO,MAAM,KAAK,IAAI,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,MAAM,KAAK,SAAS,CAAC;IAChC,CAAC;AACH,CAAC"}
package/docs/SPEC.html ADDED
@@ -0,0 +1,57 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>systemoneprompts definition contract</title>
7
+ <style>
8
+ :root { color-scheme: light dark; }
9
+ body { max-width: 920px; margin: 3rem auto; padding: 0 1.25rem; font: 16px/1.6 system-ui, sans-serif; }
10
+ code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
11
+ code { padding: .1rem .25rem; border-radius: .25rem; background: #8882; }
12
+ pre { overflow-x: auto; padding: 1rem; border-radius: .5rem; background: #8882; }
13
+ h1, h2, h3 { line-height: 1.2; margin-top: 2rem; }
14
+ a { color: #268bd2; }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <h1 id="systemoneprompts-definition-contract">systemoneprompts definition contract</h1>
19
+ <p>Status: contract version <code>v1</code>. The TypeScript package is the reference implementation; the Python package is required to match the language-neutral rules below. Package-specific APIs may be idiomatic, but the parsed questions, state guarantees, factor truth tables, diagnostics, and generated artifacts must preserve the same behavior.</p>
20
+ <h2 id="definition-shape">Definition shape</h2>
21
+ <p>A definition is a TOML document with optional scalar metadata (<code>title</code>, <code>version</code>, <code>description</code>, <code>model</code>, plus other scalar keys) and four recognized tables: <code>[requires]</code>, <code>[questions]</code>, <code>[factors]</code>, and optional <code>[data]</code>. Unknown top-level tables produce warnings and are not silently interpreted. <code>model</code> is an optional non-empty string; a blank model is an error.</p>
22
+ <p>The parser throws only for invalid TOML. Structural problems are returned as diagnostics and the invalid entry is omitted. <code>checkDefinition</code>/<code>check_definition</code> adds cross-cutting reference, conflict, cycle, and lint diagnostics.</p>
23
+ <h2 id="application-data">Application data</h2>
24
+ <p><code>[data]</code> is an optional application-owned namespace. Its root must be a TOML table. Beneath it, arbitrary nested JSON-compatible objects, arrays, strings, booleans, finite numbers, and arrays of tables are preserved verbatim. TOML dates/times and other non-JSON values are rejected with diagnostics. An absent or invalid data tree is represented as an empty object/dictionary when the definition is returned; invalid definitions still fail normal checking and generation.</p>
25
+ <p>systemoneprompts does not assign meaning to child keys, validate application IDs or placeholders, resolve references, interpolate strings, load files, send data to TypeSafe, or make factors and questions depend on it. It does not apply question backtick linting inside data. Applications decide their own schema, validation and runtime use. Generated TypeScript and Python modules export the parsed tree as <code>data</code>; generated output remains deterministic. Application-only data therefore has no provider or cache effect unless application code explicitly projects it into a question or state.</p>
26
+ <h2 id="questions">Questions</h2>
27
+ <p>At least one question is required. Question IDs are literal TOML keys, including quoted IDs containing dots. Every question is a table with only <code>type</code>, <code>instructions</code>, and <code>criteria</code>:</p>
28
+ <ul>
29
+ <li><code>noul</code>: optional <code>criteria</code> table with only <code>true</code> and <code>false</code> entries.</li>
30
+ <li><code>choice</code>: non-empty criteria table with at most 255 labels.</li>
31
+ <li><code>score</code>: criteria array with at least two entries.</li>
32
+ </ul>
33
+ <p><code>instructions</code> and criteria entries are forwarded verbatim when they are a string, JSON-compatible table, or JSON-compatible array. TOML dates, times, cycles, non-finite numbers, and other runtime-only values are rejected. The resulting objects use the native TypeSafe field names and shapes; no aliases or implicit question vocabulary are introduced.</p>
34
+ <p>Native System One answers under a response <code>answers</code> map:</p>
35
+ <ul>
36
+ <li>Noul: type <code>noul</code> and a finite <code>noul</code> number.</li>
37
+ <li>Choice: type <code>choice</code>, a <code>choice</code> label, finite <code>confidence</code>, and <code>probabilities</code> with a finite probability for every criteria label.</li>
38
+ <li>Score: type <code>score</code>, a finite <code>score</code> expected value (a float between levels, not a level label), finite <code>confidence</code>, plus <code>legend</code> and <code>probabilities</code> keyed by the decimal string of each criteria index (<code>"0"</code>, <code>"1"</code>, ...).</li>
39
+ </ul>
40
+ <p>Packages may expose helpers that read those fields and that partition answers into valid, missing, and malformed ids. They must not invent a Score level as a native field. <code>wireQuestions</code> / <code>wire_questions</code> returns only <code>type</code>, <code>instructions</code>, and <code>criteria</code> for each question.</p>
41
+ <h2 id="state-requirements">State requirements</h2>
42
+ <p><code>[requires]</code> maps dotted and indexed paths to one of: <code>string</code>, <code>number</code>, <code>boolean</code>, <code>array</code>, <code>object</code>, <code>null</code>, or <code>exists</code>. Paths use own object keys, zero-based <code>[n]</code> indexes, negative <code>[-n]</code> indexes from the end of an array, and empty <code>[]</code> indexes. <code>[]</code> means every array element: <code>"messages[].text" = "string"</code> requires <code>messages</code> to be an array and every element's <code>text</code> to be a string. An empty array satisfies a <code>[]</code> requirement; a container that is not an array fails as <code>messages: expected array, got &lt;type&gt;</code>. <code>[]</code> and <code>[n]</code> both imply an array container and do not conflict with each other. A backticked <code>[n]</code> path is guaranteed when <code>[requires]</code> names the same path with <code>[]</code>; a backticked <code>[]</code> path is not guaranteed by a more specific <code>[n]</code> requirement. <code>exists</code> accepts null; all other types require the value to match. <code>number</code>, <code>array</code>, and <code>object</code> also require JSON-compatible values. Assertions never copy, coerce, or reshape the application state.</p>
43
+ <p>Explicit requirements and containers implied by descendants must agree. For example, <code>ticket = "object"</code> may accompany <code>ticket.message</code>, while <code>ticket = "string"</code> may not. Dotted and indexed descendants cannot require the same container to be both an object and an array. Equivalent index spellings refer to the same index, and out-of-bounds indexes fail at runtime.</p>
44
+ <h2 id="factors">Factors</h2>
45
+ <p>Every factor evaluates to a Boolean. A factor is exactly one predicate (<code>ref</code>) or one Boolean operator (<code>all</code>, <code>any</code>, <code>not</code>, <code>at_least</code>). Predicate fields are <code>known</code>, <code>choice</code>, <code>noul</code>, <code>score</code>, and <code>confidence</code>; numeric fields use one or more finite comparators from <code>gt</code>, <code>gte</code>, <code>lt</code>, and <code>lte</code> and all present comparators are ANDed.</p>
46
+ <p>Bare Noul references in Boolean operators use <code>noul &gt;= 0.5</code>. Choice and Score answers must be wrapped in a predicate. Missing answers are runtime errors, not false values, except a <code>known</code>-only predicate: it returns false for an absent or unusable answer. <code>known</code> treats explicit <code>missing</code>, confidence <code>0</code>, and a bare Noul exactly equal to <code>0.5</code> as unknown; usable Choice and Score answers are known.</p>
47
+ <p>Boolean operators validate every operand even if an earlier operand already determines the result. Factor definitions are snapshotted when an evaluator is created, factor IDs are prototype-safe, and independent cycles are reported together. Unknown references, question/factor ID collisions, invalid operator fields, invalid choice labels, primitive mismatches, and cycles are definition errors.</p>
48
+ <h2 id="generation-and-cli">Generation and CLI</h2>
49
+ <p>Generation is deterministic. It emits native question objects, model metadata, the verbatim factor definitions, a state assertion, and a typed factor evaluator. Empty requirements still produce a state type assignable to the package <code>EntryType</code>. Generated output must typecheck/import in a clean consumer.</p>
50
+ <p>The CLI supports <code>check</code>, <code>generate</code>, <code>run</code>, <code>eval</code>, and <code>cache</code>. <code>check</code> and <code>generate --check</code> process every input and return nonzero if any input fails. They never call the provider. <code>run</code> validates state before any request. <code>eval</code> validates cases, labels, factor names, sweep fields, and report paths before requests; partial reports survive execution errors. Live credentials are required only by explicit live commands.</p>
51
+ <h2 id="cache-and-patterns">Cache and patterns</h2>
52
+ <p>The TypeScript development cache is a fetch interceptor, not a client wrapper. It keys per-question requests by canonical JSON request data and model, writes records atomically, treats malformed records as misses, validates cached answers against the question criteria, and merges valid cached hits with valid live answers. Read-only misses fail. Cache statistics are cumulative and prototype-safe.</p>
53
+ <p><code>runMany</code> requires a positive concurrency limit, preserves input order, and invokes a result callback at most once per result. It may ask the same questions about many states, or a list of <code>{state, questions}</code> items. Callback failures reject the batch without retries. <code>walkTaxonomy</code> requires a positive beam width and is an explicit approximate beam search; it does not promise an exhaustive traversal.</p>
54
+ <h2 id="compatibility">Compatibility</h2>
55
+ <p>The TOML author-owned <code>version</code> is distinct from this behavioral contract version. Cases in <code>conformance/v1</code> are the executable compatibility boundary. Any change to native question shape, state assertion semantics, factor truth tables, diagnostic codes, cache records, or CLI exit behavior requires a new fixture and a compatibility review.</p>
56
+ </body>
57
+ </html>
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: systemoneprompts
3
+ description: "Use the systemoneprompts TypeScript package to author System One TOML decision definitions, validate and generate modules, integrate native TypeSafe questions, and evaluate decisions. Includes domain organization and application-data authoring guidance. Use for systemoneprompts package work, not generic TypeSafe prompting without this package."
4
+ ---
5
+
6
+ # Using systemoneprompts
7
+
8
+ systemoneprompts turns System One TOML decision definitions into native TypeSafe questions,
9
+ minimum state assertions and Boolean factors. Application code calls the
10
+ provider and decides what happens. Keep that boundary visible.
11
+
12
+ ## Establish the supported contract
13
+
14
+ Read the package documentation before choosing an API or CLI option:
15
+
16
+ - [Package README](../../../README.md) for APIs, CLI options and examples.
17
+ - [Shared specification](../../SPEC.html) for format and semantic details.
18
+ - [Application-data layout](references/application-data.md) when organizing
19
+ copy, labels and examples beside domain questions.
20
+
21
+ Check the installed package version when it differs from this checkout.
22
+
23
+ Structured `[data]` is implemented in this package. It is an arbitrary,
24
+ JSON-compatible application-owned tree beneath a TOML table root. The package
25
+ preserves and exports it; it does not assign child-key semantics, render it,
26
+ send it to the provider, or validate an application's schema. For older
27
+ installed versions, verify support before using `definition.data` or a
28
+ generated `data` export.
29
+
30
+ ## Author a definition
31
+
32
+ Use native question fields: `type`, `instructions`, `criteria`. Define at least
33
+ one question. Use `noul` for a yes/no judgment, `choice` for a categorical
34
+ selection, and `score` for an ordered magnitude. Instructions and criteria
35
+ entries may contain strings, objects or arrays; they are forwarded to the
36
+ provider, so application-only metadata does not belong there.
37
+
38
+ ```toml
39
+ title = "Support topic"
40
+
41
+ [requires]
42
+ "message" = "string"
43
+
44
+ [questions.topic]
45
+ type = "choice"
46
+ instructions = "Which topic best describes `message`?"
47
+
48
+ [questions.topic.criteria]
49
+ delivery = "Shipment tracking, delivery timing, or a missing parcel."
50
+ billing = "Charges, invoices, or payment failures; excludes shipment tracking."
51
+ other = "The request fits neither topic, or its topic is unspecified."
52
+
53
+ [factors]
54
+ is_delivery = { ref = "topic", choice = "delivery" }
55
+ ```
56
+
57
+ Define one clear judgment per question. Explain neighboring boundaries rather
58
+ than relying on labels or examples alone. Structured criteria such as
59
+ `{ what = "...", not_for = "...", examples = [...] }` are ordinary author-chosen
60
+ payloads, not extra question fields or a phrase-matching grammar.
61
+
62
+ Use `[requires]` for the minimum evidence the questions need. Supported types
63
+ are `string`, `number`, `boolean`, `array`, `object`, `null` and `exists`.
64
+ Quote dotted or indexed paths, such as `"customer.orders[0].id"`; `"messages[].text"` requires every element's `text`. Assertions
65
+ check the supplied state; they neither transform it nor remove extra fields.
66
+ Build an appropriate provider state explicitly in application code.
67
+
68
+ Question and factor IDs are literal keys. A dotted ID is not a nested path:
69
+ quote it when authoring one. Do not give a question and factor the same ID.
70
+ Quote date/time values intended as strings and avoid non-finite numbers.
71
+
72
+ ## Check, generate and integrate
73
+
74
+ 1. Validate the definition before provider calls. `checkDefinition` returns
75
+ diagnostics for structural and cross-reference problems;
76
+ parsing successfully does not mean a definition is valid. Fix errors and
77
+ inspect warnings. `--strict` makes warnings errors when that is appropriate
78
+ for the project.
79
+ 2. Generate the module using the package CLI, or load and validate definitions
80
+ at runtime using its API. Do not hand-edit generated files.
81
+ 3. Assert state, call `TypeSafeClient.systemOne` (or Python
82
+ `TypeSafeClient.system_one`), and evaluate factors against its answers.
83
+ Application code owns thresholds, routing and side effects.
84
+ 4. After source changes, regenerate checked-in output and use `generate --check`
85
+ to detect stale artifacts. Follow the target package's output-path options.
86
+
87
+ TypeScript consumer commands:
88
+
89
+ ```sh
90
+ npm install systemoneprompts
91
+ # or: bun add systemoneprompts
92
+ npx systemoneprompts check support.toml --strict
93
+ npx systemoneprompts generate support.toml
94
+ npx systemoneprompts generate support.toml --check
95
+ # bunx systemoneprompts works the same way
96
+ ```
97
+
98
+ Generated-module usage; executing the provider call requires live credentials:
99
+
100
+ ```ts
101
+ import { TypeSafeClient } from "systemoneprompts";
102
+ import {
103
+ assertState, questions, model, evaluateFactors,
104
+ } from "./support.generated.js";
105
+
106
+ const state = { message: "Where is my parcel?" };
107
+ assertState(state);
108
+ const response = await new TypeSafeClient().systemOne({ state, questions, model });
109
+ const factors = evaluateFactors(response.answers);
110
+ // Application code consumes factors.is_delivery and the underlying answers.
111
+ ```
112
+
113
+ `assertState` returns nothing; do not assign its result to state. For an
114
+ offline answer check, call the generated `evaluateFactors` with supplied
115
+ answers. The TypeScript CLI has no `run --answers` option.
116
+
117
+ Live `run` and `eval` build `{ state, questions, model }`. Native TypeSafe uses
118
+ `TYPESAFE_API_KEY`. OpenRouter is the same client with
119
+ `baseURL: "https://openrouter.ai/api"`; pass the OpenRouter key as `apiKey`, or
120
+ put it in `TYPESAFE_API_KEY` for CLI. There is no `OPENROUTER_API_KEY`
121
+ integration. Cloudflare Workers AI is the same client with
122
+ `cloudflareAccountId` / `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`
123
+ (not `TYPESAFE_API_KEY`); do not set `TYPESAFE_BASE_URL` at the same time. The
124
+ client rewrites the body to `{ model: "typesafe/jev", input: { state, questions } }`
125
+ at `https://api.cloudflare.com/client/v4/accounts/{id}/ai/run`. `--model` does
126
+ not change that catalog id. `--cache` wraps Cloudflare inside the cache so keys
127
+ stay System One JSON. See the package README Providers section for model ids.
128
+
129
+ `check` and `generate` are offline. Live `run` and `eval` use provider
130
+ credentials; a format or rendering edit alone does not require a live call.
131
+
132
+ ## Use factors for small Boolean derivations
133
+
134
+ Every factor is one predicate (`ref`) or one operator (`all`, `any`, `not`,
135
+ `at_least`). Use explicit `choice`, `noul`, `score` or supported `confidence`
136
+ predicates with finite `gt`, `gte`, `lt`, `lte` comparisons where needed.
137
+ Calibrate operational thresholds against the application's evaluation cases.
138
+
139
+ Keep these semantics in mind:
140
+
141
+ - A bare Noul in a Boolean operator means `noul >= 0.5`. It is not a calibrated
142
+ authorization threshold. Choice and Score references require predicates.
143
+ - Missing answers normally throw. A `known`-only predicate is the exception
144
+ for checking absent or unusable answers. `known` does not prove correctness.
145
+ - Boolean operators validate every operand, even when an earlier operand
146
+ determines the result. Do not build a conditional decoder by assuming
147
+ short-circuit behaviour or that `known` will guard a later missing operand.
148
+ - Weighted scores, required-versus-optional answers, calculations and workflow
149
+ precedence belong in ordinary code. Factors do not authorize actions merely
150
+ because their names contain words such as `safe` or `approved`.
151
+
152
+ ## Organize domain files for humans
153
+
154
+ Prefer one file per coherent area and a separate `router.toml` when useful.
155
+ Keep local meanings and related authored material together. Split a file when
156
+ navigating it becomes harder than understanding the domain; one giant TOML is
157
+ not a goal.
158
+
159
+ The router owns distinctions between areas; domain files own their local
160
+ distinctions. These are organizational conventions, not built-in routing.
161
+ Application code imports and assembles files, handles ID collisions explicitly,
162
+ and decides scheduling. Separate files do not require separate model calls.
163
+ Independent questions can share a batch, but a question cannot consume another
164
+ answer from that same batch.
165
+
166
+ Use TOML when changing the definition is easier to review than changing code.
167
+ If an edit requires mentally executing conditions, loops or state transitions,
168
+ prefer a function. Do not invent include/merge rules or a workflow language to
169
+ make every part of an application fit in configuration.
170
+
171
+ ## Author application data without imposing a universal schema
172
+
173
+ Apply these conventions to application-owned configuration and `[data]`. The
174
+ feature preserves and exports an arbitrary JSON-compatible tree beneath a
175
+ table root. Applications choose its structure, validation and interpretation.
176
+ Names such
177
+ as `topics`, `templates`, `utterances` or `examples` have no core semantics.
178
+
179
+ Choose content deliberately:
180
+
181
+ - Co-locate stable authored labels, descriptions, short copy, wording variants,
182
+ domain metadata and representative cases that change together.
183
+ - Keep model instructions in questions. Application data is not automatically
184
+ sent to the model; projecting selected values into a request requires code.
185
+ - Keep live facts, dynamic candidates and state in their authoritative runtime
186
+ sources. Avoid duplicating prices, availability or capability lists across
187
+ prompts and UI copy. A static authored policy may live in configuration when
188
+ that configuration is its authoritative source.
189
+ - Keep rendering decisions, computations, consent, state changes and execution
190
+ in code. A template can hold wording; it does not choose when to speak or
191
+ supply facts. Literal braces do not imply a systemoneprompts template engine.
192
+ - Distinguish recognition examples, response utterances and evaluation cases.
193
+ Held-out cases must not automatically become prompt examples. Example lists
194
+ illustrate boundaries; they do not enumerate all supported wording.
195
+ - Keep secrets, private conversation histories and runtime logs out of authored
196
+ definition files.
197
+
198
+ Format for easy scanning and review:
199
+
200
+ - Use shallow hierarchy and one header per meaningful collection, avoiding a
201
+ repeated dotted header for each label or phrase.
202
+ - Prefer keyed tables for simple dictionaries. Prefer multiline arrays of
203
+ compact inline records when entries have several fields, one record per row.
204
+ - Put each utterance on its own line in a variant list. Use multiline strings
205
+ for paragraphs. Expand large records into tables or arrays of tables when a
206
+ single row becomes unwieldy.
207
+ - Use stable IDs instead of list positions for references. Keep a predictable
208
+ order, related entries together, and one authoritative definition per purpose.
209
+ - Use normal TOML values, not delimiter-separated strings or embedded expression
210
+ languages. Comments should explain distinctions and ownership.
211
+ - Show a complete small domain when explaining a layout, focused diffs when
212
+ reviewing an edit, and clearly label future or application-specific syntax.
213
+
214
+ The [delivery example](references/application-data.md)
215
+ illustrates compact records, multiline utterances and application-owned cases.
216
+ Its alternative keyed label table illustrates when records add needless noise.
217
+ These layouts are suggestions; follow an application's established schema.
218
+
219
+ Validate that schema in the application, preferably before runtime use. Check
220
+ duplicate record IDs, unknown fields, copy references, placeholders and code
221
+ registrations where relevant. Those are application guarantees, not core
222
+ systemoneprompts checks. A field such as `read_only = true` cannot enforce behaviour.
223
+ Inline examples also need an application adapter before they are CLI eval cases.
224
+
225
+ ## Evaluate the decision, then report what was verified
226
+
227
+ The CLI eval format is JSONL: each case supplies `state`, optional `id`,
228
+ expected question `labels`, and/or expected Boolean `factors`. Choice labels
229
+ are option IDs, Noul labels are Booleans, and Score labels are integer indices.
230
+ Use full cases and defined factor names; inspect errors before provider calls.
231
+
232
+ Include contrastive, ambiguous and out-of-domain inputs. Keep held-out cases
233
+ separate from prompt examples. For a bad result, inspect the failed boundary
234
+ before adding more wording or changing a threshold. Application tests should
235
+ also verify any state or action invariants beyond classification.
236
+
237
+ Distinguish offline parsing, generation and supplied-answer checks from live
238
+ recognition evaluation. Report the checks actually run. Keep the change scoped
239
+ to package usage unless the user also requests library implementation work.
@@ -0,0 +1,79 @@
1
+ # Application-owned data layout
2
+
3
+ Status: `[data]` is implemented in this package as of 20 September 2026.
4
+ Verify support in older installed versions before relying on the generated
5
+ `data` export. Applications own the child schema and interpretation.
6
+
7
+ This example keeps one area's questions, compact metadata, copy and a few
8
+ recognition checks together. The `data` namespace is the core feature; every
9
+ child name and reference is an application convention.
10
+
11
+ ```toml
12
+ title = "Delivery"
13
+
14
+ [requires]
15
+ "message" = "string"
16
+
17
+ [questions.topic]
18
+ type = "choice"
19
+ instructions = """
20
+ Identify the delivery information requested in `message`.
21
+ Asking about a delivery method does not select it.
22
+ """
23
+
24
+ [questions.topic.criteria]
25
+ cost = "Asks about delivery prices or charges."
26
+ timing = "Asks when delivery arrives or how long it takes."
27
+ none = "No delivery-information request."
28
+ unclear = "A delivery question whose meaning is uncertain."
29
+
30
+ [data]
31
+ topics = [
32
+ { id = "cost", label = "Delivery prices", scope = "delivery_method", reply = "cost" },
33
+ { id = "timing", label = "Delivery times", scope = "delivery_method", reply = "timing" },
34
+ ]
35
+
36
+ templates = [
37
+ { id = "cost", text = "{method_label} costs {price_label}." },
38
+ { id = "timing", text = "{method_label}: {timing_label}." },
39
+ { id = "missing_scope", text = "Which delivery method do you mean?" },
40
+ ]
41
+
42
+ utterances = [
43
+ { id = "acknowledge", variants = [
44
+ "Of course.",
45
+ "Sure.",
46
+ ] },
47
+ { id = "explain", variants = [
48
+ """
49
+ I can explain delivery prices and timing.
50
+ The available options depend on your order.
51
+ """,
52
+ ] },
53
+ ]
54
+
55
+ examples = [
56
+ { message = "what would express set me back?", labels = { topic = "cost" } },
57
+ { message = "how long does standard take?", labels = { topic = "timing" } },
58
+ { message = "use express", labels = { topic = "none" } },
59
+ ]
60
+ ```
61
+
62
+ The application validates IDs, references and placeholders, supplies verified
63
+ prices and timing, and decides whether to acknowledge or clarify. systemoneprompts
64
+ would preserve data without rendering it, forwarding it to the model or
65
+ executing anything. The examples need an application adapter to become CLI
66
+ eval cases with full `state` objects; they are not automatically prompt examples.
67
+
68
+ For a simple dictionary, a keyed table can be shorter than records:
69
+
70
+ ```toml
71
+ [data.labels]
72
+ cost = "Delivery prices"
73
+ timing = "Delivery times"
74
+ ```
75
+
76
+ This is an alternative organization, not a requirement to duplicate the labels
77
+ from `topics`. Prefer a header for a meaningful collection over a separate
78
+ `[data.labels.cost]` header for a single string. Use tables or arrays of tables
79
+ when complex records cease to fit comfortably on one row.