nodal-agents 0.8.7 → 0.8.8

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.
Files changed (142) hide show
  1. package/README.md +1 -1
  2. package/cli.js +85 -5
  3. package/package.json +1 -1
  4. package/runner.js +527 -146
  5. package/web/.next/BUILD_ID +1 -1
  6. package/web/.next/app-path-routes-manifest.json +1 -1
  7. package/web/.next/build-manifest.json +2 -2
  8. package/web/.next/prerender-manifest.json +3 -3
  9. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page.js +1 -1
  10. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page_client-reference-manifest.js +1 -1
  11. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +2 -2
  12. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  13. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +1 -1
  14. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  15. package/web/.next/server/app/(dashboard)/agents/page.js +1 -1
  16. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  17. package/web/.next/server/app/(dashboard)/approvals/page.js +1 -1
  18. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  19. package/web/.next/server/app/(dashboard)/automations/page.js +1 -1
  20. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  21. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  22. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/code/[id]/page.js +1 -1
  24. package/web/.next/server/app/(dashboard)/code/[id]/page_client-reference-manifest.js +1 -1
  25. package/web/.next/server/app/(dashboard)/code/page.js +1 -1
  26. package/web/.next/server/app/(dashboard)/code/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
  28. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
  30. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +1 -1
  32. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/jobs/page.js +1 -1
  34. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/learned-skills/page.js +1 -1
  36. package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
  38. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/logs/page.js +1 -1
  40. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
  42. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/memories/page.js +1 -1
  44. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/page.js +2 -2
  46. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/(dashboard)/settings/page.js +1 -1
  48. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/settings/root-context/page.js +1 -1
  50. package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +1 -1
  52. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  53. package/web/.next/server/app/(dashboard)/skills/new/page.js +1 -1
  54. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
  56. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/_global-error.html +1 -1
  59. package/web/.next/server/app/_global-error.rsc +2 -2
  60. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  61. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +2 -2
  62. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  63. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/_not-found.html +1 -1
  65. package/web/.next/server/app/_not-found.rsc +2 -2
  66. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  67. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  68. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  69. package/web/.next/server/app/login/page.js +1 -1
  70. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/onboarding/page.js +2 -2
  72. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app-paths-manifest.json +1 -1
  74. package/web/.next/server/chunks/{7650.js → 1721.js} +5 -5
  75. package/web/.next/server/chunks/{7251.js → 1824.js} +1 -1
  76. package/web/.next/server/chunks/196.js +1 -0
  77. package/web/.next/server/chunks/2009.js +1 -0
  78. package/web/.next/server/chunks/210.js +1 -1
  79. package/web/.next/server/chunks/3927.js +3 -3
  80. package/web/.next/server/chunks/42.js +2 -2
  81. package/web/.next/server/chunks/5384.js +1 -1
  82. package/web/.next/server/chunks/{4869.js → 6484.js} +1 -1
  83. package/web/.next/server/chunks/7915.js +1 -0
  84. package/web/.next/server/chunks/8447.js +1 -1
  85. package/web/.next/server/chunks/9949.js +8 -8
  86. package/web/.next/server/middleware-build-manifest.js +1 -1
  87. package/web/.next/server/middleware.js +4 -4
  88. package/web/.next/server/pages/404.html +1 -1
  89. package/web/.next/server/pages/500.html +1 -1
  90. package/web/.next/server/server-reference-manifest.js +1 -1
  91. package/web/.next/server/server-reference-manifest.json +1 -1
  92. package/web/.next/static/chunks/{6306-6448703d936feed3.js → 3451-58a5c57e79371ae4.js} +2 -2
  93. package/web/.next/static/chunks/{5034-df0e39b679214174.js → 5034-e249414dc457d97d.js} +1 -1
  94. package/web/.next/static/chunks/{6646-60db74d7d175dba0.js → 6646-35d756ba2c002ecf.js} +1 -1
  95. package/web/.next/static/chunks/{2515-a9fd443091bb4291.js → 6967-3b77488c4b708136.js} +1 -1
  96. package/web/.next/static/chunks/{9416-baf32aa3deceb0ed.js → 9416-391f60c712340297.js} +1 -1
  97. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-dd6460b3a050ddf7.js +6 -0
  98. package/web/.next/static/chunks/app/(dashboard)/agents/page-04ac243f09f1f620.js +1 -0
  99. package/web/.next/static/chunks/app/(dashboard)/approvals/{page-a752b0ddc39d34f4.js → page-dfd4cf86827c0aed.js} +1 -1
  100. package/web/.next/static/chunks/app/(dashboard)/automations/page-0e724dfa1716a937.js +1 -0
  101. package/web/.next/static/chunks/app/(dashboard)/chat/page-041eedb2e6cf29fb.js +1 -0
  102. package/web/.next/static/chunks/app/(dashboard)/code/page-ac3a349d07d95fd9.js +1 -0
  103. package/web/.next/static/chunks/app/(dashboard)/connectors/page-0f39f3e59541badf.js +1 -0
  104. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-1719a805a2e39ccc.js +1 -0
  105. package/web/.next/static/chunks/app/(dashboard)/jobs/page-129c4cd41458438a.js +1 -0
  106. package/web/.next/static/chunks/app/(dashboard)/layout-1602118a43db0d42.js +1 -0
  107. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-16a376c609001dd2.js +1 -0
  108. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-7bd5a6f909d8a136.js +1 -0
  109. package/web/.next/static/chunks/app/(dashboard)/logs/page-a2d32cf8ffa4d4a6.js +1 -0
  110. package/web/.next/static/chunks/app/(dashboard)/mcp/page-86fac62ecfc87b98.js +1 -0
  111. package/web/.next/static/chunks/app/(dashboard)/memories/page-bd61659f6bbccb21.js +1 -0
  112. package/web/.next/static/chunks/app/(dashboard)/{page-8b3f80ee2f3d8c11.js → page-70ea130d3de66e30.js} +1 -1
  113. package/web/.next/static/chunks/app/(dashboard)/settings/page-2fec30e99b307637.js +1 -0
  114. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-5a7dae2d7e9ce07f.js +1 -0
  115. package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/{page-b8e71ad3ef0b27d4.js → page-c22bde781a44b751.js} +1 -1
  116. package/web/.next/static/chunks/app/(dashboard)/skills/new/{page-0d777140d4c73ad8.js → page-0e8b89dc355078a8.js} +1 -1
  117. package/web/.next/static/chunks/app/(dashboard)/skills/page-93884e1ef158297f.js +1 -0
  118. package/web/.next/static/chunks/app/login/page-7303a5eca7eeb19b.js +1 -0
  119. package/web/.next/static/chunks/app/onboarding/{page-0145253536f365ee.js → page-0ec8d988ee84bdb1.js} +2 -2
  120. package/web/.next/server/chunks/2834.js +0 -1
  121. package/web/.next/server/chunks/3666.js +0 -1
  122. package/web/.next/server/chunks/3756.js +0 -1
  123. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-42261de6e1de3f0d.js +0 -6
  124. package/web/.next/static/chunks/app/(dashboard)/agents/page-b028af9e30e8fb83.js +0 -1
  125. package/web/.next/static/chunks/app/(dashboard)/automations/page-521ded8178a4513f.js +0 -1
  126. package/web/.next/static/chunks/app/(dashboard)/chat/page-1042ea3f25d7b430.js +0 -1
  127. package/web/.next/static/chunks/app/(dashboard)/code/page-b72af9e2731d0bb1.js +0 -1
  128. package/web/.next/static/chunks/app/(dashboard)/connectors/page-8a1993ba5a7ba872.js +0 -1
  129. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-522a1f164f88f89b.js +0 -1
  130. package/web/.next/static/chunks/app/(dashboard)/jobs/page-15d22e17291edb01.js +0 -1
  131. package/web/.next/static/chunks/app/(dashboard)/layout-09b1990c5a3a9a09.js +0 -1
  132. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-93aa992e100c0b5a.js +0 -1
  133. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-d121748077e7c685.js +0 -1
  134. package/web/.next/static/chunks/app/(dashboard)/logs/page-e4b6136ecf9ccd14.js +0 -1
  135. package/web/.next/static/chunks/app/(dashboard)/mcp/page-b762d306176a4851.js +0 -1
  136. package/web/.next/static/chunks/app/(dashboard)/memories/page-de710d983bae276e.js +0 -1
  137. package/web/.next/static/chunks/app/(dashboard)/settings/page-977685a40ec1a2f2.js +0 -1
  138. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-db8f2599cc9771e1.js +0 -1
  139. package/web/.next/static/chunks/app/(dashboard)/skills/page-127e5d5374a4bb2a.js +0 -1
  140. package/web/.next/static/chunks/app/login/page-8d873e8ff103a226.js +0 -1
  141. /package/web/.next/static/{FW6WAOvY3tiwZHzAR2ZUZ → Ox1nSNbTz9Sz93pV6rEcD}/_buildManifest.js +0 -0
  142. /package/web/.next/static/{FW6WAOvY3tiwZHzAR2ZUZ → Ox1nSNbTz9Sz93pV6rEcD}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -46,7 +46,7 @@ Every agent runs on the model **you** choose, with the tools **you** grant, in a
