@pellux/goodvibes-agent 1.6.3 → 1.6.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Product-facing release notes for GoodVibes Agent.
4
4
 
5
+ ## 1.6.4 - 2026-07-07
6
+
7
+ - The exec tool no longer denies destructive- or escalation-class commands (kill, docker, sudo) that the permission configuration allows — class-level risk is decided by permission settings alone. The only remaining unconditional block is a small frozen catastrophic list (root filesystem deletion, raw disk destruction, fork bombs).
8
+
5
9
  ## 1.6.3 - 2026-07-07
6
10
 
7
11
  - SDK 1.4.0 pin: the shared daemon contracts gain server-side companion-chat turn control — a true stop verb (provider stream aborted, honest partial persisted), queue-when-busy sends, and steer (interrupt-and-send-now). No agent-side behavior changes; agent session turns already had lifecycle control on the operator wire.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # GoodVibes Agent
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4
- [![Version: 1.5.3](https://img.shields.io/badge/version-1.6.3-blue.svg)](#install)
4
+ [![Version: 1.5.3](https://img.shields.io/badge/version-1.6.4-blue.svg)](#install)
5
5
 
6
6
  GoodVibes Agent is the installable autonomous operator assistant for GoodVibes. It keeps the existing terminal renderer and workspace bones, but the product goal is different from a vibecoding harness: the user should experience one assistant that can chat, plan, remember, research, schedule, send, generate, run visible agents, and operate the GoodVibes daemon contract with clear confirmation gates.
7
7
 
@@ -4463,7 +4463,7 @@ var init_mcp = __esm(() => {
4463
4463
  // node_modules/@pellux/goodvibes-sdk/dist/platform/version.js
4464
4464
  import { readFileSync as readFileSync3 } from "fs";
4465
4465
  import { join as join4 } from "path";
4466
- var version = "1.4.0", VERSION2;
4466
+ var version = "1.4.1", VERSION2;
4467
4467
  var init_version = __esm(() => {
4468
4468
  try {
4469
4469
  const pkg = JSON.parse(readFileSync3(join4(import.meta.dir, "..", "..", "package.json"), "utf-8"));
@@ -63439,6 +63439,39 @@ function collectCommandNodes(node, acc = []) {
63439
63439
  }
63440
63440
 
63441
63441
  // node_modules/@pellux/goodvibes-sdk/dist/platform/runtime/permissions/normalization/classifier.js
63442
+ function catastrophicReason(seg) {
63443
+ const { command, args: args2, flags: flags2, raw } = seg;
63444
+ const operands = [
63445
+ ...args2,
63446
+ ...seg.tokens.filter((t) => t.type !== "command" && t.type !== "flag").map((t) => t.value)
63447
+ ];
63448
+ if (command === "rm") {
63449
+ if (flags2.includes("--no-preserve-root")) {
63450
+ return "rm --no-preserve-root: destructive root filesystem deletion";
63451
+ }
63452
+ const recursive = flags2.some((f) => f.includes("r") || f === "--recursive");
63453
+ const force = flags2.some((f) => f.includes("f") || f === "--force");
63454
+ if (recursive && force && operands.some((a) => a === "/" || a === "/*")) {
63455
+ return "rm -rf /: destructive root filesystem deletion";
63456
+ }
63457
+ }
63458
+ if (command === "dd" && operands.some((a) => a.startsWith("of=/dev/"))) {
63459
+ return "dd writing to a raw device: destructive disk overwrite";
63460
+ }
63461
+ if (command.startsWith("mkfs") || command === "wipefs") {
63462
+ return `${command}: destructive filesystem/device wipe`;
63463
+ }
63464
+ if (command === "shred" && operands.some((a) => a.startsWith("/dev/"))) {
63465
+ return "shred on a raw device: destructive disk overwrite";
63466
+ }
63467
+ if (raw.includes(":(){") || raw.includes(":|:&")) {
63468
+ return "fork bomb: destructive resource exhaustion";
63469
+ }
63470
+ if (/>\s*\/dev\/(sd|hd|nvme|vd|mmcblk)/.test(raw)) {
63471
+ return "redirect to a raw disk device: destructive disk overwrite";
63472
+ }
63473
+ return null;
63474
+ }
63442
63475
  function higherPriority(a, b) {
63443
63476
  const ai = CLASSIFICATION_PRIORITY.indexOf(a);
63444
63477
  const bi = CLASSIFICATION_PRIORITY.indexOf(b);
@@ -63880,7 +63913,7 @@ No parseable command segments found. Denied as a precaution.`,
63880
63913
  }
63881
63914
  return compound;
63882
63915
  }
63883
- var DEFAULT_ALLOWED_CLASSES, OBFUSCATION_CHECKS, CLASSIFICATION_PRIORITY2, DEFAULT_POLICIES;
63916
+ var DEFAULT_ALLOWED_CLASSES, ALL_COMMAND_CLASSES, OBFUSCATION_CHECKS, CLASSIFICATION_PRIORITY2, DEFAULT_POLICIES;
63884
63917
  var init_verdict = __esm(() => {
63885
63918
  init_classifier();
63886
63919
  DEFAULT_ALLOWED_CLASSES = new Set([
@@ -63888,6 +63921,13 @@ var init_verdict = __esm(() => {
63888
63921
  "write",
63889
63922
  "network"
63890
63923
  ]);
63924
+ ALL_COMMAND_CLASSES = new Set([
63925
+ "read",
63926
+ "write",
63927
+ "network",
63928
+ "destructive",
63929
+ "escalation"
63930
+ ]);
63891
63931
  OBFUSCATION_CHECKS = [
63892
63932
  {
63893
63933
  description: "base64-encoded argument (possible command injection)",
@@ -63930,9 +63970,16 @@ var init_verdict = __esm(() => {
63930
63970
  "read"
63931
63971
  ];
63932
63972
  DEFAULT_POLICIES = [
63933
- (_, cls) => cls === "destructive" ? `segment classified as destructive \u2014 denied by policy` : null,
63934
- (_, cls) => cls === "escalation" ? `segment classified as escalation \u2014 denied by policy` : null,
63935
- (_node, _cls) => null
63973
+ (node, _cls) => {
63974
+ const reason = catastrophicReason({
63975
+ raw: node.raw,
63976
+ tokens: node.tokens,
63977
+ command: node.command,
63978
+ args: node.args,
63979
+ flags: node.flags
63980
+ });
63981
+ return reason === null ? null : `unconditionally blocked destructive command \u2014 ${reason}`;
63982
+ }
63936
63983
  ];
63937
63984
  });
63938
63985
 
@@ -64004,15 +64051,27 @@ var init_normalization = __esm(() => {
64004
64051
  function isASTNormalizationEnabled(flagManager) {
64005
64052
  return flagManager?.isEnabled("shell-ast-normalization") ?? false;
64006
64053
  }
64007
- function baselineGuard(command) {
64054
+ function baselineGuard(command, allowedClasses) {
64008
64055
  const normalized = normalizeCommand(command);
64056
+ for (const seg of normalized.segments) {
64057
+ const reason = catastrophicReason(seg);
64058
+ if (reason !== null) {
64059
+ return {
64060
+ allowed: false,
64061
+ denialMessage: `Command denied (safety block): "${command}"
64062
+ ` + `Unconditionally blocked destructive command \u2014 ${reason}.
64063
+ ` + `This block is not affected by permission settings.`,
64064
+ astModeActive: false
64065
+ };
64066
+ }
64067
+ }
64009
64068
  const cls = normalized.highestClassification;
64010
- if (cls === "destructive" || cls === "escalation") {
64069
+ if (!allowedClasses.has(cls)) {
64011
64070
  return {
64012
64071
  allowed: false,
64013
- denialMessage: `Command denied (baseline mode): "${command}"
64072
+ denialMessage: `Command denied (command-class policy): "${command}"
64014
64073
  ` + `Classification: ${cls}
64015
- ` + `Highest-risk operation in compound command is classified as ${cls}.`,
64074
+ ` + `Classification "${cls}" is not in the caller's allowed set [${[...allowedClasses].join(", ")}].`,
64016
64075
  astModeActive: false
64017
64076
  };
64018
64077
  }
@@ -64039,7 +64098,7 @@ async function guardExecCommand(command, allowedClasses = DEFAULT_ALLOWED_CLASSE
64039
64098
  if (isASTNormalizationEnabled(flagManager)) {
64040
64099
  return astGuard(command, allowedClasses);
64041
64100
  }
64042
- return baselineGuard(command);
64101
+ return baselineGuard(command, allowedClasses);
64043
64102
  }
64044
64103
  function formatDenialResponse(result, cmd) {
64045
64104
  const segmentDetails = result.verdict?.segments.map((s) => ({
@@ -64062,6 +64121,7 @@ var init_ast_guard = __esm(() => {
64062
64121
  init_parser();
64063
64122
  init_verdict();
64064
64123
  init_normalization();
64124
+ init_classifier();
64065
64125
  });
64066
64126
 
64067
64127
  // node_modules/@pellux/goodvibes-sdk/dist/platform/tools/exec/file-ops.js
@@ -64434,7 +64494,7 @@ function handleBgSpecialCommand(processManager, cmd) {
64434
64494
  return processManager.handleCommand(cmd);
64435
64495
  }
64436
64496
  async function runCommand(processManager, overflowHandler, featureFlags, cmdStr, cmdInput, workingDirectory, globalTimeout, signal) {
64437
- const guardResult = await guardExecCommand(cmdStr, DEFAULT_ALLOWED_CLASSES, featureFlags);
64497
+ const guardResult = await guardExecCommand(cmdStr, ALL_COMMAND_CLASSES, featureFlags);
64438
64498
  if (!guardResult.allowed) {
64439
64499
  const denial = formatDenialResponse(guardResult, cmdStr);
64440
64500
  return {
@@ -264004,7 +264064,7 @@ var FOUNDATION_METADATA;
264004
264064
  var init_foundation_metadata = __esm(() => {
264005
264065
  FOUNDATION_METADATA = {
264006
264066
  productId: "goodvibes",
264007
- productVersion: "1.4.0",
264067
+ productVersion: "1.4.1",
264008
264068
  operatorMethodCount: 329,
264009
264069
  operatorEventCount: 31,
264010
264070
  peerEndpointCount: 6
@@ -264019,7 +264079,7 @@ var init_operator_contract = __esm(() => {
264019
264079
  product: {
264020
264080
  id: "goodvibes",
264021
264081
  surface: "operator",
264022
- version: "1.4.0"
264082
+ version: "1.4.1"
264023
264083
  },
264024
264084
  auth: {
264025
264085
  modes: [
@@ -464542,23 +464602,6 @@ function createSchema2(db) {
464542
464602
  )
464543
464603
  `);
464544
464604
  }
464545
- function getKnowledgeSchemaStatements() {
464546
- const statements = [];
464547
- createSchema2({
464548
- run(sql) {
464549
- const normalized = sql.trim();
464550
- if (normalized.length > 0)
464551
- statements.push(normalized);
464552
- }
464553
- });
464554
- return statements;
464555
- }
464556
- function renderKnowledgeSchemaSql() {
464557
- return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
464558
-
464559
- `)}
464560
- `;
464561
- }
464562
464605
  function rowObject(columns, values2) {
464563
464606
  return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
464564
464607
  }
@@ -777931,9 +777974,6 @@ var init_ingest = __esm(() => {
777931
777974
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
777932
777975
  var init_browser_history = __esm(() => {
777933
777976
  init_ingest();
777934
- init_discover();
777935
- init_readers();
777936
- init_paths2();
777937
777977
  });
777938
777978
 
777939
777979
  // node_modules/graphql/jsutils/devAssert.mjs
@@ -795808,7 +795848,6 @@ var init_semantic = __esm(() => {
795808
795848
  init_llm();
795809
795849
  init_gap_repair();
795810
795850
  init_service5();
795811
- init_self_improvement();
795812
795851
  });
795813
795852
 
795814
795853
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
@@ -799777,40 +799816,8 @@ var init_map_view = __esm(() => {
799777
799816
  });
799778
799817
 
799779
799818
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
799780
- var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
799819
+ var HOME_GRAPH_CAPABILITIES;
799781
799820
  var init_types15 = __esm(() => {
799782
- HOME_GRAPH_NODE_KINDS = [
799783
- "ha_home",
799784
- "ha_entity",
799785
- "ha_device",
799786
- "ha_area",
799787
- "ha_automation",
799788
- "ha_script",
799789
- "ha_scene",
799790
- "ha_label",
799791
- "ha_integration",
799792
- "ha_room",
799793
- "ha_device_passport",
799794
- "ha_maintenance_item",
799795
- "ha_troubleshooting_case",
799796
- "ha_purchase",
799797
- "ha_network_node"
799798
- ];
799799
- HOME_GRAPH_RELATIONS = [
799800
- "controls",
799801
- "located_in",
799802
- "belongs_to_device",
799803
- "has_manual",
799804
- "has_receipt",
799805
- "has_warranty",
799806
- "has_issue",
799807
- "fixed_by",
799808
- "uses_battery",
799809
- "connected_via",
799810
- "part_of_network",
799811
- "mentioned_by",
799812
- "source_for"
799813
- ];
799814
799821
  HOME_GRAPH_CAPABILITIES = [
799815
799822
  "knowledge-space-isolation",
799816
799823
  "snapshot-sync",
@@ -801601,7 +801608,6 @@ var init_service6 = __esm(() => {
801601
801608
  var init_home_graph = __esm(() => {
801602
801609
  init_service6();
801603
801610
  init_extension();
801604
- init_types15();
801605
801611
  });
801606
801612
 
801607
801613
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-record-delete.js
@@ -804026,14 +804032,10 @@ var init_service7 = __esm(() => {
804026
804032
  var init_project_planning = __esm(() => {
804027
804033
  init_service7();
804028
804034
  init_helpers3();
804029
- init_readiness();
804030
804035
  });
804031
804036
 
804032
804037
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
804033
- var init_persistence = __esm(() => {
804034
- init_store_schema();
804035
- init_store_load();
804036
- });
804038
+ var init_persistence = () => {};
804037
804039
 
804038
804040
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
804039
804041
  class KnowledgeProjectionService {
@@ -807587,21 +807589,21 @@ var init_service8 = __esm(() => {
807587
807589
  var exports_knowledge = {};
807588
807590
  __export(exports_knowledge, {
807589
807591
  withKnowledgeSpace: () => withKnowledgeSpace,
807590
- uniqKnowledgeValues: () => uniq2,
807591
- stabilizeKnowledgeText: () => stableText,
807592
- runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
807592
+ uniqKnowledgeValues: () => uniq3,
807593
+ stabilizeKnowledgeText: () => stableText2,
807594
+ runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement2,
807593
807595
  resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
807594
- resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
807596
+ resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir2,
807595
807597
  renderPacket: () => renderPacket,
807596
807598
  renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
807597
807599
  renderKnowledgeMap: () => renderKnowledgeMap,
807598
807600
  readKnowledgeSearchText: () => readKnowledgeSearchText,
807599
- readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
807601
+ readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile2,
807600
807602
  projectPlanningSourceId: () => projectPlanningSourceId,
807601
807603
  projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
807602
807604
  projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
807603
807605
  projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
807604
- parseKnowledgeJsonValue: () => parseJsonValue,
807606
+ parseKnowledgeJsonValue: () => parseJsonValue2,
807605
807607
  normalizeProjectId: () => normalizeProjectId,
807606
807608
  normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
807607
807609
  normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
@@ -807609,12 +807611,12 @@ __export(exports_knowledge, {
807609
807611
  materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
807610
807612
  looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
807611
807613
  looksBinaryLikeText: () => looksBinaryLikeText,
807612
- loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
807614
+ loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot2,
807613
807615
  listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
807614
- listBrowserKinds: () => listBrowserKinds,
807616
+ listBrowserKinds: () => listBrowserKinds2,
807615
807617
  knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
807616
807618
  knowledgePageSourceWeight: () => knowledgePageSourceWeight,
807617
- knowledgeNowMs: () => nowMs,
807619
+ knowledgeNowMs: () => nowMs2,
807618
807620
  knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
807619
807621
  isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
807620
807622
  isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
@@ -807634,12 +807636,12 @@ __export(exports_knowledge, {
807634
807636
  generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
807635
807637
  generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
807636
807638
  extractKnowledgeArtifact: () => extractKnowledgeArtifact,
807637
- evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
807638
- discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
807639
+ evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness2,
807640
+ discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles2,
807639
807641
  createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
807640
807642
  createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
807641
807643
  createMemoryApi: () => createMemoryApi,
807642
- createKnowledgeSchema: () => createSchema2,
807644
+ createKnowledgeSchema: () => createSchema3,
807643
807645
  createKnowledgeApi: () => createKnowledgeApi,
807644
807646
  createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
807645
807647
  compareKnowledgePageSources: () => compareKnowledgePageSources,
@@ -810112,7 +810114,7 @@ var init_delivery_manager = __esm(() => {
810112
810114
  });
810113
810115
 
810114
810116
  // node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
810115
- function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
810117
+ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
810116
810118
  let slotsInUse = 0;
810117
810119
  const queuedRuns = [];
810118
810120
  for (const run7 of runs) {
@@ -810122,7 +810124,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
810122
810124
  queuedRuns.push(run7);
810123
810125
  }
810124
810126
  const queueDepth = queuedRuns.length;
810125
- const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
810127
+ const oldestQueuedAgeMs = queueDepth > 0 ? nowMs3 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
810126
810128
  return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
810127
810129
  }
810128
810130
 
@@ -837618,7 +837620,7 @@ var createStyledCell = (char, overrides = {}) => ({
837618
837620
  // src/version.ts
837619
837621
  import { readFileSync } from "fs";
837620
837622
  import { join } from "path";
837621
- var _version = "1.6.3";
837623
+ var _version = "1.6.4";
837622
837624
  try {
837623
837625
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
837624
837626
  _version = typeof pkg.version === "string" ? pkg.version : _version;
@@ -862775,7 +862777,7 @@ var WORK_PLAN_STATUSES = [
862775
862777
  "failed",
862776
862778
  "cancelled"
862777
862779
  ];
862778
- function nowMs2() {
862780
+ function nowMs3() {
862779
862781
  return Date.now();
862780
862782
  }
862781
862783
  function isObject4(value) {
@@ -862881,7 +862883,7 @@ class WorkPlanStore {
862881
862883
  if (!normalizedTitle)
862882
862884
  throw new Error("Work plan item title is required.");
862883
862885
  const plan = this.readPlan();
862884
- const time4 = nowMs2();
862886
+ const time4 = nowMs3();
862885
862887
  const item = {
862886
862888
  id: createItemId(),
862887
862889
  title: normalizedTitle,
@@ -862905,7 +862907,7 @@ class WorkPlanStore {
862905
862907
  updateItem(idOrPrefix, patch2) {
862906
862908
  const plan = this.readPlan();
862907
862909
  const item = this.resolveItem(plan, idOrPrefix);
862908
- const time4 = nowMs2();
862910
+ const time4 = nowMs3();
862909
862911
  const nextStatus = patch2.status ?? item.status;
862910
862912
  const next = this.pruneItem({
862911
862913
  ...item,
@@ -862938,7 +862940,7 @@ class WorkPlanStore {
862938
862940
  removeItem(idOrPrefix) {
862939
862941
  const plan = this.readPlan();
862940
862942
  const item = this.resolveItem(plan, idOrPrefix);
862941
- const time4 = nowMs2();
862943
+ const time4 = nowMs3();
862942
862944
  const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
862943
862945
  this.writePlan({
862944
862946
  ...plan,
@@ -862958,7 +862960,7 @@ class WorkPlanStore {
862958
862960
  ...plan,
862959
862961
  items: remaining,
862960
862962
  activeItemId: remaining[0]?.id,
862961
- updatedAt: nowMs2()
862963
+ updatedAt: nowMs3()
862962
862964
  });
862963
862965
  return removed;
862964
862966
  }
@@ -862997,7 +862999,7 @@ class WorkPlanStore {
862997
862999
  const parsed = JSON.parse(raw);
862998
863000
  if (!isObject4(parsed))
862999
863001
  return this.createEmptyPlan();
863000
- const time4 = nowMs2();
863002
+ const time4 = nowMs3();
863001
863003
  const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
863002
863004
  const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
863003
863005
  const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
@@ -863016,7 +863018,7 @@ class WorkPlanStore {
863016
863018
  };
863017
863019
  }
863018
863020
  createEmptyPlan() {
863019
- const time4 = nowMs2();
863021
+ const time4 = nowMs3();
863020
863022
  return {
863021
863023
  id: createPlanId(this.options.projectId, this.options.projectRoot),
863022
863024
  projectId: this.options.projectId,
@@ -974831,8 +974833,8 @@ function formatDigestTime(at, from = Date.now()) {
974831
974833
  return `yesterday ${time4}`;
974832
974834
  return `${d4.toLocaleDateString(undefined, { month: "short", day: "numeric" })} ${time4}`;
974833
974835
  }
974834
- function formatRelativeTime(targetMs, nowMs3 = Date.now()) {
974835
- const diffMs = targetMs - nowMs3;
974836
+ function formatRelativeTime(targetMs, nowMs4 = Date.now()) {
974837
+ const diffMs = targetMs - nowMs4;
974836
974838
  if (diffMs <= 0)
974837
974839
  return "soon";
974838
974840
  const diffMin = Math.round(diffMs / 60000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -92,7 +92,7 @@
92
92
  },
93
93
  "dependencies": {},
94
94
  "devDependencies": {
95
- "@pellux/goodvibes-sdk": "1.4.0",
95
+ "@pellux/goodvibes-sdk": "1.4.1",
96
96
  "sql.js": "^1.14.1",
97
97
  "sqlite-vec": "^0.1.9",
98
98
  "zustand": "^5.0.12",
package/src/version.ts CHANGED
@@ -6,7 +6,7 @@ import { join } from 'node:path';
6
6
  // The prebuild script updates the fallback value before compilation.
7
7
  // Uses import.meta.dir (Bun) to locate package.json relative to this file,
8
8
  // which is correct regardless of the process working directory.
9
- let _version = '1.6.3';
9
+ let _version = '1.6.4';
10
10
  try {
11
11
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
12
12
  readonly version?: unknown;