@lumenflow/cli 3.15.0 → 3.16.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/docs-sync.js +97 -46
- package/dist/docs-sync.js.map +1 -1
- package/dist/lumenflow-upgrade.js +19 -13
- package/dist/lumenflow-upgrade.js.map +1 -1
- package/package.json +8 -8
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/dist/chunk-2D2VOCA4.js +0 -37
- package/dist/chunk-2D5KFYGX.js +0 -284
- package/dist/chunk-2GXVIN57.js +0 -14072
- package/dist/chunk-2MQ7HZWZ.js +0 -26
- package/dist/chunk-2UFQ3A3C.js +0 -643
- package/dist/chunk-3RG5ZIWI.js +0 -10
- package/dist/chunk-4N74J3UT.js +0 -15
- package/dist/chunk-5GTOXFYR.js +0 -392
- package/dist/chunk-5VY6MQMC.js +0 -240
- package/dist/chunk-67XVPMRY.js +0 -1297
- package/dist/chunk-6HO4GWJE.js +0 -164
- package/dist/chunk-6W5XHWYV.js +0 -1890
- package/dist/chunk-6X4EMYJQ.js +0 -64
- package/dist/chunk-6XYXI2NQ.js +0 -772
- package/dist/chunk-7ANSOV6Q.js +0 -285
- package/dist/chunk-A624LFLB.js +0 -1380
- package/dist/chunk-ADN5NHG4.js +0 -126
- package/dist/chunk-B7YJYJKG.js +0 -33
- package/dist/chunk-CCLHCPKG.js +0 -210
- package/dist/chunk-CK36VROC.js +0 -1584
- package/dist/chunk-D3UOFRSB.js +0 -81
- package/dist/chunk-DFR4DJBM.js +0 -230
- package/dist/chunk-DSYBDHYH.js +0 -79
- package/dist/chunk-DWMLTXKQ.js +0 -1176
- package/dist/chunk-E3REJTAJ.js +0 -28
- package/dist/chunk-EA3IVO64.js +0 -633
- package/dist/chunk-EK2AKZKD.js +0 -55
- package/dist/chunk-ELD7JTTT.js +0 -343
- package/dist/chunk-EX6TT2XI.js +0 -195
- package/dist/chunk-EXINSFZE.js +0 -82
- package/dist/chunk-EZ6ZBYBM.js +0 -510
- package/dist/chunk-FBKAPTJ2.js +0 -16
- package/dist/chunk-FVLV5RYH.js +0 -1118
- package/dist/chunk-GDNSBQVK.js +0 -2485
- package/dist/chunk-GPQHMBNN.js +0 -278
- package/dist/chunk-GTFJB67L.js +0 -68
- package/dist/chunk-HANJXVKW.js +0 -1127
- package/dist/chunk-HEVS5YLD.js +0 -269
- package/dist/chunk-HMEVZKPQ.js +0 -9
- package/dist/chunk-HRGSYNLM.js +0 -3511
- package/dist/chunk-ISZR5N4K.js +0 -60
- package/dist/chunk-J6SUPR2C.js +0 -226
- package/dist/chunk-JERYVEIZ.js +0 -244
- package/dist/chunk-JHHWGL2N.js +0 -87
- package/dist/chunk-JONWQUB5.js +0 -775
- package/dist/chunk-K2DIWWDM.js +0 -1766
- package/dist/chunk-KY4PGL5V.js +0 -969
- package/dist/chunk-L737LQ4C.js +0 -1285
- package/dist/chunk-LFTWYIB2.js +0 -497
- package/dist/chunk-LV47RFNJ.js +0 -41
- package/dist/chunk-MKSAITI7.js +0 -15
- package/dist/chunk-MZ7RKIX4.js +0 -212
- package/dist/chunk-NAP6CFSO.js +0 -84
- package/dist/chunk-ND6MY37M.js +0 -16
- package/dist/chunk-NMG736UR.js +0 -683
- package/dist/chunk-NRAXROED.js +0 -32
- package/dist/chunk-NRIZR3A7.js +0 -690
- package/dist/chunk-NX43BG3M.js +0 -233
- package/dist/chunk-O645XLSI.js +0 -297
- package/dist/chunk-OMJD6A3S.js +0 -235
- package/dist/chunk-QB6SJD4T.js +0 -430
- package/dist/chunk-QFSTL4J3.js +0 -276
- package/dist/chunk-QLGDFMFX.js +0 -212
- package/dist/chunk-RIAAGL2E.js +0 -13
- package/dist/chunk-RWO5XMZ6.js +0 -86
- package/dist/chunk-RXRKBBSM.js +0 -149
- package/dist/chunk-RZOZMML6.js +0 -363
- package/dist/chunk-U7I7FS7T.js +0 -113
- package/dist/chunk-UI42RODY.js +0 -717
- package/dist/chunk-UTVMVSCO.js +0 -519
- package/dist/chunk-V6OJGLBA.js +0 -1746
- package/dist/chunk-W2JHVH7D.js +0 -152
- package/dist/chunk-WD3Y7VQN.js +0 -280
- package/dist/chunk-WOCTQ5MS.js +0 -303
- package/dist/chunk-WZR3ZUNN.js +0 -696
- package/dist/chunk-XGI665H7.js +0 -150
- package/dist/chunk-XKY65P2T.js +0 -304
- package/dist/chunk-Y4CQZY65.js +0 -57
- package/dist/chunk-YFEXKLVE.js +0 -194
- package/dist/chunk-YHO3HS5X.js +0 -287
- package/dist/chunk-YLS7AZSX.js +0 -738
- package/dist/chunk-ZE473AO6.js +0 -49
- package/dist/chunk-ZF747T3O.js +0 -644
- package/dist/chunk-ZHCZHZH3.js +0 -43
- package/dist/chunk-ZZNZX2XY.js +0 -87
- package/dist/constants-7QAP3VQ4.js +0 -23
- package/dist/dist-IY3UUMWK.js +0 -33
- package/dist/invariants-runner-W5RGHCSU.js +0 -27
- package/dist/lane-lock-6J36HD5O.js +0 -35
- package/dist/mem-checkpoint-core-EANG2GVN.js +0 -14
- package/dist/mem-signal-core-2LZ2WYHW.js +0 -19
- package/dist/memory-store-OLB5FO7K.js +0 -18
- package/dist/service-6BYCOCO5.js +0 -13
- package/dist/spawn-policy-resolver-NTSZYQ6R.js +0 -17
- package/dist/spawn-task-builder-R4E2BHSW.js +0 -22
- package/dist/wu-done-pr-WLFFFEPJ.js +0 -25
- package/dist/wu-done-validation-3J5E36FE.js +0 -30
- package/dist/wu-duplicate-id-detector-5S7JHELK.js +0 -232
- package/packs/sidekick/.turbo/turbo-typecheck.log +0 -4
- package/packs/software-delivery/.turbo/turbo-typecheck.log +0 -4
package/dist/chunk-UTVMVSCO.js
DELETED
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
WorkspaceControlPlaneConfigSchema,
|
|
3
|
-
resolvePackManifestPaths,
|
|
4
|
-
resolvePackSchemaMetadata
|
|
5
|
-
} from "./chunk-HANJXVKW.js";
|
|
6
|
-
import {
|
|
7
|
-
runCLI,
|
|
8
|
-
withMicroWorktree
|
|
9
|
-
} from "./chunk-2GXVIN57.js";
|
|
10
|
-
import {
|
|
11
|
-
FILE_SYSTEM
|
|
12
|
-
} from "./chunk-DWMLTXKQ.js";
|
|
13
|
-
import {
|
|
14
|
-
LumenFlowConfigSchema,
|
|
15
|
-
MANAGED_ROOT_KEYS,
|
|
16
|
-
WORKSPACE_CONFIG_FILE_NAME,
|
|
17
|
-
WRITABLE_ROOT_KEYS,
|
|
18
|
-
clearConfigCache,
|
|
19
|
-
findProjectRoot,
|
|
20
|
-
normalizeConfigKeys
|
|
21
|
-
} from "./chunk-V6OJGLBA.js";
|
|
22
|
-
import {
|
|
23
|
-
ErrorCodes,
|
|
24
|
-
createError,
|
|
25
|
-
die
|
|
26
|
-
} from "./chunk-RXRKBBSM.js";
|
|
27
|
-
|
|
28
|
-
// src/config-set.ts
|
|
29
|
-
import path from "path";
|
|
30
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
31
|
-
import YAML from "yaml";
|
|
32
|
-
var LOG_PREFIX = "[config:set]";
|
|
33
|
-
var OPERATION_NAME = "config-set";
|
|
34
|
-
var ARG_KEY = "--key";
|
|
35
|
-
var ARG_VALUE = "--value";
|
|
36
|
-
var ARG_HELP = "--help";
|
|
37
|
-
var COMMIT_PREFIX = "chore: config:set";
|
|
38
|
-
var WORKSPACE_INIT_COMMAND = "pnpm workspace-init --yes";
|
|
39
|
-
var WORKSPACE_FILE_NAME = WORKSPACE_CONFIG_FILE_NAME;
|
|
40
|
-
var KNOWN_SD_SUBKEYS = [
|
|
41
|
-
"version",
|
|
42
|
-
"methodology",
|
|
43
|
-
"gates",
|
|
44
|
-
"directories",
|
|
45
|
-
"state",
|
|
46
|
-
"git",
|
|
47
|
-
"wu",
|
|
48
|
-
"memory",
|
|
49
|
-
"ui",
|
|
50
|
-
"yaml",
|
|
51
|
-
"agents",
|
|
52
|
-
"experimental",
|
|
53
|
-
"cleanup",
|
|
54
|
-
"telemetry",
|
|
55
|
-
"cloud",
|
|
56
|
-
"lanes",
|
|
57
|
-
"escalation",
|
|
58
|
-
"package_manager",
|
|
59
|
-
"test_runner",
|
|
60
|
-
"build_command"
|
|
61
|
-
];
|
|
62
|
-
var SD_PACK_ID = "software-delivery";
|
|
63
|
-
var SET_HELP_TEXT = `Usage: pnpm config:set --key <dotpath> --value <value>
|
|
64
|
-
|
|
65
|
-
Safely update ${WORKSPACE_FILE_NAME} via micro-worktree commit.
|
|
66
|
-
Keys must be fully qualified from the workspace root.
|
|
67
|
-
Validates against schema before writing.
|
|
68
|
-
|
|
69
|
-
Required:
|
|
70
|
-
${ARG_KEY} <dotpath> Config key in dot notation (fully qualified)
|
|
71
|
-
${ARG_VALUE} <value> Value to set (comma-separated for arrays)
|
|
72
|
-
|
|
73
|
-
Examples:
|
|
74
|
-
pnpm config:set --key software_delivery.methodology.testing --value test-after
|
|
75
|
-
pnpm config:set --key software_delivery.gates.minCoverage --value 85
|
|
76
|
-
pnpm config:set --key control_plane.sync_interval --value 60
|
|
77
|
-
pnpm config:set --key memory_namespace --value my-project
|
|
78
|
-
`;
|
|
79
|
-
var GET_HELP_TEXT = `Usage: pnpm config:get --key <dotpath>
|
|
80
|
-
|
|
81
|
-
Read and display a value from ${WORKSPACE_FILE_NAME}.
|
|
82
|
-
Keys must be fully qualified from the workspace root.
|
|
83
|
-
|
|
84
|
-
Required:
|
|
85
|
-
${ARG_KEY} <dotpath> Config key in dot notation (fully qualified)
|
|
86
|
-
|
|
87
|
-
Examples:
|
|
88
|
-
pnpm config:get --key software_delivery.methodology.testing
|
|
89
|
-
pnpm config:get --key software_delivery.gates.minCoverage
|
|
90
|
-
pnpm config:get --key control_plane.sync_interval
|
|
91
|
-
`;
|
|
92
|
-
function parseConfigSetArgs(argv) {
|
|
93
|
-
if (argv.includes(ARG_HELP)) {
|
|
94
|
-
console.log(SET_HELP_TEXT);
|
|
95
|
-
process.exit(0);
|
|
96
|
-
}
|
|
97
|
-
let key;
|
|
98
|
-
let value;
|
|
99
|
-
for (let i = 0; i < argv.length; i++) {
|
|
100
|
-
const arg = argv[i];
|
|
101
|
-
const next = argv[i + 1];
|
|
102
|
-
switch (arg) {
|
|
103
|
-
case ARG_KEY:
|
|
104
|
-
key = next;
|
|
105
|
-
i++;
|
|
106
|
-
break;
|
|
107
|
-
case ARG_VALUE:
|
|
108
|
-
value = next;
|
|
109
|
-
i++;
|
|
110
|
-
break;
|
|
111
|
-
default:
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (!key) {
|
|
116
|
-
throw createError(
|
|
117
|
-
ErrorCodes.INVALID_ARGUMENT,
|
|
118
|
-
`${ARG_KEY} is required. Run with ${ARG_HELP} for usage.`
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
if (value === void 0) {
|
|
122
|
-
throw createError(
|
|
123
|
-
ErrorCodes.INVALID_ARGUMENT,
|
|
124
|
-
`${ARG_VALUE} is required. Run with ${ARG_HELP} for usage.`
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
return { key, value };
|
|
128
|
-
}
|
|
129
|
-
function parseConfigGetArgs(argv) {
|
|
130
|
-
if (argv.includes(ARG_HELP)) {
|
|
131
|
-
console.log(GET_HELP_TEXT);
|
|
132
|
-
process.exit(0);
|
|
133
|
-
}
|
|
134
|
-
let key;
|
|
135
|
-
for (let i = 0; i < argv.length; i++) {
|
|
136
|
-
const arg = argv[i];
|
|
137
|
-
const next = argv[i + 1];
|
|
138
|
-
if (arg === ARG_KEY) {
|
|
139
|
-
key = next;
|
|
140
|
-
i++;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (!key) {
|
|
144
|
-
throw createError(
|
|
145
|
-
ErrorCodes.INVALID_ARGUMENT,
|
|
146
|
-
`${ARG_KEY} is required. Run with ${ARG_HELP} for usage.`
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
return { key };
|
|
150
|
-
}
|
|
151
|
-
function routeConfigKey(key, packConfigKeys) {
|
|
152
|
-
const segments = key.split(".");
|
|
153
|
-
const firstSegment = segments[0];
|
|
154
|
-
const subPath = segments.slice(1).join(".");
|
|
155
|
-
if (WRITABLE_ROOT_KEYS.has(firstSegment)) {
|
|
156
|
-
return { type: "workspace-root", rootKey: firstSegment, subPath };
|
|
157
|
-
}
|
|
158
|
-
const packId = packConfigKeys.get(firstSegment);
|
|
159
|
-
if (packId !== void 0) {
|
|
160
|
-
return { type: "pack-config", rootKey: firstSegment, subPath, packId };
|
|
161
|
-
}
|
|
162
|
-
if (firstSegment in MANAGED_ROOT_KEYS) {
|
|
163
|
-
const managedCommand = MANAGED_ROOT_KEYS[firstSegment];
|
|
164
|
-
return { type: "managed-error", rootKey: firstSegment, command: managedCommand };
|
|
165
|
-
}
|
|
166
|
-
const suggestion = buildDidYouMeanSuggestion(key, firstSegment, packConfigKeys);
|
|
167
|
-
return { type: "unknown-error", rootKey: firstSegment, suggestion };
|
|
168
|
-
}
|
|
169
|
-
function buildDidYouMeanSuggestion(fullKey, firstSegment, packConfigKeys) {
|
|
170
|
-
if (KNOWN_SD_SUBKEYS.includes(firstSegment)) {
|
|
171
|
-
for (const [configKey] of packConfigKeys) {
|
|
172
|
-
return `Did you mean "${configKey}.${fullKey}"?`;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return void 0;
|
|
176
|
-
}
|
|
177
|
-
function getConfigValue(obj, dotpath) {
|
|
178
|
-
const segments = dotpath.split(".");
|
|
179
|
-
let current = obj;
|
|
180
|
-
for (const segment of segments) {
|
|
181
|
-
if (current === null || current === void 0 || typeof current !== "object") {
|
|
182
|
-
return void 0;
|
|
183
|
-
}
|
|
184
|
-
current = current[segment];
|
|
185
|
-
}
|
|
186
|
-
return current;
|
|
187
|
-
}
|
|
188
|
-
function setNestedValue(obj, dotpath, value) {
|
|
189
|
-
const result = JSON.parse(JSON.stringify(obj));
|
|
190
|
-
const segments = dotpath.split(".");
|
|
191
|
-
let current = result;
|
|
192
|
-
for (let i = 0; i < segments.length - 1; i++) {
|
|
193
|
-
const segment = segments[i];
|
|
194
|
-
if (current[segment] === void 0 || current[segment] === null || typeof current[segment] !== "object") {
|
|
195
|
-
current[segment] = {};
|
|
196
|
-
}
|
|
197
|
-
current = current[segment];
|
|
198
|
-
}
|
|
199
|
-
const lastSegment = segments[segments.length - 1];
|
|
200
|
-
current[lastSegment] = value;
|
|
201
|
-
return result;
|
|
202
|
-
}
|
|
203
|
-
function isNumericString(value) {
|
|
204
|
-
if (value === "" || value.trim() !== value) return false;
|
|
205
|
-
const num = Number(value);
|
|
206
|
-
return !isNaN(num) && isFinite(num);
|
|
207
|
-
}
|
|
208
|
-
function coerceValue(value, existingValue) {
|
|
209
|
-
if (value === "true") return true;
|
|
210
|
-
if (value === "false") return false;
|
|
211
|
-
if (typeof existingValue === "number" || isNumericString(value)) {
|
|
212
|
-
const numValue = Number(value);
|
|
213
|
-
if (!isNaN(numValue)) return numValue;
|
|
214
|
-
}
|
|
215
|
-
if (Array.isArray(existingValue)) {
|
|
216
|
-
const newItems = value.split(",").map((s) => s.trim());
|
|
217
|
-
return [...existingValue, ...newItems];
|
|
218
|
-
}
|
|
219
|
-
return value;
|
|
220
|
-
}
|
|
221
|
-
function findStrippedKeys(input, parsed, prefix = "") {
|
|
222
|
-
const stripped = [];
|
|
223
|
-
for (const key of Object.keys(input)) {
|
|
224
|
-
const fullPath = prefix ? `${prefix}.${key}` : key;
|
|
225
|
-
if (!(key in parsed)) {
|
|
226
|
-
stripped.push(fullPath);
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
const inputVal = input[key];
|
|
230
|
-
const parsedVal = parsed[key];
|
|
231
|
-
if (inputVal !== null && inputVal !== void 0 && typeof inputVal === "object" && !Array.isArray(inputVal) && parsedVal !== null && parsedVal !== void 0 && typeof parsedVal === "object" && !Array.isArray(parsedVal)) {
|
|
232
|
-
stripped.push(
|
|
233
|
-
...findStrippedKeys(
|
|
234
|
-
inputVal,
|
|
235
|
-
parsedVal,
|
|
236
|
-
fullPath
|
|
237
|
-
)
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return stripped;
|
|
242
|
-
}
|
|
243
|
-
function applyConfigSet(workspace, key, rawValue, packConfigKeys, packSchemaOpts) {
|
|
244
|
-
const route = routeConfigKey(key, packConfigKeys);
|
|
245
|
-
switch (route.type) {
|
|
246
|
-
case "managed-error":
|
|
247
|
-
return {
|
|
248
|
-
ok: false,
|
|
249
|
-
error: `Key "${route.rootKey}" is managed by a dedicated command. Use \`pnpm ${route.command}\` instead.`
|
|
250
|
-
};
|
|
251
|
-
case "unknown-error": {
|
|
252
|
-
const hint = route.suggestion ? ` ${route.suggestion}` : "";
|
|
253
|
-
return {
|
|
254
|
-
ok: false,
|
|
255
|
-
error: `Unknown root key "${route.rootKey}".${hint} Valid root keys: ${[...WRITABLE_ROOT_KEYS].join(", ")}, or a pack config_key (${[...packConfigKeys.keys()].join(", ")}).`
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
case "workspace-root":
|
|
259
|
-
return applyWorkspaceRootSet(workspace, key, rawValue);
|
|
260
|
-
case "pack-config":
|
|
261
|
-
return applyPackConfigSet(workspace, route, rawValue, packSchemaOpts);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
var SCALAR_ROOT_KEYS = /* @__PURE__ */ new Set(["memory_namespace", "event_namespace"]);
|
|
265
|
-
function applyWorkspaceRootSet(workspace, key, rawValue) {
|
|
266
|
-
const segments = key.split(".");
|
|
267
|
-
const rootKey = segments[0];
|
|
268
|
-
const subPath = segments.slice(1).join(".");
|
|
269
|
-
if (SCALAR_ROOT_KEYS.has(rootKey)) {
|
|
270
|
-
if (subPath) {
|
|
271
|
-
return {
|
|
272
|
-
ok: false,
|
|
273
|
-
error: `"${rootKey}" is a scalar value and does not support sub-path writes. Use: config:set --key ${rootKey} --value <string>`
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
return { ok: true, config: setNestedValue(workspace, key, rawValue) };
|
|
277
|
-
}
|
|
278
|
-
if (rootKey === "control_plane") {
|
|
279
|
-
if (!subPath) {
|
|
280
|
-
return {
|
|
281
|
-
ok: false,
|
|
282
|
-
error: `Cannot overwrite "control_plane" with a scalar value. Set individual sub-keys instead (e.g., control_plane.sync_interval).`
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
const existingCP = workspace.control_plane;
|
|
286
|
-
const cpConfig = existingCP && typeof existingCP === "object" && !Array.isArray(existingCP) ? JSON.parse(JSON.stringify(existingCP)) : {};
|
|
287
|
-
const existingValue2 = getConfigValue(cpConfig, subPath);
|
|
288
|
-
const coercedValue2 = coerceValue(rawValue, existingValue2);
|
|
289
|
-
const updatedCP = setNestedValue(cpConfig, subPath, coercedValue2);
|
|
290
|
-
const parseResult = WorkspaceControlPlaneConfigSchema.partial().strict().safeParse(updatedCP);
|
|
291
|
-
if (!parseResult.success) {
|
|
292
|
-
const issues = parseResult.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
293
|
-
return {
|
|
294
|
-
ok: false,
|
|
295
|
-
error: `Validation failed for ${key}=${rawValue}: ${issues}`
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
const updatedWorkspace2 = { ...workspace, control_plane: updatedCP };
|
|
299
|
-
return { ok: true, config: updatedWorkspace2 };
|
|
300
|
-
}
|
|
301
|
-
const existingValue = getConfigValue(workspace, key);
|
|
302
|
-
const coercedValue = coerceValue(rawValue, existingValue);
|
|
303
|
-
const updatedWorkspace = setNestedValue(workspace, key, coercedValue);
|
|
304
|
-
return { ok: true, config: updatedWorkspace };
|
|
305
|
-
}
|
|
306
|
-
function validateJsonSchemaPath(schema, dotpath) {
|
|
307
|
-
const segments = dotpath.split(".");
|
|
308
|
-
let currentSchema = schema;
|
|
309
|
-
const unrecognized = [];
|
|
310
|
-
for (let i = 0; i < segments.length; i++) {
|
|
311
|
-
const segment = segments[i];
|
|
312
|
-
const properties = currentSchema.properties;
|
|
313
|
-
if (!properties || !(segment in properties)) {
|
|
314
|
-
unrecognized.push(segments.slice(0, i + 1).join("."));
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
currentSchema = properties[segment];
|
|
318
|
-
}
|
|
319
|
-
return unrecognized;
|
|
320
|
-
}
|
|
321
|
-
function applyPackConfigSet(workspace, route, rawValue, packSchemaOpts) {
|
|
322
|
-
const packSection = workspace[route.rootKey];
|
|
323
|
-
const packConfig = packSection && typeof packSection === "object" && !Array.isArray(packSection) ? packSection : {};
|
|
324
|
-
if (!route.subPath) {
|
|
325
|
-
return {
|
|
326
|
-
ok: false,
|
|
327
|
-
error: `Key must target a nested field under ${route.rootKey} (e.g., ${route.rootKey}.methodology.testing).`
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
const existingValue = getConfigValue(packConfig, route.subPath);
|
|
331
|
-
const coercedValue = coerceValue(rawValue, existingValue);
|
|
332
|
-
const updatedPackConfig = setNestedValue(packConfig, route.subPath, coercedValue);
|
|
333
|
-
if (route.packId === SD_PACK_ID || !packSchemaOpts) {
|
|
334
|
-
return applyPackConfigSetWithZod(workspace, route, rawValue, updatedPackConfig);
|
|
335
|
-
}
|
|
336
|
-
const hasSchema = packSchemaOpts.packSchemaMap.get(route.packId);
|
|
337
|
-
if (!hasSchema) {
|
|
338
|
-
return {
|
|
339
|
-
ok: false,
|
|
340
|
-
error: `Pack "${route.packId}" declares no config_schema. Config writes to "${route.rootKey}" are rejected because the pack has not declared a schema for validation.`
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
const jsonSchema = packSchemaOpts.jsonSchemas.get(route.packId);
|
|
344
|
-
if (!jsonSchema) {
|
|
345
|
-
return {
|
|
346
|
-
ok: false,
|
|
347
|
-
error: `Pack "${route.packId}" declares a config_schema but the schema could not be loaded. Config writes to "${route.rootKey}" are rejected.`
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
return applyPackConfigSetWithJsonSchema(workspace, route, updatedPackConfig, jsonSchema);
|
|
351
|
-
}
|
|
352
|
-
function applyPackConfigSetWithZod(workspace, route, rawValue, updatedPackConfig) {
|
|
353
|
-
const normalized = normalizeConfigKeys(updatedPackConfig);
|
|
354
|
-
const parseResult = LumenFlowConfigSchema.safeParse(normalized);
|
|
355
|
-
if (!parseResult.success) {
|
|
356
|
-
const issues = parseResult.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
357
|
-
return {
|
|
358
|
-
ok: false,
|
|
359
|
-
error: `Validation failed for ${route.rootKey}.${route.subPath}=${rawValue}: ${issues}`
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
const parsedData = parseResult.data;
|
|
363
|
-
const writeTargetKey = route.subPath.split(".")[0];
|
|
364
|
-
let strippedKeys;
|
|
365
|
-
if (writeTargetKey && typeof normalized[writeTargetKey] === "object" && normalized[writeTargetKey] !== null && !Array.isArray(normalized[writeTargetKey]) && typeof parsedData[writeTargetKey] === "object" && parsedData[writeTargetKey] !== null && !Array.isArray(parsedData[writeTargetKey])) {
|
|
366
|
-
strippedKeys = findStrippedKeys(
|
|
367
|
-
normalized[writeTargetKey],
|
|
368
|
-
parsedData[writeTargetKey],
|
|
369
|
-
writeTargetKey
|
|
370
|
-
);
|
|
371
|
-
} else {
|
|
372
|
-
strippedKeys = writeTargetKey && writeTargetKey in normalized && !(writeTargetKey in parsedData) ? [writeTargetKey] : [];
|
|
373
|
-
}
|
|
374
|
-
if (strippedKeys.length > 0) {
|
|
375
|
-
return {
|
|
376
|
-
ok: false,
|
|
377
|
-
error: `Unknown config key(s) rejected: ${strippedKeys.join(", ")}. These keys are not recognized by the ${route.rootKey} schema.`
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
const updatedWorkspace = {
|
|
381
|
-
...workspace,
|
|
382
|
-
[route.rootKey]: updatedPackConfig
|
|
383
|
-
};
|
|
384
|
-
return { ok: true, config: updatedWorkspace };
|
|
385
|
-
}
|
|
386
|
-
function applyPackConfigSetWithJsonSchema(workspace, route, updatedPackConfig, jsonSchema) {
|
|
387
|
-
const unrecognized = validateJsonSchemaPath(jsonSchema, route.subPath);
|
|
388
|
-
if (unrecognized.length > 0) {
|
|
389
|
-
return {
|
|
390
|
-
ok: false,
|
|
391
|
-
error: `Unknown config key(s) rejected for pack "${route.packId}": ${unrecognized.join(", ")}. These keys are not recognized by the ${route.rootKey} schema.`
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
const updatedWorkspace = {
|
|
395
|
-
...workspace,
|
|
396
|
-
[route.rootKey]: updatedPackConfig
|
|
397
|
-
};
|
|
398
|
-
return { ok: true, config: updatedWorkspace };
|
|
399
|
-
}
|
|
400
|
-
function readRawWorkspace(workspacePath) {
|
|
401
|
-
const content = readFileSync(workspacePath, FILE_SYSTEM.UTF8);
|
|
402
|
-
const parsed = YAML.parse(content);
|
|
403
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
404
|
-
}
|
|
405
|
-
function writeRawWorkspace(workspacePath, workspace) {
|
|
406
|
-
const nextContent = YAML.stringify(workspace);
|
|
407
|
-
writeFileSync(workspacePath, nextContent, FILE_SYSTEM.UTF8);
|
|
408
|
-
}
|
|
409
|
-
function loadPackConfigKeys(projectRoot, workspace) {
|
|
410
|
-
const packs = workspace.packs;
|
|
411
|
-
if (!Array.isArray(packs)) {
|
|
412
|
-
return /* @__PURE__ */ new Map();
|
|
413
|
-
}
|
|
414
|
-
return resolvePackManifestPaths({ projectRoot, packs });
|
|
415
|
-
}
|
|
416
|
-
function loadPackSchemaOpts(projectRoot, workspace) {
|
|
417
|
-
const packs = workspace.packs;
|
|
418
|
-
const packSchemaMap = /* @__PURE__ */ new Map();
|
|
419
|
-
const jsonSchemas = /* @__PURE__ */ new Map();
|
|
420
|
-
if (!Array.isArray(packs)) {
|
|
421
|
-
return { packSchemaMap, jsonSchemas };
|
|
422
|
-
}
|
|
423
|
-
packSchemaMap.set(SD_PACK_ID, true);
|
|
424
|
-
const schemaMetadata = resolvePackSchemaMetadata({ projectRoot, packs });
|
|
425
|
-
for (const [packId, meta] of schemaMetadata) {
|
|
426
|
-
if (packId === SD_PACK_ID) {
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
if (meta.hasSchema && meta.schemaPath) {
|
|
430
|
-
packSchemaMap.set(packId, true);
|
|
431
|
-
if (existsSync(meta.schemaPath)) {
|
|
432
|
-
try {
|
|
433
|
-
const schemaContent = readFileSync(meta.schemaPath, "utf8");
|
|
434
|
-
const parsed = JSON.parse(schemaContent);
|
|
435
|
-
jsonSchemas.set(packId, parsed);
|
|
436
|
-
} catch {
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
} else {
|
|
440
|
-
packSchemaMap.set(packId, false);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return { packSchemaMap, jsonSchemas };
|
|
444
|
-
}
|
|
445
|
-
async function main() {
|
|
446
|
-
const userArgs = process.argv.slice(2);
|
|
447
|
-
const options = parseConfigSetArgs(userArgs);
|
|
448
|
-
const projectRoot = findProjectRoot();
|
|
449
|
-
const workspacePath = path.join(projectRoot, WORKSPACE_FILE_NAME);
|
|
450
|
-
if (!existsSync(workspacePath)) {
|
|
451
|
-
die(`${LOG_PREFIX} Missing ${WORKSPACE_FILE_NAME}. Run \`${WORKSPACE_INIT_COMMAND}\` first.`);
|
|
452
|
-
}
|
|
453
|
-
const rawWorkspace = readRawWorkspace(workspacePath);
|
|
454
|
-
const packConfigKeys = loadPackConfigKeys(projectRoot, rawWorkspace);
|
|
455
|
-
const route = routeConfigKey(options.key, packConfigKeys);
|
|
456
|
-
if (route.type === "managed-error") {
|
|
457
|
-
die(
|
|
458
|
-
`${LOG_PREFIX} Key "${route.rootKey}" is managed by a dedicated command. Use \`pnpm ${route.command}\` instead.`
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
if (route.type === "unknown-error") {
|
|
462
|
-
const hint = route.suggestion ? ` ${route.suggestion}` : "";
|
|
463
|
-
die(
|
|
464
|
-
`${LOG_PREFIX} Unknown root key "${route.rootKey}".${hint} Valid root keys: ${[...WRITABLE_ROOT_KEYS].join(", ")}, or a pack config_key (${[...packConfigKeys.keys()].join(", ")}).`
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
console.log(
|
|
468
|
-
`${LOG_PREFIX} Setting ${options.key}=${options.value} in ${WORKSPACE_FILE_NAME} via micro-worktree isolation`
|
|
469
|
-
);
|
|
470
|
-
await withMicroWorktree({
|
|
471
|
-
operation: OPERATION_NAME,
|
|
472
|
-
id: `config-set-${Date.now()}`,
|
|
473
|
-
logPrefix: LOG_PREFIX,
|
|
474
|
-
pushOnly: true,
|
|
475
|
-
async execute({ worktreePath }) {
|
|
476
|
-
const workspaceRelPath = WORKSPACE_FILE_NAME;
|
|
477
|
-
const mwWorkspacePath = path.join(worktreePath, workspaceRelPath);
|
|
478
|
-
if (!existsSync(mwWorkspacePath)) {
|
|
479
|
-
die(`${LOG_PREFIX} Config file not found in micro-worktree: ${workspaceRelPath}`);
|
|
480
|
-
}
|
|
481
|
-
const workspace = readRawWorkspace(mwWorkspacePath);
|
|
482
|
-
const mwPackConfigKeys = loadPackConfigKeys(worktreePath, workspace);
|
|
483
|
-
const mwPackSchemaOpts = loadPackSchemaOpts(worktreePath, workspace);
|
|
484
|
-
const result = applyConfigSet(
|
|
485
|
-
workspace,
|
|
486
|
-
options.key,
|
|
487
|
-
options.value,
|
|
488
|
-
mwPackConfigKeys,
|
|
489
|
-
mwPackSchemaOpts
|
|
490
|
-
);
|
|
491
|
-
if (!result.ok) {
|
|
492
|
-
die(`${LOG_PREFIX} ${result.error}`);
|
|
493
|
-
}
|
|
494
|
-
writeRawWorkspace(mwWorkspacePath, result.config);
|
|
495
|
-
console.log(`${LOG_PREFIX} Config validated and written successfully.`);
|
|
496
|
-
return {
|
|
497
|
-
commitMessage: `${COMMIT_PREFIX} ${options.key}=${options.value}`,
|
|
498
|
-
files: [workspaceRelPath]
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
clearConfigCache();
|
|
503
|
-
console.log(`${LOG_PREFIX} Successfully set ${options.key}=${options.value}`);
|
|
504
|
-
}
|
|
505
|
-
if (import.meta.main) {
|
|
506
|
-
void runCLI(main);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
export {
|
|
510
|
-
WORKSPACE_FILE_NAME,
|
|
511
|
-
parseConfigSetArgs,
|
|
512
|
-
parseConfigGetArgs,
|
|
513
|
-
routeConfigKey,
|
|
514
|
-
getConfigValue,
|
|
515
|
-
applyConfigSet,
|
|
516
|
-
loadPackConfigKeys,
|
|
517
|
-
loadPackSchemaOpts,
|
|
518
|
-
main
|
|
519
|
-
};
|