@agent-api/cli 0.2.0 → 0.2.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/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const cliName = "agent-tui";
|
|
2
2
|
export declare const cliAuthor = "AgentsWay";
|
|
3
|
-
export declare const cliVersion = "0.2.
|
|
3
|
+
export declare const cliVersion = "0.2.1";
|
|
4
4
|
export declare const runtime: import("@agent-api/sdk/local").LocalRuntime;
|
|
5
5
|
export declare function ensureRuntime(): Promise<import("@agent-api/sdk/local").LocalRuntime>;
|
package/dist/runtime/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { cp, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promis
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
export const cliName = "agent-tui";
|
|
5
5
|
export const cliAuthor = "AgentsWay";
|
|
6
|
-
export const cliVersion = "0.2.
|
|
6
|
+
export const cliVersion = "0.2.1";
|
|
7
7
|
const legacyCliName = "agent-api-cli";
|
|
8
8
|
export const runtime = createLocalRuntime({
|
|
9
9
|
appName: cliName,
|
|
@@ -22,14 +22,20 @@ export async function ensureRuntime() {
|
|
|
22
22
|
return runtime;
|
|
23
23
|
}
|
|
24
24
|
async function migrateLegacyRuntime() {
|
|
25
|
-
|
|
25
|
+
await migrateLegacyConfigDirectory();
|
|
26
|
+
for (const key of ["data", "cache", "logs"]) {
|
|
26
27
|
await moveDirectoryIfNeeded(legacyRuntime.dirs[key], runtime.dirs[key]);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
async function moveDirectoryIfNeeded(from, to) {
|
|
30
|
-
if (from === to || !(await isDirectory(from))
|
|
31
|
+
if (from === to || !(await isDirectory(from)))
|
|
31
32
|
return;
|
|
32
33
|
await mkdir(path.dirname(to), { recursive: true });
|
|
34
|
+
if (await pathExists(to)) {
|
|
35
|
+
await cp(from, to, { recursive: true, errorOnExist: false, force: false });
|
|
36
|
+
await rm(from, { recursive: true, force: true });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
33
39
|
try {
|
|
34
40
|
await rename(from, to);
|
|
35
41
|
}
|
|
@@ -40,6 +46,39 @@ async function moveDirectoryIfNeeded(from, to) {
|
|
|
40
46
|
await rm(from, { recursive: true, force: true });
|
|
41
47
|
}
|
|
42
48
|
}
|
|
49
|
+
async function migrateLegacyConfigDirectory() {
|
|
50
|
+
const from = legacyRuntime.dirs.config;
|
|
51
|
+
const to = runtime.dirs.config;
|
|
52
|
+
if (from === to || !(await isDirectory(from)))
|
|
53
|
+
return;
|
|
54
|
+
await mkdir(to, { recursive: true });
|
|
55
|
+
const legacyProfilesPath = path.join(from, "profiles.json");
|
|
56
|
+
const profilesPath = path.join(to, "profiles.json");
|
|
57
|
+
const legacyRaw = await readJSONRecord(legacyProfilesPath);
|
|
58
|
+
if (legacyRaw) {
|
|
59
|
+
const nextRaw = await readJSONRecord(profilesPath) ?? {};
|
|
60
|
+
const legacyProfiles = recordValue(legacyRaw.profiles);
|
|
61
|
+
const nextProfiles = recordValue(nextRaw.profiles);
|
|
62
|
+
const mergedProfiles = { ...legacyProfiles, ...nextProfiles };
|
|
63
|
+
const activeProfile = typeof nextRaw.activeProfile === "string"
|
|
64
|
+
? nextRaw.activeProfile
|
|
65
|
+
: typeof legacyRaw.activeProfile === "string"
|
|
66
|
+
? legacyRaw.activeProfile
|
|
67
|
+
: "default";
|
|
68
|
+
await writeJSON(profilesPath, { ...nextRaw, activeProfile, profiles: mergedProfiles });
|
|
69
|
+
const configurationPath = path.join(to, "configuration.json");
|
|
70
|
+
if ("workbench" in legacyRaw && !(await pathExists(configurationPath))) {
|
|
71
|
+
await writeJSON(configurationPath, { workbench: recordValue(legacyRaw.workbench) });
|
|
72
|
+
}
|
|
73
|
+
const conversationsPath = path.join(to, "conversations.json");
|
|
74
|
+
if ("conversations" in legacyRaw && !(await pathExists(conversationsPath))) {
|
|
75
|
+
await writeJSON(conversationsPath, { conversations: recordValue(legacyRaw.conversations) });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await copyFileIfMissing(path.join(from, "configuration.json"), path.join(to, "configuration.json"));
|
|
79
|
+
await copyFileIfMissing(path.join(from, "conversations.json"), path.join(to, "conversations.json"));
|
|
80
|
+
await rm(from, { recursive: true, force: true });
|
|
81
|
+
}
|
|
43
82
|
async function splitMonolithicConfig() {
|
|
44
83
|
const profilesPath = path.join(runtime.dirs.config, "profiles.json");
|
|
45
84
|
const raw = await readJSONRecord(profilesPath);
|
|
@@ -66,6 +105,9 @@ async function splitMonolithicConfig() {
|
|
|
66
105
|
await writeJSON(profilesPath, raw);
|
|
67
106
|
}
|
|
68
107
|
}
|
|
108
|
+
function recordValue(value) {
|
|
109
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
110
|
+
}
|
|
69
111
|
async function readJSONRecord(file) {
|
|
70
112
|
try {
|
|
71
113
|
const value = JSON.parse(await readFile(file, "utf8"));
|
|
@@ -81,6 +123,12 @@ async function writeJSON(file, value) {
|
|
|
81
123
|
await mkdir(path.dirname(file), { recursive: true });
|
|
82
124
|
await writeFile(file, `${JSON.stringify(value, null, 2)}\n`);
|
|
83
125
|
}
|
|
126
|
+
async function copyFileIfMissing(from, to) {
|
|
127
|
+
if (!(await pathExists(from)) || await pathExists(to))
|
|
128
|
+
return;
|
|
129
|
+
await mkdir(path.dirname(to), { recursive: true });
|
|
130
|
+
await cp(from, to, { errorOnExist: true, force: false });
|
|
131
|
+
}
|
|
84
132
|
async function pathExists(file) {
|
|
85
133
|
try {
|
|
86
134
|
await stat(file);
|
package/dist/tui/ink/app.js
CHANGED
|
@@ -188,6 +188,10 @@ function WorkbenchApp({ authController, onLogin, onLogout, onDeleteProfile, onSw
|
|
|
188
188
|
if (settings.activity) {
|
|
189
189
|
dispatch({ type: "activity.add", level: "success", text: settings.activity });
|
|
190
190
|
}
|
|
191
|
+
if (settings.notice) {
|
|
192
|
+
dispatch({ type: "message.add", role: "system", text: settings.notice });
|
|
193
|
+
dispatch({ type: "activity.add", level: "warning", text: "Shell isolation setup is not configured" });
|
|
194
|
+
}
|
|
191
195
|
if (settings.warning) {
|
|
192
196
|
dispatch({ type: "activity.add", level: "warning", text: settings.warning });
|
|
193
197
|
}
|
|
@@ -17,6 +17,7 @@ export function createWorkbenchSettingsController(options = {}) {
|
|
|
17
17
|
defaultPreset: preferences.defaultPreset,
|
|
18
18
|
...(preferences.isolation ? { shellIsolation: preferences.isolation } : {}),
|
|
19
19
|
...(activity ? { activity } : {}),
|
|
20
|
+
...(isolatorSetupNotice(preferences.isolation) ? { notice: isolatorSetupNotice(preferences.isolation) } : {}),
|
|
20
21
|
...(warning ? { warning } : {}),
|
|
21
22
|
runPreset: shouldApplyDefaultPreset(agentOptions)
|
|
22
23
|
? effectiveDefaultPreset(preferences, agentOptions.preset)
|
|
@@ -25,7 +26,12 @@ export function createWorkbenchSettingsController(options = {}) {
|
|
|
25
26
|
},
|
|
26
27
|
async saveShellIsolationMode(value) {
|
|
27
28
|
const mode = normalizeShellIsolationMode(value);
|
|
28
|
-
const preferences = await updateWorkbenchPreferencesImpl({
|
|
29
|
+
const preferences = await updateWorkbenchPreferencesImpl({
|
|
30
|
+
isolation: {
|
|
31
|
+
mode,
|
|
32
|
+
installSkipped: mode === "none" ? true : false,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
29
35
|
return {
|
|
30
36
|
...settingsSnapshot(preferences),
|
|
31
37
|
message: `Saved shell isolation mode: ${formatShellIsolation(preferences.isolation)}.`,
|
|
@@ -254,6 +260,21 @@ function userFacingError(error) {
|
|
|
254
260
|
return error.message;
|
|
255
261
|
return String(error);
|
|
256
262
|
}
|
|
263
|
+
function isolatorSetupNotice(shellIsolation) {
|
|
264
|
+
if (process.env.AGENT_ISOLATOR_PATH)
|
|
265
|
+
return "";
|
|
266
|
+
if (shellIsolation?.installSkipped || shellIsolation?.mode === "none" || shellIsolation?.executablePath)
|
|
267
|
+
return "";
|
|
268
|
+
return [
|
|
269
|
+
"Local shell isolation is not configured yet.",
|
|
270
|
+
"",
|
|
271
|
+
"To enable it, set a verified target path and downloadable source URL:",
|
|
272
|
+
"/config isolator path <absolute-path>",
|
|
273
|
+
"/config isolator source <https-url>",
|
|
274
|
+
"",
|
|
275
|
+
"To skip this setup for future starts, use /config isolation none.",
|
|
276
|
+
].join("\n");
|
|
277
|
+
}
|
|
257
278
|
async function reconcileConfiguredIsolator(preferences, updatePreferences, installOptions, formatError) {
|
|
258
279
|
const isolation = preferences.isolation;
|
|
259
280
|
if (!isolation?.sourceURL || !isolation.executablePath)
|