46
46
  ### 🏠 Own your whole stack
47
47
 
48
48
  - **Local-first** — single command, embedded Postgres, zero cloud dependency.
49
- - **Your data & keys** — conversations, memory, and credentials never leave your machine; API keys are AES-256-GCM encrypted at rest.
49
+ - **Your data & keys** — conversations, memory, and credentials never leave your machine, and every credential is AES-256-GCM encrypted at rest: API keys, OAuth tokens, MCP server secrets, the bot tokens of every messaging channel, and your webhook secrets.
50
50
  - **Workspaces** — multiple isolated workspaces on one install (personal vs work), each with its own agents, skills, connectors, jobs, and memory.
51
51
  - **No markup** — bring your own API keys; you pay the provider directly, nothing on top.
52
52
 
package/cli.js CHANGED
@@ -13085,6 +13085,33 @@ var init_model_catalog = __esm({
13085
13085
  contextWindow: 1048576,
13086
13086
  pricing: { inputPerMillionUsd: 1.4, outputPerMillionUsd: 4.4 }
13087
13087
  },
13088
+ {
13089
+ modelId: "z-ai/glm-5.3-flash",
13090
+ label: "GLM 5.3 Flash",
13091
+ // The cheap, fast sibling of 5.3 — ~19x cheaper in, ~18x cheaper out,
13092
+ // and a LARGER context (1.31M vs 1.05M). Two real differences from the
13093
+ // full 5.3, both read off OpenRouter's /api/v1/models on 2026-08-28:
13094
+ // - it is MULTIMODAL (input_modalities: text, image, video) where 5.3
13095
+ // is text-only, so it is in VISION_MODEL_IDS below;
13096
+ // - reasoning is supported (`reasoning`, `reasoning_effort` are in
13097
+ // supported_parameters) but NOT mandatory the way 5.2/5.3's is —
13098
+ // nothing upstream says this one always thinks, so 'off' stays on
13099
+ // the UI scale rather than being hidden on a guess.
13100
+ // forcedToolChoice:false follows the family posture: `tool_choice` is
13101
+ // accepted, but nothing states 'required' is honoured, and the runtime
13102
+ // tool_choice floor relaxes it anyway.
13103
+ capabilities: {
13104
+ tools: true,
13105
+ forcedToolChoice: false,
13106
+ reasoning: true,
13107
+ reasoningControl: {
13108
+ kind: "effort",
13109
+ levels: ["low", "medium", "high", "max"]
13110
+ }
13111
+ },
13112
+ contextWindow: 1310720,
13113
+ pricing: { inputPerMillionUsd: 0.075, outputPerMillionUsd: 0.25 }
13114
+ },
13088
13115
  // Moonshot (Kimi)
13089
13116
  {
13090
13117
  modelId: "moonshotai/kimi-k2.6",
@@ -13242,6 +13269,10 @@ var init_model_catalog = __esm({
13242
13269
  "openai/gpt-5.6-luna-pro",
13243
13270
  "openai/gpt-5.6-terra-pro",
13244
13271
  "qwen/qwen3.8-max",
13272
+ // Verified via OpenRouter /api/v1/models input_modalities on 2026-08-28:
13273
+ // z-ai/glm-5.3-flash reports ["text","image","video"]. The full z-ai/glm-5.3
13274
+ // reports ["text"] only and is deliberately NOT in this set.
13275
+ "z-ai/glm-5.3-flash",
13245
13276
  // Verified via OpenRouter /api/v1/models input_modalities (2026-07-20).
13246
13277
  // qwen/qwen3.7-max is deliberately absent — text-only per the same source.
13247
13278
  "x-ai/grok-4.5",
@@ -15604,6 +15635,17 @@ async function assertMasterKeyRestorable(db, options = {}) {
15604
15635
  return Object.values(env).some((v) => typeof v === "string" && isEncrypted(v));
15605
15636
  });
15606
15637
  if (hasEncryptedMcp) throw missingKeyError("a stored MCP server secret");
15638
+ const bindingRows = await db.select({ credentials: channelBindings.credentials }).from(channelBindings);
15639
+ const hasEncryptedBinding = bindingRows.some(
15640
+ (r) => !!r.credentials && isEncrypted(r.credentials)
15641
+ );
15642
+ if (hasEncryptedBinding) throw missingKeyError("a stored channel credential");
15643
+ const agentRows = await db.select({ botToken: agents.telegramBotToken }).from(agents);
15644
+ const hasEncryptedBotToken = agentRows.some((r) => !!r.botToken && isEncrypted(r.botToken));
15645
+ if (hasEncryptedBotToken) throw missingKeyError("a stored channel credential (bot token)");
15646
+ const webhookRows = await db.select({ secret: webhookTriggers.secret }).from(webhookTriggers);
15647
+ const hasEncryptedWebhookSecret = webhookRows.some((r) => !!r.secret && isEncrypted(r.secret));
15648
+ if (hasEncryptedWebhookSecret) throw missingKeyError("a stored webhook secret");
15607
15649
  }
15608
15650
  function missingKeyError(what) {
15609
15651
  return new Error(
@@ -15617,11 +15659,15 @@ var init_master_key_guard = __esm({
15617
15659
  init_llm_keys();
15618
15660
  init_connectors();
15619
15661
  init_mcp();
15662
+ init_channel_bindings();
15663
+ init_agents();
15664
+ init_webhooks();
15620
15665
  init_src3();
15621
15666
  }
15622
15667
  });
15623
15668
 
15624
15669
  // ../../packages/db/src/queries/channel-identity.ts
15670
+ import { createHash } from "crypto";
15625
15671
  async function resolveOwnerConversation(db, agentId, channel) {
15626
15672
  if (channel === "telegram") {
15627
15673
  const [row2] = await db.select({ chatId: telegramAllowedChats.chatId }).from(telegramAllowedChats).where(
@@ -15677,15 +15723,44 @@ async function getChannelBinding(db, agentId, channel) {
15677
15723
  async function listChannelBindings(db, agentId) {
15678
15724
  return db.select().from(channelBindings).where(eq(channelBindings.agentId, agentId));
15679
15725
  }
15726
+ function decryptChannelSecret(raw, what) {
15727
+ if (!isEncrypted(raw)) return raw;
15728
+ try {
15729
+ return decrypt(raw);
15730
+ } catch (err) {
15731
+ throw new Error(
15732
+ `failed to decrypt ${what}: ${err instanceof Error ? err.message : String(err)}. The master key at ~/.nodalai/secrets.key does not match the one this row was written with (restored backup? copied database?). Re-enter the credential from the dashboard to re-encrypt it under the current key.`
15733
+ );
15734
+ }
15735
+ }
15736
+ function encryptChannelCredentials(creds) {
15737
+ return encrypt(JSON.stringify(creds));
15738
+ }
15739
+ function encryptChannelSecret(plaintext) {
15740
+ return isEncrypted(plaintext) ? plaintext : encrypt(plaintext);
15741
+ }
15742
+ function credentialsFingerprint(creds) {
15743
+ const canonical = JSON.stringify(
15744
+ Object.keys(creds).sort().map((k) => [k, creds[k]])
15745
+ );
15746
+ return createHash("sha256").update(canonical).digest("hex");
15747
+ }
15680
15748
  async function getBindingCredentials(db, agentId, channel) {
15681
15749
  if (channel === "telegram") {
15682
15750
  const [row] = await db.select({ botToken: agents.telegramBotToken }).from(agents).where(eq(agents.id, agentId)).limit(1);
15683
- return row?.botToken ? { botToken: row.botToken } : null;
15751
+ if (!row?.botToken) return null;
15752
+ return {
15753
+ botToken: decryptChannelSecret(row.botToken, `telegram bot token (agent ${agentId})`)
15754
+ };
15684
15755
  }
15685
15756
  const binding = await getChannelBinding(db, agentId, channel);
15686
15757
  if (!binding) return null;
15758
+ const json2 = decryptChannelSecret(
15759
+ binding.credentials,
15760
+ `${channel} credentials (agent ${agentId})`
15761
+ );
15687
15762
  try {
15688
- const parsed = JSON.parse(binding.credentials);
15763
+ const parsed = JSON.parse(json2);
15689
15764
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
15690
15765
  return parsed;
15691
15766
  } catch {
@@ -15738,6 +15813,7 @@ var init_channel_identity = __esm({
15738
15813
  "../../packages/db/src/queries/channel-identity.ts"() {
15739
15814
  "use strict";
15740
15815
  init_drizzle_orm();
15816
+ init_src3();
15741
15817
  init_telegram_allowed_chats();
15742
15818
  init_channel_bindings();
15743
15819
  init_channel_allowed_conversations();
@@ -16214,8 +16290,12 @@ __export(src_exports, {
16214
16290
  createClient: () => createClient,
16215
16291
  createSkillRepo: () => createSkillRepo,
16216
16292
  credentials: () => credentials,
16293
+ credentialsFingerprint: () => credentialsFingerprint,
16294
+ decryptChannelSecret: () => decryptChannelSecret,
16217
16295
  decryptCredentialForDisplay: () => decryptCredentialForDisplay,
16218
16296
  desc: () => desc,
16297
+ encryptChannelCredentials: () => encryptChannelCredentials,
16298
+ encryptChannelSecret: () => encryptChannelSecret,
16219
16299
  entities: () => entities,
16220
16300
  entityLlmKeys: () => entityLlmKeys,
16221
16301
  entityMembers: () => entityMembers,
@@ -16349,7 +16429,7 @@ var init_local_auth = __esm({
16349
16429
  });
16350
16430
 
16351
16431
  // ../../packages/auth/src/lib/constant-time.ts
16352
- import { createHash, timingSafeEqual } from "crypto";
16432
+ import { createHash as createHash2, timingSafeEqual } from "crypto";
16353
16433
  var init_constant_time = __esm({
16354
16434
  "../../packages/auth/src/lib/constant-time.ts"() {
16355
16435
  "use strict";
@@ -17911,7 +17991,7 @@ var init_logs = __esm({
17911
17991
 
17912
17992
  // ../../packages/checkpoints/src/checkpoints.ts
17913
17993
  import { execFile } from "child_process";
17914
- import { createHash as createHash2 } from "crypto";
17994
+ import { createHash as createHash3 } from "crypto";
17915
17995
  import { mkdir, writeFile } from "fs/promises";
17916
17996
  import { existsSync as existsSync11 } from "fs";
17917
17997
  import { join as join10 } from "path";
@@ -17922,7 +18002,7 @@ function workspaceKey(workspace) {
17922
18002
  norm = norm.toLowerCase().replace(/\//g, "\\");
17923
18003
  }
17924
18004
  norm = norm.replace(/[\\/]+$/, "");
17925
- return createHash2("sha256").update(norm).digest("hex").slice(0, 16);
18005
+ return createHash3("sha256").update(norm).digest("hex").slice(0, 16);
17926
18006
  }
17927
18007
  async function git(store, workspace, args) {
17928
18008
  const key = workspaceKey(workspace);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodal-agents",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "Local-first AI agent platform with a web dashboard — install in one command.",
5
5
  "license": "MIT",
6
6
  "repository": {