memorix 1.2.1 → 1.2.2
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/CHANGELOG.md +16 -0
- package/README.md +14 -2
- package/README.zh-CN.md +14 -2
- package/TEAM.md +86 -86
- package/dist/cli/index.js +15407 -13779
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1321 -529
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.d.ts +1 -1
- package/dist/maintenance-runner.js +8458 -8087
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +16 -0
- package/dist/sdk.d.ts +7 -2
- package/dist/sdk.js +1349 -535
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +49 -1
- package/dist/types.js.map +1 -1
- package/docs/1.2.2-MEMORY-CONTROL-PLANE.md +434 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +4 -0
- package/docs/API_REFERENCE.md +24 -4
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/README.md +1 -1
- package/docs/dev-log/progress.txt +91 -11
- package/package.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/src/audit/index.ts +156 -156
- package/src/cli/command-guide.ts +192 -0
- package/src/cli/commands/audit-list.ts +89 -89
- package/src/cli/commands/audit.ts +9 -4
- package/src/cli/commands/background.ts +659 -659
- package/src/cli/commands/cleanup.ts +5 -1
- package/src/cli/commands/codegraph.ts +15 -5
- package/src/cli/commands/context.ts +3 -2
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/explain.ts +9 -3
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +75 -61
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/identity.ts +116 -0
- package/src/cli/commands/ingest-commit.ts +153 -153
- package/src/cli/commands/ingest-image.ts +71 -69
- package/src/cli/commands/ingest-log.ts +180 -180
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/lock.ts +93 -92
- package/src/cli/commands/memory.ts +58 -21
- package/src/cli/commands/message.ts +123 -118
- package/src/cli/commands/operator-shared.ts +98 -3
- package/src/cli/commands/poll.ts +74 -64
- package/src/cli/commands/purge-all-memory.ts +85 -85
- package/src/cli/commands/purge-project-memory.ts +83 -83
- package/src/cli/commands/reasoning.ts +135 -121
- package/src/cli/commands/retention.ts +9 -4
- package/src/cli/commands/serve-http.ts +8 -2
- package/src/cli/commands/serve-shared.ts +118 -118
- package/src/cli/commands/session.ts +29 -3
- package/src/cli/commands/skills.ts +124 -119
- package/src/cli/commands/status.ts +4 -3
- package/src/cli/commands/task.ts +193 -184
- package/src/cli/commands/team.ts +14 -10
- package/src/cli/commands/transfer.ts +108 -55
- package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
- package/src/cli/identity.ts +89 -0
- package/src/cli/index.ts +96 -19
- package/src/cli/invocation.ts +115 -0
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/Sidebar.tsx +179 -179
- package/src/cli/tui/chat-service.ts +41 -18
- package/src/cli/tui/data.ts +23 -44
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/tui/markdown-render.tsx +371 -371
- package/src/cli/tui/operator-context.ts +60 -0
- package/src/cli/tui/use-mouse.ts +157 -157
- package/src/cli/tui/useNavigation.ts +56 -56
- package/src/cli/tui/views/MemoryView.tsx +10 -8
- package/src/cli/update-checker.ts +211 -211
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/codegraph/auto-context.ts +31 -2
- package/src/codegraph/context-pack.ts +1 -0
- package/src/codegraph/project-context.ts +2 -0
- package/src/compact/engine.ts +26 -10
- package/src/compact/index-format.ts +25 -2
- package/src/compact/token-budget.ts +74 -74
- package/src/dashboard/project-classification.ts +64 -64
- package/src/dashboard/server.ts +46 -9
- package/src/embedding/fastembed-provider.ts +142 -142
- package/src/embedding/transformers-provider.ts +111 -111
- package/src/git/extractor.ts +209 -209
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/admission.ts +117 -0
- package/src/hooks/handler.ts +98 -91
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/significance-filter.ts +250 -250
- package/src/knowledge/context-assembly.ts +97 -0
- package/src/knowledge/workset.ts +179 -10
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/provider.ts +885 -885
- package/src/llm/quality.ts +248 -248
- package/src/memory/admission.ts +57 -0
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/consolidation.ts +13 -2
- package/src/memory/disclosure-policy.ts +140 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/export-import.ts +11 -3
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/formation/extract.ts +361 -361
- package/src/memory/formation/index.ts +417 -417
- package/src/memory/formation/resolve.ts +344 -344
- package/src/memory/formation/types.ts +315 -315
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph-context.ts +8 -2
- package/src/memory/graph.ts +197 -197
- package/src/memory/observations.ts +162 -4
- package/src/memory/quality-audit.ts +2 -0
- package/src/memory/refs.ts +94 -94
- package/src/memory/retention.ts +22 -2
- package/src/memory/secret-filter.ts +79 -79
- package/src/memory/session.ts +5 -2
- package/src/memory/visibility.ts +80 -0
- package/src/multimodal/image-loader.ts +143 -143
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/spawn-helper.ts +286 -286
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/context-compact.ts +188 -188
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +378 -340
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/orchestrate/worktree.ts +232 -232
- package/src/project/aliases.ts +374 -374
- package/src/project/detector.ts +268 -268
- package/src/rules/adapters/claude-code.ts +99 -99
- package/src/rules/adapters/codex.ts +97 -97
- package/src/rules/adapters/copilot.ts +124 -124
- package/src/rules/adapters/cursor.ts +114 -114
- package/src/rules/adapters/kiro.ts +126 -126
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/adapters/windsurf.ts +83 -83
- package/src/rules/syncer.ts +235 -235
- package/src/runtime/control-plane-maintenance.ts +1 -0
- package/src/runtime/isolated-maintenance.ts +1 -0
- package/src/runtime/lifecycle.ts +18 -0
- package/src/runtime/maintenance-jobs.ts +1 -0
- package/src/runtime/maintenance-runner.ts +2 -0
- package/src/runtime/project-maintenance.ts +89 -0
- package/src/sdk.ts +334 -304
- package/src/search/intent-detector.ts +289 -289
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/server.ts +260 -81
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/orama-store.ts +61 -6
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/store/sqlite-db.ts +23 -1
- package/src/store/sqlite-store.ts +12 -2
- package/src/team/event-bus.ts +76 -76
- package/src/team/file-locks.ts +173 -173
- package/src/team/handoff.ts +168 -161
- package/src/team/messages.ts +203 -203
- package/src/team/poll.ts +132 -132
- package/src/team/tasks.ts +211 -211
- package/src/types.ts +51 -0
- package/src/wiki/generator.ts +2 -0
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
- package/src/workspace/workflow-sync.ts +131 -131
package/src/cli/tui/data.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as fs from 'node:fs';
|
|
9
|
+
import { getTuiOperatorContext } from './operator-context.js';
|
|
9
10
|
|
|
10
11
|
export interface ProjectInfo {
|
|
11
12
|
name: string;
|
|
@@ -98,9 +99,7 @@ function truncate(text: string, max = 60): string {
|
|
|
98
99
|
|
|
99
100
|
export async function getProjectInfo(): Promise<ProjectInfo | null> {
|
|
100
101
|
try {
|
|
101
|
-
const {
|
|
102
|
-
const proj = detectProject(process.cwd());
|
|
103
|
-
if (!proj) return null;
|
|
102
|
+
const { project: proj } = await getTuiOperatorContext();
|
|
104
103
|
return {
|
|
105
104
|
name: proj.name,
|
|
106
105
|
id: proj.id,
|
|
@@ -127,12 +126,8 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
|
|
|
127
126
|
};
|
|
128
127
|
|
|
129
128
|
try {
|
|
130
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
131
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
132
129
|
const { initObservationStore: initStore, getObservationStore: getStore } = await import('../../store/obs-store.js');
|
|
133
|
-
|
|
134
|
-
const proj = detectProject(process.cwd());
|
|
135
|
-
if (!proj) return defaults;
|
|
130
|
+
const { project: proj, dataDir, reader } = await getTuiOperatorContext();
|
|
136
131
|
|
|
137
132
|
// Load .env BEFORE any process.env reads or provider initialization (#46)
|
|
138
133
|
try {
|
|
@@ -141,11 +136,11 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
|
|
|
141
136
|
} catch { /* best-effort */ }
|
|
142
137
|
|
|
143
138
|
const effectiveProjectId = projectId || proj.id;
|
|
144
|
-
|
|
139
|
+
if (effectiveProjectId !== proj.id) return defaults;
|
|
145
140
|
await initStore(dataDir);
|
|
146
141
|
const allObs = (await getStore().loadAll()) as any[];
|
|
147
|
-
|
|
148
|
-
const obs = allObs
|
|
142
|
+
const { filterReadableObservations } = await import('../../memory/visibility.js');
|
|
143
|
+
const obs = filterReadableObservations(allObs, reader);
|
|
149
144
|
const active = obs.filter((o: any) => (o.status ?? 'active') === 'active');
|
|
150
145
|
|
|
151
146
|
defaults.totalMemories = obs.length;
|
|
@@ -219,19 +214,15 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
|
|
|
219
214
|
|
|
220
215
|
export async function getRecentMemories(limit = 8, projectId?: string): Promise<MemoryItem[]> {
|
|
221
216
|
try {
|
|
222
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
223
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
224
217
|
const { initObservationStore: initStore, getObservationStore: getStore } = await import('../../store/obs-store.js');
|
|
225
|
-
|
|
226
|
-
const proj = detectProject(process.cwd());
|
|
227
|
-
if (!proj) return [];
|
|
218
|
+
const { project: proj, dataDir, reader } = await getTuiOperatorContext();
|
|
228
219
|
|
|
229
220
|
const effectiveProjectId = projectId || proj.id;
|
|
230
|
-
|
|
221
|
+
if (effectiveProjectId !== proj.id) return [];
|
|
231
222
|
await initStore(dataDir);
|
|
232
223
|
const allObs = (await getStore().loadAll()) as any[];
|
|
233
|
-
|
|
234
|
-
const projectObs = allObs
|
|
224
|
+
const { filterReadableObservations } = await import('../../memory/visibility.js');
|
|
225
|
+
const projectObs = filterReadableObservations(allObs, reader);
|
|
235
226
|
const active = projectObs.filter((o: any) => (o.status ?? 'active') === 'active');
|
|
236
227
|
const filtered = active.filter((o: any) => !/^(Ran:|Command:|Executed:)\s/i.test(o.title || ''));
|
|
237
228
|
|
|
@@ -251,18 +242,13 @@ export async function getRecentMemories(limit = 8, projectId?: string): Promise<
|
|
|
251
242
|
export async function searchMemories(query: string, limit = 10): Promise<SearchResult[]> {
|
|
252
243
|
try {
|
|
253
244
|
const { searchObservations } = await import('../../store/orama-store.js');
|
|
254
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
255
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
256
245
|
const { initObservations, prepareSearchIndex } = await import('../../memory/observations.js');
|
|
246
|
+
const { project: proj, dataDir, reader } = await getTuiOperatorContext();
|
|
257
247
|
|
|
258
|
-
const proj = detectProject(process.cwd());
|
|
259
|
-
if (!proj) return [];
|
|
260
|
-
|
|
261
|
-
const dataDir = await getProjectDataDir(proj.id);
|
|
262
248
|
await initObservations(dataDir);
|
|
263
249
|
await prepareSearchIndex();
|
|
264
250
|
|
|
265
|
-
const results = await searchObservations({ query, limit, projectId: proj.id });
|
|
251
|
+
const results = await searchObservations({ query, limit, projectId: proj.id, reader });
|
|
266
252
|
|
|
267
253
|
const typeIcons: Record<string, string> = {
|
|
268
254
|
gotcha: '!',
|
|
@@ -290,15 +276,10 @@ export async function searchMemories(query: string, limit = 10): Promise<SearchR
|
|
|
290
276
|
|
|
291
277
|
export async function storeQuickMemory(text: string): Promise<{ id: number; title: string } | null> {
|
|
292
278
|
try {
|
|
293
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
294
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
295
279
|
const { initObservations, storeObservation } = await import('../../memory/observations.js');
|
|
296
280
|
const { initObservationStore } = await import('../../store/obs-store.js');
|
|
281
|
+
const { project: proj, dataDir, reader, identity } = await getTuiOperatorContext();
|
|
297
282
|
|
|
298
|
-
const proj = detectProject(process.cwd());
|
|
299
|
-
if (!proj) return null;
|
|
300
|
-
|
|
301
|
-
const dataDir = await getProjectDataDir(proj.id);
|
|
302
283
|
await initObservationStore(dataDir);
|
|
303
284
|
await initObservations(dataDir);
|
|
304
285
|
|
|
@@ -310,6 +291,8 @@ export async function storeQuickMemory(text: string): Promise<{ id: number; titl
|
|
|
310
291
|
facts: [],
|
|
311
292
|
projectId: proj.id,
|
|
312
293
|
sourceDetail: 'explicit',
|
|
294
|
+
visibilityReader: reader,
|
|
295
|
+
...(identity ? { createdByAgentId: identity.agentId } : {}),
|
|
313
296
|
});
|
|
314
297
|
|
|
315
298
|
return { id: result.observation.id, title: text.slice(0, 100) };
|
|
@@ -484,23 +467,21 @@ export async function getKnowledgeGraph(
|
|
|
484
467
|
projectId?: string,
|
|
485
468
|
): Promise<import('../../wiki/types.js').ProjectKnowledgeGraph | null> {
|
|
486
469
|
try {
|
|
487
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
488
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
489
470
|
const { initObservationStore } = await import('../../store/obs-store.js');
|
|
490
471
|
const { initObservations, getAllObservations } = await import('../../memory/observations.js');
|
|
472
|
+
const { filterReadableObservations } = await import('../../memory/visibility.js');
|
|
491
473
|
const { initMiniSkillStore, getMiniSkillStore } = await import('../../store/mini-skill-store.js');
|
|
492
474
|
const { generateKnowledgeGraph } = await import('../../wiki/knowledge-graph.js');
|
|
493
475
|
|
|
494
|
-
const proj =
|
|
495
|
-
if (!proj) return null;
|
|
476
|
+
const { project: proj, dataDir, reader } = await getTuiOperatorContext();
|
|
496
477
|
|
|
497
478
|
const effectiveProjectId = projectId || proj.id;
|
|
498
|
-
|
|
479
|
+
if (effectiveProjectId !== proj.id) return null;
|
|
499
480
|
await initObservationStore(dataDir);
|
|
500
481
|
await initObservations(dataDir);
|
|
501
482
|
await initMiniSkillStore(dataDir);
|
|
502
483
|
|
|
503
|
-
const observations = getAllObservations();
|
|
484
|
+
const observations = filterReadableObservations(getAllObservations(), reader);
|
|
504
485
|
const skills = await getMiniSkillStore().loadByProject(effectiveProjectId);
|
|
505
486
|
|
|
506
487
|
return generateKnowledgeGraph({
|
|
@@ -515,23 +496,21 @@ export async function getKnowledgeGraph(
|
|
|
515
496
|
|
|
516
497
|
export async function getKnowledgeBase(projectId?: string): Promise<import('../../wiki/types.js').ProjectKnowledgeOverview | null> {
|
|
517
498
|
try {
|
|
518
|
-
const { detectProject } = await import('../../project/detector.js');
|
|
519
|
-
const { getProjectDataDir } = await import('../../store/persistence.js');
|
|
520
499
|
const { initObservationStore } = await import('../../store/obs-store.js');
|
|
521
500
|
const { initObservations, getAllObservations } = await import('../../memory/observations.js');
|
|
501
|
+
const { filterReadableObservations } = await import('../../memory/visibility.js');
|
|
522
502
|
const { initMiniSkillStore, getMiniSkillStore } = await import('../../store/mini-skill-store.js');
|
|
523
503
|
const { generateKnowledgeBase } = await import('../../wiki/generator.js');
|
|
524
504
|
|
|
525
|
-
const proj =
|
|
526
|
-
if (!proj) return null;
|
|
505
|
+
const { project: proj, dataDir, reader } = await getTuiOperatorContext();
|
|
527
506
|
|
|
528
507
|
const effectiveProjectId = projectId || proj.id;
|
|
529
|
-
|
|
508
|
+
if (effectiveProjectId !== proj.id) return null;
|
|
530
509
|
await initObservationStore(dataDir);
|
|
531
510
|
await initObservations(dataDir);
|
|
532
511
|
await initMiniSkillStore(dataDir);
|
|
533
512
|
|
|
534
|
-
const observations = getAllObservations();
|
|
513
|
+
const observations = filterReadableObservations(getAllObservations(), reader);
|
|
535
514
|
const skills = await getMiniSkillStore().loadByProject(effectiveProjectId);
|
|
536
515
|
|
|
537
516
|
return generateKnowledgeBase({
|
package/src/cli/tui/index.ts
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memorix TUI entry point.
|
|
3
|
-
*
|
|
4
|
-
* Renders the Ink-based workbench in alternate screen buffer.
|
|
5
|
-
* All commands are now Ink-native — no interactive fallback needed.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { getCliVersion } from '../version.js';
|
|
9
|
-
|
|
10
|
-
const ALT_ON = '\x1b[?1049h\x1b[?25l';
|
|
11
|
-
const ALT_OFF = '\x1b[?25h\x1b[?1049l';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Start the fullscreen Ink-based workbench.
|
|
15
|
-
* All views are Ink-native. No alternate-screen exit/re-enter loop.
|
|
16
|
-
*/
|
|
17
|
-
export async function startWorkbench(): Promise<void> {
|
|
18
|
-
const { render } = await import('ink');
|
|
19
|
-
const React = await import('react');
|
|
20
|
-
const { WorkbenchApp } = await import('./App.js');
|
|
21
|
-
|
|
22
|
-
process.stdout.write(ALT_ON);
|
|
23
|
-
|
|
24
|
-
const app = React.createElement(WorkbenchApp, {
|
|
25
|
-
version: getCliVersion(),
|
|
26
|
-
onExitForInteractive: () => {
|
|
27
|
-
// No-op: all commands are now Ink-native.
|
|
28
|
-
// Kept for interface compatibility but never called.
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const instance = render(app, { exitOnCtrlC: false });
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
await instance.waitUntilExit();
|
|
36
|
-
} catch {
|
|
37
|
-
// Ignore unmount-triggered exits.
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
process.stdout.write(ALT_OFF);
|
|
41
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Memorix TUI entry point.
|
|
3
|
+
*
|
|
4
|
+
* Renders the Ink-based workbench in alternate screen buffer.
|
|
5
|
+
* All commands are now Ink-native — no interactive fallback needed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { getCliVersion } from '../version.js';
|
|
9
|
+
|
|
10
|
+
const ALT_ON = '\x1b[?1049h\x1b[?25l';
|
|
11
|
+
const ALT_OFF = '\x1b[?25h\x1b[?1049l';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Start the fullscreen Ink-based workbench.
|
|
15
|
+
* All views are Ink-native. No alternate-screen exit/re-enter loop.
|
|
16
|
+
*/
|
|
17
|
+
export async function startWorkbench(): Promise<void> {
|
|
18
|
+
const { render } = await import('ink');
|
|
19
|
+
const React = await import('react');
|
|
20
|
+
const { WorkbenchApp } = await import('./App.js');
|
|
21
|
+
|
|
22
|
+
process.stdout.write(ALT_ON);
|
|
23
|
+
|
|
24
|
+
const app = React.createElement(WorkbenchApp, {
|
|
25
|
+
version: getCliVersion(),
|
|
26
|
+
onExitForInteractive: () => {
|
|
27
|
+
// No-op: all commands are now Ink-native.
|
|
28
|
+
// Kept for interface compatibility but never called.
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const instance = render(app, { exitOnCtrlC: false });
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
await instance.waitUntilExit();
|
|
36
|
+
} catch {
|
|
37
|
+
// Ignore unmount-triggered exits.
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process.stdout.write(ALT_OFF);
|
|
41
|
+
}
|