oh-my-customcode 0.16.0 → 0.16.2
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/cli/index.js
CHANGED
|
@@ -9152,8 +9152,28 @@ function checkOutdated(tools) {
|
|
|
9152
9152
|
}
|
|
9153
9153
|
} catch {}
|
|
9154
9154
|
}
|
|
9155
|
+
function collectToolResults(toolNames) {
|
|
9156
|
+
const tools = [];
|
|
9157
|
+
for (const toolName of toolNames) {
|
|
9158
|
+
const tool = getToolInfo(toolName);
|
|
9159
|
+
tools.push(tool);
|
|
9160
|
+
}
|
|
9161
|
+
checkOutdated(tools);
|
|
9162
|
+
const hasUpdates = tools.some((t) => t.updateAvailable);
|
|
9163
|
+
return {
|
|
9164
|
+
tools,
|
|
9165
|
+
hasUpdates,
|
|
9166
|
+
warnings: [],
|
|
9167
|
+
skipped: false
|
|
9168
|
+
};
|
|
9169
|
+
}
|
|
9155
9170
|
async function runPreflightCheck(options = {}) {
|
|
9156
|
-
const {
|
|
9171
|
+
const {
|
|
9172
|
+
skip = false,
|
|
9173
|
+
tools: toolNames = ["claude-code"],
|
|
9174
|
+
timeout = 5000,
|
|
9175
|
+
_collectFn = collectToolResults
|
|
9176
|
+
} = options;
|
|
9157
9177
|
if (skip) {
|
|
9158
9178
|
return {
|
|
9159
9179
|
tools: [],
|
|
@@ -9181,8 +9201,8 @@ async function runPreflightCheck(options = {}) {
|
|
|
9181
9201
|
skipReason: "Homebrew not available"
|
|
9182
9202
|
};
|
|
9183
9203
|
}
|
|
9184
|
-
|
|
9185
|
-
|
|
9204
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
9205
|
+
setTimeout(() => {
|
|
9186
9206
|
resolve({
|
|
9187
9207
|
tools: [],
|
|
9188
9208
|
hasUpdates: false,
|
|
@@ -9191,34 +9211,21 @@ async function runPreflightCheck(options = {}) {
|
|
|
9191
9211
|
skipReason: "Timeout"
|
|
9192
9212
|
});
|
|
9193
9213
|
}, timeout);
|
|
9194
|
-
try {
|
|
9195
|
-
const tools = [];
|
|
9196
|
-
for (const toolName of toolNames) {
|
|
9197
|
-
const tool = getToolInfo(toolName);
|
|
9198
|
-
tools.push(tool);
|
|
9199
|
-
}
|
|
9200
|
-
checkOutdated(tools);
|
|
9201
|
-
const hasUpdates = tools.some((t) => t.updateAvailable);
|
|
9202
|
-
const warnings = [];
|
|
9203
|
-
clearTimeout(timeoutId);
|
|
9204
|
-
resolve({
|
|
9205
|
-
tools,
|
|
9206
|
-
hasUpdates,
|
|
9207
|
-
warnings,
|
|
9208
|
-
skipped: false
|
|
9209
|
-
});
|
|
9210
|
-
} catch (error) {
|
|
9211
|
-
clearTimeout(timeoutId);
|
|
9212
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
9213
|
-
resolve({
|
|
9214
|
-
tools: [],
|
|
9215
|
-
hasUpdates: false,
|
|
9216
|
-
warnings: [`Pre-flight check failed: ${errorMessage}`],
|
|
9217
|
-
skipped: true,
|
|
9218
|
-
skipReason: "Error during check"
|
|
9219
|
-
});
|
|
9220
|
-
}
|
|
9221
9214
|
});
|
|
9215
|
+
const collectPromise = (async () => {
|
|
9216
|
+
const result = await _collectFn(toolNames);
|
|
9217
|
+
return result;
|
|
9218
|
+
})().catch((error) => {
|
|
9219
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
9220
|
+
return {
|
|
9221
|
+
tools: [],
|
|
9222
|
+
hasUpdates: false,
|
|
9223
|
+
warnings: [`Pre-flight check failed: ${errorMessage}`],
|
|
9224
|
+
skipped: true,
|
|
9225
|
+
skipReason: "Error during check"
|
|
9226
|
+
};
|
|
9227
|
+
});
|
|
9228
|
+
return Promise.race([collectPromise, timeoutPromise]);
|
|
9222
9229
|
}
|
|
9223
9230
|
function formatPreflightWarnings(result) {
|
|
9224
9231
|
if (!result.hasUpdates) {
|
|
@@ -12608,7 +12615,7 @@ var $visitAsync = visit.visitAsync;
|
|
|
12608
12615
|
import { join as join3 } from "node:path";
|
|
12609
12616
|
|
|
12610
12617
|
// src/utils/fs.ts
|
|
12611
|
-
import { dirname as dirname2, isAbsolute, join as join2,
|
|
12618
|
+
import { dirname as dirname2, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
|
|
12612
12619
|
import { fileURLToPath } from "node:url";
|
|
12613
12620
|
function validatePreserveFilePath(filePath, projectRoot) {
|
|
12614
12621
|
if (!filePath || filePath.trim() === "") {
|
|
@@ -12623,19 +12630,12 @@ function validatePreserveFilePath(filePath, projectRoot) {
|
|
|
12623
12630
|
reason: "Absolute paths are not allowed"
|
|
12624
12631
|
};
|
|
12625
12632
|
}
|
|
12626
|
-
const
|
|
12627
|
-
if (normalizedPath.startsWith("..")) {
|
|
12628
|
-
return {
|
|
12629
|
-
valid: false,
|
|
12630
|
-
reason: "Path cannot traverse outside project root"
|
|
12631
|
-
};
|
|
12632
|
-
}
|
|
12633
|
-
const resolvedPath = resolve(projectRoot, normalizedPath);
|
|
12633
|
+
const resolvedPath = resolve(projectRoot, filePath);
|
|
12634
12634
|
const relativePath = relative(projectRoot, resolvedPath);
|
|
12635
12635
|
if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
|
|
12636
12636
|
return {
|
|
12637
12637
|
valid: false,
|
|
12638
|
-
reason: "
|
|
12638
|
+
reason: "Path cannot traverse outside project root"
|
|
12639
12639
|
};
|
|
12640
12640
|
}
|
|
12641
12641
|
return { valid: true };
|
|
@@ -13000,7 +13000,6 @@ function getDefaultConfig() {
|
|
|
13000
13000
|
lastUpdated: "",
|
|
13001
13001
|
installedComponents: [],
|
|
13002
13002
|
componentVersions: {},
|
|
13003
|
-
agents: {},
|
|
13004
13003
|
preferences: getDefaultPreferences(),
|
|
13005
13004
|
sourceRepo: "https://github.com/baekenough/oh-my-customcode",
|
|
13006
13005
|
autoUpdate: {
|
|
@@ -13091,10 +13090,10 @@ function mergeConfig(defaults, overrides, targetDir) {
|
|
|
13091
13090
|
...defaults.componentVersions,
|
|
13092
13091
|
...overrides.componentVersions
|
|
13093
13092
|
},
|
|
13094
|
-
agents: {
|
|
13093
|
+
agents: defaults.agents || overrides.agents ? {
|
|
13095
13094
|
...defaults.agents,
|
|
13096
13095
|
...overrides.agents
|
|
13097
|
-
},
|
|
13096
|
+
} : undefined,
|
|
13098
13097
|
preserveFiles: mergedPreserveFiles,
|
|
13099
13098
|
customComponents: overrides.customComponents ? deduplicateCustomComponents([
|
|
13100
13099
|
...defaults.customComponents || [],
|
|
@@ -13732,10 +13731,7 @@ function determineWorkflowType(hasDevelop, branchPatterns, allBranches) {
|
|
|
13732
13731
|
if (!hasDevelop && !hasFeatureBranches) {
|
|
13733
13732
|
return "trunk-based";
|
|
13734
13733
|
}
|
|
13735
|
-
|
|
13736
|
-
return "git-flow";
|
|
13737
|
-
}
|
|
13738
|
-
return "github-flow";
|
|
13734
|
+
return "git-flow";
|
|
13739
13735
|
}
|
|
13740
13736
|
function detectGitWorkflow(cwd) {
|
|
13741
13737
|
if (!isGitRepo(cwd)) {
|
|
@@ -14696,12 +14692,7 @@ async function pathExists2(targetPath) {
|
|
|
14696
14692
|
}
|
|
14697
14693
|
}
|
|
14698
14694
|
function isValidUtf8Text(content) {
|
|
14699
|
-
|
|
14700
|
-
content.toString("utf-8");
|
|
14701
|
-
return true;
|
|
14702
|
-
} catch {
|
|
14703
|
-
return false;
|
|
14704
|
-
}
|
|
14695
|
+
return !content.includes(0);
|
|
14705
14696
|
}
|
|
14706
14697
|
async function findAllFiles(dir2) {
|
|
14707
14698
|
const results = [];
|
|
@@ -15194,15 +15185,7 @@ function resolveConfigPreserveFiles(options, config) {
|
|
|
15194
15185
|
const preserveFiles = config.preserveFiles || [];
|
|
15195
15186
|
const validatedPaths = [];
|
|
15196
15187
|
for (const filePath of preserveFiles) {
|
|
15197
|
-
|
|
15198
|
-
if (validation.valid) {
|
|
15199
|
-
validatedPaths.push(filePath);
|
|
15200
|
-
} else {
|
|
15201
|
-
warn("preserve_files.invalid_path", {
|
|
15202
|
-
path: filePath,
|
|
15203
|
-
reason: validation.reason ?? "Invalid path"
|
|
15204
|
-
});
|
|
15205
|
-
}
|
|
15188
|
+
validatedPaths.push(filePath);
|
|
15206
15189
|
}
|
|
15207
15190
|
return validatedPaths;
|
|
15208
15191
|
}
|
|
@@ -15243,11 +15226,8 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
|
|
|
15243
15226
|
lastUpdated: new Date().toISOString()
|
|
15244
15227
|
};
|
|
15245
15228
|
}
|
|
15246
|
-
|
|
15247
|
-
|
|
15248
|
-
return customizations;
|
|
15249
|
-
}
|
|
15250
|
-
return null;
|
|
15229
|
+
customizations.preserveFiles = validatedManifestFiles;
|
|
15230
|
+
return customizations;
|
|
15251
15231
|
}
|
|
15252
15232
|
async function updateEntryDoc(targetDir, config, options) {
|
|
15253
15233
|
const layout = getProviderLayout();
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
5
5
|
import { join as join2 } from "node:path";
|
|
6
6
|
|
|
7
7
|
// src/utils/fs.ts
|
|
8
|
-
import { dirname, isAbsolute, join,
|
|
8
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
function validatePreserveFilePath(filePath, projectRoot) {
|
|
11
11
|
if (!filePath || filePath.trim() === "") {
|
|
@@ -20,19 +20,12 @@ function validatePreserveFilePath(filePath, projectRoot) {
|
|
|
20
20
|
reason: "Absolute paths are not allowed"
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
const
|
|
24
|
-
if (normalizedPath.startsWith("..")) {
|
|
25
|
-
return {
|
|
26
|
-
valid: false,
|
|
27
|
-
reason: "Path cannot traverse outside project root"
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
const resolvedPath = resolve(projectRoot, normalizedPath);
|
|
23
|
+
const resolvedPath = resolve(projectRoot, filePath);
|
|
31
24
|
const relativePath = relative(projectRoot, resolvedPath);
|
|
32
25
|
if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
|
|
33
26
|
return {
|
|
34
27
|
valid: false,
|
|
35
|
-
reason: "
|
|
28
|
+
reason: "Path cannot traverse outside project root"
|
|
36
29
|
};
|
|
37
30
|
}
|
|
38
31
|
return { valid: true };
|
|
@@ -388,7 +381,6 @@ function getDefaultConfig() {
|
|
|
388
381
|
lastUpdated: "",
|
|
389
382
|
installedComponents: [],
|
|
390
383
|
componentVersions: {},
|
|
391
|
-
agents: {},
|
|
392
384
|
preferences: getDefaultPreferences(),
|
|
393
385
|
sourceRepo: "https://github.com/baekenough/oh-my-customcode",
|
|
394
386
|
autoUpdate: {
|
|
@@ -479,10 +471,10 @@ function mergeConfig(defaults, overrides, targetDir) {
|
|
|
479
471
|
...defaults.componentVersions,
|
|
480
472
|
...overrides.componentVersions
|
|
481
473
|
},
|
|
482
|
-
agents: {
|
|
474
|
+
agents: defaults.agents || overrides.agents ? {
|
|
483
475
|
...defaults.agents,
|
|
484
476
|
...overrides.agents
|
|
485
|
-
},
|
|
477
|
+
} : undefined,
|
|
486
478
|
preserveFiles: mergedPreserveFiles,
|
|
487
479
|
customComponents: overrides.customComponents ? deduplicateCustomComponents([
|
|
488
480
|
...defaults.customComponents || [],
|
|
@@ -578,10 +570,7 @@ function determineWorkflowType(hasDevelop, branchPatterns, allBranches) {
|
|
|
578
570
|
if (!hasDevelop && !hasFeatureBranches) {
|
|
579
571
|
return "trunk-based";
|
|
580
572
|
}
|
|
581
|
-
|
|
582
|
-
return "git-flow";
|
|
583
|
-
}
|
|
584
|
-
return "github-flow";
|
|
573
|
+
return "git-flow";
|
|
585
574
|
}
|
|
586
575
|
function detectGitWorkflow(cwd) {
|
|
587
576
|
if (!isGitRepo(cwd)) {
|
|
@@ -1233,15 +1222,7 @@ function resolveConfigPreserveFiles(options, config) {
|
|
|
1233
1222
|
const preserveFiles = config.preserveFiles || [];
|
|
1234
1223
|
const validatedPaths = [];
|
|
1235
1224
|
for (const filePath of preserveFiles) {
|
|
1236
|
-
|
|
1237
|
-
if (validation.valid) {
|
|
1238
|
-
validatedPaths.push(filePath);
|
|
1239
|
-
} else {
|
|
1240
|
-
warn("preserve_files.invalid_path", {
|
|
1241
|
-
path: filePath,
|
|
1242
|
-
reason: validation.reason ?? "Invalid path"
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1225
|
+
validatedPaths.push(filePath);
|
|
1245
1226
|
}
|
|
1246
1227
|
return validatedPaths;
|
|
1247
1228
|
}
|
|
@@ -1282,11 +1263,8 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
|
|
|
1282
1263
|
lastUpdated: new Date().toISOString()
|
|
1283
1264
|
};
|
|
1284
1265
|
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
return customizations;
|
|
1288
|
-
}
|
|
1289
|
-
return null;
|
|
1266
|
+
customizations.preserveFiles = validatedManifestFiles;
|
|
1267
|
+
return customizations;
|
|
1290
1268
|
}
|
|
1291
1269
|
async function updateEntryDoc(targetDir, config, options) {
|
|
1292
1270
|
const layout = getProviderLayout();
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"hooks": [
|
|
8
8
|
{
|
|
9
9
|
"type": "command",
|
|
10
|
-
"command": "
|
|
10
|
+
"command": "bash .claude/hooks/scripts/stage-blocker.sh"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"description": "Block Write/Edit tools during plan/verify/compound stages — only allow in implement stage"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Stage-blocking hook: blocks Write/Edit in non-implement stages
|
|
3
|
+
if [ -f /tmp/.claude-dev-stage ]; then
|
|
4
|
+
stage=$(cat /tmp/.claude-dev-stage | tr -d '[:space:]')
|
|
5
|
+
if [ -z "$stage" ]; then exit 0; fi
|
|
6
|
+
case "$stage" in
|
|
7
|
+
plan|verify-plan|verify-impl|compound|done)
|
|
8
|
+
echo "⛔ BLOCKED: Write/Edit disabled in '$stage' stage. Only allowed during 'implement' stage. Use 'echo implement > /tmp/.claude-dev-stage' to transition."
|
|
9
|
+
exit 2
|
|
10
|
+
;;
|
|
11
|
+
esac
|
|
12
|
+
fi
|