@workbuddy/cli-edge 1.0.7 → 1.0.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 (2) hide show
  1. package/dist/index.js +2321 -280
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2421,6 +2421,14 @@ async function getErrorMessage(response, fallback) {
2421
2421
  // src/client.ts
2422
2422
  import { Buffer as Buffer2 } from "node:buffer";
2423
2423
  var PUBLIC_API_BASE_PATH = "/api/v2/public";
2424
+
2425
+ class CliError extends Error {
2426
+ exitCode;
2427
+ constructor(message, exitCode = 1) {
2428
+ super(message);
2429
+ this.exitCode = exitCode;
2430
+ }
2431
+ }
2424
2432
  async function executeOperation(operation, values, config) {
2425
2433
  if (!config.baseUrl) {
2426
2434
  throw new Error("Missing WorkBuddy base URL. Run workbuddy auth login or pass --base-url.");
@@ -2460,7 +2468,8 @@ async function executeOperation(operation, values, config) {
2460
2468
  const buffer = Buffer2.from(await response.arrayBuffer());
2461
2469
  const contentType = response.headers.get("content-type") ?? "application/octet-stream";
2462
2470
  if (!response.ok) {
2463
- throw new Error(buildHttpErrorMessage(response.status, contentType, buffer));
2471
+ const exitCodeMap = { 401: 10, 403: 11, 404: 12, 400: 13, 409: 14, 422: 15, 429: 16 };
2472
+ throw new CliError(buildHttpErrorMessage(response.status, contentType, buffer), exitCodeMap[response.status] ?? 1);
2464
2473
  }
2465
2474
  if (contentType.includes("application/json")) {
2466
2475
  const text = buffer.length > 0 ? buffer.toString("utf-8") : "null";
@@ -2536,24 +2545,40 @@ function validateTagOperationPayloads(body) {
2536
2545
  }
2537
2546
  function buildHttpErrorMessage(status, contentType, buffer) {
2538
2547
  const text = buffer.toString("utf-8");
2539
- if (!text) {
2540
- return "Request failed with status " + status;
2541
- }
2542
- if (contentType.includes("application/json")) {
2548
+ let message = "Request failed with status " + status;
2549
+ if (text && contentType.includes("application/json")) {
2543
2550
  try {
2544
2551
  const parsed = JSON.parse(text);
2545
2552
  const errorObj = parsed?.error;
2546
2553
  if (errorObj && typeof errorObj === "object") {
2547
- const msg = errorObj.message ?? errorObj.code ?? JSON.stringify(errorObj);
2548
- return "Request failed with status " + status + ": " + msg;
2554
+ message += ": " + (errorObj.message ?? errorObj.code ?? JSON.stringify(errorObj));
2555
+ } else {
2556
+ const detail = parsed?.message ?? (typeof errorObj === "string" ? errorObj : null) ?? parsed?.details;
2557
+ if (detail)
2558
+ message += ": " + detail;
2559
+ else
2560
+ message += ": " + text;
2549
2561
  }
2550
- const detail = parsed?.message ?? (typeof errorObj === "string" ? errorObj : null) ?? parsed?.details;
2551
- return detail ? "Request failed with status " + status + ": " + detail : "Request failed with status " + status + ": " + text;
2552
2562
  } catch {
2553
- return "Request failed with status " + status + ": " + text;
2563
+ message += ": " + text;
2554
2564
  }
2565
+ } else if (text) {
2566
+ message += ": " + text;
2567
+ }
2568
+ const hints = {
2569
+ 400: "Hint: Run the command with --describe to see required fields, or --example for a sample body.",
2570
+ 401: 'Hint: Run "workbuddy auth login" to authenticate, or pass --access-token.',
2571
+ 403: "Hint: The OAuth client may not have the required scope. Check client configuration in WorkBuddy settings.",
2572
+ 404: "Hint: Verify the entity ID or number exists. Use the list/search command to find valid identifiers.",
2573
+ 409: "Hint: The entity may have been modified. Retry with the latest updatedAt value.",
2574
+ 422: "Hint: Run the command with --describe to see field types and allowed values.",
2575
+ 429: "Hint: Rate limit exceeded. Wait a moment and retry."
2576
+ };
2577
+ if (hints[status]) {
2578
+ message += `
2579
+ ` + hints[status];
2555
2580
  }
2556
- return "Request failed with status " + status + ": " + text;
2581
+ return message;
2557
2582
  }
2558
2583
  function parseCliValue(value, type) {
2559
2584
  if (typeof value !== "string") {
@@ -2967,7 +2992,17 @@ var operations = [
2967
2992
  description: "Raw request body JSON (overrides individual fields)"
2968
2993
  }
2969
2994
  ],
2970
- hasRequestBody: true
2995
+ hasRequestBody: true,
2996
+ responseFields: [
2997
+ {
2998
+ name: "items",
2999
+ type: "array"
3000
+ },
3001
+ {
3002
+ name: "pagination",
3003
+ type: "object"
3004
+ }
3005
+ ]
2971
3006
  },
2972
3007
  {
2973
3008
  operationId: "PublicApiJobController_get",
@@ -2987,7 +3022,128 @@ var operations = [
2987
3022
  description: "Job ID (MongoDB ObjectId) or job number (e.g., JOB-12345)"
2988
3023
  }
2989
3024
  ],
2990
- hasRequestBody: false
3025
+ hasRequestBody: false,
3026
+ responseFields: [
3027
+ {
3028
+ name: "id",
3029
+ type: "string",
3030
+ description: "Entity ID"
3031
+ },
3032
+ {
3033
+ name: "jobNumber",
3034
+ type: "string"
3035
+ },
3036
+ {
3037
+ name: "description",
3038
+ type: "string",
3039
+ description: "Detailed description"
3040
+ },
3041
+ {
3042
+ name: "status",
3043
+ type: "object",
3044
+ description: "Status filter"
3045
+ },
3046
+ {
3047
+ name: "customer",
3048
+ type: "object",
3049
+ description: "Inline customer object — alternative to customerId"
3050
+ },
3051
+ {
3052
+ name: "site",
3053
+ type: "string",
3054
+ description: "Inline site object — alternative to siteId"
3055
+ },
3056
+ {
3057
+ name: "contact",
3058
+ type: "string",
3059
+ description: "Inline contact object — alternative to contactId"
3060
+ },
3061
+ {
3062
+ name: "customerSupervisor",
3063
+ type: "string"
3064
+ },
3065
+ {
3066
+ name: "type",
3067
+ type: "string"
3068
+ },
3069
+ {
3070
+ name: "priority",
3071
+ type: "string"
3072
+ },
3073
+ {
3074
+ name: "owner",
3075
+ type: "string"
3076
+ },
3077
+ {
3078
+ name: "zones",
3079
+ type: "array"
3080
+ },
3081
+ {
3082
+ name: "tags",
3083
+ type: "array",
3084
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
3085
+ },
3086
+ {
3087
+ name: "notes",
3088
+ type: "string",
3089
+ description: "Additional notes or comments"
3090
+ },
3091
+ {
3092
+ name: "reference",
3093
+ type: "string",
3094
+ description: "External reference number"
3095
+ },
3096
+ {
3097
+ name: "customerWO",
3098
+ type: "string",
3099
+ description: "Customer work order reference"
3100
+ },
3101
+ {
3102
+ name: "customerPO",
3103
+ type: "string",
3104
+ description: "Customer purchase order reference"
3105
+ },
3106
+ {
3107
+ name: "priceBook",
3108
+ type: "string"
3109
+ },
3110
+ {
3111
+ name: "billingCompany",
3112
+ type: "string"
3113
+ },
3114
+ {
3115
+ name: "stages",
3116
+ type: "array"
3117
+ },
3118
+ {
3119
+ name: "totals",
3120
+ type: "object"
3121
+ },
3122
+ {
3123
+ name: "customFields",
3124
+ type: "string",
3125
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
3126
+ },
3127
+ {
3128
+ name: "dueDate",
3129
+ type: "string",
3130
+ description: "Due date (ISO 8601 datetime)"
3131
+ },
3132
+ {
3133
+ name: "startDate",
3134
+ type: "string",
3135
+ description: "Start date (ISO 8601 datetime)"
3136
+ },
3137
+ {
3138
+ name: "createdAt",
3139
+ type: "string"
3140
+ },
3141
+ {
3142
+ name: "updatedAt",
3143
+ type: "string",
3144
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
3145
+ }
3146
+ ]
2991
3147
  },
2992
3148
  {
2993
3149
  operationId: "PublicApiJobController_delete",
@@ -3025,7 +3181,13 @@ var operations = [
3025
3181
  description: "Raw request body JSON (overrides individual fields)"
3026
3182
  }
3027
3183
  ],
3028
- hasRequestBody: true
3184
+ hasRequestBody: true,
3185
+ responseFields: [
3186
+ {
3187
+ name: "cancelled",
3188
+ type: "boolean"
3189
+ }
3190
+ ]
3029
3191
  },
3030
3192
  {
3031
3193
  operationId: "PublicApiJobController_create",
@@ -3060,7 +3222,8 @@ var operations = [
3060
3222
  source: "body",
3061
3223
  type: "string",
3062
3224
  required: false,
3063
- description: "Customer ID — use /crm/customers to look up"
3225
+ description: "Customer ID — use /crm/customers to look up",
3226
+ lookupEndpoint: "/crm/customers"
3064
3227
  },
3065
3228
  {
3066
3229
  name: "customer",
@@ -3078,7 +3241,8 @@ var operations = [
3078
3241
  source: "body",
3079
3242
  type: "string",
3080
3243
  required: false,
3081
- description: "Site ID — use /crm/sites to look up"
3244
+ description: "Site ID — use /crm/sites to look up",
3245
+ lookupEndpoint: "/crm/sites"
3082
3246
  },
3083
3247
  {
3084
3248
  name: "site",
@@ -3096,7 +3260,8 @@ var operations = [
3096
3260
  source: "body",
3097
3261
  type: "string",
3098
3262
  required: false,
3099
- description: "Contact ID — use /crm/contacts to look up"
3263
+ description: "Contact ID — use /crm/contacts to look up",
3264
+ lookupEndpoint: "/crm/contacts"
3100
3265
  },
3101
3266
  {
3102
3267
  name: "contact",
@@ -3114,7 +3279,8 @@ var operations = [
3114
3279
  source: "body",
3115
3280
  type: "string",
3116
3281
  required: false,
3117
- description: "Job type ID — use /settings/job-types to look up"
3282
+ description: "Job type ID — use /settings/job-types to look up",
3283
+ lookupEndpoint: "/settings/job-types"
3118
3284
  },
3119
3285
  {
3120
3286
  name: "priorityId",
@@ -3123,7 +3289,8 @@ var operations = [
3123
3289
  source: "body",
3124
3290
  type: "string",
3125
3291
  required: false,
3126
- description: "Priority ID — use /settings/priorities to look up"
3292
+ description: "Priority ID — use /settings/priorities to look up",
3293
+ lookupEndpoint: "/settings/priorities"
3127
3294
  },
3128
3295
  {
3129
3296
  name: "priceBookId",
@@ -3132,7 +3299,8 @@ var operations = [
3132
3299
  source: "body",
3133
3300
  type: "string",
3134
3301
  required: false,
3135
- description: "Price book ID for job pricing"
3302
+ description: "Price book ID for job pricing",
3303
+ lookupEndpoint: "/settings/price-books"
3136
3304
  },
3137
3305
  {
3138
3306
  name: "ownerId",
@@ -3141,7 +3309,8 @@ var operations = [
3141
3309
  source: "body",
3142
3310
  type: "string",
3143
3311
  required: false,
3144
- description: "Owner (employee) ID — use /crm/employees to look up"
3312
+ description: "Owner (employee) ID — use /crm/employees to look up",
3313
+ lookupEndpoint: "/crm/employees"
3145
3314
  },
3146
3315
  {
3147
3316
  name: "fieldSupervisorId",
@@ -3150,7 +3319,8 @@ var operations = [
3150
3319
  source: "body",
3151
3320
  type: "string",
3152
3321
  required: false,
3153
- description: "Field supervisor (employee) ID — use /crm/employees to look up"
3322
+ description: "Field supervisor (employee) ID — use /crm/employees to look up",
3323
+ lookupEndpoint: "/crm/employees"
3154
3324
  },
3155
3325
  {
3156
3326
  name: "zoneId",
@@ -3159,7 +3329,8 @@ var operations = [
3159
3329
  source: "body",
3160
3330
  type: "string",
3161
3331
  required: false,
3162
- description: "Zone ID — use /settings/zones to look up"
3332
+ description: "Zone ID — use /settings/zones to look up",
3333
+ lookupEndpoint: "/settings/zones"
3163
3334
  },
3164
3335
  {
3165
3336
  name: "tagIds",
@@ -3168,7 +3339,8 @@ var operations = [
3168
3339
  source: "body",
3169
3340
  type: "array",
3170
3341
  required: false,
3171
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
3342
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
3343
+ lookupEndpoint: "/settings/tags"
3172
3344
  },
3173
3345
  {
3174
3346
  name: "notes",
@@ -3213,7 +3385,8 @@ var operations = [
3213
3385
  source: "body",
3214
3386
  type: "string",
3215
3387
  required: false,
3216
- description: "Template ID to pre-populate fields from a template"
3388
+ description: "Template ID to pre-populate fields from a template",
3389
+ lookupEndpoint: "/settings/templates"
3217
3390
  },
3218
3391
  {
3219
3392
  name: "startDate",
@@ -3254,7 +3427,128 @@ var operations = [
3254
3427
  description: "Raw request body JSON (overrides individual fields)"
3255
3428
  }
3256
3429
  ],
3257
- hasRequestBody: true
3430
+ hasRequestBody: true,
3431
+ responseFields: [
3432
+ {
3433
+ name: "id",
3434
+ type: "string",
3435
+ description: "Entity ID"
3436
+ },
3437
+ {
3438
+ name: "jobNumber",
3439
+ type: "string"
3440
+ },
3441
+ {
3442
+ name: "description",
3443
+ type: "string",
3444
+ description: "Detailed description"
3445
+ },
3446
+ {
3447
+ name: "status",
3448
+ type: "object",
3449
+ description: "Status filter"
3450
+ },
3451
+ {
3452
+ name: "customer",
3453
+ type: "object",
3454
+ description: "Inline customer object — alternative to customerId"
3455
+ },
3456
+ {
3457
+ name: "site",
3458
+ type: "string",
3459
+ description: "Inline site object — alternative to siteId"
3460
+ },
3461
+ {
3462
+ name: "contact",
3463
+ type: "string",
3464
+ description: "Inline contact object — alternative to contactId"
3465
+ },
3466
+ {
3467
+ name: "customerSupervisor",
3468
+ type: "string"
3469
+ },
3470
+ {
3471
+ name: "type",
3472
+ type: "string"
3473
+ },
3474
+ {
3475
+ name: "priority",
3476
+ type: "string"
3477
+ },
3478
+ {
3479
+ name: "owner",
3480
+ type: "string"
3481
+ },
3482
+ {
3483
+ name: "zones",
3484
+ type: "array"
3485
+ },
3486
+ {
3487
+ name: "tags",
3488
+ type: "array",
3489
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
3490
+ },
3491
+ {
3492
+ name: "notes",
3493
+ type: "string",
3494
+ description: "Additional notes or comments"
3495
+ },
3496
+ {
3497
+ name: "reference",
3498
+ type: "string",
3499
+ description: "External reference number"
3500
+ },
3501
+ {
3502
+ name: "customerWO",
3503
+ type: "string",
3504
+ description: "Customer work order reference"
3505
+ },
3506
+ {
3507
+ name: "customerPO",
3508
+ type: "string",
3509
+ description: "Customer purchase order reference"
3510
+ },
3511
+ {
3512
+ name: "priceBook",
3513
+ type: "string"
3514
+ },
3515
+ {
3516
+ name: "billingCompany",
3517
+ type: "string"
3518
+ },
3519
+ {
3520
+ name: "stages",
3521
+ type: "array"
3522
+ },
3523
+ {
3524
+ name: "totals",
3525
+ type: "object"
3526
+ },
3527
+ {
3528
+ name: "customFields",
3529
+ type: "string",
3530
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
3531
+ },
3532
+ {
3533
+ name: "dueDate",
3534
+ type: "string",
3535
+ description: "Due date (ISO 8601 datetime)"
3536
+ },
3537
+ {
3538
+ name: "startDate",
3539
+ type: "string",
3540
+ description: "Start date (ISO 8601 datetime)"
3541
+ },
3542
+ {
3543
+ name: "createdAt",
3544
+ type: "string"
3545
+ },
3546
+ {
3547
+ name: "updatedAt",
3548
+ type: "string",
3549
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
3550
+ }
3551
+ ]
3258
3552
  },
3259
3553
  {
3260
3554
  operationId: "PublicApiJobController_update",
@@ -3308,7 +3602,8 @@ var operations = [
3308
3602
  source: "body",
3309
3603
  type: "string",
3310
3604
  required: false,
3311
- description: "Site ID — use /crm/sites to look up"
3605
+ description: "Site ID — use /crm/sites to look up",
3606
+ lookupEndpoint: "/crm/sites"
3312
3607
  },
3313
3608
  {
3314
3609
  name: "contactId",
@@ -3317,7 +3612,8 @@ var operations = [
3317
3612
  source: "body",
3318
3613
  type: "string",
3319
3614
  required: false,
3320
- description: "Contact ID — use /crm/contacts to look up"
3615
+ description: "Contact ID — use /crm/contacts to look up",
3616
+ lookupEndpoint: "/crm/contacts"
3321
3617
  },
3322
3618
  {
3323
3619
  name: "typeId",
@@ -3326,7 +3622,8 @@ var operations = [
3326
3622
  source: "body",
3327
3623
  type: "string",
3328
3624
  required: false,
3329
- description: "Job type ID — use /settings/job-types to look up"
3625
+ description: "Job type ID — use /settings/job-types to look up",
3626
+ lookupEndpoint: "/settings/job-types"
3330
3627
  },
3331
3628
  {
3332
3629
  name: "priorityId",
@@ -3335,7 +3632,8 @@ var operations = [
3335
3632
  source: "body",
3336
3633
  type: "string",
3337
3634
  required: false,
3338
- description: "Priority ID — use /settings/priorities to look up"
3635
+ description: "Priority ID — use /settings/priorities to look up",
3636
+ lookupEndpoint: "/settings/priorities"
3339
3637
  },
3340
3638
  {
3341
3639
  name: "priceBookId",
@@ -3344,7 +3642,8 @@ var operations = [
3344
3642
  source: "body",
3345
3643
  type: "string",
3346
3644
  required: false,
3347
- description: "Price book ID for job pricing"
3645
+ description: "Price book ID for job pricing",
3646
+ lookupEndpoint: "/settings/price-books"
3348
3647
  },
3349
3648
  {
3350
3649
  name: "ownerId",
@@ -3353,7 +3652,8 @@ var operations = [
3353
3652
  source: "body",
3354
3653
  type: "string",
3355
3654
  required: false,
3356
- description: "Owner (employee) ID — use /crm/employees to look up"
3655
+ description: "Owner (employee) ID — use /crm/employees to look up",
3656
+ lookupEndpoint: "/crm/employees"
3357
3657
  },
3358
3658
  {
3359
3659
  name: "fieldSupervisorId",
@@ -3362,7 +3662,8 @@ var operations = [
3362
3662
  source: "body",
3363
3663
  type: "string",
3364
3664
  required: false,
3365
- description: "Field supervisor (employee) ID — use /crm/employees to look up"
3665
+ description: "Field supervisor (employee) ID — use /crm/employees to look up",
3666
+ lookupEndpoint: "/crm/employees"
3366
3667
  },
3367
3668
  {
3368
3669
  name: "zoneId",
@@ -3371,7 +3672,8 @@ var operations = [
3371
3672
  source: "body",
3372
3673
  type: "string",
3373
3674
  required: false,
3374
- description: "Zone ID — use /settings/zones to look up"
3675
+ description: "Zone ID — use /settings/zones to look up",
3676
+ lookupEndpoint: "/settings/zones"
3375
3677
  },
3376
3678
  {
3377
3679
  name: "tagIds",
@@ -3380,7 +3682,8 @@ var operations = [
3380
3682
  source: "body",
3381
3683
  type: "array",
3382
3684
  required: false,
3383
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
3685
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
3686
+ lookupEndpoint: "/settings/tags"
3384
3687
  },
3385
3688
  {
3386
3689
  name: "notes",
@@ -3457,73 +3760,136 @@ var operations = [
3457
3760
  description: "Raw request body JSON (overrides individual fields)"
3458
3761
  }
3459
3762
  ],
3460
- hasRequestBody: true
3461
- },
3462
- {
3463
- operationId: "PublicApiJobController_dispatch",
3464
- displayName: "Dispatch a job",
3465
- description: "Change job status to dispatched, making it ready for field work.",
3466
- method: "POST",
3467
- path: "/jobs/{id}/dispatch",
3468
- commandPath: ["jobs", "dispatch"],
3469
- options: [
3763
+ hasRequestBody: true,
3764
+ responseFields: [
3470
3765
  {
3471
3766
  name: "id",
3472
- cliName: "id",
3473
- optionKey: "id",
3474
- source: "path",
3475
3767
  type: "string",
3476
- required: true,
3477
- description: "Job ID"
3478
- }
3479
- ],
3480
- hasRequestBody: false
3481
- },
3482
- {
3483
- operationId: "PublicApiJobController_getJobStages",
3484
- displayName: "List job stages",
3485
- description: "Get all stages (work orders) for a job.",
3486
- method: "GET",
3487
- path: "/jobs/{id}/stages",
3488
- commandPath: ["jobs", "stages", "list"],
3489
- options: [
3768
+ description: "Entity ID"
3769
+ },
3490
3770
  {
3491
- name: "id",
3492
- cliName: "id",
3493
- optionKey: "id",
3494
- source: "path",
3771
+ name: "jobNumber",
3772
+ type: "string"
3773
+ },
3774
+ {
3775
+ name: "description",
3495
3776
  type: "string",
3496
- required: true,
3497
- description: "Job ID"
3777
+ description: "Detailed description"
3498
3778
  },
3499
3779
  {
3500
- name: "cursor",
3501
- cliName: "cursor",
3502
- optionKey: "cursor",
3503
- source: "query",
3780
+ name: "status",
3781
+ type: "object",
3782
+ description: "Status filter"
3783
+ },
3784
+ {
3785
+ name: "customer",
3786
+ type: "object",
3787
+ description: "Inline customer object — alternative to customerId"
3788
+ },
3789
+ {
3790
+ name: "site",
3504
3791
  type: "string",
3505
- required: false,
3506
- description: "Pagination cursor from previous response"
3792
+ description: "Inline site object — alternative to siteId"
3507
3793
  },
3508
3794
  {
3509
- name: "limit",
3510
- cliName: "limit",
3511
- optionKey: "limit",
3512
- source: "query",
3513
- type: "number",
3514
- required: false,
3515
- description: "Maximum results to return (1-200)"
3795
+ name: "contact",
3796
+ type: "string",
3797
+ description: "Inline contact object — alternative to contactId"
3798
+ },
3799
+ {
3800
+ name: "customerSupervisor",
3801
+ type: "string"
3802
+ },
3803
+ {
3804
+ name: "type",
3805
+ type: "string"
3806
+ },
3807
+ {
3808
+ name: "priority",
3809
+ type: "string"
3810
+ },
3811
+ {
3812
+ name: "owner",
3813
+ type: "string"
3814
+ },
3815
+ {
3816
+ name: "zones",
3817
+ type: "array"
3818
+ },
3819
+ {
3820
+ name: "tags",
3821
+ type: "array",
3822
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
3823
+ },
3824
+ {
3825
+ name: "notes",
3826
+ type: "string",
3827
+ description: "Additional notes or comments"
3828
+ },
3829
+ {
3830
+ name: "reference",
3831
+ type: "string",
3832
+ description: "External reference number"
3833
+ },
3834
+ {
3835
+ name: "customerWO",
3836
+ type: "string",
3837
+ description: "Customer work order reference"
3838
+ },
3839
+ {
3840
+ name: "customerPO",
3841
+ type: "string",
3842
+ description: "Customer purchase order reference"
3843
+ },
3844
+ {
3845
+ name: "priceBook",
3846
+ type: "string"
3847
+ },
3848
+ {
3849
+ name: "billingCompany",
3850
+ type: "string"
3851
+ },
3852
+ {
3853
+ name: "stages",
3854
+ type: "array"
3855
+ },
3856
+ {
3857
+ name: "totals",
3858
+ type: "object"
3859
+ },
3860
+ {
3861
+ name: "customFields",
3862
+ type: "string",
3863
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
3864
+ },
3865
+ {
3866
+ name: "dueDate",
3867
+ type: "string",
3868
+ description: "Due date (ISO 8601 datetime)"
3869
+ },
3870
+ {
3871
+ name: "startDate",
3872
+ type: "string",
3873
+ description: "Start date (ISO 8601 datetime)"
3874
+ },
3875
+ {
3876
+ name: "createdAt",
3877
+ type: "string"
3878
+ },
3879
+ {
3880
+ name: "updatedAt",
3881
+ type: "string",
3882
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
3516
3883
  }
3517
- ],
3518
- hasRequestBody: false
3884
+ ]
3519
3885
  },
3520
3886
  {
3521
- operationId: "PublicApiJobController_getJobStage",
3522
- displayName: "Get job stage",
3523
- description: "Get a specific stage within a job.",
3524
- method: "GET",
3525
- path: "/jobs/{id}/stages/{stageId}",
3526
- commandPath: ["jobs", "stages", "get"],
3887
+ operationId: "PublicApiJobController_dispatch",
3888
+ displayName: "Dispatch a job",
3889
+ description: "Change job status to dispatched, making it ready for field work.",
3890
+ method: "POST",
3891
+ path: "/jobs/{id}/dispatch",
3892
+ commandPath: ["jobs", "dispatch"],
3527
3893
  options: [
3528
3894
  {
3529
3895
  name: "id",
@@ -3533,26 +3899,138 @@ var operations = [
3533
3899
  type: "string",
3534
3900
  required: true,
3535
3901
  description: "Job ID"
3902
+ }
3903
+ ],
3904
+ hasRequestBody: false,
3905
+ responseFields: [
3906
+ {
3907
+ name: "id",
3908
+ type: "string",
3909
+ description: "Entity ID"
3536
3910
  },
3537
3911
  {
3538
- name: "stageId",
3539
- cliName: "stage-id",
3540
- optionKey: "stageId",
3541
- source: "path",
3912
+ name: "jobNumber",
3913
+ type: "string"
3914
+ },
3915
+ {
3916
+ name: "description",
3542
3917
  type: "string",
3543
- required: true,
3544
- description: "Stage ID"
3918
+ description: "Detailed description"
3919
+ },
3920
+ {
3921
+ name: "status",
3922
+ type: "object",
3923
+ description: "Status filter"
3924
+ },
3925
+ {
3926
+ name: "customer",
3927
+ type: "object",
3928
+ description: "Inline customer object — alternative to customerId"
3929
+ },
3930
+ {
3931
+ name: "site",
3932
+ type: "string",
3933
+ description: "Inline site object — alternative to siteId"
3934
+ },
3935
+ {
3936
+ name: "contact",
3937
+ type: "string",
3938
+ description: "Inline contact object — alternative to contactId"
3939
+ },
3940
+ {
3941
+ name: "customerSupervisor",
3942
+ type: "string"
3943
+ },
3944
+ {
3945
+ name: "type",
3946
+ type: "string"
3947
+ },
3948
+ {
3949
+ name: "priority",
3950
+ type: "string"
3951
+ },
3952
+ {
3953
+ name: "owner",
3954
+ type: "string"
3955
+ },
3956
+ {
3957
+ name: "zones",
3958
+ type: "array"
3959
+ },
3960
+ {
3961
+ name: "tags",
3962
+ type: "array",
3963
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
3964
+ },
3965
+ {
3966
+ name: "notes",
3967
+ type: "string",
3968
+ description: "Additional notes or comments"
3969
+ },
3970
+ {
3971
+ name: "reference",
3972
+ type: "string",
3973
+ description: "External reference number"
3974
+ },
3975
+ {
3976
+ name: "customerWO",
3977
+ type: "string",
3978
+ description: "Customer work order reference"
3979
+ },
3980
+ {
3981
+ name: "customerPO",
3982
+ type: "string",
3983
+ description: "Customer purchase order reference"
3984
+ },
3985
+ {
3986
+ name: "priceBook",
3987
+ type: "string"
3988
+ },
3989
+ {
3990
+ name: "billingCompany",
3991
+ type: "string"
3992
+ },
3993
+ {
3994
+ name: "stages",
3995
+ type: "array"
3996
+ },
3997
+ {
3998
+ name: "totals",
3999
+ type: "object"
4000
+ },
4001
+ {
4002
+ name: "customFields",
4003
+ type: "string",
4004
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
4005
+ },
4006
+ {
4007
+ name: "dueDate",
4008
+ type: "string",
4009
+ description: "Due date (ISO 8601 datetime)"
4010
+ },
4011
+ {
4012
+ name: "startDate",
4013
+ type: "string",
4014
+ description: "Start date (ISO 8601 datetime)"
4015
+ },
4016
+ {
4017
+ name: "createdAt",
4018
+ type: "string"
4019
+ },
4020
+ {
4021
+ name: "updatedAt",
4022
+ type: "string",
4023
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
3545
4024
  }
3546
- ],
3547
- hasRequestBody: false
4025
+ ]
3548
4026
  },
3549
4027
  {
3550
- operationId: "PublicApiJobController_getStageItems",
3551
- displayName: "List stage items",
3552
- description: "Get all items (line items) for a stage.",
4028
+ operationId: "PublicApiJobController_getJobStages",
4029
+ displayName: "List job stages",
4030
+ description: "Get all stages (work orders) for a job.",
3553
4031
  method: "GET",
3554
- path: "/jobs/{id}/stages/{stageId}/items",
3555
- commandPath: ["jobs", "stages", "items", "list"],
4032
+ path: "/jobs/{id}/stages",
4033
+ commandPath: ["jobs", "stages", "list"],
3556
4034
  options: [
3557
4035
  {
3558
4036
  name: "id",
@@ -3563,15 +4041,6 @@ var operations = [
3563
4041
  required: true,
3564
4042
  description: "Job ID"
3565
4043
  },
3566
- {
3567
- name: "stageId",
3568
- cliName: "stage-id",
3569
- optionKey: "stageId",
3570
- source: "path",
3571
- type: "string",
3572
- required: true,
3573
- description: "Stage ID"
3574
- },
3575
4044
  {
3576
4045
  name: "cursor",
3577
4046
  cliName: "cursor",
@@ -3591,15 +4060,25 @@ var operations = [
3591
4060
  description: "Maximum results to return (1-200)"
3592
4061
  }
3593
4062
  ],
3594
- hasRequestBody: false
4063
+ hasRequestBody: false,
4064
+ responseFields: [
4065
+ {
4066
+ name: "items",
4067
+ type: "array"
4068
+ },
4069
+ {
4070
+ name: "pagination",
4071
+ type: "object"
4072
+ }
4073
+ ]
3595
4074
  },
3596
4075
  {
3597
- operationId: "PublicApiJobController_getStageItem",
3598
- displayName: "Get stage item",
3599
- description: "Get a specific item within a stage.",
4076
+ operationId: "PublicApiJobController_getJobStage",
4077
+ displayName: "Get job stage",
4078
+ description: "Get a specific stage within a job.",
3600
4079
  method: "GET",
3601
- path: "/jobs/{id}/stages/{stageId}/items/{itemId}",
3602
- commandPath: ["jobs", "stages", "items", "get"],
4080
+ path: "/jobs/{id}/stages/{stageId}",
4081
+ commandPath: ["jobs", "stages", "get"],
3603
4082
  options: [
3604
4083
  {
3605
4084
  name: "id",
@@ -3618,18 +4097,293 @@ var operations = [
3618
4097
  type: "string",
3619
4098
  required: true,
3620
4099
  description: "Stage ID"
3621
- },
4100
+ }
4101
+ ],
4102
+ hasRequestBody: false,
4103
+ responseFields: [
3622
4104
  {
3623
- name: "itemId",
3624
- cliName: "item-id",
3625
- optionKey: "itemId",
3626
- source: "path",
4105
+ name: "id",
4106
+ type: "string",
4107
+ description: "Entity ID"
4108
+ },
4109
+ {
4110
+ name: "stageNumber",
4111
+ type: "string"
4112
+ },
4113
+ {
4114
+ name: "jobId",
4115
+ type: "string",
4116
+ description: "Job ID or job number (e.g. J12345)"
4117
+ },
4118
+ {
4119
+ name: "job",
4120
+ type: "object"
4121
+ },
4122
+ {
4123
+ name: "name",
4124
+ type: "string",
4125
+ description: "Display name"
4126
+ },
4127
+ {
4128
+ name: "description",
4129
+ type: "string",
4130
+ description: "Detailed description"
4131
+ },
4132
+ {
4133
+ name: "status",
4134
+ type: "object",
4135
+ description: "Status filter"
4136
+ },
4137
+ {
4138
+ name: "sequence",
4139
+ type: "number",
4140
+ description: "Display order / sequence number"
4141
+ },
4142
+ {
4143
+ name: "owner",
4144
+ type: "string"
4145
+ },
4146
+ {
4147
+ name: "contractor",
4148
+ type: "string"
4149
+ },
4150
+ {
4151
+ name: "technician",
4152
+ type: "string"
4153
+ },
4154
+ {
4155
+ name: "resources",
4156
+ type: "string"
4157
+ },
4158
+ {
4159
+ name: "startDate",
4160
+ type: "string",
4161
+ description: "Start date (ISO 8601 datetime)"
4162
+ },
4163
+ {
4164
+ name: "dueDate",
4165
+ type: "string",
4166
+ description: "Due date (ISO 8601 datetime)"
4167
+ },
4168
+ {
4169
+ name: "completedDate",
4170
+ type: "string",
4171
+ description: "Completion date (ISO 8601 datetime)"
4172
+ },
4173
+ {
4174
+ name: "completedBy",
4175
+ type: "string"
4176
+ },
4177
+ {
4178
+ name: "completedNote",
4179
+ type: "string"
4180
+ },
4181
+ {
4182
+ name: "finalisedDate",
4183
+ type: "string",
4184
+ description: "Finalisation date (ISO 8601 datetime)"
4185
+ },
4186
+ {
4187
+ name: "notes",
4188
+ type: "string",
4189
+ description: "Additional notes or comments"
4190
+ },
4191
+ {
4192
+ name: "tags",
4193
+ type: "string",
4194
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
4195
+ },
4196
+ {
4197
+ name: "schedulingTags",
4198
+ type: "string",
4199
+ description: "Scheduling tag operation — use set, add, or remove"
4200
+ },
4201
+ {
4202
+ name: "items",
4203
+ type: "array"
4204
+ },
4205
+ {
4206
+ name: "totals",
4207
+ type: "object"
4208
+ },
4209
+ {
4210
+ name: "customFields",
4211
+ type: "string",
4212
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
4213
+ },
4214
+ {
4215
+ name: "createdAt",
4216
+ type: "string"
4217
+ },
4218
+ {
4219
+ name: "updatedAt",
4220
+ type: "string",
4221
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
4222
+ }
4223
+ ]
4224
+ },
4225
+ {
4226
+ operationId: "PublicApiJobController_getStageItems",
4227
+ displayName: "List stage items",
4228
+ description: "Get all items (line items) for a stage.",
4229
+ method: "GET",
4230
+ path: "/jobs/{id}/stages/{stageId}/items",
4231
+ commandPath: ["jobs", "stages", "items", "list"],
4232
+ options: [
4233
+ {
4234
+ name: "id",
4235
+ cliName: "id",
4236
+ optionKey: "id",
4237
+ source: "path",
4238
+ type: "string",
4239
+ required: true,
4240
+ description: "Job ID"
4241
+ },
4242
+ {
4243
+ name: "stageId",
4244
+ cliName: "stage-id",
4245
+ optionKey: "stageId",
4246
+ source: "path",
4247
+ type: "string",
4248
+ required: true,
4249
+ description: "Stage ID"
4250
+ },
4251
+ {
4252
+ name: "cursor",
4253
+ cliName: "cursor",
4254
+ optionKey: "cursor",
4255
+ source: "query",
4256
+ type: "string",
4257
+ required: false,
4258
+ description: "Pagination cursor from previous response"
4259
+ },
4260
+ {
4261
+ name: "limit",
4262
+ cliName: "limit",
4263
+ optionKey: "limit",
4264
+ source: "query",
4265
+ type: "number",
4266
+ required: false,
4267
+ description: "Maximum results to return (1-200)"
4268
+ }
4269
+ ],
4270
+ hasRequestBody: false,
4271
+ responseFields: [
4272
+ {
4273
+ name: "items",
4274
+ type: "array"
4275
+ },
4276
+ {
4277
+ name: "pagination",
4278
+ type: "object"
4279
+ }
4280
+ ]
4281
+ },
4282
+ {
4283
+ operationId: "PublicApiJobController_getStageItem",
4284
+ displayName: "Get stage item",
4285
+ description: "Get a specific item within a stage.",
4286
+ method: "GET",
4287
+ path: "/jobs/{id}/stages/{stageId}/items/{itemId}",
4288
+ commandPath: ["jobs", "stages", "items", "get"],
4289
+ options: [
4290
+ {
4291
+ name: "id",
4292
+ cliName: "id",
4293
+ optionKey: "id",
4294
+ source: "path",
4295
+ type: "string",
4296
+ required: true,
4297
+ description: "Job ID"
4298
+ },
4299
+ {
4300
+ name: "stageId",
4301
+ cliName: "stage-id",
4302
+ optionKey: "stageId",
4303
+ source: "path",
4304
+ type: "string",
4305
+ required: true,
4306
+ description: "Stage ID"
4307
+ },
4308
+ {
4309
+ name: "itemId",
4310
+ cliName: "item-id",
4311
+ optionKey: "itemId",
4312
+ source: "path",
3627
4313
  type: "string",
3628
4314
  required: true,
3629
4315
  description: "Item ID"
3630
4316
  }
3631
4317
  ],
3632
- hasRequestBody: false
4318
+ hasRequestBody: false,
4319
+ responseFields: [
4320
+ {
4321
+ name: "id",
4322
+ type: "string",
4323
+ description: "Entity ID"
4324
+ },
4325
+ {
4326
+ name: "jobId",
4327
+ type: "string",
4328
+ description: "Job ID or job number (e.g. J12345)"
4329
+ },
4330
+ {
4331
+ name: "stageId",
4332
+ type: "string",
4333
+ description: "Stage ID or stage number"
4334
+ },
4335
+ {
4336
+ name: "code",
4337
+ type: "string"
4338
+ },
4339
+ {
4340
+ name: "description",
4341
+ type: "string",
4342
+ description: "Detailed description"
4343
+ },
4344
+ {
4345
+ name: "type",
4346
+ type: "string"
4347
+ },
4348
+ {
4349
+ name: "quantity",
4350
+ type: "number"
4351
+ },
4352
+ {
4353
+ name: "unit",
4354
+ type: "string"
4355
+ },
4356
+ {
4357
+ name: "status",
4358
+ type: "string",
4359
+ description: "Status filter"
4360
+ },
4361
+ {
4362
+ name: "buyPrice",
4363
+ type: "number"
4364
+ },
4365
+ {
4366
+ name: "sellPrice",
4367
+ type: "number"
4368
+ },
4369
+ {
4370
+ name: "invoicingStatus",
4371
+ type: "string"
4372
+ },
4373
+ {
4374
+ name: "suppliedBySubcontractor",
4375
+ type: "boolean"
4376
+ },
4377
+ {
4378
+ name: "createdAt",
4379
+ type: "string"
4380
+ },
4381
+ {
4382
+ name: "updatedAt",
4383
+ type: "string",
4384
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
4385
+ }
4386
+ ]
3633
4387
  },
3634
4388
  {
3635
4389
  operationId: "PublicJobStageController_create",
@@ -3664,7 +4418,8 @@ var operations = [
3664
4418
  source: "body",
3665
4419
  type: "string",
3666
4420
  required: false,
3667
- description: "Work category ID — use /settings/work-types to look up"
4421
+ description: "Work category ID — use /settings/work-types to look up",
4422
+ lookupEndpoint: "/settings/work-types"
3668
4423
  },
3669
4424
  {
3670
4425
  name: "sequence",
@@ -3721,42 +4476,164 @@ var operations = [
3721
4476
  description: "Raw request body JSON (overrides individual fields)"
3722
4477
  }
3723
4478
  ],
3724
- hasRequestBody: true
3725
- },
3726
- {
3727
- operationId: "PublicJobStageController_update",
3728
- displayName: "Update a stage",
3729
- description: "Partially update a stage. Only provided fields will be modified.",
3730
- method: "PATCH",
3731
- path: "/stages/{id}",
3732
- commandPath: ["stages", "update"],
3733
- options: [
4479
+ hasRequestBody: true,
4480
+ responseFields: [
3734
4481
  {
3735
4482
  name: "id",
3736
- cliName: "id",
3737
- optionKey: "id",
3738
- source: "path",
3739
4483
  type: "string",
3740
- required: true,
3741
- description: "Stage ID"
4484
+ description: "Entity ID"
4485
+ },
4486
+ {
4487
+ name: "stageNumber",
4488
+ type: "string"
4489
+ },
4490
+ {
4491
+ name: "jobId",
4492
+ type: "string",
4493
+ description: "Job ID or job number (e.g. J12345)"
4494
+ },
4495
+ {
4496
+ name: "job",
4497
+ type: "object"
3742
4498
  },
3743
4499
  {
3744
4500
  name: "name",
3745
- cliName: "name",
3746
- optionKey: "name",
3747
- source: "body",
3748
4501
  type: "string",
3749
- required: false,
3750
4502
  description: "Display name"
3751
4503
  },
3752
4504
  {
3753
- name: "workCategoryId",
3754
- cliName: "work-category-id",
3755
- optionKey: "workCategoryId",
3756
- source: "body",
4505
+ name: "description",
4506
+ type: "string",
4507
+ description: "Detailed description"
4508
+ },
4509
+ {
4510
+ name: "status",
4511
+ type: "object",
4512
+ description: "Status filter"
4513
+ },
4514
+ {
4515
+ name: "sequence",
4516
+ type: "number",
4517
+ description: "Display order / sequence number"
4518
+ },
4519
+ {
4520
+ name: "owner",
4521
+ type: "string"
4522
+ },
4523
+ {
4524
+ name: "contractor",
4525
+ type: "string"
4526
+ },
4527
+ {
4528
+ name: "technician",
4529
+ type: "string"
4530
+ },
4531
+ {
4532
+ name: "resources",
4533
+ type: "string"
4534
+ },
4535
+ {
4536
+ name: "startDate",
4537
+ type: "string",
4538
+ description: "Start date (ISO 8601 datetime)"
4539
+ },
4540
+ {
4541
+ name: "dueDate",
4542
+ type: "string",
4543
+ description: "Due date (ISO 8601 datetime)"
4544
+ },
4545
+ {
4546
+ name: "completedDate",
4547
+ type: "string",
4548
+ description: "Completion date (ISO 8601 datetime)"
4549
+ },
4550
+ {
4551
+ name: "completedBy",
4552
+ type: "string"
4553
+ },
4554
+ {
4555
+ name: "completedNote",
4556
+ type: "string"
4557
+ },
4558
+ {
4559
+ name: "finalisedDate",
4560
+ type: "string",
4561
+ description: "Finalisation date (ISO 8601 datetime)"
4562
+ },
4563
+ {
4564
+ name: "notes",
4565
+ type: "string",
4566
+ description: "Additional notes or comments"
4567
+ },
4568
+ {
4569
+ name: "tags",
4570
+ type: "string",
4571
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
4572
+ },
4573
+ {
4574
+ name: "schedulingTags",
4575
+ type: "string",
4576
+ description: "Scheduling tag operation — use set, add, or remove"
4577
+ },
4578
+ {
4579
+ name: "items",
4580
+ type: "array"
4581
+ },
4582
+ {
4583
+ name: "totals",
4584
+ type: "object"
4585
+ },
4586
+ {
4587
+ name: "customFields",
4588
+ type: "string",
4589
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
4590
+ },
4591
+ {
4592
+ name: "createdAt",
4593
+ type: "string"
4594
+ },
4595
+ {
4596
+ name: "updatedAt",
4597
+ type: "string",
4598
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
4599
+ }
4600
+ ]
4601
+ },
4602
+ {
4603
+ operationId: "PublicJobStageController_update",
4604
+ displayName: "Update a stage",
4605
+ description: "Partially update a stage. Only provided fields will be modified.",
4606
+ method: "PATCH",
4607
+ path: "/stages/{id}",
4608
+ commandPath: ["stages", "update"],
4609
+ options: [
4610
+ {
4611
+ name: "id",
4612
+ cliName: "id",
4613
+ optionKey: "id",
4614
+ source: "path",
4615
+ type: "string",
4616
+ required: true,
4617
+ description: "Stage ID"
4618
+ },
4619
+ {
4620
+ name: "name",
4621
+ cliName: "name",
4622
+ optionKey: "name",
4623
+ source: "body",
4624
+ type: "string",
4625
+ required: false,
4626
+ description: "Display name"
4627
+ },
4628
+ {
4629
+ name: "workCategoryId",
4630
+ cliName: "work-category-id",
4631
+ optionKey: "workCategoryId",
4632
+ source: "body",
3757
4633
  type: "string",
3758
4634
  required: false,
3759
- description: "Work category ID — use /settings/work-types to look up"
4635
+ description: "Work category ID — use /settings/work-types to look up",
4636
+ lookupEndpoint: "/settings/work-types"
3760
4637
  },
3761
4638
  {
3762
4639
  name: "startDate",
@@ -3864,7 +4741,128 @@ var operations = [
3864
4741
  description: "Raw request body JSON (overrides individual fields)"
3865
4742
  }
3866
4743
  ],
3867
- hasRequestBody: true
4744
+ hasRequestBody: true,
4745
+ responseFields: [
4746
+ {
4747
+ name: "id",
4748
+ type: "string",
4749
+ description: "Entity ID"
4750
+ },
4751
+ {
4752
+ name: "stageNumber",
4753
+ type: "string"
4754
+ },
4755
+ {
4756
+ name: "jobId",
4757
+ type: "string",
4758
+ description: "Job ID or job number (e.g. J12345)"
4759
+ },
4760
+ {
4761
+ name: "job",
4762
+ type: "object"
4763
+ },
4764
+ {
4765
+ name: "name",
4766
+ type: "string",
4767
+ description: "Display name"
4768
+ },
4769
+ {
4770
+ name: "description",
4771
+ type: "string",
4772
+ description: "Detailed description"
4773
+ },
4774
+ {
4775
+ name: "status",
4776
+ type: "object",
4777
+ description: "Status filter"
4778
+ },
4779
+ {
4780
+ name: "sequence",
4781
+ type: "number",
4782
+ description: "Display order / sequence number"
4783
+ },
4784
+ {
4785
+ name: "owner",
4786
+ type: "string"
4787
+ },
4788
+ {
4789
+ name: "contractor",
4790
+ type: "string"
4791
+ },
4792
+ {
4793
+ name: "technician",
4794
+ type: "string"
4795
+ },
4796
+ {
4797
+ name: "resources",
4798
+ type: "string"
4799
+ },
4800
+ {
4801
+ name: "startDate",
4802
+ type: "string",
4803
+ description: "Start date (ISO 8601 datetime)"
4804
+ },
4805
+ {
4806
+ name: "dueDate",
4807
+ type: "string",
4808
+ description: "Due date (ISO 8601 datetime)"
4809
+ },
4810
+ {
4811
+ name: "completedDate",
4812
+ type: "string",
4813
+ description: "Completion date (ISO 8601 datetime)"
4814
+ },
4815
+ {
4816
+ name: "completedBy",
4817
+ type: "string"
4818
+ },
4819
+ {
4820
+ name: "completedNote",
4821
+ type: "string"
4822
+ },
4823
+ {
4824
+ name: "finalisedDate",
4825
+ type: "string",
4826
+ description: "Finalisation date (ISO 8601 datetime)"
4827
+ },
4828
+ {
4829
+ name: "notes",
4830
+ type: "string",
4831
+ description: "Additional notes or comments"
4832
+ },
4833
+ {
4834
+ name: "tags",
4835
+ type: "string",
4836
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
4837
+ },
4838
+ {
4839
+ name: "schedulingTags",
4840
+ type: "string",
4841
+ description: "Scheduling tag operation — use set, add, or remove"
4842
+ },
4843
+ {
4844
+ name: "items",
4845
+ type: "array"
4846
+ },
4847
+ {
4848
+ name: "totals",
4849
+ type: "object"
4850
+ },
4851
+ {
4852
+ name: "customFields",
4853
+ type: "string",
4854
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
4855
+ },
4856
+ {
4857
+ name: "createdAt",
4858
+ type: "string"
4859
+ },
4860
+ {
4861
+ name: "updatedAt",
4862
+ type: "string",
4863
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
4864
+ }
4865
+ ]
3868
4866
  },
3869
4867
  {
3870
4868
  operationId: "PublicJobStageController_delete",
@@ -3884,7 +4882,13 @@ var operations = [
3884
4882
  description: "Stage ID"
3885
4883
  }
3886
4884
  ],
3887
- hasRequestBody: false
4885
+ hasRequestBody: false,
4886
+ responseFields: [
4887
+ {
4888
+ name: "deleted",
4889
+ type: "boolean"
4890
+ }
4891
+ ]
3888
4892
  },
3889
4893
  {
3890
4894
  operationId: "PublicJobStageController_dispatch",
@@ -3904,58 +4908,300 @@ var operations = [
3904
4908
  description: "Stage ID"
3905
4909
  }
3906
4910
  ],
3907
- hasRequestBody: false
3908
- },
3909
- {
3910
- operationId: "PublicJobStageController_complete",
3911
- displayName: "Complete a stage",
3912
- description: "Mark a stage as completed. Field work is done but stage may still need finalisation/billing.",
3913
- method: "POST",
3914
- path: "/stages/{id}/complete",
3915
- commandPath: ["stages", "complete"],
3916
- options: [
4911
+ hasRequestBody: false,
4912
+ responseFields: [
3917
4913
  {
3918
4914
  name: "id",
3919
- cliName: "id",
3920
- optionKey: "id",
3921
- source: "path",
3922
4915
  type: "string",
3923
- required: true,
3924
- description: "Stage ID"
4916
+ description: "Entity ID"
3925
4917
  },
3926
4918
  {
3927
- name: "completedDate",
3928
- cliName: "completed-date",
3929
- optionKey: "completedDate",
3930
- source: "body",
4919
+ name: "stageNumber",
4920
+ type: "string"
4921
+ },
4922
+ {
4923
+ name: "jobId",
3931
4924
  type: "string",
3932
- required: false,
3933
- description: "Completion date (ISO 8601 datetime)",
3934
- format: "date-time"
4925
+ description: "Job ID or job number (e.g. J12345)"
3935
4926
  },
3936
4927
  {
3937
- name: "notes",
3938
- cliName: "notes",
3939
- optionKey: "notes",
3940
- source: "body",
4928
+ name: "job",
4929
+ type: "object"
4930
+ },
4931
+ {
4932
+ name: "name",
3941
4933
  type: "string",
3942
- required: false,
3943
- description: "Additional notes or comments"
4934
+ description: "Display name"
3944
4935
  },
3945
4936
  {
3946
- name: "raw-body",
3947
- cliName: "raw-body",
3948
- optionKey: "rawBody",
3949
- source: "body",
4937
+ name: "description",
4938
+ type: "string",
4939
+ description: "Detailed description"
4940
+ },
4941
+ {
4942
+ name: "status",
3950
4943
  type: "object",
3951
- required: false,
3952
- description: "Raw request body JSON (overrides individual fields)"
3953
- }
3954
- ],
3955
- hasRequestBody: true
3956
- },
3957
- {
3958
- operationId: "PublicJobStageController_finalise",
4944
+ description: "Status filter"
4945
+ },
4946
+ {
4947
+ name: "sequence",
4948
+ type: "number",
4949
+ description: "Display order / sequence number"
4950
+ },
4951
+ {
4952
+ name: "owner",
4953
+ type: "string"
4954
+ },
4955
+ {
4956
+ name: "contractor",
4957
+ type: "string"
4958
+ },
4959
+ {
4960
+ name: "technician",
4961
+ type: "string"
4962
+ },
4963
+ {
4964
+ name: "resources",
4965
+ type: "string"
4966
+ },
4967
+ {
4968
+ name: "startDate",
4969
+ type: "string",
4970
+ description: "Start date (ISO 8601 datetime)"
4971
+ },
4972
+ {
4973
+ name: "dueDate",
4974
+ type: "string",
4975
+ description: "Due date (ISO 8601 datetime)"
4976
+ },
4977
+ {
4978
+ name: "completedDate",
4979
+ type: "string",
4980
+ description: "Completion date (ISO 8601 datetime)"
4981
+ },
4982
+ {
4983
+ name: "completedBy",
4984
+ type: "string"
4985
+ },
4986
+ {
4987
+ name: "completedNote",
4988
+ type: "string"
4989
+ },
4990
+ {
4991
+ name: "finalisedDate",
4992
+ type: "string",
4993
+ description: "Finalisation date (ISO 8601 datetime)"
4994
+ },
4995
+ {
4996
+ name: "notes",
4997
+ type: "string",
4998
+ description: "Additional notes or comments"
4999
+ },
5000
+ {
5001
+ name: "tags",
5002
+ type: "string",
5003
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
5004
+ },
5005
+ {
5006
+ name: "schedulingTags",
5007
+ type: "string",
5008
+ description: "Scheduling tag operation — use set, add, or remove"
5009
+ },
5010
+ {
5011
+ name: "items",
5012
+ type: "array"
5013
+ },
5014
+ {
5015
+ name: "totals",
5016
+ type: "object"
5017
+ },
5018
+ {
5019
+ name: "customFields",
5020
+ type: "string",
5021
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
5022
+ },
5023
+ {
5024
+ name: "createdAt",
5025
+ type: "string"
5026
+ },
5027
+ {
5028
+ name: "updatedAt",
5029
+ type: "string",
5030
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
5031
+ }
5032
+ ]
5033
+ },
5034
+ {
5035
+ operationId: "PublicJobStageController_complete",
5036
+ displayName: "Complete a stage",
5037
+ description: "Mark a stage as completed. Field work is done but stage may still need finalisation/billing.",
5038
+ method: "POST",
5039
+ path: "/stages/{id}/complete",
5040
+ commandPath: ["stages", "complete"],
5041
+ options: [
5042
+ {
5043
+ name: "id",
5044
+ cliName: "id",
5045
+ optionKey: "id",
5046
+ source: "path",
5047
+ type: "string",
5048
+ required: true,
5049
+ description: "Stage ID"
5050
+ },
5051
+ {
5052
+ name: "completedDate",
5053
+ cliName: "completed-date",
5054
+ optionKey: "completedDate",
5055
+ source: "body",
5056
+ type: "string",
5057
+ required: false,
5058
+ description: "Completion date (ISO 8601 datetime)",
5059
+ format: "date-time"
5060
+ },
5061
+ {
5062
+ name: "notes",
5063
+ cliName: "notes",
5064
+ optionKey: "notes",
5065
+ source: "body",
5066
+ type: "string",
5067
+ required: false,
5068
+ description: "Additional notes or comments"
5069
+ },
5070
+ {
5071
+ name: "raw-body",
5072
+ cliName: "raw-body",
5073
+ optionKey: "rawBody",
5074
+ source: "body",
5075
+ type: "object",
5076
+ required: false,
5077
+ description: "Raw request body JSON (overrides individual fields)"
5078
+ }
5079
+ ],
5080
+ hasRequestBody: true,
5081
+ responseFields: [
5082
+ {
5083
+ name: "id",
5084
+ type: "string",
5085
+ description: "Entity ID"
5086
+ },
5087
+ {
5088
+ name: "stageNumber",
5089
+ type: "string"
5090
+ },
5091
+ {
5092
+ name: "jobId",
5093
+ type: "string",
5094
+ description: "Job ID or job number (e.g. J12345)"
5095
+ },
5096
+ {
5097
+ name: "job",
5098
+ type: "object"
5099
+ },
5100
+ {
5101
+ name: "name",
5102
+ type: "string",
5103
+ description: "Display name"
5104
+ },
5105
+ {
5106
+ name: "description",
5107
+ type: "string",
5108
+ description: "Detailed description"
5109
+ },
5110
+ {
5111
+ name: "status",
5112
+ type: "object",
5113
+ description: "Status filter"
5114
+ },
5115
+ {
5116
+ name: "sequence",
5117
+ type: "number",
5118
+ description: "Display order / sequence number"
5119
+ },
5120
+ {
5121
+ name: "owner",
5122
+ type: "string"
5123
+ },
5124
+ {
5125
+ name: "contractor",
5126
+ type: "string"
5127
+ },
5128
+ {
5129
+ name: "technician",
5130
+ type: "string"
5131
+ },
5132
+ {
5133
+ name: "resources",
5134
+ type: "string"
5135
+ },
5136
+ {
5137
+ name: "startDate",
5138
+ type: "string",
5139
+ description: "Start date (ISO 8601 datetime)"
5140
+ },
5141
+ {
5142
+ name: "dueDate",
5143
+ type: "string",
5144
+ description: "Due date (ISO 8601 datetime)"
5145
+ },
5146
+ {
5147
+ name: "completedDate",
5148
+ type: "string",
5149
+ description: "Completion date (ISO 8601 datetime)"
5150
+ },
5151
+ {
5152
+ name: "completedBy",
5153
+ type: "string"
5154
+ },
5155
+ {
5156
+ name: "completedNote",
5157
+ type: "string"
5158
+ },
5159
+ {
5160
+ name: "finalisedDate",
5161
+ type: "string",
5162
+ description: "Finalisation date (ISO 8601 datetime)"
5163
+ },
5164
+ {
5165
+ name: "notes",
5166
+ type: "string",
5167
+ description: "Additional notes or comments"
5168
+ },
5169
+ {
5170
+ name: "tags",
5171
+ type: "string",
5172
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
5173
+ },
5174
+ {
5175
+ name: "schedulingTags",
5176
+ type: "string",
5177
+ description: "Scheduling tag operation — use set, add, or remove"
5178
+ },
5179
+ {
5180
+ name: "items",
5181
+ type: "array"
5182
+ },
5183
+ {
5184
+ name: "totals",
5185
+ type: "object"
5186
+ },
5187
+ {
5188
+ name: "customFields",
5189
+ type: "string",
5190
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
5191
+ },
5192
+ {
5193
+ name: "createdAt",
5194
+ type: "string"
5195
+ },
5196
+ {
5197
+ name: "updatedAt",
5198
+ type: "string",
5199
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
5200
+ }
5201
+ ]
5202
+ },
5203
+ {
5204
+ operationId: "PublicJobStageController_finalise",
3959
5205
  displayName: "Finalise a stage",
3960
5206
  description: "Finalise a completed stage. This typically indicates billing/invoicing is complete.",
3961
5207
  method: "POST",
@@ -3991,7 +5237,128 @@ var operations = [
3991
5237
  description: "Raw request body JSON (overrides individual fields)"
3992
5238
  }
3993
5239
  ],
3994
- hasRequestBody: true
5240
+ hasRequestBody: true,
5241
+ responseFields: [
5242
+ {
5243
+ name: "id",
5244
+ type: "string",
5245
+ description: "Entity ID"
5246
+ },
5247
+ {
5248
+ name: "stageNumber",
5249
+ type: "string"
5250
+ },
5251
+ {
5252
+ name: "jobId",
5253
+ type: "string",
5254
+ description: "Job ID or job number (e.g. J12345)"
5255
+ },
5256
+ {
5257
+ name: "job",
5258
+ type: "object"
5259
+ },
5260
+ {
5261
+ name: "name",
5262
+ type: "string",
5263
+ description: "Display name"
5264
+ },
5265
+ {
5266
+ name: "description",
5267
+ type: "string",
5268
+ description: "Detailed description"
5269
+ },
5270
+ {
5271
+ name: "status",
5272
+ type: "object",
5273
+ description: "Status filter"
5274
+ },
5275
+ {
5276
+ name: "sequence",
5277
+ type: "number",
5278
+ description: "Display order / sequence number"
5279
+ },
5280
+ {
5281
+ name: "owner",
5282
+ type: "string"
5283
+ },
5284
+ {
5285
+ name: "contractor",
5286
+ type: "string"
5287
+ },
5288
+ {
5289
+ name: "technician",
5290
+ type: "string"
5291
+ },
5292
+ {
5293
+ name: "resources",
5294
+ type: "string"
5295
+ },
5296
+ {
5297
+ name: "startDate",
5298
+ type: "string",
5299
+ description: "Start date (ISO 8601 datetime)"
5300
+ },
5301
+ {
5302
+ name: "dueDate",
5303
+ type: "string",
5304
+ description: "Due date (ISO 8601 datetime)"
5305
+ },
5306
+ {
5307
+ name: "completedDate",
5308
+ type: "string",
5309
+ description: "Completion date (ISO 8601 datetime)"
5310
+ },
5311
+ {
5312
+ name: "completedBy",
5313
+ type: "string"
5314
+ },
5315
+ {
5316
+ name: "completedNote",
5317
+ type: "string"
5318
+ },
5319
+ {
5320
+ name: "finalisedDate",
5321
+ type: "string",
5322
+ description: "Finalisation date (ISO 8601 datetime)"
5323
+ },
5324
+ {
5325
+ name: "notes",
5326
+ type: "string",
5327
+ description: "Additional notes or comments"
5328
+ },
5329
+ {
5330
+ name: "tags",
5331
+ type: "string",
5332
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
5333
+ },
5334
+ {
5335
+ name: "schedulingTags",
5336
+ type: "string",
5337
+ description: "Scheduling tag operation — use set, add, or remove"
5338
+ },
5339
+ {
5340
+ name: "items",
5341
+ type: "array"
5342
+ },
5343
+ {
5344
+ name: "totals",
5345
+ type: "object"
5346
+ },
5347
+ {
5348
+ name: "customFields",
5349
+ type: "string",
5350
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
5351
+ },
5352
+ {
5353
+ name: "createdAt",
5354
+ type: "string"
5355
+ },
5356
+ {
5357
+ name: "updatedAt",
5358
+ type: "string",
5359
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
5360
+ }
5361
+ ]
3995
5362
  },
3996
5363
  {
3997
5364
  operationId: "PublicJobStageController_cancel",
@@ -4029,7 +5396,128 @@ var operations = [
4029
5396
  description: "Raw request body JSON (overrides individual fields)"
4030
5397
  }
4031
5398
  ],
4032
- hasRequestBody: true
5399
+ hasRequestBody: true,
5400
+ responseFields: [
5401
+ {
5402
+ name: "id",
5403
+ type: "string",
5404
+ description: "Entity ID"
5405
+ },
5406
+ {
5407
+ name: "stageNumber",
5408
+ type: "string"
5409
+ },
5410
+ {
5411
+ name: "jobId",
5412
+ type: "string",
5413
+ description: "Job ID or job number (e.g. J12345)"
5414
+ },
5415
+ {
5416
+ name: "job",
5417
+ type: "object"
5418
+ },
5419
+ {
5420
+ name: "name",
5421
+ type: "string",
5422
+ description: "Display name"
5423
+ },
5424
+ {
5425
+ name: "description",
5426
+ type: "string",
5427
+ description: "Detailed description"
5428
+ },
5429
+ {
5430
+ name: "status",
5431
+ type: "object",
5432
+ description: "Status filter"
5433
+ },
5434
+ {
5435
+ name: "sequence",
5436
+ type: "number",
5437
+ description: "Display order / sequence number"
5438
+ },
5439
+ {
5440
+ name: "owner",
5441
+ type: "string"
5442
+ },
5443
+ {
5444
+ name: "contractor",
5445
+ type: "string"
5446
+ },
5447
+ {
5448
+ name: "technician",
5449
+ type: "string"
5450
+ },
5451
+ {
5452
+ name: "resources",
5453
+ type: "string"
5454
+ },
5455
+ {
5456
+ name: "startDate",
5457
+ type: "string",
5458
+ description: "Start date (ISO 8601 datetime)"
5459
+ },
5460
+ {
5461
+ name: "dueDate",
5462
+ type: "string",
5463
+ description: "Due date (ISO 8601 datetime)"
5464
+ },
5465
+ {
5466
+ name: "completedDate",
5467
+ type: "string",
5468
+ description: "Completion date (ISO 8601 datetime)"
5469
+ },
5470
+ {
5471
+ name: "completedBy",
5472
+ type: "string"
5473
+ },
5474
+ {
5475
+ name: "completedNote",
5476
+ type: "string"
5477
+ },
5478
+ {
5479
+ name: "finalisedDate",
5480
+ type: "string",
5481
+ description: "Finalisation date (ISO 8601 datetime)"
5482
+ },
5483
+ {
5484
+ name: "notes",
5485
+ type: "string",
5486
+ description: "Additional notes or comments"
5487
+ },
5488
+ {
5489
+ name: "tags",
5490
+ type: "string",
5491
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
5492
+ },
5493
+ {
5494
+ name: "schedulingTags",
5495
+ type: "string",
5496
+ description: "Scheduling tag operation — use set, add, or remove"
5497
+ },
5498
+ {
5499
+ name: "items",
5500
+ type: "array"
5501
+ },
5502
+ {
5503
+ name: "totals",
5504
+ type: "object"
5505
+ },
5506
+ {
5507
+ name: "customFields",
5508
+ type: "string",
5509
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
5510
+ },
5511
+ {
5512
+ name: "createdAt",
5513
+ type: "string"
5514
+ },
5515
+ {
5516
+ name: "updatedAt",
5517
+ type: "string",
5518
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
5519
+ }
5520
+ ]
4033
5521
  },
4034
5522
  {
4035
5523
  operationId: "PublicJobStageController_reverse",
@@ -4040,44 +5528,165 @@ var operations = [
4040
5528
  commandPath: ["stages", "reverse"],
4041
5529
  options: [
4042
5530
  {
4043
- name: "id",
4044
- cliName: "id",
4045
- optionKey: "id",
4046
- source: "path",
5531
+ name: "id",
5532
+ cliName: "id",
5533
+ optionKey: "id",
5534
+ source: "path",
5535
+ type: "string",
5536
+ required: true,
5537
+ description: "Stage ID"
5538
+ },
5539
+ {
5540
+ name: "targetStatus",
5541
+ cliName: "target-status",
5542
+ optionKey: "targetStatus",
5543
+ source: "body",
5544
+ type: "string",
5545
+ required: true,
5546
+ description: "",
5547
+ enumValues: ["new", "assigned", "dispatched", "in_progress", "on_hold", "completed", "finalised"]
5548
+ },
5549
+ {
5550
+ name: "note",
5551
+ cliName: "note",
5552
+ optionKey: "note",
5553
+ source: "body",
5554
+ type: "string",
5555
+ required: false,
5556
+ description: ""
5557
+ },
5558
+ {
5559
+ name: "raw-body",
5560
+ cliName: "raw-body",
5561
+ optionKey: "rawBody",
5562
+ source: "body",
5563
+ type: "object",
5564
+ required: false,
5565
+ description: "Raw request body JSON (overrides individual fields)"
5566
+ }
5567
+ ],
5568
+ hasRequestBody: true,
5569
+ responseFields: [
5570
+ {
5571
+ name: "id",
5572
+ type: "string",
5573
+ description: "Entity ID"
5574
+ },
5575
+ {
5576
+ name: "stageNumber",
5577
+ type: "string"
5578
+ },
5579
+ {
5580
+ name: "jobId",
5581
+ type: "string",
5582
+ description: "Job ID or job number (e.g. J12345)"
5583
+ },
5584
+ {
5585
+ name: "job",
5586
+ type: "object"
5587
+ },
5588
+ {
5589
+ name: "name",
5590
+ type: "string",
5591
+ description: "Display name"
5592
+ },
5593
+ {
5594
+ name: "description",
5595
+ type: "string",
5596
+ description: "Detailed description"
5597
+ },
5598
+ {
5599
+ name: "status",
5600
+ type: "object",
5601
+ description: "Status filter"
5602
+ },
5603
+ {
5604
+ name: "sequence",
5605
+ type: "number",
5606
+ description: "Display order / sequence number"
5607
+ },
5608
+ {
5609
+ name: "owner",
5610
+ type: "string"
5611
+ },
5612
+ {
5613
+ name: "contractor",
5614
+ type: "string"
5615
+ },
5616
+ {
5617
+ name: "technician",
5618
+ type: "string"
5619
+ },
5620
+ {
5621
+ name: "resources",
5622
+ type: "string"
5623
+ },
5624
+ {
5625
+ name: "startDate",
5626
+ type: "string",
5627
+ description: "Start date (ISO 8601 datetime)"
5628
+ },
5629
+ {
5630
+ name: "dueDate",
5631
+ type: "string",
5632
+ description: "Due date (ISO 8601 datetime)"
5633
+ },
5634
+ {
5635
+ name: "completedDate",
5636
+ type: "string",
5637
+ description: "Completion date (ISO 8601 datetime)"
5638
+ },
5639
+ {
5640
+ name: "completedBy",
5641
+ type: "string"
5642
+ },
5643
+ {
5644
+ name: "completedNote",
5645
+ type: "string"
5646
+ },
5647
+ {
5648
+ name: "finalisedDate",
4047
5649
  type: "string",
4048
- required: true,
4049
- description: "Stage ID"
5650
+ description: "Finalisation date (ISO 8601 datetime)"
4050
5651
  },
4051
5652
  {
4052
- name: "targetStatus",
4053
- cliName: "target-status",
4054
- optionKey: "targetStatus",
4055
- source: "body",
5653
+ name: "notes",
4056
5654
  type: "string",
4057
- required: true,
4058
- description: "",
4059
- enumValues: ["new", "assigned", "dispatched", "in_progress", "on_hold", "completed", "finalised"]
5655
+ description: "Additional notes or comments"
4060
5656
  },
4061
5657
  {
4062
- name: "note",
4063
- cliName: "note",
4064
- optionKey: "note",
4065
- source: "body",
5658
+ name: "tags",
4066
5659
  type: "string",
4067
- required: false,
4068
- description: ""
5660
+ description: "Tag operation — use set, add, or remove (mutually exclusive: set vs add/remove)"
4069
5661
  },
4070
5662
  {
4071
- name: "raw-body",
4072
- cliName: "raw-body",
4073
- optionKey: "rawBody",
4074
- source: "body",
4075
- type: "object",
4076
- required: false,
4077
- description: "Raw request body JSON (overrides individual fields)"
5663
+ name: "schedulingTags",
5664
+ type: "string",
5665
+ description: "Scheduling tag operation — use set, add, or remove"
5666
+ },
5667
+ {
5668
+ name: "items",
5669
+ type: "array"
5670
+ },
5671
+ {
5672
+ name: "totals",
5673
+ type: "object"
5674
+ },
5675
+ {
5676
+ name: "customFields",
5677
+ type: "string",
5678
+ description: "Custom fields as key-value pairs — validated against tenant field definitions"
5679
+ },
5680
+ {
5681
+ name: "createdAt",
5682
+ type: "string"
5683
+ },
5684
+ {
5685
+ name: "updatedAt",
5686
+ type: "string",
5687
+ description: "For optimistic concurrency — update fails if entity was modified after this timestamp"
4078
5688
  }
4079
- ],
4080
- hasRequestBody: true
5689
+ ]
4081
5690
  },
4082
5691
  {
4083
5692
  operationId: "PublicJobStageController_reissue",
@@ -4097,7 +5706,13 @@ var operations = [
4097
5706
  description: "Stage ID"
4098
5707
  }
4099
5708
  ],
4100
- hasRequestBody: false
5709
+ hasRequestBody: false,
5710
+ responseFields: [
5711
+ {
5712
+ name: "reissuedCount",
5713
+ type: "number"
5714
+ }
5715
+ ]
4101
5716
  },
4102
5717
  {
4103
5718
  operationId: "PublicJobStageResourceController_list",
@@ -4144,7 +5759,17 @@ var operations = [
4144
5759
  description: "Max results (1-200)"
4145
5760
  }
4146
5761
  ],
4147
- hasRequestBody: false
5762
+ hasRequestBody: false,
5763
+ responseFields: [
5764
+ {
5765
+ name: "items",
5766
+ type: "array"
5767
+ },
5768
+ {
5769
+ name: "pagination",
5770
+ type: "object"
5771
+ }
5772
+ ]
4148
5773
  },
4149
5774
  {
4150
5775
  operationId: "PublicJobStageResourceController_assign",
@@ -4188,7 +5813,8 @@ var operations = [
4188
5813
  source: "body",
4189
5814
  type: "string",
4190
5815
  required: true,
4191
- description: "Contact ID — use /crm/contacts to look up"
5816
+ description: "Contact ID — use /crm/contacts to look up",
5817
+ lookupEndpoint: "/crm/contacts"
4192
5818
  },
4193
5819
  {
4194
5820
  name: "raw-body",
@@ -4200,7 +5826,36 @@ var operations = [
4200
5826
  description: "Raw request body JSON (overrides individual fields)"
4201
5827
  }
4202
5828
  ],
4203
- hasRequestBody: true
5829
+ hasRequestBody: true,
5830
+ responseFields: [
5831
+ {
5832
+ name: "id",
5833
+ type: "string",
5834
+ description: "Entity ID"
5835
+ },
5836
+ {
5837
+ name: "status",
5838
+ type: "string",
5839
+ description: "Status filter"
5840
+ },
5841
+ {
5842
+ name: "contact",
5843
+ type: "string",
5844
+ description: "Inline contact object — alternative to contactId"
5845
+ },
5846
+ {
5847
+ name: "isContractor",
5848
+ type: "boolean"
5849
+ },
5850
+ {
5851
+ name: "assignedAt",
5852
+ type: "string"
5853
+ },
5854
+ {
5855
+ name: "dispatchedAt",
5856
+ type: "string"
5857
+ }
5858
+ ]
4204
5859
  },
4205
5860
  {
4206
5861
  operationId: "PublicJobStageResourceController_get",
@@ -4238,7 +5893,36 @@ var operations = [
4238
5893
  description: "Resource ID"
4239
5894
  }
4240
5895
  ],
4241
- hasRequestBody: false
5896
+ hasRequestBody: false,
5897
+ responseFields: [
5898
+ {
5899
+ name: "id",
5900
+ type: "string",
5901
+ description: "Entity ID"
5902
+ },
5903
+ {
5904
+ name: "status",
5905
+ type: "string",
5906
+ description: "Status filter"
5907
+ },
5908
+ {
5909
+ name: "contact",
5910
+ type: "string",
5911
+ description: "Inline contact object — alternative to contactId"
5912
+ },
5913
+ {
5914
+ name: "isContractor",
5915
+ type: "boolean"
5916
+ },
5917
+ {
5918
+ name: "assignedAt",
5919
+ type: "string"
5920
+ },
5921
+ {
5922
+ name: "dispatchedAt",
5923
+ type: "string"
5924
+ }
5925
+ ]
4242
5926
  },
4243
5927
  {
4244
5928
  operationId: "PublicJobStageResourceController_unassign",
@@ -4409,7 +6093,13 @@ var operations = [
4409
6093
  description: "Entity type (customer, contractor, supplier)"
4410
6094
  }
4411
6095
  ],
4412
- hasRequestBody: false
6096
+ hasRequestBody: false,
6097
+ responseFields: [
6098
+ {
6099
+ name: "items",
6100
+ type: "array"
6101
+ }
6102
+ ]
4413
6103
  },
4414
6104
  {
4415
6105
  operationId: "PublicApiJobStatusController_list",
@@ -4419,7 +6109,13 @@ var operations = [
4419
6109
  path: "/settings/job-statuses",
4420
6110
  commandPath: ["settings", "job-statuses", "list"],
4421
6111
  options: [],
4422
- hasRequestBody: false
6112
+ hasRequestBody: false,
6113
+ responseFields: [
6114
+ {
6115
+ name: "items",
6116
+ type: "array"
6117
+ }
6118
+ ]
4423
6119
  },
4424
6120
  {
4425
6121
  operationId: "PublicApiJobTypeController_list",
@@ -4429,7 +6125,13 @@ var operations = [
4429
6125
  path: "/settings/job-types",
4430
6126
  commandPath: ["settings", "job-types", "list"],
4431
6127
  options: [],
4432
- hasRequestBody: false
6128
+ hasRequestBody: false,
6129
+ responseFields: [
6130
+ {
6131
+ name: "items",
6132
+ type: "array"
6133
+ }
6134
+ ]
4433
6135
  },
4434
6136
  {
4435
6137
  operationId: "PublicApiPriorityController_list",
@@ -4439,7 +6141,13 @@ var operations = [
4439
6141
  path: "/settings/priorities",
4440
6142
  commandPath: ["settings", "priorities", "list"],
4441
6143
  options: [],
4442
- hasRequestBody: false
6144
+ hasRequestBody: false,
6145
+ responseFields: [
6146
+ {
6147
+ name: "items",
6148
+ type: "array"
6149
+ }
6150
+ ]
4443
6151
  },
4444
6152
  {
4445
6153
  operationId: "PublicApiStageStatusController_list",
@@ -4449,7 +6157,13 @@ var operations = [
4449
6157
  path: "/settings/stage-statuses",
4450
6158
  commandPath: ["settings", "stage-statuses", "list"],
4451
6159
  options: [],
4452
- hasRequestBody: false
6160
+ hasRequestBody: false,
6161
+ responseFields: [
6162
+ {
6163
+ name: "items",
6164
+ type: "array"
6165
+ }
6166
+ ]
4453
6167
  },
4454
6168
  {
4455
6169
  operationId: "PublicApiTagController_list",
@@ -4459,7 +6173,13 @@ var operations = [
4459
6173
  path: "/settings/tags",
4460
6174
  commandPath: ["settings", "tags", "list"],
4461
6175
  options: [],
4462
- hasRequestBody: false
6176
+ hasRequestBody: false,
6177
+ responseFields: [
6178
+ {
6179
+ name: "items",
6180
+ type: "array"
6181
+ }
6182
+ ]
4463
6183
  },
4464
6184
  {
4465
6185
  operationId: "PublicApiZoneController_list",
@@ -4469,7 +6189,13 @@ var operations = [
4469
6189
  path: "/settings/zones",
4470
6190
  commandPath: ["settings", "zones", "list"],
4471
6191
  options: [],
4472
- hasRequestBody: false
6192
+ hasRequestBody: false,
6193
+ responseFields: [
6194
+ {
6195
+ name: "items",
6196
+ type: "array"
6197
+ }
6198
+ ]
4473
6199
  },
4474
6200
  {
4475
6201
  operationId: "PublicApiWorkTypeController_list",
@@ -4479,7 +6205,13 @@ var operations = [
4479
6205
  path: "/settings/work-types",
4480
6206
  commandPath: ["settings", "work-types", "list"],
4481
6207
  options: [],
4482
- hasRequestBody: false
6208
+ hasRequestBody: false,
6209
+ responseFields: [
6210
+ {
6211
+ name: "items",
6212
+ type: "array"
6213
+ }
6214
+ ]
4483
6215
  },
4484
6216
  {
4485
6217
  operationId: "PublicApiTemplateController_listEmailTemplates",
@@ -4500,7 +6232,13 @@ var operations = [
4500
6232
  enumValues: ["job", "stage"]
4501
6233
  }
4502
6234
  ],
4503
- hasRequestBody: false
6235
+ hasRequestBody: false,
6236
+ responseFields: [
6237
+ {
6238
+ name: "items",
6239
+ type: "array"
6240
+ }
6241
+ ]
4504
6242
  },
4505
6243
  {
4506
6244
  operationId: "PublicApiTemplateController_listSmsTemplates",
@@ -4521,7 +6259,13 @@ var operations = [
4521
6259
  enumValues: ["job", "stage"]
4522
6260
  }
4523
6261
  ],
4524
- hasRequestBody: false
6262
+ hasRequestBody: false,
6263
+ responseFields: [
6264
+ {
6265
+ name: "items",
6266
+ type: "array"
6267
+ }
6268
+ ]
4525
6269
  },
4526
6270
  {
4527
6271
  operationId: "PublicAttachmentController_createUploadSession",
@@ -4580,7 +6324,25 @@ var operations = [
4580
6324
  description: "Raw request body JSON (overrides individual fields)"
4581
6325
  }
4582
6326
  ],
4583
- hasRequestBody: true
6327
+ hasRequestBody: true,
6328
+ responseFields: [
6329
+ {
6330
+ name: "uploadUrl",
6331
+ type: "string"
6332
+ },
6333
+ {
6334
+ name: "headers",
6335
+ type: "object"
6336
+ },
6337
+ {
6338
+ name: "expiresAt",
6339
+ type: "string"
6340
+ },
6341
+ {
6342
+ name: "attachment",
6343
+ type: "object"
6344
+ }
6345
+ ]
4584
6346
  },
4585
6347
  {
4586
6348
  operationId: "PublicAttachmentController_download",
@@ -4719,7 +6481,8 @@ var operations = [
4719
6481
  source: "body",
4720
6482
  type: "array",
4721
6483
  required: false,
4722
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
6484
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
6485
+ lookupEndpoint: "/settings/tags"
4723
6486
  },
4724
6487
  {
4725
6488
  name: "attachmentIds",
@@ -4775,7 +6538,8 @@ var operations = [
4775
6538
  source: "body",
4776
6539
  type: "string",
4777
6540
  required: false,
4778
- description: "Template ID to pre-populate fields from a template"
6541
+ description: "Template ID to pre-populate fields from a template",
6542
+ lookupEndpoint: "/settings/templates"
4779
6543
  },
4780
6544
  {
4781
6545
  name: "subject",
@@ -4829,7 +6593,8 @@ var operations = [
4829
6593
  source: "body",
4830
6594
  type: "array",
4831
6595
  required: false,
4832
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
6596
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
6597
+ lookupEndpoint: "/settings/tags"
4833
6598
  },
4834
6599
  {
4835
6600
  name: "attachmentIds",
@@ -4885,7 +6650,8 @@ var operations = [
4885
6650
  source: "body",
4886
6651
  type: "string",
4887
6652
  required: false,
4888
- description: "Template ID to pre-populate fields from a template"
6653
+ description: "Template ID to pre-populate fields from a template",
6654
+ lookupEndpoint: "/settings/templates"
4889
6655
  },
4890
6656
  {
4891
6657
  name: "body",
@@ -4912,7 +6678,8 @@ var operations = [
4912
6678
  source: "body",
4913
6679
  type: "array",
4914
6680
  required: false,
4915
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
6681
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
6682
+ lookupEndpoint: "/settings/tags"
4916
6683
  },
4917
6684
  {
4918
6685
  name: "sharing",
@@ -5015,7 +6782,8 @@ var operations = [
5015
6782
  source: "body",
5016
6783
  type: "array",
5017
6784
  required: false,
5018
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
6785
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
6786
+ lookupEndpoint: "/settings/tags"
5019
6787
  },
5020
6788
  {
5021
6789
  name: "sharing",
@@ -5241,7 +7009,8 @@ var operations = [
5241
7009
  source: "body",
5242
7010
  type: "array",
5243
7011
  required: false,
5244
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
7012
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
7013
+ lookupEndpoint: "/settings/tags"
5245
7014
  },
5246
7015
  {
5247
7016
  name: "attachmentIds",
@@ -5306,7 +7075,8 @@ var operations = [
5306
7075
  source: "body",
5307
7076
  type: "string",
5308
7077
  required: false,
5309
- description: "Template ID to pre-populate fields from a template"
7078
+ description: "Template ID to pre-populate fields from a template",
7079
+ lookupEndpoint: "/settings/templates"
5310
7080
  },
5311
7081
  {
5312
7082
  name: "subject",
@@ -5360,7 +7130,8 @@ var operations = [
5360
7130
  source: "body",
5361
7131
  type: "array",
5362
7132
  required: false,
5363
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
7133
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
7134
+ lookupEndpoint: "/settings/tags"
5364
7135
  },
5365
7136
  {
5366
7137
  name: "attachmentIds",
@@ -5425,7 +7196,8 @@ var operations = [
5425
7196
  source: "body",
5426
7197
  type: "string",
5427
7198
  required: false,
5428
- description: "Template ID to pre-populate fields from a template"
7199
+ description: "Template ID to pre-populate fields from a template",
7200
+ lookupEndpoint: "/settings/templates"
5429
7201
  },
5430
7202
  {
5431
7203
  name: "body",
@@ -5452,7 +7224,8 @@ var operations = [
5452
7224
  source: "body",
5453
7225
  type: "array",
5454
7226
  required: false,
5455
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
7227
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
7228
+ lookupEndpoint: "/settings/tags"
5456
7229
  },
5457
7230
  {
5458
7231
  name: "sharing",
@@ -5564,7 +7337,8 @@ var operations = [
5564
7337
  source: "body",
5565
7338
  type: "array",
5566
7339
  required: false,
5567
- description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")'
7340
+ description: 'Array of label/tag IDs to attach (comma-separated, e.g. "id1,id2")',
7341
+ lookupEndpoint: "/settings/tags"
5568
7342
  },
5569
7343
  {
5570
7344
  name: "sharing",
@@ -5975,7 +7749,8 @@ var operations = [
5975
7749
  source: "body",
5976
7750
  type: "array",
5977
7751
  required: false,
5978
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
7752
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
7753
+ lookupEndpoint: "/settings/tags"
5979
7754
  },
5980
7755
  {
5981
7756
  name: "evidenceOptions",
@@ -6143,7 +7918,8 @@ var operations = [
6143
7918
  source: "body",
6144
7919
  type: "array",
6145
7920
  required: false,
6146
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
7921
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
7922
+ lookupEndpoint: "/settings/tags"
6147
7923
  },
6148
7924
  {
6149
7925
  name: "sharing",
@@ -6432,7 +8208,8 @@ var operations = [
6432
8208
  source: "body",
6433
8209
  type: "array",
6434
8210
  required: false,
6435
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
8211
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
8212
+ lookupEndpoint: "/settings/tags"
6436
8213
  },
6437
8214
  {
6438
8215
  name: "evidenceOptions",
@@ -6618,7 +8395,8 @@ var operations = [
6618
8395
  source: "body",
6619
8396
  type: "array",
6620
8397
  required: false,
6621
- description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up'
8398
+ description: 'Array of tag IDs (comma-separated, e.g. "id1,id2") — use /settings/tags to look up',
8399
+ lookupEndpoint: "/settings/tags"
6622
8400
  },
6623
8401
  {
6624
8402
  name: "sharing",
@@ -6950,7 +8728,17 @@ var operations = [
6950
8728
  description: ""
6951
8729
  }
6952
8730
  ],
6953
- hasRequestBody: false
8731
+ hasRequestBody: false,
8732
+ responseFields: [
8733
+ {
8734
+ name: "items",
8735
+ type: "array"
8736
+ },
8737
+ {
8738
+ name: "pagination",
8739
+ type: "object"
8740
+ }
8741
+ ]
6954
8742
  },
6955
8743
  {
6956
8744
  operationId: "PublicCrmCustomerController_getById",
@@ -6970,7 +8758,13 @@ var operations = [
6970
8758
  description: "Customer ID"
6971
8759
  }
6972
8760
  ],
6973
- hasRequestBody: false
8761
+ hasRequestBody: false,
8762
+ responseFields: [
8763
+ {
8764
+ name: "item",
8765
+ type: "object"
8766
+ }
8767
+ ]
6974
8768
  },
6975
8769
  {
6976
8770
  operationId: "PublicCrmCustomerController_listContacts",
@@ -6987,7 +8781,8 @@ var operations = [
6987
8781
  source: "path",
6988
8782
  type: "string",
6989
8783
  required: true,
6990
- description: "Customer ID"
8784
+ description: "Customer ID",
8785
+ lookupEndpoint: "/crm/customers"
6991
8786
  },
6992
8787
  {
6993
8788
  name: "cursor",
@@ -7008,7 +8803,17 @@ var operations = [
7008
8803
  description: ""
7009
8804
  }
7010
8805
  ],
7011
- hasRequestBody: false
8806
+ hasRequestBody: false,
8807
+ responseFields: [
8808
+ {
8809
+ name: "items",
8810
+ type: "array"
8811
+ },
8812
+ {
8813
+ name: "pagination",
8814
+ type: "object"
8815
+ }
8816
+ ]
7012
8817
  },
7013
8818
  {
7014
8819
  operationId: "PublicCrmCustomerController_listSites",
@@ -7025,7 +8830,8 @@ var operations = [
7025
8830
  source: "path",
7026
8831
  type: "string",
7027
8832
  required: true,
7028
- description: "Customer ID"
8833
+ description: "Customer ID",
8834
+ lookupEndpoint: "/crm/customers"
7029
8835
  },
7030
8836
  {
7031
8837
  name: "cursor",
@@ -7046,7 +8852,17 @@ var operations = [
7046
8852
  description: ""
7047
8853
  }
7048
8854
  ],
7049
- hasRequestBody: false
8855
+ hasRequestBody: false,
8856
+ responseFields: [
8857
+ {
8858
+ name: "items",
8859
+ type: "array"
8860
+ },
8861
+ {
8862
+ name: "pagination",
8863
+ type: "object"
8864
+ }
8865
+ ]
7050
8866
  },
7051
8867
  {
7052
8868
  operationId: "PublicCrmEmployeeController_list",
@@ -7075,7 +8891,17 @@ var operations = [
7075
8891
  description: ""
7076
8892
  }
7077
8893
  ],
7078
- hasRequestBody: false
8894
+ hasRequestBody: false,
8895
+ responseFields: [
8896
+ {
8897
+ name: "items",
8898
+ type: "array"
8899
+ },
8900
+ {
8901
+ name: "pagination",
8902
+ type: "object"
8903
+ }
8904
+ ]
7079
8905
  },
7080
8906
  {
7081
8907
  operationId: "PublicCrmEmployeeController_getById",
@@ -7095,7 +8921,13 @@ var operations = [
7095
8921
  description: "Employee ID"
7096
8922
  }
7097
8923
  ],
7098
- hasRequestBody: false
8924
+ hasRequestBody: false,
8925
+ responseFields: [
8926
+ {
8927
+ name: "item",
8928
+ type: "object"
8929
+ }
8930
+ ]
7099
8931
  },
7100
8932
  {
7101
8933
  operationId: "PublicCrmContractorController_list",
@@ -7124,7 +8956,17 @@ var operations = [
7124
8956
  description: ""
7125
8957
  }
7126
8958
  ],
7127
- hasRequestBody: false
8959
+ hasRequestBody: false,
8960
+ responseFields: [
8961
+ {
8962
+ name: "items",
8963
+ type: "array"
8964
+ },
8965
+ {
8966
+ name: "pagination",
8967
+ type: "object"
8968
+ }
8969
+ ]
7128
8970
  },
7129
8971
  {
7130
8972
  operationId: "PublicCrmContractorController_getById",
@@ -7144,7 +8986,13 @@ var operations = [
7144
8986
  description: "Contractor ID"
7145
8987
  }
7146
8988
  ],
7147
- hasRequestBody: false
8989
+ hasRequestBody: false,
8990
+ responseFields: [
8991
+ {
8992
+ name: "item",
8993
+ type: "object"
8994
+ }
8995
+ ]
7148
8996
  },
7149
8997
  {
7150
8998
  operationId: "PublicCrmSupplierController_list",
@@ -7173,7 +9021,17 @@ var operations = [
7173
9021
  description: ""
7174
9022
  }
7175
9023
  ],
7176
- hasRequestBody: false
9024
+ hasRequestBody: false,
9025
+ responseFields: [
9026
+ {
9027
+ name: "items",
9028
+ type: "array"
9029
+ },
9030
+ {
9031
+ name: "pagination",
9032
+ type: "object"
9033
+ }
9034
+ ]
7177
9035
  },
7178
9036
  {
7179
9037
  operationId: "PublicCrmSupplierController_getById",
@@ -7193,7 +9051,13 @@ var operations = [
7193
9051
  description: "Supplier ID"
7194
9052
  }
7195
9053
  ],
7196
- hasRequestBody: false
9054
+ hasRequestBody: false,
9055
+ responseFields: [
9056
+ {
9057
+ name: "item",
9058
+ type: "object"
9059
+ }
9060
+ ]
7197
9061
  },
7198
9062
  {
7199
9063
  operationId: "PublicCrmCompanyController_list",
@@ -7222,7 +9086,17 @@ var operations = [
7222
9086
  description: ""
7223
9087
  }
7224
9088
  ],
7225
- hasRequestBody: false
9089
+ hasRequestBody: false,
9090
+ responseFields: [
9091
+ {
9092
+ name: "items",
9093
+ type: "array"
9094
+ },
9095
+ {
9096
+ name: "pagination",
9097
+ type: "object"
9098
+ }
9099
+ ]
7226
9100
  },
7227
9101
  {
7228
9102
  operationId: "PublicCrmCompanyController_getById",
@@ -7242,7 +9116,13 @@ var operations = [
7242
9116
  description: "Company ID"
7243
9117
  }
7244
9118
  ],
7245
- hasRequestBody: false
9119
+ hasRequestBody: false,
9120
+ responseFields: [
9121
+ {
9122
+ name: "item",
9123
+ type: "object"
9124
+ }
9125
+ ]
7246
9126
  },
7247
9127
  {
7248
9128
  operationId: "PublicCrmExternalUserController_list",
@@ -7271,7 +9151,17 @@ var operations = [
7271
9151
  description: ""
7272
9152
  }
7273
9153
  ],
7274
- hasRequestBody: false
9154
+ hasRequestBody: false,
9155
+ responseFields: [
9156
+ {
9157
+ name: "items",
9158
+ type: "array"
9159
+ },
9160
+ {
9161
+ name: "pagination",
9162
+ type: "object"
9163
+ }
9164
+ ]
7275
9165
  },
7276
9166
  {
7277
9167
  operationId: "PublicCrmExternalUserController_getById",
@@ -7291,7 +9181,13 @@ var operations = [
7291
9181
  description: "External User ID"
7292
9182
  }
7293
9183
  ],
7294
- hasRequestBody: false
9184
+ hasRequestBody: false,
9185
+ responseFields: [
9186
+ {
9187
+ name: "item",
9188
+ type: "object"
9189
+ }
9190
+ ]
7295
9191
  },
7296
9192
  {
7297
9193
  operationId: "PublicCrmContactController_list",
@@ -7320,7 +9216,17 @@ var operations = [
7320
9216
  description: ""
7321
9217
  }
7322
9218
  ],
7323
- hasRequestBody: false
9219
+ hasRequestBody: false,
9220
+ responseFields: [
9221
+ {
9222
+ name: "items",
9223
+ type: "array"
9224
+ },
9225
+ {
9226
+ name: "pagination",
9227
+ type: "object"
9228
+ }
9229
+ ]
7324
9230
  },
7325
9231
  {
7326
9232
  operationId: "PublicCrmContactController_getById",
@@ -7340,7 +9246,13 @@ var operations = [
7340
9246
  description: "Contact ID"
7341
9247
  }
7342
9248
  ],
7343
- hasRequestBody: false
9249
+ hasRequestBody: false,
9250
+ responseFields: [
9251
+ {
9252
+ name: "item",
9253
+ type: "object"
9254
+ }
9255
+ ]
7344
9256
  },
7345
9257
  {
7346
9258
  operationId: "PublicCrmInviteController_list",
@@ -7369,7 +9281,17 @@ var operations = [
7369
9281
  description: ""
7370
9282
  }
7371
9283
  ],
7372
- hasRequestBody: false
9284
+ hasRequestBody: false,
9285
+ responseFields: [
9286
+ {
9287
+ name: "items",
9288
+ type: "array"
9289
+ },
9290
+ {
9291
+ name: "pagination",
9292
+ type: "object"
9293
+ }
9294
+ ]
7373
9295
  },
7374
9296
  {
7375
9297
  operationId: "PublicCrmInviteController_getById",
@@ -7389,7 +9311,13 @@ var operations = [
7389
9311
  description: "Invite ID"
7390
9312
  }
7391
9313
  ],
7392
- hasRequestBody: false
9314
+ hasRequestBody: false,
9315
+ responseFields: [
9316
+ {
9317
+ name: "item",
9318
+ type: "object"
9319
+ }
9320
+ ]
7393
9321
  },
7394
9322
  {
7395
9323
  operationId: "PublicCrmSiteController_list",
@@ -7427,7 +9355,17 @@ var operations = [
7427
9355
  description: ""
7428
9356
  }
7429
9357
  ],
7430
- hasRequestBody: false
9358
+ hasRequestBody: false,
9359
+ responseFields: [
9360
+ {
9361
+ name: "items",
9362
+ type: "array"
9363
+ },
9364
+ {
9365
+ name: "pagination",
9366
+ type: "object"
9367
+ }
9368
+ ]
7431
9369
  },
7432
9370
  {
7433
9371
  operationId: "PublicCrmSiteController_getById",
@@ -7447,7 +9385,13 @@ var operations = [
7447
9385
  description: "Site ID"
7448
9386
  }
7449
9387
  ],
7450
- hasRequestBody: false
9388
+ hasRequestBody: false,
9389
+ responseFields: [
9390
+ {
9391
+ name: "item",
9392
+ type: "object"
9393
+ }
9394
+ ]
7451
9395
  },
7452
9396
  {
7453
9397
  operationId: "PublicApiWebhookV2Controller_listEntities",
@@ -8006,8 +9950,33 @@ function prompt(question, mask = false) {
8006
9950
  async function main() {
8007
9951
  const program2 = new Command;
8008
9952
  program2.name("workbuddy").description("WorkBuddy CLI").version(packageVersion);
9953
+ program2.option("--describe", "Print machine-readable JSON description of all available operations");
8009
9954
  registerAuthCommands(program2);
8010
9955
  registerGeneratedCommands(program2);
9956
+ if (process.argv.includes("--describe")) {
9957
+ const args = process.argv.slice(2).filter((a) => a !== "--describe");
9958
+ if (args.length === 0) {
9959
+ console.log(JSON.stringify({ name: "workbuddy", version: packageVersion, operations: operations.map(describeOperation) }, null, 2));
9960
+ return;
9961
+ }
9962
+ const prefix = args.join(" ");
9963
+ const matched = operations.filter((op) => {
9964
+ const cmd = op.commandPath.join(" ");
9965
+ return cmd === prefix || cmd.startsWith(prefix + " ");
9966
+ });
9967
+ if (matched.length > 0) {
9968
+ if (matched.length === 1 && matched[0].commandPath.join(" ") === prefix) {
9969
+ console.log(JSON.stringify(describeOperation(matched[0]), null, 2));
9970
+ } else {
9971
+ console.log(JSON.stringify({
9972
+ group: prefix,
9973
+ description: GROUP_DESCRIPTIONS[args[args.length - 1]] || prefix,
9974
+ operations: matched.map(describeOperation)
9975
+ }, null, 2));
9976
+ }
9977
+ return;
9978
+ }
9979
+ }
8011
9980
  await program2.parseAsync(process.argv);
8012
9981
  }
8013
9982
  function registerAuthCommands(program2) {
@@ -8154,6 +10123,14 @@ function registerGeneratedCommands(program2) {
8154
10123
  }
8155
10124
  return;
8156
10125
  }
10126
+ if (options.stdin) {
10127
+ const chunks = [];
10128
+ for await (const chunk of process.stdin)
10129
+ chunks.push(Buffer.from(chunk));
10130
+ const stdinBody = Buffer.concat(chunks).toString("utf-8").trim();
10131
+ if (stdinBody)
10132
+ options.rawBody = stdinBody;
10133
+ }
8157
10134
  const config = resolveConfig({
8158
10135
  profile: options.profile,
8159
10136
  baseUrl: options.baseUrl,
@@ -8168,9 +10145,45 @@ function registerGeneratedCommands(program2) {
8168
10145
  return;
8169
10146
  }
8170
10147
  const outputFormat = getOutputFormat(options.output);
10148
+ const quiet = Boolean(options.quiet);
8171
10149
  validateRequiredOptions(operation, options);
8172
- const response = await executeOperation(operation, options, config);
8173
- printResponse(response, outputFormat, options.save);
10150
+ let responseData;
10151
+ if (options.all) {
10152
+ const allItems = [];
10153
+ let cursor;
10154
+ let page = 0;
10155
+ do {
10156
+ const pageOptions = { ...options, cursor: cursor || options.cursor };
10157
+ const response = await executeOperation(operation, pageOptions, config);
10158
+ const data = response.data;
10159
+ const items = data?.items ?? data?.data ?? (Array.isArray(data) ? data : null);
10160
+ if (items) {
10161
+ allItems.push(...items);
10162
+ } else {
10163
+ responseData = response.data;
10164
+ break;
10165
+ }
10166
+ cursor = data?.pagination?.nextCursor ?? data?.nextCursor;
10167
+ page += 1;
10168
+ if (page > 100)
10169
+ break;
10170
+ } while (cursor);
10171
+ if (!responseData)
10172
+ responseData = { items: allItems, total: allItems.length };
10173
+ } else {
10174
+ const response = await executeOperation(operation, options, config);
10175
+ responseData = response.data;
10176
+ }
10177
+ if (options.field) {
10178
+ const extracted = extractField(responseData, options.field);
10179
+ console.log(typeof extracted === "string" ? extracted : JSON.stringify(extracted, null, 2));
10180
+ return;
10181
+ }
10182
+ if (quiet) {
10183
+ console.log(JSON.stringify(responseData, null, 2));
10184
+ } else {
10185
+ printResponse({ status: 200, contentType: "application/json", data: responseData }, outputFormat, options.save);
10186
+ }
8174
10187
  });
8175
10188
  }
8176
10189
  }
@@ -8186,6 +10199,10 @@ function applyCommonOptions(command) {
8186
10199
  command.option("--describe", "Print machine-readable JSON description of this command");
8187
10200
  command.option("--example", "Print an example request body for this command");
8188
10201
  command.option("--dry-run", "Print the request that would be sent without executing it");
10202
+ command.option("--all", "Auto-paginate: follow nextCursor and return all results");
10203
+ command.option("--quiet", "Suppress hints and status — output only data (for piping)");
10204
+ command.option("--field <path>", "Extract a single field from the response (e.g. --field id or --field data.items)");
10205
+ command.option("--stdin", "Read request body from stdin as JSON");
8189
10206
  }
8190
10207
  function applyOperationOptions(command, options) {
8191
10208
  for (const option of options) {
@@ -8200,6 +10217,9 @@ function buildOptionDescription(option) {
8200
10217
  if (option.required) {
8201
10218
  parts.push("required");
8202
10219
  }
10220
+ if (option.type === "array" && !(option.description || "").includes("comma-separated")) {
10221
+ parts.push('(comma-separated, e.g. "val1,val2")');
10222
+ }
8203
10223
  return parts.join(" ");
8204
10224
  }
8205
10225
  function describeOperation(operation) {
@@ -8210,6 +10230,7 @@ function describeOperation(operation) {
8210
10230
  path: operation.path,
8211
10231
  description: operation.description,
8212
10232
  hasRequestBody: operation.hasRequestBody,
10233
+ ...operation.scopes?.length ? { scopes: operation.scopes } : {},
8213
10234
  options: operation.options.filter((o) => o.name !== "raw-body").map((option) => ({
8214
10235
  name: option.name,
8215
10236
  flag: "--" + option.cliName,
@@ -8218,8 +10239,10 @@ function describeOperation(operation) {
8218
10239
  required: option.required,
8219
10240
  description: option.description,
8220
10241
  ...option.enumValues?.length ? { enum: option.enumValues } : {},
8221
- ...option.format ? { format: option.format } : {}
8222
- }))
10242
+ ...option.format ? { format: option.format } : {},
10243
+ ...option.lookupEndpoint ? { lookupEndpoint: option.lookupEndpoint } : {}
10244
+ })),
10245
+ ...operation.responseFields?.length ? { responseFields: operation.responseFields } : {}
8223
10246
  };
8224
10247
  }
8225
10248
  function generateExample(operation) {
@@ -8293,6 +10316,18 @@ function buildDryRun(operation, values, config) {
8293
10316
  ...body !== undefined ? { body } : {}
8294
10317
  };
8295
10318
  }
10319
+ function extractField(data, fieldPath) {
10320
+ const segments = fieldPath.split(".");
10321
+ let current = data;
10322
+ for (const segment of segments) {
10323
+ if (current === null || current === undefined)
10324
+ return;
10325
+ if (typeof current !== "object")
10326
+ return;
10327
+ current = current[segment];
10328
+ }
10329
+ return current;
10330
+ }
8296
10331
  function validateRequiredOptions(operation, values) {
8297
10332
  const hasBody = typeof values.rawBody === "string" && values.rawBody.length > 0;
8298
10333
  const missing = operation.options.filter((option) => {
@@ -8319,6 +10354,12 @@ function isMissing(value) {
8319
10354
  return value === undefined || value === null || value === "";
8320
10355
  }
8321
10356
  main().catch((error) => {
8322
- console.error(error instanceof Error ? error.message : String(error));
8323
- process.exit(1);
10357
+ const quiet = process.argv.includes("--quiet");
10358
+ const message = error instanceof Error ? error.message : String(error);
10359
+ if (quiet) {
10360
+ console.error(JSON.stringify({ error: message, exitCode: error instanceof CliError ? error.exitCode : 1 }));
10361
+ } else {
10362
+ console.error(message);
10363
+ }
10364
+ process.exit(error instanceof CliError ? error.exitCode : 1);
8324
10365
  });