ssmforge 0.2.1__tar.gz → 0.2.2__tar.gz

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 (24) hide show
  1. {ssmforge-0.2.1/src/ssmforge.egg-info → ssmforge-0.2.2}/PKG-INFO +47 -2
  2. {ssmforge-0.2.1 → ssmforge-0.2.2}/README.md +46 -1
  3. {ssmforge-0.2.1 → ssmforge-0.2.2}/pyproject.toml +1 -1
  4. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/__init__.py +1 -1
  5. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/cli.py +56 -2
  6. {ssmforge-0.2.1 → ssmforge-0.2.2/src/ssmforge.egg-info}/PKG-INFO +47 -2
  7. {ssmforge-0.2.1 → ssmforge-0.2.2}/LICENSE +0 -0
  8. {ssmforge-0.2.1 → ssmforge-0.2.2}/MANIFEST.in +0 -0
  9. {ssmforge-0.2.1 → ssmforge-0.2.2}/docs/DEPLOY.md +0 -0
  10. {ssmforge-0.2.1 → ssmforge-0.2.2}/docs/INSTALL.md +0 -0
  11. {ssmforge-0.2.1 → ssmforge-0.2.2}/docs/quickstart.md +0 -0
  12. {ssmforge-0.2.1 → ssmforge-0.2.2}/setup.cfg +0 -0
  13. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/__init__.py +0 -0
  14. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/diff.py +0 -0
  15. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/graph.py +0 -0
  16. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/markdown_render.py +0 -0
  17. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/report.py +0 -0
  18. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/state_dict_scan.py +0 -0
  19. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge/analyze/summary.py +0 -0
  20. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge.egg-info/SOURCES.txt +0 -0
  21. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge.egg-info/dependency_links.txt +0 -0
  22. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge.egg-info/entry_points.txt +0 -0
  23. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge.egg-info/requires.txt +0 -0
  24. {ssmforge-0.2.1 → ssmforge-0.2.2}/src/ssmforge.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssmforge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Standalone HF architecture analyzer (`ssmforge arch`). Inspects any HuggingFace model and reports architectural quirks — attention biases, fused QKV/gate-up, tied embeddings, GQA, MQA, MoE, sliding window, LayerScale, soft-capping, partial RoPE, MLP type, norm type. Outputs structured JSON + human-readable summary.
5
5
  Author: SSMForge Contributors
6
6
  License-Expression: Apache-2.0
@@ -82,6 +82,14 @@ visible *before* you spend the next hour finding out the hard way.
82
82
  It does **not** modify the model. It does **not** run inference. It only
83
83
  inspects.
84
84
 
85
+ ### What's new in 0.2.2
86
+
87
+ | Fix | What was broken |
88
+ |-----|-----------------|
89
+ | `--output PATH` with bad parent dir | Previously got a generic `bash: Permission denied` (when redirecting) or a Python traceback (when using `--output`). Now pre-flight checks the parent directory, prints a clear hint pointing at writable locations like `./` and `~/`, then exits 1. |
90
+
91
+ Plus 6 new tests (162 total). Tiny release — main bug fix only.
92
+
85
93
  ### What's new in 0.2.1
86
94
 
87
95
  | Feature | Why it matters |
@@ -1392,7 +1400,44 @@ install.
1392
1400
 
1393
1401
  ## 16. Update log
1394
1402
 
1395
- ### v0.2.1 (current) — 2026-09-23
1403
+ ### v0.2.2 (current) — 2026-09-23
1404
+
1405
+ **Bug fix: `--output PATH` directory validation**
1406
+
1407
+ When `--output PATH` points to a non-writable location, users were getting
1408
+ either a generic shell `Permission denied` (when using shell redirection)
1409
+ or an opaque Python `OSError` (when using `--output` directly). Now
1410
+ ssmforge pre-flight checks the parent directory and prints a friendly
1411
+ hint pointing at writable alternatives.
1412
+
1413
+ **Before:**
1414
+ ```
1415
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1416
+ bash: q.md: Permission denied
1417
+
1418
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1419
+ Error: cannot write to 'C:\\q.md': [Errno 13] Permission denied: 'C:\\q.md'
1420
+ ```
1421
+
1422
+ **After:**
1423
+ ```
1424
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1425
+ # (still works in any shell that allows the redirect)
1426
+
1427
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1428
+ Error: cannot write to directory: C:\
1429
+ Permission denied.
1430
+ Try a writable location like:
1431
+ --output ./report.md (current directory)
1432
+ --output ~/report.md (your home directory)
1433
+ --output $TMPDIR/report.md (system temp)
1434
+ ```
1435
+
1436
+ Tests: 162 passed (was 156). 6 new tests for `_check_output_path`
1437
+ (returns (None, None) for None / '-' paths, validates writability,
1438
+ emits helpful hints for missing or read-only parents).
1439
+
1440
+ ### v0.2.1 — 2026-09-23
1396
1441
 
