staysfixed 0.7.0 → 0.7.1

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
@@ -4,6 +4,21 @@ All notable changes to this project are recorded here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the version
5
5
  numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.7.1] — 2026-08-30
8
+
9
+ Found by installing 0.7.0 from npm into an empty folder and running it the way a
10
+ stranger would, which is the only way this was ever going to be found.
11
+
12
+ ### Fixed
13
+
14
+ - **`init` asked for a build step on a script that runs straight from source.** A
15
+ plain Node command-line tool is recorded as "not built", because there is
16
+ nothing to build — and that was read as "it has not been built yet". So a fresh
17
+ install told its owner to go and name the command that builds a file sitting
18
+ right there, in the same breath as offering to run it. Being sent shopping for
19
+ nothing is the fastest way to make somebody stop reading the page, and this
20
+ project's README promises it never happens. A test holds it shut.
21
+
7
22
  ## [0.7.0] — 2026-08-30
8
23
 
9
24
  The release where the front door was found to be locked.
@@ -81,6 +96,11 @@ printed, which is the only way this kind of mistake is ever found.
81
96
  - **It reported Docker as present because the command was on the path**, on a
82
97
  machine where Docker Desktop was shut and nothing it promises would have worked.
83
98
  It asks the engine for its version now.
99
+ - **It said an iPhone app "cannot be done here at all" on a Mac with Xcode and
100
+ three simulator runtimes on it.** The real reason was that this repository has
101
+ no iPhone app in it, which is not a limit of the machine. Those two reasons are
102
+ two different sentences now, and the object carries
103
+ `surfaces[].notInThisProject` so an agent can tell them apart too.
84
104
  - No probe in `doctor` uses a shell variable or a loop any more. One machine in
85
105
  this config reaches Windows through an OpenSSH server that hands the command down
86
106
  through a second shell, and every `$p` is expanded to nothing before the shell
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "staysfixed",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Prove that what already worked still works after an agent changed the code. Picture checks, guards for fixed bugs, a pre-release walkthrough, and known-good markers — as a CLI and as an MCP server.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/v2/init.js CHANGED
@@ -432,7 +432,17 @@ function productNeeds(product, project) {
432
432
  // A command-line program that has to be built before it can be run. This is what a product
433
433
  // nothing in package.json names looks like on a fresh clone: the source is there, the
434
434
  // program is real, and the file that would be run does not exist yet.
435
- if (product.kind === 'cli' && !product.built.found) {
435
+ //
436
+ // `built.found === false` is NOT that on its own, and reading it as though it were sent a
437
+ // plain Node command-line tool's owner shopping for a build step it does not have. A
438
+ // script that runs straight from source is recorded as `found: false, how: "nothing to
439
+ // build — it runs from source"`, and this file used to ask a person to "name the command
440
+ // that builds it" about a file that was sitting right there and that the very same run
441
+ // had already worked out how to run. Two signals rule it out, and either is enough: the
442
+ // detector saying there is nothing to build, and a command already worked out for it.
443
+ const nothingToBuild = /nothing to build/i.test(String(product.built.how ?? ''));
444
+ const alreadyRunnable = Array.isArray(suggest.commands) && suggest.commands.length > 0;
445
+ if (product.kind === 'cli' && !product.built.found && !nothingToBuild && !alreadyRunnable) {
436
446
  const build = typeof suggest.buildWith === 'string' ? String(suggest.buildWith) : null;
437
447
  needs.push({
438
448
  what: `${product.name}, built`,