Merge branch 'workstream-n-completion'
Resolve conflict: use --compile for both CLI binaries Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"reviq": "./dist/reviq"
|
||||
"reviq": "./dist/reviq",
|
||||
"__reviq_bash_complete": "./dist/bash-complete"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "bun build src/bin/reviq.ts --compile --outfile dist/reviq",
|
||||
"build": "bun build src/bin/reviq.ts --compile --outfile dist/reviq && bun build src/bin/bash-complete.ts --compile --outfile dist/bash-complete",
|
||||
"cli": "bun run src/bin/reviq.ts",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint . --cache",
|
||||
@@ -15,6 +16,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@stricli/core": "^1.2.5",
|
||||
"@stricli/auto-complete": "^1.0.0",
|
||||
"@reviq/db": "workspace:*",
|
||||
"@noble/hashes": "^2.0.1"
|
||||
},
|
||||
|
||||
9
apps/cli/src/app.ts
Normal file
9
apps/cli/src/app.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { buildApplication } from "@stricli/core";
|
||||
import { rootRouteMap } from "./routes/_command.js";
|
||||
|
||||
export const app = buildApplication(rootRouteMap, {
|
||||
name: "reviq",
|
||||
versionInfo: {
|
||||
currentVersion: "0.0.0",
|
||||
},
|
||||
});
|
||||
22
apps/cli/src/bin/bash-complete.ts
Normal file
22
apps/cli/src/bin/bash-complete.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import type { LocalContext } from "../context.js";
|
||||
import { proposeCompletions } from "@stricli/core";
|
||||
import { app } from "../app.js";
|
||||
|
||||
const inputs = process.argv.slice(3);
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars -- COMP_LINE is set by bash completion
|
||||
if (process.env.COMP_LINE?.endsWith(" ")) {
|
||||
inputs.push("");
|
||||
}
|
||||
|
||||
const context: LocalContext = { process };
|
||||
|
||||
try {
|
||||
const completions = await proposeCompletions(app, inputs, context);
|
||||
for (const { completion } of completions) {
|
||||
process.stdout.write(`${completion}\n`);
|
||||
}
|
||||
} catch {
|
||||
// Silently ignore errors during completion
|
||||
}
|
||||
@@ -1,15 +1,8 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import type { LocalContext } from "../context.js";
|
||||
import { buildApplication, run } from "@stricli/core";
|
||||
import { rootRouteMap } from "../routes/_command.js";
|
||||
|
||||
const app = buildApplication(rootRouteMap, {
|
||||
name: "reviq",
|
||||
versionInfo: {
|
||||
currentVersion: "0.0.0",
|
||||
},
|
||||
});
|
||||
import { run } from "@stricli/core";
|
||||
import { app } from "../app.js";
|
||||
|
||||
const context: LocalContext = {
|
||||
process,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { buildRouteMap } from "@stricli/core";
|
||||
import { authRouteMap } from "./auth/_command.js";
|
||||
import { bootstrapCommand } from "./bootstrap.js";
|
||||
import { completionsCommand } from "./completions.js";
|
||||
import { orgRouteMap } from "./org/_command.js";
|
||||
import { userRouteMap } from "./user/_command.js";
|
||||
|
||||
@@ -10,6 +11,7 @@ export const rootRouteMap = buildRouteMap({
|
||||
auth: authRouteMap,
|
||||
user: userRouteMap,
|
||||
org: orgRouteMap,
|
||||
completions: completionsCommand,
|
||||
},
|
||||
docs: {
|
||||
brief: "RevIQ CLI for database and user management",
|
||||
|
||||
104
apps/cli/src/routes/completions.ts
Normal file
104
apps/cli/src/routes/completions.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { LocalContext } from "../context.js";
|
||||
import { buildCommand } from "@stricli/core";
|
||||
|
||||
type Shell = "bash" | "zsh" | "fish";
|
||||
|
||||
const SUPPORTED_SHELLS: readonly Shell[] = ["bash", "zsh", "fish"] as const;
|
||||
|
||||
function parseShell(value: string): Shell {
|
||||
const shell = value.toLowerCase();
|
||||
if (!SUPPORTED_SHELLS.includes(shell as Shell)) {
|
||||
throw new Error(
|
||||
`Invalid shell: ${value}. Supported shells: ${SUPPORTED_SHELLS.join(", ")}`,
|
||||
);
|
||||
}
|
||||
return shell as Shell;
|
||||
}
|
||||
|
||||
const ZSH_COMPLETION_SCRIPT = `#compdef reviq
|
||||
|
||||
_reviq() {
|
||||
local -a completions
|
||||
local -a words_to_complete
|
||||
|
||||
# Build array of words up to cursor
|
||||
words_to_complete=("\${words[@]:1:$((CURRENT-1))}")
|
||||
|
||||
# Add empty string if we're completing a new word
|
||||
if [[ -z "\${words[CURRENT]}" ]] || [[ "\${BUFFER}" == *" " ]]; then
|
||||
words_to_complete+=("")
|
||||
fi
|
||||
|
||||
# Call the completion helper
|
||||
completions=(\${(f)"$(COMP_LINE="$BUFFER" __reviq_bash_complete reviq "\${words_to_complete[@]}" 2>/dev/null)"})
|
||||
|
||||
if [[ \${#completions[@]} -gt 0 ]]; then
|
||||
_describe 'command' completions
|
||||
fi
|
||||
}
|
||||
|
||||
_reviq "$@"
|
||||
`;
|
||||
|
||||
function completions(
|
||||
this: LocalContext,
|
||||
_flags: Record<string, never>,
|
||||
shell: Shell,
|
||||
): void {
|
||||
// biome-ignore lint/nursery/noUnnecessaryConditions: switch on union type is valid
|
||||
switch (shell) {
|
||||
case "bash":
|
||||
console.log("To enable bash completions for reviq, run:\n");
|
||||
console.log(
|
||||
" npx @stricli/auto-complete install reviq --bash __reviq_bash_complete\n",
|
||||
);
|
||||
console.log(
|
||||
"This will modify your ~/.bashrc to enable tab completion for reviq commands.",
|
||||
);
|
||||
console.log("\nTo uninstall, run:\n");
|
||||
console.log(" npx @stricli/auto-complete uninstall reviq --bash");
|
||||
break;
|
||||
|
||||
case "zsh":
|
||||
console.log("# Add the following to your ~/.zshrc:\n");
|
||||
console.log(ZSH_COMPLETION_SCRIPT);
|
||||
console.log("\n# Or save to a file and source it:");
|
||||
console.log(
|
||||
"# reviq completions zsh > ~/.config/reviq/completions.zsh",
|
||||
);
|
||||
console.log(
|
||||
'# echo "source ~/.config/reviq/completions.zsh" >> ~/.zshrc',
|
||||
);
|
||||
break;
|
||||
|
||||
case "fish":
|
||||
console.log(`Shell completions for ${shell} are not yet supported.`);
|
||||
console.log(
|
||||
"\nCurrently only bash and zsh are supported. fish support is planned.",
|
||||
);
|
||||
this.process.exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export const completionsCommand = buildCommand({
|
||||
func: completions,
|
||||
parameters: {
|
||||
flags: {},
|
||||
positional: {
|
||||
kind: "tuple",
|
||||
parameters: [
|
||||
{
|
||||
brief: "Shell to generate completions for (bash, zsh, fish)",
|
||||
parse: parseShell,
|
||||
placeholder: "shell",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
brief: "Generate shell completions",
|
||||
fullDescription:
|
||||
"Generate shell completion scripts for bash, zsh, or fish.\n\nCurrently bash and zsh are supported. fish support is planned.",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user