@jini-ai/agentic 0.3.7 → 0.4.1

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 (142) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/README.md +33 -6
  3. package/dist/core/a2ui/agent-to-renderer.d.ts +3 -1
  4. package/dist/core/a2ui/agent-to-renderer.js +1 -1
  5. package/dist/core/a2ui/catalog.d.ts +14 -5
  6. package/dist/core/a2ui/catalog.js +5 -5
  7. package/dist/core/a2ui/common-types.d.ts +11 -3
  8. package/dist/core/a2ui/common-types.js +5 -3
  9. package/dist/core/a2ui/index.d.ts +1 -1
  10. package/dist/core/a2ui/index.js +1 -1
  11. package/dist/core/a2ui/interpreter.d.ts +45 -10
  12. package/dist/core/a2ui/interpreter.js +38 -43
  13. package/dist/core/a2ui/json-pointer.d.ts +16 -4
  14. package/dist/core/a2ui/json-pointer.js +7 -7
  15. package/dist/core/a2ui/renderer-to-agent.d.ts +22 -8
  16. package/dist/core/a2ui/renderer-to-agent.js +5 -5
  17. package/dist/core/a2ui/resolve.d.ts +7 -2
  18. package/dist/core/a2ui/resolve.js +10 -9
  19. package/dist/core/a2ui/tree.d.ts +8 -2
  20. package/dist/core/a2ui/tree.js +2 -2
  21. package/dist/core/ag-ui.d.ts +17 -9
  22. package/dist/core/ag-ui.js +4 -4
  23. package/dist/core/annotated-actions-script.d.ts +13 -0
  24. package/dist/core/annotated-actions-script.js +137 -0
  25. package/dist/core/capability.d.ts +12 -3
  26. package/dist/core/capability.js +3 -3
  27. package/dist/core/dom/dom-page-driver.d.ts +8 -4
  28. package/dist/core/dom/dom-page-driver.js +19 -20
  29. package/dist/core/dom/index.d.ts +3 -3
  30. package/dist/core/dom/index.js +1 -1
  31. package/dist/core/dom/model-context.d.ts +18 -8
  32. package/dist/core/dom/model-context.js +12 -15
  33. package/dist/core/dom/native-model-context.d.ts +6 -0
  34. package/dist/core/dom/native-model-context.js +19 -0
  35. package/dist/core/element-handles.d.ts +6 -2
  36. package/dist/core/element-handles.js +3 -3
  37. package/dist/core/gen-ui/encoder.d.ts +21 -11
  38. package/dist/core/gen-ui/encoder.js +8 -7
  39. package/dist/core/gen-ui/events.d.ts +6 -5
  40. package/dist/core/gen-ui/events.js +6 -5
  41. package/dist/core/gen-ui/index.d.ts +1 -1
  42. package/dist/core/gen-ui/index.js +1 -1
  43. package/dist/core/guards.d.ts +17 -5
  44. package/dist/core/guards.js +6 -6
  45. package/dist/core/handle.d.ts +12 -5
  46. package/dist/core/handle.js +9 -8
  47. package/dist/core/index.d.ts +3 -1
  48. package/dist/core/index.js +3 -1
  49. package/dist/core/list-handles.d.ts +4 -1
  50. package/dist/core/list-handles.js +1 -1
  51. package/dist/core/mcp-ui-apps.d.ts +39 -9
  52. package/dist/core/mcp-ui-apps.js +10 -8
  53. package/dist/core/messages.d.ts +6 -0
  54. package/dist/core/messages.js +6 -0
  55. package/dist/core/page-capabilities.d.ts +0 -11
  56. package/dist/core/page-capabilities.js +13 -1
  57. package/dist/core/page-driver.d.ts +32 -11
  58. package/dist/core/page-executor.d.ts +8 -2
  59. package/dist/core/page-executor.js +31 -31
  60. package/dist/core/webmcp.d.ts +27 -8
  61. package/dist/core/webmcp.js +14 -14
  62. package/dist/index.d.ts +30 -0
  63. package/dist/index.js +30 -0
  64. package/dist/skills/install/archive.d.ts +8 -0
  65. package/dist/skills/install/archive.js +47 -0
  66. package/dist/skills/install/fetch-adapter.d.ts +6 -0
  67. package/dist/skills/install/fetch-adapter.js +6 -0
  68. package/dist/skills/install/github.d.ts +21 -0
  69. package/dist/skills/install/github.js +92 -0
  70. package/dist/skills/install/index.d.ts +11 -0
  71. package/dist/skills/install/index.js +11 -0
  72. package/dist/skills/install/install-service.d.ts +44 -0
  73. package/dist/skills/install/install-service.js +121 -0
  74. package/dist/skills/install/layout.d.ts +13 -0
  75. package/dist/skills/install/layout.js +22 -0
  76. package/dist/skills/install/live-registration.d.ts +61 -0
  77. package/dist/skills/install/live-registration.js +64 -0
  78. package/dist/skills/install/node-filesystem.d.ts +4 -0
  79. package/dist/skills/install/node-filesystem.js +41 -0
  80. package/dist/skills/install/ports.d.ts +101 -0
  81. package/dist/skills/install/ports.js +2 -0
  82. package/dist/skills/install/state.d.ts +13 -0
  83. package/dist/skills/install/state.js +23 -0
  84. package/dist/skills/install/validation.d.ts +45 -0
  85. package/dist/skills/install/validation.js +104 -0
  86. package/package.json +20 -5
  87. package/dist/a2ui/agent-to-renderer.d.ts +0 -613
  88. package/dist/a2ui/agent-to-renderer.js +0 -191
  89. package/dist/a2ui/catalog.d.ts +0 -73
  90. package/dist/a2ui/catalog.js +0 -304
  91. package/dist/a2ui/common-types.d.ts +0 -401
  92. package/dist/a2ui/common-types.js +0 -130
  93. package/dist/a2ui/index.d.ts +0 -16
  94. package/dist/a2ui/index.js +0 -16
  95. package/dist/a2ui/interpreter.d.ts +0 -71
  96. package/dist/a2ui/interpreter.js +0 -337
  97. package/dist/a2ui/json-pointer.d.ts +0 -48
  98. package/dist/a2ui/json-pointer.js +0 -174
  99. package/dist/a2ui/renderer-to-agent.d.ts +0 -342
  100. package/dist/a2ui/renderer-to-agent.js +0 -111
  101. package/dist/a2ui/resolve.d.ts +0 -28
  102. package/dist/a2ui/resolve.js +0 -144
  103. package/dist/a2ui/tree.d.ts +0 -66
  104. package/dist/a2ui/tree.js +0 -74
  105. package/dist/ag-ui.d.ts +0 -82
  106. package/dist/ag-ui.js +0 -85
  107. package/dist/agui/encoder.d.ts +0 -50
  108. package/dist/agui/encoder.js +0 -97
  109. package/dist/agui/events.d.ts +0 -59
  110. package/dist/agui/events.js +0 -15
  111. package/dist/capability.d.ts +0 -81
  112. package/dist/capability.js +0 -79
  113. package/dist/dom/dom-page-driver.d.ts +0 -36
  114. package/dist/dom/dom-page-driver.js +0 -601
  115. package/dist/dom/index.d.ts +0 -17
  116. package/dist/dom/index.js +0 -17
  117. package/dist/dom/model-context.d.ts +0 -69
  118. package/dist/dom/model-context.js +0 -44
  119. package/dist/element-handles.d.ts +0 -120
  120. package/dist/element-handles.js +0 -39
  121. package/dist/gen-ui/encoder.d.ts +0 -50
  122. package/dist/gen-ui/encoder.js +0 -97
  123. package/dist/gen-ui/events.d.ts +0 -59
  124. package/dist/gen-ui/events.js +0 -15
  125. package/dist/gen-ui/index.d.ts +0 -18
  126. package/dist/gen-ui/index.js +0 -17
  127. package/dist/guards.d.ts +0 -96
  128. package/dist/guards.js +0 -186
  129. package/dist/handle.d.ts +0 -41
  130. package/dist/handle.js +0 -41
  131. package/dist/mcp-ui-apps.d.ts +0 -223
  132. package/dist/mcp-ui-apps.js +0 -252
  133. package/dist/mcp-ui.d.ts +0 -133
  134. package/dist/mcp-ui.js +0 -134
  135. package/dist/page-capabilities.d.ts +0 -14
  136. package/dist/page-capabilities.js +0 -129
  137. package/dist/page-driver.d.ts +0 -120
  138. package/dist/page-driver.js +0 -2
  139. package/dist/page-executor.d.ts +0 -94
  140. package/dist/page-executor.js +0 -320
  141. package/dist/webmcp.d.ts +0 -202
  142. package/dist/webmcp.js +0 -173
