feat: Add intelligent auto-router and enhanced integrations

- Add intelligent-router.sh hook for automatic agent routing
- Add AUTO-TRIGGER-SUMMARY.md documentation
- Add FINAL-INTEGRATION-SUMMARY.md documentation
- Complete Prometheus integration (6 commands + 4 tools)
- Complete Dexto integration (12 commands + 5 tools)
- Enhanced Ralph with access to all agents
- Fix /clawd command (removed disable-model-invocation)
- Update hooks.json to v5 with intelligent routing
- 291 total skills now available
- All 21 commands with automatic routing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
admin
2026-01-28 00:27:56 +04:00
Unverified
parent 3b128ba3bd
commit b52318eeae
1724 changed files with 351216 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
# @dexto/analytics
## 1.5.6
### Patch Changes
- 042f4f0: ### CLI Improvements
- Add `/export` command to export conversations as Markdown or JSON
- Add `Ctrl+T` toggle for task list visibility during processing
- Improve task list UI with collapsible view near the processing message
- Fix race condition causing duplicate rendering (mainly visible with explore tool)
- Don't truncate `pattern` and `question` args in tool output display
### Bug Fixes
- Fix build script to preserve `.dexto` storage (conversations, logs) during clean builds
- Fix `@dexto/tools-todo` versioning - add to fixed version group in changeset config
### Configuration Changes
- Remove approval timeout defaults - now waits indefinitely (better UX for CLI)
- Add package versioning guidelines to AGENTS.md
- Updated dependencies [042f4f0]
- @dexto/agent-management@1.5.6
- @dexto/core@1.5.6
## 1.5.5
### Patch Changes
- Updated dependencies [63fa083]
- Updated dependencies [6df3ca9]
- @dexto/core@1.5.5
- @dexto/agent-management@1.5.5
## 1.5.4
### Patch Changes
- 499b890: Fix model override persistence after compaction and improve context token tracking
**Bug Fixes:**
- Fix model override resetting to config model after compaction (now respects session overrides)
**Context Tracking Improvements:**
- New algorithm uses actual `input_tokens` and `output_tokens` from LLM responses as source of truth
- Self-correcting estimates: inaccuracies auto-correct when next LLM response arrives
- Handles pruning automatically (next response's input_tokens reflects pruned state)
- `/context` and compaction decisions now share common calculation logic
- Removed `outputBuffer` concept in favor of single configurable threshold
- Default compaction threshold lowered to 90%
**New `/context` Command:**
- Interactive overlay with stacked token bar visualization
- Breakdown by component: system prompt, tools, messages, free space, auto-compact buffer
- Expandable per-tool token details
- Shows pruned tool count and compaction history
**Observability:**
- Comparison logging between estimated vs actual tokens for calibration
- `dexto_llm_tokens_consumed` metric now includes estimated input tokens and accuracy metrics
- Updated dependencies [0016cd3]
- Updated dependencies [499b890]
- Updated dependencies [aa2c9a0]
- @dexto/core@1.5.4
- @dexto/agent-management@1.5.4
## 1.5.3
### Patch Changes
- Updated dependencies [4f00295]
- Updated dependencies [69c944c]
- @dexto/agent-management@1.5.3
- @dexto/core@1.5.3
## 1.5.2
### Patch Changes
- Updated dependencies [91acb03]
- Updated dependencies [8a85ea4]
- Updated dependencies [527f3f9]
- @dexto/agent-management@1.5.2
- @dexto/core@1.5.2
## 1.5.1
### Patch Changes
- Updated dependencies [a25d3ee]
- Updated dependencies [bfcc7b1]
- Updated dependencies [4aabdb7]
- @dexto/agent-management@1.5.1
- @dexto/core@1.5.1
## 1.5.0
### Minor Changes
- e7722e5: Minor version bump for new release with bundler, custom tool pkgs, etc.
### Patch Changes
- abfe5ce: Update and standardize analytics for CLI and web UI
- Updated dependencies [ee12727]
- Updated dependencies [1e7e974]
- Updated dependencies [4c05310]
- Updated dependencies [5fa79fa]
- Updated dependencies [ef40e60]
- Updated dependencies [e714418]
- Updated dependencies [e7722e5]
- Updated dependencies [7d5ab19]
- Updated dependencies [436a900]
- @dexto/agent-management@1.5.0
- @dexto/core@1.5.0
## 1.4.0
### Patch Changes
- Updated dependencies [bd5c097]
- Updated dependencies [7a64414]
- Updated dependencies [3cdce89]
- Updated dependencies [d640e40]
- Updated dependencies [6f5627d]
- Updated dependencies [6e6a3e7]
- Updated dependencies [f73a519]
- Updated dependencies [c54760f]
- Updated dependencies [ab47df8]
- Updated dependencies [3b4b919]
- @dexto/core@1.4.0
- @dexto/agent-management@1.4.0
## 1.3.0
### Patch Changes
- Updated dependencies [e2f770b]
- Updated dependencies [f843b62]
- Updated dependencies [eb266af]
- @dexto/core@1.3.0
- @dexto/agent-management@1.3.0
## 1.2.6
### Patch Changes
- Updated dependencies [7feb030]
- @dexto/core@1.2.6
- @dexto/agent-management@1.2.6
## 1.2.5
### Patch Changes
- 5e27806: Add changeset for updated agentCard with protocol version 0.3.0
- a35a256: Migrate from WebSocket to Server-Sent Events (SSE) for real-time streaming
- Replace WebSocket with SSE for message streaming via new `/api/message-stream` endpoint
- Refactor approval system from event-based providers to simpler handler pattern
- Add new APIs for session approval
- Move session title generation to a separate API
- Add `ApprovalCoordinator` for multi-client SSE routing with sessionId mapping
- Add stream and generate methods to DextoAgent and integ tests for itq=
- a154ae0: UI refactor with TanStack Query, new agent management package, and Hono as default server
**Server:**
- Make Hono the default API server (use `DEXTO_USE_EXPRESS=true` env var to use Express)
- Fix agentId propagation to Hono server for correct agent name display
- Fix circular reference crashes in error logging by using structured logger context
**WebUI:**
- Integrate TanStack Query for server state management with automatic caching and invalidation
- Add centralized query key factory and API client with structured error handling
- Replace manual data fetching with TanStack Query hooks across all components
- Add Zustand for client-side persistent state (recent agents in localStorage)
- Add keyboard shortcuts support with react-hotkeys-hook
- Add optimistic updates for session management via WebSocket events
- Fix Dialog auto-close bug in CreateMemoryModal
- Add defensive null handling in MemoryPanel
- Standardize Prettier formatting (single quotes, 4-space indentation)
**Agent Management:**
- Add `@dexto/agent-management` package for centralized agent configuration management
- Extract agent registry, preferences, and path utilities into dedicated package
**Internal:**
- Improve build orchestration and fix dependency imports
- Add `@dexto/agent-management` to global CLI installation
- ac649fd: Fix error handling and UI bugs, add gpt-5.1, gemini-3
- Updated dependencies [c1e814f]
- Updated dependencies [f9bca72]
- Updated dependencies [c0a10cd]
- Updated dependencies [81598b5]
- Updated dependencies [4c90ffe]
- Updated dependencies [1a20506]
- Updated dependencies [8f373cc]
- Updated dependencies [f28ad7e]
- Updated dependencies [4dd4998]
- Updated dependencies [5e27806]
- Updated dependencies [a35a256]
- Updated dependencies [0fa6ef5]
- Updated dependencies [e2fb5f8]
- Updated dependencies [a154ae0]
- Updated dependencies [ac649fd]
- @dexto/agent-management@1.2.5
- @dexto/core@1.2.5
## 1.2.4
### Patch Changes
- cd706e7: bump up version after fixing node-machine-id
- Updated dependencies [cd706e7]
- @dexto/core@1.2.4
## 1.2.3
### Patch Changes
- 5d6ae73: Bump up version to fix bugs
- Updated dependencies [5d6ae73]
- @dexto/core@1.2.3
## 1.2.2
### Patch Changes
- 8b96b63: Add posthog analytics package and add to web ui
- @dexto/core@1.2.2

View File

@@ -0,0 +1,27 @@
# @dexto/analytics
Shared analytics utilities for Dexto CLI and WebUI.
## What's included
- **constants.ts**: PostHog configuration (keys, host, analytics disabled check)
- **state.ts**: Analytics state management (distinct ID persistence)
## Usage
```typescript
import { loadState, isAnalyticsDisabled, DEFAULT_POSTHOG_KEY } from '@dexto/analytics';
// Check if analytics is disabled
if (isAnalyticsDisabled()) {
// Skip analytics
}
// Load analytics state (distinct ID)
const state = await loadState();
console.log(state.distinctId);
```
## Note
This is an internal package used by `@dexto/cli` and `@dexto/webui`. It is marked as private and not published to npm.

View File

@@ -0,0 +1,34 @@
{
"name": "@dexto/analytics",
"version": "1.5.6",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./package.json": "./package.json"
},
"dependencies": {
"@dexto/agent-management": "workspace:*",
"@dexto/core": "workspace:*",
"node-machine-id": "^1.1.12"
},
"scripts": {
"build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tsup && cross-env NODE_OPTIONS='--max-old-space-size=4096' tsc -p tsconfig.json --emitDeclarationOnly",
"dev": "tsup --watch",
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
"lint": "eslint . --ext .ts"
},
"files": [
"dist",
"README.md"
],
"publishConfig": {
"access": "public"
},
"sideEffects": false
}