1397
1442
  **New feature: `doctor --check-install`**
1398
1443
 
@@ -59,6 +59,14 @@ visible *before* you spend the next hour finding out the hard way.
59
59
  It does **not** modify the model. It does **not** run inference. It only
60
60
  inspects.
61
61
 
62
+ ### What's new in 0.2.2
63
+
64
+ | Fix | What was broken |
65
+ |-----|-----------------|
66
+ | `--output PATH` with bad parent dir | Previously got a generic `bash: Permission denied` (when redirecting) or a Python traceback (when using `--output`). Now pre-flight checks the parent directory, prints a clear hint pointing at writable locations like `./` and `~/`, then exits 1. |
67
+
68
+ Plus 6 new tests (162 total). Tiny release — main bug fix only.
69
+
62
70
  ### What's new in 0.2.1
63
71
 
64
72
  | Feature | Why it matters |
@@ -1369,7 +1377,44 @@ install.
1369
1377
 
1370
1378
  ## 16. Update log
1371
1379
 
1372
- ### v0.2.1 (current) — 2026-09-23
1380
+ ### v0.2.2 (current) — 2026-09-23
1381
+
1382
+ **Bug fix: `--output PATH` directory validation**
1383
+
1384
+ When `--output PATH` points to a non-writable location, users were getting
1385
+ either a generic shell `Permission denied` (when using shell redirection)
1386
+ or an opaque Python `OSError` (when using `--output` directly). Now
1387
+ ssmforge pre-flight checks the parent directory and prints a friendly
1388
+ hint pointing at writable alternatives.
1389
+
1390
+ **Before:**
1391
+ ```
1392
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1393
+ bash: q.md: Permission denied
1394
+
1395
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1396
+ Error: cannot write to 'C:\\q.md': [Errno 13] Permission denied: 'C:\\q.md'
1397
+ ```
1398
+
1399
+ **After:**
1400
+ ```
1401
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1402
+ # (still works in any shell that allows the redirect)
1403
+
1404
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1405
+ Error: cannot write to directory: C:\
1406
+ Permission denied.
1407
+ Try a writable location like:
1408
+ --output ./report.md (current directory)
1409
+ --output ~/report.md (your home directory)
1410
+ --output $TMPDIR/report.md (system temp)
1411
+ ```
1412
+
1413
+ Tests: 162 passed (was 156). 6 new tests for `_check_output_path`
1414
+ (returns (None, None) for None / '-' paths, validates writability,
1415
+ emits helpful hints for missing or read-only parents).
1416
+
1417
+ ### v0.2.1 — 2026-09-23
1373
1418
 
1374
1419
  **New feature: `doctor --check-install`**
1375
1420
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ssmforge"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "Standalone HF architecture analyzer (`ssmforge arch`). Inspects any HuggingFace model and reports architectural quirks — attention biases, fused QKV/gate-up, tied embeddings, GQA, MQA, MoE, sliding window, LayerScale, soft-capping, partial RoPE, MLP type, norm type. Outputs structured JSON + human-readable summary."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,3 +1,3 @@
1
1
  """SSMForge — architecture analyzer for HuggingFace models."""
2
2
 
3
- __version__ = "0.2.1"
3
+ __version__ = "0.2.2"
@@ -282,16 +282,70 @@ def _format_dry_run_summary(report: dict) -> str:
282
282
  return "\n".join(lines)
283
283
 
284
284
 
285
+ def _check_output_path(output_path: str | None) -> tuple[Path | None, str | None]:
286
+ """Pre-flight check on an --output target before writing.
287
+
288
+ Returns ``(parent_dir_or_None, error_message_or_None)``:
289
+ - ``(None, None)`` when output_path is None or '-' (stdout).
290
+ - ``(parent_dir, None)`` when the directory exists and is writable.
291
+ - ``(parent_dir, error_message)`` when the path can't be written.
292
+
293
+ The error_message is a user-friendly hint that names the actual problem
294
+ (missing parent dir, not a directory, permission denied) and suggests
295
+ writable alternatives when appropriate.
296
+ """
297
+ if not output_path or output_path == "-":
298
+ return None, None
299
+ p = Path(output_path)
300
+ parent = p.parent if str(p.parent) else Path(".")
301
+ # Catch a bare filename like 'report.md' (parent is '.') which DOES work
302
+ parent = parent.resolve()
303
+ # Case 1: parent doesn't exist
304
+ if not parent.exists():
305
+ return parent, (
306
+ f"Error: output directory does not exist: {parent}\n"
307
+ f" Hint: create the directory first, or use a writable location.\n"
308
+ f" Try: --output ./report.md (current working directory)"
309
+ )
310
+ # Case 2: parent exists but is a file (not a dir)
311
+ if parent.is_file():
312
+ return parent, (
313
+ f"Error: output path's parent is a file, not a directory: {parent}"
314
+ )
315
+ # Case 3: parent is not writable
316
+ if not os.access(parent, os.W_OK):
317
+ return parent, (
318
+ f"Error: cannot write to directory: {parent}\n"
319
+ f" Permission denied.\n"
320
+ f" Try a writable location like:\n"
321
+ f" --output ./report.md (current directory)\n"
322
+ f" --output ~/report.md (your home directory)\n"
323
+ f" --output $TMPDIR/report.md (system temp)"
324
+ )
325
+ return parent, None
326
+
327
+
285
328
  def _write_or_print(text: str, output_path: str | None) -> None:
