Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions .github/workflows/claude-code-review.yml

This file was deleted.

76 changes: 76 additions & 0 deletions .github/workflows/issue-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Issue Triage
on:
issues:
types: [opened]

jobs:
triage-issue:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
issues: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Triage issue with Claude
uses: anthropics/claude-code-action@v1
with:
prompt: |
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.

IMPORTANT: Don't post any comments or messages to the issue. Your only action should be to apply labels.

Issue Information:
- REPO: ${{ github.repository }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}

TASK OVERVIEW:

1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.

2. Next, use the GitHub tools to get context about the issue:
- You have access to these tools:
- mcp__github__get_issue: Use this to retrieve the current issue's details including title, description, and existing labels
- mcp__github__get_issue_comments: Use this to read any discussion or additional context provided in the comments
- mcp__github__update_issue: Use this to apply labels to the issue (do not use this for commenting)
- mcp__github__search_issues: Use this to find similar issues that might provide context for proper categorization and to identify potential duplicate issues
- mcp__github__list_issues: Use this to understand patterns in how other issues are labeled
- Start by using mcp__github__get_issue to get the issue details

3. Analyze the issue content, considering:
- The issue title and description
- The type of issue (bug report, feature request, question, etc.)
- Technical areas mentioned
- Severity or priority indicators
- User impact
- Components affected

4. Select appropriate labels from the available labels list provided above:
- Choose labels that accurately reflect the issue's nature
- Be specific but comprehensive
- Select priority labels if you can determine urgency (high-priority, med-priority, or low-priority)
- Consider platform labels (android, ios) if applicable
- If you find similar issues using mcp__github__search_issues, consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue.

5. Apply the selected labels:
- Use mcp__github__update_issue to apply your selected labels
- DO NOT post any comments explaining your decision
- DO NOT communicate directly with users
- If no labels are clearly applicable, do not apply any labels

IMPORTANT GUIDELINES:
- Be thorough in your analysis
- Only select labels from the provided list above
- DO NOT post any comments to the issue
- Your ONLY action should be to apply labels using mcp__github__update_issue
- It's okay to not add any labels if none are clearly applicable

anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
claude_args: |
--allowedTools "Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues"
11 changes: 7 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ The Package.swift heavily uses environment variables for conditional compilation

### Commit Workflow
When asked to commit changes:
1. **Generate a commit message** and provide it to the user
2. **List the files to be committed** (specify if not all files)
3. **Let the user commit through GitBulter GUI** - do not run git commit commands
4. Wait for user confirmation before proceeding with any PR creation
1. **Generate a commit message** and provide it to the user (formatted without extra spaces)
2. **Save the commit message** to `.claude/tmp/commit-message.md` for easy copying
3. **List the files to be committed** (specify if not all files)
4. **Let the user commit through GitBulter GUI** - do not run git commit commands
5. Wait for user confirmation before proceeding with any PR creation

Example response when asked to commit:
```
Expand All @@ -154,6 +155,8 @@ Here's the commit message for you to use in GitBulter:
Files to commit:
- src/feature.swift
- tests/feature_test.swift

(Saved to .claude/tmp/commit-message.md)
```

