Skip to content

Commit a5d6d91

Browse files
Tiwasclaude
andcommitted
feat(flow-doctor): show device/app/card names in issue details, not raw ids
Every checkCard issue (missingApp, unknownCard, deprecatedCard, missingArg, missingDevice, unknownArg, deviceMissingApp) now goes through a new describeCard() helper that turns "homey:device:<uuid>:<action>" into "<device name> → <card title>". For app-owned cards it becomes "<app name> → <card title>". Raw ids still surface as a fallback when the device has been deleted or the card title can't be looked up — which keeps the original signal for the rare cases where the human-friendly name is unavailable. Concrete example from the user's Homey: the deprecated card "homey:device:266c8ee2-…:clg_turn_off_all_members" now displays as "Circadian Light Group → Turn off all lights in the group". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c4527ef commit a5d6d91

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

docs/tools/flow-doctor.html

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,27 @@ <h3 class="font-bold text-red-800 mb-2" data-i18n="error.title">Something went w
753753
return null;
754754
};
755755

756+
const describeCard = (card, def) => {
757+
const id = card.id || card.uri || '';
758+
const titleRaw = def && (def.title || def.titleFormatted);
759+
const title = typeof titleRaw === 'object' ? (titleRaw.en || Object.values(titleRaw)[0]) : titleRaw;
760+
if (id.startsWith('homey:device:')) {
761+
const devId = id.substring('homey:device:'.length).split(':')[0];
762+
const devName = devices[devId]?.name || devId;
763+
return title ? `${devName}${title}` : `${devName}${id.split(':').pop()}`;
764+
}
765+
if (id.startsWith('homey:app:')) {
766+
const aid = id.substring('homey:app:'.length).split(':')[0];
767+
const appName = installedApps[aid]?.name || aid;
768+
return title ? `${appName}${title}` : `${appName}${id.split(':').pop()}`;
769+
}
770+
if (id.startsWith('homey:manager:')) {
771+
const mgr = id.substring('homey:manager:'.length).split(':')[0];
772+
return title ? `${mgr}${title}` : id;
773+
}
774+
return title || id;
775+
};
776+
756777
const checkCard = (card, kind) => {
757778
const issues = [];
758779
if (!card) return issues;
@@ -766,7 +787,7 @@ <h3 class="font-bold text-red-800 mb-2" data-i18n="error.title">Something went w
766787
if (uri.startsWith('homey:app:')) {
767788
appId = uri.substring('homey:app:'.length).split(':')[0];
768789
if (appId && !installedAppIds.has(appId)) {
769-
issues.push({ severity: 'error', key: 'issue.missingApp', detail: appId + ' · ' + (card.id || ''), appId });
790+
issues.push({ severity: 'error', key: 'issue.missingApp', detail: describeCard(card, null), appId });
770791
return issues;
771792
}
772793
}
@@ -775,11 +796,11 @@ <h3 class="font-bold text-red-800 mb-2" data-i18n="error.title">Something went w
775796
if (uri.startsWith('homey:app:') || uri.startsWith('homey:manager:') || uri.startsWith('homey:device:')) {
776797
def = lookupCardDef(card, kind);
777798
if (!def) {
778-
issues.push({ severity: 'error', key: 'issue.unknownCard', detail: (card.id || '') + ' (' + uri + ')', appId });
799+
issues.push({ severity: 'error', key: 'issue.unknownCard', detail: describeCard(card, null), appId });
779800
return issues;
780801
}
781802
if (def.deprecated) {
782-
issues.push({ severity: 'warn', key: 'issue.deprecatedCard', detail: (card.id || ''), appId });
803+
issues.push({ severity: 'warn', key: 'issue.deprecatedCard', detail: describeCard(card, def), appId });
783804
}
784805
}
785806

@@ -790,19 +811,19 @@ <h3 class="font-bold text-red-800 mb-2" data-i18n="error.title">Something went w
790811
for (const argDef of def.args) {
791812
const val = provided[argDef.name];
792813
if ((val === undefined || val === null) && argDef.required !== false) {
793-
issues.push({ severity: 'warn', key: 'issue.missingArg', detail: argDef.name + ' (' + (card.id || '') + ')', appId });
814+
issues.push({ severity: 'warn', key: 'issue.missingArg', detail: describeCard(card, def) + ' · arg "' + argDef.name + '"', appId });
794815
}
795816
// Device reference check — only for actual device-typed args
796817
if (argDef.type === 'device' && val && typeof val === 'object' && val.id && typeof val.id === 'string') {
797818
if (deviceIds.size > 0 && !deviceIds.has(val.id) && val.id.length >= 16) {
798-
issues.push({ severity: 'error', key: 'issue.missingDevice', detail: argDef.name + ' → ' + (val.name || val.id), appId });
819+
issues.push({ severity: 'error', key: 'issue.missingDevice', detail: describeCard(card, def) + ' · arg "' + argDef.name + '" → ' + (val.name || val.id), appId });
799820
}
800821
}
801822
}
802823
// Unknown args (args present in flow but not in manifest)
803824
for (const argName of Object.keys(provided)) {
804825
if (!defArgNames.has(argName)) {
805-
issues.push({ severity: 'warn', key: 'issue.unknownArg', detail: argName + ' (' + (card.id || '') + ')', appId });
826+
issues.push({ severity: 'warn', key: 'issue.unknownArg', detail: describeCard(card, def) + ' · unknown arg "' + argName + '"', appId });
806827
}
807828
}
808829
}
@@ -811,10 +832,11 @@ <h3 class="font-bold text-red-800 mb-2" data-i18n="error.title">Something went w
811832
if (uri.startsWith('homey:device:')) {
812833
const devId = uri.substring('homey:device:'.length).split(':')[0];
813834
if (deviceIds.size > 0 && devId && !deviceIds.has(devId)) {
814-
issues.push({ severity: 'error', key: 'issue.missingDevice', detail: devId, appId });
835+
issues.push({ severity: 'error', key: 'issue.missingDevice', detail: describeCard(card, def), appId });
815836
} else if (deviceToApp[devId] && !installedAppIds.has(deviceToApp[devId])) {
816837
// Device exists but its owning app isn't installed — orphan device.
817-
issues.push({ severity: 'warn', key: 'issue.deviceMissingApp', detail: deviceToApp[devId], appId: deviceToApp[devId] });
838+
const missingApp = deviceToApp[devId];
839+
issues.push({ severity: 'warn', key: 'issue.deviceMissingApp', detail: describeCard(card, def) + ' · app: ' + missingApp, appId: missingApp });
818840
}
819841
}
820842

0 commit comments

Comments
 (0)