@withone/cli 1.55.4 → 1.56.0

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/index.js CHANGED
@@ -32,10 +32,10 @@ import {
32
32
  validateActionInput,
33
33
  walkSteps,
34
34
  writeCache
35
- } from "./chunk-WXJWF7QG.js";
35
+ } from "./chunk-QCXFSOTS.js";
36
36
  import {
37
37
  memSqlCommand
38
- } from "./chunk-OWDR5L3Q.js";
38
+ } from "./chunk-KAF5SVJS.js";
39
39
  import {
40
40
  collectIdentityKeys,
41
41
  countRecords,
@@ -66,7 +66,7 @@ import {
66
66
  writeDraftProfile,
67
67
  writePageToMemory,
68
68
  writeProfile
69
- } from "./chunk-FS4HAKZ6.js";
69
+ } from "./chunk-XWTV7FA3.js";
70
70
  import {
71
71
  getByDotPath
72
72
  } from "./chunk-44CV5IMX.js";
@@ -90,7 +90,7 @@ import {
90
90
  semanticSearchUpgradeLine,
91
91
  setAgentMode,
92
92
  silenceWarningsInAgentMode
93
- } from "./chunk-GNSR3NYN.js";
93
+ } from "./chunk-OLQ55K6B.js";
94
94
  import {
95
95
  SCHEMA_VERSION,
96
96
  addRecord,
@@ -100,7 +100,7 @@ import {
100
100
  listBackendPlugins,
101
101
  loadBackendFromConfig,
102
102
  updateRecord
103
- } from "./chunk-DDCDPVJH.js";
103
+ } from "./chunk-VH46MAE4.js";
104
104
  import {
105
105
  DEFAULT_MEMORY_CONFIG,
106
106
  defaultSearchableText,
@@ -110,7 +110,7 @@ import {
110
110
  memoryConfigExists,
111
111
  setOpenAiApiKey,
112
112
  updateMemoryConfig
113
- } from "./chunk-5O5KODGV.js";
113
+ } from "./chunk-YMUY55U2.js";
114
114
  import {
115
115
  appendAnalyticsQueue,
116
116
  appendUsageLog,
@@ -138,6 +138,7 @@ import {
138
138
  readProjectConfig,
139
139
  readUsageState,
140
140
  resolveConfig,
141
+ saveCredentials,
141
142
  telemetryNoticeShown,
142
143
  updateAccessControl,
143
144
  updateApiBase,
@@ -146,18 +147,18 @@ import {
146
147
  writeConfig,
147
148
  writeUsageLog,
148
149
  writeUsageState
149
- } from "./chunk-EVEUGRCB.js";
150
+ } from "./chunk-6UB623BG.js";
150
151
 
151
152
  // src/cli.ts
152
153
  import { createRequire as createRequire3 } from "module";
153
- import path12 from "path";
154
+ import path13 from "path";
154
155
  import { Command } from "commander";
155
156
 
156
157
  // src/commands/init.ts
157
158
  import * as p3 from "@clack/prompts";
158
- import pc3 from "picocolors";
159
- import fs3 from "fs";
160
- import path4 from "path";
159
+ import pc4 from "picocolors";
160
+ import fs4 from "fs";
161
+ import path5 from "path";
161
162
  import { fileURLToPath as fileURLToPath3 } from "url";
162
163
 
163
164
  // src/lib/agents.ts
@@ -259,6 +260,12 @@ function getAgents() {
259
260
  }
260
261
  ];
261
262
  }
