Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/create-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ on:
- image-resize
- llm-router
- fp
- github
- mcp
- memory
- memory-consolidate
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ on:
- 'image-resize/v*'
- 'llm-router/v*'
- 'fp/v*'
- 'github/v*'
- 'mcp/v*'
- 'memory/v*'
- 'memory-consolidate/v*'
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ npx skills add iii-hq/iii --all
| [`scrapling`](scrapling/) | Python | [Scrapling](https://github.com/D4Vinci/Scrapling) as an iii worker — `scrapling::*` map three fetch tiers (HTTP / Camoufox stealth / Playwright), screenshots, and CSS/XPath/regex/adaptive extraction over the bus. |
| [`browser`](browser/) | Rust | Interactive Chromium sessions over CDP with console/network capture, a11y-tree snapshots with actionable refs, viewable screenshots, and DevTools element picking for the console UI. |
| [`worktree`](worktree/) | Rust | Git worktree lifecycle for parallel agents — `worktree::*` mint, claim, and track isolated worktrees per repo, emit six lifecycle trigger types, and land branches back through a per-repo FIFO queue (rebase, test gate, ff-only merge). |
| [`github`](github/) | Rust | GitHub CLI (`gh`) as an iii worker — typed `github::pr/issue/repo/run/workflow/release/search::*` functions plus `github::exec` argv passthrough and `github::api` for any GitHub REST endpoint. |

## SDK

Expand Down
2 changes: 1 addition & 1 deletion console/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion console/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[package]
name = "console"
version = "1.6.10"
version = "1.6.11"
edition = "2021"
publish = false

Expand Down
12 changes: 10 additions & 2 deletions console/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { buildViewOptions } from '@/lib/nav-options'
import { cn } from '@/lib/utils'
import { Browser } from '@/pages/Browser'
import { Configuration } from '@/pages/Configuration'
import { Github } from '@/pages/Github'
import { Memory } from '@/pages/Memory'
import { TracesV2 } from '@/pages/TracesV2'
import { Workers } from '@/pages/Workers'
Expand Down Expand Up @@ -100,6 +101,8 @@ export function App() {
<Browser />
) : view === 'memory' ? (
<Memory />
) : view === 'github' ? (
<Github />
) : (
<TracesV2 />
)}
Expand Down Expand Up @@ -129,12 +132,17 @@ function Header({
// Optional-worker entries appear only while their worker is present; a
// direct #/worktrees or #/browser hit still lands on that page's install
// notice.
const { worktreeAvailable, browserAvailable, memoryAvailable } =
useConversationsCtx()
const {
worktreeAvailable,
browserAvailable,
memoryAvailable,
githubAvailable,
} = useConversationsCtx()
const viewOptions = buildViewOptions(
worktreeAvailable,
browserAvailable,
memoryAvailable,
githubAvailable,
)
const onConsoleSettings = view === 'configuration'
return (
Expand Down
19 changes: 19 additions & 0 deletions console/web/src/hooks/use-github-status.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest'
import {
GITHUB_WATCH_FN,
GITHUB_WORKER_NAME,
isGithubAvailable,
} from './use-github-status'

describe('github presence probe wiring', () => {
it('probes the github worker with its own watch handler id', () => {
expect(GITHUB_WORKER_NAME).toBe('github')
expect(GITHUB_WATCH_FN).toBe('console::github-watch')
})

it('gates on both presence and the initial probe settling', () => {
expect(isGithubAvailable({ present: true, loading: false })).toBe(true)
expect(isGithubAvailable({ present: true, loading: true })).toBe(false)
expect(isGithubAvailable({ present: false, loading: false })).toBe(false)
})
})
43 changes: 43 additions & 0 deletions console/web/src/hooks/use-github-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
isWorkerPresent,
useWorkerPresence,
type WorkerPresence,
} from './use-worker-presence'

/**
* Presence probe for the `github` worker. It wraps the GitHub CLI (`gh`) as
* typed `github::*` functions (pull requests, issues, Actions runs, releases,
* search). It is OPTIONAL, so the console gates the Github page on its
* presence rather than rendering controls that would call functions that
* don't exist. Thin wrapper over the generic worker-presence probe.
*/

/** Engine worker name for the github worker. */
const GITHUB_WORKER_NAME = 'github'
/** Base id for the browser-local handler bound to the `worker` trigger. */
const GITHUB_WATCH_FN = 'console::github-watch'

export type GithubStatus = WorkerPresence

/**
* @param enabled - only run against the real backend; pass `false` for the
* mock/Storybook backend (treats github as present so its UI shows in
* isolation).
*/
export function useGithubStatus(enabled: boolean): GithubStatus {
return useWorkerPresence({
workerName: GITHUB_WORKER_NAME,
watchFnId: GITHUB_WATCH_FN,
enabled,
})
}

/**
* Whether the github worker's functions are registered and safe to trigger.
* False during the initial presence probe and while the worker is absent.
*/
export function isGithubAvailable(status: GithubStatus): boolean {
return isWorkerPresent(status)
}

export { GITHUB_WATCH_FN, GITHUB_WORKER_NAME }
6 changes: 6 additions & 0 deletions console/web/src/hooks/use-hash-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type View =
| 'worktrees'
| 'browser'
| 'memory'
| 'github'

export interface WorkersConfigurationRoute {
configurationId: string | null
Expand Down Expand Up @@ -97,6 +98,9 @@ function routeFromHash(hash: string): View | null {
if (hash === '#/memory') {
return 'memory'
}
if (hash === '#/github') {
return 'github'
}
if (hash === '#/browser' || hash.startsWith('#/browser/')) {
return 'browser'
}
Expand Down Expand Up @@ -130,6 +134,8 @@ function hashFor(view: View): string {
return '#/browser'
case 'memory':
return '#/memory'
case 'github':
return '#/github'
case 'configuration':
return '#/configuration'
}
Expand Down
11 changes: 11 additions & 0 deletions console/web/src/lib/conversations-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
type ConversationsApi,
useConversations,
} from '@/hooks/use-conversations'
import { isGithubAvailable, useGithubStatus } from '@/hooks/use-github-status'
import {
type HarnessStatus,
isHarnessAvailable,
Expand Down Expand Up @@ -92,6 +93,12 @@ interface ConversationsContextValue extends ConversationsApi {
* backend.
*/
memoryAvailable: boolean
/**
* Whether the optional `github` worker is connected — gates the Github
* page nav entry and its `github::*` RPC. Only meaningful on the real
* backend.
*/
githubAvailable: boolean
}

const ConversationsContext = createContext<ConversationsContextValue | null>(
Expand Down Expand Up @@ -126,6 +133,9 @@ export function ConversationsProvider({
const memoryAvailable = isMemoryAvailable(
useMemoryStatus(backend.id === 'real'),
)
const githubAvailable = isGithubAvailable(
useGithubStatus(backend.id === 'real'),
)
const {
modelOptions,
catalogKeys,
Expand Down Expand Up @@ -175,6 +185,7 @@ export function ConversationsProvider({
worktreeAvailable,
browserAvailable,
memoryAvailable,
githubAvailable,
}

return (
Expand Down
Loading
Loading