oharness 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/bin/sync.d.ts +3 -0
  2. package/dist/bin/sync.js +4 -0
  3. package/dist/bin/sync.js.map +1 -0
  4. package/dist/bin/web.d.ts +10 -0
  5. package/dist/bin/web.js +11 -0
  6. package/dist/bin/web.js.map +1 -0
  7. package/dist/headless/main.d.ts +2 -0
  8. package/dist/headless/main.js +133 -0
  9. package/dist/headless/main.js.map +1 -0
  10. package/dist/index.d.ts +8 -0
  11. package/dist/index.js +9 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/providers.d.ts +2 -0
  14. package/dist/providers.js +3 -0
  15. package/dist/providers.js.map +1 -0
  16. package/dist/tools.d.ts +2 -0
  17. package/dist/tools.js +3 -0
  18. package/dist/tools.js.map +1 -0
  19. package/dist/ui/artifact.d.ts +32 -0
  20. package/dist/ui/artifact.js +49 -0
  21. package/dist/ui/artifact.js.map +1 -0
  22. package/dist/ui/auth.d.ts +14 -0
  23. package/dist/ui/auth.js +177 -0
  24. package/dist/ui/auth.js.map +1 -0
  25. package/dist/ui/colors.d.ts +21 -0
  26. package/dist/ui/colors.js +28 -0
  27. package/dist/ui/colors.js.map +1 -0
  28. package/dist/ui/ink/app.d.ts +13 -0
  29. package/dist/ui/ink/app.js +418 -0
  30. package/dist/ui/ink/app.js.map +1 -0
  31. package/dist/ui/ink/logo.d.ts +6 -0
  32. package/dist/ui/ink/logo.js +20 -0
  33. package/dist/ui/ink/logo.js.map +1 -0
  34. package/dist/ui/ink/main.d.ts +2 -0
  35. package/dist/ui/ink/main.js +55 -0
  36. package/dist/ui/ink/main.js.map +1 -0
  37. package/dist/ui/ink/screen.d.ts +15 -0
  38. package/dist/ui/ink/screen.js +76 -0
  39. package/dist/ui/ink/screen.js.map +1 -0
  40. package/dist/ui/ink/select.d.ts +24 -0
  41. package/dist/ui/ink/select.js +74 -0
  42. package/dist/ui/ink/select.js.map +1 -0
  43. package/dist/ui/main.d.ts +2 -0
  44. package/dist/ui/main.js +1062 -0
  45. package/dist/ui/main.js.map +1 -0
  46. package/dist/ui/render.d.ts +15 -0
  47. package/dist/ui/render.js +130 -0
  48. package/dist/ui/render.js.map +1 -0
  49. package/dist/ui/select.d.ts +26 -0
  50. package/dist/ui/select.js +107 -0
  51. package/dist/ui/select.js.map +1 -0
  52. package/dist/ui/tui/app.d.ts +96 -0
  53. package/dist/ui/tui/app.js +476 -0
  54. package/dist/ui/tui/app.js.map +1 -0
  55. package/dist/ui/tui/editor.d.ts +40 -0
  56. package/dist/ui/tui/editor.js +124 -0
  57. package/dist/ui/tui/editor.js.map +1 -0
  58. package/dist/ui/tui/keys.d.ts +25 -0
  59. package/dist/ui/tui/keys.js +133 -0
  60. package/dist/ui/tui/keys.js.map +1 -0
  61. package/dist/ui/tui/layout.d.ts +63 -0
  62. package/dist/ui/tui/layout.js +202 -0
  63. package/dist/ui/tui/layout.js.map +1 -0
  64. package/dist/ui/tui/logo.d.ts +18 -0
  65. package/dist/ui/tui/logo.js +33 -0
  66. package/dist/ui/tui/logo.js.map +1 -0
  67. package/dist/ui/tui/screen.d.ts +48 -0
  68. package/dist/ui/tui/screen.js +150 -0
  69. package/dist/ui/tui/screen.js.map +1 -0
  70. package/dist/ui/tui/width.d.ts +30 -0
  71. package/dist/ui/tui/width.js +197 -0
  72. package/dist/ui/tui/width.js.map +1 -0
  73. package/dist/ui/wordmark.d.ts +30 -0
  74. package/dist/ui/wordmark.js +63 -0
  75. package/dist/ui/wordmark.js.map +1 -0
  76. package/package.json +49 -0
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ export interface Option<T> {
3
+ value: T;
4
+ label: string;
5
+ /** Dimmed, right-aligned: a provider, a context size, a timestamp. */
6
+ hint?: string;
7
+ /** Grouped under this heading, in the order groups first appear. */
8
+ group?: string;
9
+ /** Marked with a check as the value currently in force. */
10
+ current?: boolean;
11
+ }
12
+ export interface SelectProps<T> {
13
+ title: string;
14
+ options: Option<T>[];
15
+ onPick: (value: T) => void;
16
+ /** Cancelling must never resolve to the highlighted row. */
17
+ onCancel: () => void;
18
+ /** Lines above the list: a command, a reason, the arguments being approved. */
19
+ detail?: string[];
20
+ /** Below this many options the filter is noise. */
21
+ filterFrom?: number;
22
+ height?: number;
23
+ }
24
+ export declare function Select<T>({ title, options, onPick, onCancel, detail, filterFrom, height, }: SelectProps<T>): React.ReactElement;
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import { Box, Text, useInput } from "ink";
3
+ /**
4
+ * The one dialog primitive.
5
+ *
6
+ * opencode builds two dozen dialogs — model, provider, session, theme, agent,
7
+ * skill, MCP — on a single filterable select, and that is the load-bearing
8
+ * decision rather than any particular layout: a new picker becomes a list of
9
+ * options instead of another hand-written keyboard loop, and every one of them
10
+ * filters and navigates identically.
11
+ */
12
+ const h = React.createElement;
13
+ export function Select({ title, options, onPick, onCancel, detail, filterFrom = 8, height = 12, }) {
14
+ const [query, setQuery] = React.useState("");
15
+ const [cursor, setCursor] = React.useState(() => Math.max(0, options.findIndex((option) => option.current)));
16
+ const matches = React.useMemo(() => {
17
+ if (!query)
18
+ return options;
19
+ // Every word must appear somewhere, so "qwen flash" finds qwen/qwen3-flash
20
+ // regardless of the order typed. A substring match on the whole query
21
+ // fails that, and typing vendor-first is as common as model-first.
22
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
23
+ return options.filter((option) => {
24
+ const hay = `${option.label} ${option.group ?? ""} ${option.hint ?? ""}`.toLowerCase();
25
+ return words.every((word) => hay.includes(word));
26
+ });
27
+ }, [options, query]);
28
+ React.useEffect(() => {
29
+ if (cursor >= matches.length)
30
+ setCursor(Math.max(0, matches.length - 1));
31
+ }, [matches.length, cursor]);
32
+ useInput((char, key) => {
33
+ if (key.escape || (key.ctrl && char === "c"))
34
+ return onCancel();
35
+ if (key.return) {
36
+ const picked = matches[cursor];
37
+ if (picked)
38
+ onPick(picked.value);
39
+ return;
40
+ }
41
+ if (key.upArrow)
42
+ return setCursor((at) => (at - 1 + matches.length) % Math.max(1, matches.length));
43
+ if (key.downArrow)
44
+ return setCursor((at) => (at + 1) % Math.max(1, matches.length));
45
+ if (key.backspace || key.delete) {
46
+ setCursor(0);
47
+ return setQuery((value) => [...value].slice(0, -1).join(""));
48
+ }
49
+ if (char && !key.ctrl && !key.meta) {
50
+ setCursor(0);
51
+ setQuery((value) => value + char);
52
+ }
53
+ });
54
+ // A window around the cursor, so a four-hundred-model list scrolls rather
55
+ // than rendering four hundred rows Ink then has to diff.
56
+ const start = Math.max(0, Math.min(cursor - Math.floor(height / 2), matches.length - height));
57
+ const visible = matches.slice(Math.max(0, start), Math.max(0, start) + height);
58
+ let lastGroup;
59
+ const rows = [];
60
+ visible.forEach((option, i) => {
61
+ const index = Math.max(0, start) + i;
62
+ if (option.group && option.group !== lastGroup) {
63
+ lastGroup = option.group;
64
+ rows.push(h(Text, { key: `g${index}`, dimColor: true }, ` ${option.group.toUpperCase()}`));
65
+ }
66
+ rows.push(h(Box, { key: index }, h(Text, { color: index === cursor ? "cyan" : undefined }, index === cursor ? "❯ " : " "), h(Text, { color: option.current ? "green" : undefined }, option.current ? "✓ " : " "), h(Text, { bold: index === cursor }, option.label), option.hint ? h(Text, { dimColor: true }, ` ${option.hint}`) : null));
67
+ });
68
+ return h(Box, { flexDirection: "column", borderStyle: "round", borderDimColor: true, paddingX: 1 }, h(Text, { bold: true }, title), ...(detail ?? []).map((line, i) => h(Text, { key: `d${i}`, dimColor: true }, line)), options.length >= filterFrom
69
+ ? h(Text, { dimColor: true }, query ? `filter: ${query}` : "type to filter")
70
+ : null, ...rows, matches.length === 0 ? h(Text, { dimColor: true }, " no match") : null, matches.length > visible.length
71
+ ? h(Text, { dimColor: true }, ` ${matches.length} total`)
72
+ : null);
73
+ }
74
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../src/ui/ink/select.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};