Skip to content

Commit 25beb4a

Browse files
committed
chore(openspec): archive design-source-abstraction, sync specs
Sync 4 delta specs to main: design-source-protocol (new), source-dispatch (new), configuration (updated), tokens-file-source (updated). Archive completed change.
1 parent f33c84b commit 25beb4a

12 files changed

Lines changed: 399 additions & 442 deletions

File tree

openspec/changes/design-source-abstraction/.openspec.yaml renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/.openspec.yaml

File renamed without changes.

openspec/changes/design-source-abstraction/design.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/design.md

File renamed without changes.

openspec/changes/design-source-abstraction/proposal.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/proposal.md

File renamed without changes.

openspec/changes/design-source-abstraction/specs/configuration/spec.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/specs/configuration/spec.md

File renamed without changes.

openspec/changes/design-source-abstraction/specs/design-source-protocol/spec.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/specs/design-source-protocol/spec.md

File renamed without changes.

openspec/changes/design-source-abstraction/specs/source-dispatch/spec.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/specs/source-dispatch/spec.md

File renamed without changes.

openspec/changes/design-source-abstraction/specs/tokens-file-source/spec.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/specs/tokens-file-source/spec.md

File renamed without changes.

openspec/changes/design-source-abstraction/tasks.md renamed to openspec/changes/archive/2026-03-21-design-source-abstraction/tasks.md

File renamed without changes.
Lines changed: 61 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,98 @@
1-
# Configuration
2-
3-
Default values and constraints for PKL configuration schemas.
4-
51
## ADDED Requirements
62

7-
### Requirement: iOS default values
8-
9-
iOS PKL schema SHALL provide sensible default values for commonly used fields to reduce boilerplate in configuration files.
10-
11-
#### Scenario: iOS ColorsEntry defaults
12-
13-
- **WHEN** an iOS ColorsEntry does not specify `useColorAssets`
14-
- **THEN** the system SHALL use `true` as the default value
15-
16-
#### Scenario: iOS ColorsEntry nameStyle default
17-
18-
- **WHEN** an iOS ColorsEntry does not specify `nameStyle`
19-
- **THEN** the system SHALL use `"camelCase"` as the default value
20-
21-
#### Scenario: iOS IconsEntry defaults
22-
23-
- **WHEN** an iOS IconsEntry does not specify `format`
24-
- **THEN** the system SHALL use `"pdf"` as the default value
25-
26-
#### Scenario: iOS IconsEntry assetsFolder default
27-
28-
- **WHEN** an iOS IconsEntry does not specify `assetsFolder`
29-
- **THEN** the system SHALL use `"Icons"` as the default value
30-
31-
#### Scenario: iOS ImagesEntry scales default
32-
33-
- **WHEN** an iOS ImagesEntry does not specify `scales`
34-
- **THEN** the system SHALL use `[1, 2, 3]` as the default value
35-
36-
#### Scenario: iOS ImagesEntry format defaults
37-
38-
- **WHEN** an iOS ImagesEntry does not specify `sourceFormat` or `outputFormat`
39-
- **THEN** the system SHALL use `"png"` as the default for both
40-
41-
#### Scenario: iOS iOSConfig xcassetsInMainBundle default
42-
43-
- **WHEN** an iOSConfig does not specify `xcassetsInMainBundle`
44-
- **THEN** the system SHALL use `true` as the default value
45-
46-
### Requirement: Android default values
47-
48-
Android PKL schema SHALL provide sensible default values for commonly used fields.
49-
50-
#### Scenario: Android ImagesEntry format default
51-
52-
- **WHEN** an Android ImagesEntry does not specify `format`
53-
- **THEN** the system SHALL use `"png"` as the default value
54-
55-
#### Scenario: Android IconsEntry nameStyle default
56-
57-
- **WHEN** an Android IconsEntry does not specify `nameStyle`
58-
- **THEN** the system SHALL use `"snake_case"` as the default value
59-
60-
#### Scenario: Android ImagesEntry scales default
61-
62-
- **WHEN** an Android ImagesEntry does not specify `scales`
63-
- **THEN** the system SHALL use `[1, 1.5, 2, 3, 4]` as the default value
64-
65-
#### Scenario: Android ThemeAttributes defaults
3+
### Requirement: SourceKind typealias in Common.pkl
664

