@crewx/sdk 0.8.0-rc.80 → 0.8.0-rc.83

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 (217) hide show
  1. package/dist/__tests__/adapter/context-builder.test.d.ts +1 -0
  2. package/dist/__tests__/adapter/plugin-helper.test.d.ts +1 -0
  3. package/dist/__tests__/adapter/registration-integration.test.d.ts +1 -0
  4. package/dist/__tests__/adapter/scoped-store.test.d.ts +1 -0
  5. package/dist/__tests__/plugins/conversation.test.d.ts +1 -0
  6. package/dist/__tests__/testing/createMockContext.test.d.ts +1 -0
  7. package/dist/adapter/context-builder.d.ts +0 -9
  8. package/dist/adapter/index.d.ts +0 -1
  9. package/dist/adapter/plugin-helper.d.ts +0 -7
  10. package/dist/adapter/scoped-store.d.ts +0 -10
  11. package/dist/adapter/types.d.ts +0 -7
  12. package/dist/agent/resolver.d.ts +0 -13
  13. package/dist/boxing/box-storage.interface.d.ts +0 -4
  14. package/dist/boxing/box.service.d.ts +0 -4
  15. package/dist/boxing/box.types.d.ts +0 -4
  16. package/dist/boxing/context-builder.d.ts +0 -4
  17. package/dist/client/CrewxClient.d.ts +0 -32
  18. package/dist/client/index.d.ts +0 -1
  19. package/dist/client/index.js +1 -6
  20. package/dist/config/loader.browser.d.ts +0 -8
  21. package/dist/config/loader.d.ts +0 -12
  22. package/dist/conversation/__tests__/sqlite-provider.test.d.ts +1 -0
  23. package/dist/conversation/__tests__/to-task-reader.test.d.ts +1 -0
  24. package/dist/conversation/index.d.ts +0 -1
  25. package/dist/conversation/sqlite-provider.d.ts +0 -9
  26. package/dist/conversation/to-task-reader.d.ts +0 -11
  27. package/dist/conversation/to-template-messages.d.ts +0 -13
  28. package/dist/conversation/types.d.ts +0 -58
  29. package/dist/esm/client/index.js +1 -0
  30. package/dist/esm/hooks/index.js +7 -0
  31. package/dist/esm/index.js +79 -0
  32. package/dist/esm/plugins/index.js +52 -0
  33. package/dist/esm/testing/index.js +1 -0
  34. package/dist/esm/tools/node/index.js +36 -0
  35. package/dist/events/TypedEventEmitter.d.ts +0 -24
  36. package/dist/events/types.d.ts +0 -43
  37. package/dist/facade/Crewx.browser.d.ts +0 -40
  38. package/dist/facade/Crewx.d.ts +0 -163
  39. package/dist/hooks/define.d.ts +0 -1
  40. package/dist/hooks/dispatch.d.ts +0 -12
  41. package/dist/hooks/index.d.ts +0 -1
  42. package/dist/hooks/index.js +7 -24
  43. package/dist/hooks/observer.d.ts +0 -1
  44. package/dist/hooks/plugin.d.ts +0 -1
  45. package/dist/hooks/tool-normalize.d.ts +0 -26
  46. package/dist/hooks/types.d.ts +0 -1
  47. package/dist/hooks/yaml-plugin.d.ts +0 -1
  48. package/dist/index.browser.d.ts +0 -7
  49. package/dist/index.browser.js +2 -25
  50. package/dist/index.d.ts +0 -4
  51. package/dist/index.js +79 -151
  52. package/dist/layout/loader.d.ts +0 -20
  53. package/dist/layout/props-validator.d.ts +0 -6
  54. package/dist/layout/renderer.d.ts +0 -24
  55. package/dist/layout/types.d.ts +0 -42
  56. package/dist/parallel/agent-runtime.d.ts +0 -11
  57. package/dist/parallel/helpers.d.ts +0 -1
  58. package/dist/parallel/index.d.ts +0 -1
  59. package/dist/parallel/parallel-runner.d.ts +0 -8
  60. package/dist/parallel/types.d.ts +0 -24
  61. package/dist/parsers/agent-call.util.d.ts +0 -3
  62. package/dist/parsers/claude.parser.d.ts +0 -8
  63. package/dist/parsers/codex.parser.d.ts +0 -8
  64. package/dist/parsers/copilot.parser.d.ts +0 -9
  65. package/dist/parsers/gemini.parser.d.ts +0 -10
  66. package/dist/parsers/opencode.parser.d.ts +0 -10
  67. package/dist/parsers/router.d.ts +0 -5
  68. package/dist/paths.d.ts +1 -0
  69. package/dist/platform/BrowserFsAdapter.d.ts +0 -20
  70. package/dist/platform/IFsAdapter.d.ts +0 -23
  71. package/dist/platform/NodeFsAdapter.d.ts +0 -8
  72. package/dist/plugin/plugin-provider.d.ts +0 -22
  73. package/dist/plugin/types.d.ts +0 -31
  74. package/dist/plugin.d.ts +0 -27
  75. package/dist/plugins/conversation.d.ts +0 -2
  76. package/dist/plugins/file-logger.d.ts +0 -13
  77. package/dist/plugins/index.d.ts +0 -10
  78. package/dist/plugins/index.js +52 -19
  79. package/dist/plugins/sqlite-tracing.d.ts +0 -13
  80. package/dist/plugins/sqlite-tracing.spec.d.ts +1 -0
  81. package/dist/provider/bridge.browser.d.ts +0 -20
  82. package/dist/provider/bridge.d.ts +0 -47
  83. package/dist/provider/parse-usage.d.ts +0 -14
  84. package/dist/provider/register-api.d.ts +0 -7
  85. package/dist/provider/vercel-runtime.d.ts +0 -29
  86. package/dist/remote/index.d.ts +0 -6
  87. package/dist/remote/remote-agent-manager.d.ts +0 -31
  88. package/dist/remote/remote-provider.d.ts +0 -15
  89. package/dist/remote/remote-transport.d.ts +0 -17
  90. package/dist/remote/types.d.ts +0 -59
  91. package/dist/server/auth.d.ts +0 -16
  92. package/dist/server/handler.d.ts +0 -17
  93. package/dist/server/index.d.ts +0 -4
  94. package/dist/server/tool-adapter.d.ts +0 -16
  95. package/dist/template/engine.d.ts +0 -19
  96. package/dist/template/helpers/exec.browser.d.ts +0 -7
  97. package/dist/template/helpers/exec.d.ts +0 -45
  98. package/dist/template/helpers/fenced_code.d.ts +0 -16
  99. package/dist/template/helpers/format-conversation.d.ts +0 -22
  100. package/dist/template/helpers/include.d.ts +0 -15
  101. package/dist/template/helpers/p1p2.d.ts +0 -32
  102. package/dist/template/loader/DocumentLoader.d.ts +0 -30
  103. package/dist/template/types.d.ts +0 -30
  104. package/dist/testing/index.d.ts +0 -1
  105. package/dist/testing/index.js +1 -16
  106. package/dist/testing/mock-audit.d.ts +0 -1
  107. package/dist/testing/mock-context.d.ts +0 -1
  108. package/dist/testing/mock-logger.d.ts +0 -1
  109. package/dist/testing/mock-router.d.ts +0 -1
  110. package/dist/testing/mock-storage.d.ts +0 -1
  111. package/dist/testing/mock-store.d.ts +0 -1
  112. package/dist/tools/delegate.d.ts +0 -7
  113. package/dist/tools/index.d.ts +0 -4
  114. package/dist/tools/node/builtin.d.ts +0 -16
  115. package/dist/tools/node/index.d.ts +0 -20
  116. package/dist/tools/node/index.js +36 -59
  117. package/dist/types/index.d.ts +0 -20
  118. package/dist/types/task-log.types.d.ts +0 -4
  119. package/dist/utils/env-defaults.d.ts +0 -16
  120. package/dist/utils/glob-match.d.ts +0 -16
  121. package/dist/utils/id.d.ts +0 -15
  122. package/dist/utils/timestamp.d.ts +0 -1
  123. package/dist/utils/workspace.d.ts +0 -4
  124. package/package.json +24 -25
  125. package/dist/adapter/context-builder.js +0 -87
  126. package/dist/adapter/index.js +0 -21
  127. package/dist/adapter/plugin-helper.js +0 -45
  128. package/dist/adapter/scoped-store.js +0 -43
  129. package/dist/adapter/types.js +0 -23
  130. package/dist/agent/resolver.js +0 -46
  131. package/dist/boxing/box-storage.interface.js +0 -6
  132. package/dist/boxing/box.service.js +0 -73
  133. package/dist/boxing/box.types.js +0 -6
  134. package/dist/boxing/context-builder.js +0 -79
  135. package/dist/client/CrewxClient.js +0 -86
  136. package/dist/config/loader.browser.js +0 -59
  137. package/dist/config/loader.js +0 -95
  138. package/dist/conversation/index.js +0 -25
  139. package/dist/conversation/sqlite-provider.js +0 -178
  140. package/dist/conversation/to-task-reader.js +0 -28
  141. package/dist/conversation/to-template-messages.js +0 -34
  142. package/dist/conversation/types.js +0 -10
  143. package/dist/events/TypedEventEmitter.js +0 -65
  144. package/dist/events/types.js +0 -9
  145. package/dist/facade/Crewx.browser.js +0 -314
  146. package/dist/facade/Crewx.js +0 -1299
  147. package/dist/hooks/define.js +0 -13
  148. package/dist/hooks/dispatch.js +0 -147
  149. package/dist/hooks/observer.js +0 -60
  150. package/dist/hooks/plugin.js +0 -17
  151. package/dist/hooks/tool-normalize.js +0 -110
  152. package/dist/hooks/types.js +0 -12
  153. package/dist/hooks/yaml-plugin.js +0 -356
  154. package/dist/layout/loader.js +0 -305
  155. package/dist/layout/props-validator.js +0 -301
  156. package/dist/layout/renderer.js +0 -193
  157. package/dist/layout/types.js +0 -36
  158. package/dist/parallel/agent-runtime.js +0 -25
  159. package/dist/parallel/helpers.js +0 -219
  160. package/dist/parallel/index.js +0 -13
  161. package/dist/parallel/parallel-runner.js +0 -226
  162. package/dist/parallel/types.js +0 -6
  163. package/dist/parsers/agent-call.util.js +0 -19
  164. package/dist/parsers/claude.parser.js +0 -67
  165. package/dist/parsers/codex.parser.js +0 -100
  166. package/dist/parsers/copilot.parser.js +0 -66
  167. package/dist/parsers/gemini.parser.js +0 -46
  168. package/dist/parsers/opencode.parser.js +0 -76
  169. package/dist/parsers/router.js +0 -56
  170. package/dist/platform/BrowserFsAdapter.js +0 -84
  171. package/dist/platform/IFsAdapter.js +0 -3
  172. package/dist/platform/NodeFsAdapter.js +0 -38
  173. package/dist/plugin/plugin-provider.js +0 -207
  174. package/dist/plugin/types.js +0 -9
  175. package/dist/plugin.js +0 -29
  176. package/dist/plugins/conversation.js +0 -59
  177. package/dist/plugins/file-logger.js +0 -87
  178. package/dist/plugins/sqlite-tracing.js +0 -112
  179. package/dist/provider/bridge.browser.js +0 -49
  180. package/dist/provider/bridge.js +0 -381
  181. package/dist/provider/parse-usage.js +0 -83
  182. package/dist/provider/register-api.js +0 -24
  183. package/dist/provider/vercel-runtime.js +0 -347
  184. package/dist/remote/index.js +0 -32
  185. package/dist/remote/remote-agent-manager.js +0 -198
  186. package/dist/remote/remote-provider.js +0 -141
  187. package/dist/remote/remote-transport.js +0 -83
  188. package/dist/remote/types.js +0 -9
  189. package/dist/server/auth.js +0 -35
  190. package/dist/server/handler.js +0 -75
  191. package/dist/server/index.js +0 -9
  192. package/dist/server/tool-adapter.js +0 -95
  193. package/dist/template/engine.js +0 -137
  194. package/dist/template/helpers/exec.browser.js +0 -41
  195. package/dist/template/helpers/exec.js +0 -230
  196. package/dist/template/helpers/fenced_code.js +0 -20
  197. package/dist/template/helpers/format-conversation.js +0 -53
  198. package/dist/template/helpers/include.js +0 -23
  199. package/dist/template/helpers/p1p2.js +0 -90
  200. package/dist/template/loader/DocumentLoader.js +0 -128
  201. package/dist/template/types.js +0 -6
  202. package/dist/testing/mock-audit.js +0 -13
  203. package/dist/testing/mock-context.js +0 -68
  204. package/dist/testing/mock-logger.js +0 -27
  205. package/dist/testing/mock-router.js +0 -67
  206. package/dist/testing/mock-storage.js +0 -21
  207. package/dist/testing/mock-store.js +0 -8
  208. package/dist/tools/delegate.js +0 -60
  209. package/dist/tools/index.js +0 -9
  210. package/dist/tools/node/builtin.js +0 -547
  211. package/dist/types/index.js +0 -32
  212. package/dist/types/task-log.types.js +0 -6
  213. package/dist/utils/env-defaults.js +0 -27
  214. package/dist/utils/glob-match.js +0 -42
  215. package/dist/utils/id.js +0 -50
  216. package/dist/utils/timestamp.js +0 -13
  217. package/dist/utils/workspace.js +0 -58
