cascade-ai 0.15.2 → 0.17.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.cts CHANGED
@@ -1574,10 +1574,15 @@ type T1Evaluator = (req: PermissionRequest) => Promise<PermissionDecision | null
1574
1574
  * PermissionEscalator manages the hierarchical permission flow for a single task run.
1575
1575
  *
1576
1576
  * Decision cascade:
1577
- * 1. Check session cache (section-wide key `${t2Id}:${toolName}`) return if hit
1578
- * 2. Ask T2 evaluator if decision returned, cache + return
1579
- * 3. Ask T1 evaluator if decision returned, cache + return
1580
- * 4. Emit `permission:user-required` wait for external decision via `resolveUserDecision()`
1577
+ * 1. Check the task-wide cache (USER/T1 "always" decisions, keyed by `toolName`
1578
+ * alone) → return if hit. These are deliberately NOT scoped to one T2, so a
1579
+ * user's or T1's "Always" covers every sibling worker anywhere in the run.
1580
+ * 2. Check the per-T2 session cache (section-wide key `${t2Id}:${toolName}`)
1581
+ * → return if hit
1582
+ * 3. Ask T2 evaluator → if decision returned, cache (per-T2) + return
1583
+ * 4. Ask T1 evaluator → if decision returned, cache (task-wide) + return
1584
+ * 5. Emit `permission:user-required` → wait for external decision via
1585
+ * `resolveUserDecision()`; an "always" answer caches task-wide.
1581
1586
  */
