deepline 0.3.97 → 0.3.98

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 (36) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +144 -4
  2. package/dist/bundling-sources/sdk/src/index.ts +17 -4
  3. package/dist/bundling-sources/sdk/src/monitor-fleets.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/monitor-input-contract.ts +1 -0
  5. package/dist/bundling-sources/sdk/src/monitors.ts +8 -25
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +1 -0
  8. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +218 -16
  9. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-input-contract.ts +455 -0
  10. package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +6 -1
  11. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +2 -1
  12. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -0
  13. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +19 -3
  15. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +5 -1
  16. package/dist/cli/index.js +1004 -289
  17. package/dist/cli/index.mjs +1004 -289
  18. package/dist/index.d.mts +43 -24
  19. package/dist/index.d.ts +43 -24
  20. package/dist/index.js +604 -41
  21. package/dist/index.mjs +600 -41
  22. package/dist/install-integrity.json +6 -0
  23. package/dist/monitor-fleet-contract.d.mts +44 -8
  24. package/dist/monitor-fleet-contract.d.ts +44 -8
  25. package/dist/monitor-fleet-contract.js +354 -27
  26. package/dist/monitor-fleet-contract.mjs +343 -27
  27. package/dist/monitor-input-contract.d.mts +33 -0
  28. package/dist/monitor-input-contract.d.ts +33 -0
  29. package/dist/monitor-input-contract.js +392 -0
  30. package/dist/monitor-input-contract.mjs +353 -0
  31. package/dist/plays/bundle-play-file.mjs +1 -1
  32. package/dist/release.d.mts +1 -1
  33. package/dist/release.d.ts +1 -1
  34. package/dist/release.js +1 -1
  35. package/dist/release.mjs +1 -1
  36. package/package.json +7 -1
