@posthog/agent 2.1.70 → 2.1.82
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/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +22 -2
- package/dist/adapters/claude/permissions/permission-options.d.ts +3 -1
- package/dist/adapters/claude/permissions/permission-options.js +5 -2
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/questions/utils.d.ts +1 -0
- package/dist/agent.d.ts +30 -5
- package/dist/agent.js +10 -8
- package/dist/agent.js.map +1 -1
- package/dist/gateway-models.d.ts +1 -2
- package/dist/gateway-models.js +0 -5
- package/dist/gateway-models.js.map +1 -1
- package/dist/index.d.ts +1 -257
- package/dist/index.js +1 -10531
- package/dist/index.js.map +1 -1
- package/dist/server/agent-server.js +10 -8
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +10 -8
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -4
- package/src/acp-extensions.ts +0 -98
- package/src/adapters/acp-connection.ts +1 -1
- package/src/adapters/claude/permissions/permission-handlers.ts +1 -0
- package/src/adapters/claude/permissions/permission-options.ts +10 -1
- package/src/adapters/claude/session/options.ts +1 -0
- package/src/gateway-models.ts +0 -7
- package/src/index.ts +1 -79
- package/src/test/mocks/msw-handlers.ts +0 -3
- package/dist/agent-DK1apkaG.d.ts +0 -133
- package/dist/logger-DDBiMOOD.d.ts +0 -24
- package/src/adapters/claude/tool-meta.ts +0 -143
- package/src/test/assertions.ts +0 -114
- package/src/test/controllers/sse-controller.ts +0 -107
- package/src/test/fixtures/notifications.ts +0 -92
- package/src/test/setup.ts +0 -114
- package/src/test/wait.ts +0 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/agent",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.82",
|
|
4
4
|
"repository": "https://github.com/PostHog/twig",
|
|
5
5
|
"description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
6
6
|
"exports": {
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"node": ">=20.0.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@changesets/cli": "^2.27.8",
|
|
67
66
|
"@types/bun": "latest",
|
|
68
67
|
"@types/tar": "^6.1.13",
|
|
69
68
|
"minimatch": "^10.0.3",
|
|
@@ -88,8 +87,6 @@
|
|
|
88
87
|
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
89
88
|
"@types/jsonwebtoken": "^9.0.10",
|
|
90
89
|
"commander": "^14.0.2",
|
|
91
|
-
"diff": "^8.0.2",
|
|
92
|
-
"dotenv": "^17.2.3",
|
|
93
90
|
"hono": "^4.11.7",
|
|
94
91
|
"jsonwebtoken": "^9.0.2",
|
|
95
92
|
"tar": "^7.5.0",
|
package/src/acp-extensions.ts
CHANGED
|
@@ -62,101 +62,3 @@ export const POSTHOG_NOTIFICATIONS = {
|
|
|
62
62
|
/** Marks a boundary for log compaction */
|
|
63
63
|
COMPACT_BOUNDARY: "_posthog/compact_boundary",
|
|
64
64
|
} as const;
|
|
65
|
-
|
|
66
|
-
export type PostHogNotificationType =
|
|
67
|
-
(typeof POSTHOG_NOTIFICATIONS)[keyof typeof POSTHOG_NOTIFICATIONS];
|
|
68
|
-
|
|
69
|
-
// --- Payload types for each notification ---
|
|
70
|
-
|
|
71
|
-
export interface BranchCreatedPayload {
|
|
72
|
-
branch: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface RunStartedPayload {
|
|
76
|
-
sessionId: string;
|
|
77
|
-
runId: string;
|
|
78
|
-
taskId?: string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface TaskCompletePayload {
|
|
82
|
-
sessionId: string;
|
|
83
|
-
taskId: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface ErrorNotificationPayload {
|
|
87
|
-
sessionId: string;
|
|
88
|
-
message: string;
|
|
89
|
-
error?: unknown;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export interface ConsoleNotificationPayload {
|
|
93
|
-
sessionId: string;
|
|
94
|
-
level: "debug" | "info" | "warn" | "error";
|
|
95
|
-
message: string;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface SdkSessionPayload {
|
|
99
|
-
taskRunId: string;
|
|
100
|
-
sessionId: string;
|
|
101
|
-
adapter: "claude" | "codex";
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface TreeSnapshotPayload {
|
|
105
|
-
treeHash: string;
|
|
106
|
-
baseCommit: string | null;
|
|
107
|
-
archiveUrl?: string;
|
|
108
|
-
changes: Array<{ path: string; status: "A" | "M" | "D" }>;
|
|
109
|
-
timestamp: string;
|
|
110
|
-
interrupted?: boolean;
|
|
111
|
-
device?: {
|
|
112
|
-
type: "local" | "cloud";
|
|
113
|
-
name?: string;
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface ModeChangePayload {
|
|
118
|
-
mode: "interactive" | "background";
|
|
119
|
-
previous_mode: "interactive" | "background";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export interface SessionResumePayload {
|
|
123
|
-
sessionId: string;
|
|
124
|
-
fromSnapshot?: string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface UserMessagePayload {
|
|
128
|
-
content: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export interface StatusPayload {
|
|
132
|
-
sessionId: string;
|
|
133
|
-
status: string;
|
|
134
|
-
message?: string;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export interface TaskNotificationPayload {
|
|
138
|
-
sessionId: string;
|
|
139
|
-
type: string;
|
|
140
|
-
message?: string;
|
|
141
|
-
data?: Record<string, unknown>;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export interface CompactBoundaryPayload {
|
|
145
|
-
sessionId: string;
|
|
146
|
-
timestamp: string;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export type PostHogNotificationPayload =
|
|
150
|
-
| BranchCreatedPayload
|
|
151
|
-
| RunStartedPayload
|
|
152
|
-
| TaskCompletePayload
|
|
153
|
-
| ErrorNotificationPayload
|
|
154
|
-
| ConsoleNotificationPayload
|
|
155
|
-
| SdkSessionPayload
|
|
156
|
-
| TreeSnapshotPayload
|
|
157
|
-
| ModeChangePayload
|
|
158
|
-
| SessionResumePayload
|
|
159
|
-
| UserMessagePayload
|
|
160
|
-
| StatusPayload
|
|
161
|
-
| TaskNotificationPayload
|
|
162
|
-
| CompactBoundaryPayload;
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { ClaudeAcpAgent } from "./claude/claude-agent.js";
|
|
14
14
|
import { type CodexProcessOptions, spawnCodexProcess } from "./codex/spawn.js";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
type AgentAdapter = "claude" | "codex";
|
|
17
17
|
|
|
18
18
|
export type AcpConnectionConfig = {
|
|
19
19
|
adapter?: AgentAdapter;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PermissionUpdate } from "@anthropic-ai/claude-agent-sdk";
|
|
1
2
|
import { BASH_TOOLS, READ_TOOLS, SEARCH_TOOLS, WRITE_TOOLS } from "../tools.js";
|
|
2
3
|
|
|
3
4
|
export interface PermissionOption {
|
|
@@ -24,13 +25,21 @@ export function buildPermissionOptions(
|
|
|
24
25
|
toolName: string,
|
|
25
26
|
toolInput: Record<string, unknown>,
|
|
26
27
|
cwd?: string,
|
|
28
|
+
suggestions?: PermissionUpdate[],
|
|
27
29
|
): PermissionOption[] {
|
|
28
30
|
if (BASH_TOOLS.has(toolName)) {
|
|
31
|
+
const rawRuleContent = suggestions
|
|
32
|
+
?.flatMap((s) => ("rules" in s ? s.rules : []))
|
|
33
|
+
.find((r) => r.toolName === "Bash" && r.ruleContent)?.ruleContent;
|
|
34
|
+
const ruleContent = rawRuleContent?.replace(/:?\*$/, "");
|
|
35
|
+
|
|
29
36
|
const command = toolInput?.command as string | undefined;
|
|
30
37
|
const cmdName = command?.split(/\s+/)[0] ?? "this command";
|
|
31
38
|
const cwdLabel = cwd ? ` in ${cwd}` : "";
|
|
39
|
+
const label = ruleContent ?? `\`${cmdName}\` commands`;
|
|
40
|
+
|
|
32
41
|
return permissionOptions(
|
|
33
|
-
`Yes, and don't ask again for
|
|
42
|
+
`Yes, and don't ask again for ${label}${cwdLabel}`,
|
|
34
43
|
);
|
|
35
44
|
}
|
|
36
45
|
|
package/src/gateway-models.ts
CHANGED
|
@@ -79,13 +79,6 @@ export function isAnthropicModel(model: GatewayModel): boolean {
|
|
|
79
79
|
return model.id.startsWith("claude-") || model.id.startsWith("anthropic/");
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
export async function fetchArrayModelIds(
|
|
83
|
-
options?: FetchGatewayModelsOptions,
|
|
84
|
-
): Promise<string[]> {
|
|
85
|
-
const models = await fetchArrayModels(options);
|
|
86
|
-
return models.map((model) => model.id);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
82
|
export interface ArrayModelInfo {
|
|
90
83
|
id: string;
|
|
91
84
|
owned_by?: string;
|
package/src/index.ts
CHANGED
|
@@ -1,79 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
BranchCreatedPayload,
|
|
3
|
-
CompactBoundaryPayload,
|
|
4
|
-
ConsoleNotificationPayload,
|
|
5
|
-
ErrorNotificationPayload,
|
|
6
|
-
ModeChangePayload,
|
|
7
|
-
PostHogNotificationPayload,
|
|
8
|
-
PostHogNotificationType,
|
|
9
|
-
RunStartedPayload,
|
|
10
|
-
SdkSessionPayload,
|
|
11
|
-
SessionResumePayload,
|
|
12
|
-
StatusPayload,
|
|
13
|
-
TaskCompletePayload,
|
|
14
|
-
TaskNotificationPayload,
|
|
15
|
-
TreeSnapshotPayload,
|
|
16
|
-
UserMessagePayload,
|
|
17
|
-
} from "./acp-extensions.js";
|
|
18
|
-
export { POSTHOG_NOTIFICATIONS } from "./acp-extensions.js";
|
|
19
|
-
export type {
|
|
20
|
-
AcpConnection,
|
|
21
|
-
AcpConnectionConfig,
|
|
22
|
-
AgentAdapter,
|
|
23
|
-
InProcessAcpConnection,
|
|
24
|
-
} from "./adapters/acp-connection.js";
|
|
25
|
-
export { createAcpConnection } from "./adapters/acp-connection.js";
|
|
26
|
-
export {
|
|
27
|
-
fetchMcpToolMetadata,
|
|
28
|
-
isMcpToolReadOnly,
|
|
29
|
-
} from "./adapters/claude/mcp/tool-metadata.js";
|
|
30
|
-
export type { CodexProcessOptions } from "./adapters/codex/spawn.js";
|
|
31
|
-
export { Agent } from "./agent.js";
|
|
32
|
-
export {
|
|
33
|
-
type ArrayModelInfo,
|
|
34
|
-
BLOCKED_MODELS,
|
|
35
|
-
DEFAULT_GATEWAY_MODEL,
|
|
36
|
-
type FetchGatewayModelsOptions,
|
|
37
|
-
fetchArrayModels,
|
|
38
|
-
fetchGatewayModels,
|
|
39
|
-
formatGatewayModelName,
|
|
40
|
-
type GatewayModel,
|
|
41
|
-
getProviderName,
|
|
42
|
-
isAnthropicModel,
|
|
43
|
-
} from "./gateway-models.js";
|
|
44
|
-
export type { OtelLogConfig, SessionContext } from "./otel-log-writer.js";
|
|
45
|
-
export { OtelLogWriter } from "./otel-log-writer.js";
|
|
46
|
-
export { PostHogAPIClient } from "./posthog-api.js";
|
|
47
|
-
export type {
|
|
48
|
-
ConversationTurn,
|
|
49
|
-
ResumeConfig,
|
|
50
|
-
ResumeState,
|
|
51
|
-
ToolCallInfo,
|
|
52
|
-
} from "./resume.js";
|
|
53
|
-
export { conversationToPromptHistory, resumeFromLog } from "./resume.js";
|
|
54
|
-
export type { SessionLogWriterOptions } from "./session-log-writer.js";
|
|
55
|
-
export { SessionLogWriter } from "./session-log-writer.js";
|
|
56
|
-
export type { TreeSnapshot, TreeTrackerConfig } from "./tree-tracker.js";
|
|
57
|
-
export {
|
|
58
|
-
isCommitOnRemote,
|
|
59
|
-
TreeTracker,
|
|
60
|
-
validateForCloudHandoff,
|
|
61
|
-
} from "./tree-tracker.js";
|
|
62
|
-
export type {
|
|
63
|
-
AgentConfig,
|
|
64
|
-
AgentMode,
|
|
65
|
-
DeviceInfo,
|
|
66
|
-
FileChange,
|
|
67
|
-
FileStatus,
|
|
68
|
-
LogLevel,
|
|
69
|
-
OnLogCallback,
|
|
70
|
-
OtelTransportConfig,
|
|
71
|
-
StoredEntry,
|
|
72
|
-
StoredNotification,
|
|
73
|
-
Task,
|
|
74
|
-
TaskRun,
|
|
75
|
-
TreeSnapshotEvent,
|
|
76
|
-
} from "./types.js";
|
|
77
|
-
export { getLlmGatewayUrl } from "./utils/gateway.js";
|
|
78
|
-
export type { LoggerConfig } from "./utils/logger.js";
|
|
79
|
-
export { Logger } from "./utils/logger.js";
|
|
1
|
+
export { isMcpToolReadOnly } from "./adapters/claude/mcp/tool-metadata.js";
|
package/dist/agent-DK1apkaG.d.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { AgentSideConnection } from '@agentclientprotocol/sdk';
|
|
2
|
-
import { StoredNotification, ProcessSpawnedCallback, AgentConfig, TaskExecutionOptions } from './types.js';
|
|
3
|
-
import { L as Logger } from './logger-DDBiMOOD.js';
|
|
4
|
-
import { PostHogAPIClient } from './posthog-api.js';
|
|
5
|
-
|
|
6
|
-
interface OtelLogConfig {
|
|
7
|
-
/** PostHog ingest host, e.g., "https://us.i.posthog.com" */
|
|
8
|
-
posthogHost: string;
|
|
9
|
-
/** Project API key, e.g., "phc_xxx" */
|
|
10
|
-
apiKey: string;
|
|
11
|
-
/** Batch flush interval in ms (default: 500) */
|
|
12
|
-
flushIntervalMs?: number;
|
|
13
|
-
/** Override the logs endpoint path (default: /i/v1/agent-logs) */
|
|
14
|
-
logsPath?: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Session context for resource attributes.
|
|
18
|
-
* These are set once per OTEL logger instance and indexed via resource_fingerprint
|
|
19
|
-
*/
|
|
20
|
-
interface SessionContext {
|
|
21
|
-
/** Parent task grouping - all runs for a task share this */
|
|
22
|
-
taskId: string;
|
|
23
|
-
/** Primary conversation identifier - all events in a run share this */
|
|
24
|
-
runId: string;
|
|
25
|
-
/** Deployment environment - "local" for desktop, "cloud" for cloud sandbox */
|
|
26
|
-
deviceType?: "local" | "cloud";
|
|
27
|
-
}
|
|
28
|
-
declare class OtelLogWriter {
|
|
29
|
-
private loggerProvider;
|
|
30
|
-
private logger;
|
|
31
|
-
constructor(config: OtelLogConfig, sessionContext: SessionContext, _debugLogger?: Logger);
|
|
32
|
-
/**
|
|
33
|
-
* Emit an agent event to PostHog Logs via OTEL.
|
|
34
|
-
*/
|
|
35
|
-
emit(entry: {
|
|
36
|
-
notification: StoredNotification;
|
|
37
|
-
}): void;
|
|
38
|
-
flush(): Promise<void>;
|
|
39
|
-
shutdown(): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface SessionLogWriterOptions {
|
|
43
|
-
/** PostHog API client for log persistence */
|
|
44
|
-
posthogAPI?: PostHogAPIClient;
|
|
45
|
-
/** Logger instance */
|
|
46
|
-
logger?: Logger;
|
|
47
|
-
/** Local cache path for instant log loading (e.g., ~/.twig) */
|
|
48
|
-
localCachePath?: string;
|
|
49
|
-
}
|
|
50
|
-
declare class SessionLogWriter {
|
|
51
|
-
private static readonly FLUSH_DEBOUNCE_MS;
|
|
52
|
-
private static readonly FLUSH_MAX_INTERVAL_MS;
|
|
53
|
-
private static readonly MAX_FLUSH_RETRIES;
|
|
54
|
-
private static readonly MAX_RETRY_DELAY_MS;
|
|
55
|
-
private posthogAPI?;
|
|
56
|
-
private pendingEntries;
|
|
57
|
-
private flushTimeouts;
|
|
58
|
-
private lastFlushAttemptTime;
|
|
59
|
-
private retryCounts;
|
|
60
|
-
private sessions;
|
|
61
|
-
private messageCounts;
|
|
62
|
-
private logger;
|
|
63
|
-
private localCachePath?;
|
|
64
|
-
constructor(options?: SessionLogWriterOptions);
|
|
65
|
-
flushAll(): Promise<void>;
|
|
66
|
-
register(sessionId: string, context: SessionContext): void;
|
|
67
|
-
isRegistered(sessionId: string): boolean;
|
|
68
|
-
appendRawLine(sessionId: string, line: string): void;
|
|
69
|
-
flush(sessionId: string): Promise<void>;
|
|
70
|
-
private isAgentMessageChunk;
|
|
71
|
-
private extractChunkText;
|
|
72
|
-
private emitCoalescedMessage;
|
|
73
|
-
private scheduleFlush;
|
|
74
|
-
private writeToLocalCache;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
type StreamPair = {
|
|
78
|
-
readable: globalThis.ReadableStream<Uint8Array>;
|
|
79
|
-
writable: globalThis.WritableStream<Uint8Array>;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
interface CodexProcessOptions {
|
|
83
|
-
cwd?: string;
|
|
84
|
-
apiBaseUrl?: string;
|
|
85
|
-
apiKey?: string;
|
|
86
|
-
model?: string;
|
|
87
|
-
binaryPath?: string;
|
|
88
|
-
logger?: Logger;
|
|
89
|
-
processCallbacks?: ProcessSpawnedCallback;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
type AgentAdapter = "claude" | "codex";
|
|
93
|
-
type AcpConnectionConfig = {
|
|
94
|
-
adapter?: AgentAdapter;
|
|
95
|
-
logWriter?: SessionLogWriter;
|
|
96
|
-
taskRunId?: string;
|
|
97
|
-
taskId?: string;
|
|
98
|
-
/** Deployment environment - "local" for desktop, "cloud" for cloud sandbox */
|
|
99
|
-
deviceType?: "local" | "cloud";
|
|
100
|
-
logger?: Logger;
|
|
101
|
-
processCallbacks?: ProcessSpawnedCallback;
|
|
102
|
-
codexOptions?: CodexProcessOptions;
|
|
103
|
-
allowedModelIds?: Set<string>;
|
|
104
|
-
};
|
|
105
|
-
type AcpConnection = {
|
|
106
|
-
agentConnection?: AgentSideConnection;
|
|
107
|
-
clientStreams: StreamPair;
|
|
108
|
-
cleanup: () => Promise<void>;
|
|
109
|
-
};
|
|
110
|
-
type InProcessAcpConnection = AcpConnection;
|
|
111
|
-
/**
|
|
112
|
-
* Creates an ACP connection with the specified agent framework.
|
|
113
|
-
*
|
|
114
|
-
* @param config - Configuration including framework selection
|
|
115
|
-
* @returns Connection with agent and client streams
|
|
116
|
-
*/
|
|
117
|
-
declare function createAcpConnection(config?: AcpConnectionConfig): AcpConnection;
|
|
118
|
-
|
|
119
|
-
declare class Agent {
|
|
120
|
-
private posthogAPI?;
|
|
121
|
-
private logger;
|
|
122
|
-
private acpConnection?;
|
|
123
|
-
private taskRunId?;
|
|
124
|
-
private sessionLogWriter?;
|
|
125
|
-
constructor(config: AgentConfig);
|
|
126
|
-
private _configureLlmGateway;
|
|
127
|
-
run(taskId: string, taskRunId: string, options?: TaskExecutionOptions): Promise<InProcessAcpConnection>;
|
|
128
|
-
attachPullRequestToTask(taskId: string, prUrl: string, branchName?: string): Promise<void>;
|
|
129
|
-
flushAllLogs(): Promise<void>;
|
|
130
|
-
cleanup(): Promise<void>;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export { type AcpConnection as A, type CodexProcessOptions as C, type InProcessAcpConnection as I, type OtelLogConfig as O, type SessionContext as S, type AcpConnectionConfig as a, Agent as b, type AgentAdapter as c, OtelLogWriter as d, SessionLogWriter as e, type SessionLogWriterOptions as f, createAcpConnection as g };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { OnLogCallback } from './types.js';
|
|
2
|
-
|
|
3
|
-
interface LoggerConfig {
|
|
4
|
-
debug?: boolean;
|
|
5
|
-
prefix?: string;
|
|
6
|
-
scope?: string;
|
|
7
|
-
onLog?: OnLogCallback;
|
|
8
|
-
}
|
|
9
|
-
declare class Logger {
|
|
10
|
-
private debugEnabled;
|
|
11
|
-
private prefix;
|
|
12
|
-
private scope;
|
|
13
|
-
private onLog?;
|
|
14
|
-
constructor(config?: LoggerConfig);
|
|
15
|
-
private formatMessage;
|
|
16
|
-
private emitLog;
|
|
17
|
-
error(message: string, error?: Error | unknown): void;
|
|
18
|
-
warn(message: string, data?: unknown): void;
|
|
19
|
-
info(message: string, data?: unknown): void;
|
|
20
|
-
debug(message: string, data?: unknown): void;
|
|
21
|
-
child(childPrefix: string): Logger;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { Logger as L, type LoggerConfig as a };
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
const QuestionOptionSchema = z.object({
|
|
4
|
-
label: z.string(),
|
|
5
|
-
description: z.string().optional(),
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
const QuestionItemSchema = z.object({
|
|
9
|
-
question: z.string(),
|
|
10
|
-
header: z.string().optional(),
|
|
11
|
-
options: z.array(QuestionOptionSchema),
|
|
12
|
-
multiSelect: z.boolean().optional(),
|
|
13
|
-
completed: z.boolean().optional(),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export const QuestionMetaSchema = z.object({
|
|
17
|
-
questions: z.array(QuestionItemSchema),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export type QuestionOption = z.infer<typeof QuestionOptionSchema>;
|
|
21
|
-
export type QuestionItem = z.infer<typeof QuestionItemSchema>;
|
|
22
|
-
export type QuestionMeta = z.infer<typeof QuestionMetaSchema>;
|
|
23
|
-
|
|
24
|
-
const toolSchemas = {
|
|
25
|
-
bash: z.object({
|
|
26
|
-
command: z.string(),
|
|
27
|
-
description: z.string().optional(),
|
|
28
|
-
}),
|
|
29
|
-
edit: z.object({
|
|
30
|
-
file_path: z.string(),
|
|
31
|
-
old_string: z.string(),
|
|
32
|
-
new_string: z.string(),
|
|
33
|
-
replace_all: z.boolean().optional(),
|
|
34
|
-
}),
|
|
35
|
-
write: z.object({
|
|
36
|
-
file_path: z.string(),
|
|
37
|
-
content: z.string(),
|
|
38
|
-
}),
|
|
39
|
-
read: z.object({
|
|
40
|
-
file_path: z.string(),
|
|
41
|
-
offset: z.number().optional(),
|
|
42
|
-
limit: z.number().optional(),
|
|
43
|
-
}),
|
|
44
|
-
switch_mode: z.object({
|
|
45
|
-
plan: z.string().optional(),
|
|
46
|
-
}),
|
|
47
|
-
} as const;
|
|
48
|
-
|
|
49
|
-
type ToolKind = keyof typeof toolSchemas;
|
|
50
|
-
const _toolKinds = Object.keys(toolSchemas) as ToolKind[];
|
|
51
|
-
|
|
52
|
-
const sdkToolNameToKind: Record<string, ToolKind> = {
|
|
53
|
-
Bash: "bash",
|
|
54
|
-
Edit: "edit",
|
|
55
|
-
Write: "write",
|
|
56
|
-
Read: "read",
|
|
57
|
-
ExitPlanMode: "switch_mode",
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const BaseTwigToolMetaSchema = z.object({
|
|
61
|
-
claudeCode: z
|
|
62
|
-
.object({
|
|
63
|
-
toolName: z.string(),
|
|
64
|
-
toolResponse: z.unknown().optional(),
|
|
65
|
-
})
|
|
66
|
-
.optional(),
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
type BaseMeta = z.infer<typeof BaseTwigToolMetaSchema>;
|
|
70
|
-
|
|
71
|
-
type ToolMeta<K extends ToolKind> = BaseMeta & {
|
|
72
|
-
twigToolKind: K;
|
|
73
|
-
} & { [P in K]: z.infer<(typeof toolSchemas)[K]> };
|
|
74
|
-
|
|
75
|
-
export type BashToolMeta = ToolMeta<"bash">;
|
|
76
|
-
export type EditToolMeta = ToolMeta<"edit">;
|
|
77
|
-
export type WriteToolMeta = ToolMeta<"write">;
|
|
78
|
-
export type ReadToolMeta = ToolMeta<"read">;
|
|
79
|
-
export type SwitchModeToolMeta = ToolMeta<"switch_mode">;
|
|
80
|
-
export type QuestionToolMeta = BaseMeta & {
|
|
81
|
-
twigToolKind: "question";
|
|
82
|
-
questions: QuestionItem[];
|
|
83
|
-
};
|
|
84
|
-
export type GenericToolMeta = BaseMeta & { twigToolKind?: undefined };
|
|
85
|
-
|
|
86
|
-
export type TwigToolMeta =
|
|
87
|
-
| BashToolMeta
|
|
88
|
-
| EditToolMeta
|
|
89
|
-
| WriteToolMeta
|
|
90
|
-
| ReadToolMeta
|
|
91
|
-
| SwitchModeToolMeta
|
|
92
|
-
| QuestionToolMeta
|
|
93
|
-
| GenericToolMeta;
|
|
94
|
-
|
|
95
|
-
export function isBashToolMeta(meta: TwigToolMeta): meta is BashToolMeta {
|
|
96
|
-
return meta.twigToolKind === "bash";
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function isEditToolMeta(meta: TwigToolMeta): meta is EditToolMeta {
|
|
100
|
-
return meta.twigToolKind === "edit";
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function isWriteToolMeta(meta: TwigToolMeta): meta is WriteToolMeta {
|
|
104
|
-
return meta.twigToolKind === "write";
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function isReadToolMeta(meta: TwigToolMeta): meta is ReadToolMeta {
|
|
108
|
-
return meta.twigToolKind === "read";
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function isSwitchModeToolMeta(
|
|
112
|
-
meta: TwigToolMeta,
|
|
113
|
-
): meta is SwitchModeToolMeta {
|
|
114
|
-
return meta.twigToolKind === "switch_mode";
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function isQuestionToolMeta(
|
|
118
|
-
meta: TwigToolMeta,
|
|
119
|
-
): meta is QuestionToolMeta {
|
|
120
|
-
return meta.twigToolKind === "question";
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export function buildToolMeta(
|
|
124
|
-
toolName: string,
|
|
125
|
-
input: Record<string, unknown>,
|
|
126
|
-
): TwigToolMeta {
|
|
127
|
-
const kind = sdkToolNameToKind[toolName];
|
|
128
|
-
if (!kind) {
|
|
129
|
-
return { claudeCode: { toolName } };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const schema = toolSchemas[kind];
|
|
133
|
-
const result = schema.safeParse(input);
|
|
134
|
-
if (!result.success) {
|
|
135
|
-
return { claudeCode: { toolName } };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
claudeCode: { toolName },
|
|
140
|
-
twigToolKind: kind,
|
|
141
|
-
[kind]: result.data,
|
|
142
|
-
} as TwigToolMeta;
|
|
143
|
-
}
|
package/src/test/assertions.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { expect } from "vitest";
|
|
2
|
-
|
|
3
|
-
export interface NotificationEntry {
|
|
4
|
-
notification?: {
|
|
5
|
-
method?: string;
|
|
6
|
-
params?: {
|
|
7
|
-
sessionId?: string;
|
|
8
|
-
update?: {
|
|
9
|
-
sessionUpdate?: string;
|
|
10
|
-
content?: {
|
|
11
|
-
type?: string;
|
|
12
|
-
text?: string;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface NotificationMatcher {
|
|
20
|
-
method?: string;
|
|
21
|
-
text?: string;
|
|
22
|
-
sessionId?: string;
|
|
23
|
-
sessionUpdate?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function entryMatchesNotification(
|
|
27
|
-
entry: unknown,
|
|
28
|
-
matcher: NotificationMatcher,
|
|
29
|
-
): boolean {
|
|
30
|
-
const notification = (entry as NotificationEntry).notification;
|
|
31
|
-
if (!notification) return false;
|
|
32
|
-
|
|
33
|
-
if (matcher.method && notification.method !== matcher.method) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
if (
|
|
37
|
-
matcher.sessionId &&
|
|
38
|
-
notification.params?.sessionId !== matcher.sessionId
|
|
39
|
-
) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
if (
|
|
43
|
-
matcher.sessionUpdate &&
|
|
44
|
-
notification.params?.update?.sessionUpdate !== matcher.sessionUpdate
|
|
45
|
-
) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
if (matcher.text) {
|
|
49
|
-
const text = notification.params?.update?.content?.text;
|
|
50
|
-
if (!text || !text.includes(matcher.text)) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function findNotification(
|
|
58
|
-
appendLogCalls: unknown[][],
|
|
59
|
-
matcher: NotificationMatcher,
|
|
60
|
-
): NotificationEntry | undefined {
|
|
61
|
-
for (const entries of appendLogCalls) {
|
|
62
|
-
for (const entry of entries) {
|
|
63
|
-
if (entryMatchesNotification(entry, matcher)) {
|
|
64
|
-
return entry as NotificationEntry;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function hasNotification(
|
|
72
|
-
appendLogCalls: unknown[][],
|
|
73
|
-
matcher: NotificationMatcher,
|
|
74
|
-
): boolean {
|
|
75
|
-
return findNotification(appendLogCalls, matcher) !== undefined;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function expectNotification(
|
|
79
|
-
appendLogCalls: unknown[][],
|
|
80
|
-
matcher: NotificationMatcher,
|
|
81
|
-
): NotificationEntry {
|
|
82
|
-
const found = findNotification(appendLogCalls, matcher);
|
|
83
|
-
expect(
|
|
84
|
-
found,
|
|
85
|
-
`Expected notification matching ${JSON.stringify(matcher)}`,
|
|
86
|
-
).toBeDefined();
|
|
87
|
-
return found!;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function expectNoNotification(
|
|
91
|
-
appendLogCalls: unknown[][],
|
|
92
|
-
matcher: NotificationMatcher,
|
|
93
|
-
): void {
|
|
94
|
-
const found = findNotification(appendLogCalls, matcher);
|
|
95
|
-
expect(
|
|
96
|
-
found,
|
|
97
|
-
`Expected no notification matching ${JSON.stringify(matcher)}`,
|
|
98
|
-
).toBeUndefined();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function countNotifications(
|
|
102
|
-
appendLogCalls: unknown[][],
|
|
103
|
-
matcher: NotificationMatcher,
|
|
104
|
-
): number {
|
|
105
|
-
let count = 0;
|
|
106
|
-
for (const entries of appendLogCalls) {
|
|
107
|
-
for (const entry of entries) {
|
|
108
|
-
if (entryMatchesNotification(entry, matcher)) {
|
|
109
|
-
count++;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return count;
|
|
114
|
-
}
|