@heyquilt/seam 0.26.0 → 0.27.0
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/bin/seam.js +1 -0
- package/lib/quilts/cli.js +13 -1
- package/lib/quilts/client.js +2 -0
- package/lib/quilts/tools.js +12 -1
- package/package.json +1 -1
package/bin/seam.js
CHANGED
|
@@ -23,6 +23,7 @@ Docs: https://seam.heyquilt.com/docs
|
|
|
23
23
|
seam oauth client new <name> --redirect <uri> | list | revoke <client_id> apps that ask people for access (OAuth 2, PKCE)
|
|
24
24
|
seam quilts [new <slug> | show <q>] Your quilts (repositories)
|
|
25
25
|
seam import git <path> [--into <slug>]
|
|
26
|
+
seam github [import <owner/name> --installation <id> [--into <slug>]] from GitHub, followed
|
|
26
27
|
seam import git <remote-url> --into <slug> [--follow] [--interval <s>] [--credential <name>]
|
|
27
28
|
seam import status <id> | seam import poke <id> | seam import cutover <id> an import that follows git
|
|
28
29
|
seam export remote <url> --quilt <q> [--line main,release/*] [--releases] [--credential <name>] | seam export status
|
package/lib/quilts/cli.js
CHANGED
|
@@ -42,7 +42,7 @@ export function parseTiers (text) {
|
|
|
42
42
|
|
|
43
43
|
/** `test/**,**\/*.test.js` → a list; `none` clears it. */
|
|
44
44
|
export const parseGlobs = (text) => text === 'none' ? null : text.split(',').map((x) => x.trim()).filter(Boolean)
|
|
45
|
-
const VALUE_FLAGS = new Set(['-m', '--quilts', '--message', '-n', '--max-count', '--into', '--onto', '--on-conflict', '--quilt', '--square', '--dir', '--line', '--task', '--level', '--title', '--slug', '--format', '--expect-tip', '--side', '--file', '--batch', '--to', '--note', '--after', '--kinds', '--webhook', '--secret', '--branch', '--from', '-S', '--run', '--marks', '--patch', '--on', '--path', '--checks', '--name', '--public-key', '--interval', '--credential', '--as', '--runners', '--run-key', '--state', '--tier', '--tiers', '--tests', '--ci-config', '--commit', '--check', '--log-url'])
|
|
45
|
+
const VALUE_FLAGS = new Set(['-m', '--installation', '--quilts', '--message', '-n', '--max-count', '--into', '--onto', '--on-conflict', '--quilt', '--square', '--dir', '--line', '--task', '--level', '--title', '--slug', '--format', '--expect-tip', '--side', '--file', '--batch', '--to', '--note', '--after', '--kinds', '--webhook', '--secret', '--branch', '--from', '-S', '--run', '--marks', '--patch', '--on', '--path', '--checks', '--name', '--public-key', '--interval', '--credential', '--as', '--runners', '--run-key', '--state', '--tier', '--tiers', '--tests', '--ci-config', '--commit', '--check', '--log-url'])
|
|
46
46
|
|
|
47
47
|
export function parse (argv) {
|
|
48
48
|
const pos = []; const flags = {}; const paths = []
|
|
@@ -491,6 +491,18 @@ export async function runSeamCommand (cmd, argv, { cwd = process.cwd(), token, o
|
|
|
491
491
|
const r = await client.tree(needQuilt(), pos[0] || 'main', pos.slice(1).concat(paths))
|
|
492
492
|
return print(r, r.entries.map((e) => `${e.mode}\t${e.blob ? e.blob.slice(0, 12) : e.term.slice(0, 12)}\t${e.path}`).join('\n'))
|
|
493
493
|
}
|
|
494
|
+
case 'github': {
|
|
495
|
+
// GitHub through the Seam app: what it reaches, and importing (and following) a repository.
|
|
496
|
+
if (pos[0] === 'import') {
|
|
497
|
+
if (!pos[1] || !flags['--installation']) throw new Error('seam github import <owner/name> --installation <id> [--into <slug>] [--no-follow]')
|
|
498
|
+
const r = await client.importGithub({ installation_id: flags['--installation'], repo: pos[1], slug: flags['--into'] || undefined, follow: !flags['--no-follow'] })
|
|
499
|
+
return print(r, `Importing ${pos[1]} (import ${r.id})${r.follow ? ', following it: GitHub tells Seam of every push' : ''}. seam import status ${r.id}`)
|
|
500
|
+
}
|
|
501
|
+
const g = await client.github()
|
|
502
|
+
if (!g.configured) return print(g, 'GitHub is not set up on this Seam server.')
|
|
503
|
+
if (!g.installations.length) return print(g, `No GitHub installations yet: install the Seam app from ${g.app.install_url}`)
|
|
504
|
+
return print(g, g.installations.map((i) => `${i.login} (installation ${i.id})\n${i.repos.map((r) => ` ${r.full_name}${r.private ? ' (private)' : ''}`).join('\n') || ' no repositories'}`).join('\n'))
|
|
505
|
+
}
|
|
494
506
|
case 'import': {
|
|
495
507
|
// From a git remote, on the server, and following it (14): status and poke name the import.
|
|
496
508
|
if (pos[0] === 'cutover') {
|
package/lib/quilts/client.js
CHANGED
|
@@ -112,6 +112,8 @@ export function quiltClient ({ api, token, fetch: fetchImpl = globalThis.fetch,
|
|
|
112
112
|
setExport: (q, b) => call('PUT', `${Q(q)}/export`, b),
|
|
113
113
|
exportStatus: (q) => call('GET', `${Q(q)}/export`),
|
|
114
114
|
startImport: (b) => call('POST', '/v1/imports', b),
|
|
115
|
+
github: () => call('GET', '/v1/github'),
|
|
116
|
+
importGithub: (b) => call('POST', '/v1/github/import', b),
|
|
115
117
|
importStatus: (id) => call('GET', `/v1/imports/${enc(id)}`),
|
|
116
118
|
cutover: (id, b = {}) => call('POST', `/v1/imports/${enc(id)}/cutover`, b),
|
|
117
119
|
pokeImport: (id) => call('POST', `/v1/imports/${enc(id)}/poke`),
|
package/lib/quilts/tools.js
CHANGED
|
@@ -12,7 +12,7 @@ import { describeLog, describeShow, describeDiff, describeBlame, describeStatus,
|
|
|
12
12
|
import { signWithLocalKey, localKey, makeLocalKey, signingKeyFile } from './signing.js'
|
|
13
13
|
import { status as blockStatus, commitFolder, amendFolder, syncTo, restore, reset, clean, localChanges } from './block.js'
|
|
14
14
|
|
|
15
|
-
export const SEAM_TOOLS = ['seam_quilts', 'seam_open_square', 'seam_squares', 'seam_log', 'seam_show', 'seam_diff', 'seam_blame', 'seam_cat', 'seam_ls', 'seam_commit', 'seam_merge', 'seam_rebase', 'seam_revert', 'seam_cherry_pick', 'seam_resolve', 'seam_square_status', 'seam_square_handoff', 'seam_abandon', 'seam_square_merged', 'seam_reopen', 'seam_fold', 'seam_split', 'seam_events', 'seam_events_webhook', 'seam_line_list', 'seam_line_new', 'seam_line_freeze', 'seam_line_unfreeze', 'seam_line_require', 'seam_reviews', 'seam_review', 'seam_tag_list', 'seam_tag', 'seam_release_list', 'seam_release', 'seam_import_git', 'seam_import_remote', 'seam_import_status', 'seam_import_poke', 'seam_import_cutover', 'seam_export_remote', 'seam_export_status', 'seam_restore', 'seam_reset', 'seam_clean', 'seam_live', 'seam_live_set', 'seam_bisect', 'seam_grep', 'seam_search', 'seam_describe', 'seam_merge_base', 'seam_claims', 'seam_claim', 'seam_unclaim', 'seam_check', 'seam_resolutions', 'seam_forget_resolution', 'seam_sign', 'seam_keys', 'seam_key_add', 'seam_key_remove', 'seam_token_list', 'seam_token_new', 'seam_token_revoke', 'seam_checks', 'seam_check_rerun']
|
|
15
|
+
export const SEAM_TOOLS = ['seam_quilts', 'seam_open_square', 'seam_squares', 'seam_log', 'seam_show', 'seam_diff', 'seam_blame', 'seam_cat', 'seam_ls', 'seam_commit', 'seam_merge', 'seam_rebase', 'seam_revert', 'seam_cherry_pick', 'seam_resolve', 'seam_square_status', 'seam_square_handoff', 'seam_abandon', 'seam_square_merged', 'seam_reopen', 'seam_fold', 'seam_split', 'seam_events', 'seam_events_webhook', 'seam_line_list', 'seam_line_new', 'seam_line_freeze', 'seam_line_unfreeze', 'seam_line_require', 'seam_reviews', 'seam_review', 'seam_tag_list', 'seam_tag', 'seam_release_list', 'seam_release', 'seam_import_git', 'seam_import_remote', 'seam_github', 'seam_github_import', 'seam_import_status', 'seam_import_poke', 'seam_import_cutover', 'seam_export_remote', 'seam_export_status', 'seam_restore', 'seam_reset', 'seam_clean', 'seam_live', 'seam_live_set', 'seam_bisect', 'seam_grep', 'seam_search', 'seam_describe', 'seam_merge_base', 'seam_claims', 'seam_claim', 'seam_unclaim', 'seam_check', 'seam_resolutions', 'seam_forget_resolution', 'seam_sign', 'seam_keys', 'seam_key_add', 'seam_key_remove', 'seam_token_list', 'seam_token_new', 'seam_token_revoke', 'seam_checks', 'seam_check_rerun']
|
|
16
16
|
|
|
17
17
|
/** What every agent is told about source control, in each MCP's instructions. */
|
|
18
18
|
export const SEAM_GUIDE = 'Quilt source control (quilts): a quilt is a repository on the Quilt server; you work in a square (your own branch and working copy), commit save points in it, and merge it into main, where it becomes a patch. ' +
|
|
@@ -46,6 +46,8 @@ export const SEAM_DESCRIPTIONS = {
|
|
|
46
46
|
seam_line_freeze: 'Freezes a line (admins): merges into it are refused with line_frozen until seam_line_unfreeze.',
|
|
47
47
|
seam_line_unfreeze: 'Unfreezes a line (admins): it takes merges again.',
|
|
48
48
|
seam_tag_list: 'The quilt\'s tags: name, commit, the patch it is, and whether it is a release.',
|
|
49
|
+
seam_github: 'Your GitHub installations of the Seam app and the repositories each reaches (install it from seam.heyquilt.com/github). Import one with seam_github_import.',
|
|
50
|
+
seam_github_import: 'Imports a GitHub repository the Seam app reaches into a new quilt and follows it (GitHub tells Seam of every push), with the installation as its credential: no token to paste.',
|
|
49
51
|
seam_import_remote: 'Imports a git remote (https:// or ssh) into a new quilt on the server. With follow, it keeps taking new commits on main and release/* every interval (and on seam_import_poke) and freezes those lines until cut-over, because git stays the authority. Returns the import id and its poke secret (shown once).',
|
|
50
52
|
seam_export_remote: 'Exports lines of a quilt to a git remote (admins) after each merge on them, as fast-forwards that are never forced; releases: true pushes release tags too. While an import follows git, only to a scratch remote (scratch: true).',
|
|
51
53
|
seam_export_status: 'The export to a git remote: its target, lines, state (idle, ok, retrying, refused), each line\'s last exported patch and sha, and the last error.',
|
|
@@ -114,6 +116,8 @@ export const SEAM_INPUTS = {
|
|
|
114
116
|
seam_line_freeze: { quilt: QUILT, line: z.string().max(110) },
|
|
115
117
|
seam_line_unfreeze: { quilt: QUILT, line: z.string().max(110) },
|
|
116
118
|
seam_tag_list: { quilt: QUILT },
|
|
119
|
+
seam_github: {},
|
|
120
|
+
seam_github_import: { repo: z.string().max(201).describe('owner/name, as seam_github lists it'), installation: z.string().max(20).describe('The installation id seam_github shows for it'), into: z.string().max(63).optional().describe('The new quilt\'s slug (default the repo\'s name)'), follow: z.boolean().optional().describe('Keep following it (default true)') },
|
|
117
121
|
seam_import_remote: { url: z.string().max(2000).describe('The git remote: https://, ssh:// or user@host:path'), into: z.string().max(63).describe('The new quilt\'s slug'), follow: z.boolean().optional().describe('Keep following main and release/* until cut-over'), interval: z.number().int().min(60).optional().describe('Seconds between follow passes (default 600)'), credential: z.string().max(100).optional().describe('The name of the server secret that reads the remote (user:token or a token)') },
|
|
118
122
|
seam_export_remote: { quilt: z.string().max(100).optional().describe('The quilt'), target: z.string().max(2000).describe('The git remote'), lines: z.array(z.string().max(100)).max(20).optional().describe('Lines to export (default ["main"]); release/* for every release line'), releases: z.boolean().optional().describe('Push release tags too'), credential: z.string().max(100).optional().describe('The name of the server secret that may push'), scratch: z.boolean().optional().describe('A scratch remote nothing pins a sha from'), enabled: z.boolean().optional().describe('false turns the export off') },
|
|
119
123
|
seam_export_status: { quilt: z.string().max(100).optional().describe('The quilt') },
|
|
@@ -310,6 +314,13 @@ export async function runSeamTool (name, args, { client, found = null }) {
|
|
|
310
314
|
case 'seam_line_unfreeze': { const l = await client.unfreezeLine(needQuilt(), args.line); return `${l.name} takes merges again.` }
|
|
311
315
|
case 'seam_tag_list': { const ts = await client.tags(needQuilt()); return ts.length ? ts.map(describeTag).join('\n') : 'No tags yet.' }
|
|
312
316
|
case 'seam_release_list': { const rs = await client.releases(needQuilt()); return rs.length ? rs.map(describeRelease).join('\n') : 'No releases yet.' }
|
|
317
|
+
case 'seam_github': {
|
|
318
|
+
const g = await client.github()
|
|
319
|
+
if (!g.configured) return 'GitHub is not set up on this Seam server.'
|
|
320
|
+
if (!g.installations.length) return `No GitHub installations yet: install the Seam app from ${g.app.install_url} (or seam.heyquilt.com/github).`
|
|
321
|
+
return g.installations.map((i) => `${i.login} (installation ${i.id}): ${i.repos.map((r) => r.full_name).join(', ') || 'no repositories'}`).join('\n')
|
|
322
|
+
}
|
|
323
|
+
case 'seam_github_import': { const r = await client.importGithub({ installation_id: args.installation, repo: args.repo, slug: args.into, follow: args.follow !== false }); return `Importing ${args.repo} into ${r.id ? (args.into || args.repo.split('/')[1]) : '?'} (import ${r.id})${r.follow ? ', following it' : ''}.` }
|
|
313
324
|
case 'seam_import_remote': { const r = await client.startImport({ url: args.url, slug: args.into, follow: !!args.follow, interval: args.interval, credential: args.credential }); return `Importing ${args.url} into ${args.into} (import ${r.id})${r.follow ? `, following every ${r.interval_s} s; poke secret ${r.poke_secret} (shown once)` : ''}.` }
|
|
314
325
|
case 'seam_export_remote': { const r = await client.setExport(needQuilt(), { target: args.target, lines: args.lines, releases: args.releases, credential: args.credential, scratch: args.scratch, enabled: args.enabled !== false }); return r.enabled ? `Exporting ${r.lines.join(', ')} to ${r.target} after each merge.` : `The export to ${r.target} is off.` }
|
|
315
326
|
case 'seam_export_status': { const r = await client.exportStatus(needQuilt()); return JSON.stringify({ target: r.target, lines: r.lines, releases: r.releases, enabled: r.enabled, status: r.status }, null, 2) }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyquilt/seam",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "seam: Quilt Source's command. Git's verbs for source control that runs on the server, built for many agents and people at once.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|