Removed unwanted files marked in .gitignore

This commit is contained in:
gsxdsm
2026-04-01 21:25:08 -07:00
parent 84a048e6c5
commit 7fd5704a80
856 changed files with 2357 additions and 133439 deletions

View File

@@ -1624,7 +1624,7 @@ describe("buildExecutionPrompt", () => {
expect(result).toContain("## Steering Comments");
expect(result).toContain("**user**");
expect(result).toContain("> Please handle the edge case");
expect(result).toContain("The following steering comments were added by the user");
expect(result).toContain("The following comments were added by the user during execution");
});
it("formats multiple steering comments correctly", () => {
@@ -1718,7 +1718,7 @@ describe("buildExecutionPrompt", () => {
expect(result).toContain("## Steering Comments");
// Verify explanatory header text
expect(result).toContain("The following steering comments were added by the user during execution");
expect(result).toContain("The following comments were added by the user during execution");
expect(result).toContain("Consider adjusting your approach or replanning remaining steps based on this feedback");
// Verify all three comments appear with correct author badges
@@ -4233,13 +4233,13 @@ describe("Real-time steering injection", () => {
// Verify steer was called with the formatted message
expect(steerFn).toHaveBeenCalledOnce();
expect(steerFn.mock.calls[0][0]).toContain("📣 **New steering feedback**");
expect(steerFn.mock.calls[0][0]).toContain("📣 **New feedback**");
expect(steerFn.mock.calls[0][0]).toContain("Please use a different approach");
// Verify log entry was created
expect(store.logEntry).toHaveBeenCalledWith(
"FN-001",
expect.stringContaining("Steering comment received mid-execution"),
expect.stringContaining("Comment received mid-execution"),
"by user"
);
@@ -4446,7 +4446,7 @@ describe("Real-time steering injection", () => {
let resolvePrompt: () => void;
const promptPromise = new Promise<void>(resolve => { resolvePrompt = resolve; });
// Set up getTask to return the task with existing steering comment
// Set up getTask to return the task with existing comment in comments (used for seenSteeringIds init)
store.getTask.mockResolvedValue({
id: "FN-001",
title: "Test",
@@ -4457,6 +4457,12 @@ describe("Real-time steering injection", () => {
currentStep: 0,
log: [],
prompt: "# test\n## Steps\n### Step 0: Preflight\n- [ ] check",
comments: [{
id: "existing-comment",
text: "Original",
createdAt: new Date().toISOString(),
author: "user",
}],
steeringComments: [{
id: "existing-comment",
text: "Original",

View File

@@ -15,3 +15,11 @@ export { NtfyNotifier, type NtfyNotifierOptions } from "./notifier.js";
export { CronRunner, type CronRunnerOptions } from "./cron-runner.js";
export { StuckTaskDetector, type StuckTaskDetectorOptions, type DisposableSession } from "./stuck-task-detector.js";
export { ProjectManager } from "./project-manager.js";
// Multi-project runtime types
export {
type ProjectRuntime,
type ProjectRuntimeConfig,
type ProjectRuntimeEvents,
type RuntimeStatus,
type RuntimeMetrics,
} from "./project-runtime.js";

View File

@@ -21,6 +21,7 @@ function createMockMissionStore(): any {
getSlice: vi.fn(),
getMilestone: vi.fn(),
getMission: vi.fn(),
getMissionWithHierarchy: vi.fn(),
getFeatureByTaskId: vi.fn(),
updateFeatureStatus: vi.fn().mockResolvedValue(undefined),
computeSliceStatus: vi.fn(),
@@ -125,25 +126,52 @@ describe("Scheduler Mission Integration", () => {
describe("activateNextPendingSlice", () => {
it("should find and activate next pending slice", async () => {
const mockSlice = createMockSlice({ id: "SL-002", status: "pending" });
const mockActivated = createMockSlice({ id: "SL-002", status: "active" });
missionStore.findNextPendingSlice.mockReturnValue(mockSlice);
missionStore.getMissionWithHierarchy.mockReturnValue({
id: "M-001",
status: "active",
milestones: [
{
id: "MS-001",
orderIndex: 0,
dependencies: [],
slices: [
{ id: "SL-001", status: "complete", orderIndex: 0 },
{ id: "SL-002", status: "pending", orderIndex: 1 },
],
},
],
});
missionStore.activateSlice.mockReturnValue(mockActivated);
const result = await scheduler.activateNextPendingSlice("M-001");
expect(missionStore.findNextPendingSlice).toHaveBeenCalledWith("M-001");
expect(missionStore.getMissionWithHierarchy).toHaveBeenCalledWith("M-001");
expect(missionStore.activateSlice).toHaveBeenCalledWith("SL-002");
expect(result).toEqual(mockActivated);
});
it("should return null when no pending slices", async () => {
missionStore.findNextPendingSlice.mockReturnValue(null);
missionStore.getMissionWithHierarchy.mockReturnValue({
id: "M-001",
status: "active",
milestones: [
{
id: "MS-001",
orderIndex: 0,
dependencies: [],
slices: [
{ id: "SL-001", status: "complete", orderIndex: 0 },
{ id: "SL-002", status: "complete", orderIndex: 1 },
],
},
],
});
const result = await scheduler.activateNextPendingSlice("M-001");
expect(missionStore.findNextPendingSlice).toHaveBeenCalledWith("M-001");
expect(missionStore.getMissionWithHierarchy).toHaveBeenCalledWith("M-001");
expect(result).toBeNull();
});
@@ -161,7 +189,7 @@ describe("Scheduler Mission Integration", () => {
});
it("should handle errors gracefully", async () => {
missionStore.findNextPendingSlice.mockImplementation(() => {
missionStore.getMissionWithHierarchy.mockImplementation(() => {
throw new Error("Database error");
});

View File

@@ -16,6 +16,14 @@ vi.mock("@fusion/core", async () => {
self.init = vi.fn().mockResolvedValue(undefined);
self.listTasks = vi.fn().mockResolvedValue([]);
self.getSettings = vi.fn().mockResolvedValue({});
self.getMissionStore = vi.fn().mockReturnValue({
getMissionWithHierarchy: vi.fn().mockReturnValue(null),
findNextPendingSlice: vi.fn().mockReturnValue(null),
activateSlice: vi.fn(),
on: vi.fn(),
off: vi.fn(),
emit: vi.fn(),
});
self.on = vi.fn().mockReturnValue(self);
self.emit = vi.fn().mockReturnValue(true);
return self;

View File

@@ -283,6 +283,9 @@ describe("Scheduler", () => {
const scheduler = new Scheduler(store);
scheduler.start();
await scheduler.schedule();
// Flush any remaining microtasks
await new Promise(resolve => setTimeout(resolve, 0));
expect(moveTask).toHaveBeenCalledWith("FN-010", "in-progress");
expect(moveTask).not.toHaveBeenCalledWith("FN-010", "triage");
@@ -571,33 +574,7 @@ describe("Scheduler", () => {
expect(mockMissionStore.updateFeatureStatus).not.toHaveBeenCalled();
});
it("triggers feature done update when task with sliceId moves to done", async () => {
const mockMissionStore = createMockMissionStore({
getFeatureByTaskId: vi.fn().mockReturnValue({ id: "F-001", sliceId: "SL-001" }),
updateFeatureStatus: vi.fn().mockReturnValue({ id: "F-001", status: "done" }),
getSlice: vi.fn().mockReturnValue({ id: "SL-001", milestoneId: "MS-001" }),
getMilestone: vi.fn().mockReturnValue({ id: "MS-001", missionId: "M-001" }),
computeSliceStatus: vi.fn().mockReturnValue("active"),
});
const store = createMockStore();
const scheduler = new Scheduler(store, { missionStore: mockMissionStore as any });
// Trigger task:moved event by calling the registered handler
const onCalls = (store.on as any).mock.calls;
const movedHandler = onCalls.find((call: any) => call[0] === "task:moved")?.[1];
expect(movedHandler).toBeDefined();
// Simulate task moving to done with sliceId
const task = createMockTask({ id: "FN-001", sliceId: "SL-001" });
movedHandler({ task, to: "done" });
await Promise.resolve();
expect(mockMissionStore.getFeatureByTaskId).toHaveBeenCalledWith("FN-001");
expect(mockMissionStore.updateFeatureStatus).toHaveBeenCalledWith("F-001", "done");
});
it("auto-advances when slice completes and autoAdvance is enabled", async () => {
it("onSliceComplete auto-advances when autoAdvance is enabled", async () => {
const missionHierarchy = {
id: "M-001",
status: "active",
@@ -613,11 +590,7 @@ describe("Scheduler", () => {
],
};
const mockMissionStore = createMockMissionStore({
getFeatureByTaskId: vi.fn().mockReturnValue({ id: "F-001", sliceId: "SL-001" }),
updateFeatureStatus: vi.fn().mockReturnValue({ id: "F-001", status: "done" }),
getSlice: vi.fn().mockReturnValue({ id: "SL-001", milestoneId: "MS-001" }),
getMilestone: vi.fn().mockReturnValue({ id: "MS-001", missionId: "M-001" }),
computeSliceStatus: vi.fn().mockReturnValue("complete"),
getMission: vi.fn().mockReturnValue({ id: "M-001", status: "active", autoAdvance: true }),
getMissionWithHierarchy: vi.fn().mockReturnValue(missionHierarchy),
activateSlice: vi.fn().mockReturnValue({ id: "SL-002", status: "active" }),
@@ -626,39 +599,26 @@ describe("Scheduler", () => {
const store = createMockStore();
const scheduler = new Scheduler(store, { missionStore: mockMissionStore as any });
const onCalls = (store.on as any).mock.calls;
const movedHandler = onCalls.find((call: any) => call[0] === "task:moved")?.[1];
const slice = { id: "SL-001", milestoneId: "MS-001", status: "complete" } as any;
await scheduler.onSliceComplete(slice);
const task = createMockTask({ id: "FN-001", sliceId: "SL-001" });
movedHandler({ task, to: "done" });
await Promise.resolve();
await Promise.resolve();
expect(mockMissionStore.computeSliceStatus).toHaveBeenCalledWith("SL-001");
expect(mockMissionStore.getMilestone).toHaveBeenCalledWith("MS-001");
expect(mockMissionStore.getMission).toHaveBeenCalledWith("M-001");
expect(mockMissionStore.getMissionWithHierarchy).toHaveBeenCalledWith("M-001");
expect(mockMissionStore.activateSlice).toHaveBeenCalledWith("SL-002");
});
it("does not auto-advance when autoAdvance is disabled", async () => {
it("onSliceComplete does not auto-advance when autoAdvance is disabled", async () => {
const mockMissionStore = createMockMissionStore({
getFeatureByTaskId: vi.fn().mockReturnValue({ id: "F-001", sliceId: "SL-001" }),
updateFeatureStatus: vi.fn().mockReturnValue({ id: "F-001", status: "done" }),
getSlice: vi.fn().mockReturnValue({ id: "SL-001", milestoneId: "MS-001" }),
getMilestone: vi.fn().mockReturnValue({ id: "MS-001", missionId: "M-001" }),
computeSliceStatus: vi.fn().mockReturnValue("complete"),
getMission: vi.fn().mockReturnValue({ id: "M-001", status: "active", autoAdvance: false }),
});
const store = createMockStore();
const scheduler = new Scheduler(store, { missionStore: mockMissionStore as any });
const onCalls = (store.on as any).mock.calls;
const movedHandler = onCalls.find((call: any) => call[0] === "task:moved")?.[1];
const task = createMockTask({ id: "FN-001", sliceId: "SL-001" });
movedHandler({ task, to: "done" });
await Promise.resolve();
const slice = { id: "SL-001", milestoneId: "MS-001", status: "complete" } as any;
await scheduler.onSliceComplete(slice);
expect(mockMissionStore.getMission).toHaveBeenCalledWith("M-001");
expect(mockMissionStore.activateSlice).not.toHaveBeenCalled();
@@ -684,25 +644,17 @@ describe("Scheduler", () => {
expect(mockMissionStore.getSlice).not.toHaveBeenCalled();
});
it("does not auto-advance when mission is not active", async () => {
it("onSliceComplete does not auto-advance when mission is not active", async () => {
const mockMissionStore = createMockMissionStore({
getFeatureByTaskId: vi.fn().mockReturnValue({ id: "F-001", sliceId: "SL-001" }),
updateFeatureStatus: vi.fn().mockReturnValue({ id: "F-001", status: "done" }),
getSlice: vi.fn().mockReturnValue({ id: "SL-001", milestoneId: "MS-001" }),
getMilestone: vi.fn().mockReturnValue({ id: "MS-001", missionId: "M-001" }),
computeSliceStatus: vi.fn().mockReturnValue("complete"),
getMission: vi.fn().mockReturnValue({ id: "M-001", status: "planning", autoAdvance: true }),
});
const store = createMockStore();
const scheduler = new Scheduler(store, { missionStore: mockMissionStore as any });
const onCalls = (store.on as any).mock.calls;
const movedHandler = onCalls.find((call: any) => call[0] === "task:moved")?.[1];
const task = createMockTask({ id: "FN-001", sliceId: "SL-001" });
movedHandler({ task, to: "done" });
await Promise.resolve();
const slice = { id: "SL-001", milestoneId: "MS-001", status: "complete" } as any;
await scheduler.onSliceComplete(slice);
expect(mockMissionStore.getMission).toHaveBeenCalledWith("M-001");
expect(mockMissionStore.activateSlice).not.toHaveBeenCalled();
@@ -716,16 +668,12 @@ describe("Scheduler", () => {
const store = createMockStore();
const scheduler = new Scheduler(store, { missionStore: mockMissionStore as any });
// Trigger task:moved event
const onCalls = (store.on as any).mock.calls;
const movedHandler = onCalls.find((call: any) => call[0] === "task:moved")?.[1];
const slice = { id: "SL-001", milestoneId: "MS-001", status: "complete" } as any;
await scheduler.onSliceComplete(slice);
const task = createMockTask({ id: "FN-001", sliceId: "SL-001" });
movedHandler({ task, to: "done" });
await Promise.resolve();
expect(mockMissionStore.getFeatureByTaskId).toHaveBeenCalledWith("FN-001");
expect(mockMissionStore.updateFeatureStatus).not.toHaveBeenCalled();
// onSliceComplete does not call getFeatureByTaskId; it checks milestone/mission/missionHierarchy
// This test verifies no errors are thrown when slice has no linked feature
expect(mockMissionStore.activateSlice).not.toHaveBeenCalled();
});
it("activateNextPendingSlice finds and activates correct slice", async () => {
@@ -757,7 +705,7 @@ describe("Scheduler", () => {
expect(mockMissionStore.getMissionWithHierarchy).toHaveBeenCalledWith("M-001");
expect(mockMissionStore.activateSlice).toHaveBeenCalledWith("SL-002");
expect(result).toEqual({ id: "SL-002", status: "active" });
expect(result).toEqual({ id: "SL-002", status: "active", orderIndex: 1 });
});
it("activateNextPendingSlice skips milestones with incomplete dependencies", async () => {