@dugleelabs/copair 1.6.0 → 1.7.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/dist/api.d.ts +77 -10
- package/dist/api.js +149 -122
- package/dist/api.js.map +1 -1
- package/dist/index.js +148 -121
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/api.d.ts
CHANGED
|
@@ -216,21 +216,42 @@ declare class ToolRegistry {
|
|
|
216
216
|
getAllDefinitions(): ToolDefinition[];
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Path-level permissions — model-agnostic.
|
|
221
|
+
* Applies regardless of which tool the model uses (read, bash cat, grep, etc.).
|
|
222
|
+
* write permission implies read.
|
|
223
|
+
*/
|
|
224
|
+
interface PathPermissions {
|
|
225
|
+
read: string[];
|
|
226
|
+
write: string[];
|
|
227
|
+
}
|
|
219
228
|
interface AllowRules {
|
|
220
229
|
/** bash entries: exact match, or prefix if the pattern ends with " *" */
|
|
221
230
|
bash: string[];
|
|
222
231
|
/**
|
|
223
232
|
* git entries: matched against the args string.
|
|
224
|
-
* Entry is the subcommand (e.g. "diff") —
|
|
225
|
-
* flags for that subcommand (e.g. "diff --cached", "diff HEAD~1").
|
|
233
|
+
* Entry is the subcommand (e.g. "diff") — covers all flags for that subcommand.
|
|
226
234
|
*/
|
|
227
235
|
git: string[];
|
|
228
236
|
/**
|
|
229
|
-
*
|
|
230
|
-
*
|
|
237
|
+
* Tool-specific read/write/edit entries (kept for backward-compat and
|
|
238
|
+
* fine-grained tool control). For multi-model setups, prefer `paths:`.
|
|
231
239
|
*/
|
|
240
|
+
read: string[];
|
|
232
241
|
write: string[];
|
|
233
242
|
edit: string[];
|
|
243
|
+
/**
|
|
244
|
+
* Path-level permissions — the preferred way to allow cross-repo access.
|
|
245
|
+
* Works regardless of which tool the model chooses to use for an operation.
|
|
246
|
+
*
|
|
247
|
+
* Example allow.yaml:
|
|
248
|
+
* paths:
|
|
249
|
+
* read:
|
|
250
|
+
* - "../../other-repo/**"
|
|
251
|
+
* write:
|
|
252
|
+
* - "../../shared-output/**"
|
|
253
|
+
*/
|
|
254
|
+
paths: PathPermissions;
|
|
234
255
|
}
|
|
235
256
|
declare class AllowList {
|
|
236
257
|
private rules;
|
|
@@ -238,11 +259,25 @@ declare class AllowList {
|
|
|
238
259
|
/**
|
|
239
260
|
* Returns true when the operation is explicitly listed and should bypass
|
|
240
261
|
* the approval prompt. Called by ApprovalGate before prompting.
|
|
262
|
+
*
|
|
263
|
+
* Check order per tool:
|
|
264
|
+
* 1. Tool-specific entries (bash:, git:, read:, write:, edit:) — fine-grained
|
|
265
|
+
* 2. Path-level entries (paths.read / paths.write) — model-agnostic
|
|
241
266
|
*/
|
|
242
267
|
matches(toolName: string, input: Record<string, unknown>): boolean;
|
|
243
268
|
private matchBash;
|
|
269
|
+
/**
|
|
270
|
+
* Path-level bash matching: extract path tokens from the command, classify
|
|
271
|
+
* as read or write intent, then check against paths.read / paths.write.
|
|
272
|
+
* All path tokens in the command must be covered for the check to pass.
|
|
273
|
+
*/
|
|
274
|
+
private matchBashByPath;
|
|
244
275
|
private matchGit;
|
|
245
276
|
private matchPath;
|
|
277
|
+
/**
|
|
278
|
+
* Check filePath against paths.read or paths.write (write implies read).
|
|
279
|
+
*/
|
|
280
|
+
private matchPathAgainstPermissions;
|
|
246
281
|
}
|
|
247
282
|
|
|
248
283
|
interface ToolInfo {
|
|
@@ -275,15 +310,27 @@ interface TokenUsage {
|
|
|
275
310
|
contextPercent?: number;
|
|
276
311
|
}
|
|
277
312
|
type ApprovalAnswer = 'allow' | 'always' | 'deny' | 'all' | 'similar';
|
|
313
|
+
/** Pre-approval diff shown at the approval prompt (before execution). */
|
|
314
|
+
interface ApprovalDiffPreview {
|
|
315
|
+
filePath: string;
|
|
316
|
+
oldContent: string | null;
|
|
317
|
+
newContent: string;
|
|
318
|
+
diffText: string;
|
|
319
|
+
}
|
|
278
320
|
interface ApprovalRequest {
|
|
279
321
|
toolName: string;
|
|
280
322
|
input: Record<string, unknown>;
|
|
281
323
|
summary: string;
|
|
282
324
|
index: number;
|
|
283
325
|
total: number;
|
|
284
|
-
diff
|
|
326
|
+
/** Pre-approval diff preview (shown before user approves). */
|
|
327
|
+
diff?: ApprovalDiffPreview | null;
|
|
285
328
|
/** Present when a bash command references a sensitive system path. */
|
|
286
329
|
warning?: string;
|
|
330
|
+
/** Present when a bash command references a path outside the project root. */
|
|
331
|
+
crossRepoBashPath?: string;
|
|
332
|
+
/** Present when a read/glob/grep targets a path outside the project root. */
|
|
333
|
+
crossRepoReadPath?: string;
|
|
287
334
|
}
|
|
288
335
|
interface AgentBridgeEvents {
|
|
289
336
|
'stream-text': (text: string) => void;
|
|
@@ -297,11 +344,13 @@ interface AgentBridgeEvents {
|
|
|
297
344
|
'approval-request': (request: ApprovalRequest, respond: (answer: ApprovalAnswer) => void) => void;
|
|
298
345
|
'diff': (diff: DiffInfo) => void;
|
|
299
346
|
'usage': (usage: TokenUsage) => void;
|
|
300
|
-
'thinking-start': () => void;
|
|
347
|
+
'thinking-start': (label?: string) => void;
|
|
301
348
|
'thinking-stop': () => void;
|
|
302
349
|
'turn-complete': () => void;
|
|
303
350
|
'error': (message: string) => void;
|
|
304
351
|
'input-request': (respond: (input: string) => void) => void;
|
|
352
|
+
'context-limit-warning': () => void;
|
|
353
|
+
'context-limit-action': (respond: (action: 'compact' | 'abort') => void) => void;
|
|
305
354
|
}
|
|
306
355
|
type EventName = keyof AgentBridgeEvents;
|
|
307
356
|
/**
|
|
@@ -335,8 +384,8 @@ declare class AgentBridge extends EventEmitter {
|
|
|
335
384
|
* input_summary is always redacted and truncated to ≤ 200 chars before
|
|
336
385
|
* writing so that raw secrets never appear in the audit log.
|
|
337
386
|
*/
|
|
338
|
-
type AuditEvent = 'session_start' | 'session_end' | 'tool_call' | 'approval' | 'denial' | 'path_block' | 'schema_rejection' | 'bash_sensitive_path';
|
|
339
|
-
type AuditOutcome = 'allowed' | 'denied' | 'error';
|
|
387
|
+
type AuditEvent = 'session_start' | 'session_end' | 'tool_call' | 'approval' | 'denial' | 'path_block' | 'schema_rejection' | 'bash_sensitive_path' | 'bash_cross_repo' | 'cross_repo_read';
|
|
388
|
+
type AuditOutcome = 'allowed' | 'denied' | 'error' | 'flagged';
|
|
340
389
|
interface AuditEntry {
|
|
341
390
|
ts: string;
|
|
342
391
|
event: AuditEvent;
|
|
@@ -386,7 +435,7 @@ declare class ApprovalGate {
|
|
|
386
435
|
* The agent never calls this. ToolExecutor calls it. The agent only
|
|
387
436
|
* sees the resulting ExecutionResult.
|
|
388
437
|
*/
|
|
389
|
-
allow(toolName: string, input: Record<string, unknown
|
|
438
|
+
allow(toolName: string, input: Record<string, unknown>, diffPreview?: ApprovalDiffPreview): Promise<boolean>;
|
|
390
439
|
/** Bridge-based approval: emit event and await response from ink UI. */
|
|
391
440
|
private bridgePrompt;
|
|
392
441
|
/** Legacy approval prompt: reads from /dev/tty directly (not stdin).
|
|
@@ -455,7 +504,15 @@ declare class PathGuard {
|
|
|
455
504
|
* @param mustExist true for read operations (file must exist); false for
|
|
456
505
|
* write/edit operations (parent dir must exist).
|
|
457
506
|
*/
|
|
458
|
-
check(rawPath: string, mustExist: boolean
|
|
507
|
+
check(rawPath: string, mustExist: boolean, opts?: {
|
|
508
|
+
skipBoundaryCheck?: boolean;
|
|
509
|
+
}): PathGuardResult;
|
|
510
|
+
/**
|
|
511
|
+
* Check whether a raw path resolves to somewhere inside the project root.
|
|
512
|
+
* Used by the tool executor to flag cross-repo references before the gate fires.
|
|
513
|
+
* Returns false on any resolution error — treat as outside.
|
|
514
|
+
*/
|
|
515
|
+
isInsideProject(rawPath: string): boolean;
|
|
459
516
|
private isDenied;
|
|
460
517
|
private isAllowed;
|
|
461
518
|
/**
|
|
@@ -664,6 +721,8 @@ interface AgentOptions {
|
|
|
664
721
|
toolCallFormat?: FormatName;
|
|
665
722
|
bridge?: AgentBridge;
|
|
666
723
|
pluginManager?: PluginManager;
|
|
724
|
+
/** Fraction of maxTokens at which to warn about context limit (0–1, default 0.9). */
|
|
725
|
+
contextLimitThresholdPct?: number;
|
|
667
726
|
}
|
|
668
727
|
declare class Agent {
|
|
669
728
|
private provider;
|
|
@@ -693,6 +752,14 @@ declare class Agent {
|
|
|
693
752
|
/** Input tokens from the last API call — reflects actual context window usage. */
|
|
694
753
|
lastInputTokens: number;
|
|
695
754
|
}>;
|
|
755
|
+
/**
|
|
756
|
+
* Detect whether the model likely hit its context limit this turn.
|
|
757
|
+
* Two signals:
|
|
758
|
+
* 1. Token threshold: input tokens ≥ contextLimitThresholdPct of maxTokens
|
|
759
|
+
* 2. Truncation heuristic: text present, no tool calls, and response ends
|
|
760
|
+
* without terminal punctuation (sentence was cut off mid-stream)
|
|
761
|
+
*/
|
|
762
|
+
private detectContextLimit;
|
|
696
763
|
}
|
|
697
764
|
|
|
698
765
|
interface SessionMetadata {
|