@@ -1,356 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.YamlHookPlugin = void 0;
4
- exports.validateHooksSchema = validateHooksSchema;
5
- const plugin_1 = require("./plugin");
6
- const node_crypto_1 = require("node:crypto");
7
- const node_path_1 = require("node:path");
8
- const node_os_1 = require("node:os");
9
- const node_fs_1 = require("node:fs");
10
- const glob_match_1 = require("../utils/glob-match");
11
- const dispatch_1 = require("./dispatch");
12
- const MAX_FILE_SIZE_FOR_LINE_COUNT = 10 * 1024 * 1024;
13
- const SIZE_UNITS = {
14
- b: 1,
15
- kb: 1024,
16
- mb: 1024 * 1024,
17
- gb: 1024 * 1024 * 1024,
18
- };
19
- function matches(selector, value) {
20
- if (selector === undefined)
21
- return true;
22
- if (Array.isArray(selector))
23
- return selector.includes(value);
24
- return selector === value;
25
- }
26
- function matchesAny(selector, values) {
27
- if (selector === undefined)
28
- return true;
29
- if (Array.isArray(selector))
30
- return selector.some(s => values.includes(s));
31
- return values.includes(selector);
32
- }
33
- function parseSizeValue(val) {
34
- if (typeof val === 'number')
35
- return val;
36
- const match = val.match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/i);
37
- if (!match)
38
- return 0;
39
- const num = parseFloat(match[1]);
40
- const unit = (match[2] ?? 'b').toLowerCase();
41
- return Math.floor(num * (SIZE_UNITS[unit] ?? 1));
42
- }
43
- function isSizeInBytes(val) {
44
- return typeof val === 'string';
45
- }
46
- function getFileLineCount(filePath) {
47
- try {
48
- const stat = (0, node_fs_1.statSync)(filePath);
49
- if (stat.size > MAX_FILE_SIZE_FOR_LINE_COUNT) {
50
- process.stderr.write(`[YamlHookPlugin] File too large for line count: ${filePath} (${stat.size} bytes)\n`);
51
- return null;
52
- }
53
- const content = (0, node_fs_1.readFileSync)(filePath, 'utf8');
54
- return content.split('\n').length;
55
- }
56
- catch {
57
- return null;
58
- }
59
- }
60
- function getFileSizeBytes(filePath) {
61
- try {
62
- return (0, node_fs_1.statSync)(filePath).size;
63
- }
64
- catch {
65
- return null;
66
- }
67
- }
68
- function matchPathPattern(pathPattern, toolInput, cwd) {
69
- if (!pathPattern)
70
- return true;
71
- const input = toolInput;
72
- const path = input?.path ?? input?.file_path ?? input?.filePath ?? input?.filename;
73
- if (typeof path !== 'string')
74
- return false;
75
- if ((0, glob_match_1.matchesPattern)(path, pathPattern))
76
- return true;
77
- // Provider가 절대경로를 보내는 경우(Claude Read 등) cwd 기준 상대경로로도 시도.
78
- if (cwd && path.startsWith('/')) {
79
- const { relative, isAbsolute } = require('node:path');
80
- if (isAbsolute(path)) {
81
- const rel = relative(cwd, path);
82
- if (rel && !rel.startsWith('..') && (0, glob_match_1.matchesPattern)(rel, pathPattern))
83
- return true;
84
- }
85
- }
86
- return false;
87
- }
88
- function matchPattern(pattern, toolInput) {
89
- if (!pattern)
90
- return true;
91
- const inputStr = JSON.stringify(toolInput);
92
- return inputStr.includes(pattern);
93
- }
94
- function matchRegex(regex, toolInput) {
95
- if (!regex)
96
- return true;
97
- try {
98
- const re = new RegExp(regex);
99
- const inputStr = JSON.stringify(toolInput);
100
- return re.test(inputStr);
101
- }
102
- catch {
103
- return false;
104
- }
105
- }
106
- function matchWhenInputRegex(regex, toolInput) {
107
- if (!regex)
108
- return true;
109
- try {
110
- const re = new RegExp(regex);
111
- const inputStr = JSON.stringify(toolInput);
112
- return re.test(inputStr);
113
- }
114
- catch {
115
- return false;
116
- }
117
- }
118
- function matchPathSize(rule, toolInput) {
119
- if (rule.pathSizeMin === undefined && rule.pathSizeMax === undefined)
120
- return true;
121
- const input = toolInput;
122
- const filePath = input?.path ?? input?.file_path ?? input?.filePath ?? input?.filename;
123
- if (typeof filePath !== 'string')
124
- return false;
125
- if (rule.pathSizeMin !== undefined) {
126
- if (isSizeInBytes(rule.pathSizeMin)) {
127
- const sizeBytes = getFileSizeBytes(filePath);
128
- if (sizeBytes === null)
129
- return false;
130
- if (sizeBytes < parseSizeValue(rule.pathSizeMin))
131
- return false;
132
- }
133
- else {
134
- const lineCount = getFileLineCount(filePath);
135
- if (lineCount === null)
136
- return false;
137
- if (lineCount < rule.pathSizeMin)
138
- return false;
139
- }
140
- }
141
- if (rule.pathSizeMax !== undefined) {
142
- if (isSizeInBytes(rule.pathSizeMax)) {
143
- const sizeBytes = getFileSizeBytes(filePath);
144
- if (sizeBytes === null)
145
- return false;
146
- if (sizeBytes > parseSizeValue(rule.pathSizeMax))
147
- return false;
148
- }
149
- else {
150
- const lineCount = getFileLineCount(filePath);
151
- if (lineCount === null)
152
- return false;
153
- if (lineCount > rule.pathSizeMax)
154
- return false;
155
- }
156
- }
157
- return true;
158
- }
159
- function validateHooksSchema(hooks) {
160
- const valid = [];
161
- const warnings = [];
162
- for (let i = 0; i < hooks.length; i++) {
163
- const entry = hooks[i];
164
- if (!entry || typeof entry !== 'object') {
165
- warnings.push(`Hook at index ${i}: not an object, skipping`);
166
- continue;
167
- }
168
- const obj = entry;
169
- if (typeof obj.name !== 'string' || !obj.name) {
170
- warnings.push(`Hook at index ${i}: missing or invalid "name", skipping`);
171
- continue;
172
- }
173
- const hasGuide = obj.guide && typeof obj.guide === 'object';
174
- const hasDeny = obj.deny && typeof obj.deny === 'object';
175
- const hasPlugin = typeof obj.plugin === 'string';
176
- if (!hasGuide && !hasDeny && !hasPlugin) {
177
- warnings.push(`Hook "${obj.name}": missing guide/deny/plugin, skipping`);
178
- continue;
179
- }
180
- if (hasGuide) {
181
- const guide = obj.guide;
182
- if (typeof guide.say !== 'string') {
183
- warnings.push(`Hook "${obj.name}": guide.say is required and must be string, skipping`);
184
- continue;
185
- }
186
- }
187
- if (hasDeny) {
188
- const deny = obj.deny;
189
- if (typeof deny.reason !== 'string') {
190
- warnings.push(`Hook "${obj.name}": deny.reason is required and must be string, skipping`);
191
- continue;
192
- }
193
- }
194
- valid.push(obj);
195
- }
196
- return { valid, warnings };
197
- }
198
- class YamlHookPlugin extends plugin_1.HookPlugin {
199
- name = '@crewx/yaml-hook-plugin';
200
- version = '0.1.0';
201
- capabilities = { required: ['inject'] };
202
- hooks;
203
- agentMap;
204
- constructor(config) {
205
- super();
206
- this.hooks = config.hooks;
207
- this.agentMap = new Map((config.agents ?? []).map(a => [a.id, a]));
208
- }
209
- async run(ctx) {
210
- const injected = [];
211
- const logPath = process.env.CREWX_TASK_LOG_PATH;
212
- const verbose = process.env.CREWX_HOOK_LOG_VERBOSE === '1';
213
- for (const entry of this.hooks) {
214
- if (!this.matchEntryLevel(entry, ctx))
215
- continue;
216
- if (!entry.guide)
217
- continue;
218
- if (!this.matchRuleLevel(entry.guide, ctx)) {
219
- if (verbose && logPath) {
220
- this.appendHookLog(logPath, {
221
- rule: entry.name,
222
- action: 'pass',
223
- once: entry.guide.once ?? false,
224
- ctx,
225
- matched: false,
226
- });
227
- }
228
- continue;
229
- }
230
- if (entry.guide.once && this.hasFired(ctx.sessionId, entry.name))
231
- continue;
232
- if (entry.guide.once)
233
- this.markFired(ctx.sessionId, entry.name);
234
- injected.push(entry.guide.say);
235
- if (logPath) {
236
- this.appendHookLog(logPath, {
237
- rule: entry.name,
238
- action: 'inject',
239
- once: entry.guide.once ?? false,
240
- ctx,
241
- matched: true,
242
- message: entry.guide.say,
243
- });
244
- }
245
- }
246
- return injected.length ? ctx.inject(injected.join('\n\n')) : ctx.pass();
247
- }
248
- appendHookLog(logPath, opts) {
249
- try {
250
- const entry = {
251
- rule: opts.rule,
252
- action: opts.action,
253
- once: opts.once,
254
- sessionId: opts.ctx.sessionId,
255
- provider: opts.ctx.provider,
256
- agent: opts.ctx.agent.id,
257
- toolName: opts.ctx.tool.name,
258
- rawToolName: opts.ctx.tool.rawName,
259
- };
260
- if (opts.message) {
261
- entry.chars = opts.message.length;
262
- if (process.env.CREWX_HOOK_LOG_VERBOSE === '1') {
263
- entry.message = (0, dispatch_1.sanitizeInjectMessage)(opts.message).slice(0, 500);
264
- }
265
- }
266
- const line = `[${new Date().toISOString()}] HOOK: ${JSON.stringify(entry)}\n`;
267
- (0, node_fs_1.appendFileSync)(logPath, line, { encoding: 'utf8', mode: 0o600 });
268
- }
269
- catch {
270
- // Non-fatal
271
- }
272
- }
273
- matchEntryLevel(entry, ctx) {
274
- if (entry.provider !== undefined) {
275
- const provider = ctx.provider.replace(/^cli\//, '');
276
- if (!matches(entry.provider, provider))
277
- return false;
278
- }
279
- if (entry.team !== undefined) {
280
- const agent = this.agentMap.get(ctx.agent.id);
281
- const team = agent?.team ?? ctx.agent.team;
282
- if (!matches(entry.team, team))
283
- return false;
284
- }
285
- if (entry.role !== undefined) {
286
- const agent = this.agentMap.get(ctx.agent.id);
287
- const role = agent?.role ?? ctx.agent.role;
288
- if (!matches(entry.role, role))
289
- return false;
290
- }
291
- if (entry.tag !== undefined) {
292
- const agent = this.agentMap.get(ctx.agent.id);
293
- const tags = agent?.tags ?? [];
294
- if (!matchesAny(entry.tag, tags))
295
- return false;
296
- }
297
- if (entry.agents !== undefined) {
298
- if (!entry.agents.includes(ctx.agent.id))
299
- return false;
300
- }
301
- return true;
302
- }
303
- matchRuleLevel(rule, ctx) {
304
- if (rule.when !== undefined && rule.when.length > 0) {
305
- if (!rule.when.includes(ctx.tool.name) && !rule.when.includes(ctx.tool.rawName))
306
- return false;
307
- }
308
- if (!matchPattern(rule.pattern, ctx.tool.input))
309
- return false;
310
- if (!matchRegex(rule.regex, ctx.tool.input))
311
- return false;
312
- if (!matchPathPattern(rule.pathPattern, ctx.tool.input, ctx.cwd))
313
- return false;
314
- if (!matchPathSize(rule, ctx.tool.input))
315
- return false;
316
- if (!matchWhenInputRegex(rule.whenInputRegex, ctx.tool.input))
317
- return false;
318
- return true;
319
- }
320
- hasFired(sessionId, ruleName) {
321
- try {
322
- const path = this.firedFilePath(sessionId);
323
- if (!(0, node_fs_1.existsSync)(path))
324
- return false;
325
- const state = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
326
- return Array.isArray(state.fired) && state.fired.includes(ruleName);
327
- }
328
- catch {
329
- return false;
330
- }
331
- }
332
- markFired(sessionId, ruleName) {
333
- try {
334
- const path = this.firedFilePath(sessionId);
335
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true, mode: 0o700 });
336
- const state = (0, node_fs_1.existsSync)(path)
337
- ? JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'))
338
- : { fired: [] };
339
- if (!Array.isArray(state.fired))
340
- state.fired = [];
341
- if (!state.fired.includes(ruleName)) {
342
- state.fired.push(ruleName);
343
- (0, node_fs_1.writeFileSync)(path, JSON.stringify(state), { mode: 0o600 });
344
- }
345
- }
346
- catch (e) {
347
- process.stderr.write(`[YamlHookPlugin] once state write failed: ${e}\n`);
348
- }
349
- }
350
- firedFilePath(sessionId) {
351
- const safe = (0, node_crypto_1.createHash)('sha1').update(sessionId).digest('hex');
352
- return (0, node_path_1.join)((0, node_os_1.homedir)(), '.crewx', 'sessions', safe, 'fired-rules.json');
353
- }
354
- }
355
- exports.YamlHookPlugin = YamlHookPlugin;
356
- //# sourceMappingURL=yaml-plugin.js.map
@@ -1,305 +0,0 @@
1
- "use strict";
2
- /**
3
- * LayoutLoader — loads layout templates from templates/agents/*.yaml files.
4
- * Ported 1:1 from packages/sdk-bak/src/services/layout-loader.service.ts.
5
- * Only import paths and DEFAULT_OPTIONS.templatesPath are changed.
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.LayoutLoader = void 0;
42
- const fs_1 = require("fs");
43
- const path = __importStar(require("path"));
44
- const js_yaml_1 = require("js-yaml");
45
- const types_1 = require("./types");
46
- /**
47
- * Default loader options — points to SDK's bundled templates directory.
48
- */
49
- const DEFAULT_OPTIONS = {
50
- templatesPath: path.join(__dirname, '../../../templates/agents'),
51
- validationMode: 'lenient',
52
- fallbackLayoutId: 'crewx/default',
53
- };
54
- /**
55
- * Layout loader service.
56
- * Loads and caches layout definitions from YAML files.
57
- * Provides fallback mechanism and prop override support.
58
- */
59
- class LayoutLoader {
60
- layouts = new Map();
61
- options;
62
- constructor(options) {
63
- this.options = { ...DEFAULT_OPTIONS, ...options };
64
- this.loadAllLayouts();
65
- }
66
- /**
67
- * Load a layout by ID with optional props override.
68
- */
69
- load(layoutId, propsOverride) {
70
- let layout = this.layouts.get(layoutId);
71
- if (!layout) {
72
- const normalizedId = this.normalizeLayoutId(layoutId);
73
- layout = this.layouts.get(normalizedId);
74
- }
75
- if (!layout) {
76
- console.warn(`Layout not found: ${layoutId}, falling back to ${this.options.fallbackLayoutId}`);
77
- layout = this.layouts.get(this.options.fallbackLayoutId);
78
- if (!layout) {
79
- throw new types_1.LayoutLoadError(`Fallback layout not found: ${this.options.fallbackLayoutId}`, this.options.fallbackLayoutId);
80
- }
81
- }
82
- if (propsOverride && Object.keys(propsOverride).length > 0) {
83
- return {
84
- ...layout,
85
- defaultProps: { ...layout.defaultProps, ...propsOverride },
86
- };
87
- }
88
- return layout;
89
- }
90
- getLayoutIds() {
91
- return Array.from(this.layouts.keys());
92
- }
93
- hasLayout(layoutId) {
94
- if (this.layouts.has(layoutId))
95
- return true;
96
- const normalizedId = this.normalizeLayoutId(layoutId);
97
- return this.layouts.has(normalizedId);
98
- }
99
- reload() {
100
- this.layouts.clear();
101
- this.loadAllLayouts();
102
- }
103
- /**
104
- * Register or override a layout at runtime.
105
- */
106
- registerLayout(layoutId, layoutConfig) {
107
- if (!layoutId || typeof layoutId !== 'string') {
108
- throw new types_1.LayoutLoadError('Layout ID must be a non-empty string', layoutId);
109
- }
110
- const config = typeof layoutConfig === 'string'
111
- ? { template: layoutConfig }
112
- : layoutConfig;
113
- const template = typeof config.template === 'string' ? config.template : '';
114
- if (!template || template.trim().length === 0) {
115
- throw new types_1.LayoutLoadError(`Custom layout template is empty for ${layoutId}`, layoutId);
116
- }
117
- const propsSchemaRaw = config.propsSchema || {};
118
- const defaultPropsFromSchema = this.extractDefaultProps(propsSchemaRaw);
119
- const explicitDefaults = config.defaultProps || {};
120
- const layoutDefinition = {
121
- id: layoutId,
122
- version: config.version || '1.0.0',
123
- description: config.description || `Custom layout ${layoutId}`,
124
- template,
125
- propsSchema: this.parsePropsSchema(propsSchemaRaw),
126
- defaultProps: { ...defaultPropsFromSchema, ...explicitDefaults },
127
- };
128
- const existingLayout = this.layouts.get(layoutId);
129
- const templatesEqual = existingLayout?.template === template &&
130
- JSON.stringify(existingLayout?.defaultProps ?? {}) === JSON.stringify(layoutDefinition.defaultProps ?? {}) &&
131
- JSON.stringify(existingLayout?.propsSchema ?? {}) === JSON.stringify(layoutDefinition.propsSchema ?? {});
132
- this.layouts.set(layoutId, layoutDefinition);
133
- if (process.env.CREWX_VERBOSE === '1') {
134
- if (!existingLayout) {
135
- console.error(`Registered custom layout: ${layoutId}`);
136
- }
137
- else if (!templatesEqual) {
138
- console.error(`Updated custom layout: ${layoutId}`);
139
- }
140
- }
141
- }
142
- /**
143
- * Register multiple layouts from a map.
144
- */
145
- registerLayouts(layoutsMap) {
146
- for (const [id, config] of Object.entries(layoutsMap)) {
147
- try {
148
- this.registerLayout(id, config);
149
- }
150
- catch (error) {
151
- console.warn(`Failed to register custom layout ${id}:`, error instanceof Error ? error.message : error);
152
- }
153
- }
154
- }
155
- loadAllLayouts() {
156
- const layoutsDir = this.options.templatesPath;
157
- if (!(0, fs_1.existsSync)(layoutsDir)) {
158
- throw new types_1.LayoutLoadError(`Templates directory not found: ${layoutsDir}`, undefined, new Error(`Directory does not exist: ${layoutsDir}`));
159
- }
160
- try {
161
- const files = (0, fs_1.readdirSync)(layoutsDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
162
- if (files.length === 0) {
163
- console.warn(`No layout files found in ${layoutsDir}`);
164
- }
165
- for (const file of files) {
166
- const layoutName = file.replace(/\.(yaml|yml)$/, '');
167
- const layoutPath = path.join(layoutsDir, file);
168
- try {
169
- const layout = this.loadLayoutFile(layoutPath, layoutName);
170
- const layoutId = `crewx/${layoutName}`;
171
- this.layouts.set(layoutId, layout);
172
- if (layoutId !== 'crewx/minimal') {
173
- if (process.env.CREWX_VERBOSE === '1')
174
- console.error(`Loaded layout: ${layoutId} from ${file}`);
175
- }
176
- }
177
- catch (error) {
178
- console.error(`Failed to load layout file ${file}:`, error);
179
- }
180
- }
181
- if (process.env.CREWX_VERBOSE === '1')
182
- console.error(`Loaded ${this.layouts.size} layouts from ${layoutsDir}`);
183
- }
184
- catch (error) {
185
- throw new types_1.LayoutLoadError(`Failed to read layouts directory: ${layoutsDir}`, undefined, error instanceof Error ? error : new Error(String(error)));
186
- }
187
- }
188
- loadLayoutFile(filePath, layoutName) {
189
- try {
190
- const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
191
- if (!content || content.trim().length === 0) {
192
- console.warn(`Empty YAML file: ${filePath}, will use fallback`);
193
- throw new types_1.LayoutLoadError(`Empty YAML file: ${filePath}`, layoutName, new Error('File content is empty'));
194
- }
195
- const parsed = (0, js_yaml_1.load)(content);
196
- if (!parsed || typeof parsed !== 'object') {
197
- console.warn(`Invalid YAML content in ${filePath} (parsed as ${typeof parsed}), will use fallback`);
198
- throw new types_1.LayoutLoadError(`Invalid or empty YAML in ${filePath}`, layoutName, new Error('YAML parsing returned null/undefined or non-object'));
199
- }
200
- // Format 2: layouts map (templates/agents/default.yaml format)
201
- if (parsed.layouts && typeof parsed.layouts === 'object') {
202
- const entry = this.resolveLayoutEntry(parsed.layouts, layoutName);
203
- if (!entry || entry.template.trim().length === 0) {
204
- console.warn(`Empty or missing layout template in ${filePath} for ${layoutName}`);
205
- throw new types_1.LayoutLoadError(`Layout template not found or empty in layouts map: ${layoutName}`, layoutName);
206
- }
207
- // propsSchema may be inline in the layout entry object (e.g. default.yaml) or at the top level
208
- const propsSchemaRaw = entry.propsSchema || parsed.propsSchema || {};
209
- return {
210
- id: `crewx/${layoutName}`,
211
- version: parsed.version || '1.0.0',
212
- description: parsed.description || `CrewX ${layoutName} layout`,
213
- template: entry.template,
214
- propsSchema: this.parsePropsSchema(propsSchemaRaw),
215
- defaultProps: this.extractDefaultProps(propsSchemaRaw),
216
- };
217
- }
218
- else {
219
- // Format 1: direct layout definition
220
- if (!parsed.template || (typeof parsed.template === 'string' && parsed.template.trim().length === 0)) {
221
- console.warn(`Empty or missing template field in ${filePath}`);
222
- throw new types_1.LayoutLoadError(`Layout template is missing or empty in ${filePath}`, layoutName);
223
- }
224
- return {
225
- id: parsed.id || `crewx/${layoutName}`,
226
- version: parsed.version || '1.0.0',
227
- description: parsed.description || '',
228
- template: parsed.template,
229
- propsSchema: this.parsePropsSchema(parsed.propsSchema || {}),
230
- defaultProps: this.extractDefaultProps(parsed.propsSchema || {}),
231
- };
232
- }
233
- }
234
- catch (error) {
235
- throw new types_1.LayoutLoadError(`Failed to load layout file: ${filePath}`, layoutName, error instanceof Error ? error : new Error(String(error)));
236
- }
237
- }
238
- parsePropsSchema(raw) {
239
- const schema = {};
240
- for (const [key, value] of Object.entries(raw)) {
241
- if (typeof value === 'object' && value !== null) {
242
- schema[key] = value;
243
- }
244
- }
245
- return schema;
246
- }
247
- extractDefaultProps(propsSchema) {
248
- const defaults = {};
249
- for (const [key, schema] of Object.entries(propsSchema)) {
250
- if (schema && typeof schema === 'object') {
251
- if ('defaultValue' in schema) {
252
- defaults[key] = schema.defaultValue;
253
- }
254
- else if ('default' in schema) {
255
- defaults[key] = schema.default;
256
- }
257
- }
258
- }
259
- return defaults;
260
- }
261
- normalizeLayoutId(layoutId) {
262
- if (!layoutId)
263
- return this.options.fallbackLayoutId;
264
- if (layoutId.includes('/'))
265
- return layoutId;
266
- return `crewx/${layoutId}`;
267
- }
268
- resolveLayoutEntry(layoutsMap, layoutName) {
269
- const candidates = new Set();
270
- if (layoutName) {
271
- candidates.add(layoutName);
272
- if (layoutName.includes('/')) {
273
- const parts = layoutName.split('/');
274
- const last = parts[parts.length - 1];
275
- if (last)
276
- candidates.add(last);
277
- }
278
- else {
279
- candidates.add(`crewx/${layoutName}`);
280
- }
281
- }
282
- candidates.add('default');
283
- for (const key of candidates) {
284
- const value = layoutsMap[key];
285
- if (typeof value === 'string' && value.trim().length > 0) {
286
- return { template: value };
287
- }
288
- if (value && typeof value === 'object' && typeof value.template === 'string' && value.template.trim().length > 0) {
289
- return { template: value.template, propsSchema: value.propsSchema };
290
- }
291
- }
292
- for (const value of Object.values(layoutsMap)) {
293
- if (typeof value === 'string' && value.trim().length > 0) {
294
- return { template: value };
295
- }
296
- const v = value;
297
- if (v && typeof v === 'object' && typeof v.template === 'string' && v.template.trim().length > 0) {
298
- return { template: v.template, propsSchema: v.propsSchema };
299
- }
300
- }
301
- return undefined;
302
- }
303
- }
304
- exports.LayoutLoader = LayoutLoader;
305
- //# sourceMappingURL=loader.js.map