@unerr-ai/unerr 0.1.8 → 0.1.9

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.
Files changed (2) hide show
  1. package/dist/cli.js +115 -18
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -10780,6 +10780,7 @@ var init_protocol = __esm({
10780
10780
  var registry_exports = {};
10781
10781
  __export(registry_exports, {
10782
10782
  addRepo: () => addRepo,
10783
+ clearNeedsInputKey: () => clearNeedsInputKey,
10783
10784
  deriveLabel: () => deriveLabel,
10784
10785
  detectChildConflicts: () => detectChildConflicts,
10785
10786
  detectParentConflict: () => detectParentConflict,
@@ -10950,6 +10951,13 @@ function writeNeedsInput(repoPath, signals) {
10950
10951
  `
10951
10952
  );
10952
10953
  }
10954
+ function clearNeedsInputKey(repoPath, key) {
10955
+ const existing = readNeedsInput(repoPath);
10956
+ if (existing.length === 0) return;
10957
+ const remaining = existing.filter((s) => s.key !== key);
10958
+ if (remaining.length === existing.length) return;
10959
+ writeNeedsInput(repoPath, remaining);
10960
+ }
10953
10961
  function buildSettings(partial) {
10954
10962
  const s = {};
10955
10963
  for (const [k, v] of Object.entries(partial)) {
@@ -11037,6 +11045,7 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
11037
11045
  const outputDir = join29(projectRoot, ".unerr", "scip");
11038
11046
  const binaryPath = binaryInfo.path ?? binaryInfo.binaryName;
11039
11047
  let extraArgs;
11048
+ let javaPlan = null;
11040
11049
  if (language === "typescript") {
11041
11050
  if (!existsSync25(join29(projectRoot, "tsconfig.json")) && !existsSync25(join29(projectRoot, "jsconfig.json"))) {
11042
11051
  log6.info(
@@ -11046,9 +11055,12 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
11046
11055
  }
11047
11056
  }
11048
11057
  if (language === "java") {
11049
- const buildToolResult = await resolveJavaBuildTool(projectRoot, options);
11050
- if (buildToolResult) {
11051
- extraArgs = buildToolResult.extraArgs;
11058
+ javaPlan = await resolveJavaBuildTool(projectRoot, options);
11059
+ if (!javaPlan) {
11060
+ log6.info(
11061
+ "SCIP skipping java: no recognized build tool (Maven/Gradle/Bazel/Sbt) detected"
11062
+ );
11063
+ continue;
11052
11064
  }
11053
11065
  }
11054
11066
  if (language === "cpp") {
@@ -11065,7 +11077,13 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
11065
11077
  log6.info(
11066
11078
  `SCIP enrichment: ${language} (${binaryInfo.bundled ? "bundled" : "external"}: ${binaryInfo.binaryName})`
11067
11079
  );
11068
- const runResult = await runScipIndexer({
11080
+ const runResult = language === "java" && javaPlan ? await runJavaScipWithCascade({
11081
+ binaryPath,
11082
+ projectRoot,
11083
+ outputDir,
11084
+ timeoutMs: 3e4,
11085
+ plan: javaPlan
11086
+ }) : await runScipIndexer({
11069
11087
  language,
11070
11088
  binaryPath,
11071
11089
  projectRoot,
@@ -11226,29 +11244,106 @@ async function resolveJavaBuildTool(projectRoot, _options) {
11226
11244
  const stored = getStoredBuildTool(projectRoot);
11227
11245
  if (stored && detected.includes(stored)) {
11228
11246
  log6.info(`Java build tool: ${stored} (from config)`);
11229
- return { tool: stored, extraArgs: [`--build-tool=${stored}`] };
11247
+ return {
11248
+ primary: stored,
11249
+ alternatives: [],
11250
+ reason: "from config",
11251
+ ambiguous: false,
11252
+ fromConfig: true
11253
+ };
11230
11254
  }
11231
11255
  const choice = chooseBuildTool(detected, projectRoot);
11232
11256
  if (!choice) return null;
11233
- storeBuildTool(projectRoot, choice.tool);
11234
11257
  if (choice.ambiguous) {
11235
- const signal = {
11236
- type: "needs_input",
11237
- key: "javaBuildTool",
11238
- auto: choice.tool,
11239
- alternatives: choice.alternatives,
11240
- reason: choice.reason
11241
- };
11242
- writeNeedsInput(projectRoot, [signal]);
11243
11258
  log6.info(
11244
- `Java build tool: ${choice.tool} (auto: ${choice.reason}). Override: unerr pm config . --java-build-tool=<tool>`
11259
+ `Java build tool: ${choice.tool} (auto: ${choice.reason}; fallbacks: ${choice.alternatives.join(", ")})`
11245
11260
  );
11246
11261
  } else {
11247
11262
  log6.info(`Java build tool: ${choice.tool} (${choice.reason})`);
11248
11263
  }
11249
11264
  return {
11250
- tool: choice.tool,
11251
- extraArgs: [`--build-tool=${choice.tool}`]
11265
+ primary: choice.tool,
11266
+ alternatives: choice.alternatives,
11267
+ reason: choice.reason,
11268
+ ambiguous: choice.ambiguous,
11269
+ fromConfig: false
11270
+ };
11271
+ }
11272
+ function parseScipJavaBuildToolMismatch(error) {
11273
+ if (!error) return [];
11274
+ const match = error.match(
11275
+ /Automatically detected the build tool\(s\) ([^.]+?) but none of them match/i
11276
+ );
11277
+ if (!match?.[1]) return [];
11278
+ const known = new Set(JAVA_BUILD_TOOLS);
11279
+ return match[1].split(/[,\s]+/).map((s) => s.trim()).filter((s) => known.has(s));
11280
+ }
11281
+ async function runJavaScipWithCascade(opts) {
11282
+ const candidates = [
11283
+ opts.plan.primary,
11284
+ ...opts.plan.alternatives
11285
+ ];
11286
+ const attempted = [];
11287
+ let lastResult = null;
11288
+ for (let i = 0; i < candidates.length; i++) {
11289
+ const tool = candidates[i];
11290
+ attempted.push(tool);
11291
+ if (i === 0) {
11292
+ log6.info(`scip-java attempting --build-tool=${tool}`);
11293
+ } else {
11294
+ log6.info(
11295
+ `scip-java retrying --build-tool=${tool} (fallback #${i}, after ${attempted.slice(0, -1).join(" \u2192 ")})`
11296
+ );
11297
+ }
11298
+ const result = await runScipIndexer({
11299
+ language: "java",
11300
+ binaryPath: opts.binaryPath,
11301
+ projectRoot: opts.projectRoot,
11302
+ outputDir: opts.outputDir,
11303
+ timeoutMs: opts.timeoutMs,
11304
+ extraArgs: [`--build-tool=${tool}`]
11305
+ });
11306
+ lastResult = result;
11307
+ if (result.success) {
11308
+ storeBuildTool(opts.projectRoot, tool);
11309
+ clearNeedsInputKey(opts.projectRoot, "javaBuildTool");
11310
+ if (attempted.length > 1) {
11311
+ log6.info(
11312
+ `scip-java cascade resolved: ${tool} (${attempted.join(" \u2192 ")})`
11313
+ );
11314
+ }
11315
+ return result;
11316
+ }
11317
+ const detectedByScip = parseScipJavaBuildToolMismatch(result.error);
11318
+ if (detectedByScip.length === 0) {
11319
+ return result;
11320
+ }
11321
+ const detectedSet = new Set(detectedByScip);
11322
+ const remaining = candidates.slice(i + 1).filter((t) => detectedSet.has(t) && !attempted.includes(t));
11323
+ if (remaining.length === 0) {
11324
+ log6.warn(
11325
+ `scip-java cascade exhausted: tried ${attempted.join(" \u2192 ")}; scip-java detected ${detectedByScip.join(", ")} but no viable fallback remains`
11326
+ );
11327
+ const signal = {
11328
+ type: "needs_input",
11329
+ key: "javaBuildTool",
11330
+ auto: opts.plan.primary,
11331
+ alternatives: opts.plan.alternatives,
11332
+ reason: `cascade exhausted (tried ${attempted.join(" \u2192 ")}); override with unerr pm config <repo> --java-build-tool=<tool>`
11333
+ };
11334
+ writeNeedsInput(opts.projectRoot, [signal]);
11335
+ return result;
11336
+ }
11337
+ candidates.splice(i + 1, candidates.length - i - 1, ...remaining);
11338
+ log6.warn(
11339
+ `scip-java rejected --build-tool=${tool} (scip-java detected: ${detectedByScip.join(", ")}); cascading to ${candidates[i + 1]}`
11340
+ );
11341
+ }
11342
+ return lastResult ?? {
11343
+ success: false,
11344
+ outputPath: null,
11345
+ durationMs: 0,
11346
+ error: "no Java build tool candidates available"
11252
11347
  };
11253
11348
  }
11254
11349
  function resolveCompileCommandsJson(projectRoot) {
@@ -11333,6 +11428,7 @@ var init_orchestrator = __esm({
11333
11428
  init_downloader();
11334
11429
  init_merger();
11335
11430
  init_runner();
11431
+ init_protocol();
11336
11432
  init_registry();
11337
11433
  log6 = createModuleLogger("scip-orchestrator");
11338
11434
  BUILD_TOOL_FILES = {
@@ -14874,7 +14970,7 @@ function installFileLogger(opts) {
14874
14970
  bytesWritten = statSync9(filePath).size;
14875
14971
  } catch {
14876
14972
  }
14877
- const linePrefix = usePrefix ? `[pid=${process.pid} sid=${getOrCreateSid()}] ` : "";
14973
+ const idSuffix = usePrefix ? ` pid=${process.pid} sid=${getOrCreateSid()}] ` : "";
14878
14974
  const original = process.stderr.write;
14879
14975
  const bound = original.bind(process.stderr);
14880
14976
  const wrapped = ((chunk, ...rest) => {
@@ -14882,6 +14978,7 @@ function installFileLogger(opts) {
14882
14978
  try {
14883
14979
  const text2 = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf-8");
14884
14980
  const clean = stripAnsi2(text2);
14981
+ const linePrefix = usePrefix ? `[${(/* @__PURE__ */ new Date()).toISOString()}${idSuffix}` : "";
14885
14982
  const out = usePrefix ? prefixLines(clean, linePrefix) : clean;
14886
14983
  appendFileSync5(filePath, out);
14887
14984
  bytesWritten += out.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unerr-ai/unerr",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Local-first code intelligence CLI for unerr",
5
5
  "type": "module",
6
6
  "bin": {