feat(FN-3742): unify agent action gating classifications across permanent a

Merges a significant refactor of agent action gating into a unified `gating-classifications.ts` module shared across permanent agents and executor gating logic, plus new glasses quick-capture support with dedicated routes and parser, and a fix restoring step progress visibility during task execution

Fusion-Task-Id: FN-3742
This commit is contained in:
Fusion
2026-05-08 13:59:14 -07:00
committed by gsxdsm
parent ded66d0488
commit 8c112ffda8
12 changed files with 422 additions and 54 deletions

View File

@@ -1118,14 +1118,14 @@
/* Larger touch targets for file entries on mobile */
.changed-files-sidebar.mobile .changed-files-entry {
padding: 10px var(--space-md);
padding: calc(var(--space-sm) + var(--space-xs) / 2) var(--space-md);
min-height: 36px;
}
/* Clearer active state on mobile */
.changed-files-sidebar.mobile .changed-files-entry.active {
background: var(--card-hover);
border-left: 3px solid var(--in-progress);
border-left: calc(var(--btn-border-width) * 3) solid var(--in-progress);
}
.changed-files-content.mobile {

View File

@@ -210,7 +210,7 @@ async function runConfiguredCommand(
// ── Tool parameter schemas (module-level for reuse in ToolDefinition generics) ──
const taskUpdateParams = Type.Object({
step: Type.Number({ description: "Step number (0-indexed)" }),
step: Type.Number({ description: "Step number (1-indexed)" }),
status: Type.Union(
STEP_STATUSES.map((s) => Type.Literal(s)),
{ description: "New status: pending, in-progress, done, or skipped" },
@@ -3916,18 +3916,28 @@ export class TaskExecutor {
};
}
if (!Number.isInteger(step) || step < 0) {
if (!Number.isInteger(step) || step < 1) {
return {
content: [{
type: "text" as const,
text: `Invalid step number: ${step}. Steps are 0-indexed.`,
text: `Invalid step number: ${step}. Steps are 1-indexed.`,
}],
details: {},
};
}
const task = await store.updateStep(taskId, step, status as StepStatus);
const stepInfo = task.steps[step];
const stepIndex = step - 1;
const task = await store.updateStep(taskId, stepIndex, status as StepStatus);
const stepInfo = task.steps[stepIndex];
if (!stepInfo) {
return {
content: [{
type: "text" as const,
text: `Invalid step number: ${step}. This task has ${task.steps.length} step(s) (1-indexed).`,
}],
details: {},
};
}
const persistedStatus = stepInfo.status;
const progress = task.steps.filter((s) => s.status === "done").length;