@ronkovic/aad 0.5.0 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronkovic/aad",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Autonomous Agent Development Orchestrator - Multi-agent TDD pipeline powered by Claude",
5
5
  "module": "src/main.ts",
6
6
  "type": "module",
@@ -350,4 +350,79 @@ describe("ClaudeSdkAdapter", () => {
350
350
  expect(response.exitCode).toBe(0);
351
351
  expect(response.result).toBe("Final result");
352
352
  });
353
+
354
+ test("call() - ANTHROPIC_API_KEY が env に渡される", async () => {
355
+ const originalKey = process.env.ANTHROPIC_API_KEY;
356
+ process.env.ANTHROPIC_API_KEY = "sk-ant-test-key";
357
+ try {
358
+ await adapter.call({ prompt: "Test" });
359
+ const callArgs = mockQuery.mock.calls[0] as unknown as [
360
+ { prompt: string; options: { env?: Record<string, string> } }
361
+ ];
362
+ expect(callArgs[0]!.options.env?.ANTHROPIC_API_KEY).toBe("sk-ant-test-key");
363
+ } finally {
364
+ if (originalKey) process.env.ANTHROPIC_API_KEY = originalKey;
365
+ else delete process.env.ANTHROPIC_API_KEY;
366
+ }
367
+ });
368
+
369
+ test("call() - CLAUDE_CODE_OAUTH_TOKEN が env に渡される", async () => {
370
+ const originalToken = process.env.CLAUDE_CODE_OAUTH_TOKEN;
371
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "oauth-test-token";
372
+ try {
373
+ await adapter.call({ prompt: "Test" });
374
+ const callArgs = mockQuery.mock.calls[0] as unknown as [
375
+ { prompt: string; options: { env?: Record<string, string> } }
376
+ ];
377
+ expect(callArgs[0]!.options.env?.CLAUDE_CODE_OAUTH_TOKEN).toBe("oauth-test-token");
378
+ } finally {
379
+ if (originalToken) process.env.CLAUDE_CODE_OAUTH_TOKEN = originalToken;
380
+ else delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
381
+ }
382
+ });
383
+
384
+ test("call() - タイムアウトで AbortError が発生する", async () => {
385
+ mockQuery.mockImplementationOnce(
386
+ (params: { prompt: string; options?: unknown }) => {
387
+ const abortController = (params.options as { abortController?: AbortController })?.abortController;
388
+ return (async function* () {
389
+ // AbortControllerのabortを監視
390
+ if (abortController) {
391
+ await new Promise((_, reject) => {
392
+ abortController.signal.addEventListener("abort", () => {
393
+ reject(new Error("The operation was aborted"));
394
+ });
395
+ // 長時間待機
396
+ setTimeout(() => {}, 5000);
397
+ });
398
+ }
399
+ yield { type: "result", subtype: "success", result: "late" } as MockSDKMessage;
400
+ })() as AsyncGenerator<MockSDKMessage, void, unknown>;
401
+ }
402
+ );
403
+
404
+ await expect(adapter.call({ prompt: "Test", timeout: 50 })).rejects.toThrow();
405
+ }, 10_000);
406
+
407
+ test("call() - effortLevel がレスポンスに反映される", async () => {
408
+ const response = await adapter.call({ prompt: "Test", effortLevel: "low" });
409
+ expect(response.effortLevel).toBe("low");
410
+ });
411
+
412
+ test("call() - model override がレスポンスに反映される", async () => {
413
+ mockQuery.mockReturnValueOnce(
414
+ (async function* () {
415
+ yield {
416
+ type: "assistant",
417
+ message: {
418
+ model: "claude-haiku-4-5-20251001",
419
+ content: [{ type: "text", text: "Response" }],
420
+ },
421
+ } as MockSDKMessage;
422
+ yield { type: "result", subtype: "success", result: "Response" } as MockSDKMessage;
423
+ })() as AsyncGenerator<MockSDKMessage, void, unknown>
424
+ );
425
+ const response = await adapter.call({ prompt: "Test", model: "claude-haiku-4-5-20251001" });
426
+ expect(response.model).toContain("haiku");
427
+ });
353
428
  });
