Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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