@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/ag-kit.js
CHANGED
|
@@ -5,30 +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");
|
|
12
|
+
const GeminiAdapter = require("./adapters/gemini");
|
|
9
13
|
const CodexAdapter = require("./adapters/codex");
|
|
10
|
-
const {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
selectGeminiAgentsPolicy,
|
|
14
|
-
} = require("./interactive");
|
|
15
|
-
|
|
16
|
-
const BUNDLED_AGENT_DIR = fs.existsSync(path.resolve(__dirname, "../.agents"))
|
|
17
|
-
? path.resolve(__dirname, "../.agents")
|
|
18
|
-
: path.resolve(__dirname, "../.agent");
|
|
14
|
+
const { selectTargets } = require("./interactive");
|
|
15
|
+
|
|
16
|
+
const BUNDLED_AGENT_DIR = path.resolve(__dirname, "../.agents");
|
|
19
17
|
const WORKSPACE_INDEX_VERSION = 2;
|
|
20
18
|
const UPSTREAM_GLOBAL_PACKAGE = "@vudovn/ag-kit";
|
|
21
19
|
const TOOLKIT_PACKAGE_NAMES = new Set(["@mison/ag-kit-cn", "antigravity-kit-cn", "antigravity-kit"]);
|
|
22
|
-
const SUPPORTED_TARGETS = ["
|
|
23
|
-
const
|
|
24
|
-
full: "
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
codex:
|
|
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
|
+
],
|
|
28
44
|
};
|
|
29
45
|
const INDEX_LOCK_RETRY_MS = 50;
|
|
30
46
|
const INDEX_LOCK_TIMEOUT_MS = 3000;
|
|
31
47
|
const INDEX_LOCK_STALE_MS = 30000;
|
|
48
|
+
const QUIET_STATUS_EXIT_CODES = {
|
|
49
|
+
installed: 0,
|
|
50
|
+
broken: 1,
|
|
51
|
+
missing: 2,
|
|
52
|
+
};
|
|
32
53
|
|
|
33
54
|
function nowISO() {
|
|
34
55
|
return new Date().toISOString();
|
|
@@ -51,20 +72,79 @@ function createEmptyWorkspaceIndex() {
|
|
|
51
72
|
};
|
|
52
73
|
}
|
|
53
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
|
+
|
|
54
135
|
function printUsage() {
|
|
55
136
|
console.log("用法:");
|
|
56
137
|
console.log(" ag-kit init [--force] [--path <dir>] [--branch <name>] [--target <name>|--targets <a,b>] [--non-interactive] [--no-index] [--quiet] [--dry-run]");
|
|
57
138
|
console.log(" ag-kit update [--path <dir>] [--branch <name>] [--target <name>|--targets <a,b>] [--no-index] [--quiet] [--dry-run]");
|
|
58
139
|
console.log(" ag-kit update-all [--branch <name>] [--targets <a,b>] [--prune-missing] [--quiet] [--dry-run]");
|
|
59
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]");
|
|
60
143
|
console.log(" ag-kit exclude list [--quiet]");
|
|
61
144
|
console.log(" ag-kit exclude add --path <dir> [--dry-run] [--quiet]");
|
|
62
145
|
console.log(" ag-kit exclude remove --path <dir> [--dry-run] [--quiet]");
|
|
63
146
|
console.log(" ag-kit status [--path <dir>] [--quiet]");
|
|
64
147
|
console.log(" ag-kit --version");
|
|
65
|
-
console.log("");
|
|
66
|
-
console.log("说明:");
|
|
67
|
-
console.log(" --target gemini/codex/full 现均归一为统一 full 安装(.agents 为主目录)");
|
|
68
148
|
}
|
|
69
149
|
|
|
70
150
|
function printVersion() {
|
|
@@ -89,18 +169,16 @@ function parseArgs(argv) {
|
|
|
89
169
|
path: "",
|
|
90
170
|
branch: "",
|
|
91
171
|
targets: [],
|
|
92
|
-
agentConflictPolicy: "",
|
|
93
|
-
geminiAgentsPolicy: "",
|
|
94
172
|
};
|
|
95
173
|
const providedFlags = [];
|
|
96
174
|
|
|
97
175
|
let startIndex = 1;
|
|
98
|
-
if (command === "exclude") {
|
|
176
|
+
if (command === "exclude" || command === "global") {
|
|
99
177
|
if (argv.length > 1 && !argv[1].startsWith("--")) {
|
|
100
178
|
options.subcommand = argv[1];
|
|
101
179
|
startIndex = 2;
|
|
102
180
|
} else {
|
|
103
|
-
options.subcommand = "list";
|
|
181
|
+
options.subcommand = command === "global" ? "status" : "list";
|
|
104
182
|
startIndex = 1;
|
|
105
183
|
}
|
|
106
184
|
}
|
|
@@ -167,6 +245,8 @@ const COMMAND_ALLOWED_FLAGS = {
|
|
|
167
245
|
"update-all": ["--branch", "--targets", "--prune-missing", "--quiet", "--dry-run"],
|
|
168
246
|
doctor: ["--path", "--target", "--targets", "--fix", "--quiet"],
|
|
169
247
|
status: ["--path", "--quiet"],
|
|
248
|
+
"global:sync": ["--target", "--targets", "--branch", "--quiet", "--dry-run"],
|
|
249
|
+
"global:status": ["--quiet"],
|
|
170
250
|
"exclude:list": ["--quiet"],
|
|
171
251
|
"exclude:add": ["--path", "--dry-run", "--quiet"],
|
|
172
252
|
"exclude:remove": ["--path", "--dry-run", "--quiet"],
|
|
@@ -178,6 +258,11 @@ function resolveAllowedFlags(command, options) {
|
|
|
178
258
|
const key = `exclude:${subcommand}`;
|
|
179
259
|
return COMMAND_ALLOWED_FLAGS[key] || null;
|
|
180
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
|
+
}
|
|
181
266
|
return COMMAND_ALLOWED_FLAGS[command] || null;
|
|
182
267
|
}
|
|
183
268
|
|
|
@@ -186,6 +271,10 @@ function resolveCommandLabel(command, options) {
|
|
|
186
271
|
const subcommand = String(options.subcommand || "list").toLowerCase();
|
|
187
272
|
return `exclude ${subcommand}`;
|
|
188
273
|
}
|
|
274
|
+
if (command === "global") {
|
|
275
|
+
const subcommand = String(options.subcommand || "status").toLowerCase();
|
|
276
|
+
return `global ${subcommand}`;
|
|
277
|
+
}
|
|
189
278
|
return command;
|
|
190
279
|
}
|
|
191
280
|
|
|
@@ -357,25 +446,34 @@ function normalizeTargetState(value) {
|
|
|
357
446
|
};
|
|
358
447
|
}
|
|
359
448
|
|
|
360
|
-
function
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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];
|
|
364
459
|
}
|
|
365
|
-
|
|
460
|
+
if (SUPPORTED_TARGETS.includes(normalized)) {
|
|
461
|
+
return normalized;
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
366
464
|
}
|
|
367
465
|
|
|
368
466
|
function normalizeWorkspaceRecordV2(item, normalizedPath) {
|
|
369
467
|
const targets = {};
|
|
370
468
|
if (item && item.targets && typeof item.targets === "object") {
|
|
371
469
|
for (const [targetName, state] of Object.entries(item.targets)) {
|
|
372
|
-
const
|
|
373
|
-
if (!
|
|
470
|
+
const normalizedTargetName = normalizeIndexTargetName(targetName);
|
|
471
|
+
if (!normalizedTargetName) {
|
|
374
472
|
continue;
|
|
375
473
|
}
|
|
376
474
|
const normalizedState = normalizeTargetState(state);
|
|
377
475
|
if (normalizedState) {
|
|
378
|
-
targets[
|
|
476
|
+
targets[normalizedTargetName] = normalizedState;
|
|
379
477
|
}
|
|
380
478
|
}
|
|
381
479
|
}
|
|
@@ -389,7 +487,7 @@ function migrateRecordV1ToV2(item, normalizedPath) {
|
|
|
389
487
|
const targets = {};
|
|
390
488
|
const installedAt = typeof item.installedAt === "string" ? item.installedAt : "";
|
|
391
489
|
if (installedAt) {
|
|
392
|
-
targets.
|
|
490
|
+
targets.gemini = {
|
|
393
491
|
version: typeof item.cliVersion === "string" ? item.cliVersion : "",
|
|
394
492
|
installedAt,
|
|
395
493
|
updatedAt: typeof item.lastUpdatedAt === "string" ? item.lastUpdatedAt : installedAt,
|
|
@@ -594,14 +692,13 @@ function upsertWorkspaceTarget(index, workspaceRoot, targetName, timestamp) {
|
|
|
594
692
|
record.targets = {};
|
|
595
693
|
}
|
|
596
694
|
|
|
597
|
-
const
|
|
598
|
-
const prev = normalizeTargetState(record.targets[normalizedTarget]) || {
|
|
695
|
+
const prev = normalizeTargetState(record.targets[targetName]) || {
|
|
599
696
|
version: "",
|
|
600
697
|
installedAt: "",
|
|
601
698
|
updatedAt: "",
|
|
602
699
|
};
|
|
603
700
|
|
|
604
|
-
record.targets[
|
|
701
|
+
record.targets[targetName] = {
|
|
605
702
|
version: pkg.version,
|
|
606
703
|
installedAt: prev.installedAt || timestamp,
|
|
607
704
|
updatedAt: timestamp,
|
|
@@ -698,7 +795,12 @@ function maybeWarnUpstreamGlobalConflict(command, options) {
|
|
|
698
795
|
if (process.env.AG_KIT_SKIP_UPSTREAM_CHECK === "1") {
|
|
699
796
|
return;
|
|
700
797
|
}
|
|
701
|
-
|
|
798
|
+
const shouldWarn =
|
|
799
|
+
command === "init"
|
|
800
|
+
|| command === "update"
|
|
801
|
+
|| command === "update-all"
|
|
802
|
+
|| (command === "global" && String(options.subcommand || "").toLowerCase() === "sync");
|
|
803
|
+
if (!shouldWarn) {
|
|
702
804
|
return;
|
|
703
805
|
}
|
|
704
806
|
|
|
@@ -714,25 +816,7 @@ function maybeWarnUpstreamGlobalConflict(command, options) {
|
|
|
714
816
|
log(options, `⚠️ 检测到全局已安装上游英文版 ${UPSTREAM_GLOBAL_PACKAGE}。`);
|
|
715
817
|
log(options, "⚠️ 上游英文版与当前中文版共用 `ag-kit` 命令名,后安装者会覆盖命令入口。");
|
|
716
818
|
log(options, `👉 建议执行: npm uninstall -g ${UPSTREAM_GLOBAL_PACKAGE}`);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
function maybeWarnLegacyTargetAlias(options, rawTargets) {
|
|
720
|
-
if (options.quiet) {
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
const aliases = [];
|
|
724
|
-
for (const raw of rawTargets || []) {
|
|
725
|
-
const key = String(raw || "").trim().toLowerCase();
|
|
726
|
-
if (!key || key === "full" || key === "agents") {
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
|
-
if (key === "gemini" || key === "codex") {
|
|
730
|
-
aliases.push(key);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
if (aliases.length > 0) {
|
|
734
|
-
log(options, `ℹ️ 检测到兼容目标参数: ${Array.from(new Set(aliases)).join(", ")},将自动归一为 full 安装流程。`);
|
|
735
|
-
}
|
|
819
|
+
log(options, "ℹ️ 若你通过 bun install -g 安装,Bun 默认会阻止本包 postinstall;因此这里会在首次执行 CLI 时再次提醒。");
|
|
736
820
|
}
|
|
737
821
|
|
|
738
822
|
function normalizeTargets(rawTargets) {
|
|
@@ -752,13 +836,9 @@ function normalizeTargets(rawTargets) {
|
|
|
752
836
|
if (!SUPPORTED_TARGETS.includes(target)) {
|
|
753
837
|
throw new Error(`不支持的目标: ${target}(可选: ${SUPPORTED_TARGETS.join(", ")})`);
|
|
754
838
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
}
|
|
759
|
-
if (!seen.has(normalized)) {
|
|
760
|
-
seen.add(normalized);
|
|
761
|
-
result.push(normalized);
|
|
839
|
+
if (!seen.has(target)) {
|
|
840
|
+
seen.add(target);
|
|
841
|
+
result.push(target);
|
|
762
842
|
}
|
|
763
843
|
}
|
|
764
844
|
}
|
|
@@ -766,66 +846,155 @@ function normalizeTargets(rawTargets) {
|
|
|
766
846
|
return result;
|
|
767
847
|
}
|
|
768
848
|
|
|
769
|
-
function
|
|
770
|
-
const
|
|
771
|
-
if (
|
|
772
|
-
|
|
849
|
+
function detectInstalledTargets(workspaceRoot) {
|
|
850
|
+
const targets = [];
|
|
851
|
+
if (fs.existsSync(path.join(workspaceRoot, ".agent"))) {
|
|
852
|
+
targets.push("gemini");
|
|
773
853
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
const target = typeof parsed.target === "string" ? parsed.target.toLowerCase() : "";
|
|
777
|
-
return (target === "codex" || target === "full") && parsed.files && typeof parsed.files === "object";
|
|
778
|
-
} catch (_err) {
|
|
779
|
-
return false;
|
|
854
|
+
if (fs.existsSync(path.join(workspaceRoot, ".agents")) || fs.existsSync(path.join(workspaceRoot, ".codex"))) {
|
|
855
|
+
targets.push("codex");
|
|
780
856
|
}
|
|
857
|
+
return targets;
|
|
781
858
|
}
|
|
782
859
|
|
|
783
|
-
function
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
860
|
+
function isTargetInstalled(workspaceRoot, targetName) {
|
|
861
|
+
if (targetName === "gemini") {
|
|
862
|
+
return fs.existsSync(path.join(workspaceRoot, ".agent"));
|
|
863
|
+
}
|
|
864
|
+
if (targetName === "codex") {
|
|
865
|
+
return fs.existsSync(path.join(workspaceRoot, ".agents")) || fs.existsSync(path.join(workspaceRoot, ".codex"));
|
|
866
|
+
}
|
|
867
|
+
return false;
|
|
787
868
|
}
|
|
788
869
|
|
|
789
|
-
function
|
|
790
|
-
|
|
791
|
-
|
|
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";
|
|
792
882
|
}
|
|
793
|
-
return
|
|
883
|
+
return "broken";
|
|
794
884
|
}
|
|
795
885
|
|
|
796
|
-
function
|
|
797
|
-
const
|
|
798
|
-
if (
|
|
799
|
-
return
|
|
886
|
+
function evaluateWorkspaceState(workspaceRoot, options) {
|
|
887
|
+
const targets = detectInstalledTargets(workspaceRoot);
|
|
888
|
+
if (targets.length === 0) {
|
|
889
|
+
return {
|
|
890
|
+
state: "missing",
|
|
891
|
+
targets: [],
|
|
892
|
+
};
|
|
800
893
|
}
|
|
801
|
-
|
|
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
|
+
};
|
|
802
962
|
}
|
|
803
963
|
|
|
804
964
|
function createAdapter(targetName, workspaceRoot, options) {
|
|
805
|
-
|
|
806
|
-
|
|
965
|
+
if (targetName === "gemini") {
|
|
966
|
+
return new GeminiAdapter(workspaceRoot, options);
|
|
967
|
+
}
|
|
968
|
+
if (targetName === "codex") {
|
|
807
969
|
return new CodexAdapter(workspaceRoot, options);
|
|
808
970
|
}
|
|
809
971
|
throw new Error(`未知目标: ${targetName}`);
|
|
810
972
|
}
|
|
811
973
|
|
|
812
974
|
async function resolveTargetsForInit(options) {
|
|
813
|
-
maybeWarnLegacyTargetAlias(options, options.targets);
|
|
814
975
|
let targets = normalizeTargets(options.targets);
|
|
815
976
|
|
|
816
977
|
if (targets.length > 0) {
|
|
817
978
|
return targets;
|
|
818
979
|
}
|
|
980
|
+
|
|
981
|
+
if (options.nonInteractive) {
|
|
982
|
+
throw new Error("非交互模式下必须通过 --target 或 --targets 指定目标");
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
986
|
+
throw new Error("当前环境不是交互终端,请通过 --target 或 --targets 指定目标");
|
|
987
|
+
}
|
|
988
|
+
|
|
819
989
|
targets = normalizeTargets(await selectTargets(options));
|
|
820
990
|
if (targets.length === 0) {
|
|
821
|
-
|
|
991
|
+
throw new Error("必须选择至少一个目标");
|
|
822
992
|
}
|
|
823
993
|
|
|
824
994
|
return targets;
|
|
825
995
|
}
|
|
826
996
|
|
|
827
997
|
function resolveTargetsForUpdate(workspaceRoot, options) {
|
|
828
|
-
maybeWarnLegacyTargetAlias(options, options.targets);
|
|
829
998
|
const requested = normalizeTargets(options.targets);
|
|
830
999
|
if (requested.length > 0) {
|
|
831
1000
|
return requested;
|
|
@@ -833,50 +1002,267 @@ function resolveTargetsForUpdate(workspaceRoot, options) {
|
|
|
833
1002
|
return detectInstalledTargets(workspaceRoot);
|
|
834
1003
|
}
|
|
835
1004
|
|
|
836
|
-
|
|
837
|
-
const
|
|
838
|
-
|
|
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";
|
|
839
1018
|
|
|
840
|
-
if (
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
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";
|
|
845
1034
|
}
|
|
846
1035
|
}
|
|
847
1036
|
|
|
848
|
-
if (!
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
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 };
|
|
853
1069
|
}
|
|
854
1070
|
}
|
|
855
1071
|
|
|
856
|
-
|
|
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}`);
|
|
857
1245
|
}
|
|
858
1246
|
|
|
859
1247
|
async function commandInit(options) {
|
|
860
1248
|
const workspaceRoot = resolveWorkspaceRoot(options.path);
|
|
861
1249
|
const targets = await resolveTargetsForInit(options);
|
|
862
|
-
const runOptions = await resolveConflictPolicies(workspaceRoot, options);
|
|
863
1250
|
|
|
864
1251
|
for (const target of targets) {
|
|
865
|
-
const adapter = createAdapter(target, workspaceRoot,
|
|
1252
|
+
const adapter = createAdapter(target, workspaceRoot, options);
|
|
866
1253
|
log(options, `📦 正在初始化目标 [${target}] ...`);
|
|
867
1254
|
adapter.install(BUNDLED_AGENT_DIR);
|
|
868
|
-
registerWorkspaceTarget(workspaceRoot, target,
|
|
1255
|
+
registerWorkspaceTarget(workspaceRoot, target, options);
|
|
869
1256
|
}
|
|
870
1257
|
|
|
871
1258
|
if (targets.length > 0) {
|
|
872
|
-
log(options, `✅ 初始化完成 (
|
|
1259
|
+
log(options, `✅ 初始化完成 (Targets: ${targets.join(", ")})`);
|
|
873
1260
|
}
|
|
874
1261
|
}
|
|
875
1262
|
|
|
876
1263
|
async function commandUpdate(options) {
|
|
877
1264
|
const workspaceRoot = resolveWorkspaceRoot(options.path);
|
|
878
1265
|
const targets = resolveTargetsForUpdate(workspaceRoot, options);
|
|
879
|
-
const runOptions = await resolveConflictPolicies(workspaceRoot, options);
|
|
880
1266
|
|
|
881
1267
|
if (targets.length === 0) {
|
|
882
1268
|
throw new Error("此目录未检测到 Antigravity Kit 安装,无法更新。请先执行 init。");
|
|
@@ -894,11 +1280,11 @@ async function commandUpdate(options) {
|
|
|
894
1280
|
continue;
|
|
895
1281
|
}
|
|
896
1282
|
|
|
897
|
-
const
|
|
898
|
-
const adapter = createAdapter(target, workspaceRoot,
|
|
1283
|
+
const runOptions = { ...options, force: true };
|
|
1284
|
+
const adapter = createAdapter(target, workspaceRoot, runOptions);
|
|
899
1285
|
log(options, `📦 更新 [${target}] ...`);
|
|
900
1286
|
adapter.update(BUNDLED_AGENT_DIR);
|
|
901
|
-
registerWorkspaceTarget(workspaceRoot, target,
|
|
1287
|
+
registerWorkspaceTarget(workspaceRoot, target, runOptions);
|
|
902
1288
|
updatedAny = true;
|
|
903
1289
|
}
|
|
904
1290
|
|
|
@@ -912,13 +1298,12 @@ function mergeUpdatedTargets(record, workspacePath, targetNames, timestamp) {
|
|
|
912
1298
|
const next = normalizeWorkspaceRecordV2(record || {}, normalizedPath);
|
|
913
1299
|
|
|
914
1300
|
for (const target of targetNames) {
|
|
915
|
-
const
|
|
916
|
-
const prev = normalizeTargetState(next.targets[normalizedTarget]) || {
|
|
1301
|
+
const prev = normalizeTargetState(next.targets[target]) || {
|
|
917
1302
|
version: "",
|
|
918
1303
|
installedAt: "",
|
|
919
1304
|
updatedAt: "",
|
|
920
1305
|
};
|
|
921
|
-
next.targets[
|
|
1306
|
+
next.targets[target] = {
|
|
922
1307
|
version: pkg.version,
|
|
923
1308
|
installedAt: prev.installedAt || timestamp,
|
|
924
1309
|
updatedAt: timestamp,
|
|
@@ -933,7 +1318,6 @@ async function commandUpdateAll(options) {
|
|
|
933
1318
|
throw new Error("update-all 不支持 --path,请直接执行 ag-kit update-all");
|
|
934
1319
|
}
|
|
935
1320
|
|
|
936
|
-
maybeWarnLegacyTargetAlias(options, options.targets);
|
|
937
1321
|
const requestedTargets = normalizeTargets(options.targets);
|
|
938
1322
|
const { indexPath, index } = readWorkspaceIndex();
|
|
939
1323
|
const records = index.workspaces || [];
|
|
@@ -1016,8 +1400,6 @@ async function commandUpdateAll(options) {
|
|
|
1016
1400
|
force: true,
|
|
1017
1401
|
path: workspacePath,
|
|
1018
1402
|
silentIndexLog: true,
|
|
1019
|
-
agentConflictPolicy: "backup_replace",
|
|
1020
|
-
geminiAgentsPolicy: "append",
|
|
1021
1403
|
};
|
|
1022
1404
|
const adapter = createAdapter(target, workspacePath, runOptions);
|
|
1023
1405
|
adapter.update(BUNDLED_AGENT_DIR);
|
|
@@ -1311,61 +1693,76 @@ function countSkillsRecursive(dir) {
|
|
|
1311
1693
|
|
|
1312
1694
|
function commandStatus(options) {
|
|
1313
1695
|
const workspaceRoot = resolveWorkspaceRoot(options.path);
|
|
1314
|
-
const
|
|
1696
|
+
const summary = evaluateWorkspaceState(workspaceRoot, options);
|
|
1315
1697
|
|
|
1316
|
-
if (
|
|
1698
|
+
if (summary.state === "missing") {
|
|
1699
|
+
if (options.quiet) {
|
|
1700
|
+
console.log("missing");
|
|
1701
|
+
}
|
|
1317
1702
|
if (!options.quiet) {
|
|
1318
1703
|
console.log("❌ 未检测到 Antigravity Kit 安装");
|
|
1319
1704
|
console.log(` 目标目录: ${workspaceRoot}`);
|
|
1320
1705
|
}
|
|
1321
|
-
|
|
1706
|
+
setQuietStatusExitCode("missing");
|
|
1322
1707
|
return;
|
|
1323
1708
|
}
|
|
1324
1709
|
|
|
1325
1710
|
if (options.quiet) {
|
|
1326
|
-
console.log(
|
|
1711
|
+
console.log(summary.state);
|
|
1712
|
+
setQuietStatusExitCode(summary.state);
|
|
1327
1713
|
return;
|
|
1328
1714
|
}
|
|
1329
1715
|
|
|
1330
|
-
console.log("✅ Antigravity Kit
|
|
1716
|
+
console.log(summary.state === "installed" ? "✅ Antigravity Kit 状态正常" : "⚠️ Antigravity Kit 存在问题");
|
|
1331
1717
|
console.log(` CLI 版本: ${pkg.version}`);
|
|
1332
1718
|
console.log(` 工作区: ${workspaceRoot}`);
|
|
1333
|
-
console.log(`
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
console.log(` Manifest: ${hasManifest ? "yes" : "no"}`);
|
|
1719
|
+
console.log(` 总体状态: ${summary.state}`);
|
|
1720
|
+
console.log(` Targets: ${summary.targets.map((item) => item.targetName).join(", ")}`);
|
|
1721
|
+
|
|
1722
|
+
const geminiState = summary.targets.find((item) => item.targetName === "gemini");
|
|
1723
|
+
if (geminiState) {
|
|
1724
|
+
const agentDir = path.join(workspaceRoot, ".agent");
|
|
1725
|
+
const agentsCount = countFilesIfExists(path.join(agentDir, "agents"), (name) => name.endsWith(".md"));
|
|
1726
|
+
const workflowsCount = countFilesIfExists(path.join(agentDir, "workflows"), (name) => name.endsWith(".md"));
|
|
1727
|
+
const skillsCount = countSkillsRecursive(path.join(agentDir, "skills"));
|
|
1728
|
+
console.log("\n[gemini]");
|
|
1729
|
+
console.log(` 状态: ${geminiState.state}`);
|
|
1730
|
+
console.log(` 路径: ${agentDir}`);
|
|
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
|
+
}
|
|
1355
1740
|
}
|
|
1356
1741
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1742
|
+
const codexState = summary.targets.find((item) => item.targetName === "codex");
|
|
1743
|
+
if (codexState) {
|
|
1744
|
+
const managedDir = path.join(workspaceRoot, ".agents");
|
|
1745
|
+
const legacyDir = path.join(workspaceRoot, ".codex");
|
|
1746
|
+
const activeDir = fs.existsSync(managedDir) ? managedDir : legacyDir;
|
|
1747
|
+
const skillsCount = countSkillsRecursive(path.join(activeDir, "skills"));
|
|
1748
|
+
const hasManifest = fs.existsSync(path.join(activeDir, "manifest.json"));
|
|
1749
|
+
const legacyDetected = fs.existsSync(legacyDir);
|
|
1750
|
+
console.log("\n[codex]");
|
|
1751
|
+
console.log(` 状态: ${codexState.state}`);
|
|
1752
|
+
console.log(` 路径: ${activeDir}`);
|
|
1753
|
+
console.log(` Skills: ${skillsCount}`);
|
|
1754
|
+
console.log(` Manifest: ${hasManifest ? "yes" : "no"}`);
|
|
1755
|
+
if (legacyDetected) {
|
|
1756
|
+
console.log(" Legacy: 检测到 .codex(建议执行 ag-kit update 迁移清理)");
|
|
1757
|
+
}
|
|
1758
|
+
if (codexState.state !== "installed") {
|
|
1759
|
+
for (const issue of codexState.integrity.issues || []) {
|
|
1760
|
+
console.log(` Issue: ${issue}`);
|
|
1761
|
+
}
|
|
1367
1762
|
}
|
|
1368
1763
|
}
|
|
1764
|
+
|
|
1765
|
+
setQuietStatusExitCode(summary.state);
|
|
1369
1766
|
}
|
|
1370
1767
|
|
|
1371
1768
|
async function main() {
|
|
@@ -1407,6 +1804,11 @@ async function main() {
|
|
|
1407
1804
|
return;
|
|
1408
1805
|
}
|
|
1409
1806
|
|
|
1807
|
+
if (command === "global") {
|
|
1808
|
+
await commandGlobal(options);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1410
1812
|
if (command === "exclude") {
|
|
1411
1813
|
commandExclude(options);
|
|
1412
1814
|
return;
|