Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[bug] Codebase import: --skip-enrich drops AI enrichment, same-name --dir checkouts collide, and deep enrich follows symlinks

Open
#1,422 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@kittimzhe is already working on this.

Since Oct 27, 2026.

  • #1448 by @kittimzhe — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
54/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
node.js, typescript
Domain
backend, cli

Research direction

Start with the named paths in src/import-codebase.ts, src/codebase-extract.ts, and src/deep-enrich.ts; compare the staging and publish flow under --skip-enrich, how --dir sources get identities, and the deep-enrich write sites. Check docs/guide/knowledge.md for the incremental behavior described there. Done means all four reproductions are addressed, including preventing writes through symlink targets.

Written by the indexing model from the issue text.

Description

bug help wanted

What happens

Four gaps in how teamai import publishes a codebase's evidence (teamwiki/evidence/code/<slug>/) and how deep enrich writes into it. All four are on main (f70ce259) and were found while reviewing #1417.

  1. --skip-enrich drops the AI enrichment. A daily static sync (import --skip-enrich --incremental) loses the published AI _manifest.json, _domains.json and the deep-enrich docs/. router.md falls back to the default domain until the next AI run.
  2. Two --dir checkouts with the same basename share one evidence directory. Importing /a/svc and then /b/svc replaces the first codebase's evidence with the second's.
  3. --incremental on a --dir checkout without an origin remote always runs a full extraction. The run prints [extract] no matching source baseline, running full extraction, while docs/guide/knowledge.md:151 says --incremental re-extracts only the changed files.
  4. Deep enrich writes through symlinks in docs/. If the team repo holds a symlink at evidence/code/<slug>/docs/<component>.md (or README.md, graph-g*.md), deep enrich overwrites the file it points to, outside the teamwiki.

Why

  1. Under --skip-enrich, extraction writes the deterministic fallback _manifest.json into staging (src/codebase-extract.ts:1001-1008). importCodebase then deletes everything in the published evidence directory except .indices, and copies staging over it (src/import-codebase.ts:112-118). Deep enrich does not run under --skip-enrich (import-codebase.ts:159), so nothing rebuilds what was removed.
  2. defaultProjectSlug returns path.basename(dir) unless the directory is a workspace root (src/codebase-extract.ts:556-563). Remote imports use <provider>__<owner>__<repo>, so only --dir collides.
  3. The incremental baseline is used only when its source-manifest.json matches the source's repoIdentity (manifestMatchesSource, src/codebase-extract.ts:604). A checkout with no remote has no identity, so it never matches.
  4. src/deep-enrich.ts checks component slugs with assertSafeResourceName (line 433), then writes with writeFile (lines 440, 483, 505-507, 635, 664, 693), which follows a symlink at the target path. It takes write access to the team repo, which can already ship hooks, so this is hardening rather than a new exposure.

Reproduction

Run with built CLIs and an isolated HOME during the #1417 review:

  • (1) AI-enriched evidence (manifest, _domains.json, docs/ written by hand), then import --dir <src> --skip-enrich --all --incremental after one source change: all three are gone, and router.md shows the fallback domain.
  • (2) import --dir /a/svc with a curated doc, then import --dir /b/svc: A's evidence is replaced by B's.
  • (3) The same --incremental run with and without an origin remote: only the run with a remote seeds from the baseline.
  • (4) A symlink at docs/README.md or docs/graph-g1-relations.md pointing outside the teamwiki: deep enrich overwrote the outside file. (A link at docs/<component>.md to an existing file is skipped as already written; a dangling one is followed.)

Possible fix

  • (1) #1417 carries docs/ and _domains.json across imports. The fallback manifest lists the same top-level modules as the AI one, so pruning removed components against it is correct. What it still loses is the AI-written component content in _manifest.json; keeping that under --skip-enrich is the remaining part.
  • (2) Make the --dir slug unique when the directory has a remote (use the repo identity, as remote imports do). Otherwise refuse to replace evidence whose source-manifest.json names a different source.
  • (3) Either fall back to the checkout's path as identity, or have the docs say --incremental needs an origin remote for --dir.
  • (4) Refuse to write through a symlink in the evidence directory (lstat before writing, or write to a temp file and rename).
Dominant language
TypeScript
Stars
5.6k
Forks
471
Avg merge
22h 54m
Merged PRs (30d)
347

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Tencent/teamai-cli

All issues in Tencent/teamai-cli

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.