@cleocode/contracts 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +36 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +8 -0
- package/dist/adapter.js.map +1 -0
- package/dist/archive.d.ts +100 -0
- package/dist/archive.d.ts.map +1 -0
- package/dist/archive.js +7 -0
- package/dist/archive.js.map +1 -0
- package/dist/brain.d.ts +36 -0
- package/dist/brain.d.ts.map +1 -0
- package/dist/brain.js +10 -0
- package/dist/brain.js.map +1 -0
- package/dist/capabilities.d.ts +21 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +7 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/config.d.ts +118 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -0
- package/dist/context-monitor.d.ts +16 -0
- package/dist/context-monitor.d.ts.map +1 -0
- package/dist/context-monitor.js +7 -0
- package/dist/context-monitor.js.map +1 -0
- package/dist/data-accessor.d.ts +167 -0
- package/dist/data-accessor.d.ts.map +1 -0
- package/dist/data-accessor.js +18 -0
- package/dist/data-accessor.js.map +1 -0
- package/dist/discovery.d.ts +29 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +7 -0
- package/dist/discovery.js.map +1 -0
- package/dist/exit-codes.d.ts +109 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +158 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/hooks.d.ts +17 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +8 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +26 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +8 -0
- package/dist/install.js.map +1 -0
- package/dist/lafs.d.ts +132 -0
- package/dist/lafs.d.ts.map +1 -0
- package/dist/lafs.js +26 -0
- package/dist/lafs.js.map +1 -0
- package/dist/memory.d.ts +51 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +8 -0
- package/dist/memory.js.map +1 -0
- package/dist/operations/index.d.ts +17 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +17 -0
- package/dist/operations/index.js.map +1 -0
- package/dist/operations/issues.d.ts +75 -0
- package/dist/operations/issues.d.ts.map +1 -0
- package/dist/operations/issues.js +10 -0
- package/dist/operations/issues.js.map +1 -0
- package/dist/operations/lifecycle.d.ts +141 -0
- package/dist/operations/lifecycle.d.ts.map +1 -0
- package/dist/operations/lifecycle.js +8 -0
- package/dist/operations/lifecycle.js.map +1 -0
- package/dist/operations/orchestrate.d.ts +202 -0
- package/dist/operations/orchestrate.d.ts.map +1 -0
- package/dist/operations/orchestrate.js +8 -0
- package/dist/operations/orchestrate.js.map +1 -0
- package/dist/operations/release.d.ts +97 -0
- package/dist/operations/release.d.ts.map +1 -0
- package/dist/operations/release.js +7 -0
- package/dist/operations/release.js.map +1 -0
- package/dist/operations/research.d.ts +126 -0
- package/dist/operations/research.d.ts.map +1 -0
- package/dist/operations/research.js +11 -0
- package/dist/operations/research.js.map +1 -0
- package/dist/operations/session.d.ts +99 -0
- package/dist/operations/session.d.ts.map +1 -0
- package/dist/operations/session.js +12 -0
- package/dist/operations/session.js.map +1 -0
- package/dist/operations/skills.d.ts +182 -0
- package/dist/operations/skills.d.ts.map +1 -0
- package/dist/operations/skills.js +10 -0
- package/dist/operations/skills.js.map +1 -0
- package/dist/operations/system.d.ts +147 -0
- package/dist/operations/system.d.ts.map +1 -0
- package/dist/operations/system.js +8 -0
- package/dist/operations/system.js.map +1 -0
- package/dist/operations/tasks.d.ts +231 -0
- package/dist/operations/tasks.d.ts.map +1 -0
- package/dist/operations/tasks.js +13 -0
- package/dist/operations/tasks.js.map +1 -0
- package/dist/operations/validate.d.ts +170 -0
- package/dist/operations/validate.d.ts.map +1 -0
- package/dist/operations/validate.js +8 -0
- package/dist/operations/validate.js.map +1 -0
- package/dist/provider-paths.d.ts +16 -0
- package/dist/provider-paths.d.ts.map +1 -0
- package/dist/provider-paths.js +7 -0
- package/dist/provider-paths.js.map +1 -0
- package/dist/results.d.ts +188 -0
- package/dist/results.d.ts.map +1 -0
- package/dist/results.js +10 -0
- package/dist/results.js.map +1 -0
- package/dist/session.d.ts +106 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +77 -0
- package/dist/session.js.map +1 -0
- package/dist/spawn-types.d.ts +119 -0
- package/dist/spawn-types.d.ts.map +1 -0
- package/dist/spawn-types.js +12 -0
- package/dist/spawn-types.js.map +1 -0
- package/dist/spawn.d.ts +30 -0
- package/dist/spawn.d.ts.map +1 -0
- package/dist/spawn.js +7 -0
- package/dist/spawn.js.map +1 -0
- package/dist/status-registry.d.ts +50 -0
- package/dist/status-registry.d.ts.map +1 -0
- package/dist/status-registry.js +125 -0
- package/dist/status-registry.js.map +1 -0
- package/dist/task-record.d.ts +67 -0
- package/dist/task-record.d.ts.map +1 -0
- package/dist/task-record.js +11 -0
- package/dist/task-record.js.map +1 -0
- package/dist/task-sync.d.ts +143 -0
- package/dist/task-sync.d.ts.map +1 -0
- package/dist/task-sync.js +11 -0
- package/dist/task-sync.js.map +1 -0
- package/dist/task.d.ts +294 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +24 -0
- package/dist/task.js.map +1 -0
- package/dist/tessera.d.ts +32 -0
- package/dist/tessera.d.ts.map +1 -0
- package/dist/tessera.js +11 -0
- package/dist/tessera.js.map +1 -0
- package/dist/todowrite.d.ts +53 -0
- package/dist/todowrite.d.ts.map +1 -0
- package/dist/todowrite.js +7 -0
- package/dist/todowrite.js.map +1 -0
- package/dist/transport.d.ts +12 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +7 -0
- package/dist/transport.js.map +1 -0
- package/dist/warp-chain.d.ts +121 -0
- package/dist/warp-chain.d.ts.map +1 -0
- package/dist/warp-chain.js +13 -0
- package/dist/warp-chain.js.map +1 -0
- package/package.json +29 -0
- package/src/adapter.ts +38 -0
- package/src/archive.ts +121 -0
- package/src/brain.ts +39 -0
- package/src/capabilities.ts +21 -0
- package/src/config.ts +135 -0
- package/src/context-monitor.ts +16 -0
- package/src/data-accessor.ts +239 -0
- package/src/discovery.ts +31 -0
- package/src/exit-codes.ts +175 -0
- package/src/hooks.ts +17 -0
- package/src/index.ts +298 -0
- package/src/install.ts +28 -0
- package/src/lafs.ts +194 -0
- package/src/memory.ts +57 -0
- package/src/operations/index.ts +17 -0
- package/src/operations/issues.ts +86 -0
- package/src/operations/lifecycle.ts +176 -0
- package/src/operations/orchestrate.ts +199 -0
- package/src/operations/release.ts +114 -0
- package/src/operations/research.ts +156 -0
- package/src/operations/session.ts +119 -0
- package/src/operations/skills.ts +210 -0
- package/src/operations/system.ts +174 -0
- package/src/operations/tasks.ts +279 -0
- package/src/operations/validate.ts +199 -0
- package/src/provider-paths.ts +16 -0
- package/src/results.ts +207 -0
- package/src/session.ts +157 -0
- package/src/spawn-types.ts +140 -0
- package/src/spawn.ts +32 -0
- package/src/status-registry.ts +166 -0
- package/src/task-record.ts +71 -0
- package/src/task-sync.ts +167 -0
- package/src/task.ts +387 -0
- package/src/tessera.ts +35 -0
- package/src/todowrite.ts +58 -0
- package/src/transport.ts +12 -0
- package/src/warp-chain.ts +174 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration type definitions for CLEO.
|
|
3
|
+
*
|
|
4
|
+
* Covers project and global config with cascade resolution.
|
|
5
|
+
* These are stable types shared across core, dispatch, and CLI.
|
|
6
|
+
*
|
|
7
|
+
* @epic T4454
|
|
8
|
+
* @task T4456
|
|
9
|
+
* @task T5710
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Output format options. */
|
|
13
|
+
export type OutputFormat = 'json' | 'text' | 'jsonl' | 'markdown' | 'table';
|
|
14
|
+
|
|
15
|
+
/** Date format options. */
|
|
16
|
+
export type DateFormat = 'relative' | 'iso' | 'short' | 'long';
|
|
17
|
+
|
|
18
|
+
/** Output configuration. */
|
|
19
|
+
export interface OutputConfig {
|
|
20
|
+
defaultFormat: OutputFormat;
|
|
21
|
+
showColor: boolean;
|
|
22
|
+
showUnicode: boolean;
|
|
23
|
+
showProgressBars: boolean;
|
|
24
|
+
dateFormat: DateFormat;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Backup configuration. */
|
|
28
|
+
export interface BackupConfig {
|
|
29
|
+
maxOperationalBackups: number;
|
|
30
|
+
maxSafetyBackups: number;
|
|
31
|
+
compressionEnabled: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Hierarchy enforcement profile preset. */
|
|
35
|
+
export type EnforcementProfile = 'llm-agent-first' | 'human-cognitive' | 'custom';
|
|
36
|
+
|
|
37
|
+
/** Hierarchy configuration. */
|
|
38
|
+
export interface HierarchyConfig {
|
|
39
|
+
maxDepth: number;
|
|
40
|
+
maxSiblings: number;
|
|
41
|
+
cascadeDelete: boolean;
|
|
42
|
+
/** Maximum number of active (non-done) siblings. 0 = disabled. */
|
|
43
|
+
maxActiveSiblings: number;
|
|
44
|
+
/** Whether done tasks count toward the sibling limit. */
|
|
45
|
+
countDoneInLimit: boolean;
|
|
46
|
+
/** Enforcement profile preset. Explicit fields override preset values. */
|
|
47
|
+
enforcementProfile: EnforcementProfile;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Session configuration. */
|
|
51
|
+
export interface SessionConfig {
|
|
52
|
+
autoStart: boolean;
|
|
53
|
+
requireNotes: boolean;
|
|
54
|
+
multiSession: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Pino log levels. */
|
|
58
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent';
|
|
59
|
+
|
|
60
|
+
/** Logging configuration. */
|
|
61
|
+
export interface LoggingConfig {
|
|
62
|
+
/** Minimum log level to record (default: 'info') */
|
|
63
|
+
level: LogLevel;
|
|
64
|
+
/** Log file path relative to .cleo/ (default: 'logs/cleo.log') */
|
|
65
|
+
filePath: string;
|
|
66
|
+
/** Max log file size in bytes before rotation (default: 10MB) */
|
|
67
|
+
maxFileSize: number;
|
|
68
|
+
/** Number of rotated log files to retain (default: 5) */
|
|
69
|
+
maxFiles: number;
|
|
70
|
+
/** Days to retain audit_log rows before pruning (default: 90) */
|
|
71
|
+
auditRetentionDays: number;
|
|
72
|
+
/** Whether to archive pruned rows to compressed JSONL before deletion (default: true) */
|
|
73
|
+
archiveBeforePrune: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Lifecycle enforcement mode. */
|
|
77
|
+
export type LifecycleEnforcementMode = 'strict' | 'advisory' | 'off';
|
|
78
|
+
|
|
79
|
+
/** Lifecycle enforcement configuration. */
|
|
80
|
+
export interface LifecycleConfig {
|
|
81
|
+
mode: LifecycleEnforcementMode;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Sharing mode: whether .cleo/ files are committed to the project git repo. */
|
|
85
|
+
export type SharingMode = 'none' | 'project';
|
|
86
|
+
|
|
87
|
+
/** Sharing configuration for multi-contributor .cleo/ state management. */
|
|
88
|
+
export interface SharingConfig {
|
|
89
|
+
/** Sharing mode (default: 'none'). */
|
|
90
|
+
mode: SharingMode;
|
|
91
|
+
/** Files/patterns in .cleo/ to commit to project git (relative to .cleo/). */
|
|
92
|
+
commitAllowlist: string[];
|
|
93
|
+
/** Files/patterns to always exclude, even if in commitAllowlist. */
|
|
94
|
+
denylist: string[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** SignalDock transport mode. */
|
|
98
|
+
export type SignalDockMode = 'http' | 'native';
|
|
99
|
+
|
|
100
|
+
/** SignalDock integration configuration. */
|
|
101
|
+
export interface SignalDockConfig {
|
|
102
|
+
/** Whether SignalDock transport is enabled (default: false). */
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
/** Transport mode: 'http' for REST API client, 'native' for napi-rs bindings (default: 'http'). */
|
|
105
|
+
mode: SignalDockMode;
|
|
106
|
+
/** SignalDock API server endpoint (default: 'http://localhost:4000'). */
|
|
107
|
+
endpoint: string;
|
|
108
|
+
/** Prefix for CLEO agent names in SignalDock registry (default: 'cleo-'). */
|
|
109
|
+
agentPrefix: string;
|
|
110
|
+
/** Default privacy tier for registered agents (default: 'private'). */
|
|
111
|
+
privacyTier: 'public' | 'discoverable' | 'private';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** CLEO project configuration (config.json). */
|
|
115
|
+
export interface CleoConfig {
|
|
116
|
+
version: string;
|
|
117
|
+
output: OutputConfig;
|
|
118
|
+
backup: BackupConfig;
|
|
119
|
+
hierarchy: HierarchyConfig;
|
|
120
|
+
session: SessionConfig;
|
|
121
|
+
lifecycle: LifecycleConfig;
|
|
122
|
+
logging: LoggingConfig;
|
|
123
|
+
sharing: SharingConfig;
|
|
124
|
+
/** SignalDock inter-agent transport (optional, disabled by default). */
|
|
125
|
+
signaldock?: SignalDockConfig;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Configuration resolution priority. */
|
|
129
|
+
export type ConfigSource = 'cli' | 'env' | 'project' | 'global' | 'default';
|
|
130
|
+
|
|
131
|
+
/** A resolved config value with its source. */
|
|
132
|
+
export interface ResolvedValue<T> {
|
|
133
|
+
value: T;
|
|
134
|
+
source: ConfigSource;
|
|
135
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context monitor provider interface for CLEO provider adapters.
|
|
3
|
+
* Allows providers to implement context window tracking and statusline integration.
|
|
4
|
+
* @task T5240
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface AdapterContextMonitorProvider {
|
|
8
|
+
/** Process context window input and return a status string */
|
|
9
|
+
processContextInput(input: unknown, cwd?: string): Promise<string>;
|
|
10
|
+
/** Check if statusline integration is configured */
|
|
11
|
+
checkStatuslineIntegration(): 'configured' | 'not_configured' | 'custom_no_cleo' | 'no_settings';
|
|
12
|
+
/** Get the statusline configuration object */
|
|
13
|
+
getStatuslineConfig(): Record<string, unknown>;
|
|
14
|
+
/** Get human-readable setup instructions */
|
|
15
|
+
getSetupInstructions(): string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataAccessor: File-level storage abstraction for core modules.
|
|
3
|
+
*
|
|
4
|
+
* Core modules operate on whole-file data structures (ArchiveFile, SessionsFile).
|
|
5
|
+
* The DataAccessor abstracts WHERE that data is stored (SQLite via Drizzle ORM)
|
|
6
|
+
* while preserving the read-modify-write pattern that core business logic relies on.
|
|
7
|
+
*
|
|
8
|
+
* This is the DRY/SOLID injection point: core modules accept a DataAccessor parameter
|
|
9
|
+
* instead of calling readJson/saveJson directly.
|
|
10
|
+
*
|
|
11
|
+
* Implementation: SqliteDataAccessor (materializes/dematerializes from SQLite tables)
|
|
12
|
+
*
|
|
13
|
+
* @epic T4454
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { ArchivedTask } from './archive.js';
|
|
17
|
+
import type { Session } from './session.js';
|
|
18
|
+
import type {
|
|
19
|
+
Task,
|
|
20
|
+
TaskPriority,
|
|
21
|
+
TaskSize,
|
|
22
|
+
TaskStatus,
|
|
23
|
+
TaskType,
|
|
24
|
+
} from './task.js';
|
|
25
|
+
|
|
26
|
+
/** Archive-specific fields for task upsert. */
|
|
27
|
+
export interface ArchiveFields {
|
|
28
|
+
archivedAt?: string;
|
|
29
|
+
archiveReason?: string;
|
|
30
|
+
cycleTimeDays?: number | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Archive file structure. */
|
|
34
|
+
export interface ArchiveFile {
|
|
35
|
+
archivedTasks: ArchivedTask[];
|
|
36
|
+
version?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Targeted query/mutation types (Phase 2 modernization)
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
/** Filter bag for queryTasks(). Covers ~90% of task query patterns. */
|
|
44
|
+
export interface TaskQueryFilters {
|
|
45
|
+
status?: TaskStatus | TaskStatus[];
|
|
46
|
+
priority?: TaskPriority;
|
|
47
|
+
type?: TaskType;
|
|
48
|
+
parentId?: string | null; // null = root tasks only
|
|
49
|
+
phase?: string;
|
|
50
|
+
label?: string;
|
|
51
|
+
search?: string; // SQL LIKE on title+description
|
|
52
|
+
excludeStatus?: TaskStatus | TaskStatus[];
|
|
53
|
+
limit?: number;
|
|
54
|
+
offset?: number;
|
|
55
|
+
orderBy?: 'position' | 'createdAt' | 'updatedAt' | 'priority';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Result from queryTasks() with pagination support. */
|
|
59
|
+
export interface QueryTasksResult {
|
|
60
|
+
tasks: Task[];
|
|
61
|
+
total: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Partial task row fields for updateTaskFields(). */
|
|
65
|
+
export interface TaskFieldUpdates {
|
|
66
|
+
title?: string;
|
|
67
|
+
description?: string | null;
|
|
68
|
+
status?: TaskStatus;
|
|
69
|
+
priority?: TaskPriority;
|
|
70
|
+
type?: TaskType | null;
|
|
71
|
+
parentId?: string | null;
|
|
72
|
+
phase?: string | null;
|
|
73
|
+
size?: TaskSize | null;
|
|
74
|
+
position?: number | null;
|
|
75
|
+
positionVersion?: number;
|
|
76
|
+
labelsJson?: string;
|
|
77
|
+
notesJson?: string;
|
|
78
|
+
acceptanceJson?: string;
|
|
79
|
+
filesJson?: string;
|
|
80
|
+
origin?: string | null;
|
|
81
|
+
blockedBy?: string | null;
|
|
82
|
+
epicLifecycle?: string | null;
|
|
83
|
+
noAutoComplete?: boolean | null;
|
|
84
|
+
completedAt?: string | null;
|
|
85
|
+
cancelledAt?: string | null;
|
|
86
|
+
cancellationReason?: string | null;
|
|
87
|
+
verificationJson?: string | null;
|
|
88
|
+
createdBy?: string | null;
|
|
89
|
+
modifiedBy?: string | null;
|
|
90
|
+
sessionId?: string | null;
|
|
91
|
+
updatedAt?: string | null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Subset of DataAccessor methods available inside a transaction callback.
|
|
96
|
+
* Write-only — reads use the outer accessor (snapshot isolation).
|
|
97
|
+
*/
|
|
98
|
+
export interface TransactionAccessor {
|
|
99
|
+
upsertSingleTask(task: Task): Promise<void>;
|
|
100
|
+
archiveSingleTask(taskId: string, fields: ArchiveFields): Promise<void>;
|
|
101
|
+
removeSingleTask(taskId: string): Promise<void>;
|
|
102
|
+
setMetaValue(key: string, value: unknown): Promise<void>;
|
|
103
|
+
updateTaskFields(taskId: string, fields: TaskFieldUpdates): Promise<void>;
|
|
104
|
+
appendLog(entry: Record<string, unknown>): Promise<void>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* DataAccessor interface.
|
|
109
|
+
*
|
|
110
|
+
* Core modules call these methods instead of readJson/saveJson.
|
|
111
|
+
* Each method maps directly to the file-level operations that
|
|
112
|
+
* core modules already perform.
|
|
113
|
+
*/
|
|
114
|
+
export interface DataAccessor {
|
|
115
|
+
/** The storage engine backing this accessor. */
|
|
116
|
+
readonly engine: 'sqlite';
|
|
117
|
+
|
|
118
|
+
// ---- Archive data ----
|
|
119
|
+
|
|
120
|
+
/** Load the archive file. Returns null if archive doesn't exist. */
|
|
121
|
+
loadArchive(): Promise<ArchiveFile | null>;
|
|
122
|
+
|
|
123
|
+
/** Save the archive file atomically. Creates backup before write. */
|
|
124
|
+
saveArchive(data: ArchiveFile): Promise<void>;
|
|
125
|
+
|
|
126
|
+
// ---- Session data ----
|
|
127
|
+
|
|
128
|
+
/** Load all sessions from the store. Returns empty array if none exist. */
|
|
129
|
+
loadSessions(): Promise<Session[]>;
|
|
130
|
+
|
|
131
|
+
/** Save all sessions to the store atomically. */
|
|
132
|
+
saveSessions(sessions: Session[]): Promise<void>;
|
|
133
|
+
|
|
134
|
+
// ---- Audit log ----
|
|
135
|
+
|
|
136
|
+
/** Append an entry to the audit log. */
|
|
137
|
+
appendLog(entry: Record<string, unknown>): Promise<void>;
|
|
138
|
+
|
|
139
|
+
// ---- Lifecycle ----
|
|
140
|
+
|
|
141
|
+
/** Release any resources (close DB connections, etc.). */
|
|
142
|
+
close(): Promise<void>;
|
|
143
|
+
|
|
144
|
+
// ---- Fine-grained task operations (T5034) ----
|
|
145
|
+
|
|
146
|
+
/** Upsert a single task (targeted write, no full-file reload). */
|
|
147
|
+
upsertSingleTask(task: Task): Promise<void>;
|
|
148
|
+
|
|
149
|
+
/** Archive a single task by ID (sets status='archived' + archive metadata). */
|
|
150
|
+
archiveSingleTask(taskId: string, fields: ArchiveFields): Promise<void>;
|
|
151
|
+
|
|
152
|
+
/** Delete a single task permanently from the tasks table. */
|
|
153
|
+
removeSingleTask(taskId: string): Promise<void>;
|
|
154
|
+
|
|
155
|
+
/** Load a single task by ID with its dependencies and relations. Returns null if not found. */
|
|
156
|
+
loadSingleTask(taskId: string): Promise<Task | null>;
|
|
157
|
+
|
|
158
|
+
/** Insert a row into the task_relations table (T5168). */
|
|
159
|
+
addRelation(
|
|
160
|
+
taskId: string,
|
|
161
|
+
relatedTo: string,
|
|
162
|
+
relationType: string,
|
|
163
|
+
reason?: string,
|
|
164
|
+
): Promise<void>;
|
|
165
|
+
|
|
166
|
+
// ---- Metadata (schema_meta KV store) ----
|
|
167
|
+
|
|
168
|
+
/** Read a typed value from the metadata store. Returns null if not found. */
|
|
169
|
+
getMetaValue<T>(key: string): Promise<T | null>;
|
|
170
|
+
|
|
171
|
+
/** Write a typed value to the metadata store. */
|
|
172
|
+
setMetaValue(key: string, value: unknown): Promise<void>;
|
|
173
|
+
|
|
174
|
+
/** Read the schema version from metadata. Convenience for getMetaValue('schema_version'). */
|
|
175
|
+
getSchemaVersion(): Promise<string | null>;
|
|
176
|
+
|
|
177
|
+
// ---- Targeted query methods (Phase 2 modernization) ----
|
|
178
|
+
|
|
179
|
+
/** Query tasks with filters, pagination, and ordering. Returns matching tasks + total count. */
|
|
180
|
+
queryTasks(filters: TaskQueryFilters): Promise<QueryTasksResult>;
|
|
181
|
+
|
|
182
|
+
/** Count tasks matching optional filters. Excludes archived by default. */
|
|
183
|
+
countTasks(filters?: { status?: TaskStatus | TaskStatus[]; parentId?: string }): Promise<number>;
|
|
184
|
+
|
|
185
|
+
/** Get direct children of a parent task. */
|
|
186
|
+
getChildren(parentId: string): Promise<Task[]>;
|
|
187
|
+
|
|
188
|
+
/** Count direct children of a parent task (all statuses except archived). */
|
|
189
|
+
countChildren(parentId: string): Promise<number>;
|
|
190
|
+
|
|
191
|
+
/** Count active (non-terminal) children of a parent task. */
|
|
192
|
+
countActiveChildren(parentId: string): Promise<number>;
|
|
193
|
+
|
|
194
|
+
/** Get ancestor chain from task to root via WITH RECURSIVE CTE. Ordered root-first. */
|
|
195
|
+
getAncestorChain(taskId: string): Promise<Task[]>;
|
|
196
|
+
|
|
197
|
+
/** Get full subtree rooted at taskId via WITH RECURSIVE CTE. Includes root. */
|
|
198
|
+
getSubtree(rootId: string): Promise<Task[]>;
|
|
199
|
+
|
|
200
|
+
/** Get tasks that depend on (are blocked by) the given task. Reverse dep lookup. */
|
|
201
|
+
getDependents(taskId: string): Promise<Task[]>;
|
|
202
|
+
|
|
203
|
+
/** Get transitive dependency chain via WITH RECURSIVE CTE. Returns task IDs. */
|
|
204
|
+
getDependencyChain(taskId: string): Promise<string[]>;
|
|
205
|
+
|
|
206
|
+
/** Check if a task exists (any status including archived). */
|
|
207
|
+
taskExists(taskId: string): Promise<boolean>;
|
|
208
|
+
|
|
209
|
+
/** Load multiple tasks by ID in a single batch query. */
|
|
210
|
+
loadTasks(taskIds: string[]): Promise<Task[]>;
|
|
211
|
+
|
|
212
|
+
// ---- Targeted write methods (Phase 2 modernization) ----
|
|
213
|
+
|
|
214
|
+
/** Update specific fields on a task without full load/save cycle. */
|
|
215
|
+
updateTaskFields(taskId: string, fields: TaskFieldUpdates): Promise<void>;
|
|
216
|
+
|
|
217
|
+
/** Get next available position for a task within a parent scope (SQL-level, race-safe). */
|
|
218
|
+
getNextPosition(parentId: string | null): Promise<number>;
|
|
219
|
+
|
|
220
|
+
/** Shift positions of siblings >= fromPosition by delta (bulk SQL update). */
|
|
221
|
+
shiftPositions(parentId: string | null, fromPosition: number, delta: number): Promise<void>;
|
|
222
|
+
|
|
223
|
+
/** Execute a function inside a SQLite transaction (BEGIN IMMEDIATE / COMMIT / ROLLBACK). */
|
|
224
|
+
transaction<T>(fn: (tx: TransactionAccessor) => Promise<T>): Promise<T>;
|
|
225
|
+
|
|
226
|
+
// ---- Fine-grained session operations ----
|
|
227
|
+
|
|
228
|
+
/** Get the currently active session (status='active', most recent). */
|
|
229
|
+
getActiveSession(): Promise<Session | null>;
|
|
230
|
+
|
|
231
|
+
/** Upsert a single session (targeted write). */
|
|
232
|
+
upsertSingleSession(session: Session): Promise<void>;
|
|
233
|
+
|
|
234
|
+
/** Remove a single session by ID. */
|
|
235
|
+
removeSingleSession(sessionId: string): Promise<void>;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Factory functions (createDataAccessor, getAccessor) live in @cleocode/core,
|
|
239
|
+
// not here. Contracts is types-only.
|
package/src/discovery.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter manifest and discovery contracts for CLEO provider adapters.
|
|
3
|
+
*
|
|
4
|
+
* @task T5240
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AdapterCapabilities } from './capabilities.js';
|
|
8
|
+
|
|
9
|
+
export interface AdapterManifest {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
version: string;
|
|
13
|
+
description: string;
|
|
14
|
+
/** Provider identifier, e.g. "claude-code", "opencode", "cursor" */
|
|
15
|
+
provider: string;
|
|
16
|
+
/** Relative path to the main adapter module */
|
|
17
|
+
entryPoint: string;
|
|
18
|
+
/**
|
|
19
|
+
* Resolved absolute path to the adapter package root.
|
|
20
|
+
* Populated at discovery time by discoverAdapterManifests().
|
|
21
|
+
*/
|
|
22
|
+
packagePath: string;
|
|
23
|
+
capabilities: AdapterCapabilities;
|
|
24
|
+
detectionPatterns: DetectionPattern[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface DetectionPattern {
|
|
28
|
+
type: 'env' | 'file' | 'process' | 'cli';
|
|
29
|
+
pattern: string;
|
|
30
|
+
description: string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLEO exit codes — canonical definitions shared across all layers.
|
|
3
|
+
*
|
|
4
|
+
* Ranges: 0 = success, 1-99 = errors, 100+ = special (non-error) states.
|
|
5
|
+
*
|
|
6
|
+
* @epic T4454
|
|
7
|
+
* @task T4456
|
|
8
|
+
* @task T5710
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export enum ExitCode {
|
|
12
|
+
// === SUCCESS (0) ===
|
|
13
|
+
SUCCESS = 0,
|
|
14
|
+
|
|
15
|
+
// === GENERAL ERRORS (1-9) ===
|
|
16
|
+
GENERAL_ERROR = 1,
|
|
17
|
+
INVALID_INPUT = 2,
|
|
18
|
+
FILE_ERROR = 3,
|
|
19
|
+
NOT_FOUND = 4,
|
|
20
|
+
DEPENDENCY_ERROR = 5,
|
|
21
|
+
VALIDATION_ERROR = 6,
|
|
22
|
+
LOCK_TIMEOUT = 7,
|
|
23
|
+
CONFIG_ERROR = 8,
|
|
24
|
+
|
|
25
|
+
// === HIERARCHY ERRORS (10-19) ===
|
|
26
|
+
PARENT_NOT_FOUND = 10,
|
|
27
|
+
DEPTH_EXCEEDED = 11,
|
|
28
|
+
SIBLING_LIMIT = 12,
|
|
29
|
+
INVALID_PARENT_TYPE = 13,
|
|
30
|
+
CIRCULAR_REFERENCE = 14,
|
|
31
|
+
ORPHAN_DETECTED = 15,
|
|
32
|
+
HAS_CHILDREN = 16,
|
|
33
|
+
TASK_COMPLETED = 17,
|
|
34
|
+
CASCADE_FAILED = 18,
|
|
35
|
+
HAS_DEPENDENTS = 19,
|
|
36
|
+
|
|
37
|
+
// === CONCURRENCY ERRORS (20-29) ===
|
|
38
|
+
CHECKSUM_MISMATCH = 20,
|
|
39
|
+
CONCURRENT_MODIFICATION = 21,
|
|
40
|
+
ID_COLLISION = 22,
|
|
41
|
+
|
|
42
|
+
// === SESSION ERRORS (30-39) ===
|
|
43
|
+
SESSION_EXISTS = 30,
|
|
44
|
+
SESSION_NOT_FOUND = 31,
|
|
45
|
+
SCOPE_CONFLICT = 32,
|
|
46
|
+
SCOPE_INVALID = 33,
|
|
47
|
+
TASK_NOT_IN_SCOPE = 34,
|
|
48
|
+
TASK_CLAIMED = 35,
|
|
49
|
+
SESSION_REQUIRED = 36,
|
|
50
|
+
SESSION_CLOSE_BLOCKED = 37,
|
|
51
|
+
ACTIVE_TASK_REQUIRED = 38,
|
|
52
|
+
NOTES_REQUIRED = 39,
|
|
53
|
+
|
|
54
|
+
// === VERIFICATION ERRORS (40-47) ===
|
|
55
|
+
VERIFICATION_INIT_FAILED = 40,
|
|
56
|
+
GATE_UPDATE_FAILED = 41,
|
|
57
|
+
INVALID_GATE = 42,
|
|
58
|
+
INVALID_AGENT = 43,
|
|
59
|
+
MAX_ROUNDS_EXCEEDED = 44,
|
|
60
|
+
GATE_DEPENDENCY = 45,
|
|
61
|
+
VERIFICATION_LOCKED = 46,
|
|
62
|
+
ROUND_MISMATCH = 47,
|
|
63
|
+
|
|
64
|
+
// === CONTEXT SAFEGUARD (50-54) ===
|
|
65
|
+
CONTEXT_WARNING = 50,
|
|
66
|
+
CONTEXT_CAUTION = 51,
|
|
67
|
+
CONTEXT_CRITICAL = 52,
|
|
68
|
+
CONTEXT_EMERGENCY = 53,
|
|
69
|
+
CONTEXT_STALE = 54,
|
|
70
|
+
|
|
71
|
+
// === ORCHESTRATOR ERRORS (60-67) ===
|
|
72
|
+
PROTOCOL_MISSING = 60,
|
|
73
|
+
INVALID_RETURN_MESSAGE = 61,
|
|
74
|
+
MANIFEST_ENTRY_MISSING = 62,
|
|
75
|
+
SPAWN_VALIDATION_FAILED = 63,
|
|
76
|
+
AUTONOMOUS_BOUNDARY = 64,
|
|
77
|
+
HANDOFF_REQUIRED = 65,
|
|
78
|
+
RESUME_FAILED = 66,
|
|
79
|
+
CONCURRENT_SESSION = 67,
|
|
80
|
+
|
|
81
|
+
// === NEXUS ERRORS (70-79) ===
|
|
82
|
+
NEXUS_NOT_INITIALIZED = 70,
|
|
83
|
+
NEXUS_PROJECT_NOT_FOUND = 71,
|
|
84
|
+
NEXUS_PERMISSION_DENIED = 72,
|
|
85
|
+
NEXUS_INVALID_SYNTAX = 73,
|
|
86
|
+
NEXUS_SYNC_FAILED = 74,
|
|
87
|
+
NEXUS_REGISTRY_CORRUPT = 75,
|
|
88
|
+
NEXUS_PROJECT_EXISTS = 76,
|
|
89
|
+
NEXUS_QUERY_FAILED = 77,
|
|
90
|
+
NEXUS_GRAPH_ERROR = 78,
|
|
91
|
+
NEXUS_RESERVED = 79,
|
|
92
|
+
|
|
93
|
+
// === LIFECYCLE ENFORCEMENT (80-84) ===
|
|
94
|
+
LIFECYCLE_GATE_FAILED = 80,
|
|
95
|
+
AUDIT_MISSING = 81,
|
|
96
|
+
CIRCULAR_VALIDATION = 82,
|
|
97
|
+
LIFECYCLE_TRANSITION_INVALID = 83,
|
|
98
|
+
PROVENANCE_REQUIRED = 84,
|
|
99
|
+
|
|
100
|
+
// === ARTIFACT PUBLISH (85-89) ===
|
|
101
|
+
ARTIFACT_TYPE_UNKNOWN = 85,
|
|
102
|
+
ARTIFACT_VALIDATION_FAILED = 86,
|
|
103
|
+
ARTIFACT_BUILD_FAILED = 87,
|
|
104
|
+
ARTIFACT_PUBLISH_FAILED = 88,
|
|
105
|
+
ARTIFACT_ROLLBACK_FAILED = 89,
|
|
106
|
+
|
|
107
|
+
// === PROVENANCE (90-94) ===
|
|
108
|
+
PROVENANCE_CONFIG_INVALID = 90,
|
|
109
|
+
SIGNING_KEY_MISSING = 91,
|
|
110
|
+
SIGNATURE_INVALID = 92,
|
|
111
|
+
DIGEST_MISMATCH = 93,
|
|
112
|
+
ATTESTATION_INVALID = 94,
|
|
113
|
+
|
|
114
|
+
// === ADAPTER ERRORS (95-99) ===
|
|
115
|
+
ADAPTER_NOT_FOUND = 95,
|
|
116
|
+
ADAPTER_INIT_FAILED = 96,
|
|
117
|
+
ADAPTER_HOOK_FAILED = 97,
|
|
118
|
+
ADAPTER_SPAWN_FAILED = 98,
|
|
119
|
+
ADAPTER_INSTALL_FAILED = 99,
|
|
120
|
+
|
|
121
|
+
// === SPECIAL CODES (100+) - NOT errors ===
|
|
122
|
+
NO_DATA = 100,
|
|
123
|
+
ALREADY_EXISTS = 101,
|
|
124
|
+
NO_CHANGE = 102,
|
|
125
|
+
TESTS_SKIPPED = 103,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Check if an exit code represents an error (1-99). */
|
|
129
|
+
export function isErrorCode(code: ExitCode): boolean {
|
|
130
|
+
return code >= 1 && code < 100;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Check if an exit code represents success (0 or 100+). */
|
|
134
|
+
export function isSuccessCode(code: ExitCode): boolean {
|
|
135
|
+
return code === 0 || code >= 100;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Check if an exit code indicates no change (idempotent operation). */
|
|
139
|
+
export function isNoChangeCode(code: ExitCode): boolean {
|
|
140
|
+
return code === ExitCode.NO_CHANGE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Check if an exit code is recoverable (retry may succeed). */
|
|
144
|
+
export function isRecoverableCode(code: ExitCode): boolean {
|
|
145
|
+
const nonRecoverable = new Set<ExitCode>([
|
|
146
|
+
ExitCode.FILE_ERROR,
|
|
147
|
+
ExitCode.DEPENDENCY_ERROR,
|
|
148
|
+
ExitCode.CIRCULAR_REFERENCE,
|
|
149
|
+
ExitCode.CASCADE_FAILED,
|
|
150
|
+
ExitCode.SESSION_CLOSE_BLOCKED,
|
|
151
|
+
ExitCode.VERIFICATION_LOCKED,
|
|
152
|
+
ExitCode.CONTEXT_WARNING,
|
|
153
|
+
ExitCode.CONTEXT_CAUTION,
|
|
154
|
+
ExitCode.CONTEXT_CRITICAL,
|
|
155
|
+
ExitCode.CONTEXT_EMERGENCY,
|
|
156
|
+
ExitCode.CONTEXT_STALE,
|
|
157
|
+
ExitCode.AUTONOMOUS_BOUNDARY,
|
|
158
|
+
ExitCode.HANDOFF_REQUIRED,
|
|
159
|
+
ExitCode.NEXUS_PERMISSION_DENIED,
|
|
160
|
+
ExitCode.NEXUS_REGISTRY_CORRUPT,
|
|
161
|
+
ExitCode.CIRCULAR_VALIDATION,
|
|
162
|
+
ExitCode.LIFECYCLE_TRANSITION_INVALID,
|
|
163
|
+
ExitCode.ARTIFACT_TYPE_UNKNOWN,
|
|
164
|
+
ExitCode.ARTIFACT_ROLLBACK_FAILED,
|
|
165
|
+
ExitCode.DIGEST_MISMATCH,
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
if (!isErrorCode(code)) return false;
|
|
169
|
+
return !nonRecoverable.has(code);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Human-readable name for an exit code. */
|
|
173
|
+
export function getExitCodeName(code: ExitCode): string {
|
|
174
|
+
return ExitCode[code] ?? 'UNKNOWN';
|
|
175
|
+
}
|
package/src/hooks.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook provider interface for CLEO provider adapters.
|
|
3
|
+
* Maps provider-specific events to CAAMP hook events.
|
|
4
|
+
*
|
|
5
|
+
* @task T5240
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface AdapterHookProvider {
|
|
9
|
+
/** Map a provider-specific event name to a CAAMP hook event name, or null if unmapped. */
|
|
10
|
+
mapProviderEvent(providerEvent: string): string | null;
|
|
11
|
+
/** Register the provider's native hook mechanism for a project. */
|
|
12
|
+
registerNativeHooks(projectDir: string): Promise<void>;
|
|
13
|
+
/** Unregister all native hooks previously registered. */
|
|
14
|
+
unregisterNativeHooks(): Promise<void>;
|
|
15
|
+
/** Return the full event mapping for introspection. */
|
|
16
|
+
getEventMap?(): Readonly<Record<string, string>>;
|
|
17
|
+
}
|