@openlucaskaka/kagent 0.1.7

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 (117) hide show
  1. package/README.md +353 -0
  2. package/npm/bin/kagent-serve.js +6 -0
  3. package/npm/bin/kagent.js +6 -0
  4. package/npm/lib/App.js +524 -0
  5. package/npm/lib/app-state.js +224 -0
  6. package/npm/lib/approval-choice.js +25 -0
  7. package/npm/lib/commands.js +59 -0
  8. package/npm/lib/editor.js +188 -0
  9. package/npm/lib/ink-runner.js +41 -0
  10. package/npm/lib/kagent-home.js +39 -0
  11. package/npm/lib/launcher.js +221 -0
  12. package/npm/lib/protocol.js +33 -0
  13. package/npm/lib/provider-setup.js +139 -0
  14. package/npm/lib/python-runner.js +892 -0
  15. package/npm/lib/runtime-client.js +390 -0
  16. package/npm/lib/terminal-input.js +127 -0
  17. package/npm/lib/terminal-text.js +19 -0
  18. package/npm/lib/terminal-width.js +14 -0
  19. package/npm/lib/transcript.js +227 -0
  20. package/npm/lib/ui-components.js +247 -0
  21. package/npm/lib/update-manager.js +334 -0
  22. package/package.json +39 -0
  23. package/pyproject.toml +55 -0
  24. package/src/kagent/__init__.py +90 -0
  25. package/src/kagent/cli/__init__.py +5 -0
  26. package/src/kagent/cli/__main__.py +6 -0
  27. package/src/kagent/cli/commands.py +112 -0
  28. package/src/kagent/cli/conversation.py +127 -0
  29. package/src/kagent/cli/interactive.py +841 -0
  30. package/src/kagent/cli/main.py +685 -0
  31. package/src/kagent/cli/memory.py +460 -0
  32. package/src/kagent/cli/pending_approval.py +169 -0
  33. package/src/kagent/cli/provider.py +27 -0
  34. package/src/kagent/cli/session_commands.py +401 -0
  35. package/src/kagent/cli/stdio_runtime.py +784 -0
  36. package/src/kagent/cli/trace.py +67 -0
  37. package/src/kagent/cli/ui.py +931 -0
  38. package/src/kagent/core/__init__.py +0 -0
  39. package/src/kagent/core/agent.py +296 -0
  40. package/src/kagent/core/faults.py +11 -0
  41. package/src/kagent/core/invariants.py +47 -0
  42. package/src/kagent/core/normalization.py +81 -0
  43. package/src/kagent/core/planning.py +48 -0
  44. package/src/kagent/core/state.py +73 -0
  45. package/src/kagent/core/summary.py +64 -0
  46. package/src/kagent/core/tools.py +196 -0
  47. package/src/kagent/core/trace.py +57 -0
  48. package/src/kagent/eval/__init__.py +11 -0
  49. package/src/kagent/eval/cases.py +229 -0
  50. package/src/kagent/eval/evaluator.py +216 -0
  51. package/src/kagent/integrations/__init__.py +3 -0
  52. package/src/kagent/integrations/audit.py +95 -0
  53. package/src/kagent/integrations/backends.py +131 -0
  54. package/src/kagent/integrations/memory.py +301 -0
  55. package/src/kagent/ops/__init__.py +0 -0
  56. package/src/kagent/ops/batch.py +156 -0
  57. package/src/kagent/ops/doctor.py +255 -0
  58. package/src/kagent/ops/metrics.py +214 -0
  59. package/src/kagent/ops/release_evidence.py +877 -0
  60. package/src/kagent/ops/release_manifest.py +142 -0
  61. package/src/kagent/ops/trace_replay.py +285 -0
  62. package/src/kagent/providers/__init__.py +7 -0
  63. package/src/kagent/providers/embeddings.py +187 -0
  64. package/src/kagent/providers/llm.py +770 -0
  65. package/src/kagent/py.typed +1 -0
  66. package/src/kagent/runtime/__init__.py +28 -0
  67. package/src/kagent/runtime/action_graph.py +543 -0
  68. package/src/kagent/runtime/agent.py +2089 -0
  69. package/src/kagent/runtime/approval.py +64 -0
  70. package/src/kagent/runtime/cancellation.py +64 -0
  71. package/src/kagent/runtime/checkpoint_state.py +146 -0
  72. package/src/kagent/runtime/checkpoint_storage.py +270 -0
  73. package/src/kagent/runtime/context.py +65 -0
  74. package/src/kagent/runtime/file_transaction.py +195 -0
  75. package/src/kagent/runtime/hooks.py +74 -0
  76. package/src/kagent/runtime/metadata.py +116 -0
  77. package/src/kagent/runtime/patch_checkpoints.py +385 -0
  78. package/src/kagent/runtime/policy.py +50 -0
  79. package/src/kagent/runtime/presentation.py +205 -0
  80. package/src/kagent/runtime/redaction.py +130 -0
  81. package/src/kagent/runtime/sandbox.py +331 -0
  82. package/src/kagent/runtime/skills.py +66 -0
  83. package/src/kagent/runtime/steering.py +56 -0
  84. package/src/kagent/runtime/steps.py +255 -0
  85. package/src/kagent/runtime/task_state.py +40 -0
  86. package/src/kagent/runtime/tools.py +3532 -0
  87. package/src/kagent/runtime/types.py +240 -0
  88. package/src/kagent/runtime/workspace.py +597 -0
  89. package/src/kagent/service/__init__.py +26 -0
  90. package/src/kagent/service/__main__.py +6 -0
  91. package/src/kagent/service/active_runs.py +178 -0
  92. package/src/kagent/service/cli.py +737 -0
  93. package/src/kagent/service/contract.py +2571 -0
  94. package/src/kagent/service/errors.py +71 -0
  95. package/src/kagent/service/idempotency.py +584 -0
  96. package/src/kagent/service/router.py +884 -0
  97. package/src/kagent/service/run.py +150 -0
  98. package/src/kagent/service/runtime.py +1915 -0
  99. package/src/kagent/service/runtime_approval.py +20 -0
  100. package/src/kagent/service/runtime_cancel.py +192 -0
  101. package/src/kagent/service/runtime_lifecycle.py +229 -0
  102. package/src/kagent/service/runtime_metadata.py +21 -0
  103. package/src/kagent/service/runtime_policy.py +115 -0
  104. package/src/kagent/service/runtime_recovery.py +573 -0
  105. package/src/kagent/service/runtime_resume.py +382 -0
  106. package/src/kagent/service/runtime_resume_claim.py +116 -0
  107. package/src/kagent/service/runtime_run.py +350 -0
  108. package/src/kagent/service/runtime_status.py +2007 -0
  109. package/src/kagent/service/safety.py +139 -0
  110. package/src/kagent/service/server.py +114 -0
  111. package/src/kagent/service/status.py +233 -0
  112. package/src/kagent/service/trace_store.py +322 -0
  113. package/src/kagent/service/transport.py +24 -0
  114. package/src/kagent/utils/__init__.py +0 -0
  115. package/src/kagent/utils/config_validation.py +21 -0
  116. package/src/kagent/utils/json_output.py +23 -0
  117. package/src/kagent/utils/paths.py +473 -0
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createRuntimeSessionClient = createRuntimeSessionClient;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const node_readline_1 = __importDefault(require("node:readline"));
10
+ const kagent_home_1 = require("./kagent-home");
11
+ const protocol_1 = require("./protocol");
12
+ const pythonRunner = require("./python-runner");
13
+ const APPROVAL_EXECUTION_INTERRUPTED_MESSAGE = "The approved action was interrupted and was not replayed because its side-effect state is uncertain.";
14
+ function createRuntimeSessionClient() {
15
+ const sessionId = (0, node_crypto_1.randomUUID)();
16
+ const configuredPendingApprovalPath = process.env.KAGENT_PENDING_APPROVAL_PATH;
17
+ const pendingApprovalPath = configuredPendingApprovalPath || (() => {
18
+ const pendingApprovalDirectory = (0, kagent_home_1.kagentStatePath)("pending-approvals");
19
+ return node_path_1.default.join(pendingApprovalDirectory, `${sessionId}.json`);
20
+ })();
21
+ let child = null;
22
+ let stdout = null;
23
+ let currentHandler = null;
24
+ let busy = false;
25
+ let closed = false;
26
+ let generation = 0;
27
+ let ready = false;
28
+ let restartUsed = false;
29
+ let queuedRequest = null;
30
+ let startupFailure = "";
31
+ let approvalExecutionUncertain = false;
32
+ let recoveringActive = false;
33
+ let recoveryFailureMessage = "";
34
+ let lifecycleEvent = null;
35
+ const subscribers = new Set();
36
+ function spawn() {
37
+ generation += 1;
38
+ const childGeneration = generation;
39
+ ready = false;
40
+ let nextChild;
41
+ try {
42
+ nextChild = pythonRunner.spawnPythonModule("kagent.cli.stdio_runtime", [], {
43
+ cwd: process.cwd(),
44
+ env: {
45
+ ...process.env,
46
+ KAGENT_PENDING_APPROVAL_PATH: pendingApprovalPath,
47
+ },
48
+ });
49
+ }
50
+ catch (error) {
51
+ recoverFromChildFailure(childGeneration, errorMessage(error));
52
+ return;
53
+ }
54
+ const nextStdout = node_readline_1.default.createInterface({ input: nextChild.stdout });
55
+ child = nextChild;
56
+ stdout = nextStdout;
57
+ nextStdout.on("line", (line) => {
58
+ if (childGeneration !== generation) {
59
+ return;
60
+ }
61
+ try {
62
+ const event = (0, protocol_1.parseRuntimeProtocolLine)(line);
63
+ if (!event) {
64
+ return;
65
+ }
66
+ if (event.type === "runtime_ready") {
67
+ ready = true;
68
+ startupFailure = "";
69
+ lifecycleEvent = event;
70
+ notify(event);
71
+ if (recoveringActive) {
72
+ if (event.pending_approval) {
73
+ approvalExecutionUncertain = false;
74
+ recoveringActive = false;
75
+ recoveryFailureMessage = "";
76
+ }
77
+ else if (event.approval_execution_interrupted) {
78
+ approvalExecutionUncertain = true;
79
+ recoveringActive = false;
80
+ recoveryFailureMessage = "";
81
+ queuedRequest = null;
82
+ }
83
+ else {
84
+ const failureMessage = recoveryFailureMessage;
85
+ recoveringActive = false;
86
+ recoveryFailureMessage = "";
87
+ failCurrent(failureMessage);
88
+ }
89
+ }
90
+ if (queuedRequest) {
91
+ const request = queuedRequest;
92
+ queuedRequest = null;
93
+ writeNow(request);
94
+ }
95
+ return;
96
+ }
97
+ if (event.type === "runtime_unavailable") {
98
+ ready = false;
99
+ startupFailure = event.message;
100
+ notify(event);
101
+ failCurrent(event.message);
102
+ return;
103
+ }
104
+ if (!currentHandler) {
105
+ return;
106
+ }
107
+ if (event.type === "approval_required") {
108
+ approvalExecutionUncertain = false;
109
+ }
110
+ currentHandler(event);
111
+ if (event.type === "provider_configured") {
112
+ updateProviderLifecycle(event);
113
+ }
114
+ if (event.type === "run_completed" ||
115
+ event.type === "run_failed" ||
116
+ event.type === "provider_configured" ||
117
+ event.type === "provider_configuration_failed" ||
118
+ event.type === "session_command_completed" ||
119
+ event.type === "session_command_failed") {
120
+ approvalExecutionUncertain = false;
121
+ recoveringActive = false;
122
+ recoveryFailureMessage = "";
123
+ busy = false;
124
+ currentHandler = null;
125
+ }
126
+ }
127
+ catch (error) {
128
+ failCurrent(errorMessage(error));
129
+ }
130
+ });
131
+ nextChild.stderr.on("data", () => {
132
+ // Drain the child pipe, but never forward stderr into user-visible events.
133
+ });
134
+ nextChild.on("error", (error) => {
135
+ recoverFromChildFailure(childGeneration, error.message);
136
+ });
137
+ nextChild.on("close", (code) => {
138
+ recoverFromChildFailure(childGeneration, `runtime exited with code ${code ?? 1}`);
139
+ });
140
+ }
141
+ function recoverFromChildFailure(childGeneration, message) {
142
+ if (childGeneration !== generation || closed) {
143
+ return;
144
+ }
145
+ generation += 1;
146
+ ready = false;
147
+ lifecycleEvent = null;
148
+ stdout?.close();
149
+ child = null;
150
+ stdout = null;
151
+ const activeRequest = busy && currentHandler !== null;
152
+ if (restartUsed) {
153
+ const preserveUncertainTombstone = approvalExecutionUncertain;
154
+ if (activeRequest) {
155
+ if (preserveUncertainTombstone) {
156
+ failCurrentWithEvent({
157
+ type: "run_failed",
158
+ error_code: "approval_execution_interrupted",
159
+ message: APPROVAL_EXECUTION_INTERRUPTED_MESSAGE,
160
+ });
161
+ }
162
+ else {
163
+ failCurrent(message);
164
+ }
165
+ }
166
+ startupFailure = message;
167
+ notify({ type: "client_failed", message });
168
+ return;
169
+ }
170
+ if (activeRequest) {
171
+ recoveringActive = true;
172
+ recoveryFailureMessage = message;
173
+ }
174
+ else if (busy) {
175
+ failCurrent(message);
176
+ }
177
+ restartUsed = true;
178
+ startupFailure = "";
179
+ setImmediate(() => {
180
+ if (!closed) {
181
+ spawn();
182
+ }
183
+ });
184
+ }
185
+ function writeNow(request) {
186
+ if (!child ||
187
+ child.killed ||
188
+ child.exitCode !== null ||
189
+ child.signalCode !== null ||
190
+ !child.stdin.writable) {
191
+ throw new Error("runtime session is not available");
192
+ }
193
+ child.stdin.write(`${JSON.stringify(request)}\n`);
194
+ }
195
+ function send(request) {
196
+ if (startupFailure) {
197
+ throw new Error(startupFailure);
198
+ }
199
+ if (!ready) {
200
+ queuedRequest = request;
201
+ return;
202
+ }
203
+ writeNow(request);
204
+ }
205
+ function notify(event) {
206
+ for (const subscriber of subscribers) {
207
+ subscriber(event);
208
+ }
209
+ }
210
+ function updateProviderLifecycle(event) {
211
+ if (!lifecycleEvent) {
212
+ return;
213
+ }
214
+ lifecycleEvent = { ...lifecycleEvent, provider: event.provider };
215
+ notify(lifecycleEvent);
216
+ }
217
+ function failCurrent(message) {
218
+ failCurrentWithEvent({ type: "client_failed", message });
219
+ }
220
+ function failCurrentWithEvent(event) {
221
+ const handler = currentHandler;
222
+ const preserveUncertainTombstone = event.type === "run_failed" &&
223
+ event.error_code === "approval_execution_interrupted";
224
+ busy = false;
225
+ currentHandler = null;
226
+ queuedRequest = null;
227
+ approvalExecutionUncertain = preserveUncertainTombstone;
228
+ recoveringActive = false;
229
+ recoveryFailureMessage = "";
230
+ handler?.(event);
231
+ }
232
+ spawn();
233
+ return {
234
+ subscribe(handler) {
235
+ subscribers.add(handler);
236
+ if (lifecycleEvent) {
237
+ handler(lifecycleEvent);
238
+ }
239
+ else if (startupFailure) {
240
+ handler({ type: "client_failed", message: startupFailure });
241
+ }
242
+ return () => subscribers.delete(handler);
243
+ },
244
+ configureProvider(config, onEvent) {
245
+ if (closed) {
246
+ onEvent({ type: "client_failed", message: "runtime session is closed" });
247
+ return;
248
+ }
249
+ if (busy) {
250
+ onEvent({ type: "client_failed", message: "runtime session is busy" });
251
+ return;
252
+ }
253
+ busy = true;
254
+ currentHandler = onEvent;
255
+ const request = {
256
+ type: "provider_configure",
257
+ provider: config.provider,
258
+ base_url: config.baseUrl,
259
+ model: config.model,
260
+ api_key: config.apiKey,
261
+ };
262
+ try {
263
+ send(request);
264
+ }
265
+ catch (error) {
266
+ failCurrent(errorMessage(error));
267
+ }
268
+ },
269
+ run(goal, onEvent, options = {}) {
270
+ if (closed) {
271
+ onEvent({ type: "client_failed", message: "runtime session is closed" });
272
+ return;
273
+ }
274
+ if (busy) {
275
+ onEvent({ type: "client_failed", message: "runtime session is busy" });
276
+ return;
277
+ }
278
+ busy = true;
279
+ currentHandler = onEvent;
280
+ const request = {
281
+ type: "run_request",
282
+ goal,
283
+ max_iterations: options.maxIterations ?? 3,
284
+ };
285
+ if (options.runtimePlan) {
286
+ request.runtime_plan = options.runtimePlan;
287
+ }
288
+ try {
289
+ send(request);
290
+ }
291
+ catch (error) {
292
+ failCurrent(errorMessage(error));
293
+ }
294
+ },
295
+ command(command, onEvent) {
296
+ if (closed) {
297
+ onEvent({ type: "client_failed", message: "runtime session is closed" });
298
+ return;
299
+ }
300
+ if (busy) {
301
+ onEvent({ type: "client_failed", message: "runtime session is busy" });
302
+ return;
303
+ }
304
+ busy = true;
305
+ currentHandler = onEvent;
306
+ const request = {
307
+ type: "session_command",
308
+ command,
309
+ };
310
+ try {
311
+ send(request);
312
+ }
313
+ catch (error) {
314
+ failCurrent(errorMessage(error));
315
+ }
316
+ },
317
+ respondToApproval(actionId, approved) {
318
+ if (!busy || !currentHandler) {
319
+ throw new Error("there is no pending runtime request");
320
+ }
321
+ const request = {
322
+ type: "approval_response",
323
+ action_id: actionId,
324
+ approved,
325
+ };
326
+ approvalExecutionUncertain = approved;
327
+ try {
328
+ send(request);
329
+ }
330
+ catch (error) {
331
+ queuedRequest = request;
332
+ child?.kill();
333
+ recoverFromChildFailure(generation, errorMessage(error));
334
+ }
335
+ },
336
+ steer(instruction) {
337
+ if (!busy || !currentHandler) {
338
+ throw new Error("there is no active runtime request to steer");
339
+ }
340
+ const request = {
341
+ type: "steer_request",
342
+ instruction,
343
+ };
344
+ try {
345
+ send(request);
346
+ }
347
+ catch (error) {
348
+ failCurrent(errorMessage(error));
349
+ }
350
+ },
351
+ cancel() {
352
+ if (!busy) {
353
+ return;
354
+ }
355
+ const request = {
356
+ type: "cancel_request",
357
+ reason: "user requested cancellation",
358
+ };
359
+ try {
360
+ send(request);
361
+ }
362
+ catch (error) {
363
+ failCurrent(errorMessage(error));
364
+ }
365
+ },
366
+ close() {
367
+ if (closed) {
368
+ return;
369
+ }
370
+ closed = true;
371
+ busy = false;
372
+ currentHandler = null;
373
+ queuedRequest = null;
374
+ approvalExecutionUncertain = false;
375
+ recoveringActive = false;
376
+ recoveryFailureMessage = "";
377
+ subscribers.clear();
378
+ generation += 1;
379
+ stdout?.close();
380
+ if (child && !child.killed) {
381
+ child.kill("SIGTERM");
382
+ }
383
+ child = null;
384
+ stdout = null;
385
+ },
386
+ };
387
+ }
388
+ function errorMessage(error) {
389
+ return error instanceof Error ? error.message : String(error);
390
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTerminalInputBridge = createTerminalInputBridge;
4
+ const node_readline_1 = require("node:readline");
5
+ const node_stream_1 = require("node:stream");
6
+ const node_string_decoder_1 = require("node:string_decoder");
7
+ const BRACKETED_PASTE_START = "\x1b[200~";
8
+ const BRACKETED_PASTE_END = "\x1b[201~";
9
+ function createTerminalInputBridge(handler) {
10
+ const input = new node_stream_1.PassThrough();
11
+ const decoder = new node_string_decoder_1.StringDecoder("utf8");
12
+ let pendingInput = "";
13
+ let pastedInput = null;
14
+ input.setEncoding("utf8");
15
+ (0, node_readline_1.emitKeypressEvents)(input);
16
+ const handleKeypress = (character, key) => {
17
+ const terminalKey = normalizeTerminalKey(key);
18
+ const value = terminalKey.ctrl ? terminalKey.name || "" : printableInput(character);
19
+ handler(value, terminalKey);
20
+ };
21
+ input.on("keypress", handleKeypress);
22
+ const emitPaste = (value, sequence) => {
23
+ const normalized = normalizePastedInput(value);
24
+ if (!normalized) {
25
+ return;
26
+ }
27
+ handler(normalized, {
28
+ sequence,
29
+ ctrl: false,
30
+ meta: false,
31
+ shift: false,
32
+ });
33
+ };
34
+ const writeParsedInput = (value) => {
35
+ if (value.length > 1 && !value.includes("\x1b") && /[\r\n]/.test(value)) {
36
+ emitPaste(value, value);
37
+ return;
38
+ }
39
+ input.write(value);
40
+ };
41
+ const consume = (value) => {
42
+ let remaining = pendingInput + value;
43
+ pendingInput = "";
44
+ while (remaining) {
45
+ if (pastedInput !== null) {
46
+ const combined = pastedInput + remaining;
47
+ const endIndex = combined.indexOf(BRACKETED_PASTE_END);
48
+ if (endIndex === -1) {
49
+ pastedInput = combined;
50
+ return;
51
+ }
52
+ const completedPaste = combined.slice(0, endIndex);
53
+ emitPaste(completedPaste, BRACKETED_PASTE_START + completedPaste + BRACKETED_PASTE_END);
54
+ pastedInput = null;
55
+ remaining = combined.slice(endIndex + BRACKETED_PASTE_END.length);
56
+ continue;
57
+ }
58
+ const startIndex = remaining.indexOf(BRACKETED_PASTE_START);
59
+ if (startIndex !== -1) {
60
+ writeParsedInput(remaining.slice(0, startIndex));
61
+ pastedInput = "";
62
+ remaining = remaining.slice(startIndex + BRACKETED_PASTE_START.length);
63
+ continue;
64
+ }
65
+ const suffixLength = pasteStartSuffixLength(remaining);
66
+ const parsedEnd = suffixLength > 1 ? remaining.length - suffixLength : remaining.length;
67
+ writeParsedInput(remaining.slice(0, parsedEnd));
68
+ pendingInput = remaining.slice(parsedEnd);
69
+ return;
70
+ }
71
+ };
72
+ return {
73
+ write(chunk) {
74
+ consume(typeof chunk === "string" ? chunk : decoder.write(chunk));
75
+ },
76
+ close() {
77
+ consume(decoder.end());
78
+ writeParsedInput(pendingInput);
79
+ pendingInput = "";
80
+ input.removeListener("keypress", handleKeypress);
81
+ input.end();
82
+ },
83
+ };
84
+ }
85
+ function printableInput(character) {
86
+ if (!character) {
87
+ return "";
88
+ }
89
+ const codePoint = character.codePointAt(0) || 0;
90
+ return codePoint < 32 || codePoint === 127 ? "" : character;
91
+ }
92
+ function normalizePastedInput(value) {
93
+ return value
94
+ .replace(/\r\n|\r/g, "\n")
95
+ .replace(/\t/g, " ")
96
+ .replace(/[\u0000-\u0009\u000b-\u001f\u007f]/g, "");
97
+ }
98
+ function normalizeTerminalKey(key) {
99
+ const sequence = key.sequence || "";
100
+ const modifiedReturn = /^\x1b\[13;(\d+)u$/.exec(sequence);
101
+ if (modifiedReturn) {
102
+ const modifiers = Number(modifiedReturn[1]) - 1;
103
+ return {
104
+ sequence,
105
+ name: "return",
106
+ shift: Boolean(modifiers & 1),
107
+ meta: Boolean(modifiers & 2),
108
+ ctrl: Boolean(modifiers & 4),
109
+ };
110
+ }
111
+ return {
112
+ sequence,
113
+ name: key.name,
114
+ ctrl: Boolean(key.ctrl),
115
+ meta: Boolean(key.meta),
116
+ shift: Boolean(key.shift),
117
+ };
118
+ }
119
+ function pasteStartSuffixLength(value) {
120
+ const maxLength = Math.min(value.length, BRACKETED_PASTE_START.length - 1);
121
+ for (let length = maxLength; length > 1; length -= 1) {
122
+ if (value.endsWith(BRACKETED_PASTE_START.slice(0, length))) {
123
+ return length;
124
+ }
125
+ }
126
+ return 0;
127
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.splitGraphemes = splitGraphemes;
7
+ exports.terminalGraphemeWidth = terminalGraphemeWidth;
8
+ exports.terminalSafeText = terminalSafeText;
9
+ const string_width_1 = __importDefault(require("string-width"));
10
+ const GRAPHEME_SEGMENTER = new Intl.Segmenter(undefined, { granularity: "grapheme" });
11
+ function splitGraphemes(value) {
12
+ return Array.from(GRAPHEME_SEGMENTER.segment(value), ({ segment }) => segment);
13
+ }
14
+ function terminalGraphemeWidth(grapheme) {
15
+ return (0, string_width_1.default)(grapheme);
16
+ }
17
+ function terminalSafeText(value) {
18
+ return value.replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
19
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.terminalGraphemeWidth = void 0;
4
+ exports.estimateTextRows = estimateTextRows;
5
+ const terminal_text_1 = require("./terminal-text");
6
+ function estimateTextRows(text, columns) {
7
+ const safeColumns = Math.max(1, columns);
8
+ return text.split("\n").reduce((total, line) => {
9
+ const width = (0, terminal_text_1.splitGraphemes)(line).reduce((lineWidth, grapheme) => lineWidth + (0, terminal_text_1.terminalGraphemeWidth)(grapheme), 0);
10
+ return total + Math.max(1, Math.ceil(width / safeColumns));
11
+ }, 0);
12
+ }
13
+ var terminal_text_2 = require("./terminal-text");
14
+ Object.defineProperty(exports, "terminalGraphemeWidth", { enumerable: true, get: function () { return terminal_text_2.terminalGraphemeWidth; } });