@alecsibilia/luca 13.0.0-alpha.7 → 13.0.0-alpha.8
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/doctor.mjs
CHANGED
|
@@ -13,6 +13,7 @@ async function executeDoctor(options = {}) {
|
|
|
13
13
|
const { legacyPackageCheck } = await import('./legacy-package.mjs');
|
|
14
14
|
const { strayLocalInstallCheck } = await import('./stray-local-install.mjs');
|
|
15
15
|
const { configVersionSkewCheck } = await import('./config-version-skew.mjs');
|
|
16
|
+
const { vaultConfigLocationCheck } = await import('./vault-config-location.mjs');
|
|
16
17
|
const allChecks = [
|
|
17
18
|
// Prerequisites
|
|
18
19
|
bunRuntimeCheck,
|
|
@@ -24,7 +25,8 @@ async function executeDoctor(options = {}) {
|
|
|
24
25
|
legacyPackageCheck,
|
|
25
26
|
// Project (cwd-dependent)
|
|
26
27
|
strayLocalInstallCheck,
|
|
27
|
-
configVersionSkewCheck
|
|
28
|
+
configVersionSkewCheck,
|
|
29
|
+
vaultConfigLocationCheck
|
|
28
30
|
];
|
|
29
31
|
const checks = scope ? allChecks.filter((check) => check.scope === scope) : allChecks;
|
|
30
32
|
if (checks.length === 0) {
|
package/dist/chunks/init.mjs
CHANGED
|
@@ -45,8 +45,12 @@ async function writeProjectSkeleton(opts) {
|
|
|
45
45
|
contents: JSON.stringify(
|
|
46
46
|
{
|
|
47
47
|
lucaVersion: LUCA_VERSION,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
oversight: "full-auto",
|
|
49
|
+
// Canonical vault location is `muninn.vault` (see
|
|
50
|
+
// resolveRepoVault + the vault-routing rule). `luca
|
|
51
|
+
// vault:init` fills this in later; the placeholder makes the
|
|
52
|
+
// canonical home discoverable in a fresh config.
|
|
53
|
+
muninn: { vault: null }
|
|
50
54
|
},
|
|
51
55
|
null,
|
|
52
56
|
2
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { writeFile, readFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const CHECK_NAME = "Vault config location";
|
|
6
|
+
function configPath() {
|
|
7
|
+
return join(process.cwd(), ".luca", "config.json");
|
|
8
|
+
}
|
|
9
|
+
async function readConfig() {
|
|
10
|
+
const p = configPath();
|
|
11
|
+
if (!existsSync(p)) return null;
|
|
12
|
+
try {
|
|
13
|
+
const raw = JSON.parse(await readFile(p, "utf-8"));
|
|
14
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : null;
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function nonEmptyTrimmed(v) {
|
|
20
|
+
if (typeof v === "string") {
|
|
21
|
+
const trimmed = v.trim();
|
|
22
|
+
if (trimmed.length > 0) return trimmed;
|
|
23
|
+
}
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
function muninnVaultOf(config) {
|
|
27
|
+
const muninn = config.muninn;
|
|
28
|
+
if (muninn && typeof muninn === "object" && !Array.isArray(muninn)) {
|
|
29
|
+
return nonEmptyTrimmed(muninn.vault);
|
|
30
|
+
}
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
const vaultConfigLocationCheck = {
|
|
34
|
+
name: CHECK_NAME,
|
|
35
|
+
scope: "project",
|
|
36
|
+
async run() {
|
|
37
|
+
const pass = (message) => ({
|
|
38
|
+
name: CHECK_NAME,
|
|
39
|
+
status: "pass",
|
|
40
|
+
message,
|
|
41
|
+
fixCommand: null,
|
|
42
|
+
details: null
|
|
43
|
+
});
|
|
44
|
+
const config = await readConfig();
|
|
45
|
+
if (config === null) {
|
|
46
|
+
return pass("no .luca/config.json to check");
|
|
47
|
+
}
|
|
48
|
+
if (!("vault" in config)) {
|
|
49
|
+
return pass("no legacy top-level vault key present");
|
|
50
|
+
}
|
|
51
|
+
const topLevel = nonEmptyTrimmed(config.vault);
|
|
52
|
+
const muninnVault = muninnVaultOf(config);
|
|
53
|
+
const wouldFold = topLevel !== void 0 && muninnVault === void 0;
|
|
54
|
+
const detail = wouldFold ? `It carries "${topLevel}" and muninn.vault is unset \u2014 \`--fix\` folds it into muninn.vault, then removes the top-level key.` : `\`--fix\` removes it (muninn.vault is the source of truth).`;
|
|
55
|
+
return {
|
|
56
|
+
name: CHECK_NAME,
|
|
57
|
+
status: "warning",
|
|
58
|
+
message: "config.json has a top-level `vault` key (canonical location is `muninn.vault`)",
|
|
59
|
+
fixCommand: "luca doctor --fix",
|
|
60
|
+
details: [
|
|
61
|
+
`.luca/config.json stores a top-level \`vault\` key. The canonical location is \`muninn.vault\`; the top-level key is only read as a legacy fallback.`,
|
|
62
|
+
detail
|
|
63
|
+
].join("\n ")
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
async fix() {
|
|
67
|
+
const config = await readConfig();
|
|
68
|
+
if (config === null || !("vault" in config)) {
|
|
69
|
+
return { applied: [], errors: [] };
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const topLevel = nonEmptyTrimmed(config.vault);
|
|
73
|
+
const muninnVault = muninnVaultOf(config);
|
|
74
|
+
const next = { ...config };
|
|
75
|
+
const applied = [];
|
|
76
|
+
if (topLevel !== void 0 && muninnVault === void 0) {
|
|
77
|
+
const existingMuninn = config.muninn && typeof config.muninn === "object" && !Array.isArray(config.muninn) ? config.muninn : {};
|
|
78
|
+
next.muninn = { ...existingMuninn, vault: topLevel };
|
|
79
|
+
applied.push(`Folded top-level vault "${topLevel}" \u2192 muninn.vault`);
|
|
80
|
+
}
|
|
81
|
+
delete next.vault;
|
|
82
|
+
applied.push("Removed stale top-level `vault` key from .luca/config.json");
|
|
83
|
+
await writeFile(configPath(), JSON.stringify(next, null, 2) + "\n");
|
|
84
|
+
return { applied, errors: [] };
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return {
|
|
87
|
+
applied: [],
|
|
88
|
+
errors: [
|
|
89
|
+
`Failed to normalize .luca/config.json vault location: ${err.message}`
|
|
90
|
+
]
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export { vaultConfigLocationCheck };
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alecsibilia/luca",
|
|
3
3
|
"description": "Luca — spec-driven agentic development workflow for Claude Code (umbrella; bundles luca-cli, luca-core, luca-tools)",
|
|
4
|
-
"version": "13.0.0-alpha.
|
|
4
|
+
"version": "13.0.0-alpha.8",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Alec Sibilia <sibilia.alec@gmail.com>",
|
|
7
7
|
"homepage": "https://github.com/asibilia/luca-framework#readme",
|