@mison/ag-kit-cn 3.0.0-beta.0 → 3.0.0
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.
- package/CHANGELOG.md +13 -11
- package/README.md +70 -35
- package/bin/adapters/codex.js +105 -372
- package/bin/adapters/gemini.js +133 -13
- package/bin/ag-kit.js +557 -155
- package/bin/core/builder.js +1 -1
- package/bin/core/generator.js +4 -4
- package/bin/core/resource-loader.js +2 -2
- package/bin/interactive.js +36 -81
- package/bin/utils/manifest.js +3 -3
- package/bin/utils.js +8 -3
- package/docs/PLAN.md +39 -0
- package/docs/TECH.md +136 -0
- package/package.json +11 -10
- package/scripts/ci-verify.js +95 -0
- package/scripts/clean.js +123 -0
- package/scripts/health-check.js +132 -0
- package/scripts/health-check.sh +6 -0
- package/tests/atomic-writer.test.js +47 -0
- package/tests/clean-script.test.js +77 -0
- package/tests/cli-smoke.test.js +479 -0
- package/tests/codex-adapter.test.js +132 -0
- package/tests/doctor.test.js +94 -0
- package/tests/gemini-adapter.test.js +30 -0
- package/tests/generator.test.js +48 -0
- package/tests/git-helper.test.js +53 -0
- package/tests/global-sync.test.js +133 -0
- package/tests/health-check-script.test.js +30 -0
- package/tests/managed-block.test.js +41 -0
- package/tests/manifest.test.js +97 -0
- package/tests/package-tarball.test.js +27 -0
- package/tests/phase-c.test.js +107 -0
- package/tests/standards-compliance.test.js +266 -0
- package/tests/transformer.test.js +74 -0
- package/docs/codex-rules-template.md +0 -36
- package/docs/mapping-spec.md +0 -62
- package/docs/multi-target-adapter.md +0 -46
- package/docs/official/README.md +0 -45
- package/docs/official/antigravity/agent-modes-settings.md +0 -64
- package/docs/official/antigravity/rules-workflows.md +0 -96
- package/docs/official/antigravity/skills.md +0 -147
- package/docs/official/codex/agents-md.md +0 -119
- package/docs/official/codex/config-advanced.md +0 -358
- package/docs/official/codex/config-basic.md +0 -141
- package/docs/official/codex/config-reference.md +0 -223
- package/docs/official/codex/config-sample.md +0 -216
- package/docs/official/codex/mcp.md +0 -107
- package/docs/official/codex/rules.md +0 -79
- package/docs/official/codex/skills.md +0 -114
- package/docs/official/mechanism-compat-audit-2026-03-04.md +0 -36
- package/docs/official/rules-baseline.md +0 -67
- package/docs/official/sources-index.md +0 -79
- package/docs/operations.md +0 -75
- package/docs/terminology-style-guide.md +0 -69
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/charts.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/colors.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/icons.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/landing.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/products.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/prompts.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/react-performance.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/styles.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/typography.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/data/web-interface.csv +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/scripts/core.py +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/scripts/design_system.py +0 -0
- /package/{.agent → .agents}/.shared/ui-ux-pro-max/scripts/search.py +0 -0
- /package/{.agent → .agents}/ARCHITECTURE.md +0 -0
- /package/{.agent → .agents}/agents/backend-specialist.md +0 -0
- /package/{.agent → .agents}/agents/code-archaeologist.md +0 -0
- /package/{.agent → .agents}/agents/database-architect.md +0 -0
- /package/{.agent → .agents}/agents/debugger.md +0 -0
- /package/{.agent → .agents}/agents/devops-engineer.md +0 -0
- /package/{.agent → .agents}/agents/documentation-writer.md +0 -0
- /package/{.agent → .agents}/agents/explorer-agent.md +0 -0
- /package/{.agent → .agents}/agents/frontend-specialist.md +0 -0
- /package/{.agent → .agents}/agents/game-developer.md +0 -0
- /package/{.agent → .agents}/agents/mobile-developer.md +0 -0
- /package/{.agent → .agents}/agents/orchestrator.md +0 -0
- /package/{.agent → .agents}/agents/penetration-tester.md +0 -0
- /package/{.agent → .agents}/agents/performance-optimizer.md +0 -0
- /package/{.agent → .agents}/agents/product-manager.md +0 -0
- /package/{.agent → .agents}/agents/product-owner.md +0 -0
- /package/{.agent → .agents}/agents/project-planner.md +0 -0
- /package/{.agent → .agents}/agents/qa-automation-engineer.md +0 -0
- /package/{.agent → .agents}/agents/security-auditor.md +0 -0
- /package/{.agent → .agents}/agents/seo-specialist.md +0 -0
- /package/{.agent → .agents}/agents/test-engineer.md +0 -0
- /package/{.agent → .agents}/mcp_config.json +0 -0
- /package/{.agent → .agents}/rules/GEMINI.md +0 -0
- /package/{.agent → .agents}/scripts/auto_preview.py +0 -0
- /package/{.agent → .agents}/scripts/checklist.py +0 -0
- /package/{.agent → .agents}/scripts/session_manager.py +0 -0
- /package/{.agent → .agents}/scripts/verify_all.py +0 -0
- /package/{.agent → .agents}/skills/api-patterns/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/api-style.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/auth.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/documentation.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/graphql.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/rate-limiting.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/response.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/rest.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/scripts/api_validator.py +0 -0
- /package/{.agent → .agents}/skills/api-patterns/security-testing.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/trpc.md +0 -0
- /package/{.agent → .agents}/skills/api-patterns/versioning.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/agent-coordination.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/feature-building.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/project-detection.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/scaffolding.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/tech-stack.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/express-api/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -0
- /package/{.agent → .agents}/skills/architecture/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/architecture/context-discovery.md +0 -0
- /package/{.agent → .agents}/skills/architecture/examples.md +0 -0
- /package/{.agent → .agents}/skills/architecture/pattern-selection.md +0 -0
- /package/{.agent → .agents}/skills/architecture/patterns-reference.md +0 -0
- /package/{.agent → .agents}/skills/architecture/trade-off-analysis.md +0 -0
- /package/{.agent → .agents}/skills/bash-linux/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/behavioral-modes/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/brainstorming/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/brainstorming/dynamic-questioning.md +0 -0
- /package/{.agent → .agents}/skills/clean-code/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/code-review-checklist/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/database-design/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/database-design/database-selection.md +0 -0
- /package/{.agent → .agents}/skills/database-design/indexing.md +0 -0
- /package/{.agent → .agents}/skills/database-design/migrations.md +0 -0
- /package/{.agent → .agents}/skills/database-design/optimization.md +0 -0
- /package/{.agent → .agents}/skills/database-design/orm-selection.md +0 -0
- /package/{.agent → .agents}/skills/database-design/schema-design.md +0 -0
- /package/{.agent → .agents}/skills/database-design/scripts/schema_validator.py +0 -0
- /package/{.agent → .agents}/skills/deployment-procedures/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/doc.md +0 -0
- /package/{.agent → .agents}/skills/documentation-templates/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/animation-guide.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/color-system.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/decision-trees.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/motion-graphics.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/scripts/accessibility_checker.py +0 -0
- /package/{.agent → .agents}/skills/frontend-design/scripts/ux_audit.py +0 -0
- /package/{.agent → .agents}/skills/frontend-design/typography-system.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/ux-psychology.md +0 -0
- /package/{.agent → .agents}/skills/frontend-design/visual-effects.md +0 -0
- /package/{.agent → .agents}/skills/game-development/2d-games/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/3d-games/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/game-art/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/game-audio/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/game-design/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/mobile-games/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/multiplayer/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/pc-games/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/vr-ar/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/game-development/web-games/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/geo-fundamentals/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/geo-fundamentals/scripts/geo_checker.py +0 -0
- /package/{.agent → .agents}/skills/i18n-localization/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/i18n-localization/scripts/i18n_checker.py +0 -0
- /package/{.agent → .agents}/skills/intelligent-routing/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/lint-and-validate/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/lint-and-validate/scripts/lint_runner.py +0 -0
- /package/{.agent → .agents}/skills/lint-and-validate/scripts/type_coverage.py +0 -0
- /package/{.agent → .agents}/skills/mcp-builder/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/decision-trees.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-backend.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-color-system.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-debugging.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-design-thinking.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-navigation.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-performance.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-testing.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/mobile-typography.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/platform-android.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/platform-ios.md +0 -0
- /package/{.agent → .agents}/skills/mobile-design/scripts/mobile_audit.py +0 -0
- /package/{.agent → .agents}/skills/mobile-design/touch-psychology.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/scripts/convert_rules.py +0 -0
- /package/{.agent → .agents}/skills/nextjs-react-expert/scripts/react_performance_checker.py +0 -0
- /package/{.agent → .agents}/skills/nodejs-best-practices/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/parallel-agents/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/performance-profiling/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/performance-profiling/scripts/lighthouse_audit.py +0 -0
- /package/{.agent → .agents}/skills/plan-writing/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/powershell-windows/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/python-patterns/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/red-team-tactics/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/refactoring-patterns/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/rust-pro/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/seo-fundamentals/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/seo-fundamentals/scripts/seo_checker.py +0 -0
- /package/{.agent → .agents}/skills/server-management/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/systematic-debugging/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/tailwind-patterns/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/tdd-workflow/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/testing-patterns/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/testing-patterns/scripts/test_runner.py +0 -0
- /package/{.agent → .agents}/skills/vulnerability-scanner/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/vulnerability-scanner/checklists.md +0 -0
- /package/{.agent → .agents}/skills/vulnerability-scanner/scripts/security_scan.py +0 -0
- /package/{.agent → .agents}/skills/web-design-guidelines/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/webapp-testing/SKILL.md +0 -0
- /package/{.agent → .agents}/skills/webapp-testing/scripts/playwright_runner.py +0 -0
- /package/{.agent → .agents}/workflows/brainstorm.md +0 -0
- /package/{.agent → .agents}/workflows/create.md +0 -0
- /package/{.agent → .agents}/workflows/debug.md +0 -0
- /package/{.agent → .agents}/workflows/deploy.md +0 -0
- /package/{.agent → .agents}/workflows/enhance.md +0 -0
- /package/{.agent → .agents}/workflows/orchestrate.md +0 -0
- /package/{.agent → .agents}/workflows/plan.md +0 -0
- /package/{.agent → .agents}/workflows/preview.md +0 -0
- /package/{.agent → .agents}/workflows/restore-localize-compat.md +0 -0
- /package/{.agent → .agents}/workflows/status.md +0 -0
- /package/{.agent → .agents}/workflows/test.md +0 -0
- /package/{.agent → .agents}/workflows/ui-ux-pro-max.md +0 -0
package/bin/adapters/codex.js
CHANGED
|
@@ -7,34 +7,26 @@ const AtomicWriter = require("../utils/atomic-writer");
|
|
|
7
7
|
const GitHelper = require("../utils/git-helper");
|
|
8
8
|
const { upsertManagedBlock } = require("../utils/managed-block");
|
|
9
9
|
const { cloneBranchAgentDir } = require("../utils");
|
|
10
|
-
const CodexBuilder = require("../core/builder");
|
|
11
10
|
const pkg = require("../../package.json");
|
|
12
11
|
|
|
13
12
|
const MANAGED_DIR_NAME = ".agents";
|
|
14
13
|
const LEGACY_DIR_NAME = ".codex";
|
|
15
|
-
const AGENT_DIR_NAME = ".agent";
|
|
16
|
-
const GEMINI_DIR_NAME = ".gemini";
|
|
17
|
-
const PROJECTION_MARKER = ".ag-kit-projection.json";
|
|
18
|
-
const DEFAULT_AGENT_CONFLICT_POLICY = "backup_replace";
|
|
19
|
-
const DEFAULT_GEMINI_AGENTS_POLICY = "append";
|
|
20
14
|
|
|
21
15
|
class CodexAdapter extends BaseAdapter {
|
|
22
16
|
get targetName() {
|
|
23
|
-
return "
|
|
17
|
+
return "codex";
|
|
24
18
|
}
|
|
25
19
|
|
|
26
20
|
getInstalledVersion() {
|
|
27
21
|
const managedManifest = path.join(this.workspaceRoot, MANAGED_DIR_NAME, "manifest.json");
|
|
28
22
|
const legacyManifest = path.join(this.workspaceRoot, LEGACY_DIR_NAME, "manifest.json");
|
|
29
|
-
const manifestPath = fs.existsSync(managedManifest)
|
|
30
|
-
? managedManifest
|
|
31
|
-
: (this._isManagedLegacyCodexDir(path.join(this.workspaceRoot, LEGACY_DIR_NAME)) ? legacyManifest : "");
|
|
23
|
+
const manifestPath = fs.existsSync(managedManifest) ? managedManifest : legacyManifest;
|
|
32
24
|
|
|
33
|
-
if (!
|
|
25
|
+
if (!fs.existsSync(manifestPath)) {
|
|
34
26
|
return null;
|
|
35
27
|
}
|
|
36
28
|
|
|
37
|
-
const manager = new ManifestManager(manifestPath, { target: "
|
|
29
|
+
const manager = new ManifestManager(manifestPath, { target: "codex" });
|
|
38
30
|
const manifest = manager.load();
|
|
39
31
|
if (manifest && typeof manifest.kitVersion === "string" && manifest.kitVersion) {
|
|
40
32
|
return manifest.kitVersion;
|
|
@@ -55,18 +47,15 @@ class CodexAdapter extends BaseAdapter {
|
|
|
55
47
|
const managedDir = path.join(this.workspaceRoot, MANAGED_DIR_NAME);
|
|
56
48
|
const legacyDir = path.join(this.workspaceRoot, LEGACY_DIR_NAME);
|
|
57
49
|
const managedExists = fs.existsSync(managedDir);
|
|
58
|
-
const legacyManaged = this._isManagedLegacyCodexDir(legacyDir);
|
|
59
50
|
const legacyExists = fs.existsSync(legacyDir);
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
|| fs.existsSync(path.join(this.workspaceRoot, AGENT_DIR_NAME))
|
|
63
|
-
|| fs.existsSync(path.join(this.workspaceRoot, GEMINI_DIR_NAME));
|
|
51
|
+
const hasExistingInstall = managedExists || legacyExists;
|
|
52
|
+
const currentDataDir = managedExists ? managedDir : legacyDir;
|
|
64
53
|
|
|
65
|
-
if (mode === "install" &&
|
|
66
|
-
throw new Error(`${MANAGED_DIR_NAME} 目录已存在。请使用 --force 覆盖。`);
|
|
54
|
+
if (mode === "install" && hasExistingInstall && !this.options.force) {
|
|
55
|
+
throw new Error(`${MANAGED_DIR_NAME} 或 ${LEGACY_DIR_NAME} 目录已存在。请使用 --force 覆盖。`);
|
|
67
56
|
}
|
|
68
|
-
if (mode === "update" && !
|
|
69
|
-
throw new Error(`${MANAGED_DIR_NAME}
|
|
57
|
+
if (mode === "update" && !hasExistingInstall) {
|
|
58
|
+
throw new Error(`${MANAGED_DIR_NAME} 目录不存在,无法更新。请先执行 init --target codex。`);
|
|
70
59
|
}
|
|
71
60
|
|
|
72
61
|
const { installSource, sourceLabel, cleanup } = this._resolveInstallSource(sourceDir);
|
|
@@ -80,28 +69,25 @@ class CodexAdapter extends BaseAdapter {
|
|
|
80
69
|
|
|
81
70
|
if (this.options.dryRun) {
|
|
82
71
|
this.log(`[dry-run] 将原子更新: ${managedDir}`);
|
|
83
|
-
if (
|
|
84
|
-
|
|
72
|
+
if (legacyExists) {
|
|
73
|
+
this.log(`[dry-run] 将删除遗留目录: ${legacyDir}`);
|
|
74
|
+
}
|
|
75
|
+
if (hasExistingInstall && this.options.force) {
|
|
76
|
+
const candidates = this._collectBackupCandidates(currentDataDir, incomingFiles);
|
|
85
77
|
if (candidates.fullSnapshot) {
|
|
86
|
-
this.log(`[dry-run]
|
|
78
|
+
this.log(`[dry-run] 发现旧版或缺失 manifest,覆盖前将备份整目录 ${path.basename(currentDataDir)}`);
|
|
87
79
|
} else if (candidates.files.length > 0) {
|
|
88
|
-
this.log(`[dry-run]
|
|
80
|
+
this.log(`[dry-run] 将备份 ${candidates.files.length} 个用户修改文件到 .agents-backup`);
|
|
89
81
|
}
|
|
90
82
|
}
|
|
91
|
-
if (legacyManaged) {
|
|
92
|
-
this.log(`[dry-run] 检测到托管 legacy ${LEGACY_DIR_NAME},将迁移并清理`);
|
|
93
|
-
} else if (legacyUnmanaged) {
|
|
94
|
-
this.log(`[dry-run] 检测到非托管 ${LEGACY_DIR_NAME},将保留不删除`);
|
|
95
|
-
}
|
|
96
|
-
this.log(`[dry-run] 将同步投影目录: ${AGENT_DIR_NAME}, ${GEMINI_DIR_NAME}`);
|
|
97
83
|
this.log("[dry-run] 将更新工作区托管文件: AGENTS.md, antigravity.rules");
|
|
98
84
|
this._cleanupGitIgnore();
|
|
99
85
|
return;
|
|
100
86
|
}
|
|
101
87
|
|
|
102
|
-
if (
|
|
103
|
-
const candidates = this._collectBackupCandidates(
|
|
104
|
-
const backupResult = this._backupCandidates(
|
|
88
|
+
if (hasExistingInstall && this.options.force) {
|
|
89
|
+
const candidates = this._collectBackupCandidates(currentDataDir, incomingFiles);
|
|
90
|
+
const backupResult = this._backupCandidates(currentDataDir, candidates);
|
|
105
91
|
if (backupResult) {
|
|
106
92
|
this.log(`📦 已备份覆盖前文件: ${backupResult.summary}`);
|
|
107
93
|
}
|
|
@@ -110,22 +96,15 @@ class CodexAdapter extends BaseAdapter {
|
|
|
110
96
|
AtomicWriter.atomicCopyDir(stagingDir, managedDir, { logger: this.log.bind(this) });
|
|
111
97
|
this.log(`⚡️ ${MANAGED_DIR_NAME} 原子更新完成`);
|
|
112
98
|
|
|
113
|
-
if (
|
|
114
|
-
const legacyBackup = this._backupDirectorySnapshot(legacyDir, "legacy-codex");
|
|
115
|
-
if (legacyBackup) {
|
|
116
|
-
this.log(`📦 已备份托管 legacy 目录: ${legacyBackup}`);
|
|
117
|
-
}
|
|
99
|
+
if (legacyExists) {
|
|
118
100
|
fs.rmSync(legacyDir, { recursive: true, force: true });
|
|
119
|
-
this.log(`🧹
|
|
120
|
-
} else if (legacyUnmanaged) {
|
|
121
|
-
this.log(`ℹ️ 检测到非托管 ${LEGACY_DIR_NAME},已保留不删除`);
|
|
101
|
+
this.log(`🧹 已移除遗留 ${LEGACY_DIR_NAME} 目录`);
|
|
122
102
|
}
|
|
123
103
|
|
|
124
104
|
this._syncWorkspaceManagedFiles(managedDir);
|
|
125
|
-
this._syncProjectionLayouts(managedDir);
|
|
126
105
|
this._cleanupGitIgnore();
|
|
127
106
|
|
|
128
|
-
this.log(`✅ [
|
|
107
|
+
this.log(`✅ [Codex] ${mode === "install" ? "安装" : "更新"}完成`);
|
|
129
108
|
} finally {
|
|
130
109
|
if (stagingDir) {
|
|
131
110
|
fs.rmSync(stagingDir, { recursive: true, force: true });
|
|
@@ -150,102 +129,76 @@ class CodexAdapter extends BaseAdapter {
|
|
|
150
129
|
cleanup = remote.cleanup;
|
|
151
130
|
}
|
|
152
131
|
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
const codexBuildRoot = resolved.codexBuildRoot;
|
|
156
|
-
|
|
157
|
-
const mergedTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-full-stage-"));
|
|
158
|
-
this._copyDir(canonicalSourceDir, mergedTemp);
|
|
159
|
-
|
|
160
|
-
let codexTemp = "";
|
|
161
|
-
if (codexBuildRoot) {
|
|
162
|
-
codexTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-codex-bridge-"));
|
|
163
|
-
CodexBuilder.build(codexBuildRoot, codexTemp);
|
|
164
|
-
this._copyDir(codexTemp, mergedTemp);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const previousCleanup = cleanup;
|
|
168
|
-
cleanup = () => {
|
|
169
|
-
if (previousCleanup) {
|
|
170
|
-
previousCleanup();
|
|
171
|
-
}
|
|
172
|
-
if (codexTemp) {
|
|
173
|
-
fs.rmSync(codexTemp, { recursive: true, force: true });
|
|
174
|
-
}
|
|
175
|
-
fs.rmSync(mergedTemp, { recursive: true, force: true });
|
|
176
|
-
if (resolved.mockRoot) {
|
|
177
|
-
fs.rmSync(resolved.mockRoot, { recursive: true, force: true });
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
sourceLabel = `${sourceLabel}:full`;
|
|
182
|
-
return { installSource: mergedTemp, sourceLabel, cleanup };
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
_resolveCanonicalSourceDir(installSource) {
|
|
186
|
-
const sourceAbs = path.resolve(installSource);
|
|
132
|
+
const CodexBuilder = require("../core/builder");
|
|
133
|
+
let buildTemp = "";
|
|
187
134
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
codexBuildRoot: mockRoot,
|
|
193
|
-
mockRoot,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
135
|
+
const hasAgentsRoot = fs.existsSync(path.join(installSource, ".agents"));
|
|
136
|
+
const hasLegacyAgentRoot = fs.existsSync(path.join(installSource, ".agent"));
|
|
137
|
+
const hasSkillsDir = fs.existsSync(path.join(installSource, "skills"));
|
|
138
|
+
const isCodexPrebuilt = fs.existsSync(path.join(installSource, "manifest.json"));
|
|
196
139
|
|
|
197
|
-
if (
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
mockRoot
|
|
202
|
-
|
|
203
|
-
}
|
|
140
|
+
if (!isCodexPrebuilt) {
|
|
141
|
+
if (hasSkillsDir) {
|
|
142
|
+
this.log("🛠️ 检测到模板目录格式,正在构建 Codex 结构...");
|
|
143
|
+
const mockRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-root-"));
|
|
144
|
+
const mockAgents = path.join(mockRoot, ".agents");
|
|
145
|
+
this._copyDir(installSource, mockAgents);
|
|
204
146
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
codexBuildRoot: mockRoot,
|
|
210
|
-
mockRoot,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
147
|
+
buildTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-out-"));
|
|
148
|
+
CodexBuilder.build(mockRoot, buildTemp);
|
|
149
|
+
installSource = buildTemp;
|
|
150
|
+
sourceLabel = `${sourceLabel}:compiled`;
|
|
213
151
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
152
|
+
const previousCleanup = cleanup;
|
|
153
|
+
cleanup = () => {
|
|
154
|
+
if (previousCleanup) previousCleanup();
|
|
155
|
+
fs.rmSync(mockRoot, { recursive: true, force: true });
|
|
156
|
+
fs.rmSync(buildTemp, { recursive: true, force: true });
|
|
157
|
+
};
|
|
158
|
+
} else if (hasAgentsRoot) {
|
|
159
|
+
this.log("🛠️ 检测到仓库根目录格式(.agents),正在构建 Codex 结构...");
|
|
160
|
+
buildTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-out-"));
|
|
161
|
+
CodexBuilder.build(installSource, buildTemp);
|
|
162
|
+
installSource = buildTemp;
|
|
163
|
+
sourceLabel = `${sourceLabel}:compiled`;
|
|
164
|
+
|
|
165
|
+
const previousCleanup = cleanup;
|
|
166
|
+
cleanup = () => {
|
|
167
|
+
if (previousCleanup) previousCleanup();
|
|
168
|
+
fs.rmSync(buildTemp, { recursive: true, force: true });
|
|
169
|
+
};
|
|
170
|
+
} else if (hasLegacyAgentRoot) {
|
|
171
|
+
this.log("🛠️ 检测到旧版仓库根目录格式(.agent),正在构建 Codex 结构...");
|
|
172
|
+
const mockRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-root-"));
|
|
173
|
+
const mockAgents = path.join(mockRoot, ".agents");
|
|
174
|
+
this._copyDir(path.join(installSource, ".agent"), mockAgents);
|
|
175
|
+
|
|
176
|
+
buildTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-out-"));
|
|
177
|
+
CodexBuilder.build(mockRoot, buildTemp);
|
|
178
|
+
installSource = buildTemp;
|
|
179
|
+
sourceLabel = `${sourceLabel}:compiled`;
|
|
180
|
+
|
|
181
|
+
const previousCleanup = cleanup;
|
|
182
|
+
cleanup = () => {
|
|
183
|
+
if (previousCleanup) previousCleanup();
|
|
184
|
+
fs.rmSync(mockRoot, { recursive: true, force: true });
|
|
185
|
+
fs.rmSync(buildTemp, { recursive: true, force: true });
|
|
186
|
+
};
|
|
187
|
+
}
|
|
220
188
|
}
|
|
221
189
|
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
_createMockRoot(sourceAgentLikeDir) {
|
|
226
|
-
const mockRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-root-"));
|
|
227
|
-
const mockAgentDir = path.join(mockRoot, AGENT_DIR_NAME);
|
|
228
|
-
this._copyDir(sourceAgentLikeDir, mockAgentDir);
|
|
229
|
-
return mockRoot;
|
|
190
|
+
return { installSource, sourceLabel, cleanup };
|
|
230
191
|
}
|
|
231
192
|
|
|
232
193
|
_createStaging(installSource, sourceLabel) {
|
|
233
194
|
const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-codex-stage-"));
|
|
234
195
|
this._copyDir(installSource, stagingDir);
|
|
235
|
-
const existingManifest = path.join(stagingDir, "manifest.json");
|
|
236
|
-
if (fs.existsSync(existingManifest)) {
|
|
237
|
-
fs.rmSync(existingManifest, { force: true });
|
|
238
|
-
}
|
|
239
196
|
|
|
240
197
|
const manifestPath = path.join(stagingDir, "manifest.json");
|
|
241
198
|
const manager = new ManifestManager(manifestPath, {
|
|
242
|
-
target: "
|
|
199
|
+
target: "codex",
|
|
243
200
|
kitVersion: pkg.version,
|
|
244
201
|
});
|
|
245
|
-
|
|
246
|
-
manager.manifest.version = 3;
|
|
247
|
-
manager.manifest.target = "full";
|
|
248
|
-
manager.manifest.kitVersion = pkg.version;
|
|
249
202
|
manager.manifest.files = ManifestManager.generateFileEntriesFromDir(stagingDir, {
|
|
250
203
|
baseDir: stagingDir,
|
|
251
204
|
sourcePrefix: sourceLabel,
|
|
@@ -258,29 +211,6 @@ class CodexAdapter extends BaseAdapter {
|
|
|
258
211
|
};
|
|
259
212
|
}
|
|
260
213
|
|
|
261
|
-
_isManagedLegacyCodexDir(legacyDir) {
|
|
262
|
-
if (!fs.existsSync(legacyDir)) {
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const manifestPath = path.join(legacyDir, "manifest.json");
|
|
267
|
-
if (!fs.existsSync(manifestPath)) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
try {
|
|
272
|
-
const parsed = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
273
|
-
if (!parsed || typeof parsed !== "object") {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
const target = typeof parsed.target === "string" ? parsed.target.toLowerCase() : "";
|
|
277
|
-
const files = parsed.files;
|
|
278
|
-
return (target === "codex" || target === "full") && files && typeof files === "object";
|
|
279
|
-
} catch (_err) {
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
214
|
_collectBackupCandidates(targetDir, incomingFiles) {
|
|
285
215
|
const manifestPath = path.join(targetDir, "manifest.json");
|
|
286
216
|
if (!fs.existsSync(manifestPath)) {
|
|
@@ -294,11 +224,11 @@ class CodexAdapter extends BaseAdapter {
|
|
|
294
224
|
if (!files || Object.keys(files).length === 0) {
|
|
295
225
|
return { fullSnapshot: true, files: [] };
|
|
296
226
|
}
|
|
297
|
-
} catch (
|
|
227
|
+
} catch (err) {
|
|
298
228
|
return { fullSnapshot: true, files: [] };
|
|
299
229
|
}
|
|
300
230
|
|
|
301
|
-
const manager = new ManifestManager(manifestPath, { target: "
|
|
231
|
+
const manager = new ManifestManager(manifestPath, { target: "codex" });
|
|
302
232
|
manager.load();
|
|
303
233
|
|
|
304
234
|
return {
|
|
@@ -312,7 +242,9 @@ class CodexAdapter extends BaseAdapter {
|
|
|
312
242
|
return null;
|
|
313
243
|
}
|
|
314
244
|
|
|
315
|
-
const
|
|
245
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
246
|
+
const backupRoot = path.join(this.workspaceRoot, ".agents-backup", timestamp);
|
|
247
|
+
fs.mkdirSync(backupRoot, { recursive: true });
|
|
316
248
|
|
|
317
249
|
if (candidates.fullSnapshot) {
|
|
318
250
|
const snapshotDir = path.join(backupRoot, "full-snapshot");
|
|
@@ -333,24 +265,6 @@ class CodexAdapter extends BaseAdapter {
|
|
|
333
265
|
return { summary: `${backupRoot} (${candidates.files.length} files)` };
|
|
334
266
|
}
|
|
335
267
|
|
|
336
|
-
_backupDirectorySnapshot(sourceDir, label) {
|
|
337
|
-
if (!fs.existsSync(sourceDir)) {
|
|
338
|
-
return "";
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
const backupRoot = this._createBackupRoot();
|
|
342
|
-
const snapshotDir = path.join(backupRoot, label || "snapshot");
|
|
343
|
-
this._copyDir(sourceDir, snapshotDir);
|
|
344
|
-
return snapshotDir;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
_createBackupRoot() {
|
|
348
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
349
|
-
const backupRoot = path.join(this.workspaceRoot, ".agents-backup", timestamp);
|
|
350
|
-
fs.mkdirSync(backupRoot, { recursive: true });
|
|
351
|
-
return backupRoot;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
268
|
_syncWorkspaceManagedFiles(managedDir) {
|
|
355
269
|
const managedAgentsPath = path.join(managedDir, "AGENTS.md");
|
|
356
270
|
const managedRulesPath = path.join(managedDir, "antigravity.rules");
|
|
@@ -374,178 +288,8 @@ class CodexAdapter extends BaseAdapter {
|
|
|
374
288
|
}
|
|
375
289
|
}
|
|
376
290
|
|
|
377
|
-
_syncProjectionLayouts(managedDir) {
|
|
378
|
-
this._syncAgentProjection(managedDir);
|
|
379
|
-
this._syncGeminiProjection(managedDir);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
_syncAgentProjection(managedDir) {
|
|
383
|
-
const projectionDir = path.join(this.workspaceRoot, AGENT_DIR_NAME);
|
|
384
|
-
const exists = fs.existsSync(projectionDir);
|
|
385
|
-
|
|
386
|
-
if (exists && !this._isManagedProjection(projectionDir, "agent")) {
|
|
387
|
-
const policy = this.options.agentConflictPolicy || DEFAULT_AGENT_CONFLICT_POLICY;
|
|
388
|
-
|
|
389
|
-
if (policy === "keep") {
|
|
390
|
-
this.log(`ℹ️ 按策略保留已有 ${AGENT_DIR_NAME},跳过投影同步`);
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (policy === "rename_disable") {
|
|
395
|
-
const suffix = new Date().toISOString().replace(/[:.]/g, "-");
|
|
396
|
-
const renamed = path.join(this.workspaceRoot, `.agent.user.${suffix}`);
|
|
397
|
-
fs.renameSync(projectionDir, renamed);
|
|
398
|
-
this.log(`📦 已将旧 ${AGENT_DIR_NAME} 重命名为 ${path.basename(renamed)}`);
|
|
399
|
-
} else {
|
|
400
|
-
const backup = this._backupDirectorySnapshot(projectionDir, "agent-conflict");
|
|
401
|
-
this.log(`📦 已备份冲突 ${AGENT_DIR_NAME}: ${backup}`);
|
|
402
|
-
fs.rmSync(projectionDir, { recursive: true, force: true });
|
|
403
|
-
}
|
|
404
|
-
} else if (exists) {
|
|
405
|
-
fs.rmSync(projectionDir, { recursive: true, force: true });
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
this._copyDir(managedDir, projectionDir);
|
|
409
|
-
this._writeProjectionMarker(projectionDir, "agent");
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
_syncGeminiProjection(managedDir) {
|
|
413
|
-
const geminiRoot = path.join(this.workspaceRoot, GEMINI_DIR_NAME);
|
|
414
|
-
fs.mkdirSync(geminiRoot, { recursive: true });
|
|
415
|
-
|
|
416
|
-
this._mergeGeminiSettings(managedDir, geminiRoot);
|
|
417
|
-
this._syncGeminiAgents(managedDir, geminiRoot);
|
|
418
|
-
this._writeProjectionMarker(geminiRoot, "gemini");
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
_mergeGeminiSettings(managedDir, geminiRoot) {
|
|
422
|
-
const settingsPath = path.join(geminiRoot, "settings.json");
|
|
423
|
-
const mcpPath = path.join(managedDir, "mcp_config.json");
|
|
424
|
-
const servers = this._loadContext7Servers(mcpPath);
|
|
425
|
-
|
|
426
|
-
if (Object.keys(servers).length === 0) {
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
let settings = {};
|
|
431
|
-
if (fs.existsSync(settingsPath)) {
|
|
432
|
-
try {
|
|
433
|
-
settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
|
|
434
|
-
} catch (_err) {
|
|
435
|
-
const backup = this._backupFile(settingsPath, "gemini-settings-invalid.json");
|
|
436
|
-
this.log(`📦 已备份无效 ${GEMINI_DIR_NAME}/settings.json: ${backup}`);
|
|
437
|
-
settings = {};
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const mcpServers = (settings.mcpServers && typeof settings.mcpServers === "object")
|
|
442
|
-
? { ...settings.mcpServers }
|
|
443
|
-
: {};
|
|
444
|
-
|
|
445
|
-
for (const [name, config] of Object.entries(servers)) {
|
|
446
|
-
mcpServers[name] = config;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
settings.mcpServers = mcpServers;
|
|
450
|
-
fs.writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
_loadContext7Servers(mcpPath) {
|
|
454
|
-
if (!fs.existsSync(mcpPath)) {
|
|
455
|
-
return {};
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
try {
|
|
459
|
-
const parsed = JSON.parse(fs.readFileSync(mcpPath, "utf8"));
|
|
460
|
-
const mcpServers = parsed && parsed.mcpServers && typeof parsed.mcpServers === "object"
|
|
461
|
-
? parsed.mcpServers
|
|
462
|
-
: {};
|
|
463
|
-
|
|
464
|
-
const selected = {};
|
|
465
|
-
if (mcpServers.context7) {
|
|
466
|
-
selected.context7 = mcpServers.context7;
|
|
467
|
-
}
|
|
468
|
-
if (mcpServers.context7_backup) {
|
|
469
|
-
selected.context7_backup = mcpServers.context7_backup;
|
|
470
|
-
}
|
|
471
|
-
return selected;
|
|
472
|
-
} catch (_err) {
|
|
473
|
-
return {};
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
_syncGeminiAgents(managedDir, geminiRoot) {
|
|
478
|
-
const sourceAgentsDir = path.join(managedDir, "agents");
|
|
479
|
-
if (!fs.existsSync(sourceAgentsDir)) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const targetAgentsDir = path.join(geminiRoot, "agents");
|
|
484
|
-
const policy = this.options.geminiAgentsPolicy || DEFAULT_GEMINI_AGENTS_POLICY;
|
|
485
|
-
|
|
486
|
-
if (policy === "skip") {
|
|
487
|
-
this.log(`ℹ️ 按策略跳过 ${GEMINI_DIR_NAME}/agents 写入`);
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (policy === "backup_replace" && fs.existsSync(targetAgentsDir)) {
|
|
492
|
-
const backup = this._backupDirectorySnapshot(targetAgentsDir, "gemini-agents-conflict");
|
|
493
|
-
this.log(`📦 已备份冲突 ${GEMINI_DIR_NAME}/agents: ${backup}`);
|
|
494
|
-
fs.rmSync(targetAgentsDir, { recursive: true, force: true });
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
fs.mkdirSync(targetAgentsDir, { recursive: true });
|
|
498
|
-
|
|
499
|
-
const entries = fs.readdirSync(sourceAgentsDir, { withFileTypes: true });
|
|
500
|
-
for (const entry of entries) {
|
|
501
|
-
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
const src = path.join(sourceAgentsDir, entry.name);
|
|
505
|
-
const dest = path.join(targetAgentsDir, `ag-kit-${entry.name}`);
|
|
506
|
-
fs.copyFileSync(src, dest);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
_isManagedProjection(dirPath, type) {
|
|
511
|
-
const markerPath = path.join(dirPath, PROJECTION_MARKER);
|
|
512
|
-
if (!fs.existsSync(markerPath)) {
|
|
513
|
-
return false;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
try {
|
|
517
|
-
const parsed = JSON.parse(fs.readFileSync(markerPath, "utf8"));
|
|
518
|
-
return parsed && parsed.type === type && parsed.managedBy === "ag-kit-cn";
|
|
519
|
-
} catch (_err) {
|
|
520
|
-
return false;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
_writeProjectionMarker(dirPath, type) {
|
|
525
|
-
const markerPath = path.join(dirPath, PROJECTION_MARKER);
|
|
526
|
-
const payload = {
|
|
527
|
-
managedBy: "ag-kit-cn",
|
|
528
|
-
type,
|
|
529
|
-
version: pkg.version,
|
|
530
|
-
generatedAt: new Date().toISOString(),
|
|
531
|
-
};
|
|
532
|
-
fs.writeFileSync(markerPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
_backupFile(filePath, backupName) {
|
|
536
|
-
const backupRoot = this._createBackupRoot();
|
|
537
|
-
const target = path.join(backupRoot, backupName || path.basename(filePath));
|
|
538
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
539
|
-
fs.copyFileSync(filePath, target);
|
|
540
|
-
return target;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
291
|
_cleanupGitIgnore() {
|
|
544
|
-
const cleanupResult = GitHelper.removeIgnoreRules(
|
|
545
|
-
this.workspaceRoot,
|
|
546
|
-
[MANAGED_DIR_NAME, LEGACY_DIR_NAME, AGENT_DIR_NAME, GEMINI_DIR_NAME],
|
|
547
|
-
this.options,
|
|
548
|
-
);
|
|
292
|
+
const cleanupResult = GitHelper.removeIgnoreRules(this.workspaceRoot, [MANAGED_DIR_NAME, LEGACY_DIR_NAME], this.options);
|
|
549
293
|
if (cleanupResult.removedCount > 0) {
|
|
550
294
|
this.log(`🧹 已从 .gitignore 移除 ${cleanupResult.removedCount} 条规则`);
|
|
551
295
|
}
|
|
@@ -571,36 +315,36 @@ class CodexAdapter extends BaseAdapter {
|
|
|
571
315
|
const result = { status: "ok", issues: [] };
|
|
572
316
|
|
|
573
317
|
if (!fs.existsSync(managedDir)) {
|
|
574
|
-
if (
|
|
318
|
+
if (fs.existsSync(legacyDir)) {
|
|
575
319
|
return {
|
|
576
320
|
status: "broken",
|
|
577
|
-
issues: [`Legacy:
|
|
321
|
+
issues: [`Legacy: ${LEGACY_DIR_NAME} directory detected; run update to migrate to ${MANAGED_DIR_NAME}`],
|
|
578
322
|
};
|
|
579
323
|
}
|
|
580
|
-
return {
|
|
581
|
-
status: "missing",
|
|
582
|
-
issues: [`Critical: ${MANAGED_DIR_NAME} 目录缺失`],
|
|
583
|
-
};
|
|
324
|
+
return { status: "missing", issues: [`Critical: ${MANAGED_DIR_NAME} directory missing`] };
|
|
584
325
|
}
|
|
585
326
|
|
|
586
327
|
const manifestPath = path.join(managedDir, "manifest.json");
|
|
587
328
|
if (!fs.existsSync(manifestPath)) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
329
|
+
result.status = "broken";
|
|
330
|
+
result.issues.push("Critical: manifest.json missing");
|
|
331
|
+
return result;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (fs.existsSync(legacyDir)) {
|
|
335
|
+
result.status = "broken";
|
|
336
|
+
result.issues.push(`Legacy: ${LEGACY_DIR_NAME} directory should be removed`);
|
|
592
337
|
}
|
|
593
338
|
|
|
594
|
-
const manager = new ManifestManager(manifestPath, { target: "
|
|
339
|
+
const manager = new ManifestManager(manifestPath, { target: "codex" });
|
|
595
340
|
manager.load();
|
|
596
341
|
if (manager.lastLoadError) {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
};
|
|
342
|
+
result.status = "broken";
|
|
343
|
+
result.issues.push("Critical: manifest.json invalid JSON");
|
|
344
|
+
return result;
|
|
601
345
|
}
|
|
602
|
-
|
|
603
346
|
const drift = manager.checkDrift(managedDir);
|
|
347
|
+
|
|
604
348
|
if (drift.missing.length > 0) {
|
|
605
349
|
result.status = "broken";
|
|
606
350
|
for (const relPath of drift.missing) {
|
|
@@ -617,13 +361,6 @@ class CodexAdapter extends BaseAdapter {
|
|
|
617
361
|
}
|
|
618
362
|
}
|
|
619
363
|
|
|
620
|
-
if (this._isManagedLegacyCodexDir(legacyDir)) {
|
|
621
|
-
result.status = "broken";
|
|
622
|
-
result.issues.push(`Legacy: 托管 ${LEGACY_DIR_NAME} 目录仍存在,需清理`);
|
|
623
|
-
} else if (fs.existsSync(legacyDir)) {
|
|
624
|
-
result.issues.push(`Notice: 非托管 ${LEGACY_DIR_NAME} 目录已保留`);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
364
|
return result;
|
|
628
365
|
}
|
|
629
366
|
|
|
@@ -633,32 +370,29 @@ class CodexAdapter extends BaseAdapter {
|
|
|
633
370
|
const fixes = [];
|
|
634
371
|
|
|
635
372
|
if (!fs.existsSync(managedDir)) {
|
|
636
|
-
if (
|
|
637
|
-
const legacyBackup = this._backupDirectorySnapshot(legacyDir, "legacy-codex");
|
|
373
|
+
if (fs.existsSync(legacyDir)) {
|
|
638
374
|
AtomicWriter.atomicCopyDir(legacyDir, managedDir, { logger: this.log.bind(this) });
|
|
639
375
|
fs.rmSync(legacyDir, { recursive: true, force: true });
|
|
640
|
-
fixes.push(`migrated ${LEGACY_DIR_NAME} to ${MANAGED_DIR_NAME}
|
|
376
|
+
fixes.push(`migrated ${LEGACY_DIR_NAME} to ${MANAGED_DIR_NAME}`);
|
|
641
377
|
} else {
|
|
642
378
|
return {
|
|
643
379
|
fixed: false,
|
|
644
|
-
summary: `缺少 ${MANAGED_DIR_NAME}
|
|
380
|
+
summary: `缺少 ${MANAGED_DIR_NAME},无法自动修复。请执行 ag-kit init --target codex 或 ag-kit update。`,
|
|
645
381
|
};
|
|
646
382
|
}
|
|
647
383
|
}
|
|
648
384
|
|
|
649
|
-
if (
|
|
650
|
-
const legacyBackup = this._backupDirectorySnapshot(legacyDir, "legacy-codex");
|
|
385
|
+
if (fs.existsSync(legacyDir)) {
|
|
651
386
|
fs.rmSync(legacyDir, { recursive: true, force: true });
|
|
652
|
-
fixes.push(`removed
|
|
387
|
+
fixes.push(`removed stale ${LEGACY_DIR_NAME} directory`);
|
|
653
388
|
}
|
|
654
389
|
|
|
655
390
|
const manifestPath = path.join(managedDir, "manifest.json");
|
|
656
391
|
if (!fs.existsSync(manifestPath)) {
|
|
657
392
|
const manager = new ManifestManager(manifestPath, {
|
|
658
|
-
target: "
|
|
393
|
+
target: "codex",
|
|
659
394
|
kitVersion: pkg.version,
|
|
660
395
|
});
|
|
661
|
-
manager.manifest.version = 3;
|
|
662
396
|
manager.manifest.files = ManifestManager.generateFileEntriesFromDir(managedDir, {
|
|
663
397
|
baseDir: managedDir,
|
|
664
398
|
sourcePrefix: "recovered",
|
|
@@ -668,7 +402,6 @@ class CodexAdapter extends BaseAdapter {
|
|
|
668
402
|
}
|
|
669
403
|
|
|
670
404
|
this._syncWorkspaceManagedFiles(managedDir);
|
|
671
|
-
this._syncProjectionLayouts(managedDir);
|
|
672
405
|
this._cleanupGitIgnore();
|
|
673
406
|
|
|
674
407
|
return {
|