286
329
  """Write text to a file if path given, else print to stdout.
287
330
 
288
331
  Special-case: if output_path is '-', print to stdout (Unix convention).
332
+ Pre-flight checks the parent directory exists and is writable; on
333
+ failure prints a friendly hint and exits 1.
289
334
  """
290
335
  if output_path and output_path != "-":
336
+ parent, err = _check_output_path(output_path)
337
+ if err is not None:
338
+ print(err, file=sys.stderr)
339
+ sys.exit(1)
291
340
  try:
292
- Path(output_path).write_text(text, encoding="utf-8")
341
+ p = Path(output_path)
342
+ p.write_text(text, encoding="utf-8")
293
343
  except (PermissionError, FileNotFoundError, IsADirectoryError, OSError) as e:
294
- print(f"Error: cannot write to {output_path!r}: {e}", file=sys.stderr)
344
+ print(
345
+ f"Error: cannot write to {output_path!r}: {e}\n"
346
+ f" Hint: try --output ./report.md for the current directory",
347
+ file=sys.stderr,
348
+ )
295
349
  sys.exit(1)
296
350
  print(f"Report written to {output_path}", file=sys.stderr)
297
351
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssmforge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Standalone HF architecture analyzer (`ssmforge arch`). Inspects any HuggingFace model and reports architectural quirks — attention biases, fused QKV/gate-up, tied embeddings, GQA, MQA, MoE, sliding window, LayerScale, soft-capping, partial RoPE, MLP type, norm type. Outputs structured JSON + human-readable summary.
5
5
  Author: SSMForge Contributors
6
6
  License-Expression: Apache-2.0
@@ -82,6 +82,14 @@ visible *before* you spend the next hour finding out the hard way.
82
82
  It does **not** modify the model. It does **not** run inference. It only
83
83
  inspects.
84
84
 
85
+ ### What's new in 0.2.2
86
+
87
+ | Fix | What was broken |
88
+ |-----|-----------------|
89
+ | `--output PATH` with bad parent dir | Previously got a generic `bash: Permission denied` (when redirecting) or a Python traceback (when using `--output`). Now pre-flight checks the parent directory, prints a clear hint pointing at writable locations like `./` and `~/`, then exits 1. |
90
+
91
+ Plus 6 new tests (162 total). Tiny release — main bug fix only.
92
+
85
93
  ### What's new in 0.2.1
86
94
 
87
95
  | Feature | Why it matters |
@@ -1392,7 +1400,44 @@ install.
1392
1400
 
1393
1401
  ## 16. Update log
1394
1402
 
1395
- ### v0.2.1 (current) — 2026-09-23
1403
+ ### v0.2.2 (current) — 2026-09-23
1404
+
1405
+ **Bug fix: `--output PATH` directory validation**
1406
+
1407
+ When `--output PATH` points to a non-writable location, users were getting
1408
+ either a generic shell `Permission denied` (when using shell redirection)
1409
+ or an opaque Python `OSError` (when using `--output` directly). Now
1410
+ ssmforge pre-flight checks the parent directory and prints a friendly
1411
+ hint pointing at writable alternatives.
1412
+
1413
+ **Before:**
1414
+ ```
1415
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1416
+ bash: q.md: Permission denied
1417
+
1418
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1419
+ Error: cannot write to 'C:\\q.md': [Errno 13] Permission denied: 'C:\\q.md'
1420
+ ```
1421
+
1422
+ **After:**
1423
+ ```
1424
+ $ python -m ssmforge.cli arch X --graph --format markdown > q.md
1425
+ # (still works in any shell that allows the redirect)
1426
+
1427
+ $ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
1428
+ Error: cannot write to directory: C:\
1429
+ Permission denied.
1430
+ Try a writable location like:
1431
+ --output ./report.md (current directory)
1432
+ --output ~/report.md (your home directory)
1433
+ --output $TMPDIR/report.md (system temp)
1434
+ ```
1435
+
1436
+ Tests: 162 passed (was 156). 6 new tests for `_check_output_path`
1437
+ (returns (None, None) for None / '-' paths, validates writability,
1438
+ emits helpful hints for missing or read-only parents).
1439
+
1440
+ ### v0.2.1 — 2026-09-23
1396
1441
 
1397
1442
  **New feature: `doctor --check-install`**
1398
1443
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes