heyquilt 0.0.1 → 0.3.106
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.
- package/LICENSE +85 -0
- package/README.md +633 -2
- package/RELEASES.md +862 -0
- package/assets/logo.svg +1 -0
- package/bin/quilt.js +849 -0
- package/desktop/main.js +315 -0
- package/package.json +163 -7
- package/src/account.js +591 -0
- package/src/admit-policy.js +32 -0
- package/src/agent-join.js +370 -0
- package/src/agent-task-workflow.js +176 -0
- package/src/agents/actions.js +85 -0
- package/src/agents/claude-code.js +187 -0
- package/src/agents/common.js +21 -0
- package/src/agents/cursor-transcripts.js +177 -0
- package/src/agents/cursor.js +404 -0
- package/src/agents/index.js +69 -0
- package/src/ai-vm-signin.js +110 -0
- package/src/ai-vm.js +522 -0
- package/src/api/access.js +75 -0
- package/src/api/activity.js +181 -0
- package/src/api/agent-auth.js +136 -0
- package/src/api/agent-placement.js +157 -0
- package/src/api/audit.js +83 -0
- package/src/api/auth.js +17 -0
- package/src/api/domains.js +30 -0
- package/src/api/file-paths.js +40 -0
- package/src/api/file-store.js +99 -0
- package/src/api/fly-machines.js +133 -0
- package/src/api/github-app.js +172 -0
- package/src/api/http.js +34 -0
- package/src/api/invite-email.js +53 -0
- package/src/api/issues.js +110 -0
- package/src/api/join-text.js +78 -0
- package/src/api/mailer.js +47 -0
- package/src/api/memory-store.js +1219 -0
- package/src/api/org-access.js +54 -0
- package/src/api/permissions.js +71 -0
- package/src/api/relay-cluster.js +545 -0
- package/src/api/relay-machines.js +92 -0
- package/src/api/releases.js +87 -0
- package/src/api/routes/access-types.js +54 -0
- package/src/api/routes/agent-invites.js +115 -0
- package/src/api/routes/agents.js +252 -0
- package/src/api/routes/ai-vm.js +495 -0
- package/src/api/routes/github.js +380 -0
- package/src/api/routes/grants.js +70 -0
- package/src/api/routes/invites.js +188 -0
- package/src/api/routes/issues.js +47 -0
- package/src/api/routes/join.js +167 -0
- package/src/api/routes/members.js +110 -0
- package/src/api/routes/orgs.js +179 -0
- package/src/api/routes/relay-cluster.js +90 -0
- package/src/api/routes/relay.js +76 -0
- package/src/api/routes/secrets.js +448 -0
- package/src/api/routes/session-invites.js +119 -0
- package/src/api/routes/sessions.js +92 -0
- package/src/api/routes/teams.js +132 -0
- package/src/api/routes/workspace-agents.js +332 -0
- package/src/api/routes/workspace-files.js +277 -0
- package/src/api/routes/workspace-invites.js +196 -0
- package/src/api/routes/workspaces.js +232 -0
- package/src/api/sandbox-keys.js +57 -0
- package/src/api/secrets-access.js +93 -0
- package/src/api/server.js +654 -0
- package/src/api/slugs.js +20 -0
- package/src/api/supabase-store.js +875 -0
- package/src/api/team-access.js +30 -0
- package/src/api/tokens.js +31 -0
- package/src/api/workspace-access.js +62 -0
- package/src/api/workspace-reach.js +60 -0
- package/src/autowork-tools.js +166 -0
- package/src/autowork.js +375 -0
- package/src/blobstore.js +99 -0
- package/src/boxes.js +37 -0
- package/src/branchdocs.js +235 -0
- package/src/branches.js +194 -0
- package/src/catchup.js +111 -0
- package/src/chat-archive.js +85 -0
- package/src/chat-links.js +923 -0
- package/src/clash.js +128 -0
- package/src/cloud-ai.js +50 -0
- package/src/commit-request.js +59 -0
- package/src/commit.js +213 -0
- package/src/connection.js +569 -0
- package/src/control.js +248 -0
- package/src/conversation.js +125 -0
- package/src/doctor.js +156 -0
- package/src/duties.js +303 -0
- package/src/editors.js +228 -0
- package/src/fsutil.js +97 -0
- package/src/git-hook.js +48 -0
- package/src/git.js +147 -0
- package/src/github-commit.js +320 -0
- package/src/gitignore.js +49 -0
- package/src/gitstate.js +924 -0
- package/src/history.js +307 -0
- package/src/hooks.js +371 -0
- package/src/hosted-agents.js +24 -0
- package/src/hosted-client.js +112 -0
- package/src/identity.js +99 -0
- package/src/inbox.js +237 -0
- package/src/integrations.js +221 -0
- package/src/key-cli.js +115 -0
- package/src/largefiles.js +91 -0
- package/src/legacy.js +25 -0
- package/src/mcp-proxy.js +45 -0
- package/src/mcp-room.js +32 -0
- package/src/mcp.js +1258 -0
- package/src/merge3.js +240 -0
- package/src/merges.js +148 -0
- package/src/pass-source.js +183 -0
- package/src/passes.js +64 -0
- package/src/pathrules.js +134 -0
- package/src/persona.js +101 -0
- package/src/presence.js +360 -0
- package/src/private-file.js +41 -0
- package/src/procs.js +70 -0
- package/src/project-rules.js +178 -0
- package/src/protocol.js +92 -0
- package/src/quiet-warnings.js +9 -0
- package/src/relay-ai-vm.js +82 -0
- package/src/relay-ask.js +141 -0
- package/src/relay-ci.js +111 -0
- package/src/relay-clash.js +214 -0
- package/src/relay-cluster.js +454 -0
- package/src/relay-commit.js +887 -0
- package/src/relay-filekey.js +46 -0
- package/src/relay-git.js +274 -0
- package/src/relay-githttp.js +166 -0
- package/src/relay-github.js +109 -0
- package/src/relay-lease.js +137 -0
- package/src/relay-lfs.js +37 -0
- package/src/relay-mcp.js +1691 -0
- package/src/relay-metrics.js +140 -0
- package/src/relay-outbound.js +1273 -0
- package/src/relay-sync.js +716 -0
- package/src/relay-turn-sync.js +506 -0
- package/src/relay-upstream.js +804 -0
- package/src/relay-webhooks.js +111 -0
- package/src/releases.js +138 -0
- package/src/report.js +129 -0
- package/src/runner.js +307 -0
- package/src/same-edit.js +18 -0
- package/src/secret-import.js +55 -0
- package/src/secret-names.js +26 -0
- package/src/secret-run.js +80 -0
- package/src/secrets-client.js +56 -0
- package/src/server.js +4214 -0
- package/src/session-access.js +170 -0
- package/src/session-name.js +15 -0
- package/src/session.js +7446 -0
- package/src/settings.js +46 -0
- package/src/setup.js +184 -0
- package/src/shell-path.js +46 -0
- package/src/status.js +197 -0
- package/src/summarize.js +109 -0
- package/src/sync-words.js +42 -0
- package/src/task-comments.js +92 -0
- package/src/tasks.js +670 -0
- package/src/textdiff.js +20 -0
- package/src/turn-sync-plan.js +145 -0
- package/src/turn-sync.js +212 -0
- package/src/ui/access-form.js +37 -0
- package/src/ui/agent-env-key.js +76 -0
- package/src/ui/agent-guide.js +127 -0
- package/src/ui/agent-kinds.js +175 -0
- package/src/ui/agent-place.js +265 -0
- package/src/ui/app.css +2494 -0
- package/src/ui/app.js +546 -0
- package/src/ui/board.js +465 -0
- package/src/ui/boxes.js +76 -0
- package/src/ui/branches.js +111 -0
- package/src/ui/catchup.js +77 -0
- package/src/ui/changes.js +159 -0
- package/src/ui/chat.js +266 -0
- package/src/ui/cloud-ai-model.js +108 -0
- package/src/ui/cloud-ai.js +221 -0
- package/src/ui/common.js +433 -0
- package/src/ui/csv.js +21 -0
- package/src/ui/diffview.js +74 -0
- package/src/ui/feed-convs.js +39 -0
- package/src/ui/feed.js +174 -0
- package/src/ui/files.js +579 -0
- package/src/ui/fileview.js +150 -0
- package/src/ui/git-rule.js +60 -0
- package/src/ui/home.js +1322 -0
- package/src/ui/index.html +16 -0
- package/src/ui/invite.js +97 -0
- package/src/ui/invites.js +79 -0
- package/src/ui/loom-model.js +516 -0
- package/src/ui/loom.css +365 -0
- package/src/ui/loom.js +786 -0
- package/src/ui/mark.js +104 -0
- package/src/ui/rail-model.js +75 -0
- package/src/ui/rail.js +173 -0
- package/src/ui/releases.js +182 -0
- package/src/ui/sandbox-keys-model.js +53 -0
- package/src/ui/sandbox-keys.js +132 -0
- package/src/ui/schedule.js +156 -0
- package/src/ui/secret-rules.js +255 -0
- package/src/ui/secrets-view.js +162 -0
- package/src/ui/secrets.js +283 -0
- package/src/ui/session.js +3292 -0
- package/src/ui/signin.js +75 -0
- package/src/ui/sounds.js +110 -0
- package/src/ui/tool-logo.js +86 -0
- package/src/ui/tree.js +281 -0
- package/src/ui/workspaces.js +547 -0
- package/src/ui-server.js +1381 -0
- package/src/update-check.js +67 -0
- package/src/upstream.js +192 -0
- package/src/vault/crypto.js +96 -0
- package/src/vault/kms.js +61 -0
- package/src/vault/main.js +33 -0
- package/src/vault/server.js +279 -0
- package/src/vault/sigv4.js +38 -0
- package/src/webhooks.js +235 -0
- package/src/workspace-cli.js +62 -0
- package/src/workspace-tools.js +340 -0
- package/index.js +0 -2
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Comments on a task: work notes, handoffs and the reasoning behind an assignment, kept on
|
|
2
|
+
// the ticket instead of in the session chat. Stored apart from the task (map "taskComments",
|
|
3
|
+
// task id -> list), so an app from before comments existed can move or edit a task without
|
|
4
|
+
// dropping them.
|
|
5
|
+
import crypto from 'node:crypto'
|
|
6
|
+
|
|
7
|
+
export const MAX_COMMENT = 2000
|
|
8
|
+
export const MAX_COMMENTS = 50 // per task: the oldest go first
|
|
9
|
+
const INVISIBLE = /[\u0000-\u0008\u000b-\u001f\u007f\u200b-\u200f\u202a-\u202e\u2066-\u2069\ufeff]/g // eslint-disable-line no-control-regex
|
|
10
|
+
|
|
11
|
+
/** A comment's text: newlines kept, control characters and bidi overrides dropped. */
|
|
12
|
+
export function cleanComment (text) {
|
|
13
|
+
return String(text ?? '').replace(/\r\n?/g, '\n').replace(INVISIBLE, ' ')
|
|
14
|
+
.split('\n').map((l) => l.replace(/[ \t]+/g, ' ').trimEnd()).join('\n')
|
|
15
|
+
.replace(/\n{3,}/g, '\n\n').trim().slice(0, MAX_COMMENT).trimEnd()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A stored comment we'll show, or null for anything a modified client pushed that isn't this shape. */
|
|
19
|
+
function publicComment (c) {
|
|
20
|
+
if (!c || typeof c !== 'object') return null
|
|
21
|
+
if (typeof c.id !== 'string' || !/^[0-9a-f]{16}$/.test(c.id)) return null
|
|
22
|
+
if (typeof c.by !== 'string' || !c.by || c.by.length > 80) return null
|
|
23
|
+
if (typeof c.text !== 'string' || !c.text || c.text !== cleanComment(c.text)) return null
|
|
24
|
+
if (typeof c.ts !== 'number' || !Number.isFinite(c.ts)) return null
|
|
25
|
+
return { id: c.id, by: c.by, text: c.text, ts: c.ts }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The comments on task `id`, oldest first. */
|
|
29
|
+
export function readComments (map, id) {
|
|
30
|
+
const list = map && map.get(id)
|
|
31
|
+
return Array.isArray(list) ? list.map(publicComment).filter(Boolean) : []
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Every task's comments: { taskId: [comment] }, for tasks that have any. */
|
|
35
|
+
export function allComments (map) {
|
|
36
|
+
const out = {}
|
|
37
|
+
if (!map) return out
|
|
38
|
+
map.forEach((_, id) => { const list = readComments(map, id); if (list.length) out[id] = list })
|
|
39
|
+
return out
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `tasks` with `comments` on each (an empty list when it has none). */
|
|
43
|
+
export function withComments (tasks, map) {
|
|
44
|
+
const all = allComments(map)
|
|
45
|
+
return tasks.map((t) => ({ ...t, comments: all[t.id] || [] }))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Adds a comment by `by` to task `taskId` (which must be on the board). Returns the comment. */
|
|
49
|
+
export function addComment (doc, map, tasks, { taskId, by, text }, origin) {
|
|
50
|
+
if (!tasks.some((t) => t.id === taskId)) throw new Error('no such task')
|
|
51
|
+
const clean = cleanComment(text)
|
|
52
|
+
if (!clean) throw new Error('say what the comment is')
|
|
53
|
+
const who = String(by ?? '').replace(/\s+/g, ' ').trim().slice(0, 80) || 'someone'
|
|
54
|
+
const comment = { id: crypto.randomBytes(8).toString('hex'), by: who, text: clean, ts: Date.now() }
|
|
55
|
+
const next = [...readComments(map, taskId), comment].slice(-MAX_COMMENTS)
|
|
56
|
+
// Comments of tasks no longer on the board go at the same time.
|
|
57
|
+
const ids = new Set(tasks.map((t) => t.id))
|
|
58
|
+
const gone = [...map.keys()].filter((id) => !ids.has(id))
|
|
59
|
+
doc.transact(() => {
|
|
60
|
+
for (const id of gone) map.delete(id)
|
|
61
|
+
map.set(taskId, next)
|
|
62
|
+
}, origin)
|
|
63
|
+
return comment
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Plain text for an agent: one comment per paragraph. */
|
|
67
|
+
export function formatComments (list, ago) {
|
|
68
|
+
if (!list.length) return 'No comments yet.'
|
|
69
|
+
return list.map((c) => `- ${c.by} (${ago(c.ts)}): ${c.text.replace(/\n/g, '\n ')}`).join('\n')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** One task in full, as plain text for an agent: `task` as the board lists it, with `comments`. */
|
|
73
|
+
export function formatTaskDetails (task, now = Date.now()) {
|
|
74
|
+
const ago = (ts) => {
|
|
75
|
+
const s = Math.max(0, Math.round((now - (ts || 0)) / 1000))
|
|
76
|
+
return s < 60 ? `${s}s ago` : s < 3600 ? `${Math.round(s / 60)}m ago` : s < 86400 ? `${Math.round(s / 3600)}h ago` : `${Math.round(s / 86400)}d ago`
|
|
77
|
+
}
|
|
78
|
+
const column = { todo: 'To do', doing: 'In progress', qa: 'QA', done: 'Done' }[task.column] || task.column
|
|
79
|
+
const who = task.assignee ? `${task.assignee}${task.forAi ? `'s AI${task.tool ? ` (${task.tool})` : ''}` : ''}` : 'nobody'
|
|
80
|
+
const comments = Array.isArray(task.comments) ? task.comments : []
|
|
81
|
+
return [
|
|
82
|
+
task.title,
|
|
83
|
+
`id: ${task.id}`,
|
|
84
|
+
`Column: ${column}`,
|
|
85
|
+
`Assigned to: ${who}`,
|
|
86
|
+
`Added by ${task.by}, ${ago(task.ts)}`,
|
|
87
|
+
task.files?.length ? `Files: ${task.files.join(', ')}` : null,
|
|
88
|
+
task.qaNotes ? `QA notes:\n${task.qaNotes}` : null,
|
|
89
|
+
task.verified ? `Verified:\n${task.verified}` : null,
|
|
90
|
+
`Comments (${comments.length}):\n${formatComments(comments, ago)}`
|
|
91
|
+
].filter((x) => x !== null).join('\n')
|
|
92
|
+
}
|