@vesk/agentic 0.2.11
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 +53 -0
- package/dist/checkpoints.d.ts +155 -0
- package/dist/checkpoints.d.ts.map +1 -0
- package/dist/checkpoints.js +394 -0
- package/dist/config.d.ts +57 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +399 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +64 -0
- package/dist/dev-api.d.ts +85 -0
- package/dist/dev-api.d.ts.map +1 -0
- package/dist/dev-api.js +942 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/loop.d.ts +156 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +178 -0
- package/dist/permissions.d.ts +14 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +74 -0
- package/dist/plugin.d.ts +38 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +28 -0
- package/dist/providers/anthropic.d.ts +13 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +100 -0
- package/dist/providers/google.d.ts +12 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +87 -0
- package/dist/providers/ollama.d.ts +11 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +61 -0
- package/dist/providers/openai.d.ts +12 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +193 -0
- package/dist/providers/registry.d.ts +7 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +33 -0
- package/dist/providers/types.d.ts +28 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +15 -0
- package/dist/slash.d.ts +18 -0
- package/dist/slash.d.ts.map +1 -0
- package/dist/slash.js +77 -0
- package/dist/tools/browser.d.ts +3 -0
- package/dist/tools/browser.d.ts.map +1 -0
- package/dist/tools/browser.js +289 -0
- package/dist/tools/command.d.ts +14 -0
- package/dist/tools/command.d.ts.map +1 -0
- package/dist/tools/command.js +55 -0
- package/dist/tools/fs.d.ts +10 -0
- package/dist/tools/fs.d.ts.map +1 -0
- package/dist/tools/fs.js +142 -0
- package/dist/tools/vesk.d.ts +22 -0
- package/dist/tools/vesk.d.ts.map +1 -0
- package/dist/tools/vesk.js +828 -0
- package/dist/tools/web.d.ts +3 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +111 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @vesk/agentic
|
|
2
|
+
|
|
3
|
+
Agentic AI plugin for Vesk — zero-deps agent loop, provider abstraction, permissions, tools, checkpoints. Vendored clone of `@narimangardi/agent-loop` (20.7kB, zero deps) — core Vesk ships no agent runtime.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @vesk/agentic
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage — add to `vesk.config.ts`
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// vesk.config.ts
|
|
15
|
+
import { defineConfig } from '@vesk/compiler';
|
|
16
|
+
import agentic from '@vesk/agentic/src/plugin.js';
|
|
17
|
+
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
plugins: [
|
|
20
|
+
agentic({
|
|
21
|
+
provider: 'openai', // 'openai' | 'openai-compatible' | 'anthropic' | 'google' | 'ollama'
|
|
22
|
+
model: 'gpt-4o-mini',
|
|
23
|
+
// apiKey: process.env.VESK_AGENTIC_API_KEY,
|
|
24
|
+
mode: 'explore', // 'explore' | 'debug' | 'agent'
|
|
25
|
+
maxSteps: 10,
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `provider`/`model`/`apiKey`/`baseUrl` are provider-agnostic — switching models never touches the agent implementation.
|
|
32
|
+
- `mode` selects the default permission set (`explore`=read-only, `debug`=controlled fixes, `agent`=per-capability toggles). All checks are server-enforced via the Dev Server capability gate.
|
|
33
|
+
- When the plugin is inactive (toggled off in the devtool or not listed), it is fully excluded from the build — zero bundle/build cost.
|
|
34
|
+
|
|
35
|
+
## DevTools AI panel
|
|
36
|
+
|
|
37
|
+
When `@vesk/agentic` is installed & active, `vesk dev` exposes the **AI** panel in the devtools overlay:
|
|
38
|
+
|
|
39
|
+
- Provider / model / key config (shown only when the plugin is active)
|
|
40
|
+
- Mode + granular permissions (`readFiles`, `writeFiles`, `deleteFiles`, `executeCommands`, `installPackages`, `modifyConfig`, `managePlugins`, `runBuild`, `runTests`, `modifyAgentsMd`, `createCheckpoint`, `rollback`)
|
|
41
|
+
- Layered context (framework knowledge + project `agents.md` + live project state via Dev Server)
|
|
42
|
+
- Vesk-native tools (`vesk.inspectProject`, `vesk.readConfig`, `vesk.runBuild`, `vesk.createCheckpoint`, etc.) gated by permissions
|
|
43
|
+
- Checkpoints / history / rollback — every agent action checkpoints; rollback restores prior file state
|
|
44
|
+
|
|
45
|
+
Inactive ⇒ the AI panel is hidden and no agent code is bundled.
|
|
46
|
+
|
|
47
|
+
## Zero dependencies
|
|
48
|
+
|
|
49
|
+
No runtime deps on `openai`, `@anthropic-ai/sdk`, `@google/genai`, or `@aws-sdk`. Each provider is a fetch-only adapter; bring your own key.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vesk/agentic — checkpoints & transactions
|
|
3
|
+
*
|
|
4
|
+
* Zero-deps checkpoint system for agent operations.
|
|
5
|
+
*
|
|
6
|
+
* Two complementary surfaces in one module (both zero-deps):
|
|
7
|
+
*
|
|
8
|
+
* 1. `CheckpointManager` — in-memory, browser-safe manager for `Preview → Approve → Execute → Validate → Checkpoint`
|
|
9
|
+
* flows inside the agent loop. Persists only metadata; caller restores files.
|
|
10
|
+
*
|
|
11
|
+
* 2. File-system store — `createCheckpoint(projectDir, message, changes, buildResult)` and friends
|
|
12
|
+
* persisting to `<projectDir>/.vesk/agentic/history.json` + `checkpoints/{id}/checkpoint.json`.
|
|
13
|
+
* Used by `@vesk/agentic` Dev Server router (`createAgentRouter`) and `vesk.*` tools (`createVeskTools`).
|
|
14
|
+
*
|
|
15
|
+
* Both surfaces share the same unified `Checkpoint` shape (superset of manager + file-system fields)
|
|
16
|
+
* so the Dev Server router and in-memory tests interoperate without type drift.
|
|
17
|
+
*/
|
|
18
|
+
export interface CheckpointFile {
|
|
19
|
+
path: string;
|
|
20
|
+
before: string | null;
|
|
21
|
+
after: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface CheckpointDeps {
|
|
24
|
+
installed: string[];
|
|
25
|
+
removed: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface CheckpointBuild {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
ms?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface CheckpointTest {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CheckpointCommand {
|
|
37
|
+
argv: string[];
|
|
38
|
+
stdout: string;
|
|
39
|
+
stderr: string;
|
|
40
|
+
code: number | null;
|
|
41
|
+
}
|
|
42
|
+
export interface CheckpointBuildResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
output?: string;
|
|
45
|
+
errors?: string[];
|
|
46
|
+
[k: string]: unknown;
|
|
47
|
+
}
|
|
48
|
+
export interface Checkpoint {
|
|
49
|
+
id: string;
|
|
50
|
+
timestamp: number;
|
|
51
|
+
createdAt: string;
|
|
52
|
+
message: string;
|
|
53
|
+
label?: string;
|
|
54
|
+
prompt?: string;
|
|
55
|
+
files: CheckpointFile[];
|
|
56
|
+
commands: string[][] | CheckpointCommand[];
|
|
57
|
+
deps: CheckpointDeps | string[];
|
|
58
|
+
build: CheckpointBuild | null;
|
|
59
|
+
test: CheckpointTest | null;
|
|
60
|
+
buildResult?: unknown;
|
|
61
|
+
parentId?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface CreateCheckpointOptions {
|
|
64
|
+
id?: string;
|
|
65
|
+
label?: string;
|
|
66
|
+
message?: string;
|
|
67
|
+
prompt?: string;
|
|
68
|
+
files?: CheckpointFile[];
|
|
69
|
+
commands?: string[][] | CheckpointCommand[];
|
|
70
|
+
deps?: Partial<CheckpointDeps> | string[];
|
|
71
|
+
build?: CheckpointBuild | null;
|
|
72
|
+
test?: CheckpointTest | null;
|
|
73
|
+
buildResult?: unknown;
|
|
74
|
+
parentId?: string;
|
|
75
|
+
createdAt?: string;
|
|
76
|
+
timestamp?: number;
|
|
77
|
+
}
|
|
78
|
+
export interface CheckpointChanges {
|
|
79
|
+
files?: CheckpointFile[];
|
|
80
|
+
commands?: CheckpointCommand[] | string[][];
|
|
81
|
+
deps?: string[] | CheckpointDeps;
|
|
82
|
+
parentId?: string;
|
|
83
|
+
prompt?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface TransactionPreview {
|
|
86
|
+
files: CheckpointFile[];
|
|
87
|
+
commands?: CheckpointCommand[] | string[][];
|
|
88
|
+
deps?: string[] | CheckpointDeps;
|
|
89
|
+
message?: string;
|
|
90
|
+
prompt?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface TransactionOptions {
|
|
93
|
+
message: string;
|
|
94
|
+
prompt?: string;
|
|
95
|
+
parentId?: string;
|
|
96
|
+
preview: () => TransactionPreview | Promise<TransactionPreview>;
|
|
97
|
+
approve: (preview: TransactionPreview) => boolean | Promise<boolean>;
|
|
98
|
+
execute: () => {
|
|
99
|
+
files?: CheckpointFile[];
|
|
100
|
+
commands?: CheckpointCommand[] | string[][];
|
|
101
|
+
deps?: string[] | CheckpointDeps;
|
|
102
|
+
} | void | Promise<{
|
|
103
|
+
files?: CheckpointFile[];
|
|
104
|
+
commands?: CheckpointCommand[] | string[][];
|
|
105
|
+
deps?: string[] | CheckpointDeps;
|
|
106
|
+
} | void>;
|
|
107
|
+
validate?: () => unknown | Promise<unknown>;
|
|
108
|
+
}
|
|
109
|
+
export declare class CheckpointManager {
|
|
110
|
+
private store;
|
|
111
|
+
private order;
|
|
112
|
+
private readonly maxKeep;
|
|
113
|
+
constructor(opts?: {
|
|
114
|
+
maxKeep?: number;
|
|
115
|
+
});
|
|
116
|
+
create(opts?: CreateCheckpointOptions): Checkpoint;
|
|
117
|
+
list(): Checkpoint[];
|
|
118
|
+
listNewestFirst(): Checkpoint[];
|
|
119
|
+
get(id: string): Checkpoint | undefined;
|
|
120
|
+
has(id: string): boolean;
|
|
121
|
+
delete(id: string): boolean;
|
|
122
|
+
clear(): void;
|
|
123
|
+
size(): number;
|
|
124
|
+
/**
|
|
125
|
+
* Rollback plan for a checkpoint: returns the files that must be restored
|
|
126
|
+
* to their `before` state. Caller is responsible for actually writing/deleting files.
|
|
127
|
+
* Returns null if checkpoint does not exist.
|
|
128
|
+
*/
|
|
129
|
+
rollback(id: string): {
|
|
130
|
+
id: string;
|
|
131
|
+
checkpoint: Checkpoint;
|
|
132
|
+
filesToRestore: CheckpointFile[];
|
|
133
|
+
} | null;
|
|
134
|
+
/**
|
|
135
|
+
* Helper: build a rollback summary describing what filesystem actions are required.
|
|
136
|
+
*/
|
|
137
|
+
static describeRollback(files: CheckpointFile[]): {
|
|
138
|
+
writes: number;
|
|
139
|
+
deletes: number;
|
|
140
|
+
creates: number;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export declare function getAgenticDir(projectDir: string): string;
|
|
144
|
+
export declare function getHistoryPath(projectDir: string): string;
|
|
145
|
+
export declare function getCheckpointDir(projectDir: string, id: string): string;
|
|
146
|
+
export declare function getCheckpointPath(projectDir: string, id: string): string;
|
|
147
|
+
export declare function createCheckpoint(projectDir: string, message: string, changes?: CheckpointChanges, buildResult?: unknown): Checkpoint;
|
|
148
|
+
export declare function listCheckpoints(projectDir: string): Checkpoint[];
|
|
149
|
+
export declare function getCheckpoint(projectDir: string, id: string): Checkpoint | null;
|
|
150
|
+
export declare function rollback(projectDir: string, id: string): Checkpoint | null;
|
|
151
|
+
export declare function withTransaction(projectDir: string, options: TransactionOptions): Promise<Checkpoint | null>;
|
|
152
|
+
export declare function deleteCheckpoint(projectDir: string, id: string): boolean;
|
|
153
|
+
export declare function clearCheckpoints(projectDir: string): void;
|
|
154
|
+
export declare function ensureAgenticStore(projectDir: string): void;
|
|
155
|
+
//# sourceMappingURL=checkpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../src/checkpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vesk/agentic — checkpoints & transactions
|
|
3
|
+
*
|
|
4
|
+
* Zero-deps checkpoint system for agent operations.
|
|
5
|
+
*
|
|
6
|
+
* Two complementary surfaces in one module (both zero-deps):
|
|
7
|
+
*
|
|
8
|
+
* 1. `CheckpointManager` — in-memory, browser-safe manager for `Preview → Approve → Execute → Validate → Checkpoint`
|
|
9
|
+
* flows inside the agent loop. Persists only metadata; caller restores files.
|
|
10
|
+
*
|
|
11
|
+
* 2. File-system store — `createCheckpoint(projectDir, message, changes, buildResult)` and friends
|
|
12
|
+
* persisting to `<projectDir>/.vesk/agentic/history.json` + `checkpoints/{id}/checkpoint.json`.
|
|
13
|
+
* Used by `@vesk/agentic` Dev Server router (`createAgentRouter`) and `vesk.*` tools (`createVeskTools`).
|
|
14
|
+
*
|
|
15
|
+
* Both surfaces share the same unified `Checkpoint` shape (superset of manager + file-system fields)
|
|
16
|
+
* so the Dev Server router and in-memory tests interoperate without type drift.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync, unlinkSync, rmSync, renameSync } from 'node:fs';
|
|
19
|
+
import { join, resolve, dirname, sep } from 'node:path';
|
|
20
|
+
import { randomUUID as nodeRandomUUID } from 'node:crypto';
|
|
21
|
+
function generateId() {
|
|
22
|
+
// Prefer crypto.randomUUID when available (Node 19+, browsers), fallback to Math.random.
|
|
23
|
+
try {
|
|
24
|
+
const c = globalThis.crypto;
|
|
25
|
+
if (c?.randomUUID)
|
|
26
|
+
return c.randomUUID();
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
try {
|
|
30
|
+
return nodeRandomUUID();
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
return `chk_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
34
|
+
}
|
|
35
|
+
export class CheckpointManager {
|
|
36
|
+
store = new Map();
|
|
37
|
+
order = [];
|
|
38
|
+
maxKeep;
|
|
39
|
+
constructor(opts) {
|
|
40
|
+
this.maxKeep = opts?.maxKeep;
|
|
41
|
+
}
|
|
42
|
+
create(opts = {}) {
|
|
43
|
+
const id = opts.id ?? generateId();
|
|
44
|
+
const createdAt = opts.createdAt ?? new Date().toISOString();
|
|
45
|
+
const timestamp = opts.timestamp ?? (Date.parse(createdAt) || Date.now());
|
|
46
|
+
// message/label are aliases — populate both from whichever is provided
|
|
47
|
+
const rawMessage = opts.message ?? opts.label ?? '';
|
|
48
|
+
const label = opts.label ?? (rawMessage || undefined);
|
|
49
|
+
const message = rawMessage || (opts.label ?? '');
|
|
50
|
+
// Normalize deps: object {installed, removed} or string[] → union kept as-is but object is canonical for manager
|
|
51
|
+
let deps = { installed: [], removed: [] };
|
|
52
|
+
if (Array.isArray(opts.deps))
|
|
53
|
+
deps = [...opts.deps];
|
|
54
|
+
else if (opts.deps && typeof opts.deps === 'object') {
|
|
55
|
+
const d = opts.deps;
|
|
56
|
+
deps = { installed: d.installed ? [...d.installed] : [], removed: d.removed ? [...d.removed] : [] };
|
|
57
|
+
}
|
|
58
|
+
// Normalize commands: keep as provided (string[][] or CheckpointCommand[])
|
|
59
|
+
let commands = [];
|
|
60
|
+
if (Array.isArray(opts.commands)) {
|
|
61
|
+
// Detect which shape by inspecting first element
|
|
62
|
+
const first = opts.commands[0];
|
|
63
|
+
if (first && typeof first === 'object' && !Array.isArray(first) && 'argv' in first) {
|
|
64
|
+
commands = opts.commands.map((c) => ({ ...c }));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
commands = opts.commands.map((c) => [...c]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const checkpoint = {
|
|
71
|
+
id,
|
|
72
|
+
timestamp,
|
|
73
|
+
createdAt,
|
|
74
|
+
message,
|
|
75
|
+
label,
|
|
76
|
+
prompt: opts.prompt,
|
|
77
|
+
files: opts.files ? opts.files.map((f) => ({ ...f })) : [],
|
|
78
|
+
commands,
|
|
79
|
+
deps,
|
|
80
|
+
build: opts.build !== undefined ? (opts.build ? { ...opts.build } : null) : null,
|
|
81
|
+
test: opts.test !== undefined ? (opts.test ? { ...opts.test } : null) : null,
|
|
82
|
+
...(opts.buildResult !== undefined ? { buildResult: opts.buildResult } : {}),
|
|
83
|
+
...(opts.parentId ? { parentId: opts.parentId } : {}),
|
|
84
|
+
};
|
|
85
|
+
// If id already exists, remove old position (idempotent update)
|
|
86
|
+
if (this.store.has(id)) {
|
|
87
|
+
this.order = this.order.filter((x) => x !== id);
|
|
88
|
+
}
|
|
89
|
+
this.store.set(id, checkpoint);
|
|
90
|
+
this.order.push(id);
|
|
91
|
+
// Prune oldest when over maxKeep
|
|
92
|
+
if (this.maxKeep !== undefined && this.order.length > this.maxKeep) {
|
|
93
|
+
const excess = this.order.length - this.maxKeep;
|
|
94
|
+
for (let i = 0; i < excess; i++) {
|
|
95
|
+
const oldest = this.order.shift();
|
|
96
|
+
this.store.delete(oldest);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return checkpoint;
|
|
100
|
+
}
|
|
101
|
+
list() {
|
|
102
|
+
// Oldest-first (insertion order) — callers can reverse for newest-first UI.
|
|
103
|
+
return this.order.map((id) => this.store.get(id));
|
|
104
|
+
}
|
|
105
|
+
listNewestFirst() {
|
|
106
|
+
return [...this.list()].reverse();
|
|
107
|
+
}
|
|
108
|
+
get(id) {
|
|
109
|
+
return this.store.get(id);
|
|
110
|
+
}
|
|
111
|
+
has(id) {
|
|
112
|
+
return this.store.has(id);
|
|
113
|
+
}
|
|
114
|
+
delete(id) {
|
|
115
|
+
const ok = this.store.delete(id);
|
|
116
|
+
if (ok)
|
|
117
|
+
this.order = this.order.filter((x) => x !== id);
|
|
118
|
+
return ok;
|
|
119
|
+
}
|
|
120
|
+
clear() {
|
|
121
|
+
this.store.clear();
|
|
122
|
+
this.order = [];
|
|
123
|
+
}
|
|
124
|
+
size() {
|
|
125
|
+
return this.store.size;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Rollback plan for a checkpoint: returns the files that must be restored
|
|
129
|
+
* to their `before` state. Caller is responsible for actually writing/deleting files.
|
|
130
|
+
* Returns null if checkpoint does not exist.
|
|
131
|
+
*/
|
|
132
|
+
rollback(id) {
|
|
133
|
+
const cp = this.store.get(id);
|
|
134
|
+
if (!cp)
|
|
135
|
+
return null;
|
|
136
|
+
return {
|
|
137
|
+
id,
|
|
138
|
+
checkpoint: cp,
|
|
139
|
+
filesToRestore: cp.files.map((f) => ({ ...f })),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Helper: build a rollback summary describing what filesystem actions are required.
|
|
144
|
+
*/
|
|
145
|
+
static describeRollback(files) {
|
|
146
|
+
let writes = 0;
|
|
147
|
+
let deletes = 0;
|
|
148
|
+
let creates = 0;
|
|
149
|
+
for (const f of files) {
|
|
150
|
+
if (f.before === null && f.after !== null)
|
|
151
|
+
deletes++; // file was created → delete it
|
|
152
|
+
else if (f.before !== null && f.after === null)
|
|
153
|
+
creates++; // file was deleted → recreate
|
|
154
|
+
else if (f.before !== null)
|
|
155
|
+
writes++; // modified → overwrite
|
|
156
|
+
// before===null && after===null → no-op (should not happen)
|
|
157
|
+
}
|
|
158
|
+
return { writes, deletes, creates };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// ── File-system store (persisted) ────────────────────────────────────────────
|
|
162
|
+
// Mirrors the original file-system implementation (now unified with Manager's shape)
|
|
163
|
+
// so `createVeskTools` and `createAgentRouter` keep working.
|
|
164
|
+
export function getAgenticDir(projectDir) {
|
|
165
|
+
return join(resolve(projectDir), '.vesk', 'agentic');
|
|
166
|
+
}
|
|
167
|
+
export function getHistoryPath(projectDir) {
|
|
168
|
+
return join(getAgenticDir(projectDir), 'history.json');
|
|
169
|
+
}
|
|
170
|
+
export function getCheckpointDir(projectDir, id) {
|
|
171
|
+
return join(getAgenticDir(projectDir), 'checkpoints', id);
|
|
172
|
+
}
|
|
173
|
+
export function getCheckpointPath(projectDir, id) {
|
|
174
|
+
return join(getCheckpointDir(projectDir, id), 'checkpoint.json');
|
|
175
|
+
}
|
|
176
|
+
function ensureDir(dir) {
|
|
177
|
+
mkdirSync(dir, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
function readJson(filePath, fallback) {
|
|
180
|
+
try {
|
|
181
|
+
if (!existsSync(filePath))
|
|
182
|
+
return fallback;
|
|
183
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
184
|
+
if (raw.trim() === '')
|
|
185
|
+
return fallback;
|
|
186
|
+
return JSON.parse(raw);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return fallback;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function writeJsonAtomic(filePath, data) {
|
|
193
|
+
ensureDir(dirname(filePath));
|
|
194
|
+
const tmp = `${filePath}.tmp`;
|
|
195
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2), 'utf-8');
|
|
196
|
+
try {
|
|
197
|
+
renameSync(tmp, filePath);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
try {
|
|
201
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
202
|
+
try {
|
|
203
|
+
unlinkSync(tmp);
|
|
204
|
+
}
|
|
205
|
+
catch { }
|
|
206
|
+
}
|
|
207
|
+
catch { }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function readHistory(projectDir) {
|
|
211
|
+
const p = getHistoryPath(projectDir);
|
|
212
|
+
const data = readJson(p, []);
|
|
213
|
+
return Array.isArray(data) ? data : [];
|
|
214
|
+
}
|
|
215
|
+
function writeHistory(projectDir, history) {
|
|
216
|
+
writeJsonAtomic(getHistoryPath(projectDir), history);
|
|
217
|
+
}
|
|
218
|
+
export function createCheckpoint(projectDir, message, changes = {}, buildResult) {
|
|
219
|
+
const id = generateId();
|
|
220
|
+
const timestamp = Date.now();
|
|
221
|
+
const createdAt = new Date(timestamp).toISOString();
|
|
222
|
+
const files = changes.files ? changes.files.map((f) => ({ ...f })) : [];
|
|
223
|
+
// Normalize commands/deps
|
|
224
|
+
let commands = [];
|
|
225
|
+
if (changes.commands) {
|
|
226
|
+
const first = changes.commands[0];
|
|
227
|
+
if (first && typeof first === 'object' && !Array.isArray(first) && 'argv' in first) {
|
|
228
|
+
commands = changes.commands.map((c) => ({ ...c }));
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
commands = changes.commands.map((c) => [...c]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let deps = [];
|
|
235
|
+
if (Array.isArray(changes.deps))
|
|
236
|
+
deps = [...changes.deps];
|
|
237
|
+
else if (changes.deps && typeof changes.deps === 'object') {
|
|
238
|
+
const d = changes.deps;
|
|
239
|
+
deps = { installed: d.installed ? [...d.installed] : [], removed: d.removed ? [...d.removed] : [] };
|
|
240
|
+
}
|
|
241
|
+
const checkpoint = {
|
|
242
|
+
id,
|
|
243
|
+
timestamp,
|
|
244
|
+
createdAt,
|
|
245
|
+
message,
|
|
246
|
+
label: message,
|
|
247
|
+
prompt: changes.prompt,
|
|
248
|
+
files,
|
|
249
|
+
commands,
|
|
250
|
+
deps,
|
|
251
|
+
build: null,
|
|
252
|
+
test: null,
|
|
253
|
+
...(buildResult !== undefined ? { buildResult } : {}),
|
|
254
|
+
...(changes.parentId ? { parentId: changes.parentId } : {}),
|
|
255
|
+
};
|
|
256
|
+
const agenticDir = getAgenticDir(projectDir);
|
|
257
|
+
ensureDir(agenticDir);
|
|
258
|
+
ensureDir(join(agenticDir, 'checkpoints'));
|
|
259
|
+
const cpDir = getCheckpointDir(projectDir, id);
|
|
260
|
+
ensureDir(cpDir);
|
|
261
|
+
writeJsonAtomic(getCheckpointPath(projectDir, id), checkpoint);
|
|
262
|
+
const history = readHistory(projectDir);
|
|
263
|
+
history.unshift(checkpoint);
|
|
264
|
+
writeHistory(projectDir, history);
|
|
265
|
+
return checkpoint;
|
|
266
|
+
}
|
|
267
|
+
export function listCheckpoints(projectDir) {
|
|
268
|
+
const history = readHistory(projectDir);
|
|
269
|
+
return [...history].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
270
|
+
}
|
|
271
|
+
export function getCheckpoint(projectDir, id) {
|
|
272
|
+
const cpPath = getCheckpointPath(projectDir, id);
|
|
273
|
+
const fromFile = readJson(cpPath, null);
|
|
274
|
+
if (fromFile && typeof fromFile === 'object' && fromFile.id === id)
|
|
275
|
+
return fromFile;
|
|
276
|
+
const history = readHistory(projectDir);
|
|
277
|
+
return history.find((c) => c.id === id) ?? null;
|
|
278
|
+
}
|
|
279
|
+
export function rollback(projectDir, id) {
|
|
280
|
+
const cp = getCheckpoint(projectDir, id);
|
|
281
|
+
if (!cp)
|
|
282
|
+
return null;
|
|
283
|
+
const projectRoot = resolve(projectDir);
|
|
284
|
+
for (const f of cp.files) {
|
|
285
|
+
if (!f.path || !f.path.trim())
|
|
286
|
+
continue;
|
|
287
|
+
const abs = resolve(projectRoot, f.path);
|
|
288
|
+
if (f.before === null) {
|
|
289
|
+
try {
|
|
290
|
+
if (existsSync(abs)) {
|
|
291
|
+
const s = statSync(abs);
|
|
292
|
+
if (s.isDirectory())
|
|
293
|
+
rmSync(abs, { recursive: true, force: true });
|
|
294
|
+
else
|
|
295
|
+
unlinkSync(abs);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch { }
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
try {
|
|
302
|
+
ensureDir(dirname(abs));
|
|
303
|
+
writeFileSync(abs, f.before, 'utf-8');
|
|
304
|
+
}
|
|
305
|
+
catch { }
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return cp;
|
|
309
|
+
}
|
|
310
|
+
export async function withTransaction(projectDir, options) {
|
|
311
|
+
const preview = await options.preview();
|
|
312
|
+
const approved = await options.approve(preview);
|
|
313
|
+
if (!approved)
|
|
314
|
+
return null;
|
|
315
|
+
const executedRaw = await options.execute();
|
|
316
|
+
const executed = (executedRaw ?? {});
|
|
317
|
+
const files = executed.files ?? preview.files ?? [];
|
|
318
|
+
const commands = executed.commands ?? preview.commands ?? [];
|
|
319
|
+
const deps = executed.deps ?? preview.deps ?? [];
|
|
320
|
+
let buildResult;
|
|
321
|
+
if (options.validate) {
|
|
322
|
+
const v = await options.validate();
|
|
323
|
+
buildResult = typeof v === 'boolean' ? { success: v } : v;
|
|
324
|
+
}
|
|
325
|
+
let parentId = options.parentId;
|
|
326
|
+
if (!parentId) {
|
|
327
|
+
const latest = listCheckpoints(projectDir)[0];
|
|
328
|
+
if (latest)
|
|
329
|
+
parentId = latest.id;
|
|
330
|
+
}
|
|
331
|
+
const message = options.message;
|
|
332
|
+
const changes = {
|
|
333
|
+
files,
|
|
334
|
+
commands: commands,
|
|
335
|
+
deps: deps,
|
|
336
|
+
...(parentId ? { parentId } : {}),
|
|
337
|
+
...(options.prompt ? { prompt: options.prompt } : {}),
|
|
338
|
+
...(preview.prompt ? { prompt: preview.prompt } : {}),
|
|
339
|
+
};
|
|
340
|
+
return createCheckpoint(projectDir, message, changes, buildResult);
|
|
341
|
+
}
|
|
342
|
+
export function deleteCheckpoint(projectDir, id) {
|
|
343
|
+
const cpDir = getCheckpointDir(projectDir, id);
|
|
344
|
+
let existed = false;
|
|
345
|
+
try {
|
|
346
|
+
if (existsSync(cpDir)) {
|
|
347
|
+
rmSync(cpDir, { recursive: true, force: true });
|
|
348
|
+
existed = true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
catch { }
|
|
352
|
+
const history = readHistory(projectDir);
|
|
353
|
+
const next = history.filter((c) => c.id !== id);
|
|
354
|
+
if (next.length !== history.length) {
|
|
355
|
+
writeHistory(projectDir, next);
|
|
356
|
+
existed = true;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
const cpPath = getCheckpointPath(projectDir, id);
|
|
360
|
+
if (existsSync(cpPath)) {
|
|
361
|
+
try {
|
|
362
|
+
unlinkSync(cpPath);
|
|
363
|
+
}
|
|
364
|
+
catch { }
|
|
365
|
+
existed = true;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return existed;
|
|
369
|
+
}
|
|
370
|
+
export function clearCheckpoints(projectDir) {
|
|
371
|
+
const agenticDir = getAgenticDir(projectDir);
|
|
372
|
+
const historyPath = getHistoryPath(projectDir);
|
|
373
|
+
try {
|
|
374
|
+
if (existsSync(historyPath))
|
|
375
|
+
unlinkSync(historyPath);
|
|
376
|
+
}
|
|
377
|
+
catch { }
|
|
378
|
+
const checkpointsRoot = join(agenticDir, 'checkpoints');
|
|
379
|
+
try {
|
|
380
|
+
if (existsSync(checkpointsRoot))
|
|
381
|
+
rmSync(checkpointsRoot, { recursive: true, force: true });
|
|
382
|
+
}
|
|
383
|
+
catch { }
|
|
384
|
+
}
|
|
385
|
+
export function ensureAgenticStore(projectDir) {
|
|
386
|
+
const dir = getAgenticDir(projectDir);
|
|
387
|
+
ensureDir(dir);
|
|
388
|
+
ensureDir(join(dir, 'checkpoints'));
|
|
389
|
+
const hp = getHistoryPath(projectDir);
|
|
390
|
+
if (!existsSync(hp))
|
|
391
|
+
writeJsonAtomic(hp, []);
|
|
392
|
+
}
|
|
393
|
+
// Ensure sep is used (avoid unused import warning)
|
|
394
|
+
void sep;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface AgenticConfig {
|
|
2
|
+
provider: 'openai' | 'anthropic' | 'google' | 'ollama' | 'opencode' | 'opencode-go' | 'openrouter' | 'loopers' | 'custom';
|
|
3
|
+
model: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
mode: 'explore' | 'debug' | 'agent';
|
|
6
|
+
maxSteps: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const SUPPORTED_PROVIDERS: string[];
|
|
9
|
+
export declare function providerDotenvVar(provider: string): string;
|
|
10
|
+
export declare function dotenvPath(projectDir: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Read a provider key from the project `.env.local` file.
|
|
13
|
+
* Note: normally `process.env` already reflects `.env.local` (loaded at CLI
|
|
14
|
+
* startup); this reads the file directly as a defensive fallback (e.g. when
|
|
15
|
+
* the file changed after startup, or callers didn't go through loadEnvFiles).
|
|
16
|
+
*/
|
|
17
|
+
export declare function readDotenvValue(projectDir: string, key: string, def?: string | null): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Set a `KEY=VALUE` line in the project `.env.local`, creating the file if
|
|
20
|
+
* missing, updating in place if present. Also mirrors into `process.env` so
|
|
21
|
+
* the current process sees it immediately. Returns true on success.
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeDotenvValue(projectDir: string, key: string, value: string): boolean;
|
|
24
|
+
export declare function loadAgenticConfig(projectDir: string): AgenticConfig & {
|
|
25
|
+
hasKey: boolean;
|
|
26
|
+
};
|
|
27
|
+
export declare function saveAgenticConfig(projectDir: string, patch: Partial<AgenticConfig>): AgenticConfig;
|
|
28
|
+
export declare function maskApiKey(apiKey: string | null | undefined): string | null;
|
|
29
|
+
export declare const maskKey: typeof maskApiKey;
|
|
30
|
+
export declare const maskedPreview: typeof maskApiKey;
|
|
31
|
+
export declare function getMaskedKey(projectDir: string, provider: string): string | null;
|
|
32
|
+
export declare function getApiKeyPreview(projectDir: string, provider: string): string | null;
|
|
33
|
+
export declare function getMaskedPreview(projectDir: string, provider: string): string | null;
|
|
34
|
+
export declare function getKeyPreview(projectDir: string, provider: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Save an API key for a specific provider.
|
|
37
|
+
*
|
|
38
|
+
* Supports both new 3-arg form `saveApiKey(projectDir, provider, apiKey)`
|
|
39
|
+
* and legacy 2-arg form `saveApiKey(projectDir, apiKey)` for backward compat.
|
|
40
|
+
* Keys are stored in project `.env.local` as VK_{PROVIDER}_KEY (0600).
|
|
41
|
+
* The legacy 2-arg form targets the currently-configured provider.
|
|
42
|
+
*/
|
|
43
|
+
export declare function saveApiKey(projectDir: string, providerOrApiKey: string, apiKeyMaybe?: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get API key for a provider.
|
|
46
|
+
* Precedence:
|
|
47
|
+
* 1. .env.local VK_{PROVIDER}_KEY (primary store; reflected in process.env)
|
|
48
|
+
* 2. (fallback) legacy .vesk/agentic/keys/{provider}.key
|
|
49
|
+
* If `provider` is omitted, returns the key for the currently-configured
|
|
50
|
+
* provider, else null.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getApiKey(projectDir: string, provider?: string): string | null;
|
|
53
|
+
export declare function hasApiKey(projectDirOrProvider: string, providerMaybe?: string): boolean;
|
|
54
|
+
export declare const hasKey: typeof hasApiKey;
|
|
55
|
+
export declare const hasApiKeys: typeof hasApiKey;
|
|
56
|
+
export declare function listApiKeys(projectDir: string): Record<string, boolean>;
|
|
57
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1H,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AASD,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAGvC,CAAC;AAkCF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI1D;AACD,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,GAAG,IAAI,CAmBzG;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA4BxF;AAMD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAYzF;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CASlG;AAMD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM3E;AAGD,eAAO,MAAM,OAAO,mBAAa,CAAC;AAClC,eAAO,MAAM,aAAa,mBAAa,CAAC;AACxC,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhF;AACD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpF;AACD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpF;AACD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKjF;AA2BD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAyBnG;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4B9E;AAID,wBAAgB,SAAS,CAAC,oBAAoB,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAmCvF;AAGD,eAAO,MAAM,MAAM,kBAAY,CAAC;AAEhC,eAAO,MAAM,UAAU,kBAAY,CAAC;AAIpC,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsCvE"}
|