@alecsibilia/luca 13.0.0-alpha.1 → 13.0.0-alpha.3
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/chunks/branch.mjs +6 -6
- package/dist/chunks/checks.mjs +6 -6
- package/dist/chunks/claim-verify.mjs +1 -1
- package/dist/chunks/classify.mjs +1 -1
- package/dist/chunks/confidence.mjs +6 -6
- package/dist/chunks/doctor.mjs +6 -0
- package/dist/chunks/hook.mjs +27 -9
- package/dist/chunks/init.mjs +4 -5
- package/dist/chunks/legacy-package.mjs +47 -0
- package/dist/chunks/muninn-mcp.mjs +104 -0
- package/dist/chunks/muninndb-health.mjs +1 -1
- package/dist/chunks/phase.mjs +28 -8
- package/dist/chunks/pr-review.mjs +6 -6
- package/dist/chunks/preferences.mjs +6 -6
- package/dist/chunks/repair.mjs +1 -1
- package/dist/chunks/repo.mjs +6 -6
- package/dist/chunks/retro.mjs +5 -5
- package/dist/chunks/roadmap.mjs +6 -6
- package/dist/chunks/rules.mjs +5 -5
- package/dist/chunks/stale-global-symlinks.mjs +78 -0
- package/dist/chunks/state.mjs +6 -6
- package/dist/chunks/stray-local-install.mjs +15 -7
- package/dist/chunks/telemetry.mjs +1 -1
- package/dist/chunks/todo.mjs +6 -6
- package/dist/chunks/vault-init.mjs +6 -4
- package/dist/chunks/verification.mjs +4 -4
- package/dist/chunks/workflow.mjs +6 -6
- package/dist/claude/.claude/hooks/context-refresher.ts +14047 -252
- package/dist/claude/.claude/hooks/continuation-messages.ts +14024 -190
- package/dist/claude/.claude/hooks/pipeline-guard.ts +14016 -162
- package/dist/claude/skills/caveman/SKILL.md +58 -0
- package/dist/claude/skills/lu/SKILL.md +1 -1
- package/dist/claude/skills/milestone-complete/SKILL.md +8 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/{luca.CrXzXueR.mjs → luca.BH2GZl5z.mjs} +1 -1
- package/dist/shared/{luca.B3saVjJm.mjs → luca.BHov6l1O.mjs} +25 -5
- package/dist/shared/{luca.BmhNkYe2.mjs → luca.BQXFn5yo.mjs} +2 -2
- package/dist/shared/{luca.BYdjkfnz.mjs → luca.BfjhRHhj.mjs} +1 -1
- package/dist/shared/{luca.C4gMUoBd.mjs → luca.BhM9TDAo.mjs} +3 -3
- package/dist/shared/{luca.HZxBTBgD.mjs → luca.CuvqWf4b.mjs} +2 -2
- package/dist/shared/{luca.CRmaAfXR.mjs → luca.DXUcpbIe.mjs} +5 -4
- package/dist/shared/{luca.B3Mimc0P.mjs → luca.Djs7oPPj.mjs} +5 -0
- package/dist/shared/{luca.DjDTeDCi.mjs → luca.DykMxS_D.mjs} +125 -16
- package/dist/shared/{luca.TSMg1t7I.mjs → luca.pqZahLS5.mjs} +1 -1
- package/package.json +1 -1
package/dist/chunks/branch.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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,
|
|
11
|
+
import { r as runWriteHandler, t as lucaBranchGuardTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
17
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
18
18
|
|
|
19
19
|
const guardCommand = defineCommand({
|
|
20
20
|
meta: {
|
package/dist/chunks/checks.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 {
|
|
11
|
+
import { e as readJsonPayload, r as runWriteHandler, s as lucaChecksRunTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
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.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.mjs';
|
|
4
4
|
import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
5
5
|
import 'node:fs/promises';
|
|
6
6
|
import { join } from 'node:path';
|
package/dist/chunks/classify.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
|
-
import { C as ClassifyComplexityInputSchema } from '../shared/luca.
|
|
2
|
+
import { C as ClassifyComplexityInputSchema } from '../shared/luca.DXUcpbIe.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.
|
|
3
|
-
import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.
|
|
2
|
+
import '../shared/luca.DXUcpbIe.mjs';
|
|
3
|
+
import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.BH2GZl5z.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.
|
|
11
|
+
import { b as renderConfidenceJournalMarkdown, r as readConfidenceJournal, g as getConfidenceSummary } from '../shared/luca.CuvqWf4b.mjs';
|
|
12
12
|
import { l as logger } from '../shared/luca.dM-MKlNE.mjs';
|
|
13
13
|
import 'zod';
|
|
14
|
-
import {
|
|
14
|
+
import { e as readJsonPayload, r as runWriteHandler, v as lucaConfidenceLogTool } from '../shared/luca.DykMxS_D.mjs';
|
|
15
15
|
import 'node:os';
|
|
16
|
-
import '../shared/luca.
|
|
16
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
17
17
|
import 'consola';
|
|
18
18
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
19
|
-
import '../shared/luca.
|
|
19
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
20
20
|
|
|
21
21
|
async function resolveSlug(opts) {
|
|
22
22
|
if (opts.explicit) return opts.explicit;
|
package/dist/chunks/doctor.mjs
CHANGED
|
@@ -7,7 +7,10 @@ async function executeDoctor(options = {}) {
|
|
|
7
7
|
logger.info("Running environment diagnostics...\n");
|
|
8
8
|
const { bunRuntimeCheck } = await import('./bun-runtime.mjs');
|
|
9
9
|
const { muninndbHealthCheck } = await import('./muninndb-health.mjs');
|
|
10
|
+
const { muninnMcpCheck } = await import('./muninn-mcp.mjs');
|
|
10
11
|
const { staleMcpServerCheck } = await import('./stale-mcp-server.mjs');
|
|
12
|
+
const { staleGlobalSymlinksCheck } = await import('./stale-global-symlinks.mjs');
|
|
13
|
+
const { legacyPackageCheck } = await import('./legacy-package.mjs');
|
|
11
14
|
const { strayLocalInstallCheck } = await import('./stray-local-install.mjs');
|
|
12
15
|
const allChecks = [
|
|
13
16
|
// Prerequisites
|
|
@@ -15,6 +18,9 @@ async function executeDoctor(options = {}) {
|
|
|
15
18
|
staleMcpServerCheck,
|
|
16
19
|
// Global
|
|
17
20
|
muninndbHealthCheck,
|
|
21
|
+
muninnMcpCheck,
|
|
22
|
+
staleGlobalSymlinksCheck,
|
|
23
|
+
legacyPackageCheck,
|
|
18
24
|
// Project (cwd-dependent)
|
|
19
25
|
strayLocalInstallCheck
|
|
20
26
|
];
|
package/dist/chunks/hook.mjs
CHANGED
|
@@ -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.
|
|
3
|
-
import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.
|
|
2
|
+
import { c as coarsePhaseOf, a as classifyWritePath, A as AUDIT_PATH_PATTERN, W as WAVE_FILE_RE } from '../shared/luca.DXUcpbIe.mjs';
|
|
3
|
+
import { l as loadCurrentState, r as resolveActiveSlug } from '../shared/luca.BH2GZl5z.mjs';
|
|
4
4
|
import 'node:fs';
|
|
5
5
|
import 'node:fs/promises';
|
|
6
|
-
import 'node:path';
|
|
7
|
-
import { S as STEP_ARTIFACTS } from '../shared/luca.
|
|
8
|
-
import { p as phasePathFor } from '../shared/luca.
|
|
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.pqZahLS5.mjs';
|
|
9
9
|
import 'node:crypto';
|
|
10
10
|
import 'node:module';
|
|
11
11
|
import 'node:url';
|
|
@@ -72,6 +72,13 @@ function isToolAllowed({
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const READONLY_COMMANDS = /* @__PURE__ */ new Set([
|
|
75
|
+
// Shell navigation/no-ops: mutate shell state, not files — benign for
|
|
76
|
+
// the file/repo-mutation policy this classifier enforces. `cd` is the
|
|
77
|
+
// big one: agents prefix nearly every command with `cd <dir> && …`, so
|
|
78
|
+
// omitting it made every compound command classify as a mutate.
|
|
79
|
+
"cd",
|
|
80
|
+
"pushd",
|
|
81
|
+
"popd",
|
|
75
82
|
"ls",
|
|
76
83
|
"cat",
|
|
77
84
|
"grep",
|
|
@@ -195,7 +202,7 @@ const LUCA_READ_VERBS = /* @__PURE__ */ new Set([
|
|
|
195
202
|
]);
|
|
196
203
|
const LUCA_NOUN_VERBS = {
|
|
197
204
|
state: /* @__PURE__ */ new Set(["read", "advance"]),
|
|
198
|
-
phase: /* @__PURE__ */ new Set(["current"]),
|
|
205
|
+
phase: /* @__PURE__ */ new Set(["current", "advance", "archive"]),
|
|
199
206
|
roadmap: /* @__PURE__ */ new Set(["read", "create"]),
|
|
200
207
|
preferences: /* @__PURE__ */ new Set(["read", "write"]),
|
|
201
208
|
todo: /* @__PURE__ */ new Set(["add", "list", "update"]),
|
|
@@ -212,7 +219,7 @@ const LUCA_NOUN_VERBS = {
|
|
|
212
219
|
};
|
|
213
220
|
function classifyLucaCommand(rest) {
|
|
214
221
|
const noun = rest.find((t) => !t.startsWith("-"));
|
|
215
|
-
if (!noun) return
|
|
222
|
+
if (!noun) return "bash-readonly";
|
|
216
223
|
const verbs = LUCA_NOUN_VERBS[noun];
|
|
217
224
|
if (!verbs) return void 0;
|
|
218
225
|
const afterNoun = rest.slice(rest.indexOf(noun) + 1);
|
|
@@ -358,6 +365,16 @@ function classifySubcommand(sub) {
|
|
|
358
365
|
};
|
|
359
366
|
}
|
|
360
367
|
}
|
|
368
|
+
if (cmd === "sed" || cmd === "awk") {
|
|
369
|
+
const sedInPlace = cmd === "sed" && rest.some((a) => a === "--in-place" || a.startsWith("-i"));
|
|
370
|
+
const awkInPlace = cmd === "awk" && rest.some((a, i) => a === "-i" && rest[i + 1] === "inplace");
|
|
371
|
+
if (!sedInPlace && !awkInPlace) {
|
|
372
|
+
return {
|
|
373
|
+
category: sub.redirect ? "bash-mutate" : "bash-readonly",
|
|
374
|
+
targetPaths: targetsFromRedirect
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
361
378
|
if (MUTATE_COMMANDS.has(cmd)) {
|
|
362
379
|
const lastArg = cmd === "cp" || cmd === "mv" || cmd === "ln" ? lastNonFlag(rest) : void 0;
|
|
363
380
|
const sedTarget = cmd === "sed" && rest.includes("-i") ? rest[rest.length - 1] : void 0;
|
|
@@ -494,11 +511,12 @@ async function handleStageGateHook(opts) {
|
|
|
494
511
|
log(`stage-gate: ${toolName} without file_path \u2014 allowing`);
|
|
495
512
|
return { exitCode: 0, toolName, toolInput, decision: "allow" };
|
|
496
513
|
}
|
|
497
|
-
const
|
|
514
|
+
const relTarget = isAbsolute(targetPath) ? relative(cwd, targetPath) : targetPath;
|
|
515
|
+
const pc = classifyWritePath(targetPath, { homedir, cwd });
|
|
498
516
|
if (pc.class === "denied") {
|
|
499
517
|
pathBlockReason = `${toolName} to '${targetPath}' is always denied: ${pc.reason ?? "forbidden path"}`;
|
|
500
518
|
} else if (pc.class === "planning-general" || pc.class === "planning-audit") {
|
|
501
|
-
const gate = artifactPathGate(
|
|
519
|
+
const gate = artifactPathGate(relTarget, state.pipelineStep, state);
|
|
502
520
|
if (gate.kind === "block") {
|
|
503
521
|
const msg = `stage-gate BLOCK: ${toolName} ${gate.reason} (pipelineStep=${state.pipelineStep})`;
|
|
504
522
|
log(msg);
|
package/dist/chunks/init.mjs
CHANGED
|
@@ -3,16 +3,16 @@ import { defineCommand, runMain } from 'citty';
|
|
|
3
3
|
import { existsSync, chmodSync } from 'node:fs';
|
|
4
4
|
import { mkdir, writeFile, readFile, readdir, copyFile } from 'node:fs/promises';
|
|
5
5
|
import { join, dirname, delimiter } from 'node:path';
|
|
6
|
-
import { l as lucaStateSchema } from '../shared/luca.
|
|
6
|
+
import { l as lucaStateSchema } from '../shared/luca.DXUcpbIe.mjs';
|
|
7
7
|
import 'node:crypto';
|
|
8
8
|
import 'node:module';
|
|
9
9
|
import 'node:url';
|
|
10
10
|
import 'node:child_process';
|
|
11
11
|
import { g as generateRunId } from '../shared/luca.naWEcQ4B.mjs';
|
|
12
12
|
import { LUCA_VERSION } from '../index.mjs';
|
|
13
|
-
import { d as defaultClaudeHome, r as resolveBundledArtifactsForHooks, i as installSkills } from '../shared/luca.
|
|
13
|
+
import { d as defaultClaudeHome, r as resolveBundledArtifactsForHooks, i as installSkills } from '../shared/luca.BHov6l1O.mjs';
|
|
14
14
|
import { l as logger } from '../shared/luca.dM-MKlNE.mjs';
|
|
15
|
-
import { M as MuninndbInstallResultSchema, r as resolvePlatformTarget, g as getLucaHomePaths, a as MUNINNDB_BINARY_NAME, b as getCommonBinaryPaths, c as resolveMuninndbPort, d as checkMuninndbService, e as MuninndbServiceStatusSchema, w as waitForMuninndbHealthy, f as ensureLucaHome, h as checkMuninndbBinary
|
|
15
|
+
import { M as MuninndbInstallResultSchema, r as resolvePlatformTarget, g as getLucaHomePaths, a as MUNINNDB_BINARY_NAME, b as getCommonBinaryPaths, c as resolveMuninndbPort, d as checkMuninndbService, e as MuninndbServiceStatusSchema, w as waitForMuninndbHealthy, f as ensureLucaHome, h as checkMuninndbBinary } from '../shared/luca.BfjhRHhj.mjs';
|
|
16
16
|
import { join as join$1 } from 'pathe';
|
|
17
17
|
import { c as checkPrerequisites, p as promptBunInstall } from '../shared/luca.DTomPq7I.mjs';
|
|
18
18
|
import 'zod';
|
|
@@ -689,12 +689,11 @@ const initCommand = defineCommand({
|
|
|
689
689
|
readout.push(
|
|
690
690
|
" stores them in MuninnDB; downstream pipeline modes consult them)"
|
|
691
691
|
);
|
|
692
|
-
const mcpPort = muninndbPort ?? MUNINNDB_DEFAULT_PORT;
|
|
693
692
|
readout.push(
|
|
694
693
|
" To expose MuninnDB to Claude Code: register it as an MCP server,"
|
|
695
694
|
);
|
|
696
695
|
readout.push(
|
|
697
|
-
` e.g. claude mcp add --transport
|
|
696
|
+
` e.g. claude mcp add --transport sse muninn http://localhost:8750/mcp \\`
|
|
698
697
|
);
|
|
699
698
|
readout.push(
|
|
700
699
|
' --header "Authorization: Bearer <your-muninn-api-key>"'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const CHECK_NAME = "Legacy global package";
|
|
6
|
+
const LEGACY = "@alecsibilia/luca-framework";
|
|
7
|
+
const UMBRELLA = "@alecsibilia/luca";
|
|
8
|
+
function bunGlobalNodeModules() {
|
|
9
|
+
const bunInstall = process.env.BUN_INSTALL ?? join(homedir(), ".bun");
|
|
10
|
+
return join(bunInstall, "install", "global", "node_modules");
|
|
11
|
+
}
|
|
12
|
+
function isInstalled(nodeModules, pkg) {
|
|
13
|
+
return existsSync(join(nodeModules, pkg, "package.json"));
|
|
14
|
+
}
|
|
15
|
+
const legacyPackageCheck = {
|
|
16
|
+
name: CHECK_NAME,
|
|
17
|
+
scope: "global",
|
|
18
|
+
async run() {
|
|
19
|
+
const nm = bunGlobalNodeModules();
|
|
20
|
+
const legacyInstalled = isInstalled(nm, LEGACY);
|
|
21
|
+
if (!legacyInstalled) {
|
|
22
|
+
return {
|
|
23
|
+
name: CHECK_NAME,
|
|
24
|
+
status: "pass",
|
|
25
|
+
message: `no legacy ${LEGACY} global install`,
|
|
26
|
+
fixCommand: null,
|
|
27
|
+
details: null
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const umbrellaInstalled = isInstalled(nm, UMBRELLA);
|
|
31
|
+
const conflict = umbrellaInstalled ? `Both ${UMBRELLA} and ${LEGACY} are installed globally \u2014 they provide the same \`luca\` binary, so the active one is whichever was installed last.` : `The pre-v13 ${LEGACY} is still installed globally; install ${UMBRELLA} for the v13 CLI.`;
|
|
32
|
+
const message = umbrellaInstalled ? `legacy ${LEGACY} installed globally (conflicts with ${UMBRELLA})` : `legacy ${LEGACY} still installed globally (pre-v13)`;
|
|
33
|
+
return {
|
|
34
|
+
name: CHECK_NAME,
|
|
35
|
+
status: "warning",
|
|
36
|
+
message,
|
|
37
|
+
fixCommand: `bun rm -g ${LEGACY}`,
|
|
38
|
+
details: [
|
|
39
|
+
conflict,
|
|
40
|
+
`Remove the legacy package: bun rm -g ${LEGACY}`,
|
|
41
|
+
`(reversible \u2014 \`bun add -g ${LEGACY}\` reinstalls it).`
|
|
42
|
+
].join("\n ")
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { legacyPackageCheck };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
const CHECK_NAME = "MuninnDB MCP wiring";
|
|
5
|
+
const MCP_URL = "http://127.0.0.1:8750/mcp";
|
|
6
|
+
const ADD_COMMAND = 'claude mcp add --transport sse muninn http://localhost:8750/mcp --header "Authorization: Bearer <your-muninn-api-key>"';
|
|
7
|
+
async function readJsonObject(path) {
|
|
8
|
+
try {
|
|
9
|
+
const file = Bun.file(path);
|
|
10
|
+
if (!await file.exists()) return null;
|
|
11
|
+
const parsed = JSON.parse(await file.text());
|
|
12
|
+
return parsed !== null && typeof parsed === "object" ? parsed : null;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function hasMuninnEntry(mcpServers) {
|
|
18
|
+
return mcpServers !== null && typeof mcpServers === "object" && "muninn" in mcpServers;
|
|
19
|
+
}
|
|
20
|
+
async function isMuninnRegistered(cwd) {
|
|
21
|
+
const projectMcp = await readJsonObject(join(cwd, ".mcp.json"));
|
|
22
|
+
if (hasMuninnEntry(projectMcp?.mcpServers)) return true;
|
|
23
|
+
const userConfig = await readJsonObject(join(homedir(), ".claude.json"));
|
|
24
|
+
if (hasMuninnEntry(userConfig?.mcpServers)) return true;
|
|
25
|
+
const projects = userConfig?.projects;
|
|
26
|
+
if (projects !== null && typeof projects === "object") {
|
|
27
|
+
const project = projects[cwd];
|
|
28
|
+
if (project !== null && typeof project === "object" && hasMuninnEntry(project.mcpServers)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
async function isMcpReachable() {
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch(MCP_URL, {
|
|
37
|
+
method: "GET",
|
|
38
|
+
signal: AbortSignal.timeout(2500)
|
|
39
|
+
});
|
|
40
|
+
return res.status >= 200 && res.status < 300 || res.status === 401 || res.status === 403;
|
|
41
|
+
} catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const muninnMcpCheck = {
|
|
46
|
+
name: CHECK_NAME,
|
|
47
|
+
scope: "global",
|
|
48
|
+
async run() {
|
|
49
|
+
const [reachable, registered] = await Promise.all([
|
|
50
|
+
isMcpReachable(),
|
|
51
|
+
isMuninnRegistered(process.cwd())
|
|
52
|
+
]);
|
|
53
|
+
if (reachable && registered) {
|
|
54
|
+
return {
|
|
55
|
+
name: CHECK_NAME,
|
|
56
|
+
status: "pass",
|
|
57
|
+
message: "muninn MCP registered and reachable on :8750",
|
|
58
|
+
fixCommand: null,
|
|
59
|
+
details: null
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (reachable && !registered) {
|
|
63
|
+
return {
|
|
64
|
+
name: CHECK_NAME,
|
|
65
|
+
status: "warning",
|
|
66
|
+
message: "MuninnDB MCP is up but not registered with Claude Code",
|
|
67
|
+
fixCommand: ADD_COMMAND,
|
|
68
|
+
details: [
|
|
69
|
+
"The MCP endpoint on :8750 is reachable, but no `muninn`",
|
|
70
|
+
"server is registered, so the pipeline cannot use memory.",
|
|
71
|
+
"Register it (use the key from `luca vault:init` / .env):",
|
|
72
|
+
` ${ADD_COMMAND}`
|
|
73
|
+
].join("\n ")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (!reachable && registered) {
|
|
77
|
+
return {
|
|
78
|
+
name: CHECK_NAME,
|
|
79
|
+
status: "warning",
|
|
80
|
+
message: "muninn MCP registered but endpoint unreachable on :8750",
|
|
81
|
+
fixCommand: "luca init",
|
|
82
|
+
details: [
|
|
83
|
+
"A `muninn` server is registered, but nothing is answering",
|
|
84
|
+
"on :8750. Is MuninnDB running? Start it with `luca init`",
|
|
85
|
+
"or `muninn start`, then restart Claude Code."
|
|
86
|
+
].join("\n ")
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
name: CHECK_NAME,
|
|
91
|
+
status: "warning",
|
|
92
|
+
message: "MuninnDB MCP not running and not registered (optional)",
|
|
93
|
+
fixCommand: ADD_COMMAND,
|
|
94
|
+
details: [
|
|
95
|
+
"MuninnDB provides cross-session memory for the pipeline. It is",
|
|
96
|
+
"optional, but recommended. Start it (`luca init`) and register",
|
|
97
|
+
"the MCP server:",
|
|
98
|
+
` ${ADD_COMMAND}`
|
|
99
|
+
].join("\n ")
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export { muninnMcpCheck };
|
package/dist/chunks/phase.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 } from '../shared/luca.
|
|
11
|
+
import { r as runWriteHandler, b as lucaPhaseCurrentTool, c as lucaPhaseAdvanceTool, d as lucaPhaseArchiveTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
17
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
18
18
|
|
|
19
19
|
const currentCommand = defineCommand({
|
|
20
20
|
meta: {
|
|
@@ -25,13 +25,33 @@ const currentCommand = defineCommand({
|
|
|
25
25
|
await runWriteHandler("phase current", lucaPhaseCurrentTool, {});
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
|
+
const advanceCommand = defineCommand({
|
|
29
|
+
meta: {
|
|
30
|
+
name: "advance",
|
|
31
|
+
description: "Advance the active roadmap phase by one (currentPhase \u2192 currentPhase+1), marking the completed phase done and the next in-progress. Call at the phase boundary (learn step) when more phases remain; the final phase routes to the milestone step."
|
|
32
|
+
},
|
|
33
|
+
async run() {
|
|
34
|
+
await runWriteHandler("phase advance", lucaPhaseAdvanceTool, {});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const archiveCommand = defineCommand({
|
|
38
|
+
meta: {
|
|
39
|
+
name: "archive",
|
|
40
|
+
description: "Archive all active phase directories (.luca/phases/<slug>/ \u2192 .luca/archive/<slug>/) at milestone close, so the next milestone starts from an empty phases/ dir. Idempotent; skips slugs already archived. Allowed only in the milestone/complete steps."
|
|
41
|
+
},
|
|
42
|
+
async run() {
|
|
43
|
+
await runWriteHandler("phase archive", lucaPhaseArchiveTool, {});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
28
46
|
const phaseCommand = defineCommand({
|
|
29
47
|
meta: {
|
|
30
48
|
name: "phase",
|
|
31
|
-
description: "Inspect
|
|
49
|
+
description: "Inspect, advance, and archive Luca workflow phases"
|
|
32
50
|
},
|
|
33
51
|
subCommands: {
|
|
34
|
-
current: currentCommand
|
|
52
|
+
current: currentCommand,
|
|
53
|
+
advance: advanceCommand,
|
|
54
|
+
archive: archiveCommand
|
|
35
55
|
}
|
|
36
56
|
});
|
|
37
57
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 {
|
|
11
|
+
import { e as readJsonPayload, r as runWriteHandler, n as lucaPrReviewDetectConvergenceTool, o as lucaPrReviewFilterStaleTool, p as lucaPrReviewRegressionCheckTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
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.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 {
|
|
11
|
+
import { e as readJsonPayload, r as runWriteHandler, h as lucaPreferencesReadTool, i as lucaPreferencesWriteTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
17
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
18
18
|
|
|
19
19
|
const readCommand = defineCommand({
|
|
20
20
|
meta: {
|
package/dist/chunks/repair.mjs
CHANGED
|
@@ -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.
|
|
5
|
+
import { l as lucaStateSchema } from '../shared/luca.DXUcpbIe.mjs';
|
|
6
6
|
import 'node:crypto';
|
|
7
7
|
import 'node:module';
|
|
8
8
|
import 'node:url';
|
package/dist/chunks/repo.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 {
|
|
11
|
+
import { e as readJsonPayload, r as runWriteHandler, q as lucaRepoCleanupApplyTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
17
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
18
18
|
|
|
19
19
|
const cleanupApplyCommand = defineCommand({
|
|
20
20
|
meta: {
|
package/dist/chunks/retro.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
|
-
import '../shared/luca.
|
|
2
|
+
import '../shared/luca.DXUcpbIe.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.
|
|
11
|
-
import { l as listRuns } from '../shared/luca.
|
|
10
|
+
import { a as analyzeRun, g as gatherRunArtifacts, r as renderPostmortemMarkdown, c as computePostmortemExitCode } from '../shared/luca.BhM9TDAo.mjs';
|
|
11
|
+
import { l as listRuns } from '../shared/luca.CuvqWf4b.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.
|
|
16
|
-
import '../shared/luca.
|
|
15
|
+
import '../shared/luca.BQXFn5yo.mjs';
|
|
16
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
17
17
|
import 'pathe';
|
|
18
18
|
import 'consola';
|
|
19
19
|
|
package/dist/chunks/roadmap.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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 {
|
|
11
|
+
import { e as readJsonPayload, r as runWriteHandler, f as lucaRoadmapReadTool, g as lucaRoadmapCreateTool } from '../shared/luca.DykMxS_D.mjs';
|
|
12
12
|
import 'node:os';
|
|
13
|
-
import '../shared/luca.
|
|
14
|
-
import '../shared/luca.
|
|
15
|
-
import '../shared/luca.
|
|
13
|
+
import '../shared/luca.BH2GZl5z.mjs';
|
|
14
|
+
import '../shared/luca.CuvqWf4b.mjs';
|
|
15
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
16
16
|
import '../shared/luca.CQ3g1xrD.mjs';
|
|
17
|
-
import '../shared/luca.
|
|
17
|
+
import '../shared/luca.Djs7oPPj.mjs';
|
|
18
18
|
|
|
19
19
|
const readCommand = defineCommand({
|
|
20
20
|
meta: {
|
package/dist/chunks/rules.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import { join as join$1 } from 'pathe';
|
|
3
|
-
import '../shared/luca.
|
|
3
|
+
import '../shared/luca.DXUcpbIe.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.
|
|
12
|
-
import { l as listRuns } from '../shared/luca.
|
|
11
|
+
import { a as analyzeRun, g as gatherRunArtifacts } from '../shared/luca.BhM9TDAo.mjs';
|
|
12
|
+
import { l as listRuns } from '../shared/luca.CuvqWf4b.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.
|
|
17
|
-
import '../shared/luca.
|
|
16
|
+
import '../shared/luca.BQXFn5yo.mjs';
|
|
17
|
+
import '../shared/luca.pqZahLS5.mjs';
|
|
18
18
|
import 'consola';
|
|
19
19
|
|
|
20
20
|
let tsModuleCache = void 0;
|