@@ -0,0 +1,353 @@
1
+ // ../integration-contracts/monitor-input-contract.ts
2
+ import Handlebars from "handlebars";
3
+ function authoredMonitorFieldPath(path, field) {
4
+ const batch = /^monitors\.(\d+)$/.exec(path);
5
+ return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
6
+ }
7
+ function record(value) {
8
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
9
+ }
10
+ function json(value, path, issues) {
11
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
12
+ return;
13
+ }
14
+ if (Array.isArray(value)) {
15
+ value.forEach((child, index) => json(child, `${path}.${index}`, issues));
16
+ return;
17
+ }
18
+ const object = record(value);
19
+ if (!object) {
20
+ issues.push({
21
+ severity: "error",
22
+ code: "invalid_monitor_json_value",
23
+ path,
24
+ message: "Monitor values must be JSON values."
25
+ });
26
+ return;
27
+ }
28
+ for (const [key, child] of Object.entries(object)) {
29
+ json(child, `${path}.${key}`, issues);
30
+ }
31
+ }
32
+ function monitorSpec(value, path, issues) {
33
+ const input = record(value);
34
+ if (!input) {
35
+ issues.push({
36
+ severity: "error",
37
+ code: "invalid_monitor_spec",
38
+ path,
39
+ message: "A monitor must be a JSON object."
40
+ });
41
+ return null;
42
+ }
43
+ const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
44
+ for (const key2 of Object.keys(input)) {
45
+ if (!allowed.has(key2)) {
46
+ if (key2 === "controls") {
47
+ issues.push({
48
+ severity: "error",
49
+ code: "CONTROLS_NOT_SUPPORTED",
50
+ path: authoredMonitorFieldPath(path, "controls"),
51
+ message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
52
+ suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
53
+ });
54
+ continue;
55
+ }
56
+ if (key2 === "play") {
57
+ issues.push({
58
+ severity: "error",
59
+ code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
60
+ path: authoredMonitorFieldPath(path, "play"),
61
+ message: "A monitor does not own Play bindings.",
62
+ suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
63
+ });
64
+ continue;
65
+ }
66
+ issues.push({
67
+ severity: "error",
68
+ code: "unknown_monitor_field",
69
+ path: `${path}.${key2}`,
70
+ message: `Monitor definitions do not accept '${key2}'.`
71
+ });
72
+ }
73
+ }
74
+ const key = typeof input.key === "string" ? input.key.trim() : "";
75
+ const tool = typeof input.tool === "string" ? input.tool.trim() : "";
76
+ const name = input.name === void 0 ? void 0 : typeof input.name === "string" && input.name.trim() ? input.name.trim() : null;
77
+ const payload = record(input.payload);
78
+ if (!key) {
79
+ issues.push({
80
+ severity: "error",
81
+ code: "invalid_monitor_key",
82
+ path: `${path}.key`,
83
+ message: "Monitor key must be a non-empty string."
84
+ });
85
+ }
86
+ if (!tool) {
87
+ issues.push({
88
+ severity: "error",
89
+ code: "invalid_monitor_tool",
90
+ path: `${path}.tool`,
91
+ message: "Monitor tool must be a non-empty literal string."
92
+ });
93
+ }
94
+ if (name === null) {
95
+ issues.push({
96
+ severity: "error",
97
+ code: "invalid_monitor_name",
98
+ path: `${path}.name`,
99
+ message: "Monitor name must be a non-empty string when supplied."
100
+ });
101
+ }
102
+ if (!payload) {
103
+ issues.push({
104
+ severity: "error",
105
+ code: "invalid_monitor_payload",
106
+ path: `${path}.payload`,
107
+ message: "Monitor payload must be an object."
108
+ });
109
+ } else {
110
+ json(payload, `${path}.payload`, issues);
111
+ }
112
+ if (!key || !tool || !payload || name === null) {
113
+ return null;
114
+ }
115
+ return {
116
+ key,
117
+ tool,
118
+ ...name ? { name } : {},
119
+ payload
120
+ };
121
+ }
122
+ function issueOrder(left, right) {
123
+ return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
124
+ }
125
+ function lintMonitorBatchInput(value) {
126
+ const issues = [];
127
+ const versionlessEnvelope = !Array.isArray(value) && (() => {
128
+ const candidate = record(value);
129
+ return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
130
+ })();
131
+ const legacy = Array.isArray(value) || versionlessEnvelope;
132
+ const input = legacy ? null : record(value);
133
+ let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
134
+ const candidate = record(value)?.monitors;
135
+ return Array.isArray(candidate) ? candidate : null;
136
+ })() : null;
137
+ if (Array.isArray(value)) {
138
+ issues.push({
139
+ severity: "warning",
140
+ code: "deprecated_batch_array",
141
+ path: "",
142
+ message: "Bare monitor arrays are supported for compatibility.",
143
+ suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
144
+ });
145
+ } else if (versionlessEnvelope) {
146
+ issues.push({
147
+ severity: "warning",
148
+ code: "deprecated_batch_missing_envelope_fields",
149
+ path: "",
150
+ message: "Versionless monitor envelopes are supported for compatibility.",
151
+ suggestion: 'Add "version": 1 and "kind": "batch".'
152
+ });
153
+ if (!monitors) {
154
+ issues.push({
155
+ severity: "error",
156
+ code: "invalid_batch_monitors",
157
+ path: "monitors",
158
+ message: "Batch monitors must be an array."
159
+ });
160
+ }
161
+ } else if (!input) {
162
+ issues.push({
163
+ severity: "error",
164
+ code: "invalid_batch",
165
+ path: "",
166
+ message: "Batch input must be an object or a legacy array."
167
+ });
168
+ } else {
169
+ for (const key of Object.keys(input)) {
170
+ if (!["version", "kind", "monitors"].includes(key)) {
171
+ issues.push({
172
+ severity: "error",
173
+ code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
174
+ path: key,
175
+ message: `Batch input does not accept '${key}'.`
176
+ });
177
+ }
178
+ }
179
+ if (input.version !== 1) {
180
+ issues.push({
181
+ severity: "error",
182
+ code: "unsupported_batch_version",
183
+ path: "version",
184
+ message: "Batch input version must be 1."
185
+ });
186
+ }
187
+ if (input.kind !== "batch") {
188
+ issues.push({
189
+ severity: "error",
190
+ code: "invalid_batch_kind",
191
+ path: "kind",
192
+ message: 'Batch input kind must be "batch".'
193
+ });
194
+ }
195
+ monitors = Array.isArray(input.monitors) ? input.monitors : null;
196
+ if (!monitors) {
197
+ issues.push({
198
+ severity: "error",
199
+ code: "invalid_batch_monitors",
200
+ path: "monitors",
201
+ message: "Batch monitors must be an array."
202
+ });
203
+ }
204
+ }
205
+ if (!monitors || monitors.length === 0) {
206
+ if (monitors?.length === 0) {
207
+ issues.push({
208
+ severity: "error",
209
+ code: "empty_batch",
210
+ path: "monitors",
211
+ message: "A Batch needs at least one monitor."
212
+ });
213
+ }
214
+ return { issues: issues.sort(issueOrder) };
215
+ }
216
+ const normalized = monitors.map(
217
+ (item, index) => monitorSpec(item, `monitors.${index}`, issues)
218
+ );
219
+ const seen = /* @__PURE__ */ new Map();
220
+ normalized.forEach((item, index) => {
221
+ if (!item) return;
222
+ const first = seen.get(item.key);
223
+ if (first !== void 0) {
224
+ for (const position of [first, index]) {
225
+ issues.push({
226
+ severity: "error",
227
+ code: "duplicate_monitor_key",
228
+ path: `monitors.${position}.key`,
229
+ message: `Duplicate monitor key '${item.key}'.`
230
+ });
231
+ }
232
+ } else {
233
+ seen.set(item.key, index);
234
+ }
235
+ });
236
+ const ordered = issues.sort(issueOrder);
237
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
238
+ normalized: {
239
+ version: 1,
240
+ kind: "batch",
241
+ monitors: normalized
242
+ },
243
+ issues: ordered
244
+ };
245
+ }
246
+ function validateHandlebars(value, path, issues) {
247
+ if (!value.includes("{{")) return;
248
+ try {
249
+ Handlebars.parse(value);
250
+ } catch (error) {
251
+ issues.push({
252
+ severity: "error",
253
+ code: "invalid_handlebars_template",
254
+ path,
255
+ message: error instanceof Error ? error.message : "Invalid Handlebars template."
256
+ });
257
+ return;
258
+ }
259
+ const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
260
+ if (expressions.some(
261
+ (expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
262
+ )) {
263
+ issues.push({
264
+ severity: "error",
265
+ code: "unsupported_handlebars_expression",
266
+ path,
267
+ message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
268
+ });
269
+ }
270
+ }
271
+ function walkTemplates(value, path, issues) {
272
+ if (typeof value === "string") return validateHandlebars(value, path, issues);
273
+ if (Array.isArray(value)) {
274
+ value.forEach(
275
+ (item, index) => walkTemplates(item, `${path}.${index}`, issues)
276
+ );
277
+ return;
278
+ }
279
+ const input = record(value);
280
+ if (!input) return;
281
+ for (const [key, child] of Object.entries(input)) {
282
+ walkTemplates(child, `${path}.${key}`, issues);
283
+ }
284
+ }
285
+ function lintMonitorSpecTemplate(value, path = "monitor") {
286
+ const issues = [];
287
+ const normalized = monitorSpec(value, path, issues);
288
+ const input = record(value);
289
+ if (input && typeof input.tool === "string" && input.tool.includes("{{")) {
290
+ issues.push({
291
+ severity: "error",
292
+ code: "templated_monitor_tool",
293
+ path: `${path}.tool`,
294
+ message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
295
+ });
296
+ }
297
+ if (input) {
298
+ for (const field of ["key", "name", "payload"]) {
299
+ if (input[field] !== void 0)
300
+ walkTemplates(input[field], `${path}.${field}`, issues);
301
+ }
302
+ }
303
+ const ordered = issues.sort(issueOrder);
304
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
305
+ }
306
+ function renderValue(value, row) {
307
+ if (typeof value === "string" && value.includes("{{")) {
308
+ const context = Object.assign(/* @__PURE__ */ Object.create(null), row);
309
+ return Handlebars.compile(value, {
310
+ noEscape: true,
311
+ strict: true,
312
+ knownHelpersOnly: true,
313
+ preventIndent: true
314
+ })(context, {
315
+ allowProtoMethodsByDefault: false,
316
+ allowProtoPropertiesByDefault: false,
317
+ helpers: /* @__PURE__ */ Object.create(null),
318
+ partials: /* @__PURE__ */ Object.create(null)
319
+ });
320
+ }
321
+ if (Array.isArray(value)) return value.map((item) => renderValue(item, row));
322
+ const input = record(value);
323
+ if (!input) return value;
324
+ return Object.fromEntries(
325
+ Object.entries(input).map(([key, item]) => [key, renderValue(item, row)])
326
+ );
327
+ }
328
+ function renderMonitorSpecTemplate(template, row) {
329
+ const lint = lintMonitorSpecTemplate(template);
330
+ if (!lint.normalized) return { issues: lint.issues };
331
+ try {
332
+ const rendered = renderValue(lint.normalized, row);
333
+ const issues = [];
334
+ const spec = monitorSpec(rendered, "monitor", issues);
335
+ return spec ? { spec, issues: issues.sort(issueOrder) } : { issues: issues.sort(issueOrder) };
336
+ } catch (error) {
337
+ return {
338
+ issues: [
339
+ {
340
+ severity: "error",
341
+ code: "monitor_template_render_failed",
342
+ path: "monitor",
343
+ message: error instanceof Error ? error.message : "Fleet template rendering failed."
344
+ }
345
+ ]
346
+ };
347
+ }
348
+ }
349
+ export {
350
+ lintMonitorBatchInput,
351
+ lintMonitorSpecTemplate,
352
+ renderMonitorSpecTemplate
353
+ };
@@ -3887,7 +3887,7 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
3887
3887
  name: "deepline-imported-play-proxy",
3888
3888
  setup(buildContext) {
3889
3889
  buildContext.onResolve({ filter: /.*/ }, async (args) => {
3890
- if (!args.importer || !isLocalSpecifier(args.path)) {
3890
+ if (!args.importer || !isLocalSpecifier(args.path) || args.importer.split(/[\\/]+/).includes("node_modules")) {
3891
3891
  return null;
3892
3892
  }
3893
3893
  const resolvedPath = await resolveLocalImport(args.importer, args.path);
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.97";
152
+ readonly version: "0.3.98";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.97";
152
+ readonly version: "0.3.98";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.97",
77
+ version: "0.3.98",
78
78
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.97",
51
+ version: "0.3.98",
52
52
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.97",
3
+ "version": "0.3.98",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",
@@ -26,6 +26,11 @@
26
26
  "import": "./dist/monitor-fleet-contract.mjs",
27
27
  "require": "./dist/monitor-fleet-contract.js"
28
28
  },
29
+ "./monitor-input-contract": {
30
+ "types": "./dist/monitor-input-contract.d.ts",
31
+ "import": "./dist/monitor-input-contract.mjs",
32
+ "require": "./dist/monitor-input-contract.js"
33
+ },
29
34
  "./release": {
30
35
  "types": "./dist/release.d.ts",
31
36
  "import": "./dist/release.mjs",
@@ -65,6 +70,7 @@
65
70
  "commander": "^14.0.3",
66
71
  "csv-parse": "^5.6.0",
67
72
  "csv-stringify": "^6.5.0",
73
+ "handlebars": "4.7.8",
68
74
  "undici": "^6.22.0"
69
75
  },
70
76
  "optionalDependencies": {