dlw-machine-setup 0.9.4 → 0.9.6
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/bin/installer.js +154 -41
- package/package.json +1 -1
package/bin/installer.js
CHANGED
|
@@ -3295,9 +3295,9 @@ ${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes4.default.cursor
|
|
|
3295
3295
|
});
|
|
3296
3296
|
|
|
3297
3297
|
// src/index.ts
|
|
3298
|
-
var
|
|
3298
|
+
var import_fs17 = require("fs");
|
|
3299
3299
|
var import_readline2 = require("readline");
|
|
3300
|
-
var
|
|
3300
|
+
var import_path17 = require("path");
|
|
3301
3301
|
|
|
3302
3302
|
// src/utils/fetch.ts
|
|
3303
3303
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
@@ -3951,6 +3951,7 @@ var Journal = class {
|
|
|
3951
3951
|
// src/steps/index.ts
|
|
3952
3952
|
var steps_exports = {};
|
|
3953
3953
|
__export(steps_exports, {
|
|
3954
|
+
buildCodeIndex: () => build_code_index_default,
|
|
3954
3955
|
fetchAbapHooks: () => fetch_abap_hooks_default,
|
|
3955
3956
|
fetchContexts: () => fetch_contexts_default,
|
|
3956
3957
|
fetchFactory: () => fetch_factory_default,
|
|
@@ -4465,20 +4466,29 @@ function runBundleV2(manifest, ctx) {
|
|
|
4465
4466
|
filesPatched: [],
|
|
4466
4467
|
markerBlockFiles: []
|
|
4467
4468
|
};
|
|
4468
|
-
const
|
|
4469
|
+
const mergePatches = /* @__PURE__ */ new Map();
|
|
4469
4470
|
for (const asset of manifest.assets ?? []) {
|
|
4470
|
-
runAsset(asset, profile,
|
|
4471
|
+
runAsset(asset, profile, mergePatches, ctx, result);
|
|
4471
4472
|
result.opsExecuted++;
|
|
4472
4473
|
}
|
|
4473
|
-
for (const [file, patch] of hookPatches) {
|
|
4474
|
-
runMergeJson({ op: "merge-json", file, patch }, manifest.name, ctx, result);
|
|
4475
|
-
}
|
|
4476
4474
|
for (const op of manifest.ops ?? []) {
|
|
4477
4475
|
if (op.when === "hooks-supported" && !profile.handlers.hook.supported) continue;
|
|
4478
4476
|
if (op.when === "statusline-supported" && !profile.statusLineSupported) continue;
|
|
4479
|
-
|
|
4477
|
+
const substituted = substituteHookDir(op, profile);
|
|
4478
|
+
if (substituted.op === "merge-json") {
|
|
4479
|
+
const existing = mergePatches.get(substituted.file);
|
|
4480
|
+
mergePatches.set(
|
|
4481
|
+
substituted.file,
|
|
4482
|
+
deepMerge2(existing ?? {}, substituted.patch)
|
|
4483
|
+
);
|
|
4484
|
+
} else {
|
|
4485
|
+
executeOp(substituted, manifest.name, ctx, result);
|
|
4486
|
+
}
|
|
4480
4487
|
result.opsExecuted++;
|
|
4481
4488
|
}
|
|
4489
|
+
for (const [file, patch] of mergePatches) {
|
|
4490
|
+
runMergeJson({ op: "merge-json", file, patch }, manifest.name, ctx, result);
|
|
4491
|
+
}
|
|
4482
4492
|
writeGitignoreBlock(manifest, ctx, result);
|
|
4483
4493
|
const snippet = result.instructionsSnippet;
|
|
4484
4494
|
if (snippet) {
|
|
@@ -5458,9 +5468,112 @@ function isClaudeCliAvailable() {
|
|
|
5458
5468
|
return check2.status === 0;
|
|
5459
5469
|
}
|
|
5460
5470
|
|
|
5461
|
-
// src/steps/setup/
|
|
5471
|
+
// src/steps/setup/build-code-index.ts
|
|
5472
|
+
var import_child_process4 = require("child_process");
|
|
5462
5473
|
var import_fs13 = require("fs");
|
|
5463
5474
|
var import_path13 = require("path");
|
|
5475
|
+
var CODE_INDEX_RELATIVE_PATH = ".claude/factory/utils/code-index";
|
|
5476
|
+
var INDEX_OUTPUT_RELATIVE_PATH = ".claude/factory/repo-index.json";
|
|
5477
|
+
var INDEX_STAMP_RELATIVE_PATH = ".claude/factory/index.stamp";
|
|
5478
|
+
var build_code_index_default = defineStep({
|
|
5479
|
+
name: "build-code-index",
|
|
5480
|
+
label: "Building code index",
|
|
5481
|
+
when: (ctx) => ctx.installed.factoryInstalled === true,
|
|
5482
|
+
execute: async (ctx) => {
|
|
5483
|
+
const codeIndexDirectory = (0, import_path13.join)(ctx.config.projectPath, CODE_INDEX_RELATIVE_PATH);
|
|
5484
|
+
if (!(0, import_fs13.existsSync)(codeIndexDirectory)) {
|
|
5485
|
+
return {
|
|
5486
|
+
status: "skipped",
|
|
5487
|
+
detail: `code-index not found at ${CODE_INDEX_RELATIVE_PATH} \u2014 older Factory release?`,
|
|
5488
|
+
record: { depsInstalled: false, indexBuilt: false }
|
|
5489
|
+
};
|
|
5490
|
+
}
|
|
5491
|
+
if (!isNodeAvailable()) {
|
|
5492
|
+
return {
|
|
5493
|
+
status: "skipped",
|
|
5494
|
+
detail: "`node` not found on PATH \u2014 run the indexer manually once node is available",
|
|
5495
|
+
record: { depsInstalled: false, indexBuilt: false }
|
|
5496
|
+
};
|
|
5497
|
+
}
|
|
5498
|
+
const npmResult = (0, import_child_process4.spawnSync)("npm install --silent --no-audit --no-fund --omit=dev", {
|
|
5499
|
+
shell: true,
|
|
5500
|
+
stdio: "pipe",
|
|
5501
|
+
encoding: "utf-8",
|
|
5502
|
+
cwd: codeIndexDirectory
|
|
5503
|
+
});
|
|
5504
|
+
const depsInstalled = npmResult.status === 0;
|
|
5505
|
+
if (!depsInstalled) {
|
|
5506
|
+
const stderrFirstLine = (npmResult.stderr ?? "").trim().split("\n")[0] || `exit ${npmResult.status}`;
|
|
5507
|
+
return {
|
|
5508
|
+
status: "failed",
|
|
5509
|
+
detail: `npm install failed: ${stderrFirstLine}`,
|
|
5510
|
+
record: { depsInstalled: false, indexBuilt: false }
|
|
5511
|
+
};
|
|
5512
|
+
}
|
|
5513
|
+
const indexerScriptPath = (0, import_path13.join)(codeIndexDirectory, "index.cjs");
|
|
5514
|
+
const indexerResult = (0, import_child_process4.spawnSync)(`node "${indexerScriptPath}" "${ctx.config.projectPath}"`, {
|
|
5515
|
+
shell: true,
|
|
5516
|
+
stdio: "pipe",
|
|
5517
|
+
encoding: "utf-8",
|
|
5518
|
+
cwd: ctx.config.projectPath
|
|
5519
|
+
});
|
|
5520
|
+
const indexBuilt = indexerResult.status === 0;
|
|
5521
|
+
if (!indexBuilt) {
|
|
5522
|
+
const stderrFirstLine = (indexerResult.stderr ?? "").trim().split("\n")[0] || `exit ${indexerResult.status}`;
|
|
5523
|
+
return {
|
|
5524
|
+
status: "success",
|
|
5525
|
+
message: "deps installed; initial index build failed (run manually)",
|
|
5526
|
+
detail: `indexer error: ${stderrFirstLine}`,
|
|
5527
|
+
record: { depsInstalled: true, indexBuilt: false }
|
|
5528
|
+
};
|
|
5529
|
+
}
|
|
5530
|
+
const lastStdoutLines = (indexerResult.stdout ?? "").trim().split("\n").slice(-5).join(" | ");
|
|
5531
|
+
return {
|
|
5532
|
+
status: "success",
|
|
5533
|
+
message: lastStdoutLines || "index built",
|
|
5534
|
+
record: { depsInstalled: true, indexBuilt: true }
|
|
5535
|
+
};
|
|
5536
|
+
},
|
|
5537
|
+
inverse: {
|
|
5538
|
+
label: "Removing code index",
|
|
5539
|
+
execute: async (raw, ctx) => {
|
|
5540
|
+
const record = raw ?? {};
|
|
5541
|
+
const projectPath = ctx.config.projectPath;
|
|
5542
|
+
const summaryActions = [];
|
|
5543
|
+
if (record.indexBuilt) {
|
|
5544
|
+
const indexFilePath = (0, import_path13.join)(projectPath, INDEX_OUTPUT_RELATIVE_PATH);
|
|
5545
|
+
if ((0, import_fs13.existsSync)(indexFilePath)) {
|
|
5546
|
+
(0, import_fs13.unlinkSync)(indexFilePath);
|
|
5547
|
+
summaryActions.push(`removed ${INDEX_OUTPUT_RELATIVE_PATH}`);
|
|
5548
|
+
}
|
|
5549
|
+
const stampFilePath = (0, import_path13.join)(projectPath, INDEX_STAMP_RELATIVE_PATH);
|
|
5550
|
+
if ((0, import_fs13.existsSync)(stampFilePath)) {
|
|
5551
|
+
(0, import_fs13.unlinkSync)(stampFilePath);
|
|
5552
|
+
summaryActions.push(`removed ${INDEX_STAMP_RELATIVE_PATH}`);
|
|
5553
|
+
}
|
|
5554
|
+
}
|
|
5555
|
+
if (record.depsInstalled) {
|
|
5556
|
+
const nodeModulesPath = (0, import_path13.join)(projectPath, CODE_INDEX_RELATIVE_PATH, "node_modules");
|
|
5557
|
+
if ((0, import_fs13.existsSync)(nodeModulesPath)) {
|
|
5558
|
+
(0, import_fs13.rmSync)(nodeModulesPath, { recursive: true, force: true });
|
|
5559
|
+
summaryActions.push("removed code-index node_modules");
|
|
5560
|
+
}
|
|
5561
|
+
}
|
|
5562
|
+
return {
|
|
5563
|
+
status: "success",
|
|
5564
|
+
message: summaryActions.length > 0 ? summaryActions.join(", ") : "nothing to remove"
|
|
5565
|
+
};
|
|
5566
|
+
}
|
|
5567
|
+
}
|
|
5568
|
+
});
|
|
5569
|
+
function isNodeAvailable() {
|
|
5570
|
+
const probeResult = (0, import_child_process4.spawnSync)("node --version", { shell: true, stdio: "ignore" });
|
|
5571
|
+
return probeResult.status === 0;
|
|
5572
|
+
}
|
|
5573
|
+
|
|
5574
|
+
// src/steps/setup/update-gitignore.ts
|
|
5575
|
+
var import_fs14 = require("fs");
|
|
5576
|
+
var import_path14 = require("path");
|
|
5464
5577
|
var MARKER_START2 = "# one-shot-installer:start";
|
|
5465
5578
|
var MARKER_END2 = "# one-shot-installer:end";
|
|
5466
5579
|
var CORE_GITIGNORE_ENTRIES = [
|
|
@@ -5481,8 +5594,8 @@ var update_gitignore_default = defineStep({
|
|
|
5481
5594
|
name: "update-gitignore",
|
|
5482
5595
|
label: "Updating .gitignore",
|
|
5483
5596
|
execute: async (ctx) => {
|
|
5484
|
-
const gitignorePath = (0,
|
|
5485
|
-
const fileExistedBefore = (0,
|
|
5597
|
+
const gitignorePath = (0, import_path14.join)(ctx.config.projectPath, ".gitignore");
|
|
5598
|
+
const fileExistedBefore = (0, import_fs14.existsSync)(gitignorePath);
|
|
5486
5599
|
upsertMarkerBlock(gitignorePath, MARKER_START2, MARKER_END2, CORE_GITIGNORE_ENTRIES.join("\n"));
|
|
5487
5600
|
const record = {
|
|
5488
5601
|
filePath: ".gitignore",
|
|
@@ -5510,8 +5623,8 @@ var update_gitignore_default = defineStep({
|
|
|
5510
5623
|
});
|
|
5511
5624
|
|
|
5512
5625
|
// src/steps/setup/write-state.ts
|
|
5513
|
-
var
|
|
5514
|
-
var
|
|
5626
|
+
var import_fs15 = require("fs");
|
|
5627
|
+
var import_path15 = require("path");
|
|
5515
5628
|
var import_os2 = require("os");
|
|
5516
5629
|
|
|
5517
5630
|
// package.json
|
|
@@ -5545,7 +5658,7 @@ var write_state_default = defineStep({
|
|
|
5545
5658
|
name: "write-state",
|
|
5546
5659
|
label: "Saving installation state",
|
|
5547
5660
|
execute: async (ctx) => {
|
|
5548
|
-
const statePath = (0,
|
|
5661
|
+
const statePath = (0, import_path15.join)(ctx.config.projectPath, ".one-shot-state.json");
|
|
5549
5662
|
const mcpServersAdded = ctx.installed.mcpServersAdded ?? [];
|
|
5550
5663
|
const filteredMcpConfig = Object.fromEntries(
|
|
5551
5664
|
Object.entries(ctx.config.mcpConfig).filter(([name]) => mcpServersAdded.includes(name))
|
|
@@ -5576,13 +5689,13 @@ var write_state_default = defineStep({
|
|
|
5576
5689
|
* mislead the uninstall preview which reads this field. */
|
|
5577
5690
|
factory: ctx.installed.factoryInstalled ? ".claude/" : null,
|
|
5578
5691
|
abapHooks: ctx.installed.abapHooksInstalled ? ".claude/hooks/" : null,
|
|
5579
|
-
globalConfig: (0,
|
|
5692
|
+
globalConfig: (0, import_path15.join)((0, import_os2.homedir)(), ".one-shot-installer")
|
|
5580
5693
|
}
|
|
5581
5694
|
};
|
|
5582
5695
|
if (ctx.journal) {
|
|
5583
5696
|
ctx.journal.setSummary(state);
|
|
5584
5697
|
} else {
|
|
5585
|
-
(0,
|
|
5698
|
+
(0, import_fs15.writeFileSync)(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
5586
5699
|
}
|
|
5587
5700
|
return { status: "success" };
|
|
5588
5701
|
},
|
|
@@ -5597,9 +5710,9 @@ var write_state_default = defineStep({
|
|
|
5597
5710
|
});
|
|
5598
5711
|
|
|
5599
5712
|
// src/uninstall.ts
|
|
5600
|
-
var
|
|
5713
|
+
var import_fs16 = require("fs");
|
|
5601
5714
|
var import_readline = require("readline");
|
|
5602
|
-
var
|
|
5715
|
+
var import_path16 = require("path");
|
|
5603
5716
|
var dim = (text) => `\x1B[2m${text}\x1B[0m`;
|
|
5604
5717
|
var yellow = (text) => `\x1B[33m${text}\x1B[0m`;
|
|
5605
5718
|
var red3 = (text) => `\x1B[31m${text}\x1B[0m`;
|
|
@@ -5619,11 +5732,11 @@ async function uninstall() {
|
|
|
5619
5732
|
try {
|
|
5620
5733
|
const projectInput = await esm_default4({
|
|
5621
5734
|
message: "Project directory to uninstall from:",
|
|
5622
|
-
default: (0,
|
|
5735
|
+
default: (0, import_path16.resolve)(process.cwd())
|
|
5623
5736
|
});
|
|
5624
|
-
const projectPath = (0,
|
|
5625
|
-
const statePath = (0,
|
|
5626
|
-
if (!(0,
|
|
5737
|
+
const projectPath = (0, import_path16.resolve)(projectInput);
|
|
5738
|
+
const statePath = (0, import_path16.join)(projectPath, ".one-shot-state.json");
|
|
5739
|
+
if (!(0, import_fs16.existsSync)(statePath)) {
|
|
5627
5740
|
console.log("");
|
|
5628
5741
|
console.log(red3(" No .one-shot-state.json found at:"));
|
|
5629
5742
|
console.log(` ${statePath}`);
|
|
@@ -5648,7 +5761,7 @@ async function uninstall() {
|
|
|
5648
5761
|
default: false
|
|
5649
5762
|
});
|
|
5650
5763
|
if (proceed2) {
|
|
5651
|
-
(0,
|
|
5764
|
+
(0, import_fs16.unlinkSync)(statePath);
|
|
5652
5765
|
console.log(" Removed .one-shot-state.json");
|
|
5653
5766
|
}
|
|
5654
5767
|
await waitForEnter();
|
|
@@ -5689,7 +5802,7 @@ async function uninstall() {
|
|
|
5689
5802
|
console.log("");
|
|
5690
5803
|
const result = await runRollback(stepList, ctx);
|
|
5691
5804
|
try {
|
|
5692
|
-
if ((0,
|
|
5805
|
+
if ((0, import_fs16.existsSync)(statePath)) (0, import_fs16.unlinkSync)(statePath);
|
|
5693
5806
|
} catch {
|
|
5694
5807
|
}
|
|
5695
5808
|
printSummary(result);
|
|
@@ -5701,7 +5814,7 @@ async function uninstall() {
|
|
|
5701
5814
|
}
|
|
5702
5815
|
function readSummary(statePath) {
|
|
5703
5816
|
try {
|
|
5704
|
-
const raw = JSON.parse((0,
|
|
5817
|
+
const raw = JSON.parse((0, import_fs16.readFileSync)(statePath, "utf-8"));
|
|
5705
5818
|
return raw;
|
|
5706
5819
|
} catch {
|
|
5707
5820
|
return {};
|
|
@@ -5782,19 +5895,19 @@ var dim2 = (text) => `\x1B[2m${text}\x1B[0m`;
|
|
|
5782
5895
|
var yellow2 = (text) => `\x1B[33m${text}\x1B[0m`;
|
|
5783
5896
|
var green2 = (text) => `\x1B[32m${text}\x1B[0m`;
|
|
5784
5897
|
function detectMarkerFileMode(filePath, markerStart) {
|
|
5785
|
-
if (!(0,
|
|
5786
|
-
const content = (0,
|
|
5898
|
+
if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
|
|
5899
|
+
const content = (0, import_fs17.readFileSync)(filePath, "utf-8");
|
|
5787
5900
|
if (content.includes(markerStart)) return yellow2("update");
|
|
5788
5901
|
return yellow2("append");
|
|
5789
5902
|
}
|
|
5790
5903
|
function detectMCPFileMode(filePath) {
|
|
5791
|
-
if (!(0,
|
|
5904
|
+
if (!(0, import_fs17.existsSync)(filePath)) return green2("create");
|
|
5792
5905
|
return yellow2("merge");
|
|
5793
5906
|
}
|
|
5794
5907
|
function detectContextMode(projectPath, domain) {
|
|
5795
|
-
const contextDir = (0,
|
|
5796
|
-
const contextDirLower = (0,
|
|
5797
|
-
if ((0,
|
|
5908
|
+
const contextDir = (0, import_path17.join)(projectPath, "_ai-context", domain.toUpperCase());
|
|
5909
|
+
const contextDirLower = (0, import_path17.join)(projectPath, "_ai-context", domain);
|
|
5910
|
+
if ((0, import_fs17.existsSync)(contextDir) || (0, import_fs17.existsSync)(contextDirLower)) return yellow2("overwrite");
|
|
5798
5911
|
return green2("create");
|
|
5799
5912
|
}
|
|
5800
5913
|
function waitForEnter2() {
|
|
@@ -5840,7 +5953,7 @@ async function main() {
|
|
|
5840
5953
|
await waitForEnter2();
|
|
5841
5954
|
return;
|
|
5842
5955
|
}
|
|
5843
|
-
const statePath = (0,
|
|
5956
|
+
const statePath = (0, import_path17.join)(config.projectPath, ".one-shot-state.json");
|
|
5844
5957
|
const journal = new Journal(statePath);
|
|
5845
5958
|
journal.startFresh();
|
|
5846
5959
|
const ctx = {
|
|
@@ -5924,7 +6037,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
|
|
|
5924
6037
|
}
|
|
5925
6038
|
const projectInput = await esm_default4({
|
|
5926
6039
|
message: "Project directory:",
|
|
5927
|
-
default: (0,
|
|
6040
|
+
default: (0, import_path17.resolve)(process.cwd())
|
|
5928
6041
|
});
|
|
5929
6042
|
const isAbapSelected = selectedTechnologies.some((t) => t.domains.includes("ABAP"));
|
|
5930
6043
|
const installAbapHooks = abapHooksAvailable && agent === "claude-code" && isAbapSelected;
|
|
@@ -5932,7 +6045,7 @@ async function collectInputs(options, releaseVersion, factoryAvailable = false,
|
|
|
5932
6045
|
technologies: selectedTechnologies,
|
|
5933
6046
|
agent,
|
|
5934
6047
|
azureDevOpsOrg,
|
|
5935
|
-
projectPath: (0,
|
|
6048
|
+
projectPath: (0, import_path17.resolve)(projectInput),
|
|
5936
6049
|
baseMcpServers: options.baseMcpServers,
|
|
5937
6050
|
mcpConfig,
|
|
5938
6051
|
releaseVersion,
|
|
@@ -5947,9 +6060,9 @@ async function previewAndConfirm(config, options) {
|
|
|
5947
6060
|
const instructionFile = target.instructions;
|
|
5948
6061
|
const mcpConfigFile = target.mcpConfig;
|
|
5949
6062
|
const serverEntries = Object.entries(config.mcpConfig);
|
|
5950
|
-
const instructionFilePath = (0,
|
|
5951
|
-
const mcpConfigFilePath = (0,
|
|
5952
|
-
const gitignorePath = (0,
|
|
6063
|
+
const instructionFilePath = (0, import_path17.join)(config.projectPath, instructionFile);
|
|
6064
|
+
const mcpConfigFilePath = (0, import_path17.join)(config.projectPath, mcpConfigFile);
|
|
6065
|
+
const gitignorePath = (0, import_path17.join)(config.projectPath, ".gitignore");
|
|
5953
6066
|
const instructionMode = detectMarkerFileMode(instructionFilePath, "<!-- one-shot-installer:start -->");
|
|
5954
6067
|
const mcpMode = detectMCPFileMode(mcpConfigFilePath);
|
|
5955
6068
|
const gitignoreMode = detectMarkerFileMode(gitignorePath, "# one-shot-installer:start");
|
|
@@ -5976,11 +6089,11 @@ async function previewAndConfirm(config, options) {
|
|
|
5976
6089
|
console.log(` ${mcpConfigFile.padEnd(domainColWidth + 14)}${mcpMode}`);
|
|
5977
6090
|
console.log(` ${".gitignore".padEnd(domainColWidth + 14)}${gitignoreMode}`);
|
|
5978
6091
|
if (config.installFactory || config.installAbapHooks) {
|
|
5979
|
-
const claudeDir = (0,
|
|
5980
|
-
const claudeMode = (0,
|
|
6092
|
+
const claudeDir = (0, import_path17.join)(config.projectPath, ".claude");
|
|
6093
|
+
const claudeMode = (0, import_fs17.existsSync)(claudeDir) ? yellow2("merge") : green2("create");
|
|
5981
6094
|
console.log(` ${".claude/".padEnd(domainColWidth + 14)}${claudeMode}`);
|
|
5982
|
-
const settingsPath = (0,
|
|
5983
|
-
const settingsMode = (0,
|
|
6095
|
+
const settingsPath = (0, import_path17.join)(config.projectPath, ".claude", "settings.json");
|
|
6096
|
+
const settingsMode = (0, import_fs17.existsSync)(settingsPath) ? yellow2("merge") : green2("create");
|
|
5984
6097
|
console.log(` ${".claude/settings.json".padEnd(domainColWidth + 14)}${settingsMode}`);
|
|
5985
6098
|
}
|
|
5986
6099
|
if (serverEntries.length > 0) {
|