์๋ฆฌ์ฆ: oh-my-claudecode ๋ด๋ถ ๊ตฌ์กฐ๋ถํฐ ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ๊น์ง
์ด ์๋ฆฌ์ฆ๋ Claude Code ํ๋ฌ๊ทธ์ธ ์์คํ ์ ๋ด๋ถ ๋์์ ๋จ๊ณ๋ณ๋ก ํด๋ถํ๊ณ , ์ต์ข ์ ์ผ๋ก ๋๋ง์ ํ๋ฌ๊ทธ์ธ์ ์ง์ ๊ฐ๋ฐํ๋ ๊ฒ๊น์ง ๋๋ฌํ๋ ๊ณผ์ ์ด๋ค.
| ํธ | ๋ด์ฉ | ํต์ฌ |
|---|---|---|
| 1ํธ | Plugin Anatomy | plugin.json ํ๋๋ก ์์ํ๋ ํ๋ฌ๊ทธ์ธ ๋ผ๋ |
| 2ํธ (๋ณธ๋ฌธ) | Hook System | ์ด๋ฒคํธ โ stdin JSON โ ์คํฌ๋ฆฝํธ โ stdout JSON |
| 3ํธ | Skill System | SKILL.md๋ก ์ํฌํ๋ก์ฐ๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ |
| 4ํธ | Agent System | Task tool๋ก ์์๋๋ ์ค์ ์์ ์ํ์ |
| 5ํธ | MCP Tools Bridge | LSP, AST ๋ฑ ์ปค์คํ ๋๊ตฌ ์๋ฒ |
| 6ํธ | State & Lifecycle | .omc/ ์ํ ๊ด๋ฆฌ์ ๋ชจ๋ ์ง์ |
| 7ํธ | Parallel Orchestration | Ultrawork, Team, Autopilot, Ralph ํจํด |
- Claude Code Hook System์ Claude Code๊ฐ ๋ด๋ถ ์ด๋ฒคํธ ๋ฐ์ ์ ์ธ๋ถ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ ํ๋์ ๊ฐ๋ก์ฑ๊ฑฐ๋ ์กฐ์ํ ์ ์๊ฒ ํ๋ ๊ณต์ ์ธํฐํ์ด์ค
- Claude Code๊ฐ 21๊ฐ์ง ์ด๋ฒคํธ + stdin/stdout JSON ๊ณ์ฝ์ ์ ์ํ๊ณ , ํ๋ฌ๊ทธ์ธ์ด ๊ทธ์ ๋ง๋ ์คํฌ๋ฆฝํธ๋ฅผ ๊ฐ๋ฐํ์ฌ ๋ฑ๋กํ๋ 2-๋ ์ด์ด ๊ตฌ์กฐ
- ํต์ฌ ๊ณ์ฝ: stdin JSON in โ stdout JSON out
์์ฑ์ผ: 2026-03-14 Claude Code ๊ณต์ ๋ฌธ์: https://code.claude.com/docs/en/hooks (21๊ฐ ์ด๋ฒคํธ) OMC ์์ค ๋ฒ์ :
hooks/hooks.json๊ธฐ์ค (11๊ฐ ์ด๋ฒคํธ, 18๊ฐ ์คํฌ๋ฆฝํธ ๋ฑ๋ก)
ํด๋น ๊ฐ๋ ์ด ํ์ํ ์ด์
- Claude Code๋ ๊ธฐ๋ณธ ๋๊ตฌ(Read, Write, Edit, Bash ๋ฑ)๋ง ์ ๊ณตํ๋ฉฐ, ์ฌ์ฉ์์ ์ ๋ ฅ์ ๊ฐ๋ก์ฑ๊ฑฐ๋ ์ข ๋ฃ๋ฅผ ์ฐจ๋จํ๋ ๊ธฐ๋ฅ์ด ์๋ค
- ํ๋ฌ๊ทธ์ธ์ด Claude Code์ ๋์์ ๊ฐ์ ํ๋ ค๋ฉด, Claude Code๊ฐ ์ ๊ณตํ๋ ๊ณต์ ์ด๋ฒคํธ ํ ํฌ์ธํธ๋ฅผ ํตํด์ผ ํ๋ค
- OMC ๊ฐ์ ํ๋ฌ๊ทธ์ธ์ ์ด Hook ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํ์ฌ ํค์๋ ๊ฐ์ง, ๋ชจ๋ ์ง์, ์๋ฌ ๋ณต๊ตฌ ๋ฑ์ ๊ตฌํํ๋ค
AS-IS
sequenceDiagram autonumber participant U as User participant CC as Claude Code U->>CC: "ultrawork refactor the API" CC->>CC: ๊ธฐ๋ณธ ๋๊ตฌ๋ก ์ฒ๋ฆฌ CC-->>U: ์๋ต ์๋ฃ (์ข ๋ฃ) Note over CC: ํค์๋ ๊ฐ์ง ๋ถ๊ฐ, ์ข ๋ฃ ์ฐจ๋จ ๋ถ๊ฐ, ๋ชจ๋ ๊ฐ๋ ์์
TO-BE
sequenceDiagram autonumber participant U as User participant CC as Claude Code box OMC participant HK as Hook Script end U->>CC: "ultrawork refactor the API" CC->>HK: UserPromptSubmit ์ด๋ฒคํธ (stdin JSON) HK->>HK: "ultrawork" ํค์๋ ๊ฐ์ง HK-->>CC: stdout: { additionalContext: "SKILL ํธ์ถ ์ง์" } CC->>CC: Skill ๋ก๋ โ Agent ์์ โ ๋ณ๋ ฌ ์คํ CC->>HK: Stop ์ด๋ฒคํธ (์ข ๋ฃ ์๋) HK-->>CC: { continue: false, decision: "block" } (์์ง ์์ ์ค) Note over CC: ์์ ์๋ฃ๊น์ง ์ข ๋ฃํ์ง ์์
Hook ์์คํ ์ 2-๋ ์ด์ด ๊ตฌ์กฐ
graph TB subgraph Layer2["Layer 2: ํ๋ฌ๊ทธ์ธ"] Scripts["์ด๋ฒคํธ์ ๋ฐ์ํ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ"] Register["hooks.json์ ์ด๋ฒคํธ๋ณ ์คํฌ๋ฆฝํธ ๋ฑ๋ก"] Logic["๋น์ฆ๋์ค ๋ก์ง ๊ตฌํ"] end subgraph Layer1["Layer 1: Claude Code"] Events["21๊ฐ์ง Hook ์ด๋ฒคํธ ์ ์"] Contract["stdin/stdout JSON ๊ณ์ฝ"] HooksJson["hooks.json ๋ก๋ฉ & ์คํฌ๋ฆฝํธ ์คํ"] end Logic ~~~ Events Events --> HooksJson Contract --> HooksJson HooksJson -->|"command ์คํ, stdin ์ ๋ฌ"| Scripts Scripts -->|"stdout JSON ๋ฐํ"| HooksJson Register -.->|"๋ฑ๋ก"| HooksJson
Claude Code๊ฐ โ21๊ฐ์ ์ฝ์ผํธ(์ด๋ฒคํธ)โ๋ฅผ ์ ๊ณตํ๊ณ , ํ๋ฌ๊ทธ์ธ์ ๊ฑฐ๊ธฐ์ ์ํ๋ โ๊ฐ์ ์ ํ(์คํฌ๋ฆฝํธ)โ์ ๊ฝ๋ ๊ตฌ์กฐ. ์ฝ์ผํธ ์์ฒด๋ฅผ ์ถ๊ฐํ ์ ์์ง๋ง, ๊ฝ๋ ๊ฑด ์์ ๋ค.
ํต์ ํ๋กํ ์ฝ ์์ธ
Hook์ ์๋ ํ๋ฆ
sequenceDiagram autonumber participant CC as Claude Code participant HJ as hooks.json participant SC as Hook Script (.mjs) CC->>CC: ๋ด๋ถ ์ด๋ฒคํธ ๋ฐ์ (์: UserPromptSubmit) CC->>HJ: ํด๋น ์ด๋ฒคํธ์ hook ๋ชฉ๋ก ์กฐํ CC->>SC: command ์คํ, stdin์ผ๋ก ์ด๋ฒคํธ JSON ์ ๋ฌ SC->>SC: ์ฒ๋ฆฌ (ํค์๋ ๊ฐ์ง, ์ํ ํ์ธ ๋ฑ) SC-->>CC: stdout์ผ๋ก ์๋ต JSON ๋ฐํ CC->>CC: ์๋ต ํด์ํ์ฌ ํ๋ ๊ฒฐ์
๊ณตํต stdin ์ ๋ ฅ (๋ชจ๋ ์ด๋ฒคํธ)
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/working/directory",
"permission_mode": "default|plan|acceptEdits|dontAsk|bypassPermissions",
"hook_event_name": "EventName",
"agent_id": "optional-subagent-id",
"agent_type": "optional-agent-name"
}์ด๋ฒคํธ๋ณ๋ก tool_name, tool_input, user_prompt, reason ๋ฑ ์ถ๊ฐ ํ๋๊ฐ ํฌํจ๋๋ค.
๊ณตํต stdout ์ถ๋ ฅ (๋ชจ๋ Hook)
{
"continue": true,
"stopReason": "message",
"suppressOutput": false,
"systemMessage": "warning"
}| ํ๋ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
continue | true | false๋ฉด Claude๊ฐ ์ฒ๋ฆฌ ์์ ์ค๋จ. ๋ชจ๋ decision๋ณด๋ค ์ฐ์ |
stopReason | ์์ | continue: false์ผ ๋ ์ฌ์ฉ์์๊ฒ ํ์ (Claude์๊ฒ ์ ๋ณด์) |
suppressOutput | false | true๋ฉด verbose ๋ชจ๋ ์ถ๋ ฅ์์ ์จ๊น |
systemMessage | ์์ | ์ฌ์ฉ์์๊ฒ ํ์ํ ๊ฒฝ๊ณ ๋ฉ์์ง |
์ด๋ฒคํธ๋ณ hookSpecificOutput
// UserPromptSubmit, SessionStart, SubagentStart, PostToolUseFailure ๋ฑ
{
hookSpecificOutput: {
hookEventName: "UserPromptSubmit",
additionalContext: "Claude context์ ์ฃผ์
ํ ํ
์คํธ"
}
}
// PreToolUse โ ๋๊ตฌ ์คํ ํ์ฉ/์ฐจ๋จ/์์
{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "allow" | "deny" | "ask",
permissionDecisionReason: "์ฌ์ ",
updatedInput: { field: "์์ ๋ ๊ฐ" },
additionalContext: "Claude์๊ฒ ์ถ๊ฐ ์ปจํ
์คํธ"
}
}
// Stop, SubagentStop โ ์ข
๋ฃ ์ฐจ๋จ
{
continue: false, // ํต์ฌ ํ๋: false๋ฉด ์ข
๋ฃ ์ฐจ๋จ
decision: "block", // ๋ณด์กฐ ํ๋
reason: "์ฐจ๋จ ์ฌ์ "
}
// ์ข
๋ฃ ํ์ฉ ์
{
continue: true,
suppressOutput: true
}
// PermissionRequest โ ๊ถํ ์๋ ์น์ธ/๊ฑฐ๋ถ
{
hookSpecificOutput: {
hookEventName: "PermissionRequest",
decision: {
behavior: "allow" | "deny",
message: "deny ์ฌ์ "
}
}
}Exit Code ๋์
| Exit Code | ๋์ |
|---|---|
| 0 | ์ฑ๊ณต, stdout์์ JSON ํ์ฑ |
| 2 | ๋ธ๋กํน ์๋ฌ, stderr๊ฐ Claude์๊ฒ ์ ๋ฌ, JSON ๋ฌด์ |
| ๊ธฐํ | ๋น๋ธ๋กํน ์๋ฌ, ์คํ ๊ณ์ ์งํ |
continue, additionalContext, hookEventName์ ๋ชจ๋ ๊ณต์ ํ๋
์ด ํ๋๋ค์ OMC๊ฐ ์์ฒด ์ ์ํ ๊ฒ์ด ์๋๋ผ Claude Code ๊ณต์ ์ธํฐํ์ด์ค์ ์ผ๋ถ์ด๋ค. ๊ณต์ ๋ฌธ์(https://code.claude.com/docs/en/hooks)์ ๋ชจ๋ ํ๋๊ฐ ๋ช ์๋์ด ์์ผ๋ฉฐ, OMC๋ฅผ ํฌํจํ ๋ชจ๋ ํ๋ฌ๊ทธ์ธ์ด ์ด ๊ณ์ฝ์ ๋ง์ถฐ ์คํฌ๋ฆฝํธ๋ฅผ ๊ฐ๋ฐํ๋ค.
Claude Code ๊ณต์ Hook ์ด๋ฒคํธ (21๊ฐ์ง)
| # | ์ด๋ฒคํธ | ๋ฐ์ ์์ | OMC ์ฌ์ฉ |
|---|---|---|---|
| 1 | SessionStart | ์ธ์ ์์/์ฌ๊ฐ ์ | โ |
| 2 | UserPromptSubmit | ์ฌ์ฉ์ ํ๋กฌํํธ ์ ์ถ ์ | โ |
| 3 | PreToolUse | ๋๊ตฌ ์คํ ์ | โ |
| 4 | PermissionRequest | ๊ถํ ๋ค์ด์ผ๋ก๊ทธ ํ์ ์ | โ |
| 5 | PostToolUse | ๋๊ตฌ ์ฑ๊ณต ํ | โ |
| 6 | PostToolUseFailure | ๋๊ตฌ ์คํจ ํ | โ |
| 7 | Notification | Claude Code ์๋ฆผ ๋ฐ์ก ์ | |
| 8 | SubagentStart | ์๋ธ์์ด์ ํธ ์์ฑ ์ | โ |
| 9 | SubagentStop | ์๋ธ์์ด์ ํธ ์ข ๋ฃ ์ | โ |
| 10 | Stop | Claude ์๋ต ์ข ๋ฃ ์ | โ |
| 11 | TeammateIdle | ํ ์์ด์ ํธ๊ฐ idle ์ํ ์ ํ ์ | |
| 12 | TaskCompleted | ํ์คํฌ ์๋ฃ ํ์ ์ | |
| 13 | InstructionsLoaded | CLAUDE.md/rules ๋ก๋ ์ | |
| 14 | ConfigChange | ์ค์ ํ์ผ ๋ณ๊ฒฝ ์ | |
| 15 | WorktreeCreate | worktree ์์ฑ ์ | |
| 16 | WorktreeRemove | worktree ์ ๊ฑฐ ์ | |
| 17 | PreCompact | ์ปจํ ์คํธ ์์ถ ์ | โ |
| 18 | PostCompact | ์ปจํ ์คํธ ์์ถ ํ | |
| 19 | Elicitation | MCP ์๋ฒ๊ฐ ์ฌ์ฉ์ ์ ๋ ฅ ์์ฒญ ์ | |
| 20 | ElicitationResult | MCP elicitation ์๋ต ํ | |
| 21 | SessionEnd | ์ธ์ ์ข ๋ฃ ์ | โ |
OMC๋ ์ด ์ค 11๊ฐ ์ด๋ฒคํธ์ ์ปค์คํ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฑ๋กํ์ฌ ์ฌ์ฉํ๋ค.
hooks.json ๊ตฌ์กฐ
{
"hooks": {
"์ด๋ฒคํธ์ด๋ฆ": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs ...",
"timeout": 5
}
]
}
]
}
}- ํ ์ด๋ฒคํธ์ ์ฌ๋ฌ matcher ๋ฑ๋ก ๊ฐ๋ฅ (๋ฐฐ์ด)
- ํ matcher์ ์ฌ๋ฌ hook ๋ฑ๋ก ๊ฐ๋ฅ (์์ฐจ ์คํ)
matcher: "*"๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์คํ,"Bash"๋ Bash ๋๊ตฌ์๋ง ์คํtimeout์ด๊ณผ ์ hook์ด ๋ฌด์๋๊ณ Claude Code๊ฐ ์ ์ ์งํ
OMC hooks.json ์ด๋ฒคํธ๋ณ ๋ฑ๋ก ํํฉ (18๊ฐ ์คํฌ๋ฆฝํธ)
| # | ์ด๋ฒคํธ | matcher | ์คํฌ๋ฆฝํธ | timeout | ์ญํ |
|---|---|---|---|---|---|
| 1 | UserPromptSubmit | * | keyword-detector.mjs | 5s | ๋งค์ง ํค์๋ ๊ฐ์ง โ ์คํฌ ์ฃผ์ |
* | skill-injector.mjs | 3s | ํ์ต๋ ์คํฌ ๋งค์นญ โ context ์ฃผ์ | ||
| 2 | SessionStart | * | session-start.mjs | 5s | ์ด๊ธฐ ์ค์ , HUD ์ด๊ธฐํ |
* | project-memory-session.mjs | 5s | ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ๋ก๋ | ||
init | setup-init.mjs | 30s | ์ต์ด ์ด๊ธฐํ (๋๋ ํ ๋ฆฌ ์์ฑ ๋ฑ) | ||
maintenance | setup-maintenance.mjs | 60s | ์ ์ง๋ณด์ (์ํ ํ์ผ ์ ๋ฆฌ ๋ฑ) | ||
| 3 | PreToolUse | * | pre-tool-enforcer.mjs | 3s | ํ ๋ผ์ฐํ , ์ปจํ ์คํธ ์์ง ๊ฐ์ง |
| 4 | PermissionRequest | Bash | permission-handler.mjs | 5s | Bash ๋ช ๋ น๋ง ์๋ ์น์ธ ํ๋จ |
| 5 | PostToolUse | * | post-tool-verifier.mjs | 3s | ์๋ฌ ๋ณต๊ตฌ, ์ปจํ ์คํธ ์ฃผ์ |
* | project-memory-posttool.mjs | 3s | ๋๊ตฌ ๊ฒฐ๊ณผ์์ ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ํ์ต | ||
| 6 | PostToolUseFailure | * | post-tool-use-failure.mjs | 3s | ์คํจ ์๋ฌ ๋ณต๊ตฌ ๊ฐ์ด๋ |
| 7 | SubagentStart | * | subagent-tracker.mjs start | 3s | ์๋ธ์์ด์ ํธ ์์ ์ถ์ |
| 8 | SubagentStop | * | subagent-tracker.mjs stop | 5s | ์๋ธ์์ด์ ํธ ์ข ๋ฃ ์ถ์ |
* | verify-deliverables.mjs | 5s | ์๋ธ์์ด์ ํธ ๊ฒฐ๊ณผ๋ฌผ ๊ฒ์ฆ | ||
| 9 | PreCompact | * | pre-compact.mjs | 10s | ์์ถ ์ ํต์ฌ ์ ๋ณด ๋ณด์กด |
* | project-memory-precompact.mjs | 5s | ํ๋ก์ ํธ ๋ฉ๋ชจ๋ฆฌ ๋ณด์กด | ||
| 10 | Stop | * | context-guard-stop.mjs | 5s | ์ปจํ ์คํธ ๊ฐ๋ |
* | persistent-mode.cjs | 10s | ๋ชจ๋ ์ง์ โ ์ข ๋ฃ ์ฐจ๋จ | ||
* | code-simplifier.mjs | 5s | ์ฝ๋ ๊ฐ์ํ ์ฒดํฌ | ||
| 11 | SessionEnd | * | session-end.mjs | 10s | ๋ฉํธ๋ฆญ ๊ธฐ๋ก, ์ํ ์ ๋ฆฌ |
hooks.json์์ ์ฝ๋ ์ค๊ณ ํจํด
์์ฐจ ์คํ โ ๊ฐ์ matcher ์์ hooks ๋ฐฐ์ด
๊ฐ์ matcher์ hooks ๋ฐฐ์ด์ ์์ฐจ ์คํ๋๋ค.
UserPromptSubmit: keyword-detector.mjs (5s) โ skill-injector.mjs (3s)
ํค์๋๋ฅผ ๋จผ์ ๊ฐ์งํ ๋ค, ํ์ต๋ ์คํฌ์ ๋งค์นญํ๋ ์์.
matcher๋ก ์กฐ๊ฑด ๋ถ๊ธฐ โ SessionStart
SessionStart๋ง ์ ์ผํ๊ฒ 3๊ฐ์ matcher๋ฅผ ์ฌ์ฉํ๋ค:
*โ ํญ์ ์คํ (์ธ์ ์์, ๋ฉ๋ชจ๋ฆฌ ๋ก๋)initโ ์ด๊ธฐํ ์์๋ง (timeout 30s)maintenanceโ ์ ์ง๋ณด์ ์์๋ง (timeout 60s๋ก ๊ฐ์ฅ ๊ธธ๋ค)
ํน์ ๋๊ตฌ๋ง ๊ฐ์ โ PermissionRequest
๋ค๋ฅธ ์ด๋ฒคํธ๋ ๋ชจ๋ matcher: "*"์ธ๋ฐ, PermissionRequest๋ง matcher: "Bash". Bash ๋ช
๋ น ์คํ ๊ถํ๋ง ์๋ ํ๋จํ๊ณ , Read/Edit ๋ฑ ๋ค๋ฅธ ๋๊ตฌ๋ ๊ด์ฌํ์ง ์๋๋ค.
Stop ์ด๋ฒคํธ๊ฐ ๊ฐ์ฅ ๋ณต์ก โ 3๊ฐ ์คํฌ๋ฆฝํธ ์์ฐจ ์คํ
context-guard-stop.mjs โ persistent-mode.cjs โ code-simplifier.mjs
์ข ๋ฃ ์์ ์ ์ปจํ ์คํธ ์ํ ํ์ธ โ ํ์ฑ ๋ชจ๋๋ฉด ์ข ๋ฃ ์ฐจ๋จ โ ์ฝ๋ ํ์ง ์ฒดํฌ๊น์ง 3๋จ๊ณ.
์คํ ์ฒด์ธ: scripts/run.cjs
graph LR HJ["hooks.json command"] -->|"node run.cjs keyword-detector.mjs"| R["run.cjs"] R -->|"process.execPath๋ก ์คํฐ"| KD["keyword-detector.mjs"] R -->|"์ฌ๋ณผ๋ฆญ ๋งํฌ ํด๊ฒฐ, ์บ์ ๊ฒฝ๋ก ํด๊ฒฐ"| KD KD -->|"stdio: inherit, stdin/stdout ์ ๋ฌ"| R
run.cjs๊ฐ ํ์ํ ์ด์ :
- ํฌ๋ก์ค ํ๋ซํผ ์ง์ (Windows์์ sh ๋์ Node.js ์ฌ์ฉ)
- ํ๋ฌ๊ทธ์ธ ์บ์ ๊ฒฝ๋ก ํด๊ฒฐ (stale
$CLAUDE_PLUGIN_ROOT๋์) - Node ๋ฐ์ด๋๋ฆฌ ๊ฒฝ๋ก ์๋ ํ์ง
Hook ์คํฌ๋ฆฝํธ ํจํด
๋ชจ๋ hook ์คํฌ๋ฆฝํธ๋ ๊ฐ์ ํจํด์ ๋ฐ๋ฅธ๋ค:
// scripts/my-hook.mjs
import { readStdin } from './lib/stdin.mjs';
async function main() {
// 1. stdin์์ JSON ์ฝ๊ธฐ
const input = await readStdin();
const data = JSON.parse(input);
// 2. ์ฒ๋ฆฌ (์ด๋ฒคํธ ๋ฐ์ดํฐ ๋ถ์, ํ๋จ)
const prompt = data.prompt || '';
// 3. stdout์ผ๋ก JSON ์๋ต
if (/* ์กฐ๊ฑด ์ถฉ์กฑ */) {
console.log(JSON.stringify({
continue: true,
hookSpecificOutput: {
hookEventName: 'UserPromptSubmit',
additionalContext: '์ฃผ์
ํ ํ
์คํธ'
}
}));
} else {
console.log(JSON.stringify({ continue: true }));
}
}
main();