@metasession.co/devaudit-cli 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-cli",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^0.8.2",
36
- "@metasession.co/devaudit-plugin-sdk": "^0.3.8",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.3.9",
37
37
  "ajv": "^8.20.0",
38
38
  "commander": "^12.1.0",
39
39
  "consola": "^3.2.3",
@@ -54,6 +54,14 @@
54
54
  # Issue from: Project Settings → API Keys in
55
55
  # META-COMPLY's web UI.
56
56
  #
57
+ # Large-file uploads (>=25MB):
58
+ # Files above 25MB use a presigned R2 upload flow (3-step: request URL →
59
+ # PUT to R2 → notify portal) instead of multipart POST. This requires
60
+ # the Portal to be configured with R2 evidence storage
61
+ # (R2_EVIDENCE_BUCKET and related env vars). If R2 is not configured,
62
+ # the Portal returns a clear error which is surfaced to the operator.
63
+ # #298 — the Portal response body is included in the error output.
64
+ #
57
65
  # Examples:
58
66
  # ./scripts/upload-evidence.sh meta-ats REQ-001 screenshot \
59
67
  # compliance/evidence/REQ-001/screenshots/
@@ -345,9 +353,9 @@ upload_presigned() {
345
353
  echo -n "(portal did not return presigned URL, falling back to multipart) "
346
354
  return 255
347
355
  fi
348
- rm -f "$resp_body"
349
356
  if [ "$curl_exit" -ne 0 ] || [ "$http_code" = "429" ] || { [ "$http_code" -ge 500 ] && [ "$http_code" -lt 600 ]; }; then
350
357
  if [ "$attempt" -lt "$PRESIGNED_MAX_ATTEMPTS" ]; then
358
+ rm -f "$resp_body"
351
359
  echo -n "(step 1: HTTP ${http_code}, retry in ${backoff}s) "
352
360
  sleep "$backoff"
353
361
  attempt=$((attempt + 1))
@@ -355,8 +363,20 @@ upload_presigned() {
355
363
  continue
356
364
  fi
357
365
  fi
358
- # Non-retriable error (4xx other than 429).
359
- echo -n "(step 1 failed: HTTP ${http_code}) "
366
+ # Non-retriable error (4xx other than 429) or exhausted retries.
367
+ # #298 Surface the Portal response body so operators see WHY it
368
+ # failed (e.g. "Presigned uploads require R2 storage configuration")
369
+ # instead of just "HTTP 501". Include up to 500 chars of the body.
370
+ local err_excerpt=""
371
+ if [ -s "$resp_body" ]; then
372
+ err_excerpt=$(head -c 500 "$resp_body")
373
+ fi
374
+ rm -f "$resp_body"
375
+ echo -n "(step 1 failed: HTTP ${http_code}"
376
+ if [ -n "$err_excerpt" ]; then
377
+ echo -n " — ${err_excerpt}"
378
+ fi
379
+ echo ") "
360
380
  return 1
361
381
  done
362
382
 
@@ -275,6 +275,54 @@ make_fixture "$WORK/c21" "chore(release): reconcile REQ-089 close-out
275
275
  Release-Closeout: REQ-089"
276
276
  assert_eq "close-out marker -> empty version" "" "$(run_helper)"
277
277
 
278
+ # Case 22 (#571 Gap 3): close-out marker with no REQ digits — must NOT
279
+ # suppress the bare-date fallback. The regex requires REQ-[0-9]{3,} so
280
+ # a malformed marker like "Release-Closeout: REQ-AB" should fall through
281
+ # to the bare date.
282
+ make_fixture "$WORK/c22" "chore(release): reconcile close-out
283
+
284
+ Release-Closeout: REQ-AB"
285
+ assert_eq "malformed close-out marker -> bare date $TODAY" "$TODAY" "$(run_helper)"
286
+
287
+ # Case 23 (#571 Gap 3): close-out marker with extra whitespace — must
288
+ # still suppress (regex allows leading whitespace after the colon).
289
+ make_fixture "$WORK/c23" "chore(release): reconcile REQ-100 close-out
290
+
291
+ Release-Closeout: REQ-100"
292
+ assert_eq "close-out marker with extra whitespace -> empty" "" "$(run_helper)"
293
+
294
+ # Case 24 (#571 Gap 3): no ticket file, no RTM, no git tags, no close-out
295
+ # marker — the ultimate fallback chain reaches the bare date. This tests
296
+ # that every prior step's `exit 0` guard correctly falls through when
297
+ # its condition is not met.
298
+ make_fixture "$WORK/c24" "chore: misc cleanup with no compliance state"
299
+ assert_eq "no compliance state at all -> bare date $TODAY" "$TODAY" "$(run_helper)"
300
+
301
+ # Case 25 (#571 Gap 3): pending-releases dir exists but is empty — step 4
302
+ # must not crash and must fall through to step 4-bis / bare date.
303
+ make_fixture "$WORK/c25" "chore: devaudit update to 0.1.30"
304
+ mkdir -p compliance/pending-releases
305
+ assert_eq "empty pending-releases dir -> bare date $TODAY" "$TODAY" "$(run_helper)"
306
+
307
+ # Case 26 (#571 Gap 3): RTM.md exists but has no IN PROGRESS rows —
308
+ # step 4-bis must fall through to the bare date.
309
+ make_fixture "$WORK/c26" "chore: devaudit update to 0.1.30"
310
+ mkdir -p compliance
311
+ cat > compliance/RTM.md <<'RTM'
312
+ | REQ-ID | Status |
313
+ | ------- | ------------- |
314
+ | REQ-001 | RELEASED |
315
+ | REQ-002 | DRAFT |
316
+ RTM
317
+ assert_eq "RTM with no IN PROGRESS -> bare date $TODAY" "$TODAY" "$(run_helper)"
318
+
319
+ # Case 27 (#571 Gap 3): RTM.md exists but is empty (no rows at all) —
320
+ # step 4-bis must not crash and must fall through.
321
+ make_fixture "$WORK/c27" "chore: devaudit update to 0.1.30"
322
+ mkdir -p compliance
323
+ echo "# Requirements Traceability Matrix" > compliance/RTM.md
324
+ assert_eq "empty RTM.md -> bare date $TODAY" "$TODAY" "$(run_helper)"
325
+
278
326
  echo ""
279
327
  echo "=== Summary: $PASS pass / $FAIL fail ==="
280
328
 
@@ -273,6 +273,91 @@ assert_eq "RTM issue title fallback without ticket" "Issue title from RTM" "$REL
273
273
  assert_empty "Summary empty without ticket" "$RELEASE_SUMMARY"
274
274
  echo ""
275
275
 
276
+ # --- Test 12 (#571 Gap 3): No ticket, no RTM, no gh CLI — all fallbacks empty ---
277
+ echo "--- Test 12: All fallbacks unreachable ---"
278
+ make_fixture "$WORK/test12"
279
+ source "$HELPER"
280
+ extract_release_metadata "REQ-999"
281
+ assert_empty "Title empty when no ticket, no RTM, no gh" "$RELEASE_TITLE"
282
+ assert_empty "Summary empty when no ticket" "$RELEASE_SUMMARY"
283
+ echo ""
284
+
285
+ # --- Test 13 (#571 Gap 3): Ticket exists but has no **Requirement:** line,
286
+ # no H1, and no ## Summary — all extraction targets are unreachable ---
287
+ echo "--- Test 13: Ticket with no extractable content ---"
288
+ make_fixture "$WORK/test13"
289
+ cat > "compliance/pending-releases/RELEASE-TICKET-REQ-012.md" <<'TICKET'
290
+ Some prose without any standard headings.
291
+
292
+ Just a paragraph.
293
+ TICKET
294
+
295
+ source "$HELPER"
296
+ extract_release_metadata "REQ-012"
297
+ assert_empty "Title empty when no Requirement line or H1" "$RELEASE_TITLE"
298
+ assert_empty "Summary empty when no ## Summary section" "$RELEASE_SUMMARY"
299
+ echo ""
300
+
301
+ # --- Test 14 (#571 Gap 3): RTM row exists but has no issue number,
302
+ # so the gh CLI fallback is unreachable. Title should be empty. ---
303
+ echo "--- Test 14: RTM row without issue number ---"
304
+ make_fixture "$WORK/test14"
305
+ cat > compliance/RTM.md <<'RTM'
306
+ | REQ-ID | Issue | Risk | Evidence | Status |
307
+ | ------- | ----- | ---- | -------- | ------ |
308
+ | REQ-013 | | LOW | n/a | DRAFT |
309
+ RTM
310
+ source "$HELPER"
311
+ extract_release_metadata "REQ-013"
312
+ assert_empty "Title empty when RTM row has no issue number" "$RELEASE_TITLE"
313
+ echo ""
314
+
315
+ # --- Test 15 (#571 Gap 3): gh CLI exists but issue lookup fails —
316
+ # must fall through to H1 fallback, not error out ---
317
+ echo "--- Test 15: gh CLI fails, falls through to H1 ---"
318
+ make_fixture "$WORK/test15"
319
+ cat > "compliance/pending-releases/RELEASE-TICKET-REQ-014.md" <<'TICKET'
320
+ # Fix critical payment bug
321
+
322
+ ## Summary
323
+ Fixes the payment redirect issue.
324
+ TICKET
325
+ cat > compliance/RTM.md <<'RTM'
326
+ | REQ-ID | Issue | Risk | Evidence | Status |
327
+ | ------- | ----- | ---- | -------- | ------ |
328
+ | REQ-014 | #999 | LOW | n/a | DRAFT |
329
+ RTM
330
+ mkdir -p bin
331
+ cat > bin/gh <<'GH'
332
+ #!/usr/bin/env bash
333
+ # Simulate gh CLI failing (e.g. rate limited, issue not found)
334
+ exit 1
335
+ GH
336
+ chmod +x bin/gh
337
+ PATH="$PWD/bin:$PATH"
338
+ source "$HELPER"
339
+ extract_release_metadata "REQ-014"
340
+ assert_eq "H1 fallback when gh CLI fails" "Fix critical payment bug" "$RELEASE_TITLE"
341
+ echo ""
342
+
343
+ # --- Test 16 (#571 Gap 3): Summary section exists but is only whitespace ---
344
+ echo "--- Test 16: Whitespace-only summary is cleared ---"
345
+ make_fixture "$WORK/test16"
346
+ cat > "compliance/pending-releases/RELEASE-TICKET-REQ-015.md" <<'TICKET'
347
+ **Requirement:** REQ-015 — Feature fifteen
348
+
349
+ ## Summary
350
+
351
+ ## Changes
352
+ - Change A
353
+ TICKET
354
+
355
+ source "$HELPER"
356
+ extract_release_metadata "REQ-015"
357
+ assert_eq "Title extracted" "Feature fifteen" "$RELEASE_TITLE"
358
+ assert_empty "Whitespace-only summary cleared" "$RELEASE_SUMMARY"
359
+ echo ""
360
+
276
361
  echo ""
277
362
  echo "=== Results: $PASS passed, $FAIL failed ==="
278
363
  exit $FAIL