@polderlabs/bizar 4.2.0 → 4.2.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/bizar-dash/src/server/memory-git.mjs +62 -0
- package/bizar-dash/src/server/memory-store.mjs +82 -10
- package/bizar-dash/tests/memory-cli-readlistdelete.test.mjs +405 -0
- package/bizar-dash/tests/memory-cli-setup.test.mjs +382 -0
- package/bizar-dash/tests/memory-cli.test.mjs +54 -0
- package/bizar-dash/tests/memory-conflicts.test.mjs +229 -0
- package/bizar-dash/tests/memory-namespace.test.mjs +404 -0
- package/bizar-dash/tests/memory-path-safety.test.mjs +427 -0
- package/bizar-dash/tests/memory-roundtrip.test.mjs +219 -0
- package/cli/memory.mjs +273 -6
- package/package.json +2 -2
package/cli/memory.mjs
CHANGED
|
@@ -104,6 +104,10 @@ async function cmdWrite(args) {
|
|
|
104
104
|
(default: verified)
|
|
105
105
|
--tag <tag> Tag to attach (may be passed multiple times)
|
|
106
106
|
--title <title> Frontmatter title field
|
|
107
|
+
--memory-id <id> Custom memory_id (default: <type>_<timestamp>)
|
|
108
|
+
Must match [a-zA-Z0-9._-]+
|
|
109
|
+
--scope <scope> Frontmatter scope field (e.g. project, team)
|
|
110
|
+
--source-agent <name> Frontmatter source_agent field
|
|
107
111
|
--body <text> Note body as a string
|
|
108
112
|
--body-file <path> Path to a file containing the body
|
|
109
113
|
(exactly one of --body / --body-file is allowed)
|
|
@@ -177,6 +181,30 @@ async function cmdWrite(args) {
|
|
|
177
181
|
process.exit(1);
|
|
178
182
|
}
|
|
179
183
|
|
|
184
|
+
// --memory-id (kebab/snake-case only)
|
|
185
|
+
const memoryId = optVal('--memory-id');
|
|
186
|
+
if (memoryId !== undefined) {
|
|
187
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(memoryId)) {
|
|
188
|
+
error(`invalid --memory-id: '${memoryId}' (must be kebab/snake-case)`);
|
|
189
|
+
info('expected pattern: mem_<path>, e.g. mem_api_memory_schema_md');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// --scope (free-form, but non-empty when provided)
|
|
195
|
+
const scope = optVal('--scope');
|
|
196
|
+
if (scope !== undefined && scope.length === 0) {
|
|
197
|
+
error('--scope must be a non-empty string');
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// --source-agent (free-form, but non-empty when provided)
|
|
202
|
+
const sourceAgent = optVal('--source-agent');
|
|
203
|
+
if (sourceAgent !== undefined && sourceAgent.length === 0) {
|
|
204
|
+
error('--source-agent must be a non-empty string');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
|
|
180
208
|
let body = '';
|
|
181
209
|
if (bodyFile) {
|
|
182
210
|
try {
|
|
@@ -201,6 +229,9 @@ async function cmdWrite(args) {
|
|
|
201
229
|
tags,
|
|
202
230
|
});
|
|
203
231
|
if (title) frontmatter.title = title;
|
|
232
|
+
if (memoryId) frontmatter.memory_id = memoryId;
|
|
233
|
+
if (scope) frontmatter.scope = scope;
|
|
234
|
+
if (sourceAgent) frontmatter.source_agent = sourceAgent;
|
|
204
235
|
|
|
205
236
|
// ── Write ───────────────────────────────────────────────────────────────
|
|
206
237
|
let result;
|
|
@@ -254,7 +285,25 @@ async function cmdInit(args) {
|
|
|
254
285
|
const projectRoot = getProjectRoot();
|
|
255
286
|
const { loadConfig, saveConfig } = memoryStore;
|
|
256
287
|
|
|
257
|
-
|
|
288
|
+
// ── Help (must come before any work — fixes gap in cmdInit --help coverage) ─
|
|
289
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
290
|
+
console.log(`
|
|
291
|
+
Usage: bizar memory init [options]
|
|
292
|
+
|
|
293
|
+
Initialize memory config for this project.
|
|
294
|
+
|
|
295
|
+
Options:
|
|
296
|
+
--memory-mode <managed|local-only> Vault mode (default: managed)
|
|
297
|
+
--memory-repo-name <name> Vault directory name (managed mode)
|
|
298
|
+
--yes Skip prompts; non-interactive
|
|
299
|
+
--non-interactive Alias for --yes
|
|
300
|
+
--help, -h Show this help
|
|
301
|
+
`.trim());
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// --non-interactive is the canonical alias; --yes kept for backward compat.
|
|
306
|
+
const yesFlag = args.includes('--yes') || args.includes('--non-interactive');
|
|
258
307
|
|
|
259
308
|
const existing = loadConfig(projectRoot);
|
|
260
309
|
if (existing.exists) {
|
|
@@ -879,7 +928,7 @@ async function cmdUnlink(_args) {
|
|
|
879
928
|
async function cmdPull(_args) {
|
|
880
929
|
const projectRoot = getProjectRoot();
|
|
881
930
|
const { loadConfig, resolveVault } = memoryStore;
|
|
882
|
-
const { pull, isGitInstalled } = memoryGit;
|
|
931
|
+
const { pull, isGitInstalled, ensureUpstream } = memoryGit;
|
|
883
932
|
|
|
884
933
|
const { config } = loadConfig(projectRoot);
|
|
885
934
|
if (config.mode === 'local-only') {
|
|
@@ -892,7 +941,18 @@ async function cmdPull(_args) {
|
|
|
892
941
|
process.exit(1);
|
|
893
942
|
}
|
|
894
943
|
|
|
895
|
-
const { vaultRoot } = resolveVault(projectRoot);
|
|
944
|
+
const { vaultRoot, branch } = resolveVault(projectRoot);
|
|
945
|
+
const remoteName = config.gitRemote ? 'origin' : 'origin';
|
|
946
|
+
|
|
947
|
+
// Pre-flight: ensure upstream is set. Without this, `git pull` fails with
|
|
948
|
+
// "no tracking information" on freshly-cloned or locally-initialized vaults.
|
|
949
|
+
const upstreamResult = ensureUpstream(vaultRoot, config.branch || branch || 'main', remoteName);
|
|
950
|
+
if (!upstreamResult.ok) {
|
|
951
|
+
info(`upstream not set (${upstreamResult.error}); pull may fail`);
|
|
952
|
+
} else if (upstreamResult.action === 'set') {
|
|
953
|
+
success(`set upstream to ${remoteName}/${config.branch || branch || 'main'}`);
|
|
954
|
+
}
|
|
955
|
+
|
|
896
956
|
info(`pulling into ${vaultRoot}`);
|
|
897
957
|
const result = pull(vaultRoot);
|
|
898
958
|
if (!result.ok) {
|
|
@@ -985,7 +1045,7 @@ async function cmdPush(_args) {
|
|
|
985
1045
|
async function cmdSync(args) {
|
|
986
1046
|
const projectRoot = getProjectRoot();
|
|
987
1047
|
const { loadConfig, resolveVault, validateAll, scanForSecrets, listNotes } = memoryStore;
|
|
988
|
-
const { pull, addAll, commit: gitCommit, push: gitPush, status: gitStatus, acquireLock, isGitInstalled } = memoryGit;
|
|
1048
|
+
const { pull, addAll, commit: gitCommit, push: gitPush, status: gitStatus, acquireLock, isGitInstalled, ensureUpstream } = memoryGit;
|
|
989
1049
|
|
|
990
1050
|
const { config } = loadConfig(projectRoot);
|
|
991
1051
|
if (config.mode === 'local-only') {
|
|
@@ -998,7 +1058,19 @@ async function cmdSync(args) {
|
|
|
998
1058
|
process.exit(1);
|
|
999
1059
|
}
|
|
1000
1060
|
|
|
1001
|
-
const { vaultRoot } = resolveVault(projectRoot);
|
|
1061
|
+
const { vaultRoot, branch } = resolveVault(projectRoot);
|
|
1062
|
+
const branchName = config.branch || branch || 'main';
|
|
1063
|
+
|
|
1064
|
+
// Pre-flight: ensure upstream is set. Some workflows create a vault before
|
|
1065
|
+
// origin exists; without upstream, `git pull` fails with "no tracking".
|
|
1066
|
+
if (config.gitRemote) {
|
|
1067
|
+
const upstreamResult = ensureUpstream(vaultRoot, branchName, 'origin');
|
|
1068
|
+
if (!upstreamResult.ok) {
|
|
1069
|
+
info(`upstream not set (${upstreamResult.error}); pull may fail`);
|
|
1070
|
+
} else if (upstreamResult.action === 'set') {
|
|
1071
|
+
success(`set upstream to origin/${branchName}`);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1002
1074
|
|
|
1003
1075
|
// Acquire lock
|
|
1004
1076
|
const lock = acquireLock(vaultRoot);
|
|
@@ -1237,7 +1309,7 @@ async function cmdConflicts(_args) {
|
|
|
1237
1309
|
const filePath = join(vaultRoot, note.relPath);
|
|
1238
1310
|
try {
|
|
1239
1311
|
const content = rf(filePath, 'utf8');
|
|
1240
|
-
if (/^<{7}\s|^={7}\s
|
|
1312
|
+
if (/^<{7}\s|^={7}\s|^>{7}\s/m.test(content)) {
|
|
1241
1313
|
conflicts.push({ relPath: note.relPath, reason: 'git conflict markers detected' });
|
|
1242
1314
|
}
|
|
1243
1315
|
} catch { /* skip */ }
|
|
@@ -1346,6 +1418,189 @@ async function cmdDoctor(_args) {
|
|
|
1346
1418
|
console.log();
|
|
1347
1419
|
}
|
|
1348
1420
|
|
|
1421
|
+
// ─── read / list / delete (Fix 4 + Fix 5 plumbing) ────────────────────────────
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* Parse `--namespace <ns>` and return the chosen namespace plus the remaining
|
|
1425
|
+
* positional args. Defaults to 'project' when the flag is absent.
|
|
1426
|
+
*/
|
|
1427
|
+
function parseNamespaceFlag(args) {
|
|
1428
|
+
const idx = args.indexOf('--namespace');
|
|
1429
|
+
if (idx === -1) return { namespace: 'project', rest: args };
|
|
1430
|
+
const v = args[idx + 1];
|
|
1431
|
+
if (!v || v.startsWith('-')) return { namespace: 'project', rest: args };
|
|
1432
|
+
// Remove the flag and its value from the rest
|
|
1433
|
+
const rest = args.filter((a, i) => i !== idx && i !== idx + 1);
|
|
1434
|
+
return { namespace: v, rest };
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
/**
|
|
1438
|
+
* `bizar memory read [--namespace <ns>] <relpath>`
|
|
1439
|
+
*
|
|
1440
|
+
* Read a single note and print its raw content (frontmatter + body) to stdout.
|
|
1441
|
+
*/
|
|
1442
|
+
async function cmdRead(args) {
|
|
1443
|
+
const projectRoot = getProjectRoot();
|
|
1444
|
+
const { resolveVault, resolveNamespaceRoot } = memoryStore;
|
|
1445
|
+
|
|
1446
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
1447
|
+
console.log(`
|
|
1448
|
+
Usage: bizar memory read [--namespace <ns>] <relpath>
|
|
1449
|
+
|
|
1450
|
+
Read a single note and print it to stdout (YAML frontmatter + body).
|
|
1451
|
+
|
|
1452
|
+
Options:
|
|
1453
|
+
--namespace <project|global|user> Namespace to read from (default: project)
|
|
1454
|
+
--help, -h Show this help
|
|
1455
|
+
`.trim());
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
const { namespace, rest } = parseNamespaceFlag(args);
|
|
1460
|
+
const relpath = rest.filter((a) => !a.startsWith('-'))[0];
|
|
1461
|
+
if (!relpath) {
|
|
1462
|
+
error('relpath is required: `bizar memory read <relpath>`');
|
|
1463
|
+
info('run `bizar memory read --help` for usage');
|
|
1464
|
+
process.exit(1);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
let note;
|
|
1468
|
+
if (namespace === 'project') {
|
|
1469
|
+
note = memoryStore.readNote(projectRoot, relpath);
|
|
1470
|
+
} else {
|
|
1471
|
+
const vi = resolveVault(projectRoot);
|
|
1472
|
+
const root = resolveNamespaceRoot(vi, namespace);
|
|
1473
|
+
if (!root) {
|
|
1474
|
+
error(`unknown namespace: ${namespace}`);
|
|
1475
|
+
process.exit(1);
|
|
1476
|
+
}
|
|
1477
|
+
note = memoryStore.readNote(projectRoot, relpath, { root });
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
if (!note) {
|
|
1481
|
+
error(`note not found: ${relpath}`);
|
|
1482
|
+
process.exit(1);
|
|
1483
|
+
}
|
|
1484
|
+
process.stdout.write(note.raw);
|
|
1485
|
+
if (!note.raw.endsWith('\n')) process.stdout.write('\n');
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* `bizar memory list [--namespace <ns>] [--json] [dir]`
|
|
1490
|
+
*
|
|
1491
|
+
* List notes under a directory. Default: walk the project namespace root.
|
|
1492
|
+
* Pass `dir` (e.g. `decisions/`) to scope to a subdirectory. The dir is
|
|
1493
|
+
* resolved RELATIVE TO the namespace root.
|
|
1494
|
+
*/
|
|
1495
|
+
async function cmdList(args) {
|
|
1496
|
+
const projectRoot = getProjectRoot();
|
|
1497
|
+
const { resolveVault, resolveNamespaceRoot } = memoryStore;
|
|
1498
|
+
|
|
1499
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
1500
|
+
console.log(`
|
|
1501
|
+
Usage: bizar memory list [--namespace <ns>] [dir]
|
|
1502
|
+
|
|
1503
|
+
List notes under a directory. Default: the project namespace root.
|
|
1504
|
+
|
|
1505
|
+
Options:
|
|
1506
|
+
--namespace <project|global|user> Namespace to list (default: project)
|
|
1507
|
+
--json Emit JSON array
|
|
1508
|
+
[dir] Subdirectory under the namespace (e.g. decisions/)
|
|
1509
|
+
--help, -h Show this help
|
|
1510
|
+
`.trim());
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
const { namespace, rest } = parseNamespaceFlag(args);
|
|
1515
|
+
const asJson = rest.includes('--json');
|
|
1516
|
+
const dir = rest.filter((a) => !a.startsWith('-'))[0] || '';
|
|
1517
|
+
|
|
1518
|
+
let notes;
|
|
1519
|
+
if (namespace === 'project') {
|
|
1520
|
+
notes = memoryStore.listNotes(projectRoot, dir ? { namespace: dir } : {});
|
|
1521
|
+
} else {
|
|
1522
|
+
const vi = resolveVault(projectRoot);
|
|
1523
|
+
const root = resolveNamespaceRoot(vi, namespace);
|
|
1524
|
+
if (!root) {
|
|
1525
|
+
error(`unknown namespace: ${namespace}`);
|
|
1526
|
+
process.exit(1);
|
|
1527
|
+
}
|
|
1528
|
+
notes = memoryStore.listNotes(projectRoot, dir ? { root, namespace: dir } : { root });
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// listNotes returns relPaths RELATIVE to the search root, so when we
|
|
1532
|
+
// filter by `dir` we need to re-attach the dir prefix for display —
|
|
1533
|
+
// otherwise the user sees `0001-foo.md` instead of the more useful
|
|
1534
|
+
// `decisions/0001-foo.md`. Strip a trailing slash for cleanliness.
|
|
1535
|
+
const displayPrefix = dir ? dir.replace(/\/+$/, '') + '/' : '';
|
|
1536
|
+
|
|
1537
|
+
if (asJson) {
|
|
1538
|
+
console.log(JSON.stringify(notes.map((n) => ({
|
|
1539
|
+
relPath: displayPrefix + n.relPath,
|
|
1540
|
+
size: n.size,
|
|
1541
|
+
mtime: n.mtime,
|
|
1542
|
+
})), null, 2));
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
if (notes.length === 0) {
|
|
1546
|
+
console.log(chalk.dim(' (no notes)'));
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
for (const n of notes) {
|
|
1550
|
+
console.log(` ${displayPrefix}${n.relPath}`);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
/**
|
|
1555
|
+
* `bizar memory delete [--namespace <ns>] <relpath>`
|
|
1556
|
+
*
|
|
1557
|
+
* Delete a single note from the vault.
|
|
1558
|
+
*/
|
|
1559
|
+
async function cmdDelete(args) {
|
|
1560
|
+
const projectRoot = getProjectRoot();
|
|
1561
|
+
const { resolveVault, resolveNamespaceRoot } = memoryStore;
|
|
1562
|
+
|
|
1563
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
1564
|
+
console.log(`
|
|
1565
|
+
Usage: bizar memory delete [--namespace <ns>] <relpath>
|
|
1566
|
+
|
|
1567
|
+
Delete a single note from the vault.
|
|
1568
|
+
|
|
1569
|
+
Options:
|
|
1570
|
+
--namespace <project|global|user> Namespace to delete from (default: project)
|
|
1571
|
+
--help, -h Show this help
|
|
1572
|
+
`.trim());
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
const { namespace, rest } = parseNamespaceFlag(args);
|
|
1577
|
+
const relpath = rest.filter((a) => !a.startsWith('-'))[0];
|
|
1578
|
+
if (!relpath) {
|
|
1579
|
+
error('relpath is required: `bizar memory delete <relpath>`');
|
|
1580
|
+
info('run `bizar memory delete --help` for usage');
|
|
1581
|
+
process.exit(1);
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
let ok;
|
|
1585
|
+
if (namespace === 'project') {
|
|
1586
|
+
ok = memoryStore.deleteNote(projectRoot, relpath);
|
|
1587
|
+
} else {
|
|
1588
|
+
const vi = resolveVault(projectRoot);
|
|
1589
|
+
const root = resolveNamespaceRoot(vi, namespace);
|
|
1590
|
+
if (!root) {
|
|
1591
|
+
error(`unknown namespace: ${namespace}`);
|
|
1592
|
+
process.exit(1);
|
|
1593
|
+
}
|
|
1594
|
+
ok = memoryStore.deleteNote(projectRoot, relpath, { root });
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
if (!ok) {
|
|
1598
|
+
error(`note not found: ${relpath}`);
|
|
1599
|
+
process.exit(1);
|
|
1600
|
+
}
|
|
1601
|
+
success(`deleted ${relpath}`);
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1349
1604
|
// ─── Dispatcher ──────────────────────────────────────────────────────────────
|
|
1350
1605
|
|
|
1351
1606
|
/**
|
|
@@ -1372,6 +1627,15 @@ export async function runMemory(subcommand, args) {
|
|
|
1372
1627
|
case 'write':
|
|
1373
1628
|
await cmdWrite(args);
|
|
1374
1629
|
break;
|
|
1630
|
+
case 'read':
|
|
1631
|
+
await cmdRead(args);
|
|
1632
|
+
break;
|
|
1633
|
+
case 'list':
|
|
1634
|
+
await cmdList(args);
|
|
1635
|
+
break;
|
|
1636
|
+
case 'delete':
|
|
1637
|
+
await cmdDelete(args);
|
|
1638
|
+
break;
|
|
1375
1639
|
case 'pull':
|
|
1376
1640
|
await cmdPull(args);
|
|
1377
1641
|
break;
|
|
@@ -1422,6 +1686,9 @@ function showHelp() {
|
|
|
1422
1686
|
link <path> Link to a shared memory repo (clone if URL)
|
|
1423
1687
|
unlink Revert to local-only mode
|
|
1424
1688
|
write Write a single note to the vault
|
|
1689
|
+
read Read a single note and print it to stdout
|
|
1690
|
+
list List notes (optionally filtered by namespace + dir)
|
|
1691
|
+
delete Delete a single note from the vault
|
|
1425
1692
|
pull Git pull from the shared repo
|
|
1426
1693
|
commit [-m] Git commit staged changes
|
|
1427
1694
|
push Git push to the shared repo
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polderlabs/bizar",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "Norse-pantheon multi-agent system for opencode — 13 agents across 4 cost tiers with cost-aware routing, plans, and a configurable agent harness. v4 ships as a single npm package bundling the dashboard server, opencode plugin, and typed SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build:sdk": "tsc -p packages/sdk/tsconfig.json",
|
|
22
22
|
"test:sdk": "npm test --prefix packages/sdk",
|
|
23
23
|
"test:sdk:watch": "npm run test:watch --prefix packages/sdk",
|
|
24
|
-
"test": "npm run typecheck && npm run test:sdk && bun test plugins/bizar/tests/loop.test.ts plugins/bizar/tests/block.test.ts plugins/bizar/tests/stall-think.test.ts plugins/bizar/tests/tools/bg-get-comments.test.ts plugins/bizar/tests/tools/bg-spawn-delegation.test.ts plugins/bizar/tests/tools/opencode-runner.test.ts plugins/bizar/tests/settings.test.ts plugins/bizar/tests/commands.test.ts plugins/bizar/tests/commands-impl.test.ts plugins/bizar/tests/tools/plan-action.test.ts plugins/bizar/tests/tools/wait-for-feedback.test.ts plugins/bizar/tests/tools/read-glyph-feedback.test.ts plugins/bizar/tests/reasoning-clean.test.ts plugins/bizar/tests/key-rotation.test.ts && node bizar-dash/tests/smoke-v2.mjs && node --test bizar-dash/tests/path-safe.test.mjs bizar-dash/tests/tmux-wrap.test.mjs bizar-dash/tests/opencode-runner.test.mjs bizar-dash/tests/mod-instructions.node.test.mjs bizar-dash/tests/mod-upgrade.node.test.mjs bizar-dash/tests/graphify-mod-spawn.node.test.mjs bizar-dash/tests/no-agent-browser.node.test.mjs bizar-dash/tests/providers-store-backup-keys.node.test.mjs bizar-dash/tests/dashboard-ports.test.mjs bizar-dash/tests/submit-feedback.test.mjs bizar-dash/tests/yaml.test.mjs bizar-dash/tests/memory-store.test.mjs bizar-dash/tests/memory-schema.test.mjs bizar-dash/tests/memory-secrets.test.mjs bizar-dash/tests/memory-git.test.mjs bizar-dash/tests/memory-sync.test.mjs bizar-dash/tests/obsidian-back-compat.test.mjs bizar-dash/tests/memory-lightrag.test.mjs bizar-dash/tests/memory-config.test.mjs bizar-dash/tests/memory-cli.test.mjs",
|
|
24
|
+
"test": "npm run typecheck && npm run test:sdk && bun test plugins/bizar/tests/loop.test.ts plugins/bizar/tests/block.test.ts plugins/bizar/tests/stall-think.test.ts plugins/bizar/tests/tools/bg-get-comments.test.ts plugins/bizar/tests/tools/bg-spawn-delegation.test.ts plugins/bizar/tests/tools/opencode-runner.test.ts plugins/bizar/tests/settings.test.ts plugins/bizar/tests/commands.test.ts plugins/bizar/tests/commands-impl.test.ts plugins/bizar/tests/tools/plan-action.test.ts plugins/bizar/tests/tools/wait-for-feedback.test.ts plugins/bizar/tests/tools/read-glyph-feedback.test.ts plugins/bizar/tests/reasoning-clean.test.ts plugins/bizar/tests/key-rotation.test.ts && node bizar-dash/tests/smoke-v2.mjs && node --test bizar-dash/tests/path-safe.test.mjs bizar-dash/tests/tmux-wrap.test.mjs bizar-dash/tests/opencode-runner.test.mjs bizar-dash/tests/mod-instructions.node.test.mjs bizar-dash/tests/mod-upgrade.node.test.mjs bizar-dash/tests/graphify-mod-spawn.node.test.mjs bizar-dash/tests/no-agent-browser.node.test.mjs bizar-dash/tests/providers-store-backup-keys.node.test.mjs bizar-dash/tests/dashboard-ports.test.mjs bizar-dash/tests/submit-feedback.test.mjs bizar-dash/tests/yaml.test.mjs bizar-dash/tests/memory-store.test.mjs bizar-dash/tests/memory-schema.test.mjs bizar-dash/tests/memory-secrets.test.mjs bizar-dash/tests/memory-git.test.mjs bizar-dash/tests/memory-sync.test.mjs bizar-dash/tests/obsidian-back-compat.test.mjs bizar-dash/tests/memory-lightrag.test.mjs bizar-dash/tests/memory-config.test.mjs bizar-dash/tests/memory-cli.test.mjs bizar-dash/tests/memory-cli-readlistdelete.test.mjs bizar-dash/tests/memory-cli-setup.test.mjs bizar-dash/tests/memory-conflicts.test.mjs bizar-dash/tests/memory-namespace.test.mjs bizar-dash/tests/memory-path-safety.test.mjs bizar-dash/tests/memory-protocol-drift.test.mjs bizar-dash/tests/memory-roundtrip.test.mjs",
|
|
25
25
|
"build": "npm run build:sdk"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|