@cleocode/mcp-server 0.90.3 → 0.94.1
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 +2 -2
- package/dist/domains/index.d.ts +1 -0
- package/dist/domains/index.d.ts.map +1 -1
- package/dist/domains/index.js +1 -0
- package/dist/domains/index.js.map +1 -1
- package/dist/domains/issues.d.ts +44 -0
- package/dist/domains/issues.d.ts.map +1 -0
- package/dist/domains/issues.js +182 -0
- package/dist/domains/issues.js.map +1 -0
- package/dist/domains/lifecycle.d.ts.map +1 -1
- package/dist/domains/lifecycle.js +8 -0
- package/dist/domains/lifecycle.js.map +1 -1
- package/dist/domains/orchestrate.js +6 -6
- package/dist/domains/orchestrate.js.map +1 -1
- package/dist/domains/release.js +4 -4
- package/dist/domains/release.js.map +1 -1
- package/dist/domains/research.d.ts.map +1 -1
- package/dist/domains/research.js +8 -0
- package/dist/domains/research.js.map +1 -1
- package/dist/domains/session.d.ts +20 -1
- package/dist/domains/session.d.ts.map +1 -1
- package/dist/domains/session.js +133 -7
- package/dist/domains/session.js.map +1 -1
- package/dist/domains/system.d.ts +20 -1
- package/dist/domains/system.d.ts.map +1 -1
- package/dist/domains/system.js +211 -7
- package/dist/domains/system.js.map +1 -1
- package/dist/domains/tasks.d.ts +20 -1
- package/dist/domains/tasks.d.ts.map +1 -1
- package/dist/domains/tasks.js +165 -1
- package/dist/domains/tasks.js.map +1 -1
- package/dist/domains/validate.d.ts.map +1 -1
- package/dist/domains/validate.js +8 -0
- package/dist/domains/validate.js.map +1 -1
- package/dist/engine/caamp-adapter.d.ts +93 -0
- package/dist/engine/caamp-adapter.d.ts.map +1 -0
- package/dist/engine/caamp-adapter.js +358 -0
- package/dist/engine/caamp-adapter.js.map +1 -0
- package/dist/engine/caamp-verify.d.ts +2 -0
- package/dist/engine/caamp-verify.d.ts.map +1 -0
- package/dist/engine/caamp-verify.js +15 -0
- package/dist/engine/caamp-verify.js.map +1 -0
- package/dist/engine/capability-matrix.d.ts +67 -0
- package/dist/engine/capability-matrix.d.ts.map +1 -0
- package/dist/engine/capability-matrix.js +227 -0
- package/dist/engine/capability-matrix.js.map +1 -0
- package/dist/engine/config-engine.d.ts +29 -0
- package/dist/engine/config-engine.d.ts.map +1 -0
- package/dist/engine/config-engine.js +110 -0
- package/dist/engine/config-engine.js.map +1 -0
- package/dist/engine/id-generator.d.ts +34 -0
- package/dist/engine/id-generator.d.ts.map +1 -0
- package/dist/engine/id-generator.js +91 -0
- package/dist/engine/id-generator.js.map +1 -0
- package/dist/engine/index.d.ts +18 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +28 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/init-engine.d.ts +52 -0
- package/dist/engine/init-engine.d.ts.map +1 -0
- package/dist/engine/init-engine.js +222 -0
- package/dist/engine/init-engine.js.map +1 -0
- package/dist/engine/schema-validator.d.ts +47 -0
- package/dist/engine/schema-validator.d.ts.map +1 -0
- package/dist/engine/schema-validator.js +219 -0
- package/dist/engine/schema-validator.js.map +1 -0
- package/dist/engine/session-engine.d.ts +139 -0
- package/dist/engine/session-engine.d.ts.map +1 -0
- package/dist/engine/session-engine.js +401 -0
- package/dist/engine/session-engine.js.map +1 -0
- package/dist/engine/store.d.ts +67 -0
- package/dist/engine/store.d.ts.map +1 -0
- package/dist/engine/store.js +284 -0
- package/dist/engine/store.js.map +1 -0
- package/dist/engine/task-engine.d.ts +139 -0
- package/dist/engine/task-engine.d.ts.map +1 -0
- package/dist/engine/task-engine.js +481 -0
- package/dist/engine/task-engine.js.map +1 -0
- package/dist/engine/validation-rules.d.ts +78 -0
- package/dist/engine/validation-rules.d.ts.map +1 -0
- package/dist/engine/validation-rules.js +218 -0
- package/dist/engine/validation-rules.js.map +1 -0
- package/dist/gateways/mutate.d.ts +1 -1
- package/dist/gateways/mutate.d.ts.map +1 -1
- package/dist/gateways/mutate.js +6 -1
- package/dist/gateways/mutate.js.map +1 -1
- package/dist/gateways/query.d.ts +1 -1
- package/dist/gateways/query.d.ts.map +1 -1
- package/dist/gateways/query.js +4 -1
- package/dist/gateways/query.js.map +1 -1
- package/dist/index.js +31 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/executor.d.ts +12 -0
- package/dist/lib/executor.d.ts.map +1 -1
- package/dist/lib/executor.js +16 -0
- package/dist/lib/executor.js.map +1 -1
- package/dist/lib/mode-detector.d.ts +71 -0
- package/dist/lib/mode-detector.d.ts.map +1 -0
- package/dist/lib/mode-detector.js +184 -0
- package/dist/lib/mode-detector.js.map +1 -0
- package/dist/lib/router.d.ts +2 -1
- package/dist/lib/router.d.ts.map +1 -1
- package/dist/lib/router.js +7 -5
- package/dist/lib/router.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/package.json +8 -3
- package/schemas/requests/issues/create.schema.json +37 -0
- package/schemas/requests/issues/diagnostics.schema.json +8 -0
- package/schemas/responses/issues/create.schema.json +49 -0
- package/schemas/responses/issues/diagnostics.schema.json +45 -0
- package/server.json +2 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Engine
|
|
3
|
+
*
|
|
4
|
+
* Native TypeScript implementation of session lifecycle operations.
|
|
5
|
+
* Supports both single-session (focus in todo.json) and multi-session
|
|
6
|
+
* (separate sessions.json) modes.
|
|
7
|
+
*
|
|
8
|
+
* Supports: status, list, show, focus.get, focus.set, focus.clear, start, end
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Session object matching sessions.schema.json
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionRecord {
|
|
14
|
+
id: string;
|
|
15
|
+
status: 'active' | 'suspended' | 'ended' | 'archived';
|
|
16
|
+
agentId?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
scope: {
|
|
19
|
+
type: string;
|
|
20
|
+
rootTaskId: string;
|
|
21
|
+
phaseFilter?: string | null;
|
|
22
|
+
labelFilter?: string[] | null;
|
|
23
|
+
includeDescendants?: boolean;
|
|
24
|
+
maxDepth?: number | null;
|
|
25
|
+
explicitTaskIds?: string[] | null;
|
|
26
|
+
excludeTaskIds?: string[] | null;
|
|
27
|
+
computedTaskIds?: string[];
|
|
28
|
+
computedAt?: string;
|
|
29
|
+
};
|
|
30
|
+
focus: {
|
|
31
|
+
currentTask?: string | null;
|
|
32
|
+
currentPhase?: string | null;
|
|
33
|
+
previousTask?: string | null;
|
|
34
|
+
sessionNote?: string | null;
|
|
35
|
+
nextAction?: string | null;
|
|
36
|
+
blockedReason?: string | null;
|
|
37
|
+
focusHistory?: Array<{
|
|
38
|
+
taskId: string;
|
|
39
|
+
timestamp: string;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
42
|
+
startedAt: string;
|
|
43
|
+
lastActivity: string;
|
|
44
|
+
suspendedAt?: string | null;
|
|
45
|
+
endedAt?: string | null;
|
|
46
|
+
archivedAt?: string | null;
|
|
47
|
+
resumeCount?: number;
|
|
48
|
+
stats?: {
|
|
49
|
+
tasksCompleted: number;
|
|
50
|
+
tasksCreated: number;
|
|
51
|
+
tasksUpdated: number;
|
|
52
|
+
focusChanges: number;
|
|
53
|
+
totalActiveMinutes: number;
|
|
54
|
+
suspendCount: number;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Focus state from todo.json (single-session mode)
|
|
59
|
+
*/
|
|
60
|
+
interface FocusState {
|
|
61
|
+
currentTask: string | null;
|
|
62
|
+
currentPhase: string | null;
|
|
63
|
+
blockedUntil: string | null;
|
|
64
|
+
sessionNote: string | null;
|
|
65
|
+
sessionNotes: unknown[];
|
|
66
|
+
nextAction: string | null;
|
|
67
|
+
primarySession: string | null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Engine result wrapper
|
|
71
|
+
*/
|
|
72
|
+
export interface EngineResult<T = unknown> {
|
|
73
|
+
success: boolean;
|
|
74
|
+
data?: T;
|
|
75
|
+
error?: {
|
|
76
|
+
code: string;
|
|
77
|
+
message: string;
|
|
78
|
+
details?: unknown;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get current session status
|
|
83
|
+
*/
|
|
84
|
+
export declare function sessionStatus(projectRoot: string): EngineResult<{
|
|
85
|
+
hasActiveSession: boolean;
|
|
86
|
+
multiSessionEnabled: boolean;
|
|
87
|
+
session?: SessionRecord | null;
|
|
88
|
+
focus?: FocusState | null;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* List sessions (multi-session mode)
|
|
92
|
+
*/
|
|
93
|
+
export declare function sessionList(projectRoot: string, params?: {
|
|
94
|
+
active?: boolean;
|
|
95
|
+
limit?: number;
|
|
96
|
+
}): EngineResult<SessionRecord[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Show a specific session
|
|
99
|
+
*/
|
|
100
|
+
export declare function sessionShow(projectRoot: string, sessionId: string): EngineResult<SessionRecord>;
|
|
101
|
+
/**
|
|
102
|
+
* Get current focus
|
|
103
|
+
*/
|
|
104
|
+
export declare function focusGet(projectRoot: string): EngineResult<{
|
|
105
|
+
currentTask: string | null;
|
|
106
|
+
currentPhase: string | null;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Set focus to a specific task
|
|
110
|
+
*/
|
|
111
|
+
export declare function focusSet(projectRoot: string, taskId: string): Promise<EngineResult<{
|
|
112
|
+
taskId: string;
|
|
113
|
+
previousTask: string | null;
|
|
114
|
+
}>>;
|
|
115
|
+
/**
|
|
116
|
+
* Clear current focus
|
|
117
|
+
*/
|
|
118
|
+
export declare function focusClear(projectRoot: string): Promise<EngineResult<{
|
|
119
|
+
cleared: boolean;
|
|
120
|
+
previousTask: string | null;
|
|
121
|
+
}>>;
|
|
122
|
+
/**
|
|
123
|
+
* Start a new session
|
|
124
|
+
*/
|
|
125
|
+
export declare function sessionStart(projectRoot: string, params: {
|
|
126
|
+
scope: string;
|
|
127
|
+
name?: string;
|
|
128
|
+
autoFocus?: boolean;
|
|
129
|
+
focus?: string;
|
|
130
|
+
}): Promise<EngineResult<SessionRecord>>;
|
|
131
|
+
/**
|
|
132
|
+
* End the current session
|
|
133
|
+
*/
|
|
134
|
+
export declare function sessionEnd(projectRoot: string, notes?: string): Promise<EngineResult<{
|
|
135
|
+
sessionId: string;
|
|
136
|
+
ended: boolean;
|
|
137
|
+
}>>;
|
|
138
|
+
export {};
|
|
139
|
+
//# sourceMappingURL=session-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-engine.d.ts","sourceRoot":"","sources":["../../src/engine/session-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Engine
|
|
3
|
+
*
|
|
4
|
+
* Native TypeScript implementation of session lifecycle operations.
|
|
5
|
+
* Supports both single-session (focus in todo.json) and multi-session
|
|
6
|
+
* (separate sessions.json) modes.
|
|
7
|
+
*
|
|
8
|
+
* Supports: status, list, show, focus.get, focus.set, focus.clear, start, end
|
|
9
|
+
*/
|
|
10
|
+
import { readJsonFile, writeJsonFileAtomic, withFileLock, getDataPath } from './store.js';
|
|
11
|
+
import { randomBytes } from 'crypto';
|
|
12
|
+
/**
|
|
13
|
+
* Generate a session ID matching CLEO format: session_YYYYMMDD_HHMMSS_<hex6>
|
|
14
|
+
*/
|
|
15
|
+
function generateSessionId() {
|
|
16
|
+
const now = new Date();
|
|
17
|
+
const date = now.toISOString().replace(/[-:T]/g, '').substring(0, 8);
|
|
18
|
+
const time = now.toISOString().replace(/[-:T]/g, '').substring(8, 14);
|
|
19
|
+
const hex = randomBytes(3).toString('hex');
|
|
20
|
+
return `session_${date}_${time}_${hex}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if multi-session mode is enabled
|
|
24
|
+
*/
|
|
25
|
+
function isMultiSession(projectRoot) {
|
|
26
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
27
|
+
const todo = readJsonFile(todoPath);
|
|
28
|
+
return todo?._meta?.multiSessionEnabled === true;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get current session status
|
|
32
|
+
*/
|
|
33
|
+
export function sessionStatus(projectRoot) {
|
|
34
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
35
|
+
const todo = readJsonFile(todoPath);
|
|
36
|
+
if (!todo) {
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No todo.json found' },
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const multiSession = todo._meta?.multiSessionEnabled === true;
|
|
43
|
+
if (multiSession) {
|
|
44
|
+
const sessionsPath = getDataPath(projectRoot, todo._meta?.sessionsFile || 'sessions.json');
|
|
45
|
+
const sessions = readJsonFile(sessionsPath);
|
|
46
|
+
const active = sessions?.sessions?.find((s) => s.status === 'active');
|
|
47
|
+
return {
|
|
48
|
+
success: true,
|
|
49
|
+
data: {
|
|
50
|
+
hasActiveSession: !!active,
|
|
51
|
+
multiSessionEnabled: true,
|
|
52
|
+
session: active || null,
|
|
53
|
+
focus: null,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
data: {
|
|
60
|
+
hasActiveSession: !!todo.focus?.currentTask,
|
|
61
|
+
multiSessionEnabled: false,
|
|
62
|
+
session: null,
|
|
63
|
+
focus: todo.focus || null,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* List sessions (multi-session mode)
|
|
69
|
+
*/
|
|
70
|
+
export function sessionList(projectRoot, params) {
|
|
71
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
72
|
+
const todo = readJsonFile(todoPath);
|
|
73
|
+
if (!todo) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No todo.json found' },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const multiSession = todo._meta?.multiSessionEnabled === true;
|
|
80
|
+
if (!multiSession) {
|
|
81
|
+
// Single-session mode: return synthetic session if focus is set
|
|
82
|
+
if (todo.focus?.currentTask) {
|
|
83
|
+
const syntheticSession = {
|
|
84
|
+
id: todo._meta?.activeSession || 'default',
|
|
85
|
+
status: 'active',
|
|
86
|
+
scope: { type: 'task', rootTaskId: todo.focus.currentTask },
|
|
87
|
+
focus: {
|
|
88
|
+
currentTask: todo.focus.currentTask,
|
|
89
|
+
currentPhase: todo.focus.currentPhase,
|
|
90
|
+
},
|
|
91
|
+
startedAt: new Date().toISOString(),
|
|
92
|
+
lastActivity: new Date().toISOString(),
|
|
93
|
+
};
|
|
94
|
+
return { success: true, data: [syntheticSession] };
|
|
95
|
+
}
|
|
96
|
+
return { success: true, data: [] };
|
|
97
|
+
}
|
|
98
|
+
const sessionsPath = getDataPath(projectRoot, todo._meta?.sessionsFile || 'sessions.json');
|
|
99
|
+
const sessions = readJsonFile(sessionsPath);
|
|
100
|
+
if (!sessions) {
|
|
101
|
+
return { success: true, data: [] };
|
|
102
|
+
}
|
|
103
|
+
let result = sessions.sessions || [];
|
|
104
|
+
if (params?.active === true) {
|
|
105
|
+
result = result.filter((s) => s.status === 'active');
|
|
106
|
+
}
|
|
107
|
+
else if (params?.active === false) {
|
|
108
|
+
result = result.filter((s) => s.status !== 'active');
|
|
109
|
+
}
|
|
110
|
+
if (params?.limit && params.limit > 0) {
|
|
111
|
+
result = result.slice(0, params.limit);
|
|
112
|
+
}
|
|
113
|
+
return { success: true, data: result };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Show a specific session
|
|
117
|
+
*/
|
|
118
|
+
export function sessionShow(projectRoot, sessionId) {
|
|
119
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
120
|
+
const todo = readJsonFile(todoPath);
|
|
121
|
+
if (!todo) {
|
|
122
|
+
return {
|
|
123
|
+
success: false,
|
|
124
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No todo.json found' },
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const sessionsPath = getDataPath(projectRoot, todo._meta?.sessionsFile || 'sessions.json');
|
|
128
|
+
const sessions = readJsonFile(sessionsPath);
|
|
129
|
+
if (!sessions) {
|
|
130
|
+
return {
|
|
131
|
+
success: false,
|
|
132
|
+
error: { code: 'E_NOT_FOUND', message: `Session '${sessionId}' not found` },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const session = sessions.sessions?.find((s) => s.id === sessionId);
|
|
136
|
+
if (!session) {
|
|
137
|
+
// Check history
|
|
138
|
+
const historical = sessions.sessionHistory?.find((s) => s.id === sessionId);
|
|
139
|
+
if (historical) {
|
|
140
|
+
return { success: true, data: historical };
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
success: false,
|
|
144
|
+
error: { code: 'E_NOT_FOUND', message: `Session '${sessionId}' not found` },
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return { success: true, data: session };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get current focus
|
|
151
|
+
*/
|
|
152
|
+
export function focusGet(projectRoot) {
|
|
153
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
154
|
+
const todo = readJsonFile(todoPath);
|
|
155
|
+
if (!todo) {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No todo.json found' },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
data: {
|
|
164
|
+
currentTask: todo.focus?.currentTask || null,
|
|
165
|
+
currentPhase: todo.focus?.currentPhase || null,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Set focus to a specific task
|
|
171
|
+
*/
|
|
172
|
+
export async function focusSet(projectRoot, taskId) {
|
|
173
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
174
|
+
return await withFileLock(todoPath, () => {
|
|
175
|
+
const current = readJsonFile(todoPath);
|
|
176
|
+
if (!current) {
|
|
177
|
+
return {
|
|
178
|
+
success: false,
|
|
179
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No valid todo.json found' },
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Verify task exists
|
|
183
|
+
const taskExists = current.tasks?.some((t) => t.id === taskId);
|
|
184
|
+
if (!taskExists) {
|
|
185
|
+
return {
|
|
186
|
+
success: false,
|
|
187
|
+
error: { code: 'E_NOT_FOUND', message: `Task '${taskId}' not found` },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const previousTask = current.focus?.currentTask || null;
|
|
191
|
+
if (!current.focus) {
|
|
192
|
+
current.focus = {
|
|
193
|
+
currentTask: null,
|
|
194
|
+
currentPhase: null,
|
|
195
|
+
blockedUntil: null,
|
|
196
|
+
sessionNote: null,
|
|
197
|
+
sessionNotes: [],
|
|
198
|
+
nextAction: null,
|
|
199
|
+
primarySession: null,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
current.focus.currentTask = taskId;
|
|
203
|
+
current.lastUpdated = new Date().toISOString();
|
|
204
|
+
if (current._meta) {
|
|
205
|
+
current._meta.generation = (current._meta.generation || 0) + 1;
|
|
206
|
+
}
|
|
207
|
+
writeJsonFileAtomic(todoPath, current);
|
|
208
|
+
return { success: true, data: { taskId, previousTask } };
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Clear current focus
|
|
213
|
+
*/
|
|
214
|
+
export async function focusClear(projectRoot) {
|
|
215
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
216
|
+
return await withFileLock(todoPath, () => {
|
|
217
|
+
const current = readJsonFile(todoPath);
|
|
218
|
+
if (!current) {
|
|
219
|
+
return {
|
|
220
|
+
success: false,
|
|
221
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No valid todo.json found' },
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const previousTask = current.focus?.currentTask || null;
|
|
225
|
+
if (current.focus) {
|
|
226
|
+
current.focus.currentTask = null;
|
|
227
|
+
}
|
|
228
|
+
current.lastUpdated = new Date().toISOString();
|
|
229
|
+
if (current._meta) {
|
|
230
|
+
current._meta.generation = (current._meta.generation || 0) + 1;
|
|
231
|
+
}
|
|
232
|
+
writeJsonFileAtomic(todoPath, current);
|
|
233
|
+
return { success: true, data: { cleared: true, previousTask } };
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Start a new session
|
|
238
|
+
*/
|
|
239
|
+
export async function sessionStart(projectRoot, params) {
|
|
240
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
241
|
+
return await withFileLock(todoPath, () => {
|
|
242
|
+
const current = readJsonFile(todoPath);
|
|
243
|
+
if (!current) {
|
|
244
|
+
return {
|
|
245
|
+
success: false,
|
|
246
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No valid todo.json found' },
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// Parse scope (e.g., "epic:T001" -> { type: 'epic', rootTaskId: 'T001' })
|
|
250
|
+
const scopeParts = params.scope.split(':');
|
|
251
|
+
const scopeType = scopeParts[0] || 'task';
|
|
252
|
+
const rootTaskId = scopeParts[1] || '';
|
|
253
|
+
if (!rootTaskId) {
|
|
254
|
+
return {
|
|
255
|
+
success: false,
|
|
256
|
+
error: { code: 'E_INVALID_INPUT', message: 'Scope must include a task ID (e.g., epic:T001)' },
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
// Verify root task exists
|
|
260
|
+
const rootTask = current.tasks?.find((t) => t.id === rootTaskId);
|
|
261
|
+
if (!rootTask) {
|
|
262
|
+
return {
|
|
263
|
+
success: false,
|
|
264
|
+
error: { code: 'E_NOT_FOUND', message: `Root task '${rootTaskId}' not found` },
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const now = new Date().toISOString();
|
|
268
|
+
const sessionId = generateSessionId();
|
|
269
|
+
const newSession = {
|
|
270
|
+
id: sessionId,
|
|
271
|
+
status: 'active',
|
|
272
|
+
name: params.name,
|
|
273
|
+
scope: {
|
|
274
|
+
type: scopeType,
|
|
275
|
+
rootTaskId,
|
|
276
|
+
includeDescendants: true,
|
|
277
|
+
},
|
|
278
|
+
focus: {
|
|
279
|
+
currentTask: params.focus || (params.autoFocus ? rootTaskId : null),
|
|
280
|
+
currentPhase: null,
|
|
281
|
+
previousTask: null,
|
|
282
|
+
},
|
|
283
|
+
startedAt: now,
|
|
284
|
+
lastActivity: now,
|
|
285
|
+
resumeCount: 0,
|
|
286
|
+
stats: {
|
|
287
|
+
tasksCompleted: 0,
|
|
288
|
+
tasksCreated: 0,
|
|
289
|
+
tasksUpdated: 0,
|
|
290
|
+
focusChanges: 0,
|
|
291
|
+
totalActiveMinutes: 0,
|
|
292
|
+
suspendCount: 0,
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
// Update focus in todo.json
|
|
296
|
+
if (!current.focus) {
|
|
297
|
+
current.focus = {
|
|
298
|
+
currentTask: null,
|
|
299
|
+
currentPhase: null,
|
|
300
|
+
blockedUntil: null,
|
|
301
|
+
sessionNote: null,
|
|
302
|
+
sessionNotes: [],
|
|
303
|
+
nextAction: null,
|
|
304
|
+
primarySession: null,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
if (params.focus) {
|
|
308
|
+
current.focus.currentTask = params.focus;
|
|
309
|
+
}
|
|
310
|
+
else if (params.autoFocus) {
|
|
311
|
+
current.focus.currentTask = rootTaskId;
|
|
312
|
+
}
|
|
313
|
+
if (current._meta) {
|
|
314
|
+
current._meta.lastSessionId = sessionId;
|
|
315
|
+
current._meta.activeSession = sessionId;
|
|
316
|
+
current._meta.generation = (current._meta.generation || 0) + 1;
|
|
317
|
+
}
|
|
318
|
+
current.lastUpdated = now;
|
|
319
|
+
writeJsonFileAtomic(todoPath, current);
|
|
320
|
+
// If multi-session enabled, also write to sessions.json
|
|
321
|
+
if (current._meta?.multiSessionEnabled) {
|
|
322
|
+
const sessionsPath = getDataPath(projectRoot, current._meta?.sessionsFile || 'sessions.json');
|
|
323
|
+
const sessions = readJsonFile(sessionsPath) || {
|
|
324
|
+
_meta: {
|
|
325
|
+
schemaVersion: '1.0.0',
|
|
326
|
+
checksum: '',
|
|
327
|
+
lastModified: now,
|
|
328
|
+
totalSessionsCreated: 0,
|
|
329
|
+
},
|
|
330
|
+
sessions: [],
|
|
331
|
+
sessionHistory: [],
|
|
332
|
+
};
|
|
333
|
+
sessions.sessions.push(newSession);
|
|
334
|
+
if (sessions._meta) {
|
|
335
|
+
sessions._meta.lastModified = now;
|
|
336
|
+
sessions._meta.lastSessionId = sessionId;
|
|
337
|
+
sessions._meta.totalSessionsCreated =
|
|
338
|
+
(sessions._meta.totalSessionsCreated || 0) + 1;
|
|
339
|
+
}
|
|
340
|
+
writeJsonFileAtomic(sessionsPath, sessions);
|
|
341
|
+
}
|
|
342
|
+
return { success: true, data: newSession };
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* End the current session
|
|
347
|
+
*/
|
|
348
|
+
export async function sessionEnd(projectRoot, notes) {
|
|
349
|
+
const todoPath = getDataPath(projectRoot, 'todo.json');
|
|
350
|
+
return await withFileLock(todoPath, () => {
|
|
351
|
+
const current = readJsonFile(todoPath);
|
|
352
|
+
if (!current) {
|
|
353
|
+
return {
|
|
354
|
+
success: false,
|
|
355
|
+
error: { code: 'E_NOT_INITIALIZED', message: 'No valid todo.json found' },
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
const sessionId = current._meta?.activeSession || 'default';
|
|
359
|
+
const now = new Date().toISOString();
|
|
360
|
+
// Clear focus
|
|
361
|
+
if (current.focus) {
|
|
362
|
+
current.focus.currentTask = null;
|
|
363
|
+
if (notes) {
|
|
364
|
+
if (!current.focus.sessionNotes)
|
|
365
|
+
current.focus.sessionNotes = [];
|
|
366
|
+
current.focus.sessionNotes.push({ timestamp: now, note: notes });
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (current._meta) {
|
|
370
|
+
current._meta.activeSession = null;
|
|
371
|
+
current._meta.generation = (current._meta.generation || 0) + 1;
|
|
372
|
+
}
|
|
373
|
+
current.lastUpdated = now;
|
|
374
|
+
writeJsonFileAtomic(todoPath, current);
|
|
375
|
+
// Update sessions.json if multi-session
|
|
376
|
+
if (current._meta?.multiSessionEnabled && sessionId !== 'default') {
|
|
377
|
+
const sessionsPath = getDataPath(projectRoot, current._meta?.sessionsFile || 'sessions.json');
|
|
378
|
+
const sessions = readJsonFile(sessionsPath);
|
|
379
|
+
if (sessions) {
|
|
380
|
+
const sessionIndex = sessions.sessions.findIndex((s) => s.id === sessionId);
|
|
381
|
+
if (sessionIndex !== -1) {
|
|
382
|
+
const session = sessions.sessions[sessionIndex];
|
|
383
|
+
session.status = 'ended';
|
|
384
|
+
session.endedAt = now;
|
|
385
|
+
session.lastActivity = now;
|
|
386
|
+
// Move to history
|
|
387
|
+
if (!sessions.sessionHistory)
|
|
388
|
+
sessions.sessionHistory = [];
|
|
389
|
+
sessions.sessionHistory.push(session);
|
|
390
|
+
sessions.sessions.splice(sessionIndex, 1);
|
|
391
|
+
if (sessions._meta) {
|
|
392
|
+
sessions._meta.lastModified = now;
|
|
393
|
+
}
|
|
394
|
+
writeJsonFileAtomic(sessionsPath, sessions);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return { success: true, data: { sessionId, ended: true } };
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=session-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-engine.js","sourceRoot":"","sources":["../../src/engine/session-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON File Store
|
|
3
|
+
*
|
|
4
|
+
* Handles reading and writing CLEO JSON files with:
|
|
5
|
+
* - Atomic writes (temp file -> validate -> backup -> rename)
|
|
6
|
+
* - Cross-process file locking (proper-lockfile)
|
|
7
|
+
* - Numbered backup rotation matching Tier 1 bash behavior
|
|
8
|
+
* - Lock ordering to prevent deadlocks (todo.json before archive)
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Read a JSON file, returning parsed content or null if not found
|
|
12
|
+
*/
|
|
13
|
+
export declare function readJsonFile<T = unknown>(filePath: string): T | null;
|
|
14
|
+
/**
|
|
15
|
+
* Write a JSON file atomically with backup rotation.
|
|
16
|
+
*
|
|
17
|
+
* Pattern: write temp -> backup original -> rename temp to target
|
|
18
|
+
*
|
|
19
|
+
* @param filePath - Target file path
|
|
20
|
+
* @param data - Data to serialize as JSON
|
|
21
|
+
* @param indent - JSON indentation (default: 2 spaces)
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeJsonFileAtomic<T>(filePath: string, data: T, indent?: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* Read and write a JSON file with exclusive locking.
|
|
26
|
+
*
|
|
27
|
+
* Acquires a cross-process lock, reads current state, applies the
|
|
28
|
+
* transform function, validates, and writes back atomically.
|
|
29
|
+
*
|
|
30
|
+
* @param filePath - File to lock and modify
|
|
31
|
+
* @param transform - Function that receives current data and returns new data
|
|
32
|
+
* @returns The transformed data
|
|
33
|
+
*/
|
|
34
|
+
export declare function withLock<T>(filePath: string, transform: (current: T | null) => T): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Acquire a file lock and execute an operation.
|
|
37
|
+
* Unlike withLock, this doesn't read/write the file - caller manages I/O.
|
|
38
|
+
* The return type R is independent of the file content type.
|
|
39
|
+
*/
|
|
40
|
+
export declare function withFileLock<R>(filePath: string, operation: () => R | Promise<R>): Promise<R>;
|
|
41
|
+
/**
|
|
42
|
+
* Acquire locks on multiple files in correct order.
|
|
43
|
+
* Used for operations that need to modify multiple files atomically
|
|
44
|
+
* (e.g., moving a task from todo.json to archive).
|
|
45
|
+
*
|
|
46
|
+
* @param filePaths - Files to lock
|
|
47
|
+
* @param operation - Function to execute while locks are held
|
|
48
|
+
*/
|
|
49
|
+
export declare function withMultiLock<T>(filePaths: string[], operation: () => T | Promise<T>): Promise<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Check if a CLEO project directory exists at the given path
|
|
52
|
+
*/
|
|
53
|
+
export declare function isProjectInitialized(projectRoot: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the project root directory.
|
|
56
|
+
* Checks CLEO_ROOT env, then falls back to cwd.
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveProjectRoot(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Get the path to a CLEO data file
|
|
61
|
+
*/
|
|
62
|
+
export declare function getDataPath(projectRoot: string, filename: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* List backup files for a given data file
|
|
65
|
+
*/
|
|
66
|
+
export declare function listBackups(filePath: string): string[];
|
|
67
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/engine/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0CH;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAUpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,CAAC,EACP,MAAM,GAAE,MAAU,GACjB,IAAI,CA2BN;AAED;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CAyBZ;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,CAAC,CAAC,CAoBZ;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,CAAC,CAAC,CAgCZ;AAoDD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBtD"}
|