@corbat-tech/coco 2.34.0 → 2.36.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/index.d.ts CHANGED
@@ -503,6 +503,7 @@ declare const CocoConfigSchema: z.ZodObject<{
503
503
  "kimi-code": "kimi-code";
504
504
  lmstudio: "lmstudio";
505
505
  codex: "codex";
506
+ vertex: "vertex";
506
507
  copilot: "copilot";
507
508
  groq: "groq";
508
509
  openrouter: "openrouter";
@@ -511,7 +512,6 @@ declare const CocoConfigSchema: z.ZodObject<{
511
512
  together: "together";
512
513
  huggingface: "huggingface";
513
514
  qwen: "qwen";
514
- vertex: "vertex";
515
515
  ollama: "ollama";
516
516
  }>>;
517
517
  apiKey: z.ZodOptional<z.ZodString>;
@@ -957,6 +957,10 @@ type ProjectType = "cli" | "api" | "web_app" | "library" | "service" | "full_sta
957
957
  type ThinkingMode = "off" | "auto" | "low" | "medium" | "high" | {
958
958
  budget: number;
959
959
  };
960
+ /**
961
+ * Whether this provider/model uses effort buckets (OpenAI) or token budgets (Anthropic, Gemini).
962
+ */
963
+ type ThinkingKind = "effort" | "budget";
960
964
 
961
965
  /**
962
966
  * LLM Provider types for Corbat-Coco
@@ -3136,6 +3140,75 @@ declare class TaskError extends CocoError {
3136
3140
  });
3137
3141
  }
3138
3142
 
3143
+ /**
3144
+ * Provider and model catalog.
3145
+ *
3146
+ * This is the source of truth for model IDs, defaults, context windows,
3147
+ * pricing metadata, and provider capabilities. Endpoint adapters still own
3148
+ * request/response conversion, but they should read model metadata from here.
3149
+ */
3150
+
3151
+ type ModelStatus = "current" | "legacy" | "deprecated" | "experimental";
3152
+ type ModelCapability = "streaming" | "tool-use" | "vision" | "reasoning-effort" | "adaptive-thinking" | "thinking-budget" | "openai-responses" | "openai-chat" | "anthropic-messages" | "gemini-generate-content";
3153
+ interface ProviderSource {
3154
+ name: string;
3155
+ url: string;
3156
+ verifiedAt: string;
3157
+ }
3158
+ interface ModelPricing {
3159
+ inputPerMillion: number;
3160
+ outputPerMillion: number;
3161
+ }
3162
+ interface ModelCatalogEntry {
3163
+ id: string;
3164
+ name: string;
3165
+ description?: string;
3166
+ contextWindow: number;
3167
+ maxOutputTokens?: number;
3168
+ recommended?: boolean;
3169
+ status: ModelStatus;
3170
+ capabilities: ModelCapability[];
3171
+ pricing?: ModelPricing;
3172
+ source: ProviderSource;
3173
+ }
3174
+ interface ProviderCatalogEntry {
3175
+ id: ProviderType;
3176
+ defaultModel: string;
3177
+ models: ModelCatalogEntry[];
3178
+ }
3179
+
3180
+ /**
3181
+ * Runtime compatibility view derived from the static provider catalog.
3182
+ *
3183
+ * The catalog records what a model is; this module records how Coco should use it
3184
+ * safely at runtime, including endpoint selection and reasoning/tooling limits.
3185
+ */
3186
+
3187
+ type ProviderEndpointStrategy = "anthropic-messages" | "openai-responses" | "openai-chat" | "gemini-generate-content";
3188
+ type ModelCompatibilityStatus = ModelStatus | "unverified";
3189
+ interface ProviderRuntimeCapability {
3190
+ provider: ProviderType;
3191
+ model: string;
3192
+ catalogModel?: ModelCatalogEntry;
3193
+ status: ModelCompatibilityStatus;
3194
+ endpoint: ProviderEndpointStrategy;
3195
+ supportsStreaming: boolean;
3196
+ supportsToolUse: boolean;
3197
+ supportsVision: boolean;
3198
+ supportsReasoning: boolean;
3199
+ reasoningKinds: ThinkingKind[];
3200
+ defaultReasoning: ThinkingMode;
3201
+ contextWindow: number;
3202
+ maxOutputTokens?: number;
3203
+ sourceUrl?: string;
3204
+ restrictions: string[];
3205
+ }
3206
+ interface ProviderProbeResult extends ProviderRuntimeCapability {
3207
+ available: boolean | "not-checked";
3208
+ checkedAt: string;
3209
+ error?: string;
3210
+ }
3211
+
3139
3212
  /**
3140
3213
  * Provider exports for Corbat-Coco
3141
3214
  */
@@ -3149,6 +3222,1006 @@ type ProviderType = "anthropic" | "openai" | "codex" | "copilot" | "gemini" | "v
3149
3222
  */
3150
3223
  declare function createProvider(type: ProviderType, config?: ProviderConfig): Promise<LLMProvider>;
3151
3224
 
3225
+ /**
3226
+ * Agent mode registry.
3227
+ *
3228
+ * Modes describe the intended control flow for a turn without changing the
3229
+ * provider interface. The REPL can route prompts, tools, and confirmations
3230
+ * through these definitions while keeping compatibility with existing plan
3231
+ * mode and quality loop behavior.
3232
+ */
3233
+ type AgentModeId = "ask" | "plan" | "build" | "debug" | "review" | "architect";
3234
+ interface AgentModeDefinition {
3235
+ id: AgentModeId;
3236
+ label: string;
3237
+ description: string;
3238
+ readOnly: boolean;
3239
+ preferredTools: string[];
3240
+ requiresVerification: boolean;
3241
+ }
3242
+
3243
+ /**
3244
+ * Context window manager for automatic token tracking
3245
+ * Monitors token usage and triggers compaction when threshold is exceeded
3246
+ */
3247
+ /**
3248
+ * Configuration for the context manager
3249
+ */
3250
+ interface ContextManagerConfig {
3251
+ /** Maximum tokens available (from provider.getContextWindow()) */
3252
+ maxTokens: number;
3253
+ /** Threshold percentage (0-1) at which to trigger compaction (default 0.8 = 80%) */
3254
+ compactionThreshold: number;
3255
+ /** Tokens reserved for response generation (default 4096) */
3256
+ reservedTokens: number;
3257
+ }
3258
+ /**
3259
+ * Context usage statistics
3260
+ */
3261
+ interface ContextUsageStats {
3262
+ /** Tokens currently used */
3263
+ used: number;
3264
+ /** Tokens available for use (excluding reserved) */
3265
+ available: number;
3266
+ /** Total capacity */
3267
+ total: number;
3268
+ /** Usage percentage (0-100) */
3269
+ percentage: number;
3270
+ /** Whether compaction is recommended */
3271
+ shouldCompact: boolean;
3272
+ }
3273
+ /**
3274
+ * Manages context window usage and determines when compaction is needed
3275
+ */
3276
+ declare class ContextManager {
3277
+ private usedTokens;
3278
+ private config;
3279
+ constructor(config?: Partial<ContextManagerConfig>);
3280
+ /**
3281
+ * Add tokens to the usage counter
3282
+ */
3283
+ addTokens(count: number): void;
3284
+ /**
3285
+ * Remove tokens from the usage counter
3286
+ */
3287
+ removeTokens(count: number): void;
3288
+ /**
3289
+ * Set the used token count directly
3290
+ */
3291
+ setUsedTokens(count: number): void;
3292
+ /**
3293
+ * Get the number of tokens currently used
3294
+ */
3295
+ getUsedTokens(): number;
3296
+ /**
3297
+ * Get the number of tokens available (excluding reserved)
3298
+ */
3299
+ getAvailableTokens(): number;
3300
+ /**
3301
+ * Get usage percentage (0-100)
3302
+ */
3303
+ getUsagePercent(): number;
3304
+ /**
3305
+ * Check if compaction should be triggered
3306
+ */
3307
+ shouldCompact(): boolean;
3308
+ /**
3309
+ * Get full usage statistics
3310
+ */
3311
+ getUsageStats(): ContextUsageStats;
3312
+ /**
3313
+ * Reset the token counter
3314
+ */
3315
+ reset(): void;
3316
+ /**
3317
+ * Update configuration (e.g., when switching providers/models)
3318
+ */
3319
+ updateConfig(config: Partial<ContextManagerConfig>): void;
3320
+ /**
3321
+ * Get current configuration
3322
+ */
3323
+ getConfig(): ContextManagerConfig;
3324
+ /**
3325
+ * Format usage for display
3326
+ */
3327
+ formatUsage(): string;
3328
+ }
3329
+
3330
+ /**
3331
+ * Progress Tracking Types
3332
+ *
3333
+ * Types for TodoWrite-like progress tracking in the REPL.
3334
+ */
3335
+ /**
3336
+ * Status of a todo item
3337
+ */
3338
+ type TodoStatus = "pending" | "in_progress" | "completed" | "failed";
3339
+ /**
3340
+ * A single todo item for tracking progress
3341
+ */
3342
+ interface TodoItem {
3343
+ /** Unique identifier for the todo */
3344
+ id: string;
3345
+ /** Description of what needs to be done (imperative form) */
3346
+ content: string;
3347
+ /** Present tense description shown during execution */
3348
+ activeForm: string;
3349
+ /** Current status of the todo */
3350
+ status: TodoStatus;
3351
+ /** ISO timestamp when the todo was created */
3352
+ createdAt: string;
3353
+ /** ISO timestamp when the todo was last updated */
3354
+ updatedAt: string;
3355
+ /** Parent todo ID for nested todos */
3356
+ parentId?: string;
3357
+ }
3358
+ /**
3359
+ * Serializable progress state
3360
+ */
3361
+ interface ProgressState {
3362
+ /** List of all todos */
3363
+ todos: TodoItem[];
3364
+ /** ID of the currently active task */
3365
+ currentTask?: string;
3366
+ }
3367
+ /**
3368
+ * Progress statistics
3369
+ */
3370
+ interface ProgressStats {
3371
+ /** Total number of todos */
3372
+ total: number;
3373
+ /** Number of pending todos */
3374
+ pending: number;
3375
+ /** Number of in-progress todos */
3376
+ inProgress: number;
3377
+ /** Number of completed todos */
3378
+ completed: number;
3379
+ /** Number of failed todos */
3380
+ failed: number;
3381
+ /** Completion percentage (0-100) */
3382
+ completionPercent: number;
3383
+ }
3384
+
3385
+ /**
3386
+ * Progress Tracker
3387
+ *
3388
+ * Manages todo items for tracking task progress in the REPL.
3389
+ */
3390
+
3391
+ /**
3392
+ * Tracks progress of tasks via a todo list
3393
+ */
3394
+ declare class ProgressTracker {
3395
+ private todos;
3396
+ private currentTaskId?;
3397
+ /**
3398
+ * Create a new progress tracker
3399
+ * @param initialState Optional initial state to restore from
3400
+ */
3401
+ constructor(initialState?: ProgressState);
3402
+ /**
3403
+ * Add a new todo item
3404
+ * @param content Description of what needs to be done (imperative form)
3405
+ * @param activeForm Present tense description shown during execution
3406
+ * @param parentId Optional parent todo ID for nested todos
3407
+ * @returns The created todo item
3408
+ */
3409
+ addTodo(content: string, activeForm: string, parentId?: string): TodoItem;
3410
+ /**
3411
+ * Add multiple todos at once
3412
+ * @param items Array of { content, activeForm, parentId } objects
3413
+ * @returns Array of created todo items
3414
+ */
3415
+ addTodos(items: Array<{
3416
+ content: string;
3417
+ activeForm: string;
3418
+ parentId?: string;
3419
+ }>): TodoItem[];
3420
+ /**
3421
+ * Update the status of a todo
3422
+ * @param id Todo ID
3423
+ * @param status New status
3424
+ * @throws Error if todo not found
3425
+ */
3426
+ updateStatus(id: string, status: TodoStatus): void;
3427
+ /**
3428
+ * Start a todo (set to in_progress)
3429
+ * @param id Todo ID
3430
+ */
3431
+ startTodo(id: string): void;
3432
+ /**
3433
+ * Complete a todo
3434
+ * @param id Todo ID
3435
+ */
3436
+ completeTodo(id: string): void;
3437
+ /**
3438
+ * Mark a todo as failed
3439
+ * @param id Todo ID
3440
+ */
3441
+ failTodo(id: string): void;
3442
+ /**
3443
+ * Get a todo by ID
3444
+ * @param id Todo ID
3445
+ * @returns The todo item or undefined
3446
+ */
3447
+ getTodo(id: string): TodoItem | undefined;
3448
+ /**
3449
+ * Get all todos
3450
+ * @returns Array of all todo items
3451
+ */
3452
+ getTodos(): TodoItem[];
3453
+ /**
3454
+ * Get todos filtered by status
3455
+ * @param status Status to filter by
3456
+ * @returns Array of matching todo items
3457
+ */
3458
+ getTodosByStatus(status: TodoStatus): TodoItem[];
3459
+ /**
3460
+ * Get child todos of a parent
3461
+ * @param parentId Parent todo ID
3462
+ * @returns Array of child todo items
3463
+ */
3464
+ getChildTodos(parentId: string): TodoItem[];
3465
+ /**
3466
+ * Get the currently in-progress task
3467
+ * @returns The current task or undefined
3468
+ */
3469
+ getCurrentTask(): TodoItem | undefined;
3470
+ /**
3471
+ * Get progress statistics
3472
+ * @returns Progress stats object
3473
+ */
3474
+ getStats(): ProgressStats;
3475
+ /**
3476
+ * Remove a todo
3477
+ * @param id Todo ID
3478
+ * @returns true if removed, false if not found
3479
+ */
3480
+ removeTodo(id: string): boolean;
3481
+ /**
3482
+ * Clear all todos
3483
+ */
3484
+ clear(): void;
3485
+ /**
3486
+ * Check if there are any todos
3487
+ * @returns true if there are todos
3488
+ */
3489
+ hasTodos(): boolean;
3490
+ /**
3491
+ * Check if all todos are completed
3492
+ * @returns true if all todos are completed (or no todos exist)
3493
+ */
3494
+ isComplete(): boolean;
3495
+ /**
3496
+ * Format progress for display
3497
+ * @returns Formatted progress string
3498
+ */
3499
+ formatProgress(): string;
3500
+ /**
3501
+ * Serialize to JSON
3502
+ * @returns Serializable progress state
3503
+ */
3504
+ toJSON(): ProgressState;
3505
+ /**
3506
+ * Restore from JSON state
3507
+ * @param state Progress state to restore
3508
+ */
3509
+ fromJSON(state: ProgressState): void;
3510
+ }
3511
+
3512
+ /**
3513
+ * Memory source level indicating where a memory file originates.
3514
+ *
3515
+ * The levels form a hierarchy with increasing specificity:
3516
+ * - `user`: Global user preferences (~/.coco/COCO.md)
3517
+ * - `project`: Project-specific instructions (./COCO.md, committed to repo)
3518
+ * - `directory`: Subdirectory-specific instructions (e.g., src/api/COCO.md)
3519
+ * - `local`: Personal overrides (./COCO.local.md, gitignored)
3520
+ *
3521
+ * Higher specificity levels override lower ones when conflicts occur.
3522
+ * Directory-level files are collected from all directories between project root
3523
+ * and the current working directory, with closer directories taking precedence.
3524
+ */
3525
+ type MemoryLevel = "user" | "project" | "directory" | "local";
3526
+ /**
3527
+ * Represents a parsed section within a memory file.
3528
+ *
3529
+ * Sections are delimited by markdown headings (## heading).
3530
+ * Each section contains instructions or configuration for a specific topic.
3531
+ *
3532
+ * @example
3533
+ * ```typescript
3534
+ * const section: MemorySection = {
3535
+ * title: "Code Style",
3536
+ * content: "- Use 2-space indentation\n- Prefer const over let",
3537
+ * startLine: 10,
3538
+ * endLine: 15
3539
+ * };
3540
+ * ```
3541
+ */
3542
+ interface MemorySection {
3543
+ /**
3544
+ * Section title extracted from the heading.
3545
+ * The leading ## and any trailing whitespace are stripped.
3546
+ */
3547
+ title: string;
3548
+ /**
3549
+ * Raw markdown content of the section, excluding the heading line.
3550
+ * Preserves original formatting including code blocks and lists.
3551
+ */
3552
+ content: string;
3553
+ /**
3554
+ * 1-based line number where the section heading appears.
3555
+ */
3556
+ startLine: number;
3557
+ /**
3558
+ * 1-based line number of the last line of the section content.
3559
+ * This is the line before the next heading or end of file.
3560
+ */
3561
+ endLine: number;
3562
+ }
3563
+ /**
3564
+ * Represents an import directive that references external content.
3565
+ *
3566
+ * Imports use the @path/to/file syntax to include content from other files.
3567
+ * This allows modularizing memory across multiple files.
3568
+ *
3569
+ * @example
3570
+ * ```typescript
3571
+ * const memoryImport: MemoryImport = {
3572
+ * originalPath: "@./docs/style-guide.md",
3573
+ * resolvedPath: "/project/docs/style-guide.md",
3574
+ * resolved: true,
3575
+ * line: 5,
3576
+ * content: "# Style Guide\n..."
3577
+ * };
3578
+ * ```
3579
+ */
3580
+ interface MemoryImport {
3581
+ /**
3582
+ * Original import path as written in the memory file.
3583
+ * Includes the @ prefix.
3584
+ *
3585
+ * @example "@./docs/conventions.md"
3586
+ */
3587
+ originalPath: string;
3588
+ /**
3589
+ * Fully resolved absolute path to the imported file.
3590
+ * Resolved relative to the containing memory file's directory.
3591
+ */
3592
+ resolvedPath: string;
3593
+ /**
3594
+ * Whether the import was successfully resolved and loaded.
3595
+ * False if the file doesn't exist or couldn't be read.
3596
+ */
3597
+ resolved: boolean;
3598
+ /**
3599
+ * 1-based line number where the import directive appears.
3600
+ */
3601
+ line: number;
3602
+ /**
3603
+ * Content of the imported file, if successfully resolved.
3604
+ * Undefined if the import failed.
3605
+ */
3606
+ content?: string;
3607
+ /**
3608
+ * Error message if the import failed to resolve.
3609
+ * Provides details about why the import couldn't be loaded.
3610
+ */
3611
+ error?: string;
3612
+ }
3613
+ /**
3614
+ * Represents a single memory file with its parsed content.
3615
+ *
3616
+ * Memory files are markdown documents containing instructions, preferences,
3617
+ * and configuration for the AI assistant. They can include sections
3618
+ * organized by headings and import other files.
3619
+ *
3620
+ * @example
3621
+ * ```typescript
3622
+ * const memoryFile: MemoryFile = {
3623
+ * path: "/project/COCO.md",
3624
+ * level: "project",
3625
+ * content: "# Project Memory\n\n## Code Style\n...",
3626
+ * sections: [...],
3627
+ * imports: [...],
3628
+ * modifiedAt: new Date("2024-01-15"),
3629
+ * exists: true
3630
+ * };
3631
+ * ```
3632
+ */
3633
+ interface MemoryFile {
3634
+ /**
3635
+ * Absolute path to the memory file on the filesystem.
3636
+ */
3637
+ path: string;
3638
+ /**
3639
+ * Source level indicating the origin of this memory file.
3640
+ * Determines precedence when merging multiple memory sources.
3641
+ */
3642
+ level: MemoryLevel;
3643
+ /**
3644
+ * Processed content of the memory file (after import resolution).
3645
+ * Empty string if the file doesn't exist.
3646
+ */
3647
+ content: string;
3648
+ /**
3649
+ * Parsed sections extracted from the file content.
3650
+ * Each section corresponds to a ## heading and its content.
3651
+ */
3652
+ sections: MemorySection[];
3653
+ /**
3654
+ * Import directives found in the file and their resolution status.
3655
+ * Includes both successful and failed imports.
3656
+ */
3657
+ imports: MemoryImport[];
3658
+ /**
3659
+ * Timestamp when the file was last modified.
3660
+ * Used for cache invalidation and change detection.
3661
+ */
3662
+ modifiedAt: Date;
3663
+ /**
3664
+ * Whether the memory file exists on disk.
3665
+ * False for expected but missing memory files.
3666
+ */
3667
+ exists: boolean;
3668
+ }
3669
+ /**
3670
+ * Represents an error that occurred while loading or parsing memory.
3671
+ *
3672
+ * Errors can be recoverable (warnings) or fatal (blocking).
3673
+ * Recoverable errors allow the system to continue with partial memory.
3674
+ *
3675
+ * @example
3676
+ * ```typescript
3677
+ * const error: MemoryError = {
3678
+ * file: "/project/COCO.md",
3679
+ * level: "project",
3680
+ * error: "Circular import detected: ./a.md -> ./b.md -> ./a.md",
3681
+ * recoverable: true
3682
+ * };
3683
+ * ```
3684
+ */
3685
+ interface MemoryError {
3686
+ /**
3687
+ * Path to the file where the error occurred.
3688
+ * May be the memory file itself or an imported file.
3689
+ */
3690
+ file: string;
3691
+ /**
3692
+ * Memory level of the file that caused the error.
3693
+ */
3694
+ level: MemoryLevel;
3695
+ /**
3696
+ * Human-readable description of the error.
3697
+ */
3698
+ error: string;
3699
+ /**
3700
+ * Whether the system can continue despite this error.
3701
+ *
3702
+ * - `true`: Warning - the system can proceed with partial memory
3703
+ * - `false`: Fatal - the memory loading process should abort
3704
+ */
3705
+ recoverable: boolean;
3706
+ }
3707
+ /**
3708
+ * Combined memory context for a session, aggregating all memory sources.
3709
+ *
3710
+ * This is the primary interface used by the REPL and other components
3711
+ * to access the merged memory from all levels.
3712
+ *
3713
+ * @example
3714
+ * ```typescript
3715
+ * const context: MemoryContext = {
3716
+ * files: [userMemory, projectMemory, localMemory],
3717
+ * combinedContent: "# User Memory\n...\n# Project Memory\n...",
3718
+ * totalSize: 15420,
3719
+ * errors: []
3720
+ * };
3721
+ * ```
3722
+ */
3723
+ interface MemoryContext {
3724
+ /**
3725
+ * All loaded memory files, in order of precedence.
3726
+ * Includes files that don't exist (with exists: false).
3727
+ */
3728
+ files: MemoryFile[];
3729
+ /**
3730
+ * Combined content from all memory files, ready for use in prompts.
3731
+ *
3732
+ * The content is merged with clear delimiters between sources.
3733
+ * Later sources (higher precedence) appear after earlier ones.
3734
+ */
3735
+ combinedContent: string;
3736
+ /**
3737
+ * Total size of the combined content in characters.
3738
+ * Used for enforcing size limits and estimating token usage.
3739
+ */
3740
+ totalSize: number;
3741
+ /**
3742
+ * All errors encountered during memory loading.
3743
+ * Includes both recoverable warnings and fatal errors.
3744
+ */
3745
+ errors: MemoryError[];
3746
+ }
3747
+
3748
+ /**
3749
+ * Stack Detector for REPL Context Enrichment
3750
+ *
3751
+ * Detects project technology stack at REPL startup to enrich LLM context.
3752
+ * Prevents COCO from suggesting incompatible technologies (e.g., npm in Java projects).
3753
+ */
3754
+ type ProjectStack = "node" | "java" | "python" | "go" | "rust" | "unknown";
3755
+ interface ProjectStackContext {
3756
+ /** Primary language/runtime */
3757
+ stack: ProjectStack;
3758
+ /** Package manager (npm, pnpm, yarn, maven, gradle, cargo, pip, go) */
3759
+ packageManager: string | null;
3760
+ /** Key dependencies (name → version) */
3761
+ dependencies: Record<string, string>;
3762
+ /** Inferred frameworks (e.g., ["Spring Boot", "React", "FastAPI"]) */
3763
+ frameworks: string[];
3764
+ /** Build tools detected (e.g., ["gradle", "webpack", "vite"]) */
3765
+ buildTools: string[];
3766
+ /** Testing frameworks (e.g., ["junit", "vitest", "pytest"]) */
3767
+ testingFrameworks: string[];
3768
+ /** Languages detected (e.g., ["TypeScript", "Java", "Python"]) */
3769
+ languages: string[];
3770
+ }
3771
+
3772
+ /**
3773
+ * Unified Skill Types for Corbat-Coco
3774
+ *
3775
+ * Supports two kinds of skills:
3776
+ * - Markdown (SKILL.md): Industry-standard format from skills.sh, injected into LLM system prompt
3777
+ * - Native (TypeScript): Executable skills like /ship with deep runtime integration
3778
+ */
3779
+
3780
+ /** Where a skill was discovered */
3781
+ type SkillScope = "builtin" | "global" | "project";
3782
+ /** Two fundamental skill types */
3783
+ type SkillKind = "markdown" | "native";
3784
+ /** Extended categories (superset of existing REPL SkillCategory) */
3785
+ type SkillCategory = "general" | "git" | "model" | "coco" | "debug" | "custom" | "coding" | "testing" | "deployment" | "documentation" | "workflow";
3786
+ /** Skill execution risk level for routing and confirmation policy. */
3787
+ type SkillRisk = "read-only" | "write" | "network" | "destructive" | "secrets-sensitive";
3788
+ /** Agent surfaces a skill is known to support. */
3789
+ type SupportedAgentSurface = "coco" | "claude" | "codex" | "gemini" | "opencode";
3790
+ /** Lightweight skill descriptor (~50 tokens each, loaded at startup) */
3791
+ interface SkillMetadata {
3792
+ /** Unique identifier (derived from name, kebab-case) */
3793
+ id: string;
3794
+ /** Human-readable name */
3795
+ name: string;
3796
+ /** Short description -- used for semantic matching */
3797
+ description: string;
3798
+ /** Source repository or origin (e.g., "anthropics/skills", "local") */
3799
+ source?: string;
3800
+ /** Namespace prefix (derived from source directory structure) */
3801
+ namespace?: string;
3802
+ /** Version */
3803
+ version: string;
3804
+ /** Category for organization */
3805
+ category: SkillCategory;
3806
+ /** Kind of skill */
3807
+ kind: SkillKind;
3808
+ /** Where this skill was found */
3809
+ scope: SkillScope;
3810
+ /** Filesystem path to the skill root */
3811
+ path: string;
3812
+ /** Optional aliases for slash-command invocation */
3813
+ aliases?: string[];
3814
+ /** Optional glob patterns for auto-activation */
3815
+ globs?: string[];
3816
+ /** Tags for discovery */
3817
+ tags?: string[];
3818
+ /** Author information */
3819
+ author?: string;
3820
+ /** If true, this skill should NOT be auto-activated by the matcher */
3821
+ disableModelInvocation?: boolean;
3822
+ /** Tools this skill is allowed to use */
3823
+ allowedTools?: string[];
3824
+ /** Argument hint for CLI autocomplete */
3825
+ argumentHint?: string;
3826
+ /** Environment compatibility notes */
3827
+ compatibility?: string;
3828
+ /** Keyword triggers for explicit or automatic routing */
3829
+ triggers?: string[];
3830
+ /** Risk policy for confirmation/tool routing */
3831
+ risk?: SkillRisk;
3832
+ /** Agent surfaces this skill is intended to work with */
3833
+ supportedAgents?: SupportedAgentSurface[];
3834
+ /** Model override for this skill */
3835
+ model?: string;
3836
+ /** Execution context */
3837
+ context?: "fork" | "agent" | "inline";
3838
+ }
3839
+ /** Fully loaded markdown skill content */
3840
+ interface MarkdownSkillContent {
3841
+ /** The full markdown instructions */
3842
+ instructions: string;
3843
+ /** Paths to reference files, if any */
3844
+ references: string[];
3845
+ /** Paths to script files, if any */
3846
+ scripts: string[];
3847
+ /** Paths to template files, if any */
3848
+ templates: string[];
3849
+ }
3850
+ /** Fully loaded native skill content */
3851
+ interface NativeSkillContent {
3852
+ /** The execute function */
3853
+ execute: (args: string, context: SkillExecutionContext) => Promise<SkillExecutionResult>;
3854
+ }
3855
+ /** Union of loaded skill content */
3856
+ type SkillContent = MarkdownSkillContent | NativeSkillContent;
3857
+ /** A skill with content loaded */
3858
+ interface LoadedSkill {
3859
+ metadata: SkillMetadata;
3860
+ content: SkillContent;
3861
+ }
3862
+ /** Context for skill execution */
3863
+ interface SkillExecutionContext {
3864
+ cwd: string;
3865
+ session?: unknown;
3866
+ provider?: unknown;
3867
+ config?: unknown;
3868
+ }
3869
+ /** Result of skill execution */
3870
+ interface SkillExecutionResult {
3871
+ success: boolean;
3872
+ output?: string;
3873
+ error?: string;
3874
+ shouldExit?: boolean;
3875
+ /** If true, the output should be run as a subagent prompt (for context: fork/agent skills) */
3876
+ shouldFork?: boolean;
3877
+ }
3878
+ /** Result of matching user input against available skills */
3879
+ interface SkillMatch {
3880
+ skill: SkillMetadata;
3881
+ /** Relevance score 0-1 */
3882
+ score: number;
3883
+ /** Why this skill matched */
3884
+ reason: string;
3885
+ }
3886
+
3887
+ /**
3888
+ * TypeScript Native Skill Loader
3889
+ *
3890
+ * Adapts existing native Skill objects (from the REPL skills system)
3891
+ * into the unified skill type system. This is a thin wrapper that
3892
+ * converts existing skills without requiring changes to their code.
3893
+ */
3894
+
3895
+ /** The existing REPL Skill interface (duplicated here to avoid circular deps) */
3896
+ interface LegacySkill {
3897
+ name: string;
3898
+ description: string;
3899
+ usage?: string;
3900
+ aliases?: string[];
3901
+ category?: string;
3902
+ execute: (args: string, context: unknown) => Promise<{
3903
+ success: boolean;
3904
+ output?: string;
3905
+ error?: string;
3906
+ shouldExit?: boolean;
3907
+ }>;
3908
+ }
3909
+
3910
+ /**
3911
+ * Unified Skill Registry
3912
+ *
3913
+ * Central registry supporting both markdown (SKILL.md) and native (TypeScript) skills.
3914
+ * Metadata is loaded eagerly at startup; full content is loaded lazily on demand.
3915
+ */
3916
+
3917
+ /** Skill lifecycle events */
3918
+ type SkillEvent = {
3919
+ type: "activated";
3920
+ skillId: string;
3921
+ } | {
3922
+ type: "deactivated";
3923
+ skillId: string;
3924
+ } | {
3925
+ type: "executed";
3926
+ skillId: string;
3927
+ success: boolean;
3928
+ } | {
3929
+ type: "discovered";
3930
+ count: number;
3931
+ };
3932
+ type SkillEventListener = (event: SkillEvent) => void;
3933
+ /** Skills configuration (mirrors SkillsConfigSchema from config/schema.ts) */
3934
+ interface SkillsRuntimeConfig {
3935
+ enabled?: boolean;
3936
+ globalDir?: string;
3937
+ globalDirs?: string[];
3938
+ projectDir?: string;
3939
+ projectDirs?: string[];
3940
+ autoActivate?: boolean;
3941
+ maxActiveSkills?: number;
3942
+ disabled?: string[];
3943
+ }
3944
+ declare class UnifiedSkillRegistry {
3945
+ /** Skill metadata indexed by ID (loaded eagerly) */
3946
+ private metadata;
3947
+ /** Alias -> skill ID mapping */
3948
+ private aliases;
3949
+ /** Cached loaded skills (loaded lazily) */
3950
+ private loadedCache;
3951
+ /** Currently active markdown skill IDs (injected into system prompt) */
3952
+ private activeSkillIds;
3953
+ /** Event listeners for skill lifecycle events */
3954
+ private listeners;
3955
+ /** Runtime configuration from CocoConfig.skills */
3956
+ private _config;
3957
+ /**
3958
+ * Set runtime configuration for skills behavior
3959
+ */
3960
+ setConfig(config: SkillsRuntimeConfig): void;
3961
+ /** Get current configuration (read-only) */
3962
+ get config(): Readonly<SkillsRuntimeConfig>;
3963
+ /** Subscribe to skill lifecycle events. Returns an unsubscribe function. */
3964
+ on(listener: SkillEventListener): () => void;
3965
+ private emit;
3966
+ /**
3967
+ * Discover and register all skills across all scopes
3968
+ */
3969
+ discoverAndRegister(projectPath: string, builtinSkills?: LegacySkill[], globalDir?: string): Promise<void>;
3970
+ /**
3971
+ * Register skill metadata (and its aliases)
3972
+ */
3973
+ registerMetadata(meta: SkillMetadata): void;
3974
+ /** Get metadata by ID or alias */
3975
+ getMetadata(idOrAlias: string): SkillMetadata | undefined;
3976
+ /** Check if a skill exists */
3977
+ has(idOrAlias: string): boolean;
3978
+ /** Get all skill metadata */
3979
+ getAllMetadata(): SkillMetadata[];
3980
+ /** Get skills by category */
3981
+ getByCategory(category: SkillCategory): SkillMetadata[];
3982
+ /** Get skills by scope */
3983
+ getByScope(scope: SkillScope): SkillMetadata[];
3984
+ /** Get total skill count */
3985
+ get size(): number;
3986
+ /**
3987
+ * Load full skill content by ID (cached)
3988
+ */
3989
+ loadSkill(id: string): Promise<LoadedSkill | null>;
3990
+ /**
3991
+ * Activate a markdown skill (loads content and marks as active)
3992
+ *
3993
+ * Respects maxActiveSkills config: if limit would be exceeded,
3994
+ * the oldest active skill (FIFO) is deactivated to make room.
3995
+ */
3996
+ activateSkill(id: string): Promise<boolean>;
3997
+ /** Deactivate a skill */
3998
+ deactivateSkill(id: string): void;
3999
+ /** Deactivate all skills */
4000
+ deactivateAll(): void;
4001
+ /** Get all currently active loaded skills */
4002
+ getActiveSkills(): LoadedSkill[];
4003
+ /** Get active skill IDs */
4004
+ getActiveSkillIds(): string[];
4005
+ /**
4006
+ * Execute a skill by ID or alias
4007
+ */
4008
+ execute(idOrAlias: string, args: string, context: SkillExecutionContext): Promise<SkillExecutionResult>;
4009
+ /**
4010
+ * Find skills relevant to a user message
4011
+ */
4012
+ findRelevantSkills(userMessage: string, maxResults?: number, minScore?: number): SkillMatch[];
4013
+ }
4014
+
4015
+ /**
4016
+ * REPL types for Corbat-Coco
4017
+ */
4018
+
4019
+ /**
4020
+ * REPL session state
4021
+ */
4022
+ interface ReplSession {
4023
+ id: string;
4024
+ startedAt: Date;
4025
+ messages: Message[];
4026
+ projectPath: string;
4027
+ config: ReplConfig;
4028
+ /** Tools trusted for this session (skip confirmation) */
4029
+ trustedTools: Set<string>;
4030
+ /** Context window manager for tracking token usage */
4031
+ contextManager?: ContextManager;
4032
+ /** Progress tracker for todo-like task tracking */
4033
+ progressTracker?: ProgressTracker;
4034
+ /** Memory context from COCO.md/CLAUDE.md files */
4035
+ memoryContext?: MemoryContext;
4036
+ /** Project stack context (detected at startup) */
4037
+ projectContext?: ProjectStackContext;
4038
+ /** Unified skill registry (markdown + native skills) */
4039
+ skillRegistry?: UnifiedSkillRegistry;
4040
+ /** Last arguments passed to a skill (for $ARGUMENTS substitution) */
4041
+ lastSkillArguments?: string;
4042
+ /** Plan mode: restricts agent to read-only tools for planning */
4043
+ planMode?: boolean;
4044
+ /** Pending plan text awaiting user approval */
4045
+ pendingPlan?: string | null;
4046
+ /** Active workflow mode controlling prompts, tool access, and UX hints */
4047
+ agentMode?: AgentModeId;
4048
+ /** Reusable runtime facade for provider/tools/permissions/observability */
4049
+ runtime?: AgentRuntime;
4050
+ }
4051
+ /**
4052
+ * REPL configuration
4053
+ */
4054
+ interface ReplConfig {
4055
+ provider: {
4056
+ type: ProviderType;
4057
+ model: string;
4058
+ maxTokens: number;
4059
+ project?: string;
4060
+ location?: string;
4061
+ /** Active thinking/reasoning mode (undefined = not supported or use model default) */
4062
+ thinking?: ThinkingMode;
4063
+ /** Optional cheap model for background tasks (compaction, summarization) */
4064
+ weakModel?: string;
4065
+ /** Optional cheap model for file write/edit operations (architect/editor split) */
4066
+ editorModel?: string;
4067
+ };
4068
+ ui: {
4069
+ theme: "dark" | "light" | "auto";
4070
+ showTimestamps: boolean;
4071
+ maxHistorySize: number;
4072
+ /** When to show diff after file modifications */
4073
+ showDiff: "never" | "on_request" | "on_complete" | "always";
4074
+ };
4075
+ agent: {
4076
+ systemPrompt: string;
4077
+ maxToolIterations: number;
4078
+ confirmDestructive: boolean;
4079
+ /** If true, Coco may switch provider automatically after repeated provider failures */
4080
+ enableAutoSwitchProvider?: boolean;
4081
+ /** Enables bounded stream/provider recovery retries inside the agent loop */
4082
+ recoveryV2?: boolean;
4083
+ /** Enforces stricter read-only guarantees while plan mode is active */
4084
+ planModeStrict?: boolean;
4085
+ /** Enables the expanded read-only doctor diagnostics command */
4086
+ doctorV2?: boolean;
4087
+ /** Enables output offload instrumentation without changing context behavior */
4088
+ outputOffload?: boolean;
4089
+ };
4090
+ }
4091
+
4092
+ /**
4093
+ * Session persistence types for Corbat-Coco
4094
+ *
4095
+ * This module defines types for persisting and resuming REPL sessions,
4096
+ * allowing users to continue work after restarts or interruptions.
4097
+ */
4098
+
4099
+ /**
4100
+ * Session status indicating the state when the session was last saved
4101
+ */
4102
+ type SessionStatus = "active" | "completed" | "interrupted" | "error";
4103
+ /**
4104
+ * Persisted session metadata for quick listing and resumption
4105
+ */
4106
+ interface PersistedSession {
4107
+ /** Unique session identifier */
4108
+ id: string;
4109
+ /** Project path where session was created */
4110
+ projectPath: string;
4111
+ /** When the session started */
4112
+ startedAt: Date;
4113
+ /** When the session was last saved */
4114
+ lastSavedAt: Date;
4115
+ /** Session configuration */
4116
+ config: ReplConfig;
4117
+ /** Message count (for quick display without loading full conversation) */
4118
+ messageCount: number;
4119
+ /** Total tokens used during the session */
4120
+ totalTokens: {
4121
+ input: number;
4122
+ output: number;
4123
+ };
4124
+ /** Human-readable title/summary of the session */
4125
+ title?: string;
4126
+ /** Whether session completed normally or was interrupted */
4127
+ status: SessionStatus;
4128
+ }
4129
+ /**
4130
+ * Session storage interface for persistence operations
4131
+ */
4132
+ interface SessionStorage {
4133
+ /**
4134
+ * Save a session to disk
4135
+ * @param session - The REPL session to persist
4136
+ */
4137
+ save(session: ReplSession): Promise<void>;
4138
+ /**
4139
+ * Load a session from disk
4140
+ * @param sessionId - The unique session identifier
4141
+ * @returns The loaded session or null if not found
4142
+ */
4143
+ load(sessionId: string): Promise<ReplSession | null>;
4144
+ /**
4145
+ * List all sessions, optionally filtered by project path
4146
+ * @param projectPath - Optional project path to filter by
4147
+ * @returns Array of persisted session metadata
4148
+ */
4149
+ listSessions(projectPath?: string): Promise<PersistedSession[]>;
4150
+ /**
4151
+ * Delete a session from disk
4152
+ * @param sessionId - The unique session identifier
4153
+ * @returns True if deleted, false if not found
4154
+ */
4155
+ delete(sessionId: string): Promise<boolean>;
4156
+ /**
4157
+ * Get the most recent session for a project
4158
+ * @param projectPath - The project path to search
4159
+ * @returns The most recent session or null if none exist
4160
+ */
4161
+ getMostRecent(projectPath: string): Promise<PersistedSession | null>;
4162
+ }
4163
+ /**
4164
+ * Configuration for session persistence behavior
4165
+ */
4166
+ interface SessionPersistenceConfig {
4167
+ /** Directory to store session files */
4168
+ storageDir: string;
4169
+ /** Auto-save interval in milliseconds (default: 30000 = 30 seconds) */
4170
+ autoSaveInterval: number;
4171
+ /** Maximum sessions to keep per project (default: 20) */
4172
+ maxSessionsPerProject: number;
4173
+ /** Whether to compress old sessions to save disk space */
4174
+ compressOldSessions: boolean;
4175
+ }
4176
+
4177
+ /**
4178
+ * Session Storage Implementation
4179
+ *
4180
+ * Handles persisting and loading REPL sessions to disk.
4181
+ * Uses a directory-per-session structure for efficient reads and writes.
4182
+ *
4183
+ * Storage Structure:
4184
+ * ~/.coco/sessions/
4185
+ * <session-id>/
4186
+ * metadata.json - PersistedSession info
4187
+ * conversation.jsonl - Messages, one per line
4188
+ * context.json - Context manager state
4189
+ */
4190
+
4191
+ /**
4192
+ * SessionStore class implementing SessionStorage interface
4193
+ */
4194
+ declare class SessionStore implements SessionStorage {
4195
+ private config;
4196
+ private initialized;
4197
+ constructor(config?: Partial<SessionPersistenceConfig>);
4198
+ private ensureInitialized;
4199
+ private getSessionFiles;
4200
+ getSessionDir(sessionId: string): string;
4201
+ exists(sessionId: string): Promise<boolean>;
4202
+ save(session: ReplSession): Promise<void>;
4203
+ load(sessionId: string): Promise<ReplSession | null>;
4204
+ listSessions(projectPath?: string): Promise<PersistedSession[]>;
4205
+ delete(sessionId: string): Promise<boolean>;
4206
+ getMostRecent(projectPath: string): Promise<PersistedSession | null>;
4207
+ /**
4208
+ * Append messages to an existing session's conversation file
4209
+ * Creates the file if it doesn't exist
4210
+ * @param sessionId - The session ID
4211
+ * @param messages - Messages to append
4212
+ */
4213
+ appendMessages(sessionId: string, messages: Message[]): Promise<void>;
4214
+ /**
4215
+ * Prune old sessions to keep storage manageable
4216
+ * Keeps the most recent maxSessionsPerProject sessions per project
4217
+ * @param projectPath - Optional project path to prune (prunes all if not specified)
4218
+ * @returns Number of sessions deleted
4219
+ */
4220
+ pruneOldSessions(projectPath?: string): Promise<number>;
4221
+ private calculateTokens;
4222
+ private generateTitle;
4223
+ }
4224
+
3152
4225
  /**
3153
4226
  * Tool Registry for Corbat-Coco
3154
4227
  * Central management of all available tools
@@ -3253,6 +4326,200 @@ declare class ToolRegistry {
3253
4326
  */
3254
4327
  declare function createToolRegistry(): ToolRegistry;
3255
4328
 
4329
+ /** Catalog-backed provider/model registry used by runtime consumers. */
4330
+ declare class ProviderRegistry {
4331
+ listProviders(): ProviderCatalogEntry[];
4332
+ getProvider(provider: ProviderType): ProviderCatalogEntry;
4333
+ listModels(provider: ProviderType): ModelCatalogEntry[];
4334
+ getModel(provider: ProviderType, model: string): ModelCatalogEntry | undefined;
4335
+ getDefaultModel(provider: ProviderType): string;
4336
+ getRecommendedModel(provider: ProviderType): ModelCatalogEntry;
4337
+ getCapability(provider: ProviderType, model?: string): ProviderRuntimeCapability;
4338
+ createProvider(provider: ProviderType, config?: ProviderConfig): Promise<LLMProvider>;
4339
+ probe(provider: ProviderType, model: string | undefined, checkAvailability?: () => Promise<boolean>): Promise<ProviderProbeResult>;
4340
+ }
4341
+ declare function createProviderRegistry(): ProviderRegistry;
4342
+
4343
+ type ReasoningEffort = "auto" | "low" | "medium" | "high" | "max";
4344
+ type RuntimeMode = AgentModeId;
4345
+ interface AgentRuntimeOptions {
4346
+ providerType: ProviderType;
4347
+ model?: string;
4348
+ providerConfig?: ProviderConfig;
4349
+ provider?: LLMProvider;
4350
+ toolRegistry?: ToolRegistry;
4351
+ sessionStore?: SessionStore;
4352
+ permissionPolicy?: PermissionPolicy;
4353
+ eventLog?: EventLog;
4354
+ eventLogPath?: string;
4355
+ /**
4356
+ * Publish provider/tools into Coco's legacy process-global subagent bridge.
4357
+ * CLI/headless use this for compatibility; embedders should leave it false.
4358
+ */
4359
+ publishToGlobalBridge?: boolean;
4360
+ }
4361
+ interface AgentRuntimeSnapshot {
4362
+ provider: {
4363
+ type: ProviderType;
4364
+ model: string;
4365
+ capability: ProviderRuntimeCapability;
4366
+ };
4367
+ tools: {
4368
+ count: number;
4369
+ names: string[];
4370
+ };
4371
+ modes: AgentModeDefinition[];
4372
+ }
4373
+ type RuntimeEventType = "runtime.initialized" | "provider.attached" | "provider.created" | "provider.updated" | "turn.started" | "turn.completed" | "turn.failed" | "tool.started" | "tool.completed" | "tool.allowed" | "tool.blocked" | "tool.skipped" | "workflow.planned" | "workflow.started" | "workflow.completed" | "workflow.failed" | "session.created" | "checkpoint.created" | "error";
4374
+ interface RuntimeEvent {
4375
+ id: string;
4376
+ type: RuntimeEventType;
4377
+ timestamp: string;
4378
+ data: Record<string, unknown>;
4379
+ }
4380
+ interface EventLog {
4381
+ record(type: RuntimeEventType, data?: Record<string, unknown>): RuntimeEvent;
4382
+ list(): RuntimeEvent[];
4383
+ count(): number;
4384
+ clear(): void;
4385
+ }
4386
+ interface PermissionDecision {
4387
+ allowed: boolean;
4388
+ reason?: string;
4389
+ requiresConfirmation?: boolean;
4390
+ risk: "read-only" | "write" | "network" | "destructive" | "secrets-sensitive";
4391
+ }
4392
+ interface PermissionPolicy {
4393
+ canExecuteTool(mode: RuntimeMode, tool: ToolDefinition): PermissionDecision;
4394
+ }
4395
+ interface ProviderRuntimeSelection {
4396
+ provider: ProviderType;
4397
+ model: string;
4398
+ thinking?: ThinkingMode;
4399
+ }
4400
+
4401
+ /**
4402
+ * Reusable runtime facade for wiring providers, tools, permissions, sessions,
4403
+ * and observability. It does not own the CLI loop; CLI/headless are adapters on
4404
+ * top of this boundary.
4405
+ */
4406
+ declare class AgentRuntime {
4407
+ private readonly options;
4408
+ readonly providerRegistry: ProviderRegistry;
4409
+ readonly toolRegistry: ToolRegistry;
4410
+ readonly sessionStore: SessionStore;
4411
+ readonly permissionPolicy: PermissionPolicy;
4412
+ readonly eventLog: EventLog;
4413
+ private providerType;
4414
+ private model;
4415
+ constructor(options: AgentRuntimeOptions);
4416
+ initialize(): Promise<void>;
4417
+ getModel(): string;
4418
+ updateProvider(providerType: ProviderType, model: string | undefined, provider: LLMProvider): void;
4419
+ private publishToGlobalBridge;
4420
+ snapshot(): AgentRuntimeSnapshot;
4421
+ assertToolAllowed(mode: RuntimeMode, toolName: string): boolean;
4422
+ }
4423
+ declare function createAgentRuntime(options: AgentRuntimeOptions): Promise<AgentRuntime>;
4424
+
4425
+ declare class InMemoryEventLog implements EventLog {
4426
+ private events;
4427
+ record(type: RuntimeEventType, data?: Record<string, unknown>): RuntimeEvent;
4428
+ list(): RuntimeEvent[];
4429
+ count(): number;
4430
+ clear(): void;
4431
+ }
4432
+ declare class FileEventLog implements EventLog {
4433
+ private readonly filePath;
4434
+ private memory;
4435
+ private writable;
4436
+ constructor(filePath: string);
4437
+ record(type: RuntimeEventType, data?: Record<string, unknown>): RuntimeEvent;
4438
+ list(): RuntimeEvent[];
4439
+ count(): number;
4440
+ clear(): void;
4441
+ }
4442
+ declare function createEventLog(): EventLog;
4443
+ declare function createFileEventLog(filePath: string): EventLog;
4444
+
4445
+ declare class DefaultPermissionPolicy implements PermissionPolicy {
4446
+ canExecuteTool(mode: RuntimeMode, tool: ToolDefinition): PermissionDecision;
4447
+ }
4448
+ declare function createPermissionPolicy(): PermissionPolicy;
4449
+
4450
+ type ExtensionRisk = "read-only" | "write" | "network" | "destructive" | "secrets-sensitive";
4451
+ type AgentSurface = "coco" | "claude" | "codex" | "gemini" | "opencode";
4452
+ interface SkillManifest {
4453
+ name: string;
4454
+ description: string;
4455
+ triggers: string[];
4456
+ requiredTools: string[];
4457
+ risk: ExtensionRisk;
4458
+ compatibleAgents: AgentSurface[];
4459
+ sourcePath?: string;
4460
+ }
4461
+ interface RecipeStep {
4462
+ id: string;
4463
+ description: string;
4464
+ requiredTools?: string[];
4465
+ check?: string;
4466
+ }
4467
+ interface RecipeManifest {
4468
+ name: string;
4469
+ description: string;
4470
+ inputs: string[];
4471
+ suggestedModels?: string[];
4472
+ steps: RecipeStep[];
4473
+ checks: string[];
4474
+ risk: ExtensionRisk;
4475
+ }
4476
+ interface McpToolPolicy {
4477
+ server: string;
4478
+ tool: string;
4479
+ risk: ExtensionRisk;
4480
+ requiresConfirmation: boolean;
4481
+ allowedModes: string[];
4482
+ }
4483
+ declare function createMcpToolPolicy(server: string, tool: string, risk: ExtensionRisk, allowedModes?: string[]): McpToolPolicy;
4484
+
4485
+ type WorkflowRisk = "read-only" | "write" | "network" | "destructive" | "secrets-sensitive";
4486
+ interface WorkflowStepDefinition {
4487
+ id: string;
4488
+ description: string;
4489
+ requiredTools: string[];
4490
+ risk: WorkflowRisk;
4491
+ }
4492
+ interface WorkflowDefinition {
4493
+ id: string;
4494
+ name: string;
4495
+ description: string;
4496
+ inputSchema: string;
4497
+ steps: WorkflowStepDefinition[];
4498
+ checks: string[];
4499
+ outputKind: "markdown" | "json" | "patch" | "pull-request" | "release";
4500
+ replayable: boolean;
4501
+ }
4502
+ interface WorkflowPlan {
4503
+ id: string;
4504
+ workflowId: string;
4505
+ input: Record<string, unknown>;
4506
+ status: "planned";
4507
+ createdAt: string;
4508
+ }
4509
+ /** Descriptive catalog of reusable workflow definitions; it does not execute workflows. */
4510
+ declare class WorkflowCatalog {
4511
+ private workflows;
4512
+ constructor(workflows?: WorkflowDefinition[]);
4513
+ register(workflow: WorkflowDefinition): void;
4514
+ get(id: string): WorkflowDefinition | undefined;
4515
+ list(): WorkflowDefinition[];
4516
+ createPlan(workflowId: string, input: Record<string, unknown>, eventLog?: EventLog): WorkflowPlan;
4517
+ }
4518
+ declare const DEFAULT_WORKFLOWS: WorkflowDefinition[];
4519
+ declare const WorkflowRegistry: typeof WorkflowCatalog;
4520
+ declare function createWorkflowCatalog(workflows?: WorkflowDefinition[]): WorkflowCatalog;
4521
+ declare function createWorkflowRegistry(workflows?: WorkflowDefinition[]): WorkflowCatalog;
4522
+
3256
4523
  /**
3257
4524
  * Tool exports for Corbat-Coco
3258
4525
  */
@@ -3300,4 +4567,4 @@ interface SystemProxyConfig {
3300
4567
  */
3301
4568
  declare function installProxyDispatcher(resolveSystem?: () => SystemProxyConfig | null): string | null;
3302
4569
 
3303
- export { ADRGenerator, AnthropicProvider, ArchitectureGenerator, type Backlog, BacklogGenerator, CICDGenerator, type ChatOptions, type ChatResponse, type CocoConfig, CocoError, CodeGenerator, CodeReviewer, CompleteExecutor, ConfigError, ConvergeExecutor, DiscoveryEngine, DockerGenerator, DocsGenerator, type Epic, type LLMProvider, type Message, OrchestrateExecutor, type Orchestrator, type OrchestratorConfig, OutputExecutor, type Phase, type PhaseContext, PhaseError, type PhaseExecutor, type PhaseResult, type Progress, type ProjectState, type QualityDimensions, type QualityScores, type QualityThresholds, SessionManager, SpecificationGenerator, type Sprint, type Story, type Task, TaskError, type TaskHistory, TaskIterator, type TaskVersion, ToolRegistry, VERSION, configExists, createADRGenerator, createAnthropicProvider, createArchitectureGenerator, createBacklogGenerator, createCICDGenerator, createCodeGenerator, createCodeReviewer, createCompleteExecutor, createConvergeExecutor, createDefaultConfig, createDiscoveryEngine, createDockerGenerator, createDocsGenerator, createFullToolRegistry, createLogger, createOrchestrateExecutor, createOrchestrator, createOutputExecutor, createProvider, createSessionManager, createSpecificationGenerator, createTaskIterator, createToolRegistry, installProxyDispatcher, loadConfig, registerAllTools, saveConfig };
4570
+ export { ADRGenerator, AgentRuntime, type AgentRuntimeOptions, type AgentRuntimeSnapshot, type AgentSurface, AnthropicProvider, ArchitectureGenerator, type Backlog, BacklogGenerator, CICDGenerator, type ChatOptions, type ChatResponse, type CocoConfig, CocoError, CodeGenerator, CodeReviewer, CompleteExecutor, ConfigError, ConvergeExecutor, DEFAULT_WORKFLOWS, DefaultPermissionPolicy, DiscoveryEngine, DockerGenerator, DocsGenerator, type Epic, type EventLog, type ExtensionRisk, FileEventLog, InMemoryEventLog, type LLMProvider, type McpToolPolicy, type Message, OrchestrateExecutor, type Orchestrator, type OrchestratorConfig, OutputExecutor, type PermissionDecision, type PermissionPolicy, type Phase, type PhaseContext, PhaseError, type PhaseExecutor, type PhaseResult, type Progress, type ProjectState, ProviderRegistry, type ProviderRuntimeSelection, type QualityDimensions, type QualityScores, type QualityThresholds, type ReasoningEffort, type RecipeManifest, type RecipeStep, type RuntimeEvent, type RuntimeEventType, type RuntimeMode, SessionManager, type SkillManifest, SpecificationGenerator, type Sprint, type Story, type Task, TaskError, type TaskHistory, TaskIterator, type TaskVersion, ToolRegistry, VERSION, WorkflowCatalog, type WorkflowDefinition, type WorkflowPlan, WorkflowRegistry, type WorkflowRisk, type WorkflowStepDefinition, configExists, createADRGenerator, createAgentRuntime, createAnthropicProvider, createArchitectureGenerator, createBacklogGenerator, createCICDGenerator, createCodeGenerator, createCodeReviewer, createCompleteExecutor, createConvergeExecutor, createDefaultConfig, createDiscoveryEngine, createDockerGenerator, createDocsGenerator, createEventLog, createFileEventLog, createFullToolRegistry, createLogger, createMcpToolPolicy, createOrchestrateExecutor, createOrchestrator, createOutputExecutor, createPermissionPolicy, createProvider, createProviderRegistry, createSessionManager, createSpecificationGenerator, createTaskIterator, createToolRegistry, createWorkflowCatalog, createWorkflowRegistry, installProxyDispatcher, loadConfig, registerAllTools, saveConfig };