@mrclrchtr/supi-debug 2.6.1 → 2.8.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 +1 -1
- package/node_modules/@mrclrchtr/supi-core/README.md +1 -1
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +1 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +14 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +31 -14
- package/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
- package/package.json +2 -2
- package/src/debug.ts +6 -1
- package/src/status-log.ts +6 -2
package/README.md
CHANGED
|
@@ -114,7 +114,7 @@ Defaults come from the shared debug registry:
|
|
|
114
114
|
|
|
115
115
|
## Extra status logging
|
|
116
116
|
|
|
117
|
-
If `SUPI_LOG_STATUS` is enabled in the environment, the package emits a versioned SuPi load-status marker to stderr
|
|
117
|
+
If `SUPI_LOG_STATUS` is enabled in the environment, the package emits a versioned SuPi load-status marker to stderr during `resources_discover` (after session-start registrations) and appends the same payload as a session entry. The payload uses `phase: "resources_discover"`. Version 2 reports observed tool and command inventory only; external harnesses decide which resources they require.
|
|
118
118
|
|
|
119
119
|
## Source
|
|
120
120
|
|
|
@@ -43,7 +43,7 @@ Config file locations:
|
|
|
43
43
|
- `registerSettingsCommand(pi)` — register `/supi-settings` (used by `@mrclrchtr/supi-settings`)
|
|
44
44
|
- `openSettingsOverlay(pi, ctx)` — open the shared settings UI directly
|
|
45
45
|
- `createInputSubmenu()` — helper for simple text-entry submenus
|
|
46
|
-
- `createModelPickerSubmenu()` — helper for scoped model selection submenus
|
|
46
|
+
- `createModelPickerSubmenu()` — helper for scoped model selection submenus, with optional host-owned choices and `disabled` control
|
|
47
47
|
|
|
48
48
|
The built-in settings UI supports:
|
|
49
49
|
|
|
@@ -91,9 +91,23 @@ export interface StringListField extends BaseField {
|
|
|
91
91
|
kind: "stringList";
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/** One non-model choice shown before the scoped models in a model picker. */
|
|
95
|
+
export interface ModelPickerStaticOption {
|
|
96
|
+
/** Persisted value for the choice. */
|
|
97
|
+
value: string;
|
|
98
|
+
/** Human-readable picker label. */
|
|
99
|
+
label: string;
|
|
100
|
+
/** Optional explanation shown alongside the label. */
|
|
101
|
+
description?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
94
104
|
/** Model picker backed by the scoped model set. */
|
|
95
105
|
export interface ModelPickerField extends BaseField {
|
|
96
106
|
kind: "modelPicker";
|
|
107
|
+
/** Additional host-owned choices shown before scoped models. */
|
|
108
|
+
staticOptions?: ModelPickerStaticOption[];
|
|
109
|
+
/** Whether to include the built-in `disabled` choice. Defaults to true. */
|
|
110
|
+
includeDisabled?: boolean;
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
/**
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Text,
|
|
15
15
|
} from "@earendil-works/pi-tui";
|
|
16
16
|
import { getSelectableModels } from "../model-selection.ts";
|
|
17
|
+
import type { ModelPickerField } from "./settings-schema.ts";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Creates a pi-tui Input-backed submenu component with enter-to-confirm
|
|
@@ -57,25 +58,26 @@ export function createInputSubmenu(
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
|
-
* Creates a model picker submenu
|
|
61
|
+
* Creates a model picker submenu backed by the scoped model set.
|
|
62
|
+
*
|
|
63
|
+
* The built-in `disabled` choice remains enabled by default. Callers can add
|
|
64
|
+
* host-owned static choices or omit `disabled` through the field options.
|
|
61
65
|
*/
|
|
62
66
|
export function createModelPickerSubmenu(
|
|
63
67
|
currentValue: string,
|
|
64
68
|
done: (selectedValue?: string) => void,
|
|
65
69
|
ctx?: ExtensionContext,
|
|
70
|
+
options: Pick<ModelPickerField, "includeDisabled" | "staticOptions"> = {},
|
|
66
71
|
): {
|
|
67
72
|
render: (width: number) => string[];
|
|
68
73
|
invalidate: () => void;
|
|
69
74
|
handleInput: (data: string) => boolean;
|
|
70
75
|
} {
|
|
71
|
-
const items = buildModelItems(ctx);
|
|
72
|
-
const initialIndex =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
0,
|
|
77
|
-
items.findIndex((item) => item.value === currentValue),
|
|
78
|
-
);
|
|
76
|
+
const items = buildModelItems(ctx, options);
|
|
77
|
+
const initialIndex = Math.max(
|
|
78
|
+
0,
|
|
79
|
+
items.findIndex((item) => item.value === currentValue),
|
|
80
|
+
);
|
|
79
81
|
|
|
80
82
|
const container = new Container();
|
|
81
83
|
container.addChild(new Text(" Select model", 1, 0));
|
|
@@ -105,20 +107,35 @@ export function createModelPickerSubmenu(
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
/** Build
|
|
109
|
-
function buildModelItems(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
/** Build static choices followed by the selectable scoped models. */
|
|
111
|
+
function buildModelItems(
|
|
112
|
+
ctx: ExtensionContext | undefined,
|
|
113
|
+
options: Pick<ModelPickerField, "includeDisabled" | "staticOptions">,
|
|
114
|
+
): SelectItem[] {
|
|
115
|
+
const items: SelectItem[] = [];
|
|
116
|
+
const seen = new Set<string>();
|
|
117
|
+
for (const option of options.staticOptions ?? []) {
|
|
118
|
+
if (seen.has(option.value)) continue;
|
|
119
|
+
items.push({ ...option });
|
|
120
|
+
seen.add(option.value);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (options.includeDisabled !== false && !seen.has("disabled")) {
|
|
124
|
+
items.push({ value: "disabled", label: "disabled", description: "No model selected" });
|
|
125
|
+
seen.add("disabled");
|
|
126
|
+
}
|
|
127
|
+
|
|
113
128
|
if (!ctx) return items;
|
|
114
129
|
const models = getSelectableModels(ctx);
|
|
115
130
|
for (const model of models) {
|
|
131
|
+
if (seen.has(model.canonicalId)) continue;
|
|
116
132
|
const suffix = model.isCurrent ? " [current]" : "";
|
|
117
133
|
items.push({
|
|
118
134
|
value: model.canonicalId,
|
|
119
135
|
label: `${model.canonicalId}${suffix}`,
|
|
120
136
|
description: model.label !== model.canonicalId ? model.label : undefined,
|
|
121
137
|
});
|
|
138
|
+
seen.add(model.canonicalId);
|
|
122
139
|
}
|
|
123
140
|
return items;
|
|
124
141
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-debug",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "SuPi Debug extension — shared debug event inspection for SuPi extensions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@mrclrchtr/supi-core": "2.
|
|
34
|
+
"@mrclrchtr/supi-core": "2.8.0"
|
|
35
35
|
},
|
|
36
36
|
"bundledDependencies": [
|
|
37
37
|
"@mrclrchtr/supi-core"
|
package/src/debug.ts
CHANGED
|
@@ -279,7 +279,12 @@ export default function debugExtension(pi: ExtensionAPI) {
|
|
|
279
279
|
pi.on("session_start", async (_event, ctx) => {
|
|
280
280
|
clearDebugEvents();
|
|
281
281
|
applyDebugConfig(ctx.cwd);
|
|
282
|
-
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// Commands registered during every extension's session_start handler are
|
|
285
|
+
// available before resource discovery, so this inventory is load-order safe.
|
|
286
|
+
pi.on("resources_discover", async (_event, ctx) => {
|
|
287
|
+
maybeLogLoadStatus(pi, ctx.cwd, "resources_discover");
|
|
283
288
|
});
|
|
284
289
|
|
|
285
290
|
pi.registerCommand("supi-debug", {
|
package/src/status-log.ts
CHANGED
|
@@ -24,7 +24,11 @@ function statusLogEnabled(): boolean {
|
|
|
24
24
|
* stderr is captured by Harbor's `2>&1 | tee pi.txt` command for `--no-session`
|
|
25
25
|
* runs where session entries are not inspectable.
|
|
26
26
|
*/
|
|
27
|
-
export function maybeLogLoadStatus(
|
|
27
|
+
export function maybeLogLoadStatus(
|
|
28
|
+
pi: ExtensionAPI,
|
|
29
|
+
cwd: string,
|
|
30
|
+
phase: "session_start" | "resources_discover" = "session_start",
|
|
31
|
+
): void {
|
|
28
32
|
if (!statusLogEnabled()) return;
|
|
29
33
|
|
|
30
34
|
const allTools = typeof pi.getAllTools === "function" ? pi.getAllTools() : [];
|
|
@@ -37,7 +41,7 @@ export function maybeLogLoadStatus(pi: ExtensionAPI, cwd: string): void {
|
|
|
37
41
|
const status = {
|
|
38
42
|
type: "supi_status",
|
|
39
43
|
version: 2,
|
|
40
|
-
phase
|
|
44
|
+
phase,
|
|
41
45
|
cwd,
|
|
42
46
|
tools: {
|
|
43
47
|
registered: registeredToolNames,
|