@@ -1,127 +0,0 @@
1
- import { describe, test, expect } from "bun:test";
2
- import { ClaudeSdkAdapter } from "../claude-sdk.adapter";
3
- import { loadConfig } from "../../../shared/config";
4
- import pino from "pino";
5
- import { ClaudeProviderError } from "../../../shared/errors";
6
-
7
- /**
8
- * 実環境バリデーションテスト
9
- * ANTHROPIC_API_KEY または CLAUDE_CODE_OAUTH_TOKEN が設定されている場合のみ実行
10
- */
11
-
12
- const hasApiKey = !!process.env.ANTHROPIC_API_KEY;
13
- const hasOAuth = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
14
- const hasAuth = hasApiKey || hasOAuth;
15
-
16
- const logger = pino({ level: "silent" });
17
-
18
- function createAdapter() {
19
- const config = loadConfig();
20
- return new ClaudeSdkAdapter(config, logger);
21
- }
22
-
23
- describe.skipIf(!hasAuth)("ClaudeSdkAdapter - Real Environment", () => {
24
- test("simple query returns valid response", async () => {
25
- const adapter = createAdapter();
26
- const response = await adapter.call({
27
- prompt: "Reply with exactly: PING",
28
- });
29
-
30
- expect(response.result).toBeDefined();
31
- expect(response.result.length).toBeGreaterThan(0);
32
- expect(response.exitCode).toBe(0);
33
- expect(response.model).toBeDefined();
34
- expect(response.duration).toBeGreaterThan(0);
35
- }, 30_000);
36
-
37
- test("detects authentication method", () => {
38
- if (hasApiKey) {
39
- expect(process.env.ANTHROPIC_API_KEY).toBeDefined();
40
- console.log("Auth: ANTHROPIC_API_KEY");
41
- }
42
- if (hasOAuth) {
43
- expect(process.env.CLAUDE_CODE_OAUTH_TOKEN).toBeDefined();
44
- console.log("Auth: CLAUDE_CODE_OAUTH_TOKEN");
45
- }
46
- });
47
-
48
- test("throws ClaudeProviderError on invalid auth", async () => {
49
- const originalKey = process.env.ANTHROPIC_API_KEY;
50
- const originalOAuth = process.env.CLAUDE_CODE_OAUTH_TOKEN;
51
-
52
- try {
53
- // 無効な認証情報に差し替え
54
- process.env.ANTHROPIC_API_KEY = "sk-ant-invalid-key-for-testing";
55
- delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
56
-
57
- const adapter = createAdapter();
58
- await expect(
59
- adapter.call({ prompt: "test" })
60
- ).rejects.toThrow(ClaudeProviderError);
61
- } finally {
62
- // 復元
63
- if (originalKey) process.env.ANTHROPIC_API_KEY = originalKey;
64
- else delete process.env.ANTHROPIC_API_KEY;
65
- if (originalOAuth) process.env.CLAUDE_CODE_OAUTH_TOKEN = originalOAuth;
66
- else delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
67
- }
68
- }, 15_000);
69
-
70
- test("respects timeout/abort", async () => {
71
- const adapter = createAdapter();
72
-
73
- await expect(
74
- adapter.call({
75
- prompt: "Write a very long essay about the history of computing.",
76
- timeout: 100, // 100ms — 即タイムアウト
77
- })
78
- ).rejects.toThrow();
79
- }, 10_000);
80
-
81
- test("passes effort level correctly", async () => {
82
- const adapter = createAdapter();
83
- const response = await adapter.call({
84
- prompt: "Reply with exactly: OK",
85
- effortLevel: "low",
86
- });
87
-
88
- expect(response.result).toBeDefined();
89
- expect(response.exitCode).toBe(0);
90
- expect(response.effortLevel).toBe("low");
91
- }, 30_000);
92
-
93
- test("respects model override", async () => {
94
- const adapter = createAdapter();
95
- const response = await adapter.call({
96
- prompt: "Reply with exactly: HI",
97
- model: "claude-haiku-4-5-20251001",
98
- });
99
-
100
- expect(response.result).toBeDefined();
101
- expect(response.exitCode).toBe(0);
102
- // model名はSDKが返す値に依存するが、haiku系であることを確認
103
- expect(response.model).toContain("haiku");
104
- }, 30_000);
105
- });
106
-
107
- describe.skipIf(!hasOAuth)("ClaudeSdkAdapter - OAuth Authentication", () => {
108
- test("authenticates with CLAUDE_CODE_OAUTH_TOKEN", async () => {
109
- const originalKey = process.env.ANTHROPIC_API_KEY;
110
-
111
- try {
112
- // API Keyを一時的に除外してOAuthのみで認証
113
- delete process.env.ANTHROPIC_API_KEY;
114
-
115
- const adapter = createAdapter();
116
- const response = await adapter.call({
117
- prompt: "Reply with exactly: OAUTH_OK",
118
- });
119
-
120
- expect(response.result).toBeDefined();
121
- expect(response.exitCode).toBe(0);
122
- } finally {
123
- if (originalKey) process.env.ANTHROPIC_API_KEY = originalKey;
124
- else delete process.env.ANTHROPIC_API_KEY;
125
- }
126
- }, 30_000);
127
- });