yapout 0.8.0 → 0.10.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.
Files changed (2) hide show
  1. package/dist/index.js +606 -354
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,16 +7,16 @@ import {
7
7
  } from "./chunk-DLHFRTYU.js";
8
8
 
9
9
  // src/index.ts
10
- import { Command as Command16 } from "commander";
10
+ import { Command as Command17 } from "commander";
11
11
 
12
12
  // src/commands/login.ts
13
- import { Command } from "commander";
14
- import http from "http";
15
- import { createHash } from "crypto";
16
- import { hostname, userInfo } from "os";
17
- import chalk from "chalk";
13
+ import { Command as Command2 } from "commander";
14
+ import http2 from "http";
15
+ import { createHash as createHash2 } from "crypto";
16
+ import { hostname as hostname2, userInfo as userInfo2 } from "os";
17
+ import chalk3 from "chalk";
18
18
  import open from "open";
19
- import { anyApi as anyApi2 } from "convex/server";
19
+ import { anyApi as anyApi3 } from "convex/server";
20
20
 
21
21
  // src/lib/config.ts
22
22
  import { homedir } from "os";
@@ -521,8 +521,267 @@ function registerProtocolHandler() {
521
521
  }
522
522
  }
523
523
 
524
+ // src/commands/serve.ts
525
+ import { Command } from "commander";
526
+ import http from "http";
527
+ import { createHash } from "crypto";
528
+ import { hostname, userInfo, platform as platform2, type } from "os";
529
+ import { join as join3 } from "path";
530
+ import {
531
+ readFileSync as readFileSync2,
532
+ writeFileSync as writeFileSync3,
533
+ existsSync as existsSync2,
534
+ unlinkSync as unlinkSync3,
535
+ openSync
536
+ } from "fs";
537
+ import { spawn } from "child_process";
538
+ import chalk2 from "chalk";
539
+ import { anyApi as anyApi2 } from "convex/server";
540
+
541
+ // src/lib/auth.ts
542
+ import chalk from "chalk";
543
+ function requireAuth() {
544
+ const creds = readCredentials();
545
+ if (!creds) {
546
+ console.error(
547
+ chalk.red("Not logged in.") + " Run " + chalk.cyan("yapout login") + " first."
548
+ );
549
+ process.exit(1);
550
+ }
551
+ if (Date.now() > creds.expiresAt) {
552
+ console.error(
553
+ chalk.red("Session expired.") + " Run " + chalk.cyan("yapout login") + " to re-authenticate."
554
+ );
555
+ process.exit(1);
556
+ }
557
+ return creds;
558
+ }
559
+
560
+ // src/commands/serve.ts
561
+ var CLI_VERSION = "0.10.0";
562
+ var DEFAULT_PORT = 7777;
563
+ var PORT_RANGE = 10;
564
+ var HEARTBEAT_MS = 3e4;
565
+ var PID_FILE = join3(getYapoutDir(), "serve.pid");
566
+ var PORT_FILE = join3(getYapoutDir(), "serve.port");
567
+ var LOG_FILE = join3(getYapoutDir(), "serve.log");
568
+ var ALLOWED_ORIGINS = [
569
+ "https://yapout.com",
570
+ "https://www.yapout.com",
571
+ "https://yapout.vercel.app",
572
+ // Local dev / sandbox ports — wide range so any worktree's auto-allocated
573
+ // Next.js port works without configuration.
574
+ ...Array.from({ length: 20 }, (_, i) => `http://localhost:${3e3 + i}`),
575
+ ...Array.from({ length: 20 }, (_, i) => `http://127.0.0.1:${3e3 + i}`)
576
+ ];
577
+ function computeDeviceId() {
578
+ return createHash("sha256").update(hostname() + userInfo().username).digest("hex").slice(0, 16);
579
+ }
580
+ function corsHeadersFor(origin) {
581
+ const allowOrigin = origin && ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0];
582
+ return {
583
+ "Access-Control-Allow-Origin": allowOrigin,
584
+ "Access-Control-Allow-Methods": "GET, OPTIONS",
585
+ "Access-Control-Allow-Headers": "Content-Type",
586
+ "Access-Control-Allow-Private-Network": "true",
587
+ Vary: "Origin"
588
+ };
589
+ }
590
+ function startServer(payload) {
591
+ const server = http.createServer((req, res) => {
592
+ const origin = req.headers.origin;
593
+ const headers = corsHeadersFor(origin);
594
+ if (req.method === "OPTIONS") {
595
+ res.writeHead(204, headers);
596
+ res.end();
597
+ return;
598
+ }
599
+ if (req.method === "GET" && req.url === "/device") {
600
+ res.writeHead(200, {
601
+ ...headers,
602
+ "Content-Type": "application/json",
603
+ "Cache-Control": "no-store"
604
+ });
605
+ res.end(JSON.stringify(payload));
606
+ return;
607
+ }
608
+ res.writeHead(404, headers);
609
+ res.end();
610
+ });
611
+ return new Promise((resolve12, reject) => {
612
+ let attempt = 0;
613
+ const tryListen = () => {
614
+ const port = DEFAULT_PORT + attempt;
615
+ const onError = (err) => {
616
+ server.removeListener("error", onError);
617
+ if (err.code === "EADDRINUSE" && attempt < PORT_RANGE - 1) {
618
+ attempt++;
619
+ tryListen();
620
+ } else {
621
+ reject(err);
622
+ }
623
+ };
624
+ server.once("error", onError);
625
+ server.listen(port, "127.0.0.1", () => {
626
+ server.removeListener("error", onError);
627
+ resolve12({
628
+ port,
629
+ close: () => server.close()
630
+ });
631
+ });
632
+ };
633
+ tryListen();
634
+ });
635
+ }
636
+ async function runForeground() {
637
+ const creds = requireAuth();
638
+ const deviceId = computeDeviceId();
639
+ const payload = {
640
+ deviceId,
641
+ name: hostname(),
642
+ hostname: hostname(),
643
+ platform: `${type()} ${platform2()}`,
644
+ cliVersion: CLI_VERSION
645
+ };
646
+ const { port } = await startServer(payload);
647
+ writeFileSync3(PORT_FILE, String(port));
648
+ writeFileSync3(PID_FILE, String(process.pid));
649
+ console.log(chalk2.green(`yapout serve listening on http://127.0.0.1:${port}`));
650
+ console.log(chalk2.dim(`Device: ${payload.name} (${deviceId})`));
651
+ console.log(chalk2.dim("Press Ctrl-C to stop."));
652
+ const client = createConvexClient(creds.token);
653
+ const heartbeat = async () => {
654
+ try {
655
+ await client.mutation(anyApi2.functions.devices.heartbeatDevice, {
656
+ deviceId
657
+ });
658
+ } catch {
659
+ }
660
+ };
661
+ client.mutation(anyApi2.functions.devices.registerDevice, {
662
+ deviceId,
663
+ name: payload.name,
664
+ cliVersion: CLI_VERSION,
665
+ machineHostname: payload.hostname
666
+ }).catch(() => {
667
+ });
668
+ void heartbeat();
669
+ const interval = setInterval(heartbeat, HEARTBEAT_MS);
670
+ const shutdown = async () => {
671
+ clearInterval(interval);
672
+ try {
673
+ await client.mutation(anyApi2.functions.devices.markDeviceOffline, {
674
+ deviceId
675
+ });
676
+ } catch {
677
+ }
678
+ try {
679
+ if (existsSync2(PID_FILE)) unlinkSync3(PID_FILE);
680
+ } catch {
681
+ }
682
+ try {
683
+ if (existsSync2(PORT_FILE)) unlinkSync3(PORT_FILE);
684
+ } catch {
685
+ }
686
+ process.exit(0);
687
+ };
688
+ process.on("SIGINT", () => {
689
+ void shutdown();
690
+ });
691
+ process.on("SIGTERM", () => {
692
+ void shutdown();
693
+ });
694
+ await new Promise(() => {
695
+ });
696
+ }
697
+ function isProcessRunning(pid) {
698
+ try {
699
+ process.kill(pid, 0);
700
+ return true;
701
+ } catch {
702
+ return false;
703
+ }
704
+ }
705
+ function readPid() {
706
+ if (!existsSync2(PID_FILE)) return null;
707
+ const raw = readFileSync2(PID_FILE, "utf-8").trim();
708
+ const pid = parseInt(raw, 10);
709
+ return Number.isFinite(pid) ? pid : null;
710
+ }
711
+ function readPort() {
712
+ if (!existsSync2(PORT_FILE)) return null;
713
+ const raw = readFileSync2(PORT_FILE, "utf-8").trim();
714
+ const port = parseInt(raw, 10);
715
+ return Number.isFinite(port) ? port : null;
716
+ }
717
+ function spawnServeDaemon(argv0) {
718
+ const existingPid = readPid();
719
+ if (existingPid && isProcessRunning(existingPid)) return;
720
+ const logFd = openSync(LOG_FILE, "a");
721
+ const child = spawn(process.execPath, [argv0, "serve"], {
722
+ detached: true,
723
+ stdio: ["ignore", logFd, logFd],
724
+ env: process.env
725
+ });
726
+ child.unref();
727
+ }
728
+ var serveCommand = new Command("serve").description(
729
+ "Run the local device discovery server (auto-started by `yapout login`)"
730
+ ).option("--status", "Check if the server is running").option("--stop", "Stop the running server").action(async (opts) => {
731
+ if (opts.status) {
732
+ const pid = readPid();
733
+ const port = readPort();
734
+ if (pid && isProcessRunning(pid)) {
735
+ console.log(
736
+ chalk2.green(`yapout serve is running`) + chalk2.dim(` (PID ${pid}, port ${port ?? "?"})`)
737
+ );
738
+ } else {
739
+ if (pid) unlinkSync3(PID_FILE);
740
+ console.log(chalk2.dim("yapout serve is not running"));
741
+ }
742
+ return;
743
+ }
744
+ if (opts.stop) {
745
+ const pid = readPid();
746
+ if (!pid) {
747
+ console.log(chalk2.dim("yapout serve is not running"));
748
+ return;
749
+ }
750
+ try {
751
+ process.kill(pid, "SIGTERM");
752
+ console.log(chalk2.green(`Stopped yapout serve`) + chalk2.dim(` (PID ${pid})`));
753
+ } catch {
754
+ console.log(chalk2.dim("Server already stopped"));
755
+ }
756
+ try {
757
+ unlinkSync3(PID_FILE);
758
+ } catch {
759
+ }
760
+ try {
761
+ unlinkSync3(PORT_FILE);
762
+ } catch {
763
+ }
764
+ return;
765
+ }
766
+ const existingPid = readPid();
767
+ if (existingPid && !isProcessRunning(existingPid)) {
768
+ try {
769
+ unlinkSync3(PID_FILE);
770
+ } catch {
771
+ }
772
+ } else if (existingPid && isProcessRunning(existingPid)) {
773
+ console.log(
774
+ chalk2.dim(
775
+ `yapout serve is already running (PID ${existingPid}). Use --stop first.`
776
+ )
777
+ );
778
+ process.exit(1);
779
+ }
780
+ await runForeground();
781
+ });
782
+
524
783
  // src/commands/login.ts
