@seamapi/cli 0.27.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/bin/cli.js +11 -11
- package/bin/cli.js.map +1 -1
- package/lib/commands/local/completion.d.ts +5 -1
- package/lib/commands/local/completion.js +72 -4
- package/lib/commands/local/completion.js.map +1 -1
- package/lib/commands/local/wizard.js +6 -1
- package/lib/commands/local/wizard.js.map +1 -1
- package/lib/completion/detect-shell.d.ts +6 -0
- package/lib/completion/detect-shell.js +57 -0
- package/lib/completion/detect-shell.js.map +1 -0
- package/lib/completion/install.d.ts +19 -0
- package/lib/completion/install.js +81 -0
- package/lib/completion/install.js.map +1 -0
- package/lib/render/completion/index.d.ts +1 -0
- package/lib/render/completion/index.js +33 -13
- package/lib/render/completion/index.js.map +1 -1
- package/lib/render/help.js +2 -2
- package/lib/render/help.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/bin/cli.ts +22 -17
- package/src/lib/commands/local/completion.ts +113 -4
- package/src/lib/commands/local/wizard.ts +6 -1
- package/src/lib/completion/detect-shell.ts +88 -0
- package/src/lib/completion/install.ts +128 -0
- package/src/lib/render/completion/index.ts +34 -13
- package/src/lib/render/help.ts +2 -2
- package/src/lib/version.ts +1 -1
package/README.md
CHANGED
|
@@ -32,10 +32,14 @@ On Arch Linux, install the [`seam-bin`][aur] package from the AUR with
|
|
|
32
32
|
$ paru -S seam-bin
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
The AUR and Homebrew packages install [shell completion] themselves. After an
|
|
36
|
+
npm or manual install, run `seam completion --install`.
|
|
37
|
+
|
|
35
38
|
[aur]: https://aur.archlinux.org/packages/seam-bin
|
|
36
39
|
[latest GitHub release]: https://github.com/seamapi/cli/releases/latest
|
|
37
40
|
[npm]: https://www.npmjs.com/
|
|
38
41
|
[Seam Wizard]: https://github.com/seamapi/wizard
|
|
42
|
+
[shell completion]: #shell-completion
|
|
39
43
|
|
|
40
44
|
## Usage
|
|
41
45
|
|
|
@@ -283,7 +287,21 @@ seam devices list --help
|
|
|
283
287
|
The CLI can print a completion script for bash, fish, and zsh that completes
|
|
284
288
|
commands, flags, and flag values such as device types.
|
|
285
289
|
|
|
286
|
-
|
|
290
|
+
Install them into the shell you are in, or one you name, with
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
seam completion --install
|
|
294
|
+
seam completion --install zsh
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
If you use Zsh you must enable compinit in your `.zshrc` with
|
|
298
|
+
|
|
299
|
+
```zsh
|
|
300
|
+
autoload -Uz compinit
|
|
301
|
+
compinit
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Load completions into the current shell instead with
|
|
287
305
|
|
|
288
306
|
```bash
|
|
289
307
|
# bash
|
package/bin/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import chalk from 'chalk';
|
|
|
4
4
|
import { cliFlags, getInteractivity, parseCliArgs, toAuthOverrides, toParameterName, } from '../lib/args/parse.js';
|
|
5
5
|
import { assertKnownArgs, assertNoAuthOverrides } from '../lib/args/validate.js';
|
|
6
6
|
import { getApiBlueprint } from '../lib/blueprint/index.js';
|
|
7
|
-
import { printCompletion, printCompletionLoader, } from '../lib/commands/local/completion.js';
|
|
7
|
+
import { installCompletionForShell, printCompletion, printCompletionLoader, readCompletionAction, resolveCompletionShell, } from '../lib/commands/local/completion.js';
|
|
8
8
|
import { runWizard } from '../lib/commands/local/wizard.js';
|
|
9
9
|
import { acceptedParamsOf, buildRegistry, findLocalCommand, findLocalCommandTakingPositional, } from '../lib/commands/registry.js';
|
|
10
10
|
import { getConfig } from '../lib/config/index.js';
|
|
@@ -19,7 +19,6 @@ import { parseJsonParams, readStdinJson } from '../lib/output/read-stdin-json.js
|
|
|
19
19
|
import { resolveOutputFormat } from '../lib/output/resolve-output-format.js';
|
|
20
20
|
import { setAuthOverrides } from '../lib/overrides.js';
|
|
21
21
|
import { canPrompt } from '../lib/prompt.js';
|
|
22
|
-
import { completionShells, isCompletionShell, } from '../lib/render/completion/index.js';
|
|
23
22
|
import { renderHelp } from '../lib/render/help.js';
|
|
24
23
|
import seamapiCliVersion from '../lib/version.js';
|
|
25
24
|
async function cli(args, argv) {
|
|
@@ -88,18 +87,19 @@ async function cli(args, argv) {
|
|
|
88
87
|
argParams[key] = value;
|
|
89
88
|
}
|
|
90
89
|
if (args._[0] === 'completion') {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
process.exitCode = 1;
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
90
|
+
const action = readCompletionAction(args);
|
|
91
|
+
const shellArg = args._[1];
|
|
92
|
+
const shell = resolveCompletionShell(shellArg, action);
|
|
97
93
|
const command = findLocalCommand(['completion', shell]);
|
|
98
|
-
assertKnownArgs(argParams, ['completion', shell], {
|
|
94
|
+
assertKnownArgs(argParams, shellArg == null ? ['completion'] : ['completion', shell], {
|
|
99
95
|
accepted: command == null ? new Set() : acceptedParamsOf(command.definition),
|
|
100
96
|
isLocal: true,
|
|
101
97
|
});
|
|
102
|
-
if (
|
|
98
|
+
if (action === 'install') {
|
|
99
|
+
await installCompletionForShell(shell);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (action === 'loader') {
|
|
103
103
|
printCompletionLoader(shell);
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
@@ -189,7 +189,7 @@ const run = async (argv) => {
|
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
const args = parseCliArgs(argv, {
|
|
192
|
-
booleanKeys: argv[0]?.toLowerCase() === 'completion' ? ['loader'] : [],
|
|
192
|
+
booleanKeys: argv[0]?.toLowerCase() === 'completion' ? ['install', 'loader'] : [],
|
|
193
193
|
});
|
|
194
194
|
const isTty = process.stdout.isTTY === true;
|
|
195
195
|
setOutput(createOutput({
|
package/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/bin/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAExD,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EACL,eAAe,EACf,qBAAqB,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/bin/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { ParsedArgs } from 'minimist';
|
|
1
2
|
import type { ApiBlueprint } from '../../blueprint/index.js';
|
|
2
3
|
import type { Command } from '../../commands/registry.js';
|
|
3
4
|
import type { CommandSpec } from '../../commands/spec.js';
|
|
4
5
|
import { type CompletionShell } from '../../render/completion/index.js';
|
|
6
|
+
export type CompletionAction = 'script' | 'install' | 'loader';
|
|
5
7
|
/**
|
|
6
8
|
* Print the completion script for a shell.
|
|
7
9
|
*
|
|
@@ -13,8 +15,10 @@ import { type CompletionShell } from '../../render/completion/index.js';
|
|
|
13
15
|
* the registered command's executor — one implementation for both.
|
|
14
16
|
*/
|
|
15
17
|
export declare const printCompletion: (shell: CompletionShell, spec: CommandSpec) => void;
|
|
16
|
-
/** Print the network-free loader installed in a shell completion directory. */
|
|
17
18
|
export declare const printCompletionLoader: (shell: CompletionShell) => void;
|
|
19
|
+
export declare const installCompletionForShell: (shell: CompletionShell) => Promise<void>;
|
|
20
|
+
export declare const readCompletionAction: (args: ParsedArgs) => CompletionAction;
|
|
21
|
+
export declare const resolveCompletionShell: (shellArg: string | undefined, action: CompletionAction) => CompletionShell;
|
|
18
22
|
type BuildSpec = (blueprint: ApiBlueprint) => CommandSpec;
|
|
19
23
|
export declare const createCompletionCommands: (buildSpec: BuildSpec) => Command[];
|
|
20
24
|
export {};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { detectShell } from '../../completion/detect-shell.js';
|
|
2
|
+
import { installCompletion, resolveCompletionTarget, } from '../../completion/install.js';
|
|
3
|
+
import { UsageError } from '../../errors.js';
|
|
1
4
|
import { getOutput } from '../../output/get-output.js';
|
|
2
|
-
import { renderCompletion, renderCompletionStub, } from '../../render/completion/index.js';
|
|
5
|
+
import { completionShells, isCompletionShell, renderCompletion, renderCompletionStub, } from '../../render/completion/index.js';
|
|
6
|
+
const completionActionFlags = ['install', 'loader'];
|
|
3
7
|
/**
|
|
4
8
|
* Print the completion script for a shell.
|
|
5
9
|
*
|
|
@@ -13,10 +17,62 @@ import { renderCompletion, renderCompletionStub, } from '../../render/completion
|
|
|
13
17
|
export const printCompletion = (shell, spec) => {
|
|
14
18
|
getOutput().text(renderCompletion(shell, spec));
|
|
15
19
|
};
|
|
16
|
-
/** Print the network-free loader installed in a shell completion directory. */
|
|
17
20
|
export const printCompletionLoader = (shell) => {
|
|
18
21
|
getOutput().text(renderCompletionStub(shell));
|
|
19
22
|
};
|
|
23
|
+
export const installCompletionForShell = async (shell) => {
|
|
24
|
+
const output = getOutput();
|
|
25
|
+
const target = resolveCompletionTarget(shell);
|
|
26
|
+
const { outcome, notes, warnings } = await installCompletion(target);
|
|
27
|
+
output.info(describeOutcome(outcome, target));
|
|
28
|
+
for (const note of notes)
|
|
29
|
+
output.info(note);
|
|
30
|
+
for (const warning of warnings)
|
|
31
|
+
output.warn(`\n${warning}`);
|
|
32
|
+
};
|
|
33
|
+
export const readCompletionAction = (args) => {
|
|
34
|
+
const given = completionActionFlags.filter((flag) => args[flag] === true);
|
|
35
|
+
if (given.length > 1) {
|
|
36
|
+
throw new UsageError(`Only one of ${completionActionFlags
|
|
37
|
+
.map((flag) => `--${flag}`)
|
|
38
|
+
.join(', ')} may be given for seam completion.`, { hint: completionUsage });
|
|
39
|
+
}
|
|
40
|
+
return given[0] ?? 'script';
|
|
41
|
+
};
|
|
42
|
+
export const resolveCompletionShell = (shellArg, action) => {
|
|
43
|
+
if (shellArg != null) {
|
|
44
|
+
if (isCompletionShell(shellArg))
|
|
45
|
+
return shellArg;
|
|
46
|
+
throw new UsageError(`Unknown shell for seam completion: ${shellArg}`, {
|
|
47
|
+
hint: completionUsage,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (action === 'script' || action === 'loader') {
|
|
51
|
+
throw new UsageError('Missing required argument for seam completion: <shell>', { hint: completionUsage });
|
|
52
|
+
}
|
|
53
|
+
const detected = detectShell();
|
|
54
|
+
if (detected == null) {
|
|
55
|
+
throw new UsageError(`Could not tell which shell you are in: it is none of ${listShells()}.`, {
|
|
56
|
+
hint: `Name the shell instead, e.g., 'seam completion --${action} zsh'.`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return detected;
|
|
60
|
+
};
|
|
61
|
+
const completionUsage = [
|
|
62
|
+
`Usage: seam completion <${completionShells.join('|')}>`,
|
|
63
|
+
` seam completion --install [${completionShells.join('|')}]`,
|
|
64
|
+
` seam completion --loader [${completionShells.join('|')}]`,
|
|
65
|
+
].join('\n');
|
|
66
|
+
const listShells = () => `${completionShells.slice(0, -1).join(', ')}, or ${completionShells.at(-1) ?? ''}`;
|
|
67
|
+
const describeOutcome = (outcome, { shell, file }) => {
|
|
68
|
+
if (outcome === 'present') {
|
|
69
|
+
return `${file} already loads ${shell} completions for seam.`;
|
|
70
|
+
}
|
|
71
|
+
if (outcome === 'written') {
|
|
72
|
+
return `Installed ${shell} completions for seam to ${file}.`;
|
|
73
|
+
}
|
|
74
|
+
return `Added ${shell} completions for seam to ${file}.`;
|
|
75
|
+
};
|
|
20
76
|
const completionCommand = (shell, buildSpec) => ({
|
|
21
77
|
definition: {
|
|
22
78
|
path: ['completion', shell],
|
|
@@ -24,10 +80,18 @@ const completionCommand = (shell, buildSpec) => ({
|
|
|
24
80
|
title: `Print the ${shell} completion script.`,
|
|
25
81
|
description: '',
|
|
26
82
|
flags: [
|
|
83
|
+
{
|
|
84
|
+
long: 'install',
|
|
85
|
+
short: null,
|
|
86
|
+
description: `Add what ${shell} needs to complete seam commands to its config, instead of printing the script.`,
|
|
87
|
+
values: [],
|
|
88
|
+
takesValue: false,
|
|
89
|
+
isRequired: false,
|
|
90
|
+
},
|
|
27
91
|
{
|
|
28
92
|
long: 'loader',
|
|
29
93
|
short: null,
|
|
30
|
-
description:
|
|
94
|
+
description: `Print the loader --install writes, to install it into ${shell} by hand or from a package.`,
|
|
31
95
|
values: [],
|
|
32
96
|
takesValue: false,
|
|
33
97
|
isRequired: false,
|
|
@@ -36,7 +100,11 @@ const completionCommand = (shell, buildSpec) => ({
|
|
|
36
100
|
},
|
|
37
101
|
requiresAuth: false,
|
|
38
102
|
execute: async (invocation, ctx) => {
|
|
39
|
-
|
|
103
|
+
const action = readCompletionAction(invocation.args);
|
|
104
|
+
if (action === 'install') {
|
|
105
|
+
await installCompletionForShell(shell);
|
|
106
|
+
}
|
|
107
|
+
else if (action === 'loader') {
|
|
40
108
|
printCompletionLoader(shell);
|
|
41
109
|
}
|
|
42
110
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/lib/commands/local/completion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/lib/commands/local/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,12 @@ export const runWizard = async (argv, load = loadWizard) => {
|
|
|
18
18
|
'',
|
|
19
19
|
'This is most likely because the packaging source does not allow software that includes dependencies with non-commercial licenses, including the Claude SDK used by the Wizard.',
|
|
20
20
|
'',
|
|
21
|
-
'
|
|
21
|
+
'If you installed the Seam CLI with Homebrew, reinstall it from the Seam tap:',
|
|
22
|
+
'',
|
|
23
|
+
' brew uninstall --cask seam',
|
|
24
|
+
' brew install --cask seamapi/tap/seam-cli',
|
|
25
|
+
'',
|
|
26
|
+
'Otherwise, install the Seam CLI from npm:',
|
|
22
27
|
'',
|
|
23
28
|
' npm i -g seam',
|
|
24
29
|
].join('\n'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../src/lib/commands/local/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAOxC,OAAO,WAAW,MAAM,aAAa,CAAA;AAGrC,OAAO,EAAkB,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAY1C,MAAM,UAAU,GAAe,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;AAE1E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,IAAc,EACd,OAAmB,UAAU,EACd,EAAE;IACjB,IAAI,MAAc,CAAA;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAA;QAC3B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,UAAU,CAClB;gBACE,wDAAwD;gBACxD,EAAE;gBACF,gLAAgL;gBAChL,EAAE;gBACF,
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../src/lib/commands/local/wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CompletionShell } from '../render/completion/index.js';
|
|
2
|
+
export interface DetectShellOptions {
|
|
3
|
+
env?: NodeJS.ProcessEnv;
|
|
4
|
+
ancestors?: () => string[];
|
|
5
|
+
}
|
|
6
|
+
export declare const detectShell: ({ env, ancestors, }?: DetectShellOptions) => CompletionShell | null;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { basename } from 'node:path';
|
|
4
|
+
import { isCompletionShell, } from '../render/completion/index.js';
|
|
5
|
+
export const detectShell = ({ env = process.env, ancestors = processAncestors, } = {}) => {
|
|
6
|
+
for (const command of ancestors()) {
|
|
7
|
+
const name = toShellName(command);
|
|
8
|
+
if (isCompletionShell(name))
|
|
9
|
+
return name;
|
|
10
|
+
}
|
|
11
|
+
const name = toShellName(env['SHELL'] ?? '');
|
|
12
|
+
return isCompletionShell(name) ? name : null;
|
|
13
|
+
};
|
|
14
|
+
const toShellName = (command) => basename(command.trim()).replace(/^-/, '');
|
|
15
|
+
const maxAncestors = 10;
|
|
16
|
+
const processAncestors = () => {
|
|
17
|
+
const commands = [];
|
|
18
|
+
let pid = process.ppid;
|
|
19
|
+
for (let depth = 0; depth < maxAncestors && pid > 1; depth += 1) {
|
|
20
|
+
const parent = readProcess(pid);
|
|
21
|
+
if (parent == null)
|
|
22
|
+
break;
|
|
23
|
+
commands.push(parent.command);
|
|
24
|
+
pid = parent.ppid;
|
|
25
|
+
}
|
|
26
|
+
return commands;
|
|
27
|
+
};
|
|
28
|
+
const readProcess = (pid) => readFromProcfs(pid) ?? readFromPs(pid);
|
|
29
|
+
const readFromProcfs = (pid) => {
|
|
30
|
+
try {
|
|
31
|
+
const command = readFileSync(`/proc/${pid}/comm`, 'utf8').trim();
|
|
32
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf8');
|
|
33
|
+
const afterCommand = stat.slice(stat.lastIndexOf(')') + 1).trim();
|
|
34
|
+
const ppid = Number(afterCommand.split(/\s+/)[1]);
|
|
35
|
+
return command !== '' && Number.isInteger(ppid) ? { command, ppid } : null;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const readFromPs = (pid) => {
|
|
42
|
+
try {
|
|
43
|
+
const fields = execFileSync('ps', ['-p', String(pid), '-o', 'comm=,ppid='], {
|
|
44
|
+
encoding: 'utf8',
|
|
45
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
46
|
+
})
|
|
47
|
+
.trim()
|
|
48
|
+
.split(/\s+/);
|
|
49
|
+
const ppid = Number(fields.pop());
|
|
50
|
+
const command = fields.join(' ');
|
|
51
|
+
return command !== '' && Number.isInteger(ppid) ? { command, ppid } : null;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=detect-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-shell.js","sourceRoot":"","sources":["../../src/lib/completion/detect-shell.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CompletionShell } from '../render/completion/index.js';
|
|
2
|
+
export type CompletionFileKind = 'config' | 'completion';
|
|
3
|
+
export interface CompletionTarget {
|
|
4
|
+
shell: CompletionShell;
|
|
5
|
+
file: string;
|
|
6
|
+
kind: CompletionFileKind;
|
|
7
|
+
}
|
|
8
|
+
export interface ResolveCompletionTargetOptions {
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
home?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const resolveCompletionTarget: (shell: CompletionShell, { env, home }?: ResolveCompletionTargetOptions) => CompletionTarget;
|
|
13
|
+
export type InstallOutcome = 'added' | 'present' | 'written';
|
|
14
|
+
export interface InstallResult {
|
|
15
|
+
outcome: InstallOutcome;
|
|
16
|
+
notes: string[];
|
|
17
|
+
warnings: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare const installCompletion: (target: CompletionTarget) => Promise<InstallResult>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { renderCompletionEval, renderCompletionStub, } from '../render/completion/index.js';
|
|
6
|
+
export const resolveCompletionTarget = (shell, { env = process.env, home = homedir() } = {}) => {
|
|
7
|
+
if (shell === 'fish') {
|
|
8
|
+
const configHome = readPath(env['XDG_CONFIG_HOME']) ?? join(home, '.config');
|
|
9
|
+
return {
|
|
10
|
+
shell,
|
|
11
|
+
file: join(configHome, 'fish', 'completions', 'seam.fish'),
|
|
12
|
+
kind: 'completion',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (shell === 'zsh') {
|
|
16
|
+
const dotDirectory = readPath(env['ZDOTDIR']) ?? home;
|
|
17
|
+
return { shell, file: join(dotDirectory, '.zshrc'), kind: 'config' };
|
|
18
|
+
}
|
|
19
|
+
return { shell, file: bashConfig(home), kind: 'config' };
|
|
20
|
+
};
|
|
21
|
+
const bashConfig = (home) => {
|
|
22
|
+
const bashrc = join(home, '.bashrc');
|
|
23
|
+
const bashProfile = join(home, '.bash_profile');
|
|
24
|
+
if (existsSync(bashrc))
|
|
25
|
+
return bashrc;
|
|
26
|
+
if (existsSync(bashProfile))
|
|
27
|
+
return bashProfile;
|
|
28
|
+
return bashrc;
|
|
29
|
+
};
|
|
30
|
+
export const installCompletion = async (target) => {
|
|
31
|
+
await mkdir(dirname(target.file), { recursive: true });
|
|
32
|
+
if (target.kind === 'completion') {
|
|
33
|
+
await writeFile(target.file, renderCompletionStub(target.shell), 'utf8');
|
|
34
|
+
return { outcome: 'written', ...adviceFor(target, null) };
|
|
35
|
+
}
|
|
36
|
+
const line = renderCompletionEval(target.shell);
|
|
37
|
+
const config = await readFileOrNull(target.file);
|
|
38
|
+
if (config != null && config.includes(line)) {
|
|
39
|
+
return { outcome: 'present', ...adviceFor(target, config) };
|
|
40
|
+
}
|
|
41
|
+
await appendFile(target.file, `${separatorFor(config)}${line}\n`, 'utf8');
|
|
42
|
+
return { outcome: 'added', ...adviceFor(target, config) };
|
|
43
|
+
};
|
|
44
|
+
const separatorFor = (config) => {
|
|
45
|
+
if (config == null || config === '')
|
|
46
|
+
return '';
|
|
47
|
+
return config.endsWith('\n') ? '\n' : '\n\n';
|
|
48
|
+
};
|
|
49
|
+
const adviceFor = ({ shell, file }, config) => ({
|
|
50
|
+
notes: [
|
|
51
|
+
`Open a new shell to complete seam commands, or run 'exec ${shell}' now.`,
|
|
52
|
+
],
|
|
53
|
+
warnings: shell === 'zsh' && config?.includes('compinit') !== true
|
|
54
|
+
? [
|
|
55
|
+
[
|
|
56
|
+
`Nothing in ${file} turns the zsh completion system on. If nothing`,
|
|
57
|
+
'else does either, completions stay inert until you add this above',
|
|
58
|
+
'the block just installed:',
|
|
59
|
+
'',
|
|
60
|
+
' autoload -Uz compinit',
|
|
61
|
+
' compinit',
|
|
62
|
+
].join('\n'),
|
|
63
|
+
]
|
|
64
|
+
: [],
|
|
65
|
+
});
|
|
66
|
+
const readFileOrNull = async (file) => {
|
|
67
|
+
try {
|
|
68
|
+
return await readFile(file, 'utf8');
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (isMissingFileError(error))
|
|
72
|
+
return null;
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const isMissingFileError = (error) => error instanceof Error && error.code === 'ENOENT';
|
|
77
|
+
const readPath = (value) => {
|
|
78
|
+
const trimmedValue = value?.trim();
|
|
79
|
+
return trimmedValue == null || trimmedValue === '' ? null : trimmedValue;
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/lib/completion/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ export declare const renderCompletion: (shell: CompletionShell, spec: CommandSpe
|
|
|
20
20
|
* completion command, is ever evaluated as shell code.
|
|
21
21
|
*/
|
|
22
22
|
export declare const renderCompletionStub: (shell: CompletionShell) => string;
|
|
23
|
+
export declare const renderCompletionEval: (shell: CompletionShell) => string;
|
|
23
24
|
/**
|
|
24
25
|
* First line of each generated completion script, which the loaders require
|
|
25
26
|
* before evaluating one. Must match the output of {@link renderCompletion}.
|
|
@@ -26,6 +26,10 @@ export const renderCompletion = (shell, spec) => renderers[shell](spec);
|
|
|
26
26
|
* completion command, is ever evaluated as shell code.
|
|
27
27
|
*/
|
|
28
28
|
export const renderCompletionStub = (shell) => stubs[shell];
|
|
29
|
+
export const renderCompletionEval = (shell) => {
|
|
30
|
+
const loader = `seam completion --loader ${shell} 2> /dev/null`;
|
|
31
|
+
return shell === 'fish' ? `${loader} | source` : `eval "$(${loader})"`;
|
|
32
|
+
};
|
|
29
33
|
/**
|
|
30
34
|
* First line of each generated completion script, which the loaders require
|
|
31
35
|
* before evaluating one. Must match the output of {@link renderCompletion}.
|
|
@@ -45,13 +49,21 @@ const stubs = {
|
|
|
45
49
|
#
|
|
46
50
|
# Install to /usr/share/bash-completion/completions/seam
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
_seam_completion_loader() {
|
|
53
|
+
local script
|
|
54
|
+
script="$(seam completion bash 2> /dev/null)"
|
|
50
55
|
# Evaluate only a completion script, never anything else the CLI printed.
|
|
51
|
-
case "$
|
|
52
|
-
'${completionScriptSentinels.bash}'*) eval "$
|
|
56
|
+
case "$script" in
|
|
57
|
+
'${completionScriptSentinels.bash}'*) eval "$script" ;;
|
|
58
|
+
*) return 1 ;;
|
|
53
59
|
esac
|
|
54
|
-
|
|
60
|
+
return 124
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 1))); then
|
|
64
|
+
complete -F _seam_completion_loader seam
|
|
65
|
+
else
|
|
66
|
+
_seam_completion_loader || :
|
|
55
67
|
fi
|
|
56
68
|
`,
|
|
57
69
|
fish: `${stubHeader('fish')}
|
|
@@ -71,15 +83,23 @@ ${stubHeader('zsh')}
|
|
|
71
83
|
#
|
|
72
84
|
# Install to a directory in fpath as _seam
|
|
73
85
|
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
_seam() {
|
|
87
|
+
local script
|
|
88
|
+
script="$(seam completion zsh 2> /dev/null)"
|
|
89
|
+
# Evaluate only a completion script, never anything else the CLI printed.
|
|
90
|
+
# The script ends by dispatching on funcstack, so evaluating it while this
|
|
91
|
+
# _seam runs both redefines _seam and completes the in-flight request.
|
|
92
|
+
if [[ "$script" == '${completionScriptSentinels.zsh}'* ]]; then
|
|
93
|
+
eval "$script"
|
|
94
|
+
fi
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (( $+functions[compdef] )); then
|
|
98
|
+
compdef _seam seam
|
|
99
|
+
fi
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# autoloaded _seam runs both redefines _seam and completes the in-flight
|
|
80
|
-
# request.
|
|
81
|
-
if [[ "$__seam_completion_script" == '${completionScriptSentinels.zsh}'* ]]; then
|
|
82
|
-
eval "$__seam_completion_script"
|
|
101
|
+
if (( \${funcstack[(I)_seam]} )); then
|
|
102
|
+
_seam "$@"
|
|
83
103
|
fi
|
|
84
104
|
`,
|
|
85
105
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/render/completion/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAIhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAA4B,EAAE,CAC5E,gBAAgB,CAAC,QAAQ,CAAC,KAAwB,CAAC,CAAA;AAErD,MAAM,SAAS,GAA2D;IACxE,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE,oBAAoB;IAC1B,GAAG,EAAE,mBAAmB;CACzB,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAsB,EACtB,IAAiB,EACT,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAA;AAEnC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAsB,EAAU,EAAE,CACrE,KAAK,CAAC,KAAK,CAAC,CAAA;AAEd;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAoC;IACxE,IAAI,EAAE,yCAAyC;IAC/C,IAAI,EAAE,yCAAyC;IAC/C,GAAG,EAAE,eAAe;CACrB,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAU,EAAE,CACpD,KAAK,KAAK;;;;uEAI2D,KAAK,IAAI,CAAA;AAEhF,MAAM,KAAK,GAAoC;IAC7C,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/render/completion/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAIhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAA4B,EAAE,CAC5E,gBAAgB,CAAC,QAAQ,CAAC,KAAwB,CAAC,CAAA;AAErD,MAAM,SAAS,GAA2D;IACxE,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE,oBAAoB;IAC1B,GAAG,EAAE,mBAAmB;CACzB,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAsB,EACtB,IAAiB,EACT,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAA;AAEnC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAsB,EAAU,EAAE,CACrE,KAAK,CAAC,KAAK,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAsB,EAAU,EAAE;IACrE,MAAM,MAAM,GAAG,4BAA4B,KAAK,eAAe,CAAA;IAC/D,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,WAAW,MAAM,IAAI,CAAA;AACxE,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAoC;IACxE,IAAI,EAAE,yCAAyC;IAC/C,IAAI,EAAE,yCAAyC;IAC/C,GAAG,EAAE,eAAe;CACrB,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAU,EAAE,CACpD,KAAK,KAAK;;;;uEAI2D,KAAK,IAAI,CAAA;AAEhF,MAAM,KAAK,GAAoC;IAC7C,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;;;;;;;;;OAStB,yBAAyB,CAAC,IAAI;;;;;;;;;;;CAWpC;IACC,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;;;;;;;+BAOE,yBAAyB,CAAC,IAAI;;;;CAI5D;IACC,GAAG,EAAE;EACL,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;wBAUK,yBAAyB,CAAC,GAAG;;;;;;;;;;;;CAYpD;CACA,CAAA"}
|
package/lib/render/help.js
CHANGED
|
@@ -63,8 +63,8 @@ const examples = [
|
|
|
63
63
|
summary: 'Pipe request params in as JSON.',
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
name: 'seam completion
|
|
67
|
-
summary: '
|
|
66
|
+
name: 'seam completion {bold --install}',
|
|
67
|
+
summary: 'Complete seam commands in bash, fish, or zsh.',
|
|
68
68
|
},
|
|
69
69
|
];
|
|
70
70
|
const groupSections = (group, spec) => {
|
package/lib/render/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/lib/render/help.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,EAAE,EAAgB,MAAM,oBAAoB,CAAA;AAEnE,OAAO,EAKL,WAAW,EACX,SAAS,GACV,MAAM,sBAAsB,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAc,EACd,IAAiB,EACF,EAAE;IACjB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACnC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,gBAAgB,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAEtE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACvC,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,gBAAgB,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;IAE5E,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,QAAQ,GACZ,qNAAqN,CAAA;AAEvN,MAAM,aAAa,GAAG;IACpB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE;QACP,gIAAgI;QAChI,6DAA6D;QAC7D,qJAAqJ;KACtJ;CACF,CAAA;AAED,MAAM,QAAQ,GAAG;IACf,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,2CAA2C,EAAE;IACtE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE;IACjD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,qCAAqC,EAAE;IACvE,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,wBAAwB,EAAE;IACpE;QACE,IAAI,EAAE,8BAA8B;QACpC,OAAO,EAAE,8CAA8C;KACxD;IACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,iCAAiC,EAAE;IACzE;QACE,IAAI,EAAE,wCAAwC;QAC9C,OAAO,EAAE,iDAAiD;KAC3D;IACD;QACE,IAAI,EAAE,4CAA4C;QAClD,OAAO,EAAE,6CAA6C;KACvD;IACD;QACE,IAAI,EAAE,oDAAoD;QAC1D,OAAO,EAAE,gBAAgB;KAC1B;IACD;QACE,IAAI,EAAE,uEAAuE;QAC7E,OAAO,EAAE,wBAAwB;KAClC;IACD;QACE,IAAI,EAAE,0DAA0D;QAChE,OAAO,EAAE,gCAAgC;KAC1C;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,uCAAuC;KACjD;IACD;QACE,IAAI,EAAE,0CAA0C;QAChD,OAAO,EAAE,iCAAiC;KAC3C;IACD;QACE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/lib/render/help.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,EAAE,EAAgB,MAAM,oBAAoB,CAAA;AAEnE,OAAO,EAKL,WAAW,EACX,SAAS,GACV,MAAM,sBAAsB,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAc,EACd,IAAiB,EACF,EAAE;IACjB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACnC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,gBAAgB,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAEtE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACvC,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,gBAAgB,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;IAE5E,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,QAAQ,GACZ,qNAAqN,CAAA;AAEvN,MAAM,aAAa,GAAG;IACpB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE;QACP,gIAAgI;QAChI,6DAA6D;QAC7D,qJAAqJ;KACtJ;CACF,CAAA;AAED,MAAM,QAAQ,GAAG;IACf,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,2CAA2C,EAAE;IACtE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE;IACjD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,qCAAqC,EAAE;IACvE,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,wBAAwB,EAAE;IACpE;QACE,IAAI,EAAE,8BAA8B;QACpC,OAAO,EAAE,8CAA8C;KACxD;IACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,iCAAiC,EAAE;IACzE;QACE,IAAI,EAAE,wCAAwC;QAC9C,OAAO,EAAE,iDAAiD;KAC3D;IACD;QACE,IAAI,EAAE,4CAA4C;QAClD,OAAO,EAAE,6CAA6C;KACvD;IACD;QACE,IAAI,EAAE,oDAAoD;QAC1D,OAAO,EAAE,gBAAgB;KAC1B;IACD;QACE,IAAI,EAAE,uEAAuE;QAC7E,OAAO,EAAE,wBAAwB;KAClC;IACD;QACE,IAAI,EAAE,0DAA0D;QAChE,OAAO,EAAE,gCAAgC;KAC1C;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,uCAAuC;KACjD;IACD;QACE,IAAI,EAAE,0CAA0C;QAChD,OAAO,EAAE,iCAAiC;KAC3C;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,+CAA+C;KACzD;CACF,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAE,IAAiB,EAAa,EAAE;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAE9C,OAAO;QACL,MAAM;YACJ,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE;YAC3C,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,IAAI,GAAG,EAAE;QACxD,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,sBAAsB,EAAE;QAC3D,GAAG,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC;QACzC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC/B,GAAG,CAAC,MAAM;YACR,CAAC,CAAC,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,EAAE,OAAO,EAAE,QAAQ,IAAI,gDAAgD,EAAE;KAC1E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,uBAAuB,GAAG,CAC9B,KAAmB,EACnB,MAAe,EACJ,EAAE;IACb,MAAM,OAAO,GAAG,CAAC,WAAwC,EAAE,EAAE,CAC3D,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;IAE9E,4EAA4E;IAC5E,0EAA0E;IAC1E,8BAA8B;IAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IAElE,OAAO;QACL,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;QAC7C,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;KAClD,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACnD,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CACtB,OAA0B,EAC1B,IAAiB,EACN,EAAE;IACb,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IACzC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;IAE9B,OAAO;QACL;YACE,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAClD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CACtB;SACF;QACD;YACE,MAAM,EAAE,OAAO;YACf,OAAO,EACL,UAAU,IAAI,IAAI;gBAChB,CAAC,CAAC,GAAG,IAAI,YAAY;gBACrB,CAAC,CAAC,GAAG,IAAI,KAAK,UAAU,CAAC,IAAI,aAAa;SAC/C;QACD,GAAG,CAAC,UAAU,IAAI,IAAI;YACpB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE;oBACE,MAAM,EAAE,WAAW;oBACnB,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,eAAe,UAAU,CAAC,IAAI,IAAI;4BACxC,OAAO,EAAE,UAAU,CAAC,WAAW;yBAChC;qBACF;iBACF;aACF,CAAC;QACN,wEAAwE;QACxE,wDAAwD;QACxD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC/B,GAAG,CAAC,QAAQ;YACV,CAAC,CAAC;gBACE;oBACE,OAAO,EACL,gEAAgE;iBACnE;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,MAAM,GAAG,SAAS,EAAW,EAAE,CAAC,CAAC;IAC5E,MAAM;IACN,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC;CAC1C,CAAC,CAAA;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAU7B,MAAM,kBAAkB,GAAG,CAAC,IAAiB,EAAoB,EAAE;IACjE,MAAM,WAAW,GAAG;QAClB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE;QAC1C,IAAI,CAAC,WAAW;QAChB,cAAc,CAAC,IAAI,CAAC;KACrB;SACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;SAC7B,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,OAAO;QACL,wEAAwE;QACxE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QACpD,0EAA0E;QAC1E,sBAAsB;QACtB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;QACxC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,WAAW;KACZ,CAAA;AACH,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,IAAiB,EAAU,EAAE;IACnD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,mBAAmB,CAAA;IAErD,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAA;AAC/E,CAAC,CAAA"}
|
package/lib/version.d.ts
CHANGED
package/lib/version.js
CHANGED
package/package.json
CHANGED
package/src/bin/cli.ts
CHANGED
|
@@ -14,8 +14,11 @@ import {
|
|
|
14
14
|
import { assertKnownArgs, assertNoAuthOverrides } from 'lib/args/validate.js'
|
|
15
15
|
import { getApiBlueprint } from 'lib/blueprint/index.js'
|
|
16
16
|
import {
|
|
17
|
+
installCompletionForShell,
|
|
17
18
|
printCompletion,
|
|
18
19
|
printCompletionLoader,
|
|
20
|
+
readCompletionAction,
|
|
21
|
+
resolveCompletionShell,
|
|
19
22
|
} from 'lib/commands/local/completion.js'
|
|
20
23
|
import { runWizard } from 'lib/commands/local/wizard.js'
|
|
21
24
|
import {
|
|
@@ -36,10 +39,6 @@ import { parseJsonParams, readStdinJson } from 'lib/output/read-stdin-json.js'
|
|
|
36
39
|
import { resolveOutputFormat } from 'lib/output/resolve-output-format.js'
|
|
37
40
|
import { setAuthOverrides } from 'lib/overrides.js'
|
|
38
41
|
import { canPrompt } from 'lib/prompt.js'
|
|
39
|
-
import {
|
|
40
|
-
completionShells,
|
|
41
|
-
isCompletionShell,
|
|
42
|
-
} from 'lib/render/completion/index.js'
|
|
43
42
|
import { renderHelp } from 'lib/render/help.js'
|
|
44
43
|
import seamapiCliVersion from 'lib/version.js'
|
|
45
44
|
|
|
@@ -118,22 +117,27 @@ async function cli(args: ParsedArgs, argv: string[]) {
|
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
if (args._[0] === 'completion') {
|
|
121
|
-
const
|
|
120
|
+
const action = readCompletionAction(args)
|
|
121
|
+
const shellArg = args._[1]
|
|
122
|
+
const shell = resolveCompletionShell(shellArg, action)
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
const command = findLocalCommand(['completion', shell])
|
|
125
|
+
assertKnownArgs(
|
|
126
|
+
argParams,
|
|
127
|
+
shellArg == null ? ['completion'] : ['completion', shell],
|
|
128
|
+
{
|
|
129
|
+
accepted:
|
|
130
|
+
command == null ? new Set() : acceptedParamsOf(command.definition),
|
|
131
|
+
isLocal: true,
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if (action === 'install') {
|
|
136
|
+
await installCompletionForShell(shell)
|
|
126
137
|
return
|
|
127
138
|
}
|
|
128
139
|
|
|
129
|
-
|
|
130
|
-
assertKnownArgs(argParams, ['completion', shell], {
|
|
131
|
-
accepted:
|
|
132
|
-
command == null ? new Set() : acceptedParamsOf(command.definition),
|
|
133
|
-
isLocal: true,
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
if (args['loader'] === true) {
|
|
140
|
+
if (action === 'loader') {
|
|
137
141
|
printCompletionLoader(shell)
|
|
138
142
|
return
|
|
139
143
|
}
|
|
@@ -253,7 +257,8 @@ const run = async (argv: string[]) => {
|
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
const args = parseCliArgs(argv, {
|
|
256
|
-
booleanKeys:
|
|
260
|
+
booleanKeys:
|
|
261
|
+
argv[0]?.toLowerCase() === 'completion' ? ['install', 'loader'] : [],
|
|
257
262
|
})
|
|
258
263
|
|
|
259
264
|
const isTty = process.stdout.isTTY === true
|
|
@@ -1,13 +1,29 @@
|
|
|
1
|
+
import type { ParsedArgs } from 'minimist'
|
|
2
|
+
|
|
1
3
|
import type { ApiBlueprint } from 'lib/blueprint/index.js'
|
|
2
4
|
import type { Command } from 'lib/commands/registry.js'
|
|
3
5
|
import type { CommandSpec } from 'lib/commands/spec.js'
|
|
6
|
+
import { detectShell } from 'lib/completion/detect-shell.js'
|
|
7
|
+
import {
|
|
8
|
+
type CompletionTarget,
|
|
9
|
+
installCompletion,
|
|
10
|
+
type InstallOutcome,
|
|
11
|
+
resolveCompletionTarget,
|
|
12
|
+
} from 'lib/completion/install.js'
|
|
13
|
+
import { UsageError } from 'lib/errors.js'
|
|
4
14
|
import { getOutput } from 'lib/output/get-output.js'
|
|
5
15
|
import {
|
|
6
16
|
type CompletionShell,
|
|
17
|
+
completionShells,
|
|
18
|
+
isCompletionShell,
|
|
7
19
|
renderCompletion,
|
|
8
20
|
renderCompletionStub,
|
|
9
21
|
} from 'lib/render/completion/index.js'
|
|
10
22
|
|
|
23
|
+
export type CompletionAction = 'script' | 'install' | 'loader'
|
|
24
|
+
|
|
25
|
+
const completionActionFlags = ['install', 'loader'] as const
|
|
26
|
+
|
|
11
27
|
/**
|
|
12
28
|
* Print the completion script for a shell.
|
|
13
29
|
*
|
|
@@ -25,11 +41,92 @@ export const printCompletion = (
|
|
|
25
41
|
getOutput().text(renderCompletion(shell, spec))
|
|
26
42
|
}
|
|
27
43
|
|
|
28
|
-
/** Print the network-free loader installed in a shell completion directory. */
|
|
29
44
|
export const printCompletionLoader = (shell: CompletionShell): void => {
|
|
30
45
|
getOutput().text(renderCompletionStub(shell))
|
|
31
46
|
}
|
|
32
47
|
|
|
48
|
+
export const installCompletionForShell = async (
|
|
49
|
+
shell: CompletionShell,
|
|
50
|
+
): Promise<void> => {
|
|
51
|
+
const output = getOutput()
|
|
52
|
+
const target = resolveCompletionTarget(shell)
|
|
53
|
+
const { outcome, notes, warnings } = await installCompletion(target)
|
|
54
|
+
|
|
55
|
+
output.info(describeOutcome(outcome, target))
|
|
56
|
+
for (const note of notes) output.info(note)
|
|
57
|
+
for (const warning of warnings) output.warn(`\n${warning}`)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const readCompletionAction = (args: ParsedArgs): CompletionAction => {
|
|
61
|
+
const given = completionActionFlags.filter((flag) => args[flag] === true)
|
|
62
|
+
|
|
63
|
+
if (given.length > 1) {
|
|
64
|
+
throw new UsageError(
|
|
65
|
+
`Only one of ${completionActionFlags
|
|
66
|
+
.map((flag) => `--${flag}`)
|
|
67
|
+
.join(', ')} may be given for seam completion.`,
|
|
68
|
+
{ hint: completionUsage },
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return given[0] ?? 'script'
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const resolveCompletionShell = (
|
|
76
|
+
shellArg: string | undefined,
|
|
77
|
+
action: CompletionAction,
|
|
78
|
+
): CompletionShell => {
|
|
79
|
+
if (shellArg != null) {
|
|
80
|
+
if (isCompletionShell(shellArg)) return shellArg
|
|
81
|
+
|
|
82
|
+
throw new UsageError(`Unknown shell for seam completion: ${shellArg}`, {
|
|
83
|
+
hint: completionUsage,
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (action === 'script' || action === 'loader') {
|
|
88
|
+
throw new UsageError(
|
|
89
|
+
'Missing required argument for seam completion: <shell>',
|
|
90
|
+
{ hint: completionUsage },
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const detected = detectShell()
|
|
95
|
+
|
|
96
|
+
if (detected == null) {
|
|
97
|
+
throw new UsageError(
|
|
98
|
+
`Could not tell which shell you are in: it is none of ${listShells()}.`,
|
|
99
|
+
{
|
|
100
|
+
hint: `Name the shell instead, e.g., 'seam completion --${action} zsh'.`,
|
|
101
|
+
},
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return detected
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const completionUsage = [
|
|
109
|
+
`Usage: seam completion <${completionShells.join('|')}>`,
|
|
110
|
+
` seam completion --install [${completionShells.join('|')}]`,
|
|
111
|
+
` seam completion --loader [${completionShells.join('|')}]`,
|
|
112
|
+
].join('\n')
|
|
113
|
+
|
|
114
|
+
const listShells = (): string =>
|
|
115
|
+
`${completionShells.slice(0, -1).join(', ')}, or ${completionShells.at(-1) ?? ''}`
|
|
116
|
+
|
|
117
|
+
const describeOutcome = (
|
|
118
|
+
outcome: InstallOutcome,
|
|
119
|
+
{ shell, file }: CompletionTarget,
|
|
120
|
+
): string => {
|
|
121
|
+
if (outcome === 'present') {
|
|
122
|
+
return `${file} already loads ${shell} completions for seam.`
|
|
123
|
+
}
|
|
124
|
+
if (outcome === 'written') {
|
|
125
|
+
return `Installed ${shell} completions for seam to ${file}.`
|
|
126
|
+
}
|
|
127
|
+
return `Added ${shell} completions for seam to ${file}.`
|
|
128
|
+
}
|
|
129
|
+
|
|
33
130
|
type BuildSpec = (blueprint: ApiBlueprint) => CommandSpec
|
|
34
131
|
|
|
35
132
|
const completionCommand = (
|
|
@@ -42,11 +139,18 @@ const completionCommand = (
|
|
|
42
139
|
title: `Print the ${shell} completion script.`,
|
|
43
140
|
description: '',
|
|
44
141
|
flags: [
|
|
142
|
+
{
|
|
143
|
+
long: 'install',
|
|
144
|
+
short: null,
|
|
145
|
+
description: `Add what ${shell} needs to complete seam commands to its config, instead of printing the script.`,
|
|
146
|
+
values: [],
|
|
147
|
+
takesValue: false,
|
|
148
|
+
isRequired: false,
|
|
149
|
+
},
|
|
45
150
|
{
|
|
46
151
|
long: 'loader',
|
|
47
152
|
short: null,
|
|
48
|
-
description:
|
|
49
|
-
'Print the dynamic, network-free loader for installation by a package manager.',
|
|
153
|
+
description: `Print the loader --install writes, to install it into ${shell} by hand or from a package.`,
|
|
50
154
|
values: [],
|
|
51
155
|
takesValue: false,
|
|
52
156
|
isRequired: false,
|
|
@@ -55,11 +159,16 @@ const completionCommand = (
|
|
|
55
159
|
},
|
|
56
160
|
requiresAuth: false,
|
|
57
161
|
execute: async (invocation, ctx) => {
|
|
58
|
-
|
|
162
|
+
const action = readCompletionAction(invocation.args)
|
|
163
|
+
|
|
164
|
+
if (action === 'install') {
|
|
165
|
+
await installCompletionForShell(shell)
|
|
166
|
+
} else if (action === 'loader') {
|
|
59
167
|
printCompletionLoader(shell)
|
|
60
168
|
} else {
|
|
61
169
|
printCompletion(shell, buildSpec(ctx.blueprint))
|
|
62
170
|
}
|
|
171
|
+
|
|
63
172
|
return { kind: 'done' }
|
|
64
173
|
},
|
|
65
174
|
})
|
|
@@ -42,7 +42,12 @@ export const runWizard = async (
|
|
|
42
42
|
'',
|
|
43
43
|
'This is most likely because the packaging source does not allow software that includes dependencies with non-commercial licenses, including the Claude SDK used by the Wizard.',
|
|
44
44
|
'',
|
|
45
|
-
'
|
|
45
|
+
'If you installed the Seam CLI with Homebrew, reinstall it from the Seam tap:',
|
|
46
|
+
'',
|
|
47
|
+
' brew uninstall --cask seam',
|
|
48
|
+
' brew install --cask seamapi/tap/seam-cli',
|
|
49
|
+
'',
|
|
50
|
+
'Otherwise, install the Seam CLI from npm:',
|
|
46
51
|
'',
|
|
47
52
|
' npm i -g seam',
|
|
48
53
|
].join('\n'),
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
import { basename } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
type CompletionShell,
|
|
7
|
+
isCompletionShell,
|
|
8
|
+
} from 'lib/render/completion/index.js'
|
|
9
|
+
|
|
10
|
+
export interface DetectShellOptions {
|
|
11
|
+
env?: NodeJS.ProcessEnv
|
|
12
|
+
ancestors?: () => string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const detectShell = ({
|
|
16
|
+
env = process.env,
|
|
17
|
+
ancestors = processAncestors,
|
|
18
|
+
}: DetectShellOptions = {}): CompletionShell | null => {
|
|
19
|
+
for (const command of ancestors()) {
|
|
20
|
+
const name = toShellName(command)
|
|
21
|
+
if (isCompletionShell(name)) return name
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const name = toShellName(env['SHELL'] ?? '')
|
|
25
|
+
|
|
26
|
+
return isCompletionShell(name) ? name : null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const toShellName = (command: string): string =>
|
|
30
|
+
basename(command.trim()).replace(/^-/, '')
|
|
31
|
+
|
|
32
|
+
const maxAncestors = 10
|
|
33
|
+
|
|
34
|
+
const processAncestors = (): string[] => {
|
|
35
|
+
const commands: string[] = []
|
|
36
|
+
|
|
37
|
+
let pid = process.ppid
|
|
38
|
+
for (let depth = 0; depth < maxAncestors && pid > 1; depth += 1) {
|
|
39
|
+
const parent = readProcess(pid)
|
|
40
|
+
if (parent == null) break
|
|
41
|
+
commands.push(parent.command)
|
|
42
|
+
pid = parent.ppid
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return commands
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface ProcessInfo {
|
|
49
|
+
command: string
|
|
50
|
+
ppid: number
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const readProcess = (pid: number): ProcessInfo | null =>
|
|
54
|
+
readFromProcfs(pid) ?? readFromPs(pid)
|
|
55
|
+
|
|
56
|
+
const readFromProcfs = (pid: number): ProcessInfo | null => {
|
|
57
|
+
try {
|
|
58
|
+
const command = readFileSync(`/proc/${pid}/comm`, 'utf8').trim()
|
|
59
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf8')
|
|
60
|
+
const afterCommand = stat.slice(stat.lastIndexOf(')') + 1).trim()
|
|
61
|
+
const ppid = Number(afterCommand.split(/\s+/)[1])
|
|
62
|
+
|
|
63
|
+
return command !== '' && Number.isInteger(ppid) ? { command, ppid } : null
|
|
64
|
+
} catch {
|
|
65
|
+
return null
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const readFromPs = (pid: number): ProcessInfo | null => {
|
|
70
|
+
try {
|
|
71
|
+
const fields = execFileSync(
|
|
72
|
+
'ps',
|
|
73
|
+
['-p', String(pid), '-o', 'comm=,ppid='],
|
|
74
|
+
{
|
|
75
|
+
encoding: 'utf8',
|
|
76
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
77
|
+
},
|
|
78
|
+
)
|
|
79
|
+
.trim()
|
|
80
|
+
.split(/\s+/)
|
|
81
|
+
const ppid = Number(fields.pop())
|
|
82
|
+
const command = fields.join(' ')
|
|
83
|
+
|
|
84
|
+
return command !== '' && Number.isInteger(ppid) ? { command, ppid } : null
|
|
85
|
+
} catch {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { homedir } from 'node:os'
|
|
4
|
+
import { dirname, join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
type CompletionShell,
|
|
8
|
+
renderCompletionEval,
|
|
9
|
+
renderCompletionStub,
|
|
10
|
+
} from 'lib/render/completion/index.js'
|
|
11
|
+
|
|
12
|
+
export type CompletionFileKind = 'config' | 'completion'
|
|
13
|
+
|
|
14
|
+
export interface CompletionTarget {
|
|
15
|
+
shell: CompletionShell
|
|
16
|
+
file: string
|
|
17
|
+
kind: CompletionFileKind
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ResolveCompletionTargetOptions {
|
|
21
|
+
env?: NodeJS.ProcessEnv
|
|
22
|
+
home?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const resolveCompletionTarget = (
|
|
26
|
+
shell: CompletionShell,
|
|
27
|
+
{ env = process.env, home = homedir() }: ResolveCompletionTargetOptions = {},
|
|
28
|
+
): CompletionTarget => {
|
|
29
|
+
if (shell === 'fish') {
|
|
30
|
+
const configHome = readPath(env['XDG_CONFIG_HOME']) ?? join(home, '.config')
|
|
31
|
+
return {
|
|
32
|
+
shell,
|
|
33
|
+
file: join(configHome, 'fish', 'completions', 'seam.fish'),
|
|
34
|
+
kind: 'completion',
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (shell === 'zsh') {
|
|
39
|
+
const dotDirectory = readPath(env['ZDOTDIR']) ?? home
|
|
40
|
+
return { shell, file: join(dotDirectory, '.zshrc'), kind: 'config' }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { shell, file: bashConfig(home), kind: 'config' }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const bashConfig = (home: string): string => {
|
|
47
|
+
const bashrc = join(home, '.bashrc')
|
|
48
|
+
const bashProfile = join(home, '.bash_profile')
|
|
49
|
+
|
|
50
|
+
if (existsSync(bashrc)) return bashrc
|
|
51
|
+
if (existsSync(bashProfile)) return bashProfile
|
|
52
|
+
|
|
53
|
+
return bashrc
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type InstallOutcome = 'added' | 'present' | 'written'
|
|
57
|
+
|
|
58
|
+
export interface InstallResult {
|
|
59
|
+
outcome: InstallOutcome
|
|
60
|
+
notes: string[]
|
|
61
|
+
warnings: string[]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const installCompletion = async (
|
|
65
|
+
target: CompletionTarget,
|
|
66
|
+
): Promise<InstallResult> => {
|
|
67
|
+
await mkdir(dirname(target.file), { recursive: true })
|
|
68
|
+
|
|
69
|
+
if (target.kind === 'completion') {
|
|
70
|
+
await writeFile(target.file, renderCompletionStub(target.shell), 'utf8')
|
|
71
|
+
return { outcome: 'written', ...adviceFor(target, null) }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const line = renderCompletionEval(target.shell)
|
|
75
|
+
const config = await readFileOrNull(target.file)
|
|
76
|
+
|
|
77
|
+
if (config != null && config.includes(line)) {
|
|
78
|
+
return { outcome: 'present', ...adviceFor(target, config) }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await appendFile(target.file, `${separatorFor(config)}${line}\n`, 'utf8')
|
|
82
|
+
|
|
83
|
+
return { outcome: 'added', ...adviceFor(target, config) }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const separatorFor = (config: string | null): string => {
|
|
87
|
+
if (config == null || config === '') return ''
|
|
88
|
+
return config.endsWith('\n') ? '\n' : '\n\n'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const adviceFor = (
|
|
92
|
+
{ shell, file }: CompletionTarget,
|
|
93
|
+
config: string | null,
|
|
94
|
+
): Pick<InstallResult, 'notes' | 'warnings'> => ({
|
|
95
|
+
notes: [
|
|
96
|
+
`Open a new shell to complete seam commands, or run 'exec ${shell}' now.`,
|
|
97
|
+
],
|
|
98
|
+
warnings:
|
|
99
|
+
shell === 'zsh' && config?.includes('compinit') !== true
|
|
100
|
+
? [
|
|
101
|
+
[
|
|
102
|
+
`Nothing in ${file} turns the zsh completion system on. If nothing`,
|
|
103
|
+
'else does either, completions stay inert until you add this above',
|
|
104
|
+
'the block just installed:',
|
|
105
|
+
'',
|
|
106
|
+
' autoload -Uz compinit',
|
|
107
|
+
' compinit',
|
|
108
|
+
].join('\n'),
|
|
109
|
+
]
|
|
110
|
+
: [],
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const readFileOrNull = async (file: string): Promise<string | null> => {
|
|
114
|
+
try {
|
|
115
|
+
return await readFile(file, 'utf8')
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (isMissingFileError(error)) return null
|
|
118
|
+
throw error
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const isMissingFileError = (error: unknown): boolean =>
|
|
123
|
+
error instanceof Error && (error as NodeJS.ErrnoException).code === 'ENOENT'
|
|
124
|
+
|
|
125
|
+
const readPath = (value: string | undefined): string | null => {
|
|
126
|
+
const trimmedValue = value?.trim()
|
|
127
|
+
return trimmedValue == null || trimmedValue === '' ? null : trimmedValue
|
|
128
|
+
}
|
|
@@ -41,6 +41,11 @@ export const renderCompletion = (
|
|
|
41
41
|
export const renderCompletionStub = (shell: CompletionShell): string =>
|
|
42
42
|
stubs[shell]
|
|
43
43
|
|
|
44
|
+
export const renderCompletionEval = (shell: CompletionShell): string => {
|
|
45
|
+
const loader = `seam completion --loader ${shell} 2> /dev/null`
|
|
46
|
+
return shell === 'fish' ? `${loader} | source` : `eval "$(${loader})"`
|
|
47
|
+
}
|
|
48
|
+
|
|
44
49
|
/**
|
|
45
50
|
* First line of each generated completion script, which the loaders require
|
|
46
51
|
* before evaluating one. Must match the output of {@link renderCompletion}.
|
|
@@ -63,13 +68,21 @@ const stubs: Record<CompletionShell, string> = {
|
|
|
63
68
|
#
|
|
64
69
|
# Install to /usr/share/bash-completion/completions/seam
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
_seam_completion_loader() {
|
|
72
|
+
local script
|
|
73
|
+
script="$(seam completion bash 2> /dev/null)"
|
|
68
74
|
# Evaluate only a completion script, never anything else the CLI printed.
|
|
69
|
-
case "$
|
|
70
|
-
'${completionScriptSentinels.bash}'*) eval "$
|
|
75
|
+
case "$script" in
|
|
76
|
+
'${completionScriptSentinels.bash}'*) eval "$script" ;;
|
|
77
|
+
*) return 1 ;;
|
|
71
78
|
esac
|
|
72
|
-
|
|
79
|
+
return 124
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 1))); then
|
|
83
|
+
complete -F _seam_completion_loader seam
|
|
84
|
+
else
|
|
85
|
+
_seam_completion_loader || :
|
|
73
86
|
fi
|
|
74
87
|
`,
|
|
75
88
|
fish: `${stubHeader('fish')}
|
|
@@ -89,15 +102,23 @@ ${stubHeader('zsh')}
|
|
|
89
102
|
#
|
|
90
103
|
# Install to a directory in fpath as _seam
|
|
91
104
|
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
_seam() {
|
|
106
|
+
local script
|
|
107
|
+
script="$(seam completion zsh 2> /dev/null)"
|
|
108
|
+
# Evaluate only a completion script, never anything else the CLI printed.
|
|
109
|
+
# The script ends by dispatching on funcstack, so evaluating it while this
|
|
110
|
+
# _seam runs both redefines _seam and completes the in-flight request.
|
|
111
|
+
if [[ "$script" == '${completionScriptSentinels.zsh}'* ]]; then
|
|
112
|
+
eval "$script"
|
|
113
|
+
fi
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (( $+functions[compdef] )); then
|
|
117
|
+
compdef _seam seam
|
|
118
|
+
fi
|
|
94
119
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
# autoloaded _seam runs both redefines _seam and completes the in-flight
|
|
98
|
-
# request.
|
|
99
|
-
if [[ "$__seam_completion_script" == '${completionScriptSentinels.zsh}'* ]]; then
|
|
100
|
-
eval "$__seam_completion_script"
|
|
120
|
+
if (( \${funcstack[(I)_seam]} )); then
|
|
121
|
+
_seam "$@"
|
|
101
122
|
fi
|
|
102
123
|
`,
|
|
103
124
|
}
|
package/src/lib/render/help.ts
CHANGED
|
@@ -79,8 +79,8 @@ const examples = [
|
|
|
79
79
|
summary: 'Pipe request params in as JSON.',
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
|
-
name: 'seam completion
|
|
83
|
-
summary: '
|
|
82
|
+
name: 'seam completion {bold --install}',
|
|
83
|
+
summary: 'Complete seam commands in bash, fish, or zsh.',
|
|
84
84
|
},
|
|
85
85
|
]
|
|
86
86
|
|
package/src/lib/version.ts
CHANGED