### Pull Request Workflow
Expand Down
2 changes: 1 addition & 1 deletion Example/HostingExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ class ViewController: NSViewController {

struct ContentView: View {
var body: some View {
GeometryReaderExample()
ObservationExample()
}
}
38 changes: 38 additions & 0 deletions Example/SharedExample/Data/ObservationExample.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ObservationExample.swift
// SharedExample

#if OPENSWIFTUI
import OpenObservation
import OpenSwiftUI
#else
import Observation
import SwiftUI
#endif

@Observable
private class Model {
var showRed = false
}

struct ObservationExample: View {
@State private var model = Model()

private var showRed: Bool {
get { model.showRed }
nonmutating set { model.showRed = newValue }
}

var body: some View {
VStack {
Color(platformColor: showRed ? .red : .blue)
.frame(width: showRed ? 200 : 400, height: showRed ? 200 : 400)
}
.animation(.spring, value: showRed)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
showRed.toggle()
}
}
}
}
6 changes: 3 additions & 3 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -232,24 +232,25 @@ struct PlatformViewChild<Content: PlatformViewRepresentable>: StatefulRule {
}
if platformView == nil {
let host = ViewGraph.viewRendererHost
// TODO: StatefulRule.withObservation
Graph.withoutUpdate {
let representableContext = PlatformViewRepresentableContext<Content>(
coordinator: coordinator!,
preferenceBridge: bridge,
transaction: transaction,
environmentStorage: .eager(environment)
)
representableContext.values.asCurrent {
let provider = view.makeViewProvider(context: representableContext)
let environment = environment.removingTracker()
platformView = PlatformViewHost(
provider,
host: host,
environment: environment,
viewPhase: phase,
importer: importer
withObservation {
Graph.withoutUpdate {
let representableContext = PlatformViewRepresentableContext<Content>(
coordinator: coordinator!,
preferenceBridge: bridge,
transaction: transaction,
environmentStorage: .eager(environment)
)
representableContext.values.asCurrent {
let provider = view.makeViewProvider(context: representableContext)
let environment = environment.removingTracker()
platformView = PlatformViewHost(
provider,
host: host,
environment: environment,
viewPhase: phase,
importer: importer
)
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/OpenSwiftUI/Util/AnyAttributeFix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ package typealias AttributeType = OpenSwiftUICore.AttributeType
extension AnyAttribute {
package static var `nil`: AnyAttribute { AnyAttribute(rawValue: 0x2) }

package static var currentWasModified: Bool { false }

package var source: AnyAttribute? {
get { preconditionFailure("#39") }
nonmutating set { preconditionFailure("#39") }
Expand Down
24 changes: 17 additions & 7 deletions Sources/OpenSwiftUICore/Data/DynamicProperty/DynamicProperty.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,11 @@ private struct StaticBody<Accessor: BodyAccessor, ThreadFlags: RuleThreadFlags>
extension StaticBody: StatefulRule {
typealias Value = Accessor.Body

// Audited with 6.5.4
func updateValue() {
accessor.updateBody(of: container, changed: true)
withObservation {
accessor.updateBody(of: container, changed: true)
}
}

static var flags: Flags { ThreadFlags.value }
Expand Down Expand Up @@ -370,19 +373,26 @@ private struct DynamicBody<Accessor: BodyAccessor, ThreadFlags: RuleThreadFlags>
extension DynamicBody: StatefulRule {
typealias Value = Accessor.Body

// Audited with 6.5.4
mutating func updateValue() {
if resetSeed != phase.resetSeed {
links.reset()
resetSeed = phase.resetSeed
}
var (container, containerChanged) = $container.changedValue()
let linkChanged = withUnsafeMutablePointer(to: &container) {
links.update(container: $0, phase: phase)
var (container, changed) = $container.changedValue()
withObservation {
withUnsafeMutablePointer(to: &container) {
if links.update(container: $0, phase: phase) {
changed = true
}
}
accessor.updateBody(
of: container,
changed: changed || !hasValue || AnyAttribute.currentWasModified
)
}
let changed = linkChanged || containerChanged || !hasValue
accessor.updateBody(of: container, changed: changed)
}

static var flags: Flags { ThreadFlags.value }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// OpenSwiftUICore
//
// Audited for iOS 18.0
// Status: Blocked by Observation
// Status: Complete
// ID: 1DBD4F024EFF0E73A70DB6DD05D5B548 (SwiftUI)
// ID: E370275CDB55AC7AD9ACF0420859A9E8 (SwiftUICore)

Expand Down Expand Up @@ -63,14 +63,14 @@ private struct ChildEnvironment<Value>: StatefulRule, AsyncAttribute, CustomStri

typealias Value = EnvironmentValues

// FIXME
mutating func updateValue() {
var (environment, environmentChanged) = _environment.changedValue()
let keyPath = modifier.keyPath
var newValue = environment[keyPath: keyPath]
$modifier.syncMainIfReferences { modifier in
// TODO: Observation
modifier.transform(&newValue)
withObservation {
modifier.transform(&newValue)
}
}
guard !environmentChanged,
let valueChanged = oldValue.map({ compareValues($0, newValue, mode: .equatableUnlessPOD) }), !valueChanged,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//
// ObservationUtil.swift
// ObservationUtils.swift
// OpenSwiftUICore
//
// Audited for 6.5.4
// Status: Blocked by TraceEvent
// ID: 7DF024579E4FC31D4E92A33BBA0366D6 (SwiftUI?)
// ID: 7DF024579E4FC31D4E92A33BBA0366D6 (SwiftUICore)

import Foundation
package import OpenAttributeGraphShims
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ extension PreferencesOutputs {
}
}

// MARK: - PreferenceTransform [6.0.87]
// MARK: - PreferenceTransform [6.5.4]

private struct PreferenceTransform<K>: Rule, AsyncAttribute, CustomStringConvertible where K: PreferenceKey {
@Attribute var transform: (inout K.Value) -> Void
Expand All @@ -97,8 +97,9 @@ private struct PreferenceTransform<K>: Rule, AsyncAttribute, CustomStringConvert
var value: K.Value {
var value = childValue ?? K.defaultValue
$transform.syncMainIfReferences { transform in
// TODO: Observation support
transform(&value)
withObservation {
transform(&value)
}
}
return value
}
Expand Down
Loading