@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
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { test, describe } = require("node:test");
|
|
2
|
+
const assert = require("node:assert");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { spawnSync } = require("node:child_process");
|
|
5
|
+
|
|
6
|
+
const REPO_ROOT = path.resolve(__dirname, "..");
|
|
7
|
+
|
|
8
|
+
describe("Package Tarball", () => {
|
|
9
|
+
test("npm pack --dry-run should include maintenance scripts and tests", () => {
|
|
10
|
+
const result = spawnSync("npm", ["pack", "--json", "--dry-run"], {
|
|
11
|
+
cwd: REPO_ROOT,
|
|
12
|
+
encoding: "utf8",
|
|
13
|
+
});
|
|
14
|
+
assert.strictEqual(result.status, 0, result.stderr || result.stdout);
|
|
15
|
+
|
|
16
|
+
const payload = JSON.parse(result.stdout);
|
|
17
|
+
assert.ok(Array.isArray(payload) && payload.length > 0, "missing npm pack json payload");
|
|
18
|
+
|
|
19
|
+
const files = new Set(payload[0].files.map((item) => item.path));
|
|
20
|
+
assert.ok(files.has("scripts/clean.js"), "tarball missing scripts/clean.js");
|
|
21
|
+
assert.ok(files.has("scripts/ci-verify.js"), "tarball missing scripts/ci-verify.js");
|
|
22
|
+
assert.ok(files.has("scripts/health-check.js"), "tarball missing scripts/health-check.js");
|
|
23
|
+
assert.ok(files.has("scripts/health-check.sh"), "tarball missing scripts/health-check.sh");
|
|
24
|
+
assert.ok(files.has("tests/cli-smoke.test.js"), "tarball missing tests/cli-smoke.test.js");
|
|
25
|
+
assert.ok(files.has("tests/global-sync.test.js"), "tarball missing tests/global-sync.test.js");
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const { test, describe, beforeEach, afterEach } = require('node:test');
|
|
2
|
+
const assert = require('node:assert');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const CodexAdapter = require('../bin/adapters/codex');
|
|
7
|
+
const pkg = require('../package.json');
|
|
8
|
+
|
|
9
|
+
describe('Phase C Integration', () => {
|
|
10
|
+
let workDir;
|
|
11
|
+
let geminiRepo;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'phase-c-test-'));
|
|
15
|
+
geminiRepo = path.join(workDir, 'gemini-repo');
|
|
16
|
+
|
|
17
|
+
// Setup specialized Gemini-like structure
|
|
18
|
+
const agentDir = path.join(geminiRepo, '.agent');
|
|
19
|
+
const skillsDir = path.join(agentDir, 'skills');
|
|
20
|
+
const workflowsDir = path.join(agentDir, 'workflows');
|
|
21
|
+
|
|
22
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
23
|
+
fs.mkdirSync(workflowsDir, { recursive: true });
|
|
24
|
+
|
|
25
|
+
// Create a Skill
|
|
26
|
+
const skillPath = path.join(skillsDir, 'test-skill');
|
|
27
|
+
fs.mkdirSync(skillPath);
|
|
28
|
+
fs.writeFileSync(path.join(skillPath, 'SKILL.md'), '# Test Skill');
|
|
29
|
+
|
|
30
|
+
// Create a Workflow
|
|
31
|
+
fs.writeFileSync(path.join(workflowsDir, 'test-flow.md'), '# Test Workflow');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
fs.rmSync(workDir, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('CodexAdapter should build from Gemini structure on the fly', () => {
|
|
39
|
+
const options = { quiet: true, force: true };
|
|
40
|
+
const adapter = new CodexAdapter(workDir, options);
|
|
41
|
+
|
|
42
|
+
// Install from Gemini Repo Root
|
|
43
|
+
adapter.install(geminiRepo);
|
|
44
|
+
|
|
45
|
+
const codexDir = path.join(workDir, '.agents');
|
|
46
|
+
// Verification 1: Structure Created
|
|
47
|
+
assert.ok(fs.existsSync(codexDir));
|
|
48
|
+
|
|
49
|
+
// Verification 2: Transformation Happened
|
|
50
|
+
const builtSkill = path.join(codexDir, 'skills', 'test-skill', 'SKILL.md');
|
|
51
|
+
assert.ok(fs.existsSync(builtSkill));
|
|
52
|
+
|
|
53
|
+
// Workflow: workflow-test-flow
|
|
54
|
+
const builtWorkflow = path.join(codexDir, 'skills', 'workflow-test-flow', 'SKILL.md');
|
|
55
|
+
assert.ok(fs.existsSync(builtWorkflow));
|
|
56
|
+
|
|
57
|
+
// Verification 3: Manifest & Meta
|
|
58
|
+
assert.ok(fs.existsSync(path.join(codexDir, 'codex.json')));
|
|
59
|
+
assert.ok(fs.existsSync(path.join(codexDir, 'AGENTS.md')));
|
|
60
|
+
assert.ok(fs.existsSync(path.join(codexDir, 'antigravity.rules')));
|
|
61
|
+
|
|
62
|
+
const agentsMd = fs.readFileSync(path.join(codexDir, 'AGENTS.md'), 'utf8');
|
|
63
|
+
assert.ok(agentsMd.includes('test-skill'));
|
|
64
|
+
assert.ok(agentsMd.includes('(Codex Managed)'));
|
|
65
|
+
|
|
66
|
+
// Verification 4: Workspace managed block injection
|
|
67
|
+
const workspaceAgents = fs.readFileSync(path.join(workDir, 'AGENTS.md'), 'utf8');
|
|
68
|
+
const workspaceRules = fs.readFileSync(path.join(workDir, 'antigravity.rules'), 'utf8');
|
|
69
|
+
assert.ok(workspaceAgents.includes('BEGIN AG-KIT MANAGED BLOCK: codex-core-rules'));
|
|
70
|
+
assert.ok(workspaceAgents.includes('test-skill'));
|
|
71
|
+
assert.ok(workspaceRules.includes('BEGIN AG-KIT MANAGED BLOCK: codex-risk-controls'));
|
|
72
|
+
|
|
73
|
+
const codexJson = JSON.parse(fs.readFileSync(path.join(codexDir, 'codex.json'), 'utf8'));
|
|
74
|
+
assert.strictEqual(codexJson.version, pkg.version);
|
|
75
|
+
assert.ok(agentsMd.includes(`Version: ${pkg.version}`));
|
|
76
|
+
assert.ok(workspaceRules.includes(`version: ${pkg.version}`));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('CodexBuilder should avoid ID collisions between skills and workflows', () => {
|
|
80
|
+
const skillCollisionPath = path.join(geminiRepo, '.agent', 'skills', 'wf-test-flow');
|
|
81
|
+
fs.mkdirSync(skillCollisionPath, { recursive: true });
|
|
82
|
+
fs.writeFileSync(path.join(skillCollisionPath, 'SKILL.md'), '# Skill wf-test-flow');
|
|
83
|
+
|
|
84
|
+
const options = { quiet: true, force: true };
|
|
85
|
+
const adapter = new CodexAdapter(workDir, options);
|
|
86
|
+
adapter.install(geminiRepo);
|
|
87
|
+
|
|
88
|
+
const codexJson = JSON.parse(
|
|
89
|
+
fs.readFileSync(path.join(workDir, '.agents', 'codex.json'), 'utf8')
|
|
90
|
+
);
|
|
91
|
+
const collisionEntries = (codexJson.skills || []).filter(
|
|
92
|
+
(item) => item.originalName === 'wf-test-flow' || item.originalName === 'test-flow'
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
assert.strictEqual(collisionEntries.length, 2, 'skill/workflow should both be preserved');
|
|
96
|
+
assert.notStrictEqual(
|
|
97
|
+
collisionEntries[0].id,
|
|
98
|
+
collisionEntries[1].id,
|
|
99
|
+
'colliding IDs should be disambiguated',
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
for (const entry of collisionEntries) {
|
|
103
|
+
const skillFile = path.join(workDir, '.agents', entry.path);
|
|
104
|
+
assert.ok(fs.existsSync(skillFile), `missing transformed file: ${entry.path}`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
const { test, describe } = require('node:test');
|
|
2
|
+
const assert = require('node:assert');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const REF_ROOT = path.resolve('reference/antigravity-kit');
|
|
7
|
+
const REF_AGENTS_ROOT = path.resolve('reference/antigravity-kit/.agents');
|
|
8
|
+
const REF_LEGACY_AGENT_ROOT = path.resolve('reference/antigravity-kit/.agent');
|
|
9
|
+
const REF_SCRIPTS_ROOT = fs.existsSync(REF_AGENTS_ROOT) ? REF_AGENTS_ROOT : REF_LEGACY_AGENT_ROOT;
|
|
10
|
+
const HAS_REF_SCRIPTS_ROOT = fs.existsSync(REF_SCRIPTS_ROOT);
|
|
11
|
+
|
|
12
|
+
function collectTokens(content, regex) {
|
|
13
|
+
const tokens = new Set();
|
|
14
|
+
for (const match of String(content || "").matchAll(regex)) {
|
|
15
|
+
tokens.add(match[1] || match[0]);
|
|
16
|
+
}
|
|
17
|
+
return tokens;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe('Standards Compliance', () => {
|
|
21
|
+
test('all skill directories should include SKILL.md', () => {
|
|
22
|
+
const skillsRoot = path.resolve('.agents/skills');
|
|
23
|
+
assert.ok(fs.existsSync(skillsRoot), 'missing .agents/skills');
|
|
24
|
+
|
|
25
|
+
const skillDirs = fs
|
|
26
|
+
.readdirSync(skillsRoot, { withFileTypes: true })
|
|
27
|
+
.filter((entry) => entry.isDirectory())
|
|
28
|
+
.map((entry) => path.join(skillsRoot, entry.name));
|
|
29
|
+
|
|
30
|
+
for (const dir of skillDirs) {
|
|
31
|
+
const skillMd = path.join(dir, 'SKILL.md');
|
|
32
|
+
assert.ok(fs.existsSync(skillMd), `missing SKILL.md in ${path.relative(process.cwd(), dir)}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('deprecated .codex primary-layout wording should be removed from user-facing docs and generator', () => {
|
|
37
|
+
const targets = [
|
|
38
|
+
'README.md',
|
|
39
|
+
'docs/PLAN.md',
|
|
40
|
+
'docs/TECH.md',
|
|
41
|
+
'bin/core/generator.js',
|
|
42
|
+
];
|
|
43
|
+
const skipped = [];
|
|
44
|
+
|
|
45
|
+
for (const rel of targets) {
|
|
46
|
+
const abs = path.resolve(rel);
|
|
47
|
+
if (!fs.existsSync(abs)) {
|
|
48
|
+
skipped.push(rel);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const content = fs.readFileSync(abs, 'utf8');
|
|
52
|
+
assert.ok(!content.includes('Managed resources are synchronized under `.codex/`.'), `${rel} still contains deprecated .codex guidance`);
|
|
53
|
+
assert.ok(!content.includes('Do not edit files under `.codex/` directly.'), `${rel} still contains deprecated .codex guidance`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (skipped.length > 0) {
|
|
57
|
+
console.warn(`[standards-compliance] skipped missing optional files: ${skipped.join(', ')}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('critical mechanism tokens should remain aligned with reference snapshot', { skip: !fs.existsSync(REF_ROOT) }, () => {
|
|
62
|
+
const refRoot = REF_ROOT;
|
|
63
|
+
const tokenRegex = /(ag-kit|python3?|checklist\.py|verify_all\.py|security_scan\.py|ux_audit\.py|accessibility_checker\.py|schema_validator\.py|lint_runner\.py|type_coverage\.py|playwright_runner\.py|lighthouse_audit\.py|api_validator\.py|mobile_audit\.py|seo_checker\.py|geo_checker\.py|i18n_checker\.py|\.agent\/|\.agents\/|\.agents-backup\/|\.codex\/|AGENTS\.md|antigravity\.rules|manifest\.json|--target|--targets|--fix|--path|--no-index|--dry-run|--quiet|--force)/g;
|
|
64
|
+
const slashCommandRegex = /(?:^|[\s`"'(\[])(\/(?:brainstorm|create|debug|deploy|enhance|orchestrate|plan|preview|status|test|ui-ux-pro-max))(?=$|[\s`"',。,.::)\]])/gm;
|
|
65
|
+
|
|
66
|
+
const markdownFiles = [];
|
|
67
|
+
const stack = [refRoot];
|
|
68
|
+
while (stack.length > 0) {
|
|
69
|
+
const current = stack.pop();
|
|
70
|
+
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
71
|
+
const abs = path.join(current, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
stack.push(abs);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (/\.(md|mdx|txt)$/i.test(entry.name)) {
|
|
77
|
+
markdownFiles.push(abs);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const mismatches = [];
|
|
83
|
+
for (const refFile of markdownFiles) {
|
|
84
|
+
const rel = path.relative(refRoot, refFile);
|
|
85
|
+
const localFile = path.resolve(rel);
|
|
86
|
+
if (!fs.existsSync(localFile)) continue;
|
|
87
|
+
|
|
88
|
+
const refContent = fs.readFileSync(refFile, 'utf8');
|
|
89
|
+
const refTokens = new Set([
|
|
90
|
+
...collectTokens(refContent, tokenRegex),
|
|
91
|
+
...collectTokens(refContent, slashCommandRegex),
|
|
92
|
+
]);
|
|
93
|
+
if (refTokens.size === 0) continue;
|
|
94
|
+
|
|
95
|
+
const localContent = fs.readFileSync(localFile, 'utf8');
|
|
96
|
+
const localTokens = new Set([
|
|
97
|
+
...collectTokens(localContent, tokenRegex),
|
|
98
|
+
...collectTokens(localContent, slashCommandRegex),
|
|
99
|
+
]);
|
|
100
|
+
|
|
101
|
+
const missing = [...refTokens].filter((token) => !localTokens.has(token));
|
|
102
|
+
if (missing.length > 0) {
|
|
103
|
+
mismatches.push({ rel, missing });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
assert.strictEqual(
|
|
108
|
+
mismatches.length,
|
|
109
|
+
0,
|
|
110
|
+
`critical mechanism tokens drifted:\n${mismatches
|
|
111
|
+
.slice(0, 10)
|
|
112
|
+
.map((item) => `${item.rel} -> ${item.missing.join(', ')}`)
|
|
113
|
+
.join('\n')}`,
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('user-facing docs should track current repo and global skill locations', () => {
|
|
118
|
+
const file = path.resolve('docs/TECH.md');
|
|
119
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
120
|
+
|
|
121
|
+
assert.ok(content.includes('$HOME/.codex/skills/'), 'missing global skill path: $HOME/.codex/skills/');
|
|
122
|
+
assert.ok(content.includes('$HOME/.gemini/skills/'), 'missing global skill path: $HOME/.gemini/skills/');
|
|
123
|
+
assert.ok(content.includes('$HOME/.gemini/antigravity/skills/'), 'missing global skill path: $HOME/.gemini/antigravity/skills/');
|
|
124
|
+
assert.ok(content.includes('.agents/skills'), 'missing repo skill path: .agents/skills');
|
|
125
|
+
assert.ok(!content.includes('$HOME/.agents/skills/'), 'should not contain deprecated global path: $HOME/.agents/skills/');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('.agents script files should stay identical to reference snapshot', { skip: !HAS_REF_SCRIPTS_ROOT }, () => {
|
|
129
|
+
const refScriptsRoot = REF_SCRIPTS_ROOT;
|
|
130
|
+
const mismatches = [];
|
|
131
|
+
|
|
132
|
+
const stack = [refScriptsRoot];
|
|
133
|
+
while (stack.length > 0) {
|
|
134
|
+
const current = stack.pop();
|
|
135
|
+
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
136
|
+
const abs = path.join(current, entry.name);
|
|
137
|
+
if (entry.isDirectory()) {
|
|
138
|
+
stack.push(abs);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (!abs.includes(`${path.sep}scripts${path.sep}`)) continue;
|
|
142
|
+
if (abs.includes(`${path.sep}__pycache__${path.sep}`) || abs.endsWith('.pyc')) continue;
|
|
143
|
+
|
|
144
|
+
const rel = path.relative(refScriptsRoot, abs);
|
|
145
|
+
const localFile = path.resolve('.agents', rel);
|
|
146
|
+
if (!fs.existsSync(localFile)) {
|
|
147
|
+
mismatches.push(`${rel} (missing local file)`);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const refContent = fs.readFileSync(abs, 'utf8');
|
|
152
|
+
const localContent = fs.readFileSync(localFile, 'utf8');
|
|
153
|
+
if (refContent !== localContent) {
|
|
154
|
+
mismatches.push(rel);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
assert.strictEqual(
|
|
160
|
+
mismatches.length,
|
|
161
|
+
0,
|
|
162
|
+
`script content drifted:\n${mismatches.slice(0, 20).join('\n')}`,
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('critical path handling should avoid hardcoded platform separators in managed paths', () => {
|
|
167
|
+
const adapterFile = path.resolve('bin/adapters/codex.js');
|
|
168
|
+
const content = fs.readFileSync(adapterFile, 'utf8');
|
|
169
|
+
|
|
170
|
+
// Keep this focused on managed path constants that must remain path.join-driven.
|
|
171
|
+
assert.ok(content.includes('path.join'), 'codex adapter should use path.join for managed paths');
|
|
172
|
+
assert.ok(content.includes('os.tmpdir()'), 'codex adapter should use os.tmpdir() for temp paths');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('official antigravity docs baselines should be present in localized pages', () => {
|
|
176
|
+
const checks = [
|
|
177
|
+
{
|
|
178
|
+
file: 'web/src/app/docs/skills/page.tsx',
|
|
179
|
+
required: [
|
|
180
|
+
'SKILL.md',
|
|
181
|
+
'workspace-root',
|
|
182
|
+
'~/.gemini/antigravity/skills',
|
|
183
|
+
'description',
|
|
184
|
+
'scripts/',
|
|
185
|
+
'examples/',
|
|
186
|
+
'resources/',
|
|
187
|
+
'Discovery',
|
|
188
|
+
'Activation',
|
|
189
|
+
'Execution',
|
|
190
|
+
'--help',
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
file: 'web/src/app/docs/rules-workflows/page.tsx',
|
|
195
|
+
required: [
|
|
196
|
+
'12,000',
|
|
197
|
+
'~/.gemini/GEMINI.md',
|
|
198
|
+
'.agent/rules',
|
|
199
|
+
'Manual',
|
|
200
|
+
'Always On',
|
|
201
|
+
'Model Decision',
|
|
202
|
+
'Glob',
|
|
203
|
+
'@filename',
|
|
204
|
+
'/workflow-name',
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
file: 'web/src/app/docs/task-groups/page.tsx',
|
|
209
|
+
required: ['规划模式', '总体目标', '已编辑文件', '待处理区'],
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
file: 'web/src/app/docs/strict-mode/page.tsx',
|
|
213
|
+
required: ['Allowlist/Denylist', 'Request Review', '.gitignore', '工作区隔离'],
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
file: 'web/src/app/docs/sandbox-mode/page.tsx',
|
|
217
|
+
required: [
|
|
218
|
+
'sandbox-exec',
|
|
219
|
+
'Enable Terminal Sandboxing',
|
|
220
|
+
'Sandbox Allow Network',
|
|
221
|
+
'Bypass Sandbox',
|
|
222
|
+
'Strict Mode',
|
|
223
|
+
],
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
file: 'web/src/app/docs/mcp/page.tsx',
|
|
227
|
+
required: [
|
|
228
|
+
'Model Context Protocol',
|
|
229
|
+
'MCP Store',
|
|
230
|
+
'Manage MCP Servers',
|
|
231
|
+
'View raw config',
|
|
232
|
+
'mcp_config.json',
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
file: 'web/src/app/docs/command/page.tsx',
|
|
237
|
+
required: ['Command + I', 'Ctrl + I'],
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
file: 'web/src/app/docs/allowlist-denylist/page.tsx',
|
|
241
|
+
required: ['BadUrlsChecker', 'always allow', 'localhost'],
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
file: 'web/src/app/docs/browser-subagent/page.tsx',
|
|
245
|
+
required: ['DOM 捕获', '截图', '蓝色边框'],
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
const missing = [];
|
|
250
|
+
for (const { file, required } of checks) {
|
|
251
|
+
const abs = path.resolve(file);
|
|
252
|
+
const content = fs.readFileSync(abs, 'utf8');
|
|
253
|
+
for (const token of required) {
|
|
254
|
+
if (!content.includes(token)) {
|
|
255
|
+
missing.push(`${file} -> ${token}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
assert.strictEqual(
|
|
261
|
+
missing.length,
|
|
262
|
+
0,
|
|
263
|
+
`localized docs missing official baseline tokens:\n${missing.join('\n')}`,
|
|
264
|
+
);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const { test, describe, beforeEach, afterEach } = require("node:test");
|
|
2
|
+
const assert = require("node:assert");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const ResourceTransformer = require("../bin/core/transformer");
|
|
7
|
+
|
|
8
|
+
describe("ResourceTransformer", () => {
|
|
9
|
+
let tempDir;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "ag-kit-transformer-test-"));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
function transformWorkflow(markdown) {
|
|
20
|
+
const workflowPath = path.join(tempDir, "workflow.md");
|
|
21
|
+
fs.writeFileSync(workflowPath, markdown, "utf8");
|
|
22
|
+
|
|
23
|
+
const result = ResourceTransformer.transform({
|
|
24
|
+
skills: [],
|
|
25
|
+
workflows: [{ name: "demo", path: workflowPath, type: "workflow" }],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return result.mappedFiles.find((item) => item.destPath.endsWith("/SKILL.md"));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
test("workflow frontmatter should parse CRLF and keep colon in description", () => {
|
|
32
|
+
const mapped = transformWorkflow([
|
|
33
|
+
"---\r",
|
|
34
|
+
"description: \"Run /debug: inspect failures\"\r",
|
|
35
|
+
"---\r",
|
|
36
|
+
"",
|
|
37
|
+
"# Workflow body",
|
|
38
|
+
].join("\n"));
|
|
39
|
+
|
|
40
|
+
assert.ok(mapped);
|
|
41
|
+
assert.ok(mapped.content.includes("description: \"Run /debug: inspect failures\""));
|
|
42
|
+
assert.ok(mapped.content.includes("# Workflow body"));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("workflow frontmatter should parse folded multiline description", () => {
|
|
46
|
+
const mapped = transformWorkflow([
|
|
47
|
+
"---",
|
|
48
|
+
"description: >",
|
|
49
|
+
" 先执行 /plan",
|
|
50
|
+
" 再执行 /debug",
|
|
51
|
+
"---",
|
|
52
|
+
"",
|
|
53
|
+
"# Workflow body",
|
|
54
|
+
].join("\n"));
|
|
55
|
+
|
|
56
|
+
assert.ok(mapped);
|
|
57
|
+
assert.ok(mapped.content.includes("description: \"先执行 /plan 再执行 /debug\""));
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("workflow frontmatter should parse indented multiline description", () => {
|
|
61
|
+
const mapped = transformWorkflow([
|
|
62
|
+
"---",
|
|
63
|
+
"description:",
|
|
64
|
+
" 统一排查流程: 先收集日志",
|
|
65
|
+
" 再定位根因",
|
|
66
|
+
"---",
|
|
67
|
+
"",
|
|
68
|
+
"# Workflow body",
|
|
69
|
+
].join("\n"));
|
|
70
|
+
|
|
71
|
+
assert.ok(mapped);
|
|
72
|
+
assert.ok(mapped.content.includes("description: \"统一排查流程: 先收集日志 再定位根因\""));
|
|
73
|
+
});
|
|
74
|
+
});
|
package/.agent/mcp_config.json
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Codex `.rules` 模板(手动配置)
|
|
2
|
-
|
|
3
|
-
> 用途:给 Codex 官方规则引擎提供命令审批策略。
|
|
4
|
-
> 注意:这不是 `antigravity.rules` 的替代品,二者职责不同。
|
|
5
|
-
|
|
6
|
-
## 路径约定
|
|
7
|
-
|
|
8
|
-
- 全局默认路径:`~/.codex/rules/default.rules`
|
|
9
|
-
- 本项目不会自动写入该文件,请按需手动创建。
|
|
10
|
-
|
|
11
|
-
## 最小模板(Starlark)
|
|
12
|
-
|
|
13
|
-
```python
|
|
14
|
-
# default.rules
|
|
15
|
-
# 允许常见只读命令直接执行,其余命令走人工审批
|
|
16
|
-
|
|
17
|
-
load("builtin://rules/rules.star", "prefix_rule")
|
|
18
|
-
|
|
19
|
-
rules = [
|
|
20
|
-
prefix_rule(["ls"], action="allow"),
|
|
21
|
-
prefix_rule(["cat"], action="allow"),
|
|
22
|
-
prefix_rule(["rg"], action="allow"),
|
|
23
|
-
prefix_rule(["git", "status"], action="allow"),
|
|
24
|
-
]
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## 建议策略
|
|
28
|
-
|
|
29
|
-
1. 先放行只读命令(`ls`/`cat`/`rg`/`git status`)。
|
|
30
|
-
2. 对写操作、网络请求、脚本执行保持 `review` 或 `deny`。
|
|
31
|
-
3. 团队场景下,将策略文件纳入内部安全评审流程。
|
|
32
|
-
|
|
33
|
-
## 与 `antigravity.rules` 的关系
|
|
34
|
-
|
|
35
|
-
- `antigravity.rules`:本仓库在工作区注入的托管说明内容,用于记录受管资源与运维约束。
|
|
36
|
-
- `.rules`:Codex 官方可执行审批规则(Starlark),影响命令放行策略。
|
package/docs/mapping-spec.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Codex(代码智能体环境)资源映射规范
|
|
2
|
-
|
|
3
|
-
Codex(代码智能体环境)适配器包含一个内置的资源转换层(`bin/core/`),负责将通用的 Agent(智能体)能力描述、Skill(技能)与 Workflow(工作流)转换为 Codex 兼容的标准化格式。
|
|
4
|
-
|
|
5
|
-
## 转换规则
|
|
6
|
-
|
|
7
|
-
### 1. Skill(技能)
|
|
8
|
-
|
|
9
|
-
- **源路径**: `.agent/skills/<name>/SKILL.md`
|
|
10
|
-
- **Codex ID(标识)**: `<name>`(保持与上游技能名一致)
|
|
11
|
-
- **目标路径**: `.agents/skills/<name>/SKILL.md`
|
|
12
|
-
|
|
13
|
-
### 2. Workflow(工作流)
|
|
14
|
-
|
|
15
|
-
- **源路径**: `.agent/workflows/<name>.md`
|
|
16
|
-
- **Codex ID(标识)**: `workflow-<name>`
|
|
17
|
-
- **目标路径**: `.agents/skills/workflow-<name>/SKILL.md`
|
|
18
|
-
- **说明**: 工作流会转换为符合 Codex 规范的 `SKILL.md`(自动补齐 `name` / `description` Frontmatter(文档头元数据))。
|
|
19
|
-
- **冲突处理**: 若生成 ID 与现有 Skill/Workflow 冲突,构建器会自动追加 `-2`、`-3`... 后缀,确保 ID 和目录唯一。
|
|
20
|
-
|
|
21
|
-
## 托管文件生成
|
|
22
|
-
|
|
23
|
-
### `codex.json` 元数据
|
|
24
|
-
|
|
25
|
-
包含版本信息和所有资源的清单映射。
|
|
26
|
-
|
|
27
|
-
### `AGENTS.md` 规则接入点
|
|
28
|
-
|
|
29
|
-
自动生成的 Markdown 文件,列出所有 Capabilities(能力)并声明版本。
|
|
30
|
-
安装/更新时,CLI(命令行界面)会把该内容注入工作区根目录 `AGENTS.md` 的托管区块中(不会覆盖用户自定义内容)。
|
|
31
|
-
|
|
32
|
-
### `antigravity.rules` 风险控制
|
|
33
|
-
|
|
34
|
-
自动生成风险控制规则,安装/更新时同样会注入工作区根目录 `antigravity.rules` 的托管区块。
|
|
35
|
-
|
|
36
|
-
> 注意:这里的 `antigravity.rules` 是本项目的托管说明文件,不是 Codex 官方 `.rules` 审批策略文件。
|
|
37
|
-
> 如需配置 Codex 官方审批规则,请单独维护 `~/.codex/rules/default.rules`(参考 `docs/codex-rules-template.md`)。
|
|
38
|
-
|
|
39
|
-
### `manifest.json` 托管清单
|
|
40
|
-
|
|
41
|
-
用于完整性与漂移检测,核心结构如下:
|
|
42
|
-
|
|
43
|
-
```json
|
|
44
|
-
{
|
|
45
|
-
"version": 2,
|
|
46
|
-
"target": "codex",
|
|
47
|
-
"kitVersion": "2.0.1",
|
|
48
|
-
"files": {
|
|
49
|
-
"skills/example-skill/SKILL.md": {
|
|
50
|
-
"hash": "sha256...",
|
|
51
|
-
"source": "bundled/skills/example-skill/SKILL.md"
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
覆盖策略:仅当当前文件 hash(哈希)同时满足 `当前文件 hash != manifest hash` 且 `当前文件 hash != 新版本 hash` 时,才会备份并覆盖。
|
|
58
|
-
|
|
59
|
-
## 动态构建
|
|
60
|
-
|
|
61
|
-
当使用 `ag-kit init --target codex` 安装旧版 Gemini 结构的仓库时,CLI 会自动触发 Just-in-Time Build(即时构建)流程:
|
|
62
|
-
|
|
63
|
-
1. 克隆/读取源仓库。
|
|
64
|
-
2. 识别为 Legacy(旧版)结构(`.agent/skills` 存在但无 `manifest.json`)。
|
|
65
|
-
3. 在临时目录启动构建流水线。
|
|
66
|
-
4. 将构建产物安装到项目的 `.agents` 目录(若检测到旧版 `.codex` 会自动迁移/清理)。
|
|
67
|
-
|
|
68
|
-
此过程对用户透明。
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# 多目标适配器
|
|
2
|
-
|
|
3
|
-
当前版本引入多目标适配器架构,支持在同一项目中共存并管理不同类型的 Agent(智能体)模板源。
|
|
4
|
-
|
|
5
|
-
## 架构概览
|
|
6
|
-
|
|
7
|
-
```mermaid
|
|
8
|
-
graph TD
|
|
9
|
-
CLI[ag-kit CLI] --> Router[Target Router]
|
|
10
|
-
Router --> |target=gemini| Gemini[GeminiAdapter (.agent)]
|
|
11
|
-
Router --> |target=codex| Codex[CodexAdapter (.agents)]
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## 支持的目标
|
|
15
|
-
|
|
16
|
-
### 1. Gemini(旧版)
|
|
17
|
-
|
|
18
|
-
- **标识**: `gemini`
|
|
19
|
-
- **存储**: `.agent/`(直连模式)
|
|
20
|
-
- **特点**: 轻量级,直接克隆自 Git 仓库或本地模板。
|
|
21
|
-
- **适用**: 个人开发者、快速原型、不强制版本控制的场景。
|
|
22
|
-
|
|
23
|
-
### 2. Codex(代码智能体环境)
|
|
24
|
-
|
|
25
|
-
- **标识**: `codex`
|
|
26
|
-
- **存储**:
|
|
27
|
-
- `.agents/`(托管上游,用户不可修改)
|
|
28
|
-
- `.agents-backup/`(发生覆盖冲突时自动备份)
|
|
29
|
-
- `AGENTS.md` / `antigravity.rules`(工作区托管区块注入)
|
|
30
|
-
- **特点**:
|
|
31
|
-
- **Drift Detection(漂移检测)**: 自动识别用户对托管文件的修改。
|
|
32
|
-
- **Atomic Update(原子更新)**: 防止更新中断导致损坏。
|
|
33
|
-
- **资源映射**: 自动将标准 Skill(技能)/Workflow(工作流)转换为 Codex 规范。
|
|
34
|
-
- **遗留迁移**: 自动识别旧版 `.codex/` 并迁移到 `.agents/`。
|
|
35
|
-
- **适用**: 团队协作、生产环境、需要严格版本管理和升级保障的场景。
|
|
36
|
-
|
|
37
|
-
> 说明:`antigravity.rules` 是 Ag-Kit 注入的托管说明内容,不等同于 Codex 官方 `.rules`(命令审批执行规则)。
|
|
38
|
-
|
|
39
|
-
## 命令行用法
|
|
40
|
-
|
|
41
|
-
CLI(命令行界面)命令如下。
|
|
42
|
-
|
|
43
|
-
### 安装/初始化
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
# 安装 Gemini
|
|
47
|
-
ag-kit init --target gemini
|
|
48
|
-
|
|
49
|
-
# 安装 Codex
|
|
50
|
-
ag-kit init --target codex
|
|
51
|
-
|
|
52
|
-
# 交互选择目标,TTY(终端)下无默认值
|
|
53
|
-
ag-kit init
|
|
54
|
-
|
|
55
|
-
# 临时目录验证(跳过全局索引登记)
|
|
56
|
-
ag-kit init --target codex --no-index
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 更新
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# 更新当前项目(自动检测已安装目标)
|
|
63
|
-
ag-kit update
|
|
64
|
-
|
|
65
|
-
# 强制更新指定目标
|
|
66
|
-
ag-kit update --target codex
|
|
67
|
-
|
|
68
|
-
# 更新但不刷新全局索引
|
|
69
|
-
ag-kit update --target codex --no-index
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 诊断与修复
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# 检查所有目标健康状态
|
|
76
|
-
ag-kit doctor
|
|
77
|
-
|
|
78
|
-
# 尝试自动修复
|
|
79
|
-
ag-kit doctor --fix
|
|
80
|
-
```
|