@mison/ag-kit-cn 2.0.1

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.
Files changed (237) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
  28. package/.agent/ARCHITECTURE.md +285 -0
  29. package/.agent/agents/backend-specialist.md +268 -0
  30. package/.agent/agents/code-archaeologist.md +106 -0
  31. package/.agent/agents/database-architect.md +225 -0
  32. package/.agent/agents/debugger.md +225 -0
  33. package/.agent/agents/devops-engineer.md +242 -0
  34. package/.agent/agents/documentation-writer.md +104 -0
  35. package/.agent/agents/explorer-agent.md +73 -0
  36. package/.agent/agents/frontend-specialist.md +618 -0
  37. package/.agent/agents/game-developer.md +162 -0
  38. package/.agent/agents/mobile-developer.md +382 -0
  39. package/.agent/agents/orchestrator.md +438 -0
  40. package/.agent/agents/penetration-tester.md +188 -0
  41. package/.agent/agents/performance-optimizer.md +187 -0
  42. package/.agent/agents/product-manager.md +112 -0
  43. package/.agent/agents/product-owner.md +95 -0
  44. package/.agent/agents/project-planner.md +405 -0
  45. package/.agent/agents/qa-automation-engineer.md +103 -0
  46. package/.agent/agents/security-auditor.md +170 -0
  47. package/.agent/agents/seo-specialist.md +111 -0
  48. package/.agent/agents/test-engineer.md +158 -0
  49. package/.agent/mcp_config.json +12 -0
  50. package/.agent/rules/GEMINI.md +273 -0
  51. package/.agent/scripts/auto_preview.py +148 -0
  52. package/.agent/scripts/checklist.py +217 -0
  53. package/.agent/scripts/session_manager.py +120 -0
  54. package/.agent/scripts/verify_all.py +327 -0
  55. package/.agent/skills/api-patterns/SKILL.md +84 -0
  56. package/.agent/skills/api-patterns/api-style.md +42 -0
  57. package/.agent/skills/api-patterns/auth.md +24 -0
  58. package/.agent/skills/api-patterns/documentation.md +26 -0
  59. package/.agent/skills/api-patterns/graphql.md +41 -0
  60. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  61. package/.agent/skills/api-patterns/response.md +37 -0
  62. package/.agent/skills/api-patterns/rest.md +40 -0
  63. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  64. package/.agent/skills/api-patterns/security-testing.md +122 -0
  65. package/.agent/skills/api-patterns/trpc.md +41 -0
  66. package/.agent/skills/api-patterns/versioning.md +22 -0
  67. package/.agent/skills/app-builder/SKILL.md +75 -0
  68. package/.agent/skills/app-builder/agent-coordination.md +74 -0
  69. package/.agent/skills/app-builder/feature-building.md +53 -0
  70. package/.agent/skills/app-builder/project-detection.md +34 -0
  71. package/.agent/skills/app-builder/scaffolding.md +118 -0
  72. package/.agent/skills/app-builder/tech-stack.md +40 -0
  73. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  74. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  75. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  76. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  77. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  78. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  79. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  80. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  81. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  82. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  83. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  84. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  85. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  86. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  87. package/.agent/skills/architecture/SKILL.md +57 -0
  88. package/.agent/skills/architecture/context-discovery.md +43 -0
  89. package/.agent/skills/architecture/examples.md +94 -0
  90. package/.agent/skills/architecture/pattern-selection.md +68 -0
  91. package/.agent/skills/architecture/patterns-reference.md +50 -0
  92. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  93. package/.agent/skills/bash-linux/SKILL.md +201 -0
  94. package/.agent/skills/behavioral-modes/SKILL.md +264 -0
  95. package/.agent/skills/brainstorming/SKILL.md +164 -0
  96. package/.agent/skills/brainstorming/dynamic-questioning.md +359 -0
  97. package/.agent/skills/clean-code/SKILL.md +200 -0
  98. package/.agent/skills/code-review-checklist/SKILL.md +125 -0
  99. package/.agent/skills/database-design/SKILL.md +54 -0
  100. package/.agent/skills/database-design/database-selection.md +43 -0
  101. package/.agent/skills/database-design/indexing.md +39 -0
  102. package/.agent/skills/database-design/migrations.md +50 -0
  103. package/.agent/skills/database-design/optimization.md +36 -0
  104. package/.agent/skills/database-design/orm-selection.md +30 -0
  105. package/.agent/skills/database-design/schema-design.md +56 -0
  106. package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
  107. package/.agent/skills/deployment-procedures/SKILL.md +241 -0
  108. package/.agent/skills/doc.md +177 -0
  109. package/.agent/skills/documentation-templates/SKILL.md +194 -0
  110. package/.agent/skills/frontend-design/SKILL.md +418 -0
  111. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  112. package/.agent/skills/frontend-design/color-system.md +307 -0
  113. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  114. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  115. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  116. package/.agent/skills/frontend-design/scripts/ux_audit.py +727 -0
  117. package/.agent/skills/frontend-design/typography-system.md +345 -0
  118. package/.agent/skills/frontend-design/ux-psychology.md +1118 -0
  119. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  120. package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
  121. package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
  122. package/.agent/skills/game-development/SKILL.md +167 -0
  123. package/.agent/skills/game-development/game-art/SKILL.md +185 -0
  124. package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
  125. package/.agent/skills/game-development/game-design/SKILL.md +129 -0
  126. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
  127. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
  128. package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
  129. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
  130. package/.agent/skills/game-development/web-games/SKILL.md +150 -0
  131. package/.agent/skills/geo-fundamentals/SKILL.md +155 -0
  132. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  133. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  134. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  135. package/.agent/skills/intelligent-routing/SKILL.md +335 -0
  136. package/.agent/skills/lint-and-validate/SKILL.md +44 -0
  137. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
  138. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  139. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  140. package/.agent/skills/mobile-design/SKILL.md +394 -0
  141. package/.agent/skills/mobile-design/decision-trees.md +516 -0
  142. package/.agent/skills/mobile-design/mobile-backend.md +491 -0
  143. package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
  144. package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
  145. package/.agent/skills/mobile-design/mobile-design-thinking.md +355 -0
  146. package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
  147. package/.agent/skills/mobile-design/mobile-performance.md +767 -0
  148. package/.agent/skills/mobile-design/mobile-testing.md +356 -0
  149. package/.agent/skills/mobile-design/mobile-typography.md +432 -0
  150. package/.agent/skills/mobile-design/platform-android.md +666 -0
  151. package/.agent/skills/mobile-design/platform-ios.md +561 -0
  152. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
  153. package/.agent/skills/mobile-design/touch-psychology.md +537 -0
  154. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +311 -0
  155. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +241 -0
  156. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +489 -0
  157. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +263 -0
  158. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
  159. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +431 -0
  160. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +683 -0
  161. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +149 -0
  162. package/.agent/skills/nextjs-react-expert/SKILL.md +286 -0
  163. package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
  164. package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
  165. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
  166. package/.agent/skills/parallel-agents/SKILL.md +194 -0
  167. package/.agent/skills/performance-profiling/SKILL.md +149 -0
  168. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  169. package/.agent/skills/plan-writing/SKILL.md +152 -0
  170. package/.agent/skills/powershell-windows/SKILL.md +166 -0
  171. package/.agent/skills/python-patterns/SKILL.md +441 -0
  172. package/.agent/skills/red-team-tactics/SKILL.md +203 -0
  173. package/.agent/skills/rust-pro/SKILL.md +190 -0
  174. package/.agent/skills/seo-fundamentals/SKILL.md +135 -0
  175. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +215 -0
  176. package/.agent/skills/server-management/SKILL.md +161 -0
  177. package/.agent/skills/systematic-debugging/SKILL.md +114 -0
  178. package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
  179. package/.agent/skills/tdd-workflow/SKILL.md +149 -0
  180. package/.agent/skills/testing-patterns/SKILL.md +178 -0
  181. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
  182. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
  183. package/.agent/skills/vulnerability-scanner/checklists.md +131 -0
  184. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +459 -0
  185. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  186. package/.agent/skills/webapp-testing/SKILL.md +187 -0
  187. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  188. package/.agent/workflows/brainstorm.md +113 -0
  189. package/.agent/workflows/create.md +59 -0
  190. package/.agent/workflows/debug.md +103 -0
  191. package/.agent/workflows/deploy.md +176 -0
  192. package/.agent/workflows/enhance.md +63 -0
  193. package/.agent/workflows/orchestrate.md +242 -0
  194. package/.agent/workflows/plan.md +89 -0
  195. package/.agent/workflows/preview.md +80 -0
  196. package/.agent/workflows/restore-localize-compat.md +525 -0
  197. package/.agent/workflows/status.md +86 -0
  198. package/.agent/workflows/test.md +144 -0
  199. package/.agent/workflows/ui-ux-pro-max.md +295 -0
  200. package/AGENT_FLOW.md +609 -0
  201. package/CHANGELOG.md +68 -0
  202. package/LICENSE +21 -0
  203. package/README.md +260 -0
  204. package/bin/adapters/base.js +63 -0
  205. package/bin/adapters/codex.js +391 -0
  206. package/bin/adapters/gemini.js +137 -0
  207. package/bin/ag-kit.js +1336 -0
  208. package/bin/core/builder.js +80 -0
  209. package/bin/core/generator.js +59 -0
  210. package/bin/core/resource-loader.js +64 -0
  211. package/bin/core/transformer.js +208 -0
  212. package/bin/interactive.js +65 -0
  213. package/bin/utils/atomic-writer.js +97 -0
  214. package/bin/utils/git-helper.js +68 -0
  215. package/bin/utils/managed-block.js +65 -0
  216. package/bin/utils/manifest.js +241 -0
  217. package/bin/utils.js +82 -0
  218. package/docs/codex-rules-template.md +36 -0
  219. package/docs/mapping-spec.md +68 -0
  220. package/docs/multi-target-adapter.md +80 -0
  221. package/docs/official/README.md +53 -0
  222. package/docs/official/antigravity/agent-modes-settings.md +64 -0
  223. package/docs/official/antigravity/rules-workflows.md +96 -0
  224. package/docs/official/antigravity/skills.md +147 -0
  225. package/docs/official/codex/agents-md.md +119 -0
  226. package/docs/official/codex/config-advanced.md +358 -0
  227. package/docs/official/codex/config-basic.md +141 -0
  228. package/docs/official/codex/config-reference.md +223 -0
  229. package/docs/official/codex/config-sample.md +216 -0
  230. package/docs/official/codex/mcp.md +107 -0
  231. package/docs/official/codex/rules.md +79 -0
  232. package/docs/official/codex/skills.md +114 -0
  233. package/docs/official/sources-index.md +32 -0
  234. package/docs/operations.md +145 -0
  235. package/docs/terminology-style-guide.md +69 -0
  236. package/package.json +51 -0
  237. package/scripts/postinstall-check.js +112 -0
