Skip to content

feat(code): enricher run#2016

Open
adboio wants to merge 1 commit intomainfrom
05-04-feat_code_enricher_run
Open

feat(code): enricher run#2016
adboio wants to merge 1 commit intomainfrom
05-04-feat_code_enricher_run

Conversation

@adboio
Copy link
Copy Markdown
Contributor

@adboio adboio commented May 4, 2026

Problem

first task discovery is great, but it takes 3-4 minutes

let's give users something faster

Changes

uses the enricher to scan the user's codebase and suggest "tasks" (bundled skills):

  • if posthog not installed -> wizard run
  • if installed && stale flags -> clean up stale flags
  • else -> run sdk health audit

How did you test this?

manually

Publish to changelog?

sure

Copy link
Copy Markdown
Contributor Author

adboio commented May 4, 2026

@adboio adboio force-pushed the 04-20-wizard_integration_and_first_data-less_tasks branch from c67e833 to 8b0d42b Compare May 4, 2026 21:36
@adboio adboio force-pushed the 05-04-feat_code_enricher_run branch 4 times, most recently from f7ef6a8 to 7533bba Compare May 5, 2026 00:25
@adboio adboio force-pushed the 04-20-wizard_integration_and_first_data-less_tasks branch from 8b0d42b to e31183b Compare May 5, 2026 00:25
@charlesvien charlesvien added the Create release This will trigger a new release label May 5, 2026
@adboio adboio changed the base branch from 04-20-wizard_integration_and_first_data-less_tasks to graphite-base/2016 May 5, 2026 03:14
@adboio adboio force-pushed the graphite-base/2016 branch from e31183b to eeedfa0 Compare May 5, 2026 03:14
@adboio adboio force-pushed the 05-04-feat_code_enricher_run branch from 7533bba to 359d05b Compare May 5, 2026 03:14
@graphite-app graphite-app Bot changed the base branch from graphite-base/2016 to main May 5, 2026 03:14
@adboio adboio force-pushed the 05-04-feat_code_enricher_run branch 2 times, most recently from 45aaa95 to 05e09e2 Compare May 5, 2026 03:39
@adboio adboio requested a review from a team May 5, 2026 20:22
@adboio adboio marked this pull request as ready for review May 5, 2026 20:22
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 5, 2026

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/code/src/main/services/enrichment/service.ts:357-383
`processInBatches` is a generic results-collecting utility, but the callback here always returns `null` and the `R[]` return value is immediately discarded — all real work is done as a side effect on the `files` closure. This makes the signature misleading and violates the "no superfluous parts" rule. A plain batched loop expresses the intent directly.

```suggestion
    const files = new Map<string, ParsedRepoEntry>();
    for (let i = 0; i < toParse.length; i += SCAN_BATCH_SIZE) {
      const batch = toParse.slice(i, i + SCAN_BATCH_SIZE);
      await Promise.all(
        batch.map(async (candidate) => {
          let content: string;
          try {
            content = await fs.readFile(
              path.join(repoPath, candidate.relPath),
              "utf-8",
            );
          } catch {
            return;
          }
          try {
            const result = await enricher.parse(content, candidate.langId);
            files.set(candidate.relPath, { langId: candidate.langId, result });
          } catch (err) {
            log.debug("enricher.parse threw during repo scan, skipping file", {
              file: candidate.relPath,
              error: err instanceof Error ? err.message : String(err),
            });
            files.set(candidate.relPath, {
              langId: candidate.langId,
              result: null,
            });
          }
        }),
      );
      await yieldToEventLoop();
    }
```

### Issue 2 of 2
apps/code/src/main/services/enrichment/service.ts:322-326
**`null` scan results are not memoised**

When `runScan` fails (e.g. `git grep` throws because the directory is not a git repo, or the process is unavailable), the `null` result is never written to `repoScanCache`. After the in-flight promise settles, a subsequent call to `scanRepo` for the same path will start a brand-new `runScan` and fail again. For persistent error conditions this means every call pair to `detectPosthogInstallState` / `findStaleFlagSuggestions` retries an already-known-failing git operation. Caching the `null` would be consistent with the "concurrent callers wait on the same promise" contract.

Reviews (1): Last reviewed commit: "feat(code): enricher run" | Re-trigger Greptile

