@loxtep/sdk 0.2.1 → 0.3.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 (171) hide show
  1. package/README.md +152 -5
  2. package/dist/authoring/agent.d.ts +164 -0
  3. package/dist/authoring/agent.d.ts.map +1 -0
  4. package/dist/authoring/agent.js +376 -0
  5. package/dist/authoring/agent.js.map +1 -0
  6. package/dist/authoring/compiler.d.ts +98 -0
  7. package/dist/authoring/compiler.d.ts.map +1 -0
  8. package/dist/authoring/compiler.js +156 -0
  9. package/dist/authoring/compiler.js.map +1 -0
  10. package/dist/authoring/define-data-workflow.d.ts +24 -0
  11. package/dist/authoring/define-data-workflow.d.ts.map +1 -0
  12. package/dist/authoring/define-data-workflow.js +93 -0
  13. package/dist/authoring/define-data-workflow.js.map +1 -0
  14. package/dist/authoring/index.d.ts +19 -0
  15. package/dist/authoring/index.d.ts.map +1 -0
  16. package/dist/authoring/index.js +15 -0
  17. package/dist/authoring/index.js.map +1 -0
  18. package/dist/authoring/toolbox.d.ts +133 -0
  19. package/dist/authoring/toolbox.d.ts.map +1 -0
  20. package/dist/authoring/toolbox.js +166 -0
  21. package/dist/authoring/toolbox.js.map +1 -0
  22. package/dist/authoring/triggers.d.ts +41 -0
  23. package/dist/authoring/triggers.d.ts.map +1 -0
  24. package/dist/authoring/triggers.js +60 -0
  25. package/dist/authoring/triggers.js.map +1 -0
  26. package/dist/authoring/types.d.ts +64 -0
  27. package/dist/authoring/types.d.ts.map +1 -0
  28. package/dist/authoring/types.js +9 -0
  29. package/dist/authoring/types.js.map +1 -0
  30. package/dist/cli/commands/activity-cmd.d.ts +28 -0
  31. package/dist/cli/commands/activity-cmd.d.ts.map +1 -0
  32. package/dist/cli/commands/activity-cmd.js +78 -0
  33. package/dist/cli/commands/activity-cmd.js.map +1 -0
  34. package/dist/cli/commands/attach-cmd.d.ts +38 -0
  35. package/dist/cli/commands/attach-cmd.d.ts.map +1 -0
  36. package/dist/cli/commands/attach-cmd.js +141 -0
  37. package/dist/cli/commands/attach-cmd.js.map +1 -0
  38. package/dist/cli/commands/deploy-cmd.d.ts +101 -0
  39. package/dist/cli/commands/deploy-cmd.d.ts.map +1 -0
  40. package/dist/cli/commands/deploy-cmd.js +461 -0
  41. package/dist/cli/commands/deploy-cmd.js.map +1 -0
  42. package/dist/cli/commands/generate-cmd.d.ts +35 -0
  43. package/dist/cli/commands/generate-cmd.d.ts.map +1 -0
  44. package/dist/cli/commands/generate-cmd.js +134 -0
  45. package/dist/cli/commands/generate-cmd.js.map +1 -0
  46. package/dist/cli/commands/improvements-cmd.d.ts +44 -0
  47. package/dist/cli/commands/improvements-cmd.d.ts.map +1 -0
  48. package/dist/cli/commands/improvements-cmd.js +215 -0
  49. package/dist/cli/commands/improvements-cmd.js.map +1 -0
  50. package/dist/cli/commands/init-cmd.d.ts +78 -0
  51. package/dist/cli/commands/init-cmd.d.ts.map +1 -0
  52. package/dist/cli/commands/init-cmd.js +250 -0
  53. package/dist/cli/commands/init-cmd.js.map +1 -0
  54. package/dist/cli/commands/login.d.ts +4 -4
  55. package/dist/cli/commands/login.js +4 -4
  56. package/dist/cli/commands/login.js.map +1 -1
  57. package/dist/cli/commands/test-cmd.d.ts +89 -0
  58. package/dist/cli/commands/test-cmd.d.ts.map +1 -0
  59. package/dist/cli/commands/test-cmd.js +378 -0
  60. package/dist/cli/commands/test-cmd.js.map +1 -0
  61. package/dist/cli/index.d.ts +1 -1
  62. package/dist/cli/index.js +150 -8
  63. package/dist/cli/index.js.map +1 -1
  64. package/dist/cli/project-context.d.ts +153 -0
  65. package/dist/cli/project-context.d.ts.map +1 -0
  66. package/dist/cli/project-context.js +190 -0
  67. package/dist/cli/project-context.js.map +1 -0
  68. package/dist/client/activity-types.d.ts +66 -0
  69. package/dist/client/activity-types.d.ts.map +1 -0
  70. package/dist/client/activity-types.js +9 -0
  71. package/dist/client/activity-types.js.map +1 -0
  72. package/dist/client/activity.d.ts +22 -0
  73. package/dist/client/activity.d.ts.map +1 -0
  74. package/dist/client/activity.js +43 -0
  75. package/dist/client/activity.js.map +1 -0
  76. package/dist/client/data-products.d.ts.map +1 -1
  77. package/dist/client/data-products.js +4 -98
  78. package/dist/client/data-products.js.map +1 -1
  79. package/dist/client/flow-types.d.ts +4 -2
  80. package/dist/client/flow-types.d.ts.map +1 -1
  81. package/dist/client/flows.d.ts +1 -1
  82. package/dist/client/flows.d.ts.map +1 -1
  83. package/dist/client/flows.js +49 -124
  84. package/dist/client/flows.js.map +1 -1
  85. package/dist/client/improvements-types.d.ts +55 -0
  86. package/dist/client/improvements-types.d.ts.map +1 -0
  87. package/dist/client/improvements-types.js +9 -0
  88. package/dist/client/improvements-types.js.map +1 -0
  89. package/dist/client/improvements.d.ts +29 -0
  90. package/dist/client/improvements.d.ts.map +1 -0
  91. package/dist/client/improvements.js +50 -0
  92. package/dist/client/improvements.js.map +1 -0
  93. package/dist/client/index.d.ts +6 -2
  94. package/dist/client/index.d.ts.map +1 -1
  95. package/dist/client/index.js.map +1 -1
  96. package/dist/client/loxtep-client.d.ts +45 -0
  97. package/dist/client/loxtep-client.d.ts.map +1 -1
  98. package/dist/client/loxtep-client.js +68 -0
  99. package/dist/client/loxtep-client.js.map +1 -1
  100. package/dist/client/projects-types.d.ts +25 -0
  101. package/dist/client/projects-types.d.ts.map +1 -1
  102. package/dist/client/projects.d.ts +2 -1
  103. package/dist/client/projects.d.ts.map +1 -1
  104. package/dist/client/projects.js +17 -0
  105. package/dist/client/projects.js.map +1 -1
  106. package/dist/client/queue-types.d.ts +15 -2
  107. package/dist/client/queue-types.d.ts.map +1 -1
  108. package/dist/client/queues.d.ts.map +1 -1
  109. package/dist/client/queues.js +3 -14
  110. package/dist/client/queues.js.map +1 -1
  111. package/dist/codegen/emit.d.ts +25 -0
  112. package/dist/codegen/emit.d.ts.map +1 -0
  113. package/dist/codegen/emit.js +158 -0
  114. package/dist/codegen/emit.js.map +1 -0
  115. package/dist/codegen/index.d.ts +17 -0
  116. package/dist/codegen/index.d.ts.map +1 -0
  117. package/dist/codegen/index.js +16 -0
  118. package/dist/codegen/index.js.map +1 -0
  119. package/dist/codegen/load-workspace-context.d.ts +30 -0
  120. package/dist/codegen/load-workspace-context.d.ts.map +1 -0
  121. package/dist/codegen/load-workspace-context.js +127 -0
  122. package/dist/codegen/load-workspace-context.js.map +1 -0
  123. package/dist/codegen/normalize.d.ts +35 -0
  124. package/dist/codegen/normalize.d.ts.map +1 -0
  125. package/dist/codegen/normalize.js +77 -0
  126. package/dist/codegen/normalize.js.map +1 -0
  127. package/dist/codegen/types.d.ts +89 -0
  128. package/dist/codegen/types.d.ts.map +1 -0
  129. package/dist/codegen/types.js +9 -0
  130. package/dist/codegen/types.js.map +1 -0
  131. package/dist/codegen/write-artifact.d.ts +40 -0
  132. package/dist/codegen/write-artifact.d.ts.map +1 -0
  133. package/dist/codegen/write-artifact.js +74 -0
  134. package/dist/codegen/write-artifact.js.map +1 -0
  135. package/dist/config/index.d.ts +1 -0
  136. package/dist/config/index.d.ts.map +1 -1
  137. package/dist/config/index.js +1 -0
  138. package/dist/config/index.js.map +1 -1
  139. package/dist/config/workspace-config.d.ts +76 -0
  140. package/dist/config/workspace-config.d.ts.map +1 -0
  141. package/dist/config/workspace-config.js +129 -0
  142. package/dist/config/workspace-config.js.map +1 -0
  143. package/dist/index.d.ts +3 -0
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +3 -0
  146. package/dist/index.js.map +1 -1
  147. package/dist/rstreams/event-bridge.d.ts +16 -2
  148. package/dist/rstreams/event-bridge.d.ts.map +1 -1
  149. package/dist/rstreams/event-bridge.js +38 -5
  150. package/dist/rstreams/event-bridge.js.map +1 -1
  151. package/dist/skills/check-scope.d.ts +42 -0
  152. package/dist/skills/check-scope.d.ts.map +1 -0
  153. package/dist/skills/check-scope.js +84 -0
  154. package/dist/skills/check-scope.js.map +1 -0
  155. package/dist/skills/index.d.ts +14 -0
  156. package/dist/skills/index.d.ts.map +1 -0
  157. package/dist/skills/index.js +12 -0
  158. package/dist/skills/index.js.map +1 -0
  159. package/dist/skills/loader.d.ts +79 -0
  160. package/dist/skills/loader.d.ts.map +1 -0
  161. package/dist/skills/loader.js +102 -0
  162. package/dist/skills/loader.js.map +1 -0
  163. package/dist/skills/types.d.ts +55 -0
  164. package/dist/skills/types.d.ts.map +1 -0
  165. package/dist/skills/types.js +9 -0
  166. package/dist/skills/types.js.map +1 -0
  167. package/dist/skills/validate-references.d.ts +54 -0
  168. package/dist/skills/validate-references.d.ts.map +1 -0
  169. package/dist/skills/validate-references.js +80 -0
  170. package/dist/skills/validate-references.js.map +1 -0
  171. package/package.json +5 -3
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Pure fail-closed scope decision function.
3
+ *
4
+ * `checkScope` determines whether a given operation on a resource is permitted
5
+ * by a skill definition. The function is deny-by-default: if any check fails
6
+ * or cannot complete, the operation is blocked.
7
+ *
8
+ * Decision logic (in order):
9
+ * 1. If the skill definition is undefined → UNKNOWN_SKILL
10
+ * 2. If the resource type has no scope entries, or the resource id is not
11
+ * in the scope list → SCOPE_VIOLATION
12
+ * 3. If the resource type has no permissions, or the operation is not in
13
+ * the permissions list → OPERATION_DENIED
14
+ * 4. Otherwise → allowed
15
+ *
16
+ * Any unexpected error during validation → SCOPE_VALIDATION_FAILED (fail-closed)
17
+ */
18
+ import type { SkillDefinition, SkillScope, Operation, ScopeDecision } from './types.js';
19
+ /**
20
+ * Check whether a specific operation on a resource is permitted by a skill.
21
+ *
22
+ * @param skill - The skill definition to check against, or undefined if not found
23
+ * @param resourceType - The type of resource being accessed (e.g. 'data_products')
24
+ * @param resourceId - The specific resource identifier being accessed
25
+ * @param operation - The operation being attempted (read, write, create, delete)
26
+ * @returns A ScopeDecision indicating whether the operation is allowed or denied
27
+ */
28
+ export declare function checkScope(skill: SkillDefinition | undefined, resourceType: keyof SkillScope, resourceId: string, operation: Operation): ScopeDecision;
29
+ /**
30
+ * Resolve a skill by name from a map and check scope in one step.
31
+ * Convenience wrapper used by both the SDK client-side enforcement and
32
+ * the MCP server-side checker.
33
+ *
34
+ * @param skills - Map of skill name → SkillDefinition
35
+ * @param skillName - The name of the skill to look up
36
+ * @param resourceType - The type of resource being accessed
37
+ * @param resourceId - The specific resource identifier
38
+ * @param operation - The operation being attempted
39
+ * @returns A ScopeDecision
40
+ */
41
+ export declare function checkScopeByName(skills: Map<string, SkillDefinition>, skillName: string, resourceType: keyof SkillScope, resourceId: string, operation: Operation): ScopeDecision;
42
+ //# sourceMappingURL=check-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-scope.d.ts","sourceRoot":"","sources":["../../src/skills/check-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAExF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,YAAY,EAAE,MAAM,UAAU,EAC9B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,GACnB,aAAa,CAkCf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,UAAU,EAC9B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,GACnB,aAAa,CAUf"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Pure fail-closed scope decision function.
3
+ *
4
+ * `checkScope` determines whether a given operation on a resource is permitted
5
+ * by a skill definition. The function is deny-by-default: if any check fails
6
+ * or cannot complete, the operation is blocked.
7
+ *
8
+ * Decision logic (in order):
9
+ * 1. If the skill definition is undefined → UNKNOWN_SKILL
10
+ * 2. If the resource type has no scope entries, or the resource id is not
11
+ * in the scope list → SCOPE_VIOLATION
12
+ * 3. If the resource type has no permissions, or the operation is not in
13
+ * the permissions list → OPERATION_DENIED
14
+ * 4. Otherwise → allowed
15
+ *
16
+ * Any unexpected error during validation → SCOPE_VALIDATION_FAILED (fail-closed)
17
+ */
18
+ /**
19
+ * Check whether a specific operation on a resource is permitted by a skill.
20
+ *
21
+ * @param skill - The skill definition to check against, or undefined if not found
22
+ * @param resourceType - The type of resource being accessed (e.g. 'data_products')
23
+ * @param resourceId - The specific resource identifier being accessed
24
+ * @param operation - The operation being attempted (read, write, create, delete)
25
+ * @returns A ScopeDecision indicating whether the operation is allowed or denied
26
+ */
27
+ export function checkScope(skill, resourceType, resourceId, operation) {
28
+ try {
29
+ // 1. Unknown skill — no definition provided
30
+ if (skill === undefined) {
31
+ return { allowed: false, code: 'UNKNOWN_SKILL', skillName: '' };
32
+ }
33
+ // 2. Scope check — is the resource within the skill's declared scope?
34
+ const scopeList = skill.scope[resourceType];
35
+ if (!scopeList || !scopeList.includes(resourceId)) {
36
+ return {
37
+ allowed: false,
38
+ code: 'SCOPE_VIOLATION',
39
+ deniedResource: `${resourceType}/${resourceId}`,
40
+ };
41
+ }
42
+ // 3. Permission check — is the operation allowed for this resource type?
43
+ const permittedOps = skill.permissions[resourceType];
44
+ if (!permittedOps || !permittedOps.includes(operation)) {
45
+ return {
46
+ allowed: false,
47
+ code: 'OPERATION_DENIED',
48
+ deniedOperation: operation,
49
+ resource: `${resourceType}/${resourceId}`,
50
+ };
51
+ }
52
+ // 4. All checks pass
53
+ return { allowed: true };
54
+ }
55
+ catch {
56
+ // Fail-closed: any unexpected error blocks the operation
57
+ return { allowed: false, code: 'SCOPE_VALIDATION_FAILED' };
58
+ }
59
+ }
60
+ /**
61
+ * Resolve a skill by name from a map and check scope in one step.
62
+ * Convenience wrapper used by both the SDK client-side enforcement and
63
+ * the MCP server-side checker.
64
+ *
65
+ * @param skills - Map of skill name → SkillDefinition
66
+ * @param skillName - The name of the skill to look up
67
+ * @param resourceType - The type of resource being accessed
68
+ * @param resourceId - The specific resource identifier
69
+ * @param operation - The operation being attempted
70
+ * @returns A ScopeDecision
71
+ */
72
+ export function checkScopeByName(skills, skillName, resourceType, resourceId, operation) {
73
+ try {
74
+ const skill = skills.get(skillName);
75
+ if (!skill) {
76
+ return { allowed: false, code: 'UNKNOWN_SKILL', skillName };
77
+ }
78
+ return checkScope(skill, resourceType, resourceId, operation);
79
+ }
80
+ catch {
81
+ return { allowed: false, code: 'SCOPE_VALIDATION_FAILED' };
82
+ }
83
+ }
84
+ //# sourceMappingURL=check-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-scope.js","sourceRoot":"","sources":["../../src/skills/check-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CACxB,KAAkC,EAClC,YAA8B,EAC9B,UAAkB,EAClB,SAAoB;IAEpB,IAAI,CAAC;QACH,4CAA4C;QAC5C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAClE,CAAC;QAED,sEAAsE;QACtE,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAClD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,iBAAiB;gBACvB,cAAc,EAAE,GAAG,YAAY,IAAI,UAAU,EAAE;aAChD,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,kBAAkB;gBACxB,eAAe,EAAE,SAAS;gBAC1B,QAAQ,EAAE,GAAG,YAAY,IAAI,UAAU,EAAE;aAC1C,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;QACzD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAoC,EACpC,SAAiB,EACjB,YAA8B,EAC9B,UAAkB,EAClB,SAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;QAC9D,CAAC;QACD,OAAO,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IAC7D,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Skill scoping model — YAML loader and fail-closed scope decision.
3
+ *
4
+ * A skill is a scoped integration bundle declaring which platform resources
5
+ * and operations an AI agent may reach. The platform enforces scope fail-closed:
6
+ * out-of-scope → SCOPE_VIOLATION, disallowed op → OPERATION_DENIED, unknown
7
+ * skill → rejected, check failure → blocks the operation.
8
+ */
9
+ export type { SkillScope, Operation, SkillDefinition, ScopeDecision, } from './types.js';
10
+ export { checkScope, checkScopeByName } from './check-scope.js';
11
+ export { parseSkillYaml, loadSkillFromFile, loadSkillsFromDirectory, SkillDefinitionSchema, } from './loader.js';
12
+ export type { SkillReferenceError, SkillValidationResult } from './validate-references.js';
13
+ export { validateSkillReferences, formatSkillValidationErrors, } from './validate-references.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EACV,UAAU,EACV,SAAS,EACT,eAAe,EACf,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EACL,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Skill scoping model — YAML loader and fail-closed scope decision.
3
+ *
4
+ * A skill is a scoped integration bundle declaring which platform resources
5
+ * and operations an AI agent may reach. The platform enforces scope fail-closed:
6
+ * out-of-scope → SCOPE_VIOLATION, disallowed op → OPERATION_DENIED, unknown
7
+ * skill → rejected, check failure → blocks the operation.
8
+ */
9
+ export { checkScope, checkScopeByName } from './check-scope.js';
10
+ export { parseSkillYaml, loadSkillFromFile, loadSkillsFromDirectory, SkillDefinitionSchema, } from './loader.js';
11
+ export { validateSkillReferences, formatSkillValidationErrors, } from './validate-references.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Skill YAML schema validation and loader.
3
+ *
4
+ * Parses `.loxtep/skills/<name>.yaml` files into validated `SkillDefinition`
5
+ * objects using zod for schema enforcement. Invalid YAML or schema violations
6
+ * produce descriptive errors.
7
+ */
8
+ import { z } from 'zod/v4';
9
+ import type { SkillDefinition } from './types.js';
10
+ declare const SkillDefinitionSchema: z.ZodObject<{
11
+ name: z.ZodString;
12
+ description: z.ZodOptional<z.ZodString>;
13
+ scope: z.ZodObject<{
14
+ data_products: z.ZodOptional<z.ZodArray<z.ZodString>>;
15
+ connectors: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
+ workflows: z.ZodOptional<z.ZodArray<z.ZodString>>;
17
+ domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
18
+ queues: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
+ }, z.core.$strip>;
20
+ permissions: z.ZodObject<{
21
+ data_products: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<{
22
+ write: "write";
23
+ read: "read";
24
+ create: "create";
25
+ delete: "delete";
26
+ }>>>>;
27
+ connectors: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<{
28
+ write: "write";
29
+ read: "read";
30
+ create: "create";
31
+ delete: "delete";
32
+ }>>>>;
33
+ workflows: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<{
34
+ write: "write";
35
+ read: "read";
36
+ create: "create";
37
+ delete: "delete";
38
+ }>>>>;
39
+ domains: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<{
40
+ write: "write";
41
+ read: "read";
42
+ create: "create";
43
+ delete: "delete";
44
+ }>>>>;
45
+ queues: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<{
46
+ write: "write";
47
+ read: "read";
48
+ create: "create";
49
+ delete: "delete";
50
+ }>>>>;
51
+ }, z.core.$strip>;
52
+ }, z.core.$strip>;
53
+ export { SkillDefinitionSchema };
54
+ /**
55
+ * Parse a YAML string into a validated SkillDefinition.
56
+ *
57
+ * @param content - Raw YAML content
58
+ * @param filename - Source filename (for error messages)
59
+ * @returns Validated SkillDefinition
60
+ * @throws Error with descriptive message on invalid YAML or schema violations
61
+ */
62
+ export declare function parseSkillYaml(content: string, filename?: string): SkillDefinition;
63
+ /**
64
+ * Load a single skill definition from a YAML file path.
65
+ *
66
+ * @param filePath - Absolute or relative path to the `.yaml` file
67
+ * @returns Validated SkillDefinition
68
+ * @throws Error if file cannot be read or fails validation
69
+ */
70
+ export declare function loadSkillFromFile(filePath: string): SkillDefinition;
71
+ /**
72
+ * Load all skill definitions from a `.loxtep/skills/` directory.
73
+ *
74
+ * @param skillsDir - Path to the skills directory (e.g. `.loxtep/skills/`)
75
+ * @returns Map of skill name → SkillDefinition
76
+ * @throws Error if any file fails to parse or validate
77
+ */
78
+ export declare function loadSkillsFromDirectory(skillsDir: string): Map<string, SkillDefinition>;
79
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/skills/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgBlD,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAWzB,CAAC;AAEH,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAqBlF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAGnE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAwBvF"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Skill YAML schema validation and loader.
3
+ *
4
+ * Parses `.loxtep/skills/<name>.yaml` files into validated `SkillDefinition`
5
+ * objects using zod for schema enforcement. Invalid YAML or schema violations
6
+ * produce descriptive errors.
7
+ */
8
+ import { z } from 'zod/v4';
9
+ import * as yaml from 'js-yaml';
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ /**
13
+ * Zod schema for a skill definition YAML file.
14
+ * Validates the structure and constraints of skill scope and permissions.
15
+ */
16
+ const OperationSchema = z.enum(['read', 'write', 'create', 'delete']);
17
+ const SkillScopeSchema = z.object({
18
+ data_products: z.array(z.string()).optional(),
19
+ connectors: z.array(z.string()).optional(),
20
+ workflows: z.array(z.string()).optional(),
21
+ domains: z.array(z.string()).optional(),
22
+ queues: z.array(z.string()).optional(),
23
+ });
24
+ const SkillDefinitionSchema = z.object({
25
+ name: z.string().min(1),
26
+ description: z.string().optional(),
27
+ scope: SkillScopeSchema,
28
+ permissions: z.object({
29
+ data_products: z.array(OperationSchema).optional(),
30
+ connectors: z.array(OperationSchema).optional(),
31
+ workflows: z.array(OperationSchema).optional(),
32
+ domains: z.array(OperationSchema).optional(),
33
+ queues: z.array(OperationSchema).optional(),
34
+ }).partial(),
35
+ });
36
+ export { SkillDefinitionSchema };
37
+ /**
38
+ * Parse a YAML string into a validated SkillDefinition.
39
+ *
40
+ * @param content - Raw YAML content
41
+ * @param filename - Source filename (for error messages)
42
+ * @returns Validated SkillDefinition
43
+ * @throws Error with descriptive message on invalid YAML or schema violations
44
+ */
45
+ export function parseSkillYaml(content, filename) {
46
+ let parsed;
47
+ try {
48
+ parsed = yaml.load(content);
49
+ }
50
+ catch (err) {
51
+ const prefix = filename ? `${filename}: ` : '';
52
+ throw new Error(`${prefix}Invalid YAML: ${err instanceof Error ? err.message : String(err)}`);
53
+ }
54
+ const result = SkillDefinitionSchema.safeParse(parsed);
55
+ if (!result.success) {
56
+ const prefix = filename ? `${filename}: ` : '';
57
+ const issues = result.error.issues
58
+ .map((i) => ` - ${i.path.join('.')}: ${i.message}`)
59
+ .join('\n');
60
+ throw new Error(`${prefix}Skill schema validation failed:\n${issues}`);
61
+ }
62
+ return result.data;
63
+ }
64
+ /**
65
+ * Load a single skill definition from a YAML file path.
66
+ *
67
+ * @param filePath - Absolute or relative path to the `.yaml` file
68
+ * @returns Validated SkillDefinition
69
+ * @throws Error if file cannot be read or fails validation
70
+ */
71
+ export function loadSkillFromFile(filePath) {
72
+ const content = fs.readFileSync(filePath, 'utf-8');
73
+ return parseSkillYaml(content, path.basename(filePath));
74
+ }
75
+ /**
76
+ * Load all skill definitions from a `.loxtep/skills/` directory.
77
+ *
78
+ * @param skillsDir - Path to the skills directory (e.g. `.loxtep/skills/`)
79
+ * @returns Map of skill name → SkillDefinition
80
+ * @throws Error if any file fails to parse or validate
81
+ */
82
+ export function loadSkillsFromDirectory(skillsDir) {
83
+ const skills = new Map();
84
+ if (!fs.existsSync(skillsDir)) {
85
+ return skills;
86
+ }
87
+ const entries = fs.readdirSync(skillsDir);
88
+ for (const entry of entries) {
89
+ if (!entry.endsWith('.yaml') && !entry.endsWith('.yml')) {
90
+ continue;
91
+ }
92
+ const filePath = path.join(skillsDir, entry);
93
+ const stat = fs.statSync(filePath);
94
+ if (!stat.isFile()) {
95
+ continue;
96
+ }
97
+ const skill = loadSkillFromFile(filePath);
98
+ skills.set(skill.name, skill);
99
+ }
100
+ return skills;
101
+ }
102
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/skills/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Skill types for the scoped access model.
3
+ *
4
+ * A skill defines which platform resources and operations an AI agent may
5
+ * reach within a workspace. The scope is fail-closed: any check that cannot
6
+ * complete blocks the operation.
7
+ */
8
+ /**
9
+ * The set of resource types a skill can scope access to.
10
+ * Each key maps to a list of permitted resource identifiers (IDs or names).
11
+ */
12
+ export interface SkillScope {
13
+ data_products?: string[];
14
+ connectors?: string[];
15
+ workflows?: string[];
16
+ domains?: string[];
17
+ queues?: string[];
18
+ }
19
+ /**
20
+ * The set of operations that can be permitted on a resource type.
21
+ */
22
+ export type Operation = 'read' | 'write' | 'create' | 'delete';
23
+ /**
24
+ * A parsed skill definition from `.loxtep/skills/<name>.yaml`.
25
+ */
26
+ export interface SkillDefinition {
27
+ name: string;
28
+ description?: string;
29
+ scope: SkillScope;
30
+ permissions: Partial<Record<keyof SkillScope, Operation[]>>;
31
+ }
32
+ /**
33
+ * The result of a scope check decision.
34
+ * Only `{ allowed: true }` permits execution. All other variants deny.
35
+ */
36
+ export type ScopeDecision = {
37
+ allowed: true;
38
+ } | {
39
+ allowed: false;
40
+ code: 'SCOPE_VIOLATION';
41
+ deniedResource: string;
42
+ } | {
43
+ allowed: false;
44
+ code: 'OPERATION_DENIED';
45
+ deniedOperation: Operation;
46
+ resource: string;
47
+ } | {
48
+ allowed: false;
49
+ code: 'UNKNOWN_SKILL';
50
+ skillName: string;
51
+ } | {
52
+ allowed: false;
53
+ code: 'SCOPE_VALIDATION_FAILED';
54
+ };
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;CAC7D;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,eAAe,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1F;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,yBAAyB,CAAA;CAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Skill types for the scoped access model.
3
+ *
4
+ * A skill defines which platform resources and operations an AI agent may
5
+ * reach within a workspace. The scope is fail-closed: any check that cannot
6
+ * complete blocks the operation.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Generate-time skill validation against the Workspace_Context.
3
+ *
4
+ * During `loxtep generate`, every skill definition file at `.loxtep/skills/*.yaml`
5
+ * is validated against the loaded Workspace_Context. If a skill references a
6
+ * resource that does not exist in the context, `generate` exits non-zero with
7
+ * the skill name and each missing resource identifier.
8
+ *
9
+ * Requirements: 5.8, 5.9
10
+ */
11
+ import type { SkillDefinition, SkillScope } from './types.js';
12
+ import type { WorkspaceContext } from '../codegen/types.js';
13
+ /**
14
+ * A single invalid resource reference found during validation.
15
+ */
16
+ export interface SkillReferenceError {
17
+ /** Name of the skill that contains the invalid reference */
18
+ skillName: string;
19
+ /** Resource type (e.g. 'data_products', 'connectors') */
20
+ resourceType: keyof SkillScope;
21
+ /** The identifier that does not exist in the Workspace_Context */
22
+ missingIdentifier: string;
23
+ }
24
+ /**
25
+ * Result of validating skill references against the workspace context.
26
+ */
27
+ export type SkillValidationResult = {
28
+ valid: true;
29
+ } | {
30
+ valid: false;
31
+ errors: SkillReferenceError[];
32
+ };
33
+ /**
34
+ * Validate all skill resource references against the loaded Workspace_Context.
35
+ *
36
+ * For each skill, every identifier listed in the skill's `scope` is checked
37
+ * against the corresponding resource collection in the context. Resource
38
+ * identifiers in skill scope files are matched by `name` against the workspace
39
+ * context collections.
40
+ *
41
+ * @param skills - Map of skill name → SkillDefinition (loaded from `.loxtep/skills/`)
42
+ * @param context - The Workspace_Context loaded from the platform
43
+ * @returns Validation result: either `{ valid: true }` or `{ valid: false, errors: [...] }`
44
+ */
45
+ export declare function validateSkillReferences(skills: Map<string, SkillDefinition>, context: WorkspaceContext): SkillValidationResult;
46
+ /**
47
+ * Format skill validation errors into human-readable error messages.
48
+ * Each message identifies the skill name, resource type, and missing identifier.
49
+ *
50
+ * @param errors - Array of SkillReferenceError from validation
51
+ * @returns Formatted error messages, one per line
52
+ */
53
+ export declare function formatSkillValidationErrors(errors: SkillReferenceError[]): string;
54
+ //# sourceMappingURL=validate-references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../../src/skills/validate-references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,YAAY,EAAE,MAAM,UAAU,CAAC;IAC/B,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GACf;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,EAAE,CAAA;CAAE,CAAC;AA2BpD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,OAAO,EAAE,gBAAgB,GACxB,qBAAqB,CA+BvB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAMjF"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Generate-time skill validation against the Workspace_Context.
3
+ *
4
+ * During `loxtep generate`, every skill definition file at `.loxtep/skills/*.yaml`
5
+ * is validated against the loaded Workspace_Context. If a skill references a
6
+ * resource that does not exist in the context, `generate` exits non-zero with
7
+ * the skill name and each missing resource identifier.
8
+ *
9
+ * Requirements: 5.8, 5.9
10
+ */
11
+ /**
12
+ * Mapping from skill scope resource type keys to the corresponding
13
+ * WorkspaceContext collection keys.
14
+ */
15
+ const RESOURCE_TYPE_TO_CONTEXT_KEY = {
16
+ data_products: 'dataProducts',
17
+ connectors: 'connectors',
18
+ workflows: 'workflows',
19
+ domains: 'domains',
20
+ queues: 'queues',
21
+ };
22
+ /**
23
+ * Extract the set of resource names available in the workspace context
24
+ * for a given resource type.
25
+ */
26
+ function getAvailableNames(context, resourceType) {
27
+ const contextKey = RESOURCE_TYPE_TO_CONTEXT_KEY[resourceType];
28
+ const collection = context[contextKey];
29
+ return new Set(collection.map((r) => r.name));
30
+ }
31
+ /**
32
+ * Validate all skill resource references against the loaded Workspace_Context.
33
+ *
34
+ * For each skill, every identifier listed in the skill's `scope` is checked
35
+ * against the corresponding resource collection in the context. Resource
36
+ * identifiers in skill scope files are matched by `name` against the workspace
37
+ * context collections.
38
+ *
39
+ * @param skills - Map of skill name → SkillDefinition (loaded from `.loxtep/skills/`)
40
+ * @param context - The Workspace_Context loaded from the platform
41
+ * @returns Validation result: either `{ valid: true }` or `{ valid: false, errors: [...] }`
42
+ */
43
+ export function validateSkillReferences(skills, context) {
44
+ const errors = [];
45
+ for (const [, skill] of skills) {
46
+ const resourceTypes = Object.keys(skill.scope);
47
+ for (const resourceType of resourceTypes) {
48
+ const identifiers = skill.scope[resourceType];
49
+ if (!identifiers || identifiers.length === 0) {
50
+ continue;
51
+ }
52
+ const availableNames = getAvailableNames(context, resourceType);
53
+ for (const identifier of identifiers) {
54
+ if (!availableNames.has(identifier)) {
55
+ errors.push({
56
+ skillName: skill.name,
57
+ resourceType,
58
+ missingIdentifier: identifier,
59
+ });
60
+ }
61
+ }
62
+ }
63
+ }
64
+ if (errors.length === 0) {
65
+ return { valid: true };
66
+ }
67
+ return { valid: false, errors };
68
+ }
69
+ /**
70
+ * Format skill validation errors into human-readable error messages.
71
+ * Each message identifies the skill name, resource type, and missing identifier.
72
+ *
73
+ * @param errors - Array of SkillReferenceError from validation
74
+ * @returns Formatted error messages, one per line
75
+ */
76
+ export function formatSkillValidationErrors(errors) {
77
+ const lines = errors.map((e) => `Skill "${e.skillName}": references ${e.resourceType} "${e.missingIdentifier}" which does not exist in the workspace context`);
78
+ return lines.join('\n');
79
+ }
80
+ //# sourceMappingURL=validate-references.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-references.js","sourceRoot":"","sources":["../../src/skills/validate-references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwBH;;;GAGG;AACH,MAAM,4BAA4B,GAAqD;IACrF,aAAa,EAAE,cAAc;IAC7B,UAAU,EAAE,YAAY;IACxB,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF;;;GAGG;AACH,SAAS,iBAAiB,CACxB,OAAyB,EACzB,YAA8B;IAE9B,MAAM,UAAU,GAAG,4BAA4B,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAuB,CAAC;IAC7D,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAoC,EACpC,OAAyB;IAEzB,MAAM,MAAM,GAA0B,EAAE,CAAC;IAEzC,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAyB,CAAC;QAEvE,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9C,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7C,SAAS;YACX,CAAC;YAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAEhE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBACpC,MAAM,CAAC,IAAI,CAAC;wBACV,SAAS,EAAE,KAAK,CAAC,IAAI;wBACrB,YAAY;wBACZ,iBAAiB,EAAE,UAAU;qBAC9B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAA6B;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CACtB,CAAC,CAAC,EAAE,EAAE,CACJ,UAAU,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,iBAAiB,iDAAiD,CAChI,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loxtep/sdk",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Loxtep SDK for Node.js - data products, flows, projects, queues",
5
5
  "author": "Loxtep <engineering@loxtep.io>",
6
6
  "homepage": "https://loxtep.io",
@@ -78,17 +78,19 @@
78
78
  "@smithy/protocol-http": "^5.4.3",
79
79
  "@smithy/signature-v4": "^5.4.3",
80
80
  "@smithy/types": "^4.14.2",
81
- "leo-sdk": "7.1.12"
81
+ "js-yaml": "4.1.0",
82
+ "leo-sdk": "7.1.12",
83
+ "zod": "^4.4.3"
82
84
  },
83
85
  "devDependencies": {
84
86
  "@types/jest": "^30.0.0",
87
+ "@types/js-yaml": "4.0.9",
85
88
  "fast-check": "^4.8.0",
86
89
  "jest": "^30.4.2",
87
90
  "ts-jest": "^29.4.9",
88
91
  "tsx": "^4.22.0",
89
92
  "typedoc": "^0.28.19",
90
93
  "typescript": "^6.0.3",
91
- "zod": "^4.4.3",
92
94
  "zod-to-ts": "^2.0.0"
93
95
  }
94
96
  }