deepline 0.3.294 → 0.3.296

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 (138) hide show
  1. package/dist/bundling-sources/sdk/src/compat.ts +35 -7
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +108 -35
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +25 -0
  5. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +14 -1
  6. package/dist/cli/auth-JCGIDVDF.mjs +31 -0
  7. package/dist/cli/auth-QDWV3TXX.js +31 -0
  8. package/dist/cli/billing-OQBSIXRG.mjs +1749 -0
  9. package/dist/cli/billing-YBK3J4WP.js +1749 -0
  10. package/dist/cli/chunk-2C3AVPTY.js +5688 -0
  11. package/dist/cli/chunk-2MZ5EQZE.mjs +499 -0
  12. package/dist/cli/chunk-3KC45UVF.js +150 -0
  13. package/dist/cli/chunk-3XX5TEA4.js +15 -0
  14. package/dist/cli/chunk-4MBOJQPL.mjs +0 -0
  15. package/dist/cli/chunk-4Y6CG4GE.js +2240 -0
  16. package/dist/cli/chunk-4ZB3CJRD.js +1269 -0
  17. package/dist/cli/chunk-5JLQPVNX.js +3056 -0
  18. package/dist/cli/chunk-6A3TJUWC.js +76 -0
  19. package/dist/cli/chunk-6HPEDBSJ.js +1995 -0
  20. package/dist/cli/chunk-7D6QG5KF.js +890 -0
  21. package/dist/cli/chunk-7P5AA3SN.js +344 -0
  22. package/dist/cli/chunk-7UAO5MWV.mjs +190 -0
  23. package/dist/cli/chunk-A7427JJH.js +190 -0
  24. package/dist/cli/chunk-AQRTLPHZ.js +735 -0
  25. package/dist/cli/chunk-AYHLUHE5.js +52 -0
  26. package/dist/cli/chunk-BZ77OTRF.mjs +923 -0
  27. package/dist/cli/chunk-CBVIJSHF.mjs +560 -0
  28. package/dist/cli/chunk-COGTRVWW.js +30 -0
  29. package/dist/cli/chunk-DLIRSHV6.mjs +28 -0
  30. package/dist/cli/chunk-DYWHXO7O.mjs +34 -0
  31. package/dist/cli/chunk-EDWJY6T4.mjs +3056 -0
  32. package/dist/cli/chunk-EXMLR72R.mjs +0 -0
  33. package/dist/cli/chunk-G46HHFNB.mjs +1269 -0
  34. package/dist/cli/chunk-GAMFK2ZP.mjs +148 -0
  35. package/dist/cli/chunk-GLKUGBTP.mjs +2240 -0
  36. package/dist/cli/chunk-GONRLVV3.js +3440 -0
  37. package/dist/cli/chunk-GVUJJJ5G.mjs +76 -0
  38. package/dist/cli/chunk-H7HIDGZ7.mjs +150 -0
  39. package/dist/cli/chunk-HUZXWOSK.mjs +503 -0
  40. package/dist/cli/chunk-I5YZLGMG.js +1 -0
  41. package/dist/cli/chunk-ITOFSXIU.mjs +15 -0
  42. package/dist/cli/chunk-J2D3VDOU.mjs +5688 -0
  43. package/dist/cli/chunk-J5NA2TTX.js +503 -0
  44. package/dist/cli/chunk-JCS5TPNY.mjs +3440 -0
  45. package/dist/cli/chunk-JNNOCMQY.js +47 -0
  46. package/dist/cli/chunk-KRD6H754.mjs +30 -0
  47. package/dist/cli/chunk-L4HBNHFW.js +34 -0
  48. package/dist/cli/chunk-LA46MMTL.js +560 -0
  49. package/dist/cli/chunk-LIKFCE7Z.js +190 -0
  50. package/dist/cli/chunk-MIMASXO4.mjs +389 -0
  51. package/dist/cli/chunk-NPPJX3BL.mjs +1995 -0
  52. package/dist/cli/chunk-NTEZFZLE.mjs +890 -0
  53. package/dist/cli/chunk-NXDRDJ4K.js +389 -0
  54. package/dist/cli/chunk-NXGCO4JB.mjs +344 -0
  55. package/dist/cli/chunk-OG64RBAC.js +6 -0
  56. package/dist/cli/chunk-OWJZUE3Y.mjs +103 -0
  57. package/dist/cli/chunk-QSIO4TX2.mjs +190 -0
  58. package/dist/cli/chunk-RCUE5C5C.mjs +735 -0
  59. package/dist/cli/chunk-SDK3ZA2C.js +103 -0
  60. package/dist/cli/chunk-SFLARO4Y.mjs +47 -0
  61. package/dist/cli/chunk-TAC3JIFE.mjs +354 -0
  62. package/dist/cli/chunk-UC6GHEL4.js +499 -0
  63. package/dist/cli/chunk-UFS752TU.mjs +52 -0
  64. package/dist/cli/chunk-UNEMDKXN.js +1 -0
  65. package/dist/cli/chunk-WB6Z2Q44.mjs +1622 -0
  66. package/dist/cli/chunk-WJYPBHTE.js +148 -0
  67. package/dist/cli/chunk-WOHBA5PV.js +354 -0
  68. package/dist/cli/chunk-WZYKRD7T.mjs +6 -0
  69. package/dist/cli/chunk-XNYIZMNQ.js +28 -0
  70. package/dist/cli/chunk-ZDO3TO3M.js +1622 -0
  71. package/dist/cli/chunk-ZDOC4HFL.js +923 -0
  72. package/dist/cli/client-CZDA4JKO.mjs +20 -0
  73. package/dist/cli/client-IZGIN2ZA.js +20 -0
  74. package/dist/cli/csv-6KOMZA2H.mjs +585 -0
  75. package/dist/cli/csv-UTEQY3NA.js +585 -0
  76. package/dist/cli/db-D5EP6TKO.mjs +486 -0
  77. package/dist/cli/db-SIBLPIKC.js +486 -0
  78. package/dist/cli/executions-2PHT57IO.js +28 -0
  79. package/dist/cli/executions-DFWM2YYY.mjs +28 -0
  80. package/dist/cli/feedback-GZW37JMI.mjs +107 -0
  81. package/dist/cli/feedback-IQVWIJZ4.js +107 -0
  82. package/dist/cli/getting-started.js +18 -76
  83. package/dist/cli/getting-started.mjs +10 -37
  84. package/dist/cli/git-563GYLMA.js +23 -0
  85. package/dist/cli/git-B72Y4FFQ.mjs +23 -0
  86. package/dist/cli/index.js +291 -54294
  87. package/dist/cli/index.mjs +209 -54352
  88. package/dist/cli/legacy-noops-37F5MX2P.mjs +157 -0
  89. package/dist/cli/legacy-noops-IFGVDCOM.js +157 -0
  90. package/dist/cli/monitors-42H6LOVT.mjs +3251 -0
  91. package/dist/cli/monitors-GQCHXBXZ.js +3251 -0
  92. package/dist/cli/org-4GCPBTGR.js +849 -0
  93. package/dist/cli/org-JYZA3ZRJ.mjs +849 -0
  94. package/dist/cli/play-46ZJ4FMI.js +18439 -0
  95. package/dist/cli/play-Q2XV3FZZ.mjs +18439 -0
  96. package/dist/cli/providers-CTKQP45X.mjs +95 -0
  97. package/dist/cli/providers-PCNF5E3K.js +95 -0
  98. package/dist/cli/proxy-env-EBANZHPV.js +161 -0
  99. package/dist/cli/proxy-env-M4ZHXHRL.mjs +161 -0
  100. package/dist/cli/quickstart-FTHWRVWN.js +69 -0
  101. package/dist/cli/quickstart-X7EVVWRG.mjs +69 -0
  102. package/dist/cli/search-73YPOFDO.mjs +18 -0
  103. package/dist/cli/search-XA5UVC3G.js +18 -0
  104. package/dist/cli/secrets-OUMPT4FX.mjs +400 -0
  105. package/dist/cli/secrets-UOEVR73Q.js +400 -0
  106. package/dist/cli/sessions-CMKXCN5Y.js +15 -0
  107. package/dist/cli/sessions-ZIFGDZE7.mjs +15 -0
  108. package/dist/cli/settings-OO5R3G52.mjs +846 -0
  109. package/dist/cli/settings-ULZT2NIC.js +846 -0
  110. package/dist/cli/setup-6GZH52OZ.mjs +1257 -0
  111. package/dist/cli/setup-DHGERXPZ.js +1257 -0
  112. package/dist/cli/skills-Q7NUCS2W.js +28 -0
  113. package/dist/cli/skills-T3EY2656.mjs +28 -0
  114. package/dist/cli/tools-BIMOAOTX.mjs +2955 -0
  115. package/dist/cli/tools-ODXVCKO7.js +2955 -0
  116. package/dist/cli/update-UMB3ULBR.js +28 -0
  117. package/dist/cli/update-X4HX7Z3M.mjs +28 -0
  118. package/dist/cli/workflow-EAUFVPIP.mjs +1936 -0
  119. package/dist/cli/workflow-IVLCPFTG.js +1936 -0
  120. package/dist/helpers.js +6 -32
  121. package/dist/helpers.mjs +2 -0
  122. package/dist/index.js +1972 -12825
  123. package/dist/index.mjs +1910 -12672
  124. package/dist/install-integrity.json +110 -0
  125. package/dist/monitor-fleet-contract.js +31 -730
  126. package/dist/monitor-fleet-contract.mjs +18 -667
  127. package/dist/monitor-input-contract.js +10 -390
  128. package/dist/monitor-input-contract.mjs +7 -348
  129. package/dist/plays/bundle-play-file.mjs +13 -5178
  130. package/dist/plays/csv-data-input.js +5 -3132
  131. package/dist/plays/csv-data-input.mjs +5 -3105
  132. package/dist/plays/run-request.js +56 -664
  133. package/dist/plays/run-request.mjs +30 -588
  134. package/dist/release.d.mts +1 -1
  135. package/dist/release.d.ts +1 -1
  136. package/dist/release.js +5 -212
  137. package/dist/release.mjs +5 -185
  138. package/package.json +1 -1
