Repository navigation
fix(import, init): exit 1 when deep enrich does not finish or init --http would replace another local agent - #1534
Conversation
import --dir and --from-repo logged "Deep enrich complete" and exited 0 when deep enrich left component or architecture docs missing, and turned a deep enrich error into a debug line. They now warn, print the teamai codebase --deep-enrich command that resumes it, and exit 1. The extracted evidence is still published. ci extract-mr keeps exiting 0. Part of Tencent#1500.
init --http swallowed the local agent's "already initialized" error and exited 0, so the old endpoint and token stayed. It also hit that error on every first user-scope run, because the local agent backfills from the config init has just saved, so the local agent was never set up. Re-running with the same endpoint and token is now not a replacement. Another endpoint or token is refused before anything is written, and exits 1 until --force. A same-endpoint run without --token keeps the stored token, and a token is never carried to another endpoint. Part of Tencent#1500.
The PR description documents sufficient testing, including a build followed by representative real-CLI runs and exit statuses. No testing-record blocker. Nothing from the PR was run, built, or installed during this review. |
A path with a space split into two arguments when the printed command was copied.
|
Fixed in bf8dcf8. Checked on the built CLI: The copied command resolves the same teamwiki. New test: |
|
No new findings in the specified PR diff.
Nothing from the PR was run, built, or installed during this review. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
@hz89Dev Thanks for #1500's exit codes. With the built CLI at bf8dcf83:
import.--dir,--from-repoand--from-repo-listexit 1 when deep enrich is incomplete, and--diralso exits 1 when it throws. The evidence is still published. With--output, the printed retry works, including a quoted path with a space. That was the CI review's finding, now fixed.init --http. Another endpoint or token is refused with exit 1 and nothing written, and--forcereplaces it. A first user-scope run now sets up the local agent and its token file, and--tokenwins overTEAMAI_API_TOKEN.- Checks. tsc and lint pass, the six changed test files pass (82/82), and 11 of their tests fail on main. The CHANGELOG and both docs pages match.
One thing blocks it:
-
[P1 blocking] In a team repo, the printed retry doesn't publish, and it blocks the next
teamai push. Runteamai import --dir ./svcwith no--output, and have the AI tool fail. The import printsRun `teamai codebase --deep-enrich --project svc` to retryand exits 1. Then:- Running that retry with the AI tool working exits 0 with
Deep enrichment complete, butarchitecture.mdandlib.mdstay in the local team clone. The remote never gets them. - The clone is left dirty, so the member's next
teamai pushfails withCannot push: the team repo has uncommitted changes … Paths: teamwiki/router.md. - Re-running the same import (
--dir ./svc, or--from-repo <url>) resumes deep enrich and does publish both docs.
codebase --deep-enrichbehaves the same way on main, but main never recommends it. The retry text comes from #1500's own proposal, which didn't cover the team-repo case. Suggested fix: keep the current line with--output. Without it, print the import command to re-run, naming--from-repo <url>for each unfinished repo in a batch. Update the CHANGELOG sentence to match. - Running that retry with the AI tool working exits 0 with
Non-blocking:
- [P3 nit] With
TEAMAI_HTTP_ENDPOINT(or a similar variable) set, a firstinit --httpis refused with "already uses …" though nothing is on disk. - [P3 nit]
source add-httpon the same endpoint now keeps the stored token instead of clearing it. That seems right, but neither the body nor the CHANGELOG mentions it. - [P3 nit] After a symlink refusal, the retry line points to a retry that can't succeed until the link is removed.
Overlap with #1495. Both PRs change src/init.ts, src/local-agent.ts, src/source.ts and the member-guide.md pages, and they conflict in both merge orders. This PR removes the cause of one of #1495's blockers, the "already initialized" error swallowed in Step 6. A clean split: this PR owns the refusal before any write and the Step 6 error handling. #1495 owns per-agent tokens, and on rebase it would move its "same endpoint, one agent's token" exception into assertNoLocalAgentReplacement, so this PR's "another token" refusal doesn't block it.
In a team repo, `codebase --deep-enrich` writes the missing docs only into the local clone: nothing pushes them, and the dirty clone blocks the next `teamai push`. Without `--output`, the line now names the same import, which re-extracts and publishes what deep enrich adds. It drops `--incremental`, which would skip an unchanged source, and keeps `--max-files`, `--domain` and `--ssh`. A batch names `--from-repo <url>` for each unfinished repo. A deep enrich refused at a symbolic link now says to replace the link, so the retry that follows can succeed.
…eplace With TEAMAI_HTTP_ENDPOINT set, a first `init --http` on another endpoint was refused as a replacement, though nothing was stored. The config init writes takes precedence over the environment, so the preflight now reads only config.json and a legacy config.yaml.
|
Fixed in 1fc8cd7 and d678fa2. The body has the new real-CLI record. [P1] Retry in a team repo. Without After the second run the team clone is clean, and the remote has [P3] [P3] [P3] Symlink refusal. The error now reads #1495. Agreed on the split. This PR keeps the refusal before any write and the Step 6 error handling. The "same endpoint, one agent's token" exception belongs in |
|
No new findings in the specified PR diff.
Nothing from the PR was run, built, or installed during this review. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
@hz89Dev Thanks, approving d678fa20.
- The team-repo retry works. We ran every printed retry line exactly as printed, in four modes:
--dirin a team repo printsteamai import --dir ./svc --max-files 300, without--incremental. It exits 0, the docs reach the remote, the clone is clean andteamai pushexits 0.--dir --output "./my wiki": the quoted retry exits 0 and writes there.--from-repo … --domain saleskeeps--domainand publishes.- A
--from-repo-listbatch prints one line, only for the unfinished repo, with that repo's--domainand the batch's--max-files. That line exits 0 and leaves the clone clean.
- The P3s. A first
init --httpwithTEAMAI_HTTP_ENDPOINTset to another endpoint exits 0.source add-httpkeeping the token is now in the CHANGELOG. The symlink error says what to do. - What #1544 got wrong stays right here. A first user-scope
init --httpon a clean HOME exits 0, and a refused one writes nothing.ci extract-mrand the--from-mrteamwiki update stay at exit 0. We checked that last one in the code and the unit test, not against a real MR API. - With #1541 on main. The merge with main (
793e0351) is clean, and build and tsc pass on it. When the push fails, the import exits 1 with the push error and prints no retry line, and rerunning the same import publishes everything.
npm ci, build, tsc and lint pass, and the seven changed test files pass (102/102). The red Lint & Test (Node 24 on ubuntu-latest) was workflow-workspace.test.ts "does not publish conflict markers a prompt staged in a quoted path". It doesn't touch this PR, it passes locally, and it passed on rerun. The CI review found nothing new, and we agree.
Two notes, neither blocking: the --from-repo retry drops --depth, and a batch entry with auth: public has no flag to carry over. And a parallel --from-repo-list batch sometimes fails one repo with ENOENT on teamwiki/source-manifest.json. That predates this PR and is now #1546.
…encent#1534 lets it fail init initHttp no longer swallows a local agent setup that fails, and this file's fs mock has no readJson, so the case that checks a re-init keeps the member's workflow settings failed on the setup it does not test. Tested: init.test.ts passes (85).
…encent#1534 lets it fail init initHttp no longer swallows a local agent setup that fails, and this file's fs mock has no readJson, so the case that checks a re-init keeps the member's workflow settings failed on the setup it does not test. Tested: init.test.ts passes (85).
…encent#1534 lets it fail init initHttp no longer swallows a local agent setup that fails, and this file's fs mock has no readJson, so the case that checks a re-init keeps the member's workflow settings failed on the setup it does not test. Tested: init.test.ts passes (85).
…http would replace another local agent (Tencent#1534) teamai import (--dir, --from-repo, --from-repo-list) exits 1 when its deep enrich is incomplete or fails, names what is missing, still publishes the extracted evidence, and prints a retry that works where it ran: the same import in a team repo, the codebase command with --output. ci extract-mr and the --from-mr teamwiki update stay best effort. teamai init --http refuses, before writing anything, to replace another local agent without --force, and a first init exits 0. Closes Tencent#1500.
Summary
Two commands reported a failure and still exited 0, so scripts and CI carried on as if they had worked.
teamai importprintedDeep enrich completeafter deep enrich had left docs missing, and it logged a deep enrich error only at debug level.teamai init --httpswallowed the local agent'salready initializederror, so the old endpoint and token stayed in place. Both now exit 1 and say what to run next.The extracted evidence is still published. A deep enrich error is now a warning. In a team repo the retry is the same import, because only an import publishes:
codebase --deep-enrichthere leaves the docs uncommitted in the clone, and the nextteamai pushrefuses the dirty clone. The retry drops--incremental, which would skip an unchanged source, and keeps--max-files,--domainand--ssh. A batch prints--from-repo <url>for each unfinished repo. The teamwiki update thatimport --from-mrruns (silently) andteamai ci extract-mr, andcodebase --upgrade-wikikeep exit 0:importFromReponow returns whether deep enrich finished, and only--from-repoand the batch loop turn that into exit 1.Type of Change
Test Plan
npx tsc --noEmitpassesnpm run lintpassesnpx vitest runpasses. Locally: 18699 passed. The only failures were 60 s timeouts inworkflow-local-driver,workflow-reconciliationandworkflow-settle-costwhile the machine's load average was around 40. Those files pass when run on their own, and this diff does not touch them. CI is the check for the full suite.Tests that fail on
mainand pass here:import-dir.test.ts, throughimportCmd({ dir }): when deep enrich is incomplete it exits 1 with the retry line (including--output), and the evidence is on disk. When deep enrich throws, it warns with the error and exits 1. In a team repo the retry isteamai import --dir <dir>, with--max-filesand without--incremental. A path with a space is single-quoted in the retry line, so it can be copied as is.codebase-deep-enrich.test.ts: a deep enrich refused at a symbolic link names the link and says to replace it before retrying.import-repo-merge.test.ts, throughimportCmd({ fromRepo }): exits 1 with the retry line.importFromReporeports an unfinished deep enrich to its caller and leavesprocess.exitCodealone, which keeps--from-mrand--upgrade-wikiat exit 0.import-repo-list.test.ts: the batch exits 1 and names only the repo whose deep enrich did not finish. In a team repo each line isteamai import --from-repo <url>with that entry's--sshand--domain, and the batch's--max-files.http-repo-integration.test.ts, throughinit({ http }):mainit skipped this without saying so.--tokenkeeps the stored token.--forcereplaces it.TEAMAI_API_TOKENset to another key writes the--tokenvalue.TEAMAI_HTTP_ENDPOINTset to another endpoint sets up the local agent instead of refusing.Real-CLI record for the team-repo retry, at d678fa2 (
npm run build, thendist/cli.js, isolated HOME,teamai init https://git.example.com/acme/team-ai.git --provider gitserved from a local bare repo throughurl.<path>.insteadOf,TEAMAI_AI_TOOL=codexpointing at a stubcodexthat fails or answers):Earlier real-CLI record for
--outputandinit --http, at bf8dcf8 (same setup, no AI tool installed):On
main(a484299 per the issue, and rechecked here at 898b82a), the sameimport --dirprintedℹ Deep enrich complete: svcand exited 0. The firstinit --http --scope userprinted[debug] Local agent init: HTTP local agent is already initializedand exited 0.Not run here: providers
gitlab/githubagainst real hosts, and agents other than the default; left to CI.Related Issues
Closes #1500. This covers the remaining Part 1 rows (A3–A5). A1 and A2 landed in #1512, Part 2 in #1509 and Part 3 in #1510.
Notes for Reviewers
main, every firstinit --http --scope useralready hitalready initialized:loadLocalAgentConfigrebuildsconfig.jsonfrom the~/.teamai/config.yamlthatinitsaved one step earlier. A literal "exit 1 on that error" would fail every first run. So the same endpoint and token count as a re-run and succeed, and only another endpoint or token is refused.assertNoLocalAgentReplacementis a read-only preflight (loadLocalAgentConfig({ dryRun: true, envFallback: false })). It runs before scope resolution, which can migrate a legacy config.initLocalAgentHttpno longer takesforceand always writes. By Step 6 its own read can see the config this init saved, or aTEAMAI_API_TOKENkey, so a second check there would refuse after the writes.--tokenkeeps the stored token. A token is never carried over to another endpoint. That also holds forteamai source add-http, which sharesinitLocalAgentHttp: on the endpoint already set up, without--token, it now keeps the stored token instead of clearing it.config.json, or a legacyconfig.yaml), notTEAMAI_HTTP_ENDPOINT: the config init writes takes precedence over the environment, so there is nothing to replace.succeededin the summary, because its evidence was published. The retry line above the summary names it.docs/guide/knowledge.mdandmember-guide.md(both languages) gain short transcripts. The grep for text that calls a failed deep enrich non-blocking or exit 0 found none to change.skill-datais unchanged: the wiki workflow imports with--skip-enrich, and no flag changed.