@alecsibilia/luca 13.0.0-alpha.4 → 13.0.0-alpha.5

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 (39) hide show
  1. package/dist/chunks/branch.mjs +6 -6
  2. package/dist/chunks/checks.mjs +6 -6
  3. package/dist/chunks/claim-verify.mjs +1 -1
  4. package/dist/chunks/classify.mjs +1 -1
  5. package/dist/chunks/confidence.mjs +6 -6
  6. package/dist/chunks/config-version-skew.mjs +97 -0
  7. package/dist/chunks/doctor.mjs +3 -1
  8. package/dist/chunks/hook.mjs +79 -9
  9. package/dist/chunks/init.mjs +28 -12
  10. package/dist/chunks/phase.mjs +6 -6
  11. package/dist/chunks/pr-review.mjs +6 -6
  12. package/dist/chunks/preferences.mjs +6 -6
  13. package/dist/chunks/repair.mjs +1 -1
  14. package/dist/chunks/repo.mjs +6 -6
  15. package/dist/chunks/retro.mjs +5 -5
  16. package/dist/chunks/roadmap.mjs +6 -6
  17. package/dist/chunks/rules.mjs +5 -5
  18. package/dist/chunks/state.mjs +47 -7
  19. package/dist/chunks/stray-local-install.mjs +1 -1
  20. package/dist/chunks/telemetry.mjs +1 -1
  21. package/dist/chunks/todo.mjs +6 -6
  22. package/dist/chunks/vault-init.mjs +1 -1
  23. package/dist/chunks/verification.mjs +4 -4
  24. package/dist/chunks/workflow.mjs +6 -6
  25. package/dist/claude/.claude/hooks/context-refresher.ts +1 -0
  26. package/dist/claude/.claude/hooks/continuation-messages.ts +1 -0
  27. package/dist/claude/.claude/hooks/pipeline-guard.ts +1 -0
  28. package/dist/claude/skills/luca-write-surface/SKILL.md +8 -3
  29. package/dist/index.mjs +1 -1
  30. package/dist/shared/{luca.BKNzBAX6.mjs → luca.0ssL9rcP.mjs} +2 -2
  31. package/dist/shared/{luca.CbQLVJY4.mjs → luca.B-w_fieK.mjs} +1 -1
  32. package/dist/shared/luca.BTcIy-Mh.mjs +183 -0
  33. package/dist/shared/{luca.EQGAqeU5.mjs → luca.BiHycbFi.mjs} +3 -3
  34. package/dist/shared/{luca.DEnRxIjr.mjs → luca.Cf93m-DM.mjs} +1 -1
  35. package/dist/shared/{luca.CSIEeM0g.mjs → luca.D7w2gjQ5.mjs} +2 -2
  36. package/dist/shared/{luca.Q3_4GQWh.mjs → luca.DZxAJmyM.mjs} +28 -2
  37. package/dist/shared/{luca.CZNcKKAw.mjs → luca.lLQ2ZIAB.mjs} +86 -134
  38. package/package.json +1 -1
  39. package/dist/shared/luca.Djs7oPPj.mjs +0 -57
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { r as runWriteHandler, t as lucaBranchGuardTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { r as runWriteHandler, u as lucaBranchGuardTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const guardCommand = defineCommand({
20
20
  meta: {
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { e as readJsonPayload, r as runWriteHandler, s as lucaChecksRunTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { f as readJsonPayload, r as runWriteHandler, t as lucaChecksRunTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const runCommand = defineCommand({
20
20
  meta: {
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import { resolve } from 'pathe';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import { join } from 'node:path';
@@ -1,5 +1,5 @@
1
1
  import { defineCommand } from 'citty';
2
- import { C as ClassifyComplexityInputSchema } from '../shared/luca.Q3_4GQWh.mjs';
2
+ import { C as ClassifyComplexityInputSchema } from '../shared/luca.DZxAJmyM.mjs';
3
3
  import 'node:fs';
4
4
  import 'node:fs/promises';
5
5
  import 'node:path';
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
- import '../shared/luca.Q3_4GQWh.mjs';
3
- import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.DEnRxIjr.mjs';
2
+ import '../shared/luca.DZxAJmyM.mjs';
3
+ import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.Cf93m-DM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,15 +8,15 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { b as renderConfidenceJournalMarkdown, r as readConfidenceJournal, g as getConfidenceSummary } from '../shared/luca.CSIEeM0g.mjs';
11
+ import { b as renderConfidenceJournalMarkdown, r as readConfidenceJournal, g as getConfidenceSummary } from '../shared/luca.D7w2gjQ5.mjs';
12
12
  import { l as logger } from '../shared/luca.dM-MKlNE.mjs';
13
13
  import 'zod';
14
- import { e as readJsonPayload, r as runWriteHandler, v as lucaConfidenceLogTool } from '../shared/luca.CZNcKKAw.mjs';
14
+ import { f as readJsonPayload, r as runWriteHandler, w as lucaConfidenceLogTool } from '../shared/luca.lLQ2ZIAB.mjs';
15
+ import '../shared/luca.BTcIy-Mh.mjs';
15
16
  import 'node:os';
16
- import '../shared/luca.CbQLVJY4.mjs';
17
+ import '../shared/luca.B-w_fieK.mjs';
17
18
  import 'consola';
18
19
  import '../shared/luca.CQ3g1xrD.mjs';
19
- import '../shared/luca.Djs7oPPj.mjs';
20
20
 
21
21
  async function resolveSlug(opts) {
22
22
  if (opts.explicit) return opts.explicit;
@@ -0,0 +1,97 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { writeFile, readFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { LUCA_VERSION } from '../index.mjs';
5
+ import 'citty';
6
+ import 'pathe';
7
+
8
+ const CHECK_NAME = "Config version skew";
9
+ function configPath() {
10
+ return join(process.cwd(), ".luca", "config.json");
11
+ }
12
+ function isDevVersion(v) {
13
+ return v === "0.0.0-dev" || v.includes("dev");
14
+ }
15
+ async function readConfig() {
16
+ const p = configPath();
17
+ if (!existsSync(p)) return null;
18
+ try {
19
+ const raw = JSON.parse(await readFile(p, "utf-8"));
20
+ return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : null;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+ const configVersionSkewCheck = {
26
+ name: CHECK_NAME,
27
+ scope: "project",
28
+ async run() {
29
+ const pass = (message) => ({
30
+ name: CHECK_NAME,
31
+ status: "pass",
32
+ message,
33
+ fixCommand: null,
34
+ details: null
35
+ });
36
+ if (isDevVersion(LUCA_VERSION)) {
37
+ return pass("dev CLI build \u2014 version skew not checked");
38
+ }
39
+ const config = await readConfig();
40
+ if (config === null) {
41
+ return pass("no .luca/config.json to check");
42
+ }
43
+ const stored = config.lucaVersion;
44
+ if (typeof stored !== "string" || stored.length === 0) {
45
+ return pass("config.json has no lucaVersion to compare");
46
+ }
47
+ if (stored === LUCA_VERSION) {
48
+ return pass(`config.lucaVersion matches CLI (${LUCA_VERSION})`);
49
+ }
50
+ return {
51
+ name: CHECK_NAME,
52
+ status: "warning",
53
+ message: `config.lucaVersion ${stored} \u2260 installed CLI ${LUCA_VERSION}`,
54
+ fixCommand: "luca doctor --fix",
55
+ details: [
56
+ `.luca/config.json records lucaVersion="${stored}" but the installed CLI is ${LUCA_VERSION}.`,
57
+ `Skills/agents that branch on lucaVersion may behave as if on the older version.`,
58
+ `Run \`luca doctor --fix\` to reconcile (rewrites lucaVersion, preserves all other config keys).`
59
+ ].join("\n ")
60
+ };
61
+ },
62
+ async fix() {
63
+ if (isDevVersion(LUCA_VERSION)) {
64
+ return { applied: [], errors: [] };
65
+ }
66
+ const config = await readConfig();
67
+ if (config === null) {
68
+ return { applied: [], errors: [] };
69
+ }
70
+ const stored = config.lucaVersion;
71
+ if (stored === LUCA_VERSION) {
72
+ return { applied: [], errors: [] };
73
+ }
74
+ try {
75
+ const next = { ...config, lucaVersion: LUCA_VERSION };
76
+ await writeFile(
77
+ configPath(),
78
+ JSON.stringify(next, null, 2) + "\n"
79
+ );
80
+ return {
81
+ applied: [
82
+ `Reconciled .luca/config.json lucaVersion ${typeof stored === "string" ? stored : "unset"} \u2192 ${LUCA_VERSION}`
83
+ ],
84
+ errors: []
85
+ };
86
+ } catch (err) {
87
+ return {
88
+ applied: [],
89
+ errors: [
90
+ `Failed to rewrite .luca/config.json lucaVersion: ${err.message}`
91
+ ]
92
+ };
93
+ }
94
+ }
95
+ };
96
+
97
+ export { configVersionSkewCheck };
@@ -12,6 +12,7 @@ async function executeDoctor(options = {}) {
12
12
  const { staleGlobalSymlinksCheck } = await import('./stale-global-symlinks.mjs');
13
13
  const { legacyPackageCheck } = await import('./legacy-package.mjs');
14
14
  const { strayLocalInstallCheck } = await import('./stray-local-install.mjs');
15
+ const { configVersionSkewCheck } = await import('./config-version-skew.mjs');
15
16
  const allChecks = [
16
17
  // Prerequisites
17
18
  bunRuntimeCheck,
@@ -22,7 +23,8 @@ async function executeDoctor(options = {}) {
22
23
  staleGlobalSymlinksCheck,
23
24
  legacyPackageCheck,
24
25
  // Project (cwd-dependent)
25
- strayLocalInstallCheck
26
+ strayLocalInstallCheck,
27
+ configVersionSkewCheck
26
28
  ];
27
29
  const checks = scope ? allChecks.filter((check) => check.scope === scope) : allChecks;
28
30
  if (checks.length === 0) {
@@ -1,11 +1,11 @@
1
1
  import { defineCommand } from 'citty';
2
- import { c as coarsePhaseOf, a as classifyWritePath, A as AUDIT_PATH_PATTERN, W as WAVE_FILE_RE } from '../shared/luca.Q3_4GQWh.mjs';
3
- import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.DEnRxIjr.mjs';
2
+ import { c as coarsePhaseOf, t as toLucaRelative, a as classifyWritePath, A as AUDIT_PATH_PATTERN, W as WAVE_FILE_RE } from '../shared/luca.DZxAJmyM.mjs';
3
+ import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.Cf93m-DM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
- import { isAbsolute, relative } from 'node:path';
7
- import { S as STEP_ARTIFACTS } from '../shared/luca.Djs7oPPj.mjs';
8
- import { p as phasePathFor } from '../shared/luca.CbQLVJY4.mjs';
6
+ import 'node:path';
7
+ import { l as lucaStateClaimOwnerTool, S as STEP_ARTIFACTS } from '../shared/luca.BTcIy-Mh.mjs';
8
+ import { p as phasePathFor } from '../shared/luca.B-w_fieK.mjs';
9
9
  import 'node:crypto';
10
10
  import 'node:module';
11
11
  import 'node:url';
@@ -94,7 +94,29 @@ const READONLY_COMMANDS = /* @__PURE__ */ new Set([
94
94
  "echo",
95
95
  "printf",
96
96
  "true",
97
- "false"
97
+ "false",
98
+ // Read-only text filters. These read stdin/files and write to stdout —
99
+ // they never mutate files on their own. Omitting them made any pipeline
100
+ // through a filter (e.g. `find . | sort`) promote to bash-mutate via the
101
+ // unknown-command fallback, blocking read-only inspection in restrictive
102
+ // phases (v13 run report, M1). `tee`/`xargs` are deliberately EXCLUDED:
103
+ // `tee` writes files and `xargs` runs an arbitrary (possibly mutating)
104
+ // command, so they stay conservative.
105
+ "sort",
106
+ "uniq",
107
+ "cut",
108
+ "tr",
109
+ "comm",
110
+ "diff",
111
+ "jq",
112
+ "rg",
113
+ "column",
114
+ "nl",
115
+ "tac",
116
+ "rev",
117
+ "paste",
118
+ "fold",
119
+ "join"
98
120
  ]);
99
121
  const GIT_READONLY_SUBCOMMANDS = /* @__PURE__ */ new Set([
100
122
  "status",
@@ -191,6 +213,16 @@ const PKG_MUTATE_PATTERNS = [
191
213
  ["pnpm", "add"]
192
214
  ];
193
215
  const ALWAYS_DENIED_COMMANDS = /* @__PURE__ */ new Set(["eval", "source", "."]);
216
+ const LUCA_TOPLEVEL_READ = /* @__PURE__ */ new Set(["version", "telemetry", "rules"]);
217
+ const LUCA_TOPLEVEL_WRITE = /* @__PURE__ */ new Set([
218
+ "init",
219
+ "vault:init",
220
+ "retro",
221
+ "claim-verify",
222
+ "classify",
223
+ "doctor",
224
+ "repair"
225
+ ]);
194
226
  const LUCA_READ_VERBS = /* @__PURE__ */ new Set([
195
227
  "read",
196
228
  "current",
@@ -202,7 +234,7 @@ const LUCA_READ_VERBS = /* @__PURE__ */ new Set([
202
234
  "regression-check"
203
235
  ]);
204
236
  const LUCA_NOUN_VERBS = {
205
- state: /* @__PURE__ */ new Set(["read", "advance"]),
237
+ state: /* @__PURE__ */ new Set(["read", "advance", "claim-owner", "set-current-phase"]),
206
238
  phase: /* @__PURE__ */ new Set(["current", "advance", "archive"]),
207
239
  roadmap: /* @__PURE__ */ new Set(["read", "create"]),
208
240
  preferences: /* @__PURE__ */ new Set(["read", "write"]),
@@ -227,7 +259,11 @@ function classifyLucaCommand(rest) {
227
259
  const noun = rest.find((t) => !t.startsWith("-"));
228
260
  if (!noun) return "bash-readonly";
229
261
  const verbs = LUCA_NOUN_VERBS[noun];
230
- if (!verbs) return void 0;
262
+ if (!verbs) {
263
+ if (LUCA_TOPLEVEL_READ.has(noun)) return "bash-readonly";
264
+ if (LUCA_TOPLEVEL_WRITE.has(noun)) return "luca-write";
265
+ return void 0;
266
+ }
231
267
  const afterNoun = rest.slice(rest.indexOf(noun) + 1);
232
268
  const verb = afterNoun.find((t) => !t.startsWith("-"));
233
269
  if (!verb || !verbs.has(verb)) {
@@ -499,9 +535,21 @@ async function handleStageGateHook(opts) {
499
535
  }
500
536
  const toolName = parsed.tool_name ?? parsed.toolName;
501
537
  const toolInput = parsed.tool_input ?? parsed.toolInput;
538
+ const sessionId = parsed.session_id ?? parsed.sessionId;
502
539
  const cwd = opts.cwd ?? process.cwd();
503
540
  const homedir = opts.homedir ?? process.env.HOME;
504
541
  const state = await loadCurrentState({ cwd });
542
+ if (toolName === "Bash" && sessionId && state.ownerSessionId !== sessionId && isStateAdvanceCommand(
543
+ toolInput?.command ?? ""
544
+ )) {
545
+ try {
546
+ await lucaStateClaimOwnerTool.handler({ sessionId }, { cwd });
547
+ state.ownerSessionId = sessionId;
548
+ } catch (err) {
549
+ log(`stage-gate: owner stamp skipped (${err.message})`);
550
+ }
551
+ }
552
+ const isBystander = Boolean(state.ownerSessionId) && Boolean(sessionId) && state.ownerSessionId !== sessionId;
505
553
  const phase = coarsePhaseOf(state.pipelineStep);
506
554
  if (phase === "IDLE") {
507
555
  log(
@@ -517,7 +565,7 @@ async function handleStageGateHook(opts) {
517
565
  log(`stage-gate: ${toolName} without file_path \u2014 allowing`);
518
566
  return { exitCode: 0, toolName, toolInput, decision: "allow" };
519
567
  }
520
- const relTarget = isAbsolute(targetPath) ? relative(cwd, targetPath) : targetPath;
568
+ const relTarget = toLucaRelative(targetPath, cwd);
521
569
  const pc = classifyWritePath(targetPath, { homedir, cwd });
522
570
  if (pc.class === "denied") {
523
571
  pathBlockReason = `${toolName} to '${targetPath}' is always denied: ${pc.reason ?? "forbidden path"}`;
@@ -579,6 +627,12 @@ async function handleStageGateHook(opts) {
579
627
  log("stage-gate: could not classify tool \u2014 allowing");
580
628
  return { exitCode: 0, toolName, toolInput, decision: "allow" };
581
629
  }
630
+ if (isBystander) {
631
+ log(
632
+ `stage-gate: session ${sessionId} is not the run owner (${state.ownerSessionId}) \u2014 exempting ${toolName} (category=${category}) from the phase=${phase} matrix`
633
+ );
634
+ return { exitCode: 0, toolName, toolInput, decision: "allow" };
635
+ }
582
636
  const allowed = isToolAllowed({ phase, category });
583
637
  if (!allowed) {
584
638
  const msg = `stage-gate BLOCK: ${toolName} (category=${category}) is not allowed in phase=${phase} (pipelineStep=${state.pipelineStep})`;
@@ -596,6 +650,22 @@ async function handleStageGateHook(opts) {
596
650
  );
597
651
  return { exitCode: 0, toolName, toolInput, decision: "allow" };
598
652
  }
653
+ function isStateAdvanceCommand(command) {
654
+ if (!command.includes("advance")) return false;
655
+ let entries;
656
+ try {
657
+ entries = parse(command);
658
+ } catch {
659
+ return false;
660
+ }
661
+ const toks = entries.filter((e) => typeof e === "string");
662
+ for (let i = 0; i <= toks.length - 3; i += 1) {
663
+ if (toks[i] === "luca" && toks[i + 1] === "state" && toks[i + 2] === "advance") {
664
+ return true;
665
+ }
666
+ }
667
+ return false;
668
+ }
599
669
  const FIXED_PHASE_FILE_ARTIFACTS = /* @__PURE__ */ new Set([
600
670
  "research",
601
671
  "context",
@@ -1,9 +1,9 @@
1
1
  import * as p from '@clack/prompts';
2
2
  import { defineCommand, runMain } from 'citty';
3
3
  import { existsSync, chmodSync } from 'node:fs';
4
- import { mkdir, writeFile, readFile, readdir, copyFile } from 'node:fs/promises';
4
+ import { mkdir, readFile, writeFile, readdir, copyFile } from 'node:fs/promises';
5
5
  import { join, dirname, delimiter } from 'node:path';
6
- import { l as lucaStateSchema } from '../shared/luca.Q3_4GQWh.mjs';
6
+ import { l as lucaStateSchema } from '../shared/luca.DZxAJmyM.mjs';
7
7
  import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
@@ -25,16 +25,21 @@ async function writeProjectSkeleton(opts) {
25
25
  });
26
26
  const lucaDir = join(opts.cwd, ".luca");
27
27
  await mkdir(lucaDir, { recursive: true });
28
- await writeIfMissing({
29
- path: join(lucaDir, "state.json"),
30
- contents: JSON.stringify(
31
- lucaStateSchema.parse({ sessionId: generateRunId() }),
32
- null,
33
- 2
34
- ) + "\n",
35
- force: opts.force ?? false,
36
- log
37
- });
28
+ const statePath = join(lucaDir, "state.json");
29
+ if (existsSync(statePath) && await isActiveState(statePath)) {
30
+ log(` skip: ${statePath} (active workflow \u2014 refusing to overwrite)`);
31
+ } else {
32
+ await writeIfMissing({
33
+ path: statePath,
34
+ contents: JSON.stringify(
35
+ lucaStateSchema.parse({ sessionId: generateRunId() }),
36
+ null,
37
+ 2
38
+ ) + "\n",
39
+ force: opts.force ?? false,
40
+ log
41
+ });
42
+ }
38
43
  await writeIfMissing({
39
44
  path: join(lucaDir, "config.json"),
40
45
  contents: JSON.stringify(
@@ -50,6 +55,17 @@ async function writeProjectSkeleton(opts) {
50
55
  log
51
56
  });
52
57
  }
58
+ async function isActiveState(statePath) {
59
+ try {
60
+ const raw = JSON.parse(await readFile(statePath, "utf-8"));
61
+ const step = raw.pipelineStep;
62
+ const roadmap = raw.roadmap;
63
+ const currentPhase = raw.currentPhase;
64
+ return typeof step === "string" && step !== "idle" || Array.isArray(roadmap) && roadmap.length > 0 || typeof currentPhase === "number" && currentPhase > 0;
65
+ } catch {
66
+ return false;
67
+ }
68
+ }
53
69
  async function writeIfMissing(args) {
54
70
  if (existsSync(args.path) && !args.force) {
55
71
  args.log(` skip: ${args.path} (already exists)`);
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { r as runWriteHandler, b as lucaPhaseCurrentTool, c as lucaPhaseAdvanceTool, d as lucaPhaseArchiveTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { r as runWriteHandler, c as lucaPhaseCurrentTool, d as lucaPhaseAdvanceTool, e as lucaPhaseArchiveTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const currentCommand = defineCommand({
20
20
  meta: {
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { e as readJsonPayload, r as runWriteHandler, n as lucaPrReviewDetectConvergenceTool, o as lucaPrReviewFilterStaleTool, p as lucaPrReviewRegressionCheckTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { f as readJsonPayload, r as runWriteHandler, o as lucaPrReviewDetectConvergenceTool, p as lucaPrReviewFilterStaleTool, q as lucaPrReviewRegressionCheckTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const filterStaleCommand = defineCommand({
20
20
  meta: {
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { e as readJsonPayload, r as runWriteHandler, h as lucaPreferencesReadTool, i as lucaPreferencesWriteTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { f as readJsonPayload, r as runWriteHandler, i as lucaPreferencesReadTool, j as lucaPreferencesWriteTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const readCommand = defineCommand({
20
20
  meta: {
@@ -2,7 +2,7 @@ import { defineCommand } from 'citty';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { readFile, rm } from 'node:fs/promises';
4
4
  import { join } from 'node:path';
5
- import { l as lucaStateSchema } from '../shared/luca.Q3_4GQWh.mjs';
5
+ import { l as lucaStateSchema } from '../shared/luca.DZxAJmyM.mjs';
6
6
  import 'node:crypto';
7
7
  import 'node:module';
8
8
  import 'node:url';
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { e as readJsonPayload, r as runWriteHandler, q as lucaRepoCleanupApplyTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { f as readJsonPayload, r as runWriteHandler, s as lucaRepoCleanupApplyTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const cleanupApplyCommand = defineCommand({
20
20
  meta: {
@@ -1,5 +1,5 @@
1
1
  import { defineCommand } from 'citty';
2
- import '../shared/luca.Q3_4GQWh.mjs';
2
+ import '../shared/luca.DZxAJmyM.mjs';
3
3
  import 'node:fs';
4
4
  import 'node:fs/promises';
5
5
  import 'node:path';
@@ -7,13 +7,13 @@ import 'node:crypto';
7
7
  import 'node:module';
8
8
  import 'node:url';
9
9
  import 'node:child_process';
10
- import { a as analyzeRun, g as gatherRunArtifacts, r as renderPostmortemMarkdown, c as computePostmortemExitCode } from '../shared/luca.EQGAqeU5.mjs';
11
- import { l as listRuns } from '../shared/luca.CSIEeM0g.mjs';
10
+ import { a as analyzeRun, g as gatherRunArtifacts, r as renderPostmortemMarkdown, c as computePostmortemExitCode } from '../shared/luca.BiHycbFi.mjs';
11
+ import { l as listRuns } from '../shared/luca.D7w2gjQ5.mjs';
12
12
  import { l as logger } from '../shared/luca.dM-MKlNE.mjs';
13
13
  import 'zod';
14
14
  import 'node:os';
15
- import '../shared/luca.BKNzBAX6.mjs';
16
- import '../shared/luca.CbQLVJY4.mjs';
15
+ import '../shared/luca.0ssL9rcP.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
17
17
  import 'pathe';
18
18
  import 'consola';
19
19
 
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import 'zod';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import 'node:module';
9
9
  import 'node:url';
10
10
  import 'node:child_process';
11
- import { e as readJsonPayload, r as runWriteHandler, f as lucaRoadmapReadTool, g as lucaRoadmapCreateTool } from '../shared/luca.CZNcKKAw.mjs';
11
+ import { f as readJsonPayload, r as runWriteHandler, g as lucaRoadmapReadTool, h as lucaRoadmapCreateTool } from '../shared/luca.lLQ2ZIAB.mjs';
12
+ import '../shared/luca.BTcIy-Mh.mjs';
12
13
  import 'node:os';
13
- import '../shared/luca.DEnRxIjr.mjs';
14
- import '../shared/luca.CSIEeM0g.mjs';
15
- import '../shared/luca.CbQLVJY4.mjs';
14
+ import '../shared/luca.Cf93m-DM.mjs';
15
+ import '../shared/luca.D7w2gjQ5.mjs';
16
+ import '../shared/luca.B-w_fieK.mjs';
16
17
  import '../shared/luca.CQ3g1xrD.mjs';
17
- import '../shared/luca.Djs7oPPj.mjs';
18
18
 
19
19
  const readCommand = defineCommand({
20
20
  meta: {
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import { join as join$1 } from 'pathe';
3
- import '../shared/luca.Q3_4GQWh.mjs';
3
+ import '../shared/luca.DZxAJmyM.mjs';
4
4
  import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
5
5
  import 'node:fs/promises';
6
6
  import { isAbsolute, resolve, join, extname } from 'node:path';
@@ -8,13 +8,13 @@ import 'node:crypto';
8
8
  import { createRequire } from 'node:module';
9
9
  import { pathToFileURL } from 'node:url';
10
10
  import 'node:child_process';
11
- import { a as analyzeRun, g as gatherRunArtifacts } from '../shared/luca.EQGAqeU5.mjs';
12
- import { l as listRuns } from '../shared/luca.CSIEeM0g.mjs';
11
+ import { a as analyzeRun, g as gatherRunArtifacts } from '../shared/luca.BiHycbFi.mjs';
12
+ import { l as listRuns } from '../shared/luca.D7w2gjQ5.mjs';
13
13
  import { l as logger } from '../shared/luca.dM-MKlNE.mjs';
14
14
  import 'zod';
15
15
  import 'node:os';
16
- import '../shared/luca.BKNzBAX6.mjs';
17
- import '../shared/luca.CbQLVJY4.mjs';
16
+ import '../shared/luca.0ssL9rcP.mjs';
17
+ import '../shared/luca.B-w_fieK.mjs';
18
18
  import 'consola';
19
19
 
20
20
  let tsModuleCache = void 0;