mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 08:03:14 +00:00
Seed workspace creation from task source context
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -57,7 +57,7 @@ Done means: users can tell where Tasks are being fetched from, and changing exec
|
||||
## 4. New Workspace Modal, Start Work, And Workspace Creation
|
||||
|
||||
- [x] Split “start from task/issue/PR” source context from workspace run target in New Workspace modal state.
|
||||
- [~] When opening the New Workspace modal from Tasks, preselect the logical project and a reasonable run host without treating the source repo as the only execution target.
|
||||
- [x] When opening the New Workspace modal from Tasks, preselect the logical project and a reasonable run host without treating the source repo as the only execution target.
|
||||
- [x] Ensure pending worktree/workspace creation persists both the source task context and selected run host.
|
||||
- [x] Make “create workspace on host” only show hosts where the project has a ProjectHostSetup.
|
||||
- [x] Keep “add project to host” as the path for making a project available on another host; do not present workspace creation as if Orca is responsible for bootstrapping repos/dependencies.
|
||||
@@ -189,6 +189,7 @@ Done means: reviewers and future agents can understand the vision, implementatio
|
||||
- [x] 2026-06-12: Added Linear/Jira Settings account-scope diagnostics showing whether provider credentials and account checks are owned by the local desktop client or the selected remote server; verified with provider account-scope tests and web typecheck.
|
||||
- [x] 2026-06-12: Added repo-backed Tasks empty-state copy that distinguishes missing project sources from no matching GitHub/GitLab work, then verified with focused empty-state tests and web typecheck.
|
||||
- [x] 2026-06-12: Scoped Jira Tasks drawer/list cache reconciliation by Jira task source context and site id so same-key issues from different hosts/accounts cannot replace each other; verified with focused cache selector tests, targeted oxlint, and full typecheck.
|
||||
- [x] 2026-06-12: Seeded New Workspace run-target selection from the incoming task source context so Linear/Jira starts preselect the logical project/source host instead of the ambient active repo; verified with a focused composer host-boundary test, targeted oxlint, and full typecheck.
|
||||
- [x] 2026-06-12: Fed Tasks source-context diagnostics from the shared execution-host registry so the source chip now reports SSH availability and blocked/incompatible remote-server hosts; verified with summary tests and web typecheck.
|
||||
- [x] 2026-06-12: Extended Linear/Jira Tasks source diagnostics to include the account-owning host plus blocked remote-server availability, keeping account source separate from workspace run host; verified with summary tests and web typecheck.
|
||||
- [x] 2026-06-12: Started the user-facing Host copy audit by replacing stale “remote project” and “Remote SSH” UI labels with project-on-host / SSH-host language; verified with web typecheck.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { resolveInitialWorkspaceRunSeed } from './useComposerState'
|
||||
|
||||
const HOOK_SOURCE = readFileSync(join(__dirname, 'useComposerState.ts'), 'utf8')
|
||||
|
||||
@@ -38,4 +39,45 @@ describe('useComposerState host-context boundaries', () => {
|
||||
expect(section).toContain('repoId: runRepo.id')
|
||||
expect(section).not.toContain('repoId: repoForItem.id')
|
||||
})
|
||||
|
||||
it('seeds initial workspace run target from the task source context', () => {
|
||||
expect(
|
||||
resolveInitialWorkspaceRunSeed({
|
||||
initialTaskSourceContext: {
|
||||
projectId: 'logical-project',
|
||||
hostId: 'ssh:builder',
|
||||
projectHostSetupId: 'setup-builder'
|
||||
}
|
||||
})
|
||||
).toEqual({
|
||||
projectId: 'logical-project',
|
||||
hostId: 'ssh:builder',
|
||||
projectHostSetupId: 'setup-builder'
|
||||
})
|
||||
|
||||
expect(
|
||||
resolveInitialWorkspaceRunSeed({
|
||||
draftProjectId: 'draft-project',
|
||||
draftHostId: 'local',
|
||||
draftProjectHostSetupId: 'setup-local',
|
||||
initialTaskSourceContext: {
|
||||
projectId: 'logical-project',
|
||||
hostId: 'ssh:builder',
|
||||
projectHostSetupId: 'setup-builder'
|
||||
}
|
||||
})
|
||||
).toEqual({
|
||||
projectId: 'draft-project',
|
||||
hostId: 'local',
|
||||
projectHostSetupId: 'setup-local'
|
||||
})
|
||||
|
||||
const section = sourceBetween(HOOK_SOURCE, 'const initialRunSeed', 'const [internalRepoId')
|
||||
|
||||
expect(section).toContain('resolveInitialWorkspaceRunSeed')
|
||||
expect(section).toContain('initialTaskSourceContext')
|
||||
expect(section).toContain('projectId: initialRunSeed.projectId')
|
||||
expect(section).toContain('hostId: initialRunSeed.hostId')
|
||||
expect(section).toContain('projectHostSetupId: initialRunSeed.projectHostSetupId')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -103,6 +103,7 @@ import {
|
||||
type NewWorkspaceProjectOption
|
||||
} from '@/lib/new-workspace-project-options'
|
||||
import { buildExecutionHostRegistry } from '../../../shared/execution-host-registry'
|
||||
import { normalizeExecutionHostId, type ExecutionHostId } from '../../../shared/execution-host'
|
||||
import { getHostDisplayLabelOverrides } from '../../../shared/host-setting-overrides'
|
||||
import { queueNewWorkspaceTerminalFocus } from '@/lib/new-workspace-terminal-focus'
|
||||
import { getSettingsForRepoRuntimeOwner } from '@/lib/repo-runtime-owner'
|
||||
@@ -281,6 +282,34 @@ export type UseComposerStateResult = {
|
||||
createDisabled: boolean
|
||||
}
|
||||
|
||||
export type InitialWorkspaceRunSeedInput = {
|
||||
draftProjectId?: string | null
|
||||
draftHostId?: string | null
|
||||
draftProjectHostSetupId?: string | null
|
||||
initialTaskSourceContext?: Pick<
|
||||
TaskSourceContext,
|
||||
'projectId' | 'hostId' | 'projectHostSetupId'
|
||||
> | null
|
||||
}
|
||||
|
||||
export function resolveInitialWorkspaceRunSeed({
|
||||
draftProjectId,
|
||||
draftHostId,
|
||||
draftProjectHostSetupId,
|
||||
initialTaskSourceContext
|
||||
}: InitialWorkspaceRunSeedInput): {
|
||||
projectId: string | null
|
||||
hostId: ExecutionHostId | null
|
||||
projectHostSetupId: string | null
|
||||
} {
|
||||
return {
|
||||
projectId: draftProjectId ?? initialTaskSourceContext?.projectId ?? null,
|
||||
hostId: normalizeExecutionHostId(draftHostId ?? initialTaskSourceContext?.hostId),
|
||||
projectHostSetupId:
|
||||
draftProjectHostSetupId ?? initialTaskSourceContext?.projectHostSetupId ?? null
|
||||
}
|
||||
}
|
||||
|
||||
// Why: both the full-page TaskPage composer and the Cmd+J modal can be
|
||||
// mounted simultaneously. Without instance scoping, a single native file
|
||||
// drop fires every subscriber and duplicates attachments/prompt edits across
|
||||
@@ -363,6 +392,15 @@ export function useComposerState(options: UseComposerStateOptions): UseComposerS
|
||||
const draftProjectHostSetupId = persistDraft
|
||||
? (newWorkspaceDraft?.projectHostSetupId ?? null)
|
||||
: null
|
||||
// Why: Tasks can start work from Linear/Jira source contexts that are not
|
||||
// repo-backed. Seed the run target from the logical project/source host so
|
||||
// the modal does not silently fall back to the ambient active repo.
|
||||
const initialRunSeed = resolveInitialWorkspaceRunSeed({
|
||||
draftProjectId,
|
||||
draftHostId,
|
||||
draftProjectHostSetupId,
|
||||
initialTaskSourceContext
|
||||
})
|
||||
const resolvedInitialWorkspaceStatus = useMemo(
|
||||
() =>
|
||||
initialWorkspaceStatus && isWorkspaceStatusId(initialWorkspaceStatus, workspaceStatuses)
|
||||
@@ -378,9 +416,9 @@ export function useComposerState(options: UseComposerStateOptions): UseComposerS
|
||||
draftRepoId,
|
||||
initialRepoId,
|
||||
activeRepoId,
|
||||
projectId: draftProjectId,
|
||||
hostId: draftHostId,
|
||||
projectHostSetupId: draftProjectHostSetupId,
|
||||
projectId: initialRunSeed.projectId,
|
||||
hostId: initialRunSeed.hostId,
|
||||
projectHostSetupId: initialRunSeed.projectHostSetupId,
|
||||
focusedHostScope: workspaceHostScope
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user