mu-harness 0.16.20 → 0.16.22
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/esm/tui/chat/ChatApp.js
CHANGED
|
@@ -717,6 +717,8 @@ export class ChatApp {
|
|
|
717
717
|
return true;
|
|
718
718
|
}
|
|
719
719
|
deleteMention() {
|
|
720
|
+
if (this.pickerMention !== undefined)
|
|
721
|
+
return false;
|
|
720
722
|
const value = this.editor.getValue();
|
|
721
723
|
const cursor = this.editor.cursorPos;
|
|
722
724
|
const re = /@[^\s]+/g;
|
|
@@ -1159,7 +1161,7 @@ export class ChatApp {
|
|
|
1159
1161
|
children.push(listView(rows, this.paletteCursor, this.theme()));
|
|
1160
1162
|
}
|
|
1161
1163
|
else if (this.pickerVisible()) {
|
|
1162
|
-
const rows = this.pickerRanked.map((c) => ({ left: c.label, right: c.kind === '
|
|
1164
|
+
const rows = this.pickerRanked.map((c) => ({ left: c.label, right: c.kind === 'file' ? '' : c.kind }));
|
|
1163
1165
|
children.push(listView(rows, this.pickerCursor, this.theme()));
|
|
1164
1166
|
}
|
|
1165
1167
|
const waiting = this.waitingView();
|
package/esm/tui/chat/picker.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface Candidate {
|
|
2
2
|
label: string;
|
|
3
3
|
insert: string;
|
|
4
|
-
kind: 'file' | 'agent';
|
|
4
|
+
kind: 'file' | 'dir' | 'agent';
|
|
5
5
|
}
|
|
6
6
|
export declare function collectCandidates(cwd: string, agentNames: string[]): Candidate[];
|
|
7
7
|
export declare function rank(query: string, candidates: Candidate[], limit?: number): Candidate[];
|
package/esm/tui/chat/picker.js
CHANGED
|
@@ -36,9 +36,10 @@ function gitFiles(cwd) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
function walk(cwd) {
|
|
39
|
-
const
|
|
39
|
+
const files = [];
|
|
40
|
+
const dirs = [];
|
|
40
41
|
const stack = [{ dir: cwd, depth: 0 }];
|
|
41
|
-
while (stack.length > 0 &&
|
|
42
|
+
while (stack.length > 0 && files.length < MAX_ENTRIES) {
|
|
42
43
|
const { dir, depth } = stack.pop();
|
|
43
44
|
let entries;
|
|
44
45
|
try {
|
|
@@ -61,23 +62,34 @@ function walk(cwd) {
|
|
|
61
62
|
continue;
|
|
62
63
|
}
|
|
63
64
|
if (isDir) {
|
|
65
|
+
dirs.push(relative(cwd, full));
|
|
64
66
|
if (depth < MAX_DEPTH)
|
|
65
67
|
stack.push({ dir: full, depth: depth + 1 });
|
|
66
68
|
}
|
|
67
69
|
else {
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
+
files.push(relative(cwd, full));
|
|
71
|
+
if (files.length >= MAX_ENTRIES)
|
|
70
72
|
break;
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
|
-
return
|
|
76
|
+
return { files: files.sort(), dirs: dirs.sort() };
|
|
75
77
|
}
|
|
76
78
|
export function collectCandidates(cwd, agentNames) {
|
|
77
|
-
const paths = gitFiles(cwd) ?? walk(cwd);
|
|
78
79
|
const agents = agentNames.map((name) => ({ label: `@${name}`, insert: name, kind: 'agent' }));
|
|
80
|
+
const tracked = gitFiles(cwd);
|
|
81
|
+
const walked = walk(cwd);
|
|
82
|
+
const paths = tracked ?? walked.files;
|
|
83
|
+
const dirs = new Set(walked.dirs);
|
|
84
|
+
for (const path of paths) {
|
|
85
|
+
for (let i = 0; i < path.length; i++) {
|
|
86
|
+
if (path[i] === '/' || path[i] === '\\')
|
|
87
|
+
dirs.add(path.slice(0, i));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const dirCandidates = [...dirs].map((path) => ({ label: `${path}/`, insert: `${path}/`, kind: 'dir' }));
|
|
79
91
|
const files = paths.map((path) => ({ label: path, insert: path, kind: 'file' }));
|
|
80
|
-
return [...agents, ...files];
|
|
92
|
+
return [...agents, ...dirCandidates, ...files];
|
|
81
93
|
}
|
|
82
94
|
function isBoundary(target, i) {
|
|
83
95
|
if (i === 0)
|
|
@@ -119,8 +131,9 @@ function fuzzyScore(query, target) {
|
|
|
119
131
|
return total;
|
|
120
132
|
}
|
|
121
133
|
function basename(path) {
|
|
122
|
-
const
|
|
123
|
-
|
|
134
|
+
const p = path.endsWith('/') || path.endsWith('\\') ? path.slice(0, -1) : path;
|
|
135
|
+
const cut = Math.max(p.lastIndexOf('/'), p.lastIndexOf('\\'));
|
|
136
|
+
return cut === -1 ? p : p.slice(cut + 1);
|
|
124
137
|
}
|
|
125
138
|
function score(query, candidate) {
|
|
126
139
|
if (query.length === 0)
|
|
@@ -129,7 +142,7 @@ function score(query, candidate) {
|
|
|
129
142
|
if (pathScore === undefined)
|
|
130
143
|
return undefined;
|
|
131
144
|
let total = pathScore;
|
|
132
|
-
if (candidate.kind === 'file') {
|
|
145
|
+
if (candidate.kind === 'file' || candidate.kind === 'dir') {
|
|
133
146
|
const base = basename(candidate.label);
|
|
134
147
|
const baseScore = fuzzyScore(query, base);
|
|
135
148
|
if (baseScore !== undefined) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mu-harness",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.22",
|
|
4
4
|
"description": "Agent harness: createHarness wires mu-core into a host — XDG paths, model registry, plugins, disk-loaded agents & skills, sub-agents, sessions (JSONL + SQLite catalog), slash commands, permission/approval hooks, an optional scheduler, and a composable TUI chat app",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./script/index.js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"@swc/wasm-typescript": "^1.15.0",
|
|
24
24
|
"cli-highlight": "^2.1.11",
|
|
25
25
|
"croner": "^9.0.0",
|
|
26
|
-
"mu-core": "^0.16.
|
|
27
|
-
"mu-tui": "^0.16.
|
|
26
|
+
"mu-core": "^0.16.22",
|
|
27
|
+
"mu-tui": "^0.16.22"
|
|
28
28
|
},
|
|
29
29
|
"_generatedBy": "dnt@dev",
|
|
30
30
|
"types": "./esm/index.d.ts"
|
|
@@ -720,6 +720,8 @@ class ChatApp {
|
|
|
720
720
|
return true;
|
|
721
721
|
}
|
|
722
722
|
deleteMention() {
|
|
723
|
+
if (this.pickerMention !== undefined)
|
|
724
|
+
return false;
|
|
723
725
|
const value = this.editor.getValue();
|
|
724
726
|
const cursor = this.editor.cursorPos;
|
|
725
727
|
const re = /@[^\s]+/g;
|
|
@@ -1162,7 +1164,7 @@ class ChatApp {
|
|
|
1162
1164
|
children.push(listView(rows, this.paletteCursor, this.theme()));
|
|
1163
1165
|
}
|
|
1164
1166
|
else if (this.pickerVisible()) {
|
|
1165
|
-
const rows = this.pickerRanked.map((c) => ({ left: c.label, right: c.kind === '
|
|
1167
|
+
const rows = this.pickerRanked.map((c) => ({ left: c.label, right: c.kind === 'file' ? '' : c.kind }));
|
|
1166
1168
|
children.push(listView(rows, this.pickerCursor, this.theme()));
|
|
1167
1169
|
}
|
|
1168
1170
|
const waiting = this.waitingView();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface Candidate {
|
|
2
2
|
label: string;
|
|
3
3
|
insert: string;
|
|
4
|
-
kind: 'file' | 'agent';
|
|
4
|
+
kind: 'file' | 'dir' | 'agent';
|
|
5
5
|
}
|
|
6
6
|
export declare function collectCandidates(cwd: string, agentNames: string[]): Candidate[];
|
|
7
7
|
export declare function rank(query: string, candidates: Candidate[], limit?: number): Candidate[];
|
|
@@ -41,9 +41,10 @@ function gitFiles(cwd) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
function walk(cwd) {
|
|
44
|
-
const
|
|
44
|
+
const files = [];
|
|
45
|
+
const dirs = [];
|
|
45
46
|
const stack = [{ dir: cwd, depth: 0 }];
|
|
46
|
-
while (stack.length > 0 &&
|
|
47
|
+
while (stack.length > 0 && files.length < MAX_ENTRIES) {
|
|
47
48
|
const { dir, depth } = stack.pop();
|
|
48
49
|
let entries;
|
|
49
50
|
try {
|
|
@@ -66,23 +67,34 @@ function walk(cwd) {
|
|
|
66
67
|
continue;
|
|
67
68
|
}
|
|
68
69
|
if (isDir) {
|
|
70
|
+
dirs.push((0, node_path_1.relative)(cwd, full));
|
|
69
71
|
if (depth < MAX_DEPTH)
|
|
70
72
|
stack.push({ dir: full, depth: depth + 1 });
|
|
71
73
|
}
|
|
72
74
|
else {
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
+
files.push((0, node_path_1.relative)(cwd, full));
|
|
76
|
+
if (files.length >= MAX_ENTRIES)
|
|
75
77
|
break;
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
|
-
return
|
|
81
|
+
return { files: files.sort(), dirs: dirs.sort() };
|
|
80
82
|
}
|
|
81
83
|
function collectCandidates(cwd, agentNames) {
|
|
82
|
-
const paths = gitFiles(cwd) ?? walk(cwd);
|
|
83
84
|
const agents = agentNames.map((name) => ({ label: `@${name}`, insert: name, kind: 'agent' }));
|
|
85
|
+
const tracked = gitFiles(cwd);
|
|
86
|
+
const walked = walk(cwd);
|
|
87
|
+
const paths = tracked ?? walked.files;
|
|
88
|
+
const dirs = new Set(walked.dirs);
|
|
89
|
+
for (const path of paths) {
|
|
90
|
+
for (let i = 0; i < path.length; i++) {
|
|
91
|
+
if (path[i] === '/' || path[i] === '\\')
|
|
92
|
+
dirs.add(path.slice(0, i));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const dirCandidates = [...dirs].map((path) => ({ label: `${path}/`, insert: `${path}/`, kind: 'dir' }));
|
|
84
96
|
const files = paths.map((path) => ({ label: path, insert: path, kind: 'file' }));
|
|
85
|
-
return [...agents, ...files];
|
|
97
|
+
return [...agents, ...dirCandidates, ...files];
|
|
86
98
|
}
|
|
87
99
|
function isBoundary(target, i) {
|
|
88
100
|
if (i === 0)
|
|
@@ -124,8 +136,9 @@ function fuzzyScore(query, target) {
|
|
|
124
136
|
return total;
|
|
125
137
|
}
|
|
126
138
|
function basename(path) {
|
|
127
|
-
const
|
|
128
|
-
|
|
139
|
+
const p = path.endsWith('/') || path.endsWith('\\') ? path.slice(0, -1) : path;
|
|
140
|
+
const cut = Math.max(p.lastIndexOf('/'), p.lastIndexOf('\\'));
|
|
141
|
+
return cut === -1 ? p : p.slice(cut + 1);
|
|
129
142
|
}
|
|
130
143
|
function score(query, candidate) {
|
|
131
144
|
if (query.length === 0)
|
|
@@ -134,7 +147,7 @@ function score(query, candidate) {
|
|
|
134
147
|
if (pathScore === undefined)
|
|
135
148
|
return undefined;
|
|
136
149
|
let total = pathScore;
|
|
137
|
-
if (candidate.kind === 'file') {
|
|
150
|
+
if (candidate.kind === 'file' || candidate.kind === 'dir') {
|
|
138
151
|
const base = basename(candidate.label);
|
|
139
152
|
const baseScore = fuzzyScore(query, base);
|
|
140
153
|
if (baseScore !== undefined) {
|