Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fa8275b
improved result card fitted template
burieberry Jun 29, 2026
1fa85eb
update .agents/skills outdated title references
burieberry Jun 29, 2026
a5efc93
update isolated result card
burieberry Jun 29, 2026
4100381
refactor(software-factory): reuse shared delay() from runtime-common
burieberry Jun 29, 2026
67ceb7e
refactor(software-factory): import Option from kanban-config instead …
burieberry Jun 29, 2026
4b76390
fix(software-factory): size overview icons via width/height attributes
burieberry Jun 29, 2026
ac9a9d7
fix(software-factory): retry the in-loop bootstrap-wiring hook
burieberry Jun 29, 2026
def79e2
fix(software-factory): select bootstrap board and project by one policy
burieberry Jun 29, 2026
3187fda
perf(software-factory): wire bootstrap board and project concurrently
burieberry Jun 29, 2026
bd7882c
fix(template-lint): catch split/concatenated data-test selectors in <…
burieberry Jun 29, 2026
82875c5
fix(software-factory): sort validation runs by runAt, not per-issue s…
burieberry Jun 29, 2026
9b4ec7e
fix(software-factory): import delay from runtime-common/utils subpath
burieberry Jun 29, 2026
d3e8e8f
fix(template-lint): don't stitch data-test selectors across dynamic n…
burieberry Jun 30, 2026
0cb4c11
handle seqNo edge case display
burieberry Jun 30, 2026
4355c20
Group validation runs by issue instead of by type
burieberry Jun 30, 2026
7738eaf
Organize validation runs by type
burieberry Jun 30, 2026
f4e21d5
performance improvements
burieberry Jun 30, 2026
62159ee
refactor
burieberry Jun 30, 2026
0808c2a
set edit templates
burieberry Jun 30, 2026
119b938
update fitted error display
burieberry Jun 30, 2026
5fb0229
refactor validation cards to have a common base def
burieberry Jun 30, 2026
444cffc
update embedded result templates
burieberry Jun 30, 2026
23924f7
refactor result template
burieberry Jun 30, 2026
860d46d
icons
burieberry Jun 30, 2026
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
20 changes: 12 additions & 8 deletions .agents/skills/boxel-development/references/dev-core-patterns.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
**Card with computed title:**
**Card with computed cardTitle:**

A card's display name comes from `cardTitle` (a computed pass-through from
`cardInfo.name`). To derive it from another field, override `cardTitle` — do
NOT override the base `title` field; the host reads `cardTitle`, not `title`.

```gts
export class BlogPost extends CardDef {
@field headline = contains(StringField);

@field title = contains(StringField, {
@field cardTitle = contains(StringField, {
computeVia: function (this: BlogPost) {
return this.headline ?? 'Untitled Post';
},
Expand Down Expand Up @@ -60,15 +64,15 @@ export class BlogPost extends CardDef {
@field tags = containsMany(TagField);
@field relatedPosts = linksToMany(() => BlogPost);

@field title = contains(StringField, {
@field cardTitle = contains(StringField, {
computeVia: function (this: BlogPost) {
try {
const baseTitle = this.headline ?? 'Untitled Post';
const maxLength = 50;
if (baseTitle.length <= maxLength) return baseTitle;
return baseTitle.substring(0, maxLength - 3) + '...';
} catch (e) {
console.error('BlogPost: Error computing title', e);
console.error('BlogPost: Error computing cardTitle', e);
return 'Untitled Post';
}
},
Expand Down Expand Up @@ -137,9 +141,9 @@ export class AddressField extends FieldDef {

```gts
// ❌ DANGEROUS: Self-reference causes infinite recursion
@field title = contains(StringField, {
@field cardTitle = contains(StringField, {
computeVia: function(this: BlogPost) {
return this.title || 'Untitled'; // STACK OVERFLOW!
return this.cardTitle || 'Untitled'; // STACK OVERFLOW!
}
});

Expand Down Expand Up @@ -170,9 +174,9 @@ static isolated = class Isolated extends Component<typeof BlogPost> { // ³⁰ I
// ³¹ CRITICAL: Do ALL computation in functions, never in templates
get safeTitle() {
try {
return this.args?.model?.title ?? 'Untitled Post';
return this.args?.model?.cardTitle ?? 'Untitled Post';
} catch (e) {
console.error('BlogPost: Error accessing title', e);
console.error('BlogPost: Error accessing cardTitle', e);
return 'Untitled Post';
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export class Task extends CardDef {
@field taskName = contains(StringField);
@field priority = contains(PriorityField);

@field title = contains(StringField, {
@field cardTitle = contains(StringField, {
computeVia: function (this: Task) {
return this.taskName ?? 'Untitled Task';
},
Expand Down
Loading