@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,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAppRuntimeState = createAppRuntimeState;
4
+ exports.appRuntimeReducer = appRuntimeReducer;
5
+ const provider_setup_1 = require("./provider-setup");
6
+ const transcript_1 = require("./transcript");
7
+ function createAppRuntimeState() {
8
+ return {
9
+ transcript: (0, transcript_1.createTranscriptState)(),
10
+ status: "starting",
11
+ statusText: "",
12
+ approval: null,
13
+ provider: null,
14
+ setup: null,
15
+ commandCatalog: [],
16
+ };
17
+ }
18
+ function appRuntimeReducer(state, action) {
19
+ if (action.type === "submit") {
20
+ return {
21
+ ...state,
22
+ transcript: (0, transcript_1.transcriptReducer)(state.transcript, {
23
+ type: "user_submitted",
24
+ text: action.text,
25
+ }),
26
+ status: "thinking",
27
+ statusText: action.command ? "Running command" : "Thinking",
28
+ };
29
+ }
30
+ if (action.type === "setup_action") {
31
+ return state.setup
32
+ ? { ...state, setup: (0, provider_setup_1.providerSetupReducer)(state.setup, action.action) }
33
+ : state;
34
+ }
35
+ if (action.type === "approval_response") {
36
+ return {
37
+ ...state,
38
+ approval: null,
39
+ status: "thinking",
40
+ statusText: action.approved ? "Continuing" : "Cancelling",
41
+ };
42
+ }
43
+ if (action.type === "cancel_requested") {
44
+ return { ...state, status: "cancelling", statusText: action.label };
45
+ }
46
+ if (action.type === "transcript_action") {
47
+ return {
48
+ ...state,
49
+ transcript: (0, transcript_1.transcriptReducer)(state.transcript, action.action),
50
+ };
51
+ }
52
+ if (action.type === "error") {
53
+ return failureState(state, action.message);
54
+ }
55
+ return reduceRuntimeEvent(state, action.channel, action.event);
56
+ }
57
+ function reduceRuntimeEvent(state, channel, event) {
58
+ if (channel === "lifecycle") {
59
+ return reduceLifecycleEvent(state, event);
60
+ }
61
+ if (channel === "provider") {
62
+ return reduceProviderEvent(state, event);
63
+ }
64
+ if (channel === "command") {
65
+ return reduceCommandEvent(state, event);
66
+ }
67
+ return reduceRunEvent(state, event);
68
+ }
69
+ function reduceLifecycleEvent(state, event) {
70
+ if (event.type === "runtime_ready") {
71
+ try {
72
+ return {
73
+ ...state,
74
+ provider: event.provider,
75
+ commandCatalog: event.session_commands || [],
76
+ setup: event.provider.configured
77
+ ? null
78
+ : (0, provider_setup_1.createProviderSetupState)(event.provider_options),
79
+ status: "idle",
80
+ statusText: "",
81
+ };
82
+ }
83
+ catch (error) {
84
+ return failureState(state, errorMessage(error));
85
+ }
86
+ }
87
+ if (event.type === "runtime_unavailable" || event.type === "client_failed") {
88
+ return failureState(state, event.message);
89
+ }
90
+ return state;
91
+ }
92
+ function reduceProviderEvent(state, event) {
93
+ if (event.type === "provider_configured") {
94
+ return {
95
+ ...state,
96
+ provider: event.provider,
97
+ setup: null,
98
+ status: "idle",
99
+ statusText: "",
100
+ };
101
+ }
102
+ if (event.type === "provider_configuration_failed" || event.type === "client_failed") {
103
+ if (!state.setup) {
104
+ return failureState(state, event.message);
105
+ }
106
+ return {
107
+ ...state,
108
+ setup: (0, provider_setup_1.providerSetupReducer)(state.setup, {
109
+ type: "failure",
110
+ message: event.message,
111
+ field: event.type === "provider_configuration_failed" ? event.field : undefined,
112
+ }),
113
+ };
114
+ }
115
+ return state;
116
+ }
117
+ function reduceCommandEvent(state, event) {
118
+ if (event.type === "session_command_completed") {
119
+ return {
120
+ ...state,
121
+ status: "idle",
122
+ statusText: "",
123
+ transcript: (0, transcript_1.transcriptReducer)(state.transcript, {
124
+ type: "command_completed",
125
+ title: event.title,
126
+ text: event.message,
127
+ clear: event.clear_messages,
128
+ }),
129
+ };
130
+ }
131
+ if (event.type === "session_command_failed" || event.type === "client_failed") {
132
+ return failureState(state, event.message);
133
+ }
134
+ return state;
135
+ }
136
+ function reduceRunEvent(state, event) {
137
+ if (event.type === "run_started") {
138
+ return { ...state, status: "thinking", statusText: "Thinking" };
139
+ }
140
+ if (event.type === "run_progress") {
141
+ const transcriptAction = (0, transcript_1.progressTranscriptAction)(event.event);
142
+ return {
143
+ ...state,
144
+ statusText: progressLabel(event.event),
145
+ transcript: transcriptAction
146
+ ? (0, transcript_1.transcriptReducer)(state.transcript, transcriptAction)
147
+ : state.transcript,
148
+ };
149
+ }
150
+ if (event.type === "run_cancel_requested") {
151
+ return { ...state, status: "cancelling", statusText: "Stopping" };
152
+ }
153
+ if (event.type === "run_steer_queued") {
154
+ return {
155
+ ...state,
156
+ status: "thinking",
157
+ statusText: event.replaced === "true" ? "Instruction updated" : "Instruction queued",
158
+ };
159
+ }
160
+ if (event.type === "run_steer_rejected") {
161
+ return {
162
+ ...state,
163
+ statusText: "Instruction was not applied",
164
+ };
165
+ }
166
+ if (event.type === "approval_required") {
167
+ return { ...state, approval: event, status: "approval", statusText: "" };
168
+ }
169
+ if (event.type === "run_completed") {
170
+ const fallback = event.status === "cancelled" ? "Action cancelled." : "Done.";
171
+ return {
172
+ ...state,
173
+ approval: null,
174
+ status: "idle",
175
+ statusText: "",
176
+ transcript: (0, transcript_1.transcriptReducer)(state.transcript, {
177
+ type: "assistant_completed",
178
+ text: event.answer || fallback,
179
+ outcome: event.status === "cancelled" ? "cancelled" : "complete",
180
+ }),
181
+ };
182
+ }
183
+ if (event.type === "run_failed") {
184
+ const message = event.error_code === "approval_execution_interrupted"
185
+ ? "Action outcome is uncertain. kagent did not retry it. Check the target before trying again."
186
+ : event.message;
187
+ return failureState({ ...state, approval: null }, message);
188
+ }
189
+ if (event.type === "client_failed") {
190
+ return failureState({ ...state, approval: null }, event.message);
191
+ }
192
+ return state;
193
+ }
194
+ function failureState(state, message) {
195
+ return {
196
+ ...state,
197
+ approval: null,
198
+ status: "error",
199
+ statusText: "",
200
+ transcript: (0, transcript_1.transcriptReducer)(state.transcript, { type: "error", text: message }),
201
+ };
202
+ }
203
+ function progressLabel(event) {
204
+ const type = String(event.type || "");
205
+ if (type === "steering_applied") {
206
+ return "Updating direction";
207
+ }
208
+ if (type === "planner_started") {
209
+ return "Thinking";
210
+ }
211
+ if (type === "plan_ready") {
212
+ return "Planning next steps";
213
+ }
214
+ if (type === "tool_started") {
215
+ return "Working";
216
+ }
217
+ if (type === "tool_completed") {
218
+ return "Reviewing result";
219
+ }
220
+ return type.endsWith("failed") ? "Retrying" : "Working";
221
+ }
222
+ function errorMessage(error) {
223
+ return error instanceof Error ? error.message : String(error);
224
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveApprovalInput = resolveApprovalInput;
4
+ function resolveApprovalInput(choice, value, keyName = "") {
5
+ const answer = value.toLowerCase();
6
+ if (answer === "d") {
7
+ return { type: "toggle_details" };
8
+ }
9
+ if (answer === "y") {
10
+ return { type: "submit", approved: true };
11
+ }
12
+ if (answer === "n") {
13
+ return { type: "submit", approved: false };
14
+ }
15
+ if (keyName === "left" || keyName === "up") {
16
+ return { type: "select", choice: "allow" };
17
+ }
18
+ if (keyName === "right" || keyName === "down") {
19
+ return { type: "select", choice: "deny" };
20
+ }
21
+ if (keyName === "enter" || keyName === "return") {
22
+ return { type: "submit", approved: choice === "allow" };
23
+ }
24
+ return null;
25
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateCommandMenu = updateCommandMenu;
4
+ exports.moveCommandSelection = moveCommandSelection;
5
+ exports.commandCompletion = commandCompletion;
6
+ function updateCommandMenu(catalog, input, previous) {
7
+ const query = commandQuery(input);
8
+ if (query === null) {
9
+ return null;
10
+ }
11
+ const normalized = query.toLowerCase();
12
+ const options = catalog.filter((option) => commandNames(option).some((name) => name.toLowerCase().startsWith(normalized)));
13
+ if (options.length === 0) {
14
+ return null;
15
+ }
16
+ const selectedCommand = typeof previous === "string" ? previous : previous?.selectedCommand;
17
+ const previousIndex = selectedCommand
18
+ ? options.findIndex((option) => option.command === selectedCommand)
19
+ : -1;
20
+ const selectedIndex = previousIndex >= 0 ? previousIndex : 0;
21
+ return {
22
+ query,
23
+ options,
24
+ selectedIndex,
25
+ selectedCommand: options[selectedIndex].command,
26
+ };
27
+ }
28
+ function moveCommandSelection(state, offset) {
29
+ if (offset === 0 || state.options.length === 0) {
30
+ return state;
31
+ }
32
+ const selectedIndex = wrapIndex(state.selectedIndex + offset, state.options.length);
33
+ return {
34
+ ...state,
35
+ selectedIndex,
36
+ selectedCommand: state.options[selectedIndex].command,
37
+ };
38
+ }
39
+ function commandCompletion(state) {
40
+ const selected = state.options[state.selectedIndex];
41
+ if (!selected) {
42
+ return state.query;
43
+ }
44
+ const commandName = selected.command.split(/\s+/, 1)[0];
45
+ return selected.command.includes(" ") ? `${commandName} ` : commandName;
46
+ }
47
+ function commandQuery(input) {
48
+ const value = input.trimStart();
49
+ if (!value.startsWith("/") || /\s/.test(value)) {
50
+ return null;
51
+ }
52
+ return value;
53
+ }
54
+ function commandNames(option) {
55
+ return [option.command.split(/\s+/, 1)[0], ...option.aliases];
56
+ }
57
+ function wrapIndex(value, length) {
58
+ return ((value % length) + length) % length;
59
+ }
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.splitGraphemes = void 0;
4
+ exports.createEditorState = createEditorState;
5
+ exports.insertInput = insertInput;
6
+ exports.deleteBeforeCursor = deleteBeforeCursor;
7
+ exports.deleteAtCursor = deleteAtCursor;
8
+ exports.moveCursor = moveCursor;
9
+ exports.moveCursorVertical = moveCursorVertical;
10
+ exports.editorVisualLineCount = editorVisualLineCount;
11
+ exports.moveCursorToStart = moveCursorToStart;
12
+ exports.moveCursorToEnd = moveCursorToEnd;
13
+ exports.submitInput = submitInput;
14
+ exports.navigateHistory = navigateHistory;
15
+ const terminal_text_1 = require("./terminal-text");
16
+ var terminal_text_2 = require("./terminal-text");
17
+ Object.defineProperty(exports, "splitGraphemes", { enumerable: true, get: function () { return terminal_text_2.splitGraphemes; } });
18
+ function createEditorState(history = []) {
19
+ return {
20
+ value: "",
21
+ cursor: 0,
22
+ history: history.slice(),
23
+ historyIndex: null,
24
+ draft: "",
25
+ };
26
+ }
27
+ function insertInput(state, rawInput) {
28
+ const characters = (0, terminal_text_1.splitGraphemes)(state.value);
29
+ const cursor = clampCursor(state.cursor, characters.length);
30
+ const before = characters.slice(0, cursor).join("");
31
+ const inserted = (0, terminal_text_1.splitGraphemes)(rawInput).filter(isPrintableGrapheme).join("");
32
+ const after = characters.slice(cursor).join("");
33
+ const prefix = before + inserted;
34
+ return editBuffer(state, prefix + after, (0, terminal_text_1.splitGraphemes)(prefix).length);
35
+ }
36
+ function deleteBeforeCursor(state) {
37
+ const characters = (0, terminal_text_1.splitGraphemes)(state.value);
38
+ const cursor = clampCursor(state.cursor, characters.length);
39
+ if (cursor === 0) {
40
+ return state;
41
+ }
42
+ characters.splice(cursor - 1, 1);
43
+ return editBuffer(state, characters.join(""), cursor - 1);
44
+ }
45
+ function deleteAtCursor(state) {
46
+ const characters = (0, terminal_text_1.splitGraphemes)(state.value);
47
+ const cursor = clampCursor(state.cursor, characters.length);
48
+ if (cursor === characters.length) {
49
+ return state;
50
+ }
51
+ characters.splice(cursor, 1);
52
+ return editBuffer(state, characters.join(""), cursor);
53
+ }
54
+ function moveCursor(state, offset) {
55
+ const length = (0, terminal_text_1.splitGraphemes)(state.value).length;
56
+ return {
57
+ ...state,
58
+ cursor: clampCursor(state.cursor + offset, length),
59
+ };
60
+ }
61
+ function moveCursorVertical(state, direction, columns = Number.MAX_SAFE_INTEGER) {
62
+ const characters = (0, terminal_text_1.splitGraphemes)(state.value);
63
+ const cursor = clampCursor(state.cursor, characters.length);
64
+ const positions = visualCursorPositions(characters, columns);
65
+ const current = positions[cursor];
66
+ const targetRow = current.row + direction;
67
+ if (targetRow < 0 || targetRow >= positions.at(-1).row + 1) {
68
+ return state;
69
+ }
70
+ let targetCursor = cursor;
71
+ let targetDistance = Number.MAX_SAFE_INTEGER;
72
+ positions.forEach((position, index) => {
73
+ if (position.row !== targetRow) {
74
+ return;
75
+ }
76
+ const distance = Math.abs(position.column - current.column);
77
+ if (distance < targetDistance) {
78
+ targetCursor = index;
79
+ targetDistance = distance;
80
+ }
81
+ });
82
+ return {
83
+ ...state,
84
+ cursor: targetCursor,
85
+ };
86
+ }
87
+ function editorVisualLineCount(value, columns) {
88
+ const positions = visualCursorPositions((0, terminal_text_1.splitGraphemes)(value), columns);
89
+ const finalPosition = positions.at(-1);
90
+ return finalPosition.row + 1;
91
+ }
92
+ function moveCursorToStart(state) {
93
+ return { ...state, cursor: 0 };
94
+ }
95
+ function moveCursorToEnd(state) {
96
+ return { ...state, cursor: (0, terminal_text_1.splitGraphemes)(state.value).length };
97
+ }
98
+ function submitInput(state) {
99
+ const value = state.value.trim();
100
+ if (!value) {
101
+ return { value: null, state };
102
+ }
103
+ return {
104
+ value,
105
+ state: createEditorState(state.history.concat(value)),
106
+ };
107
+ }
108
+ function navigateHistory(state, offset) {
109
+ if (state.history.length === 0 || offset === 0) {
110
+ return state;
111
+ }
112
+ if (offset < 0) {
113
+ const historyIndex = state.historyIndex === null
114
+ ? state.history.length - 1
115
+ : Math.max(state.historyIndex - 1, 0);
116
+ return historyState(state, historyIndex, state.historyIndex === null ? state.value : state.draft);
117
+ }
118
+ if (state.historyIndex === null) {
119
+ return state;
120
+ }
121
+ if (state.historyIndex < state.history.length - 1) {
122
+ return historyState(state, state.historyIndex + 1, state.draft);
123
+ }
124
+ return {
125
+ ...state,
126
+ value: state.draft,
127
+ cursor: (0, terminal_text_1.splitGraphemes)(state.draft).length,
128
+ historyIndex: null,
129
+ draft: "",
130
+ };
131
+ }
132
+ function historyState(state, historyIndex, draft) {
133
+ const value = state.history[historyIndex];
134
+ return {
135
+ ...state,
136
+ value,
137
+ cursor: (0, terminal_text_1.splitGraphemes)(value).length,
138
+ historyIndex,
139
+ draft,
140
+ };
141
+ }
142
+ function editBuffer(state, value, cursor) {
143
+ return {
144
+ ...state,
145
+ value,
146
+ cursor,
147
+ ...(isEditorState(state) ? { historyIndex: null, draft: "" } : {}),
148
+ };
149
+ }
150
+ function isEditorState(state) {
151
+ return "history" in state;
152
+ }
153
+ function clampCursor(cursor, length) {
154
+ return Math.min(Math.max(cursor, 0), length);
155
+ }
156
+ function visualCursorPositions(characters, columns) {
157
+ const safeColumns = Math.max(1, Math.trunc(columns));
158
+ const positions = [{ row: 0, column: 0 }];
159
+ let row = 0;
160
+ let column = 0;
161
+ characters.forEach((character) => {
162
+ if (character === "\n") {
163
+ row += 1;
164
+ column = 0;
165
+ }
166
+ else {
167
+ const width = (0, terminal_text_1.terminalGraphemeWidth)(character);
168
+ if (column > 0 && column + width > safeColumns) {
169
+ row += 1;
170
+ column = 0;
171
+ }
172
+ column += width;
173
+ if (column >= safeColumns) {
174
+ row += 1;
175
+ column = 0;
176
+ }
177
+ }
178
+ positions.push({ row, column });
179
+ });
180
+ return positions;
181
+ }
182
+ function isPrintableGrapheme(character) {
183
+ if (character === "\n") {
184
+ return true;
185
+ }
186
+ const codePoint = character.codePointAt(0) || 0;
187
+ return codePoint >= 32 && codePoint !== 127;
188
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldRunInkTui = shouldRunInkTui;
4
+ exports.runKagentInk = runKagentInk;
5
+ const App_1 = require("./App");
6
+ const dynamicImport = new Function("specifier", "return import(specifier)");
7
+ function shouldRunInkTui(args, stdin) {
8
+ if (process.env.KAGENT_CLASSIC_UI) {
9
+ return false;
10
+ }
11
+ if (args.includes("--classic")) {
12
+ return false;
13
+ }
14
+ if (args.length > 0) {
15
+ return false;
16
+ }
17
+ return Boolean(stdin && stdin.isTTY);
18
+ }
19
+ async function runKagentInk(_args, options = {}) {
20
+ try {
21
+ const React = (await dynamicImport("react"));
22
+ const Ink = (await dynamicImport("ink"));
23
+ const element = React.createElement(App_1.KagentInkApp, { React, Ink: Ink });
24
+ Ink.render(element, { exitOnCtrlC: false });
25
+ }
26
+ catch (error) {
27
+ if (typeof options.fallback === "function") {
28
+ process.stderr.write(`kagent: terminal UI unavailable: ${errorMessage(error)}; using classic CLI\n`);
29
+ options.fallback();
30
+ return;
31
+ }
32
+ throw error;
33
+ }
34
+ }
35
+ function errorMessage(error) {
36
+ return error instanceof Error ? error.message : String(error);
37
+ }
38
+ module.exports = {
39
+ runKagentInk,
40
+ shouldRunInkTui,
41
+ };
@@ -0,0 +1,39 @@
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.resolveKagentHome = resolveKagentHome;
7
+ exports.kagentStatePath = kagentStatePath;
8
+ exports.kagentCachePath = kagentCachePath;
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ function requiredHome(env) {
12
+ const home = env.HOME?.trim();
13
+ return home || node_os_1.default.homedir();
14
+ }
15
+ function resolveKagentHome(env = process.env) {
16
+ const configured = env.KAGENT_HOME;
17
+ if (Object.prototype.hasOwnProperty.call(env, "KAGENT_HOME")) {
18
+ if (!configured?.trim()) {
19
+ throw new Error("KAGENT_HOME must not be empty");
20
+ }
21
+ if (configured === "~") {
22
+ return node_path_1.default.resolve(requiredHome(env));
23
+ }
24
+ if (configured.startsWith("~/")) {
25
+ return node_path_1.default.resolve(requiredHome(env), configured.slice(2));
26
+ }
27
+ if (!node_path_1.default.isAbsolute(configured)) {
28
+ throw new Error("KAGENT_HOME must be an absolute or tilde-prefixed path");
29
+ }
30
+ return node_path_1.default.resolve(configured);
31
+ }
32
+ return node_path_1.default.resolve(requiredHome(env), ".kagent");
33
+ }
34
+ function kagentStatePath(name, env = process.env) {
35
+ return node_path_1.default.join(resolveKagentHome(env), "state", name);
36
+ }
37
+ function kagentCachePath(name, env = process.env) {
38
+ return node_path_1.default.join(resolveKagentHome(env), "cache", name);
39
+ }