@bradygaster/squad-sdk 0.6.2 → 0.8.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 +296 -296
- package/dist/adapter/client.d.ts +225 -0
- package/dist/adapter/client.d.ts.map +1 -0
- package/dist/adapter/client.js +397 -0
- package/dist/adapter/client.js.map +1 -0
- package/dist/adapter/errors.d.ts +260 -0
- package/dist/adapter/errors.d.ts.map +1 -0
- package/dist/adapter/errors.js +362 -0
- package/dist/adapter/errors.js.map +1 -0
- package/dist/adapter/types.d.ts +779 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/adapter/types.js +11 -0
- package/dist/adapter/types.js.map +1 -0
- package/dist/agents/charter-compiler.d.ts +102 -0
- package/dist/agents/charter-compiler.d.ts.map +1 -0
- package/dist/agents/charter-compiler.js +157 -0
- package/dist/agents/charter-compiler.js.map +1 -0
- package/dist/agents/history-shadow.d.ts +80 -0
- package/dist/agents/history-shadow.d.ts.map +1 -0
- package/dist/agents/history-shadow.js +239 -0
- package/dist/agents/history-shadow.js.map +1 -0
- package/dist/agents/index.d.ts +68 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +74 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/lifecycle.d.ts +138 -0
- package/dist/agents/lifecycle.d.ts.map +1 -0
- package/dist/agents/lifecycle.js +258 -0
- package/dist/agents/lifecycle.js.map +1 -0
- package/dist/agents/model-selector.d.ts +80 -0
- package/dist/agents/model-selector.d.ts.map +1 -0
- package/dist/agents/model-selector.js +198 -0
- package/dist/agents/model-selector.js.map +1 -0
- package/dist/agents/onboarding.d.ts +65 -0
- package/dist/agents/onboarding.d.ts.map +1 -0
- package/dist/agents/onboarding.js +373 -0
- package/dist/agents/onboarding.js.map +1 -0
- package/dist/build/bundle.d.ts +32 -0
- package/dist/build/bundle.d.ts.map +1 -0
- package/dist/build/bundle.js +97 -0
- package/dist/build/bundle.js.map +1 -0
- package/dist/build/ci-pipeline.d.ts +51 -0
- package/dist/build/ci-pipeline.d.ts.map +1 -0
- package/dist/build/ci-pipeline.js +180 -0
- package/dist/build/ci-pipeline.js.map +1 -0
- package/dist/build/github-dist.d.ts +37 -0
- package/dist/build/github-dist.d.ts.map +1 -0
- package/dist/build/github-dist.js +117 -0
- package/dist/build/github-dist.js.map +1 -0
- package/dist/build/index.d.ts +11 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +11 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/install-migration.d.ts +28 -0
- package/dist/build/install-migration.d.ts.map +1 -0
- package/dist/build/install-migration.js +103 -0
- package/dist/build/install-migration.js.map +1 -0
- package/dist/build/npm-package.d.ts +54 -0
- package/dist/build/npm-package.d.ts.map +1 -0
- package/dist/build/npm-package.js +128 -0
- package/dist/build/npm-package.js.map +1 -0
- package/dist/build/release.d.ts +108 -0
- package/dist/build/release.d.ts.map +1 -0
- package/dist/build/release.js +295 -0
- package/dist/build/release.js.map +1 -0
- package/dist/build/versioning.d.ts +38 -0
- package/dist/build/versioning.d.ts.map +1 -0
- package/dist/build/versioning.js +113 -0
- package/dist/build/versioning.js.map +1 -0
- package/dist/casting/casting-engine.d.ts +60 -0
- package/dist/casting/casting-engine.d.ts.map +1 -0
- package/dist/casting/casting-engine.js +223 -0
- package/dist/casting/casting-engine.js.map +1 -0
- package/dist/casting/casting-history.d.ts +54 -0
- package/dist/casting/casting-history.d.ts.map +1 -0
- package/dist/casting/casting-history.js +63 -0
- package/dist/casting/casting-history.js.map +1 -0
- package/dist/casting/index.d.ts +46 -0
- package/dist/casting/index.d.ts.map +1 -0
- package/dist/casting/index.js +37 -0
- package/dist/casting/index.js.map +1 -0
- package/dist/client/event-bus.d.ts +29 -0
- package/dist/client/event-bus.d.ts.map +1 -0
- package/dist/client/event-bus.js +53 -0
- package/dist/client/event-bus.js.map +1 -0
- package/dist/client/index.d.ts +100 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +170 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/session-pool.d.ts +66 -0
- package/dist/client/session-pool.d.ts.map +1 -0
- package/dist/client/session-pool.js +145 -0
- package/dist/client/session-pool.js.map +1 -0
- package/dist/config/agent-doc.d.ts +43 -0
- package/dist/config/agent-doc.d.ts.map +1 -0
- package/dist/config/agent-doc.js +158 -0
- package/dist/config/agent-doc.js.map +1 -0
- package/dist/config/agent-source.d.ts +95 -0
- package/dist/config/agent-source.d.ts.map +1 -0
- package/dist/config/agent-source.js +274 -0
- package/dist/config/agent-source.js.map +1 -0
- package/dist/config/doc-sync.d.ts +66 -0
- package/dist/config/doc-sync.d.ts.map +1 -0
- package/dist/config/doc-sync.js +270 -0
- package/dist/config/doc-sync.js.map +1 -0
- package/dist/config/feature-audit.d.ts +49 -0
- package/dist/config/feature-audit.d.ts.map +1 -0
- package/dist/config/feature-audit.js +148 -0
- package/dist/config/feature-audit.js.map +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +15 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/init.d.ts +61 -0
- package/dist/config/init.d.ts.map +1 -0
- package/dist/config/init.js +369 -0
- package/dist/config/init.js.map +1 -0
- package/dist/config/legacy-fallback.d.ts +83 -0
- package/dist/config/legacy-fallback.d.ts.map +1 -0
- package/dist/config/legacy-fallback.js +212 -0
- package/dist/config/legacy-fallback.js.map +1 -0
- package/dist/config/markdown-migration.d.ts +157 -0
- package/dist/config/markdown-migration.d.ts.map +1 -0
- package/dist/config/markdown-migration.js +434 -0
- package/dist/config/markdown-migration.js.map +1 -0
- package/dist/config/migration.d.ts +123 -0
- package/dist/config/migration.d.ts.map +1 -0
- package/dist/config/migration.js +273 -0
- package/dist/config/migration.js.map +1 -0
- package/dist/config/migrations/index.d.ts +36 -0
- package/dist/config/migrations/index.d.ts.map +1 -0
- package/dist/config/migrations/index.js +216 -0
- package/dist/config/migrations/index.js.map +1 -0
- package/dist/config/models.d.ts +134 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +354 -0
- package/dist/config/models.js.map +1 -0
- package/dist/config/routing.d.ts +118 -0
- package/dist/config/routing.d.ts.map +1 -0
- package/dist/config/routing.js +247 -0
- package/dist/config/routing.js.map +1 -0
- package/dist/config/schema.d.ts +72 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +63 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/coordinator/coordinator.d.ts +82 -0
- package/dist/coordinator/coordinator.d.ts.map +1 -0
- package/dist/coordinator/coordinator.js +174 -0
- package/dist/coordinator/coordinator.js.map +1 -0
- package/dist/coordinator/direct-response.d.ts +83 -0
- package/dist/coordinator/direct-response.d.ts.map +1 -0
- package/dist/coordinator/direct-response.js +187 -0
- package/dist/coordinator/direct-response.js.map +1 -0
- package/dist/coordinator/fan-out.d.ts +83 -0
- package/dist/coordinator/fan-out.d.ts.map +1 -0
- package/dist/coordinator/fan-out.js +161 -0
- package/dist/coordinator/fan-out.js.map +1 -0
- package/dist/coordinator/index.d.ts +47 -0
- package/dist/coordinator/index.d.ts.map +1 -0
- package/dist/coordinator/index.js +54 -0
- package/dist/coordinator/index.js.map +1 -0
- package/dist/coordinator/response-tiers.d.ts +49 -0
- package/dist/coordinator/response-tiers.d.ts.map +1 -0
- package/dist/coordinator/response-tiers.js +149 -0
- package/dist/coordinator/response-tiers.js.map +1 -0
- package/dist/hooks/index.d.ts +103 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +279 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +24 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/marketplace/backend.d.ts +35 -0
- package/dist/marketplace/backend.d.ts.map +1 -0
- package/dist/marketplace/backend.js +99 -0
- package/dist/marketplace/backend.js.map +1 -0
- package/dist/marketplace/browser.d.ts +33 -0
- package/dist/marketplace/browser.d.ts.map +1 -0
- package/dist/marketplace/browser.js +97 -0
- package/dist/marketplace/browser.js.map +1 -0
- package/dist/marketplace/extension-adapter.d.ts +51 -0
- package/dist/marketplace/extension-adapter.d.ts.map +1 -0
- package/dist/marketplace/extension-adapter.js +81 -0
- package/dist/marketplace/extension-adapter.js.map +1 -0
- package/dist/marketplace/index.d.ts +51 -0
- package/dist/marketplace/index.d.ts.map +1 -0
- package/dist/marketplace/index.js +108 -0
- package/dist/marketplace/index.js.map +1 -0
- package/dist/marketplace/packaging.d.ts +25 -0
- package/dist/marketplace/packaging.d.ts.map +1 -0
- package/dist/marketplace/packaging.js +117 -0
- package/dist/marketplace/packaging.js.map +1 -0
- package/dist/marketplace/schema.d.ts +50 -0
- package/dist/marketplace/schema.d.ts.map +1 -0
- package/dist/marketplace/schema.js +120 -0
- package/dist/marketplace/schema.js.map +1 -0
- package/dist/marketplace/security.d.ts +26 -0
- package/dist/marketplace/security.d.ts.map +1 -0
- package/dist/marketplace/security.js +199 -0
- package/dist/marketplace/security.js.map +1 -0
- package/dist/parsers.d.ts +15 -0
- package/dist/parsers.d.ts.map +1 -0
- package/dist/parsers.js +15 -0
- package/dist/parsers.js.map +1 -0
- package/dist/ralph/index.d.ts +56 -0
- package/dist/ralph/index.d.ts.map +1 -0
- package/dist/ralph/index.js +61 -0
- package/dist/ralph/index.js.map +1 -0
- package/dist/resolution.d.ts +47 -0
- package/dist/resolution.d.ts.map +1 -0
- package/dist/resolution.js +106 -0
- package/dist/resolution.js.map +1 -0
- package/dist/runtime/benchmarks.d.ts +121 -0
- package/dist/runtime/benchmarks.d.ts.map +1 -0
- package/dist/runtime/benchmarks.js +251 -0
- package/dist/runtime/benchmarks.js.map +1 -0
- package/dist/runtime/config.d.ts +313 -0
- package/dist/runtime/config.d.ts.map +1 -0
- package/dist/runtime/config.js +466 -0
- package/dist/runtime/config.js.map +1 -0
- package/dist/runtime/cost-tracker.d.ts +73 -0
- package/dist/runtime/cost-tracker.d.ts.map +1 -0
- package/dist/runtime/cost-tracker.js +157 -0
- package/dist/runtime/cost-tracker.js.map +1 -0
- package/dist/runtime/event-bus.d.ts +190 -0
- package/dist/runtime/event-bus.d.ts.map +1 -0
- package/dist/runtime/event-bus.js +218 -0
- package/dist/runtime/event-bus.js.map +1 -0
- package/dist/runtime/health.d.ts +66 -0
- package/dist/runtime/health.d.ts.map +1 -0
- package/dist/runtime/health.js +111 -0
- package/dist/runtime/health.js.map +1 -0
- package/dist/runtime/i18n.d.ts +54 -0
- package/dist/runtime/i18n.d.ts.map +1 -0
- package/dist/runtime/i18n.js +126 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/offline.d.ts +64 -0
- package/dist/runtime/offline.d.ts.map +1 -0
- package/dist/runtime/offline.js +108 -0
- package/dist/runtime/offline.js.map +1 -0
- package/dist/runtime/streaming.d.ts +97 -0
- package/dist/runtime/streaming.d.ts.map +1 -0
- package/dist/runtime/streaming.js +156 -0
- package/dist/runtime/streaming.js.map +1 -0
- package/dist/runtime/telemetry.d.ts +82 -0
- package/dist/runtime/telemetry.d.ts.map +1 -0
- package/dist/runtime/telemetry.js +120 -0
- package/dist/runtime/telemetry.js.map +1 -0
- package/dist/sharing/agent-repo.d.ts +33 -0
- package/dist/sharing/agent-repo.d.ts.map +1 -0
- package/dist/sharing/agent-repo.js +79 -0
- package/dist/sharing/agent-repo.js.map +1 -0
- package/dist/sharing/cache.d.ts +36 -0
- package/dist/sharing/cache.d.ts.map +1 -0
- package/dist/sharing/cache.js +85 -0
- package/dist/sharing/cache.js.map +1 -0
- package/dist/sharing/conflicts.d.ts +32 -0
- package/dist/sharing/conflicts.d.ts.map +1 -0
- package/dist/sharing/conflicts.js +121 -0
- package/dist/sharing/conflicts.js.map +1 -0
- package/dist/sharing/export.d.ts +50 -0
- package/dist/sharing/export.d.ts.map +1 -0
- package/dist/sharing/export.js +156 -0
- package/dist/sharing/export.js.map +1 -0
- package/dist/sharing/history-split.d.ts +34 -0
- package/dist/sharing/history-split.d.ts.map +1 -0
- package/dist/sharing/history-split.js +101 -0
- package/dist/sharing/history-split.js.map +1 -0
- package/dist/sharing/import.d.ts +37 -0
- package/dist/sharing/import.d.ts.map +1 -0
- package/dist/sharing/import.js +138 -0
- package/dist/sharing/import.js.map +1 -0
- package/dist/sharing/index.d.ts +11 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +11 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/versioning.d.ts +32 -0
- package/dist/sharing/versioning.d.ts.map +1 -0
- package/dist/sharing/versioning.js +64 -0
- package/dist/sharing/versioning.js.map +1 -0
- package/dist/skills/index.d.ts +49 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +85 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/skill-loader.d.ts +56 -0
- package/dist/skills/skill-loader.d.ts.map +1 -0
- package/dist/skills/skill-loader.js +106 -0
- package/dist/skills/skill-loader.js.map +1 -0
- package/dist/skills/skill-source.d.ts +63 -0
- package/dist/skills/skill-source.d.ts.map +1 -0
- package/dist/skills/skill-source.js +199 -0
- package/dist/skills/skill-source.js.map +1 -0
- package/dist/tools/index.d.ts +87 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +419 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/normalize-eol.d.ts +6 -0
- package/dist/utils/normalize-eol.d.ts.map +1 -0
- package/dist/utils/normalize-eol.js +8 -0
- package/dist/utils/normalize-eol.js.map +1 -0
- package/package.json +115 -39
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ralph — Work Monitor (PRD 8)
|
|
3
|
+
*
|
|
4
|
+
* Persistent SDK session that monitors agent work in real time.
|
|
5
|
+
* Replaces ephemeral polling spawns with an event-driven observer
|
|
6
|
+
* that accumulates knowledge across monitoring cycles.
|
|
7
|
+
*
|
|
8
|
+
* Three monitoring layers:
|
|
9
|
+
* 1. In-session: Event subscriptions via EventBus
|
|
10
|
+
* 2. Watchdog: Periodic health checks on session pool
|
|
11
|
+
* 3. Cloud heartbeat: External health signal (future)
|
|
12
|
+
*/
|
|
13
|
+
import type { EventBus } from '../client/event-bus.js';
|
|
14
|
+
export interface MonitorConfig {
|
|
15
|
+
/** Team root directory */
|
|
16
|
+
teamRoot: string;
|
|
17
|
+
/** Health check interval (ms, default: 30000) */
|
|
18
|
+
healthCheckInterval?: number;
|
|
19
|
+
/** Stale session threshold (ms, default: 300000) */
|
|
20
|
+
staleSessionThreshold?: number;
|
|
21
|
+
/** Path to persist monitor state for crash recovery */
|
|
22
|
+
statePath?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface AgentWorkStatus {
|
|
25
|
+
agentName: string;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
status: 'working' | 'idle' | 'stale' | 'error';
|
|
28
|
+
lastActivity: Date;
|
|
29
|
+
currentTask?: string;
|
|
30
|
+
milestones: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface MonitorState {
|
|
33
|
+
/** Timestamp of last health check */
|
|
34
|
+
lastHealthCheck: Date | null;
|
|
35
|
+
/** Per-agent work status */
|
|
36
|
+
agents: Map<string, AgentWorkStatus>;
|
|
37
|
+
/** Accumulated observations across cycles */
|
|
38
|
+
observations: string[];
|
|
39
|
+
}
|
|
40
|
+
export declare class RalphMonitor {
|
|
41
|
+
private config;
|
|
42
|
+
private state;
|
|
43
|
+
private eventBus;
|
|
44
|
+
constructor(config: MonitorConfig);
|
|
45
|
+
/** Start monitoring — subscribe to EventBus and begin health checks */
|
|
46
|
+
start(eventBus: EventBus): Promise<void>;
|
|
47
|
+
/** Handle an incoming event from the EventBus */
|
|
48
|
+
private handleEvent;
|
|
49
|
+
/** Run a health check across all tracked agent sessions */
|
|
50
|
+
healthCheck(): Promise<AgentWorkStatus[]>;
|
|
51
|
+
/** Get current work status for all agents */
|
|
52
|
+
getStatus(): AgentWorkStatus[];
|
|
53
|
+
/** Stop monitoring and persist final state */
|
|
54
|
+
stop(): Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ralph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,wBAAwB,CAAC;AAInE,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IAEjB,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,oDAAoD;IACpD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,YAAY,EAAE,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B,4BAA4B;IAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrC,6CAA6C;IAC7C,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,MAAM,EAAE,aAAa;IAWjC,uEAAuE;IACjE,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,iDAAiD;IACjD,OAAO,CAAC,WAAW;IAMnB,2DAA2D;IACrD,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAQ/C,6CAA6C;IAC7C,SAAS,IAAI,eAAe,EAAE;IAI9B,8CAA8C;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ralph — Work Monitor (PRD 8)
|
|
3
|
+
*
|
|
4
|
+
* Persistent SDK session that monitors agent work in real time.
|
|
5
|
+
* Replaces ephemeral polling spawns with an event-driven observer
|
|
6
|
+
* that accumulates knowledge across monitoring cycles.
|
|
7
|
+
*
|
|
8
|
+
* Three monitoring layers:
|
|
9
|
+
* 1. In-session: Event subscriptions via EventBus
|
|
10
|
+
* 2. Watchdog: Periodic health checks on session pool
|
|
11
|
+
* 3. Cloud heartbeat: External health signal (future)
|
|
12
|
+
*/
|
|
13
|
+
// --- Ralph Monitor ---
|
|
14
|
+
export class RalphMonitor {
|
|
15
|
+
config;
|
|
16
|
+
state;
|
|
17
|
+
eventBus = null;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.state = {
|
|
21
|
+
lastHealthCheck: null,
|
|
22
|
+
agents: new Map(),
|
|
23
|
+
observations: [],
|
|
24
|
+
};
|
|
25
|
+
// TODO: PRD 8 — Load persisted state from statePath if exists
|
|
26
|
+
// TODO: PRD 8 — Initialize as persistent SDK session via resumeSession('squad-ralph')
|
|
27
|
+
}
|
|
28
|
+
/** Start monitoring — subscribe to EventBus and begin health checks */
|
|
29
|
+
async start(eventBus) {
|
|
30
|
+
this.eventBus = eventBus;
|
|
31
|
+
// TODO: PRD 8 — Subscribe to session lifecycle events
|
|
32
|
+
// TODO: PRD 8 — Subscribe to agent.milestone events
|
|
33
|
+
// TODO: PRD 8 — Start periodic health check timer
|
|
34
|
+
// TODO: PRD 8 — Register onSessionStart hook to track new agents
|
|
35
|
+
}
|
|
36
|
+
/** Handle an incoming event from the EventBus */
|
|
37
|
+
handleEvent(event) {
|
|
38
|
+
// TODO: PRD 8 — Update agent work status based on event type
|
|
39
|
+
// TODO: PRD 8 — Extract [MILESTONE] markers from agent output
|
|
40
|
+
// TODO: PRD 8 — Detect stale sessions and flag for coordinator
|
|
41
|
+
}
|
|
42
|
+
/** Run a health check across all tracked agent sessions */
|
|
43
|
+
async healthCheck() {
|
|
44
|
+
// TODO: PRD 8 — Check each session's last activity timestamp
|
|
45
|
+
// TODO: PRD 8 — Mark stale sessions (no activity > threshold)
|
|
46
|
+
// TODO: PRD 8 — Persist state to statePath for crash recovery
|
|
47
|
+
this.state.lastHealthCheck = new Date();
|
|
48
|
+
return Array.from(this.state.agents.values());
|
|
49
|
+
}
|
|
50
|
+
/** Get current work status for all agents */
|
|
51
|
+
getStatus() {
|
|
52
|
+
return Array.from(this.state.agents.values());
|
|
53
|
+
}
|
|
54
|
+
/** Stop monitoring and persist final state */
|
|
55
|
+
async stop() {
|
|
56
|
+
// TODO: PRD 8 — Unsubscribe from EventBus
|
|
57
|
+
// TODO: PRD 8 — Stop health check timer
|
|
58
|
+
// TODO: PRD 8 — Persist final state to statePath
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ralph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAsCH,wBAAwB;AAExB,MAAM,OAAO,YAAY;IACf,MAAM,CAAgB;IACtB,KAAK,CAAe;IACpB,QAAQ,GAAoB,IAAI,CAAC;IAEzC,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG;YACX,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,IAAI,GAAG,EAAE;YACjB,YAAY,EAAE,EAAE;SACjB,CAAC;QACF,8DAA8D;QAC9D,sFAAsF;IACxF,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,KAAK,CAAC,QAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,sDAAsD;QACtD,oDAAoD;QACpD,kDAAkD;QAClD,iEAAiE;IACnE,CAAC;IAED,iDAAiD;IACzC,WAAW,CAAC,KAAiB;QACnC,6DAA6D;QAC7D,8DAA8D;QAC9D,+DAA+D;IACjE,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,WAAW;QACf,6DAA6D;QAC7D,8DAA8D;QAC9D,8DAA8D;QAC9D,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,IAAI;QACR,0CAA0C;QAC1C,wCAAwC;QACxC,iDAAiD;IACnD,CAAC;CACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Squad directory resolution — walk-up and global path algorithms.
|
|
3
|
+
*
|
|
4
|
+
* resolveSquad() — find .squad/ by walking up from startDir to .git boundary
|
|
5
|
+
* resolveGlobalSquadPath() — platform-specific global config directory
|
|
6
|
+
*
|
|
7
|
+
* @module resolution
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Walk up the directory tree from `startDir` looking for a `.squad/` directory.
|
|
11
|
+
*
|
|
12
|
+
* Stops at the repository root (the directory containing `.git`).
|
|
13
|
+
* Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
|
|
14
|
+
*
|
|
15
|
+
* Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
|
|
16
|
+
*
|
|
17
|
+
* @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
|
|
18
|
+
* @returns Absolute path to `.squad/` or `null`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveSquad(startDir?: string): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Return the platform-specific global Squad configuration directory.
|
|
23
|
+
*
|
|
24
|
+
* | Platform | Path |
|
|
25
|
+
* |----------|--------------------------------------------|
|
|
26
|
+
* | Windows | `%APPDATA%/squad/` |
|
|
27
|
+
* | macOS | `~/Library/Application Support/squad/` |
|
|
28
|
+
* | Linux | `$XDG_CONFIG_HOME/squad/` (default `~/.config/squad/`) |
|
|
29
|
+
*
|
|
30
|
+
* The directory is created (recursively) if it does not already exist.
|
|
31
|
+
*
|
|
32
|
+
* @returns Absolute path to the global squad config directory.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveGlobalSquadPath(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Validate that a file path is within `.squad/` or the system temp directory.
|
|
37
|
+
*
|
|
38
|
+
* Use this guard before writing any scratch/temp/state files to ensure Squad
|
|
39
|
+
* never clutters the repo root or arbitrary filesystem locations.
|
|
40
|
+
*
|
|
41
|
+
* @param filePath - Absolute path to validate.
|
|
42
|
+
* @param squadRoot - Absolute path to the `.squad/` directory (e.g. from `resolveSquad()`).
|
|
43
|
+
* @returns The resolved absolute `filePath` if it is safe.
|
|
44
|
+
* @throws If `filePath` is outside `.squad/` and not in the system temp directory.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ensureSquadPath(filePath: string, squadRoot: string): string;
|
|
47
|
+
//# sourceMappingURL=resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2B7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmB3E"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Squad directory resolution — walk-up and global path algorithms.
|
|
3
|
+
*
|
|
4
|
+
* resolveSquad() — find .squad/ by walking up from startDir to .git boundary
|
|
5
|
+
* resolveGlobalSquadPath() — platform-specific global config directory
|
|
6
|
+
*
|
|
7
|
+
* @module resolution
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import os from 'node:os';
|
|
12
|
+
/**
|
|
13
|
+
* Walk up the directory tree from `startDir` looking for a `.squad/` directory.
|
|
14
|
+
*
|
|
15
|
+
* Stops at the repository root (the directory containing `.git`).
|
|
16
|
+
* Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
|
|
17
|
+
*
|
|
18
|
+
* Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
|
|
19
|
+
*
|
|
20
|
+
* @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
|
|
21
|
+
* @returns Absolute path to `.squad/` or `null`.
|
|
22
|
+
*/
|
|
23
|
+
export function resolveSquad(startDir) {
|
|
24
|
+
let current = path.resolve(startDir ?? process.cwd());
|
|
25
|
+
// eslint-disable-next-line no-constant-condition
|
|
26
|
+
while (true) {
|
|
27
|
+
const candidate = path.join(current, '.squad');
|
|
28
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
|
|
29
|
+
return candidate;
|
|
30
|
+
}
|
|
31
|
+
// Stop if we hit a .git boundary (directory or worktree file)
|
|
32
|
+
const gitMarker = path.join(current, '.git');
|
|
33
|
+
if (fs.existsSync(gitMarker)) {
|
|
34
|
+
// We've reached the repo root — don't walk higher
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const parent = path.dirname(current);
|
|
38
|
+
// Filesystem root reached — nowhere left to walk
|
|
39
|
+
if (parent === current) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
current = parent;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Return the platform-specific global Squad configuration directory.
|
|
47
|
+
*
|
|
48
|
+
* | Platform | Path |
|
|
49
|
+
* |----------|--------------------------------------------|
|
|
50
|
+
* | Windows | `%APPDATA%/squad/` |
|
|
51
|
+
* | macOS | `~/Library/Application Support/squad/` |
|
|
52
|
+
* | Linux | `$XDG_CONFIG_HOME/squad/` (default `~/.config/squad/`) |
|
|
53
|
+
*
|
|
54
|
+
* The directory is created (recursively) if it does not already exist.
|
|
55
|
+
*
|
|
56
|
+
* @returns Absolute path to the global squad config directory.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveGlobalSquadPath() {
|
|
59
|
+
const platform = process.platform;
|
|
60
|
+
let base;
|
|
61
|
+
if (platform === 'win32') {
|
|
62
|
+
// %APPDATA% is always set on Windows; fall back to %LOCALAPPDATA%, then homedir
|
|
63
|
+
base = process.env['APPDATA']
|
|
64
|
+
?? process.env['LOCALAPPDATA']
|
|
65
|
+
?? path.join(os.homedir(), 'AppData', 'Roaming');
|
|
66
|
+
}
|
|
67
|
+
else if (platform === 'darwin') {
|
|
68
|
+
base = path.join(os.homedir(), 'Library', 'Application Support');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Linux / other POSIX — respect XDG_CONFIG_HOME
|
|
72
|
+
base = process.env['XDG_CONFIG_HOME'] ?? path.join(os.homedir(), '.config');
|
|
73
|
+
}
|
|
74
|
+
const globalDir = path.join(base, 'squad');
|
|
75
|
+
if (!fs.existsSync(globalDir)) {
|
|
76
|
+
fs.mkdirSync(globalDir, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
return globalDir;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validate that a file path is within `.squad/` or the system temp directory.
|
|
82
|
+
*
|
|
83
|
+
* Use this guard before writing any scratch/temp/state files to ensure Squad
|
|
84
|
+
* never clutters the repo root or arbitrary filesystem locations.
|
|
85
|
+
*
|
|
86
|
+
* @param filePath - Absolute path to validate.
|
|
87
|
+
* @param squadRoot - Absolute path to the `.squad/` directory (e.g. from `resolveSquad()`).
|
|
88
|
+
* @returns The resolved absolute `filePath` if it is safe.
|
|
89
|
+
* @throws If `filePath` is outside `.squad/` and not in the system temp directory.
|
|
90
|
+
*/
|
|
91
|
+
export function ensureSquadPath(filePath, squadRoot) {
|
|
92
|
+
const resolved = path.resolve(filePath);
|
|
93
|
+
const resolvedSquad = path.resolve(squadRoot);
|
|
94
|
+
const resolvedTmp = path.resolve(os.tmpdir());
|
|
95
|
+
// Allow paths inside the .squad/ directory
|
|
96
|
+
if (resolved === resolvedSquad || resolved.startsWith(resolvedSquad + path.sep)) {
|
|
97
|
+
return resolved;
|
|
98
|
+
}
|
|
99
|
+
// Allow paths inside the system temp directory
|
|
100
|
+
if (resolved === resolvedTmp || resolved.startsWith(resolvedTmp + path.sep)) {
|
|
101
|
+
return resolved;
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Path "${resolved}" is outside the .squad/ directory ("${resolvedSquad}"). ` +
|
|
104
|
+
'All squad scratch/temp/state files must be written inside .squad/ or the system temp directory.');
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution.js","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M6-11: Performance profiling & benchmarks
|
|
3
|
+
* Provides benchmark utilities to measure Squad operation timings.
|
|
4
|
+
*
|
|
5
|
+
* @module runtime/benchmarks
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Result of a single benchmark run.
|
|
9
|
+
*/
|
|
10
|
+
export interface BenchmarkResult {
|
|
11
|
+
/** Benchmark name */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Number of iterations run */
|
|
14
|
+
iterations: number;
|
|
15
|
+
/** Average time in ms */
|
|
16
|
+
avg: number;
|
|
17
|
+
/** Minimum time in ms */
|
|
18
|
+
min: number;
|
|
19
|
+
/** Maximum time in ms */
|
|
20
|
+
max: number;
|
|
21
|
+
/** 95th percentile time in ms */
|
|
22
|
+
p95: number;
|
|
23
|
+
/** 99th percentile time in ms */
|
|
24
|
+
p99: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Timing summary returned by individual benchmark functions.
|
|
28
|
+
*/
|
|
29
|
+
export interface TimingResult {
|
|
30
|
+
avg: number;
|
|
31
|
+
min: number;
|
|
32
|
+
max: number;
|
|
33
|
+
p95: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Full benchmark report returned by `runAll`.
|
|
37
|
+
*/
|
|
38
|
+
export interface BenchmarkReport {
|
|
39
|
+
results: BenchmarkResult[];
|
|
40
|
+
totalTime: number;
|
|
41
|
+
timestamp: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* An async operation that can be benchmarked.
|
|
45
|
+
*/
|
|
46
|
+
export type BenchmarkFn = () => Promise<void> | void;
|
|
47
|
+
/**
|
|
48
|
+
* Calculate percentile from a sorted array of numbers.
|
|
49
|
+
*/
|
|
50
|
+
export declare function percentile(sorted: number[], p: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* Measure the execution time of a function over N iterations and return stats.
|
|
53
|
+
*/
|
|
54
|
+
export declare function measureIterations(fn: BenchmarkFn, iterations: number): Promise<{
|
|
55
|
+
avg: number;
|
|
56
|
+
min: number;
|
|
57
|
+
max: number;
|
|
58
|
+
p95: number;
|
|
59
|
+
p99: number;
|
|
60
|
+
timings: number[];
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Runs performance benchmarks on Squad operations.
|
|
64
|
+
*
|
|
65
|
+
* Usage:
|
|
66
|
+
* ```ts
|
|
67
|
+
* const suite = new BenchmarkSuite();
|
|
68
|
+
* const report = await suite.runAll(100);
|
|
69
|
+
* console.log(formatBenchmarkReport(report.results));
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare class BenchmarkSuite {
|
|
73
|
+
private benchmarks;
|
|
74
|
+
constructor();
|
|
75
|
+
/**
|
|
76
|
+
* Register a custom benchmark.
|
|
77
|
+
*/
|
|
78
|
+
register(name: string, fn: BenchmarkFn): void;
|
|
79
|
+
/**
|
|
80
|
+
* Unregister a benchmark by name.
|
|
81
|
+
*/
|
|
82
|
+
unregister(name: string): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* List all registered benchmark names.
|
|
85
|
+
*/
|
|
86
|
+
list(): string[];
|
|
87
|
+
/**
|
|
88
|
+
* Benchmark config loading.
|
|
89
|
+
*/
|
|
90
|
+
benchmarkConfigLoad(iterations: number): Promise<TimingResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Benchmark charter compilation.
|
|
93
|
+
*/
|
|
94
|
+
benchmarkCharterCompile(iterations: number): Promise<TimingResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Benchmark routing operations.
|
|
97
|
+
*/
|
|
98
|
+
benchmarkRouting(iterations: number): Promise<TimingResult>;
|
|
99
|
+
/**
|
|
100
|
+
* Benchmark model selection.
|
|
101
|
+
*/
|
|
102
|
+
benchmarkModelSelection(iterations: number): Promise<TimingResult>;
|
|
103
|
+
/**
|
|
104
|
+
* Benchmark export/import round-trip.
|
|
105
|
+
*/
|
|
106
|
+
benchmarkExportImport(iterations: number): Promise<TimingResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Run all registered benchmarks and produce a full report.
|
|
109
|
+
*/
|
|
110
|
+
runAll(iterations?: number): Promise<BenchmarkReport>;
|
|
111
|
+
private configLoadOp;
|
|
112
|
+
private charterCompileOp;
|
|
113
|
+
private routingOp;
|
|
114
|
+
private modelSelectionOp;
|
|
115
|
+
private exportImportOp;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Format benchmark results as a terminal-formatted table.
|
|
119
|
+
*/
|
|
120
|
+
export declare function formatBenchmarkReport(results: BenchmarkResult[]): string;
|
|
121
|
+
//# sourceMappingURL=benchmarks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmarks.d.ts","sourceRoot":"","sources":["../../src/runtime/benchmarks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAMrD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,WAAW,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyBjG;AAMD;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAuC;;IAWzD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAI7C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;IAIhB;;OAEG;IACG,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKpE;;OAEG;IACG,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKxE;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKjE;;OAEG;IACG,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKxE;;OAEG;IACG,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKtE;;OAEG;IACG,MAAM,CAAC,UAAU,GAAE,MAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IA4BhE,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,cAAc;CAYvB;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAiCxE"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M6-11: Performance profiling & benchmarks
|
|
3
|
+
* Provides benchmark utilities to measure Squad operation timings.
|
|
4
|
+
*
|
|
5
|
+
* @module runtime/benchmarks
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Helpers
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Calculate percentile from a sorted array of numbers.
|
|
12
|
+
*/
|
|
13
|
+
export function percentile(sorted, p) {
|
|
14
|
+
if (sorted.length === 0)
|
|
15
|
+
return 0;
|
|
16
|
+
const idx = Math.ceil((p / 100) * sorted.length) - 1;
|
|
17
|
+
return sorted[Math.max(0, idx)];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Measure the execution time of a function over N iterations and return stats.
|
|
21
|
+
*/
|
|
22
|
+
export async function measureIterations(fn, iterations) {
|
|
23
|
+
if (iterations < 1) {
|
|
24
|
+
throw new Error('Iterations must be at least 1');
|
|
25
|
+
}
|
|
26
|
+
const timings = [];
|
|
27
|
+
for (let i = 0; i < iterations; i++) {
|
|
28
|
+
const start = performance.now();
|
|
29
|
+
await fn();
|
|
30
|
+
const end = performance.now();
|
|
31
|
+
timings.push(end - start);
|
|
32
|
+
}
|
|
33
|
+
timings.sort((a, b) => a - b);
|
|
34
|
+
const sum = timings.reduce((a, b) => a + b, 0);
|
|
35
|
+
return {
|
|
36
|
+
avg: sum / timings.length,
|
|
37
|
+
min: timings[0],
|
|
38
|
+
max: timings[timings.length - 1],
|
|
39
|
+
p95: percentile(timings, 95),
|
|
40
|
+
p99: percentile(timings, 99),
|
|
41
|
+
timings,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// BenchmarkSuite
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* Runs performance benchmarks on Squad operations.
|
|
49
|
+
*
|
|
50
|
+
* Usage:
|
|
51
|
+
* ```ts
|
|
52
|
+
* const suite = new BenchmarkSuite();
|
|
53
|
+
* const report = await suite.runAll(100);
|
|
54
|
+
* console.log(formatBenchmarkReport(report.results));
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export class BenchmarkSuite {
|
|
58
|
+
benchmarks = new Map();
|
|
59
|
+
constructor() {
|
|
60
|
+
// Register built-in benchmarks
|
|
61
|
+
this.benchmarks.set('configLoad', () => this.configLoadOp());
|
|
62
|
+
this.benchmarks.set('charterCompile', () => this.charterCompileOp());
|
|
63
|
+
this.benchmarks.set('routing', () => this.routingOp());
|
|
64
|
+
this.benchmarks.set('modelSelection', () => this.modelSelectionOp());
|
|
65
|
+
this.benchmarks.set('exportImport', () => this.exportImportOp());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Register a custom benchmark.
|
|
69
|
+
*/
|
|
70
|
+
register(name, fn) {
|
|
71
|
+
this.benchmarks.set(name, fn);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Unregister a benchmark by name.
|
|
75
|
+
*/
|
|
76
|
+
unregister(name) {
|
|
77
|
+
return this.benchmarks.delete(name);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* List all registered benchmark names.
|
|
81
|
+
*/
|
|
82
|
+
list() {
|
|
83
|
+
return [...this.benchmarks.keys()];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Benchmark config loading.
|
|
87
|
+
*/
|
|
88
|
+
async benchmarkConfigLoad(iterations) {
|
|
89
|
+
const stats = await measureIterations(() => this.configLoadOp(), iterations);
|
|
90
|
+
return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Benchmark charter compilation.
|
|
94
|
+
*/
|
|
95
|
+
async benchmarkCharterCompile(iterations) {
|
|
96
|
+
const stats = await measureIterations(() => this.charterCompileOp(), iterations);
|
|
97
|
+
return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Benchmark routing operations.
|
|
101
|
+
*/
|
|
102
|
+
async benchmarkRouting(iterations) {
|
|
103
|
+
const stats = await measureIterations(() => this.routingOp(), iterations);
|
|
104
|
+
return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Benchmark model selection.
|
|
108
|
+
*/
|
|
109
|
+
async benchmarkModelSelection(iterations) {
|
|
110
|
+
const stats = await measureIterations(() => this.modelSelectionOp(), iterations);
|
|
111
|
+
return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Benchmark export/import round-trip.
|
|
115
|
+
*/
|
|
116
|
+
async benchmarkExportImport(iterations) {
|
|
117
|
+
const stats = await measureIterations(() => this.exportImportOp(), iterations);
|
|
118
|
+
return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Run all registered benchmarks and produce a full report.
|
|
122
|
+
*/
|
|
123
|
+
async runAll(iterations = 100) {
|
|
124
|
+
const totalStart = performance.now();
|
|
125
|
+
const results = [];
|
|
126
|
+
for (const [name, fn] of this.benchmarks) {
|
|
127
|
+
const stats = await measureIterations(fn, iterations);
|
|
128
|
+
results.push({
|
|
129
|
+
name,
|
|
130
|
+
iterations,
|
|
131
|
+
avg: stats.avg,
|
|
132
|
+
min: stats.min,
|
|
133
|
+
max: stats.max,
|
|
134
|
+
p95: stats.p95,
|
|
135
|
+
p99: stats.p99,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const totalTime = performance.now() - totalStart;
|
|
139
|
+
return {
|
|
140
|
+
results,
|
|
141
|
+
totalTime,
|
|
142
|
+
timestamp: new Date().toISOString(),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// -- Internal operations simulating real Squad work --
|
|
146
|
+
configLoadOp() {
|
|
147
|
+
// Simulate config parsing: build and validate a config-like object
|
|
148
|
+
const config = {
|
|
149
|
+
version: '1.0.0',
|
|
150
|
+
models: { defaultModel: 'claude-sonnet-4.5', defaultTier: 'standard', fallbackChains: { premium: [], standard: [], fast: [] } },
|
|
151
|
+
routing: { rules: [{ workType: 'feature-dev', agents: ['@coordinator'] }] },
|
|
152
|
+
};
|
|
153
|
+
JSON.parse(JSON.stringify(config));
|
|
154
|
+
}
|
|
155
|
+
charterCompileOp() {
|
|
156
|
+
// Simulate agent charter compilation from markdown
|
|
157
|
+
const charter = `# Agent Charter\n\n## Role\nCore developer\n\n## Skills\n- TypeScript\n- Testing\n\n## Rules\n1. Follow conventions\n2. Write tests`;
|
|
158
|
+
const lines = charter.split('\n');
|
|
159
|
+
const sections = {};
|
|
160
|
+
let current = '';
|
|
161
|
+
for (const line of lines) {
|
|
162
|
+
if (line.startsWith('## ')) {
|
|
163
|
+
current = line.slice(3).trim().toLowerCase();
|
|
164
|
+
sections[current] = [];
|
|
165
|
+
}
|
|
166
|
+
else if (current) {
|
|
167
|
+
sections[current].push(line);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
JSON.stringify(sections);
|
|
171
|
+
}
|
|
172
|
+
routingOp() {
|
|
173
|
+
// Simulate routing rule evaluation
|
|
174
|
+
const rules = [
|
|
175
|
+
{ workType: 'feature-dev', agents: ['fenster'], patterns: [/feature/i, /feat/i] },
|
|
176
|
+
{ workType: 'bug-fix', agents: ['kujan'], patterns: [/bug/i, /fix/i] },
|
|
177
|
+
{ workType: 'testing', agents: ['verbal'], patterns: [/test/i, /spec/i] },
|
|
178
|
+
{ workType: 'documentation', agents: ['mcmanus'], patterns: [/doc/i, /readme/i] },
|
|
179
|
+
];
|
|
180
|
+
const input = 'Implement a new feature for the routing module';
|
|
181
|
+
for (const rule of rules) {
|
|
182
|
+
for (const pattern of rule.patterns) {
|
|
183
|
+
if (pattern.test(input))
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
modelSelectionOp() {
|
|
189
|
+
// Simulate model selection logic
|
|
190
|
+
const tiers = {
|
|
191
|
+
premium: ['claude-opus-4.6', 'gpt-5.2'],
|
|
192
|
+
standard: ['claude-sonnet-4.5', 'gpt-5.1-codex'],
|
|
193
|
+
fast: ['claude-haiku-4.5', 'gpt-5-mini'],
|
|
194
|
+
};
|
|
195
|
+
const role = 'developer';
|
|
196
|
+
const complexity = 7;
|
|
197
|
+
const tier = complexity > 8 ? 'premium' : complexity > 4 ? 'standard' : 'fast';
|
|
198
|
+
const models = tiers[tier];
|
|
199
|
+
const _selected = models[0];
|
|
200
|
+
void _selected;
|
|
201
|
+
void role;
|
|
202
|
+
}
|
|
203
|
+
exportImportOp() {
|
|
204
|
+
// Simulate export → serialize → deserialize → import round-trip
|
|
205
|
+
const bundle = {
|
|
206
|
+
config: { version: '1.0.0', models: {}, routing: { rules: [] } },
|
|
207
|
+
agents: [{ name: 'fenster', role: 'developer', content: '# Fenster' }],
|
|
208
|
+
skills: ['typescript', 'testing'],
|
|
209
|
+
routingRules: [{ pattern: 'feature/*', agent: 'fenster' }],
|
|
210
|
+
metadata: { version: '1.0.0', timestamp: new Date().toISOString(), source: 'test' },
|
|
211
|
+
};
|
|
212
|
+
const serialized = JSON.stringify(bundle);
|
|
213
|
+
JSON.parse(serialized);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// Report Formatting
|
|
218
|
+
// ============================================================================
|
|
219
|
+
/**
|
|
220
|
+
* Format benchmark results as a terminal-formatted table.
|
|
221
|
+
*/
|
|
222
|
+
export function formatBenchmarkReport(results) {
|
|
223
|
+
if (results.length === 0) {
|
|
224
|
+
return 'No benchmark results to display.';
|
|
225
|
+
}
|
|
226
|
+
const COL_NAME = 24;
|
|
227
|
+
const COL_NUM = 12;
|
|
228
|
+
const header = [
|
|
229
|
+
'Name'.padEnd(COL_NAME),
|
|
230
|
+
'Iter'.padStart(COL_NUM),
|
|
231
|
+
'Avg (ms)'.padStart(COL_NUM),
|
|
232
|
+
'Min (ms)'.padStart(COL_NUM),
|
|
233
|
+
'Max (ms)'.padStart(COL_NUM),
|
|
234
|
+
'P95 (ms)'.padStart(COL_NUM),
|
|
235
|
+
'P99 (ms)'.padStart(COL_NUM),
|
|
236
|
+
].join(' ');
|
|
237
|
+
const separator = '─'.repeat(header.length);
|
|
238
|
+
const rows = results.map((r) => {
|
|
239
|
+
return [
|
|
240
|
+
r.name.padEnd(COL_NAME),
|
|
241
|
+
String(r.iterations).padStart(COL_NUM),
|
|
242
|
+
r.avg.toFixed(3).padStart(COL_NUM),
|
|
243
|
+
r.min.toFixed(3).padStart(COL_NUM),
|
|
244
|
+
r.max.toFixed(3).padStart(COL_NUM),
|
|
245
|
+
r.p95.toFixed(3).padStart(COL_NUM),
|
|
246
|
+
r.p99.toFixed(3).padStart(COL_NUM),
|
|
247
|
+
].join(' ');
|
|
248
|
+
});
|
|
249
|
+
return [separator, header, separator, ...rows, separator].join('\n');
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=benchmarks.js.map
|