@pentoshi/clai 3.11.8 → 3.11.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/agent/confirm-port.d.ts +4 -0
- package/dist/agent/confirm-port.js +9 -1
- package/dist/agent/confirm-port.js.map +1 -1
- package/dist/agent/runner.js +13 -5
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/tool-call-parser.js +3 -0
- package/dist/agent/tool-call-parser.js.map +1 -1
- package/dist/app/adapters/current-interactive-sessions-adapter.d.ts +4 -0
- package/dist/app/adapters/current-interactive-sessions-adapter.js +12 -0
- package/dist/app/adapters/current-interactive-sessions-adapter.js.map +1 -0
- package/dist/app/controllers/cancel-all-result.d.ts +8 -0
- package/dist/app/controllers/cancel-all-result.js +32 -0
- package/dist/app/controllers/cancel-all-result.js.map +1 -0
- package/dist/app/controllers/session-controller.d.ts +3 -0
- package/dist/app/controllers/session-controller.js +22 -6
- package/dist/app/controllers/session-controller.js.map +1 -1
- package/dist/app/ports/interactive-sessions-port.d.ts +22 -0
- package/dist/app/ports/interactive-sessions-port.js +9 -0
- package/dist/app/ports/interactive-sessions-port.js.map +1 -0
- package/dist/index.js +24 -13
- package/dist/index.js.map +1 -1
- package/dist/interactive-session/artifact-writer.d.ts +54 -0
- package/dist/interactive-session/artifact-writer.js +161 -0
- package/dist/interactive-session/artifact-writer.js.map +1 -0
- package/dist/interactive-session/cleanup.d.ts +37 -0
- package/dist/interactive-session/cleanup.js +191 -0
- package/dist/interactive-session/cleanup.js.map +1 -0
- package/dist/interactive-session/config.d.ts +118 -0
- package/dist/interactive-session/config.js +141 -0
- package/dist/interactive-session/config.js.map +1 -0
- package/dist/interactive-session/input-policy.d.ts +26 -0
- package/dist/interactive-session/input-policy.js +70 -0
- package/dist/interactive-session/input-policy.js.map +1 -0
- package/dist/interactive-session/manager.d.ts +118 -0
- package/dist/interactive-session/manager.js +1214 -0
- package/dist/interactive-session/manager.js.map +1 -0
- package/dist/interactive-session/output-store.d.ts +81 -0
- package/dist/interactive-session/output-store.js +239 -0
- package/dist/interactive-session/output-store.js.map +1 -0
- package/dist/interactive-session/output-view.d.ts +20 -0
- package/dist/interactive-session/output-view.js +142 -0
- package/dist/interactive-session/output-view.js.map +1 -0
- package/dist/interactive-session/recovery-journal.d.ts +53 -0
- package/dist/interactive-session/recovery-journal.js +167 -0
- package/dist/interactive-session/recovery-journal.js.map +1 -0
- package/dist/interactive-session/registry.d.ts +59 -0
- package/dist/interactive-session/registry.js +170 -0
- package/dist/interactive-session/registry.js.map +1 -0
- package/dist/interactive-session/runtime.d.ts +107 -0
- package/dist/interactive-session/runtime.js +191 -0
- package/dist/interactive-session/runtime.js.map +1 -0
- package/dist/interactive-session/session-runtime.d.ts +53 -0
- package/dist/interactive-session/session-runtime.js +65 -0
- package/dist/interactive-session/session-runtime.js.map +1 -0
- package/dist/interactive-session/streaming-redactor.d.ts +53 -0
- package/dist/interactive-session/streaming-redactor.js +271 -0
- package/dist/interactive-session/streaming-redactor.js.map +1 -0
- package/dist/interactive-session/telemetry.d.ts +30 -0
- package/dist/interactive-session/telemetry.js +47 -0
- package/dist/interactive-session/telemetry.js.map +1 -0
- package/dist/interactive-session/transport-factory.d.ts +8 -0
- package/dist/interactive-session/transport-factory.js +16 -0
- package/dist/interactive-session/transport-factory.js.map +1 -0
- package/dist/interactive-session/transport-node-pty.d.ts +38 -0
- package/dist/interactive-session/transport-node-pty.js +390 -0
- package/dist/interactive-session/transport-node-pty.js.map +1 -0
- package/dist/interactive-session/transport-pipe.d.ts +9 -0
- package/dist/interactive-session/transport-pipe.js +267 -0
- package/dist/interactive-session/transport-pipe.js.map +1 -0
- package/dist/interactive-session/transport.d.ts +110 -0
- package/dist/interactive-session/transport.js +89 -0
- package/dist/interactive-session/transport.js.map +1 -0
- package/dist/interactive-session/types.d.ts +258 -0
- package/dist/interactive-session/types.js +191 -0
- package/dist/interactive-session/types.js.map +1 -0
- package/dist/os/process-identity.d.ts +46 -0
- package/dist/os/process-identity.js +147 -0
- package/dist/os/process-identity.js.map +1 -0
- package/dist/os/process-tree.d.ts +1 -0
- package/dist/os/process-tree.js +11 -0
- package/dist/os/process-tree.js.map +1 -1
- package/dist/prompts/embedded.js +1 -1
- package/dist/prompts/embedded.js.map +1 -1
- package/dist/prompts/system.agent.md +3 -0
- package/dist/repl.js +16 -1
- package/dist/repl.js.map +1 -1
- package/dist/safety/classifier.d.ts +9 -0
- package/dist/safety/classifier.js +119 -18
- package/dist/safety/classifier.js.map +1 -1
- package/dist/safety/engagement-policy.d.ts +13 -0
- package/dist/safety/engagement-policy.js +129 -34
- package/dist/safety/engagement-policy.js.map +1 -1
- package/dist/tools/definitions.js +94 -0
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/interactive-session-tools.d.ts +11 -0
- package/dist/tools/interactive-session-tools.js +276 -0
- package/dist/tools/interactive-session-tools.js.map +1 -0
- package/dist/tools/registry.js +3 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tui-v2/bootstrap/composition-root.d.ts +3 -0
- package/dist/tui-v2/bootstrap/composition-root.js +3 -0
- package/dist/tui-v2/bootstrap/composition-root.js.map +1 -1
- package/dist/tui-v2/bootstrap/start-tui-v2.js +8 -0
- package/dist/tui-v2/bootstrap/start-tui-v2.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Two things make it practical for everyday use:
|
|
|
19
19
|
- **Scope-based pentesting.** Opt-in engagement scope with authorized/excluded targets, allowed phases, rate and concurrency ceilings, redirect and DNS-rebinding escape detection, and out-of-scope flagging — designed for authorized pentests and bug-bounty programs.
|
|
20
20
|
- **Real building & debugging.** Scaffolds apps, edits code surgically, installs packages, runs builds/tests, starts dev servers as background jobs, and probes them before reporting success.
|
|
21
21
|
- **Durable plans.** `plan.create` / `task.update` drive a live checklist that survives context compaction and reloads with `/history` — the agent works task-by-task and won't fake completion.
|
|
22
|
+
- **Persistent interactive terminals.** Conversation-owned PTY or pipe sessions keep REPLs such as Python, Metasploit, Meterpreter, database consoles, and debuggers open across model turns. The agent can send follow-up input, read incremental output, resize, interrupt, and close them without losing state.
|
|
22
23
|
- **Native + text tool calling.** Uses provider-native function calling where available, with a text-fence fallback (`toolCalling: auto|native|text`).
|
|
23
24
|
- **Safety gate you control.** Every action is classified safe / confirm / block; deletes always confirm with a preview; destructive patterns are blocked.
|
|
24
25
|
|
|
@@ -416,6 +417,20 @@ Drop a `.clai/context.md` in a repo and its contents are injected every turn —
|
|
|
416
417
|
|
|
417
418
|
---
|
|
418
419
|
|
|
420
|
+
## Interactive REPLs and terminals
|
|
421
|
+
|
|
422
|
+
Ask clai to use an interactive terminal whenever a program needs more than one input step. It keeps the process attached to the current conversation instead of treating it like a one-line shell command:
|
|
423
|
+
|
|
424
|
+
```text
|
|
425
|
+
Start a Python REPL, inspect the failing parser, make a small change, and show me the result.
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
The agent uses `terminal.start`, `terminal.send`, `terminal.read`, `terminal.status`, `terminal.list`, `terminal.resize`, and `terminal.close` internally. Sessions are isolated per conversation, capture output as cursor-addressed pages, redact prompted secret input before it reaches transcripts or artifacts, and reliably terminate their process trees on close. In plan mode, starting or sending terminal input waits for plan approval; read, status, list, and close operations remain available.
|
|
429
|
+
|
|
430
|
+
For authorized security work, interactive effects are re-evaluated against the active engagement scope at the time they are delivered. That includes the target, port, phase, and expiry accumulated from prior REPL commands, so a split sequence cannot bypass scope controls.
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
419
434
|
## Configuration & privacy
|
|
420
435
|
|
|
421
436
|
```sh
|
|
@@ -29,6 +29,10 @@ export interface ConfirmPort {
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function restoreInteractiveStdin(): void;
|
|
31
31
|
export declare const inquirerConfirmPort: ConfirmPort;
|
|
32
|
+
export declare function inquirerSecretRequester(request: {
|
|
33
|
+
title: string;
|
|
34
|
+
prompt: string;
|
|
35
|
+
}): Promise<string | undefined>;
|
|
32
36
|
export declare function ensurePentestAuthorization(call: ToolCall, autoConfirm: boolean, session: SessionPolicy, confirmPort: ConfirmPort): Promise<boolean>;
|
|
33
37
|
export declare function confirmToolExecution(call: ToolCall, autoConfirm: boolean, session: SessionPolicy, confirmPort: ConfirmPort, options?: {
|
|
34
38
|
forceConfirm?: boolean | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { confirm } from "@inquirer/prompts";
|
|
1
|
+
import { confirm, password } from "@inquirer/prompts";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { getConfig } from "../store/config.js";
|
|
4
4
|
import { isPentestToolCall } from "../safety/classifier.js";
|
|
@@ -58,6 +58,14 @@ export const inquirerConfirmPort = {
|
|
|
58
58
|
});
|
|
59
59
|
},
|
|
60
60
|
};
|
|
61
|
+
export async function inquirerSecretRequester(request) {
|
|
62
|
+
try {
|
|
63
|
+
return await password({ message: request.prompt || request.title });
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
restoreInteractiveStdin();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
61
69
|
export async function ensurePentestAuthorization(call, autoConfirm, session, confirmPort) {
|
|
62
70
|
if (!isPentestToolCall(call))
|
|
63
71
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm-port.js","sourceRoot":"","sources":["../../src/agent/confirm-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"confirm-port.js","sourceRoot":"","sources":["../../src/agent/confirm-port.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -82,7 +82,7 @@ import { EngagementPolicyEngine, actionFromUrl, engagementActionsForToolCall, ev
|
|
|
82
82
|
import { patchPlanMeta } from "../store/plan.js";
|
|
83
83
|
import { extractProjectRootFromPlan, extractProjectRootFromScaffold, extractProjectRootFromText, getActiveProjectRoot, setActiveProjectRootIfValid, } from "./project-root.js";
|
|
84
84
|
import { buildWorkspaceOrientation, discoverImmediateProjectRoots, guessProjectFolderName, isBareParentDirectory, isScaffoldCancelledOutput, scaffoldLooksMaterialized, scaffoldTargetConflictMessage, resolveScaffoldTargetPath, } from "./workspace-orient.js";
|
|
85
|
-
import { inquirerConfirmPort, restoreInteractiveStdin, ensurePentestAuthorization, confirmToolExecution, } from "./confirm-port.js";
|
|
85
|
+
import { inquirerConfirmPort, inquirerSecretRequester, restoreInteractiveStdin, ensurePentestAuthorization, confirmToolExecution, } from "./confirm-port.js";
|
|
86
86
|
import { buildRichStopSummary } from "./stop-summary.js";
|
|
87
87
|
import { composeAgentSystemPrompt } from "./prompt-composer.js";
|
|
88
88
|
import { createGovernorState, governProgress, } from "./evidence-governor.js";
|
|
@@ -1638,9 +1638,17 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
1638
1638
|
if (isPlanMode &&
|
|
1639
1639
|
!session.planApproved.value &&
|
|
1640
1640
|
!isScratchOnlyWrite(call, scratchDir)) {
|
|
1641
|
-
const cmd =
|
|
1642
|
-
|
|
1643
|
-
|
|
1641
|
+
const cmd = call.name === "terminal.send"
|
|
1642
|
+
? typeof call.args.text === "string"
|
|
1643
|
+
? call.args.text
|
|
1644
|
+
: ""
|
|
1645
|
+
: typeof call.args.command === "string"
|
|
1646
|
+
? call.args.command
|
|
1647
|
+
: "";
|
|
1648
|
+
const shellBlocked = call.name === "terminal.start" ||
|
|
1649
|
+
call.name === "terminal.send" ||
|
|
1650
|
+
((call.name === "shell.exec" || call.name === "shell.start") &&
|
|
1651
|
+
!isPlanModeAllowedShellCommand(cmd));
|
|
1644
1652
|
const allowed = isPlanModeAllowedTool(call.name) && !shellBlocked;
|
|
1645
1653
|
if (!allowed) {
|
|
1646
1654
|
const reason = `plan mode — ${call.name} is blocked (gather-only). ` +
|
|
@@ -2083,7 +2091,7 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
2083
2091
|
const runToolWithForcedSettle = () => {
|
|
2084
2092
|
const work = runToolCall(call, {
|
|
2085
2093
|
signal: toolAc.signal,
|
|
2086
|
-
requestSecret: options.requestSecret,
|
|
2094
|
+
requestSecret: options.requestSecret ?? inquirerSecretRequester,
|
|
2087
2095
|
onOutput: (chunk) => {
|
|
2088
2096
|
if (toolAc.signal.aborted)
|
|
2089
2097
|
return;
|