ccprofiles-core 0.10.1 → 0.10.2
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/delegate.d.ts +1 -1
- package/dist/delegate.js +20 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/scope.d.ts +38 -0
- package/dist/scope.js +83 -0
- package/package.json +1 -1
package/dist/delegate.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* so a Claude session cannot dispatch a native subagent onto Kimi, GLM, or Codex.
|
|
9
9
|
*/
|
|
10
10
|
/** Env that pins a session to one account/provider. Must never survive into a delegate. */
|
|
11
|
-
export declare const PROVIDER_ENV_KEYS: readonly ["CLAUDE_CONFIG_DIR", "CODEX_HOME", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", "ANTHROPIC_MODEL", "ANTHROPIC_SMALL_FAST_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL"];
|
|
11
|
+
export declare const PROVIDER_ENV_KEYS: readonly ["CLAUDE_CONFIG_DIR", "CODEX_HOME", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "ANTHROPIC_CUSTOM_HEADERS", "ANTHROPIC_MODEL", "ANTHROPIC_SMALL_FAST_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "CLAUDE_CODE_SKIP_BEDROCK_AUTH", "CLAUDE_CODE_SKIP_VERTEX_AUTH", "AWS_BEARER_TOKEN_BEDROCK", "ANTHROPIC_BEDROCK_BASE_URL", "ANTHROPIC_VERTEX_BASE_URL", "ANTHROPIC_VERTEX_PROJECT_ID", "CLOUD_ML_REGION", "OPENAI_API_KEY", "OPENAI_BASE_URL"];
|
|
12
12
|
export interface DelegateLaunch {
|
|
13
13
|
command: string;
|
|
14
14
|
args: string[];
|
package/dist/delegate.js
CHANGED
|
@@ -13,12 +13,29 @@ export const PROVIDER_ENV_KEYS = [
|
|
|
13
13
|
'CODEX_HOME',
|
|
14
14
|
'ANTHROPIC_API_KEY',
|
|
15
15
|
'ANTHROPIC_AUTH_TOKEN',
|
|
16
|
+
// a direct auth override — left in place, the delegate authenticates as the *parent* account
|
|
17
|
+
'CLAUDE_CODE_OAUTH_TOKEN',
|
|
16
18
|
'ANTHROPIC_BASE_URL',
|
|
19
|
+
// gateways route and bill on these, so they re-point a delegate as surely as a base URL
|
|
20
|
+
'ANTHROPIC_CUSTOM_HEADERS',
|
|
17
21
|
'ANTHROPIC_MODEL',
|
|
18
22
|
'ANTHROPIC_SMALL_FAST_MODEL',
|
|
19
23
|
'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
20
24
|
'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
21
25
|
'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
26
|
+
// alternate backends: these switch the provider wholesale, ignoring ANTHROPIC_BASE_URL
|
|
27
|
+
'CLAUDE_CODE_USE_BEDROCK',
|
|
28
|
+
'CLAUDE_CODE_USE_VERTEX',
|
|
29
|
+
'CLAUDE_CODE_SKIP_BEDROCK_AUTH',
|
|
30
|
+
'CLAUDE_CODE_SKIP_VERTEX_AUTH',
|
|
31
|
+
'AWS_BEARER_TOKEN_BEDROCK',
|
|
32
|
+
'ANTHROPIC_BEDROCK_BASE_URL',
|
|
33
|
+
'ANTHROPIC_VERTEX_BASE_URL',
|
|
34
|
+
'ANTHROPIC_VERTEX_PROJECT_ID',
|
|
35
|
+
'CLOUD_ML_REGION',
|
|
36
|
+
// codex targets pin on the OpenAI pair, the exact mirror of the Anthropic leak
|
|
37
|
+
'OPENAI_API_KEY',
|
|
38
|
+
'OPENAI_BASE_URL',
|
|
22
39
|
];
|
|
23
40
|
/**
|
|
24
41
|
* Parent env minus every provider pin, plus the target's own.
|
|
@@ -55,7 +72,9 @@ export function buildDelegateLaunch(opts) {
|
|
|
55
72
|
// codex resolves its workspace from --cd, not the spawn cwd
|
|
56
73
|
if (codex)
|
|
57
74
|
args.push('-C', opts.cwd);
|
|
58
|
-
|
|
75
|
+
// `--` or a prompt like "-fix the tests" is parsed as an option by the child and the whole
|
|
76
|
+
// delegation fails. Both `claude` (commander) and `codex exec` (clap) honour the separator.
|
|
77
|
+
args.push('--', opts.prompt);
|
|
59
78
|
return {
|
|
60
79
|
command: codex ? 'codex' : 'claude',
|
|
61
80
|
args,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path-lane enforcement for parallel delegation.
|
|
3
|
+
*
|
|
4
|
+
* Running two agents at once is only safe while they touch disjoint files. A scope stated in
|
|
5
|
+
* the prompt is a request, not a constraint — models drift the moment a task turns out to need
|
|
6
|
+
* a shared type or config. These helpers turn "they probably stayed in their lane" into a
|
|
7
|
+
* checkable fact after the run.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Glob → RegExp for the subset that matters here: `**` (any depth, may be empty), `*` (one
|
|
11
|
+
* segment), `?` (one char). Everything else is escaped literally. Deliberately not a full
|
|
12
|
+
* globbing implementation — a scope is a coarse directory lane, not a filter language.
|
|
13
|
+
*/
|
|
14
|
+
export declare function globToRegExp(glob: string): RegExp;
|
|
15
|
+
/**
|
|
16
|
+
* A lane written as a bare directory (`src/web` or `src/web/`) means everything under it.
|
|
17
|
+
* Taken literally it would match exactly zero files and flag every in-lane edit as a
|
|
18
|
+
* violation — a footgun that makes the check useless in precisely the way that looks broken.
|
|
19
|
+
*/
|
|
20
|
+
export declare function normalizeScope(scope: string): string;
|
|
21
|
+
/** True when `file` falls inside any lane. An empty scope list means "no lane declared". */
|
|
22
|
+
export declare function inScope(file: string, scopes: string[]): boolean;
|
|
23
|
+
export interface ScopeReport {
|
|
24
|
+
touched: string[];
|
|
25
|
+
violations: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Which files the delegate touched, and which of those left the lane.
|
|
29
|
+
*
|
|
30
|
+
* `before`/`after` map a repo-relative path to a change fingerprint (see snapshotChanges).
|
|
31
|
+
* A path counts as touched if its fingerprint appeared, vanished, or moved — the vanish case
|
|
32
|
+
* matters because a delegate that reverts your edit or deletes your untracked file would
|
|
33
|
+
* otherwise be invisible.
|
|
34
|
+
*
|
|
35
|
+
* `committed` carries paths from commits the delegate made, which leave the working tree clean
|
|
36
|
+
* and so never show up in either snapshot at all.
|
|
37
|
+
*/
|
|
38
|
+
export declare function scopeReport(before: Map<string, string>, after: Map<string, string>, scopes: string[], committed?: string[]): ScopeReport;
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path-lane enforcement for parallel delegation.
|
|
3
|
+
*
|
|
4
|
+
* Running two agents at once is only safe while they touch disjoint files. A scope stated in
|
|
5
|
+
* the prompt is a request, not a constraint — models drift the moment a task turns out to need
|
|
6
|
+
* a shared type or config. These helpers turn "they probably stayed in their lane" into a
|
|
7
|
+
* checkable fact after the run.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Glob → RegExp for the subset that matters here: `**` (any depth, may be empty), `*` (one
|
|
11
|
+
* segment), `?` (one char). Everything else is escaped literally. Deliberately not a full
|
|
12
|
+
* globbing implementation — a scope is a coarse directory lane, not a filter language.
|
|
13
|
+
*/
|
|
14
|
+
export function globToRegExp(glob) {
|
|
15
|
+
let re = '';
|
|
16
|
+
for (let i = 0; i < glob.length; i++) {
|
|
17
|
+
const c = glob[i];
|
|
18
|
+
if (c === '*') {
|
|
19
|
+
if (glob[i + 1] === '*') {
|
|
20
|
+
i++;
|
|
21
|
+
if (glob[i + 1] === '/') {
|
|
22
|
+
// mid-pattern `a/**/b` must also match `a/b`, so the whole group is optional
|
|
23
|
+
i++;
|
|
24
|
+
re += '(?:.*/)?';
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// trailing `a/**` is "everything under a/", files included
|
|
28
|
+
re += '.*';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
re += '[^/]*';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (c === '?') {
|
|
36
|
+
re += '[^/]';
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
re += c.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return new RegExp(`^${re}$`);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A lane written as a bare directory (`src/web` or `src/web/`) means everything under it.
|
|
46
|
+
* Taken literally it would match exactly zero files and flag every in-lane edit as a
|
|
47
|
+
* violation — a footgun that makes the check useless in precisely the way that looks broken.
|
|
48
|
+
*/
|
|
49
|
+
export function normalizeScope(scope) {
|
|
50
|
+
const s = scope.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
51
|
+
return /[*?]/.test(s) ? s : `${s}/**`;
|
|
52
|
+
}
|
|
53
|
+
/** True when `file` falls inside any lane. An empty scope list means "no lane declared". */
|
|
54
|
+
export function inScope(file, scopes) {
|
|
55
|
+
if (!scopes.length)
|
|
56
|
+
return true;
|
|
57
|
+
const normalized = file.replace(/\\/g, '/');
|
|
58
|
+
return scopes.some(s => globToRegExp(normalizeScope(s)).test(normalized));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Which files the delegate touched, and which of those left the lane.
|
|
62
|
+
*
|
|
63
|
+
* `before`/`after` map a repo-relative path to a change fingerprint (see snapshotChanges).
|
|
64
|
+
* A path counts as touched if its fingerprint appeared, vanished, or moved — the vanish case
|
|
65
|
+
* matters because a delegate that reverts your edit or deletes your untracked file would
|
|
66
|
+
* otherwise be invisible.
|
|
67
|
+
*
|
|
68
|
+
* `committed` carries paths from commits the delegate made, which leave the working tree clean
|
|
69
|
+
* and so never show up in either snapshot at all.
|
|
70
|
+
*/
|
|
71
|
+
export function scopeReport(before, after, scopes, committed = []) {
|
|
72
|
+
const touched = new Set(committed.map(f => f.replace(/\\/g, '/')));
|
|
73
|
+
for (const [file, fp] of after) {
|
|
74
|
+
if (before.get(file) !== fp)
|
|
75
|
+
touched.add(file);
|
|
76
|
+
}
|
|
77
|
+
for (const file of before.keys()) {
|
|
78
|
+
if (!after.has(file))
|
|
79
|
+
touched.add(file); // reverted or deleted
|
|
80
|
+
}
|
|
81
|
+
const list = [...touched].sort();
|
|
82
|
+
return { touched: list, violations: list.filter(f => !inScope(f, scopes)) };
|
|
83
|
+
}
|
package/package.json
CHANGED