Manage FABER workflow state (CRUD operations)
Manages FABER workflow state files with CRUD operations. Claude uses this when tracking workflow phases, steps, artifacts, and completion status during FABER execution.
/plugin marketplace add fractary/claude-plugins/plugin install fractary-faber@fractaryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
scripts/state-mark-complete.shscripts/state-record-artifact.shscripts/state-update-step.shState is stored at:
.fractary/plugins/faber/runs/{run_id}/state.json.fractary/plugins/faber/state.jsonState tracks: current phase, phase statuses, artifacts, retry counts, errors, last_event_id </CONTEXT>
<CRITICAL_RULES> YOU MUST:
../core/scripts/)YOU MUST NOT:
<STATE_STRUCTURE>
{
"run_id": "fractary/my-project/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_id": "fractary-claude-plugins-csv-export-20251208T160000",
"work_id": "123",
"workflow_id": "default",
"workflow_version": "2.1",
"status": "in_progress",
"current_phase": "build",
"current_step_index": 2,
"steps_completed": ["generate-spec", "create-branch"],
"last_event_id": 15,
"started_at": "2025-12-03T10:00:00Z",
"updated_at": "2025-12-03T10:30:00Z",
"completed_at": null,
"phases": {
"frame": {
"status": "completed",
"started_at": "2025-12-03T10:00:00Z",
"completed_at": "2025-12-03T10:05:00Z",
"steps": [],
"retry_count": 0
},
"architect": {
"status": "completed",
"started_at": "2025-12-03T10:05:00Z",
"completed_at": "2025-12-03T10:15:00Z",
"steps": [
{"id": "generate-spec", "status": "completed", "started_at": "...", "completed_at": "...", "duration_ms": 5000}
],
"retry_count": 0
},
"build": {
"status": "in_progress",
"started_at": "2025-12-03T10:15:00Z",
"steps": [
{"id": "implement", "status": "in_progress", "started_at": "..."},
{"id": "commit", "status": "pending"}
],
"retry_count": 0
},
"evaluate": {"status": "pending", "steps": [], "retry_count": 0},
"release": {"status": "pending", "steps": [], "retry_count": 0}
},
"artifacts": {
"spec_path": "specs/WORK-00123-feature.md",
"branch_name": "feat/123-add-feature",
"pr_url": null,
"pr_number": null
},
"errors": []
}
Note: Steps in state use id field for identification. For backward compatibility with existing state files, name field is also supported during reads.
</STATE_STRUCTURE>
Initialize a new workflow state file.
Script: ../core/scripts/state-init.sh
Parameters:
work_id (required): Work item identifierrun_id (optional): Run identifier (format: org/project/uuid). If provided, state is stored in per-run directory.workflow_id (optional): Workflow to use (default: "default")state_path (optional): Path to state file (computed from run_id if provided)Returns:
{
"status": "success",
"operation": "init-state",
"work_id": "123",
"run_id": "fractary/my-project/a1b2c3d4-...",
"workflow_id": "default",
"state_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json"
}
Execution:
# With run_id (preferred for new workflows)
../core/scripts/state-init.sh --run-id "$RUN_ID" "$WORK_ID" "$WORKFLOW_ID"
# Legacy (without run_id)
../core/scripts/state-init.sh "$WORK_ID" "$WORKFLOW_ID" "$STATE_PATH"
Read current workflow state.
Script: ../core/scripts/state-read.sh
Parameters:
run_id (optional): Run identifier. If provided, reads from per-run directory.state_path (optional): Path to state file (computed from run_id if provided)query (optional): jq query for specific field (e.g., .current_phase)Returns:
{
"status": "success",
"operation": "read-state",
"state": { ... full state object ... }
}
Or with query:
{
"status": "success",
"operation": "read-state",
"query": ".current_phase",
"result": "build"
}
Execution:
# With run_id (preferred)
../core/scripts/state-read.sh --run-id "$RUN_ID" "$QUERY"
# Legacy
../core/scripts/state-read.sh "$STATE_PATH" "$QUERY"
Update a phase's status and data.
Script: ../core/scripts/state-update-phase.sh
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.phase (required): Phase name (frame, architect, build, evaluate, release)status (required): New status (pending, in_progress, completed, failed, skipped)data (optional): Additional phase data as JSONReturns:
{
"status": "success",
"operation": "update-phase",
"phase": "build",
"phase_status": "in_progress",
"current_phase": "build"
}
Execution:
# With run_id (preferred)
../core/scripts/state-update-phase.sh --run-id "$RUN_ID" "$PHASE" "$STATUS" "$DATA_JSON"
# Legacy
../core/scripts/state-update-phase.sh "$PHASE" "$STATUS" "$DATA_JSON"
Update a step's status within a phase.
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.phase (required): Phase containing the stepstep_id (required): Unique identifier of the step (uses id field, falls back to name for backward compatibility)status (required): New status (pending, in_progress, completed, failed, skipped)data (optional): Step result dataReturns:
{
"status": "success",
"operation": "update-step",
"phase": "build",
"step_id": "implement",
"step_status": "completed"
}
Execution:
step_id (check id field first, then name for backward compatibility)Note: Step identification uses the id field (preferred) or name field (deprecated, backward compatible). This ensures consistent step tracking across logging, state management, and step targeting.
Record an artifact in state (spec, branch, PR, etc.).
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.artifact_type (required): Type of artifact (spec_path, branch_name, pr_url, pr_number, custom)artifact_value (required): Value to recordReturns:
{
"status": "success",
"operation": "record-artifact",
"artifact_type": "branch_name",
"artifact_value": "feat/123-add-feature"
}
Execution:
state.artifacts[artifact_type] = artifact_valueupdated_at timestampMark the workflow as completed or failed.
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.final_status (required): Final status (completed, failed, cancelled)summary (optional): Completion summaryerrors (optional): Error details if failedReturns:
{
"status": "success",
"operation": "mark-complete",
"final_status": "completed",
"completed_at": "2025-12-03T11:00:00Z"
}
Execution:
state.status = final_statusstate.completed_at = now()Track exact step progress within a phase (for resume support).
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.phase (required): Current phase being executedcurrent_step_index (required): Index of the current/next step in the phasesteps_completed (required): Array of step names/IDs that have been completedReturns:
{
"status": "success",
"operation": "update-step-progress",
"phase": "build",
"current_step_index": 2,
"steps_completed": ["generate-spec", "create-branch"],
"resumable": true
}
Execution:
state.current_phase = phasestate.current_step_index = current_step_indexstate.steps_completed = steps_completedupdated_at timestampPurpose: This operation enables exact-step resume by tracking:
When resuming with --resume, the executor reads this state and passes it
to faber-manager as resume_context, allowing the manager to skip completed
steps and continue from the exact position.
Increment the retry counter for the current phase (for Build-Evaluate loop).
Parameters:
run_id (optional): Run identifier. If provided, updates per-run state.phase (optional): Phase to increment retry for (default: current_phase)Returns:
{
"status": "success",
"operation": "increment-retry",
"phase": "evaluate",
"retry_count": 2,
"max_retries": 3,
"can_retry": true
}
Execution:
state.phases[phase].retry_countCheck if a state file exists for a run or work item.
Parameters:
run_id (optional): Run identifier. If provided, checks per-run state.work_id (optional): Work ID to check (legacy)state_path (optional): Specific state file path (computed from run_id if provided)Returns:
{
"status": "success",
"operation": "check-exists",
"exists": true,
"run_id": "fractary/my-project/a1b2c3d4-...",
"state_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json",
"work_id": "123",
"current_phase": "build"
}
Validate state file structure.
Script: ../core/scripts/state-validate.sh
Parameters:
run_id (optional): Run identifier. If provided, validates per-run state.state_path (optional): Path to state file (computed from run_id if provided)Returns:
{
"status": "success",
"operation": "validate-state",
"valid": true,
"run_id": "fractary/my-project/a1b2c3d4-..."
}
Create a backup of current state.
Script: ../core/scripts/state-backup.sh
Parameters:
run_id (optional): Run identifier. If provided, backs up per-run state.state_path (optional): Path to state file (computed from run_id if provided)Returns:
{
"status": "success",
"operation": "backup-state",
"backup_path": ".fractary/plugins/faber/runs/fractary/my-project/a1b2c3d4-.../state.json.backup.20251203T110000Z"
}
</OPERATIONS>
<WORKFLOW>
When invoked with an operation:
Parse Request
Execute Operation
Return Result
<ERROR_HANDLING>
| Error | Code | Action |
|---|---|---|
| State file not found | STATE_NOT_FOUND | Return error (for read operations) or create (for init) |
| Invalid state JSON | STATE_INVALID | Return error with parse details |
| Invalid phase name | INVALID_PHASE | Return error with valid phase names |
| Invalid status | INVALID_STATUS | Return error with valid statuses |
| Write failed | STATE_WRITE_ERROR | Return error, state unchanged |
| Max retries exceeded | MAX_RETRIES | Return with can_retry: false |
| </ERROR_HANDLING> |
<OUTPUT_FORMAT> Always output start/end messages for visibility:
🎯 STARTING: FABER State
Operation: update-phase
Phase: build
Status: in_progress
───────────────────────────────────────
[... execution ...]
✅ COMPLETED: FABER State
Phase: build → in_progress
Current Phase: build
───────────────────────────────────────
</OUTPUT_FORMAT>
<DEPENDENCIES> - `jq` for JSON parsing and manipulation - Existing scripts in `../core/scripts/` </DEPENDENCIES><FILE_LOCATIONS> With run_id (preferred):
.fractary/plugins/faber/runs/{run_id}/state.json.fractary/plugins/faber/runs/{run_id}/metadata.json.fractary/plugins/faber/runs/{run_id}/events/.fractary/plugins/faber/runs/{run_id}/state.json.backup.<timestamp>Legacy (no run_id):
.fractary/plugins/faber/state.json.fractary/plugins/faber/state.json.backup.<timestamp>Helper function to compute state path:
get_state_path() {
local run_id="$1"
if [ -n "$run_id" ]; then
echo ".fractary/plugins/faber/runs/$run_id/state.json"
else
echo ".fractary/plugins/faber/state.json"
fi
}
</FILE_LOCATIONS>
<IDEMPOTENCY> State operations are designed for idempotency: - `init-state`: Only creates if not exists, otherwise returns existing - `update-phase`: Same status update is a no-op - `record-artifact`: Overwrites existing value (idempotent) - `mark-complete`: No-op if already in terminal state </IDEMPOTENCY>Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.