@crewx/sdk 0.8.0-rc.58

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 (303) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1022 -0
  3. package/dist/adapters/MastraToolAdapter.d.ts +9 -0
  4. package/dist/adapters/MastraToolAdapter.js +66 -0
  5. package/dist/adapters/MastraToolAdapter.js.map +1 -0
  6. package/dist/api/index.d.ts +2 -0
  7. package/dist/api/index.js +8 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/boxing/box-storage.interface.d.ts +13 -0
  10. package/dist/boxing/box-storage.interface.js +3 -0
  11. package/dist/boxing/box-storage.interface.js.map +1 -0
  12. package/dist/boxing/box.service.d.ts +15 -0
  13. package/dist/boxing/box.service.js +70 -0
  14. package/dist/boxing/box.service.js.map +1 -0
  15. package/dist/boxing/box.types.d.ts +86 -0
  16. package/dist/boxing/box.types.js +3 -0
  17. package/dist/boxing/box.types.js.map +1 -0
  18. package/dist/boxing/context-builder.d.ts +8 -0
  19. package/dist/boxing/context-builder.js +76 -0
  20. package/dist/boxing/context-builder.js.map +1 -0
  21. package/dist/boxing/index.d.ts +6 -0
  22. package/dist/boxing/index.js +11 -0
  23. package/dist/boxing/index.js.map +1 -0
  24. package/dist/boxing/tokenizer.d.ts +3 -0
  25. package/dist/boxing/tokenizer.js +11 -0
  26. package/dist/boxing/tokenizer.js.map +1 -0
  27. package/dist/config/api-provider-parser.d.ts +58 -0
  28. package/dist/config/api-provider-parser.js +212 -0
  29. package/dist/config/api-provider-parser.js.map +1 -0
  30. package/dist/config/index.d.ts +3 -0
  31. package/dist/config/index.js +20 -0
  32. package/dist/config/index.js.map +1 -0
  33. package/dist/config/log.config.d.ts +7 -0
  34. package/dist/config/log.config.js +20 -0
  35. package/dist/config/log.config.js.map +1 -0
  36. package/dist/config/pricing.d.ts +10 -0
  37. package/dist/config/pricing.js +44 -0
  38. package/dist/config/pricing.js.map +1 -0
  39. package/dist/config/timeout.config.d.ts +14 -0
  40. package/dist/config/timeout.config.js +34 -0
  41. package/dist/config/timeout.config.js.map +1 -0
  42. package/dist/config/yaml-loader.d.ts +8 -0
  43. package/dist/config/yaml-loader.js +155 -0
  44. package/dist/config/yaml-loader.js.map +1 -0
  45. package/dist/constants/index.d.ts +4 -0
  46. package/dist/constants/index.js +8 -0
  47. package/dist/constants/index.js.map +1 -0
  48. package/dist/constants.d.ts +1 -0
  49. package/dist/constants.js +18 -0
  50. package/dist/constants.js.map +1 -0
  51. package/dist/conversation/conversation-config.d.ts +9 -0
  52. package/dist/conversation/conversation-config.js +22 -0
  53. package/dist/conversation/conversation-config.js.map +1 -0
  54. package/dist/conversation/conversation-history.interface.d.ts +36 -0
  55. package/dist/conversation/conversation-history.interface.js +3 -0
  56. package/dist/conversation/conversation-history.interface.js.map +1 -0
  57. package/dist/conversation/conversation-storage.service.d.ts +16 -0
  58. package/dist/conversation/conversation-storage.service.js +213 -0
  59. package/dist/conversation/conversation-storage.service.js.map +1 -0
  60. package/dist/conversation/index.d.ts +3 -0
  61. package/dist/conversation/index.js +20 -0
  62. package/dist/conversation/index.js.map +1 -0
  63. package/dist/core/agent/agent-factory.d.ts +37 -0
  64. package/dist/core/agent/agent-factory.js +68 -0
  65. package/dist/core/agent/agent-factory.js.map +1 -0
  66. package/dist/core/agent/agent-runtime.d.ts +52 -0
  67. package/dist/core/agent/agent-runtime.js +206 -0
  68. package/dist/core/agent/agent-runtime.js.map +1 -0
  69. package/dist/core/agent/event-bus.d.ts +44 -0
  70. package/dist/core/agent/event-bus.js +43 -0
  71. package/dist/core/agent/event-bus.js.map +1 -0
  72. package/dist/core/agent/index.d.ts +3 -0
  73. package/dist/core/agent/index.js +13 -0
  74. package/dist/core/agent/index.js.map +1 -0
  75. package/dist/core/env-defaults.d.ts +1 -0
  76. package/dist/core/env-defaults.js +7 -0
  77. package/dist/core/env-defaults.js.map +1 -0
  78. package/dist/core/parallel/helpers.d.ts +27 -0
  79. package/dist/core/parallel/helpers.js +252 -0
  80. package/dist/core/parallel/helpers.js.map +1 -0
  81. package/dist/core/parallel/index.d.ts +4 -0
  82. package/dist/core/parallel/index.js +11 -0
  83. package/dist/core/parallel/index.js.map +1 -0
  84. package/dist/core/parallel/parallel-runner.d.ts +16 -0
  85. package/dist/core/parallel/parallel-runner.js +230 -0
  86. package/dist/core/parallel/parallel-runner.js.map +1 -0
  87. package/dist/core/parallel/types.d.ts +41 -0
  88. package/dist/core/parallel/types.js +3 -0
  89. package/dist/core/parallel/types.js.map +1 -0
  90. package/dist/core/providers/MastraAPIProvider.d.ts +31 -0
  91. package/dist/core/providers/MastraAPIProvider.js +365 -0
  92. package/dist/core/providers/MastraAPIProvider.js.map +1 -0
  93. package/dist/core/providers/ai-provider.interface.d.ts +78 -0
  94. package/dist/core/providers/ai-provider.interface.js +23 -0
  95. package/dist/core/providers/ai-provider.interface.js.map +1 -0
  96. package/dist/core/providers/base-ai.provider.d.ts +80 -0
  97. package/dist/core/providers/base-ai.provider.js +1183 -0
  98. package/dist/core/providers/base-ai.provider.js.map +1 -0
  99. package/dist/core/providers/base-ai.types.d.ts +26 -0
  100. package/dist/core/providers/base-ai.types.js +3 -0
  101. package/dist/core/providers/base-ai.types.js.map +1 -0
  102. package/dist/core/providers/claude.provider.d.ts +19 -0
  103. package/dist/core/providers/claude.provider.js +170 -0
  104. package/dist/core/providers/claude.provider.js.map +1 -0
  105. package/dist/core/providers/codex.provider.d.ts +21 -0
  106. package/dist/core/providers/codex.provider.js +134 -0
  107. package/dist/core/providers/codex.provider.js.map +1 -0
  108. package/dist/core/providers/copilot.provider.d.ts +24 -0
  109. package/dist/core/providers/copilot.provider.js +146 -0
  110. package/dist/core/providers/copilot.provider.js.map +1 -0
  111. package/dist/core/providers/dynamic-provider.factory.d.ts +74 -0
  112. package/dist/core/providers/dynamic-provider.factory.js +643 -0
  113. package/dist/core/providers/dynamic-provider.factory.js.map +1 -0
  114. package/dist/core/providers/gemini.provider.d.ts +16 -0
  115. package/dist/core/providers/gemini.provider.js +101 -0
  116. package/dist/core/providers/gemini.provider.js.map +1 -0
  117. package/dist/core/providers/index.d.ts +8 -0
  118. package/dist/core/providers/index.js +20 -0
  119. package/dist/core/providers/index.js.map +1 -0
  120. package/dist/core/providers/mock.provider.d.ts +13 -0
  121. package/dist/core/providers/mock.provider.js +55 -0
  122. package/dist/core/providers/mock.provider.js.map +1 -0
  123. package/dist/core/providers/provider-factory.d.ts +3 -0
  124. package/dist/core/providers/provider-factory.js +65 -0
  125. package/dist/core/providers/provider-factory.js.map +1 -0
  126. package/dist/core/providers/tool-call.types.d.ts +39 -0
  127. package/dist/core/providers/tool-call.types.js +3 -0
  128. package/dist/core/providers/tool-call.types.js.map +1 -0
  129. package/dist/core/remote/index.d.ts +3 -0
  130. package/dist/core/remote/index.js +20 -0
  131. package/dist/core/remote/index.js.map +1 -0
  132. package/dist/core/remote/remote-agent-manager.d.ts +24 -0
  133. package/dist/core/remote/remote-agent-manager.js +195 -0
  134. package/dist/core/remote/remote-agent-manager.js.map +1 -0
  135. package/dist/core/remote/remote-transport.d.ts +15 -0
  136. package/dist/core/remote/remote-transport.js +70 -0
  137. package/dist/core/remote/remote-transport.js.map +1 -0
  138. package/dist/core/remote/types.d.ts +79 -0
  139. package/dist/core/remote/types.js +3 -0
  140. package/dist/core/remote/types.js.map +1 -0
  141. package/dist/index.d.ts +56 -0
  142. package/dist/index.js +133 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/internal/index.d.ts +1 -0
  145. package/dist/internal/index.js +6 -0
  146. package/dist/internal/index.js.map +1 -0
  147. package/dist/knowledge/DocumentManager.d.ts +4 -0
  148. package/dist/knowledge/DocumentManager.js +119 -0
  149. package/dist/knowledge/DocumentManager.js.map +1 -0
  150. package/dist/knowledge/index.d.ts +1 -0
  151. package/dist/knowledge/index.js +18 -0
  152. package/dist/knowledge/index.js.map +1 -0
  153. package/dist/parsers/agent-call.util.d.ts +3 -0
  154. package/dist/parsers/agent-call.util.js +17 -0
  155. package/dist/parsers/agent-call.util.js.map +1 -0
  156. package/dist/parsers/claude.parser.d.ts +2 -0
  157. package/dist/parsers/claude.parser.js +46 -0
  158. package/dist/parsers/claude.parser.js.map +1 -0
  159. package/dist/parsers/codex.parser.d.ts +2 -0
  160. package/dist/parsers/codex.parser.js +89 -0
  161. package/dist/parsers/codex.parser.js.map +1 -0
  162. package/dist/parsers/copilot.parser.d.ts +2 -0
  163. package/dist/parsers/copilot.parser.js +58 -0
  164. package/dist/parsers/copilot.parser.js.map +1 -0
  165. package/dist/parsers/gemini.parser.d.ts +2 -0
  166. package/dist/parsers/gemini.parser.js +36 -0
  167. package/dist/parsers/gemini.parser.js.map +1 -0
  168. package/dist/parsers/index.d.ts +7 -0
  169. package/dist/parsers/index.js +45 -0
  170. package/dist/parsers/index.js.map +1 -0
  171. package/dist/schema/skills-parser.d.ts +8 -0
  172. package/dist/schema/skills-parser.js +438 -0
  173. package/dist/schema/skills-parser.js.map +1 -0
  174. package/dist/schema/skills.types.d.ts +158 -0
  175. package/dist/schema/skills.types.js +41 -0
  176. package/dist/schema/skills.types.js.map +1 -0
  177. package/dist/schemas/api-provider.schema.d.ts +432 -0
  178. package/dist/schemas/api-provider.schema.js +50 -0
  179. package/dist/schemas/api-provider.schema.js.map +1 -0
  180. package/dist/services/index.d.ts +2 -0
  181. package/dist/services/index.js +19 -0
  182. package/dist/services/index.js.map +1 -0
  183. package/dist/services/layout-loader.service.d.ts +18 -0
  184. package/dist/services/layout-loader.service.js +271 -0
  185. package/dist/services/layout-loader.service.js.map +1 -0
  186. package/dist/services/layout-renderer.service.d.ts +34 -0
  187. package/dist/services/layout-renderer.service.js +325 -0
  188. package/dist/services/layout-renderer.service.js.map +1 -0
  189. package/dist/services/props-validator.service.d.ts +29 -0
  190. package/dist/services/props-validator.service.js +332 -0
  191. package/dist/services/props-validator.service.js.map +1 -0
  192. package/dist/skills/adapter/claude-skill-adapter.d.ts +11 -0
  193. package/dist/skills/adapter/claude-skill-adapter.js +222 -0
  194. package/dist/skills/adapter/claude-skill-adapter.js.map +1 -0
  195. package/dist/skills/index.d.ts +6 -0
  196. package/dist/skills/index.js +31 -0
  197. package/dist/skills/index.js.map +1 -0
  198. package/dist/skills/runtime/progressive-loader.d.ts +27 -0
  199. package/dist/skills/runtime/progressive-loader.js +186 -0
  200. package/dist/skills/runtime/progressive-loader.js.map +1 -0
  201. package/dist/skills/runtime/runtime-requirements-validator.d.ts +23 -0
  202. package/dist/skills/runtime/runtime-requirements-validator.js +248 -0
  203. package/dist/skills/runtime/runtime-requirements-validator.js.map +1 -0
  204. package/dist/skills/runtime/skill-runtime.service.d.ts +42 -0
  205. package/dist/skills/runtime/skill-runtime.service.js +434 -0
  206. package/dist/skills/runtime/skill-runtime.service.js.map +1 -0
  207. package/dist/tools/file-system.service.d.ts +10 -0
  208. package/dist/tools/file-system.service.js +33 -0
  209. package/dist/tools/file-system.service.js.map +1 -0
  210. package/dist/tools/find.tool.d.ts +85 -0
  211. package/dist/tools/find.tool.js +139 -0
  212. package/dist/tools/find.tool.js.map +1 -0
  213. package/dist/tools/glob.tool.d.ts +100 -0
  214. package/dist/tools/glob.tool.js +153 -0
  215. package/dist/tools/glob.tool.js.map +1 -0
  216. package/dist/tools/grep.tool.d.ts +30 -0
  217. package/dist/tools/grep.tool.js +137 -0
  218. package/dist/tools/grep.tool.js.map +1 -0
  219. package/dist/tools/index.d.ts +12 -0
  220. package/dist/tools/index.js +40 -0
  221. package/dist/tools/index.js.map +1 -0
  222. package/dist/tools/ls.tool.d.ts +24 -0
  223. package/dist/tools/ls.tool.js +94 -0
  224. package/dist/tools/ls.tool.js.map +1 -0
  225. package/dist/tools/read-file.tool.d.ts +30 -0
  226. package/dist/tools/read-file.tool.js +69 -0
  227. package/dist/tools/read-file.tool.js.map +1 -0
  228. package/dist/tools/replace.tool.d.ts +36 -0
  229. package/dist/tools/replace.tool.js +68 -0
  230. package/dist/tools/replace.tool.js.map +1 -0
  231. package/dist/tools/run-shell-command.tool.d.ts +24 -0
  232. package/dist/tools/run-shell-command.tool.js +64 -0
  233. package/dist/tools/run-shell-command.tool.js.map +1 -0
  234. package/dist/tools/tree.tool.d.ts +24 -0
  235. package/dist/tools/tree.tool.js +109 -0
  236. package/dist/tools/tree.tool.js.map +1 -0
  237. package/dist/tools/types.d.ts +42 -0
  238. package/dist/tools/types.js +13 -0
  239. package/dist/tools/types.js.map +1 -0
  240. package/dist/tools/utils/file-utils.d.ts +5 -0
  241. package/dist/tools/utils/file-utils.js +221 -0
  242. package/dist/tools/utils/file-utils.js.map +1 -0
  243. package/dist/tools/write-file.tool.d.ts +24 -0
  244. package/dist/tools/write-file.tool.js +55 -0
  245. package/dist/tools/write-file.tool.js.map +1 -0
  246. package/dist/types/agent.types.d.ts +134 -0
  247. package/dist/types/agent.types.js +16 -0
  248. package/dist/types/agent.types.js.map +1 -0
  249. package/dist/types/api-provider.types.d.ts +85 -0
  250. package/dist/types/api-provider.types.js +65 -0
  251. package/dist/types/api-provider.types.js.map +1 -0
  252. package/dist/types/index.d.ts +6 -0
  253. package/dist/types/index.js +23 -0
  254. package/dist/types/index.js.map +1 -0
  255. package/dist/types/layout.types.d.ts +115 -0
  256. package/dist/types/layout.types.js +22 -0
  257. package/dist/types/layout.types.js.map +1 -0
  258. package/dist/types/provider.types.d.ts +12 -0
  259. package/dist/types/provider.types.js +3 -0
  260. package/dist/types/provider.types.js.map +1 -0
  261. package/dist/types/skill-runtime.types.d.ts +244 -0
  262. package/dist/types/skill-runtime.types.js +44 -0
  263. package/dist/types/skill-runtime.types.js.map +1 -0
  264. package/dist/types/structured-payload.types.d.ts +46 -0
  265. package/dist/types/structured-payload.types.js +65 -0
  266. package/dist/types/structured-payload.types.js.map +1 -0
  267. package/dist/types/task-log.types.d.ts +14 -0
  268. package/dist/types/task-log.types.js +3 -0
  269. package/dist/types/task-log.types.js.map +1 -0
  270. package/dist/types/template.types.d.ts +38 -0
  271. package/dist/types/template.types.js +3 -0
  272. package/dist/types/template.types.js.map +1 -0
  273. package/dist/types.d.ts +1 -0
  274. package/dist/types.js +18 -0
  275. package/dist/types.js.map +1 -0
  276. package/dist/utils/api-provider-normalizer.d.ts +16 -0
  277. package/dist/utils/api-provider-normalizer.js +135 -0
  278. package/dist/utils/api-provider-normalizer.js.map +1 -0
  279. package/dist/utils/base-message-formatter.d.ts +32 -0
  280. package/dist/utils/base-message-formatter.js +170 -0
  281. package/dist/utils/base-message-formatter.js.map +1 -0
  282. package/dist/utils/error-utils.d.ts +3 -0
  283. package/dist/utils/error-utils.js +27 -0
  284. package/dist/utils/error-utils.js.map +1 -0
  285. package/dist/utils/index.d.ts +4 -0
  286. package/dist/utils/index.js +21 -0
  287. package/dist/utils/index.js.map +1 -0
  288. package/dist/utils/math-utils.d.ts +3 -0
  289. package/dist/utils/math-utils.js +10 -0
  290. package/dist/utils/math-utils.js.map +1 -0
  291. package/dist/utils/mention-parser.d.ts +18 -0
  292. package/dist/utils/mention-parser.js +136 -0
  293. package/dist/utils/mention-parser.js.map +1 -0
  294. package/dist/utils/string-utils.d.ts +1 -0
  295. package/dist/utils/string-utils.js +10 -0
  296. package/dist/utils/string-utils.js.map +1 -0
  297. package/dist/utils.d.ts +3 -0
  298. package/dist/utils.js +20 -0
  299. package/dist/utils.js.map +1 -0
  300. package/package.json +134 -0
  301. package/schema/api-provider-config.json +138 -0
  302. package/schema/crewx-config.json +224 -0
  303. package/schema/skills-config.json +306 -0
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.LayoutLoader = void 0;
37
+ const fs_1 = require("fs");
38
+ const path = __importStar(require("path"));
39
+ const js_yaml_1 = require("js-yaml");
40
+ const layout_types_1 = require("../types/layout.types");
41
+ const DEFAULT_OPTIONS = {
42
+ templatesPath: path.join(__dirname, '../../../templates/agents'),
43
+ validationMode: 'lenient',
44
+ fallbackLayoutId: 'crewx/default',
45
+ };
46
+ class LayoutLoader {
47
+ constructor(options) {
48
+ this.layouts = new Map();
49
+ this.options = { ...DEFAULT_OPTIONS, ...options };
50
+ this.loadAllLayouts();
51
+ }
52
+ load(layoutId, propsOverride) {
53
+ let layout = this.layouts.get(layoutId);
54
+ if (!layout) {
55
+ const normalizedId = this.normalizeLayoutId(layoutId);
56
+ layout = this.layouts.get(normalizedId);
57
+ }
58
+ if (!layout) {
59
+ console.warn(`Layout not found: ${layoutId}, falling back to ${this.options.fallbackLayoutId}`);
60
+ layout = this.layouts.get(this.options.fallbackLayoutId);
61
+ if (!layout) {
62
+ throw new layout_types_1.LayoutLoadError(`Fallback layout not found: ${this.options.fallbackLayoutId}`, this.options.fallbackLayoutId);
63
+ }
64
+ }
65
+ if (propsOverride && Object.keys(propsOverride).length > 0) {
66
+ return {
67
+ ...layout,
68
+ defaultProps: { ...layout.defaultProps, ...propsOverride },
69
+ };
70
+ }
71
+ return layout;
72
+ }
73
+ getLayoutIds() {
74
+ return Array.from(this.layouts.keys());
75
+ }
76
+ hasLayout(layoutId) {
77
+ if (this.layouts.has(layoutId)) {
78
+ return true;
79
+ }
80
+ const normalizedId = this.normalizeLayoutId(layoutId);
81
+ return this.layouts.has(normalizedId);
82
+ }
83
+ reload() {
84
+ this.layouts.clear();
85
+ this.loadAllLayouts();
86
+ }
87
+ loadAllLayouts() {
88
+ const layoutsDir = this.options.templatesPath;
89
+ if (!(0, fs_1.existsSync)(layoutsDir)) {
90
+ throw new layout_types_1.LayoutLoadError(`Templates directory not found: ${layoutsDir}`, undefined, new Error(`Directory does not exist: ${layoutsDir}`));
91
+ }
92
+ try {
93
+ const files = (0, fs_1.readdirSync)(layoutsDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
94
+ if (files.length === 0) {
95
+ console.warn(`No layout files found in ${layoutsDir}`);
96
+ }
97
+ for (const file of files) {
98
+ const layoutName = file.replace(/\.(yaml|yml)$/, '');
99
+ const layoutPath = path.join(layoutsDir, file);
100
+ try {
101
+ const layout = this.loadLayoutFile(layoutPath, layoutName);
102
+ const layoutId = `crewx/${layoutName}`;
103
+ this.layouts.set(layoutId, layout);
104
+ if (layoutId !== 'crewx/minimal') {
105
+ console.log(`Loaded layout: ${layoutId} from ${file}`);
106
+ }
107
+ }
108
+ catch (error) {
109
+ console.error(`Failed to load layout file ${file}:`, error);
110
+ }
111
+ }
112
+ console.log(`Loaded ${this.layouts.size} layouts from ${layoutsDir}`);
113
+ }
114
+ catch (error) {
115
+ throw new layout_types_1.LayoutLoadError(`Failed to read layouts directory: ${layoutsDir}`, undefined, error instanceof Error ? error : new Error(String(error)));
116
+ }
117
+ }
118
+ loadLayoutFile(filePath, layoutName) {
119
+ try {
120
+ const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
121
+ if (!content || content.trim().length === 0) {
122
+ console.warn(`Empty YAML file: ${filePath}, will use fallback`);
123
+ throw new layout_types_1.LayoutLoadError(`Empty YAML file: ${filePath}`, layoutName, new Error('File content is empty'));
124
+ }
125
+ const parsed = (0, js_yaml_1.load)(content);
126
+ if (!parsed || typeof parsed !== 'object') {
127
+ console.warn(`Invalid YAML content in ${filePath} (parsed as ${typeof parsed}), will use fallback`);
128
+ throw new layout_types_1.LayoutLoadError(`Invalid or empty YAML in ${filePath}`, layoutName, new Error('YAML parsing returned null/undefined or non-object'));
129
+ }
130
+ if (parsed.layouts && typeof parsed.layouts === 'object') {
131
+ const layoutTemplate = this.resolveLayoutTemplate(parsed.layouts, layoutName);
132
+ if (!layoutTemplate || (typeof layoutTemplate === 'string' && layoutTemplate.trim().length === 0)) {
133
+ console.warn(`Empty or missing layout template in ${filePath} for ${layoutName}`);
134
+ throw new layout_types_1.LayoutLoadError(`Layout template not found or empty in layouts map: ${layoutName}`, layoutName);
135
+ }
136
+ return {
137
+ id: `crewx/${layoutName}`,
138
+ version: parsed.version || '1.0.0',
139
+ description: parsed.description || `CrewX ${layoutName} layout`,
140
+ template: layoutTemplate,
141
+ propsSchema: this.parsePropsSchema(parsed.propsSchema || {}),
142
+ defaultProps: this.extractDefaultProps(parsed.propsSchema || {}),
143
+ };
144
+ }
145
+ else {
146
+ if (!parsed.template || (typeof parsed.template === 'string' && parsed.template.trim().length === 0)) {
147
+ console.warn(`Empty or missing template field in ${filePath}`);
148
+ throw new layout_types_1.LayoutLoadError(`Layout template is missing or empty in ${filePath}`, layoutName);
149
+ }
150
+ return {
151
+ id: parsed.id || `crewx/${layoutName}`,
152
+ version: parsed.version || '1.0.0',
153
+ description: parsed.description || '',
154
+ template: parsed.template,
155
+ propsSchema: this.parsePropsSchema(parsed.propsSchema || {}),
156
+ defaultProps: this.extractDefaultProps(parsed.propsSchema || {}),
157
+ };
158
+ }
159
+ }
160
+ catch (error) {
161
+ throw new layout_types_1.LayoutLoadError(`Failed to load layout file: ${filePath}`, layoutName, error instanceof Error ? error : new Error(String(error)));
162
+ }
163
+ }
164
+ parsePropsSchema(raw) {
165
+ const schema = {};
166
+ for (const [key, value] of Object.entries(raw)) {
167
+ if (typeof value === 'object' && value !== null) {
168
+ schema[key] = value;
169
+ }
170
+ }
171
+ return schema;
172
+ }
173
+ extractDefaultProps(propsSchema) {
174
+ const defaults = {};
175
+ for (const [key, schema] of Object.entries(propsSchema)) {
176
+ if (schema && typeof schema === 'object') {
177
+ if ('defaultValue' in schema) {
178
+ defaults[key] = schema.defaultValue;
179
+ }
180
+ else if ('default' in schema) {
181
+ defaults[key] = schema.default;
182
+ }
183
+ }
184
+ }
185
+ return defaults;
186
+ }
187
+ normalizeLayoutId(layoutId) {
188
+ if (!layoutId) {
189
+ return this.options.fallbackLayoutId;
190
+ }
191
+ if (layoutId.includes('/')) {
192
+ return layoutId;
193
+ }
194
+ return `crewx/${layoutId}`;
195
+ }
196
+ registerLayout(layoutId, layoutConfig) {
197
+ if (!layoutId || typeof layoutId !== 'string') {
198
+ throw new layout_types_1.LayoutLoadError('Layout ID must be a non-empty string', layoutId);
199
+ }
200
+ const config = typeof layoutConfig === 'string'
201
+ ? { template: layoutConfig }
202
+ : layoutConfig;
203
+ const template = typeof config.template === 'string' ? config.template : '';
204
+ if (!template || template.trim().length === 0) {
205
+ throw new layout_types_1.LayoutLoadError(`Custom layout template is empty for ${layoutId}`, layoutId);
206
+ }
207
+ const propsSchemaRaw = config.propsSchema || {};
208
+ const defaultPropsFromSchema = this.extractDefaultProps(propsSchemaRaw);
209
+ const explicitDefaults = config.defaultProps || {};
210
+ const layoutDefinition = {
211
+ id: layoutId,
212
+ version: config.version || '1.0.0',
213
+ description: config.description || `Custom layout ${layoutId}`,
214
+ template,
215
+ propsSchema: this.parsePropsSchema(propsSchemaRaw),
216
+ defaultProps: { ...defaultPropsFromSchema, ...explicitDefaults },
217
+ };
218
+ const existingLayout = this.layouts.get(layoutId);
219
+ const templatesEqual = existingLayout?.template === template &&
220
+ JSON.stringify(existingLayout?.defaultProps ?? {}) === JSON.stringify(layoutDefinition.defaultProps ?? {}) &&
221
+ JSON.stringify(existingLayout?.propsSchema ?? {}) === JSON.stringify(layoutDefinition.propsSchema ?? {});
222
+ this.layouts.set(layoutId, layoutDefinition);
223
+ if (!existingLayout) {
224
+ console.log(`Registered custom layout: ${layoutId}`);
225
+ }
226
+ else if (!templatesEqual) {
227
+ console.log(`Updated custom layout: ${layoutId}`);
228
+ }
229
+ }
230
+ registerLayouts(layoutsMap) {
231
+ for (const [id, config] of Object.entries(layoutsMap)) {
232
+ try {
233
+ this.registerLayout(id, config);
234
+ }
235
+ catch (error) {
236
+ console.warn(`Failed to register custom layout ${id}:`, error instanceof Error ? error.message : error);
237
+ }
238
+ }
239
+ }
240
+ resolveLayoutTemplate(layoutsMap, layoutName) {
241
+ const candidates = new Set();
242
+ if (layoutName) {
243
+ candidates.add(layoutName);
244
+ if (layoutName.includes('/')) {
245
+ const parts = layoutName.split('/');
246
+ const last = parts[parts.length - 1];
247
+ if (last) {
248
+ candidates.add(last);
249
+ }
250
+ }
251
+ else {
252
+ candidates.add(`crewx/${layoutName}`);
253
+ }
254
+ }
255
+ candidates.add('default');
256
+ for (const key of candidates) {
257
+ const value = layoutsMap[key];
258
+ if (typeof value === 'string' && value.trim().length > 0) {
259
+ return value;
260
+ }
261
+ }
262
+ for (const value of Object.values(layoutsMap)) {
263
+ if (typeof value === 'string' && value.trim().length > 0) {
264
+ return value;
265
+ }
266
+ }
267
+ return undefined;
268
+ }
269
+ }
270
+ exports.LayoutLoader = LayoutLoader;
271
+ //# sourceMappingURL=layout-loader.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-loader.service.js","sourceRoot":"","sources":["../../src/services/layout-loader.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { PropsValidator } from './props-validator.service';
2
+ import type { LayoutDefinition, RenderContext, PropSchema, ValidationResult } from '../types/layout.types';
3
+ export { PropsValidationError } from '../types/layout.types';
4
+ export type { LayoutDefinition, RenderContext, PropSchema, ValidationResult as PropsValidationResult, } from '../types/layout.types';
5
+ export interface RenderOptions {
6
+ validationMode?: 'strict' | 'lenient';
7
+ skipValidation?: boolean;
8
+ }
9
+ export interface ExecHelperConfig {
10
+ timeout?: number;
11
+ allow?: string[];
12
+ deny?: string[];
13
+ }
14
+ export interface TemplateConfig {
15
+ exec?: ExecHelperConfig;
16
+ helpers?: Record<string, string>;
17
+ }
18
+ export declare class LayoutRenderer {
19
+ private readonly handlebars;
20
+ private readonly propsValidator;
21
+ constructor(propsValidator?: PropsValidator);
22
+ render(layout: LayoutDefinition, context: RenderContext, options?: RenderOptions): string;
23
+ validate(props: Record<string, any> | undefined, propsSchema: Record<string, PropSchema>, mode?: 'strict' | 'lenient'): ValidationResult;
24
+ resolveProps(layout: LayoutDefinition, props: Record<string, any> | undefined, mode?: 'strict' | 'lenient'): ValidationResult;
25
+ private prepareRenderContext;
26
+ private registerHelpers;
27
+ registerTemplateHelpers(config: TemplateConfig): void;
28
+ private executeValidation;
29
+ private mergeProps;
30
+ private deepMerge;
31
+ private cloneDeep;
32
+ private isPlainObject;
33
+ private sanitizeVars;
34
+ }
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LayoutRenderer = exports.PropsValidationError = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const child_process_1 = require("child_process");
9
+ const fs_1 = require("fs");
10
+ const path_1 = require("path");
11
+ const props_validator_service_1 = require("./props-validator.service");
12
+ const layout_types_1 = require("../types/layout.types");
13
+ var layout_types_2 = require("../types/layout.types");
14
+ Object.defineProperty(exports, "PropsValidationError", { enumerable: true, get: function () { return layout_types_2.PropsValidationError; } });
15
+ const SENSITIVE_ENV_PATTERNS = [
16
+ /^ANTHROPIC_/i, /^OPENAI_/i, /^AWS_SECRET/i, /^SLACK_/i,
17
+ /^GITHUB_TOKEN$/i, /^CREWX_MCP_KEY$/i, /^DATABASE_/i,
18
+ /^AWS_ACCESS_KEY/i, /^AWS_SESSION_TOKEN$/i,
19
+ /^GH_TOKEN$/i, /^GH_APP_/i,
20
+ /^NPM_TOKEN$/i, /^NPM_AUTH/i,
21
+ /^GOOGLE_APPLICATION/i, /^GCLOUD_/i,
22
+ /^AZURE_/i, /^ARM_/i,
23
+ /^DOCKER_PASSWORD$/i, /^DOCKER_AUTH/i,
24
+ /^SSH_PRIVATE/i, /^SSH_AUTH_SOCK$/i,
25
+ /^CI_JOB_TOKEN$/i, /^ACTIONS_RUNTIME_TOKEN$/i,
26
+ /^VAULT_TOKEN$/i, /^SONAR_TOKEN$/i, /^CODECOV_TOKEN$/i,
27
+ /TOKEN$/i, /SECRET$/i, /PASSWORD$/i, /API_KEY$/i,
28
+ ];
29
+ const SHELL_METACHAR = /[;|&`$(){}!><\n\r]/;
30
+ const MAX_EXEC_DEPTH = 2;
31
+ const DANGEROUS_PATTERNS = ['*', '**', '*:*', '* *', '**/*'];
32
+ class LayoutRenderer {
33
+ constructor(propsValidator) {
34
+ this.handlebars = handlebars_1.default.create();
35
+ this.propsValidator = propsValidator ?? new props_validator_service_1.PropsValidator();
36
+ this.registerHelpers();
37
+ }
38
+ render(layout, context, options = {}) {
39
+ try {
40
+ const preparedContext = this.prepareRenderContext(layout, context, options);
41
+ const template = this.handlebars.compile(layout.template);
42
+ const result = template(preparedContext);
43
+ return result;
44
+ }
45
+ catch (error) {
46
+ if (error instanceof Error) {
47
+ throw new Error(`Template rendering failed for layout '${layout.id}': ${error.message}`);
48
+ }
49
+ throw new Error(`Unknown error rendering layout '${layout.id}'`);
50
+ }
51
+ }
52
+ validate(props, propsSchema, mode = 'lenient') {
53
+ return this.executeValidation(props, propsSchema, mode);
54
+ }
55
+ resolveProps(layout, props, mode = 'lenient') {
56
+ const mergedProps = this.mergeProps(layout.defaultProps, props);
57
+ if (!layout.propsSchema || Object.keys(layout.propsSchema).length === 0) {
58
+ return {
59
+ valid: true,
60
+ props: mergedProps,
61
+ errors: [],
62
+ };
63
+ }
64
+ return this.executeValidation(mergedProps, layout.propsSchema, mode);
65
+ }
66
+ prepareRenderContext(layout, context, options) {
67
+ const { validationMode = 'lenient', skipValidation = false } = options;
68
+ const resolvedProps = skipValidation
69
+ ? this.mergeProps(layout.defaultProps, context.props)
70
+ : this.resolveProps(layout, context.props, validationMode).props;
71
+ return {
72
+ ...context,
73
+ vars: this.sanitizeVars(context.vars),
74
+ props: resolvedProps,
75
+ };
76
+ }
77
+ registerHelpers() {
78
+ if (handlebars_1.default.helpers.each) {
79
+ this.handlebars.registerHelper('each', handlebars_1.default.helpers.each);
80
+ }
81
+ if (handlebars_1.default.helpers.if) {
82
+ this.handlebars.registerHelper('if', handlebars_1.default.helpers.if);
83
+ }
84
+ if (handlebars_1.default.helpers.unless) {
85
+ this.handlebars.registerHelper('unless', handlebars_1.default.helpers.unless);
86
+ }
87
+ if (handlebars_1.default.helpers.with) {
88
+ this.handlebars.registerHelper('with', handlebars_1.default.helpers.with);
89
+ }
90
+ this.handlebars.registerHelper('eq', function (a, b) {
91
+ return a === b;
92
+ });
93
+ this.handlebars.registerHelper('ne', function (a, b) {
94
+ return a !== b;
95
+ });
96
+ this.handlebars.registerHelper('gt', function (a, b) {
97
+ return a > b;
98
+ });
99
+ this.handlebars.registerHelper('lt', function (a, b) {
100
+ return a < b;
101
+ });
102
+ this.handlebars.registerHelper('json', function (obj) {
103
+ return new handlebars_1.default.SafeString(JSON.stringify(obj));
104
+ });
105
+ this.handlebars.registerHelper('raw', function (options) {
106
+ return typeof options?.fn === 'function' ? options.fn(this) : '';
107
+ });
108
+ this.handlebars.registerHelper('escapeHandlebars', function (text) {
109
+ if (typeof text !== 'string') {
110
+ return '';
111
+ }
112
+ return text.replace(/\{\{/g, '&#123;&#123;').replace(/\}\}/g, '&#125;&#125;');
113
+ });
114
+ this.handlebars.registerHelper('formatFileSize', function (bytes) {
115
+ if (bytes === 0)
116
+ return '0 B';
117
+ const sizes = ['B', 'KB', 'MB', 'GB'];
118
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
119
+ return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i];
120
+ });
121
+ const handlebarsInstance = this.handlebars;
122
+ this.handlebars.registerHelper('formatConversation', function (messages, platform, options) {
123
+ const isBlockHelper = options && typeof options.fn === 'function';
124
+ if (!Array.isArray(messages) || messages.length === 0) {
125
+ return '';
126
+ }
127
+ const assistantAgentIds = Array.from(new Set(messages
128
+ .filter((msg) => msg?.isAssistant && msg?.metadata?.agent_id)
129
+ .map((msg) => msg.metadata.agent_id)));
130
+ const primaryAgentId = assistantAgentIds.length > 0 ? assistantAgentIds[0] : '';
131
+ if (isBlockHelper) {
132
+ return options.fn({
133
+ messages,
134
+ platform,
135
+ messagesCount: messages.length,
136
+ agentIds: assistantAgentIds,
137
+ primaryAgentId,
138
+ });
139
+ }
140
+ const templatePath = (0, path_1.join)(process.cwd(), '.crewx', 'templates', 'conversation-history-default.hbs');
141
+ let templateContent;
142
+ try {
143
+ if ((0, fs_1.existsSync)(templatePath)) {
144
+ templateContent = (0, fs_1.readFileSync)(templatePath, 'utf8');
145
+ }
146
+ }
147
+ catch {
148
+ }
149
+ if (!templateContent) {
150
+ templateContent = `{{#if messages}}
151
+ {{#if primaryAgentId}}Primary agent: @{{primaryAgentId}}
152
+ {{else}}Primary agent: (unknown)
153
+ {{/if}}
154
+ Previous conversation ({{messagesCount}} messages):
155
+ {{#each messages}}
156
+ {{#if isAssistant}}
157
+ **Assistant{{#if metadata.agent_id}} (@{{metadata.agent_id}}){{/if}}**
158
+ {{else}}
159
+ **{{#if metadata.slack}}{{#with metadata.slack}}{{#if user_profile.display_name}}{{user_profile.display_name}}{{else if username}}{{username}}{{else if user_id}}User ({{user_id}}){{else}}User{{/if}}{{/with}}{{else}}User{{/if}}**
160
+ {{/if}}: {{{escapeHandlebars text}}}
161
+ {{#if files}}
162
+ {{#each files}}
163
+ 📎 {{name}} ({{formatFileSize size}}) - Local: {{localPath}}
164
+ {{/each}}
165
+ {{/if}}
166
+ {{/each}}{{/if}}`;
167
+ }
168
+ const template = handlebarsInstance.compile(templateContent, { noEscape: true });
169
+ return template({
170
+ messages,
171
+ platform,
172
+ messagesCount: messages.length,
173
+ agentIds: assistantAgentIds,
174
+ primaryAgentId,
175
+ });
176
+ });
177
+ }
178
+ registerTemplateHelpers(config) {
179
+ const execConfig = config.exec || {};
180
+ const hbs = this.handlebars;
181
+ const shellQuote = require('shell-quote');
182
+ const _minimatchMod = require('minimatch');
183
+ const minimatchFn = typeof _minimatchMod === 'function' ? _minimatchMod : _minimatchMod.minimatch;
184
+ const validatePattern = (pattern) => {
185
+ if (DANGEROUS_PATTERNS.includes(pattern.trim())) {
186
+ throw new Error(`exec config error: overly broad pattern "${pattern}" is not allowed`);
187
+ }
188
+ if (!/^[\w./@-]/.test(pattern)) {
189
+ throw new Error(`exec config error: pattern must start with a command name`);
190
+ }
191
+ };
192
+ for (const p of [...(execConfig.allow || []), ...(execConfig.deny || [])]) {
193
+ validatePattern(p);
194
+ }
195
+ const logAudit = (entry) => {
196
+ console.error(JSON.stringify({ span: 'template_exec', ...entry, timestamp: new Date().toISOString() }));
197
+ };
198
+ hbs.registerHelper('exec', function (command) {
199
+ if (typeof command !== 'string')
200
+ return '';
201
+ const startMs = Date.now();
202
+ const execDepth = parseInt(process.env.CREWX_EXEC_DEPTH || '0', 10);
203
+ if (isNaN(execDepth) || execDepth >= MAX_EXEC_DEPTH) {
204
+ logAudit({ command, status: 'denied', reason: 'invalid or max recursion depth' });
205
+ return '(exec blocked: max recursion depth reached)';
206
+ }
207
+ if (SHELL_METACHAR.test(command)) {
208
+ logAudit({ command, status: 'denied', reason: 'shell metacharacter detected' });
209
+ return `(exec blocked: shell metacharacter detected in "${command}")`;
210
+ }
211
+ const isCommandAllowed = (cmd) => {
212
+ const { allow = [], deny = [] } = execConfig;
213
+ if (deny.some(p => minimatchFn(cmd, p)))
214
+ return false;
215
+ if (/^npx\s+@crewx\/[\w-]+/.test(cmd))
216
+ return true;
217
+ return allow.some(p => minimatchFn(cmd, p));
218
+ };
219
+ if (!isCommandAllowed(command)) {
220
+ logAudit({ command, status: 'denied', reason: 'not in allow list' });
221
+ return `(exec blocked: ${command})`;
222
+ }
223
+ try {
224
+ const parsed = shellQuote.parse(command).map(String);
225
+ const [bin, ...args] = parsed;
226
+ if (!bin)
227
+ return `(exec failed: ${command})`;
228
+ const env = { ...process.env };
229
+ for (const key of Object.keys(env)) {
230
+ if (SENSITIVE_ENV_PATTERNS.some(p => p.test(key)))
231
+ delete env[key];
232
+ }
233
+ const result = (0, child_process_1.execFileSync)(bin, args, {
234
+ timeout: execConfig.timeout || 5000,
235
+ maxBuffer: 64 * 1024,
236
+ encoding: 'utf-8',
237
+ env: { ...env, CREWX_EXEC_DEPTH: String(execDepth + 1) },
238
+ stdio: ['pipe', 'pipe', 'pipe'],
239
+ });
240
+ const durationMs = Date.now() - startMs;
241
+ logAudit({ command, status: 'allowed', duration_ms: durationMs });
242
+ return new handlebars_1.default.SafeString(`<exec-output cmd="${command}">\n${result.trim()}\n</exec-output>`);
243
+ }
244
+ catch {
245
+ logAudit({ command, status: 'error', reason: 'execution failed' });
246
+ return `(exec failed: ${command})`;
247
+ }
248
+ });
249
+ if (config.helpers) {
250
+ for (const [name] of Object.entries(config.helpers)) {
251
+ console.warn(`Custom helper '${name}' rejected: user-defined JavaScript execution is disabled for security`);
252
+ }
253
+ }
254
+ }
255
+ executeValidation(props, propsSchema, mode) {
256
+ try {
257
+ return this.propsValidator.validate(props, propsSchema, mode);
258
+ }
259
+ catch (error) {
260
+ if (error instanceof layout_types_1.PropsValidationError && error.errors && error.errors.length > 0) {
261
+ const firstError = error.errors[0];
262
+ if (firstError) {
263
+ throw new layout_types_1.PropsValidationError(firstError.message, error.errors);
264
+ }
265
+ }
266
+ throw error;
267
+ }
268
+ }
269
+ mergeProps(defaultProps, overrides) {
270
+ const base = this.cloneDeep(defaultProps ?? {});
271
+ if (!overrides) {
272
+ return base;
273
+ }
274
+ return this.deepMerge(base, overrides);
275
+ }
276
+ deepMerge(target, source) {
277
+ for (const [key, value] of Object.entries(source)) {
278
+ if (this.isPlainObject(value)) {
279
+ const existing = target[key];
280
+ target[key] = this.deepMerge(this.isPlainObject(existing) ? existing : {}, value);
281
+ continue;
282
+ }
283
+ if (Array.isArray(value)) {
284
+ target[key] = this.cloneDeep(value);
285
+ continue;
286
+ }
287
+ target[key] = value;
288
+ }
289
+ return target;
290
+ }
291
+ cloneDeep(value) {
292
+ if (Array.isArray(value)) {
293
+ return value.map(item => this.cloneDeep(item));
294
+ }
295
+ if (this.isPlainObject(value)) {
296
+ const cloned = {};
297
+ for (const [key, nested] of Object.entries(value)) {
298
+ cloned[key] = this.cloneDeep(nested);
299
+ }
300
+ return cloned;
301
+ }
302
+ return value;
303
+ }
304
+ isPlainObject(value) {
305
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
306
+ }
307
+ sanitizeVars(vars) {
308
+ if (!vars) {
309
+ return {};
310
+ }
311
+ const sanitizedVars = { ...vars };
312
+ if (typeof vars.user_input === 'string') {
313
+ sanitizedVars.user_input_raw = vars.user_input;
314
+ const escapedHandlebars = vars.user_input
315
+ .replace(/\{\{\{/g, '&#123;&#123;&#123;')
316
+ .replace(/\}\}\}/g, '&#125;&#125;&#125;')
317
+ .replace(/\{\{/g, '&#123;&#123;')
318
+ .replace(/\}\}/g, '&#125;&#125;');
319
+ sanitizedVars.user_input = this.handlebars.escapeExpression(escapedHandlebars);
320
+ }
321
+ return sanitizedVars;
322
+ }
323
+ }
324
+ exports.LayoutRenderer = LayoutRenderer;
325
+ //# sourceMappingURL=layout-renderer.service.js.map