@agentshouse/kit 0.2.1-c7f53ff9eaf98 → 0.2.1-c845e172df1af
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/README.md +17 -17
- package/dist/acp.js +36 -16
- package/dist/agents.js +36 -16
- package/dist/api.js +5 -5
- package/dist/bootstrap.json +4 -4
- package/dist/bridge.js +1 -1
- package/dist/calls.js +63 -0
- package/dist/clis.js +1 -1
- package/dist/{stream.js → connection.js} +32 -30
- package/dist/conversations.js +242 -116
- package/dist/copies.js +53 -51
- package/dist/end.js +6 -2
- package/dist/events.js +2 -2
- package/dist/files.js +116 -27
- package/dist/git.js +1 -1
- package/dist/house-cli.js +95 -59
- package/dist/instructions.js +2 -2
- package/dist/kit-cli.js +2 -2
- package/dist/mcp.js +4 -2
- package/dist/placement.js +11 -2
- package/dist/resident.js +32 -30
- package/dist/scope.js +3 -0
- package/dist/service.js +23 -1
- package/dist/sign-in.js +19 -37
- package/dist/skills.js +3 -3
- package/dist/translate.js +2 -8
- package/dist/update.js +42 -45
- package/dist/wire.js +19 -3
- package/package.json +3 -3
package/dist/copies.js
CHANGED
|
@@ -11,7 +11,7 @@ import { changed } from './translate.js';
|
|
|
11
11
|
import { relayed } from './relay.js';
|
|
12
12
|
const BRANCH = 'main';
|
|
13
13
|
const PROVENANCE = '_provenance';
|
|
14
|
-
const IDENTITY = { GIT_COMMITTER_NAME: '
|
|
14
|
+
const IDENTITY = { GIT_COMMITTER_NAME: 'Kit', GIT_COMMITTER_EMAIL: 'house-kit@localhost' };
|
|
15
15
|
function causeOf(error) {
|
|
16
16
|
return error instanceof Error ? error.message : String(error);
|
|
17
17
|
}
|
|
@@ -58,6 +58,9 @@ function expiredAuthority(error) {
|
|
|
58
58
|
return undefined;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
function grouped(items, size) {
|
|
62
|
+
return items.flatMap((_, index) => (index % size === 0 ? [items.slice(index, index + size)] : []));
|
|
63
|
+
}
|
|
61
64
|
function covers(path, prefix) {
|
|
62
65
|
return prefix === '' || path === prefix || path.startsWith(`${prefix}/`);
|
|
63
66
|
}
|
|
@@ -130,7 +133,7 @@ async function ignoreRules(repository, writable, copy) {
|
|
|
130
133
|
].map(pattern);
|
|
131
134
|
const granted = readOnly.filter((path) => !protectedPath(path)).map(pattern);
|
|
132
135
|
await ruled(join(repository, '.gitignore'), [
|
|
133
|
-
'#
|
|
136
|
+
'# Kit writes this file and .ignore. The paths below are read-only House',
|
|
134
137
|
'# content: Git does not track them, and House refuses a change to them even',
|
|
135
138
|
'# when this file is edited or a path is force-added.',
|
|
136
139
|
'/.gitignore',
|
|
@@ -145,7 +148,7 @@ async function ignoreRules(repository, writable, copy) {
|
|
|
145
148
|
'',
|
|
146
149
|
].join('\n'));
|
|
147
150
|
await ruled(join(repository, '.ignore'), [
|
|
148
|
-
'#
|
|
151
|
+
'# Kit writes this file so native search still reads the read-only House',
|
|
149
152
|
'# content that .gitignore keeps out of Git.',
|
|
150
153
|
`!${PROVENANCE}`,
|
|
151
154
|
...[...house, ...granted].map((rule) => `!${rule}`),
|
|
@@ -215,53 +218,56 @@ export class LocalCopies {
|
|
|
215
218
|
async mapping() {
|
|
216
219
|
await this.answering;
|
|
217
220
|
return [...this.copies.values()]
|
|
218
|
-
.filter((copy) => copy.
|
|
221
|
+
.filter((copy) => copy.unfollowed === undefined)
|
|
219
222
|
.map((copy) => `${rootOf(copy.room_handle)}: ${copy.repository}`)
|
|
220
223
|
.sort();
|
|
221
224
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
connected() {
|
|
226
|
+
return this.selected();
|
|
227
|
+
}
|
|
228
|
+
async changed(rooms) {
|
|
229
|
+
if (rooms.length > 0)
|
|
230
|
+
await this.selected(rooms);
|
|
226
231
|
}
|
|
227
232
|
fetch() {
|
|
228
233
|
return this.answered(() => this.fetched(true));
|
|
229
234
|
}
|
|
235
|
+
async selected(rooms) {
|
|
236
|
+
const copied = await this.answered(() => this.fetched(false, rooms));
|
|
237
|
+
if (copied.refused)
|
|
238
|
+
logged(copied.text);
|
|
239
|
+
}
|
|
230
240
|
answered(work) {
|
|
231
241
|
const answered = this.answering.then(work);
|
|
232
242
|
this.answering = answered.catch(() => undefined);
|
|
233
243
|
return answered;
|
|
234
244
|
}
|
|
235
|
-
async fetched(refreshing) {
|
|
236
|
-
const { local_copy: answer } = await this.house.post('/kit/local-copy/selection', {});
|
|
245
|
+
async fetched(refreshing, rooms) {
|
|
246
|
+
const { local_copy: answer } = await this.house.post('/kit/local-copy/selection', rooms === undefined ? {} : { rooms });
|
|
237
247
|
const synced = new Map(answer.rooms.map((room) => [`rooms/${room.room_ref}`, room.room_handle]));
|
|
238
|
-
|
|
248
|
+
const named = rooms === undefined ? null : new Set(rooms.map((room) => `rooms/${room}`));
|
|
249
|
+
const held = () => [...this.copies.values()].filter((copy) => named === null || named.has(copy.key));
|
|
250
|
+
return this.holding([...new Set([...held().map((copy) => copy.key), ...synced.keys()])].sort(), async () => {
|
|
239
251
|
const said = [];
|
|
240
252
|
let refused = false;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (
|
|
253
|
+
const mark = refreshing ? 'said' : 'unsaid';
|
|
254
|
+
for (const copy of held()) {
|
|
255
|
+
if (synced.has(copy.key) || copy.unfollowed === 'said' || copy.unfollowed === mark)
|
|
244
256
|
continue;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
said.push(`${rootOf(copy.room_handle)}:
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
refused = true;
|
|
251
|
-
said.push(`${rootOf(copy.room_handle)}: ${causeOf(error)}`);
|
|
252
|
-
}
|
|
257
|
+
await this.save({ ...copy, unfollowed: mark });
|
|
258
|
+
if (refreshing)
|
|
259
|
+
said.push(`${rootOf(copy.room_handle)}: no longer followed; kept as it is`);
|
|
253
260
|
}
|
|
254
261
|
const current = [];
|
|
255
262
|
for (const [key, handle] of synced) {
|
|
256
263
|
try {
|
|
257
264
|
const held = this.copies.get(key);
|
|
258
|
-
if (held?.erasing)
|
|
259
|
-
continue;
|
|
260
265
|
if (held === undefined || !(await exists(held.repository))) {
|
|
261
266
|
said.push(await this.materialize(key, handle));
|
|
262
267
|
continue;
|
|
263
268
|
}
|
|
264
|
-
|
|
269
|
+
const { unfollowed, ...followed } = held;
|
|
270
|
+
current.push(unfollowed === undefined && held.room_handle === handle ? held : await this.save({ ...followed, room_handle: handle }));
|
|
265
271
|
}
|
|
266
272
|
catch (error) {
|
|
267
273
|
refused = true;
|
|
@@ -269,13 +275,12 @@ export class LocalCopies {
|
|
|
269
275
|
}
|
|
270
276
|
}
|
|
271
277
|
if (refreshing && current.length > 0) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
catch (error) {
|
|
278
|
+
const failed = await this.refreshed(current).then(() => null, houseCause);
|
|
279
|
+
for (const copy of current)
|
|
280
|
+
said.push(...moved(copy, this.copies.get(copy.key)));
|
|
281
|
+
if (failed !== null) {
|
|
277
282
|
refused = true;
|
|
278
|
-
said.push(
|
|
283
|
+
said.push(failed);
|
|
279
284
|
}
|
|
280
285
|
}
|
|
281
286
|
return { refused, text: said.length === 0 ? 'Nothing new from House.' : said.join('\n') };
|
|
@@ -287,8 +292,6 @@ export class LocalCopies {
|
|
|
287
292
|
return;
|
|
288
293
|
await this.exclusive(key, async () => {
|
|
289
294
|
const copy = this.copies.get(key);
|
|
290
|
-
if (copy === undefined || copy.erasing)
|
|
291
|
-
return;
|
|
292
295
|
let moves = copy.moves;
|
|
293
296
|
for (const { from, to } of report.moves) {
|
|
294
297
|
const held = moves.find((move) => move.worktree === report.worktree && move.to === from);
|
|
@@ -344,12 +347,6 @@ export class LocalCopies {
|
|
|
344
347
|
this.copies.set(copy.key, copy);
|
|
345
348
|
return copy;
|
|
346
349
|
}
|
|
347
|
-
async erase(copy) {
|
|
348
|
-
await this.save({ ...copy, erasing: true });
|
|
349
|
-
await rm(copy.repository, { recursive: true, force: true });
|
|
350
|
-
await rm(recordOf(copy.key), { force: true });
|
|
351
|
-
this.copies.delete(copy.key);
|
|
352
|
-
}
|
|
353
350
|
async read(handle) {
|
|
354
351
|
const prefixes = [rootOf(handle)];
|
|
355
352
|
const discovery = await this.house.post('/kit/door/discover', { prefixes });
|
|
@@ -391,7 +388,7 @@ export class LocalCopies {
|
|
|
391
388
|
throw new Error('House serves nothing of it to copy');
|
|
392
389
|
const repository = join(localCopies(), 'rooms', read.anchor);
|
|
393
390
|
if (await exists(repository))
|
|
394
|
-
throw new Error(`${repository} already exists and
|
|
391
|
+
throw new Error(`${repository} already exists and Kit leaves it as it is`);
|
|
395
392
|
const staging = join(dirname(repository), `.${randomUUID()}`);
|
|
396
393
|
await mkdir(staging, { recursive: true });
|
|
397
394
|
let house;
|
|
@@ -450,19 +447,24 @@ export class LocalCopies {
|
|
|
450
447
|
return next;
|
|
451
448
|
}
|
|
452
449
|
async refreshed(copies) {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
});
|
|
456
|
-
const
|
|
450
|
+
const discover = (group) => this.house.post('/kit/door/discover', { prefixes: group.map((copy) => rootOf(copy.room_handle)) });
|
|
451
|
+
const [first, ...rest] = copies;
|
|
452
|
+
const { bounds, authorities } = await discover([first]);
|
|
453
|
+
for (const group of grouped(rest, bounds.max_prefixes))
|
|
454
|
+
authorities.push(...(await discover(group)).authorities);
|
|
455
|
+
const unchanged = [];
|
|
457
456
|
for (const copy of copies) {
|
|
458
|
-
const authority =
|
|
457
|
+
const authority = authorities.find((entry) => entry.room_ref === copy.room_ref);
|
|
459
458
|
if (authority !== undefined &&
|
|
460
459
|
JSON.stringify([authority.operations.write, authority.protected_paths]) !== JSON.stringify([copy.write, copy.protected])) {
|
|
461
|
-
|
|
460
|
+
await this.save(await this.received(copy));
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
unchanged.push(copy);
|
|
462
464
|
}
|
|
463
465
|
}
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
+
for (const group of grouped(unchanged, bounds.max_prefixes))
|
|
467
|
+
await this.caughtUp(group, false);
|
|
466
468
|
}
|
|
467
469
|
async caughtUp(copies, whole) {
|
|
468
470
|
const caught = new Map(copies.map((copy) => [copy.key, copy]));
|
|
@@ -544,8 +546,6 @@ export class LocalCopies {
|
|
|
544
546
|
}
|
|
545
547
|
async pushed(key, worktree, selector, caller) {
|
|
546
548
|
let copy = this.copies.get(key);
|
|
547
|
-
if (copy === undefined || copy.erasing)
|
|
548
|
-
return outside(worktree);
|
|
549
549
|
if (copy.push?.state === 'submitted')
|
|
550
550
|
return this.settle(copy, caller);
|
|
551
551
|
const selected = await run(worktree, ['rev-parse', '--verify', '--quiet', '--end-of-options', `${selector}^{commit}`]);
|
|
@@ -660,8 +660,10 @@ export class LocalCopies {
|
|
|
660
660
|
}
|
|
661
661
|
if (outcome.refused.code === 'expired')
|
|
662
662
|
return this.recovered(copy);
|
|
663
|
-
const rebased = rebaseFixes(outcome.refused);
|
|
664
663
|
let settled = await this.save(without(copy));
|
|
664
|
+
if (settled.unfollowed !== undefined)
|
|
665
|
+
return { refused: true, text: outcome.refused.text };
|
|
666
|
+
const rebased = rebaseFixes(outcome.refused);
|
|
665
667
|
try {
|
|
666
668
|
settled = (await this.caughtUp([settled], true))[0];
|
|
667
669
|
}
|
package/dist/end.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { KIT_RELEASE } from './clis.js';
|
|
1
2
|
import { forgetRejected } from './home.js';
|
|
2
3
|
import { installCommand } from './placement.js';
|
|
3
4
|
import { killDescendants } from './scope.js';
|
|
4
|
-
export const REPLACED = 'another Kit started for this Environment';
|
|
5
|
+
export const REPLACED = 'another Kit process started for this Environment';
|
|
5
6
|
function exit(reason, status) {
|
|
6
7
|
process.stderr.write(`kit: ${reason}\n`);
|
|
7
8
|
killDescendants();
|
|
8
9
|
process.exit(status);
|
|
9
10
|
}
|
|
10
11
|
export function end(reason) {
|
|
11
|
-
exit(reason, 0);
|
|
12
|
+
exit(reason, process.env.HOUSE_KIT_RESIDENT === String(process.pid) ? 0 : 1);
|
|
12
13
|
}
|
|
13
14
|
export function restart(reason) {
|
|
14
15
|
exit(reason, 1);
|
|
@@ -17,6 +18,9 @@ export function updateRequired() {
|
|
|
17
18
|
const command = installCommand();
|
|
18
19
|
end(command === null ? 'This Kit is too old for House; install it again.' : `This Kit is too old for House. Update it: ${command}`);
|
|
19
20
|
}
|
|
21
|
+
export function newerThanHouse(release, command) {
|
|
22
|
+
end(`Kit ${KIT_RELEASE} is newer than this Building supports (Kit ${release}). Install Kit ${release}: ${command}`);
|
|
23
|
+
}
|
|
20
24
|
export async function signInAgain(rejected) {
|
|
21
25
|
await forgetRejected(rejected);
|
|
22
26
|
restart('sign in again');
|
package/dist/events.js
CHANGED
|
@@ -2,7 +2,7 @@ const COMMAND = { shown: 'command' };
|
|
|
2
2
|
const HIDDEN = { shown: 'hidden' };
|
|
3
3
|
const FINISHED = new Set(['completed', 'failed']);
|
|
4
4
|
export const RUNNING_JOB = new Set(['running', 'paused']);
|
|
5
|
-
const
|
|
5
|
+
const MESSAGE_TARGETS = { send_routine_request: 'access', cancel_routine_request: 'request', send_mail: 'request' };
|
|
6
6
|
function words(line) {
|
|
7
7
|
const found = [];
|
|
8
8
|
let word = null;
|
|
@@ -48,7 +48,7 @@ export function houseMessage(line) {
|
|
|
48
48
|
catch {
|
|
49
49
|
return null;
|
|
50
50
|
}
|
|
51
|
-
const argument =
|
|
51
|
+
const argument = MESSAGE_TARGETS[call.command];
|
|
52
52
|
if (argument === undefined)
|
|
53
53
|
return null;
|
|
54
54
|
const target = call.arguments?.[argument];
|
package/dist/files.js
CHANGED
|
@@ -1,42 +1,131 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { createWriteStream } from 'node:fs';
|
|
3
|
+
import { mkdir, rename, rm } from 'node:fs/promises';
|
|
4
|
+
import { basename, dirname, join } from 'node:path';
|
|
5
|
+
import { Readable, Transform } from 'node:stream';
|
|
6
|
+
import { pipeline } from 'node:stream/promises';
|
|
7
|
+
import { retrying, retryDelay } from './api.js';
|
|
8
|
+
import { Unsettled } from './mcp.js';
|
|
5
9
|
import { relayed } from './relay.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
const STALLED_ROUNDS = 8;
|
|
11
|
+
function paused(milliseconds) {
|
|
12
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
13
|
+
}
|
|
14
|
+
export function storeRefusal(act, status) {
|
|
15
|
+
return new Error(`the ${act} answered ${status}; ${act} the file again`);
|
|
16
|
+
}
|
|
17
|
+
export async function uploaded(declared, uploading) {
|
|
18
|
+
let upload = declared;
|
|
19
|
+
let idle = 0;
|
|
20
|
+
let stalled = 0;
|
|
21
|
+
for (;;) {
|
|
22
|
+
let sent = 0;
|
|
23
|
+
let failure = null;
|
|
24
|
+
for (const { part, url } of upload.parts) {
|
|
25
|
+
const start = (part - 1) * upload.part_bytes;
|
|
26
|
+
try {
|
|
27
|
+
await uploading.send(url, start, Math.min(start + upload.part_bytes, uploading.bytes));
|
|
28
|
+
sent++;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
failure = error;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (sent > 0) {
|
|
36
|
+
idle = 0;
|
|
37
|
+
stalled = 0;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (failure !== null && ++stalled >= STALLED_ROUNDS)
|
|
41
|
+
throw failure;
|
|
42
|
+
// A round that sent no part, its store unreachable or not yet started, is followed by the next finishing call on the jittered curve.
|
|
43
|
+
await paused(retryDelay(idle++));
|
|
44
|
+
}
|
|
45
|
+
let answer = await finishing(uploading, upload.id);
|
|
46
|
+
while ('checking' in answer) {
|
|
47
|
+
// A finishing call that finds House still checking the stored bytes is sent again after five seconds, the cadence at which House takes up a check it handed over.
|
|
48
|
+
await paused(5_000);
|
|
49
|
+
answer = await finishing(uploading, upload.id);
|
|
50
|
+
}
|
|
51
|
+
if (!('upload' in answer))
|
|
52
|
+
return answer;
|
|
53
|
+
upload = answer.upload;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function finishing(uploading, upload) {
|
|
57
|
+
for (let unsettled = 1;; unsettled++) {
|
|
58
|
+
try {
|
|
59
|
+
return await uploading.finish(upload);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (!(error instanceof Unsettled) || unsettled === STALLED_ROUNDS)
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
// A finishing call House did not settle, unreached or refused short of final, is sent again on the jittered curve as a conversation resends it, so a dropped connection or a House restart resumes the upload instead of ending it.
|
|
66
|
+
await paused(retryDelay(unsettled - 1));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function drained(body) {
|
|
70
|
+
for await (const _chunk of body)
|
|
71
|
+
;
|
|
72
|
+
}
|
|
73
|
+
export async function downloaded(address, fetching, destination, name) {
|
|
74
|
+
for (let asked = 1;; asked++) {
|
|
75
|
+
const { download, sha256 } = await address();
|
|
76
|
+
const answer = await fetching(download);
|
|
77
|
+
if (answer.status === 403 && asked === 1) {
|
|
78
|
+
await drained(answer.body);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (answer.status !== 200) {
|
|
82
|
+
await drained(answer.body);
|
|
83
|
+
throw storeRefusal('download', answer.status);
|
|
84
|
+
}
|
|
85
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
86
|
+
const partial = join(dirname(destination), `.${basename(destination)}.${randomUUID()}`);
|
|
87
|
+
const digest = createHash('sha256');
|
|
88
|
+
const hashed = new Transform({
|
|
89
|
+
transform(chunk, _encoding, done) {
|
|
90
|
+
digest.update(chunk);
|
|
91
|
+
done(null, chunk);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
try {
|
|
95
|
+
await pipeline(answer.body, hashed, createWriteStream(partial, { flags: 'wx' }));
|
|
96
|
+
if (digest.digest('hex') !== sha256)
|
|
97
|
+
throw new Error(`${name} did not arrive whole; download it again`);
|
|
98
|
+
await rename(partial, destination);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
await rm(partial, { force: true });
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function fetched(url, signal) {
|
|
108
|
+
const answer = await fetch(relayed(url), { signal });
|
|
109
|
+
return { status: answer.status, body: answer.body ?? Readable.from([]) };
|
|
10
110
|
}
|
|
11
111
|
export async function placeFiles(house, directory, files, signal) {
|
|
12
112
|
const paths = [];
|
|
13
113
|
for (const file of files) {
|
|
14
|
-
const original =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
throw new Error(`${file.name} did not download: ${answer.status}`);
|
|
18
|
-
const folder = join(directory, '.house', 'files', original.message, file.version);
|
|
114
|
+
const original = () => retrying(() => house.post('/kit/conversation/originals/get', { version: file.version, download: true }, signal), signal);
|
|
115
|
+
let first = await original();
|
|
116
|
+
const folder = join(directory, '.house', 'files', first.message, file.version);
|
|
19
117
|
await mkdir(join(directory, '.house')).catch((error) => {
|
|
20
118
|
if (error.code !== 'EEXIST')
|
|
21
119
|
throw error;
|
|
22
120
|
});
|
|
23
121
|
await mkdir(folder, { recursive: true });
|
|
24
122
|
const path = join(folder, file.name);
|
|
25
|
-
await
|
|
123
|
+
await downloaded(async () => {
|
|
124
|
+
const answered = first ?? (await original());
|
|
125
|
+
first = null;
|
|
126
|
+
return { download: answered.download.url, sha256: file.sha256 };
|
|
127
|
+
}, (url) => fetched(url, signal), path, file.name);
|
|
26
128
|
paths.push(path);
|
|
27
129
|
}
|
|
28
130
|
return paths;
|
|
29
131
|
}
|
|
30
|
-
export function uploadBytes(upload, bytes) {
|
|
31
|
-
return retrying(async () => {
|
|
32
|
-
const answer = await fetch(relayed(upload.url), {
|
|
33
|
-
method: 'POST',
|
|
34
|
-
headers: { 'content-type': 'application/octet-stream', 'x-house-byte-operation': upload.operation },
|
|
35
|
-
body: bytes,
|
|
36
|
-
});
|
|
37
|
-
const text = await answer.text();
|
|
38
|
-
if (!answer.ok)
|
|
39
|
-
throw new HouseRefusal(upload.url, answer.status, text);
|
|
40
|
-
return JSON.parse(text);
|
|
41
|
-
});
|
|
42
|
-
}
|
package/dist/git.js
CHANGED
|
@@ -8,7 +8,7 @@ export function localCopies() {
|
|
|
8
8
|
return join(workspaceRoot(), 'local-copies');
|
|
9
9
|
}
|
|
10
10
|
export const HOUSE_REF = 'refs/house/received';
|
|
11
|
-
const COMMITTER = '
|
|
11
|
+
const COMMITTER = 'Kit <house-kit@localhost>';
|
|
12
12
|
export function run(cwd, args, input, env = {}) {
|
|
13
13
|
return new Promise((resolve, reject) => {
|
|
14
14
|
const child = spawn('git', args, { cwd, env: { ...withoutProxy(), ...env } });
|