skilldrop-cli 0.16.0 → 0.16.2

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 (115) hide show
  1. package/package.json +1 -1
  2. package/packs/ai-engineering/skills/agent-adoption-stage/SKILL.md +1 -0
  3. package/packs/ai-engineering/skills/agent-adoption-stage/manifest.json +1 -1
  4. package/packs/ai-engineering/skills/agent-budget/SKILL.md +2 -0
  5. package/packs/ai-engineering/skills/agent-budget/manifest.json +1 -1
  6. package/packs/ai-engineering/skills/agent-loop-design/SKILL.md +2 -0
  7. package/packs/ai-engineering/skills/agent-loop-design/manifest.json +1 -1
  8. package/packs/ai-engineering/skills/agent-threat-model/SKILL.md +2 -0
  9. package/packs/ai-engineering/skills/agent-threat-model/manifest.json +1 -1
  10. package/packs/ai-engineering/skills/ai-readiness-assessment/SKILL.md +1 -0
  11. package/packs/ai-engineering/skills/ai-readiness-assessment/manifest.json +1 -1
  12. package/packs/ai-engineering/skills/ai-usage-report/evals/files/1/northwind-ai-events.csv +4213 -0
  13. package/packs/ai-engineering/skills/subagent-design/SKILL.md +2 -0
  14. package/packs/ai-engineering/skills/subagent-design/manifest.json +1 -1
  15. package/packs/api-builder/skills/eval-harness-generator/evals/files/1/SKILL.md +31 -0
  16. package/packs/converters/skills/file-to-markdown/SKILL.md +2 -0
  17. package/packs/converters/skills/file-to-markdown/evals/files/1/northwind-q3.pptx +0 -0
  18. package/packs/converters/skills/file-to-markdown/evals/files/2/acme-contract-summary.pdf +93 -0
  19. package/packs/converters/skills/file-to-markdown/manifest.json +1 -1
  20. package/packs/converters/skills/file-to-markdown/scripts/to_markdown.py +33 -2
  21. package/packs/converters/skills/md-to-docx/SKILL.md +2 -0
  22. package/packs/converters/skills/md-to-docx/evals/files/1/brand/brand.json +80 -0
  23. package/packs/converters/skills/md-to-docx/evals/files/1/brand/logo-white.png +0 -0
  24. package/packs/converters/skills/md-to-docx/evals/files/1/brand/logo.png +0 -0
  25. package/packs/converters/skills/md-to-docx/evals/files/1/brand/mark.png +0 -0
  26. package/packs/converters/skills/md-to-docx/evals/files/1/docs/vendor-onboarding.md +42 -0
  27. package/packs/converters/skills/md-to-docx/manifest.json +1 -1
  28. package/packs/converters/skills/md-to-docx/scripts/md_to_docx.py +3 -1
  29. package/packs/converters/skills/md-to-html/evals/files/1/brand/brand.json +80 -0
  30. package/packs/converters/skills/md-to-html/evals/files/1/brand/logo-white.png +0 -0
  31. package/packs/converters/skills/md-to-html/evals/files/1/brand/logo.png +0 -0
  32. package/packs/converters/skills/md-to-html/evals/files/1/brand/mark.png +0 -0
  33. package/packs/converters/skills/md-to-html/evals/files/1/docs/q3-review.md +35 -0
  34. package/packs/converters/skills/md-to-html/evals/files/1/img/dashboard.png +0 -0
  35. package/packs/converters/skills/md-to-xlsx/SKILL.md +2 -1
  36. package/packs/converters/skills/md-to-xlsx/evals/files/1/exports/northwind-invoices.csv +25 -0
  37. package/packs/converters/skills/md-to-xlsx/evals/files/2/reports/q3-ops-review.md +32 -0
  38. package/packs/converters/skills/md-to-xlsx/manifest.json +1 -1
  39. package/packs/converters/skills/md-to-xlsx/scripts/md_to_xlsx.py +18 -4
  40. package/packs/converters/skills/mermaid-render/SKILL.md +1 -0
  41. package/packs/converters/skills/mermaid-render/evals/files/1/docs/contoso-orders.md +23 -0
  42. package/packs/converters/skills/mermaid-render/manifest.json +1 -1
  43. package/packs/core/skills/brief-intake/SKILL.md +1 -0
  44. package/packs/core/skills/brief-intake/manifest.json +1 -1
  45. package/packs/core/skills/output-hygiene/SKILL.md +2 -0
  46. package/packs/core/skills/output-hygiene/manifest.json +1 -1
  47. package/packs/design/skills/brand-kit/evals/files/1/brand/northwind-logo-white.png +0 -0
  48. package/packs/design/skills/brand-kit/evals/files/1/brand/northwind-logo.png +0 -0
  49. package/packs/design/skills/deck-builder/SKILL.md +2 -0
  50. package/packs/design/skills/deck-builder/manifest.json +1 -1
  51. package/packs/design/skills/marketing-flyer/evals/files/1/brand/brand.json +80 -0
  52. package/packs/design/skills/marketing-flyer/evals/files/1/brand/logo-white.png +0 -0
  53. package/packs/design/skills/marketing-flyer/evals/files/1/brand/logo.png +0 -0
  54. package/packs/design/skills/marketing-flyer/evals/files/1/brand/mark.png +0 -0
  55. package/packs/dev-team/skills/agents-md-generator/SKILL.md +4 -2
  56. package/packs/dev-team/skills/agents-md-generator/evals/files/1/.github/workflows/ci.yml +10 -0
  57. package/packs/dev-team/skills/agents-md-generator/evals/files/1/Makefile +5 -0
  58. package/packs/dev-team/skills/agents-md-generator/evals/files/1/alembic/versions/0001_create_bookings.py +10 -0
  59. package/packs/dev-team/skills/agents-md-generator/evals/files/1/booking/__init__.py +0 -0
  60. package/packs/dev-team/skills/agents-md-generator/evals/files/1/booking/app.py +8 -0
  61. package/packs/dev-team/skills/agents-md-generator/evals/files/1/pyproject.toml +11 -0
  62. package/packs/dev-team/skills/agents-md-generator/evals/files/1/tests/test_health.py +5 -0
  63. package/packs/dev-team/skills/agents-md-generator/evals/files/2/AGENTS.md +3 -0
  64. package/packs/dev-team/skills/agents-md-generator/evals/files/2/package.json +12 -0
  65. package/packs/dev-team/skills/agents-md-generator/evals/files/2/src/index.ts +1 -0
  66. package/packs/dev-team/skills/agents-md-generator/manifest.json +1 -1
  67. package/packs/dev-team/skills/agents-md-generator/templates/agents-md.md +2 -2
  68. package/packs/dev-team/skills/devils-advocate/SKILL.md +1 -0
  69. package/packs/dev-team/skills/devils-advocate/manifest.json +1 -1
  70. package/packs/dev-team/skills/pre-merge-review/SKILL.md +2 -0
  71. package/packs/dev-team/skills/pre-merge-review/manifest.json +1 -1
  72. package/packs/dev-team/skills/pre-merge-review/scripts/gate.py +4 -1
  73. package/packs/infra-as-code/skills/terraform-plan-review/evals/files/2/plan.json +133 -0
  74. package/packs/product-manager/skills/prfaq/SKILL.md +1 -0
  75. package/packs/product-manager/skills/prfaq/manifest.json +1 -1
  76. package/packs/product-manager/skills/strategy-analysis/SKILL.md +1 -1
  77. package/packs/product-manager/skills/strategy-analysis/manifest.json +1 -1
  78. package/packs/product-manager/skills/success-metrics/SKILL.md +2 -0
  79. package/packs/product-manager/skills/success-metrics/manifest.json +1 -1
  80. package/packs/product-manager/skills/user-journey-map/SKILL.md +1 -0
  81. package/packs/product-manager/skills/user-journey-map/manifest.json +1 -1
  82. package/packs/research/skills/research-plan/SKILL.md +2 -0
  83. package/packs/research/skills/research-plan/manifest.json +1 -1
  84. package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/changelog-writer/SKILL.md +10 -0
  85. package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/pr-summary/SKILL.md +12 -0
  86. package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/pr-summary/references/tone.md +3 -0
  87. package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/pr-summary/scripts/collect.py +6 -0
  88. package/packs/solution-architect/skills/adr-generator/SKILL.md +3 -2
  89. package/packs/solution-architect/skills/adr-generator/manifest.json +1 -1
  90. package/packs/solution-architect/skills/figma-diagrams/SKILL.md +1 -0
  91. package/packs/solution-architect/skills/figma-diagrams/manifest.json +1 -1
  92. package/packs/sre-oncall/skills/delivery-metrics-report/SKILL.md +3 -1
  93. package/packs/sre-oncall/skills/delivery-metrics-report/evals/files/1/deploys.csv +49 -0
  94. package/packs/sre-oncall/skills/delivery-metrics-report/evals/files/1/incidents.csv +7 -0
  95. package/packs/sre-oncall/skills/delivery-metrics-report/evals/files/1/prs.csv +84 -0
  96. package/packs/sre-oncall/skills/delivery-metrics-report/manifest.json +1 -1
  97. package/packs/sre-oncall/skills/postmortem-generator/SKILL.md +1 -0
  98. package/packs/sre-oncall/skills/postmortem-generator/manifest.json +1 -1
  99. package/packs/stakeholder-comms/skills/audience-profile/SKILL.md +1 -0
  100. package/packs/stakeholder-comms/skills/audience-profile/manifest.json +1 -1
  101. package/packs/stakeholder-comms/skills/decision-log/SKILL.md +1 -0
  102. package/packs/stakeholder-comms/skills/decision-log/manifest.json +1 -1
  103. package/packs/stakeholder-comms/skills/guide-builder/SKILL.md +1 -0
  104. package/packs/stakeholder-comms/skills/guide-builder/manifest.json +1 -1
  105. package/packs/trackers/skills/backlog-triage/SKILL.md +1 -0
  106. package/packs/trackers/skills/backlog-triage/evals/files/1/examples/northwind-backlog.csv +28 -0
  107. package/packs/trackers/skills/backlog-triage/evals/files/2/issues.json +6052 -0
  108. package/packs/trackers/skills/backlog-triage/manifest.json +1 -1
  109. package/packs/trackers/skills/team-status-report/SKILL.md +1 -0
  110. package/packs/trackers/skills/team-status-report/evals/files/1/examples/northwind-week-40.csv +16 -0
  111. package/packs/trackers/skills/team-status-report/evals/files/2/issues.json +1212 -0
  112. package/packs/trackers/skills/team-status-report/manifest.json +1 -1
  113. package/packs/trackers/skills/tracker-brief-sync/evals/files/1/examples/prd-guest-checkout.md +53 -0
  114. package/packs/trackers/skills/tracker-brief-sync/evals/files/2/examples/prd-guest-checkout.md +53 -0
  115. package/packs/trackers/skills/tracker-brief-sync/evals/files/2/examples/tracker-after-two-weeks.csv +30 -0
