unify agent items into a flat file-based store, drop the marketplace
Replace the marketplace service dependency and the native/global/user scope tiers with a single external directory ($OFFICER_ITEMS_DIR) holding skills, tools, tasks, processes and extensions as plain files. - tasks move from Postgres to TASK.md files (new file-backed task layer); task editing now works, which the DB path never supported - skills/tools/processes collapse into one shared file router (single dir) - remove the marketplace client (sync-marketplace/sync-version) and the boot-time sync; pi-bridge/pi-manager/sandbox point at the flat store - drop the dead tasks + vestigial skills/tools/processes/extensions + item_chats tables (migration 0004) - one-time migration script exports DB tasks and consolidates disk items Migration verified: all 6 tasks round-trip through the runtime parser identically to their DB rows (pipeline steps, triggers, script impls and agentic bodies all intact). NOTE: not yet functionally tested end-to-end — every item (each task mode, tool, skill, extension) still needs to be run/exercised in the app before this is trusted. To be done manually. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,8 @@ import { randomUUID } from 'crypto';
|
||||
import { readdirSync, existsSync, mkdirSync, writeFileSync, chmodSync, rmSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { getTaskByDirName, getUserSettings } from 'officerdb';
|
||||
import { getUserSettings } from 'officerdb';
|
||||
import { getTaskByDirName } from './task-files';
|
||||
import { getHomeDirForRole, getHomeDir } from '../../data-path';
|
||||
import { resolveBaseCwd } from '../pi/websocket';
|
||||
import { SANDBOX_HOME } from '../../sidecar/sandbox';
|
||||
@@ -471,7 +472,7 @@ export type ExecutePipelineParams = {
|
||||
};
|
||||
|
||||
export async function executePipeline({ userId, email, username, role, taskDirName, inputs, cwd, model: modelOverride, startAt, abortSignal, emit }: ExecutePipelineParams): Promise<void> {
|
||||
const pipelineTask = await getTaskByDirName(taskDirName, userId);
|
||||
const pipelineTask = await getTaskByDirName(taskDirName);
|
||||
if (!pipelineTask) {
|
||||
emit({ type: 'error', message: `Task not found: ${taskDirName}` });
|
||||
return;
|
||||
@@ -514,7 +515,7 @@ export async function executePipeline({ userId, email, username, role, taskDirNa
|
||||
|
||||
const step = config.steps[stepIdx]!;
|
||||
|
||||
const stepTask = await getTaskByDirName(step.task, userId);
|
||||
const stepTask = await getTaskByDirName(step.task);
|
||||
if (!stepTask) {
|
||||
emit({ type: 'error', message: `Step task not found: ${step.task}` });
|
||||
return;
|
||||
@@ -648,7 +649,7 @@ export async function message(ws: ServerWebSocket<WSData>, raw: string | Buffer)
|
||||
const { userId, email, username, role } = ws.data;
|
||||
|
||||
// Resolve task name for the DB record
|
||||
const task = await getTaskByDirName(msg.taskDirName, userId);
|
||||
const task = await getTaskByDirName(msg.taskDirName);
|
||||
if (!task) {
|
||||
send(ws, { type: 'error', message: `Task not found: ${msg.taskDirName}` });
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user