halfcycle 0.4.0 → 0.4.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.
@@ -32,17 +32,17 @@
32
32
  * this id is *not*, and where the right one lives; it cannot answer the question
33
33
  * directly.
34
34
  *
35
- * **REWORDING THIS STRING REWRITES A FILE IN EVERY INSTALLED TREE AT ONCE, and
36
- * that is not what it looks like.** The identity writer reads `projectId`,
37
- * `rootCommit` and `remote` back off disk when the file is already there, so those
38
- * three survive a re-install — but it takes THIS field from this constant on every
39
- * run, never from disk. So a re-install after any edit here finds a file whose
40
- * bytes differ, replaces it, and reports a write; the developer's identity is
41
- * preserved and the file is not. The change reads like copy-editing and lands
42
- * everywhere the installer has ever run. If you must change it, change it knowing
43
- * that, and say so in the commit.
35
+ * **REWORDING THIS STRING SPLITS INSTALLED TREES IN TWO, and that is not what it
36
+ * looks like.** It is written into every NEW `project.json`, and an existing file is
37
+ * never rewritten (`writeProjectIdentity`; onboarding fix wave T-05). So after an
38
+ * edit here every tree set up earlier keeps the old text for good and every later
39
+ * one carries the new, with nothing on disk saying which is current. The change
40
+ * reads like copy-editing. If you must change it, change it knowing that, and say so
41
+ * in the commit.
44
42
  */
45
43
  export declare const PROJECT_IDENTITY_NOTE: string;
44
+ /** Where the committed identity lives, relative to the folder being installed into. */
45
+ export declare const PROJECT_IDENTITY_REL = ".halfcycle/project.json";
46
46
  /** The committed project identity: minted id plus the repo's root fingerprint. */
47
47
  export interface ProjectIdentity {
48
48
  /** A minted, stable project id (uuid). Assigned once, at first install. */
@@ -58,10 +58,9 @@ export interface ProjectIdentity {
58
58
  /**
59
59
  * A fixed disambiguation string, always `PROJECT_IDENTITY_NOTE` — see there.
60
60
  * Present so a session reading this file directly (not through a tool
61
- * description) sees the warning too. Reconciled on every install: if an
62
- * install written before this field existed re-installs, the note is
63
- * backfilled (`writeProjectIdentity` rewrites iff the serialized bytes
64
- * differ) — `projectId`/`rootCommit`/`remote` are never touched by that.
61
+ * description) sees the warning too. Written only when the file is created: a
62
+ * file from before this field existed keeps its bytes and never gains it
63
+ * (`writeProjectIdentity` never rewrites an existing `project.json`).
65
64
  */
66
65
  note: string;
67
66
  }
@@ -69,6 +68,19 @@ export interface ProjectIdentity {
69
68
  export declare function gitEnvForNamedRepo(): NodeJS.ProcessEnv;
70
69
  /** Read the repository's root commit hash (the first commit, reachable from HEAD). */
71
70
  export declare function readRootCommit(targetRepoRoot: string): string | null;
71
+ /**
72
+ * Is `targetRepoRoot` inside a git working tree? Decides whether the install's
73
+ * closing output tells the person which files to commit (`project-identity-reuse`
74
+ * AC8) — outside a repository there is nothing to commit them to.
75
+ */
76
+ export declare function isGitWorkTree(targetRepoRoot: string): boolean;
77
+ /**
78
+ * Can this machine run `git` at all? Asked only once `isGitWorkTree` has said no,
79
+ * because `git()` above answers `null` for "not a repository" and for "no git" alike —
80
+ * and the advice differs: `git init` cannot help someone who has no Git (the macOS and
81
+ * Linux walks' B5, onboarding fix wave FW-1).
82
+ */
83
+ export declare function gitIsInstalled(): boolean;
72
84
  /** Read the `origin` remote URL. */
73
85
  export declare function readRemote(targetRepoRoot: string): string | null;
74
86
  /**
@@ -132,4 +144,36 @@ export declare function mintOrReadIdentity(targetRepoRoot: string): {
132
144
  identity: ProjectIdentity;
133
145
  minted: boolean;
134
146
  };
147
+ /**
148
+ * The ONE serializer for `project.json`, called from exactly one place:
149
+ * `createProjectIdentityFile` below, to produce the bytes for a freshly minted
150
+ * identity. `install()`'s `writeProjectIdentity` no longer calls this function
151
+ * itself — until the onboarding fix wave (T-05, from review R-03) it did, to
152
+ * reconcile an existing file's bytes against what it would have written and
153
+ * rewrite one that differed. That reconciliation is retired: `writeProjectIdentity`
154
+ * now only calls `createProjectIdentityFile`, which skips a file that is already
155
+ * there, whatever its bytes (`project-identity-reuse` AC1). A file the pre-write
156
+ * created is therefore read back as `skipped`, never compared or rewritten.
157
+ */
158
+ export declare function serializeProjectIdentity(identity: ProjectIdentity): string;
159
+ /**
160
+ * Create `.halfcycle/project.json` if it is absent, and never replace it
161
+ * (`project-identity-reuse` AC1, #1555 decision D1: the folder's id decides the
162
+ * project, so the id must exist before the installer asks for the project).
163
+ *
164
+ * A fresh identity is written to a temporary file beside the target and hard-linked
165
+ * into place. `linkSync` fails with `EEXIST` when the target is already there, which
166
+ * is the whole of the "never replace" rule: two installs started at the same moment
167
+ * both try, exactly one link lands, and both then read the one file that exists. A
168
+ * committed `project.json` from someone else is never rewritten. There is no
169
+ * "does it exist?" branch before the write, on purpose: the temporary write is also
170
+ * the check that this folder can be written to, so it runs on every call and a
171
+ * re-run in a folder that has since become read-only is refused before any request,
172
+ * not after a project was created. The temporary file is always removed.
173
+ *
174
+ * Throws whatever the filesystem throws for a folder it cannot write to; the caller
175
+ * (`pre-create-checks.ts`) turns that into a sentence. Reading and judging the file
176
+ * that ends up in place is the caller's too — this module imports only builtins.
177
+ */
178
+ export declare function createProjectIdentityFile(targetRepoRoot: string): void;
135
179
  //# sourceMappingURL=identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,qBAAqB,QAGF,CAAC;AAEjC,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD,gFAAgF;AAChF,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,UAAU,CAItD;AAqBD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMpE;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAyBvG;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAmBzG"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,qBAAqB,QAGF,CAAC;AAEjC,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD,gFAAgF;AAChF,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,UAAU,CAItD;AAqBD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMpE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAyBvG;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAazG;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAiBtE"}