@vsuryav/agent-sim 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 (154) hide show
  1. package/README.md +25 -0
  2. package/bin/agent-sim.js +25 -0
  3. package/package.json +72 -0
  4. package/src/app-paths.ts +29 -0
  5. package/src/app-sync.test.ts +75 -0
  6. package/src/app-sync.ts +110 -0
  7. package/src/cli.ts +129 -0
  8. package/src/collector/claude-code.test.ts +102 -0
  9. package/src/collector/claude-code.ts +133 -0
  10. package/src/collector/codex-cli.test.ts +116 -0
  11. package/src/collector/codex-cli.ts +149 -0
  12. package/src/collector/db.test.ts +59 -0
  13. package/src/collector/db.ts +125 -0
  14. package/src/collector/names.test.ts +21 -0
  15. package/src/collector/names.ts +28 -0
  16. package/src/collector/personality.test.ts +40 -0
  17. package/src/collector/personality.ts +46 -0
  18. package/src/collector/remote-sync.test.ts +31 -0
  19. package/src/collector/remote-sync.ts +171 -0
  20. package/src/collector/sync.test.ts +67 -0
  21. package/src/collector/sync.ts +148 -0
  22. package/src/collector/types.ts +1 -0
  23. package/src/engine/bootstrap/state.ts +3 -0
  24. package/src/engine/buddy/CompanionSprite.tsx +371 -0
  25. package/src/engine/buddy/companion.ts +133 -0
  26. package/src/engine/buddy/prompt.ts +36 -0
  27. package/src/engine/buddy/sprites.ts +514 -0
  28. package/src/engine/buddy/types.ts +148 -0
  29. package/src/engine/buddy/useBuddyNotification.tsx +98 -0
  30. package/src/engine/ink/Ansi.tsx +292 -0
  31. package/src/engine/ink/bidi.ts +139 -0
  32. package/src/engine/ink/clearTerminal.ts +74 -0
  33. package/src/engine/ink/colorize.ts +231 -0
  34. package/src/engine/ink/components/AlternateScreen.tsx +80 -0
  35. package/src/engine/ink/components/App.tsx +658 -0
  36. package/src/engine/ink/components/AppContext.ts +21 -0
  37. package/src/engine/ink/components/Box.tsx +214 -0
  38. package/src/engine/ink/components/Button.tsx +192 -0
  39. package/src/engine/ink/components/ClockContext.tsx +112 -0
  40. package/src/engine/ink/components/CursorDeclarationContext.ts +32 -0
  41. package/src/engine/ink/components/ErrorOverview.tsx +109 -0
  42. package/src/engine/ink/components/Link.tsx +42 -0
  43. package/src/engine/ink/components/Newline.tsx +39 -0
  44. package/src/engine/ink/components/NoSelect.tsx +68 -0
  45. package/src/engine/ink/components/RawAnsi.tsx +57 -0
  46. package/src/engine/ink/components/ScrollBox.tsx +237 -0
  47. package/src/engine/ink/components/Spacer.tsx +20 -0
  48. package/src/engine/ink/components/StdinContext.ts +49 -0
  49. package/src/engine/ink/components/TerminalFocusContext.tsx +52 -0
  50. package/src/engine/ink/components/TerminalSizeContext.tsx +7 -0
  51. package/src/engine/ink/components/Text.tsx +254 -0
  52. package/src/engine/ink/constants.ts +2 -0
  53. package/src/engine/ink/dom.ts +484 -0
  54. package/src/engine/ink/events/click-event.ts +38 -0
  55. package/src/engine/ink/events/dispatcher.ts +233 -0
  56. package/src/engine/ink/events/emitter.ts +39 -0
  57. package/src/engine/ink/events/event-handlers.ts +73 -0
  58. package/src/engine/ink/events/event.ts +11 -0
  59. package/src/engine/ink/events/focus-event.ts +21 -0
  60. package/src/engine/ink/events/input-event.ts +205 -0
  61. package/src/engine/ink/events/keyboard-event.ts +51 -0
  62. package/src/engine/ink/events/terminal-event.ts +107 -0
  63. package/src/engine/ink/events/terminal-focus-event.ts +19 -0
  64. package/src/engine/ink/focus.ts +181 -0
  65. package/src/engine/ink/frame.ts +124 -0
  66. package/src/engine/ink/get-max-width.ts +27 -0
  67. package/src/engine/ink/global.d.ts +18 -0
  68. package/src/engine/ink/hit-test.ts +130 -0
  69. package/src/engine/ink/hooks/use-animation-frame.ts +57 -0
  70. package/src/engine/ink/hooks/use-app.ts +8 -0
  71. package/src/engine/ink/hooks/use-declared-cursor.ts +73 -0
  72. package/src/engine/ink/hooks/use-input.ts +92 -0
  73. package/src/engine/ink/hooks/use-interval.ts +67 -0
  74. package/src/engine/ink/hooks/use-search-highlight.ts +53 -0
  75. package/src/engine/ink/hooks/use-selection.ts +104 -0
  76. package/src/engine/ink/hooks/use-stdin.ts +8 -0
  77. package/src/engine/ink/hooks/use-tab-status.ts +72 -0
  78. package/src/engine/ink/hooks/use-terminal-focus.ts +16 -0
  79. package/src/engine/ink/hooks/use-terminal-title.ts +31 -0
  80. package/src/engine/ink/hooks/use-terminal-viewport.ts +96 -0
  81. package/src/engine/ink/ink.tsx +1723 -0
  82. package/src/engine/ink/instances.ts +10 -0
  83. package/src/engine/ink/layout/engine.ts +6 -0
  84. package/src/engine/ink/layout/geometry.ts +97 -0
  85. package/src/engine/ink/layout/node.ts +152 -0
  86. package/src/engine/ink/layout/yoga.ts +308 -0
  87. package/src/engine/ink/line-width-cache.ts +24 -0
  88. package/src/engine/ink/log-update.ts +773 -0
  89. package/src/engine/ink/measure-element.ts +23 -0
  90. package/src/engine/ink/measure-text.ts +47 -0
  91. package/src/engine/ink/node-cache.ts +54 -0
  92. package/src/engine/ink/optimizer.ts +93 -0
  93. package/src/engine/ink/output.ts +797 -0
  94. package/src/engine/ink/parse-keypress.ts +801 -0
  95. package/src/engine/ink/reconciler.ts +512 -0
  96. package/src/engine/ink/render-border.ts +231 -0
  97. package/src/engine/ink/render-node-to-output.ts +1462 -0
  98. package/src/engine/ink/render-to-screen.ts +231 -0
  99. package/src/engine/ink/renderer.ts +178 -0
  100. package/src/engine/ink/root.ts +184 -0
  101. package/src/engine/ink/screen.ts +1486 -0
  102. package/src/engine/ink/searchHighlight.ts +93 -0
  103. package/src/engine/ink/selection.ts +917 -0
  104. package/src/engine/ink/squash-text-nodes.ts +92 -0
  105. package/src/engine/ink/stringWidth.ts +222 -0
  106. package/src/engine/ink/styles.ts +771 -0
  107. package/src/engine/ink/supports-hyperlinks.ts +57 -0
  108. package/src/engine/ink/tabstops.ts +46 -0
  109. package/src/engine/ink/terminal-focus-state.ts +47 -0
  110. package/src/engine/ink/terminal-querier.ts +212 -0
  111. package/src/engine/ink/terminal.ts +248 -0
  112. package/src/engine/ink/termio/ansi.ts +75 -0
  113. package/src/engine/ink/termio/csi.ts +319 -0
  114. package/src/engine/ink/termio/dec.ts +60 -0
  115. package/src/engine/ink/termio/esc.ts +67 -0
  116. package/src/engine/ink/termio/osc.ts +493 -0
  117. package/src/engine/ink/termio/parser.ts +394 -0
  118. package/src/engine/ink/termio/sgr.ts +308 -0
  119. package/src/engine/ink/termio/tokenize.ts +319 -0
  120. package/src/engine/ink/termio/types.ts +236 -0
  121. package/src/engine/ink/useTerminalNotification.ts +126 -0
  122. package/src/engine/ink/warn.ts +9 -0
  123. package/src/engine/ink/widest-line.ts +19 -0
  124. package/src/engine/ink/wrap-text.ts +74 -0
  125. package/src/engine/ink/wrapAnsi.ts +20 -0
  126. package/src/engine/native-ts/yoga-layout/enums.ts +134 -0
  127. package/src/engine/native-ts/yoga-layout/index.ts +2578 -0
  128. package/src/engine/stubs/bootstrap-state.ts +4 -0
  129. package/src/engine/stubs/debug.ts +6 -0
  130. package/src/engine/stubs/log.ts +4 -0
  131. package/src/engine/utils/debug.ts +5 -0
  132. package/src/engine/utils/earlyInput.ts +4 -0
  133. package/src/engine/utils/env.ts +15 -0
  134. package/src/engine/utils/envUtils.ts +4 -0
  135. package/src/engine/utils/execFileNoThrow.ts +24 -0
  136. package/src/engine/utils/fullscreen.ts +4 -0
  137. package/src/engine/utils/intl.ts +9 -0
  138. package/src/engine/utils/log.ts +3 -0
  139. package/src/engine/utils/semver.ts +13 -0
  140. package/src/engine/utils/sliceAnsi.ts +10 -0
  141. package/src/engine/utils/theme.ts +17 -0
  142. package/src/game/App.tsx +141 -0
  143. package/src/game/agents/behavior.ts +249 -0
  144. package/src/game/agents/speech.ts +57 -0
  145. package/src/game/canvas.ts +98 -0
  146. package/src/game/launch.ts +36 -0
  147. package/src/game/ship/ShipView.tsx +145 -0
  148. package/src/game/ship/ship-map.ts +172 -0
  149. package/src/game/ui/AgentBio.tsx +72 -0
  150. package/src/game/ui/HUD.tsx +63 -0
  151. package/src/game/ui/StatusBar.tsx +49 -0
  152. package/src/game/useKeyboard.ts +62 -0
  153. package/src/main.tsx +22 -0
  154. package/src/run-interactive.ts +74 -0
