ocpipe 0.4.3 → 0.5.1

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 CHANGED
@@ -68,6 +68,18 @@ const pipeline = new Pipeline({
68
68
  name: 'my-pipeline',
69
69
  defaultModel: { backend: 'claude-code', providerID: 'anthropic', modelID: 'claude-sonnet-4-20250514' },
70
70
  defaultAgent: 'default',
71
+ // Permission mode controls what Claude Code can do without prompting
72
+ // Options: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan'
73
+ claudeCode: { permissionMode: 'acceptEdits' }, // default: auto-approve file writes
74
+ }, createBaseState)
75
+
76
+ // To bypass all permission prompts (use with caution):
77
+ const pipeline = new Pipeline({
78
+ ...config,
79
+ claudeCode: {
80
+ permissionMode: 'bypassPermissions',
81
+ dangerouslySkipPermissions: true, // required safety flag
82
+ },
71
83
  }, createBaseState)
72
84
  ```
73
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocpipe",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "description": "SDK for LLM pipelines with OpenCode and Zod",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/agent.ts CHANGED
@@ -34,7 +34,7 @@ export async function runAgent(
34
34
  async function runOpencodeAgent(
35
35
  options: RunAgentOptions,
36
36
  ): Promise<RunAgentResult> {
37
- const { prompt, agent, model, sessionId, timeoutSec = 300, workdir } = options
37
+ const { prompt, agent, model, sessionId, timeoutSec = 600, workdir } = options
38
38
 
39
39
  const modelStr = `${model.providerID}/${model.modelID}`
40
40
  const sessionInfo = sessionId ? `[session:${sessionId}]` : '[new session]'
@@ -8,9 +8,19 @@ import {
8
8
  unstable_v2_createSession,
9
9
  unstable_v2_resumeSession,
10
10
  type SDKMessage,
11
+ type SDKSessionOptions,
11
12
  } from '@anthropic-ai/claude-agent-sdk'
12
13
  import type { RunAgentOptions, RunAgentResult } from './types.js'
13
14
 
15
+ /** Normalize model ID to Claude Code format (opus, sonnet, haiku). */
16
+ function normalizeModelId(modelId: string): string {
17
+ const lower = modelId.toLowerCase()
18
+ if (lower.includes('opus')) return 'opus'
19
+ if (lower.includes('sonnet')) return 'sonnet'
20
+ if (lower.includes('haiku')) return 'haiku'
21
+ return modelId
22
+ }
23
+
14
24
  /** Extract text from assistant messages. */
15
25
  function getAssistantText(msg: SDKMessage): string | null {
16
26
  if (msg.type !== 'assistant') return null
@@ -27,22 +37,34 @@ function getAssistantText(msg: SDKMessage): string | null {
27
37
  export async function runClaudeCodeAgent(
28
38
  options: RunAgentOptions,
29
39
  ): Promise<RunAgentResult> {
30
- const { prompt, model, sessionId, timeoutSec = 300 } = options
40
+ const { prompt, model, sessionId, timeoutSec = 600, claudeCode } = options
31
41
 
32
- // Claude Agent SDK only uses modelID, not providerID
33
- const modelStr = model.modelID
42
+ // Claude Code understands simple names: opus, sonnet, haiku
43
+ const modelStr = normalizeModelId(model.modelID)
34
44
  const sessionInfo = sessionId ? `[session:${sessionId}]` : '[new session]'
35
45
  const promptPreview = prompt.slice(0, 50).replace(/\n/g, ' ')
36
46
 
47
+ // Build session options with configurable permission mode (default: acceptEdits)
48
+ const permissionMode = claudeCode?.permissionMode ?? 'acceptEdits'
49
+ const sessionOptions: SDKSessionOptions = {
50
+ model: modelStr,
51
+ permissionMode,
52
+ // bypassPermissions requires explicit opt-in
53
+ ...(permissionMode === 'bypassPermissions' &&
54
+ claudeCode?.dangerouslySkipPermissions && {
55
+ allowDangerouslySkipPermissions: true,
56
+ }),
57
+ }
58
+
37
59
  console.error(
38
- `\n>>> Claude Code [${modelStr}] ${sessionInfo}: ${promptPreview}...`,
60
+ `\n>>> Claude Code [${modelStr}] [${permissionMode}] ${sessionInfo}: ${promptPreview}...`,
39
61
  )
40
62
 
41
63
  // Create or resume session
42
64
  const session =
43
65
  sessionId ?
44
- unstable_v2_resumeSession(sessionId, { model: modelStr })
45
- : unstable_v2_createSession({ model: modelStr })
66
+ unstable_v2_resumeSession(sessionId, sessionOptions)
67
+ : unstable_v2_createSession(sessionOptions)
46
68
 
47
69
  try {
48
70
  // Send the prompt
package/src/index.ts CHANGED
@@ -88,6 +88,8 @@ export type { MockResponse } from './testing.js'
88
88
  export type {
89
89
  // Core types
90
90
  BackendType,
91
+ PermissionMode,
92
+ ClaudeCodeOptions,
91
93
  ModelConfig,
92
94
  ExecutionContext,
93
95
  StepResult,
package/src/pipeline.ts CHANGED
@@ -31,8 +31,9 @@ export class Pipeline<S extends BaseState> {
31
31
  sessionId: undefined,
32
32
  defaultModel: config.defaultModel,
33
33
  defaultAgent: config.defaultAgent,
34
- timeoutSec: config.timeoutSec ?? 300,
34
+ timeoutSec: config.timeoutSec ?? 600,
35
35
  workdir: config.workdir,
36
+ claudeCode: config.claudeCode,
36
37
  }
37
38
  }
38
39
 
package/src/predict.ts CHANGED
@@ -76,6 +76,7 @@ export class Predict<S extends AnySignature> {
76
76
  sessionId: this.config.newSession ? undefined : ctx.sessionId,
77
77
  timeoutSec: ctx.timeoutSec,
78
78
  workdir: ctx.workdir,
79
+ claudeCode: ctx.claudeCode,
79
80
  })
80
81
 
81
82
  // Update context with new session ID for continuity
@@ -204,6 +205,7 @@ export class Predict<S extends AnySignature> {
204
205
  agent: ctx.defaultAgent,
205
206
  timeoutSec: 60,
206
207
  workdir: ctx.workdir,
208
+ claudeCode: ctx.claudeCode,
207
209
  })
208
210
 
209
211
  // Try to parse the repaired JSON
@@ -279,6 +281,7 @@ export class Predict<S extends AnySignature> {
279
281
  agent: ctx.defaultAgent,
280
282
  timeoutSec: 60, // Short timeout for simple patches
281
283
  workdir: ctx.workdir,
284
+ claudeCode: ctx.claudeCode,
282
285
  })
283
286
 
284
287
  // Extract and apply the patch based on method
package/src/types.ts CHANGED
@@ -11,6 +11,21 @@ import type { z } from 'zod/v4'
11
11
  /** Backend type for running agents. */
12
12
  export type BackendType = 'opencode' | 'claude-code'
13
13
 
14
+ /** Permission mode for Claude Code sessions. */
15
+ export type PermissionMode =
16
+ | 'default'
17
+ | 'acceptEdits'
18
+ | 'bypassPermissions'
19
+ | 'plan'
20
+
21
+ /** Claude Code specific session options. */
22
+ export interface ClaudeCodeOptions {
23
+ /** Permission mode (default: 'acceptEdits'). */
24
+ permissionMode?: PermissionMode
25
+ /** Required when using 'bypassPermissions' mode. */
26
+ dangerouslySkipPermissions?: boolean
27
+ }
28
+
14
29
  /** Model configuration for LLM backends. */
15
30
  export interface ModelConfig {
16
31
  /** Backend to use (default: 'opencode'). */
@@ -35,6 +50,8 @@ export interface ExecutionContext {
35
50
  timeoutSec: number
36
51
  /** Working directory for opencode (where .opencode/agents/ lives). */
37
52
  workdir?: string
53
+ /** Claude Code specific options. */
54
+ claudeCode?: ClaudeCodeOptions
38
55
  }
39
56
 
40
57
  // ============================================================================
@@ -249,6 +266,8 @@ export interface PipelineConfig {
249
266
  timeoutSec?: number
250
267
  /** Working directory for opencode (where .opencode/agents/ lives). */
251
268
  workdir?: string
269
+ /** Claude Code specific options. */
270
+ claudeCode?: ClaudeCodeOptions
252
271
  }
253
272
 
254
273
  /** Options for running a pipeline step. */
@@ -281,6 +300,8 @@ export interface RunAgentOptions {
281
300
  timeoutSec?: number
282
301
  /** Working directory for opencode (where .opencode/agents/ lives). */
283
302
  workdir?: string
303
+ /** Claude Code specific options. */
304
+ claudeCode?: ClaudeCodeOptions
284
305
  }
285
306
 
286
307
  /** Result from running an OpenCode agent. */