@codetreker/daynight 0.6.2 → 0.8.1

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 (46) hide show
  1. package/dist/cli/commands.js +2 -0
  2. package/dist/cli/commands.js.map +1 -1
  3. package/dist/cli/context.d.ts +2 -0
  4. package/dist/cli/context.js +2 -0
  5. package/dist/cli/context.js.map +1 -1
  6. package/dist/cli/prompts.d.ts +9 -0
  7. package/dist/cli/prompts.js +55 -0
  8. package/dist/cli/prompts.js.map +1 -0
  9. package/dist/commands/completion/command.js +14 -6
  10. package/dist/commands/completion/command.js.map +1 -1
  11. package/dist/commands/completion/definition.js +18 -4
  12. package/dist/commands/completion/definition.js.map +1 -1
  13. package/dist/commands/completion/setup.d.ts +21 -0
  14. package/dist/commands/completion/setup.js +210 -0
  15. package/dist/commands/completion/setup.js.map +1 -0
  16. package/dist/commands/project/command.js +23 -2
  17. package/dist/commands/project/command.js.map +1 -1
  18. package/dist/commands/project/definition.js +3 -3
  19. package/dist/commands/project/definition.js.map +1 -1
  20. package/dist/commands/review/command.js +3 -2
  21. package/dist/commands/review/command.js.map +1 -1
  22. package/dist/commands/review/config.js +10 -3
  23. package/dist/commands/review/config.js.map +1 -1
  24. package/dist/commands/review/repositories.d.ts +2 -0
  25. package/dist/commands/review/repositories.js +2 -2
  26. package/dist/commands/review/repositories.js.map +1 -1
  27. package/dist/commands/server/runtime.js +19 -3
  28. package/dist/commands/server/runtime.js.map +1 -1
  29. package/dist/commands/setup/command.d.ts +2 -0
  30. package/dist/commands/setup/command.js +21 -0
  31. package/dist/commands/setup/command.js.map +1 -0
  32. package/dist/commands/setup/definition.d.ts +2 -0
  33. package/dist/commands/setup/definition.js +12 -0
  34. package/dist/commands/setup/definition.js.map +1 -0
  35. package/dist/config/errors.d.ts +9 -0
  36. package/dist/config/errors.js +24 -0
  37. package/dist/config/errors.js.map +1 -0
  38. package/dist/config/files.d.ts +1 -1
  39. package/dist/config/files.js +36 -2
  40. package/dist/config/files.js.map +1 -1
  41. package/dist/config/server.js +2 -1
  42. package/dist/config/server.js.map +1 -1
  43. package/dist/config/setup.d.ts +10 -0
  44. package/dist/config/setup.js +142 -0
  45. package/dist/config/setup.js.map +1 -0
  46. package/package.json +2 -2
@@ -3,7 +3,9 @@ import { reviewDefinition } from "../commands/review/definition.js";
3
3
  import { projectDefinition } from "../commands/project/definition.js";
4
4
  import { taskDefinition } from "../commands/task/definition.js";
5
5
  import { updateDefinition } from "../commands/update/definition.js";
