@mean-weasel/lineage 0.1.15 → 0.1.17
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 +13 -0
- package/README.md +249 -19
- package/dist/cli/lineage-channel.js +25 -5
- package/dist/cli/lineage-channel.js.map +2 -2
- package/dist/cli/lineage-dev.js +891 -52
- package/dist/cli/lineage-dev.js.map +4 -4
- package/dist/cli/lineage-preview.js +891 -52
- package/dist/cli/lineage-preview.js.map +4 -4
- package/dist/cli/lineage.js +891 -52
- package/dist/cli/lineage.js.map +4 -4
- package/dist/cli/managed-service.js +19 -5
- package/dist/cli/managed-service.js.map +2 -2
- package/dist/runtime-build.json +4 -4
- package/dist/server.js +883 -89
- package/dist/server.js.map +4 -4
- package/dist/web/assets/agent-shared-state-DOfpTLiw.webp +0 -0
- package/dist/web/assets/agent-to-canvas-DtIu_cPq.mp4 +0 -0
- package/dist/web/assets/{app-CDxSvoD3.css → app-B-fAyNsU.css} +1 -1
- package/dist/web/assets/app-DMogkUoS.js +16 -0
- package/dist/web/assets/attempt-history-D6wdic6n.webp +0 -0
- package/dist/web/assets/branching-tree-B8I5_S6D.png +0 -0
- package/dist/web/assets/canvas-cli-DHBacq7r.png +0 -0
- package/dist/web/assets/hero-agent-sync-CSyh0tHy.mp4 +0 -0
- package/dist/web/assets/hero-board-DG3ED4AW.webp +0 -0
- package/dist/web/assets/hero-lineage-growth-Bsl9tiq-.mp4 +0 -0
- package/dist/web/assets/hero-trace-connections-Bb52ABBc.mp4 +0 -0
- package/dist/web/assets/human-selection-BdDBDE-I.webp +0 -0
- package/dist/web/assets/human-to-agent-D1z92ZO9.mp4 +0 -0
- package/dist/web/assets/{jsx-runtime-_Rdg6et1.js → jsx-runtime-DAFSxiwi.js} +1 -1
- package/dist/web/assets/landing-Bn4qKbIO.css +1 -0
- package/dist/web/assets/landing-CoyGmxBo.js +1 -0
- package/dist/web/assets/reroll-history-DQcEH42R.mp4 +0 -0
- package/dist/web/index.html +3 -3
- package/dist/web/landing/index.html +3 -3
- package/fixtures/demo-project/lineage/swissifier-rich-demo.json +13 -13
- package/package.json +4 -3
- package/dist/web/assets/app-CYUgf6rX.js +0 -16
- package/dist/web/assets/landing-D3Y679_B.css +0 -1
- package/dist/web/assets/landing-ii8AH_DG.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.17
|
|
4
|
+
|
|
5
|
+
- Add atomic `profile init` for fresh installs, including exact runtime pinning, owner-only manifests, bound SQLite identity, no-clobber rollback, and actionable guidance when an unbound runtime attempts a write.
|
|
6
|
+
- Make stable and preview launcher installation, managed services, and `make install-dev` agree with the documented first-run paths while preserving strict runtime/profile/database identity checks.
|
|
7
|
+
- Add a version-qualified Codex plugin installer with read-only diagnostics, explicit temporary Codex-home support, exact app/plugin version locking, and rollback-safe activation.
|
|
8
|
+
- Prevent the app's topbar and lineage action menus from overlapping, update the vulnerable `body-parser` dependency, and continuously prove install, profile, service, seed, CLI, and plugin onboarding in an isolated end-to-end smoke test.
|
|
9
|
+
|
|
10
|
+
## 0.1.16
|
|
11
|
+
|
|
12
|
+
- Add editable one- or two-word lineage edge summaries with agent/human provenance, optimistic concurrency protection, accessible keyboard editing, and consistent labels across every graph orientation.
|
|
13
|
+
- Add a versioned generation-output manifest that binds each new output to its selected parent and required edge summary while preserving completion of already-planned legacy jobs.
|
|
14
|
+
- Upgrade the node inspector with uncropped media, Branch, Re-roll, and Details actions, focus-scoped B/R/D shortcuts, and modal-safe dismissal in place of the redundant fixed Inspecting card.
|
|
15
|
+
|
|
3
16
|
## 0.1.15
|
|
4
17
|
|
|
5
18
|
- Add a subtle root marker that makes the starting point of each lineage tree immediately recognizable.
|
package/README.md
CHANGED
|
@@ -1,6 +1,132 @@
|
|
|
1
1
|
# Lineage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The shared visual workspace where humans and agents shape creative work together.**
|
|
4
|
+
|
|
5
|
+
Chat is a good interface for directing agent-driven creative work, but it is not
|
|
6
|
+
built to hold the state of that work. Lineage keeps every asset, path, prompt,
|
|
7
|
+
iteration, relationship, selection, and annotation in one local-first record:
|
|
8
|
+
visual enough for humans to review and direct, and precise enough for agents to
|
|
9
|
+
retrieve through the CLI and continue accurately.
|
|
10
|
+
|
|
11
|
+
[See the landing page](https://mean-weasel.github.io/lineage/) ·
|
|
12
|
+
[Install Lineage](#first-run) ·
|
|
13
|
+
[Use the Codex plugin](#codex-plugin) ·
|
|
14
|
+
[Develop locally](#local-development)
|
|
15
|
+
|
|
16
|
+
## One creative state for humans and agents
|
|
17
|
+
|
|
18
|
+
- **Humans keep the history organized.** Review branches and attempts, compare
|
|
19
|
+
results, choose the exact asset to continue from, and annotate the next move.
|
|
20
|
+
- **Agents keep the context behind the work.** Read the same assets, prompts,
|
|
21
|
+
relationships, and decisions instead of reconstructing them from chat.
|
|
22
|
+
- **Context travels both ways.** Agent-created work returns to the visual record;
|
|
23
|
+
human selections and annotations become precise context for the next agent
|
|
24
|
+
action.
|
|
25
|
+
|
|
26
|
+
With Lineage, you can trace an asset from its origin through every branch,
|
|
27
|
+
selection, and campaign format; continue from any useful point without losing
|
|
28
|
+
earlier work; and hand a clear, durable work packet to the next human, agent, or
|
|
29
|
+
downstream tool.
|
|
30
|
+
|
|
31
|
+
## Built with GPT-5.6 Sol in Codex
|
|
32
|
+
|
|
33
|
+
Lineage is itself a human-agent collaboration. We use GPT-5.6 Sol in Codex
|
|
34
|
+
throughout the project to:
|
|
35
|
+
|
|
36
|
+
- design and implement the web app, server, CLI, and version-locked Codex plugin;
|
|
37
|
+
- exercise real workflows through the Codex in-app browser and Codex Chrome
|
|
38
|
+
extension, alongside automated browser tests;
|
|
39
|
+
- shape architecture and safety boundaries for runtime channels, local data,
|
|
40
|
+
agent claims, and handoffs;
|
|
41
|
+
- diagnose failures, review changes, write tests, and stabilize end-to-end
|
|
42
|
+
behavior;
|
|
43
|
+
- create and refine the landing page, including its visual design, interactions,
|
|
44
|
+
and supporting visual assets; and
|
|
45
|
+
- build and verify CI, packaging, release automation, public documentation, and
|
|
46
|
+
product messaging.
|
|
47
|
+
|
|
48
|
+
Model-assisted work is held to the same proof standard as any other change. The
|
|
49
|
+
repository's automated gates cover unit, integration, and browser behavior;
|
|
50
|
+
runtime and database isolation; public-readiness checks; installability; plugin
|
|
51
|
+
integrity; and dependency audits.
|
|
52
|
+
|
|
53
|
+
## First Run
|
|
54
|
+
|
|
55
|
+
### Prerequisites
|
|
56
|
+
|
|
57
|
+
Before installing anything, verify the tools used by the path you choose:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
node --version
|
|
61
|
+
npm --version
|
|
62
|
+
make --version
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Lineage requires Node.js 22.22.0 or newer and npm. Make is required only for
|
|
66
|
+
the documented `make` shortcuts. A real Codex installation is optional for the
|
|
67
|
+
app, but required to install and activate the Codex plugin; verify that
|
|
68
|
+
additional prerequisite with `codex --version` before following the plugin
|
|
69
|
+
step.
|
|
70
|
+
|
|
71
|
+
### Develop from a fresh clone
|
|
72
|
+
|
|
73
|
+
This is the shortest source-development path with hot reload and isolated
|
|
74
|
+
development data:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/mean-weasel/lineage.git
|
|
78
|
+
cd lineage
|
|
79
|
+
npm ci
|
|
80
|
+
npm run lineage:dev -- profile init --profile team-development --confirm-write --json
|
|
81
|
+
npm run dev -- --profile team-development
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Open `http://lineage-dev.localhost:5198`, then choose **Load demo lineage** for
|
|
85
|
+
a small graph or use the workspace menu's **Load rich image demo** for the full
|
|
86
|
+
media-backed example. On later runs, reuse the same healthy profile and run
|
|
87
|
+
only the final start command. If profile initialization reports an existing but
|
|
88
|
+
unhealthy profile, run the exact `profile doctor` command it prints before
|
|
89
|
+
changing anything.
|
|
90
|
+
|
|
91
|
+
### Install the published channels
|
|
92
|
+
|
|
93
|
+
Use the currently published npm dist-tags when you want installed rather than
|
|
94
|
+
checkout code:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm install -g @mean-weasel/lineage@latest
|
|
98
|
+
lineage-channel install stable
|
|
99
|
+
lineage-stable runtime doctor --json
|
|
100
|
+
lineage-stable profile init --profile team-production --confirm-write --json
|
|
101
|
+
lineage-stable start --profile team-production
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Preview is independent and must use its own runtime root and profile:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
lineage-channel install preview
|
|
108
|
+
lineage-preview runtime doctor --json
|
|
109
|
+
lineage-preview profile init --profile team-preview --confirm-write --json
|
|
110
|
+
lineage-preview start --profile team-preview
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The version in this checkout may be ahead of npm and is not necessarily
|
|
114
|
+
published. The channel installer resolves `latest` or `next` at install time;
|
|
115
|
+
do not substitute the checkout version or install both tags into one global npm
|
|
116
|
+
prefix.
|
|
117
|
+
|
|
118
|
+
To add the optional Codex plugin, first choose the exact Codex home you intend
|
|
119
|
+
to modify, then install and doctor the matching published channel:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
export CODEX_HOME="$HOME/.codex"
|
|
123
|
+
npx --yes @mean-weasel/lineage-plugin-installer@latest install --channel latest --codex-home "$CODEX_HOME"
|
|
124
|
+
npx --yes @mean-weasel/lineage-plugin-installer@latest doctor --channel latest --codex-home "$CODEX_HOME"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If doctor fails, it prints a version-pinned remediation command for that same
|
|
128
|
+
Codex home. For verification, use a temporary `--codex-home`; do not test an
|
|
129
|
+
installer against your real Codex profile.
|
|
4
130
|
|
|
5
131
|
## Package Channels
|
|
6
132
|
|
|
@@ -19,8 +145,12 @@ lineage-channel install preview
|
|
|
19
145
|
|
|
20
146
|
By default the installer writes immutable version/integrity roots beneath
|
|
21
147
|
`~/Library/Application Support/Lineage/runtimes`, plus channel-qualified
|
|
22
|
-
launchers
|
|
23
|
-
|
|
148
|
+
launchers in npm's global executable directory (the directory already on
|
|
149
|
+
`PATH` for the globally installed `lineage-channel`). Every launcher is pinned
|
|
150
|
+
to an absolute package root and install receipt; it does not select code from
|
|
151
|
+
`PATH` at runtime. Use `--shim-dir <path>` to choose another launcher directory,
|
|
152
|
+
or `--root <path>` to keep both a custom runtime and its launchers under that
|
|
153
|
+
root. Lineage never edits shell startup files.
|
|
24
154
|
|
|
25
155
|
The three exact channel meanings are:
|
|
26
156
|
|
|
@@ -37,6 +167,20 @@ lineage-preview runtime doctor --json
|
|
|
37
167
|
npm run lineage:dev -- runtime doctor --json
|
|
38
168
|
```
|
|
39
169
|
|
|
170
|
+
On a first install, initialize one new profile per channel before starting it:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
lineage-stable profile init --profile team-production --confirm-write --json
|
|
174
|
+
lineage-preview profile init --profile team-preview --confirm-write --json
|
|
175
|
+
npm run lineage:dev -- profile init --profile team-development --confirm-write --json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`profile init` derives the environment and exact verified code pin from the
|
|
179
|
+
launcher, creates owner-only media and SQLite paths, binds the new database
|
|
180
|
+
identity, and publishes the profile manifest only after those steps succeed.
|
|
181
|
+
It is fresh-only: it never adopts or overwrites an existing directory or
|
|
182
|
+
database. Use `profile bind` only to migrate an existing database.
|
|
183
|
+
|
|
40
184
|
`runtime doctor` fails unless channel, canonical package/checkout root, exact
|
|
41
185
|
version, embedded Git/build fingerprint, install receipt, and installed package
|
|
42
186
|
tree agree. `runtime info` prints the same identity without requiring it to pass
|
|
@@ -55,19 +199,20 @@ npm run lineage:dev -- start --profile team-development
|
|
|
55
199
|
|
|
56
200
|
Stable defaults to `lineage.localhost:5197`, dev to
|
|
57
201
|
`lineage-dev.localhost:5198`, and preview to
|
|
58
|
-
`lineage-preview.localhost:5199`.
|
|
59
|
-
|
|
202
|
+
`lineage-preview.localhost:5199`. A named profile owns its host, port, database,
|
|
203
|
+
and asset root. To choose another service origin, set it when creating the
|
|
204
|
+
profile:
|
|
60
205
|
|
|
61
206
|
```bash
|
|
62
|
-
lineage-stable
|
|
207
|
+
lineage-stable profile init --profile team-production-6123 \
|
|
208
|
+
--service-origin http://lineage.localhost:6123 --confirm-write --json
|
|
209
|
+
lineage-stable start --profile team-production-6123
|
|
63
210
|
```
|
|
64
211
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
the installed package directory remains responsible only for bundled code,
|
|
70
|
-
web assets, and public demo fixtures.
|
|
212
|
+
Starts with a named profile reject conflicting `--host`, `--port`, `--db`, or
|
|
213
|
+
asset-root selections. Direct path selection is retained only for explicit
|
|
214
|
+
diagnostic, read-only access. The installed package directory remains
|
|
215
|
+
responsible only for bundled code, web assets, and public demo fixtures.
|
|
71
216
|
|
|
72
217
|
## Runtime Channels and SQLite
|
|
73
218
|
|
|
@@ -107,14 +252,19 @@ service and its data:
|
|
|
107
252
|
|
|
108
253
|
Named profiles live at `$LINEAGE_PROFILE_ROOT/<profile-id>/profile.json` by
|
|
109
254
|
default, or can be selected with an explicit manifest path. Relative database
|
|
110
|
-
and asset paths resolve from the manifest directory.
|
|
111
|
-
|
|
255
|
+
and asset paths resolve from the manifest directory. Create a fresh profile,
|
|
256
|
+
then inspect it without making further changes:
|
|
112
257
|
|
|
113
258
|
```bash
|
|
259
|
+
lineage-stable profile init --profile team-production --confirm-write --json
|
|
114
260
|
lineage-stable profile doctor --profile team-production --json
|
|
115
261
|
lineage-stable start --profile team-production
|
|
116
262
|
```
|
|
117
263
|
|
|
264
|
+
Pass `--service-origin http://host:port` to `profile init` when the profile
|
|
265
|
+
must use a non-default local origin. Once initialized, that origin is part of
|
|
266
|
+
the immutable profile identity rather than a per-start override.
|
|
267
|
+
|
|
118
268
|
`LINEAGE_PROFILE` is equivalent to `--profile`. Profile commands reject direct
|
|
119
269
|
`--db` and `--asset-root` overrides, and a dev or preview runtime refuses to
|
|
120
270
|
open a production profile. Doctor also requires the existing SQLite database
|
|
@@ -130,6 +280,8 @@ can be bound or used for writes. `profile bind` may add a fingerprint to a
|
|
|
130
280
|
matching legacy identity, but refuses a conflicting identity. An unprofiled
|
|
131
281
|
CLI or service is `legacy-unbound` and read-only; mutating CLI commands and HTTP
|
|
132
282
|
methods fail with a profile-required error instead of creating a database.
|
|
283
|
+
That error points new installations to `profile init`; direct database paths do
|
|
284
|
+
not opt a process into writes.
|
|
133
285
|
|
|
134
286
|
Checkout fingerprints intentionally change as tracked or untracked source
|
|
135
287
|
changes. To repin an existing development profile, first stop its managed
|
|
@@ -206,6 +358,13 @@ lineage-preview db info --profile team-preview --json
|
|
|
206
358
|
npm run lineage:dev -- db info --profile team-development --json
|
|
207
359
|
```
|
|
208
360
|
|
|
361
|
+
Offline `db info` reports the one-shot CLI under `process` with
|
|
362
|
+
`role: "command"` and omits `service`; its PID is never service-health evidence.
|
|
363
|
+
HTTP runtime responses from a launched app report `process.role: "service"` and
|
|
364
|
+
a separate `service` identity. `service.mode: "managed"` records the launch
|
|
365
|
+
context only—managed health still requires the profile-scoped receipt and an
|
|
366
|
+
exact `/api/runtime` code/profile/database/instance match.
|
|
367
|
+
|
|
209
368
|
Managed services are profile-scoped. Their receipts record the launcher PID
|
|
210
369
|
and start token, unique service instance, code root/fingerprint, profile and
|
|
211
370
|
database fingerprints, origin, and log path. Start waits for `/api/runtime` to
|
|
@@ -287,12 +446,33 @@ Keep the claim fresh and pass it to mutating commands:
|
|
|
287
446
|
|
|
288
447
|
```bash
|
|
289
448
|
lineage agent heartbeat --claim-token "$LINEAGE_CLAIM_TOKEN" --json
|
|
290
|
-
lineage link-child --project demo-project --root <root-asset-id> --child <child-asset-id> --claim-token "$LINEAGE_CLAIM_TOKEN" --confirm-write --json
|
|
449
|
+
lineage link-child --project demo-project --root <root-asset-id> --child <child-asset-id> --summary "Cleaner type" --claim-token "$LINEAGE_CLAIM_TOKEN" --confirm-write --json
|
|
291
450
|
lineage agent release --claim-token "$LINEAGE_CLAIM_TOKEN" --json
|
|
292
451
|
```
|
|
293
452
|
|
|
294
453
|
`lineage link-child` creates a new visible descendant in the lineage graph. Do
|
|
295
|
-
not use it for re-rolls.
|
|
454
|
+
not use it for re-rolls. The coordinating agent must supply `--summary` with a
|
|
455
|
+
one- or two-word description of the change from parent to child.
|
|
456
|
+
|
|
457
|
+
For a coordinated multi-output generation job, plan from the selected lineage
|
|
458
|
+
bases, copy `job.handoff.output_manifest` from the JSON response into a manifest
|
|
459
|
+
file, and fill every output's `file_path` and distinct one- or two-word
|
|
460
|
+
`edge_summary` before import:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
lineage generate image plan --project demo-project --prompt "Create two variations" --from-lineage-selection --count 2 --json
|
|
464
|
+
lineage generate image inspect --project demo-project --job-id <job-id> --json
|
|
465
|
+
lineage generate image import --project demo-project --job-id <job-id> --manifest .asset-scratch/generation-output-manifest.json --confirm-write --json
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Newly planned selection jobs require the versioned manifest and reject mixed
|
|
469
|
+
`--manifest`, `--files`, or `--parent-files` input. Jobs already planned with
|
|
470
|
+
the legacy adapter may still finish with `--files` or `--parent-files`; those
|
|
471
|
+
legacy child edges remain unlabeled. Manifest retries are idempotent only while
|
|
472
|
+
the output mapping, original summary, and current agent provenance still match.
|
|
473
|
+
Asset indexing precedes the receipt transaction, so a later transactional
|
|
474
|
+
failure can leave an indexed asset even though outputs, edges, receipt, job
|
|
475
|
+
status, and selection reset roll back together.
|
|
296
476
|
|
|
297
477
|
For re-roll work, mark the target, have the agent plan/import one replacement
|
|
298
478
|
attempt, and cancel only when the request should be abandoned:
|
|
@@ -340,9 +520,19 @@ The versioned Codex plugin lives in `plugins/lineage-codex-plugin`. Install the
|
|
|
340
520
|
plugin that matches the resolved `@mean-weasel/lineage` package version with:
|
|
341
521
|
|
|
342
522
|
```bash
|
|
343
|
-
npx @mean-weasel/lineage-plugin-installer install --channel latest
|
|
523
|
+
npx --yes @mean-weasel/lineage-plugin-installer@latest install --channel latest
|
|
524
|
+
npx --yes @mean-weasel/lineage-plugin-installer@latest doctor --channel latest
|
|
344
525
|
```
|
|
345
526
|
|
|
527
|
+
The explicit installer `@latest` prevents `npx` from reusing an older installed
|
|
528
|
+
or cached CLI. Both commands honor `CODEX_HOME`; pass `--codex-home <path>` to
|
|
529
|
+
make the target visible in the command and machine-readable result. `doctor` is
|
|
530
|
+
read-only and fails unless the selected Codex home reports the matching plugin
|
|
531
|
+
installed and enabled from the expected Lineage marketplace root.
|
|
532
|
+
On failure it distinguishes a missing or mismatched marketplace, missing or
|
|
533
|
+
disabled plugin, version mismatch, and invalid manifest, then prints an exact
|
|
534
|
+
`--version`-pinned install/reinstall command for that Codex home.
|
|
535
|
+
|
|
346
536
|
The installer verifies the plugin artifact checksum and rejects plugin manifests
|
|
347
537
|
whose version or `lineage.version` does not exactly match the resolved Lineage
|
|
348
538
|
package version. It then creates a dedicated marketplace under the active
|
|
@@ -367,14 +557,54 @@ activation path.
|
|
|
367
557
|
|
|
368
558
|
## Local Development
|
|
369
559
|
|
|
560
|
+
For source development with hot reload:
|
|
561
|
+
|
|
370
562
|
```bash
|
|
371
563
|
npm ci
|
|
372
|
-
npm run dev
|
|
564
|
+
npm run lineage:dev -- profile init --profile team-development --confirm-write --json
|
|
565
|
+
npm run dev -- --profile team-development
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Both source and bundled server starts require a named profile. The hot-reload
|
|
569
|
+
launcher doctors the profile before it binds a port, then derives the database,
|
|
570
|
+
asset root, host, and port exclusively from that profile. Reuse an existing
|
|
571
|
+
development profile by omitting the `profile init` line.
|
|
572
|
+
|
|
573
|
+
For the profile-safe CLI and managed development service, prepare the checkout
|
|
574
|
+
once, initialize a development profile, and start it:
|
|
575
|
+
|
|
576
|
+
```bash
|
|
577
|
+
make install-dev
|
|
578
|
+
npm run lineage:dev -- profile init --profile team-development --confirm-write --json
|
|
579
|
+
make start-dev LINEAGE_DEV_PROFILE=team-development
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
Managed starts are idempotent: rerunning the same `start-*-bg` command returns
|
|
583
|
+
success only after the existing service again matches the exact code, profile,
|
|
584
|
+
database, origin, and service-instance receipt. Identity conflicts and unhealthy
|
|
585
|
+
services remain errors. If `profile init` reports that a profile already passes
|
|
586
|
+
doctor, reuse it with `start --profile <id>`; if it fails doctor, run the printed
|
|
587
|
+
`profile doctor` command and inspect the profile directory before retrying.
|
|
588
|
+
|
|
589
|
+
`make install-dev` installs the locked dependencies and builds the bundled
|
|
590
|
+
server required by `lineage-dev start`; no separate build command is needed.
|
|
591
|
+
Run the verification gates with:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
373
594
|
npm run ci
|
|
595
|
+
npm run onboarding:smoke
|
|
374
596
|
npm run runtime:oracle
|
|
375
597
|
```
|
|
376
598
|
|
|
377
|
-
`npm run dev
|
|
599
|
+
`npm run dev -- --profile <development-profile>` starts the local development server from source with Vite hot reload. `npm run ci` runs the full local verification gate.
|
|
600
|
+
`npm run onboarding:smoke` uses only temporary runtime, profile, service, npm,
|
|
601
|
+
media, and Codex roots to prove the installed stable launcher, profile init and
|
|
602
|
+
doctor, managed app, basic and rich seeds, CLI handoff, plugin activation, and
|
|
603
|
+
plugin doctor as one first-user journey. It uses the real `codex` executable
|
|
604
|
+
when one is on `PATH`; otherwise it uses a deterministic protocol harness so
|
|
605
|
+
the public CI gate remains portable. Run `npm run plugin:codex-smoke` on a
|
|
606
|
+
machine with Codex installed for real-CLI activation, reinstallation, cleanup,
|
|
607
|
+
and rollback proof.
|
|
378
608
|
`npm run runtime:oracle` creates three temporary code roots, profiles,
|
|
379
609
|
databases, ports, and managed services, proves their identities are distinct
|
|
380
610
|
while all are live, attacks every cross-channel and stale-identity boundary,
|
|
@@ -42,6 +42,22 @@ function runtimeRoot() {
|
|
|
42
42
|
if (platform() === "win32") return join(process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local"), "Lineage", "runtimes");
|
|
43
43
|
return join(process.env.XDG_DATA_HOME || join(homedir(), ".local", "share"), "lineage", "runtimes");
|
|
44
44
|
}
|
|
45
|
+
function globalNpmExecutableDirectory() {
|
|
46
|
+
let prefix;
|
|
47
|
+
try {
|
|
48
|
+
prefix = execFileSync("npm", ["prefix", "--global"], { encoding: "utf8" }).trim();
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw new Error("Could not locate the global npm executable directory; pass --shim-dir explicitly", { cause: error });
|
|
51
|
+
}
|
|
52
|
+
if (!prefix) throw new Error("npm returned an empty global prefix; pass --shim-dir explicitly");
|
|
53
|
+
return platform() === "win32" ? resolve(prefix) : resolve(prefix, "bin");
|
|
54
|
+
}
|
|
55
|
+
function shimDirectory(args, root) {
|
|
56
|
+
const explicit = readOption(args, "--shim-dir");
|
|
57
|
+
if (explicit) return resolve(explicit);
|
|
58
|
+
if (readOption(args, "--root") || process.env.LINEAGE_RUNTIME_ROOT) return join(root, "bin");
|
|
59
|
+
return globalNpmExecutableDirectory();
|
|
60
|
+
}
|
|
45
61
|
function parseChannel(value) {
|
|
46
62
|
if (value === "stable" || value === "preview") return value;
|
|
47
63
|
throw new Error("Channel must be stable or preview; dev is checkout-only");
|
|
@@ -140,10 +156,11 @@ function resolveSpec(spec, allowLocalPackage) {
|
|
|
140
156
|
function shellQuote(value) {
|
|
141
157
|
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
142
158
|
}
|
|
143
|
-
function writeShim(path, channel, receiptPath, entrypoint) {
|
|
159
|
+
function writeShim(path, channel, receiptPath, entrypoint, environment = {}) {
|
|
144
160
|
const tempPath = `${path}.tmp-${process.pid}`;
|
|
161
|
+
const assignments = Object.entries(environment).map(([key, value]) => `${key}=${shellQuote(value)}`).join(" ");
|
|
145
162
|
const script = `#!/bin/sh
|
|
146
|
-
LINEAGE_RUNTIME_RECEIPT=${shellQuote(receiptPath)} LINEAGE_RELEASE_CHANNEL=${shellQuote(channel)} exec ${shellQuote(process.execPath)} ${shellQuote(entrypoint)} "$@"
|
|
163
|
+
LINEAGE_RUNTIME_RECEIPT=${shellQuote(receiptPath)} LINEAGE_RELEASE_CHANNEL=${shellQuote(channel)}${assignments ? ` ${assignments}` : ""} exec ${shellQuote(process.execPath)} ${shellQuote(entrypoint)} "$@"
|
|
147
164
|
`;
|
|
148
165
|
writeFileSync(tempPath, script, { mode: 493 });
|
|
149
166
|
chmodSync(tempPath, 493);
|
|
@@ -164,7 +181,7 @@ function validateExistingReceipt(receiptPath, channel, expected) {
|
|
|
164
181
|
}
|
|
165
182
|
function install(channel, args) {
|
|
166
183
|
const root = resolve(readOption(args, "--root") || runtimeRoot());
|
|
167
|
-
const shimDir =
|
|
184
|
+
const shimDir = shimDirectory(args, root);
|
|
168
185
|
const requestedSpec = readOption(args, "--package") || `${packageInfo.name}@${channel === "stable" ? "latest" : "next"}`;
|
|
169
186
|
const resolvedSpec = resolveSpec(requestedSpec, args.includes("--allow-local-package"));
|
|
170
187
|
const channelRoot = join(root, "installs", channel);
|
|
@@ -228,7 +245,7 @@ function install(channel, args) {
|
|
|
228
245
|
const serviceShim = join(shimDir, channel === "stable" ? "lineage-stable-service" : "lineage-preview-service");
|
|
229
246
|
const serviceEntrypoint = join(finalPackageRoot, "dist", "cli", "managed-service.js");
|
|
230
247
|
if (!existsSync(serviceEntrypoint)) throw new Error(`Installed package is missing ${serviceEntrypoint}`);
|
|
231
|
-
writeShim(serviceShim, channel, receiptPath, serviceEntrypoint);
|
|
248
|
+
writeShim(serviceShim, channel, receiptPath, serviceEntrypoint, { LINEAGE_CHANNEL_LAUNCHER: shim });
|
|
232
249
|
const pointerDir = join(root, "channels");
|
|
233
250
|
mkdirSync(pointerDir, { recursive: true });
|
|
234
251
|
writeFileSync(join(pointerDir, `${channel}.json`), `${JSON.stringify({ channel, receipt_path: receiptPath, service_shim: serviceShim, shim }, null, 2)}
|
|
@@ -263,7 +280,10 @@ Usage:
|
|
|
263
280
|
|
|
264
281
|
Stable and preview are installed into separate content-addressed roots. Dev is
|
|
265
282
|
checkout-only and is started with npm run lineage:dev -- <command>. Local
|
|
266
|
-
tarballs are refused unless --allow-local-package is supplied explicitly
|
|
283
|
+
tarballs are refused unless --allow-local-package is supplied explicitly.
|
|
284
|
+
Default installs put launchers in npm's global executable directory, which is
|
|
285
|
+
already on PATH when lineage-channel is invoked. A custom --root keeps its
|
|
286
|
+
launchers under <root>/bin unless --shim-dir is also supplied.`;
|
|
267
287
|
}
|
|
268
288
|
function print(value, json) {
|
|
269
289
|
if (json) console.log(JSON.stringify(value, null, 2));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/lineage-channel.ts", "../../src/shared/runtimeInfoTypes.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport { createHash } from 'node:crypto';\nimport { execFileSync } from 'node:child_process';\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n readdirSync,\n readlinkSync,\n realpathSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n lineageRuntimeBuildSchemaVersion,\n lineageRuntimeInstallSchemaVersion,\n type LineageRuntimeBuildIdentity,\n type LineageRuntimeInstallReceipt,\n} from '../shared/runtimeInfoTypes';\n\ntype PublishedChannel = 'stable' | 'preview';\ninterface ResolvedPackageSpec {\n expectedVersion?: string;\n installSpec: string;\n integrity: string;\n requestedSpec: string;\n source: LineageRuntimeInstallReceipt['package_source'];\n}\n\ninterface RegistryPackageMetadata {\n dist?: { integrity?: unknown };\n 'dist.integrity'?: unknown;\n version?: unknown;\n}\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');\nconst packageInfo = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')) as { name: string; version: string };\n\nfunction sha256(value: string | Buffer): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction readOption(args: string[], name: string): string | undefined {\n const inline = args.find(arg => arg.startsWith(`${name}=`));\n if (inline) return inline.slice(name.length + 1);\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction runtimeRoot(): string {\n if (process.env.LINEAGE_RUNTIME_ROOT) return resolve(process.env.LINEAGE_RUNTIME_ROOT);\n if (platform() === 'darwin') return join(homedir(), 'Library', 'Application Support', 'Lineage', 'runtimes');\n if (platform() === 'win32') return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Lineage', 'runtimes');\n return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'lineage', 'runtimes');\n}\n\nfunction parseChannel(value?: string): PublishedChannel {\n if (value === 'stable' || value === 'preview') return value;\n throw new Error('Channel must be stable or preview; dev is checkout-only');\n}\n\nfunction packageTreeSha256(root: string): string {\n const hash = createHash('sha256');\n const visit = (directory: string, relativeDirectory = '') => {\n for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {\n const relativePath = relativeDirectory ? join(relativeDirectory, entry.name) : entry.name;\n const path = join(directory, entry.name);\n hash.update(relativePath.replaceAll('\\\\', '/'));\n hash.update('\\0');\n if (entry.isDirectory()) {\n hash.update('directory\\0');\n visit(path, relativePath);\n } else if (entry.isSymbolicLink()) {\n hash.update('symlink\\0');\n hash.update(readlinkSync(path));\n } else if (entry.isFile()) {\n hash.update('file\\0');\n hash.update(readFileSync(path));\n } else {\n hash.update('other\\0');\n }\n hash.update('\\0');\n }\n };\n visit(root);\n return hash.digest('hex');\n}\n\nfunction expectedBuildFingerprint(build: Omit<LineageRuntimeBuildIdentity, 'build_fingerprint'>): string {\n return sha256(JSON.stringify({\n package_name: build.package_name,\n package_version: build.package_version,\n schema_version: build.schema_version,\n source_dirty: build.source_dirty,\n source_fingerprint: build.source_fingerprint,\n source_git_sha: build.source_git_sha,\n }));\n}\n\nfunction validateBuild(root: string, installed: { name: string; version: string }): LineageRuntimeBuildIdentity {\n const path = join(root, 'dist', 'runtime-build.json');\n const build = JSON.parse(readFileSync(path, 'utf8')) as LineageRuntimeBuildIdentity;\n if (build.schema_version !== lineageRuntimeBuildSchemaVersion) throw new Error(`Unsupported build identity schema in ${path}`);\n if (build.package_name !== installed.name || build.package_version !== installed.version) throw new Error('Embedded build identity does not match installed package.json');\n if (!/^[a-f0-9]{40}$/i.test(build.source_git_sha)) throw new Error('Embedded build Git revision is invalid');\n if (!/^[a-f0-9]{64}$/i.test(build.source_fingerprint)) throw new Error('Embedded source fingerprint is invalid');\n if (build.build_fingerprint !== expectedBuildFingerprint(build)) throw new Error('Embedded build fingerprint does not match its contents');\n if (build.source_dirty) throw new Error('Refusing stable/preview installation of a dirty-source build');\n return build;\n}\n\nexport function parseRegistryPackageMetadata(value: unknown): { integrity: string; version: string } {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('npm metadata was not a JSON object');\n }\n const metadata = value as RegistryPackageMetadata;\n const nestedIntegrity = metadata.dist?.integrity;\n const flatIntegrity = metadata['dist.integrity'];\n if (\n typeof nestedIntegrity === 'string'\n && typeof flatIntegrity === 'string'\n && nestedIntegrity !== flatIntegrity\n ) {\n throw new Error('npm metadata returned conflicting integrity values');\n }\n const integrity = typeof nestedIntegrity === 'string' ? nestedIntegrity : flatIntegrity;\n if (typeof metadata.version !== 'string' || !metadata.version || typeof integrity !== 'string' || !integrity) {\n throw new Error('npm metadata did not include exact version and integrity');\n }\n return { integrity, version: metadata.version };\n}\n\nfunction resolveSpec(spec: string, allowLocalPackage: boolean): ResolvedPackageSpec {\n const localPath = resolve(spec.replace(/^file:/, ''));\n if (existsSync(localPath)) {\n if (!allowLocalPackage) {\n throw new Error('Local package paths require --allow-local-package; normal stable/preview installs must resolve from the npm registry');\n }\n return {\n installSpec: localPath,\n integrity: `sha512-${createHash('sha512').update(readFileSync(localPath)).digest('base64')}`,\n requestedSpec: spec,\n source: 'local',\n };\n }\n let metadata: { integrity: string; version: string };\n try {\n metadata = parseRegistryPackageMetadata(JSON.parse(execFileSync('npm', ['view', spec, 'version', 'dist.integrity', '--json'], { encoding: 'utf8' })));\n } catch (error) {\n throw new Error(`npm metadata for ${spec} did not include exact version and integrity`, { cause: error });\n }\n const name = spec.startsWith('@') ? spec.slice(0, spec.indexOf('@', 1)) : spec.split('@')[0];\n return {\n installSpec: `${name}@${metadata.version}`,\n integrity: metadata.integrity,\n expectedVersion: metadata.version,\n requestedSpec: spec,\n source: 'registry',\n };\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\nfunction writeShim(path: string, channel: PublishedChannel, receiptPath: string, entrypoint: string): void {\n const tempPath = `${path}.tmp-${process.pid}`;\n const script = `#!/bin/sh\\nLINEAGE_RUNTIME_RECEIPT=${shellQuote(receiptPath)} LINEAGE_RELEASE_CHANNEL=${shellQuote(channel)} exec ${shellQuote(process.execPath)} ${shellQuote(entrypoint)} \"$@\"\\n`;\n writeFileSync(tempPath, script, { mode: 0o755 });\n chmodSync(tempPath, 0o755);\n renameSync(tempPath, path);\n}\n\nfunction validateExistingReceipt(\n receiptPath: string,\n channel: PublishedChannel,\n expected?: { build: LineageRuntimeBuildIdentity; integrity: string; packageRoot: string; source: ResolvedPackageSpec['source']; version: string },\n): LineageRuntimeInstallReceipt {\n const receipt = JSON.parse(readFileSync(receiptPath, 'utf8')) as LineageRuntimeInstallReceipt;\n if (receipt.schema_version !== lineageRuntimeInstallSchemaVersion || receipt.channel !== channel) throw new Error(`Invalid existing ${channel} runtime receipt`);\n const installed = JSON.parse(readFileSync(join(receipt.package_root, 'package.json'), 'utf8')) as { name: string; version: string };\n const build = validateBuild(receipt.package_root, installed);\n if (receipt.package_name !== installed.name || receipt.package_version !== installed.version) throw new Error(`Existing ${channel} receipt does not match package.json`);\n if (receipt.build_fingerprint !== build.build_fingerprint) throw new Error(`Existing ${channel} receipt does not match embedded build identity`);\n if (packageTreeSha256(receipt.package_root) !== receipt.package_tree_sha256) throw new Error(`Existing ${channel} runtime package tree has changed`);\n if (expected && (\n receipt.package_integrity !== expected.integrity\n || receipt.package_root !== expected.packageRoot\n || receipt.package_source !== expected.source\n || receipt.package_version !== expected.version\n || receipt.build_fingerprint !== expected.build.build_fingerprint\n )) {\n throw new Error(`Existing ${channel} runtime receipt does not match the freshly resolved package`);\n }\n return receipt;\n}\n\nfunction install(channel: PublishedChannel, args: string[]): LineageRuntimeInstallReceipt & { receipt_path: string; service_shim: string; shim: string } {\n const root = resolve(readOption(args, '--root') || runtimeRoot());\n const shimDir = resolve(readOption(args, '--shim-dir') || join(root, 'bin'));\n const requestedSpec = readOption(args, '--package') || `${packageInfo.name}@${channel === 'stable' ? 'latest' : 'next'}`;\n const resolvedSpec = resolveSpec(requestedSpec, args.includes('--allow-local-package'));\n const channelRoot = join(root, 'installs', channel);\n mkdirSync(channelRoot, { recursive: true });\n const stagingRoot = mkdtempSync(join(channelRoot, '.staging-'));\n let keepStaging = false;\n try {\n execFileSync('npm', [\n 'install', '--prefix', stagingRoot, '--ignore-scripts', '--no-audit', '--no-fund', '--package-lock=false', resolvedSpec.installSpec,\n ], { stdio: 'ignore' });\n const stagingPackageRoot = join(stagingRoot, 'node_modules', ...packageInfo.name.split('/'));\n const installed = JSON.parse(readFileSync(join(stagingPackageRoot, 'package.json'), 'utf8')) as { name: string; version: string };\n if (installed.name !== packageInfo.name) throw new Error(`Installed unexpected package ${installed.name}`);\n if (resolvedSpec.expectedVersion && installed.version !== resolvedSpec.expectedVersion) throw new Error(`Installed ${installed.version}, expected ${resolvedSpec.expectedVersion}`);\n const build = validateBuild(stagingPackageRoot, installed);\n const installId = `${installed.version}-${sha256(resolvedSpec.integrity).slice(0, 16)}`;\n const finalRoot = join(channelRoot, installId);\n const finalPackageRoot = join(finalRoot, 'node_modules', ...packageInfo.name.split('/'));\n const receiptPath = join(finalRoot, 'lineage-runtime-receipt.json');\n let receipt: LineageRuntimeInstallReceipt;\n if (existsSync(finalRoot)) {\n receipt = validateExistingReceipt(receiptPath, channel, {\n build,\n integrity: resolvedSpec.integrity,\n packageRoot: finalPackageRoot,\n source: resolvedSpec.source,\n version: installed.version,\n });\n } else {\n const packageTree = packageTreeSha256(stagingPackageRoot);\n renameSync(stagingRoot, finalRoot);\n keepStaging = true;\n receipt = {\n build_fingerprint: build.build_fingerprint,\n channel,\n installed_at: new Date().toISOString(),\n package_integrity: resolvedSpec.integrity,\n package_name: installed.name,\n package_root: finalPackageRoot,\n package_source: resolvedSpec.source,\n package_spec: resolvedSpec.requestedSpec,\n package_tree_sha256: packageTree,\n package_version: installed.version,\n schema_version: lineageRuntimeInstallSchemaVersion,\n };\n writeFileSync(receiptPath, `${JSON.stringify(receipt, null, 2)}\\n`, { mode: 0o600 });\n }\n mkdirSync(shimDir, { recursive: true });\n const shim = join(shimDir, channel === 'stable' ? 'lineage-stable' : 'lineage-preview');\n const entrypoint = join(finalPackageRoot, 'dist', 'cli', channel === 'stable' ? 'lineage.js' : 'lineage-preview.js');\n if (!existsSync(entrypoint)) throw new Error(`Installed package is missing ${entrypoint}`);\n writeShim(shim, channel, receiptPath, entrypoint);\n const serviceShim = join(shimDir, channel === 'stable' ? 'lineage-stable-service' : 'lineage-preview-service');\n const serviceEntrypoint = join(finalPackageRoot, 'dist', 'cli', 'managed-service.js');\n if (!existsSync(serviceEntrypoint)) throw new Error(`Installed package is missing ${serviceEntrypoint}`);\n writeShim(serviceShim, channel, receiptPath, serviceEntrypoint);\n const pointerDir = join(root, 'channels');\n mkdirSync(pointerDir, { recursive: true });\n writeFileSync(join(pointerDir, `${channel}.json`), `${JSON.stringify({ channel, receipt_path: receiptPath, service_shim: serviceShim, shim }, null, 2)}\\n`, { mode: 0o600 });\n return { ...receipt, receipt_path: receiptPath, service_shim: serviceShim, shim };\n } finally {\n if (!keepStaging) rmSync(stagingRoot, { force: true, recursive: true });\n }\n}\n\nfunction status(args: string[]): unknown {\n const root = resolve(readOption(args, '--root') || runtimeRoot());\n return Object.fromEntries((['stable', 'preview'] as const).map(channel => {\n const pointerPath = join(root, 'channels', `${channel}.json`);\n if (!existsSync(pointerPath)) return [channel, { installed: false }];\n try {\n const pointer = JSON.parse(readFileSync(pointerPath, 'utf8')) as { receipt_path: string; service_shim: string; shim: string };\n const receipt = validateExistingReceipt(pointer.receipt_path, channel);\n if (!existsSync(pointer.shim) || !existsSync(pointer.service_shim)) throw new Error(`Existing ${channel} runtime shims are missing`);\n return [channel, { installed: true, receipt, receipt_path: pointer.receipt_path, service_shim: pointer.service_shim, shim: pointer.shim }];\n } catch (error) {\n return [channel, { error: error instanceof Error ? error.message : String(error), installed: false }];\n }\n }));\n}\n\nfunction usage(): string {\n return `lineage-channel ${packageInfo.version}\n\nUsage:\n lineage-channel install stable [--root <path>] [--shim-dir <path>] [--package <npm-spec>] [--json]\n lineage-channel install preview [--root <path>] [--shim-dir <path>] [--package <npm-spec>] [--json]\n lineage-channel status [--root <path>] [--json]\n\nStable and preview are installed into separate content-addressed roots. Dev is\ncheckout-only and is started with npm run lineage:dev -- <command>. Local\ntarballs are refused unless --allow-local-package is supplied explicitly.`;\n}\n\nfunction print(value: unknown, json: boolean): void {\n if (json) console.log(JSON.stringify(value, null, 2));\n else if (value && typeof value === 'object' && 'shim' in value) {\n const installed = value as { channel: string; package_version: string; service_shim: string; shim: string };\n console.log(`Installed Lineage ${installed.channel} ${installed.package_version}`);\n console.log(`Launcher: ${installed.shim}`);\n console.log(`Service manager: ${installed.service_shim}`);\n } else console.log(JSON.stringify(value, null, 2));\n}\n\nexport function runLineageChannel(args = process.argv.slice(2)): void {\n const json = args.includes('--json');\n try {\n if (args.length === 0 || args.includes('--help') || args.includes('-h')) {\n console.log(usage());\n } else if (args.includes('--version') || args.includes('-v')) {\n console.log(packageInfo.version);\n } else if (args[0] === 'install') {\n print(install(parseChannel(args[1] || readOption(args, '--channel')), args.slice(2)), json);\n } else if (args[0] === 'status') {\n print(status(args.slice(1)), json);\n } else {\n throw new Error(`Unknown lineage-channel command: ${args[0]}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) console.error(JSON.stringify({ error: message, ok: false }, null, 2));\n else console.error(`lineage-channel: ${message}`);\n process.exitCode = 1;\n }\n}\n\nif (process.argv[1] && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) runLineageChannel();\n", "export type LineageRuntimeChannel = 'stable' | 'preview' | 'dev';\n\nexport const lineageRuntimeBuildSchemaVersion = 'lineage.runtime_build.v1' as const;\nexport const lineageRuntimeInstallSchemaVersion = 'lineage.runtime_install.v1' as const;\n\ntype LineageRuntimeEnvironment = 'production' | 'preview' | 'development';\n\ninterface LineageRuntimeDatabaseInfo {\n error?: string;\n exists: boolean;\n modified_at?: string;\n path: string;\n projects?: number;\n size_bytes?: number;\n workspaces?: number;\n}\n\ninterface LineageRuntimeProfileInfo {\n bound: boolean;\n environment: LineageRuntimeEnvironment;\n fingerprint?: string;\n id: string;\n manifest_path?: string;\n service_origin?: string;\n warning?: string;\n}\n\ninterface LineageRuntimeSchemaInfo {\n migration_keys: string[];\n profile_environment?: LineageRuntimeEnvironment;\n profile_fingerprint?: string;\n profile_id?: string;\n}\n\nexport interface LineageRuntimeBuildIdentity {\n build_fingerprint: string;\n package_name: string;\n package_version: string;\n schema_version: typeof lineageRuntimeBuildSchemaVersion;\n source_dirty: boolean;\n source_fingerprint: string;\n source_git_sha: string;\n}\n\nexport interface LineageRuntimeInstallReceipt {\n build_fingerprint: string;\n channel: Exclude<LineageRuntimeChannel, 'dev'>;\n installed_at: string;\n package_integrity: string;\n package_name: string;\n package_root: string;\n package_source: 'local' | 'registry';\n package_spec: string;\n package_tree_sha256: string;\n package_version: string;\n schema_version: typeof lineageRuntimeInstallSchemaVersion;\n}\n\nexport interface LineageRuntimeCodeIdentity {\n build?: LineageRuntimeBuildIdentity;\n channel: LineageRuntimeChannel;\n dirty?: boolean;\n errors: string[];\n fingerprint: string;\n git_sha?: string;\n install?: LineageRuntimeInstallReceipt & { receipt_path: string };\n origin: 'checkout' | 'package' | 'unknown';\n package_version: string;\n root: string;\n source_fingerprint?: string;\n verified: boolean;\n}\n\nexport interface LineageRuntimeInfo {\n asset_root: string;\n channel: LineageRuntimeChannel;\n code?: LineageRuntimeCodeIdentity;\n database: LineageRuntimeDatabaseInfo;\n fetchedAt: string;\n git_sha?: string;\n node_env?: string;\n package_name: string;\n profile: LineageRuntimeProfileInfo;\n schema: LineageRuntimeSchemaInfo;\n service?: {\n instance_id?: string;\n launcher_pid?: number;\n pid: number;\n started_at: string;\n };\n version: string;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { createHash } from 'node:crypto';\nimport { execFileSync } from 'node:child_process';\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n readdirSync,\n readlinkSync,\n realpathSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n lineageRuntimeBuildSchemaVersion,\n lineageRuntimeInstallSchemaVersion,\n type LineageRuntimeBuildIdentity,\n type LineageRuntimeInstallReceipt,\n} from '../shared/runtimeInfoTypes';\n\ntype PublishedChannel = 'stable' | 'preview';\ninterface ResolvedPackageSpec {\n expectedVersion?: string;\n installSpec: string;\n integrity: string;\n requestedSpec: string;\n source: LineageRuntimeInstallReceipt['package_source'];\n}\n\ninterface RegistryPackageMetadata {\n dist?: { integrity?: unknown };\n 'dist.integrity'?: unknown;\n version?: unknown;\n}\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');\nconst packageInfo = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')) as { name: string; version: string };\n\nfunction sha256(value: string | Buffer): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction readOption(args: string[], name: string): string | undefined {\n const inline = args.find(arg => arg.startsWith(`${name}=`));\n if (inline) return inline.slice(name.length + 1);\n const index = args.indexOf(name);\n return index >= 0 ? args[index + 1] : undefined;\n}\n\nfunction runtimeRoot(): string {\n if (process.env.LINEAGE_RUNTIME_ROOT) return resolve(process.env.LINEAGE_RUNTIME_ROOT);\n if (platform() === 'darwin') return join(homedir(), 'Library', 'Application Support', 'Lineage', 'runtimes');\n if (platform() === 'win32') return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Lineage', 'runtimes');\n return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'lineage', 'runtimes');\n}\n\nfunction globalNpmExecutableDirectory(): string {\n let prefix: string;\n try {\n prefix = execFileSync('npm', ['prefix', '--global'], { encoding: 'utf8' }).trim();\n } catch (error) {\n throw new Error('Could not locate the global npm executable directory; pass --shim-dir explicitly', { cause: error });\n }\n if (!prefix) throw new Error('npm returned an empty global prefix; pass --shim-dir explicitly');\n return platform() === 'win32' ? resolve(prefix) : resolve(prefix, 'bin');\n}\n\nfunction shimDirectory(args: string[], root: string): string {\n const explicit = readOption(args, '--shim-dir');\n if (explicit) return resolve(explicit);\n if (readOption(args, '--root') || process.env.LINEAGE_RUNTIME_ROOT) return join(root, 'bin');\n return globalNpmExecutableDirectory();\n}\n\nfunction parseChannel(value?: string): PublishedChannel {\n if (value === 'stable' || value === 'preview') return value;\n throw new Error('Channel must be stable or preview; dev is checkout-only');\n}\n\nfunction packageTreeSha256(root: string): string {\n const hash = createHash('sha256');\n const visit = (directory: string, relativeDirectory = '') => {\n for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {\n const relativePath = relativeDirectory ? join(relativeDirectory, entry.name) : entry.name;\n const path = join(directory, entry.name);\n hash.update(relativePath.replaceAll('\\\\', '/'));\n hash.update('\\0');\n if (entry.isDirectory()) {\n hash.update('directory\\0');\n visit(path, relativePath);\n } else if (entry.isSymbolicLink()) {\n hash.update('symlink\\0');\n hash.update(readlinkSync(path));\n } else if (entry.isFile()) {\n hash.update('file\\0');\n hash.update(readFileSync(path));\n } else {\n hash.update('other\\0');\n }\n hash.update('\\0');\n }\n };\n visit(root);\n return hash.digest('hex');\n}\n\nfunction expectedBuildFingerprint(build: Omit<LineageRuntimeBuildIdentity, 'build_fingerprint'>): string {\n return sha256(JSON.stringify({\n package_name: build.package_name,\n package_version: build.package_version,\n schema_version: build.schema_version,\n source_dirty: build.source_dirty,\n source_fingerprint: build.source_fingerprint,\n source_git_sha: build.source_git_sha,\n }));\n}\n\nfunction validateBuild(root: string, installed: { name: string; version: string }): LineageRuntimeBuildIdentity {\n const path = join(root, 'dist', 'runtime-build.json');\n const build = JSON.parse(readFileSync(path, 'utf8')) as LineageRuntimeBuildIdentity;\n if (build.schema_version !== lineageRuntimeBuildSchemaVersion) throw new Error(`Unsupported build identity schema in ${path}`);\n if (build.package_name !== installed.name || build.package_version !== installed.version) throw new Error('Embedded build identity does not match installed package.json');\n if (!/^[a-f0-9]{40}$/i.test(build.source_git_sha)) throw new Error('Embedded build Git revision is invalid');\n if (!/^[a-f0-9]{64}$/i.test(build.source_fingerprint)) throw new Error('Embedded source fingerprint is invalid');\n if (build.build_fingerprint !== expectedBuildFingerprint(build)) throw new Error('Embedded build fingerprint does not match its contents');\n if (build.source_dirty) throw new Error('Refusing stable/preview installation of a dirty-source build');\n return build;\n}\n\nexport function parseRegistryPackageMetadata(value: unknown): { integrity: string; version: string } {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('npm metadata was not a JSON object');\n }\n const metadata = value as RegistryPackageMetadata;\n const nestedIntegrity = metadata.dist?.integrity;\n const flatIntegrity = metadata['dist.integrity'];\n if (\n typeof nestedIntegrity === 'string'\n && typeof flatIntegrity === 'string'\n && nestedIntegrity !== flatIntegrity\n ) {\n throw new Error('npm metadata returned conflicting integrity values');\n }\n const integrity = typeof nestedIntegrity === 'string' ? nestedIntegrity : flatIntegrity;\n if (typeof metadata.version !== 'string' || !metadata.version || typeof integrity !== 'string' || !integrity) {\n throw new Error('npm metadata did not include exact version and integrity');\n }\n return { integrity, version: metadata.version };\n}\n\nfunction resolveSpec(spec: string, allowLocalPackage: boolean): ResolvedPackageSpec {\n const localPath = resolve(spec.replace(/^file:/, ''));\n if (existsSync(localPath)) {\n if (!allowLocalPackage) {\n throw new Error('Local package paths require --allow-local-package; normal stable/preview installs must resolve from the npm registry');\n }\n return {\n installSpec: localPath,\n integrity: `sha512-${createHash('sha512').update(readFileSync(localPath)).digest('base64')}`,\n requestedSpec: spec,\n source: 'local',\n };\n }\n let metadata: { integrity: string; version: string };\n try {\n metadata = parseRegistryPackageMetadata(JSON.parse(execFileSync('npm', ['view', spec, 'version', 'dist.integrity', '--json'], { encoding: 'utf8' })));\n } catch (error) {\n throw new Error(`npm metadata for ${spec} did not include exact version and integrity`, { cause: error });\n }\n const name = spec.startsWith('@') ? spec.slice(0, spec.indexOf('@', 1)) : spec.split('@')[0];\n return {\n installSpec: `${name}@${metadata.version}`,\n integrity: metadata.integrity,\n expectedVersion: metadata.version,\n requestedSpec: spec,\n source: 'registry',\n };\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\nfunction writeShim(\n path: string,\n channel: PublishedChannel,\n receiptPath: string,\n entrypoint: string,\n environment: Record<string, string> = {},\n): void {\n const tempPath = `${path}.tmp-${process.pid}`;\n const assignments = Object.entries(environment).map(([key, value]) => `${key}=${shellQuote(value)}`).join(' ');\n const script = `#!/bin/sh\\nLINEAGE_RUNTIME_RECEIPT=${shellQuote(receiptPath)} LINEAGE_RELEASE_CHANNEL=${shellQuote(channel)}${assignments ? ` ${assignments}` : ''} exec ${shellQuote(process.execPath)} ${shellQuote(entrypoint)} \"$@\"\\n`;\n writeFileSync(tempPath, script, { mode: 0o755 });\n chmodSync(tempPath, 0o755);\n renameSync(tempPath, path);\n}\n\nfunction validateExistingReceipt(\n receiptPath: string,\n channel: PublishedChannel,\n expected?: { build: LineageRuntimeBuildIdentity; integrity: string; packageRoot: string; source: ResolvedPackageSpec['source']; version: string },\n): LineageRuntimeInstallReceipt {\n const receipt = JSON.parse(readFileSync(receiptPath, 'utf8')) as LineageRuntimeInstallReceipt;\n if (receipt.schema_version !== lineageRuntimeInstallSchemaVersion || receipt.channel !== channel) throw new Error(`Invalid existing ${channel} runtime receipt`);\n const installed = JSON.parse(readFileSync(join(receipt.package_root, 'package.json'), 'utf8')) as { name: string; version: string };\n const build = validateBuild(receipt.package_root, installed);\n if (receipt.package_name !== installed.name || receipt.package_version !== installed.version) throw new Error(`Existing ${channel} receipt does not match package.json`);\n if (receipt.build_fingerprint !== build.build_fingerprint) throw new Error(`Existing ${channel} receipt does not match embedded build identity`);\n if (packageTreeSha256(receipt.package_root) !== receipt.package_tree_sha256) throw new Error(`Existing ${channel} runtime package tree has changed`);\n if (expected && (\n receipt.package_integrity !== expected.integrity\n || receipt.package_root !== expected.packageRoot\n || receipt.package_source !== expected.source\n || receipt.package_version !== expected.version\n || receipt.build_fingerprint !== expected.build.build_fingerprint\n )) {\n throw new Error(`Existing ${channel} runtime receipt does not match the freshly resolved package`);\n }\n return receipt;\n}\n\nfunction install(channel: PublishedChannel, args: string[]): LineageRuntimeInstallReceipt & { receipt_path: string; service_shim: string; shim: string } {\n const root = resolve(readOption(args, '--root') || runtimeRoot());\n const shimDir = shimDirectory(args, root);\n const requestedSpec = readOption(args, '--package') || `${packageInfo.name}@${channel === 'stable' ? 'latest' : 'next'}`;\n const resolvedSpec = resolveSpec(requestedSpec, args.includes('--allow-local-package'));\n const channelRoot = join(root, 'installs', channel);\n mkdirSync(channelRoot, { recursive: true });\n const stagingRoot = mkdtempSync(join(channelRoot, '.staging-'));\n let keepStaging = false;\n try {\n execFileSync('npm', [\n 'install', '--prefix', stagingRoot, '--ignore-scripts', '--no-audit', '--no-fund', '--package-lock=false', resolvedSpec.installSpec,\n ], { stdio: 'ignore' });\n const stagingPackageRoot = join(stagingRoot, 'node_modules', ...packageInfo.name.split('/'));\n const installed = JSON.parse(readFileSync(join(stagingPackageRoot, 'package.json'), 'utf8')) as { name: string; version: string };\n if (installed.name !== packageInfo.name) throw new Error(`Installed unexpected package ${installed.name}`);\n if (resolvedSpec.expectedVersion && installed.version !== resolvedSpec.expectedVersion) throw new Error(`Installed ${installed.version}, expected ${resolvedSpec.expectedVersion}`);\n const build = validateBuild(stagingPackageRoot, installed);\n const installId = `${installed.version}-${sha256(resolvedSpec.integrity).slice(0, 16)}`;\n const finalRoot = join(channelRoot, installId);\n const finalPackageRoot = join(finalRoot, 'node_modules', ...packageInfo.name.split('/'));\n const receiptPath = join(finalRoot, 'lineage-runtime-receipt.json');\n let receipt: LineageRuntimeInstallReceipt;\n if (existsSync(finalRoot)) {\n receipt = validateExistingReceipt(receiptPath, channel, {\n build,\n integrity: resolvedSpec.integrity,\n packageRoot: finalPackageRoot,\n source: resolvedSpec.source,\n version: installed.version,\n });\n } else {\n const packageTree = packageTreeSha256(stagingPackageRoot);\n renameSync(stagingRoot, finalRoot);\n keepStaging = true;\n receipt = {\n build_fingerprint: build.build_fingerprint,\n channel,\n installed_at: new Date().toISOString(),\n package_integrity: resolvedSpec.integrity,\n package_name: installed.name,\n package_root: finalPackageRoot,\n package_source: resolvedSpec.source,\n package_spec: resolvedSpec.requestedSpec,\n package_tree_sha256: packageTree,\n package_version: installed.version,\n schema_version: lineageRuntimeInstallSchemaVersion,\n };\n writeFileSync(receiptPath, `${JSON.stringify(receipt, null, 2)}\\n`, { mode: 0o600 });\n }\n mkdirSync(shimDir, { recursive: true });\n const shim = join(shimDir, channel === 'stable' ? 'lineage-stable' : 'lineage-preview');\n const entrypoint = join(finalPackageRoot, 'dist', 'cli', channel === 'stable' ? 'lineage.js' : 'lineage-preview.js');\n if (!existsSync(entrypoint)) throw new Error(`Installed package is missing ${entrypoint}`);\n writeShim(shim, channel, receiptPath, entrypoint);\n const serviceShim = join(shimDir, channel === 'stable' ? 'lineage-stable-service' : 'lineage-preview-service');\n const serviceEntrypoint = join(finalPackageRoot, 'dist', 'cli', 'managed-service.js');\n if (!existsSync(serviceEntrypoint)) throw new Error(`Installed package is missing ${serviceEntrypoint}`);\n writeShim(serviceShim, channel, receiptPath, serviceEntrypoint, { LINEAGE_CHANNEL_LAUNCHER: shim });\n const pointerDir = join(root, 'channels');\n mkdirSync(pointerDir, { recursive: true });\n writeFileSync(join(pointerDir, `${channel}.json`), `${JSON.stringify({ channel, receipt_path: receiptPath, service_shim: serviceShim, shim }, null, 2)}\\n`, { mode: 0o600 });\n return { ...receipt, receipt_path: receiptPath, service_shim: serviceShim, shim };\n } finally {\n if (!keepStaging) rmSync(stagingRoot, { force: true, recursive: true });\n }\n}\n\nfunction status(args: string[]): unknown {\n const root = resolve(readOption(args, '--root') || runtimeRoot());\n return Object.fromEntries((['stable', 'preview'] as const).map(channel => {\n const pointerPath = join(root, 'channels', `${channel}.json`);\n if (!existsSync(pointerPath)) return [channel, { installed: false }];\n try {\n const pointer = JSON.parse(readFileSync(pointerPath, 'utf8')) as { receipt_path: string; service_shim: string; shim: string };\n const receipt = validateExistingReceipt(pointer.receipt_path, channel);\n if (!existsSync(pointer.shim) || !existsSync(pointer.service_shim)) throw new Error(`Existing ${channel} runtime shims are missing`);\n return [channel, { installed: true, receipt, receipt_path: pointer.receipt_path, service_shim: pointer.service_shim, shim: pointer.shim }];\n } catch (error) {\n return [channel, { error: error instanceof Error ? error.message : String(error), installed: false }];\n }\n }));\n}\n\nfunction usage(): string {\n return `lineage-channel ${packageInfo.version}\n\nUsage:\n lineage-channel install stable [--root <path>] [--shim-dir <path>] [--package <npm-spec>] [--json]\n lineage-channel install preview [--root <path>] [--shim-dir <path>] [--package <npm-spec>] [--json]\n lineage-channel status [--root <path>] [--json]\n\nStable and preview are installed into separate content-addressed roots. Dev is\ncheckout-only and is started with npm run lineage:dev -- <command>. Local\ntarballs are refused unless --allow-local-package is supplied explicitly.\nDefault installs put launchers in npm's global executable directory, which is\nalready on PATH when lineage-channel is invoked. A custom --root keeps its\nlaunchers under <root>/bin unless --shim-dir is also supplied.`;\n}\n\nfunction print(value: unknown, json: boolean): void {\n if (json) console.log(JSON.stringify(value, null, 2));\n else if (value && typeof value === 'object' && 'shim' in value) {\n const installed = value as { channel: string; package_version: string; service_shim: string; shim: string };\n console.log(`Installed Lineage ${installed.channel} ${installed.package_version}`);\n console.log(`Launcher: ${installed.shim}`);\n console.log(`Service manager: ${installed.service_shim}`);\n } else console.log(JSON.stringify(value, null, 2));\n}\n\nexport function runLineageChannel(args = process.argv.slice(2)): void {\n const json = args.includes('--json');\n try {\n if (args.length === 0 || args.includes('--help') || args.includes('-h')) {\n console.log(usage());\n } else if (args.includes('--version') || args.includes('-v')) {\n console.log(packageInfo.version);\n } else if (args[0] === 'install') {\n print(install(parseChannel(args[1] || readOption(args, '--channel')), args.slice(2)), json);\n } else if (args[0] === 'status') {\n print(status(args.slice(1)), json);\n } else {\n throw new Error(`Unknown lineage-channel command: ${args[0]}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) console.error(JSON.stringify({ error: message, ok: false }, null, 2));\n else console.error(`lineage-channel: ${message}`);\n process.exitCode = 1;\n }\n}\n\nif (process.argv[1] && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) runLineageChannel();\n", "export type LineageRuntimeChannel = 'stable' | 'preview' | 'dev';\n\nexport const lineageRuntimeBuildSchemaVersion = 'lineage.runtime_build.v1' as const;\nexport const lineageRuntimeInstallSchemaVersion = 'lineage.runtime_install.v1' as const;\n\ntype LineageRuntimeEnvironment = 'production' | 'preview' | 'development';\n\ninterface LineageRuntimeDatabaseInfo {\n error?: string;\n exists: boolean;\n modified_at?: string;\n path: string;\n projects?: number;\n size_bytes?: number;\n workspaces?: number;\n}\n\ninterface LineageRuntimeProfileInfo {\n bound: boolean;\n environment: LineageRuntimeEnvironment;\n fingerprint?: string;\n id: string;\n manifest_path?: string;\n service_origin?: string;\n warning?: string;\n}\n\ninterface LineageRuntimeSchemaInfo {\n migration_keys: string[];\n profile_environment?: LineageRuntimeEnvironment;\n profile_fingerprint?: string;\n profile_id?: string;\n}\n\nexport interface LineageRuntimeBuildIdentity {\n build_fingerprint: string;\n package_name: string;\n package_version: string;\n schema_version: typeof lineageRuntimeBuildSchemaVersion;\n source_dirty: boolean;\n source_fingerprint: string;\n source_git_sha: string;\n}\n\nexport interface LineageRuntimeInstallReceipt {\n build_fingerprint: string;\n channel: Exclude<LineageRuntimeChannel, 'dev'>;\n installed_at: string;\n package_integrity: string;\n package_name: string;\n package_root: string;\n package_source: 'local' | 'registry';\n package_spec: string;\n package_tree_sha256: string;\n package_version: string;\n schema_version: typeof lineageRuntimeInstallSchemaVersion;\n}\n\nexport interface LineageRuntimeCodeIdentity {\n build?: LineageRuntimeBuildIdentity;\n channel: LineageRuntimeChannel;\n dirty?: boolean;\n errors: string[];\n fingerprint: string;\n git_sha?: string;\n install?: LineageRuntimeInstallReceipt & { receipt_path: string };\n origin: 'checkout' | 'package' | 'unknown';\n package_version: string;\n root: string;\n source_fingerprint?: string;\n verified: boolean;\n}\n\nexport interface LineageRuntimeInfo {\n asset_root: string;\n channel: LineageRuntimeChannel;\n code?: LineageRuntimeCodeIdentity;\n database: LineageRuntimeDatabaseInfo;\n fetchedAt: string;\n git_sha?: string;\n node_env?: string;\n package_name: string;\n process?: {\n pid: number;\n role: 'command' | 'service';\n started_at: string;\n };\n profile: LineageRuntimeProfileInfo;\n schema: LineageRuntimeSchemaInfo;\n service?: {\n instance_id?: string;\n mode: 'foreground' | 'managed';\n launcher_pid?: number;\n pid: number;\n started_at: string;\n };\n version: string;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|