looply-cli 0.2.0 → 0.4.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.
Files changed (52) hide show
  1. package/dist/.src-hash +1 -1
  2. package/dist/bin.d.ts.map +1 -1
  3. package/dist/bin.js +25 -11
  4. package/dist/bin.js.map +1 -1
  5. package/dist/connect-node.d.ts +8 -0
  6. package/dist/connect-node.d.ts.map +1 -0
  7. package/dist/connect-node.js +110 -0
  8. package/dist/connect-node.js.map +1 -0
  9. package/dist/connect.d.ts +135 -0
  10. package/dist/connect.d.ts.map +1 -0
  11. package/dist/connect.js +329 -0
  12. package/dist/connect.js.map +1 -0
  13. package/dist/daemon-cmd.d.ts +11 -2
  14. package/dist/daemon-cmd.d.ts.map +1 -1
  15. package/dist/daemon-cmd.js +20 -6
  16. package/dist/daemon-cmd.js.map +1 -1
  17. package/dist/repo-init.d.ts +36 -0
  18. package/dist/repo-init.d.ts.map +1 -0
  19. package/dist/repo-init.js +61 -0
  20. package/dist/repo-init.js.map +1 -0
  21. package/dist/repo-origin.d.ts +15 -0
  22. package/dist/repo-origin.d.ts.map +1 -0
  23. package/dist/repo-origin.js +28 -0
  24. package/dist/repo-origin.js.map +1 -0
  25. package/dist/repo-requests.d.ts +79 -0
  26. package/dist/repo-requests.d.ts.map +1 -0
  27. package/dist/repo-requests.js +180 -0
  28. package/dist/repo-requests.js.map +1 -0
  29. package/dist/repo-scan.d.ts +47 -0
  30. package/dist/repo-scan.d.ts.map +1 -0
  31. package/dist/repo-scan.js +84 -0
  32. package/dist/repo-scan.js.map +1 -0
  33. package/dist/serve-cmd.d.ts +132 -0
  34. package/dist/serve-cmd.d.ts.map +1 -0
  35. package/dist/serve-cmd.js +532 -0
  36. package/dist/serve-cmd.js.map +1 -0
  37. package/dist/serve-tasks.d.ts +17 -0
  38. package/dist/serve-tasks.d.ts.map +1 -0
  39. package/dist/serve-tasks.js +124 -0
  40. package/dist/serve-tasks.js.map +1 -0
  41. package/dist/serve.d.ts +202 -0
  42. package/dist/serve.d.ts.map +1 -0
  43. package/dist/serve.js +413 -0
  44. package/dist/serve.js.map +1 -0
  45. package/dist/server-client.d.ts +37 -0
  46. package/dist/server-client.d.ts.map +1 -1
  47. package/dist/server-client.js +21 -0
  48. package/dist/server-client.js.map +1 -1
  49. package/dist/sync.d.ts.map +1 -1
  50. package/dist/sync.js +3 -1
  51. package/dist/sync.js.map +1 -1
  52. package/package.json +54 -54
