fix(agent-grok): use json import for manifest metadata (#2040)

This commit is contained in:
yyovil 2026-05-23 16:22:44 +05:30 committed by GitHub
parent 19fcf42f20
commit cdd1030d8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 124 additions and 21 deletions

View File

@ -0,0 +1,8 @@
---
"@aoagents/ao": minor
"@aoagents/ao-cli": minor
"@aoagents/ao-web": minor
"@aoagents/ao-plugin-agent-grok": minor
---
Load agent-grok package metadata through JSON import attributes so packaged web and CLI runtimes do not keep a publish-host package.json lookup. This also raises the Node.js engine floor to 20.18.3+, where JSON modules with import attributes are non-experimental.

View File

@ -45,7 +45,7 @@ Agent Orchestrator manages fleets of AI coding agents working in parallel on you
## Quick Start
> **Prerequisites:** [Node.js 20+](https://nodejs.org), [Git 2.25+](https://git-scm.com), [`gh` CLI](https://cli.github.com), and:
> **Prerequisites:** [Node.js 20.18.3+](https://nodejs.org), [Git 2.25+](https://git-scm.com), [`gh` CLI](https://cli.github.com), and:
> - **macOS / Linux:** [tmux](https://github.com/tmux/tmux/wiki/Installing) — install via `brew install tmux` or `sudo apt install tmux`.
> - **Windows:** PowerShell 7+ recommended. tmux is **not** required — AO uses native ConPTY via the `runtime-process` plugin (the default on Windows). Set `AO_SHELL=bash` if you have Git Bash and prefer it.

View File

@ -87,7 +87,7 @@ For AI agent-specific guidance (including high-risk files like `types.ts`, `life
## Getting Started
**Prerequisites**: Node.js 20+, pnpm 9.15+, Git 2.25+
**Prerequisites**: Node.js 20.18.3+, pnpm 9.15+, Git 2.25+
```bash
git clone https://github.com/ComposioHQ/agent-orchestrator.git

View File

@ -5,7 +5,7 @@
"description": "Orchestrate parallel AI coding agents across any runtime, any repo, any issue tracker",
"license": "MIT",
"engines": {
"node": ">=20.0.0"
"node": ">=20.18.3"
},
"packageManager": "pnpm@9.15.4",
"type": "module",

View File

@ -25,7 +25,7 @@ npm install -g @aoagents/ao
> **Nightly builds** (latest `main`): `npm install -g @aoagents/ao@nightly` — back to stable with `@latest`.
**Prerequisites:** [Node.js 20+](https://nodejs.org), [Git 2.25+](https://git-scm.com), the [`gh` CLI](https://cli.github.com), and at least one coding-agent CLI (e.g. [Claude Code](https://www.anthropic.com/claude-code)).
**Prerequisites:** [Node.js 20.18.3+](https://nodejs.org), [Git 2.25+](https://git-scm.com), the [`gh` CLI](https://cli.github.com), and at least one coding-agent CLI (e.g. [Claude Code](https://www.anthropic.com/claude-code)).
- **macOS / Linux:** [tmux](https://github.com/tmux/tmux/wiki/Installing) — `brew install tmux` or `sudo apt install tmux`.
- **Windows:** PowerShell 7+ recommended; tmux is **not** required (AO uses native ConPTY via the `process` runtime).

View File

@ -39,7 +39,7 @@
"url": "https://github.com/ComposioHQ/agent-orchestrator/issues"
},
"engines": {
"node": ">=20.0.0"
"node": ">=20.18.3"
},
"dependencies": {
"@aoagents/ao-cli": "workspace:*"

View File

@ -22,7 +22,7 @@
"url": "https://github.com/ComposioHQ/agent-orchestrator/issues"
},
"engines": {
"node": ">=20.0.0"
"node": ">=20.18.3"
},
"scripts": {
"build": "tsc && node --input-type=commonjs -e \"require('fs').cpSync('src/assets','dist/assets',{recursive:true})\"",

View File

@ -25,7 +25,7 @@
"url": "https://github.com/ComposioHQ/agent-orchestrator/issues"
},
"engines": {
"node": ">=20.0.0"
"node": ">=20.18.3"
},
"scripts": {
"build": "tsc",

View File

@ -1,13 +1,7 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import type { AgentLaunchConfig, RuntimeHandle, Session } from "@aoagents/ao-core";
import { createRequire } from "node:module";
import packageJson from "../../package.json" with { type: "json" };
const require = createRequire(import.meta.url);
const packageJson = require("../../package.json") as {
name: string;
version: string;
description: string;
};
const PACKAGE_NAME_PREFIX = "@aoagents/ao-plugin-agent-";
const pluginName = packageJson.name.startsWith(PACKAGE_NAME_PREFIX)
? packageJson.name.slice(PACKAGE_NAME_PREFIX.length)
@ -144,6 +138,7 @@ beforeEach(() => {
describe("manifest", () => {
it("has correct Grok manifest", () => {
expect(manifest.version).toBe(packageJson.version);
expect(manifest).toEqual({
name: pluginName,
slot: "agent",

View File

@ -0,0 +1,101 @@
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import ts from "typescript";
import { describe, expect, it } from "vitest";
import packageJson from "../../package.json" with { type: "json" };
import { manifest } from "../index.js";
const testFilePath = fileURLToPath(import.meta.url);
const packageRoot = path.resolve(path.dirname(testFilePath), "../..");
const sourcePath = path.join(packageRoot, "src/index.ts");
const forbiddenPackageMetadataLookups = [
"createRequire(import.meta.url)",
'require("../package.json")',
'readFileSync(new URL("../package.json", import.meta.url))',
];
function assertPackageMetadataImportPattern(label: string, source: string): void {
for (const forbidden of forbiddenPackageMetadataLookups) {
expect(source, `${label} must not contain ${forbidden}`).not.toContain(forbidden);
}
const packageJsonImports = [...source.matchAll(/from\s+["']\.\.\/package\.json["'][^;]*/g)].map(
(match) => match[0],
);
expect(packageJsonImports.length, `${label} imports ../package.json`).toBeGreaterThan(0);
for (const importStatement of packageJsonImports) {
expect(
importStatement,
`${label} package.json import must use a JSON import attribute`,
).toMatch(/\swith\s*\{\s*type:\s*["']json["']\s*\}/);
}
}
function compileAgentGrokTo(outDir: string): void {
const configPath = path.join(packageRoot, "tsconfig.json");
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
if (configFile.error) {
throw new Error(
ts.formatDiagnosticsWithColorAndContext([configFile.error], {
getCanonicalFileName: (fileName) => fileName,
getCurrentDirectory: ts.sys.getCurrentDirectory,
getNewLine: () => ts.sys.newLine,
}),
);
}
const parsedConfig = ts.parseJsonConfigFileContent(
configFile.config,
ts.sys,
packageRoot,
{
declaration: false,
declarationMap: false,
outDir,
sourceMap: false,
},
configPath,
);
const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options);
const emitResult = program.emit();
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
if (emitResult.emitSkipped || diagnostics.length > 0) {
const message =
diagnostics.length > 0
? ts.formatDiagnosticsWithColorAndContext(diagnostics, {
getCanonicalFileName: (fileName) => fileName,
getCurrentDirectory: ts.sys.getCurrentDirectory,
getNewLine: () => ts.sys.newLine,
})
: "TypeScript emit skipped without diagnostics.";
throw new Error(message);
}
}
describe("package metadata import", () => {
it("keeps manifest version in sync with package.json", () => {
expect(manifest.version).toBe(packageJson.version);
});
it("uses JSON import attributes in the source runtime module", async () => {
const source = await readFile(sourcePath, "utf8");
assertPackageMetadataImportPattern("src/index.ts", source);
});
it("uses JSON import attributes in the compiled runtime module", async () => {
const outDir = await mkdtemp(path.join(tmpdir(), "ao-agent-grok-"));
try {
compileAgentGrokTo(outDir);
const compiledSource = await readFile(path.join(outDir, "index.js"), "utf8");
assertPackageMetadataImportPattern("compiled index.js", compiledSource);
} finally {
await rm(outDir, { force: true, recursive: true });
}
});
});

View File

@ -22,17 +22,11 @@ import {
type WorkspaceHooksConfig,
} from "@aoagents/ao-core";
import { execFile } from "node:child_process";
import { createRequire } from "node:module";
import { setTimeout as sleep } from "node:timers/promises";
import { promisify } from "node:util";
import which from "which";
import packageJson from "../package.json" with { type: "json" };
const require = createRequire(import.meta.url);
const packageJson = require("../package.json") as {
name: string;
version: string;
description: string;
};
const PACKAGE_NAME_PREFIX = "@aoagents/ao-plugin-agent-";
const pluginName = packageJson.name.startsWith(PACKAGE_NAME_PREFIX)
? packageJson.name.slice(PACKAGE_NAME_PREFIX.length)

View File

@ -1,6 +1,8 @@
{
"extends": "../../../tsconfig.node.json",
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src"
},

View File

@ -13,6 +13,9 @@
"bugs": {
"url": "https://github.com/ComposioHQ/agent-orchestrator/issues"
},
"engines": {
"node": ">=20.18.3"
},
"publishConfig": {
"access": "public",
"provenance": true