heyquilt 0.3.121 → 0.3.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/RELEASES.md +292 -17
  2. package/bin/quilt.js +72 -5
  3. package/desktop/main.js +16 -2
  4. package/package.json +3 -1
  5. package/src/agent-task-workflow.js +2 -2
  6. package/src/agents/common.js +13 -0
  7. package/src/ai-vm.js +9 -1
  8. package/src/api/activity.js +5 -0
  9. package/src/api/memory-store.js +21 -10
  10. package/src/api/notify.js +134 -0
  11. package/src/api/routes/browsers.js +29 -0
  12. package/src/api/routes/github.js +0 -13
  13. package/src/api/routes/relay.js +26 -3
  14. package/src/api/routes/seam-connect.js +103 -0
  15. package/src/api/routes/session-migrate.js +39 -0
  16. package/src/api/routes/sessions.js +73 -1
  17. package/src/api/server.js +46 -12
  18. package/src/api/supabase-store.js +53 -4
  19. package/src/autowork.js +182 -16
  20. package/src/connection.js +39 -9
  21. package/src/control.js +139 -13
  22. package/src/force-date.js +27 -0
  23. package/src/fsutil.js +13 -3
  24. package/src/gitstate.js +38 -2
  25. package/src/history.js +25 -1
  26. package/src/mcp.js +93 -7
  27. package/src/merge3.js +11 -3
  28. package/src/now-summary.js +113 -0
  29. package/src/pathrules.js +12 -0
  30. package/src/protocol.js +10 -2
  31. package/src/quilt-default.js +84 -0
  32. package/src/quilt-history.js +106 -0
  33. package/src/quilt-remote.js +78 -0
  34. package/src/relay-commit.js +5 -0
  35. package/src/relay-lease.js +6 -2
  36. package/src/relay-mcp.js +172 -8
  37. package/src/relay-outbound.js +1 -1
  38. package/src/relay-prune.js +4 -1
  39. package/src/release-words.js +2 -2
  40. package/src/runner.js +20 -7
  41. package/src/seam-access.js +97 -0
  42. package/src/seam-claims.js +53 -0
  43. package/src/seam-url.js +15 -0
  44. package/src/server.js +1767 -33
  45. package/src/session-follow.js +515 -0
  46. package/src/session-layout3.js +466 -0
  47. package/src/session-migrate.js +123 -0
  48. package/src/session-quilt.js +145 -0
  49. package/src/session-seam.js +284 -0
  50. package/src/session.js +899 -46
  51. package/src/source-live/bring-in.js +283 -0
  52. package/src/source-live/live-block.js +507 -35
  53. package/src/source-live/live-square.js +17 -6
  54. package/src/status.js +5 -0
  55. package/src/ui/agent-guide.js +1 -1
  56. package/src/ui/app.css +85 -20
  57. package/src/ui/app.js +4 -1
  58. package/src/ui/chat.js +9 -3
  59. package/src/ui/cloud-ai-model.js +13 -0
  60. package/src/ui/cloud-ai.js +10 -2
  61. package/src/ui/common.js +6 -2
  62. package/src/ui/fileview.js +20 -7
  63. package/src/ui/force-words.js +19 -0
  64. package/src/ui/git-rule.js +9 -0
  65. package/src/ui/home.js +0 -147
  66. package/src/ui/loom-model.js +15 -1
  67. package/src/ui/quiltview.js +213 -0
  68. package/src/ui/seam-model.js +251 -0
  69. package/src/ui/session.js +413 -31
  70. package/src/ui/voice-call.js +83 -14
  71. package/src/ui/voice-model.js +39 -0
  72. package/src/ui/voice.js +167 -17
  73. package/src/ui-server.js +80 -28
  74. package/src/update-check.js +25 -1
  75. package/src/voice.js +13 -6
  76. package/src/git.js +0 -147
  77. package/src/quilts/AGENTS.md +0 -1
  78. package/src/quilts/CLAUDE.md +0 -1
  79. package/src/quilts/archiver.js +0 -175
  80. package/src/quilts/autorevert.js +0 -49
  81. package/src/quilts/bisect-run.js +0 -31
  82. package/src/quilts/blame.js +0 -103
  83. package/src/quilts/block.js +0 -347
  84. package/src/quilts/bucket.js +0 -25
  85. package/src/quilts/cbor.js +0 -92
  86. package/src/quilts/claims.js +0 -144
  87. package/src/quilts/cli.js +0 -449
  88. package/src/quilts/client.js +0 -128
  89. package/src/quilts/conflict-format.js +0 -190
  90. package/src/quilts/describe.js +0 -266
  91. package/src/quilts/dogfood.js +0 -82
  92. package/src/quilts/errors.js +0 -8
  93. package/src/quilts/events.js +0 -160
  94. package/src/quilts/export-git.js +0 -130
  95. package/src/quilts/export.js +0 -81
  96. package/src/quilts/fastmerge.js +0 -41
  97. package/src/quilts/hash.js +0 -44
  98. package/src/quilts/history.js +0 -266
  99. package/src/quilts/ids.js +0 -12
  100. package/src/quilts/import-git.js +0 -291
  101. package/src/quilts/import.js +0 -134
  102. package/src/quilts/index.js +0 -72
  103. package/src/quilts/limits.js +0 -67
  104. package/src/quilts/lines.js +0 -49
  105. package/src/quilts/live.js +0 -50
  106. package/src/quilts/merge-smart.js +0 -114
  107. package/src/quilts/merge.js +0 -486
  108. package/src/quilts/objects.js +0 -144
  109. package/src/quilts/pack.js +0 -118
  110. package/src/quilts/records.js +0 -211
  111. package/src/quilts/resolutions.js +0 -69
  112. package/src/quilts/reviews.js +0 -195
  113. package/src/quilts/routes.js +0 -126
  114. package/src/quilts/service.js +0 -923
  115. package/src/quilts/setup.js +0 -34
  116. package/src/quilts/signing.js +0 -149
  117. package/src/quilts/squares.js +0 -239
  118. package/src/quilts/store-memory.js +0 -683
  119. package/src/quilts/store-rpc.js +0 -79
  120. package/src/quilts/store-supabase.js +0 -13
  121. package/src/quilts/tags.js +0 -64
  122. package/src/quilts/textdiff.js +0 -96
  123. package/src/quilts/tokens.js +0 -66
  124. package/src/quilts/tools.js +0 -375
  125. package/src/quilts/tree.js +0 -351
  126. package/src/quilts/webhook.js +0 -116
  127. package/src/quilts/window.js +0 -119
  128. package/src/quilts/xdiff.js +0 -435
  129. package/src/ui/branches.js +0 -111
