@deployanyway/ship-it-meter 0.1.1 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — 2026-10-08
4
+
5
+ - Preflight, with a parachute: `preflight(input)` returns the same score, verdict and reasons as `shipIt`, plus actionable `actions`. CLI `--checklist` includes them in text or JSON output. It uses only supplied evidence and is not a deployment guarantee.
6
+ - Add npm and CI badges to the published README.
7
+
3
8
  ## 0.1.1 — 2026-10-08
4
9
 
5
10
  - Correct npm installation and npx documentation after the initial publication.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # ship-it-meter
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/%40deployanyway%2Fship-it-meter)](https://www.npmjs.com/package/@deployanyway/ship-it-meter)
4
+ [![CI](https://github.com/DeployAnyway/ship-it-meter/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/DeployAnyway/ship-it-meter/actions/workflows/ci.yml)
5
+
3
6
  Explainable deployment readiness scoring for tests, coverage, and builds. Turns questionable confidence into a number.
4
7
 
5
8
  ```text
@@ -150,3 +153,17 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).
150
153
  - [doggo-log](https://github.com/DeployAnyway/doggo-log)
151
154
  - [ship-it-meter](https://github.com/DeployAnyway/ship-it-meter)
152
155
  - [bro-say](https://github.com/DeployAnyway/bro-say)
156
+
157
+ ## Preflight, with a parachute
158
+
159
+ `preflight(input)` returns the same score, verdict and reasons as `shipIt`, plus actionable `actions`. CLI `--checklist` includes them in text or JSON output. It uses only supplied evidence and is not a deployment guarantee.
160
+
161
+ ```sh
162
+ npx @deployanyway/ship-it-meter --tests 125 --coverage 82 --build pass --day friday --checklist
163
+ ```
164
+
165
+ API (import the named functions from this package):
166
+
167
+ ```js
168
+ preflight({ tests: 125, coverage: 82, build: true, day: "friday" });
169
+ ```
package/bin/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { parseArgs } from "node:util";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { URL } from "node:url";
5
- import { shipIt } from "../src/index.js";
5
+ import { shipIt, preflight } from "../src/index.js";
6
6
 
7
7
  try {
8
8
  const { values } = parseArgs({
@@ -10,6 +10,7 @@ try {
10
10
  help: { type: "boolean", short: "h" },
11
11
  version: { type: "boolean", short: "v" },
12
12
  json: { type: "boolean" },
13
+ checklist: { type: "boolean" },
13
14
  tests: { type: "string" },
14
15
  failing: { type: "string" },
15
16
  coverage: { type: "string" },
@@ -23,7 +24,7 @@ try {
23
24
  });
24
25
  if (values.help) {
25
26
  console.log(
26
- "Usage: ship-it-meter [options]\n\nOptions:\n --tests number Total tests\n --failing number Failing tests\n --coverage number Coverage percent\n --build pass|fail Build result\n --critical number Open critical issues\n --lint number Lint failures\n --dirty Uncommitted changes\n --branch name Branch name\n --day weekday Full weekday name\n --json Structured output\n -h, --help Help\n -v, --version Version\n\nMissing test, coverage, and build evidence reduces readiness.\nExit codes: 0 scored successfully; 2 invalid arguments.",
27
+ "Usage: ship-it-meter [options]\n\nOptions:\n --tests number Total tests\n --failing number Failing tests\n --coverage number Coverage percent\n --build pass|fail Build result\n --critical number Open critical issues\n --lint number Lint failures\n --dirty Uncommitted changes\n --branch name Branch name\n --day weekday Full weekday name\n --checklist Actionable, mildly concerned preflight\n --json Structured output\n -h, --help Help\n -v, --version Version\n\nMissing test, coverage, and build evidence reduces readiness.\nExit codes: 0 scored successfully; 2 invalid arguments.",
27
28
  );
28
29
  } else if (values.version) {
29
30
  console.log(
@@ -54,11 +55,11 @@ try {
54
55
  for (const key of ["day", "branch"])
55
56
  if (values[key] !== undefined) input[key] = values[key];
56
57
  if (values.dirty) input.uncommittedChanges = true;
57
- const result = shipIt(input);
58
+ const result = values.checklist ? preflight(input) : shipIt(input);
58
59
  console.log(
59
60
  values.json
60
61
  ? JSON.stringify(result, null, 2)
61
- : `${result.score}/100 — ${result.verdict}\n${result.reasons.map((reason) => `- ${reason}`).join("\n")}`,
62
+ : `${result.score}/100 — ${result.verdict}\n${result.reasons.map((reason) => `- ${reason}`).join("\n")}${result.actions ? "\n\nBefore you ship:\n" + result.actions.map((action) => `[ ] ${action}`).join("\n") : ""}`,
62
63
  );
63
64
  }
64
65
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deployanyway/ship-it-meter",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Explainable deployment readiness scoring for tests, coverage, and builds. Turns questionable confidence into a number.",
5
5
  "type": "module",
6
6
  "exports": "./src/index.js",
package/src/index.js CHANGED
@@ -123,3 +123,38 @@ export function shipIt(input = {}) {
123
123
  : "Suspiciously Ready";
124
124
  return { score, verdict, reasons };
125
125
  }
126
+
127
+ /** Return actionable preflight tasks alongside the existing score. */
128
+ export function preflight(input = {}) {
129
+ const result = shipIt(input);
130
+ const actions = [];
131
+ if (input.build !== true)
132
+ actions.push("Get a passing build. Confidence is not a build artifact.");
133
+ if (!input.tests)
134
+ actions.push("Run tests and report the count. Vibes are not assertions.");
135
+ if (input.failingTests)
136
+ actions.push("Fix failing tests. Red is not a festive deployment theme.");
137
+ if (input.coverage === undefined || input.coverage < 80)
138
+ actions.push(
139
+ "Measure coverage and review untested paths. The bugs enjoy privacy.",
140
+ );
141
+ if (input.criticalIssues)
142
+ actions.push(
143
+ "Resolve critical issues. The incident channel deserves a quiet afternoon.",
144
+ );
145
+ if (input.lintFailures)
146
+ actions.push("Fix lint failures. Let the semicolons retire in peace.");
147
+ if (input.uncommittedChanges)
148
+ actions.push(
149
+ "Commit or stash local changes. Your laptop is not the release archive.",
150
+ );
151
+ if (input.day?.trim().toLowerCase() === "friday")
152
+ actions.push(
153
+ "Confirm rollback and on-call cover. The weekend has other plans.",
154
+ );
155
+ if (!actions.length)
156
+ actions.push(
157
+ "Confirm monitoring and rollback. Even excellent evidence needs a parachute.",
158
+ );
159
+ return { ...result, actions };
160
+ }