feat(wave1): populate @mosaic/types and migrate @mosaic/queue imports
- @mosaic/types: full type definitions extracted from queue, bootstrap, context packages - @mosaic/queue: type imports now sourced from @mosaic/types via workspace:* - Task, TaskStatus, TaskPriority, TaskLane, CreateTaskInput, etc. centralised - Runtime constants (TASK_STATUSES etc.) remain in queue/src/task.ts
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"bin/**/*.ts\" \"vitest.config.ts\"",
|
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"bin/**/*.ts\" \"vitest.config.ts\"",
|
||||||
"build": "tsc -p tsconfig.build.json",
|
"build": "tsc -p tsconfig.build.json",
|
||||||
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"prepublishOnly": "pnpm lint && pnpm test && pnpm build"
|
"prepublishOnly": "pnpm lint && pnpm test && pnpm build"
|
||||||
},
|
},
|
||||||
@@ -32,9 +33,13 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*",
|
||||||
"@modelcontextprotocol/sdk": "^1.27.1",
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
||||||
"commander": "^14.0.3",
|
"commander": "^14.0.3",
|
||||||
"ioredis": "^5.10.0",
|
"ioredis": "^5.10.0",
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vitest": "^3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ interface CompleteCommandOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ClosableRedisTaskClient extends RedisTaskClient {
|
interface ClosableRedisTaskClient extends RedisTaskClient {
|
||||||
|
ping(): Promise<string>;
|
||||||
quit(): Promise<string>;
|
quit(): Promise<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export interface QueueMcpDependencies {
|
|||||||
readonly serverInfo: Implementation;
|
readonly serverInfo: Implementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToolSchema = z.ZodObject<Record<string, z.ZodTypeAny>>;
|
type ToolSchema = z.ZodTypeAny;
|
||||||
|
|
||||||
interface QueueMcpToolDefinition<TArgs extends z.ZodTypeAny> {
|
interface QueueMcpToolDefinition<TArgs extends z.ZodTypeAny> {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
@@ -55,6 +55,7 @@ interface QueueMcpToolDefinition<TArgs extends z.ZodTypeAny> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ClosableRedisTaskClient extends RedisTaskClient {
|
interface ClosableRedisTaskClient extends RedisTaskClient {
|
||||||
|
ping(): Promise<string>;
|
||||||
quit(): Promise<string>;
|
quit(): Promise<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_list',
|
name: 'queue_list',
|
||||||
description: 'List queue tasks with optional project/mission/status filters',
|
description: 'List queue tasks with optional project/mission/status filters',
|
||||||
inputSchema: queueListToolInputSchema,
|
inputSchema: queueListToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueListToolInputSchema>) => {
|
||||||
const tasks = await session.repository.list(input);
|
const tasks = await session.repository.list(input);
|
||||||
return {
|
return {
|
||||||
tasks,
|
tasks,
|
||||||
@@ -84,7 +85,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_get',
|
name: 'queue_get',
|
||||||
description: 'Get a single queue task by taskId',
|
description: 'Get a single queue task by taskId',
|
||||||
inputSchema: queueGetToolInputSchema,
|
inputSchema: queueGetToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueGetToolInputSchema>) => {
|
||||||
const task = await session.repository.get(input.taskId);
|
const task = await session.repository.get(input.taskId);
|
||||||
return {
|
return {
|
||||||
task,
|
task,
|
||||||
@@ -95,7 +96,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_claim',
|
name: 'queue_claim',
|
||||||
description: 'Atomically claim a task for an agent',
|
description: 'Atomically claim a task for an agent',
|
||||||
inputSchema: queueClaimToolInputSchema,
|
inputSchema: queueClaimToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueClaimToolInputSchema>) => {
|
||||||
const task = await session.repository.claim(input.taskId, {
|
const task = await session.repository.claim(input.taskId, {
|
||||||
agentId: input.agentId,
|
agentId: input.agentId,
|
||||||
ttlSeconds: input.ttlSeconds,
|
ttlSeconds: input.ttlSeconds,
|
||||||
@@ -110,7 +111,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_heartbeat',
|
name: 'queue_heartbeat',
|
||||||
description: 'Refresh claim ownership TTL for a task',
|
description: 'Refresh claim ownership TTL for a task',
|
||||||
inputSchema: queueHeartbeatToolInputSchema,
|
inputSchema: queueHeartbeatToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueHeartbeatToolInputSchema>) => {
|
||||||
const task = await session.repository.heartbeat(input.taskId, {
|
const task = await session.repository.heartbeat(input.taskId, {
|
||||||
agentId: input.agentId,
|
agentId: input.agentId,
|
||||||
ttlSeconds: input.ttlSeconds,
|
ttlSeconds: input.ttlSeconds,
|
||||||
@@ -125,7 +126,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_release',
|
name: 'queue_release',
|
||||||
description: 'Release a claimed task back to pending',
|
description: 'Release a claimed task back to pending',
|
||||||
inputSchema: queueReleaseToolInputSchema,
|
inputSchema: queueReleaseToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueReleaseToolInputSchema>) => {
|
||||||
const task = await session.repository.release(input.taskId, {
|
const task = await session.repository.release(input.taskId, {
|
||||||
agentId: input.agentId,
|
agentId: input.agentId,
|
||||||
});
|
});
|
||||||
@@ -139,7 +140,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_complete',
|
name: 'queue_complete',
|
||||||
description: 'Mark a claimed task as completed',
|
description: 'Mark a claimed task as completed',
|
||||||
inputSchema: queueCompleteToolInputSchema,
|
inputSchema: queueCompleteToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueCompleteToolInputSchema>) => {
|
||||||
const task = await session.repository.complete(input.taskId, {
|
const task = await session.repository.complete(input.taskId, {
|
||||||
agentId: input.agentId,
|
agentId: input.agentId,
|
||||||
summary: input.summary,
|
summary: input.summary,
|
||||||
@@ -154,7 +155,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_fail',
|
name: 'queue_fail',
|
||||||
description: 'Mark a claimed task as failed with a reason',
|
description: 'Mark a claimed task as failed with a reason',
|
||||||
inputSchema: queueFailToolInputSchema,
|
inputSchema: queueFailToolInputSchema,
|
||||||
execute: async (session, input) => {
|
execute: async (session: QueueMcpSession, input: z.output<typeof queueFailToolInputSchema>) => {
|
||||||
const task = await session.repository.fail(input.taskId, {
|
const task = await session.repository.fail(input.taskId, {
|
||||||
agentId: input.agentId,
|
agentId: input.agentId,
|
||||||
reason: input.reason,
|
reason: input.reason,
|
||||||
@@ -169,7 +170,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
name: 'queue_status',
|
name: 'queue_status',
|
||||||
description: 'Return queue health and task status counters',
|
description: 'Return queue health and task status counters',
|
||||||
inputSchema: queueStatusToolInputSchema,
|
inputSchema: queueStatusToolInputSchema,
|
||||||
execute: async (session) => {
|
execute: async (session: QueueMcpSession) => {
|
||||||
const tasks = await session.repository.list({});
|
const tasks = await session.repository.list({});
|
||||||
const health = await session.checkHealth();
|
const health = await session.checkHealth();
|
||||||
const counts = countStatuses(tasks);
|
const counts = countStatuses(tasks);
|
||||||
@@ -181,7 +182,7 @@ export const QUEUE_MCP_TOOL_DEFINITIONS = [
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
] as const satisfies readonly QueueMcpToolDefinition<ToolSchema>[];
|
] as const;
|
||||||
|
|
||||||
export function buildQueueMcpServer(
|
export function buildQueueMcpServer(
|
||||||
dependencyOverrides: Partial<QueueMcpDependencies> = {},
|
dependencyOverrides: Partial<QueueMcpDependencies> = {},
|
||||||
@@ -196,11 +197,11 @@ export function buildQueueMcpServer(
|
|||||||
description: definition.description,
|
description: definition.description,
|
||||||
inputSchema: definition.inputSchema,
|
inputSchema: definition.inputSchema,
|
||||||
},
|
},
|
||||||
async (args) => {
|
async (args: unknown) => {
|
||||||
return withSession(dependencies, async (session) => {
|
return withSession(dependencies, async (session) => {
|
||||||
try {
|
try {
|
||||||
const parsedArgs = definition.inputSchema.parse(args);
|
const parsedArgs = definition.inputSchema.parse(args);
|
||||||
const response = await definition.execute(session, parsedArgs);
|
const response = await definition.execute(session, parsedArgs as never);
|
||||||
return toToolResult(response);
|
return toToolResult(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return toToolErrorResult(error);
|
return toToolErrorResult(error);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Redis, { type RedisOptions } from 'ioredis';
|
import Redis, { type Redis as RedisClient, type RedisOptions } from 'ioredis';
|
||||||
|
|
||||||
const ERR_MISSING_REDIS_URL =
|
const ERR_MISSING_REDIS_URL =
|
||||||
'Missing required Valkey/Redis connection URL. Set VALKEY_URL or REDIS_URL.';
|
'Missing required Valkey/Redis connection URL. Set VALKEY_URL or REDIS_URL.';
|
||||||
@@ -36,7 +36,7 @@ export function resolveRedisUrl(env: NodeJS.ProcessEnv = process.env): string {
|
|||||||
return resolvedUrl;
|
return resolvedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createRedisClient<TClient = Redis>(
|
export function createRedisClient<TClient = RedisClient>(
|
||||||
options: CreateRedisClientOptions<TClient> = {},
|
options: CreateRedisClientOptions<TClient> = {},
|
||||||
): TClient {
|
): TClient {
|
||||||
const redisUrl = resolveRedisUrl(options.env);
|
const redisUrl = resolveRedisUrl(options.env);
|
||||||
|
|||||||
@@ -518,22 +518,28 @@ type TaskWithoutCompletionAndFailureFields = Omit<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
function withoutClaimFields(task: Task): TaskWithoutClaimFields {
|
function withoutClaimFields(task: Task): TaskWithoutClaimFields {
|
||||||
const draft: Partial<Task> = { ...task };
|
const {
|
||||||
delete draft.claimedBy;
|
claimedBy: _claimedBy,
|
||||||
delete draft.claimedAt;
|
claimedAt: _claimedAt,
|
||||||
delete draft.claimTTL;
|
claimTTL: _claimTTL,
|
||||||
return draft as TaskWithoutClaimFields;
|
...taskWithoutClaimFields
|
||||||
|
} = task;
|
||||||
|
|
||||||
|
return taskWithoutClaimFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
function withoutCompletionAndFailureFields(
|
function withoutCompletionAndFailureFields(
|
||||||
task: TaskWithoutClaimFields,
|
task: TaskWithoutClaimFields,
|
||||||
): TaskWithoutCompletionAndFailureFields {
|
): TaskWithoutCompletionAndFailureFields {
|
||||||
const draft: Partial<TaskWithoutClaimFields> = { ...task };
|
const {
|
||||||
delete draft.completedAt;
|
completedAt: _completedAt,
|
||||||
delete draft.failedAt;
|
failedAt: _failedAt,
|
||||||
delete draft.failureReason;
|
failureReason: _failureReason,
|
||||||
delete draft.completionSummary;
|
completionSummary: _completionSummary,
|
||||||
return draft as TaskWithoutCompletionAndFailureFields;
|
...taskWithoutCompletionAndFailureFields
|
||||||
|
} = task;
|
||||||
|
|
||||||
|
return taskWithoutCompletionAndFailureFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserializeTask(taskId: string, raw: string): Task {
|
function deserializeTask(taskId: string, raw: string): Task {
|
||||||
@@ -588,18 +594,18 @@ function deserializeTask(taskId: string, raw: string): Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: parsed.id,
|
id: parsed.id as string,
|
||||||
project: parsed.project,
|
project: parsed.project as string,
|
||||||
mission: parsed.mission,
|
mission: parsed.mission as string,
|
||||||
taskId: parsed.taskId,
|
taskId: parsed.taskId as string,
|
||||||
title: parsed.title,
|
title: parsed.title as string,
|
||||||
status: parsed.status,
|
status: parsed.status as TaskStatus,
|
||||||
priority: parsed.priority,
|
priority: parsed.priority as TaskPriority,
|
||||||
dependencies: parsed.dependencies,
|
dependencies: parsed.dependencies as string[],
|
||||||
lane: parsed.lane,
|
lane: parsed.lane as TaskLane,
|
||||||
retryCount: parsed.retryCount,
|
retryCount: parsed.retryCount as number,
|
||||||
createdAt: parsed.createdAt,
|
createdAt: parsed.createdAt as number,
|
||||||
updatedAt: parsed.updatedAt,
|
updatedAt: parsed.updatedAt as number,
|
||||||
...(typeof parsed.description === 'string'
|
...(typeof parsed.description === 'string'
|
||||||
? { description: parsed.description }
|
? { description: parsed.description }
|
||||||
: {}),
|
: {}),
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { describe, expect, it, vi } from 'vitest';
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { runQueueCli, type QueueCliDependencies, type QueueRepository } from '../src/cli.js';
|
import { runQueueCli, type QueueCliDependencies, type QueueRepository } from '../src/cli.js';
|
||||||
|
import type { Task } from '@mosaic/types';
|
||||||
|
|
||||||
function createRepositoryMock(): QueueRepository {
|
function createRepositoryMock(): QueueRepository {
|
||||||
return {
|
return {
|
||||||
create: vi.fn(() =>
|
create: vi.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve<Task>({
|
||||||
id: 'MQ-005',
|
id: 'MQ-005',
|
||||||
project: 'queue',
|
project: 'queue',
|
||||||
mission: 'phase1',
|
mission: 'phase1',
|
||||||
@@ -23,7 +24,7 @@ function createRepositoryMock(): QueueRepository {
|
|||||||
list: vi.fn(() => Promise.resolve([])),
|
list: vi.fn(() => Promise.resolve([])),
|
||||||
get: vi.fn(() => Promise.resolve(null)),
|
get: vi.fn(() => Promise.resolve(null)),
|
||||||
claim: vi.fn(() =>
|
claim: vi.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve<Task>({
|
||||||
id: 'MQ-005',
|
id: 'MQ-005',
|
||||||
project: 'queue',
|
project: 'queue',
|
||||||
mission: 'phase1',
|
mission: 'phase1',
|
||||||
@@ -42,7 +43,7 @@ function createRepositoryMock(): QueueRepository {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
release: vi.fn(() =>
|
release: vi.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve<Task>({
|
||||||
id: 'MQ-005',
|
id: 'MQ-005',
|
||||||
project: 'queue',
|
project: 'queue',
|
||||||
mission: 'phase1',
|
mission: 'phase1',
|
||||||
@@ -58,7 +59,7 @@ function createRepositoryMock(): QueueRepository {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
complete: vi.fn(() =>
|
complete: vi.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve<Task>({
|
||||||
id: 'MQ-005',
|
id: 'MQ-005',
|
||||||
project: 'queue',
|
project: 'queue',
|
||||||
mission: 'phase1',
|
mission: 'phase1',
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "@mosaic/types",
|
"name": "@mosaic/types",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": false,
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"files": [
|
"exports": {
|
||||||
"dist",
|
".": {
|
||||||
"README.md"
|
"import": "./dist/index.js",
|
||||||
],
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": ["dist"],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"test": "echo \"No tests for @mosaic/types\"",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "echo \"No lint configured for @mosaic/types\"",
|
"lint": "echo 'ok'",
|
||||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
"test": "echo 'ok'"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,342 @@
|
|||||||
// @mosaic/types - shared type definitions
|
// @mosaic/types
|
||||||
export type Placeholder = Record<string, never>;
|
// Shared foundational types extracted from queue, bootstrap, and context packages.
|
||||||
|
|
||||||
|
// === Queue ===
|
||||||
|
|
||||||
|
export type TaskStatus =
|
||||||
|
| 'pending'
|
||||||
|
| 'claimed'
|
||||||
|
| 'in-progress'
|
||||||
|
| 'completed'
|
||||||
|
| 'failed'
|
||||||
|
| 'blocked';
|
||||||
|
|
||||||
|
export type TaskPriority = 'critical' | 'high' | 'medium' | 'low';
|
||||||
|
|
||||||
|
export type TaskLane = 'planning' | 'coding' | 'any';
|
||||||
|
|
||||||
|
export interface Task {
|
||||||
|
readonly id: string;
|
||||||
|
readonly project: string;
|
||||||
|
readonly mission: string;
|
||||||
|
readonly taskId: string;
|
||||||
|
readonly title: string;
|
||||||
|
readonly description?: string;
|
||||||
|
readonly status: TaskStatus;
|
||||||
|
readonly priority: TaskPriority;
|
||||||
|
readonly dependencies: readonly string[];
|
||||||
|
readonly lane: TaskLane;
|
||||||
|
readonly claimedBy?: string;
|
||||||
|
readonly claimedAt?: number;
|
||||||
|
readonly claimTTL?: number;
|
||||||
|
readonly completedAt?: number;
|
||||||
|
readonly failedAt?: number;
|
||||||
|
readonly failureReason?: string;
|
||||||
|
readonly completionSummary?: string;
|
||||||
|
readonly retryCount: number;
|
||||||
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
||||||
|
readonly createdAt: number;
|
||||||
|
readonly updatedAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateTaskInput {
|
||||||
|
readonly project: string;
|
||||||
|
readonly mission: string;
|
||||||
|
readonly taskId: string;
|
||||||
|
readonly title: string;
|
||||||
|
readonly description?: string;
|
||||||
|
readonly priority?: TaskPriority;
|
||||||
|
readonly dependencies?: readonly string[];
|
||||||
|
readonly lane?: TaskLane;
|
||||||
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TaskListFilters {
|
||||||
|
readonly project?: string;
|
||||||
|
readonly mission?: string;
|
||||||
|
readonly status?: TaskStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TaskUpdateInput {
|
||||||
|
readonly title?: string;
|
||||||
|
readonly description?: string;
|
||||||
|
readonly status?: TaskStatus;
|
||||||
|
readonly priority?: TaskPriority;
|
||||||
|
readonly dependencies?: readonly string[];
|
||||||
|
readonly lane?: TaskLane;
|
||||||
|
readonly claimedBy?: string;
|
||||||
|
readonly claimedAt?: number;
|
||||||
|
readonly claimTTL?: number;
|
||||||
|
readonly completedAt?: number;
|
||||||
|
readonly failedAt?: number;
|
||||||
|
readonly failureReason?: string;
|
||||||
|
readonly completionSummary?: string;
|
||||||
|
readonly retryCount?: number;
|
||||||
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClaimTaskInput {
|
||||||
|
readonly agentId: string;
|
||||||
|
readonly ttlSeconds: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReleaseTaskInput {
|
||||||
|
readonly agentId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeartbeatTaskInput {
|
||||||
|
readonly agentId?: string;
|
||||||
|
readonly ttlSeconds?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompleteTaskInput {
|
||||||
|
readonly agentId?: string;
|
||||||
|
readonly summary?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FailTaskInput {
|
||||||
|
readonly agentId?: string;
|
||||||
|
readonly reason: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Agent ===
|
||||||
|
|
||||||
|
export type AgentMessageRole =
|
||||||
|
| 'user'
|
||||||
|
| 'assistant'
|
||||||
|
| 'tool'
|
||||||
|
| 'system'
|
||||||
|
| (string & {});
|
||||||
|
|
||||||
|
export interface AgentMessage {
|
||||||
|
readonly role: AgentMessageRole;
|
||||||
|
readonly content: unknown;
|
||||||
|
readonly timestamp?: number;
|
||||||
|
readonly [key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OpenBrainThoughtMetadata = Readonly<
|
||||||
|
Record<string, unknown> & {
|
||||||
|
sessionId?: string;
|
||||||
|
turn?: number;
|
||||||
|
role?: string;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
|
||||||
|
export interface OpenBrainThought {
|
||||||
|
readonly id: string;
|
||||||
|
readonly content: string;
|
||||||
|
readonly source: string;
|
||||||
|
readonly metadata?: OpenBrainThoughtMetadata;
|
||||||
|
readonly createdAt?: string;
|
||||||
|
readonly updatedAt?: string;
|
||||||
|
readonly score?: number;
|
||||||
|
readonly [key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpenBrainThoughtInput {
|
||||||
|
readonly content: string;
|
||||||
|
readonly source: string;
|
||||||
|
readonly metadata?: OpenBrainThoughtMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpenBrainSearchInput {
|
||||||
|
readonly query: string;
|
||||||
|
readonly limit: number;
|
||||||
|
readonly source?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Context Engine ===
|
||||||
|
|
||||||
|
export interface AssembleResult {
|
||||||
|
readonly messages: readonly AgentMessage[];
|
||||||
|
readonly estimatedTokens: number;
|
||||||
|
readonly systemPromptAddition?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompactResultData {
|
||||||
|
readonly summary?: string;
|
||||||
|
readonly firstKeptEntryId?: string;
|
||||||
|
readonly tokensBefore: number;
|
||||||
|
readonly tokensAfter?: number;
|
||||||
|
readonly details?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompactResult {
|
||||||
|
readonly ok: boolean;
|
||||||
|
readonly compacted: boolean;
|
||||||
|
readonly reason?: string;
|
||||||
|
readonly result?: CompactResultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IngestResult {
|
||||||
|
readonly ingested: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IngestBatchResult {
|
||||||
|
readonly ingestedCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BootstrapResult {
|
||||||
|
readonly bootstrapped: boolean;
|
||||||
|
readonly importedMessages?: number;
|
||||||
|
readonly reason?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineInfo {
|
||||||
|
readonly id: string;
|
||||||
|
readonly name: string;
|
||||||
|
readonly version?: string;
|
||||||
|
readonly ownsCompaction?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubagentSpawnPreparation {
|
||||||
|
readonly rollback: () => void | Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SubagentEndReason = 'deleted' | 'completed' | 'swept' | 'released';
|
||||||
|
|
||||||
|
export interface ContextEngineBootstrapParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly sessionFile: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineIngestParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly message: AgentMessage;
|
||||||
|
readonly isHeartbeat?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineIngestBatchParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly messages: readonly AgentMessage[];
|
||||||
|
readonly isHeartbeat?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineAfterTurnParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly sessionFile: string;
|
||||||
|
readonly messages: readonly AgentMessage[];
|
||||||
|
readonly prePromptMessageCount: number;
|
||||||
|
readonly autoCompactionSummary?: string;
|
||||||
|
readonly isHeartbeat?: boolean;
|
||||||
|
readonly tokenBudget?: number;
|
||||||
|
readonly legacyCompactionParams?: Readonly<Record<string, unknown>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineAssembleParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly messages: readonly AgentMessage[];
|
||||||
|
readonly tokenBudget?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineCompactParams {
|
||||||
|
readonly sessionId: string;
|
||||||
|
readonly sessionFile: string;
|
||||||
|
readonly tokenBudget?: number;
|
||||||
|
readonly force?: boolean;
|
||||||
|
readonly currentTokenCount?: number;
|
||||||
|
readonly compactionTarget?: 'budget' | 'threshold';
|
||||||
|
readonly customInstructions?: string;
|
||||||
|
readonly legacyParams?: Readonly<Record<string, unknown>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEnginePrepareSubagentSpawnParams {
|
||||||
|
readonly parentSessionKey: string;
|
||||||
|
readonly childSessionKey: string;
|
||||||
|
readonly ttlMs?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngineSubagentEndedParams {
|
||||||
|
readonly childSessionKey: string;
|
||||||
|
readonly reason: SubagentEndReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContextEngine {
|
||||||
|
readonly info: ContextEngineInfo;
|
||||||
|
bootstrap?(params: ContextEngineBootstrapParams): Promise<BootstrapResult>;
|
||||||
|
ingest(params: ContextEngineIngestParams): Promise<IngestResult>;
|
||||||
|
ingestBatch?(params: ContextEngineIngestBatchParams): Promise<IngestBatchResult>;
|
||||||
|
afterTurn?(params: ContextEngineAfterTurnParams): Promise<void>;
|
||||||
|
assemble(params: ContextEngineAssembleParams): Promise<AssembleResult>;
|
||||||
|
compact(params: ContextEngineCompactParams): Promise<CompactResult>;
|
||||||
|
prepareSubagentSpawn?(
|
||||||
|
params: ContextEnginePrepareSubagentSpawnParams,
|
||||||
|
): Promise<SubagentSpawnPreparation | undefined>;
|
||||||
|
onSubagentEnded?(params: ContextEngineSubagentEndedParams): Promise<void>;
|
||||||
|
dispose?(): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ContextEngineFactory = () => ContextEngine | Promise<ContextEngine>;
|
||||||
|
|
||||||
|
export interface PluginLogger {
|
||||||
|
readonly debug?: (...args: unknown[]) => void;
|
||||||
|
readonly info?: (...args: unknown[]) => void;
|
||||||
|
readonly warn?: (...args: unknown[]) => void;
|
||||||
|
readonly error?: (...args: unknown[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpenClawPluginApi {
|
||||||
|
readonly pluginConfig?: Readonly<Record<string, unknown>>;
|
||||||
|
readonly logger?: PluginLogger;
|
||||||
|
readonly registerContextEngine: (id: string, factory: ContextEngineFactory) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Wizard ===
|
||||||
|
// Wizard bootstrap/setup types are package-specific but intentionally exported
|
||||||
|
// for cross-package tooling and install orchestration.
|
||||||
|
|
||||||
|
export type WizardMode = 'quick' | 'advanced';
|
||||||
|
export type InstallAction = 'fresh' | 'keep' | 'reconfigure' | 'reset';
|
||||||
|
export type CommunicationStyle = 'direct' | 'friendly' | 'formal';
|
||||||
|
export type RuntimeName = 'claude' | 'codex' | 'opencode';
|
||||||
|
|
||||||
|
export interface SoulConfig {
|
||||||
|
readonly agentName?: string;
|
||||||
|
readonly roleDescription?: string;
|
||||||
|
readonly communicationStyle?: CommunicationStyle;
|
||||||
|
readonly accessibility?: string;
|
||||||
|
readonly customGuardrails?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserConfig {
|
||||||
|
readonly userName?: string;
|
||||||
|
readonly pronouns?: string;
|
||||||
|
readonly timezone?: string;
|
||||||
|
readonly background?: string;
|
||||||
|
readonly accessibilitySection?: string;
|
||||||
|
readonly communicationPrefs?: string;
|
||||||
|
readonly personalBoundaries?: string;
|
||||||
|
readonly projectsTable?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GitProvider {
|
||||||
|
readonly name: string;
|
||||||
|
readonly url: string;
|
||||||
|
readonly cli: string;
|
||||||
|
readonly purpose: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ToolsConfig {
|
||||||
|
readonly gitProviders?: readonly GitProvider[];
|
||||||
|
readonly credentialsLocation?: string;
|
||||||
|
readonly customToolsSection?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuntimeState {
|
||||||
|
readonly detected: readonly RuntimeName[];
|
||||||
|
readonly mcpConfigured: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WizardState {
|
||||||
|
readonly mosaicHome: string;
|
||||||
|
readonly sourceDir: string;
|
||||||
|
readonly mode: WizardMode;
|
||||||
|
readonly installAction: InstallAction;
|
||||||
|
readonly soul: SoulConfig;
|
||||||
|
readonly user: UserConfig;
|
||||||
|
readonly tools: ToolsConfig;
|
||||||
|
readonly runtimes: RuntimeState;
|
||||||
|
readonly selectedSkills: readonly string[];
|
||||||
|
}
|
||||||
|
|||||||
1741
pnpm-lock.yaml
generated
1741
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user