Skip to content

wndnjs3865/flowagent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

31 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

FlowAgent

A local-first Korean SMB workflow orchestrator โ€” Run pre-built workflows for daily office work entirely on your laptop. Your company data never leaves the machine.

License: Apache 2.0 Made for Korean SMB GitHub stars

๐ŸŒ https://taskflow.kr โ€” ๋‹ค์šด๋กœ๋“œ ยท ๊ฐ€๊ฒฉ ยท ๋ฌธ์„œ ยท ํ…œํ”Œ๋ฆฟ

ํšŒ์‚ฌ ๋ฐ์ดํ„ฐ๋Š” ๋…ธํŠธ๋ถ ์•ˆ์—๋งŒ. ํ•œ๊ตญ์–ด ์‚ฌ๋ฌด ์ž๋™ํ™”, 8 ์›Œํฌํ”Œ๋กœ ยท 3 ํŽ˜๋ฅด์†Œ๋‚˜ ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

๐ŸŽ‰ 2026-05-20 ์ถœ์‹œ โ€” A ์‚ฌ๋ฌด์ง ยท B 1์ธ ์ž์˜์—…ยทํ”„๋ฆฌ๋žœ์„œ ยท D SMB ์‚ฌ์žฅ 3 ํŽ˜๋ฅด์†Œ๋‚˜ ์นด๋“œ ๋ชจ๋‘ ์ž‘๋™.

โฌ‡ ๋‹ค์šด๋กœ๋“œ ยท ๐Ÿ“– ๋ฌธ์„œ ยท ๐Ÿ’ฐ ๊ฐ€๊ฒฉ ยท ๐ŸŽฏ 8 ์›Œํฌํ”Œ๋กœ ยท ๐Ÿ“ LICENSE ยท โ„ข TRADEMARK


ํ•œ ํ™”๋ฉด ์š”์•ฝ

ํŽ˜๋ฅด์†Œ๋‚˜๋ณ„ ์ง„์ž…

ํŽ˜๋ฅด์†Œ๋‚˜ ์ง„์ž… ํŽ˜์ด์ง€ ํ•ต์‹ฌ ์›Œํฌํ”Œ๋กœ
A ์‚ฌ๋ฌด์ง ยท ์ด๋ฌด ยท ์šด์˜ํŒ€ /sumu meeting-actions ยท weekly-report ยท approval-triage
B 1์ธ ์ž์˜์—… ยท ํ”„๋ฆฌ๋žœ์„œ /solo quote-email ยท sales-followup ยท sns-replies
D SMB ์‚ฌ์žฅ ยท ๋Œ€ํ‘œ /executive sales-summary (๋งค์ผ) ยท weekly-report (๋ฐ›๋Š” ์ž…์žฅ)

๊ณตํ†ต: sales-summaryยทinquiry-triage๋Š” ํŽ˜๋ฅด์†Œ๋‚˜ ๋น„์ค‘๋งŒ ๋‹ค๋ฅผ ๋ฟ 3 ํŽ˜๋ฅด์†Œ๋‚˜ ๋ชจ๋‘ ์‚ฌ์šฉ. ์ž์„ธํ•œ ๋งคํ•‘์€ Bundled workflows.

์ฐจ๋ณ„์  (ํ•œ๊ตญ ์‹œ์žฅ ์œ ์ผ)

  • ํšŒ์‚ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธํŠธ๋ถ ๋ฐ–์œผ๋กœ ์•ˆ ๋‚˜๊ฐ (local-first) โ€” Notion AIยทChatGPTยท๋คผํŠผ์€ ํด๋ผ์šฐ๋“œ SaaS.
  • ํ•œ๊ตญ์–ด ์‚ฌ๋ฌด ์›Œํฌํ”Œ๋กœ 8์ข… ๋ฒˆ๋“ค โ€” n8nยทMakeยทZapier๋Š” ๋นˆ ํŽ˜์ด์ง€์—์„œ ์‹œ์ž‘.
  • start.bat ๋”๋ธ”ํด๋ฆญ ์ง„์ž… โ€” ๋น„๊ฐœ๋ฐœ์ž๋„ 5๋ถ„ ์•ˆ์— ์ฒซ ๊ฒฐ๊ณผ.

๋ฐ˜๋ณต ์—…๋ฌด ์ŠคํŠธ๋ ˆ์Šค๋ฅผ ์ค„์ด๋Š” ๋กœ์ปฌ ์›Œํฌํ”Œ๋กœ์šฐ ๋Ÿฌ๋„ˆ. LLM ํ˜ธ์ถœ๊ณผ ์…ธ ๋ช…๋ น์„ YAML ํ•œ ํŒŒ์ผ๋กœ ์—ฎ์–ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ SSE๋กœ ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ผ ์‚ฌ์šฉ์žยท๋‹จ์ผ ๋จธ์‹ ยทDAG ์—†์Œยทํ ์—†์Œ.


๋น ๋ฅธ ์‹œ์ž‘

๊ถŒ์žฅ: taskflow.kr/download์—์„œ zip ๋ฐ›๊ธฐ โ†’ ์••์ถ• ํ’€๊ณ  start.bat ๋”๋ธ”ํด๋ฆญ. Anthropic API ํ‚ค๋งŒ ์ž…๋ ฅํ•˜๋ฉด ๋.

๊ฐœ๋ฐœ์ž: git clone https://github.com/wndnjs3865/flowagent.git && pnpm install && pnpm dev

๋„๋ฉ”์ธ ์šฉ์–ด (Workflow, Step, Run, Runner, Agent) ๋Š” CONTEXT.md ์— ์ •์˜๋ผ ์žˆ์–ด์š”. ์ฝ”๋“œ, ์ปค๋ฐ‹, PR ์ œ๋ชฉ์—์„œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.


์–ด๋””๋ถ€ํ„ฐ ์ฝ์–ด์•ผ ํ•˜๋‚˜์š”?

์ด README๋Š” ๋‘ ์ข…๋ฅ˜์˜ ๋…์ž๋ฅผ ์œ„ํ•ด ๋ถ„๋ฆฌ๋ผ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณธ์ธ ๊ฒฝ๋กœ๋งŒ ๋”ฐ๋ผ๊ฐ€์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ ์‹œ์ž‘ ์œ„์น˜ ๋ชฉํ‘œ
์ผ๋ฐ˜ ์‚ฌ์šฉ์ž (๋น„๊ฐœ๋ฐœ์ž, ์‚ฌ๋ฌดยท์ด๋ฌดยท์˜์—…์ง€์›) โ€” ๋…ธํŠธ๋ถ์—์„œ 8 ์›Œํฌํ”Œ๋กœ ๋ฐ๋ชจ๋ฅผ ์ง์ ‘ ๋Œ๋ ค๋ณด๊ณ  ์‹ถ์Œ ๋ฐ”๋กœ ์•„๋ž˜ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์šฉ 5๋ถ„ ์‹œ์ž‘ ๊ฐ€์ด๋“œ ์„ค์น˜ โ†’ 8 ์›Œํฌํ”Œ๋กœ ๋ฐ๋ชจ ์‹คํ–‰. customize๋Š” ๋ฏธํŒ… ์‹ ์ฒญ์œผ๋กœ
๊ฐœ๋ฐœ์ž / Pilot ์šด์˜์ž โ€” ์ฝ”๋“œ ์ˆ˜์ •, ์ƒˆ ์›Œํฌํ”Œ๋กœ์šฐ ์ž‘์„ฑ, ๋ฏธํŒ… ์‹œ์—ฐยทcustomize ์ง„ํ–‰ Developer quickstart โ†’ Demo path (Pilot ์šด์˜์ž์šฉ) โ†’ Writing a workflow 8 ์›Œํฌํ”Œ๋กœ ์™ธ ์‚ฌ๋ก€๋ฅผ yaml๋กœ, 4์ฃผ Pilot ์ง„ํ–‰, ์ฝ”๋“œ ๊ธฐ์—ฌ

