Milestone v1 (v2.0.0): Mokosh — Session Capture #1
@@ -98,6 +98,17 @@ const NOTIFICATION_STARTUP_PREFIX = 'mokosh-startup-';
|
||||
const NOTIFICATION_RECOVERY_PREFIX = 'mokosh-recovery-';
|
||||
const POPUP_HTML_PATH = 'src/popup/index.html';
|
||||
|
||||
// ─── Plan 01-10 onboarding constants (D-17-onboarding) ───────────────
|
||||
// Project naming standard: SCREAMING_SNAKE for true constants. These
|
||||
// drive the first-install welcome-tab flow (chrome.runtime.onInstalled
|
||||
// → openWelcomeIfFirstInstall; flag persisted via chrome.storage.local).
|
||||
// The 'onboarding-completed' key is the storage-schema identifier
|
||||
// preserved across SW respawns (and surveyed by the unit test in
|
||||
// tests/background/onboarding.test.ts Test A).
|
||||
const ONBOARDING_FLAG = 'onboarding-completed';
|
||||
const ONBOARDING_INSTALLED_AT = 'installed-at';
|
||||
const WELCOME_PATH = 'src/welcome/welcome.html';
|
||||
|
||||
// Plan 01-12 Wave 4: operator-facing copy fallbacks for the notification
|
||||
// title (extName) + the two notification messages. Same `|| fallback`
|
||||
// pattern as the popup — unit-test contexts without chrome.i18n stub
|
||||
@@ -217,6 +228,58 @@ async function ensureOffscreen() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the welcome page on first install (Plan 01-10 D-17-onboarding).
|
||||
*
|
||||
* The 'D-17-onboarding' suffix disambiguates from D-17-port-lifecycle
|
||||
* per CONTEXT.md lines 540-545. Trigger conditions (all must hold):
|
||||
* - details.reason === 'install' (NOT 'update' / 'chrome_update' /
|
||||
* 'shared_module_update');
|
||||
* - chrome.storage.local key 'onboarding-completed' NOT === true.
|
||||
*
|
||||
* Side effects on first install:
|
||||
* - chrome.tabs.create({url: chrome.runtime.getURL('src/welcome/welcome.html')})
|
||||
* - chrome.storage.local.set({'onboarding-completed': true,
|
||||
* 'installed-at': Date.now()})
|
||||
*
|
||||
* Failure mode: any thrown chrome.* call is caught + logged via
|
||||
* logger.warn. The welcome tab failing is NOT fatal — the toolbar
|
||||
* onClicked path (D-16-toolbar) remains the operator's start path and
|
||||
* is independent of the onboarding flow.
|
||||
*
|
||||
* Architectural note: the fetch of 'onboarding-completed' uses the
|
||||
* EXACT string key (no array form) so the unit-test contract in
|
||||
* tests/background/onboarding.test.ts Test A's assertion
|
||||
* "saw chrome.storage.local.get('onboarding-completed')" holds. The
|
||||
* storage-schema cross-version-compat pin (I-02 lesson preserved from
|
||||
* prior plan draft) lives in that test.
|
||||
*/
|
||||
async function openWelcomeIfFirstInstall(
|
||||
details: chrome.runtime.InstalledDetails,
|
||||
): Promise<void> {
|
||||
if (details.reason !== 'install') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stored = await chrome.storage.local.get(ONBOARDING_FLAG);
|
||||
if (stored[ONBOARDING_FLAG] === true) {
|
||||
logger.log('Onboarding already completed; skipping welcome tab.');
|
||||
return;
|
||||
}
|
||||
const url = chrome.runtime.getURL(WELCOME_PATH);
|
||||
await chrome.tabs.create({ url });
|
||||
await chrome.storage.local.set({
|
||||
[ONBOARDING_FLAG]: true,
|
||||
[ONBOARDING_INSTALLED_AT]: Date.now(),
|
||||
});
|
||||
logger.log(
|
||||
'Welcome tab opened (D-17-onboarding); onboarding flag set.',
|
||||
);
|
||||
} catch (err) {
|
||||
logger.warn('openWelcomeIfFirstInstall failed:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// Outer-bound buffer fetch budget. Larger than the legacy
|
||||
// BUFFER_FETCH_TIMEOUT_MS (was 2 s; per-port-attempt) because the new
|
||||
// architecture covers MULTIPLE port-replacement retries inside one outer
|
||||
@@ -1002,6 +1065,14 @@ chrome.runtime.onInstalled.addListener((details) => {
|
||||
logger.warn('IDB cleanup failed:', e);
|
||||
}
|
||||
initialize();
|
||||
// Plan 01-10 D-17-onboarding: open welcome tab on first install.
|
||||
// Fire-and-forget — the helper logs its own errors and rejected
|
||||
// promises are caught at the .catch boundary so they cannot escape
|
||||
// the synchronous listener. The toolbar onClicked start path
|
||||
// (D-16-toolbar) is independent of this flow.
|
||||
openWelcomeIfFirstInstall(details).catch((err) => {
|
||||
logger.warn('openWelcomeIfFirstInstall threw:', err);
|
||||
});
|
||||
});
|
||||
|
||||
// Запуск при старте Service Worker
|
||||
|
||||
Reference in New Issue
Block a user