View File

@@ -0,0 +1,27 @@
// packages/analytics/src/constants.ts
// Single source for PostHog configuration.
// Embed your public key here (safe to publish). Host can stay default.
export const DEFAULT_POSTHOG_KEY = 'phc_IJHITHjBKOjDyFiVeilfdumcGniXMuLeXeiLQhYvwDW';
export const DEFAULT_POSTHOG_HOST = 'https://app.posthog.com';
/**
* Single opt-out switch for analytics.
*
* Usage:
* DEXTO_ANALYTICS_DISABLED=1 dexto ...
*
* When set to a truthy value ("1", "true", "yes"), analytics are fully disabled.
*/
export function isAnalyticsDisabled(): boolean {
const v = process.env.DEXTO_ANALYTICS_DISABLED;
return typeof v === 'string' && /^(1|true|yes)$/i.test(v);
}
/**
* Generic per-command timeout (in milliseconds) used by the analytics wrapper.
*
* This does NOT terminate the command. It emits a non-terminating timeout
* event when the duration threshold is crossed to help diagnose long runs.
*/
export const COMMAND_TIMEOUT_MS = 120000; // 2 minutes (default for quick commands)

View File

@@ -0,0 +1,175 @@
/**
* Platform source for analytics events.
* Used to distinguish which interface generated the event.
*/
export type AnalyticsSource = 'cli' | 'webui';
/**
* LLM token consumption event.
* Emitted after each LLM response with token usage data.
*
*/
export interface LLMTokensConsumedEvent {
source: AnalyticsSource;
sessionId: string;
provider?: string | undefined;
model?: string | undefined;
inputTokens?: number | undefined;
outputTokens?: number | undefined;
reasoningTokens?: number | undefined;
totalTokens?: number | undefined;
cacheReadTokens?: number | undefined;
cacheWriteTokens?: number | undefined;
/** Estimated input tokens (before LLM call, using length/4 heuristic) */
estimatedInputTokens?: number | undefined;
/** Accuracy of estimate vs actual: (estimated - actual) / actual * 100 */
estimateAccuracyPercent?: number | undefined;
}
/**
* Message sent event.
* Emitted when user sends a message to the agent.
*/
export interface MessageSentEvent {
source: AnalyticsSource;
sessionId: string;
provider: string;
model: string;
hasImage: boolean;
hasFile: boolean;
messageLength: number;
messageCount?: number | undefined;
isQueued?: boolean | undefined;
}
/**
* Tool called event.
* Emitted when a tool is invoked by the LLM.
*/
export interface ToolCalledEvent {
source: AnalyticsSource;
sessionId: string;
toolName: string;
mcpServer?: string | undefined;
}
/**
* Tool result event.
* Emitted when a tool execution completes.
*/
export interface ToolResultEvent {
source: AnalyticsSource;
sessionId: string;
toolName: string;
success: boolean;
approvalStatus?: 'approved' | 'rejected' | undefined;
}
/**
* Session created event.
*/
export interface SessionCreatedEvent {
source: AnalyticsSource;
sessionId: string;
trigger: 'first_message' | 'manual' | 'resume';
}
/**
* Session reset event (conversation cleared).
*/
export interface SessionResetEvent {
source: AnalyticsSource;
sessionId: string;
messageCount: number;
}
/**
* LLM switched event.
*/
export interface LLMSwitchedEvent {
source: AnalyticsSource;
sessionId?: string | undefined;
fromProvider: string;
fromModel: string;
toProvider: string;
toModel: string;
trigger: 'user_action' | 'config_change';
}
/**
* Session switched event.
* Emitted when user switches to a different session.
*/
export interface SessionSwitchedEvent {
source: AnalyticsSource;
fromSessionId: string | null;
toSessionId: string;
}
/**
* Agent switched event.
* Emitted when user switches to a different agent.
*/
export interface AgentSwitchedEvent {
source: AnalyticsSource;
fromAgentId: string | null;
toAgentId: string;
toAgentName?: string | undefined;
sessionId?: string | undefined;
}
/**
* MCP server connected event.
* Emitted when an MCP server connects successfully.
*/
export interface MCPServerConnectedEvent {
source: AnalyticsSource;
serverName: string;
transportType: 'stdio' | 'http' | 'sse';
toolCount?: number | undefined;
}
/**
* File attached event.
* Emitted when user attaches a file to a message.
*/
export interface FileAttachedEvent {
source: AnalyticsSource;
sessionId: string;
fileType: string;
fileSizeBytes?: number | undefined;
}
/**
* Image attached event.
* Emitted when user attaches an image to a message.
*/
export interface ImageAttachedEvent {
source: AnalyticsSource;
sessionId: string;
imageType: string;
imageSizeBytes?: number | undefined;
}
/**
* Shared analytics event map containing events supported by ALL platforms.
* CLI and WebUI extend this map with platform-specific events.
*
* IMPORTANT: If an event is tracked by both CLI and WebUI, add it here.
* Platform-specific events should be added to the respective platform's event map.
*/
export interface SharedAnalyticsEventMap {
dexto_llm_tokens_consumed: LLMTokensConsumedEvent;
dexto_message_sent: MessageSentEvent;
dexto_tool_called: ToolCalledEvent;
dexto_tool_result: ToolResultEvent;
dexto_session_created: SessionCreatedEvent;
dexto_session_reset: SessionResetEvent;
dexto_llm_switched: LLMSwitchedEvent;
dexto_session_switched: SessionSwitchedEvent;
dexto_agent_switched: AgentSwitchedEvent;
dexto_mcp_server_connected: MCPServerConnectedEvent;
dexto_image_attached: ImageAttachedEvent;
}
export type SharedAnalyticsEventName = keyof SharedAnalyticsEventMap;

