@praxis.guard/auditor-cli 0.0.51 → 0.0.52
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/README.vscode.md +48 -0
- package/dist/adapters/copilot-cli/adapter.d.ts +10 -0
- package/dist/adapters/copilot-cli/adapter.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/adapter.js +105 -0
- package/dist/adapters/copilot-cli/adapter.js.map +1 -0
- package/dist/adapters/copilot-cli/config.d.ts +18 -0
- package/dist/adapters/copilot-cli/config.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/config.js +118 -0
- package/dist/adapters/copilot-cli/config.js.map +1 -0
- package/dist/adapters/copilot-cli/index.d.ts +3 -0
- package/dist/adapters/copilot-cli/index.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/index.js +3 -0
- package/dist/adapters/copilot-cli/index.js.map +1 -0
- package/dist/adapters/copilot-cli/paths.d.ts +8 -0
- package/dist/adapters/copilot-cli/paths.d.ts.map +1 -0
- package/dist/adapters/copilot-cli/paths.js +18 -0
- package/dist/adapters/copilot-cli/paths.js.map +1 -0
- package/dist/adapters/copilot-cli.d.ts +1 -13
- package/dist/adapters/copilot-cli.d.ts.map +1 -1
- package/dist/adapters/copilot-cli.js +1 -231
- package/dist/adapters/copilot-cli.js.map +1 -1
- package/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +2 -0
- package/dist/adapters/registry.js.map +1 -1
- package/dist/adapters/types.d.ts +1 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/vscode.d.ts +9 -0
- package/dist/adapters/vscode.d.ts.map +1 -0
- package/dist/adapters/vscode.js +87 -0
- package/dist/adapters/vscode.js.map +1 -0
- package/dist/codex/config-hooks.d.ts +7 -0
- package/dist/codex/config-hooks.d.ts.map +1 -0
- package/dist/codex/config-hooks.js +61 -0
- package/dist/codex/config-hooks.js.map +1 -0
- package/dist/codex/config-io.d.ts +6 -0
- package/dist/codex/config-io.d.ts.map +1 -0
- package/dist/codex/config-io.js +34 -0
- package/dist/codex/config-io.js.map +1 -0
- package/dist/codex/config-toml.d.ts +4 -0
- package/dist/codex/config-toml.d.ts.map +1 -0
- package/dist/codex/config-toml.js +65 -0
- package/dist/codex/config-toml.js.map +1 -0
- package/dist/codex/config.d.ts +1 -4
- package/dist/codex/config.d.ts.map +1 -1
- package/dist/codex/config.js +8 -152
- package/dist/codex/config.js.map +1 -1
- package/package.json +1 -1
package/README.vscode.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# VS Code integration for `auditor` CLI
|
|
2
|
+
|
|
3
|
+
This document explains how the `vscode` AgentAdapter integrates Visual Studio Code with the `auditor` CLI and how to enable it in your development environment.
|
|
4
|
+
|
|
5
|
+
What it does
|
|
6
|
+
- The `vscode` adapter writes `PRAXIS_AGENT_HOST = "vscode"` into your VS Code user settings under the appropriate `terminal.integrated.env.*` key for your platform. This ensures terminals and tasks launched by VS Code receive the env var so the Praxis MCP heartbeat and telemetry can tag calls coming from VS Code.
|
|
7
|
+
|
|
8
|
+
Where it writes
|
|
9
|
+
- macOS: `~/Library/Application Support/Code/User/settings.json`
|
|
10
|
+
- Linux: `~/.config/Code/User/settings.json`
|
|
11
|
+
- Windows: `%APPDATA%/Code/User/settings.json`
|
|
12
|
+
|
|
13
|
+
Enable (write changes)
|
|
14
|
+
Run the auditor CLI (package must be built) to write settings:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm --filter @praxis.guard/auditor-cli run -- auditor setup mcp --for=vscode
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
You can also include VS Code when configuring all known adapters:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm --filter @praxis.guard/auditor-cli run -- auditor setup all
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Dry-run (preview changes)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm --filter @praxis.guard/auditor-cli run -- auditor setup mcp --for=vscode --dry-run
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Verify (doctor)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm --filter @praxis.guard/auditor-cli run -- auditor setup doctor
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Notes and troubleshooting
|
|
39
|
+
- After `auditor setup mcp --for=vscode` you must restart VS Code for terminal env changes to take effect.
|
|
40
|
+
- To undo the change, remove `PRAXIS_AGENT_HOST` from the `terminal.integrated.env.*` block in your user `settings.json`.
|
|
41
|
+
- The adapter only detects VS Code when a user settings file exists; if you want the CLI to target VS Code in CI or unusual environments, provide the explicit `--user-config`/`--for` flags as supported by the `auditor` setup commands.
|
|
42
|
+
|
|
43
|
+
Security
|
|
44
|
+
- The adapter only writes a single string env var into user settings. It does not change other settings or commit repository files.
|
|
45
|
+
|
|
46
|
+
Where to look in the code
|
|
47
|
+
- Adapter implementation: `packages/auditor-cli/src/adapters/vscode.ts`
|
|
48
|
+
- Tests: `packages/auditor-cli/src/adapters/vscode.test.ts`
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AgentAdapter, AgentStatus, SetupResult, StatusOpts, UpsertHookOpts, UpsertMcpOpts } from "../types.js";
|
|
2
|
+
export declare class CopilotCliAdapter implements AgentAdapter {
|
|
3
|
+
readonly id: "copilot-cli";
|
|
4
|
+
readonly label = "GitHub Copilot CLI";
|
|
5
|
+
detectInstalled(): boolean;
|
|
6
|
+
upsertHook(opts: UpsertHookOpts): Promise<SetupResult>;
|
|
7
|
+
upsertMcp(opts: UpsertMcpOpts): Promise<SetupResult>;
|
|
8
|
+
status(opts?: StatusOpts): Promise<AgentStatus>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAsBrB,qBAAa,iBAAkB,YAAW,YAAY;IACpD,QAAQ,CAAC,EAAE,EAAG,aAAa,CAAU;IACrC,QAAQ,CAAC,KAAK,wBAAwB;IAEtC,eAAe,IAAI,OAAO;IAIpB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAmBtD,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IA2BpD,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CA8CtD"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readJson, writeJsonAtomic } from "../claude-code/config-io.js";
|
|
4
|
+
import { asJsonMap, cloneJson, commandAvailable, hasConfiguredMcp, hasPraxisHook, hookConfigsInDir, readForStatus, statusWarnings, upsertPraxisHook, } from "./config.js";
|
|
5
|
+
import { AGENT_HOST, copilotGlobalHooksPath, copilotHomeDir, copilotMcpConfigPath, copilotProjectSettingsPath, MCP_SERVER_KEY, } from "./paths.js";
|
|
6
|
+
export class CopilotCliAdapter {
|
|
7
|
+
id = "copilot-cli";
|
|
8
|
+
label = "GitHub Copilot CLI";
|
|
9
|
+
detectInstalled() {
|
|
10
|
+
return existsSync(copilotHomeDir());
|
|
11
|
+
}
|
|
12
|
+
async upsertHook(opts) {
|
|
13
|
+
const project = opts.projectDir || process.cwd();
|
|
14
|
+
const cfgPath = opts.explicitPath?.trim() || (opts.scope === "project"
|
|
15
|
+
? copilotProjectSettingsPath(project)
|
|
16
|
+
: copilotGlobalHooksPath());
|
|
17
|
+
const existing = await readJson(cfgPath);
|
|
18
|
+
const config = cloneJson(existing);
|
|
19
|
+
upsertPraxisHook(config, opts.scope === "global");
|
|
20
|
+
const changed = JSON.stringify(existing ?? {}) !== JSON.stringify(config);
|
|
21
|
+
if (changed && !opts.dryRun)
|
|
22
|
+
await writeJsonAtomic(cfgPath, config);
|
|
23
|
+
return {
|
|
24
|
+
path: cfgPath,
|
|
25
|
+
changed,
|
|
26
|
+
message: changed
|
|
27
|
+
? opts.dryRun ? "would update GitHub Copilot CLI preToolUse hook" : "updated GitHub Copilot CLI preToolUse hook"
|
|
28
|
+
: "GitHub Copilot CLI preToolUse hook already up to date",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async upsertMcp(opts) {
|
|
32
|
+
const cfgPath = opts.explicitPath?.trim() || copilotMcpConfigPath();
|
|
33
|
+
const existing = await readJson(cfgPath);
|
|
34
|
+
const config = cloneJson(existing);
|
|
35
|
+
const servers = asJsonMap(config.mcpServers) ?? {};
|
|
36
|
+
config.mcpServers = servers;
|
|
37
|
+
const entry = asJsonMap(servers[MCP_SERVER_KEY]) ?? {};
|
|
38
|
+
const env = asJsonMap(entry.env) ?? {};
|
|
39
|
+
servers[MCP_SERVER_KEY] = {
|
|
40
|
+
...entry,
|
|
41
|
+
type: "local",
|
|
42
|
+
command: "auditor",
|
|
43
|
+
args: ["mcp"],
|
|
44
|
+
env: { ...env, PRAXIS_AGENT_HOST: AGENT_HOST },
|
|
45
|
+
tools: ["*"],
|
|
46
|
+
};
|
|
47
|
+
const changed = JSON.stringify(existing ?? {}) !== JSON.stringify(config);
|
|
48
|
+
if (changed && !opts.dryRun)
|
|
49
|
+
await writeJsonAtomic(cfgPath, config);
|
|
50
|
+
return {
|
|
51
|
+
path: cfgPath,
|
|
52
|
+
changed,
|
|
53
|
+
message: changed
|
|
54
|
+
? opts.dryRun ? "would update GitHub Copilot CLI MCP config" : "updated GitHub Copilot CLI MCP config"
|
|
55
|
+
: "GitHub Copilot CLI MCP config already up to date",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async status(opts) {
|
|
59
|
+
const projectDir = opts?.projectDir || process.cwd();
|
|
60
|
+
const globalPath = copilotGlobalHooksPath();
|
|
61
|
+
const projectPath = copilotProjectSettingsPath(projectDir);
|
|
62
|
+
const repositorySettingsPath = path.join(projectDir, ".github", "copilot", "settings.json");
|
|
63
|
+
const userSettingsPath = path.join(copilotHomeDir(), "settings.json");
|
|
64
|
+
const mcpPath = opts?.mcpConfigPath?.trim() || copilotMcpConfigPath();
|
|
65
|
+
const warnings = [];
|
|
66
|
+
const [globalConfig, projectConfig, repositoryConfig, userConfig, mcpConfig, userHookFiles, projectHookFiles] = await Promise.all([
|
|
67
|
+
readForStatus(globalPath, warnings),
|
|
68
|
+
readForStatus(projectPath, warnings),
|
|
69
|
+
readForStatus(repositorySettingsPath, warnings),
|
|
70
|
+
readForStatus(userSettingsPath, warnings),
|
|
71
|
+
readForStatus(mcpPath, warnings),
|
|
72
|
+
hookConfigsInDir(path.join(copilotHomeDir(), "hooks"), globalPath),
|
|
73
|
+
hookConfigsInDir(path.join(projectDir, ".github", "hooks")),
|
|
74
|
+
]);
|
|
75
|
+
const globalHook = hasPraxisHook(globalConfig);
|
|
76
|
+
const projectHook = hasPraxisHook(projectConfig);
|
|
77
|
+
const mcpConfigured = hasConfiguredMcp(mcpConfig);
|
|
78
|
+
const disabledConfigs = [projectConfig, repositoryConfig];
|
|
79
|
+
const disabled = disabledConfigs.some((config) => config?.disableAllHooks === true);
|
|
80
|
+
const auditorAvailable = commandAvailable("auditor");
|
|
81
|
+
const hookCount = [globalConfig, projectConfig, repositoryConfig, userConfig, ...userHookFiles, ...projectHookFiles]
|
|
82
|
+
.filter(hasPraxisHook).length;
|
|
83
|
+
const hookConfigured = globalHook || projectHook;
|
|
84
|
+
warnings.push(...statusWarnings({
|
|
85
|
+
hookConfigured,
|
|
86
|
+
mcpConfigured,
|
|
87
|
+
disabled,
|
|
88
|
+
hookCount,
|
|
89
|
+
auditorAvailable,
|
|
90
|
+
projectPath,
|
|
91
|
+
}));
|
|
92
|
+
return {
|
|
93
|
+
installed: this.detectInstalled(),
|
|
94
|
+
hook: {
|
|
95
|
+
global: { shell: globalHook && !disabled, mcp: globalHook && !disabled, path: globalPath, shellLabel: "preToolUse", mcpLabel: "preToolUse" },
|
|
96
|
+
project: { shell: projectHook && !disabled, mcp: projectHook && !disabled, path: projectPath, shellLabel: "preToolUse", mcpLabel: "preToolUse" },
|
|
97
|
+
},
|
|
98
|
+
mcp: { configured: mcpConfigured, path: mcpPath },
|
|
99
|
+
warnings,
|
|
100
|
+
ready: !disabled && auditorAvailable,
|
|
101
|
+
hookReady: hookConfigured && !disabled,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type JsonMap } from "../claude-code/config-io.js";
|
|
2
|
+
export declare function cloneJson(value: JsonMap | null): JsonMap;
|
|
3
|
+
export declare function asJsonMap(value: unknown): JsonMap | undefined;
|
|
4
|
+
export declare function hasPraxisHook(config: JsonMap | null): boolean;
|
|
5
|
+
export declare function upsertPraxisHook(config: JsonMap, includeVersion: boolean): void;
|
|
6
|
+
export declare function hasConfiguredMcp(config: JsonMap | null): boolean;
|
|
7
|
+
export declare function commandAvailable(command: string): boolean;
|
|
8
|
+
export declare function readForStatus(pathname: string, warnings: string[]): Promise<JsonMap | null>;
|
|
9
|
+
export declare function hookConfigsInDir(dir: string, excludedPath?: string): Promise<JsonMap[]>;
|
|
10
|
+
export declare function statusWarnings(input: {
|
|
11
|
+
hookConfigured: boolean;
|
|
12
|
+
mcpConfigured: boolean;
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
hookCount: number;
|
|
15
|
+
auditorAvailable: boolean;
|
|
16
|
+
projectPath: string;
|
|
17
|
+
}): string[];
|
|
18
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAIrE,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAExD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAG7D;AAOD,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAQ7D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAc/E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAShE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAczD;AAMD,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAOzB;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAU7F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,EAAE,CAYX"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { accessSync, constants } from "node:fs";
|
|
2
|
+
import { readdir } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readJson } from "../claude-code/config-io.js";
|
|
5
|
+
import { AGENT_HOST, HOOK_COMMAND, MCP_SERVER_KEY } from "./paths.js";
|
|
6
|
+
export function cloneJson(value) {
|
|
7
|
+
return value ? JSON.parse(JSON.stringify(value)) : {};
|
|
8
|
+
}
|
|
9
|
+
export function asJsonMap(value) {
|
|
10
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
11
|
+
return undefined;
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function matchesStringArray(value, expected) {
|
|
15
|
+
if (!Array.isArray(value) || value.length !== expected.length)
|
|
16
|
+
return false;
|
|
17
|
+
return expected.every((item, index) => value[index] === item);
|
|
18
|
+
}
|
|
19
|
+
export function hasPraxisHook(config) {
|
|
20
|
+
const hooks = config?.hooks;
|
|
21
|
+
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks))
|
|
22
|
+
return false;
|
|
23
|
+
const entries = hooks.preToolUse;
|
|
24
|
+
return Array.isArray(entries) && entries.some((entry) => {
|
|
25
|
+
if (!entry || typeof entry !== "object")
|
|
26
|
+
return false;
|
|
27
|
+
return entry.command === HOOK_COMMAND;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function upsertPraxisHook(config, includeVersion) {
|
|
31
|
+
if (includeVersion)
|
|
32
|
+
config.version = 1;
|
|
33
|
+
if (!config.hooks || typeof config.hooks !== "object" || Array.isArray(config.hooks)) {
|
|
34
|
+
config.hooks = {};
|
|
35
|
+
}
|
|
36
|
+
const hooks = config.hooks;
|
|
37
|
+
const entries = Array.isArray(hooks.preToolUse) ? hooks.preToolUse : [];
|
|
38
|
+
hooks.preToolUse = [
|
|
39
|
+
...entries.filter((entry) => {
|
|
40
|
+
if (!entry || typeof entry !== "object")
|
|
41
|
+
return true;
|
|
42
|
+
return entry.command !== HOOK_COMMAND;
|
|
43
|
+
}),
|
|
44
|
+
{ type: "command", command: HOOK_COMMAND },
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
export function hasConfiguredMcp(config) {
|
|
48
|
+
const servers = asJsonMap(config?.mcpServers);
|
|
49
|
+
if (!servers)
|
|
50
|
+
return false;
|
|
51
|
+
const entry = asJsonMap(servers[MCP_SERVER_KEY]);
|
|
52
|
+
if (!entry)
|
|
53
|
+
return false;
|
|
54
|
+
if (entry.type !== "local" || entry.command !== "auditor")
|
|
55
|
+
return false;
|
|
56
|
+
if (!matchesStringArray(entry.args, ["mcp"]))
|
|
57
|
+
return false;
|
|
58
|
+
if (!matchesStringArray(entry.tools, ["*"]))
|
|
59
|
+
return false;
|
|
60
|
+
return asJsonMap(entry.env)?.PRAXIS_AGENT_HOST === AGENT_HOST;
|
|
61
|
+
}
|
|
62
|
+
export function commandAvailable(command) {
|
|
63
|
+
const pathValue = process.env.PATH ?? "";
|
|
64
|
+
const extensions = process.platform === "win32"
|
|
65
|
+
? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
|
|
66
|
+
: [""];
|
|
67
|
+
return pathValue.split(path.delimiter).some((dir) => extensions.some((ext) => {
|
|
68
|
+
const candidate = path.join(dir || ".", `${command}${ext}`);
|
|
69
|
+
try {
|
|
70
|
+
accessSync(candidate, constants.X_OK);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
async function readOptional(pathname) {
|
|
79
|
+
return readJson(pathname).catch(() => null);
|
|
80
|
+
}
|
|
81
|
+
export async function readForStatus(pathname, warnings) {
|
|
82
|
+
try {
|
|
83
|
+
return await readJson(pathname);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
warnings.push(`Malformed Copilot config at ${pathname}: ${String(error)}`);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function hookConfigsInDir(dir, excludedPath) {
|
|
91
|
+
const names = await readdir(dir).catch(() => []);
|
|
92
|
+
const configs = await Promise.all(names
|
|
93
|
+
.filter((name) => name.endsWith(".json"))
|
|
94
|
+
.map(async (name) => {
|
|
95
|
+
const pathname = path.join(dir, name);
|
|
96
|
+
if (pathname === excludedPath)
|
|
97
|
+
return null;
|
|
98
|
+
return readOptional(pathname);
|
|
99
|
+
}));
|
|
100
|
+
return configs.filter((config) => config !== null);
|
|
101
|
+
}
|
|
102
|
+
export function statusWarnings(input) {
|
|
103
|
+
const warnings = [];
|
|
104
|
+
if (input.hookConfigured && !input.mcpConfigured) {
|
|
105
|
+
warnings.push("Hook is configured but MCP is missing. Run: auditor setup mcp --for=copilot-cli");
|
|
106
|
+
}
|
|
107
|
+
if (input.mcpConfigured && !input.hookConfigured) {
|
|
108
|
+
warnings.push("MCP is configured without an enforcing hook. Run: auditor setup hook --for=copilot-cli");
|
|
109
|
+
}
|
|
110
|
+
if (input.disabled)
|
|
111
|
+
warnings.push(`Hooks are disabled by ${input.projectPath}; set disableAllHooks to false.`);
|
|
112
|
+
if (input.hookCount > 1)
|
|
113
|
+
warnings.push("Duplicate Praxis Copilot hooks found; remove extra entries to avoid repeated evaluation.");
|
|
114
|
+
if (!input.auditorAvailable)
|
|
115
|
+
warnings.push("auditor is not available on PATH; install or expose the CLI before starting Copilot.");
|
|
116
|
+
return warnings;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const HOOK_COMMAND = "auditor hook copilot-cli";
|
|
2
|
+
export declare const MCP_SERVER_KEY = "praxis-guard";
|
|
3
|
+
export declare const AGENT_HOST = "copilot-cli";
|
|
4
|
+
export declare function copilotHomeDir(): string;
|
|
5
|
+
export declare function copilotGlobalHooksPath(): string;
|
|
6
|
+
export declare function copilotMcpConfigPath(): string;
|
|
7
|
+
export declare function copilotProjectSettingsPath(projectDir: string): string;
|
|
8
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,6BAA6B,CAAC;AACvD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAC7C,eAAO,MAAM,UAAU,gBAAgB,CAAC;AAExC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAErE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const HOOK_COMMAND = "auditor hook copilot-cli";
|
|
4
|
+
export const MCP_SERVER_KEY = "praxis-guard";
|
|
5
|
+
export const AGENT_HOST = "copilot-cli";
|
|
6
|
+
export function copilotHomeDir() {
|
|
7
|
+
return process.env.COPILOT_HOME?.trim() || path.join(os.homedir(), ".copilot");
|
|
8
|
+
}
|
|
9
|
+
export function copilotGlobalHooksPath() {
|
|
10
|
+
return path.join(copilotHomeDir(), "hooks", "praxis.json");
|
|
11
|
+
}
|
|
12
|
+
export function copilotMcpConfigPath() {
|
|
13
|
+
return path.join(copilotHomeDir(), "mcp-config.json");
|
|
14
|
+
}
|
|
15
|
+
export function copilotProjectSettingsPath(projectDir) {
|
|
16
|
+
return path.join(projectDir, ".github", "copilot", "settings.local.json");
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/adapters/copilot-cli/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,YAAY,GAAG,0BAA0B,CAAC;AACvD,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;AAExC,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function copilotHomeDir(): string;
|
|
3
|
-
export declare function copilotGlobalHooksPath(): string;
|
|
4
|
-
export declare function copilotMcpConfigPath(): string;
|
|
5
|
-
export declare function copilotProjectSettingsPath(projectDir: string): string;
|
|
6
|
-
export declare class CopilotCliAdapter implements AgentAdapter {
|
|
7
|
-
readonly id: "copilot-cli";
|
|
8
|
-
readonly label = "GitHub Copilot CLI";
|
|
9
|
-
detectInstalled(): boolean;
|
|
10
|
-
upsertHook(opts: UpsertHookOpts): Promise<SetupResult>;
|
|
11
|
-
upsertMcp(opts: UpsertMcpOpts): Promise<SetupResult>;
|
|
12
|
-
status(opts?: StatusOpts): Promise<AgentStatus>;
|
|
13
|
-
}
|
|
1
|
+
export { CopilotCliAdapter, copilotGlobalHooksPath, copilotHomeDir, copilotMcpConfigPath, copilotProjectSettingsPath, } from "./copilot-cli/index.js";
|
|
14
2
|
//# sourceMappingURL=copilot-cli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/copilot-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"copilot-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/copilot-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC"}
|
|
@@ -1,232 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { readdir } from "node:fs/promises";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { readJson, writeJsonAtomic } from "./claude-code/config-io.js";
|
|
6
|
-
const HOOK_COMMAND = "auditor hook copilot-cli";
|
|
7
|
-
const MCP_SERVER_KEY = "praxis-guard";
|
|
8
|
-
const AGENT_HOST = "copilot-cli";
|
|
9
|
-
export function copilotHomeDir() {
|
|
10
|
-
return process.env.COPILOT_HOME?.trim() || path.join(os.homedir(), ".copilot");
|
|
11
|
-
}
|
|
12
|
-
export function copilotGlobalHooksPath() {
|
|
13
|
-
return path.join(copilotHomeDir(), "hooks", "praxis.json");
|
|
14
|
-
}
|
|
15
|
-
export function copilotMcpConfigPath() {
|
|
16
|
-
return path.join(copilotHomeDir(), "mcp-config.json");
|
|
17
|
-
}
|
|
18
|
-
export function copilotProjectSettingsPath(projectDir) {
|
|
19
|
-
return path.join(projectDir, ".github", "copilot", "settings.local.json");
|
|
20
|
-
}
|
|
21
|
-
function cloneJson(value) {
|
|
22
|
-
return value ? JSON.parse(JSON.stringify(value)) : {};
|
|
23
|
-
}
|
|
24
|
-
function asJsonMap(value) {
|
|
25
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
26
|
-
return undefined;
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
function matchesStringArray(value, expected) {
|
|
30
|
-
if (!Array.isArray(value) || value.length !== expected.length)
|
|
31
|
-
return false;
|
|
32
|
-
return expected.every((item, index) => value[index] === item);
|
|
33
|
-
}
|
|
34
|
-
function hasPraxisHook(config) {
|
|
35
|
-
const hooks = config?.hooks;
|
|
36
|
-
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks))
|
|
37
|
-
return false;
|
|
38
|
-
const entries = hooks.preToolUse;
|
|
39
|
-
return Array.isArray(entries) && entries.some((entry) => {
|
|
40
|
-
if (!entry || typeof entry !== "object")
|
|
41
|
-
return false;
|
|
42
|
-
return entry.command === HOOK_COMMAND;
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function upsertPraxisHook(config, includeVersion) {
|
|
46
|
-
if (includeVersion)
|
|
47
|
-
config.version = 1;
|
|
48
|
-
if (!config.hooks || typeof config.hooks !== "object" || Array.isArray(config.hooks)) {
|
|
49
|
-
config.hooks = {};
|
|
50
|
-
}
|
|
51
|
-
const hooks = config.hooks;
|
|
52
|
-
const entries = Array.isArray(hooks.preToolUse) ? hooks.preToolUse : [];
|
|
53
|
-
hooks.preToolUse = [
|
|
54
|
-
...entries.filter((entry) => {
|
|
55
|
-
if (!entry || typeof entry !== "object")
|
|
56
|
-
return true;
|
|
57
|
-
return entry.command !== HOOK_COMMAND;
|
|
58
|
-
}),
|
|
59
|
-
{ type: "command", command: HOOK_COMMAND },
|
|
60
|
-
];
|
|
61
|
-
}
|
|
62
|
-
function hasConfiguredMcp(config) {
|
|
63
|
-
const servers = asJsonMap(config?.mcpServers);
|
|
64
|
-
if (!servers)
|
|
65
|
-
return false;
|
|
66
|
-
const entry = asJsonMap(servers[MCP_SERVER_KEY]);
|
|
67
|
-
if (!entry)
|
|
68
|
-
return false;
|
|
69
|
-
if (entry.type !== "local" || entry.command !== "auditor")
|
|
70
|
-
return false;
|
|
71
|
-
if (!matchesStringArray(entry.args, ["mcp"]))
|
|
72
|
-
return false;
|
|
73
|
-
if (!matchesStringArray(entry.tools, ["*"]))
|
|
74
|
-
return false;
|
|
75
|
-
return asJsonMap(entry.env)?.PRAXIS_AGENT_HOST === AGENT_HOST;
|
|
76
|
-
}
|
|
77
|
-
function commandAvailable(command) {
|
|
78
|
-
const pathValue = process.env.PATH ?? "";
|
|
79
|
-
const extensions = process.platform === "win32"
|
|
80
|
-
? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
|
|
81
|
-
: [""];
|
|
82
|
-
return pathValue.split(path.delimiter).some((dir) => extensions.some((ext) => {
|
|
83
|
-
const candidate = path.join(dir || ".", `${command}${ext}`);
|
|
84
|
-
try {
|
|
85
|
-
accessSync(candidate, constants.X_OK);
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
async function readOptional(pathname) {
|
|
94
|
-
return readJson(pathname).catch(() => null);
|
|
95
|
-
}
|
|
96
|
-
async function readForStatus(pathname, warnings) {
|
|
97
|
-
try {
|
|
98
|
-
return await readJson(pathname);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
warnings.push(`Malformed Copilot config at ${pathname}: ${String(error)}`);
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
async function hookConfigsInDir(dir, excludedPath) {
|
|
106
|
-
const names = await readdir(dir).catch(() => []);
|
|
107
|
-
const configs = await Promise.all(names
|
|
108
|
-
.filter((name) => name.endsWith(".json"))
|
|
109
|
-
.map(async (name) => {
|
|
110
|
-
const pathname = path.join(dir, name);
|
|
111
|
-
if (pathname === excludedPath)
|
|
112
|
-
return null;
|
|
113
|
-
return readOptional(pathname);
|
|
114
|
-
}));
|
|
115
|
-
return configs.filter((config) => config !== null);
|
|
116
|
-
}
|
|
117
|
-
function statusWarnings(input) {
|
|
118
|
-
const warnings = [];
|
|
119
|
-
if (input.hookConfigured && !input.mcpConfigured) {
|
|
120
|
-
warnings.push("Hook is configured but MCP is missing. Run: auditor setup mcp --for=copilot-cli");
|
|
121
|
-
}
|
|
122
|
-
if (input.mcpConfigured && !input.hookConfigured) {
|
|
123
|
-
warnings.push("MCP is configured without an enforcing hook. Run: auditor setup hook --for=copilot-cli");
|
|
124
|
-
}
|
|
125
|
-
if (input.disabled)
|
|
126
|
-
warnings.push(`Hooks are disabled by ${input.projectPath}; set disableAllHooks to false.`);
|
|
127
|
-
if (input.hookCount > 1)
|
|
128
|
-
warnings.push("Duplicate Praxis Copilot hooks found; remove extra entries to avoid repeated evaluation.");
|
|
129
|
-
if (!input.auditorAvailable)
|
|
130
|
-
warnings.push("auditor is not available on PATH; install or expose the CLI before starting Copilot.");
|
|
131
|
-
return warnings;
|
|
132
|
-
}
|
|
133
|
-
export class CopilotCliAdapter {
|
|
134
|
-
id = "copilot-cli";
|
|
135
|
-
label = "GitHub Copilot CLI";
|
|
136
|
-
detectInstalled() {
|
|
137
|
-
return existsSync(copilotHomeDir());
|
|
138
|
-
}
|
|
139
|
-
async upsertHook(opts) {
|
|
140
|
-
const project = opts.projectDir || process.cwd();
|
|
141
|
-
const cfgPath = opts.explicitPath?.trim() || (opts.scope === "project"
|
|
142
|
-
? copilotProjectSettingsPath(project)
|
|
143
|
-
: copilotGlobalHooksPath());
|
|
144
|
-
const existing = await readJson(cfgPath);
|
|
145
|
-
const config = cloneJson(existing);
|
|
146
|
-
upsertPraxisHook(config, opts.scope === "global");
|
|
147
|
-
const changed = JSON.stringify(existing ?? {}) !== JSON.stringify(config);
|
|
148
|
-
if (changed && !opts.dryRun)
|
|
149
|
-
await writeJsonAtomic(cfgPath, config);
|
|
150
|
-
return {
|
|
151
|
-
path: cfgPath,
|
|
152
|
-
changed,
|
|
153
|
-
message: changed
|
|
154
|
-
? opts.dryRun ? "would update GitHub Copilot CLI preToolUse hook" : "updated GitHub Copilot CLI preToolUse hook"
|
|
155
|
-
: "GitHub Copilot CLI preToolUse hook already up to date",
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
async upsertMcp(opts) {
|
|
159
|
-
const cfgPath = opts.explicitPath?.trim() || copilotMcpConfigPath();
|
|
160
|
-
const existing = await readJson(cfgPath);
|
|
161
|
-
const config = cloneJson(existing);
|
|
162
|
-
const servers = asJsonMap(config.mcpServers) ?? {};
|
|
163
|
-
config.mcpServers = servers;
|
|
164
|
-
const entry = asJsonMap(servers[MCP_SERVER_KEY]) ?? {};
|
|
165
|
-
const env = asJsonMap(entry.env) ?? {};
|
|
166
|
-
servers[MCP_SERVER_KEY] = {
|
|
167
|
-
...entry,
|
|
168
|
-
type: "local",
|
|
169
|
-
command: "auditor",
|
|
170
|
-
args: ["mcp"],
|
|
171
|
-
env: { ...env, PRAXIS_AGENT_HOST: AGENT_HOST },
|
|
172
|
-
tools: ["*"],
|
|
173
|
-
};
|
|
174
|
-
const changed = JSON.stringify(existing ?? {}) !== JSON.stringify(config);
|
|
175
|
-
if (changed && !opts.dryRun)
|
|
176
|
-
await writeJsonAtomic(cfgPath, config);
|
|
177
|
-
return {
|
|
178
|
-
path: cfgPath,
|
|
179
|
-
changed,
|
|
180
|
-
message: changed
|
|
181
|
-
? opts.dryRun ? "would update GitHub Copilot CLI MCP config" : "updated GitHub Copilot CLI MCP config"
|
|
182
|
-
: "GitHub Copilot CLI MCP config already up to date",
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
async status(opts) {
|
|
186
|
-
const projectDir = opts?.projectDir || process.cwd();
|
|
187
|
-
const globalPath = copilotGlobalHooksPath();
|
|
188
|
-
const projectPath = copilotProjectSettingsPath(projectDir);
|
|
189
|
-
const repositorySettingsPath = path.join(projectDir, ".github", "copilot", "settings.json");
|
|
190
|
-
const userSettingsPath = path.join(copilotHomeDir(), "settings.json");
|
|
191
|
-
const mcpPath = opts?.mcpConfigPath?.trim() || copilotMcpConfigPath();
|
|
192
|
-
const warnings = [];
|
|
193
|
-
const [globalConfig, projectConfig, repositoryConfig, userConfig, mcpConfig, userHookFiles, projectHookFiles] = await Promise.all([
|
|
194
|
-
readForStatus(globalPath, warnings),
|
|
195
|
-
readForStatus(projectPath, warnings),
|
|
196
|
-
readForStatus(repositorySettingsPath, warnings),
|
|
197
|
-
readForStatus(userSettingsPath, warnings),
|
|
198
|
-
readForStatus(mcpPath, warnings),
|
|
199
|
-
hookConfigsInDir(path.join(copilotHomeDir(), "hooks"), globalPath),
|
|
200
|
-
hookConfigsInDir(path.join(projectDir, ".github", "hooks")),
|
|
201
|
-
]);
|
|
202
|
-
const globalHook = hasPraxisHook(globalConfig);
|
|
203
|
-
const projectHook = hasPraxisHook(projectConfig);
|
|
204
|
-
const mcpConfigured = hasConfiguredMcp(mcpConfig);
|
|
205
|
-
const disabledConfigs = [projectConfig, repositoryConfig];
|
|
206
|
-
const disabled = disabledConfigs.some((config) => config?.disableAllHooks === true);
|
|
207
|
-
const auditorAvailable = commandAvailable("auditor");
|
|
208
|
-
const hookCount = [globalConfig, projectConfig, repositoryConfig, userConfig, ...userHookFiles, ...projectHookFiles]
|
|
209
|
-
.filter(hasPraxisHook).length;
|
|
210
|
-
const hookConfigured = globalHook || projectHook;
|
|
211
|
-
warnings.push(...statusWarnings({
|
|
212
|
-
hookConfigured,
|
|
213
|
-
mcpConfigured,
|
|
214
|
-
disabled,
|
|
215
|
-
hookCount,
|
|
216
|
-
auditorAvailable,
|
|
217
|
-
projectPath,
|
|
218
|
-
}));
|
|
219
|
-
return {
|
|
220
|
-
installed: this.detectInstalled(),
|
|
221
|
-
hook: {
|
|
222
|
-
global: { shell: globalHook && !disabled, mcp: globalHook && !disabled, path: globalPath, shellLabel: "preToolUse", mcpLabel: "preToolUse" },
|
|
223
|
-
project: { shell: projectHook && !disabled, mcp: projectHook && !disabled, path: projectPath, shellLabel: "preToolUse", mcpLabel: "preToolUse" },
|
|
224
|
-
},
|
|
225
|
-
mcp: { configured: mcpConfigured, path: mcpPath },
|
|
226
|
-
warnings,
|
|
227
|
-
ready: !disabled && auditorAvailable,
|
|
228
|
-
hookReady: hookConfigured && !disabled,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
1
|
+
export { CopilotCliAdapter, copilotGlobalHooksPath, copilotHomeDir, copilotMcpConfigPath, copilotProjectSettingsPath, } from "./copilot-cli/index.js";
|
|
232
2
|
//# sourceMappingURL=copilot-cli.js.map
|