maka-agent 0.2.0-dev.24.20260907 → 0.2.0-dev.26.20260909
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.
- package/README.md +38 -19
- package/README.zh-CN.md +34 -19
- package/dist/mcp-capability-provider.js +4 -1
- package/dist/pi-transcript-tools.js +6 -0
- package/dist/pi-tui-layout.js +56 -10
- package/dist/pi-tui-mcp-status.js +2 -2
- package/dist/pi-tui-pickers.js +121 -30
- package/dist/pi-tui-runner.js +156 -42
- package/dist/pi-tui-todo.js +221 -0
- package/dist/pi-tui-transcript-viewer.js +134 -7
- package/dist/runtime-host-cli-context.js +70 -13
- package/dist/runtime-host-handoff-surface.js +51 -26
- package/dist/runtime-host-local-handoff.js +11 -1
- package/dist/runtime-host-service-manager.js +0 -3
- package/dist/runtime-host-session-channel.js +13 -0
- package/dist/runtime-host-session-driver.js +42 -1
- package/dist/tui-autocomplete-layout.js +3 -1
- package/dist/tui-copy-catalog.js +85 -6
- package/dist/tui-editor-render.js +36 -0
- package/dist/tui-mcp-control.js +41 -6
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/agent-run.js +1 -0
- package/node_modules/@maka/core/dist/attachments.js +3 -0
- package/node_modules/@maka/core/dist/canonical-json.js +27 -0
- package/node_modules/@maka/core/dist/capabilities.js +35 -0
- package/node_modules/@maka/core/dist/computer-use.js +0 -1
- package/node_modules/@maka/core/dist/display-redaction.js +18 -0
- package/node_modules/@maka/core/dist/llm-connections.js +13 -0
- package/node_modules/@maka/core/dist/model-call-attempt.js +2 -0
- package/node_modules/@maka/core/dist/model-metadata.js +4 -0
- package/node_modules/@maka/core/dist/redaction.js +35 -0
- package/node_modules/@maka/core/dist/run-composition.js +77 -2
- package/node_modules/@maka/core/dist/runtime-event.js +3 -0
- package/node_modules/@maka/core/dist/session.js +57 -6
- package/node_modules/@maka/core/dist/slash-command-catalog.js +1 -0
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/workhub-action-result.js +68 -0
- package/node_modules/@maka/core/package.json +3 -3
- package/node_modules/@maka/eval/dist/experiment-directory.js +4 -13
- package/node_modules/@maka/eval/dist/toolchain-verification.js +1 -1
- package/node_modules/@maka/mcp/dist/form-elicitation.js +213 -0
- package/node_modules/@maka/mcp/dist/index.js +337 -71
- package/node_modules/@maka/runtime/dist/agent-run-inspect.js +0 -13
- package/node_modules/@maka/runtime/dist/agent-run.js +90 -2
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +16 -8
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +57 -50
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +2 -2
- package/node_modules/@maka/runtime/dist/context-budget-helpers.js +0 -16
- package/node_modules/@maka/runtime/dist/conversation-copy.js +153 -11
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +3 -3
- package/node_modules/@maka/runtime/dist/goal-continuation.js +5 -1
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +69 -1
- package/node_modules/@maka/runtime/dist/mcp-tools.js +7 -2
- package/node_modules/@maka/runtime/dist/model-fetcher.js +42 -2
- package/node_modules/@maka/runtime/dist/model-history.js +0 -112
- package/node_modules/@maka/runtime/dist/plugin-runtime.js +20 -10
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +205 -0
- package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +8 -1
- package/node_modules/@maka/runtime/dist/request-shape.js +23 -0
- package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +1 -1
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +24 -1
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +127 -13
- package/node_modules/@maka/runtime/dist/session-manager.js +20 -36
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +21 -0
- package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +0 -5
- package/node_modules/@maka/runtime/dist/test-connection.js +0 -1
- package/node_modules/@maka/runtime/dist/tool-activation-identity.js +41 -0
- package/node_modules/@maka/runtime/dist/tool-availability.js +11 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +63 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +42 -12
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +27 -4
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/client/connection.js +30 -5
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +52 -13
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +4 -2
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +18 -1
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +19 -0
- package/node_modules/@maka/runtime-host/dist/control/endpoint.js +1 -3
- package/node_modules/@maka/runtime-host/dist/node-error.js +22 -0
- package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +1 -3
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +0 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +1 -3
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +9 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +3 -2
- package/node_modules/@maka/runtime-host/dist/protocol/plan.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +27 -5
- package/node_modules/@maka/runtime-host/dist/protocol/project-catalog.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +86 -157
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/agent-graph-coordinator.js +0 -3
- package/node_modules/@maka/runtime-host/dist/server/canonical-session-projection.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/connection-session.js +28 -8
- package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +112 -56
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +32 -32
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +85 -25
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +42 -14
- package/node_modules/@maka/runtime-host/dist/server/failure-diagnostic.js +24 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +7 -3
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -3
- package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +3 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +34 -4
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +51 -23
- package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +2 -7
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +110 -14
- package/node_modules/@maka/runtime-host/dist/server/runtime-resource-coordinator.js +11 -8
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +31 -21
- package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +20 -8
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +15 -104
- package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +59 -82
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +132 -139
- package/node_modules/@maka/runtime-host/dist/server/workhub-message-attachments.js +46 -0
- package/node_modules/@maka/storage/dist/agent-run-store.js +14 -1
- package/node_modules/@maka/storage/dist/artifact-store.js +40 -3
- package/node_modules/@maka/storage/dist/atomic-file-write.js +74 -0
- package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +0 -1
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +284 -196
- package/node_modules/@maka/storage/dist/credential-store.js +12 -63
- package/node_modules/@maka/storage/dist/execution-stores.js +4 -1
- package/node_modules/@maka/storage/dist/git-exec.js +61 -0
- package/node_modules/@maka/storage/dist/git-worktree-child-executor.js +8 -35
- package/node_modules/@maka/storage/dist/goal-authority.js +2 -2
- package/node_modules/@maka/storage/dist/interaction-store.js +2 -2
- package/node_modules/@maka/storage/dist/mcp-config-store.js +10 -25
- package/node_modules/@maka/storage/dist/project-catalog.js +2 -23
- package/node_modules/@maka/storage/dist/runtime-event-invariants.js +2 -2
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +8 -3
- package/node_modules/@maka/storage/dist/scheduled-task-store.js +249 -283
- package/node_modules/@maka/storage/dist/session-bundle-manifest.js +5 -17
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +2 -1
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +2 -1
- package/node_modules/@maka/storage/dist/session-store.js +14 -2
- package/node_modules/@maka/storage/dist/settings-store.js +8 -4
- package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +11 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +1 -2
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +12 -1
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +67 -3
- package/node_modules/@maka/storage/dist/stable-storage.js +14 -1
- package/node_modules/@maka/storage/dist/storage-id.js +28 -0
- package/node_modules/@maka/storage/dist/tool-result-archive-evidence.js +31 -4
- package/node_modules/@maka/storage/dist/workspace-identity.js +2 -15
- package/node_modules/@maka/storage/dist/workspace-version-authority-internal.js +1 -8
- package/package.json +1 -1
- package/node_modules/@maka/core/dist/workhub-creation-intent.js +0 -990
- package/node_modules/@maka/core/dist/workhub-session-resolver.js +0 -50
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { Key, matchesKey, truncateToWidth, visibleWidth, } from '@earendil-works/pi-tui';
|
|
20
|
-
import { ansi } from './tui-ansi.js';
|
|
19
|
+
import { Key, Input, isKeyRelease, isKeyRepeat, matchesKey, truncateToWidth, visibleWidth, } from '@earendil-works/pi-tui';
|
|
20
|
+
import { ansi, stripAnsi } from './tui-ansi.js';
|
|
21
|
+
import { TUI_COPY_RESOURCES } from './tui-copy-catalog.js';
|
|
21
22
|
const VIEWER_CHROME_ROWS = 2;
|
|
22
23
|
/**
|
|
23
24
|
* Full-screen, read-only navigation over the CLI transcript projection.
|
|
@@ -28,19 +29,100 @@ const VIEWER_CHROME_ROWS = 2;
|
|
|
28
29
|
*/
|
|
29
30
|
export class TranscriptViewerOverlay {
|
|
30
31
|
input;
|
|
32
|
+
focused = false;
|
|
31
33
|
top = 0;
|
|
32
34
|
documentRows = 0;
|
|
33
35
|
bodyRows = 0;
|
|
34
36
|
followsEnd = true;
|
|
37
|
+
document = { lines: [], anchors: [] };
|
|
38
|
+
expanded = true;
|
|
39
|
+
anchor;
|
|
40
|
+
search = new Input();
|
|
41
|
+
searching = false;
|
|
42
|
+
query = '';
|
|
43
|
+
matches = [];
|
|
44
|
+
searchOrigin;
|
|
45
|
+
matchedLine;
|
|
35
46
|
constructor(input) {
|
|
36
47
|
this.input = input;
|
|
37
48
|
}
|
|
38
49
|
invalidate() { }
|
|
39
50
|
handleInput(data) {
|
|
51
|
+
if (isKeyRelease(data))
|
|
52
|
+
return;
|
|
53
|
+
if (matchesKey(data, Key.ctrl('o'))) {
|
|
54
|
+
if (!isKeyRepeat(data))
|
|
55
|
+
this.input.onClose();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (this.searching) {
|
|
59
|
+
if (matchesKey(data, Key.escape)) {
|
|
60
|
+
this.searching = false;
|
|
61
|
+
this.query = '';
|
|
62
|
+
this.matches = [];
|
|
63
|
+
if (this.searchOrigin)
|
|
64
|
+
Object.assign(this, this.searchOrigin);
|
|
65
|
+
this.input.onChange();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (matchesKey(data, Key.enter)) {
|
|
69
|
+
this.searching = false;
|
|
70
|
+
this.input.onChange();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (matchesKey(data, Key.up) || matchesKey(data, Key.down)) {
|
|
74
|
+
this.nextMatch(matchesKey(data, Key.up) ? -1 : 1);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.search.handleInput(data);
|
|
78
|
+
const query = this.search.getValue().trim().toLocaleLowerCase();
|
|
79
|
+
if (query !== this.query) {
|
|
80
|
+
this.query = query;
|
|
81
|
+
this.findMatches();
|
|
82
|
+
const target = this.matches.find((line) => line >= (this.searchOrigin?.top ?? 0)) ?? this.matches[0];
|
|
83
|
+
if (target !== undefined)
|
|
84
|
+
this.goToMatch(target);
|
|
85
|
+
}
|
|
86
|
+
this.input.onChange();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (matchesKey(data, Key.escape) && this.query) {
|
|
90
|
+
this.query = '';
|
|
91
|
+
this.matches = [];
|
|
92
|
+
if (this.searchOrigin)
|
|
93
|
+
Object.assign(this, this.searchOrigin);
|
|
94
|
+
this.input.onChange();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
40
97
|
if (matchesKey(data, Key.escape) || matchesKey(data, 'q')) {
|
|
41
98
|
this.input.onClose();
|
|
42
99
|
return;
|
|
43
100
|
}
|
|
101
|
+
if (matchesKey(data, '/')) {
|
|
102
|
+
this.searchOrigin = {
|
|
103
|
+
top: this.top,
|
|
104
|
+
followsEnd: this.followsEnd,
|
|
105
|
+
anchor: this.anchor ? { ...this.anchor } : undefined,
|
|
106
|
+
};
|
|
107
|
+
this.search.setValue(this.query);
|
|
108
|
+
this.searching = true;
|
|
109
|
+
this.input.onChange();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (this.query && (matchesKey(data, 'n') || matchesKey(data, Key.shift('n')))) {
|
|
113
|
+
this.nextMatch(matchesKey(data, Key.shift('n')) ? -1 : 1);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (matchesKey(data, Key.ctrl('e'))) {
|
|
117
|
+
if (!isKeyRepeat(data)) {
|
|
118
|
+
this.expanded = !this.expanded;
|
|
119
|
+
// A detail that disappears on collapse returns to its own heading.
|
|
120
|
+
if (!this.expanded && this.anchor)
|
|
121
|
+
this.anchor.offset = 0;
|
|
122
|
+
this.input.onChange();
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
44
126
|
if (matchesKey(data, Key.up)) {
|
|
45
127
|
this.scrollBy(-1);
|
|
46
128
|
return;
|
|
@@ -60,12 +142,14 @@ export class TranscriptViewerOverlay {
|
|
|
60
142
|
if (matchesKey(data, Key.home)) {
|
|
61
143
|
this.followsEnd = false;
|
|
62
144
|
this.top = 0;
|
|
145
|
+
this.captureAnchor();
|
|
63
146
|
this.input.onChange();
|
|
64
147
|
return;
|
|
65
148
|
}
|
|
66
149
|
if (matchesKey(data, Key.end)) {
|
|
67
150
|
this.followsEnd = true;
|
|
68
151
|
this.top = this.maxTop();
|
|
152
|
+
this.captureAnchor();
|
|
69
153
|
this.input.onChange();
|
|
70
154
|
}
|
|
71
155
|
}
|
|
@@ -76,31 +160,74 @@ export class TranscriptViewerOverlay {
|
|
|
76
160
|
// navigation chrome only. The footer appears once header + body + footer fit.
|
|
77
161
|
const showFooter = viewportRows > 2;
|
|
78
162
|
this.bodyRows = Math.max(0, viewportRows - (showFooter ? VIEWER_CHROME_ROWS : 1));
|
|
79
|
-
|
|
163
|
+
this.document = this.input.renderTranscript(safeWidth, this.expanded);
|
|
164
|
+
const document = this.document.lines;
|
|
80
165
|
this.documentRows = document.length;
|
|
166
|
+
if (!this.followsEnd && this.anchor) {
|
|
167
|
+
const index = this.document.anchors.findIndex((entry) => entry.id === this.anchor.id);
|
|
168
|
+
if (index >= 0) {
|
|
169
|
+
const entry = this.document.anchors[index];
|
|
170
|
+
const end = this.document.anchors[index + 1]?.line ?? document.length;
|
|
171
|
+
this.top = entry.line + Math.min(this.anchor.offset, Math.max(0, end - entry.line - 1));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
81
174
|
const maxTop = this.maxTop();
|
|
82
175
|
this.top = this.followsEnd ? maxTop : clamp(this.top, 0, maxTop);
|
|
83
|
-
this.
|
|
176
|
+
this.captureAnchor();
|
|
177
|
+
this.findMatches();
|
|
84
178
|
const visible = document.slice(this.top, this.top + this.bodyRows);
|
|
85
179
|
const start = visible.length === 0 ? 0 : this.top + 1;
|
|
86
180
|
const end = visible.length === 0 ? 0 : this.top + visible.length;
|
|
87
|
-
const
|
|
181
|
+
const copy = TUI_COPY_RESOURCES['transcript-reader'][this.input.locale ?? 'en'];
|
|
182
|
+
const header = padLine(`${ansi.bold(copy.title)} ${ansi.dim(`${start}-${end}/${document.length} · ${copy.scope}`)}`, safeWidth);
|
|
183
|
+
const matchingLines = new Set(this.matches);
|
|
88
184
|
const body = [
|
|
89
|
-
...visible.map((line) => padLine(line, safeWidth)),
|
|
185
|
+
...visible.map((line, index) => padLine(matchingLines.has(this.top + index) ? ansi.reverse(stripAnsi(line)) : line, safeWidth)),
|
|
90
186
|
...Array.from({ length: Math.max(0, this.bodyRows - visible.length) }, () => ' '.repeat(safeWidth)),
|
|
91
187
|
];
|
|
92
188
|
if (!showFooter)
|
|
93
189
|
return [header, ...body];
|
|
94
|
-
|
|
190
|
+
this.search.focused = this.focused && this.searching;
|
|
191
|
+
const footer = padLine(this.searching
|
|
192
|
+
? `/ ${this.search.render(Math.max(1, safeWidth - 3))[0] ?? ''}`
|
|
193
|
+
: ansi.dim(this.query
|
|
194
|
+
? `${this.matches.length} ${copy.matches} · n/N · Esc ${copy.back}`
|
|
195
|
+
: copy.hint), safeWidth);
|
|
95
196
|
return [header, ...body, footer];
|
|
96
197
|
}
|
|
97
198
|
scrollBy(delta) {
|
|
199
|
+
this.matchedLine = undefined;
|
|
98
200
|
const maxTop = this.maxTop();
|
|
99
201
|
this.top = clamp(this.top + delta, 0, maxTop);
|
|
100
202
|
// Follow the tail whenever the clamped position is the end, including the
|
|
101
203
|
// no-op case where a short transcript cannot move at all: a stray Up key
|
|
102
204
|
// must not pin the viewer at the head once the transcript grows.
|
|
103
205
|
this.followsEnd = this.top === maxTop;
|
|
206
|
+
this.captureAnchor();
|
|
207
|
+
this.input.onChange();
|
|
208
|
+
}
|
|
209
|
+
captureAnchor() {
|
|
210
|
+
const entry = [...this.document.anchors].reverse().find((entry) => entry.line <= this.top);
|
|
211
|
+
this.anchor = entry ? { id: entry.id, offset: this.top - entry.line } : undefined;
|
|
212
|
+
}
|
|
213
|
+
findMatches() {
|
|
214
|
+
this.matches = this.query
|
|
215
|
+
? this.document.lines.flatMap((line, index) => stripAnsi(line).toLocaleLowerCase().includes(this.query) ? [index] : [])
|
|
216
|
+
: [];
|
|
217
|
+
}
|
|
218
|
+
goToMatch(line) {
|
|
219
|
+
this.matchedLine = line;
|
|
220
|
+
this.top = clamp(line, 0, this.maxTop());
|
|
221
|
+
this.followsEnd = false;
|
|
222
|
+
this.captureAnchor();
|
|
223
|
+
}
|
|
224
|
+
nextMatch(direction) {
|
|
225
|
+
const current = this.matchedLine ?? this.top;
|
|
226
|
+
const line = direction > 0
|
|
227
|
+
? (this.matches.find((line) => line > current) ?? this.matches[0])
|
|
228
|
+
: ([...this.matches].reverse().find((line) => line < current) ?? this.matches.at(-1));
|
|
229
|
+
if (line !== undefined)
|
|
230
|
+
this.goToMatch(line);
|
|
104
231
|
this.input.onChange();
|
|
105
232
|
}
|
|
106
233
|
maxTop() {
|
|
@@ -20,8 +20,8 @@ import { activateLocalManagedRuntimeHost } from './runtime-host-local-managed-ac
|
|
|
20
20
|
import { randomUUID } from 'node:crypto';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
22
|
import { NO_REAL_CONNECTION_CODE } from '@maka/core/connection-error-copy';
|
|
23
|
-
import { connectOrSpawnRuntimeHost, connectRuntimeHost, connectRuntimeHostProfile, createClientRuntimeHostProfileCatalog, createRuntimeHostPeerClientFromEnvironment, createRuntimeHostReconnectingConnection, loadOrCreateRuntimeHostClientInstanceId, LOCAL_RUNTIME_HOST_PROFILE, readRuntimeHostConnectionCatalog, RuntimeHostPermanentReconnectError, RuntimeHostRemoteCompatibilityError, runHostHandoff, runtimeHostStartupError, } from '@maka/runtime-host/client';
|
|
24
|
-
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, } from '@maka/runtime-host/protocol';
|
|
23
|
+
import { connectOrSpawnRuntimeHost, forceTerminateObservedRegisteredRuntimeHost, connectRuntimeHost, connectRuntimeHostProfile, createClientRuntimeHostProfileCatalog, createRuntimeHostPeerClientFromEnvironment, createRuntimeHostReconnectingConnection, loadOrCreateRuntimeHostClientInstanceId, LOCAL_RUNTIME_HOST_PROFILE, readRuntimeHostConnectionCatalog, RuntimeHostPermanentReconnectError, RuntimeHostRemoteCompatibilityError, runHostHandoff, runtimeHostStartupError, } from '@maka/runtime-host/client';
|
|
24
|
+
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, RUNTIME_HOST_COMPATIBILITY_EPOCH, } from '@maka/runtime-host/protocol';
|
|
25
25
|
import { readLocalHostDeploymentRecord, resolveRuntimeHostManagedDeploymentAuthority, } from '@maka/runtime-host/operator';
|
|
26
26
|
import { resolveMakaClientDataRoot } from '@maka/storage/workspace-root';
|
|
27
27
|
import { isTemporaryNpxInstallation, resolveRuntimeHostNpmGlobalInstallation, } from './runtime-host-cli-installation.js';
|
|
@@ -70,6 +70,7 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
70
70
|
createPeerClient: createRuntimeHostPeerClientFromEnvironment,
|
|
71
71
|
resolveInstallation: resolveRuntimeHostNpmGlobalInstallation,
|
|
72
72
|
isTemporaryNpxInstallation,
|
|
73
|
+
terminateObservedHost: forceTerminateObservedRegisteredRuntimeHost,
|
|
73
74
|
restartDeployment: restartRuntimeHostNpmGlobalDeployment,
|
|
74
75
|
sourceRetirementAvailable: runtimeHostNpmGlobalSourceRetirementAvailable,
|
|
75
76
|
...overrides,
|
|
@@ -157,6 +158,7 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
157
158
|
: await deps.readDeploymentRecord(connected.registration.rootId);
|
|
158
159
|
let replacement;
|
|
159
160
|
let installation;
|
|
161
|
+
let installationFailure;
|
|
160
162
|
// On-demand managed Hosts are also ephemeral processes. Their durable
|
|
161
163
|
// operator authority, not the process lifetime label, decides who may
|
|
162
164
|
// replace them (including when the Host was already running).
|
|
@@ -164,8 +166,8 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
164
166
|
try {
|
|
165
167
|
installation = await deps.resolveInstallation();
|
|
166
168
|
}
|
|
167
|
-
catch {
|
|
168
|
-
|
|
169
|
+
catch (error) {
|
|
170
|
+
installationFailure = error instanceof Error ? error.message : String(error);
|
|
169
171
|
}
|
|
170
172
|
const owner = record?.state.kind === 'handoff' ? record.state.from : record?.state.owner;
|
|
171
173
|
if (installation &&
|
|
@@ -173,15 +175,16 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
173
175
|
(owner.kind === installation.owner.kind &&
|
|
174
176
|
owner.installationId === installation.owner.installationId))) {
|
|
175
177
|
const expectedInstallation = installation;
|
|
176
|
-
const canInterrupt =
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
178
|
+
const canInterrupt = connected.processIdentity !== undefined ||
|
|
179
|
+
(record
|
|
180
|
+
? await deps
|
|
181
|
+
.sourceRetirementAvailable({
|
|
182
|
+
rootId: connected.registration.rootId,
|
|
183
|
+
owner: installation.owner,
|
|
184
|
+
source: record.state.selected,
|
|
185
|
+
})
|
|
186
|
+
.catch(() => false)
|
|
187
|
+
: false);
|
|
185
188
|
replacement = {
|
|
186
189
|
kind: record?.state.kind === 'handoff' ? 'repair' : 'replace',
|
|
187
190
|
canReplaceIdle: true,
|
|
@@ -190,6 +193,9 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
190
193
|
const result = await deps.restartDeployment({
|
|
191
194
|
rootPath: input.rootPath,
|
|
192
195
|
registration: connected.registration,
|
|
196
|
+
...(connected.processIdentity
|
|
197
|
+
? { processIdentity: connected.processIdentity }
|
|
198
|
+
: {}),
|
|
193
199
|
activeWorkPolicy,
|
|
194
200
|
expectedInstallation,
|
|
195
201
|
...(attemptSignal ? { signal: attemptSignal } : {}),
|
|
@@ -210,11 +216,45 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
210
216
|
};
|
|
211
217
|
}
|
|
212
218
|
}
|
|
219
|
+
// The same observed-process recovery used by Desktop is available to
|
|
220
|
+
// persistent local invocations without a deployment owner. This is an
|
|
221
|
+
// explicit interruption, never an idle inference or an installation claim.
|
|
222
|
+
const processIdentity = connected.processIdentity;
|
|
223
|
+
if (!replacement &&
|
|
224
|
+
!managed &&
|
|
225
|
+
!record &&
|
|
226
|
+
!invocationOwned &&
|
|
227
|
+
connected.registration.lifecycleMode === 'ephemeral' &&
|
|
228
|
+
processIdentity) {
|
|
229
|
+
const registration = connected.registration;
|
|
230
|
+
replacement = {
|
|
231
|
+
kind: 'replace',
|
|
232
|
+
canReplaceIdle: false,
|
|
233
|
+
canInterrupt: true,
|
|
234
|
+
execute: async (policy, progress, consent, attemptSignal) => {
|
|
235
|
+
if (policy !== 'interrupt_active_work' || consent !== 'explicit') {
|
|
236
|
+
return { kind: 'active_work' };
|
|
237
|
+
}
|
|
238
|
+
attemptSignal?.throwIfAborted();
|
|
239
|
+
if ((await deps.resolveManagedAuthority(registration.rootId)) ||
|
|
240
|
+
(await deps.readDeploymentRecord(registration.rootId)))
|
|
241
|
+
return { kind: 'changed' };
|
|
242
|
+
attemptSignal?.throwIfAborted();
|
|
243
|
+
progress('retiring');
|
|
244
|
+
const stopped = await deps.terminateObservedHost({ rootPath: input.rootPath, registration }, { processIdentity, isCurrent: () => !signal?.aborted && !attemptSignal?.aborted });
|
|
245
|
+
if (!stopped)
|
|
246
|
+
return { kind: 'changed' };
|
|
247
|
+
progress('verifying');
|
|
248
|
+
return { kind: 'completed' };
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
213
252
|
return {
|
|
214
253
|
kind: 'blocked',
|
|
215
254
|
blocker: {
|
|
216
255
|
identity: JSON.stringify([
|
|
217
256
|
connected.registration,
|
|
257
|
+
processIdentity,
|
|
218
258
|
managed?.record,
|
|
219
259
|
record,
|
|
220
260
|
installation,
|
|
@@ -226,6 +266,23 @@ export async function connectRuntimeHostCliConnection(input, overrides = {}) {
|
|
|
226
266
|
hostEpoch: connected.registration.hostEpoch,
|
|
227
267
|
},
|
|
228
268
|
reason: record?.state.kind === 'handoff' ? 'repair' : 'upgrade',
|
|
269
|
+
...(!replacement
|
|
270
|
+
? {
|
|
271
|
+
recoveryBlocker: managed || connected.registration.lifecycleMode === 'service'
|
|
272
|
+
? 'managed'
|
|
273
|
+
: record
|
|
274
|
+
? 'owner'
|
|
275
|
+
: invocationOwned
|
|
276
|
+
? 'installation'
|
|
277
|
+
: 'identity',
|
|
278
|
+
diagnostic: [
|
|
279
|
+
`Host compatibility: ${connected.registration.compatibilityEpoch}; client: ${RUNTIME_HOST_COMPATIBILITY_EPOCH}.`,
|
|
280
|
+
installationFailure,
|
|
281
|
+
]
|
|
282
|
+
.filter(Boolean)
|
|
283
|
+
.join('\n'),
|
|
284
|
+
}
|
|
285
|
+
: {}),
|
|
229
286
|
...(connected.handshake?.activity ? { activity: connected.handshake.activity } : {}),
|
|
230
287
|
mayExitNaturally: !managed &&
|
|
231
288
|
connected.registration.lifecycleMode === 'ephemeral' &&
|
|
@@ -16,37 +16,25 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { createInterface } from 'node:readline';
|
|
19
|
+
import { clearLine, createInterface, cursorTo } from 'node:readline';
|
|
20
20
|
import { stripVTControlCharacters } from 'node:util';
|
|
21
21
|
import { formatHostHandoff, } from '@maka/runtime-host/client';
|
|
22
|
-
/**
|
|
22
|
+
/** The surface owns terminal input; replacement policy stays in the shared handoff. */
|
|
23
23
|
export function createCliHostHandoffSurface(locale, input = process.stdin, output = process.stderr) {
|
|
24
24
|
return (submit) => {
|
|
25
|
-
|
|
25
|
+
let readline;
|
|
26
26
|
let current;
|
|
27
27
|
let closed = false;
|
|
28
28
|
let ended = false;
|
|
29
|
+
const releaseReader = () => {
|
|
30
|
+
const previous = readline;
|
|
31
|
+
readline = undefined;
|
|
32
|
+
previous?.close();
|
|
33
|
+
};
|
|
29
34
|
const cancel = () => {
|
|
30
35
|
if (current)
|
|
31
36
|
submit(current.revision, 'cancel');
|
|
32
37
|
};
|
|
33
|
-
readline.on('SIGINT', cancel);
|
|
34
|
-
readline.on('close', () => {
|
|
35
|
-
ended = true;
|
|
36
|
-
if (!closed)
|
|
37
|
-
cancel();
|
|
38
|
-
});
|
|
39
|
-
readline.on('line', (line) => {
|
|
40
|
-
if (!current)
|
|
41
|
-
return;
|
|
42
|
-
const answer = line.trim().toLowerCase();
|
|
43
|
-
const action = answer === 'r' ? 'retry' : answer === 'stop' ? 'interrupt' : 'cancel';
|
|
44
|
-
if (!current.actions.includes(action)) {
|
|
45
|
-
readline.prompt();
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
submit(current.revision, action);
|
|
49
|
-
});
|
|
50
38
|
return {
|
|
51
39
|
update(view) {
|
|
52
40
|
if (closed || current?.revision === view.revision)
|
|
@@ -56,9 +44,13 @@ export function createCliHostHandoffSurface(locale, input = process.stdin, outpu
|
|
|
56
44
|
cancel();
|
|
57
45
|
return;
|
|
58
46
|
}
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
// A new observation gets a new input buffer. Ctrl+U leaves text after
|
|
48
|
+
// the cursor intact and is ignored by readline in TERM=dumb.
|
|
49
|
+
releaseReader();
|
|
50
|
+
if (output.isTTY) {
|
|
51
|
+
clearLine(output, 0);
|
|
52
|
+
cursorTo(output, 0);
|
|
53
|
+
}
|
|
62
54
|
const copy = formatHostHandoff(view, locale);
|
|
63
55
|
const text = [copy.title, copy.description, copy.detail, view.diagnostic]
|
|
64
56
|
.filter(Boolean)
|
|
@@ -69,12 +61,45 @@ export function createCliHostHandoffSurface(locale, input = process.stdin, outpu
|
|
|
69
61
|
if (view.actions.length === 0)
|
|
70
62
|
return;
|
|
71
63
|
const options = copy.actions.map(({ action, label }) => `${action === 'interrupt' ? 'stop' : action === 'retry' ? 'r' : 'Enter'}: ${label}`);
|
|
72
|
-
|
|
73
|
-
readline
|
|
64
|
+
// Create the reader only after the explanation is visible, with the
|
|
65
|
+
// final action prompt already installed. Never draw readline's default >.
|
|
66
|
+
const reader = createInterface({
|
|
67
|
+
input,
|
|
68
|
+
output,
|
|
69
|
+
terminal: output.isTTY === true,
|
|
70
|
+
prompt: options.join(' · ') + ' > ',
|
|
71
|
+
});
|
|
72
|
+
readline = reader;
|
|
73
|
+
reader.on('SIGINT', cancel);
|
|
74
|
+
reader.on('close', () => {
|
|
75
|
+
if (readline !== reader)
|
|
76
|
+
return;
|
|
77
|
+
ended = true;
|
|
78
|
+
if (!closed)
|
|
79
|
+
cancel();
|
|
80
|
+
});
|
|
81
|
+
reader.on('line', (line) => {
|
|
82
|
+
if (readline !== reader || current?.revision !== view.revision)
|
|
83
|
+
return;
|
|
84
|
+
const answer = line.trim().toLowerCase();
|
|
85
|
+
const action = answer === 'r'
|
|
86
|
+
? 'retry'
|
|
87
|
+
: answer === 'stop'
|
|
88
|
+
? 'interrupt'
|
|
89
|
+
: answer === ''
|
|
90
|
+
? 'cancel'
|
|
91
|
+
: undefined;
|
|
92
|
+
if (!action || !view.actions.includes(action)) {
|
|
93
|
+
reader.prompt();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
submit(view.revision, action);
|
|
97
|
+
});
|
|
98
|
+
reader.prompt();
|
|
74
99
|
},
|
|
75
100
|
close() {
|
|
76
101
|
closed = true;
|
|
77
|
-
|
|
102
|
+
releaseReader();
|
|
78
103
|
},
|
|
79
104
|
};
|
|
80
105
|
};
|
|
@@ -23,7 +23,7 @@ import { dirname, join, posix, resolve, win32 } from 'node:path';
|
|
|
23
23
|
import { isDeepStrictEqual } from 'node:util';
|
|
24
24
|
import { claimLocalHostProcessDeployment, handoffLocalHostProcessDeployment, readLocalHostDeploymentRecord, resolveRuntimeHostManagedDeploymentAuthority, } from '@maka/runtime-host/operator';
|
|
25
25
|
import { compareProductReleaseVersions } from '@maka/runtime-host/operator/update-package-evidence';
|
|
26
|
-
import { connectExistingRuntimeHost } from '@maka/runtime-host/client';
|
|
26
|
+
import { connectExistingRuntimeHost, forceTerminateObservedRegisteredRuntimeHost, } from '@maka/runtime-host/client';
|
|
27
27
|
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, } from '@maka/runtime-host/protocol';
|
|
28
28
|
import { resolveRuntimeHostNpmGlobalInstallation, } from './runtime-host-cli-installation.js';
|
|
29
29
|
import { openRuntimeHostPackageDeployment, prepareRuntimeHostPackageDeployment, resolveRuntimeHostPackageCliPath, } from './runtime-host-package-deployment.js';
|
|
@@ -73,6 +73,7 @@ export async function restartRuntimeHostNpmGlobalDeployment(input, authorityOpti
|
|
|
73
73
|
connectExisting: connectExistingRuntimeHost,
|
|
74
74
|
activateTarget: launchRuntimeHostTargetActivator,
|
|
75
75
|
retireSource: launchRuntimeHostLocalSourceRetirement,
|
|
76
|
+
terminateObservedHost: forceTerminateObservedRegisteredRuntimeHost,
|
|
76
77
|
...overrides,
|
|
77
78
|
};
|
|
78
79
|
if (await deps.resolveManagedAuthority(input.registration.rootId)) {
|
|
@@ -205,6 +206,15 @@ export async function restartRuntimeHostNpmGlobalDeployment(input, authorityOpti
|
|
|
205
206
|
}
|
|
206
207
|
return { kind: 'target_present' };
|
|
207
208
|
}
|
|
209
|
+
// Older source packages cannot negotiate retirement. Explicit consent may
|
|
210
|
+
// use Desktop's exact-process recovery, inside this existing deployment
|
|
211
|
+
// transaction and only after staging the verified successor.
|
|
212
|
+
if (activeWorkPolicy === 'interrupt_active_work' && input.processIdentity) {
|
|
213
|
+
input.signal?.throwIfAborted();
|
|
214
|
+
const stopped = await deps.terminateObservedHost({ rootPath: input.rootPath, registration: input.registration }, { processIdentity: input.processIdentity, isCurrent: () => !input.signal?.aborted });
|
|
215
|
+
if (!stopped)
|
|
216
|
+
throw new Error('The observed Runtime Host changed before it could be stopped safely');
|
|
217
|
+
}
|
|
208
218
|
const activated = await activateExactTarget(rootId, stagedTarget, inheritableAuthorityLeaseFd, registration.hostEpoch);
|
|
209
219
|
if (activated === 'active_work')
|
|
210
220
|
return { kind: 'active_work' };
|
|
@@ -670,9 +670,6 @@ async function normalizeStateRoot(requestedRoot) {
|
|
|
670
670
|
throw new RuntimeHostServiceManagerError('invalid_config', `Invalid Runtime Host State Root: ${requestedRoot}`, { cause: error });
|
|
671
671
|
}
|
|
672
672
|
}
|
|
673
|
-
export async function resolveRuntimeHostManagedStateRoot(requestedRoot) {
|
|
674
|
-
return normalizeStateRoot(requestedRoot);
|
|
675
|
-
}
|
|
676
673
|
async function normalizeProjectDirectoryRoots(roots) {
|
|
677
674
|
let canonicalRoots;
|
|
678
675
|
try {
|
|
@@ -37,6 +37,7 @@ export class RuntimeHostSessionChannel {
|
|
|
37
37
|
#now;
|
|
38
38
|
#onTurnStarted;
|
|
39
39
|
#onRuntimeResourceChanged;
|
|
40
|
+
#onSessionDomainChanged;
|
|
40
41
|
#onInteractionPending;
|
|
41
42
|
#onInteractionResolved;
|
|
42
43
|
#onTranscriptSettlement;
|
|
@@ -71,6 +72,7 @@ export class RuntimeHostSessionChannel {
|
|
|
71
72
|
this.#now = options.now;
|
|
72
73
|
this.#onTurnStarted = options.onTurnStarted;
|
|
73
74
|
this.#onRuntimeResourceChanged = options.onRuntimeResourceChanged;
|
|
75
|
+
this.#onSessionDomainChanged = options.onSessionDomainChanged;
|
|
74
76
|
this.#onInteractionPending = options.onInteractionPending;
|
|
75
77
|
this.#onInteractionResolved = options.onInteractionResolved;
|
|
76
78
|
this.#onTranscriptSettlement = options.onTranscriptSettlement;
|
|
@@ -79,6 +81,16 @@ export class RuntimeHostSessionChannel {
|
|
|
79
81
|
this.#onSnapshotChanged = options.onSnapshotChanged;
|
|
80
82
|
this.#onFailed = options.onFailed;
|
|
81
83
|
this.#onRecovered = options.onRecovered;
|
|
84
|
+
this.#subscribeSessionDomainChanges(subscription);
|
|
85
|
+
}
|
|
86
|
+
#subscribeSessionDomainChanges(subscription) {
|
|
87
|
+
if (!this.#onSessionDomainChanged)
|
|
88
|
+
return;
|
|
89
|
+
subscription.subscribeSessionDomainChanges((frame) => {
|
|
90
|
+
if (!this.#closing && this.#subscription === subscription) {
|
|
91
|
+
this.#onSessionDomainChanged?.(frame);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
82
94
|
}
|
|
83
95
|
static async open(options) {
|
|
84
96
|
const subscription = await options.connection.openSessionSubscription({
|
|
@@ -343,6 +355,7 @@ export class RuntimeHostSessionChannel {
|
|
|
343
355
|
return;
|
|
344
356
|
}
|
|
345
357
|
this.#subscription = replacement;
|
|
358
|
+
this.#subscribeSessionDomainChanges(replacement);
|
|
346
359
|
this.#ready = false;
|
|
347
360
|
this.#pendingFrames.length = 0;
|
|
348
361
|
void this.#pump(replacement);
|
|
@@ -20,6 +20,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { DEFAULT_SESSION_NAME } from '@maka/core/session-name';
|
|
22
22
|
import { decodeStoredMessage as decodePersistedStoredMessage, deriveTurnRecords, userFacingText, } from '@maka/core/session';
|
|
23
|
+
import { projectSessionTodoItemsForDisplay } from '@maka/core/session-todo';
|
|
23
24
|
import { markPersisted } from '@maka/core/persisted-value';
|
|
24
25
|
import { isSideConversationSession } from '@maka/core/side-conversation';
|
|
25
26
|
import { createSessionCopyCleanupAuthority, } from '@maka/storage/session-copy-cleanup';
|
|
@@ -88,6 +89,7 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
88
89
|
#transcriptRefreshSequence = 0;
|
|
89
90
|
#startedTurnListeners = new Set();
|
|
90
91
|
#goalListeners = new Set();
|
|
92
|
+
#todoChangeListeners = new Set();
|
|
91
93
|
#pendingInteractionListeners = new Set();
|
|
92
94
|
#claimedTurnIds = new Set();
|
|
93
95
|
#shellRunListeners = new Set();
|
|
@@ -381,6 +383,22 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
381
383
|
const sessionId = await this.#ensureSession();
|
|
382
384
|
return this.#request('turn.message.query', { sessionId, messageIds });
|
|
383
385
|
}
|
|
386
|
+
async queryTodo(sessionId) {
|
|
387
|
+
const currentSessionId = this.#requireSession('query Todo');
|
|
388
|
+
if (sessionId !== currentSessionId) {
|
|
389
|
+
throw new Error(`Cannot query Todo for a non-current Session: ${sessionId}`);
|
|
390
|
+
}
|
|
391
|
+
const sessionGeneration = this.#sessionGeneration;
|
|
392
|
+
const result = await this.#request('session.todo.query', { sessionId });
|
|
393
|
+
this.#assertCurrentSession(sessionId, sessionGeneration);
|
|
394
|
+
if (result.sessionId !== sessionId) {
|
|
395
|
+
throw new Error(`Runtime Host returned Todo for an unexpected Session: ${result.sessionId}`);
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
sessionId,
|
|
399
|
+
items: projectSessionTodoItemsForDisplay(result.items),
|
|
400
|
+
};
|
|
401
|
+
}
|
|
384
402
|
async retractQueued() {
|
|
385
403
|
if (!this.#sessionId)
|
|
386
404
|
return { text: '', messageIds: [] };
|
|
@@ -856,6 +874,10 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
856
874
|
this.#goalListeners.add(listener);
|
|
857
875
|
return () => this.#goalListeners.delete(listener);
|
|
858
876
|
}
|
|
877
|
+
subscribeTodoChanges(listener) {
|
|
878
|
+
this.#todoChangeListeners.add(listener);
|
|
879
|
+
return () => this.#todoChangeListeners.delete(listener);
|
|
880
|
+
}
|
|
859
881
|
async controlGoal(action) {
|
|
860
882
|
const sessionId = this.#sessionId;
|
|
861
883
|
if (!sessionId)
|
|
@@ -1246,6 +1268,7 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
1246
1268
|
now: this.#now,
|
|
1247
1269
|
onTurnStarted: (turn) => this.#publishStartedTurn(turn, sessionGeneration),
|
|
1248
1270
|
onRuntimeResourceChanged: (sourceSessionId, ref) => this.#publishRuntimeResource(sourceSessionId, ref),
|
|
1271
|
+
onSessionDomainChanged: (frame) => this.#publishSessionDomainChanged(frame, sessionId, sessionGeneration),
|
|
1249
1272
|
onInteractionPending: (pending) => {
|
|
1250
1273
|
for (const listener of this.#pendingInteractionListeners)
|
|
1251
1274
|
listener(pending);
|
|
@@ -1261,9 +1284,27 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
1261
1284
|
for (const listener of this.#goalListeners)
|
|
1262
1285
|
listener(goal);
|
|
1263
1286
|
},
|
|
1264
|
-
onRecovered: () =>
|
|
1287
|
+
onRecovered: () => {
|
|
1288
|
+
this.#refreshRuntimeResources(sessionId);
|
|
1289
|
+
this.#publishTodoChanged(sessionId, sessionGeneration);
|
|
1290
|
+
},
|
|
1265
1291
|
});
|
|
1266
1292
|
}
|
|
1293
|
+
#publishSessionDomainChanged(frame, sessionId, sessionGeneration) {
|
|
1294
|
+
if (frame.domain !== 'todo' ||
|
|
1295
|
+
frame.sessionId !== sessionId ||
|
|
1296
|
+
this.#sessionId !== sessionId ||
|
|
1297
|
+
this.#sessionGeneration !== sessionGeneration) {
|
|
1298
|
+
return;
|
|
1299
|
+
}
|
|
1300
|
+
this.#publishTodoChanged(sessionId, sessionGeneration);
|
|
1301
|
+
}
|
|
1302
|
+
#publishTodoChanged(sessionId, sessionGeneration) {
|
|
1303
|
+
if (this.#sessionId !== sessionId || this.#sessionGeneration !== sessionGeneration)
|
|
1304
|
+
return;
|
|
1305
|
+
for (const listener of this.#todoChangeListeners)
|
|
1306
|
+
listener(sessionId);
|
|
1307
|
+
}
|
|
1267
1308
|
#publishRuntimeResource(sourceSessionId, ref) {
|
|
1268
1309
|
void this.#request('runtime.resource.query', {
|
|
1269
1310
|
kind: 'get',
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { selectListTheme, stripAnsi } from './tui-ansi.js';
|
|
20
|
+
import { stripUnfocusedCursorStyle } from './tui-editor-render.js';
|
|
20
21
|
export function arrangeAutocompleteAboveEditor(input) {
|
|
21
22
|
if (!input.autocompleteShowing) {
|
|
22
23
|
return { lines: input.lines, autocompleteSlotRows: 0, editorRows: input.lines.length };
|
|
@@ -72,7 +73,8 @@ export class MakaAutocompleteAboveEditorComponent {
|
|
|
72
73
|
this.editor.handleInput(data);
|
|
73
74
|
}
|
|
74
75
|
render(width) {
|
|
75
|
-
const
|
|
76
|
+
const renderedLines = this.editor.render(width);
|
|
77
|
+
const lines = stripUnfocusedCursorStyle(renderedLines, this.editor.focused);
|
|
76
78
|
const result = arrangeAutocompleteAboveEditor({
|
|
77
79
|
lines,
|
|
78
80
|
autocompleteShowing: this.editor.isShowingAutocomplete(),
|