Skip to content

Commit 2b301a9

Browse files
committed
bunp version
1 parent 05e98df commit 2b301a9

6 files changed

Lines changed: 125 additions & 31 deletions

File tree

.github/workflows/claude-cli-watch.yml

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ jobs:
145145
CHANGED_FLAGS: ${{ steps.detect.outputs.changed_flags }}
146146
CHANGED_MODELS: ${{ steps.detect.outputs.changed_models }}
147147
CHANGED_FEATURES: ${{ steps.detect.outputs.changed_features }}
148-
ASSIGNEE: ${{ vars.SDK_SYNC_ASSIGNEE != '' && vars.SDK_SYNC_ASSIGNEE || 'copilot' }}
148+
ASSIGNEE: ${{ vars.SDK_SYNC_ASSIGNEE }}
149149
with:
150150
script: |
151151
const currentSha = process.env.CURRENT_SHA;
@@ -156,7 +156,7 @@ jobs:
156156
const changedFlags = process.env.CHANGED_FLAGS || '- (not provided)';
157157
const changedModels = process.env.CHANGED_MODELS || '- (not provided)';
158158
const changedFeatures = process.env.CHANGED_FEATURES || '- (not provided)';
159-
const assignee = process.env.ASSIGNEE || 'copilot';
159+
const assignee = (process.env.ASSIGNEE || '').trim();
160160
161161
const shortCurrent = currentSha.slice(0, 7);
162162
const shortLatest = latestSha.slice(0, 7);
@@ -248,33 +248,29 @@ jobs:
248248
`_Opened automatically by scheduled workflow 'Claude Code Upstream Watch'._`,
249249
].join('\n');
250250
251-
let issue;
252-
try {
253-
issue = await github.rest.issues.create({
254-
owner: context.repo.owner,
255-
repo: context.repo.repo,
256-
title,
257-
body,
258-
labels: [labelName],
259-
assignees: [assignee],
260-
});
261-
core.info(`Created and assigned issue #${issue.data.number} to @${assignee}`);
262-
} catch (error) {
263-
core.warning(`Issue assignment failed (${error.message}), creating without assignee.`);
264-
issue = await github.rest.issues.create({
265-
owner: context.repo.owner,
266-
repo: context.repo.repo,
267-
title,
268-
body,
269-
labels: [labelName],
270-
});
251+
const createParams = {
252+
owner: context.repo.owner,
253+
repo: context.repo.repo,
254+
title,
255+
body,
256+
labels: [labelName],
257+
};
271258
272-
await github.rest.issues.createComment({
273-
owner: context.repo.owner,
274-
repo: context.repo.repo,
275-
issue_number: issue.data.number,
276-
body: `Could not auto-assign @${assignee}. Please assign manually.`,
277-
});
259+
let issue;
260+
if (assignee) {
261+
try {
262+
issue = await github.rest.issues.create({
263+
...createParams,
264+
assignees: [assignee],
265+
});
266+
core.info(`Created and assigned issue #${issue.data.number} to @${assignee}`);
267+
} catch (error) {
268+
core.warning(`Issue assignment failed (${error.message}), creating without assignee.`);
269+
issue = await github.rest.issues.create(createParams);
270+
}
271+
} else {
272+
issue = await github.rest.issues.create(createParams);
273+
core.info(`Created issue #${issue.data.number} without assignee.`);
278274
}
279275
280276
core.info(`Issue URL: ${issue.data.html_url}`);

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ If no new rule is detected -> do not update the file.
9393
- When asked to fix review findings, close every confirmed finding in the same pass; do not leave partial fixes.
9494
- Do not keep or add public sample projects; repository focus is SDK + tests only.
9595
- Upstream sync automation must track real `anthropics/claude-code` CLI changes (flags/models/features), not TypeScript SDK surface diffs, and open actionable repository issues for required SDK follow-up.
96-
- Automatically opened upstream sync issues must include change summary/checklist and assign Copilot by default.
96+
- Automatically opened upstream sync issues must include change summary/checklist and must not auto-assign Copilot by default.
9797
- Release workflow must pack and publish every NuGet package that belongs to this repository; do not leave repository packages out of workflow publishing.
9898
- Run verification in this order:
9999
- focused tests for changed behavior

ClaudeCodeSharpSDK.Tests/Unit/ClaudeThreadTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ public partial class ClaudeThreadTests
1818
private const string ClaudeCodeVersion = "2.0.75";
1919
private const string DefaultPermissionMode = "default";
2020
private const string DraftAnswerText = "Draft answer";
21+
private const string FileChangeAddKind = "add";
22+
private const string FileChangeInProgressStatus = "in_progress";
23+
private const string FileChangeItemId = "change-1";
24+
private const string FileChangeItemType = "file_change";
2125
private const string FinalAnswerText = "Final answer";
2226
private const string FirstEventId = "evt-1";
2327
private const string HelloClaudeInput = "Hello";
2428
private const string ImagePath = "/tmp/image.png";
2529
private const string InitSubtype = "init";
30+
private const string ItemStartedEventType = "item.started";
2631
private const string JsonSchemaFlag = "--json-schema";
2732
private const string MessageRoleAssistant = "assistant";
2833
private const string MessageType = "message";
@@ -34,6 +39,7 @@ public partial class ClaudeThreadTests
3439
private const string ResultEventType = "result";
3540
private const string ReturnJsonPrompt = "Return JSON";
3641
private const string ResumeFlag = "--resume";
42+
private const string SandboxApplePath = "C:/git/CodexSandbox/apple.txt";
3743
private const string SecondEventId = "evt-2";
3844
private const string SessionId = "session-123";
3945
private const string SuccessSubtype = "success";
@@ -146,6 +152,23 @@ public async Task RunAsync_WithNoSessionPersistence_PropagatesFlag()
146152
await Assert.That(runner.Invocations[0].Arguments.Contains(NoSessionPersistenceFlag)).IsTrue();
147153
}
148154

