feat(apps): M3 publisher — guided publish, updates, register-existing

- publisher (§11): resumable state machine persisted in .rowboat-publish.json
  (packaged → repo_created → source_pushed → release_created →
  assets_uploaded → registered → published); Git Data API single-commit
  source push with generated README/LICENSE/.gitignore when absent; both
  release assets uploaded (bundle + standalone manifest); fork+PR registry
  registration with rejected:<code> parsing and rename-retry surface
- publish update (§11.3): semver bump, package, push, release — no registry
- register existing release (§11.5) with client-side asset probe
- IPC: apps:publish/publishUpdate/registerExisting + apps:progress pushes
This commit is contained in:
Gagan 2026-07-06 15:08:36 +05:30
parent 6dea528fb4
commit 35c781b8e4
3 changed files with 480 additions and 0 deletions

View file

@ -1319,6 +1319,28 @@ const ipcSchemas = {
req: z.object({ folder: z.string() }),
res: z.object({ app: AppSummarySchema }),
},
// Advisory progress pushes for long-running app operations (§13).
'apps:progress': {
req: z.object({ folder: z.string(), step: z.string(), detail: z.string().optional() }),
res: z.null(),
},
'apps:publish': {
req: z.object({ folder: z.string() }),
res: z.object({
status: z.enum(['published', 'pending']),
repoUrl: z.string(),
releaseUrl: z.string(),
prUrl: z.string().optional(),
}),
},
'apps:publishUpdate': {
req: z.object({ folder: z.string(), increment: z.enum(['patch', 'minor', 'major']) }),
res: z.object({ version: z.string(), releaseUrl: z.string() }),
},
'apps:registerExisting': {
req: z.object({ name: z.string(), repo: z.string() }),
res: z.object({ status: z.enum(['published', 'pending']), prUrl: z.string() }),
},
// GitHub auth (device flow) — required only for publishing apps (spec §10).
'githubAuth:start': {
req: z.object({}),