@@ -0,0 +1,231 @@
1
+ import chalk from 'chalk'
2
+ import cliBoxes, { type Boxes, type BoxStyle } from 'cli-boxes'
3
+ import { applyColor } from './colorize.js'
4
+ import type { DOMNode } from './dom.js'
5
+ import type Output from './output.js'
6
+ import { stringWidth } from './stringWidth.js'
7
+ import type { Color } from './styles.js'
8
+
9
+ export type BorderTextOptions = {
10
+ content: string // Pre-rendered string with ANSI color codes
11
+ position: 'top' | 'bottom'
12
+ align: 'start' | 'end' | 'center'
13
+ offset?: number // Only used with 'start' or 'end' alignment. Number of characters from the edge.
14
+ }
15
+
16
+ export const CUSTOM_BORDER_STYLES = {
17
+ dashed: {
18
+ top: '╌',
19
+ left: '╎',
20
+ right: '╎',
21
+ bottom: '╌',
22
+ // there aren't any line-drawing characters for dashes unfortunately
23
+ topLeft: ' ',
24
+ topRight: ' ',
25
+ bottomLeft: ' ',
26
+ bottomRight: ' ',
27
+ },
28
+ } as const
29
+
30
+ export type BorderStyle =
31
+ | keyof Boxes
32
+ | keyof typeof CUSTOM_BORDER_STYLES
33
+ | BoxStyle
34
+
35
+ function embedTextInBorder(
36
+ borderLine: string,
37
+ text: string,
38
+ align: 'start' | 'end' | 'center',
39
+ offset: number = 0,
40
+ borderChar: string,
41
+ ): [before: string, text: string, after: string] {
42
+ const textLength = stringWidth(text)
43
+ const borderLength = borderLine.length
44
+
45
+ if (textLength >= borderLength - 2) {
46
+ return ['', text.substring(0, borderLength), '']
47
+ }
48
+
49
+ let position: number
50
+ if (align === 'center') {
51
+ position = Math.floor((borderLength - textLength) / 2)
52
+ } else if (align === 'start') {
53
+ position = offset + 1 // +1 to account for corner character
54
+ } else {
55
+ // align === 'end'
56
+ position = borderLength - textLength - offset - 1 // -1 for corner character
57
+ }
58
+
59
+ // Ensure position is valid
60
+ position = Math.max(1, Math.min(position, borderLength - textLength - 1))
61
+
62
+ const before = borderLine.substring(0, 1) + borderChar.repeat(position - 1)
63
+ const after =
64
+ borderChar.repeat(borderLength - position - textLength - 1) +
65
+ borderLine.substring(borderLength - 1)
66
+
67
+ return [before, text, after]
68
+ }
69
+
70
+ function styleBorderLine(
71
+ line: string,
72
+ color: Color | undefined,
73
+ dim: boolean | undefined,
74
+ ): string {
75
+ let styled = applyColor(line, color)
76
+ if (dim) {
77
+ styled = chalk.dim(styled)
78
+ }
79
+ return styled
80
+ }
81
+
82
+ const renderBorder = (
83
+ x: number,
84
+ y: number,
85
+ node: DOMNode,
86
+ output: Output,
87
+ ): void => {
88
+ if (node.style.borderStyle) {
89
+ const width = Math.floor(node.yogaNode!.getComputedWidth())
90
+ const height = Math.floor(node.yogaNode!.getComputedHeight())
91
+ const box =
92
+ typeof node.style.borderStyle === 'string'
93
+ ? (CUSTOM_BORDER_STYLES[
94
+ node.style.borderStyle as keyof typeof CUSTOM_BORDER_STYLES
95
+ ] ?? cliBoxes[node.style.borderStyle as keyof Boxes])
96
+ : node.style.borderStyle
97
+
98
+ const topBorderColor = node.style.borderTopColor ?? node.style.borderColor
99
+ const bottomBorderColor =
100
+ node.style.borderBottomColor ?? node.style.borderColor
101
+ const leftBorderColor = node.style.borderLeftColor ?? node.style.borderColor
102
+ const rightBorderColor =
103
+ node.style.borderRightColor ?? node.style.borderColor
104
+
105
+ const dimTopBorderColor =
106
+ node.style.borderTopDimColor ?? node.style.borderDimColor
107
+
108
+ const dimBottomBorderColor =
109
+ node.style.borderBottomDimColor ?? node.style.borderDimColor
110
+
111
+ const dimLeftBorderColor =
112
+ node.style.borderLeftDimColor ?? node.style.borderDimColor
113
+
114
+ const dimRightBorderColor =
115
+ node.style.borderRightDimColor ?? node.style.borderDimColor
116
+
117
+ const showTopBorder = node.style.borderTop !== false
118
+ const showBottomBorder = node.style.borderBottom !== false
119
+ const showLeftBorder = node.style.borderLeft !== false
120
+ const showRightBorder = node.style.borderRight !== false
121
+
122
+ const contentWidth = Math.max(
123
+ 0,
124
+ width - (showLeftBorder ? 1 : 0) - (showRightBorder ? 1 : 0),
125
+ )
126
+
127
+ const topBorderLine = showTopBorder
128
+ ? (showLeftBorder ? box.topLeft : '') +
129
+ box.top.repeat(contentWidth) +
130
+ (showRightBorder ? box.topRight : '')
131
+ : ''
132
+
133
+ // Handle text in top border
134
+ let topBorder: string | undefined
135
+ if (showTopBorder && node.style.borderText?.position === 'top') {
136
+ const [before, text, after] = embedTextInBorder(
137
+ topBorderLine,
138
+ node.style.borderText.content,
139
+ node.style.borderText.align,
140
+ node.style.borderText.offset,
141
+ box.top,
142
+ )
143
+ topBorder =
144
+ styleBorderLine(before, topBorderColor, dimTopBorderColor) +
145
+ text +
146
+ styleBorderLine(after, topBorderColor, dimTopBorderColor)
147
+ } else if (showTopBorder) {
148
+ topBorder = styleBorderLine(
149
+ topBorderLine,
150
+ topBorderColor,
151
+ dimTopBorderColor,
152
+ )
153
+ }
154
+
155
+ let verticalBorderHeight = height
156
+
157
+ if (showTopBorder) {
158
+ verticalBorderHeight -= 1
159
+ }
160
+
161
+ if (showBottomBorder) {
162
+ verticalBorderHeight -= 1
163
+ }
164
+
165
+ verticalBorderHeight = Math.max(0, verticalBorderHeight)
166
+
167
+ let leftBorder = (applyColor(box.left, leftBorderColor) + '\n').repeat(
168
+ verticalBorderHeight,
169
+ )
170
+
171
+ if (dimLeftBorderColor) {
172
+ leftBorder = chalk.dim(leftBorder)
173
+ }
174
+
175
+ let rightBorder = (applyColor(box.right, rightBorderColor) + '\n').repeat(
176
+ verticalBorderHeight,
177
+ )
178
+
179
+ if (dimRightBorderColor) {
180
+ rightBorder = chalk.dim(rightBorder)
181
+ }
182
+
183
+ const bottomBorderLine = showBottomBorder
184
+ ? (showLeftBorder ? box.bottomLeft : '') +
185
+ box.bottom.repeat(contentWidth) +
186
+ (showRightBorder ? box.bottomRight : '')
187
+ : ''
188
+
189
+ // Handle text in bottom border
190
+ let bottomBorder: string | undefined
191
+ if (showBottomBorder && node.style.borderText?.position === 'bottom') {
192
+ const [before, text, after] = embedTextInBorder(
193
+ bottomBorderLine,
194
+ node.style.borderText.content,
195
+ node.style.borderText.align,
196
+ node.style.borderText.offset,
197
+ box.bottom,
198
+ )
199
+ bottomBorder =
200
+ styleBorderLine(before, bottomBorderColor, dimBottomBorderColor) +
201
+ text +
202
+ styleBorderLine(after, bottomBorderColor, dimBottomBorderColor)
203
+ } else if (showBottomBorder) {
204
+ bottomBorder = styleBorderLine(
205
+ bottomBorderLine,
206
+ bottomBorderColor,
207
+ dimBottomBorderColor,
208
+ )
209
+ }
210
+
211
+ const offsetY = showTopBorder ? 1 : 0
212
+
213
+ if (topBorder) {
214
+ output.write(x, y, topBorder)
215
+ }
216
+
217
+ if (showLeftBorder) {
218
+ output.write(x, y + offsetY, leftBorder)
219
+ }
220
+
221
+ if (showRightBorder) {
222
+ output.write(x + width - 1, y + offsetY, rightBorder)
223
+ }
224
+
225
+ if (bottomBorder) {
226
+ output.write(x, y + height - 1, bottomBorder)
227
+ }
228
+ }
229
+ }
230
+
231
+ export default renderBorder