@jhizzard/termdeck 0.4.6 → 0.5.1
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 +10 -2
- package/package.json +3 -2
- package/packages/cli/src/auto-orchestrate.js +26 -0
- package/packages/cli/src/index.js +24 -2
- package/packages/cli/src/stack.js +23 -6
package/README.md
CHANGED
|
@@ -22,6 +22,14 @@ First-time user? The **config** button in the toolbar shows what's set up and wh
|
|
|
22
22
|
|
|
23
23
|
Enabling Flashback takes **one additional 15-minute setup step** — see Tier 2 below. The rest of this README explains what you get, how it works, and how to go deeper.
|
|
24
24
|
|
|
25
|
+
### Want the whole stack in one command?
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @jhizzard/termdeck-stack
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The meta-installer prints a layered overview of the four packages (TermDeck + Mnestra + Rumen + Supabase MCP), detects what's already on your machine, asks which tier you want, runs `npm install -g` for the missing pieces, and merges Mnestra + Supabase MCP entries into `~/.claude/mcp.json`. See [packages/stack-installer/README.md](packages/stack-installer/README.md) for details, or `npx @jhizzard/termdeck-stack --help`.
|
|
32
|
+
|
|
25
33
|
---
|
|
26
34
|
|
|
27
35
|
## Documentation hierarchy
|
|
@@ -211,8 +219,8 @@ For users who want more than `npx` — cloning from source, building a macOS `.a
|
|
|
211
219
|
|
|
212
220
|
### Alternative install paths
|
|
213
221
|
|
|
214
|
-
- **Permanent global install:** `npm install -g @jhizzard/termdeck` then `termdeck` from anywhere
|
|
215
|
-
- **
|
|
222
|
+
- **Permanent global install:** `npm install -g @jhizzard/termdeck` then `termdeck` from anywhere. From v0.5.0, `termdeck` (no subcommand) auto-detects a configured stack and boots Mnestra + checks Rumen automatically — same four-step output as `scripts/start.sh`. Use `termdeck --no-stack` to force a Tier-1-only boot.
|
|
223
|
+
- **Force-orchestrate alias:** `termdeck stack` always runs the orchestrator regardless of detection — kept for backward compatibility with v0.4.6 docs and muscle memory.
|
|
216
224
|
- **macOS native app:** `git clone && cd && ./install.sh` — creates `~/Applications/TermDeck.app`
|
|
217
225
|
- **From source:** `git clone && npm install && npm run dev`
|
|
218
226
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jhizzard/termdeck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Browser-based terminal multiplexer with metadata overlays, panel flashback memory recall, and AI-aware session management",
|
|
5
5
|
"bin": {
|
|
6
6
|
"termdeck": "./packages/cli/src/index.js"
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"workspaces": [
|
|
19
19
|
"packages/server",
|
|
20
20
|
"packages/client",
|
|
21
|
-
"packages/cli"
|
|
21
|
+
"packages/cli",
|
|
22
|
+
"packages/stack-installer"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
25
|
"dev": "node packages/server/src/index.js",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Detection helper for Sprint 24: should `termdeck` (no subcommand)
|
|
2
|
+
// auto-route through stack.js? Pure function, isolated for testability —
|
|
3
|
+
// the dispatcher in index.js still owns the actual routing decision.
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
function shouldAutoOrchestrate(homeDir) {
|
|
10
|
+
const home = homeDir || os.homedir();
|
|
11
|
+
const secretsPath = path.join(home, '.termdeck', 'secrets.env');
|
|
12
|
+
const configPath = path.join(home, '.termdeck', 'config.yaml');
|
|
13
|
+
if (!fs.existsSync(secretsPath) || !fs.existsSync(configPath)) return false;
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
const yaml = require('yaml');
|
|
17
|
+
parsed = yaml.parse(fs.readFileSync(configPath, 'utf8')) || {};
|
|
18
|
+
} catch (_e) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const mnestraAuto = parsed.mnestra && parsed.mnestra.autoStart === true;
|
|
22
|
+
const ragEnabled = parsed.rag && parsed.rag.enabled === true;
|
|
23
|
+
return Boolean(mnestraAuto || ragEnabled);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { shouldAutoOrchestrate };
|
|
@@ -76,6 +76,27 @@ if (args[0] === 'stack') {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
// Sprint 24: when `termdeck` is invoked with no subcommand AND a configured
|
|
80
|
+
// stack is detected, route through stack.js so users don't have to remember
|
|
81
|
+
// the `stack` subcommand. `--no-stack` is the explicit opt-out.
|
|
82
|
+
const { shouldAutoOrchestrate } = require(path.join(__dirname, 'auto-orchestrate.js'));
|
|
83
|
+
|
|
84
|
+
const KNOWN_SUBCOMMANDS = new Set(['init', 'forge', 'stack']);
|
|
85
|
+
const noStackIdx = args.indexOf('--no-stack');
|
|
86
|
+
const noStackRequested = noStackIdx !== -1;
|
|
87
|
+
if (noStackRequested) args.splice(noStackIdx, 1); // strip before flag parsing
|
|
88
|
+
|
|
89
|
+
const wantsHelp = args.includes('--help') || args.includes('-h');
|
|
90
|
+
|
|
91
|
+
if (!KNOWN_SUBCOMMANDS.has(args[0]) && !noStackRequested && !wantsHelp && shouldAutoOrchestrate()) {
|
|
92
|
+
const stack = require(path.join(__dirname, 'stack.js'));
|
|
93
|
+
stack(args).then((code) => process.exit(code || 0)).catch((err) => {
|
|
94
|
+
console.error('[cli] auto-stack failed:', err && err.stack || err);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
79
100
|
const flags = {};
|
|
80
101
|
for (let i = 0; i < args.length; i++) {
|
|
81
102
|
if (args[i] === '--port' && args[i + 1]) {
|
|
@@ -90,8 +111,9 @@ for (let i = 0; i < args.length; i++) {
|
|
|
90
111
|
TermDeck - Web-based terminal multiplexer
|
|
91
112
|
|
|
92
113
|
Usage:
|
|
93
|
-
termdeck
|
|
94
|
-
termdeck stack
|
|
114
|
+
termdeck Auto-orchestrate stack if configured, else Tier-1-only
|
|
115
|
+
termdeck stack Force boot Mnestra + check Rumen + start TermDeck
|
|
116
|
+
termdeck --no-stack Skip orchestrator (force Tier-1-only boot)
|
|
95
117
|
termdeck --port 8080 Start on custom port
|
|
96
118
|
termdeck --no-open Don't auto-open browser
|
|
97
119
|
termdeck --session-logs Write per-session markdown logs to ~/.termdeck/sessions/
|
|
@@ -385,15 +385,32 @@ async function checkRumen() {
|
|
|
385
385
|
// ── Step 4: TermDeck ────────────────────────────────────────────────
|
|
386
386
|
|
|
387
387
|
function execTermDeck({ port, extra }) {
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
//
|
|
388
|
+
// Spawn a fresh node process for the CLI rather than require()-ing it
|
|
389
|
+
// in-process. Two reasons:
|
|
390
|
+
// 1. require() hits Node's module cache after stack.js → index.js →
|
|
391
|
+
// stack.js bounces (the v0.5.0 auto-orchestrate path), so the
|
|
392
|
+
// cached index.js is a no-op and the server never starts. This
|
|
393
|
+
// manifested in `scripts/start.sh` which already exec'd node, then
|
|
394
|
+
// v0.5.0's auto-orchestrate routed it back through stack.js, then
|
|
395
|
+
// stack.js tried to re-require the (cached) CLI — silent exit.
|
|
396
|
+
// 2. Pass --no-stack on the way back so index.js definitively skips
|
|
397
|
+
// the auto-orchestrate detection. Defensive even with the spawn.
|
|
391
398
|
const cliPath = path.join(__dirname, 'index.js');
|
|
392
|
-
const argv = [];
|
|
399
|
+
const argv = [cliPath, '--no-stack'];
|
|
393
400
|
if (port) argv.push('--port', String(port));
|
|
394
401
|
argv.push(...extra);
|
|
395
|
-
|
|
396
|
-
|
|
402
|
+
const child = spawn(process.execPath, argv, {
|
|
403
|
+
stdio: 'inherit',
|
|
404
|
+
env: process.env,
|
|
405
|
+
});
|
|
406
|
+
child.on('exit', (code, signal) => {
|
|
407
|
+
if (signal) process.kill(process.pid, signal);
|
|
408
|
+
else process.exit(code == null ? 0 : code);
|
|
409
|
+
});
|
|
410
|
+
// Forward Ctrl+C cleanly so the spawned server can shut down.
|
|
411
|
+
for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
412
|
+
process.on(sig, () => { try { child.kill(sig); } catch (_e) { /* gone */ } });
|
|
413
|
+
}
|
|
397
414
|
}
|
|
398
415
|
|
|
399
416
|
// ── Main ────────────────────────────────────────────────────────────
|