@@ -170,8 +170,11 @@ def type_text(s, formulas, stats, tz_flag, infer_numbers=True):
170
170
  text = "0"
171
171
  return Cell("n", text, fmt, width)
172
172
  if RE_SCI.match(s):
173
- stats["numbers"] += 1
174
- return Cell("n", repr(float(s)), None, width)
173
+ val = float(s)
174
+ # 1e999 overflows to inf, which is not a number Excel can read: keep it as text
175
+ if val == val and val not in (float("inf"), float("-inf")):
176
+ stats["numbers"] += 1
177
+ return Cell("n", num_text(val), None, width)
175
178
  if len(raw) > MAX_CELL:
176
179
  stats["truncated"] += 1
177
180
  s = s[:MAX_CELL]
@@ -189,6 +192,10 @@ def type_json(v, formulas, stats, tz_flag):
189
192
  if v != v or v in (float("inf"), float("-inf")):
190
193
  stats["text"] += 1
191
194
  return Cell("s", str(v), None, len(str(v)))
195
+ if isinstance(v, int) and len(str(abs(v))) > 15:
196
+ # Excel keeps 15 significant digits; a longer integer is an ID, and rounding it is data loss
197
+ stats["text"] += 1
198
+ return Cell("s", str(v), None, len(str(v)))
192
199
  stats["numbers"] += 1
