mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
fix(skills/understand): canonicalize isCli paths so symlinked SKILL_DIR runs main()
import.meta.url resolves through symlinks but pathToFileURL(process.argv[1]) preserves them, so extract-structure.mjs silently exited 0 without writing output when invoked via the plugin's symlinked install path — the documented Claude Code / Copilot CLI layout. Compare both sides via realpathSync and add a post-write existence assertion plus caller-side guidance in the agent. Closes #162
This commit is contained in:
@@ -64,6 +64,8 @@ node <SKILL_DIR>/extract-structure.mjs \
|
||||
|
||||
If the script exits non-zero, read stderr and report the error. Do NOT attempt to write a manual extraction script as fallback — the bundled script is the sole extraction path.
|
||||
|
||||
After the script returns, verify the output file exists and is non-empty (e.g. `test -s $PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-results-<batchIndex>.json`). Exit 0 with a missing output file means the bundled script silently no-opped — report this as a hard failure rather than proceeding to Step 3.
|
||||
|
||||
### Step 3 — Read the extraction results
|
||||
|
||||
Read `$PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-results-<batchIndex>.json`. The output format is:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { createRequire } from 'node:module';
|
||||
import { dirname, resolve, join } from 'node:path';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
// skills/understand/ -> plugin root is two dirs up
|
||||
@@ -133,6 +133,10 @@ async function main() {
|
||||
};
|
||||
|
||||
writeFileSync(outputPath, JSON.stringify(output, null, 2), 'utf-8');
|
||||
|
||||
if (!existsSync(outputPath)) {
|
||||
throw new Error(`output file missing after write: ${outputPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -302,11 +306,25 @@ export function buildResult(file, totalLines, nonEmptyLines, analysis, callGraph
|
||||
// ---------------------------------------------------------------------------
|
||||
// Run only when executed directly as a CLI; importing the module (e.g. from
|
||||
// tests) must not trigger main().
|
||||
//
|
||||
// Canonicalize both sides through realpathSync. Node ESM resolves
|
||||
// import.meta.url through symlinks but pathToFileURL(process.argv[1]) preserves
|
||||
// them, so a raw equality check silently no-ops when the script is invoked via
|
||||
// a symlinked plugin install path (the default in Claude Code / Copilot CLI
|
||||
// caches). See GitHub issue #162.
|
||||
// ---------------------------------------------------------------------------
|
||||
const isCli =
|
||||
process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
|
||||
function isCliEntry() {
|
||||
if (!process.argv[1]) return false;
|
||||
try {
|
||||
const modulePath = realpathSync(fileURLToPath(import.meta.url));
|
||||
const argvPath = realpathSync(process.argv[1]);
|
||||
return modulePath === argvPath;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCli) {
|
||||
if (isCliEntry()) {
|
||||
try {
|
||||
await main();
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user