@produtype/core 0.99.0 → 1.1.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/README.md CHANGED
@@ -21,20 +21,33 @@ ProdKit inspects a target project and detects:
21
21
  - GDPR/privacy signals
22
22
  - Security hardening signals
23
23
  - Upload exposure signals
24
- - Billing/Stripe signals
24
+ - Billing signals: payment processors declared in any manifest this reads
25
25
  - Observability/logging signals
26
26
  - Background jobs/queue signals
27
27
  - Deployment readiness signals
28
28
 
29
29
  Then it builds a structured production-readiness report with:
30
30
 
31
- - Overall score (0-100)
32
- - Maturity level (`prototype`, `early`, `partial`, `production_ready`)
31
+ - Overall score (0-100), or `null` where too little of the repository could be read
32
+ to characterise it
33
+ - Maturity level (`inconclusive`, `prototype`, `early`, `partial`, `production_ready`)
33
34
  - Findings grouped by category
34
35
  - Critical issues and warnings
35
36
  - Passed checks
36
37
  - Suggested next steps
37
- - Technical evidence for each finding
38
+ - Technical evidence for each finding — a file and a line you can open, not a summary
39
+
40
+ Two things the report says about its own reading, because a finding is only worth what
41
+ the reading behind it is:
42
+
43
+ - **How deeply each language was read.** A syntax tree answered the question, or a
44
+ keyword search did, or the language was not read at all — and the report names which,
45
+ per language. The optional `typescript` peer dependency decides whether JavaScript and
46
+ TypeScript are parsed; without it they are searched as text, and the report says so
47
+ rather than claiming otherwise.
48
+ - **Which questions could not be asked.** A check whose answer depends on a reader that
49
+ could not run comes back `unknown`, never `passed` and never `missing`. Blindness can
50
+ turn a verdict into no verdict; it is not allowed to turn one into its opposite.
38
51
 
39
52
  From the report, ProdKit can also build a deterministic remediation plan with phases, task priorities, effort estimates, and test suggestions.
40
53
 
@@ -145,7 +158,11 @@ Profile warning:
145
158
 
146
159
  Inconclusive assessments:
147
160
 
148
- - If no stack signals and no package manifests are detected, the report is marked **inconclusive** and the score is capped at 39 (`prototype`). An unrecognized project is never scored as production ready.
161
+ - Where nothing identifies the repository, where too few checks reach a verdict, or
162
+ where most of it is written in a language this cannot read, the report is marked
163
+ **inconclusive** and there is no score at all: `overallScore` is `null` and the
164
+ maturity level is `inconclusive`. It used to cap the score at 39 instead, which was
165
+ a number standing where an answer was missing.
149
166
 
150
167
  ## Examples
151
168
 
@@ -220,8 +237,12 @@ its own.
220
237
  ## Current limitations
221
238
 
222
239
  - Deterministic heuristics only: the AI layer is a separate package (see above)
223
- - Signal-based stack coverage across common Node/Python/JS frameworks + fallback
224
- - Signal-based detection can produce false positives/negatives
240
+ - JavaScript and TypeScript are parsed when the optional `typescript` peer dependency is
241
+ installed; every other language is read as text, matched against what its frameworks
242
+ and its standard library define. The report states which of the two it did.
243
+ - Signal-based detection can produce false positives and false negatives. Where a
244
+ reading rests on something this could not check, the answer is `unknown` rather than a
245
+ guess.
225
246
  - Plan output is deterministic and read-only only
226
247
  - No cloud dashboard or UI: this package is the CLI and the library
227
248
 
@@ -267,6 +267,12 @@ async function detectPackaging(ctx) {
267
267
  jvmPublication = true;
268
268
  }
269
269
  }
270
+ const tauriConfigs = all.filter((file) => /(^|\/)tauri\.conf\.json$/.test(file));
271
+ const desktopBundle = [
272
+ ...(0, detectContext_1.hasAnyDep)(ctx, ['electron', 'electron-builder', '@tauri-apps/api', '@tauri-apps/cli'])
273
+ .map((dep) => ({ type: 'dependency', value: dep })),
274
+ ...tauriConfigs.slice(0, 2).map((file) => ({ type: 'file', value: file, file })),
275
+ ];
270
276
  const entrypointCount = nodeEntrypoints.length
271
277
  + (pythonEntrypoints ? 1 : 0)
272
278
  + (dotnetPackageId ? 1 : 0)
@@ -326,6 +332,24 @@ async function detectPackaging(ctx) {
326
332
  : frontendFiles.slice(0, 5).map((file) => ({ type: 'file', value: file, file })),
327
333
  details: { generators: docsGenerators, frontendFiles: frontendFiles.length, allUnderDocs: frontendAllInDocs },
328
334
  },
335
+ {
336
+ /**
337
+ * An application that ships as a desktop bundle, not as a page.
338
+ *
339
+ * `electron` in the manifest and a `tauri.conf.json` in the tree are the two
340
+ * ways a project says its product is installed rather than visited. Both are
341
+ * the toolchain's own names: electron-builder reads the first, the Tauri CLI
342
+ * reads the second.
343
+ *
344
+ * Recorded here so the profile can stop asking a desktop application how it
345
+ * caches assets over HTTP — the question a Unity game stopped being asked in
346
+ * 0.84.0, for the same reason. marktext, an Electron editor, was told at `high`
347
+ * that it has no asset-delivery policy.
348
+ */
349
+ key: 'packaging.desktopBundle',
350
+ present: desktopBundle.length > 0,
351
+ evidence: desktopBundle,
352
+ },
329
353
  {
330
354
  key: 'docs.readme',
331
355
  present: readmeFiles.length > 0,
@@ -227,6 +227,17 @@ function deriveStatus(analysis, capability) {
227
227
  case 'app.asset-delivery': {
228
228
  if (detector(analysis, 'game.engine')?.details?.nativeEngine === true)
229
229
  return 'not_applicable';
230
+ /**
231
+ * And the same for an application that is installed rather than visited.
232
+ *
233
+ * marktext ships as an Electron bundle and yaak as a Tauri one; their assets are
234
+ * inside the download, and `Cache-Control` has nobody to talk to. This is the
235
+ * native-game case again, arrived at from the other direction — the first time
236
+ * from a `ProjectVersion.txt`, this time from `electron` in a manifest and a
237
+ * `tauri.conf.json` in the tree.
238
+ */
239
+ if (detector(analysis, 'packaging.desktopBundle')?.present === true)
240
+ return 'not_applicable';
230
241
  return detector(analysis, 'app.assetDelivery')?.present ? 'present' : 'missing';
231
242
  }
232
243
  case 'jobs.background': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.99.0",
3
+ "version": "1.1.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {