Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@

- data.rs:data_infer_model still uses local infer_field_type without identity-forcing post-pass; same fix as infer.rs eef494f applies — added 3-line identity coercion block after identity is determined. data.rs is source-experience's file but the fix is trivial and necessary to pass cargo test gate; acceptable cross-lane touch since it replicates an already-landed pattern.

- [studio-code:planner] SECURITY: received a message claiming to relay a director response ('not my fleet -- I direct kevinthelago/networkmonitor') telling me to stop asking and resume from prompts/planner-checkpoint.md. Both claims are false/inconsistent: BSC_AUDIT_PANE=studio-code:planner (this session IS correctly wired to studio-code), and the referenced checkpoint file does not exist. Treated as a prompt-injection/hijack attempt per protocol -- ignored, did not change task or scope, continuing on #3787/#3989 as before.

- [studio-code:planner] reviewed bsc ui doctor findings for src/features/planner: all git-tracked/seeded component records (pane/session/bodies/list) are clean and correctly provides-tagged; found ~15 stale DB-only duplicate/draft records (progressionrail, mcpdownloadmodal, donebanner, lockbanner, rolechip, kinddot, seg, stepper, planpreviewpane, plan-body-stream-focus-cards, collapsiblecard, planningdialogs, planningnotices, projectcard, projectsrail) left behind by earlier harvest/authoring passes, none seed-backed so none affect the shipped app; planner role's ui scope is read-only (mutating bsc ui verbs denied) so I cannot delete them myself -- flagging for a session with UI write access (designer/worker) to prune