@@ -0,0 +1,103 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// ../plays/bootstrap-routes.ts
2
+ var DEEPLINE_TOOL_CATEGORIES = [
3
+ "company_search",
4
+ "people_search",
5
+ "people_enrich",
6
+ "email_finder",
7
+ "email_verify",
8
+ "phone_finder",
9
+ "phone_verify",
10
+ "identity_resolution",
11
+ "reverse_lookup",
12
+ "enrichment",
13
+ "batch",
14
+ "premium",
15
+ "free"
16
+ ];
17
+ var PLAY_BOOTSTRAP_TEMPLATES = [
18
+ "people-list",
19
+ "company-list",
20
+ "people-email",
21
+ "people-phone",
22
+ "company-people",
23
+ "company-people-email",
24
+ "company-people-phone"
25
+ ];
26
+ var PLAY_BOOTSTRAP_SOURCE_KINDS = [
27
+ "csv",
28
+ "play",
29
+ "provider",
30
+ "providers"
31
+ ];
32
+ var PLAY_BOOTSTRAP_STAGE_KINDS = [
33
+ "play",
34
+ "provider",
35
+ "providers"
36
+ ];
37
+ var PLAY_BOOTSTRAP_FINDER_KINDS = [
38
+ "email_finder",
39
+ "phone_finder"
40
+ ];
41
+ var PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY = "company_search";
42
+ var PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY = "people_search";
43
+ var PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER = {
44
+ email_finder: "email_finder",
45
+ phone_finder: "phone_finder"
46
+ };
47
+ var PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER = {
48
+ email_finder: "email",
49
+ phone_finder: "phone"
50
+ };
51
+ var PLAY_BOOTSTRAP_CONTACT_FIELDS = [
52
+ "first_name",
53
+ "last_name",
54
+ "domain",
55
+ "company_name",
56
+ "linkedin_url",
57
+ "title",
58
+ "email",
59
+ "phone"
60
+ ];
61
+ var PLAY_BOOTSTRAP_COMPANY_FIELDS = [
62
+ "domain",
63
+ "company_domain",
64
+ "company_name",
65
+ "linkedin_url",
66
+ "website"
67
+ ];
68
+ function isPlayBootstrapFinderKind(value) {
69
+ return PLAY_BOOTSTRAP_FINDER_KINDS.includes(value);
70
+ }
71
+ function isPlayBootstrapTemplate(value) {
72
+ return PLAY_BOOTSTRAP_TEMPLATES.includes(value);
73
+ }
74
+ function formatPlayBootstrapFinderKinds() {
75
+ return PLAY_BOOTSTRAP_FINDER_KINDS.join("|");
76
+ }
77
+ function formatPlayBootstrapTemplates() {
78
+ return PLAY_BOOTSTRAP_TEMPLATES.join("|");
79
+ }
80
+ function formatPlayBootstrapFinderKindsForSentence() {
81
+ const allButLast = PLAY_BOOTSTRAP_FINDER_KINDS.slice(0, -1);
82
+ const last = PLAY_BOOTSTRAP_FINDER_KINDS.at(-1);
83
+ return `${allButLast.join(", ")} or ${last}`;
84
+ }
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ exports.DEEPLINE_TOOL_CATEGORIES = DEEPLINE_TOOL_CATEGORIES; exports.PLAY_BOOTSTRAP_TEMPLATES = PLAY_BOOTSTRAP_TEMPLATES; exports.PLAY_BOOTSTRAP_SOURCE_KINDS = PLAY_BOOTSTRAP_SOURCE_KINDS; exports.PLAY_BOOTSTRAP_STAGE_KINDS = PLAY_BOOTSTRAP_STAGE_KINDS; exports.PLAY_BOOTSTRAP_FINDER_KINDS = PLAY_BOOTSTRAP_FINDER_KINDS; exports.PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY = PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY; exports.PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY = PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY; exports.PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER = PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER; exports.PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER; exports.PLAY_BOOTSTRAP_CONTACT_FIELDS = PLAY_BOOTSTRAP_CONTACT_FIELDS; exports.PLAY_BOOTSTRAP_COMPANY_FIELDS = PLAY_BOOTSTRAP_COMPANY_FIELDS; exports.isPlayBootstrapFinderKind = isPlayBootstrapFinderKind; exports.isPlayBootstrapTemplate = isPlayBootstrapTemplate; exports.formatPlayBootstrapFinderKinds = formatPlayBootstrapFinderKinds; exports.formatPlayBootstrapTemplates = formatPlayBootstrapTemplates; exports.formatPlayBootstrapFinderKindsForSentence = formatPlayBootstrapFinderKindsForSentence;
@@ -0,0 +1,47 @@
1
+ // src/cli/getting-started.ts
2
+ var DEEPLINE_GTM_SKILL = "/deepline-gtm";
3
+ var DEEPLINE_GTM_STARTER_PROMPTS = [
4
+ {
5
+ id: "competitor-tracking",
6
+ title: "Competitor tracking",
7
+ prompt: "/deepline-gtm Track competitors of my company. Use my business email domain when available; otherwise ask for my company name."
8
+ },
9
+ {
10
+ id: "contact-email-enrichment",
11
+ title: "Contact email enrichment",
12
+ prompt: "/deepline-gtm Find 10 CTOs at B2B SaaS companies and enrich them with email addresses."
13
+ },
14
+ {
15
+ // Historical ID retained for SDK payload compatibility; the current
16
+ // starter copy is the fintech hiring-and-growth workflow below.
17
+ id: "decision-maker-discovery",
18
+ title: "Fintech hiring and growth",
19
+ prompt: "/deepline-gtm Find five fintech companies with live SDR openings and six-month headcount growth. Show dated evidence for both."
20
+ }
21
+ ];
22
+ var DEEPLINE_GTM_PRIMARY_STARTER_PROMPT = DEEPLINE_GTM_STARTER_PROMPTS[0].prompt;
23
+ var DEEPLINE_GTM_HANDOFF_QUESTION = "What would you like to do with Deepline?";
24
+ var DEEPLINE_GTM_CUSTOM_OPTION = "Tell me what you want to accomplish and I'll help you build it";
25
+ var DEEPLINE_GTM_STARTER_OPTIONS = [
26
+ ...DEEPLINE_GTM_STARTER_PROMPTS.map(({ prompt }) => prompt),
27
+ DEEPLINE_GTM_CUSTOM_OPTION
28
+ ];
29
+ function deeplineGtmGettingStartedPayload() {
30
+ return {
31
+ skill: DEEPLINE_GTM_SKILL,
32
+ examples: DEEPLINE_GTM_STARTER_PROMPTS,
33
+ question: DEEPLINE_GTM_HANDOFF_QUESTION,
34
+ customOption: DEEPLINE_GTM_CUSTOM_OPTION,
35
+ customProblemBehavior: "Turn the business problem into one exact /deepline-gtm prompt, show that reusable prompt, then execute it without asking the user to paste it again."
36
+ };
37
+ }
38
+
39
+ export {
40
+ DEEPLINE_GTM_SKILL,
41
+ DEEPLINE_GTM_STARTER_PROMPTS,
42
+ DEEPLINE_GTM_PRIMARY_STARTER_PROMPT,
43
+ DEEPLINE_GTM_HANDOFF_QUESTION,
44
+ DEEPLINE_GTM_CUSTOM_OPTION,
45
+ DEEPLINE_GTM_STARTER_OPTIONS,
46
+ deeplineGtmGettingStartedPayload
47
+ };
@@ -0,0 +1,354 @@
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
+
350
+ export {
351
+ lintMonitorBatchInput,
352
+ lintMonitorSpecTemplate,
353
+ renderMonitorSpecTemplate
354
+ };