ownkey 1.2.0 → 1.3.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 +16 -0
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/ui/App.d.ts +17 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +109 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/complete.d.ts +22 -0
- package/dist/ui/complete.d.ts.map +1 -0
- package/dist/ui/complete.js +41 -0
- package/dist/ui/complete.js.map +1 -0
- package/dist/ui/context.d.ts +11 -0
- package/dist/ui/context.d.ts.map +1 -0
- package/dist/ui/context.js +37 -0
- package/dist/ui/context.js.map +1 -0
- package/dist/ui/session.d.ts +3 -0
- package/dist/ui/session.d.ts.map +1 -0
- package/dist/ui/session.js +114 -0
- package/dist/ui/session.js.map +1 -0
- package/dist/ui/words.d.ts +6 -0
- package/dist/ui/words.d.ts.map +1 -0
- package/dist/ui/words.js +46 -0
- package/dist/ui/words.js.map +1 -0
- package/package.json +16 -12
package/README.md
CHANGED
|
@@ -102,10 +102,26 @@ ownkey undo --list # recent applies
|
|
|
102
102
|
|
|
103
103
|
For a whole-project audit of any folder, git or not, use `ownkey suggest .`
|
|
104
104
|
|
|
105
|
+
## Interactive session
|
|
106
|
+
|
|
107
|
+
Run `ownkey` with no arguments in any project folder and it opens a session for that folder. The header shows the repository, branch, how many files changed, and which model is reviewing. Then type any command without the `ownkey` prefix:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
› review --staged
|
|
111
|
+
› apply 3 --verify "npm test"
|
|
112
|
+
› undo --last
|
|
113
|
+
› bench --case off-by-one
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Tab completes commands and their flags, the arrow keys walk your history (kept in `~/.ownkey/history`), `help` lists every command, and Ctrl+D leaves. Commands run exactly as they do from the shell, including interactive prompts like the `config` wizard. Ctrl+C stops the running command without closing the session.
|
|
117
|
+
|
|
118
|
+
Outside an interactive terminal (pipes, scripts, CI), or with `OWNKEY_NO_UI=1` set, a bare `ownkey` prints help as before. Every subcommand behaves the same with or without the session.
|
|
119
|
+
|
|
105
120
|
## Commands
|
|
106
121
|
|
|
107
122
|
| Command | Purpose |
|
|
108
123
|
|---|---|
|
|
124
|
+
| `ownkey` | Open the interactive session for the current folder. |
|
|
109
125
|
| `ownkey config` | Set the AI provider, model, endpoint, and optional database. Run with no flags for an interactive wizard. |
|
|
110
126
|
| `ownkey review [path]` | Review git changes: staged, uncommitted, or a branch against its base. |
|
|
111
127
|
| `ownkey suggest [path]` | Audit a whole folder and store suggestions. |
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,19 @@ program.hook('preAction', async (thisCommand, actionCommand) => {
|
|
|
56
56
|
program.hook('postAction', async () => {
|
|
57
57
|
await dbClient.disconnect();
|
|
58
58
|
});
|
|
59
|
-
//
|
|
60
|
-
|
|
59
|
+
// A bare `ownkey` at a terminal opens the interactive session, where commands are typed
|
|
60
|
+
// without the prefix. Scripts, CI, pipes and every subcommand behave exactly as before.
|
|
61
|
+
const interactive = process.argv.length <= 2 && !process.env.OWNKEY_NO_UI && !process.env.CI && process.stdin.isTTY && process.stdout.isTTY;
|
|
62
|
+
if (interactive) {
|
|
63
|
+
const { startSession } = await import('./ui/session.js');
|
|
64
|
+
const commands = program.commands.map((c) => ({
|
|
65
|
+
name: c.name(),
|
|
66
|
+
description: c.description(),
|
|
67
|
+
options: c.options.map((o) => ({ flags: o.flags, description: o.description })),
|
|
68
|
+
}));
|
|
69
|
+
await startSession(commands, program.version() ?? '');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
await program.parseAsync();
|
|
73
|
+
}
|
|
61
74
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC;AAExE,iBAAiB;AACjB,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC,CAAC;AACnE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;AACtD,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;AAClD,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;AAE3D,WAAW;AACX,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,+CAA+C;AAC/C,mFAAmF;AACnF,iFAAiF;AACjF,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE;IAC3D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IAEpB,wCAAwC;IACxC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IAEhC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,yFAAyF;IACzF,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO;IACX,CAAC;IAED,2EAA2E;IAC3E,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,+BAA+B;AAC/B,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAClC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CommandInfo } from './complete.js';
|
|
2
|
+
import type { SessionInfo } from './context.js';
|
|
3
|
+
export interface PromptProps {
|
|
4
|
+
info: SessionInfo;
|
|
5
|
+
commands: CommandInfo[];
|
|
6
|
+
history: string[];
|
|
7
|
+
/** Called once with the submitted line, or null when the user leaves */
|
|
8
|
+
onDone: (line: string | null) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function Banner({ version }: {
|
|
11
|
+
version: string;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
export declare function Header({ info }: {
|
|
14
|
+
info: SessionInfo;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
export declare function Prompt({ info, commands, history, onDone }: PromptProps): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=App.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACzC;AAID,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,+BAatD;AAED,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,+BAmBrD;AAED,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,+BA+GtE"}
|
package/dist/ui/App.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text, useApp, useInput } from 'ink';
|
|
4
|
+
import { applySuggestion, suggest } from './complete.js';
|
|
5
|
+
const ORANGE = '#ff5a1f';
|
|
6
|
+
export function Banner({ version }) {
|
|
7
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: ORANGE, paddingX: 1, flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: ORANGE, bold: true, children: "\u25C6 OwnKey" }), _jsxs(Text, { dimColor: true, children: [" ", version] }), _jsx(Text, { children: " local-first AI code review on your own keys" })] }), _jsx(Text, { dimColor: true, children: "Type any command without the ownkey prefix. Tab completes, \u2191\u2193 history, help lists everything." })] }));
|
|
8
|
+
}
|
|
9
|
+
export function Header({ info }) {
|
|
10
|
+
const where = [info.folder, info.branch, info.changed === undefined ? undefined : info.changed === 0 ? 'clean' : `${info.changed} changed`]
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.join(' · ');
|
|
13
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { children: [_jsx(Text, { bold: true, children: where }), _jsx(Text, { dimColor: true, children: " \u00B7 " }), info.provider ? (_jsxs(Text, { color: "cyan", children: [info.provider, " / ", info.model] })) : (_jsx(Text, { color: "yellow", children: "No model yet. Type config to set one up." }))] }) }));
|
|
14
|
+
}
|
|
15
|
+
export function Prompt({ info, commands, history, onDone }) {
|
|
16
|
+
const { exit } = useApp();
|
|
17
|
+
const [value, setValue] = useState('');
|
|
18
|
+
const [cursor, setCursor] = useState(0);
|
|
19
|
+
const [histIndex, setHistIndex] = useState(history.length);
|
|
20
|
+
const [selected, setSelected] = useState(0);
|
|
21
|
+
const [finished, setFinished] = useState(false);
|
|
22
|
+
const suggestions = suggest(value.slice(0, cursor), commands);
|
|
23
|
+
const sel = Math.min(selected, Math.max(0, suggestions.length - 1));
|
|
24
|
+
// Exit only after the final frame (prompt line alone, no header or menu) has rendered,
|
|
25
|
+
// so scrollback keeps a clean record of each command.
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (finished)
|
|
28
|
+
exit();
|
|
29
|
+
}, [finished, exit]);
|
|
30
|
+
const finish = (line) => {
|
|
31
|
+
onDone(line);
|
|
32
|
+
setFinished(true);
|
|
33
|
+
};
|
|
34
|
+
const set = (v, c = v.length) => {
|
|
35
|
+
setValue(v);
|
|
36
|
+
setCursor(c);
|
|
37
|
+
setSelected(0);
|
|
38
|
+
};
|
|
39
|
+
useInput((input, key) => {
|
|
40
|
+
if (finished)
|
|
41
|
+
return;
|
|
42
|
+
if (key.ctrl && input === 'c') {
|
|
43
|
+
if (value)
|
|
44
|
+
set('');
|
|
45
|
+
else
|
|
46
|
+
finish(null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (key.ctrl && input === 'd') {
|
|
50
|
+
if (!value)
|
|
51
|
+
finish(null);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (key.return) {
|
|
55
|
+
finish(value);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (key.tab) {
|
|
59
|
+
if (suggestions.length)
|
|
60
|
+
set(applySuggestion(value, suggestions[sel].value));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (key.escape) {
|
|
64
|
+
set('');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (key.upArrow || key.downArrow) {
|
|
68
|
+
// With a suggestion list open, arrows pick from it; otherwise they walk history
|
|
69
|
+
if (suggestions.length > 1 && value) {
|
|
70
|
+
const n = suggestions.length;
|
|
71
|
+
setSelected((sel + (key.upArrow ? n - 1 : 1)) % n);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const next = Math.max(0, Math.min(history.length, histIndex + (key.upArrow ? -1 : 1)));
|
|
75
|
+
setHistIndex(next);
|
|
76
|
+
set(history[next] ?? '');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (key.leftArrow)
|
|
80
|
+
return setCursor(Math.max(0, cursor - 1));
|
|
81
|
+
if (key.rightArrow)
|
|
82
|
+
return setCursor(Math.min(value.length, cursor + 1));
|
|
83
|
+
if (key.ctrl && input === 'a')
|
|
84
|
+
return setCursor(0);
|
|
85
|
+
if (key.ctrl && input === 'e')
|
|
86
|
+
return setCursor(value.length);
|
|
87
|
+
if (key.ctrl && input === 'u')
|
|
88
|
+
return set(value.slice(cursor), 0);
|
|
89
|
+
if (key.backspace || key.delete) {
|
|
90
|
+
if (cursor > 0)
|
|
91
|
+
set(value.slice(0, cursor - 1) + value.slice(cursor), cursor - 1);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (input && !key.ctrl && !key.meta) {
|
|
95
|
+
// A paste (or fast typing) can arrive with its Enter in the same chunk
|
|
96
|
+
const nl = input.search(/[\r\n]/);
|
|
97
|
+
const text = nl === -1 ? input : input.slice(0, nl);
|
|
98
|
+
const next = value.slice(0, cursor) + text + value.slice(cursor);
|
|
99
|
+
set(next, cursor + text.length);
|
|
100
|
+
if (nl !== -1)
|
|
101
|
+
finish(next);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const before = value.slice(0, cursor);
|
|
105
|
+
const at = value[cursor] ?? ' ';
|
|
106
|
+
const after = value.slice(cursor + 1);
|
|
107
|
+
return (_jsxs(Box, { flexDirection: "column", children: [!finished ? _jsx(Header, { info: info }) : null, _jsxs(Text, { children: [_jsxs(Text, { color: ORANGE, bold: true, children: ["\u203A", ' '] }), _jsx(Text, { children: before }), finished ? _jsx(Text, { children: at === ' ' ? '' : at }) : _jsx(Text, { inverse: true, children: at }), _jsx(Text, { children: after })] }), !finished && suggestions.length > 0 ? (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: suggestions.map((s, i) => (_jsxs(Text, { children: [_jsx(Text, { color: i === sel ? ORANGE : undefined, bold: i === sel, children: s.label.padEnd(22) }), _jsx(Text, { dimColor: true, children: s.description })] }, s.label))) })) : null, !finished ? _jsx(Text, { dimColor: true, children: " Tab complete \u00B7 \u2191\u2193 history \u00B7 help \u00B7 Ctrl+D exit" }) : null] }));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface CommandInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
options: Array<{
|
|
5
|
+
flags: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export interface Suggestion {
|
|
10
|
+
/** What Tab inserts for the current word */
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const BUILTINS: CommandInfo[];
|
|
16
|
+
/** Long flag of a commander flags string, e.g. "-y, --yes" -> "--yes", "--case <ids>" -> "--case". */
|
|
17
|
+
export declare function longFlag(flags: string): string;
|
|
18
|
+
/** Suggestions for the word being typed at the end of `line`. */
|
|
19
|
+
export declare function suggest(line: string, commands: CommandInfo[]): Suggestion[];
|
|
20
|
+
/** Replace the word being typed with `value`, followed by a space. */
|
|
21
|
+
export declare function applySuggestion(line: string, value: string): string;
|
|
22
|
+
//# sourceMappingURL=complete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/ui/complete.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,UAAU;IACvB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,QAAQ,EAAE,WAAW,EAIjC,CAAC;AAIF,sGAAsG;AACtG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,CAoB3E;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const BUILTINS = [
|
|
2
|
+
{ name: 'help', description: 'Show commands and keys', options: [] },
|
|
3
|
+
{ name: 'clear', description: 'Clear the screen', options: [] },
|
|
4
|
+
{ name: 'exit', description: 'Leave OwnKey (Ctrl+D)', options: [] },
|
|
5
|
+
];
|
|
6
|
+
const MAX = 6;
|
|
7
|
+
/** Long flag of a commander flags string, e.g. "-y, --yes" -> "--yes", "--case <ids>" -> "--case". */
|
|
8
|
+
export function longFlag(flags) {
|
|
9
|
+
const parts = flags.split(/[ ,|]+/).filter((p) => p.startsWith('-'));
|
|
10
|
+
return parts.find((p) => p.startsWith('--')) ?? parts[0] ?? flags;
|
|
11
|
+
}
|
|
12
|
+
/** Suggestions for the word being typed at the end of `line`. */
|
|
13
|
+
export function suggest(line, commands) {
|
|
14
|
+
const all = [...commands, ...BUILTINS];
|
|
15
|
+
const trimmedStart = line.replace(/^\s+/, '').replace(/^ownkey\s+/, '');
|
|
16
|
+
const words = trimmedStart.split(/\s+/);
|
|
17
|
+
if (words.length <= 1) {
|
|
18
|
+
const w = words[0] ?? '';
|
|
19
|
+
return all
|
|
20
|
+
.filter((c) => c.name.startsWith(w) && c.name !== w)
|
|
21
|
+
.slice(0, MAX)
|
|
22
|
+
.map((c) => ({ value: c.name, label: c.name, description: c.description }));
|
|
23
|
+
}
|
|
24
|
+
const cmd = all.find((c) => c.name === words[0]);
|
|
25
|
+
if (!cmd)
|
|
26
|
+
return [];
|
|
27
|
+
const current = words[words.length - 1];
|
|
28
|
+
if (current !== '' && !current.startsWith('-'))
|
|
29
|
+
return [];
|
|
30
|
+
const used = new Set(words.slice(1, -1));
|
|
31
|
+
return cmd.options
|
|
32
|
+
.map((o) => ({ value: longFlag(o.flags), label: o.flags, description: o.description }))
|
|
33
|
+
.filter((s) => s.value.startsWith(current) && s.value !== current && !used.has(s.value))
|
|
34
|
+
.slice(0, MAX);
|
|
35
|
+
}
|
|
36
|
+
/** Replace the word being typed with `value`, followed by a space. */
|
|
37
|
+
export function applySuggestion(line, value) {
|
|
38
|
+
const i = Math.max(line.lastIndexOf(' '), line.lastIndexOf('\t'));
|
|
39
|
+
return line.slice(0, i + 1) + value + ' ';
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=complete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/ui/complete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SessionInfo {
|
|
2
|
+
version: string;
|
|
3
|
+
folder: string;
|
|
4
|
+
branch?: string;
|
|
5
|
+
changed?: number;
|
|
6
|
+
provider?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
}
|
|
9
|
+
/** What the header shows: where you are, what changed, and which model reviews it. */
|
|
10
|
+
export declare function loadSessionInfo(cwd: string, version: string): Promise<SessionInfo>;
|
|
11
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/ui/context.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAUD,sFAAsF;AACtF,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBxF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { basename } from 'path';
|
|
3
|
+
import { configManager } from '../config/manager.js';
|
|
4
|
+
import { AIProviderFactory } from '../ai/factory.js';
|
|
5
|
+
function git(cwd, args) {
|
|
6
|
+
try {
|
|
7
|
+
return execFileSync('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** What the header shows: where you are, what changed, and which model reviews it. */
|
|
14
|
+
export async function loadSessionInfo(cwd, version) {
|
|
15
|
+
const root = git(cwd, ['rev-parse', '--show-toplevel']);
|
|
16
|
+
const info = { version, folder: basename(root ?? cwd) };
|
|
17
|
+
if (root) {
|
|
18
|
+
info.branch = git(root, ['rev-parse', '--abbrev-ref', 'HEAD']) || undefined;
|
|
19
|
+
const status = git(root, ['status', '--porcelain']);
|
|
20
|
+
info.changed = status === undefined ? undefined : status.split('\n').filter(Boolean).length;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
if (await configManager.exists()) {
|
|
24
|
+
const config = await configManager.load();
|
|
25
|
+
if (config.activeProvider) {
|
|
26
|
+
info.provider = config.activeProvider;
|
|
27
|
+
const p = config.providers[config.activeProvider];
|
|
28
|
+
info.model = p?.model || AIProviderFactory.getRecommendedModel(config.activeProvider);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Unreadable config: the header just shows the setup hint
|
|
34
|
+
}
|
|
35
|
+
return info;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/ui/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAWrD,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc;IACpC,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7G,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,OAAe;IAC9D,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;IACrE,IAAI,IAAI,EAAE,CAAC;QACP,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,SAAS,CAAC;QAC5E,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAChG,CAAC;IACD,IAAI,CAAC;QACD,IAAI,MAAM,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC;gBACtC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAmC,CAAC;gBACpF,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,iBAAiB,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC1F,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,0DAA0D;IAC9D,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/ui/session.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AA2D3D,wBAAsB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgD1F"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render } from 'ink';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { Banner, Prompt } from './App.js';
|
|
9
|
+
import { BUILTINS } from './complete.js';
|
|
10
|
+
import { loadSessionInfo } from './context.js';
|
|
11
|
+
import { splitWords } from './words.js';
|
|
12
|
+
const HISTORY_FILE = join(homedir(), '.ownkey', 'history');
|
|
13
|
+
const HISTORY_MAX = 500;
|
|
14
|
+
function loadHistory() {
|
|
15
|
+
try {
|
|
16
|
+
return readFileSync(HISTORY_FILE, 'utf-8').split('\n').filter(Boolean).slice(-HISTORY_MAX);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function saveHistory(history) {
|
|
23
|
+
try {
|
|
24
|
+
mkdirSync(join(homedir(), '.ownkey'), { recursive: true });
|
|
25
|
+
writeFileSync(HISTORY_FILE, history.slice(-HISTORY_MAX).join('\n') + '\n', { mode: 0o600 });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// History is a convenience; never fail a session over it
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function ask(props) {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
let answer = null;
|
|
34
|
+
const app = render(_jsx(Prompt, { ...props, onDone: (line) => (answer = line) }), { exitOnCtrlC: false });
|
|
35
|
+
app.waitUntilExit().then(() => resolve(answer));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** Run one ownkey command as a child process with the real terminal, exactly as if typed in a shell. */
|
|
39
|
+
function runCommand(args) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
// Ctrl+C belongs to the running command; the session survives it
|
|
42
|
+
const ignore = () => undefined;
|
|
43
|
+
process.on('SIGINT', ignore);
|
|
44
|
+
const child = spawn(process.execPath, [...process.execArgv, process.argv[1], ...args], {
|
|
45
|
+
stdio: 'inherit',
|
|
46
|
+
env: { ...process.env, OWNKEY_NO_UI: '1' },
|
|
47
|
+
});
|
|
48
|
+
const done = (code) => {
|
|
49
|
+
process.off('SIGINT', ignore);
|
|
50
|
+
resolve(code);
|
|
51
|
+
};
|
|
52
|
+
child.on('error', () => done(2));
|
|
53
|
+
child.on('close', (code, signal) => done(code ?? (signal ? 130 : 1)));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function printHelp(commands) {
|
|
57
|
+
const rows = [...commands, ...BUILTINS];
|
|
58
|
+
console.log('');
|
|
59
|
+
for (const c of rows)
|
|
60
|
+
console.log(` ${chalk.bold(c.name.padEnd(10))} ${chalk.gray(c.description)}`);
|
|
61
|
+
console.log(chalk.gray('\n Add --help to any command for its options, e.g. review --help'));
|
|
62
|
+
console.log(chalk.gray(' Keys: Tab complete, ↑↓ history or suggestions, ←→ move, Ctrl+U clear line, Esc clear, Ctrl+D exit\n'));
|
|
63
|
+
}
|
|
64
|
+
export async function startSession(commands, version) {
|
|
65
|
+
const history = loadHistory();
|
|
66
|
+
const known = new Set(commands.map((c) => c.name));
|
|
67
|
+
const banner = render(_jsx(Banner, { version: version }));
|
|
68
|
+
banner.unmount();
|
|
69
|
+
for (;;) {
|
|
70
|
+
const info = await loadSessionInfo(process.cwd(), version);
|
|
71
|
+
const line = await ask({ info, commands, history });
|
|
72
|
+
if (line === null)
|
|
73
|
+
break;
|
|
74
|
+
const trimmed = line.trim();
|
|
75
|
+
if (!trimmed)
|
|
76
|
+
continue;
|
|
77
|
+
if (history[history.length - 1] !== trimmed)
|
|
78
|
+
history.push(trimmed);
|
|
79
|
+
saveHistory(history);
|
|
80
|
+
let args;
|
|
81
|
+
try {
|
|
82
|
+
args = splitWords(trimmed);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.log(chalk.red(` ${e.message}`));
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (args[0] === 'ownkey')
|
|
89
|
+
args = args.slice(1);
|
|
90
|
+
const [name] = args;
|
|
91
|
+
if (!name)
|
|
92
|
+
continue;
|
|
93
|
+
if (name === 'exit' || name === 'quit' || name === 'q')
|
|
94
|
+
break;
|
|
95
|
+
if (name === 'help' || name === '?') {
|
|
96
|
+
printHelp(commands);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (name === 'clear' || name === 'cls') {
|
|
100
|
+
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (!known.has(name) && !name.startsWith('-')) {
|
|
104
|
+
console.log(chalk.yellow(` Unknown command "${name}". Type help to see them all.`));
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const started = Date.now();
|
|
108
|
+
const code = await runCommand(args);
|
|
109
|
+
const secs = ((Date.now() - started) / 1000).toFixed(1);
|
|
110
|
+
console.log(code === 0 ? chalk.gray(` ✓ done in ${secs}s\n`) : chalk.red(` ✗ exited with code ${code} after ${secs}s\n`));
|
|
111
|
+
}
|
|
112
|
+
console.log(chalk.gray(' Bye.'));
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/ui/session.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC3D,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,SAAS,WAAW;IAChB,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,OAAiB;IAClC,IAAI,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACL,yDAAyD;IAC7D,CAAC;AACL,CAAC;AAED,SAAS,GAAG,CAAC,KAA0D;IACnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAC,MAAM,OAAK,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;QACrG,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,wGAAwG;AACxG,SAAS,UAAU,CAAC,IAAc;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,iEAAiE;QACjE,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE;YACnF,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;SAC7C,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;YAC1B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,SAAS,CAAC,QAAuB;IACtC,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uGAAuG,CAAC,CAAC,CAAC;AACrI,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAuB,EAAE,OAAe;IACvE,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,CAAC;IAEjB,SAAS,CAAC;QACN,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,IAAI,IAAI,KAAK,IAAI;YAAE,MAAM;QAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnE,WAAW,CAAC,OAAO,CAAC,CAAC;QAErB,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC;YACD,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,SAAS;QACb,CAAC;QACD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG;YAAE,MAAM;QAC9D,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAClC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpB,SAAS;QACb,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC7C,SAAS;QACb,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,IAAI,+BAA+B,CAAC,CAAC,CAAC;YACrF,SAAS;QACb,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,IAAI,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC;IAChI,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a typed command line into arguments the way a shell would for simple cases:
|
|
3
|
+
* whitespace separates, single and double quotes group, backslash escapes the next character.
|
|
4
|
+
*/
|
|
5
|
+
export declare function splitWords(line: string): string[];
|
|
6
|
+
//# sourceMappingURL=words.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.d.ts","sourceRoot":"","sources":["../../src/ui/words.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BjD"}
|
package/dist/ui/words.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a typed command line into arguments the way a shell would for simple cases:
|
|
3
|
+
* whitespace separates, single and double quotes group, backslash escapes the next character.
|
|
4
|
+
*/
|
|
5
|
+
export function splitWords(line) {
|
|
6
|
+
const out = [];
|
|
7
|
+
let cur = '';
|
|
8
|
+
let quote = null;
|
|
9
|
+
let has = false;
|
|
10
|
+
for (let i = 0; i < line.length; i++) {
|
|
11
|
+
const ch = line[i];
|
|
12
|
+
if (quote) {
|
|
13
|
+
if (ch === quote)
|
|
14
|
+
quote = null;
|
|
15
|
+
else if (ch === '\\' && quote === '"' && i + 1 < line.length)
|
|
16
|
+
cur += line[++i];
|
|
17
|
+
else
|
|
18
|
+
cur += ch;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ch === '"' || ch === "'") {
|
|
22
|
+
quote = ch;
|
|
23
|
+
has = true;
|
|
24
|
+
}
|
|
25
|
+
else if (ch === '\\' && i + 1 < line.length) {
|
|
26
|
+
cur += line[++i];
|
|
27
|
+
has = true;
|
|
28
|
+
}
|
|
29
|
+
else if (/\s/.test(ch)) {
|
|
30
|
+
if (has)
|
|
31
|
+
out.push(cur);
|
|
32
|
+
cur = '';
|
|
33
|
+
has = false;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
cur += ch;
|
|
37
|
+
has = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (quote)
|
|
41
|
+
throw new Error('Unclosed quote');
|
|
42
|
+
if (has)
|
|
43
|
+
out.push(cur);
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=words.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.js","sourceRoot":"","sources":["../../src/ui/words.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,KAAK,GAAqB,IAAI,CAAC;IACnC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,EAAE,KAAK,KAAK;gBAAE,KAAK,GAAG,IAAI,CAAC;iBAC1B,IAAI,EAAE,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;;gBAC1E,GAAG,IAAI,EAAE,CAAC;YACf,SAAS;QACb,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC3B,KAAK,GAAG,EAAE,CAAC;YACX,GAAG,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACjB,GAAG,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,IAAI,GAAG;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,GAAG,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,KAAK,CAAC;QAChB,CAAC;aAAM,CAAC;YACJ,GAAG,IAAI,EAAE,CAAC;YACV,GAAG,GAAG,IAAI,CAAC;QACf,CAAC;IACL,CAAC;IACD,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,GAAG;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ownkey",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Local-first AI code reviewer CLI: review git changes, gate PRs with SARIF, and apply verified fixes using your own OpenAI, Anthropic, Gemini, or Ollama keys",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -56,24 +56,28 @@
|
|
|
56
56
|
"node": ">=18.0.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"chalk": "^5.3.0",
|
|
59
60
|
"commander": "^12.1.0",
|
|
61
|
+
"diff": "^7.0.0",
|
|
60
62
|
"drizzle-orm": "^0.36.4",
|
|
61
|
-
"postgres": "^3.4.5",
|
|
62
|
-
"chalk": "^5.3.0",
|
|
63
|
-
"ora": "^8.1.1",
|
|
64
|
-
"inquirer": "^12.2.0",
|
|
65
63
|
"ignore": "^6.0.2",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
64
|
+
"ink": "^5.2.1",
|
|
65
|
+
"inquirer": "^12.2.0",
|
|
66
|
+
"keytar": "^7.9.0",
|
|
67
|
+
"ora": "^8.1.1",
|
|
68
|
+
"postgres": "^3.4.5",
|
|
69
|
+
"react": "^18.3.1"
|
|
68
70
|
},
|
|
69
71
|
"devDependencies": {
|
|
70
|
-
"@types/node": "^22.10.5",
|
|
71
72
|
"@types/diff": "^6.0.0",
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
73
|
+
"@types/node": "^22.10.5",
|
|
74
|
+
"@types/react": "^18.3.31",
|
|
75
|
+
"drizzle-kit": "^0.30.1",
|
|
75
76
|
"eslint": "^9.18.0",
|
|
77
|
+
"ink-testing-library": "^4.0.0",
|
|
76
78
|
"prettier": "^3.4.2",
|
|
77
|
-
"
|
|
79
|
+
"tsx": "^4.19.2",
|
|
80
|
+
"typescript": "^5.7.3",
|
|
81
|
+
"vitest": "^2.1.8"
|
|
78
82
|
}
|
|
79
83
|
}
|