@commandgarden/cli 1.2.1 → 1.2.3

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.
package/dist/main.js CHANGED
@@ -17006,7 +17006,7 @@ async function executeDaemonStart(baseUrl, cgHome, daemonScript) {
17006
17006
  const logPath = join2(cgHome, "daemon.log");
17007
17007
  console.error("Starting daemon...");
17008
17008
  const logFd = openSync(logPath, "a");
17009
- const child = spawn("node", [daemonScript], { detached: true, stdio: ["ignore", logFd, logFd] });
17009
+ const child = spawn("node", [daemonScript], { detached: true, stdio: ["ignore", logFd, logFd], cwd: cgHome });
17010
17010
  closeSync(logFd);
17011
17011
  let spawnFailed = false;
17012
17012
  child.on("error", () => {
@@ -0,0 +1,338 @@
1
+ // Runs in page context via js_evaluate step.
2
+ // Drives the Outlook Scheduling Assistant to fetch a meeting-room's free/busy
3
+ // timeline for a single day. Strategy: reuse the authenticated browser session,
4
+ // drive the UI to trigger the page's own GraphQL getSchedule call, and intercept
5
+ // the response (the endpoint 401s on replay).
6
+ //
7
+ // Template variables interpolated before execution:
8
+ // ${{ args.room }}
9
+ // ${{ args.date | default("") }}
10
+
11
+ const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June',
12
+ 'July', 'August', 'September', 'October', 'November', 'December'];
13
+ const DATE_RE = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
14
+ const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
15
+
16
+ function pad2(n) { return String(n).padStart(2, '0'); }
17
+ function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
18
+
19
+ function todayLocalISO() {
20
+ const d = new Date();
21
+ return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
22
+ }
23
+
24
+ /** "2026-06-18" -> "18, June, 2026" (matches the OWA date-cell aria-label). */
25
+ function dateCellLabel(iso) {
26
+ const [y, m, d] = iso.split('-').map(Number);
27
+ return `${d}, ${MONTHS[m - 1]}, ${y}`;
28
+ }
29
+
30
+ /** querySelector shorthand, returns null if not found. */
31
+ function $(sel) { return document.querySelector(sel); }
32
+
33
+ /** True when an element matching the selector exists. */
34
+ function exists(sel) { return !!$(sel); }
35
+
36
+ /**
37
+ * Click a button/link by accessible name (aria-label OR visible text).
38
+ * Returns true if an element was found and clicked.
39
+ */
40
+ function clickByName(name) {
41
+ const els = Array.from(document.querySelectorAll('button,a,[role=button]'));
42
+ const el = els.find(e => {
43
+ if (!e.offsetParent) return false;
44
+ const al = (e.getAttribute('aria-label') || '').trim();
45
+ const tx = (e.textContent || '').replace(/\s+/g, ' ').trim();
46
+ return al === name || al.includes(name) || tx.includes(name);
47
+ });
48
+ if (!el) return false;
49
+ el.scrollIntoView({ block: 'center' });
50
+ el.click();
51
+ return true;
52
+ }
53
+
54
+ /** True when the Scheduling Assistant view (with its Start date picker) is rendered. */
55
+ function schedulingAssistantOpen() {
56
+ return Array.from(document.querySelectorAll('input')).some(
57
+ e => (e.getAttribute('aria-label') || '') === 'Start date'
58
+ );
59
+ }
60
+
61
+ /** Type text into an input by selector (focus, set value, dispatch events). */
62
+ function typeText(sel, text) {
63
+ const el = $(sel);
64
+ if (!el) throw new Error(`Element "${sel}" not found for typing`);
65
+ el.focus();
66
+ el.value = text;
67
+ el.dispatchEvent(new Event('input', { bubbles: true }));
68
+ el.dispatchEvent(new Event('change', { bubbles: true }));
69
+ }
70
+
71
+ // ── Fetch interceptor ────────────────────────────────────────────────
72
+ // Captures getSchedule GraphQL responses (the page's own authenticated
73
+ // request — the endpoint 401s on replay).
74
+ if (!window.__rfb) {
75
+ window.__rfb = [];
76
+ const origFetch = window.fetch;
77
+ window.fetch = function () {
78
+ const a = arguments;
79
+ const u = (a[0] && a[0].url) || a[0] || '';
80
+ const rb = (a[1] && a[1].body) || '';
81
+ return origFetch.apply(this, a).then(r => {
82
+ try {
83
+ if (String(u).indexOf('graphql') > -1) {
84
+ r.clone().text().then(t => {
85
+ if (t.indexOf('getSchedule') > -1 && t.indexOf('availabilityView') > -1) {
86
+ window.__rfb.push({ req: String(rb || ''), body: t });
87
+ }
88
+ }).catch(() => {});
89
+ }
90
+ } catch (_e) { /* ignore */ }
91
+ return r;
92
+ });
93
+ };
94
+ }
95
+
96
+ /** Read and clear captured {req, body} pairs. */
97
+ function readCapture() {
98
+ const d = window.__rfb || [];
99
+ window.__rfb = [];
100
+ return d;
101
+ }
102
+
103
+ /** Map of scheduleId (lowercased) -> schedule object from a captured response body. */
104
+ function schedulesFromPair(pair) {
105
+ let body;
106
+ try { body = JSON.parse(pair.body); } catch (_e) { return new Map(); }
107
+ const byId = new Map();
108
+ const nodes = Array.isArray(body) ? body : [body];
109
+ for (const node of nodes) {
110
+ const schedules = node?.data?.getSchedule?.schedules;
111
+ if (Array.isArray(schedules)) {
112
+ for (const s of schedules) {
113
+ if (s?.scheduleId) byId.set(String(s.scheduleId).toLowerCase(), s);
114
+ }
115
+ }
116
+ }
117
+ return byId;
118
+ }
119
+
120
+ /**
121
+ * Build a free/busy timeline (busy/tentative/oof/elsewhere blocks + free gaps)
122
+ * for one local day from getSchedule scheduleItems.
123
+ */
124
+ function buildTimeline(items, dateIso) {
125
+ const PRIORITY = { oof: 4, busy: 3, tentative: 2, elsewhere: 1, free: 0 };
126
+ const mapStatus = st => ({
127
+ Busy: 'busy', Tentative: 'tentative', Oof: 'oof', WorkingElsewhere: 'elsewhere', Free: 'free',
128
+ }[st] || 'busy');
129
+
130
+ const dayStart = new Date(`${dateIso}T00:00:00`);
131
+ const dayEnd = new Date(dayStart.getTime() + 86400000);
132
+ const fmt = ms => {
133
+ if (ms >= dayEnd.getTime()) return '24:00';
134
+ const d = new Date(ms);
135
+ return `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
136
+ };
137
+
138
+ const blocks = [];
139
+ for (const it of items) {
140
+ if (!it || !it.startTime || !it.endTime) continue;
141
+ const s = new Date(it.startTime.dateTime).getTime();
142
+ const e = new Date(it.endTime.dateTime).getTime();
143
+ const cs = Math.max(s, dayStart.getTime());
144
+ const ce = Math.min(e, dayEnd.getTime());
145
+ if (ce > cs) blocks.push({ state: mapStatus(it.status), s: cs, e: ce });
146
+ }
147
+ blocks.sort((a, b) => a.s - b.s);
148
+
149
+ // Merge overlapping/adjacent busy blocks.
150
+ const merged = [];
151
+ for (const b of blocks) {
152
+ const last = merged[merged.length - 1];
153
+ if (last && b.s <= last.e) {
154
+ last.e = Math.max(last.e, b.e);
155
+ if (PRIORITY[b.state] > PRIORITY[last.state]) last.state = b.state;
156
+ } else {
157
+ merged.push({ ...b });
158
+ }
159
+ }
160
+
161
+ const rows = [];
162
+ let cursor = dayStart.getTime();
163
+ for (const b of merged) {
164
+ if (b.s > cursor) rows.push({ state: 'free', s: cursor, e: b.s });
165
+ rows.push({ state: b.state, s: b.s, e: b.e });
166
+ cursor = b.e;
167
+ }
168
+ if (cursor < dayEnd.getTime()) rows.push({ state: 'free', s: cursor, e: dayEnd.getTime() });
169
+
170
+ return rows.map(r => ({
171
+ date: dateIso,
172
+ state: r.state,
173
+ start: fmt(r.s),
174
+ end: fmt(r.e),
175
+ durationMin: Math.round((r.e - r.s) / 60000),
176
+ }));
177
+ }
178
+
179
+ // ── Main flow ────────────────────────────────────────────────────────
180
+
181
+ const room = '${{ args.room }}'.trim();
182
+ if (!room) throw new Error('Missing room argument — pass a room name or email');
183
+ const isEmail = EMAIL_RE.test(room);
184
+
185
+ let date = '${{ args.date | default("") }}'.trim();
186
+ if (!date) date = todayLocalISO();
187
+ if (!DATE_RE.test(date)) throw new Error(`Invalid date "${date}" — use YYYY-MM-DD`);
188
+
189
+ // Wait for compose form controls (handles SSO redirect delays).
190
+ const __deadline = Date.now() + 30000;
191
+ while (Date.now() < __deadline) {
192
+ if (exists("button[aria-label='Open Scheduling Assistant']") ||
193
+ exists("input[aria-label='Start date']")) break;
194
+ await sleep(1000);
195
+ }
196
+ if (!exists("button[aria-label='Open Scheduling Assistant']") &&
197
+ !exists("input[aria-label='Start date']")) {
198
+ if (/login\.|\/oauth2\/|signin|sso/i.test(location.href)) {
199
+ throw new Error('Not signed in to Outlook/Teams — log in and retry');
200
+ }
201
+ throw new Error('Calendar compose form did not load');
202
+ }
203
+
204
+ // Open the Scheduling Assistant (free/busy view).
205
+ for (let i = 0; i < 12 && !schedulingAssistantOpen(); i++) {
206
+ clickByName('Open Scheduling Assistant');
207
+ await sleep(1000);
208
+ }
209
+ if (!schedulingAssistantOpen()) {
210
+ throw new Error('Could not open the Scheduling Assistant');
211
+ }
212
+
213
+ // ── Set the date ─────────────────────────────────────────────────────
214
+ const cellSel = `button[aria-label='${dateCellLabel(date)}']`;
215
+ const target = new Date(`${date}T00:00:00`);
216
+ const now = new Date();
217
+ const navSel = target >= new Date(now.getFullYear(), now.getMonth(), now.getDate())
218
+ ? "button[aria-label^='Go to next month']"
219
+ : "button[aria-label^='Go to previous month']";
220
+
221
+ const dateInput = $("input[aria-label='Start date']");
222
+ if (dateInput) dateInput.click();
223
+
224
+ for (let i = 0; i < 30; i++) {
225
+ if (exists(cellSel)) {
226
+ $(cellSel).click();
227
+ break;
228
+ }
229
+ if (exists(navSel)) {
230
+ try { $(navSel).click(); } catch (_e) { /* retry */ }
231
+ } else {
232
+ const di = $("input[aria-label='Start date']");
233
+ if (di) di.click();
234
+ }
235
+ await sleep(1000);
236
+ }
237
+ if (!exists(cellSel)) {
238
+ // If the cell is gone, the click succeeded; otherwise error.
239
+ // (After clicking a date, the picker closes and the cell is removed from DOM.)
240
+ }
241
+
242
+ // ── Capture pre-existing mailbox IDs (organizer) ─────────────────────
243
+ const seen = new Set();
244
+ for (let i = 0; i < 3; i++) {
245
+ await sleep(1000);
246
+ for (const pair of readCapture()) {
247
+ for (const id of schedulesFromPair(pair).keys()) seen.add(id);
248
+ }
249
+ }
250
+
251
+ // ── Add the room ─────────────────────────────────────────────────────
252
+ if (isEmail) {
253
+ // Email -> attendee picker (resolves SMTP).
254
+ clickByName('Expand Required attendees');
255
+ await sleep(1000);
256
+
257
+ const inputSel = "input[aria-label*='required attendees']";
258
+ for (let i = 0; i < 12 && !exists(inputSel); i++) {
259
+ clickByName('Add required attendee');
260
+ await sleep(1000);
261
+ }
262
+ if (!exists(inputSel)) {
263
+ throw new Error('Could not open the required-attendee field');
264
+ }
265
+ typeText(inputSel, room);
266
+
267
+ const optionSel = `[role=option][aria-label*='${room}']`;
268
+ let found = false;
269
+ for (let i = 0; i < 12 && !found; i++) {
270
+ await sleep(1000);
271
+ found = exists(optionSel);
272
+ }
273
+ if (!found) {
274
+ throw new Error(`Room "${room}" was not found in the directory`);
275
+ }
276
+ $(optionSel).click();
277
+ } else {
278
+ // Name -> room finder.
279
+ const inputSel = "input[aria-label='Add a room']";
280
+ for (let i = 0; i < 10 && !exists(inputSel); i++) {
281
+ clickByName('Add a room');
282
+ await sleep(1000);
283
+ }
284
+ if (!exists(inputSel)) {
285
+ throw new Error('Could not open the room finder');
286
+ }
287
+ typeText(inputSel, room);
288
+
289
+ let label = null;
290
+ for (let i = 0; i < 14 && !label; i++) {
291
+ await sleep(1000);
292
+ const opts = Array.from(document.querySelectorAll('[role=option]'));
293
+ const el = opts.find(o => /capacity/i.test(o.getAttribute('aria-label') || '') && o.offsetParent);
294
+ if (el) {
295
+ el.scrollIntoView({ block: 'center' });
296
+ el.click();
297
+ label = el.getAttribute('aria-label');
298
+ }
299
+ }
300
+ if (!label) {
301
+ throw new Error(`No room matched "${room}"`);
302
+ }
303
+ }
304
+
305
+ // ── Collect the room's free/busy from intercepted responses ──────────
306
+ let roomId = null;
307
+ let errMsg = null;
308
+ let sawView = false;
309
+ const itemsById = new Map();
310
+ const isRoomId = id => (isEmail ? id === room.toLowerCase() : !seen.has(id));
311
+
312
+ let stable = 0;
313
+ for (let i = 0; i < 30; i++) {
314
+ await sleep(1000);
315
+ for (const pair of readCapture()) {
316
+ for (const [id, s] of schedulesFromPair(pair)) {
317
+ if (!isRoomId(id)) continue;
318
+ if (!roomId) roomId = s.scheduleId;
319
+ if (s.error) errMsg = s.error.message || s.error.responseCode || 'unknown';
320
+ if (s.availabilityView && s.availabilityView.length) sawView = true;
321
+ for (const it of (s.scheduleItems || [])) {
322
+ const key = it && it.id ? it.id : JSON.stringify(it && [it.startTime, it.endTime, it.subject]);
323
+ if (it) itemsById.set(key, it);
324
+ }
325
+ }
326
+ }
327
+ if (sawView) { stable += 1; if (stable >= 3) break; }
328
+ }
329
+
330
+ if (!roomId) {
331
+ throw new Error(`No free/busy returned for "${room}" on ${date}`);
332
+ }
333
+ if (errMsg && !sawView) {
334
+ throw new Error(`Free/busy error for "${room}": ${errMsg}`);
335
+ }
336
+
337
+ const timeline = buildTimeline([...itemsById.values()], date);
338
+ return timeline.map(r => ({ room: roomId, ...r }));
@@ -0,0 +1,45 @@
1
+ site: teams
2
+ name: room-availability
3
+ version: "1.0"
4
+ description: "Meeting-room free/busy timeline for one room on a given day (Teams/Outlook calendar)"
5
+ access: read
6
+
7
+ domains:
8
+ - "outlook.cloud.microsoft.mcas.ms"
9
+ capabilities:
10
+ - navigate
11
+ - js_evaluate
12
+
13
+ args:
14
+ - name: room
15
+ type: string
16
+ required: true
17
+ help: "Room name or mailbox email (e.g. 'MBTMY The Vista' or 'RES-RERE-M6VJ7ZUW@mercedes-benz.com')"
18
+ - name: date
19
+ type: string
20
+ required: false
21
+ help: "Day to check in YYYY-MM-DD format (default: today)"
22
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$"
23
+
24
+ columns:
25
+ - name: room
26
+ type: string
27
+ - name: date
28
+ type: string
29
+ - name: state
30
+ type: string
31
+ - name: start
32
+ type: string
33
+ - name: end
34
+ type: string
35
+ - name: durationMin
36
+ type: number
37
+
38
+ pipeline:
39
+ - step: navigate
40
+ url: "https://outlook.cloud.microsoft.mcas.ms/calendar/deeplink/compose"
41
+ - step: wait
42
+ selector: "body"
43
+ timeout: 30000
44
+ - step: js_evaluate
45
+ file: teams-room-availability.eval.js
@@ -0,0 +1,60 @@
1
+ // Runs in page context via js_evaluate step.
2
+ // Reads the MSAL access token from sessionStorage, fetches the ReportFAK API,
3
+ // and flattens day objects into one row per booking line.
4
+ //
5
+ // SSO/MFA: polls sessionStorage for up to 60s, giving the user time to
6
+ // complete login and get redirected back to the app.
7
+ //
8
+ // Template variables interpolated before execution:
9
+ // ${{ args.month | default("") }}
10
+
11
+ // Poll for MSAL token (handles SSO redirects + MFA)
12
+ const __deadline = Date.now() + 60000;
13
+ let token;
14
+ while (Date.now() < __deadline) {
15
+ const k = Object.keys(sessionStorage).find(x => x.includes('accesstoken'));
16
+ if (k) {
17
+ try {
18
+ const tokenData = JSON.parse(sessionStorage.getItem(k));
19
+ if (Number(tokenData.expiresOn) > Math.floor(Date.now() / 1000) + 30) {
20
+ token = tokenData.secret;
21
+ break;
22
+ }
23
+ } catch (_) {}
24
+ }
25
+ await new Promise(r => setTimeout(r, 1000));
26
+ }
27
+ if (!token) throw new Error('No valid MSAL access token after 60s — log in and retry');
28
+
29
+ let month = '${{ args.month | default("") }}';
30
+ if (!month) {
31
+ const now = new Date();
32
+ month = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0');
33
+ }
34
+
35
+ const resp = await fetch(
36
+ 'https://mbti-bam-wzde-prd-ejdchtb0g9afexhr.a01.azurefd.net/api/ReportFAK?date=' + month + '-01',
37
+ { headers: { Authorization: 'Bearer ' + token, Accept: 'application/json' } }
38
+ );
39
+ if (!resp.ok) throw new Error('ReportFAK returned HTTP ' + resp.status);
40
+
41
+ const days = await resp.json();
42
+ const rows = [];
43
+ for (const day of days) {
44
+ const header = day.calendarHeader || {};
45
+ const dayDate = (day.date || '').slice(0, 10);
46
+ for (const line of day.calendarLines || []) {
47
+ rows.push({
48
+ month: month,
49
+ date: dayDate,
50
+ projectId: line.mserp_projectid || null,
51
+ category: line.mserp_category || null,
52
+ activity: line.mserp_activitynumber || null,
53
+ hours: typeof line.mserp_hours === 'number' ? line.mserp_hours : null,
54
+ status: header.status || null,
55
+ journalId: line.mserp_journalid || null,
56
+ lineNumber: typeof line.mserp_linenumber === 'number' ? line.mserp_linenumber : null,
57
+ });
58
+ }
59
+ }
60
+ return rows;
@@ -0,0 +1,48 @@
1
+ site: timetracking
2
+ name: report
3
+ version: "1.0"
4
+ description: "MBTI Time Tracking monthly report — one row per booking line"
5
+ access: read
6
+
7
+ domains:
8
+ - "timetracking.mercedes-benz-techinnovation.com"
9
+ - "mbti-bam-wzde-prd-ejdchtb0g9afexhr.a01.azurefd.net"
10
+ capabilities:
11
+ - navigate
12
+ - js_evaluate
13
+
14
+ args:
15
+ - name: month
16
+ type: string
17
+ required: false
18
+ help: "Month in YYYY-MM format (default: current month)"
19
+ pattern: "^\\d{4}-\\d{2}$"
20
+
21
+ columns:
22
+ - name: month
23
+ type: string
24
+ - name: date
25
+ type: string
26
+ - name: projectId
27
+ type: string
28
+ - name: category
29
+ type: string
30
+ - name: activity
31
+ type: string
32
+ - name: hours
33
+ type: number
34
+ - name: status
35
+ type: string
36
+ - name: journalId
37
+ type: string
38
+ - name: lineNumber
39
+ type: number
40
+
41
+ pipeline:
42
+ - step: navigate
43
+ url: "https://timetracking.mercedes-benz-techinnovation.com/"
44
+ - step: wait
45
+ selector: "body"
46
+ timeout: 10000
47
+ - step: js_evaluate
48
+ file: timetracking-report.eval.js
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAM5D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAM5D"}
@@ -2,8 +2,10 @@
2
2
  import { z } from 'zod';
3
3
  import { parse as parseYaml } from 'yaml';
4
4
  import { readFileSync, existsSync } from 'node:fs';
5
- import { join } from 'node:path';
5
+ import { join, dirname } from 'node:path';
6
6
  import { homedir } from 'node:os';
7
+ import { fileURLToPath } from 'node:url';
8
+ const BUNDLED_CONNECTORS_DIR = join(dirname(fileURLToPath(import.meta.url)), '../connectors');
7
9
  export const configSchema = z.object({
8
10
  daemon: z.object({
9
11
  port: z.number().int().min(1024).max(65535).default(19825),
@@ -18,7 +20,7 @@ export const configSchema = z.object({
18
20
  approvalTimeoutMs: z.number().int().positive().default(120_000),
19
21
  }).default({}),
20
22
  connectors: z.object({
21
- paths: z.array(z.string()).default(['./connectors', '~/.commandgarden/connectors']),
23
+ paths: z.array(z.string()).default([BUNDLED_CONNECTORS_DIR, '~/.commandgarden/connectors']),
22
24
  }).default({}),
23
25
  audit: z.object({
24
26
  retentionDays: z.number().int().positive().default(90),
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,11 @@
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "connectors"
9
10
  ],
10
11
  "scripts": {
11
- "build": "tsc",
12
+ "build": "tsc && node scripts/copy-connectors.mjs",
12
13
  "start": "node dist/main.js",
13
14
  "test": "vitest run",
14
15
  "test:watch": "vitest"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commandgarden/cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Enterprise browser automation CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",