@@ -0,0 +1,391 @@
1
+ const fs = require("fs");
2
+ const os = require("os");
3
+ const path = require("path");
4
+ const BaseAdapter = require("./base");
5
+ const ManifestManager = require("../utils/manifest");
6
+ const AtomicWriter = require("../utils/atomic-writer");
7
+ const GitHelper = require("../utils/git-helper");
8
+ const { upsertManagedBlock } = require("../utils/managed-block");
9
+ const { cloneBranchAgentDir } = require("../utils");
10
+ const pkg = require("../../package.json");
11
+
12
+ const MANAGED_DIR_NAME = ".agents";
13
+ const LEGACY_DIR_NAME = ".codex";
14
+
15
+ class CodexAdapter extends BaseAdapter {
16
+ get targetName() {
17
+ return "codex";
18
+ }
19
+
20
+ getInstalledVersion() {
21
+ const managedManifest = path.join(this.workspaceRoot, MANAGED_DIR_NAME, "manifest.json");
22
+ const legacyManifest = path.join(this.workspaceRoot, LEGACY_DIR_NAME, "manifest.json");
23
+ const manifestPath = fs.existsSync(managedManifest) ? managedManifest : legacyManifest;
24
+
25
+ if (!fs.existsSync(manifestPath)) {
26
+ return null;
27
+ }
28
+
29
+ const manager = new ManifestManager(manifestPath, { target: "codex" });
30
+ const manifest = manager.load();
31
+ if (manifest && typeof manifest.kitVersion === "string" && manifest.kitVersion) {
32
+ return manifest.kitVersion;
33
+ }
34
+
35
+ return "1.0.0";
36
+ }
37
+
38
+ install(sourceDir) {
39
+ this._applyManagedFlow("install", sourceDir);
40
+ }
41
+
42
+ update(sourceDir) {
43
+ this._applyManagedFlow("update", sourceDir);
44
+ }
45
+
46
+ _applyManagedFlow(mode, sourceDir) {
47
+ const managedDir = path.join(this.workspaceRoot, MANAGED_DIR_NAME);
48
+ const legacyDir = path.join(this.workspaceRoot, LEGACY_DIR_NAME);
49
+ const managedExists = fs.existsSync(managedDir);
50
+ const legacyExists = fs.existsSync(legacyDir);
51
+ const hasExistingInstall = managedExists || legacyExists;
52
+ const currentDataDir = managedExists ? managedDir : legacyDir;
53
+
54
+ if (mode === "install" && hasExistingInstall && !this.options.force) {
55
+ throw new Error(`${MANAGED_DIR_NAME} 或 ${LEGACY_DIR_NAME} 目录已存在。请使用 --force 覆盖。`);
56
+ }
57
+ if (mode === "update" && !hasExistingInstall) {
58
+ throw new Error(`${MANAGED_DIR_NAME} 目录不存在,无法更新。请先执行 init --target codex。`);
59
+ }
60
+
61
+ const { installSource, sourceLabel, cleanup } = this._resolveInstallSource(sourceDir);
62
+ let stagingDir = "";
63
+ let incomingFiles = {};
64
+
65
+ try {
66
+ const staging = this._createStaging(installSource, sourceLabel);
67
+ stagingDir = staging.stagingDir;
68
+ incomingFiles = staging.incomingFiles;
69
+
70
+ if (this.options.dryRun) {
71
+ this.log(`[dry-run] 将原子更新: ${managedDir}`);
72
+ if (legacyExists) {
73
+ this.log(`[dry-run] 将删除遗留目录: ${legacyDir}`);
74
+ }
75
+ if (hasExistingInstall && this.options.force) {
76
+ const candidates = this._collectBackupCandidates(currentDataDir, incomingFiles);
77
+ if (candidates.fullSnapshot) {
78
+ this.log(`[dry-run] 发现旧版或缺失 manifest,覆盖前将备份整目录 ${path.basename(currentDataDir)}`);
79
+ } else if (candidates.files.length > 0) {
80
+ this.log(`[dry-run] 将备份 ${candidates.files.length} 个用户修改文件到 .agents-backup`);
81
+ }
82
+ }
83
+ this.log("[dry-run] 将更新工作区托管文件: AGENTS.md, antigravity.rules");
84
+ this._cleanupGitIgnore();
85
+ return;
86
+ }
87
+
88
+ if (hasExistingInstall && this.options.force) {
89
+ const candidates = this._collectBackupCandidates(currentDataDir, incomingFiles);
90
+ const backupResult = this._backupCandidates(currentDataDir, candidates);
91
+ if (backupResult) {
92
+ this.log(`📦 已备份覆盖前文件: ${backupResult.summary}`);
93
+ }
94
+ }
95
+
96
+ AtomicWriter.atomicCopyDir(stagingDir, managedDir, { logger: this.log.bind(this) });
97
+ this.log(`⚡️ ${MANAGED_DIR_NAME} 原子更新完成`);
98
+
99
+ if (legacyExists) {
100
+ fs.rmSync(legacyDir, { recursive: true, force: true });
101
+ this.log(`🧹 已移除遗留 ${LEGACY_DIR_NAME} 目录`);
102
+ }
103
+
104
+ this._syncWorkspaceManagedFiles(managedDir);
105
+ this._cleanupGitIgnore();
106
+
107
+ this.log(`✅ [Codex] ${mode === "install" ? "安装" : "更新"}完成`);
108
+ } finally {
109
+ if (stagingDir) {
110
+ fs.rmSync(stagingDir, { recursive: true, force: true });
111
+ }
112
+ if (cleanup) {
113
+ cleanup();
114
+ }
115
+ }
116
+ }
117
+
118
+ _resolveInstallSource(sourceDir) {
119
+ let installSource = sourceDir;
120
+ let cleanup = null;
121
+ let sourceLabel = this.options.branch ? `branch:${this.options.branch}` : "bundled";
122
+
123
+ if (this.options.branch) {
124
+ const remote = cloneBranchAgentDir(this.options.branch, {
125
+ quiet: this.options.quiet,
126
+ logger: this.log.bind(this),
127
+ });
128
+ installSource = remote.agentDir;
129
+ cleanup = remote.cleanup;
130
+ }
131
+
132
+ const CodexBuilder = require("../core/builder");
133
+ let buildTemp = "";
134
+
135
+ const hasAgentDir = fs.existsSync(path.join(installSource, ".agent"));
136
+ const hasSkillsDir = fs.existsSync(path.join(installSource, "skills"));
137
+ const isCodexPrebuilt = fs.existsSync(path.join(installSource, "manifest.json"));
138
+
139
+ if (!isCodexPrebuilt) {
140
+ if (hasSkillsDir) {
141
+ this.log("🛠️ 检测到 .agent 内容格式,正在构建 Codex 结构...");
142
+ const mockRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-root-"));
143
+ const mockAgent = path.join(mockRoot, ".agent");
144
+ this._copyDir(installSource, mockAgent);
145
+
146
+ buildTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-out-"));
147
+ CodexBuilder.build(mockRoot, buildTemp);
148
+ installSource = buildTemp;
149
+ sourceLabel = `${sourceLabel}:compiled`;
150
+
151
+ const previousCleanup = cleanup;
152
+ cleanup = () => {
153
+ if (previousCleanup) previousCleanup();
154
+ fs.rmSync(mockRoot, { recursive: true, force: true });
155
+ fs.rmSync(buildTemp, { recursive: true, force: true });
156
+ };
157
+ } else if (hasAgentDir) {
158
+ this.log("🛠️ 检测到仓库根目录格式,正在构建 Codex 结构...");
159
+ buildTemp = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-build-out-"));
160
+ CodexBuilder.build(installSource, buildTemp);
161
+ installSource = buildTemp;
162
+ sourceLabel = `${sourceLabel}:compiled`;
163
+
164
+ const previousCleanup = cleanup;
165
+ cleanup = () => {
166
+ if (previousCleanup) previousCleanup();
167
+ fs.rmSync(buildTemp, { recursive: true, force: true });
168
+ };
169
+ }
170
+ }
171
+
172
+ return { installSource, sourceLabel, cleanup };
173
+ }
174
+
175
+ _createStaging(installSource, sourceLabel) {
176
+ const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-codex-stage-"));
177
+ this._copyDir(installSource, stagingDir);
178
+
179
+ const manifestPath = path.join(stagingDir, "manifest.json");
180
+ const manager = new ManifestManager(manifestPath, {
181
+ target: "codex",
182
+ kitVersion: pkg.version,
183
+ });
184
+ manager.manifest.files = ManifestManager.generateFileEntriesFromDir(stagingDir, {
185
+ baseDir: stagingDir,
186
+ sourcePrefix: sourceLabel,
187
+ });
188
+ manager.save();
189
+
190
+ return {
191
+ stagingDir,
192
+ incomingFiles: manager.manifest.files,
193
+ };
194
+ }
195
+
196
+ _collectBackupCandidates(targetDir, incomingFiles) {
197
+ const manifestPath = path.join(targetDir, "manifest.json");
198
+ if (!fs.existsSync(manifestPath)) {
199
+ return { fullSnapshot: true, files: [] };
200
+ }
201
+
202
+ try {
203
+ const raw = fs.readFileSync(manifestPath, "utf8");
204
+ const parsed = JSON.parse(raw);
205
+ const files = parsed && typeof parsed.files === "object" ? parsed.files : null;
206
+ if (!files || Object.keys(files).length === 0) {
207
+ return { fullSnapshot: true, files: [] };
208
+ }
209
+ } catch (err) {
210
+ return { fullSnapshot: true, files: [] };
211
+ }
212
+
213
+ const manager = new ManifestManager(manifestPath, { target: "codex" });
214
+ manager.load();
215
+
216
+ return {
217
+ fullSnapshot: false,
218
+ files: manager.collectSmartOverwriteConflicts(targetDir, incomingFiles),
219
+ };
220
+ }
221
+
222
+ _backupCandidates(targetDir, candidates) {
223
+ if (!candidates.fullSnapshot && candidates.files.length === 0) {
224
+ return null;
225
+ }
226
+
227
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
228
+ const backupRoot = path.join(this.workspaceRoot, ".agents-backup", timestamp);
229
+ fs.mkdirSync(backupRoot, { recursive: true });
230
+
231
+ if (candidates.fullSnapshot) {
232
+ const snapshotDir = path.join(backupRoot, "full-snapshot");
233
+ this._copyDir(targetDir, snapshotDir);
234
+ return { summary: `${backupRoot} (full snapshot)` };
235
+ }
236
+
237
+ for (const relPath of candidates.files) {
238
+ const src = path.join(targetDir, relPath);
239
+ if (!fs.existsSync(src)) {
240
+ continue;
241
+ }
242
+ const dest = path.join(backupRoot, relPath);
243
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
244
+ fs.copyFileSync(src, dest);
245
+ }
246
+
247
+ return { summary: `${backupRoot} (${candidates.files.length} files)` };
248
+ }
249
+
250
+ _syncWorkspaceManagedFiles(managedDir) {
251
+ const managedAgentsPath = path.join(managedDir, "AGENTS.md");
252
+ const managedRulesPath = path.join(managedDir, "antigravity.rules");
253
+
254
+ if (fs.existsSync(managedAgentsPath)) {
255
+ const body = fs.readFileSync(managedAgentsPath, "utf8");
256
+ const outputPath = path.join(this.workspaceRoot, "AGENTS.md");
257
+ const result = upsertManagedBlock(outputPath, "codex-core-rules", body, {
258
+ dryRun: this.options.dryRun,
259
+ });
260
+ this.log(`🧩 AGENTS.md 托管区块同步: ${result.action}`);
261
+ }
262
+
263
+ if (fs.existsSync(managedRulesPath)) {
264
+ const body = fs.readFileSync(managedRulesPath, "utf8");
265
+ const outputPath = path.join(this.workspaceRoot, "antigravity.rules");
266
+ const result = upsertManagedBlock(outputPath, "codex-risk-controls", body, {
267
+ dryRun: this.options.dryRun,
268
+ });
269
+ this.log(`🧩 antigravity.rules 托管区块同步: ${result.action}`);
270
+ }
271
+ }
272
+
273
+ _cleanupGitIgnore() {
274
+ const cleanupResult = GitHelper.removeIgnoreRules(this.workspaceRoot, [MANAGED_DIR_NAME, LEGACY_DIR_NAME], this.options);
275
+ if (cleanupResult.removedCount > 0) {
276
+ this.log(`🧹 已从 .gitignore 移除 ${cleanupResult.removedCount} 条规则`);
277
+ }
278
+ }
279
+
280
+ _copyDir(src, dest) {
281
+ fs.mkdirSync(dest, { recursive: true });
282
+ const entries = fs.readdirSync(src, { withFileTypes: true });
283
+ for (const entry of entries) {
284
+ const srcPath = path.join(src, entry.name);
285
+ const destPath = path.join(dest, entry.name);
286
+ if (entry.isDirectory()) {
287
+ this._copyDir(srcPath, destPath);
288
+ } else {
289
+ fs.copyFileSync(srcPath, destPath);
290
+ }
291
+ }
292
+ }
293
+
294
+ checkIntegrity() {
295
+ const managedDir = path.join(this.workspaceRoot, MANAGED_DIR_NAME);
296
+ const legacyDir = path.join(this.workspaceRoot, LEGACY_DIR_NAME);
297
+ const result = { status: "ok", issues: [] };
298
+
299
+ if (!fs.existsSync(managedDir)) {
300
+ if (fs.existsSync(legacyDir)) {
301
+ return {
302
+ status: "broken",
303
+ issues: [`Legacy: ${LEGACY_DIR_NAME} directory detected; run update to migrate to ${MANAGED_DIR_NAME}`],
304
+ };
305
+ }
306
+ return { status: "missing", issues: [`Critical: ${MANAGED_DIR_NAME} directory missing`] };
307
+ }
308
+
309
+ const manifestPath = path.join(managedDir, "manifest.json");
310
+ if (!fs.existsSync(manifestPath)) {
311
+ result.status = "broken";
312
+ result.issues.push("Critical: manifest.json missing");
313
+ return result;
314
+ }
315
+
316
+ if (fs.existsSync(legacyDir)) {
317
+ result.status = "broken";
318
+ result.issues.push(`Legacy: ${LEGACY_DIR_NAME} directory should be removed`);
319
+ }
320
+
321
+ const manager = new ManifestManager(manifestPath, { target: "codex" });
322
+ manager.load();
323
+ const drift = manager.checkDrift(managedDir);
324
+
325
+ if (drift.missing.length > 0) {
326
+ result.status = "broken";
327
+ for (const relPath of drift.missing) {
328
+ result.issues.push(`Missing managed file: ${relPath}`);
329
+ }
330
+ }
331
+
332
+ if (drift.modified.length > 0) {
333
+ if (result.status === "ok") {
334
+ result.status = "drift";
335
+ }
336
+ for (const relPath of drift.modified) {
337
+ result.issues.push(`File modified (Drift): ${relPath}`);
338
+ }
339
+ }
340
+
341
+ return result;
342
+ }
343
+
344
+ fixIntegrity() {
345
+ const managedDir = path.join(this.workspaceRoot, MANAGED_DIR_NAME);
346
+ const legacyDir = path.join(this.workspaceRoot, LEGACY_DIR_NAME);
347
+ const fixes = [];
348
+
349
+ if (!fs.existsSync(managedDir)) {
350
+ if (fs.existsSync(legacyDir)) {
351
+ AtomicWriter.atomicCopyDir(legacyDir, managedDir, { logger: this.log.bind(this) });
352
+ fs.rmSync(legacyDir, { recursive: true, force: true });
353
+ fixes.push(`migrated ${LEGACY_DIR_NAME} to ${MANAGED_DIR_NAME}`);
354
+ } else {
355
+ return {
356
+ fixed: false,
357
+ summary: `缺少 ${MANAGED_DIR_NAME},无法自动修复。请执行 ag-kit init --target codex 或 ag-kit update。`,
358
+ };
359
+ }
360
+ }
361
+
362
+ if (fs.existsSync(legacyDir)) {
363
+ fs.rmSync(legacyDir, { recursive: true, force: true });
364
+ fixes.push(`removed stale ${LEGACY_DIR_NAME} directory`);
365
+ }
366
+
367
+ const manifestPath = path.join(managedDir, "manifest.json");
368
+ if (!fs.existsSync(manifestPath)) {
369
+ const manager = new ManifestManager(manifestPath, {
370
+ target: "codex",
371
+ kitVersion: pkg.version,
372
+ });
373
+ manager.manifest.files = ManifestManager.generateFileEntriesFromDir(managedDir, {
374
+ baseDir: managedDir,
375
+ sourcePrefix: "recovered",
376
+ });
377
+ manager.save();
378
+ fixes.push("regenerated manifest.json");
379
+ }
380
+
381
+ this._syncWorkspaceManagedFiles(managedDir);
382
+ this._cleanupGitIgnore();
383
+
384
+ return {
385
+ fixed: fixes.length > 0,
386
+ summary: fixes.length > 0 ? `Fixed: ${fixes.join(", ")}` : "No automatic fixes available.",
387
+ };
388
+ }
389
+ }
390
+
391
+ module.exports = CodexAdapter;
@@ -0,0 +1,137 @@
1
+ const fs = require("fs");
2
+ const os = require("os");
3
+ const path = require("path");
4
+ const BaseAdapter = require("./base");
5
+ const { cloneBranchAgentDir } = require("../utils");
6
+ const GitHelper = require("../utils/git-helper");
7
+
8
+ class GeminiAdapter extends BaseAdapter {
9
+ get targetName() {
10
+ return "gemini";
11
+ }
12
+
13
+ getInstalledVersion() {
14
+ // In v1, version was not strictly tracked per target in a file.
15
+ // We assume check existence of .agent/agents directory.
16
+ const agentDir = path.join(this.workspaceRoot, ".agent");
17
+ if (fs.existsSync(agentDir)) {
18
+ return "2.0.1"; // Default to current version if exists
19
+ }
20
+ return null;
21
+ }
22
+
23
+ _copyDir(src, dest) {
24
+ fs.mkdirSync(dest, { recursive: true });
25
+ const entries = fs.readdirSync(src, { withFileTypes: true });
26
+
27
+ for (const entry of entries) {
28
+ const srcPath = path.join(src, entry.name);
29
+ const destPath = path.join(dest, entry.name);
30
+
31
+ if (entry.isDirectory()) {
32
+ this._copyDir(srcPath, destPath);
33
+ } else {
34
+ fs.copyFileSync(srcPath, destPath);
35
+ }
36
+ }
37
+ }
38
+
39
+ // Remove old _removeAgentIgnoreRules implementation
40
+ _removeAgentIgnoreRules() {
41
+ // Deprecated, using GitHelper
42
+ return { fileExists: false, removedCount: 0 };
43
+ }
44
+
45
+ _samePath(a, b) {
46
+ const left = path.resolve(a);
47
+ const right = path.resolve(b);
48
+ if (process.platform === "win32") {
49
+ return left.toLowerCase() === right.toLowerCase();
50
+ }
51
+ return left === right;
52
+ }
53
+
54
+ install(sourceDir) {
55
+ let installSource = sourceDir;
56
+ let cleanup = null;
57
+
58
+ if (this.options.branch) {
59
+ const remote = cloneBranchAgentDir(this.options.branch, {
60
+ quiet: this.options.quiet,
61
+ logger: this.log.bind(this)
62
+ });
63
+ installSource = remote.agentDir;
64
+ cleanup = remote.cleanup;
65
+ }
66
+
67
+ try {
68
+ const targetDir = path.join(this.workspaceRoot, ".agent");
69
+
70
+ if (!fs.existsSync(installSource)) {
71
+ throw new Error(`未找到模板目录: ${installSource}`);
72
+ }
73
+
74
+ if (this._samePath(installSource, targetDir) && !this.options.dryRun) {
75
+ const tempSource = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-gemini-src-"));
76
+ this._copyDir(installSource, tempSource);
77
+ const oldCleanup = cleanup;
78
+ cleanup = () => {
79
+ if (oldCleanup) oldCleanup();
80
+ fs.rmSync(tempSource, { recursive: true, force: true });
81
+ };
82
+ installSource = tempSource;
83
+ this.log("ℹ️ 检测到源目录与目标目录相同,已切换为临时副本执行覆盖更新。");
84
+ }
85
+
86
+ // Log logic handled by caller mostly, but validation here
87
+ if (fs.existsSync(targetDir)) {
88
+ if (!this.options.force) {
89
+ throw new Error(".agent 目录已存在。请使用 --force 覆盖。");
90
+ }
91
+ if (this.options.dryRun) {
92
+ this.log(`[dry-run] 将删除: ${targetDir}`);
93
+ } else {
94
+ fs.rmSync(targetDir, { recursive: true, force: true });
95
+ this.log(`🗑️ 已删除旧目录: ${targetDir}`);
96
+ }
97
+ }
98
+
99
+ if (this.options.dryRun) {
100
+ this.log(`[dry-run] 将复制: ${installSource} -> ${targetDir}`);
101
+ const cleanupGit = GitHelper.removeIgnoreRules(this.workspaceRoot, [".agent"], this.options);
102
+ if(cleanupGit.removedCount > 0) this.log(`[dry-run] 将移除 .gitignore 规则`);
103
+ return;
104
+ }
105
+
106
+ fs.mkdirSync(this.workspaceRoot, { recursive: true });
107
+ this._copyDir(installSource, targetDir);
108
+ const cleanupResult = GitHelper.removeIgnoreRules(this.workspaceRoot, [".agent"], this.options);
109
+ if(cleanupResult.removedCount > 0) {
110
+ this.log(`🧹 已从 .gitignore 移除 ${cleanupResult.removedCount} 条规则`);
111
+ }
112
+
113
+ this.log("✅ [Gemini] 安装完成 (.agent)");
114
+ } finally {
115
+ if (cleanup) cleanup();
116
+ }
117
+ }
118
+
119
+ update(sourceDir) {
120
+ this.options.force = true; // Updates are forced installs
121
+ this.install(sourceDir);
122
+ }
123
+
124
+ checkIntegrity() {
125
+ const agentDir = path.join(this.workspaceRoot, ".agent");
126
+ if (!fs.existsSync(agentDir)) {
127
+ return { status: "missing", issues: [".agent directory missing"] };
128
+ }
129
+ return { status: "ok", issues: [] };
130
+ }
131
+
132
+ fixIntegrity() {
133
+ return { fixed: false, summary: "Gemini Adapter does not support self-healing yet. Please run update." };
134
+ }
135
+ }
136
+
137
+ module.exports = GeminiAdapter;