1582
1587
  declare class PermissionEscalator extends EventEmitter {
1583
1588
  /**
@@ -1585,6 +1590,13 @@ declare class PermissionEscalator extends EventEmitter {
1585
1590
  * All T3 workers under the same T2 share cached decisions for the same tool.
1586
1591
  */
1587
1592
  private sessionCache;
1593
+ /**
1594
+ * Task-wide cache keyed by `toolName` alone, for USER- and T1-level
1595
+ * "always" decisions — these are meant to cover every sibling T2/T3 in the
1596
+ * run, not just the one that happened to ask first (see PermissionDecision
1597
+ * doc comment: "task-wide for T1").
1598
+ */
1599
+ private taskWideCache;
1588
1600
  private t2Evaluator?;
1589
1601
  private t1Evaluator?;
1590
1602
  /** Pending user-decision resolvers keyed by request ID */
@@ -1742,6 +1754,9 @@ declare class T1Administrator extends BaseTier {
1742
1754
  * so it never blocks the approval gate.
1743
1755
  */
1744
1756
  private reviewPlan;
1757
+ /** Structured, grounded summary of what's already done — used to keep
1758
+ * corrective replan passes from re-emitting completed sections. */
1759
+ private summarizeCompletedSections;
1745
1760
  private decomposeTask;
1746
1761
  private validatePlan;
1747
1762
  private dispatchT2Managers;
@@ -2346,6 +2361,17 @@ declare class DashboardSocket {
2346
2361
  private setupHandlers;
2347
2362
  onSessionRate(callback: (sessionId: string, rating: 'good' | 'bad') => void): void;
2348
2363
  onSessionHalt(callback: (sessionId: string) => void): void;
2364
+ /**
2365
+ * Boardroom plan decisions from a connected client. The desktop shows a
2366
+ * plan-review modal on `plan:approval-required` and answers here; the
2367
+ * server routes the decision into the paused run via resolvePlanApproval.
2368
+ */
2369
+ onPlanDecision(callback: (data: {
2370
+ sessionId: string;
2371
+ approved: boolean;
2372
+ note?: string;
2373
+ editedPlan?: unknown;
2374
+ }) => void): void;
2349
2375
  onSessionSteer(callback: (message: string, sessionId?: string, nodeId?: string) => void): void;
2350
2376
  onConfigUpdate(callback: (data: {
2351
2377
  keys?: Record<string, string>;
@@ -2385,6 +2411,14 @@ declare class DashboardServer {
2385
2411
  * map is how that answer reaches the run that's blocked on it.
2386
2412
  */
2387
2413
  private pendingApprovals;
2414
+ /**
2415
+ * The orchestration decision trail ("why") of each session's most recent
2416
+ * run — captured when the run ends so the desktop's Why panel can show it
2417
+ * after the fact. Bounded: oldest entry evicted past 50 sessions.
2418
+ */
2419
+ private whyBySession;
2420
+ /** Cron scheduler for the Schedules UI — runs tasks while this server is up. */
2421
+ private scheduler;
2388
2422
  private port;
2389
2423
  private host;
2390
2424
  private workspacePath;
@@ -2392,6 +2426,14 @@ declare class DashboardServer {
2392
2426
  start(): Promise<void>;
2393
2427
  stop(): Promise<void>;
2394
2428
  getSocket(): DashboardSocket;
2429
+ /**
2430
+ * Rebind the workspace tasks execute in — e.g. the desktop app's Code view
2431
+ * opening a different project folder — without tearing down the socket
2432
+ * server (which would drop the port/auth token/connection mid-session).
2433
+ * The next `cascade:run` picks this up immediately since `this.workspacePath`
2434
+ * is read live per-run (see onCascadeRun below).
2435
+ */
2436
+ setWorkspacePath(workspacePath: string): void;
2395
2437
  /**
2396
2438
  * Write the in-memory config back to the workspace config file so mutations
2397
2439
  * made over the socket (Settings → Save) persist across restarts. Best-effort:
@@ -2417,6 +2459,12 @@ declare class DashboardServer {
2417
2459
  private persistRunStart;
2418
2460
  /** Record run end: the assistant reply (when there is one) and the runtime row's final status. */
2419
2461
  private persistRunEnd;
2462
+ /**
2463
+ * Capture the run's decision trail + router economics ("why") and broadcast
2464
+ * it so the desktop's Why panel updates live; kept per-session for the
2465
+ * GET /api/sessions/:id/why fallback (panel opened after the run).
2466
+ */
2467
+ private captureWhy;
2420
2468
  /**
2421
2469
  * Route steering text into running Cascade instances. Targets the given
2422
2470
  * session, or every active session when none is specified (the desktop
@@ -2434,6 +2482,13 @@ declare class DashboardServer {
2434
2482
  * timeout denies it.
2435
2483
  */
2436
2484
  private makeApprovalCallback;
2485
+ /**
2486
+ * Execute one scheduled task firing. Runs headless (like `cascade run -p`):
2487
+ * tool approvals are auto-granted since nobody may be watching when the cron
2488
+ * fires — the Schedules UI states this. Events broadcast to every connected
2489
+ * client so an open desktop sees the run appear live.
2490
+ */
2491
+ private runScheduledTask;
2437
2492
  /** Deny + clear any approvals still pending for a session (run end / abort). */
2438
2493
  private denyPendingApprovals;
2439
2494
  private persistRuntimeRow;
package/dist/index.d.ts CHANGED
@@ -1574,10 +1574,15 @@ type T1Evaluator = (req: PermissionRequest) => Promise<PermissionDecision | null
1574
1574
  * PermissionEscalator manages the hierarchical permission flow for a single task run.
1575
1575
  *
1576
1576
  * Decision cascade:
1577
- * 1. Check session cache (section-wide key `${t2Id}:${toolName}`) return if hit
1578
- * 2. Ask T2 evaluator if decision returned, cache + return
1579
- * 3. Ask T1 evaluator if decision returned, cache + return
1580
- * 4. Emit `permission:user-required` wait for external decision via `resolveUserDecision()`
1577
+ * 1. Check the task-wide cache (USER/T1 "always" decisions, keyed by `toolName`
1578
+ * alone) → return if hit. These are deliberately NOT scoped to one T2, so a
1579
+ * user's or T1's "Always" covers every sibling worker anywhere in the run.
1580
+ * 2. Check the per-T2 session cache (section-wide key `${t2Id}:${toolName}`)
1581
+ * → return if hit
1582
+ * 3. Ask T2 evaluator → if decision returned, cache (per-T2) + return
1583
+ * 4. Ask T1 evaluator → if decision returned, cache (task-wide) + return
1584
+ * 5. Emit `permission:user-required` → wait for external decision via
1585
+ * `resolveUserDecision()`; an "always" answer caches task-wide.
1581
1586
  */
1582
1587
  declare class PermissionEscalator extends EventEmitter {
1583
1588
  /**
@@ -1585,6 +1590,13 @@ declare class PermissionEscalator extends EventEmitter {
1585
1590
  * All T3 workers under the same T2 share cached decisions for the same tool.
1586
1591
  */
1587
1592
  private sessionCache;
1593
+ /**
1594
+ * Task-wide cache keyed by `toolName` alone, for USER- and T1-level
1595
+ * "always" decisions — these are meant to cover every sibling T2/T3 in the
1596
+ * run, not just the one that happened to ask first (see PermissionDecision
1597
+ * doc comment: "task-wide for T1").
1598
+ */
1599
+ private taskWideCache;
1588
1600
  private t2Evaluator?;
1589
1601
  private t1Evaluator?;
1590
1602
  /** Pending user-decision resolvers keyed by request ID */
@@ -1742,6 +1754,9 @@ declare class T1Administrator extends BaseTier {
1742
1754
  * so it never blocks the approval gate.
1743
1755
  */
1744
1756
  private reviewPlan;
1757
+ /** Structured, grounded summary of what's already done — used to keep
1758
+ * corrective replan passes from re-emitting completed sections. */
1759
+ private summarizeCompletedSections;
1745
1760
  private decomposeTask;
1746
1761
  private validatePlan;
1747
1762
  private dispatchT2Managers;
@@ -2346,6 +2361,17 @@ declare class DashboardSocket {
2346
2361
  private setupHandlers;
2347
2362
  onSessionRate(callback: (sessionId: string, rating: 'good' | 'bad') => void): void;
2348
2363
  onSessionHalt(callback: (sessionId: string) => void): void;
2364
+ /**
2365
+ * Boardroom plan decisions from a connected client. The desktop shows a
2366
+ * plan-review modal on `plan:approval-required` and answers here; the
2367
+ * server routes the decision into the paused run via resolvePlanApproval.
2368
+ */
2369
+ onPlanDecision(callback: (data: {
2370
+ sessionId: string;
2371
+ approved: boolean;
2372
+ note?: string;
2373
+ editedPlan?: unknown;
2374
+ }) => void): void;
2349
2375
  onSessionSteer(callback: (message: string, sessionId?: string, nodeId?: string) => void): void;
2350
2376
  onConfigUpdate(callback: (data: {
2351
2377
  keys?: Record<string, string>;
@@ -2385,6 +2411,14 @@ declare class DashboardServer {
2385
2411
  * map is how that answer reaches the run that's blocked on it.
2386
2412
  */
2387
2413
  private pendingApprovals;
2414
+ /**
2415
+ * The orchestration decision trail ("why") of each session's most recent
2416
+ * run — captured when the run ends so the desktop's Why panel can show it
2417
+ * after the fact. Bounded: oldest entry evicted past 50 sessions.
2418
+ */
2419
+ private whyBySession;
2420
+ /** Cron scheduler for the Schedules UI — runs tasks while this server is up. */
2421
+ private scheduler;
2388
2422
  private port;
2389
2423
  private host;
2390
2424
  private workspacePath;
@@ -2392,6 +2426,14 @@ declare class DashboardServer {
2392
2426
  start(): Promise<void>;
2393
2427
  stop(): Promise<void>;
2394
2428
  getSocket(): DashboardSocket;
2429
+ /**
2430
+ * Rebind the workspace tasks execute in — e.g. the desktop app's Code view
2431
+ * opening a different project folder — without tearing down the socket
2432
+ * server (which would drop the port/auth token/connection mid-session).
2433
+ * The next `cascade:run` picks this up immediately since `this.workspacePath`
2434
+ * is read live per-run (see onCascadeRun below).
2435
+ */
2436
+ setWorkspacePath(workspacePath: string): void;
2395
2437
  /**
2396
2438
  * Write the in-memory config back to the workspace config file so mutations
2397
2439
  * made over the socket (Settings → Save) persist across restarts. Best-effort:
@@ -2417,6 +2459,12 @@ declare class DashboardServer {
2417
2459
  private persistRunStart;
2418
2460
  /** Record run end: the assistant reply (when there is one) and the runtime row's final status. */
2419
2461
  private persistRunEnd;
2462
+ /**
2463
+ * Capture the run's decision trail + router economics ("why") and broadcast
2464
+ * it so the desktop's Why panel updates live; kept per-session for the
2465
+ * GET /api/sessions/:id/why fallback (panel opened after the run).
2466
+ */
2467
+ private captureWhy;
2420
2468
  /**
2421
2469
  * Route steering text into running Cascade instances. Targets the given
2422
2470
  * session, or every active session when none is specified (the desktop
@@ -2434,6 +2482,13 @@ declare class DashboardServer {
2434
2482
  * timeout denies it.
2435
2483
  */
2436
2484
  private makeApprovalCallback;
2485
+ /**
2486
+ * Execute one scheduled task firing. Runs headless (like `cascade run -p`):
2487
+ * tool approvals are auto-granted since nobody may be watching when the cron
2488
+ * fires — the Schedules UI states this. Events broadcast to every connected
2489
+ * client so an open desktop sees the run appear live.
2490
+ */
2491
+ private runScheduledTask;
2437
2492
  /** Deny + clear any approvals still pending for a session (run end / abort). */
2438
2493
  private denyPendingApprovals;
2439
2494
  private persistRuntimeRow;