linersh 0.5.7 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -159
- package/bin/liner.js +89 -44
- package/cli-update-docs/README.md +6 -6
- package/cli-update-docs/SKILL.md +72 -37
- package/cli-update-docs/quality-check-tests.md +256 -8
- package/cli-update-docs/source-finding-tactics.md +140 -3
- package/cli-update-docs/source-quality-hierarchy.md +83 -0
- package/cli-update-docs/synthesis-guidance.md +19 -5
- package/dist/agents/artifact-validation.js +440 -0
- package/dist/agents/artifact-validation.js.map +1 -0
- package/dist/agents/candidate-longlist.js +100 -0
- package/dist/agents/candidate-longlist.js.map +1 -0
- package/dist/agents/detect.js +3 -2
- package/dist/agents/detect.js.map +1 -1
- package/dist/agents/evaluation-assembly.js +270 -0
- package/dist/agents/evaluation-assembly.js.map +1 -0
- package/dist/agents/headless-runner.js +227 -0
- package/dist/agents/headless-runner.js.map +1 -0
- package/dist/agents/jtbd-clarify.js +42 -41
- package/dist/agents/jtbd-clarify.js.map +1 -1
- package/dist/agents/models.js +6 -7
- package/dist/agents/models.js.map +1 -1
- package/dist/agents/prompts.js +220 -20
- package/dist/agents/prompts.js.map +1 -1
- package/dist/agents/runner.js +462 -21
- package/dist/agents/runner.js.map +1 -1
- package/dist/phases.js +13 -13
- package/dist/phases.js.map +1 -1
- package/dist/source-inbox.js +297 -0
- package/dist/source-inbox.js.map +1 -0
- package/dist/version.js +3 -9
- package/dist/version.js.map +1 -1
- package/dist/yaml-io.js +42 -11
- package/dist/yaml-io.js.map +1 -1
- package/package.json +26 -23
- package/cli-update-docs/ABOUT.md +0 -69
- package/cli-update-docs/AI-HANDOFF.md +0 -241
- package/cli-update-docs/CURATION.md +0 -261
- package/cli-update-docs/JOB-STORY-MIGRATION.md +0 -99
- package/cli-update-docs/JTBD-MASTER-PROMPT-ABOUT.md +0 -133
- package/cli-update-docs/JTBD-MASTER-PROMPT.md +0 -147
- package/cli-update-docs/LINER-MASTER.md +0 -546
- package/cli-update-docs/MIXTAPE-FORMAT.md +0 -398
- package/cli-update-docs/PLATFORM.md +0 -210
- package/cli-update-docs/TUI-BACKLOG.md +0 -155
- package/dist/App.js +0 -220
- package/dist/App.js.map +0 -1
- package/dist/colors.js +0 -132
- package/dist/colors.js.map +0 -1
- package/dist/components/Header.js +0 -15
- package/dist/components/Header.js.map +0 -1
- package/dist/components/KeyHints.js +0 -17
- package/dist/components/KeyHints.js.map +0 -1
- package/dist/components/LabeledBox.js +0 -53
- package/dist/components/LabeledBox.js.map +0 -1
- package/dist/components/NextSteps.js +0 -18
- package/dist/components/NextSteps.js.map +0 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +0 -1
- package/dist/screens/AgentSetup.js +0 -224
- package/dist/screens/AgentSetup.js.map +0 -1
- package/dist/screens/BootSplash.js +0 -163
- package/dist/screens/BootSplash.js.map +0 -1
- package/dist/screens/CompileView.js +0 -567
- package/dist/screens/CompileView.js.map +0 -1
- package/dist/screens/FramingConfirmReview.js +0 -197
- package/dist/screens/FramingConfirmReview.js.map +0 -1
- package/dist/screens/Gate1Review.js +0 -147
- package/dist/screens/Gate1Review.js.map +0 -1
- package/dist/screens/Gate2Review.js +0 -162
- package/dist/screens/Gate2Review.js.map +0 -1
- package/dist/screens/ImportPrompt.js +0 -173
- package/dist/screens/ImportPrompt.js.map +0 -1
- package/dist/screens/JsSetup.js +0 -77
- package/dist/screens/JsSetup.js.map +0 -1
- package/dist/screens/LocalFilePicker.js +0 -139
- package/dist/screens/LocalFilePicker.js.map +0 -1
- package/dist/screens/NewMixtapeWizard.js +0 -662
- package/dist/screens/NewMixtapeWizard.js.map +0 -1
- package/dist/screens/PhaseRunner.js +0 -1203
- package/dist/screens/PhaseRunner.js.map +0 -1
- package/dist/screens/ProcessManifest.js +0 -160
- package/dist/screens/ProcessManifest.js.map +0 -1
- package/dist/screens/ProjectHub.js +0 -557
- package/dist/screens/ProjectHub.js.map +0 -1
- package/dist/screens/SourceModal.js +0 -269
- package/dist/screens/SourceModal.js.map +0 -1
- package/dist/screens/TapeBrowser.js +0 -312
- package/dist/screens/TapeBrowser.js.map +0 -1
- package/dist/screens/TapeDraftReview.js +0 -444
- package/dist/screens/TapeDraftReview.js.map +0 -1
- package/dist/screens/TapeEditor.js +0 -310
- package/dist/screens/TapeEditor.js.map +0 -1
- package/dist/screens/cassette-art.js +0 -72
- package/dist/screens/cassette-art.js.map +0 -1
- package/dist/store.js +0 -10
- package/dist/store.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,197 +1,122 @@
|
|
|
1
|
-
# Liner
|
|
1
|
+
# Liner NPM Shim And Runner Package
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package is still named `linersh` because it owns the published `liner`
|
|
4
|
+
binary. It is no longer the React/Ink TUI implementation.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Active responsibilities:
|
|
7
|
+
|
|
8
|
+
- `bin/liner.js`: npm binary shim
|
|
9
|
+
- Go TUI launcher for `packages/go-tui/` in development
|
|
10
|
+
- TypeScript headless methodology runner under `src/agents/`
|
|
11
|
+
- packaged curation skill bundle copied from `../../docs/curation-skill/` into
|
|
12
|
+
`cli-update-docs/`
|
|
13
|
+
- optional per-platform packages that contain the native CLI and Go TUI
|
|
14
|
+
binaries for installed users
|
|
15
|
+
|
|
16
|
+
The old React/Ink TUI has been decommissioned and is no longer part of the
|
|
17
|
+
active package shape. `LINER_TUI=ink` intentionally fails with a decommissioning
|
|
18
|
+
message.
|
|
6
19
|
|
|
7
20
|
## Install
|
|
8
21
|
|
|
9
22
|
```sh
|
|
10
|
-
# One-shot:
|
|
11
23
|
npx linersh
|
|
12
|
-
|
|
13
|
-
# Persistent:
|
|
14
|
-
npm install -g linersh # adds `liner` to PATH
|
|
24
|
+
npm install -g linersh
|
|
15
25
|
liner
|
|
16
26
|
```
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
With no arguments, `liner` launches the Go TUI. CLI subcommands such as
|
|
29
|
+
`liner compile`, `liner share`, `liner import`, `liner status`, and
|
|
30
|
+
`liner setup-js` pass through to the Python core. If you are using one-shot
|
|
31
|
+
`npx` instead of a global install, pass subcommands through the package:
|
|
32
|
+
`npx --yes linersh@latest setup-js` or
|
|
33
|
+
`npx --yes linersh@latest uninstall --yes`.
|
|
19
34
|
|
|
20
|
-
|
|
35
|
+
## Try It Cleanly
|
|
21
36
|
|
|
22
|
-
|
|
23
|
-
liner setup-js
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
That command is idempotent and downloads the Playwright browser used for `render: js` and automatic JS-wall fallback (about 150MB). The TUI also offers this during first-run onboarding, and again from compile results if a source needs JS rendering. For debugging or local development, `LINER_BIN=/path/to/liner liner` overrides the bundled binary.
|
|
27
|
-
|
|
28
|
-
To reset a machine for clean testing, run:
|
|
37
|
+
For a regular-user smoke test without touching your real Liner workspace:
|
|
29
38
|
|
|
30
39
|
```sh
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
tmp=$(mktemp -d)
|
|
41
|
+
home="$tmp/home"
|
|
42
|
+
cache="$tmp/npm-cache"
|
|
43
|
+
projects="$tmp/projects"
|
|
44
|
+
mkdir -p "$home" "$cache" "$projects"
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
HOME="$home" npm_config_cache="$cache" LINER_DIR="$projects" npx --yes linersh@latest --version
|
|
47
|
+
HOME="$home" npm_config_cache="$cache" LINER_DIR="$projects" npx --yes linersh@latest
|
|
37
48
|
|
|
38
|
-
|
|
39
|
-
cd ~/projects/my-thing
|
|
40
|
-
liner
|
|
49
|
+
rm -rf "$tmp"
|
|
41
50
|
```
|
|
42
51
|
|
|
43
|
-
The
|
|
52
|
+
The second command opens the Go TUI. Create a test Liner Project, build the
|
|
53
|
+
corpus with your configured local Claude or Codex runner, then run Create
|
|
54
|
+
Operating Layer. Because `HOME`, the npm cache, and `LINER_DIR` all point inside
|
|
55
|
+
`$tmp`, cleanup is just `rm -rf "$tmp"`.
|
|
56
|
+
|
|
57
|
+
## Run Locally
|
|
44
58
|
|
|
45
|
-
|
|
59
|
+
From the repo root:
|
|
46
60
|
|
|
47
61
|
```sh
|
|
48
|
-
|
|
62
|
+
npm --prefix packages/tui run dev
|
|
49
63
|
```
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### Browser
|
|
54
|
-
| Key | Action |
|
|
55
|
-
|---|---|
|
|
56
|
-
| `↑` `↓` or `j` `k` | move selection |
|
|
57
|
-
| `enter` or `o` | open the selected mixtape hub |
|
|
58
|
-
| `e` | open the selected mixtape source editor |
|
|
59
|
-
| `n` | new mixtape (prompts for slug) |
|
|
60
|
-
| `c` | compile selected |
|
|
61
|
-
| `s` | share selected (zip to `.mixtape`) |
|
|
62
|
-
| `i` | import a `.mixtape` archive |
|
|
63
|
-
| `d` | delete selected folder (with confirm) |
|
|
64
|
-
| `r` | refresh |
|
|
65
|
-
| `q` | quit |
|
|
66
|
-
|
|
67
|
-
### Project Hub
|
|
68
|
-
| Key | Action |
|
|
69
|
-
|---|---|
|
|
70
|
-
| `↑` `↓` | select phase |
|
|
71
|
-
| `enter` | run/open the selected phase's primary action |
|
|
72
|
-
| `e` | edit the selected artifact by hand |
|
|
73
|
-
| `p` | open the process manifest |
|
|
74
|
-
| `s` | share the mixtape |
|
|
75
|
-
| `o` | open the project folder |
|
|
76
|
-
| `esc` | back |
|
|
77
|
-
| `q` | quit |
|
|
78
|
-
|
|
79
|
-
Completed mixtapes land in a ready state. If `MIXTAPE.md` is current, pressing `enter` on Compile opens the existing compile result instead of fetching sources again. Press `r` from the compile result screen to explicitly re-run/retry.
|
|
80
|
-
|
|
81
|
-
### Source Editor
|
|
82
|
-
| Key | Action |
|
|
83
|
-
|---|---|
|
|
84
|
-
| `t` `d` `u` | edit title / description / curator |
|
|
85
|
-
| `m` | toggle mode (`quick` ⇄ `methodology`) |
|
|
86
|
-
| `g` | edit JTBD (job-to-be-done) |
|
|
87
|
-
| `E` | open `synthesis.md` in `$EDITOR` |
|
|
88
|
-
| `↑` `↓` | select source |
|
|
89
|
-
| `a` `e` `x` | add / edit / remove source |
|
|
90
|
-
| `K` `J` | reorder selected source up/down |
|
|
91
|
-
| `s` | save `tape.yaml` |
|
|
92
|
-
| `c` | save + compile (blocked if synthesis is empty or still a placeholder) |
|
|
93
|
-
| `esc` | back (warns on unsaved changes) |
|
|
94
|
-
|
|
95
|
-
A soft warning appears when any source is missing a curator note. Notes are load-bearing — see [CURATION.md](https://liner.sh) §6.
|
|
96
|
-
|
|
97
|
-
#### Local sources
|
|
98
|
-
|
|
99
|
-
`local_file` sources reference content you've placed under `<project>/personal/` — book chapter PDFs, Reader-Mode-saved articles, exported HIG pages. Use them for material that isn't on the public web or that lives behind a paywall you have legitimate access to.
|
|
100
|
-
|
|
101
|
-
Workflow:
|
|
102
|
-
|
|
103
|
-
1. Save the file into `<project>/personal/`. The TUI creates the folder lazily — the file picker offers a "new file (paste path)" option that you can use after saving the file manually with your OS file manager.
|
|
104
|
-
2. Add a source in the editor; press `T` in the source modal to switch the type to `local_file`.
|
|
105
|
-
3. Pick the file via the picker; supply a `citation` (author, title, publication, date — the AI uses this to weight the source).
|
|
106
|
-
4. Compile. The CLI extracts the content (PDFs via `pdfplumber`, HTML via the same readability pipeline as web sources, `.md`/`.txt` as-is).
|
|
107
|
-
|
|
108
|
-
`liner share` includes `personal/` by default. Pass `--no-personal` (or use the corresponding TUI flag) to exclude it — required for any tape intended as a library submission.
|
|
109
|
-
|
|
110
|
-
The synthesis indicator shows one of:
|
|
111
|
-
- `✗ missing` — `liner compile` will hard-fail
|
|
112
|
-
- `⚠ placeholder` — file exists but still has the boilerplate from `liner init`
|
|
113
|
-
- `⚠ empty` — file exists but is empty
|
|
114
|
-
- `✓ N chars` — ready to compile
|
|
115
|
-
|
|
116
|
-
### Source modal
|
|
117
|
-
| Key | Action |
|
|
118
|
-
|---|---|
|
|
119
|
-
| `↑` `↓` | move between fields |
|
|
120
|
-
| `enter` | edit the focused field (or open the file picker on the path field for `local_file` sources) |
|
|
121
|
-
| `tab` | next field while editing |
|
|
122
|
-
| `T` | toggle source type (`web` ⇄ `local_file`) |
|
|
123
|
-
| `R` | toggle `render: server` ⇄ `render: js` (web sources only) |
|
|
124
|
-
| `p` | toggle required/optional |
|
|
125
|
-
| `s` | save source |
|
|
126
|
-
| `esc` | cancel |
|
|
127
|
-
|
|
128
|
-
For `web` sources the URL is the load-bearing field; the type is auto-detected as `youtube` or `web`. For `local_file` sources the modal shows `path`, `citation`, `note`, `section`, `priority` — pick the path via the file picker (lists files under `personal/`, with a "paste path" affordance for new files).
|
|
129
|
-
|
|
130
|
-
### Compile
|
|
131
|
-
| Key | Action |
|
|
132
|
-
|---|---|
|
|
133
|
-
| `↑` `↓` | scroll sources |
|
|
134
|
-
| `pgup` `pgdn` | jump through sources |
|
|
135
|
-
| `j` | install JS rendering support when the result says it is needed |
|
|
136
|
-
| `esc` | cancel running compile |
|
|
137
|
-
| `y` | copy compiled `MIXTAPE.md` to clipboard (`pbcopy` / `xclip`) |
|
|
138
|
-
| `s` | share the compiled mixtape (zip to `.mixtape`) |
|
|
139
|
-
| `o` | open the project folder |
|
|
140
|
-
| `r` | retry failed sources / re-run compile |
|
|
141
|
-
| `b` | back to hub |
|
|
142
|
-
| `q` | quit |
|
|
143
|
-
|
|
144
|
-
The compile writes `MIXTAPE.md` and `sources/NN-<slug>.md` files directly into the project folder. A partial compile is still treated as a usable finished state when `MIXTAPE.md` is written; the hub shows "compiled with warnings" and the compile result screen lists the remaining warnings. There's nothing to "save" afterwards — the artifacts are already on disk.
|
|
145
|
-
|
|
146
|
-
## Uninstalling
|
|
147
|
-
|
|
148
|
-
The TUI ships in the same `linersh` package as the CLI. For npm/npx installs, use the package uninstaller:
|
|
65
|
+
From this package:
|
|
149
66
|
|
|
150
67
|
```sh
|
|
151
|
-
|
|
152
|
-
liner uninstall --yes
|
|
68
|
+
npm run dev
|
|
153
69
|
```
|
|
154
70
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
## Develop
|
|
71
|
+
Override the projects folder:
|
|
158
72
|
|
|
159
73
|
```sh
|
|
160
|
-
|
|
161
|
-
npm install
|
|
162
|
-
npm run dev # tsx (no watch — Ctrl+C and re-run after code changes)
|
|
163
|
-
npm run dev:built # builds, then runs the compiled output (closer to ship)
|
|
164
|
-
npm run typecheck
|
|
165
|
-
npm test # vitest
|
|
166
|
-
npm run build # emits dist/
|
|
74
|
+
LINER_DIR=/path/to/projects node bin/liner.js
|
|
167
75
|
```
|
|
168
76
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
In dev, the bin-resolver tries `LINER_BIN`, the bundled optional package, the repo-local `.venv/bin/liner`, then `liner` on `$PATH`. To point at a specific binary:
|
|
77
|
+
Override the Python/core binary:
|
|
172
78
|
|
|
173
79
|
```sh
|
|
174
|
-
LINER_BIN=/path/to/liner
|
|
80
|
+
LINER_BIN=/absolute/path/to/liner node bin/liner.js
|
|
175
81
|
```
|
|
176
82
|
|
|
177
|
-
##
|
|
83
|
+
## Build And Test
|
|
178
84
|
|
|
85
|
+
```sh
|
|
86
|
+
npm run build
|
|
87
|
+
npm run build:go
|
|
88
|
+
npm run build:package
|
|
89
|
+
npm test
|
|
179
90
|
```
|
|
180
|
-
BootSplash ─────► TapeBrowser ──────► ProjectHub ──────┐
|
|
181
|
-
│ │
|
|
182
|
-
│ ImportPrompt ─────┤
|
|
183
|
-
│ │
|
|
184
|
-
├────► NewProjectWizard ─────┤
|
|
185
|
-
│ │
|
|
186
|
-
├────► TapeEditor ⇄ SourceModal
|
|
187
|
-
│ │
|
|
188
|
-
├────► PhaseRunner / gates / draft review
|
|
189
|
-
│ │
|
|
190
|
-
└────► CompileView (streams NDJSON from `liner compile --emit-events`)
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
State is global via `AppContext`. YAML is parsed and re-written in Node via the `yaml` package's `Document` API so user-written block comments survive edits. All folder operations (`init`, `compile`, `share`, `import`, `list`) go through the Python CLI as subprocesses — the TUI never reimplements them.
|
|
194
|
-
|
|
195
|
-
The CLI's `compile --emit-events` streams NDJSON progress events to stdout; the TUI parses each line and updates per-source state live. The final `result` event reports the produced folder, `MIXTAPE.md` path, and per-source file paths.
|
|
196
91
|
|
|
197
|
-
|
|
92
|
+
Notes:
|
|
93
|
+
|
|
94
|
+
- `build` compiles the TypeScript headless runner and shared runner utilities.
|
|
95
|
+
- `build:go` compiles `../go-tui/cmd/liner-tui` into `bin/liner-tui` for local
|
|
96
|
+
development.
|
|
97
|
+
- `build:package` runs both.
|
|
98
|
+
- Release packaging is verified with `npm run acceptance:go -- release-smoke`,
|
|
99
|
+
which packs a local platform package plus the main `linersh` package and
|
|
100
|
+
installs both into a clean consumer project.
|
|
101
|
+
|
|
102
|
+
## Useful Environment Variables
|
|
103
|
+
|
|
104
|
+
- `LINER_DIR=/path/to/projects`: change the projects folder.
|
|
105
|
+
- `LINER_BIN=/path/to/liner`: force the Python/core binary.
|
|
106
|
+
- `LINER_GO_TUI_BIN=/path/to/liner-tui`: force the Go TUI binary.
|
|
107
|
+
- `LINER_HEADLESS_RUNNER=/path/to/headless-runner.js`: force the methodology
|
|
108
|
+
runner script.
|
|
109
|
+
- `LINER_AGENT=codex|claude`: override the agent selected by Liner config.
|
|
110
|
+
- `LINER_TUI=go`: accepted for compatibility, but no longer required.
|
|
111
|
+
|
|
112
|
+
## Developer Gotchas
|
|
113
|
+
|
|
114
|
+
- Rebuild `bin/liner-tui` after Go changes or the npm shim may launch an older
|
|
115
|
+
binary.
|
|
116
|
+
- Rebuild `dist/` after TypeScript runner changes or methodology will fail.
|
|
117
|
+
- The published main package intentionally excludes `bin/liner-tui`; installed
|
|
118
|
+
users get the native TUI from `linersh-<platform>-<arch>`.
|
|
119
|
+
- If Project Health says `status failed`, check the resolved core. Older bundled
|
|
120
|
+
cores may reject `--no-write`; the Go wrapper has a fallback, but direct
|
|
121
|
+
`node bin/liner.js status ... --no-write` can still fail until platform cores
|
|
122
|
+
are refreshed.
|
package/bin/liner.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Entry shim for `npx linersh` / `liner`.
|
|
3
3
|
//
|
|
4
|
-
// No args: launch the
|
|
4
|
+
// No args: launch the selected TUI.
|
|
5
|
+
// unset -> launch the Charm Go TUI
|
|
6
|
+
// LINER_TUI=go -> launch the Charm Go TUI explicitly
|
|
5
7
|
// CLI args: forward to the bundled Python core (or LINER_BIN/dev fallback).
|
|
6
8
|
//
|
|
7
9
|
// This lets the npm package expose one binary name while still supporting
|
|
@@ -41,6 +43,7 @@ const CLI_COMMANDS = new Set([
|
|
|
41
43
|
"clone",
|
|
42
44
|
"setup-js",
|
|
43
45
|
"list",
|
|
46
|
+
"skills",
|
|
44
47
|
"cache",
|
|
45
48
|
"manifest",
|
|
46
49
|
"status",
|
|
@@ -66,44 +69,69 @@ if (wantsCli(argv)) {
|
|
|
66
69
|
process.exit(code ?? 1);
|
|
67
70
|
});
|
|
68
71
|
} else {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
// Only enter alt-screen on a real TTY; piped/redirected stdout shouldn't
|
|
82
|
-
// receive raw escape sequences.
|
|
83
|
-
const useAltScreen = process.stdout.isTTY === true;
|
|
84
|
-
|
|
85
|
-
if (useAltScreen) {
|
|
86
|
-
process.stdout.write("\x1b[?1049h");
|
|
87
|
-
const restoreScreen = () => {
|
|
88
|
-
process.stdout.write("\x1b[?1049l");
|
|
89
|
-
};
|
|
90
|
-
process.on("exit", restoreScreen);
|
|
91
|
-
process.on("SIGINT", () => {
|
|
92
|
-
restoreScreen();
|
|
93
|
-
process.exit(130);
|
|
94
|
-
});
|
|
95
|
-
process.on("SIGTERM", () => {
|
|
96
|
-
restoreScreen();
|
|
97
|
-
process.exit(143);
|
|
98
|
-
});
|
|
99
|
-
process.on("uncaughtException", (err) => {
|
|
100
|
-
restoreScreen();
|
|
101
|
-
console.error(err);
|
|
102
|
-
process.exit(1);
|
|
103
|
-
});
|
|
72
|
+
const tui = (process.env.LINER_TUI || "go").toLowerCase();
|
|
73
|
+
if (tui !== "go") {
|
|
74
|
+
console.error(
|
|
75
|
+
[
|
|
76
|
+
`Unsupported LINER_TUI value: ${process.env.LINER_TUI}`,
|
|
77
|
+
"",
|
|
78
|
+
"The Ink TUI has been decommissioned and moved to the repo's ink/ archive.",
|
|
79
|
+
"Run `liner` with no LINER_TUI override, or set LINER_TUI=go.",
|
|
80
|
+
].join("\n"),
|
|
81
|
+
);
|
|
82
|
+
process.exit(1);
|
|
104
83
|
}
|
|
105
84
|
|
|
106
|
-
|
|
85
|
+
const resolved = resolveGoTuiBinary();
|
|
86
|
+
const headlessRunner = tryResolveHeadlessRunnerScript();
|
|
87
|
+
const child = spawn(resolved.command, resolved.args, {
|
|
88
|
+
stdio: "inherit",
|
|
89
|
+
cwd: resolved.cwd || process.cwd(),
|
|
90
|
+
env: {
|
|
91
|
+
...process.env,
|
|
92
|
+
LINER_BIN: process.env.LINER_BIN || tryResolveCliCommand() || "",
|
|
93
|
+
LINER_HEADLESS_RUNNER: process.env.LINER_HEADLESS_RUNNER || headlessRunner || "",
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
child.on("exit", (code, signal) => {
|
|
97
|
+
if (signal) {
|
|
98
|
+
process.kill(process.pid, signal);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
process.exit(code ?? 1);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function resolveGoTuiBinary() {
|
|
106
|
+
const envBin = process.env.LINER_GO_TUI_BIN;
|
|
107
|
+
if (envBin && existsSync(envBin)) return { command: envBin, args: [] };
|
|
108
|
+
|
|
109
|
+
const packaged = join(packageRoot, "bin", process.platform === "win32" ? "liner-tui.exe" : "liner-tui");
|
|
110
|
+
if (existsSync(packaged)) return { command: packaged, args: [] };
|
|
111
|
+
|
|
112
|
+
const bundled = findBundledGoTuiBinary();
|
|
113
|
+
if (bundled) return { command: bundled, args: [] };
|
|
114
|
+
|
|
115
|
+
const sourceDir = join(packageRoot, "..", "go-tui");
|
|
116
|
+
if (existsSync(join(sourceDir, "go.mod"))) {
|
|
117
|
+
const go = spawnSync("go", ["version"], { encoding: "utf8" });
|
|
118
|
+
if (go.status === 0) {
|
|
119
|
+
return { command: "go", args: ["run", "./cmd/liner-tui"], cwd: sourceDir };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.error(
|
|
124
|
+
[
|
|
125
|
+
"Could not find the Go Liner TUI.",
|
|
126
|
+
"",
|
|
127
|
+
"Expected one of:",
|
|
128
|
+
" - LINER_GO_TUI_BIN=/path/to/liner-tui",
|
|
129
|
+
" - packages/tui/bin/liner-tui built by npm run build:go",
|
|
130
|
+
" - bundled platform package (linersh-<platform>-<arch>)",
|
|
131
|
+
" - repo source at packages/go-tui with go installed",
|
|
132
|
+
].join("\n"),
|
|
133
|
+
);
|
|
134
|
+
process.exit(1);
|
|
107
135
|
}
|
|
108
136
|
|
|
109
137
|
function resolveCliBinary() {
|
|
@@ -112,12 +140,12 @@ function resolveCliBinary() {
|
|
|
112
140
|
return { command: envBin, args: [] };
|
|
113
141
|
}
|
|
114
142
|
|
|
115
|
-
const bundled = findBundledBinary();
|
|
116
|
-
if (bundled) return { command: bundled, args: [] };
|
|
117
|
-
|
|
118
143
|
const repoVenv = findRepoVenvBinary();
|
|
119
144
|
if (repoVenv) return { command: repoVenv, args: [] };
|
|
120
145
|
|
|
146
|
+
const bundled = findBundledBinary();
|
|
147
|
+
if (bundled) return { command: bundled, args: [] };
|
|
148
|
+
|
|
121
149
|
const pathHit = findPathBinary();
|
|
122
150
|
if (pathHit) return { command: pathHit, args: [] };
|
|
123
151
|
|
|
@@ -254,13 +282,25 @@ function playwrightCachePath(home) {
|
|
|
254
282
|
}
|
|
255
283
|
|
|
256
284
|
function findBundledBinary() {
|
|
285
|
+
const baseDir = findBundledPackageDir();
|
|
286
|
+
if (!baseDir) return null;
|
|
287
|
+
const candidate = join(baseDir, exeName());
|
|
288
|
+
return existsSync(candidate) ? candidate : null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function findBundledGoTuiBinary() {
|
|
292
|
+
const baseDir = findBundledPackageDir();
|
|
293
|
+
if (!baseDir) return null;
|
|
294
|
+
const candidate = join(baseDir, process.platform === "win32" ? "liner-tui.exe" : "liner-tui");
|
|
295
|
+
return existsSync(candidate) ? candidate : null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function findBundledPackageDir() {
|
|
257
299
|
const require = createRequire(import.meta.url);
|
|
258
300
|
const target = `linersh-${process.platform}-${process.arch}`;
|
|
259
301
|
try {
|
|
260
302
|
const pkgJson = require.resolve(`${target}/package.json`);
|
|
261
|
-
|
|
262
|
-
const candidate = join(baseDir, exeName());
|
|
263
|
-
return existsSync(candidate) ? candidate : null;
|
|
303
|
+
return pkgJson.replace(/[\\/]package\.json$/, "");
|
|
264
304
|
} catch {
|
|
265
305
|
return null;
|
|
266
306
|
}
|
|
@@ -311,7 +351,12 @@ function readTuiVersion() {
|
|
|
311
351
|
function tryResolveCliCommand() {
|
|
312
352
|
const envBin = process.env.LINER_BIN;
|
|
313
353
|
if (envBin && existsSync(envBin)) return envBin;
|
|
314
|
-
return
|
|
354
|
+
return findRepoVenvBinary() || findBundledBinary() || findPathBinary() || null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function tryResolveHeadlessRunnerScript() {
|
|
358
|
+
const candidate = join(packageRoot, "dist", "agents", "headless-runner.js");
|
|
359
|
+
return existsSync(candidate) ? candidate : null;
|
|
315
360
|
}
|
|
316
361
|
|
|
317
362
|
function printVersion() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Curating Mixtapes — Skill Bundle
|
|
2
2
|
|
|
3
|
-
This is the Liner methodology made executable by Claude. The bundle implements CURATION.md v2.0 as instructions to a running AI, drives the mixtape lifecycle from a
|
|
3
|
+
This is the Liner methodology made executable by Claude or Codex. The bundle implements CURATION.md v2.0 as instructions to a running AI, drives the mixtape lifecycle from a task description to a project folder ready for `liner compile`, and supports both quick mode (the AI does most of the work, with lightweight gate review) and methodology mode (the curator engages substantively at every phase).
|
|
4
4
|
|
|
5
5
|
It is one of Liner's surfaces, alongside the CLI, the TUI, the planned MCP server, and the planned web builder. The skill is the surface for Claude-Code-native and TUI-subprocess authoring. Methodology-mode curators can also use it directly when working in a Claude Code session.
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ curating-mixtapes/
|
|
|
18
18
|
└── synthesis-guidance.md # Phase 6
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
`SKILL.md` is the orchestrator. It defines the trigger description, the two modes, the
|
|
21
|
+
`SKILL.md` is the orchestrator. It defines the trigger description, the two modes, the review gates, the lifecycle skeleton, the AI biases to compensate for, the boundaries (what the skill does NOT do), and the failure modes to watch. It is always loaded when the skill fires.
|
|
22
22
|
|
|
23
23
|
The five companion files are loaded only at the phases that use them. Phases 1, 3, 7, and 8 have no companion file — their guidance fits inside SKILL.md.
|
|
24
24
|
|
|
@@ -28,7 +28,7 @@ The split is deliberate. Every invocation pulls SKILL.md's ~2,300 words into con
|
|
|
28
28
|
|
|
29
29
|
**Local testing.** Drop this directory into `~/.claude/skills/curating-mixtapes/`. Claude Code and Claude Desktop both look there for user-installed skills. The skill fires when the user says something the description matches — "help me make a mixtape on [topic]" is the canonical trigger.
|
|
30
30
|
|
|
31
|
-
**Shipping.** The canonical bundle lives at
|
|
31
|
+
**Shipping.** The canonical bundle lives at `docs/curation-skill/`. The TUI copies this directory into `packages/tui/cli-update-docs/` during `prepack` and ships it inside the `linersh` npm package, so end users do not need a separate skill install for TUI-driven agent phases.
|
|
32
32
|
|
|
33
33
|
**Direct skill use.** A documented copy/install flow for using the skill outside the TUI is still planned. Until then, direct local use is a developer workflow.
|
|
34
34
|
|
|
@@ -48,7 +48,7 @@ The user says something the description matches. Claude loads SKILL.md. Claude r
|
|
|
48
48
|
|
|
49
49
|
At Phase 2, Claude reads `source-finding-tactics.md`. At Phase 4, Claude reads `source-quality-hierarchy.md` and `curator-notes.md`. At Phase 5, Claude reads `quality-check-tests.md`. At Phase 6, Claude reads `synthesis-guidance.md`. Each companion file is read at the start of its phase, before any work in that phase happens.
|
|
50
50
|
|
|
51
|
-
The
|
|
51
|
+
The gates pause for user input. In quick mode, defaults can auto-continue while preserving project state. In methodology mode, the AI pauses for substantive review.
|
|
52
52
|
|
|
53
53
|
The skill writes artifacts to a project folder named for the topic (e.g., `mobile-design-foundations/`) as it goes. The working notes are produced phase by phase, so the user can stop at any phase boundary and resume later — the working files are picked up where they were left.
|
|
54
54
|
|
|
@@ -80,7 +80,7 @@ The bundle is functional and ships inside the npm TUI package so agent-backed ph
|
|
|
80
80
|
|
|
81
81
|
The bundle still benefits from more worked examples in the companion files, but it is no longer blocked by the old "second pass before any shipping" constraint. Current product risk lives more in curation quality and fetcher edge cases than in basic skill availability.
|
|
82
82
|
|
|
83
|
-
As of `linersh@0.
|
|
83
|
+
As of `linersh@1.0.0`, compilation is the corpus-ready milestone and Create Operating Layer is the project-complete milestone. A project can be "ready to use — compiled with warnings" when `MIXTAPE.md` is written but some sources are missing or soft-failed. The TUI opens the existing compile result for a completed mixtape and requires an explicit retry/re-run from that screen. Framing also has a validation contract: Phase 1 must produce a capability brief and required source roles before source discovery can proceed.
|
|
84
84
|
|
|
85
85
|
## Versioning
|
|
86
86
|
|
|
@@ -100,7 +100,7 @@ The skill is the methodology made executable. It sits alongside Liner's other su
|
|
|
100
100
|
|
|
101
101
|
**The Liner CLI** runs `liner compile` against the project folder this skill produces. The skill never compiles; the CLI never authors. Clean split.
|
|
102
102
|
|
|
103
|
-
**The Liner TUI** invokes this skill internally for
|
|
103
|
+
**The Liner TUI** invokes this skill internally for agent-backed authoring via the local Claude or Codex CLI. Same methodology, different UX.
|
|
104
104
|
|
|
105
105
|
**The Liner MCP server** (planned) will expose mechanical operations — fetch this URL, validate this tape file, query the cache — as tools. A future skill version will use those tools where v1 uses Claude's own web search.
|
|
106
106
|
|