@@ -1,126 +0,0 @@
1
- // Seam's HTTP door (plans/quilt-source-control/04): routes any server can mount. The host says
2
- // who is calling: identify(req) → { member_id, kind, name, tool?, on_behalf_of? }, or throws its
3
- // own refusal (Quilt's accounts API builds it from its sign-in, src/api/server.js). Every caller
4
- // reaches the same operations as the seam CLI and seam_* tools.
5
- import { QuiltError } from './service.js'
6
- import { classify, tokenKey } from './limits.js'
7
-
8
- const Q = '/v1/quilts/([^/]+)'
9
- const MAX_JSON = 96 * 1024 * 1024
10
- const MAX_PACK = 65 * 1024 * 1024
11
-
12
- const query = (req) => new URL(req.url, 'http://x').searchParams
13
- const list = (v) => (v ? String(v).split(',').map((s) => s.trim()).filter(Boolean) : [])
14
-
15
- export function quiltRoutes ({ quilts, identify }) {
16
- if (!quilts) return []
17
- if (typeof identify !== 'function') throw new Error('quiltRoutes needs identify(req): who is calling')
18
-
19
- /** The caller as a quilt member: a quilt token (tokens.js, `Authorization: Bearer sqt_…`, a key for one quilt), else whoever the host says. */
20
- async function me (req) {
21
- const h = String(req.headers?.authorization || '')
22
- if (h.startsWith('Bearer sqt_')) {
23
- const t = await quilts.tokenCaller(h.slice(7).trim())
24
- if (!t) throw new QuiltError(401, 'bad_token', 'this quilt token is unknown or revoked')
25
- return t
26
- }
27
- return identify(req)
28
- }
29
-
30
- // Every answer is the server's record; a refusal carries its wire code (12's WriteResult).
31
- // Per-token rate limits (04, limits.js), when the quilts were made with them.
32
- const limiter = quilts.rateLimiter || null
33
- const run = (fn) => async (req, body, params) => {
34
- try {
35
- const m = await me(req)
36
- if (limiter) limiter.take(tokenKey(req, m), classify(req.method, req.url, body), m.kind === 'person')
37
- return await fn(m, body, params, req)
38
- } catch (err) {
39
- if (err instanceof QuiltError) return [err.status, { ok: false, error: err.message, code: err.code, ...err.extra }]
40
- if (err && /^(bad path|a path|.*: (put|bad|give)|commit message|changes must|too many files)/.test(String(err.message))) return [400, { ok: false, error: err.message, code: 'bad_request' }]
41
- throw err
42
- }
43
- }
44
- const big = { maxBody: MAX_JSON }
45
-
46
- return [
47
- ['GET', /^\/v1\/quilts$/, run(async (m) => ({ quilts: await quilts.quilts(m) }))],
48
- ['POST', /^\/v1\/quilts$/, run(async (m, b) => [201, await quilts.createQuilt(m, b)])],
49
- ['GET', new RegExp(`^${Q}$`), run((m, b, [q]) => quilts.quiltInfo(m, q))],
50
- ['POST', new RegExp(`^${Q}/members$`), run((m, b, [q]) => quilts.addMember(m, q, b))],
51
- ['GET', new RegExp(`^${Q}/tokens$`), run((m, b, [q]) => quilts.tokens(m, q))],
52
- ['POST', new RegExp(`^${Q}/tokens$`), run(async (m, b, [q]) => [201, await quilts.createToken(m, q, b)])],
53
- ['DELETE', new RegExp(`^${Q}/tokens/([^/]+)$`), run((m, b, [q, id]) => quilts.revokeToken(m, q, decodeURIComponent(id)))],
54
-
55
- ['GET', new RegExp(`^${Q}/squares$`), run(async (m, b, [q], req) => { const s = query(req); return { squares: await quilts.squares(m, q, { state: s.get('state') || undefined, mine: s.get('mine') === '1', task: s.get('task') || undefined }) } })],
56
- ['POST', new RegExp(`^${Q}/squares$`), run(async (m, b, [q]) => [201, await quilts.openSquare(m, q, b)])],
57
- ['GET', new RegExp(`^${Q}/squares/([^/]+)$`), run((m, b, [q, s]) => quilts.square(m, q, s))],
58
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/commit$`), run(async (m, b, [q, s]) => [201, await quilts.commit(m, q, s, b)]), big],
59
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/amend$`), run(async (m, b, [q, s]) => [201, await quilts.amend(m, q, s, b)]), big],
60
- ['GET', new RegExp(`^${Q}/resolutions$`), run((m, b, [q], req) => quilts.resolutions(m, q, { path: query(req).get('path') || undefined }))],
61
- ['DELETE', new RegExp(`^${Q}/resolutions/([^/]+)$`), run((m, b, [q, k]) => quilts.forgetResolution(m, q, decodeURIComponent(k)))],
62
- ['GET', new RegExp(`^${Q}/claims$`), run((m, b, [q], req) => quilts.claims(m, q, { square: query(req).get('square') || undefined }))],
63
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/claims$`), run(async (m, b, [q, s]) => [201, await quilts.claim(m, q, s, b)])],
64
- ['DELETE', new RegExp(`^${Q}/squares/([^/]+)/claims/(.+)$`), run((m, b, [q, s, c]) => quilts.unclaim(m, q, s, decodeURIComponent(c)))],
65
- ['GET', new RegExp(`^${Q}/squares/([^/]+)/reviews$`), run((m, b, [q, s]) => quilts.reviews(m, q, s))],
66
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/reviews$`), run(async (m, b, [q, s]) => [201, await quilts.review(m, q, s, b)])],
67
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/checks$`), run((m, b, [q, s]) => quilts.reportSquareCheck(m, q, s, b))],
68
- ['GET', new RegExp(`^${Q}/lines/([^/]+)/policy$`), run((m, b, [q, line]) => quilts.linePolicy(m, q, decodeURIComponent(line)))],
69
- ['PUT', new RegExp(`^${Q}/lines/([^/]+)/policy$`), run((m, b, [q, line]) => quilts.setLinePolicy(m, q, decodeURIComponent(line), b))],
70
- ['GET', new RegExp(`^${Q}/squares/([^/]+)/live$`), run((m, b, [q, s]) => quilts.live(m, q, s))],
71
- ['PUT', new RegExp(`^${Q}/squares/([^/]+)/live$`), run((m, b, [q, s]) => quilts.setLive(m, q, s, b)), big],
72
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/handoff$`), run((m, b, [q, s]) => quilts.handoff(m, q, s, b))],
73
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/abandon$`), run((m, b, [q, s]) => quilts.abandon(m, q, s, b))],
74
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/reopen$`), run((m, b, [q, s]) => quilts.reopen(m, q, s, b))],
75
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/merge$`), run(async (m, b, [q, s]) => { const r = await quilts.mergeSquare(m, q, s, b); return r.noop ? r : [201, r] })],
76
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/fold$`), run((m, b, [q, s]) => quilts.fold(m, q, s, b))],
77
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/split$`), run(async (m, b, [q, s]) => [201, await quilts.split(m, q, s, b)])],
78
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/rebase$`), run((m, b, [q, s]) => quilts.rebase(m, q, s, b))],
79
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/cherry-pick$`), run((m, b, [q, s]) => quilts.cherryPick(m, q, s, b))],
80
- ['POST', new RegExp(`^${Q}/squares/([^/]+)/resolve$`), run((m, b, [q, s]) => quilts.resolve(m, q, s, b))],
81
- ['GET', new RegExp(`^${Q}/lines$`), run((m, b, [q]) => quilts.lines(m, q))],
82
- ['POST', new RegExp(`^${Q}/lines$`), run(async (m, b, [q]) => [201, await quilts.newLine(m, q, b)])],
83
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/freeze$`), run((m, b, [q, line]) => quilts.freezeLine(m, q, line))],
84
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/unfreeze$`), run((m, b, [q, line]) => quilts.unfreezeLine(m, q, line))],
85
- ['GET', new RegExp(`^${Q}/tags$`), run((m, b, [q]) => quilts.tags(m, q))],
86
- ['POST', new RegExp(`^${Q}/tags$`), run(async (m, b, [q]) => [201, await quilts.createTag(m, q, b)])],
87
- ['GET', new RegExp(`^${Q}/tags/(.+)$`), run((m, b, [q, name]) => quilts.getTag(m, q, decodeURIComponent(name)))],
88
- ['GET', new RegExp(`^${Q}/releases$`), run((m, b, [q]) => quilts.releases(m, q))],
89
- ['POST', new RegExp(`^${Q}/releases$`), run(async (m, b, [q]) => [201, await quilts.createRelease(m, q, b)])],
90
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/merge$`), run(async (m, b, [q, line]) => { const r = await quilts.mergeIntoLine(m, q, line, b); return r.ok || r.dry_run ? [r.dry_run ? 200 : 201, r] : [422, { ...r, error: r.refused.detail, code: r.refused.code }] })],
91
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/checks$`), run((m, b, [q, line]) => quilts.reportCheck(m, q, line, b))],
92
- ['GET', new RegExp(`^${Q}/lines/([^/]+)/window$`), run((m, b, [q, line]) => quilts.lineWindow(m, q, line))],
93
- ['GET', new RegExp(`^${Q}/lines/([^/]+)/patches$`), run((m, b, [q, line], req) => { const s = query(req); return quilts.linePatches(m, q, line, { before: s.get('before') || undefined, limit: s.get('limit') || 100 }) })],
94
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/window$`), run((m, b, [q, line]) => quilts.setLineLimits(m, q, line, b))],
95
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/checks$`), run((m, b, [q, line]) => quilts.reportCheck(m, q, line, b))],
96
- ['GET', new RegExp(`^${Q}/lines/([^/]+)/window$`), run((m, b, [q, line]) => quilts.lineWindow(m, q, line))],
97
- ['POST', new RegExp(`^${Q}/lines/([^/]+)/window$`), run((m, b, [q, line]) => quilts.setLineLimits(m, q, line, b))],
98
- ['POST', new RegExp(`^${Q}/patches/(\\d+)/revert$`), run(async (m, b, [q, n]) => [201, await quilts.revert(m, q, { ...b, rev: `${b.line || 'main'}:${n}` })])],
99
- ['POST', new RegExp(`^${Q}/revert$`), run(async (m, b, [q]) => [201, await quilts.revert(m, q, b)])],
100
-
101
- ['GET', new RegExp(`^${Q}/events$`), run((m, b, [q], req) => { const s = query(req); return quilts.events(m, q, { after: s.get('after') || 0, kinds: list(s.get('kinds')), limit: s.get('limit') || 100 }) })],
102
- ['POST', new RegExp(`^${Q}/webhook$`), run((m, b, [q]) => quilts.subscribe(m, q, b))],
103
- ['GET', new RegExp(`^${Q}/show/([^/]+)$`), run((m, b, [q, rev], req) => { const s = query(req); return quilts.show(m, q, rev, { format: s.get('format') || 'unified', paths: list(s.get('paths')) }) })],
104
- ['GET', new RegExp(`^${Q}/export/git$`), run((m, b, [q], req) => { const s = query(req); return quilts.exportPatches(m, q, { line: s.get('line') || 'main', after: s.has('after') ? Number(s.get('after')) : -1, limit: Number(s.get('limit')) || 200 }) })],
105
- ['GET', new RegExp(`^${Q}/log$`), run((m, b, [q], req) => { const s = query(req); return quilts.log(m, q, { rev: s.get('rev') || 'main', paths: list(s.get('paths')), limit: Number(s.get('limit')) || 20, follow: s.get('follow') === '1' || s.get('follow') === 'true', search: s.get('search') ?? undefined, show_signature: s.get('show_signature') === '1' || s.get('show_signature') === 'true' }) })],
106
- ['POST', new RegExp(`^${Q}/commits/([^/]+)/signatures$`), run(async (m, b, [q, rev]) => [201, await quilts.sign(m, q, decodeURIComponent(rev), b)])],
107
- ['GET', /^\/v1\/search$/, run((m, b, p, req) => { const s = query(req); const yes = (k) => s.get(k) === '1' || s.get(k) === 'true'; return quilts.search(m, { pattern: s.get('pattern'), rev: s.get('rev') || 'main', quilts: list(s.get('quilts')), paths: list(s.get('paths')), ignore_case: yes('ignore_case'), fixed: yes('fixed'), limit: Number(s.get('limit')) || 200 }) })],
108
- ['GET', /^\/v1\/signing-keys$/, run((m, b, p, req) => quilts.signingKeys(m, null, { member: query(req).get('member') || undefined }))],
109
- ['POST', /^\/v1\/signing-keys$/, run(async (m, b) => [201, await quilts.addKey(m, null, b)])],
110
- ['DELETE', /^\/v1\/signing-keys\/([^/]+)$/, run((m, b, [key]) => quilts.removeKey(m, null, decodeURIComponent(key)))],
111
- ['GET', new RegExp(`^${Q}/describe$`), run((m, b, [q], req) => quilts.describe(m, q, query(req).get('rev') || 'main'))],
112
- ['GET', new RegExp(`^${Q}/merge-base$`), run((m, b, [q], req) => { const s = query(req); return quilts.mergeBaseOf(m, q, s.get('a'), s.get('b')) })],
113
- ['GET', new RegExp(`^${Q}/grep$`), run((m, b, [q], req) => { const s = query(req); const yes = (k) => s.get(k) === '1' || s.get(k) === 'true'; return quilts.grep(m, q, { pattern: s.get('pattern'), rev: s.get('rev') || 'main', paths: list(s.get('paths')), ignore_case: yes('ignore_case'), fixed: yes('fixed'), limit: Number(s.get('limit')) || 200 }) })],
114
- ['POST', new RegExp(`^${Q}/bisect$`), run((m, b, [q]) => quilts.bisect(m, q, b || {}))],
115
- ['GET', new RegExp(`^${Q}/diff$`), run((m, b, [q], req) => { const s = query(req); return quilts.diff(m, q, { from: s.get('from') || undefined, to: s.get('to') || undefined, paths: list(s.get('paths')), format: s.get('format') || 'unified' }) })],
116
- ['GET', new RegExp(`^${Q}/tree/([^/]+)$`), run((m, b, [q, rev], req) => quilts.tree(m, q, rev, { paths: list(query(req).get('paths')) }))],
117
- ['GET', new RegExp(`^${Q}/blob/([^/]+)/(.+)$`), run((m, b, [q, rev, path], req) => quilts.cat(m, q, rev, path, { format: query(req).get('format') || 'diff' }))],
118
- ['GET', new RegExp(`^${Q}/blame/([^/]+)/(.+)$`), run((m, b, [q, rev, path]) => quilts.blame(m, q, rev, path))],
119
-
120
- ['POST', new RegExp(`^${Q}/have$`), run((m, b, [q]) => quilts.have(m, q, b.ids)), { maxBody: 2 * 1024 * 1024 }],
121
- ['POST', new RegExp(`^${Q}/blobs$`), run((m, b, [q]) => quilts.blobs(m, q, b.ids)), { maxBody: 2 * 1024 * 1024 }],
122
- ['POST', new RegExp(`^${Q}/packs$`), run(async (m, b, [q]) => [201, await quilts.uploadPack(m, q, b)]), { raw: true, maxBody: MAX_PACK }],
123
- ['POST', new RegExp(`^${Q}/import/commits$`), run((m, b, [q]) => quilts.importBatch(m, q, b)), big],
124
- ['POST', new RegExp(`^${Q}/import/known$`), run((m, b, [q]) => quilts.importKnown(m, q, b)), big]
125
- ]
126
- }