@mirrowel/opencode-subagent-explorer 0.1.0-dev.1 → 0.1.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/dist/wizard.js +5 -5
- package/package.json +1 -1
- package/src/palette-category.ts +83 -83
package/dist/wizard.js
CHANGED
|
@@ -1571,10 +1571,10 @@ The host client does not expose session.list for this directory.`
|
|
|
1571
1571
|
}
|
|
1572
1572
|
}
|
|
1573
1573
|
export {
|
|
1574
|
-
|
|
1575
|
-
computeDialogRows,
|
|
1576
|
-
explorerRows,
|
|
1577
|
-
loadExplorerData,
|
|
1574
|
+
rowTitle,
|
|
1578
1575
|
mainMenu,
|
|
1579
|
-
|
|
1576
|
+
loadExplorerData,
|
|
1577
|
+
explorerRows,
|
|
1578
|
+
computeDialogRows,
|
|
1579
|
+
SubagentTreeDialog
|
|
1580
1580
|
};
|
package/package.json
CHANGED
package/src/palette-category.ts
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared palette category for Mirrowel OpenCode plugins loaded in the same
|
|
3
|
-
* session. Every family plugin declares its own label into a process-wide
|
|
4
|
-
* registry at TUI activation; a delayed reconciler joins all declared labels
|
|
5
|
-
* (alphabetical, deterministic) and writes the join into every registered
|
|
6
|
-
* command object, so the palette shows one combined section. A plugin loaded
|
|
7
|
-
* alone keeps its own name; third-party plugins never declare and stay out.
|
|
8
|
-
*
|
|
9
|
-
* Labels are defined only in each plugin's entry point - this module carries
|
|
10
|
-
* no per-plugin data. Keep the logic copies in sync across family repos.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const REGISTRY_KEY = Symbol.for("mirrowel.opencode.paletteCategory")
|
|
14
|
-
|
|
15
|
-
// v1 command objects group via `category`; v2 keymap commands use `group`.
|
|
16
|
-
// Stamping both keeps one registry meaningful on both hosts.
|
|
17
|
-
type CategorizedCommand = { category?: string; group?: string }
|
|
18
|
-
type RegistryEntry = { label: string; commands: CategorizedCommand[] }
|
|
19
|
-
type Registry = { entries: RegistryEntry[] }
|
|
20
|
-
|
|
21
|
-
function registry(): Registry {
|
|
22
|
-
const globals = globalThis as { [key: symbol]: Registry | undefined }
|
|
23
|
-
if (!globals[REGISTRY_KEY]) globals[REGISTRY_KEY] = { entries: [] }
|
|
24
|
-
return globals[REGISTRY_KEY]!
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function joinLabels(labels: string[]): string {
|
|
28
|
-
if (labels.length <= 1) return labels[0] ?? ""
|
|
29
|
-
return `${labels.slice(0, -1).join(", ")} & ${labels[labels.length - 1]!}`
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function joinedCategory(): string {
|
|
33
|
-
const labels = [...new Set(registry().entries.map((entry) => entry.label))].sort((a, b) => a.localeCompare(b))
|
|
34
|
-
return joinLabels(labels)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Declares this plugin's category label and attaches command objects whose
|
|
39
|
-
* `category` field is kept in sync. Returns the current join, so the very
|
|
40
|
-
* first registration already renders correctly even before reconcilers run.
|
|
41
|
-
*/
|
|
42
|
-
export function declarePaletteCategory(label: string, ...commands: CategorizedCommand[]): string {
|
|
43
|
-
const reg = registry()
|
|
44
|
-
let entry = reg.entries.find((item) => item.label === label)
|
|
45
|
-
if (!entry) {
|
|
46
|
-
entry = { label, commands: [] }
|
|
47
|
-
reg.entries.push(entry)
|
|
48
|
-
}
|
|
49
|
-
for (const command of commands) {
|
|
50
|
-
if (command && !entry.commands.includes(command)) entry.commands.push(command)
|
|
51
|
-
}
|
|
52
|
-
reconcilePaletteCategories()
|
|
53
|
-
return joinedCategory()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Live join for callback-style command registration (reads fresh each call). */
|
|
57
|
-
export function currentPaletteCategory(): string {
|
|
58
|
-
return joinedCategory()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** Writes the current join into every declared command (idempotent). */
|
|
62
|
-
export function reconcilePaletteCategories(): void {
|
|
63
|
-
const category = joinedCategory()
|
|
64
|
-
for (const entry of registry().entries) {
|
|
65
|
-
for (const command of entry.commands) {
|
|
66
|
-
command.category = category
|
|
67
|
-
command.group = category
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Delayed reconciles so later-activating siblings join before the user opens the palette. */
|
|
73
|
-
export function schedulePaletteReconcile(delaysMs: readonly number[] = [2000, 6000]): void {
|
|
74
|
-
for (const delay of delaysMs) {
|
|
75
|
-
const timer = setTimeout(() => reconcilePaletteCategories(), delay)
|
|
76
|
-
;(timer as { unref?: () => void }).unref?.()
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Tests only: drop all declarations. */
|
|
81
|
-
export function __resetPaletteRegistry(): void {
|
|
82
|
-
;(globalThis as { [key: symbol]: Registry | undefined })[REGISTRY_KEY] = undefined
|
|
83
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared palette category for Mirrowel OpenCode plugins loaded in the same
|
|
3
|
+
* session. Every family plugin declares its own label into a process-wide
|
|
4
|
+
* registry at TUI activation; a delayed reconciler joins all declared labels
|
|
5
|
+
* (alphabetical, deterministic) and writes the join into every registered
|
|
6
|
+
* command object, so the palette shows one combined section. A plugin loaded
|
|
7
|
+
* alone keeps its own name; third-party plugins never declare and stay out.
|
|
8
|
+
*
|
|
9
|
+
* Labels are defined only in each plugin's entry point - this module carries
|
|
10
|
+
* no per-plugin data. Keep the logic copies in sync across family repos.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const REGISTRY_KEY = Symbol.for("mirrowel.opencode.paletteCategory")
|
|
14
|
+
|
|
15
|
+
// v1 command objects group via `category`; v2 keymap commands use `group`.
|
|
16
|
+
// Stamping both keeps one registry meaningful on both hosts.
|
|
17
|
+
type CategorizedCommand = { category?: string; group?: string }
|
|
18
|
+
type RegistryEntry = { label: string; commands: CategorizedCommand[] }
|
|
19
|
+
type Registry = { entries: RegistryEntry[] }
|
|
20
|
+
|
|
21
|
+
function registry(): Registry {
|
|
22
|
+
const globals = globalThis as { [key: symbol]: Registry | undefined }
|
|
23
|
+
if (!globals[REGISTRY_KEY]) globals[REGISTRY_KEY] = { entries: [] }
|
|
24
|
+
return globals[REGISTRY_KEY]!
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function joinLabels(labels: string[]): string {
|
|
28
|
+
if (labels.length <= 1) return labels[0] ?? ""
|
|
29
|
+
return `${labels.slice(0, -1).join(", ")} & ${labels[labels.length - 1]!}`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function joinedCategory(): string {
|
|
33
|
+
const labels = [...new Set(registry().entries.map((entry) => entry.label))].sort((a, b) => a.localeCompare(b))
|
|
34
|
+
return joinLabels(labels)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Declares this plugin's category label and attaches command objects whose
|
|
39
|
+
* `category` field is kept in sync. Returns the current join, so the very
|
|
40
|
+
* first registration already renders correctly even before reconcilers run.
|
|
41
|
+
*/
|
|
42
|
+
export function declarePaletteCategory(label: string, ...commands: CategorizedCommand[]): string {
|
|
43
|
+
const reg = registry()
|
|
44
|
+
let entry = reg.entries.find((item) => item.label === label)
|
|
45
|
+
if (!entry) {
|
|
46
|
+
entry = { label, commands: [] }
|
|
47
|
+
reg.entries.push(entry)
|
|
48
|
+
}
|
|
49
|
+
for (const command of commands) {
|
|
50
|
+
if (command && !entry.commands.includes(command)) entry.commands.push(command)
|
|
51
|
+
}
|
|
52
|
+
reconcilePaletteCategories()
|
|
53
|
+
return joinedCategory()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Live join for callback-style command registration (reads fresh each call). */
|
|
57
|
+
export function currentPaletteCategory(): string {
|
|
58
|
+
return joinedCategory()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Writes the current join into every declared command (idempotent). */
|
|
62
|
+
export function reconcilePaletteCategories(): void {
|
|
63
|
+
const category = joinedCategory()
|
|
64
|
+
for (const entry of registry().entries) {
|
|
65
|
+
for (const command of entry.commands) {
|
|
66
|
+
command.category = category
|
|
67
|
+
command.group = category
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Delayed reconciles so later-activating siblings join before the user opens the palette. */
|
|
73
|
+
export function schedulePaletteReconcile(delaysMs: readonly number[] = [2000, 6000]): void {
|
|
74
|
+
for (const delay of delaysMs) {
|
|
75
|
+
const timer = setTimeout(() => reconcilePaletteCategories(), delay)
|
|
76
|
+
;(timer as { unref?: () => void }).unref?.()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Tests only: drop all declarations. */
|
|
81
|
+
export function __resetPaletteRegistry(): void {
|
|
82
|
+
;(globalThis as { [key: symbol]: Registry | undefined })[REGISTRY_KEY] = undefined
|
|
83
|
+
}
|