claude-dev-env 1.82.0 → 1.84.0
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/CLAUDE.md +16 -13
- package/_shared/pr-loop/audit-contract.md +24 -12
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/README.md +1 -0
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +16 -5
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviewer_availability_constants.py +12 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +0 -2
- package/_shared/pr-loop/scripts/reviewer_availability.py +182 -0
- package/_shared/pr-loop/scripts/reviews_disabled.py +2 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +9 -33
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +2 -0
- package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +212 -0
- package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +18 -0
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +18 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +37 -0
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability.py +159 -0
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability_constants.py +36 -0
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +14 -0
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +14 -4
- package/agents/clean-coder.md +3 -0
- package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +1 -1
- package/bin/install.mjs +16 -8
- package/bin/install.test.mjs +17 -6
- package/commands/CLAUDE.md +0 -1
- package/docs/CODE_RULES.md +1 -1
- package/hooks/blocking/CLAUDE.md +2 -4
- package/hooks/blocking/code_rules_constants_config.py +164 -1
- package/hooks/blocking/code_rules_docstrings.py +428 -15
- package/hooks/blocking/code_rules_enforcer.py +33 -0
- package/hooks/blocking/code_rules_imports_logging.py +867 -1
- package/hooks/blocking/code_rules_magic_values.py +5 -0
- package/hooks/blocking/code_rules_naming_collection.py +152 -6
- package/hooks/blocking/code_rules_shared.py +34 -0
- package/hooks/blocking/code_rules_string_magic.py +68 -0
- package/hooks/blocking/duplicate_rmtree_helper_blocker.py +4 -4
- package/hooks/blocking/pre_tool_use_dispatcher.py +3 -3
- package/hooks/blocking/reviewer_spawn_gate.py +182 -0
- package/hooks/blocking/stale_comment_reference_blocker.py +267 -0
- package/hooks/blocking/state_description_blocker.py +96 -5
- package/hooks/blocking/test_code_rules_config_duplicate_path_anchor.py +132 -0
- package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +2 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_delegation_summary.py +385 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +197 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +27 -0
- package/hooks/blocking/test_code_rules_enforcer_join_separator_magic.py +67 -0
- package/hooks/blocking/test_code_rules_enforcer_module_docstring_roster.py +40 -0
- package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +213 -0
- package/hooks/blocking/test_code_rules_enforcer_referenced_underscore_loop.py +169 -0
- package/hooks/blocking/test_code_rules_enforcer_split_constants_config.py +33 -0
- package/hooks/blocking/test_code_rules_enforcer_split_shared.py +23 -0
- package/hooks/blocking/test_code_rules_js_bare_flag_return_directive.py +266 -0
- package/hooks/blocking/test_code_rules_js_sibling_return_object_key_drift.py +490 -0
- package/hooks/blocking/test_code_rules_logging_adjacent_literals.py +171 -0
- package/hooks/blocking/test_code_rules_magic_values.py +54 -0
- package/hooks/blocking/test_duplicate_rmtree_helper_blocker.py +0 -6
- package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +184 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +9 -3
- package/hooks/blocking/test_reviewer_spawn_gate.py +230 -0
- package/hooks/blocking/test_shared_stdin_adoption.py +5 -30
- package/hooks/blocking/test_stale_comment_reference_blocker.py +236 -0
- package/hooks/blocking/test_state_description_blocker.py +135 -0
- package/hooks/hooks.json +5 -0
- package/hooks/hooks_constants/CLAUDE.md +3 -4
- package/hooks/hooks_constants/blocking_check_limits.py +46 -0
- package/hooks/hooks_constants/code_rules_enforcer_constants.py +41 -0
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
- package/hooks/hooks_constants/duplicate_rmtree_helper_blocker_constants.py +0 -1
- package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -5
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
- package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +41 -0
- package/hooks/hooks_constants/stale_comment_reference_blocker_constants.py +76 -0
- package/hooks/hooks_constants/state_description_blocker_constants.py +8 -0
- package/hooks/validation/post_tool_use_dispatcher.py +1 -1
- package/hooks/validation/test_post_tool_use_dispatcher.py +51 -35
- package/hooks/workflow/CLAUDE.md +2 -8
- package/package.json +1 -1
- package/rules/CLAUDE.md +5 -2
- package/rules/claude-md-orphan-file.md +5 -0
- package/rules/docstring-prose-matches-implementation.md +10 -1
- package/rules/env-var-table-code-drift.md +5 -0
- package/rules/es-exe-file-search.md +17 -0
- package/rules/no-historical-clutter.md +12 -1
- package/rules/orphan-css-class.md +5 -0
- package/rules/package-inventory-stale-entry.md +10 -0
- package/rules/paired-test-coverage.md +5 -0
- package/rules/plain-illustrative-docstrings.md +40 -1
- package/rules/verify-before-asking.md +7 -0
- package/rules/verify-runtime-state.md +40 -0
- package/rules/windows-filesystem-safe.md +8 -0
- package/rules/workers-done-before-complete.md +33 -0
- package/rules/workflow-substitution-slots.md +5 -0
- package/skills/CLAUDE.md +7 -2
- package/skills/autoconverge/SKILL.md +48 -61
- package/skills/autoconverge/reference/closing-report.md +6 -6
- package/skills/autoconverge/reference/convergence.md +17 -15
- package/skills/autoconverge/reference/gotchas.md +6 -3
- package/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +2 -9
- package/skills/autoconverge/workflow/converge.contract.test.mjs +153 -10
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +55 -19
- package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +16 -9
- package/skills/autoconverge/workflow/converge.mjs +167 -106
- package/skills/autoconverge/workflow/render_report.py +7 -11
- package/skills/bugteam/CLAUDE.md +1 -1
- package/skills/bugteam/PROMPTS.md +7 -6
- package/skills/bugteam/SKILL.md +25 -72
- package/skills/bugteam/reference/CLAUDE.md +1 -3
- package/skills/bugteam/reference/README.md +1 -1
- package/skills/bugteam/reference/audit-and-teammates.md +1 -1
- package/skills/bugteam/reference/obstacles/fix-publish-summary.md +1 -1
- package/skills/bugteam/reference/team-setup.md +8 -7
- package/skills/bugteam/scripts/CLAUDE.md +0 -6
- package/skills/bugteam/scripts/README.md +0 -4
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +0 -1
- package/skills/code/SKILL.md +2 -0
- package/skills/copilot-review/CLAUDE.md +1 -1
- package/skills/copilot-review/SKILL.md +25 -23
- package/skills/everything-search/SKILL.md +5 -0
- package/skills/findbugs/CLAUDE.md +2 -2
- package/skills/findbugs/SKILL.md +22 -83
- package/skills/fixbugs/SKILL.md +2 -4
- package/skills/log-audit/CLAUDE.md +20 -0
- package/skills/log-audit/SKILL.md +68 -0
- package/skills/log-audit/reference/CLAUDE.md +9 -0
- package/skills/log-audit/reference/charter.md +52 -0
- package/skills/log-audit/scripts/CLAUDE.md +27 -0
- package/skills/log-audit/scripts/cluster_recurrences.py +261 -0
- package/skills/log-audit/scripts/collect_log_window.py +199 -0
- package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +12 -0
- package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +23 -0
- package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +24 -0
- package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +49 -0
- package/skills/log-audit/scripts/mine_copilot_findings.py +302 -0
- package/skills/log-audit/scripts/test_cluster_recurrences.py +160 -0
- package/skills/log-audit/scripts/test_collect_log_window.py +111 -0
- package/skills/log-audit/scripts/test_mine_copilot_findings.py +126 -0
- package/skills/monitor-open-prs/SKILL.md +2 -2
- package/skills/post-audit-findings/SKILL.md +84 -0
- package/skills/pr-converge/CLAUDE.md +2 -0
- package/skills/pr-converge/SKILL.md +72 -59
- package/skills/pr-converge/reference/CLAUDE.md +1 -1
- package/skills/pr-converge/reference/convergence-gates.md +16 -19
- package/skills/pr-converge/reference/examples.md +5 -5
- package/skills/pr-converge/reference/fix-protocol.md +16 -43
- package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +1 -1
- package/skills/pr-converge/reference/per-tick.md +24 -45
- package/skills/pr-converge/reference/state-schema.md +15 -0
- package/skills/pr-converge/scripts/README.md +3 -5
- package/skills/pr-fix-protocol/SKILL.md +70 -0
- package/skills/pr-loop-lifecycle/SKILL.md +73 -0
- package/skills/{bugteam → pr-loop-lifecycle}/reference/teardown-publish-permissions.md +22 -24
- package/skills/pr-scope-resolve/SKILL.md +48 -0
- package/skills/qbug/CLAUDE.md +4 -4
- package/skills/qbug/SKILL.md +46 -144
- package/skills/qbug/test_qbug_skill_audit_schema.py +2 -2
- package/skills/qbug/test_qbug_skill_post_fix_audit.py +1 -1
- package/skills/reviewer-gates/SKILL.md +96 -0
- package/skills/session-log/CLAUDE.md +7 -7
- package/skills/session-log/SKILL.md +27 -44
- package/skills/test_markdown_link_integrity.py +103 -0
- package/commands/doc-gist.md +0 -16
- package/hooks/blocking/_md_to_html_blocker_test_support.py +0 -65
- package/hooks/blocking/conftest.py +0 -30
- package/hooks/blocking/md_path_exemptions.py +0 -224
- package/hooks/blocking/md_to_html_blocker.py +0 -155
- package/hooks/blocking/test_md_to_html_blocker_exemptions.py +0 -434
- package/hooks/blocking/test_md_to_html_blocker_extensions.py +0 -157
- package/hooks/blocking/test_md_to_html_blocker_path_resolution.py +0 -336
- package/hooks/hooks_constants/doc_gist_auto_publish_constants.py +0 -18
- package/hooks/hooks_constants/html_companion_constants.py +0 -20
- package/hooks/hooks_constants/md_to_html_blocker_constants.py +0 -76
- package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +0 -125
- package/hooks/workflow/doc_gist_auto_publish.py +0 -144
- package/hooks/workflow/md_to_html_companion.py +0 -358
- package/hooks/workflow/test_doc_gist_auto_publish.py +0 -117
- package/hooks/workflow/test_md_to_html_companion.py +0 -613
- package/skills/bugteam/reference/audit-contract.md +0 -163
- package/skills/bugteam/scripts/_bugteam_permissions_common.py +0 -455
- package/skills/bugteam/scripts/bugteam_scripts_constants/claude_permissions_common_constants.py +0 -69
- package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -280
- package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -266
- package/skills/bugteam/scripts/test__bugteam_permissions_common.py +0 -160
- package/skills/bugteam/scripts/test_agent_config_carveout.py +0 -356
- package/skills/bugteam/scripts/test_bugteam_permissions_common.py +0 -140
- package/skills/doc-gist/CLAUDE.md +0 -25
- package/skills/doc-gist/SKILL.md +0 -97
- package/skills/doc-gist/references/CLAUDE.md +0 -9
- package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +0 -453
- package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +0 -515
- package/skills/doc-gist/references/examples/03-code-review-pr.html +0 -638
- package/skills/doc-gist/references/examples/04-code-understanding.html +0 -491
- package/skills/doc-gist/references/examples/05-design-system.html +0 -629
- package/skills/doc-gist/references/examples/06-component-variants.html +0 -605
- package/skills/doc-gist/references/examples/07-prototype-animation.html +0 -455
- package/skills/doc-gist/references/examples/08-prototype-interaction.html +0 -396
- package/skills/doc-gist/references/examples/09-slide-deck.html +0 -592
- package/skills/doc-gist/references/examples/10-svg-illustrations.html +0 -492
- package/skills/doc-gist/references/examples/11-status-report.html +0 -528
- package/skills/doc-gist/references/examples/12-incident-report.html +0 -596
- package/skills/doc-gist/references/examples/13-flowchart-diagram.html +0 -395
- package/skills/doc-gist/references/examples/14-research-feature-explainer.html +0 -381
- package/skills/doc-gist/references/examples/15-research-concept-explainer.html +0 -368
- package/skills/doc-gist/references/examples/16-implementation-plan.html +0 -702
- package/skills/doc-gist/references/examples/17-pr-writeup.html +0 -595
- package/skills/doc-gist/references/examples/18-editor-triage-board.html +0 -573
- package/skills/doc-gist/references/examples/19-editor-feature-flags.html +0 -663
- package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +0 -722
- package/skills/doc-gist/references/examples/21-decision-signoff.html +0 -546
- package/skills/doc-gist/references/examples/CLAUDE.md +0 -25
- package/skills/doc-gist/references/examples/README.md +0 -5
- package/skills/doc-gist/scripts/CLAUDE.md +0 -27
- package/skills/doc-gist/scripts/doc_gist_scripts_constants/CLAUDE.md +0 -10
- package/skills/doc-gist/scripts/doc_gist_scripts_constants/gist_upload_constants.py +0 -16
- package/skills/doc-gist/scripts/gist_upload.py +0 -177
- package/skills/doc-gist/scripts/test_gist_upload.py +0 -51
- /package/skills/{doc-gist/scripts/doc_gist_scripts_constants → log-audit/scripts/log_audit_constants}/__init__.py +0 -0
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
"""Upload an HTML file as a secret GitHub gist and emit the htmlpreview URL.
|
|
2
|
-
|
|
3
|
-
Single-purpose transport. Takes HTML on stdin or via `--input <path>`, runs
|
|
4
|
-
`gh gist create` (secret by default), parses the gist URL from gh's output,
|
|
5
|
-
composes the htmlpreview.github.io preview URL, optionally opens it in the
|
|
6
|
-
default browser, and prints both URLs.
|
|
7
|
-
|
|
8
|
-
Designed to compose with anything that produces HTML — pipe in the output of
|
|
9
|
-
a script, the contents of a hand-authored file, or have the auto-publish
|
|
10
|
-
hook invoke it on a file Claude just wrote. The script does not opine on
|
|
11
|
-
HTML shape, structure, or styling.
|
|
12
|
-
|
|
13
|
-
Usage:
|
|
14
|
-
gist_upload.py --input <path>
|
|
15
|
-
gist_upload.py --input - --filename writeup.html < some.html
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
from __future__ import annotations
|
|
19
|
-
|
|
20
|
-
import argparse
|
|
21
|
-
import os
|
|
22
|
-
import subprocess
|
|
23
|
-
import sys
|
|
24
|
-
import tempfile
|
|
25
|
-
import webbrowser
|
|
26
|
-
from pathlib import Path
|
|
27
|
-
from urllib.parse import quote
|
|
28
|
-
|
|
29
|
-
_script_directory = str(Path(__file__).resolve().parent)
|
|
30
|
-
if _script_directory not in sys.path:
|
|
31
|
-
sys.path.insert(0, _script_directory)
|
|
32
|
-
|
|
33
|
-
from doc_gist_scripts_constants.gist_upload_constants import ( # noqa: E402
|
|
34
|
-
GIST_DEFAULT_FILENAME,
|
|
35
|
-
GIST_HOST_PREFIX,
|
|
36
|
-
MINIMUM_GIST_URL_PARTS,
|
|
37
|
-
PREVIEW_URL_TEMPLATE,
|
|
38
|
-
UPLOAD_TIMEOUT_SECONDS,
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _read_html(input_argument: str) -> str:
|
|
43
|
-
"""Read HTML content from stdin (when input is '-') or a file path.
|
|
44
|
-
|
|
45
|
-
Reads the full stdin stream when input_argument is '-'. Callers piping
|
|
46
|
-
content through an external process should ensure bounded input.
|
|
47
|
-
"""
|
|
48
|
-
if input_argument == "-":
|
|
49
|
-
return sys.stdin.read()
|
|
50
|
-
try:
|
|
51
|
-
return Path(input_argument).expanduser().resolve().read_text(encoding="utf-8")
|
|
52
|
-
except (OSError, UnicodeError) as error:
|
|
53
|
-
raise SystemExit(f"Cannot read {input_argument}: {error}")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _resolve_filename(input_argument: str, override: str | None) -> str:
|
|
57
|
-
"""Pick the filename gh will use for the gist file."""
|
|
58
|
-
default_filename = GIST_DEFAULT_FILENAME
|
|
59
|
-
if override:
|
|
60
|
-
return Path(override).name
|
|
61
|
-
if input_argument != "-":
|
|
62
|
-
return Path(input_argument).name
|
|
63
|
-
return default_filename
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def _write_to_temp(html_text: str, filename: str, parent_directory: Path) -> Path:
|
|
67
|
-
"""Write HTML to a temp file inside parent_directory with the given filename."""
|
|
68
|
-
target_path = parent_directory / filename
|
|
69
|
-
target_path.write_text(html_text, encoding="utf-8")
|
|
70
|
-
return target_path
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _create_secret_gist(html_path: Path, description: str) -> str:
|
|
74
|
-
"""Run `gh gist create` against html_path and return the gist URL."""
|
|
75
|
-
try:
|
|
76
|
-
completed = subprocess.run(
|
|
77
|
-
["gh", "gist", "create", str(html_path), "--desc", description],
|
|
78
|
-
check=False,
|
|
79
|
-
capture_output=True,
|
|
80
|
-
text=True,
|
|
81
|
-
encoding="utf-8",
|
|
82
|
-
errors="replace",
|
|
83
|
-
timeout=UPLOAD_TIMEOUT_SECONDS,
|
|
84
|
-
)
|
|
85
|
-
except FileNotFoundError:
|
|
86
|
-
raise SystemExit(
|
|
87
|
-
"gh CLI not found. Install GitHub CLI (https://cli.github.com) and run `gh auth login`."
|
|
88
|
-
)
|
|
89
|
-
except subprocess.TimeoutExpired:
|
|
90
|
-
raise SystemExit(
|
|
91
|
-
f"gh gist create timed out after {UPLOAD_TIMEOUT_SECONDS}s. Check network and retry."
|
|
92
|
-
)
|
|
93
|
-
if completed.returncode != 0:
|
|
94
|
-
message_text = completed.stderr.strip() or completed.stdout.strip()
|
|
95
|
-
raise SystemExit(
|
|
96
|
-
f"gh gist create failed:\n{message_text}\nRun `gh auth login` and retry."
|
|
97
|
-
)
|
|
98
|
-
output_lines = completed.stdout.strip().splitlines()
|
|
99
|
-
if not output_lines:
|
|
100
|
-
raise SystemExit("gh gist create produced no output.")
|
|
101
|
-
last_line = output_lines[-1].strip()
|
|
102
|
-
if not last_line.startswith(GIST_HOST_PREFIX):
|
|
103
|
-
raise SystemExit(f"Unexpected gh gist create output: {last_line!r}")
|
|
104
|
-
return last_line
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _compose_preview_url(gist_url: str, filename: str) -> str:
|
|
108
|
-
"""Build the htmlpreview.github.io URL from the gist URL and the gist filename."""
|
|
109
|
-
minimum_parts = MINIMUM_GIST_URL_PARTS
|
|
110
|
-
preview_template = PREVIEW_URL_TEMPLATE
|
|
111
|
-
path_after_host = gist_url[len(GIST_HOST_PREFIX) :]
|
|
112
|
-
parts = path_after_host.split("/")
|
|
113
|
-
if len(parts) < minimum_parts:
|
|
114
|
-
raise SystemExit(f"Cannot parse gist URL: {gist_url!r}")
|
|
115
|
-
return preview_template.format(user=parts[0], gist_id=parts[1], filename=quote(filename, safe=""))
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def _open_in_browser(url: str) -> None:
|
|
119
|
-
"""Open the URL in the default browser, deferring to OS-native behavior on Windows."""
|
|
120
|
-
if sys.platform.startswith("win"):
|
|
121
|
-
os.startfile(url)
|
|
122
|
-
return
|
|
123
|
-
webbrowser.open(url)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def main() -> int:
|
|
127
|
-
"""Entry point — read HTML, upload as secret gist, print URLs, open preview.
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
Process exit code (0 on success).
|
|
131
|
-
"""
|
|
132
|
-
parser = argparse.ArgumentParser(
|
|
133
|
-
description="Upload HTML as a secret gist; print gist + htmlpreview URLs."
|
|
134
|
-
)
|
|
135
|
-
parser.add_argument(
|
|
136
|
-
"--input",
|
|
137
|
-
required=True,
|
|
138
|
-
help="Path to an .html file, or '-' for stdin.",
|
|
139
|
-
)
|
|
140
|
-
parser.add_argument(
|
|
141
|
-
"--filename",
|
|
142
|
-
default=None,
|
|
143
|
-
help="Filename inside the gist. Defaults to the input filename, or 'doc.html' for stdin.",
|
|
144
|
-
)
|
|
145
|
-
parser.add_argument(
|
|
146
|
-
"--description",
|
|
147
|
-
default="HTML artifact",
|
|
148
|
-
help="Gist description.",
|
|
149
|
-
)
|
|
150
|
-
parser.add_argument(
|
|
151
|
-
"--no-open",
|
|
152
|
-
action="store_true",
|
|
153
|
-
help="Skip opening the preview URL in the default browser.",
|
|
154
|
-
)
|
|
155
|
-
arguments = parser.parse_args()
|
|
156
|
-
|
|
157
|
-
html_text = _read_html(arguments.input)
|
|
158
|
-
filename = _resolve_filename(arguments.input, arguments.filename)
|
|
159
|
-
|
|
160
|
-
with tempfile.TemporaryDirectory(prefix="gist-upload-") as temp_directory:
|
|
161
|
-
upload_path = _write_to_temp(html_text, filename, Path(temp_directory))
|
|
162
|
-
gist_url = _create_secret_gist(upload_path, arguments.description)
|
|
163
|
-
preview_url = _compose_preview_url(gist_url, filename)
|
|
164
|
-
|
|
165
|
-
print(f"Gist: {gist_url}", file=sys.stderr)
|
|
166
|
-
print(f"Preview: {preview_url}", file=sys.stderr)
|
|
167
|
-
|
|
168
|
-
if not arguments.no_open:
|
|
169
|
-
_open_in_browser(preview_url)
|
|
170
|
-
print("Opened preview in default browser.", file=sys.stderr)
|
|
171
|
-
|
|
172
|
-
print(preview_url)
|
|
173
|
-
return 0
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if __name__ == "__main__":
|
|
177
|
-
sys.exit(main())
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"""Tests for gist_upload.py pure functions — URL composition and filename resolution."""
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
_script_directory = str(Path(__file__).resolve().parent)
|
|
7
|
-
if _script_directory not in sys.path:
|
|
8
|
-
sys.path.insert(0, _script_directory)
|
|
9
|
-
|
|
10
|
-
from gist_upload import _compose_preview_url, _resolve_filename
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class TestResolveFilename:
|
|
14
|
-
def test_uses_override_when_provided(self):
|
|
15
|
-
assert (
|
|
16
|
-
_resolve_filename("report.html", "custom-name.html") == "custom-name.html"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def test_strips_directory_from_override(self):
|
|
20
|
-
assert (
|
|
21
|
-
_resolve_filename("report.html", "/some/path/override.html")
|
|
22
|
-
== "override.html"
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
def test_uses_input_filename_when_no_override(self):
|
|
26
|
-
assert _resolve_filename("report.html", None) == "report.html"
|
|
27
|
-
|
|
28
|
-
def test_uses_default_for_stdin_without_override(self):
|
|
29
|
-
assert _resolve_filename("-", None) == "doc.html"
|
|
30
|
-
|
|
31
|
-
def test_override_takes_precedence_over_stdin(self):
|
|
32
|
-
assert _resolve_filename("-", "writeup.html") == "writeup.html"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class TestComposePreviewUrl:
|
|
36
|
-
def test_standard_gist_url(self):
|
|
37
|
-
result = _compose_preview_url(
|
|
38
|
-
"https://gist.github.com/user123/abc123def456",
|
|
39
|
-
"report.html",
|
|
40
|
-
)
|
|
41
|
-
assert result == (
|
|
42
|
-
"https://htmlpreview.github.io/"
|
|
43
|
-
"?https://gist.githubusercontent.com/user123/abc123def456/raw/report.html"
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
def test_filename_with_spaces_is_encoded(self):
|
|
47
|
-
result = _compose_preview_url(
|
|
48
|
-
"https://gist.github.com/user123/abc123def456",
|
|
49
|
-
"my report.html",
|
|
50
|
-
)
|
|
51
|
-
assert "my%20report.html" in result
|
|
File without changes
|