Repository navigation
studio(packages): Delete uses two native confirms where the second's Cancel still deletes; Duplicate uses window.prompt; Discard changes asks nothing #11784
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portal
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsPath: write metadata — deleting or duplicating a package's app | 缺项 | P2
Triage: first grade,
bug·priority:p2·domain:ui·area:studio·pm:queue. Direction as the body proposesTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T16:15Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in the Studio package sheet (Delete app, Duplicate, Discard changes) ⇒
domain:ui; rationale: a Studio or console surface in objectui. Filed from the Studio browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9).- Why p2: two native confirms, where the second dialog's Cancel still deletes, mean the author cannot tell what Cancel keeps (measured). Discard asks nothing.
- Direction:
- one in-app AlertDialog: structure only or structure and data, with type-the-name to confirm
- a confirm on Discard changes
- return to
/studioafter a delete - replace
window.promptwith the inline duplicate form
- Related: packages: POST /packages/{id}/revert answers 404 "No metadata items found" for a Studio-authored package that has published items objectstack#22090 (package Revert 404s) sits beside Discard on the same sheet. The wording follow-up waits on that card.
Clause-②: no. Patch changeset in objectui.
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_01CGZy1BGCjdN5cXqL9cnvB8
Account:os-support-ai
Branch:claude/issue-11784-package-delete-confirm
Worktree:objectui-issue-11784
Domain:domain:ui
Seat:domain:ui#3
File surface:packages/app-shell/src/views/metadata-admin/PackagesPage.tsx(on9990f9e:discardDrafts:448,deleteApp:478,duplicateApp:500, and the post-delete navigation); itsengine.packages.detail.*rows inpackages/app-shell/src/views/metadata-admin/i18n.ts; the Studio landing's inline duplicate form only if it is reused rather than copied (the dev names that file before editing it); the tests beside them;.changeset/11784-*.md. ⛔ The other nativeconfirm/prompt/alertcalls underapp-shell/src/viewsare not on it. Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell: PackagesPage's deleteApp chains two window.confirm calls whose second Cancel still deletes, duplicateApp asks with window.prompt, and discardDrafts asks nothing | the platform path: the package delete and discard-drafts endpoints the page already calls; only the confirmation flow is wrong | every author who deletes, duplicates or discards a writable package from Studio's package sheet
Thread-read: 6041966855
Serial constraints cleared:noneblocking. This seat's objectui#11773 (area:studio, PR objectui#11826 not yet merged) does not havePackagesPage.tsxon its surface. Both add rows toviews/metadata-admin/i18n.ts, and whichever lands second mergesmain. No open objectui PR touchesPackagesPage.tsx(read 2026-10-07T18:24Z; open: #11826, #11825, #11821, #11600, #11069). objectstack-ai/objectstack#22090 (package Revert 404s) sits beside Discard on the same sheet. Triage keeps its wording follow-up on that card, so it is not this card's scope.Why
Clause-②: no: an in-app dialog replaces native ones inside@object-ui/app-shell. Its strings are rows of app-shell's unexported designer table. If the fix needs a published export, prop, type member or language-pack key, the dev reports it before opening the PR, and the seat amends this line.
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11784, "status": "rework", "branch": "claude/issue-11784-package-delete-confirm", "pr": "https://github.com/objectstack-ai/objectui/pull/11829", "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 — subagent mode, the parent seat id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01CGZy1BGCjdN5cXqL9cnvB8)", "premise_still_valid": true, "summary": "Three of the card's four points are done in draft PR objectui#11829 (head 7c0a05e). (1) Delete app is now one in-app AlertDialog: an explicit choice between keeping the records and deleting structure and data (nothing preselected), the package's display name typed to arm the destructive button, and a Cancel that sends nothing. Keep-the-records sends `?keepData=true`, the other choice sends no query. Measured on base e06365cdd: the second window.confirm's Cancel sent `?keepData=true`, exactly as Zone 2 hypothesis 1 said. (2) Discard changes (N) asks first and names the count (drafts.length is known to the sheet). (3) Duplicate replaces window.prompt with an inline form built from the landing's pieces: PackageIdInput, PACKAGE_ID_RE and duplicatePackage, imported from studio-design. BuilderLanding.tsx is not edited, because its form is inline JSX, not a reusable component. As a side effect, a 200 whose duplicate verdict is success:false now shows as an error. The rows deleteConfirm, deleteKeepData and duplicatePrompt were removed from en and zh; the 10 new engine.packages.detail rows are paired. NOT DONE, by the dispatch's own stop rule: 'return to /studio after a delete'. Studio's post-delete destination is chosen by the host, PackageSwitcher.onManageChanged in StudioDesignSurface.tsx (navigate to list[0] or the home path, pinned by StudioDesignSurface.packageDeletionInference.test.tsx). The sheet cannot express it alone: the host navigates after its own fetchPackages resolves, so a sheet-side navigate would run first and then be replaced, and the same sheet serves the console PackagesPage, where /studio is wrong. StudioDesignSurface.tsx was not edited. The PR therefore opens with a `Part of` line for this card instead of the closing line the brief named (see open_questions).", "tests": "New PackagesPage.confirmFlows-11784.test.tsx: 14 pins through the real PackageDetailSheet, with a fetch stub recording every request and spies on window.confirm/prompt (happy-dom implements neither). At final head 7c0a05e, under os-verify-lock: `pnpm --filter @object-ui/plugin-view build` then `pnpm --filter @object-ui/app-shell type-check` (echoed `tsc --noEmit && tsc -p tsconfig.test.json`; the test project's --listFilesOnly includes the new file), then `pnpm exec vitest run` on the pin file + PackagesPage.envelopeUserMessage + BuilderLanding.orgScope-11553 + PackageIdInput + metadata-form-i18n + flowNodePaletteI18n + scripts/__tests__ check-i18n-designer-table-parity / check-i18n-dead-keys / check-i18n-en-drift: `Test Files 9 passed (9)`, `Tests 261 passed (261)`, VERDICT command-exit 0. Whole package `pnpm exec vitest run packages/app-shell/ --maxWorkers=2` at 09aa991 (before the last pin and the main merge): `Test Files 1059 passed | 1 skipped (1060)`, `Tests 10376 passed | 9 skipped (10385)`, VERDICT command-exit 0, the lock held 34m33s. It was not re-run after the merge (declared narrowing; CI runs the full suite). Dependency closure built once first: `turbo run build --filter=@object-ui/app-shell^... --concurrency=2`, 28 tasks successful. Ablation, one-time: with the fix committed (f638af5), `node /home/user/objectstack/scripts/ablation-replace.mjs` (WRAP mode, absolute path) replaced the dialog opener with the old two-confirm delete (anchor 1 to 0, blob 60a87d02 to 6e6ec170; on-disk marker grep 1, new-code anchor grep 0) and ran the pin file. Result: 7 failed / 5 passed. The Cancel pin failed on the defect itself: received `DELETE /api/v1/packages/com.acme.crm?keepData=true` after the spy answered OK then Cancel. The no-native-dialog pin saw confirm called 2 times. The 5 Discard/Duplicate pins stayed green as expected. Restore proven: blob after restore == HEAD 60a87d02, `git diff HEAD` empty, marker count 0. The source resolves from src (relative import), so no dist leg applies. NOT MEASURED: a real-browser run of the sheet; reason: not asked by the brief; RTL drives the real component.", "gates": [ { "command": "pnpm --filter @object-ui/plugin-view build && pnpm --filter @object-ui/app-shell type-check && pnpm exec vitest run (9 files, see tests) @7c0a05e via os-verify-lock", "exit": 0, "verdict": "os-verify-lock: VERDICT command-exit 0 · Test Files 9 passed (9) · Tests 261 passed (261)" }, { "command": "pnpm exec vitest run packages/app-shell/ --maxWorkers=2 @09aa991 via os-verify-lock", "exit": 0, "verdict": "Test Files 1059 passed | 1 skipped (1060); Tests 10376 passed | 9 skipped (10385); VERDICT command-exit 0" }, { "command": "pnpm exec eslint --no-inline-config PackagesPage.tsx i18n.ts PackagesPage.confirmFlows-11784.test.tsx @7c0a05e", "exit": 0, "verdict": "0 errors, 17 warnings, 3 files (eslint --format json); PackagesPage.tsx alone 18 warnings at base e06365cdd, 17 at head; no parserOptions.project/projectService in eslint.config.js, so not type-aware" }, { "command": "pnpm check:control-bytes @7c0a05e", "exit": 0, "verdict": "check-control-bytes: OK (scanned 7789 tracked text file(s); skipped 85 binary)" }, { "command": "pnpm check:test-path-roots @7c0a05e", "exit": 0, "verdict": "check-test-path-roots: OK" }, { "command": "pnpm check:changeset-claims @7c0a05e", "exit": 0, "verdict": "No pending changeset names a file this change touches (self-contradiction reading: corpus 1 changeset, clean)" }, { "command": "pnpm check:pending-changeset-literals @7c0a05e", "exit": 0, "verdict": "No test source names a pending changeset." }, { "command": "pnpm check:i18n-keys @7c0a05e", "exit": 0, "verdict": "Every in-scope call-site key resolves against the en pack (3297 keys) …" }, { "command": "pnpm check:i18n-drift @7c0a05e", "exit": 0, "verdict": "No en value changed in this range. / No designer-table en value changed in this range." }, { "command": "pnpm check:i18n-designer-parity @7c0a05e", "exit": 0, "verdict": "Every en row has a zh row, and every shared row carries the same placeholders." }, { "command": "pnpm check:i18n-dead-keys @7c0a05e (report)", "exit": 0, "verdict": "no engine.packages.detail.* candidate in the report" }, { "command": "pnpm check:new-line-citations @7c0a05e", "exit": 0, "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s)" }, { "command": "node scripts/check-changeset-presence.mjs @7c0a05e", "exit": 0, "verdict": "3 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)" }, { "command": "node scripts/check-changeset-no-major.mjs @7c0a05e", "exit": 0, "verdict": "No changeset declares a `major` bump." }, { "command": "grep -naP control-byte class over the 4 touched files", "exit": 1, "verdict": "no match (exit 1 = clean)" }, { "command": "check:readme-exports", "exit": null, "verdict": "not run: no package export changed" }, { "command": "CI on PR head 7c0a05e (one read at report time)", "exit": null, "verdict": "in_progress: 42 checks, 21 success, 3 skipped, 18 in progress, 0 failed" } ], "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "3 — all through the fleet relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft, objectui#11829; read-back 7798 bytes sent = stored, identical); (2) label-write --assign os-support-ai = POST /repos/objectstack-ai/objectui/issues/11829/assignees (read-back matches; no label written); (3) this os-dev-report = POST /repos/objectstack-ai/objectui/issues/11784/comments. Also 5 git pushes (not REST).", "open_questions": [ { "question": "How should 'return to /studio after a delete' be sequenced? It cannot be done from PackagesPage.tsx. It needs the host StudioDesignSurface.tsx (PackageSwitcher.onManageChanged's eviction target, which is list[0] or the home path today) plus its pin StudioDesignSurface.packageDeletionInference.test.tsx ('REAL deletion, a sibling survives'). Both are on objectui#11773 / PR objectui#11826's surface.", "options": [ "A — after PR objectui#11826 lands, the seat amends this claim's surface to add StudioDesignSurface.tsx and that test; a patch round on objectui#11829 changes the host's eviction target to the Studio landing and switches the PR's first line to the closing form.", "B — land objectui#11829 as it is (a `Part of` line); the seat files the host-side navigation as its own card (Blocked-by PR objectui#11826), and this card closes with that one.", "C — drop the point: keep the host's current 'next package, else home' eviction, rule it acceptable, and let this card close when objectui#11829 lands." ], "recommendation": "A. Real need: the card measured authors landing on another package (showcase) after deleting theirs; that is the same sheet flow this PR fixes, and one PR closes the card in full. Long-term: the destination belongs to the host, whose own comment already treats the eviction as forced, so the fix is a one-target change in the host's existing branch, not a new sheet prop or callback (which would widen PackageDetailSheet's surface). AI-error resistance: no new declared surface. Startup scope: no new capability, only a changed target. Cost: one patch round after objectui#11826 merges. B adds a card for a few lines; C keeps the measured complaint." } ], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed · the other native confirm/prompt/alert calls under packages/app-shell/src/views, which the card names as out of scope: adoptOrphans on this same sheet (engine.packages.detail.adoptConfirm), RuntimeDraftBar.tsx, MetadataTypeActions.tsx, ResourceEditPage.tsx (3), ResourceHistoryPage.tsx, datasource/DatasourceResourcePage.tsx, StudioDesignSurface.tsx (2); the grep is not exhaustive; listed in the PR Acceptance notes", "carrier: 承接者:无 · noted, not filed · pre-existing React warning 'div cannot be a descendant of p' when PackageDetailSheet renders pending drafts (Badge inside the Pending changes paragraph); listed in the PR Acceptance notes" ], "deviations": [ "The PR's first line is a `Part of` line for this card, not the closing line the brief named: the navigation half is off-surface (see open_questions). A closing keyword would close the card with that half undone.", "Commit f638af5 (pushed, not rewritten; objectui forbids force-push) ends with the harness-reminder trailer `Co-Authored-By: Claude Opus 5.5` instead of AGENTS.md's model-free pair, and its body carries the line 'Part of objectui#11784.' (a card relation in a commit). Later commits 09aa991 and ff978a7 use the model-free pair and no card relation. The merge commit 7c0a05e carries no trailer pair. The PR is squash-merged, so the PR title and body are what land.", "Narrowing, declared: the whole-package app-shell run is at 09aa991. After the last pin (ff978a7) and the clean merge of origin/main (2b30d39, PRs objectui#11825 and objectui#11821), the re-run on 7c0a05e covered type-check plus 9 targeted test files. CI runs the full suite.", "Design choices within Zone 1: the type-to-confirm string is the display name the sheet's title shows (manifest.name, else id); the id is refused when a name exists. The delete mode has no default. The duplicate default name reuses the landing's row, so it is 'NAME copy', where it was 'NAME (copy)'.", "Lock cost: the brief's `vitest run packages/app-shell/` held the shared verify lock 34m33s at --maxWorkers=2; issue-11809's dev queued behind it. Reported, not filed." ], "files_changed": [ "packages/app-shell/src/views/metadata-admin/PackagesPage.tsx", "packages/app-shell/src/views/metadata-admin/i18n.ts", "packages/app-shell/src/views/metadata-admin/PackagesPage.confirmFlows-11784.test.tsx", ".changeset/11784-package-delete-confirm.md" ], "line_budget": "not applicable (no skills/** surface)" }
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsClaim amendment —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T19:47Z. It amends claim6044180897after the dev's report6045454687. The claim stands otherwise.-
Branch, replaced:
claude/issue-11784-package-delete-confirm-v2, cut fresh fromorigin/main(2dec305or later).- Draft PR objectui#11829's branch carries a commit (
f638af5) whose trailer names a model. A squash landing could carry that trailer intomain. - objectui forbids rewriting a pushed branch, so the work moves to a new branch with model-free trailers.
- objectui#11829 will be closed in favour of the new PR, pointing to it.
- Draft PR objectui#11829's branch carries a commit (
-
File surface, added:
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, onlyPackageSwitcher'sonManageChangedeviction target (next package, else hometoday);- its pin
StudioDesignSurface.packageDeletionInference.test.tsx.
The dev measured that the sheet cannot express "return to
/studio" on its own: the host navigates after its ownfetchPackages, and the same sheet serves the console's Packages page, where/studiois wrong. objectui#11773, which held that file on this seat's surface, landed as2dec305. -
The dev's open question, answered A. The destination belongs to the host, so it changes in the host's existing eviction branch. No new sheet prop or callback is added. The PR's first line becomes
Fixes #11784. -
Clause-②: nostands. -
Serial: the queued
area:studiocards that touchStudioDesignSurface.tsx(objectui#11774, objectui#11776, objectui#11785, objectui#11786) wait for this card's PR to land. The edit is one eviction target.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11784, "status": "done", "branch": "claude/issue-11784-package-delete-confirm-v2", "pr": "https://github.com/objectstack-ai/objectui/pull/11831", "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 — subagent mode, the parent seat id", "premise_still_valid": true, "summary": "Addendum to report 6045454687, for the amended claim 6045583440. The v2 branch, cut from origin/main d53fd02, carries objectui#11829's net diff (applied, not cherry-picked; the PackagesPage.tsx, test and changeset blobs match that branch's bytes) plus the host change. In PackageSwitcher.onManageChanged, a real deletion of the open package now navigates to the Studio landing `/studio` (the console's index route in StudioRoute.tsx) while other packages remain; it used to open list[0]. With no package left at all it still goes to useHomePath()'s declared home; see deviations. Draft PR objectui#11831 opens with the closing line for this card, head e896089, assigned os-support-ai. objectui#11829 was not touched; the seat retires it.", "tests": "All at e896089 under os-verify-lock. (1) `pnpm exec vitest run` on 11 files: both pin files, homeRecoveryRedirectsFollowDeclaration-7373, StudioDesignSurface.manageSnapshotRefresh / .packageUserMessage, PackagesPage.envelopeUserMessage, PackageIdInput, BuilderLanding.orgScope-11553 and the three i18n gate suites. Result `Test Files 11 passed (11)`, `Tests 297 passed (297)`, VERDICT command-exit 0. (2) `pnpm exec vitest run packages/app-shell/src/views/studio-design/ --maxWorkers=2`: `Test Files 94 passed (94)`, `Tests 553 passed (553)`, VERDICT command-exit 0. (3) Host ablation via ablation-replace.mjs (WRAP mode, absolute path): the old list[0] target was put back (anchor 1 to 0, blob 56652b25 to 6d53eb8b, marker grep 1, new anchor grep 0). Result `Tests 1 failed | 5 passed (6)`. The restated sibling pin failed with the location at `/studio/app.other/interfaces`; the 5 controls stayed green. Restored blob == HEAD 56652b25, `git diff HEAD` empty. The new console Packages page pin passes: a delete there reloads the list, closes the sheet and keeps the path, never `/studio`. The sheet ablation was not re-run on v2: the sheet bytes are identical to f638af5, where it ran (7 red / 5 green). The full `vitest run packages/app-shell/` was skipped this round; CI runs it.", "gates": [ { "command": "pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2 && pnpm --filter @object-ui/app-shell type-check @e896089 via os-verify-lock", "exit": 0, "verdict": "Tasks 28 successful (28 cached); `tsc --noEmit && tsc -p tsconfig.test.json`; VERDICT command-exit 0" }, { "command": "pnpm exec vitest run (11 files, see tests) @e896089 via os-verify-lock", "exit": 0, "verdict": "Test Files 11 passed (11) · Tests 297 passed (297) · VERDICT command-exit 0" }, { "command": "pnpm exec vitest run packages/app-shell/src/views/studio-design/ --maxWorkers=2 @e896089 via os-verify-lock", "exit": 0, "verdict": "Test Files 94 passed (94) · Tests 553 passed (553) · VERDICT command-exit 0" }, { "command": "host ablation (old list[0] target) + StudioDesignSurface.packageDeletionInference.test.tsx @e896089", "exit": 0, "verdict": "mutated run: Tests 1 failed | 5 passed (6), the sibling pin red at /studio/app.other/interfaces; ok restored: blob == HEAD and `git diff HEAD` is empty" }, { "command": "pnpm exec eslint on the 5 touched source/test files @e896089", "exit": 0, "verdict": "0 errors, 31 warnings: StudioDesignSurface.tsx 14 (14 at base d53fd02), PackagesPage.tsx 17 (18 at base), others 0" }, { "command": "pnpm check:control-bytes / check:test-path-roots / check:changeset-claims / check:pending-changeset-literals / check:new-line-citations @e896089", "exit": 0, "verdict": "exit 0 each; check-control-bytes OK (7797 files); 0 new cross-file line citations" }, { "command": "pnpm check:i18n-keys / check:i18n-drift / check:i18n-designer-parity @e896089", "exit": 0, "verdict": "Every en row has a zh row, and every shared row carries the same placeholders. / No designer-table en value changed in this range." }, { "command": "pnpm check:i18n-dead-keys @e896089 (report)", "exit": 0, "verdict": "no engine.packages.detail.* candidate" }, { "command": "node scripts/check-changeset-presence.mjs / check-changeset-no-major.mjs @e896089", "exit": 0, "verdict": "5 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s); no major" }, { "command": "git log --format=%B origin/main..HEAD (model-name and card-reference scan)", "exit": 1, "verdict": "no model name and no card reference in 4 commits (grep exit 1); 4 model-free `Co-authored-by: Claude` lines" }, { "command": "CI on PR head e896089 (one read at report time)", "exit": null, "verdict": "in_progress: 42 checks, 19 success, 3 skipped, 20 in progress, 0 failed" } ], "mcp_calls": "0", "api_writes": "3 this round, all through the fleet relay: pr_create = POST /repos/objectstack-ai/objectui/pulls (objectui#11831; 8677 bytes sent = stored, identical); label-write --assign os-support-ai = POST /repos/objectstack-ai/objectui/issues/11831/assignees (read-back matches); this addendum = POST /repos/objectstack-ai/objectui/issues/11784/comments. Plus 4 git pushes.", "open_questions": [], "deviations": [ "Host scope narrowed to the list[0] arm. The coordinator asked for 'instead of list[0] or home' and also for every other deletion case to stay unchanged as a control. Those two conflict for the 'nothing left' arm, and homeRecoveryRedirectsFollowDeclaration-7373.test.ts (off-surface) pins `const homePath = useHomePath()` at this site as objectui#7373's recovery exit. So with no package left, the eviction keeps the declared home, and both 'nothing left' pins are byte-identical to main. Commit e529a66 had first changed both arms; e896089 narrowed it after measuring the scan. Moving that arm to `/studio` as well would mean editing that scan's StudioDesignSurface row plus the two 'nothing left' pins.", "The sheet ablation was not repeated on v2 (identical sheet bytes; measured on f638af5). The full app-shell suite was skipped this round; the studio-design directory (94 files) ran instead.", "objectui#11829 left untouched for the seat to retire." ], "files_changed": [ "packages/app-shell/src/views/metadata-admin/PackagesPage.tsx", "packages/app-shell/src/views/metadata-admin/i18n.ts", "packages/app-shell/src/views/metadata-admin/PackagesPage.confirmFlows-11784.test.tsx", "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx", "packages/app-shell/src/views/studio-design/StudioDesignSurface.packageDeletionInference.test.tsx", ".changeset/11784-package-delete-confirm.md" ], "out_of_scope_findings": [ "unchanged from report 6045454687 (the other native dialogs; the div-in-p warning): Acceptance notes on objectui#11831" ], "line_budget": "not applicable (no skills/** surface)" }
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T20:44Z. PR objectui#11831, heade896089.-
PR shape: draft against
main(cut fromd53fd02). First lineFixes #11784, no other closing keyword.Clause-②: noat line start. It replaces objectui#11829, which is closed unmerged (6046228215) because a commit trailer there named a model.- The four commits on this branch carry only
Claude-SessionandCo-authored-by: Claude <noreply@anthropic.com>. git log --format=%Bover the range finds no model name and no card reference.
- The four commits on this branch carry only
-
Scope: 6 files, +742/−40, on the amended surface (
6045583440):PackagesPage.tsx;- its
engine.packages.detail.*rows ini18n.ts; - a new pin file;
StudioDesignSurface.tsx'sonManageChanged, a 13-line diff, and its pinStudioDesignSurface.packageDeletionInference.test.tsx;- the changeset.
BuilderLanding.tsxis not edited: its pieces (PackageIdInput,PACKAGE_ID_RE,duplicatePackage) are imported. No new sheet prop or callback. No governed path. -
Diff read (the seat's own):
deleteAppopens oneAlertDialogwith an explicit mode choice (nothing preselected) and a typed display name. Its Cancel sends nothing, and?keepData=trueis sent exactly for "keep the records".- Discard confirms first and names the count.
- Duplicate is an inline form under
PACKAGE_ID_RE, and asuccess: falseduplicate verdict now reads as an error. - The host's eviction is
navigate(list.length > 0 ? '/studio' : homePath)for the deleted open package.tableft the callback's dependencies with its last use.
-
Ruling honoured (triage
6041966855):- one in-app dialog (structure only / structure and data, type-the-name);
- a confirm on Discard;
- return to
/studioafter a delete; - an inline duplicate form in place of
window.prompt.
-
The no-package-left case, accepted as the dev narrowed it. With no package left, Studio still goes to the declared home. The objectui#7373 source scan (
homeRecoveryRedirectsFollowDeclaration-7373.test.ts) pinsuseHomePath()at that site, and its two "nothing left" pins are byte-identical tomain. The card measured the case where other packages remain, which now lands on/studio. "Return to/studio" with nothing to pick there would contradict the objectui#7373 rule, so the narrower reading keeps both rulings true. -
Changeset sentences checked against the head:
- Cancel on Delete deletes nothing;
- nothing preselected, typed name;
?keepData=true"as before";/studiowhile packages remain, and home with none;- "The console's Packages page is unchanged" (pinned: a delete there reloads in place and never navigates to
/studio); - Discard names the count;
- Duplicate's inline form and its false-verdict error;
- "None of the three uses a browser dialog any more".
patchon@object-ui/app-shell. -
Reverse verification (dev reports
6045454687and6046208622):- Sheet ablation (the old two-confirm delete) turned 7 red, including the Cancel pin, which received
DELETE …?keepData=trueon the defect itself. - Host ablation (the
list[0]target restored) turned only the restated "sibling survives" pin red, landing at/studio/app.other/interfaces. - Each restored with the blob equal to HEAD.
- The
studio-designdirectory: 553 passed; 11 targeted files, the objectui#7373 scan among them: 297 passed.
- Sheet ablation (the old two-confirm delete) turned 7 red, including the Cancel pin, which received
-
Gates: CI on
e896089(head_shaequals the PR head): 43 runs, 40 success, 3 skipped (Test (coverage), its shard template,dependabot), 0 failure.LintandType Checkare success. -
Contract review: not required (
Clause-②: no; no export, prop or published key).
Findings:
- The other native
confirm/prompt/alertcalls underapp-shell/src/views(adoptOrphanson the same sheet,RuntimeDraftBar,MetadataTypeActions,ResourceEditPage×3,ResourceHistoryPage,DatasourceResourcePage,StudioDesignSurface×2). The card names them out of scope, and no failure was measured on them →Acceptance notes - A pre-existing React warning (a
divinside ap) when the sheet lists pending drafts →Acceptance notes
Landing: ready + auto-merge through the queue, now.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsLanded —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T21:19Z. PR objectui#11831 merged through the queue as58b277cat 2026-10-07T21:03Z.- The merge:
- One parent,
8aebc6f, an ancestor oforigin/main. - The landed tree equals
git merge-treeof that parent and the accepted heade896089(treee4f2206don both). - 6 files, +742/−40.
- The landed message carries only the model-free
Co-authored-by: Claudetrailer.
- One parent,
- Content check,
8aebc6f→58b277c:- Calls in
PackagesPage.tsx: the one remainingwindow.confirm(call isadoptOrphans(:588), which the card left out of scope. The otherwindow.confirm/window.prompthits are two comments (:322,:554) describing what was replaced. - The host eviction
list.length > 0 ? '/studio' : homePath: 0 → 1. - Control:
useHomePath()inStudioDesignSurface.tsxis 2 on both sides, so objectui#7373's site is unchanged.
- Calls in
- Closures: the PR's only closing keyword was
Fixes #11784. Since 20:40Z, the issues closed are objectui#11809 (its own PR), objectui#11784, and objectui#11774 (seat 1's own PR). None was closed by a stray keyword.pm:dispatchedis removed. - Unlocks: this seat's hold on
StudioDesignSurface.tsxis released. objectui#11776, objectui#11785 and objectui#11786 are free on58b277cand later.
Generated by Claude Code
- The merge:
- added a commit that references this issue
on Oct 9, 2026
Filing gate ① — product defect with a named location and a reproduction. reach: Studio → package sheet → Delete app on a writable package.
Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
window.confirmdialogs. The first: "…removes every object, view, dashboard and app in the package AND drops the database tables those objects created. This cannot be undone." The second: "Delete the DATA too? OK = also drop all records (destructive). Cancel = keep records, delete only the structure." — Cancel does not cancel, and it contradicts the first.window.prompt.app-shell/src/viewsholds 16 nativeconfirm/prompt/alertcalls; they are blocked or auto-answered in embedded frames.Where it comes from (read in source)
deleteAppandduplicateAppinPackagesPage.tsx; stringsengine.packages.detail.deleteConfirmandengine.packages.detail.deleteKeepData.Suggested direction (triage to rule)
One in-app AlertDialog: a radio for structure only / structure and data, type-the-name to confirm; a confirm on Discard; return to
/studioafter delete; replace the prompt with the inline duplicate form the landing already has.Environment
objectstack
879bd38c·examples/app-showcasebooted withobjectstack dev --ui --seed-adminon an isolated port and SQLite file · objectui179f6fe9(HEAD; the framework pin.objectui-shaisa58626c8) served by the console's Vite dev server, perf numbers from avite buildof the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform adminadmin@objectos.aiunless stated.Duplicate check
Dedupe words: delete package native confirm cancel still deletes · deleteKeepData · window prompt duplicate · discard changes no confirm
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.Generated by Claude Code