원클릭으로
fullstack-worker
Fullstack worker for features touching both server API and TUI
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Fullstack worker for features touching both server API and TUI
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | fullstack-worker |
| description | Fullstack worker for features touching both server API and TUI |
NOTE: Startup and cleanup are handled by worker-base. This skill defines the WORK PROCEDURE.
Use for features that modify BOTH backend (services/server/client) AND the TUI (inbox.py). This includes:
None — but workers should use tuistory skill if available for visual verification of TUI changes.
Read the feature description carefully. Understand the full scope: which server endpoints are needed, which TUI widgets/views change, what the user flow looks like.
Investigate the current code:
inbox.py to understand the TUI structure (widgets, tabs, CSS, bindings)inbox_server.py and services.py for the backendinbox_client.py for client methods you'll need to add/modify.factory/library/architecture.md, .factory/services.yamlPlan the implementation — identify ALL files that need changes:
services.py — new data access functionsinbox_server.py — new endpointsinbox_client.py — new client methodsinbox.py — new widgets, tabs, bindings, CSStests/ — new test files or additions to existing onesBackend first — write failing tests, then implement:
services.py (with tests)inbox_server.py (with TestClient tests)inbox_client.py (with mocked tests)uv run pytest -x -q — verify tests passTUI implementation:
ConversationItem, EventItem, NoteItem)compose() method if adding new tabs/viewsCSS class attributeBINDINGS list@work(thread=True) for any blocking I/Ocall_from_thread to update UI from worker threadsreactive for data that triggers re-rendersWrite TUI tests using Textual Pilot:
async def test_reminders_tab(self):
async with InboxApp().run_test() as pilot:
await pilot.press("ctrl+6")
# Assert tab switched, widgets rendered
Mock the InboxClient to avoid needing a real server.
Run full validation:
uv run pytest -x -q — all tests passuv run pyright — 0 errorsuv run ruff check . — 0 errorsManual verification:
uv run python inbox_server.py & then test API with curllsof -ti :9849 | xargs killVerify ALL items in the feature's expectedBehavior and verificationSteps.
Commit your changes.
class ReminderItem(ListItem):
def __init__(self, data: dict) -> None:
super().__init__()
self.data = data
def compose(self) -> ComposeResult:
d = self.data
t = Text()
t.append("icon ", style="dim")
t.append(d.get("title", ""), style="bold white")
# ... format additional fields
yield Static(t)
# In Tabs widget:
Tab("Reminders", id="tab-rem"),
# In BINDINGS:
Binding("ctrl+6", "filter_rem", "Reminders"),
# In tab_map:
"tab-rem": "reminders",
# In _render_sidebar:
if self._active_filter == "reminders":
for r in self.reminders_data:
lv.append(ReminderItem(r))
if self._active_filter == "reminders":
compose_input.placeholder = "New reminder title (Enter to create)"
{
"salientSummary": "Added Reminders tab to TUI with full CRUD: list display (title, due date, list name), create from compose input, complete via 'c' key, filter by list. Added 3 new server endpoints (PUT /reminders/{id}, DELETE /reminders/{id}, GET /reminders/search). 8 backend tests + 4 TUI pilot tests, all passing.",
"whatWasImplemented": "New ReminderItem widget in inbox.py with title/due_date/list_name display. Reminders tab accessible via Ctrl+6. Compose input creates reminders when on Reminders tab. 'c' key completes selected reminder, 'd' key deletes. Filter by list via input. Empty state shows 'No reminders'. Backend: PUT /reminders/{id} for edit, DELETE /reminders/{id} for delete, search endpoint. Client methods: edit_reminder(), delete_reminder().",
"whatWasLeftUndone": "",
"verification": {
"commandsRun": [
{"command": "uv run pytest -x -q", "exitCode": 0, "observation": "205 passed in 4.1s"},
{"command": "uv run pyright", "exitCode": 0, "observation": "0 errors"},
{"command": "uv run ruff check .", "exitCode": 0, "observation": "All checks passed"},
{"command": "curl -X POST localhost:9849/reminders -H 'Content-Type: application/json' -d '{\"title\":\"Test\"}'", "exitCode": 0, "observation": "201 with ok:true"},
{"command": "curl localhost:9849/reminders?list_name=Reminders", "exitCode": 0, "observation": "JSON array with reminders including 'Test'"}
],
"interactiveChecks": [
{"action": "Would launch TUI, press Ctrl+6 to switch to Reminders tab", "observed": "Reminders tab renders with ReminderItem widgets showing title, due date, list name"},
{"action": "Would type 'Buy groceries' in compose and press Enter", "observed": "New reminder created, appears in list after refresh"},
{"action": "Would press 'c' on a selected reminder", "observed": "Reminder marked complete, disappears from active list"}
]
},
"tests": {
"added": [
{
"file": "tests/test_server_endpoints.py",
"cases": [
{"name": "test_edit_reminder", "verifies": "PUT /reminders/{id} updates title and due date"},
{"name": "test_delete_reminder", "verifies": "DELETE /reminders/{id} removes reminder"},
{"name": "test_reminders_filter_by_list", "verifies": "GET /reminders?list_name=X returns only X list"}
]
},
{
"file": "tests/test_tui_reminders.py",
"cases": [
{"name": "test_reminders_tab_switch", "verifies": "Ctrl+6 activates Reminders tab"},
{"name": "test_reminder_create_from_compose", "verifies": "Enter in compose creates reminder"},
{"name": "test_reminder_complete", "verifies": "'c' key completes selected reminder"},
{"name": "test_reminders_empty_state", "verifies": "Empty list shows 'No reminders' message"}
]
}
]
},
"discoveredIssues": []
}