View File

@@ -0,0 +1,12 @@
// packages/analytics/src/index.ts
// Shared analytics utilities for Dexto CLI and WebUI
export {
DEFAULT_POSTHOG_KEY,
DEFAULT_POSTHOG_HOST,
COMMAND_TIMEOUT_MS,
isAnalyticsDisabled,
} from './constants.js';
export { loadState, saveState } from './state.js';
export type { AnalyticsState } from './state.js';
export * from './events.js';

View File

@@ -0,0 +1,90 @@
// packages/analytics/src/state.ts
import { promises as fs } from 'fs';
import * as path from 'path';
import os from 'os';
import { randomUUID, createHash } from 'crypto';
import { createRequire } from 'module';
import { getDextoGlobalPath } from '@dexto/core';
/**
* Shape of the persisted analytics state written to
* ~/.dexto/telemetry/state.json.
*
* - distinctId: Anonymous ID (UUID) for grouping events by machine.
* - createdAt: ISO timestamp when the state was first created.
* - commandRunCounts: Local counters per command for coarse diagnostics.
*/
export interface AnalyticsState {
distinctId: string;
createdAt: string; // ISO string
commandRunCounts?: Record<string, number>;
}
const STATE_DIR = getDextoGlobalPath('telemetry');
const STATE_FILE = path.join(STATE_DIR, 'state.json');
/**
* Load the persisted analytics state, creating a new file if missing.
* Returns a valid state object with defaults populated.
*/
export async function loadState(): Promise<AnalyticsState> {
try {
const content = await fs.readFile(STATE_FILE, 'utf8');
const parsed = JSON.parse(content) as Partial<AnalyticsState>;
// Validate minimal shape
if (!parsed.distinctId) throw new Error('invalid state');
return {
distinctId: parsed.distinctId,
createdAt: parsed.createdAt || new Date().toISOString(),
commandRunCounts: parsed.commandRunCounts ?? {},
};
} catch {
await fs.mkdir(STATE_DIR, { recursive: true });
const state: AnalyticsState = {
distinctId: computeDistinctId(),
createdAt: new Date().toISOString(),
commandRunCounts: {},
};
await saveState(state);
return state;
}
}
/**
* Persist the analytics state to ~/.dexto/telemetry/state.json.
*/
export async function saveState(state: AnalyticsState): Promise<void> {
await fs.mkdir(STATE_DIR, { recursive: true });
await fs.writeFile(STATE_FILE, JSON.stringify(state, null, 2), 'utf8');
}
/**
* Compute a stable, privacysafe machine identifier so identity
* survives ~/.dexto deletion by default.
*
* Strategy:
* - Prefer node-machine-id (hashed), which abstracts platform differences.
* - Fallback to a salted/hashed hostname.
* - As a last resort, generate a random UUID.
*/
function computeDistinctId(): string {
try {
// node-machine-id is CommonJS; require lazily to avoid import-time failures
const requireCJS = createRequire(import.meta.url);
const { machineIdSync } = requireCJS('node-machine-id') as {
machineIdSync: (original?: boolean) => string;
};
// machineIdSync(true) returns a hashed, stable identifier
const id = machineIdSync(true);
if (typeof id === 'string' && id.length > 0) return `DEXTO-${id}`;
} catch {
// fall through to hostname hash
}
// Fallback: hash hostname to avoid exposing raw value
const hostname = os.hostname() || 'unknown-host';
const digest = createHash('sha256').update(hostname).digest('hex');
if (digest) return `DEXTO-${digest.slice(0, 32)}`;
// Last resort
return `DEXTO-${randomUUID()}`;
}

View File

@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "src",
"outDir": "dist",
"noEmit": false,
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": false
},
"include": ["src/**/*"],
"exclude": ["**/*.test.ts", "**/*.spec.ts", "**/*.integration.test.ts", "dist", "node_modules"]
}

View File

@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["dist", "node_modules"]
}

View File

@@ -0,0 +1,18 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/**/*.ts'],
format: ['cjs', 'esm'],
outDir: 'dist',
dts: false, // Use tsc for declaration files
platform: 'node',
bundle: false,
clean: true,
tsconfig: './tsconfig.json',
esbuildOptions(options) {
options.logOverride = {
...(options.logOverride ?? {}),
'empty-import-meta': 'silent',
};
},
});