@@ -0,0 +1,135 @@
1
+ import type { InitOutcome } from './repo-init';
2
+ import { type ScanFs } from './repo-scan';
3
+ import { type Platform, type ServeFs } from './serve';
4
+ /**
5
+ * `looply connect` — THE ONE COMMAND A PERSON RUNS ONCE PER MACHINE.
6
+ *
7
+ * Before it, putting a machine to work was five commands per repository —
8
+ * `pair`, then in every folder `init`, `serve add`, and finally `serve
9
+ * install` and `serve` — and the repository a person forgot was the one that
10
+ * went quiet. `connect` is those same steps, in that order, over every git
11
+ * repository under the folders a person names:
12
+ *
13
+ * 1. pair, if this machine is not paired yet (the same flow as `looply pair`);
14
+ * 2. choose the code roots — `--root`, else ask, else refuse;
15
+ * 3. find the repositories under them (`repo-scan.ts`);
16
+ * 4. `init` each one that has no config, non-interactively, and `serve add` it;
17
+ * 5. record the roots, so the supervisor finds the next repository by itself;
18
+ * 6. `serve install`, and start the supervisor unless `--no-start`.
19
+ *
20
+ * ⚠️ NOTHING HERE IS A SECOND IMPLEMENTATION. Pairing is `pairCommand`, the
21
+ * draft is `init`'s (`repo-init.ts`), the list is `serve`'s registry, the
22
+ * startup entry is `serve install`. This file only decides which of them to
23
+ * call, on what.
24
+ *
25
+ * ⚠️ AND IT IS CONSENT IN THE SAME SENSE `serve add` IS. Every served
26
+ * repository's daemon runs with `--yes` and registers it with the server
27
+ * without asking; so `connect` shows what it found and asks before serving it
28
+ * — or, with no terminal, refuses unless `--yes` said so up front.
29
+ */
30
+ export declare const CONNECT_USAGE: string;
31
+ export declare const EXIT_OK = 0;
32
+ export declare const EXIT_REFUSED = 1;
33
+ export declare const EXIT_USAGE = 64;
34
+ export interface ProvisionDeps {
35
+ readonly home: string;
36
+ readonly platform: Platform;
37
+ readonly fs: ServeFs;
38
+ now(): Date;
39
+ initRepo(dir: string): InitOutcome;
40
+ /**
41
+ * Why the repository's `.looply/config.yaml` would not load, or null when it
42
+ * would. Absent means "assume it loads".
43
+ *
44
+ * 🔴 ASKED BEFORE SERVING, because a daemon that cannot load its config
45
+ * exits at once and the supervisor restarts it for ever. `init`'s own draft
46
+ * is one such file: a repository where no typecheck or test command was
47
+ * detected gets `gates:` with nothing under it, which the loader refuses —
48
+ * correctly, since a gate-less run proves nothing. So the draft is written
49
+ * and left for a person to finish, and the repository is not served yet.
50
+ */
51
+ configProblem?(dir: string): string | null;
52
+ }
53
+ export interface ProvisionRow {
54
+ readonly path: string;
55
+ readonly init: InitOutcome['kind'];
56
+ readonly served: 'added' | 'already' | 'not';
57
+ /** Why it is not served, when it is not. */
58
+ readonly reason?: string;
59
+ }
60
+ /**
61
+ * Set up and list a batch of repositories: `init` where there is no config,
62
+ * then add each one to the served list — ONE read and ONE write of the list,
63
+ * so a batch of forty is not forty rewrites racing the supervisor's reads.
64
+ *
65
+ * A repository `init` could not draft is not added: a listed repository with
66
+ * no config is one the supervisor would skip and complain about every minute.
67
+ *
68
+ * Throws when the list cannot be read (corrupt is loud — see `readRegistry`).
69
+ */
70
+ export declare function provisionRepos(paths: readonly string[], deps: ProvisionDeps): ProvisionRow[];
71
+ /** How often the supervisor walks the recorded roots again. */
72
+ export declare const RESCAN_EVERY_MS: number;
73
+ export interface RescanDeps extends ProvisionDeps {
74
+ readonly scanFs: ScanFs;
75
+ log(line: string): void;
76
+ }
77
+ /**
78
+ * Walk the recorded roots and serve what is new.
79
+ *
80
+ * ⚠️ ONLY WHAT IS NEW. A repository already listed is left alone — its config
81
+ * may have been deleted on purpose, and putting a fresh draft back every five
82
+ * minutes would undo that — and one a person `serve remove`d is in `ignored`
83
+ * and stays out. A repository that could not be set up is said once, not
84
+ * every five minutes.
85
+ */
86
+ export declare class RootRescanner {
87
+ private readonly deps;
88
+ private readonly saidFailed;
89
+ constructor(deps: RescanDeps);
90
+ run(): string[];
91
+ }
92
+ export interface ConnectDeps extends ProvisionDeps {
93
+ readonly cwd: string;
94
+ readonly scanFs: ScanFs;
95
+ /** A terminal a person can answer on. */
96
+ readonly interactive: boolean;
97
+ /** Present only when `interactive`. */
98
+ ask?(prompt: string): Promise<string>;
99
+ /** Throws when the identity file is unreadable — that is not "unpaired". */
100
+ paired(): boolean;
101
+ pair(opts: {
102
+ server?: string;
103
+ name?: string;
104
+ }): Promise<number>;
105
+ isRepo(dir: string): boolean;
106
+ /** `looply serve install`. */
107
+ install(): Promise<number>;
108
+ /** The pid of a running supervisor, or null. */
109
+ supervisorPid(): number | null;
110
+ startSupervisor(): {
111
+ ok: true;
112
+ } | {
113
+ ok: false;
114
+ reason: string;
115
+ };
116
+ out(line: string): void;
117
+ err(line: string): void;
118
+ }
119
+ interface ConnectArgs {
120
+ roots: string[];
121
+ yes: boolean;
122
+ noStart: boolean;
123
+ server?: string;
124
+ name?: string;
125
+ }
126
+ export declare function parseConnectArgs(argv: readonly string[]): ConnectArgs | {
127
+ error: string;
128
+ };
129
+ /** Where `connect` suggests looking: the folder that holds this repository, or this folder. */
130
+ export declare function defaultRoot(cwd: string, isRepo: (dir: string) => boolean, platform: Platform): string;
131
+ export declare function connectCommand(argv: readonly string[], deps: ConnectDeps): Promise<number>;
132
+ /** The short table: repository, whether it was set up now, whether it is served. */
133
+ export declare function renderTable(rows: readonly ProvisionRow[]): string[];
134
+ export {};
135
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RootRescanner = exports.RESCAN_EVERY_MS = exports.EXIT_USAGE = exports.EXIT_REFUSED = exports.EXIT_OK = exports.CONNECT_USAGE = void 0;
4
+ exports.provisionRepos = provisionRepos;
5
+ exports.parseConnectArgs = parseConnectArgs;
6
+ exports.defaultRoot = defaultRoot;
7
+ exports.connectCommand = connectCommand;
8
+ exports.renderTable = renderTable;
9
+ const node_path_1 = require("node:path");
10
+ const repo_scan_1 = require("./repo-scan");
11
+ const serve_1 = require("./serve");
12
+ /**
13
+ * `looply connect` — THE ONE COMMAND A PERSON RUNS ONCE PER MACHINE.
14
+ *
15
+ * Before it, putting a machine to work was five commands per repository —
16
+ * `pair`, then in every folder `init`, `serve add`, and finally `serve
17
+ * install` and `serve` — and the repository a person forgot was the one that
18
+ * went quiet. `connect` is those same steps, in that order, over every git
19
+ * repository under the folders a person names:
20
+ *
21
+ * 1. pair, if this machine is not paired yet (the same flow as `looply pair`);
22
+ * 2. choose the code roots — `--root`, else ask, else refuse;
23
+ * 3. find the repositories under them (`repo-scan.ts`);
24
+ * 4. `init` each one that has no config, non-interactively, and `serve add` it;
25
+ * 5. record the roots, so the supervisor finds the next repository by itself;
26
+ * 6. `serve install`, and start the supervisor unless `--no-start`.
27
+ *
28
+ * ⚠️ NOTHING HERE IS A SECOND IMPLEMENTATION. Pairing is `pairCommand`, the
29
+ * draft is `init`'s (`repo-init.ts`), the list is `serve`'s registry, the
30
+ * startup entry is `serve install`. This file only decides which of them to
31
+ * call, on what.
32
+ *
33
+ * ⚠️ AND IT IS CONSENT IN THE SAME SENSE `serve add` IS. Every served
34
+ * repository's daemon runs with `--yes` and registers it with the server
35
+ * without asking; so `connect` shows what it found and asks before serving it
36
+ * — or, with no terminal, refuses unless `--yes` said so up front.
37
+ */
38
+ exports.CONNECT_USAGE = [
39
+ 'looply connect [--root <dir>]... [--yes] [--no-start] [--server <url>]',
40
+ ' pair this machine (if it is not yet), then set up and serve every git repository under each root;',
41
+ ' the supervisor keeps watching the roots for new repositories and clones ones you ask for',
42
+ ].join('\n');
43
+ exports.EXIT_OK = 0;
44
+ exports.EXIT_REFUSED = 1;
45
+ exports.EXIT_USAGE = 64;
46
+ /**
47
+ * Set up and list a batch of repositories: `init` where there is no config,
48
+ * then add each one to the served list — ONE read and ONE write of the list,
49
+ * so a batch of forty is not forty rewrites racing the supervisor's reads.
50
+ *
51
+ * A repository `init` could not draft is not added: a listed repository with
52
+ * no config is one the supervisor would skip and complain about every minute.
53
+ *
54
+ * Throws when the list cannot be read (corrupt is loud — see `readRegistry`).
55
+ */
56
+ function provisionRepos(paths, deps) {
57
+ const file = (0, serve_1.servedFilePath)(deps.home);
58
+ let registry = (0, serve_1.readRegistry)(deps.fs, file);
59
+ const rows = [];
60
+ let changed = false;
61
+ for (const path of paths) {
62
+ const init = deps.initRepo(path);
63
+ if (init.kind === 'failed') {
64
+ rows.push({ path, init: init.kind, served: 'not', reason: init.reason });
65
+ continue;
66
+ }
67
+ const problem = deps.configProblem?.(path) ?? null;
68
+ if (problem !== null) {
69
+ rows.push({
70
+ path,
71
+ init: init.kind,
72
+ served: 'not',
73
+ reason: `.looply/config.yaml does not load (${problem}) — fix it, then \`looply serve add ${path}\``,
74
+ });
75
+ continue;
76
+ }
77
+ const out = (0, serve_1.addRepo)(registry, path, deps.now().toISOString(), deps.platform);
78
+ if (out.registry !== registry)
79
+ changed = true;
80
+ registry = out.registry;
81
+ rows.push({ path, init: init.kind, served: out.added ? 'added' : 'already' });
82
+ }
83
+ if (changed)
84
+ (0, serve_1.writeRegistry)(deps.fs, file, registry);
85
+ return rows;
86
+ }
87
+ /* ───────────────────────────── the supervisor's rescan ──────────────────── */
88
+ /** How often the supervisor walks the recorded roots again. */
89
+ exports.RESCAN_EVERY_MS = 5 * 60_000;
90
+ /**
91
+ * Walk the recorded roots and serve what is new.
92
+ *
93
+ * ⚠️ ONLY WHAT IS NEW. A repository already listed is left alone — its config
94
+ * may have been deleted on purpose, and putting a fresh draft back every five
95
+ * minutes would undo that — and one a person `serve remove`d is in `ignored`
96
+ * and stays out. A repository that could not be set up is said once, not
97
+ * every five minutes.
98
+ */
99
+ class RootRescanner {
100
+ deps;
101
+ saidFailed = new Set();
102
+ constructor(deps) {
103
+ this.deps = deps;
104
+ }
105
+ run() {
106
+ const registry = (0, serve_1.readRegistry)(this.deps.fs, (0, serve_1.servedFilePath)(this.deps.home));
107
+ const roots = (registry.roots ?? []).map((r) => r.path);
108
+ if (roots.length === 0)
109
+ return [];
110
+ const found = (0, repo_scan_1.scanForRepos)(roots, this.deps.scanFs, { join: pathFor(this.deps.platform).join });
111
+ const known = new Set(registry.repos.map((r) => (0, serve_1.repoKey)(r.path, this.deps.platform)));
112
+ const fresh = found.repos.filter((p) => !known.has((0, serve_1.repoKey)(p, this.deps.platform)) &&
113
+ !(0, serve_1.isIgnored)(registry, p, this.deps.platform) &&
114
+ !this.saidFailed.has((0, serve_1.repoKey)(p, this.deps.platform)));
115
+ if (found.capped)
116
+ this.deps.log(`[serve] rescan: stopped at ${repo_scan_1.SCAN_MAX_REPOS} repositories under the roots`);
117
+ if (fresh.length === 0)
118
+ return [];
119
+ const added = [];
120
+ for (const row of provisionRepos(fresh, this.deps)) {
121
+ if (row.served === 'added') {
122
+ added.push(row.path);
123
+ this.deps.log(`[serve] rescan: now serving ${row.path}${row.init === 'initialised' ? ' (drafted .looply/config.yaml)' : ''}`);
124
+ }
125
+ else if (row.served === 'not') {
126
+ this.saidFailed.add((0, serve_1.repoKey)(row.path, this.deps.platform));
127
+ this.deps.log(`[serve] rescan: found ${row.path} but could not set it up — ${row.reason ?? 'unknown'}`);
128
+ }
129
+ }
130
+ return added;
131
+ }
132
+ }
133
+ exports.RootRescanner = RootRescanner;
134
+ function parseConnectArgs(argv) {
135
+ const out = { roots: [], yes: false, noStart: false };
136
+ for (let i = 0; i < argv.length; i += 1) {
137
+ const a = argv[i];
138
+ const value = () => {
139
+ const v = argv[i + 1];
140
+ if (v === undefined || v.startsWith('--'))
141
+ return null;
142
+ i += 1;
143
+ return v;
144
+ };
145
+ if (a === '--yes' || a === '-y')
146
+ out.yes = true;
147
+ else if (a === '--no-start')
148
+ out.noStart = true;
149
+ else if (a === '--root' || a.startsWith('--root=')) {
150
+ const v = a.startsWith('--root=') ? a.slice('--root='.length) : value();
151
+ if (!v)
152
+ return { error: '--root needs a folder' };
153
+ out.roots.push(v);
154
+ }
155
+ else if (a === '--server') {
156
+ const v = value();
157
+ if (!v)
158
+ return { error: '--server needs a URL' };
159
+ out.server = v;
160
+ }
161
+ else if (a === '--name') {
162
+ const v = value();
163
+ if (!v)
164
+ return { error: '--name needs a machine name' };
165
+ out.name = v;
166
+ }
167
+ else
168
+ return { error: `${JSON.stringify(a)} — no idea what that means` };
169
+ }
170
+ return out;
171
+ }
172
+ const pathFor = (platform) => (platform === 'win32' ? node_path_1.win32 : node_path_1.posix);
173
+ /** Where `connect` suggests looking: the folder that holds this repository, or this folder. */
174
+ function defaultRoot(cwd, isRepo, platform) {
175
+ return isRepo(cwd) ? pathFor(platform).dirname(cwd) : cwd;
176
+ }
177
+ async function connectCommand(argv, deps) {
178
+ const args = parseConnectArgs(argv);
179
+ if ('error' in args) {
180
+ deps.err(`looply connect: ${args.error}\n\n${exports.CONNECT_USAGE}`);
181
+ return exports.EXIT_USAGE;
182
+ }
183
+ // Before pairing, because pairing is minutes of somebody's attention and
184
+ // this refusal is certain: with no terminal and no --root there is nobody
185
+ // to ask where the code is.
186
+ if (args.roots.length === 0 && !deps.interactive) {
187
+ deps.err('looply connect: which folders hold your code? There is no terminal to ask on, so name them:');
188
+ deps.err(' looply connect --root <folder> [--root <another>] --yes');
189
+ return exports.EXIT_REFUSED;
190
+ }
191
+ /* 1 ── pair */
192
+ let paired;
193
+ try {
194
+ paired = deps.paired();
195
+ }
196
+ catch (e) {
197
+ deps.err(`looply connect: ${e.message}`);
198
+ return exports.EXIT_REFUSED;
199
+ }
200
+ if (paired) {
201
+ deps.out('connect : this machine is paired.');
202
+ }
203
+ else {
204
+ deps.out('connect : this machine is not paired yet — pairing first.');
205
+ deps.out(' A 6-digit code appears below. Type it into either:');
206
+ deps.out(' • AutoRyn — Integrations → Software execution → "Use Looply through AutoRyn"');
207
+ deps.out(' • the Looply app on your phone');
208
+ let code;
209
+ try {
210
+ code = await deps.pair({
211
+ ...(args.server !== undefined ? { server: args.server } : {}),
212
+ ...(args.name !== undefined ? { name: args.name } : {}),
213
+ });
214
+ }
215
+ catch (e) {
216
+ deps.err(`looply connect: could not pair — ${e.message}. Nothing else was done.`);
217
+ return exports.EXIT_REFUSED;
218
+ }
219
+ if (code !== 0) {
220
+ deps.err('looply connect: not paired, so nothing else was done. Run `looply connect` again when you are ready.');
221
+ return exports.EXIT_REFUSED;
222
+ }
223
+ }
224
+ /* 2 ── roots */
225
+ let rawRoots = args.roots;
226
+ if (rawRoots.length === 0) {
227
+ const suggested = defaultRoot(deps.cwd, deps.isRepo, deps.platform);
228
+ const answer = deps.ask ? (await deps.ask(`Which folder holds your code? [${suggested}] `)).trim() : '';
229
+ rawRoots = [answer === '' ? suggested : answer];
230
+ }
231
+ const roots = [...new Set(rawRoots.map((r) => (0, serve_1.normaliseRepoPath)(r, deps.cwd, deps.platform)))];
232
+ const missing = roots.filter((r) => !deps.fs.isDir(r));
233
+ if (missing.length > 0) {
234
+ for (const m of missing)
235
+ deps.err(`looply connect: ${m} is not a folder`);
236
+ return exports.EXIT_REFUSED;
237
+ }
238
+ /* 3 ── scan */
239
+ const found = (0, repo_scan_1.scanForRepos)(roots, deps.scanFs, { join: pathFor(deps.platform).join });
240
+ deps.out(`connect : found ${found.repos.length} git ${found.repos.length === 1 ? 'repository' : 'repositories'} under ${roots.join(', ')}` +
241
+ ` (up to ${repo_scan_1.SCAN_MAX_DEPTH} folders deep)`);
242
+ if (found.capped) {
243
+ deps.out(` ⚠ stopped at ${repo_scan_1.SCAN_MAX_REPOS}. Name a narrower --root to serve the rest.`);
244
+ }
245
+ for (const u of found.unreadable)
246
+ deps.out(` could not look inside ${u}`);
247
+ let registry;
248
+ try {
249
+ registry = (0, serve_1.readRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home));
250
+ }
251
+ catch (e) {
252
+ deps.err(`looply connect: ${e.message}`);
253
+ return exports.EXIT_REFUSED;
254
+ }
255
+ // A repository the person took out with `serve remove` stays out; connect
256
+ // is not a way to undo that by accident.
257
+ const skipped = found.repos.filter((p) => (0, serve_1.isIgnored)(registry, p, deps.platform));
258
+ const candidates = found.repos.filter((p) => !(0, serve_1.isIgnored)(registry, p, deps.platform));
259
+ for (const s of skipped)
260
+ deps.out(` left out ${s} — you removed it earlier; \`looply serve add\` there to bring it back`);
261
+ /* 4 ── consent, then init + serve add */
262
+ if (candidates.length > 0 && !args.yes) {
263
+ for (const c of candidates)
264
+ deps.out(` ${c}`);
265
+ if (!deps.interactive || !deps.ask) {
266
+ deps.err('looply connect: serving these registers each one with the server. Re-run with --yes to agree.');
267
+ return exports.EXIT_REFUSED;
268
+ }
269
+ const answer = await deps.ask(`Set up and serve ${candidates.length === 1 ? 'this repository' : `these ${candidates.length} repositories`}? Each is registered with the server. [y/N] `);
270
+ if (!/^(y|yes)$/i.test(answer.trim())) {
271
+ deps.out('connect : nothing was set up or served.');
272
+ return exports.EXIT_REFUSED;
273
+ }
274
+ }
275
+ let rows;
276
+ try {
277
+ rows = provisionRepos(candidates, deps);
278
+ /* 5 ── record the roots */
279
+ const after = (0, serve_1.readRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home));
280
+ const withRoots = (0, serve_1.addRoots)(after, roots, deps.now().toISOString(), deps.platform);
281
+ if (withRoots.added.length > 0)
282
+ (0, serve_1.writeRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home), withRoots.registry);
283
+ }
284
+ catch (e) {
285
+ deps.err(`looply connect: ${e.message}`);
286
+ return exports.EXIT_REFUSED;
287
+ }
288
+ if (rows.length > 0)
289
+ for (const line of renderTable(rows))
290
+ deps.out(line);
291
+ deps.out(`connect : watching ${roots.join(', ')} — a repository that appears there later is served within five minutes.`);
292
+ /* 6 ── install + start */
293
+ const installed = await deps.install();
294
+ if (installed !== 0)
295
+ deps.out('connect : could not install the login entry (above); the supervisor will not start at login.');
296
+ if (args.noStart) {
297
+ deps.out('connect : --no-start — the supervisor was not started. `looply serve` starts it.');
298
+ }
299
+ else {
300
+ const pid = deps.supervisorPid();
301
+ if (pid !== null) {
302
+ deps.out(`connect : the supervisor is already running (pid ${pid}); it picks these up within 30 seconds.`);
303
+ }
304
+ else {
305
+ const started = deps.startSupervisor();
306
+ if (started.ok)
307
+ deps.out('connect : started the supervisor in the background.');
308
+ else
309
+ deps.err(`looply connect: could not start the supervisor — ${started.reason}. Run \`looply serve\`.`);
310
+ }
311
+ }
312
+ // A config left for a person to finish is not a failure of `connect`; a
313
+ // repository it could not even draft one in is.
314
+ return rows.some((r) => r.init === 'failed') ? exports.EXIT_REFUSED : exports.EXIT_OK;
315
+ }
316
+ /** The short table: repository, whether it was set up now, whether it is served. */
317
+ function renderTable(rows) {
318
+ const setup = (r) => r.init === 'initialised' ? 'initialised now' : r.init === 'already' ? 'already set up' : 'FAILED';
319
+ const served = (r) => r.served === 'added' ? 'served' : r.served === 'already' ? 'already served' : `not served — ${r.reason ?? ''}`;
320
+ const width = Math.max('repository'.length, ...rows.map((r) => r.path.length));
321
+ const setupWidth = Math.max('setup'.length, ...rows.map((r) => setup(r).length));
322
+ return [
323
+ '',
324
+ ` ${'repository'.padEnd(width)} ${'setup'.padEnd(setupWidth)} served`,
325
+ ...rows.map((r) => ` ${r.path.padEnd(width)} ${setup(r).padEnd(setupWidth)} ${served(r)}`),
326
+ '',
327
+ ];
328
+ }
329
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,8 @@ export interface PairCmdOptions {
21
21
  serverUrl: string;
22
22
  machineName?: string;
23
23
  log: (line: string) => void;
24
+ /** The "what now" line once paired; `connect` carries on by itself, so it says so instead. */
25
+ next?: string;
24
26
  }
