@swarmclawai/swarmclaw 1.3.2 → 1.3.3

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/README.md CHANGED
@@ -204,6 +204,11 @@ Read the full setup guide in [`SWARMDOCK.md`](./SWARMDOCK.md), browse the public
204
204
 
205
205
  ## Release Notes
206
206
 
207
+ ### v1.3.3 Highlights
208
+
209
+ - **Bug fix — stale connector status after auto-restart (#31)**: connectors that auto-restart via the daemon health monitor now show "Starting" instead of a stale "Stopped" or "Error" status in the UI until the daemon reports runtime state. Added `starting` to the `ConnectorStatus` type and updated both the connector list and detail views.
210
+ - **Bug fix — stale credentialId after credential rotation (#30)**: when a provider credential is deleted and re-created, connector sessions now fall back to resolving any valid credential for the same provider instead of failing with "Missing credentials."
211
+
207
212
  ### v1.3.2 Highlights
208
213
 
209
214
  - **Custom provider fix for standalone builds**: fixed `require('@/lib/server/storage')` path alias resolution failure that caused custom providers to silently break in standalone/npm-global installs with "a is not a function" errors. All dynamic requires now use relative paths that resolve correctly at runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmclawai/swarmclaw",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Self-hosted AI runtime for OpenClaw, delegation, autonomy, runtime skills, crypto wallets, and chat platform connectors.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -322,7 +322,7 @@ export function ConnectorList({ inSidebar }: { inSidebar?: boolean }) {
322
322
  {meta.label}
323
323
  </span>
324
324
  <span className="text-[11px] text-text-3">
325
- {isRunning ? 'Connected' : c.status === 'error' ? 'Error' : 'Stopped'}
325
+ {isRunning ? 'Connected' : c.status === 'error' ? 'Error' : c.status === 'starting' ? 'Starting' : 'Stopped'}
326
326
  </span>
327
327
  </div>
328
328
  </div>
@@ -1270,7 +1270,7 @@ export function ConnectorSheet() {
1270
1270
  runtimeConnector?.status === 'error' ? 'bg-red-400' : 'bg-white/20'
1271
1271
  }`} />
1272
1272
  {effectiveRunning ? (waAuthenticated ? 'Connected and listening' : 'Connecting...') :
1273
- runtimeConnector?.status === 'error' ? 'Error — see below' : 'Not connected'}
1273
+ runtimeConnector?.status === 'error' ? 'Error — see below' : runtimeConnector?.status === 'starting' ? 'Starting...' : 'Not connected'}
1274
1274
  </div>
1275
1275
  </div>
1276
1276
  {effectiveRunning ? (
@@ -28,6 +28,7 @@ import {
28
28
  selectChatroomRecipients,
29
29
  } from '@/lib/server/chatrooms/chatroom-routing'
30
30
  import { markProviderFailure, markProviderSuccess } from '../provider-health'
31
+ import { listCredentialIdsByProvider, resolveCredentialSecret } from '@/lib/server/credentials/credential-service'
31
32
  import { buildIdentityContinuityContext } from '../identity-continuity'
32
33
  import { buildRuntimeSkillPromptBlocks, resolveRuntimeSkills } from '@/lib/server/skills/runtime-skill-resolver'
33
34
  import { getProvider } from '@/lib/providers'
@@ -1009,6 +1010,18 @@ async function routeMessage(connector: Connector, msg: InboundMessage): Promise<
1009
1010
  }
1010
1011
  }
1011
1012
 
1013
+ // Fallback: session credential was deleted — try any credential for this provider
1014
+ if (!apiKey && session.provider) {
1015
+ const providerCredentialIds = listCredentialIdsByProvider(session.provider)
1016
+ for (const id of providerCredentialIds) {
1017
+ const resolved = resolveCredentialSecret(id)
1018
+ if (resolved) {
1019
+ apiKey = resolved
1020
+ break
1021
+ }
1022
+ }
1023
+ }
1024
+
1012
1025
  // Build system prompt: [identity] \n\n [userPrompt] \n\n [soul] \n\n [systemPrompt]
1013
1026
  const settings = loadSettings()
1014
1027
  const promptParts: string[] = []
@@ -62,11 +62,13 @@ function persistConnector(connector: Connector): void {
62
62
  }
63
63
 
64
64
  function applyRuntimeFields(connector: Connector, runtime: DaemonConnectorRuntimeState | null): Connector {
65
- connector.status = runtime?.status
66
- ? runtime.status
67
- : connector.lastError
68
- ? 'error'
69
- : 'stopped'
65
+ if (runtime?.status) {
66
+ connector.status = runtime.status
67
+ } else if (connector.isEnabled) {
68
+ connector.status = 'starting'
69
+ } else {
70
+ connector.status = connector.lastError ? 'error' : 'stopped'
71
+ }
70
72
 
71
73
  if (connector.platform === 'whatsapp') {
72
74
  connector.authenticated = runtime?.authenticated
@@ -29,7 +29,7 @@ export type ConnectorPlatform =
29
29
  | 'webchat'
30
30
  | 'mockmail'
31
31
  | 'swarmdock'
32
- export type ConnectorStatus = 'stopped' | 'running' | 'error'
32
+ export type ConnectorStatus = 'stopped' | 'running' | 'error' | 'starting'
33
33
 
34
34
  export interface MessageSource {
35
35
  platform: ConnectorPlatform