@aiwayds/dsh-tui-pi 0.4.3 → 0.5.0
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 +270 -420
- package/README.zh.md +306 -0
- package/lib/commands.d.ts +12 -0
- package/lib/commands.js +62 -9
- package/lib/commands.js.map +1 -1
- package/lib/index.js +104 -5
- package/lib/index.js.map +1 -1
- package/lib/messages.d.ts +10 -2
- package/lib/messages.js +16 -5
- package/lib/messages.js.map +1 -1
- package/lib/selectors.d.ts +13 -0
- package/lib/selectors.js +48 -0
- package/lib/selectors.js.map +1 -1
- package/lib/session.d.ts +19 -0
- package/lib/session.js +81 -0
- package/lib/session.js.map +1 -1
- package/lib/settings.d.ts +18 -1
- package/lib/settings.js +343 -7
- package/lib/settings.js.map +1 -1
- package/lib/skills.d.ts +225 -0
- package/lib/skills.js +426 -0
- package/lib/skills.js.map +1 -0
- package/package.json +2 -1
package/lib/skills.js
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill invocation surface for the TUI.
|
|
3
|
+
*
|
|
4
|
+
* dsh exposes skills through the `ctx.skills` registry service (list / get /
|
|
5
|
+
* snapshot); skills are not commands, so they are absent from the command
|
|
6
|
+
* catalog. This module owns the pure logic behind two user-facing surfaces:
|
|
7
|
+
*
|
|
8
|
+
* 1. `/skill:<name>` completion + invocation. A skill is triggered the way
|
|
9
|
+
* the harness itself does it — the `/name ` gesture on a user message
|
|
10
|
+
* (packages/skill/tool-skill scans user messages in `agent/pre-step` and
|
|
11
|
+
* injects the rendered `<skill_content>`). The colon form `/skill:<name>`
|
|
12
|
+
* is a TUI convenience that is not a valid command name (parseCommand
|
|
13
|
+
* rejects `:`), so the TUI translates it to the native gesture
|
|
14
|
+
* (`/<name> `) and sends that through the normal prompt path.
|
|
15
|
+
* 2. The `/settings` Skills browser's enable/disable toggle, which edits the
|
|
16
|
+
* skill's own SKILL.md frontmatter (`disable-model-invocation` /
|
|
17
|
+
* `user-invocable`) — the same keys skill-filesystem parses, so the
|
|
18
|
+
* harness watcher picks the change up with no restart.
|
|
19
|
+
*
|
|
20
|
+
* The pure functions here are unit-tested against the built lib/; the
|
|
21
|
+
* frontmatter editing keeps this file's body and non-invocation keys intact.
|
|
22
|
+
*/
|
|
23
|
+
import { readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { dirname, join } from 'node:path';
|
|
25
|
+
/**
|
|
26
|
+
* Enabled state of a skill for a human user: visible and loadable on every
|
|
27
|
+
* surface (model catalog, `skill` tool, user gesture) only when both
|
|
28
|
+
* invocation controls allow it. Matches how skill-filesystem derives the
|
|
29
|
+
* defaults: an unset `disable-model-invocation` → modelInvocable true, an
|
|
30
|
+
* unset `user-invocable` → userInvocable true.
|
|
31
|
+
*/
|
|
32
|
+
export function skillEnabled(summary) {
|
|
33
|
+
return summary.invocation.modelInvocable && summary.invocation.userInvocable;
|
|
34
|
+
}
|
|
35
|
+
/** Only skills a user may explicitly invoke appear in the picker / completion. */
|
|
36
|
+
export function isUserSkill(summary) {
|
|
37
|
+
return summary.invocation.userInvocable;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Map a file-toggle read (readSkillToggle) onto the enabled boolean the
|
|
41
|
+
* settings browser displays: a skill is enabled when neither invocation lock
|
|
42
|
+
* is set. Mirrors `skillEnabled` for the on-disk-truth path — used on the
|
|
43
|
+
* toggle write-failure re-read so a stale in-memory summary never lies about
|
|
44
|
+
* the frontmatter on disk.
|
|
45
|
+
*/
|
|
46
|
+
export function skillToggleEnabled(toggle) {
|
|
47
|
+
return !toggle.disable && toggle.invoke;
|
|
48
|
+
}
|
|
49
|
+
const SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
50
|
+
/**
|
|
51
|
+
* Parse a `/skill`-shaped line into its requested action.
|
|
52
|
+
* @returns `{ kind: 'invoke', name }` for `/skill:<name>`; `{ kind: 'picker' }`
|
|
53
|
+
* for a bare `/skill`; `undefined` for anything else (not a skill command).
|
|
54
|
+
*/
|
|
55
|
+
export function parseSkillCommand(line) {
|
|
56
|
+
const m = /^\/skill(?::(\S+))?\s*$/.exec(line.trim());
|
|
57
|
+
if (m === null)
|
|
58
|
+
return undefined;
|
|
59
|
+
const name = m[1];
|
|
60
|
+
if (name === undefined || name === '')
|
|
61
|
+
return { kind: 'picker' };
|
|
62
|
+
// The public skill-name grammar is kebab-case; anything else (a space, a
|
|
63
|
+
// second colon, an underscore) is malformed for a direct invocation.
|
|
64
|
+
if (!SKILL_NAME_RE.test(name))
|
|
65
|
+
return undefined;
|
|
66
|
+
return { kind: 'invoke', name };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The harness-native gesture line the model-facing injection recognizes:
|
|
70
|
+
* `/name ` (a whitespace-bounded `/name` token — see tool-skill's
|
|
71
|
+
* SKILL_GESTURE). Skill names are validated kebab-case by construction.
|
|
72
|
+
*/
|
|
73
|
+
export function skillGesture(name) {
|
|
74
|
+
return `/${name} `;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extract the skill-completion query from a leading slash token, or `undefined`
|
|
78
|
+
* when this token is not a skill completion. The token may carry the leading
|
|
79
|
+
* `/` the cursor reads off the editor (the canonical shape from tokenAtCursor),
|
|
80
|
+
* so it is stripped before matching. The bare `skill` prefix yields an empty
|
|
81
|
+
* query (all user skills), `skill:<prefix>` filters by the text after the colon.
|
|
82
|
+
*/
|
|
83
|
+
export function skillCompletionQuery(token) {
|
|
84
|
+
const lower = token.toLowerCase().replace(/^\//, '');
|
|
85
|
+
if (lower === 'skill')
|
|
86
|
+
return '';
|
|
87
|
+
if (lower.startsWith('skill:'))
|
|
88
|
+
return lower.slice('skill:'.length);
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
/** The completion badge tag for each kind (fixed-width aligned, see badgeText). */
|
|
92
|
+
export const COMPLETION_BADGES = {
|
|
93
|
+
'explicit-skill': '[skill]',
|
|
94
|
+
'native-skill': '[skill]',
|
|
95
|
+
command: '[cmd]',
|
|
96
|
+
};
|
|
97
|
+
/** The widest badge tag — the alignment target every row's badge pads to. */
|
|
98
|
+
export const BADGE_WIDTH = Math.max(COMPLETION_BADGES['explicit-skill'].length, COMPLETION_BADGES.command.length);
|
|
99
|
+
/** The badge text of `kind`, right-padded to the common tag width. */
|
|
100
|
+
export function badgeText(kind) {
|
|
101
|
+
return COMPLETION_BADGES[kind].padEnd(BADGE_WIDTH);
|
|
102
|
+
}
|
|
103
|
+
/** The display label for one completion row: aligned badge + candidate value. */
|
|
104
|
+
export function completionLabel(kind, value) {
|
|
105
|
+
return `${badgeText(kind)} ${value}`;
|
|
106
|
+
}
|
|
107
|
+
/** Fixed width of the toggle state prefix in the settings Skills row. */
|
|
108
|
+
export const SKILL_STATE_WIDTH = 5;
|
|
109
|
+
/**
|
|
110
|
+
* The settings Skills-row label: a fixed-width toggle state in front, then the
|
|
111
|
+
* `[skill] <name>` completion row. Leading the row with the state (padded to a
|
|
112
|
+
* common width) keeps every skill name on the same column regardless of how
|
|
113
|
+
* long the state strings are — `'false'` is one column wider than `'true'`.
|
|
114
|
+
*/
|
|
115
|
+
export function skillSettingRowLabel(enabled, name) {
|
|
116
|
+
const state = enabled ? 'true' : 'false';
|
|
117
|
+
return `${state.padEnd(SKILL_STATE_WIDTH)} ${completionLabel('explicit-skill', name)}`;
|
|
118
|
+
}
|
|
119
|
+
/** Clamp a panel cursor into `[0, length)`; an empty list pins the cursor at 0. */
|
|
120
|
+
export function clampSkillCursor(cursor, length) {
|
|
121
|
+
if (length <= 0)
|
|
122
|
+
return 0;
|
|
123
|
+
if (cursor < 0)
|
|
124
|
+
return 0;
|
|
125
|
+
if (cursor >= length)
|
|
126
|
+
return length - 1;
|
|
127
|
+
return cursor;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The scroll offset that keeps `cursor` inside `[offset, offset + visibleRows)`
|
|
131
|
+
* for a list of `length` items. An empty list or zero visible rows returns 0.
|
|
132
|
+
* Pure helper so the scrolling logic is unit-testable without a live TUI.
|
|
133
|
+
*/
|
|
134
|
+
export function clampScrollOffset(cursor, visibleRows, length, currentOffset) {
|
|
135
|
+
if (length <= 0 || visibleRows <= 0)
|
|
136
|
+
return 0;
|
|
137
|
+
if (cursor < currentOffset)
|
|
138
|
+
return cursor;
|
|
139
|
+
if (cursor >= currentOffset + visibleRows)
|
|
140
|
+
return cursor - visibleRows + 1;
|
|
141
|
+
return currentOffset;
|
|
142
|
+
}
|
|
143
|
+
/** Fixed page size for the settings Skills panel paged navigation (PgUp/PgDn). */
|
|
144
|
+
export const SKILL_PAGE_SIZE = 10;
|
|
145
|
+
/**
|
|
146
|
+
* The next cursor for a `jump` from `cursor` over `length` rows, clamped by
|
|
147
|
+
* `clampSkillCursor`. `home` pins to the first row, `end` to the last; both
|
|
148
|
+
* are no-ops on an empty list. `pageSize` (PgUp/PgDn step) defaults to
|
|
149
|
+
* `SKILL_PAGE_SIZE`.
|
|
150
|
+
*/
|
|
151
|
+
export function skillJumpCursor(cursor, length, jump, pageSize = SKILL_PAGE_SIZE) {
|
|
152
|
+
switch (jump) {
|
|
153
|
+
case 'up':
|
|
154
|
+
return clampSkillCursor(cursor - 1, length);
|
|
155
|
+
case 'down':
|
|
156
|
+
return clampSkillCursor(cursor + 1, length);
|
|
157
|
+
case 'pageUp':
|
|
158
|
+
return clampSkillCursor(cursor - pageSize, length);
|
|
159
|
+
case 'pageDown':
|
|
160
|
+
return clampSkillCursor(cursor + pageSize, length);
|
|
161
|
+
case 'home':
|
|
162
|
+
return clampSkillCursor(0, length);
|
|
163
|
+
case 'end':
|
|
164
|
+
return clampSkillCursor(length - 1, length);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ------------------------------------------------------------------ filter --
|
|
168
|
+
/**
|
|
169
|
+
* Filter skill-panel rows by a case-insensitive prefix match on the skill name.
|
|
170
|
+
* Returns a new array (never mutates the input). An empty query returns all
|
|
171
|
+
* rows. Pure helper so the filtering logic is unit-testable without a live TUI.
|
|
172
|
+
*/
|
|
173
|
+
export function filterSkillRows(rows, query) {
|
|
174
|
+
if (query === '')
|
|
175
|
+
return [...rows];
|
|
176
|
+
const lower = query.toLowerCase();
|
|
177
|
+
return rows.filter(row => row.name.toLowerCase().startsWith(lower));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Detect a printable single-character input (ASCII visible, not DEL/0x7f).
|
|
181
|
+
* Returns `true` for characters that should accumulate into the filter query.
|
|
182
|
+
*/
|
|
183
|
+
export function isPrintableInput(data) {
|
|
184
|
+
return data.length === 1 && data.charCodeAt(0) >= 0x20 && data.charCodeAt(0) !== 0x7f;
|
|
185
|
+
}
|
|
186
|
+
/** Column width of the 1-based row index in the settings Skills panel. */
|
|
187
|
+
export const SKILL_INDEX_WIDTH = 3;
|
|
188
|
+
/**
|
|
189
|
+
* Plain-text layout contract for one Skills panel row: a cursor-marker column
|
|
190
|
+
* (`▸` selected / space otherwise), then a 1-based row index, then the
|
|
191
|
+
* fixed-width state + `[skill] <name>` row. The state appears exactly once,
|
|
192
|
+
* up front — the row never repeats it at the tail (the bug the custom render
|
|
193
|
+
* fixes). The component applies color per segment on top of this layout;
|
|
194
|
+
* tests assert the plain text.
|
|
195
|
+
*
|
|
196
|
+
* Prefix column widths: marker(2) + index(4) + state(6) + badge(8) = 20.
|
|
197
|
+
*/
|
|
198
|
+
export function skillPanelRowLine(selected, enabled, name, index) {
|
|
199
|
+
const marker = selected ? '▸' : ' ';
|
|
200
|
+
const idx = String(index).padStart(SKILL_INDEX_WIDTH);
|
|
201
|
+
return `${marker} ${idx} ${skillSettingRowLabel(enabled, name)}`;
|
|
202
|
+
}
|
|
203
|
+
/** The `kind` recorded on a completion item (`command` for unmarked rows). */
|
|
204
|
+
export function itemKind(item) {
|
|
205
|
+
const tagged = item;
|
|
206
|
+
return tagged.kind ?? 'command';
|
|
207
|
+
}
|
|
208
|
+
/** A skill completion row (native `/name` or explicit `/skill:<name>`). */
|
|
209
|
+
export function isSkillCompletionItem(item) {
|
|
210
|
+
const kind = itemKind(item);
|
|
211
|
+
return kind === 'native-skill' || kind === 'explicit-skill';
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The explicit `/skill:<name>` row completes a whole invocation — it must not
|
|
215
|
+
* gain the trailing-space separator a command/native skill gets.
|
|
216
|
+
*/
|
|
217
|
+
export function isExplicitSkillItem(item) {
|
|
218
|
+
return itemKind(item) === 'explicit-skill';
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The native display name used for prefix filtering and mixed-list sorting:
|
|
222
|
+
* the value after the leading `/`, with a `/skill:` form reduced to the name
|
|
223
|
+
* after the colon so an explicit row sorts under its real skill name rather
|
|
224
|
+
* than stacking in the `s` bucket.
|
|
225
|
+
*/
|
|
226
|
+
export function completionName(item) {
|
|
227
|
+
const value = item.value;
|
|
228
|
+
if (value.startsWith('/skill:'))
|
|
229
|
+
return value.slice('/skill:'.length);
|
|
230
|
+
return value.slice(1);
|
|
231
|
+
}
|
|
232
|
+
/** Sort completion rows by their native display name (stable, locale-aware). */
|
|
233
|
+
export function sortCompletionItems(items) {
|
|
234
|
+
return [...items].sort((a, b) => completionName(a).localeCompare(completionName(b)));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Merge command rows with the user skills' native `/name` rows into one
|
|
238
|
+
* mixed completion list (the generic `/` completion), each filtered by the
|
|
239
|
+
* query prefix and the combined set sorted by native display name. Extracted
|
|
240
|
+
* from the autocomplete provider so the interleave/filter/sort is unit-testable
|
|
241
|
+
* without a live CommandService.
|
|
242
|
+
*/
|
|
243
|
+
export function mergeMixedSkillItems(commandItems, nativeSkillItems, query) {
|
|
244
|
+
const filtered = [...commandItems, ...nativeSkillItems].filter(item => query === '' || completionName(item).toLowerCase().startsWith(query));
|
|
245
|
+
return sortCompletionItems(filtered);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Autocomplete items for the explicit `/skill:<name>` form: `value`/`label`
|
|
249
|
+
* are the full invocation (no argument), `description` is the skill's own
|
|
250
|
+
* routing line. Carries `kind: 'explicit-skill'` so applyCompletion omits the
|
|
251
|
+
* trailing-space separator (a completed `/skill:<name>` is a complete call —
|
|
252
|
+
* Enter submits it). Filtered by the prefix after `skill:`.
|
|
253
|
+
*/
|
|
254
|
+
export function buildSkillCompletionCandidates(skills, afterColon) {
|
|
255
|
+
const q = afterColon.toLowerCase();
|
|
256
|
+
return skills
|
|
257
|
+
.filter(skill => isUserSkill(skill) && (q === '' || skill.name.toLowerCase().startsWith(q)))
|
|
258
|
+
.map(skill => {
|
|
259
|
+
const value = `/skill:${skill.name}`;
|
|
260
|
+
return {
|
|
261
|
+
value,
|
|
262
|
+
label: completionLabel('explicit-skill', value),
|
|
263
|
+
description: skill.description,
|
|
264
|
+
kind: 'explicit-skill',
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Autocomplete items for a skill under its own native `/name`, for the generic
|
|
270
|
+
* `/` command list where commands and skills mix. Carries
|
|
271
|
+
* `kind: 'native-skill'` so applyCompletion adds the trailing-space separator
|
|
272
|
+
* like a command row (the native `/name ` is a valid command-shaped line that
|
|
273
|
+
* falls through to the harness skill gesture once submitted). Not
|
|
274
|
+
* prefix-filtered here — the caller filters the mixed list by query.
|
|
275
|
+
*/
|
|
276
|
+
export function buildNativeSkillCandidates(skills) {
|
|
277
|
+
return skills
|
|
278
|
+
.filter(isUserSkill)
|
|
279
|
+
.map(skill => {
|
|
280
|
+
const value = `/${skill.name}`;
|
|
281
|
+
return {
|
|
282
|
+
value,
|
|
283
|
+
label: completionLabel('native-skill', value),
|
|
284
|
+
description: skill.description,
|
|
285
|
+
kind: 'native-skill',
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
// ------------------------------------------------------------- frontmatter --
|
|
290
|
+
/**
|
|
291
|
+
* The frontmatter key transform for one toggle action. Disabling hides a skill
|
|
292
|
+
* from every surface: `disable-model-invocation: true` clears the model-facing
|
|
293
|
+
* catalog/tool and `user-invocable: false` clears the user gesture/picker.
|
|
294
|
+
* Enabling restores the defaults by removing both keys (skill-filesystem treats
|
|
295
|
+
* an absent key as permissive — a skill with neither key is fully enabled).
|
|
296
|
+
*/
|
|
297
|
+
export function skillDisableUpdates() {
|
|
298
|
+
return { 'disable-model-invocation': 'true', 'user-invocable': 'false' };
|
|
299
|
+
}
|
|
300
|
+
export function skillEnableUpdates() {
|
|
301
|
+
return { 'disable-model-invocation': null, 'user-invocable': null };
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Apply a set of frontmatter key writes/removals to a markdown file, keeping
|
|
305
|
+
* every other line and the body verbatim. Existing keys are rewritten in
|
|
306
|
+
* place; missing keys are inserted just before the closing fence; `null`
|
|
307
|
+
* removes the key's line. An absent opening or closing fence is an error.
|
|
308
|
+
* Returns an error message, or `undefined` on success (an empty diff still
|
|
309
|
+
* succeeds). The write is atomic (tmp + rename in the same directory) so the
|
|
310
|
+
* harness watcher never observes half a file.
|
|
311
|
+
*/
|
|
312
|
+
export function applySkillFrontmatter(path, updates) {
|
|
313
|
+
let text;
|
|
314
|
+
try {
|
|
315
|
+
text = readFileSync(path, 'utf8');
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return `cannot read skill file: ${path}`;
|
|
319
|
+
}
|
|
320
|
+
const eol = text.includes('\r\n') ? '\r\n' : '\n';
|
|
321
|
+
const lines = text.split(/\r?\n/);
|
|
322
|
+
// A YAML frontmatter block opens at line 0 and closes at the next `---`.
|
|
323
|
+
if (lines[0]?.trim() !== '---')
|
|
324
|
+
return 'missing frontmatter (file must start with `---`)';
|
|
325
|
+
let close = -1;
|
|
326
|
+
for (let i = 1; i < lines.length; i++) {
|
|
327
|
+
if (lines[i].trim() === '---') {
|
|
328
|
+
close = i;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (close < 0)
|
|
333
|
+
return 'missing closing frontmatter fence';
|
|
334
|
+
let changed = false;
|
|
335
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
336
|
+
const rendered = value === null ? null : `${key}: ${value}`;
|
|
337
|
+
let found = -1;
|
|
338
|
+
for (let i = 1; i < close; i++) {
|
|
339
|
+
// Match the key at the start of the line (hyphens included), then a colon.
|
|
340
|
+
if (lines[i].trimStart().startsWith(`${key}:`)) {
|
|
341
|
+
found = i;
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (found >= 0) {
|
|
346
|
+
if (rendered === null) {
|
|
347
|
+
lines.splice(found, 1);
|
|
348
|
+
close--;
|
|
349
|
+
changed = true;
|
|
350
|
+
}
|
|
351
|
+
else if (lines[found] !== rendered) {
|
|
352
|
+
lines[found] = rendered;
|
|
353
|
+
changed = true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else if (rendered !== null) {
|
|
357
|
+
lines.splice(close, 0, rendered);
|
|
358
|
+
close++;
|
|
359
|
+
changed = true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (!changed)
|
|
363
|
+
return undefined;
|
|
364
|
+
const out = lines.join(eol);
|
|
365
|
+
// Atomic replace in the same directory: write a sibling then rename over, so
|
|
366
|
+
// a crash or an early watcher event never sees a truncated frontmatter.
|
|
367
|
+
const pathBase = path.split('/').pop() ?? 'skill';
|
|
368
|
+
const tmp = join(dirname(path), `.${pathBase}.tmp-${process.pid}`);
|
|
369
|
+
try {
|
|
370
|
+
writeFileSync(tmp, out);
|
|
371
|
+
renameSync(tmp, path);
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
// A failed write/rename can leave the `.SKILL.md.tmp-<pid>` sibling behind;
|
|
375
|
+
// clean it up so a crash or an early watcher event never sees a stray file.
|
|
376
|
+
try {
|
|
377
|
+
rmSync(tmp, { force: true });
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// Best-effort — the original error is what we surface.
|
|
381
|
+
}
|
|
382
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
383
|
+
return `cannot write skill file: ${message}`;
|
|
384
|
+
}
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Read the frontmatter of a skill markdown file and report the current toggle
|
|
389
|
+
* values (`disable` = `disable-model-invocation: true`, `invoke` =
|
|
390
|
+
* `user-invocable` absent/true). Returns `undefined` when the file is
|
|
391
|
+
* unreadable or has no usable frontmatter (the caller degrades to the
|
|
392
|
+
* in-memory summary).
|
|
393
|
+
*/
|
|
394
|
+
export function readSkillToggle(path) {
|
|
395
|
+
let text;
|
|
396
|
+
try {
|
|
397
|
+
text = readFileSync(path, 'utf8');
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
const lines = text.split(/\r?\n/);
|
|
403
|
+
if (lines[0]?.trim() !== '---')
|
|
404
|
+
return undefined;
|
|
405
|
+
let close = -1;
|
|
406
|
+
for (let i = 1; i < lines.length; i++) {
|
|
407
|
+
if (lines[i].trim() === '---') {
|
|
408
|
+
close = i;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (close < 0)
|
|
413
|
+
return undefined;
|
|
414
|
+
let disable = false;
|
|
415
|
+
let invoke = true;
|
|
416
|
+
for (let i = 1; i < close; i++) {
|
|
417
|
+
if (lines[i].trimStart().startsWith('disable-model-invocation:')) {
|
|
418
|
+
disable = lines[i].includes('true');
|
|
419
|
+
}
|
|
420
|
+
else if (lines[i].trimStart().startsWith('user-invocable:')) {
|
|
421
|
+
invoke = !lines[i].includes('false');
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return { disable, invoke };
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiwayds/dsh-tui-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "pi-style terminal UI for DeepSeek Harness (dsh) — pi-tui look & feel, dsh slash commands, GitHub light/dark themes, powerline footer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@aiwayds/dsh-dcp": "latest",
|
|
35
|
+
"@aiwayds/dsh-subagent-registry": "latest",
|
|
35
36
|
"@earendil-works/pi-tui": "0.84.2"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|