tenbo-dashboard 0.7.0 → 0.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.
@@ -9,20 +9,21 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
  const root = path.resolve(__dirname, '..');
10
10
 
11
11
  /**
12
- * Find the tsx binary by walking up node_modules from this file's directory.
13
- * Required because npm hoists shared dependencies to a parent node_modules,
14
- * so `<package>/node_modules/.bin/tsx` may not exist for consumers.
12
+ * Find tsx's loader by walking up node_modules from this file's directory.
13
+ * Running the tsx CLI starts an IPC server for parent/child coordination; some
14
+ * sandboxes reject that pipe. `node --import <loader>` runs the same TypeScript
15
+ * entrypoints without that extra IPC listener.
15
16
  */
16
- function findTsx() {
17
+ function findTsxLoader() {
17
18
  let dir = __dirname;
18
19
  for (let i = 0; i < 10; i++) {
19
- const candidate = path.join(dir, 'node_modules', '.bin', 'tsx');
20
+ const candidate = path.join(dir, 'node_modules', 'tsx', 'dist', 'loader.mjs');
20
21
  if (existsSync(candidate)) return candidate;
21
22
  const parent = path.dirname(dir);
22
23
  if (parent === dir) break;
23
24
  dir = parent;
24
25
  }
25
- return 'tsx'; // last-resort fallback to PATH
26
+ return 'tsx'; // last-resort fallback to package resolution
26
27
  }
27
28
 
28
29
  const [command, ...args] = process.argv.slice(2);
@@ -51,8 +52,8 @@ const commands = {
51
52
  const LAUNCH_ALIASES = new Set(['serve', 'start', 'dev']);
52
53
 
53
54
  function run(script, scriptArgs) {
54
- const tsx = findTsx();
55
- const child = spawn(tsx, [path.join(root, script), ...scriptArgs], {
55
+ const tsxLoader = findTsxLoader();
56
+ const child = spawn(process.execPath, ['--import', tsxLoader, path.join(root, script), ...scriptArgs], {
56
57
  stdio: 'inherit',
57
58
  cwd: process.cwd(),
58
59
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tenbo-dashboard",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Local-first architecture dashboard and CLI tools for .tenbo/ repos",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,9 +37,9 @@
37
37
  "dev": "vite",
38
38
  "build": "tsc -b && vite build",
39
39
  "test": "vitest",
40
- "validate": "tsx scripts/validate-cli.ts",
41
- "next-id": "tsx scripts/next-id.ts",
42
- "compute-metrics": "tsx scripts/compute-metrics.ts"
40
+ "validate": "node --import ./node_modules/tsx/dist/loader.mjs scripts/validate-cli.ts",
41
+ "next-id": "node --import ./node_modules/tsx/dist/loader.mjs scripts/next-id.ts",
42
+ "compute-metrics": "node --import ./node_modules/tsx/dist/loader.mjs scripts/compute-metrics.ts"
43
43
  },
44
44
  "dependencies": {
45
45
  "@dnd-kit/core": "^6.3.1",
@@ -9,7 +9,7 @@ import { allocateNextId, STALE_LOCK_MS } from './next-id';
9
9
  // under jsdom. Vitest runs from the package root, so cwd === tenbo-dashboard.
10
10
  const APP_ROOT = process.cwd();
11
11
  const SCRIPT_PATH = path.join(APP_ROOT, 'scripts', 'next-id.ts');
12
- const TSX_BIN = path.join(APP_ROOT, 'node_modules', '.bin', 'tsx');
12
+ const TSX_LOADER = path.join(APP_ROOT, 'node_modules', 'tsx', 'dist', 'loader.mjs');
13
13
 
14
14
  const created: string[] = [];
15
15
 
@@ -98,7 +98,7 @@ describe('next-id allocator', () => {
98
98
  // Fan out N parallel child processes that all try to allocate `ed`.
99
99
  const N = 5;
100
100
  const procs = Array.from({ length: N }, () =>
101
- spawnSync(TSX_BIN, [SCRIPT_PATH, 'ed'], {
101
+ spawnSync(process.execPath, ['--import', TSX_LOADER, SCRIPT_PATH, 'ed'], {
102
102
  cwd: root,
103
103
  encoding: 'utf8',
104
104
  }),
@@ -3,9 +3,7 @@ import { sortByPriority, comparePriority } from './priority';
3
3
  import type { Item, Priority } from '../../types';
4
4
 
5
5
  const item = (id: string, priority?: Priority): Item =>
6
- ({ id, title: id, status: 'now', description: '' } as Item) as any && (
7
- { id, title: id, status: 'now', description: '', priority } as unknown as Item
8
- );
6
+ ({ id, title: id, status: 'now', description: '', priority } as unknown as Item);
9
7
 
10
8
  describe('sortByPriority', () => {
11
9
  it('orders p0 → p1 → p2 → p3 → unset', () => {
@@ -12,7 +12,7 @@ export function usePrompt() {
12
12
  if (timerRef.current) clearTimeout(timerRef.current);
13
13
  try {
14
14
  await navigator.clipboard.writeText(text);
15
- setToast(`${label} copied. Paste into Claude Code in the repo root.`);
15
+ setToast(`${label} copied. Paste into your coding agent in the repo root.`);
16
16
  } catch {
17
17
  setToast('Copy failed. Select and copy manually.');
18
18
  }
@@ -4,7 +4,7 @@ export function EmptyState({ message }: { message: string }) {
4
4
  return (
5
5
  <div className={styles.empty}>
6
6
  <p>{message}</p>
7
- <p className={styles.hint}>Run <code>set up tenbo</code> in Claude Code, then reload.</p>
7
+ <p className={styles.hint}>Run <code>set up tenbo</code> with your coding agent, then reload.</p>
8
8
  </div>
9
9
  );
10
10
  }
@@ -1,4 +1,4 @@
1
- import type { Item, Phase, Status } from '../../types';
1
+ import type { Item, Status } from '../../types';
2
2
  import { phaseProgress } from '../../api/lib/phases';
3
3
 
4
4
  const STATUSES: Status[] = ['now', 'next', 'later', 'done', 'dropped'];
@@ -59,8 +59,8 @@ export function DecisionsTab({ state }: { state: TenboState }) {
59
59
  because Y.&rdquo; They live in <code>.tenbo/decisions/&lt;slug&gt;.md</code>.
60
60
  </p>
61
61
  <p className={styles.emptyBody}>
62
- See <code>skill/templates/decision.md.tmpl</code> for the file shape
63
- (frontmatter + Context / Decision / Consequences / When to revisit).
62
+ Create a Markdown file with frontmatter plus Context, Decision,
63
+ Consequences, and When to revisit sections.
64
64
  </p>
65
65
  </div>
66
66
  );