@oh-my-pi/pi-coding-agent 11.0.3 → 11.2.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 +199 -49
- package/README.md +1 -1
- package/docs/config-usage.md +3 -4
- package/docs/sdk.md +6 -5
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
- package/examples/sdk/README.md +1 -1
- package/package.json +19 -11
- package/src/cli/args.ts +11 -94
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/oclif-help.ts +26 -0
- package/src/cli/web-search-cli.ts +148 -0
- package/src/cli.ts +8 -2
- package/src/commands/commit.ts +36 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/grep.ts +41 -0
- package/src/commands/index/index.ts +136 -0
- package/src/commands/jupyter.ts +32 -0
- package/src/commands/plugin.ts +70 -0
- package/src/commands/setup.ts +39 -0
- package/src/commands/shell.ts +29 -0
- package/src/commands/stats.ts +29 -0
- package/src/commands/update.ts +21 -0
- package/src/commands/web-search.ts +50 -0
- package/src/commit/agentic/index.ts +3 -2
- package/src/commit/agentic/tools/analyze-file.ts +1 -3
- package/src/commit/git/errors.ts +4 -6
- package/src/commit/pipeline.ts +3 -2
- package/src/config/keybindings.ts +1 -3
- package/src/config/model-registry.ts +89 -162
- package/src/config/settings-schema.ts +10 -0
- package/src/config.ts +202 -132
- package/src/exa/mcp-client.ts +8 -41
- package/src/export/html/index.ts +1 -1
- package/src/extensibility/extensions/loader.ts +7 -10
- package/src/extensibility/extensions/runner.ts +5 -15
- package/src/extensibility/extensions/types.ts +1 -1
- package/src/extensibility/hooks/runner.ts +6 -9
- package/src/index.ts +0 -1
- package/src/ipy/kernel.ts +10 -22
- package/src/lsp/clients/biome-client.ts +4 -7
- package/src/lsp/clients/lsp-linter-client.ts +4 -6
- package/src/lsp/index.ts +5 -4
- package/src/lsp/utils.ts +18 -0
- package/src/main.ts +86 -181
- package/src/mcp/json-rpc.ts +2 -2
- package/src/mcp/transports/http.ts +12 -49
- package/src/modes/components/armin.ts +1 -3
- package/src/modes/components/assistant-message.ts +4 -4
- package/src/modes/components/bash-execution.ts +5 -3
- package/src/modes/components/branch-summary-message.ts +1 -3
- package/src/modes/components/compaction-summary-message.ts +1 -3
- package/src/modes/components/custom-message.ts +4 -5
- package/src/modes/components/extensions/extension-dashboard.ts +10 -16
- package/src/modes/components/extensions/extension-list.ts +5 -5
- package/src/modes/components/footer.ts +1 -4
- package/src/modes/components/hook-editor.ts +7 -32
- package/src/modes/components/hook-message.ts +4 -5
- package/src/modes/components/model-selector.ts +2 -2
- package/src/modes/components/plugin-settings.ts +16 -20
- package/src/modes/components/python-execution.ts +5 -5
- package/src/modes/components/session-selector.ts +6 -7
- package/src/modes/components/settings-defs.ts +49 -40
- package/src/modes/components/settings-selector.ts +8 -17
- package/src/modes/components/skill-message.ts +1 -3
- package/src/modes/components/status-line-segment-editor.ts +1 -3
- package/src/modes/components/status-line.ts +1 -3
- package/src/modes/components/todo-reminder.ts +5 -7
- package/src/modes/components/tree-selector.ts +10 -12
- package/src/modes/components/ttsr-notification.ts +1 -3
- package/src/modes/components/user-message-selector.ts +2 -4
- package/src/modes/components/welcome.ts +6 -18
- package/src/modes/controllers/event-controller.ts +1 -0
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +7 -34
- package/src/modes/controllers/selector-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +27 -1
- package/src/modes/rpc/rpc-client.ts +2 -5
- package/src/modes/rpc/rpc-mode.ts +2 -2
- package/src/modes/theme/theme.ts +2 -6
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +6 -1
- package/src/patch/index.ts +1 -4
- package/src/prompts/agents/explore.md +1 -0
- package/src/prompts/agents/frontmatter.md +2 -1
- package/src/prompts/agents/init.md +1 -0
- package/src/prompts/agents/plan.md +1 -0
- package/src/prompts/agents/reviewer.md +1 -0
- package/src/prompts/system/subagent-submit-reminder.md +2 -0
- package/src/prompts/system/subagent-system-prompt.md +2 -0
- package/src/prompts/system/subagent-user-prompt.md +8 -0
- package/src/prompts/system/system-prompt.md +5 -3
- package/src/prompts/system/web-search.md +6 -4
- package/src/prompts/tools/task.md +216 -163
- package/src/sdk.ts +11 -110
- package/src/session/agent-session.ts +117 -83
- package/src/session/auth-storage.ts +10 -51
- package/src/session/messages.ts +17 -3
- package/src/session/session-manager.ts +30 -30
- package/src/session/streaming-output.ts +1 -1
- package/src/ssh/ssh-executor.ts +6 -3
- package/src/task/agents.ts +2 -0
- package/src/task/discovery.ts +1 -1
- package/src/task/executor.ts +5 -10
- package/src/task/index.ts +43 -23
- package/src/task/render.ts +67 -64
- package/src/task/template.ts +17 -34
- package/src/task/types.ts +49 -22
- package/src/tools/ask.ts +1 -3
- package/src/tools/bash.ts +1 -4
- package/src/tools/browser.ts +5 -7
- package/src/tools/exit-plan-mode.ts +1 -4
- package/src/tools/fetch.ts +1 -3
- package/src/tools/find.ts +4 -3
- package/src/tools/gemini-image.ts +24 -55
- package/src/tools/grep.ts +4 -4
- package/src/tools/index.ts +12 -14
- package/src/tools/notebook.ts +1 -5
- package/src/tools/python.ts +4 -3
- package/src/tools/read.ts +2 -4
- package/src/tools/render-utils.ts +23 -0
- package/src/tools/ssh.ts +8 -12
- package/src/tools/todo-write.ts +1 -4
- package/src/tools/tool-errors.ts +1 -4
- package/src/tools/write.ts +1 -3
- package/src/utils/external-editor.ts +59 -0
- package/src/utils/file-mentions.ts +39 -1
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +4 -4
- package/src/web/search/auth.ts +3 -33
- package/src/web/search/index.ts +73 -139
- package/src/web/search/provider.ts +58 -0
- package/src/web/search/providers/anthropic.ts +53 -14
- package/src/web/search/providers/base.ts +22 -0
- package/src/web/search/providers/codex.ts +38 -16
- package/src/web/search/providers/exa.ts +30 -6
- package/src/web/search/providers/gemini.ts +56 -20
- package/src/web/search/providers/jina.ts +28 -5
- package/src/web/search/providers/perplexity.ts +103 -36
- package/src/web/search/render.ts +84 -74
- package/src/web/search/types.ts +285 -59
- package/src/migrations.ts +0 -175
- package/src/session/storage-migration.ts +0 -173
package/src/migrations.ts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-time migrations that run on startup.
|
|
3
|
-
*/
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import * as path from "node:path";
|
|
6
|
-
import { isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
7
|
-
import chalk from "chalk";
|
|
8
|
-
import { getAgentDbPath, getAgentDir } from "./config";
|
|
9
|
-
import { AgentStorage } from "./session/agent-storage";
|
|
10
|
-
import type { AuthCredential } from "./session/auth-storage";
|
|
11
|
-
|
|
12
|
-
type SessionHeader = {
|
|
13
|
-
type: "session";
|
|
14
|
-
cwd: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
function isSessionHeader(value: unknown): value is SessionHeader {
|
|
18
|
-
if (!value || typeof value !== "object") return false;
|
|
19
|
-
const record = value as Record<string, unknown>;
|
|
20
|
-
return record.type === "session" && typeof record.cwd === "string" && record.cwd.length > 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Migrate legacy oauth.json and settings.json apiKeys to agent.db.
|
|
25
|
-
*
|
|
26
|
-
* @returns Array of provider names that were migrated
|
|
27
|
-
*/
|
|
28
|
-
export async function migrateAuthToAgentDb(): Promise<string[]> {
|
|
29
|
-
const agentDir = getAgentDir();
|
|
30
|
-
const oauthPath = path.join(agentDir, "oauth.json");
|
|
31
|
-
const settingsPath = path.join(agentDir, "settings.json");
|
|
32
|
-
const storage = await AgentStorage.open(getAgentDbPath(agentDir));
|
|
33
|
-
|
|
34
|
-
const migrated: Record<string, AuthCredential[]> = {};
|
|
35
|
-
const providers: string[] = [];
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const oauth = await Bun.file(oauthPath).json();
|
|
39
|
-
try {
|
|
40
|
-
for (const [provider, cred] of Object.entries(oauth)) {
|
|
41
|
-
if (storage.listAuthCredentials(provider).length > 0) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
migrated[provider] = [{ type: "oauth", ...(cred as object) } as AuthCredential];
|
|
45
|
-
providers.push(provider);
|
|
46
|
-
}
|
|
47
|
-
await fs.promises.rename(oauthPath, `${oauthPath}.migrated`);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
logger.warn("Failed to migrate oauth.json", { path: oauthPath, error: String(error) });
|
|
50
|
-
}
|
|
51
|
-
} catch (err) {
|
|
52
|
-
if (!isEnoent(err)) {
|
|
53
|
-
logger.warn("Failed to read oauth.json", { path: oauthPath, error: String(err) });
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const settings = await Bun.file(settingsPath).json();
|
|
59
|
-
try {
|
|
60
|
-
if (settings.apiKeys && typeof settings.apiKeys === "object") {
|
|
61
|
-
for (const [provider, key] of Object.entries(settings.apiKeys)) {
|
|
62
|
-
if (typeof key !== "string") continue;
|
|
63
|
-
if (migrated[provider]) continue;
|
|
64
|
-
if (storage.listAuthCredentials(provider).length > 0) continue;
|
|
65
|
-
migrated[provider] = [{ type: "api_key", key }];
|
|
66
|
-
providers.push(provider);
|
|
67
|
-
}
|
|
68
|
-
delete settings.apiKeys;
|
|
69
|
-
await Bun.write(settingsPath, JSON.stringify(settings, null, 2));
|
|
70
|
-
}
|
|
71
|
-
} catch (error) {
|
|
72
|
-
logger.warn("Failed to migrate settings.json apiKeys", { path: settingsPath, error: String(error) });
|
|
73
|
-
}
|
|
74
|
-
} catch (err) {
|
|
75
|
-
if (!isEnoent(err)) {
|
|
76
|
-
logger.warn("Failed to read settings.json", { path: settingsPath, error: String(err) });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
for (const [provider, credentials] of Object.entries(migrated)) {
|
|
81
|
-
storage.replaceAuthCredentialsForProvider(provider, credentials);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return providers;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Migrate sessions from ~/.omp/agent/*.jsonl to proper session directories.
|
|
89
|
-
*
|
|
90
|
-
* Bug in v0.30.0: Sessions were saved to ~/.omp/agent/ instead of
|
|
91
|
-
* ~/.omp/agent/sessions/<encoded-cwd>/. This migration moves them
|
|
92
|
-
* to the correct location based on the cwd in their session header.
|
|
93
|
-
*
|
|
94
|
-
* See: https://github.com/badlogic/pi-mono/issues/320
|
|
95
|
-
*/
|
|
96
|
-
export async function migrateSessionsFromAgentRoot(): Promise<void> {
|
|
97
|
-
const agentDir = getAgentDir();
|
|
98
|
-
|
|
99
|
-
// Find all .jsonl files directly in agentDir (not in subdirectories)
|
|
100
|
-
let files: string[];
|
|
101
|
-
try {
|
|
102
|
-
const entries = await fs.promises.readdir(agentDir);
|
|
103
|
-
files = entries.filter(f => f.endsWith(".jsonl")).map(f => path.join(agentDir, f));
|
|
104
|
-
} catch (error) {
|
|
105
|
-
logger.warn("Failed to read agent directory for session migration", { path: agentDir, error: String(error) });
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (files.length === 0) return;
|
|
110
|
-
|
|
111
|
-
for (const file of files) {
|
|
112
|
-
try {
|
|
113
|
-
// Read first line to get session header
|
|
114
|
-
let content: string;
|
|
115
|
-
try {
|
|
116
|
-
content = await Bun.file(file).text();
|
|
117
|
-
} catch (err) {
|
|
118
|
-
if (isEnoent(err)) continue;
|
|
119
|
-
throw err;
|
|
120
|
-
}
|
|
121
|
-
const entries: unknown[] = Bun.JSONL.parse(content);
|
|
122
|
-
const header = entries[0];
|
|
123
|
-
if (!isSessionHeader(header)) continue;
|
|
124
|
-
|
|
125
|
-
const cwd = header.cwd;
|
|
126
|
-
|
|
127
|
-
// Compute the correct session directory (same encoding as session-manager.ts)
|
|
128
|
-
const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
129
|
-
const correctDir = path.join(agentDir, "sessions", safePath);
|
|
130
|
-
|
|
131
|
-
// Create directory if needed
|
|
132
|
-
await fs.promises.mkdir(correctDir, { recursive: true });
|
|
133
|
-
|
|
134
|
-
// Move the file
|
|
135
|
-
const fileName = file.split("/").pop() || file.split("\\").pop();
|
|
136
|
-
const newPath = path.join(correctDir, fileName!);
|
|
137
|
-
|
|
138
|
-
if (fs.existsSync(newPath)) continue; // Skip if target exists
|
|
139
|
-
|
|
140
|
-
await fs.promises.rename(file, newPath);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
logger.warn("Failed to migrate session file", { path: file, error: String(error) });
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Run all migrations. Called once on startup.
|
|
149
|
-
*
|
|
150
|
-
* @param _cwd - Current working directory (reserved for future project-local migrations)
|
|
151
|
-
* @returns Object with migration results
|
|
152
|
-
*/
|
|
153
|
-
export async function runMigrations(_cwd: string): Promise<{
|
|
154
|
-
migratedAuthProviders: string[];
|
|
155
|
-
deprecationWarnings: string[];
|
|
156
|
-
}> {
|
|
157
|
-
// Then: run data migrations
|
|
158
|
-
const migratedAuthProviders = await migrateAuthToAgentDb();
|
|
159
|
-
await migrateSessionsFromAgentRoot();
|
|
160
|
-
|
|
161
|
-
return { migratedAuthProviders, deprecationWarnings: [] };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Display deprecation warnings to the user in interactive mode.
|
|
166
|
-
*
|
|
167
|
-
* @param warnings - Array of deprecation warning messages
|
|
168
|
-
*/
|
|
169
|
-
export async function showDeprecationWarnings(warnings: string[]): Promise<void> {
|
|
170
|
-
console.log(chalk.yellow("\n⚠ Deprecation Warnings:"));
|
|
171
|
-
for (const warning of warnings) {
|
|
172
|
-
console.log(chalk.yellow(` • ${warning}`));
|
|
173
|
-
}
|
|
174
|
-
console.log();
|
|
175
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migrates legacy auth.json to SQLite-based agent.db.
|
|
3
|
-
* Auth credentials merge per-provider when missing.
|
|
4
|
-
* Original JSON files are backed up to .bak and removed after successful migration.
|
|
5
|
-
*
|
|
6
|
-
* NOTE: Settings migration is now handled by SettingsManager.migrateToYaml(),
|
|
7
|
-
* which migrates from both settings.json and agent.db to config.yaml.
|
|
8
|
-
*/
|
|
9
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
10
|
-
import { getAgentDbPath } from "../config";
|
|
11
|
-
import { AgentStorage } from "./agent-storage";
|
|
12
|
-
import type { AuthCredential, AuthCredentialEntry, AuthStorageData } from "./auth-storage";
|
|
13
|
-
|
|
14
|
-
/** Paths configuration for the storage migration process. */
|
|
15
|
-
type MigrationPaths = {
|
|
16
|
-
/** Directory containing agent.db */
|
|
17
|
-
agentDir: string;
|
|
18
|
-
/** Path to legacy settings.json file (kept for API compatibility, no longer used) */
|
|
19
|
-
settingsPath: string;
|
|
20
|
-
/** Candidate paths to search for auth.json (checked in order) */
|
|
21
|
-
authPaths: string[];
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/** Result of the JSON-to-SQLite storage migration. */
|
|
25
|
-
export interface StorageMigrationResult {
|
|
26
|
-
/** Whether settings.json was migrated (always false - settings migration is handled elsewhere) */
|
|
27
|
-
migratedSettings: boolean;
|
|
28
|
-
/** Whether auth.json was migrated to agent.db */
|
|
29
|
-
migratedAuth: boolean;
|
|
30
|
-
/** Non-fatal issues encountered during migration */
|
|
31
|
-
warnings: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Type guard for plain objects.
|
|
36
|
-
* @param value - Value to check
|
|
37
|
-
* @returns True if value is a non-null, non-array object
|
|
38
|
-
*/
|
|
39
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
40
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Normalizes credential entries to array format (legacy stored single credentials).
|
|
45
|
-
* @param entry - Single credential or array of credentials
|
|
46
|
-
* @returns Array of credentials (empty if entry is undefined)
|
|
47
|
-
*/
|
|
48
|
-
function normalizeCredentialEntry(entry: AuthCredentialEntry | undefined): AuthCredential[] {
|
|
49
|
-
if (!entry) return [];
|
|
50
|
-
return Array.isArray(entry) ? entry : [entry];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Reads and parses a JSON file.
|
|
55
|
-
* @param path - Path to the JSON file
|
|
56
|
-
* @returns Parsed JSON content, or null if file doesn't exist or parsing fails
|
|
57
|
-
*/
|
|
58
|
-
async function readJsonFile<T>(path: string): Promise<T | null> {
|
|
59
|
-
try {
|
|
60
|
-
const file = Bun.file(path);
|
|
61
|
-
if (!(await file.exists())) return null;
|
|
62
|
-
const content = await file.text();
|
|
63
|
-
return JSON.parse(content) as T;
|
|
64
|
-
} catch (error) {
|
|
65
|
-
logger.warn("Storage migration failed to read JSON", { path, error: String(error) });
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Backs up a JSON file to .bak and removes the original.
|
|
72
|
-
* Prevents re-migration on subsequent runs.
|
|
73
|
-
* @param path - Path to the JSON file to backup
|
|
74
|
-
*/
|
|
75
|
-
async function backupJson(path: string): Promise<void> {
|
|
76
|
-
const file = Bun.file(path);
|
|
77
|
-
if (!(await file.exists())) return;
|
|
78
|
-
|
|
79
|
-
const backupPath = `${path}.bak`;
|
|
80
|
-
try {
|
|
81
|
-
const content = await file.arrayBuffer();
|
|
82
|
-
await Bun.write(backupPath, content);
|
|
83
|
-
await file.unlink();
|
|
84
|
-
} catch (error) {
|
|
85
|
-
logger.warn("Storage migration failed to backup JSON", { path, error: String(error) });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Finds the first valid auth.json from candidate paths (checked in priority order).
|
|
91
|
-
* @param authPaths - Candidate paths to search (e.g., project-local before global)
|
|
92
|
-
* @returns First valid auth file with its path and parsed data, or null if none found
|
|
93
|
-
*/
|
|
94
|
-
async function findFirstAuthJson(authPaths: string[]): Promise<{ path: string; data: AuthStorageData } | null> {
|
|
95
|
-
for (const authPath of authPaths) {
|
|
96
|
-
const data = await readJsonFile<AuthStorageData>(authPath);
|
|
97
|
-
if (data && isRecord(data)) {
|
|
98
|
-
return { path: authPath, data };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Validates that a credential has a recognized type.
|
|
106
|
-
* @param entry - Credential to validate
|
|
107
|
-
* @returns True if credential type is api_key or oauth
|
|
108
|
-
*/
|
|
109
|
-
function isValidCredential(entry: AuthCredential): boolean {
|
|
110
|
-
return entry.type === "api_key" || entry.type === "oauth";
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Migrates auth.json to SQLite storage for providers missing in agent.db.
|
|
115
|
-
* @param storage - AgentStorage instance to migrate into
|
|
116
|
-
* @param authPaths - Candidate paths to search for auth.json
|
|
117
|
-
* @param warnings - Array to collect non-fatal warnings
|
|
118
|
-
* @returns True if migration was performed
|
|
119
|
-
*/
|
|
120
|
-
async function migrateAuth(storage: AgentStorage, authPaths: string[], warnings: string[]): Promise<boolean> {
|
|
121
|
-
const authJson = await findFirstAuthJson(authPaths);
|
|
122
|
-
if (!authJson) return false;
|
|
123
|
-
|
|
124
|
-
let sawValid = false;
|
|
125
|
-
let migratedAny = false;
|
|
126
|
-
|
|
127
|
-
for (const [provider, entry] of Object.entries(authJson.data)) {
|
|
128
|
-
const credentials = normalizeCredentialEntry(entry)
|
|
129
|
-
.filter(isValidCredential)
|
|
130
|
-
.map(credential => credential);
|
|
131
|
-
|
|
132
|
-
if (credentials.length === 0) continue;
|
|
133
|
-
sawValid = true;
|
|
134
|
-
|
|
135
|
-
if (storage.listAuthCredentials(provider).length > 0) {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
storage.replaceAuthCredentialsForProvider(provider, credentials);
|
|
140
|
-
migratedAny = true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (sawValid) {
|
|
144
|
-
await backupJson(authJson.path);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!migratedAny && sawValid) {
|
|
148
|
-
warnings.push(`auth.json entries already present in agent.db: ${authJson.path}`);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return migratedAny;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Migrates legacy auth.json to SQLite-based agent.db.
|
|
156
|
-
* Settings migration is handled separately by SettingsManager.migrateToYaml().
|
|
157
|
-
* @param paths - Configuration specifying locations of legacy files and target DB
|
|
158
|
-
* @returns Result indicating what was migrated and any warnings encountered
|
|
159
|
-
*/
|
|
160
|
-
export async function migrateJsonStorage(paths: MigrationPaths): Promise<StorageMigrationResult> {
|
|
161
|
-
const storage = await AgentStorage.open(getAgentDbPath(paths.agentDir));
|
|
162
|
-
const warnings: string[] = [];
|
|
163
|
-
|
|
164
|
-
const migratedAuth = await migrateAuth(storage, paths.authPaths, warnings);
|
|
165
|
-
|
|
166
|
-
if (warnings.length > 0) {
|
|
167
|
-
for (const warning of warnings) {
|
|
168
|
-
logger.warn("Storage migration warning", { warning });
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return { migratedSettings: false, migratedAuth, warnings };
|
|
173
|
-
}
|