Comment on lines +357 to +383
const files = new Map<string, ParsedRepoEntry>();
await processInBatches(toParse, SCAN_BATCH_SIZE, async (candidate) => {
let content: string;
try {
content = await fs.readFile(
path.join(repoPath, candidate.relPath),
"utf-8",
);
} catch {
return null;
}
try {
const result = await enricher.parse(content, candidate.langId);
files.set(candidate.relPath, { langId: candidate.langId, result });
return null;
} catch (err) {
log.debug("enricher.parse threw during repo scan, skipping file", {
file: candidate.relPath,
error: err instanceof Error ? err.message : String(err),
});
files.set(candidate.relPath, {
langId: candidate.langId,
result: null,
});
return null;
}
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 processInBatches is a generic results-collecting utility, but the callback here always returns null and the R[] return value is immediately discarded — all real work is done as a side effect on the files closure. This makes the signature misleading and violates the "no superfluous parts" rule. A plain batched loop expresses the intent directly.

Suggested change
const files = new Map<string, ParsedRepoEntry>();
await processInBatches(toParse, SCAN_BATCH_SIZE, async (candidate) => {
let content: string;
try {
content = await fs.readFile(
path.join(repoPath, candidate.relPath),
"utf-8",
);
} catch {
return null;
}
try {
const result = await enricher.parse(content, candidate.langId);
files.set(candidate.relPath, { langId: candidate.langId, result });
return null;
} catch (err) {
log.debug("enricher.parse threw during repo scan, skipping file", {
file: candidate.relPath,
error: err instanceof Error ? err.message : String(err),
});
files.set(candidate.relPath, {
langId: candidate.langId,
result: null,
});
return null;
}
});
const files = new Map<string, ParsedRepoEntry>();
for (let i = 0; i < toParse.length; i += SCAN_BATCH_SIZE) {
const batch = toParse.slice(i, i + SCAN_BATCH_SIZE);
await Promise.all(
batch.map(async (candidate) => {
let content: string;
try {
content = await fs.readFile(
path.join(repoPath, candidate.relPath),
"utf-8",
);
} catch {
return;
}
try {
const result = await enricher.parse(content, candidate.langId);
files.set(candidate.relPath, { langId: candidate.langId, result });
} catch (err) {
log.debug("enricher.parse threw during repo scan, skipping file", {
file: candidate.relPath,
error: err instanceof Error ? err.message : String(err),
});
files.set(candidate.relPath, {
langId: candidate.langId,
result: null,
});
}
}),
);
await yieldToEventLoop();
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/main/services/enrichment/service.ts
Line: 357-383

Comment:
`processInBatches` is a generic results-collecting utility, but the callback here always returns `null` and the `R[]` return value is immediately discarded — all real work is done as a side effect on the `files` closure. This makes the signature misleading and violates the "no superfluous parts" rule. A plain batched loop expresses the intent directly.

```suggestion
    const files = new Map<string, ParsedRepoEntry>();
    for (let i = 0; i < toParse.length; i += SCAN_BATCH_SIZE) {
      const batch = toParse.slice(i, i + SCAN_BATCH_SIZE);
      await Promise.all(
        batch.map(async (candidate) => {
          let content: string;
          try {
            content = await fs.readFile(
              path.join(repoPath, candidate.relPath),
              "utf-8",
            );
          } catch {
            return;
          }
          try {
            const result = await enricher.parse(content, candidate.langId);
            files.set(candidate.relPath, { langId: candidate.langId, result });
          } catch (err) {
            log.debug("enricher.parse threw during repo scan, skipping file", {
              file: candidate.relPath,
              error: err instanceof Error ? err.message : String(err),
            });
            files.set(candidate.relPath, {
              langId: candidate.langId,
              result: null,
            });
          }
        }),
      );
      await yieldToEventLoop();
    }
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +322 to +326
const promise = this.runScan(repoPath).finally(() => {
this.repoScanInflight.delete(repoPath);
});
this.repoScanInflight.set(repoPath, promise);
return promise;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 null scan results are not memoised

When runScan fails (e.g. git grep throws because the directory is not a git repo, or the process is unavailable), the null result is never written to repoScanCache. After the in-flight promise settles, a subsequent call to scanRepo for the same path will start a brand-new runScan and fail again. For persistent error conditions this means every call pair to detectPosthogInstallState / findStaleFlagSuggestions retries an already-known-failing git operation. Caching the null would be consistent with the "concurrent callers wait on the same promise" contract.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/main/services/enrichment/service.ts
Line: 322-326

Comment:
**`null` scan results are not memoised**

When `runScan` fails (e.g. `git grep` throws because the directory is not a git repo, or the process is unavailable), the `null` result is never written to `repoScanCache`. After the in-flight promise settles, a subsequent call to `scanRepo` for the same path will start a brand-new `runScan` and fail again. For persistent error conditions this means every call pair to `detectPosthogInstallState` / `findStaleFlagSuggestions` retries an already-known-failing git operation. Caching the `null` would be consistent with the "concurrent callers wait on the same promise" contract.

How can I resolve this? If you propose a fix, please make it concise.

@adboio adboio force-pushed the 05-04-feat_code_enricher_run branch from 05e09e2 to 5f2249e Compare May 5, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Create release This will trigger a new release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants