mirror of
https://github.com/denberek/obsidian-agent-fleet.git
synced 2026-07-22 07:47:06 +00:00
release: 0.13.4 — warning cleanup (trashFile, builtin-modules, unused vars)
This commit is contained in:
parent
694874f7ac
commit
c2477d08bc
13 changed files with 139 additions and 125 deletions
|
|
@ -1,5 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## 0.13.4 — 2026-06-14
|
||||
|
||||
Further community-review cleanup (all non-blocking warnings). No user-facing behavior changes.
|
||||
|
||||
- **Deletions respect your trash preference** — file/folder removals now go through `FileManager.trashFile` instead of `Vault.delete`/`Vault.trash`, so they honor your "move to system trash vs. permanently delete" setting.
|
||||
- Replaced the `builtin-modules` build dependency with Node's built-in `module.builtinModules`.
|
||||
- Removed a few unused local variables.
|
||||
|
||||
## 0.13.3 — 2026-06-14
|
||||
|
||||
Clears the blocking errors from the Obsidian Community Plugins automated review. No user-facing behavior changes.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import esbuild from "esbuild";
|
||||
import builtins from "builtin-modules";
|
||||
import { builtinModules } from "node:module";
|
||||
|
||||
// Node built-ins (plus their `node:` aliases) are external — the plugin runs in
|
||||
// Electron's Node context and must not bundle them.
|
||||
const builtins = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
|
||||
|
||||
const prod = process.argv.includes("production");
|
||||
|
||||
|
|
|
|||
178
main.js
178
main.js
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "agent-fleet",
|
||||
"name": "Agent Fleet",
|
||||
"version": "0.13.3",
|
||||
"version": "0.13.4",
|
||||
"minAppVersion": "1.11.4",
|
||||
"description": "File-backed AI agents with task scheduling, channels, memory, and MCP — running on Claude Code or OpenAI Codex, all as plain markdown.",
|
||||
"author": "Denis Berekchiyan",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-agent-fleet",
|
||||
"version": "0.13.3",
|
||||
"version": "0.13.4",
|
||||
"description": "Obsidian plugin for file-backed AI agents, task scheduling, channels (Slack), heartbeat, and interactive chat.",
|
||||
"license": "MIT",
|
||||
"main": "plugin/main.js",
|
||||
|
|
@ -27,7 +27,6 @@
|
|||
"devDependencies": {
|
||||
"@types/node": "^24.5.2",
|
||||
"@types/ws": "^8.18.1",
|
||||
"builtin-modules": "^4.0.0",
|
||||
"esbuild": "^0.25.9",
|
||||
"obsidian": "^1.8.10",
|
||||
"tslib": "^2.8.1",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { join } from "path";
|
||||
import { FileSystemAdapter, TFile, TFolder, Vault, normalizePath } from "obsidian";
|
||||
import { App, FileSystemAdapter, TFile, TFolder, Vault, normalizePath } from "obsidian";
|
||||
import {
|
||||
DEFAULT_SETTINGS,
|
||||
DEFAULT_MEMORY_TOKEN_BUDGET,
|
||||
|
|
@ -145,7 +145,10 @@ export class FleetRepository {
|
|||
* reflection path and the lock-held capture path can't double-seed raw. */
|
||||
private migratingMemory = new Set<string>();
|
||||
|
||||
constructor(private readonly vault: Vault, private readonly settings: FleetSettings) {}
|
||||
private readonly vault: Vault;
|
||||
constructor(private readonly app: App, private readonly settings: FleetSettings) {
|
||||
this.vault = app.vault;
|
||||
}
|
||||
|
||||
/** Inject a live credential getter so validation reads from the credential store
|
||||
* instead of the (possibly empty post-migration) settings.channelCredentials. */
|
||||
|
|
@ -1182,19 +1185,19 @@ export class FleetRepository {
|
|||
const path = this.getConversationPath(agent, conversationId);
|
||||
const file = this.vault.getAbstractFileByPath(path);
|
||||
if (file instanceof TFile) {
|
||||
await this.vault.delete(file);
|
||||
await this.app.fileManager.trashFile(file);
|
||||
}
|
||||
|
||||
const threadsDir = path.replace(/\.json$/, ".threads");
|
||||
const threadsFolder = this.vault.getAbstractFileByPath(threadsDir);
|
||||
if (threadsFolder instanceof TFolder) {
|
||||
await this.vault.delete(threadsFolder, true);
|
||||
await this.app.fileManager.trashFile(threadsFolder);
|
||||
}
|
||||
|
||||
const dir = this.getConversationsDir(agent);
|
||||
const folder = this.vault.getAbstractFileByPath(dir);
|
||||
if (folder instanceof TFolder && folder.children.length === 0) {
|
||||
await this.vault.delete(folder, true);
|
||||
await this.app.fileManager.trashFile(folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1706,7 +1709,7 @@ export class FleetRepository {
|
|||
}
|
||||
} else if (permFile instanceof TFile) {
|
||||
// Remove permissions.json if both lists are empty
|
||||
await this.vault.trash(permFile, true);
|
||||
await this.app.fileManager.trashFile(permFile);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1757,7 +1760,7 @@ export class FleetRepository {
|
|||
await this.vault.create(sidecarPath, content);
|
||||
}
|
||||
} else if (sidecarFile instanceof TFile) {
|
||||
await this.vault.trash(sidecarFile, true);
|
||||
await this.app.fileManager.trashFile(sidecarFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1882,7 +1885,7 @@ export class FleetRepository {
|
|||
const folderPath = normalizePath(skill.filePath.replace(/\/skill\.md$/, ""));
|
||||
const folder = this.vault.getAbstractFileByPath(folderPath);
|
||||
if (folder instanceof TFolder) {
|
||||
await this.vault.trash(folder, true);
|
||||
await this.app.fileManager.trashFile(folder);
|
||||
}
|
||||
} else {
|
||||
await this.trashFile(skill.filePath);
|
||||
|
|
@ -1944,7 +1947,7 @@ export class FleetRepository {
|
|||
);
|
||||
const folder = this.vault.getAbstractFileByPath(sessionsFolder);
|
||||
if (folder instanceof TFolder) {
|
||||
await this.vault.trash(folder, true);
|
||||
await this.app.fileManager.trashFile(folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2072,7 +2075,7 @@ export class FleetRepository {
|
|||
for (const f of files) {
|
||||
trashedFiles.push(f.path);
|
||||
}
|
||||
await this.vault.trash(folder, true);
|
||||
await this.app.fileManager.trashFile(folder);
|
||||
}
|
||||
} else {
|
||||
// Trash the single agent definition file
|
||||
|
|
@ -2089,7 +2092,7 @@ export class FleetRepository {
|
|||
const memoryDir = this.getMemoryDir(agentName);
|
||||
const memoryFolder = this.vault.getAbstractFileByPath(memoryDir);
|
||||
if (memoryFolder instanceof TFolder) {
|
||||
await this.vault.trash(memoryFolder, true);
|
||||
await this.app.fileManager.trashFile(memoryFolder);
|
||||
trashedFiles.push(memoryDir);
|
||||
}
|
||||
|
||||
|
|
@ -2108,7 +2111,7 @@ export class FleetRepository {
|
|||
async trashFile(path: string): Promise<void> {
|
||||
const file = this.vault.getAbstractFileByPath(path);
|
||||
if (file) {
|
||||
await this.vault.trash(file, true);
|
||||
await this.app.fileManager.trashFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export default class AgentFleetPlugin extends Plugin {
|
|||
async onload(): Promise<void> {
|
||||
await this.loadSettings();
|
||||
this.settings.claudeCliPath = await this.resolveClaudeCliPath(this.settings.claudeCliPath);
|
||||
this.repository = new FleetRepository(this.app.vault, this.settings);
|
||||
this.repository = new FleetRepository(this.app, this.settings);
|
||||
this.repository.setChannelCredentialGetter(() => this.channelCredentials.toRecord());
|
||||
this.runtime = new FleetRuntime(this.repository, this.settings, this.mcpAuth);
|
||||
|
||||
|
|
@ -301,7 +301,7 @@ export default class AgentFleetPlugin extends Plugin {
|
|||
// task crons run alongside the new one's, producing duplicate runs and
|
||||
// making schedule edits appear not to take effect until full reload.
|
||||
this.runtime.shutdown();
|
||||
this.repository = new FleetRepository(this.app.vault, this.settings);
|
||||
this.repository = new FleetRepository(this.app, this.settings);
|
||||
this.repository.setChannelCredentialGetter(() => this.channelCredentials.toRecord());
|
||||
this.runtime = new FleetRuntime(this.repository, this.settings, this.mcpAuth);
|
||||
await this.repository.ensureFleetStructure();
|
||||
|
|
|
|||
|
|
@ -497,7 +497,6 @@ export class SlackAdapter implements ChannelAdapter {
|
|||
const actions = payload.actions as Array<Record<string, unknown>> | undefined;
|
||||
const user = payload.user as Record<string, unknown> | undefined;
|
||||
const channel = payload.channel as Record<string, unknown> | undefined;
|
||||
const message = payload.message as Record<string, unknown> | undefined;
|
||||
if (!actions?.length || !user || !channel) return;
|
||||
|
||||
const action = actions[0];
|
||||
|
|
|
|||
|
|
@ -568,10 +568,9 @@ export class ChatSession {
|
|||
/** Clear persisted state — for "New Chat" */
|
||||
async clearPersistedState(): Promise<void> {
|
||||
const path = this.getChatFilePath();
|
||||
const file = this.vault.getAbstractFileByPath(path);
|
||||
if (file instanceof TFile) {
|
||||
await this.vault.delete(file);
|
||||
}
|
||||
// Route through the repository so deletion respects the user's trash
|
||||
// preference (FileManager.trashFile).
|
||||
await this.repository.trashFile(path);
|
||||
this.messages = [];
|
||||
this.claudeSessionId = null;
|
||||
this.basePromptSent = false;
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ export class AgentFleetSettingTab extends PluginSettingTab {
|
|||
if (!ok) return;
|
||||
try {
|
||||
await deleteWikiKeeperAgent(
|
||||
this.plugin.app.vault,
|
||||
this.plugin.app,
|
||||
this.plugin.settings.fleetFolder,
|
||||
agent.name,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -850,7 +850,6 @@ export class FleetDashboardView extends ItemView {
|
|||
): void {
|
||||
const state = this.plugin.runtime.getAgentState(agent.name);
|
||||
const agentRuns = this.plugin.runtime.getRecentRuns().filter((r) => r.agent === agent.name);
|
||||
const agentTasks = snapshot.tasks.filter((t) => t.agent === agent.name);
|
||||
|
||||
const card = container.createDiv({ cls: `af-agent-card${agent.enabled ? "" : " disabled"}` });
|
||||
|
||||
|
|
@ -2087,7 +2086,7 @@ export class FleetDashboardView extends ItemView {
|
|||
const headerInfo = headerLeft.createDiv();
|
||||
headerInfo.createDiv({ cls: "af-detail-header-name", text: "Create New Channel" });
|
||||
headerInfo.createDiv({ cls: "af-detail-header-desc", text: "Connect an external chat transport to an agent" });
|
||||
header.createDiv({ cls: "af-detail-header-actions" });
|
||||
const headerActions = header.createDiv({ cls: "af-detail-header-actions" });
|
||||
|
||||
// Form state
|
||||
const state = {
|
||||
|
|
@ -2349,7 +2348,7 @@ export class FleetDashboardView extends ItemView {
|
|||
const headerInfo = headerLeft.createDiv();
|
||||
headerInfo.createDiv({ cls: "af-detail-header-name", text: `Edit Channel: ${channel.name}` });
|
||||
headerInfo.createDiv({ cls: "af-detail-header-desc", text: `Status: ${status}` });
|
||||
header.createDiv({ cls: "af-detail-header-actions" });
|
||||
const headerActions = header.createDiv({ cls: "af-detail-header-actions" });
|
||||
|
||||
// Form state pre-filled
|
||||
const state = {
|
||||
|
|
@ -4735,7 +4734,7 @@ export class FleetDashboardView extends ItemView {
|
|||
headerInfo.createDiv({ cls: "af-detail-header-name", text: "Create New Task" });
|
||||
headerInfo.createDiv({ cls: "af-detail-header-desc", text: "Configure a new task for your fleet" });
|
||||
|
||||
header.createDiv({ cls: "af-detail-header-actions" });
|
||||
const headerActions = header.createDiv({ cls: "af-detail-header-actions" });
|
||||
|
||||
// Form state
|
||||
const state = {
|
||||
|
|
@ -5039,7 +5038,7 @@ export class FleetDashboardView extends ItemView {
|
|||
headerInfo.createDiv({ cls: "af-detail-header-name", text: `Edit Task: ${task.taskId}` });
|
||||
headerInfo.createDiv({ cls: "af-detail-header-desc", text: "Modify task configuration" });
|
||||
|
||||
header.createDiv({ cls: "af-detail-header-actions" });
|
||||
const headerActions = header.createDiv({ cls: "af-detail-header-actions" });
|
||||
|
||||
const hasSchedule = !!(task.schedule || task.runAt);
|
||||
|
||||
|
|
@ -5860,7 +5859,7 @@ export class FleetDashboardView extends ItemView {
|
|||
const headerInfo = headerLeft.createDiv();
|
||||
headerInfo.createDiv({ cls: "af-detail-header-name", text: "Add MCP Server" });
|
||||
headerInfo.createDiv({ cls: "af-detail-header-desc", text: "Register a new MCP server for agents to use" });
|
||||
header.createDiv({ cls: "af-detail-header-actions" });
|
||||
const headerActions = header.createDiv({ cls: "af-detail-header-actions" });
|
||||
|
||||
// Form state
|
||||
const state: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { normalizePath, TFile, TFolder, type Vault } from "obsidian";
|
||||
import { type App, normalizePath, TFile, TFolder, type Vault } from "obsidian";
|
||||
import { parseMarkdownWithFrontmatter, slugify, stringifyMarkdownWithFrontmatter } from "./utils/markdown";
|
||||
|
||||
/** User-supplied inputs when creating a Wiki Keeper instance. */
|
||||
|
|
@ -585,22 +585,24 @@ export async function updateWikiKeeperAgent(
|
|||
/** Delete a Wiki Keeper agent folder. Leaves the scope's own content
|
||||
* (inbox, topics, index, log) untouched — that's the user's wiki, not ours. */
|
||||
export async function deleteWikiKeeperAgent(
|
||||
vault: Vault,
|
||||
app: App,
|
||||
fleetFolder: string,
|
||||
agentName: string,
|
||||
): Promise<void> {
|
||||
const vault = app.vault;
|
||||
const folderPath = normalizePath(`${fleetFolder}/agents/${agentName}`);
|
||||
const folder = vault.getAbstractFileByPath(folderPath);
|
||||
if (!folder) return;
|
||||
if (!(folder instanceof TFolder)) {
|
||||
throw new Error(`Expected folder at ${folderPath}`);
|
||||
}
|
||||
await vault.adapter.rmdir(folderPath, true);
|
||||
// Trash (don't hard-delete) so it respects the user's deletion preference.
|
||||
await app.fileManager.trashFile(folder);
|
||||
|
||||
// Also delete the sibling lint task file, if present.
|
||||
// Also trash the sibling lint task file, if present.
|
||||
const taskPath = lintTaskPath(fleetFolder, agentName);
|
||||
const taskFile = vault.getAbstractFileByPath(taskPath);
|
||||
if (taskFile instanceof TFile) {
|
||||
await vault.delete(taskFile);
|
||||
await app.fileManager.trashFile(taskFile);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@
|
|||
"0.13.0": "1.6.0",
|
||||
"0.13.1": "1.6.0",
|
||||
"0.13.2": "1.6.0",
|
||||
"0.13.3": "1.11.4"
|
||||
"0.13.3": "1.11.4",
|
||||
"0.13.4": "1.11.4"
|
||||
}
|
||||
Loading…
Reference in a new issue