@@ -0,0 +1,45 @@
1
+ import type { YamlReaderPort } from "./ports.js";
2
+ export type SkillYamlPort = YamlReaderPort;
3
+ export declare class SkillInputError extends Error {
4
+ constructor({ message }: {
5
+ message: string;
6
+ }, optional?: {
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ export interface SkillUploadFile {
11
+ readonly path: string;
12
+ readonly contentBase64: string;
13
+ }
14
+ export declare const MAX_SKILL_BYTES: number;
15
+ export declare const MAX_SKILL_FILES = 256;
16
+ export declare const MAX_SKILL_FILE_BYTES: number;
17
+ /** Decodes bounded canonical base64; malformed encodings never silently turn into empty files. */
18
+ export declare function decodeSkillBase64({ value }: {
19
+ value: string;
20
+ }, { maxBytes }?: {
21
+ maxBytes?: number;
22
+ }): Buffer;
23
+ export declare function validateSkillPath({ filePath }: {
24
+ filePath: string;
25
+ }, _optional?: Record<string, never>): void;
26
+ /** Strict frontmatter for new installs; the legacy disk loader remains backwards compatible. */
27
+ export declare function validateSkillMarkdown({ markdown, yamlReader }: {
28
+ markdown: string;
29
+ yamlReader: YamlReaderPort;
30
+ }, _optional?: Record<string, never>): {
31
+ name: string;
32
+ description: string;
33
+ };
34
+ /** Validates the whole package before writes, including cross-file collisions and combined limits.
35
+ * @complexity O(total bytes + files × path length), bounded to 8 MiB / 256 files.
36
+ */
37
+ export declare function validateSkillFiles({ files: upload, yamlReader }: {
38
+ files: readonly SkillUploadFile[];
39
+ yamlReader: YamlReaderPort;
40
+ }, _optional?: Record<string, never>): {
41
+ files: Map<string, Buffer<ArrayBufferLike>>;
42
+ name: string;
43
+ description: string;
44
+ };
45
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1,104 @@
1
+ /** Bounded skill-bundle validation; scripts are stored as data and never executed. */
2
+ import path from "node:path";
3
+ export class SkillInputError extends Error {
4
+ constructor({ message }, optional = {}) {
5
+ super(message, optional);
6
+ }
7
+ }
8
+ export const MAX_SKILL_BYTES = 8 * 1024 * 1024;
9
+ export const MAX_SKILL_FILES = 256;
10
+ export const MAX_SKILL_FILE_BYTES = 1024 * 1024;
11
+ const TEXT_EXTENSIONS = new Set([".md", ".txt", ".json", ".yaml", ".yml", ".csv", ".svg", ".sh", ".py", ".js", ".ts", ".mjs"]);
12
+ const ASSET_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".webp"]);
13
+ /** Decodes bounded canonical base64; malformed encodings never silently turn into empty files. */
14
+ export function decodeSkillBase64({ value }, { maxBytes = MAX_SKILL_BYTES } = {}) {
15
+ if (typeof value !== "string" || value.length > Math.ceil(maxBytes / 3) * 4)
16
+ throw new SkillInputError({ message: "Skill upload exceeds its size limit." });
17
+ if (value.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value))
18
+ throw new SkillInputError({ message: "Skill upload must use valid base64." });
19
+ const bytes = Buffer.from(value, "base64");
20
+ if (bytes.length > maxBytes)
21
+ throw new SkillInputError({ message: "Skill upload exceeds its size limit." });
22
+ return bytes;
23
+ }
24
+ export function validateSkillPath({ filePath }, _optional = {}) {
25
+ if (typeof filePath !== "string" || filePath.length === 0 || filePath.length > 240 || /[\\\x00-\x1f\x7f:]/.test(filePath) || path.posix.isAbsolute(filePath) || filePath.split("/").some(p => !p || p === "." || p === ".." || p.startsWith(".")))
26
+ throw new SkillInputError({ message: `Unsafe skill file path: ${filePath}` });
27
+ }
28
+ /** Strict frontmatter for new installs; the legacy disk loader remains backwards compatible. */
29
+ export function validateSkillMarkdown({ markdown, yamlReader }, _optional = {}) {
30
+ const frontmatter = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
31
+ if (!frontmatter)
32
+ throw new SkillInputError({ message: "SKILL.md must have YAML frontmatter with a name and description." });
33
+ let fields;
34
+ try {
35
+ fields = yamlReader.read({ yaml: frontmatter[1] });
36
+ }
37
+ catch {
38
+ throw new SkillInputError({ message: "SKILL.md must have valid YAML frontmatter." });
39
+ }
40
+ const { name, description } = (fields && typeof fields === "object" ? fields : {});
41
+ if (typeof name !== "string" || typeof description !== "string" || !description.trim())
42
+ throw new SkillInputError({ message: "SKILL.md must have YAML frontmatter with a name and description." });
43
+ if (name.length > 64 || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name))
44
+ throw new SkillInputError({ message: "Skill name must use lowercase letters, digits and single hyphens (1–64 characters)." });
45
+ if (description.length > 1024)
46
+ throw new SkillInputError({ message: "Skill description exceeds 1024 characters." });
47
+ return { name, description: description.replace(/\s+/g, " ").trim() };
48
+ }
49
+ /** Validates the whole package before writes, including cross-file collisions and combined limits.
50
+ * @complexity O(total bytes + files × path length), bounded to 8 MiB / 256 files.
51
+ */
52
+ export function validateSkillFiles({ files: upload, yamlReader }, _optional = {}) {
53
+ if (!Array.isArray(upload) || upload.length === 0 || upload.length > MAX_SKILL_FILES)
54
+ throw new SkillInputError({ message: "A skill must contain 1–256 files." });
55
+ for (const file of upload)
56
+ validateSkillPath({ filePath: file.path });
57
+ const skillFiles = upload.filter(f => f.path === "SKILL.md" || f.path.endsWith("/SKILL.md"));
58
+ if (skillFiles.length !== 1) {
59
+ if (skillFiles.length > 1 && new Set(skillFiles.map(f => f.path)).size === 1)
60
+ throw new SkillInputError({ message: `Duplicate skill file path: ${skillFiles[0].path}` });
61
+ throw new SkillInputError({ message: "Choose one skill folder containing a single SKILL.md." });
62
+ }
63
+ const prefix = skillFiles[0].path.slice(0, -"SKILL.md".length);
64
+ const files = new Map();
65
+ let total = 0;
66
+ for (const file of upload) {
67
+ if (!file.path.startsWith(prefix))
68
+ throw new SkillInputError({ message: "All files must belong to the selected skill folder." });
69
+ const relative = file.path.slice(prefix.length);
70
+ validateSkillPath({ filePath: relative });
71
+ if (files.has(relative))
72
+ throw new SkillInputError({ message: `Duplicate skill file path: ${relative}` });
73
+ const extension = path.posix.extname(relative).toLowerCase();
74
+ const top = relative.split("/")[0];
75
+ if (relative !== "SKILL.md" && relative !== "README.md" && relative !== "LICENSE" && !["references", "scripts", "assets"].includes(top))
76
+ throw new SkillInputError({ message: `Unsupported skill file location: ${relative}` });
77
+ if (relative !== "LICENSE" && !TEXT_EXTENSIONS.has(extension) && !(top === "assets" && ASSET_EXTENSIONS.has(extension)))
78
+ throw new SkillInputError({ message: `Unsupported skill file type: ${relative}` });
79
+ const bytes = decodeSkillBase64({ value: file.contentBase64 }, { maxBytes: MAX_SKILL_FILE_BYTES });
80
+ if (relative === "SKILL.md" && bytes.length > 128 * 1024)
81
+ throw new SkillInputError({ message: "SKILL.md exceeds 128 KiB." });
82
+ total += bytes.length;
83
+ if (total > MAX_SKILL_BYTES)
84
+ throw new SkillInputError({ message: "Skill files exceed 8 MiB combined." });
85
+ if (TEXT_EXTENSIONS.has(extension) || relative === "LICENSE") {
86
+ try {
87
+ new TextDecoder("utf-8", { fatal: true }).decode(bytes);
88
+ }
89
+ catch {
90
+ throw new SkillInputError({ message: `Skill text file must be valid UTF-8 without null bytes: ${relative}` });
91
+ }
92
+ if (bytes.includes(0))
93
+ throw new SkillInputError({ message: `Skill text file must be valid UTF-8 without null bytes: ${relative}` });
94
+ }
95
+ else {
96
+ const valid = extension === ".png" ? bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])) : extension === ".webp" ? bytes.toString("ascii", 0, 4) === "RIFF" && bytes.toString("ascii", 8, 12) === "WEBP" : bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255;
97
+ if (!valid)
98
+ throw new SkillInputError({ message: `Skill asset content does not match its file type: ${relative}` });
99
+ }
100
+ files.set(relative, bytes);
101
+ }
102
+ return { ...validateSkillMarkdown({ markdown: files.get("SKILL.md").toString("utf8"), yamlReader }), files };
103
+ }
104
+ //# sourceMappingURL=validation.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/agentic",
3
- "version": "0.3.7",
3
+ "version": "0.4.1",
4
4
  "description": "Framework-free agent-control layer: page-capability vocabulary and manifests, the data-agent-* markup convention, AG-UI projection, generative-UI streams, and A2UI.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -16,7 +16,9 @@