193
200
  return Cell("n", num_text(v), None, len(num_text(v)))
194
201
  if isinstance(v, (dict, list)):
@@ -230,6 +237,9 @@ def split_row(line):
230
237
  return cells
231
238
 
232
239
 
240
+ HTML_TAGS = [0] # tags removed by strip_md, reported once per file
241
+
242
+
233
243
  def strip_md(s):
234
244
  """Plain text from a Markdown table cell."""
235
245
  s = re.sub(r"<br\s*/?>", "\n", s, flags=re.I)
@@ -240,7 +250,8 @@ def strip_md(s):
240
250
  s = re.sub(r"(?<![\w*])\*(?!\s)(.+?)(?<!\s)\*(?![\w*])", r"\1", s)
241
251
  s = re.sub(r"(?<!\w)_(?!\s)(.+?)(?<!\s)_(?!\w)", r"\1", s)
242
252
  s = re.sub(r"~~(.+?)~~", r"\1", s)
243
- s = re.sub(r"</?[A-Za-z][^>]*>", "", s)
253
+ s, n = re.subn(r"</?[A-Za-z][^>]*>", "", s)
254
+ HTML_TAGS[0] += n
244
255
  s = re.sub(r"\\([\\`*_{}\[\]()#+\-.!|~])", r"\1", s)
245
256
  return s
246
257
 
@@ -280,6 +291,9 @@ def read_markdown(text):
280
291
  tables.append((heading, header, rows, start))
281
292
  continue
282
293
  i += 1
294
+ if HTML_TAGS[0]:
295
+ warn("%d HTML tag(s) removed from headings and cells (text between them kept); write a literal "
296
+ "<...> as &lt;...&gt; or in backticks to keep it" % HTML_TAGS[0])
283
297
  return tables
284
298
 
285
299
 
@@ -533,7 +547,7 @@ def write_xlsx(out, sheets, title, formulas):
533
547
  '<bookViews><workbookView activeTab="0"/></bookViews><sheets>%s</sheets>'
534
548
  '<definedNames>%s</definedNames>%s</workbook>') % (
535
549
  "".join(sheet_tags), "".join(names), '<calcPr fullCalcOnLoad="1"/>' if formulas else "")
