@hartvig/developer-control-center 0.8.2
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/.developer-control-center/metrics.json +1 -0
- package/.developer-control-center/status.json +1 -0
- package/.developer-control-center/timings.jsonl +3 -0
- package/.github/workflows/ci.yml +47 -0
- package/AGENTS.md +51 -0
- package/PLUGINS.md +145 -0
- package/README.md +147 -0
- package/developer-control-center.config.example.js +91 -0
- package/developer-control-center.config.js +177 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +223 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +4 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +96 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/loader.test.d.ts +2 -0
- package/dist/config/loader.test.d.ts.map +1 -0
- package/dist/config/loader.test.js +25 -0
- package/dist/config/loader.test.js.map +1 -0
- package/dist/config/presets/node.d.ts +10 -0
- package/dist/config/presets/node.d.ts.map +1 -0
- package/dist/config/presets/node.js +31 -0
- package/dist/config/presets/node.js.map +1 -0
- package/dist/config/presets/react.d.ts +10 -0
- package/dist/config/presets/react.d.ts.map +1 -0
- package/dist/config/presets/react.js +36 -0
- package/dist/config/presets/react.js.map +1 -0
- package/dist/config/types.d.ts +55 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/types.test.d.ts +2 -0
- package/dist/config/types.test.d.ts.map +1 -0
- package/dist/config/types.test.js +23 -0
- package/dist/config/types.test.js.map +1 -0
- package/dist/core/ci.d.ts +6 -0
- package/dist/core/ci.d.ts.map +1 -0
- package/dist/core/ci.js +22 -0
- package/dist/core/ci.js.map +1 -0
- package/dist/core/ci.test.d.ts +2 -0
- package/dist/core/ci.test.d.ts.map +1 -0
- package/dist/core/ci.test.js +45 -0
- package/dist/core/ci.test.js.map +1 -0
- package/dist/core/event-bus.d.ts +18 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +19 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/event-bus.test.d.ts +2 -0
- package/dist/core/event-bus.test.d.ts.map +1 -0
- package/dist/core/event-bus.test.js +49 -0
- package/dist/core/event-bus.test.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/notifier.d.ts +2 -0
- package/dist/core/notifier.d.ts.map +1 -0
- package/dist/core/notifier.js +28 -0
- package/dist/core/notifier.js.map +1 -0
- package/dist/core/notifier.test.d.ts +2 -0
- package/dist/core/notifier.test.d.ts.map +1 -0
- package/dist/core/notifier.test.js +25 -0
- package/dist/core/notifier.test.js.map +1 -0
- package/dist/core/runtime.d.ts +25 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +85 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/task-runner.d.ts +26 -0
- package/dist/core/task-runner.d.ts.map +1 -0
- package/dist/core/task-runner.js +354 -0
- package/dist/core/task-runner.js.map +1 -0
- package/dist/core/timer-plugin.d.ts +3 -0
- package/dist/core/timer-plugin.d.ts.map +1 -0
- package/dist/core/timer-plugin.js +34 -0
- package/dist/core/timer-plugin.js.map +1 -0
- package/dist/core/workspaces.d.ts +6 -0
- package/dist/core/workspaces.d.ts.map +1 -0
- package/dist/core/workspaces.js +60 -0
- package/dist/core/workspaces.js.map +1 -0
- package/dist/core/workspaces.test.d.ts +2 -0
- package/dist/core/workspaces.test.d.ts.map +1 -0
- package/dist/core/workspaces.test.js +62 -0
- package/dist/core/workspaces.test.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +2 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/manager.d.ts +13 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +43 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/manager.test.d.ts +2 -0
- package/dist/plugins/manager.test.d.ts.map +1 -0
- package/dist/plugins/manager.test.js +79 -0
- package/dist/plugins/manager.test.js.map +1 -0
- package/dist/plugins/types.d.ts +17 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/status/index.d.ts +3 -0
- package/dist/status/index.d.ts.map +1 -0
- package/dist/status/index.js +2 -0
- package/dist/status/index.js.map +1 -0
- package/dist/status/store.d.ts +18 -0
- package/dist/status/store.d.ts.map +1 -0
- package/dist/status/store.js +76 -0
- package/dist/status/store.js.map +1 -0
- package/dist/status/store.test.d.ts +2 -0
- package/dist/status/store.test.d.ts.map +1 -0
- package/dist/status/store.test.js +107 -0
- package/dist/status/store.test.js.map +1 -0
- package/dist/status/types.d.ts +12 -0
- package/dist/status/types.d.ts.map +1 -0
- package/dist/status/types.js +2 -0
- package/dist/status/types.js.map +1 -0
- package/dist/ui/app.d.ts +10 -0
- package/dist/ui/app.d.ts.map +1 -0
- package/dist/ui/app.js +479 -0
- package/dist/ui/app.js.map +1 -0
- package/dist/ui/command-list.d.ts +30 -0
- package/dist/ui/command-list.d.ts.map +1 -0
- package/dist/ui/command-list.js +45 -0
- package/dist/ui/command-list.js.map +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/metrics-panel.d.ts +10 -0
- package/dist/ui/metrics-panel.d.ts.map +1 -0
- package/dist/ui/metrics-panel.js +139 -0
- package/dist/ui/metrics-panel.js.map +1 -0
- package/dist/ui/panel.d.ts +16 -0
- package/dist/ui/panel.d.ts.map +1 -0
- package/dist/ui/panel.js +16 -0
- package/dist/ui/panel.js.map +1 -0
- package/dist/ui/status-panel.d.ts +16 -0
- package/dist/ui/status-panel.d.ts.map +1 -0
- package/dist/ui/status-panel.js +52 -0
- package/dist/ui/status-panel.js.map +1 -0
- package/docs/architecture.md +29 -0
- package/docs/config.md +15 -0
- package/docs/mvp.md +17 -0
- package/docs/phases.md +49 -0
- package/docs/technical-decisions.md +19 -0
- package/docs/ui.md +14 -0
- package/package.json +30 -0
- package/src/cli.ts +242 -0
- package/src/config/index.ts +2 -0
- package/src/config/loader.test.ts +30 -0
- package/src/config/loader.ts +123 -0
- package/src/config/presets/node.ts +30 -0
- package/src/config/presets/react.ts +35 -0
- package/src/config/types.test.ts +24 -0
- package/src/config/types.ts +52 -0
- package/src/core/ci.test.ts +54 -0
- package/src/core/ci.ts +26 -0
- package/src/core/event-bus.test.ts +56 -0
- package/src/core/event-bus.ts +34 -0
- package/src/core/index.ts +8 -0
- package/src/core/notifier.test.ts +30 -0
- package/src/core/notifier.ts +34 -0
- package/src/core/runtime.ts +99 -0
- package/src/core/task-runner.ts +408 -0
- package/src/core/timer-plugin.ts +34 -0
- package/src/core/workspaces.test.ts +72 -0
- package/src/core/workspaces.ts +73 -0
- package/src/index.ts +15 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/manager.test.ts +92 -0
- package/src/plugins/manager.ts +54 -0
- package/src/plugins/types.ts +18 -0
- package/src/status/index.ts +2 -0
- package/src/status/store.test.ts +122 -0
- package/src/status/store.ts +88 -0
- package/src/status/types.ts +12 -0
- package/src/ui/app.tsx +606 -0
- package/src/ui/command-list.tsx +163 -0
- package/src/ui/index.tsx +10 -0
- package/src/ui/metrics-panel.tsx +234 -0
- package/src/ui/panel.tsx +76 -0
- package/src/ui/status-panel.tsx +160 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"projectRunning":true,"activeTasks":1,"packageVersion":"0.8.2","latestTest":{"label":"Test all packages","status":"success","time":1780431890869},"latestBuild":{"status":"success","time":1780431872826}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[["deploy-publish",{"id":"deploy-publish","label":"Publish package","status":"running","output":"","startTime":1780432163378,"watchMode":false}]]
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"id":"build","label":"Build all packages","duration":2460,"exitCode":0,"status":"success","timestamp":"2026-06-02T20:24:32.829Z"}
|
|
2
|
+
{"id":"test","label":"Test all packages","duration":1614,"exitCode":0,"status":"success","timestamp":"2026-06-02T20:24:50.874Z"}
|
|
3
|
+
{"id":"deploy-publish","label":"Publish package","duration":1468,"exitCode":1,"status":"failure","timestamp":"2026-06-02T20:25:16.699Z"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
node-version: [20, 22]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: ${{ matrix.node-version }}
|
|
22
|
+
cache: npm
|
|
23
|
+
- run: npm ci
|
|
24
|
+
- run: npm run build
|
|
25
|
+
- run: npm test
|
|
26
|
+
|
|
27
|
+
publish:
|
|
28
|
+
needs: build
|
|
29
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: actions/setup-node@v4
|
|
34
|
+
with:
|
|
35
|
+
node-version: 22
|
|
36
|
+
registry-url: https://registry.npmjs.org
|
|
37
|
+
- run: npm ci
|
|
38
|
+
- run: npm run build
|
|
39
|
+
- name: Publish packages
|
|
40
|
+
run: |
|
|
41
|
+
for pkg in packages/config packages/status packages/plugins packages/core packages/ui packages/cli packages/preset-node packages/preset-react; do
|
|
42
|
+
cd "$pkg"
|
|
43
|
+
npm publish --access public 2>/dev/null || echo "skipping $pkg (already published)"
|
|
44
|
+
cd ../..
|
|
45
|
+
done
|
|
46
|
+
env:
|
|
47
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Build & Run
|
|
4
|
+
|
|
5
|
+
- Build all packages: `npm run build` (runs `tsc -b` at root)
|
|
6
|
+
- Watch mode: `npm run dev` (`tsc -b -w`)
|
|
7
|
+
- Clean builds: `npm run clean` (`tsc -b --clean`)
|
|
8
|
+
- Run CLI: `npm start` (or `node packages/cli/dist/index.js`)
|
|
9
|
+
- Run tests: `npm test` (`vitest --run`)
|
|
10
|
+
- Watch tests: `npm run test:watch` (`vitest`)
|
|
11
|
+
- **ESM-only**: all packages use `"type": "module"`. Config files can be `.mjs`, `.cjs`, or `.js` (with `"type": "module"` context).
|
|
12
|
+
|
|
13
|
+
## Monorepo Structure
|
|
14
|
+
|
|
15
|
+
- npm workspaces with 6 packages under `packages/*`.
|
|
16
|
+
- TypeScript project references; root `tsc -b` builds all.
|
|
17
|
+
- Base tsconfig at `tsconfig.base.json`; each package extends it.
|
|
18
|
+
|
|
19
|
+
Package dependency order (bottom-up):
|
|
20
|
+
- `config/` — standalone, loads `developer-control-center.config.js` (CJS/ESM)
|
|
21
|
+
- `status/` — standalone, `StatusStore` with subscribe pattern
|
|
22
|
+
- `plugins/` — standalone, plugin registry
|
|
23
|
+
- `core/` — depends on config + status + plugins; owns `Runtime`, `EventBus`, `TaskRunner`
|
|
24
|
+
- `ui/` — depends on core + config + status; Ink 7 + React 19, renders `App` component
|
|
25
|
+
- `cli.ts` — depends on config + core + ui; bin entrypoint
|
|
26
|
+
|
|
27
|
+
## Architecture
|
|
28
|
+
|
|
29
|
+
- Runtime flow: `CLI -> Config Loader -> Core Runtime -> Ink UI`
|
|
30
|
+
- Core runtime owns `TaskRunner` (spawns child processes), `StatusStore` (observable task state), `EventBus` (typed events), and `PluginManager`.
|
|
31
|
+
- Config is project-local `developer-control-center.config.{mjs,cjs,js}` using `export default` (ESM) or `module.exports` (CJS); see `docs/config.md`.
|
|
32
|
+
- MVP scope per `docs/mvp.md`; CI/cloud/plugin-marketplace are out of scope.
|
|
33
|
+
|
|
34
|
+
## Design Docs
|
|
35
|
+
|
|
36
|
+
- `docs/*.md` describe planned intent, not necessarily what is implemented.
|
|
37
|
+
- Current Phase 2: search/filter (`/` key), confirmation prompts for `confirm: true` commands, scrollable output (50 lines active / 10 inactive), git branch in header, status persistence in `.developer-control-center/status.json`.
|
|
38
|
+
- Phase 1 delivered: foundation monorepo, command execution, config loading, Ink UI shell with keyboard nav.
|
|
39
|
+
|
|
40
|
+
## Config
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
// developer-control-center.config.js
|
|
44
|
+
export default {
|
|
45
|
+
name: 'my-project',
|
|
46
|
+
commands: [
|
|
47
|
+
{ id: 'build', label: 'Build', command: 'npm run build' },
|
|
48
|
+
{ id: 'deploy', label: 'Deploy', command: 'npm run deploy', confirm: true },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
```
|
package/PLUGINS.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Plugin Author Guide
|
|
2
|
+
|
|
3
|
+
developer-control-center supports a plugin system that hooks into the task lifecycle. Plugins are npm packages loaded at startup.
|
|
4
|
+
|
|
5
|
+
## Plugin Interface
|
|
6
|
+
|
|
7
|
+
A plugin is a module that exports an object conforming to `ProkomPlugin`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface ProkomPlugin {
|
|
11
|
+
name: string;
|
|
12
|
+
hooks: {
|
|
13
|
+
beforeRun?: (command: ProkomCommand) => void | Promise<void>;
|
|
14
|
+
afterRun?: (command: ProkomCommand, result: { exitCode?: number; status: string }) => void | Promise<void>;
|
|
15
|
+
onOutput?: (taskId: string, text: string) => void | Promise<void>;
|
|
16
|
+
onError?: (taskId: string, error: Error) => void | Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Hook Reference
|
|
22
|
+
|
|
23
|
+
| Hook | Arguments | When |
|
|
24
|
+
|------|-----------|------|
|
|
25
|
+
| `beforeRun` | `(command)` | Before a command starts executing |
|
|
26
|
+
| `afterRun` | `(command, result)` | After a command finishes (success or failure) |
|
|
27
|
+
| `onOutput` | `(taskId, text)` | On each chunk of stdout/stderr |
|
|
28
|
+
| `onError` | `(taskId, error)` | On spawn errors |
|
|
29
|
+
|
|
30
|
+
## Creating a Plugin
|
|
31
|
+
|
|
32
|
+
### 1. Create the package
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
my-dcc-plugin/
|
|
36
|
+
├── package.json
|
|
37
|
+
├── index.js
|
|
38
|
+
└── README.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Implement the hooks
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
// index.js
|
|
45
|
+
export default {
|
|
46
|
+
name: 'my-plugin',
|
|
47
|
+
hooks: {
|
|
48
|
+
beforeRun(command) {
|
|
49
|
+
console.log(`[my-plugin] starting: ${command.label}`);
|
|
50
|
+
},
|
|
51
|
+
afterRun(command, result) {
|
|
52
|
+
console.log(`[my-plugin] finished: ${command.label} (exit ${result.exitCode})`);
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Use it in config
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
// developer-control-center.config.js
|
|
62
|
+
export default {
|
|
63
|
+
plugins: ['my-dcc-plugin'],
|
|
64
|
+
commands: [ /* ... */ ],
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Plugin Resolution
|
|
69
|
+
|
|
70
|
+
- Plugins are resolved via `require()`, so they must be installed or linked.
|
|
71
|
+
- Use npm/yarn workspaces for local plugins: `"my-plugin": "file:./plugins/my-plugin"`.
|
|
72
|
+
|
|
73
|
+
## Using Hooks
|
|
74
|
+
|
|
75
|
+
### Simple Observer
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
export default {
|
|
79
|
+
name: 'logger',
|
|
80
|
+
hooks: {
|
|
81
|
+
onOutput(taskId, text) {
|
|
82
|
+
// stream output to a log file
|
|
83
|
+
fs.appendFileSync(`logs/${taskId}.log`, text);
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Guard Plugin (prevent execution)
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
export default {
|
|
93
|
+
name: 'time-guard',
|
|
94
|
+
hooks: {
|
|
95
|
+
beforeRun(command) {
|
|
96
|
+
const hour = new Date().getHours();
|
|
97
|
+
if (command.id === 'deploy' && (hour < 9 || hour > 17)) {
|
|
98
|
+
throw new Error('Deployments only allowed during working hours');
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Plugin with State
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
export default {
|
|
109
|
+
name: 'stats',
|
|
110
|
+
hooks: {
|
|
111
|
+
beforeRun() { this.startTime = Date.now(); },
|
|
112
|
+
afterRun(command, result) {
|
|
113
|
+
const elapsed = Date.now() - this.startTime;
|
|
114
|
+
console.log(`[stats] ${command.id}: ${elapsed}ms`);
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Presets
|
|
121
|
+
|
|
122
|
+
Presets are reusable command collections. Built-in presets are `node` and `react`.
|
|
123
|
+
|
|
124
|
+
A preset exports a `ProkomPreset`:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
interface ProkomPreset {
|
|
128
|
+
name: string;
|
|
129
|
+
commands: ProkomCommand[];
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Example:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
export default {
|
|
137
|
+
name: 'node',
|
|
138
|
+
commands: [
|
|
139
|
+
{ id: 'test', label: 'Test', command: 'npm test' },
|
|
140
|
+
{ id: 'build', label: 'Build', command: 'npm run build' },
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Built-in presets: `node`, `react`.
|
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# developer-control-center
|
|
2
|
+
|
|
3
|
+
A project-local developer control center — a TUI launcher for commands, builds, pipelines, and status tracking.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Command menu** — keyboard-navigable list of project commands
|
|
8
|
+
- **Search** — press `/` to filter commands by name
|
|
9
|
+
- **Parallel execution** — run multiple tasks simultaneously
|
|
10
|
+
- **Pipelines** — chain commands with sequential step execution
|
|
11
|
+
- **Watch mode** — auto-re-run commands on file changes
|
|
12
|
+
- **Confirmation prompts** — guard destructive commands with `confirm: true`
|
|
13
|
+
- **Status panel** — live output, exit codes, duration, scrollable history
|
|
14
|
+
- **Environment profiles** — switch command sets with `--profile`
|
|
15
|
+
- **Workspace detection** — auto-detect monorepo packages
|
|
16
|
+
- **Git branch** — shows current branch in header
|
|
17
|
+
- **CI integration** — auto-detects CI environments, applies `ci` profile
|
|
18
|
+
- **Desktop notifications** — alerts on task completion/failure
|
|
19
|
+
- **Presets** — reusable command collections (node, react)
|
|
20
|
+
- **Plugin API** — lifecycle hooks for custom extensions
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @hartvig/developer-control-center
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or run from a local checkout:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone <url>
|
|
32
|
+
cd developer-control-center
|
|
33
|
+
npm install
|
|
34
|
+
npm run build
|
|
35
|
+
npm start
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Launch in current directory
|
|
42
|
+
dcc
|
|
43
|
+
|
|
44
|
+
# Use a specific config file
|
|
45
|
+
dcc ./configs/developer-control-center.config.js
|
|
46
|
+
|
|
47
|
+
# Use a CI profile
|
|
48
|
+
dcc --profile ci
|
|
49
|
+
|
|
50
|
+
# Show help
|
|
51
|
+
dcc --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Keyboard Controls
|
|
55
|
+
|
|
56
|
+
| Key | Action |
|
|
57
|
+
|-----|--------|
|
|
58
|
+
| `↑`/`↓` | Navigate commands / scroll status |
|
|
59
|
+
| `Enter` | Run selected command |
|
|
60
|
+
| `/` | Enter search mode |
|
|
61
|
+
| `Tab` | Focus status panel |
|
|
62
|
+
| `Esc` | Back to commands / exit search |
|
|
63
|
+
| `y`/`n` | Confirm / cancel (confirmation prompts) |
|
|
64
|
+
| `Ctrl+C` / `Esc` (in command mode) | Quit |
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
Create `developer-control-center.config.js` (or `.mjs` / `.cjs`) in your project root:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
export default {
|
|
72
|
+
name: 'my-project',
|
|
73
|
+
commands: [
|
|
74
|
+
{
|
|
75
|
+
id: 'build',
|
|
76
|
+
label: 'Build',
|
|
77
|
+
command: 'npm run build',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'deploy',
|
|
81
|
+
label: 'Deploy to staging',
|
|
82
|
+
command: 'npm run deploy:staging',
|
|
83
|
+
confirm: true,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'dev-watch',
|
|
87
|
+
label: 'Dev server',
|
|
88
|
+
command: 'npm run dev',
|
|
89
|
+
watch: true,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Presets
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
export default {
|
|
99
|
+
presets: ['node'], // loads built-in node preset
|
|
100
|
+
commands: [
|
|
101
|
+
// your project-specific overrides
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Built-in presets: `node` (test, build, lint, typecheck, clean), `react` (dev, build, test, lint, typecheck, preview).
|
|
107
|
+
|
|
108
|
+
### Profiles
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
export default {
|
|
112
|
+
profiles: {
|
|
113
|
+
ci: {
|
|
114
|
+
commands: [
|
|
115
|
+
{ id: 'build', label: 'Build (CI)', command: 'npm run build' },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Pipelines
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
export default {
|
|
126
|
+
pipelines: [
|
|
127
|
+
{
|
|
128
|
+
id: 'deploy-all',
|
|
129
|
+
label: 'Build, test, deploy',
|
|
130
|
+
steps: ['build', 'test', 'deploy'],
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Full options documented in [docs/config.md](docs/config.md).
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm run dev # watch mode
|
|
142
|
+
npm test # run tests
|
|
143
|
+
npm run build # compile TypeScript
|
|
144
|
+
npm start # run CLI
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
See [PLUGINS.md](PLUGINS.md) for the plugin API and [docs/architecture.md](docs/architecture.md) for the system architecture.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
name: 'my-project',
|
|
3
|
+
menuRows: 8,
|
|
4
|
+
// outputRows: 12, // defaults to menuRows
|
|
5
|
+
|
|
6
|
+
commands: [
|
|
7
|
+
// --- Simple command ---
|
|
8
|
+
{
|
|
9
|
+
id: 'build',
|
|
10
|
+
label: 'Build',
|
|
11
|
+
description: 'Build the project.',
|
|
12
|
+
command: 'npm run build',
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
// --- Toggle (start/stop) ---
|
|
16
|
+
{
|
|
17
|
+
id: 'dev',
|
|
18
|
+
label: 'Watch mode',
|
|
19
|
+
description: 'Start or stop the file watcher.',
|
|
20
|
+
toggle: { start: 'npm run dev' },
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// --- Confirm before running ---
|
|
24
|
+
{
|
|
25
|
+
id: 'deploy',
|
|
26
|
+
label: 'Deploy',
|
|
27
|
+
description: 'Deploy to production.',
|
|
28
|
+
command: 'npm run deploy',
|
|
29
|
+
confirm: true,
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// --- Prompt for input ---
|
|
33
|
+
{
|
|
34
|
+
id: 'bump-version',
|
|
35
|
+
label: 'Bump version',
|
|
36
|
+
description: 'Increment the project version.',
|
|
37
|
+
command: 'npm version {input}',
|
|
38
|
+
confirm: true,
|
|
39
|
+
input: { message: 'Bump type? (patch/minor/major):', placeholder: 'patch', default: 'patch' },
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
// --- Conditional follow-up on non-zero exit ---
|
|
43
|
+
{
|
|
44
|
+
id: 'check-outdated',
|
|
45
|
+
label: 'Check outdated deps',
|
|
46
|
+
description: 'List outdated npm dependencies.',
|
|
47
|
+
command: 'npm outdated',
|
|
48
|
+
onNonZeroExit: {
|
|
49
|
+
label: 'Update all',
|
|
50
|
+
command: 'npm update',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// --- Run in a specific directory ---
|
|
55
|
+
{
|
|
56
|
+
id: 'build-sub',
|
|
57
|
+
label: 'Build sub-package',
|
|
58
|
+
description: 'Build only the sub-package.',
|
|
59
|
+
command: 'npm run build',
|
|
60
|
+
cwd: 'packages/sub',
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// --- Parallel-safe task ---
|
|
64
|
+
{
|
|
65
|
+
id: 'sleep-long',
|
|
66
|
+
label: 'Long task',
|
|
67
|
+
description: 'Demo task that runs 10 seconds.',
|
|
68
|
+
command: 'sleep 10',
|
|
69
|
+
parallel: true,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
|
|
73
|
+
// --- Profiles (override/extend commands for different environments) ---
|
|
74
|
+
profiles: {
|
|
75
|
+
ci: {
|
|
76
|
+
commands: [
|
|
77
|
+
{ id: 'build', label: 'Build (CI)', command: 'npm run build' },
|
|
78
|
+
{ id: 'lint', label: 'Lint', command: 'npm run lint' },
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// --- Pipelines (run multiple commands sequentially) ---
|
|
84
|
+
pipelines: [
|
|
85
|
+
{
|
|
86
|
+
id: 'pipeline-full-check',
|
|
87
|
+
label: 'Full check',
|
|
88
|
+
steps: ['lint', 'build', 'test'],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
name: 'developer-control-center',
|
|
3
|
+
menuRows: 10,
|
|
4
|
+
// Available presets (use: presets: ['node'] or presets: ['react']):
|
|
5
|
+
// node — Test, Build, Lint, TypeCheck, Clean (npm run / npm test)
|
|
6
|
+
// react — Dev server, Build, Test, Lint, TypeCheck, Preview build
|
|
7
|
+
// To use both: presets: ['node', 'react']
|
|
8
|
+
|
|
9
|
+
commands: [
|
|
10
|
+
{
|
|
11
|
+
id: 'dev',
|
|
12
|
+
label: 'Watch mode',
|
|
13
|
+
description: 'Start or stop the TypeScript project-reference watcher.',
|
|
14
|
+
toggle: { start: 'npm run dev', stop: 'pkill -f "tsc -w" 2>/dev/null || true' },
|
|
15
|
+
group: 'Development',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'test',
|
|
19
|
+
label: 'Test all packages',
|
|
20
|
+
description: 'Run the full Vitest suite once.',
|
|
21
|
+
command: 'npm test',
|
|
22
|
+
group: 'Development',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'clean',
|
|
26
|
+
label: 'Clean builds',
|
|
27
|
+
description: 'Remove TypeScript project-reference build output.',
|
|
28
|
+
command: 'npm run clean',
|
|
29
|
+
group: 'Development',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'install',
|
|
33
|
+
label: 'Install all packages',
|
|
34
|
+
description: 'Install all npm dependencies across workspaces.',
|
|
35
|
+
command: 'npm install',
|
|
36
|
+
group: 'Development',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'bump-version',
|
|
40
|
+
label: 'Bump version',
|
|
41
|
+
description: 'Increment the project version. Prompts for patch, minor, or major.',
|
|
42
|
+
command: 'npm version --no-git-tag-version {input}',
|
|
43
|
+
group: 'Build',
|
|
44
|
+
confirm: true,
|
|
45
|
+
input: { message: 'Bump type? (patch/minor/major):', placeholder: 'patch', default: 'patch' },
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'build',
|
|
49
|
+
label: 'Build all packages',
|
|
50
|
+
description: 'Compile all TypeScript.',
|
|
51
|
+
command: 'npm run build',
|
|
52
|
+
group: 'Build',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'deploy-dry-run',
|
|
56
|
+
label: 'Publish dry run',
|
|
57
|
+
description: 'Preview publishing without publishing (uses npm token auth).',
|
|
58
|
+
command: 'npm publish --dry-run',
|
|
59
|
+
group: 'Deploy',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'deploy-publish',
|
|
63
|
+
label: 'Publish package',
|
|
64
|
+
description: 'Publish to npm (uses npm token auth).',
|
|
65
|
+
command: 'npm publish --access public',
|
|
66
|
+
group: 'Deploy',
|
|
67
|
+
confirm: true,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'dev-server-toggle',
|
|
71
|
+
label: 'Dev server',
|
|
72
|
+
description: 'Demo toggle command that simulates a long-running server.',
|
|
73
|
+
toggle: { start: 'sleep 60', stop: 'echo "server stopped"' },
|
|
74
|
+
group: 'Demo',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'parallel-demo',
|
|
78
|
+
label: 'Parallel demo (sleep 3)',
|
|
79
|
+
description: 'Demo command that can run alongside other parallel tasks.',
|
|
80
|
+
command: 'sleep 3',
|
|
81
|
+
parallel: true,
|
|
82
|
+
group: 'Demo',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'parallel-demo-2',
|
|
86
|
+
label: 'Parallel demo (sleep 5)',
|
|
87
|
+
description: 'Second demo command for parallel execution.',
|
|
88
|
+
command: 'sleep 5',
|
|
89
|
+
parallel: true,
|
|
90
|
+
group: 'Demo',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'demo-confirm-overlay',
|
|
94
|
+
label: 'Confirm overlay demo',
|
|
95
|
+
description: 'Shows a yes/no overlay inside the command pane.',
|
|
96
|
+
command: '',
|
|
97
|
+
group: 'Demo',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'parallel-steps-demo',
|
|
101
|
+
label: 'Parallel steps (sleep 3 + 5)',
|
|
102
|
+
description: 'Run both demo sleep tasks concurrently as one command.',
|
|
103
|
+
command: '',
|
|
104
|
+
parallelSteps: ['parallel-demo', 'parallel-demo-2'],
|
|
105
|
+
group: 'Demo',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'status-git',
|
|
109
|
+
label: 'Git status',
|
|
110
|
+
description: 'Show concise git working-tree status.',
|
|
111
|
+
command: 'git status --short',
|
|
112
|
+
group: 'Management',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'git-commit-push',
|
|
116
|
+
label: 'Commit & push',
|
|
117
|
+
description: 'Prompt for a commit message, commit all changes, then push.',
|
|
118
|
+
command: 'git add -A && git commit --allow-empty -m "{input}" && git push',
|
|
119
|
+
group: 'Management',
|
|
120
|
+
confirm: true,
|
|
121
|
+
input: { message: 'Commit message:', placeholder: 'type a message…' },
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'git-push',
|
|
125
|
+
label: 'Git push',
|
|
126
|
+
description: 'Push the current branch to its configured remote.',
|
|
127
|
+
command: 'git push',
|
|
128
|
+
group: 'Management',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 'status-outdated',
|
|
132
|
+
label: 'Check outdated deps',
|
|
133
|
+
description: 'List outdated npm dependencies.',
|
|
134
|
+
command: 'npm outdated',
|
|
135
|
+
group: 'Management',
|
|
136
|
+
onNonZeroExit: {
|
|
137
|
+
label: 'Update all',
|
|
138
|
+
command: 'npm update',
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'status-packages',
|
|
143
|
+
label: 'List workspace packages',
|
|
144
|
+
description: 'List installed top-level packages.',
|
|
145
|
+
command: 'npm ls --depth=0',
|
|
146
|
+
group: 'Management',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
profiles: {
|
|
150
|
+
ci: {
|
|
151
|
+
commands: [
|
|
152
|
+
{
|
|
153
|
+
id: 'build',
|
|
154
|
+
label: 'Build (CI)',
|
|
155
|
+
command: 'npm run build',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: 'status-git',
|
|
159
|
+
label: 'Check git diff',
|
|
160
|
+
command: 'git diff --stat',
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
pipelines: [
|
|
166
|
+
{
|
|
167
|
+
id: 'pipeline-build-clean',
|
|
168
|
+
label: 'Build then clean',
|
|
169
|
+
steps: ['build', 'clean'],
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: 'pipeline-status',
|
|
173
|
+
label: 'Full status check',
|
|
174
|
+
steps: ['status-git', 'status-outdated', 'status-packages'],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
};
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|