agencyx-cli 0.0.0-stage → 0.1.0-dev.4
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/dist/adapters/agent.js +73 -0
- package/dist/adapters/ambient.js +35 -0
- package/dist/adapters/instructions.js +102 -0
- package/dist/adapters/mcp.js +237 -0
- package/dist/adapters/permissions.js +42 -0
- package/dist/adapters/plugins.js +484 -0
- package/dist/agency/invocation.js +97 -0
- package/dist/agency/prepared-input.js +124 -0
- package/dist/bridge/execution.js +119 -0
- package/dist/bridge/main.js +26 -0
- package/dist/bridge/plan.js +268 -0
- package/dist/bridge/version.js +2 -0
- package/dist/cli-options.js +96 -0
- package/dist/cli.js +41 -0
- package/dist/codex/agents.js +72 -0
- package/dist/codex/app-server.js +116 -0
- package/dist/codex/inspection.js +217 -0
- package/dist/codex/mcp-readiness.js +45 -0
- package/dist/codex/native-plugins.js +109 -0
- package/dist/codex/options.js +170 -0
- package/dist/codex/plugin-hooks.js +93 -0
- package/dist/codex/rpc.js +170 -0
- package/dist/codex/session-proxy.js +258 -0
- package/dist/codex/skill-policy.js +69 -0
- package/dist/codex/skill-views.js +104 -0
- package/dist/codex/toml.js +46 -0
- package/dist/commands/codex.js +118 -0
- package/dist/commands/doctor.js +58 -0
- package/dist/commands/passthrough.js +14 -0
- package/dist/diagnostics/plan.js +87 -0
- package/dist/diagnostics.js +39 -0
- package/dist/model.js +2 -0
- package/dist/runtime/ipc.js +316 -0
- package/dist/runtime/process.js +286 -0
- package/dist/runtime/resolve-command.js +38 -0
- package/dist/runtime/session.js +107 -0
- package/dist/validation.js +31 -0
- package/package.json +41 -4
- package/README.md +0 -3
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { mkdtemp, chmod, writeFile, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
5
|
+
import { COPILOT_PROTOCOL_VERSION } from "../bridge/version.js";
|
|
6
|
+
export async function createSession(parent = tmpdir()) {
|
|
7
|
+
const root = await mkdtemp(path.join(parent, "agencyx-"));
|
|
8
|
+
await chmod(root, 0o700);
|
|
9
|
+
const id = randomUUID();
|
|
10
|
+
const token = randomBytes(32).toString("hex");
|
|
11
|
+
const endpoint = process.platform === "win32"
|
|
12
|
+
? `\\\\.\\pipe\\agencyx-${process.pid}-${id}`
|
|
13
|
+
: path.join(root, "control.sock");
|
|
14
|
+
return {
|
|
15
|
+
id,
|
|
16
|
+
root,
|
|
17
|
+
token,
|
|
18
|
+
endpoint,
|
|
19
|
+
dispose: () => rm(root, { recursive: true, force: true, maxRetries: 3 }),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export const WINDOWS_LAUNCHER = String.raw `$ErrorActionPreference = 'Stop'
|
|
23
|
+
$sessionFile = [System.IO.Path]::Combine($PSScriptRoot, 'session.json')
|
|
24
|
+
|
|
25
|
+
# Keep Agency's version probe within its five-second budget, including cold
|
|
26
|
+
# PowerShell startup. Execution still authenticates through the Node bridge.
|
|
27
|
+
if ($args.Count -eq 1 -and $args[0] -in @('--version', '--binary-version', '-V')) {
|
|
28
|
+
if (-not [System.IO.File]::Exists($sessionFile)) { exit 6 }
|
|
29
|
+
[Console]::Out.WriteLine('GitHub Copilot CLI ${COPILOT_PROTOCOL_VERSION}')
|
|
30
|
+
exit 0
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Keep the waiting host alive when Ctrl+C is delivered to the foreground group.
|
|
34
|
+
# The Node bridge and Codex receive the same console event independently.
|
|
35
|
+
Add-Type -TypeDefinition @'
|
|
36
|
+
using System;
|
|
37
|
+
using System.Runtime.InteropServices;
|
|
38
|
+
public static class AgencyxConsoleHost {
|
|
39
|
+
private delegate bool Handler(uint kind);
|
|
40
|
+
private static readonly Handler KeepAlive = kind => kind == 0 || kind == 1;
|
|
41
|
+
[DllImport("kernel32.dll")]
|
|
42
|
+
private static extern bool SetConsoleCtrlHandler(Handler handler, bool add);
|
|
43
|
+
public static void Initialize() { SetConsoleCtrlHandler(KeepAlive, true); }
|
|
44
|
+
}
|
|
45
|
+
'@
|
|
46
|
+
[AgencyxConsoleHost]::Initialize()
|
|
47
|
+
try {
|
|
48
|
+
$session = [System.IO.File]::ReadAllText($sessionFile) | Microsoft.PowerShell.Utility\ConvertFrom-Json
|
|
49
|
+
} catch {
|
|
50
|
+
[Console]::Error.WriteLine('AGENCYX_LAUNCHER_FAILED: Could not read the private session context.')
|
|
51
|
+
exit 6
|
|
52
|
+
}
|
|
53
|
+
$env:AGENCYX_SESSION_FILE = $sessionFile
|
|
54
|
+
|
|
55
|
+
function ConvertTo-NativeArgument {
|
|
56
|
+
param([AllowEmptyString()][string] $Value)
|
|
57
|
+
$escaped = [regex]::Replace($Value, '(\\*)"', '$1$1\"')
|
|
58
|
+
$escaped = [regex]::Replace($escaped, '(\\+)$', '$1$1')
|
|
59
|
+
return '"' + $escaped + '"'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
$start = New-Object System.Diagnostics.ProcessStartInfo
|
|
63
|
+
$start.FileName = $session.nodePath
|
|
64
|
+
$start.WorkingDirectory = $session.cwd
|
|
65
|
+
$start.UseShellExecute = $false
|
|
66
|
+
$values = @($session.entryPath, '__bridge') + @($args)
|
|
67
|
+
$start.Arguments = ($values | ForEach-Object { ConvertTo-NativeArgument $_ }) -join ' '
|
|
68
|
+
$child = New-Object System.Diagnostics.Process
|
|
69
|
+
$child.StartInfo = $start
|
|
70
|
+
$status = 6
|
|
71
|
+
try {
|
|
72
|
+
if ($child.Start()) {
|
|
73
|
+
$child.WaitForExit()
|
|
74
|
+
$status = $child.ExitCode
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
[Console]::Error.WriteLine('AGENCYX_LAUNCHER_FAILED: Could not start the pinned Node bridge.')
|
|
78
|
+
} finally {
|
|
79
|
+
$child.Dispose()
|
|
80
|
+
}
|
|
81
|
+
exit $status
|
|
82
|
+
`;
|
|
83
|
+
export async function createLauncher(session, entryPath, nodePath = process.execPath, cwd = process.cwd()) {
|
|
84
|
+
const windows = process.platform === "win32";
|
|
85
|
+
const launcher = path.join(session.root, windows ? "bridge.ps1" : "bridge.sh");
|
|
86
|
+
const sessionFile = path.join(session.root, "session.json");
|
|
87
|
+
await writeFile(sessionFile, JSON.stringify({
|
|
88
|
+
protocol: 1,
|
|
89
|
+
id: session.id,
|
|
90
|
+
token: session.token,
|
|
91
|
+
endpoint: session.endpoint,
|
|
92
|
+
nodePath,
|
|
93
|
+
entryPath,
|
|
94
|
+
cwd,
|
|
95
|
+
}), { mode: 0o600 });
|
|
96
|
+
const shellQuote = (value) => `'${value.replaceAll("'", "'\"'\"'")}'`;
|
|
97
|
+
const contents = windows
|
|
98
|
+
? WINDOWS_LAUNCHER
|
|
99
|
+
: `#!/bin/sh\nAGENCYX_SESSION_FILE=${shellQuote(sessionFile)} exec ${shellQuote(nodePath)} ${shellQuote(entryPath)} __bridge "$@"\n`;
|
|
100
|
+
await writeFile(launcher, contents, { mode: 0o700 });
|
|
101
|
+
return { path: launcher, env: {} };
|
|
102
|
+
}
|
|
103
|
+
export function engineEnvironment(env) {
|
|
104
|
+
return Object.fromEntries(Object.entries(env).filter(([key]) => !key.toUpperCase().startsWith("AGENCYX_") &&
|
|
105
|
+
key !== "COPILOT_CUSTOM_INSTRUCTIONS_DIRS"));
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { fail } from "./diagnostics.js";
|
|
2
|
+
export function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
export function record(value, component) {
|
|
6
|
+
if (!isRecord(value))
|
|
7
|
+
fail("CONFIG_INVALID", "configuration", "Expected a JSON object.", {
|
|
8
|
+
component,
|
|
9
|
+
});
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
export function stringArray(value, component) {
|
|
13
|
+
if (!Array.isArray(value) ||
|
|
14
|
+
!value.every((item) => typeof item === "string" && !item.includes("\0"))) {
|
|
15
|
+
fail("CONFIG_INVALID", "configuration", "Expected an array of strings without NUL characters.", { component });
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
export function nonEmptyString(value, component) {
|
|
20
|
+
if (typeof value !== "string" || value.length === 0 || value.includes("\0")) {
|
|
21
|
+
fail("CONFIG_INVALID", "configuration", "Expected a non-empty string without NUL characters.", { component });
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
export function assertKnownFields(value, known, component, sourcePath) {
|
|
26
|
+
for (const key of Object.keys(value)) {
|
|
27
|
+
if (!known.includes(key))
|
|
28
|
+
fail("CONTRACT_UNSUPPORTED", "compatibility", "An unknown execution or permission field cannot be ignored.", { component, field: key, ...(sourcePath ? { path: sourcePath } : {}) });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=validation.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agencyx-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-dev.4",
|
|
4
|
+
"description": "Use Agency configuration and authentication with the official Codex CLI.",
|
|
5
|
+
"readme": " ",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"agencyx": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**/*.js"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=22.15.0"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json && node scripts/prepare-bin.mjs",
|
|
19
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
20
|
+
"format": "prettier --write src test scripts package.json tsconfig.json .github/workflows/ci.yml",
|
|
21
|
+
"format:check": "prettier --check src test scripts package.json tsconfig.json .github/workflows/ci.yml",
|
|
22
|
+
"test": "npm run build && node --test test/unit/*.test.mjs test/integration/*.test.mjs",
|
|
23
|
+
"test:coverage": "npm run build && c8 --all --src dist --include \"dist/**/*.js\" --exclude \"**/*.d.ts\" --exclude \"dist/model.js\" --reporter text --reporter lcov --reporter json-summary --check-coverage --lines 90 --functions 90 --branches 85 node --test test/unit/*.test.mjs test/integration/*.test.mjs",
|
|
24
|
+
"test:e2e": "npm run build && node --test --test-concurrency=1 test/e2e/*.test.mjs",
|
|
25
|
+
"check": "npm run typecheck && npm run test:coverage && npm run check:package",
|
|
26
|
+
"check:package": "node scripts/check-package.mjs",
|
|
27
|
+
"prepack": "npm run build && npm run check:package"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"cross-spawn": "^7.0.6",
|
|
31
|
+
"smol-toml": "^1.4.2",
|
|
32
|
+
"ws": "^8.18.3",
|
|
33
|
+
"yaml": "^2.8.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/cross-spawn": "^6.0.6",
|
|
37
|
+
"@types/node": "^22.15.0",
|
|
38
|
+
"@types/ws": "^8.18.1",
|
|
39
|
+
"c8": "^9.1.0",
|
|
40
|
+
"prettier": "^3.6.2",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/README.md
DELETED