์ค์ผ์ค๋ฌ ์์ด์ ํธ ๊ด๋ฆฌ ๊ฐ์ด๋
ํ๋ก์ ํธ(CSN)๋ณ๋ก ๋ฑ๋ก๋ ์๋ํ ์คํ๊ธฐ(gissue ์ค์ผ์ค๋ฌ ๋ฑ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ด์ ํธ)์ ์จ๋ผ์ธ/์คํ๋ผ์ธ ์ํ, ์คํ ์ํยท์ด๋ ฅ, ์ค์๊ฐ ๋ก๊ทธ๋ฅผ ํ ํ๋ฉด์์ ๊ด๋ฆฌํฉ๋๋ค.
๐ ์ค์ผ์ค๋ฌ ์์ด์ ํธ ๊ด๋ฆฌ ํ์ด์ง๋ก ์ด๋ โ
๐ค AI ์๊ฒ ๋งก๊ฒจ gissue ์ค์ผ์ค๋ฌ ๋ง๋ค๊ธฐ
์ด ๋ฌธ์๋ฅผ AI ์๊ฒ ์ฃผ๋ฉด, AI ๊ฐ giip-fde-agent ์ ์ฅ์(https://github.com/LowyShin/giip-fde-agent.git)๋ฅผ cloneํ๊ฑฐ๋ ์ต์ ํํ ๋ค gissue ์ฒ๋ฆฌ์ฉ ์ค์ผ์ค๋ฌ๋ฅผ ์ค์นยท๋ฑ๋กยท๊ฒ์ฆ๊น์ง ์๋์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ์ฒ์๋ถํฐ ์คํฌ๋ฆฝํธ๋ฅผ ์๋ก ์ง์ง ๋ง๊ณ ์ด ์ ์ฐจ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
ํ๋กฌํํธ(๋ณต์ฌํด์ ๊ทธ๋๋ก ์ฌ์ฉ):
์ด ๋ฌธ์(/help/catquest-schedulers.ko.md)๋ฅผ ์ฝ๊ณ , ์๋ '์ค์น ์ ์ฐจ'๋๋ก gissue ์ค์ผ์ค๋ฌ๋ฅผ ์ด PC ์ ์ค์นํด์ค.
giip-fde-agent ๊ฐ ์์ผ๋ฉด clone, ์์ผ๋ฉด git pull --ff-only ๋ก ์ต์ ํ. ๋ก์ปฌ ๋ณ๊ฒฝ์ด ์์ผ๋ฉด ๋ฎ์ด์ฐ์ง ๋ง๊ณ ์ค๋จํ๊ณ ๋ณด๊ณ ํด.
๋์ CSN ์ <CSN>, ์์
ํด๋๋ <๊ฒฝ๋ก> ๋ก ์ง์ ํด.
SK ๋ giipAgent.cnf(๋๋ giipAgent.cfg)์์ sk= ๊ฐ์ ์ฝ๊ณ ๋์๊ฒ ๋ฌป์ง ๋ง.
๊ฐ ๋จ๊ณ ํ์ธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ํด.
์ค์น ์ ์ฐจ
- ์ฌ์ ์ ๊ฒ โ ์คํ โ
git --version,node --version,claude --version, Windows ๋powershell -Command $PSVersionTable.PSVersion, Linux ๋pwsh --version. ๋ชจ๋ PATH ์ ์์ด์ผ ๋ค์ ๋จ๊ณ๋ก. - giip-fde-agent ํ๋ณด โ ์คํ โ ์์ผ๋ฉด
git clone https://github.com/LowyShin/giip-fde-agent.git, ์์ผ๋ฉดgit pull --ff-only. ๋ก์ปฌ ๋ณ๊ฒฝ์ด ์์ผ๋ฉด ์ค๋จํ๊ณ ๋ณด๊ณ . - ์ ๋ณธ ์คํ ์ฝ๊ธฐ โ
docs/60-operations/hourly-issue-scheduler.mdยง4~ยง5 ๋ฅผ ์ฝ๊ณ CSNโworkdir ๋งคํ, heartbeat ๋ธ๋ก, SK ์์น๋ฅผ ํ์ธ. - csn-projects.json ์์ฑ โ
scripts/gissue/csn-projects.json.example์csn-projects.json์ผ๋ก ๋ณต์ฌ. ๋์ CSN ์workdir/enabled: true์ฑ์ฐ๊ณ , ์ต์์heartbeat๋ธ๋ก์lssn(์๋ฒ๋ฒํธ)/hostname(์ด PC ์๋ณ์)/skFile(sk= ํ์ ํ์ผ ๊ฒฝ๋ก) ํ์๋ก ์ง์ . ์์ผ๋ฉด ์ด ํ๋ฉด์ ํ์ด ๋ํ๋์ง ์์. - ์ํฌ๋ฆฟ ์ค๋น โ ์์ ํด๋
giipAgent.cnf(๋๋giipAgent.cfg)์์sk=๊ฐ์ ์ฝ์. ์ฌ์ฉ์์๊ฒ ๋๋ฌป์ง ์๊ณ , ์ถ๋ ฅ์๋ ๊ธฐ๋กํ์ง ์์.slack-bot/.secrets/giip-accounts.json(.sample.json ๋ณต์ฌ)๋ ์ค๋น. - ๋๋ผ์ด๋ฐ โ
scripts/gissue/manage-gissue-scheduler.ps1 -Action DryRun -OnlyCsn <CSN>์คํ โ[PREFLIGHT-FAIL]๋ก๊ทธ ์์ด ๋๋๋ฉด ์ฑ๊ณต. - ๋ฑ๋ก
- Windows โ
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\register-hourly-issue-scheduler.ps1 -Action Register -RepoRoot <giip-fde-agent ๋ฃจํธ> - Linux โ ์ ์ฉ ๋ฑ๋ก ์คํฌ๋ฆฝํธ๋ ์๊ณ ,
/etc/cron.d/gissue-scheduler๊ฐ์ cron ํ ์ค๋ก ๋ฑ๋กํฉ๋๋ค(์ค์ docker ๋ฐฐํฌ์ ๊ฐ์ ํ์):7,27,47 * * * * <์ผ๋ฐ ์ฌ์ฉ์> cd <๋ฃจํธ> && pwsh -NoProfile -NonInteractive -File "<๋ฃจํธ>/scripts/gissue/run-gissue-claude.ps1" -OnlyCsn <CSN> >> <๋ฃจํธ>/scripts/gissue/logs/cron.log 2>&1. ๋ฐ๋์ root ๊ฐ ์๋ ์ผ๋ฐ ์ฌ์ฉ์๋ก ๋ฑ๋กํฉ๋๋ค(claude ๊ฐ root ์์--dangerously-skip-permissions๋ฅผ ๊ฑฐ๋ถํด ์ด์๊ฐ ๋ชจ๋ ์คํจํจ). ๊ทธ ์ฌ์ฉ์์ claude ๋ก๊ทธ์ธ ์ ๋ณด๋ ํ์ํฉ๋๋ค. - Docker ์ธ์คํด์ค โ ์ปจํ
์ด๋ ๊ธฐ๋ ์
docker/entrypoint.sh๊ฐ ์ cron ์ ์๋ ๋ฑ๋กํฉ๋๋ค(GIIP_ENABLE_SCHEDULER๊ธฐ๋ณธ true,-OnlyCsn์csn-projects.json์์ ํ์). ์ด ๊ฒฝ์ฐ 7๋จ๊ณ๋ ์ด๋ฏธ ๋๋ ์์ผ๋ฏ๋ก/etc/cron.d/gissue-scheduler์กด์ฌ๋ง ํ์ธํ๊ณscripts/bootstrap-instance.sh๋ก ํ๊ฒฝ(pwsh ๋งํฌ ๋ฑ)์ ์ ๊ฒํฉ๋๋ค.
- Windows โ
- ๊ฒ์ฆ โ
manage-gissue-scheduler.ps1 -Action RunOnce -OnlyCsn <CSN>๋ก ํ ๋ฒ ์คํํ๊ฑฐ๋ ๋ค์ :07 ์ ๊ธฐ๋ค๋ฆฐ ๋ค ์ด ํ๋ฉด์ ์๋ก๊ณ ์นจ โgissue_csn<CSN>ํ์ด online ์ด๊ณ History ์ ์คํ์ด ๋จ์ ์์ผ๋ฉด ์ฑ๊ณต. ์ ๋ณด์ด๋ฉดscripts/gissue/logs/gissue_csn<CSN>.log์[WARN][SchedulerState-...]์ค์ ํ์ธ.
AI ๊ฐ ํ์ง ๋ง์์ผ ํ ๊ฒ
- giip-fde-agent ์ ๋ฌ๋(
run-gissue-claude.ps1)๋ฅผ ์๋ก ์์ฑํ์ง ์๋๋ค - SP ๋ฅผ ์ง์ ํธ์ถํ๋ ์ฝ๋๋ฅผ ๋ฐ๋ก ์ง์ง ์๋๋ค(์ค์น๋ ๋ฌ๋๊ฐ ์ฒ๋ฆฌํ๋ค)
- SK ๊ฐ์ ๋ฌธ์๋ ๋ก๊ทธ์ ๋จ๊ธฐ์ง ์๋๋ค
- giip-fde-agent ์ฝ๋ ์์ฒด๋ฅผ ์์ ํ์ง ์๋๋ค
๐ ๊ฐ์
์ค์ผ์ค๋ฌ ์์ด์ ํธ ๊ด๋ฆฌ๋ ํ์ฌ ์ ํ๋ ํ๋ก์ ํธ(CSN)์ ๋ฑ๋ก๋ ๋ชจ๋ ์๋ํ ์์ด์ ํธ โ ์๋ฅผ ๋ค์ด gissue์ ๋งค์๊ฐ ์ค์ผ์ค๋ฌ, ๋ํํ Claude Code ์ธ์
๋ฑ์ ๋ณด์ฌ์ค๋๋ค. giip ์ด์๋ฅผ ๊ณ ์์ด๋ก ์๊ฐํํ๋ /admin/catquest์ ๋ฌ๋ฆฌ, ์ด ํ๋ฉด์ ์๋ํ ์์
์ ์คํํ๋ ์์ด์ ํธ ์์ฒด๋ฅผ ๊ด๋ฆฌํ๋ ์ด์ ๋์๋ณด๋์
๋๋ค: ๊ฐ ์์ด์ ํธ๊ฐ ์ด์์๋์ง, ํ์ฌ ์คํ์ด ์ ์์ธ์ง, ๋ก๊ทธ๋ ์ด๋์ ๋ณผ ์ ์๋์ง๋ฅผ ํ์ธํฉ๋๋ค.
๐จ ์ํ ์์
์์ด์ ํธ๋ง๋ค ์๋ก ๋ ๋ฆฝ์ ์ธ ๋ ๊ฐ์ง ์ํ ์ ํธ๊ฐ ํ์๋ฉ๋๋ค โ ํผ๋ํ์ง ๋ง์ธ์.
Identity ์ํ (์์ด์ ํธ ์ด๋ฆ ์ ์์ ์ )
๊ฐ๋ณ ์คํ(run)๊ณผ ๋ฌด๊ดํ๊ฒ, ์์ด์ ํธ ํ๋ก์ธ์ค ์์ฒด์ ์ ๊ทผ ๊ฐ๋ฅํ์ง๋ฅผ ๋ํ๋
๋๋ค(tSchedulerAgent.status).
| ์์ | ์ํ | ์๋ฏธ |
|---|---|---|
| ๐ข ์ด๋ก | online | ์์ด์ ํธ์ ์ ๊ทผ ๊ฐ๋ฅํ๋ฉฐ ์ ์ ๋ณด๊ณ ์ค |
| ๐ด ๋นจ๊ฐ | error | ์์ด์ ํธ๊ฐ ์ค๋ฅ ์ํ๋ฅผ ๋ณด๊ณ ํจ |
| โช ํ์(slate-400) | offline | ํ์ฌ ์์ด์ ํธ์ ์ ๊ทผํ ์ ์์ |
| โช ์ฐํ ํ์(slate-300) | unknown | ์์ง ์ํ๊ฐ ๋ณด๊ณ ๋์ง ์์ |
์คํ ์ํ (Status ์ปฌ๋ผ์ ๋ฐฐ์ง)
๊ฐ์ฅ ์ต๊ทผ ์ค์ผ์ค๋ฌ *์คํ(run)*์ ์ํ(currentStatus)์ stale(์ ์ฒด) ํ์ง ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ํฉ๋๋ค.
| ์์ | ํ์ ๋ผ๋ฒจ | ์กฐ๊ฑด | ์๋ฏธ |
|---|---|---|---|
| ๐ข ์ด๋ก | RUNNING | currentStatus = RUNNING์ด๊ณ stale ์๋ | ์ ์์ ์ผ๋ก ์คํ ์ค |
| ๐ด ๋นจ๊ฐ | STALE | currentStatus = RUNNING ์ด๋ฉด์ isStale = true | ์คํ ์ค์ผ๋ก ํ์๋ผ ์์ง๋ง heartbeat๊ฐ ๋๋ฌด ์ค๋ ๋๊น โ ๋ฉ์ถฐ๋ฒ๋ฆฐ/์ข๋น ์คํ์ผ๋ก ๋ณด์ |
| ๐ ์ฃผํฉ | STALE | currentStatus = STALE(๋ช
์์ ๊ฐ) | ๋ฐฑ์๋๊ฐ ์คํ ์์ฒด๋ฅผ stale๋ก ํ์ ํจ |
| โช ํ์ | ENDED | currentStatus = ENDED | ์ข ๋ฃ๋จ(์ ์ ์๋ฃ ๋๋ ์ ์์ ์ธ ์ค์ง) |
| โช ํ์ | (์๋ณธ ๊ฐ) | ๊ทธ ์ธ / ์คํ ์ด๋ ฅ ์์ | ์ ์ ์์ / ๋ฐ์ดํฐ ์์ |
์๋ ์คํ์ด๋ ฅ ๋ชจ๋ฌ์์๋ ์๋ฃ๋ ์คํ์ด ๋นจ๊ฐ์ FAILED๋ก๋ ํ์๋ ์ ์์ต๋๋ค โ ENDED(์ ์ ์ข ๋ฃ)๋ stale/ํ์์์๊ณผ๋ ๊ตฌ๋ถ๋๋, ์ค๋ฅ๋ก ์ข ๋ฃ๋ ์คํ์ ๋๋ค.
๐ ํ๋ฉด ๊ตฌ์ฑ
1. ์๋จ ํค๋
/admin/catquest๋ก ๋์๊ฐ๋ ๋ค๋ก๊ฐ๊ธฐ ํ์ดํ(โ).- Refresh: ํ์ฌ CSN์ ์์ด์ ํธ ๋ชฉ๋ก์ ๋ค์ ๋ถ๋ฌ์ต๋๋ค.
2. Open Interactive Sessions
ํ์ฑ ์ํ์ธ claude_interactive_session ์์ด์ ํธ โ ์ฆ ํ์ฌ ํธ์คํธ์์ ์คํ ์ค์ผ๋ก ๋ฑ๋ก๋ ๋ํํ Claude Code ์ธ์
โ ์ด ํ๋ ์ด์ ์์ ๋๋ง ๋ณ๋ ์นด๋๋ก ํ์๋ฉ๋๋ค. ๊ฐ ํ์ ์ธ์
์ด๋ฆ, ํธ์คํธ, ๋ง์ง๋ง ํต์ ์๊ฐ, ๊ทธ๋ฆฌ๊ณ ์์ด์ ํธ์ capabilities์ ์ธ์
URL์ด ๋ฑ๋ก๋ผ ์์ ๋ ํ์๋๋ "Open session" ๋งํฌ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
3. ์์ด์ ํธ ๋ชฉ๋ก (ํ)
์ค์ผ์ค๋ฌ ์์ด์ ํธ๋น ํ ํ์ฉ ํ์๋๋ฉฐ, ๋ค์ ์ ๋ณด๋ฅผ ๋ด์ต๋๋ค.
- Name โ identity ์ํ ์ , ์์ด์ ํธ ์ด๋ฆ, OS/์์ด์ ํธ ์ ํ/๋ฒ์ ๋ฐฐ์ง,
lssn(์ฐ๊ฒฐ๋ ์๋ฒ), ์๋ฆฐ capabilities ์์ฝ, ๋ง์ง๋ง ์ค๋ฅ(์๋ ๊ฒฝ์ฐ). - Host โ
hostIdentifier. - Windows Task โ ํด๋น๋๋ ๊ฒฝ์ฐ, ์ด ์์ด์ ํธ๋ฅผ ์คํํ๋ Windows ์์ ์ค์ผ์ค๋ฌ ์์ ์ด๋ฆ.
- Project โ ํ๋ก์ ํธ ์ด๋ฆ.
- Active โ ON/OFF ๋ฐฐ์ง(
isActive). - Last Comm โ ๋ง์ง๋ง heartbeat/ํต์ ์๊ฐ.
- Status โ ์์์ ์ค๋ช ํ ์คํ ์ํ ๋ฐฐ์ง์, ๋ณด๊ณ ๋ ๊ฒฝ์ฐ ํ์ฌ ๋จ๊ณ(phase) ํ ์คํธ.
ํ๋จ ํต๊ณ ํธํฐ๋ ๋ชฉ๋ก์ ํ์๋ ๋ชจ๋ ์์ด์ ํธ์ ์ฒ๋ฆฌ(Processed) / ์คํต(Skipped) / ์คํจ(Failed) ๊ฑด์ ํฉ๊ณ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
4. ์คํ์ด๋ ฅ (Run History)
ํ ์๋ "View History" ์นด๋์ ๋ชจ๋ ์์ด์ ํธ๊ฐ ๋ค์ ๋์ด๋๋ฉฐ, ํ์ History ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํด๋น ์์ด์ ํธ์ ์ต๊ทผ ์คํ ๋ชฉ๋ก์ ๋ชจ๋ฌ๋ก ๋ณด์ฌ์ค๋๋ค โ ์คํ ๋ชจ๋, ์ํ(FAILED ํฌํจ), ์์/์ข ๋ฃ ์๊ฐ, ์์ ์๊ฐ, ์ฒ๋ฆฌ/์คํต/์คํจ ๊ฑด์, ๋จ๊ณ, ์์ฝ.
5. ์ค์๊ฐ ๋ก๊ทธ ๋ทฐ์ด (Live Log Viewer)
๋ ์์ญ์ผ๋ก ๊ตฌ์ฑ๋ ์ค์๊ฐ tailing ํ๋ฉด์ ๋๋ค.
- ์ข์ธก(์์ด์ ํธ โ ์คํธ๋ฆผ ํธ๋ฆฌ): ์์ด์ ํธ๋ณ๋ก ๊ทธ๋ฃนํ๋๋ฉฐ, ๊ฐ ์์ด์ ํธ๋ฅผ ํผ์น๋ฉด ์๋ ค์ง ๋ก๊ทธ ์คํธ๋ฆผ ๋ชฉ๋ก์ด ๋์ต๋๋ค(์คํธ๋ฆผ์
streamKey๋ก ์๋ณ๋๋ฉฐstreamType๊ณผ ๋กํ ์ด์ ์ธ๋ ๋ฒํธ๋ฅผ ๊ฐ์ง๋๋ค). ์์ด์ ํธ๋ ๋ง์ง๋ง ํต์ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก online/offline์ด ํ์๋ฉ๋๋ค. - ์ฐ์ธก(๋ก๊ทธ ์คํธ๋ฆผ ์นด๋): ์คํธ๋ฆผ์ ์ ํํ๋ฉด ์ต๊ทผ ๋ก๊ทธ ๋ผ์ธ์ด ํ์๋๊ณ , ์ค์๊ฐ tailing์ ์ํด ๊ณ์ ๊ฐฑ์ ๋ฉ๋๋ค.
โ ๋ค๋ฅธ ํธ์คํธ ์ถ๊ฐํ๊ธฐ
์ด ํ๋ฉด์๋ ํธ์คํธ๋ฅผ ์๋์ผ๋ก "์ถ๊ฐ"ํ๋ ๋ฒํผ์ด๋ ์
๋ ฅ ํผ์ด ์์ต๋๋ค โ ๋ชฉ๋ก์ ์ ์ ์ผ๋ก ์๋ ๋ ๊ฐ์ง ์๋ ๋ฑ๋ก ๊ฒฝ๋ก์ ๊ฒฐ๊ณผ์
๋๋ค. ๋ ๊ฒฝ๋ก ๋ชจ๋ **CSN(ํ๋ก์ ํธ)๋ณ๋ก ๋ฐ๊ธ๋ Secret Key(SK)**๋ก giipApiSk4 ์๋ํฌ์ธํธ๋ฅผ ํธ์ถํด tSchedulerAgent/tSchedulerAgentRun์ ์์ ์ ๋ฑ๋ก(upsert)ํ๋ ๋ฐฉ์์ด๋ฉฐ, ์ ํจํ SK ์์ด๋ ํธ์ถ ์์ฒด๊ฐ 401 Unauthorized๋ก ์คํจํ๋ฏ๋ก ์๋ ์ ์ฐจ๋ฅผ ์์๋ ์์๋ก ๋จ์ ํ๋ก์ ํธ์ ๊ฐ์ง ์์ด์ ํธ๋ฅผ ๋ฑ๋กํ ์๋ ์์ต๋๋ค.
โ ๏ธ ์๋ SK/AK ๊ฐ์ ํญ์ ์์ ํ๋ ์ด์คํ๋์ ๋๋ค. ์ค์ ๊ฐ์ ์ ๋ ๋ฌธ์ยท์ฝ๋์ ํ๋์ฝ๋ฉํ์ง ๋ง๊ณ , ๋ฐ๊ธ๋ฐ์ ๊ฐ์ ๊ฐ์ ์์ ํ ๋ฐฉ์(์ํฌ๋ฆฟ ํ์ผ, ํ๊ฒฝ๋ณ์, ์ํฌ๋ฆฟ ๋งค๋์ ๋ฑ)์ผ๋ก ๋ณด๊ดํ์ธ์.
๊ณตํต ์ฌ์ ์กฐ๊ฑด
| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| ๋์ CSN | ์์ด์ ํธ๋ฅผ ๋ฑ๋กํ ํ๋ก์ ํธ ๋ฒํธ. ์ด ํ์ด์ง๋ ์ธ์ ์ ํ์ฌ CSN ๊ธฐ์ค์ผ๋ก ๋ชฉ๋ก์ ๋ณด์ฌ์ค๋๋ค. |
| SK (Secret Key) | ํด๋น CSN์ ๋ํด ์ฐ๊ธฐ(๋ฑ๋ก) ๊ถํ์ ๊ฐ์ง ๋น๋ฐํค. ํ๋ก์ ํธ ๊ด๋ฆฌ์์๊ฒ ํด๋น CSN์ฉ SK ๋ฐ๊ธ์ ์์ฒญํ์ธ์ โ ์ด ํ๋ฉด์ด๋ API๋ก ์ค์ค๋ก ๋ฐ๊ธ๋ฐ์ ์ ์์ต๋๋ค. |
| ๋ฑ๋ก ์๋ํฌ์ธํธ | https://giipfaw.azurewebsites.net/api/giipApiSk4 (anonymous ์ธ์ฆ โ Function key ๋ถํ์, ์์ฒญ ํผ์ SK ํ ํฐ์ผ๋ก ์ธ์ฆ) |
์ฝ์์ ์ด ํ๋ฉด์ ๋ฑ๋กํ๊ธฐ โ ๊ทธ๋๋ก ๋ณต์ฌํด์ ์ฝ์์ ๋ถ์ฌ๋ฃ๊ธฐ
์ด ํ๋ฉด์ "Open Interactive Sessions" ์ ์ง๊ธ ์ฐ๋ Claude Code ์ฝ์์ด ๋ณด์ด์ง ์์ผ๋ฉด, ์๋ ์์ฒญ๋ฌธ์ ์ฝ์(Claude Code)์ ๊ทธ๋๋ก ๋ถ์ฌ๋ฃ์ผ๋ฉด ๋ฉ๋๋ค. ์ฝ์์ด ์๋ "๋ฐฉ๋ฒ A" ์ ๊ท๊ฒฉ(agentKey ๊ท์น, SP ํธ์ถ)๋ง์ผ๋ก ๋ฑ๋ก์ ์ํํ๋ฏ๋ก ๋ณ๋ ์คํฌ๋ฆฝํธ๋ ๋ค๋ฅธ ์ ์ฅ์๊ฐ ํ์ ์์ต๋๋ค. <CSN> ์ ๋ฑ๋กํ ํ๋ก์ ํธ ๋ฒํธ๋ก ๋ฐ๊ฟ ๋ฃ์ผ์ธ์.
์ฌ์ ์กฐ๊ฑด: ๋์ CSN ์ฉ SK ๊ฐ ์ด PC ์ ์์ ํด๋
giipAgent.cnf(๋๋giipAgent.cfg)์sk=๋ก ์์ด์ผ ํฉ๋๋ค(์์ผ๋ฉด ํ๋ก์ ํธ ๊ด๋ฆฌ์์๊ฒ ํด๋น CSN ์ฉ SK ๋ฐ๊ธ์ ์์ฒญ). ์ฝ์์ SK ๋ฅผ ์ฌ์ฉ์์๊ฒ ๋๋ฌป์ง ์๊ณ ๊ทธ ํ์ผ์์ ์ฝ์ต๋๋ค.
์์ฒญ๋ฌธ 1 โ ์ง๊ธ ์ด๋ฆฐ ์ด ์ฝ์์ ํ ๋ฒ ๋ฑ๋ก
giip ์ค์ผ์ค๋ฌ ์์ด์ ํธ ํ๋ฉด(/ko/admin/catquest/schedulers)์ ์ง๊ธ ์ด๋ ค ์๋ ์ด ์ฝ์ ์ธ์
์ CSN <CSN> ์ ๋ํํ ์ธ์
์ผ๋ก ํ ๋ฒ ๋ฑ๋กํด์ค.
์ด ๋ฌธ์(/help/catquest-schedulers.ko.md)์ "๋ฐฉ๋ฒ A โ ๋ํํ Claude Code ์ธ์
๋ฑ๋ก"์ ์ฝ๊ณ ๊ทธ ๊ท๊ฒฉ ๊ทธ๋๋ก ๋ฐ๋ผ. register-interactive-session.ps1 ๊ฐ์ ๋ณ๋ ์คํฌ๋ฆฝํธ๋ ์๋ ๊ฒ์ผ๋ก ๋ณด๊ณ , ๋ฌธ์์ ์ ํ giipApiSk4 ํธ์ถ(HTTP POST, ํผ ํ๋ text/token/jsondata)์ ์ง์ ์คํํด.
1. agentKey: ๋ฌธ์์ "agentKey ์์ฑ ๊ท์น" 5๋จ๊ณ๋๋ก ๋ง๋ค์ด. ์๋ณธ ID ๋ ์ด ์ธ์
์ session_id ๋ฅผ ์๋ฉด ๊ทธ ๊ฐ, ๋ชจ๋ฅด๋ฉด fallback_<COMPUTERNAME>_<PID>. COMPUTERNAME ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด hostname ๋ช
๋ น ๊ฒฐ๊ณผ๋ฅผ ์จ.
2. SchedulerAgentUpsert: text ๋ "SchedulerAgentUpsert agentKey displayName hostIdentifier windowsTaskName projectName scheduleDesc isActive lssn osType agentType version". jsondata ๋ agentKey, displayName="Claude Interactive Session (<ํธ์คํธ๋ช
>)", hostIdentifier=<ํธ์คํธ๋ช
>, windowsTaskName/projectName/scheduleDesc ๋ ๋น ๋ฌธ์์ด, isActive="1", lssn="0", osType=Windows ๋๋ Linux, agentType="claude_interactive_session", version="". ํ๊ฒฝ๋ณ์ CLAUDE_CODE_BRIDGE_SESSION_ID ๊ฐ ์์ผ๋ฉด text ์ jsondata ๋งจ ๋์ capabilities={"sessionUrl":"https://claude.ai/code/<๊ทธ ๊ฐ>"} ๋ฅผ ์ถ๊ฐํ๊ณ , ์์ผ๋ฉด capabilities ๋ฅผ ํต์งธ๋ก ๋นผ. ๋ค๋ฅธ ๊ฐ์ผ๋ก sessionUrl ์ ๋ง๋ค์ด๋ด์ง ๋ง.
3. SchedulerAgentRunStart: text ๋ "SchedulerAgentRunStart runIdKey agentKey executionMode totalIssueCount". runIdKey=<agentKey>_<ํ์ฌ์๊ฐ yyyyMMddHHmmss>, executionMode="interactive", totalIssueCount="0".
4. SK ๋ ์์ ํด๋์ giipAgent.cnf(์์ผ๋ฉด giipAgent.cfg)์ sk= ๊ฐ์ ์ฝ์ด token ์ผ๋ก ์จ. ๋์๊ฒ ๋๋ฌป์ง ๋ง๊ณ , SK ๊ฐ์ ํ๋ฉดยท๋ก๊ทธยทํ์ผ ์ด๋์๋ ์ถ๋ ฅํ๊ฑฐ๋ ๊ธฐ๋กํ์ง ๋ง.
5. ํ์ธ: ๊ฐ์ giipApiSk4 ๋ก text "SchedulerAgentList csn", jsondata {"csn":"<CSN>"} ๋ฅผ ํธ์ถํด ๋ฐฉ๊ธ ๋ง๋ agentKey ์ ํ์ด is_active=true, current_status=RUNNING ์ธ์ง ํ์ธํด. ๊ฒฐ๊ณผ์ ์ฌ์ฉํ agentKey/runIdKey ๋ฅผ ์๋ ค์ค(๊ฐ ์ค SK ๋ ์ ์ธ).
์์ฒญ๋ฌธ 2 โ ์์ผ๋ก ๋ชจ๋ ์ธ์ ์ด ์๋ ๋ฑ๋ก๋๊ฒ ํ ์ค์
์ด PC ์์ Claude Code ์ธ์
์ด ์ด๋ฆฌ๊ณ ๋ซํ ๋๋ง๋ค giip ์ค์ผ์ค๋ฌ ์์ด์ ํธ ํ๋ฉด์ ์๋์ผ๋ก ๋ฑ๋ก/ํด์ ๋๋๋ก SessionStart/SessionEnd ํ
์ ์ค์ ํด์ค. ๋์ CSN ์ <CSN>.
์ด ๋ฌธ์(/help/catquest-schedulers.ko.md)์ "๋ฐฉ๋ฒ A โ ๋ํํ Claude Code ์ธ์
๋ฑ๋ก"์ ์ฝ๊ณ ๊ทธ ๊ท๊ฒฉ๋ง์ผ๋ก ์ง์ ๊ตฌํํด. ๋ค๋ฅธ ์ ์ฅ์์์ ์คํฌ๋ฆฝํธ๋ฅผ ๊ฐ์ ธ์ค๋ ค ํ์ง ๋ง.
1. ํ
์ฒ๋ฆฌ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉ์ ํ ์๋ ํ ๊ณณ(์: ~/.claude/giip-console-hook.ps1)์ ๋ง๋ค์ด. ์ธ์๋ก Start ๋๋ End ๋ฅผ ๋ฐ๊ณ , ํ์ค์
๋ ฅ์ผ๋ก ํ
์ด๋ฒคํธ JSON ์ ์ฝ์ด. Windows ๊ฐ ์๋๋ฉด pwsh ๋ bash ๋ก ์์ฑํด๋ ๋ผ.
2. ํ
๋ฑ๋ก์ ๋ฌธ์์ JSON ๋๋ก ~/.claude/settings.json(์ ์ญ)์ hooks.SessionStart ์ hooks.SessionEnd ์ command ํ
์ ์ถ๊ฐํด. matcher ๋ ๋ฃ์ง ๋ง. ์ด๋ฏธ ์๋ hooks ํญ๋ชฉ์ ๋ฎ์ด์ฐ์ง ๋ง๊ณ ๋ฐฐ์ด์ ์ถ๊ฐํ๊ณ , ๋ฌธ์ JSON ์ timeout ๊ฐ์ ๊ทธ๋๋ก ์จ.
3. ํค๋๋ฆฌ์ค ์ ์ธ: ์คํฌ๋ฆฝํธ๋ ๋จผ์ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ claude ํ๋ก์ธ์ค์ ์ปค๋งจ๋๋ผ์ธ์ -p ๋๋ --print ๊ฐ ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ํ์ง ์๊ณ ์ข
๋ฃํด(๋ฌธ์์ ํค๋๋ฆฌ์ค ํ์ ). CLAUDE_CODE_BRIDGE_SESSION_ID ์ ์ ๋ฌด๋ก ํค๋๋ฆฌ์ค๋ฅผ ํ์ ํ์ง ๋ง.
4. Start: agentKey ๋ ๋ฌธ์์ "agentKey ์์ฑ ๊ท์น"๋๋ก(์๋ณธ ID = stdin ์ session_id, ์์ผ๋ฉด fallback_<COMPUTERNAME>_<PID>) ๋ง๋ ๋ค, SchedulerAgentUpsert(agentType="claude_interactive_session", isActive="1", ํ๋์ ์์๋ ๋ฌธ์์ ์์์ ๋์ผ)์ SchedulerAgentRunStart(executionMode="interactive", totalIssueCount="0")๋ฅผ ํธ์ถํด. runIdKey=<agentKey>_<ํ์ฌ์๊ฐ yyyyMMddHHmmss> ์ด๊ณ , End ์์ ์ฐ๋๋ก ์์ ํด๋์ ํ์ผ์ ์ ์ฅํด. CLAUDE_CODE_BRIDGE_SESSION_ID ๊ฐ ์์ ๋๋ง capabilities.sessionUrl ์ ๋ฃ๊ณ , ์์ผ๋ฉด capabilities ๋ฅผ ๋บ ์ฑ ๋ฑ๋ก์ ๊ณ์ํด.
5. End: ๊ฐ์ ๊ท์น์ผ๋ก agentKey ๋ฅผ ๋ค์ ๊ณ์ฐํด SchedulerAgentRunEnd(status="ENDED", processedCount/skippedCount/failedCount="0")๋ฅผ ํธ์ถํ๊ณ , ์ด์ด์ SchedulerAgentUpsert ๋ฅผ isActive="0" ์ผ๋ก ํธ์ถํด ์คํ๋ผ์ธ์ผ๋ก ์ ํํด.
6. ํธ์ถ์ ๋ชจ๋ giipApiSk4(text/token/jsondata)๋ก ํ๊ณ , ํ
์ด ์คํจํด๋ ์ธ์
์ด ๋งํ์ง ์๊ฒ ํญ์ ์ข
๋ฃ์ฝ๋ 0 ์ผ๋ก ๋๋ด.
7. SK ๊ฐ์ ์คํฌ๋ฆฝํธ์ ๋ฃ์ง ๋ง๊ณ , ์คํํ ๋๋ง๋ค giipAgent.cnf(์์ผ๋ฉด giipAgent.cfg)์ sk= ์์ ์ฝ๋๋ก ๊ทธ ํ์ผ์ ์ ๋๊ฒฝ๋ก๋ง ์ ์ด. ๋์๊ฒ ๋๋ฌป์ง ๋ง๊ณ , SK ๊ฐ์ ์ถ๋ ฅยท๋ก๊ทธยทํ์ผ์ ๋จ๊ธฐ์ง ๋ง.
8. ๋๋๋ฉด ๋ง๋ค๊ฑฐ๋ ๋ฐ๊พผ ํ์ผ์ ๊ฒฝ๋ก ๋ชฉ๋ก๊ณผ, ์ ์ธ์
์์ ๋ฑ๋ก๋๋์ง ํ์ธํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค.
- ์์ฒญ๋ฌธ 1 ๋ก ๋ฑ๋กํ ์ธ์ ์ ์ข ๋ฃ ํ ์ด ์์ผ๋ฏ๋ก, ๋ซ์ ๋ ํด์ ํ๋ ค๋ฉด ์ฝ์์๊ฒ "์๋ ค์ค agentKey/runIdKey ๋ก SchedulerAgentRunEnd ๋ฅผ ํธ์ถํ๊ณ SchedulerAgentUpsert ๋ฅผ isActive=0 ์ผ๋ก ํธ์ถํด์ค" ๋ผ๊ณ ์์ฒญํ์ธ์. ํ (์์ฒญ๋ฌธ 2)์ ์ฐ๋ฉด ์ข ๋ฃ ์ ์๋์ผ๋ก ํด์ ๋ฉ๋๋ค.
- ์ฑ๊ณต ํ์ธ: ํ๋ฉด ์๋ก๊ณ ์นจ ์ "Open Interactive Sessions" ์นด๋์ ์์ด์ ํธ ๋ชฉ๋ก์ ์ธ์ ์ด ๋ํ๋ฉ๋๋ค. ์์ธ ๊ท๊ฒฉ์ ์๋ "๋ฐฉ๋ฒ A" ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
๋ฐฉ๋ฒ A โ ๋ํํ Claude Code ์ธ์ ๋ฑ๋ก
Claude Code ๊ฐ์ ๋ํํ AI ์ฝ๋ฉ ์ธ์ ์ "Open Interactive Sessions" ์นด๋์ ๋ํ๋๊ฒ ํ๋ ค๋ฉด, ์ธ์ ์ SessionStart/SessionEnd ํ ์์ ์๋ ์ ์ฐจ๋ฅผ ์คํํ๋๋ก ๊ตฌ์ฑํฉ๋๋ค.
- ์ฌ์ ์กฐ๊ฑด: ์ ๊ณตํต ์ฌ์ ์กฐ๊ฑด(๋์ CSN์ฉ SK) + ์ธ์ ์ ์คํํ๋ ๋๊ตฌ(Claude Code ๋ฑ)์ SessionStart/SessionEnd ํ ์ ๋ฑ๋กํ ์ ์๋ ์ค์ ๊ถํ.
- ์ธ์
์์(SessionStart) ์ โ
SchedulerAgentUpsertํธ์ถ๋ก identity ๋ฑ๋ก/๊ฐฑ์ ํSchedulerAgentRunStartํธ์ถ๋ก ์คํ ์์์ ๊ธฐ๋กํฉ๋๋ค. - ์ธ์
์ข
๋ฃ(SessionEnd) ์ โ
SchedulerAgentRunEndํธ์ถ๋ก ์คํ ์ข ๋ฃ๋ฅผ ๊ธฐ๋กํ๊ณ ,SchedulerAgentUpsert๋ฅผisActive=0์ผ๋ก ๋ค์ ํธ์ถํด ์คํ๋ผ์ธ์ผ๋ก ์ ํํฉ๋๋ค.
agentKey ์์ฑ ๊ท์น(๊ทธ๋๋ก ์ ์ฉ, ํ๋จ ๋ถํ์): csn + agentKey ์กฐํฉ์ด DB์์ UNIQUE ์ ์ฝ์ด๋ฏ๋ก, ๊ฐ์ ์ธ์
์ ์ฌ์์ํด๋ ํญ์ ๊ฐ์ ๊ฐ์ด ๋์์ผ ํฉ๋๋ค(๊ทธ๋์ผ ์ฌ์์ ์ ์ ํ์ด ์๋๋ผ ๊ธฐ์กด ํ์ด ๊ฐฑ์ ๋ฉ๋๋ค). ์๋ ์์๋ฅผ ๊ทธ๋๋ก ์ ์ฉํด ๊ณ์ฐํ์ญ์์ค.
- ์๋ณธ ID: ํ
stdin JSON์
session_idํ๋ ๊ฐ์ด ์์ผ๋ฉด ๊ทธ ๊ฐ์ ์ด๋ค. ์์ผ๋ฉดfallback_<COMPUTERNAME ํ๊ฒฝ๋ณ์ ๊ฐ>_<ํ์ฌ ํ๋ก์ธ์ค PID>๋ฅผ ์๋ณธ ID๋ก ์ด๋ค. - ์ ๊ทํ: ์๋ณธ ID์์ ์์ซ์(
a-z,A-Z,0-9)๊ฐ ์๋ ๋ฌธ์๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ค(์ ๊ท์ ์นํ:[^a-zA-Z0-9]โ''). - ์๋ฅด๊ธฐ(1์ฐจ): ์ ๊ทํ๋ ๊ฐ์ด 24์๋ฅผ ๋์ผ๋ฉด ์ 24์๋ง ๋จ๊ธด๋ค.
- ์กฐํฉ:
agentKey = "claude_interactive_" + <COMPUTERNAME ํ๊ฒฝ๋ณ์ ๊ฐ> + "_" + <3๋จ๊ณ ๊ฒฐ๊ณผ๊ฐ> - ์๋ฅด๊ธฐ(2์ฐจ): 4๋จ๊ณ ๊ฒฐ๊ณผ๊ฐ 100์๋ฅผ ๋์ผ๋ฉด ์ 100์๋ง ๋จ๊ธด๋ค. ์ด ์ต์ข
๊ฐ์
agentKey๋ก ์ด๋ค.
SessionStart/SessionEnd ํ
๋ฑ๋ก ์์น(๊ทธ๋๋ก ๋ถ์ฌ๋ฃ์ JSON): Claude Code์์๋ ํ๋ก์ ํธ ๋ฃจํธ์ .claude/settings.json(ํด๋น ํ๋ก์ ํธ์๋ง ์ ์ฉ) ๋๋ ์ฌ์ฉ์ ํ์ ~/.claude/settings.json(๋ชจ๋ ํ๋ก์ ํธ์ ์ ์ญ ์ ์ฉ) ์ค ํ๋๋ฅผ ๊ณ ๋ฅธ ๋ค, ๊ทธ ํ์ผ์ ์ต์์์ ์๋ hooks ํค๋ฅผ ๋ณํฉํ์ญ์์ค. ํ์ผ์ ์ด๋ฏธ hooks ํค๊ฐ ์๋ค๋ฉด SessionStart/SessionEnd ๋ฐฐ์ด ์์ ์๋ ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ์ญ์์ค(๊ธฐ์กด ํญ๋ชฉ์ ๋ฎ์ด์ฐ์ง ๋ง์ญ์์ค). matcher ํ๋๋ ๋ฃ์ง ์์ต๋๋ค โ ์ด ํ
์ ๋ชจ๋ ์ธ์
์ ์ ์ญ ์ ์ฉ๋ฉ๋๋ค.
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "<์ธ์
์์ ์ ์คํํ command. ์: powershell -NoProfile -ExecutionPolicy Bypass -File \"<๋ฑ๋ก ์คํฌ๋ฆฝํธ์ ์ ๋๊ฒฝ๋ก>\" -Action Start>",
"timeout": 15000
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "<์ธ์
์ข
๋ฃ ์ ์คํํ command. ์: powershell -NoProfile -ExecutionPolicy Bypass -File \"<๋ฑ๋ก ์คํฌ๋ฆฝํธ์ ์ ๋๊ฒฝ๋ก>\" -Action End>",
"timeout": 15000
}
]
}
]
}
}
โ ๏ธ ์ ์ญ(matcher ์๋) ํ ์ผ๋ก ๋ฑ๋กํ ๊ฒฝ์ฐ ํค๋๋ฆฌ์ค ์คํ์ ์ฃผ์(giip #1837): ์ ํ ์ matcher๊ฐ ์์ด ์ด ํธ์คํธ์์ ์คํ๋๋ ๋ชจ๋ claude ํ๋ก์ธ์ค(๋ํํ ์ธ์ ๋ฟ ์๋๋ผ, ๋ฌด์ธ ์ค์ผ์ค๋ฌ๊ฐ
claude -p๋ก ์ฌ๋ ํค๋๋ฆฌ์ค ์คํ๊น์ง ์ ๋ถ)์์ ๋ฐํํฉ๋๋ค. ๊ทธ๋์ ๋ฑ๋ก ์คํฌ๋ฆฝํธ ์์ "์ง๊ธ ์ด ์คํ์ด ๋ํํ์ธ์ง ํค๋๋ฆฌ์ค์ธ์ง" ํ์ ๋ก์ง์ด ์ฌ์ค์ ํ์์ ๋๋ค. ์ด๋$env:CLAUDE_CODE_BRIDGE_SESSION_ID(Remote Control ๋ธ๋ฆฟ์ง ์ฐ๊ฒฐ ์ฌ๋ถ)๋ฅผ ํ์ ๊ธฐ์ค์ผ๋ก ์ฐ์ง ๋ง์ญ์์ค โ ์ด ๊ฐ์ ๋ธ๋ฆฟ์ง ์ฐ๊ฒฐ ์ฌ๋ถ๋ง ๋ํ๋ผ ๋ฟ ํค๋๋ฆฌ์ค ์ฌ๋ถ์ ๋ฌด๊ดํ๋ฉฐ, ์ง์ง ๋ํํ ์ธ์ ๋ ์์ง/remote-control์ ์คํ/์ฐ๊ฒฐํ์ง ์์๋ค๋ฉด ์ด ๊ฐ์ด ์์ ์ ์์ต๋๋ค(๊ทธ๋ฐ ์ธ์ ๊น์ง ํค๋๋ฆฌ์ค๋ก ์คํํด ๋ฑ๋ก ์์ฒด๊ฐ ์คํต๋๋ ์ฌ๊ณ ๊ฐ ์ค์ ๋ก ์์์ต๋๋ค โ giip #1837). ์ฌ๋ฐ๋ฅธ ํ์ ๋ฐฉ๋ฒ: ์ด ํ ์ ์คํํ๋ ํ๋ก์ธ์ค ์์ ์ ๋ถ๋ชจ๋ฅผ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ ์ค์ claude/claude.exeํ๋ก์ธ์ค๋ฅผ ์ฐพ๊ณ , ๊ทธ ํ๋ก์ธ์ค์ ์ปค๋งจ๋๋ผ์ธ์-p/function Test-IsHeadlessClaudeInvocation { try { $checkPid = $PID for ($i = 0; $i -lt 6; $i++) { $proc = Get-CimInstance Win32_Process -Filter "ProcessId=$checkPid" -ErrorAction Stop if (-not $proc) { return $false } if ($proc.Name -eq 'claude.exe') { $cmd = $proc.CommandLine if ($cmd -and ($cmd -match '(^|\s)(-p|--print)(\s|$)')) { return $true } return $false } $checkPid = $proc.ParentProcessId if (-not $checkPid -or $checkPid -eq 0) { return $false } } return $false } catch { return $false } }Windows๊ฐ ์๋ ํ๊ฒฝ์์๋ ๋์ผํ ์๋ฆฌ(๋ถ๋ชจ ํ๋ก์ธ์ค์ ์ปค๋งจ๋๋ผ์ธ์์
-p/
์ด command๋ ํ์ค์
๋ ฅ(stdin)์ผ๋ก ํ
์ด๋ฒคํธ JSON(session_id ๋ฑ ํฌํจ)์ ๋ฐ์ต๋๋ค. ์๋ ์ด ๋ฌธ์์ ์ ํ SP ํธ์ถ ์คํ(ํธ์ถ ๊ท์ฝ, ํ๋ ๋ชฉ๋ก, agentKey ์์ฑ ๊ท์น)๋ง์ผ๋ก ์๊ธฐ ์๊ฒฐ์ ์ผ๋ก ๊ตฌํ ๊ฐ๋ฅํฉ๋๋ค โ ์ด ๋ฌธ์๋ฅผ ๊ด๋ฆฌํ๋ ์ด์์๊ฐ ๊ฐ์ธ์ ์ผ๋ก ์ฐธ๊ณ ํ๋ ๊ตฌํ์ฒด๊ฐ ์๋๋ผ๋ ๊ทธ ์ ์ฅ์๋ ๋น๊ณต๊ฐ๋ผ ๋ค๋ฅธ ์ธ์
์ด ์ ๊ทผํ ์ ์์ผ๋, ์ฝ๋๋ฅผ ์ด๋๊ฐ์์ ๊ฐ์ ธ์ค๋ ค ํ์ง ๋ง๊ณ ์ด ๋ฌธ์์ ์คํ๋ง์ผ๋ก ์ง์ ์์ฑํ์ญ์์ค.
์ด๋ agentKey์ capabilities.sessionUrl์ ์๋ก ๋ค๋ฅธ ๊ฐ์์ ๋์ค๋ ๋ณ๊ฐ์ ID๋ผ๋ ์ ์ ์ฃผ์ํ์ธ์ โ ์ด ๋์ ํผ๋ํ๋ฉด "์ธ์
ID๊ฐ ์์ด์ URL์ ๋ชป ๋ง๋ ๋ค"๋ ์ฐฉ๊ฐ์ ๋น ์ ธ ๋ฑ๋ก ์์ฒด๋ฅผ ํฌ๊ธฐํ๊ฒ ๋ ์ ์์ต๋๋ค:
agentKeyโ ํ stdin์session_id(ํ๋์ค ๋ด๋ถ UUID, ์:~/.claude/projects/*/<uuid>.jsonlํ์ผ๋ช ์ ์ฐ์ด๋ ๊ฐ) ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑํฉ๋๋ค. "์ฌ์์ํด๋ ๊ฐ์ ์ธ์ ์ด๋ฉด ๊ฐ์ ํค๊ฐ ๋์ค๊ฒ" ํ๊ธฐ ์ํ ์ฉ๋์ผ ๋ฟ, URL์ด ์๋๋๋ค.capabilities.sessionUrlโ ์๋ค๋ฉด$env:CLAUDE_CODE_BRIDGE_SESSION_ID(์:session_01JGmSiTajXu9iZmjVZC27Nt๊ฐ์ ULID ์คํ์ผ ๊ฐ โ ํ stdin์session_id์๋ ๊ฐ์ด ๋ค๋ฅธ ๋ณ๊ฐ์ ID)๋ฅผ ์ด์ฉํดhttps://claude.ai/code/<์ด ๊ฐ>ํํ๋ก ๊ตฌ์ฑํฉ๋๋ค.
์ด ํ๊ฒฝ๋ณ์๋ ๋ชจ๋ ์ธ์
์ ์๋ ๊ฒ ์๋๋๋ค โ ์๋ฅผ ๋ค์ด claude.ai/code ๋ธ๋ฆฟ์ง๋ฅผ ๊ฑฐ์น์ง ์์ ๋ก์ปฌ CLI ์ธ์
์๋ ์์ ์ ์์ต๋๋ค. $env:CLAUDE_CODE_BRIDGE_SESSION_ID๊ฐ ์๋ค๋ฉด sessionUrl์ ๋ง๋ค ์ ์๋ค๋ ๋ป์ด์ง, ๋ฑ๋ก์ด ๋งํ๋ค๋ ๋ป์ด ์๋๋๋ค โ ๊ทธ๋ด ๋๋ capabilities ํ๋ ์์ฒด๋ฅผ ํธ์ถ์์ ํต์งธ๋ก ๋นผ๊ณ ๋๋จธ์ง ํ๋๋ง์ผ๋ก ๋ฑ๋ก์ ๊ณ์ ์งํํ๋ฉด ๋ฉ๋๋ค(์๋ "sessionUrl์ ๋ง๋ค ์ ์์ ๋" ์ฐธ๊ณ ).
CLAUDE_CODE_BRIDGE_SESSION_ID๊ฐ ์ธ์ ์๊ธฐ๋์ง, ์์ ๋ ์ฌํ์ ์ป์ ์ ์๋์ง(๊ณต์ ๋ฌธ์ https://code.claude.com/docs/en/remote-control ๊ธฐ์ค, ๊ทธ๋๋ก ์คํ ๊ฐ๋ฅํ ์ ์ฐจ):
์ด ํ๊ฒฝ๋ณ์๋ ์ธ์
์ด Anthropic์ "Remote Control" ๊ธฐ๋ฅ์ ์ฐ๊ฒฐ๋ผ ์์ ๋๋ง ์กด์ฌํฉ๋๋ค. ์๋ ์กฐ๊ฑด์ ํ๋๋ผ๋ ๋ง์กฑํ์ง ๋ชปํ๋ฉด ์์ฒ์ ์ผ๋ก ์ป์ ์ ์์ผ๋ฉฐ, ์ด๋ ๊ฒฐํจ์ด ์๋๋ผ ์ ์ ์ํ์
๋๋ค โ ์ด ๊ฒฝ์ฐ ๋ค๋ฅธ ์๋๋ฅผ ํ์ง ๋ง๊ณ ๊ณง๋ฐ๋ก capabilities๋ฅผ ์๋ตํ๊ณ ๋ฑ๋ก์ ๊ณ์ํ์ญ์์ค.
- ํค๋๋ฆฌ์ค(
claude -p) ์ธ์ ์๋ ์ด ๊ธฐ๋ฅ ์์ฒด๊ฐ ์์ต๋๋ค. Remote Control์ ๋ํํ ์ธ์ ์ ์ฉ์ด๋ฏ๋ก, gissue ์ค์ผ์ค๋ฌ์ฒ๋ผclaude -p๋ก ๋๋ ๋ฌด์ธ ํ๋ก์ธ์ค๋ ์ด ๊ฐ์ ์ ๋ ๊ฐ์ง ์ ์์ต๋๋ค. - API ํค(
ANTHROPIC_API_KEY) ์ธ์ฆ ์ธ์ ์ Remote Control์ ์ง์ํ์ง ์์ต๋๋ค. claude.ai ๊ณ์ ๋ก๊ทธ์ธ(claude์คํ ํ/login)์ด ํ์ํฉ๋๋ค. - Amazon Bedrock / Google Vertex / Microsoft Foundry ๊ฒฝ์ ์ด๊ฑฐ๋,
ANTHROPIC_BASE_URL์ดapi.anthropic.com์ธ์ ๊ฐ(LLM ๊ฒ์ดํธ์จ์ดยทํ๋ก์ ๋ฑ)์ผ๋ก ์ค์ ๋ผ ์์ผ๋ฉด ์ง์๋์ง ์์ต๋๋ค. DISABLE_TELEMETRY,DO_NOT_TRACK,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,DISABLE_GROWTHBOOK์ค ํ๋๋ผ๋ ์ค์ ๋ผ ์์ผ๋ฉด ์ง์๋์ง ์์ต๋๋ค(์ค์ ๋ผ ์๋ค๋ฉด ๊ทธ ๋ณ์๋ฅผ ํด์ ํด์ผ ํจ).
์ ์กฐ๊ฑด์ ์ ๋ถ ๋ง์กฑํ๋ ์ผ๋ฐ ๋ํํ ์ธ์
์ธ๋ฐ๋ ์ด ๋ณ์๊ฐ ์๋ค๋ฉด, ์์ง Remote Control์ด ์ฐ๊ฒฐ๋ง ์ ๋ ๊ฒ๋ฟ์
๋๋ค. ์ธ์
์ ์ฌ์์ํ ํ์ ์์ด, ๊ทธ ์ธ์
์์์ ๋ค์ ๋ช
๋ น์ ์คํํ๋ฉด ์ฆ์ ์ฐ๊ฒฐ๋๊ณ ๊ทธ ์๊ฐ๋ถํฐ $env:CLAUDE_CODE_BRIDGE_SESSION_ID๊ฐ ์ค์ ๋ฉ๋๋ค:
/remote-control
(/rc๋ ๋์ผ) ๋ค์ ์ธ์
๋ถํฐ ๋งค๋ฒ ์๋์ผ๋ก ์ฐ๊ฒฐ๋๊ฒ ํ๋ ค๋ฉด ์ธ์
์์์ /config๋ฅผ ์คํํด "Enable Remote Control for all sessions"๋ฅผ ์ผ๊ฑฐ๋, ์ฌ์ฉ์ ํ์ ~/.claude/settings.json์ ๋ค์์ ์ถ๊ฐํ์ญ์์ค:
{
"remoteControlAtStartup": true
}
์ฌ๊ธฐ์๋ ์ ๋ ๊ธ์ง (guide 147ํ ์์น๊ณผ ๋์ผ): ์ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ๋ชปํด(ํค๋๋ฆฌ์ค ์คํ, API ํค ์ธ์ฆ ๋ฑ) CLAUDE_CODE_BRIDGE_SESSION_ID๋ฅผ ์ป์ ์ ์๋ ๊ฒฝ์ฐ, ํ
stdin์ session_id๋ $env:CLAUDE_CODE_SESSION_ID ๊ฐ์ ๋ค๋ฅธ ๊ฐ์ผ๋ก ๋์ฒดํด sessionUrl์ "๋ง๋ค์ด๋ด๋ ค" ํ์ง ๋ง์ญ์์ค โ ์ด ๊ฐ๋ค์ claude.ai/code์ ์ค์ ์ธ์
๊ณผ ๋ฌด๊ดํด ์ด๋ฆฌ์ง ์๋(404) ๋งํฌ๊ฐ ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ ์ ์ผํ ์ ๋ต์ capabilities๋ฅผ ์๋ตํ๊ณ ๋ฑ๋ก์ ๊ณ์ ์งํํ๋ ๊ฒ์ด๋ฉฐ, ๋ณ๋ ์กฐ์น๋ฅผ ์๋ํ ํ์๊ฐ ์์ต๋๋ค.
์ด ํ๋จ์ ์์ ํ ๊ธฐ๊ณ์ ์
๋๋ค โ ์ฌ๋์๊ฒ ๋ฌป์ง ์์ต๋๋ค. ์์ ์ ํ๋ก์ธ์ค์์ $env:CLAUDE_CODE_BRIDGE_SESSION_ID ์กด์ฌ ์ฌ๋ถ๋ง ํ์ธํด ๋ถ๊ธฐํ๋ฉฐ, ์ด๋ค ๊ฐ์ ์ธ์ง ์ฌ์ฉ์์๊ฒ ์ ํ์ง๋ก ์ ์ํ๊ฑฐ๋ ์ง๋ฌธํ๋ ๊ฒ์ ์ ๋ ๊ธ์ง์
๋๋ค. ํ
stdin์ session_id(agentKey์ ์ถ์ฒ)๋ฅผ sessionUrl๋ก ์ฌ์ฌ์ฉํ๋ ๊ฒ๋ ์ ๋ ๊ธ์ง์
๋๋ค โ ์๋ก ๋ค๋ฅธ ID์ด๋ฉฐ ๊นจ์ง/404 ๋งํฌ๊ฐ ๋ฉ๋๋ค. ๋ด๋ถ ๋๊ตฌ ๋งํฌ, ์์ URL ๋ฑ ๋ค๋ฅธ ๊ฐ์ผ๋ก sessionUrl์ ๋์ ์ฑ์ฐ๋ ๊ฒ๋ ๊ธ์ง์
๋๋ค โ sessionUrl์ ์ค์ง claude.ai/code ๋ธ๋ฆฟ์ง ๋งํฌ์ด๊ฑฐ๋, ์์ ์๋(์๋ต๋) ๊ฐ์ด์ด์ผ ํฉ๋๋ค.
sessionUrl์ ๋ฐ๋์ ์ฑ์ฐ๊ณ ์ถ๋ค๋ฉด: ์ด ๋ฑ๋ก์ ์ํํ๋ ์ธ์
"์๊ธฐ ์์ "์ด Remote Control ๋ธ๋ฆฟ์ง์ ์ฐ๊ฒฐ๋ผ ์์ด์ผ $env:CLAUDE_CODE_BRIDGE_SESSION_ID๊ฐ ์ฑ์์ง๋๋ค. ์ด๋ ๊ฐ ์ธ์
์ด ์ค์ค๋ก ๊ฐ์ถ๋ ์ํ์ด์ง, ๋ค๋ฅธ ์ด์์์ PC ์ค์ (์: ์ธ์
์์ ์ ์๋์ผ๋ก ๋ธ๋ฆฟ์ง์ ์ฐ๊ฒฐํ๋ ์ค์ )์ ์์กดํ ์ ์์ต๋๋ค โ ๋ค๋ฅธ ์ฌ๋์ PC ์ค์ ์ ์ด ์ธ์
์ ์๋ฌด ์ํฅ๋ ์ฃผ์ง ์์ต๋๋ค. ์์ง ์ฐ๊ฒฐ ์ ์ด๋ผ๋ฉด /remote-control ๋ช
๋ น์ ์คํํ๊ฑฐ๋(๋ํํ ์ธ์
๋ด์์) claude --remote-control/--rc ํ๋๊ทธ๋ก ๋ค์ ์์ํด ์ค์ค๋ก ์ฐ๊ฒฐํ์ญ์์ค. ์ฐ๊ฒฐ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์์๋ ๋ฑ๋ก ์์ฒด(Upsert/RunStart)๋ ๊ณ์ ์งํํด์ผ ํฉ๋๋ค โ ์๋ "sessionUrl์ ๋ง๋ค ์ ์์ ๋(capabilities ์๋ต)" ์ ์ ๋ฐฉ์๋๋ก ํ๊ณ , ๋ฑ๋ก์ ํต์งธ๋ก ๋ฏธ๋ฃจ์ง ๋ง์ญ์์ค.
ํธ์ถ ๊ท์ฝ(giipApiSk4 ๊ณตํต): HTTP POST, application/x-www-form-urlencoded ํผ ํ๋ 3๊ฐ.
โ ๏ธ ์์น ๊ธฐ๋ฐ ํ๋ผ๋ฏธํฐ: ์ด SP๋ค(
pApiSchedulerAgentUpsertBySK๋ฑ)์jsondata์ ํ๋๋ฅผ SP์ ๊ฐ๋ณ ์์น ํ๋ผ๋ฏธํฐ(@p0, @p1, ...)์ ์์๋๋ก ๋ฐ์ธ๋ฉํฉ๋๋ค โ ์ค๊ฐ ํ๋๋ฅผ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๋ค์ชฝ ํ๋(์:capabilities)๊น์ง ๊ฐ์ ์ฑ์ฐ๋ ค๋ฉด ๊ทธ ์์ ๋ชจ๋ ํ๋๋ฅผ ํจ๊ป ๋ณด๋ด์ผ ํ๋ฉฐ, ์ค์ ๋ก ์ ์ฐ๋ ํ๋๋ ์์ ํ ์๋ฆฌ๊ฐ(์:windowsTaskName='',projectName='',scheduleDesc='',lssn='0',version='')์ผ๋ก ์ฑ์๋๋ค. ์ ์ํ ํ๋ผ๋ฏธํฐ(lssn๋ฑ)์ ๋น ๋ฌธ์์ด์ ๋ณด๋ด๋ฉด ๋ณํ ์ค๋ฅ๊ฐ ๋๋ฏ๋ก ๋ฐ๋์ ์ซ์ ๋ฌธ์์ด์ ์จ์ผ ํฉ๋๋ค. ๋ค๋งcapabilities๋ ์ด ํ๋ ๋ชฉ๋ก์ ๋งจ ๋์ ์์ผ๋ฏ๋ก, ๊ฐ์ด ์์ผ๋ฉด(์์์ ์ค๋ช ํ$env:CLAUDE_CODE_BRIDGE_SESSION_ID๋ถ์ฌ ์ํฉ) ํ๋ ์์ฒด๋ฅผ ํต์งธ๋ก ์๋ตํด๋ ์์ ํฉ๋๋ค โ ๋ค์ ์ด์ด์ง๋ ๋ค๋ฅธ ํ๋๊ฐ ์์ด ์์น๊ฐ ๋ฐ๋ฆฌ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์์น ๊ธฐ๋ฐ ์ ์ฝ์ ์ด๋๊น์ง๋ ์ค๊ฐ ํ๋๋ฅผ ๊ฑด๋๋ธ ์ ์๋ค๋ ๋ป์ด๋ฉฐ, ๋ ํ๋๊น์ง ๋ฌด์กฐ๊ฑด ์ฑ์์ผ ํ๋ค๋ ๋ป์ ์๋๋๋ค.
| ํผ ํ๋ | ๊ฐ |
|---|---|
text | "<SP์ด๋ฆ> <ํ๋1> <ํ๋2> ..." (SP ์ด๋ฆ์ BySK ์ ๋ฏธ์ฌ๋ฅผ ๋บ ์ด๋ฆ, ๋ค์ ์ด ํธ์ถ์์ ์ฑ์ธ ํ๋๋ช
์ ๊ณต๋ฐฑ์ผ๋ก ๋์ด) |
token | <YOUR_SECRET_KEY> (๋์ CSN์ SK) |
jsondata | ํ๋๋ช
โ๊ฐ ๋งคํ JSON ๋ฌธ์์ด, ์: {"agentKey":"...","displayName":"..."} |
๊ฐ ๋จ๊ณ์์ ์ค์ ๋ก ์ฑ์ฐ๋ ํ๋:
| ๋จ๊ณ | SP ์ด๋ฆ(text์ ์ฒซ ํ ํฐ) | ์ฃผ์ ํ๋ |
|---|---|---|
| ์์ โ identity ๋ฑ๋ก/๊ฐฑ์ | SchedulerAgentUpsert | agentKey(ํธ์คํธ+์ธ์
๋ณ ๊ณ ์ ์๋ณ์), displayName, hostIdentifier(ํธ์คํธ๋ช
), windowsTaskName, projectName, scheduleDesc, isActive=1, lssn, osType, agentType(์: claude_interactive_session), version, capabilities(JSON ๋ฌธ์์ด, ์: {"sessionUrl":"<์ธ์
์ ์ด ์ ์๋ URL>"}) |
| ์์ โ ์คํ(run) ์์ | SchedulerAgentRunStart | runIdKey(์ด ์คํ์ ๊ณ ์ ํค), agentKey, executionMode=interactive, totalIssueCount |
| ์ข ๋ฃ โ ์คํ(run) ์ข ๋ฃ | SchedulerAgentRunEnd | runIdKey, agentKey, status=ENDED, processedCount, skippedCount, failedCount |
| ์ข ๋ฃ โ identity ์คํ๋ผ์ธ ์ ํ | SchedulerAgentUpsert | agentKey, displayName, hostIdentifier, windowsTaskName, projectName, scheduleDesc, isActive=0 |
์์(PowerShell, ๊ฐ์ ๋ชจ๋ ํ๋ ์ด์คํ๋):
$body = @{
text = 'SchedulerAgentUpsert agentKey displayName hostIdentifier windowsTaskName projectName scheduleDesc isActive lssn osType agentType version capabilities'
token = '<YOUR_SECRET_KEY>'
jsondata = (@{
agentKey = 'claude_interactive_<YOUR_HOST>_<UNIQUE_ID>'
displayName = 'Claude Interactive Session (<YOUR_HOST>)'
hostIdentifier = '<YOUR_HOST>'
windowsTaskName = ''
projectName = ''
scheduleDesc = ''
isActive = '1'
lssn = '0'
osType = 'Windows'
agentType = 'claude_interactive_session'
version = ''
capabilities = (@{ sessionUrl = '<์ธ์
URL, ์ ํ์ฌํญ>' } | ConvertTo-Json -Compress)
} | ConvertTo-Json -Compress)
}
Invoke-WebRequest -Uri 'https://giipfaw.azurewebsites.net/api/giipApiSk4' -Method Post -Body $body
sessionUrl์ ๋ง๋ค ์ ์์ ๋(capabilities ์๋ต): $env:CLAUDE_CODE_BRIDGE_SESSION_ID๊ฐ ์์ด capabilities๋ฅผ ๊ตฌ์ฑํ ์ ์๋ ๊ฒฝ์ฐ, ์ ์์์์ text์ capabilities ํ ํฐ๊ณผ jsondata์ capabilities ํ๋๋ง ๋นผ๊ณ ๋๋จธ์ง 11๊ฐ ํ๋๋ ๊ทธ๋๋ก ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. sessionUrl ์์ด๋ ๋ฑ๋ก ์์ฒด๋ ์์ ํ ์ ์์ ์ผ๋ก ์ฑ๊ณตํฉ๋๋ค โ ๋ค๋ง "Open Interactive Sessions" ์นด๋์ "Open session" ๋งํฌ๋ง ๋ํ๋์ง ์์ ๋ฟ์
๋๋ค(์๋ "๋ฌธ์ ํด๊ฒฐ" ์ ์ฐธ๊ณ ).
$body = @{
text = 'SchedulerAgentUpsert agentKey displayName hostIdentifier windowsTaskName projectName scheduleDesc isActive lssn osType agentType version'
token = '<YOUR_SECRET_KEY>'
jsondata = (@{
agentKey = 'claude_interactive_<YOUR_HOST>_<UNIQUE_ID>'
displayName = 'Claude Interactive Session (<YOUR_HOST>)'
hostIdentifier = '<YOUR_HOST>'
windowsTaskName = ''
projectName = ''
scheduleDesc = ''
isActive = '1'
lssn = '0'
osType = 'Windows'
agentType = 'claude_interactive_session'
version = ''
} | ConvertTo-Json -Compress)
}
Invoke-WebRequest -Uri 'https://giipfaw.azurewebsites.net/api/giipApiSk4' -Method Post -Body $body
๋ค๋ฅธ ํธ์คํธ์์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌํํ๋ ค๋ฉด ๋ค์ ๋ ๊ฐ์ง๊ฐ ๊ทธ๋๋ก ํ์ํฉ๋๋ค(๋ ๋ค ๊ณ ์ ์๊ตฌ์ฌํญ์ด๋ฉฐ ์ฌ๋์ ์ฌ์ง๊ฐ ์์ต๋๋ค): (a) ํด๋น ํธ์คํธ์ ์ธ์
์คํ ๋๊ตฌ์๋ ์์ ๋์ผํ hooks.SessionStart/hooks.SessionEnd ๊ตฌ์ฑ, (b) ๋ฑ๋กํ๋ ค๋ CSN์ ๋ํด ์ ํจํ SK.
SK๋ฅผ ์ด๋์ ๋ณด๊ดํ ์ง๋(์ด ์ ์ฐจ์ ๋ฌด๊ดํ) ์์ ๋ณด์ ์ฌ๋ ์ฌํญ์
๋๋ค โ ์ฐธ๊ณ ๋ก ์ด ์ด์์์ ๊ฐ์ธ ํ๊ฒฝ(lowyworkenv ์ ์ฅ์)์์๋ ์ด SK๋ฅผ slack-bot/.secrets/giip-accounts.json์ด๋ผ๋ JSON ํ์ผ(Slack ์ฑ๋ID โ {login_id, sk, csn} ๋งคํ ๊ตฌ์กฐ)๋ก ๋ณด๊ดํ์ง๋ง, ์ด๋ ์ฐธ๊ณ ์ฉ ์์ ๊ตฌ์กฐ์ผ ๋ฟ์
๋๋ค โ ์ด ํน์ ํ์ผ ๊ฒฝ๋ก๋ฅผ ๊ทธ๋๋ก ๋ฐ๋ผ ํ๋ผ๋ ๋ป์ด ์๋๋ฉฐ, ๋ค๋ฅธ ํธ์คํธ/์ด์์๋ ๊ฐ์ ์์ ํ ๋ฐฉ์(OS ์๊ฒฉ ์ฆ๋ช
์ ์ฅ์, ์ํฌ๋ฆฟ ๋งค๋์ , ํ๊ฒฝ๋ณ์ ๋ฑ)์ผ๋ก SK๋ฅผ ๋ณด๊ดํ๋ฉด ๋ฉ๋๋ค.
์ฑ๊ณต ํ์ธ: ํ๋ฉด ์๋ก๊ณ ์นจ ์ "Open Interactive Sessions" ์นด๋์ ์ธ์ ์ด ๋ํ๋ฉ๋๋ค.
๋ฐฉ๋ฒ B โ ์ค์ผ์ค๋ฌ ์์ด์ ํธ(์๋ํ ์คํ๊ธฐ) ๋ฑ๋ก
gissue ์ค์ผ์ค๋ฌ ๊ฐ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋ํ ์คํ๊ธฐ๋ฅผ ๋ฑ๋กํ๋ ์ ์ฐจ๋ ๋ฐฉ๋ฒ A์ ๊ฐ์ SP ๊ณ์ด์ ์ฐ๋, 1ํ์ฑ์ด ์๋๋ผ ์ฃผ๊ธฐ์ ์ผ๋ก(heartbeat) ์์ ์ identity์ ์คํ ์ํ๋ฅผ ๊ฐฑ์ ํฉ๋๋ค.
ํ์ค ๊ตฌํ์ giip-fde-agent ์ ๋๋ค. ์ฒ์๋ถํฐ ์ง์ง ๋ง๊ณ ์ 'AI ์๊ฒ ๋งก๊ฒจ gissue ์ค์ผ์ค๋ฌ ๋ง๋ค๊ธฐ' ์ ์ฐจ๋ฅผ ๋ฐ๋ฅด์ญ์์ค. ์๋ SP ๊ท๊ฒฉ์ ๋ฌ๋๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ฐ๋ ํธ์ถ์ด๋ฉฐ, ์ง์ ๊ตฌํํด์ผ ํ ๋๋ง ์ฐธ๊ณ ํ์ญ์์ค.
- ์ฌ์ ์กฐ๊ฑด: ์ ๊ณตํต ์ฌ์ ์กฐ๊ฑด(๋์ CSN์ฉ SK).
- ์ต์ด ๋ฑ๋ก/์ฃผ๊ธฐ์ identity ๊ฐฑ์ :
SchedulerAgentUpsert(๋ฐฉ๋ฒ A์ ๋์ผ ํ๋ โagentKey/displayName/hostIdentifier/osType/agentType/version/capabilities๋ฑ)๋ฅผ ํ๋ก์ธ์ค ์์ ์ 1ํ ํธ์ถํ๊ณ , ๊ทธ ๋ค๋ก๋ ์ต๋ 5๋ถ ๊ฐ๊ฒฉ(๊ถ์ฅ: 2๋ถ ๊ฐ๊ฒฉ)์ผ๋ก ๋ฐ๋ณต ํธ์ถํฉ๋๋ค. - ์คํ(run) ์์:
SchedulerAgentRunStart(runIdKey,agentKey,executionMode=scheduled,totalIssueCount). - ์คํ ๋์ค ์งํ ์ํฉ ๊ฐฑ์ (heartbeat):
SchedulerAgentHeartbeatPutโrunIdKey,agentKey,processedCount,skippedCount,failedCount,currentPhase,currentIssueNum,totalIssueCount. ์ฒ๋ฆฌ ๋จ์(์: ์ด์ 1๊ฑด ์ฒ๋ฆฌ ์๋ฃ)๋ง๋ค ํธ์ถํ๊ณ , ์ฒ๋ฆฌํ ํญ๋ชฉ์ด ์์ด ์ ํด ์ํ์ด๋๋ผ๋ ์ต๋ 2๋ถ ๊ฐ๊ฒฉ์ผ๋ก ํธ์ถํ์ญ์์ค โ 5๋ถ ์ด์ heartbeat๊ฐ ๋๊ธฐ๋ฉด ํ๋ฉด์ STALE๋ก ํ์๋ฉ๋๋ค. - ์คํ ์ข
๋ฃ:
SchedulerAgentRunEnd(runIdKey,agentKey,status,processedCount,skippedCount,failedCount,exitCode,summary).status๊ฐ์SUCCEEDED/TIMED_OUT/FAILED,exitCode๋ ์ซ์ ๋ฌธ์์ด('0'๋๋'1').
| SP ์ด๋ฆ | ์ธ์ฆ | ์ฉ๋ |
|---|---|---|
SchedulerAgentUpsert | SK | identity ๋ฑ๋ก/๊ฐฑ์ |
SchedulerAgentRunStart | SK | ์คํ ์์ ๊ธฐ๋ก |
SchedulerAgentHeartbeatPut | SK | ์คํ ์ค ์งํ๋ฅ /heartbeat ๊ฐฑ์ |
SchedulerAgentRunEnd | SK | ์คํ ์ข ๋ฃ ๊ธฐ๋ก |
SchedulerAgentList | AK(๋ก๊ทธ์ธ ์ธ์ ) | ์ด ํ๋ฉด์ด ๋ชฉ๋ก์ ์กฐํํ ๋ ์ฌ์ฉ โ ๋ฑ๋ก์๋ ํ์ ์์ |
์์น ์ธ์ ์์(๋ฐฉ์ 1 ๊ธฐ์ค):
- Upsert ์ธ์ ์์:
agentKey,displayName,hostIdentifier,windowsTaskName,projectName,scheduleDesc,isActive - RunStart ์ธ์ ์์:
runIdKey,agentKey,executionMode,totalIssueCount - HeartbeatPut ์ธ์ ์์:
runIdKey,agentKey,processedCount,skippedCount,failedCount,currentPhase,currentIssueNum
ํธ์ถ ๊ท์ฝ์ ๋ ๊ฐ์ง ๋ฐฉ์์ด ๋ชจ๋ ์ ํจํฉ๋๋ค. ๋ฐฉ์ 1(๋ฌ๋ ๋ด๋ถ): giipApiSk2์ token=SK, text="SP์ด๋ฆ '๊ฐ1' '๊ฐ2' ..."(SP ํ๋ผ๋ฏธํฐ ์ ์ธ ์์์ ์์น ์ธ์, ๊ฐ์ ์์๋ฐ์ดํ ๋ฆฌํฐ๋ด), jsondata๋ ๋น ๊ฐ. ๋ฐฉ์ 2(์ง์ ๊ตฌํ ์, ๋ฐฉ๋ฒ A ์ ๊ฐ์ ํ์): giipApiSk4์ token=SK, text์ ํ๋๋ช
์ ๊ณต๋ฐฑ ๋์ด, jsondata์ {"ํ๋๋ช
":"๊ฐ",...} JSON.
์ฐธ๊ณ : ์ด ์ ์ฅ์๊ฐ ๊ด๋ฆฌํ๋ giipAgentWin/giipAgentLinux(์๋ฒ ์ธํ๋ผ ์์ด์ ํธ)๋ ์ด
tSchedulerAgent์ฒด๊ณ์๋ ๋ณ๊ฐ์ ๋ฑ๋ก ๋ฉ์ปค๋์ฆ(x-api-key ๊ธฐ๋ฐagent-register/agent-heartbeatAPI)์ ์ฌ์ฉํ๋ฉฐ, ์ด ํ๋ฉด๊ณผ๋ ๋ฌด๊ดํฉ๋๋ค. ์ด ํ๋ฉด(admin/catquest/schedulers)์ ๋ฑ๋กํ๋ ค๋ฉด ์ SP ๊ณ์ด์ ํธ์ถํ๋ ๊ตฌํ์ด ํ์ํ๋ฉฐ, gissue ๋งค์๊ฐ ์ค์ผ์ค๋ฌ์ ํ์ค ๊ตฌํ์ giip-fde-agent ์run-gissue-claude.ps1์ ๋๋ค.
์ฑ๊ณต ํ์ธ: ๋ค์ heartbeat/์๋ก๊ณ ์นจ ํ ์์ด์ ํธ ๋ชฉ๋ก ํ์ ๋ํ๋ฉ๋๋ค.
๐ก ์ ์ ์ฌํญ
- ์ด ํ๋ฉด์ ๊ด๋ฆฌ์ ์ ์ฉ์
๋๋ค.
AdminGuard(uLevel โฅ 70) ์ ๊ทผ ๊ถํ์ด ํ์ํฉ๋๋ค. - ์์ด์ ํธ ๋ชฉ๋ก, ์คํ์ด๋ ฅ, ๋ก๊ทธ ์นดํ๋ก๊ทธ๋ ๋ชจ๋ ์ธ์ ์ ํ์ฌ CSN์ ๊ธฐ์ค์ผ๋ก ์กฐํ๋ฉ๋๋ค โ ๋ค๋ฅธ ํ๋ก์ ํธ์ ์์ด์ ํธ๋ฅผ ํ์ธํ๋ ค๋ฉด ์๋จ ๋ด๋น๊ฒ์ด์ ์์ ํ๋ก์ ํธ๋ฅผ ์ ํํ์ธ์.
- ๋ฐ์ดํฐ ์กฐํ์๋ ์ธ์ฆ๋ ์ธ์ (AK ํ ํฐ)์ด ํ์ํฉ๋๋ค. ์์ฒญ์ด ์ธ์ฆ ์ค๋ฅ๋ก ์คํจํ๊ธฐ ์์ํ๋ฉด ๋ค์ ๋ก๊ทธ์ธ ํ Refresh๋ฅผ ๋๋ฅด์ธ์.
- ์ด ํ์ด์ง๋
/admin/catquest์๋ ๋ณ๊ฐ์ ๋๊ตฌ์ ๋๋ค โ CatQuest ํ๋ฉด์ ๋ด๋น๊ฒ์ด์ ์ ํตํด ์ง์ ํ๋ค๊ณ ํด์ CatQuest์ ๊ณ ์์ด ์๊ฐํ ๋ฐ์ดํฐ๋ ๋์ ์ฌ์ฉ์๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ ์๋๋๋ค.
๋ฌธ์ ํด๊ฒฐ
| ์ฆ์ | ์์ธ | ํด๊ฒฐ |
|---|---|---|
| ๋ํํ ์ธ์ ์ ๋ฑ๋ก์ ์ง์ํ๋๋ฐ "Open Interactive Sessions"์ ์ ํ ์ ๋ํ๋จ | ์ ์ญ ํ
์ ํค๋๋ฆฌ์ค ํ์ ๋ก์ง์ด $env:CLAUDE_CODE_BRIDGE_SESSION_ID ์ ๋ฌด๋ง์ผ๋ก ํ๋จํด, ๋ธ๋ฆฟ์ง ๋ฏธ์ฐ๊ฒฐ ๋ํํ ์ธ์
๊น์ง ํค๋๋ฆฌ์ค๋ก ์ค์ธํด ๋ฑ๋ก ์์ฒด๋ฅผ ์คํตํ์ ๊ฐ๋ฅ์ฑ์ด ๊ฐ์ฅ ํผ(giip #1837) | ์ "์ ์ญ ํ ์ผ๋ก ๋ฑ๋กํ ๊ฒฝ์ฐ ํค๋๋ฆฌ์ค ์คํ์ ์ฃผ์" ๋ฐ์ค์ ํ๋ก์ธ์ค ์ปค๋งจ๋๋ผ์ธ ๊ฒ์ฌ ๋ฐฉ์์ผ๋ก ํ์ ๋ก์ง์ ๊ต์ฒดํ์ญ์์ค. |
| "Authentication required" ์ค๋ฅ | AK/์ธ์ ํ ํฐ์ ์ฐพ์ ์ ์์ | ๋ค์ ๋ก๊ทธ์ธํ ๋ค ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ์ธ์. |
| ์์ด์ ํธ ๋ชฉ๋ก์ด ๋น์ด ์์ | ์ด CSN์ ๋ฑ๋ก๋ ์ค์ผ์ค๋ฌ ์์ด์ ํธ๊ฐ ์๊ฑฐ๋, ํ๋ก์ ํธ๊ฐ ์๋ชป ์ ํ๋จ | ์๋จ ๋ด๋น๊ฒ์ด์ ์์ ์ฌ๋ฐ๋ฅธ ํ๋ก์ ํธ(CSN)๊ฐ ์ ํ๋ผ ์๋์ง ํ์ธํ์ธ์. |
| ์์ ์ด ์ ํด ์ํ์ธ ๊ฑธ ์๋๋ฐ๋ ํ์ด ๋นจ๊ฐ์ STALE๋ก ํ์๋จ | ์์ด์ ํธ๊ฐ ENDED๋ก ์ ์ด๋์ง ์์ ์ฑ ์คํ ๋์ค heartbeat ์ ์ก์ด ๋ฉ์ถค(isStale = true) โ ํ๋ก์ธ์ค๊ฐ ํฌ๋์ํ๊ฑฐ๋ ๊ฐ์ ์ข
๋ฃ๋์ ๊ฐ๋ฅ์ฑ | ์์ด์ ํธ ํธ์คํธ๋ฅผ ์ง์ ํ์ธํ์ธ์. ์ฌ์์ ํ ๋ค์ ๋ณด๊ณ ๋ฅผ ์์ํ๋ฉด ๋ฐฐ์ง๊ฐ ๊ฐฑ์ ๋ฉ๋๋ค. |
| Live Log Viewer์ "No streams yet."์ด ํ์๋จ | ์์ด์ ํธ๊ฐ ์์ง ๋ก๊ทธ ์คํธ๋ฆผ์ ๋ฑ๋กํ์ง ์์๊ฑฐ๋, ์นดํ๋ก๊ทธ๊ฐ ๋ง์ง๋ง์ผ๋ก ๊ฐฑ์ ๋ ์ดํ ์ถ๋ ฅ์ด ์์ | ์์ด์ ํธ์ ๋ค์ ์คํ์ ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋, ์์ด์ ํธ ํ๋ก์ธ์ค๊ฐ ์ค์ ๋ก ๋ก๊ทธ๋ฅผ ์ฐ๊ณ ์๋์ง ํ์ธํ์ธ์. |
| Open Interactive Sessions์ "Open session" ๋งํฌ๊ฐ ์์ | ํด๋น ์์ด์ ํธ์ ๋ฑ๋ก๋ capabilities์ sessionUrl์ด ํฌํจ๋ผ ์์ง ์์ | ์ด ์ ์๋ ํญ๋ชฉ์ด ์์ต๋๋ค โ ํด๋น ๋ํํ ์ธ์ ์ด ์ ๊ทผ ๊ฐ๋ฅํ URL์ ๋ฑ๋กํ์ง ์์์ต๋๋ค. |
๋ฒ์ : 1.1
์ต์ข
์
๋ฐ์ดํธ: 2026-09-01
์์ค ํ์ผ: giipv3/public/help/catquest-schedulers.ko.md