22/**
33 * Slack broker registration CLI.
44 *
5- * Registers this baudbot server with a Slack broker workspace using:
5+ * Registers this baudbot server with a broker org using:
66 * - broker URL
7- * - workspace ID
7+ * - org ID
88 * - registration token from dashboard callback
99 *
1010 * On success, stores broker config and generated server key material in:
@@ -22,9 +22,10 @@ import { pathToFileURL } from "node:url";
2222
2323const { subtle } = webcrypto ;
2424
25- const WORKSPACE_ID_RE = / ^ T [ A - Z 0 - 9 ] + $ / ;
25+ const ORG_ID_RE = / ^ [ A - Z a - z 0 - 9 ] [ A - Z a - z 0 - 9 . _ : - ] * $ / ;
2626const ENV_KEYS = [
2727 "SLACK_BROKER_URL" ,
28+ "SLACK_BROKER_ORG_ID" ,
2829 "SLACK_BROKER_WORKSPACE_ID" ,
2930 "SLACK_BROKER_SERVER_PRIVATE_KEY" ,
3031 "SLACK_BROKER_SERVER_PUBLIC_KEY" ,
@@ -47,7 +48,8 @@ export function usageText() {
4748 "" ,
4849 "Options:" ,
4950 " --broker-url URL Broker base URL (e.g. https://broker.example.com)" ,
50- " --workspace-id ID Slack workspace ID (e.g. T0123ABCD)" ,
51+ " --org-id ID Broker org ID (e.g. org_1234abcd)" ,
52+ " --workspace-id ID Deprecated alias for --org-id (supported for compatibility)" ,
5153 " --registration-token TOKEN Registration token from dashboard callback (required)" ,
5254 " --no-restart Skip automatic agent restart after registration" ,
5355 " -v, --verbose Show detailed registration progress" ,
@@ -60,7 +62,7 @@ export function usageText() {
6062export function parseArgs ( argv ) {
6163 const out = {
6264 brokerUrl : "" ,
63- workspaceId : "" ,
65+ orgId : "" ,
6466 registrationToken : "" ,
6567 verbose : false ,
6668 help : false ,
@@ -95,13 +97,24 @@ export function parseArgs(argv) {
9597 continue ;
9698 }
9799
100+ if ( arg . startsWith ( "--org-id=" ) ) {
101+ out . orgId = arg . slice ( "--org-id=" . length ) ;
102+ continue ;
103+ }
104+ if ( arg === "--org-id" ) {
105+ i ++ ;
106+ out . orgId = argv [ i ] || "" ;
107+ continue ;
108+ }
109+
110+ // Backward-compatible CLI alias.
98111 if ( arg . startsWith ( "--workspace-id=" ) ) {
99- out . workspaceId = arg . slice ( "--workspace-id=" . length ) ;
112+ out . orgId = arg . slice ( "--workspace-id=" . length ) ;
100113 continue ;
101114 }
102115 if ( arg === "--workspace-id" ) {
103116 i ++ ;
104- out . workspaceId = argv [ i ] || "" ;
117+ out . orgId = argv [ i ] || "" ;
105118 continue ;
106119 }
107120
@@ -115,7 +128,6 @@ export function parseArgs(argv) {
115128 continue ;
116129 }
117130
118-
119131 throw new Error ( `unknown argument: ${ arg } ` ) ;
120132 }
121133
@@ -145,8 +157,14 @@ export function normalizeBrokerUrl(raw) {
145157 return parsed . toString ( ) . replace ( / \/ $ / , "" ) ;
146158}
147159
160+ export function validateOrgId ( orgId ) {
161+ const normalized = String ( orgId || "" ) . trim ( ) ;
162+ return normalized . length > 0 && normalized . length <= 128 && ORG_ID_RE . test ( normalized ) ;
163+ }
164+
165+ // Backward-compatible export for older imports/tests.
148166export function validateWorkspaceId ( workspaceId ) {
149- return WORKSPACE_ID_RE . test ( String ( workspaceId || "" ) ) ;
167+ return validateOrgId ( workspaceId ) ;
150168}
151169
152170function decodeBase64Url ( value ) {
@@ -222,10 +240,10 @@ export function mapRegisterError(status, errorText) {
222240 return "registration token already used — re-run OAuth install and use a fresh token" ;
223241 }
224242 if ( status === 409 && / a l r e a d y a c t i v e / i. test ( text ) ) {
225- return "workspace already active — unregister the current server first" ;
243+ return "org already active — unregister the current server first" ;
226244 }
227- if ( status === 404 && / w o r k s p a c e n o t f o u n d / i. test ( text ) ) {
228- return "workspace not found — complete broker OAuth install first" ;
245+ if ( status === 404 && / ( w o r k s p a c e | o r g ) n o t f o u n d / i. test ( text ) ) {
246+ return "org not found — complete dashboard registration first" ;
229247 }
230248 if ( status >= 500 ) {
231249 return `broker server error (${ status } ) — ${ text } ` ;
@@ -235,7 +253,7 @@ export function mapRegisterError(status, errorText) {
235253
236254export async function registerWithBroker ( {
237255 brokerUrl,
238- workspaceId ,
256+ orgId ,
239257 registrationToken,
240258 serverKeys,
241259 fetchImpl = fetch ,
@@ -246,13 +264,15 @@ export async function registerWithBroker({
246264
247265 const endpoint = new URL ( "/api/register" , brokerUrl ) ;
248266 const registerRequestBody = {
249- workspace_id : workspaceId ,
267+ org_id : orgId ,
268+ // Keep workspace_id during migration so older broker APIs still accept this payload.
269+ workspace_id : orgId ,
250270 server_pubkey : serverKeys . server_pubkey ,
251271 server_signing_pubkey : serverKeys . server_signing_pubkey ,
252272 registration_token : registrationToken ,
253273 } ;
254274
255- logger ( `Registering workspace ${ workspaceId } at ${ endpoint } ` ) ;
275+ logger ( `Registering org ${ orgId } at ${ endpoint } ` ) ;
256276
257277 let registerResponse ;
258278 try {
@@ -262,7 +282,7 @@ export async function registerWithBroker({
262282 body : JSON . stringify ( registerRequestBody ) ,
263283 } ) ;
264284 } catch ( err ) {
265- throw new Error ( `network failure registering workspace : ${ err instanceof Error ? err . message : "unknown error" } ` ) ;
285+ throw new Error ( `network failure registering org : ${ err instanceof Error ? err . message : "unknown error" } ` ) ;
266286 }
267287
268288 let registerResponseBody = { } ;
@@ -471,11 +491,15 @@ async function collectInputs(parsedArgs) {
471491
472492 const brokerUrl = parsedArgs . brokerUrl
473493 || existing . SLACK_BROKER_URL
494+ || existing . GATEWAY_BROKER_URL
474495 || ( await prompt ( "Broker URL: " ) ) ;
475496
476- const workspaceId = parsedArgs . workspaceId
497+ const orgId = parsedArgs . orgId
498+ || existing . SLACK_BROKER_ORG_ID
499+ || existing . GATEWAY_BROKER_ORG_ID
477500 || existing . SLACK_BROKER_WORKSPACE_ID
478- || ( await prompt ( "Workspace ID (starts with T): " ) ) ;
501+ || existing . GATEWAY_BROKER_WORKSPACE_ID
502+ || ( await prompt ( "Org ID: " ) ) ;
479503
480504 const registrationToken = parsedArgs . registrationToken || ( await prompt ( "Registration token: " ) ) ;
481505
@@ -485,21 +509,21 @@ async function collectInputs(parsedArgs) {
485509
486510 return {
487511 brokerUrl : normalizeBrokerUrl ( brokerUrl ) ,
488- workspaceId : workspaceId . trim ( ) ,
512+ orgId : orgId . trim ( ) ,
489513 registrationToken,
490514 configTargets,
491515 } ;
492516}
493517
494518export async function runRegistration ( {
495519 brokerUrl,
496- workspaceId ,
520+ orgId ,
497521 registrationToken,
498522 fetchImpl = fetch ,
499523 logger = ( ) => { } ,
500524} ) {
501- if ( ! validateWorkspaceId ( workspaceId ) ) {
502- throw new Error ( "workspace ID must match Slack team ID format (e.g. T0123ABCD) " ) ;
525+ if ( ! validateOrgId ( orgId ) ) {
526+ throw new Error ( "org ID is required and must use only letters, numbers, '.', '_', ':', or '-' " ) ;
503527 }
504528
505529 if ( ! registrationToken ) {
@@ -512,7 +536,7 @@ export async function runRegistration({
512536 const serverKeys = await generateServerKeyMaterial ( ) ;
513537 const registration = await registerWithBroker ( {
514538 brokerUrl : normalizedBrokerUrl ,
515- workspaceId ,
539+ orgId ,
516540 registrationToken,
517541 serverKeys,
518542 fetchImpl,
@@ -521,7 +545,9 @@ export async function runRegistration({
521545
522546 const updates = {
523547 SLACK_BROKER_URL : normalizedBrokerUrl ,
524- SLACK_BROKER_WORKSPACE_ID : workspaceId ,
548+ SLACK_BROKER_ORG_ID : orgId ,
549+ // Keep workspace key for backward compatibility with older runtimes.
550+ SLACK_BROKER_WORKSPACE_ID : orgId ,
525551 SLACK_BROKER_SERVER_PRIVATE_KEY : serverKeys . server_private_key ,
526552 SLACK_BROKER_SERVER_PUBLIC_KEY : serverKeys . server_pubkey ,
527553 SLACK_BROKER_SERVER_SIGNING_PRIVATE_KEY : serverKeys . server_signing_private_key ,
@@ -615,7 +641,7 @@ export async function main(argv = process.argv.slice(2)) {
615641
616642 logger ( "Collecting registration inputs..." ) ;
617643 const input = await collectInputs ( parsed ) ;
618- logger ( `Using broker ${ input . brokerUrl } for workspace ${ input . workspaceId } ` ) ;
644+ logger ( `Using broker ${ input . brokerUrl } for org ${ input . orgId } ` ) ;
619645 logger ( `Config targets: ${ input . configTargets . map ( ( t ) => t . path ) . join ( ", " ) } ` ) ;
620646
621647 const { updates } = await runRegistration ( { ...input , logger } ) ;
@@ -646,4 +672,4 @@ if (isMainModule()) {
646672 console . error ( `❌ ${ message } ` ) ;
647673 process . exit ( 1 ) ;
648674 } ) ;
649- }
675+ }
0 commit comments