@storyshelf/app 0.7.0 → 0.9.0-next-d2cc082
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/dist/app-types.d.mts +1 -3
- package/dist/asset-manifest.mjs +1 -2
- package/dist/assets/htmx.mjs +1 -2
- package/dist/assets/mark.mjs +1 -2
- package/dist/boot-tasks.mjs +1 -2
- package/dist/build-state-flags.mjs +1 -2
- package/dist/build-state-setup.mjs +1 -2
- package/dist/capture-alerts.mjs +1 -2
- package/dist/capture-process.mjs +1 -2
- package/dist/capture-setup.mjs +1 -2
- package/dist/connections.mjs +1 -2
- package/dist/consumer-setup.mjs +1 -2
- package/dist/credential-keys.mjs +1 -2
- package/dist/credentials.mjs +1 -2
- package/dist/design-events.mjs +71 -0
- package/dist/design-events.mjs.map +1 -0
- package/dist/git-status.mjs +1 -2
- package/dist/hidden-data.mjs +1 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +2 -3
- package/dist/insights/budget.mjs +1 -2
- package/dist/insights/deps.mjs +1 -2
- package/dist/insights/errors.mjs +1 -2
- package/dist/insights/health-panel.mjs +0 -1
- package/dist/insights/job.mjs +1 -2
- package/dist/insights/load-health.mjs +1 -2
- package/dist/insights/load-triage.mjs +1 -2
- package/dist/insights/panel.mjs +1 -2
- package/dist/insights/request.mjs +1 -2
- package/dist/insights/stale.mjs +1 -2
- package/dist/insights/usage-report.mjs +1 -2
- package/dist/insights/view.mjs +1 -2
- package/dist/job-canceller.mjs +1 -2
- package/dist/job-queue.mjs +1 -2
- package/dist/jobs-setup.mjs +1 -2
- package/dist/lifecycle.mjs +2 -3
- package/dist/lifecycle.mjs.map +1 -1
- package/dist/middleware/auth-gate.mjs +1 -2
- package/dist/middleware/csrf.mjs +1 -2
- package/dist/middleware/rate-limit.mjs +1 -2
- package/dist/middleware/request-log.mjs +1 -2
- package/dist/middleware/require-review.mjs +1 -2
- package/dist/middleware/require-testing.mjs +1 -2
- package/dist/middleware/server-timing.mjs +1 -2
- package/dist/middleware/setup-gate.mjs +1 -2
- package/dist/middleware/store-scope.mjs +1 -2
- package/dist/notifications-pause.mjs +1 -2
- package/dist/notify.d.mts +1 -3
- package/dist/notify.mjs +5 -3
- package/dist/notify.mjs.map +1 -1
- package/dist/pages/a11y-violations.mjs +1 -2
- package/dist/pages/admin-ai.mjs +1 -2
- package/dist/pages/admin-system-origin.mjs +19 -10
- package/dist/pages/admin-system-origin.mjs.map +1 -1
- package/dist/pages/admin-system-targets.mjs +1 -2
- package/dist/pages/admin-system.mjs +1 -2
- package/dist/pages/build-detail.mjs +1 -2
- package/dist/pages/build-diff-actions.mjs +1 -2
- package/dist/pages/build-diff-comments.mjs +1 -2
- package/dist/pages/build-diff-default.mjs +53 -0
- package/dist/pages/build-diff-default.mjs.map +1 -0
- package/dist/pages/build-diff-environment.mjs +34 -5
- package/dist/pages/build-diff-environment.mjs.map +1 -1
- package/dist/pages/build-diff-header.mjs +1 -2
- package/dist/pages/build-diff-insight.mjs +1 -2
- package/dist/pages/build-diff-model.mjs +20 -3
- package/dist/pages/build-diff-model.mjs.map +1 -1
- package/dist/pages/build-diff-nav.mjs +1 -2
- package/dist/pages/build-diff-reference.mjs +84 -0
- package/dist/pages/build-diff-reference.mjs.map +1 -0
- package/dist/pages/build-diff-shortcuts.mjs +1 -2
- package/dist/pages/build-diff-stale.mjs +1 -2
- package/dist/pages/build-diff-usage.mjs +1 -2
- package/dist/pages/build-diff-viewer.mjs +38 -12
- package/dist/pages/build-diff-viewer.mjs.map +1 -1
- package/dist/pages/build-diff.mjs +6 -12
- package/dist/pages/build-diff.mjs.map +1 -1
- package/dist/pages/build-tests.mjs +1 -2
- package/dist/pages/component-detail.mjs +1 -2
- package/dist/pages/component-stories.mjs +1 -2
- package/dist/pages/compute-jobs.mjs +1 -2
- package/dist/pages/design-links.mjs +1 -2
- package/dist/pages/environment-change.mjs +16 -4
- package/dist/pages/environment-change.mjs.map +1 -1
- package/dist/pages/health-panel.mjs +1 -2
- package/dist/pages/invite.mjs +1 -2
- package/dist/pages/label-detail.mjs +1 -2
- package/dist/pages/library-grid.mjs +1 -2
- package/dist/pages/library-model.mjs +1 -2
- package/dist/pages/library-snapshots.mjs +1 -2
- package/dist/pages/library.mjs +1 -2
- package/dist/pages/login.mjs +1 -2
- package/dist/pages/notifications-paused.mjs +1 -2
- package/dist/pages/passkey-ceremony.mjs +1 -2
- package/dist/pages/profile.mjs +1 -2
- package/dist/pages/project-builds-table.mjs +1 -2
- package/dist/pages/project-builds.mjs +1 -2
- package/dist/pages/project-create.mjs +1 -2
- package/dist/pages/project-settings.mjs +1 -2
- package/dist/pages/projects-card.mjs +1 -2
- package/dist/pages/projects.mjs +1 -2
- package/dist/pages/review-changeset.mjs +1 -2
- package/dist/pages/review-comments.mjs +1 -2
- package/dist/pages/review-verdict.mjs +1 -2
- package/dist/pages/root.mjs +1 -2
- package/dist/pages/settings-ai.mjs +1 -2
- package/dist/pages/settings-capture.mjs +1 -2
- package/dist/pages/settings-design-credential.mjs +1 -2
- package/dist/pages/settings-design-links.mjs +1 -2
- package/dist/pages/settings-design.mjs +1 -2
- package/dist/pages/settings-general.mjs +1 -2
- package/dist/pages/settings-labels.mjs +1 -2
- package/dist/pages/settings-links.mjs +1 -2
- package/dist/pages/settings-members.mjs +1 -2
- package/dist/pages/settings-notifications-git.mjs +1 -2
- package/dist/pages/settings-notifications.mjs +1 -2
- package/dist/pages/settings-tests.mjs +1 -2
- package/dist/pages/settings-tokens.mjs +1 -2
- package/dist/pages/settings-webhooks.mjs +1 -2
- package/dist/pages/storybook.mjs +1 -2
- package/dist/pages/target-choices.mjs +1 -2
- package/dist/publish-setup.mjs +1 -2
- package/dist/retention-timer.mjs +10 -11
- package/dist/retention-timer.mjs.map +1 -1
- package/dist/review-events.mjs +1 -2
- package/dist/routers/admin-pages.mjs +1 -2
- package/dist/routers/admin-public-origin.mjs +10 -3
- package/dist/routers/admin-public-origin.mjs.map +1 -1
- package/dist/routers/admin.mjs +8 -4
- package/dist/routers/admin.mjs.map +1 -1
- package/dist/routers/assets.mjs +1 -2
- package/dist/routers/attempts.mjs +1 -2
- package/dist/routers/auth-sync.mjs +1 -2
- package/dist/routers/auth.mjs +1 -2
- package/dist/routers/baseline-guard.mjs +2 -3
- package/dist/routers/baseline-guard.mjs.map +1 -1
- package/dist/routers/baseline-reference.mjs +72 -0
- package/dist/routers/baseline-reference.mjs.map +1 -0
- package/dist/routers/baselines.handlers.mjs +1 -2
- package/dist/routers/baselines.mjs +1 -2
- package/dist/routers/build-cancel.mjs +1 -2
- package/dist/routers/build-changeset.mjs +1 -2
- package/dist/routers/build-reviews.handlers.mjs +1 -2
- package/dist/routers/build-reviews.mjs +1 -2
- package/dist/routers/builds.handlers.mjs +23 -9
- package/dist/routers/builds.handlers.mjs.map +1 -1
- package/dist/routers/builds.mjs +7 -3
- package/dist/routers/builds.mjs.map +1 -1
- package/dist/routers/capture-cache.mjs +29 -0
- package/dist/routers/capture-cache.mjs.map +1 -0
- package/dist/routers/capture-config.mjs +1 -2
- package/dist/routers/comments.mjs +1 -2
- package/dist/routers/comparison-image.mjs +29 -0
- package/dist/routers/comparison-image.mjs.map +1 -0
- package/dist/routers/component-catalog.handlers.mjs +1 -2
- package/dist/routers/component.handlers.mjs +1 -2
- package/dist/routers/connections.mjs +1 -2
- package/dist/routers/design-connect.handlers.mjs +1 -2
- package/dist/routers/design.handlers.mjs +8 -2
- package/dist/routers/design.handlers.mjs.map +1 -1
- package/dist/routers/flash.mjs +1 -2
- package/dist/routers/health-report.mjs +1 -2
- package/dist/routers/health.mjs +1 -2
- package/dist/routers/helpers.mjs +1 -2
- package/dist/routers/htmx.mjs +1 -2
- package/dist/routers/insights-ui.mjs +1 -2
- package/dist/routers/insights.handlers.mjs +1 -2
- package/dist/routers/insights.mjs +1 -2
- package/dist/routers/labels.mjs +1 -2
- package/dist/routers/links.handlers.mjs +1 -2
- package/dist/routers/links.mjs +1 -2
- package/dist/routers/media.mjs +14 -5
- package/dist/routers/media.mjs.map +1 -1
- package/dist/routers/members.mjs +1 -2
- package/dist/routers/notification-channels.mjs +1 -2
- package/dist/routers/notification-subscriptions.mjs +1 -2
- package/dist/routers/oauth-state.mjs +1 -2
- package/dist/routers/preview-base.mjs +1 -2
- package/dist/routers/preview-token.mjs +1 -2
- package/dist/routers/profile.mjs +1 -2
- package/dist/routers/projects.mjs +1 -2
- package/dist/routers/publish-upload.mjs +19 -12
- package/dist/routers/publish-upload.mjs.map +1 -1
- package/dist/routers/published-access.mjs +1 -2
- package/dist/routers/published-compression.mjs +109 -0
- package/dist/routers/published-compression.mjs.map +1 -0
- package/dist/routers/published-files.mjs +26 -9
- package/dist/routers/published-files.mjs.map +1 -1
- package/dist/routers/review-forms.mjs +1 -2
- package/dist/routers/review-next.mjs +1 -2
- package/dist/routers/review-section.handlers.mjs +1 -2
- package/dist/routers/review-switch-off.mjs +1 -2
- package/dist/routers/schemas.mjs +1 -2
- package/dist/routers/scoped-models.mjs +1 -2
- package/dist/routers/settings-ai.mjs +1 -2
- package/dist/routers/settings-capture.mjs +1 -2
- package/dist/routers/settings-design.mjs +1 -2
- package/dist/routers/settings-general.mjs +1 -2
- package/dist/routers/settings-git-channel.mjs +1 -2
- package/dist/routers/settings-labels.mjs +1 -2
- package/dist/routers/settings-links.mjs +1 -2
- package/dist/routers/settings-members.mjs +1 -2
- package/dist/routers/settings-notifications.mjs +1 -2
- package/dist/routers/settings-tokens.mjs +1 -2
- package/dist/routers/settings-webhooks.mjs +1 -2
- package/dist/routers/settings.handlers.mjs +1 -2
- package/dist/routers/settings.mjs +1 -2
- package/dist/routers/signed-storybook.mjs +5 -3
- package/dist/routers/signed-storybook.mjs.map +1 -1
- package/dist/routers/snapshot-groups.mjs +1 -2
- package/dist/routers/snapshots.mjs +1 -2
- package/dist/routers/storybook.mjs +21 -17
- package/dist/routers/storybook.mjs.map +1 -1
- package/dist/routers/tokens.mjs +1 -2
- package/dist/routers/ui.mjs +4 -2
- package/dist/routers/ui.mjs.map +1 -1
- package/dist/routers/webhooks.mjs +1 -2
- package/dist/routers/well-known.mjs +1 -2
- package/dist/routes/api-routes.mjs +1 -2
- package/dist/routes/classification.mjs +1 -2
- package/dist/routes/openapi-classes.mjs +1 -2
- package/dist/routes/page-routes.mjs +2 -3
- package/dist/routes/page-routes.mjs.map +1 -1
- package/dist/runtime.mjs +1 -2
- package/dist/serverless.mjs +1 -2
- package/dist/store.mjs +1 -2
- package/dist/targets.mjs +1 -2
- package/dist/ui/avatar.mjs +1 -2
- package/dist/ui/buttons.mjs +1 -2
- package/dist/ui/code-block.mjs +1 -2
- package/dist/ui/compare-stage.mjs +86 -54
- package/dist/ui/compare-stage.mjs.map +1 -1
- package/dist/ui/csrf-field.mjs +1 -2
- package/dist/ui/css.mjs +1 -2
- package/dist/ui/design-reference.mjs +1 -2
- package/dist/ui/document.mjs +1 -2
- package/dist/ui/dropdown.mjs +1 -2
- package/dist/ui/feedback.mjs +1 -2
- package/dist/ui/filter-input.mjs +1 -2
- package/dist/ui/forms.mjs +1 -2
- package/dist/ui/icons/icon.mjs +1 -2
- package/dist/ui/icons/paths.mjs +1 -2
- package/dist/ui/icons/sprite.mjs +1 -2
- package/dist/ui/kbd.mjs +1 -2
- package/dist/ui/layout.mjs +1 -2
- package/dist/ui/preview-embed.mjs +1 -2
- package/dist/ui/progress.mjs +1 -2
- package/dist/ui/segmented.mjs +1 -2
- package/dist/ui/shell/account.mjs +1 -2
- package/dist/ui/shell/bare.mjs +1 -2
- package/dist/ui/shell/boot-script.mjs +1 -2
- package/dist/ui/shell/client-script.mjs +1 -2
- package/dist/ui/shell/nav.mjs +1 -2
- package/dist/ui/shell/review-script.mjs +17 -3
- package/dist/ui/shell/review-script.mjs.map +1 -1
- package/dist/ui/shell/sidebar.mjs +1 -2
- package/dist/ui/shell/topbar.mjs +1 -2
- package/dist/ui/stacks.mjs +1 -2
- package/dist/ui/styles/base.mjs +1 -2
- package/dist/ui/styles/behavior.mjs +1 -2
- package/dist/ui/styles/review-layout.mjs +1 -2
- package/dist/ui/styles/review.mjs +1 -2
- package/dist/ui/styles/tokens.mjs +1 -2
- package/dist/ui/styles.mjs +1 -2
- package/dist/ui/subnav.mjs +1 -2
- package/dist/ui/table.mjs +1 -2
- package/dist/ui/theme.mjs +1 -2
- package/dist/ui/thumbnail.mjs +1 -2
- package/dist/ui/time.mjs +1 -2
- package/package.json +9 -18
package/dist/app-types.d.mts
CHANGED
|
@@ -5,11 +5,10 @@ import { AdapterSetupResult } from "@storyshelf/core/adapter/setup";
|
|
|
5
5
|
import { ShelfConfig, UIConfig } from "@storyshelf/core/config";
|
|
6
6
|
import { NotifierProvider } from "@storyshelf/core/adapter/notifier";
|
|
7
7
|
import { AuthUser } from "@storyshelf/core/types";
|
|
8
|
+
import { DatabaseAdapter } from "@storyshelf/core/adapter/database";
|
|
8
9
|
import { Logger, createShelfLogger } from "@storyshelf/core/logger";
|
|
9
10
|
import { CaptureQueue } from "@storyshelf/core/adapter/capture-queue";
|
|
10
|
-
import { DatabaseAdapter } from "@storyshelf/core/adapter/database";
|
|
11
11
|
import { StorageAdapter } from "@storyshelf/core/adapter/storage";
|
|
12
|
-
//#region src/app-types.d.ts
|
|
13
12
|
/** Per-request shelf context (adapters, config, user, capture queue). */
|
|
14
13
|
interface ShelfContext {
|
|
15
14
|
requestId?: string;
|
|
@@ -47,6 +46,5 @@ interface ShelfLifecycle {
|
|
|
47
46
|
type ShelfApp = ShelfRouter & {
|
|
48
47
|
readonly lifecycle: ShelfLifecycle;
|
|
49
48
|
};
|
|
50
|
-
//#endregion
|
|
51
49
|
export { ShelfApp, ShelfContext, ShelfLifecycle, ShelfRouter };
|
|
52
50
|
//# sourceMappingURL=app-types.d.mts.map
|
package/dist/asset-manifest.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { contentHash, iconSprite, iconSpriteHash, iconSpriteHref } from "./ui/ic
|
|
|
5
5
|
import { htmxSource } from "./assets/htmx.mjs";
|
|
6
6
|
import { markSource } from "./assets/mark.mjs";
|
|
7
7
|
import { clientScript } from "./ui/shell/client-script.mjs";
|
|
8
|
-
|
|
8
|
+
// src/asset-manifest.ts
|
|
9
9
|
/**
|
|
10
10
|
* Static assets with content-addressed URLs. A URL that embeds the content
|
|
11
11
|
* hash may be cached forever (`immutable`): changing the file changes the
|
|
@@ -43,7 +43,6 @@ const assetManifest = {
|
|
|
43
43
|
href: `/assets/mark-${markHash}.svg`
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
|
-
//#endregion
|
|
47
46
|
export { assetManifest };
|
|
48
47
|
|
|
49
48
|
//# sourceMappingURL=asset-manifest.mjs.map
|
package/dist/assets/htmx.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/assets/htmx.ts
|
|
5
5
|
const htmxSource = String.raw`(function (e, t) {
|
|
6
6
|
if (typeof define === "function" && define.amd) {
|
|
7
7
|
define([], t);
|
|
@@ -3307,7 +3307,6 @@ const htmxSource = String.raw`(function (e, t) {
|
|
|
3307
3307
|
})();
|
|
3308
3308
|
});
|
|
3309
3309
|
`;
|
|
3310
|
-
//#endregion
|
|
3311
3310
|
export { htmxSource };
|
|
3312
3311
|
|
|
3313
3312
|
//# sourceMappingURL=htmx.mjs.map
|
package/dist/assets/mark.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/assets/mark.ts
|
|
5
5
|
/** The StoryShelf brand mark (an SVG): the favicon and the default sidebar logo. */
|
|
6
6
|
const markSource = String.raw`<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64' role='img' aria-label='StoryShelf'><rect width='64' height='64' rx='14' fill='#1d5fcf'/><path d='M15 11 H49 A4 4 0 0 1 53 15 V15 A2 2 0 0 1 51 17 H13 A2 2 0 0 1 11 15 V15 A4 4 0 0 1 15 11 Z' fill='#ffffff'/><path d='M13 29 H51 A2 2 0 0 1 53 31 V33 A2 2 0 0 1 51 35 H13 A2 2 0 0 1 11 33 V31 A2 2 0 0 1 13 29 Z' fill='#ffffff'/><path d='M13 47 H51 A2 2 0 0 1 53 49 V49 A4 4 0 0 1 49 53 H15 A4 4 0 0 1 11 49 V49 A2 2 0 0 1 13 47 Z' fill='#ffffff'/><path d='M16 19 H16 A2 2 0 0 1 18 21 V27 A2 2 0 0 1 16 29 H16 A2 2 0 0 1 14 27 V21 A2 2 0 0 1 16 19 Z' fill='#ffffff'/><path d='M22 21 H22 A2 2 0 0 1 24 23 V27 A2 2 0 0 1 22 29 H22 A2 2 0 0 1 20 27 V23 A2 2 0 0 1 22 21 Z' fill='#ffffff'/><path d='M28 23 H28 A2 2 0 0 1 30 25 V27 A2 2 0 0 1 28 29 H28 A2 2 0 0 1 26 27 V25 A2 2 0 0 1 28 23 Z' fill='#ffffff'/><path d='M48 37 H48 A2 2 0 0 1 50 39 V45 A2 2 0 0 1 48 47 H48 A2 2 0 0 1 46 45 V39 A2 2 0 0 1 48 37 Z' fill='#ffffff'/><path d='M42 39 H42 A2 2 0 0 1 44 41 V45 A2 2 0 0 1 42 47 H42 A2 2 0 0 1 40 45 V41 A2 2 0 0 1 42 39 Z' fill='#ffffff'/><path d='M36 41 H36 A2 2 0 0 1 38 43 V45 A2 2 0 0 1 36 47 H36 A2 2 0 0 1 34 45 V43 A2 2 0 0 1 36 41 Z' fill='#ffffff'/></svg>`;
|
|
7
|
-
//#endregion
|
|
8
7
|
export { markSource };
|
|
9
8
|
|
|
10
9
|
//# sourceMappingURL=mark.mjs.map
|
package/dist/boot-tasks.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { startConsumer, trackBackground } from "./lifecycle.mjs";
|
|
|
6
6
|
import { checkCredentialsAfterSetup } from "./credentials.mjs";
|
|
7
7
|
import { logHostingOnlyMode } from "./hidden-data.mjs";
|
|
8
8
|
import { requestOpenBuildStates, sweepOrphanedScratch } from "@storyshelf/core/capture";
|
|
9
|
-
|
|
9
|
+
// src/boot-tasks.ts
|
|
10
10
|
/**
|
|
11
11
|
* Boot-time work that runs once adapters are ready: the job consumer starts (there is no boot sweep
|
|
12
12
|
* of builds left `capturing`: leases expire and jobs are redelivered, so a second instance can
|
|
@@ -74,7 +74,6 @@ function sweepScratchOnBoot(cell, scratchDir, logger) {
|
|
|
74
74
|
logger.warn({ err: error }, "scratch sweep failed");
|
|
75
75
|
}));
|
|
76
76
|
}
|
|
77
|
-
//#endregion
|
|
78
77
|
export { runBootTasks };
|
|
79
78
|
|
|
80
79
|
//# sourceMappingURL=boot-tasks.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/build-state-flags.ts
|
|
5
5
|
/**
|
|
6
6
|
* What decides which statuses a project's builds show: the instance's `testing` and the project's
|
|
7
7
|
* review switch (a row without the column, from a hand-built table, counts as on, the default).
|
|
@@ -12,7 +12,6 @@ function buildStateFlags(testing, project) {
|
|
|
12
12
|
review: project.reviewEnabled !== false
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
//#endregion
|
|
16
15
|
export { buildStateFlags };
|
|
17
16
|
|
|
18
17
|
//# sourceMappingURL=build-state-flags.mjs.map
|
|
@@ -6,7 +6,7 @@ import { notifySystemWith } from "./notify.mjs";
|
|
|
6
6
|
import { buildStateFlags } from "./build-state-flags.mjs";
|
|
7
7
|
import { createBuildStatePublisher, createNotifyEnqueuer, createNotifyHandler, notifyExhausted } from "@storyshelf/core/capture";
|
|
8
8
|
import { ProjectModel } from "@storyshelf/core/models";
|
|
9
|
-
|
|
9
|
+
// src/build-state-setup.ts
|
|
10
10
|
/**
|
|
11
11
|
* Build-state wiring (ADR 0014, decisions 5 and 7): the publisher every build transition calls and
|
|
12
12
|
* the `notify` job kind behind it. On a host that polls the queue, a transition queues one durable
|
|
@@ -69,7 +69,6 @@ async function alertAdmins(options, runtime, failure) {
|
|
|
69
69
|
message: `${failure.provider} channel of ${project?.slug ?? "a project"} could not show build ${failure.buildId}: ${failure.error}`
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
|
-
//#endregion
|
|
73
72
|
export { setupBuildState };
|
|
74
73
|
|
|
75
74
|
//# sourceMappingURL=build-state-setup.mjs.map
|
package/dist/capture-alerts.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { notifyProjectWith, notifySystemWith } from "./notify.mjs";
|
|
5
5
|
import { BuildModel, ProjectModel } from "@storyshelf/core/models";
|
|
6
|
-
|
|
6
|
+
// src/capture-alerts.ts
|
|
7
7
|
/**
|
|
8
8
|
* Builds already alerted about, keyed by the build's last update. A sharded build settles one job
|
|
9
9
|
* per shard and every one of them sees the failed build; only the first alerts. A retry rewrites
|
|
@@ -40,7 +40,6 @@ async function notifyCaptureFailed(options, config, logger, buildId, publicOrigi
|
|
|
40
40
|
status: "failed"
|
|
41
41
|
}, `/builds/${buildId}`);
|
|
42
42
|
}
|
|
43
|
-
//#endregion
|
|
44
43
|
export { alreadyAlerted, notifyCaptureFailed };
|
|
45
44
|
|
|
46
45
|
//# sourceMappingURL=capture-alerts.mjs.map
|
package/dist/capture-process.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { DIFF_WORKERS_ENV, IMAGE_ENGINE_ENV } from "@storyshelf/core/diff";
|
|
5
5
|
import { detectResources } from "@storyshelf/core/utils";
|
|
6
6
|
import { CAPTURE_RETRIES_ENV, CAPTURE_SHARD_SIZE_ENV, canForkCaptureChild, createForkedCaptureHandler, decideCaptureProcess, forkCaptureChild } from "@storyshelf/core/capture";
|
|
7
|
-
|
|
7
|
+
// src/capture-process.ts
|
|
8
8
|
/** Chooses between in-process and forked capture, and builds the forked handler. */
|
|
9
9
|
/**
|
|
10
10
|
* Whether to fork a capture child. `mode: "fork"` forces it (and fails if it cannot); `auto` forks
|
|
@@ -53,7 +53,6 @@ function createForkedHandler(deps) {
|
|
|
53
53
|
logger: deps.logger
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
//#endregion
|
|
57
56
|
export { childEnvOf, createForkedHandler, shouldForkCapture };
|
|
58
57
|
|
|
59
58
|
//# sourceMappingURL=capture-process.mjs.map
|
package/dist/capture-setup.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { createForkedHandler, shouldForkCapture } from "./capture-process.mjs";
|
|
|
7
7
|
import { DEFAULT_SCRATCH_DIR } from "@storyshelf/core/config";
|
|
8
8
|
import { currentTraceparent } from "@storyshelf/observability";
|
|
9
9
|
import { DEFAULT_RETRIES, captureDispatchDeps, createCaptureHandler, failCrashedCapture, isFinalAttempt } from "@storyshelf/core/capture";
|
|
10
|
-
|
|
10
|
+
// src/capture-setup.ts
|
|
11
11
|
/** Queue a build, continuing the active request trace when present. */
|
|
12
12
|
function enqueuerFor(queue) {
|
|
13
13
|
return async (buildId, reqId) => {
|
|
@@ -111,7 +111,6 @@ function alerting(inner, retries, alert) {
|
|
|
111
111
|
...inner.close ? { close: inner.close } : {}
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
|
-
//#endregion
|
|
115
114
|
export { setupCapture };
|
|
116
115
|
|
|
117
116
|
//# sourceMappingURL=capture-setup.mjs.map
|
package/dist/connections.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { credentialKeys } from "./credential-keys.mjs";
|
|
5
5
|
import { getStore } from "./store.mjs";
|
|
6
6
|
import { ConnectionModel } from "@storyshelf/core/models";
|
|
7
|
-
|
|
7
|
+
// src/connections.ts
|
|
8
8
|
/**
|
|
9
9
|
* Services a user can connect their own account to. Today only design providers
|
|
10
10
|
* offer OAuth; a future issue-tracker or notifier adapter that exposes
|
|
@@ -28,7 +28,6 @@ function canConnect() {
|
|
|
28
28
|
const { authEnabled, user, config } = getStore();
|
|
29
29
|
return authEnabled && Boolean(user) && Boolean(config.secret);
|
|
30
30
|
}
|
|
31
|
-
//#endregion
|
|
32
31
|
export { canConnect, connectableServices, connectionModel, findConnectable };
|
|
33
32
|
|
|
34
33
|
//# sourceMappingURL=connections.mjs.map
|
package/dist/consumer-setup.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { captureMetrics } from "@storyshelf/observability";
|
|
5
5
|
import { createCaptureConsumer } from "@storyshelf/core/capture";
|
|
6
|
-
|
|
6
|
+
// src/consumer-setup.ts
|
|
7
7
|
/**
|
|
8
8
|
* The consumer of the app's queues (ADR 0006, decision 5): built when first started, so a host
|
|
9
9
|
* that never starts one never touches the queue, and drained as a unit on teardown.
|
|
@@ -52,7 +52,6 @@ function jobMetrics() {
|
|
|
52
52
|
else if (event.outcome === "failed") instruments.jobsFailed.add(1, attributes);
|
|
53
53
|
} };
|
|
54
54
|
}
|
|
55
|
-
//#endregion
|
|
56
55
|
export { combineConsumers, jobMetrics, lazyConsumer };
|
|
57
56
|
|
|
58
57
|
//# sourceMappingURL=consumer-setup.mjs.map
|
package/dist/credential-keys.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/credential-keys.ts
|
|
5
5
|
/**
|
|
6
6
|
* Key material for encrypted credentials: the current secret, plus
|
|
7
7
|
* `previousSecret` as a decrypt-only fallback during a rotation. Not for
|
|
@@ -14,7 +14,6 @@ function credentialKeys(config) {
|
|
|
14
14
|
};
|
|
15
15
|
return config.secret;
|
|
16
16
|
}
|
|
17
|
-
//#endregion
|
|
18
17
|
export { credentialKeys };
|
|
19
18
|
|
|
20
19
|
//# sourceMappingURL=credential-keys.mjs.map
|
package/dist/credentials.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { trackBackground } from "./lifecycle.mjs";
|
|
5
5
|
import { probeCredentials, reencryptCredentials } from "@storyshelf/core/models";
|
|
6
|
-
|
|
6
|
+
// src/credentials.ts
|
|
7
7
|
/** Current/previous key pair for a probe, or null when no secret is configured. */
|
|
8
8
|
function secretKeysOf(config) {
|
|
9
9
|
if (!config.secret) return null;
|
|
@@ -51,7 +51,6 @@ function checkCredentialsAfterSetup(cell, db, config, logger) {
|
|
|
51
51
|
logger.error({ err: error }, "credential check failed");
|
|
52
52
|
}));
|
|
53
53
|
}
|
|
54
|
-
//#endregion
|
|
55
54
|
export { checkCredentialsAfterSetup, checkCredentialsAtBoot, loadCredentialProbe, reencryptWithCurrent, secretKeysOf };
|
|
56
55
|
|
|
57
56
|
//# sourceMappingURL=credentials.mjs.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { credentialKeys } from "./credential-keys.mjs";
|
|
5
|
+
import { clearPaused, notificationOrigin, warnPaused } from "./notifications-pause.mjs";
|
|
6
|
+
import { notifyProjectWith } from "./notify.mjs";
|
|
7
|
+
import { designChange } from "@storyshelf/core/models";
|
|
8
|
+
import { emitWebhookEvent } from "@storyshelf/core/adapter/webhook-events";
|
|
9
|
+
import { createUrlBuilder } from "@storyshelf/core/urls";
|
|
10
|
+
// src/design-events.ts
|
|
11
|
+
/**
|
|
12
|
+
* `design:changed`: a design moved after its baseline was approved, or no longer exists. It rides
|
|
13
|
+
* the existing paths (signed webhooks and the notification fan-out) and is a normal subscribable
|
|
14
|
+
* topic: it is not default-on (see `notify.ts`), so only people who opted in hear about it.
|
|
15
|
+
*
|
|
16
|
+
* Sent once per (project, design node, design version) from the first health check that sees the
|
|
17
|
+
* change. The durable claim is `DesignNodeModel.claimChange`; with no confirmed public origin
|
|
18
|
+
* nothing is sent and nothing is claimed, so the change is still announced once an origin exists.
|
|
19
|
+
* There is no boot replay: an unannounced change waits for the next health check.
|
|
20
|
+
*/
|
|
21
|
+
/** Event name of a design change. */
|
|
22
|
+
const DESIGN_CHANGED_EVENT = "design:changed";
|
|
23
|
+
/**
|
|
24
|
+
* Announce every observed design change not announced before. Never throws: a failure is logged
|
|
25
|
+
* and the next health check tries again.
|
|
26
|
+
*/
|
|
27
|
+
async function announceDesignChangesWith(deps, nodes, project, observations) {
|
|
28
|
+
const changes = observations.flatMap((observation) => {
|
|
29
|
+
const change = observation.componentPath ? designChange(observation.node, observation.baselineVersion) : null;
|
|
30
|
+
return observation.node && observation.componentPath && change ? [{
|
|
31
|
+
...observation,
|
|
32
|
+
node: observation.node,
|
|
33
|
+
componentPath: observation.componentPath,
|
|
34
|
+
change
|
|
35
|
+
}] : [];
|
|
36
|
+
});
|
|
37
|
+
if (changes.length === 0 || !await originConfirmed(deps)) return;
|
|
38
|
+
await Promise.all(changes.map(async (item) => {
|
|
39
|
+
try {
|
|
40
|
+
if (await nodes.claimChange(item.node, item.change)) await announce(deps, project, item);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
deps.logger.warn({
|
|
43
|
+
err: error,
|
|
44
|
+
projectId: project.id
|
|
45
|
+
}, "design change not announced");
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
async function originConfirmed(deps) {
|
|
50
|
+
if (await notificationOrigin(deps) === void 0) {
|
|
51
|
+
warnPaused(deps.logger, DESIGN_CHANGED_EVENT);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
clearPaused(deps.logger);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
async function announce(deps, project, item) {
|
|
58
|
+
const data = {
|
|
59
|
+
projectId: project.id,
|
|
60
|
+
componentPath: item.componentPath,
|
|
61
|
+
figmaUrl: item.url,
|
|
62
|
+
change: item.change.change,
|
|
63
|
+
designVersion: item.change.designVersion
|
|
64
|
+
};
|
|
65
|
+
await emitWebhookEvent(deps.db, { webhooks: deps.db.tables.webhooks }, project.id, DESIGN_CHANGED_EVENT, data, credentialKeys(deps.config), deps.logger);
|
|
66
|
+
const component = createUrlBuilder("").component(project.slug, item.componentPath);
|
|
67
|
+
await notifyProjectWith(deps, project, DESIGN_CHANGED_EVENT, data, component.slice(`/projects/${project.slug}`.length));
|
|
68
|
+
}
|
|
69
|
+
export { DESIGN_CHANGED_EVENT, announceDesignChangesWith };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=design-events.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-events.mjs","names":[],"sources":["../src/design-events.ts"],"sourcesContent":["/**\n * `design:changed`: a design moved after its baseline was approved, or no longer exists. It rides\n * the existing paths (signed webhooks and the notification fan-out) and is a normal subscribable\n * topic: it is not default-on (see `notify.ts`), so only people who opted in hear about it.\n *\n * Sent once per (project, design node, design version) from the first health check that sees the\n * change. The durable claim is `DesignNodeModel.claimChange`; with no confirmed public origin\n * nothing is sent and nothing is claimed, so the change is still announced once an origin exists.\n * There is no boot replay: an unannounced change waits for the next health check.\n */\nimport { emitWebhookEvent } from \"@storyshelf/core/adapter/webhook-events\";\nimport { designChange, type DesignChange, type DesignNodeModel } from \"@storyshelf/core/models\";\nimport type { DesignNode, Project } from \"@storyshelf/core/schema\";\nimport { createUrlBuilder } from \"@storyshelf/core/urls\";\nimport { credentialKeys } from \"./credential-keys.ts\";\nimport { clearPaused, notificationOrigin, warnPaused } from \"./notifications-pause.ts\";\nimport { notifyProjectWith, type NotifyDeps } from \"./notify.ts\";\n\n/** Event name of a design change. */\nexport const DESIGN_CHANGED_EVENT = \"design:changed\";\n\n/** What `design:changed` carries. */\nexport interface DesignChangedData extends Record<string, unknown> {\n projectId: string;\n /** Story file (the component) whose design changed. */\n componentPath: string;\n figmaUrl: string;\n change: DesignChange[\"change\"];\n designVersion: string | null;\n}\n\n/** One design a health check looked at. */\nexport interface DesignObservation {\n url: string;\n node: DesignNode | undefined;\n /** The component (story file) the design belongs to. */\n componentPath: string | null;\n /** Version of the baseline the component was approved at. */\n baselineVersion: string | null;\n}\n\n/**\n * Announce every observed design change not announced before. Never throws: a failure is logged\n * and the next health check tries again.\n */\nexport async function announceDesignChangesWith(\n deps: NotifyDeps,\n nodes: Pick<DesignNodeModel, \"claimChange\">,\n project: Pick<Project, \"id\" | \"slug\">,\n observations: readonly DesignObservation[],\n): Promise<void> {\n const changes = observations.flatMap((observation) => {\n const change = observation.componentPath\n ? designChange(observation.node, observation.baselineVersion)\n : null;\n return observation.node && observation.componentPath && change\n ? [\n {\n ...observation,\n node: observation.node,\n componentPath: observation.componentPath,\n change,\n },\n ]\n : [];\n });\n if (changes.length === 0 || !(await originConfirmed(deps))) return;\n await Promise.all(\n changes.map(async (item) => {\n try {\n if (await nodes.claimChange(item.node, item.change)) await announce(deps, project, item);\n } catch (error) {\n deps.logger.warn({ err: error, projectId: project.id }, \"design change not announced\");\n }\n }),\n );\n}\n\nasync function originConfirmed(deps: NotifyDeps): Promise<boolean> {\n const origin = await notificationOrigin(deps);\n if (origin === undefined) {\n warnPaused(deps.logger, DESIGN_CHANGED_EVENT);\n return false;\n }\n clearPaused(deps.logger);\n return true;\n}\n\nasync function announce(\n deps: NotifyDeps,\n project: Pick<Project, \"id\" | \"slug\">,\n item: { url: string; componentPath: string; change: DesignChange },\n): Promise<void> {\n const data: DesignChangedData = {\n projectId: project.id,\n componentPath: item.componentPath,\n figmaUrl: item.url,\n change: item.change.change,\n designVersion: item.change.designVersion,\n };\n await emitWebhookEvent(\n deps.db,\n { webhooks: deps.db.tables.webhooks },\n project.id,\n DESIGN_CHANGED_EVENT,\n data,\n credentialKeys(deps.config),\n deps.logger,\n );\n const component = createUrlBuilder(\"\").component(project.slug, item.componentPath);\n await notifyProjectWith(\n deps,\n project,\n DESIGN_CHANGED_EVENT,\n data,\n component.slice(`/projects/${project.slug}`.length),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,MAAa,uBAAuB;;;;;AA0BpC,eAAsB,0BACpB,MACA,OACA,SACA,cACe;CACf,MAAM,UAAU,aAAa,SAAS,gBAAgB;EACpD,MAAM,SAAS,YAAY,gBACvB,aAAa,YAAY,MAAM,YAAY,eAAe,IAC1D;EACJ,OAAO,YAAY,QAAQ,YAAY,iBAAiB,SACpD,CACE;GACE,GAAG;GACH,MAAM,YAAY;GAClB,eAAe,YAAY;GAC3B;EACF,CACF,IACA,CAAC;CACP,CAAC;CACD,IAAI,QAAQ,WAAW,KAAK,CAAE,MAAM,gBAAgB,IAAI,GAAI;CAC5D,MAAM,QAAQ,IACZ,QAAQ,IAAI,OAAO,SAAS;EAC1B,IAAI;GACF,IAAI,MAAM,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,GAAG,MAAM,SAAS,MAAM,SAAS,IAAI;EACzF,SAAS,OAAO;GACd,KAAK,OAAO,KAAK;IAAE,KAAK;IAAO,WAAW,QAAQ;GAAG,GAAG,6BAA6B;EACvF;CACF,CAAC,CACH;AACF;AAEA,eAAe,gBAAgB,MAAoC;CAEjE,IAAI,MADiB,mBAAmB,IAAI,MAC7B,KAAA,GAAW;EACxB,WAAW,KAAK,QAAQ,oBAAoB;EAC5C,OAAO;CACT;CACA,YAAY,KAAK,MAAM;CACvB,OAAO;AACT;AAEA,eAAe,SACb,MACA,SACA,MACe;CACf,MAAM,OAA0B;EAC9B,WAAW,QAAQ;EACnB,eAAe,KAAK;EACpB,UAAU,KAAK;EACf,QAAQ,KAAK,OAAO;EACpB,eAAe,KAAK,OAAO;CAC7B;CACA,MAAM,iBACJ,KAAK,IACL,EAAE,UAAU,KAAK,GAAG,OAAO,SAAS,GACpC,QAAQ,IACR,sBACA,MACA,eAAe,KAAK,MAAM,GAC1B,KAAK,MACP;CACA,MAAM,YAAY,iBAAiB,EAAE,CAAC,CAAC,UAAU,QAAQ,MAAM,KAAK,aAAa;CACjF,MAAM,kBACJ,MACA,SACA,sBACA,MACA,UAAU,MAAM,aAAa,QAAQ,OAAO,MAAM,CACpD;AACF"}
|
package/dist/git-status.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { getStore } from "./store.mjs";
|
|
|
6
6
|
import { notificationOrigin } from "./notifications-pause.mjs";
|
|
7
7
|
import { buildStateFlags } from "./build-state-flags.mjs";
|
|
8
8
|
import { createBuildStatePublisher, requestOpenBuildStates } from "@storyshelf/core/capture";
|
|
9
|
-
|
|
9
|
+
// src/git-status.ts
|
|
10
10
|
/** Ask for a build's state to be shown on its project's git channels (ADR 0014, decision 5). */
|
|
11
11
|
/**
|
|
12
12
|
* Show the build's current state (commit statuses and the pull-request comment) on every git
|
|
@@ -40,7 +40,6 @@ function inlinePublisher(store) {
|
|
|
40
40
|
logger: store.logger
|
|
41
41
|
} });
|
|
42
42
|
}
|
|
43
|
-
//#endregion
|
|
44
43
|
export { requestBuildState, requestOpenBuildStatesNow };
|
|
45
44
|
|
|
46
45
|
//# sourceMappingURL=git-status.mjs.map
|
package/dist/hidden-data.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/hidden-data.ts
|
|
5
5
|
/**
|
|
6
6
|
* Snapshots stored in the database. With `testing` off they are hidden, not deleted (ADR 0006,
|
|
7
7
|
* decision 1): the System page and the startup log say how many.
|
|
@@ -18,7 +18,6 @@ async function logHostingOnlyMode(db, logger) {
|
|
|
18
18
|
}
|
|
19
19
|
logger.info("testing is off: hosting Storybooks only (no capture, compare or baselines)");
|
|
20
20
|
}
|
|
21
|
-
//#endregion
|
|
22
21
|
export { countHiddenSnapshots, logHostingOnlyMode };
|
|
23
22
|
|
|
24
23
|
//# sourceMappingURL=hidden-data.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,6 @@ import { ShelfApp, ShelfContext, ShelfLifecycle, ShelfRouter } from "./app-types
|
|
|
4
4
|
import { createAuthSystemHook } from "./notify.mjs";
|
|
5
5
|
import { BrandTheme, NotificationsConfig, ShelfCompareOptions, ShelfConfig, ShelfNotificationsOptions, ShelfOptions, ShelfOptions as ShelfOptions$1, ShelfTestingOptions, UIConfig } from "@storyshelf/core/config";
|
|
6
6
|
import { Logger, LoggerOptions, PinoTransport, createShelfLogger } from "@storyshelf/core/logger";
|
|
7
|
-
//#region src/index.d.ts
|
|
8
7
|
/**
|
|
9
8
|
* Create the StoryShelf Hono app with all API routes and HTML pages.
|
|
10
9
|
*
|
|
@@ -13,6 +12,5 @@ import { Logger, LoggerOptions, PinoTransport, createShelfLogger } from "@storys
|
|
|
13
12
|
* fail-fast startup, or let the first request gate on settlement.
|
|
14
13
|
*/
|
|
15
14
|
declare function createShelfApp(rawOptions: ShelfOptions$1): ShelfApp;
|
|
16
|
-
//#endregion
|
|
17
15
|
export { type BrandTheme, type Logger, type LoggerOptions, type NotificationsConfig, type PinoTransport, type ShelfApp, type ShelfCompareOptions, type ShelfConfig, type ShelfContext, type ShelfLifecycle, type ShelfNotificationsOptions, type ShelfOptions, type ShelfRouter, type ShelfTestingOptions, type UIConfig, createAuthSystemHook, createShelfApp, createShelfLogger };
|
|
18
16
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -52,7 +52,7 @@ import { STORYBOOK_TOKEN_PREFIX } from "@storyshelf/core/utils";
|
|
|
52
52
|
import { createHttpMiddleware, createInstrumentedDatabase, createInstrumentedStorage } from "@storyshelf/observability";
|
|
53
53
|
import { requestId } from "hono/request-id";
|
|
54
54
|
import { createShelfLogger } from "@storyshelf/core/logger";
|
|
55
|
-
|
|
55
|
+
// src/index.tsx
|
|
56
56
|
/**
|
|
57
57
|
* StoryShelf app: compose database, storage, capture, auth, and notifier
|
|
58
58
|
* adapters into a complete self-hosted visual-testing Hono app.
|
|
@@ -380,9 +380,8 @@ function registerDocs(app) {
|
|
|
380
380
|
* from source (dev server, tests).
|
|
381
381
|
*/
|
|
382
382
|
function packageVersion() {
|
|
383
|
-
return "0.
|
|
383
|
+
return "0.9.0-next-d2cc082";
|
|
384
384
|
}
|
|
385
|
-
//#endregion
|
|
386
385
|
export { createAuthSystemHook, createShelfApp, createShelfLogger };
|
|
387
386
|
|
|
388
387
|
//# sourceMappingURL=index.mjs.map
|
package/dist/insights/budget.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { notifySystemWith } from "../notify.mjs";
|
|
|
5
5
|
import { failWith } from "./errors.mjs";
|
|
6
6
|
import { AiBudgetAlertModel, AiUsageModel } from "@storyshelf/core/models";
|
|
7
7
|
import { countedTokens, crossedThresholds, utcDay, utcDayStart } from "@storyshelf/core/insights";
|
|
8
|
-
|
|
8
|
+
// src/insights/budget.ts
|
|
9
9
|
/** DB-counted budget: pre-flight limits, usage rows and threshold alerts. */
|
|
10
10
|
const HOUR_MS = 36e5;
|
|
11
11
|
/** Tokens counted so far today (UTC), summed across all instances from rows. */
|
|
@@ -43,7 +43,6 @@ async function recordUsage(deps, input) {
|
|
|
43
43
|
await fireAlerts(deps, crossedThresholds(before, after, dailyTokens), utcDay(now), after, dailyTokens);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
//#endregion
|
|
47
46
|
export { assertWithinBudget, dayTokens, recordUsage };
|
|
48
47
|
|
|
49
48
|
//# sourceMappingURL=budget.mjs.map
|
package/dist/insights/deps.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { getStore } from "../store.mjs";
|
|
5
|
-
|
|
5
|
+
// src/insights/deps.ts
|
|
6
6
|
/** Snapshot the current request store into explicit deps (null when AI is off). */
|
|
7
7
|
function insightDepsFromStore() {
|
|
8
8
|
const store = getStore();
|
|
@@ -15,7 +15,6 @@ function insightDepsFromStore() {
|
|
|
15
15
|
notify: store
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
//#endregion
|
|
19
18
|
export { insightDepsFromStore };
|
|
20
19
|
|
|
21
20
|
//# sourceMappingURL=deps.mjs.map
|
package/dist/insights/errors.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { HTTPException } from "hono/http-exception";
|
|
5
|
-
|
|
5
|
+
// src/insights/errors.ts
|
|
6
6
|
/** JSON errors for the insights API (`{ message }`, optional `Retry-After`). */
|
|
7
7
|
/** Throw an HTTP error with a JSON `{ message }` body. */
|
|
8
8
|
function failWith(status, message, retryAfterSeconds) {
|
|
@@ -16,7 +16,6 @@ function failWith(status, message, retryAfterSeconds) {
|
|
|
16
16
|
})
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
//#endregion
|
|
20
19
|
export { failWith };
|
|
21
20
|
|
|
22
21
|
//# sourceMappingURL=errors.mjs.map
|
package/dist/insights/job.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { notifyProjectWith } from "../notify.mjs";
|
|
|
5
5
|
import { recordUsage } from "./budget.mjs";
|
|
6
6
|
import { InsightModel } from "@storyshelf/core/models";
|
|
7
7
|
import { AiError } from "@storyshelf/core/ai";
|
|
8
|
-
|
|
8
|
+
// src/insights/job.ts
|
|
9
9
|
/** Background insight job: summarize, record usage, persist the result, notify. */
|
|
10
10
|
const running = /* @__PURE__ */ new Set();
|
|
11
11
|
/** Wait for in-flight jobs (graceful teardown and tests). */
|
|
@@ -97,7 +97,6 @@ function spawnJob(deps, row, spec) {
|
|
|
97
97
|
});
|
|
98
98
|
running.add(promise);
|
|
99
99
|
}
|
|
100
|
-
//#endregion
|
|
101
100
|
export { packResult, settleInsightJobs, spawnJob };
|
|
102
101
|
|
|
103
102
|
//# sourceMappingURL=job.mjs.map
|
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { BuildModel, SnapshotModel } from "@storyshelf/core/models";
|
|
5
5
|
import { buildHealthEvidence, resolveLimits, snapshotKey } from "@storyshelf/core/insights";
|
|
6
6
|
import { modeSegment } from "@storyshelf/core/paths";
|
|
7
|
-
|
|
7
|
+
// src/insights/load-health.ts
|
|
8
8
|
/** Load project-health evidence: build aggregates plus the most churny stories. */
|
|
9
9
|
const DAY_MS = 864e5;
|
|
10
10
|
/** Parse windows like `30d` (1–365 days); null for anything else. */
|
|
@@ -53,7 +53,6 @@ async function loadHealthEvidence(deps, project, window, days) {
|
|
|
53
53
|
limits: resolveLimits(deps.ai.limits())
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
//#endregion
|
|
57
56
|
export { loadHealthEvidence, parseWindow };
|
|
58
57
|
|
|
59
58
|
//# sourceMappingURL=load-health.mjs.map
|
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { CaptureAttemptModel, CaptureLogModel, CommentModel, SnapshotModel } from "@storyshelf/core/models";
|
|
5
5
|
import { buildTriageEvidence, rankSnapshots, resolveLimits } from "@storyshelf/core/insights";
|
|
6
6
|
import { modeSegment } from "@storyshelf/core/paths";
|
|
7
|
-
|
|
7
|
+
// src/insights/load-triage.ts
|
|
8
8
|
/** Load triage evidence inputs (snapshots, logs, comments, thumbnails) and assemble them. */
|
|
9
9
|
function storyIdOf(log) {
|
|
10
10
|
try {
|
|
@@ -92,7 +92,6 @@ async function loadTriageEvidence(deps, project, build) {
|
|
|
92
92
|
limits
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
//#endregion
|
|
96
95
|
export { loadTriageEvidence };
|
|
97
96
|
|
|
98
97
|
//# sourceMappingURL=load-triage.mjs.map
|
package/dist/insights/panel.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { APPROVER_ROLES } from "../routers/builds.handlers.mjs";
|
|
|
8
8
|
import { freshen } from "./stale.mjs";
|
|
9
9
|
import { toInsightView } from "./view.mjs";
|
|
10
10
|
import { InsightModel } from "@storyshelf/core/models";
|
|
11
|
-
|
|
11
|
+
// src/insights/panel.ts
|
|
12
12
|
/** Data for the build-review insight panel (null when AI is off for the project). */
|
|
13
13
|
/** Load the panel for a build, or null when AI is off site-wide or for the project. */
|
|
14
14
|
async function loadInsightPanel(project, build) {
|
|
@@ -22,7 +22,6 @@ async function loadInsightPanel(project, build) {
|
|
|
22
22
|
canGenerate: role !== null && APPROVER_ROLES.includes(role)
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
//#endregion
|
|
26
25
|
export { loadInsightPanel };
|
|
27
26
|
|
|
28
27
|
//# sourceMappingURL=panel.mjs.map
|
|
@@ -8,7 +8,7 @@ import { loadTriageEvidence } from "./load-triage.mjs";
|
|
|
8
8
|
import { InsightModel } from "@storyshelf/core/models";
|
|
9
9
|
import { HEALTH_SYSTEM, PROMPT_VERSION, TRIAGE_SYSTEM, computeInputHash, healthEnvelopeSchema, triageEnvelopeSchema } from "@storyshelf/core/insights";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
|
-
|
|
11
|
+
// src/insights/request.ts
|
|
12
12
|
/** Request-side insight orchestration: evidence, hash, cache check, budget, spawn. */
|
|
13
13
|
/** The profile a project uses: override, else its gate value (`default` = default profile). */
|
|
14
14
|
function profileFor(deps, project, override) {
|
|
@@ -107,7 +107,6 @@ async function requestHealth(deps, project, window, options) {
|
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
//#endregion
|
|
111
110
|
export { profileFor, requestHealth, requestTriage };
|
|
112
111
|
|
|
113
112
|
//# sourceMappingURL=request.mjs.map
|
package/dist/insights/stale.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { InsightModel } from "@storyshelf/core/models";
|
|
5
5
|
import { STALE_RUN_MS } from "@storyshelf/core/retention";
|
|
6
|
-
|
|
6
|
+
// src/insights/stale.ts
|
|
7
7
|
/** Lazy interruption check: a run stuck past the stale window is failed on read. */
|
|
8
8
|
/** Return the row, first marking it `interrupted` when it is stale and still in flight. */
|
|
9
9
|
async function freshen(deps, row) {
|
|
@@ -15,7 +15,6 @@ async function freshen(deps, row) {
|
|
|
15
15
|
errorCode: "interrupted"
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
//#endregion
|
|
19
18
|
export { freshen };
|
|
20
19
|
|
|
21
20
|
//# sourceMappingURL=stale.mjs.map
|
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { AiUsageModel } from "@storyshelf/core/models";
|
|
5
5
|
import { countedTokens, utcDay } from "@storyshelf/core/insights";
|
|
6
|
-
|
|
6
|
+
// src/insights/usage-report.ts
|
|
7
7
|
/** Aggregates for the site-admin AI usage page (counted tokens per day and profile). */
|
|
8
8
|
const DAY_MS = 864e5;
|
|
9
9
|
function addTo(map, key, make, tokens, failed) {
|
|
@@ -54,7 +54,6 @@ async function buildUsageReport(deps, windowDays = 14, now = /* @__PURE__ */ new
|
|
|
54
54
|
dailyTokens: dailyTokens ?? null
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
//#endregion
|
|
58
57
|
export { buildUsageReport };
|
|
59
58
|
|
|
60
59
|
//# sourceMappingURL=usage-report.mjs.map
|
package/dist/insights/view.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/insights/view.ts
|
|
5
5
|
function parseResult(raw) {
|
|
6
6
|
if (!raw) return {
|
|
7
7
|
output: null,
|
|
@@ -42,7 +42,6 @@ function toInsightView(row) {
|
|
|
42
42
|
finishedAt: row.finishedAt
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
-
//#endregion
|
|
46
45
|
export { toInsightView };
|
|
47
46
|
|
|
48
47
|
//# sourceMappingURL=view.mjs.map
|
package/dist/job-canceller.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/job-canceller.ts
|
|
5
5
|
/** Ask each queue that can cancel to cancel the build's jobs; a queue without `cancel` is skipped. */
|
|
6
6
|
function createJobCanceller(queues) {
|
|
7
7
|
return async (buildId) => {
|
|
8
8
|
return (await Promise.all(queues.map(async (queue) => await queue?.cancel?.(buildId) ?? false))).some(Boolean);
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
//#endregion
|
|
12
11
|
export { createJobCanceller };
|
|
13
12
|
|
|
14
13
|
//# sourceMappingURL=job-canceller.mjs.map
|
package/dist/job-queue.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { DATABASE_QUEUE_METADATA, createDatabaseCaptureQueue } from "@storyshelf/core/capture";
|
|
5
|
-
|
|
5
|
+
// src/job-queue.ts
|
|
6
6
|
/**
|
|
7
7
|
* Create the lazy queue polling `kinds`, with `retries` after a first failed attempt, the lease
|
|
8
8
|
* of `testing.leaseSeconds` and the clock of `testing.queueClock` (production: real time).
|
|
@@ -45,7 +45,6 @@ function queueView(get) {
|
|
|
45
45
|
cancel: async (id) => await get().cancel(id)
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
//#endregion
|
|
49
48
|
export { createJobQueue };
|
|
50
49
|
|
|
51
50
|
//# sourceMappingURL=job-queue.mjs.map
|