halfcycle 0.3.26 → 0.3.28
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/.claude-plugin/plugin.json +1 -1
- package/README.md +8 -8
- package/bin/bin.bundle.mjs +122 -55
- package/dist/bin.d.ts +11 -5
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +1397 -359
- package/dist/bin.js.map +3 -3
- package/dist/cli-contract.d.ts +1 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/create-engagement.d.ts +5 -5
- package/dist/device-signin.d.ts +17 -7
- package/dist/device-signin.d.ts.map +1 -1
- package/dist/engagement-credential.d.ts +50 -4
- package/dist/engagement-credential.d.ts.map +1 -1
- package/dist/index.js +689 -165
- package/dist/index.js.map +3 -3
- package/dist/install-manifest.d.ts +169 -0
- package/dist/install-manifest.d.ts.map +1 -0
- package/dist/install.d.ts +146 -7
- package/dist/install.d.ts.map +1 -1
- package/dist/loopback-signin.d.ts +25 -5
- package/dist/loopback-signin.d.ts.map +1 -1
- package/dist/merge-settings.d.ts +12 -0
- package/dist/merge-settings.d.ts.map +1 -1
- package/dist/open-phase.d.ts.map +1 -1
- package/dist/own-engagement.d.ts.map +1 -1
- package/dist/scan.d.ts +7 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/uninstall.d.ts +96 -0
- package/dist/uninstall.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/ci-bind.d.ts +0 -116
- package/dist/ci-bind.d.ts.map +0 -1
package/dist/install.d.ts
CHANGED
|
@@ -237,6 +237,53 @@ export declare const ZONE_B_DIR = ".workbench";
|
|
|
237
237
|
* depending on build mode — see the comment above `findBundleRoot`).
|
|
238
238
|
*/
|
|
239
239
|
export declare const BUNDLE_ROOT: string;
|
|
240
|
+
/** The committed pin. */
|
|
241
|
+
export declare const BUNDLE_PIN_REL = ".halfcycle/bundle.json";
|
|
242
|
+
/** The three files the installer merges into rather than owns. */
|
|
243
|
+
export declare const SETTINGS_REL = ".claude/settings.json";
|
|
244
|
+
export declare const GITIGNORE_REL = ".gitignore";
|
|
245
|
+
export interface ClosedWriteSet {
|
|
246
|
+
/** Files the installer writes whole. */
|
|
247
|
+
readonly files: ReadonlySet<string>;
|
|
248
|
+
/** Files the installer merges its entries into. */
|
|
249
|
+
readonly merged: ReadonlySet<string>;
|
|
250
|
+
/** Every directory any of the above can create. */
|
|
251
|
+
readonly dirs: ReadonlySet<string>;
|
|
252
|
+
/** The directories owned by path: `.halfcycle/` and those under it. */
|
|
253
|
+
readonly ownedDirs: ReadonlySet<string>;
|
|
254
|
+
/** Every hook command string the installer generates into `.claude/settings.json`. */
|
|
255
|
+
readonly hookCommands: ReadonlySet<string>;
|
|
256
|
+
/** The SHA-256 of every deny rule the installer adds. */
|
|
257
|
+
readonly denyRuleSha256: ReadonlySet<string>;
|
|
258
|
+
/** Every line the installer appends to `.gitignore`. */
|
|
259
|
+
readonly gitignoreLines: ReadonlySet<string>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* THE CLOSED WRITE SET, derived from the same constants the installer writes with
|
|
263
|
+
* (`client-uninstall.md`, INV-023's two-key removal).
|
|
264
|
+
*
|
|
265
|
+
* THE SECOND KEY REACHES INSIDE THE MERGED FILES TOO (R-21, F1). A hook command, a
|
|
266
|
+
* deny rule or a `.gitignore` line is taken out only if the manifest records it AND
|
|
267
|
+
* it is one the installer generates: the commands `generateSettingsJson` emits, the
|
|
268
|
+
* hashes of `DENY_PATTERNS`, and the `.gitignore` header plus
|
|
269
|
+
* `REQUIRED_GITIGNORE_ENTRIES` plus the `.env.local` line older versions wrote.
|
|
270
|
+
* Without it a crafted manifest could name a developer's own hook, deny rule or
|
|
271
|
+
* ignore line and have uninstall delete it.
|
|
272
|
+
*
|
|
273
|
+
* A path in the install manifest never decides a removal on its own: uninstall
|
|
274
|
+
* removes or edits a path only if the manifest lists it AND it is a member here. The
|
|
275
|
+
* manifest is a committed file anyone who can land a commit can edit; this set is
|
|
276
|
+
* code, shipped in the package. So a manifest naming `src/index.ts` names a path
|
|
277
|
+
* that is not removed, whatever else it says.
|
|
278
|
+
*
|
|
279
|
+
* DERIVED, NOT LISTED. The command stubs come from `plugin.json`'s `commands[]`, the
|
|
280
|
+
* same array `copyManifestCommands` copies from; the hook scripts and the headers
|
|
281
|
+
* helper from `OWNED_GENERATED_HEADERS`, the table the owned-generated writes key
|
|
282
|
+
* on; the rest from the named constants their writers use. The directories are the
|
|
283
|
+
* ancestors of every member, so a new file under a new directory brings its
|
|
284
|
+
* directory with it. The writer and the remover therefore cannot hold two lists.
|
|
285
|
+
*/
|
|
286
|
+
export declare function closedWriteSet(): ClosedWriteSet;
|
|
240
287
|
/**
|
|
241
288
|
* The write outcome for one target path under the copy set.
|
|
242
289
|
* - `written` — the file did not exist and was created.
|
|
@@ -333,6 +380,87 @@ export declare const WRITE_CAPABLE_TOOLS: readonly string[];
|
|
|
333
380
|
* across lines, this hook has one line of context budget to spend per prompt.
|
|
334
381
|
*/
|
|
335
382
|
export declare const USER_PROMPT_REMINDER_SENTENCE: string;
|
|
383
|
+
/** What `removeLegacyCiStanza` found on disk and did about it. */
|
|
384
|
+
export type CiStanzaRemoval = 'removed' | 'kept-foreign' | 'kept-uncommitted' | 'absent' | 'failed';
|
|
385
|
+
/**
|
|
386
|
+
* Delete `.halfcycle/ci-stanza.yml` when, and only when, BOTH hold (R-25 fix
|
|
387
|
+
* wave, F1): its opening line hashes to exactly one generation this installer
|
|
388
|
+
* ever shipped, AND the file is a clean, committed copy in git. Nothing writes
|
|
389
|
+
* this path any more; this only retires one an earlier version left on an
|
|
390
|
+
* already-installed tree.
|
|
391
|
+
*
|
|
392
|
+
* **Either check failing means KEEP, with a message — never delete.** A header
|
|
393
|
+
* hash matching none of `CI_STANZA_KNOWN_HEADER_HASHES` might be a developer's
|
|
394
|
+
* own file at this name, or a generation of ours this enumeration has not been
|
|
395
|
+
* kept in step with. A header that matches but a file that is uncommitted, or
|
|
396
|
+
* committed with local edits, might be a hand-edited stanza whose header line a
|
|
397
|
+
* developer left untouched while changing everything below it — the exact
|
|
398
|
+
* defect this rule now refuses, walked before this fix landed: a truncated
|
|
399
|
+
* prefix matched that file and deleted it. Either way, deleting on uncertainty
|
|
400
|
+
* is the wrong side of it. This is the same posture criterion 5 established for
|
|
401
|
+
* the generated hook scripts — evidence before disturbing a file this installer
|
|
402
|
+
* did not just write — applied to a delete instead of an overwrite.
|
|
403
|
+
*
|
|
404
|
+
* BEST-EFFORT, mirroring `migrateLegacyEnvLocal`: a read or unlink failure is
|
|
405
|
+
* reported, never thrown. Cleaning up a file this task retires must not fail an
|
|
406
|
+
* otherwise-successful install.
|
|
407
|
+
*/
|
|
408
|
+
export declare function removeLegacyCiStanza(targetRepo: string): CiStanzaRemoval;
|
|
409
|
+
/**
|
|
410
|
+
* **THE INSTALLER WRITES NO `.env.example`, AND THIS IS WHERE THAT GENERATOR WAS.**
|
|
411
|
+
*
|
|
412
|
+
* It survived the removal of the four common addresses earlier the same day, still
|
|
413
|
+
* declaring three names — the engagement's token, its id, and the same credential
|
|
414
|
+
* under the name every other surface reads. The operator then read the file it
|
|
415
|
+
* produced and asked whether the remaining three needed to be there at all. They did
|
|
416
|
+
* not, and the block was **a second home**:
|
|
417
|
+
*
|
|
418
|
+
* - The token and the engagement id were declared in the generated CI stanza,
|
|
419
|
+
* **at the point they were used**, with their own correct explanation. The
|
|
420
|
+
* scaffold repeated that for a job the stanza already owned. *(Overtaken
|
|
421
|
+
* 2026-09-16, T-15: the stanza declared neither by then — the CI job
|
|
422
|
+
* authenticated with an identity token and no stored secret. Overtaken again
|
|
423
|
+
* at T-25: the stanza itself is gone, CI setup being project scope rather than
|
|
424
|
+
* a product requirement, so there is no generated file left for either name to
|
|
425
|
+
* have a home in.)*
|
|
426
|
+
* - `HALFCYCLE_TOKEN` is not in the stanza at all. It is the escape hatch for
|
|
427
|
+
* running as a specific identity — ours, not something a client sets — which is
|
|
428
|
+
* the same category as the control origin, and the same reason that one went.
|
|
429
|
+
* - **The file's own text was the argument against it.** It spent twenty lines
|
|
430
|
+
* explaining that you must not do the thing a `.env.example` exists for. The
|
|
431
|
+
* convention of that filename is *copy this and fill it in*, and no comment
|
|
432
|
+
* outranks a convention.
|
|
433
|
+
*
|
|
434
|
+
* So the decision is not "declare fewer names" but "declare none, and place no such
|
|
435
|
+
* file": one fewer file in someone else's repository, and each of these facts keeps
|
|
436
|
+
* exactly one home. The address paragraph this file used to carry did not die with
|
|
437
|
+
* it — it moved into the CI stanza's comment block, where a reader looking for
|
|
438
|
+
* something to configure will actually meet it.
|
|
439
|
+
*
|
|
440
|
+
* **AN EXISTING `.env.example` IS NOT TOUCHED, and that is a decision rather than an
|
|
441
|
+
* oversight.** A tree an older install wrote still carries the block it appended; a
|
|
442
|
+
* re-install neither strips nor deletes it. The alternative is a pass with DELETE
|
|
443
|
+
* authority over a file the developer owns, identifying our old block by a header
|
|
444
|
+
* string that has itself changed twice — guesswork, on a population that is close to
|
|
445
|
+
* empty, since the CLI reaches a developer only on a republish. The credential
|
|
446
|
+
* migration that does have delete authority earned it by operating on keys it wrote
|
|
447
|
+
* itself in a file this product created; neither is true here. The stale block names
|
|
448
|
+
* three variables that are genuinely the client's and instructs nobody to set an
|
|
449
|
+
* address, so leaving it is inert.
|
|
450
|
+
*
|
|
451
|
+
* **WHAT MUST NOT MOVE WITH IT.** `ENGAGEMENT_ENV_KEYS` and `CREDENTIAL_REQUIRED_KEYS`
|
|
452
|
+
* are untouched: every name is still WRITTEN into the machine-level credential store.
|
|
453
|
+
* Declaring and writing were decoupled when the addresses came out, and dropping a
|
|
454
|
+
* key from the store makes every already-installed repository read as credential-less
|
|
455
|
+
* on its next run and silently join a fresh credential.
|
|
456
|
+
*/
|
|
457
|
+
/** The project-scoped MCP registration file — `.mcp.json` at the repo root, the
|
|
458
|
+
* Claude Code convention. Root-level, so it is a distinct allowlist entry. */
|
|
459
|
+
export declare const MCP_REGISTRATION_REL = ".mcp.json";
|
|
460
|
+
/** The key the Halfcycle server is registered under inside `.mcp.json`'s
|
|
461
|
+
* `mcpServers` — one home, because two generated shell scripts now look for it and
|
|
462
|
+
* a literal typed twice is a literal that can disagree with itself. */
|
|
463
|
+
export declare const MCP_SERVER_KEY = "halfcycle";
|
|
336
464
|
/**
|
|
337
465
|
* THE ONE HOME of *which generated files this installer claims as its own, and by
|
|
338
466
|
* what evidence* (#1103). Every entry is a client-tree path this package
|
|
@@ -360,10 +488,12 @@ export declare const USER_PROMPT_REMINDER_SENTENCE: string;
|
|
|
360
488
|
* change a marker. `test/install-stop-hook.test.ts` DID declare its own copy and
|
|
361
489
|
* now imports this table instead.
|
|
362
490
|
*
|
|
363
|
-
* `.halfcycle/ci-stanza.yml` is deliberately ABSENT
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
491
|
+
* `.halfcycle/ci-stanza.yml` is deliberately ABSENT — it was never a member of
|
|
492
|
+
* this table even while it was generated, because its opening line took four
|
|
493
|
+
* distinct forms and no prefix long enough to be evidence covered every
|
|
494
|
+
* generation (`#1112`). T-25 removed the generator itself; the four forms' hashes
|
|
495
|
+
* now live in `CI_STANZA_KNOWN_HEADER_HASHES`, evidence for a REMOVAL rather than
|
|
496
|
+
* a write.
|
|
367
497
|
*/
|
|
368
498
|
export declare const OWNED_GENERATED_HEADERS: {
|
|
369
499
|
readonly '.claude/hooks/guard-runner.sh': "# Governance hook wrapper — generated by";
|
|
@@ -372,6 +502,12 @@ export declare const OWNED_GENERATED_HEADERS: {
|
|
|
372
502
|
readonly '.claude/hooks/session-start-marker.sh': "# Session-start marker — generated by";
|
|
373
503
|
readonly '.halfcycle/mcp-headers.sh': "# Halfcycle MCP connection headers — generated by";
|
|
374
504
|
};
|
|
505
|
+
/**
|
|
506
|
+
* The header line every `.gitignore` block this installer appends opens with. One
|
|
507
|
+
* form in every published version (`client-uninstall.md`, *Grounded claims*), which
|
|
508
|
+
* is what lets a first-manifest run claim the blocks an older version appended.
|
|
509
|
+
*/
|
|
510
|
+
export declare const GITIGNORE_HEADER = "# Halfcycle \u2014 machine-local secrets/state and Zone-B (never push to client remote)";
|
|
375
511
|
/**
|
|
376
512
|
* Read the pinned bundle.json from a target repo and compare its version
|
|
377
513
|
* against the current bundle version. Returns the installed pin if present.
|
|
@@ -491,15 +627,18 @@ export declare function checkDrift(targetRepoRoot: string): {
|
|
|
491
627
|
* 4. vendored guard binary → .halfcycle/bin/bin.bundle.mjs (self-contained)
|
|
492
628
|
* 5. Governance-hook wiring (.claude/settings.json, guard-runner.sh,
|
|
493
629
|
* session-start-marker.sh, user-prompt-reminder.sh)
|
|
494
|
-
* 6. CI stanza
|
|
495
|
-
* names (credentialed installs only — T-24).
|
|
496
|
-
* writes no `.env.example` at all
|
|
630
|
+
* 6. (nothing) — no CI stanza (removed at T-25); the MCP registration and the
|
|
631
|
+
* connection-headers helper it names (credentialed installs only — T-24).
|
|
632
|
+
* NO env scaffold either: the installer writes no `.env.example` at all
|
|
633
|
+
* (operator decision, 2026-08-30)
|
|
497
634
|
* 7. .gitignore + project identity + the engagement credential (OUTSIDE the tree,
|
|
498
635
|
* at machine level — T-09) + migration of any pre-T-09 in-tree credential
|
|
499
636
|
* 8. .halfcycle/bundle.json pin
|
|
500
637
|
* 8b. .halfcycle/crew.json — CREW_ROSTER, serialised verbatim (crew-roster-and-dispatch)
|
|
501
638
|
* 9. Bootstrap scan → .halfcycle/state.json (INV-021 — once, onboarding-time,
|
|
502
639
|
* a no-op if the file already exists; never re-run on a re-install)
|
|
640
|
+
* 10. .halfcycle/install-manifest.json — what this and every earlier install put
|
|
641
|
+
* here, for `halfcycle uninstall` (T-21, `install-manifest.ts`)
|
|
503
642
|
*/
|
|
504
643
|
export declare function install(options: InstallOptions): Promise<InstallResult>;
|
|
505
644
|
export {};
|
package/dist/install.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* chooses between them; this module only ever reports what it MEASURED.
|
|
21
21
|
*
|
|
22
22
|
* ---------------------------------------------------------------------------
|
|
23
|
-
*
|
|
23
|
+
* FIVE PROPERTIES THIS MODULE IS RESPONSIBLE FOR. **Each one names the test that
|
|
24
24
|
* reds when it is mutated** — named, rather than claimed in aggregate, because the
|
|
25
25
|
* aggregate version of this sentence shipped once while property 3's call site was
|
|
26
26
|
* covered by nothing at all (see `createCallbackHandler`). A list that says "all of
|
|
@@ -51,8 +51,15 @@
|
|
|
51
51
|
* threw would push the caller towards guessing from the environment instead.
|
|
52
52
|
* → *"a port that is already taken is a MEASURED bind failure"*, against a real
|
|
53
53
|
* squatter on a real port.
|
|
54
|
+
* 5. **Only an engagement id reaches the completion page's onward address.** The
|
|
55
|
+
* id the page may deep-link to arrives from a committed file or an argument, so
|
|
56
|
+
* it is checked against `isEngagementId` — the shape's one home, in
|
|
57
|
+
* `@halfcycle/core` — and anything else sends the browser to the projects list
|
|
58
|
+
* instead. See `onwardTarget`.
|
|
59
|
+
* → *"a hostile id never reaches the page"*, which feeds quotes, markup and a
|
|
60
|
+
* `javascript:` URL through the real handler and reads back the body.
|
|
54
61
|
*
|
|
55
|
-
* INV-001: Node builtins and `@halfcycle/events` only.
|
|
62
|
+
* INV-001: Node builtins, `@halfcycle/core` and `@halfcycle/events` only.
|
|
56
63
|
*/
|
|
57
64
|
import { type LoopbackRedirectTarget, type LoopbackResult } from '@halfcycle/events';
|
|
58
65
|
/**
|
|
@@ -105,6 +112,12 @@ export interface LoopbackBindFailed {
|
|
|
105
112
|
reason: string;
|
|
106
113
|
}
|
|
107
114
|
export type LoopbackBindOutcome = LoopbackListener | LoopbackBindFailed;
|
|
115
|
+
/**
|
|
116
|
+
* How long the approved page stays up before it moves on, in seconds — long enough to
|
|
117
|
+
* read the line that says to go back to the terminal, short enough that nobody reaches
|
|
118
|
+
* for the link first. Pinned by a test that reads the literal out of the page body.
|
|
119
|
+
*/
|
|
120
|
+
export declare const COMPLETION_REDIRECT_SECONDS = 2;
|
|
108
121
|
/**
|
|
109
122
|
* Is this peer on the loopback interface?
|
|
110
123
|
*
|
|
@@ -143,7 +156,7 @@ export interface LoopbackResponse {
|
|
|
143
156
|
* THE ONE HANDLER, built here and used by `createServer` below and by nothing else.
|
|
144
157
|
*
|
|
145
158
|
* Extracted from the `createServer` call it used to be written inline in, for a
|
|
146
|
-
* reason worth stating rather than filing as a refactor. This file's header
|
|
159
|
+
* reason worth stating rather than filing as a refactor. This file's header claimed
|
|
147
160
|
* *"four properties, each of which has a test that reds when it is mutated"* — and
|
|
148
161
|
* for property 3 (**a request from a non-loopback peer is refused, independently of
|
|
149
162
|
* the bind address**) that was FALSE. Only the pure predicate `isLoopbackPeer` was
|
|
@@ -157,8 +170,12 @@ export interface LoopbackResponse {
|
|
|
157
170
|
* survive a FUTURE widening of property 1 — the moment the bind is wrong, this is
|
|
158
171
|
* what still refuses the network — so it needs an assertion that does not depend on
|
|
159
172
|
* the bind being right. Handing the handler a peer address is that assertion.
|
|
173
|
+
*
|
|
174
|
+
* `engagementId` is where an approved page sends the browser next, when the caller
|
|
175
|
+
* knew the project before signing in. It is passed through to `completionPage` as
|
|
176
|
+
* given; `onwardTarget` is what decides whether it may be used.
|
|
160
177
|
*/
|
|
161
|
-
export declare function createCallbackHandler(state: string, onCallback: (callback: LoopbackCallback) => void): (req: LoopbackRequest, res: LoopbackResponse) => void;
|
|
178
|
+
export declare function createCallbackHandler(state: string, onCallback: (callback: LoopbackCallback) => void, engagementId?: string): (req: LoopbackRequest, res: LoopbackResponse) => void;
|
|
162
179
|
/**
|
|
163
180
|
* Bind the callback listener, or report why it could not be bound.
|
|
164
181
|
*
|
|
@@ -168,6 +185,9 @@ export declare function createCallbackHandler(state: string, onCallback: (callba
|
|
|
168
185
|
* `reason` string the caller prints. A heuristic would be wrong in both directions:
|
|
169
186
|
* a container with a forwarded browser has no `DISPLAY` and works, and a locked-down
|
|
170
187
|
* desktop has one and does not.
|
|
188
|
+
*
|
|
189
|
+
* `engagementId` is the project the completion page may send the browser on to —
|
|
190
|
+
* see `createCallbackHandler`.
|
|
171
191
|
*/
|
|
172
|
-
export declare function bindLoopback(env?: NodeJS.ProcessEnv): Promise<LoopbackBindOutcome>;
|
|
192
|
+
export declare function bindLoopback(env?: NodeJS.ProcessEnv, engagementId?: string): Promise<LoopbackBindOutcome>;
|
|
173
193
|
//# sourceMappingURL=loopback-signin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopback-signin.d.ts","sourceRoot":"","sources":["../src/loopback-signin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loopback-signin.d.ts","sourceRoot":"","sources":["../src/loopback-signin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAKH,OAAO,EASL,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAE3D,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,EAAE,sBAAsB,CAAC;IAC/B;;;;;;;;OAQG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,+DAA+D;QAC/D,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,4EAA4E;AAC5E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;AAKxE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAqG7C;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAIzE;AAgBD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,CAAC;IAC9E,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EAChD,YAAY,CAAC,EAAE,MAAM,GACpB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAmCvD;AAoBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,CAAC,CAuE9B"}
|
package/dist/merge-settings.d.ts
CHANGED
|
@@ -60,6 +60,18 @@ export interface ClaudeSettings {
|
|
|
60
60
|
permissions?: ClaudePermissions;
|
|
61
61
|
[key: string]: unknown;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* True iff `entry` is Halfcycle-authored — i.e. it carries a hook command that
|
|
65
|
+
* matches one of ours. This is how a re-install replaces our entry in place
|
|
66
|
+
* rather than appending a duplicate. A developer's own entry (any other command
|
|
67
|
+
* string) is never matched, so it is never touched.
|
|
68
|
+
*
|
|
69
|
+
* Exported because it is THE rule for recognising a Halfcycle hook entry, and the
|
|
70
|
+
* installer's manifest (deciding whether a pre-manifest settings file is adopted)
|
|
71
|
+
* and the uninstaller (deciding which entries to take apart) ask the same question.
|
|
72
|
+
* A second predicate beside either of them would be a second answer to it.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isHalfcycleEntry(entry: HookEntry, halfcycleCommands: Set<string>): boolean;
|
|
63
75
|
/**
|
|
64
76
|
* Merge Halfcycle's generated hook entries into an existing settings object.
|
|
65
77
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-settings.d.ts","sourceRoot":"","sources":["../src/merge-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"merge-settings.d.ts","sourceRoot":"","sources":["../src/merge-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAE1F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,GAAG,cAAc,CAwCjG"}
|
package/dist/open-phase.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-phase.d.ts","sourceRoot":"","sources":["../src/open-phase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"open-phase.d.ts","sourceRoot":"","sources":["../src/open-phase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAY3B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sFAAsF;AACtF,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qDAAqD;IACrD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,yEAAyE;QACzE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aAEd,OAAO,EAAE,MAAM,GAAG,IAAI;gBAFtB,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM,EACC,OAAO,EAAE,MAAM,GAAG,IAAI;CAKzC;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,kFAItB,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,CAAC,EAAE,MAAM,GACZ,cAAc,CA4BhB;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,iBAAiB,GAAG,IAAI,CAmB1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,KAAK,EAAE,kBAAkB,EACzB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,CAAC,CAyEtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"own-engagement.d.ts","sourceRoot":"","sources":["../src/own-engagement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGxF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;CAC3C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;CAC3C;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GAAG,eAAe,GACxC,MAAM,IAAI,eAAe,CAE3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAmD1B;
|
|
1
|
+
{"version":3,"file":"own-engagement.d.ts","sourceRoot":"","sources":["../src/own-engagement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGxF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;CAC3C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;CAC3C;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GAAG,eAAe,GACxC,MAAM,IAAI,eAAe,CAE3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAmD1B;AAmDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,eAAe,GAAG,eAAe,CAAC,CAuF5C"}
|
package/dist/scan.d.ts
CHANGED
|
@@ -101,6 +101,13 @@ export interface HalfcycleStateFile {
|
|
|
101
101
|
export declare const LAYER_ARTEFACT_PATHS: Partial<Record<MethodLayer, string[]>>;
|
|
102
102
|
/** Scan `targetRepo` for each layer's artefact convention. Pure filesystem read. */
|
|
103
103
|
export declare function scanLayers(targetRepo: string, scannedAt?: string): HalfcycleStateFile;
|
|
104
|
+
/**
|
|
105
|
+
* Where the scan writes, relative to the repository root. Named once because the
|
|
106
|
+
* installer's closed write set (`install.ts`, `closedWriteSet`) is derived from the
|
|
107
|
+
* constants the writers use, so the path uninstall may remove is the path this
|
|
108
|
+
* writes, and not a second spelling of it.
|
|
109
|
+
*/
|
|
110
|
+
export declare const BOOTSTRAP_STATE_REL = ".halfcycle/state.json";
|
|
104
111
|
/**
|
|
105
112
|
* Run the bootstrap scan ONCE. If `.halfcycle/state.json` already exists this
|
|
106
113
|
* is a no-op (returns the existing file unchanged) — the "never again" half of
|
package/dist/scan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMxE,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,EAAG,yBAAkC,CAAC;AAEzE,kFAAkF;AAClF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,iBAAiB,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,gBAAgB,CAAC;IACzB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,QAStB,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC;;;OAGG;IACH,IAAI,EAAE,OAAO,oBAAoB,CAAC;IAClC,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;CACzD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAOvE,CAAC;AAMF,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAAiC,GAAG,kBAAkB,CAc/G;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAUhG;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,qBAAqB,EAAE,WAAW,CAAC,WAAW,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC,CAAC,CAcvD"}
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMxE,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,EAAG,yBAAkC,CAAC;AAEzE,kFAAkF;AAClF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,iBAAiB,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,gBAAgB,CAAC;IACzB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,QAStB,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC;;;OAGG;IACH,IAAI,EAAE,OAAO,oBAAoB,CAAC;IAClC,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;CACzD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAOvE,CAAC;AAMF,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAAiC,GAAG,kBAAkB,CAc/G;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAUhG;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,qBAAqB,EAAE,WAAW,CAAC,WAAW,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC,CAAC,CAcvD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `halfcycle uninstall` — takes back exactly what the installer put in this
|
|
3
|
+
* repository, and nothing else (`client-uninstall.md`, T-21).
|
|
4
|
+
*
|
|
5
|
+
* WHAT DECIDES THAT A PATH IS OURS: two keys, both required (INV-023). The committed
|
|
6
|
+
* install manifest (`install-manifest.ts`) must list it, AND it must be a member of
|
|
7
|
+
* the closed write set held in code (`install.ts`, `closedWriteSet`). The manifest is
|
|
8
|
+
* a file anyone who can land a commit can edit, so on its own it decides nothing.
|
|
9
|
+
* A file is then removed only while its bytes still hash to what the installer last
|
|
10
|
+
* wrote; one that changed is kept and named. A symbolic link, or a path under one, is
|
|
11
|
+
* never followed.
|
|
12
|
+
*
|
|
13
|
+
* THE ORDER OF WORK IS THE SPEC'S, and it is load-bearing:
|
|
14
|
+
* 1. validate everything and change nothing on any failure — the arguments (in
|
|
15
|
+
* `bin.ts`), the manifest, the pin, the project id when the credential is to go,
|
|
16
|
+
* and that each merged JSON file present parses as a JSON object;
|
|
17
|
+
* 2. unmerge `.claude/settings.json` first, so no hook points at a deleted script,
|
|
18
|
+
* then `.mcp.json`, so no registration points at a deleted helper;
|
|
19
|
+
* 3. remove the recorded files, except the pin and the manifest, and the CI
|
|
20
|
+
* template an earlier version wrote (`removeLegacyCiStanza`, which carries its
|
|
21
|
+
* own two keys: an exact known header and a clean committed copy);
|
|
22
|
+
* 4. remove the directories an install created, deepest first, when empty;
|
|
23
|
+
* 5. trim `.gitignore`;
|
|
24
|
+
* 6. remove this machine's credential for the project, if asked;
|
|
25
|
+
* 7. only when nothing so far failed: the pin, the manifest, then `.halfcycle/`.
|
|
26
|
+
* A failure at 3–6 therefore leaves the pin and the manifest in place, and a rerun
|
|
27
|
+
* finds everything else already absent — absent counts as removed — and retries.
|
|
28
|
+
*
|
|
29
|
+
* WHAT IT NEVER TOUCHES: any path outside the closed write set (Build Records, what
|
|
30
|
+
* setup wrote, `.workbench/`, captured fixtures, `.claude/agents/`), the project on
|
|
31
|
+
* Halfcycle, this machine's sign-in (`~/.halfcycle/account.json`) and the shared
|
|
32
|
+
* local log directory. It makes no network call and asks nothing.
|
|
33
|
+
*
|
|
34
|
+
* INV-001: imports only Node built-ins and this package's own modules.
|
|
35
|
+
*/
|
|
36
|
+
/** The verb's one flag. */
|
|
37
|
+
export declare const REMOVE_CREDENTIAL_FLAG = "--remove-credential";
|
|
38
|
+
export interface UninstallOptions {
|
|
39
|
+
readonly targetRepo: string;
|
|
40
|
+
readonly removeCredential: boolean;
|
|
41
|
+
/** The home directory `~/.halfcycle` lives under; defaults to `os.homedir()`. */
|
|
42
|
+
readonly home?: string;
|
|
43
|
+
}
|
|
44
|
+
/** What happened to this machine's credential for the project. */
|
|
45
|
+
export type CredentialOutcome = {
|
|
46
|
+
readonly kind: 'nothing-to-say';
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: 'still-held';
|
|
49
|
+
readonly dir: string;
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: 'invalid-id';
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: 'removed';
|
|
54
|
+
readonly dir: string;
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: 'not-held';
|
|
57
|
+
readonly dir: string;
|
|
58
|
+
} | {
|
|
59
|
+
readonly kind: 'no-project-id';
|
|
60
|
+
} | {
|
|
61
|
+
readonly kind: 'failed';
|
|
62
|
+
readonly dir: string;
|
|
63
|
+
readonly reason: string;
|
|
64
|
+
};
|
|
65
|
+
export interface UninstallResult {
|
|
66
|
+
readonly outcome: 'not-installed' | 'refused' | 'uninstalled';
|
|
67
|
+
readonly exitCode: 0 | 1;
|
|
68
|
+
/** Why a refused run changed nothing, and what to do. */
|
|
69
|
+
readonly refusal?: string;
|
|
70
|
+
readonly removed: string[];
|
|
71
|
+
readonly restored: string[];
|
|
72
|
+
/** Installed files that changed after the installer wrote them. */
|
|
73
|
+
readonly kept: string[];
|
|
74
|
+
/** `.gitignore` lines kept because the path they cover still exists. */
|
|
75
|
+
readonly keptIgnoreLines: string[];
|
|
76
|
+
readonly leftAlone: string[];
|
|
77
|
+
readonly failed: string[];
|
|
78
|
+
readonly credential: CredentialOutcome;
|
|
79
|
+
}
|
|
80
|
+
/** Parse the verb's arguments (global flags are already stripped by `bin.ts`). */
|
|
81
|
+
export declare function parseUninstallArgs(args: readonly string[]): {
|
|
82
|
+
removeCredential: boolean;
|
|
83
|
+
} | {
|
|
84
|
+
error: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Run the uninstall. Never throws for a condition the spec names: a refusal comes
|
|
88
|
+
* back as `outcome: 'refused'` with nothing changed.
|
|
89
|
+
*/
|
|
90
|
+
export declare function uninstall(options: UninstallOptions): UninstallResult;
|
|
91
|
+
/** The report, as the CLI prints it: stdout for a finished run, stderr for a refusal. */
|
|
92
|
+
export declare function renderUninstallReport(result: UninstallResult, home?: string): {
|
|
93
|
+
stdout: string;
|
|
94
|
+
stderr: string;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=uninstall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../src/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAsCH,2BAA2B;AAC3B,eAAO,MAAM,sBAAsB,wBAAwB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,aAAa,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;CACxC;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,gBAAgB,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAc7G;AAwWD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CA6HpE;AA+OD,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAmEhH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "halfcycle",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"description": "Your coding agents are the engineers. Halfcycle is the rest of the team: product owner, architect, planner and independent reviewer for Claude Code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"homepage": "https://halfcycle.ai",
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/Halfcycle-AI/halfcycle
|
|
22
|
+
"url": "git+https://github.com/Halfcycle-AI/halfcycle.git"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"type": "module",
|
package/dist/ci-bind.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE `ci bind` / `ci unbind` VERBS' WIRING — the client half of T-05's
|
|
3
|
-
* account-authenticated trust binding (`ci-oidc-token-exchange`, T-11, AC2 client
|
|
4
|
-
* half).
|
|
5
|
-
*
|
|
6
|
-
* `PUT|DELETE {baseUrl}/engagements/:engagementId/ci-bindings/:owner/:repo` says
|
|
7
|
-
* which repository's GitHub Actions OIDC tokens an engagement trusts — a signed-in
|
|
8
|
-
* developer states it once, from their own machine, and a client's CI afterwards
|
|
9
|
-
* needs no secret of ours to authenticate (the exchange itself, on the control
|
|
10
|
-
* plane, is the other half).
|
|
11
|
-
*
|
|
12
|
-
* WIRING, NOT MACHINERY — the same posture as `open-phase.ts` and `close-phase.ts`.
|
|
13
|
-
* Every rule this route enforces (ownership, the one-project-at-a-time conflict,
|
|
14
|
-
* what a repository string may be) is the route's; this module builds the request,
|
|
15
|
-
* sends it, and reports what came back.
|
|
16
|
-
*
|
|
17
|
-
* ---------------------------------------------------------------------------
|
|
18
|
-
* **THE ACCOUNT CREDENTIAL, NOT THE ENGAGEMENT TOKEN.** The route refuses a browser
|
|
19
|
-
* session by construction and refuses EVERY engagement token as a class — whether or
|
|
20
|
-
* not it carries an account. So this module resolves its credential exactly the way
|
|
21
|
-
* `own-engagement.ts` resolves the create/join credential — `resolve-credential.ts`'s
|
|
22
|
-
* `obtainCredential`, never `open-phase.ts`'s `readRepoCredential`, which reads the
|
|
23
|
-
* OTHER credential class (the engagement token) out of a repository's pinned env.
|
|
24
|
-
*
|
|
25
|
-
* **THIS PARAGRAPH USED TO REST ON "an engagement token that carries no account", AND
|
|
26
|
-
* THAT WAS THE HOLE** (T-05f, 2026-09-16): that phrasing describes a column, not a
|
|
27
|
-
* credential class, and once those rows began carrying an account the route admitted
|
|
28
|
-
* them — measured, at 204, with the binding surviving the token's revocation. There is
|
|
29
|
-
* a consequence for the caller here, and it is intended: `obtainCredential` gives
|
|
30
|
-
* `HALFCYCLE_TOKEN` precedence over a saved sign-in, so a developer with that variable
|
|
31
|
-
* set is now refused with a `403` whose sentence names unsetting it as the step. Before
|
|
32
|
-
* the fix that caller silently bound with the wrong credential class.
|
|
33
|
-
*
|
|
34
|
-
* **NO IDENTITY-CONFIRMATION CEREMONY, AND THAT IS A DELIBERATE NARROWING FROM
|
|
35
|
-
* `own-engagement.ts`, NOT AN OMISSION.** `createOwnedEngagement`/`joinPinnedEngagement`
|
|
36
|
-
* run `confirmActingIdentity` first because a create or a join under a stale saved
|
|
37
|
-
* sign-in SUCCEEDS silently, under the wrong account — a durable resource now exists
|
|
38
|
-
* that the person at the keyboard did not ask for. A bind under the wrong account
|
|
39
|
-
* cannot do that: T-05's `isOwnedBy` gate refuses it with `CiBindRefused` (403)
|
|
40
|
-
* before anything changes, so the failure mode this ceremony exists to interrupt is
|
|
41
|
-
* not reachable here — the route answers it, every time, without this client having
|
|
42
|
-
* to ask first.
|
|
43
|
-
*
|
|
44
|
-
* **THE RETRY IS ON `401` ALONE**, mirroring `joinPinnedEngagement`'s reasoning in
|
|
45
|
-
* `own-engagement.ts` exactly: this route's other refusals — `403` (not an account
|
|
46
|
-
* credential, or an engagement the caller does not own) and `409` (bound elsewhere)
|
|
47
|
-
* — are not a stale credential, and retrying either would discard a perfectly good
|
|
48
|
-
* sign-in to arrive at the identical refusal a moment later.
|
|
49
|
-
*
|
|
50
|
-
* INV-001: Node builtins, `@halfcycle/events` (transitively, via `resolve-credential`),
|
|
51
|
-
* and bundle-internal modules — never the control service. The route declares no
|
|
52
|
-
* wire shape (T-05: path segments in, `204` out — deliberately, so a `POST … {
|
|
53
|
-
* repository, engagementId }` body never needed a second `packages/events` home),
|
|
54
|
-
* so there is nothing here for this file to validate a body against; its only job
|
|
55
|
-
* is the path and the header.
|
|
56
|
-
*/
|
|
57
|
-
import { type ResolveOptions } from './resolve-credential.js';
|
|
58
|
-
/** The repository a `ci bind`/`ci unbind` call names. */
|
|
59
|
-
export interface CiRepository {
|
|
60
|
-
readonly owner: string;
|
|
61
|
-
readonly repo: string;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Read `owner/repo` off the command line. `null` for anything that is not exactly
|
|
65
|
-
* two non-blank segments — the same shape the route's own repository normaliser
|
|
66
|
-
* refuses, checked here only so a malformed argument fails before a round trip
|
|
67
|
-
* rather than after one to a route this CLI could have refused itself.
|
|
68
|
-
*/
|
|
69
|
-
export declare function parseCiRepositoryArg(arg: string): CiRepository | null;
|
|
70
|
-
/**
|
|
71
|
-
* A refusal from the control plane, carried whole so the CLI can print it.
|
|
72
|
-
*
|
|
73
|
-
* `403` covers two causes this file cannot and must not tell apart — the caller's
|
|
74
|
-
* credential is not an account credential at all, or it names an engagement the
|
|
75
|
-
* caller does not own — the same one-sentence-for-both posture T-05's own
|
|
76
|
-
* `CI_BIND_REFUSED_MESSAGE` is written with, so nothing here would have a second
|
|
77
|
-
* sentence to pick between anyway. `409` is the repository being bound elsewhere,
|
|
78
|
-
* client-safely worded by the route to name no other project.
|
|
79
|
-
*/
|
|
80
|
-
export declare class CiBindRefused extends Error {
|
|
81
|
-
readonly status: number;
|
|
82
|
-
constructor(status: number, message: string);
|
|
83
|
-
/** Is this the ONE arm signing in again can fix — see this file's header. */
|
|
84
|
-
get authRefused(): boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Is this "ours to fix, try again", not "yours to fix"? The question is not
|
|
87
|
-
* mechanical (did a handler run) — it is what a developer reading the message
|
|
88
|
-
* does next. `502`/`504` are the reverse proxy in front of the published origin
|
|
89
|
-
* answering for a control plane that is down or slow, with an HTML body this
|
|
90
|
-
* file's own `requestBinding` cannot parse, so the message would otherwise
|
|
91
|
-
* degrade to a bare "the URL returned 502". `503` is `resolveAccount`'s own
|
|
92
|
-
* fail-closed refusal when it could not reach the token store — the caller's
|
|
93
|
-
* credential was never actually checked, and its posture is emphatic this is NOT
|
|
94
|
-
* a "no". **`500` belongs beside them, not with the 4xx arms.** It is an
|
|
95
|
-
* unhandled throw: nothing decided the request's merits, and the bind may even
|
|
96
|
-
* have half-happened if the throw landed after a commit. On this route the
|
|
97
|
-
* body is the same degraded "the URL returned 500" a 502/504 produces — an
|
|
98
|
-
* internal path echoed back with no advice — so `refused (500)` would send a
|
|
99
|
-
* developer to re-check ownership, the repository name and whether it is bound
|
|
100
|
-
* elsewhere: every 4xx question, none of them this status's actual cause.
|
|
101
|
-
*
|
|
102
|
-
* So this is every `5xx`, not an enumerated set of three — the boundary is
|
|
103
|
-
* "did any handler decide yes or no", and a 4xx is the only family that ever did.
|
|
104
|
-
*/
|
|
105
|
-
get unavailable(): boolean;
|
|
106
|
-
}
|
|
107
|
-
/** Trust this engagement's CI with tokens from `repository` (T-05's `PUT` route). */
|
|
108
|
-
export declare function bindCiRepository(serviceUrl: string, engagementId: string, repository: CiRepository, deps?: ResolveOptions): Promise<void>;
|
|
109
|
-
/**
|
|
110
|
-
* Withdraw that trust (T-05's `DELETE` route) — reversible, and a success whether or
|
|
111
|
-
* not the repository was bound to this engagement in the first place (T-05's own
|
|
112
|
-
* docblock: `204` either way, so this route is never an oracle for whether a
|
|
113
|
-
* repository the caller does not own is bound to something else).
|
|
114
|
-
*/
|
|
115
|
-
export declare function unbindCiRepository(serviceUrl: string, engagementId: string, repository: CiRepository, deps?: ResolveOptions): Promise<void>;
|
|
116
|
-
//# sourceMappingURL=ci-bind.d.ts.map
|
package/dist/ci-bind.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ci-bind.d.ts","sourceRoot":"","sources":["../src/ci-bind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAOrE;AAED;;;;;;;;;GASG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAEpB,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM;IAMjB,6EAA6E;IAC7E,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;CACF;AAiFD,qFAAqF;AACrF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,YAAY,EACxB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,YAAY,EACxB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAEf"}
|