25
27
  export declare function pairCommand(opts: PairCmdOptions): Promise<number>;
26
28
  export interface DaemonCmdOptions {
@@ -40,7 +42,14 @@ export interface DaemonCmdOptions {
40
42
  * `(machineId, repoPathHash)` so even a lost cache converges rather than
41
43
  * duplicating.
42
44
  */
43
- export declare function resolveProjectId(store: MachineStore, client: ServerClient, machineId: string, cwd: string, name: string): Promise<string>;
45
+ export declare function resolveProjectId(store: MachineStore, client: ServerClient, machineId: string, cwd: string, name: string,
46
+ /**
47
+ * The checkout's `origin`, normalised, or null. Asked only when a
48
+ * registration is about to happen — a known directory costs no git call —
49
+ * and sent so the server can match this project to a repository somebody
50
+ * named by URL (AutoRyn, a clone request). Absent is ordinary.
51
+ */
52
+ originOf?: () => Promise<string | null>): Promise<string>;
44
53
  /** What the human is being asked to agree to. */
45
54
  export interface RegisterAsk {
46
55
  cwd: string;
@@ -79,7 +88,7 @@ export type ProjectResolution = {
79
88
  * case is unchanged and the question only appears when something new is about to
80
89
  * be created.
81
90
  */
82
- export declare function resolveProjectIdWithConsent(store: MachineStore, client: ServerClient, machineId: string, cwd: string, name: string, gate: RegisterGate): Promise<ProjectResolution>;
91
+ export declare function resolveProjectIdWithConsent(store: MachineStore, client: ServerClient, machineId: string, cwd: string, name: string, gate: RegisterGate, originOf?: () => Promise<string | null>): Promise<ProjectResolution>;
83
92
  /** Blank means no. The safe answer to "shall I create something permanent" is the default one. */
84
93
  export declare function isYes(raw: string): boolean;
85
94
  export declare function renderRegisterAsk(info: RegisterAsk): string;
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-cmd.d.ts","sourceRoot":"","sources":["../src/daemon-cmd.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"daemon-cmd.d.ts","sourceRoot":"","sources":["../src/daemon-cmd.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAiC,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAmC,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAyD,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAKtG,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAgB,MAAM,oBAAoB,CAAC;AAWnE,OAAO,EAAE,aAAa,EAAkB,MAAM,kBAAkB,CAAC;AAOjE,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AA8BxF;;;;;;GAMG;AAEH,eAAO,MAAM,WAAW,UAAU,CAAC;AAKnC,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,8FAA8F;IAC9F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BvE;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kFAAkF;IAClF,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM;AACZ;;;;;GAKG;AACH,QAAQ,GAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAoB,GACxD,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAAA;CAAE,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GACtC,OAAO,CAAC,iBAAiB,CAAC,CAU5B;AAED,kGAAkG;AAClG,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE1C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAa3D;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAUnG;AAED;;;;;;;;;;GAUG;AAGH,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,CAC9B,KAAK,EAAE,YAAY;AACnB,+EAA+E;AAC/E,SAAS,EAAE,MAAM;AACjB,6GAA6G;AAC7G,SAAS,CAAC,EAAE,MAAM,KACf,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,4HACsF,CAAC;AACvH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAKpE;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC3B,OAAO,CAAC,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,aAAa;AACvB;;;;;GAKG;AACH,QAAQ,CAAC,EAAE,eAAe;AAC1B,uFAAuF;AACvF,SAAS,CAAC,EAAE,MAAM;AAClB;;;;;;GAMG;AACH,QAAQ,CAAC,EAAE,YAAY;AACvB;;;;;;;GAOG;AACH,QAAQ,CAAC,EAAE,aAAa;AACxB;;;;;;;;;;;GAWG;AACH,SAAS,CAAC,EAAE,iBAAiB;AAC7B;;;;;;;;;;GAUG;AACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS;AACrD;;;;;GAKG;AACH,YAAY,CAAC,EAAE,MAAM;AACrB;;;;;GAKG;AACH,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CA8UhB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqpC3E;AAkBD,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,MAA8B,GAAG;IAClF,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CA+BP"}
@@ -19,6 +19,7 @@ const server_client_1 = require("./server-client");
19
19
  const daemon_1 = require("./daemon");
20
20
  const signals_1 = require("./signals");
21
21
  const pair_cmd_1 = require("./pair-cmd");
22
+ const repo_origin_1 = require("./repo-origin");
22
23
  const redraw_1 = require("./redraw");
23
24
  const goal_ownership_1 = require("./goal-ownership");
24
25
  const run_launcher_1 = require("./run-launcher");
@@ -103,7 +104,7 @@ async function pairCommand(opts) {
103
104
  opts.log(`pair : gave up — ${result.reason ?? 'unknown'}`);
104
105
  return 1;
105
106
  }
106
- opts.log(' next: `looply daemon` to keep this machine connected.');
107
+ opts.log(opts.next ?? ' next: `looply daemon` to keep this machine connected.');
107
108
  return 0;
108
109
  }
109
110
  /**
@@ -114,12 +115,25 @@ async function pairCommand(opts) {
114
115
  * `(machineId, repoPathHash)` so even a lost cache converges rather than
115
116
  * duplicating.
116
117
  */
117
- async function resolveProjectId(store, client, machineId, cwd, name) {
118
+ async function resolveProjectId(store, client, machineId, cwd, name,
119
+ /**
120
+ * The checkout's `origin`, normalised, or null. Asked only when a
121
+ * registration is about to happen — a known directory costs no git call —
122
+ * and sent so the server can match this project to a repository somebody
123
+ * named by URL (AutoRyn, a clone request). Absent is ordinary.
124
+ */
125
+ originOf = async () => null) {
118
126
  const hash = (0, machine_store_1.repoPathHash)(cwd, sha256);
119
127
  const cached = store.projectFor(hash);
120
128
  if (cached)
121
129
  return cached;
122
- const r = await client.registerProject({ machineId, name, repoPathHash: hash });
130
+ const repoUrl = await originOf().catch(() => null);
131
+ const r = await client.registerProject({
132
+ machineId,
133
+ name,
134
+ repoPathHash: hash,
135
+ ...(repoUrl !== null ? { repoUrl } : {}),
136
+ });
123
137
  store.rememberProject(hash, r.project.id);
124
138
  return r.project.id;
125
139
  }
@@ -134,7 +148,7 @@ async function resolveProjectId(store, client, machineId, cwd, name) {
134
148
  * case is unchanged and the question only appears when something new is about to
135
149
  * be created.
136
150
  */
137
- async function resolveProjectIdWithConsent(store, client, machineId, cwd, name, gate) {
151
+ async function resolveProjectIdWithConsent(store, client, machineId, cwd, name, gate, originOf) {
138
152
  const cached = store.projectFor((0, machine_store_1.repoPathHash)(cwd, sha256));
139
153
  if (cached)
140
154
  return { kind: 'known', projectId: cached };
@@ -144,7 +158,7 @@ async function resolveProjectIdWithConsent(store, client, machineId, cwd, name,
144
158
  if (!(await gate.ask({ cwd, name })))
145
159
  return { kind: 'refused', reason: 'declined' };
146
160
  }
147
- return { kind: 'registered', projectId: await resolveProjectId(store, client, machineId, cwd, name) };
161
+ return { kind: 'registered', projectId: await resolveProjectId(store, client, machineId, cwd, name, originOf) };
148
162
  }
149
163
  /** Blank means no. The safe answer to "shall I create something permanent" is the default one. */
150
164
  function isYes(raw) {
@@ -573,7 +587,7 @@ async function daemonCommand(opts) {
573
587
  const client = new server_client_1.ServerClient({ baseUrl: identity.serverUrl }).withToken(identity.token);
574
588
  let projectId;
575
589
  try {
576
- const resolved = await resolveProjectIdWithConsent(store, client, identity.machineId, opts.cwd, opts.config.project.name, opts.gate ?? {});
590
+ const resolved = await resolveProjectIdWithConsent(store, client, identity.machineId, opts.cwd, opts.config.project.name, opts.gate ?? {}, () => (0, repo_origin_1.readOriginUrl)((0, git_driver_1.nodeGitExec)(opts.cwd)));
577
591
  if (resolved.kind === 'refused') {
578
592
  opts.log(resolved.reason === 'declined'
579
593
  ? 'daemon : nothing registered, nothing started. Run it inside the project you meant.'