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
359 changes: 357 additions & 2 deletions contracts/runpane/contract.json

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions contracts/runpane/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,17 @@
},
"agents": {
"$ref": "#/$defs/stringList"
},
"eventSelectors": {
"$ref": "#/$defs/stringList"
}
},
"additionalProperties": false
},
"eventSelectorMap": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"agentTemplates": {
"type": "object",
"additionalProperties": {
Expand Down Expand Up @@ -283,6 +290,13 @@
},
"jsonSchemas": {
"$ref": "#/$defs/stringList"
},
"outputMode": {
"enum": ["jsonl"]
},
"exitCodes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"additionalProperties": false
Expand Down Expand Up @@ -330,6 +344,9 @@
},
"description": {
"type": "string"
},
"repeatable": {
"type": "boolean"
}
},
"additionalProperties": false
Expand All @@ -352,6 +369,8 @@
"panes archive",
"panes pin",
"panes unpin",
"panes status",
"panes watch",
"panels",
"panels create",
"panels list",
Expand All @@ -361,6 +380,10 @@
"panels submit",
"panels submit-composer",
"panels wait",
"panels events",
"panels watch",
"panels await",
"panels await-any",
"agent-context"
],
"properties": {
Expand Down Expand Up @@ -409,6 +432,8 @@
"panes unpin": {
"$ref": "#/$defs/helpLines"
},
"panes status": { "$ref": "#/$defs/helpLines" },
"panes watch": { "$ref": "#/$defs/helpLines" },
"panels": {
"$ref": "#/$defs/helpLines"
},
Expand Down Expand Up @@ -436,6 +461,16 @@
"panels wait": {
"$ref": "#/$defs/helpLines"
},
"panels events": {
"$ref": "#/$defs/helpLines"
},
"panels watch": {
"$ref": "#/$defs/helpLines"
},
"panels await": {
"$ref": "#/$defs/helpLines"
},
"panels await-any": { "$ref": "#/$defs/helpLines" },
"agent-context": {
"$ref": "#/$defs/helpLines"
}
Expand Down
12 changes: 12 additions & 0 deletions docs/RUNPANE_CLI_CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ Brief tools:
- `panels submit`: Send text plus terminal Enter to a terminal panel.
- `panels submit-composer`: Submit an agent composer with the correct key sequence, including Ctrl+Enter for Codex.
- `panels wait`: Wait for terminal initialized, ready, idle, or text state with compact output.
- `panels events`: Replay semantic panel events after a cursor.
- `panels watch`: Stream semantic panel events as JSONL.
- `panels await`: Wait for a matching semantic panel event.

Managed AGENTS.md block body:

Expand Down Expand Up @@ -296,6 +299,11 @@ These flags are consumed by local daemon-control commands:
--for <initialized|ready|idle|text>
--contains <text>
--interval-ms <milliseconds>
--event <selector>
--since <cursor>
--changed-since <cursor>
--heartbeat-ms <milliseconds>
--handle-known-interstitials <safe>
--text <text>
--input-file <path|->
--source <user|agent>
Expand All @@ -306,6 +314,10 @@ These flags are consumed by local daemon-control commands:
--focus
--pinned
--force
--jsonl
--include-future-panels
--start-agent
--wait-active
```

`runpane doctor --json`, `runpane repos list`, `runpane panes list`, `runpane panes create`, and `runpane panels ...` commands use or describe the local framed daemon socket/pipe for a running Pane app. `--pane-dir` points the wrapper at a non-default Pane data directory, such as `PANE_DIR=~/.pane_test` in development. `runpane agent-context` is local/offline and can be used before Pane is running. In a Pane repository checkout, if `runpane` is not on PATH, use the built local wrapper with Node 22, for example `PATH=/opt/homebrew/opt/node@22/bin:$PATH node packages/runpane/dist/cli.js doctor --json`. From WSL, if the user runs Windows Pane, call the Windows wrapper through `powershell.exe -NoProfile -Command 'Set-Location $env:TEMP; runpane ...'` so the command can reach the Windows named-pipe daemon and avoid UNC cwd issues.
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export interface AppConfig {
autoStartOnBoot?: boolean;
// Keep the computer awake while any session is active
keepAwakeWhileSessionsActive?: boolean;
// Silence interval before agent activity is considered idle
agentIdleDebounceMs?: number;
// Stravu MCP integration
stravuApiKey?: string;
stravuServerUrl?: string;
Expand Down Expand Up @@ -167,6 +169,7 @@ export interface UpdateConfigRequest {
autoCheckUpdates?: boolean;
autoStartOnBoot?: boolean;
keepAwakeWhileSessionsActive?: boolean;
agentIdleDebounceMs?: number;
stravuApiKey?: string;
stravuServerUrl?: string;
theme?: AppConfig['theme'];
Expand Down
6 changes: 6 additions & 0 deletions main/src/core/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ConfigManager } from '../services/configManager';
import type { PtyHostSpawnOpts } from '../ptyHost/types';
import { noopPaneEventSink, type PaneEventSink } from './eventSink';
import type { RunpaneEventLog } from '../services/runpaneEventLog';

export interface PaneWebviewContext {
panelId: string;
Expand Down Expand Up @@ -53,6 +54,7 @@ export interface PaneRuntime {
*/
daemonEventSink?: PaneEventSink;
getConfigManager(): ConfigManager;
getRunpaneEventLog(): RunpaneEventLog;
getPtyHostRuntime(): PtyHostRuntime | null;
getWebviewContextMap(): Map<number, PaneWebviewContext>;
}
Expand Down Expand Up @@ -83,6 +85,10 @@ export function getRuntimeConfigManager(): ConfigManager {
return getPaneRuntime().getConfigManager();
}

export function getRuntimeRunpaneEventLog(): RunpaneEventLog {
return getPaneRuntime().getRunpaneEventLog();
}

export function getPtyHostRuntime(): PtyHostRuntime | null {
return getPaneRuntime().getPtyHostRuntime();
}
Expand Down
7 changes: 6 additions & 1 deletion main/src/daemon/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { setupEventListeners } from '../events';
import { getAppDirectory } from '../utils/appDirectory';
import { resourceMonitorService } from '../services/resourceMonitorService';
import type { PaneCommandRegistry } from './commandRegistry';
import { RunpaneEventLog } from '../services/runpaneEventLog';

interface PaneDaemonHostOptions {
app: App;
Expand Down Expand Up @@ -65,11 +66,13 @@ function installPaneRuntime(
getPtyHostRuntime: () => PtyHostRuntime | null,
getWebviewContextMap: () => Map<number, PaneWebviewContext>,
daemonEventSink?: PaneEventSink,
runpaneEventLog = new RunpaneEventLog(),
): void {
setPaneRuntime({
eventSink,
daemonEventSink,
getConfigManager: () => configManager,
getRunpaneEventLog: () => runpaneEventLog,
getPtyHostRuntime,
getWebviewContextMap,
});
Expand All @@ -93,10 +96,11 @@ export async function createPaneDaemonHost(options: PaneDaemonHostOptions): Prom
const rendererEventSink = options.rendererEventSink ?? noopPaneEventSink;
const headlessWebviewContextMap = new Map<number, PaneWebviewContext>();
const getWebviewContextMap = options.getWebviewContextMap ?? (() => headlessWebviewContextMap);
const runpaneEventLog = new RunpaneEventLog();

const configManager = new ConfigManager();
await configManager.initialize();
installPaneRuntime(rendererEventSink, configManager, options.getPtyHostRuntime, getWebviewContextMap);
installPaneRuntime(rendererEventSink, configManager, options.getPtyHostRuntime, getWebviewContextMap, undefined, runpaneEventLog);

const logger = new Logger(configManager);
console.log('[Main] Logger initialized with file logging to ~/.pane/logs');
Expand Down Expand Up @@ -256,6 +260,7 @@ export async function createPaneDaemonHost(options: PaneDaemonHostOptions): Prom
options.getPtyHostRuntime,
getWebviewContextMap,
createFanoutEventSink(daemonSinks),
runpaneEventLog,
);

setupEventListeners(services);
Expand Down
12 changes: 12 additions & 0 deletions main/src/ipc/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ describe('config IPC handlers', () => {
}
});

it('round-trips agentIdleDebounceMs through config:update', async () => {
const ipcMain = createIpcMainStub();
registerConfigHandlers(ipcMain as unknown as IpcMain, createServicesStub([]));

const updateConfig = ipcMain.handlers.get('config:update');
expect(updateConfig).toBeDefined();
await expect(updateConfig?.({}, { agentIdleDebounceMs: 12_345 })).resolves.toEqual({
success: true,
data: expect.objectContaining({ agentIdleDebounceMs: 12_345 }),
});
});

it('removes managed AGENTS blocks from all saved projects when disabled', async () => {
const activeProject = await createTempProject(1);
const inactiveProject = await createTempProject(2);
Expand Down
Loading
Loading