155+
[Test]
156+
public async Task RunAsync_WithUnknownIntermediateItemStartedEvent_IgnoresItAndCompletesTurn()
157+
{
158+
var runner = new FakeClaudeProcessRunner(
159+
CreateSystemInitLine(SessionId, [], FirstEventId),
160+
CreateUnknownItemStartedLine(),
161+
CreateResultLine(SessionId, FinalAnswerText, SecondEventId, durationMs: 8, durationApiMs: 7, totalCostUsd: 0m, inputTokens: 3, cacheCreationInputTokens: 0, cacheReadInputTokens: 0, outputTokens: 2));
162+
using var thread = CreateThread(runner);
163+
164+
var result = await thread.RunAsync(HelloClaudeInput);
165+
166+
await Assert.That(thread.Id).IsEqualTo(SessionId);
167+
await Assert.That(result.FinalResponse).IsEqualTo(FinalAnswerText);
168+
await Assert.That(result.Items.Count).IsEqualTo(0);
169+
await Assert.That(result.Usage).IsNotNull();
170+
}
171+
149172
private static ClaudeThread CreateThread(FakeClaudeProcessRunner runner, ThreadOptions? threadOptions = null)
150173
{
151174
var exec = new ClaudeExec(TestConstants.ClaudeExecutablePath, null, null, runner);
@@ -221,6 +244,19 @@ private static string CreateSystemInitLine(string sessionId, string[] tools, str
221244
ClaudeThreadJsonContext.Default.SystemInitEventPayload);
222245
}
223246

