claudekit-cli 3.41.0 → 3.41.1-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -14880,7 +14880,7 @@ var init_ck_config = __esm(() => {
14880
14880
  "gemini-3-flash": "gemini-3-flash-preview",
14881
14881
  "gemini-3-pro": "gemini-3-pro-preview"
14882
14882
  };
14883
- GeminiModelSchema = exports_external.enum(GEMINI_MODEL_VALUES);
14883
+ GeminiModelSchema = exports_external.string().default("gemini-3-flash-preview");
14884
14884
  StatuslineModeSchema = exports_external.enum(["full", "compact", "minimal", "none"]);
14885
14885
  StatuslineSectionIdSchema = exports_external.enum([
14886
14886
  "model",
@@ -15193,6 +15193,7 @@ __export(exports_types, {
15193
15193
  GitHubReleaseAssetSchema: () => GitHubReleaseAssetSchema,
15194
15194
  GitHubError: () => GitHubError,
15195
15195
  GeminiModelSchema: () => GeminiModelSchema,
15196
+ GEMINI_MODEL_VALUES: () => GEMINI_MODEL_VALUES,
15196
15197
  FrameworkSchema: () => FrameworkSchema,
15197
15198
  FoldersConfigSchema: () => FoldersConfigSchema,
15198
15199
  ExtractionError: () => ExtractionError,
@@ -57632,7 +57633,7 @@ var package_default;
57632
57633
  var init_package = __esm(() => {
57633
57634
  package_default = {
57634
57635
  name: "claudekit-cli",
57635
- version: "3.41.0",
57636
+ version: "3.41.1-dev.1",
57636
57637
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
57637
57638
  type: "module",
57638
57639
  repository: {
@@ -57652,8 +57653,12 @@ var init_package = __esm(() => {
57652
57653
  "dist/ui/"
57653
57654
  ],
57654
57655
  scripts: {
57656
+ tauri: "tauri",
57657
+ "tauri:dev": "tauri dev",
57658
+ "tauri:build": "tauri build",
57655
57659
  dev: "bun run src/index.ts",
57656
57660
  "dashboard:dev": "cd src/ui && bun install --silent && cd ../.. && bun run src/index.ts config ui --dev",
57661
+ "dashboard:tauri": "cd src/ui && bun install --silent && cd ../.. && bun run src/index.ts config ui --dev --no-open --port 3456",
57657
57662
  "ui:build": "cd src/ui && bun install --silent && bun run build",
57658
57663
  "ui:dev": "cd src/ui && bun run dev",
57659
57664
  build: `bun build src/index.ts --outdir dist --target node --external @octokit/rest --external better-sqlite3 && node -e "const fs=require('fs'),f='dist/index.js',c=fs.readFileSync(f,'utf-8');fs.writeFileSync(f,c.replace(/^#!.*\\n\\/\\/ @bun\\n/,''))"`,
@@ -57718,6 +57723,7 @@ var init_package = __esm(() => {
57718
57723
  "@biomejs/biome": "^1.9.4",
57719
57724
  "@semantic-release/changelog": "^6.0.3",
57720
57725
  "@semantic-release/git": "^10.0.1",
57726
+ "@tauri-apps/cli": "^2",
57721
57727
  "@types/better-sqlite3": "^7.6.13",
57722
57728
  "@types/bun": "latest",
57723
57729
  "@types/cli-progress": "^3.11.6",
@@ -68343,7 +68349,7 @@ var init_content_validator = __esm(() => {
68343
68349
  import { createHash as createHash6 } from "node:crypto";
68344
68350
  import { existsSync as existsSync66, mkdirSync as mkdirSync4, readFileSync as readFileSync15, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
68345
68351
  import { rename as rename9, writeFile as writeFile35 } from "node:fs/promises";
68346
- import { homedir as homedir34 } from "node:os";
68352
+ import { homedir as homedir33 } from "node:os";
68347
68353
  import { basename as basename19, join as join132 } from "node:path";
68348
68354
  function getCachedContext(repoPath) {
68349
68355
  const cachePath = getCacheFilePath(repoPath);
@@ -68418,7 +68424,7 @@ function getCacheFilePath(repoPath) {
68418
68424
  }
68419
68425
  var CACHE_DIR, CACHE_TTL_MS4;
68420
68426
  var init_context_cache_manager = __esm(() => {
68421
- CACHE_DIR = join132(homedir34(), ".claudekit", "cache");
68427
+ CACHE_DIR = join132(homedir33(), ".claudekit", "cache");
68422
68428
  CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
68423
68429
  });
68424
68430
 
@@ -68872,10 +68878,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
68872
68878
  // src/commands/content/phases/photo-generator.ts
68873
68879
  import { execSync as execSync7 } from "node:child_process";
68874
68880
  import { existsSync as existsSync68, mkdirSync as mkdirSync5, readdirSync as readdirSync10 } from "node:fs";
68875
- import { homedir as homedir35 } from "node:os";
68881
+ import { homedir as homedir34 } from "node:os";
68876
68882
  import { join as join134 } from "node:path";
68877
68883
  async function generatePhoto(_content, context, config, platform14, contentId, contentLogger) {
68878
- const mediaDir = join134(config.contentDir.replace(/^~/, homedir35()), "media", String(contentId));
68884
+ const mediaDir = join134(config.contentDir.replace(/^~/, homedir34()), "media", String(contentId));
68879
68885
  if (!existsSync68(mediaDir)) {
68880
68886
  mkdirSync5(mediaDir, { recursive: true });
68881
68887
  }
@@ -68989,7 +68995,7 @@ var init_content_creator = __esm(() => {
68989
68995
 
68990
68996
  // src/commands/content/phases/content-logger.ts
68991
68997
  import { createWriteStream as createWriteStream4, existsSync as existsSync69, mkdirSync as mkdirSync6, statSync as statSync11 } from "node:fs";
68992
- import { homedir as homedir36 } from "node:os";
68998
+ import { homedir as homedir35 } from "node:os";
68993
68999
  import { join as join135 } from "node:path";
68994
69000
 
68995
69001
  class ContentLogger {
@@ -68998,7 +69004,7 @@ class ContentLogger {
68998
69004
  logDir;
68999
69005
  maxBytes;
69000
69006
  constructor(maxBytes = 0) {
69001
- this.logDir = join135(homedir36(), ".claudekit", "logs");
69007
+ this.logDir = join135(homedir35(), ".claudekit", "logs");
69002
69008
  this.maxBytes = maxBytes;
69003
69009
  }
69004
69010
  init() {
@@ -70597,11 +70603,11 @@ var init_setup_wizard = __esm(() => {
70597
70603
 
70598
70604
  // src/commands/content/content-review-commands.ts
70599
70605
  import { existsSync as existsSync73 } from "node:fs";
70600
- import { homedir as homedir37 } from "node:os";
70606
+ import { homedir as homedir36 } from "node:os";
70601
70607
  async function queueContent() {
70602
70608
  const cwd2 = process.cwd();
70603
70609
  const config = await loadContentConfig(cwd2);
70604
- const dbPath = config.dbPath.replace(/^~/, homedir37());
70610
+ const dbPath = config.dbPath.replace(/^~/, homedir36());
70605
70611
  if (!existsSync73(dbPath)) {
70606
70612
  logger.info("No content database found. Run 'ck content setup' first.");
70607
70613
  return;
@@ -70628,7 +70634,7 @@ async function queueContent() {
70628
70634
  async function approveContentCmd(id) {
70629
70635
  const cwd2 = process.cwd();
70630
70636
  const config = await loadContentConfig(cwd2);
70631
- const dbPath = config.dbPath.replace(/^~/, homedir37());
70637
+ const dbPath = config.dbPath.replace(/^~/, homedir36());
70632
70638
  const db = initDatabase(dbPath);
70633
70639
  try {
70634
70640
  approveContent(db, Number.parseInt(id, 10));
@@ -70640,7 +70646,7 @@ async function approveContentCmd(id) {
70640
70646
  async function rejectContentCmd(id, reason) {
70641
70647
  const cwd2 = process.cwd();
70642
70648
  const config = await loadContentConfig(cwd2);
70643
- const dbPath = config.dbPath.replace(/^~/, homedir37());
70649
+ const dbPath = config.dbPath.replace(/^~/, homedir36());
70644
70650
  const db = initDatabase(dbPath);
70645
70651
  try {
70646
70652
  rejectContent(db, Number.parseInt(id, 10), reason);
@@ -70671,7 +70677,7 @@ __export(exports_content_subcommands, {
70671
70677
  approveContentCmd: () => approveContentCmd
70672
70678
  });
70673
70679
  import { existsSync as existsSync74, readFileSync as readFileSync18, unlinkSync as unlinkSync5 } from "node:fs";
70674
- import { homedir as homedir38 } from "node:os";
70680
+ import { homedir as homedir37 } from "node:os";
70675
70681
  import { join as join140 } from "node:path";
70676
70682
  function isDaemonRunning() {
70677
70683
  const lockFile = join140(LOCK_DIR, `${LOCK_NAME2}.lock`);
@@ -70745,7 +70751,7 @@ async function statusContent() {
70745
70751
  } catch {}
70746
70752
  }
70747
70753
  async function logsContent(options2) {
70748
- const logDir = join140(homedir38(), ".claudekit", "logs");
70754
+ const logDir = join140(homedir37(), ".claudekit", "logs");
70749
70755
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
70750
70756
  const logPath = join140(logDir, `content-${dateStr}.log`);
70751
70757
  if (!existsSync74(logPath)) {
@@ -70779,12 +70785,12 @@ var init_content_subcommands = __esm(() => {
70779
70785
  init_setup_wizard();
70780
70786
  init_state_manager();
70781
70787
  init_content_review_commands();
70782
- LOCK_DIR = join140(homedir38(), ".claudekit", "locks");
70788
+ LOCK_DIR = join140(homedir37(), ".claudekit", "locks");
70783
70789
  });
70784
70790
 
70785
70791
  // src/commands/content/content-command.ts
70786
70792
  import { existsSync as existsSync75, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync6 } from "node:fs";
70787
- import { homedir as homedir39 } from "node:os";
70793
+ import { homedir as homedir38 } from "node:os";
70788
70794
  import { join as join141 } from "node:path";
70789
70795
  async function contentCommand(options2) {
70790
70796
  const cwd2 = process.cwd();
@@ -70817,7 +70823,7 @@ async function contentCommand(options2) {
70817
70823
  if (!existsSync75(LOCK_DIR2))
70818
70824
  mkdirSync8(LOCK_DIR2, { recursive: true });
70819
70825
  writeFileSync6(LOCK_FILE, String(process.pid), "utf-8");
70820
- const dbPath = config.dbPath.replace(/^~/, homedir39());
70826
+ const dbPath = config.dbPath.replace(/^~/, homedir38());
70821
70827
  const db = initDatabase(dbPath);
70822
70828
  contentLogger.info(`Database initialised at ${dbPath}`);
70823
70829
  const adapters = initializeAdapters(config);
@@ -70963,7 +70969,7 @@ var init_content_command = __esm(() => {
70963
70969
  init_publisher();
70964
70970
  init_review_manager();
70965
70971
  init_state_manager();
70966
- LOCK_DIR2 = join141(homedir39(), ".claudekit", "locks");
70972
+ LOCK_DIR2 = join141(homedir38(), ".claudekit", "locks");
70967
70973
  LOCK_FILE = join141(LOCK_DIR2, "ck-content.lock");
70968
70974
  });
70969
70975
 
@@ -82792,9 +82798,9 @@ var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
82792
82798
  import { mkdir as mkdir19 } from "node:fs/promises";
82793
82799
  import os5 from "node:os";
82794
82800
  import { join as join75 } from "node:path";
82795
- var LOCK_CONFIG = {
82796
- stale: 60000,
82797
- retries: 0
82801
+ var LOCK_CONFIGS = {
82802
+ short: { stale: 60000, retries: 0 },
82803
+ long: { stale: 300000, retries: 0 }
82798
82804
  };
82799
82805
  var activeLocks = new Set;
82800
82806
  var cleanupRegistered = false;
@@ -82804,8 +82810,7 @@ function getLocksDir() {
82804
82810
  function cleanupLocks() {
82805
82811
  for (const name of activeLocks) {
82806
82812
  try {
82807
- const lockPath = join75(getLocksDir(), `${name}.lock`);
82808
- import_proper_lockfile4.default.unlockSync(lockPath, { realpath: false });
82813
+ import_proper_lockfile4.default.unlockSync(getLockPaths(name).resource, { realpath: false });
82809
82814
  } catch {
82810
82815
  try {
82811
82816
  logger.verbose(`Failed to cleanup lock: ${name}`);
@@ -82824,13 +82829,24 @@ async function ensureLocksDir() {
82824
82829
  const lockDir = getLocksDir();
82825
82830
  await mkdir19(lockDir, { recursive: true });
82826
82831
  }
82827
- async function withProcessLock(lockName, fn) {
82832
+ function getLockPaths(lockName) {
82833
+ const resource = join75(getLocksDir(), `${lockName}.lock`);
82834
+ return { resource, lockfile: `${resource}.lock` };
82835
+ }
82836
+ async function withProcessLock(lockName, fn, duration = "short") {
82828
82837
  registerCleanupHandlers();
82829
82838
  await ensureLocksDir();
82830
- const lockPath = join75(getLocksDir(), `${lockName}.lock`);
82839
+ const { resource: lockPath } = getLockPaths(lockName);
82840
+ const config = LOCK_CONFIGS[duration];
82831
82841
  let release;
82832
82842
  try {
82833
- release = await import_proper_lockfile4.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
82843
+ release = await import_proper_lockfile4.default.lock(lockPath, {
82844
+ ...config,
82845
+ realpath: false,
82846
+ onCompromised: duration === "long" ? (err) => {
82847
+ logger.warning(`Lock "${lockName}" compromised: ${err.message}. Continuing...`);
82848
+ } : undefined
82849
+ });
82834
82850
  activeLocks.add(lockName);
82835
82851
  return await fn();
82836
82852
  } catch (e2) {
@@ -82840,11 +82856,24 @@ async function withProcessLock(lockName, fn) {
82840
82856
 
82841
82857
  Operation: ${lockName}
82842
82858
  Wait for it to complete or remove lock: ${lockPath}`);
82859
+ }
82860
+ if (error.code === "ECOMPROMISED") {
82861
+ throw new Error(`Lock was compromised (stale or externally removed).
82862
+
82863
+ Operation: ${lockName}
82864
+ Use --force to clear and restart.`);
82843
82865
  }
82844
82866
  throw e2;
82845
82867
  } finally {
82846
82868
  if (release) {
82847
- await release();
82869
+ try {
82870
+ await release();
82871
+ } catch (releaseErr) {
82872
+ const code = releaseErr.code;
82873
+ if (code !== "ERELEASED") {
82874
+ logger.warning(`Failed to release lock "${lockName}": ${releaseErr.message}`);
82875
+ }
82876
+ }
82848
82877
  }
82849
82878
  activeLocks.delete(lockName);
82850
82879
  }
@@ -93449,7 +93478,10 @@ class SettingsProcessor {
93449
93478
  }
93450
93479
  let transformed = content;
93451
93480
  const rawPrefix = prefix.replace(/"/g, "");
93452
- transformed = transformed.replace(/(node\s+)(?:\.\/)?(\.claude\/[^\s"\\]+)/g, `$1\\"${rawPrefix}/$2\\"`);
93481
+ transformed = transformed.replace(/(node\s+)(?:\.\/)?(\.claude\/[^\s"\\]+)([^"\\]*)/g, (_match, nodePrefix, relativePath, suffix) => {
93482
+ const normalizedRelativePath = relativePath.replace(/\\/g, "/");
93483
+ return rawPrefix === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}\\"${rawPrefix}\\"/${normalizedRelativePath}${suffix}` : `${nodePrefix}\\"${rawPrefix}/${normalizedRelativePath}\\"${suffix}`;
93484
+ });
93453
93485
  if (rawPrefix.includes("HOME") || rawPrefix.includes("USERPROFILE")) {
93454
93486
  transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g, rawPrefix);
93455
93487
  transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g, rawPrefix);
@@ -93495,33 +93527,38 @@ class SettingsProcessor {
93495
93527
  fixSingleCommandPath(cmd) {
93496
93528
  if (!cmd.includes(".claude/") && !cmd.includes(".claude\\"))
93497
93529
  return cmd;
93498
- const bareRelativeRe = /^(node\s+)(?:\.\/)?\.claude\//;
93499
- if (bareRelativeRe.test(cmd)) {
93500
- const prefix = this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR";
93501
- return cmd.replace(/^(node\s+)(?:\.\/)?(\.claude\/.+)$/, `$1"${prefix}/$2"`);
93502
- }
93503
- const varOnlyQuotingRe = /^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](.+)$/;
93504
- const varOnlyMatch = cmd.match(varOnlyQuotingRe);
93505
- if (varOnlyMatch) {
93506
- const [, nodePrefix, capturedVar, restPath] = varOnlyMatch;
93507
- const canonicalVar = this.canonicalizePathVar(capturedVar);
93508
- return `${nodePrefix}"${canonicalVar}/${restPath.replace(/\\/g, "/")}"`;
93509
- }
93510
- const tildeRe = /^(node\s+)~[/\\](.+)$/;
93511
- const tildeMatch = cmd.match(tildeRe);
93530
+ const bareRelativeMatch = cmd.match(/^(node\s+)(?:\.\/)?(\.claude[/\\][^\s"]+)(.*)$/);
93531
+ if (bareRelativeMatch) {
93532
+ const [, nodePrefix, relativePath, suffix] = bareRelativeMatch;
93533
+ return this.formatCommandPath(nodePrefix, this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR", relativePath, suffix);
93534
+ }
93535
+ const embeddedQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
93536
+ if (embeddedQuotedMatch) {
93537
+ const [, nodePrefix, capturedVar, relativePath, suffix] = embeddedQuotedMatch;
93538
+ return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
93539
+ }
93540
+ const varOnlyQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](\.claude[/\\][^\s"]+)(.*)$/);
93541
+ if (varOnlyQuotedMatch) {
93542
+ const [, nodePrefix, capturedVar, relativePath, suffix] = varOnlyQuotedMatch;
93543
+ return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
93544
+ }
93545
+ const tildeMatch = cmd.match(/^(node\s+)~[/\\](\.claude[/\\][^\s"]+)(.*)$/);
93512
93546
  if (tildeMatch) {
93513
- const [, nodePrefix, restPath] = tildeMatch;
93514
- return `${nodePrefix}"$HOME/${restPath.replace(/\\/g, "/")}"`;
93547
+ const [, nodePrefix, relativePath, suffix] = tildeMatch;
93548
+ return this.formatCommandPath(nodePrefix, "$HOME", relativePath, suffix);
93515
93549
  }
93516
- const unquotedRe = /^(node\s+)(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](.+)$/;
93517
- const unquotedMatch = cmd.match(unquotedRe);
93550
+ const unquotedMatch = cmd.match(/^(node\s+)(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^\s"]+)(.*)$/);
93518
93551
  if (unquotedMatch) {
93519
- const [, nodePrefix, capturedVar, restPath] = unquotedMatch;
93520
- const canonicalVar = this.canonicalizePathVar(capturedVar);
93521
- return `${nodePrefix}"${canonicalVar}/${restPath.replace(/\\/g, "/")}"`;
93552
+ const [, nodePrefix, capturedVar, relativePath, suffix] = unquotedMatch;
93553
+ return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
93522
93554
  }
93523
93555
  return cmd;
93524
93556
  }
93557
+ formatCommandPath(nodePrefix, capturedVar, relativePath, suffix = "") {
93558
+ const canonicalVar = this.canonicalizePathVar(capturedVar);
93559
+ const normalizedRelativePath = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
93560
+ return canonicalVar === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}"${canonicalVar}"/${normalizedRelativePath}${suffix}` : `${nodePrefix}"${canonicalVar}/${normalizedRelativePath}"${suffix}`;
93561
+ }
93525
93562
  canonicalizePathVar(capturedVar) {
93526
93563
  switch (capturedVar) {
93527
93564
  case "%USERPROFILE%":
@@ -93570,7 +93607,6 @@ class SettingsProcessor {
93570
93607
  logger.warning("Failed to read settings file for team hooks injection");
93571
93608
  return;
93572
93609
  }
93573
- const prefix = this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR";
93574
93610
  if (!settings.hooks) {
93575
93611
  settings.hooks = {};
93576
93612
  }
@@ -93581,7 +93617,7 @@ class SettingsProcessor {
93581
93617
  { event: "TeammateIdle", handler: "teammate-idle-handler.cjs" }
93582
93618
  ];
93583
93619
  for (const { event, handler } of teamHooks) {
93584
- const hookCommand = `node "${prefix}/.claude/hooks/${handler}"`;
93620
+ const hookCommand = this.formatCommandPath("node ", this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR", `.claude/hooks/${handler}`);
93585
93621
  const eventHooks = settings.hooks[event];
93586
93622
  if (eventHooks && eventHooks.length > 0)
93587
93623
  continue;
@@ -101684,7 +101720,6 @@ ${import_picocolors38.default.bold(import_picocolors38.default.cyan(result.kitCo
101684
101720
  init_logger();
101685
101721
  import { existsSync as existsSync65 } from "node:fs";
101686
101722
  import { rm as rm16 } from "node:fs/promises";
101687
- import { homedir as homedir33 } from "node:os";
101688
101723
  import { join as join131 } from "node:path";
101689
101724
  var import_picocolors39 = __toESM(require_picocolors(), 1);
101690
101725
 
@@ -102236,6 +102271,9 @@ async function invokeClaude(options2) {
102236
102271
  "--allowedTools",
102237
102272
  tools
102238
102273
  ];
102274
+ if (outputFormat === "stream-json") {
102275
+ args.push("--verbose");
102276
+ }
102239
102277
  const child = spawn10("claude", args, {
102240
102278
  cwd: options2.cwd,
102241
102279
  stdio: ["pipe", "pipe", "pipe"],
@@ -102281,7 +102319,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
102281
102319
  });
102282
102320
  }
102283
102321
  function logStreamEvent(chunk) {
102284
- for (const line of chunk.split(`
102322
+ for (const line of chunk.replace(/\r/g, "").split(`
102285
102323
  `).filter(Boolean)) {
102286
102324
  try {
102287
102325
  const event = JSON.parse(line);
@@ -102309,7 +102347,7 @@ function logStreamEvent(chunk) {
102309
102347
  }
102310
102348
  }
102311
102349
  function parseStreamJsonOutput(stdout2) {
102312
- const lines = stdout2.split(`
102350
+ const lines = stdout2.replace(/\r/g, "").split(`
102313
102351
  `).filter(Boolean);
102314
102352
  for (let i = lines.length - 1;i >= 0; i--) {
102315
102353
  try {
@@ -103409,11 +103447,13 @@ async function watchCommand(options2) {
103409
103447
  process.removeListener("SIGINT", shutdown);
103410
103448
  process.removeListener("SIGTERM", shutdown);
103411
103449
  }
103412
- });
103450
+ }, "long");
103413
103451
  } catch (error) {
103414
103452
  const err = error;
103415
103453
  if (err.message?.includes("Another ClaudeKit process")) {
103416
103454
  logger.error("Another ck watch instance is already running. Use --force to override.");
103455
+ } else if (err.message?.includes("Lock was compromised")) {
103456
+ logger.error("Lock was compromised (stale or externally removed). Use --force to restart.");
103417
103457
  } else {
103418
103458
  watchLog.error("Watch command failed", err);
103419
103459
  console.error(`[ck watch] Fatal: ${err.message}`);
@@ -103496,9 +103536,12 @@ async function resetState(state, projectDir, watchLog) {
103496
103536
  watchLog.info(`Watch state reset (--force) for ${projectDir}`);
103497
103537
  }
103498
103538
  async function forceRemoveLock(watchLog) {
103499
- const lockPath = join131(homedir33(), ".claudekit", "locks", `${LOCK_NAME}.lock`);
103539
+ const { resource, lockfile: lockfile5 } = getLockPaths(LOCK_NAME);
103500
103540
  try {
103501
- await rm16(lockPath, { recursive: true, force: true });
103541
+ await Promise.all([
103542
+ rm16(resource, { recursive: true, force: true }),
103543
+ rm16(lockfile5, { recursive: true, force: true })
103544
+ ]);
103502
103545
  watchLog.info("Removed existing lock file (--force)");
103503
103546
  } catch {}
103504
103547
  }