@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.
- package/README.md +152 -5
- package/dist/authoring/agent.d.ts +164 -0
- package/dist/authoring/agent.d.ts.map +1 -0
- package/dist/authoring/agent.js +376 -0
- package/dist/authoring/agent.js.map +1 -0
- package/dist/authoring/compiler.d.ts +98 -0
- package/dist/authoring/compiler.d.ts.map +1 -0
- package/dist/authoring/compiler.js +156 -0
- package/dist/authoring/compiler.js.map +1 -0
- package/dist/authoring/define-data-workflow.d.ts +24 -0
- package/dist/authoring/define-data-workflow.d.ts.map +1 -0
- package/dist/authoring/define-data-workflow.js +93 -0
- package/dist/authoring/define-data-workflow.js.map +1 -0
- package/dist/authoring/index.d.ts +19 -0
- package/dist/authoring/index.d.ts.map +1 -0
- package/dist/authoring/index.js +15 -0
- package/dist/authoring/index.js.map +1 -0
- package/dist/authoring/toolbox.d.ts +133 -0
- package/dist/authoring/toolbox.d.ts.map +1 -0
- package/dist/authoring/toolbox.js +166 -0
- package/dist/authoring/toolbox.js.map +1 -0
- package/dist/authoring/triggers.d.ts +41 -0
- package/dist/authoring/triggers.d.ts.map +1 -0
- package/dist/authoring/triggers.js +60 -0
- package/dist/authoring/triggers.js.map +1 -0
- package/dist/authoring/types.d.ts +64 -0
- package/dist/authoring/types.d.ts.map +1 -0
- package/dist/authoring/types.js +9 -0
- package/dist/authoring/types.js.map +1 -0
- package/dist/cli/commands/activity-cmd.d.ts +28 -0
- package/dist/cli/commands/activity-cmd.d.ts.map +1 -0
- package/dist/cli/commands/activity-cmd.js +78 -0
- package/dist/cli/commands/activity-cmd.js.map +1 -0
- package/dist/cli/commands/attach-cmd.d.ts +38 -0
- package/dist/cli/commands/attach-cmd.d.ts.map +1 -0
- package/dist/cli/commands/attach-cmd.js +141 -0
- package/dist/cli/commands/attach-cmd.js.map +1 -0
- package/dist/cli/commands/deploy-cmd.d.ts +101 -0
- package/dist/cli/commands/deploy-cmd.d.ts.map +1 -0
- package/dist/cli/commands/deploy-cmd.js +461 -0
- package/dist/cli/commands/deploy-cmd.js.map +1 -0
- package/dist/cli/commands/generate-cmd.d.ts +35 -0
- package/dist/cli/commands/generate-cmd.d.ts.map +1 -0
- package/dist/cli/commands/generate-cmd.js +134 -0
- package/dist/cli/commands/generate-cmd.js.map +1 -0
- package/dist/cli/commands/improvements-cmd.d.ts +44 -0
- package/dist/cli/commands/improvements-cmd.d.ts.map +1 -0
- package/dist/cli/commands/improvements-cmd.js +215 -0
- package/dist/cli/commands/improvements-cmd.js.map +1 -0
- package/dist/cli/commands/init-cmd.d.ts +78 -0
- package/dist/cli/commands/init-cmd.d.ts.map +1 -0
- package/dist/cli/commands/init-cmd.js +250 -0
- package/dist/cli/commands/init-cmd.js.map +1 -0
- package/dist/cli/commands/login.d.ts +4 -4
- package/dist/cli/commands/login.js +4 -4
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/test-cmd.d.ts +89 -0
- package/dist/cli/commands/test-cmd.d.ts.map +1 -0
- package/dist/cli/commands/test-cmd.js +378 -0
- package/dist/cli/commands/test-cmd.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +150 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/project-context.d.ts +153 -0
- package/dist/cli/project-context.d.ts.map +1 -0
- package/dist/cli/project-context.js +190 -0
- package/dist/cli/project-context.js.map +1 -0
- package/dist/client/activity-types.d.ts +66 -0
- package/dist/client/activity-types.d.ts.map +1 -0
- package/dist/client/activity-types.js +9 -0
- package/dist/client/activity-types.js.map +1 -0
- package/dist/client/activity.d.ts +22 -0
- package/dist/client/activity.d.ts.map +1 -0
- package/dist/client/activity.js +43 -0
- package/dist/client/activity.js.map +1 -0
- package/dist/client/data-products.d.ts.map +1 -1
- package/dist/client/data-products.js +4 -98
- package/dist/client/data-products.js.map +1 -1
- package/dist/client/flow-types.d.ts +4 -2
- package/dist/client/flow-types.d.ts.map +1 -1
- package/dist/client/flows.d.ts +1 -1
- package/dist/client/flows.d.ts.map +1 -1
- package/dist/client/flows.js +49 -124
- package/dist/client/flows.js.map +1 -1
- package/dist/client/improvements-types.d.ts +55 -0
- package/dist/client/improvements-types.d.ts.map +1 -0
- package/dist/client/improvements-types.js +9 -0
- package/dist/client/improvements-types.js.map +1 -0
- package/dist/client/improvements.d.ts +29 -0
- package/dist/client/improvements.d.ts.map +1 -0
- package/dist/client/improvements.js +50 -0
- package/dist/client/improvements.js.map +1 -0
- package/dist/client/index.d.ts +6 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/loxtep-client.d.ts +45 -0
- package/dist/client/loxtep-client.d.ts.map +1 -1
- package/dist/client/loxtep-client.js +68 -0
- package/dist/client/loxtep-client.js.map +1 -1
- package/dist/client/projects-types.d.ts +25 -0
- package/dist/client/projects-types.d.ts.map +1 -1
- package/dist/client/projects.d.ts +2 -1
- package/dist/client/projects.d.ts.map +1 -1
- package/dist/client/projects.js +17 -0
- package/dist/client/projects.js.map +1 -1
- package/dist/client/queue-types.d.ts +15 -2
- package/dist/client/queue-types.d.ts.map +1 -1
- package/dist/client/queues.d.ts.map +1 -1
- package/dist/client/queues.js +3 -14
- package/dist/client/queues.js.map +1 -1
- package/dist/codegen/emit.d.ts +25 -0
- package/dist/codegen/emit.d.ts.map +1 -0
- package/dist/codegen/emit.js +158 -0
- package/dist/codegen/emit.js.map +1 -0
- package/dist/codegen/index.d.ts +17 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +16 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/load-workspace-context.d.ts +30 -0
- package/dist/codegen/load-workspace-context.d.ts.map +1 -0
- package/dist/codegen/load-workspace-context.js +127 -0
- package/dist/codegen/load-workspace-context.js.map +1 -0
- package/dist/codegen/normalize.d.ts +35 -0
- package/dist/codegen/normalize.d.ts.map +1 -0
- package/dist/codegen/normalize.js +77 -0
- package/dist/codegen/normalize.js.map +1 -0
- package/dist/codegen/types.d.ts +89 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +9 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/codegen/write-artifact.d.ts +40 -0
- package/dist/codegen/write-artifact.d.ts.map +1 -0
- package/dist/codegen/write-artifact.js +74 -0
- package/dist/codegen/write-artifact.js.map +1 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/workspace-config.d.ts +76 -0
- package/dist/config/workspace-config.d.ts.map +1 -0
- package/dist/config/workspace-config.js +129 -0
- package/dist/config/workspace-config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/rstreams/event-bridge.d.ts +16 -2
- package/dist/rstreams/event-bridge.d.ts.map +1 -1
- package/dist/rstreams/event-bridge.js +38 -5
- package/dist/rstreams/event-bridge.js.map +1 -1
- package/dist/skills/check-scope.d.ts +42 -0
- package/dist/skills/check-scope.d.ts.map +1 -0
- package/dist/skills/check-scope.js +84 -0
- package/dist/skills/check-scope.js.map +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +12 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +79 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +102 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/types.d.ts +55 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +9 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/skills/validate-references.d.ts +54 -0
- package/dist/skills/validate-references.d.ts.map +1 -0
- package/dist/skills/validate-references.js +80 -0
- package/dist/skills/validate-references.js.map +1 -0
- 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.
|
|
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
|
-
"
|
|
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
|
}
|