@mison/ag-kit-cn 2.0.1 → 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/{.agent → .agents}/agents/frontend-specialist.md +2 -2
- package/{.agent → .agents}/agents/orchestrator.md +1 -3
- package/.agents/mcp_config.json +22 -0
- package/{.agent → .agents}/rules/GEMINI.md +2 -2
- package/{.agent → .agents}/skills/api-patterns/SKILL.md +2 -2
- package/{.agent → .agents}/skills/app-builder/project-detection.md +1 -1
- package/{.agent → .agents}/skills/nextjs-react-expert/SKILL.md +2 -2
- package/{.agent → .agents}/skills/parallel-agents/SKILL.md +0 -1
- package/.agents/skills/refactoring-patterns/SKILL.md +43 -0
- package/{.agent → .agents}/workflows/create.md +1 -1
- package/CHANGELOG.md +21 -0
- package/README.md +54 -8
- package/bin/adapters/codex.js +29 -6
- package/bin/adapters/gemini.js +23 -3
- package/bin/ag-kit.js +512 -17
- package/bin/core/builder.js +1 -1
- package/bin/core/resource-loader.js +2 -2
- package/bin/utils/manifest.js +3 -0
- package/bin/utils.js +10 -3
- package/docs/PLAN.md +39 -0
- package/docs/TECH.md +136 -0
- package/package.json +12 -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/.agent/mcp_config.json +0 -12
- package/docs/codex-rules-template.md +0 -36
- package/docs/mapping-spec.md +0 -68
- package/docs/multi-target-adapter.md +0 -80
- package/docs/official/README.md +0 -53
- 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/sources-index.md +0 -32
- package/docs/operations.md +0 -145
- 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/game-developer.md +0 -0
- /package/{.agent → .agents}/agents/mobile-developer.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}/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/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/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/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/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/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/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/ag-kit.js
CHANGED
|
@@ -5,19 +5,51 @@ const os = require("os");
|
|
|
5
5
|
const path = require("path");
|
|
6
6
|
|
|
7
7
|
const pkg = require("../package.json");
|
|
8
|
-
const { readGlobalNpmDependencies } = require("./utils");
|
|
8
|
+
const { readGlobalNpmDependencies, cloneBranchAgentDir } = require("./utils");
|
|
9
|
+
const ManifestManager = require("./utils/manifest");
|
|
10
|
+
const AtomicWriter = require("./utils/atomic-writer");
|
|
11
|
+
const CodexBuilder = require("./core/builder");
|
|
9
12
|
const GeminiAdapter = require("./adapters/gemini");
|
|
10
13
|
const CodexAdapter = require("./adapters/codex");
|
|
11
14
|
const { selectTargets } = require("./interactive");
|
|
12
15
|
|
|
13
|
-
const BUNDLED_AGENT_DIR = path.resolve(__dirname, "../.
|
|
16
|
+
const BUNDLED_AGENT_DIR = path.resolve(__dirname, "../.agents");
|
|
14
17
|
const WORKSPACE_INDEX_VERSION = 2;
|
|
15
18
|
const UPSTREAM_GLOBAL_PACKAGE = "@vudovn/ag-kit";
|
|
16
19
|
const TOOLKIT_PACKAGE_NAMES = new Set(["@mison/ag-kit-cn", "antigravity-kit-cn", "antigravity-kit"]);
|
|
17
20
|
const SUPPORTED_TARGETS = ["gemini", "codex"];
|
|
21
|
+
const LEGACY_INDEX_TARGET_ALIASES = {
|
|
22
|
+
full: "gemini",
|
|
23
|
+
};
|
|
24
|
+
const GLOBAL_TARGET_DESTINATIONS = {
|
|
25
|
+
codex: [
|
|
26
|
+
{
|
|
27
|
+
id: "codex",
|
|
28
|
+
rootParts: [".codex"],
|
|
29
|
+
skillsParts: [".codex", "skills"],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
gemini: [
|
|
33
|
+
{
|
|
34
|
+
id: "gemini-cli",
|
|
35
|
+
rootParts: [".gemini", "skills"],
|
|
36
|
+
skillsParts: [".gemini", "skills"],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "antigravity",
|
|
40
|
+
rootParts: [".gemini", "antigravity"],
|
|
41
|
+
skillsParts: [".gemini", "antigravity", "skills"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
18
45
|
const INDEX_LOCK_RETRY_MS = 50;
|
|
19
46
|
const INDEX_LOCK_TIMEOUT_MS = 3000;
|
|
20
47
|
const INDEX_LOCK_STALE_MS = 30000;
|
|
48
|
+
const QUIET_STATUS_EXIT_CODES = {
|
|
49
|
+
installed: 0,
|
|
50
|
+
broken: 1,
|
|
51
|
+
missing: 2,
|
|
52
|
+
};
|
|
21
53
|
|
|
22
54
|
function nowISO() {
|
|
23
55
|
return new Date().toISOString();
|
|
@@ -40,12 +72,74 @@ function createEmptyWorkspaceIndex() {
|
|
|
40
72
|
};
|
|
41
73
|
}
|
|
42
74
|
|
|
75
|
+
function resolveGlobalRootDir() {
|
|
76
|
+
const customRoot = process.env.AG_KIT_GLOBAL_ROOT;
|
|
77
|
+
if (typeof customRoot === "string" && customRoot.trim()) {
|
|
78
|
+
return path.resolve(process.cwd(), customRoot);
|
|
79
|
+
}
|
|
80
|
+
return os.homedir();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getGlobalDestinations(targetName, globalRoot = resolveGlobalRootDir()) {
|
|
84
|
+
const config = GLOBAL_TARGET_DESTINATIONS[targetName];
|
|
85
|
+
if (!config) {
|
|
86
|
+
throw new Error(`未知目标: ${targetName}`);
|
|
87
|
+
}
|
|
88
|
+
return config.map((item) => ({
|
|
89
|
+
...item,
|
|
90
|
+
targetName,
|
|
91
|
+
rootDir: path.join(globalRoot, ...item.rootParts),
|
|
92
|
+
skillsRoot: path.join(globalRoot, ...item.skillsParts),
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function listGlobalDestinations(globalRoot = resolveGlobalRootDir()) {
|
|
97
|
+
return Object.keys(GLOBAL_TARGET_DESTINATIONS).flatMap((targetName) => getGlobalDestinations(targetName, globalRoot));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function resolveGlobalBackupRoot(timestamp) {
|
|
101
|
+
const globalRoot = resolveGlobalRootDir();
|
|
102
|
+
return path.join(globalRoot, ".ag-kit", "backups", "global", timestamp);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function copyDirRecursive(src, dest) {
|
|
106
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
107
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
const srcPath = path.join(src, entry.name);
|
|
110
|
+
const destPath = path.join(dest, entry.name);
|
|
111
|
+
if (entry.isDirectory()) {
|
|
112
|
+
copyDirRecursive(srcPath, destPath);
|
|
113
|
+
} else {
|
|
114
|
+
fs.copyFileSync(srcPath, destPath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function areDirectoriesEqual(leftDir, rightDir) {
|
|
120
|
+
const left = ManifestManager.generateFromDir(leftDir);
|
|
121
|
+
const right = ManifestManager.generateFromDir(rightDir);
|
|
122
|
+
const leftKeys = Object.keys(left);
|
|
123
|
+
const rightKeys = Object.keys(right);
|
|
124
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
for (const key of leftKeys) {
|
|
128
|
+
if (left[key] !== right[key]) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
43
135
|
function printUsage() {
|
|
44
136
|
console.log("用法:");
|
|
45
137
|
console.log(" ag-kit init [--force] [--path <dir>] [--branch <name>] [--target <name>|--targets <a,b>] [--non-interactive] [--no-index] [--quiet] [--dry-run]");
|
|
46
138
|
console.log(" ag-kit update [--path <dir>] [--branch <name>] [--target <name>|--targets <a,b>] [--no-index] [--quiet] [--dry-run]");
|
|
47
139
|
console.log(" ag-kit update-all [--branch <name>] [--targets <a,b>] [--prune-missing] [--quiet] [--dry-run]");
|
|
48
140
|
console.log(" ag-kit doctor [--path <dir>] [--target <name>|--targets <a,b>] [--fix] [--quiet]");
|
|
141
|
+
console.log(" ag-kit global sync [--target <name>|--targets <a,b>] [--branch <name>] [--quiet] [--dry-run] # 默认同步 codex + gemini(cli+antigravity)");
|
|
142
|
+
console.log(" ag-kit global status [--quiet]");
|
|
49
143
|
console.log(" ag-kit exclude list [--quiet]");
|
|
50
144
|
console.log(" ag-kit exclude add --path <dir> [--dry-run] [--quiet]");
|
|
51
145
|
console.log(" ag-kit exclude remove --path <dir> [--dry-run] [--quiet]");
|
|
@@ -79,12 +173,12 @@ function parseArgs(argv) {
|
|
|
79
173
|
const providedFlags = [];
|
|
80
174
|
|
|
81
175
|
let startIndex = 1;
|
|
82
|
-
if (command === "exclude") {
|
|
176
|
+
if (command === "exclude" || command === "global") {
|
|
83
177
|
if (argv.length > 1 && !argv[1].startsWith("--")) {
|
|
84
178
|
options.subcommand = argv[1];
|
|
85
179
|
startIndex = 2;
|
|
86
180
|
} else {
|
|
87
|
-
options.subcommand = "list";
|
|
181
|
+
options.subcommand = command === "global" ? "status" : "list";
|
|
88
182
|
startIndex = 1;
|
|
89
183
|
}
|
|
90
184
|
}
|
|
@@ -151,6 +245,8 @@ const COMMAND_ALLOWED_FLAGS = {
|
|
|
151
245
|
"update-all": ["--branch", "--targets", "--prune-missing", "--quiet", "--dry-run"],
|
|
152
246
|
doctor: ["--path", "--target", "--targets", "--fix", "--quiet"],
|
|
153
247
|
status: ["--path", "--quiet"],
|
|
248
|
+
"global:sync": ["--target", "--targets", "--branch", "--quiet", "--dry-run"],
|
|
249
|
+
"global:status": ["--quiet"],
|
|
154
250
|
"exclude:list": ["--quiet"],
|
|
155
251
|
"exclude:add": ["--path", "--dry-run", "--quiet"],
|
|
156
252
|
"exclude:remove": ["--path", "--dry-run", "--quiet"],
|
|
@@ -162,6 +258,11 @@ function resolveAllowedFlags(command, options) {
|
|
|
162
258
|
const key = `exclude:${subcommand}`;
|
|
163
259
|
return COMMAND_ALLOWED_FLAGS[key] || null;
|
|
164
260
|
}
|
|
261
|
+
if (command === "global") {
|
|
262
|
+
const subcommand = String(options.subcommand || "status").toLowerCase();
|
|
263
|
+
const key = `global:${subcommand}`;
|
|
264
|
+
return COMMAND_ALLOWED_FLAGS[key] || null;
|
|
265
|
+
}
|
|
165
266
|
return COMMAND_ALLOWED_FLAGS[command] || null;
|
|
166
267
|
}
|
|
167
268
|
|
|
@@ -170,6 +271,10 @@ function resolveCommandLabel(command, options) {
|
|
|
170
271
|
const subcommand = String(options.subcommand || "list").toLowerCase();
|
|
171
272
|
return `exclude ${subcommand}`;
|
|
172
273
|
}
|
|
274
|
+
if (command === "global") {
|
|
275
|
+
const subcommand = String(options.subcommand || "status").toLowerCase();
|
|
276
|
+
return `global ${subcommand}`;
|
|
277
|
+
}
|
|
173
278
|
return command;
|
|
174
279
|
}
|
|
175
280
|
|
|
@@ -341,13 +446,34 @@ function normalizeTargetState(value) {
|
|
|
341
446
|
};
|
|
342
447
|
}
|
|
343
448
|
|
|
449
|
+
function normalizeIndexTargetName(targetName) {
|
|
450
|
+
if (typeof targetName !== "string") {
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
const normalized = targetName.trim().toLowerCase();
|
|
454
|
+
if (!normalized) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
if (Object.prototype.hasOwnProperty.call(LEGACY_INDEX_TARGET_ALIASES, normalized)) {
|
|
458
|
+
return LEGACY_INDEX_TARGET_ALIASES[normalized];
|
|
459
|
+
}
|
|
460
|
+
if (SUPPORTED_TARGETS.includes(normalized)) {
|
|
461
|
+
return normalized;
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
|
|
344
466
|
function normalizeWorkspaceRecordV2(item, normalizedPath) {
|
|
345
467
|
const targets = {};
|
|
346
468
|
if (item && item.targets && typeof item.targets === "object") {
|
|
347
469
|
for (const [targetName, state] of Object.entries(item.targets)) {
|
|
470
|
+
const normalizedTargetName = normalizeIndexTargetName(targetName);
|
|
471
|
+
if (!normalizedTargetName) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
348
474
|
const normalizedState = normalizeTargetState(state);
|
|
349
475
|
if (normalizedState) {
|
|
350
|
-
targets[
|
|
476
|
+
targets[normalizedTargetName] = normalizedState;
|
|
351
477
|
}
|
|
352
478
|
}
|
|
353
479
|
}
|
|
@@ -669,7 +795,12 @@ function maybeWarnUpstreamGlobalConflict(command, options) {
|
|
|
669
795
|
if (process.env.AG_KIT_SKIP_UPSTREAM_CHECK === "1") {
|
|
670
796
|
return;
|
|
671
797
|
}
|
|
672
|
-
|
|
798
|
+
const shouldWarn =
|
|
799
|
+
command === "init"
|
|
800
|
+
|| command === "update"
|
|
801
|
+
|| command === "update-all"
|
|
802
|
+
|| (command === "global" && String(options.subcommand || "").toLowerCase() === "sync");
|
|
803
|
+
if (!shouldWarn) {
|
|
673
804
|
return;
|
|
674
805
|
}
|
|
675
806
|
|
|
@@ -685,6 +816,7 @@ function maybeWarnUpstreamGlobalConflict(command, options) {
|
|
|
685
816
|
log(options, `⚠️ 检测到全局已安装上游英文版 ${UPSTREAM_GLOBAL_PACKAGE}。`);
|
|
686
817
|
log(options, "⚠️ 上游英文版与当前中文版共用 `ag-kit` 命令名,后安装者会覆盖命令入口。");
|
|
687
818
|
log(options, `👉 建议执行: npm uninstall -g ${UPSTREAM_GLOBAL_PACKAGE}`);
|
|
819
|
+
log(options, "ℹ️ 若你通过 bun install -g 安装,Bun 默认会阻止本包 postinstall;因此这里会在首次执行 CLI 时再次提醒。");
|
|
688
820
|
}
|
|
689
821
|
|
|
690
822
|
function normalizeTargets(rawTargets) {
|
|
@@ -735,6 +867,100 @@ function isTargetInstalled(workspaceRoot, targetName) {
|
|
|
735
867
|
return false;
|
|
736
868
|
}
|
|
737
869
|
|
|
870
|
+
function setQuietStatusExitCode(state) {
|
|
871
|
+
process.exitCode = Object.prototype.hasOwnProperty.call(QUIET_STATUS_EXIT_CODES, state)
|
|
872
|
+
? QUIET_STATUS_EXIT_CODES[state]
|
|
873
|
+
: 1;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
function normalizeIntegrityState(result) {
|
|
877
|
+
if (!result || result.status === "missing") {
|
|
878
|
+
return "missing";
|
|
879
|
+
}
|
|
880
|
+
if (result.status === "ok") {
|
|
881
|
+
return "installed";
|
|
882
|
+
}
|
|
883
|
+
return "broken";
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
function evaluateWorkspaceState(workspaceRoot, options) {
|
|
887
|
+
const targets = detectInstalledTargets(workspaceRoot);
|
|
888
|
+
if (targets.length === 0) {
|
|
889
|
+
return {
|
|
890
|
+
state: "missing",
|
|
891
|
+
targets: [],
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
const targetStates = targets.map((targetName) => {
|
|
896
|
+
const adapter = createAdapter(targetName, workspaceRoot, {
|
|
897
|
+
...options,
|
|
898
|
+
quiet: true,
|
|
899
|
+
});
|
|
900
|
+
const integrity = adapter.checkIntegrity();
|
|
901
|
+
return {
|
|
902
|
+
targetName,
|
|
903
|
+
state: normalizeIntegrityState(integrity),
|
|
904
|
+
integrity,
|
|
905
|
+
version: typeof adapter.getInstalledVersion === "function" ? adapter.getInstalledVersion() : null,
|
|
906
|
+
};
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
const hasIssue = targetStates.some((item) => item.state !== "installed");
|
|
910
|
+
return {
|
|
911
|
+
state: hasIssue ? "broken" : "installed",
|
|
912
|
+
targets: targetStates,
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
function evaluateGlobalState() {
|
|
917
|
+
const globalRoot = resolveGlobalRootDir();
|
|
918
|
+
const targetStates = listGlobalDestinations(globalRoot).map((destination) => {
|
|
919
|
+
const rootExists = fs.existsSync(destination.rootDir);
|
|
920
|
+
const skillsExists = fs.existsSync(destination.skillsRoot);
|
|
921
|
+
const skillsCount = skillsExists ? countSkillsRecursive(destination.skillsRoot) : 0;
|
|
922
|
+
let state = "missing";
|
|
923
|
+
const issues = [];
|
|
924
|
+
|
|
925
|
+
if (rootExists || skillsExists) {
|
|
926
|
+
if (!skillsExists) {
|
|
927
|
+
state = "broken";
|
|
928
|
+
issues.push("Skills 根目录缺失");
|
|
929
|
+
} else if (skillsCount === 0) {
|
|
930
|
+
state = "broken";
|
|
931
|
+
issues.push("未检测到任何 SKILL.md");
|
|
932
|
+
} else {
|
|
933
|
+
state = "installed";
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
return {
|
|
938
|
+
targetName: destination.id,
|
|
939
|
+
family: destination.targetName,
|
|
940
|
+
state,
|
|
941
|
+
rootDir: destination.rootDir,
|
|
942
|
+
skillsRoot: destination.skillsRoot,
|
|
943
|
+
skillsCount,
|
|
944
|
+
issues,
|
|
945
|
+
};
|
|
946
|
+
}).filter((item) => item.state !== "missing");
|
|
947
|
+
|
|
948
|
+
if (targetStates.length === 0) {
|
|
949
|
+
return {
|
|
950
|
+
globalRoot,
|
|
951
|
+
state: "missing",
|
|
952
|
+
targets: [],
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
const hasIssue = targetStates.some((item) => item.state !== "installed");
|
|
957
|
+
return {
|
|
958
|
+
globalRoot,
|
|
959
|
+
state: hasIssue ? "broken" : "installed",
|
|
960
|
+
targets: targetStates,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
738
964
|
function createAdapter(targetName, workspaceRoot, options) {
|
|
739
965
|
if (targetName === "gemini") {
|
|
740
966
|
return new GeminiAdapter(workspaceRoot, options);
|
|
@@ -776,6 +1002,248 @@ function resolveTargetsForUpdate(workspaceRoot, options) {
|
|
|
776
1002
|
return detectInstalledTargets(workspaceRoot);
|
|
777
1003
|
}
|
|
778
1004
|
|
|
1005
|
+
function resolveTargetsForGlobalSync(options) {
|
|
1006
|
+
const requested = normalizeTargets(options.targets);
|
|
1007
|
+
if (requested.length > 0) {
|
|
1008
|
+
return requested;
|
|
1009
|
+
}
|
|
1010
|
+
// 保持 global sync 简洁:默认同步 codex + gemini;其中 gemini 会展开为 gemini-cli 与 antigravity。
|
|
1011
|
+
return ["codex", "gemini"];
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
function resolveAgentInstallSource(options) {
|
|
1015
|
+
let agentDir = BUNDLED_AGENT_DIR;
|
|
1016
|
+
let cleanup = null;
|
|
1017
|
+
let sourceLabel = "bundled";
|
|
1018
|
+
|
|
1019
|
+
if (options.branch) {
|
|
1020
|
+
const remote = cloneBranchAgentDir(options.branch, {
|
|
1021
|
+
quiet: options.quiet,
|
|
1022
|
+
logger: log.bind(null, options),
|
|
1023
|
+
});
|
|
1024
|
+
agentDir = remote.agentDir;
|
|
1025
|
+
cleanup = remote.cleanup;
|
|
1026
|
+
sourceLabel = `branch:${options.branch}`;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
if (!fs.existsSync(agentDir) && !options.branch) {
|
|
1030
|
+
const legacyDir = path.resolve(__dirname, "../.agent");
|
|
1031
|
+
if (fs.existsSync(legacyDir)) {
|
|
1032
|
+
agentDir = legacyDir;
|
|
1033
|
+
sourceLabel = "bundled:legacy";
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
if (!fs.existsSync(agentDir)) {
|
|
1038
|
+
throw new Error(`未找到模板目录: ${agentDir}`);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
return { agentDir, cleanup, sourceLabel };
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function listSkillDirectories(skillsRoot) {
|
|
1045
|
+
if (!fs.existsSync(skillsRoot)) {
|
|
1046
|
+
return [];
|
|
1047
|
+
}
|
|
1048
|
+
return fs
|
|
1049
|
+
.readdirSync(skillsRoot, { withFileTypes: true })
|
|
1050
|
+
.filter((entry) => entry.isDirectory())
|
|
1051
|
+
.map((entry) => entry.name)
|
|
1052
|
+
.filter((name) => fs.existsSync(path.join(skillsRoot, name, "SKILL.md")));
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
function backupSkillDirectory(targetName, skillName, sourceDir, timestamp, options) {
|
|
1056
|
+
const backupRoot = resolveGlobalBackupRoot(timestamp);
|
|
1057
|
+
const backupDir = path.join(backupRoot, targetName, skillName);
|
|
1058
|
+
fs.mkdirSync(path.dirname(backupDir), { recursive: true });
|
|
1059
|
+
copyDirRecursive(sourceDir, backupDir);
|
|
1060
|
+
log(options, `📦 已备份 ${targetName} 全局 Skill: ${skillName} -> ${backupDir}`);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
function syncSkillDirectory(destination, srcDir, destDir, timestamp, options) {
|
|
1064
|
+
const exists = fs.existsSync(destDir);
|
|
1065
|
+
if (exists) {
|
|
1066
|
+
if (areDirectoriesEqual(srcDir, destDir)) {
|
|
1067
|
+
log(options, `⏭️ 全局 Skill 已最新,无需同步: ${destination.id}/${path.basename(destDir)}`);
|
|
1068
|
+
return { skipped: 1, synced: 0, backedUp: 0 };
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (options.dryRun) {
|
|
1073
|
+
log(options, `[dry-run] 将同步全局 Skill: ${destination.id}/${path.basename(destDir)}`);
|
|
1074
|
+
return { skipped: 0, synced: 0, backedUp: exists ? 1 : 0 };
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
let backedUp = 0;
|
|
1078
|
+
if (exists) {
|
|
1079
|
+
backupSkillDirectory(destination.id, path.basename(destDir), destDir, timestamp, options);
|
|
1080
|
+
backedUp = 1;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
const logger = options.quiet ? (() => {}) : log.bind(null, options);
|
|
1084
|
+
AtomicWriter.atomicCopyDir(srcDir, destDir, { logger });
|
|
1085
|
+
log(options, `✅ 已同步全局 Skill: ${destination.id}/${path.basename(destDir)}`);
|
|
1086
|
+
|
|
1087
|
+
return { skipped: 0, synced: 1, backedUp };
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
function syncGlobalSkillsFromRoot(targetName, skillsRoot, timestamp, options) {
|
|
1091
|
+
const destinations = getGlobalDestinations(targetName);
|
|
1092
|
+
const skillNames = listSkillDirectories(skillsRoot);
|
|
1093
|
+
if (skillNames.length === 0) {
|
|
1094
|
+
throw new Error(`未检测到可同步的 Skills: ${skillsRoot}`);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
if (options.dryRun) {
|
|
1098
|
+
for (const destination of destinations) {
|
|
1099
|
+
log(options, `[dry-run] 将同步 ${skillNames.length} 个全局 Skills -> ${destination.skillsRoot}`);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
let synced = 0;
|
|
1104
|
+
let skipped = 0;
|
|
1105
|
+
let backedUp = 0;
|
|
1106
|
+
const destinationResults = [];
|
|
1107
|
+
|
|
1108
|
+
for (const destination of destinations) {
|
|
1109
|
+
let destinationSynced = 0;
|
|
1110
|
+
let destinationSkipped = 0;
|
|
1111
|
+
let destinationBackedUp = 0;
|
|
1112
|
+
|
|
1113
|
+
for (const skillName of skillNames) {
|
|
1114
|
+
const srcDir = path.join(skillsRoot, skillName);
|
|
1115
|
+
const destDir = path.join(destination.skillsRoot, skillName);
|
|
1116
|
+
const result = syncSkillDirectory(destination, srcDir, destDir, timestamp, options);
|
|
1117
|
+
synced += result.synced;
|
|
1118
|
+
skipped += result.skipped;
|
|
1119
|
+
backedUp += result.backedUp;
|
|
1120
|
+
destinationSynced += result.synced;
|
|
1121
|
+
destinationSkipped += result.skipped;
|
|
1122
|
+
destinationBackedUp += result.backedUp;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
destinationResults.push({
|
|
1126
|
+
targetName: destination.id,
|
|
1127
|
+
family: destination.targetName,
|
|
1128
|
+
destRoot: destination.skillsRoot,
|
|
1129
|
+
total: skillNames.length,
|
|
1130
|
+
synced: destinationSynced,
|
|
1131
|
+
skipped: destinationSkipped,
|
|
1132
|
+
backedUp: destinationBackedUp,
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
return {
|
|
1137
|
+
total: skillNames.length * destinations.length,
|
|
1138
|
+
skillsPerDestination: skillNames.length,
|
|
1139
|
+
synced,
|
|
1140
|
+
skipped,
|
|
1141
|
+
backedUp,
|
|
1142
|
+
destinations: destinationResults,
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
function applyGlobalSync(targetName, agentDir, timestamp, options) {
|
|
1147
|
+
if (targetName === "codex") {
|
|
1148
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-global-codex-"));
|
|
1149
|
+
const mockRoot = path.join(tempRoot, "source");
|
|
1150
|
+
const mockAgent = path.join(mockRoot, ".agents");
|
|
1151
|
+
const outputDir = path.join(tempRoot, "out");
|
|
1152
|
+
|
|
1153
|
+
try {
|
|
1154
|
+
copyDirRecursive(agentDir, mockAgent);
|
|
1155
|
+
CodexBuilder.build(mockRoot, outputDir);
|
|
1156
|
+
const skillsRoot = path.join(outputDir, "skills");
|
|
1157
|
+
return syncGlobalSkillsFromRoot(targetName, skillsRoot, timestamp, options);
|
|
1158
|
+
} finally {
|
|
1159
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
if (targetName === "gemini") {
|
|
1164
|
+
const skillsRoot = path.join(agentDir, "skills");
|
|
1165
|
+
return syncGlobalSkillsFromRoot(targetName, skillsRoot, timestamp, options);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
throw new Error(`未知目标: ${targetName}`);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
async function commandGlobalSync(options) {
|
|
1172
|
+
const targets = await resolveTargetsForGlobalSync(options);
|
|
1173
|
+
const { agentDir, cleanup, sourceLabel } = resolveAgentInstallSource(options);
|
|
1174
|
+
const timestamp = nowISO().replace(/[:.]/g, "-");
|
|
1175
|
+
|
|
1176
|
+
try {
|
|
1177
|
+
log(options, `🌍 全局同步源: ${sourceLabel}`);
|
|
1178
|
+
for (const target of targets) {
|
|
1179
|
+
log(options, `📦 正在同步全局目标 [${target}] ...`);
|
|
1180
|
+
const result = applyGlobalSync(target, agentDir, timestamp, options);
|
|
1181
|
+
if (!options.dryRun) {
|
|
1182
|
+
log(options, `📊 全局同步完成 [${target}]:总计 ${result.total},新增/覆盖 ${result.synced},跳过 ${result.skipped},备份 ${result.backedUp}`);
|
|
1183
|
+
for (const item of result.destinations) {
|
|
1184
|
+
log(options, ` - ${item.targetName}: ${item.destRoot}(每目标 ${item.total} 个 Skills)`);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
} finally {
|
|
1189
|
+
if (cleanup) cleanup();
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
function commandGlobalStatus(options) {
|
|
1194
|
+
const summary = evaluateGlobalState();
|
|
1195
|
+
|
|
1196
|
+
if (summary.state === "missing") {
|
|
1197
|
+
if (options.quiet) {
|
|
1198
|
+
console.log("missing");
|
|
1199
|
+
}
|
|
1200
|
+
if (!options.quiet) {
|
|
1201
|
+
console.log("❌ 未检测到全局安装的 Skills");
|
|
1202
|
+
console.log(` 全局根目录: ${summary.globalRoot}`);
|
|
1203
|
+
}
|
|
1204
|
+
setQuietStatusExitCode("missing");
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
if (options.quiet) {
|
|
1209
|
+
console.log(summary.state);
|
|
1210
|
+
setQuietStatusExitCode(summary.state);
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
console.log(summary.state === "installed" ? "✅ 全局 Skills 状态正常" : "⚠️ 全局 Skills 存在问题");
|
|
1215
|
+
console.log(` 全局根目录: ${summary.globalRoot}`);
|
|
1216
|
+
console.log(` 总体状态: ${summary.state}`);
|
|
1217
|
+
console.log(` Targets: ${summary.targets.map((item) => item.targetName).join(", ")}`);
|
|
1218
|
+
|
|
1219
|
+
for (const item of summary.targets) {
|
|
1220
|
+
console.log(`\n[${item.targetName}:global]`);
|
|
1221
|
+
console.log(` 家族: ${item.family}`);
|
|
1222
|
+
console.log(` 状态: ${item.state}`);
|
|
1223
|
+
console.log(` 路径: ${item.skillsRoot}`);
|
|
1224
|
+
if (item.state === "installed") {
|
|
1225
|
+
console.log(` Skills: ${item.skillsCount}`);
|
|
1226
|
+
continue;
|
|
1227
|
+
}
|
|
1228
|
+
for (const issue of item.issues) {
|
|
1229
|
+
console.log(` Issue: ${issue}`);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
setQuietStatusExitCode(summary.state);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
function commandGlobal(options) {
|
|
1237
|
+
const subcommand = String(options.subcommand || "status").toLowerCase();
|
|
1238
|
+
if (subcommand === "sync") {
|
|
1239
|
+
return commandGlobalSync(options);
|
|
1240
|
+
}
|
|
1241
|
+
if (subcommand === "status") {
|
|
1242
|
+
return commandGlobalStatus(options);
|
|
1243
|
+
}
|
|
1244
|
+
throw new Error(`未知 global 子命令: ${subcommand}`);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
779
1247
|
async function commandInit(options) {
|
|
780
1248
|
const workspaceRoot = resolveWorkspaceRoot(options.path);
|
|
781
1249
|
const targets = await resolveTargetsForInit(options);
|
|
@@ -1225,40 +1693,54 @@ function countSkillsRecursive(dir) {
|
|
|
1225
1693
|
|
|
1226
1694
|
function commandStatus(options) {
|
|
1227
1695
|
const workspaceRoot = resolveWorkspaceRoot(options.path);
|
|
1228
|
-
const
|
|
1696
|
+
const summary = evaluateWorkspaceState(workspaceRoot, options);
|
|
1229
1697
|
|
|
1230
|
-
if (
|
|
1698
|
+
if (summary.state === "missing") {
|
|
1699
|
+
if (options.quiet) {
|
|
1700
|
+
console.log("missing");
|
|
1701
|
+
}
|
|
1231
1702
|
if (!options.quiet) {
|
|
1232
1703
|
console.log("❌ 未检测到 Antigravity Kit 安装");
|
|
1233
1704
|
console.log(` 目标目录: ${workspaceRoot}`);
|
|
1234
1705
|
}
|
|
1235
|
-
|
|
1706
|
+
setQuietStatusExitCode("missing");
|
|
1236
1707
|
return;
|
|
1237
1708
|
}
|
|
1238
1709
|
|
|
1239
1710
|
if (options.quiet) {
|
|
1240
|
-
console.log(
|
|
1711
|
+
console.log(summary.state);
|
|
1712
|
+
setQuietStatusExitCode(summary.state);
|
|
1241
1713
|
return;
|
|
1242
1714
|
}
|
|
1243
1715
|
|
|
1244
|
-
console.log("✅ Antigravity Kit
|
|
1716
|
+
console.log(summary.state === "installed" ? "✅ Antigravity Kit 状态正常" : "⚠️ Antigravity Kit 存在问题");
|
|
1245
1717
|
console.log(` CLI 版本: ${pkg.version}`);
|
|
1246
1718
|
console.log(` 工作区: ${workspaceRoot}`);
|
|
1247
|
-
console.log(`
|
|
1719
|
+
console.log(` 总体状态: ${summary.state}`);
|
|
1720
|
+
console.log(` Targets: ${summary.targets.map((item) => item.targetName).join(", ")}`);
|
|
1248
1721
|
|
|
1249
|
-
|
|
1722
|
+
const geminiState = summary.targets.find((item) => item.targetName === "gemini");
|
|
1723
|
+
if (geminiState) {
|
|
1250
1724
|
const agentDir = path.join(workspaceRoot, ".agent");
|
|
1251
1725
|
const agentsCount = countFilesIfExists(path.join(agentDir, "agents"), (name) => name.endsWith(".md"));
|
|
1252
1726
|
const workflowsCount = countFilesIfExists(path.join(agentDir, "workflows"), (name) => name.endsWith(".md"));
|
|
1253
1727
|
const skillsCount = countSkillsRecursive(path.join(agentDir, "skills"));
|
|
1254
1728
|
console.log("\n[gemini]");
|
|
1729
|
+
console.log(` 状态: ${geminiState.state}`);
|
|
1255
1730
|
console.log(` 路径: ${agentDir}`);
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1731
|
+
if (geminiState.state === "installed") {
|
|
1732
|
+
console.log(` Agents: ${agentsCount}`);
|
|
1733
|
+
console.log(` Skills: ${skillsCount}`);
|
|
1734
|
+
console.log(` Workflows: ${workflowsCount}`);
|
|
1735
|
+
} else {
|
|
1736
|
+
for (const issue of geminiState.integrity.issues || []) {
|
|
1737
|
+
console.log(` Issue: ${issue}`);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1259
1740
|
}
|
|
1260
1741
|
|
|
1261
|
-
|
|
1742
|
+
const codexState = summary.targets.find((item) => item.targetName === "codex");
|
|
1743
|
+
if (codexState) {
|
|
1262
1744
|
const managedDir = path.join(workspaceRoot, ".agents");
|
|
1263
1745
|
const legacyDir = path.join(workspaceRoot, ".codex");
|
|
1264
1746
|
const activeDir = fs.existsSync(managedDir) ? managedDir : legacyDir;
|
|
@@ -1266,13 +1748,21 @@ function commandStatus(options) {
|
|
|
1266
1748
|
const hasManifest = fs.existsSync(path.join(activeDir, "manifest.json"));
|
|
1267
1749
|
const legacyDetected = fs.existsSync(legacyDir);
|
|
1268
1750
|
console.log("\n[codex]");
|
|
1751
|
+
console.log(` 状态: ${codexState.state}`);
|
|
1269
1752
|
console.log(` 路径: ${activeDir}`);
|
|
1270
1753
|
console.log(` Skills: ${skillsCount}`);
|
|
1271
1754
|
console.log(` Manifest: ${hasManifest ? "yes" : "no"}`);
|
|
1272
1755
|
if (legacyDetected) {
|
|
1273
1756
|
console.log(" Legacy: 检测到 .codex(建议执行 ag-kit update 迁移清理)");
|
|
1274
1757
|
}
|
|
1758
|
+
if (codexState.state !== "installed") {
|
|
1759
|
+
for (const issue of codexState.integrity.issues || []) {
|
|
1760
|
+
console.log(` Issue: ${issue}`);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1275
1763
|
}
|
|
1764
|
+
|
|
1765
|
+
setQuietStatusExitCode(summary.state);
|
|
1276
1766
|
}
|
|
1277
1767
|
|
|
1278
1768
|
async function main() {
|
|
@@ -1314,6 +1804,11 @@ async function main() {
|
|
|
1314
1804
|
return;
|
|
1315
1805
|
}
|
|
1316
1806
|
|
|
1807
|
+
if (command === "global") {
|
|
1808
|
+
await commandGlobal(options);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1317
1812
|
if (command === "exclude") {
|
|
1318
1813
|
commandExclude(options);
|
|
1319
1814
|
return;
|
package/bin/core/builder.js
CHANGED
|
@@ -9,7 +9,7 @@ const pkg = require("../../package.json");
|
|
|
9
9
|
class CodexBuilder {
|
|
10
10
|
/**
|
|
11
11
|
* Build a Codex structure from a legacy/source repository
|
|
12
|
-
* @param {string} sourceRoot Root of the repo (containing .
|
|
12
|
+
* @param {string} sourceRoot Root of the repo (containing .agents/)
|
|
13
13
|
* @param {string} outputDir Directory to output the built .agents-compatible structure
|
|
14
14
|
*/
|
|
15
15
|
static build(sourceRoot, outputDir) {
|