pi-command-center 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Warren Winter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Command Center for Pi (`pi-command-center`)
2
+
3
+ A scrollable overview of available /commands (from extensions, prompts, skills) shown as a widget above the editor. The editor stays fully interactive; you can keep the widget open while typing and submitting commands.
4
+
5
+ See source repo for more documentation.
6
+
7
+ ## Install
8
+
9
+ From npm:
10
+
11
+ ```bash
12
+ pi install npm:pi-command-center
13
+ ```
14
+
15
+ From the dot314 git bundle (filtered install):
16
+
17
+ Add to `~/.pi/agent/settings.json` (or replace an existing unfiltered `git:github.com/w-winter/dot314` entry):
18
+
19
+ ```json
20
+ {
21
+ "packages": [
22
+ {
23
+ "source": "git:github.com/w-winter/dot314",
24
+ "extensions": ["extensions/command-center/index.ts"],
25
+ "skills": [],
26
+ "themes": [],
27
+ "prompts": []
28
+ }
29
+ ]
30
+ }
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ This package ships a template at:
36
+
37
+ - `extensions/command-center/config.json.example`
38
+
39
+ Copy it to `config.json`, edit, then run `/reload`.
40
+
41
+ See `extensions/command-center/README.md` for the full config options.
@@ -0,0 +1,73 @@
1
+ # Command Center
2
+
3
+ A scrollable overview of available /commands (from extensions, prompts, skills, and optionally† built-ins) shown as a widget above the editor. The editor stays fully interactive; you can keep the widget open while typing and submitting commands.
4
+
5
+ <p align="center">
6
+ <img width="333" alt="command center demo" src="https://github.com/user-attachments/assets/f9ed3649-ac5b-4658-836b-86091e4985a1" />
7
+ </p>
8
+
9
+ ## Usage
10
+
11
+ - Command: `/command-center` (toggle)
12
+ - Shortcut: configurable in `config.json`
13
+
14
+ ## Configuration
15
+
16
+ 1. Copy `config.json.example` → `config.json`
17
+ 2. Edit `config.json` to your preferences
18
+ 3. Run `/reload`
19
+
20
+ ### Recommended defaults
21
+
22
+ #### Hide built-ins (†)
23
+
24
+ By default, this extension excludes built-in interactive commands because:
25
+ - Built-ins are already discoverable via the editor’s native `/` autocomplete (with descriptions)
26
+ - Keeping a built-in list inside this extension requires manual maintenance as pi evolves
27
+
28
+ If you still want them, set:
29
+
30
+ ```json
31
+ {
32
+ "display": { "includeBuiltins": true }
33
+ }
34
+ ```
35
+
36
+ #### Widget height
37
+
38
+ You can force a fixed widget height (rows):
39
+
40
+ ```json
41
+ {
42
+ "layout": { "height": 14 }
43
+ }
44
+ ```
45
+
46
+ Suggested values:
47
+ - Small terminals: **20–30** rows
48
+ - Larger terminals: increase as you like
49
+
50
+ Notes:
51
+ - The widget height is clamped so the editor always has some space
52
+ - If pi can’t determine terminal height, Command Center assumes a fallback terminal height of **54** rows
53
+ (so the effective maximum widget height is typically **48** rows due to reserved editor space)
54
+
55
+ If `layout.height` is `null` or omitted, the widget auto-sizes based on terminal height.
56
+
57
+ ### Keybindings
58
+
59
+ All shortcuts are configured here (strings are pi key ids):
60
+
61
+ ```json
62
+ {
63
+ "keybindings": {
64
+ "toggle": "ctrl+shift+/",
65
+ "scrollUp": "ctrl+shift+up",
66
+ "scrollDown": "ctrl+shift+down",
67
+ "scrollPageUp": null,
68
+ "scrollPageDown": null
69
+ }
70
+ }
71
+ ```
72
+
73
+ Set any binding to `null` to disable it.
@@ -0,0 +1,15 @@
1
+ {
2
+ "display": {
3
+ "includeBuiltins": false
4
+ },
5
+ "layout": {
6
+ "height": 24
7
+ },
8
+ "keybindings": {
9
+ "toggle": "ctrl+shift+/",
10
+ "scrollUp": "ctrl+shift+up",
11
+ "scrollDown": "ctrl+shift+down",
12
+ "scrollPageUp": null,
13
+ "scrollPageDown": null
14
+ }
15
+ }
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Command Center Extension
3
+ *
4
+ * A scrollable commands cheat sheet shown as a widget above the editor.
5
+ *
6
+ * Keybindings are configured in ./config.json (relative to this file).
7
+ */
8
+
9
+ import type { ExtensionAPI, ExtensionContext, SlashCommandInfo } from "@mariozechner/pi-coding-agent";
10
+ import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
11
+
12
+ import * as fs from "node:fs";
13
+ import * as path from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+
16
+ // Note: pi.getCommands() does NOT include built-in interactive commands (e.g. /model, /settings)
17
+ // because those do not execute when sent via prompt. Until the extension API exposes built-ins,
18
+ // we keep a small local list in case includeBuiltins is configured true
19
+ const BUILTIN_COMMANDS: string[] = [
20
+ "/settings",
21
+ "/model",
22
+ "/scoped-models",
23
+ "/name",
24
+ "/session",
25
+ "/reload",
26
+ "/compact",
27
+ "/tree",
28
+ "/fork",
29
+ "/new",
30
+ "/resume",
31
+ "/export",
32
+ "/copy",
33
+ "/share",
34
+ "/hotkeys",
35
+ "/changelog",
36
+ "/login",
37
+ "/logout",
38
+ ];
39
+
40
+ type ExtensionKeybindingsConfig = {
41
+ toggle?: string | null;
42
+ scrollUp?: string | null;
43
+ scrollDown?: string | null;
44
+ scrollPageUp?: string | null;
45
+ scrollPageDown?: string | null;
46
+ };
47
+
48
+ type ExtensionLayoutConfig = {
49
+ /**
50
+ * Fixed widget height in rows.
51
+ *
52
+ * If omitted, height is computed from terminal height.
53
+ */
54
+ height?: number | null;
55
+ };
56
+
57
+ type ExtensionDisplayConfig = {
58
+ /**
59
+ * Whether to include built-in interactive commands in the widget output
60
+ *
61
+ * Recommended default: false
62
+ * - Built-ins are already discoverable via the editor's native `/` autocomplete
63
+ * - Keeping built-ins here requires manually maintaining a list as pi evolves
64
+ */
65
+ includeBuiltins?: boolean;
66
+ };
67
+
68
+ type ExtensionConfig = {
69
+ keybindings?: ExtensionKeybindingsConfig;
70
+ layout?: ExtensionLayoutConfig;
71
+ display?: ExtensionDisplayConfig;
72
+ };
73
+
74
+ const DEFAULT_CONFIG: Required<ExtensionConfig> = {
75
+ keybindings: {
76
+ toggle: "ctrl+shift+/",
77
+ scrollUp: "ctrl+shift+up",
78
+ scrollDown: "ctrl+shift+down",
79
+ scrollPageUp: null,
80
+ scrollPageDown: null,
81
+ },
82
+ layout: {
83
+ height: null,
84
+ },
85
+ display: {
86
+ includeBuiltins: false,
87
+ },
88
+ };
89
+
90
+ function loadConfig(): Required<ExtensionConfig> {
91
+ const dir = path.dirname(fileURLToPath(import.meta.url));
92
+ const configPath = path.join(dir, "config.json");
93
+
94
+ if (!fs.existsSync(configPath)) {
95
+ return DEFAULT_CONFIG;
96
+ }
97
+
98
+ try {
99
+ const parsed = JSON.parse(fs.readFileSync(configPath, "utf-8")) as ExtensionConfig;
100
+ const keybindings = {
101
+ ...DEFAULT_CONFIG.keybindings,
102
+ ...(parsed.keybindings ?? {}),
103
+ };
104
+ const layout = {
105
+ ...DEFAULT_CONFIG.layout,
106
+ ...(parsed.layout ?? {}),
107
+ };
108
+ const display = {
109
+ ...DEFAULT_CONFIG.display,
110
+ ...(parsed.display ?? {}),
111
+ };
112
+ return { keybindings, layout, display };
113
+ } catch {
114
+ // If config is invalid, fall back to defaults rather than breaking the session
115
+ return DEFAULT_CONFIG;
116
+ }
117
+ }
118
+
119
+ function visLen(s: string): number {
120
+ return visibleWidth(s);
121
+ }
122
+
123
+ function padRight(s: string, width: number): string {
124
+ const visible = visLen(s);
125
+ const padding = Math.max(0, width - visible);
126
+ return s + " ".repeat(padding);
127
+ }
128
+
129
+ function makeColumns(items: string[], colWidth: number, maxCols: number): string[] {
130
+ const lines: string[] = [];
131
+ for (let i = 0; i < items.length; i += maxCols) {
132
+ const row = items.slice(i, i + maxCols);
133
+ lines.push(row.map((s) => padRight(s, colWidth)).join(""));
134
+ }
135
+ return lines;
136
+ }
137
+
138
+ function clamp(n: number, min: number, max: number): number {
139
+ return Math.max(min, Math.min(max, n));
140
+ }
141
+
142
+ function truncatePlain(s: string, maxVisibleChars: number): string {
143
+ if (s.length <= maxVisibleChars) return s;
144
+ if (maxVisibleChars <= 1) return "…";
145
+ return s.slice(0, maxVisibleChars - 1) + "…";
146
+ }
147
+
148
+ function buildAllLines(width: number, commands: SlashCommandInfo[], options: { includeBuiltins: boolean }): string[] {
149
+ const lines: string[] = [];
150
+ const g = (s: string) => `\x1b[32m${s}\x1b[0m`; // green
151
+ const c = (s: string) => `\x1b[36m${s}\x1b[0m`; // cyan
152
+ const y = (s: string) => `\x1b[33m${s}\x1b[0m`; // yellow
153
+ const b = (s: string) => `\x1b[1m${s}\x1b[0m`; // bold
154
+
155
+ const usableWidth = Math.max(60, width - 6);
156
+
157
+ const builtins = BUILTIN_COMMANDS;
158
+ const extensions = commands.filter((command) => command.source === "extension").map((command) => `/${command.name}`);
159
+ const prompts = commands.filter((command) => command.source === "prompt").map((command) => `/${command.name}`);
160
+ const skills = commands.filter((command) => command.source === "skill").map((command) => `/${command.name}`);
161
+
162
+ // Order: extensions -> prompts -> skills -> builtins (optional)
163
+
164
+ lines.push(y(b(`EXTENSIONS (${extensions.length})`)));
165
+ {
166
+ const maxItemLen = extensions.length > 0 ? Math.max(...extensions.map((s) => s.length)) : 0;
167
+ const colWidth = clamp(maxItemLen + 2, 15, 34);
168
+ const cols = Math.min(6, Math.max(1, Math.floor(usableWidth / colWidth)));
169
+ const items = extensions.map((s) => g(truncatePlain(s, colWidth - 1)));
170
+ for (const line of makeColumns(items, colWidth, cols)) {
171
+ lines.push(" " + line);
172
+ }
173
+ }
174
+ lines.push("");
175
+
176
+ lines.push(y(b(`PROMPTS (${prompts.length})`)));
177
+ if (prompts.length > 0) {
178
+ const maxItemLen = Math.max(...prompts.map((s) => s.length));
179
+ const colWidth = clamp(maxItemLen + 2, 18, 40);
180
+ const cols = Math.max(1, Math.floor(usableWidth / colWidth));
181
+ const items = prompts.map((s) => c(truncatePlain(s, colWidth - 1)));
182
+ for (const line of makeColumns(items, colWidth, cols)) {
183
+ lines.push(" " + line);
184
+ }
185
+ }
186
+ lines.push("");
187
+
188
+ lines.push(y(b(`SKILLS (${skills.length})`)));
189
+ if (skills.length > 0) {
190
+ const maxItemLen = Math.max(...skills.map((s) => s.length));
191
+ const colWidth = clamp(maxItemLen + 2, 18, 40);
192
+ const cols = Math.max(1, Math.floor(usableWidth / colWidth));
193
+ const items = skills.map((s) => c(truncatePlain(s, colWidth - 1)));
194
+ for (const line of makeColumns(items, colWidth, cols)) {
195
+ lines.push(" " + line);
196
+ }
197
+ }
198
+ if (options.includeBuiltins) {
199
+ lines.push("");
200
+
201
+ lines.push(y(b(`BUILT-IN (${builtins.length})`)));
202
+ {
203
+ const maxItemLen = builtins.length > 0 ? Math.max(...builtins.map((s) => s.length)) : 0;
204
+ const colWidth = clamp(maxItemLen + 2, 14, 24);
205
+ const cols = Math.min(7, Math.max(1, Math.floor(usableWidth / colWidth)));
206
+ const items = builtins.map((s) => g(truncatePlain(s, colWidth - 1)));
207
+ for (const line of makeColumns(items, colWidth, cols)) {
208
+ lines.push(" " + line);
209
+ }
210
+ }
211
+ }
212
+
213
+ return lines;
214
+ }
215
+
216
+ type WidgetTheme = {
217
+ fg: (style: string, text: string) => string;
218
+ bold: (text: string) => string;
219
+ };
220
+
221
+ type WidgetTui = {
222
+ height?: number;
223
+ requestRender: () => void;
224
+ };
225
+
226
+ function prettyKeybinding(key: string | null | undefined): string {
227
+ if (!key) return "(unbound)";
228
+
229
+ // make a few things more readable
230
+ return key
231
+ .replaceAll("pageUp", "PgUp")
232
+ .replaceAll("pageDown", "PgDn")
233
+ .replaceAll("shift+", "Shift+")
234
+ .replaceAll("alt+", "Alt+")
235
+ .replaceAll("ctrl+", "Ctrl+")
236
+ .replaceAll("up", "↑")
237
+ .replaceAll("down", "↓")
238
+ .replaceAll("left", "←")
239
+ .replaceAll("right", "→");
240
+ }
241
+
242
+ class CommandCenterWidget {
243
+ private tui: WidgetTui;
244
+ private theme: WidgetTheme;
245
+ private pi: ExtensionAPI;
246
+ private config: Required<ExtensionConfig>;
247
+
248
+ private scroll: number = 0;
249
+ private cachedWidth: number = 0;
250
+ private cachedLines: string[] = [];
251
+
252
+ constructor(tui: WidgetTui, theme: WidgetTheme, pi: ExtensionAPI, config: Required<ExtensionConfig>) {
253
+ this.tui = tui;
254
+ this.theme = theme;
255
+ this.pi = pi;
256
+ this.config = config;
257
+ }
258
+
259
+ updateTheme(theme: WidgetTheme): void {
260
+ this.theme = theme;
261
+ this.invalidate();
262
+ }
263
+
264
+ updateConfig(config: Required<ExtensionConfig>): void {
265
+ this.config = config;
266
+ this.invalidate();
267
+ }
268
+
269
+ invalidate(): void {
270
+ this.cachedWidth = 0;
271
+ this.cachedLines = [];
272
+ }
273
+
274
+ scrollBy(delta: number): void {
275
+ this.scroll += delta;
276
+ this.tui.requestRender();
277
+ }
278
+
279
+ render(width: number): string[] {
280
+ const terminalHeight = this.tui.height ?? 54;
281
+
282
+ // Keep at least a few rows for the editor
283
+ const maxAllowedHeight = Math.max(10, terminalHeight - 6);
284
+
285
+ const configuredHeight = this.config.layout.height;
286
+ const height = configuredHeight
287
+ ? clamp(Math.floor(configuredHeight), 6, maxAllowedHeight)
288
+ : clamp(Math.floor(terminalHeight * 0.35) + 2, 10, Math.min(18, maxAllowedHeight));
289
+ const innerHeight = Math.max(3, height - 4);
290
+
291
+ if (width !== this.cachedWidth) {
292
+ this.cachedLines = buildAllLines(width, this.pi.getCommands(), {
293
+ includeBuiltins: this.config.display.includeBuiltins,
294
+ });
295
+ this.cachedWidth = width;
296
+ }
297
+
298
+ const maxScroll = Math.max(0, this.cachedLines.length - innerHeight);
299
+ this.scroll = clamp(this.scroll, 0, maxScroll);
300
+
301
+ const output: string[] = [];
302
+
303
+ const toggleKey = prettyKeybinding(this.config.keybindings.toggle);
304
+ const scrollUpKey = prettyKeybinding(this.config.keybindings.scrollUp);
305
+ const scrollDownKey = prettyKeybinding(this.config.keybindings.scrollDown);
306
+
307
+ const builtinHint = this.config.display.includeBuiltins
308
+ ? "built-ins included"
309
+ : "built-ins: type / in editor";
310
+
311
+ const header =
312
+ this.theme.fg("accent", this.theme.bold("COMMAND CENTER")) +
313
+ this.theme.fg("dim", ` (toggle ${toggleKey}, scroll ${scrollUpKey}/${scrollDownKey}; ${builtinHint})`);
314
+
315
+ output.push(this.theme.fg("dim", "┌" + "─".repeat(width - 2) + "┐"));
316
+ output.push(
317
+ this.theme.fg("dim", "│ ") +
318
+ truncateToWidth(header, width - 4, "…", true) +
319
+ this.theme.fg("dim", " │"),
320
+ );
321
+ output.push(this.theme.fg("dim", "├" + "─".repeat(width - 2) + "┤"));
322
+
323
+ const visible = this.cachedLines.slice(this.scroll, this.scroll + innerHeight);
324
+ for (const line of visible) {
325
+ const content = truncateToWidth(line, width - 4, "…", true);
326
+ output.push(this.theme.fg("dim", "│ ") + content + this.theme.fg("dim", " │"));
327
+ }
328
+
329
+ for (let i = visible.length; i < innerHeight; i++) {
330
+ output.push(this.theme.fg("dim", "│") + " ".repeat(width - 2) + this.theme.fg("dim", "│"));
331
+ }
332
+
333
+ const scrollInfo =
334
+ maxScroll > 0 ? ` ${this.scroll + 1}-${this.scroll + visible.length}/${this.cachedLines.length} ` : "";
335
+ const footerPad = Math.max(0, width - 2 - scrollInfo.length);
336
+ output.push(
337
+ this.theme.fg(
338
+ "dim",
339
+ "└" +
340
+ "─".repeat(Math.floor(footerPad / 2)) +
341
+ scrollInfo +
342
+ "─".repeat(Math.ceil(footerPad / 2)) +
343
+ "┘",
344
+ ),
345
+ );
346
+
347
+ return output.slice(0, height);
348
+ }
349
+ }
350
+
351
+ export default function commandCenterExtension(pi: ExtensionAPI): void {
352
+ const WIDGET_ID = "command-center";
353
+
354
+ let widget: CommandCenterWidget | undefined;
355
+ let visible = false;
356
+
357
+ const readConfigAndUpdateWidget = () => {
358
+ const config = loadConfig();
359
+ if (widget) {
360
+ widget.updateConfig(config);
361
+ }
362
+ return config;
363
+ };
364
+
365
+ const show = (ctx: ExtensionContext) => {
366
+ const config = readConfigAndUpdateWidget();
367
+
368
+ ctx.ui.setWidget(
369
+ WIDGET_ID,
370
+ (tui, theme) => {
371
+ if (!widget) {
372
+ widget = new CommandCenterWidget(
373
+ tui as unknown as WidgetTui,
374
+ theme as unknown as WidgetTheme,
375
+ pi,
376
+ config,
377
+ );
378
+ } else {
379
+ widget.updateTheme(theme as unknown as WidgetTheme);
380
+ widget.updateConfig(config);
381
+ }
382
+ return widget as any;
383
+ },
384
+ { placement: "aboveEditor" },
385
+ );
386
+ visible = true;
387
+ };
388
+
389
+ const hide = (ctx: ExtensionContext) => {
390
+ ctx.ui.setWidget(WIDGET_ID, undefined);
391
+ visible = false;
392
+ widget = undefined;
393
+ };
394
+
395
+ const toggle = (ctx: ExtensionContext) => {
396
+ if (visible) {
397
+ hide(ctx);
398
+ } else {
399
+ show(ctx);
400
+ }
401
+ };
402
+
403
+ pi.registerCommand("command-center", {
404
+ description: "Toggle command center widget",
405
+ handler: async (_args, ctx) => {
406
+ toggle(ctx);
407
+ },
408
+ });
409
+
410
+ // Shortcut bindings from config.json
411
+ const config = loadConfig();
412
+
413
+ const registerIfSet = (
414
+ key: string | null | undefined,
415
+ description: string,
416
+ handler: (ctx: ExtensionContext) => void,
417
+ ) => {
418
+ if (!key) return;
419
+ pi.registerShortcut(key as any, { description, handler });
420
+ };
421
+
422
+ registerIfSet(config.keybindings.toggle, "Toggle command center widget", toggle);
423
+
424
+ registerIfSet(config.keybindings.scrollUp, "Scroll command center up", () => {
425
+ if (!visible || !widget) return;
426
+ widget.scrollBy(-1);
427
+ });
428
+
429
+ registerIfSet(config.keybindings.scrollDown, "Scroll command center down", () => {
430
+ if (!visible || !widget) return;
431
+ widget.scrollBy(1);
432
+ });
433
+
434
+ registerIfSet(config.keybindings.scrollPageUp, "Scroll command center up (page)", () => {
435
+ if (!visible || !widget) return;
436
+ widget.scrollBy(-10);
437
+ });
438
+
439
+ registerIfSet(config.keybindings.scrollPageDown, "Scroll command center down (page)", () => {
440
+ if (!visible || !widget) return;
441
+ widget.scrollBy(10);
442
+ });
443
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "pi-command-center",
3
+ "version": "0.1.0",
4
+ "description": "Scrollable widget displaying available /commands from extensions/prompts/skills, compatible with simultaneous editor use.",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi",
8
+ "pi-coding-agent",
9
+ "commands",
10
+ "widget"
11
+ ],
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/w-winter/dot314.git",
16
+ "directory": "packages/pi-command-center"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/w-winter/dot314/issues"
20
+ },
21
+ "homepage": "https://github.com/w-winter/dot314#readme",
22
+ "pi": {
23
+ "extensions": [
24
+ "extensions/command-center/index.ts"
25
+ ]
26
+ },
27
+ "peerDependencies": {
28
+ "@mariozechner/pi-coding-agent": ">=0.51.0",
29
+ "@mariozechner/pi-tui": "*"
30
+ },
31
+ "scripts": {
32
+ "prepack": "node ../../scripts/pi-package-prepack.mjs"
33
+ },
34
+ "files": [
35
+ "extensions/**",
36
+ "README.md",
37
+ "LICENSE",
38
+ "package.json"
39
+ ],
40
+ "dot314Prepack": {
41
+ "copy": [
42
+ {
43
+ "from": "../../extensions/command-center/index.ts",
44
+ "to": "extensions/command-center/index.ts"
45
+ },
46
+ {
47
+ "from": "../../extensions/command-center/config.json.example",
48
+ "to": "extensions/command-center/config.json.example"
49
+ },
50
+ {
51
+ "from": "../../extensions/command-center/README.md",
52
+ "to": "extensions/command-center/README.md"
53
+ },
54
+ {
55
+ "from": "../../LICENSE",
56
+ "to": "LICENSE"
57
+ }
58
+ ]
59
+ }
60
+ }