@njeybe/nativ 2.4.0 → 2.5.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/CHANGELOG.md +31 -0
- package/README.md +26 -0
- package/dist/commands/db/db-formatter.d.ts +5 -0
- package/dist/commands/db/db-formatter.js +116 -0
- package/dist/commands/db/db-introspect.d.ts +11 -0
- package/dist/commands/db/db-introspect.js +84 -0
- package/dist/commands/db.js +4 -206
- package/dist/commands/profile.d.ts +3 -0
- package/dist/commands/profile.js +39 -0
- package/dist/commands/task/task-add.d.ts +11 -0
- package/dist/commands/task/task-add.js +169 -0
- package/dist/commands/task/task-common.d.ts +57 -0
- package/dist/commands/task/task-common.js +45 -0
- package/dist/commands/task/task-escalate.d.ts +7 -0
- package/dist/commands/task/task-escalate.js +119 -0
- package/dist/commands/task/task-lifecycle.d.ts +5 -0
- package/dist/commands/task/task-lifecycle.js +252 -0
- package/dist/commands/task/task-query.d.ts +10 -0
- package/dist/commands/task/task-query.js +269 -0
- package/dist/commands/task.d.ts +9 -87
- package/dist/commands/task.js +8 -850
- package/dist/commands/triage/triage-store.d.ts +56 -0
- package/dist/commands/triage/triage-store.js +108 -0
- package/dist/commands/triage/triage-ui.d.ts +14 -0
- package/dist/commands/triage/triage-ui.js +104 -0
- package/dist/commands/triage.d.ts +3 -52
- package/dist/commands/triage.js +8 -216
- package/dist/core/enforcement.d.ts +1 -0
- package/dist/core/enforcement.js +19 -0
- package/dist/core/human-gate.d.ts +2 -1
- package/dist/core/human-gate.js +9 -2
- package/dist/core/profiles.d.ts +14 -0
- package/dist/core/profiles.js +82 -0
- package/dist/core/setup/config-merger.d.ts +59 -0
- package/dist/core/setup/config-merger.js +107 -0
- package/dist/core/setup/session-context.d.ts +4 -0
- package/dist/core/setup/session-context.js +65 -0
- package/dist/core/setup/setup-planner.d.ts +14 -0
- package/dist/core/setup/setup-planner.js +180 -0
- package/dist/core/setup/template-planner.d.ts +8 -0
- package/dist/core/setup/template-planner.js +32 -0
- package/dist/core/setup/types.d.ts +65 -0
- package/dist/core/setup/types.js +55 -0
- package/dist/core/setup-assets.d.ts +8 -119
- package/dist/core/setup-assets.js +7 -437
- package/dist/core/spec-slices.js +119 -7
- package/dist/core/tier1-liaison.d.ts +2 -0
- package/dist/core/tier1-liaison.js +64 -3
- package/dist/core/verifier/executor.d.ts +5 -0
- package/dist/core/verifier/executor.js +62 -0
- package/dist/core/verifier/phases.d.ts +5 -0
- package/dist/core/verifier/phases.js +71 -0
- package/dist/core/verifier/task-verifier.d.ts +37 -0
- package/dist/core/verifier/task-verifier.js +233 -0
- package/dist/core/verifier/types.d.ts +51 -0
- package/dist/core/verifier/types.js +1 -0
- package/dist/core/verifier.d.ts +5 -93
- package/dist/core/verifier.js +5 -359
- package/dist/db/introspector.js +59 -59
- package/dist/governor/evaluator.d.ts +4 -64
- package/dist/governor/evaluator.js +21 -686
- package/dist/governor/patch-applier.d.ts +8 -0
- package/dist/governor/patch-applier.js +121 -0
- package/dist/governor/self-healing.d.ts +24 -0
- package/dist/governor/self-healing.js +351 -0
- package/dist/governor/test-integrity.d.ts +41 -0
- package/dist/governor/test-integrity.js +237 -0
- package/dist/index.js +8 -0
- package/dist/mcp/capture.d.ts +4 -0
- package/dist/mcp/capture.js +33 -0
- package/dist/mcp/resources.d.ts +39 -0
- package/dist/mcp/resources.js +44 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +14 -89
- package/dist/mcp/tools.d.ts +1 -0
- package/dist/mcp/tools.js +1 -0
- package/dist/runner/agent-supervisor.d.ts +8 -302
- package/dist/runner/agent-supervisor.js +41 -1030
- package/dist/runner/cli-config.d.ts +84 -0
- package/dist/runner/cli-config.js +215 -0
- package/dist/runner/native-driver.d.ts +18 -0
- package/dist/runner/native-driver.js +208 -0
- package/dist/runner/native-engine.d.ts +27 -0
- package/dist/runner/native-engine.js +184 -0
- package/dist/runner/native-tools.d.ts +31 -0
- package/dist/runner/native-tools.js +241 -0
- package/dist/runner/process-utils.d.ts +12 -0
- package/dist/runner/process-utils.js +96 -0
- package/dist/runner/run-lifecycle.d.ts +6 -0
- package/dist/runner/run-lifecycle.js +42 -0
- package/dist/runner/types.d.ts +215 -0
- package/dist/runner/types.js +41 -0
- package/dist/scanner/detector.js +42 -663
- package/dist/scanner/detectors/ecosystem-detector.d.ts +16 -0
- package/dist/scanner/detectors/ecosystem-detector.js +354 -0
- package/dist/scanner/detectors/orm-detector.d.ts +5 -0
- package/dist/scanner/detectors/orm-detector.js +59 -0
- package/dist/scanner/detectors/workspace-detector.d.ts +19 -0
- package/dist/scanner/detectors/workspace-detector.js +266 -0
- package/dist/server/cli-runner.d.ts +15 -0
- package/dist/server/cli-runner.js +43 -0
- package/dist/server/event-hub.d.ts +42 -0
- package/dist/server/event-hub.js +169 -0
- package/dist/server/http-utils.d.ts +15 -0
- package/dist/server/http-utils.js +56 -0
- package/dist/server/plan-utils.d.ts +9 -0
- package/dist/server/plan-utils.js +31 -0
- package/dist/server/routes/db-routes.d.ts +57 -0
- package/dist/server/routes/db-routes.js +484 -0
- package/dist/server/routes/task-routes.d.ts +266 -0
- package/dist/server/routes/task-routes.js +285 -0
- package/dist/server/routes/telemetry-routes.d.ts +128 -0
- package/dist/server/routes/telemetry-routes.js +179 -0
- package/dist/server/routes/triage-routes.d.ts +81 -0
- package/dist/server/routes/triage-routes.js +244 -0
- package/dist/server/routes/worktree-routes.d.ts +31 -0
- package/dist/server/routes/worktree-routes.js +144 -0
- package/dist/server/studio-server.d.ts +4 -11
- package/dist/server/studio-server.js +34 -1578
- package/dist/server/studio-ui/shell/pipeline-state.js +2 -0
- package/dist/server/studio-ui/shell/triage.js +10 -0
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/agents/architect.md +4 -2
- package/plugin/agents/verifier.md +1 -1
- package/plugin/agents/worker.md +7 -4
- package/plugin/skills/nativ/SKILL.md +1 -0
- package/templates/.claudeignore +62 -45
- package/templates/AGENTS.md +1 -0
- package/templates/CLAUDE.md +13 -0
- package/templates/claude-agents/architect.md +4 -2
- package/templates/claude-agents/verifier.md +1 -1
- package/templates/claude-agents/worker.md +7 -4
- package/templates/dot-ai/api_contracts.json +66 -66
- package/templates/dot-ai/context.md +38 -38
- package/templates/dot-ai/db_schema.json +39 -39
- package/dist/commands/session.d.ts +0 -22
- package/dist/commands/session.js +0 -106
- package/dist/core/session-memory.d.ts +0 -42
- package/dist/core/session-memory.js +0 -121
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { SessionCheckpoint, SessionSummaryEntry } from '../core/session-memory.js';
|
|
2
|
-
export interface SessionSaveOptions {
|
|
3
|
-
summary: string;
|
|
4
|
-
decision?: string[];
|
|
5
|
-
obstacle?: string[];
|
|
6
|
-
next?: string[];
|
|
7
|
-
activeFiles?: string;
|
|
8
|
-
task?: string;
|
|
9
|
-
role?: string;
|
|
10
|
-
sessionId?: string;
|
|
11
|
-
json?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface SessionListOptions {
|
|
14
|
-
limit?: number;
|
|
15
|
-
json?: boolean;
|
|
16
|
-
}
|
|
17
|
-
export interface SessionGetOptions {
|
|
18
|
-
json?: boolean;
|
|
19
|
-
}
|
|
20
|
-
export declare function runSessionSave(targetDirArg?: string, options?: SessionSaveOptions): Promise<SessionCheckpoint>;
|
|
21
|
-
export declare function runSessionList(targetDirArg?: string, options?: SessionListOptions): Promise<SessionSummaryEntry[]>;
|
|
22
|
-
export declare function runSessionGet(sessionId?: string, targetDirArg?: string, options?: SessionGetOptions): Promise<SessionCheckpoint | null>;
|
package/dist/commands/session.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import pc from 'picocolors';
|
|
3
|
-
import { saveSessionCheckpoint, getLatestSession, getSession, listSessions, } from '../core/session-memory.js';
|
|
4
|
-
export async function runSessionSave(targetDirArg, options = { summary: '' }) {
|
|
5
|
-
const targetDir = path.resolve(targetDirArg || process.cwd());
|
|
6
|
-
const files = options.activeFiles
|
|
7
|
-
? options.activeFiles.split(',').map((f) => f.trim()).filter(Boolean)
|
|
8
|
-
: undefined;
|
|
9
|
-
const checkpoint = saveSessionCheckpoint(targetDir, {
|
|
10
|
-
sessionId: options.sessionId,
|
|
11
|
-
summary: options.summary,
|
|
12
|
-
decisions: options.decision,
|
|
13
|
-
obstacles: options.obstacle,
|
|
14
|
-
nextSteps: options.next,
|
|
15
|
-
activeFiles: files,
|
|
16
|
-
taskId: options.task,
|
|
17
|
-
role: options.role,
|
|
18
|
-
});
|
|
19
|
-
if (options.json) {
|
|
20
|
-
console.log(JSON.stringify(checkpoint, null, 2));
|
|
21
|
-
return checkpoint;
|
|
22
|
-
}
|
|
23
|
-
console.log(pc.bold(pc.green(`\n✔ Saved Session Checkpoint: `)) + pc.yellow(`[${checkpoint.sessionId}]`));
|
|
24
|
-
console.log(pc.bold(' Summary: ') + pc.white(checkpoint.summary));
|
|
25
|
-
if (checkpoint.taskId) {
|
|
26
|
-
console.log(pc.bold(' Task: ') + pc.yellow(checkpoint.taskId));
|
|
27
|
-
}
|
|
28
|
-
if (checkpoint.role) {
|
|
29
|
-
console.log(pc.bold(' Role: ') + pc.magenta(checkpoint.role));
|
|
30
|
-
}
|
|
31
|
-
if (checkpoint.decisions && checkpoint.decisions.length > 0) {
|
|
32
|
-
console.log(pc.bold(' Decisions: ') + pc.dim(checkpoint.decisions.join(' | ')));
|
|
33
|
-
}
|
|
34
|
-
if (checkpoint.obstacles && checkpoint.obstacles.length > 0) {
|
|
35
|
-
console.log(pc.bold(' Obstacles: ') + pc.red(checkpoint.obstacles.join(' | ')));
|
|
36
|
-
}
|
|
37
|
-
if (checkpoint.nextSteps && checkpoint.nextSteps.length > 0) {
|
|
38
|
-
console.log(pc.bold(' Next Steps: ') + pc.cyan(checkpoint.nextSteps.join(' | ')));
|
|
39
|
-
}
|
|
40
|
-
if (checkpoint.activeFiles && checkpoint.activeFiles.length > 0) {
|
|
41
|
-
console.log(pc.bold(' Files: ') + pc.dim(checkpoint.activeFiles.join(', ')));
|
|
42
|
-
}
|
|
43
|
-
console.log();
|
|
44
|
-
return checkpoint;
|
|
45
|
-
}
|
|
46
|
-
export async function runSessionList(targetDirArg, options = {}) {
|
|
47
|
-
const targetDir = path.resolve(targetDirArg || process.cwd());
|
|
48
|
-
const sessions = listSessions(targetDir, options.limit || 10);
|
|
49
|
-
if (options.json) {
|
|
50
|
-
console.log(JSON.stringify(sessions, null, 2));
|
|
51
|
-
return sessions;
|
|
52
|
-
}
|
|
53
|
-
console.log(pc.bold(pc.cyan('\nSession Memory Checkpoints (.ai/memory/sessions/)')));
|
|
54
|
-
console.log(pc.dim(`Workspace: ${targetDir}\n`));
|
|
55
|
-
if (sessions.length === 0) {
|
|
56
|
-
console.log(pc.dim(' No saved sessions found.\n'));
|
|
57
|
-
console.log(pc.dim(' Save current progress with: ') + pc.white('nativ session save --summary "..."\n'));
|
|
58
|
-
return sessions;
|
|
59
|
-
}
|
|
60
|
-
for (const s of sessions) {
|
|
61
|
-
const roleTag = s.role ? pc.magenta(`[${s.role}] `) : '';
|
|
62
|
-
const taskTag = s.taskId ? pc.yellow(`[${s.taskId}] `) : '';
|
|
63
|
-
console.log(` ${pc.bold(pc.yellow(s.sessionId))} ${pc.dim(s.timestamp)} ${roleTag}${taskTag}\n ${pc.white(s.summary)}`);
|
|
64
|
-
}
|
|
65
|
-
console.log();
|
|
66
|
-
return sessions;
|
|
67
|
-
}
|
|
68
|
-
export async function runSessionGet(sessionId, targetDirArg, options = {}) {
|
|
69
|
-
const targetDir = path.resolve(targetDirArg || process.cwd());
|
|
70
|
-
const session = sessionId ? getSession(targetDir, sessionId) : getLatestSession(targetDir);
|
|
71
|
-
if (options.json) {
|
|
72
|
-
console.log(JSON.stringify(session, null, 2));
|
|
73
|
-
return session;
|
|
74
|
-
}
|
|
75
|
-
if (!session) {
|
|
76
|
-
console.log(pc.yellow(`\nNo session found${sessionId ? ` matching [${sessionId}]` : ''}.\n`));
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
console.log(pc.bold(pc.cyan(`\nSession Details: `)) + pc.yellow(`[${session.sessionId}]`));
|
|
80
|
-
console.log(pc.bold(' Timestamp: ') + pc.dim(session.timestamp));
|
|
81
|
-
if (session.taskId)
|
|
82
|
-
console.log(pc.bold(' Task ID: ') + pc.yellow(session.taskId));
|
|
83
|
-
if (session.role)
|
|
84
|
-
console.log(pc.bold(' Role: ') + pc.magenta(session.role));
|
|
85
|
-
console.log(pc.bold(' Summary: ') + pc.white(session.summary));
|
|
86
|
-
if (session.decisions && session.decisions.length > 0) {
|
|
87
|
-
console.log(pc.bold('\n Key Decisions:'));
|
|
88
|
-
for (const d of session.decisions)
|
|
89
|
-
console.log(pc.dim(' • ') + pc.white(d));
|
|
90
|
-
}
|
|
91
|
-
if (session.obstacles && session.obstacles.length > 0) {
|
|
92
|
-
console.log(pc.bold('\n Obstacles / Blockers:'));
|
|
93
|
-
for (const o of session.obstacles)
|
|
94
|
-
console.log(pc.red(' ✖ ') + pc.white(o));
|
|
95
|
-
}
|
|
96
|
-
if (session.nextSteps && session.nextSteps.length > 0) {
|
|
97
|
-
console.log(pc.bold('\n Next Steps:'));
|
|
98
|
-
for (const n of session.nextSteps)
|
|
99
|
-
console.log(pc.cyan(' → ') + pc.white(n));
|
|
100
|
-
}
|
|
101
|
-
if (session.activeFiles && session.activeFiles.length > 0) {
|
|
102
|
-
console.log(pc.bold('\n Active Files: ') + pc.dim(session.activeFiles.join(', ')));
|
|
103
|
-
}
|
|
104
|
-
console.log();
|
|
105
|
-
return session;
|
|
106
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export interface SessionCheckpoint {
|
|
2
|
-
sessionId: string;
|
|
3
|
-
timestamp: string;
|
|
4
|
-
role?: string;
|
|
5
|
-
taskId?: string;
|
|
6
|
-
summary: string;
|
|
7
|
-
decisions?: string[];
|
|
8
|
-
obstacles?: string[];
|
|
9
|
-
nextSteps?: string[];
|
|
10
|
-
activeFiles?: string[];
|
|
11
|
-
}
|
|
12
|
-
export interface SessionSummaryEntry {
|
|
13
|
-
sessionId: string;
|
|
14
|
-
timestamp: string;
|
|
15
|
-
role?: string;
|
|
16
|
-
taskId?: string;
|
|
17
|
-
summary: string;
|
|
18
|
-
}
|
|
19
|
-
export interface SessionIndex {
|
|
20
|
-
version: '1.0.0';
|
|
21
|
-
updatedAt: string;
|
|
22
|
-
latestSessionId?: string;
|
|
23
|
-
sessions: SessionSummaryEntry[];
|
|
24
|
-
}
|
|
25
|
-
export declare function getSessionMemoryDir(targetDir: string): string;
|
|
26
|
-
export declare function getSessionIndexPath(targetDir: string): string;
|
|
27
|
-
export declare function getLatestSessionPath(targetDir: string): string;
|
|
28
|
-
export declare function loadSessionIndex(targetDir: string): SessionIndex;
|
|
29
|
-
export declare function saveSessionIndex(targetDir: string, index: SessionIndex): void;
|
|
30
|
-
export declare function saveSessionCheckpoint(targetDir: string, input: {
|
|
31
|
-
sessionId?: string;
|
|
32
|
-
role?: string;
|
|
33
|
-
taskId?: string;
|
|
34
|
-
summary: string;
|
|
35
|
-
decisions?: string[];
|
|
36
|
-
obstacles?: string[];
|
|
37
|
-
nextSteps?: string[];
|
|
38
|
-
activeFiles?: string[];
|
|
39
|
-
}): SessionCheckpoint;
|
|
40
|
-
export declare function getLatestSession(targetDir: string): SessionCheckpoint | null;
|
|
41
|
-
export declare function getSession(targetDir: string, sessionId: string): SessionCheckpoint | null;
|
|
42
|
-
export declare function listSessions(targetDir: string, limit?: number): SessionSummaryEntry[];
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
export function getSessionMemoryDir(targetDir) {
|
|
4
|
-
return path.join(targetDir, '.ai', 'memory', 'sessions');
|
|
5
|
-
}
|
|
6
|
-
export function getSessionIndexPath(targetDir) {
|
|
7
|
-
return path.join(getSessionMemoryDir(targetDir), 'index.json');
|
|
8
|
-
}
|
|
9
|
-
export function getLatestSessionPath(targetDir) {
|
|
10
|
-
return path.join(getSessionMemoryDir(targetDir), 'latest.json');
|
|
11
|
-
}
|
|
12
|
-
export function loadSessionIndex(targetDir) {
|
|
13
|
-
const indexPath = getSessionIndexPath(targetDir);
|
|
14
|
-
if (!fs.existsSync(indexPath)) {
|
|
15
|
-
return {
|
|
16
|
-
version: '1.0.0',
|
|
17
|
-
updatedAt: new Date().toISOString(),
|
|
18
|
-
sessions: [],
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
const raw = fs.readFileSync(indexPath, 'utf8');
|
|
23
|
-
const parsed = JSON.parse(raw);
|
|
24
|
-
if (!Array.isArray(parsed.sessions)) {
|
|
25
|
-
return {
|
|
26
|
-
version: '1.0.0',
|
|
27
|
-
updatedAt: new Date().toISOString(),
|
|
28
|
-
sessions: [],
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
return parsed;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return {
|
|
35
|
-
version: '1.0.0',
|
|
36
|
-
updatedAt: new Date().toISOString(),
|
|
37
|
-
sessions: [],
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export function saveSessionIndex(targetDir, index) {
|
|
42
|
-
const dir = getSessionMemoryDir(targetDir);
|
|
43
|
-
if (!fs.existsSync(dir)) {
|
|
44
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
45
|
-
}
|
|
46
|
-
index.updatedAt = new Date().toISOString();
|
|
47
|
-
fs.writeFileSync(getSessionIndexPath(targetDir), JSON.stringify(index, null, 2), 'utf8');
|
|
48
|
-
}
|
|
49
|
-
export function saveSessionCheckpoint(targetDir, input) {
|
|
50
|
-
const dir = getSessionMemoryDir(targetDir);
|
|
51
|
-
if (!fs.existsSync(dir)) {
|
|
52
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
-
}
|
|
54
|
-
const now = new Date();
|
|
55
|
-
const dateStr = now.toISOString().replace(/[-:T]/g, '').slice(0, 14);
|
|
56
|
-
const sessionId = input.sessionId || `sess-${dateStr}`;
|
|
57
|
-
const checkpoint = {
|
|
58
|
-
sessionId,
|
|
59
|
-
timestamp: now.toISOString(),
|
|
60
|
-
...(input.role ? { role: input.role.trim() } : {}),
|
|
61
|
-
...(input.taskId ? { taskId: input.taskId.trim() } : {}),
|
|
62
|
-
summary: input.summary.trim(),
|
|
63
|
-
...(input.decisions && input.decisions.length > 0 ? { decisions: input.decisions.map((d) => d.trim()) } : {}),
|
|
64
|
-
...(input.obstacles && input.obstacles.length > 0 ? { obstacles: input.obstacles.map((o) => o.trim()) } : {}),
|
|
65
|
-
...(input.nextSteps && input.nextSteps.length > 0 ? { nextSteps: input.nextSteps.map((n) => n.trim()) } : {}),
|
|
66
|
-
...(input.activeFiles && input.activeFiles.length > 0 ? { activeFiles: input.activeFiles.map((f) => f.trim()) } : {}),
|
|
67
|
-
};
|
|
68
|
-
// Write individual session file
|
|
69
|
-
const sessionPath = path.join(dir, `${sessionId}.json`);
|
|
70
|
-
fs.writeFileSync(sessionPath, JSON.stringify(checkpoint, null, 2), 'utf8');
|
|
71
|
-
// Write latest.json
|
|
72
|
-
fs.writeFileSync(getLatestSessionPath(targetDir), JSON.stringify(checkpoint, null, 2), 'utf8');
|
|
73
|
-
// Update index
|
|
74
|
-
const index = loadSessionIndex(targetDir);
|
|
75
|
-
index.latestSessionId = sessionId;
|
|
76
|
-
// Remove existing entry with same sessionId if updating
|
|
77
|
-
index.sessions = index.sessions.filter((s) => s.sessionId !== sessionId);
|
|
78
|
-
index.sessions.unshift({
|
|
79
|
-
sessionId,
|
|
80
|
-
timestamp: checkpoint.timestamp,
|
|
81
|
-
role: checkpoint.role,
|
|
82
|
-
taskId: checkpoint.taskId,
|
|
83
|
-
summary: checkpoint.summary,
|
|
84
|
-
});
|
|
85
|
-
// Keep index trimmed to 50 most recent sessions
|
|
86
|
-
if (index.sessions.length > 50) {
|
|
87
|
-
index.sessions = index.sessions.slice(0, 50);
|
|
88
|
-
}
|
|
89
|
-
saveSessionIndex(targetDir, index);
|
|
90
|
-
return checkpoint;
|
|
91
|
-
}
|
|
92
|
-
export function getLatestSession(targetDir) {
|
|
93
|
-
const latestPath = getLatestSessionPath(targetDir);
|
|
94
|
-
if (!fs.existsSync(latestPath)) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
const raw = fs.readFileSync(latestPath, 'utf8');
|
|
99
|
-
return JSON.parse(raw);
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
export function getSession(targetDir, sessionId) {
|
|
106
|
-
const sessionPath = path.join(getSessionMemoryDir(targetDir), `${sessionId}.json`);
|
|
107
|
-
if (!fs.existsSync(sessionPath)) {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
try {
|
|
111
|
-
const raw = fs.readFileSync(sessionPath, 'utf8');
|
|
112
|
-
return JSON.parse(raw);
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
export function listSessions(targetDir, limit = 10) {
|
|
119
|
-
const index = loadSessionIndex(targetDir);
|
|
120
|
-
return index.sessions.slice(0, limit);
|
|
121
|
-
}
|