@tekmidian/pai 0.12.0 → 0.12.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.
@@ -6,7 +6,7 @@ import { n as openFederation } from "./db-CmYbAVCD.mjs";
6
6
  import { n as populateSlugs, r as searchMemory } from "./search-HcdKtMla.mjs";
7
7
  import { n as formatDetection, r as formatDetectionJson, t as detectProject } from "./detect-KjycLtXM.mjs";
8
8
  import { a as resolveHome, c as upsertSession, n as cmdScan, o as saveScanConfig, r as loadScanConfig, s as upsertProject, t as extractAndStoreTriples } from "./kg-extraction-C8DEUHTS.mjs";
9
- import { t as createStorageBackend } from "./factory-CayQCMoN.mjs";
9
+ import { t as createStorageBackend } from "./factory-Q88X1bAN.mjs";
10
10
  import { t as PaiClient } from "./ipc-client-CoyUHPod.mjs";
11
11
  import { a as expandHome, i as ensureConfigDir, n as CONFIG_FILE$2, o as loadConfig, t as CONFIG_DIR } from "./config-BuhHWyOK.mjs";
12
12
  import { s as kgQuery } from "./kg-entity-LXblD7LZ.mjs";
@@ -904,15 +904,15 @@ function cmdNames(db, opts) {
904
904
  (SELECT COUNT(*) FROM sessions s WHERE s.project_id = p.id) AS session_count,
905
905
  (SELECT MAX(s.created_at) FROM sessions s WHERE s.project_id = p.id) AS last_active
906
906
  FROM projects p
907
- JOIN aliases a ON a.project_id = p.id
907
+ ${opts.all ? "LEFT JOIN" : "JOIN"} aliases a ON a.project_id = p.id
908
908
  WHERE p.status = 'active'
909
909
  ORDER BY p.updated_at DESC
910
910
  `).all();
911
911
  if (opts.json) {
912
912
  const grouped = /* @__PURE__ */ new Map();
913
913
  for (const row of rows) if (!grouped.has(row.id)) grouped.set(row.id, {
914
- name: row.name,
915
- names: [row.name],
914
+ name: row.name ?? row.slug,
915
+ names: row.name ? [row.name] : [],
916
916
  slug: row.slug,
917
917
  display_name: row.display_name,
918
918
  root_path: row.root_path,
@@ -920,7 +920,7 @@ function cmdNames(db, opts) {
920
920
  last_active: row.last_active ? new Date(row.last_active).toISOString() : null,
921
921
  session_config: row.session_config ? JSON.parse(row.session_config) : null
922
922
  });
923
- else grouped.get(row.id).names.push(row.name);
923
+ else if (row.name) grouped.get(row.id).names.push(row.name);
924
924
  console.log(JSON.stringify([...grouped.values()], null, 2));
925
925
  return;
926
926
  }
@@ -933,10 +933,10 @@ function cmdNames(db, opts) {
933
933
  for (const row of rows) {
934
934
  if (seen.has(row.id)) continue;
935
935
  seen.add(row.id);
936
- const allNames = rows.filter((r) => r.id === row.id).map((r) => r.name);
936
+ const allNames = rows.filter((r) => r.id === row.id).map((r) => r.name).filter(Boolean);
937
937
  const perm = (row.session_config ? JSON.parse(row.session_config) : null)?.permission ?? dim("default");
938
938
  tableRows.push([
939
- bold(allNames.join(", ")),
939
+ bold(allNames.length ? allNames.join(", ") : row.slug),
940
940
  row.slug,
941
941
  dim(shortenPath(row.root_path, 40)),
942
942
  typeof perm === "string" ? perm : dim("default"),
@@ -1367,7 +1367,7 @@ function registerProjectsCommands(projectsCmd, getDb) {
1367
1367
  projectsCmd.command("unname <shortname>").description("Remove a project's short name").action((shortname) => {
1368
1368
  cmdUnname(getDb(), shortname);
1369
1369
  });
1370
- projectsCmd.command("names").description("List named projects (your curated shortlist)").option("--json", "Output JSON for AIBroker consumption").action((opts) => {
1370
+ projectsCmd.command("names").description("List named projects (your curated shortlist)").option("--json", "Output JSON for AIBroker consumption").option("--all", "Include ALL active registered projects, not just the named shortlist").action((opts) => {
1371
1371
  cmdNames(getDb(), opts);
1372
1372
  });
1373
1373
  projectsCmd.command("config [identifier]").description("View or modify session launch config for a project.\nUse --options to discover available keys and presets.").option("--set <key=value...>", "Set config values (repeatable)", (v, prev) => [...prev, v], []).option("--unset <key...>", "Remove config keys (repeatable, use env.KEY for env vars)", (v, prev) => [...prev, v], []).option("--preset <name>", "Apply a permission preset: full | trusted | default").option("--defaults", "Manage global session defaults instead of a project").option("--options", "List available config keys and presets").option("--json", "Output JSON").option("--reset", "Reset config to empty (inherit global defaults)").action((identifier, opts) => {
@@ -2259,7 +2259,7 @@ function cmdLogs(opts) {
2259
2259
  }
2260
2260
  function registerDaemonCommands(daemonCmd) {
2261
2261
  daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
2262
- const { serve } = await import("./daemon-DDplhnm9.mjs").then((n) => n.t);
2262
+ const { serve } = await import("./daemon-Ca7YXHUW.mjs").then((n) => n.t);
2263
2263
  const { loadConfig: lc, ensureConfigDir } = await import("./config-BuhHWyOK.mjs").then((n) => n.r);
2264
2264
  ensureConfigDir();
2265
2265
  await serve(lc());
@@ -4403,8 +4403,23 @@ function removeOldBacklink(filePath) {
4403
4403
  }
4404
4404
  }
4405
4405
  /**
4406
+ * Return true if the note has a meaningful body — i.e. content beyond blank
4407
+ * lines, horizontal rules, and an existing master-note footer.
4408
+ *
4409
+ * Guards against stamping a "← Master" backlink onto an empty note, which
4410
+ * produces a misleading dangling stub (empty body + footer only). Whatever
4411
+ * emptied the note, we must not decorate it as if it were a real session.
4412
+ */
4413
+ function hasMeaningfulBody(content) {
4414
+ return content.replace(/\n---\n\[\[_[^\]]*-master\|[^\]]*\]\]\n?$/, "").split("\n").filter((line) => {
4415
+ const t = line.trim();
4416
+ return t !== "" && t !== "---";
4417
+ }).join("").length > 0;
4418
+ }
4419
+ /**
4406
4420
  * Append the master note backlink footer to a session file, idempotently.
4407
- * Only writes if the sentinel string is not already present.
4421
+ * Only writes if the sentinel string is not already present AND the note has
4422
+ * a meaningful body (never stamp a footer onto an empty note).
4408
4423
  */
4409
4424
  function appendBacklinkIfMissing(filePath, slug, displayName) {
4410
4425
  let content;
@@ -4413,6 +4428,7 @@ function appendBacklinkIfMissing(filePath, slug, displayName) {
4413
4428
  } catch {
4414
4429
  return false;
4415
4430
  }
4431
+ if (!hasMeaningfulBody(content)) return false;
4416
4432
  const masterName = masterFilename(slug).replace(/\.md$/, "");
4417
4433
  const sentinel = `[[${masterName}|`;
4418
4434
  if (content.includes(sentinel)) return false;
@@ -8247,4 +8263,4 @@ async function cmdPick(db, opts = {}) {
8247
8263
 
8248
8264
  //#endregion
8249
8265
  export { registerMcpCommands as C, findMovedPath as D, registerProjectsCommands as E, resolveIdentifier as O, registerDaemonCommands as S, registerRegistryCommands as T, registerZettelCommands as _, cmdPauseAll as a, registerRestoreCommands as b, cmdPause as c, registerKgCommands as d, registerTopicCommands as f, registerObservationCommands as g, registerSkillCommands as h, cmdClearNames as i, registerHelpCommand as l, registerUpdateCommand as m, cmdFind as n, cmdGoto as o, registerNotifyCommands as p, cmdList as r, cmdEnd as s, cmdPick as t, registerDbCommands as u, registerObsidianCommands as v, registerMemoryCommands as w, registerBackupCommands as x, registerSetupCommand as y };
8250
- //# sourceMappingURL=pick-Dt21ojcW.mjs.map
8266
+ //# sourceMappingURL=pick-C5sUQ5g_.mjs.map