feat(KB-635): add Mission system integration across CLI, engine, and dashboard

- Add mission CLI commands: create, list, show, delete, activate-slice
- Add pi extension tools for mission management
- Add MissionStore helper methods and Mission types
- Add scheduler mission awareness for automatic slice activation
- Add engine integration wiring for mission-aware task execution
- Add dashboard mission routes and API endpoints
- Link tasks to missions via sliceId field with autoAdvance support
This commit is contained in:
gsxdsm
2026-04-01 07:49:21 -07:00
parent 348c21544b
commit 3607f37a16
11 changed files with 1032 additions and 50 deletions

View File

@@ -45,6 +45,7 @@ const { runSettingsExport } = await import("./commands/settings-export.js");
const { runSettingsImport } = await import("./commands/settings-import.js");
const { runGitStatus, runGitFetch, runGitPull, runGitPush } = await import("./commands/git.js");
const { runBackupCreate, runBackupList, runBackupRestore, runBackupCleanup } = await import("./commands/backup.js");
const { runMissionCreate, runMissionList, runMissionShow, runMissionDelete, runMissionActivateSlice } = await import("./commands/mission.js");
const { runProjectList, runProjectAdd, runProjectRemove, runProjectShow, runProjectSetDefault, runProjectDetect } = await import("./commands/project.js");
const HELP = `
@@ -100,10 +101,11 @@ Usage:
fn backup --list List all database backups
fn backup --restore <file> Restore database from a backup file
fn backup --cleanup Remove old backups exceeding retention limit
fn project list [--json] List all registered projects
fn project add [dir] [--name <name>] [--isolation <mode>] Register a project
fn project remove <name> [--force] Unregister a project
fn project info [name] Show project details
fn mission create [title] [description] Create a new mission
fn mission list List all missions
fn mission show <id> Show mission with hierarchy
fn mission delete <id> [--force] Delete a mission
fn mission activate-slice <slice-id> Activate a pending slice
Options:
--project, -P <name> Target a specific project (for task/settings commands)
@@ -697,46 +699,65 @@ async function main() {
break;
}
case "project": {
case "mission": {
const subcommand = args[1];
switch (subcommand) {
case "create": {
const titleParts: string[] = [];
for (let i = 2; i < args.length; i++) {
titleParts.push(args[i]);
}
const fullInput = titleParts.join(" ");
// Split on first space to separate title and description if provided
const firstSpaceIdx = fullInput.indexOf(" ");
let title: string | undefined;
let description: string | undefined;
if (firstSpaceIdx > 0) {
title = fullInput.slice(0, firstSpaceIdx);
description = fullInput.slice(firstSpaceIdx + 1).trim();
} else {
title = fullInput || undefined;
}
await runMissionCreate(title, description, projectName);
break;
}
case "list":
case "ls": {
const json = args.includes("--json");
await runProjectList({ json });
case "ls":
await runMissionList(projectName);
break;
case "show":
case "info": {
const id = args[2];
if (!id) {
console.error("Usage: fn mission show <id>");
process.exit(1);
}
await runMissionShow(id, projectName);
break;
}
case "add": {
const dir = args[2];
const nameIdx = args.indexOf("--name");
const name = nameIdx !== -1 && nameIdx + 1 < args.length ? args[nameIdx + 1] : undefined;
const isolationIdx = args.indexOf("--isolation");
const isolation = isolationIdx !== -1 && isolationIdx + 1 < args.length
? args[isolationIdx + 1] as "in-process" | "child-process"
: undefined;
await runProjectAdd(dir, { name, isolation });
break;
}
case "remove":
case "delete":
case "rm": {
const name = args[2];
if (!name) {
console.error("Usage: fn project remove <name> [--force]");
const id = args[2];
if (!id) {
console.error("Usage: fn mission delete <id> [--force]");
process.exit(1);
}
const force = args.includes("--force");
await runProjectRemove(name, { force });
await runMissionDelete(id, force, projectName);
break;
}
case "info":
case "show": {
const name = args[2];
await runProjectInfo(name);
case "activate-slice": {
const id = args[2];
if (!id) {
console.error("Usage: fn mission activate-slice <slice-id>");
process.exit(1);
}
await runMissionActivateSlice(id, projectName);
break;
}
default:
console.error(`Unknown subcommand: project ${subcommand || ""}`);
console.error("Try: fn project list | add [dir] | remove <name> | info [name]");
console.error(`Unknown subcommand: mission ${subcommand || ""}`);
console.error("Try: fn mission create | list | show <id> | delete <id> | activate-slice <id>");
process.exit(1);
}
break;