์œ„ ๋‘ ๊ฒฝ๋กœ ๋ชจ๋‘์— ๊ณตํ†ต์œผ๋กœ ์œ ์šฉํ•œ ์„น์…˜: 1๋ถ„ ๋ฐ๋ชจ ์˜์ƒ, Bundled workflows, Run logs, Limits.


์ผ๋ฐ˜ ์‚ฌ์šฉ์ž โ€” ๋”๋ธ”ํด๋ฆญ 2๋ฒˆ์ด๋ฉด ๋

๋น„๊ฐœ๋ฐœ์ž๋„ GitHubยทPowerShellยทํ„ฐ๋ฏธ๋„์„ ๋ชจ๋ฅด๊ณ  ๋…ธํŠธ๋ถ์—์„œ 8 ์›Œํฌํ”Œ๋กœ ๋ฐ๋ชจ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ํ๋ฆ„.

์œ„ ํฐ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด flowagent-main.zip ์ด ์ž๋™์œผ๋กœ ๋ฐ›์•„์ง‘๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ ํด๋”๋กœ ๊ฐ€์„œ zip ํŒŒ์ผ์„ ์šฐํด๋ฆญ โ†’ "๋ชจ๋“  ํŒŒ์ผ ์••์ถ• ํ’€๊ธฐ" โ†’ ์œ„์น˜๋Š” C:\flowagent ๊ฐ™์ด ํ•œ๊ธ€ยท๊ณต๋ฐฑ ์—†๋Š” ํด๋” ๊ถŒ์žฅ.

2๏ธโƒฃ ์••์ถ• ํ‘ผ ํด๋” ์•ˆ์˜ start.bat ๋”๋ธ”ํด๋ฆญ

๋‹ค์Œ 4๋‹จ๊ณ„๊ฐ€ ์ž๋™์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ํ‘œ ์˜ค๋ฅธ์ชฝ "๋ณธ์ธ์ด ํ•  ์ผ"๋งŒ ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ž๋™ ์ง„ํ–‰ ๋ณธ์ธ์ด ํ•  ์ผ
Node.js ์„ค์น˜ ์—ฌ๋ถ€ ํ™•์ธ ์—†์œผ๋ฉด nodejs.org๊ฐ€ ์ž๋™์œผ๋กœ ์—ด๋ฆผ โ†’ LTS ์ดˆ๋ก ๋ฒ„ํŠผ์œผ๋กœ ์„ค์น˜ํ•œ ๋’ค start.bat ๋‹ค์‹œ ๋”๋ธ”ํด๋ฆญ
pnpm ์ž๋™ ์„ค์น˜ (corepack ๋˜๋Š” npm) (์—†์Œ)
๋ฉ”๋ชจ์žฅ ์ž๋™ ์‹คํ–‰ โ†’ .env ํŒŒ์ผ ์—ด๋ฆผ ANTHROPIC_API_KEY= ๋’ค์— ๋ณธ์ธ ํ‚ค ๋ถ™์—ฌ๋„ฃ๊ณ  Ctrl+S โ†’ ๋ฉ”๋ชจ์žฅ ๋‹ซ๊ธฐ (ํ‚ค ๋ฐœ๊ธ‰ 1๋ถ„ โ€” Create Key โ†’ sk-ant-โ€ฆ ๋ณต์‚ฌ)
์˜์กด์„ฑ ์„ค์น˜ + ์„œ๋ฒ„ ์‹œ์ž‘ + ๋ธŒ๋ผ์šฐ์ € ์ž๋™ ์—ด๊ธฐ ๋ธŒ๋ผ์šฐ์ €์— 5์žฅ ์นด๋“œ ๋ณด์ด๋ฉด ์นด๋“œ 1๊ฐœ โ†’ Run

๊ฒ€์€ ์ฐฝ์€ ๋‹ซ์ง€ ๋งˆ์„ธ์š” โ€” ์„œ๋ฒ„๊ฐ€ ๊บผ์ง‘๋‹ˆ๋‹ค. (SmartScreen์ด start.bat ์‹คํ–‰ ๊ฒฝ๊ณ ๋ฅผ ๋„์šฐ๋ฉด ์ถ”๊ฐ€ ์ •๋ณด โ†’ ์‹คํ–‰.)


๋‚ด ๋ฐ์ดํ„ฐ 1๊ฐœ ๋„ฃ์–ด๋ณด๊ธฐ (์„ ํƒ, 3๋ถ„)

8 ์›Œํฌํ”Œ๋กœ ๋ชจ๋‘ ๋…ธํŠธ๋ถ ์•ˆ ํŒŒ์ผ์„ LLM ์ž…๋ ฅ์œผ๋กœ ์”๋‹ˆ๋‹ค. ๊ทธ ํŒŒ์ผ์„ ๋ณธ์ธ ๋ฐ์ดํ„ฐ๋กœ ๊ฐ™์€ ์ด๋ฆ„ยท๊ฐ™์€ ํ˜•์‹์œผ๋กœ ๋ฎ์–ด์“ฐ๋ฉด ๋ณธ์ธ ๋ฐ์ดํ„ฐ ๊ฒฐ๊ณผ๊ฐ€ ์ฆ‰์‹œ ๋‚˜์˜ต๋‹ˆ๋‹ค.

