@marifold/tui 0.67.0 → 0.70.5
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/dist/core/RemoteRuntime.d.ts +38 -0
- package/dist/core/RemoteRuntime.d.ts.map +1 -0
- package/dist/core/RemoteRuntime.js +131 -0
- package/dist/core/RemoteRuntime.js.map +1 -0
- package/dist/core/TuiRuntime.d.ts +11 -0
- package/dist/core/TuiRuntime.d.ts.map +1 -0
- package/dist/core/TuiRuntime.js +2 -0
- package/dist/core/TuiRuntime.js.map +1 -0
- package/dist/core/commands.d.ts +35 -36
- package/dist/core/commands.d.ts.map +1 -1
- package/dist/core/commands.js +50 -30
- package/dist/core/commands.js.map +1 -1
- package/dist/core/inputGrammar.d.ts +1 -1
- package/dist/runTui.d.ts +2 -0
- package/dist/runTui.d.ts.map +1 -1
- package/dist/runTui.js +18 -2
- package/dist/runTui.js.map +1 -1
- package/dist/ui/App.d.ts +6 -3
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +171 -79
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/Header.js +1 -1
- package/dist/ui/Header.js.map +1 -1
- package/dist/ui/InputBox.js +1 -1
- package/dist/ui/InputBox.js.map +1 -1
- package/dist/ui/StatusLine.js +2 -2
- package/dist/ui/StatusLine.js.map +1 -1
- package/dist/ui/WorkspaceShell.d.ts +14 -0
- package/dist/ui/WorkspaceShell.d.ts.map +1 -0
- package/dist/ui/WorkspaceShell.js +176 -0
- package/dist/ui/WorkspaceShell.js.map +1 -0
- package/package.json +3 -2
package/dist/runTui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runTui.js","sourceRoot":"","sources":["../src/runTui.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"runTui.js","sourceRoot":"","sources":["../src/runTui.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { TuiRuntime } from '../core/TuiRuntime.js';
|
|
1
2
|
import React from 'react';
|
|
2
|
-
import type { LoadedMarifoldConfig
|
|
3
|
+
import type { LoadedMarifoldConfig } from '@marifold/core';
|
|
3
4
|
import { type Mode, type TranscriptItemData } from '../core/appState.js';
|
|
4
5
|
export interface AppProps {
|
|
5
|
-
runtime:
|
|
6
|
+
runtime: TuiRuntime;
|
|
7
|
+
workspaceCommand?: (args: string) => Promise<string>;
|
|
8
|
+
deviceCommand?: (args: string) => Promise<string>;
|
|
6
9
|
loadedConfig: LoadedMarifoldConfig;
|
|
7
10
|
initial: {
|
|
8
11
|
profile: string;
|
|
@@ -19,5 +22,5 @@ export interface AppProps {
|
|
|
19
22
|
transcript?: TranscriptItemData[];
|
|
20
23
|
};
|
|
21
24
|
}
|
|
22
|
-
export declare function App({ runtime, loadedConfig, initial }: AppProps): React.ReactElement;
|
|
25
|
+
export declare function App({ runtime, loadedConfig, initial, workspaceCommand, deviceCommand }: AppProps): React.ReactElement;
|
|
23
26
|
//# sourceMappingURL=App.d.ts.map
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAU7F,OAAO,KAAK,EAKV,oBAAoB,
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAwE,MAAM,OAAO,CAAC;AAU7F,OAAO,KAAK,EAKV,oBAAoB,EAOrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAkC,KAAK,IAAI,EAAwC,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAkB/I,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,YAAY,EAAE,oBAAoB,CAAC;IACnC,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;KACnC,CAAC;CACH;AAcD,wBAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,EAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,CA6hCrH"}
|
package/dist/ui/App.js
CHANGED
|
@@ -21,7 +21,7 @@ import { useTerminalSize } from './useTerminalSize.js';
|
|
|
21
21
|
import { useResizing } from './useResizing.js';
|
|
22
22
|
import { copyToClipboard, errorText, runSummary, skillInvocation, unwrapPath } from './appHelpers.js';
|
|
23
23
|
const READ_FILE_CHAR_LIMIT = 100000;
|
|
24
|
-
export function App({ runtime, loadedConfig, initial }) {
|
|
24
|
+
export function App({ runtime, loadedConfig, initial, workspaceCommand, deviceCommand }) {
|
|
25
25
|
const { exit } = useApp();
|
|
26
26
|
const [state, dispatch] = useReducer(appReducer, createInitialState({
|
|
27
27
|
profile: initial.profile,
|
|
@@ -202,11 +202,11 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
202
202
|
resolve?.(submission);
|
|
203
203
|
}, []);
|
|
204
204
|
// "Always (allow <kind>)": persist to the active profile + grant for this session.
|
|
205
|
-
const persistApprovalKind = useCallback((kind) => {
|
|
205
|
+
const persistApprovalKind = useCallback(async (kind) => {
|
|
206
206
|
const profile = stateRef.current.profile;
|
|
207
207
|
sessionGrantsRef.current.add(kind);
|
|
208
208
|
try {
|
|
209
|
-
runtime.setProfileAgentApproval(profile, kind, 'allow');
|
|
209
|
+
await runtime.setProfileAgentApproval(profile, kind, 'allow');
|
|
210
210
|
notify(`Persisted approval: ${kind} = allow for ${profile}`, 'info');
|
|
211
211
|
}
|
|
212
212
|
catch (error) {
|
|
@@ -215,10 +215,10 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
215
215
|
}, [runtime, notify]);
|
|
216
216
|
// "Always (trust <folder>)" / `/trust-folder`: persist to the active profile +
|
|
217
217
|
// trust for this session (the running run can't re-read profile.toml).
|
|
218
|
-
const trustFolderForProfile = useCallback((folder) => {
|
|
218
|
+
const trustFolderForProfile = useCallback(async (folder) => {
|
|
219
219
|
const profile = stateRef.current.profile;
|
|
220
220
|
try {
|
|
221
|
-
const resolved = runtime.addProfileTrustedFolder(profile, folder);
|
|
221
|
+
const resolved = await runtime.addProfileTrustedFolder(profile, folder);
|
|
222
222
|
sessionTrustedFoldersRef.current.add(resolved);
|
|
223
223
|
notify(`Trusting ${resolved} for ${profile} (writes here won't ask).`, 'info');
|
|
224
224
|
}
|
|
@@ -250,6 +250,7 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
250
250
|
const runner = runtime.createAgentRunner(current.profile);
|
|
251
251
|
for await (const event of runner.run({
|
|
252
252
|
objective,
|
|
253
|
+
think: thinkRef.current,
|
|
253
254
|
profile: current.profile,
|
|
254
255
|
provider: current.provider,
|
|
255
256
|
model: current.model,
|
|
@@ -485,41 +486,47 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
485
486
|
const items = runtime.listProfiles().map(profile => ({ label: profile.name, value: profile.name }));
|
|
486
487
|
setOverlay({ type: 'profile', items });
|
|
487
488
|
}, [runtime]);
|
|
488
|
-
const openSkills = useCallback((scope = '
|
|
489
|
-
const profile = stateRef.current.profile;
|
|
489
|
+
const openSkills = useCallback((scope = 'global', requestedProfile) => {
|
|
490
|
+
const profile = requestedProfile ?? stateRef.current.profile;
|
|
491
|
+
if (scope === 'profile') {
|
|
492
|
+
try {
|
|
493
|
+
runtime.getProfile(profile);
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
notify(`Cannot open profile skills: ${errorText(error)}`, 'error');
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
490
500
|
const items = runtime.listSkills(profile, scope).map(skill => ({
|
|
491
501
|
label: skill.name,
|
|
492
502
|
value: skill.name,
|
|
493
503
|
hint: skill.description,
|
|
494
504
|
}));
|
|
495
|
-
// Cross-reference the other layer so global skills stay discoverable from
|
|
496
|
-
// the profile view (and vice versa).
|
|
497
505
|
const other = scope === 'global' ? 'profile' : 'global';
|
|
498
506
|
const otherCount = runtime.listSkills(profile, other).length;
|
|
499
|
-
const otherCmd = other === 'global' ? '/skills
|
|
500
|
-
const base = scope === 'global' ? 'Global skills' :
|
|
507
|
+
const otherCmd = other === 'global' ? '/skills' : `/skills --profile ${profile}`;
|
|
508
|
+
const base = scope === 'global' ? 'Global skills' : `Skills for profile ${profile}`;
|
|
501
509
|
const title = `${base} — Enter runs, Del removes${otherCount ? ` (+${otherCount} ${other}: ${otherCmd})` : ''}`;
|
|
502
510
|
const emptyHint = scope === 'global'
|
|
503
|
-
? ['/install-skill
|
|
504
|
-
: [
|
|
511
|
+
? ['/install-skill <path> installs a global skill (all profiles)']
|
|
512
|
+
: [`/install-skill --profile ${profile} <path> installs only for this profile`];
|
|
505
513
|
if (otherCount)
|
|
506
514
|
emptyHint.push(`${otherCount} ${other} skill(s) — ${otherCmd}`);
|
|
507
|
-
setOverlay({ type: 'skills', scope, items, title, emptyHint });
|
|
508
|
-
}, [runtime]);
|
|
509
|
-
const showSessions = useCallback(() => {
|
|
515
|
+
setOverlay({ type: 'skills', scope, ...(scope === 'profile' ? { profile } : {}), items, title, emptyHint });
|
|
516
|
+
}, [runtime, notify]);
|
|
517
|
+
const showSessions = useCallback(async () => {
|
|
510
518
|
if (stateRef.current.running) {
|
|
511
519
|
notify('Stop the running task before switching sessions.', 'warn');
|
|
512
520
|
return;
|
|
513
521
|
}
|
|
514
522
|
const currentSessionId = stateRef.current.sessionId;
|
|
515
|
-
const items = runtime
|
|
516
|
-
.listSessions(20, stateRef.current.profile, { order: 'recent' })
|
|
523
|
+
const items = (await runtime.listSessions(20, stateRef.current.profile, { order: 'recent' }))
|
|
517
524
|
.map(sessionItem.bind(null, currentSessionId));
|
|
518
525
|
setOverlay({ type: 'sessions', items });
|
|
519
526
|
}, [runtime, notify]);
|
|
520
527
|
const showHelp = useCallback(() => {
|
|
521
528
|
const lines = [
|
|
522
|
-
'Plain text → talk to the agent
|
|
529
|
+
'Plain text → talk to the agent.',
|
|
523
530
|
'$<skill> [args] → run a model-backed skill.',
|
|
524
531
|
'',
|
|
525
532
|
...listCommands().map(spec => `/${spec.name}${spec.aliases ? ` (/${spec.aliases.join(', /')})` : ''} — ${spec.summary}`),
|
|
@@ -532,7 +539,6 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
532
539
|
const session = s.sessionId ?? '(starts on your first message)';
|
|
533
540
|
const lines = [
|
|
534
541
|
`Profile: ${s.profile}`,
|
|
535
|
-
`Mode: ${s.mode}`,
|
|
536
542
|
`Provider: ${s.provider}`,
|
|
537
543
|
`Model: ${s.model}`,
|
|
538
544
|
`Thinking: ${thinkRef.current ? 'on' : 'off'}`,
|
|
@@ -570,9 +576,45 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
570
576
|
];
|
|
571
577
|
dispatch({ type: 'add_item', item: { kind: 'info', title: 'Permissions', lines } });
|
|
572
578
|
}, [runtime]);
|
|
573
|
-
const runDoctor = useCallback(() => {
|
|
579
|
+
const runDoctor = useCallback(async (fix = false) => {
|
|
574
580
|
const current = stateRef.current;
|
|
575
581
|
const provider = loadedConfig.config.providers[current.provider];
|
|
582
|
+
const instructionLines = [];
|
|
583
|
+
try {
|
|
584
|
+
let detail = runtime.getProfile(current.profile);
|
|
585
|
+
const needsFix = detail.instructionFormat === 'legacy'
|
|
586
|
+
|| detail.legacyInstructionFiles.length > 0;
|
|
587
|
+
if (fix && needsFix) {
|
|
588
|
+
const migration = await runtime.migrateProfileInstructions(current.profile);
|
|
589
|
+
detail = runtime.getProfile(current.profile);
|
|
590
|
+
instructionLines.push(`Instructions: ✓ ${migration.status === 'migrated' ? 'migrated' : 'cleaned'} to INSTRUCTIONS.md`);
|
|
591
|
+
if (migration.backupPath)
|
|
592
|
+
instructionLines.push(`Backup: ${migration.backupPath}`);
|
|
593
|
+
}
|
|
594
|
+
else if (detail.instructionFormat === 'unified' && detail.legacyInstructionFiles.length === 0) {
|
|
595
|
+
instructionLines.push('Instructions: ✓ INSTRUCTIONS.md');
|
|
596
|
+
}
|
|
597
|
+
else if (detail.instructionFormat === 'legacy') {
|
|
598
|
+
instructionLines.push(`Instructions: ⚠ legacy ${detail.legacyInstructionFiles.join(', ')}`);
|
|
599
|
+
instructionLines.push('Run /doctor --fix to back up and migrate them.');
|
|
600
|
+
}
|
|
601
|
+
else if (detail.instructionFormat === 'unified') {
|
|
602
|
+
instructionLines.push('Instructions: ⚠ unified with legacy files pending cleanup');
|
|
603
|
+
instructionLines.push('Run /doctor --fix to back up and archive them.');
|
|
604
|
+
}
|
|
605
|
+
else if (detail.instructionFormat === 'built-in') {
|
|
606
|
+
instructionLines.push('Instructions: ✓ built-in');
|
|
607
|
+
}
|
|
608
|
+
else if (detail.instructionFormat === 'json') {
|
|
609
|
+
instructionLines.push('Instructions: ⚠ legacy JSON profile (supported)');
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
instructionLines.push('Instructions: ⚠ missing');
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
catch (error) {
|
|
616
|
+
instructionLines.push(`Instructions: ✗ ${errorText(error)}`);
|
|
617
|
+
}
|
|
576
618
|
const lines = [
|
|
577
619
|
`Provider: ${current.provider}`,
|
|
578
620
|
`Model: ${current.model}`,
|
|
@@ -581,36 +623,34 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
581
623
|
`API key env: ${provider?.apiKeyEnv ?? '(none)'}${provider?.apiKeyEnv ? (process.env[provider.apiKeyEnv] ? ' ✓ set' : ' ✗ unset') : ''}`,
|
|
582
624
|
`Stored key: ${provider?.apiKey ? 'present' : 'none'}`,
|
|
583
625
|
'',
|
|
626
|
+
...instructionLines,
|
|
627
|
+
'',
|
|
584
628
|
'Run `marifold model` for full provider checks.',
|
|
585
629
|
];
|
|
586
630
|
dispatch({ type: 'add_item', item: { kind: 'info', title: 'Doctor', lines } });
|
|
587
631
|
}, [loadedConfig]);
|
|
588
632
|
const installSkill = useCallback((arg) => {
|
|
589
|
-
|
|
590
|
-
// current profile (profile skills shadow global ones).
|
|
591
|
-
const tokens = arg.trim().split(/\s+/).filter(Boolean);
|
|
592
|
-
const global = tokens.includes('--global');
|
|
593
|
-
const target = unwrapPath(tokens.filter(token => token !== '--global').join(' '));
|
|
594
|
-
const scope = global ? 'global' : 'profile';
|
|
595
|
-
const profile = stateRef.current.profile;
|
|
633
|
+
const parsed = parseSkillInstallArgs(arg);
|
|
596
634
|
const run = async () => {
|
|
597
635
|
try {
|
|
598
|
-
if (!target) {
|
|
599
|
-
notify('Usage: /install-skill [--
|
|
636
|
+
if (parsed.error || !parsed.target) {
|
|
637
|
+
notify(parsed.error ?? 'Usage: /install-skill [--profile <name>] <path|url>', 'warn');
|
|
600
638
|
return;
|
|
601
639
|
}
|
|
640
|
+
if (parsed.profile)
|
|
641
|
+
runtime.getProfile(parsed.profile);
|
|
602
642
|
let installed;
|
|
603
|
-
if (/^https?:\/\//i.test(target)) {
|
|
604
|
-
const response = await fetch(target);
|
|
643
|
+
if (/^https?:\/\//i.test(parsed.target)) {
|
|
644
|
+
const response = await fetch(parsed.target);
|
|
605
645
|
if (!response.ok)
|
|
606
|
-
throw new Error(`HTTP ${response.status} fetching ${target}`);
|
|
607
|
-
installed = runtime.installSkillFromText(await response.text(), scope, profile);
|
|
646
|
+
throw new Error(`HTTP ${response.status} fetching ${parsed.target}`);
|
|
647
|
+
installed = await runtime.installSkillFromText(await response.text(), parsed.scope, parsed.profile);
|
|
608
648
|
}
|
|
609
649
|
else {
|
|
610
|
-
installed = runtime.installSkillFromFile(path.resolve(expandHome(target)), scope, profile);
|
|
650
|
+
installed = await runtime.installSkillFromFile(path.resolve(expandHome(parsed.target)), parsed.scope, parsed.profile);
|
|
611
651
|
}
|
|
612
652
|
refreshSkills();
|
|
613
|
-
notify(`Installed skill: $${installed.name} (${
|
|
653
|
+
notify(`Installed skill: $${installed.name} (${parsed.profile ? `profile ${parsed.profile}` : 'global'})`, 'info');
|
|
614
654
|
}
|
|
615
655
|
catch (error) {
|
|
616
656
|
notify(`Install failed: ${errorText(error)}`, 'error');
|
|
@@ -647,16 +687,16 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
647
687
|
pendingImagesRef.current.push({ path: resolved });
|
|
648
688
|
notify(`Attached image #${pendingImagesRef.current.length}: ${resolved}`, 'info');
|
|
649
689
|
}, [notify]);
|
|
650
|
-
const remember = useCallback((text) => {
|
|
651
|
-
const result = runtime.rememberMemory(stateRef.current.profile, 'auto_short', text, stateRef.current.sessionId);
|
|
690
|
+
const remember = useCallback(async (text) => {
|
|
691
|
+
const result = await runtime.rememberMemory(stateRef.current.profile, 'auto_short', text, stateRef.current.sessionId);
|
|
652
692
|
notify(`${result.created ? 'Remembered' : 'Already remembered'}: ${result.entry.id}`, 'info');
|
|
653
693
|
}, [runtime, notify]);
|
|
654
|
-
const forget = useCallback((query) => {
|
|
655
|
-
const result = runtime.forgetMemories(stateRef.current.profile, query);
|
|
694
|
+
const forget = useCallback(async (query) => {
|
|
695
|
+
const result = await runtime.forgetMemories(stateRef.current.profile, query);
|
|
656
696
|
notify(result.count === 0 ? 'No matching memories.' : `Forgot ${result.count} memory record(s).`, 'info');
|
|
657
697
|
}, [runtime, notify]);
|
|
658
|
-
const deleteMemory = useCallback((query) => {
|
|
659
|
-
const result = runtime.deleteMemories(stateRef.current.profile, query);
|
|
698
|
+
const deleteMemory = useCallback(async (query) => {
|
|
699
|
+
const result = await runtime.deleteMemories(stateRef.current.profile, query);
|
|
660
700
|
notify(result.count === 0 ? 'No matching memories.' : `Deleted ${result.count} memory record(s).`, 'info');
|
|
661
701
|
}, [runtime, notify]);
|
|
662
702
|
const steer = useCallback((text) => {
|
|
@@ -690,7 +730,7 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
690
730
|
model: settings.model,
|
|
691
731
|
maxContextTokens: settings.maxContextTokens ?? loadedConfig.config.default.maxContextTokens,
|
|
692
732
|
});
|
|
693
|
-
dispatch({ type: 'set_mode', mode:
|
|
733
|
+
dispatch({ type: 'set_mode', mode: 'agent' });
|
|
694
734
|
// Adopt the new profile's thinking default (bare setter — selectProfile
|
|
695
735
|
// emits its own notice; the wrapped ctx.setThink would add a spurious one).
|
|
696
736
|
setThink(settings.think);
|
|
@@ -698,7 +738,7 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
698
738
|
sessionGrantsRef.current.clear();
|
|
699
739
|
sessionTrustedFoldersRef.current.clear();
|
|
700
740
|
refreshSkills(settings.profile);
|
|
701
|
-
notify(`Switched to profile: ${settings.profile} · ${settings.provider}/${settings.model}
|
|
741
|
+
notify(`Switched to profile: ${settings.profile} · ${settings.provider}/${settings.model} (new session)`, 'info');
|
|
702
742
|
}
|
|
703
743
|
catch (error) {
|
|
704
744
|
notify(`Could not switch profile: ${errorText(error)}`, 'error');
|
|
@@ -707,21 +747,20 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
707
747
|
// CommandContext bound to the live handlers.
|
|
708
748
|
const commandContext = useMemo(() => ({
|
|
709
749
|
notify,
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
},
|
|
750
|
+
workspace: args => { if (stateRef.current.running) {
|
|
751
|
+
notify('Stop the running task before switching workspaces.', 'warn');
|
|
752
|
+
return;
|
|
753
|
+
} if (!workspaceCommand) {
|
|
754
|
+
notify('Start marifold service before using workspaces.', 'warn');
|
|
755
|
+
return;
|
|
756
|
+
} void workspaceCommand(args).then(message => notify(message, 'info')).catch(error => notify(errorText(error), 'error')); },
|
|
757
|
+
device: args => { if (stateRef.current.running) {
|
|
758
|
+
notify('Execution device is fixed for the active run.', 'warn');
|
|
759
|
+
return;
|
|
760
|
+
} if (!deviceCommand) {
|
|
761
|
+
notify('Join a workspace to choose another device.', 'warn');
|
|
762
|
+
return;
|
|
763
|
+
} void deviceCommand(args).then(message => notify(message, 'info')).catch(error => notify(errorText(error), 'error')); },
|
|
725
764
|
newSession: () => { dispatch({ type: 'new_session', sessionId: undefined }); notify('Started a new session.', 'info'); },
|
|
726
765
|
clear: () => dispatch({ type: 'clear' }),
|
|
727
766
|
stop,
|
|
@@ -770,9 +809,9 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
770
809
|
dispatch({ type: 'set_context_budget', maxContextTokens: tokens });
|
|
771
810
|
notify(tokens ? `Context budget set to ${tokens.toLocaleString()} tokens for this session.` : 'Compaction disabled for this session.', 'info');
|
|
772
811
|
},
|
|
773
|
-
setDefaultContextWindow: (tokens) => {
|
|
812
|
+
setDefaultContextWindow: async (tokens) => {
|
|
774
813
|
try {
|
|
775
|
-
const saved = runtime.setProfileMaxContextTokens(stateRef.current.profile, tokens);
|
|
814
|
+
const saved = await runtime.setProfileMaxContextTokens(stateRef.current.profile, tokens);
|
|
776
815
|
dispatch({ type: 'set_context_budget', maxContextTokens: saved });
|
|
777
816
|
notify(saved
|
|
778
817
|
? `Default context budget for ${stateRef.current.profile} set to ${saved.toLocaleString()} tokens (this and future sessions).`
|
|
@@ -803,7 +842,7 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
803
842
|
}), [
|
|
804
843
|
notify, stop, steer, exit, openModelPicker, openProfilePicker, selectProfile, openSkills,
|
|
805
844
|
showPermissions, showHelp, showStatus, copyLast, retryLast, showSessions, runDoctor, installSkill,
|
|
806
|
-
readFileCmd, setImage, remember, forget, deleteMemory, repaint, runtime, trustFolderForProfile, startTextRun,
|
|
845
|
+
readFileCmd, setImage, remember, forget, deleteMemory, repaint, runtime, trustFolderForProfile, startTextRun, workspaceCommand, deviceCommand,
|
|
807
846
|
]);
|
|
808
847
|
// --- Input routing -------------------------------------------------------
|
|
809
848
|
const handleSubmit = useCallback((raw, attachedImages = []) => {
|
|
@@ -909,28 +948,45 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
909
948
|
return _jsx(SelectList, { title: "Select profile", items: overlay.items, onSelect: selectProfile, onCancel: () => setOverlay(null), maxRows: overlayMaxRows });
|
|
910
949
|
}
|
|
911
950
|
if (overlay.type === 'sessions') {
|
|
912
|
-
return (_jsx(SelectList, { title: "Resume session", maxRows: overlayMaxRows, items: overlay.items, onSelect: value => {
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
951
|
+
return (_jsx(SelectList, { title: "Resume session", maxRows: overlayMaxRows, items: overlay.items, onSelect: async (value) => {
|
|
952
|
+
try {
|
|
953
|
+
setOverlay(null);
|
|
954
|
+
const detail = await runtime.getSession(value);
|
|
955
|
+
if (!detail) {
|
|
956
|
+
notify(`Session not found: ${value}`, 'error');
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
dispatch({ type: 'new_session', sessionId: detail.id });
|
|
960
|
+
for (const turn of detail.turns) {
|
|
961
|
+
dispatch({ type: 'add_item', item: { kind: turn.role === 'user' ? 'user' : 'assistant', text: turn.content } });
|
|
962
|
+
}
|
|
963
|
+
notify(`Resumed session ${detail.id.slice(0, 8)} — your next message continues it.`, 'info');
|
|
918
964
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
dispatch({ type: 'add_item', item: { kind: turn.role === 'user' ? 'user' : 'assistant', text: turn.content } });
|
|
965
|
+
catch (error) {
|
|
966
|
+
notify(errorText(error), 'error');
|
|
922
967
|
}
|
|
923
|
-
notify(`Resumed session ${detail.id.slice(0, 8)} — your next message continues it.`, 'info');
|
|
924
968
|
}, onCancel: () => setOverlay(null), emptyHint: ['No saved sessions for this profile yet.'] }));
|
|
925
969
|
}
|
|
926
|
-
// skills (
|
|
970
|
+
// skills (global by default, or explicitly scoped to one profile)
|
|
927
971
|
if (overlay.type === 'skills') {
|
|
928
972
|
const scope = overlay.scope;
|
|
929
|
-
return (_jsx(SelectList, { title: overlay.title, maxRows: overlayMaxRows, items: overlay.items, emptyHint: overlay.emptyHint, onSelect: value => {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
973
|
+
return (_jsx(SelectList, { title: overlay.title, maxRows: overlayMaxRows, items: overlay.items, emptyHint: overlay.emptyHint, onSelect: value => {
|
|
974
|
+
setOverlay(null);
|
|
975
|
+
if (overlay.profile && overlay.profile !== stateRef.current.profile) {
|
|
976
|
+
notify(`Switch to profile ${overlay.profile} to run $${value}.`, 'warn');
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
runSkill(value, []);
|
|
980
|
+
}, onCancel: () => setOverlay(null), onDelete: async (value) => {
|
|
981
|
+
try {
|
|
982
|
+
await runtime.removeSkill(value, overlay.profile, scope);
|
|
983
|
+
refreshSkills();
|
|
984
|
+
notify(`Removed ${overlay.profile ? `profile ${overlay.profile}` : 'global'} skill: $${value}`, 'info');
|
|
985
|
+
openSkills(scope, overlay.profile);
|
|
986
|
+
}
|
|
987
|
+
catch (error) {
|
|
988
|
+
notify(errorText(error), 'error');
|
|
989
|
+
}
|
|
934
990
|
} }));
|
|
935
991
|
}
|
|
936
992
|
return null;
|
|
@@ -958,7 +1014,43 @@ export function App({ runtime, loadedConfig, initial }) {
|
|
|
958
1014
|
const prev = staticItems[index - 1];
|
|
959
1015
|
const prevKind = prev && 'kind' in prev ? prev.kind : 'banner';
|
|
960
1016
|
return (_jsx(Box, { paddingX: 1, marginTop: topGap(item.kind, prevKind), children: _jsx(TranscriptRow, { item: item }) }, item.id));
|
|
961
|
-
} }, staticEpoch), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [!resizing && liveItem ? (_jsx(Box, { paddingX: 1, children: _jsx(TranscriptRow, { item: liveItem }) })) : null, !resizing && state.running ? (_jsx(RunStatus, { startedAt: runStartedAt.current, activity: state.activity, think: think, steeringQueued: steeringCount })) : null, activeOverlay ?? (_jsx(InputBox, { onSubmit: handleSubmit, onInterrupt: handleInterrupt, history: history, commands: commandItems, skills: skillItems, resizing: resizing, placeholder: pendingSkill ? `value for ${pendingSkill.missing[pendingSkill.index]}` : planNext ? 'planned · your next message will be planned step-by-step' :
|
|
1017
|
+
} }, staticEpoch), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [!resizing && liveItem ? (_jsx(Box, { paddingX: 1, children: _jsx(TranscriptRow, { item: liveItem }) })) : null, !resizing && state.running ? (_jsx(RunStatus, { startedAt: runStartedAt.current, activity: state.activity, think: think, steeringQueued: steeringCount })) : null, activeOverlay ?? (_jsx(InputBox, { onSubmit: handleSubmit, onInterrupt: handleInterrupt, history: history, commands: commandItems, skills: skillItems, resizing: resizing, placeholder: pendingSkill ? `value for ${pendingSkill.missing[pendingSkill.index]}` : planNext ? 'planned · your next message will be planned step-by-step' : 'message the agent · /help' })), !resizing ? _jsx(StatusLine, { state: state }) : null] })] }));
|
|
1018
|
+
}
|
|
1019
|
+
function parseSkillInstallArgs(arg) {
|
|
1020
|
+
const tokens = arg.trim().split(/\s+/).filter(Boolean);
|
|
1021
|
+
const remaining = [];
|
|
1022
|
+
let profile;
|
|
1023
|
+
let explicitGlobal = false;
|
|
1024
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
1025
|
+
const token = tokens[index];
|
|
1026
|
+
if (token === '--global' || token === '-g') {
|
|
1027
|
+
explicitGlobal = true;
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
if (token === '--profile') {
|
|
1031
|
+
const value = tokens[index + 1];
|
|
1032
|
+
if (!value || value.startsWith('-')) {
|
|
1033
|
+
return { scope: 'global', error: 'Usage: /install-skill --profile <name> <path|url>' };
|
|
1034
|
+
}
|
|
1035
|
+
if (profile !== undefined) {
|
|
1036
|
+
return { scope: 'global', error: 'Specify --profile only once.' };
|
|
1037
|
+
}
|
|
1038
|
+
if (!/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
1039
|
+
return { scope: 'global', error: `Invalid profile name: ${value}` };
|
|
1040
|
+
}
|
|
1041
|
+
profile = value;
|
|
1042
|
+
index += 1;
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
1045
|
+
remaining.push(token);
|
|
1046
|
+
}
|
|
1047
|
+
if (explicitGlobal && profile) {
|
|
1048
|
+
return { scope: 'global', error: 'Use either --profile <name> or --global, not both.' };
|
|
1049
|
+
}
|
|
1050
|
+
const target = unwrapPath(remaining.join(' '));
|
|
1051
|
+
return profile
|
|
1052
|
+
? { scope: 'profile', profile, ...(target ? { target } : {}) }
|
|
1053
|
+
: { scope: 'global', ...(target ? { target } : {}) };
|
|
962
1054
|
}
|
|
963
1055
|
const BANNER_ID = '__banner__';
|
|
964
1056
|
function sessionItem(currentSessionId, session) {
|