How TeamAI Migrates from the Legacy .teamai/ Directory to the New Partitioned Layout
TeamAI automatically migrates legacy data from the repository-root .teamai/ folder to a partitioned directory at ~/.teamai/projects/<project-slug>/ the first time you run a CLI command after upgrading, ensuring isolated storage for machine-local artefacts.
The Tencent/teamai-cli project originally stored all local data—knowledge bases, MCP manifests, and caches—inside a hidden .teamai/ directory at the root of each workspace. This caused data collisions when multiple developers shared a repository and polluted the source tree with tool-generated files. To solve this, the codebase now implements a partitioned data home that lives outside the project tree, with an idempotent migration routine that preserves existing data while eliminating the legacy layout.
Why the Legacy .teamai/ Layout Was Problematic
The original design placed all TeamAI artefacts directly inside the workspace:
- Data Collisions: When multiple developers cloned the same repository, their local learning files and MCP configurations overwrote each other because they all wrote to the same relative path.
- Workspace Pollution: Version control tools and backup scripts had to explicitly ignore the hidden folder, and the mixture of source and generated files complicated repository maintenance.
According to the Tencent/teamai-cli source code, the new partitioned layout stores data under the user's home directory, scoped by a deterministic project slug derived from the Git remote URL.
The Migration Pipeline: Step-by-Step
The migration logic is defined in src/migrate.ts and executes transparently on the first CLI invocation after detecting a legacy installation.
Step 1: Detecting the Legacy Layout
The CLI first checks for the existence of the old data home by resolving path.join(workspaceRoot, '.teamai'). If this directory exists, the migration sequence begins.
// src/migrate.ts
const legacyTeamaiHome = path.join(workspaceRoot, '.teamai');
if (existsSync(legacyTeamaiHome)) {
await migrateLegacyTeamai(workspaceRoot);
}
Step 2: Resolving the Partition Anchor
Before moving data, the system calculates the new destination. In src/utils/partition.ts, the CLI parses the project's Git remote URL to generate a reproducible projectSlug (e.g., github.com_Tencent_teamai-cli). The new data home becomes:
// src/utils/partition.ts
const newHome = path.join(os.homedir(), '.teamai', 'projects', projectSlug);
This deterministic naming ensures that every clone of the same repository maps to the same partition, enabling consistent knowledge sharing across different local copies.
Step 3: Migrating MCP Configuration
If the legacy folder contains a managed-mcp.json file, the migrateManagedMcp() helper copies it to the partitioned location. This preserves your MCP server definitions without requiring manual reconfiguration.
// src/migrate.ts
await migrateManagedMcp(
path.join(legacyTeamaiHome, 'managed-mcp.json'),
path.join(newHome, 'managed-mcp.json')
);
Step 4: Moving Knowledge Artefacts
All learning data, indexes, and caches are relocated using moveDirContents(), which recursively walks the source directory and moves entries from legacyTeamaiHome/knowledge to newHome/knowledge. This operation is atomic and reversible until the final cleanup stage.
// src/migrate.ts
await moveDirContents(
path.join(legacyTeamaiHome, 'knowledge'),
path.join(newHome, 'knowledge')
);
Step 5: Updating Internal References
After successful data movement, the CLI updates its runtime configuration in src/config.ts. Subsequent commands query getDataHome() from src/utils/home.ts, which now returns the partitioned path rather than the legacy workspace-relative location.
// src/utils/home.ts
export function getDataHome(): string {
return path.join(os.homedir(), '.teamai', 'projects', getProjectSlug());
}
Step 6: Cleaning Up Legacy Data
Once the migration succeeds and the new configuration is verified, the old .teamai/ folder is removed from the workspace root. This cleanup is guarded by safety checks ensuring no other process holds file locks on the legacy directory.
Implementation Details and Code Examples
You can verify the migration status programmatically or invoke the migration manually in edge cases.
Checking migration status:
import { existsSync } from 'fs';
import { getDataHome } from './utils/home';
const hasMigrated = existsSync(getDataHome());
console.log(hasMigrated ? 'Using partitioned layout' : 'Legacy layout detected');
Manually triggering migration:
import { migrateLegacyTeamai } from './migrate';
// Force migration check for a specific workspace
await migrateLegacyTeamai('/path/to/project');
Accessing the partitioned data home:
import { getDataHome } from './utils/home';
import path from 'path';
const projectHome = getDataHome(); // ~/.teamai/projects/<slug>
const knowledgeDir = path.join(projectHome, 'knowledge');
Summary
- Automatic Detection: The CLI checks for
<workspaceRoot>/.teamai/insrc/migrate.tsand triggers migration only when legacy data exists. - Deterministic Partitioning: The new home uses a slug derived from the Git remote URL, ensuring consistency across clones.
- Data Integrity: The
moveDirContents()utility preserves all knowledge files and MCP configurations during the transfer. - Isolation: All machine-local artefacts now live under
~/.teamai/projects/, completely outside the source repository. - Idempotent Operation: Running the migration multiple times is safe; the system skips already-migrated projects.
Frequently Asked Questions
Does the migration happen automatically?
Yes. According to the Tencent/teamai-cli source code, the first CLI command you run after upgrading detects the legacy .teamai/ directory and executes the full migration sequence without requiring manual intervention. You do not need to run a separate migration command.
What happens to my existing knowledge base?
All existing data is preserved. The moveDirContents() function in src/migrate.ts recursively transfers every file from the legacy knowledge/ subdirectory to the new partitioned location. Your learning history, indexes, and caches remain intact and accessible after migration.
How is the partition directory name determined?
The directory name is a slug generated from the repository's Git remote URL. The logic in src/utils/partition.ts converts URLs like https://github.com/Tencent/teamai-cli.git into identifiers like github.com_Tencent_teamai-cli, ensuring that every clone of the same repository maps to the same data partition.
Can I revert to the legacy .teamai/ layout?
No, the migration is designed as a one-way transition. After successful migration, src/migrate.ts removes the legacy .teamai/ folder from your workspace, and the CLI exclusively uses getDataHome() from src/utils/home.ts to resolve the partitioned path. Reverting would require manually moving data back and modifying the source code.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →