@orbit-intelligence/orbit-agent 0.3.12

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 (80) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +23 -0
  3. package/bin/orbit +26 -0
  4. package/dist/prompts/system.js +80 -0
  5. package/dist/src/cli/args.js +145 -0
  6. package/dist/src/cli/orchestrate.js +100 -0
  7. package/dist/src/cli/run.js +393 -0
  8. package/dist/src/config/config-schema.js +151 -0
  9. package/dist/src/config/index.js +57 -0
  10. package/dist/src/core/agent/agent-loop.js +402 -0
  11. package/dist/src/core/agents/delegate.js +120 -0
  12. package/dist/src/core/agents/orchestrator.js +58 -0
  13. package/dist/src/core/agents/prompts.js +82 -0
  14. package/dist/src/core/agents/types.js +1 -0
  15. package/dist/src/core/context/context-manager.js +167 -0
  16. package/dist/src/core/events.js +23 -0
  17. package/dist/src/core/llm/http.js +207 -0
  18. package/dist/src/core/llm/index.js +93 -0
  19. package/dist/src/core/llm/models.js +228 -0
  20. package/dist/src/core/llm/providers/gemini.js +211 -0
  21. package/dist/src/core/llm/providers/openai-compat.js +31 -0
  22. package/dist/src/core/llm/router.js +125 -0
  23. package/dist/src/core/llm/secrets.js +121 -0
  24. package/dist/src/core/llm/types.js +10 -0
  25. package/dist/src/core/orchestration/dispatcher.js +74 -0
  26. package/dist/src/core/orchestration/messenger.js +139 -0
  27. package/dist/src/core/orchestration/roles.js +129 -0
  28. package/dist/src/core/orchestration/runtime.js +122 -0
  29. package/dist/src/core/orchestration/session.js +204 -0
  30. package/dist/src/core/orchestration/shared-context.js +88 -0
  31. package/dist/src/core/orchestration/tools.js +187 -0
  32. package/dist/src/core/orchestration/types.js +3 -0
  33. package/dist/src/core/permissions/index.js +58 -0
  34. package/dist/src/core/project-context.js +115 -0
  35. package/dist/src/core/skill-loader.js +31 -0
  36. package/dist/src/core/tools/edit.js +142 -0
  37. package/dist/src/core/tools/filesystem.js +203 -0
  38. package/dist/src/core/tools/git.js +138 -0
  39. package/dist/src/core/tools/registry.js +73 -0
  40. package/dist/src/core/tools/search.js +90 -0
  41. package/dist/src/core/tools/shell.js +65 -0
  42. package/dist/src/core/tools/types.js +6 -0
  43. package/dist/src/core/types.js +3 -0
  44. package/dist/src/index.js +11 -0
  45. package/dist/src/session/event-log.js +55 -0
  46. package/dist/src/session/store.js +76 -0
  47. package/dist/src/setup/wizard.js +401 -0
  48. package/dist/src/tui/InkApp.js +67 -0
  49. package/dist/src/tui/ansi.js +142 -0
  50. package/dist/src/tui/app.js +768 -0
  51. package/dist/src/tui/colors.js +13 -0
  52. package/dist/src/tui/components/AgentDock.js +46 -0
  53. package/dist/src/tui/components/Composer.js +35 -0
  54. package/dist/src/tui/components/Header.js +23 -0
  55. package/dist/src/tui/components/ModelPicker.js +23 -0
  56. package/dist/src/tui/components/PermissionModal.js +29 -0
  57. package/dist/src/tui/components/SlashMenu.js +15 -0
  58. package/dist/src/tui/components/StatusLine.js +27 -0
  59. package/dist/src/tui/components/Transcript.js +31 -0
  60. package/dist/src/tui/components/WorkingStatus.js +29 -0
  61. package/dist/src/tui/components/input.js +246 -0
  62. package/dist/src/tui/components/markdown.js +384 -0
  63. package/dist/src/tui/components/message.js +105 -0
  64. package/dist/src/tui/context.js +8 -0
  65. package/dist/src/tui/geometry.js +40 -0
  66. package/dist/src/tui/renderer.js +116 -0
  67. package/dist/src/tui/rows.js +247 -0
  68. package/dist/src/tui/scheduler.js +32 -0
  69. package/dist/src/tui/store.js +127 -0
  70. package/dist/src/tui/style.js +151 -0
  71. package/dist/src/tui/term.js +309 -0
  72. package/dist/src/tui/text.js +104 -0
  73. package/dist/src/tui/themes/index.js +15 -0
  74. package/dist/src/tui/themes/palettes.js +137 -0
  75. package/dist/src/tui/themes/types.js +1 -0
  76. package/dist/src/utils/diff.js +161 -0
  77. package/dist/src/utils/platform.js +71 -0
  78. package/dist/src/utils/signals.js +26 -0
  79. package/dist/src/version.js +4 -0
  80. package/package.json +71 -0
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Box, Text, useInput, useWindowSize } from 'ink';
4
+ import { StoreContext } from './context.js';
5
+ import { rowsFromMessages } from './rows.js';
6
+ import { buildTheme } from './style.js';
7
+ import { Header } from './components/Header.js';
8
+ import { Transcript } from './components/Transcript.js';
9
+ import { WorkingStatus } from './components/WorkingStatus.js';
10
+ import { SlashMenu } from './components/SlashMenu.js';
11
+ import { ModelPicker } from './components/ModelPicker.js';
12
+ import { AgentDock } from './components/AgentDock.js';
13
+ import { Composer } from './components/Composer.js';
14
+ import { PermissionModal } from './components/PermissionModal.js';
15
+ import { StatusLine } from './components/StatusLine.js';
16
+ import { chromeHeight, composerHeight } from './geometry.js';
17
+ export function InkApp({ controller }) {
18
+ const store = controller.store;
19
+ const { columns, rows } = useWindowSize();
20
+ const [, setTick] = useState(0);
21
+ useEffect(() => {
22
+ return store.onRender(() => setTick((t) => t + 1));
23
+ }, [store]);
24
+ useInput((input, key) => {
25
+ controller.handleKey(input, key);
26
+ controller.refresh();
27
+ });
28
+ const cols = Math.max(20, columns);
29
+ // Reserve the final terminal row: an Ink frame that fills every row makes the
30
+ // terminal scroll on the trailing newline, which desyncs Ink's incremental
31
+ // diff and interleaves streamed text.
32
+ const bodyRows = Math.max(1, rows - 1);
33
+ const theme = store.theme ?? buildTheme('tokyonight');
34
+ const menuing = store.input.currentBuffer().startsWith('/');
35
+ const menuLines = menuing ? store.slashMatches().length + 1 : 0;
36
+ const modelLines = store.modelPicker.open ? Math.min(store.models.length, 10) + 1 : 0;
37
+ const dockLines = store.dockOpen
38
+ ? store.agents.size === 0
39
+ ? 2
40
+ : Math.min(store.agents.size + 1, 10)
41
+ : 0;
42
+ const working = store.streaming && !store.pendingAsk;
43
+ const compH = store.pendingAsk ? 1 : composerHeight(store.input, cols);
44
+ const chrome = chromeHeight({
45
+ working,
46
+ menuLines,
47
+ modelLines,
48
+ dockLines,
49
+ ask: Boolean(store.pendingAsk),
50
+ composerH: compH,
51
+ });
52
+ const viewport = Math.max(0, bodyRows - chrome);
53
+ let msgRows = [];
54
+ if (store.messages.length === 0) {
55
+ const dim = theme.table.sgr(theme.styles['dim']);
56
+ msgRows = [{ id: 'hint', text: `${dim}type a message to get started${'\x1b[0m'}` }];
57
+ }
58
+ else {
59
+ msgRows = rowsFromMessages(store.messages, theme, {
60
+ thinkingDefaultOpen: store.thinkingDefaultOpen,
61
+ width: cols,
62
+ streamingId: store.findStreaming()?.id,
63
+ revealChars: store.revealChars,
64
+ });
65
+ }
66
+ return (_jsx(StoreContext.Provider, { value: store, children: _jsxs(Box, { width: cols, height: bodyRows, flexDirection: "column", overflow: "hidden", children: [_jsx(Header, { width: cols }), _jsx(Text, { dimColor: true, children: 'Tip: /help for commands · /theme to switch' }), _jsx(Transcript, { rows: msgRows, viewport: viewport }), working && _jsx(WorkingStatus, {}), store.pendingAsk && _jsx(PermissionModal, { cols: cols }), store.dockOpen && _jsx(AgentDock, { width: cols, height: dockLines }), menuing && _jsx(SlashMenu, { width: cols }), store.modelPicker.open && _jsx(ModelPicker, { width: cols }), _jsx(Box, { height: 1, children: _jsx(Text, { dimColor: true, wrap: "truncate-end", children: '─'.repeat(Math.max(1, cols)) }) }), _jsx(Composer, {}), _jsx(StatusLine, { width: cols })] }) }));
67
+ }
@@ -0,0 +1,142 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ /**
4
+ * Converts a line that may contain 24-bit ANSI SGR escapes into Ink
5
+ * `Text` elements, so the existing markdown/highlighting pipeline
6
+ * (`renderMarkdown`, `messageToLines`. `renderInputArea`) can be reused
7
+ * verbatim inside the Ink renderer instead of being re-implemented.
8
+ *
9
+ * Only the SGR forms emitted by `sgrFor` are expected:
10
+ * \x1b[<38;2;r;g;b | 48;2;r;g;b | 1 | 2 | 3 | 4 | 7 | 9 where applicable>m
11
+ * and the reset \x1b[0m. Unknown sequences are preserved harmlessly.
12
+ */
13
+ const ESC = '\x1b[';
14
+ const SGR_RE = /^(.*?)(\x1b\[[0-9;]*m)/gs;
15
+ function rgbToHex(v) {
16
+ const r = (v >> 16) & 0xff;
17
+ const g = (v >> 8) & 0xff;
18
+ const b = v & 0xff;
19
+ return `#${[r, g, b].map((x) => x.toString(16).padStart(2, '0')).join('')}`;
20
+ }
21
+ function propsForStyle(style) {
22
+ const props = {};
23
+ if (style.fg != null)
24
+ props.color = rgbToHex(style.fg);
25
+ if (style.bg != null)
26
+ props.backgroundColor = rgbToHex(style.bg);
27
+ if (style.bold)
28
+ props.bold = true;
29
+ if (style.dim)
30
+ props.dimColor = true;
31
+ if (style.italic)
32
+ props.italic = true;
33
+ if (style.underline)
34
+ props.underline = true;
35
+ if (style.inverse)
36
+ props.inverse = true;
37
+ if (style.strikethrough)
38
+ props.strikethrough = true;
39
+ return props;
40
+ }
41
+ function isValidSgrCode(body) {
42
+ return /^[0-9;]*$/.test(body);
43
+ }
44
+ /**
45
+ * Produce an Ink node tree for an ANSI string. A single text run is returned
46
+ * as one <Text>; multiple runs are wrapped in one parent <Text> whose children
47
+ * each carry their own style.
48
+ */
49
+ export function renderAnsi(text, key) {
50
+ const segments = [];
51
+ let style = {};
52
+ let plain = '';
53
+ let i = 0;
54
+ let lastEnd = 0;
55
+ // Tokenize by SGR codes.
56
+ const re = /\x1b\[([0-9;]*)m/g;
57
+ let match;
58
+ while ((match = re.exec(text)) !== null) {
59
+ const body = match[1];
60
+ const escStart = match.index;
61
+ if (escStart > lastEnd) {
62
+ const run = text.slice(lastEnd, escStart);
63
+ if (run.length > 0) {
64
+ const props = propsForStyle(style);
65
+ segments.push(Object.keys(props).length > 0 ? (_jsx(Text, { ...props, children: run }, `s${i}`)) : (run));
66
+ i++;
67
+ }
68
+ }
69
+ if (isValidSgrCode(body)) {
70
+ if (body === '' || body === '0')
71
+ style = {};
72
+ else
73
+ style = applySgr(style, body);
74
+ }
75
+ lastEnd = escStart + match[0].length;
76
+ }
77
+ const tail = text.slice(lastEnd);
78
+ if (tail.length > 0) {
79
+ const props = propsForStyle(style);
80
+ plain += tail;
81
+ segments.push(Object.keys(props).length > 0 ? _jsx(Text, { ...props, children: tail }, `s${i}`) : tail);
82
+ i++;
83
+ }
84
+ if (segments.length === 0)
85
+ return _jsx(Text, { children: text }, key);
86
+ // All-plain fast path.
87
+ if (segments.length === 1 && typeof segments[0] === 'string') {
88
+ return _jsx(Text, { children: segments[0] }, key);
89
+ }
90
+ // Merge a leading plain string into the parent Text where possible; Ink
91
+ // renders nested Text fine, so simply wrap.
92
+ return _jsx(Text, { children: segments }, key);
93
+ }
94
+ function applySgr(style, body) {
95
+ const next = { ...style };
96
+ const parts = body.split(';');
97
+ for (let p = 0; p < parts.length; p++) {
98
+ const n = parseInt(parts[p] ?? '', 10);
99
+ if (Number.isNaN(n))
100
+ continue;
101
+ if (n === 1)
102
+ next.bold = true;
103
+ else if (n === 2)
104
+ next.dim = true;
105
+ else if (n === 3)
106
+ next.italic = true;
107
+ else if (n === 4)
108
+ next.underline = true;
109
+ else if (n === 7)
110
+ next.inverse = true;
111
+ else if (n === 9)
112
+ next.strikethrough = true;
113
+ else if ((n === 38 || n === 48) && parts[p + 1] === '2') {
114
+ const r = Number(parts[p + 2] ?? 0);
115
+ const g = Number(parts[p + 3] ?? 0);
116
+ const b = Number(parts[p + 4] ?? 0);
117
+ const fg = (r << 16) | (g << 8) | b;
118
+ if (n === 38)
119
+ next.fg = fg;
120
+ else
121
+ next.bg = fg;
122
+ p += 4;
123
+ }
124
+ // 39/49 reset fg/bg; 22/23/24/27/29 unset attributes
125
+ else if (n === 39)
126
+ delete next.fg;
127
+ else if (n === 49)
128
+ delete next.bg;
129
+ else if (n === 22)
130
+ next.bold = false;
131
+ else if (n === 23)
132
+ next.italic = false;
133
+ else if (n === 24)
134
+ next.underline = false;
135
+ else if (n === 27)
136
+ next.inverse = false;
137
+ else if (n === 29)
138
+ next.strikethrough = false;
139
+ }
140
+ return next;
141
+ }
142
+ export { SGR_RE as sgrTokenPattern };