67-
- **WHEN** ThemeAttributes does not specify `attrsFile`, `stylesFile`, `stylesNightFile`
68-
- **THEN** the system SHALL use `"values/attrs.xml"`, `"values/styles.xml"`, `"values-night/styles.xml"` respectively
5+
The `Common.pkl` schema SHALL define a `SourceKind` typealias:
696

70-
### Requirement: Flutter default values
7+
```pkl
8+
typealias SourceKind = "figma"|"penpot"|"tokens-file"|"tokens-studio"|"sketch-file"
9+
```
7110

72-
Flutter PKL schema SHALL provide sensible default values for commonly used fields.
11+
#### Scenario: Valid sourceKind values accepted
7312

74-
#### Scenario: Flutter ColorsEntry className default
13+
- **WHEN** a PKL config sets `sourceKind = "figma"`
14+
- **THEN** PKL evaluation SHALL succeed
7515

76-
- **WHEN** a Flutter ColorsEntry does not specify `className`
77-
- **THEN** the system SHALL use `"AppColors"` as the default value
16+
#### Scenario: Invalid sourceKind rejected
7817

79-
#### Scenario: Flutter ImagesEntry scales default
18+
- **WHEN** a PKL config sets `sourceKind = "unknown"`
19+
- **THEN** PKL evaluation SHALL fail with a validation error
8020

81-
- **WHEN** a Flutter ImagesEntry does not specify `scales`
82-
- **THEN** the system SHALL use `[1, 2, 3]` as the default value
21+
### Requirement: sourceKind field in FrameSource
8322

84-
### Requirement: Web default values
23+
The `FrameSource` open class in `Common.pkl` SHALL include an optional `sourceKind` field:
8524

86-
Web PKL schema SHALL provide sensible default values for commonly used fields.
25+
```pkl
26+
open class FrameSource extends NameProcessing {
27+
sourceKind: SourceKind?
28+
// ... existing fields
29+
}
30+
```
8731

88-
#### Scenario: Web IconsEntry defaults
32+
When `sourceKind` is `null`, the system SHALL default to `"figma"`.
8933

90-
- **WHEN** a Web IconsEntry does not specify `iconSize`
91-
- **THEN** the system SHALL use `24` as the default value
34+
#### Scenario: FrameSource without sourceKind defaults to figma
9235

93-
#### Scenario: Web IconsEntry generateReactComponents default
36+
- **WHEN** an icons entry does not specify `sourceKind`
37+
- **THEN** the system SHALL treat it as `sourceKind = "figma"`
9438

95-
- **WHEN** a Web IconsEntry does not specify `generateReactComponents`
96-
- **THEN** the system SHALL use `true` as the default value
39+
#### Scenario: FrameSource with explicit sourceKind
9740

98-
### Requirement: Common and Figma default values
41+
- **WHEN** an icons entry specifies `sourceKind = "penpot"`
42+
- **THEN** the system SHALL use `"penpot"` as the source kind for that entry
9943

100-
Common and Figma PKL schemas SHALL provide sensible default values.
44+
### Requirement: sourceKind field in VariablesSource
10145

102-
#### Scenario: Cache defaults
46+
The `VariablesSource` open class in `Common.pkl` SHALL include an optional `sourceKind` field:
10347

104-
- **WHEN** a Cache config does not specify `enabled` or `path`
105-
- **THEN** the system SHALL use `false` and `".exfig-cache.json"` respectively
48+
```pkl
49+
open class VariablesSource extends NameProcessing {
50+
sourceKind: SourceKind?
51+
// ... existing fields
52+
}
53+
```
10654

107-
#### Scenario: Figma timeout default
55+
When `sourceKind` is `null`, the system SHALL auto-detect:
10856