์›Œํฌํ”Œ๋กœ์šฐ ๋ฐ”๊ฟ€ ํŒŒ์ผ ํ˜•์‹
meeting-actions workflows\fixtures\meeting-notes-2026-w19.md ํ•œ๊ตญ์–ด ํšŒ์˜๋ก (.md)
weekly-report workflows\fixtures\weekly-progress-2026-w19.md ํ•œ ์ฃผ ์ง„ํ–‰ ๋…ธํŠธ (.md)
sales-summary workflows\fixtures\sales-2026-04.csv CSV (Excel ์ €์žฅ ์‹œ "CSV UTF-8")
inquiry-triage workflows\fixtures\inquiries-2026-05.csv CSV โ€” id,์ ‘์ˆ˜์ผ์‹œ,๊ณ ๊ฐ๋ช…,๋ฌธ์˜๋‚ด์šฉ
approval-triage workflows\fixtures\inbox-approvals-2026-05.md ๊ฒฐ์žฌ ์š”์ฒญ (.md, ## REQ-001 ํ˜•์‹)
quote-email workflows\fixtures\project-brief-2026-w20.md ํ”„๋กœ์ ํŠธ brief + ๋ณธ์ธ ๋‹จ๊ฐ€ (.md)
sales-followup workflows\fixtures\client-meeting-2026-w22.md ๋ฏธํŒ… raw ๋…ธํŠธ (.md)
sns-replies workflows\fixtures\sns-comments-2026-w23.md SNS ๋Œ“๊ธ€ยทDM raw export (.md)
  1. ์œ„ ํ‘œ์—์„œ 1๊ฐœ ์„ ํƒ โ†’ Explorer์—์„œ ํ•ด๋‹น ํŒŒ์ผ ๋”๋ธ”ํด๋ฆญํ•ด ์—ด๊ธฐ
  2. ๋ณธ์ธ ๋ฐ์ดํ„ฐ๋กœ ๋‚ด์šฉ ๋ฐ”๊พธ๊ณ  ์ €์žฅ
  3. ๋ธŒ๋ผ์šฐ์ € ์ƒˆ๋กœ๊ณ ์นจ โ†’ ๊ฐ™์€ ์นด๋“œ โ†’ Run

๋” ๊นŠ์€ customize ยท 4์ฃผ Pilot

๋ฏธํŒ… ์‹ ์ฒญ โ†’ wndnjs3865@naver.com (๋˜๋Š” ํŽ˜์ด์ง€ ์ƒ๋‹จ Pilot ๋ฏธํŒ… ์‹ ์ฒญ ๋ฐฐ๋„ˆ). 30๋ถ„ ์•ˆ์— ๊ท€์‚ฌ ๋ฐ์ดํ„ฐ๋กœ YAML ํ•˜๋‚˜ ํ•จ๊ป˜ ๋งŒ๋“ค์–ด ๋“œ๋ฆฝ๋‹ˆ๋‹ค โ€” ํšŒ์‚ฌ ๋ฐ์ดํ„ฐ๋Š” ๋…ธํŠธ๋ถ์„ ๋ฒ—์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ง‰ํž ๋•Œ

  • "Node.js๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค" โ†’ nodejs.org๊ฐ€ ์ž๋™์œผ๋กœ ์—ด๋ฆผ. LTS ์„ค์น˜ ํ›„ start.bat ๋‹ค์‹œ ๋”๋ธ”ํด๋ฆญ.
  • ๊ฒ€์€ ์ฐฝ์— "API ํ‚ค" ์˜ค๋ฅ˜ โ†’ ํด๋”์˜ .env ํŒŒ์ผ์„ ๋ฉ”๋ชจ์žฅ์œผ๋กœ ๋‹ค์‹œ ์—ด์–ด ANTHROPIC_API_KEY= ๋’ค ํ‚ค (์•ž๋’ค ๊ณต๋ฐฑยท๋”ฐ์˜ดํ‘œ ์—†์ด) ํ™•์ธ ํ›„ ์ €์žฅ โ†’ start.bat ๋‹ค์‹œ.
  • ๋ธŒ๋ผ์šฐ์ € "์‚ฌ์ดํŠธ ์—ฐ๊ฒฐ ๋ถˆ๊ฐ€" โ†’ ๊ฒ€์€ ์ฐฝ์— FlowAgent listening on โ€ฆ ์ค„ ์žˆ๋Š”์ง€ ํ™•์ธ. ์—†์œผ๋ฉด start.bat ๋‹ค์‹œ ๋”๋ธ”ํด๋ฆญ.
  • ๊ฒ€์€ ์ฐฝ ๋‹ซํ˜€๋ฒ„๋ฆผ โ†’ ์„œ๋ฒ„๊ฐ€ ๊บผ์กŒ์Šต๋‹ˆ๋‹ค. start.bat ๋‹ค์‹œ ๋”๋ธ”ํด๋ฆญ.
  • ํ•œ๊ตญ์–ด ๊นจ์ง โ†’ ๋ธŒ๋ผ์šฐ์ € Ctrl+R ์ƒˆ๋กœ๊ณ ์นจ.

Developer quickstart

pnpm install
cp .env.example .env
# edit .env and put your Anthropic API key in ANTHROPIC_API_KEY=
pnpm dev
# open http://localhost:3000

.env is loaded automatically via tsx --env-file=.env โ€” no dotenv dependency needed.

Required env:

Var Purpose
ANTHROPIC_API_KEY Used by llm steps. Without it, runs fail at the first llm step.
PORT HTTP port (default 3000).
FLOWAGENT_WORKFLOWS_DIR Directory scanned for *.yaml workflows (default workflows).
FLOWAGENT_RUNS_DIR Directory where per-run JSONL audit logs are written (default runs). Created on demand.
FLOWAGENT_PILOT_CONTACT_EMAIL Email used by the Listing page "Pilot ๋ฏธํŒ… ์‹ ์ฒญ" CTA button. The server builds a mailto: link with a fixed Korean subject. Defaults to the FlowAgent official sales channel wndnjs3865@naver.com โ€” override only if you fork for your own sales.
FLOWAGENT_SHARE_SECRET HMAC signing secret for /share/* URLs โ€” used to send dashboard results to a phone (spec ยง 5 ์˜ต์…˜ 2). Must be at least 32 characters โ€” shorter values throw at runtime. When unset, the share UI is hidden and /share/* routes return 503. Generate with openssl rand -base64 32 (or PowerShell [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))) and keep it in .env, never commit.
FLOWAGENT_PUBLIC_ORIGIN Optional public origin (e.g. https://flowagent.example.com) used when building share URLs. Useful behind a reverse proxy where the Node server sees localhost but the user-facing URL is the public domain. When unset, x-forwarded-proto + x-forwarded-host headers are honored if both present, falling back to the request URL itself.

1๋ถ„ ๋ฐ๋ชจ ์˜์ƒ

๊ธฐ๋ณธ 5์ข… ์›Œํฌํ”Œ๋กœ์šฐ ์ˆœํšŒ ๋ฐ๋ชจ. ๋…ธํŠธ๋ถ์—์„œ 5๋ถ„ ์‹œ์ž‘ โ†’ ์‹ค์ œ ๊ฒฐ๊ณผ๊นŒ์ง€ ํ•œ ํ™”๋ฉด. (B ํŽ˜๋ฅด์†Œ๋‚˜ 3์ข…์€ ์ฐจ๊ธฐ ์˜์ƒ์— ํฌํ•จ ์˜ˆ์ •.)

์˜์ƒ ์ œ์ž‘ ๊ฐ€์ด๋“œ

์˜์ƒ์€ ์ง์ ‘ ๋…นํ™”ยทํŽธ์ง‘ยท์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ ˆ์ฐจ๋Š” ๋‹ค์Œ ๋‘ ๋ฌธ์„œ ๋”ฐ๋ผ๊ฐ€๋ฉด 30๋ถ„:

  1. Storyboard โ€” docs/sales/pilot-demo-storyboard.md โ€” ์ดˆ ๋‹จ์œ„ ์ปทยท๋‚ด๋ ˆ์ด์…˜ยท๋…นํ™” ๋„๊ตฌยทํŽธ์ง‘ ๊ฐ€์ด๋“œยทfallback. ์‚ฌ์ „ ์ ๊ฒ€ 60์ดˆ + 1๋ถ„ ๋ถ„ํ•  8๋‹จ๊ณ„.
  2. Asset ํ˜ธ์ŠคํŒ… โ€” assets/README.md โ€” GitHub Release ์—…๋กœ๋“œ ์ ˆ์ฐจ, ํŒŒ์ผ๋ช… ๊ทœ์•ฝ(pilot-demo-<์šฉ๋„>-<duration>.<ext>), 1MB ์ด์ƒ ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” repo commit ๊ธˆ์ง€.

์š”์•ฝ ํ๋ฆ„:

# 1. ์‚ฌ์ „ ์ ๊ฒ€ (60์ดˆ) โ€” storyboard "์‚ฌ์ „ ์ ๊ฒ€" ์„น์…˜ ๊ทธ๋Œ€๋กœ
rm -f runs/*.jsonl && pnpm dev > /dev/null 2>&1 &
sleep 3 && curl -sf http://localhost:3000/ > /dev/null && echo OK

# 2. OBS / QuickTime์œผ๋กœ 1920ร—1080 30fps ๋…นํ™” (storyboard ๋”ฐ๋ผ 75์ดˆ โ†’ 60์ดˆ ์ปท ํŽธ์ง‘)

# 3. GitHub Release์— ์—…๋กœ๋“œ
gh release create v0.1.0-demo --title "Pilot demo assets v0.1" \
  --notes "1๋ถ„ ๋ฐ๋ชจ ์˜์ƒ" ./pilot-demo-1min.mp4

# 4. README ์œ„ <video src="..."> ์˜ URL์„ ์ƒˆ asset URL๋กœ ๊ต์ฒด
gh release view v0.1.0-demo --json assets --jq '.assets[0].browser_download_url'

๊ธฐ๋ณธ 5์ข… ์›Œํฌํ”Œ๋กœ์šฐ ์‹ค์‹œ๊ฐ„ ์‹คํ–‰ ๊ฒ€์ฆ ๊ฒฐ๊ณผ (์˜์ƒ storyboard ์ธก์ • ๊ธฐ์ค€): weekly-report 9์ดˆ / meeting-actions 10์ดˆ / sales-summary 15์ดˆ / inquiry-triage 24์ดˆ / approval-triage 17์ดˆ โ€” ์ด 75์ดˆ. ์ปท ํŽธ์ง‘์œผ๋กœ 60์ดˆ ์••์ถ•. (B ํŽ˜๋ฅด์†Œ๋‚˜ 3์ข… timing์€ ์ฐจ๊ธฐ ์ธก์ • ์‹œ ์ถ”๊ฐ€.)

Demo path (Pilot ์šด์˜์ž์šฉ) โ€” first run in 5 minutes

The fastest path from clone to a result you can show a Pilot stakeholder. Total: 5 minutes including prereqs, 3 minutes if Node/pnpm are already installed.

Prereqs (2 minutes)

Windows ์‚ฌ์šฉ์ž ์•ˆ๋‚ด (PowerShell ยท cmd ยท Git Bash ๋ชจ๋‘ ๋™์ผ ๋™์ž‘)

์ด ํ”„๋กœ์ ํŠธ์˜ shell step์€ OS-์ค‘๋ฆฝ node -e "..." ํ•œ ์ค„๋กœ ํ†ต์ผ๋ผ ์žˆ์–ด ์ถ”๊ฐ€๋กœ Git BashยทWSL ์„ค์น˜๊ฐ€ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. Windows ํ‘œ์ค€ PowerShellยทcmd ์–ด๋А ์ชฝ์—์„œ๋„ 8 ์›Œํฌํ”Œ๋กœ ๋ชจ๋‘ ๊ทธ๋Œ€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ๊ณ„ ๋ช…๋ น (PowerShell ๋˜๋Š” cmd)
1. Node.js ์„ค์น˜ https://nodejs.org/ "LTS" installer ๋˜๋Š” winget install OpenJS.NodeJS.LTS
2. pnpm ์„ค์น˜ npm i -g pnpm
3. ํ”„๋กœ์ ํŠธ ๋ฐ›๊ธฐ git clone https://github.com/wndnjs3865/flowagent && cd flowagent
4. ์˜์กด์„ฑ ์„ค์น˜ pnpm install
5. .env ์ƒ์„ฑ copy .env.example .env (cmd) ๋˜๋Š” Copy-Item .env.example .env (PowerShell) โ€” ๊ทธ ํ›„ .env ์—ด์–ด ANTHROPIC_API_KEY=sk-ant-... ๋ถ™์—ฌ๋„ฃ๊ธฐ
6. ์„œ๋ฒ„ ์‹คํ–‰ pnpm dev
7. ๋ธŒ๋ผ์šฐ์ € http://localhost:3000

PowerShell ์‹คํ–‰์ •์ฑ… ์ด์Šˆ ์‹œ โ€” pnpm.ps1์ด ์ฐจ๋‹จ๋˜๋ฉด ํ•œ ๋ฒˆ๋งŒ:

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

์ดํ›„ pnpm dev ์ •์ƒ. cmd์—์„œ๋Š” ์ด ๋ฌธ์ œ ์—†์Œ.

Steps (3 minutes)

  1. git clone <this repo> && cd flowagent
  2. pnpm install
  3. cp .env.example .env, then open .env and paste your key into ANTHROPIC_API_KEY=sk-ant-...
  4. pnpm dev โ€” you should see FlowAgent listening on http://localhost:3000. Leave it running.
  5. Open http://localhost:3000 in a browser. You'll see 5 bundled workflows in the list.
  6. Click meeting-actions โ†’ Run. Each step streams into the log box live (step-start โ†’ step-output โ†’ step-end). The full run takes ~20 seconds.
  7. After the run finishes, open runs/<runId>.jsonl in your editor. The exact events you just saw are on disk, one JSON object per line, ready to replay or share.

Try sales-summary for an executive-summary demo, inquiry-triage for a CS-desk demo, or approval-triage for an office-manager demo. Each finishes in under 30 seconds.

What you should see at the end of step 6 (the Slack-format step of meeting-actions), in Korean, ready to paste:

์ด๋ฒˆ ์ฃผ ์•ก์…˜ ์•„์ดํ…œ ์ •๋ฆฌํ•ด๋“œ๋ฆด๊ฒŒ์š” ๐Ÿ‘‡

*์ดํŒ€์žฅ*
โ€ข [5/16] ๋‹จ๊ณจ ๊ณ ๊ฐ ์‚ฌ์€ํ’ˆ ์ œ๊ณต ๋ฐฉ์•ˆ ์ดˆ์•ˆ ์ž‘์„ฑ
โ€ข [5/18] ์ฟ ํŒก ๊ด‘๊ณ ๋น„ ์žฌํŽธ์„ฑ ์•ˆ ํšŒ์˜ ์ „ ๋ณด๊ณ 
*๋ฐ•๋งค๋‹ˆ์ €*
โ€ข [5/15] ๋งˆ์ผ€ํŒ… ์ฃผ๋‹ˆ์–ด ์ฑ„์šฉ๊ณต๊ณ  ์ดˆ์•ˆ ์ž‘์„ฑ
...

Pilot meeting โ€” pre-flight (30์ดˆ ์‚ฌ์ „ ์ ๊ฒ€)

๋ฏธํŒ… 30๋ถ„ ์ „, ํ™”๋ฉด ๊ณต์œ  ์‹œ์ž‘ ์ง์ „์— ์•„๋ž˜ 4๊ฐ€์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ ์‹œ์—ฐ์ด ๋Š๊ธฐ์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ์ตœ์†Œ ๊ฐ€๋“œ.

# 1. API ํ‚ค ๋™์ž‘ ํ™•์ธ โ€” ๋นˆ ๊ฒฐ๊ณผ๋ฉด .env์˜ ANTHROPIC_API_KEY๋ฅผ ๋‹ค์‹œ ํ™•์ธ
curl -s -o /dev/null -w "key=%{http_code}\n" -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" https://api.anthropic.com/v1/models | grep -E "200|key="

# 2. ์„œ๋ฒ„ ์‚ด์•„์žˆ๋Š”์ง€ โ€” 200์ด์–ด์•ผ ํ•จ
curl -s -o /dev/null -w "server=%{http_code}\n" http://localhost:3000/

# 3. runs/ ๋น„์–ด์žˆ๋Š”์ง€ โ€” ์ƒˆ ์ถœ๋ ฅ์ด ํ•œ๋ˆˆ์— ๋ณด์ด๊ฒŒ
ls runs/*.jsonl 2>/dev/null | wc -l   # 0์ด๋ฉด OK, ์•„๋‹ˆ๋ฉด mv runs runs.bak && mkdir runs

# 4. ๋ธŒ๋ผ์šฐ์ € zoom 125%+ โ€” ํ™”๋ฉด ๊ณต์œ  ์‹œ ๊ฐ€๋…์„ฑ

Pilot meeting โ€” 3-minute live demo script (๋ฒ”์šฉ)

ํ™”๋ฉด ๊ณต์œ ํ•˜๋ฉด์„œ ์•„๋ž˜ ๋ฉ˜ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋”ฐ๋ผ ์ฝ์œผ์„ธ์š”. ์ด 3๋ถ„, ์‹œ์—ฐ 3๊ฑด.

(0:00, ์ธํŠธ๋กœ โ€” 20์ดˆ) "FlowAgent๋Š” ๋…ธํŠธ๋ถ ํ•œ ๋Œ€์—์„œ ๋„๋Š” ์›Œํฌํ”Œ๋กœ์šฐ ๋„์šฐ๋ฏธ์˜ˆ์š”. ํšŒ์‚ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์™ธ๋ถ€ SaaS์— ์˜ฌ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋˜๋Š” ์‚ฌ๋ฌด ์—…๋ฌด๋ฅผ ๋งค์ผ ๊ฐ™์€ ์†์œผ๋กœ ๋‹ค์‹œ ํ•˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒŒ ๋ชฉํ‘œ์˜ˆ์š”."

(0:20, ์‹œ์—ฐ 1 ยท meeting-actions โ€” 50์ดˆ) Run ๋ˆ„๋ฅด๋ฉฐ: "์–ด์ œ ํšŒ์˜๋ก์„ ๊ทธ๋Œ€๋กœ ๋„ฃ์–ด ๋ณธ ๊ฑฐ์˜ˆ์š”. ๋‹จ ๋ช‡ ์ดˆ ๋งŒ์— ๋‹ด๋‹น์ž๋ณ„ ์•ก์…˜ ์•„์ดํ…œ์ด ํ•œ๊ตญ์–ด๋กœ ์ •๋ฆฌ๋˜๊ณ , Slack์— ๊ทธ๋Œ€๋กœ ๋ถ™์—ฌ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•์‹๊นŒ์ง€ ๋‚˜์˜ต๋‹ˆ๋‹ค."

(1:10, ์‹œ์—ฐ 2 ยท sales-summary โ€” 50์ดˆ) Run ๋ˆ„๋ฅด๋ฉฐ: "์ด๋ฒˆ์—” 4์›” ๋งค์ถœ CSV์˜ˆ์š”. ์ฑ„๋„๋ณ„ ์ด์ƒ์น˜๋ฅผ ์งš์–ด์ฃผ๊ณ , ๊ฒฝ์˜์ง„ ๋ณด๊ณ ์šฉ 3๋ฌธ์žฅ ์š”์•ฝ์ด ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค."

(2:00, ์‹œ์—ฐ 3 ยท inquiry-triage โ€” 50์ดˆ) Run ๋ˆ„๋ฅด๋ฉฐ: "๊ณ ๊ฐ ๋ฌธ์˜ 6๊ฑด์ด์—์š”. ์นดํ…Œ๊ณ ๋ฆฌยท๊ธด๊ธ‰๋„๋กœ ๋ถ„๋ฅ˜๋œ ํ‘œ๊ฐ€ ๋จผ์ € ๋‚˜์˜ค๊ณ , ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋‹ต๋ณ€ ์ดˆ์•ˆ๊นŒ์ง€ ํ•œ ๋ฒˆ์— ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค. CS ๋‹ด๋‹น์ž๊ฐ€ ํ†ค๋งŒ ๋‹ค๋“ฌ์œผ๋ฉด ๋์ด์—์š”."

(2:50, ํด๋กœ์ง• โ€” 30์ดˆ) runs/ ํด๋” ์—ด๋ฉฐ: "๋ณด์‹œ๋‹ค์‹œํ”ผ ์ถœ๋ ฅ์€ ๋ชจ๋‘ ์ž๋™์œผ๋กœ ๋””์Šคํฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ํ•œ ๋‹ฌ ๋’ค์— '์ด ์ž๋™ํ™”๊ฐ€ ์‹œ๊ฐ„์„ ์–ผ๋งˆ๋‚˜ ์•„๊ผˆ๋Š”์ง€' ๋ฆฌํฌํŠธ๋„ ๋ช…๋ น ํ•œ ์ค„๋กœ ๋ฝ‘์„ ์ˆ˜ ์žˆ์–ด์š”. ๋‹ค์Œ ์ฃผ์— ๊ท€์‚ฌ ๋ฐ์ดํ„ฐ 1๊ฑด์œผ๋กœ ๊ฐ™์ด ๋งŒ๋“ค์–ด ๋ณด๋ฉด ์–ด๋– ์„ธ์š”?"

Persona-specific demo paths (์‹œ์—ฐ ์ˆœ์„œ ๊ฐˆ์•„๋ผ์šฐ๊ธฐ)

์ƒ๋Œ€ ํšŒ์‚ฌ๊ฐ€ ์–ด๋А ๋ถ€์„œ๋ฅผ ๋ฐ๋ ค์˜ค๋Š”์ง€ ๋ฏธ๋ฆฌ ์•Œ๋ฉด ์‹œ์—ฐ์„ ๋ฐ”๊ฟ”์„œ ์ฒซ ์ž„ํŒฉํŠธ๋ฅผ ์ตœ๋Œ€ํ™”ํ•ฉ๋‹ˆ๋‹ค.

์ƒ๋Œ€ ์ถ”์ฒœ ์‹œ์—ฐ ์ˆœ์„œ (3๋ถ„) ํด๋กœ์ง• ๊ฐ•์กฐ์ 
CSํŒ€์žฅ / ์šด์˜ํŒ€์žฅ inquiry-triage โ†’ meeting-actions โ†’ approval-triage "๋งค์ผ ๋‹ต๋ณ€ ํ†ค ํ†ต์ผ + ์šฐ์„ ์ˆœ์œ„ ๋ถ„๋ฅ˜ + ๊ฒฐ์žฌ ๋ˆ„๋ฝ ๋ฐฉ์ง€"
์žฌ๋ฌดยท์ด๋ฌดยทCFO sales-summary โ†’ approval-triage โ†’ weekly-report "์›”๋ง 1-pager ์ž๋™ํ™” + ๊ฒฐ์žฌ ์ž”๋Ÿ‰ ๊ฐ€์‹œํ™” + ์ฃผ๊ฐ„ ๋ณด๊ณ  ํ‘œ์ค€ํ™”"
๋Œ€ํ‘œยท์‹ค๋ฌด ๋งค๋‹ˆ์ € weekly-report โ†’ meeting-actions โ†’ sales-summary "๋ณด๊ณ  ์ž๋™ํ™” 3์ข… ์„ธํŠธ โ€” ์ฃผ๊ฐ„/ํšŒ์˜/์›”๊ฐ„"
์žกํƒ•(ํ˜ผํ•ฉ) ์œ„ ๋ฒ”์šฉ ์Šคํฌ๋ฆฝํŠธ ๊ทธ๋Œ€๋กœ ๋ฐ์ดํ„ฐ ์œ„์น˜ + 5๋ถ„ ์‹œ์ž‘ + JSONL ๊ฐ์‚ฌ ๋กœ๊ทธ

์žฅ์•  ๋ฐœ์ƒ ์‹œ 30์ดˆ ๋ณต๊ตฌ (live ๋ฐ๋ชจ ๋„์ค‘)

์ฆ์ƒ ํ•œ ์ค„ ๋ณต๊ตฌ ์•ˆ ๋˜๋ฉด
step-end ... ok:false ์ฒซ LLM ๋‹จ๊ณ„ ์‹คํŒจ "API ํ‚ค ํ•œ๋„ ์ดˆ๊ณผ์˜ˆ์š”" โ†’ weekly-report ๋Œ€์‹  1๋‹จ๊ณ„๋งŒ์ธ shell-only ์‚ฌ๋ก€๋กœ ์šฐํšŒ runs/*.jsonl ๋ฏธ๋ฆฌ ์บก์ฒ˜ํ•ด ๋‘” ์ด์ „ ์„ฑ๊ณต ๊ฒฐ๊ณผ๋ฅผ ํ™”๋ฉด์— ๋„์›€
๋ธŒ๋ผ์šฐ์ €์— ํ•œ๊ตญ์–ด ๊นจ์ง ์ƒˆ๋กœ๊ณ ์นจ (Ctrl/Cmd+R) โ€” Tailwind CDN ์บ์‹œ ๋ฌธ์ œ 90% ๋‹ค๋ฅธ ์›Œํฌํ”Œ๋กœ์šฐ๋กœ ์ฆ‰์‹œ ์ „ํ™˜, ๊นจ์ง์€ ๋ฏธํŒ… ํ›„ ์ฒ˜๋ฆฌ
SSE๊ฐ€ ๋ฉˆ์ถค (3์ดˆ ์ด์ƒ ์ถœ๋ ฅ ์—†์Œ) "์ž ์‹œ LLM ์‘๋‹ต ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค" ํ•œ ๋งˆ๋”” + ์šฐํšŒ๋กœ ๋‹ค๋ฅธ ํƒญ ์—ด์–ด ๋‘ ๋ฒˆ์งธ ์›Œํฌํ”Œ๋กœ์šฐ Run ์ฒซ ํƒญ์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ๋‘ ๋ฒˆ์งธ ํƒญ์—์„œ ์ง„ํ–‰
์„œ๋ฒ„ ์ž์ฒด ์ฃฝ์Œ ํ„ฐ๋ฏธ๋„ pnpm dev ์žฌ์‹คํ–‰(2์ดˆ) "๋กœ์ปฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ๊ผฌ์—ฌ์„œ์š”" ์†”์ง + ์บก์ฒ˜๋ณธ์œผ๋กœ ๋งˆ๋ฌด๋ฆฌ

After demo โ€” 30๋ถ„ ์•ˆ์— ๋ณด๋‚ด๋Š” leave-behind

  1. ์ด README ๋งํฌ (#demo-path-first-run-in-5-minutes๋กœ anchor)
  2. docs/sales/pilot-onepager.md๋ฅผ PDF๋กœ ๋ณ€ํ™˜ํ•ด ์ฒจ๋ถ€ โ€” ํ•œ๊ตญ์–ด ํฐํŠธ ํฌํ•จ: pandoc docs/sales/pilot-onepager.md -o docs/sales/pilot-onepager.pdf --pdf-engine=weasyprint --metadata title="FlowAgent โ€” Pilot 1-pager" (์‚ฌ์ „ ์„ค์น˜: apt-get install -y pandoc weasyprint)
  3. ๋ฏธํŒ… ์ค‘ ์ž‘์„ฑํ•œ ๊ท€์‚ฌ ์ผ€์ด์Šค 1๊ฑด์˜ YAML ์ดˆ์•ˆ (workflows/<customer-slug>-draft.yaml ํ˜•ํƒœ๋กœ ์ฒจ๋ถ€)
  4. ๋‹ค์Œ ๋ฏธํŒ… ํ›„๋ณด ์ผ์ • 3๊ฐœ (1์ฃผ์ฐจ ์„ค์น˜ ๋ฏธํŒ…์šฉ)
  5. ๋‹ค์Œ outreachยท์„ค์น˜ ๋ฏธํŒ… ์ œ์•ˆ ์ด๋ฉ”์ผ โ€” ํ…œํ”Œ๋ฆฟ docs/sales/pilot-outreach-email.md ์‚ฌ์šฉ. {{ํšŒ์‚ฌ๋ช…}}/{{๋‹ด๋‹น์ž๋ช…}}/{{ํ›„๋ณด1ยท2ยท3}}/{{๋ฐœ์‹ ์ž๋ช…}} ์ž๋ฆฌํ‘œ์‹œ์ž๋งŒ ์น˜ํ™˜ํ•˜๊ณ  PDF ์ฒจ๋ถ€ ํ›„ ๋ฐœ์†ก. Follow-upยทWarm introยท์„ค์น˜ ๋ฏธํŒ… 3๊ฐ€์ง€ ๋ณ€ํ˜•์ด ๊ฐ™์€ ํŒŒ์ผ ํ•˜๋‹จ์— ์žˆ์Œ.

Bundled workflows

The workflows/ directory ships eight end-to-end workflows covering the most common Korean SMB office tasks for all three target personas (A ์‚ฌ๋ฌด์ง ยท B 1์ธ ์ž์˜์—… ยท D ์‚ฌ์žฅ). All use Korean fixtures under workflows/fixtures/ and English LLM prompts that emit Korean output (see feedback_demo_fixture_language rule for why).

๊ธฐ๋ณธ 5์ข… (AยทD ํŽ˜๋ฅด์†Œ๋‚˜ ์ค‘์‹ฌ)

Workflow What it does Persona (spec ยง 3) ์—†์• ์ฃผ๋Š” ๋ฐ˜๋ณต ์—…๋ฌด ์ŠคํŠธ๋ ˆ์Šค
weekly-report ํ•œ ์ฃผ ์ง„ํ–‰ ๋…ธํŠธ โ†’ 4-section ๊ตฌ์กฐํ™” โ†’ Slack ๊ณต์œ ์šฉ ๋ฉ”์‹œ์ง€ ์‚ฌ๋ฌด์ง A โ˜…โ˜…โ˜… ยท ์‚ฌ์žฅ D โ˜…โ˜… ๋งค์ฃผ ๊ฐ™์€ ๋ณด๊ณ ์„œ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์“ฐ๋Š” 30๋ถ„
meeting-actions ํšŒ์˜๋ก โ†’ ๋‹ด๋‹น์ž๋ณ„ ์•ก์…˜ ํ‘œ โ†’ Slack ๋ณด๊ณ  ํฌ๋งท ์‚ฌ๋ฌด์ง A โ˜…โ˜…โ˜… ยท ์‚ฌ์žฅ D โ˜…โ˜… ํšŒ์˜ ๋๋‚˜๊ณ  ํšŒ์˜๋ก ๋‹ค์‹œ ์ฝ์œผ๋ฉฐ ์•ก์…˜์„ ์ถ”๋ฆฌ๋Š” ์ธ์ง€ ๋ถ€ํ•˜
sales-summary ์›”๊ฐ„ ๋งค์ถœ CSV โ†’ ์ฑ„๋„ยท์ด์ƒ์น˜ ๋ถ„์„ โ†’ ๊ฒฝ์˜์ง„ 3-๋ฌธ์žฅ ์š”์•ฝ ์‚ฌ์žฅ D โ˜…โ˜…โ˜… ยท ์‚ฌ๋ฌด์ง A โ˜…โ˜… ยท ์ž์˜์—… B โ˜…โ˜… ์›”๋ง๋งˆ๋‹ค ์ด์ƒ์น˜ ์ฐพ๊ณ  1-pager ๋งŒ๋“œ๋Š” ์••๋ฐ•
inquiry-triage ๊ณ ๊ฐ ๋ฌธ์˜ CSV โ†’ ์นดํ…Œ๊ณ ๋ฆฌยท๊ธด๊ธ‰๋„ ๋ถ„๋ฅ˜ + ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋‹ต๋ณ€ ์ดˆ์•ˆ ์ž์˜์—… B โ˜…โ˜…โ˜… ยท ์‚ฌ๋ฌด์ง A โ˜…โ˜… ๋งค์ผ ๊ฐ™์€ ํ†ค์œผ๋กœ ๋‹ต๋ณ€ ์“ฐ๊ณ  ์šฐ์„ ์ˆœ์œ„ ๋งค๊ธฐ๋Š” ํ”ผ๋กœ
approval-triage ๊ฒฐ์žฌ ๋Œ€๊ธฐํ•จ โ†’ ์ž๋™์Šน์ธยท๊ฒ€ํ† ยท์ •๋ณด๋ถ€์กฑ ๋ถ„๋ฅ˜ + ์˜ค๋Š˜์˜ brief ์‚ฌ๋ฌด์ง A โ˜…โ˜…โ˜… ยท ์‚ฌ์žฅ D โ˜…โ˜… ๊ฒฐ์žฌํ•จ์— ์ค„์„  ์š”์ฒญ์„ ํ•˜๋‚˜์”ฉ ์ฝ๊ณ  ํŒ๋‹จํ•˜๋Š” ์ธ์ง€ ๋ถ€ํ•˜

B ํŽ˜๋ฅด์†Œ๋‚˜ ์‹ ๊ทœ 3์ข… โ€” ์ถœ์‹œ ์™„๋ฃŒ (3/3)

Workflow What it does Persona (spec ยง 3) ์—†์• ์ฃผ๋Š” ๋ฐ˜๋ณต ์—…๋ฌด ์ŠคํŠธ๋ ˆ์Šค
quote-email ํ”„๋กœ์ ํŠธ brief + ๋ณธ์ธ ๋‹จ๊ฐ€ ๊ฐ€์ด๋“œ โ†’ ๊ฒฌ์  ํ•ญ๋ชฉยท๊ธˆ์•ก ์‚ฐ์ • โ†’ ๊ณ ๊ฐ ํšŒ์‹  ๋ฉ”์ผ ์ดˆ์•ˆ ์ž์˜์—… B โ˜…โ˜…โ˜… ๋งค๋ฒˆ ๋น„์Šทํ•œ ๊ฒฌ์  ๋ฉ”์ผ ๋‹ค์‹œ ์“ฐ๋ฉฐ ๋‹จ๊ฐ€ยท์ผ์ •ยท์„ธ๊ธˆ ์กฐ๊ฑด ๋น ๋œจ๋ฆฌ๋Š” ๋ถˆ์•ˆ
sales-followup ๊ณ ๊ฐ ๋ฏธํŒ…ยทํ†ตํ™” raw ๋…ธํŠธ โ†’ ๋‹ค์Œ ์•ก์…˜ยท์•ฝ์†ยท์ถ”๊ฐ€ ๊ฒฌ์  ๋ถ„๋ฆฌ + follow-up ๋ฉ”์ผ + ์ผ์ • ์ œ์•ˆ ์ž์˜์—… B โ˜…โ˜…โ˜… ๋ฏธํŒ… ๋๋‚˜๊ณ  ๋จธ๋ฆฟ์† ํฉ์–ด์ง„ ์•ก์…˜ยท์•ฝ์†ยท๋‹ค์Œ ์ผ์ •์„ ๋ฉ”๋ชจ๋กœ ๋ชป ์˜ฎ๊ธฐ๋Š” ๋ถ€๋‹ด
sns-replies ์ธ์Šคํƒ€ยท๋ธ”๋กœ๊ทธ ํ•œ ์ฃผ๊ฐ„ ๋Œ“๊ธ€ยทDM raw ๋ชฉ๋ก โ†’ ์ŠคํŒธ ๊ฑฐ๋ฆ„ + ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋‹ต๊ธ€ ์ดˆ์•ˆ + ํ˜‘์—…ยท๊ฒฌ์  lead ๋ณ„๋„ ์ถ”์  ์ž์˜์—… B โ˜…โ˜…โ˜… ๋งค์ผ ๋“ค์–ด์˜ค๋Š” ์ธ์Šคํƒ€ DMยท๋ธ”๋กœ๊ทธ ๋Œ“๊ธ€์— ์ผ์ผ์ด ๋‹ต๊ธ€ ํ†ค ๋งž์ถ”๊ณ  ์ŠคํŒธ ๊ฑฐ๋ฅด๊ณ  ์ง„์งœ lead ๋†“์น˜์ง€ ์•Š๋Š” ํ”ผ๋กœ

To adapt one for a real Pilot case, edit the file in workflows/fixtures/ to the customer's own data โ€” the YAML prompts stay the same. The customer's data never leaves their machine.

Pilot ๋ฏธํŒ… ์ž๋ฆฌ customize ์‹œ๋“œ (_pilot-draft-template.yaml) โ€” 3๋ถ„ ๊ฐ€์ด๋“œ

๊ท€์‚ฌ ์‚ฌ๋ก€ 1๊ฑด์„ ๋ฏธํŒ… ์ž๋ฆฌ์—์„œ ๊ฐ™์ด ์›Œํฌํ”Œ๋กœ์šฐ๋กœ ๋งŒ๋“œ๋Š” ์‹œ๋“œ. ๋น„๊ฐœ๋ฐœ์ž๋„ ์šด์˜์ž์™€ ํ•จ๊ป˜ 3๋‹จ๊ณ„๋กœ ๋”ฐ๋ผ์˜ต๋‹ˆ๋‹ค. ๋ณธ์ธ์ด ์ฑ„์šฐ๋Š” ์นธ์€ 5๊ฐœ(ํ•œ๊ตญ์–ด), ์˜๋ฌธ LLM ํ”„๋กฌํ”„ํŠธ 4๊ฐœ๋Š” ์šด์˜์ž๊ฐ€ ๊ฐ™์ด ์ฑ„์›Œ์ค๋‹ˆ๋‹ค.

1๋‹จ๊ณ„ โ€” ๋ณต์‚ฌ (PowerShellยทํ„ฐ๋ฏธ๋„ ํ•œ ์ค„, <ํšŒ์‚ฌ> ์ž๋ฆฌ์— ๋ณธ์ธ ํšŒ์‚ฌ ์˜๋ฌธ ์•ฝ์–ด)

cp workflows/_pilot-draft-template.yaml workflows/acme-draft.yaml

2๋‹จ๊ณ„ โ€” fixture 1๊ฑด ๋‘๊ธฐ

๋ณธ์ธ ๋ฐ์ดํ„ฐ ํŒŒ์ผ(ํšŒ์˜๋ก .md / ๋งค์ถœ .csv / ๋ฌธ์˜ .csv / ๊ฒฐ์žฌ .md ์ค‘ ํ•˜๋‚˜)์„ ์•„๋ž˜ ์œ„์น˜์— ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์ €์žฅ:

workflows/fixtures/acme-sample.md

3๋‹จ๊ณ„ โ€” ์ž๋ฆฌํ‘œ์‹œ์ž ์ฑ„์šฐ๊ธฐ (์•„๋ž˜ ํ‘œ ์ฐธ์กฐ)

์ฑ„์šฐ๋Š” ์‚ฌ๋žŒ placeholder ์˜ˆ์‹œ ์–ด๋””์— ์“ฐ์ž„
๋ณธ์ธ {{customer-slug}} acme renameยทfixture ํŒŒ์ผ๋ช…๊ณผ ์ผ์น˜ (์˜๋ฌธ ์†Œ๋ฌธ์ž)
๋ณธ์ธ {{ํ™•์žฅ์ž}} md / csv ์œ„ fixture ํ™•์žฅ์ž
๋ณธ์ธ {{๋‹ด๋‹น์ž_ํŽ˜๋ฅด์†Œ๋‚˜}} ์šด์˜ / ์‚ฌ๋ฌด๊ด€๋ฆฌ ์นด๋“œ ํŽ˜๋ฅด์†Œ๋‚˜ ํ•„ํ„ฐ
๋ณธ์ธ {{๊ท€์‚ฌ๊ฐ€_๊ฒช๋Š”_๋ฐ˜๋ณต_์—…๋ฌด_ํ•œ_์ค„}} ๋งค์ฃผ ๋™์ผํ•œ ์–‘์‹ ๋ณด๊ณ ์„œ ๋‹ค์‹œ ์“ฐ๊ธฐ ์นด๋“œ stressRelieved
๋ณธ์ธ {{ํšŒ์‚ฌ๋ช…}} Acme ๊ฒฐ๊ณผ wrap ํ—ค๋”
๋ณธ์ธ {{์›Œํฌํ”Œ๋กœ์šฐ_์ œ๋ชฉ}} ์ฃผ๊ฐ„ ์•ก์…˜ ์ •๋ฆฌ ๊ฒฐ๊ณผ wrap ํ—ค๋”
์šด์˜์ž {{์ž…๋ ฅ_์ข…๋ฅ˜_์˜๋ฌธ}} a Korean weekly meeting note 2๋‹จ๊ณ„ LLM prompt
์šด์˜์ž {{์ถ”์ถœ_๋ชฉํ‘œ_์˜๋ฌธ}} every action item with owner and deadline 2๋‹จ๊ณ„ LLM prompt
์šด์˜์ž {{์ถœ๋ ฅ_ํ˜•์‹_์˜๋ฌธ}} Korean Markdown table 2๋‹จ๊ณ„ LLM prompt
์šด์˜์ž {{์ „๋‹ฌ_์ฑ„๋„_์˜๋ฌธ}} Slack-ready Korean message 4๋‹จ๊ณ„ LLM prompt

์™„๋ฃŒ ํ›„ โ€” ๋ธŒ๋ผ์šฐ์ € listing(/) ์ƒˆ๋กœ๊ณ ์นจ โ†’ ์ƒˆ ์นด๋“œ ์ž๋™ ๋“ฑ์žฅ โ†’ Run.

_ prefix ํŒŒ์ผ์€ listing/route์—์„œ ์ž๋™ ์ œ์™ธ (src/workflows-dir.ts). ์‹œ๋“œ ์ž์ฒด๋Š” listing์— ์•ˆ ๋ณด์ด๊ณ  /workflows/_pilot-draft-templateยท/run ๋ชจ๋‘ 404. ๋ฐ๋ชจ ์ค‘ ๋ฏธ์™„์„ฑ placeholder๊ฐ€ ๊ณ ๊ฐ์—๊ฒŒ ๋…ธ์ถœ๋  ์œ„ํ—˜ ์—†์Œ. ๋ณ„๋„ ๋น„๊ณต๊ฐœ ์‹œ๋“œ๋ฅผ ๋” ๋‘๋ ค๋ฉด ๋™์ผํ•˜๊ฒŒ _ prefix๋กœ ์‹œ์ž‘ํ•˜๋Š” ํŒŒ์ผ๋ช…์„ ์‚ฌ์šฉ.

Writing a workflow

Drop a <name>.yaml file in workflows/. The filename (without extension) becomes the URL slug; the name: field is the human-readable label shown in the UI. See workflows/weekly-report.yaml for a working 3-step demo.

name: my-workflow
description: One-line summary shown on the list page.
steps:
  - type: llm
    name: draft               # optional, used in event logs
    prompt: |
      Write a haiku about workflows.
  - type: shell
    name: wrap
    command: |
      node -e "process.stdout.write('=== Output ===\n' + {{prev}} + '\n')"
  - type: llm
    prompt: |
      Translate to Korean:
      {{prev}}

{{prev}} substitution rules

{{prev}} is replaced with the previous Step's output. Different rules per step type:

  • llm step โ€” {{prev}} is spliced into the prompt string verbatim. No escaping needed.

  • shell step โ€” {{prev}} is replaced with the JS expression process.env.FLOWAGENT_PREV, and the previous output is passed via the child process's environment. The shell command must be a node -e "..." one-liner โ€” this makes commands cross-platform (PowerShell, cmd, Git Bash, sh, bash all execute identically) and neutralizes backticks, $(), $VAR, and semicolon chains inside untrusted LLM output because Node reads the value at runtime instead of the shell tokenizing it.

    # โœ… Recommended โ€” Node one-liner reads prev as a JS expression
    command: |
      node -e "process.stdout.write({{prev}})"
    
    # โœ… Wrap with a banner
    command: |
      node -e "process.stdout.write('=== Header ===\n' + {{prev}} + '\n=== End ===\n')"
    
    # โœ… Load a fixture file (replaces `cat <path>` from sh-only workflows)
    command: |
      node -e "process.stdout.write(require('fs').readFileSync('workflows/fixtures/data.csv','utf8'))"
    
    # โŒ Avoid โ€” sh-specific, fails on Windows PowerShell/cmd
    command: printf '%s' "{{prev}}"
    command: cat workflows/fixtures/data.csv

    Place {{prev}} unquoted as a bare token inside the Node expression โ€” it expands to a JS variable, not a string literal.

Project layout

src/
  spec.ts              # Zod schema + loadWorkflow(filePath) โ€” YAML โ†’ typed Workflow
  runner.ts            # runWorkflow() โ€” sequential execution + SSE-style event callback
  runners.ts           # createDefaultRunners() โ€” wires llm + shell step runners
  workflows-dir.ts     # listWorkflows(dir) โ€” file scanner
  server.ts            # Hono app factory (env-driven)
  main.ts              # HTTP entry โ€” @hono/node-server bind
  routes/
    workflows.ts       # GET /, GET /workflows/:name, POST /workflows/:name/run (SSE)
  steps/
    llm.ts             # Anthropic SDK call
    shell.ts           # child_process.exec with FLOWAGENT_PREV env-var injection
  views/
    layout.tsx         # Tailwind CDN shell
    index.tsx          # workflow list page
    run.tsx            # workflow detail page + SSE client
    error.tsx          # 404 / 500 page
workflows/             # *.yaml โ€” your workflows live here
runs/                  # <runId>.jsonl โ€” one line per SSE event, written live
docs/adr/              # architecture decisions
.claude/               # project skills, agents, commands (Claude Code config)

Run logs

Every workflow run streams its events live to runs/<runId>.jsonl as well as over SSE. One JSON object per line, in event order: step-start, step-output, step-end (ร— number of steps), then done. The file basename equals the runId reported in the done event.

# Replay the most recent run
tail -n +1 "$(ls -t runs/*.jsonl | head -1)" | jq .

# Show just the outputs for a given run
jq -r 'select(.kind=="step-output") | .output' runs/<runId>.jsonl

Disk writes happen before SSE writes, so the log stays complete even if the client disconnects mid-run.

Pilot use โ€” turning run logs into a monthly automation report

Pilot customers often want proof that automation actually saved time. The JSONL format makes this a one-liner:

# How many runs this month, and which workflows?
ls runs/2026-05-*.jsonl | wc -l
jq -r '.step.name // empty' runs/*.jsonl | sort | uniq -c | sort -rn

# Pull every Slack-ready output from this month for archival
jq -r 'select(.kind=="step-output" and .index==3) | .output' runs/2026-05-*.jsonl

Pair this with a calendar reminder ("๋งค์›” 1์ผ ์ž๋™ํ™” ํšจ๊ณผ ๋ฆฌํฌํŠธ") and the customer has a recurring business-value artifact without touching the runner.

Development

pnpm test         # vitest, one shot
pnpm test:watch   # vitest watch
pnpm typecheck    # tsc --noEmit
pnpm dev          # tsx watch with .env autoload
pnpm start        # production-ish single shot

Test layout mirrors source (*.test.ts next to the file). All step runners and routes have unit coverage; the SSE route test exercises the full event sequence with fake runners.

Operating philosophy

See CLAUDE.md for the full agent-facing config. The short version:

  1. Align before you code โ€” /grill for non-trivial requests.
  2. Spec โ†’ Build โ†’ Review โ€” one skill per lifecycle phase, see .claude/skills/.
  3. Maintainability first โ€” code should be readable by a developer who lands on this repo cold. Prefer editing existing files; surface assumptions; sanitize at every trust boundary.

Limits (intentional, MVP scope)

  • No DAG, no branching, no parallel steps. Linear only.
  • No retry, no resume, no checkpointing.
  • No auth โ€” bind to localhost only.
  • Run logs are not rotated or pruned โ€” clean runs/ manually if it grows.