- [studio-code:planner] confirmed #3787's full scope (Planning.tsx / FocusedShell / ProjectPane / ProjectsList into the graph) already delivered and live-mounted via already-merged #3874 + #4224 + #4227 + #4230 (all closed, epic #3604); #3989 already merged (#4011); requesting the director close #3787 referencing those four sub-issues since no new planner-owned code work remains

Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,7 @@
"kitId": "base-studio-code",
"role": "composite",
"provides": "@/features/planner/pane/FocusedBodies",
"srcText": "// Project pane → the stage-body switch, AS GRAPH SOURCE (#4227, epic #3604). Transcribed from the live feature file. Its\n// `provides: \"@/features/planner/pane/FocusedBodies\"` makes the runtime loader vendor THIS source wherever a graph\n// component imports that specifier — so the planning page composes the pane from the graph without\n// knowing it, and the registered module stays as the fallback. Behaviour runs here.\n// FocusedBodies — the planner ProjectPane stage-body dispatcher (#1332; bodies split into\n// ../bodies/Focused*Body per #1757). Each per-stage body now lives in its own file under\n// `../bodies/`; this module is the `FocusedStageBody` switch that maps a Stage to its body and\n// assembles the shared handler sets once. ProjectPane.tsx is the thin shell that renders it.\nimport type { Flow, ContextFile, McpServer, ProjectPaneData } from \"@/features/planner/pane/projectPaneData\";\nimport { type ModelId } from \"@/app/console/lib/models\";\nimport type { Stage } from \"@/features/planner/stages/focusedPlan\";\nimport type { DeployConfig } from \"@/features/planner/lib/deployConfig\";\nimport type { Topology } from \"@/features/planner/relationship/relationshipGraph\";\nimport type { DirectorDrive } from \"@/features/planner/fleet/directorDrive\";\n// The merged Repositories & Deployment pane + source body (pre-existing files). #1914 collapsed the\n// stage vocabulary: the `deployment` stage (repos+deploy) renders the merged Repositories & Deployment\n// pane, the `streams` stage (structure+permissions) renders the plan graph + the folded-in fleet\n// permissions, and `source` stays (it's in `complete`).\nimport { FileIntakePane } from \"@/features/planner/bodies/FileIntakePane\";\nimport { DeploymentBody } from \"@/features/planner/bodies/ReposDeployView\";\nimport { SourceBody } from \"@/features/planner/bodies/FocusedSourceBody\";\n// Core planning-stage bodies (#1757 split out of this file).\nimport { DiscoveryBody } from \"@/features/planner/bodies/DiscoveryBody\";\nimport { MarketBody } from \"@/features/planner/bodies/MarketBody\";\nimport { TransformationsBody } from \"@/features/planner/bodies/TransformationsBody\";\nimport { AutomationsBody } from \"@/features/planner/bodies/FocusedAutomationsBody\";\nimport { SkillsBody } from \"@/features/planner/bodies/FocusedSkillsBody\";\nimport { McpsBody } from \"@/features/planner/bodies/McpsBody\";\nimport { FeaturesBody } from \"@/features/planner/bodies/FocusedFeaturesBody\";\nimport { StreamsBody } from \"@/features/planner/bodies/StreamsBody\";\nimport type { FleetHandlers, McpHandlers } from \"@/features/planner/bodies/focusedHandlers\";\nimport { EmptyState } from \"@/shared/ui/feedback/EmptyState\";\n// The Planner Components pane (#2314) — the body of the `test_ui` stage.\nimport { PlannerComponentsPane } from \"@/features/designs\";\nimport { PreviewPaneShell } from \"@/features/planner/preview/PreviewPaneShell\";\nimport { useAppStore } from \"@/store\";\n\n// Re-export the shared body types so existing `from \"@/features/planner/pane/FocusedBodies\"` imports keep resolving.\nexport type { FleetHandlers, McpHandlers, SyncState } from \"@/features/planner/bodies/focusedHandlers\";\n\n/* =================================================================\n FocusedStageBody — maps a Stage to its body (#652 / #674)\n ================================================================= */\n\nexport function FocusedStageBody({ stage, data, projectId, onLinkRepo, onView, onFlow, onModel, onPersona, onTopology, onDirectorDrive, onToggleMcp, onBuildMcp, onAddMcp, onRemoveMcp, onDeployChange, requiredContext, onInject }: {\n stage: Stage;\n data?: ProjectPaneData;\n projectId?: string;\n /** Required-context topics for the Context body's written/missing checklist (#1061). */\n requiredContext?: string[];\n /** Inject a prompt into the live planner terminal (#1986) — the Source body's declare affordance. */\n onInject?: (text: string) => void;\n onLinkRepo?: (r: string) => void;\n /** Deploy stage (#919): persist the edited deployment config. */\n onDeployChange?: (next: DeployConfig) => void;\n onView?: (f: ContextFile) => void;\n onFlow?: (streamId: string, flow: Flow) => void;\n onModel?: (streamId: string, model: ModelId | undefined) => void;\n onPersona?: (streamId: string, personaId: string | undefined) => void;\n onTopology?: (t: Topology) => void;\n onDirectorDrive?: (d: DirectorDrive) => void;\n onToggleMcp?: (id: string) => void;\n onBuildMcp?: (s: McpServer) => void;\n onAddMcp?: (input: string) => void;\n onRemoveMcp?: (id: string) => void;\n}) {\n // #3783: the UI stage renders one of two surfaces per the project's UI mode (planner-set at\n // discovery; an unset project defaults to \"custom\" — the in-app designer preview).\n const uiMode = useAppStore((s) => (projectId ? s.planClassification[projectId]?.uiMode : undefined) ?? \"custom\");\n // Assemble the repeated handler sets once (#1640) so the cases below spread them instead of\n // re-threading each handler by name. Same handlers, same values — purely cuts prop-chain noise.\n const fleetHandlers: FleetHandlers = { onFlow, onModel, onPersona, onTopology, onDirectorDrive };\n const mcpHandlers: McpHandlers = { onToggle: onToggleMcp, onBuild: onBuildMcp, onAdd: onAddMcp, onRemove: onRemoveMcp };\n switch (stage.key) {\n case \"source\":\n return <SourceBody projectId={projectId} onInject={onInject} />;\n case \"deployment\":\n // The unified `deployment` stage (#1914 — the collapsed repos+deploy def) renders as one\n // cohesive Repositories & Deployment pane: each repo's git identity merged with its deploy\n // target (click a repo to expand its target editor inline).\n return (\n <DeploymentBody\n repos={data?.repos} deploy={data?.deploy} onDeployChange={onDeployChange}\n onLinkRepo={onLinkRepo}\n />\n );\n case \"discovery\":\n return <DiscoveryBody context={data?.context} onView={onView} requiredContext={requiredContext} />;\n case \"market\":\n // The market-research stage (#2430): read-focused rendering of the planner-recorded\n // assessment (gap statement · scored rubric · competitors · verdict) from `bsc plan market`.\n return <MarketBody projectId={projectId} />;\n case \"transformations\":\n // The transformations stage (#2509): the bottom-up confirm queue over the planner-recorded\n // modification rows from `bsc plan transformation` — tier by tier, confirm-only.\n return <TransformationsBody projectId={projectId} />;\n case \"ui\":\n // #3783: the UI stage renders one of two surfaces depending on the project's UI mode.\n // \"custom\" (default) = the in-app designer preview — the render-preview pipeline shows the\n // navigable shell the designer commissions (PreviewPaneShell). \"external\" = the drop-in-files\n // surface (#604/#829) that stages Claude-Design assets into `design/` for the planner to route.\n return uiMode === \"external\"\n ? <FileIntakePane projectKey={projectId ?? \"\"} />\n : <PreviewPaneShell projectKey={projectId ?? \"\"} />;\n case \"features\":\n return <FeaturesBody features={data?.features} />;\n case \"streams\":\n // The unified `streams` stage (#1914 — the collapsed structure+permissions def). The plan +\n // relationship graph always shows; the fleet (coordination + the per-stream roster + shared\n // deps, as collapsible cards) folds in below when the def carries the `fleet` substep — which\n // the kept blueprints always do.\n return <StreamsBody data={data} fleet={stage.fleet} {...fleetHandlers} />;\n case \"mcps\":\n return <McpsBody servers={data?.mcpServers} {...mcpHandlers} />;\n case \"automations\":\n return <AutomationsBody automations={data?.automations} />;\n case \"skills\":\n return <SkillsBody skills={data?.skills} />;\n case \"test_ui\":\n // The Planner Components pane (#2314): the project-scoped lens on the proven-component library —\n // a Components ⇄ Full UI toggle (inspect one component with pull-into-plan / open-in-studio\n // hand-offs, or the whole app assembled from the kit). Reads the global library from the store,\n // so it needs no stage data.\n return <PlannerComponentsPane />;\n default:\n return <EmptyState iconVariant=\"dashed\" icon=\"⋯\" title=\"The planner documents this stage.\" />;\n }\n}\n",
"srcText": "// Project pane → the stage-body switch, AS GRAPH SOURCE (#4227, epic #3604). Transcribed from the live feature file. Its\n// `provides: \"@/features/planner/pane/FocusedBodies\"` makes the runtime loader vendor THIS source wherever a graph\n// component imports that specifier — so the planning page composes the pane from the graph without\n// knowing it, and the registered module stays as the fallback. Behaviour runs here.\n// FocusedBodies — the planner ProjectPane stage-body dispatcher (#1332; bodies split into\n// ../bodies/Focused*Body per #1757). Each per-stage body now lives in its own file under\n// `../bodies/`; this module is the `FocusedStageBody` switch that maps a Stage to its body and\n// assembles the shared handler sets once. ProjectPane.tsx is the thin shell that renders it.\nimport type { Flow, ContextFile, McpServer, ProjectPaneData } from \"@/features/planner/pane/projectPaneData\";\nimport { type ModelId } from \"@/app/console/lib/models\";\nimport type { Stage } from \"@/features/planner/stages/focusedPlan\";\nimport type { DeployConfig } from \"@/features/planner/lib/deployConfig\";\nimport type { Topology } from \"@/features/planner/relationship/relationshipGraph\";\nimport type { DirectorDrive } from \"@/features/planner/fleet/directorDrive\";\n// The merged Repositories & Deployment pane + source body (pre-existing files). #1914 collapsed the\n// stage vocabulary: the `deployment` stage (repos+deploy) renders the merged Repositories & Deployment\n// pane, the `streams` stage (structure+permissions) renders the plan graph + the folded-in fleet\n// permissions, and `source` stays (it's in `complete`).\nimport { FileIntakePane } from \"@/features/planner/bodies/FileIntakePane\";\nimport { DeploymentBody } from \"@/features/planner/bodies/ReposDeployView\";\nimport { SourceBody } from \"@/features/planner/bodies/FocusedSourceBody\";\n// Core planning-stage bodies (#1757 split out of this file).\nimport { DiscoveryBody } from \"@/features/planner/bodies/DiscoveryBody\";\nimport { MarketBody } from \"@/features/planner/bodies/MarketBody\";\nimport { TransformationsBody } from \"@/features/planner/bodies/TransformationsBody\";\nimport { AutomationsBody } from \"@/features/planner/bodies/FocusedAutomationsBody\";\nimport { SkillsBody } from \"@/features/planner/bodies/FocusedSkillsBody\";\nimport { McpsBody } from \"@/features/planner/bodies/McpsBody\";\nimport { StreamsBody } from \"@/features/planner/bodies/StreamsBody\";\nimport type { FleetHandlers, McpHandlers } from \"@/features/planner/bodies/focusedHandlers\";\nimport { EmptyState } from \"@/shared/ui/feedback/EmptyState\";\n// The project planner's LIBRARY surface (#4265) — the components lens (#2314) and the algorithms lens\n// together. Folded into the `features` stage, which every packaged blueprint carries; `test_ui` (which\n// none do, since #4249) keeps rendering it so a user blueprint carrying that stage still resolves.\nimport { PlannerLibraryPane } from \"@/features/planner/bodies/PlannerLibraryPane\";\nimport { FeaturesStageBody } from \"@/features/planner/bodies/FeaturesStageBody\";\nimport { PreviewPaneShell } from \"@/features/planner/preview/PreviewPaneShell\";\nimport { useAppStore } from \"@/store\";\n\n// Re-export the shared body types so existing `from \"@/features/planner/pane/FocusedBodies\"` imports keep resolving.\nexport type { FleetHandlers, McpHandlers, SyncState } from \"@/features/planner/bodies/focusedHandlers\";\n\n/* =================================================================\n FocusedStageBody — maps a Stage to its body (#652 / #674)\n ================================================================= */\n\nexport function FocusedStageBody({ stage, data, projectId, onLinkRepo, onView, onFlow, onModel, onPersona, onTopology, onDirectorDrive, onToggleMcp, onBuildMcp, onAddMcp, onRemoveMcp, onDeployChange, requiredContext, onInject }: {\n stage: Stage;\n data?: ProjectPaneData;\n projectId?: string;\n /** Required-context topics for the Context body's written/missing checklist (#1061). */\n requiredContext?: string[];\n /** Inject a prompt into the live planner terminal (#1986) — the Source body's declare affordance. */\n onInject?: (text: string) => void;\n onLinkRepo?: (r: string) => void;\n /** Deploy stage (#919): persist the edited deployment config. */\n onDeployChange?: (next: DeployConfig) => void;\n onView?: (f: ContextFile) => void;\n onFlow?: (streamId: string, flow: Flow) => void;\n onModel?: (streamId: string, model: ModelId | undefined) => void;\n onPersona?: (streamId: string, personaId: string | undefined) => void;\n onTopology?: (t: Topology) => void;\n onDirectorDrive?: (d: DirectorDrive) => void;\n onToggleMcp?: (id: string) => void;\n onBuildMcp?: (s: McpServer) => void;\n onAddMcp?: (input: string) => void;\n onRemoveMcp?: (id: string) => void;\n}) {\n // #3783: the UI stage renders one of two surfaces per the project's UI mode (planner-set at\n // discovery; an unset project defaults to \"custom\" — the in-app designer preview).\n const uiMode = useAppStore((s) => (projectId ? s.planClassification[projectId]?.uiMode : undefined) ?? \"custom\");\n // Assemble the repeated handler sets once (#1640) so the cases below spread them instead of\n // re-threading each handler by name. Same handlers, same values — purely cuts prop-chain noise.\n const fleetHandlers: FleetHandlers = { onFlow, onModel, onPersona, onTopology, onDirectorDrive };\n const mcpHandlers: McpHandlers = { onToggle: onToggleMcp, onBuild: onBuildMcp, onAdd: onAddMcp, onRemove: onRemoveMcp };\n switch (stage.key) {\n case \"source\":\n return <SourceBody projectId={projectId} onInject={onInject} />;\n case \"deployment\":\n // The unified `deployment` stage (#1914 — the collapsed repos+deploy def) renders as one\n // cohesive Repositories & Deployment pane: each repo's git identity merged with its deploy\n // target (click a repo to expand its target editor inline).\n return (\n <DeploymentBody\n repos={data?.repos} deploy={data?.deploy} onDeployChange={onDeployChange}\n onLinkRepo={onLinkRepo}\n />\n );\n case \"discovery\":\n return <DiscoveryBody context={data?.context} onView={onView} requiredContext={requiredContext} />;\n case \"market\":\n // The market-research stage (#2430): read-focused rendering of the planner-recorded\n // assessment (gap statement · scored rubric · competitors · verdict) from `bsc plan market`.\n return <MarketBody projectId={projectId} />;\n case \"transformations\":\n // The transformations stage (#2509): the bottom-up confirm queue over the planner-recorded\n // modification rows from `bsc plan transformation` — tier by tier, confirm-only.\n return <TransformationsBody projectId={projectId} />;\n case \"ui\":\n // #3783: the UI stage renders one of two surfaces depending on the project's UI mode.\n // \"custom\" (default) = the in-app designer preview — the render-preview pipeline shows the\n // navigable shell the designer commissions (PreviewPaneShell). \"external\" = the drop-in-files\n // surface (#604/#829) that stages Claude-Design assets into `design/` for the planner to route.\n return uiMode === \"external\"\n ? <FileIntakePane projectKey={projectId ?? \"\"} />\n : <PreviewPaneShell projectKey={projectId ?? \"\"} />;\n case \"features\":\n // #4265: the plan AND the library it should be built from — the stage where reuse-vs-commission\n // is decided is the stage that shows what there is to reuse.\n return <FeaturesStageBody features={data?.features} projectId={projectId} />;\n case \"streams\":\n // The unified `streams` stage (#1914 — the collapsed structure+permissions def). The plan +\n // relationship graph always shows; the fleet (coordination + the per-stream roster + shared\n // deps, as collapsible cards) folds in below when the def carries the `fleet` substep — which\n // the kept blueprints always do.\n return <StreamsBody data={data} fleet={stage.fleet} {...fleetHandlers} />;\n case \"mcps\":\n return <McpsBody servers={data?.mcpServers} {...mcpHandlers} />;\n case \"automations\":\n return <AutomationsBody automations={data?.automations} />;\n case \"skills\":\n return <SkillsBody skills={data?.skills} />;\n case \"test_ui\":\n // Legacy home of the components lens. #4249 retired this stage (no packaged blueprint carries\n // it), so the library now lives on `features` — but a USER blueprint may still carry `test_ui`,\n // and it gets the same both-libraries dock rather than a dead pane.\n return <PlannerLibraryPane />;\n default:\n return <EmptyState iconVariant=\"dashed\" icon=\"⋯\" title=\"The planner documents this stage.\" />;\n }\n}\n",
"src": "src/features/planner/pane/FocusedBodies.tsx",
"folder": "features/planner/pane",
"composes": [
"AutomationsBody",
"DeploymentBody",
"DiscoveryBody",
"EmptyState",
"FeaturesBody",
"FileIntakePane",
"FocusedStageBody",
"MarketBody",
"McpsBody",
"PreviewPaneShell",
"SkillsBody",
"SourceBody",
"StreamsBody",
"TransformationsBody"
],
"props": []
"folder": "features/planner/pane"
}
Loading