6
+ import { setupDefinition } from "../commands/setup/definition.js";
6
7
  export const commands = [
8
+ { ...setupDefinition, load: async () => ({ run: (await import("../commands/setup/command.js")).runSetupCommand }) },
7
9
  {
8
10
  ...reviewDefinition,
9
11
  load: async () => ({ run: (await import("../commands/review/command.js")).runReviewCommand }),
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAMpE,MAAM,CAAC,MAAM,QAAQ,GAAmC;IACtD;QACE,GAAG,gBAAgB;QACnB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;KAC9F;IACD;QACE,GAAG,gBAAgB;QACnB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;KAC9F;IACD;QACE,GAAG,oBAAoB;QACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC;KACtG;IACD;QACE,GAAG,iBAAiB;QACpB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;KAChG;IACD;QACE,GAAG,cAAc;QACjB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;KAC1F;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,oDAAoD;IACjE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC;IAC/D,OAAO,EAAE;QACP,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE;QAC1E,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,EAAE,SAAS,EAAE;KAC7F;IACD,OAAO,EAAE,kDAAkD;CAC5D,CAAC"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAMlE,MAAM,CAAC,MAAM,QAAQ,GAAmC;IACtD,EAAE,GAAG,eAAe,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,EAAE;IACnH;QACE,GAAG,gBAAgB;QACnB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;KAC9F;IACD;QACE,GAAG,gBAAgB;QACnB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;KAC9F;IACD;QACE,GAAG,oBAAoB;QACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC;KACtG;IACD;QACE,GAAG,iBAAiB;QACpB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;KAChG;IACD;QACE,GAAG,cAAc;QACjB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;KAC1F;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,oDAAoD;IACjE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC;IAC/D,OAAO,EAAE;QACP,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE;QAC1E,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,EAAE,SAAS,EAAE;KAC7F;IACD,OAAO,EAAE,kDAAkD;CAC5D,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { CliPrompt } from "./prompts.js";
1
2
  export type CliContext = {
2
3
  version: string;
3
4
  packageDirectory: string;
@@ -5,6 +6,7 @@ export type CliContext = {
5
6
  workingDirectory: () => string;
6
7
  stdout: (text: string) => void;
7
8
  stderr: (text: string) => void;
9
+ prompt?: CliPrompt;
8
10
  };
9
11
  export type CliCommand = {
10
12
  run: (args: readonly string[], context: CliContext) => Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import { homedir } from "node:os";
2
+ import { createTerminalPrompt } from "./prompts.js";
2
3
  export class UsageError extends Error {
3
4
  helpCommand;
4
5
  constructor(message, helpCommand = "daynight --help") {
@@ -15,5 +16,6 @@ export const createCliContext = (version, packageDirectory) => ({
15
16
  workingDirectory: process.cwd,
16
17
  stdout: (text) => { process.stdout.write(text); },
17
18
  stderr: (text) => { process.stderr.write(text); },
19
+ prompt: createTerminalPrompt(),
18
20
  });
19
21
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAelC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACG,WAAW;IAAjD,YAAY,OAAe,EAAW,WAAW,GAAG,iBAAiB;QACnE,KAAK,CAAC,OAAO,CAAC,CAAC;2BADqB,WAAW;QAE/C,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAA4B,EAAW,EAAE,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC;AAE5G,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,gBAAwB,EAAc,EAAE,CAAC,CAAC;IAC1F,OAAO;IACP,gBAAgB;IAChB,aAAa,EAAE,OAAO;IACtB,gBAAgB,EAAE,OAAO,CAAC,GAAG;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CAClD,CAAC,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAiBpD,MAAM,OAAO,UAAW,SAAQ,KAAK;IACG,WAAW;IAAjD,YAAY,OAAe,EAAW,WAAW,GAAG,iBAAiB;QACnE,KAAK,CAAC,OAAO,CAAC,CAAC;2BADqB,WAAW;QAE/C,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAA4B,EAAW,EAAE,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC;AAE5G,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,gBAAwB,EAAc,EAAE,CAAC,CAAC;IAC1F,OAAO;IACP,gBAAgB;IAChB,aAAa,EAAE,OAAO;IACtB,gBAAgB,EAAE,OAAO,CAAC,GAAG;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,oBAAoB,EAAE;CAC/B,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare class SetupCancelledError extends Error {
2
+ constructor(options?: ErrorOptions);
3
+ }
4
+ export type CliPrompt = {
5
+ readonly isInteractive: boolean;
6
+ ask(question: string, signal: AbortSignal): Promise<string>;
7
+ close(): void;
8
+ };
9
+ export declare const createTerminalPrompt: () => CliPrompt;
@@ -0,0 +1,55 @@
1
+ import { createInterface } from "node:readline";
2
+ export class SetupCancelledError extends Error {
3
+ constructor(options) {
4
+ super("Setup cancelled.", options);
5
+ this.name = "SetupCancelledError";
6
+ }
7
+ }
8
+ export const createTerminalPrompt = () => {
9
+ let terminal;
10
+ let closed = false;
11
+ const lines = [];
12
+ let waiting;
13
+ const cancel = () => {
14
+ closed = true;
15
+ waiting?.reject(new SetupCancelledError());
16
+ waiting = undefined;
17
+ };
18
+ return {
19
+ isInteractive: process.stdin.isTTY === true && process.stderr.isTTY === true,
20
+ ask: async (question, signal) => {
21
+ signal.throwIfAborted();
22
+ if (closed)
23
+ throw new SetupCancelledError();
24
+ if (terminal === undefined) {
25
+ terminal = createInterface({ input: process.stdin, output: process.stderr, terminal: true });
26
+ terminal.on("line", (line) => {
27
+ if (waiting === undefined)
28
+ lines.push(line);
29
+ else {
30
+ const pending = waiting;
31
+ waiting = undefined;
32
+ pending.resolve(line);
33
+ }
34
+ });
35
+ terminal.on("close", cancel);
36
+ terminal.on("SIGINT", cancel);
37
+ }
38
+ process.stderr.write(question);
39
+ if (lines.length !== 0)
40
+ return lines.shift();
41
+ return new Promise((resolve, reject) => {
42
+ const abort = () => { waiting = undefined; reject(new SetupCancelledError({ cause: signal.reason })); };
43
+ waiting = {
44
+ resolve: (line) => { signal.removeEventListener("abort", abort); resolve(line); },
45
+ reject: (cause) => { signal.removeEventListener("abort", abort); reject(cause); },
46
+ };
47
+ signal.addEventListener("abort", abort, { once: true });
48
+ if (signal.aborted)
49
+ abort();
50
+ });
51
+ },
52
+ close: () => { closed = true; terminal?.close(); },
53
+ };
54
+ };
55
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"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"}
@@ -5,16 +5,24 @@ import { renderBashCompletion } from "./bash.js";
5
5
  import { renderZshCompletion } from "./zsh.js";
6
6
  export const runCompletionCommand = async (args, context) => {
7
7
  const commandPath = [commandTree.name, completionDefinition.name];
8
- if (args.length === 0) {
9
- context.stdout(renderCommandHelp(completionDefinition, commandPath));
10
- return;
11
- }
12
8
  const parsed = parseCommand(completionDefinition, args, commandPath);
13
9
  if (parsed.kind !== "run") {
14
- context.stdout(renderCommandHelp(completionDefinition, commandPath));
10
+ context.stdout(renderCommandHelp(parsed.command, parsed.path));
11
+ return;
12
+ }
13
+ if (parsed.command.name === "setup") {
14
+ const shell = parsed.options.get("--shell");
15
+ const rcFile = parsed.options.get("--rc-file");
16
+ const { setupCompletion } = await import("./setup.js");
17
+ const result = await setupCompletion({ shell, rcFile }, context);
18
+ for (const file of result.files)
19
+ context.stdout(`Completion configuration ${file.installed ? "installed" : "already present"}: ${file.path}\n`);
20
+ if (result.shell === "zsh")
21
+ context.stdout("Initialize compinit in the current shell if needed: autoload -Uz compinit; compinit\n");
22
+ context.stdout(`Activate completion in the current shell:\n source <(daynight completion ${result.shell})\n`);
15
23
  return;
16
24
  }
17
- const render = parsed.values[0] === "bash" ? renderBashCompletion : renderZshCompletion;
25
+ const render = parsed.command.name === "bash" ? renderBashCompletion : renderZshCompletion;
18
26
  context.stdout(render(commandTree));
19
27
  };
20
28
  //# sourceMappingURL=command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/completion/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAuB,EAAE,OAAmB,EAAiB,EAAE;IACxG,MAAM,WAAW,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACxF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AACtC,CAAC,CAAC"}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/completion/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAuB,EAAE,OAAmB,EAAiB,EAAE;IACxG,MAAM,WAAW,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAgC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAuB,CAAC;QACrE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;QACjE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAChJ,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,uFAAuF,CAAC,CAAC;QACpI,OAAO,CAAC,MAAM,CAAC,6EAA6E,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC;QAC/G,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAC3F,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AACtC,CAAC,CAAC"}
@@ -1,8 +1,22 @@
1
+ const help = { names: ["-h", "--help"], description: "Show this help", action: "help" };
1
2
  export const completionDefinition = {
2
3
  name: "completion",
3
- description: "Generate shell completion for Bash or zsh",
4
- arguments: [{ name: "shell", description: "Shell to generate completion for (bash or zsh)", choices: ["bash", "zsh"] }],
5
- options: [{ names: ["-h", "--help"], description: "Show this help", action: "help" }],
6
- details: "Bash >=4.2: add source <(daynight completion bash) to ~/.bashrc.\nzsh: add source <(daynight completion zsh) after compinit in ~/.zshrc.\nReload the script in existing shells after updating daynight.",
4
+ description: "Generate or install shell completion for Bash or zsh",
5
+ commands: [
6
+ { name: "bash", description: "Generate Bash >=4.2 completion", options: [help] },
7
+ { name: "zsh", description: "Generate native zsh completion", options: [help] },
8
+ {
9
+ name: "setup",
10
+ description: "Install completion in shell startup files",
11
+ options: [
12
+ { names: ["--shell"], description: "Select the shell instead of detecting the calling shell", value: { name: "shell", kind: "text", choices: ["bash", "zsh"] } },
13
+ { names: ["--rc-file"], description: "Manage only this startup file", value: { name: "path", kind: "text" } },
14
+ help,
15
+ ],
16
+ details: "Without --shell, detect the calling Bash or zsh process.\nBash setup covers ~/.bashrc and the first existing login profile.\nzsh setup uses $ZDOTDIR/.zshrc, or ~/.zshrc when ZDOTDIR is unset.\nSetup installs startup configuration; activate the current shell with source <(daynight completion bash|zsh).",
17
+ },
18
+ ],
19
+ options: [help],
20
+ details: "Bash >=4.2: source <(daynight completion bash).\nzsh: initialize compinit, then source <(daynight completion zsh).\nRun daynight completion setup to install startup configuration.\nReload the script in existing shells after updating daynight.",
7
21
  };
8
22
  //# sourceMappingURL=definition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../src/commands/completion/definition.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,2CAA2C;IACxD,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,gDAAgD,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;IACvH,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACrF,OAAO,EAAE,yMAAyM;CACnN,CAAC"}
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../src/commands/completion/definition.ts"],"names":[],"mappings":"AAEA,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAW,CAAC;AAEjG,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE;QACR,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;QAChF,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,gCAAgC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;QAC/E;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,2CAA2C;YACxD,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,yDAAyD,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;gBAChK,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC7G,IAAI;aACL;YACD,OAAO,EAAE,gTAAgT;SAC1T;KACF;IACD,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,OAAO,EAAE,oPAAoP;CAC9P,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { CliContext } from "../../cli/context.js";
2
+ export type CompletionShell = "bash" | "zsh";
3
+ type SetupOptions = {
4
+ shell: CompletionShell | undefined;
5
+ rcFile: string | undefined;
6
+ };
7
+ type SetupResult = {
8
+ shell: CompletionShell;
9
+ files: {
10
+ path: string;
11
+ installed: boolean;
12
+ }[];
13
+ };
14
+ export type SetupDependencies = {
15
+ environment: NodeJS.ProcessEnv;
16
+ callingShell: () => Promise<CompletionShell | undefined>;
17
+ };
18
+ export declare const detectCallingShell: () => Promise<CompletionShell | undefined>;
19
+ export declare const renderSetupBlock: (shell: CompletionShell) => string;
20
+ export declare const setupCompletion: (options: SetupOptions, context: Pick<CliContext, "homeDirectory" | "workingDirectory">, dependencies?: SetupDependencies) => Promise<SetupResult>;
21
+ export {};
@@ -0,0 +1,210 @@
1
+ import { execFile } from "node:child_process";
2
+ import { constants } from "node:fs";
3
+ import { access, lstat, mkdir, open, readFile, realpath, unlink } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { setTimeout } from "node:timers/promises";
7
+ import { UsageError } from "../../cli/context.js";
8
+ const execute = promisify(execFile);
9
+ const begin = "# >>> daynight completion >>>";
10
+ const end = "# <<< daynight completion <<<";
11
+ const isMissing = (error) => error.code === "ENOENT";
12
+ export const detectCallingShell = async () => {
13
+ if (process.platform === "win32")
14
+ return undefined;
15
+ const { stdout } = await execute("ps", ["-p", String(process.ppid), "-o", "comm="], { timeout: 3_000, encoding: "utf8" });
16
+ const name = path.basename(stdout.trim()).replace(/^-/, "");
17
+ return name === "bash" || name === "zsh" ? name : undefined;
18
+ };
19
+ const loadScript = (shell, indent) => [
20
+ `if __daynight_completion_script="$(daynight completion ${shell})"; then`,
21
+ ' if eval "$__daynight_completion_script"; then',
22
+ ' unset __daynight_completion_script',
23
+ ' else',
24
+ ' __daynight_completion_status=$?',
25
+ ' unset __daynight_completion_script',
26
+ ' return "$__daynight_completion_status"',
27
+ ' fi',
28
+ 'else',
29
+ ' __daynight_completion_status=$?',
30
+ ' unset __daynight_completion_script',
31
+ ' return "$__daynight_completion_status"',
32
+ 'fi',
33
+ ].map((line) => `${indent}${line}`);
34
+ export const renderSetupBlock = (shell) => {
35
+ const lines = shell === "bash" ? [
36
+ begin,
37
+ 'if [ -n "${BASH_VERSION-}" ]; then',
38
+ ' case $- in',
39
+ ' *i*)',
40
+ ' if ! declare -F _daynight_completion >/dev/null || [ "$(complete -p daynight 2>/dev/null)" != \'complete -F _daynight_completion daynight\' ]; then',
41
+ ...loadScript(shell, " "),
42
+ ' fi',
43
+ ' ;;',
44
+ ' esac',
45
+ 'fi',
46
+ end,
47
+ ] : [
48
+ begin,
49
+ 'if [[ -o interactive ]]; then',
50
+ ' if (( $+functions[compdef] )) || { autoload -Uz compinit && compinit; }; then',
51
+ ' if [[ "${_comps[daynight]-}" != _daynight ]] || (( ! $+functions[_daynight] )); then',
52
+ ...loadScript(shell, " "),
53
+ ' fi',
54
+ ' else',
55
+ ' return $?',
56
+ ' fi',
57
+ 'fi',
58
+ end,
59
+ ];
60
+ return `${lines.join("\n")}\n`;
61
+ };
62
+ const configured = (content, shell, file) => {
63
+ const lines = content.toString("utf8").split(/\r?\n/);
64
+ const starts = lines.flatMap((line, index) => line.includes(begin) ? [index] : []);
65
+ const ends = lines.flatMap((line, index) => line.includes(end) ? [index] : []);
66
+ if (starts.length !== 0 || ends.length !== 0) {
67
+ if (starts.length !== 1 || ends.length !== 1 || starts[0] >= ends[0]) {
68
+ throw new Error(`Malformed or duplicate daynight completion block in ${file}. Remove or repair its markers before running setup.`);
69
+ }
70
+ const block = lines.slice(starts[0], ends[0] + 1).join("\n");
71
+ if (block !== renderSetupBlock(shell).trimEnd())
72
+ throw new Error(`Unrecognized daynight completion block in ${file}. Remove or repair it before running setup.`);
73
+ return true;
74
+ }
75
+ return lines.some((line) => line.trim() === `source <(daynight completion ${shell})`);
76
+ };
77
+ const targetPath = async (file) => {
78
+ try {
79
+ const info = await lstat(file);
80
+ if (info.isSymbolicLink()) {
81
+ const resolved = await realpath(file);
82
+ if (!(await lstat(resolved)).isFile())
83
+ throw new Error(`Completion startup target is not a regular file: ${file}`);
84
+ return resolved;
85
+ }
86
+ if (!info.isFile())
87
+ throw new Error(`Completion startup target is not a regular file: ${file}`);
88
+ return file;
89
+ }
90
+ catch (error) {
91
+ if (isMissing(error)) {
92
+ // A dangling link is not a new startup file: creating through it hides a broken configuration.
93
+ try {
94
+ await lstat(file);
95
+ }
96
+ catch (missing) {
97
+ if (isMissing(missing))
98
+ return file;
99
+ throw missing;
100
+ }
101
+ }
102
+ throw error;
103
+ }
104
+ };
105
+ const acquireLock = async (file) => {
106
+ for (let attempt = 0;; attempt += 1) {
107
+ try {
108
+ return await open(file, "wx", 0o600);
109
+ }
110
+ catch (error) {
111
+ if (error.code !== "EEXIST" || attempt === 40) {
112
+ throw new Error(`Cannot lock completion startup file. Another setup may be running; inspect ${file}.`, { cause: error });
113
+ }
114
+ await setTimeout(50);
115
+ }
116
+ }
117
+ };
118
+ const install = async (file, shell) => {
119
+ const resolved = await targetPath(file);
120
+ try {
121
+ if (configured(await readFile(resolved), shell, file))
122
+ return false;
123
+ }
124
+ catch (error) {
125
+ if (!isMissing(error))
126
+ throw error;
127
+ }
128
+ await mkdir(path.dirname(resolved), { recursive: true });
129
+ const lockPath = `${resolved}.daynight-completion.lock`;
130
+ const lock = await acquireLock(lockPath);
131
+ try {
132
+ if (await targetPath(file) !== resolved)
133
+ throw new Error(`Completion startup target changed during setup: ${file}`);
134
+ // Append keeps existing bytes, mode and symlink identity, including concurrent unrelated appends.
135
+ const handle = await open(resolved, constants.O_RDWR | constants.O_CREAT | constants.O_APPEND | constants.O_NOFOLLOW, 0o666);
136
+ try {
137
+ const before = await handle.stat();
138
+ if (!before.isFile())
139
+ throw new Error(`Completion startup target is not a regular file: ${file}`);
140
+ const content = await handle.readFile();
141
+ if (configured(content, shell, file))
142
+ return false;
143
+ const current = await lstat(resolved);
144
+ if (await targetPath(file) !== resolved || current.dev !== before.dev || current.ino !== before.ino || current.size !== before.size || current.mtimeMs !== before.mtimeMs) {
145
+ throw new Error(`Completion startup file changed during setup; run setup again: ${file}`);
146
+ }
147
+ const separator = content.length === 0 || content.at(-1) === 10 ? "" : "\n";
148
+ await handle.writeFile(`${separator}${renderSetupBlock(shell)}`);
149
+ await handle.sync();
150
+ return true;
151
+ }
152
+ finally {
153
+ await handle.close();
154
+ }
155
+ }
156
+ catch (error) {
157
+ throw new Error(`Cannot configure completion in ${file}.`, { cause: error });
158
+ }
159
+ finally {
160
+ await lock.close();
161
+ await unlink(lockPath);
162
+ }
163
+ };
164
+ const bashTargets = async (home) => {
165
+ let unreadable;
166
+ for (const name of [".bash_profile", ".bash_login", ".profile"]) {
167
+ const file = path.join(home, name);
168
+ try {
169
+ await lstat(file);
170
+ }
171
+ catch (error) {
172
+ if (isMissing(error))
173
+ continue;
174
+ throw error;
175
+ }
176
+ try {
177
+ await access(file, constants.R_OK);
178
+ return [path.join(home, ".bashrc"), file];
179
+ }
180
+ catch (error) {
181
+ if (error.code !== "EACCES")
182
+ throw error;
183
+ unreadable = error;
184
+ }
185
+ }
186
+ if (unreadable !== undefined)
187
+ throw new Error("No existing Bash login profile is readable. Make a profile readable before running setup.", { cause: unreadable });
188
+ return [path.join(home, ".bashrc"), path.join(home, ".bash_profile")];
189
+ };
190
+ export const setupCompletion = async (options, context, dependencies = { environment: process.env, callingShell: detectCallingShell }) => {
191
+ let shell = options.shell;
192
+ if (shell === undefined) {
193
+ try {
194
+ shell = await dependencies.callingShell();
195
+ }
196
+ catch (error) {
197
+ throw new Error("Cannot detect the calling shell. Specify --shell bash or --shell zsh.", { cause: error });
198
+ }
199
+ }
200
+ if (shell === undefined)
201
+ throw new UsageError("Cannot identify the calling Bash or zsh shell. Specify --shell bash or --shell zsh.", "daynight completion setup --help");
202
+ const targets = options.rcFile !== undefined ? [path.resolve(context.workingDirectory(), options.rcFile)] : shell === "bash"
203
+ ? await bashTargets(context.homeDirectory())
204
+ : [path.resolve(context.workingDirectory(), `${dependencies.environment.ZDOTDIR === undefined ? context.homeDirectory() : dependencies.environment.ZDOTDIR}/.zshrc`)];
205
+ const files = [];
206
+ for (const file of targets)
207
+ files.push({ path: file, installed: await install(file, shell) });
208
+ return { shell, files };
209
+ };
210
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/commands/completion/setup.ts"],"names":[],"mappings":"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"}
@@ -22,17 +22,38 @@ export const runProjectCommand = async (args, context, dependencies = defaultDep
22
22
  if (projectId === undefined)
23
23
  throw new UsageError("project-id must be a hyphenated UUID.", "daynight project show --help");
24
24
  }
25
- await dependencies.runServerCommand(context, async ({ api }) => {
25
+ await dependencies.runServerCommand(context, async ({ api, operation }) => {
26
+ operation.check();
26
27
  const { renderProject, renderProjectJson, renderProjectList } = await import("./rendering.js");
28
+ operation.check();
27
29
  if (command.command.name === "create") {
28
- const project = await api.createProject({ name: name, repoUrl: command.options.get("--repo") });
30
+ const { repositoryIdentity } = await import("../../repository/identity.js");
31
+ operation.check();
32
+ const explicitRepo = command.options.get("--repo");
33
+ const repoUrl = explicitRepo === undefined
34
+ ? (await (await import("../../repository/git.js")).discoverRepository(context.workingDirectory(), operation)).remote
35
+ : explicitRepo;
36
+ operation.check();
37
+ const identity = repositoryIdentity(repoUrl);
38
+ const projects = await api.listProjects();
39
+ operation.check();
40
+ const matches = projects.filter((project) => repositoryIdentity(project.repoUrl) === identity);
41
+ operation.check();
42
+ if (matches.length > 1)
43
+ throw new Error(`Multiple projects match this repository (${matches.map(({ id }) => id).join(", ")}); choose an existing project by its ID.`);
44
+ if (matches.length === 1)
45
+ return `Project already exists.\n${renderProject(matches[0])}`;
46
+ const project = await api.createProject({ name: name, repoUrl });
47
+ operation.check();
29
48
  return `Project created.\n${renderProject(project)}`;
30
49
  }
31
50
  if (command.command.name === "list") {
32
51
  const projects = await api.listProjects();
52
+ operation.check();
33
53
  return command.options.has("--json") ? renderProjectJson(projects) : renderProjectList(projects);
34
54
  }
35
55
  const project = await api.getProject(projectId);
56
+ operation.check();
36
57
  return command.options.has("--json") ? renderProjectJson(project) : renderProject(project);
37
58
  });
38
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/project/command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/project/command.ts"],"names":[],"mappings":"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"}
@@ -6,14 +6,14 @@ export const projectDefinition = {
6
6
  commands: [
7
7
  {
8
8
  name: "create",
9
- description: "Create a project with its name and repository address",
9
+ description: "Create a project unless its repository is already registered",
10
10
  arguments: [{ name: "name", description: "Project name" }],
11
11
  allowOptionsTerminator: true,
12
12
  options: [
13
- { names: ["--repo"], description: "Repository address to register", value: { name: "repo", kind: "text" }, required: true },
13
+ { names: ["--repo"], description: "Repository address (defaults to the current Git origin)", value: { name: "repo", kind: "text" } },
14
14
  helpOption,
15
15
  ],
16
- details: "Submit the original name and repository address to the configured server.\nProject creation does not depend on the current Git repository.\nFor a name beginning with a dash, put options first and use -- before the name.",
16
+ details: "Without --repo, use the current Git worktree's effective origin fetch address.\nAn explicit --repo works outside Git and overrides the current repository.\nRead all server projects and return an existing project with an equivalent repository address.\nMultiple matching projects require choosing an existing project by its ID.\nOtherwise, submit the original name and repository address to the configured server.\nFor a name beginning with a dash, put options first and use -- before the name.",
17
17
  },
18
18
  {
19
19
  name: "list",
@@ -1 +1 @@
1
- {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../src/commands/project/definition.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAkB,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7G,MAAM,UAAU,GAAkB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;AAErH,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,oDAAoD;IACjE,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,uDAAuD;YACpE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;YAC1D,sBAAsB,EAAE,IAAI;YAC5B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC3H,UAAU;aACX;YACD,OAAO,EAAE,6NAA6N;SACvO;QACD;YACE,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,4CAA4C;YACzD,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,OAAO,EAAE,gHAAgH;SAC1H;QACD;YACE,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,0BAA0B;YACvC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,OAAO,EAAE,oHAAoH;SAC9H;KACF;IACD,OAAO,EAAE,CAAC,UAAU,CAAC;IACrB,OAAO,EAAE,uGAAuG;CACjH,CAAC"}
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../src/commands/project/definition.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAkB,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7G,MAAM,UAAU,GAAkB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;AAErH,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,oDAAoD;IACjE,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,8DAA8D;YAC3E,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;YAC1D,sBAAsB,EAAE,IAAI;YAC5B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,yDAAyD,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBACpI,UAAU;aACX;YACD,OAAO,EAAE,+eAA+e;SACzf;QACD;YACE,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,4CAA4C;YACzD,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,OAAO,EAAE,gHAAgH;SAC1H;QACD;YACE,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,0BAA0B;YACvC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,OAAO,EAAE,oHAAoH;SAC9H;KACF;IACD,OAAO,EAAE,CAAC,UAAU,CAAC;IACrB,OAAO,EAAE,uGAAuG;CACjH,CAAC"}
@@ -2,10 +2,11 @@ import { parseCommand, renderCommandHelp } from "../../cli/schema.js";
2
2
  import { UsageError } from "../../cli/context.js";
3
3
  import { reviewDefinition } from "./definition.js";
4
4
  import { resolveReviewPaths } from "./paths.js";
5
+ import { guideMissingConfiguration } from "../../config/setup.js";
5
6
  const defaultDependencies = (context) => ({
6
7
  addRepository: async (...args) => (await import("./repositories.js")).addRepository(...args),
7
- listReviews: async (paths) => (await import("./listing.js")).listReviews(paths),
8
- loadConfiguration: async (paths) => (await import("./config.js")).loadConfiguration(paths),
8
+ listReviews: async (paths) => guideMissingConfiguration(context, "review", async () => (await import("./listing.js")).listReviews(paths)),
9
+ loadConfiguration: async (paths) => guideMissingConfiguration(context, "review", async () => (await import("./config.js")).loadConfiguration(paths)),
9
10
  runReview: async (configuration, paths) => {
10
11
  const { formatCoordinatorEvent, runForegroundReview } = await import("./runtime.js");
11
12
  await runForegroundReview(configuration, paths, {
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/review/command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/commands/review/command.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { parseConfigurationDocument } from "../../config/document.js";
3
3
  import { readConfigurationSource } from "../../config/files.js";
4
+ import { MissingConfigurationFieldError } from "../../config/errors.js";
4
5
  import { ancestorIdentities, missingPathsReferToSameDirectory, pathsEqual, pathsOverlap, resolvePhysicalDirectory } from "../../platform/filesystem.js";
5
6
  export const defaultRepositoryRoot = "~/daynights";
6
7
  export const configurationDefaults = {
@@ -155,7 +156,7 @@ const parseReviewConfiguration = (source, runtimePaths, pathApi, allowMissingRep
155
156
  if (allowMissingRepositories) {
156
157
  return { ...settings, repositories: [] };
157
158
  }
158
- throw new Error("Review repositories are not configured; use daynight review add-repo.");
159
+ throw new MissingConfigurationFieldError("repositories", "Review repositories are not configured; use daynight setup --review-repo <remote> or daynight review add-repo.");
159
160
  }
160
161
  if (!Array.isArray(mapping.repositories) || mapping.repositories.length === 0) {
161
162
  throw new Error("repositories must be a nonempty sequence.");
@@ -205,8 +206,14 @@ const validatePhysicalRepositoryPaths = async (configuration, stateDirectory, re
205
206
  const stateAncestors = await ancestryOf(stateDirectory);
206
207
  for (const [index, directory] of repositoryDirectories.entries()) {
207
208
  const repositoryAncestors = await ancestryOf(directory);
208
- if (repositoryAncestors.has(stateDirectory.ancestorIdentity) ||
209
- (directory.missingComponents.length === 0 && stateAncestors.has(directory.ancestorIdentity))) {
209
+ const sharedAncestor = directory.ancestorIdentity === stateDirectory.ancestorIdentity;
210
+ const prefixLength = Math.min(directory.missingComponents.length, stateDirectory.missingComponents.length);
211
+ const statePrefix = stateDirectory.missingComponents.slice(0, prefixLength);
212
+ const repositoryPrefix = directory.missingComponents.slice(0, prefixLength);
213
+ const sharedMissingPrefix = sharedAncestor && (statePrefix.every((component, componentIndex) => component === repositoryPrefix[componentIndex]) ||
214
+ await missingPathsReferToSameDirectory(directory.ancestorPath, statePrefix, repositoryPrefix));
215
+ if ((stateDirectory.missingComponents.length === 0 && repositoryAncestors.has(stateDirectory.ancestorIdentity)) ||
216
+ (directory.missingComponents.length === 0 && stateAncestors.has(directory.ancestorIdentity)) || sharedMissingPrefix) {
210
217
  throw new Error(`repositories[${index}].path must not overlap the state directory ${statePath}.`);
211
218
  }
212
219
  for (const [previousIndex, previous] of repositoryDirectories.slice(0, index).entries()) {