536
- now = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
550
+ now = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
537
551
  core = ('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'
538
552
  '<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" '
539
553
  'xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" '
@@ -106,3 +106,4 @@ block end> at <file>:<line>` and do not render that diagram.
106
106
  - ❌ **Rendering with `--force` and shipping the result.** Mermaid draws an error graphic, not the diagram.
107
107
  - ❌ **Sending the HTML fallback as if it were an SVG.** It is a web page that needs network.
108
108
  - ❌ **Linting a copy and reporting line numbers from it.** Run the script on the user's own `.md` so the numbers match their editor.
109
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
@@ -0,0 +1,23 @@
1
+ # Contoso orders
2
+
3
+ ## Order states
4
+
5
+ ```mermaid
6
+ stateDiagram-v2
7
+ [*] --> Placed
8
+ Placed --> Paid
9
+ Paid --> Shipped
10
+ Shipped --> [*]
11
+ ```
12
+
13
+ ## Order flow
14
+
15
+ ```mermaid
16
+ flowchart TD
17
+ A[Customer places order] --> B{In stock?}
18
+ B -->|Yes| C[Reserve stock (warehouse)]
19
+ B -->|No| D[Back-order]
20
+ C -> E[Take payment]
21
+ E --> F[Ship]
22
+ D --> F
23
+ ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mermaid-render",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Check Mermaid diagrams for the mistakes that stop them rendering (unknown diagram type, unbalanced brackets or quotes, unquoted parentheses in labels, the word end as a node id, missing arrows, unclosed subgraphs or alt blocks) with line numbers and a fix for each, then render them to SVG, PNG or PDF with mermaid-cli, or to a standalone HTML page when it is not installed. Works on a .mmd file or every mermaid fence in a Markdown doc. Use when a diagram \"won't render\", the user says \"check my mermaid\", \"export this diagram as SVG/PNG\", or needs the diagrams in a doc as image files.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": {
@@ -76,3 +76,4 @@ You help the user (or the next skill in the chain) absorb raw unstructured input
76
76
  - ❌ Skipping the gaps section because the brief looks fine — the gaps are the *most useful output* for the user about to invoke the downstream skill.
77
77
  - ❌ Asking 4+ clarifying questions. If the source is too thin, say so once and let the user decide whether to add material or proceed with gaps flagged.
78
78
  - ❌ Emitting the brief in prose. Downstream skills want structured fields, not paragraphs.
79
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brief-intake",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Turn raw mess — a Slack thread, meeting transcript, Jira ticket, half-written Notion page, email chain, or paragraph of free-form context — into a structured brief that the downstream skill (adr-generator, design-doc, runbook-generator, exec-summary, deck-builder, tech-comparison-matrix) can consume without further intake. Use whenever the user has unstructured source material and is about to invoke another skilldrop skill, or when a draft is missing the load-bearing context the next step will need.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -93,3 +93,5 @@ There is no cryptographic watermark in Claude's text output, and this skill does
93
93
  - ❌ **Auto-replacing a homoglyph with the ASCII letter that looks like it.** The word may be genuinely non-English. Report it, show the codepoint, let the author decide.
94
94
  - ❌ **Re-reading the whole draft for characters the script already found.** The script is exhaustive on its classes and cheaper than a model pass. Spend the model on prose.
95
95
  - ❌ **Running `--fix` and reporting only the count.** "Removed 6 artifacts" is not auditable. List them.
96
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
97
+ - ❌ **A bare `BLOCKED` line.** Keep the `BLOCKED: need <X>` line, then write for a person: what is missing in plain words, what you will produce once you have it, and anything the request already lets you say.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "output-hygiene",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Review agent-written text before it ships and strip the machine artifacts it carries — invisible Unicode, non-breaking spaces, homoglyphs, harness-added provenance trailers, trailing chat closers — then flag the prose tells a script cannot catch, each quoted with a rewrite. Use when the user wants to clean up AI-generated output, asks to remove a Claude watermark, attribution footer, or \"Generated with\" line, wants a draft that does not read as machine-written, or needs a pre-ship hygiene pass on a document, commit message, or pasted chat answer.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": {
@@ -197,3 +197,5 @@ A generated deck is a strong first draft. Always tell the user to:
197
197
  - ❌ Shipping the deck with a grey placeholder box still in it because the warning went unread.
198
198
  - ❌ Defaulting to bullets when a `big_number`, `chart`, `quote` or `two_column` would land harder.
199
199
  - ❌ More than ~20 slides for any audience. If the point needs 21, the deck is the wrong format.
200
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
201
+ - ❌ **A bare `BLOCKED` line.** Keep the `BLOCKED: need <X>` line, then write for a person: what is missing in plain words, what you will produce once you have it, and anything the request already lets you say.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deck-builder",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Generate a real PowerPoint (.pptx) file from content, audience, and either a brand template or a color palette — with charts, tables and images, not only bullets. Slide count, density and layout are tuned to the audience: execs, boards, technical reviewers, sales prospects, investors, internal teams. Use when the user wants an actual editable .pptx rather than an outline, wants their corporate template or brand colours applied, or says \"build the deck\", \"make it a pptx\", \"use our template\".",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": {
@@ -0,0 +1,80 @@
1
+ {
2
+ "$comment": "brand-kit output. deck-builder and marketing-flyer read this file; any field left out is asked for or defaulted by them. Paths are relative to this file. Every value carries where it came from in `sources`.",
3
+ "name": "Northwind Health",
4
+ "tagline": "Care that comes to you",
5
+ "logo": {
6
+ "primary": "logo.png",
7
+ "on_dark": "logo-white.png",
8
+ "mark": "mark.png",
9
+ "notes": "Keep clear space equal to the height of the N on every side. Never place the full-colour logo on the green."
10
+ },
11
+ "colors": {
12
+ "primary": "#0E5A46",
13
+ "secondary": "#3D7F6B",
14
+ "accent": "#F2A541",
15
+ "background": "#FFFFFF",
16
+ "text": "#1F2A28",
17
+ "extra": [
18
+ {
19
+ "name": "Mist",
20
+ "hex": "#E8F1EE",
21
+ "use": "panel backgrounds"
22
+ }
23
+ ]
24
+ },
25
+ "fonts": {
26
+ "heading": {
27
+ "family": "Georgia",
28
+ "fallback": "serif",
29
+ "weight": 700
30
+ },
31
+ "body": {
32
+ "family": "Arial",
33
+ "fallback": "sans-serif",
34
+ "weight": 400
35
+ }
36
+ },
37
+ "voice": {
38
+ "tone": "Warm, plain, confident. Short sentences.",
39
+ "use": [
40
+ "members",
41
+ "care team",
42
+ "near you"
43
+ ],
44
+ "avoid": [
45
+ "patients",
46
+ "cutting-edge",
47
+ "solutions"
48
+ ]
49
+ },
50
+ "imagery": {
51
+ "style": "Real people in daylight, community settings, no stock handshakes.",
52
+ "do": [
53
+ "natural light",
54
+ "diverse ages"
55
+ ],
56
+ "dont": [
57
+ "clinical close-ups",
58
+ "illustrated icons as hero images"
59
+ ]
60
+ },
61
+ "templates": {
62
+ "pptx": "northwind-master.potx"
63
+ },
64
+ "contact": {
65
+ "website": "northwindhealth.example",
66
+ "email": "hello@northwindhealth.example",
67
+ "phone": "",
68
+ "address": ""
69
+ },
70
+ "legal": {
71
+ "footer": "\u00a9 2026 Northwind Health",
72
+ "disclaimer": ""
73
+ },
74
+ "sources": {
75
+ "colors": "brand guidelines PDF, page 4 [explicit]",
76
+ "fonts": "brand guidelines PDF, page 6 [explicit]",
77
+ "voice": "website About page [inferred]",
78
+ "logo": "files supplied by the user [explicit]"
79
+ }
80
+ }
@@ -21,7 +21,7 @@ Two modes, chosen by what's already there:
21
21
 
22
22
  2. **Apply the evidence rule without exception.** A command appears only if it traces to a file in the repo. Never infer from ecosystem convention: a Python repo does not necessarily run `pytest`, and a repo with `jest` in `devDependencies` may still have no test script.
23
23
 
24
- When a section needs a command that doesn't exist, write the marker, not a guess: ✅ *"Test: `[missing: no test script in package.json or CI]`"* — ❌ *"Test: `npm test`"*. The marker is useful; the guess is a trap.
24
+ When a section needs a command that doesn't exist, record the gap, not a guess. In the provenance table it is `[missing: no test script in package.json or CI]`. In the file itself it is a plain line an agent can act on: ✅ *"Test: none defined in this repo. Do not run `npm test`."* — ❌ *"Test: `npm test`"*. The stated gap is useful; the guess is a trap.
25
25
 
26
26
  3. **Derive file placement from the actual tree**, not from what the framework usually does. Name the directories that exist and what belongs in each. Two or three rows beat a full tree dump.
27
27
 
@@ -46,7 +46,7 @@ Two modes, chosen by what's already there:
46
46
 
47
47
  ## Quality bar
48
48
 
49
- - **Zero unverified commands.** Every one traces to a file and key, or carries a `[missing: …]` marker. This is the bar; a file that fails it is worse than no file.
49
+ - **Zero unverified commands.** Every one traces to a file and key, or is stated as a gap (`[missing: …]` in the provenance table, a plain "none defined" line in the file). This is the bar; a file that fails it is worse than no file.
50
50
  - **A newcomer agent could build and test from this file alone** — or can see plainly that the repo has no such command.
51
51
  - **Forbidden actions are named**, not implied.
52
52
  - **Every convention line passes the counterfactual test.** If an agent would do the right thing without it, it is padding.
@@ -78,3 +78,5 @@ Two modes, chosen by what's already there:
78
78
  - ❌ **A satellite that duplicates `AGENTS.md`.** Guaranteed drift, invisible until an agent acts on the stale copy.
79
79
  - ❌ **Silently rewriting a hand-tuned file.** Audit mode emits a diff and lets a human choose; the file may encode decisions the repo can't show you.
80
80
  - ❌ **Writing to the cap.** 150 lines is a ceiling, not a target. Most repos need far less.
81
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
82
+ - ❌ **A bare `BLOCKED` line.** Keep the `BLOCKED: need <X>` line, then write for a person: what is missing in plain words, what you will produce once you have it, and anything the request already lets you say.
@@ -0,0 +1,10 @@
1
+ name: ci
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - run: pip install -e .[dev]
9
+ - run: ruff check .
10
+ - run: pytest -q
@@ -0,0 +1,5 @@
1
+ run:
2
+ uvicorn booking.app:app --reload
3
+
4
+ migrate:
5
+ alembic upgrade head
@@ -0,0 +1,10 @@
1
+ revision = "0001"
2
+ down_revision = None
3
+
4
+
5
+ def upgrade():
6
+ pass
7
+
8
+
9
+ def downgrade():
10
+ pass
@@ -0,0 +1,8 @@
1
+ from fastapi import FastAPI
2
+
3
+ app = FastAPI()
4
+
5
+
6
+ @app.get("/health")
7
+ def health():
8
+ return {"ok": True}
@@ -0,0 +1,11 @@
1
+ [project]
2
+ name = "northwind-booking"
3
+ version = "0.4.0"
4
+ requires-python = ">=3.11"
5
+ dependencies = ["fastapi", "sqlalchemy", "alembic"]
6
+
7
+ [project.optional-dependencies]
8
+ dev = ["pytest", "ruff"]
9
+
10
+ [tool.ruff]
11
+ line-length = 100
@@ -0,0 +1,5 @@
1
+ from booking.app import health
2
+
3
+
4
+ def test_health():
5
+ assert health() == {"ok": True}
@@ -0,0 +1,3 @@
1
+ # AGENTS.md
2
+
3
+ Run `npm test` to test. Write clean, maintainable code and follow best practices. Be thorough in reviews.
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "acme-portal",
3
+ "version": "1.2.0",
4
+ "scripts": {
5
+ "build": "tsc -p .",
6
+ "lint": "eslint src"
7
+ },
8
+ "devDependencies": {
9
+ "typescript": "^5.4.0",
10
+ "eslint": "^9.0.0"
11
+ }
12
+ }
@@ -0,0 +1 @@
1
+ export const main = (): string => "acme-portal";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-md-generator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Generate or audit a repository's AGENTS.md — the agent-policy file Claude Code, Codex, Cursor, Copilot, Kiro and Antigravity read — with every command traced to real evidence in the repo, generic virtue instructions stripped, and forbidden actions named. Use when a repo has no AGENTS.md, when an existing one is stale or ignored, when onboarding a codebase to agentic coding, or when an agent keeps running commands that don't exist.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -14,7 +14,7 @@
14
14
  |---|---|---|
15
15
  | Install | `{cmd}` | `{file}` → `{key}` |
16
16
  | Build | `{cmd}` | `{file}` → `{key}` |
17
- | Test | `{cmd}` *or* `[missing: no test command in CI or manifests]` | `{file}` → `{key}` |
17
+ | Test | `{cmd}` *or* none defined in this repo; do not guess one | `{file}` → `{key}` |
18
18
  | Lint | `{cmd}` | `{file}` → `{key}` |
19
19
  | Run locally | `{cmd}` | `{file}` → `{key}` |
20
20
 
@@ -44,5 +44,5 @@
44
44
 
45
45
  <!--
46
46
  Line budget: 150. Provenance for every command was verified at generation time.
47
- Commands marked [missing] are findings, not omissions — the repo has no such command.
47
+ A row that says "none defined" is a finding, not an omission — the repo has no such command.
48
48
  -->
@@ -140,3 +140,4 @@ Specifically:
140
140
  - ❌ **Reviewing untouched code.** Out-of-scope. The skill challenges the *change*, not the codebase.
141
141
  - ❌ **Demanding tests for *everything* the change touches.** Only the new logic and new error paths. Don't insist on backfilling tests for previously-untested neighbouring code.
142
142
  - ❌ **Skipping "what's solid".** Trains the user (or downstream agent) to dread the skill. End on signal that's actionable in the other direction.
143
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devils-advocate",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Adversarial review of just-generated code, run *after* an agent (or human) declares a feature done. Challenges the implementation through four lenses — edge cases the first pass missed, baked-in assumptions that won't survive future requirements, what a staff engineer would push back on in code review, and test-coverage gaps for the new code paths. Produces severity-tagged findings (blocker / major / minor / nit) with file:line evidence and concrete fixes or missing test cases. Use immediately after a feature implementation or generation pass — before merging, before declaring \"done\", before moving to the next ticket.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -79,5 +79,7 @@ The honest limit: a portable *skill* can't physically block an agent — enforce
79
79
  - ❌ **Triple-reporting.** The same `file:line` flagged by all three lenses as three findings. Merge them.
80
80
  - ❌ **Adjudicating a design debate.** Settling "queue vs cron" inside the verdict instead of gating on gate+severity and offering `council-review`.
81
81
  - ❌ **Calling a reviewer *skill* from here.** Skills don't invoke skills (see CLAUDE.md). Drive the review *subagents* where they exist, or sweep the lenses inline.
82
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
83
+ - ❌ **A bare `BLOCKED` line.** Keep the `BLOCKED: need <X>` line, then write for a person: what is missing in plain words, what you will produce once you have it, and anything the request already lets you say.
82
84
 
83
85
  **Non-interactive:** if the verify commands can't be detected and none were supplied, emit `BLOCKED: need verify commands (--cmd/--config)` — never fabricate a green gate. If the change scope is ambiguous, default to the working-tree diff and tag it `[assumption]` at the top of the report.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pre-merge-review",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Gate an existing change for merge — run one skill that fires the whole production-readiness pass. First a deterministic mechanical gate (lint + typecheck + tests, via a script whose exit code decides), then the three-reviewer panel dispatched in parallel — devils-advocate (correctness), security-reviewer (exploitability), code-quality (craft) — then a single READY / NOT READY verdict. Use before opening a PR or merging, when you want the full review fleet run on a diff you already have. Do NOT use to implement a feature from a spec (that's feature-implement-loop) or to review a document (that's doc-critique).",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -112,7 +112,10 @@ def install_hook(root, cmd, config):
112
112
  body += "\n" + _hook_block(cmd, config)
113
113
  with open(path, "w", encoding="utf-8") as fh:
114
114
  fh.write(body)
115
- os.chmod(path, 0o755)
115
+ # chmod +x, not a fixed 0o755: add execute only where the umask already granted read, so a
116
+ # restrictive umask (077) keeps the hook private instead of being widened to world-readable.
117
+ mode = os.stat(path).st_mode
118
+ os.chmod(path, mode | ((mode & 0o444) >> 2))
116
119
  print(f"gate: installed a blocking pre-commit hook -> {path}")
117
120
  print(" a RED gate now blocks `git commit` (any tool). Bypass once with --no-verify; "
118
121
  "wire CI required-checks for the un-bypassable backstop.")
@@ -0,0 +1,133 @@
1
+ {
2
+ "format_version": "1.2",
3
+ "terraform_version": "1.9.5",
4
+ "resource_drift": [
5
+ {
6
+ "address": "aws_route_table.private",
7
+ "mode": "managed",
8
+ "type": "aws_route_table",
9
+ "name": "private",
10
+ "provider_name": "registry.terraform.io/hashicorp/aws",
11
+ "change": {
12
+ "actions": [
13
+ "update"
14
+ ],
15
+ "before": {
16
+ "id": "rtb-0aa11bb22cc33dd44",
17
+ "route": [
18
+ {
19
+ "cidr_block": "0.0.0.0/0",
20
+ "nat_gateway_id": "nat-0123456789abcdef0"
21
+ }
22
+ ],
23
+ "tags": {
24
+ "Name": "northwind-private"
25
+ }
26
+ },
27
+ "after": {
28
+ "id": "rtb-0aa11bb22cc33dd44",
29
+ "route": [
30
+ {
31
+ "cidr_block": "0.0.0.0/0",
32
+ "nat_gateway_id": "nat-0123456789abcdef0"
33
+ },
34
+ {
35
+ "cidr_block": "10.99.0.0/16",
36
+ "vpc_peering_connection_id": "pcx-0fedcba9876543210"
37
+ }
38
+ ],
39
+ "tags": {
40
+ "Name": "northwind-private"
41
+ }
42
+ },
43
+ "after_unknown": {},
44
+ "before_sensitive": {},
45
+ "after_sensitive": {}
46
+ }
47
+ }
48
+ ],
49
+ "resource_changes": [
50
+ {
51
+ "address": "module.vpc.aws_subnet.private[\"c\"]",
52
+ "mode": "managed",
53
+ "type": "aws_subnet",
54
+ "name": "private",
55
+ "provider_name": "registry.terraform.io/hashicorp/aws",
56
+ "change": {
57
+ "actions": [
58
+ "create"
59
+ ],
60
+ "before": null,
61
+ "after": {
62
+ "availability_zone": "eu-west-1c",
63
+ "cidr_block": "10.20.12.0/24",
64
+ "map_public_ip_on_launch": false,
65
+ "tags": {
66
+ "Name": "northwind-private-c"
67
+ },
68
+ "vpc_id": "vpc-0123456789abcdef0"
69
+ },
70
+ "after_unknown": {},
71
+ "before_sensitive": {},
72
+ "after_sensitive": {}
73
+ },
74
+ "module_address": "module.vpc"
75
+ },
76
+ {
77
+ "address": "aws_iam_role_policy.ci",
78
+ "mode": "managed",
79
+ "type": "aws_iam_role_policy",
80
+ "name": "ci",
81
+ "provider_name": "registry.terraform.io/hashicorp/aws",
82
+ "change": {
83
+ "actions": [
84
+ "update"
85
+ ],
86
+ "before": {
87
+ "id": "northwind-ci:deploy",
88
+ "name": "deploy",
89
+ "role": "northwind-ci",
90
+ "policy": "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"ec2:Describe*\", \"Resource\": \"*\"}]}"
91
+ },
92
+ "after": {
93
+ "id": "northwind-ci:deploy",
94
+ "name": "deploy",
95
+ "role": "northwind-ci",
96
+ "policy": "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"*\", \"Resource\": \"*\"}]}"
97
+ },
98
+ "after_unknown": {},
99
+ "before_sensitive": {},
100
+ "after_sensitive": {}
101
+ }
102
+ },
103
+ {
104
+ "address": "module.vpc.aws_subnet.private[\"a\"]",
105
+ "mode": "managed",
106
+ "type": "aws_subnet",
107
+ "name": "private",
108
+ "provider_name": "registry.terraform.io/hashicorp/aws",
109
+ "change": {
110
+ "actions": [
111
+ "no-op"
112
+ ],
113
+ "before": {
114
+ "availability_zone": "eu-west-1a",
115
+ "cidr_block": "10.20.10.0/24"
116
+ },
117
+ "after": {
118
+ "availability_zone": "eu-west-1a",
119
+ "cidr_block": "10.20.10.0/24"
120
+ },
121
+ "after_unknown": {},
122
+ "before_sensitive": {},
123
+ "after_sensitive": {}
124
+ },
125
+ "module_address": "module.vpc"
126
+ }
127
+ ],
128
+ "output_changes": {},
129
+ "applyable": true,
130
+ "complete": true,
131
+ "errored": false,
132
+ "timestamp": "2026-09-30T10:12:00Z"
133
+ }
@@ -73,3 +73,4 @@ The working-backwards forcing function: write the launch press release *before*
73
73
  - ❌ **Launch-as-adoption.** "Ship to beta" as first success conflates the team's delivery with the customer's value. First success is something the *customer* does.
74
74
  - ❌ **Moat without mechanism.** Claiming defensibility without naming what makes it hard to copy — data advantage, network effect, workflow lock-in — is a wish wearing a strategy's clothes.
75
75
  - ❌ **All-good-news FAQs.** If the customer FAQ reads like the pricing page, the hard questions were dodged and the document proves nothing.
76
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prfaq",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Write an Amazon-style PR/FAQ — the launch press release for a product that doesn't exist yet, plus the customer FAQ and internal FAQ that force the hard questions before engineering starts. Use when the user wants a PRFAQ, a working-backwards document, a \"write the press release first\" exercise, or needs to align stakeholders on what a product must be before committing a team to build it.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -17,7 +17,7 @@ Runs the classic strategy frameworks the way a good strategist does and a bad de
17
17
  | Industry attractiveness / profit pressure: "should we enter", "why are margins thin", "can we defend" | **Porter's Five Forces** |
18
18
  | Macro environment: regulation, technology shifts, demographics affecting a multi-year bet | **PESTLE** |
19
19
 
20
- The user asked for a framework by name and it fits → run it. It doesn't fit → say so in one line and run the fitting framework instead — the quality bar treats a misfit framework as a category error, and a "SWOT" request that's really "should we enter this market" is Five Forces work; run the requested framework only if the user insists after the flag. Portfolio-allocation questions across many products (BCG-matrix territory) → name it, note it needs per-product market-share and growth data, and run it only if that data is supplied.
20
+ The user asked for a framework by name and it fits → run it. It doesn't fit → say so in one line and run the fitting framework instead — the quality bar treats a misfit framework as a category error, and a "SWOT" request that's really "should we enter this market" is Five Forces work; then give the framework they asked for as well, after it and shorter (a SWOT still arrives as TOWS). They asked for it by name, and a reply that withholds it reads as not listening. Portfolio-allocation questions across many products (BCG-matrix territory) → name it, note it needs per-product market-share and growth data, and run it only if that data is supplied.
21
21
 
22
22
  2. **Collect the evidence base before filling anything.** Name what is known `[data: …]`, reported `[reported by …]`, drawn from general market knowledge `[market: …]`, and assumed `[assumption]`. The `[market: …]` tag exists because on a short prompt most cells are filled from the model's own market knowledge — that's legitimate, but it must stay distinguishable from the user's facts and from guesses. Ask at most 2 questions, spent on the decision the analysis feeds ("what decision does this inform, and by when?") and the competitive set ("who do customers actually compare you to?"). No decision named → the analysis has no ranking criterion; get one before proceeding. Non-interactive run (no user to ask): derive the most plausible decision from the input, state it as `[assumption]` at the top, and rank against it; none derivable → emit `BLOCKED: need the decision this analysis feeds` rather than an unranked survey.
23
23
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strategy-analysis",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Run a strategy framework — SWOT/TOWS, Porter's Five Forces, or PESTLE — on a product, company, or market question, choosing the right framework for the question and forcing every cell to carry evidence and a so-what. Use when the user asks for a SWOT, a competitive/market analysis, \"should we enter this market\", \"what's our position against X\", or a macro-environment scan.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },
@@ -61,3 +61,5 @@ Answers "how will we know it worked?" *before* build, when the answer can still
61
61
  - ❌ **Post-hoc decision rules.** Deciding what the numbers must show *after* seeing them — the moment measurement becomes marketing.
62
62
  - ❌ **Ignoring the patience window.** Judging at day 7 what needs a 60-day cohort — novelty spikes and weekly cycles read as signal.
63
63
  - ❌ **Proxy laundering.** Using clicks as a proxy for value and then forgetting it's a proxy — label proxies as proxies, every time they're cited.
64
+ - ❌ **Showing the machinery.** The reply and the artifact are for the person who asked. Don't mention this skill, its files, templates, caps or internal terms, or that the run is non-interactive. Name another skill once, at the end, as a suggested next step, never inside the artifact.
65
+ - ❌ **A bare `BLOCKED` line.** Keep the `BLOCKED: need <X>` line, then write for a person: what is missing in plain words, what you will produce once you have it, and anything the request already lets you say.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "success-metrics",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Define how a feature's success will be measured before it's built — one primary metric with target, timeframe, and baseline; guardrail and counter-metrics; an instrumentation plan naming every event; and a pre-committed decision rule for what happens if the target is missed. Use when the user asks \"how do we know this worked\", needs KPIs or success criteria for a feature, or wants a measurement/instrumentation plan before launch.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": { "npm": [], "pip": [] },