@aglyn/plugins-ai 1.0.0-beta.288 → 1.0.0-beta.290
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/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.d.ts +3 -2
- package/src/lib/activity/ai-activity-actions.js +3 -0
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +2 -0
- package/src/lib/components/ai-job-requests.js +2 -0
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +4 -0
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-import-job.component.d.ts +6 -1
- package/src/lib/components/ai-site-import-job.component.js +124 -17
- package/src/lib/components/ai-site-import-job.component.js.map +1 -1
- package/src/lib/components/ai-site-import-start.component.d.ts +6 -0
- package/src/lib/components/ai-site-import-start.component.js +18 -4
- package/src/lib/components/ai-site-import-start.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.js +2 -1
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/jobs/ai-image-reads.d.ts +20 -2
- package/src/lib/jobs/ai-image-reads.js +47 -0
- package/src/lib/jobs/ai-image-reads.js.map +1 -1
- package/src/lib/jobs/ai-job-import-step.d.ts +53 -3
- package/src/lib/jobs/ai-job-import-step.js +386 -64
- package/src/lib/jobs/ai-job-import-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +33 -0
- package/src/lib/jobs/ai-job-layout-language.js +75 -1
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.js +8 -3
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +29 -0
- package/src/lib/jobs/ai-job-page-language.js +178 -2
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +3 -0
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-site-import-document.d.ts +117 -0
- package/src/lib/jobs/ai-site-import-document.js +710 -0
- package/src/lib/jobs/ai-site-import-document.js.map +1 -0
- package/src/lib/jobs/ai-site-import-look.d.ts +112 -0
- package/src/lib/jobs/ai-site-import-look.js +402 -0
- package/src/lib/jobs/ai-site-import-look.js.map +1 -0
- package/src/lib/jobs/ai-site-import-publish.d.ts +41 -0
- package/src/lib/jobs/ai-site-import-publish.js +92 -0
- package/src/lib/jobs/ai-site-import-publish.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +27 -2
- package/src/lib/jobs/ai-theme-brand-inputs.js +37 -8
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame.d.ts +17 -0
- package/src/lib/layout-language/ai-layout-frame.js +73 -2
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-language.d.ts +43 -0
- package/src/lib/layout-language/ai-layout-language.js +199 -0
- package/src/lib/layout-language/ai-layout-language.js.map +1 -1
- package/src/lib/model/ai-credit-estimate.d.ts +15 -0
- package/src/lib/model/ai-credit-estimate.js +14 -1
- package/src/lib/model/ai-credit-estimate.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +13 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-site-import-view.d.ts +47 -3
- package/src/lib/model/ai-site-import-view.js +122 -20
- package/src/lib/model/ai-site-import-view.js.map +1 -1
- package/src/lib/model/ai-site-import.d.ts +232 -7
- package/src/lib/model/ai-site-import.js +365 -35
- package/src/lib/model/ai-site-import.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +18 -0
- package/src/lib/runtime/ai-doctrine-validators.js +16 -5
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-palette.generated.js +31 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/server/ai-image-reads-route.js +24 -1
- package/src/lib/server/ai-image-reads-route.js.map +1 -1
- package/src/lib/server/ai-jobs-resume.js +7 -1
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/site-import/fixtures/aglyn-com-recordings.d.ts +57 -0
- package/src/lib/site-import/fixtures/aglyn-com-recordings.js +172 -0
- package/src/lib/site-import/fixtures/aglyn-com-recordings.js.map +1 -0
- package/src/lib/site-import/site-import-crawl.d.ts +32 -7
- package/src/lib/site-import/site-import-crawl.js +133 -44
- package/src/lib/site-import/site-import-crawl.js.map +1 -1
- package/src/lib/site-import/site-import-edge-server.d.ts +31 -0
- package/src/lib/site-import/site-import-edge-server.js +31 -0
- package/src/lib/site-import/site-import-edge-server.js.map +1 -0
- package/src/lib/site-import/site-import-edge.d.ts +44 -0
- package/src/lib/site-import/site-import-edge.js +108 -0
- package/src/lib/site-import/site-import-edge.js.map +1 -0
- package/src/lib/site-import/site-import-html.d.ts +73 -3
- package/src/lib/site-import/site-import-html.js +332 -45
- package/src/lib/site-import/site-import-html.js.map +1 -1
- package/src/lib/site-import/site-import-images.d.ts +22 -0
- package/src/lib/site-import/site-import-images.js +78 -2
- package/src/lib/site-import/site-import-images.js.map +1 -1
- package/src/lib/site-import/site-import-page.d.ts +44 -2
- package/src/lib/site-import/site-import-page.js +116 -16
- package/src/lib/site-import/site-import-page.js.map +1 -1
|
@@ -84,6 +84,17 @@ export type AiSiteImportPhase =
|
|
|
84
84
|
/** Out of AI credits or at a cap: the meter's pause, carried on by Resume. */
|
|
85
85
|
| 'paused' | 'done' | 'stopped';
|
|
86
86
|
export declare function aiSiteImportPhaseOf(job: Pick<AiJobSummary, 'status' | 'review' | 'siteImport'>): AiSiteImportPhase;
|
|
87
|
+
/**
|
|
88
|
+
* How a hold that is the site's to fix reads (AGL-4083): its heading, its
|
|
89
|
+
* sentence and its button. A home page bot protection turned away, or one
|
|
90
|
+
* that could not be read, is checked again for free; `null` for any other
|
|
91
|
+
* hold, which keeps its own words.
|
|
92
|
+
*/
|
|
93
|
+
export declare function aiSiteImportHeldCopy(job: Pick<AiJobSummary, 'review' | 'siteImport'>): {
|
|
94
|
+
heading: string;
|
|
95
|
+
message: string;
|
|
96
|
+
action: string;
|
|
97
|
+
} | null;
|
|
87
98
|
export type AiSiteImportRowState = 'waiting' | 'active' | 'done' | 'failed' | 'skipped';
|
|
88
99
|
export interface AiSiteImportRowView {
|
|
89
100
|
slot: string;
|
|
@@ -99,20 +110,44 @@ export interface AiSiteImportRowView {
|
|
|
99
110
|
photos: string | null;
|
|
100
111
|
/** The draft the row wrote, by its output id. */
|
|
101
112
|
outputId: string | null;
|
|
113
|
+
/** The page on the old site, to open beside the draft (AGL-4083). */
|
|
114
|
+
oldPage: string;
|
|
115
|
+
/** "1,204 of 1,310 words", once the page is in and the step has counted them. */
|
|
116
|
+
words: string | null;
|
|
117
|
+
/** "Copied as it is" or "Arranged by Aglyn AI", once the step has chosen. */
|
|
118
|
+
build: string | null;
|
|
102
119
|
}
|
|
103
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* "3 photos added", "2 photos added, 1 already in your media library"; with
|
|
122
|
+
* photos that could not come in, against all it tried: "3 of 5 photos: 2
|
|
123
|
+
* added, 1 already in your media library, 2 could not be brought in".
|
|
124
|
+
*/
|
|
104
125
|
export declare function aiSiteImportPhotosText(photos: {
|
|
105
126
|
brought: number;
|
|
106
127
|
reused: number;
|
|
128
|
+
skipped?: number;
|
|
107
129
|
} | null | undefined): string | null;
|
|
108
130
|
/** One wave's rows, the header and footer first where the wave builds them. */
|
|
109
131
|
export declare function aiSiteImportWaveRows(job: Pick<AiJobSummary, 'items' | 'siteImport' | 'status'>, wave: AiSiteImportWave): AiSiteImportRowView[];
|
|
110
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* "About 189 credits (up to 650)" for the wave, as it stands; once the step
|
|
134
|
+
* has chosen how its pages are built, it names them: "…: 7 pages arranged by
|
|
135
|
+
* Aglyn AI, 3 copied as they are" (AGL-4083).
|
|
136
|
+
*/
|
|
111
137
|
export declare function aiSiteImportWaveQuote(job: Pick<AiJobSummary, 'items' | 'siteImport'>, wave: AiSiteImportWave): string;
|
|
112
138
|
/** What a wave cost, its pages' credits less what was given back. */
|
|
113
139
|
export declare function aiSiteImportWaveSpent(job: Pick<AiJobSummary, 'items'>, wave: AiSiteImportWave): number;
|
|
114
|
-
/**
|
|
140
|
+
/** Pages the site has that AglynBot could not read: turned away, unanswered, too large or never reached. */
|
|
141
|
+
export declare function aiSiteImportUnreadCount(state: AiSiteImportState): number;
|
|
142
|
+
/**
|
|
143
|
+
* The read site in one sentence: "Found 21 pages on harbor-dental.com: Main
|
|
144
|
+
* pages (6) and Blog (14)." — and how many more could not be read (AGL-4083).
|
|
145
|
+
*/
|
|
115
146
|
export declare function aiSiteImportFoundText(state: AiSiteImportState): string;
|
|
147
|
+
/** Why the read stopped short, when it did and left pages unread (AGL-4083). */
|
|
148
|
+
export declare function aiSiteImportStopText(state: AiSiteImportState): string | null;
|
|
149
|
+
/** The read's warning when most of the site was turned away though its home page came in (AGL-4083). */
|
|
150
|
+
export declare function aiSiteImportVerdictNote(state: AiSiteImportState): string | null;
|
|
116
151
|
/** The plan's page count against the site: "Your plan includes 25 pages and this site has 0, so 20 are brought in." */
|
|
117
152
|
export declare function aiSiteImportPlanText(state: AiSiteImportState): string;
|
|
118
153
|
/** What was left out, by reason, most first. */
|
|
@@ -128,3 +163,12 @@ export declare function aiSiteImportStartAction(job: Pick<AiJobSummary, 'siteImp
|
|
|
128
163
|
label: string;
|
|
129
164
|
quote: string;
|
|
130
165
|
} | null;
|
|
166
|
+
/**
|
|
167
|
+
* "Start every remaining wave" (AGL-4083), off by default: offered beside the
|
|
168
|
+
* next wave's button when more than one wave waits, quoted as all of them.
|
|
169
|
+
*/
|
|
170
|
+
export declare function aiSiteImportStartAllAction(job: Pick<AiJobSummary, 'siteImport' | 'items'>): {
|
|
171
|
+
label: string;
|
|
172
|
+
quote: string;
|
|
173
|
+
waves: number;
|
|
174
|
+
} | null;
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
* its waves planned, a wave running, a wave in for review, a wave held for a
|
|
22
22
|
* proof or the day's limit, the import done. The components draw these; the
|
|
23
23
|
* specs hold them.
|
|
24
|
-
*=========================================*/ import {
|
|
25
|
-
import {
|
|
24
|
+
*=========================================*/ import { PLATFORM_BRAND_NAME } from "@aglyn/aglyn/app-utils/platform-brand";
|
|
25
|
+
import { aiCreditRangeText } from "./ai-credit-estimate.js";
|
|
26
|
+
import { AI_SITE_IMPORT_FRAME_SLOT, AI_SITE_IMPORT_LEFT_OUT_COPY, AI_SITE_IMPORT_LEFT_OUT_REASONS, AI_SITE_IMPORT_UNREAD_REASONS, aiSiteImportNextWave, aiSiteImportPagesText, aiSiteImportQuoteText, aiSiteImportReadStops, aiSiteImportReadVerdictMessage, aiSiteImportReadVerdictReason, aiSiteImportRemainingCreditRange, aiSiteImportReviewWave, aiSiteImportRunningWave, aiSiteImportWaveCreditRange, aiSiteImportWaveOwed } from "./ai-site-import.js";
|
|
26
27
|
/** What the card says to a plan that does not include it. */ export const AI_SITE_IMPORT_PLAN_COPY = 'Bring your current website in, every page and photo, on any paid plan. Upgrade to bring yours in.';
|
|
27
28
|
/** What the card says to a member who cannot. */ export const AI_SITE_IMPORT_ROLE_COPY = 'Only the workspace owner or an admin can bring a site in.';
|
|
28
29
|
/**
|
|
@@ -51,17 +52,38 @@ import { AI_SITE_IMPORT_FRAME_SLOT, AI_SITE_IMPORT_LEFT_OUT_COPY, AI_SITE_IMPORT
|
|
|
51
52
|
export function aiSiteImportPhaseOf(job) {
|
|
52
53
|
var _job_siteImport;
|
|
53
54
|
const state = (_job_siteImport = job.siteImport) != null ? _job_siteImport : null;
|
|
55
|
+
// A read that stopped at its home page is held, and its Check again reads again (AGL-4083).
|
|
56
|
+
const stopped = aiSiteImportReadStops(state == null ? void 0 : state.verdict);
|
|
54
57
|
if (job.status === 'done') return 'done';
|
|
55
58
|
if (job.status === 'failed' || job.status === 'canceled') return 'stopped';
|
|
56
59
|
if (job.status === 'needs_input') return 'paused';
|
|
57
60
|
if (job.status === 'needs_review') {
|
|
58
61
|
var _job_review;
|
|
59
|
-
if (((_job_review = job.review) == null ? void 0 : _job_review.reason) !== 'wave' || !state) return 'held';
|
|
62
|
+
if (((_job_review = job.review) == null ? void 0 : _job_review.reason) !== 'wave' || !state || stopped) return 'held';
|
|
60
63
|
return aiSiteImportReviewWave(state) ? 'review' : 'ready';
|
|
61
64
|
}
|
|
62
|
-
if (!state) return 'reading';
|
|
65
|
+
if (!state || stopped) return 'reading';
|
|
63
66
|
return aiSiteImportRunningWave(state) ? 'running' : 'starting';
|
|
64
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* How a hold that is the site's to fix reads (AGL-4083): its heading, its
|
|
70
|
+
* sentence and its button. A home page bot protection turned away, or one
|
|
71
|
+
* that could not be read, is checked again for free; `null` for any other
|
|
72
|
+
* hold, which keeps its own words.
|
|
73
|
+
*/ export function aiSiteImportHeldCopy(job) {
|
|
74
|
+
var _job_siteImport, _ref, _ref1;
|
|
75
|
+
var _job_review, _job_review1, _job_review2;
|
|
76
|
+
const state = (_job_siteImport = job.siteImport) != null ? _job_siteImport : null;
|
|
77
|
+
const fromState = aiSiteImportReadStops(state == null ? void 0 : state.verdict) ? aiSiteImportReadVerdictReason(state == null ? void 0 : state.verdict) : null;
|
|
78
|
+
const reason = ((_job_review = job.review) == null ? void 0 : _job_review.reason) === 'blocked' || ((_job_review1 = job.review) == null ? void 0 : _job_review1.reason) === 'unreadable' ? job.review.reason : fromState;
|
|
79
|
+
if (!reason) return null;
|
|
80
|
+
const message = (_ref = (_ref1 = fromState && state ? aiSiteImportReadVerdictMessage(state.verdict, state.domain) : null) != null ? _ref1 : (_job_review2 = job.review) == null ? void 0 : _job_review2.message) != null ? _ref : '';
|
|
81
|
+
return {
|
|
82
|
+
heading: reason === 'blocked' ? 'AglynBot was turned away' : 'Your home page could not be read',
|
|
83
|
+
message,
|
|
84
|
+
action: 'Check again'
|
|
85
|
+
};
|
|
86
|
+
}
|
|
65
87
|
function rowState(row, active) {
|
|
66
88
|
if (!row) return 'waiting';
|
|
67
89
|
if (row.status === 'succeeded' || row.status === 'degraded') return 'done';
|
|
@@ -69,15 +91,36 @@ function rowState(row, active) {
|
|
|
69
91
|
if (row.status === 'skipped') return 'skipped';
|
|
70
92
|
return active ? 'active' : 'waiting';
|
|
71
93
|
}
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
/**
|
|
95
|
+
* "3 photos added", "2 photos added, 1 already in your media library"; with
|
|
96
|
+
* photos that could not come in, against all it tried: "3 of 5 photos: 2
|
|
97
|
+
* added, 1 already in your media library, 2 could not be brought in".
|
|
98
|
+
*/ export function aiSiteImportPhotosText(photos) {
|
|
99
|
+
var _photos_skipped;
|
|
100
|
+
if (!photos) return null;
|
|
101
|
+
const skipped = Math.max(0, (_photos_skipped = photos.skipped) != null ? _photos_skipped : 0);
|
|
102
|
+
const into = photos.brought + photos.reused;
|
|
103
|
+
if (into === 0 && skipped === 0) return null;
|
|
104
|
+
if (!skipped) {
|
|
105
|
+
const added = photos.brought ? `${photos.brought} ${photos.brought === 1 ? 'photo' : 'photos'} added` : '';
|
|
106
|
+
const reused = photos.reused ? `${photos.reused} already in your media library` : '';
|
|
107
|
+
return [
|
|
108
|
+
added,
|
|
109
|
+
reused
|
|
110
|
+
].filter(Boolean).join(', ');
|
|
111
|
+
}
|
|
112
|
+
const parts = [
|
|
113
|
+
photos.brought ? `${photos.brought} added` : '',
|
|
114
|
+
photos.reused ? `${photos.reused} already in your media library` : '',
|
|
115
|
+
`${skipped} could not be brought in`
|
|
116
|
+
].filter(Boolean);
|
|
117
|
+
const tried = into + skipped;
|
|
118
|
+
return `${into} of ${tried} ${tried === 1 ? 'photo' : 'photos'}: ${parts.join(', ')}`;
|
|
80
119
|
}
|
|
120
|
+
const BUILD_COPY = {
|
|
121
|
+
copied: 'Copied as it is',
|
|
122
|
+
arranged: `Arranged by ${PLATFORM_BRAND_NAME} AI`
|
|
123
|
+
};
|
|
81
124
|
/** One wave's rows, the header and footer first where the wave builds them. */ export function aiSiteImportWaveRows(job, wave) {
|
|
82
125
|
var _job_items;
|
|
83
126
|
const state = job.siteImport;
|
|
@@ -105,7 +148,10 @@ function rowState(row, active) {
|
|
|
105
148
|
state: rowState(row, active(row)),
|
|
106
149
|
note: (_ref = (_ref1 = row == null ? void 0 : (_row_failure = row.failure) == null ? void 0 : _row_failure.message) != null ? _ref1 : row == null ? void 0 : row.note) != null ? _ref : null,
|
|
107
150
|
photos: null,
|
|
108
|
-
outputId: (_ref2 = row == null ? void 0 : row.outputs[0]) != null ? _ref2 : null
|
|
151
|
+
outputId: (_ref2 = row == null ? void 0 : row.outputs[0]) != null ? _ref2 : null,
|
|
152
|
+
oldPage: `https://${state.domain}/`,
|
|
153
|
+
words: null,
|
|
154
|
+
build: null
|
|
109
155
|
});
|
|
110
156
|
}
|
|
111
157
|
for (const slot of wave.slots){
|
|
@@ -122,14 +168,23 @@ function rowState(row, active) {
|
|
|
122
168
|
state: rowState(row, active(row)),
|
|
123
169
|
note: (_ref3 = (_ref4 = row == null ? void 0 : (_row_failure1 = row.failure) == null ? void 0 : _row_failure1.message) != null ? _ref4 : row == null ? void 0 : row.note) != null ? _ref3 : page.refused ? AI_SITE_IMPORT_LEFT_OUT_COPY[page.refused] : null,
|
|
124
170
|
photos: aiSiteImportPhotosText(page.photos),
|
|
125
|
-
outputId: (_ref5 = row == null ? void 0 : row.outputs[0]) != null ? _ref5 : null
|
|
171
|
+
outputId: (_ref5 = row == null ? void 0 : row.outputs[0]) != null ? _ref5 : null,
|
|
172
|
+
oldPage: page.url,
|
|
173
|
+
words: page.brought ? `${page.brought.words.toLocaleString('en-US')} of ${page.words.toLocaleString('en-US')} words` : null,
|
|
174
|
+
build: page.build ? BUILD_COPY[page.build] : null
|
|
126
175
|
});
|
|
127
176
|
}
|
|
128
177
|
return rows;
|
|
129
178
|
}
|
|
130
|
-
/**
|
|
131
|
-
|
|
132
|
-
|
|
179
|
+
/**
|
|
180
|
+
* "About 189 credits (up to 650)" for the wave, as it stands; once the step
|
|
181
|
+
* has chosen how its pages are built, it names them: "…: 7 pages arranged by
|
|
182
|
+
* Aglyn AI, 3 copied as they are" (AGL-4083).
|
|
183
|
+
*/ export function aiSiteImportWaveQuote(job, wave) {
|
|
184
|
+
var _job_items, _job_items1;
|
|
185
|
+
const state = job.siteImport;
|
|
186
|
+
const range = aiSiteImportWaveCreditRange(state, wave, (_job_items = job.items) != null ? _job_items : null);
|
|
187
|
+
return aiSiteImportQuoteText(range, aiSiteImportWaveOwed(state, wave, (_job_items1 = job.items) != null ? _job_items1 : null));
|
|
133
188
|
}
|
|
134
189
|
/** What a wave cost, its pages' credits less what was given back. */ export function aiSiteImportWaveSpent(job, wave) {
|
|
135
190
|
var _job_items;
|
|
@@ -144,17 +199,49 @@ function rowState(row, active) {
|
|
|
144
199
|
return total + Math.max(0, ((_row_creditsSpent = row.creditsSpent) != null ? _row_creditsSpent : 0) - ((_row_creditsRefunded = row.creditsRefunded) != null ? _row_creditsRefunded : 0));
|
|
145
200
|
}, 0);
|
|
146
201
|
}
|
|
147
|
-
/**
|
|
202
|
+
/** Pages the site has that AglynBot could not read: turned away, unanswered, too large or never reached. */ export function aiSiteImportUnreadCount(state) {
|
|
203
|
+
return AI_SITE_IMPORT_UNREAD_REASONS.reduce((total, reason)=>{
|
|
204
|
+
var _state_leftOutCount_reason;
|
|
205
|
+
return total + ((_state_leftOutCount_reason = state.leftOutCount[reason]) != null ? _state_leftOutCount_reason : 0);
|
|
206
|
+
}, 0);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The read site in one sentence: "Found 21 pages on harbor-dental.com: Main
|
|
210
|
+
* pages (6) and Blog (14)." — and how many more could not be read (AGL-4083).
|
|
211
|
+
*/ export function aiSiteImportFoundText(state) {
|
|
148
212
|
const groups = state.groups.map((group)=>`${group.label} (${group.pages})`);
|
|
149
213
|
const listed = groups.length <= 1 ? groups.join('') : `${groups.slice(0, -1).join(', ')} and ${groups[groups.length - 1]}`;
|
|
150
214
|
const found = `Found ${aiSiteImportPagesText(state.found)} on ${state.domain}`;
|
|
151
|
-
|
|
215
|
+
const lead = listed ? `${found}: ${listed}.` : `${found}.`;
|
|
216
|
+
const unread = aiSiteImportUnreadCount(state);
|
|
217
|
+
return unread ? `${lead} ${unread.toLocaleString('en-US')} more could not be read; see Not brought in.` : lead;
|
|
218
|
+
}
|
|
219
|
+
/** Why the read stopped short, when it did and left pages unread (AGL-4083). */ export function aiSiteImportStopText(state) {
|
|
220
|
+
var _state_leftOutCount_notreached;
|
|
221
|
+
const unreached = (_state_leftOutCount_notreached = state.leftOutCount['not-reached']) != null ? _state_leftOutCount_notreached : 0;
|
|
222
|
+
if (!unreached) return null;
|
|
223
|
+
const first = `Only the first ${aiSiteImportPagesText(state.found)}`;
|
|
224
|
+
const rest = 'the rest are listed under Not brought in as not reached.';
|
|
225
|
+
switch(state.stoppedBy){
|
|
226
|
+
case 'time':
|
|
227
|
+
return `${first} could be read in the time allowed; ${rest}`;
|
|
228
|
+
case 'total-bytes':
|
|
229
|
+
return `${first} could be read before the read reached its size limit; ${rest}`;
|
|
230
|
+
default:
|
|
231
|
+
return `${first} could be read this time; ${rest}`;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/** The read's warning when most of the site was turned away though its home page came in (AGL-4083). */ export function aiSiteImportVerdictNote(state) {
|
|
235
|
+
var _state_verdict;
|
|
236
|
+
return ((_state_verdict = state.verdict) == null ? void 0 : _state_verdict.kind) === 'mostly-blocked' ? aiSiteImportReadVerdictMessage(state.verdict, state.domain) : null;
|
|
152
237
|
}
|
|
153
238
|
/** The plan's page count against the site: "Your plan includes 25 pages and this site has 0, so 20 are brought in." */ export function aiSiteImportPlanText(state) {
|
|
154
239
|
const kept = state.pages.length;
|
|
155
240
|
const waves = state.waves.length;
|
|
156
241
|
const plan = state.pageLimit === null ? 'Your plan has no page limit' : `Your plan includes ${aiSiteImportPagesText(state.pageLimit)} and this site has ${state.existingPages}`;
|
|
157
|
-
|
|
242
|
+
const lead = `${plan}, so ${aiSiteImportPagesText(kept)} ${kept === 1 ? 'is' : 'are'} brought in, in ${waves === 1 ? 'one wave' : `${waves} waves`}.`;
|
|
243
|
+
const stop = aiSiteImportStopText(state);
|
|
244
|
+
return stop ? `${lead} ${stop}` : lead;
|
|
158
245
|
}
|
|
159
246
|
/** What was left out, by reason, most first. */ export function aiSiteImportLeftOutLines(state) {
|
|
160
247
|
return AI_SITE_IMPORT_LEFT_OUT_REASONS.map((reason)=>{
|
|
@@ -178,5 +265,20 @@ function rowState(row, active) {
|
|
|
178
265
|
quote: aiSiteImportWaveQuote(job, wave)
|
|
179
266
|
};
|
|
180
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* "Start every remaining wave" (AGL-4083), off by default: offered beside the
|
|
270
|
+
* next wave's button when more than one wave waits, quoted as all of them.
|
|
271
|
+
*/ export function aiSiteImportStartAllAction(job) {
|
|
272
|
+
var _job_siteImport, _job_items;
|
|
273
|
+
const state = (_job_siteImport = job.siteImport) != null ? _job_siteImport : null;
|
|
274
|
+
if (!state || !aiSiteImportNextWave(state)) return null;
|
|
275
|
+
const waves = state.waves.filter((wave)=>wave.status === 'waiting').length;
|
|
276
|
+
if (waves < 2) return null;
|
|
277
|
+
return {
|
|
278
|
+
label: 'Start every remaining wave',
|
|
279
|
+
quote: aiCreditRangeText(aiSiteImportRemainingCreditRange(state, (_job_items = job.items) != null ? _job_items : null)),
|
|
280
|
+
waves
|
|
281
|
+
};
|
|
282
|
+
}
|
|
181
283
|
|
|
182
284
|
//# sourceMappingURL=ai-site-import-view.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-site-import-view.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * BRING MY SITE, AS THE CONSOLE SHOWS IT (AGL-3976).\n *\n * Pure: what the \"Create site\" choice card says before anyone clicks, and\n * what an import job's page shows in each of its states — the site read and\n * its waves planned, a wave running, a wave in for review, a wave held for a\n * proof or the day's limit, the import done. The components draw these; the\n * specs hold them.\n *=========================================*/\n\nimport { aiCreditRangeText } from './ai-credit-estimate'\nimport type { AiJobItemLedger, AiJobSummary } from './ai-jobs.types'\nimport {\n AI_SITE_IMPORT_FRAME_SLOT,\n AI_SITE_IMPORT_LEFT_OUT_COPY,\n AI_SITE_IMPORT_LEFT_OUT_REASONS,\n aiSiteImportNextWave,\n aiSiteImportPagesText,\n aiSiteImportReviewWave,\n aiSiteImportRunningWave,\n aiSiteImportWaveCreditRange,\n type AiSiteImportLeftOutReason,\n type AiSiteImportState,\n type AiSiteImportWave,\n} from './ai-site-import'\n\n/** A domain ownership claim, as the ownership door answers it. */\nexport interface AiSiteImportClaim {\n domain: string\n status: 'pending' | 'proven'\n current: boolean\n provenMethod: 'dns' | 'meta' | 'email' | null\n provenAt: number | null\n provenDetail: string | null\n lastChecks: Partial<Record<'dns' | 'meta' | 'email', 'proven' | 'not-yet' | 'unreachable'>>\n dns: { host: string; type: 'TXT'; value: string }\n meta: { name: string; content: string; tag: string }\n email: { domain: string; pendingAddress: string | null; expiresAt: number | null; attemptsLeft: number | null }\n}\n\n/** Whether \"Bring my site\" is offered here, and if not why. */\nexport type AiSiteImportAvailability =\n | { state: 'checking' }\n /** The release flag is off, or the doors cannot be reached: the card is not drawn. */\n | { state: 'hidden' }\n /** Something the workspace can change stands in the way: the card is drawn disabled, with the reason. */\n | { state: 'blocked'; reason: 'plan' | 'role'; message: string }\n | { state: 'ready'; claims: AiSiteImportClaim[] }\n\n/** What the card says to a plan that does not include it. */\nexport const AI_SITE_IMPORT_PLAN_COPY =\n 'Bring your current website in, every page and photo, on any paid plan. Upgrade to bring yours in.'\n\n/** What the card says to a member who cannot. */\nexport const AI_SITE_IMPORT_ROLE_COPY = 'Only the workspace owner or an admin can bring a site in.'\n\n/**\n * The jobs list's `siteImport` offer (AGL-3976), as the card's state: absent\n * is the flag off, and the card is not drawn; `plan` and `role` are drawn\n * disabled with the reason.\n */\nexport function aiSiteImportOfferOf(offer: unknown): AiSiteImportAvailability {\n if (offer === 'ready') return { state: 'ready', claims: [] }\n if (offer === 'plan') return { state: 'blocked', reason: 'plan', message: AI_SITE_IMPORT_PLAN_COPY }\n if (offer === 'role') return { state: 'blocked', reason: 'role', message: AI_SITE_IMPORT_ROLE_COPY }\n return { state: 'hidden' }\n}\n\n/** Where an import job's page is. */\nexport type AiSiteImportPhase =\n /** The site is being read. */\n | 'reading'\n /** Read and planned; the first wave waits to be started. */\n | 'ready'\n /** A wave was started and has not begun yet. */\n | 'starting'\n | 'running'\n /** A wave is in; the next waits to be started. */\n | 'review'\n /** Held for something the person does: verify again, wait for tomorrow, read again. */\n | 'held'\n /** Out of AI credits or at a cap: the meter's pause, carried on by Resume. */\n | 'paused'\n | 'done'\n | 'stopped'\n\nexport function aiSiteImportPhaseOf(job: Pick<AiJobSummary, 'status' | 'review' | 'siteImport'>): AiSiteImportPhase {\n const state = job.siteImport ?? null\n if (job.status === 'done') return 'done'\n if (job.status === 'failed' || job.status === 'canceled') return 'stopped'\n if (job.status === 'needs_input') return 'paused'\n if (job.status === 'needs_review') {\n if (job.review?.reason !== 'wave' || !state) return 'held'\n return aiSiteImportReviewWave(state) ? 'review' : 'ready'\n }\n if (!state) return 'reading'\n return aiSiteImportRunningWave(state) ? 'running' : 'starting'\n}\n\nexport type AiSiteImportRowState = 'waiting' | 'active' | 'done' | 'failed' | 'skipped'\n\nexport interface AiSiteImportRowView {\n slot: string\n title: string\n /** Where it is on the old site. */\n from: string\n /** Where it is on the new one. */\n to: string\n state: AiSiteImportRowState\n /** Why it failed or was left out, or what the person should know. */\n note: string | null\n /** \"3 photos added, 1 already in your library\". */\n photos: string | null\n /** The draft the row wrote, by its output id. */\n outputId: string | null\n}\n\nfunction rowState(row: AiJobItemLedger | undefined, active: boolean): AiSiteImportRowState {\n if (!row) return 'waiting'\n if (row.status === 'succeeded' || row.status === 'degraded') return 'done'\n if (row.status === 'failed') return 'failed'\n if (row.status === 'skipped') return 'skipped'\n return active ? 'active' : 'waiting'\n}\n\n/** \"3 photos added\", \"2 photos added, 1 already in your library\". */\nexport function aiSiteImportPhotosText(photos: { brought: number; reused: number } | null | undefined): string | null {\n if (!photos || photos.brought + photos.reused === 0) return null\n const added = photos.brought ? `${photos.brought} ${photos.brought === 1 ? 'photo' : 'photos'} added` : ''\n const reused = photos.reused ? `${photos.reused} already in your media library` : ''\n return [added, reused].filter(Boolean).join(', ')\n}\n\n/** One wave's rows, the header and footer first where the wave builds them. */\nexport function aiSiteImportWaveRows(\n job: Pick<AiJobSummary, 'items' | 'siteImport' | 'status'>,\n wave: AiSiteImportWave,\n): AiSiteImportRowView[] {\n const state = job.siteImport as AiSiteImportState\n const items = new Map((job.items ?? []).map((row) => [row.slot, row]))\n const running = wave.status === 'running' && (job.status === 'running' || job.status === 'queued')\n let activeTaken = false\n const active = (row: AiJobItemLedger | undefined) => {\n if (!running || activeTaken || !row || (row.status !== 'pending' && row.status !== 'running')) return false\n activeTaken = true\n return true\n }\n const rows: AiSiteImportRowView[] = []\n if (wave.frame && state.frame) {\n const row = items.get(AI_SITE_IMPORT_FRAME_SLOT)\n rows.push({\n slot: AI_SITE_IMPORT_FRAME_SLOT,\n title: 'Header and footer',\n from: `Your menu on ${state.domain}`,\n to: 'Every page',\n state: rowState(row, active(row)),\n note: row?.failure?.message ?? row?.note ?? null,\n photos: null,\n outputId: row?.outputs[0] ?? null,\n })\n }\n for (const slot of wave.slots) {\n const page = state.pages.find((entry) => entry.slot === slot)\n if (!page) continue\n const row = items.get(slot)\n rows.push({\n slot,\n title: page.title,\n from: page.path,\n to: page.slug === '/' ? '/' : `/${page.slug}`,\n state: rowState(row, active(row)),\n note: row?.failure?.message ?? row?.note ?? (page.refused ? AI_SITE_IMPORT_LEFT_OUT_COPY[page.refused] : null),\n photos: aiSiteImportPhotosText(page.photos),\n outputId: row?.outputs[0] ?? null,\n })\n }\n return rows\n}\n\n/** \"About 189 credits (up to 650)\" for the wave, as it stands. */\nexport function aiSiteImportWaveQuote(job: Pick<AiJobSummary, 'items' | 'siteImport'>, wave: AiSiteImportWave): string {\n return aiCreditRangeText(aiSiteImportWaveCreditRange(job.siteImport as AiSiteImportState, wave, job.items ?? null))\n}\n\n/** What a wave cost, its pages' credits less what was given back. */\nexport function aiSiteImportWaveSpent(job: Pick<AiJobSummary, 'items'>, wave: AiSiteImportWave): number {\n const slots = new Set([...wave.slots, ...(wave.frame ? [AI_SITE_IMPORT_FRAME_SLOT] : [])])\n return (job.items ?? [])\n .filter((row) => slots.has(row.slot))\n .reduce((total, row) => total + Math.max(0, (row.creditsSpent ?? 0) - (row.creditsRefunded ?? 0)), 0)\n}\n\n/** The read site in one sentence: \"Found 21 pages on harbor-dental.com: Main pages (6) and Blog (14).\" */\nexport function aiSiteImportFoundText(state: AiSiteImportState): string {\n const groups = state.groups.map((group) => `${group.label} (${group.pages})`)\n const listed =\n groups.length <= 1 ? groups.join('') : `${groups.slice(0, -1).join(', ')} and ${groups[groups.length - 1]}`\n const found = `Found ${aiSiteImportPagesText(state.found)} on ${state.domain}`\n return listed ? `${found}: ${listed}.` : `${found}.`\n}\n\n/** The plan's page count against the site: \"Your plan includes 25 pages and this site has 0, so 20 are brought in.\" */\nexport function aiSiteImportPlanText(state: AiSiteImportState): string {\n const kept = state.pages.length\n const waves = state.waves.length\n const plan =\n state.pageLimit === null\n ? 'Your plan has no page limit'\n : `Your plan includes ${aiSiteImportPagesText(state.pageLimit)} and this site has ${state.existingPages}`\n return `${plan}, so ${aiSiteImportPagesText(kept)} ${kept === 1 ? 'is' : 'are'} brought in, in ${waves === 1 ? 'one wave' : `${waves} waves`}.`\n}\n\n/** What was left out, by reason, most first. */\nexport function aiSiteImportLeftOutLines(state: AiSiteImportState): Array<{ reason: AiSiteImportLeftOutReason; count: number; text: string; paths: string[] }> {\n return AI_SITE_IMPORT_LEFT_OUT_REASONS.map((reason) => ({\n reason,\n count: state.leftOutCount[reason] ?? 0,\n text: AI_SITE_IMPORT_LEFT_OUT_COPY[reason],\n paths: state.leftOut.filter((entry) => entry.reason === reason).map((entry) => entry.path),\n }))\n .filter((line) => line.count > 0)\n .sort((a, b) => b.count - a.count)\n}\n\n/** The wave a page offers to start next, and its button's words. */\nexport function aiSiteImportStartAction(\n job: Pick<AiJobSummary, 'siteImport' | 'items'>,\n): { wave: AiSiteImportWave; label: string; quote: string } | null {\n const state = job.siteImport ?? null\n const wave = aiSiteImportNextWave(state)\n if (!state || !wave) return null\n return { wave, label: `Start ${wave.label}`, quote: aiSiteImportWaveQuote(job, wave) }\n}\n"],"names":["aiCreditRangeText","AI_SITE_IMPORT_FRAME_SLOT","AI_SITE_IMPORT_LEFT_OUT_COPY","AI_SITE_IMPORT_LEFT_OUT_REASONS","aiSiteImportNextWave","aiSiteImportPagesText","aiSiteImportReviewWave","aiSiteImportRunningWave","aiSiteImportWaveCreditRange","AI_SITE_IMPORT_PLAN_COPY","AI_SITE_IMPORT_ROLE_COPY","aiSiteImportOfferOf","offer","state","claims","reason","message","aiSiteImportPhaseOf","job","siteImport","status","review","rowState","row","active","aiSiteImportPhotosText","photos","brought","reused","added","filter","Boolean","join","aiSiteImportWaveRows","wave","items","Map","map","slot","running","activeTaken","rows","frame","get","push","title","from","domain","to","note","failure","outputId","outputs","slots","page","pages","find","entry","path","slug","refused","aiSiteImportWaveQuote","aiSiteImportWaveSpent","Set","has","reduce","total","Math","max","creditsSpent","creditsRefunded","aiSiteImportFoundText","groups","group","label","listed","length","slice","found","aiSiteImportPlanText","kept","waves","plan","pageLimit","existingPages","aiSiteImportLeftOutLines","count","leftOutCount","text","paths","leftOut","line","sort","a","b","aiSiteImportStartAction","quote"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-site-import-view.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * BRING MY SITE, AS THE CONSOLE SHOWS IT (AGL-3976).\n *\n * Pure: what the \"Create site\" choice card says before anyone clicks, and\n * what an import job's page shows in each of its states — the site read and\n * its waves planned, a wave running, a wave in for review, a wave held for a\n * proof or the day's limit, the import done. The components draw these; the\n * specs hold them.\n *=========================================*/\n\nimport { PLATFORM_BRAND_NAME } from '@aglyn/aglyn/app-utils/platform-brand'\nimport { aiCreditRangeText } from './ai-credit-estimate'\nimport type { AiJobItemLedger, AiJobSummary } from './ai-jobs.types'\nimport {\n AI_SITE_IMPORT_FRAME_SLOT,\n AI_SITE_IMPORT_LEFT_OUT_COPY,\n AI_SITE_IMPORT_LEFT_OUT_REASONS,\n AI_SITE_IMPORT_UNREAD_REASONS,\n aiSiteImportNextWave,\n aiSiteImportPagesText,\n aiSiteImportQuoteText,\n aiSiteImportReadStops,\n aiSiteImportReadVerdictMessage,\n aiSiteImportReadVerdictReason,\n aiSiteImportRemainingCreditRange,\n aiSiteImportReviewWave,\n aiSiteImportRunningWave,\n aiSiteImportWaveCreditRange,\n aiSiteImportWaveOwed,\n type AiSiteImportLeftOutReason,\n type AiSiteImportState,\n type AiSiteImportWave,\n} from './ai-site-import'\n\n/** A domain ownership claim, as the ownership door answers it. */\nexport interface AiSiteImportClaim {\n domain: string\n status: 'pending' | 'proven'\n current: boolean\n provenMethod: 'dns' | 'meta' | 'email' | null\n provenAt: number | null\n provenDetail: string | null\n lastChecks: Partial<Record<'dns' | 'meta' | 'email', 'proven' | 'not-yet' | 'unreachable'>>\n dns: { host: string; type: 'TXT'; value: string }\n meta: { name: string; content: string; tag: string }\n email: { domain: string; pendingAddress: string | null; expiresAt: number | null; attemptsLeft: number | null }\n}\n\n/** Whether \"Bring my site\" is offered here, and if not why. */\nexport type AiSiteImportAvailability =\n | { state: 'checking' }\n /** The release flag is off, or the doors cannot be reached: the card is not drawn. */\n | { state: 'hidden' }\n /** Something the workspace can change stands in the way: the card is drawn disabled, with the reason. */\n | { state: 'blocked'; reason: 'plan' | 'role'; message: string }\n | { state: 'ready'; claims: AiSiteImportClaim[] }\n\n/** What the card says to a plan that does not include it. */\nexport const AI_SITE_IMPORT_PLAN_COPY =\n 'Bring your current website in, every page and photo, on any paid plan. Upgrade to bring yours in.'\n\n/** What the card says to a member who cannot. */\nexport const AI_SITE_IMPORT_ROLE_COPY = 'Only the workspace owner or an admin can bring a site in.'\n\n/**\n * The jobs list's `siteImport` offer (AGL-3976), as the card's state: absent\n * is the flag off, and the card is not drawn; `plan` and `role` are drawn\n * disabled with the reason.\n */\nexport function aiSiteImportOfferOf(offer: unknown): AiSiteImportAvailability {\n if (offer === 'ready') return { state: 'ready', claims: [] }\n if (offer === 'plan') return { state: 'blocked', reason: 'plan', message: AI_SITE_IMPORT_PLAN_COPY }\n if (offer === 'role') return { state: 'blocked', reason: 'role', message: AI_SITE_IMPORT_ROLE_COPY }\n return { state: 'hidden' }\n}\n\n/** Where an import job's page is. */\nexport type AiSiteImportPhase =\n /** The site is being read. */\n | 'reading'\n /** Read and planned; the first wave waits to be started. */\n | 'ready'\n /** A wave was started and has not begun yet. */\n | 'starting'\n | 'running'\n /** A wave is in; the next waits to be started. */\n | 'review'\n /** Held for something the person does: verify again, wait for tomorrow, read again. */\n | 'held'\n /** Out of AI credits or at a cap: the meter's pause, carried on by Resume. */\n | 'paused'\n | 'done'\n | 'stopped'\n\nexport function aiSiteImportPhaseOf(job: Pick<AiJobSummary, 'status' | 'review' | 'siteImport'>): AiSiteImportPhase {\n const state = job.siteImport ?? null\n // A read that stopped at its home page is held, and its Check again reads again (AGL-4083).\n const stopped = aiSiteImportReadStops(state?.verdict)\n if (job.status === 'done') return 'done'\n if (job.status === 'failed' || job.status === 'canceled') return 'stopped'\n if (job.status === 'needs_input') return 'paused'\n if (job.status === 'needs_review') {\n if (job.review?.reason !== 'wave' || !state || stopped) return 'held'\n return aiSiteImportReviewWave(state) ? 'review' : 'ready'\n }\n if (!state || stopped) return 'reading'\n return aiSiteImportRunningWave(state) ? 'running' : 'starting'\n}\n\n/**\n * How a hold that is the site's to fix reads (AGL-4083): its heading, its\n * sentence and its button. A home page bot protection turned away, or one\n * that could not be read, is checked again for free; `null` for any other\n * hold, which keeps its own words.\n */\nexport function aiSiteImportHeldCopy(\n job: Pick<AiJobSummary, 'review' | 'siteImport'>,\n): { heading: string; message: string; action: string } | null {\n const state = job.siteImport ?? null\n const fromState = aiSiteImportReadStops(state?.verdict) ? aiSiteImportReadVerdictReason(state?.verdict) : null\n const reason = job.review?.reason === 'blocked' || job.review?.reason === 'unreadable' ? job.review.reason : fromState\n if (!reason) return null\n const message =\n (fromState && state ? aiSiteImportReadVerdictMessage(state.verdict, state.domain) : null) ?? job.review?.message ?? ''\n return {\n heading: reason === 'blocked' ? 'AglynBot was turned away' : 'Your home page could not be read',\n message,\n action: 'Check again',\n }\n}\n\nexport type AiSiteImportRowState = 'waiting' | 'active' | 'done' | 'failed' | 'skipped'\n\nexport interface AiSiteImportRowView {\n slot: string\n title: string\n /** Where it is on the old site. */\n from: string\n /** Where it is on the new one. */\n to: string\n state: AiSiteImportRowState\n /** Why it failed or was left out, or what the person should know. */\n note: string | null\n /** \"3 photos added, 1 already in your library\". */\n photos: string | null\n /** The draft the row wrote, by its output id. */\n outputId: string | null\n /** The page on the old site, to open beside the draft (AGL-4083). */\n oldPage: string\n /** \"1,204 of 1,310 words\", once the page is in and the step has counted them. */\n words: string | null\n /** \"Copied as it is\" or \"Arranged by Aglyn AI\", once the step has chosen. */\n build: string | null\n}\n\nfunction rowState(row: AiJobItemLedger | undefined, active: boolean): AiSiteImportRowState {\n if (!row) return 'waiting'\n if (row.status === 'succeeded' || row.status === 'degraded') return 'done'\n if (row.status === 'failed') return 'failed'\n if (row.status === 'skipped') return 'skipped'\n return active ? 'active' : 'waiting'\n}\n\n/**\n * \"3 photos added\", \"2 photos added, 1 already in your media library\"; with\n * photos that could not come in, against all it tried: \"3 of 5 photos: 2\n * added, 1 already in your media library, 2 could not be brought in\".\n */\nexport function aiSiteImportPhotosText(\n photos: { brought: number; reused: number; skipped?: number } | null | undefined,\n): string | null {\n if (!photos) return null\n const skipped = Math.max(0, photos.skipped ?? 0)\n const into = photos.brought + photos.reused\n if (into === 0 && skipped === 0) return null\n if (!skipped) {\n const added = photos.brought ? `${photos.brought} ${photos.brought === 1 ? 'photo' : 'photos'} added` : ''\n const reused = photos.reused ? `${photos.reused} already in your media library` : ''\n return [added, reused].filter(Boolean).join(', ')\n }\n const parts = [\n photos.brought ? `${photos.brought} added` : '',\n photos.reused ? `${photos.reused} already in your media library` : '',\n `${skipped} could not be brought in`,\n ].filter(Boolean)\n const tried = into + skipped\n return `${into} of ${tried} ${tried === 1 ? 'photo' : 'photos'}: ${parts.join(', ')}`\n}\n\nconst BUILD_COPY = { copied: 'Copied as it is', arranged: `Arranged by ${PLATFORM_BRAND_NAME} AI` } as const\n\n/** One wave's rows, the header and footer first where the wave builds them. */\nexport function aiSiteImportWaveRows(\n job: Pick<AiJobSummary, 'items' | 'siteImport' | 'status'>,\n wave: AiSiteImportWave,\n): AiSiteImportRowView[] {\n const state = job.siteImport as AiSiteImportState\n const items = new Map((job.items ?? []).map((row) => [row.slot, row]))\n const running = wave.status === 'running' && (job.status === 'running' || job.status === 'queued')\n let activeTaken = false\n const active = (row: AiJobItemLedger | undefined) => {\n if (!running || activeTaken || !row || (row.status !== 'pending' && row.status !== 'running')) return false\n activeTaken = true\n return true\n }\n const rows: AiSiteImportRowView[] = []\n if (wave.frame && state.frame) {\n const row = items.get(AI_SITE_IMPORT_FRAME_SLOT)\n rows.push({\n slot: AI_SITE_IMPORT_FRAME_SLOT,\n title: 'Header and footer',\n from: `Your menu on ${state.domain}`,\n to: 'Every page',\n state: rowState(row, active(row)),\n note: row?.failure?.message ?? row?.note ?? null,\n photos: null,\n outputId: row?.outputs[0] ?? null,\n oldPage: `https://${state.domain}/`,\n words: null,\n build: null,\n })\n }\n for (const slot of wave.slots) {\n const page = state.pages.find((entry) => entry.slot === slot)\n if (!page) continue\n const row = items.get(slot)\n rows.push({\n slot,\n title: page.title,\n from: page.path,\n to: page.slug === '/' ? '/' : `/${page.slug}`,\n state: rowState(row, active(row)),\n note: row?.failure?.message ?? row?.note ?? (page.refused ? AI_SITE_IMPORT_LEFT_OUT_COPY[page.refused] : null),\n photos: aiSiteImportPhotosText(page.photos),\n outputId: row?.outputs[0] ?? null,\n oldPage: page.url,\n words: page.brought ? `${page.brought.words.toLocaleString('en-US')} of ${page.words.toLocaleString('en-US')} words` : null,\n build: page.build ? BUILD_COPY[page.build] : null,\n })\n }\n return rows\n}\n\n/**\n * \"About 189 credits (up to 650)\" for the wave, as it stands; once the step\n * has chosen how its pages are built, it names them: \"…: 7 pages arranged by\n * Aglyn AI, 3 copied as they are\" (AGL-4083).\n */\nexport function aiSiteImportWaveQuote(job: Pick<AiJobSummary, 'items' | 'siteImport'>, wave: AiSiteImportWave): string {\n const state = job.siteImport as AiSiteImportState\n const range = aiSiteImportWaveCreditRange(state, wave, job.items ?? null)\n return aiSiteImportQuoteText(range, aiSiteImportWaveOwed(state, wave, job.items ?? null))\n}\n\n/** What a wave cost, its pages' credits less what was given back. */\nexport function aiSiteImportWaveSpent(job: Pick<AiJobSummary, 'items'>, wave: AiSiteImportWave): number {\n const slots = new Set([...wave.slots, ...(wave.frame ? [AI_SITE_IMPORT_FRAME_SLOT] : [])])\n return (job.items ?? [])\n .filter((row) => slots.has(row.slot))\n .reduce((total, row) => total + Math.max(0, (row.creditsSpent ?? 0) - (row.creditsRefunded ?? 0)), 0)\n}\n\n/** Pages the site has that AglynBot could not read: turned away, unanswered, too large or never reached. */\nexport function aiSiteImportUnreadCount(state: AiSiteImportState): number {\n return AI_SITE_IMPORT_UNREAD_REASONS.reduce((total, reason) => total + (state.leftOutCount[reason] ?? 0), 0)\n}\n\n/**\n * The read site in one sentence: \"Found 21 pages on harbor-dental.com: Main\n * pages (6) and Blog (14).\" — and how many more could not be read (AGL-4083).\n */\nexport function aiSiteImportFoundText(state: AiSiteImportState): string {\n const groups = state.groups.map((group) => `${group.label} (${group.pages})`)\n const listed =\n groups.length <= 1 ? groups.join('') : `${groups.slice(0, -1).join(', ')} and ${groups[groups.length - 1]}`\n const found = `Found ${aiSiteImportPagesText(state.found)} on ${state.domain}`\n const lead = listed ? `${found}: ${listed}.` : `${found}.`\n const unread = aiSiteImportUnreadCount(state)\n return unread ? `${lead} ${unread.toLocaleString('en-US')} more could not be read; see Not brought in.` : lead\n}\n\n/** Why the read stopped short, when it did and left pages unread (AGL-4083). */\nexport function aiSiteImportStopText(state: AiSiteImportState): string | null {\n const unreached = state.leftOutCount['not-reached'] ?? 0\n if (!unreached) return null\n const first = `Only the first ${aiSiteImportPagesText(state.found)}`\n const rest = 'the rest are listed under Not brought in as not reached.'\n switch (state.stoppedBy) {\n case 'time':\n return `${first} could be read in the time allowed; ${rest}`\n case 'total-bytes':\n return `${first} could be read before the read reached its size limit; ${rest}`\n default:\n return `${first} could be read this time; ${rest}`\n }\n}\n\n/** The read's warning when most of the site was turned away though its home page came in (AGL-4083). */\nexport function aiSiteImportVerdictNote(state: AiSiteImportState): string | null {\n return state.verdict?.kind === 'mostly-blocked' ? aiSiteImportReadVerdictMessage(state.verdict, state.domain) : null\n}\n\n/** The plan's page count against the site: \"Your plan includes 25 pages and this site has 0, so 20 are brought in.\" */\nexport function aiSiteImportPlanText(state: AiSiteImportState): string {\n const kept = state.pages.length\n const waves = state.waves.length\n const plan =\n state.pageLimit === null\n ? 'Your plan has no page limit'\n : `Your plan includes ${aiSiteImportPagesText(state.pageLimit)} and this site has ${state.existingPages}`\n const lead = `${plan}, so ${aiSiteImportPagesText(kept)} ${kept === 1 ? 'is' : 'are'} brought in, in ${waves === 1 ? 'one wave' : `${waves} waves`}.`\n const stop = aiSiteImportStopText(state)\n return stop ? `${lead} ${stop}` : lead\n}\n\n/** What was left out, by reason, most first. */\nexport function aiSiteImportLeftOutLines(state: AiSiteImportState): Array<{ reason: AiSiteImportLeftOutReason; count: number; text: string; paths: string[] }> {\n return AI_SITE_IMPORT_LEFT_OUT_REASONS.map((reason) => ({\n reason,\n count: state.leftOutCount[reason] ?? 0,\n text: AI_SITE_IMPORT_LEFT_OUT_COPY[reason],\n paths: state.leftOut.filter((entry) => entry.reason === reason).map((entry) => entry.path),\n }))\n .filter((line) => line.count > 0)\n .sort((a, b) => b.count - a.count)\n}\n\n/** The wave a page offers to start next, and its button's words. */\nexport function aiSiteImportStartAction(\n job: Pick<AiJobSummary, 'siteImport' | 'items'>,\n): { wave: AiSiteImportWave; label: string; quote: string } | null {\n const state = job.siteImport ?? null\n const wave = aiSiteImportNextWave(state)\n if (!state || !wave) return null\n return { wave, label: `Start ${wave.label}`, quote: aiSiteImportWaveQuote(job, wave) }\n}\n\n/**\n * \"Start every remaining wave\" (AGL-4083), off by default: offered beside the\n * next wave's button when more than one wave waits, quoted as all of them.\n */\nexport function aiSiteImportStartAllAction(\n job: Pick<AiJobSummary, 'siteImport' | 'items'>,\n): { label: string; quote: string; waves: number } | null {\n const state = job.siteImport ?? null\n if (!state || !aiSiteImportNextWave(state)) return null\n const waves = state.waves.filter((wave) => wave.status === 'waiting').length\n if (waves < 2) return null\n return {\n label: 'Start every remaining wave',\n quote: aiCreditRangeText(aiSiteImportRemainingCreditRange(state, job.items ?? null)),\n waves,\n }\n}\n"],"names":["PLATFORM_BRAND_NAME","aiCreditRangeText","AI_SITE_IMPORT_FRAME_SLOT","AI_SITE_IMPORT_LEFT_OUT_COPY","AI_SITE_IMPORT_LEFT_OUT_REASONS","AI_SITE_IMPORT_UNREAD_REASONS","aiSiteImportNextWave","aiSiteImportPagesText","aiSiteImportQuoteText","aiSiteImportReadStops","aiSiteImportReadVerdictMessage","aiSiteImportReadVerdictReason","aiSiteImportRemainingCreditRange","aiSiteImportReviewWave","aiSiteImportRunningWave","aiSiteImportWaveCreditRange","aiSiteImportWaveOwed","AI_SITE_IMPORT_PLAN_COPY","AI_SITE_IMPORT_ROLE_COPY","aiSiteImportOfferOf","offer","state","claims","reason","message","aiSiteImportPhaseOf","job","siteImport","stopped","verdict","status","review","aiSiteImportHeldCopy","fromState","domain","heading","action","rowState","row","active","aiSiteImportPhotosText","photos","skipped","Math","max","into","brought","reused","added","filter","Boolean","join","parts","tried","BUILD_COPY","copied","arranged","aiSiteImportWaveRows","wave","items","Map","map","slot","running","activeTaken","rows","frame","get","push","title","from","to","note","failure","outputId","outputs","oldPage","words","build","slots","page","pages","find","entry","path","slug","refused","url","toLocaleString","aiSiteImportWaveQuote","range","aiSiteImportWaveSpent","Set","has","reduce","total","creditsSpent","creditsRefunded","aiSiteImportUnreadCount","leftOutCount","aiSiteImportFoundText","groups","group","label","listed","length","slice","found","lead","unread","aiSiteImportStopText","unreached","first","rest","stoppedBy","aiSiteImportVerdictNote","kind","aiSiteImportPlanText","kept","waves","plan","pageLimit","existingPages","stop","aiSiteImportLeftOutLines","count","text","paths","leftOut","line","sort","a","b","aiSiteImportStartAction","quote","aiSiteImportStartAllAction"],"mappings":"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"}
|