@koda-sl/baker-cli 0.439.0 → 0.440.0
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 +2 -0
- package/dist/cli.js +60 -18
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6714,6 +6714,7 @@ baker landing inspiration code <section id> # the standalone bundle
|
|
|
6714
6714
|
baker landing inspiration page <source id> # a whole page as a section sequence
|
|
6715
6715
|
baker landing inspiration sequences "b2b saas pricing page" --scope all # what follows what, across many pages
|
|
6716
6716
|
baker landing inspiration add https://linear.app --note "client likes this density"
|
|
6717
|
+
baker landing inspiration add https://linear.app --refresh # read a saved page again — the site changed
|
|
6717
6718
|
baker landing inspiration favorites # what this company has saved
|
|
6718
6719
|
baker landing inspiration retry-failed # study again every saved page that failed
|
|
6719
6720
|
baker landing inspiration scrape <url> --out .baker/<dir> # capture any page now, synchronously
|
|
@@ -6729,6 +6730,7 @@ baker landing inspiration scrape <url> --out .baker/<dir> # capture any page n
|
|
|
6729
6730
|
- **Compact by default, `--full` when you have chosen something.** Every list command returns what you need to *pick* a row; the 600-character "why it works" paragraph, the classification facets and the markup ride behind `--full` on `search`, `view`, `page`, `favorites` and `code`. A default `favorites` used to cost more than a default search for a question — "what does this client keep saving?" — that the facets alone answer.
|
|
6730
6731
|
- **`sequences` answers the ordering question search structurally can't.** Search ranks individual sections and caps each site at three, so a page's top-to-bottom order never survives its results, and `page` recovers exactly one page's order. `sequences` counts adjacency across many pages at once and returns `openers`, `transitions` (`{ from, to, count }`, most frequent first) and `closers`, filtered by `--scope --domain --section-type --limit`. It returns page **ids only** — `page` stays the one way to read a single page — and always reports `pages_considered` alongside `pages_returned`, because a frequency over an unstated denominator is not evidence. `--full` counts over every matching page and prints the whole table.
|
|
6731
6732
|
- **`page_id` on every search row** is what `page <id>` takes, so "how does this page sequence its sections?" is reachable from a result rather than only right after `add`. `favorites --limit` is capped at 100.
|
|
6733
|
+
- **Pages are re-read, on request and on a schedule.** A page is a copy taken when it was read, so `add --refresh` reads it again when the live site has changed (refused while a read is under way or within 10 minutes of the last one), and the library re-reads pages older than 30 days on its own, a small batch a day. A re-read that fails before it starts replacing the copy keeps the previous one and is reported as `refresh_failed_at`. `page` reports `read_at` and hints at `--refresh` (with the address the page is filed under) when the copy is over 30 days old.
|
|
6732
6734
|
- **`add` studies in the background; `scrape` returns with the page on disk.** `add` grows the shared library and takes minutes, so it can never answer "build our page like this one" within the same turn. `scrape` runs the identical capture locally and blocks until it finishes, writing section screenshots, standalone markup, a whole-page reproduction and `report.html`. `--no-motion` is the single biggest lever on runtime; `--no-mobile`, `--no-code` and `--no-report` skip further passes.
|
|
6733
6735
|
- **Filming is the expensive pass, and it runs three sections at a time.** Every moving section is filmed in its own fresh page load — the only way to catch an entrance animation before it fires — so a page with ten moving sections pays for ten full loads. Measured on one heavy page, filming was 74% of the capture. The takes are independent, so they overlap; a page that cannot be captured inside the library's budget now says so instead of timing out silently.
|
|
6734
6736
|
- **A page we can't open says why.** A dead certificate, an address that doesn't resolve, a site that won't answer or one that is simply too slow each produce their own plain-language reason rather than a browser error.
|
package/dist/cli.js
CHANGED
|
@@ -100940,6 +100940,12 @@ function fidelityHint(fidelity) {
|
|
|
100940
100940
|
}
|
|
100941
100941
|
return `Reproduction fidelity ${fidelity.toFixed(2)} \u2014 this section is scroll- or JS-driven and the extracted markup does NOT render like the original. Use the screenshot and the notes; treat the code as a hint only.`;
|
|
100942
100942
|
}
|
|
100943
|
+
var STALE_COPY_AFTER_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
100944
|
+
function staleCopyHint(studiedAt, filedUrl, now = Date.now()) {
|
|
100945
|
+
if (!studiedAt || now - studiedAt < STALE_COPY_AFTER_MS) return null;
|
|
100946
|
+
const date = new Date(studiedAt).toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: "UTC" });
|
|
100947
|
+
return `This copy of the page was read on ${date}. If the user says the live page looks different, run: baker landing inspiration add ${filedUrl} --refresh`;
|
|
100948
|
+
}
|
|
100943
100949
|
function reportError2(error) {
|
|
100944
100950
|
if (error instanceof ApiError) {
|
|
100945
100951
|
writeJson({ ok: false, error: { code: error.code, message: error.message } });
|
|
@@ -101117,37 +101123,67 @@ registerSchema({
|
|
|
101117
101123
|
description: "Add someone else's landing page to the reference library and save it to this company. Returns immediately \u2014 studying a page takes a few minutes, so never wait on it. Use it when the client names a site they admire, or when you find a competitor page worth learning from. Never point it at a page we built: it is refused, because the source is already in the project and reading a screenshot of it tells you less than opening the file.",
|
|
101118
101124
|
args: {
|
|
101119
101125
|
url: { type: "string", description: "Landing page address", required: true },
|
|
101120
|
-
note: { type: "string", description: "Why this page is worth keeping", required: false }
|
|
101126
|
+
note: { type: "string", description: "Why this page is worth keeping", required: false },
|
|
101127
|
+
refresh: {
|
|
101128
|
+
type: "boolean",
|
|
101129
|
+
description: "Study the page again even if it is already in the library. Use when the user says the page has changed or the saved sections look outdated",
|
|
101130
|
+
required: false
|
|
101131
|
+
}
|
|
101121
101132
|
}
|
|
101122
101133
|
});
|
|
101134
|
+
function addHints(data, { refresh }) {
|
|
101135
|
+
if (data.refreshDeclined === "studying") {
|
|
101136
|
+
return [
|
|
101137
|
+
"This page is already being studied \u2014 no second study was started. Search for it later in the turn or in a later one."
|
|
101138
|
+
];
|
|
101139
|
+
}
|
|
101140
|
+
if (data.refreshDeclined === "too_soon") {
|
|
101141
|
+
return [
|
|
101142
|
+
"This page was just studied a few minutes ago, so it was not studied again \u2014 its sections are already current.",
|
|
101143
|
+
`Search it with: baker landing inspiration search --domain ${new URL(data.canonicalUrl).hostname}`
|
|
101144
|
+
];
|
|
101145
|
+
}
|
|
101146
|
+
if (data.alreadyKnown) {
|
|
101147
|
+
return [
|
|
101148
|
+
"This page was already in the library, so nothing was re-studied \u2014 its sections are searchable now.",
|
|
101149
|
+
`Search it with: baker landing inspiration search --domain ${new URL(data.canonicalUrl).hostname}`,
|
|
101150
|
+
"If the user says the live page looks different from what the library shows, run this again with --refresh."
|
|
101151
|
+
];
|
|
101152
|
+
}
|
|
101153
|
+
return [
|
|
101154
|
+
refresh ? "Studying it again from the live site \u2014 this takes a few minutes. Until it lands, search results still show the old version, so don't build from them yet." : "Studying this page takes a few minutes. Don't wait on it \u2014 carry on, and search for it later in the turn or in a later one.",
|
|
101155
|
+
"Meanwhile, search what is already in the library: baker landing inspiration search '<what you want to see>' --scope all",
|
|
101156
|
+
"This is saved and being studied now, so it is listed as already applied \u2014 tell the user it is kept whatever they do with this chat.",
|
|
101157
|
+
// The save is not a promise that the study succeeded. An agent that
|
|
101158
|
+
// assumes it did will later search its own favorites, find nothing,
|
|
101159
|
+
// and have no idea why.
|
|
101160
|
+
"The save sticks even if the page turns out to be unreadable \u2014 `baker landing inspiration favorites` reports those separately as unreadable, so check there rather than assuming this page is searchable."
|
|
101161
|
+
];
|
|
101162
|
+
}
|
|
101123
101163
|
var addCommand = defineCommand221({
|
|
101124
101164
|
meta: {
|
|
101125
101165
|
name: "add",
|
|
101126
|
-
description: "Add someone else's landing page to the reference library. Example: baker landing inspiration add https://linear.app --note 'the client likes this density'"
|
|
101166
|
+
description: "Add someone else's landing page to the reference library. Example: baker landing inspiration add https://linear.app --note 'the client likes this density'. Add --refresh to study a saved page again after the site changed"
|
|
101127
101167
|
},
|
|
101128
101168
|
args: {
|
|
101129
101169
|
url: { type: "positional", description: "Landing page address", required: true },
|
|
101130
|
-
note: { type: "string", description: "Why this page is worth keeping", required: false }
|
|
101170
|
+
note: { type: "string", description: "Why this page is worth keeping", required: false },
|
|
101171
|
+
refresh: {
|
|
101172
|
+
type: "boolean",
|
|
101173
|
+
description: "Study it again even if it is already in the library",
|
|
101174
|
+
required: false,
|
|
101175
|
+
default: false
|
|
101176
|
+
}
|
|
101131
101177
|
},
|
|
101132
101178
|
run: async ({ args: args8 }) => {
|
|
101133
101179
|
try {
|
|
101134
101180
|
const data = await apiPost("/api/landing-inspiration/add", {
|
|
101135
101181
|
url: args8.url,
|
|
101136
101182
|
note: args8.note,
|
|
101137
|
-
favorite: true
|
|
101183
|
+
favorite: true,
|
|
101184
|
+
refresh: args8.refresh || void 0
|
|
101138
101185
|
});
|
|
101139
|
-
const hints2 = data.
|
|
101140
|
-
"This page was already in the library, so nothing was re-studied \u2014 its sections are searchable now.",
|
|
101141
|
-
`Search it with: baker landing inspiration search --domain ${new URL(data.canonicalUrl).hostname}`
|
|
101142
|
-
] : [
|
|
101143
|
-
"Studying this page takes a few minutes. Don't wait on it \u2014 carry on, and search for it later in the turn or in a later one.",
|
|
101144
|
-
"Meanwhile, search what is already in the library: baker landing inspiration search '<what you want to see>' --scope all",
|
|
101145
|
-
"This is saved and being studied now, so it is listed as already applied \u2014 tell the user it is kept whatever they do with this chat.",
|
|
101146
|
-
// The save is not a promise that the study succeeded. An agent that
|
|
101147
|
-
// assumes it did will later search its own favorites, find nothing,
|
|
101148
|
-
// and have no idea why.
|
|
101149
|
-
"The save sticks even if the page turns out to be unreadable \u2014 `baker landing inspiration favorites` reports those separately as unreadable, so check there rather than assuming this page is searchable."
|
|
101150
|
-
];
|
|
101186
|
+
const hints2 = addHints(data, { refresh: args8.refresh });
|
|
101151
101187
|
writeJson({
|
|
101152
101188
|
ok: true,
|
|
101153
101189
|
data: { id: data.sourceId, url: data.canonicalUrl, status: data.status, already_known: data.alreadyKnown },
|
|
@@ -101421,6 +101457,8 @@ var pageCommand2 = defineCommand224({
|
|
|
101421
101457
|
archetype: data.archetype,
|
|
101422
101458
|
stack: data.detectedStack,
|
|
101423
101459
|
page_fidelity: data.pageFidelity,
|
|
101460
|
+
read_at: data.studiedAt ? new Date(data.studiedAt).toISOString().slice(0, 10) : null,
|
|
101461
|
+
...data.refreshFailedAt ? { refresh_failed_at: new Date(data.refreshFailedAt).toISOString().slice(0, 10) } : {},
|
|
101424
101462
|
blueprint: data.sectionOrder,
|
|
101425
101463
|
sections: data.sections.map((section2) => ({
|
|
101426
101464
|
id: section2.id,
|
|
@@ -101441,7 +101479,11 @@ var pageCommand2 = defineCommand224({
|
|
|
101441
101479
|
"The blueprint is the section order top to bottom \u2014 the answer to 'how do good pages in this category sequence themselves'.",
|
|
101442
101480
|
"Use `baker landing inspiration view <section id>` for any section worth a closer look.",
|
|
101443
101481
|
...full ? [] : ["Add --full for the idea behind every section, once you know which page you care about."],
|
|
101444
|
-
INSPIRATION_HINTS.adapt
|
|
101482
|
+
INSPIRATION_HINTS.adapt,
|
|
101483
|
+
...[staleCopyHint(data.studiedAt, data.filedUrl)].filter((hint) => hint !== null),
|
|
101484
|
+
...data.refreshFailedAt ? [
|
|
101485
|
+
"The last attempt to read this page again failed, so this is the earlier copy. Tell the user if the live page may differ."
|
|
101486
|
+
] : []
|
|
101445
101487
|
]
|
|
101446
101488
|
});
|
|
101447
101489
|
} catch (error) {
|
|
@@ -104166,7 +104208,7 @@ Subcommands:
|
|
|
104166
104208
|
baker landing inspiration code <id> \u2014 its standalone HTML+CSS, for structure only
|
|
104167
104209
|
baker landing inspiration page <id> \u2014 a whole page as a sequence: how it orders its sections
|
|
104168
104210
|
baker landing inspiration sequences "<q>" \u2014 what follows what across MANY pages: openers, transitions, closers
|
|
104169
|
-
baker landing inspiration add <url> \u2014 add a page to the library and save it to this company (returns immediately)
|
|
104211
|
+
baker landing inspiration add <url> \u2014 add a page to the library and save it to this company (returns immediately); --refresh re-studies a page that changed
|
|
104170
104212
|
baker landing inspiration favorites \u2014 what this company has saved; the default search scope
|
|
104171
104213
|
baker landing inspiration favorite <id> \u2014 save a section
|
|
104172
104214
|
baker landing inspiration unfavorite <id> \u2014 unsave a section
|