109-
- **WHEN** a FigmaConfig does not specify `timeout`
110-
- **THEN** the system SHALL use `30` seconds as the default value
57+
- If `tokensFile` is set → `.tokensFile`
58+
- Otherwise → `.figma`
11159

112-
### Requirement: PKL constraints for required string fields
60+
#### Scenario: VariablesSource auto-detects tokensFile
11361

114-
PKL schemas SHALL validate that required string fields are not empty using `!isEmpty` constraint.
62+
- **WHEN** a colors entry has `tokensFile` set but `sourceKind` is null
63+
- **THEN** the system SHALL use `tokensFile` as the source kind
11564

116-
#### Scenario: Empty xcodeprojPath rejected
65+
#### Scenario: VariablesSource auto-detects figma
11766

118-
- **WHEN** a PKL config specifies `xcodeprojPath = ""`
119-
- **THEN** `pkl eval` SHALL fail with a constraint violation error
67+
- **WHEN** a colors entry has no `tokensFile` and `sourceKind` is null
68+
- **THEN** the system SHALL use `figma` as the source kind
12069

121-
#### Scenario: Empty tokensFileId rejected
70+
#### Scenario: Explicit sourceKind overrides auto-detection
12271

123-
- **WHEN** a PKL config specifies `tokensFileId = ""`
124-
- **THEN** `pkl eval` SHALL fail with a constraint violation error
72+
- **WHEN** a colors entry has `sourceKind = "tokens-studio"` and no `tokensFile`
73+
- **THEN** the system SHALL use `tokens-studio` as the source kind regardless of auto-detection
12574

126-
### Requirement: PKL constraints for numeric ranges
75+
#### Scenario: Explicit sourceKind takes priority over tokensFile presence
12776

128-
PKL schemas SHALL validate numeric fields with appropriate range constraints.
77+
- **WHEN** a colors entry has `sourceKind = "figma"` AND `tokensFile` is also set
78+
- **THEN** the system SHALL use `figma` as the source kind (explicit overrides auto-detection)
79+
- **NOTE:** This handles the case where a user switches back from tokens-file to figma without removing the `tokensFile` field
12980

130-
#### Scenario: Figma timeout range
81+
### Requirement: PKL codegen produces DesignSourceKind bridging
13182

132-
- **WHEN** a PKL config specifies `timeout = 0`
133-
- **THEN** `pkl eval` SHALL fail with a constraint violation error
83+
After running `./bin/mise run codegen:pkl`, the generated Swift types SHALL include `SourceKind` as a String-based enum. The ExFig-* platform entry types SHALL bridge PKL `SourceKind` to ExFigCore `DesignSourceKind`.
13484

135-
#### Scenario: Valid Figma timeout
85+
#### Scenario: PKL SourceKind bridges to Swift DesignSourceKind
13686

137-
- **WHEN** a PKL config specifies `timeout = 60`
138-
- **THEN** `pkl eval` SHALL succeed
87+
- **WHEN** a PKL config with `sourceKind = "tokens-file"` is evaluated
88+
- **THEN** the generated Swift value SHALL be bridged to `DesignSourceKind.tokensFile`
13989

140-
### Requirement: Defaults do not change generated Swift code
90+
### Requirement: Backward compatibility
14191

142-
Adding default values to PKL schemas SHALL NOT change the generated Swift types (`codegen:pkl` output).
92+
All existing PKL configs without `sourceKind` fields SHALL continue to work without modification. The field is optional with null default, and null maps to auto-detected behavior (figma for FrameSource, figma-or-tokensFile for VariablesSource).
14393

144-
#### Scenario: Zero diff after codegen
94+
#### Scenario: Existing config without sourceKind
14595

146-
- **WHEN** `./bin/mise run codegen:pkl` is run after adding defaults to PKL schemas
147-
- **THEN** the generated `Sources/ExFigConfig/Generated/*.pkl.swift` files SHALL have zero diff
96+
- **WHEN** an existing `exfig.pkl` config with no `sourceKind` fields is evaluated
97+
- **THEN** PKL evaluation SHALL succeed
98+
- **AND** export behavior SHALL be identical to the current implementation

0 commit comments

Comments
 (0)