263
+ function detectInstalledAgents() {
264
+ return getAgents().filter((agent) => {
265
+ const detectDir = expandPath(agent.detectDir);
266
+ return fs.existsSync(detectDir);
267
+ });
268
+ }
262
269
  function getAgentConfigPath(agent, scope = "global") {
263
270
  if (scope === "project" && agent.projectConfigPath) {
264
271
  return path.join(process.cwd(), agent.projectConfigPath);
@@ -341,94 +348,539 @@ function getAgentStatuses() {
341
348
 
342
349
  // src/lib/browser.ts
343
350
  import open from "open";
344
- var ONE_APP_URL = "https://app.withone.ai";
345
- function getConnectionUrl(platform, params) {
346
- const searchParams = new URLSearchParams();
347
- if (params?.orgId) searchParams.set("orgId", params.orgId);
348
- if (params?.projectId) searchParams.set("projectId", params.projectId);
349
- if (params?.env) searchParams.set("env", params.env);
350
- const qs = searchParams.toString();
351
- return `${ONE_APP_URL}/${qs ? `?${qs}` : ""}#open=${platform}`;
351
+
352
+ // src/lib/install-context.ts
353
+ import fs2 from "fs";
354
+ import os from "os";
355
+ import path3 from "path";
356
+
357
+ // src/lib/analytics.ts
358
+ import { createRequire as createRequire2 } from "module";
359
+ import { randomUUID, createHash } from "crypto";
360
+ import pc from "picocolors";
361
+
362
+ // src/lib/version.ts
363
+ import { createRequire } from "module";
364
+ import { existsSync } from "fs";
365
+ import path2 from "path";
366
+ import { fileURLToPath } from "url";
367
+ var require2 = createRequire(import.meta.url);
368
+ var cached = null;
369
+ function cliVersion() {
370
+ if (cached !== null) return cached;
371
+ const dir = path2.dirname(fileURLToPath(import.meta.url));
372
+ for (let i = 1; i <= 4; i++) {
373
+ const candidate = path2.resolve(dir, ...Array(i).fill(".."), "package.json");
374
+ if (!existsSync(candidate)) continue;
375
+ try {
376
+ const version2 = require2(candidate).version;
377
+ if (version2) {
378
+ cached = version2;
379
+ return cached;
380
+ }
381
+ } catch {
382
+ }
383
+ }
384
+ cached = "unknown";
385
+ return cached;
352
386
  }
353
- function getApiKeyUrl() {
354
- return `${ONE_APP_URL}/settings/api-keys`;
387
+
388
+ // src/lib/analytics.ts
389
+ var require3 = createRequire2(import.meta.url);
390
+ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
391
+ var DEFAULT_POSTHOG_KEY = "phc_a9ok4w0uxiZcVoSWOISIlin85lHMXQD3vWPaYnuRlRV";
392
+ var SEND_MAX_ATTEMPTS = 3;
393
+ var QUEUE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
394
+ var EXIT_GRACE_MS = 300;
395
+ var inFlight = /* @__PURE__ */ new Set();
396
+ var pending = /* @__PURE__ */ new Set();
397
+ var dispatched = /* @__PURE__ */ new Set();
398
+ var delivered = /* @__PURE__ */ new Set();
399
+ var UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
400
+ function uuidFromInsertId(insertId) {
401
+ if (UUID_SHAPE.test(insertId)) return insertId.toLowerCase();
402
+ const h = createHash("sha1").update(`one-cli-event:${insertId}`).digest("hex");
403
+ const variant = (parseInt(h[16], 16) & 3 | 8).toString(16);
404
+ return `${h.slice(0, 8)}-${h.slice(8, 12)}-5${h.slice(13, 16)}-${variant}${h.slice(17, 20)}-${h.slice(20, 32)}`;
355
405
  }
356
- async function openConnectionPage(platform, params) {
357
- const url = getConnectionUrl(platform, params);
358
- await open(url);
406
+ function posthogHost() {
407
+ return process.env.ONE_POSTHOG_HOST || DEFAULT_POSTHOG_HOST;
359
408
  }
360
- async function openApiKeyPage() {
361
- await open(getApiKeyUrl());
409
+ function posthogKey() {
410
+ return process.env.ONE_POSTHOG_KEY || DEFAULT_POSTHOG_KEY;
362
411
  }
363
- function getCliAuthUrl(port, state) {
364
- return `${ONE_APP_URL}/cli/auth?port=${port}&state=${encodeURIComponent(state)}`;
412
+ function envName() {
413
+ const key = getApiKey();
414
+ return key ? getEnvFromApiKey(key) : "live";
365
415
  }
366
- async function openCliAuthPage(port, state) {
367
- const url = getCliAuthUrl(port, state);
368
- await open(url);
416
+ function isOn(value) {
417
+ return value === "1" || value === "true";
369
418
  }
370
-
371
- // src/commands/config.ts
372
- import * as p from "@clack/prompts";
373
- import pc from "picocolors";
374
- async function configCommand() {
375
- if (isAgentMode()) {
376
- error("This command requires interactive input. Run without --agent.");
419
+ function debugLog(message) {
420
+ if (isOn(process.env.ONE_ANALYTICS_DEBUG)) {
421
+ process.stderr.write(`[analytics] ${message}
422
+ `);
377
423
  }
378
- const config2 = readConfig();
379
- if (!config2) {
380
- p.log.error(`No One config found. Run ${pc.cyan("one init")} first.`);
424
+ }
425
+ function isTelemetryDisabled() {
426
+ if (isOn(process.env.ONE_NO_TELEMETRY) || isOn(process.env.ONE_DISABLE_TELEMETRY)) return true;
427
+ if (isOn(process.env.DO_NOT_TRACK)) return true;
428
+ if (isOn(process.env.CI)) return true;
429
+ if (readConfig()?.telemetry === "off") return true;
430
+ return false;
431
+ }
432
+ function distinctId() {
433
+ return getWhoAmI()?.user?.id ?? getDeviceId();
434
+ }
435
+ function isAuthenticated() {
436
+ return !!getWhoAmI()?.user || !!getApiKey();
437
+ }
438
+ function baseProperties() {
439
+ return {
440
+ $lib: "one-cli",
441
+ cli_version: cliVersion(),
442
+ agent_mode: isAgentMode(),
443
+ env: envName(),
444
+ os: process.platform,
445
+ arch: process.arch,
446
+ node_version: process.versions.node,
447
+ authenticated: isAuthenticated()
448
+ };
449
+ }
450
+ function personSet() {
451
+ const whoami = getWhoAmI();
452
+ if (!whoami?.user) return void 0;
453
+ const set = {};
454
+ if (whoami.user.email) set.email = whoami.user.email;
455
+ if (whoami.user.name) set.name = whoami.user.name;
456
+ if (whoami.organization?.id) set.organization_id = whoami.organization.id;
457
+ return Object.keys(set).length ? set : void 0;
458
+ }
459
+ function send(item) {
460
+ const insertId = item.properties.$insert_id;
461
+ if (insertId) dispatched.add(insertId);
462
+ const controller = new AbortController();
463
+ inFlight.add(controller);
464
+ const run = (async () => {
465
+ try {
466
+ const res = await fetch(`${posthogHost()}/i/v0/e/`, {
467
+ method: "POST",
468
+ headers: { "Content-Type": "application/json" },
469
+ body: JSON.stringify({
470
+ api_key: posthogKey(),
471
+ event: item.event,
472
+ distinct_id: item.distinct_id,
473
+ // PostHog's dedupe key — a re-sent copy is dropped on ingest.
474
+ uuid: item.uuid ?? (insertId ? uuidFromInsertId(insertId) : void 0),
475
+ properties: item.properties,
476
+ timestamp: item.timestamp
477
+ }),
478
+ signal: controller.signal
479
+ });
480
+ if (res.ok && insertId) delivered.add(insertId);
481
+ debugLog(`"${item.event}" -> HTTP ${res.status}${res.ok ? "" : " (retry next run)"}`);
482
+ } catch (err) {
483
+ debugLog(`"${item.event}" not sent: ${err instanceof Error ? err.message : String(err)} (retry next run)`);
484
+ } finally {
485
+ inFlight.delete(controller);
486
+ }
487
+ })();
488
+ pending.add(run);
489
+ void run.finally(() => pending.delete(run));
490
+ }
491
+ function capture(event, properties = {}, opts = {}) {
492
+ if (isTelemetryDisabled()) {
493
+ debugLog(`disabled \u2014 skipping "${event}"`);
381
494
  return;
382
495
  }
383
- p.intro(pc.bgCyan(pc.black(" One Access Control ")));
384
- const current = getAccessControl();
385
- console.log();
386
- console.log(` ${pc.bold("Current Access Control")}`);
387
- console.log(` ${pc.dim("\u2500".repeat(42))}`);
388
- console.log(` ${pc.dim("Permissions:")} ${current.permissions ?? "admin"}`);
389
- console.log(` ${pc.dim("Connections:")} ${formatList(current.connectionKeys)}`);
390
- console.log(` ${pc.dim("Action IDs:")} ${formatList(current.actionIds)}`);
391
- console.log(` ${pc.dim("Knowledge only:")} ${current.knowledgeAgent ? "yes" : "no"}`);
392
- console.log();
393
- const permissions = await p.select({
394
- message: "Permission level",
395
- options: [
396
- { value: "admin", label: "Admin", hint: "Full access (GET, POST, PUT, PATCH, DELETE)" },
397
- { value: "write", label: "Write", hint: "GET, POST, PUT, PATCH" },
398
- { value: "read", label: "Read", hint: "GET only" }
399
- ],
400
- initialValue: current.permissions ?? "admin"
401
- });
402
- if (p.isCancel(permissions)) {
403
- p.outro("No changes made.");
404
- return;
496
+ const did = opts.distinctId ?? distinctId();
497
+ const props = { ...baseProperties(), ...properties };
498
+ if (props.$insert_id === void 0) props.$insert_id = randomUUID();
499
+ const insertId = props.$insert_id;
500
+ if (opts.personProfile === false) {
501
+ props.$process_person_profile = false;
502
+ } else if (did === distinctId()) {
503
+ const set = personSet();
504
+ if (set) props.$set = set;
405
505
  }
406
- const connectionMode = await p.select({
407
- message: "Connection scope",
408
- options: [
409
- { value: "all", label: "All connections" },
410
- { value: "specific", label: "Select specific connections" }
411
- ],
412
- initialValue: current.connectionKeys ? "specific" : "all"
413
- });
414
- if (p.isCancel(connectionMode)) {
415
- p.outro("No changes made.");
506
+ const item = {
507
+ event,
508
+ distinct_id: did,
509
+ properties: props,
510
+ timestamp: opts.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
511
+ uuid: uuidFromInsertId(insertId)
512
+ };
513
+ appendAnalyticsQueue(JSON.stringify(item));
514
+ }
515
+ var ROLLUP_WINDOW_MS = 5 * 60 * 1e3;
516
+ var ROLLUP_MAX_BATCH = 500;
517
+ function utcDay(ts) {
518
+ return new Date(ts).toISOString().slice(0, 10);
519
+ }
520
+ var PRE_AUTH_COMMANDS = /* @__PURE__ */ new Set([
521
+ "init",
522
+ "login",
523
+ "logout",
524
+ "guide",
525
+ "platforms",
526
+ "onboard",
527
+ "config",
528
+ "update",
529
+ "help"
530
+ ]);
531
+ function shouldRecord(commandPath2) {
532
+ if (isAuthenticated()) return true;
533
+ return PRE_AUTH_COMMANDS.has(commandPath2.split(" ")[0]);
534
+ }
535
+ function recordCommand(command) {
536
+ if (isTelemetryDisabled()) {
537
+ writeUsageLog([]);
416
538
  return;
417
539
  }
418
- let connectionKeys;
419
- if (connectionMode === "specific") {
420
- connectionKeys = await selectConnections(config2.apiKey);
421
- if (connectionKeys === void 0) {
422
- p.outro("No changes made.");
423
- return;
424
- }
425
- if (connectionKeys.length === 0) {
426
- p.log.info(`No connections found. Defaulting to all. Use ${pc.cyan("one add")} to connect platforms.`);
427
- connectionKeys = void 0;
428
- }
540
+ const cmdPath = commandPath(command);
541
+ if (!shouldRecord(cmdPath)) return;
542
+ const did = distinctId();
543
+ const entry = { ts: Date.now(), command: cmdPath, agent: isAgentMode(), did };
544
+ appendUsageLog(JSON.stringify(entry));
545
+ const today = utcDay(entry.ts);
546
+ const state = readUsageState();
547
+ const firstTouch = state.lastDay !== today || state.distinctId !== did;
548
+ flushUsageRollups({ force: firstTouch });
549
+ if (firstTouch) writeUsageState({ lastDay: today, distinctId: did });
550
+ }
551
+ function flushUsageRollups(opts = {}) {
552
+ if (isTelemetryDisabled()) {
553
+ writeUsageLog([]);
554
+ return;
429
555
  }
430
- const actionMode = await p.select({
431
- message: "Action scope",
556
+ const lines = claimUsageLog();
557
+ if (!lines || lines.length === 0) return;
558
+ const entries = [];
559
+ for (const line of lines) {
560
+ try {
561
+ const e = JSON.parse(line);
562
+ if (e && typeof e.ts === "number" && typeof e.command === "string" && typeof e.did === "string") {
563
+ entries.push(e);
564
+ }
565
+ } catch {
566
+ }
567
+ }
568
+ if (entries.length === 0) return;
569
+ const currentDid = entries[entries.length - 1].did;
570
+ const now = Date.now();
571
+ const groups = /* @__PURE__ */ new Map();
572
+ for (const e of entries) {
573
+ const g = groups.get(e.did);
574
+ if (g) g.push(e);
575
+ else groups.set(e.did, [e]);
576
+ }
577
+ const kept = [];
578
+ for (const [did, group] of groups) {
579
+ const due = opts.force === true || did !== currentDid || // a superseded login's batch — flush it now
580
+ group.length >= ROLLUP_MAX_BATCH || now - group[0].ts >= ROLLUP_WINDOW_MS;
581
+ if (due) emitRollup(did, group);
582
+ else kept.push(...group);
583
+ }
584
+ for (const e of kept) appendUsageLog(JSON.stringify(e));
585
+ }
586
+ function emitRollup(did, group) {
587
+ const byCommand = {};
588
+ let agentCount = 0;
589
+ for (const e of group) {
590
+ byCommand[e.command] = (byCommand[e.command] ?? 0) + 1;
591
+ if (e.agent) agentCount += 1;
592
+ }
593
+ const insertId = createHash("sha1").update(`${did}|${group.map((e) => `${e.ts}:${e.command}:${e.agent ? 1 : 0}`).join("|")}`).digest("hex");
594
+ capture(
595
+ "CLI Usage Rollup",
596
+ {
597
+ command_count: group.length,
598
+ by_command: byCommand,
599
+ agent_count: agentCount,
600
+ human_count: group.length - agentCount,
601
+ window_start: new Date(group[0].ts).toISOString(),
602
+ window_end: new Date(group[group.length - 1].ts).toISOString(),
603
+ $insert_id: insertId
604
+ },
605
+ {
606
+ distinctId: did,
607
+ timestamp: new Date(group[group.length - 1].ts).toISOString(),
608
+ // Rollups bill at the anonymous rate; the person already exists.
609
+ personProfile: false
610
+ }
611
+ );
612
+ debugLog(`rollup \u2014 ${group.length} command(s) for ${did}`);
613
+ }
614
+ function commandPath(command) {
615
+ const parts = [];
616
+ let current = command;
617
+ while (current && current.name() && current.name() !== "one") {
618
+ parts.unshift(current.name());
619
+ current = current.parent;
620
+ }
621
+ return parts.join(" ") || command.name();
622
+ }
623
+ function drainQueue() {
624
+ if (isTelemetryDisabled()) {
625
+ writeAnalyticsQueue([]);
626
+ return;
627
+ }
628
+ const now = Date.now();
629
+ const kept = [];
630
+ let changed = false;
631
+ for (const line of readAnalyticsQueue()) {
632
+ let item;
633
+ try {
634
+ item = JSON.parse(line);
635
+ } catch {
636
+ changed = true;
637
+ continue;
638
+ }
639
+ const insertId = item?.properties?.$insert_id;
640
+ if (!insertId) {
641
+ changed = true;
642
+ continue;
643
+ }
644
+ const age = now - Date.parse(item.timestamp);
645
+ const attempts = item.attempts ?? 0;
646
+ if (!(age < QUEUE_MAX_AGE_MS) || attempts >= SEND_MAX_ATTEMPTS) {
647
+ debugLog(`"${item.event}" dropped (${attempts} attempts, ${Math.round(age / 6e4)} min old)`);
648
+ changed = true;
649
+ continue;
650
+ }
651
+ if (dispatched.has(insertId)) {
652
+ kept.push(line);
653
+ continue;
654
+ }
655
+ item.attempts = attempts + 1;
656
+ if (!item.uuid) item.uuid = uuidFromInsertId(insertId);
657
+ kept.push(JSON.stringify(item));
658
+ changed = true;
659
+ send(item);
660
+ }
661
+ if (changed) writeAnalyticsQueue(kept);
662
+ }
663
+ async function flush() {
664
+ if (pending.size > 0) {
665
+ await Promise.race([
666
+ Promise.allSettled([...pending]),
667
+ new Promise((resolve) => setTimeout(resolve, EXIT_GRACE_MS))
668
+ ]);
669
+ }
670
+ for (const controller of inFlight) controller.abort();
671
+ const remaining = readAnalyticsQueue().filter((line) => {
672
+ try {
673
+ const item = JSON.parse(line);
674
+ const id = item.properties?.$insert_id;
675
+ if (!id || delivered.has(id)) return false;
676
+ return (item.attempts ?? 0) < SEND_MAX_ATTEMPTS;
677
+ } catch {
678
+ return false;
679
+ }
680
+ });
681
+ writeAnalyticsQueue(remaining);
682
+ dispatched.clear();
683
+ delivered.clear();
684
+ }
685
+ function maybeShowTelemetryNotice() {
686
+ if (isTelemetryDisabled() || isAgentMode()) return;
687
+ if (telemetryNoticeShown()) return;
688
+ markTelemetryNoticeShown();
689
+ process.stderr.write(
690
+ pc.dim(
691
+ "One CLI collects usage analytics (which commands run, linked to your One account) to improve the product.\nNo arguments, inputs, or secrets are ever collected. Opt out anytime with ONE_NO_TELEMETRY=1.\n"
692
+ )
693
+ );
694
+ }
695
+
696
+ // src/lib/install-context.ts
697
+ var EXTRA_HARNESS_DIRS = [
698
+ { id: "gemini-cli", dir: ".gemini" },
699
+ { id: "openclaw", dir: ".openclaw" },
700
+ { id: "hermes", dir: ".hermes" },
701
+ { id: "devin", dir: ".devin" }
702
+ ];
703
+ var LAUNCHER_ENV = [
704
+ { id: "claude-code", vars: ["CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT"] },
705
+ { id: "codex", vars: ["CODEX_SANDBOX", "CODEX_CI", "CODEX_THREAD_ID"] },
706
+ { id: "gemini-cli", vars: ["GEMINI_CLI"] },
707
+ // CURSOR_TRACE_ID is deliberately absent: Cursor exports it into every
708
+ // integrated-terminal shell, so it marks the editor, not an agent.
709
+ { id: "cursor", vars: ["CURSOR_AGENT"] },
710
+ { id: "windsurf", vars: ["WINDSURF_AGENT"] },
711
+ { id: "kiro", vars: ["KIRO_AGENT"] },
712
+ { id: "openclaw", vars: ["OPENCLAW_AGENT", "OPENCLAW_SESSION"] },
713
+ { id: "hermes", vars: ["HERMES_AGENT", "HERMES_SESSION"] },
714
+ { id: "devin", vars: ["DEVIN_SESSION_ID"] }
715
+ ];
716
+ function detectLauncher(env = process.env) {
717
+ for (const entry of LAUNCHER_ENV) {
718
+ if (entry.vars.some((v) => env[v] !== void 0 && env[v] !== "")) return entry.id;
719
+ }
720
+ return void 0;
721
+ }
722
+ function detectInstalledHarnesses() {
723
+ const ids = new Set(detectInstalledAgents().map((a) => a.id));
724
+ for (const { id, dir } of EXTRA_HARNESS_DIRS) {
725
+ if (fs2.existsSync(path3.join(homeDir(), dir))) ids.add(id);
726
+ }
727
+ return [...ids].sort();
728
+ }
729
+ function tryRead(read) {
730
+ try {
731
+ const value = read();
732
+ return value === null || value === "" ? void 0 : value;
733
+ } catch {
734
+ return void 0;
735
+ }
736
+ }
737
+ function collectInstallContext(opts) {
738
+ const env = opts.env ?? process.env;
739
+ const ctx = {
740
+ scope: opts.scope,
741
+ harnesses: tryRead(() => detectInstalledHarnesses()) ?? []
742
+ };
743
+ if (opts.scope === "project") {
744
+ ctx.path = opts.projectRoot ?? tryRead(() => getProjectRoot());
745
+ }
746
+ ctx.host = tryRead(() => os.hostname());
747
+ ctx.os = process.platform;
748
+ ctx.osVersion = tryRead(() => os.release());
749
+ ctx.arch = process.arch;
750
+ ctx.user = tryRead(() => os.userInfo().username);
751
+ if (!isTelemetryDisabled()) ctx.device = tryRead(() => getDeviceId());
752
+ const cli = tryRead(() => cliVersion());
753
+ ctx.cli = cli === "unknown" ? void 0 : cli;
754
+ ctx.launcher = detectLauncher(env);
755
+ return ctx;
756
+ }
757
+ function installContextToParams(ctx) {
758
+ const params = new URLSearchParams();
759
+ const set = (key, value) => {
760
+ if (value !== void 0 && value !== "") params.set(key, value);
761
+ };
762
+ set("scope", ctx.scope);
763
+ set("path", ctx.path);
764
+ set("host", ctx.host);
765
+ set("os", ctx.os);
766
+ set("osv", ctx.osVersion);
767
+ set("arch", ctx.arch);
768
+ set("user", ctx.user);
769
+ set("device", ctx.device);
770
+ set("cli", ctx.cli);
771
+ if (ctx.harnesses.length > 0) params.set("harnesses", ctx.harnesses.join(","));
772
+ set("launcher", ctx.launcher);
773
+ return params;
774
+ }
775
+ function describeInstallContext(ctx) {
776
+ const lines = [`scope: ${ctx.scope}`];
777
+ if (ctx.path) lines.push(`path: ${ctx.path}`);
778
+ if (ctx.host || ctx.os) {
779
+ const osPart = [ctx.os, ctx.osVersion].filter(Boolean).join(" ");
780
+ const detail = [osPart, ctx.arch].filter(Boolean).join(", ");
781
+ lines.push(`machine: ${ctx.host ?? "unknown"}${detail ? ` (${detail})` : ""}`);
782
+ }
783
+ if (ctx.user) lines.push(`user: ${ctx.user}`);
784
+ if (ctx.device) lines.push(`device: ${ctx.device}`);
785
+ if (ctx.harnesses.length > 0) lines.push(`harnesses: ${ctx.harnesses.join(", ")}`);
786
+ if (ctx.launcher) lines.push(`launched by: ${ctx.launcher}`);
787
+ if (ctx.cli) lines.push(`cli: ${ctx.cli}`);
788
+ return lines.join("\n");
789
+ }
790
+
791
+ // src/lib/browser.ts
792
+ var DEFAULT_APP_URL = "https://app.withone.ai";
793
+ function oneAppUrl() {
794
+ const override = process.env.ONE_APP_URL?.trim();
795
+ return (override || DEFAULT_APP_URL).replace(/\/+$/, "");
796
+ }
797
+ function getConnectionUrl(platform, params) {
798
+ const searchParams = new URLSearchParams();
799
+ if (params?.orgId) searchParams.set("orgId", params.orgId);
800
+ if (params?.projectId) searchParams.set("projectId", params.projectId);
801
+ if (params?.env) searchParams.set("env", params.env);
802
+ const qs = searchParams.toString();
803
+ return `${oneAppUrl()}/${qs ? `?${qs}` : ""}#open=${platform}`;
804
+ }
805
+ function getApiKeyUrl() {
806
+ return `${oneAppUrl()}/settings/api-keys`;
807
+ }
808
+ async function openConnectionPage(platform, params) {
809
+ await open(getConnectionUrl(platform, params));
810
+ }
811
+ async function openApiKeyPage() {
812
+ await open(getApiKeyUrl());
813
+ }
814
+ function getCliAuthUrl(port, state, context) {
815
+ const params = new URLSearchParams([
816
+ ["port", String(port)],
817
+ ["state", state],
818
+ ...context ? installContextToParams(context) : []
819
+ ]);
820
+ return `${oneAppUrl()}/cli/auth?${params.toString()}`;
821
+ }
822
+
823
+ // src/commands/config.ts
824
+ import * as p from "@clack/prompts";
825
+ import pc2 from "picocolors";
826
+ async function configCommand() {
827
+ if (isAgentMode()) {
828
+ error("This command requires interactive input. Run without --agent.");
829
+ }
830
+ const config2 = readConfig();
831
+ if (!config2) {
832
+ p.log.error(`No One config found. Run ${pc2.cyan("one init")} first.`);
833
+ return;
834
+ }
835
+ p.intro(pc2.bgCyan(pc2.black(" One Access Control ")));
836
+ const current = getAccessControl();
837
+ console.log();
838
+ console.log(` ${pc2.bold("Current Access Control")}`);
839
+ console.log(` ${pc2.dim("\u2500".repeat(42))}`);
840
+ console.log(` ${pc2.dim("Permissions:")} ${current.permissions ?? "admin"}`);
841
+ console.log(` ${pc2.dim("Connections:")} ${formatList(current.connectionKeys)}`);
842
+ console.log(` ${pc2.dim("Action IDs:")} ${formatList(current.actionIds)}`);
843
+ console.log(` ${pc2.dim("Knowledge only:")} ${current.knowledgeAgent ? "yes" : "no"}`);
844
+ console.log();
845
+ const permissions = await p.select({
846
+ message: "Permission level",
847
+ options: [
848
+ { value: "admin", label: "Admin", hint: "Full access (GET, POST, PUT, PATCH, DELETE)" },
849
+ { value: "write", label: "Write", hint: "GET, POST, PUT, PATCH" },
850
+ { value: "read", label: "Read", hint: "GET only" }
851
+ ],
852
+ initialValue: current.permissions ?? "admin"
853
+ });
854
+ if (p.isCancel(permissions)) {
855
+ p.outro("No changes made.");
856
+ return;
857
+ }
858
+ const connectionMode = await p.select({
859
+ message: "Connection scope",
860
+ options: [
861
+ { value: "all", label: "All connections" },
862
+ { value: "specific", label: "Select specific connections" }
863
+ ],
864
+ initialValue: current.connectionKeys ? "specific" : "all"
865
+ });
866
+ if (p.isCancel(connectionMode)) {
867
+ p.outro("No changes made.");
868
+ return;
869
+ }
870
+ let connectionKeys;
871
+ if (connectionMode === "specific") {
872
+ connectionKeys = await selectConnections(config2.apiKey);
873
+ if (connectionKeys === void 0) {
874
+ p.outro("No changes made.");
875
+ return;
876
+ }
877
+ if (connectionKeys.length === 0) {
878
+ p.log.info(`No connections found. Defaulting to all. Use ${pc2.cyan("one add")} to connect platforms.`);
879
+ connectionKeys = void 0;
880
+ }
881
+ }
882
+ const actionMode = await p.select({
883
+ message: "Action scope",
432
884
  options: [
433
885
  { value: "all", label: "All actions" },
434
886
  { value: "specific", label: "Restrict to specific action IDs" }
@@ -464,8 +916,8 @@ async function configCommand() {
464
916
  p.outro("No changes made.");
465
917
  return;
466
918
  }
467
- const currentBase = getApiBase();
468
- const isCustomBase = !!readConfig()?.apiBase;
919
+ const storedBase = readConfig()?.apiBase;
920
+ const isCustomBase = !!storedBase;
469
921
  const baseUrlMode = await p.select({
470
922
  message: "API base URL",
471
923
  options: [
@@ -483,7 +935,7 @@ async function configCommand() {
483
935
  const customUrl = await p.text({
484
936
  message: "Enter API base URL:",
485
937
  placeholder: "https://development-api.withone.ai",
486
- initialValue: isCustomBase ? currentBase.replace(/\/v1$/, "") : "",
938
+ initialValue: storedBase ? storedBase.replace(/\/v1$/, "") : "",
487
939
  validate: (value) => {
488
940
  if (!value) return "URL is required";
489
941
  try {
@@ -500,7 +952,7 @@ async function configCommand() {
500
952
  }
501
953
  const normalized = customUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
502
954
  const apiKey = await p.text({
503
- message: `Enter your API key for ${pc.cyan(normalized)}:`,
955
+ message: `Enter your API key for ${pc2.cyan(normalized)}:`,
504
956
  placeholder: "sk_live_...",
505
957
  validate: (value) => {
506
958
  if (!value) return "API key is required";
@@ -514,29 +966,29 @@ async function configCommand() {
514
966
  p.outro("No changes made.");
515
967
  return;
516
968
  }
517
- const spinner5 = p.spinner();
518
- spinner5.start("Validating API key...");
969
+ const spinner4 = p.spinner();
970
+ spinner4.start("Validating API key...");
519
971
  let isValid = false;
520
972
  try {
521
973
  const api = new OneApi(apiKey, `${normalized}/v1`);
522
974
  isValid = Boolean(await api.validateApiKey());
523
975
  } catch (err) {
524
- spinner5.stop("Connection failed");
976
+ spinner4.stop("Connection failed");
525
977
  const msg = err instanceof Error ? err.message : String(err);
526
- p.log.error(`Could not reach ${pc.cyan(normalized)}: ${msg}`);
978
+ p.log.error(`Could not reach ${pc2.cyan(normalized)}: ${msg}`);
527
979
  return;
528
980
  }
529
981
  if (!isValid) {
530
- spinner5.stop("Invalid API key");
531
- p.log.error(`Invalid API key for ${pc.cyan(normalized)}.`);
982
+ spinner4.stop("Invalid API key");
983
+ p.log.error(`Invalid API key for ${pc2.cyan(normalized)}.`);
532
984
  return;
533
985
  }
534
- spinner5.stop("API key validated");
986
+ spinner4.stop("API key validated");
535
987
  updateApiBase(normalized);
536
988
  newApiKey = apiKey;
537
989
  } else if (isCustomBase) {
538
990
  const apiKey = await p.text({
539
- message: `Enter your API key for ${pc.cyan("https://api.withone.ai")}:`,
991
+ message: `Enter your API key for ${pc2.cyan("https://api.withone.ai")}:`,
540
992
  placeholder: "sk_live_...",
541
993
  validate: (value) => {
542
994
  if (!value) return "API key is required";
@@ -550,24 +1002,24 @@ async function configCommand() {
550
1002
  p.outro("No changes made.");
551
1003
  return;
552
1004
  }
553
- const spinner5 = p.spinner();
554
- spinner5.start("Validating API key...");
1005
+ const spinner4 = p.spinner();
1006
+ spinner4.start("Validating API key...");
555
1007
  let isValid = false;
556
1008
  try {
557
1009
  const api = new OneApi(apiKey, "https://api.withone.ai/v1");
558
1010
  isValid = Boolean(await api.validateApiKey());
559
1011
  } catch (err) {
560
- spinner5.stop("Connection failed");
1012
+ spinner4.stop("Connection failed");
561
1013
  const msg = err instanceof Error ? err.message : String(err);
562
- p.log.error(`Could not reach ${pc.cyan("https://api.withone.ai")}: ${msg}`);
1014
+ p.log.error(`Could not reach ${pc2.cyan("https://api.withone.ai")}: ${msg}`);
563
1015
  return;
564
1016
  }
565
1017
  if (!isValid) {
566
- spinner5.stop("Invalid API key");
1018
+ spinner4.stop("Invalid API key");
567
1019
  p.log.error(`Invalid API key. Get a valid key at ${getApiKeyUrl()}`);
568
1020
  return;
569
1021
  }
570
- spinner5.stop("API key validated");
1022
+ spinner4.stop("API key validated");
571
1023
  updateApiBase(null);
572
1024
  newApiKey = apiKey;
573
1025
  }
@@ -581,7 +1033,9 @@ async function configCommand() {
581
1033
  const updatedConfig = readConfig();
582
1034
  if (updatedConfig && newApiKey !== config2.apiKey) {
583
1035
  updatedConfig.apiKey = newApiKey;
1036
+ delete updatedConfig.apiKeyName;
584
1037
  delete updatedConfig.whoami;
1038
+ delete updatedConfig.whoamiApiBase;
585
1039
  writeConfig(updatedConfig);
586
1040
  }
587
1041
  const ac = getAccessControl();
@@ -603,16 +1057,16 @@ async function configCommand() {
603
1057
  p.outro("Configuration updated.");
604
1058
  }
605
1059
  async function selectConnections(apiKey) {
606
- const spinner5 = p.spinner();
607
- spinner5.start("Fetching connections...");
1060
+ const spinner4 = p.spinner();
1061
+ spinner4.start("Fetching connections...");
608
1062
  let connections;
609
1063
  try {
610
1064
  const api = new OneApi(apiKey, getApiBase());
611
1065
  const rawConnections = await api.listConnections();
612
1066
  connections = rawConnections.map((c) => ({ platform: c.platform, key: c.key }));
613
- spinner5.stop(`Found ${connections.length} connection(s)`);
1067
+ spinner4.stop(`Found ${connections.length} connection(s)`);
614
1068
  } catch {
615
- spinner5.stop("Could not fetch connections");
1069
+ spinner4.stop("Could not fetch connections");
616
1070
  const manual = await p.text({
617
1071
  message: "Enter connection keys manually (comma-separated):",
618
1072
  placeholder: "conn_key_1, conn_key_2",
@@ -645,46 +1099,18 @@ function formatList(list) {
645
1099
  }
646
1100
 
647
1101
  // src/commands/init.ts
648
- import open2 from "open";
1102
+ import open3 from "open";
649
1103
 
650
1104
  // src/lib/skill-sync.ts
651
- import fs2 from "fs";
652
- import path3 from "path";
1105
+ import fs3 from "fs";
1106
+ import path4 from "path";
653
1107
  import { fileURLToPath as fileURLToPath2 } from "url";
654
1108
 
655
1109
  // src/commands/update.ts
656
1110
  import { spawn } from "child_process";
657
1111
  import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync, rmSync, openSync, closeSync } from "fs";
658
1112
  import { delimiter, dirname, join } from "path";
659
- import pc2 from "picocolors";
660
-
661
- // src/lib/version.ts
662
- import { createRequire } from "module";
663
- import { existsSync } from "fs";
664
- import path2 from "path";
665
- import { fileURLToPath } from "url";
666
- var require2 = createRequire(import.meta.url);
667
- var cached = null;
668
- function cliVersion() {
669
- if (cached !== null) return cached;
670
- const dir = path2.dirname(fileURLToPath(import.meta.url));
671
- for (let i = 1; i <= 4; i++) {
672
- const candidate = path2.resolve(dir, ...Array(i).fill(".."), "package.json");
673
- if (!existsSync(candidate)) continue;
674
- try {
675
- const version2 = require2(candidate).version;
676
- if (version2) {
677
- cached = version2;
678
- return cached;
679
- }
680
- } catch {
681
- }
682
- }
683
- cached = "unknown";
684
- return cached;
685
- }
686
-
687
- // src/commands/update.ts
1113
+ import pc3 from "picocolors";
688
1114
  var currentVersion = cliVersion();
689
1115
  var ONE_DIR = () => join(homeDir(), ".one");
690
1116
  var CACHE_PATH = () => join(ONE_DIR(), "update-check.json");
@@ -860,10 +1286,10 @@ function maybeWarnAboutFailedUpdates(targetVersion) {
860
1286
  if (!shouldWarnAboutFailedUpdates(state)) return;
861
1287
  writeAutoUpdateState({ ...state, lastNoticeAt: Date.now() });
862
1288
  process.stderr.write(
863
- pc2.yellow(
1289
+ pc3.yellow(
864
1290
  `One CLI could not auto-update (v${currentVersion} \u2192 v${targetVersion}) after ${state.failures} attempts.
865
1291
  `
866
- ) + pc2.dim(
1292
+ ) + pc3.dim(
867
1293
  `Update manually with: npm install -g @withone/cli@latest
868
1294
  Details: ${LOG_PATH()}. Silence this with ONE_NO_AUTO_UPDATE=1.
869
1295
  `
@@ -960,42 +1386,42 @@ function autoUpdate(targetVersion, publishedAt) {
960
1386
  var CANONICAL_SKILL_DIR = ".agents/skills";
961
1387
  var VERSION_MARKER = ".one-cli-version";
962
1388
  function getPackagedSkillDir() {
963
- const here = path3.dirname(fileURLToPath2(import.meta.url));
964
- return path3.resolve(here, "..", "skills", "one");
1389
+ const here = path4.dirname(fileURLToPath2(import.meta.url));
1390
+ return path4.resolve(here, "..", "skills", "one");
965
1391
  }
966
1392
  function getCanonicalSkillPath() {
967
- return path3.join(homeDir(), CANONICAL_SKILL_DIR, "one");
1393
+ return path4.join(homeDir(), CANONICAL_SKILL_DIR, "one");
968
1394
  }
969
1395
  function getVersionMarkerPath() {
970
- return path3.join(getCanonicalSkillPath(), VERSION_MARKER);
1396
+ return path4.join(getCanonicalSkillPath(), VERSION_MARKER);
971
1397
  }
972
1398
  function isSkillInstalled() {
973
- return fs2.existsSync(path3.join(getCanonicalSkillPath(), "SKILL.md"));
1399
+ return fs3.existsSync(path4.join(getCanonicalSkillPath(), "SKILL.md"));
974
1400
  }
975
1401
  function readInstalledSkillVersion() {
976
1402
  try {
977
- return fs2.readFileSync(getVersionMarkerPath(), "utf-8").trim() || null;
1403
+ return fs3.readFileSync(getVersionMarkerPath(), "utf-8").trim() || null;
978
1404
  } catch {
979
1405
  return null;
980
1406
  }
981
1407
  }
982
1408
  function writeInstalledSkillVersion(version2) {
983
1409
  try {
984
- fs2.mkdirSync(getCanonicalSkillPath(), { recursive: true });
985
- fs2.writeFileSync(getVersionMarkerPath(), `${version2}
1410
+ fs3.mkdirSync(getCanonicalSkillPath(), { recursive: true });
1411
+ fs3.writeFileSync(getVersionMarkerPath(), `${version2}
986
1412
  `);
987
1413
  } catch {
988
1414
  }
989
1415
  }
990
1416
  function copyDirSync(src, dest) {
991
- fs2.mkdirSync(dest, { recursive: true });
992
- for (const entry of fs2.readdirSync(src, { withFileTypes: true })) {
993
- const srcPath = path3.join(src, entry.name);
994
- const destPath = path3.join(dest, entry.name);
1417
+ fs3.mkdirSync(dest, { recursive: true });
1418
+ for (const entry of fs3.readdirSync(src, { withFileTypes: true })) {
1419
+ const srcPath = path4.join(src, entry.name);
1420
+ const destPath = path4.join(dest, entry.name);
995
1421
  if (entry.isDirectory()) {
996
1422
  copyDirSync(srcPath, destPath);
997
1423
  } else {
998
- fs2.copyFileSync(srcPath, destPath);
1424
+ fs3.copyFileSync(srcPath, destPath);
999
1425
  }
1000
1426
  }
1001
1427
  }
@@ -1018,7 +1444,7 @@ function forceSyncSkills() {
1018
1444
  }
1019
1445
  function performSync(current, reason) {
1020
1446
  const source = getPackagedSkillDir();
1021
- if (!fs2.existsSync(path3.join(source, "SKILL.md"))) {
1447
+ if (!fs3.existsSync(path4.join(source, "SKILL.md"))) {
1022
1448
  return { synced: false, reason: "source-missing" };
1023
1449
  }
1024
1450
  const canonical = getCanonicalSkillPath();
@@ -1047,21 +1473,36 @@ function getSkillStatus() {
1047
1473
  // src/commands/login.ts
1048
1474
  import http from "http";
1049
1475
  import crypto from "crypto";
1476
+ import open2 from "open";
1050
1477
  import * as p2 from "@clack/prompts";
1051
1478
  var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
1052
1479
  var PORT_RANGE_START = 49152;
1053
1480
  var PORT_RANGE_END = 65535;
1054
1481
  var MAX_PORT_ATTEMPTS = 5;
1055
- var SUCCESS_HTML = `<!DOCTYPE html>
1482
+ var MAX_KEY_NAME_LENGTH = 120;
1483
+ var MAX_ERROR_LENGTH = 200;
1484
+ var CHECK_MARK = `<div style="width:48px;height:48px;border-radius:50%;background:rgba(34,197,94,0.1);display:flex;align-items:center;justify-content:center;margin:0 auto 16px">
1485
+ <svg width="24" height="24" fill="none" stroke="#22c55e" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
1486
+ </div>`;
1487
+ function statusPage(title, body, check = false) {
1488
+ return `<!DOCTYPE html>
1056
1489
  <html><head><title>One CLI</title></head>
1057
1490
  <body style="font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#0a0a0a;color:#fafafa">
1058
1491
  <div style="text-align:center">
1059
- <div style="width:48px;height:48px;border-radius:50%;background:rgba(34,197,94,0.1);display:flex;align-items:center;justify-content:center;margin:0 auto 16px">
1060
- <svg width="24" height="24" fill="none" stroke="#22c55e" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
1061
- </div>
1062
- <h1 style="font-size:20px;margin:0 0 8px">You're all set!</h1>
1063
- <p style="color:#a1a1aa;font-size:14px">Return to your terminal. You can close this tab.</p>
1492
+ ${check ? CHECK_MARK : ""}
1493
+ <h1 style="font-size:20px;margin:0 0 8px">${title}</h1>
1494
+ <p style="color:#a1a1aa;font-size:14px">${body}</p>
1064
1495
  </div></body></html>`;
1496
+ }
1497
+ var SUCCESS_HTML = statusPage("You're all set!", "Return to your terminal. You can close this tab.", true);
1498
+ var CANCELLED_HTML = statusPage("Login cancelled", "No key was created. You can close this tab and run <code>one login</code> again.");
1499
+ var FAILED_HTML = statusPage("Login did not complete", "The consent page reported an error. Return to your terminal for details, then run <code>one login</code> again.");
1500
+ function cleanParam(value, max) {
1501
+ if (value === null) return void 0;
1502
+ const cleaned = value.replace(/[\u0000-\u001f\u007f-\u009f]/g, "").trim();
1503
+ if (!cleaned) return void 0;
1504
+ return Array.from(cleaned).slice(0, max).join("");
1505
+ }
1065
1506
  function randomPort() {
1066
1507
  return PORT_RANGE_START + Math.floor(Math.random() * (PORT_RANGE_END - PORT_RANGE_START));
1067
1508
  }
@@ -1082,12 +1523,10 @@ function startCallbackServer(expectedState) {
1082
1523
  res.end("Not found");
1083
1524
  return;
1084
1525
  }
1085
- const encodedKey = url.searchParams.get("s");
1086
1526
  const state = url.searchParams.get("state");
1087
- const apiKey = encodedKey ? Buffer.from(encodedKey, "base64").toString("utf-8") : null;
1088
- if (!apiKey || !state) {
1527
+ if (!state) {
1089
1528
  res.writeHead(400, { "Content-Type": "text/plain" });
1090
- res.end("Missing required parameters");
1529
+ res.end("Missing state");
1091
1530
  return;
1092
1531
  }
1093
1532
  if (state !== expectedState) {
@@ -1095,12 +1534,38 @@ function startCallbackServer(expectedState) {
1095
1534
  res.end("State mismatch");
1096
1535
  return;
1097
1536
  }
1098
- res.writeHead(200, { "Content-Type": "text/html" });
1099
- res.end(SUCCESS_HTML);
1100
- resolveResult({ apiKey, state });
1537
+ const encodedKey = url.searchParams.get("s");
1538
+ if (encodedKey) {
1539
+ const apiKey = Buffer.from(encodedKey, "base64").toString("utf-8");
1540
+ if (!apiKey) {
1541
+ res.writeHead(400, { "Content-Type": "text/plain" });
1542
+ res.end("Missing required parameters");
1543
+ return;
1544
+ }
1545
+ const keyName = cleanParam(url.searchParams.get("name"), MAX_KEY_NAME_LENGTH);
1546
+ res.writeHead(200, { "Content-Type": "text/html" });
1547
+ res.end(SUCCESS_HTML);
1548
+ resolveResult({ kind: "key", apiKey, keyName });
1549
+ return;
1550
+ }
1551
+ const error2 = cleanParam(url.searchParams.get("error"), MAX_ERROR_LENGTH);
1552
+ if (error2 === "cancelled") {
1553
+ res.writeHead(200, { "Content-Type": "text/html" });
1554
+ res.end(CANCELLED_HTML);
1555
+ resolveResult({ kind: "cancelled" });
1556
+ return;
1557
+ }
1558
+ if (error2) {
1559
+ res.writeHead(200, { "Content-Type": "text/html" });
1560
+ res.end(FAILED_HTML);
1561
+ resolveResult({ kind: "failed", reason: error2 });
1562
+ return;
1563
+ }
1564
+ res.writeHead(400, { "Content-Type": "text/plain" });
1565
+ res.end("Missing required parameters");
1101
1566
  });
1102
1567
  server.on("error", (err) => {
1103
- if (err.code === "EADDRINUSE" && attempts < MAX_PORT_ATTEMPTS) {
1568
+ if ((err.code === "EADDRINUSE" || err.code === "EACCES") && attempts < MAX_PORT_ATTEMPTS) {
1104
1569
  tryListen();
1105
1570
  return;
1106
1571
  }
@@ -1113,9 +1578,9 @@ function startCallbackServer(expectedState) {
1113
1578
  tryListen();
1114
1579
  });
1115
1580
  }
1116
- async function browserLogin() {
1581
+ async function browserLogin(opts) {
1117
1582
  const state = crypto.randomUUID();
1118
- const spin = p2.spinner();
1583
+ const spin = createSpinner();
1119
1584
  let server;
1120
1585
  let port;
1121
1586
  let resultPromise;
@@ -1125,14 +1590,24 @@ async function browserLogin() {
1125
1590
  error("Could not start local server. Try: one init");
1126
1591
  return null;
1127
1592
  }
1128
- const authUrl = getCliAuthUrl(port, state);
1129
- p2.note(
1130
- `If the browser doesn't open, visit:
1131
- ${authUrl}`,
1132
- "Opening browser for authentication..."
1133
- );
1593
+ const context = collectInstallContext({ scope: opts.scope });
1594
+ const authUrl = getCliAuthUrl(port, state, context);
1595
+ if (isAgentMode()) {
1596
+ process.stderr.write(`Opening the browser for authentication. If it doesn't open, visit:
1597
+ ${authUrl}
1598
+ `);
1599
+ } else {
1600
+ note(
1601
+ `If the browser doesn't open, visit:
1602
+ ${authUrl}
1603
+
1604
+ The consent page records this on the key so you can find the install later:
1605
+ ${describeInstallContext(context)}`,
1606
+ "Opening browser for authentication..."
1607
+ );
1608
+ }
1134
1609
  try {
1135
- await openCliAuthPage(port, state);
1610
+ await open2(authUrl);
1136
1611
  } catch {
1137
1612
  }
1138
1613
  spin.start("Waiting for authentication... (timeout: 5 min)");
@@ -1143,12 +1618,20 @@ ${authUrl}`,
1143
1618
  timer.unref();
1144
1619
  });
1145
1620
  try {
1146
- const payload = await Promise.race([resultPromise, timeout]);
1621
+ const outcome = await Promise.race([resultPromise, timeout]);
1622
+ if (outcome.kind === "cancelled") {
1623
+ spin.stop("Login cancelled in the browser.");
1624
+ return null;
1625
+ }
1626
+ if (outcome.kind === "failed") {
1627
+ spin.stop("Authentication failed.");
1628
+ error(`The consent page reported an error: ${outcome.reason}. Try again with: one login`);
1629
+ }
1147
1630
  spin.stop("Authentication received!");
1148
1631
  const apiBase = getApiBase();
1149
- const api = new OneApi(payload.apiKey, apiBase);
1632
+ const api = new OneApi(outcome.apiKey, apiBase);
1150
1633
  const whoami = await api.whoami();
1151
- return { apiKey: payload.apiKey, whoami };
1634
+ return { apiKey: outcome.apiKey, whoami, keyName: outcome.keyName };
1152
1635
  } catch (err) {
1153
1636
  spin.stop("Authentication failed.");
1154
1637
  if (err instanceof Error && err.message === "timeout") {
@@ -1164,17 +1647,6 @@ ${authUrl}`,
1164
1647
  server.close();
1165
1648
  }
1166
1649
  }
1167
- function saveCredentials(apiKey, scope) {
1168
- const existing = scope === "project" ? readProjectConfig() : readGlobalConfig();
1169
- writeConfig({
1170
- apiKey,
1171
- installedAgents: existing?.installedAgents ?? [],
1172
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1173
- accessControl: existing?.accessControl,
1174
- cacheTtl: existing?.cacheTtl,
1175
- apiBase: existing?.apiBase
1176
- }, scope);
1177
- }
1178
1650
  async function loginCommand() {
1179
1651
  if (isAgentMode()) {
1180
1652
  json({ error: "Browser login not available in agent mode. Use: one init" });
@@ -1184,11 +1656,11 @@ async function loginCommand() {
1184
1656
  const existingKey = getApiKey();
1185
1657
  if (existingKey) {
1186
1658
  const pc17 = (await import("picocolors")).default;
1187
- const resolved2 = resolveConfig();
1188
- const whoami2 = resolved2.config?.whoami;
1659
+ const resolved = resolveConfig();
1660
+ const whoami2 = resolved.config?.whoami;
1189
1661
  const env2 = getEnvFromApiKey(existingKey);
1190
1662
  const envLabel2 = env2 === "test" ? pc17.yellow("test") : pc17.green("live");
1191
- const currentScope = resolved2.scope === "project" ? pc17.cyan("local config") : pc17.magenta("global config");
1663
+ const currentScope = resolved.scope === "project" ? pc17.cyan("local config") : pc17.magenta("global config");
1192
1664
  const lines = ["You are already logged in.", ""];
1193
1665
  if (whoami2) {
1194
1666
  const contextParts2 = [];
@@ -1216,14 +1688,10 @@ async function loginCommand() {
1216
1688
  }
1217
1689
  targetScope = scopeChoice;
1218
1690
  }
1219
- const result = await browserLogin();
1691
+ const result = await browserLogin({ scope: targetScope });
1220
1692
  if (!result) return;
1221
- const { apiKey, whoami } = result;
1222
- saveCredentials(apiKey, targetScope);
1223
- const resolved = resolveConfig();
1224
- if (resolved.config) {
1225
- writeConfig({ ...resolved.config, whoami }, targetScope);
1226
- }
1693
+ const { apiKey, whoami, keyName } = result;
1694
+ saveCredentials(apiKey, targetScope, { keyName, whoami });
1227
1695
  const pc16 = (await import("picocolors")).default;
1228
1696
  const env = getEnvFromApiKey(apiKey);
1229
1697
  const contextParts = [];
@@ -1236,6 +1704,7 @@ async function loginCommand() {
1236
1704
  `${pc16.bold(scopeDisplay)} ${pc16.dim("\xB7")} ${envLabel}`,
1237
1705
  `${whoami.user.name} ${pc16.dim(`(${whoami.user.email})`)}`
1238
1706
  ];
1707
+ if (keyName) infoLines.push(`${pc16.dim("Key:")} ${keyName}`);
1239
1708
  if (whoami.organization) infoLines.push(`${pc16.dim("Org:")} ${whoami.organization.name}`);
1240
1709
  if (whoami.project) infoLines.push(`${pc16.dim("Project:")} ${whoami.project.name}`);
1241
1710
  infoLines.push("");
@@ -1291,13 +1760,15 @@ async function nonInteractiveInit(options) {
1291
1760
  }
1292
1761
  const scope = options.global ? "global" : options.project ? "project" : "global";
1293
1762
  let apiKey;
1763
+ let keyName;
1294
1764
  let whoami;
1295
1765
  if (auth === "browser") {
1296
- const result = await browserLogin();
1766
+ const result = await browserLogin({ scope });
1297
1767
  if (!result) {
1298
1768
  error("Browser login did not complete. Try again: one init --auth browser");
1299
1769
  }
1300
1770
  apiKey = result.apiKey;
1771
+ keyName = result.keyName;
1301
1772
  whoami = result.whoami;
1302
1773
  } else {
1303
1774
  const key = options.apiKey?.trim();
@@ -1321,19 +1792,7 @@ async function nonInteractiveInit(options) {
1321
1792
  apiKey = key;
1322
1793
  whoami = validated;
1323
1794
  }
1324
- const existing = scope === "project" ? readProjectConfig() : readGlobalConfig();
1325
- writeConfig(
1326
- {
1327
- apiKey,
1328
- installedAgents: existing?.installedAgents ?? [],
1329
- createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1330
- accessControl: existing?.accessControl,
1331
- apiBase: existing?.apiBase,
1332
- cacheTtl: existing?.cacheTtl,
1333
- whoami
1334
- },
1335
- scope
1336
- );
1795
+ saveCredentials(apiKey, scope, { keyName, whoami });
1337
1796
  if (options.openaiKey?.trim()) {
1338
1797
  try {
1339
1798
  setOpenAiApiKey(options.openaiKey.trim());
@@ -1355,6 +1814,7 @@ async function nonInteractiveInit(options) {
1355
1814
  project: whoami.project,
1356
1815
  env: getEnvFromApiKey(apiKey)
1357
1816
  },
1817
+ keyName,
1358
1818
  skillInstalled: installed,
1359
1819
  skillFailed: failed
1360
1820
  });
@@ -1365,18 +1825,19 @@ async function nonInteractiveInit(options) {
1365
1825
  if (whoami.organization) contextParts.push(whoami.organization.name);
1366
1826
  if (whoami.project) contextParts.push(whoami.project.name);
1367
1827
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
1368
- const envLabel = env === "test" ? pc3.yellow("test") : pc3.green("live");
1828
+ const envLabel = env === "test" ? pc4.yellow("test") : pc4.green("live");
1369
1829
  console.log();
1370
- console.log(` ${pc3.bold("Setup complete")} ${scopeLabel(scope)}`);
1371
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
1372
- console.log(` ${pc3.dim("Account:")} ${scopeDisplay} ${pc3.dim("\xB7")} ${envLabel}`);
1373
- console.log(` ${pc3.dim("User:")} ${whoami.user.name} ${pc3.dim(`(${whoami.user.email})`)}`);
1374
- console.log(` ${pc3.dim("Config:")} ${tildify(configPath)}`);
1830
+ console.log(` ${pc4.bold("Setup complete")} ${scopeLabel(scope)}`);
1831
+ console.log(` ${pc4.dim("\u2500".repeat(42))}`);
1832
+ console.log(` ${pc4.dim("Account:")} ${scopeDisplay} ${pc4.dim("\xB7")} ${envLabel}`);
1833
+ console.log(` ${pc4.dim("User:")} ${whoami.user.name} ${pc4.dim(`(${whoami.user.email})`)}`);
1834
+ if (keyName) console.log(` ${pc4.dim("Key:")} ${keyName}`);
1835
+ console.log(` ${pc4.dim("Config:")} ${tildify(configPath)}`);
1375
1836
  if (installed.length > 0) {
1376
- console.log(` ${pc3.dim("Skill:")} ${pc3.green("installed")} ${pc3.dim("\xB7 " + installed.join(", "))}`);
1837
+ console.log(` ${pc4.dim("Skill:")} ${pc4.green("installed")} ${pc4.dim("\xB7 " + installed.join(", "))}`);
1377
1838
  }
1378
1839
  console.log();
1379
- console.log(` ${pc3.dim("Connect a platform later with")} ${pc3.cyan("one add <platform>")}`);
1840
+ console.log(` ${pc4.dim("Connect a platform later with")} ${pc4.cyan("one add <platform>")}`);
1380
1841
  printOnboardingPrompt();
1381
1842
  }
1382
1843
  async function chooseConfigScope(options) {
@@ -1386,13 +1847,13 @@ async function chooseConfigScope(options) {
1386
1847
  const hasGlobal = globalConfigExists();
1387
1848
  const hasProject = projectConfigExists();
1388
1849
  const projectRoot = resolved.projectRoot;
1389
- const projectName = path4.basename(projectRoot);
1850
+ const projectName = path5.basename(projectRoot);
1390
1851
  const homeGlobal = tildify(getGlobalConfigPath());
1391
1852
  const homeProject = tildify(getProjectConfigPath(projectRoot));
1392
1853
  if (hasProject) {
1393
1854
  console.log();
1394
- console.log(` ${pc3.dim("Project:")} ${projectName} ${pc3.dim(projectRoot)}`);
1395
- console.log(` ${pc3.bold("Active config:")} ${pc3.cyan("project")} ${pc3.dim("\xB7 " + homeProject)}`);
1855
+ console.log(` ${pc4.dim("Project:")} ${projectName} ${pc4.dim(projectRoot)}`);
1856
+ console.log(` ${pc4.bold("Active config:")} ${pc4.cyan("project")} ${pc4.dim("\xB7 " + homeProject)}`);
1396
1857
  console.log();
1397
1858
  if (hasGlobal) {
1398
1859
  const which2 = await p3.select({
@@ -1409,11 +1870,11 @@ async function chooseConfigScope(options) {
1409
1870
  return "project";
1410
1871
  }
1411
1872
  console.log();
1412
- console.log(` ${pc3.bold("Initializing One")}`);
1413
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
1414
- console.log(` ${pc3.dim("Project:")} ${projectName} ${pc3.dim(projectRoot)}`);
1415
- console.log(` ${pc3.dim("Global:")} ${hasGlobal ? pc3.green("\u2713 configured") : pc3.yellow("\u2014 not set up")} ${pc3.dim(homeGlobal)}`);
1416
- console.log(` ${pc3.dim("Project:")} ${pc3.yellow("\u2014 not set up")} ${pc3.dim(homeProject)}`);
1873
+ console.log(` ${pc4.bold("Initializing One")}`);
1874
+ console.log(` ${pc4.dim("\u2500".repeat(42))}`);
1875
+ console.log(` ${pc4.dim("Project:")} ${projectName} ${pc4.dim(projectRoot)}`);
1876
+ console.log(` ${pc4.dim("Global:")} ${hasGlobal ? pc4.green("\u2713 configured") : pc4.yellow("\u2014 not set up")} ${pc4.dim(homeGlobal)}`);
1877
+ console.log(` ${pc4.dim("Project:")} ${pc4.yellow("\u2014 not set up")} ${pc4.dim(homeProject)}`);
1417
1878
  console.log();
1418
1879
  const defaultScope = hasGlobal ? "project" : "global";
1419
1880
  const hint = hasGlobal ? "Your global config stays as-is. This folder gets its own setup." : "No global config yet \u2014 this becomes your default for every folder.";
@@ -1442,7 +1903,7 @@ function tildify(filePath) {
1442
1903
  return filePath.startsWith(home) ? "~" + filePath.slice(home.length) : filePath;
1443
1904
  }
1444
1905
  function scopeLabel(scope) {
1445
- return scope === "project" ? pc3.cyan("[project]") : pc3.magenta("[global]");
1906
+ return scope === "project" ? pc4.cyan("[project]") : pc4.magenta("[global]");
1446
1907
  }
1447
1908
  function scopedMessage(scope, message) {
1448
1909
  return `${scopeLabel(scope)} ${message}`;
@@ -1453,20 +1914,20 @@ async function handleExistingConfig(apiKey, scope, options) {
1453
1914
  const skillInstalled = isSkillInstalled2();
1454
1915
  const activeConfigPath = scope === "project" ? getProjectConfigPath() : getGlobalConfigPath();
1455
1916
  console.log();
1456
- console.log(` ${pc3.bold("Current Setup")} ${scopeLabel(scope)}`);
1457
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
1458
- console.log(` ${pc3.dim("API Key:")} ${masked}`);
1459
- console.log(` ${pc3.dim("Skill:")} ${skillInstalled ? pc3.green("installed") : pc3.yellow("not installed")}`);
1460
- console.log(` ${pc3.dim("Config:")} ${tildify(activeConfigPath)}`);
1917
+ console.log(` ${pc4.bold("Current Setup")} ${scopeLabel(scope)}`);
1918
+ console.log(` ${pc4.dim("\u2500".repeat(42))}`);
1919
+ console.log(` ${pc4.dim("API Key:")} ${masked}`);
1920
+ console.log(` ${pc4.dim("Skill:")} ${skillInstalled ? pc4.green("installed") : pc4.yellow("not installed")}`);
1921
+ console.log(` ${pc4.dim("Config:")} ${tildify(activeConfigPath)}`);
1461
1922
  const ac = getAccessControl();
1462
1923
  if (Object.keys(ac).length > 0) {
1463
1924
  console.log();
1464
- console.log(` ${pc3.bold("Access Control")}`);
1465
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
1466
- if (ac.permissions) console.log(` ${pc3.dim("Permissions:")} ${ac.permissions}`);
1467
- if (ac.connectionKeys) console.log(` ${pc3.dim("Connections:")} ${ac.connectionKeys.join(", ")}`);
1468
- if (ac.actionIds) console.log(` ${pc3.dim("Action IDs:")} ${ac.actionIds.join(", ")}`);
1469
- if (ac.knowledgeAgent) console.log(` ${pc3.dim("Knowledge only:")} yes`);
1925
+ console.log(` ${pc4.bold("Access Control")}`);
1926
+ console.log(` ${pc4.dim("\u2500".repeat(42))}`);
1927
+ if (ac.permissions) console.log(` ${pc4.dim("Permissions:")} ${ac.permissions}`);
1928
+ if (ac.connectionKeys) console.log(` ${pc4.dim("Connections:")} ${ac.connectionKeys.join(", ")}`);
1929
+ if (ac.actionIds) console.log(` ${pc4.dim("Action IDs:")} ${ac.actionIds.join(", ")}`);
1930
+ if (ac.knowledgeAgent) console.log(` ${pc4.dim("Knowledge only:")} yes`);
1470
1931
  }
1471
1932
  console.log();
1472
1933
  const actionOptions = [];
@@ -1565,18 +2026,20 @@ async function handleUpdateKey(statuses, scope) {
1565
2026
  process.exit(0);
1566
2027
  }
1567
2028
  let newKey;
2029
+ let keyName;
1568
2030
  let whoamiResult;
1569
2031
  if (authMethod === "browser") {
1570
- const result = await browserLogin();
2032
+ const result = await browserLogin({ scope });
1571
2033
  if (!result) {
1572
2034
  p3.cancel("Browser login did not complete.");
1573
2035
  process.exit(1);
1574
2036
  }
1575
2037
  newKey = result.apiKey;
2038
+ keyName = result.keyName;
1576
2039
  whoamiResult = result.whoami;
1577
2040
  } else {
1578
2041
  p3.note(`Get your API key at:
1579
- ${pc3.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
2042
+ ${pc4.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
1580
2043
  const openBrowser = await p3.confirm({
1581
2044
  message: scopedMessage(scope, "Open browser to get API key?"),
1582
2045
  initialValue: true
@@ -1604,16 +2067,16 @@ ${pc3.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
1604
2067
  process.exit(0);
1605
2068
  }
1606
2069
  newKey = inputKey;
1607
- const spinner5 = p3.spinner();
1608
- spinner5.start("Validating API key...");
2070
+ const spinner4 = p3.spinner();
2071
+ spinner4.start("Validating API key...");
1609
2072
  const api = new OneApi(newKey, getApiBase());
1610
2073
  const validated = await api.validateApiKey();
1611
2074
  if (!validated) {
1612
- spinner5.stop("Invalid API key");
2075
+ spinner4.stop("Invalid API key");
1613
2076
  p3.cancel(`Invalid API key. Get a valid key at ${getApiKeyUrl()}`);
1614
2077
  process.exit(1);
1615
2078
  }
1616
- spinner5.stop("API key validated");
2079
+ spinner4.stop("API key validated");
1617
2080
  whoamiResult = validated;
1618
2081
  }
1619
2082
  const env = getEnvFromApiKey(newKey);
@@ -1621,10 +2084,13 @@ ${pc3.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
1621
2084
  if (whoamiResult.organization) contextParts.push(whoamiResult.organization.name);
1622
2085
  if (whoamiResult.project) contextParts.push(whoamiResult.project.name);
1623
2086
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
1624
- const envLabel = env === "test" ? pc3.yellow("test") : pc3.green("live");
2087
+ const envLabel = env === "test" ? pc4.yellow("test") : pc4.green("live");
1625
2088
  p3.note(
1626
- `${scopeDisplay} ${pc3.dim("\xB7")} ${envLabel}
1627
- ${whoamiResult.user.name} ${pc3.dim(`(${whoamiResult.user.email})`)}`,
2089
+ [
2090
+ `${scopeDisplay} ${pc4.dim("\xB7")} ${envLabel}`,
2091
+ `${whoamiResult.user.name} ${pc4.dim(`(${whoamiResult.user.email})`)}`,
2092
+ ...keyName ? [`${pc4.dim("Key:")} ${keyName}`] : []
2093
+ ].join("\n"),
1628
2094
  "Account"
1629
2095
  );
1630
2096
  const ac = getAccessControl();
@@ -1639,19 +2105,7 @@ ${whoamiResult.user.name} ${pc3.dim(`(${whoamiResult.user.email})`)}`,
1639
2105
  reinstalled.push(`${s.agent.name} (project)`);
1640
2106
  }
1641
2107
  }
1642
- const current = scope === "project" ? readProjectConfig() : readGlobalConfig();
1643
- writeConfig(
1644
- {
1645
- apiKey: newKey,
1646
- installedAgents: current?.installedAgents ?? [],
1647
- createdAt: current?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1648
- accessControl: current?.accessControl,
1649
- apiBase: current?.apiBase,
1650
- cacheTtl: current?.cacheTtl,
1651
- whoami: whoamiResult
1652
- },
1653
- scope
1654
- );
2108
+ saveCredentials(newKey, scope, { keyName, whoami: whoamiResult });
1655
2109
  if (reinstalled.length > 0) {
1656
2110
  p3.log.success(`Updated MCP configs: ${reinstalled.join(", ")}`);
1657
2111
  }
@@ -1671,30 +2125,30 @@ var SKILL_AGENTS = [
1671
2125
  ];
1672
2126
  var CANONICAL_SKILL_DIR2 = ".agents/skills";
1673
2127
  function getSkillSourceDir() {
1674
- const __dirname2 = path4.dirname(fileURLToPath3(import.meta.url));
1675
- return path4.resolve(__dirname2, "..", "skills", "one");
2128
+ const __dirname2 = path5.dirname(fileURLToPath3(import.meta.url));
2129
+ return path5.resolve(__dirname2, "..", "skills", "one");
1676
2130
  }
1677
2131
  function getCanonicalSkillPath2() {
1678
- return path4.join(homeDir(), CANONICAL_SKILL_DIR2, "one");
2132
+ return path5.join(homeDir(), CANONICAL_SKILL_DIR2, "one");
1679
2133
  }
1680
2134
  function getAgentSkillPath(agent) {
1681
- return path4.join(homeDir(), agent.skillDir, "one");
2135
+ return path5.join(homeDir(), agent.skillDir, "one");
1682
2136
  }
1683
2137
  function isSkillInstalled2() {
1684
- return fs3.existsSync(path4.join(getCanonicalSkillPath2(), "SKILL.md"));
2138
+ return fs4.existsSync(path5.join(getCanonicalSkillPath2(), "SKILL.md"));
1685
2139
  }
1686
2140
  function isSkillInstalledForAgent(agent) {
1687
- return fs3.existsSync(path4.join(getAgentSkillPath(agent), "SKILL.md"));
2141
+ return fs4.existsSync(path5.join(getAgentSkillPath(agent), "SKILL.md"));
1688
2142
  }
1689
2143
  function copyDirSync2(src, dest) {
1690
- fs3.mkdirSync(dest, { recursive: true });
1691
- for (const entry of fs3.readdirSync(src, { withFileTypes: true })) {
1692
- const srcPath = path4.join(src, entry.name);
1693
- const destPath = path4.join(dest, entry.name);
2144
+ fs4.mkdirSync(dest, { recursive: true });
2145
+ for (const entry of fs4.readdirSync(src, { withFileTypes: true })) {
2146
+ const srcPath = path5.join(src, entry.name);
2147
+ const destPath = path5.join(dest, entry.name);
1694
2148
  if (entry.isDirectory()) {
1695
2149
  copyDirSync2(srcPath, destPath);
1696
2150
  } else {
1697
- fs3.copyFileSync(srcPath, destPath);
2151
+ fs4.copyFileSync(srcPath, destPath);
1698
2152
  }
1699
2153
  }
1700
2154
  }
@@ -1703,12 +2157,12 @@ function installSkillForAgents(agentIds) {
1703
2157
  const canonical = getCanonicalSkillPath2();
1704
2158
  const installed = [];
1705
2159
  const failed = [];
1706
- if (!fs3.existsSync(path4.join(source, "SKILL.md"))) {
2160
+ if (!fs4.existsSync(path5.join(source, "SKILL.md"))) {
1707
2161
  return { installed: [], failed: ["skill source not found"] };
1708
2162
  }
1709
2163
  try {
1710
- if (fs3.existsSync(canonical)) {
1711
- fs3.rmSync(canonical, { recursive: true });
2164
+ if (fs4.existsSync(canonical)) {
2165
+ fs4.rmSync(canonical, { recursive: true });
1712
2166
  }
1713
2167
  copyDirSync2(source, canonical);
1714
2168
  writeInstalledSkillVersion(getCurrentVersion());
@@ -1725,15 +2179,15 @@ function installSkillForAgents(agentIds) {
1725
2179
  continue;
1726
2180
  }
1727
2181
  try {
1728
- const agentSkillsDir = path4.dirname(agentPath);
1729
- fs3.mkdirSync(agentSkillsDir, { recursive: true });
2182
+ const agentSkillsDir = path5.dirname(agentPath);
2183
+ fs4.mkdirSync(agentSkillsDir, { recursive: true });
1730
2184
  try {
1731
- fs3.lstatSync(agentPath);
1732
- fs3.rmSync(agentPath, { recursive: true });
2185
+ fs4.lstatSync(agentPath);
2186
+ fs4.rmSync(agentPath, { recursive: true });
1733
2187
  } catch {
1734
2188
  }
1735
- const relative = path4.relative(agentSkillsDir, canonical);
1736
- fs3.symlinkSync(relative, agentPath);
2189
+ const relative = path5.relative(agentSkillsDir, canonical);
2190
+ fs4.symlinkSync(relative, agentPath);
1737
2191
  installed.push(agent.name);
1738
2192
  seen.set(agentPath, true);
1739
2193
  } catch {
@@ -1748,7 +2202,7 @@ async function promptOpenAiKey(scope) {
1748
2202
  const entered = await p3.password({
1749
2203
  message: scopedMessage(
1750
2204
  scope,
1751
- `OpenAI API key ${pc3.dim("(optional \u2014 enables semantic search in `one mem`)")}`
2205
+ `OpenAI API key ${pc4.dim("(optional \u2014 enables semantic search in `one mem`)")}`
1752
2206
  ),
1753
2207
  mask: "\u2022",
1754
2208
  // Validator accepts empty → treated as "skip".
@@ -1803,7 +2257,7 @@ async function promptSkillInstall() {
1803
2257
  ...primaryAgents.map((a) => ({
1804
2258
  value: a.id,
1805
2259
  label: a.name,
1806
- hint: isSkillInstalledForAgent(a) ? pc3.green("installed") : void 0
2260
+ hint: isSkillInstalledForAgent(a) ? pc4.green("installed") : void 0
1807
2261
  })),
1808
2262
  {
1809
2263
  value: "_other",
@@ -1827,7 +2281,7 @@ async function promptSkillInstall() {
1827
2281
  options: otherAgents.map((a) => ({
1828
2282
  value: a.id,
1829
2283
  label: a.name,
1830
- hint: isSkillInstalledForAgent(a) ? pc3.green("installed") : void 0
2284
+ hint: isSkillInstalledForAgent(a) ? pc4.green("installed") : void 0
1831
2285
  }))
1832
2286
  });
1833
2287
  if (!p3.isCancel(otherChoice)) {
@@ -1838,12 +2292,12 @@ async function promptSkillInstall() {
1838
2292
  p3.log.info("No agents selected.");
1839
2293
  return false;
1840
2294
  }
1841
- const spinner5 = p3.spinner();
1842
- spinner5.start("Installing skill...");
2295
+ const spinner4 = p3.spinner();
2296
+ spinner4.start("Installing skill...");
1843
2297
  const { installed, failed } = installSkillForAgents(selectedIds);
1844
- spinner5.stop(installed.length > 0 ? "Skill installed" : "Installation failed");
2298
+ spinner4.stop(installed.length > 0 ? "Skill installed" : "Installation failed");
1845
2299
  for (const name of installed) {
1846
- p3.log.success(`${name}: ${pc3.green("\u2713")} skill installed`);
2300
+ p3.log.success(`${name}: ${pc4.green("\u2713")} skill installed`);
1847
2301
  }
1848
2302
  for (const name of failed) {
1849
2303
  p3.log.warn(`${name}: failed to install`);
@@ -1852,19 +2306,19 @@ async function promptSkillInstall() {
1852
2306
  }
1853
2307
  function printOnboardingPrompt() {
1854
2308
  console.log();
1855
- console.log(pc3.bold(" Copy-paste this to your AI agent:"));
2309
+ console.log(pc4.bold(" Copy-paste this to your AI agent:"));
1856
2310
  console.log();
1857
- console.log(pc3.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1858
- console.log(pc3.cyan(" \u2502"));
1859
- console.log(pc3.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
1860
- console.log(pc3.cyan(" \u2502 lets you interact with 600+ third-party platforms (Gmail,"));
1861
- console.log(pc3.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
1862
- console.log(pc3.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
1863
- console.log(pc3.cyan(" \u2502 third-party platform or external service, use the `one`"));
1864
- console.log(pc3.cyan(" \u2502 skill. Please save this to your project instructions or"));
1865
- console.log(pc3.cyan(" \u2502 memory so you remember it in future conversations."));
1866
- console.log(pc3.cyan(" \u2502"));
1867
- console.log(pc3.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2311
+ console.log(pc4.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2312
+ console.log(pc4.cyan(" \u2502"));
2313
+ console.log(pc4.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
2314
+ console.log(pc4.cyan(" \u2502 lets you interact with 600+ third-party platforms (Gmail,"));
2315
+ console.log(pc4.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
2316
+ console.log(pc4.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
2317
+ console.log(pc4.cyan(" \u2502 third-party platform or external service, use the `one`"));
2318
+ console.log(pc4.cyan(" \u2502 skill. Please save this to your project instructions or"));
2319
+ console.log(pc4.cyan(" \u2502 memory so you remember it in future conversations."));
2320
+ console.log(pc4.cyan(" \u2502"));
2321
+ console.log(pc4.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1868
2322
  console.log();
1869
2323
  }
1870
2324
  async function freshSetup(scope, options) {
@@ -1881,7 +2335,7 @@ async function freshSetup(scope, options) {
1881
2335
  }
1882
2336
  let apiKey;
1883
2337
  if (authMethod === "browser") {
1884
- const result = await browserLogin();
2338
+ const result = await browserLogin({ scope });
1885
2339
  if (!result) {
1886
2340
  p3.cancel("Browser login did not complete. Try: one init");
1887
2341
  process.exit(1);
@@ -1892,24 +2346,19 @@ async function freshSetup(scope, options) {
1892
2346
  if (result.whoami.organization) contextParts.push(result.whoami.organization.name);
1893
2347
  if (result.whoami.project) contextParts.push(result.whoami.project.name);
1894
2348
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
1895
- const envLabel = env2 === "test" ? pc3.yellow("test") : pc3.green("live");
2349
+ const envLabel = env2 === "test" ? pc4.yellow("test") : pc4.green("live");
1896
2350
  p3.note(
1897
- `${scopeDisplay} ${pc3.dim("\xB7")} ${envLabel}
1898
- ${result.whoami.user.name} ${pc3.dim(`(${result.whoami.user.email})`)}`,
2351
+ [
2352
+ `${scopeDisplay} ${pc4.dim("\xB7")} ${envLabel}`,
2353
+ `${result.whoami.user.name} ${pc4.dim(`(${result.whoami.user.email})`)}`,
2354
+ ...result.keyName ? [`${pc4.dim("Key:")} ${result.keyName}`] : []
2355
+ ].join("\n"),
1899
2356
  "Account"
1900
2357
  );
1901
- writeConfig(
1902
- {
1903
- apiKey,
1904
- installedAgents: [],
1905
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1906
- whoami: result.whoami
1907
- },
1908
- scope
1909
- );
2358
+ saveCredentials(apiKey, scope, { keyName: result.keyName, whoami: result.whoami });
1910
2359
  } else {
1911
2360
  p3.note(`Get your API key at:
1912
- ${pc3.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
2361
+ ${pc4.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
1913
2362
  const openBrowser = await p3.confirm({
1914
2363
  message: scopedMessage(scope, "Open browser to get API key?"),
1915
2364
  initialValue: true
@@ -1937,36 +2386,28 @@ ${pc3.cyan(getApiKeyUrl())}`, `API Key ${scopeLabel(scope)}`);
1937
2386
  process.exit(0);
1938
2387
  }
1939
2388
  apiKey = inputKey;
1940
- const spinner5 = p3.spinner();
1941
- spinner5.start("Validating API key...");
2389
+ const spinner4 = p3.spinner();
2390
+ spinner4.start("Validating API key...");
1942
2391
  const api = new OneApi(apiKey, getApiBase());
1943
2392
  const whoami = await api.validateApiKey();
1944
2393
  if (!whoami) {
1945
- spinner5.stop("Invalid API key");
2394
+ spinner4.stop("Invalid API key");
1946
2395
  p3.cancel(`Invalid API key. Get a valid key at ${getApiKeyUrl()}`);
1947
2396
  process.exit(1);
1948
2397
  }
1949
- spinner5.stop("API key validated");
2398
+ spinner4.stop("API key validated");
1950
2399
  const env2 = getEnvFromApiKey(apiKey);
1951
2400
  const contextParts = [];
1952
2401
  if (whoami.organization) contextParts.push(whoami.organization.name);
1953
2402
  if (whoami.project) contextParts.push(whoami.project.name);
1954
2403
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
1955
- const envLabel = env2 === "test" ? pc3.yellow("test") : pc3.green("live");
2404
+ const envLabel = env2 === "test" ? pc4.yellow("test") : pc4.green("live");
1956
2405
  p3.note(
1957
- `${scopeDisplay} ${pc3.dim("\xB7")} ${envLabel}
1958
- ${whoami.user.name} ${pc3.dim(`(${whoami.user.email})`)}`,
2406
+ `${scopeDisplay} ${pc4.dim("\xB7")} ${envLabel}
2407
+ ${whoami.user.name} ${pc4.dim(`(${whoami.user.email})`)}`,
1959
2408
  "Account"
1960
2409
  );
1961
- writeConfig(
1962
- {
1963
- apiKey,
1964
- installedAgents: [],
1965
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1966
- whoami
1967
- },
1968
- scope
1969
- );
2410
+ saveCredentials(apiKey, scope, { whoami });
1970
2411
  }
1971
2412
  await promptOpenAiKey(scope);
1972
2413
  await promptSkillInstall();
@@ -1979,11 +2420,11 @@ ${whoami.user.name} ${pc3.dim(`(${whoami.user.email})`)}`,
1979
2420
  };
1980
2421
  await promptConnectIntegrations(apiKey, connParams);
1981
2422
  const savedPath = scope === "project" ? getProjectConfigPath() : getGlobalConfigPath();
1982
- const resolutionHint = scope === "project" ? `When you run ${pc3.cyan("one")} from ${pc3.bold(path4.basename(getProjectRoot()))}, it uses this project config.
2423
+ const resolutionHint = scope === "project" ? `When you run ${pc4.cyan("one")} from ${pc4.bold(path5.basename(getProjectRoot()))}, it uses this project config.
1983
2424
  From anywhere else, it falls back to your global config.` : `This config applies to every folder unless a project config is set.`;
1984
2425
  p3.note(
1985
2426
  `${scopeLabel(scope)} Config saved to:
1986
- ${pc3.dim(tildify(savedPath))}
2427
+ ${pc4.dim(tildify(savedPath))}
1987
2428
 
1988
2429
  ${resolutionHint}`,
1989
2430
  "Setup Complete"
@@ -1993,18 +2434,18 @@ ${resolutionHint}`,
1993
2434
  }
1994
2435
  function printBanner() {
1995
2436
  console.log();
1996
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
1997
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
1998
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
1999
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2000
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "));
2001
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "));
2002
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2003
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2004
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2005
- console.log(pc3.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2437
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2438
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2439
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2440
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2441
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "));
2442
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 "));
2443
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2444
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 "));
2445
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2446
+ console.log(pc4.yellow(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
2006
2447
  console.log();
2007
- console.log(pc3.dim(" I N F R A S T R U C T U R E F O R A G E N T S"));
2448
+ console.log(pc4.dim(" I N F R A S T R U C T U R E F O R A G E N T S"));
2008
2449
  console.log();
2009
2450
  }
2010
2451
  var TOP_INTEGRATIONS = [
@@ -2043,19 +2484,20 @@ async function promptConnectIntegrations(apiKey, connParams) {
2043
2484
  break;
2044
2485
  }
2045
2486
  if (choice === "more") {
2487
+ const connectionsUrl = `${oneAppUrl()}/connections`;
2046
2488
  try {
2047
- await open2("https://app.withone.ai/connections");
2489
+ await open3(connectionsUrl);
2048
2490
  p3.log.info("Opened One dashboard in browser.");
2049
2491
  } catch {
2050
- p3.note("https://app.withone.ai/connections", "Open in browser");
2492
+ p3.note(connectionsUrl, "Open in browser");
2051
2493
  }
2052
- p3.log.info(`Connect from the dashboard, or use ${pc3.cyan("one add <platform>")}`);
2494
+ p3.log.info(`Connect from the dashboard, or use ${pc4.cyan("one add <platform>")}`);
2053
2495
  break;
2054
2496
  }
2055
2497
  const platform = choice;
2056
2498
  const integration = TOP_INTEGRATIONS.find((i) => i.value === platform);
2057
2499
  const label = integration?.label ?? platform;
2058
- p3.log.info(`Opening browser to connect ${pc3.cyan(label)}...`);
2500
+ p3.log.info(`Opening browser to connect ${pc4.cyan(label)}...`);
2059
2501
  try {
2060
2502
  await openConnectionPage(platform, connParams);
2061
2503
  } catch {
@@ -2063,18 +2505,18 @@ async function promptConnectIntegrations(apiKey, connParams) {
2063
2505
  p3.log.warn("Could not open browser automatically.");
2064
2506
  p3.note(url, "Open manually");
2065
2507
  }
2066
- const spinner5 = p3.spinner();
2067
- spinner5.start("Waiting for connection... (complete auth in browser)");
2508
+ const spinner4 = p3.spinner();
2509
+ spinner4.start("Waiting for connection... (complete auth in browser)");
2068
2510
  try {
2069
2511
  await api.waitForConnection(platform, 5 * 60 * 1e3, 5e3);
2070
- spinner5.stop(`${label} connected!`);
2071
- p3.log.success(`${pc3.green("\u2713")} ${label} is now available to your AI agents`);
2512
+ spinner4.stop(`${label} connected!`);
2513
+ p3.log.success(`${pc4.green("\u2713")} ${label} is now available to your AI agents`);
2072
2514
  connected.push(platform);
2073
2515
  first = false;
2074
2516
  } catch (error2) {
2075
- spinner5.stop("Connection timed out");
2517
+ spinner4.stop("Connection timed out");
2076
2518
  if (error2 instanceof TimeoutError) {
2077
- p3.log.warn(`No worries. Connect later with: ${pc3.cyan(`one add ${platform}`)}`);
2519
+ p3.log.warn(`No worries. Connect later with: ${pc4.cyan(`one add ${platform}`)}`);
2078
2520
  }
2079
2521
  first = false;
2080
2522
  }
@@ -2091,7 +2533,7 @@ function maskApiKey(key) {
2091
2533
 
2092
2534
  // src/commands/connection.ts
2093
2535
  import * as p4 from "@clack/prompts";
2094
- import pc5 from "picocolors";
2536
+ import pc6 from "picocolors";
2095
2537
 
2096
2538
  // src/lib/access.ts
2097
2539
  async function resolveAllowedActions(api, actionIds) {
@@ -2177,7 +2619,7 @@ function countMatchingChars(a, b) {
2177
2619
  }
2178
2620
 
2179
2621
  // src/lib/table.ts
2180
- import pc4 from "picocolors";
2622
+ import pc5 from "picocolors";
2181
2623
  function printTable(columns, rows) {
2182
2624
  if (rows.length === 0) return;
2183
2625
  const gap = " ";
@@ -2189,10 +2631,10 @@ function printTable(columns, rows) {
2189
2631
  });
2190
2632
  const header = columns.map((col, i) => {
2191
2633
  const padded = col.align === "right" ? col.label.padStart(widths[i]) : col.label.padEnd(widths[i]);
2192
- return pc4.dim(padded);
2634
+ return pc5.dim(padded);
2193
2635
  }).join(gap);
2194
2636
  console.log(`${indent}${header}`);
2195
- const separator = columns.map((_, i) => pc4.dim("\u2500".repeat(widths[i]))).join(gap);
2637
+ const separator = columns.map((_, i) => pc5.dim("\u2500".repeat(widths[i]))).join(gap);
2196
2638
  console.log(`${indent}${separator}`);
2197
2639
  for (const row of rows) {
2198
2640
  const line = columns.map((col, i) => {
@@ -2217,21 +2659,21 @@ async function connectionAddCommand(platformArg, options) {
2217
2659
  if (isAgentMode()) {
2218
2660
  error("This command requires interactive input. Run without --agent.");
2219
2661
  }
2220
- p4.intro(pc5.bgCyan(pc5.black(" One ")));
2662
+ p4.intro(pc6.bgCyan(pc6.black(" One ")));
2221
2663
  const apiKey = getApiKey();
2222
2664
  if (!apiKey) {
2223
2665
  p4.cancel("Not configured. Run `one init` first.");
2224
2666
  process.exit(1);
2225
2667
  }
2226
2668
  const api = new OneApi(apiKey, getApiBase());
2227
- const spinner5 = p4.spinner();
2228
- spinner5.start("Loading platforms...");
2669
+ const spinner4 = p4.spinner();
2670
+ spinner4.start("Loading platforms...");
2229
2671
  let platforms;
2230
2672
  try {
2231
2673
  platforms = await api.listPlatforms();
2232
- spinner5.stop(`${platforms.length} platforms available`);
2674
+ spinner4.stop(`${platforms.length} platforms available`);
2233
2675
  } catch (error2) {
2234
- spinner5.stop("Failed to load platforms");
2676
+ spinner4.stop("Failed to load platforms");
2235
2677
  p4.cancel(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2236
2678
  process.exit(1);
2237
2679
  }
@@ -2252,7 +2694,7 @@ async function connectionAddCommand(platformArg, options) {
2252
2694
  ]
2253
2695
  });
2254
2696
  if (p4.isCancel(suggestion) || suggestion === "__other__") {
2255
- p4.note(`Run ${pc5.cyan("one platforms")} to see all available platforms.`);
2697
+ p4.note(`Run ${pc6.cyan("one platforms")} to see all available platforms.`);
2256
2698
  p4.cancel("Connection cancelled.");
2257
2699
  process.exit(0);
2258
2700
  }
@@ -2260,7 +2702,7 @@ async function connectionAddCommand(platformArg, options) {
2260
2702
  } else {
2261
2703
  p4.cancel(`Unknown platform: ${platformArg}
2262
2704
 
2263
- Run ${pc5.cyan("one platforms")} to see available platforms.`);
2705
+ Run ${pc6.cyan("one platforms")} to see available platforms.`);
2264
2706
  process.exit(1);
2265
2707
  }
2266
2708
  }
@@ -2283,7 +2725,7 @@ Run ${pc5.cyan("one platforms")} to see available platforms.`);
2283
2725
  } else {
2284
2726
  p4.cancel(`Unknown platform: ${platformInput}
2285
2727
 
2286
- Run ${pc5.cyan("one platforms")} to see available platforms.`);
2728
+ Run ${pc6.cyan("one platforms")} to see available platforms.`);
2287
2729
  process.exit(1);
2288
2730
  }
2289
2731
  }
@@ -2294,8 +2736,8 @@ Run ${pc5.cyan("one platforms")} to see available platforms.`);
2294
2736
  ...whoami?.project && { projectId: whoami.project.id }
2295
2737
  };
2296
2738
  const url = getConnectionUrl(platform, connParams);
2297
- p4.log.info(`Opening browser to connect ${pc5.cyan(platform)}...`);
2298
- p4.note(pc5.dim(url), "URL");
2739
+ p4.log.info(`Opening browser to connect ${pc6.cyan(platform)}...`);
2740
+ p4.note(pc6.dim(url), "URL");
2299
2741
  try {
2300
2742
  await openConnectionPage(platform, connParams);
2301
2743
  } catch {
@@ -2323,7 +2765,7 @@ The connection is usable; set the tag later in the dashboard or retry.`
2323
2765
  );
2324
2766
  }
2325
2767
  }
2326
- p4.log.success(`${pc5.green("\u2713")} ${connection2.platform} is now available to your AI agents.${tag ? ` (tag: ${tag})` : ""}`);
2768
+ p4.log.success(`${pc6.green("\u2713")} ${connection2.platform} is now available to your AI agents.${tag ? ` (tag: ${tag})` : ""}`);
2327
2769
  p4.outro("Connection complete!");
2328
2770
  } catch (error2) {
2329
2771
  pollSpinner.stop("Connection timed out");
@@ -2334,7 +2776,7 @@ The connection is usable; set the tag later in the dashboard or retry.`
2334
2776
  - Browser popup was blocked
2335
2777
  - Wrong account selected
2336
2778
 
2337
- Try again with: ${pc5.cyan(`one connection add ${platform}`)}`,
2779
+ Try again with: ${pc6.cyan(`one connection add ${platform}`)}`,
2338
2780
  "Timed Out"
2339
2781
  );
2340
2782
  } else {
@@ -2349,8 +2791,8 @@ async function connectionListCommand(options) {
2349
2791
  error("Not configured. Run `one init` first.");
2350
2792
  }
2351
2793
  const api = new OneApi(apiKey, getApiBase());
2352
- const spinner5 = createSpinner();
2353
- spinner5.start("Loading connections...");
2794
+ const spinner4 = createSpinner();
2795
+ spinner4.start("Loading connections...");
2354
2796
  try {
2355
2797
  const allConnections = await api.listConnections();
2356
2798
  const ac = getAccessControlFromAllSources();
@@ -2392,20 +2834,20 @@ async function connectionListCommand(options) {
2392
2834
  return;
2393
2835
  }
2394
2836
  const displayed = limitArg !== void 0 ? filtered.slice(0, limitArg) : filtered;
2395
- spinner5.stop(`${filtered.length} connection${filtered.length === 1 ? "" : "s"} found`);
2837
+ spinner4.stop(`${filtered.length} connection${filtered.length === 1 ? "" : "s"} found`);
2396
2838
  if (filtered.length === 0) {
2397
2839
  if (searchQuery) {
2398
2840
  p4.note(
2399
2841
  `No connections matching "${searchQuery}".
2400
2842
 
2401
- Try: ${pc5.cyan("one connection list")} to see all connections.`,
2843
+ Try: ${pc6.cyan("one connection list")} to see all connections.`,
2402
2844
  "No Results"
2403
2845
  );
2404
2846
  } else {
2405
2847
  p4.note(
2406
2848
  `No connections yet.
2407
2849
 
2408
- Add one with: ${pc5.cyan("one connection add gmail")}`,
2850
+ Add one with: ${pc6.cyan("one connection add gmail")}`,
2409
2851
  "No Connections"
2410
2852
  );
2411
2853
  }
@@ -2427,9 +2869,9 @@ Add one with: ${pc5.cyan("one connection add gmail")}`,
2427
2869
  { key: "status", label: "" },
2428
2870
  { key: "platform", label: "Platform" },
2429
2871
  { key: "state", label: "Status" },
2430
- { key: "key", label: "Connection Key", color: pc5.dim },
2431
- ...hasTags ? [{ key: "tags", label: "Tags", color: pc5.dim }] : [],
2432
- ...hasScopedAccess ? [{ key: "access", label: "Access", color: pc5.yellow }] : []
2872
+ { key: "key", label: "Connection Key", color: pc6.dim },
2873
+ ...hasTags ? [{ key: "tags", label: "Tags", color: pc6.dim }] : [],
2874
+ ...hasScopedAccess ? [{ key: "access", label: "Access", color: pc6.yellow }] : []
2433
2875
  ],
2434
2876
  rows
2435
2877
  );
@@ -2443,7 +2885,7 @@ Add one with: ${pc5.cyan("one connection add gmail")}`,
2443
2885
  }
2444
2886
  p4.note(`${wrapText(lines.join("\n"))}
2445
2887
 
2446
- Change it with: ${pc5.cyan("one config")}`, "Access");
2888
+ Change it with: ${pc6.cyan("one config")}`, "Access");
2447
2889
  }
2448
2890
  if (displayed.length < filtered.length) {
2449
2891
  p4.note(
@@ -2451,10 +2893,10 @@ Change it with: ${pc5.cyan("one config")}`, "Access");
2451
2893
  "Limited"
2452
2894
  );
2453
2895
  } else {
2454
- p4.note(`Add more with: ${pc5.cyan("one connection add <platform>")}`, "Tip");
2896
+ p4.note(`Add more with: ${pc6.cyan("one connection add <platform>")}`, "Tip");
2455
2897
  }
2456
2898
  } catch (error2) {
2457
- spinner5.stop("Failed to load connections");
2899
+ spinner4.stop("Failed to load connections");
2458
2900
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2459
2901
  }
2460
2902
  }
@@ -2464,13 +2906,13 @@ async function connectionDeleteCommand(connectionKey, options) {
2464
2906
  error("Not configured. Run `one init` first.");
2465
2907
  }
2466
2908
  const api = new OneApi(apiKey, getApiBase());
2467
- const spinner5 = createSpinner();
2468
- spinner5.start("Finding connection...");
2909
+ const spinner4 = createSpinner();
2910
+ spinner4.start("Finding connection...");
2469
2911
  let allConnections;
2470
2912
  try {
2471
2913
  allConnections = await api.listConnections();
2472
2914
  } catch (error2) {
2473
- spinner5.stop("Failed to load connections");
2915
+ spinner4.stop("Failed to load connections");
2474
2916
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2475
2917
  return;
2476
2918
  }
@@ -2479,15 +2921,15 @@ async function connectionDeleteCommand(connectionKey, options) {
2479
2921
  const connections = allowedKeys.includes("*") ? allConnections : allConnections.filter((conn) => allowedKeys.includes(conn.key));
2480
2922
  const match = connections.find((conn) => conn.key === connectionKey);
2481
2923
  if (!match) {
2482
- spinner5.stop("Connection not found");
2924
+ spinner4.stop("Connection not found");
2483
2925
  error(`No connection found with key: ${connectionKey}`);
2484
2926
  return;
2485
2927
  }
2486
2928
  const connection2 = match;
2487
- spinner5.stop(`Found ${connection2.platform} (${connection2.state})`);
2929
+ spinner4.stop(`Found ${connection2.platform} (${connection2.state})`);
2488
2930
  if (!isAgentMode() && !options?.force) {
2489
2931
  console.log();
2490
- console.log(` ${getStatusIndicator(connection2.state)} ${connection2.platform} ${pc5.dim(connection2.key)}`);
2932
+ console.log(` ${getStatusIndicator(connection2.state)} ${connection2.platform} ${pc6.dim(connection2.key)}`);
2491
2933
  console.log();
2492
2934
  const confirmed = await p4.confirm({
2493
2935
  message: "Are you sure you want to delete this connection?",
@@ -2511,7 +2953,7 @@ async function connectionDeleteCommand(connectionKey, options) {
2511
2953
  });
2512
2954
  return;
2513
2955
  }
2514
- p4.log.success(`${pc5.green("\u2713")} ${connection2.platform} connection removed.`);
2956
+ p4.log.success(`${pc6.green("\u2713")} ${connection2.platform} connection removed.`);
2515
2957
  } catch (error2) {
2516
2958
  deleteSpinner.stop("Failed to delete connection");
2517
2959
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
@@ -2551,19 +2993,19 @@ function wrapText(text5, width = 72) {
2551
2993
  function getStatusIndicator(state) {
2552
2994
  switch (state) {
2553
2995
  case "operational":
2554
- return pc5.green("\u25CF");
2996
+ return pc6.green("\u25CF");
2555
2997
  case "degraded":
2556
- return pc5.yellow("\u25CF");
2998
+ return pc6.yellow("\u25CF");
2557
2999
  case "failed":
2558
- return pc5.red("\u25CF");
3000
+ return pc6.red("\u25CF");
2559
3001
  default:
2560
- return pc5.dim("\u25CB");
3002
+ return pc6.dim("\u25CB");
2561
3003
  }
2562
3004
  }
2563
3005
 
2564
3006
  // src/commands/platforms.ts
2565
3007
  import * as p5 from "@clack/prompts";
2566
- import pc6 from "picocolors";
3008
+ import pc7 from "picocolors";
2567
3009
  async function platformsCommand(options) {
2568
3010
  const apiKey = getApiKey();
2569
3011
  if (!apiKey) {
@@ -2573,11 +3015,11 @@ async function platformsCommand(options) {
2573
3015
  options.json = true;
2574
3016
  }
2575
3017
  const api = new OneApi(apiKey, getApiBase());
2576
- const spinner5 = createSpinner();
2577
- spinner5.start("Loading platforms...");
3018
+ const spinner4 = createSpinner();
3019
+ spinner4.start("Loading platforms...");
2578
3020
  try {
2579
3021
  const platforms = await api.listPlatforms();
2580
- spinner5.stop(`${platforms.length} platforms available`);
3022
+ spinner4.stop(`${platforms.length} platforms available`);
2581
3023
  let filtered = platforms;
2582
3024
  if (options.category) {
2583
3025
  filtered = platforms.filter((plat) => (plat.category || "Other") === options.category);
@@ -2629,16 +3071,16 @@ async function platformsCommand(options) {
2629
3071
  );
2630
3072
  }
2631
3073
  console.log();
2632
- p5.note(`Connect with: ${pc6.cyan("one connection add <platform>")}`, "Tip");
3074
+ p5.note(`Connect with: ${pc7.cyan("one connection add <platform>")}`, "Tip");
2633
3075
  } catch (error2) {
2634
- spinner5.stop("Failed to load platforms");
3076
+ spinner4.stop("Failed to load platforms");
2635
3077
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2636
3078
  }
2637
3079
  }
2638
3080
 
2639
3081
  // src/commands/actions.ts
2640
3082
  import * as p6 from "@clack/prompts";
2641
- import pc7 from "picocolors";
3083
+ import pc8 from "picocolors";
2642
3084
  function getConfig() {
2643
3085
  const apiKey = getApiKey();
2644
3086
  if (!apiKey) {
@@ -2659,11 +3101,11 @@ function parseJsonArg2(value, argName) {
2659
3101
  }
2660
3102
  }
2661
3103
  async function actionsSearchCommand(platform, query, options) {
2662
- intro(pc7.bgCyan(pc7.black(" One ")));
3104
+ intro(pc8.bgCyan(pc8.black(" One ")));
2663
3105
  const { apiKey, permissions, actionIds, knowledgeAgent } = getConfig();
2664
3106
  const api = new OneApi(apiKey, getApiBase());
2665
- const spinner5 = createSpinner();
2666
- spinner5.start(`Searching actions on ${pc7.cyan(platform)} for "${query}"...`);
3107
+ const spinner4 = createSpinner();
3108
+ spinner4.start(`Searching actions on ${pc8.cyan(platform)} for "${query}"...`);
2667
3109
  try {
2668
3110
  const agentType = knowledgeAgent ? "knowledge" : options.type || "execute";
2669
3111
  const useCache = options.cache !== false;
@@ -2729,14 +3171,14 @@ async function actionsSearchCommand(platform, query, options) {
2729
3171
  return;
2730
3172
  }
2731
3173
  if (cleanedActions.length === 0) {
2732
- spinner5.stop("No actions found");
3174
+ spinner4.stop("No actions found");
2733
3175
  p6.note(
2734
3176
  `No actions found for platform '${platform}' matching query '${query}'.
2735
3177
 
2736
3178
  Suggestions:
2737
3179
  - Try a more general query (e.g., 'list', 'get', 'search', 'create')
2738
3180
  - Verify the platform name is correct
2739
- - Check available platforms with ${pc7.cyan("one platforms")}
3181
+ - Check available platforms with ${pc8.cyan("one platforms")}
2740
3182
 
2741
3183
  Examples of good queries:
2742
3184
  - "search contacts"
@@ -2747,7 +3189,7 @@ Examples of good queries:
2747
3189
  );
2748
3190
  return;
2749
3191
  }
2750
- spinner5.stop(
3192
+ spinner4.stop(
2751
3193
  `Found ${cleanedActions.length} action(s) for '${platform}' matching '${query}'`
2752
3194
  );
2753
3195
  console.log();
@@ -2761,19 +3203,19 @@ Examples of good queries:
2761
3203
  [
2762
3204
  { key: "method", label: "Method" },
2763
3205
  { key: "title", label: "Title" },
2764
- { key: "actionId", label: "Action ID", color: pc7.dim },
2765
- { key: "path", label: "Path", color: pc7.dim }
3206
+ { key: "actionId", label: "Action ID", color: pc8.dim },
3207
+ { key: "path", label: "Path", color: pc8.dim }
2766
3208
  ],
2767
3209
  rows
2768
3210
  );
2769
3211
  console.log();
2770
3212
  p6.note(
2771
- `Get details: ${pc7.cyan(`one actions knowledge ${platform} <actionId>`)}
2772
- Execute: ${pc7.cyan(`one actions execute ${platform} <actionId> <connectionKey>`)}`,
3213
+ `Get details: ${pc8.cyan(`one actions knowledge ${platform} <actionId>`)}
3214
+ Execute: ${pc8.cyan(`one actions execute ${platform} <actionId> <connectionKey>`)}`,
2773
3215
  "Next Steps"
2774
3216
  );
2775
3217
  } catch (error2) {
2776
- spinner5.stop("Search failed");
3218
+ spinner4.stop("Search failed");
2777
3219
  error(
2778
3220
  `Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`
2779
3221
  );
@@ -2802,32 +3244,32 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
2802
3244
  }
2803
3245
  return;
2804
3246
  }
2805
- intro(pc7.bgCyan(pc7.black(" One ")));
3247
+ intro(pc8.bgCyan(pc8.black(" One ")));
2806
3248
  const { apiKey, actionIds, connectionKeys } = getConfig();
2807
3249
  const api = new OneApi(apiKey, getApiBase());
2808
3250
  if (!isActionAllowed(actionId, actionIds)) {
2809
3251
  error(`Action "${actionId}" is not in the allowed action list.`);
2810
3252
  }
2811
3253
  if (!connectionKeys.includes("*")) {
2812
- const spinner6 = createSpinner();
2813
- spinner6.start("Checking connections...");
3254
+ const spinner5 = createSpinner();
3255
+ spinner5.start("Checking connections...");
2814
3256
  try {
2815
3257
  const connections = await api.listConnections();
2816
3258
  const connectedPlatforms = connections.map((c) => c.platform);
2817
3259
  if (!connectedPlatforms.includes(platform)) {
2818
- spinner6.stop("Platform not connected");
3260
+ spinner5.stop("Platform not connected");
2819
3261
  error(`Platform "${platform}" has no allowed connections.`);
2820
3262
  }
2821
- spinner6.stop("Connection verified");
3263
+ spinner5.stop("Connection verified");
2822
3264
  } catch (error2) {
2823
- spinner6.stop("Failed to check connections");
3265
+ spinner5.stop("Failed to check connections");
2824
3266
  error(
2825
3267
  `Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`
2826
3268
  );
2827
3269
  }
2828
3270
  }
2829
- const spinner5 = createSpinner();
2830
- spinner5.start(`Loading knowledge for action ${pc7.dim(actionId)}...`);
3271
+ const spinner4 = createSpinner();
3272
+ spinner4.start(`Loading knowledge for action ${pc8.dim(actionId)}...`);
2831
3273
  try {
2832
3274
  const { details, cacheHit, entry } = await resolveActionDetails(api, actionId, {
2833
3275
  useCache: options.cache !== false
@@ -2851,23 +3293,23 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
2851
3293
  json(response);
2852
3294
  return;
2853
3295
  }
2854
- spinner5.stop("Knowledge loaded");
3296
+ spinner4.stop("Knowledge loaded");
2855
3297
  console.log();
2856
3298
  console.log(knowledgeWithGuidance);
2857
3299
  console.log();
2858
3300
  p6.note(
2859
- `Execute: ${pc7.cyan(`one actions execute ${platform} ${actionId} <connectionKey>`)}`,
3301
+ `Execute: ${pc8.cyan(`one actions execute ${platform} ${actionId} <connectionKey>`)}`,
2860
3302
  "Next Step"
2861
3303
  );
2862
3304
  } catch (error2) {
2863
- spinner5.stop("Failed to load knowledge");
3305
+ spinner4.stop("Failed to load knowledge");
2864
3306
  error(
2865
3307
  `Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`
2866
3308
  );
2867
3309
  }
2868
3310
  }
2869
3311
  async function actionsExecuteCommand(platform, actionId, connectionKey, options) {
2870
- intro(pc7.bgCyan(pc7.black(" One ")));
3312
+ intro(pc8.bgCyan(pc8.black(" One ")));
2871
3313
  const { apiKey, permissions, actionIds, connectionKeys, knowledgeAgent } = getConfig();
2872
3314
  if (knowledgeAgent) {
2873
3315
  error(
@@ -2881,18 +3323,18 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2881
3323
  error(`Connection key "${connectionKey}" is not allowed.`);
2882
3324
  }
2883
3325
  const api = new OneApi(apiKey, getApiBase());
2884
- const spinner5 = createSpinner();
2885
- spinner5.start("Resolving action details...");
3326
+ const spinner4 = createSpinner();
3327
+ spinner4.start("Resolving action details...");
2886
3328
  try {
2887
3329
  const { details: actionDetails, cacheHit: preflightCacheHit } = await resolveActionDetails(api, actionId, { useCache: options.cache !== false });
2888
3330
  if (!isMethodAllowed(actionDetails.method, permissions)) {
2889
- spinner5.stop("Permission denied");
3331
+ spinner4.stop("Permission denied");
2890
3332
  error(
2891
3333
  `Method "${actionDetails.method}" is not allowed under "${permissions}" permission level.`
2892
3334
  );
2893
3335
  }
2894
- spinner5.stop(
2895
- `Action: ${actionDetails.title} [${actionDetails.method}]` + (preflightCacheHit ? pc7.dim(" (cached)") : "")
3336
+ spinner4.stop(
3337
+ `Action: ${actionDetails.title} [${actionDetails.method}]` + (preflightCacheHit ? pc8.dim(" (cached)") : "")
2896
3338
  );
2897
3339
  const data = options.data ? parseJsonArg2(options.data, "--data") : void 0;
2898
3340
  const pathVariables = options.pathVars ? parseJsonArg2(options.pathVars, "--path-vars") : void 0;
@@ -2901,7 +3343,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2901
3343
  if (!options.skipValidation) {
2902
3344
  const validation = validateActionInput(actionDetails, { data, pathVariables, queryParams });
2903
3345
  if (!validation.valid) {
2904
- spinner5.stop("Validation failed");
3346
+ spinner4.stop("Validation failed");
2905
3347
  if (isAgentMode()) {
2906
3348
  json({
2907
3349
  error: "Validation failed: missing required parameters",
@@ -2912,9 +3354,9 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2912
3354
  }
2913
3355
  console.log();
2914
3356
  for (const m of validation.missing) {
2915
- console.log(pc7.red(` ${m.flag} is missing "${m.param}"`));
3357
+ console.log(pc8.red(` ${m.flag} is missing "${m.param}"`));
2916
3358
  if (m.description) {
2917
- console.log(pc7.dim(` ${m.description}`));
3359
+ console.log(pc8.dim(` ${m.description}`));
2918
3360
  }
2919
3361
  }
2920
3362
  console.log();
@@ -2922,7 +3364,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2922
3364
  }
2923
3365
  }
2924
3366
  if (options.mock) {
2925
- spinner5.stop("Mock \u2014 returning example response");
3367
+ spinner4.stop("Mock \u2014 returning example response");
2926
3368
  const mockResponse = actionDetails.ioSchema?.ioExample?.output ?? null;
2927
3369
  if (isAgentMode()) {
2928
3370
  json({
@@ -2939,7 +3381,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2939
3381
  }
2940
3382
  console.log();
2941
3383
  if (mockResponse) {
2942
- console.log(pc7.bold("Mock Response:"));
3384
+ console.log(pc8.bold("Mock Response:"));
2943
3385
  console.log(JSON.stringify(mockResponse, null, 2));
2944
3386
  } else {
2945
3387
  note("No example output available for this action", "Mock");
@@ -2980,33 +3422,33 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2980
3422
  return;
2981
3423
  }
2982
3424
  console.log();
2983
- console.log(pc7.dim("Request:"));
3425
+ console.log(pc8.dim("Request:"));
2984
3426
  console.log(
2985
- pc7.dim(
3427
+ pc8.dim(
2986
3428
  ` ${result.requestConfig.method} ${result.requestConfig.url}`
2987
3429
  )
2988
3430
  );
2989
3431
  if (options.dryRun) {
2990
3432
  if (result.requestConfig.data) {
2991
3433
  console.log();
2992
- console.log(pc7.dim("Body:"));
2993
- console.log(pc7.dim(JSON.stringify(result.requestConfig.data, null, 2)));
3434
+ console.log(pc8.dim("Body:"));
3435
+ console.log(pc8.dim(JSON.stringify(result.requestConfig.data, null, 2)));
2994
3436
  }
2995
3437
  console.log();
2996
3438
  note("Dry run \u2014 request was not sent", "Dry Run");
2997
3439
  } else {
2998
3440
  console.log();
2999
- console.log(pc7.bold("Response:"));
3441
+ console.log(pc8.bold("Response:"));
3000
3442
  const rd = result.responseData;
3001
3443
  if (rd && typeof rd === "object" && typeof rd.text === "string" && "contentType" in rd) {
3002
- if (rd.contentType) console.log(pc7.dim(`(${rd.contentType})`));
3444
+ if (rd.contentType) console.log(pc8.dim(`(${rd.contentType})`));
3003
3445
  console.log(rd.text);
3004
3446
  } else {
3005
3447
  console.log(JSON.stringify(result.responseData, null, 2));
3006
3448
  }
3007
3449
  }
3008
3450
  } catch (error2) {
3009
- spinner5.stop("Execution failed");
3451
+ spinner4.stop("Execution failed");
3010
3452
  error(
3011
3453
  `Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`
3012
3454
  );
@@ -3203,7 +3645,7 @@ async function actionsExecuteParallelCommand() {
3203
3645
  }
3204
3646
  console.log();
3205
3647
  for (const e of errors) {
3206
- console.log(` ${pc7.red("\u2717")} Segment ${e.segment} (${e.label}):`);
3648
+ console.log(` ${pc8.red("\u2717")} Segment ${e.segment} (${e.label}):`);
3207
3649
  for (const msg of e.messages) {
3208
3650
  console.log(` ${msg}`);
3209
3651
  }
@@ -3298,17 +3740,17 @@ async function actionsExecuteParallelCommand() {
3298
3740
  console.log();
3299
3741
  for (const r of results) {
3300
3742
  const label = `${r.platform}/${r.actionId}`;
3301
- const time = pc7.dim(`(${(r.durationMs / 1e3).toFixed(2)}s)`);
3743
+ const time = pc8.dim(`(${(r.durationMs / 1e3).toFixed(2)}s)`);
3302
3744
  if (r.mock) {
3303
- console.log(` [${r.segment}/${total}] ${label} ${pc7.cyan("\u25C7 mock")} ${time}`);
3304
- if (r.response) console.log(` ${pc7.dim(JSON.stringify(r.response, null, 2).split("\n").join("\n "))}`);
3745
+ console.log(` [${r.segment}/${total}] ${label} ${pc8.cyan("\u25C7 mock")} ${time}`);
3746
+ if (r.response) console.log(` ${pc8.dim(JSON.stringify(r.response, null, 2).split("\n").join("\n "))}`);
3305
3747
  } else if (r.dryRun) {
3306
- console.log(` [${r.segment}/${total}] ${label} ${pc7.yellow("\u2298 dry-run")} ${time}`);
3748
+ console.log(` [${r.segment}/${total}] ${label} ${pc8.yellow("\u2298 dry-run")} ${time}`);
3307
3749
  } else if (r.status === "success") {
3308
- console.log(` [${r.segment}/${total}] ${label} ${pc7.green("\u2713")} ${time}`);
3309
- if (r.response) console.log(` ${pc7.dim(JSON.stringify(r.response, null, 2).split("\n").join("\n "))}`);
3750
+ console.log(` [${r.segment}/${total}] ${label} ${pc8.green("\u2713")} ${time}`);
3751
+ if (r.response) console.log(` ${pc8.dim(JSON.stringify(r.response, null, 2).split("\n").join("\n "))}`);
3310
3752
  } else {
3311
- console.log(` [${r.segment}/${total}] ${label} ${pc7.red("\u2717")} ${time} \u2014 ${r.error}`);
3753
+ console.log(` [${r.segment}/${total}] ${label} ${pc8.red("\u2717")} ${time} \u2014 ${r.error}`);
3312
3754
  }
3313
3755
  }
3314
3756
  console.log();
@@ -3323,26 +3765,26 @@ async function actionsExecuteParallelCommand() {
3323
3765
  function colorMethod(method) {
3324
3766
  switch (method.toUpperCase()) {
3325
3767
  case "GET":
3326
- return pc7.green(method);
3768
+ return pc8.green(method);
3327
3769
  case "POST":
3328
- return pc7.yellow(method);
3770
+ return pc8.yellow(method);
3329
3771
  case "PUT":
3330
- return pc7.blue(method);
3772
+ return pc8.blue(method);
3331
3773
  case "PATCH":
3332
- return pc7.magenta(method);
3774
+ return pc8.magenta(method);
3333
3775
  case "DELETE":
3334
- return pc7.red(method);
3776
+ return pc8.red(method);
3335
3777
  default:
3336
3778
  return method;
3337
3779
  }
3338
3780
  }
3339
3781
 
3340
3782
  // src/commands/flow.ts
3341
- import pc8 from "picocolors";
3783
+ import pc9 from "picocolors";
3342
3784
 
3343
3785
  // src/lib/flow-validator.ts
3344
- import fs4 from "fs";
3345
- import path5 from "path";
3786
+ import fs5 from "fs";
3787
+ import path6 from "path";
3346
3788
  import { spawnSync } from "child_process";
3347
3789
  function validateFlowSchema(flow2) {
3348
3790
  const errors = [];
@@ -3417,32 +3859,32 @@ function validateStepsArray(steps, pathPrefix, errors) {
3417
3859
  const validTypes = FLOW_SCHEMA.stepTypes.map((st) => st.type);
3418
3860
  for (let i = 0; i < steps.length; i++) {
3419
3861
  const step = steps[i];
3420
- const path13 = `${pathPrefix}[${i}]`;
3862
+ const path14 = `${pathPrefix}[${i}]`;
3421
3863
  if (!step || typeof step !== "object" || Array.isArray(step)) {
3422
- errors.push({ path: path13, message: "Step must be an object" });
3864
+ errors.push({ path: path14, message: "Step must be an object" });
3423
3865
  continue;
3424
3866
  }
3425
3867
  const s = step;
3426
3868
  if (!s.id || typeof s.id !== "string") {
3427
- errors.push({ path: `${path13}.id`, message: 'Step must have a string "id"' });
3869
+ errors.push({ path: `${path14}.id`, message: 'Step must have a string "id"' });
3428
3870
  }
3429
3871
  if (!s.name || typeof s.name !== "string") {
3430
- errors.push({ path: `${path13}.name`, message: 'Step must have a string "name"' });
3872
+ errors.push({ path: `${path14}.name`, message: 'Step must have a string "name"' });
3431
3873
  }
3432
3874
  if (!s.type || !validTypes.includes(s.type)) {
3433
- errors.push({ path: `${path13}.type`, message: `Step type must be one of: ${validTypes.join(", ")}` });
3875
+ errors.push({ path: `${path14}.type`, message: `Step type must be one of: ${validTypes.join(", ")}` });
3434
3876
  continue;
3435
3877
  }
3436
3878
  if (s.requires !== void 0) {
3437
3879
  if (!Array.isArray(s.requires)) {
3438
- errors.push({ path: `${path13}.requires`, message: '"requires" must be an array of selector strings (e.g. ["$.steps.foo.output.bar"])' });
3880
+ errors.push({ path: `${path14}.requires`, message: '"requires" must be an array of selector strings (e.g. ["$.steps.foo.output.bar"])' });
3439
3881
  } else {
3440
3882
  for (let r = 0; r < s.requires.length; r++) {
3441
3883
  const sel = s.requires[r];
3442
3884
  if (typeof sel !== "string") {
3443
- errors.push({ path: `${path13}.requires[${r}]`, message: '"requires" entry must be a selector string' });
3885
+ errors.push({ path: `${path14}.requires[${r}]`, message: '"requires" entry must be a selector string' });
3444
3886
  } else if (!sel.startsWith("$.")) {
3445
- errors.push({ path: `${path13}.requires[${r}]`, message: `"requires" entry "${sel}" must be a selector starting with "$." (e.g. "$.steps.foo.output.bar")` });
3887
+ errors.push({ path: `${path14}.requires[${r}]`, message: `"requires" entry "${sel}" must be a selector starting with "$." (e.g. "$.steps.foo.output.bar")` });
3446
3888
  }
3447
3889
  }
3448
3890
  }
@@ -3450,7 +3892,7 @@ function validateStepsArray(steps, pathPrefix, errors) {
3450
3892
  if (s.onError && typeof s.onError === "object") {
3451
3893
  const oe = s.onError;
3452
3894
  if (!FLOW_SCHEMA.errorStrategies.includes(oe.strategy)) {
3453
- errors.push({ path: `${path13}.onError.strategy`, message: `Error strategy must be one of: ${FLOW_SCHEMA.errorStrategies.join(", ")}` });
3895
+ errors.push({ path: `${path14}.onError.strategy`, message: `Error strategy must be one of: ${FLOW_SCHEMA.errorStrategies.join(", ")}` });
3454
3896
  }
3455
3897
  }
3456
3898
  const descriptor = getStepTypeDescriptor(s.type);
@@ -3460,14 +3902,14 @@ function validateStepsArray(steps, pathPrefix, errors) {
3460
3902
  if (!configObj || typeof configObj !== "object") {
3461
3903
  const hint = detectFlatConfigHint(s, descriptor);
3462
3904
  errors.push({
3463
- path: `${path13}.${configKey}`,
3905
+ path: `${path14}.${configKey}`,
3464
3906
  message: `${capitalize(descriptor.type)} step must have a "${configKey}" config object${hint}`
3465
3907
  });
3466
3908
  continue;
3467
3909
  }
3468
3910
  const config2 = configObj;
3469
3911
  for (const [fieldName, fd] of Object.entries(descriptor.fields)) {
3470
- const fieldPath = `${path13}.${configKey}.${fieldName}`;
3912
+ const fieldPath = `${path14}.${configKey}.${fieldName}`;
3471
3913
  const value = config2[fieldName];
3472
3914
  if (fd.required && (value === void 0 || value === null || value === "")) {
3473
3915
  errors.push({ path: fieldPath, message: `${capitalize(descriptor.type)} must have ${fd.type === "string" ? "a string" : fd.type === "array" ? "a" : "a"} "${fieldName}"` });
@@ -3500,30 +3942,30 @@ function validateStepsArray(steps, pathPrefix, errors) {
3500
3942
  }
3501
3943
  }
3502
3944
  if (descriptor.type === "action") {
3503
- validateConnectionForm(config2, `${path13}.${configKey}`, errors);
3945
+ validateConnectionForm(config2, `${path14}.${configKey}`, errors);
3504
3946
  }
3505
3947
  if (descriptor.type === "code") {
3506
3948
  const hasSource = typeof config2.source === "string" && config2.source.length > 0;
3507
3949
  const hasModule = typeof config2.module === "string" && config2.module.length > 0;
3508
3950
  if (!hasSource && !hasModule) {
3509
- errors.push({ path: `${path13}.${configKey}`, message: 'Code step must define either "source" (inline JS) or "module" (path to .mjs file)' });
3951
+ errors.push({ path: `${path14}.${configKey}`, message: 'Code step must define either "source" (inline JS) or "module" (path to .mjs file)' });
3510
3952
  } else if (hasSource && hasModule) {
3511
- errors.push({ path: `${path13}.${configKey}`, message: 'Code step cannot define both "source" and "module" \u2014 pick one' });
3953
+ errors.push({ path: `${path14}.${configKey}`, message: 'Code step cannot define both "source" and "module" \u2014 pick one' });
3512
3954
  }
3513
3955
  if (hasModule) {
3514
3956
  const m = config2.module;
3515
3957
  if (m.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(m)) {
3516
- errors.push({ path: `${path13}.${configKey}.module`, message: "Code module path must be relative to the flow folder (no absolute paths)" });
3958
+ errors.push({ path: `${path14}.${configKey}.module`, message: "Code module path must be relative to the flow folder (no absolute paths)" });
3517
3959
  } else if (m.split(/[\\/]/).includes("..")) {
3518
- errors.push({ path: `${path13}.${configKey}.module`, message: 'Code module path must not escape the flow folder ("..")' });
3960
+ errors.push({ path: `${path14}.${configKey}.module`, message: 'Code module path must not escape the flow folder ("..")' });
3519
3961
  } else if (!m.endsWith(".mjs")) {
3520
- errors.push({ path: `${path13}.${configKey}.module`, message: "Code module must be a .mjs file" });
3962
+ errors.push({ path: `${path14}.${configKey}.module`, message: "Code module must be a .mjs file" });
3521
3963
  }
3522
3964
  }
3523
3965
  if (hasSource) {
3524
3966
  const syntaxError = checkCodeSourceSyntax(config2.source);
3525
3967
  if (syntaxError) {
3526
- errors.push({ path: `${path13}.${configKey}.source`, message: `Syntax error in code step: ${syntaxError}` });
3968
+ errors.push({ path: `${path14}.${configKey}.source`, message: `Syntax error in code step: ${syntaxError}` });
3527
3969
  }
3528
3970
  }
3529
3971
  }
@@ -3595,16 +4037,16 @@ function validateStepIds(flow2) {
3595
4037
  function collectIds(steps, pathPrefix) {
3596
4038
  for (let i = 0; i < steps.length; i++) {
3597
4039
  const step = steps[i];
3598
- const path13 = `${pathPrefix}[${i}]`;
4040
+ const path14 = `${pathPrefix}[${i}]`;
3599
4041
  if (seen.has(step.id)) {
3600
- errors.push({ path: `${path13}.id`, message: `Duplicate step ID: "${step.id}"` });
4042
+ errors.push({ path: `${path14}.id`, message: `Duplicate step ID: "${step.id}"` });
3601
4043
  } else {
3602
4044
  seen.add(step.id);
3603
4045
  }
3604
4046
  for (const { configKey, fieldName } of nestedKeys) {
3605
4047
  const config2 = step[configKey];
3606
4048
  if (config2 && Array.isArray(config2[fieldName])) {
3607
- collectIds(config2[fieldName], `${path13}.${configKey}.${fieldName}`);
4049
+ collectIds(config2[fieldName], `${path14}.${configKey}.${fieldName}`);
3608
4050
  }
3609
4051
  }
3610
4052
  }
@@ -3652,7 +4094,7 @@ function validateSelectorReferences(flow2, rootDir) {
3652
4094
  }
3653
4095
  return selectors;
3654
4096
  }
3655
- function checkSelectors(selectors, path13, precedingStepIds) {
4097
+ function checkSelectors(selectors, path14, precedingStepIds) {
3656
4098
  for (const selector of selectors) {
3657
4099
  const parts = selector.split(".");
3658
4100
  if (parts.length < 3) continue;
@@ -3660,15 +4102,15 @@ function validateSelectorReferences(flow2, rootDir) {
3660
4102
  if (root === "input") {
3661
4103
  const inputName = parts[2];
3662
4104
  if (!inputNames.has(inputName)) {
3663
- errors.push({ path: path13, message: `Selector "${selector}" references undefined input "${inputName}"` });
4105
+ errors.push({ path: path14, message: `Selector "${selector}" references undefined input "${inputName}"` });
3664
4106
  }
3665
4107
  } else if (root === "steps") {
3666
4108
  const stepId = parts[2].replace(/[\[\]]/g, "").split(/[\[\]]/)[0];
3667
4109
  if (!allStepIds.has(stepId)) {
3668
- errors.push({ path: path13, message: `Selector "${selector}" references undefined step "${stepId}"` });
4110
+ errors.push({ path: path14, message: `Selector "${selector}" references undefined step "${stepId}"` });
3669
4111
  } else if (precedingStepIds && !precedingStepIds.has(stepId)) {
3670
4112
  errors.push({
3671
- path: path13,
4113
+ path: path14,
3672
4114
  message: `Selector "${selector}" references step "${stepId}" which is declared after the current step. Steps execute in declaration order, so this will always resolve to undefined at runtime \u2014 move the dependency earlier in the steps array.`
3673
4115
  });
3674
4116
  }
@@ -3676,20 +4118,20 @@ function validateSelectorReferences(flow2, rootDir) {
3676
4118
  }
3677
4119
  }
3678
4120
  const EXPRESSION_FIELDS = /* @__PURE__ */ new Set(["condition.expression", "while.condition"]);
3679
- function checkOperatorsInSelectorField(value, path13) {
4121
+ function checkOperatorsInSelectorField(value, path14) {
3680
4122
  if (typeof value === "string" && value.startsWith("$.")) {
3681
4123
  if (value.includes("||")) {
3682
- errors.push({ path: path13, message: `Selector "${value}" contains unsupported operator "||". Selectors in data fields use dot-path resolution, not JS evaluation. Use the "default" field on the input definition instead, or use a "code" step for complex expressions.` });
4124
+ errors.push({ path: path14, message: `Selector "${value}" contains unsupported operator "||". Selectors in data fields use dot-path resolution, not JS evaluation. Use the "default" field on the input definition instead, or use a "code" step for complex expressions.` });
3683
4125
  } else if (value.includes("&&")) {
3684
- errors.push({ path: path13, message: `Selector "${value}" contains unsupported operator "&&". Selectors in data fields use dot-path resolution, not JS evaluation. Use a "condition" step or "code" step for complex expressions.` });
4126
+ errors.push({ path: path14, message: `Selector "${value}" contains unsupported operator "&&". Selectors in data fields use dot-path resolution, not JS evaluation. Use a "condition" step or "code" step for complex expressions.` });
3685
4127
  }
3686
4128
  } else if (value && typeof value === "object" && !Array.isArray(value)) {
3687
4129
  for (const [k, v] of Object.entries(value)) {
3688
- checkOperatorsInSelectorField(v, `${path13}.${k}`);
4130
+ checkOperatorsInSelectorField(v, `${path14}.${k}`);
3689
4131
  }
3690
4132
  } else if (Array.isArray(value)) {
3691
4133
  for (let i = 0; i < value.length; i++) {
3692
- checkOperatorsInSelectorField(value[i], `${path13}[${i}]`);
4134
+ checkOperatorsInSelectorField(value[i], `${path14}[${i}]`);
3693
4135
  }
3694
4136
  }
3695
4137
  }
@@ -3733,10 +4175,10 @@ function validateSelectorReferences(flow2, rootDir) {
3733
4175
  }
3734
4176
  const modulePath = step.type === "code" ? c.module : void 0;
3735
4177
  if (rootDir && typeof modulePath === "string" && modulePath.length > 0) {
3736
- const abs = path5.resolve(rootDir, modulePath);
3737
- if (fs4.existsSync(abs)) {
4178
+ const abs = path6.resolve(rootDir, modulePath);
4179
+ if (fs5.existsSync(abs)) {
3738
4180
  try {
3739
- const moduleText = fs4.readFileSync(abs, "utf-8");
4181
+ const moduleText = fs5.readFileSync(abs, "utf-8");
3740
4182
  checkSelectors(extractSelectors(moduleText), `${pathPrefix}.${descriptor.configKey}.module`, preceding2);
3741
4183
  } catch {
3742
4184
  }
@@ -3774,10 +4216,10 @@ var VALID_OUTPUT_SCHEMA_TYPES = /* @__PURE__ */ new Set(["string", "number", "bo
3774
4216
  function isOutputSchemaObject(v) {
3775
4217
  return !!v && typeof v === "object" && !Array.isArray(v);
3776
4218
  }
3777
- function walkOutputSchema(schema, path13) {
4219
+ function walkOutputSchema(schema, path14) {
3778
4220
  let current = schema;
3779
- for (let i = 0; i < path13.length; i++) {
3780
- const seg = path13[i];
4221
+ for (let i = 0; i < path14.length; i++) {
4222
+ const seg = path14[i];
3781
4223
  if (typeof current === "string") {
3782
4224
  return current === "unknown" || current === "object" || current === "array" ? "opaque" : "opaque";
3783
4225
  }
@@ -3929,8 +4371,8 @@ function validateCodeModules(flow2, rootDir) {
3929
4371
  const stepPath = `${pathPrefix}[${i}]`;
3930
4372
  if (step.type === "code" && step.code?.module) {
3931
4373
  const m = step.code.module;
3932
- const abs = path5.resolve(rootDir, m);
3933
- if (!fs4.existsSync(abs)) {
4374
+ const abs = path6.resolve(rootDir, m);
4375
+ if (!fs5.existsSync(abs)) {
3934
4376
  errors.push({
3935
4377
  path: `${stepPath}.code.module`,
3936
4378
  message: `Code module "${m}" not found at ${abs}`
@@ -4061,11 +4503,11 @@ function validateFileReadSchemas(flow2) {
4061
4503
  }
4062
4504
 
4063
4505
  // src/commands/flow.ts
4064
- import fs5 from "fs";
4065
- import path6 from "path";
4506
+ import fs6 from "fs";
4507
+ import path7 from "path";
4066
4508
  async function writeFlowResultFile(filePath, meta, steps) {
4067
- const abs = path6.resolve(filePath);
4068
- const ws = fs5.createWriteStream(abs);
4509
+ const abs = path7.resolve(filePath);
4510
+ const ws = fs6.createWriteStream(abs);
4069
4511
  const done = new Promise((resolve, reject) => {
4070
4512
  ws.on("finish", () => resolve());
4071
4513
  ws.on("error", reject);
@@ -4096,25 +4538,25 @@ function previewValue(value, max = 120) {
4096
4538
  }
4097
4539
  function renderDryRef(ref) {
4098
4540
  if (ref.status === "resolved") {
4099
- return `${pc8.green("\u2713")} ${ref.selector} ${pc8.dim("\u2192")} ${previewValue(ref.value)}`;
4541
+ return `${pc9.green("\u2713")} ${ref.selector} ${pc9.dim("\u2192")} ${previewValue(ref.value)}`;
4100
4542
  }
4101
4543
  if (ref.status === "deferred") {
4102
- return `${pc8.dim("\u25CB")} ${ref.selector} ${pc8.dim("\u2192 pending (produced by a later step)")}`;
4544
+ return `${pc9.dim("\u25CB")} ${ref.selector} ${pc9.dim("\u2192 pending (produced by a later step)")}`;
4103
4545
  }
4104
- return `${pc8.yellow("!")} ${ref.selector} ${pc8.yellow("\u2192 unresolved \u2014 check the input/env name")}`;
4546
+ return `${pc9.yellow("!")} ${ref.selector} ${pc9.yellow("\u2192 unresolved \u2014 check the input/env name")}`;
4105
4547
  }
4106
4548
  function renderDryResolution(steps) {
4107
4549
  const isExpr = (t) => t === "transform" || t === "condition" || t === "while";
4108
4550
  for (const s of steps) {
4109
- const label = s.name ? `${s.stepId} ${pc8.dim(`"${s.name}"`)}` : s.stepId;
4110
- console.log(` ${pc8.cyan("\u25B8")} ${label} ${pc8.dim(`(${s.type})`)}`);
4551
+ const label = s.name ? `${s.stepId} ${pc9.dim(`"${s.name}"`)}` : s.stepId;
4552
+ console.log(` ${pc9.cyan("\u25B8")} ${label} ${pc9.dim(`(${s.type})`)}`);
4111
4553
  if (s.error !== void 0) {
4112
- console.log(` ${pc8.red("error")} ${s.error}`);
4554
+ console.log(` ${pc9.red("error")} ${s.error}`);
4113
4555
  } else if (isExpr(s.type) && s.deferred) {
4114
4556
  const deps = s.references.map((r) => r.selector).join(", ");
4115
- console.log(` ${pc8.dim("\u25CB pending \u2014 depends on")} ${deps} ${pc8.dim("(produced by a later step)")}`);
4557
+ console.log(` ${pc9.dim("\u25CB pending \u2014 depends on")} ${deps} ${pc9.dim("(produced by a later step)")}`);
4116
4558
  } else if (isExpr(s.type)) {
4117
- console.log(` ${pc8.dim("=")} ${previewValue(s.resolved)}`);
4559
+ console.log(` ${pc9.dim("=")} ${previewValue(s.resolved)}`);
4118
4560
  }
4119
4561
  if (!(isExpr(s.type) && s.deferred)) {
4120
4562
  for (const ref of s.references) {
@@ -4122,7 +4564,7 @@ function renderDryResolution(steps) {
4122
4564
  }
4123
4565
  }
4124
4566
  if (!isExpr(s.type) && s.references.length === 0 && s.error === void 0) {
4125
- console.log(` ${pc8.dim("(no interpolations)")}`);
4567
+ console.log(` ${pc9.dim("(no interpolations)")}`);
4126
4568
  }
4127
4569
  }
4128
4570
  }
@@ -4176,14 +4618,14 @@ async function autoResolveConnectionInputs(flow2, inputs, api) {
4176
4618
  return resolved;
4177
4619
  }
4178
4620
  async function flowCreateCommand(key, options) {
4179
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
4621
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4180
4622
  let flow2;
4181
4623
  if (options.definition) {
4182
4624
  let raw = options.definition;
4183
4625
  if (raw.startsWith("@")) {
4184
4626
  const filePath = raw.slice(1);
4185
4627
  try {
4186
- raw = fs5.readFileSync(filePath, "utf-8");
4628
+ raw = fs6.readFileSync(filePath, "utf-8");
4187
4629
  } catch (err) {
4188
4630
  error(`Cannot read file "${filePath}": ${err.message}`);
4189
4631
  }
@@ -4232,15 +4674,15 @@ ${errors.map((e) => ` ${e.path}: ${e.message}`).join("\n")}`);
4232
4674
  return;
4233
4675
  }
4234
4676
  note(`Workflow "${flow2.name}" saved to ${flowPath}`, "Created");
4235
- outro(`Validate: ${pc8.cyan(`one flow validate ${flow2.key}`)}
4236
- Execute: ${pc8.cyan(`one flow execute ${flow2.key}`)}`);
4677
+ outro(`Validate: ${pc9.cyan(`one flow validate ${flow2.key}`)}
4678
+ Execute: ${pc9.cyan(`one flow execute ${flow2.key}`)}`);
4237
4679
  }
4238
4680
  async function flowExecuteCommand(keyOrPath, options) {
4239
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
4681
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4240
4682
  const { apiKey, permissions, actionIds } = getConfig2();
4241
4683
  const api = new OneApi(apiKey, getApiBase());
4242
- const spinner5 = createSpinner();
4243
- spinner5.start(`Loading workflow "${keyOrPath}"...`);
4684
+ const spinner4 = createSpinner();
4685
+ spinner4.start(`Loading workflow "${keyOrPath}"...`);
4244
4686
  let flow2;
4245
4687
  let rootDir;
4246
4688
  let flowFilePath;
@@ -4250,11 +4692,11 @@ async function flowExecuteCommand(keyOrPath, options) {
4250
4692
  rootDir = loaded.rootDir;
4251
4693
  flowFilePath = loaded.filePath;
4252
4694
  } catch (err) {
4253
- spinner5.stop("Workflow not found");
4695
+ spinner4.stop("Workflow not found");
4254
4696
  error(err instanceof Error ? err.message : String(err));
4255
4697
  return;
4256
4698
  }
4257
- spinner5.stop(`Workflow: ${flow2.name} (${flow2.steps.length} steps)`);
4699
+ spinner4.stop(`Workflow: ${flow2.name} (${flow2.steps.length} steps)`);
4258
4700
  const preflightErrors = validateFlow(flow2, rootDir);
4259
4701
  if (preflightErrors.length > 0) {
4260
4702
  if (isAgentMode()) {
@@ -4269,7 +4711,7 @@ ${preflightErrors.map((e) => ` ${e.path}: ${e.message}`).join("\n")}`);
4269
4711
  if (isAgentMode()) {
4270
4712
  json({ event: "flow:deprecation", flowKey: flow2.key, warning: msg });
4271
4713
  } else {
4272
- console.error(pc8.yellow(`\u26A0 ${msg}`));
4714
+ console.error(pc9.yellow(`\u26A0 ${msg}`));
4273
4715
  }
4274
4716
  }
4275
4717
  if (!options.allowBash && flowRequiresBash(flow2)) {
@@ -4303,7 +4745,7 @@ ${preflightErrors.map((e) => ` ${e.path}: ${e.message}`).join("\n")}`);
4303
4745
  runner.requestPause();
4304
4746
  if (!isAgentMode()) {
4305
4747
  console.log(`
4306
- ${pc8.yellow("Pausing after current step completes...")} (run ID: ${runId})`);
4748
+ ${pc9.yellow("Pausing after current step completes...")} (run ID: ${runId})`);
4307
4749
  }
4308
4750
  };
4309
4751
  process.on("SIGINT", sigintHandler);
@@ -4323,12 +4765,12 @@ ${pc8.yellow("Pausing after current step completes...")} (run ID: ${runId})`);
4323
4765
  } else if (options.verbose) {
4324
4766
  const ts = (/* @__PURE__ */ new Date()).toISOString().split("T")[1].slice(0, 8);
4325
4767
  if (event.event === "step:start") {
4326
- console.log(` ${pc8.dim(ts)} ${pc8.cyan("\u25B6")} ${event.stepName} ${pc8.dim(`(${event.type})`)}`);
4768
+ console.log(` ${pc9.dim(ts)} ${pc9.cyan("\u25B6")} ${event.stepName} ${pc9.dim(`(${event.type})`)}`);
4327
4769
  } else if (event.event === "step:complete") {
4328
- const status = event.status === "success" ? pc8.green("\u2713") : event.status === "skipped" ? pc8.dim("\u25CB") : pc8.red("\u2717");
4329
- console.log(` ${pc8.dim(ts)} ${status} ${event.stepId} ${pc8.dim(`${event.durationMs}ms`)}`);
4770
+ const status = event.status === "success" ? pc9.green("\u2713") : event.status === "skipped" ? pc9.dim("\u25CB") : pc9.red("\u2717");
4771
+ console.log(` ${pc9.dim(ts)} ${status} ${event.stepId} ${pc9.dim(`${event.durationMs}ms`)}`);
4330
4772
  } else if (event.event === "step:error") {
4331
- console.log(` ${pc8.dim(ts)} ${pc8.red("\u2717")} ${event.stepId}: ${event.error}`);
4773
+ console.log(` ${pc9.dim(ts)} ${pc9.red("\u2717")} ${event.stepId}: ${event.error}`);
4332
4774
  }
4333
4775
  }
4334
4776
  };
@@ -4377,8 +4819,8 @@ ${pc8.yellow("Pausing after current step completes...")} (run ID: ${runId})`);
4377
4819
  console.log();
4378
4820
  const missing = dryRunSteps.reduce((n, s) => n + s.references.filter((r) => r.status === "missing").length, 0);
4379
4821
  note(
4380
- `Dry run \u2014 no steps executed. Resolved ${dryRunSteps.length} step(s)` + (missing > 0 ? `; ${pc8.yellow(`${missing} unresolved input/env reference(s)`)}` : "") + `.
4381
- ${pc8.dim("$.steps.* refs resolve at runtime \u2014 re-run with --stop-after=<stepId> to resolve them against real output.")}`,
4822
+ `Dry run \u2014 no steps executed. Resolved ${dryRunSteps.length} step(s)` + (missing > 0 ? `; ${pc9.yellow(`${missing} unresolved input/env reference(s)`)}` : "") + `.
4823
+ ${pc9.dim("$.steps.* refs resolve at runtime \u2014 re-run with --stop-after=<stepId> to resolve them against real output.")}`,
4382
4824
  "Dry Run"
4383
4825
  );
4384
4826
  return;
@@ -4388,17 +4830,17 @@ ${pc8.dim("$.steps.* refs resolve at runtime \u2014 re-run with --stop-after=<st
4388
4830
  const failed = stepEntries.filter(([, r]) => r.status === "failed").length;
4389
4831
  const skipped = stepEntries.filter(([, r]) => r.status === "skipped").length;
4390
4832
  console.log();
4391
- console.log(` ${pc8.green("\u2713")} ${succeeded} succeeded ${failed > 0 ? pc8.red(`\u2717 ${failed} failed`) : ""} ${skipped > 0 ? pc8.dim(`\u25CB ${skipped} skipped`) : ""}`);
4392
- console.log(` ${pc8.dim(`Run ID: ${runId}`)}`);
4393
- console.log(` ${pc8.dim(`Log: ${logPath}`)}`);
4833
+ console.log(` ${pc9.green("\u2713")} ${succeeded} succeeded ${failed > 0 ? pc9.red(`\u2717 ${failed} failed`) : ""} ${skipped > 0 ? pc9.dim(`\u25CB ${skipped} skipped`) : ""}`);
4834
+ console.log(` ${pc9.dim(`Run ID: ${runId}`)}`);
4835
+ console.log(` ${pc9.dim(`Log: ${logPath}`)}`);
4394
4836
  if (dryResolveTarget) {
4395
4837
  console.log();
4396
- console.log(` ${pc8.dim(`Resolved (not executed) "${dryResolveTarget.stepId}":`)}`);
4838
+ console.log(` ${pc9.dim(`Resolved (not executed) "${dryResolveTarget.stepId}":`)}`);
4397
4839
  renderDryResolution([dryResolveTarget]);
4398
4840
  }
4399
4841
  if (stoppedAfter) {
4400
4842
  note(
4401
- `Stopped after step "${stoppedAfter}". Inspect step outputs with: ${pc8.cyan(`one flow inspect ${runId}`)}`,
4843
+ `Stopped after step "${stoppedAfter}". Inspect step outputs with: ${pc9.cyan(`one flow inspect ${runId}`)}`,
4402
4844
  "Stopped"
4403
4845
  );
4404
4846
  } else if (options.dryRun) {
@@ -4420,13 +4862,13 @@ ${pc8.dim("$.steps.* refs resolve at runtime \u2014 re-run with --stop-after=<st
4420
4862
  });
4421
4863
  process.exit(1);
4422
4864
  }
4423
- console.log(` ${pc8.dim(`Run ID: ${runId}`)}`);
4424
- console.log(` ${pc8.dim(`Log: ${logPath}`)}`);
4865
+ console.log(` ${pc9.dim(`Run ID: ${runId}`)}`);
4866
+ console.log(` ${pc9.dim(`Log: ${logPath}`)}`);
4425
4867
  error(`Workflow failed: ${errorMsg}`);
4426
4868
  }
4427
4869
  }
4428
4870
  async function flowListCommand() {
4429
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
4871
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4430
4872
  const flows = listFlows();
4431
4873
  if (isAgentMode()) {
4432
4874
  json({ workflows: flows });
@@ -4458,9 +4900,9 @@ async function flowListCommand() {
4458
4900
  console.log();
4459
4901
  }
4460
4902
  async function flowValidateCommand(keyOrPath) {
4461
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
4462
- const spinner5 = createSpinner();
4463
- spinner5.start(`Validating "${keyOrPath}"...`);
4903
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4904
+ const spinner4 = createSpinner();
4905
+ spinner4.start(`Validating "${keyOrPath}"...`);
4464
4906
  let flowData;
4465
4907
  let rootDir;
4466
4908
  try {
@@ -4470,29 +4912,29 @@ async function flowValidateCommand(keyOrPath) {
4470
4912
  rootDir = loaded.rootDir;
4471
4913
  } catch {
4472
4914
  const flowPath = resolveFlowPath(keyOrPath);
4473
- const content = fs5.readFileSync(flowPath, "utf-8");
4915
+ const content = fs6.readFileSync(flowPath, "utf-8");
4474
4916
  flowData = JSON.parse(content);
4475
- rootDir = path6.dirname(flowPath);
4917
+ rootDir = path7.dirname(flowPath);
4476
4918
  }
4477
4919
  } catch (err) {
4478
- spinner5.stop("Validation failed");
4920
+ spinner4.stop("Validation failed");
4479
4921
  error(`Could not read workflow: ${err instanceof Error ? err.message : String(err)}`);
4480
4922
  }
4481
4923
  const errors = validateFlow(flowData, rootDir);
4482
4924
  if (errors.length > 0) {
4483
- spinner5.stop("Validation failed");
4925
+ spinner4.stop("Validation failed");
4484
4926
  if (isAgentMode()) {
4485
4927
  json({ valid: false, errors });
4486
4928
  process.exit(1);
4487
4929
  }
4488
4930
  console.log();
4489
4931
  for (const e of errors) {
4490
- console.log(` ${pc8.red("\u2717")} ${pc8.dim(e.path)}: ${e.message}`);
4932
+ console.log(` ${pc9.red("\u2717")} ${pc9.dim(e.path)}: ${e.message}`);
4491
4933
  }
4492
4934
  console.log();
4493
4935
  error(`${errors.length} validation error(s) found`);
4494
4936
  }
4495
- spinner5.stop("Workflow is valid");
4937
+ spinner4.stop("Workflow is valid");
4496
4938
  if (isAgentMode()) {
4497
4939
  json({ valid: true, key: flowData.key });
4498
4940
  return;
@@ -4500,7 +4942,7 @@ async function flowValidateCommand(keyOrPath) {
4500
4942
  note(`Workflow "${flowData.key}" passed all validation checks`, "Valid");
4501
4943
  }
4502
4944
  async function flowResumeCommand(runId, options = {}) {
4503
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
4945
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4504
4946
  const state = FlowRunner.loadRunState(runId);
4505
4947
  if (!state) {
4506
4948
  error(`Run "${runId}" not found`);
@@ -4534,15 +4976,15 @@ async function flowResumeCommand(runId, options = {}) {
4534
4976
  json(event);
4535
4977
  }
4536
4978
  };
4537
- const spinner5 = createSpinner();
4538
- spinner5.start(`Resuming run ${runId} (${state.completedSteps.length} steps already completed)...`);
4979
+ const spinner4 = createSpinner();
4980
+ spinner4.start(`Resuming run ${runId} (${state.completedSteps.length} steps already completed)...`);
4539
4981
  try {
4540
4982
  const context = await runner.resume(flow2, api, permissions, actionIds, {
4541
4983
  onEvent,
4542
4984
  rootDir,
4543
4985
  allowBash: options.allowBash
4544
4986
  });
4545
- spinner5.stop("Workflow completed");
4987
+ spinner4.stop("Workflow completed");
4546
4988
  if (isAgentMode()) {
4547
4989
  json({
4548
4990
  event: "workflow:result",
@@ -4553,10 +4995,10 @@ async function flowResumeCommand(runId, options = {}) {
4553
4995
  });
4554
4996
  return;
4555
4997
  }
4556
- console.log(` ${pc8.green("\u2713")} Resumed and completed successfully`);
4557
- console.log(` ${pc8.dim(`Log: ${runner.getLogPath()}`)}`);
4998
+ console.log(` ${pc9.green("\u2713")} Resumed and completed successfully`);
4999
+ console.log(` ${pc9.dim(`Log: ${runner.getLogPath()}`)}`);
4558
5000
  } catch (error2) {
4559
- spinner5.stop("Resume failed");
5001
+ spinner4.stop("Resume failed");
4560
5002
  const errorMsg = error2 instanceof Error ? error2.message : String(error2);
4561
5003
  if (isAgentMode()) {
4562
5004
  json({ event: "workflow:result", runId, status: "failed", error: errorMsg });
@@ -4566,7 +5008,7 @@ async function flowResumeCommand(runId, options = {}) {
4566
5008
  }
4567
5009
  }
4568
5010
  async function flowRunsCommand(flowKey) {
4569
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
5011
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4570
5012
  const runs = FlowRunner.listRuns(flowKey);
4571
5013
  if (isAgentMode()) {
4572
5014
  json({
@@ -4606,7 +5048,7 @@ async function flowRunsCommand(flowKey) {
4606
5048
  console.log();
4607
5049
  }
4608
5050
  async function flowInspectCommand(runId, options = {}) {
4609
- intro(pc8.bgCyan(pc8.black(" One Workflow ")));
5051
+ intro(pc9.bgCyan(pc9.black(" One Workflow ")));
4610
5052
  const state = FlowRunner.loadRunState(runId);
4611
5053
  if (!state) {
4612
5054
  const msg = `No run found for id "${runId}". List runs with: one flow runs`;
@@ -4635,44 +5077,44 @@ async function flowInspectCommand(runId, options = {}) {
4635
5077
  return;
4636
5078
  }
4637
5079
  console.log();
4638
- console.log(` ${pc8.bold(state.flowKey)} ${pc8.dim(`run ${state.runId}`)} ${colorStatus(state.status)}`);
4639
- console.log(` ${pc8.dim(`Started: ${state.startedAt}${state.completedAt ? ` \xB7 Ended: ${state.completedAt}` : ""}`)}`);
4640
- if (state.currentStepId) console.log(` ${pc8.dim(`Current step: ${state.currentStepId}`)}`);
5080
+ console.log(` ${pc9.bold(state.flowKey)} ${pc9.dim(`run ${state.runId}`)} ${colorStatus(state.status)}`);
5081
+ console.log(` ${pc9.dim(`Started: ${state.startedAt}${state.completedAt ? ` \xB7 Ended: ${state.completedAt}` : ""}`)}`);
5082
+ if (state.currentStepId) console.log(` ${pc9.dim(`Current step: ${state.currentStepId}`)}`);
4641
5083
  console.log();
4642
5084
  if (stepEntries.length === 0) {
4643
5085
  note("No step outputs recorded yet for this run.", "Steps");
4644
5086
  } else {
4645
5087
  for (const [id, result] of stepEntries) {
4646
- const icon = result.status === "success" ? pc8.green("\u2713") : result.status === "skipped" ? pc8.dim("\u25CB") : result.status === "timeout" ? pc8.yellow("\u29D6") : pc8.red("\u2717");
4647
- const dur = result.durationMs !== void 0 ? pc8.dim(` ${result.durationMs}ms`) : "";
4648
- const retries = result.retries ? pc8.dim(` (${result.retries} retr${result.retries === 1 ? "y" : "ies"})`) : "";
4649
- console.log(` ${icon} ${id} ${pc8.dim(`[${result.status}]`)}${dur}${retries}`);
5088
+ const icon = result.status === "success" ? pc9.green("\u2713") : result.status === "skipped" ? pc9.dim("\u25CB") : result.status === "timeout" ? pc9.yellow("\u29D6") : pc9.red("\u2717");
5089
+ const dur = result.durationMs !== void 0 ? pc9.dim(` ${result.durationMs}ms`) : "";
5090
+ const retries = result.retries ? pc9.dim(` (${result.retries} retr${result.retries === 1 ? "y" : "ies"})`) : "";
5091
+ console.log(` ${icon} ${id} ${pc9.dim(`[${result.status}]`)}${dur}${retries}`);
4650
5092
  if (result.error) {
4651
- console.log(` ${pc8.red("error")} ${result.error}${result.errorCode ? pc8.dim(` (${result.errorCode})`) : ""}`);
5093
+ console.log(` ${pc9.red("error")} ${result.error}${result.errorCode ? pc9.dim(` (${result.errorCode})`) : ""}`);
4652
5094
  }
4653
5095
  if (result.output !== void 0) {
4654
5096
  const json2 = JSON.stringify(result.output, null, options.full ? 2 : 0) ?? String(result.output);
4655
- const shown = options.full || json2.length <= 240 ? json2 : `${json2.slice(0, 239)}\u2026 ${pc8.dim("(--full for all)")}`;
4656
- const indented = options.full ? shown.split("\n").map((l) => ` ${l}`).join("\n") : ` ${pc8.dim("output")} ${shown}`;
5097
+ const shown = options.full || json2.length <= 240 ? json2 : `${json2.slice(0, 239)}\u2026 ${pc9.dim("(--full for all)")}`;
5098
+ const indented = options.full ? shown.split("\n").map((l) => ` ${l}`).join("\n") : ` ${pc9.dim("output")} ${shown}`;
4657
5099
  console.log(indented);
4658
5100
  }
4659
5101
  }
4660
5102
  }
4661
5103
  console.log();
4662
- console.log(` ${pc8.dim(`State: ${statePath}`)}`);
4663
- console.log(` ${pc8.dim(`Log: ${path6.join(".one/flows/.logs", `${state.flowKey}-${state.runId}.log`)}`)}`);
5104
+ console.log(` ${pc9.dim(`State: ${statePath}`)}`);
5105
+ console.log(` ${pc9.dim(`Log: ${path7.join(".one/flows/.logs", `${state.flowKey}-${state.runId}.log`)}`)}`);
4664
5106
  console.log();
4665
5107
  }
4666
5108
  function colorStatus(status) {
4667
5109
  switch (status) {
4668
5110
  case "completed":
4669
- return pc8.green(status);
5111
+ return pc9.green(status);
4670
5112
  case "running":
4671
- return pc8.cyan(status);
5113
+ return pc9.cyan(status);
4672
5114
  case "paused":
4673
- return pc8.yellow(status);
5115
+ return pc9.yellow(status);
4674
5116
  case "failed":
4675
- return pc8.red(status);
5117
+ return pc9.red(status);
4676
5118
  default:
4677
5119
  return status;
4678
5120
  }
@@ -4850,7 +5292,7 @@ async function flowScaffoldCommand(template) {
4850
5292
  }
4851
5293
 
4852
5294
  // src/commands/relay.ts
4853
- import pc9 from "picocolors";
5295
+ import pc10 from "picocolors";
4854
5296
  function getConfig3() {
4855
5297
  const apiKey = getApiKey();
4856
5298
  if (!apiKey) {
@@ -4873,8 +5315,8 @@ async function relayCreateCommand(options) {
4873
5315
  error(`Connection key "${options.connectionKey}" is not allowed.`);
4874
5316
  }
4875
5317
  const api = new OneApi(apiKey, getApiBase());
4876
- const spinner5 = createSpinner();
4877
- spinner5.start("Creating relay endpoint...");
5318
+ const spinner4 = createSpinner();
5319
+ spinner4.start("Creating relay endpoint...");
4878
5320
  try {
4879
5321
  const body = {
4880
5322
  connectionKey: options.connectionKey
@@ -4889,29 +5331,29 @@ async function relayCreateCommand(options) {
4889
5331
  json(result);
4890
5332
  return;
4891
5333
  }
4892
- spinner5.stop("Relay endpoint created");
5334
+ spinner4.stop("Relay endpoint created");
4893
5335
  console.log();
4894
- console.log(` ${pc9.dim("ID:")} ${result.id}`);
4895
- console.log(` ${pc9.dim("URL:")} ${result.url}`);
4896
- console.log(` ${pc9.dim("Active:")} ${result.active}`);
4897
- if (result.description) console.log(` ${pc9.dim("Description:")} ${result.description}`);
4898
- if (result.eventFilters?.length) console.log(` ${pc9.dim("Events:")} ${result.eventFilters.join(", ")}`);
4899
- if (result.webhookPayload?.id) console.log(` ${pc9.dim("Webhook ID:")} ${result.webhookPayload.id}`);
5336
+ console.log(` ${pc10.dim("ID:")} ${result.id}`);
5337
+ console.log(` ${pc10.dim("URL:")} ${result.url}`);
5338
+ console.log(` ${pc10.dim("Active:")} ${result.active}`);
5339
+ if (result.description) console.log(` ${pc10.dim("Description:")} ${result.description}`);
5340
+ if (result.eventFilters?.length) console.log(` ${pc10.dim("Events:")} ${result.eventFilters.join(", ")}`);
5341
+ if (result.webhookPayload?.id) console.log(` ${pc10.dim("Webhook ID:")} ${result.webhookPayload.id}`);
4900
5342
  if (result.warning) {
4901
5343
  console.log();
4902
- console.log(` ${pc9.yellow("\u26A0 Warning:")} ${result.warning}`);
5344
+ console.log(` ${pc10.yellow("\u26A0 Warning:")} ${result.warning}`);
4903
5345
  }
4904
5346
  console.log();
4905
5347
  } catch (error2) {
4906
- spinner5.stop("Failed to create relay endpoint");
5348
+ spinner4.stop("Failed to create relay endpoint");
4907
5349
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
4908
5350
  }
4909
5351
  }
4910
5352
  async function relayListCommand(options) {
4911
5353
  const { apiKey } = getConfig3();
4912
5354
  const api = new OneApi(apiKey, getApiBase());
4913
- const spinner5 = createSpinner();
4914
- spinner5.start("Loading relay endpoints...");
5355
+ const spinner4 = createSpinner();
5356
+ spinner4.start("Loading relay endpoints...");
4915
5357
  try {
4916
5358
  const query = {};
4917
5359
  if (options.limit) query.limit = options.limit;
@@ -4934,7 +5376,7 @@ async function relayListCommand(options) {
4934
5376
  });
4935
5377
  return;
4936
5378
  }
4937
- spinner5.stop(`${endpoints.length} relay endpoint${endpoints.length === 1 ? "" : "s"} found`);
5379
+ spinner4.stop(`${endpoints.length} relay endpoint${endpoints.length === 1 ? "" : "s"} found`);
4938
5380
  if (endpoints.length === 0) {
4939
5381
  console.log("\n No relay endpoints yet.\n");
4940
5382
  return;
@@ -4945,57 +5387,57 @@ async function relayListCommand(options) {
4945
5387
  { key: "description", label: "Description" },
4946
5388
  { key: "events", label: "Events" },
4947
5389
  { key: "actions", label: "Actions" },
4948
- { key: "id", label: "ID", color: pc9.dim }
5390
+ { key: "id", label: "ID", color: pc10.dim }
4949
5391
  ],
4950
5392
  endpoints.map((e) => ({
4951
- status: e.active ? pc9.green("\u25CF") : pc9.dim("\u25CB"),
4952
- description: e.description || pc9.dim("(none)"),
4953
- events: e.eventFilters?.join(", ") || pc9.dim("all"),
5393
+ status: e.active ? pc10.green("\u25CF") : pc10.dim("\u25CB"),
5394
+ description: e.description || pc10.dim("(none)"),
5395
+ events: e.eventFilters?.join(", ") || pc10.dim("all"),
4954
5396
  actions: String(e.actions?.length || 0),
4955
5397
  id: e.id.slice(0, 8)
4956
5398
  }))
4957
5399
  );
4958
5400
  } catch (error2) {
4959
- spinner5.stop("Failed to list relay endpoints");
5401
+ spinner4.stop("Failed to list relay endpoints");
4960
5402
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
4961
5403
  }
4962
5404
  }
4963
5405
  async function relayGetCommand(id) {
4964
5406
  const { apiKey } = getConfig3();
4965
5407
  const api = new OneApi(apiKey, getApiBase());
4966
- const spinner5 = createSpinner();
4967
- spinner5.start("Loading relay endpoint...");
5408
+ const spinner4 = createSpinner();
5409
+ spinner4.start("Loading relay endpoint...");
4968
5410
  try {
4969
5411
  const result = await api.getRelayEndpoint(id);
4970
5412
  if (isAgentMode()) {
4971
5413
  json(result);
4972
5414
  return;
4973
5415
  }
4974
- spinner5.stop("Relay endpoint loaded");
5416
+ spinner4.stop("Relay endpoint loaded");
4975
5417
  console.log();
4976
- console.log(` ${pc9.dim("ID:")} ${result.id}`);
4977
- console.log(` ${pc9.dim("URL:")} ${result.url}`);
4978
- console.log(` ${pc9.dim("Active:")} ${result.active}`);
4979
- if (result.description) console.log(` ${pc9.dim("Description:")} ${result.description}`);
4980
- if (result.eventFilters?.length) console.log(` ${pc9.dim("Events:")} ${result.eventFilters.join(", ")}`);
4981
- console.log(` ${pc9.dim("Actions:")} ${result.actions?.length || 0}`);
5418
+ console.log(` ${pc10.dim("ID:")} ${result.id}`);
5419
+ console.log(` ${pc10.dim("URL:")} ${result.url}`);
5420
+ console.log(` ${pc10.dim("Active:")} ${result.active}`);
5421
+ if (result.description) console.log(` ${pc10.dim("Description:")} ${result.description}`);
5422
+ if (result.eventFilters?.length) console.log(` ${pc10.dim("Events:")} ${result.eventFilters.join(", ")}`);
5423
+ console.log(` ${pc10.dim("Actions:")} ${result.actions?.length || 0}`);
4982
5424
  if (result.actions?.length) {
4983
5425
  for (const [i, action] of result.actions.entries()) {
4984
- console.log(` ${pc9.dim(`[${i}]`)} type=${action.type}${action.actionId ? ` actionId=${action.actionId}` : ""}${action.url ? ` url=${action.url}` : ""}`);
5426
+ console.log(` ${pc10.dim(`[${i}]`)} type=${action.type}${action.actionId ? ` actionId=${action.actionId}` : ""}${action.url ? ` url=${action.url}` : ""}`);
4985
5427
  }
4986
5428
  }
4987
- console.log(` ${pc9.dim("Created:")} ${result.createdAt}`);
5429
+ console.log(` ${pc10.dim("Created:")} ${result.createdAt}`);
4988
5430
  console.log();
4989
5431
  } catch (error2) {
4990
- spinner5.stop("Failed to load relay endpoint");
5432
+ spinner4.stop("Failed to load relay endpoint");
4991
5433
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
4992
5434
  }
4993
5435
  }
4994
5436
  async function relayUpdateCommand(id, options) {
4995
5437
  const { apiKey } = getConfig3();
4996
5438
  const api = new OneApi(apiKey, getApiBase());
4997
- const spinner5 = createSpinner();
4998
- spinner5.start("Updating relay endpoint...");
5439
+ const spinner4 = createSpinner();
5440
+ spinner4.start("Updating relay endpoint...");
4999
5441
  try {
5000
5442
  const body = {};
5001
5443
  if (options.description !== void 0) body.description = options.description;
@@ -5008,40 +5450,40 @@ async function relayUpdateCommand(id, options) {
5008
5450
  json(result);
5009
5451
  return;
5010
5452
  }
5011
- spinner5.stop("Relay endpoint updated");
5012
- console.log(` ${pc9.dim("ID:")} ${result.id}`);
5013
- console.log(` ${pc9.dim("Active:")} ${result.active}`);
5014
- console.log(` ${pc9.dim("Actions:")} ${result.actions?.length || 0}`);
5453
+ spinner4.stop("Relay endpoint updated");
5454
+ console.log(` ${pc10.dim("ID:")} ${result.id}`);
5455
+ console.log(` ${pc10.dim("Active:")} ${result.active}`);
5456
+ console.log(` ${pc10.dim("Actions:")} ${result.actions?.length || 0}`);
5015
5457
  console.log();
5016
5458
  } catch (error2) {
5017
- spinner5.stop("Failed to update relay endpoint");
5459
+ spinner4.stop("Failed to update relay endpoint");
5018
5460
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5019
5461
  }
5020
5462
  }
5021
5463
  async function relayDeleteCommand(id) {
5022
5464
  const { apiKey } = getConfig3();
5023
5465
  const api = new OneApi(apiKey, getApiBase());
5024
- const spinner5 = createSpinner();
5025
- spinner5.start("Deleting relay endpoint...");
5466
+ const spinner4 = createSpinner();
5467
+ spinner4.start("Deleting relay endpoint...");
5026
5468
  try {
5027
5469
  const result = await api.deleteRelayEndpoint(id);
5028
5470
  if (isAgentMode()) {
5029
5471
  json({ deleted: true, id: result.id });
5030
5472
  return;
5031
5473
  }
5032
- spinner5.stop("Relay endpoint deleted");
5474
+ spinner4.stop("Relay endpoint deleted");
5033
5475
  console.log(` Deleted: ${result.id}`);
5034
5476
  console.log();
5035
5477
  } catch (error2) {
5036
- spinner5.stop("Failed to delete relay endpoint");
5478
+ spinner4.stop("Failed to delete relay endpoint");
5037
5479
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5038
5480
  }
5039
5481
  }
5040
5482
  async function relayActivateCommand(id, options) {
5041
5483
  const { apiKey } = getConfig3();
5042
5484
  const api = new OneApi(apiKey, getApiBase());
5043
- const spinner5 = createSpinner();
5044
- spinner5.start("Activating relay endpoint...");
5485
+ const spinner4 = createSpinner();
5486
+ spinner4.start("Activating relay endpoint...");
5045
5487
  try {
5046
5488
  const actions2 = parseJsonArg3(options.actions, "--actions");
5047
5489
  const body = { actions: actions2 };
@@ -5051,21 +5493,21 @@ async function relayActivateCommand(id, options) {
5051
5493
  json(result);
5052
5494
  return;
5053
5495
  }
5054
- spinner5.stop("Relay endpoint activated");
5055
- console.log(` ${pc9.dim("ID:")} ${result.id}`);
5056
- console.log(` ${pc9.dim("Active:")} ${result.active}`);
5057
- console.log(` ${pc9.dim("Actions:")} ${result.actions?.length || 0}`);
5496
+ spinner4.stop("Relay endpoint activated");
5497
+ console.log(` ${pc10.dim("ID:")} ${result.id}`);
5498
+ console.log(` ${pc10.dim("Active:")} ${result.active}`);
5499
+ console.log(` ${pc10.dim("Actions:")} ${result.actions?.length || 0}`);
5058
5500
  console.log();
5059
5501
  } catch (error2) {
5060
- spinner5.stop("Failed to activate relay endpoint");
5502
+ spinner4.stop("Failed to activate relay endpoint");
5061
5503
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5062
5504
  }
5063
5505
  }
5064
5506
  async function relayEventsCommand(options) {
5065
5507
  const { apiKey } = getConfig3();
5066
5508
  const api = new OneApi(apiKey, getApiBase());
5067
- const spinner5 = createSpinner();
5068
- spinner5.start("Loading relay events...");
5509
+ const spinner4 = createSpinner();
5510
+ spinner4.start("Loading relay events...");
5069
5511
  try {
5070
5512
  const query = {};
5071
5513
  if (options.limit) query.limit = options.limit;
@@ -5089,7 +5531,7 @@ async function relayEventsCommand(options) {
5089
5531
  });
5090
5532
  return;
5091
5533
  }
5092
- spinner5.stop(`${events.length} event${events.length === 1 ? "" : "s"} found`);
5534
+ spinner4.stop(`${events.length} event${events.length === 1 ? "" : "s"} found`);
5093
5535
  if (events.length === 0) {
5094
5536
  console.log("\n No events found.\n");
5095
5537
  return;
@@ -5099,42 +5541,42 @@ async function relayEventsCommand(options) {
5099
5541
  { key: "platform", label: "Platform" },
5100
5542
  { key: "eventType", label: "Event Type" },
5101
5543
  { key: "timestamp", label: "Timestamp" },
5102
- { key: "id", label: "ID", color: pc9.dim }
5544
+ { key: "id", label: "ID", color: pc10.dim }
5103
5545
  ],
5104
5546
  events.map((e) => ({
5105
5547
  platform: e.platform,
5106
- eventType: e.eventType || pc9.dim("unknown"),
5548
+ eventType: e.eventType || pc10.dim("unknown"),
5107
5549
  timestamp: e.timestamp || e.createdAt,
5108
5550
  id: e.id.slice(0, 8)
5109
5551
  }))
5110
5552
  );
5111
5553
  } catch (error2) {
5112
- spinner5.stop("Failed to list relay events");
5554
+ spinner4.stop("Failed to list relay events");
5113
5555
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5114
5556
  }
5115
5557
  }
5116
5558
  async function relayEventGetCommand(id) {
5117
5559
  const { apiKey } = getConfig3();
5118
5560
  const api = new OneApi(apiKey, getApiBase());
5119
- const spinner5 = createSpinner();
5120
- spinner5.start("Loading relay event...");
5561
+ const spinner4 = createSpinner();
5562
+ spinner4.start("Loading relay event...");
5121
5563
  try {
5122
5564
  const result = await api.getRelayEvent(id);
5123
5565
  if (isAgentMode()) {
5124
5566
  json(result);
5125
5567
  return;
5126
5568
  }
5127
- spinner5.stop("Relay event loaded");
5569
+ spinner4.stop("Relay event loaded");
5128
5570
  console.log();
5129
- console.log(` ${pc9.dim("ID:")} ${result.id}`);
5130
- console.log(` ${pc9.dim("Platform:")} ${result.platform}`);
5131
- console.log(` ${pc9.dim("Event:")} ${result.eventType}`);
5132
- console.log(` ${pc9.dim("Timestamp:")} ${result.timestamp || result.createdAt}`);
5133
- console.log(` ${pc9.dim("Payload:")}`);
5571
+ console.log(` ${pc10.dim("ID:")} ${result.id}`);
5572
+ console.log(` ${pc10.dim("Platform:")} ${result.platform}`);
5573
+ console.log(` ${pc10.dim("Event:")} ${result.eventType}`);
5574
+ console.log(` ${pc10.dim("Timestamp:")} ${result.timestamp || result.createdAt}`);
5575
+ console.log(` ${pc10.dim("Payload:")}`);
5134
5576
  console.log(JSON.stringify(result.payload, null, 2));
5135
5577
  console.log();
5136
5578
  } catch (error2) {
5137
- spinner5.stop("Failed to load relay event");
5579
+ spinner4.stop("Failed to load relay event");
5138
5580
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5139
5581
  }
5140
5582
  }
@@ -5144,8 +5586,8 @@ async function relayDeliveriesCommand(options) {
5144
5586
  }
5145
5587
  const { apiKey } = getConfig3();
5146
5588
  const api = new OneApi(apiKey, getApiBase());
5147
- const spinner5 = createSpinner();
5148
- spinner5.start("Loading deliveries...");
5589
+ const spinner4 = createSpinner();
5590
+ spinner4.start("Loading deliveries...");
5149
5591
  try {
5150
5592
  const deliveries = options.endpointId ? await api.listRelayEndpointDeliveries(options.endpointId) : await api.listRelayEventDeliveries(options.eventId);
5151
5593
  const items = Array.isArray(deliveries) ? deliveries : deliveries.rows || [];
@@ -5153,7 +5595,7 @@ async function relayDeliveriesCommand(options) {
5153
5595
  json({ deliveries: items });
5154
5596
  return;
5155
5597
  }
5156
- spinner5.stop(`${items.length} deliver${items.length === 1 ? "y" : "ies"} found`);
5598
+ spinner4.stop(`${items.length} deliver${items.length === 1 ? "y" : "ies"} found`);
5157
5599
  if (items.length === 0) {
5158
5600
  console.log("\n No deliveries found.\n");
5159
5601
  return;
@@ -5167,30 +5609,30 @@ async function relayDeliveriesCommand(options) {
5167
5609
  { key: "error", label: "Error" }
5168
5610
  ],
5169
5611
  items.map((d) => ({
5170
- status: d.status === "success" ? pc9.green(d.status) : pc9.red(d.status),
5171
- code: d.statusCode != null ? String(d.statusCode) : pc9.dim("-"),
5612
+ status: d.status === "success" ? pc10.green(d.status) : pc10.red(d.status),
5613
+ code: d.statusCode != null ? String(d.statusCode) : pc10.dim("-"),
5172
5614
  attempt: String(d.attempt),
5173
- deliveredAt: d.deliveredAt || pc9.dim("-"),
5174
- error: d.error ? pc9.red(d.error.slice(0, 50)) : pc9.dim("-")
5615
+ deliveredAt: d.deliveredAt || pc10.dim("-"),
5616
+ error: d.error ? pc10.red(d.error.slice(0, 50)) : pc10.dim("-")
5175
5617
  }))
5176
5618
  );
5177
5619
  } catch (error2) {
5178
- spinner5.stop("Failed to load deliveries");
5620
+ spinner4.stop("Failed to load deliveries");
5179
5621
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5180
5622
  }
5181
5623
  }
5182
5624
  async function relayPlatformsCommand() {
5183
5625
  const { apiKey } = getConfig3();
5184
5626
  const api = new OneApi(apiKey, getApiBase());
5185
- const spinner5 = createSpinner();
5186
- spinner5.start("Loading relay-capable platforms...");
5627
+ const spinner4 = createSpinner();
5628
+ spinner4.start("Loading relay-capable platforms...");
5187
5629
  try {
5188
5630
  const platforms = await api.listRelayPlatforms();
5189
5631
  if (isAgentMode()) {
5190
5632
  json({ platforms });
5191
5633
  return;
5192
5634
  }
5193
- spinner5.stop(`${platforms.length} relay-capable platform${platforms.length === 1 ? "" : "s"} found`);
5635
+ spinner4.stop(`${platforms.length} relay-capable platform${platforms.length === 1 ? "" : "s"} found`);
5194
5636
  if (platforms.length === 0) {
5195
5637
  console.log("\n No relay-capable platforms available.\n");
5196
5638
  return;
@@ -5199,34 +5641,34 @@ async function relayPlatformsCommand() {
5199
5641
  printTable(
5200
5642
  [
5201
5643
  { key: "platform", label: "Platform" },
5202
- { key: "eventTypeCount", label: "Event types", color: pc9.dim }
5644
+ { key: "eventTypeCount", label: "Event types", color: pc10.dim }
5203
5645
  ],
5204
5646
  platforms.map((p10) => ({ platform: p10.platform, eventTypeCount: String(p10.eventTypeCount) }))
5205
5647
  );
5206
5648
  console.log();
5207
5649
  console.log(
5208
- pc9.dim(
5209
- ` Run ${pc9.cyan("one relay event-types <platform>")} to see the full event list for a platform.
5650
+ pc10.dim(
5651
+ ` Run ${pc10.cyan("one relay event-types <platform>")} to see the full event list for a platform.
5210
5652
  `
5211
5653
  )
5212
5654
  );
5213
5655
  } catch (error2) {
5214
- spinner5.stop("Failed to load relay platforms");
5656
+ spinner4.stop("Failed to load relay platforms");
5215
5657
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5216
5658
  }
5217
5659
  }
5218
5660
  async function relayEventTypesCommand(platform) {
5219
5661
  const { apiKey } = getConfig3();
5220
5662
  const api = new OneApi(apiKey, getApiBase());
5221
- const spinner5 = createSpinner();
5222
- spinner5.start(`Loading event types for ${pc9.cyan(platform)}...`);
5663
+ const spinner4 = createSpinner();
5664
+ spinner4.start(`Loading event types for ${pc10.cyan(platform)}...`);
5223
5665
  try {
5224
5666
  const eventTypes = await api.listRelayEventTypes(platform);
5225
5667
  if (isAgentMode()) {
5226
5668
  json({ platform, eventTypes });
5227
5669
  return;
5228
5670
  }
5229
- spinner5.stop(`${eventTypes.length} event type${eventTypes.length === 1 ? "" : "s"} found`);
5671
+ spinner4.stop(`${eventTypes.length} event type${eventTypes.length === 1 ? "" : "s"} found`);
5230
5672
  if (eventTypes.length === 0) {
5231
5673
  console.log(`
5232
5674
  No event types found for ${platform}.
@@ -5239,7 +5681,7 @@ async function relayEventTypesCommand(platform) {
5239
5681
  }
5240
5682
  console.log();
5241
5683
  } catch (error2) {
5242
- spinner5.stop("Failed to load event types");
5684
+ spinner4.stop("Failed to load event types");
5243
5685
  error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5244
5686
  }
5245
5687
  }
@@ -5365,11 +5807,11 @@ function handleId(response, config2, records) {
5365
5807
  }
5366
5808
 
5367
5809
  // src/lib/memory/sync/state.ts
5368
- import fs6 from "fs";
5369
- import path7 from "path";
5370
- var SYNC_DIR = path7.join(".one", "sync");
5371
- var STATE_DIR = path7.join(SYNC_DIR, "state");
5372
- var LEGACY_SINGLE_FILE = path7.join(SYNC_DIR, "sync_state.json");
5810
+ import fs7 from "fs";
5811
+ import path8 from "path";
5812
+ var SYNC_DIR = path8.join(".one", "sync");
5813
+ var STATE_DIR = path8.join(SYNC_DIR, "state");
5814
+ var LEGACY_SINGLE_FILE = path8.join(SYNC_DIR, "sync_state.json");
5373
5815
  var legacyMigrationDone = false;
5374
5816
  function rowToState(row) {
5375
5817
  return {
@@ -5397,9 +5839,9 @@ function stateToRow(platform, model, state, lastError) {
5397
5839
  async function migrateLegacyOnce() {
5398
5840
  if (legacyMigrationDone) return;
5399
5841
  legacyMigrationDone = true;
5400
- if (fs6.existsSync(LEGACY_SINGLE_FILE)) {
5842
+ if (fs7.existsSync(LEGACY_SINGLE_FILE)) {
5401
5843
  try {
5402
- const raw = fs6.readFileSync(LEGACY_SINGLE_FILE, "utf-8");
5844
+ const raw = fs7.readFileSync(LEGACY_SINGLE_FILE, "utf-8");
5403
5845
  const legacy = JSON.parse(raw);
5404
5846
  const backend = await getBackend();
5405
5847
  for (const [platform, models] of Object.entries(legacy)) {
@@ -5409,32 +5851,32 @@ async function migrateLegacyOnce() {
5409
5851
  await backend.setSyncState(stateToRow(platform, model, modelState));
5410
5852
  }
5411
5853
  }
5412
- fs6.unlinkSync(LEGACY_SINGLE_FILE);
5854
+ fs7.unlinkSync(LEGACY_SINGLE_FILE);
5413
5855
  } catch {
5414
5856
  try {
5415
- fs6.unlinkSync(LEGACY_SINGLE_FILE);
5857
+ fs7.unlinkSync(LEGACY_SINGLE_FILE);
5416
5858
  } catch {
5417
5859
  }
5418
5860
  }
5419
5861
  }
5420
- if (fs6.existsSync(STATE_DIR)) {
5862
+ if (fs7.existsSync(STATE_DIR)) {
5421
5863
  try {
5422
5864
  const backend = await getBackend();
5423
- const platforms = fs6.readdirSync(STATE_DIR);
5865
+ const platforms = fs7.readdirSync(STATE_DIR);
5424
5866
  for (const platform of platforms) {
5425
- const platformDir = path7.join(STATE_DIR, platform);
5867
+ const platformDir = path8.join(STATE_DIR, platform);
5426
5868
  let entries;
5427
5869
  try {
5428
- entries = fs6.readdirSync(platformDir);
5870
+ entries = fs7.readdirSync(platformDir);
5429
5871
  } catch {
5430
5872
  continue;
5431
5873
  }
5432
5874
  for (const entry of entries) {
5433
5875
  if (!entry.endsWith(".json")) continue;
5434
5876
  const model = entry.slice(0, -".json".length);
5435
- const filePath = path7.join(platformDir, entry);
5877
+ const filePath = path8.join(platformDir, entry);
5436
5878
  try {
5437
- const raw = fs6.readFileSync(filePath, "utf-8");
5879
+ const raw = fs7.readFileSync(filePath, "utf-8");
5438
5880
  const modelState = JSON.parse(raw);
5439
5881
  const existing = await backend.getSyncState(platform, model);
5440
5882
  if (!existing) {
@@ -5444,7 +5886,7 @@ async function migrateLegacyOnce() {
5444
5886
  }
5445
5887
  }
5446
5888
  }
5447
- fs6.rmSync(STATE_DIR, { recursive: true, force: true });
5889
+ fs7.rmSync(STATE_DIR, { recursive: true, force: true });
5448
5890
  } catch {
5449
5891
  }
5450
5892
  }
@@ -5488,12 +5930,12 @@ async function removeModelState(platform, model) {
5488
5930
  }
5489
5931
 
5490
5932
  // src/lib/memory/sync/lock.ts
5491
- import fs7 from "fs";
5492
- import path8 from "path";
5493
- var LOCK_DIR_REL = path8.join(".one", "sync", "locks");
5933
+ import fs8 from "fs";
5934
+ import path9 from "path";
5935
+ var LOCK_DIR_REL = path9.join(".one", "sync", "locks");
5494
5936
  var STALE_MS = 30 * 60 * 1e3;
5495
5937
  function lockPath(platform, model) {
5496
- return path8.join(LOCK_DIR_REL, `${platform}_${model}`);
5938
+ return path9.join(LOCK_DIR_REL, `${platform}_${model}`);
5497
5939
  }
5498
5940
  function isProcessAlive(pid) {
5499
5941
  try {
@@ -5510,15 +5952,15 @@ var SyncLockError = class extends Error {
5510
5952
  }
5511
5953
  };
5512
5954
  function acquireSyncLock(platform, model) {
5513
- fs7.mkdirSync(LOCK_DIR_REL, { recursive: true });
5955
+ fs8.mkdirSync(LOCK_DIR_REL, { recursive: true });
5514
5956
  const dir = lockPath(platform, model);
5515
- const pidFile = path8.join(dir, "pid");
5957
+ const pidFile = path9.join(dir, "pid");
5516
5958
  try {
5517
- fs7.mkdirSync(dir);
5959
+ fs8.mkdirSync(dir);
5518
5960
  } catch (err) {
5519
5961
  const stat = (() => {
5520
5962
  try {
5521
- return fs7.statSync(dir);
5963
+ return fs8.statSync(dir);
5522
5964
  } catch {
5523
5965
  return null;
5524
5966
  }
@@ -5527,7 +5969,7 @@ function acquireSyncLock(platform, model) {
5527
5969
  const age = Date.now() - stat.mtimeMs;
5528
5970
  let ownerPid = null;
5529
5971
  try {
5530
- const raw = fs7.readFileSync(pidFile, "utf-8");
5972
+ const raw = fs8.readFileSync(pidFile, "utf-8");
5531
5973
  const parsed = parseInt(raw.trim(), 10);
5532
5974
  if (!isNaN(parsed)) ownerPid = parsed;
5533
5975
  } catch {
@@ -5536,8 +5978,8 @@ function acquireSyncLock(platform, model) {
5536
5978
  const veryOld = age > STALE_MS;
5537
5979
  if (ownerDead || veryOld) {
5538
5980
  try {
5539
- fs7.rmSync(dir, { recursive: true, force: true });
5540
- fs7.mkdirSync(dir);
5981
+ fs8.rmSync(dir, { recursive: true, force: true });
5982
+ fs8.mkdirSync(dir);
5541
5983
  } catch {
5542
5984
  throw new SyncLockError(
5543
5985
  `Could not take over stale lock at ${dir}. Remove it manually if no sync is running.`
@@ -5554,13 +5996,13 @@ function acquireSyncLock(platform, model) {
5554
5996
  }
5555
5997
  }
5556
5998
  try {
5557
- fs7.writeFileSync(pidFile, String(process.pid));
5999
+ fs8.writeFileSync(pidFile, String(process.pid));
5558
6000
  } catch {
5559
6001
  }
5560
6002
  return {
5561
6003
  release() {
5562
6004
  try {
5563
- fs7.rmSync(dir, { recursive: true, force: true });
6005
+ fs8.rmSync(dir, { recursive: true, force: true });
5564
6006
  } catch {
5565
6007
  }
5566
6008
  }
@@ -5569,9 +6011,9 @@ function acquireSyncLock(platform, model) {
5569
6011
 
5570
6012
  // src/lib/memory/sync/hooks.ts
5571
6013
  import { spawn as spawn2 } from "child_process";
5572
- import fs8 from "fs";
5573
- import path9 from "path";
5574
- var EVENTS_DIR = path9.join(".one", "sync", "events");
6014
+ import fs9 from "fs";
6015
+ import path10 from "path";
6016
+ var EVENTS_DIR = path10.join(".one", "sync", "events");
5575
6017
  function classifyRecords(db, model, records, idField, tableExists2) {
5576
6018
  if (!tableExists2 || records.length === 0) {
5577
6019
  return { inserts: records, updates: [] };
@@ -5617,10 +6059,10 @@ async function fireHooks(hookCommand, events) {
5617
6059
  function appendEventLog(events) {
5618
6060
  if (events.length === 0) return;
5619
6061
  const { platform, model } = events[0];
5620
- fs8.mkdirSync(EVENTS_DIR, { recursive: true });
5621
- const logPath = path9.join(EVENTS_DIR, `${platform}_${model}.jsonl`);
6062
+ fs9.mkdirSync(EVENTS_DIR, { recursive: true });
6063
+ const logPath = path10.join(EVENTS_DIR, `${platform}_${model}.jsonl`);
5622
6064
  const lines = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
5623
- fs8.appendFileSync(logPath, lines);
6065
+ fs9.appendFileSync(logPath, lines);
5624
6066
  }
5625
6067
  function runShellHook(command, events) {
5626
6068
  return new Promise((resolve) => {
@@ -5724,8 +6166,8 @@ function sleep(ms) {
5724
6166
  return new Promise((resolve) => setTimeout(resolve, ms));
5725
6167
  }
5726
6168
  function interpolate(template, record) {
5727
- return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_, path13) => {
5728
- const parts = path13.split(".");
6169
+ return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_, path14) => {
6170
+ const parts = path14.split(".");
5729
6171
  let value = record;
5730
6172
  for (const part of parts) {
5731
6173
  if (typeof value !== "object" || value === null) return "";
@@ -5753,8 +6195,8 @@ function deepMerge(target, source) {
5753
6195
  }
5754
6196
  return result;
5755
6197
  }
5756
- function getByDotPath2(obj, path13) {
5757
- const parts = path13.split(".");
6198
+ function getByDotPath2(obj, path14) {
6199
+ const parts = path14.split(".");
5758
6200
  let current = obj;
5759
6201
  for (const part of parts) {
5760
6202
  if (current === null || current === void 0 || typeof current !== "object") return void 0;
@@ -5763,8 +6205,8 @@ function getByDotPath2(obj, path13) {
5763
6205
  return current;
5764
6206
  }
5765
6207
  function stripExcludedFields(obj, paths) {
5766
- for (const path13 of paths) {
5767
- stripOnePath(obj, path13.replace(/\[\]/g, ".*").split("."));
6208
+ for (const path14 of paths) {
6209
+ stripOnePath(obj, path14.replace(/\[\]/g, ".*").split("."));
5768
6210
  }
5769
6211
  }
5770
6212
  function stripOnePath(obj, parts) {
@@ -6185,8 +6627,8 @@ function sleep2(ms) {
6185
6627
  return new Promise((resolve) => setTimeout(resolve, ms));
6186
6628
  }
6187
6629
  function stripFields(record, paths) {
6188
- for (const path13 of paths) {
6189
- stripOnePath2(record, path13.split("."));
6630
+ for (const path14 of paths) {
6631
+ stripOnePath2(record, path14.split("."));
6190
6632
  }
6191
6633
  }
6192
6634
  function stripOnePath2(obj, parts) {
@@ -6276,7 +6718,7 @@ async function syncModel(api, profile, options) {
6276
6718
  updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor }),
6277
6719
  (async () => {
6278
6720
  try {
6279
- const { getBackend: getBackend2 } = await import("./runtime-AFXLC4IC.js");
6721
+ const { getBackend: getBackend2 } = await import("./runtime-65IPTPVD.js");
6280
6722
  const backend = await getBackend2();
6281
6723
  await Promise.race([
6282
6724
  backend.close(),
@@ -6642,7 +7084,7 @@ async function syncModel(api, profile, options) {
6642
7084
  db.exec(`DROP TABLE IF EXISTS _seen_ids`);
6643
7085
  }
6644
7086
  if (options.toMemory !== false) {
6645
- const backend = await (await import("./runtime-AFXLC4IC.js")).getBackend();
7087
+ const backend = await (await import("./runtime-65IPTPVD.js")).getBackend();
6646
7088
  const type = `${platform}/${model}`;
6647
7089
  const existing = await backend.listKeysByType(type);
6648
7090
  const sourcePrefix = `${type}:`;
@@ -6743,7 +7185,7 @@ async function syncModel(api, profile, options) {
6743
7185
  let statusCounts;
6744
7186
  if (options.toMemory !== false) {
6745
7187
  try {
6746
- const backend = await (await import("./runtime-AFXLC4IC.js")).getBackend();
7188
+ const backend = await (await import("./runtime-65IPTPVD.js")).getBackend();
6747
7189
  const typeName = `${platform}/${model}`;
6748
7190
  const [active, archived] = await Promise.all([
6749
7191
  backend.count(typeName, { status: "active" }),
@@ -7279,19 +7721,19 @@ function inferProfileFromKnowledge(knowledge, modelName, platform) {
7279
7721
 
7280
7722
  // src/lib/memory/sync/schedule.ts
7281
7723
  import { spawnSync as spawnSync2 } from "child_process";
7282
- import fs10 from "fs";
7283
- import os from "os";
7284
- import path11 from "path";
7724
+ import fs11 from "fs";
7725
+ import os2 from "os";
7726
+ import path12 from "path";
7285
7727
 
7286
7728
  // src/lib/memory/sync/schedule-registry.ts
7287
- import fs9 from "fs";
7288
- import path10 from "path";
7289
- var REGISTRY_DIR = () => path10.join(homeDir(), ".one", "sync");
7290
- var REGISTRY_FILE = () => path10.join(REGISTRY_DIR(), "schedules.json");
7729
+ import fs10 from "fs";
7730
+ import path11 from "path";
7731
+ var REGISTRY_DIR = () => path11.join(homeDir(), ".one", "sync");
7732
+ var REGISTRY_FILE = () => path11.join(REGISTRY_DIR(), "schedules.json");
7291
7733
  function readRaw() {
7292
7734
  try {
7293
- if (!fs9.existsSync(REGISTRY_FILE())) return { schedules: [] };
7294
- const raw = fs9.readFileSync(REGISTRY_FILE(), "utf-8");
7735
+ if (!fs10.existsSync(REGISTRY_FILE())) return { schedules: [] };
7736
+ const raw = fs10.readFileSync(REGISTRY_FILE(), "utf-8");
7295
7737
  const parsed = JSON.parse(raw);
7296
7738
  if (!parsed || !Array.isArray(parsed.schedules)) return { schedules: [] };
7297
7739
  return parsed;
@@ -7300,13 +7742,13 @@ function readRaw() {
7300
7742
  }
7301
7743
  }
7302
7744
  function writeRaw(file) {
7303
- fs9.mkdirSync(REGISTRY_DIR(), { recursive: true });
7745
+ fs10.mkdirSync(REGISTRY_DIR(), { recursive: true });
7304
7746
  const tmp = REGISTRY_FILE() + ".tmp";
7305
- fs9.writeFileSync(tmp, JSON.stringify(file, null, 2));
7306
- fs9.renameSync(tmp, REGISTRY_FILE());
7747
+ fs10.writeFileSync(tmp, JSON.stringify(file, null, 2));
7748
+ fs10.renameSync(tmp, REGISTRY_FILE());
7307
7749
  }
7308
7750
  function makeScheduleId(platform, cwd) {
7309
- const slug = path10.basename(cwd).replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
7751
+ const slug = path11.basename(cwd).replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
7310
7752
  return `${platform}-${slug}`;
7311
7753
  }
7312
7754
  function listRegistered() {
@@ -7340,7 +7782,7 @@ function removeRegistered(id) {
7340
7782
 
7341
7783
  // src/lib/memory/sync/schedule.ts
7342
7784
  var MARKER = "# one-sync";
7343
- var LOG_DIR_REL = path11.join(".one", "sync", "logs");
7785
+ var LOG_DIR_REL = path12.join(".one", "sync", "logs");
7344
7786
  function durationToCron(every) {
7345
7787
  const match = every.match(/^(\d+)([mhd])$/);
7346
7788
  if (!match) return null;
@@ -7373,13 +7815,13 @@ function cronExprToDuration(expr) {
7373
7815
  return null;
7374
7816
  }
7375
7817
  function isWindows() {
7376
- return os.platform() === "win32";
7818
+ return os2.platform() === "win32";
7377
7819
  }
7378
7820
  function resolveOneBinary() {
7379
7821
  try {
7380
7822
  const entry = process.argv[1];
7381
- if (entry && fs10.existsSync(entry)) {
7382
- return fs10.realpathSync(entry);
7823
+ if (entry && fs11.existsSync(entry)) {
7824
+ return fs11.realpathSync(entry);
7383
7825
  }
7384
7826
  } catch {
7385
7827
  }
@@ -7457,7 +7899,7 @@ function migrateLegacyCronEntries() {
7457
7899
  const modelsMatch = command.match(/--models\s+(\S+)/);
7458
7900
  const models = modelsMatch ? modelsMatch[1].split(",") : void 0;
7459
7901
  const logMatch = command.match(/>>\s+"([^"]+)"/);
7460
- const logFile = logMatch ? logMatch[1] : path11.resolve(cwd, LOG_DIR_REL, `${platform}.log`);
7902
+ const logFile = logMatch ? logMatch[1] : path12.resolve(cwd, LOG_DIR_REL, `${platform}.log`);
7461
7903
  const id = makeScheduleId(platform, cwd);
7462
7904
  if (registeredIds.has(id)) continue;
7463
7905
  upsertRegistered({
@@ -7491,9 +7933,9 @@ function addSchedule(opts) {
7491
7933
  const cwd = process.cwd();
7492
7934
  const id = makeScheduleId(opts.platform, cwd);
7493
7935
  const replaced = getRegistered(id) !== void 0;
7494
- const logDir = path11.join(cwd, LOG_DIR_REL);
7495
- fs10.mkdirSync(logDir, { recursive: true });
7496
- const logFile = path11.join(logDir, `${opts.platform}.log`);
7936
+ const logDir = path12.join(cwd, LOG_DIR_REL);
7937
+ fs11.mkdirSync(logDir, { recursive: true });
7938
+ const logFile = path12.join(logDir, `${opts.platform}.log`);
7497
7939
  const entry = {
7498
7940
  id,
7499
7941
  platform: opts.platform,
@@ -7547,15 +7989,15 @@ function removeSchedule(idOrPlatform, options) {
7547
7989
  function scheduleStatus() {
7548
7990
  const entries = listSchedules();
7549
7991
  return entries.map((entry) => {
7550
- const logExists = fs10.existsSync(entry.logFile);
7551
- const logSize = logExists ? fs10.statSync(entry.logFile).size : 0;
7992
+ const logExists = fs11.existsSync(entry.logFile);
7993
+ const logSize = logExists ? fs11.statSync(entry.logFile).size : 0;
7552
7994
  let logTail = [];
7553
7995
  let lastRunAt = null;
7554
7996
  if (logExists) {
7555
7997
  try {
7556
- lastRunAt = fs10.statSync(entry.logFile).mtime.toISOString();
7998
+ lastRunAt = fs11.statSync(entry.logFile).mtime.toISOString();
7557
7999
  if (logSize > 0) {
7558
- const content = fs10.readFileSync(entry.logFile, "utf-8");
8000
+ const content = fs11.readFileSync(entry.logFile, "utf-8");
7559
8001
  logTail = content.trim().split("\n").slice(-10);
7560
8002
  }
7561
8003
  } catch {
@@ -7563,8 +8005,8 @@ function scheduleStatus() {
7563
8005
  }
7564
8006
  let drift = "ok";
7565
8007
  if (!entry.cronInstalled) drift = "missing-cron";
7566
- else if (!fs10.existsSync(entry.nodeBin)) drift = "stale-node-bin";
7567
- else if (!fs10.existsSync(entry.cliBin)) drift = "stale-cli-bin";
8008
+ else if (!fs11.existsSync(entry.nodeBin)) drift = "stale-node-bin";
8009
+ else if (!fs11.existsSync(entry.cliBin)) drift = "stale-cli-bin";
7568
8010
  return { entry, logExists, logSize, logTail, lastRunAt, drift };
7569
8011
  });
7570
8012
  }
@@ -7837,11 +8279,11 @@ function isNoise(s) {
7837
8279
  if (/^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(s)) return true;
7838
8280
  return false;
7839
8281
  }
7840
- function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
7841
- let s = stats.get(path13);
8282
+ function recordSample(stats, path14, value, jsType, recordIndex, totalSamples) {
8283
+ let s = stats.get(path14);
7842
8284
  if (!s) {
7843
8285
  s = {
7844
- path: path13,
8286
+ path: path14,
7845
8287
  total: totalSamples,
7846
8288
  recordIndices: /* @__PURE__ */ new Set(),
7847
8289
  lenSum: 0,
@@ -7850,7 +8292,7 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
7850
8292
  primaryType: jsType,
7851
8293
  examples: []
7852
8294
  };
7853
- stats.set(path13, s);
8295
+ stats.set(path14, s);
7854
8296
  }
7855
8297
  s.recordIndices.add(recordIndex);
7856
8298
  s.lenSum += value.length;
@@ -7859,28 +8301,28 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
7859
8301
  if (s.primaryType !== jsType) s.primaryType = "mixed";
7860
8302
  if (s.examples.length < 3 && value.length < 200) s.examples.push(value);
7861
8303
  }
7862
- function walkRecord(record, path13, stats, recordIndex, totalSamples) {
8304
+ function walkRecord(record, path14, stats, recordIndex, totalSamples) {
7863
8305
  if (record === null || record === void 0) return;
7864
8306
  if (typeof record === "string") {
7865
8307
  const trimmed = record.trim();
7866
- if (trimmed) recordSample(stats, path13, trimmed, "string", recordIndex, totalSamples);
8308
+ if (trimmed) recordSample(stats, path14, trimmed, "string", recordIndex, totalSamples);
7867
8309
  return;
7868
8310
  }
7869
8311
  if (typeof record === "number" || typeof record === "boolean") {
7870
8312
  const str = String(record);
7871
8313
  const kind = typeof record === "number" ? "number" : "boolean";
7872
- if (str) recordSample(stats, path13, str, kind, recordIndex, totalSamples);
8314
+ if (str) recordSample(stats, path14, str, kind, recordIndex, totalSamples);
7873
8315
  return;
7874
8316
  }
7875
8317
  if (Array.isArray(record)) {
7876
- const childPath = path13 ? `${path13}[]` : "[]";
8318
+ const childPath = path14 ? `${path14}[]` : "[]";
7877
8319
  for (const item of record) walkRecord(item, childPath, stats, recordIndex, totalSamples);
7878
8320
  return;
7879
8321
  }
7880
8322
  if (typeof record === "object") {
7881
8323
  for (const [key, value] of Object.entries(record)) {
7882
8324
  if (key.startsWith("_")) continue;
7883
- const childPath = path13 ? `${path13}.${key}` : key;
8325
+ const childPath = path14 ? `${path14}.${key}` : key;
7884
8326
  walkRecord(value, childPath, stats, recordIndex, totalSamples);
7885
8327
  }
7886
8328
  }
@@ -7918,7 +8360,7 @@ function suggestSearchablePaths(records, limit = 15) {
7918
8360
  // src/lib/memory/sync/index.ts
7919
8361
  import { spawn as spawn4 } from "child_process";
7920
8362
  import * as p7 from "@clack/prompts";
7921
- import pc10 from "picocolors";
8363
+ import pc11 from "picocolors";
7922
8364
  async function syncInstallCommand() {
7923
8365
  if (await isSqliteAvailable()) {
7924
8366
  if (isAgentMode()) {
@@ -7983,15 +8425,15 @@ async function syncDoctorCommand() {
7983
8425
  return;
7984
8426
  }
7985
8427
  for (const c of checks) {
7986
- const mark = c.ok ? pc10.green("\u2713") : pc10.red("\u2717");
7987
- console.log(` ${mark} ${c.name}${c.detail ? pc10.dim(` \u2014 ${c.detail}`) : ""}`);
8428
+ const mark = c.ok ? pc11.green("\u2713") : pc11.red("\u2717");
8429
+ console.log(` ${mark} ${c.name}${c.detail ? pc11.dim(` \u2014 ${c.detail}`) : ""}`);
7988
8430
  }
7989
8431
  if (!allOk) {
7990
8432
  console.log(`
7991
- ${pc10.yellow("Sync is not ready.")} Try: ${pc10.bold("one sync install")}`);
8433
+ ${pc11.yellow("Sync is not ready.")} Try: ${pc11.bold("one sync install")}`);
7992
8434
  } else {
7993
8435
  console.log(`
7994
- ${pc10.green("Sync is ready.")}`);
8436
+ ${pc11.green("Sync is ready.")}`);
7995
8437
  }
7996
8438
  }
7997
8439
  function getApi() {
@@ -8034,19 +8476,19 @@ async function syncProfilesCommand(platform) {
8034
8476
  if (p10.enrich) extras.push("enrich");
8035
8477
  if (p10.identityKey || p10.identityKeys) extras.push("identity");
8036
8478
  if (p10.dateFilter) extras.push("incremental");
8037
- const tags = extras.length > 0 ? ` ${pc10.dim(`[${extras.join(", ")}]`)}` : "";
8038
- console.log(` ${pc10.bold(`${p10.platform}/${p10.model}`.padEnd(35))} ${p10.description}${tags}`);
8479
+ const tags = extras.length > 0 ? ` ${pc11.dim(`[${extras.join(", ")}]`)}` : "";
8480
+ console.log(` ${pc11.bold(`${p10.platform}/${p10.model}`.padEnd(35))} ${p10.description}${tags}`);
8039
8481
  }
8040
8482
  console.log(`
8041
- ${profiles.length} built-in profile(s). Run ${pc10.bold("one sync init <platform> <model>")} to use one.`);
8483
+ ${profiles.length} built-in profile(s). Run ${pc11.bold("one sync init <platform> <model>")} to use one.`);
8042
8484
  }
8043
8485
  async function syncModelsCommand(platform) {
8044
8486
  const api = getApi();
8045
- const spinner5 = createSpinner();
8046
- spinner5.start(`Discovering models for ${platform}...`);
8487
+ const spinner4 = createSpinner();
8488
+ spinner4.start(`Discovering models for ${platform}...`);
8047
8489
  try {
8048
8490
  const models = await discoverModels(api, platform);
8049
- spinner5.stop(`Found ${models.length} models`);
8491
+ spinner4.stop(`Found ${models.length} models`);
8050
8492
  if (isAgentMode()) {
8051
8493
  json({ platform, models, total: models.length });
8052
8494
  return;
@@ -8056,19 +8498,19 @@ async function syncModelsCommand(platform) {
8056
8498
  return;
8057
8499
  }
8058
8500
  const lines = models.map(
8059
- (m) => ` ${pc10.bold(m.name.padEnd(30))} ${pc10.dim(m.listAction.method)} ${pc10.dim(m.listAction.path)}`
8501
+ (m) => ` ${pc11.bold(m.name.padEnd(30))} ${pc11.dim(m.listAction.method)} ${pc11.dim(m.listAction.path)}`
8060
8502
  );
8061
8503
  note(lines.join("\n"), `${platform} \u2014 ${models.length} models`);
8062
8504
  } catch (err) {
8063
- spinner5.stop("Failed");
8505
+ spinner4.stop("Failed");
8064
8506
  error(`Error discovering models: ${err instanceof Error ? err.message : String(err)}`);
8065
8507
  }
8066
8508
  }
8067
8509
  async function syncInitCommand(platform, model, options) {
8068
8510
  if (!options.config) {
8069
8511
  const api = getApi();
8070
- const spinner5 = createSpinner();
8071
- spinner5.start(`Looking up ${platform}/${model}...`);
8512
+ const spinner4 = createSpinner();
8513
+ spinner4.start(`Looking up ${platform}/${model}...`);
8072
8514
  try {
8073
8515
  const models = await discoverModels(api, platform);
8074
8516
  const match = models.find((m) => m.name === model || m.name.toLowerCase() === model.toLowerCase());
@@ -8078,9 +8520,9 @@ async function syncInitCommand(platform, model, options) {
8078
8520
  if (actionId && !actionId.startsWith("conn_mod_def::")) {
8079
8521
  actionId = void 0;
8080
8522
  }
8081
- spinner5.stop(actionId ? "Found model + action ID" : "Found model (action ID not resolved)");
8523
+ spinner4.stop(actionId ? "Found model + action ID" : "Found model (action ID not resolved)");
8082
8524
  } else {
8083
- spinner5.stop("Model not found in available actions");
8525
+ spinner4.stop("Model not found in available actions");
8084
8526
  }
8085
8527
  const builtin = loadBuiltinProfile(platform, model);
8086
8528
  let template;
@@ -8160,15 +8602,15 @@ async function syncInitCommand(platform, model, options) {
8160
8602
  note(JSON.stringify(template, null, 2), "Sync profile template");
8161
8603
  if (inferred && inferred.reasoning.length > 0) {
8162
8604
  console.log(`
8163
- ${pc10.bold("Inferred from knowledge:")}`);
8164
- for (const r of inferred.reasoning) console.log(` ${pc10.dim("\u2022")} ${r}`);
8605
+ ${pc11.bold("Inferred from knowledge:")}`);
8606
+ for (const r of inferred.reasoning) console.log(` ${pc11.dim("\u2022")} ${r}`);
8165
8607
  }
8166
8608
  if (testReport) {
8167
8609
  console.log(`
8168
- ${pc10.bold("Test results:")}`);
8610
+ ${pc11.bold("Test results:")}`);
8169
8611
  for (const c of testReport.checks) {
8170
- const mark = c.ok ? pc10.green("\u2713") : pc10.red("\u2717");
8171
- console.log(` ${mark} ${c.name}${c.detail ? pc10.dim(` \u2014 ${c.detail}`) : ""}`);
8612
+ const mark = c.ok ? pc11.green("\u2713") : pc11.red("\u2717");
8613
+ console.log(` ${mark} ${c.name}${c.detail ? pc11.dim(` \u2014 ${c.detail}`) : ""}`);
8172
8614
  }
8173
8615
  }
8174
8616
  console.log(`
@@ -8180,7 +8622,7 @@ Run with --config to save:
8180
8622
  }
8181
8623
  }
8182
8624
  } catch (err) {
8183
- spinner5.stop("Failed");
8625
+ spinner4.stop("Failed");
8184
8626
  error(`Error: ${err instanceof Error ? err.message : String(err)}`);
8185
8627
  }
8186
8628
  return;
@@ -8251,17 +8693,17 @@ async function syncTestCommand(platformModel, options = {}) {
8251
8693
  return;
8252
8694
  }
8253
8695
  for (const c of report.checks) {
8254
- const mark = c.ok ? pc10.green("\u2713") : pc10.red("\u2717");
8255
- console.log(` ${mark} ${c.name}${c.detail ? pc10.dim(` \u2014 ${c.detail}`) : ""}`);
8696
+ const mark = c.ok ? pc11.green("\u2713") : pc11.red("\u2717");
8697
+ console.log(` ${mark} ${c.name}${c.detail ? pc11.dim(` \u2014 ${c.detail}`) : ""}`);
8256
8698
  }
8257
8699
  if (report.detectedColumns && report.detectedColumns.length > 0) {
8258
8700
  console.log(`
8259
- ${pc10.bold("Detected columns:")}`);
8701
+ ${pc11.bold("Detected columns:")}`);
8260
8702
  for (const col of report.detectedColumns.slice(0, 20)) {
8261
- console.log(` ${col.name.padEnd(30)} ${pc10.dim(col.type)}`);
8703
+ console.log(` ${col.name.padEnd(30)} ${pc11.dim(col.type)}`);
8262
8704
  }
8263
8705
  if (report.detectedColumns.length > 20) {
8264
- console.log(pc10.dim(` ... and ${report.detectedColumns.length - 20} more`));
8706
+ console.log(pc11.dim(` ... and ${report.detectedColumns.length - 20} more`));
8265
8707
  }
8266
8708
  }
8267
8709
  if (report.identityKeysPreview) {
@@ -8269,45 +8711,45 @@ async function syncTestCommand(platformModel, options = {}) {
8269
8711
  const total = perRecord.reduce((a, b) => a + b, 0);
8270
8712
  const min = perRecord.length ? Math.min(...perRecord) : 0;
8271
8713
  const max = perRecord.length ? Math.max(...perRecord) : 0;
8272
- const mark = total === 0 ? pc10.yellow("~") : pc10.green("\u2713");
8714
+ const mark = total === 0 ? pc11.yellow("~") : pc11.green("\u2713");
8273
8715
  console.log(`
8274
- ${pc10.bold("Merge + identity keys")} ${pc10.dim(`(cross-platform \u2014 #128)`)}`);
8716
+ ${pc11.bold("Merge + identity keys")} ${pc11.dim(`(cross-platform \u2014 #128)`)}`);
8275
8717
  console.log(` ${mark} ${perRecord.length} sample${perRecord.length === 1 ? "" : "s"}, ${min}\u2013${max} key${max === 1 ? "" : "s"} per record`);
8276
8718
  if (sampleKeys.length > 0) {
8277
- console.log(` ${pc10.dim("e.g.")} ${sampleKeys.slice(0, 8).map((k) => pc10.cyan(k)).join(", ")}`);
8719
+ console.log(` ${pc11.dim("e.g.")} ${sampleKeys.slice(0, 8).map((k) => pc11.cyan(k)).join(", ")}`);
8278
8720
  } else if (resolvesAfterEnrich) {
8279
- console.log(` ${pc10.dim("note:")} 0 on these list-shape samples \u2014 this profile enriches, and its identityKeys paths resolve in the enrich phase.`);
8721
+ console.log(` ${pc11.dim("note:")} 0 on these list-shape samples \u2014 this profile enriches, and its identityKeys paths resolve in the enrich phase.`);
8280
8722
  } else {
8281
- console.log(` ${pc10.yellow("note:")} no identity keys resolved on these samples \u2014 check the identityKey/identityKeys paths.`);
8723
+ console.log(` ${pc11.yellow("note:")} no identity keys resolved on these samples \u2014 check the identityKey/identityKeys paths.`);
8282
8724
  }
8283
8725
  if (entityFanOut) {
8284
- console.log(` ${pc10.yellow("warn:")} identityKey resolved to MULTIPLE values on ${entityFanOut.count} of ${perRecord.length} samples \u2014 those records get NO merge key.`);
8285
- console.log(` ${pc10.dim("saw:")} ${entityFanOut.sampleValues.map((v) => pc10.cyan(v)).join(", ")}`);
8286
- console.log(` ${pc10.dim('A singular identityKey means "this record IS this entity", so a fan-out has no safe answer.')}`);
8287
- console.log(` ${pc10.dim("Point it at a single-valued path, or move it to identityKeys[] for participant associations.")}`);
8726
+ console.log(` ${pc11.yellow("warn:")} identityKey resolved to MULTIPLE values on ${entityFanOut.count} of ${perRecord.length} samples \u2014 those records get NO merge key.`);
8727
+ console.log(` ${pc11.dim("saw:")} ${entityFanOut.sampleValues.map((v) => pc11.cyan(v)).join(", ")}`);
8728
+ console.log(` ${pc11.dim('A singular identityKey means "this record IS this entity", so a fan-out has no safe answer.')}`);
8729
+ console.log(` ${pc11.dim("Point it at a single-valued path, or move it to identityKeys[] for participant associations.")}`);
8288
8730
  }
8289
8731
  }
8290
8732
  if (searchablePreview) {
8291
8733
  console.log(`
8292
- ${pc10.bold("Searchable preview")} ${pc10.dim(`(${searchablePreview.mode}, ${searchablePreview.sampledRecords} sample${searchablePreview.sampledRecords === 1 ? "" : "s"})`)}`);
8293
- console.log(` ${pc10.dim("length:")} ${searchablePreview.length} chars (first sample)`);
8294
- console.log(` ${pc10.dim("text:")} ${searchablePreview.text.slice(0, 300)}${searchablePreview.length > 300 ? pc10.dim(" \u2026") : ""}`);
8734
+ ${pc11.bold("Searchable preview")} ${pc11.dim(`(${searchablePreview.mode}, ${searchablePreview.sampledRecords} sample${searchablePreview.sampledRecords === 1 ? "" : "s"})`)}`);
8735
+ console.log(` ${pc11.dim("length:")} ${searchablePreview.length} chars (first sample)`);
8736
+ console.log(` ${pc11.dim("text:")} ${searchablePreview.text.slice(0, 300)}${searchablePreview.length > 300 ? pc11.dim(" \u2026") : ""}`);
8295
8737
  if (searchablePreview.paths) {
8296
- console.log(` ${pc10.dim("paths:")} ${pc10.dim('(hit rate across all samples \u2014 differentiates "wrong path" from "field sometimes missing")')}`);
8738
+ console.log(` ${pc11.dim("paths:")} ${pc11.dim('(hit rate across all samples \u2014 differentiates "wrong path" from "field sometimes missing")')}`);
8297
8739
  for (const p10 of searchablePreview.paths) {
8298
8740
  const rate = `${p10.hits}/${p10.total}`;
8299
- const mark = p10.hits === p10.total ? pc10.green("\u2713") : p10.hits === 0 ? pc10.red("\u2717") : pc10.yellow("~");
8300
- const trailer = p10.sample ? pc10.dim(` \u2192 "${p10.sample}"`) : p10.hits === 0 ? pc10.dim(" (no sample matched \u2014 typo, or field never populated in this page)") : "";
8741
+ const mark = p10.hits === p10.total ? pc11.green("\u2713") : p10.hits === 0 ? pc11.red("\u2717") : pc11.yellow("~");
8742
+ const trailer = p10.sample ? pc11.dim(` \u2192 "${p10.sample}"`) : p10.hits === 0 ? pc11.dim(" (no sample matched \u2014 typo, or field never populated in this page)") : "";
8301
8743
  console.log(` ${mark} ${rate.padStart(5)} ${p10.path}${trailer}`);
8302
8744
  }
8303
8745
  } else {
8304
- console.log(` ${pc10.yellow("note:")} no memory.searchable declared \u2014 using the default walker (walks every field, often noisy).`);
8305
- console.log(` ${pc10.dim("tip:")} run \`one sync suggest-searchable ${platform}/${model}\` for an auto-ranked starter list, or pick paths by hand and add them to profile.memory.searchable.`);
8746
+ console.log(` ${pc11.yellow("note:")} no memory.searchable declared \u2014 using the default walker (walks every field, often noisy).`);
8747
+ console.log(` ${pc11.dim("tip:")} run \`one sync suggest-searchable ${platform}/${model}\` for an auto-ranked starter list, or pick paths by hand and add them to profile.memory.searchable.`);
8306
8748
  }
8307
8749
  }
8308
8750
  console.log(
8309
8751
  `
8310
- ${report.ok ? pc10.green("Profile looks good.") : pc10.red("Profile has issues.")} ` + (report.ok ? `Run: ${pc10.bold(`one sync run ${platform} --models ${model}`)}` : "Fix the issues above and test again.")
8752
+ ${report.ok ? pc11.green("Profile looks good.") : pc11.red("Profile has issues.")} ` + (report.ok ? `Run: ${pc11.bold(`one sync run ${platform} --models ${model}`)}` : "Fix the issues above and test again.")
8311
8753
  );
8312
8754
  }
8313
8755
  function buildSearchablePreview(profile, samples) {
@@ -8315,7 +8757,7 @@ function buildSearchablePreview(profile, samples) {
8315
8757
  const first = samples[0];
8316
8758
  const paths = getSearchablePaths(profile);
8317
8759
  if (paths) {
8318
- const perPathAgg = paths.map((path13) => ({ path: path13, hits: 0, total: samples.length, sample: "" }));
8760
+ const perPathAgg = paths.map((path14) => ({ path: path14, hits: 0, total: samples.length, sample: "" }));
8319
8761
  for (const record of samples) {
8320
8762
  const { paths: perPath } = extractSearchableFromPaths(record, paths);
8321
8763
  perPath.forEach((p10, i) => {
@@ -8348,8 +8790,8 @@ async function syncRunCommand(platform, options) {
8348
8790
  if (profileDrift.length > 0 && !isAgentMode()) {
8349
8791
  for (const d of profileDrift) {
8350
8792
  console.log(
8351
- ` ${pc10.yellow("!")} ${platform}/${d.model} is missing ${d.missing.map((f) => pc10.bold(f)).join(", ")} from the current built-in profile.
8352
- Run ${pc10.bold(`one sync init ${platform} ${d.model}`)} to pick ${d.missing.length > 1 ? "them" : "it"} up.`
8793
+ ` ${pc11.yellow("!")} ${platform}/${d.model} is missing ${d.missing.map((f) => pc11.bold(f)).join(", ")} from the current built-in profile.
8794
+ Run ${pc11.bold(`one sync init ${platform} ${d.model}`)} to pick ${d.missing.length > 1 ? "them" : "it"} up.`
8353
8795
  );
8354
8796
  }
8355
8797
  }
@@ -8392,21 +8834,21 @@ async function syncRunCommand(platform, options) {
8392
8834
  return;
8393
8835
  }
8394
8836
  for (const r of results) {
8395
- const status = r.status === "complete" ? pc10.green("complete") : r.status === "dry-run" ? pc10.yellow("dry-run") : pc10.red("failed");
8396
- console.log(` ${pc10.bold(r.model)} \u2014 ${r.recordsSynced} records, ${r.pagesProcessed} pages, ${r.duration} [${status}]`);
8837
+ const status = r.status === "complete" ? pc11.green("complete") : r.status === "dry-run" ? pc11.yellow("dry-run") : pc11.red("failed");
8838
+ console.log(` ${pc11.bold(r.model)} \u2014 ${r.recordsSynced} records, ${r.pagesProcessed} pages, ${r.duration} [${status}]`);
8397
8839
  if (r.reconcileSkipped) {
8398
- console.log(` ${pc10.yellow("--full-refresh reconcile skipped \u2014 pagination truncated (e.g. --max-pages). Re-run without the cap to prune stale rows.")}`);
8840
+ console.log(` ${pc11.yellow("--full-refresh reconcile skipped \u2014 pagination truncated (e.g. --max-pages). Re-run without the cap to prune stale rows.")}`);
8399
8841
  }
8400
8842
  const sc = r.statusCounts;
8401
8843
  if (sc && (sc.archived > 0 || sc.active > 0)) {
8402
- const archivedColor = sc.archived > sc.active ? pc10.red : pc10.dim;
8403
- console.log(` memory: ${pc10.green(String(sc.active))} active, ${archivedColor(String(sc.archived))} archived`);
8844
+ const archivedColor = sc.archived > sc.active ? pc11.red : pc11.dim;
8845
+ console.log(` memory: ${pc11.green(String(sc.active))} active, ${archivedColor(String(sc.archived))} archived`);
8404
8846
  }
8405
8847
  if (r.error) {
8406
8848
  const errParts = [r.error.message];
8407
8849
  if (r.error.httpStatus) errParts.push(`HTTP ${r.error.httpStatus}`);
8408
8850
  if (r.error.retryAfter) errParts.push(`retry after ${r.error.retryAfter}s`);
8409
- console.log(` ${pc10.red(errParts.join(" \u2014 "))}`);
8851
+ console.log(` ${pc11.red(errParts.join(" \u2014 "))}`);
8410
8852
  }
8411
8853
  }
8412
8854
  }
@@ -8432,8 +8874,8 @@ async function syncQueryCommand(platformModel, options) {
8432
8874
  json(result);
8433
8875
  return;
8434
8876
  }
8435
- console.log(pc10.dim(`Query: ${result.query}`));
8436
- console.log(pc10.dim(`Source: local | Last sync: ${result.lastSync ?? "never"} | Age: ${result.syncAge ?? "n/a"}`));
8877
+ console.log(pc11.dim(`Query: ${result.query}`));
8878
+ console.log(pc11.dim(`Source: local | Last sync: ${result.lastSync ?? "never"} | Age: ${result.syncAge ?? "n/a"}`));
8437
8879
  console.log(JSON.stringify(result.results, null, 2));
8438
8880
  console.log(`
8439
8881
  ${result.total} results`);
@@ -8455,7 +8897,7 @@ async function syncSearchCommand(query, options) {
8455
8897
  return;
8456
8898
  }
8457
8899
  for (const r of result.results) {
8458
- console.log(` ${pc10.bold(`${r.platform}/${r.model}`)} ${pc10.dim(`(rank: ${r.rank.toFixed(2)})`)}`);
8900
+ console.log(` ${pc11.bold(`${r.platform}/${r.model}`)} ${pc11.dim(`(rank: ${r.rank.toFixed(2)})`)}`);
8459
8901
  console.log(` ${JSON.stringify(r.record)}`);
8460
8902
  }
8461
8903
  console.log(`
@@ -8465,7 +8907,7 @@ ${result.total} results`);
8465
8907
  }
8466
8908
  }
8467
8909
  async function syncSqlCommand(platformModel, sql) {
8468
- const { syncSqlCommand: runSyncSql } = await import("./sql-3WNYRCWP.js");
8910
+ const { syncSqlCommand: runSyncSql } = await import("./sql-QIVDWTL3.js");
8469
8911
  await runSyncSql(platformModel, sql);
8470
8912
  }
8471
8913
  async function syncDeleteCommand(platformModel, options) {
@@ -8543,7 +8985,7 @@ async function syncDeleteCommand(platformModel, options) {
8543
8985
  async function maybeAutoMigrateLegacy(platform, models) {
8544
8986
  const dbSize = getDatabaseSize(platform);
8545
8987
  if (!dbSize || dbSize === "0 B") return;
8546
- const { getBackend: getBackend2 } = await import("./runtime-AFXLC4IC.js");
8988
+ const { getBackend: getBackend2 } = await import("./runtime-65IPTPVD.js");
8547
8989
  const backend = await getBackend2();
8548
8990
  let memoryHasData = false;
8549
8991
  for (const model of models) {
@@ -8559,7 +9001,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
8559
9001
  ` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
8560
9002
  `
8561
9003
  );
8562
- const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-37A463L6.js");
9004
+ const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-IJI3BTWL.js");
8563
9005
  await memMigrateCommand3({ platform, yes: true });
8564
9006
  return;
8565
9007
  }
@@ -8568,7 +9010,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
8568
9010
  initialValue: true
8569
9011
  });
8570
9012
  if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
8571
- const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-37A463L6.js");
9013
+ const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-IJI3BTWL.js");
8572
9014
  await memMigrateCommand2({ platform, yes: true });
8573
9015
  }
8574
9016
  async function syncSuggestSearchableCommand(platformModel, options = {}) {
@@ -8606,30 +9048,30 @@ async function syncSuggestSearchableCommand(platformModel, options = {}) {
8606
9048
  return;
8607
9049
  }
8608
9050
  console.log(`
8609
- ${pc10.bold("memory.searchable \u2014 ranked suggestions")} ${pc10.dim(`(${samples.length} samples)`)}`);
9051
+ ${pc11.bold("memory.searchable \u2014 ranked suggestions")} ${pc11.dim(`(${samples.length} samples)`)}`);
8610
9052
  if (suggestions.length === 0) {
8611
- console.log(` ${pc10.yellow("no high-signal leaves found")} \u2014 page may be all UUIDs / timestamps / enum markers. Inspect the sample with \`sync test\` and pick paths manually.`);
9053
+ console.log(` ${pc11.yellow("no high-signal leaves found")} \u2014 page may be all UUIDs / timestamps / enum markers. Inspect the sample with \`sync test\` and pick paths manually.`);
8612
9054
  return;
8613
9055
  }
8614
9056
  for (const s of suggestions) {
8615
9057
  const hitPct = Math.round(s.hitRate * 100);
8616
9058
  const noisePct = Math.round(s.noiseFraction * 100);
8617
- const noiseBadge = noisePct > 0 ? pc10.dim(` noise=${noisePct}%`) : "";
9059
+ const noiseBadge = noisePct > 0 ? pc11.dim(` noise=${noisePct}%`) : "";
8618
9060
  console.log(
8619
- ` ${pc10.green(String(s.score).padStart(5))} ${pc10.cyan(s.path.padEnd(52))}` + pc10.dim(` ${hitPct}% hit`) + pc10.dim(` avg=${s.avgLength}ch`) + noiseBadge + (s.sampleValue ? pc10.dim(`
9061
+ ` ${pc11.green(String(s.score).padStart(5))} ${pc11.cyan(s.path.padEnd(52))}` + pc11.dim(` ${hitPct}% hit`) + pc11.dim(` avg=${s.avgLength}ch`) + noiseBadge + (s.sampleValue ? pc11.dim(`
8620
9062
  \u2192 "${s.sampleValue.slice(0, 140)}"`) : "")
8621
9063
  );
8622
9064
  }
8623
9065
  console.log(`
8624
- ${pc10.bold("Paste-ready:")}`);
8625
- console.log(" " + pc10.cyan(`one sync init ${platform} ${model} --config '${JSON.stringify(configPatch)}'`));
9066
+ ${pc11.bold("Paste-ready:")}`);
9067
+ console.log(" " + pc11.cyan(`one sync init ${platform} ${model} --config '${JSON.stringify(configPatch)}'`));
8626
9068
  console.log(`
8627
- ${pc10.dim("then preview: ")}${pc10.cyan(`one sync test ${platform}/${model} --show-searchable`)}`);
9069
+ ${pc11.dim("then preview: ")}${pc11.cyan(`one sync test ${platform}/${model} --show-searchable`)}`);
8628
9070
  }
8629
9071
  async function syncListCommand(platform) {
8630
9072
  const profiles = listProfiles(platform);
8631
9073
  const state = await readSyncState();
8632
- const { getBackend: getBackend2 } = await import("./runtime-AFXLC4IC.js");
9074
+ const { getBackend: getBackend2 } = await import("./runtime-65IPTPVD.js");
8633
9075
  const backend = await getBackend2();
8634
9076
  const syncs = await Promise.all(profiles.map(async (p10) => {
8635
9077
  const modelState = state[p10.platform]?.[p10.model];
@@ -8658,10 +9100,10 @@ async function syncListCommand(platform) {
8658
9100
  return;
8659
9101
  }
8660
9102
  for (const s of syncs) {
8661
- const status = s.status === "idle" ? pc10.green("idle") : s.status === "syncing" ? pc10.yellow(`syncing \u2014 page ${s.pagesProcessed}`) : pc10.red("failed");
8662
- const legacy = s.legacyDbSize && s.legacyDbSize !== "0 B" ? pc10.yellow(` legacy .db ${s.legacyDbSize}`) : "";
9103
+ const status = s.status === "idle" ? pc11.green("idle") : s.status === "syncing" ? pc11.yellow(`syncing \u2014 page ${s.pagesProcessed}`) : pc11.red("failed");
9104
+ const legacy = s.legacyDbSize && s.legacyDbSize !== "0 B" ? pc11.yellow(` legacy .db ${s.legacyDbSize}`) : "";
8663
9105
  console.log(
8664
- ` ${pc10.bold(`${s.platform}/${s.model}`.padEnd(35))} ${String(s.totalRecords).padStart(8)} records ${status} ${pc10.dim(s.lastSync ? `last: ${s.lastSync}` : "never synced")}` + legacy
9106
+ ` ${pc11.bold(`${s.platform}/${s.model}`.padEnd(35))} ${String(s.totalRecords).padStart(8)} records ${status} ${pc11.dim(s.lastSync ? `last: ${s.lastSync}` : "never synced")}` + legacy
8665
9107
  );
8666
9108
  }
8667
9109
  }
@@ -8740,8 +9182,8 @@ async function syncScheduleAddCommand(platform, options) {
8740
9182
  }
8741
9183
  const verb = replaced ? "Replaced existing schedule" : "Scheduled sync";
8742
9184
  outro(
8743
- `${verb} ${pc10.bold(entry.id)} \u2014 every ${pc10.bold(entry.every)} (cron: ${pc10.dim(entry.cronExpr)})
8744
- Logs: ${pc10.dim(entry.logFile)}`
9185
+ `${verb} ${pc11.bold(entry.id)} \u2014 every ${pc11.bold(entry.every)} (cron: ${pc11.dim(entry.cronExpr)})
9186
+ Logs: ${pc11.dim(entry.logFile)}`
8745
9187
  );
8746
9188
  } catch (err) {
8747
9189
  error(err instanceof Error ? err.message : String(err));
@@ -8760,14 +9202,14 @@ async function syncScheduleListCommand() {
8760
9202
  }
8761
9203
  for (const e of entries) {
8762
9204
  const modelsStr = e.models ? ` [${e.models.join(",")}]` : "";
8763
- const installed = e.cronInstalled ? pc10.green("\u25CF") : pc10.red("\u2717");
9205
+ const installed = e.cronInstalled ? pc11.green("\u25CF") : pc11.red("\u2717");
8764
9206
  console.log(
8765
- ` ${installed} ${pc10.bold(e.id.padEnd(32))} every ${pc10.bold(e.every.padEnd(5))} ${pc10.dim(e.cronExpr.padEnd(13))}${modelsStr}`
9207
+ ` ${installed} ${pc11.bold(e.id.padEnd(32))} every ${pc11.bold(e.every.padEnd(5))} ${pc11.dim(e.cronExpr.padEnd(13))}${modelsStr}`
8766
9208
  );
8767
- console.log(` ${pc10.dim("cwd:")} ${e.cwd}`);
9209
+ console.log(` ${pc11.dim("cwd:")} ${e.cwd}`);
8768
9210
  }
8769
9211
  console.log(`
8770
- ${pc10.dim("\u25CF = cron line installed \u2717 = registry drift, run `sync schedule repair <id>`")}`);
9212
+ ${pc11.dim("\u25CF = cron line installed \u2717 = registry drift, run `sync schedule repair <id>`")}`);
8771
9213
  } catch (err) {
8772
9214
  error(err instanceof Error ? err.message : String(err));
8773
9215
  }
@@ -8791,7 +9233,7 @@ async function syncScheduleRemoveCommand(idOrPlatform, options) {
8791
9233
  return;
8792
9234
  }
8793
9235
  for (const r of result.removed) {
8794
- console.log(` ${pc10.green("\u2713")} removed ${pc10.bold(r.id)} ${pc10.dim(`(${r.cwd})`)}`);
9236
+ console.log(` ${pc11.green("\u2713")} removed ${pc11.bold(r.id)} ${pc11.dim(`(${r.cwd})`)}`);
8795
9237
  }
8796
9238
  } catch (err) {
8797
9239
  error(err instanceof Error ? err.message : String(err));
@@ -8809,21 +9251,21 @@ async function syncScheduleStatusCommand() {
8809
9251
  return;
8810
9252
  }
8811
9253
  for (const s of statuses) {
8812
- const driftMarker = s.drift === "ok" ? pc10.green("\u25CF") : s.drift === "missing-cron" ? pc10.red("\u2717 missing cron line") : pc10.yellow(`\u26A0 ${s.drift}`);
8813
- console.log(` ${driftMarker} ${pc10.bold(s.entry.id)} \u2014 every ${s.entry.every} (${pc10.dim(s.entry.cronExpr)})`);
8814
- console.log(` ${pc10.dim("cwd:")} ${s.entry.cwd}`);
8815
- console.log(` ${pc10.dim("last run:")} ${s.lastRunAt ?? pc10.yellow("never")}`);
8816
- console.log(` ${pc10.dim("log:")} ${s.entry.logFile} ${s.logExists ? pc10.dim(`(${s.logSize} bytes)`) : pc10.yellow("(empty)")}`);
9254
+ const driftMarker = s.drift === "ok" ? pc11.green("\u25CF") : s.drift === "missing-cron" ? pc11.red("\u2717 missing cron line") : pc11.yellow(`\u26A0 ${s.drift}`);
9255
+ console.log(` ${driftMarker} ${pc11.bold(s.entry.id)} \u2014 every ${s.entry.every} (${pc11.dim(s.entry.cronExpr)})`);
9256
+ console.log(` ${pc11.dim("cwd:")} ${s.entry.cwd}`);
9257
+ console.log(` ${pc11.dim("last run:")} ${s.lastRunAt ?? pc11.yellow("never")}`);
9258
+ console.log(` ${pc11.dim("log:")} ${s.entry.logFile} ${s.logExists ? pc11.dim(`(${s.logSize} bytes)`) : pc11.yellow("(empty)")}`);
8817
9259
  if (s.logTail.length > 0) {
8818
- console.log(pc10.dim(" last lines:"));
9260
+ console.log(pc11.dim(" last lines:"));
8819
9261
  for (const line of s.logTail.slice(-3)) {
8820
- console.log(pc10.dim(` ${line}`));
9262
+ console.log(pc11.dim(` ${line}`));
8821
9263
  }
8822
9264
  }
8823
9265
  }
8824
9266
  if (statuses.some((s) => s.drift !== "ok")) {
8825
9267
  console.log(`
8826
- ${pc10.yellow("Drift detected.")} Run ${pc10.bold("one sync schedule repair <id>")} to heal.`);
9268
+ ${pc11.yellow("Drift detected.")} Run ${pc11.bold("one sync schedule repair <id>")} to heal.`);
8827
9269
  }
8828
9270
  } catch (err) {
8829
9271
  error(err instanceof Error ? err.message : String(err));
@@ -8836,7 +9278,7 @@ async function syncScheduleRepairCommand(id) {
8836
9278
  json({ status: "repaired", ...healed });
8837
9279
  return;
8838
9280
  }
8839
- outro(`Repaired ${pc10.bold(healed.id)}: re-installed cron line with current node/cli paths.`);
9281
+ outro(`Repaired ${pc11.bold(healed.id)}: re-installed cron line with current node/cli paths.`);
8840
9282
  } catch (err) {
8841
9283
  error(err instanceof Error ? err.message : String(err));
8842
9284
  }
@@ -8905,7 +9347,7 @@ function registerSyncSubcommands(sync) {
8905
9347
  await syncSqlCommand(platformModel, sql);
8906
9348
  });
8907
9349
  sync.command("schema <platform/model>").description("Inspect the JSON structure of synced records (field paths, types, examples) \u2014 useful before writing `sync sql` queries").action(async (platformModel) => {
8908
- const { syncSchemaCommand } = await import("./schema-4JJO2CIZ.js");
9350
+ const { syncSchemaCommand } = await import("./schema-OO4WK5ND.js");
8909
9351
  await syncSchemaCommand(platformModel);
8910
9352
  });
8911
9353
  sync.command("delete <platform/model>").description('Delete records from local sync data (e.g. one sync delete notion/pages --id "abc-123")').option("--id <value>", "Delete record by ID").option("--where <conditions>", 'Delete records matching conditions (e.g. "status=archived")').option("--where-sql <predicate>", `Delete using a raw SQL WHERE clause (e.g. "json_extract(data, '$.type') = 'promotion'")`).option("--yes", "Skip confirmation prompt").action(async (platformModel, options) => {
@@ -9272,16 +9714,16 @@ function projectEmbeddingApiKey(cfg) {
9272
9714
  }
9273
9715
  function redactSecrets(cfg) {
9274
9716
  const copy = JSON.parse(JSON.stringify(cfg));
9275
- for (const path13 of SECRET_PATHS) {
9276
- const val = getPath(copy, path13);
9717
+ for (const path14 of SECRET_PATHS) {
9718
+ const val = getPath(copy, path14);
9277
9719
  if (typeof val === "string" && val.length > 0) {
9278
- setPath(copy, path13, `${val.slice(0, 6)}\u2026(redacted, use --show-secrets)`);
9720
+ setPath(copy, path14, `${val.slice(0, 6)}\u2026(redacted, use --show-secrets)`);
9279
9721
  }
9280
9722
  }
9281
9723
  return copy;
9282
9724
  }
9283
- function getPath(obj, path13) {
9284
- const parts = path13.split(".");
9725
+ function getPath(obj, path14) {
9726
+ const parts = path14.split(".");
9285
9727
  let cur = obj;
9286
9728
  for (const part of parts) {
9287
9729
  if (cur == null || typeof cur !== "object") return void 0;
@@ -9289,8 +9731,8 @@ function getPath(obj, path13) {
9289
9731
  }
9290
9732
  return cur;
9291
9733
  }
9292
- function setPath(obj, path13, value) {
9293
- const parts = path13.split(".");
9734
+ function setPath(obj, path14, value) {
9735
+ const parts = path14.split(".");
9294
9736
  let cur = obj;
9295
9737
  for (let i = 0; i < parts.length - 1; i++) {
9296
9738
  const part = parts[i];
@@ -9300,8 +9742,8 @@ function setPath(obj, path13, value) {
9300
9742
  cur[parts[parts.length - 1]] = value;
9301
9743
  return obj;
9302
9744
  }
9303
- function unsetPath(obj, path13) {
9304
- const parts = path13.split(".");
9745
+ function unsetPath(obj, path14) {
9746
+ const parts = path14.split(".");
9305
9747
  let cur = obj;
9306
9748
  for (let i = 0; i < parts.length - 1; i++) {
9307
9749
  const part = parts[i];
@@ -9327,7 +9769,7 @@ function parseValue(raw) {
9327
9769
  }
9328
9770
 
9329
9771
  // src/commands/mem/records.ts
9330
- import pc11 from "picocolors";
9772
+ import pc12 from "picocolors";
9331
9773
  async function memAddCommand(type, dataRaw, flags) {
9332
9774
  requireMemoryInit();
9333
9775
  const data = parseJsonArg(dataRaw, "data");
@@ -9526,7 +9968,7 @@ function summarizeRecord(r) {
9526
9968
  const v = d[field];
9527
9969
  if (typeof v === "string" && v.trim()) return v.trim().slice(0, 80);
9528
9970
  }
9529
- return pc11.dim("(untitled)");
9971
+ return pc12.dim("(untitled)");
9530
9972
  }
9531
9973
  function relativeTime(iso) {
9532
9974
  if (!iso) return "";
@@ -9589,7 +10031,7 @@ async function memFindByKeyCommand(key, secondKey, flags) {
9589
10031
  });
9590
10032
  return;
9591
10033
  }
9592
- const label = matchedKeys.map((k) => pc11.cyan(k)).join(pc11.dim(" + "));
10034
+ const label = matchedKeys.map((k) => pc12.cyan(k)).join(pc12.dim(" + "));
9593
10035
  if (records.length === 0) {
9594
10036
  console.log(`
9595
10037
  No records linked to ${label}.
@@ -9597,27 +10039,27 @@ async function memFindByKeyCommand(key, secondKey, flags) {
9597
10039
  return;
9598
10040
  }
9599
10041
  console.log();
9600
- console.log(` ${label} ${pc11.dim("\u2014")} ${records.length}${truncated ? "+" : ""} record${records.length === 1 ? "" : "s"} across ${byType.size} type${byType.size === 1 ? "" : "s"}`);
10042
+ console.log(` ${label} ${pc12.dim("\u2014")} ${records.length}${truncated ? "+" : ""} record${records.length === 1 ? "" : "s"} across ${byType.size} type${byType.size === 1 ? "" : "s"}`);
9601
10043
  console.log();
9602
10044
  const typeWidth = Math.min(30, Math.max(...[...byType.keys()].map((t) => t.length)));
9603
10045
  for (const [type, list] of byType) {
9604
- console.log(` ${pc11.bold(type.padEnd(typeWidth))} ${pc11.dim(`${list.length} record${list.length === 1 ? "" : "s"}`)}`);
10046
+ console.log(` ${pc12.bold(type.padEnd(typeWidth))} ${pc12.dim(`${list.length} record${list.length === 1 ? "" : "s"}`)}`);
9605
10047
  for (const r of list.slice(0, perType)) {
9606
- console.log(` ${pc11.dim("\xB7")} ${summarizeRecord(r)} ${pc11.dim(relativeTime(r.updated_at))} ${pc11.dim(r.id)}`);
10048
+ console.log(` ${pc12.dim("\xB7")} ${summarizeRecord(r)} ${pc12.dim(relativeTime(r.updated_at))} ${pc12.dim(r.id)}`);
9607
10049
  }
9608
10050
  if (list.length > perType) {
9609
- console.log(` ${pc11.dim(`\u2026 and ${list.length - perType} more (raise --limit)`)}`);
10051
+ console.log(` ${pc12.dim(`\u2026 and ${list.length - perType} more (raise --limit)`)}`);
9610
10052
  }
9611
10053
  }
9612
10054
  if (truncated) {
9613
10055
  console.log();
9614
- console.log(` ${pc11.yellow("\u26A0")} Stopped at ${FIND_BY_KEY_FETCH_CAP} matches \u2014 there are more, and types sorting after the last one shown are missing entirely. Re-run with --type <type> to see them.`);
10056
+ console.log(` ${pc12.yellow("\u26A0")} Stopped at ${FIND_BY_KEY_FETCH_CAP} matches \u2014 there are more, and types sorting after the last one shown are missing entirely. Re-run with --type <type> to see them.`);
9615
10057
  }
9616
10058
  console.log();
9617
10059
  }
9618
10060
 
9619
10061
  // src/commands/mem/doctor.ts
9620
- import pc12 from "picocolors";
10062
+ import pc13 from "picocolors";
9621
10063
  async function memDoctorCommand() {
9622
10064
  const checks = [];
9623
10065
  const cfg = getMemoryConfig();
@@ -9682,7 +10124,7 @@ async function memDoctorCommand() {
9682
10124
  }
9683
10125
  if (cfg.embedding.provider === "openai") {
9684
10126
  try {
9685
- const { embed: embed2 } = await import("./embedding-Z2WCDN6R.js");
10127
+ const { embed: embed2 } = await import("./embedding-OXX4OF65.js");
9686
10128
  const result = await embed2("connectivity check");
9687
10129
  checks.push({
9688
10130
  name: "OpenAI embedding provider reachable",
@@ -9724,23 +10166,23 @@ function emit(checks, capInfo) {
9724
10166
  return;
9725
10167
  }
9726
10168
  for (const c of checks) {
9727
- const mark = c.ok ? pc12.green("\u2713") : pc12.red("\u2717");
9728
- const detail = c.detail ? pc12.dim(` \u2014 ${c.detail}`) : "";
10169
+ const mark = c.ok ? pc13.green("\u2713") : pc13.red("\u2717");
10170
+ const detail = c.detail ? pc13.dim(` \u2014 ${c.detail}`) : "";
9729
10171
  console.log(` ${mark} ${c.name}${detail}`);
9730
10172
  }
9731
10173
  if (!allOk) {
9732
- console.log("\n" + pc12.yellow("Memory is not fully healthy."));
10174
+ console.log("\n" + pc13.yellow("Memory is not fully healthy."));
9733
10175
  process.exitCode = 1;
9734
10176
  } else {
9735
- console.log("\n" + pc12.green("Memory is healthy."));
10177
+ console.log("\n" + pc13.green("Memory is healthy."));
9736
10178
  }
9737
10179
  const line = semanticSearchUpgradeLine({ vectorSearchAvailable: capInfo.vectorSearchAvailable });
9738
10180
  if (line) console.log(`
9739
- ${pc12.dim(line)}`);
10181
+ ${pc13.dim(line)}`);
9740
10182
  }
9741
10183
 
9742
10184
  // src/commands/mem/export.ts
9743
- import fs11 from "fs";
10185
+ import fs12 from "fs";
9744
10186
  import { once } from "events";
9745
10187
  async function writeLine(stream, line) {
9746
10188
  if (!stream.write(line)) {
@@ -9752,7 +10194,7 @@ async function memExportCommand(outfile) {
9752
10194
  const backend = await getBackend();
9753
10195
  const stats = await backend.stats();
9754
10196
  const toFile = !!outfile && outfile !== "-";
9755
- const stream = toFile ? fs11.createWriteStream(outfile, "utf-8") : process.stdout;
10197
+ const stream = toFile ? fs12.createWriteStream(outfile, "utf-8") : process.stdout;
9756
10198
  const all = await listAllTypes(backend);
9757
10199
  const pageSize = 500;
9758
10200
  let written = 0;
@@ -9783,9 +10225,9 @@ async function memExportCommand(outfile) {
9783
10225
  }
9784
10226
  async function memImportCommand(file) {
9785
10227
  requireMemoryInit();
9786
- if (!fs11.existsSync(file)) error(`File not found: ${file}`);
10228
+ if (!fs12.existsSync(file)) error(`File not found: ${file}`);
9787
10229
  const backend = await getBackend();
9788
- const raw = fs11.readFileSync(file, "utf-8");
10230
+ const raw = fs12.readFileSync(file, "utf-8");
9789
10231
  const lines = raw.split("\n").filter((l) => l.trim().length > 0);
9790
10232
  let inserted = 0;
9791
10233
  let updated = 0;
@@ -10031,7 +10473,7 @@ function registerMemoryCommands(program2) {
10031
10473
  }
10032
10474
 
10033
10475
  // src/commands/cache.ts
10034
- import pc13 from "picocolors";
10476
+ import pc14 from "picocolors";
10035
10477
  async function cacheClearCommand(actionId) {
10036
10478
  if (actionId) {
10037
10479
  const deleted = clearEntry(actionId);
@@ -10040,9 +10482,9 @@ async function cacheClearCommand(actionId) {
10040
10482
  return;
10041
10483
  }
10042
10484
  if (deleted) {
10043
- console.log(`Cleared cache for ${pc13.cyan(actionId)}`);
10485
+ console.log(`Cleared cache for ${pc14.cyan(actionId)}`);
10044
10486
  } else {
10045
- console.log(`No cache entry found for ${pc13.dim(actionId)}`);
10487
+ console.log(`No cache entry found for ${pc14.dim(actionId)}`);
10046
10488
  }
10047
10489
  } else {
10048
10490
  const count = clearAll();
@@ -10079,7 +10521,7 @@ async function cacheListCommand(options) {
10079
10521
  type: e.type,
10080
10522
  key: e.entry.key,
10081
10523
  age: formatAge(getAge(e.entry)),
10082
- status: isFresh(e.entry) ? pc13.green("fresh") : pc13.yellow("expired")
10524
+ status: isFresh(e.entry) ? pc14.green("fresh") : pc14.yellow("expired")
10083
10525
  }));
10084
10526
  printTable(
10085
10527
  [
@@ -10109,8 +10551,8 @@ async function cacheUpdateAllCommand() {
10109
10551
  console.log("No cached entries to update");
10110
10552
  return;
10111
10553
  }
10112
- const spinner5 = createSpinner();
10113
- spinner5.start(`Updating ${entries.length} cached ${entries.length === 1 ? "entry" : "entries"}...`);
10554
+ const spinner4 = createSpinner();
10555
+ spinner4.start(`Updating ${entries.length} cached ${entries.length === 1 ? "entry" : "entries"}...`);
10114
10556
  let updated = 0;
10115
10557
  let failed = 0;
10116
10558
  const errors = [];
@@ -10162,7 +10604,7 @@ async function cacheUpdateAllCommand() {
10162
10604
  });
10163
10605
  }
10164
10606
  }
10165
- spinner5.stop(`Updated ${updated} ${updated === 1 ? "entry" : "entries"}${failed > 0 ? `, ${failed} failed` : ""}`);
10607
+ spinner4.stop(`Updated ${updated} ${updated === 1 ? "entry" : "entries"}${failed > 0 ? `, ${failed} failed` : ""}`);
10166
10608
  if (isAgentMode()) {
10167
10609
  json({ updated, failed, errors: errors.length > 0 ? errors : void 0 });
10168
10610
  return;
@@ -10170,13 +10612,13 @@ async function cacheUpdateAllCommand() {
10170
10612
  if (errors.length > 0) {
10171
10613
  console.log();
10172
10614
  for (const e of errors) {
10173
- console.log(` ${pc13.red("\u2717")} ${e.key}: ${pc13.dim(e.error)}`);
10615
+ console.log(` ${pc14.red("\u2717")} ${e.key}: ${pc14.dim(e.error)}`);
10174
10616
  }
10175
10617
  }
10176
10618
  }
10177
10619
 
10178
10620
  // src/commands/guide.ts
10179
- import pc14 from "picocolors";
10621
+ import pc15 from "picocolors";
10180
10622
 
10181
10623
  // src/lib/guide-content.ts
10182
10624
  var GUIDE_OVERVIEW = `# One CLI \u2014 Agent Guide
@@ -10189,6 +10631,8 @@ var GUIDE_OVERVIEW = `# One CLI \u2014 Agent Guide
10189
10631
 
10190
10632
  You can also use \`one login\` / \`one logout\` to manage authentication separately (global or per-directory).
10191
10633
 
10634
+ Browser login opens a consent page that names the key and tags it with where the CLI runs (scope, project path, machine, OS user, CLI version, the agent harnesses you pick, and the per-install device id unless telemetry is off), so the dashboard can show every install. The terminal prints what will be sent before the browser opens. Set \`ONE_APP_URL\` (dashboard origin) and \`ONE_API_BASE\` (API origin) to run against a local stack; neither is written to config, so pair them with \`ONE_HOME\` to keep a local stack's credentials separate.
10635
+
10192
10636
  ### Agent-driven setup (no prompts)
10193
10637
  To onboard a user without any terminal interaction, pass \`--auth\` to \`one init\`. This disables every prompt, auto-installs the One skill, and skips the connect-a-platform step (run \`one add <platform>\` afterwards).
10194
10638
 
@@ -11337,14 +11781,14 @@ async function guideCommand(topic = "all") {
11337
11781
  json({ topic, title, content, availableTopics });
11338
11782
  return;
11339
11783
  }
11340
- intro(pc14.bgCyan(pc14.black(" One Guide ")));
11784
+ intro(pc15.bgCyan(pc15.black(" One Guide ")));
11341
11785
  console.log();
11342
11786
  console.log(content);
11343
- console.log(pc14.dim("\u2500".repeat(60)));
11787
+ console.log(pc15.dim("\u2500".repeat(60)));
11344
11788
  console.log(
11345
- pc14.dim("Available topics: ") + availableTopics.map((t) => pc14.cyan(t.topic)).join(", ")
11789
+ pc15.dim("Available topics: ") + availableTopics.map((t) => pc15.cyan(t.topic)).join(", ")
11346
11790
  );
11347
- console.log(pc14.dim(`Run ${pc14.cyan("one guide <topic>")} for a specific section.`));
11791
+ console.log(pc15.dim(`Run ${pc15.cyan("one guide <topic>")} for a specific section.`));
11348
11792
  }
11349
11793
 
11350
11794
  // src/lib/platform-meta.ts
@@ -11665,7 +12109,7 @@ function buildWorkflowIdeas(connections) {
11665
12109
  }
11666
12110
 
11667
12111
  // src/commands/logout.ts
11668
- import fs12 from "fs";
12112
+ import fs13 from "fs";
11669
12113
  import * as p9 from "@clack/prompts";
11670
12114
  function formatWhoami(config2, apiKey, pc16) {
11671
12115
  const whoami = config2.whoami;
@@ -11679,8 +12123,10 @@ function formatWhoami(config2, apiKey, pc16) {
11679
12123
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
11680
12124
  lines.push(`${pc16.bold(scopeDisplay)} ${pc16.dim("\xB7")} ${envLabel}`);
11681
12125
  lines.push(`${whoami.user.name} ${pc16.dim(`(${whoami.user.email})`)}`);
12126
+ if (config2.apiKeyName) lines.push(`${pc16.dim("Key:")} ${config2.apiKeyName}`);
11682
12127
  } else {
11683
- lines.push(`${pc16.dim("Key:")} ${apiKey.slice(0, 8)}... ${pc16.dim("\xB7")} ${envLabel}`);
12128
+ const keyLabel = config2.apiKeyName ?? `${apiKey.slice(0, 8)}...`;
12129
+ lines.push(`${pc16.dim("Key:")} ${keyLabel} ${pc16.dim("\xB7")} ${envLabel}`);
11684
12130
  }
11685
12131
  return lines;
11686
12132
  }
@@ -11698,12 +12144,12 @@ async function logoutCommand() {
11698
12144
  const globalPath = getGlobalConfigPath();
11699
12145
  const projectPath = getProjectConfigPath();
11700
12146
  let cleared = false;
11701
- if (fs12.existsSync(projectPath)) {
11702
- fs12.unlinkSync(projectPath);
12147
+ if (fs13.existsSync(projectPath)) {
12148
+ fs13.unlinkSync(projectPath);
11703
12149
  cleared = true;
11704
12150
  }
11705
- if (fs12.existsSync(globalPath)) {
11706
- fs12.unlinkSync(globalPath);
12151
+ if (fs13.existsSync(globalPath)) {
12152
+ fs13.unlinkSync(globalPath);
11707
12153
  cleared = true;
11708
12154
  }
11709
12155
  json({ status: cleared ? "logged_out" : "not_logged_in", message: cleared ? "Credentials cleared." : "No config found." });
@@ -11772,328 +12218,17 @@ async function logoutCommand() {
11772
12218
  }
11773
12219
  if (targetScope === "project" || targetScope === "both") {
11774
12220
  const projectPath = getProjectConfigPath();
11775
- if (fs12.existsSync(projectPath)) fs12.unlinkSync(projectPath);
12221
+ if (fs13.existsSync(projectPath)) fs13.unlinkSync(projectPath);
11776
12222
  }
11777
12223
  if (targetScope === "global" || targetScope === "both") {
11778
12224
  const globalPath = getGlobalConfigPath();
11779
- if (fs12.existsSync(globalPath)) fs12.unlinkSync(globalPath);
12225
+ if (fs13.existsSync(globalPath)) fs13.unlinkSync(globalPath);
11780
12226
  }
11781
12227
  p9.log.success("Credentials cleared.");
11782
12228
  p9.log.info("Your API key is still active. Manage keys at app.withone.ai/settings");
11783
12229
  p9.outro("Logged out.");
11784
12230
  }
11785
12231
 
11786
- // src/lib/analytics.ts
11787
- import { createRequire as createRequire2 } from "module";
11788
- import { randomUUID, createHash } from "crypto";
11789
- import pc15 from "picocolors";
11790
- var require3 = createRequire2(import.meta.url);
11791
- var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
11792
- var DEFAULT_POSTHOG_KEY = "phc_a9ok4w0uxiZcVoSWOISIlin85lHMXQD3vWPaYnuRlRV";
11793
- var SEND_MAX_ATTEMPTS = 3;
11794
- var QUEUE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
11795
- var EXIT_GRACE_MS = 300;
11796
- var inFlight = /* @__PURE__ */ new Set();
11797
- var pending = /* @__PURE__ */ new Set();
11798
- var dispatched = /* @__PURE__ */ new Set();
11799
- var delivered = /* @__PURE__ */ new Set();
11800
- var UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11801
- function uuidFromInsertId(insertId) {
11802
- if (UUID_SHAPE.test(insertId)) return insertId.toLowerCase();
11803
- const h = createHash("sha1").update(`one-cli-event:${insertId}`).digest("hex");
11804
- const variant = (parseInt(h[16], 16) & 3 | 8).toString(16);
11805
- return `${h.slice(0, 8)}-${h.slice(8, 12)}-5${h.slice(13, 16)}-${variant}${h.slice(17, 20)}-${h.slice(20, 32)}`;
11806
- }
11807
- function posthogHost() {
11808
- return process.env.ONE_POSTHOG_HOST || DEFAULT_POSTHOG_HOST;
11809
- }
11810
- function posthogKey() {
11811
- return process.env.ONE_POSTHOG_KEY || DEFAULT_POSTHOG_KEY;
11812
- }
11813
- function envName() {
11814
- const key = getApiKey();
11815
- return key ? getEnvFromApiKey(key) : "live";
11816
- }
11817
- function isOn(value) {
11818
- return value === "1" || value === "true";
11819
- }
11820
- function debugLog(message) {
11821
- if (isOn(process.env.ONE_ANALYTICS_DEBUG)) {
11822
- process.stderr.write(`[analytics] ${message}
11823
- `);
11824
- }
11825
- }
11826
- function isTelemetryDisabled() {
11827
- if (isOn(process.env.ONE_NO_TELEMETRY) || isOn(process.env.ONE_DISABLE_TELEMETRY)) return true;
11828
- if (isOn(process.env.DO_NOT_TRACK)) return true;
11829
- if (isOn(process.env.CI)) return true;
11830
- if (readConfig()?.telemetry === "off") return true;
11831
- return false;
11832
- }
11833
- function distinctId() {
11834
- return getWhoAmI()?.user?.id ?? getDeviceId();
11835
- }
11836
- function isAuthenticated() {
11837
- return !!getWhoAmI()?.user || !!getApiKey();
11838
- }
11839
- function baseProperties() {
11840
- return {
11841
- $lib: "one-cli",
11842
- cli_version: cliVersion(),
11843
- agent_mode: isAgentMode(),
11844
- env: envName(),
11845
- os: process.platform,
11846
- arch: process.arch,
11847
- node_version: process.versions.node,
11848
- authenticated: isAuthenticated()
11849
- };
11850
- }
11851
- function personSet() {
11852
- const whoami = getWhoAmI();
11853
- if (!whoami?.user) return void 0;
11854
- const set = {};
11855
- if (whoami.user.email) set.email = whoami.user.email;
11856
- if (whoami.user.name) set.name = whoami.user.name;
11857
- if (whoami.organization?.id) set.organization_id = whoami.organization.id;
11858
- return Object.keys(set).length ? set : void 0;
11859
- }
11860
- function send(item) {
11861
- const insertId = item.properties.$insert_id;
11862
- if (insertId) dispatched.add(insertId);
11863
- const controller = new AbortController();
11864
- inFlight.add(controller);
11865
- const run = (async () => {
11866
- try {
11867
- const res = await fetch(`${posthogHost()}/i/v0/e/`, {
11868
- method: "POST",
11869
- headers: { "Content-Type": "application/json" },
11870
- body: JSON.stringify({
11871
- api_key: posthogKey(),
11872
- event: item.event,
11873
- distinct_id: item.distinct_id,
11874
- // PostHog's dedupe key — a re-sent copy is dropped on ingest.
11875
- uuid: item.uuid ?? (insertId ? uuidFromInsertId(insertId) : void 0),
11876
- properties: item.properties,
11877
- timestamp: item.timestamp
11878
- }),
11879
- signal: controller.signal
11880
- });
11881
- if (res.ok && insertId) delivered.add(insertId);
11882
- debugLog(`"${item.event}" -> HTTP ${res.status}${res.ok ? "" : " (retry next run)"}`);
11883
- } catch (err) {
11884
- debugLog(`"${item.event}" not sent: ${err instanceof Error ? err.message : String(err)} (retry next run)`);
11885
- } finally {
11886
- inFlight.delete(controller);
11887
- }
11888
- })();
11889
- pending.add(run);
11890
- void run.finally(() => pending.delete(run));
11891
- }
11892
- function capture(event, properties = {}, opts = {}) {
11893
- if (isTelemetryDisabled()) {
11894
- debugLog(`disabled \u2014 skipping "${event}"`);
11895
- return;
11896
- }
11897
- const did = opts.distinctId ?? distinctId();
11898
- const props = { ...baseProperties(), ...properties };
11899
- if (props.$insert_id === void 0) props.$insert_id = randomUUID();
11900
- const insertId = props.$insert_id;
11901
- if (opts.personProfile === false) {
11902
- props.$process_person_profile = false;
11903
- } else if (did === distinctId()) {
11904
- const set = personSet();
11905
- if (set) props.$set = set;
11906
- }
11907
- const item = {
11908
- event,
11909
- distinct_id: did,
11910
- properties: props,
11911
- timestamp: opts.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
11912
- uuid: uuidFromInsertId(insertId)
11913
- };
11914
- appendAnalyticsQueue(JSON.stringify(item));
11915
- }
11916
- var ROLLUP_WINDOW_MS = 5 * 60 * 1e3;
11917
- var ROLLUP_MAX_BATCH = 500;
11918
- function utcDay(ts) {
11919
- return new Date(ts).toISOString().slice(0, 10);
11920
- }
11921
- var PRE_AUTH_COMMANDS = /* @__PURE__ */ new Set([
11922
- "init",
11923
- "login",
11924
- "logout",
11925
- "guide",
11926
- "platforms",
11927
- "onboard",
11928
- "config",
11929
- "update",
11930
- "help"
11931
- ]);
11932
- function shouldRecord(commandPath2) {
11933
- if (isAuthenticated()) return true;
11934
- return PRE_AUTH_COMMANDS.has(commandPath2.split(" ")[0]);
11935
- }
11936
- function recordCommand(command) {
11937
- if (isTelemetryDisabled()) {
11938
- writeUsageLog([]);
11939
- return;
11940
- }
11941
- const cmdPath = commandPath(command);
11942
- if (!shouldRecord(cmdPath)) return;
11943
- const did = distinctId();
11944
- const entry = { ts: Date.now(), command: cmdPath, agent: isAgentMode(), did };
11945
- appendUsageLog(JSON.stringify(entry));
11946
- const today = utcDay(entry.ts);
11947
- const state = readUsageState();
11948
- const firstTouch = state.lastDay !== today || state.distinctId !== did;
11949
- flushUsageRollups({ force: firstTouch });
11950
- if (firstTouch) writeUsageState({ lastDay: today, distinctId: did });
11951
- }
11952
- function flushUsageRollups(opts = {}) {
11953
- if (isTelemetryDisabled()) {
11954
- writeUsageLog([]);
11955
- return;
11956
- }
11957
- const lines = claimUsageLog();
11958
- if (!lines || lines.length === 0) return;
11959
- const entries = [];
11960
- for (const line of lines) {
11961
- try {
11962
- const e = JSON.parse(line);
11963
- if (e && typeof e.ts === "number" && typeof e.command === "string" && typeof e.did === "string") {
11964
- entries.push(e);
11965
- }
11966
- } catch {
11967
- }
11968
- }
11969
- if (entries.length === 0) return;
11970
- const currentDid = entries[entries.length - 1].did;
11971
- const now = Date.now();
11972
- const groups = /* @__PURE__ */ new Map();
11973
- for (const e of entries) {
11974
- const g = groups.get(e.did);
11975
- if (g) g.push(e);
11976
- else groups.set(e.did, [e]);
11977
- }
11978
- const kept = [];
11979
- for (const [did, group] of groups) {
11980
- const due = opts.force === true || did !== currentDid || // a superseded login's batch — flush it now
11981
- group.length >= ROLLUP_MAX_BATCH || now - group[0].ts >= ROLLUP_WINDOW_MS;
11982
- if (due) emitRollup(did, group);
11983
- else kept.push(...group);
11984
- }
11985
- for (const e of kept) appendUsageLog(JSON.stringify(e));
11986
- }
11987
- function emitRollup(did, group) {
11988
- const byCommand = {};
11989
- let agentCount = 0;
11990
- for (const e of group) {
11991
- byCommand[e.command] = (byCommand[e.command] ?? 0) + 1;
11992
- if (e.agent) agentCount += 1;
11993
- }
11994
- const insertId = createHash("sha1").update(`${did}|${group.map((e) => `${e.ts}:${e.command}:${e.agent ? 1 : 0}`).join("|")}`).digest("hex");
11995
- capture(
11996
- "CLI Usage Rollup",
11997
- {
11998
- command_count: group.length,
11999
- by_command: byCommand,
12000
- agent_count: agentCount,
12001
- human_count: group.length - agentCount,
12002
- window_start: new Date(group[0].ts).toISOString(),
12003
- window_end: new Date(group[group.length - 1].ts).toISOString(),
12004
- $insert_id: insertId
12005
- },
12006
- {
12007
- distinctId: did,
12008
- timestamp: new Date(group[group.length - 1].ts).toISOString(),
12009
- // Rollups bill at the anonymous rate; the person already exists.
12010
- personProfile: false
12011
- }
12012
- );
12013
- debugLog(`rollup \u2014 ${group.length} command(s) for ${did}`);
12014
- }
12015
- function commandPath(command) {
12016
- const parts = [];
12017
- let current = command;
12018
- while (current && current.name() && current.name() !== "one") {
12019
- parts.unshift(current.name());
12020
- current = current.parent;
12021
- }
12022
- return parts.join(" ") || command.name();
12023
- }
12024
- function drainQueue() {
12025
- if (isTelemetryDisabled()) {
12026
- writeAnalyticsQueue([]);
12027
- return;
12028
- }
12029
- const now = Date.now();
12030
- const kept = [];
12031
- let changed = false;
12032
- for (const line of readAnalyticsQueue()) {
12033
- let item;
12034
- try {
12035
- item = JSON.parse(line);
12036
- } catch {
12037
- changed = true;
12038
- continue;
12039
- }
12040
- const insertId = item?.properties?.$insert_id;
12041
- if (!insertId) {
12042
- changed = true;
12043
- continue;
12044
- }
12045
- const age = now - Date.parse(item.timestamp);
12046
- const attempts = item.attempts ?? 0;
12047
- if (!(age < QUEUE_MAX_AGE_MS) || attempts >= SEND_MAX_ATTEMPTS) {
12048
- debugLog(`"${item.event}" dropped (${attempts} attempts, ${Math.round(age / 6e4)} min old)`);
12049
- changed = true;
12050
- continue;
12051
- }
12052
- if (dispatched.has(insertId)) {
12053
- kept.push(line);
12054
- continue;
12055
- }
12056
- item.attempts = attempts + 1;
12057
- if (!item.uuid) item.uuid = uuidFromInsertId(insertId);
12058
- kept.push(JSON.stringify(item));
12059
- changed = true;
12060
- send(item);
12061
- }
12062
- if (changed) writeAnalyticsQueue(kept);
12063
- }
12064
- async function flush() {
12065
- if (pending.size > 0) {
12066
- await Promise.race([
12067
- Promise.allSettled([...pending]),
12068
- new Promise((resolve) => setTimeout(resolve, EXIT_GRACE_MS))
12069
- ]);
12070
- }
12071
- for (const controller of inFlight) controller.abort();
12072
- const remaining = readAnalyticsQueue().filter((line) => {
12073
- try {
12074
- const item = JSON.parse(line);
12075
- const id = item.properties?.$insert_id;
12076
- if (!id || delivered.has(id)) return false;
12077
- return (item.attempts ?? 0) < SEND_MAX_ATTEMPTS;
12078
- } catch {
12079
- return false;
12080
- }
12081
- });
12082
- writeAnalyticsQueue(remaining);
12083
- dispatched.clear();
12084
- delivered.clear();
12085
- }
12086
- function maybeShowTelemetryNotice() {
12087
- if (isTelemetryDisabled() || isAgentMode()) return;
12088
- if (telemetryNoticeShown()) return;
12089
- markTelemetryNoticeShown();
12090
- process.stderr.write(
12091
- pc15.dim(
12092
- "One CLI collects usage analytics (which commands run, linked to your One account) to improve the product.\nNo arguments, inputs, or secrets are ever collected. Opt out anytime with ONE_NO_TELEMETRY=1.\n"
12093
- )
12094
- );
12095
- }
12096
-
12097
12232
  // src/cli.ts
12098
12233
  silenceWarningsInAgentMode();
12099
12234
  var require4 = createRequire3(import.meta.url);
@@ -12102,7 +12237,7 @@ var program = new Command();
12102
12237
  program.name("one").option("--agent", "Machine-readable JSON output (no colors, spinners, or prompts)").description(`One CLI \u2014 Connect AI agents to 600+ platforms through one interface.
12103
12238
 
12104
12239
  Setup:
12105
- one login Authenticate via browser (opens app.withone.ai)
12240
+ one login Authenticate via browser; the consent page records where this CLI is installed
12106
12241
  one logout Clear local credentials
12107
12242
  one init Set up API key + skill (add --auth browser for no-prompt agent setup)
12108
12243
  one add <platform> Connect a platform via OAuth (e.g. gmail, slack, shopify)
@@ -12312,8 +12447,8 @@ config.command("reset").description("Remove the project config for the current d
12312
12447
  return;
12313
12448
  }
12314
12449
  }
12315
- const fs14 = await import("fs");
12316
- fs14.unlinkSync(globalPath);
12450
+ const fs15 = await import("fs");
12451
+ fs15.unlinkSync(globalPath);
12317
12452
  if (isAgentMode()) {
12318
12453
  json({ deleted: true, scope: "global" });
12319
12454
  } else {
@@ -12330,15 +12465,15 @@ config.command("reset").description("Remove the project config for the current d
12330
12465
  }
12331
12466
  return;
12332
12467
  }
12333
- const fs13 = await import("fs");
12334
- const configContent = fs13.readFileSync(resolved.path, "utf-8");
12335
- fs13.unlinkSync(resolved.path);
12468
+ const fs14 = await import("fs");
12469
+ const configContent = fs14.readFileSync(resolved.path, "utf-8");
12470
+ fs14.unlinkSync(resolved.path);
12336
12471
  const next = resolveConfig();
12337
- fs13.mkdirSync(path12.dirname(resolved.path), { recursive: true });
12338
- fs13.writeFileSync(resolved.path, configContent);
12472
+ fs14.mkdirSync(path13.dirname(resolved.path), { recursive: true });
12473
+ fs14.writeFileSync(resolved.path, configContent);
12339
12474
  let fallbackLabel;
12340
12475
  if (next.scope === "project") {
12341
- fallbackLabel = `parent project config (${path12.basename(next.projectRoot)})`;
12476
+ fallbackLabel = `parent project config (${path13.basename(next.projectRoot)})`;
12342
12477
  } else if (next.scope === "global") {
12343
12478
  fallbackLabel = "global config";
12344
12479
  } else {
@@ -12347,7 +12482,7 @@ config.command("reset").description("Remove the project config for the current d
12347
12482
  if (!isAgentMode()) {
12348
12483
  const p10 = await import("@clack/prompts");
12349
12484
  const confirmed = await p10.confirm({
12350
- message: `Delete project config for ${path12.basename(resolved.projectRoot)}? Will fall back to ${fallbackLabel}.`,
12485
+ message: `Delete project config for ${path13.basename(resolved.projectRoot)}? Will fall back to ${fallbackLabel}.`,
12351
12486
  initialValue: false
12352
12487
  });
12353
12488
  if (p10.isCancel(confirmed) || !confirmed) {
@@ -12355,9 +12490,9 @@ config.command("reset").description("Remove the project config for the current d
12355
12490
  return;
12356
12491
  }
12357
12492
  }
12358
- fs13.unlinkSync(resolved.path);
12493
+ fs14.unlinkSync(resolved.path);
12359
12494
  try {
12360
- fs13.rmdirSync(path12.dirname(resolved.path));
12495
+ fs14.rmdirSync(path13.dirname(resolved.path));
12361
12496
  } catch {
12362
12497
  }
12363
12498
  if (isAgentMode()) {
@@ -12507,6 +12642,7 @@ program.command("whoami").description("Show the user, organization, and project
12507
12642
  const resolved = resolveConfig();
12508
12643
  const configScope = resolved.scope ?? "global";
12509
12644
  const apiBase = getApiBase();
12645
+ const keyName = resolved.config?.apiKey === apiKey ? resolved.config.apiKeyName : void 0;
12510
12646
  if (isAgentMode()) {
12511
12647
  json({
12512
12648
  user: whoami.user,
@@ -12514,7 +12650,8 @@ program.command("whoami").description("Show the user, organization, and project
12514
12650
  project: whoami.project,
12515
12651
  env,
12516
12652
  configScope,
12517
- apiBase
12653
+ apiBase,
12654
+ keyName
12518
12655
  });
12519
12656
  return;
12520
12657
  }
@@ -12528,6 +12665,7 @@ program.command("whoami").description("Show the user, organization, and project
12528
12665
  console.log();
12529
12666
  console.log(` ${pc16.bold(scopeDisplay)} ${pc16.dim("\xB7")} ${envLabel}`);
12530
12667
  console.log(` ${whoami.user.name} ${pc16.dim(`(${whoami.user.email})`)}`);
12668
+ if (keyName) console.log(` ${pc16.dim("Key:")} ${keyName}`);
12531
12669
  if (whoami.organization) console.log(` ${pc16.dim("Org:")} ${whoami.organization.name} ${pc16.dim(`(${whoami.organization.id})`)}`);
12532
12670
  if (whoami.project) console.log(` ${pc16.dim("Project:")} ${whoami.project.name} ${pc16.dim(`(${whoami.project.id})`)}`);
12533
12671
  console.log();