@midhunxavier/code-flow 0.0.0-stage → 0.1.0-preview.3
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/LICENSE +21 -0
- package/README.md +141 -2
- package/bin/codeflow.mjs +8 -0
- package/bin/launcher.mjs +127 -0
- package/dist/remote-host.json +1 -0
- package/licenses/inter.txt +92 -0
- package/licenses/preact.txt +21 -0
- package/licenses/signals-core.txt +21 -0
- package/licenses/signals.txt +21 -0
- package/licenses/typescript-notices.txt +193 -0
- package/licenses/typescript.txt +55 -0
- package/licenses/uqr.txt +22 -0
- package/licenses/xterm-fit.txt +19 -0
- package/licenses/xterm.txt +21 -0
- package/package.json +34 -4
- package/public/assets/changes-62ZIEQSN.js +1 -0
- package/public/assets/chunk-2PZVOKID.js +1 -0
- package/public/assets/chunk-4D5IENEB.js +1 -0
- package/public/assets/chunk-5SARP5MU.js +1 -0
- package/public/assets/chunk-63YLZ3PR.js +1 -0
- package/public/assets/chunk-7FUHKF2M.js +1 -0
- package/public/assets/chunk-APQEVJ2K.js +1 -0
- package/public/assets/chunk-CGOZQMEZ.js +2 -0
- package/public/assets/chunk-J4VYS3KV.js +2 -0
- package/public/assets/chunk-L7TUCIYF.js +1 -0
- package/public/assets/chunk-SIHDWM2Y.js +154 -0
- package/public/assets/chunk-TEJVYIKC.js +1 -0
- package/public/assets/code-browser-VB2HGZSG.js +4 -0
- package/public/assets/filtered-tasks-ES5CP4KV.js +1 -0
- package/public/assets/interactive-browser-7F5ZXRUV.js +7 -0
- package/public/assets/join-project-6RTFHNCA.js +1 -0
- package/public/assets/main-65EW73SB.js +1 -0
- package/public/assets/project-invitations-view-GMPWGWYM.js +1 -0
- package/public/assets/settings-UB5Q4AQM.js +9 -0
- package/public/assets/styles-18792BB4.css +32 -0
- package/public/assets/team-server-wizard-2GLDWS6D.js +8 -0
- package/public/assets/terminal-IWAIM4DE.js +62 -0
- package/public/assets.json +1 -0
- package/public/bundle-meta.json +1 -0
- package/public/docs/.nojekyll +0 -0
- package/public/docs/accessibility.html +19 -0
- package/public/docs/acp-agents.html +117 -0
- package/public/docs/agent-containers.html +79 -0
- package/public/docs/api.html +1130 -0
- package/public/docs/app.js +342 -0
- package/public/docs/application-improvements.html +275 -0
- package/public/docs/architecture-explorer.html +19 -0
- package/public/docs/architecture.html +149 -0
- package/public/docs/auto-team.html +148 -0
- package/public/docs/automations.html +109 -0
- package/public/docs/checkpoint-review.html +37 -0
- package/public/docs/code-hosts.html +35 -0
- package/public/docs/code-intelligence.html +35 -0
- package/public/docs/configuration.html +346 -0
- package/public/docs/context-inspection.html +23 -0
- package/public/docs/coordinated-changes.html +28 -0
- package/public/docs/deferred-runs.html +25 -0
- package/public/docs/dependency-discovery.html +19 -0
- package/public/docs/documentation.html +84 -0
- package/public/docs/dynamic-teams-evaluation.html +174 -0
- package/public/docs/dynamic-teams-implementation-plan.html +882 -0
- package/public/docs/dynamic-teams-implementation-review-1.html +141 -0
- package/public/docs/dynamic-teams-plan-review-0.html +204 -0
- package/public/docs/extensions.html +42 -0
- package/public/docs/external-sources.html +96 -0
- package/public/docs/filesystem-policy.html +26 -0
- package/public/docs/filtered-tasks.html +44 -0
- package/public/docs/font-license.txt +92 -0
- package/public/docs/getting-started.html +143 -0
- package/public/docs/github-review-threads.html +26 -0
- package/public/docs/github.html +157 -0
- package/public/docs/help.html +69 -0
- package/public/docs/index.html +88 -0
- package/public/docs/installation.html +80 -0
- package/public/docs/launch-profiles.html +48 -0
- package/public/docs/maintenance.html +60 -0
- package/public/docs/memory-claims.html +31 -0
- package/public/docs/memory-storage.html +58 -0
- package/public/docs/notifications.html +39 -0
- package/public/docs/patterns.html +195 -0
- package/public/docs/performance-results.html +210 -0
- package/public/docs/performance.html +166 -0
- package/public/docs/project-conventions.html +22 -0
- package/public/docs/project-first-navigation-plan.html +587 -0
- package/public/docs/project-teams-implementation-plan.html +772 -0
- package/public/docs/project-teams.html +129 -0
- package/public/docs/provider-compatibility.html +20 -0
- package/public/docs/releasing.html +65 -0
- package/public/docs/remote-workers.html +64 -0
- package/public/docs/review-inbox.html +26 -0
- package/public/docs/run-storage.html +23 -0
- package/public/docs/runs.html +141 -0
- package/public/docs/search.json +1 -0
- package/public/docs/security.html +133 -0
- package/public/docs/shared-projects.html +31 -0
- package/public/docs/ssh-projects.html +60 -0
- package/public/docs/style.css +768 -0
- package/public/docs/task-reruns.html +30 -0
- package/public/docs/team-collaboration.html +412 -0
- package/public/docs/verification.html +22 -0
- package/public/docs/vscode.html +53 -0
- package/public/docs/worker-permission-verification.html +131 -0
- package/public/index.html +17 -0
- package/scripts/check-node.mjs +7 -0
- package/scripts/codeflow.mjs +55 -0
- package/scripts/computer-use.swift +64 -0
- package/scripts/pty.py +273 -0
- package/src/acp-connections.js +110 -0
- package/src/adapters/acp-presets.js +37 -0
- package/src/adapters/acp-types.js +0 -0
- package/src/adapters/acp.js +328 -0
- package/src/adapters/agent-tools.js +28 -0
- package/src/adapters/agy-auth.js +67 -0
- package/src/adapters/agy-isolation.js +242 -0
- package/src/adapters/agy-tools.js +45 -0
- package/src/adapters/agy.js +326 -0
- package/src/adapters/claude-stream.js +58 -0
- package/src/adapters/claude.js +282 -0
- package/src/adapters/codex-app-server.js +555 -0
- package/src/adapters/codex.js +311 -0
- package/src/adapters/errors.js +57 -0
- package/src/adapters/index.js +91 -0
- package/src/adapters/managed-permissions.js +37 -0
- package/src/adapters/model-discovery.js +100 -0
- package/src/adapters/process.js +433 -0
- package/src/adapters/team-tools.js +103 -0
- package/src/adapters/types.js +0 -0
- package/src/agent-browser.js +688 -0
- package/src/agent-computer.js +88 -0
- package/src/agent-container.js +155 -0
- package/src/agent-team-definitions.js +131 -0
- package/src/agent-tool-client.mjs +79 -0
- package/src/agent-tools.js +296 -0
- package/src/approvals.js +134 -0
- package/src/architecture.js +456 -0
- package/src/assets.js +44 -0
- package/src/automation.js +901 -0
- package/src/browser-files.js +293 -0
- package/src/browser-ownership.js +150 -0
- package/src/certificate-renewal.js +75 -0
- package/src/chat-family.js +25 -0
- package/src/chat-handoff.js +87 -0
- package/src/checkpoint-review.js +72 -0
- package/src/checks.js +303 -0
- package/src/code-host-git.js +102 -0
- package/src/code-hosts-api.js +99 -0
- package/src/code-hosts.js +482 -0
- package/src/code-intelligence-worker.mjs +452 -0
- package/src/code-intelligence.js +141 -0
- package/src/collab/api.js +365 -0
- package/src/collab/checkpoints.js +198 -0
- package/src/collab/connections.js +139 -0
- package/src/collab/host-execution.js +347 -0
- package/src/collab/hub-client.js +210 -0
- package/src/collab/link-api.js +229 -0
- package/src/collab/link.js +595 -0
- package/src/collab/model.js +496 -0
- package/src/collab/runner.js +1014 -0
- package/src/collab/store.js +1452 -0
- package/src/collab/terminals.js +361 -0
- package/src/collaboration-reviews.js +116 -0
- package/src/config.js +48 -0
- package/src/context-budget.js +14 -0
- package/src/context-inspection.js +204 -0
- package/src/context.js +154 -0
- package/src/conventions.js +283 -0
- package/src/coordinated-api.js +247 -0
- package/src/deferred-launch.js +82 -0
- package/src/deferred-runs.js +515 -0
- package/src/dependency-health.js +35 -0
- package/src/diff.js +43 -0
- package/src/docs-help.js +316 -0
- package/src/doctor.js +232 -0
- package/src/documentation-changes.js +20 -0
- package/src/engine.js +5258 -0
- package/src/env.js +44 -0
- package/src/execution-budget.js +8 -0
- package/src/experience.js +50 -0
- package/src/extensions.js +144 -0
- package/src/filesystem-access.js +107 -0
- package/src/filesystem-policy.js +238 -0
- package/src/filtered-task-limits.js +93 -0
- package/src/filtered-tasks-api.js +53 -0
- package/src/filtered-tasks.js +576 -0
- package/src/frame-policy.js +66 -0
- package/src/fs.js +57 -0
- package/src/git.js +626 -0
- package/src/github-review-threads.js +181 -0
- package/src/github.js +538 -0
- package/src/http.js +69 -0
- package/src/improve-settings.js +38 -0
- package/src/improve.js +187 -0
- package/src/integrations.js +373 -0
- package/src/integrity.js +259 -0
- package/src/journey-api.js +77 -0
- package/src/journey-replay.js +65 -0
- package/src/journey-store.js +97 -0
- package/src/journeys.js +60 -0
- package/src/json.js +81 -0
- package/src/launch-profiles.js +292 -0
- package/src/learnings.js +80 -0
- package/src/local-app-url.js +19 -0
- package/src/log.js +39 -0
- package/src/maintenance.js +335 -0
- package/src/memory-analysis.js +182 -0
- package/src/memory-claims.js +153 -0
- package/src/memory-sqlite.js +236 -0
- package/src/memory.js +552 -0
- package/src/merge-validation.js +58 -0
- package/src/model-catalog.js +239 -0
- package/src/model-research.js +91 -0
- package/src/notes.js +176 -0
- package/src/notifications.js +413 -0
- package/src/patterns/auto-team-model.js +230 -0
- package/src/patterns/auto-team.js +816 -0
- package/src/patterns/council.js +199 -0
- package/src/patterns/debate.js +188 -0
- package/src/patterns/findings.js +141 -0
- package/src/patterns/index.js +21 -0
- package/src/patterns/loop.js +158 -0
- package/src/patterns/pipeline.js +125 -0
- package/src/patterns/prompts.js +181 -0
- package/src/patterns/race.js +147 -0
- package/src/patterns/schemas.js +40 -0
- package/src/patterns/solo.js +46 -0
- package/src/patterns/supervisor.js +235 -0
- package/src/patterns/task-draft.js +29 -0
- package/src/patterns/task-review.js +45 -0
- package/src/patterns/tdd.js +231 -0
- package/src/patterns/team-strategies.js +67 -0
- package/src/performance.js +43 -0
- package/src/persistence-status.js +35 -0
- package/src/phone-sessions.js +96 -0
- package/src/preview-overlay.js +392 -0
- package/src/preview.js +230 -0
- package/src/privacy.js +23 -0
- package/src/project-report.js +22 -0
- package/src/project-team-budget.js +22 -0
- package/src/project-team-model.js +225 -0
- package/src/project-team-policy.js +42 -0
- package/src/project-team-store.js +234 -0
- package/src/project-team-usage.js +24 -0
- package/src/project-teams-api.js +43 -0
- package/src/project-teams.js +644 -0
- package/src/projects.js +290 -0
- package/src/provider-eligibility.js +9 -0
- package/src/readiness.js +98 -0
- package/src/remote-tls.js +66 -0
- package/src/remote-workers/bundles.js +198 -0
- package/src/remote-workers/client.js +332 -0
- package/src/remote-workers/durability.js +37 -0
- package/src/remote-workers/protocol.js +68 -0
- package/src/remote-workers/stdio.js +138 -0
- package/src/remote-workers/worker.js +304 -0
- package/src/remote.js +204 -0
- package/src/repo-config.js +201 -0
- package/src/repo-coordination.js +725 -0
- package/src/repo-tree.js +106 -0
- package/src/repository-identity.js +13 -0
- package/src/retention-policy.js +466 -0
- package/src/review-inbox.js +38 -0
- package/src/routing.js +49 -0
- package/src/run-analysis.js +111 -0
- package/src/run-cold-store.js +231 -0
- package/src/run-environment.js +15 -0
- package/src/run-history.js +91 -0
- package/src/run-log.js +160 -0
- package/src/run-permissions.js +111 -0
- package/src/run-projection.js +77 -0
- package/src/run-recovery.js +53 -0
- package/src/run-status.js +56 -0
- package/src/serve.js +138 -0
- package/src/server.js +2871 -0
- package/src/shared-access.js +103 -0
- package/src/shared-accounts.js +381 -0
- package/src/shared-api.js +239 -0
- package/src/shell.js +346 -0
- package/src/ship.js +344 -0
- package/src/slots.js +74 -0
- package/src/snapshot.js +388 -0
- package/src/source-context.js +17 -0
- package/src/sse-writer.js +70 -0
- package/src/ssh-projects/bootstrap.mjs +95 -0
- package/src/ssh-projects/config.js +45 -0
- package/src/ssh-projects/gateway.js +143 -0
- package/src/ssh-projects/manager.js +320 -0
- package/src/ssh-projects/team-autostart.mjs +93 -0
- package/src/ssh-projects/team-remove.mjs +69 -0
- package/src/ssh-projects/team-status.mjs +39 -0
- package/src/ssh-projects/transport.js +133 -0
- package/src/stats.js +139 -0
- package/src/store.js +544 -0
- package/src/stream.js +91 -0
- package/src/sweeps.js +241 -0
- package/src/tailscale.js +101 -0
- package/src/task-draft.js +23 -0
- package/src/task-team.js +164 -0
- package/src/team-evaluation.js +243 -0
- package/src/team-mailbox.js +160 -0
- package/src/team-memory.js +84 -0
- package/src/team-rerun-graph.js +15 -0
- package/src/team-reruns.js +130 -0
- package/src/team-scheduler.js +121 -0
- package/src/team-steering.js +21 -0
- package/src/team-template-store.js +98 -0
- package/src/team-templates.js +117 -0
- package/src/team-tool-client.mjs +79 -0
- package/src/team-tools.js +235 -0
- package/src/teams.js +0 -0
- package/src/templates.js +62 -0
- package/src/transcript.js +134 -0
- package/src/verification-integrity.js +27 -0
- package/src/verification.js +183 -0
- package/src/watch.js +195 -0
- package/src/work-queue.js +47 -0
- package/src/workflow-control.js +83 -0
- package/src/workspace-api.js +207 -0
- package/src/workspace-changes.js +61 -0
- package/src/workspace.js +146 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class ClaudeStream {
|
|
2
|
+
constructor(emit) {
|
|
3
|
+
this.emit = emit;
|
|
4
|
+
}
|
|
5
|
+
messageId = "";
|
|
6
|
+
blocks = /* @__PURE__ */ new Map();
|
|
7
|
+
lastText = "";
|
|
8
|
+
partial(event) {
|
|
9
|
+
if (event?.type === "message_start") {
|
|
10
|
+
this.messageId = event.message?.id ?? "";
|
|
11
|
+
this.blocks.clear();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (!this.messageId || !Number.isInteger(event?.index)) return;
|
|
15
|
+
const messageId = `${this.messageId}:${event.index}`;
|
|
16
|
+
if (event.type === "content_block_start") {
|
|
17
|
+
const block = event.content_block;
|
|
18
|
+
if (!block) return;
|
|
19
|
+
this.blocks.set(event.index, { type: block.type, id: block.id, name: block.name, input: "", text: block.text ?? "" });
|
|
20
|
+
if (block.type === "text") this.emit({ kind: "text", messageId, text: block.text ?? "" });
|
|
21
|
+
if (block.type === "thinking") this.emit({ kind: "thinking", messageId, text: block.thinking ?? "" });
|
|
22
|
+
if (block.type === "tool_use") this.emit({ kind: "tool_call", callId: block.id, name: block.name, input: JSON.stringify(block.input ?? {}) });
|
|
23
|
+
} else if (event.type === "content_block_delta") {
|
|
24
|
+
const block = this.blocks.get(event.index);
|
|
25
|
+
const delta = event.delta;
|
|
26
|
+
if (delta?.type === "text_delta") {
|
|
27
|
+
if (block) {
|
|
28
|
+
block.text += delta.text;
|
|
29
|
+
this.lastText = [...this.blocks.values()].filter((b) => b.type === "text").map((b) => b.text).join("\n\n");
|
|
30
|
+
}
|
|
31
|
+
this.emit({ kind: "text", messageId, text: delta.text, delta: true });
|
|
32
|
+
}
|
|
33
|
+
if (delta?.type === "thinking_delta") this.emit({ kind: "thinking", messageId, text: delta.thinking, delta: true });
|
|
34
|
+
if (delta?.type === "input_json_delta" && block?.id && block.name) {
|
|
35
|
+
block.input = (block.input + delta.partial_json).slice(0, 32e3);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
complete(message) {
|
|
40
|
+
const content = Array.isArray(message?.content) ? message.content : [];
|
|
41
|
+
const texts = [];
|
|
42
|
+
for (const [index, block] of content.entries()) {
|
|
43
|
+
const messageId = message.id ? `${message.id}:${index}` : void 0;
|
|
44
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
45
|
+
texts.push(block.text);
|
|
46
|
+
this.emit({ kind: "text", text: block.text, ...messageId ? { messageId } : {} });
|
|
47
|
+
} else if (block.type === "thinking" && typeof block.thinking === "string") {
|
|
48
|
+
this.emit({ kind: "thinking", text: block.thinking, ...messageId ? { messageId } : {} });
|
|
49
|
+
} else if (block.type === "tool_use") {
|
|
50
|
+
this.emit({ kind: "tool_call", callId: block.id, name: block.name, input: JSON.stringify(block.input ?? {}).slice(0, 32e3) });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (texts.length) this.lastText = texts.join("\n\n");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
ClaudeStream
|
|
58
|
+
};
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { discoverModels } from "./model-discovery.js";
|
|
2
|
+
import { managedPermissionProblem } from "./managed-permissions.js";
|
|
3
|
+
import { prepareAgentTools } from "./agent-tools.js";
|
|
4
|
+
import { AGENT_TOOL_ALLOWLIST } from "../agent-tools.js";
|
|
5
|
+
import { ClaudeStream } from "./claude-stream.js";
|
|
6
|
+
import { classifyError, cliErrorLine, resetFromText } from "./errors.js";
|
|
7
|
+
import { commandExists, describeFailure, processErrorKind, startJsonlProcess, stderrTail, stringify, truncate, unknownEvents } from "./process.js";
|
|
8
|
+
import { adapterTeamCapabilities, prepareTeamTools, TEAM_NESTED_DENYLIST, TEAM_TOOL_ALLOWLIST } from "./team-tools.js";
|
|
9
|
+
const READ_TOOLS = [
|
|
10
|
+
"Read",
|
|
11
|
+
"Grep",
|
|
12
|
+
"Glob",
|
|
13
|
+
"Bash(git diff *)",
|
|
14
|
+
"Bash(git log *)",
|
|
15
|
+
"Bash(git show *)",
|
|
16
|
+
"Bash(git status *)",
|
|
17
|
+
"Bash(ls *)"
|
|
18
|
+
];
|
|
19
|
+
const GIT_READ_DENY = ["Bash(git *--out*)", "Bash(git *--no-index*)"];
|
|
20
|
+
const IGNORED_TYPES = /* @__PURE__ */ new Set(["stream_event", "tool_progress", "tool_use_summary", "auth_status", "keep_alive", "control_request", "control_response", "control_cancel_request"]);
|
|
21
|
+
const IGNORED_BLOCKS = /* @__PURE__ */ new Set(["redacted_thinking"]);
|
|
22
|
+
const DEFAULT_WRITE_TOOLS = [
|
|
23
|
+
...READ_TOOLS,
|
|
24
|
+
"Bash(git add *)",
|
|
25
|
+
"Bash(npm *)",
|
|
26
|
+
"Bash(npx *)",
|
|
27
|
+
"Bash(node *)",
|
|
28
|
+
"Bash(pnpm *)",
|
|
29
|
+
"Bash(yarn *)",
|
|
30
|
+
"Bash(python3 *)",
|
|
31
|
+
"Bash(pytest *)",
|
|
32
|
+
"Bash(uv *)",
|
|
33
|
+
"Bash(poetry *)",
|
|
34
|
+
"Bash(cargo *)",
|
|
35
|
+
"Bash(go *)",
|
|
36
|
+
"Bash(make *)",
|
|
37
|
+
"Bash(mkdir *)"
|
|
38
|
+
];
|
|
39
|
+
function writeTools(trust = "standard") {
|
|
40
|
+
if (trust === "safe") return READ_TOOLS;
|
|
41
|
+
if (trust === "trusted") return [...READ_TOOLS, "Bash"];
|
|
42
|
+
const env = process.env.CODEFLOW_CLAUDE_WRITE_TOOLS;
|
|
43
|
+
return env ? env.split(",").map((t) => t.trim()).filter(Boolean) : DEFAULT_WRITE_TOOLS;
|
|
44
|
+
}
|
|
45
|
+
const claudeAdapter = {
|
|
46
|
+
id: "claude",
|
|
47
|
+
discoverModels: (context) => discoverModels("claude", context),
|
|
48
|
+
displayName: "Claude Code",
|
|
49
|
+
binary: "claude",
|
|
50
|
+
available: () => commandExists("claude"),
|
|
51
|
+
// The CLI has no model-listing command; it accepts these aliases (always the latest
|
|
52
|
+
// model of each family) or any full model name.
|
|
53
|
+
async catalog() {
|
|
54
|
+
return {
|
|
55
|
+
models: [
|
|
56
|
+
{ id: "fable", label: "Fable (latest)" },
|
|
57
|
+
{ id: "opus", label: "Opus (latest)" },
|
|
58
|
+
{ id: "sonnet", label: "Sonnet (latest)" },
|
|
59
|
+
{ id: "haiku", label: "Haiku (latest)" }
|
|
60
|
+
],
|
|
61
|
+
efforts: ["low", "medium", "high", "xhigh", "max"],
|
|
62
|
+
allowCustom: true
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
async run(opts, onEvent) {
|
|
66
|
+
const permissionProblem = await managedPermissionProblem("claude", opts);
|
|
67
|
+
if (permissionProblem) return permissionProblem;
|
|
68
|
+
const supportsTools = !opts.agentContainer && opts.teamTools && (await adapterTeamCapabilities("claude")).scopedTools === "tested";
|
|
69
|
+
const teamTools = supportsTools ? await prepareTeamTools(opts.teamTools) : void 0;
|
|
70
|
+
const agentTools = opts.agentTools && !opts.agentContainer && opts.permissions?.externalTools !== "disabled" ? await prepareAgentTools(opts.agentTools) : void 0;
|
|
71
|
+
if (opts.agentContainer) onEvent({ kind: "status", text: `Claude runs in Docker image ${opts.agentContainer.image}. Live team tools are unavailable in containers; use structured outcomes and next-turn replies.` });
|
|
72
|
+
else if (opts.teamTools && !teamTools) onEvent({ kind: "status", text: "This Claude CLI has no verified per-turn team tools; use structured outcomes and next-turn replies." });
|
|
73
|
+
try {
|
|
74
|
+
const interactive = !!(opts.conversation || opts.interactiveApprovals || opts.onQuestion);
|
|
75
|
+
const args = ["-p", "--output-format", "stream-json", "--verbose", "--include-partial-messages"];
|
|
76
|
+
if (interactive) args.push("--input-format", "stream-json", "--permission-prompt-tool", "stdio");
|
|
77
|
+
if (opts.permissions && !opts.conversation) args.push("--settings", '{"ultracode":false,"disableWorkflows":true,"disableAllHooks":true}');
|
|
78
|
+
if (opts.resumeSessionId) args.push("--resume", opts.resumeSessionId);
|
|
79
|
+
else if (opts.forkSessionId) args.push("--resume", opts.forkSessionId, "--fork-session");
|
|
80
|
+
if (opts.model) args.push("--model", opts.model);
|
|
81
|
+
if (opts.effort) args.push("--effort", opts.effort);
|
|
82
|
+
if (opts.jsonSchema) args.push("--json-schema", JSON.stringify(opts.jsonSchema));
|
|
83
|
+
if (teamTools) args.push("--mcp-config", teamTools.claudeConfig, "--strict-mcp-config");
|
|
84
|
+
else if (opts.permissions?.externalTools === "disabled") args.push("--mcp-config", '{"mcpServers":{}}', "--strict-mcp-config");
|
|
85
|
+
if (agentTools) args.push("--mcp-config", agentTools.claudeConfig);
|
|
86
|
+
if (opts.permissions?.externalTools === "disabled") args.push("--no-chrome");
|
|
87
|
+
const collaborationTools = [...teamTools ? TEAM_TOOL_ALLOWLIST : [], ...agentTools ? AGENT_TOOL_ALLOWLIST : []];
|
|
88
|
+
const full = opts.mode === "write" && opts.trust === "full";
|
|
89
|
+
const allowedTools = full ? [] : [...opts.mode === "write" ? writeTools(opts.trust) : READ_TOOLS, ...collaborationTools];
|
|
90
|
+
const limitedShell = !full && !allowedTools.includes("Bash");
|
|
91
|
+
const deniedTools = [...opts.mode === "read" ? ["Edit", "Write", "NotebookEdit"] : [], ...opts.questionProtocol === "structured" || opts.permissions?.nativeDelegation === false ? TEAM_NESTED_DENYLIST : [], ...opts.permissions?.externalTools === "disabled" ? ["WebSearch", "WebFetch"] : []];
|
|
92
|
+
const denied = [deniedTools.join(","), limitedShell ? GIT_READ_DENY.join(",") : ""].filter(Boolean);
|
|
93
|
+
if (denied.length) args.push("--disallowedTools", ...denied);
|
|
94
|
+
if (full) args.push("--permission-mode", "bypassPermissions");
|
|
95
|
+
else args.push("--permission-mode", opts.mode === "write" ? "acceptEdits" : "default", "--allowedTools", allowedTools.join(","));
|
|
96
|
+
let sessionId;
|
|
97
|
+
let finalText = "";
|
|
98
|
+
let lastAssistantText = "";
|
|
99
|
+
let resultError;
|
|
100
|
+
let sawResult = false;
|
|
101
|
+
let structured;
|
|
102
|
+
let rejected;
|
|
103
|
+
const unknown = unknownEvents("claude");
|
|
104
|
+
const stream = new ClaudeStream(onEvent);
|
|
105
|
+
const controls = /* @__PURE__ */ new Map();
|
|
106
|
+
const cancelControls = () => {
|
|
107
|
+
for (const controller of controls.values()) controller.abort();
|
|
108
|
+
};
|
|
109
|
+
opts.signal?.addEventListener("abort", cancelControls, { once: true });
|
|
110
|
+
const handleControl = async (msg) => {
|
|
111
|
+
const id = msg.request_id;
|
|
112
|
+
if (typeof id !== "string" || controls.has(id)) return;
|
|
113
|
+
const controller = new AbortController();
|
|
114
|
+
controls.set(id, controller);
|
|
115
|
+
const request = msg.request ?? {};
|
|
116
|
+
const isQuestion = request.tool_name === "AskUserQuestion";
|
|
117
|
+
const timer = setTimeout(() => controller.abort(), isQuestion ? 6e5 : 12e4);
|
|
118
|
+
let response = { behavior: "deny", message: "This action was not approved. Ask the user in your response if you need help." };
|
|
119
|
+
proc.pauseIdle(true);
|
|
120
|
+
try {
|
|
121
|
+
if (sawResult || opts.signal?.aborted) return;
|
|
122
|
+
const work = async () => {
|
|
123
|
+
if (request.subtype !== "can_use_tool") return;
|
|
124
|
+
const input = request.input ?? {};
|
|
125
|
+
if (isQuestion && opts.onQuestion && Array.isArray(input.questions)) {
|
|
126
|
+
const questions = input.questions.map((q, index) => ({ id: String(index), question: q.question, options: q.options?.map((o) => o.label) }));
|
|
127
|
+
const answers = await opts.onQuestion(questions, controller.signal);
|
|
128
|
+
if (answers) response = { behavior: "allow", updatedInput: { ...input, answers: Object.fromEntries(questions.map((q) => [q.question, answers[q.id]])) } };
|
|
129
|
+
} else if (opts.interactiveApprovals && opts.onApproval && typeof request.tool_name === "string") {
|
|
130
|
+
if (opts.mode === "read") return;
|
|
131
|
+
const encoded = JSON.stringify(input);
|
|
132
|
+
if (encoded.length > 16e3) return;
|
|
133
|
+
const decision = await opts.onApproval({ id, kind: "tool", toolName: request.tool_name, input: encoded, cwd: opts.cwd }, controller.signal);
|
|
134
|
+
if (decision === "approve") response = { behavior: "allow", updatedInput: input };
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
await Promise.race([work(), new Promise((resolve) => controller.signal.addEventListener("abort", () => resolve(), { once: true }))]);
|
|
138
|
+
if (!sawResult && !opts.signal?.aborted) proc.send({ type: "control_response", response: { subtype: "success", request_id: id, response: controller.signal.aborted ? { behavior: "deny", message: "Request expired or was cancelled" } : response } });
|
|
139
|
+
} catch (error2) {
|
|
140
|
+
if (!sawResult) proc.send({ type: "control_response", response: { subtype: "error", request_id: id, error: String(error2) } });
|
|
141
|
+
} finally {
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
controller.abort();
|
|
144
|
+
controls.delete(id);
|
|
145
|
+
proc.pauseIdle(controls.size > 0);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const proc = startJsonlProcess({
|
|
149
|
+
agentContainer: opts.agentContainer ? { config: opts.agentContainer, mode: opts.mode } : void 0,
|
|
150
|
+
command: "claude",
|
|
151
|
+
args,
|
|
152
|
+
input: interactive ? void 0 : opts.prompt,
|
|
153
|
+
interactive,
|
|
154
|
+
cwd: opts.cwd,
|
|
155
|
+
signal: opts.signal,
|
|
156
|
+
timeoutMs: opts.timeoutMs,
|
|
157
|
+
idleTimeoutMs: opts.idleTimeoutMs,
|
|
158
|
+
isPaused: opts.isPaused,
|
|
159
|
+
onText: (line) => onEvent({ kind: "status", text: line }),
|
|
160
|
+
onJson: (msg) => {
|
|
161
|
+
switch (msg.type) {
|
|
162
|
+
case "stream_event":
|
|
163
|
+
stream.partial(msg.event);
|
|
164
|
+
break;
|
|
165
|
+
case "control_request":
|
|
166
|
+
void handleControl(msg);
|
|
167
|
+
break;
|
|
168
|
+
case "control_cancel_request":
|
|
169
|
+
controls.get(msg.request_id)?.abort();
|
|
170
|
+
break;
|
|
171
|
+
case "system":
|
|
172
|
+
if (msg.subtype === "init" && msg.session_id) {
|
|
173
|
+
sessionId = msg.session_id;
|
|
174
|
+
onEvent({ kind: "session", sessionId: msg.session_id });
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
case "assistant":
|
|
178
|
+
stream.complete(msg.message);
|
|
179
|
+
lastAssistantText = stream.lastText;
|
|
180
|
+
for (const block of msg.message?.content ?? []) {
|
|
181
|
+
if (!["text", "thinking", "tool_use"].includes(block.type) && !IGNORED_BLOCKS.has(block.type)) {
|
|
182
|
+
unknown.add(`${block.type} block`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
case "user":
|
|
187
|
+
for (const block of msg.message?.content ?? []) {
|
|
188
|
+
if (block.type !== "tool_result") continue;
|
|
189
|
+
const output = Array.isArray(block.content) ? block.content.map((c) => c.type === "text" ? c.text : `[${c.type}]`).join("\n") : stringify(block.content ?? "");
|
|
190
|
+
onEvent({
|
|
191
|
+
kind: "tool_result",
|
|
192
|
+
callId: block.tool_use_id,
|
|
193
|
+
output: truncate(output),
|
|
194
|
+
isError: Boolean(block.is_error)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
case "rate_limit_event": {
|
|
199
|
+
const info = msg.rate_limit_info ?? {};
|
|
200
|
+
const windows = {};
|
|
201
|
+
for (const [name, w] of Object.entries(info.unifiedWindows ?? {})) {
|
|
202
|
+
windows[name] = { utilization: w?.utilization, resetsAt: w?.resetsAt ? w.resetsAt * 1e3 : void 0 };
|
|
203
|
+
}
|
|
204
|
+
if (!Object.keys(windows).length && (info.utilization !== void 0 || info.resetsAt)) {
|
|
205
|
+
windows[info.rateLimitType ?? "limit"] = { utilization: info.utilization, resetsAt: info.resetsAt ? info.resetsAt * 1e3 : void 0 };
|
|
206
|
+
}
|
|
207
|
+
onEvent({ kind: "quota", status: info.status ?? "unknown", windows });
|
|
208
|
+
if (info.status && info.status !== "allowed") onEvent({ kind: "status", text: `Claude rate limit: ${info.status}` });
|
|
209
|
+
if (info.status === "rejected") {
|
|
210
|
+
const full2 = Object.values(windows).filter((w) => (w.utilization ?? 0) >= 1 && w.resetsAt).map((w) => w.resetsAt);
|
|
211
|
+
rejected = { resetsAt: info.resetsAt ? info.resetsAt * 1e3 : full2.length ? Math.max(...full2) : void 0 };
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case "result":
|
|
216
|
+
sawResult = true;
|
|
217
|
+
cancelControls();
|
|
218
|
+
if (interactive) proc.endInput();
|
|
219
|
+
proc.resultSeen();
|
|
220
|
+
finalText = typeof msg.result === "string" ? msg.result : lastAssistantText;
|
|
221
|
+
if (msg.session_id) sessionId = msg.session_id;
|
|
222
|
+
if (msg.structured_output !== void 0) structured = msg.structured_output;
|
|
223
|
+
if (msg.is_error || /^error/.test(msg.subtype ?? "")) resultError = resultErrorText(msg);
|
|
224
|
+
onEvent({
|
|
225
|
+
kind: "usage",
|
|
226
|
+
// Writing to the prompt cache is billed as input; reading from it is counted apart.
|
|
227
|
+
inputTokens: (msg.usage?.input_tokens ?? 0) + (msg.usage?.cache_creation_input_tokens ?? 0),
|
|
228
|
+
outputTokens: msg.usage?.output_tokens,
|
|
229
|
+
cacheReadTokens: msg.usage?.cache_read_input_tokens,
|
|
230
|
+
costUsd: msg.total_cost_usd
|
|
231
|
+
});
|
|
232
|
+
if (Array.isArray(msg.permission_denials) && msg.permission_denials.length) {
|
|
233
|
+
const names = msg.permission_denials.map((d) => d.tool_name).join(", ");
|
|
234
|
+
onEvent({ kind: "status", text: `Denied in headless mode: ${names}` });
|
|
235
|
+
}
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
if (!IGNORED_TYPES.has(msg.type)) unknown.add(msg.type);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
if (interactive) {
|
|
243
|
+
proc.send({ type: "control_request", request_id: "codeflow-init", request: { subtype: "initialize", hooks: {} } });
|
|
244
|
+
proc.send({ type: "user", message: { role: "user", content: opts.prompt } });
|
|
245
|
+
}
|
|
246
|
+
const outcome = await proc.outcome;
|
|
247
|
+
cancelControls();
|
|
248
|
+
opts.signal?.removeEventListener("abort", cancelControls);
|
|
249
|
+
const drift = unknown.report();
|
|
250
|
+
if (drift) onEvent({ kind: "status", text: drift });
|
|
251
|
+
if (sawResult && !resultError && !outcome.aborted) return { ok: true, finalText, sessionId, structured };
|
|
252
|
+
const tail = stderrTail(outcome);
|
|
253
|
+
const error = resultError ? `${resultError}${tail && !resultError.includes(tail) ? `
|
|
254
|
+
${tail}` : ""}` : !sawResult && outcome.exitCode === 0 ? `claude exited without a result${tail ? `: ${tail}` : ""}` : describeFailure("claude", outcome);
|
|
255
|
+
const own = resultError ?? cliErrorLine(outcome.stderr);
|
|
256
|
+
let errorKind = processErrorKind(outcome) ?? classifyError(own);
|
|
257
|
+
if (rejected && (errorKind === "other" || errorKind === "rate_limit")) errorKind = "usage_limit";
|
|
258
|
+
const resetsAt = errorKind === "usage_limit" ? rejected?.resetsAt ?? resetFromText(own) : void 0;
|
|
259
|
+
onEvent({ kind: "error", message: error });
|
|
260
|
+
return {
|
|
261
|
+
ok: false,
|
|
262
|
+
finalText: finalText || stream.lastText || lastAssistantText,
|
|
263
|
+
sessionId: errorKind === "session_not_found" ? void 0 : sessionId,
|
|
264
|
+
error,
|
|
265
|
+
errorKind,
|
|
266
|
+
...resetsAt && { resetsAt }
|
|
267
|
+
};
|
|
268
|
+
} finally {
|
|
269
|
+
await teamTools?.cleanup();
|
|
270
|
+
await agentTools?.cleanup();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
function resultErrorText(msg) {
|
|
275
|
+
if (msg.is_error && typeof msg.result === "string" && msg.result.trim()) return msg.result.trim();
|
|
276
|
+
const errors = Array.isArray(msg.errors) ? msg.errors.filter((e) => typeof e === "string" && e).join("; ") : "";
|
|
277
|
+
const what = msg.subtype === "error_max_turns" ? "Claude stopped at its turn limit" : msg.subtype === "error_max_budget_usd" ? "Claude stopped at its budget limit" : msg.subtype === "error_during_execution" ? "Claude stopped with an error during execution" : `Claude reported an error${msg.subtype && msg.subtype !== "success" ? ` (${msg.subtype})` : ""}`;
|
|
278
|
+
return errors ? `${what}: ${errors}` : what;
|
|
279
|
+
}
|
|
280
|
+
export {
|
|
281
|
+
claudeAdapter
|
|
282
|
+
};
|