16
16
  ".": "universal",
17
17
  "./core": "universal",
18
18
  "./dom": "browser",
19
- "./a2ui": "universal"
19
+ "./a2ui": "universal",
20
+ "./skills/install": "node",
21
+ "./skills/install/node": "node"
20
22
  }
21
23
  },
22
24
  "type": "module",
@@ -43,16 +45,28 @@
43
45
  "types": "./dist/core/a2ui/index.d.ts",
44
46
  "import": "./dist/core/a2ui/index.js",
45
47
  "default": "./dist/core/a2ui/index.js"
48
+ },
49
+ "./skills/install": {
50
+ "types": "./dist/skills/install/index.d.ts",
51
+ "import": "./dist/skills/install/index.js",
52
+ "default": "./dist/skills/install/index.js"
53
+ },
54
+ "./skills/install/node": {
55
+ "types": "./dist/skills/install/node-filesystem.d.ts",
56
+ "import": "./dist/skills/install/node-filesystem.js",
57
+ "default": "./dist/skills/install/node-filesystem.js"
46
58
  }
47
59
  },
48
60
  "files": [
49
61
  "dist",
62
+ "README.md",
63
+ "CHANGELOG.md",
64
+ "LICENSE",
50
65
  "!dist/**/*.test.js",
51
66
  "!dist/**/*.test.d.ts",
52
67
  "!dist/**/*.test.js.map",
53
68
  "!dist/**/*.test.d.ts.map",
54
- "!dist/**/__tests__/**",
55
- "!dist/**/*.map"
69
+ "!dist/**/__tests__/**"
56
70
  ],
57
71
  "publishConfig": {
58
72
  "access": "public",
@@ -60,7 +74,8 @@
60
74
  },
61
75
  "dependencies": {
62
76
  "zod": "^3.25.76",
63
- "@jini-ai/protocol": "0.3.0"
77
+ "@jini-ai/core": "^0.4.0",
78
+ "@jini-ai/protocol": "^0.4.0"
64
79
  },
65
80
  "devDependencies": {
66
81
  "@vitest/coverage-v8": "^2.1.9",