vouchington-tooling 0.29.0 → 0.30.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/README.md +64 -16
- package/dist/api-contract-discovery/header-contract-registry.mjs +2 -0
- package/dist/api-contract-discovery/protocol-body-status.d.mts +2 -0
- package/dist/api-contract-discovery/protocol-body-status.mjs +4 -0
- package/dist/api-contract-discovery/protocol-callback-argument-bindings.d.mts +7 -0
- package/dist/api-contract-discovery/protocol-callback-argument-bindings.mjs +33 -0
- package/dist/api-contract-discovery/protocol-callback-invocation.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-callback-invocation.mjs +103 -0
- package/dist/api-contract-discovery/protocol-callback-mutations.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-callback-mutations.mjs +42 -0
- package/dist/api-contract-discovery/protocol-callback-registration.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-callback-registration.mjs +27 -0
- package/dist/api-contract-discovery/protocol-callback-values.d.mts +17 -0
- package/dist/api-contract-discovery/protocol-callback-values.mjs +114 -0
- package/dist/api-contract-discovery/protocol-context-alias.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-context-alias.mjs +20 -0
- package/dist/api-contract-discovery/protocol-contract-extraction.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-contract-extraction.mjs +87 -0
- package/dist/api-contract-discovery/protocol-contract-keys.d.mts +1 -0
- package/dist/api-contract-discovery/protocol-contract-keys.mjs +8 -0
- package/dist/api-contract-discovery/protocol-contract-registry.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-contract-registry.mjs +133 -0
- package/dist/api-contract-discovery/protocol-executable-path.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-executable-path.mjs +64 -0
- package/dist/api-contract-discovery/protocol-execution-path.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-execution-path.mjs +16 -0
- package/dist/api-contract-discovery/protocol-http-association.d.mts +7 -0
- package/dist/api-contract-discovery/protocol-http-association.mjs +97 -0
- package/dist/api-contract-discovery/protocol-http-body-kinds.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-http-body-kinds.mjs +19 -0
- package/dist/api-contract-discovery/protocol-http-context-callers.d.mts +6 -0
- package/dist/api-contract-discovery/protocol-http-context-callers.mjs +34 -0
- package/dist/api-contract-discovery/protocol-http-context.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-http-context.mjs +108 -0
- package/dist/api-contract-discovery/protocol-http-emission.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-http-emission.mjs +76 -0
- package/dist/api-contract-discovery/protocol-http-implicit-taint.d.mts +7 -0
- package/dist/api-contract-discovery/protocol-http-implicit-taint.mjs +26 -0
- package/dist/api-contract-discovery/protocol-http-registration.d.mts +12 -0
- package/dist/api-contract-discovery/protocol-http-registration.mjs +53 -0
- package/dist/api-contract-discovery/protocol-marker-analysis.d.mts +7 -0
- package/dist/api-contract-discovery/protocol-marker-analysis.mjs +50 -0
- package/dist/api-contract-discovery/protocol-opaque-callback.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-opaque-callback.mjs +107 -0
- package/dist/api-contract-discovery/protocol-platform-callbacks.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-platform-callbacks.mjs +72 -0
- package/dist/api-contract-discovery/protocol-platform-mutation-targets.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-platform-mutation-targets.mjs +89 -0
- package/dist/api-contract-discovery/protocol-platform-writes.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-platform-writes.mjs +92 -0
- package/dist/api-contract-discovery/protocol-requested-keys.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-requested-keys.mjs +45 -0
- package/dist/api-contract-discovery/protocol-sse-callers.d.mts +7 -0
- package/dist/api-contract-discovery/protocol-sse-callers.mjs +67 -0
- package/dist/api-contract-discovery/protocol-sse-emission.d.mts +11 -0
- package/dist/api-contract-discovery/protocol-sse-emission.mjs +61 -0
- package/dist/api-contract-discovery/protocol-sse-feasible-status.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-sse-feasible-status.mjs +24 -0
- package/dist/api-contract-discovery/protocol-sse-raw-writes.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-sse-raw-writes.mjs +70 -0
- package/dist/api-contract-discovery/protocol-sse-status.d.mts +3 -0
- package/dist/api-contract-discovery/protocol-sse-status.mjs +84 -0
- package/dist/api-contract-discovery/protocol-sse-write-access.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-sse-write-access.mjs +42 -0
- package/dist/api-contract-discovery/protocol-sse-write-helpers.d.mts +6 -0
- package/dist/api-contract-discovery/protocol-sse-write-helpers.mjs +66 -0
- package/dist/api-contract-discovery/protocol-sse-write-mutations.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-sse-write-mutations.mjs +36 -0
- package/dist/api-contract-discovery/protocol-sse-write-resolution.d.mts +14 -0
- package/dist/api-contract-discovery/protocol-sse-write-resolution.mjs +79 -0
- package/dist/api-contract-discovery/protocol-status-dominance.d.mts +5 -0
- package/dist/api-contract-discovery/protocol-status-dominance.mjs +35 -0
- package/dist/api-contract-discovery/protocol-write-receiver.d.mts +9 -0
- package/dist/api-contract-discovery/protocol-write-receiver.mjs +79 -0
- package/dist/api-contract-discovery/query-contract-registry.mjs +2 -0
- package/dist/api-contract-discovery/registered-route-binding-writes.d.mts +3 -0
- package/dist/api-contract-discovery/registered-route-binding-writes.mjs +30 -0
- package/dist/api-contract-discovery/registered-route-catalog.mjs +11 -7
- package/dist/api-contract-discovery/registered-route-factory-returns.d.mts +3 -0
- package/dist/api-contract-discovery/registered-route-factory-returns.mjs +29 -0
- package/dist/api-contract-discovery/registered-route-handler-analysis.d.mts +5 -1
- package/dist/api-contract-discovery/registered-route-handler-analysis.mjs +79 -35
- package/dist/api-contract-discovery/registered-route-runtime-parameters.d.mts +3 -0
- package/dist/api-contract-discovery/registered-route-runtime-parameters.mjs +5 -0
- package/dist/api-contract-discovery/registered-route-terminal-error.d.mts +3 -0
- package/dist/api-contract-discovery/registered-route-terminal-error.mjs +98 -0
- package/dist/api-contract-discovery/request-contract-registry.mjs +2 -0
- package/dist/api-contract-discovery/response-contract-implicit.mjs +28 -10
- package/dist/api-contract-discovery/response-contract-registry.mjs +14 -1
- package/dist/api-contract-discovery/response-contract-route-analysis.d.mts +1 -1
- package/dist/api-contract-discovery/response-contract-route-analysis.mjs +22 -4
- package/dist/api-contract-discovery/response-contract-status.d.mts +1 -1
- package/dist/api-contract-discovery/response-contract-status.mjs +10 -8
- package/dist/api-contract-discovery/response-contract-types.d.mts +7 -0
- package/dist/cli/index.mjs +0 -3
- package/dist/cli/parse-forwarded-commands.d.mts +0 -3
- package/dist/cli/parse-forwarded-commands.mjs +0 -2
- package/dist/cli/parse.d.mts +0 -3
- package/dist/cli/usage.d.mts +1 -1
- package/dist/cli/usage.mjs +0 -5
- package/dist/contract-schema/contract-schema-bounded-array.d.mts +1 -3
- package/dist/contract-schema/contract-schema-bounded-array.mjs +5 -0
- package/dist/contract-schema/contract-schema-object-tuple.mjs +7 -5
- package/dist/contract-schema/contract-schema-type-extractor.mjs +13 -0
- package/dist/contract-schema/contract-schema-validator.mjs +2 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -1
- package/dist/openapi-document/build-openapi-catalog-sse.d.mts +4 -0
- package/dist/openapi-document/build-openapi-catalog-sse.mjs +27 -0
- package/dist/openapi-document/build-openapi-document.mjs +5 -2
- package/dist/openapi-document/build-openapi-response.d.mts +2 -2
- package/dist/openapi-document/build-openapi-response.mjs +33 -3
- package/dist/openapi-document/build-openapi-sse-events.d.mts +11 -0
- package/dist/openapi-document/build-openapi-sse-events.mjs +46 -0
- package/dist/openapi-document/contract-schema-intersection-merge.mjs +11 -11
- package/dist/openapi-document/contract-schema-to-openapi.mjs +3 -3
- package/dist/openapi-document/openapi-route-helpers.mjs +1 -3
- package/dist/openapi-document/openapi-types.d.mts +3 -0
- package/dist/openapi-document/operation-types.d.mts +7 -0
- package/package.json +3 -8
- package/dist/agent-harness-config/apply.d.mts +0 -4
- package/dist/agent-harness-config/apply.mjs +0 -72
- package/dist/agent-harness-config/cli.d.mts +0 -10
- package/dist/agent-harness-config/cli.mjs +0 -100
- package/dist/agent-harness-config/index.d.mts +0 -4
- package/dist/agent-harness-config/index.mjs +0 -3
- package/dist/agent-harness-config/merge-json.d.mts +0 -5
- package/dist/agent-harness-config/merge-json.mjs +0 -62
- package/dist/agent-harness-config/merge-toml.d.mts +0 -6
- package/dist/agent-harness-config/merge-toml.mjs +0 -132
- package/dist/agent-harness-config/paths.d.mts +0 -3
- package/dist/agent-harness-config/paths.mjs +0 -117
- package/dist/agent-harness-config/policy.d.mts +0 -14
- package/dist/agent-harness-config/policy.mjs +0 -51
- package/dist/agent-harness-config/prerequisites.d.mts +0 -2
- package/dist/agent-harness-config/prerequisites.mjs +0 -67
- package/dist/agent-harness-config/toml-value.d.mts +0 -6
- package/dist/agent-harness-config/toml-value.mjs +0 -69
- package/dist/agent-harness-config/types.d.mts +0 -90
- package/dist/agent-harness-config/types.mjs +0 -2
- package/docs/agent-harness-config.md +0 -134
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_EXTRA_WRITABLE_ROOTS = [
|
|
2
|
-
'~/.cargo',
|
|
3
|
-
'~/Library/pnpm',
|
|
4
|
-
'~/.local/share/pnpm',
|
|
5
|
-
'~/.pnpm-store',
|
|
6
|
-
'~/Library/Caches/no-mistakes',
|
|
7
|
-
'~/Library/Caches/pnpm',
|
|
8
|
-
'~/.pnpm-state',
|
|
9
|
-
'~/.cache/no-mistakes',
|
|
10
|
-
'~/.cache/pnpm',
|
|
11
|
-
'~/.local/state/pnpm',
|
|
12
|
-
'/var/folders',
|
|
13
|
-
'/private/var/folders',
|
|
14
|
-
];
|
|
15
|
-
export const CLAUDE_DEFAULT_MODE = 'auto';
|
|
16
|
-
export const CODEX_APPROVAL_POLICY = 'on-request';
|
|
17
|
-
export const CODEX_APPROVALS_REVIEWER = 'auto_review';
|
|
18
|
-
export const CODEX_SANDBOX_MODE = 'workspace-write';
|
|
19
|
-
export const GROK_PERMISSION_MODE = 'auto';
|
|
20
|
-
export const GROK_SANDBOX_PROFILE = 'workspace-write';
|
|
21
|
-
export const GROK_AUTO_MODE_ENABLED = true;
|
|
22
|
-
export const GROK_DEFAULT_AUTO_MODE = true;
|
|
23
|
-
export const CURSOR_APPROVAL_MODE = 'auto-review';
|
|
24
|
-
export const CURSOR_SANDBOX_MODE = 'enabled';
|
|
25
|
-
export function dumpHarnessPolicy(extraWritableRoots = DEFAULT_EXTRA_WRITABLE_ROOTS) {
|
|
26
|
-
return {
|
|
27
|
-
claude: {
|
|
28
|
-
defaultMode: CLAUDE_DEFAULT_MODE,
|
|
29
|
-
sandboxEnabled: true,
|
|
30
|
-
sandboxFailIfUnavailable: true,
|
|
31
|
-
useAutoModeDuringPlan: true,
|
|
32
|
-
},
|
|
33
|
-
codex: {
|
|
34
|
-
approval_policy: CODEX_APPROVAL_POLICY,
|
|
35
|
-
approvals_reviewer: CODEX_APPROVALS_REVIEWER,
|
|
36
|
-
sandbox_mode: CODEX_SANDBOX_MODE,
|
|
37
|
-
},
|
|
38
|
-
cursor: { approvalMode: CURSOR_APPROVAL_MODE, sandboxMode: CURSOR_SANDBOX_MODE },
|
|
39
|
-
extraWritableRoots: [...extraWritableRoots],
|
|
40
|
-
grok: {
|
|
41
|
-
auto_mode_enabled: GROK_AUTO_MODE_ENABLED,
|
|
42
|
-
default_auto_mode: GROK_DEFAULT_AUTO_MODE,
|
|
43
|
-
permission_mode: GROK_PERMISSION_MODE,
|
|
44
|
-
sandbox_profile_defined: GROK_SANDBOX_PROFILE,
|
|
45
|
-
sandbox_profile_requires_cli_selection: true,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
export function sameValue(left, right) {
|
|
50
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
51
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join, resolve } from 'node:path';
|
|
4
|
-
import { readTomlKey } from './merge-toml.mjs';
|
|
5
|
-
import { CURSOR_APPROVAL_MODE } from './policy.mjs';
|
|
6
|
-
import { HARNESS_IDS } from './types.mjs';
|
|
7
|
-
async function readOptional(path) {
|
|
8
|
-
try {
|
|
9
|
-
return await readFile(path, 'utf8');
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
if (error.code === 'ENOENT')
|
|
13
|
-
return '';
|
|
14
|
-
throw error;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function selected(options, harness) {
|
|
18
|
-
return (options?.harnesses ?? HARNESS_IDS).includes(harness);
|
|
19
|
-
}
|
|
20
|
-
function homeDir(options) {
|
|
21
|
-
return resolve(options?.home ?? homedir());
|
|
22
|
-
}
|
|
23
|
-
async function codexTrust(root, options) {
|
|
24
|
-
const source = await readOptional(join(homeDir(options), '.codex', 'config.toml'));
|
|
25
|
-
const table = `projects.${JSON.stringify(resolve(root))}`;
|
|
26
|
-
return {
|
|
27
|
-
harness: 'codex',
|
|
28
|
-
key: 'trusted-project',
|
|
29
|
-
message: 'trust this project in Codex before relying on its .codex/config.toml',
|
|
30
|
-
satisfied: readTomlKey(source, table, 'trust_level') === 'trusted',
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
async function cursorApproval(options) {
|
|
34
|
-
const source = await readOptional(join(homeDir(options), '.cursor', 'cli-config.json'));
|
|
35
|
-
let satisfied = false;
|
|
36
|
-
try {
|
|
37
|
-
const parsed = JSON.parse(source);
|
|
38
|
-
satisfied = parsed.approvalMode === CURSOR_APPROVAL_MODE;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// A missing or invalid user config leaves the prerequisite unsatisfied.
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
harness: 'cursor',
|
|
45
|
-
key: 'global-auto-review',
|
|
46
|
-
message: 'set approvalMode=auto-review in ~/.cursor/cli-config.json',
|
|
47
|
-
satisfied,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function grokSandbox() {
|
|
51
|
-
return {
|
|
52
|
-
harness: 'grok',
|
|
53
|
-
key: 'sandbox-profile-selection',
|
|
54
|
-
message: 'start Grok with --sandbox workspace-write to activate the defined profile',
|
|
55
|
-
satisfied: false,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
export async function checkHarnessPrerequisites(root, options) {
|
|
59
|
-
const prerequisites = [];
|
|
60
|
-
if (selected(options, 'grok'))
|
|
61
|
-
prerequisites.push(grokSandbox());
|
|
62
|
-
if (root !== undefined && selected(options, 'codex'))
|
|
63
|
-
prerequisites.push(await codexTrust(root, options));
|
|
64
|
-
if (root !== undefined && selected(options, 'cursor'))
|
|
65
|
-
prerequisites.push(await cursorApproval(options));
|
|
66
|
-
return prerequisites;
|
|
67
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
export function formatTomlValue(value) {
|
|
2
|
-
if (typeof value === 'boolean')
|
|
3
|
-
return value ? 'true' : 'false';
|
|
4
|
-
if (typeof value === 'string')
|
|
5
|
-
return JSON.stringify(value);
|
|
6
|
-
const items = value.map((entry) => ` ${JSON.stringify(entry)},`).join('\n');
|
|
7
|
-
return `[\n${items}\n]`;
|
|
8
|
-
}
|
|
9
|
-
function skipSpaceAndComments(text, start) {
|
|
10
|
-
let index = start;
|
|
11
|
-
while (index < text.length) {
|
|
12
|
-
const char = text[index];
|
|
13
|
-
if (char === ' ' || char === '\t' || char === '\n' || char === '\r' || char === ',') {
|
|
14
|
-
index += 1;
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
if (char === '#') {
|
|
18
|
-
while (index < text.length && text[index] !== '\n')
|
|
19
|
-
index += 1;
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
return index;
|
|
25
|
-
}
|
|
26
|
-
function parseTomlString(text, start) {
|
|
27
|
-
const quote = text[start];
|
|
28
|
-
let index = start + 1;
|
|
29
|
-
let value = '';
|
|
30
|
-
while (index < text.length) {
|
|
31
|
-
const char = text[index];
|
|
32
|
-
if (char === quote)
|
|
33
|
-
return { end: index + 1, value };
|
|
34
|
-
if (quote === '"' && char === '\\') {
|
|
35
|
-
const next = text[index + 1];
|
|
36
|
-
if (next === undefined)
|
|
37
|
-
break;
|
|
38
|
-
value += next === 'n' ? '\n' : next === 't' ? '\t' : next;
|
|
39
|
-
index += 2;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
value += char;
|
|
43
|
-
index += 1;
|
|
44
|
-
}
|
|
45
|
-
throw new Error('unterminated TOML string');
|
|
46
|
-
}
|
|
47
|
-
export function parseTomlValue(text, start) {
|
|
48
|
-
const index = skipSpaceAndComments(text, start);
|
|
49
|
-
if (text.startsWith('true', index))
|
|
50
|
-
return { end: index + 4, value: true };
|
|
51
|
-
if (text.startsWith('false', index))
|
|
52
|
-
return { end: index + 5, value: false };
|
|
53
|
-
if (text[index] === '"' || text[index] === "'")
|
|
54
|
-
return parseTomlString(text, index);
|
|
55
|
-
if (text[index] !== '[')
|
|
56
|
-
throw new Error('unsupported TOML value');
|
|
57
|
-
const items = [];
|
|
58
|
-
let cursor = index + 1;
|
|
59
|
-
for (;;) {
|
|
60
|
-
cursor = skipSpaceAndComments(text, cursor);
|
|
61
|
-
if (text[cursor] === ']')
|
|
62
|
-
return { end: cursor + 1, value: items };
|
|
63
|
-
if (text[cursor] !== '"' && text[cursor] !== "'")
|
|
64
|
-
throw new Error('unsupported TOML array value');
|
|
65
|
-
const parsed = parseTomlString(text, cursor);
|
|
66
|
-
items.push(parsed.value);
|
|
67
|
-
cursor = parsed.end;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { HARNESS_IDS } from '../agent-harness-identity/index.mts';
|
|
2
|
-
import type { HarnessId } from '../agent-harness-identity/index.mts';
|
|
3
|
-
export { HARNESS_IDS };
|
|
4
|
-
export type { HarnessId };
|
|
5
|
-
export type ApplyTarget = {
|
|
6
|
-
readonly kind: 'global';
|
|
7
|
-
} | {
|
|
8
|
-
readonly kind: 'repo';
|
|
9
|
-
readonly root: string;
|
|
10
|
-
};
|
|
11
|
-
export interface JsonPatch {
|
|
12
|
-
readonly merge?: 'union';
|
|
13
|
-
readonly path: readonly string[];
|
|
14
|
-
readonly value: unknown;
|
|
15
|
-
}
|
|
16
|
-
export type TomlValue = boolean | string | readonly string[];
|
|
17
|
-
export interface TomlPatch {
|
|
18
|
-
readonly key: string;
|
|
19
|
-
readonly table: string;
|
|
20
|
-
readonly value: TomlValue;
|
|
21
|
-
}
|
|
22
|
-
export type FilePlan = {
|
|
23
|
-
readonly format: 'json';
|
|
24
|
-
readonly patches: readonly JsonPatch[];
|
|
25
|
-
readonly path: string;
|
|
26
|
-
} | {
|
|
27
|
-
readonly format: 'toml';
|
|
28
|
-
readonly patches: readonly TomlPatch[];
|
|
29
|
-
readonly path: string;
|
|
30
|
-
};
|
|
31
|
-
export interface KeyDrift {
|
|
32
|
-
readonly current: unknown;
|
|
33
|
-
readonly desired: unknown;
|
|
34
|
-
readonly key: string;
|
|
35
|
-
readonly path: string;
|
|
36
|
-
}
|
|
37
|
-
export interface FileResult {
|
|
38
|
-
readonly action: 'create' | 'update' | 'ok' | 'missing';
|
|
39
|
-
readonly drifts: readonly KeyDrift[];
|
|
40
|
-
readonly path: string;
|
|
41
|
-
}
|
|
42
|
-
export interface HarnessPlan {
|
|
43
|
-
readonly files: readonly FilePlan[];
|
|
44
|
-
readonly target: ApplyTarget;
|
|
45
|
-
}
|
|
46
|
-
export interface HarnessCheckResult {
|
|
47
|
-
readonly compliant: boolean;
|
|
48
|
-
readonly files: readonly FileResult[];
|
|
49
|
-
readonly prerequisites: readonly HarnessPrerequisite[];
|
|
50
|
-
readonly target: ApplyTarget;
|
|
51
|
-
}
|
|
52
|
-
export interface HarnessPrerequisite {
|
|
53
|
-
readonly harness: HarnessId;
|
|
54
|
-
readonly key: string;
|
|
55
|
-
readonly message: string;
|
|
56
|
-
readonly satisfied: boolean;
|
|
57
|
-
}
|
|
58
|
-
export interface HarnessApplyResult extends HarnessCheckResult {
|
|
59
|
-
readonly written: readonly string[];
|
|
60
|
-
}
|
|
61
|
-
export interface HarnessConfigOptions {
|
|
62
|
-
readonly extraWritableRoots?: readonly string[];
|
|
63
|
-
readonly harnesses?: readonly HarnessId[];
|
|
64
|
-
readonly home?: string;
|
|
65
|
-
}
|
|
66
|
-
export interface HarnessPolicyDump {
|
|
67
|
-
readonly claude: {
|
|
68
|
-
readonly defaultMode: 'auto';
|
|
69
|
-
readonly sandboxEnabled: true;
|
|
70
|
-
readonly sandboxFailIfUnavailable: true;
|
|
71
|
-
readonly useAutoModeDuringPlan: true;
|
|
72
|
-
};
|
|
73
|
-
readonly codex: {
|
|
74
|
-
readonly approval_policy: 'on-request';
|
|
75
|
-
readonly approvals_reviewer: 'auto_review';
|
|
76
|
-
readonly sandbox_mode: 'workspace-write';
|
|
77
|
-
};
|
|
78
|
-
readonly cursor: {
|
|
79
|
-
readonly approvalMode: 'auto-review';
|
|
80
|
-
readonly sandboxMode: 'enabled';
|
|
81
|
-
};
|
|
82
|
-
readonly extraWritableRoots: readonly string[];
|
|
83
|
-
readonly grok: {
|
|
84
|
-
readonly auto_mode_enabled: true;
|
|
85
|
-
readonly default_auto_mode: true;
|
|
86
|
-
readonly permission_mode: 'auto';
|
|
87
|
-
readonly sandbox_profile_defined: 'workspace-write';
|
|
88
|
-
readonly sandbox_profile_requires_cli_selection: true;
|
|
89
|
-
};
|
|
90
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Agent harness config
|
|
2
|
-
|
|
3
|
-
`vouchington agent-harness-config` merges a portable **classifier-auto + sandbox**
|
|
4
|
-
policy into Claude, Codex, Grok, and Cursor config files. It does not copy
|
|
5
|
-
allowlists, hooks, plugins, MCP servers, or models.
|
|
6
|
-
|
|
7
|
-
Use it to keep local interactive sessions on a permission classifier (routine
|
|
8
|
-
work proceeds, risky calls still prompt) with an OS sandbox enabled.
|
|
9
|
-
|
|
10
|
-
## Classifier vs always-approve
|
|
11
|
-
|
|
12
|
-
Always-approve / YOLO is not the same as classifier auto. Cursor
|
|
13
|
-
`unrestricted` also forces the sandbox off.
|
|
14
|
-
|
|
15
|
-
| Harness | Classifier (this tool writes) | Do not use | Sandbox |
|
|
16
|
-
| ------- | ------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------ |
|
|
17
|
-
| Claude | `permissions.defaultMode = "auto"` | `bypassPermissions` | `sandbox.enabled = true`, fail closed if unavailable |
|
|
18
|
-
| Codex | `approval_policy = "on-request"` and `approvals_reviewer = "auto_review"` | `approval_policy = "never"` | `sandbox_mode = "workspace-write"` plus extra writable roots |
|
|
19
|
-
| Grok | `ui.permission_mode = "auto"` | `always-approve` / `bypassPermissions` / `--yolo` | defines `workspace-write`; invoke with `--sandbox workspace-write` |
|
|
20
|
-
| Cursor | `approvalMode = "auto-review"` | `unrestricted` (`--force` / `--yolo`) | `sandbox.mode = "enabled"` |
|
|
21
|
-
|
|
22
|
-
Grok Auto is a separate mode from plan. Shift+Tab is `Normal → Plan → Auto
|
|
23
|
-
(when enabled) → Always-approve`. The tool also writes `auto_mode.enabled =
|
|
24
|
-
true` and `default_auto_mode = true` so Auto is available by default and
|
|
25
|
-
stays the permission classifier under plan mode. Plan-file edits remain
|
|
26
|
-
auto-approved; other file edits stay blocked. That is not YOLO.
|
|
27
|
-
|
|
28
|
-
Repo Claude settings set `sandbox.enabled` and `sandbox.failIfUnavailable`.
|
|
29
|
-
They do not change a
|
|
30
|
-
project `permissions.defaultMode` of `"plan"`.
|
|
31
|
-
|
|
32
|
-
Grok config can define a sandbox profile but cannot activate it for a future
|
|
33
|
-
session. Start Grok with `--sandbox workspace-write`; `check` reports this as
|
|
34
|
-
an unmet manual prerequisite so it never claims the profile is active.
|
|
35
|
-
|
|
36
|
-
## CLI
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
vouchington agent-harness-config dump
|
|
40
|
-
vouchington agent-harness-config check --global
|
|
41
|
-
vouchington agent-harness-config check --repo /path/to/checkout
|
|
42
|
-
vouchington agent-harness-config apply --global --repo /path --repo /other
|
|
43
|
-
vouchington agent-harness-config apply --global --harness grok --harness cursor
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
- `dump` prints the canonical key map as JSON. It does not need `--global` or `--repo`.
|
|
47
|
-
- `check` and `apply` require at least one of `--global` or `--repo` (repeatable).
|
|
48
|
-
- `--harness` filters to `claude`, `codex`, `grok`, or `cursor`. Default is all four.
|
|
49
|
-
- `--home` overrides the user home directory (tests and nonstandard layouts).
|
|
50
|
-
- `check` exits `0` when every targeted file and prerequisite matches, `1` on drift or an unmet prerequisite, and `2` on usage errors.
|
|
51
|
-
- `apply` writes only drifted keys, then exits `1` when a prerequisite remains unmet and `2` on I/O or usage errors.
|
|
52
|
-
|
|
53
|
-
## Library
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
import {
|
|
57
|
-
applyHarnessConfig,
|
|
58
|
-
checkHarnessConfig,
|
|
59
|
-
dumpHarnessPolicy,
|
|
60
|
-
planHarnessConfig,
|
|
61
|
-
} from 'vouchington-tooling/agent-harness-config'
|
|
62
|
-
|
|
63
|
-
const dump = dumpHarnessPolicy()
|
|
64
|
-
await checkHarnessConfig({ kind: 'global' }, { home: '/tmp/isolated-home' })
|
|
65
|
-
await applyHarnessConfig({ kind: 'repo', root: '/path/to/checkout' }, { harnesses: ['grok'] })
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Pass `home` in options so tests never touch the real `~/.claude` or `~/.cursor`.
|
|
69
|
-
`extraWritableRoots` replaces the shipped toolchain cache list.
|
|
70
|
-
|
|
71
|
-
## Files
|
|
72
|
-
|
|
73
|
-
Global (`--global`, under `$HOME` or `--home`):
|
|
74
|
-
|
|
75
|
-
| File | Keys |
|
|
76
|
-
| ------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
77
|
-
| `.claude/settings.json` | `permissions.defaultMode`, `sandbox.enabled`, `sandbox.failIfUnavailable`, `useAutoModeDuringPlan` |
|
|
78
|
-
| `.codex/config.toml` | `approval_policy`, `approvals_reviewer`, `sandbox_mode`, `[sandbox_workspace_write]` |
|
|
79
|
-
| `.grok/sandbox.toml` | `[profiles.workspace-write]` extra roots (written first) |
|
|
80
|
-
| `.grok/config.toml` | `ui.permission_mode`, `auto_mode.enabled`, `default_auto_mode` |
|
|
81
|
-
| `.cursor/cli-config.json` | `approvalMode`, `sandbox.mode` |
|
|
82
|
-
|
|
83
|
-
The Grok profile is selected per invocation with `--sandbox workspace-write`.
|
|
84
|
-
|
|
85
|
-
Repo (`--repo`):
|
|
86
|
-
|
|
87
|
-
| File | Keys |
|
|
88
|
-
| ----------------------- | ------------------------------------------------------------------------------- |
|
|
89
|
-
| `.claude/settings.json` | `sandbox.enabled`, `sandbox.failIfUnavailable`, `sandbox.filesystem.allowWrite` |
|
|
90
|
-
| `.codex/config.toml` | same Codex keys as global |
|
|
91
|
-
| `.grok/sandbox.toml` | extra roots only (project config cannot set the default profile) |
|
|
92
|
-
| `.cursor/sandbox.json` | `workspace_readwrite` extra roots and `networkPolicy.default = allow` |
|
|
93
|
-
|
|
94
|
-
Repo-local classifier settings have user-level prerequisites:
|
|
95
|
-
|
|
96
|
-
- Codex loads `.codex/config.toml` only after the absolute checkout path has
|
|
97
|
-
`trust_level = "trusted"` in `~/.codex/config.toml`. This command checks that
|
|
98
|
-
entry but never creates or changes it.
|
|
99
|
-
- Cursor approval mode belongs in `~/.cursor/cli-config.json`; the repo command
|
|
100
|
-
checks for global `auto-review` and intentionally leaves `.cursor/cli.json`
|
|
101
|
-
untouched.
|
|
102
|
-
- Grok sandbox activation is per invocation as described above.
|
|
103
|
-
|
|
104
|
-
These scope boundaries follow the current vendor references for
|
|
105
|
-
[Claude sandboxing](https://code.claude.com/docs/en/sandboxing),
|
|
106
|
-
[Codex project config](https://developers.openai.com/codex/config-reference),
|
|
107
|
-
[Grok settings](https://docs.x.ai/build/settings),
|
|
108
|
-
[Grok permissions](https://docs.x.ai/build/features/permissions),
|
|
109
|
-
[Cursor CLI config](https://prod.cursor.com/docs/cli/reference/configuration), and
|
|
110
|
-
[Cursor repo sandbox config](https://prod.cursor.com/docs/reference/sandbox).
|
|
111
|
-
|
|
112
|
-
Missing files are created with only these keys. Sibling keys are preserved.
|
|
113
|
-
JSON is pretty-printed with a trailing newline. TOML upserts named keys
|
|
114
|
-
without rewriting unrelated tables such as `[[marketplace.sources]]` or
|
|
115
|
-
`[projects."…"]`.
|
|
116
|
-
|
|
117
|
-
## Extra writable roots
|
|
118
|
-
|
|
119
|
-
The default list is toolchain caches, not product paths:
|
|
120
|
-
|
|
121
|
-
- `~/.cargo`
|
|
122
|
-
- `~/Library/pnpm`, `~/.local/share/pnpm`, `~/.pnpm-store`
|
|
123
|
-
- `~/Library/Caches/pnpm`, `~/.cache/pnpm`
|
|
124
|
-
- `~/.pnpm-state`, `~/.local/state/pnpm`
|
|
125
|
-
- `~/Library/Caches/no-mistakes`, `~/.cache/no-mistakes`
|
|
126
|
-
- `/var/folders`, `/private/var/folders`
|
|
127
|
-
|
|
128
|
-
Replace the list through `extraWritableRoots` when a checkout needs different roots.
|
|
129
|
-
|
|
130
|
-
## Out of scope
|
|
131
|
-
|
|
132
|
-
The tool does not copy permission allow/deny lists, `sandbox.excludedCommands`,
|
|
133
|
-
hooks, plugins, MCP servers, or model settings. Those stay in each checkout
|
|
134
|
-
or user config.
|