nex-code 0.3.5 → 0.3.7
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 +23 -1
- package/dist/bundle.js +505 -0
- package/dist/nex-code.js +485 -0
- package/package.json +8 -6
- package/bin/nex-code.js +0 -99
- package/cli/agent.js +0 -835
- package/cli/compactor.js +0 -85
- package/cli/context-engine.js +0 -507
- package/cli/context.js +0 -98
- package/cli/costs.js +0 -290
- package/cli/diff.js +0 -366
- package/cli/file-history.js +0 -94
- package/cli/format.js +0 -211
- package/cli/fuzzy-match.js +0 -270
- package/cli/git.js +0 -211
- package/cli/hooks.js +0 -173
- package/cli/index.js +0 -1289
- package/cli/mcp.js +0 -284
- package/cli/memory.js +0 -170
- package/cli/ollama.js +0 -130
- package/cli/permissions.js +0 -124
- package/cli/picker.js +0 -201
- package/cli/planner.js +0 -282
- package/cli/providers/anthropic.js +0 -333
- package/cli/providers/base.js +0 -116
- package/cli/providers/gemini.js +0 -239
- package/cli/providers/local.js +0 -249
- package/cli/providers/ollama.js +0 -228
- package/cli/providers/openai.js +0 -237
- package/cli/providers/registry.js +0 -454
- package/cli/render.js +0 -495
- package/cli/safety.js +0 -241
- package/cli/session.js +0 -133
- package/cli/skills.js +0 -412
- package/cli/spinner.js +0 -371
- package/cli/sub-agent.js +0 -441
- package/cli/tasks.js +0 -179
- package/cli/tool-tiers.js +0 -164
- package/cli/tool-validator.js +0 -138
- package/cli/tools.js +0 -1050
- package/cli/ui.js +0 -93
package/cli/picker.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* cli/picker.js — Interactive Terminal Picker
|
|
3
|
-
* Generic cursor-based list picker for terminal UIs.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { C } = require('./ui');
|
|
7
|
-
const { listProviders, getActiveProviderName, getActiveModelId, setActiveModel } = require('./providers/registry');
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Generic interactive list picker.
|
|
11
|
-
* @param {readline.Interface} rl - readline instance (will be paused during pick)
|
|
12
|
-
* @param {Array<{ label: string, value: string|null, isHeader?: boolean, isCurrent?: boolean }>} items
|
|
13
|
-
* @param {object} [options]
|
|
14
|
-
* @param {string} [options.title] - Title shown above the list
|
|
15
|
-
* @param {string} [options.hint] - Hint shown below title
|
|
16
|
-
* @returns {Promise<string|null>} selected value or null if cancelled
|
|
17
|
-
*/
|
|
18
|
-
function pickFromList(rl, items, options = {}) {
|
|
19
|
-
const { title = 'Select', hint = '\u2191\u2193 navigate \u00b7 Enter select \u00b7 Esc cancel' } = options;
|
|
20
|
-
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
// Find selectable items (non-headers)
|
|
23
|
-
const selectableIndices = items
|
|
24
|
-
.map((item, i) => (item.isHeader ? -1 : i))
|
|
25
|
-
.filter((i) => i >= 0);
|
|
26
|
-
|
|
27
|
-
if (selectableIndices.length === 0) {
|
|
28
|
-
resolve(null);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Start cursor at current item, or first selectable
|
|
33
|
-
const currentIdx = items.findIndex((item) => item.isCurrent);
|
|
34
|
-
let cursor = currentIdx >= 0 ? selectableIndices.indexOf(currentIdx) : 0;
|
|
35
|
-
if (cursor < 0) cursor = 0;
|
|
36
|
-
|
|
37
|
-
// Calculate visible window for scrolling
|
|
38
|
-
const maxVisible = process.stdout.rows ? Math.max(process.stdout.rows - 6, 5) : 20;
|
|
39
|
-
let scrollOffset = 0;
|
|
40
|
-
|
|
41
|
-
function getVisibleRange() {
|
|
42
|
-
// Ensure cursor is visible
|
|
43
|
-
const cursorItemIdx = selectableIndices[cursor];
|
|
44
|
-
if (cursorItemIdx < scrollOffset) {
|
|
45
|
-
scrollOffset = cursorItemIdx;
|
|
46
|
-
} else if (cursorItemIdx >= scrollOffset + maxVisible) {
|
|
47
|
-
scrollOffset = cursorItemIdx - maxVisible + 1;
|
|
48
|
-
}
|
|
49
|
-
return { start: scrollOffset, end: Math.min(items.length, scrollOffset + maxVisible) };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let renderedLines = 0;
|
|
53
|
-
|
|
54
|
-
function render() {
|
|
55
|
-
// Clear previous render
|
|
56
|
-
if (renderedLines > 0) {
|
|
57
|
-
process.stdout.write(`\x1b[${renderedLines}A`);
|
|
58
|
-
for (let i = 0; i < renderedLines; i++) {
|
|
59
|
-
process.stdout.write('\x1b[2K\n');
|
|
60
|
-
}
|
|
61
|
-
process.stdout.write(`\x1b[${renderedLines}A`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const lines = [];
|
|
65
|
-
lines.push(` ${C.bold}${C.cyan}${title}${C.reset}`);
|
|
66
|
-
lines.push(` ${C.dim}${hint}${C.reset}`);
|
|
67
|
-
lines.push('');
|
|
68
|
-
|
|
69
|
-
const { start, end } = getVisibleRange();
|
|
70
|
-
|
|
71
|
-
if (start > 0) {
|
|
72
|
-
lines.push(` ${C.dim}\u2191 more${C.reset}`);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
for (let i = start; i < end; i++) {
|
|
76
|
-
const item = items[i];
|
|
77
|
-
if (item.isHeader) {
|
|
78
|
-
lines.push(` ${C.bold}${C.dim}${item.label}${C.reset}`);
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const isSelected = selectableIndices[cursor] === i;
|
|
83
|
-
const pointer = isSelected ? `${C.cyan}> ` : ' ';
|
|
84
|
-
const currentTag = item.isCurrent ? ` ${C.yellow}<current>${C.reset}` : '';
|
|
85
|
-
|
|
86
|
-
if (isSelected) {
|
|
87
|
-
lines.push(`${pointer}${C.bold}${item.label}${C.reset}${currentTag}`);
|
|
88
|
-
} else {
|
|
89
|
-
lines.push(`${pointer}${C.dim}${item.label}${C.reset}${currentTag}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (end < items.length) {
|
|
94
|
-
lines.push(` ${C.dim}\u2193 more${C.reset}`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const output = lines.join('\n');
|
|
98
|
-
process.stdout.write(output + '\n');
|
|
99
|
-
renderedLines = lines.length;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Pause readline, take over stdin
|
|
103
|
-
rl.pause();
|
|
104
|
-
const wasRaw = process.stdin.isRaw;
|
|
105
|
-
if (process.stdin.isTTY) {
|
|
106
|
-
process.stdin.setRawMode(true);
|
|
107
|
-
}
|
|
108
|
-
process.stdin.resume();
|
|
109
|
-
|
|
110
|
-
function cleanup() {
|
|
111
|
-
process.stdin.removeListener('keypress', onKeypress);
|
|
112
|
-
if (process.stdin.isTTY && wasRaw !== undefined) {
|
|
113
|
-
process.stdin.setRawMode(wasRaw);
|
|
114
|
-
}
|
|
115
|
-
rl.resume();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function onKeypress(str, key) {
|
|
119
|
-
if (!key) return;
|
|
120
|
-
|
|
121
|
-
if (key.name === 'up' || (key.ctrl && key.name === 'p')) {
|
|
122
|
-
if (cursor > 0) {
|
|
123
|
-
cursor--;
|
|
124
|
-
render();
|
|
125
|
-
}
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (key.name === 'down' || (key.ctrl && key.name === 'n')) {
|
|
130
|
-
if (cursor < selectableIndices.length - 1) {
|
|
131
|
-
cursor++;
|
|
132
|
-
render();
|
|
133
|
-
}
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (key.name === 'return') {
|
|
138
|
-
const selectedItem = items[selectableIndices[cursor]];
|
|
139
|
-
cleanup();
|
|
140
|
-
resolve(selectedItem ? selectedItem.value : null);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (key.name === 'escape' || (key.ctrl && key.name === 'c')) {
|
|
145
|
-
cleanup();
|
|
146
|
-
resolve(null);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
process.stdin.on('keypress', onKeypress);
|
|
152
|
-
render();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Show the model picker and handle selection.
|
|
158
|
-
* @param {readline.Interface} rl
|
|
159
|
-
* @returns {Promise<boolean>} true if model was selected
|
|
160
|
-
*/
|
|
161
|
-
async function showModelPicker(rl) {
|
|
162
|
-
const providerList = listProviders();
|
|
163
|
-
const activeProvider = getActiveProviderName();
|
|
164
|
-
const activeModel = getActiveModelId();
|
|
165
|
-
|
|
166
|
-
// Build picker items: provider headers + model entries
|
|
167
|
-
const items = [];
|
|
168
|
-
for (const p of providerList) {
|
|
169
|
-
if (p.models.length === 0) continue;
|
|
170
|
-
|
|
171
|
-
items.push({
|
|
172
|
-
label: p.provider,
|
|
173
|
-
value: null,
|
|
174
|
-
isHeader: true,
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
for (const m of p.models) {
|
|
178
|
-
const isCurrent = p.provider === activeProvider && m.id === activeModel;
|
|
179
|
-
items.push({
|
|
180
|
-
label: ` ${m.name} (${p.provider}:${m.id})`,
|
|
181
|
-
value: `${p.provider}:${m.id}`,
|
|
182
|
-
isCurrent,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const selected = await pickFromList(rl, items, {
|
|
188
|
-
title: 'Select Model',
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
if (selected) {
|
|
192
|
-
setActiveModel(selected);
|
|
193
|
-
console.log(`${C.green}Switched to ${selected}${C.reset}`);
|
|
194
|
-
return true;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
console.log(`${C.dim}Cancelled${C.reset}`);
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
module.exports = { pickFromList, showModelPicker };
|
package/cli/planner.js
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* cli/planner.js — Plan Mode
|
|
3
|
-
* Structured planning workflow: analyze → plan → approve → execute
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const readline = require('readline');
|
|
9
|
-
const { C } = require('./ui');
|
|
10
|
-
|
|
11
|
-
// Plan state
|
|
12
|
-
let activePlan = null;
|
|
13
|
-
let planMode = false;
|
|
14
|
-
|
|
15
|
-
function getPlanDir() {
|
|
16
|
-
return path.join(process.cwd(), '.nex', 'plans');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function ensureDir() {
|
|
20
|
-
const dir = getPlanDir();
|
|
21
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @typedef {object} PlanStep
|
|
26
|
-
* @property {string} description
|
|
27
|
-
* @property {string[]} files — affected files
|
|
28
|
-
* @property {'pending'|'in_progress'|'done'|'skipped'} status
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @typedef {object} Plan
|
|
33
|
-
* @property {string} name
|
|
34
|
-
* @property {string} task — original task description
|
|
35
|
-
* @property {PlanStep[]} steps
|
|
36
|
-
* @property {'draft'|'approved'|'executing'|'completed'} status
|
|
37
|
-
* @property {string} createdAt
|
|
38
|
-
* @property {string} [updatedAt]
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Create a new plan
|
|
43
|
-
* @param {string} task
|
|
44
|
-
* @param {PlanStep[]} steps
|
|
45
|
-
* @returns {Plan}
|
|
46
|
-
*/
|
|
47
|
-
function createPlan(task, steps = []) {
|
|
48
|
-
activePlan = {
|
|
49
|
-
name: `plan-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
50
|
-
task,
|
|
51
|
-
steps: steps.map((s) => ({
|
|
52
|
-
description: s.description || s,
|
|
53
|
-
files: s.files || [],
|
|
54
|
-
status: 'pending',
|
|
55
|
-
})),
|
|
56
|
-
status: 'draft',
|
|
57
|
-
createdAt: new Date().toISOString(),
|
|
58
|
-
};
|
|
59
|
-
return activePlan;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get the active plan
|
|
64
|
-
* @returns {Plan|null}
|
|
65
|
-
*/
|
|
66
|
-
function getActivePlan() {
|
|
67
|
-
return activePlan;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Set plan mode on/off
|
|
72
|
-
*/
|
|
73
|
-
function setPlanMode(enabled) {
|
|
74
|
-
planMode = enabled;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Check if plan mode is active
|
|
79
|
-
*/
|
|
80
|
-
function isPlanMode() {
|
|
81
|
-
return planMode;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Approve the current plan
|
|
86
|
-
* @returns {boolean}
|
|
87
|
-
*/
|
|
88
|
-
function approvePlan() {
|
|
89
|
-
if (!activePlan || activePlan.status !== 'draft') return false;
|
|
90
|
-
activePlan.status = 'approved';
|
|
91
|
-
activePlan.updatedAt = new Date().toISOString();
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Start executing the plan
|
|
97
|
-
*/
|
|
98
|
-
function startExecution() {
|
|
99
|
-
if (!activePlan || activePlan.status !== 'approved') return false;
|
|
100
|
-
activePlan.status = 'executing';
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Update step status
|
|
106
|
-
* @param {number} index
|
|
107
|
-
* @param {'pending'|'in_progress'|'done'|'skipped'} status
|
|
108
|
-
*/
|
|
109
|
-
function updateStep(index, status) {
|
|
110
|
-
if (!activePlan || index < 0 || index >= activePlan.steps.length) return false;
|
|
111
|
-
activePlan.steps[index].status = status;
|
|
112
|
-
activePlan.updatedAt = new Date().toISOString();
|
|
113
|
-
|
|
114
|
-
// Check if all steps are done
|
|
115
|
-
if (activePlan.steps.every((s) => s.status === 'done' || s.status === 'skipped')) {
|
|
116
|
-
activePlan.status = 'completed';
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Format plan for display
|
|
123
|
-
* @param {Plan} plan
|
|
124
|
-
* @returns {string}
|
|
125
|
-
*/
|
|
126
|
-
function formatPlan(plan) {
|
|
127
|
-
if (!plan) return `${C.dim}No active plan${C.reset}`;
|
|
128
|
-
|
|
129
|
-
const statusIcon = {
|
|
130
|
-
draft: `${C.yellow}DRAFT${C.reset}`,
|
|
131
|
-
approved: `${C.green}APPROVED${C.reset}`,
|
|
132
|
-
executing: `${C.blue}EXECUTING${C.reset}`,
|
|
133
|
-
completed: `${C.green}COMPLETED${C.reset}`,
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const lines = [];
|
|
137
|
-
lines.push(`\n${C.bold}${C.cyan}Plan: ${plan.task}${C.reset}`);
|
|
138
|
-
lines.push(`${C.dim}Status: ${statusIcon[plan.status] || plan.status}${C.reset}\n`);
|
|
139
|
-
|
|
140
|
-
for (let i = 0; i < plan.steps.length; i++) {
|
|
141
|
-
const step = plan.steps[i];
|
|
142
|
-
let icon;
|
|
143
|
-
switch (step.status) {
|
|
144
|
-
case 'done': icon = `${C.green}✓${C.reset}`; break;
|
|
145
|
-
case 'in_progress': icon = `${C.blue}→${C.reset}`; break;
|
|
146
|
-
case 'skipped': icon = `${C.dim}○${C.reset}`; break;
|
|
147
|
-
default: icon = `${C.dim} ${C.reset}`;
|
|
148
|
-
}
|
|
149
|
-
lines.push(` ${icon} ${C.bold}Step ${i + 1}:${C.reset} ${step.description}`);
|
|
150
|
-
if (step.files.length > 0) {
|
|
151
|
-
lines.push(` ${C.dim}Files: ${step.files.join(', ')}${C.reset}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
lines.push('');
|
|
155
|
-
return lines.join('\n');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Save plan to .nex/plans/
|
|
160
|
-
*/
|
|
161
|
-
function savePlan(plan) {
|
|
162
|
-
if (!plan) plan = activePlan;
|
|
163
|
-
if (!plan) return null;
|
|
164
|
-
ensureDir();
|
|
165
|
-
const filePath = path.join(getPlanDir(), `${plan.name}.json`);
|
|
166
|
-
fs.writeFileSync(filePath, JSON.stringify(plan, null, 2), 'utf-8');
|
|
167
|
-
return filePath;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Load a plan from disk
|
|
172
|
-
*/
|
|
173
|
-
function loadPlan(name) {
|
|
174
|
-
const filePath = path.join(getPlanDir(), `${name}.json`);
|
|
175
|
-
if (!fs.existsSync(filePath)) return null;
|
|
176
|
-
try {
|
|
177
|
-
const plan = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
178
|
-
activePlan = plan;
|
|
179
|
-
return plan;
|
|
180
|
-
} catch {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* List all saved plans
|
|
187
|
-
*/
|
|
188
|
-
function listPlans() {
|
|
189
|
-
ensureDir();
|
|
190
|
-
const dir = getPlanDir();
|
|
191
|
-
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'));
|
|
192
|
-
const plans = [];
|
|
193
|
-
for (const f of files) {
|
|
194
|
-
try {
|
|
195
|
-
const data = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf-8'));
|
|
196
|
-
plans.push({
|
|
197
|
-
name: data.name,
|
|
198
|
-
task: data.task,
|
|
199
|
-
status: data.status,
|
|
200
|
-
steps: data.steps ? data.steps.length : 0,
|
|
201
|
-
createdAt: data.createdAt,
|
|
202
|
-
});
|
|
203
|
-
} catch {
|
|
204
|
-
// skip corrupt
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return plans.sort((a, b) => (b.createdAt || '').localeCompare(a.createdAt || ''));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Clear the active plan
|
|
212
|
-
*/
|
|
213
|
-
function clearPlan() {
|
|
214
|
-
activePlan = null;
|
|
215
|
-
planMode = false;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Get plan-mode system prompt addition
|
|
220
|
-
* Instructs the LLM to only analyze and plan, not execute
|
|
221
|
-
*/
|
|
222
|
-
function getPlanModePrompt() {
|
|
223
|
-
return `
|
|
224
|
-
PLAN MODE ACTIVE: You are in analysis-only mode.
|
|
225
|
-
|
|
226
|
-
# Restrictions
|
|
227
|
-
- Use ONLY read operations: read_file, list_directory, search_files, glob, grep
|
|
228
|
-
- DO NOT modify any files (no write_file, edit_file, patch_file, bash with write ops)
|
|
229
|
-
|
|
230
|
-
# Analysis Phase
|
|
231
|
-
Investigate before planning:
|
|
232
|
-
- Scope: What files and modules are affected?
|
|
233
|
-
- Architecture: How does the current code work? What patterns does it follow?
|
|
234
|
-
- Dependencies: What depends on the code being changed? What might break?
|
|
235
|
-
- Tests: What test coverage exists? What new tests are needed?
|
|
236
|
-
|
|
237
|
-
# Plan Output Format
|
|
238
|
-
For each step, provide:
|
|
239
|
-
- **What**: Clear description of the change
|
|
240
|
-
- **Where**: Specific files and line ranges
|
|
241
|
-
- **How**: Implementation approach (edit, create, delete)
|
|
242
|
-
- **Risk**: What could go wrong and how to mitigate
|
|
243
|
-
|
|
244
|
-
# Rules
|
|
245
|
-
- Order steps by dependency — later steps can depend on earlier ones, not vice versa.
|
|
246
|
-
- Flag steps that need tests and specify what to test.
|
|
247
|
-
- List any assumptions you're making about the codebase.
|
|
248
|
-
- Present the plan to the user and wait for explicit "approve" before executing.`;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Autonomy levels
|
|
252
|
-
const AUTONOMY_LEVELS = ['interactive', 'semi-auto', 'autonomous'];
|
|
253
|
-
let autonomyLevel = 'interactive';
|
|
254
|
-
|
|
255
|
-
function setAutonomyLevel(level) {
|
|
256
|
-
if (!AUTONOMY_LEVELS.includes(level)) return false;
|
|
257
|
-
autonomyLevel = level;
|
|
258
|
-
return true;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function getAutonomyLevel() {
|
|
262
|
-
return autonomyLevel;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
module.exports = {
|
|
266
|
-
createPlan,
|
|
267
|
-
getActivePlan,
|
|
268
|
-
setPlanMode,
|
|
269
|
-
isPlanMode,
|
|
270
|
-
approvePlan,
|
|
271
|
-
startExecution,
|
|
272
|
-
updateStep,
|
|
273
|
-
formatPlan,
|
|
274
|
-
savePlan,
|
|
275
|
-
loadPlan,
|
|
276
|
-
listPlans,
|
|
277
|
-
clearPlan,
|
|
278
|
-
getPlanModePrompt,
|
|
279
|
-
setAutonomyLevel,
|
|
280
|
-
getAutonomyLevel,
|
|
281
|
-
AUTONOMY_LEVELS,
|
|
282
|
-
};
|