mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-03 01:27:09 +01:00
## Thinking Path > - Paperclip manages AI agents and their work. > - The feature map records the user-facing capabilities. > - Storybook uses the same feature index. > - Step 2 found 49 UI capabilities with no authored examples. > - This pull request adds shipped-component examples with isolated fixtures. > - The catalog records each example's states and remaining production checks. ## Linked Issues or Issue Description Refs: #16167. The verification inventory is merged; this follow-up now targets master. ## What Changed - Add 37 suites and 257 scenarios for all 49 UI capabilities from the step-2 inventory. Keep existing stories and IDs. - Use shipped pages and components. Simulate API replies, sockets, props, and callbacks at their boundaries. - Activate story API fixtures before the application providers read data. Block unregistered API mutations and restore owned storage/fetch state. - Add browser checks for rendering, declared play assertions, fixture reset, and selected mobile/theme states. Update the catalog and verification inventory. ## Verification - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - UI Vitest suite: 730 files and 8,208 tests passed. Fixture boundary tests: 4 passed. - Map/catalog checks, 27 generator/map tests, and token gates: passed. - `pnpm build-storybook`: passed. All 2,248 previous built entry IDs remain present. - Pre-reconciliation static browser suite: 260 checks passed (257 scenarios, token fixture reset, and two mobile/theme cases). All non-play stories assert an explicit subject state; 129 play functions passed. - `pnpm test:run` could not complete on this Mac. Embedded PostgreSQL exhausted host shared-memory allocation. The run also reported native-runner test timeouts. Only this task's verified runner was stopped; other jobs and host settings were preserved. - Reconciled onto merged master `252d9b5077`. The six draft stories and new same-browser reset regression passed (7 checks); 16 draft-persistence tests and UI typecheck passed. Static merge verification: 32 affected-subject/draft checks passed, including same-browser reset. Rebuilt Storybook retains all 2,248 original IDs in its 2,517-entry index. Four additional play-result checks passed: visible onboarding reset, pending probe, filtered-empty runs, and optimistic queued-response removal. UI typecheck and 27 catalog/map tests also passed. Final static browser suite on `3fab35df8d912935fa86ce0de7d32d07e2b5f4c3`: all 261 checks passed (257 scenarios plus fixture-reset and mobile checks). Latest head `3fab35df8d912935fa86ce0de7d32d07e2b5f4c3`: all 55 CI/status checks passed; the two optional Storybook workflow jobs were skipped. Greptile 5/5 with no unresolved threads. - No pinned Linux visual-baseline comparison or real provider journey is claimed. ## Risks Fixtures can drift from production contracts. The catalog records inspected sources and their fingerprints. Capability links provide initial isolated UI coverage; they do not certify every recipe variant, real permissions, persistence, or provider behavior. The new examples expose existing UI limits. Plugin discovery failure stays on Loading. Document and environment-list reads lack dedicated failure feedback; Cases and Inbox fall back to empty views after errors. Goal alignment has display views but no assignment control. These findings remain visible in the inventory. ## Model Used OpenAI GPT-6 via Codex. The exact runtime deployment ID and context window are not exposed in this session. Used code generation, shell execution, and browser verification. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
173 lines
5.2 KiB
TypeScript
173 lines
5.2 KiB
TypeScript
import type { Environment, EnvironmentCapabilities } from "@paperclipai/shared";
|
|
import { prepareFixtureApi, type FixtureState } from "./api";
|
|
export const environment: Environment = {
|
|
id: "environment-gap",
|
|
name: "Release sandbox",
|
|
description: "Isolated release checks",
|
|
driver: "sandbox",
|
|
status: "active",
|
|
config: { provider: "daytona", reuseLease: true },
|
|
envVars: {},
|
|
metadata: null,
|
|
createdAt: new Date("2026-10-12"),
|
|
updatedAt: new Date("2026-10-12"),
|
|
};
|
|
const capabilities: EnvironmentCapabilities = {
|
|
adapters: [],
|
|
drivers: {
|
|
local: "supported",
|
|
ssh: "supported",
|
|
sandbox: "supported",
|
|
plugin: "unsupported",
|
|
},
|
|
sandboxProviders: {
|
|
fake: {
|
|
status: "unsupported",
|
|
supportsLoginPty: false,
|
|
supportsSavedProbe: false,
|
|
supportsUnsavedProbe: false,
|
|
supportsRunExecution: false,
|
|
supportsReusableLeases: false,
|
|
supportsInteractiveSetup: false,
|
|
interactiveSetupConnectionTypes: [],
|
|
supportsTemplateCapture: false,
|
|
supportsTemplateDelete: false,
|
|
},
|
|
daytona: {
|
|
status: "supported",
|
|
supportsLoginPty: true,
|
|
supportsSavedProbe: true,
|
|
supportsUnsavedProbe: true,
|
|
supportsRunExecution: true,
|
|
supportsReusableLeases: true,
|
|
supportsInteractiveSetup: true,
|
|
interactiveSetupConnectionTypes: ["ssh"],
|
|
supportsTemplateCapture: true,
|
|
supportsTemplateDelete: true,
|
|
displayName: "Daytona",
|
|
},
|
|
},
|
|
};
|
|
export function installEnvironmentFixture(
|
|
state: FixtureState = "ready",
|
|
image: "none" | "captured" | "failed" | "loading" | "denied" = "none",
|
|
unsupported = false,
|
|
) {
|
|
let current = { ...environment };
|
|
const template = {
|
|
id: "template-gap",
|
|
environmentId: environment.id,
|
|
provider: "daytona",
|
|
templateKind: "snapshot",
|
|
templateRef: "fixture-template",
|
|
sourceTemplateRef: null,
|
|
sourceEnvironmentConfigFingerprint: "fixture-fingerprint",
|
|
status: "active",
|
|
createdByUserId: "user-storybook",
|
|
createdByAgentId: null,
|
|
capturedAt: "2026-10-12T12:00:00Z",
|
|
lastUsedAt: null,
|
|
supersededByTemplateId: null,
|
|
metadata: null,
|
|
createdAt: "2026-10-12T12:00:00Z",
|
|
updatedAt: "2026-10-12T12:00:00Z",
|
|
};
|
|
return prepareFixtureApi(
|
|
[
|
|
{
|
|
path: "/api/instance/settings/experimental",
|
|
state: "ready",
|
|
read: () => ({
|
|
enableEnvironments: true,
|
|
enableManagedSandboxOnly: false,
|
|
}),
|
|
},
|
|
{
|
|
path: "/api/instance/settings",
|
|
state: "ready",
|
|
read: () => ({ defaultEnvironmentId: environment.id }),
|
|
},
|
|
{
|
|
path: "/api/companies/company-storybook/environments",
|
|
read: () => (state === "empty" ? [] : [current]),
|
|
},
|
|
{
|
|
path: "/api/companies/company-storybook/environments/capabilities",
|
|
read: () =>
|
|
unsupported
|
|
? {
|
|
...capabilities,
|
|
sandboxProviders: {
|
|
fake: {
|
|
status: "unsupported",
|
|
supportsLoginPty: false,
|
|
supportsSavedProbe: false,
|
|
supportsUnsavedProbe: false,
|
|
supportsRunExecution: false,
|
|
supportsReusableLeases: false,
|
|
supportsInteractiveSetup: false,
|
|
interactiveSetupConnectionTypes: [],
|
|
supportsTemplateCapture: false,
|
|
supportsTemplateDelete: false,
|
|
},
|
|
daytona: {
|
|
...capabilities.sandboxProviders.daytona,
|
|
status: "unsupported",
|
|
supportsSavedProbe: false,
|
|
supportsTemplateCapture: false,
|
|
},
|
|
},
|
|
}
|
|
: capabilities,
|
|
},
|
|
{
|
|
path: "/api/environments/environment-gap/secret-refs",
|
|
read: () => ({ refs: [] }),
|
|
},
|
|
{
|
|
path: "/api/environments/environment-gap",
|
|
method: "PATCH",
|
|
read: ({ body }) => {
|
|
current = { ...current, ...body };
|
|
return current;
|
|
},
|
|
},
|
|
{
|
|
path: "/api/environments/environment-gap/probe",
|
|
method: "POST",
|
|
read: () => ({
|
|
ok: true,
|
|
driver: "sandbox",
|
|
summary: "Provider connection succeeded.",
|
|
details: {},
|
|
}),
|
|
},
|
|
{
|
|
path: "/api/environments/environment-gap/custom-image-template",
|
|
read: () =>
|
|
image === "loading"
|
|
? new Promise<Response>(() => {})
|
|
: image === "denied"
|
|
? Response.json(
|
|
{
|
|
error: "You do not have permission to inspect this image.",
|
|
},
|
|
{ status: 403 },
|
|
)
|
|
: image === "failed"
|
|
? Response.json(
|
|
{ error: "Image metadata is unavailable." },
|
|
{ status: 503 },
|
|
)
|
|
: {
|
|
activeTemplate: image === "captured" ? template : null,
|
|
activeTemplateMatchesConfig: true,
|
|
activeSession: null,
|
|
latestSession: null,
|
|
},
|
|
},
|
|
],
|
|
state,
|
|
);
|
|
}
|