Migrating to 0.6

0.6 tightens defineDevframe's metadata, replaces terminal and WebSocket transports, and adds enforced auth.

0.6 tightens defineDevframe's metadata, replaces terminal and WebSocket transports, and adds enforced auth.

defineDevframe requires four more fields

version, packageName, homepage, description are now required alongside id/name, sourced from package.json:

import pkg from '../package.json' with { type: 'json' }

export default defineDevframe({
  id: 'my-devframe',
  name: 'My Devframe', // display label
  version: pkg.version,
  packageName: pkg.name, // maps from package.json's `name`
  homepage: pkg.homepage,
  description: pkg.description,
  setup(ctx) { /* … */ },
})

See Devframe Definition for the full reference and the optional duplicationStrategy.

Auth handshake methods are renamed

The two pre-trust RPC methods moved under the anonymous: prefix, so isAnonymousRpcMethod covers them:

0.5.x0.6
devframe:anonymous:authanonymous:devframe:auth
devframe:auth:exchangeanonymous:devframe:auth:exchange

Client calls (requestTrustWithToken(), requestTrustWithCode()) are unchanged; update only node-side handlers or authorize gates using the old names.

WebSocket connections now enforce origin and (optionally) trust

Two gates landed on the RPC socket:

  • Cross-origin upgrades rejected by default. Only loopback origins (localhost/127.0.0.1/::1) and Origin-less requests are accepted; another host needs an explicit allowlist:

    await startHttpAndWs({
      context: ctx,
      port: 9999,
      allowedOrigins: ['https://my-tunnel.example.com'],
    })

    Pass allowedOrigins: false to disable the check (not recommended).

  • Real authorization enforcement, opt-in. auth: true (default) stays permissive. A DevframeAuthHandler turns on the pre-trust gate: untrusted callers reach only anonymous: methods, else DF0036 throws. The Interactive Auth recipe builds one:

    import { startHttpAndWs } from 'devframe/node'
    import { createInteractiveAuth } from 'devframe/recipes/interactive-auth'
    
    const auth = createInteractiveAuth(ctx)
    const server = await startHttpAndWs({ context: ctx, port: 9999, auth })
    auth.printBanner()

Terminals run on zigpty, not the node-pty peer

PTY sessions (ctx.terminals.startPtySession()) now spawn through zigpty's bindings, bundled with @devframes/hub; drop the optional node-pty peer.

StartedServer.wss is now StartedServer.ws

The RPC transport moved from ws to crossws; the startHttpAndWs/createDevServer handle changed shape:

// 0.5.x
const server = await startHttpAndWs({ context: ctx, port: 9999 })
server.wss.clients // ws.WebSocketServer

// 0.6
const server = await startHttpAndWs({ context: ctx, port: 9999 })
server.ws // crossws NodeAdapter

Code reaching into .wss needs the crossws NodeAdapter API.

devframe/utils/human-id is gone

Removed. Use devframe/utils/nanoid for a short random ID, or devframe/utils/crypto-token's randomToken() / randomDigits() for security-sensitive values:

// 0.5.x
import { humanId } from 'devframe/utils/human-id'

humanId() // 'bright-orange-tiger'
// 0.6
import { nanoid } from 'devframe/utils/nanoid'

nanoid() // short URL-safe ID, no word-list dependency