525
- var CLI_VERSION = "0.8.0";
784
+ var CLI_VERSION2 = "0.10.0";
526
785
  function safeReturnTo(raw) {
527
786
  if (!raw) return null;
528
787
  try {
@@ -541,7 +800,7 @@ function startCallbackServer() {
541
800
  resolveData = res;
542
801
  rejectData = rej;
543
802
  });
544
- const server = http.createServer((req, res) => {
803
+ const server = http2.createServer((req, res) => {
545
804
  const url = new URL(req.url, `http://localhost`);
546
805
  if (url.pathname === "/callback") {
547
806
  const token = url.searchParams.get("token");
@@ -593,14 +852,21 @@ function startCallbackServer() {
593
852
  }, 12e4);
594
853
  });
595
854
  }
596
- var loginCommand = new Command("login").description("Authenticate with yapout").action(async () => {
597
- console.log(chalk.dim("Starting authentication..."));
855
+ var loginCommand = new Command2("login").description("Authenticate with yapout").action(async () => {
856
+ console.log(chalk3.dim("Starting authentication..."));
598
857
  const { port, data } = await startCallbackServer();
599
858
  const appUrl = getAppUrl();
600
- const authUrl = `${appUrl}/auth/cli?port=${port}`;
601
- console.log(chalk.dim(`Opening browser...`));
859
+ const deviceId = createHash2("sha256").update(hostname2() + userInfo2().username).digest("hex").slice(0, 16);
860
+ const authParams = new URLSearchParams({
861
+ port: String(port),
862
+ deviceId,
863
+ cliVersion: CLI_VERSION2,
864
+ hostname: hostname2()
865
+ });
866
+ const authUrl = `${appUrl}/auth/cli?${authParams.toString()}`;
867
+ console.log(chalk3.dim(`Opening browser...`));
602
868
  await open(authUrl);
603
- console.log(chalk.dim("Waiting for authentication in browser..."));
869
+ console.log(chalk3.dim("Waiting for authentication in browser..."));
604
870
  try {
605
871
  const result = await data;
606
872
  const creds = {
@@ -615,74 +881,59 @@ var loginCommand = new Command("login").description("Authenticate with yapout").
615
881
  Math.round((result.expiresAt - Date.now()) / 864e5)
616
882
  );
617
883
  console.log(
618
- chalk.green("Logged in as ") + chalk.bold(result.email) + chalk.dim(
884
+ chalk3.green("Logged in as ") + chalk3.bold(result.email) + chalk3.dim(
619
885
  ` (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
620
886
  )
621
887
  );
622
888
  try {
623
889
  const client = createConvexClient(creds.token);
624
- const deviceId = createHash("sha256").update(hostname() + userInfo().username).digest("hex").slice(0, 16);
625
- await client.mutation(anyApi2.functions.devices.registerDevice, {
890
+ await client.mutation(anyApi3.functions.devices.registerDevice, {
626
891
  deviceId,
627
- name: hostname(),
628
- cliVersion: CLI_VERSION
892
+ name: hostname2(),
893
+ cliVersion: CLI_VERSION2
629
894
  });
630
895
  } catch {
631
- console.warn(chalk.dim("Note: Could not register device. This is non-fatal."));
896
+ console.warn(chalk3.dim("Note: Could not register device. This is non-fatal."));
632
897
  }
633
898
  try {
634
899
  registerProtocolHandler();
635
900
  console.log(
636
- chalk.dim("Registered yapout:// protocol handler")
901
+ chalk3.dim("Registered yapout:// protocol handler")
637
902
  );
638
903
  } catch {
639
904
  }
905
+ try {
906
+ spawnServeDaemon(process.argv[1]);
907
+ console.log(chalk3.dim("Started yapout serve in the background"));
908
+ } catch {
909
+ }
640
910
  process.exit(0);
641
911
  } catch (err) {
642
- console.error(chalk.red(err.message));
912
+ console.error(chalk3.red(err.message));
643
913
  process.exit(1);
644
914
  }
645
915
  });
646
916
 
647
917
  // src/commands/logout.ts
648
- import { Command as Command2 } from "commander";
649
- import chalk2 from "chalk";
650
- var logoutCommand = new Command2("logout").description("Log out of yapout").action(() => {
918
+ import { Command as Command3 } from "commander";
919
+ import chalk4 from "chalk";
920
+ var logoutCommand = new Command3("logout").description("Log out of yapout").action(() => {
651
921
  deleteCredentials();
652
- console.log(chalk2.green("Logged out."));
922
+ console.log(chalk4.green("Logged out."));
653
923
  });
654
924
 
655
925
  // src/commands/link.ts
656
- import { Command as Command3 } from "commander";
657
- import { resolve as resolve2, join as join3 } from "path";
926
+ import { Command as Command4 } from "commander";
927
+ import { resolve as resolve2, join as join4 } from "path";
658
928
  import {
659
- existsSync as existsSync2,
929
+ existsSync as existsSync3,
660
930
  mkdirSync as mkdirSync3,
661
- readFileSync as readFileSync2,
662
- writeFileSync as writeFileSync3,
931
+ readFileSync as readFileSync3,
932
+ writeFileSync as writeFileSync4,
663
933
  appendFileSync
664
934
  } from "fs";
665
- import { hostname as hostname2 } from "os";
666
- import chalk4 from "chalk";
667
-
668
- // src/lib/auth.ts
669
- import chalk3 from "chalk";
670
- function requireAuth() {
671
- const creds = readCredentials();
672
- if (!creds) {
673
- console.error(
674
- chalk3.red("Not logged in.") + " Run " + chalk3.cyan("yapout login") + " first."
675
- );
676
- process.exit(1);
677
- }
678
- if (Date.now() > creds.expiresAt) {
679
- console.error(
680
- chalk3.red("Session expired.") + " Run " + chalk3.cyan("yapout login") + " to re-authenticate."
681
- );
682
- process.exit(1);
683
- }
684
- return creds;
685
- }
935
+ import { hostname as hostname3 } from "os";
936
+ import chalk5 from "chalk";
686
937
 
687
938
  // src/lib/prompts.ts
688
939
  import { select } from "@inquirer/prompts";
@@ -734,7 +985,7 @@ branch_prefix: feat
734
985
  # {{ticket.linearTicketId}}, {{ticket.id}}
735
986
  # commit_template: "{{ticket.type}}({{ticket.linearTicketId}}): {{ticket.title}}"
736
987
  `;
737
- var linkCommand = new Command3("link").description("Link the current directory to a yapout project").action(async () => {
988
+ var linkCommand = new Command4("link").description("Link the current directory to a yapout project").action(async () => {
738
989
  const creds = requireAuth();
739
990
  const cwd = resolveRepoRoot(resolve2(process.cwd()));
740
991
  const client = createConvexClient(creds.token);
@@ -746,25 +997,25 @@ var linkCommand = new Command3("link").description("Link the current directory t
746
997
  );
747
998
  } catch (err) {
748
999
  console.error(
749
- chalk4.red("Failed to fetch projects."),
1000
+ chalk5.red("Failed to fetch projects."),
750
1001
  err.message
751
1002
  );
752
1003
  process.exit(1);
753
1004
  }
754
1005
  if (projects.length === 0) {
755
1006
  console.error(
756
- chalk4.yellow("No projects found.") + " Create one at " + chalk4.cyan(`${getAppUrl()}/dashboard`)
1007
+ chalk5.yellow("No projects found.") + " Create one at " + chalk5.cyan(`${getAppUrl()}/dashboard`)
757
1008
  );
758
1009
  process.exit(1);
759
1010
  }
760
1011
  const selected = await pickProject(projects);
761
- const device = getOrCreateDeviceIdentity(hostname2());
1012
+ const device = getOrCreateDeviceIdentity(hostname3());
762
1013
  try {
763
1014
  await client.mutation(anyApi.functions.devices.registerDevice, {
764
1015
  deviceId: device.deviceId,
765
1016
  name: device.name,
766
1017
  cliVersion: getCliVersion(),
767
- machineHostname: hostname2()
1018
+ machineHostname: hostname3()
768
1019
  });
769
1020
  await client.mutation(anyApi.functions.projectCheckouts.linkCheckout, {
770
1021
  projectId: selected.id,
@@ -773,7 +1024,7 @@ var linkCommand = new Command3("link").description("Link the current directory t
773
1024
  });
774
1025
  } catch (err) {
775
1026
  console.warn(
776
- chalk4.yellow("Warning: failed to record this checkout \u2014 "),
1027
+ chalk5.yellow("Warning: failed to record this checkout \u2014 "),
777
1028
  err.message
778
1029
  );
779
1030
  }
@@ -782,17 +1033,17 @@ var linkCommand = new Command3("link").description("Link the current directory t
782
1033
  projectName: selected.name,
783
1034
  linkedAt: Date.now()
784
1035
  });
785
- const yapoutDir = join3(cwd, ".yapout");
786
- if (!existsSync2(yapoutDir)) {
1036
+ const yapoutDir = join4(cwd, ".yapout");
1037
+ if (!existsSync3(yapoutDir)) {
787
1038
  mkdirSync3(yapoutDir, { recursive: true });
788
1039
  }
789
- const configPath = join3(yapoutDir, "config.yml");
790
- if (!existsSync2(configPath)) {
791
- writeFileSync3(configPath, CONFIG_YAML_CONTENT);
1040
+ const configPath = join4(yapoutDir, "config.yml");
1041
+ if (!existsSync3(configPath)) {
1042
+ writeFileSync4(configPath, CONFIG_YAML_CONTENT);
792
1043
  }
793
- const gitignorePath = join3(cwd, ".gitignore");
794
- if (existsSync2(gitignorePath)) {
795
- const content = readFileSync2(gitignorePath, "utf-8");
1044
+ const gitignorePath = join4(cwd, ".gitignore");
1045
+ if (existsSync3(gitignorePath)) {
1046
+ const content = readFileSync3(gitignorePath, "utf-8");
796
1047
  if (!content.includes(".yapout/")) {
797
1048
  appendFileSync(
798
1049
  gitignorePath,
@@ -800,13 +1051,13 @@ var linkCommand = new Command3("link").description("Link the current directory t
800
1051
  );
801
1052
  }
802
1053
  } else {
803
- writeFileSync3(gitignorePath, "# yapout local config\n.yapout/\n");
1054
+ writeFileSync4(gitignorePath, "# yapout local config\n.yapout/\n");
804
1055
  }
805
- const mcpPath = join3(cwd, ".mcp.json");
1056
+ const mcpPath = join4(cwd, ".mcp.json");
806
1057
  let mcpConfig = {};
807
- if (existsSync2(mcpPath)) {
1058
+ if (existsSync3(mcpPath)) {
808
1059
  try {
809
- mcpConfig = JSON.parse(readFileSync2(mcpPath, "utf-8"));
1060
+ mcpConfig = JSON.parse(readFileSync3(mcpPath, "utf-8"));
810
1061
  } catch {
811
1062
  }
812
1063
  }
@@ -815,17 +1066,17 @@ var linkCommand = new Command3("link").description("Link the current directory t
815
1066
  command: "yapout",
816
1067
  args: ["mcp-server"]
817
1068
  };
818
- writeFileSync3(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1069
+ writeFileSync4(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
819
1070
  const label = selected.githubRepoFullName ? `${selected.name} (${selected.githubRepoFullName})` : selected.name;
820
1071
  const orgSuffix = selected.org ? ` in ${selected.org.name}` : "";
821
1072
  console.log(
822
- chalk4.green(`Linked to ${label}${orgSuffix}.`) + " Claude Code will discover yapout tools automatically."
1073
+ chalk5.green(`Linked to ${label}${orgSuffix}.`) + " Claude Code will discover yapout tools automatically."
823
1074
  );
824
1075
  });
825
1076
  function getCliVersion() {
826
1077
  try {
827
1078
  const pkg = JSON.parse(
828
- readFileSync2(join3(import.meta.dirname, "..", "package.json"), "utf-8")
1079
+ readFileSync3(join4(import.meta.dirname, "..", "package.json"), "utf-8")
829
1080
  );
830
1081
  return pkg.version ?? "unknown";
831
1082
  } catch {
@@ -834,15 +1085,15 @@ function getCliVersion() {
834
1085
  }
835
1086
 
836
1087
  // src/commands/unlink.ts
837
- import { Command as Command4 } from "commander";
838
- import { resolve as resolve3, join as join4 } from "path";
839
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4, rmSync } from "fs";
840
- import chalk5 from "chalk";
841
- var unlinkCommand = new Command4("unlink").description("Unlink the current directory from its yapout project").action(async () => {
1088
+ import { Command as Command5 } from "commander";
1089
+ import { resolve as resolve3, join as join5 } from "path";
1090
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync5, rmSync } from "fs";
1091
+ import chalk6 from "chalk";
1092
+ var unlinkCommand = new Command5("unlink").description("Unlink the current directory from its yapout project").action(async () => {
842
1093
  const cwd = resolve3(process.cwd());
843
1094
  const mapping = getProjectMapping(cwd);
844
1095
  if (!mapping) {
845
- console.error(chalk5.yellow("No project linked to this directory."));
1096
+ console.error(chalk6.yellow("No project linked to this directory."));
846
1097
  process.exit(1);
847
1098
  }
848
1099
  const device = readDeviceIdentity();
@@ -856,26 +1107,26 @@ var unlinkCommand = new Command4("unlink").description("Unlink the current direc
856
1107
  });
857
1108
  } catch (err) {
858
1109
  console.warn(
859
- chalk5.yellow("Warning: failed to update server \u2014 "),
1110
+ chalk6.yellow("Warning: failed to update server \u2014 "),
860
1111
  err.message
861
1112
  );
862
1113
  }
863
1114
  }
864
1115
  removeProjectMapping(cwd);
865
- const yapoutDir = join4(cwd, ".yapout");
866
- if (existsSync3(yapoutDir)) {
1116
+ const yapoutDir = join5(cwd, ".yapout");
1117
+ if (existsSync4(yapoutDir)) {
867
1118
  rmSync(yapoutDir, { recursive: true });
868
1119
  }
869
- const mcpPath = join4(cwd, ".mcp.json");
870
- if (existsSync3(mcpPath)) {
1120
+ const mcpPath = join5(cwd, ".mcp.json");
1121
+ if (existsSync4(mcpPath)) {
871
1122
  try {
872
- const mcpConfig = JSON.parse(readFileSync3(mcpPath, "utf-8"));
1123
+ const mcpConfig = JSON.parse(readFileSync4(mcpPath, "utf-8"));
873
1124
  if (mcpConfig.mcpServers?.yapout) {
874
1125
  delete mcpConfig.mcpServers.yapout;
875
1126
  if (Object.keys(mcpConfig.mcpServers).length === 0) {
876
1127
  rmSync(mcpPath);
877
1128
  } else {
878
- writeFileSync4(
1129
+ writeFileSync5(
879
1130
  mcpPath,
880
1131
  JSON.stringify(mcpConfig, null, 2) + "\n"
881
1132
  );
@@ -884,23 +1135,23 @@ var unlinkCommand = new Command4("unlink").description("Unlink the current direc
884
1135
  } catch {
885
1136
  }
886
1137
  }
887
- console.log(chalk5.green("Unlinked."));
1138
+ console.log(chalk6.green("Unlinked."));
888
1139
  });
889
1140
 
890
1141
  // src/commands/status.ts
891
- import { Command as Command5 } from "commander";
1142
+ import { Command as Command6 } from "commander";
892
1143
  import { resolve as resolve4 } from "path";
893
- import chalk6 from "chalk";
894
- var statusCommand = new Command5("status").description("Show yapout status for this directory").action(() => {
895
- console.log(chalk6.bold("yapout status\n"));
1144
+ import chalk7 from "chalk";
1145
+ var statusCommand = new Command6("status").description("Show yapout status for this directory").action(() => {
1146
+ console.log(chalk7.bold("yapout status\n"));
896
1147
  const creds = readCredentials();
897
1148
  if (!creds) {
898
1149
  console.log(
899
- ` Auth: ${chalk6.red("Not logged in.")} Run ${chalk6.cyan("yapout login")}.`
1150
+ ` Auth: ${chalk7.red("Not logged in.")} Run ${chalk7.cyan("yapout login")}.`
900
1151
  );
901
1152
  } else if (Date.now() > creds.expiresAt) {
902
1153
  console.log(
903
- ` Auth: ${chalk6.red("Session expired.")} Run ${chalk6.cyan("yapout login")}.`
1154
+ ` Auth: ${chalk7.red("Session expired.")} Run ${chalk7.cyan("yapout login")}.`
904
1155
  );
905
1156
  } else {
906
1157
  const daysLeft = Math.max(
@@ -908,35 +1159,35 @@ var statusCommand = new Command5("status").description("Show yapout status for t
908
1159
  Math.round((creds.expiresAt - Date.now()) / 864e5)
909
1160
  );
910
1161
  console.log(
911
- ` Auth: ${chalk6.green(creds.email)} (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
1162
+ ` Auth: ${chalk7.green(creds.email)} (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
912
1163
  );
913
1164
  }
914
1165
  const cwd = resolve4(process.cwd());
915
1166
  const mapping = getProjectMapping(cwd);
916
1167
  if (!mapping) {
917
1168
  console.log(
918
- ` Project: ${chalk6.yellow("No project linked.")} Run ${chalk6.cyan("yapout link")} in a repo.`
1169
+ ` Project: ${chalk7.yellow("No project linked.")} Run ${chalk7.cyan("yapout link")} in a repo.`
919
1170
  );
920
1171
  } else {
921
- console.log(` Project: ${chalk6.green(mapping.projectName)}`);
1172
+ console.log(` Project: ${chalk7.green(mapping.projectName)}`);
922
1173
  }
923
- console.log(` Daemon: ${chalk6.dim("not running")}`);
924
- console.log(` Work: ${chalk6.dim("no active tickets")}`);
1174
+ console.log(` Daemon: ${chalk7.dim("not running")}`);
1175
+ console.log(` Work: ${chalk7.dim("no active tickets")}`);
925
1176
  console.log();
926
1177
  });
927
1178
 
928
1179
  // src/commands/init.ts
929
- import { Command as Command6 } from "commander";
930
- import { resolve as resolve5, join as join5 } from "path";
1180
+ import { Command as Command7 } from "commander";
1181
+ import { resolve as resolve5, join as join6 } from "path";
931
1182
  import {
932
- existsSync as existsSync4,
1183
+ existsSync as existsSync5,
933
1184
  mkdirSync as mkdirSync4,
934
- writeFileSync as writeFileSync5,
935
- readFileSync as readFileSync4,
1185
+ writeFileSync as writeFileSync6,
1186
+ readFileSync as readFileSync5,
936
1187
  appendFileSync as appendFileSync2
937
1188
  } from "fs";
938
- import { hostname as hostname3 } from "os";
939
- import chalk7 from "chalk";
1189
+ import { hostname as hostname4 } from "os";
1190
+ import chalk8 from "chalk";
940
1191
  var CONFIG_YAML_CONTENT2 = `# yapout local configuration
941
1192
  # See: https://docs.yapout.dev/cli/config
942
1193
 
@@ -961,7 +1212,7 @@ branch_prefix: feat
961
1212
  # {{ticket.linearTicketId}}, {{ticket.id}}
962
1213
  # commit_template: "{{ticket.type}}({{ticket.linearTicketId}}): {{ticket.title}}"
963
1214
  `;
964
- var initCommand = new Command6("init").description("Create a yapout project from the current repo and link it").argument("[name]", "Project name (defaults to repo name)").option("--org <slug>", "Org slug to create the project in (skips picker)").action(async (name, options) => {
1215
+ var initCommand = new Command7("init").description("Create a yapout project from the current repo and link it").argument("[name]", "Project name (defaults to repo name)").option("--org <slug>", "Org slug to create the project in (skips picker)").action(async (name, options) => {
965
1216
  const creds = requireAuth();
966
1217
  const cwd = resolveRepoRoot(resolve5(process.cwd()));
967
1218
  let repoFullName;
@@ -971,7 +1222,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
971
1222
  defaultBranch = getDefaultBranch(cwd);
972
1223
  } catch (err) {
973
1224
  console.error(
974
- chalk7.red("Not a git repo with a GitHub remote."),
1225
+ chalk8.red("Not a git repo with a GitHub remote."),
975
1226
  err.message
976
1227
  );
977
1228
  process.exit(1);
@@ -986,14 +1237,14 @@ var initCommand = new Command6("init").description("Create a yapout project from
986
1237
  );
987
1238
  } catch (err) {
988
1239
  console.error(
989
- chalk7.red("Failed to load your orgs."),
1240
+ chalk8.red("Failed to load your orgs."),
990
1241
  err.message
991
1242
  );
992
1243
  process.exit(1);
993
1244
  }
994
1245
  if (!orgs || orgs.length === 0) {
995
1246
  console.error(
996
- chalk7.red(
1247
+ chalk8.red(
997
1248
  "You aren't a member of any org. Sign in to the web app once to create your personal org, then re-run."
998
1249
  )
999
1250
  );
@@ -1005,10 +1256,10 @@ var initCommand = new Command6("init").description("Create a yapout project from
1005
1256
  const match = orgs.find((o) => o.org.slug === options.org);
1006
1257
  if (!match) {
1007
1258
  console.error(
1008
- chalk7.red(`Org "${options.org}" not found among your memberships.`)
1259
+ chalk8.red(`Org "${options.org}" not found among your memberships.`)
1009
1260
  );
1010
1261
  console.error(
1011
- chalk7.dim(
1262
+ chalk8.dim(
1012
1263
  "Available: " + orgs.map((o) => o.org.slug).join(", ")
1013
1264
  )
1014
1265
  );
@@ -1020,7 +1271,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1020
1271
  chosenOrgId = orgs[0].org._id;
1021
1272
  chosenOrgName = orgs[0].org.name;
1022
1273
  console.log(
1023
- chalk7.dim(`Creating in `) + chalk7.cyan(chosenOrgName)
1274
+ chalk8.dim(`Creating in `) + chalk8.cyan(chosenOrgName)
1024
1275
  );
1025
1276
  } else {
1026
1277
  const picked = await pickOrg(
@@ -1034,17 +1285,17 @@ var initCommand = new Command6("init").description("Create a yapout project from
1034
1285
  chosenOrgId = picked.id;
1035
1286
  chosenOrgName = picked.name;
1036
1287
  }
1037
- const device = getOrCreateDeviceIdentity(hostname3());
1288
+ const device = getOrCreateDeviceIdentity(hostname4());
1038
1289
  try {
1039
1290
  await client.mutation(anyApi.functions.devices.registerDevice, {
1040
1291
  deviceId: device.deviceId,
1041
1292
  name: device.name,
1042
1293
  cliVersion: getCliVersion2(),
1043
- machineHostname: hostname3()
1294
+ machineHostname: hostname4()
1044
1295
  });
1045
1296
  } catch (err) {
1046
1297
  console.warn(
1047
- chalk7.yellow("Warning: device registration failed \u2014 "),
1298
+ chalk8.yellow("Warning: device registration failed \u2014 "),
1048
1299
  err.message
1049
1300
  );
1050
1301
  }
@@ -1061,7 +1312,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1061
1312
  );
1062
1313
  } catch (err) {
1063
1314
  console.error(
1064
- chalk7.red("Failed to create project."),
1315
+ chalk8.red("Failed to create project."),
1065
1316
  err.message
1066
1317
  );
1067
1318
  process.exit(1);
@@ -1074,7 +1325,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1074
1325
  });
1075
1326
  } catch (err) {
1076
1327
  console.warn(
1077
- chalk7.yellow("Warning: failed to record project checkout \u2014 "),
1328
+ chalk8.yellow("Warning: failed to record project checkout \u2014 "),
1078
1329
  err.message
1079
1330
  );
1080
1331
  }
@@ -1083,15 +1334,15 @@ var initCommand = new Command6("init").description("Create a yapout project from
1083
1334
  projectName: result.projectName,
1084
1335
  linkedAt: Date.now()
1085
1336
  });
1086
- const yapoutDir = join5(cwd, ".yapout");
1087
- if (!existsSync4(yapoutDir)) mkdirSync4(yapoutDir, { recursive: true });
1088
- const configPath = join5(yapoutDir, "config.yml");
1089
- if (!existsSync4(configPath)) {
1090
- writeFileSync5(configPath, CONFIG_YAML_CONTENT2);
1091
- }
1092
- const gitignorePath = join5(cwd, ".gitignore");
1093
- if (existsSync4(gitignorePath)) {
1094
- const content = readFileSync4(gitignorePath, "utf-8");
1337
+ const yapoutDir = join6(cwd, ".yapout");
1338
+ if (!existsSync5(yapoutDir)) mkdirSync4(yapoutDir, { recursive: true });
1339
+ const configPath = join6(yapoutDir, "config.yml");
1340
+ if (!existsSync5(configPath)) {
1341
+ writeFileSync6(configPath, CONFIG_YAML_CONTENT2);
1342
+ }
1343
+ const gitignorePath = join6(cwd, ".gitignore");
1344
+ if (existsSync5(gitignorePath)) {
1345
+ const content = readFileSync5(gitignorePath, "utf-8");
1095
1346
  if (!content.includes(".yapout/")) {
1096
1347
  appendFileSync2(
1097
1348
  gitignorePath,
@@ -1099,11 +1350,11 @@ var initCommand = new Command6("init").description("Create a yapout project from
1099
1350
  );
1100
1351
  }
1101
1352
  }
1102
- const mcpPath = join5(cwd, ".mcp.json");
1353
+ const mcpPath = join6(cwd, ".mcp.json");
1103
1354
  let mcpConfig = {};
1104
- if (existsSync4(mcpPath)) {
1355
+ if (existsSync5(mcpPath)) {
1105
1356
  try {
1106
- mcpConfig = JSON.parse(readFileSync4(mcpPath, "utf-8"));
1357
+ mcpConfig = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1107
1358
  } catch {
1108
1359
  }
1109
1360
  }
@@ -1112,20 +1363,20 @@ var initCommand = new Command6("init").description("Create a yapout project from
1112
1363
  command: "yapout",
1113
1364
  args: ["mcp-server"]
1114
1365
  };
1115
- writeFileSync5(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1366
+ writeFileSync6(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1116
1367
  console.log(
1117
- chalk7.green(`Created project "${result.projectName}"`) + chalk7.dim(
1368
+ chalk8.green(`Created project "${result.projectName}"`) + chalk8.dim(
1118
1369
  ` in ${chosenOrgName} (${repoFullName}, branch: ${defaultBranch})`
1119
1370
  )
1120
1371
  );
1121
1372
  console.log(
1122
- chalk7.dim("Run ") + chalk7.cyan("yapout_compact") + chalk7.dim(" in Claude Code to generate project context.")
1373
+ chalk8.dim("Run ") + chalk8.cyan("yapout_compact") + chalk8.dim(" in Claude Code to generate project context.")
1123
1374
  );
1124
1375
  });
1125
1376
  function getCliVersion2() {
1126
1377
  try {
1127
1378
  const pkg = JSON.parse(
1128
- readFileSync4(join5(import.meta.dirname, "..", "package.json"), "utf-8")
1379
+ readFileSync5(join6(import.meta.dirname, "..", "package.json"), "utf-8")
1129
1380
  );
1130
1381
  return pkg.version ?? "unknown";
1131
1382
  } catch {
@@ -1134,18 +1385,18 @@ function getCliVersion2() {
1134
1385
  }
1135
1386
 
1136
1387
  // src/commands/mcp-server.ts
1137
- import { Command as Command7 } from "commander";
1388
+ import { Command as Command8 } from "commander";
1138
1389
 
1139
1390
  // src/mcp/server.ts
1140
1391
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1141
1392
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1142
1393
  import { ConvexHttpClient as ConvexHttpClient2 } from "convex/browser";
1143
- import { anyApi as anyApi3 } from "convex/server";
1394
+ import { anyApi as anyApi4 } from "convex/server";
1144
1395
 
1145
1396
  // src/mcp/tools/init.ts
1146
1397
  import { z } from "zod";
1147
- import { join as join6 } from "path";
1148
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
1398
+ import { join as join7 } from "path";
1399
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "fs";
1149
1400
  import { stringify as yamlStringify } from "yaml";
1150
1401
  function registerInitTool(server, ctx) {
1151
1402
  server.tool(
@@ -1161,7 +1412,7 @@ function registerInitTool(server, ctx) {
1161
1412
  const defaultBranch = getDefaultBranch(repoRoot);
1162
1413
  const projectName = args.name || repoFullName.split("/")[1] || "unnamed";
1163
1414
  const result = await ctx.client.mutation(
1164
- anyApi3.functions.projects.createProjectFromCli,
1415
+ anyApi4.functions.projects.createProjectFromCli,
1165
1416
  {
1166
1417
  name: projectName,
1167
1418
  githubRepoFullName: repoFullName,
@@ -1176,11 +1427,11 @@ function registerInitTool(server, ctx) {
1176
1427
  projectName: result.projectName,
1177
1428
  linkedAt: Date.now()
1178
1429
  });
1179
- const yapoutDir = join6(repoRoot, ".yapout");
1180
- if (!existsSync5(yapoutDir)) mkdirSync5(yapoutDir, { recursive: true });
1181
- const configPath = join6(yapoutDir, "config.yml");
1182
- if (!existsSync5(configPath)) {
1183
- writeFileSync6(
1430
+ const yapoutDir = join7(repoRoot, ".yapout");
1431
+ if (!existsSync6(yapoutDir)) mkdirSync5(yapoutDir, { recursive: true });
1432
+ const configPath = join7(yapoutDir, "config.yml");
1433
+ if (!existsSync6(configPath)) {
1434
+ writeFileSync7(
1184
1435
  configPath,
1185
1436
  `# yapout local configuration
1186
1437
 
@@ -1249,7 +1500,7 @@ function registerCompactTool(server, ctx) {
1249
1500
  let lastUpdated;
1250
1501
  try {
1251
1502
  const project = await ctx.client.query(
1252
- anyApi3.functions.projects.getProject,
1503
+ anyApi4.functions.projects.getProject,
1253
1504
  { projectId: ctx.projectId }
1254
1505
  );
1255
1506
  currentContext = project?.contextSummary ?? void 0;
@@ -1292,7 +1543,7 @@ function registerUpdateContextTool(server, ctx) {
1292
1543
  };
1293
1544
  }
1294
1545
  await ctx.client.mutation(
1295
- anyApi3.functions.projects.updateProjectContext,
1546
+ anyApi4.functions.projects.updateProjectContext,
1296
1547
  {
1297
1548
  projectId: ctx.projectId,
1298
1549
  summary: args.summary
@@ -1362,7 +1613,7 @@ function registerQueueTool(server, ctx) {
1362
1613
  };
1363
1614
  }
1364
1615
  const data = await ctx.client.query(
1365
- anyApi3.functions.workQueue.getWorkQueue,
1616
+ anyApi4.functions.workQueue.getWorkQueue,
1366
1617
  { projectId: ctx.projectId }
1367
1618
  );
1368
1619
  if (!data) {
@@ -1471,7 +1722,7 @@ function registerGetBriefTool(server, ctx) {
1471
1722
  }
1472
1723
  try {
1473
1724
  const data = await ctx.client.query(
1474
- anyApi3.functions.findings.getFindingBrief,
1725
+ anyApi4.functions.findings.getFindingBrief,
1475
1726
  { findingId: itemId }
1476
1727
  );
1477
1728
  if (data) {
@@ -1485,7 +1736,7 @@ function registerGetBriefTool(server, ctx) {
1485
1736
  }
1486
1737
  try {
1487
1738
  const bundle = await ctx.client.query(
1488
- anyApi3.functions.bundles.getBundle,
1739
+ anyApi4.functions.bundles.getBundle,
1489
1740
  { bundleId: itemId }
1490
1741
  );
1491
1742
  if (bundle) {
@@ -1536,8 +1787,8 @@ function registerGetBriefTool(server, ctx) {
1536
1787
 
1537
1788
  // src/mcp/tools/claim.ts
1538
1789
  import { z as z5 } from "zod";
1539
- import { join as join7 } from "path";
1540
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
1790
+ import { join as join8 } from "path";
1791
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, writeFileSync as writeFileSync8 } from "fs";
1541
1792
  function readBranchPrefix(cwd) {
1542
1793
  try {
1543
1794
  const config = readYapoutConfig(cwd);
@@ -1656,7 +1907,7 @@ function formatBundleBrief(bundle, projectContext) {
1656
1907
  async function detectWorkItemKind(client, workItemId) {
1657
1908
  try {
1658
1909
  const bundle = await client.query(
1659
- anyApi3.functions.bundles.getBundle,
1910
+ anyApi4.functions.bundles.getBundle,
1660
1911
  { bundleId: workItemId }
1661
1912
  );
1662
1913
  if (bundle) {
@@ -1710,7 +1961,7 @@ function registerClaimTool(server, ctx) {
1710
1961
  }
1711
1962
  async function claimStandalone(ctx, args, findingId) {
1712
1963
  const briefData = await ctx.client.query(
1713
- anyApi3.functions.findings.getFindingBrief,
1964
+ anyApi4.functions.findings.getFindingBrief,
1714
1965
  { findingId }
1715
1966
  );
1716
1967
  if (!briefData) {
@@ -1731,11 +1982,11 @@ async function claimStandalone(ctx, args, findingId) {
1731
1982
  const slug = slugify(finding.title);
1732
1983
  const branchName = linearIssueId ? `${prefix}/${linearIssueId.toLowerCase()}-${slug}` : `${prefix}/${slug}`;
1733
1984
  const localClaim = await ctx.client.mutation(
1734
- anyApi3.functions.findings.claimFindingLocal,
1985
+ anyApi4.functions.findings.claimFindingLocal,
1735
1986
  { findingId, branchName }
1736
1987
  );
1737
1988
  const claim = await ctx.client.mutation(
1738
- anyApi3.functions.workQueue.claimForImplementation,
1989
+ anyApi4.functions.workQueue.claimForImplementation,
1739
1990
  {
1740
1991
  projectId: ctx.projectId,
1741
1992
  workItemId: findingId,
@@ -1745,7 +1996,7 @@ async function claimStandalone(ctx, args, findingId) {
1745
1996
  if (linearIssueId && ctx.projectId) {
1746
1997
  try {
1747
1998
  await ctx.client.action(
1748
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
1999
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
1749
2000
  {
1750
2001
  projectId: ctx.projectId,
1751
2002
  linearIssueId,
@@ -1802,11 +2053,11 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1802
2053
  };
1803
2054
  }
1804
2055
  const localClaim = await ctx.client.mutation(
1805
- anyApi3.functions.findings.claimFindingLocal,
2056
+ anyApi4.functions.findings.claimFindingLocal,
1806
2057
  { findingId: primaryFinding._id, branchName }
1807
2058
  );
1808
2059
  const claim = await ctx.client.mutation(
1809
- anyApi3.functions.workQueue.claimForImplementation,
2060
+ anyApi4.functions.workQueue.claimForImplementation,
1810
2061
  {
1811
2062
  projectId: ctx.projectId,
1812
2063
  workItemId: bundleId,
@@ -1817,7 +2068,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1817
2068
  if (f.linearIssueId && ctx.projectId) {
1818
2069
  try {
1819
2070
  await ctx.client.action(
1820
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
2071
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
1821
2072
  {
1822
2073
  projectId: ctx.projectId,
1823
2074
  linearIssueId: f.linearIssueId,
@@ -1831,7 +2082,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1831
2082
  let projectContext;
1832
2083
  try {
1833
2084
  const briefData = await ctx.client.query(
1834
- anyApi3.functions.findings.getFindingBrief,
2085
+ anyApi4.functions.findings.getFindingBrief,
1835
2086
  { findingId: primaryFinding._id }
1836
2087
  );
1837
2088
  projectContext = briefData?.projectContext;
@@ -1871,7 +2122,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1871
2122
  async function getDefaultBranchForProject(ctx) {
1872
2123
  try {
1873
2124
  const data = await ctx.client.query(
1874
- anyApi3.functions.projects.getProject,
2125
+ anyApi4.functions.projects.getProject,
1875
2126
  { projectId: ctx.projectId }
1876
2127
  );
1877
2128
  return data?.githubDefaultBranch || "main";
@@ -1890,7 +2141,7 @@ async function setupWorktree(ctx, itemId, branchName, defaultBranch, brief, pipe
1890
2141
  writeBrief(worktreePath, brief);
1891
2142
  try {
1892
2143
  await ctx.client.mutation(
1893
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2144
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1894
2145
  {
1895
2146
  pipelineRunId,
1896
2147
  event: "worktree_created",
@@ -1919,14 +2170,14 @@ async function setupWorktree(ctx, itemId, branchName, defaultBranch, brief, pipe
1919
2170
  };
1920
2171
  }
1921
2172
  function writeBrief(dir, brief) {
1922
- const yapoutDir = join7(dir, ".yapout");
1923
- if (!existsSync6(yapoutDir)) mkdirSync6(yapoutDir, { recursive: true });
1924
- writeFileSync7(join7(yapoutDir, "brief.md"), brief);
2173
+ const yapoutDir = join8(dir, ".yapout");
2174
+ if (!existsSync7(yapoutDir)) mkdirSync6(yapoutDir, { recursive: true });
2175
+ writeFileSync8(join8(yapoutDir, "brief.md"), brief);
1925
2176
  }
1926
2177
  async function reportClaimEvents(ctx, pipelineRunId, title, branchName) {
1927
2178
  try {
1928
2179
  await ctx.client.mutation(
1929
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2180
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1930
2181
  {
1931
2182
  pipelineRunId,
1932
2183
  event: "daemon_claimed",
@@ -1934,7 +2185,7 @@ async function reportClaimEvents(ctx, pipelineRunId, title, branchName) {
1934
2185
  }
1935
2186
  );
1936
2187
  await ctx.client.mutation(
1937
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2188
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1938
2189
  {
1939
2190
  pipelineRunId,
1940
2191
  event: "branch_created",
@@ -1961,7 +2212,7 @@ function registerEventTool(server, ctx) {
1961
2212
  async (args) => {
1962
2213
  try {
1963
2214
  await ctx.client.mutation(
1964
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2215
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1965
2216
  {
1966
2217
  pipelineRunId: args.pipelineRunId,
1967
2218
  event: args.event,
@@ -2053,8 +2304,8 @@ async function createPullRequest(title, body, branch, base, repoFullName, cwd) {
2053
2304
  }
2054
2305
 
2055
2306
  // src/mcp/tools/ship.ts
2056
- import { join as join8 } from "path";
2057
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
2307
+ import { join as join9 } from "path";
2308
+ import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
2058
2309
  function buildCommitMessage(message, template, finding, allLinearIds) {
2059
2310
  if (message) return message;
2060
2311
  if (template) {
@@ -2105,9 +2356,9 @@ function registerShipTool(server, ctx) {
2105
2356
  let isBundle = false;
2106
2357
  let bundleTitle;
2107
2358
  try {
2108
- const briefPath = join8(gitCwd, ".yapout", "brief.md");
2109
- if (existsSync7(briefPath)) {
2110
- const brief = readFileSync5(briefPath, "utf-8");
2359
+ const briefPath = join9(gitCwd, ".yapout", "brief.md");
2360
+ if (existsSync8(briefPath)) {
2361
+ const brief = readFileSync6(briefPath, "utf-8");
2111
2362
  const bundleMatch = brief.match(/^# Bundle: (.+)$/m);
2112
2363
  if (bundleMatch) {
2113
2364
  isBundle = true;
@@ -2218,7 +2469,7 @@ function registerShipTool(server, ctx) {
2218
2469
  }
2219
2470
  try {
2220
2471
  await ctx.client.mutation(
2221
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2472
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2222
2473
  {
2223
2474
  pipelineRunId: args.pipelineRunId,
2224
2475
  event: "push_completed",
@@ -2227,7 +2478,7 @@ function registerShipTool(server, ctx) {
2227
2478
  );
2228
2479
  if (prUrl) {
2229
2480
  await ctx.client.mutation(
2230
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2481
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2231
2482
  {
2232
2483
  pipelineRunId: args.pipelineRunId,
2233
2484
  event: "pr_opened",
@@ -2239,7 +2490,7 @@ function registerShipTool(server, ctx) {
2239
2490
  }
2240
2491
  try {
2241
2492
  await ctx.client.mutation(
2242
- anyApi3.functions.pipelineRuns.completePipelineLocal,
2493
+ anyApi4.functions.pipelineRuns.completePipelineLocal,
2243
2494
  {
2244
2495
  pipelineRunId: args.pipelineRunId,
2245
2496
  githubPrNumber: prNumber,
@@ -2255,7 +2506,7 @@ function registerShipTool(server, ctx) {
2255
2506
  if (ctx.projectId) {
2256
2507
  try {
2257
2508
  await ctx.client.action(
2258
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
2509
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
2259
2510
  {
2260
2511
  projectId: ctx.projectId,
2261
2512
  linearIssueId: linearId,
@@ -2267,7 +2518,7 @@ function registerShipTool(server, ctx) {
2267
2518
  if (prUrl) {
2268
2519
  try {
2269
2520
  await ctx.client.action(
2270
- anyApi3.functions.linearStatusMutations.addLinearComment,
2521
+ anyApi4.functions.linearStatusMutations.addLinearComment,
2271
2522
  {
2272
2523
  projectId: ctx.projectId,
2273
2524
  linearIssueId: linearId,
@@ -2285,7 +2536,7 @@ function registerShipTool(server, ctx) {
2285
2536
  result.worktreeCleaned = true;
2286
2537
  try {
2287
2538
  await ctx.client.mutation(
2288
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2539
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2289
2540
  {
2290
2541
  pipelineRunId: args.pipelineRunId,
2291
2542
  event: "worktree_cleaned",
@@ -2376,7 +2627,7 @@ function registerCheckTool(server, ctx) {
2376
2627
  if (args.pipelineRunId) {
2377
2628
  try {
2378
2629
  await ctx.client.mutation(
2379
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2630
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2380
2631
  {
2381
2632
  pipelineRunId: args.pipelineRunId,
2382
2633
  event: "running_check",
@@ -2396,7 +2647,7 @@ function registerCheckTool(server, ctx) {
2396
2647
  if (args.pipelineRunId) {
2397
2648
  try {
2398
2649
  await ctx.client.mutation(
2399
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2650
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2400
2651
  {
2401
2652
  pipelineRunId: args.pipelineRunId,
2402
2653
  event: passed ? "check_passed" : "check_failed",
@@ -2428,8 +2679,8 @@ function registerCheckTool(server, ctx) {
2428
2679
 
2429
2680
  // src/mcp/tools/bundle.ts
2430
2681
  import { z as z9 } from "zod";
2431
- import { join as join9 } from "path";
2432
- import { existsSync as existsSync8, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7 } from "fs";
2682
+ import { join as join10 } from "path";
2683
+ import { existsSync as existsSync9, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7 } from "fs";
2433
2684
  function registerBundleTool(server, ctx) {
2434
2685
  server.tool(
2435
2686
  "yapout_bundle",
@@ -2440,11 +2691,11 @@ function registerBundleTool(server, ctx) {
2440
2691
  },
2441
2692
  async (args) => {
2442
2693
  const result = await ctx.client.mutation(
2443
- anyApi3.functions.bundles.createBundle,
2694
+ anyApi4.functions.bundles.createBundle,
2444
2695
  { leadFindingId: args.withFinding, joiningFindingId: args.findingId }
2445
2696
  );
2446
2697
  const bundledBrief = await ctx.client.query(
2447
- anyApi3.functions.bundles.getBundledBrief,
2698
+ anyApi4.functions.bundles.getBundledBrief,
2448
2699
  { bundleId: result.bundleId }
2449
2700
  );
2450
2701
  if (!bundledBrief) {
@@ -2482,9 +2733,9 @@ function registerBundleTool(server, ctx) {
2482
2733
  sections.push("## Project Context", "", bundledBrief.projectContext);
2483
2734
  }
2484
2735
  const combinedBrief = sections.join("\n");
2485
- const yapoutDir = join9(ctx.cwd, ".yapout");
2486
- if (!existsSync8(yapoutDir)) mkdirSync7(yapoutDir, { recursive: true });
2487
- writeFileSync8(join9(yapoutDir, "brief.md"), combinedBrief);
2736
+ const yapoutDir = join10(ctx.cwd, ".yapout");
2737
+ if (!existsSync9(yapoutDir)) mkdirSync7(yapoutDir, { recursive: true });
2738
+ writeFileSync9(join10(yapoutDir, "brief.md"), combinedBrief);
2488
2739
  return {
2489
2740
  content: [
2490
2741
  {
@@ -2541,7 +2792,7 @@ After calling this tool, you should:
2541
2792
  }
2542
2793
  try {
2543
2794
  const result = await ctx.client.mutation(
2544
- anyApi3.functions.localPipeline.claimForEnrichment,
2795
+ anyApi4.functions.localPipeline.claimForEnrichment,
2545
2796
  {
2546
2797
  projectId,
2547
2798
  ...args.findingId ? { findingId: args.findingId } : {}
@@ -2601,7 +2852,7 @@ function registerGetExistingFindingsTool(server, ctx) {
2601
2852
  }
2602
2853
  try {
2603
2854
  const findings = await ctx.client.query(
2604
- anyApi3.functions.localPipeline.getExistingFindingTitles,
2855
+ anyApi4.functions.localPipeline.getExistingFindingTitles,
2605
2856
  { projectId }
2606
2857
  );
2607
2858
  if (!findings || findings.length === 0) {
@@ -2703,7 +2954,7 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2703
2954
  async (args) => {
2704
2955
  try {
2705
2956
  await ctx.client.mutation(
2706
- anyApi3.functions.localPipeline.saveLocalEnrichment,
2957
+ anyApi4.functions.localPipeline.saveLocalEnrichment,
2707
2958
  {
2708
2959
  findingId: args.findingId,
2709
2960
  title: args.title,
@@ -2718,11 +2969,11 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2718
2969
  }
2719
2970
  );
2720
2971
  await ctx.client.action(
2721
- anyApi3.functions.localPipeline.syncFindingToLinearLocal,
2972
+ anyApi4.functions.localPipeline.syncFindingToLinearLocal,
2722
2973
  { findingId: args.findingId }
2723
2974
  );
2724
2975
  const finding = await ctx.client.query(
2725
- anyApi3.functions.findings.getFinding,
2976
+ anyApi4.functions.findings.getFinding,
2726
2977
  { findingId: args.findingId }
2727
2978
  );
2728
2979
  if (args.sessionId) {
@@ -2781,7 +3032,7 @@ function registerSyncToLinearTool(server, ctx) {
2781
3032
  async (args) => {
2782
3033
  try {
2783
3034
  await ctx.client.action(
2784
- anyApi3.functions.localPipeline.syncFindingToLinearLocal,
3035
+ anyApi4.functions.localPipeline.syncFindingToLinearLocal,
2785
3036
  { findingId: args.findingId }
2786
3037
  );
2787
3038
  return {
@@ -2839,7 +3090,7 @@ function registerSubmitYapSessionTool(server, ctx) {
2839
3090
  }
2840
3091
  try {
2841
3092
  const captureId = await ctx.client.mutation(
2842
- anyApi3.functions.captures.createFromYapSession,
3093
+ anyApi4.functions.captures.createFromYapSession,
2843
3094
  {
2844
3095
  projectId: ctx.projectId,
2845
3096
  title: args.title,
@@ -3115,7 +3366,7 @@ function registerExtractFromYapTool(server, ctx) {
3115
3366
  }
3116
3367
  try {
3117
3368
  const result = await ctx.client.mutation(
3118
- anyApi3.functions.captures.extractFromYapSession,
3369
+ anyApi4.functions.captures.extractFromYapSession,
3119
3370
  {
3120
3371
  projectId: ctx.projectId,
3121
3372
  title: args.sessionTitle,
@@ -3227,7 +3478,7 @@ full spec \u2014 schema changes, files to modify, edge cases, and acceptance cri
3227
3478
  }
3228
3479
  try {
3229
3480
  const result = await ctx.client.mutation(
3230
- anyApi3.functions.localPipeline.decomposeIntoBundle,
3481
+ anyApi4.functions.localPipeline.decomposeIntoBundle,
3231
3482
  {
3232
3483
  findingId: args.findingId,
3233
3484
  bundleDescription: args.bundleDescription,
@@ -3300,7 +3551,7 @@ The finding must be in "enriching" or "enriched" status. It will be transitioned
3300
3551
  }
3301
3552
  try {
3302
3553
  const result = await ctx.client.mutation(
3303
- anyApi3.functions.findings.markDuplicate,
3554
+ anyApi4.functions.findings.markDuplicate,
3304
3555
  {
3305
3556
  findingId: args.findingId,
3306
3557
  duplicateOfLinearId: args.duplicateOfLinearId,
@@ -3363,7 +3614,7 @@ and issue counts so you can ask the user for confirmation before creating a new
3363
3614
  }
3364
3615
  try {
3365
3616
  const project = await ctx.client.query(
3366
- anyApi3.functions.projects.getProject,
3617
+ anyApi4.functions.projects.getProject,
3367
3618
  { projectId: ctx.projectId }
3368
3619
  );
3369
3620
  if (!project?.linearTeamId) {
@@ -3378,7 +3629,7 @@ and issue counts so you can ask the user for confirmation before creating a new
3378
3629
  };
3379
3630
  }
3380
3631
  const projects = await ctx.client.action(
3381
- anyApi3.functions.linearProjectsMutations.fetchProjectsDetailed,
3632
+ anyApi4.functions.linearProjectsMutations.fetchProjectsDetailed,
3382
3633
  { projectId: ctx.projectId, teamId: project.linearTeamId }
3383
3634
  );
3384
3635
  return {
@@ -3440,7 +3691,7 @@ Optionally filter by tags, capture, or explicit finding IDs.`,
3440
3691
  }
3441
3692
  try {
3442
3693
  const allFindings = await ctx.client.query(
3443
- anyApi3.functions.findings.getProjectFindings,
3694
+ anyApi4.functions.findings.getProjectFindings,
3444
3695
  { projectId }
3445
3696
  );
3446
3697
  let drafts = (allFindings ?? []).filter((f) => f.status === "draft");
@@ -3510,7 +3761,7 @@ When done=true, all findings have been processed.`,
3510
3761
  if (args.skip && args.skipFindingId) {
3511
3762
  try {
3512
3763
  await ctx.client.mutation(
3513
- anyApi3.functions.localPipeline.releaseEnrichmentClaim,
3764
+ anyApi4.functions.localPipeline.releaseEnrichmentClaim,
3514
3765
  { findingId: args.skipFindingId }
3515
3766
  );
3516
3767
  updateSessionStats(args.sessionId, {
@@ -3520,7 +3771,7 @@ When done=true, all findings have been processed.`,
3520
3771
  }
3521
3772
  }
3522
3773
  const allFindings = await ctx.client.query(
3523
- anyApi3.functions.findings.getProjectFindings,
3774
+ anyApi4.functions.findings.getProjectFindings,
3524
3775
  { projectId: session.projectId }
3525
3776
  );
3526
3777
  let drafts = (allFindings ?? []).filter(
@@ -3562,7 +3813,7 @@ When done=true, all findings have been processed.`,
3562
3813
  }
3563
3814
  const next = drafts[0];
3564
3815
  const claimResult = await ctx.client.mutation(
3565
- anyApi3.functions.localPipeline.claimForEnrichment,
3816
+ anyApi4.functions.localPipeline.claimForEnrichment,
3566
3817
  { projectId: session.projectId, findingId: next._id }
3567
3818
  );
3568
3819
  if (!claimResult) {
@@ -3643,7 +3894,7 @@ The bundle and all its findings transition to "enriching" status.`,
3643
3894
  async (args) => {
3644
3895
  try {
3645
3896
  const result = await ctx.client.mutation(
3646
- anyApi3.functions.bundles.claimBundleForEnrichment,
3897
+ anyApi4.functions.bundles.claimBundleForEnrichment,
3647
3898
  { bundleId: args.bundleId }
3648
3899
  );
3649
3900
  if (!result) {
@@ -3702,7 +3953,7 @@ Call yapout_sync_bundle_to_linear afterwards to create the Linear project.`,
3702
3953
  async (args) => {
3703
3954
  try {
3704
3955
  await ctx.client.mutation(
3705
- anyApi3.functions.bundles.saveBundleEnrichment,
3956
+ anyApi4.functions.bundles.saveBundleEnrichment,
3706
3957
  {
3707
3958
  bundleId: args.bundleId,
3708
3959
  title: args.title,
@@ -3761,7 +4012,7 @@ Transitions: enriching \u2192 needs_input. The user sees the blockerReason and q
3761
4012
  async (args) => {
3762
4013
  try {
3763
4014
  await ctx.client.mutation(
3764
- anyApi3.functions.localPipeline.blockLocalEnrichment,
4015
+ anyApi4.functions.localPipeline.blockLocalEnrichment,
3765
4016
  {
3766
4017
  findingId: args.findingId,
3767
4018
  blockerReason: args.blockerReason,
@@ -3810,7 +4061,7 @@ Same semantics as yapout_block_enrichment but for an entire bundle. Bundle statu
3810
4061
  async (args) => {
3811
4062
  try {
3812
4063
  await ctx.client.mutation(
3813
- anyApi3.functions.bundles.blockBundleEnrichment,
4064
+ anyApi4.functions.bundles.blockBundleEnrichment,
3814
4065
  {
3815
4066
  bundleId: args.bundleId,
3816
4067
  blockerReason: args.blockerReason,
@@ -3878,7 +4129,7 @@ async function startMcpServer() {
3878
4129
  };
3879
4130
  const server = new McpServer({
3880
4131
  name: "yapout",
3881
- version: "0.8.0"
4132
+ version: "0.10.0"
3882
4133
  });
3883
4134
  registerInitTool(server, ctx);
3884
4135
  registerCompactTool(server, ctx);
@@ -3910,40 +4161,40 @@ async function startMcpServer() {
3910
4161
  }
3911
4162
 
3912
4163
  // src/commands/mcp-server.ts
3913
- var mcpServerCommand = new Command7("mcp-server").description("Start the MCP server (used by Claude Code)").action(async () => {
4164
+ var mcpServerCommand = new Command8("mcp-server").description("Start the MCP server (used by Claude Code)").action(async () => {
3914
4165
  await startMcpServer();
3915
4166
  });
3916
4167
 
3917
4168
  // src/commands/worktrees.ts
3918
- import { Command as Command8 } from "commander";
3919
- import chalk8 from "chalk";
4169
+ import { Command as Command9 } from "commander";
4170
+ import chalk9 from "chalk";
3920
4171
  import { resolve as resolve6 } from "path";
3921
- var worktreesCommand = new Command8("worktrees").description("List active yapout worktrees").action(() => {
4172
+ var worktreesCommand = new Command9("worktrees").description("List active yapout worktrees").action(() => {
3922
4173
  const cwd = resolve6(process.cwd());
3923
4174
  const worktrees = listWorktrees(cwd);
3924
4175
  if (worktrees.length === 0) {
3925
- console.log(chalk8.dim("No active yapout worktrees."));
4176
+ console.log(chalk9.dim("No active yapout worktrees."));
3926
4177
  return;
3927
4178
  }
3928
- console.log(chalk8.bold("Active worktrees:\n"));
4179
+ console.log(chalk9.bold("Active worktrees:\n"));
3929
4180
  for (const wt of worktrees) {
3930
4181
  console.log(
3931
- ` ${chalk8.cyan(wt.path)} ${chalk8.green(wt.branch)}` + (wt.ticketId ? ` ${chalk8.dim(`(${wt.ticketId})`)}` : "")
4182
+ ` ${chalk9.cyan(wt.path)} ${chalk9.green(wt.branch)}` + (wt.ticketId ? ` ${chalk9.dim(`(${wt.ticketId})`)}` : "")
3932
4183
  );
3933
4184
  }
3934
4185
  console.log();
3935
4186
  });
3936
4187
 
3937
4188
  // src/commands/clean.ts
3938
- import { Command as Command9 } from "commander";
3939
- import chalk9 from "chalk";
4189
+ import { Command as Command10 } from "commander";
4190
+ import chalk10 from "chalk";
3940
4191
  import { resolve as resolve7 } from "path";
3941
- var cleanCommand = new Command9("clean").description("Remove worktrees for completed or failed tickets").action(async () => {
4192
+ var cleanCommand = new Command10("clean").description("Remove worktrees for completed or failed tickets").action(async () => {
3942
4193
  const creds = requireAuth();
3943
4194
  const cwd = resolve7(process.cwd());
3944
4195
  const worktrees = listWorktrees(cwd);
3945
4196
  if (worktrees.length === 0) {
3946
- console.log(chalk9.dim("No worktrees to clean."));
4197
+ console.log(chalk10.dim("No worktrees to clean."));
3947
4198
  return;
3948
4199
  }
3949
4200
  const client = createConvexClient(creds.token);
@@ -3959,7 +4210,7 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3959
4210
  if (isStale) {
3960
4211
  const label = ticket ? `${ticket.status}: ${ticket.title}` : "ticket not found";
3961
4212
  console.log(
3962
- chalk9.dim(`Removing worktree for ${wt.ticketId} (${label})...`)
4213
+ chalk10.dim(`Removing worktree for ${wt.ticketId} (${label})...`)
3963
4214
  );
3964
4215
  removeWorktree(cwd, wt.path);
3965
4216
  cleaned++;
@@ -3968,10 +4219,10 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3968
4219
  }
3969
4220
  }
3970
4221
  if (cleaned === 0) {
3971
- console.log(chalk9.dim("All worktrees are still active."));
4222
+ console.log(chalk10.dim("All worktrees are still active."));
3972
4223
  } else {
3973
4224
  console.log(
3974
- chalk9.green(
4225
+ chalk10.green(
3975
4226
  `Cleaned ${cleaned} worktree${cleaned === 1 ? "" : "s"}.`
3976
4227
  )
3977
4228
  );
@@ -3979,27 +4230,27 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3979
4230
  });
3980
4231
 
3981
4232
  // src/commands/watch.ts
3982
- import { Command as Command10 } from "commander";
4233
+ import { Command as Command11 } from "commander";
3983
4234
  import { resolve as resolve8 } from "path";
3984
4235
  import {
3985
- readFileSync as readFileSync6,
3986
- writeFileSync as writeFileSync9,
3987
- existsSync as existsSync10,
3988
- unlinkSync as unlinkSync3
4236
+ readFileSync as readFileSync7,
4237
+ writeFileSync as writeFileSync10,
4238
+ existsSync as existsSync11,
4239
+ unlinkSync as unlinkSync4
3989
4240
  } from "fs";
3990
- import { join as join11 } from "path";
3991
- import chalk11 from "chalk";
4241
+ import { join as join12 } from "path";
4242
+ import chalk12 from "chalk";
3992
4243
  import { ConvexHttpClient as ConvexHttpClient3 } from "convex/browser";
3993
4244
 
3994
4245
  // src/daemon/watcher.ts
3995
- import { anyApi as anyApi5 } from "convex/server";
4246
+ import { anyApi as anyApi6 } from "convex/server";
3996
4247
  import { execSync as execSync4 } from "child_process";
3997
- import { existsSync as existsSync9, mkdirSync as mkdirSync8 } from "fs";
3998
- import { join as join10 } from "path";
4248
+ import { existsSync as existsSync10, mkdirSync as mkdirSync8 } from "fs";
4249
+ import { join as join11 } from "path";
3999
4250
  import { hostname as osHostname } from "os";
4000
4251
 
4001
4252
  // src/daemon/heartbeat.ts
4002
- import { anyApi as anyApi4 } from "convex/server";
4253
+ import { anyApi as anyApi5 } from "convex/server";
4003
4254
  var HEARTBEAT_INTERVAL = 3e4;
4004
4255
  var Heartbeat = class {
4005
4256
  client;
@@ -4027,14 +4278,14 @@ var Heartbeat = class {
4027
4278
  if (currentTicketId) args.currentTicketId = currentTicketId;
4028
4279
  if (currentBranch) args.currentBranch = currentBranch;
4029
4280
  if (worktreePath) args.worktreePath = worktreePath;
4030
- await this.client.mutation(anyApi4.functions.agents.agentHeartbeat, args);
4281
+ await this.client.mutation(anyApi5.functions.agents.agentHeartbeat, args);
4031
4282
  } catch {
4032
4283
  }
4033
4284
  }
4034
4285
  };
4035
4286
 
4036
4287
  // src/daemon/spawner.ts
4037
- import { spawn } from "child_process";
4288
+ import { spawn as spawn2 } from "child_process";
4038
4289
 
4039
4290
  // src/daemon/notifications.ts
4040
4291
  var notifier = null;
@@ -4123,7 +4374,7 @@ var Spawner = class {
4123
4374
  ...process.env,
4124
4375
  YAPOUT_PROJECT_ID: this.projectId
4125
4376
  };
4126
- const child = spawn("claude", ["--dangerously-skip-permissions", prompt], {
4377
+ const child = spawn2("claude", ["--dangerously-skip-permissions", prompt], {
4127
4378
  cwd: worktreePath,
4128
4379
  stdio: ["pipe", "pipe", "pipe"],
4129
4380
  env,
@@ -4235,7 +4486,7 @@ var Spawner = class {
4235
4486
  };
4236
4487
 
4237
4488
  // src/daemon/display.ts
4238
- import chalk10 from "chalk";
4489
+ import chalk11 from "chalk";
4239
4490
  function formatElapsed(ms) {
4240
4491
  const seconds = Math.floor(ms / 1e3);
4241
4492
  if (seconds < 60) return `${seconds}s`;
@@ -4264,35 +4515,35 @@ function render(state) {
4264
4515
  if (queuedCount > 0) statusParts.push(`${queuedCount} queued`);
4265
4516
  const statusLine = statusParts.length > 0 ? statusParts.join(" | ") : "idle";
4266
4517
  lines.push(
4267
- `${chalk10.bold("yapout watch")} \u2014 ${state.projectName}`
4518
+ `${chalk11.bold("yapout watch")} \u2014 ${state.projectName}`
4268
4519
  );
4269
- lines.push(`${chalk10.green("Watching")} | ${statusLine}`);
4520
+ lines.push(`${chalk11.green("Watching")} | ${statusLine}`);
4270
4521
  lines.push("");
4271
4522
  for (const agent of state.activeAgents) {
4272
4523
  const elapsed = formatElapsed(now - agent.startedAt);
4273
- const wt = agent.worktree ? chalk10.dim(`worktree/${agent.ticketRef.toLowerCase()}`) : "";
4524
+ const wt = agent.worktree ? chalk11.dim(`worktree/${agent.ticketRef.toLowerCase()}`) : "";
4274
4525
  lines.push(
4275
- ` ${chalk10.green("\u25CF")} ${chalk10.bold(agent.ticketRef)} ${chalk10.dim(truncate2(`"${agent.title}"`, 35))} ${chalk10.yellow(agent.phase)} ${wt} ${chalk10.dim(elapsed)}`
4526
+ ` ${chalk11.green("\u25CF")} ${chalk11.bold(agent.ticketRef)} ${chalk11.dim(truncate2(`"${agent.title}"`, 35))} ${chalk11.yellow(agent.phase)} ${wt} ${chalk11.dim(elapsed)}`
4276
4527
  );
4277
4528
  }
4278
4529
  for (const ticket of state.queuedTickets) {
4279
4530
  lines.push(
4280
- ` ${chalk10.dim("\u25CB")} ${chalk10.bold(ticket.ticketRef)} ${chalk10.dim(truncate2(`"${ticket.title}"`, 35))} ${chalk10.dim("queued")}`
4531
+ ` ${chalk11.dim("\u25CB")} ${chalk11.bold(ticket.ticketRef)} ${chalk11.dim(truncate2(`"${ticket.title}"`, 35))} ${chalk11.dim("queued")}`
4281
4532
  );
4282
4533
  }
4283
4534
  if (state.activeAgents.length > 0 || state.queuedTickets.length > 0) {
4284
4535
  lines.push("");
4285
4536
  }
4286
4537
  if (state.recentEvents.length > 0) {
4287
- lines.push(chalk10.dim("Recent:"));
4538
+ lines.push(chalk11.dim("Recent:"));
4288
4539
  for (const event of state.recentEvents.slice(0, 8)) {
4289
4540
  lines.push(
4290
- ` ${chalk10.dim(formatTime(event.time))} ${event.icon} ${event.message}`
4541
+ ` ${chalk11.dim(formatTime(event.time))} ${event.icon} ${event.message}`
4291
4542
  );
4292
4543
  }
4293
4544
  lines.push("");
4294
4545
  }
4295
- lines.push(chalk10.dim("Ctrl+C to stop (agents will finish)"));
4546
+ lines.push(chalk11.dim("Ctrl+C to stop (agents will finish)"));
4296
4547
  return lines.join("\n");
4297
4548
  }
4298
4549
  function clearAndRender(state) {
@@ -4334,7 +4585,7 @@ var Watcher = class {
4334
4585
  );
4335
4586
  process.exit(1);
4336
4587
  }
4337
- await this.client.mutation(anyApi5.functions.agents.registerAgent, {
4588
+ await this.client.mutation(anyApi6.functions.agents.registerAgent, {
4338
4589
  projectId: this.options.projectId,
4339
4590
  sessionId: this.sessionId,
4340
4591
  machineHostname: this.getHostname()
@@ -4370,7 +4621,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4370
4621
  await this.spawner.gracefulShutdown();
4371
4622
  }
4372
4623
  try {
4373
- await this.client.mutation(anyApi5.functions.agents.unregisterAgent, {
4624
+ await this.client.mutation(anyApi6.functions.agents.unregisterAgent, {
4374
4625
  sessionId: this.sessionId
4375
4626
  });
4376
4627
  } catch {
@@ -4384,7 +4635,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4384
4635
  }
4385
4636
  this.heartbeat.stop();
4386
4637
  this.spawner.forceKill();
4387
- this.client.mutation(anyApi5.functions.agents.unregisterAgent, {
4638
+ this.client.mutation(anyApi6.functions.agents.unregisterAgent, {
4388
4639
  sessionId: this.sessionId
4389
4640
  }).catch(() => {
4390
4641
  });
@@ -4426,7 +4677,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4426
4677
  }
4427
4678
  async checkForEnrichmentWork(maxSlots) {
4428
4679
  const tickets = await this.client.query(
4429
- anyApi5.functions.localPipeline.getUnenrichedTickets,
4680
+ anyApi6.functions.localPipeline.getUnenrichedTickets,
4430
4681
  { projectId: this.options.projectId }
4431
4682
  );
4432
4683
  if (!tickets || tickets.length === 0) return;
@@ -4455,7 +4706,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4455
4706
  }
4456
4707
  async checkForImplementationWork(maxSlots) {
4457
4708
  const data = await this.client.query(
4458
- anyApi5.functions.tickets.getLocalQueuedTickets,
4709
+ anyApi6.functions.tickets.getLocalQueuedTickets,
4459
4710
  { projectId: this.options.projectId }
4460
4711
  );
4461
4712
  if (!data || data.ready.length === 0) return;
@@ -4487,10 +4738,10 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4487
4738
  }
4488
4739
  ensureEnrichWorktree() {
4489
4740
  const wtDir = getWorktreesDir(this.options.cwd);
4490
- const enrichPath = join10(wtDir, "_enrich");
4491
- if (existsSync9(enrichPath)) return enrichPath;
4741
+ const enrichPath = join11(wtDir, "_enrich");
4742
+ if (existsSync10(enrichPath)) return enrichPath;
4492
4743
  try {
4493
- if (!existsSync9(wtDir)) mkdirSync8(wtDir, { recursive: true });
4744
+ if (!existsSync10(wtDir)) mkdirSync8(wtDir, { recursive: true });
4494
4745
  const defaultBranch = getDefaultBranch(this.options.cwd);
4495
4746
  execSync4(
4496
4747
  `git worktree add "${enrichPath}" origin/${defaultBranch}`,
@@ -4528,7 +4779,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4528
4779
  if (wt.ticketId) {
4529
4780
  try {
4530
4781
  const ticket = await this.client.query(
4531
- anyApi5.functions.tickets.getTicket,
4782
+ anyApi6.functions.tickets.getTicket,
4532
4783
  { ticketId: wt.ticketId }
4533
4784
  );
4534
4785
  if (ticket && (ticket.status === "failed" || ticket.status === "workflow2_done")) {
@@ -4593,38 +4844,38 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4593
4844
  };
4594
4845
 
4595
4846
  // src/commands/watch.ts
4596
- var PID_FILE = join11(getYapoutDir(), "watch.pid");
4597
- var LOG_FILE = join11(getYapoutDir(), "watch.log");
4598
- var watchCommand = new Command10("watch").description("Watch for work and spawn Claude Code agents").option("--bg", "Run in background (detached)").option("--stop", "Stop the background watcher").option("--status", "Check if watcher is running").option("--force", "Force kill on Ctrl+C (don't wait for agents)").action(async (opts) => {
4847
+ var PID_FILE2 = join12(getYapoutDir(), "watch.pid");
4848
+ var LOG_FILE2 = join12(getYapoutDir(), "watch.log");
4849
+ var watchCommand = new Command11("watch").description("Watch for work and spawn Claude Code agents").option("--bg", "Run in background (detached)").option("--stop", "Stop the background watcher").option("--status", "Check if watcher is running").option("--force", "Force kill on Ctrl+C (don't wait for agents)").action(async (opts) => {
4599
4850
  if (opts.status) {
4600
- if (existsSync10(PID_FILE)) {
4601
- const pid = parseInt(readFileSync6(PID_FILE, "utf-8").trim(), 10);
4602
- if (isProcessRunning(pid)) {
4851
+ if (existsSync11(PID_FILE2)) {
4852
+ const pid = parseInt(readFileSync7(PID_FILE2, "utf-8").trim(), 10);
4853
+ if (isProcessRunning2(pid)) {
4603
4854
  console.log(
4604
- chalk11.green("Watcher is running") + chalk11.dim(` (PID ${pid})`)
4855
+ chalk12.green("Watcher is running") + chalk12.dim(` (PID ${pid})`)
4605
4856
  );
4606
4857
  } else {
4607
- console.log(chalk11.dim("Watcher is not running (stale PID file)"));
4608
- unlinkSync3(PID_FILE);
4858
+ console.log(chalk12.dim("Watcher is not running (stale PID file)"));
4859
+ unlinkSync4(PID_FILE2);
4609
4860
  }
4610
4861
  } else {
4611
- console.log(chalk11.dim("Watcher is not running"));
4862
+ console.log(chalk12.dim("Watcher is not running"));
4612
4863
  }
4613
4864
  return;
4614
4865
  }
4615
4866
  if (opts.stop) {
4616
- if (!existsSync10(PID_FILE)) {
4617
- console.log(chalk11.dim("No watcher running"));
4867
+ if (!existsSync11(PID_FILE2)) {
4868
+ console.log(chalk12.dim("No watcher running"));
4618
4869
  return;
4619
4870
  }
4620
- const pid = parseInt(readFileSync6(PID_FILE, "utf-8").trim(), 10);
4871
+ const pid = parseInt(readFileSync7(PID_FILE2, "utf-8").trim(), 10);
4621
4872
  try {
4622
4873
  process.kill(pid, "SIGTERM");
4623
- console.log(chalk11.green(`Stopped watcher (PID ${pid})`));
4874
+ console.log(chalk12.green(`Stopped watcher (PID ${pid})`));
4624
4875
  } catch {
4625
- console.log(chalk11.dim("Watcher already stopped"));
4876
+ console.log(chalk12.dim("Watcher already stopped"));
4626
4877
  }
4627
- unlinkSync3(PID_FILE);
4878
+ unlinkSync4(PID_FILE2);
4628
4879
  return;
4629
4880
  }
4630
4881
  const creds = requireAuth();
@@ -4632,7 +4883,7 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4632
4883
  const mapping = getProjectMapping(cwd);
4633
4884
  if (!mapping) {
4634
4885
  console.error(
4635
- chalk11.red("No project linked.") + " Run " + chalk11.cyan("yapout link") + " in a repo."
4886
+ chalk12.red("No project linked.") + " Run " + chalk12.cyan("yapout link") + " in a repo."
4636
4887
  );
4637
4888
  process.exit(1);
4638
4889
  }
@@ -4640,16 +4891,16 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4640
4891
  const client = new ConvexHttpClient3(getConvexUrl());
4641
4892
  client.setAuth(creds.token);
4642
4893
  if (opts.bg) {
4643
- writeFileSync9(PID_FILE, process.pid.toString());
4894
+ writeFileSync10(PID_FILE2, process.pid.toString());
4644
4895
  console.log(
4645
- chalk11.green("Watcher started in background") + chalk11.dim(` (PID ${process.pid}, log: ${LOG_FILE})`)
4896
+ chalk12.green("Watcher started in background") + chalk12.dim(` (PID ${process.pid}, log: ${LOG_FILE2})`)
4646
4897
  );
4647
4898
  }
4648
- console.log(chalk11.bold(`yapout watch v${"0.8.0"}`));
4899
+ console.log(chalk12.bold(`yapout watch v${"0.10.0"}`));
4649
4900
  console.log(
4650
- `Project: ${chalk11.green(mapping.projectName)} (${mapping.projectId})`
4901
+ `Project: ${chalk12.green(mapping.projectName)} (${mapping.projectId})`
4651
4902
  );
4652
- console.log(chalk11.dim("Watching..."));
4903
+ console.log(chalk12.dim("Watching..."));
4653
4904
  console.log();
4654
4905
  const watcher = new Watcher(
4655
4906
  {
@@ -4666,17 +4917,17 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4666
4917
  const shutdown = async () => {
4667
4918
  if (shuttingDown) {
4668
4919
  watcher.forceStop();
4669
- if (existsSync10(PID_FILE)) unlinkSync3(PID_FILE);
4920
+ if (existsSync11(PID_FILE2)) unlinkSync4(PID_FILE2);
4670
4921
  process.exit(0);
4671
4922
  }
4672
4923
  shuttingDown = true;
4673
- console.log(chalk11.dim("\nShutting down..."));
4924
+ console.log(chalk12.dim("\nShutting down..."));
4674
4925
  if (opts.force) {
4675
4926
  watcher.forceStop();
4676
4927
  } else {
4677
4928
  await watcher.stop();
4678
4929
  }
4679
- if (existsSync10(PID_FILE)) unlinkSync3(PID_FILE);
4930
+ if (existsSync11(PID_FILE2)) unlinkSync4(PID_FILE2);
4680
4931
  process.exit(0);
4681
4932
  };
4682
4933
  process.on("SIGINT", () => {
@@ -4689,7 +4940,7 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4689
4940
  await new Promise(() => {
4690
4941
  });
4691
4942
  });
4692
- function isProcessRunning(pid) {
4943
+ function isProcessRunning2(pid) {
4693
4944
  try {
4694
4945
  process.kill(pid, 0);
4695
4946
  return true;
@@ -4699,88 +4950,88 @@ function isProcessRunning(pid) {
4699
4950
  }
4700
4951
 
4701
4952
  // src/commands/queue.ts
4702
- import { Command as Command11 } from "commander";
4953
+ import { Command as Command12 } from "commander";
4703
4954
  import { resolve as resolve9 } from "path";
4704
- import chalk12 from "chalk";
4705
- var queueCommand = new Command11("queue").description("Show pipeline state \u2014 what's ready, blocked, and pending").action(async () => {
4955
+ import chalk13 from "chalk";
4956
+ var queueCommand = new Command12("queue").description("Show pipeline state \u2014 what's ready, blocked, and pending").action(async () => {
4706
4957
  const creds = requireAuth();
4707
4958
  const cwd = resolve9(process.cwd());
4708
4959
  const mapping = getProjectMapping(cwd);
4709
4960
  if (!mapping) {
4710
4961
  console.error(
4711
- chalk12.red("No project linked.") + " Run " + chalk12.cyan("yapout link") + " in a repo."
4962
+ chalk13.red("No project linked.") + " Run " + chalk13.cyan("yapout link") + " in a repo."
4712
4963
  );
4713
4964
  process.exit(1);
4714
4965
  }
4715
4966
  const client = createConvexClient(creds.token);
4716
- const { anyApi: anyApi6 } = await import("convex/server");
4967
+ const { anyApi: anyApi7 } = await import("convex/server");
4717
4968
  const [queueData, unenriched, pending] = await Promise.all([
4718
- client.query(anyApi6.functions.tickets.getLocalQueuedTickets, {
4969
+ client.query(anyApi7.functions.tickets.getLocalQueuedTickets, {
4719
4970
  projectId: mapping.projectId
4720
4971
  }),
4721
- client.query(anyApi6.functions.localPipeline.getUnenrichedTickets, {
4972
+ client.query(anyApi7.functions.localPipeline.getUnenrichedTickets, {
4722
4973
  projectId: mapping.projectId
4723
4974
  }),
4724
- client.query(anyApi6.functions.localPipeline.getPendingSources, {
4975
+ client.query(anyApi7.functions.localPipeline.getPendingSources, {
4725
4976
  projectId: mapping.projectId
4726
4977
  })
4727
4978
  ]);
4728
4979
  console.log();
4729
4980
  if (queueData?.ready && queueData.ready.length > 0) {
4730
- console.log(chalk12.bold("Ready to implement:"));
4981
+ console.log(chalk13.bold("Ready to implement:"));
4731
4982
  for (const t of queueData.ready) {
4732
4983
  const ref = t.linearTicketId ?? t.ticketId;
4733
4984
  const prio = colorPriority(t.priority);
4734
4985
  console.log(
4735
- ` ${chalk12.bold(ref)} ${t.title.slice(0, 45).padEnd(45)} ${prio} ${chalk12.dim(t.type)}`
4986
+ ` ${chalk13.bold(ref)} ${t.title.slice(0, 45).padEnd(45)} ${prio} ${chalk13.dim(t.type)}`
4736
4987
  );
4737
4988
  }
4738
4989
  console.log();
4739
4990
  }
4740
4991
  if (queueData?.blocked && queueData.blocked.length > 0) {
4741
- console.log(chalk12.bold("Blocked:"));
4992
+ console.log(chalk13.bold("Blocked:"));
4742
4993
  for (const t of queueData.blocked) {
4743
4994
  console.log(
4744
- ` ${chalk12.bold(t.ticketId.slice(-6))} ${t.title.slice(0, 45)} ${chalk12.red("blocked by " + t.blockedBy.map((id) => id.slice(-6)).join(", "))}`
4995
+ ` ${chalk13.bold(t.ticketId.slice(-6))} ${t.title.slice(0, 45)} ${chalk13.red("blocked by " + t.blockedBy.map((id) => id.slice(-6)).join(", "))}`
4745
4996
  );
4746
4997
  }
4747
4998
  console.log();
4748
4999
  }
4749
5000
  if (unenriched && unenriched.length > 0) {
4750
- console.log(chalk12.bold("Needs enrichment:"));
5001
+ console.log(chalk13.bold("Needs enrichment:"));
4751
5002
  for (const t of unenriched) {
4752
5003
  const ref = t.ticketId;
4753
5004
  console.log(
4754
- ` ${chalk12.bold(ref.slice(-6))} ${t.title.slice(0, 45).padEnd(45)} ${chalk12.dim(t.priority)}`
5005
+ ` ${chalk13.bold(ref.slice(-6))} ${t.title.slice(0, 45).padEnd(45)} ${chalk13.dim(t.priority)}`
4755
5006
  );
4756
5007
  }
4757
5008
  console.log();
4758
5009
  }
4759
5010
  if (pending && pending.length > 0) {
4760
- console.log(chalk12.bold("Pending extraction:"));
5011
+ console.log(chalk13.bold("Pending extraction:"));
4761
5012
  for (const t of pending) {
4762
5013
  const ago = formatAgo(Date.now() - t.createdAt);
4763
5014
  console.log(
4764
- ` "${t.meetingTitle ?? "Untitled"}" ${chalk12.dim(`(uploaded ${ago})`)}`
5015
+ ` "${t.meetingTitle ?? "Untitled"}" ${chalk13.dim(`(uploaded ${ago})`)}`
4765
5016
  );
4766
5017
  }
4767
5018
  console.log();
4768
5019
  }
4769
5020
  if ((!queueData?.ready || queueData.ready.length === 0) && (!unenriched || unenriched.length === 0) && (!pending || pending.length === 0)) {
4770
- console.log(chalk12.dim("Queue is empty. Upload a transcript to get started."));
5021
+ console.log(chalk13.dim("Queue is empty. Upload a transcript to get started."));
4771
5022
  console.log();
4772
5023
  }
4773
5024
  });
4774
5025
  function colorPriority(p) {
4775
5026
  switch (p) {
4776
5027
  case "urgent":
4777
- return chalk12.red(p);
5028
+ return chalk13.red(p);
4778
5029
  case "high":
4779
- return chalk12.yellow(p);
5030
+ return chalk13.yellow(p);
4780
5031
  case "medium":
4781
- return chalk12.white(p);
5032
+ return chalk13.white(p);
4782
5033
  case "low":
4783
- return chalk12.dim(p);
5034
+ return chalk13.dim(p);
4784
5035
  default:
4785
5036
  return p;
4786
5037
  }
@@ -4796,29 +5047,29 @@ function formatAgo(ms) {
4796
5047
  }
4797
5048
 
4798
5049
  // src/commands/next.ts
4799
- import { Command as Command12 } from "commander";
5050
+ import { Command as Command13 } from "commander";
4800
5051
  import { resolve as resolve10 } from "path";
4801
- import { writeFileSync as writeFileSync10 } from "fs";
4802
- import { join as join12 } from "path";
4803
- import chalk13 from "chalk";
4804
- var nextCommand = new Command12("next").description("Claim the highest priority ticket and set up for implementation").option("--worktree", "Create a git worktree instead of checking out a branch").action(async (opts) => {
5052
+ import { writeFileSync as writeFileSync11 } from "fs";
5053
+ import { join as join13 } from "path";
5054
+ import chalk14 from "chalk";
5055
+ var nextCommand = new Command13("next").description("Claim the highest priority ticket and set up for implementation").option("--worktree", "Create a git worktree instead of checking out a branch").action(async (opts) => {
4805
5056
  const creds = requireAuth();
4806
5057
  const cwd = resolve10(process.cwd());
4807
5058
  const mapping = getProjectMapping(cwd);
4808
5059
  if (!mapping) {
4809
5060
  console.error(
4810
- chalk13.red("No project linked.") + " Run " + chalk13.cyan("yapout link") + " in a repo."
5061
+ chalk14.red("No project linked.") + " Run " + chalk14.cyan("yapout link") + " in a repo."
4811
5062
  );
4812
5063
  process.exit(1);
4813
5064
  }
4814
5065
  const client = createConvexClient(creds.token);
4815
- const { anyApi: anyApi6 } = await import("convex/server");
5066
+ const { anyApi: anyApi7 } = await import("convex/server");
4816
5067
  const data = await client.query(
4817
- anyApi6.functions.tickets.getLocalQueuedTickets,
5068
+ anyApi7.functions.tickets.getLocalQueuedTickets,
4818
5069
  { projectId: mapping.projectId }
4819
5070
  );
4820
5071
  if (!data?.ready || data.ready.length === 0) {
4821
- console.log(chalk13.dim("No tickets ready for implementation."));
5072
+ console.log(chalk14.dim("No tickets ready for implementation."));
4822
5073
  return;
4823
5074
  }
4824
5075
  const ticket = data.ready[0];
@@ -4826,32 +5077,32 @@ var nextCommand = new Command12("next").description("Claim the highest priority
4826
5077
  const config = readYapoutConfig(cwd);
4827
5078
  const defaultBranch = getDefaultBranch(cwd);
4828
5079
  const branchName = `${config.branch_prefix}/${ref.toLowerCase().replace(/\s+/g, "-")}-${ticket.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 40)}`;
4829
- console.log(chalk13.bold(`
5080
+ console.log(chalk14.bold(`
4830
5081
  Claimed: ${ref} "${ticket.title}"`));
4831
5082
  fetchOrigin(cwd);
4832
5083
  let workDir = cwd;
4833
5084
  if (opts.worktree) {
4834
5085
  const { createWorktree: createWorktree2 } = await import("./worktree-ZZZIL7TK.js");
4835
5086
  workDir = createWorktree2(cwd, ticket.ticketId, branchName, defaultBranch);
4836
- console.log(`Worktree: ${chalk13.cyan(workDir)}`);
5087
+ console.log(`Worktree: ${chalk14.cyan(workDir)}`);
4837
5088
  } else {
4838
5089
  checkoutNewBranch(branchName, defaultBranch, cwd);
4839
5090
  }
4840
- console.log(`Branch: ${chalk13.cyan(branchName)}`);
5091
+ console.log(`Branch: ${chalk14.cyan(branchName)}`);
4841
5092
  const brief = await client.query(
4842
- anyApi6.functions.tickets.getTicketBrief,
5093
+ anyApi7.functions.tickets.getTicketBrief,
4843
5094
  { ticketId: ticket.ticketId }
4844
5095
  );
4845
5096
  if (brief) {
4846
- const briefPath = join12(workDir, ".yapout", "brief.md");
5097
+ const briefPath = join13(workDir, ".yapout", "brief.md");
4847
5098
  const briefContent = formatBrief(ref, ticket, brief);
4848
- writeFileSync10(briefPath, briefContent);
4849
- console.log(`Brief: ${chalk13.cyan(briefPath)}`);
5099
+ writeFileSync11(briefPath, briefContent);
5100
+ console.log(`Brief: ${chalk14.cyan(briefPath)}`);
4850
5101
  }
4851
5102
  console.log();
4852
5103
  console.log("Start Claude Code to implement, or run:");
4853
5104
  console.log(
4854
- chalk13.cyan(
5105
+ chalk14.cyan(
4855
5106
  ` claude --dangerously-skip-permissions "Read .yapout/brief.md, implement it, run yapout_check, then yapout_ship"`
4856
5107
  )
4857
5108
  );
@@ -4901,21 +5152,21 @@ function formatBrief(ref, ticket, brief) {
4901
5152
  }
4902
5153
 
4903
5154
  // src/commands/recap.ts
4904
- import { Command as Command13 } from "commander";
5155
+ import { Command as Command14 } from "commander";
4905
5156
  import { resolve as resolve11 } from "path";
4906
- import chalk14 from "chalk";
4907
- var recapCommand = new Command13("recap").description("Show a summary of recent yapout activity").option("--week", "Show full week summary (default: today)").action(async (opts) => {
5157
+ import chalk15 from "chalk";
5158
+ var recapCommand = new Command14("recap").description("Show a summary of recent yapout activity").option("--week", "Show full week summary (default: today)").action(async (opts) => {
4908
5159
  const creds = requireAuth();
4909
5160
  const cwd = resolve11(process.cwd());
4910
5161
  const mapping = getProjectMapping(cwd);
4911
5162
  if (!mapping) {
4912
5163
  console.error(
4913
- chalk14.red("No project linked.") + " Run " + chalk14.cyan("yapout link") + " in a repo."
5164
+ chalk15.red("No project linked.") + " Run " + chalk15.cyan("yapout link") + " in a repo."
4914
5165
  );
4915
5166
  process.exit(1);
4916
5167
  }
4917
5168
  const client = createConvexClient(creds.token);
4918
- const { anyApi: anyApi6 } = await import("convex/server");
5169
+ const { anyApi: anyApi7 } = await import("convex/server");
4919
5170
  const now = /* @__PURE__ */ new Date();
4920
5171
  const todayStart = new Date(
4921
5172
  now.getFullYear(),
@@ -4925,33 +5176,33 @@ var recapCommand = new Command13("recap").description("Show a summary of recent
4925
5176
  const weekStart = todayStart - 6 * 24 * 60 * 60 * 1e3;
4926
5177
  const since = opts.week ? weekStart : todayStart;
4927
5178
  const data = await client.query(
4928
- anyApi6.functions.localPipeline.getRecentActivity,
5179
+ anyApi7.functions.localPipeline.getRecentActivity,
4929
5180
  { projectId: mapping.projectId, since }
4930
5181
  );
4931
5182
  if (!data) {
4932
- console.log(chalk14.dim("Could not fetch activity data."));
5183
+ console.log(chalk15.dim("Could not fetch activity data."));
4933
5184
  return;
4934
5185
  }
4935
5186
  const period = opts.week ? "This week" : "Today";
4936
5187
  console.log();
4937
- console.log(chalk14.bold(`${period}:`));
5188
+ console.log(chalk15.bold(`${period}:`));
4938
5189
  if (data.recentTickets.length > 0) {
4939
5190
  for (const t of data.recentTickets) {
4940
5191
  const ref = t.linearTicketId ?? "ticket";
4941
- console.log(` ${chalk14.green("\u2713")} ${ref} ${t.title}`);
5192
+ console.log(` ${chalk15.green("\u2713")} ${ref} ${t.title}`);
4942
5193
  }
4943
5194
  }
4944
5195
  if (data.recentPRs.length > 0) {
4945
5196
  for (const p of data.recentPRs) {
4946
5197
  const prRef = p.githubPrNumber ? `PR #${p.githubPrNumber}` : "PR";
4947
- const statusColor = p.status === "opened" ? chalk14.green : p.status === "draft" ? chalk14.dim : chalk14.yellow;
5198
+ const statusColor = p.status === "opened" ? chalk15.green : p.status === "draft" ? chalk15.dim : chalk15.yellow;
4948
5199
  console.log(
4949
5200
  ` ${statusColor("\u2191")} ${p.prTitle.slice(0, 45)} ${statusColor(prRef)} ${statusColor(p.status)}`
4950
5201
  );
4951
5202
  }
4952
5203
  }
4953
5204
  if (data.recentTickets.length === 0 && data.recentPRs.length === 0) {
4954
- console.log(chalk14.dim(" No activity yet."));
5205
+ console.log(chalk15.dim(" No activity yet."));
4955
5206
  }
4956
5207
  console.log();
4957
5208
  console.log(
@@ -4961,12 +5212,12 @@ var recapCommand = new Command13("recap").description("Show a summary of recent
4961
5212
  });
4962
5213
 
4963
5214
  // src/commands/yap.ts
4964
- import { Command as Command14 } from "commander";
4965
- import chalk15 from "chalk";
4966
- var yapCommand = new Command14("yap").description(
5215
+ import { Command as Command15 } from "commander";
5216
+ import chalk16 from "chalk";
5217
+ var yapCommand = new Command15("yap").description(
4967
5218
  "Start a yap session \u2014 brainstorm with an AI that knows your codebase"
4968
5219
  ).action(() => {
4969
- console.log(chalk15.bold("yapout yap sessions"));
5220
+ console.log(chalk16.bold("yapout yap sessions"));
4970
5221
  console.log();
4971
5222
  console.log(
4972
5223
  "Yap sessions run inside Claude \u2014 Desktop, CLI, or web \u2014 anywhere the"
@@ -4975,27 +5226,27 @@ var yapCommand = new Command14("yap").description(
4975
5226
  console.log();
4976
5227
  console.log("Just tell Claude:");
4977
5228
  console.log(
4978
- chalk15.green(` "Let's have a yap session about [topic]"`)
5229
+ chalk16.green(` "Let's have a yap session about [topic]"`)
4979
5230
  );
4980
5231
  console.log(
4981
- chalk15.green(
5232
+ chalk16.green(
4982
5233
  ' "I want to brainstorm [idea] \u2014 be a skeptical QA engineer"'
4983
5234
  )
4984
5235
  );
4985
5236
  console.log();
4986
- console.log(chalk15.dim("Personas: tech lead, qa engineer, product owner, end user, or custom"));
5237
+ console.log(chalk16.dim("Personas: tech lead, qa engineer, product owner, end user, or custom"));
4987
5238
  console.log(
4988
- chalk15.dim(
5239
+ chalk16.dim(
4989
5240
  "Claude will call yapout_start_yap to get instructions and yapout_submit_yap_session when done."
4990
5241
  )
4991
5242
  );
4992
5243
  });
4993
5244
 
4994
5245
  // src/commands/handle-uri.ts
4995
- import { Command as Command15 } from "commander";
4996
- import { spawn as spawn2 } from "child_process";
4997
- import { platform as platform2 } from "os";
4998
- import chalk16 from "chalk";
5246
+ import { Command as Command16 } from "commander";
5247
+ import { spawn as spawn3 } from "child_process";
5248
+ import { platform as platform3 } from "os";
5249
+ import chalk17 from "chalk";
4999
5250
  var VALID_ACTIONS = ["claim", "enrich", "enrich-bulk", "enrich-bundle", "yap", "compact"];
5000
5251
  function parseYapoutUri(raw) {
5001
5252
  const url = new URL(raw);
@@ -5108,11 +5359,11 @@ function findProjectDir() {
5108
5359
  return dirs[0];
5109
5360
  }
5110
5361
  function launchTerminal(cwd, claudeArgs) {
5111
- const os = platform2();
5362
+ const os = platform3();
5112
5363
  const claudeCmd = `claude ${claudeArgs.map(shellEscape).join(" ")}`;
5113
5364
  if (os === "win32") {
5114
5365
  const wtArgs = ["wt", "-d", cwd, "cmd", "/k", claudeCmd];
5115
- const child = spawn2("cmd", ["/c", "start", ...wtArgs], {
5366
+ const child = spawn3("cmd", ["/c", "start", ...wtArgs], {
5116
5367
  cwd,
5117
5368
  stdio: "ignore",
5118
5369
  detached: true,
@@ -5120,7 +5371,7 @@ function launchTerminal(cwd, claudeArgs) {
5120
5371
  });
5121
5372
  child.unref();
5122
5373
  child.on("error", () => {
5123
- const fallback = spawn2(
5374
+ const fallback = spawn3(
5124
5375
  "cmd",
5125
5376
  ["/c", "start", "cmd", "/k", claudeCmd],
5126
5377
  { cwd, stdio: "ignore", detached: true, shell: true }
@@ -5133,7 +5384,7 @@ function launchTerminal(cwd, claudeArgs) {
5133
5384
  activate
5134
5385
  do script "cd ${shellEscape(cwd)} && ${escaped}"
5135
5386
  end tell`;
5136
- const child = spawn2("osascript", ["-e", script], {
5387
+ const child = spawn3("osascript", ["-e", script], {
5137
5388
  stdio: "ignore",
5138
5389
  detached: true
5139
5390
  });
@@ -5148,7 +5399,7 @@ end tell`;
5148
5399
  let launched = false;
5149
5400
  for (const term of terminals) {
5150
5401
  try {
5151
- const child = spawn2(term.cmd, term.args, {
5402
+ const child = spawn3(term.cmd, term.args, {
5152
5403
  stdio: "ignore",
5153
5404
  detached: true
5154
5405
  });
@@ -5161,44 +5412,44 @@ end tell`;
5161
5412
  }
5162
5413
  if (!launched) {
5163
5414
  console.error(
5164
- chalk16.red("Could not find a terminal emulator. Install gnome-terminal, konsole, or xterm.")
5415
+ chalk17.red("Could not find a terminal emulator. Install gnome-terminal, konsole, or xterm.")
5165
5416
  );
5166
5417
  process.exit(1);
5167
5418
  }
5168
5419
  }
5169
5420
  }
5170
5421
  function shellEscape(s) {
5171
- if (platform2() === "win32") {
5422
+ if (platform3() === "win32") {
5172
5423
  return `"${s.replace(/"/g, '""')}"`;
5173
5424
  }
5174
5425
  return `'${s.replace(/'/g, "'\\''")}'`;
5175
5426
  }
5176
- var handleUriCommand = new Command15("handle-uri").description("Handle a yapout:// URI (used by OS protocol handler)").argument("<uri>", "The yapout:// URI to handle").action(async (uri) => {
5427
+ var handleUriCommand = new Command16("handle-uri").description("Handle a yapout:// URI (used by OS protocol handler)").argument("<uri>", "The yapout:// URI to handle").action(async (uri) => {
5177
5428
  try {
5178
5429
  const parsed = parseYapoutUri(uri);
5179
5430
  const prompt = buildPrompt(parsed);
5180
5431
  const cwd = findProjectDir();
5181
5432
  if (!cwd) {
5182
5433
  console.error(
5183
- chalk16.red(
5434
+ chalk17.red(
5184
5435
  "No linked project found. Run `yapout init` or `yapout link` in your repo first."
5185
5436
  )
5186
5437
  );
5187
5438
  process.exit(1);
5188
5439
  }
5189
5440
  const label = parsed.ticketId ? `${parsed.action} ${parsed.ticketId}` : parsed.action;
5190
- console.log(chalk16.dim(`Launching Claude Code to ${label}...`));
5441
+ console.log(chalk17.dim(`Launching Claude Code to ${label}...`));
5191
5442
  launchTerminal(cwd, ["--dangerously-skip-permissions", prompt]);
5192
5443
  setTimeout(() => process.exit(0), 500);
5193
5444
  } catch (err) {
5194
- console.error(chalk16.red(err.message));
5445
+ console.error(chalk17.red(err.message));
5195
5446
  process.exit(1);
5196
5447
  }
5197
5448
  });
5198
5449
 
5199
5450
  // src/index.ts
5200
- var program = new Command16();
5201
- program.name("yapout").description("yapout \u2014 from meeting transcript to merged PR").version("0.8.0");
5451
+ var program = new Command17();
5452
+ program.name("yapout").description("yapout \u2014 from meeting transcript to merged PR").version("0.10.0");
5202
5453
  program.addCommand(loginCommand);
5203
5454
  program.addCommand(logoutCommand);
5204
5455
  program.addCommand(initCommand);
@@ -5214,4 +5465,5 @@ program.addCommand(nextCommand);
5214
5465
  program.addCommand(recapCommand);
5215
5466
  program.addCommand(yapCommand);
5216
5467
  program.addCommand(handleUriCommand);
5468
+ program.addCommand(serveCommand);
5217
5469
  program.parse();