$npx -y skills add jmstar85/oh-my-githubcopilot --skill push-omc> "OMG 체크포인트가 없습니다. omg_checkpoint를 먼저 호출해 현재 상태를 저장해주세요."
| 1 | # /push-omc — Export OMG Session into OMC (omg → omc) |
| 2 | |
| 3 | ## Trigger |
| 4 | - Slash command: `/push-omc` |
| 5 | - Keywords: "push omc", "omc 푸시", "omc로 보내기", "sync to omc", "export to omc" |
| 6 | |
| 7 | ## Purpose |
| 8 | Push the local OMG (`oh-my-githubcopilot`) session into OMC (`oh-my-claudecode`) so work done in GitHub Copilot can continue in Claude Code. Counterpart of `/resume-claude`. Together they form the v1.4.3 bidirectional bridge (OMG ↔ OMC). |
| 9 | |
| 10 | ## Workflow |
| 11 | |
| 12 | ### Step 1 — Detect |
| 13 | Call `omg_detect_external_session` and find the entry where `source === "omg"` (the local session). If `has_checkpoint` is `false`, abort: |
| 14 | |
| 15 | > "OMG 체크포인트가 없습니다. `omg_checkpoint`를 먼저 호출해 현재 상태를 저장해주세요." |
| 16 | |
| 17 | ### Step 2 — Compare |
| 18 | Call `omg_compare_checkpoints`. Look at `external[].omg_newer_than_external` to decide whether the push will progress real work or just collide. |
| 19 | |
| 20 | Display: |
| 21 | ``` |
| 22 | 현재 OMG 체크포인트: {timestamp} |
| 23 | OMC 상태: |
| 24 | - 마지막 OMC 체크포인트: {external[omc].timestamp or "없음"} |
| 25 | - OMG가 더 최신: {omg_newer_than_external ? "예" : "아니요"} |
| 26 | ``` |
| 27 | |
| 28 | If OMC is newer (`!omg_newer_than_external && external[omc].timestamp`), warn the user — without `force: true`, files newer on the OMC side will go to `conflicts[]`. |
| 29 | |
| 30 | ### Step 3 — Confirm |
| 31 | Use `vscode_askQuestions` to confirm export and gate `force` carefully: |
| 32 | |
| 33 | ``` |
| 34 | header: "push-omc" |
| 35 | question: "OMG 세션을 OMC로 푸시하시겠습니까?" |
| 36 | options: |
| 37 | - label: "표준 푸시 (충돌 시 건너뜀)" |
| 38 | description: ".omc/ 파일이 더 최신이면 보존하고 conflicts[]에 보고" |
| 39 | recommended: true |
| 40 | - label: "강제 푸시 (--force, .previous.{ISO}.json 백업 생성)" |
| 41 | description: "OMC 측 변경을 덮어쓰고 회전 백업 3개를 유지" |
| 42 | - label: "취소" |
| 43 | allowFreeformInput: false |
| 44 | ``` |
| 45 | |
| 46 | Strong-default the standard option. Force mode should be a deliberate user choice — once `.previous.{ISO}.json` rotation hits N=3, older snapshots are pruned. |
| 47 | |
| 48 | ### Step 4 — Export |
| 49 | Call `omg_export_external_session({target: "omc", force: <chosen>})`. |
| 50 | |
| 51 | Pre-flight: |
| 52 | - The exporter applies a project-identity guard. If the source checkpoint's `workspace_root` ≠ current workspace, it returns `{ success: false, reason: "workspace_mismatch" }` BEFORE any file mutation. Surface the error and stop. |
| 53 | |
| 54 | Composition (not a blind copy): |
| 55 | - `.omg/prd.json` → `.omc/prd.json` |
| 56 | - `.omg/project-memory.json` → `.omc/project-memory.json` |
| 57 | - `active_modes[]` from `.omg/state/session-checkpoint.json` → DECOMPOSED into `.omc/state/{mode}-state.json` files (inverse of v1.4.0 omc-importer composition) |
| 58 | - `.omc/state/session-checkpoint.json` is composed with `source_origin: "bridged-from-omg"`, `source_tool: "copilot"` (kept for back-compat), `source_session_id`, `workspace_root`, `imported_at`, `imported_summary`. chmod 0o600 best-effort. |
| 59 | |
| 60 | Atomicity (AC-22b): the `.omg/state/last-export-token.json` write is the LAST side-effect. If any prior write fails, the token is NOT created — subsequent operations correctly treat the transaction as uncommitted. |
| 61 | |
| 62 | ### Step 5 — Summarize |
| 63 | Display the export result: |
| 64 | |
| 65 | ``` |
| 66 | ✅ OMC로 푸시 완료 |
| 67 | |
| 68 | 📋 Export 결과: |
| 69 | - target: omc |
| 70 | - session_id: {session_id} |
| 71 | - exported_files: {exported_files count}개 |
| 72 | - conflicts: {conflicts count}개 |
| 73 | - source_origin: bridged-from-omg |
| 74 | - workspace_root: {workspace_root} |
| 75 | |
| 76 | 📝 요약: |
| 77 | {summary} |
| 78 | ``` |
| 79 | |
| 80 | If `success === false`: |
| 81 | - `reason: "workspace_mismatch"` → "워크스페이스가 일치하지 않습니다. expected={expected}, actual={actual}". 사용자에게 올바른 워크스페이스를 열도록 안내. |
| 82 | - 그 외 → 원본 에러 메시지 그대로 출력. |
| 83 | |
| 84 | ### Step 6 — Continue |
| 85 | Ask the user what to do next: |
| 86 | ``` |
| 87 | header: "push-omc-next-action" |
| 88 | question: "OMC로 전환하시겠습니까, 아니면 OMG에서 작업을 계속하시겠습니까?" |
| 89 | options: |
| 90 | - label: "OMC로 전환 (Claude Code에서 /resume-omc 실행 안내)" |
| 91 | recommended: true |
| 92 | - label: "OMG에서 계속 작업" |
| 93 | - label: "충돌 파일 리뷰" |
| 94 | ``` |
| 95 | |
| 96 | ## Round-trip Safety |
| 97 | - The OMC importer (`/resume-claude` flow) reads the exported checkpoint's `source_origin` and the matching `.omg/state/last-export-token.json`. If both indicate "this checkpoint came from us", the importer returns `loop_blocked: true` and does NOT mutate `.omg/`. Set `force: true` on `omg_import_external_session` to bypass when verifying round-trip. |
| 98 | - Token has no time-based TTL. It invalidates only when the OMC checkpoint's `source_origin` flips to `"native"` (OMC wrote a fresh non-bridged checkpoint) OR `source_session_id` no longer matches the token (a newer bridged write replaced it). |
| 99 | |
| 100 | ## Backup Retention |
| 101 | - `.omc/X.previous.{ISO}.json` rotates with N=3. Older snapshots are pruned automatically. |
| 102 | - For unbounded history, `git log -- .omc/` or commit before pushing. |
| 103 | |
| 104 | ## Error Handling |
| 105 | - **workspace_mismatch**: surface `expected` vs `actual`, ask user to open the correct workspace. |
| 106 | - **conflicts[].length > 0**: list affected files; offer to retry with `force: true`. |
| 107 | - **success: false** with no recognized `reason`: log the raw error and abort — do not retry blindly. |
| 108 | |
| 109 | ## Notes |
| 110 | - OMG → OMC is a (mostly) lossless inversion: prd, project-memory, and state files round-trip; provenance fields are translated. |
| 111 | - OMG → Claude Code direction is deferred to v1.5.x (would require synthesizing valid `tool_use`/`tool_result` UUID chains compatible with Claude Code's resume-by-id contract). |
| 112 | - Do not run OMC and OMG concur |