yapout 0.8.0 → 0.9.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 +599 -353
  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.9.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.9.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,14 @@ 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
859
  const authUrl = `${appUrl}/auth/cli?port=${port}`;
601
- console.log(chalk.dim(`Opening browser...`));
860
+ console.log(chalk3.dim(`Opening browser...`));
602
861
  await open(authUrl);
603
- console.log(chalk.dim("Waiting for authentication in browser..."));
862
+ console.log(chalk3.dim("Waiting for authentication in browser..."));
604
863
  try {
605
864
  const result = await data;
606
865
  const creds = {
@@ -615,74 +874,60 @@ var loginCommand = new Command("login").description("Authenticate with yapout").
615
874
  Math.round((result.expiresAt - Date.now()) / 864e5)
616
875
  );
617
876
  console.log(
618
- chalk.green("Logged in as ") + chalk.bold(result.email) + chalk.dim(
877
+ chalk3.green("Logged in as ") + chalk3.bold(result.email) + chalk3.dim(
619
878
  ` (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
620
879
  )
621
880
  );
622
881
  try {
623
882
  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, {
883
+ const deviceId = createHash2("sha256").update(hostname2() + userInfo2().username).digest("hex").slice(0, 16);
884
+ await client.mutation(anyApi3.functions.devices.registerDevice, {
626
885
  deviceId,
627
- name: hostname(),
628
- cliVersion: CLI_VERSION
886
+ name: hostname2(),
887
+ cliVersion: CLI_VERSION2
629
888
  });
630
889
  } catch {
631
- console.warn(chalk.dim("Note: Could not register device. This is non-fatal."));
890
+ console.warn(chalk3.dim("Note: Could not register device. This is non-fatal."));
632
891
  }
633
892
  try {
634
893
  registerProtocolHandler();
635
894
  console.log(
636
- chalk.dim("Registered yapout:// protocol handler")
895
+ chalk3.dim("Registered yapout:// protocol handler")
637
896
  );
638
897
  } catch {
639
898
  }
899
+ try {
900
+ spawnServeDaemon(process.argv[1]);
901
+ console.log(chalk3.dim("Started yapout serve in the background"));
902
+ } catch {
903
+ }
640
904
  process.exit(0);
641
905
  } catch (err) {
642
- console.error(chalk.red(err.message));
906
+ console.error(chalk3.red(err.message));
643
907
  process.exit(1);
644
908
  }
645
909
  });
646
910
 
647
911
  // 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(() => {
912
+ import { Command as Command3 } from "commander";
913
+ import chalk4 from "chalk";
914
+ var logoutCommand = new Command3("logout").description("Log out of yapout").action(() => {
651
915
  deleteCredentials();
652
- console.log(chalk2.green("Logged out."));
916
+ console.log(chalk4.green("Logged out."));
653
917
  });
654
918
 
655
919
  // src/commands/link.ts
656
- import { Command as Command3 } from "commander";
657
- import { resolve as resolve2, join as join3 } from "path";
920
+ import { Command as Command4 } from "commander";
921
+ import { resolve as resolve2, join as join4 } from "path";
658
922
  import {
659
- existsSync as existsSync2,
923
+ existsSync as existsSync3,
660
924
  mkdirSync as mkdirSync3,
661
- readFileSync as readFileSync2,
662
- writeFileSync as writeFileSync3,
925
+ readFileSync as readFileSync3,
926
+ writeFileSync as writeFileSync4,
663
927
  appendFileSync
664
928
  } 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
- }
929
+ import { hostname as hostname3 } from "os";
930
+ import chalk5 from "chalk";
686
931
 
687
932
  // src/lib/prompts.ts
688
933
  import { select } from "@inquirer/prompts";
@@ -734,7 +979,7 @@ branch_prefix: feat
734
979
  # {{ticket.linearTicketId}}, {{ticket.id}}
735
980
  # commit_template: "{{ticket.type}}({{ticket.linearTicketId}}): {{ticket.title}}"
736
981
  `;
737
- var linkCommand = new Command3("link").description("Link the current directory to a yapout project").action(async () => {
982
+ var linkCommand = new Command4("link").description("Link the current directory to a yapout project").action(async () => {
738
983
  const creds = requireAuth();
739
984
  const cwd = resolveRepoRoot(resolve2(process.cwd()));
740
985
  const client = createConvexClient(creds.token);
@@ -746,25 +991,25 @@ var linkCommand = new Command3("link").description("Link the current directory t
746
991
  );
747
992
  } catch (err) {
748
993
  console.error(
749
- chalk4.red("Failed to fetch projects."),
994
+ chalk5.red("Failed to fetch projects."),
750
995
  err.message
751
996
  );
752
997
  process.exit(1);
753
998
  }
754
999
  if (projects.length === 0) {
755
1000
  console.error(
756
- chalk4.yellow("No projects found.") + " Create one at " + chalk4.cyan(`${getAppUrl()}/dashboard`)
1001
+ chalk5.yellow("No projects found.") + " Create one at " + chalk5.cyan(`${getAppUrl()}/dashboard`)
757
1002
  );
758
1003
  process.exit(1);
759
1004
  }
760
1005
  const selected = await pickProject(projects);
761
- const device = getOrCreateDeviceIdentity(hostname2());
1006
+ const device = getOrCreateDeviceIdentity(hostname3());
762
1007
  try {
763
1008
  await client.mutation(anyApi.functions.devices.registerDevice, {
764
1009
  deviceId: device.deviceId,
765
1010
  name: device.name,
766
1011
  cliVersion: getCliVersion(),
767
- machineHostname: hostname2()
1012
+ machineHostname: hostname3()
768
1013
  });
769
1014
  await client.mutation(anyApi.functions.projectCheckouts.linkCheckout, {
770
1015
  projectId: selected.id,
@@ -773,7 +1018,7 @@ var linkCommand = new Command3("link").description("Link the current directory t
773
1018
  });
774
1019
  } catch (err) {
775
1020
  console.warn(
776
- chalk4.yellow("Warning: failed to record this checkout \u2014 "),
1021
+ chalk5.yellow("Warning: failed to record this checkout \u2014 "),
777
1022
  err.message
778
1023
  );
779
1024
  }
@@ -782,17 +1027,17 @@ var linkCommand = new Command3("link").description("Link the current directory t
782
1027
  projectName: selected.name,
783
1028
  linkedAt: Date.now()
784
1029
  });
785
- const yapoutDir = join3(cwd, ".yapout");
786
- if (!existsSync2(yapoutDir)) {
1030
+ const yapoutDir = join4(cwd, ".yapout");
1031
+ if (!existsSync3(yapoutDir)) {
787
1032
  mkdirSync3(yapoutDir, { recursive: true });
788
1033
  }
789
- const configPath = join3(yapoutDir, "config.yml");
790
- if (!existsSync2(configPath)) {
791
- writeFileSync3(configPath, CONFIG_YAML_CONTENT);
1034
+ const configPath = join4(yapoutDir, "config.yml");
1035
+ if (!existsSync3(configPath)) {
1036
+ writeFileSync4(configPath, CONFIG_YAML_CONTENT);
792
1037
  }
793
- const gitignorePath = join3(cwd, ".gitignore");
794
- if (existsSync2(gitignorePath)) {
795
- const content = readFileSync2(gitignorePath, "utf-8");
1038
+ const gitignorePath = join4(cwd, ".gitignore");
1039
+ if (existsSync3(gitignorePath)) {
1040
+ const content = readFileSync3(gitignorePath, "utf-8");
796
1041
  if (!content.includes(".yapout/")) {
797
1042
  appendFileSync(
798
1043
  gitignorePath,
@@ -800,13 +1045,13 @@ var linkCommand = new Command3("link").description("Link the current directory t
800
1045
  );
801
1046
  }
802
1047
  } else {
803
- writeFileSync3(gitignorePath, "# yapout local config\n.yapout/\n");
1048
+ writeFileSync4(gitignorePath, "# yapout local config\n.yapout/\n");
804
1049
  }
805
- const mcpPath = join3(cwd, ".mcp.json");
1050
+ const mcpPath = join4(cwd, ".mcp.json");
806
1051
  let mcpConfig = {};
807
- if (existsSync2(mcpPath)) {
1052
+ if (existsSync3(mcpPath)) {
808
1053
  try {
809
- mcpConfig = JSON.parse(readFileSync2(mcpPath, "utf-8"));
1054
+ mcpConfig = JSON.parse(readFileSync3(mcpPath, "utf-8"));
810
1055
  } catch {
811
1056
  }
812
1057
  }
@@ -815,17 +1060,17 @@ var linkCommand = new Command3("link").description("Link the current directory t
815
1060
  command: "yapout",
816
1061
  args: ["mcp-server"]
817
1062
  };
818
- writeFileSync3(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1063
+ writeFileSync4(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
819
1064
  const label = selected.githubRepoFullName ? `${selected.name} (${selected.githubRepoFullName})` : selected.name;
820
1065
  const orgSuffix = selected.org ? ` in ${selected.org.name}` : "";
821
1066
  console.log(
822
- chalk4.green(`Linked to ${label}${orgSuffix}.`) + " Claude Code will discover yapout tools automatically."
1067
+ chalk5.green(`Linked to ${label}${orgSuffix}.`) + " Claude Code will discover yapout tools automatically."
823
1068
  );
824
1069
  });
825
1070
  function getCliVersion() {
826
1071
  try {
827
1072
  const pkg = JSON.parse(
828
- readFileSync2(join3(import.meta.dirname, "..", "package.json"), "utf-8")
1073
+ readFileSync3(join4(import.meta.dirname, "..", "package.json"), "utf-8")
829
1074
  );
830
1075
  return pkg.version ?? "unknown";
831
1076
  } catch {
@@ -834,15 +1079,15 @@ function getCliVersion() {
834
1079
  }
835
1080
 
836
1081
  // 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 () => {
1082
+ import { Command as Command5 } from "commander";
1083
+ import { resolve as resolve3, join as join5 } from "path";
1084
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync5, rmSync } from "fs";
1085
+ import chalk6 from "chalk";
1086
+ var unlinkCommand = new Command5("unlink").description("Unlink the current directory from its yapout project").action(async () => {
842
1087
  const cwd = resolve3(process.cwd());
843
1088
  const mapping = getProjectMapping(cwd);
844
1089
  if (!mapping) {
845
- console.error(chalk5.yellow("No project linked to this directory."));
1090
+ console.error(chalk6.yellow("No project linked to this directory."));
846
1091
  process.exit(1);
847
1092
  }
848
1093
  const device = readDeviceIdentity();
@@ -856,26 +1101,26 @@ var unlinkCommand = new Command4("unlink").description("Unlink the current direc
856
1101
  });
857
1102
  } catch (err) {
858
1103
  console.warn(
859
- chalk5.yellow("Warning: failed to update server \u2014 "),
1104
+ chalk6.yellow("Warning: failed to update server \u2014 "),
860
1105
  err.message
861
1106
  );
862
1107
  }
863
1108
  }
864
1109
  removeProjectMapping(cwd);
865
- const yapoutDir = join4(cwd, ".yapout");
866
- if (existsSync3(yapoutDir)) {
1110
+ const yapoutDir = join5(cwd, ".yapout");
1111
+ if (existsSync4(yapoutDir)) {
867
1112
  rmSync(yapoutDir, { recursive: true });
868
1113
  }
869
- const mcpPath = join4(cwd, ".mcp.json");
870
- if (existsSync3(mcpPath)) {
1114
+ const mcpPath = join5(cwd, ".mcp.json");
1115
+ if (existsSync4(mcpPath)) {
871
1116
  try {
872
- const mcpConfig = JSON.parse(readFileSync3(mcpPath, "utf-8"));
1117
+ const mcpConfig = JSON.parse(readFileSync4(mcpPath, "utf-8"));
873
1118
  if (mcpConfig.mcpServers?.yapout) {
874
1119
  delete mcpConfig.mcpServers.yapout;
875
1120
  if (Object.keys(mcpConfig.mcpServers).length === 0) {
876
1121
  rmSync(mcpPath);
877
1122
  } else {
878
- writeFileSync4(
1123
+ writeFileSync5(
879
1124
  mcpPath,
880
1125
  JSON.stringify(mcpConfig, null, 2) + "\n"
881
1126
  );
@@ -884,23 +1129,23 @@ var unlinkCommand = new Command4("unlink").description("Unlink the current direc
884
1129
  } catch {
885
1130
  }
886
1131
  }
887
- console.log(chalk5.green("Unlinked."));
1132
+ console.log(chalk6.green("Unlinked."));
888
1133
  });
889
1134
 
890
1135
  // src/commands/status.ts
891
- import { Command as Command5 } from "commander";
1136
+ import { Command as Command6 } from "commander";
892
1137
  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"));
1138
+ import chalk7 from "chalk";
1139
+ var statusCommand = new Command6("status").description("Show yapout status for this directory").action(() => {
1140
+ console.log(chalk7.bold("yapout status\n"));
896
1141
  const creds = readCredentials();
897
1142
  if (!creds) {
898
1143
  console.log(
899
- ` Auth: ${chalk6.red("Not logged in.")} Run ${chalk6.cyan("yapout login")}.`
1144
+ ` Auth: ${chalk7.red("Not logged in.")} Run ${chalk7.cyan("yapout login")}.`
900
1145
  );
901
1146
  } else if (Date.now() > creds.expiresAt) {
902
1147
  console.log(
903
- ` Auth: ${chalk6.red("Session expired.")} Run ${chalk6.cyan("yapout login")}.`
1148
+ ` Auth: ${chalk7.red("Session expired.")} Run ${chalk7.cyan("yapout login")}.`
904
1149
  );
905
1150
  } else {
906
1151
  const daysLeft = Math.max(
@@ -908,35 +1153,35 @@ var statusCommand = new Command5("status").description("Show yapout status for t
908
1153
  Math.round((creds.expiresAt - Date.now()) / 864e5)
909
1154
  );
910
1155
  console.log(
911
- ` Auth: ${chalk6.green(creds.email)} (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
1156
+ ` Auth: ${chalk7.green(creds.email)} (expires in ${daysLeft} day${daysLeft === 1 ? "" : "s"})`
912
1157
  );
913
1158
  }
914
1159
  const cwd = resolve4(process.cwd());
915
1160
  const mapping = getProjectMapping(cwd);
916
1161
  if (!mapping) {
917
1162
  console.log(
918
- ` Project: ${chalk6.yellow("No project linked.")} Run ${chalk6.cyan("yapout link")} in a repo.`
1163
+ ` Project: ${chalk7.yellow("No project linked.")} Run ${chalk7.cyan("yapout link")} in a repo.`
919
1164
  );
920
1165
  } else {
921
- console.log(` Project: ${chalk6.green(mapping.projectName)}`);
1166
+ console.log(` Project: ${chalk7.green(mapping.projectName)}`);
922
1167
  }
923
- console.log(` Daemon: ${chalk6.dim("not running")}`);
924
- console.log(` Work: ${chalk6.dim("no active tickets")}`);
1168
+ console.log(` Daemon: ${chalk7.dim("not running")}`);
1169
+ console.log(` Work: ${chalk7.dim("no active tickets")}`);
925
1170
  console.log();
926
1171
  });
927
1172
 
928
1173
  // src/commands/init.ts
929
- import { Command as Command6 } from "commander";
930
- import { resolve as resolve5, join as join5 } from "path";
1174
+ import { Command as Command7 } from "commander";
1175
+ import { resolve as resolve5, join as join6 } from "path";
931
1176
  import {
932
- existsSync as existsSync4,
1177
+ existsSync as existsSync5,
933
1178
  mkdirSync as mkdirSync4,
934
- writeFileSync as writeFileSync5,
935
- readFileSync as readFileSync4,
1179
+ writeFileSync as writeFileSync6,
1180
+ readFileSync as readFileSync5,
936
1181
  appendFileSync as appendFileSync2
937
1182
  } from "fs";
938
- import { hostname as hostname3 } from "os";
939
- import chalk7 from "chalk";
1183
+ import { hostname as hostname4 } from "os";
1184
+ import chalk8 from "chalk";
940
1185
  var CONFIG_YAML_CONTENT2 = `# yapout local configuration
941
1186
  # See: https://docs.yapout.dev/cli/config
942
1187
 
@@ -961,7 +1206,7 @@ branch_prefix: feat
961
1206
  # {{ticket.linearTicketId}}, {{ticket.id}}
962
1207
  # commit_template: "{{ticket.type}}({{ticket.linearTicketId}}): {{ticket.title}}"
963
1208
  `;
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) => {
1209
+ 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
1210
  const creds = requireAuth();
966
1211
  const cwd = resolveRepoRoot(resolve5(process.cwd()));
967
1212
  let repoFullName;
@@ -971,7 +1216,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
971
1216
  defaultBranch = getDefaultBranch(cwd);
972
1217
  } catch (err) {
973
1218
  console.error(
974
- chalk7.red("Not a git repo with a GitHub remote."),
1219
+ chalk8.red("Not a git repo with a GitHub remote."),
975
1220
  err.message
976
1221
  );
977
1222
  process.exit(1);
@@ -986,14 +1231,14 @@ var initCommand = new Command6("init").description("Create a yapout project from
986
1231
  );
987
1232
  } catch (err) {
988
1233
  console.error(
989
- chalk7.red("Failed to load your orgs."),
1234
+ chalk8.red("Failed to load your orgs."),
990
1235
  err.message
991
1236
  );
992
1237
  process.exit(1);
993
1238
  }
994
1239
  if (!orgs || orgs.length === 0) {
995
1240
  console.error(
996
- chalk7.red(
1241
+ chalk8.red(
997
1242
  "You aren't a member of any org. Sign in to the web app once to create your personal org, then re-run."
998
1243
  )
999
1244
  );
@@ -1005,10 +1250,10 @@ var initCommand = new Command6("init").description("Create a yapout project from
1005
1250
  const match = orgs.find((o) => o.org.slug === options.org);
1006
1251
  if (!match) {
1007
1252
  console.error(
1008
- chalk7.red(`Org "${options.org}" not found among your memberships.`)
1253
+ chalk8.red(`Org "${options.org}" not found among your memberships.`)
1009
1254
  );
1010
1255
  console.error(
1011
- chalk7.dim(
1256
+ chalk8.dim(
1012
1257
  "Available: " + orgs.map((o) => o.org.slug).join(", ")
1013
1258
  )
1014
1259
  );
@@ -1020,7 +1265,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1020
1265
  chosenOrgId = orgs[0].org._id;
1021
1266
  chosenOrgName = orgs[0].org.name;
1022
1267
  console.log(
1023
- chalk7.dim(`Creating in `) + chalk7.cyan(chosenOrgName)
1268
+ chalk8.dim(`Creating in `) + chalk8.cyan(chosenOrgName)
1024
1269
  );
1025
1270
  } else {
1026
1271
  const picked = await pickOrg(
@@ -1034,17 +1279,17 @@ var initCommand = new Command6("init").description("Create a yapout project from
1034
1279
  chosenOrgId = picked.id;
1035
1280
  chosenOrgName = picked.name;
1036
1281
  }
1037
- const device = getOrCreateDeviceIdentity(hostname3());
1282
+ const device = getOrCreateDeviceIdentity(hostname4());
1038
1283
  try {
1039
1284
  await client.mutation(anyApi.functions.devices.registerDevice, {
1040
1285
  deviceId: device.deviceId,
1041
1286
  name: device.name,
1042
1287
  cliVersion: getCliVersion2(),
1043
- machineHostname: hostname3()
1288
+ machineHostname: hostname4()
1044
1289
  });
1045
1290
  } catch (err) {
1046
1291
  console.warn(
1047
- chalk7.yellow("Warning: device registration failed \u2014 "),
1292
+ chalk8.yellow("Warning: device registration failed \u2014 "),
1048
1293
  err.message
1049
1294
  );
1050
1295
  }
@@ -1061,7 +1306,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1061
1306
  );
1062
1307
  } catch (err) {
1063
1308
  console.error(
1064
- chalk7.red("Failed to create project."),
1309
+ chalk8.red("Failed to create project."),
1065
1310
  err.message
1066
1311
  );
1067
1312
  process.exit(1);
@@ -1074,7 +1319,7 @@ var initCommand = new Command6("init").description("Create a yapout project from
1074
1319
  });
1075
1320
  } catch (err) {
1076
1321
  console.warn(
1077
- chalk7.yellow("Warning: failed to record project checkout \u2014 "),
1322
+ chalk8.yellow("Warning: failed to record project checkout \u2014 "),
1078
1323
  err.message
1079
1324
  );
1080
1325
  }
@@ -1083,15 +1328,15 @@ var initCommand = new Command6("init").description("Create a yapout project from
1083
1328
  projectName: result.projectName,
1084
1329
  linkedAt: Date.now()
1085
1330
  });
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");
1331
+ const yapoutDir = join6(cwd, ".yapout");
1332
+ if (!existsSync5(yapoutDir)) mkdirSync4(yapoutDir, { recursive: true });
1333
+ const configPath = join6(yapoutDir, "config.yml");
1334
+ if (!existsSync5(configPath)) {
1335
+ writeFileSync6(configPath, CONFIG_YAML_CONTENT2);
1336
+ }
1337
+ const gitignorePath = join6(cwd, ".gitignore");
1338
+ if (existsSync5(gitignorePath)) {
1339
+ const content = readFileSync5(gitignorePath, "utf-8");
1095
1340
  if (!content.includes(".yapout/")) {
1096
1341
  appendFileSync2(
1097
1342
  gitignorePath,
@@ -1099,11 +1344,11 @@ var initCommand = new Command6("init").description("Create a yapout project from
1099
1344
  );
1100
1345
  }
1101
1346
  }
1102
- const mcpPath = join5(cwd, ".mcp.json");
1347
+ const mcpPath = join6(cwd, ".mcp.json");
1103
1348
  let mcpConfig = {};
1104
- if (existsSync4(mcpPath)) {
1349
+ if (existsSync5(mcpPath)) {
1105
1350
  try {
1106
- mcpConfig = JSON.parse(readFileSync4(mcpPath, "utf-8"));
1351
+ mcpConfig = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1107
1352
  } catch {
1108
1353
  }
1109
1354
  }
@@ -1112,20 +1357,20 @@ var initCommand = new Command6("init").description("Create a yapout project from
1112
1357
  command: "yapout",
1113
1358
  args: ["mcp-server"]
1114
1359
  };
1115
- writeFileSync5(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1360
+ writeFileSync6(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1116
1361
  console.log(
1117
- chalk7.green(`Created project "${result.projectName}"`) + chalk7.dim(
1362
+ chalk8.green(`Created project "${result.projectName}"`) + chalk8.dim(
1118
1363
  ` in ${chosenOrgName} (${repoFullName}, branch: ${defaultBranch})`
1119
1364
  )
1120
1365
  );
1121
1366
  console.log(
1122
- chalk7.dim("Run ") + chalk7.cyan("yapout_compact") + chalk7.dim(" in Claude Code to generate project context.")
1367
+ chalk8.dim("Run ") + chalk8.cyan("yapout_compact") + chalk8.dim(" in Claude Code to generate project context.")
1123
1368
  );
1124
1369
  });
1125
1370
  function getCliVersion2() {
1126
1371
  try {
1127
1372
  const pkg = JSON.parse(
1128
- readFileSync4(join5(import.meta.dirname, "..", "package.json"), "utf-8")
1373
+ readFileSync5(join6(import.meta.dirname, "..", "package.json"), "utf-8")
1129
1374
  );
1130
1375
  return pkg.version ?? "unknown";
1131
1376
  } catch {
@@ -1134,18 +1379,18 @@ function getCliVersion2() {
1134
1379
  }
1135
1380
 
1136
1381
  // src/commands/mcp-server.ts
1137
- import { Command as Command7 } from "commander";
1382
+ import { Command as Command8 } from "commander";
1138
1383
 
1139
1384
  // src/mcp/server.ts
1140
1385
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1141
1386
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1142
1387
  import { ConvexHttpClient as ConvexHttpClient2 } from "convex/browser";
1143
- import { anyApi as anyApi3 } from "convex/server";
1388
+ import { anyApi as anyApi4 } from "convex/server";
1144
1389
 
1145
1390
  // src/mcp/tools/init.ts
1146
1391
  import { z } from "zod";
1147
- import { join as join6 } from "path";
1148
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
1392
+ import { join as join7 } from "path";
1393
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "fs";
1149
1394
  import { stringify as yamlStringify } from "yaml";
1150
1395
  function registerInitTool(server, ctx) {
1151
1396
  server.tool(
@@ -1161,7 +1406,7 @@ function registerInitTool(server, ctx) {
1161
1406
  const defaultBranch = getDefaultBranch(repoRoot);
1162
1407
  const projectName = args.name || repoFullName.split("/")[1] || "unnamed";
1163
1408
  const result = await ctx.client.mutation(
1164
- anyApi3.functions.projects.createProjectFromCli,
1409
+ anyApi4.functions.projects.createProjectFromCli,
1165
1410
  {
1166
1411
  name: projectName,
1167
1412
  githubRepoFullName: repoFullName,
@@ -1176,11 +1421,11 @@ function registerInitTool(server, ctx) {
1176
1421
  projectName: result.projectName,
1177
1422
  linkedAt: Date.now()
1178
1423
  });
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(
1424
+ const yapoutDir = join7(repoRoot, ".yapout");
1425
+ if (!existsSync6(yapoutDir)) mkdirSync5(yapoutDir, { recursive: true });
1426
+ const configPath = join7(yapoutDir, "config.yml");
1427
+ if (!existsSync6(configPath)) {
1428
+ writeFileSync7(
1184
1429
  configPath,
1185
1430
  `# yapout local configuration
1186
1431
 
@@ -1249,7 +1494,7 @@ function registerCompactTool(server, ctx) {
1249
1494
  let lastUpdated;
1250
1495
  try {
1251
1496
  const project = await ctx.client.query(
1252
- anyApi3.functions.projects.getProject,
1497
+ anyApi4.functions.projects.getProject,
1253
1498
  { projectId: ctx.projectId }
1254
1499
  );
1255
1500
  currentContext = project?.contextSummary ?? void 0;
@@ -1292,7 +1537,7 @@ function registerUpdateContextTool(server, ctx) {
1292
1537
  };
1293
1538
  }
1294
1539
  await ctx.client.mutation(
1295
- anyApi3.functions.projects.updateProjectContext,
1540
+ anyApi4.functions.projects.updateProjectContext,
1296
1541
  {
1297
1542
  projectId: ctx.projectId,
1298
1543
  summary: args.summary
@@ -1362,7 +1607,7 @@ function registerQueueTool(server, ctx) {
1362
1607
  };
1363
1608
  }
1364
1609
  const data = await ctx.client.query(
1365
- anyApi3.functions.workQueue.getWorkQueue,
1610
+ anyApi4.functions.workQueue.getWorkQueue,
1366
1611
  { projectId: ctx.projectId }
1367
1612
  );
1368
1613
  if (!data) {
@@ -1471,7 +1716,7 @@ function registerGetBriefTool(server, ctx) {
1471
1716
  }
1472
1717
  try {
1473
1718
  const data = await ctx.client.query(
1474
- anyApi3.functions.findings.getFindingBrief,
1719
+ anyApi4.functions.findings.getFindingBrief,
1475
1720
  { findingId: itemId }
1476
1721
  );
1477
1722
  if (data) {
@@ -1485,7 +1730,7 @@ function registerGetBriefTool(server, ctx) {
1485
1730
  }
1486
1731
  try {
1487
1732
  const bundle = await ctx.client.query(
1488
- anyApi3.functions.bundles.getBundle,
1733
+ anyApi4.functions.bundles.getBundle,
1489
1734
  { bundleId: itemId }
1490
1735
  );
1491
1736
  if (bundle) {
@@ -1536,8 +1781,8 @@ function registerGetBriefTool(server, ctx) {
1536
1781
 
1537
1782
  // src/mcp/tools/claim.ts
1538
1783
  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";
1784
+ import { join as join8 } from "path";
1785
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, writeFileSync as writeFileSync8 } from "fs";
1541
1786
  function readBranchPrefix(cwd) {
1542
1787
  try {
1543
1788
  const config = readYapoutConfig(cwd);
@@ -1656,7 +1901,7 @@ function formatBundleBrief(bundle, projectContext) {
1656
1901
  async function detectWorkItemKind(client, workItemId) {
1657
1902
  try {
1658
1903
  const bundle = await client.query(
1659
- anyApi3.functions.bundles.getBundle,
1904
+ anyApi4.functions.bundles.getBundle,
1660
1905
  { bundleId: workItemId }
1661
1906
  );
1662
1907
  if (bundle) {
@@ -1710,7 +1955,7 @@ function registerClaimTool(server, ctx) {
1710
1955
  }
1711
1956
  async function claimStandalone(ctx, args, findingId) {
1712
1957
  const briefData = await ctx.client.query(
1713
- anyApi3.functions.findings.getFindingBrief,
1958
+ anyApi4.functions.findings.getFindingBrief,
1714
1959
  { findingId }
1715
1960
  );
1716
1961
  if (!briefData) {
@@ -1731,11 +1976,11 @@ async function claimStandalone(ctx, args, findingId) {
1731
1976
  const slug = slugify(finding.title);
1732
1977
  const branchName = linearIssueId ? `${prefix}/${linearIssueId.toLowerCase()}-${slug}` : `${prefix}/${slug}`;
1733
1978
  const localClaim = await ctx.client.mutation(
1734
- anyApi3.functions.findings.claimFindingLocal,
1979
+ anyApi4.functions.findings.claimFindingLocal,
1735
1980
  { findingId, branchName }
1736
1981
  );
1737
1982
  const claim = await ctx.client.mutation(
1738
- anyApi3.functions.workQueue.claimForImplementation,
1983
+ anyApi4.functions.workQueue.claimForImplementation,
1739
1984
  {
1740
1985
  projectId: ctx.projectId,
1741
1986
  workItemId: findingId,
@@ -1745,7 +1990,7 @@ async function claimStandalone(ctx, args, findingId) {
1745
1990
  if (linearIssueId && ctx.projectId) {
1746
1991
  try {
1747
1992
  await ctx.client.action(
1748
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
1993
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
1749
1994
  {
1750
1995
  projectId: ctx.projectId,
1751
1996
  linearIssueId,
@@ -1802,11 +2047,11 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1802
2047
  };
1803
2048
  }
1804
2049
  const localClaim = await ctx.client.mutation(
1805
- anyApi3.functions.findings.claimFindingLocal,
2050
+ anyApi4.functions.findings.claimFindingLocal,
1806
2051
  { findingId: primaryFinding._id, branchName }
1807
2052
  );
1808
2053
  const claim = await ctx.client.mutation(
1809
- anyApi3.functions.workQueue.claimForImplementation,
2054
+ anyApi4.functions.workQueue.claimForImplementation,
1810
2055
  {
1811
2056
  projectId: ctx.projectId,
1812
2057
  workItemId: bundleId,
@@ -1817,7 +2062,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1817
2062
  if (f.linearIssueId && ctx.projectId) {
1818
2063
  try {
1819
2064
  await ctx.client.action(
1820
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
2065
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
1821
2066
  {
1822
2067
  projectId: ctx.projectId,
1823
2068
  linearIssueId: f.linearIssueId,
@@ -1831,7 +2076,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1831
2076
  let projectContext;
1832
2077
  try {
1833
2078
  const briefData = await ctx.client.query(
1834
- anyApi3.functions.findings.getFindingBrief,
2079
+ anyApi4.functions.findings.getFindingBrief,
1835
2080
  { findingId: primaryFinding._id }
1836
2081
  );
1837
2082
  projectContext = briefData?.projectContext;
@@ -1871,7 +2116,7 @@ async function claimBundle(ctx, args, bundleId, bundleData) {
1871
2116
  async function getDefaultBranchForProject(ctx) {
1872
2117
  try {
1873
2118
  const data = await ctx.client.query(
1874
- anyApi3.functions.projects.getProject,
2119
+ anyApi4.functions.projects.getProject,
1875
2120
  { projectId: ctx.projectId }
1876
2121
  );
1877
2122
  return data?.githubDefaultBranch || "main";
@@ -1890,7 +2135,7 @@ async function setupWorktree(ctx, itemId, branchName, defaultBranch, brief, pipe
1890
2135
  writeBrief(worktreePath, brief);
1891
2136
  try {
1892
2137
  await ctx.client.mutation(
1893
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2138
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1894
2139
  {
1895
2140
  pipelineRunId,
1896
2141
  event: "worktree_created",
@@ -1919,14 +2164,14 @@ async function setupWorktree(ctx, itemId, branchName, defaultBranch, brief, pipe
1919
2164
  };
1920
2165
  }
1921
2166
  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);
2167
+ const yapoutDir = join8(dir, ".yapout");
2168
+ if (!existsSync7(yapoutDir)) mkdirSync6(yapoutDir, { recursive: true });
2169
+ writeFileSync8(join8(yapoutDir, "brief.md"), brief);
1925
2170
  }
1926
2171
  async function reportClaimEvents(ctx, pipelineRunId, title, branchName) {
1927
2172
  try {
1928
2173
  await ctx.client.mutation(
1929
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2174
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1930
2175
  {
1931
2176
  pipelineRunId,
1932
2177
  event: "daemon_claimed",
@@ -1934,7 +2179,7 @@ async function reportClaimEvents(ctx, pipelineRunId, title, branchName) {
1934
2179
  }
1935
2180
  );
1936
2181
  await ctx.client.mutation(
1937
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2182
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1938
2183
  {
1939
2184
  pipelineRunId,
1940
2185
  event: "branch_created",
@@ -1961,7 +2206,7 @@ function registerEventTool(server, ctx) {
1961
2206
  async (args) => {
1962
2207
  try {
1963
2208
  await ctx.client.mutation(
1964
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2209
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
1965
2210
  {
1966
2211
  pipelineRunId: args.pipelineRunId,
1967
2212
  event: args.event,
@@ -2053,8 +2298,8 @@ async function createPullRequest(title, body, branch, base, repoFullName, cwd) {
2053
2298
  }
2054
2299
 
2055
2300
  // src/mcp/tools/ship.ts
2056
- import { join as join8 } from "path";
2057
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
2301
+ import { join as join9 } from "path";
2302
+ import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
2058
2303
  function buildCommitMessage(message, template, finding, allLinearIds) {
2059
2304
  if (message) return message;
2060
2305
  if (template) {
@@ -2105,9 +2350,9 @@ function registerShipTool(server, ctx) {
2105
2350
  let isBundle = false;
2106
2351
  let bundleTitle;
2107
2352
  try {
2108
- const briefPath = join8(gitCwd, ".yapout", "brief.md");
2109
- if (existsSync7(briefPath)) {
2110
- const brief = readFileSync5(briefPath, "utf-8");
2353
+ const briefPath = join9(gitCwd, ".yapout", "brief.md");
2354
+ if (existsSync8(briefPath)) {
2355
+ const brief = readFileSync6(briefPath, "utf-8");
2111
2356
  const bundleMatch = brief.match(/^# Bundle: (.+)$/m);
2112
2357
  if (bundleMatch) {
2113
2358
  isBundle = true;
@@ -2218,7 +2463,7 @@ function registerShipTool(server, ctx) {
2218
2463
  }
2219
2464
  try {
2220
2465
  await ctx.client.mutation(
2221
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2466
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2222
2467
  {
2223
2468
  pipelineRunId: args.pipelineRunId,
2224
2469
  event: "push_completed",
@@ -2227,7 +2472,7 @@ function registerShipTool(server, ctx) {
2227
2472
  );
2228
2473
  if (prUrl) {
2229
2474
  await ctx.client.mutation(
2230
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2475
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2231
2476
  {
2232
2477
  pipelineRunId: args.pipelineRunId,
2233
2478
  event: "pr_opened",
@@ -2239,7 +2484,7 @@ function registerShipTool(server, ctx) {
2239
2484
  }
2240
2485
  try {
2241
2486
  await ctx.client.mutation(
2242
- anyApi3.functions.pipelineRuns.completePipelineLocal,
2487
+ anyApi4.functions.pipelineRuns.completePipelineLocal,
2243
2488
  {
2244
2489
  pipelineRunId: args.pipelineRunId,
2245
2490
  githubPrNumber: prNumber,
@@ -2255,7 +2500,7 @@ function registerShipTool(server, ctx) {
2255
2500
  if (ctx.projectId) {
2256
2501
  try {
2257
2502
  await ctx.client.action(
2258
- anyApi3.functions.linearStatusMutations.moveIssueStatus,
2503
+ anyApi4.functions.linearStatusMutations.moveIssueStatus,
2259
2504
  {
2260
2505
  projectId: ctx.projectId,
2261
2506
  linearIssueId: linearId,
@@ -2267,7 +2512,7 @@ function registerShipTool(server, ctx) {
2267
2512
  if (prUrl) {
2268
2513
  try {
2269
2514
  await ctx.client.action(
2270
- anyApi3.functions.linearStatusMutations.addLinearComment,
2515
+ anyApi4.functions.linearStatusMutations.addLinearComment,
2271
2516
  {
2272
2517
  projectId: ctx.projectId,
2273
2518
  linearIssueId: linearId,
@@ -2285,7 +2530,7 @@ function registerShipTool(server, ctx) {
2285
2530
  result.worktreeCleaned = true;
2286
2531
  try {
2287
2532
  await ctx.client.mutation(
2288
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2533
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2289
2534
  {
2290
2535
  pipelineRunId: args.pipelineRunId,
2291
2536
  event: "worktree_cleaned",
@@ -2376,7 +2621,7 @@ function registerCheckTool(server, ctx) {
2376
2621
  if (args.pipelineRunId) {
2377
2622
  try {
2378
2623
  await ctx.client.mutation(
2379
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2624
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2380
2625
  {
2381
2626
  pipelineRunId: args.pipelineRunId,
2382
2627
  event: "running_check",
@@ -2396,7 +2641,7 @@ function registerCheckTool(server, ctx) {
2396
2641
  if (args.pipelineRunId) {
2397
2642
  try {
2398
2643
  await ctx.client.mutation(
2399
- anyApi3.functions.pipelineRuns.reportDaemonEvent,
2644
+ anyApi4.functions.pipelineRuns.reportDaemonEvent,
2400
2645
  {
2401
2646
  pipelineRunId: args.pipelineRunId,
2402
2647
  event: passed ? "check_passed" : "check_failed",
@@ -2428,8 +2673,8 @@ function registerCheckTool(server, ctx) {
2428
2673
 
2429
2674
  // src/mcp/tools/bundle.ts
2430
2675
  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";
2676
+ import { join as join10 } from "path";
2677
+ import { existsSync as existsSync9, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7 } from "fs";
2433
2678
  function registerBundleTool(server, ctx) {
2434
2679
  server.tool(
2435
2680
  "yapout_bundle",
@@ -2440,11 +2685,11 @@ function registerBundleTool(server, ctx) {
2440
2685
  },
2441
2686
  async (args) => {
2442
2687
  const result = await ctx.client.mutation(
2443
- anyApi3.functions.bundles.createBundle,
2688
+ anyApi4.functions.bundles.createBundle,
2444
2689
  { leadFindingId: args.withFinding, joiningFindingId: args.findingId }
2445
2690
  );
2446
2691
  const bundledBrief = await ctx.client.query(
2447
- anyApi3.functions.bundles.getBundledBrief,
2692
+ anyApi4.functions.bundles.getBundledBrief,
2448
2693
  { bundleId: result.bundleId }
2449
2694
  );
2450
2695
  if (!bundledBrief) {
@@ -2482,9 +2727,9 @@ function registerBundleTool(server, ctx) {
2482
2727
  sections.push("## Project Context", "", bundledBrief.projectContext);
2483
2728
  }
2484
2729
  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);
2730
+ const yapoutDir = join10(ctx.cwd, ".yapout");
2731
+ if (!existsSync9(yapoutDir)) mkdirSync7(yapoutDir, { recursive: true });
2732
+ writeFileSync9(join10(yapoutDir, "brief.md"), combinedBrief);
2488
2733
  return {
2489
2734
  content: [
2490
2735
  {
@@ -2541,7 +2786,7 @@ After calling this tool, you should:
2541
2786
  }
2542
2787
  try {
2543
2788
  const result = await ctx.client.mutation(
2544
- anyApi3.functions.localPipeline.claimForEnrichment,
2789
+ anyApi4.functions.localPipeline.claimForEnrichment,
2545
2790
  {
2546
2791
  projectId,
2547
2792
  ...args.findingId ? { findingId: args.findingId } : {}
@@ -2601,7 +2846,7 @@ function registerGetExistingFindingsTool(server, ctx) {
2601
2846
  }
2602
2847
  try {
2603
2848
  const findings = await ctx.client.query(
2604
- anyApi3.functions.localPipeline.getExistingFindingTitles,
2849
+ anyApi4.functions.localPipeline.getExistingFindingTitles,
2605
2850
  { projectId }
2606
2851
  );
2607
2852
  if (!findings || findings.length === 0) {
@@ -2703,7 +2948,7 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2703
2948
  async (args) => {
2704
2949
  try {
2705
2950
  await ctx.client.mutation(
2706
- anyApi3.functions.localPipeline.saveLocalEnrichment,
2951
+ anyApi4.functions.localPipeline.saveLocalEnrichment,
2707
2952
  {
2708
2953
  findingId: args.findingId,
2709
2954
  title: args.title,
@@ -2718,11 +2963,11 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2718
2963
  }
2719
2964
  );
2720
2965
  await ctx.client.action(
2721
- anyApi3.functions.localPipeline.syncFindingToLinearLocal,
2966
+ anyApi4.functions.localPipeline.syncFindingToLinearLocal,
2722
2967
  { findingId: args.findingId }
2723
2968
  );
2724
2969
  const finding = await ctx.client.query(
2725
- anyApi3.functions.findings.getFinding,
2970
+ anyApi4.functions.findings.getFinding,
2726
2971
  { findingId: args.findingId }
2727
2972
  );
2728
2973
  if (args.sessionId) {
@@ -2781,7 +3026,7 @@ function registerSyncToLinearTool(server, ctx) {
2781
3026
  async (args) => {
2782
3027
  try {
2783
3028
  await ctx.client.action(
2784
- anyApi3.functions.localPipeline.syncFindingToLinearLocal,
3029
+ anyApi4.functions.localPipeline.syncFindingToLinearLocal,
2785
3030
  { findingId: args.findingId }
2786
3031
  );
2787
3032
  return {
@@ -2839,7 +3084,7 @@ function registerSubmitYapSessionTool(server, ctx) {
2839
3084
  }
2840
3085
  try {
2841
3086
  const captureId = await ctx.client.mutation(
2842
- anyApi3.functions.captures.createFromYapSession,
3087
+ anyApi4.functions.captures.createFromYapSession,
2843
3088
  {
2844
3089
  projectId: ctx.projectId,
2845
3090
  title: args.title,
@@ -3115,7 +3360,7 @@ function registerExtractFromYapTool(server, ctx) {
3115
3360
  }
3116
3361
  try {
3117
3362
  const result = await ctx.client.mutation(
3118
- anyApi3.functions.captures.extractFromYapSession,
3363
+ anyApi4.functions.captures.extractFromYapSession,
3119
3364
  {
3120
3365
  projectId: ctx.projectId,
3121
3366
  title: args.sessionTitle,
@@ -3227,7 +3472,7 @@ full spec \u2014 schema changes, files to modify, edge cases, and acceptance cri
3227
3472
  }
3228
3473
  try {
3229
3474
  const result = await ctx.client.mutation(
3230
- anyApi3.functions.localPipeline.decomposeIntoBundle,
3475
+ anyApi4.functions.localPipeline.decomposeIntoBundle,
3231
3476
  {
3232
3477
  findingId: args.findingId,
3233
3478
  bundleDescription: args.bundleDescription,
@@ -3300,7 +3545,7 @@ The finding must be in "enriching" or "enriched" status. It will be transitioned
3300
3545
  }
3301
3546
  try {
3302
3547
  const result = await ctx.client.mutation(
3303
- anyApi3.functions.findings.markDuplicate,
3548
+ anyApi4.functions.findings.markDuplicate,
3304
3549
  {
3305
3550
  findingId: args.findingId,
3306
3551
  duplicateOfLinearId: args.duplicateOfLinearId,
@@ -3363,7 +3608,7 @@ and issue counts so you can ask the user for confirmation before creating a new
3363
3608
  }
3364
3609
  try {
3365
3610
  const project = await ctx.client.query(
3366
- anyApi3.functions.projects.getProject,
3611
+ anyApi4.functions.projects.getProject,
3367
3612
  { projectId: ctx.projectId }
3368
3613
  );
3369
3614
  if (!project?.linearTeamId) {
@@ -3378,7 +3623,7 @@ and issue counts so you can ask the user for confirmation before creating a new
3378
3623
  };
3379
3624
  }
3380
3625
  const projects = await ctx.client.action(
3381
- anyApi3.functions.linearProjectsMutations.fetchProjectsDetailed,
3626
+ anyApi4.functions.linearProjectsMutations.fetchProjectsDetailed,
3382
3627
  { projectId: ctx.projectId, teamId: project.linearTeamId }
3383
3628
  );
3384
3629
  return {
@@ -3440,7 +3685,7 @@ Optionally filter by tags, capture, or explicit finding IDs.`,
3440
3685
  }
3441
3686
  try {
3442
3687
  const allFindings = await ctx.client.query(
3443
- anyApi3.functions.findings.getProjectFindings,
3688
+ anyApi4.functions.findings.getProjectFindings,
3444
3689
  { projectId }
3445
3690
  );
3446
3691
  let drafts = (allFindings ?? []).filter((f) => f.status === "draft");
@@ -3510,7 +3755,7 @@ When done=true, all findings have been processed.`,
3510
3755
  if (args.skip && args.skipFindingId) {
3511
3756
  try {
3512
3757
  await ctx.client.mutation(
3513
- anyApi3.functions.localPipeline.releaseEnrichmentClaim,
3758
+ anyApi4.functions.localPipeline.releaseEnrichmentClaim,
3514
3759
  { findingId: args.skipFindingId }
3515
3760
  );
3516
3761
  updateSessionStats(args.sessionId, {
@@ -3520,7 +3765,7 @@ When done=true, all findings have been processed.`,
3520
3765
  }
3521
3766
  }
3522
3767
  const allFindings = await ctx.client.query(
3523
- anyApi3.functions.findings.getProjectFindings,
3768
+ anyApi4.functions.findings.getProjectFindings,
3524
3769
  { projectId: session.projectId }
3525
3770
  );
3526
3771
  let drafts = (allFindings ?? []).filter(
@@ -3562,7 +3807,7 @@ When done=true, all findings have been processed.`,
3562
3807
  }
3563
3808
  const next = drafts[0];
3564
3809
  const claimResult = await ctx.client.mutation(
3565
- anyApi3.functions.localPipeline.claimForEnrichment,
3810
+ anyApi4.functions.localPipeline.claimForEnrichment,
3566
3811
  { projectId: session.projectId, findingId: next._id }
3567
3812
  );
3568
3813
  if (!claimResult) {
@@ -3643,7 +3888,7 @@ The bundle and all its findings transition to "enriching" status.`,
3643
3888
  async (args) => {
3644
3889
  try {
3645
3890
  const result = await ctx.client.mutation(
3646
- anyApi3.functions.bundles.claimBundleForEnrichment,
3891
+ anyApi4.functions.bundles.claimBundleForEnrichment,
3647
3892
  { bundleId: args.bundleId }
3648
3893
  );
3649
3894
  if (!result) {
@@ -3702,7 +3947,7 @@ Call yapout_sync_bundle_to_linear afterwards to create the Linear project.`,
3702
3947
  async (args) => {
3703
3948
  try {
3704
3949
  await ctx.client.mutation(
3705
- anyApi3.functions.bundles.saveBundleEnrichment,
3950
+ anyApi4.functions.bundles.saveBundleEnrichment,
3706
3951
  {
3707
3952
  bundleId: args.bundleId,
3708
3953
  title: args.title,
@@ -3761,7 +4006,7 @@ Transitions: enriching \u2192 needs_input. The user sees the blockerReason and q
3761
4006
  async (args) => {
3762
4007
  try {
3763
4008
  await ctx.client.mutation(
3764
- anyApi3.functions.localPipeline.blockLocalEnrichment,
4009
+ anyApi4.functions.localPipeline.blockLocalEnrichment,
3765
4010
  {
3766
4011
  findingId: args.findingId,
3767
4012
  blockerReason: args.blockerReason,
@@ -3810,7 +4055,7 @@ Same semantics as yapout_block_enrichment but for an entire bundle. Bundle statu
3810
4055
  async (args) => {
3811
4056
  try {
3812
4057
  await ctx.client.mutation(
3813
- anyApi3.functions.bundles.blockBundleEnrichment,
4058
+ anyApi4.functions.bundles.blockBundleEnrichment,
3814
4059
  {
3815
4060
  bundleId: args.bundleId,
3816
4061
  blockerReason: args.blockerReason,
@@ -3878,7 +4123,7 @@ async function startMcpServer() {
3878
4123
  };
3879
4124
  const server = new McpServer({
3880
4125
  name: "yapout",
3881
- version: "0.8.0"
4126
+ version: "0.9.0"
3882
4127
  });
3883
4128
  registerInitTool(server, ctx);
3884
4129
  registerCompactTool(server, ctx);
@@ -3910,40 +4155,40 @@ async function startMcpServer() {
3910
4155
  }
3911
4156
 
3912
4157
  // src/commands/mcp-server.ts
3913
- var mcpServerCommand = new Command7("mcp-server").description("Start the MCP server (used by Claude Code)").action(async () => {
4158
+ var mcpServerCommand = new Command8("mcp-server").description("Start the MCP server (used by Claude Code)").action(async () => {
3914
4159
  await startMcpServer();
3915
4160
  });
3916
4161
 
3917
4162
  // src/commands/worktrees.ts
3918
- import { Command as Command8 } from "commander";
3919
- import chalk8 from "chalk";
4163
+ import { Command as Command9 } from "commander";
4164
+ import chalk9 from "chalk";
3920
4165
  import { resolve as resolve6 } from "path";
3921
- var worktreesCommand = new Command8("worktrees").description("List active yapout worktrees").action(() => {
4166
+ var worktreesCommand = new Command9("worktrees").description("List active yapout worktrees").action(() => {
3922
4167
  const cwd = resolve6(process.cwd());
3923
4168
  const worktrees = listWorktrees(cwd);
3924
4169
  if (worktrees.length === 0) {
3925
- console.log(chalk8.dim("No active yapout worktrees."));
4170
+ console.log(chalk9.dim("No active yapout worktrees."));
3926
4171
  return;
3927
4172
  }
3928
- console.log(chalk8.bold("Active worktrees:\n"));
4173
+ console.log(chalk9.bold("Active worktrees:\n"));
3929
4174
  for (const wt of worktrees) {
3930
4175
  console.log(
3931
- ` ${chalk8.cyan(wt.path)} ${chalk8.green(wt.branch)}` + (wt.ticketId ? ` ${chalk8.dim(`(${wt.ticketId})`)}` : "")
4176
+ ` ${chalk9.cyan(wt.path)} ${chalk9.green(wt.branch)}` + (wt.ticketId ? ` ${chalk9.dim(`(${wt.ticketId})`)}` : "")
3932
4177
  );
3933
4178
  }
3934
4179
  console.log();
3935
4180
  });
3936
4181
 
3937
4182
  // src/commands/clean.ts
3938
- import { Command as Command9 } from "commander";
3939
- import chalk9 from "chalk";
4183
+ import { Command as Command10 } from "commander";
4184
+ import chalk10 from "chalk";
3940
4185
  import { resolve as resolve7 } from "path";
3941
- var cleanCommand = new Command9("clean").description("Remove worktrees for completed or failed tickets").action(async () => {
4186
+ var cleanCommand = new Command10("clean").description("Remove worktrees for completed or failed tickets").action(async () => {
3942
4187
  const creds = requireAuth();
3943
4188
  const cwd = resolve7(process.cwd());
3944
4189
  const worktrees = listWorktrees(cwd);
3945
4190
  if (worktrees.length === 0) {
3946
- console.log(chalk9.dim("No worktrees to clean."));
4191
+ console.log(chalk10.dim("No worktrees to clean."));
3947
4192
  return;
3948
4193
  }
3949
4194
  const client = createConvexClient(creds.token);
@@ -3959,7 +4204,7 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3959
4204
  if (isStale) {
3960
4205
  const label = ticket ? `${ticket.status}: ${ticket.title}` : "ticket not found";
3961
4206
  console.log(
3962
- chalk9.dim(`Removing worktree for ${wt.ticketId} (${label})...`)
4207
+ chalk10.dim(`Removing worktree for ${wt.ticketId} (${label})...`)
3963
4208
  );
3964
4209
  removeWorktree(cwd, wt.path);
3965
4210
  cleaned++;
@@ -3968,10 +4213,10 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3968
4213
  }
3969
4214
  }
3970
4215
  if (cleaned === 0) {
3971
- console.log(chalk9.dim("All worktrees are still active."));
4216
+ console.log(chalk10.dim("All worktrees are still active."));
3972
4217
  } else {
3973
4218
  console.log(
3974
- chalk9.green(
4219
+ chalk10.green(
3975
4220
  `Cleaned ${cleaned} worktree${cleaned === 1 ? "" : "s"}.`
3976
4221
  )
3977
4222
  );
@@ -3979,27 +4224,27 @@ var cleanCommand = new Command9("clean").description("Remove worktrees for compl
3979
4224
  });
3980
4225
 
3981
4226
  // src/commands/watch.ts
3982
- import { Command as Command10 } from "commander";
4227
+ import { Command as Command11 } from "commander";
3983
4228
  import { resolve as resolve8 } from "path";
3984
4229
  import {
3985
- readFileSync as readFileSync6,
3986
- writeFileSync as writeFileSync9,
3987
- existsSync as existsSync10,
3988
- unlinkSync as unlinkSync3
4230
+ readFileSync as readFileSync7,
4231
+ writeFileSync as writeFileSync10,
4232
+ existsSync as existsSync11,
4233
+ unlinkSync as unlinkSync4
3989
4234
  } from "fs";
3990
- import { join as join11 } from "path";
3991
- import chalk11 from "chalk";
4235
+ import { join as join12 } from "path";
4236
+ import chalk12 from "chalk";
3992
4237
  import { ConvexHttpClient as ConvexHttpClient3 } from "convex/browser";
3993
4238
 
3994
4239
  // src/daemon/watcher.ts
3995
- import { anyApi as anyApi5 } from "convex/server";
4240
+ import { anyApi as anyApi6 } from "convex/server";
3996
4241
  import { execSync as execSync4 } from "child_process";
3997
- import { existsSync as existsSync9, mkdirSync as mkdirSync8 } from "fs";
3998
- import { join as join10 } from "path";
4242
+ import { existsSync as existsSync10, mkdirSync as mkdirSync8 } from "fs";
4243
+ import { join as join11 } from "path";
3999
4244
  import { hostname as osHostname } from "os";
4000
4245
 
4001
4246
  // src/daemon/heartbeat.ts
4002
- import { anyApi as anyApi4 } from "convex/server";
4247
+ import { anyApi as anyApi5 } from "convex/server";
4003
4248
  var HEARTBEAT_INTERVAL = 3e4;
4004
4249
  var Heartbeat = class {
4005
4250
  client;
@@ -4027,14 +4272,14 @@ var Heartbeat = class {
4027
4272
  if (currentTicketId) args.currentTicketId = currentTicketId;
4028
4273
  if (currentBranch) args.currentBranch = currentBranch;
4029
4274
  if (worktreePath) args.worktreePath = worktreePath;
4030
- await this.client.mutation(anyApi4.functions.agents.agentHeartbeat, args);
4275
+ await this.client.mutation(anyApi5.functions.agents.agentHeartbeat, args);
4031
4276
  } catch {
4032
4277
  }
4033
4278
  }
4034
4279
  };
4035
4280
 
4036
4281
  // src/daemon/spawner.ts
4037
- import { spawn } from "child_process";
4282
+ import { spawn as spawn2 } from "child_process";
4038
4283
 
4039
4284
  // src/daemon/notifications.ts
4040
4285
  var notifier = null;
@@ -4123,7 +4368,7 @@ var Spawner = class {
4123
4368
  ...process.env,
4124
4369
  YAPOUT_PROJECT_ID: this.projectId
4125
4370
  };
4126
- const child = spawn("claude", ["--dangerously-skip-permissions", prompt], {
4371
+ const child = spawn2("claude", ["--dangerously-skip-permissions", prompt], {
4127
4372
  cwd: worktreePath,
4128
4373
  stdio: ["pipe", "pipe", "pipe"],
4129
4374
  env,
@@ -4235,7 +4480,7 @@ var Spawner = class {
4235
4480
  };
4236
4481
 
4237
4482
  // src/daemon/display.ts
4238
- import chalk10 from "chalk";
4483
+ import chalk11 from "chalk";
4239
4484
  function formatElapsed(ms) {
4240
4485
  const seconds = Math.floor(ms / 1e3);
4241
4486
  if (seconds < 60) return `${seconds}s`;
@@ -4264,35 +4509,35 @@ function render(state) {
4264
4509
  if (queuedCount > 0) statusParts.push(`${queuedCount} queued`);
4265
4510
  const statusLine = statusParts.length > 0 ? statusParts.join(" | ") : "idle";
4266
4511
  lines.push(
4267
- `${chalk10.bold("yapout watch")} \u2014 ${state.projectName}`
4512
+ `${chalk11.bold("yapout watch")} \u2014 ${state.projectName}`
4268
4513
  );
4269
- lines.push(`${chalk10.green("Watching")} | ${statusLine}`);
4514
+ lines.push(`${chalk11.green("Watching")} | ${statusLine}`);
4270
4515
  lines.push("");
4271
4516
  for (const agent of state.activeAgents) {
4272
4517
  const elapsed = formatElapsed(now - agent.startedAt);
4273
- const wt = agent.worktree ? chalk10.dim(`worktree/${agent.ticketRef.toLowerCase()}`) : "";
4518
+ const wt = agent.worktree ? chalk11.dim(`worktree/${agent.ticketRef.toLowerCase()}`) : "";
4274
4519
  lines.push(
4275
- ` ${chalk10.green("\u25CF")} ${chalk10.bold(agent.ticketRef)} ${chalk10.dim(truncate2(`"${agent.title}"`, 35))} ${chalk10.yellow(agent.phase)} ${wt} ${chalk10.dim(elapsed)}`
4520
+ ` ${chalk11.green("\u25CF")} ${chalk11.bold(agent.ticketRef)} ${chalk11.dim(truncate2(`"${agent.title}"`, 35))} ${chalk11.yellow(agent.phase)} ${wt} ${chalk11.dim(elapsed)}`
4276
4521
  );
4277
4522
  }
4278
4523
  for (const ticket of state.queuedTickets) {
4279
4524
  lines.push(
4280
- ` ${chalk10.dim("\u25CB")} ${chalk10.bold(ticket.ticketRef)} ${chalk10.dim(truncate2(`"${ticket.title}"`, 35))} ${chalk10.dim("queued")}`
4525
+ ` ${chalk11.dim("\u25CB")} ${chalk11.bold(ticket.ticketRef)} ${chalk11.dim(truncate2(`"${ticket.title}"`, 35))} ${chalk11.dim("queued")}`
4281
4526
  );
4282
4527
  }
4283
4528
  if (state.activeAgents.length > 0 || state.queuedTickets.length > 0) {
4284
4529
  lines.push("");
4285
4530
  }
4286
4531
  if (state.recentEvents.length > 0) {
4287
- lines.push(chalk10.dim("Recent:"));
4532
+ lines.push(chalk11.dim("Recent:"));
4288
4533
  for (const event of state.recentEvents.slice(0, 8)) {
4289
4534
  lines.push(
4290
- ` ${chalk10.dim(formatTime(event.time))} ${event.icon} ${event.message}`
4535
+ ` ${chalk11.dim(formatTime(event.time))} ${event.icon} ${event.message}`
4291
4536
  );
4292
4537
  }
4293
4538
  lines.push("");
4294
4539
  }
4295
- lines.push(chalk10.dim("Ctrl+C to stop (agents will finish)"));
4540
+ lines.push(chalk11.dim("Ctrl+C to stop (agents will finish)"));
4296
4541
  return lines.join("\n");
4297
4542
  }
4298
4543
  function clearAndRender(state) {
@@ -4334,7 +4579,7 @@ var Watcher = class {
4334
4579
  );
4335
4580
  process.exit(1);
4336
4581
  }
4337
- await this.client.mutation(anyApi5.functions.agents.registerAgent, {
4582
+ await this.client.mutation(anyApi6.functions.agents.registerAgent, {
4338
4583
  projectId: this.options.projectId,
4339
4584
  sessionId: this.sessionId,
4340
4585
  machineHostname: this.getHostname()
@@ -4370,7 +4615,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4370
4615
  await this.spawner.gracefulShutdown();
4371
4616
  }
4372
4617
  try {
4373
- await this.client.mutation(anyApi5.functions.agents.unregisterAgent, {
4618
+ await this.client.mutation(anyApi6.functions.agents.unregisterAgent, {
4374
4619
  sessionId: this.sessionId
4375
4620
  });
4376
4621
  } catch {
@@ -4384,7 +4629,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4384
4629
  }
4385
4630
  this.heartbeat.stop();
4386
4631
  this.spawner.forceKill();
4387
- this.client.mutation(anyApi5.functions.agents.unregisterAgent, {
4632
+ this.client.mutation(anyApi6.functions.agents.unregisterAgent, {
4388
4633
  sessionId: this.sessionId
4389
4634
  }).catch(() => {
4390
4635
  });
@@ -4426,7 +4671,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4426
4671
  }
4427
4672
  async checkForEnrichmentWork(maxSlots) {
4428
4673
  const tickets = await this.client.query(
4429
- anyApi5.functions.localPipeline.getUnenrichedTickets,
4674
+ anyApi6.functions.localPipeline.getUnenrichedTickets,
4430
4675
  { projectId: this.options.projectId }
4431
4676
  );
4432
4677
  if (!tickets || tickets.length === 0) return;
@@ -4455,7 +4700,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4455
4700
  }
4456
4701
  async checkForImplementationWork(maxSlots) {
4457
4702
  const data = await this.client.query(
4458
- anyApi5.functions.tickets.getLocalQueuedTickets,
4703
+ anyApi6.functions.tickets.getLocalQueuedTickets,
4459
4704
  { projectId: this.options.projectId }
4460
4705
  );
4461
4706
  if (!data || data.ready.length === 0) return;
@@ -4487,10 +4732,10 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4487
4732
  }
4488
4733
  ensureEnrichWorktree() {
4489
4734
  const wtDir = getWorktreesDir(this.options.cwd);
4490
- const enrichPath = join10(wtDir, "_enrich");
4491
- if (existsSync9(enrichPath)) return enrichPath;
4735
+ const enrichPath = join11(wtDir, "_enrich");
4736
+ if (existsSync10(enrichPath)) return enrichPath;
4492
4737
  try {
4493
- if (!existsSync9(wtDir)) mkdirSync8(wtDir, { recursive: true });
4738
+ if (!existsSync10(wtDir)) mkdirSync8(wtDir, { recursive: true });
4494
4739
  const defaultBranch = getDefaultBranch(this.options.cwd);
4495
4740
  execSync4(
4496
4741
  `git worktree add "${enrichPath}" origin/${defaultBranch}`,
@@ -4528,7 +4773,7 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4528
4773
  if (wt.ticketId) {
4529
4774
  try {
4530
4775
  const ticket = await this.client.query(
4531
- anyApi5.functions.tickets.getTicket,
4776
+ anyApi6.functions.tickets.getTicket,
4532
4777
  { ticketId: wt.ticketId }
4533
4778
  );
4534
4779
  if (ticket && (ticket.status === "failed" || ticket.status === "workflow2_done")) {
@@ -4593,38 +4838,38 @@ Waiting for ${this.spawner.activeCount} agent(s) to finish...`
4593
4838
  };
4594
4839
 
4595
4840
  // 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) => {
4841
+ var PID_FILE2 = join12(getYapoutDir(), "watch.pid");
4842
+ var LOG_FILE2 = join12(getYapoutDir(), "watch.log");
4843
+ 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
4844
  if (opts.status) {
4600
- if (existsSync10(PID_FILE)) {
4601
- const pid = parseInt(readFileSync6(PID_FILE, "utf-8").trim(), 10);
4602
- if (isProcessRunning(pid)) {
4845
+ if (existsSync11(PID_FILE2)) {
4846
+ const pid = parseInt(readFileSync7(PID_FILE2, "utf-8").trim(), 10);
4847
+ if (isProcessRunning2(pid)) {
4603
4848
  console.log(
4604
- chalk11.green("Watcher is running") + chalk11.dim(` (PID ${pid})`)
4849
+ chalk12.green("Watcher is running") + chalk12.dim(` (PID ${pid})`)
4605
4850
  );
4606
4851
  } else {
4607
- console.log(chalk11.dim("Watcher is not running (stale PID file)"));
4608
- unlinkSync3(PID_FILE);
4852
+ console.log(chalk12.dim("Watcher is not running (stale PID file)"));
4853
+ unlinkSync4(PID_FILE2);
4609
4854
  }
4610
4855
  } else {
4611
- console.log(chalk11.dim("Watcher is not running"));
4856
+ console.log(chalk12.dim("Watcher is not running"));
4612
4857
  }
4613
4858
  return;
4614
4859
  }
4615
4860
  if (opts.stop) {
4616
- if (!existsSync10(PID_FILE)) {
4617
- console.log(chalk11.dim("No watcher running"));
4861
+ if (!existsSync11(PID_FILE2)) {
4862
+ console.log(chalk12.dim("No watcher running"));
4618
4863
  return;
4619
4864
  }
4620
- const pid = parseInt(readFileSync6(PID_FILE, "utf-8").trim(), 10);
4865
+ const pid = parseInt(readFileSync7(PID_FILE2, "utf-8").trim(), 10);
4621
4866
  try {
4622
4867
  process.kill(pid, "SIGTERM");
4623
- console.log(chalk11.green(`Stopped watcher (PID ${pid})`));
4868
+ console.log(chalk12.green(`Stopped watcher (PID ${pid})`));
4624
4869
  } catch {
4625
- console.log(chalk11.dim("Watcher already stopped"));
4870
+ console.log(chalk12.dim("Watcher already stopped"));
4626
4871
  }
4627
- unlinkSync3(PID_FILE);
4872
+ unlinkSync4(PID_FILE2);
4628
4873
  return;
4629
4874
  }
4630
4875
  const creds = requireAuth();
@@ -4632,7 +4877,7 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4632
4877
  const mapping = getProjectMapping(cwd);
4633
4878
  if (!mapping) {
4634
4879
  console.error(
4635
- chalk11.red("No project linked.") + " Run " + chalk11.cyan("yapout link") + " in a repo."
4880
+ chalk12.red("No project linked.") + " Run " + chalk12.cyan("yapout link") + " in a repo."
4636
4881
  );
4637
4882
  process.exit(1);
4638
4883
  }
@@ -4640,16 +4885,16 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4640
4885
  const client = new ConvexHttpClient3(getConvexUrl());
4641
4886
  client.setAuth(creds.token);
4642
4887
  if (opts.bg) {
4643
- writeFileSync9(PID_FILE, process.pid.toString());
4888
+ writeFileSync10(PID_FILE2, process.pid.toString());
4644
4889
  console.log(
4645
- chalk11.green("Watcher started in background") + chalk11.dim(` (PID ${process.pid}, log: ${LOG_FILE})`)
4890
+ chalk12.green("Watcher started in background") + chalk12.dim(` (PID ${process.pid}, log: ${LOG_FILE2})`)
4646
4891
  );
4647
4892
  }
4648
- console.log(chalk11.bold(`yapout watch v${"0.8.0"}`));
4893
+ console.log(chalk12.bold(`yapout watch v${"0.9.0"}`));
4649
4894
  console.log(
4650
- `Project: ${chalk11.green(mapping.projectName)} (${mapping.projectId})`
4895
+ `Project: ${chalk12.green(mapping.projectName)} (${mapping.projectId})`
4651
4896
  );
4652
- console.log(chalk11.dim("Watching..."));
4897
+ console.log(chalk12.dim("Watching..."));
4653
4898
  console.log();
4654
4899
  const watcher = new Watcher(
4655
4900
  {
@@ -4666,17 +4911,17 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4666
4911
  const shutdown = async () => {
4667
4912
  if (shuttingDown) {
4668
4913
  watcher.forceStop();
4669
- if (existsSync10(PID_FILE)) unlinkSync3(PID_FILE);
4914
+ if (existsSync11(PID_FILE2)) unlinkSync4(PID_FILE2);
4670
4915
  process.exit(0);
4671
4916
  }
4672
4917
  shuttingDown = true;
4673
- console.log(chalk11.dim("\nShutting down..."));
4918
+ console.log(chalk12.dim("\nShutting down..."));
4674
4919
  if (opts.force) {
4675
4920
  watcher.forceStop();
4676
4921
  } else {
4677
4922
  await watcher.stop();
4678
4923
  }
4679
- if (existsSync10(PID_FILE)) unlinkSync3(PID_FILE);
4924
+ if (existsSync11(PID_FILE2)) unlinkSync4(PID_FILE2);
4680
4925
  process.exit(0);
4681
4926
  };
4682
4927
  process.on("SIGINT", () => {
@@ -4689,7 +4934,7 @@ var watchCommand = new Command10("watch").description("Watch for work and spawn
4689
4934
  await new Promise(() => {
4690
4935
  });
4691
4936
  });
4692
- function isProcessRunning(pid) {
4937
+ function isProcessRunning2(pid) {
4693
4938
  try {
4694
4939
  process.kill(pid, 0);
4695
4940
  return true;
@@ -4699,88 +4944,88 @@ function isProcessRunning(pid) {
4699
4944
  }
4700
4945
 
4701
4946
  // src/commands/queue.ts
4702
- import { Command as Command11 } from "commander";
4947
+ import { Command as Command12 } from "commander";
4703
4948
  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 () => {
4949
+ import chalk13 from "chalk";
4950
+ var queueCommand = new Command12("queue").description("Show pipeline state \u2014 what's ready, blocked, and pending").action(async () => {
4706
4951
  const creds = requireAuth();
4707
4952
  const cwd = resolve9(process.cwd());
4708
4953
  const mapping = getProjectMapping(cwd);
4709
4954
  if (!mapping) {
4710
4955
  console.error(
4711
- chalk12.red("No project linked.") + " Run " + chalk12.cyan("yapout link") + " in a repo."
4956
+ chalk13.red("No project linked.") + " Run " + chalk13.cyan("yapout link") + " in a repo."
4712
4957
  );
4713
4958
  process.exit(1);
4714
4959
  }
4715
4960
  const client = createConvexClient(creds.token);
4716
- const { anyApi: anyApi6 } = await import("convex/server");
4961
+ const { anyApi: anyApi7 } = await import("convex/server");
4717
4962
  const [queueData, unenriched, pending] = await Promise.all([
4718
- client.query(anyApi6.functions.tickets.getLocalQueuedTickets, {
4963
+ client.query(anyApi7.functions.tickets.getLocalQueuedTickets, {
4719
4964
  projectId: mapping.projectId
4720
4965
  }),
4721
- client.query(anyApi6.functions.localPipeline.getUnenrichedTickets, {
4966
+ client.query(anyApi7.functions.localPipeline.getUnenrichedTickets, {
4722
4967
  projectId: mapping.projectId
4723
4968
  }),
4724
- client.query(anyApi6.functions.localPipeline.getPendingSources, {
4969
+ client.query(anyApi7.functions.localPipeline.getPendingSources, {
4725
4970
  projectId: mapping.projectId
4726
4971
  })
4727
4972
  ]);
4728
4973
  console.log();
4729
4974
  if (queueData?.ready && queueData.ready.length > 0) {
4730
- console.log(chalk12.bold("Ready to implement:"));
4975
+ console.log(chalk13.bold("Ready to implement:"));
4731
4976
  for (const t of queueData.ready) {
4732
4977
  const ref = t.linearTicketId ?? t.ticketId;
4733
4978
  const prio = colorPriority(t.priority);
4734
4979
  console.log(
4735
- ` ${chalk12.bold(ref)} ${t.title.slice(0, 45).padEnd(45)} ${prio} ${chalk12.dim(t.type)}`
4980
+ ` ${chalk13.bold(ref)} ${t.title.slice(0, 45).padEnd(45)} ${prio} ${chalk13.dim(t.type)}`
4736
4981
  );
4737
4982
  }
4738
4983
  console.log();
4739
4984
  }
4740
4985
  if (queueData?.blocked && queueData.blocked.length > 0) {
4741
- console.log(chalk12.bold("Blocked:"));
4986
+ console.log(chalk13.bold("Blocked:"));
4742
4987
  for (const t of queueData.blocked) {
4743
4988
  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(", "))}`
4989
+ ` ${chalk13.bold(t.ticketId.slice(-6))} ${t.title.slice(0, 45)} ${chalk13.red("blocked by " + t.blockedBy.map((id) => id.slice(-6)).join(", "))}`
4745
4990
  );
4746
4991
  }
4747
4992
  console.log();
4748
4993
  }
4749
4994
  if (unenriched && unenriched.length > 0) {
4750
- console.log(chalk12.bold("Needs enrichment:"));
4995
+ console.log(chalk13.bold("Needs enrichment:"));
4751
4996
  for (const t of unenriched) {
4752
4997
  const ref = t.ticketId;
4753
4998
  console.log(
4754
- ` ${chalk12.bold(ref.slice(-6))} ${t.title.slice(0, 45).padEnd(45)} ${chalk12.dim(t.priority)}`
4999
+ ` ${chalk13.bold(ref.slice(-6))} ${t.title.slice(0, 45).padEnd(45)} ${chalk13.dim(t.priority)}`
4755
5000
  );
4756
5001
  }
4757
5002
  console.log();
4758
5003
  }
4759
5004
  if (pending && pending.length > 0) {
4760
- console.log(chalk12.bold("Pending extraction:"));
5005
+ console.log(chalk13.bold("Pending extraction:"));
4761
5006
  for (const t of pending) {
4762
5007
  const ago = formatAgo(Date.now() - t.createdAt);
4763
5008
  console.log(
4764
- ` "${t.meetingTitle ?? "Untitled"}" ${chalk12.dim(`(uploaded ${ago})`)}`
5009
+ ` "${t.meetingTitle ?? "Untitled"}" ${chalk13.dim(`(uploaded ${ago})`)}`
4765
5010
  );
4766
5011
  }
4767
5012
  console.log();
4768
5013
  }
4769
5014
  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."));
5015
+ console.log(chalk13.dim("Queue is empty. Upload a transcript to get started."));
4771
5016
  console.log();
4772
5017
  }
4773
5018
  });
4774
5019
  function colorPriority(p) {
4775
5020
  switch (p) {
4776
5021
  case "urgent":
4777
- return chalk12.red(p);
5022
+ return chalk13.red(p);
4778
5023
  case "high":
4779
- return chalk12.yellow(p);
5024
+ return chalk13.yellow(p);
4780
5025
  case "medium":
4781
- return chalk12.white(p);
5026
+ return chalk13.white(p);
4782
5027
  case "low":
4783
- return chalk12.dim(p);
5028
+ return chalk13.dim(p);
4784
5029
  default:
4785
5030
  return p;
4786
5031
  }
@@ -4796,29 +5041,29 @@ function formatAgo(ms) {
4796
5041
  }
4797
5042
 
4798
5043
  // src/commands/next.ts
4799
- import { Command as Command12 } from "commander";
5044
+ import { Command as Command13 } from "commander";
4800
5045
  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) => {
5046
+ import { writeFileSync as writeFileSync11 } from "fs";
5047
+ import { join as join13 } from "path";
5048
+ import chalk14 from "chalk";
5049
+ 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
5050
  const creds = requireAuth();
4806
5051
  const cwd = resolve10(process.cwd());
4807
5052
  const mapping = getProjectMapping(cwd);
4808
5053
  if (!mapping) {
4809
5054
  console.error(
4810
- chalk13.red("No project linked.") + " Run " + chalk13.cyan("yapout link") + " in a repo."
5055
+ chalk14.red("No project linked.") + " Run " + chalk14.cyan("yapout link") + " in a repo."
4811
5056
  );
4812
5057
  process.exit(1);
4813
5058
  }
4814
5059
  const client = createConvexClient(creds.token);
4815
- const { anyApi: anyApi6 } = await import("convex/server");
5060
+ const { anyApi: anyApi7 } = await import("convex/server");
4816
5061
  const data = await client.query(
4817
- anyApi6.functions.tickets.getLocalQueuedTickets,
5062
+ anyApi7.functions.tickets.getLocalQueuedTickets,
4818
5063
  { projectId: mapping.projectId }
4819
5064
  );
4820
5065
  if (!data?.ready || data.ready.length === 0) {
4821
- console.log(chalk13.dim("No tickets ready for implementation."));
5066
+ console.log(chalk14.dim("No tickets ready for implementation."));
4822
5067
  return;
4823
5068
  }
4824
5069
  const ticket = data.ready[0];
@@ -4826,32 +5071,32 @@ var nextCommand = new Command12("next").description("Claim the highest priority
4826
5071
  const config = readYapoutConfig(cwd);
4827
5072
  const defaultBranch = getDefaultBranch(cwd);
4828
5073
  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(`
5074
+ console.log(chalk14.bold(`
4830
5075
  Claimed: ${ref} "${ticket.title}"`));
4831
5076
  fetchOrigin(cwd);
4832
5077
  let workDir = cwd;
4833
5078
  if (opts.worktree) {
4834
5079
  const { createWorktree: createWorktree2 } = await import("./worktree-ZZZIL7TK.js");
4835
5080
  workDir = createWorktree2(cwd, ticket.ticketId, branchName, defaultBranch);
4836
- console.log(`Worktree: ${chalk13.cyan(workDir)}`);
5081
+ console.log(`Worktree: ${chalk14.cyan(workDir)}`);
4837
5082
  } else {
4838
5083
  checkoutNewBranch(branchName, defaultBranch, cwd);
4839
5084
  }
4840
- console.log(`Branch: ${chalk13.cyan(branchName)}`);
5085
+ console.log(`Branch: ${chalk14.cyan(branchName)}`);
4841
5086
  const brief = await client.query(
4842
- anyApi6.functions.tickets.getTicketBrief,
5087
+ anyApi7.functions.tickets.getTicketBrief,
4843
5088
  { ticketId: ticket.ticketId }
4844
5089
  );
4845
5090
  if (brief) {
4846
- const briefPath = join12(workDir, ".yapout", "brief.md");
5091
+ const briefPath = join13(workDir, ".yapout", "brief.md");
4847
5092
  const briefContent = formatBrief(ref, ticket, brief);
4848
- writeFileSync10(briefPath, briefContent);
4849
- console.log(`Brief: ${chalk13.cyan(briefPath)}`);
5093
+ writeFileSync11(briefPath, briefContent);
5094
+ console.log(`Brief: ${chalk14.cyan(briefPath)}`);
4850
5095
  }
4851
5096
  console.log();
4852
5097
  console.log("Start Claude Code to implement, or run:");
4853
5098
  console.log(
4854
- chalk13.cyan(
5099
+ chalk14.cyan(
4855
5100
  ` claude --dangerously-skip-permissions "Read .yapout/brief.md, implement it, run yapout_check, then yapout_ship"`
4856
5101
  )
4857
5102
  );
@@ -4901,21 +5146,21 @@ function formatBrief(ref, ticket, brief) {
4901
5146
  }
4902
5147
 
4903
5148
  // src/commands/recap.ts
4904
- import { Command as Command13 } from "commander";
5149
+ import { Command as Command14 } from "commander";
4905
5150
  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) => {
5151
+ import chalk15 from "chalk";
5152
+ 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
5153
  const creds = requireAuth();
4909
5154
  const cwd = resolve11(process.cwd());
4910
5155
  const mapping = getProjectMapping(cwd);
4911
5156
  if (!mapping) {
4912
5157
  console.error(
4913
- chalk14.red("No project linked.") + " Run " + chalk14.cyan("yapout link") + " in a repo."
5158
+ chalk15.red("No project linked.") + " Run " + chalk15.cyan("yapout link") + " in a repo."
4914
5159
  );
4915
5160
  process.exit(1);
4916
5161
  }
4917
5162
  const client = createConvexClient(creds.token);
4918
- const { anyApi: anyApi6 } = await import("convex/server");
5163
+ const { anyApi: anyApi7 } = await import("convex/server");
4919
5164
  const now = /* @__PURE__ */ new Date();
4920
5165
  const todayStart = new Date(
4921
5166
  now.getFullYear(),
@@ -4925,33 +5170,33 @@ var recapCommand = new Command13("recap").description("Show a summary of recent
4925
5170
  const weekStart = todayStart - 6 * 24 * 60 * 60 * 1e3;
4926
5171
  const since = opts.week ? weekStart : todayStart;
4927
5172
  const data = await client.query(
4928
- anyApi6.functions.localPipeline.getRecentActivity,
5173
+ anyApi7.functions.localPipeline.getRecentActivity,
4929
5174
  { projectId: mapping.projectId, since }
4930
5175
  );
4931
5176
  if (!data) {
4932
- console.log(chalk14.dim("Could not fetch activity data."));
5177
+ console.log(chalk15.dim("Could not fetch activity data."));
4933
5178
  return;
4934
5179
  }
4935
5180
  const period = opts.week ? "This week" : "Today";
4936
5181
  console.log();
4937
- console.log(chalk14.bold(`${period}:`));
5182
+ console.log(chalk15.bold(`${period}:`));
4938
5183
  if (data.recentTickets.length > 0) {
4939
5184
  for (const t of data.recentTickets) {
4940
5185
  const ref = t.linearTicketId ?? "ticket";
4941
- console.log(` ${chalk14.green("\u2713")} ${ref} ${t.title}`);
5186
+ console.log(` ${chalk15.green("\u2713")} ${ref} ${t.title}`);
4942
5187
  }
4943
5188
  }
4944
5189
  if (data.recentPRs.length > 0) {
4945
5190
  for (const p of data.recentPRs) {
4946
5191
  const prRef = p.githubPrNumber ? `PR #${p.githubPrNumber}` : "PR";
4947
- const statusColor = p.status === "opened" ? chalk14.green : p.status === "draft" ? chalk14.dim : chalk14.yellow;
5192
+ const statusColor = p.status === "opened" ? chalk15.green : p.status === "draft" ? chalk15.dim : chalk15.yellow;
4948
5193
  console.log(
4949
5194
  ` ${statusColor("\u2191")} ${p.prTitle.slice(0, 45)} ${statusColor(prRef)} ${statusColor(p.status)}`
4950
5195
  );
4951
5196
  }
4952
5197
  }
4953
5198
  if (data.recentTickets.length === 0 && data.recentPRs.length === 0) {
4954
- console.log(chalk14.dim(" No activity yet."));
5199
+ console.log(chalk15.dim(" No activity yet."));
4955
5200
  }
4956
5201
  console.log();
4957
5202
  console.log(
@@ -4961,12 +5206,12 @@ var recapCommand = new Command13("recap").description("Show a summary of recent
4961
5206
  });
4962
5207
 
4963
5208
  // src/commands/yap.ts
4964
- import { Command as Command14 } from "commander";
4965
- import chalk15 from "chalk";
4966
- var yapCommand = new Command14("yap").description(
5209
+ import { Command as Command15 } from "commander";
5210
+ import chalk16 from "chalk";
5211
+ var yapCommand = new Command15("yap").description(
4967
5212
  "Start a yap session \u2014 brainstorm with an AI that knows your codebase"
4968
5213
  ).action(() => {
4969
- console.log(chalk15.bold("yapout yap sessions"));
5214
+ console.log(chalk16.bold("yapout yap sessions"));
4970
5215
  console.log();
4971
5216
  console.log(
4972
5217
  "Yap sessions run inside Claude \u2014 Desktop, CLI, or web \u2014 anywhere the"
@@ -4975,27 +5220,27 @@ var yapCommand = new Command14("yap").description(
4975
5220
  console.log();
4976
5221
  console.log("Just tell Claude:");
4977
5222
  console.log(
4978
- chalk15.green(` "Let's have a yap session about [topic]"`)
5223
+ chalk16.green(` "Let's have a yap session about [topic]"`)
4979
5224
  );
4980
5225
  console.log(
4981
- chalk15.green(
5226
+ chalk16.green(
4982
5227
  ' "I want to brainstorm [idea] \u2014 be a skeptical QA engineer"'
4983
5228
  )
4984
5229
  );
4985
5230
  console.log();
4986
- console.log(chalk15.dim("Personas: tech lead, qa engineer, product owner, end user, or custom"));
5231
+ console.log(chalk16.dim("Personas: tech lead, qa engineer, product owner, end user, or custom"));
4987
5232
  console.log(
4988
- chalk15.dim(
5233
+ chalk16.dim(
4989
5234
  "Claude will call yapout_start_yap to get instructions and yapout_submit_yap_session when done."
4990
5235
  )
4991
5236
  );
4992
5237
  });
4993
5238
 
4994
5239
  // 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";
5240
+ import { Command as Command16 } from "commander";
5241
+ import { spawn as spawn3 } from "child_process";
5242
+ import { platform as platform3 } from "os";
5243
+ import chalk17 from "chalk";
4999
5244
  var VALID_ACTIONS = ["claim", "enrich", "enrich-bulk", "enrich-bundle", "yap", "compact"];
5000
5245
  function parseYapoutUri(raw) {
5001
5246
  const url = new URL(raw);
@@ -5108,11 +5353,11 @@ function findProjectDir() {
5108
5353
  return dirs[0];
5109
5354
  }
5110
5355
  function launchTerminal(cwd, claudeArgs) {
5111
- const os = platform2();
5356
+ const os = platform3();
5112
5357
  const claudeCmd = `claude ${claudeArgs.map(shellEscape).join(" ")}`;
5113
5358
  if (os === "win32") {
5114
5359
  const wtArgs = ["wt", "-d", cwd, "cmd", "/k", claudeCmd];
5115
- const child = spawn2("cmd", ["/c", "start", ...wtArgs], {
5360
+ const child = spawn3("cmd", ["/c", "start", ...wtArgs], {
5116
5361
  cwd,
5117
5362
  stdio: "ignore",
5118
5363
  detached: true,
@@ -5120,7 +5365,7 @@ function launchTerminal(cwd, claudeArgs) {
5120
5365
  });
5121
5366
  child.unref();
5122
5367
  child.on("error", () => {
5123
- const fallback = spawn2(
5368
+ const fallback = spawn3(
5124
5369
  "cmd",
5125
5370
  ["/c", "start", "cmd", "/k", claudeCmd],
5126
5371
  { cwd, stdio: "ignore", detached: true, shell: true }
@@ -5133,7 +5378,7 @@ function launchTerminal(cwd, claudeArgs) {
5133
5378
  activate
5134
5379
  do script "cd ${shellEscape(cwd)} && ${escaped}"
5135
5380
  end tell`;
5136
- const child = spawn2("osascript", ["-e", script], {
5381
+ const child = spawn3("osascript", ["-e", script], {
5137
5382
  stdio: "ignore",
5138
5383
  detached: true
5139
5384
  });
@@ -5148,7 +5393,7 @@ end tell`;
5148
5393
  let launched = false;
5149
5394
  for (const term of terminals) {
5150
5395
  try {
5151
- const child = spawn2(term.cmd, term.args, {
5396
+ const child = spawn3(term.cmd, term.args, {
5152
5397
  stdio: "ignore",
5153
5398
  detached: true
5154
5399
  });
@@ -5161,44 +5406,44 @@ end tell`;
5161
5406
  }
5162
5407
  if (!launched) {
5163
5408
  console.error(
5164
- chalk16.red("Could not find a terminal emulator. Install gnome-terminal, konsole, or xterm.")
5409
+ chalk17.red("Could not find a terminal emulator. Install gnome-terminal, konsole, or xterm.")
5165
5410
  );
5166
5411
  process.exit(1);
5167
5412
  }
5168
5413
  }
5169
5414
  }
5170
5415
  function shellEscape(s) {
5171
- if (platform2() === "win32") {
5416
+ if (platform3() === "win32") {
5172
5417
  return `"${s.replace(/"/g, '""')}"`;
5173
5418
  }
5174
5419
  return `'${s.replace(/'/g, "'\\''")}'`;
5175
5420
  }
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) => {
5421
+ 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
5422
  try {
5178
5423
  const parsed = parseYapoutUri(uri);
5179
5424
  const prompt = buildPrompt(parsed);
5180
5425
  const cwd = findProjectDir();
5181
5426
  if (!cwd) {
5182
5427
  console.error(
5183
- chalk16.red(
5428
+ chalk17.red(
5184
5429
  "No linked project found. Run `yapout init` or `yapout link` in your repo first."
5185
5430
  )
5186
5431
  );
5187
5432
  process.exit(1);
5188
5433
  }
5189
5434
  const label = parsed.ticketId ? `${parsed.action} ${parsed.ticketId}` : parsed.action;
5190
- console.log(chalk16.dim(`Launching Claude Code to ${label}...`));
5435
+ console.log(chalk17.dim(`Launching Claude Code to ${label}...`));
5191
5436
  launchTerminal(cwd, ["--dangerously-skip-permissions", prompt]);
5192
5437
  setTimeout(() => process.exit(0), 500);
5193
5438
  } catch (err) {
5194
- console.error(chalk16.red(err.message));
5439
+ console.error(chalk17.red(err.message));
5195
5440
  process.exit(1);
5196
5441
  }
5197
5442
  });
5198
5443
 
5199
5444
  // 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");
5445
+ var program = new Command17();
5446
+ program.name("yapout").description("yapout \u2014 from meeting transcript to merged PR").version("0.9.0");
5202
5447
  program.addCommand(loginCommand);
5203
5448
  program.addCommand(logoutCommand);
5204
5449
  program.addCommand(initCommand);
@@ -5214,4 +5459,5 @@ program.addCommand(nextCommand);
5214
5459
  program.addCommand(recapCommand);
5215
5460
  program.addCommand(yapCommand);
5216
5461
  program.addCommand(handleUriCommand);
5462
+ program.addCommand(serveCommand);
5217
5463
  program.parse();