247+
private static string CreateUnknownItemStartedLine()
248+
{
249+
return JsonSerializer.Serialize(
250+
new FileChangeStartedEventPayload(
251+
ItemStartedEventType,
252+
new FileChangePayload(
253+
FileChangeItemId,
254+
FileChangeItemType,
255+
[new FileChangeEntryPayload(SandboxApplePath, FileChangeAddKind)],
256+
FileChangeInProgressStatus)),
257+
ClaudeThreadJsonContext.Default.FileChangeStartedEventPayload);
258+
}
259+
224260
private sealed class FakeClaudeProcessRunner(params string[] lines) : IClaudeProcessRunner
225261
{
226262
private readonly IReadOnlyList<string> _lines = lines;
@@ -261,6 +297,16 @@ internal sealed record AssistantMessagePayload(
261297
UsagePayload usage,
262298
TextContentPayload[] content);
263299

300+
internal sealed record FileChangeEntryPayload(string path, string kind);
301+
302+
internal sealed record FileChangePayload(
303+
string id,
304+
string type,
305+
FileChangeEntryPayload[] changes,
306+
string status);
307+
308+
internal sealed record FileChangeStartedEventPayload(string type, FileChangePayload item);
309+
264310
internal sealed record ResultEventPayload(
265311
string type,
266312
string subtype,
@@ -302,6 +348,7 @@ internal sealed record UsagePayload(
302348

303349
[JsonSerializable(typeof(AnswerPayload))]
304350
[JsonSerializable(typeof(AssistantEventPayload))]
351+
[JsonSerializable(typeof(FileChangeStartedEventPayload))]
305352
[JsonSerializable(typeof(ResultEventPayload))]
306353
[JsonSerializable(typeof(SystemInitEventPayload))]
307354
internal sealed partial class ClaudeThreadJsonContext : JsonSerializerContext;

ClaudeCodeSharpSDK.Tests/Unit/ThreadEventParserTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ public partial class ThreadEventParserTests
1919
private const string ErrorEventText = "fatal";
2020
private const string ErrorSubtype = "status";
2121
private const string FilePath = "README.md";
22+
private const string FileChangeAddKind = "add";
23+
private const string FileChangeItemId = "change-1";
24+
private const string FileChangeInProgressStatus = "in_progress";
25+
private const string FileChangeItemType = "file_change";
2226
private const string FirstEventId = "evt-1";
2327
private const string HelpSlashCommand = "/help";
2428
private const string InitSubtype = "init";
29+
private const string ItemStartedEventType = "item.started";
30+
private const string ItemPropertyName = "item";
2531
private const string MessageRoleAssistant = "assistant";
2632
private const string MessageRoleUser = "user";
2733
private const string MessageStopReason = "stop_sequence";
@@ -33,6 +39,8 @@ public partial class ThreadEventParserTests
3339
private const string ReviewerAgentName = "reviewer";
3440
private const string SecondEventId = "evt-2";
3541
private const string SessionId = "session-123";
42+
private const string SandboxApplePath = "C:/git/CodexSandbox/apple.txt";
43+
private const string StatusPropertyName = "status";
3644
private const string StatusSubtype = "status";
3745
private const string SuccessSubtype = "success";
3846
private const string SuccessText = "ok";
@@ -195,6 +203,25 @@ public async Task Parse_UnknownType_ReturnsUnknownEvent()
195203
await Assert.That(((UnknownEvent)parsed).RawType).IsEqualTo(UnknownEventType);
196204
}
197205

206+
[Test]
207+
public async Task Parse_ItemStartedFileChangeInProgress_ReturnsUnknownEvent()
208+
{
209+
var parsed = ThreadEventParser.Parse(CreateFileChangeStartedPayload());
210+
211+
await Assert.That(parsed).IsTypeOf<UnknownEvent>();
212+
213+
var unknown = (UnknownEvent)parsed;
214+
await Assert.That(unknown.RawType).IsEqualTo(ItemStartedEventType);
215+
await Assert.That(unknown.Payload[ItemPropertyName]?[ClaudeProtocolConstants.Properties.Type]?.GetValue<string>())
216+
.IsEqualTo(FileChangeItemType);
217+
await Assert.That(unknown.Payload[ItemPropertyName]?[ClaudeProtocolConstants.Properties.Id]?.GetValue<string>())
218+
.IsEqualTo(FileChangeItemId);
219+
await Assert.That(unknown.Payload[ItemPropertyName]?[StatusPropertyName]?.GetValue<string>())
220+
.IsEqualTo(FileChangeInProgressStatus);
221+
await Assert.That(unknown.Payload[ItemPropertyName]?["changes"]?[0]?["path"]?.GetValue<string>())
222+
.IsEqualTo(SandboxApplePath);
223+
}
224+
198225
private static string CreateAssistantPayload()
199226
{
200227
return JsonSerializer.Serialize(
@@ -357,6 +384,19 @@ private static string CreateUnknownPayload()
357384
ThreadEventParserJsonContext.Default.UnknownEventPayload);
358385
}
359386

387+
private static string CreateFileChangeStartedPayload()
388+
{
389+
return JsonSerializer.Serialize(
390+
new FileChangeStartedEventPayload(
391+
ItemStartedEventType,
392+
new FileChangePayload(
393+
FileChangeItemId,
394+
FileChangeItemType,
395+
[new FileChangeEntryPayload(SandboxApplePath, FileChangeAddKind)],
396+
FileChangeInProgressStatus)),
397+
ThreadEventParserJsonContext.Default.FileChangeStartedEventPayload);
398+
}
399+
360400
private static string CreateUserPayload()
361401
{
362402
return JsonSerializer.Serialize(
@@ -402,6 +442,16 @@ internal sealed record ContentPayload(
402442

403443
internal sealed record ErrorEventPayload(string type, string? error, string? result);
404444

445+
internal sealed record FileChangeEntryPayload(string path, string kind);
446+
447+
internal sealed record FileChangePayload(
448+
string id,
449+
string type,
450+
FileChangeEntryPayload[] changes,
451+
string status);
452+
453+
internal sealed record FileChangeStartedEventPayload(string type, FileChangePayload item);
454+
405455
internal sealed record ResultEventPayload(
406456
string type,
407457
string subtype,
@@ -473,6 +523,7 @@ internal sealed record UsagePayload(
473523

474524
[JsonSerializable(typeof(AssistantEventPayload))]
475525
[JsonSerializable(typeof(ErrorEventPayload))]
526+
[JsonSerializable(typeof(FileChangeStartedEventPayload))]
476527
[JsonSerializable(typeof(ResultEventPayload))]
477528
[JsonSerializable(typeof(StructuredOutputResultEventPayload))]
478529
[JsonSerializable(typeof(SystemInitEventPayload))]

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
1414
<AnalysisLevel>latest-recommended</AnalysisLevel>
1515
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
16-
<Version>1.1.2</Version>
16+
<Version>1.1.3</Version>
1717
<PackageVersion>$(Version)</PackageVersion>
1818

1919
</PropertyGroup>

docs/Features/release-and-sync-automation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Keep package quality and upstream Claude Code CLI parity automatically verified
5151
- Claude Code CLI watch runs daily and opens an issue when upstream `anthropics/claude-code` changed since the pinned submodule SHA.
5252
- Sync automation treats `claude -p --output-format json|stream-json` as the runtime source of truth for protocol validation after upstream changes.
5353
- Sync issue body must include detected candidate changes for CLI flags/models/features and an actionable checklist.
54-
- Sync issue must assign Copilot by default.
54+
- Sync issue must not auto-assign Copilot by default.
5555
- Duplicate sync issue for the same upstream SHA is not allowed.
5656

5757
---

0 commit comments

Comments
 (0)