@wyndlass/app-sdk 0.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +212 -1
  2. package/cli/app-package.mjs +111 -0
  3. package/cli/commands.mjs +133 -0
  4. package/cli/main.mjs +73 -0
  5. package/cli/package.mjs +119 -0
  6. package/cli/preview.mjs +142 -0
  7. package/cli/zip.mjs +63 -0
  8. package/dist/contract/app-contract.d.ts +221 -0
  9. package/dist/contract/app-contract.js +6 -0
  10. package/dist/contract/app-definition.d.ts +155 -0
  11. package/dist/contract/app-definition.js +3 -0
  12. package/dist/contract/data-answer.d.ts +40 -0
  13. package/dist/contract/data-answer.js +3 -0
  14. package/dist/contract/data-calendar.d.ts +57 -0
  15. package/dist/contract/data-calendar.js +3 -0
  16. package/dist/contract/data-news.d.ts +29 -0
  17. package/dist/contract/data-news.js +3 -0
  18. package/dist/contract/data-quotes.d.ts +75 -0
  19. package/dist/contract/data-quotes.js +3 -0
  20. package/dist/contract/data-series.d.ts +51 -0
  21. package/dist/contract/data-series.js +3 -0
  22. package/dist/contract/data-snapshot.d.ts +30 -0
  23. package/dist/contract/data-snapshot.js +3 -0
  24. package/dist/contract/data-weather.d.ts +421 -0
  25. package/dist/contract/data-weather.js +3 -0
  26. package/dist/contract/player-api-event.d.ts +253 -0
  27. package/dist/contract/player-api-event.js +3 -0
  28. package/dist/contract/player-api-status.d.ts +178 -0
  29. package/dist/contract/player-api-status.js +3 -0
  30. package/dist/easing.d.ts +16 -0
  31. package/dist/easing.js +71 -0
  32. package/dist/index.d.ts +94 -0
  33. package/dist/index.js +218 -0
  34. package/dist/preview/frame/frame.js +2 -0
  35. package/dist/preview/frame/index.html +12 -0
  36. package/dist/preview/index.html +40 -0
  37. package/dist/preview/page.js +7 -0
  38. package/dist/qr.d.ts +5 -0
  39. package/dist/qr.js +14 -0
  40. package/dist/react.d.ts +52 -0
  41. package/dist/react.js +149 -0
  42. package/package.json +83 -4
  43. package/protocol/app-definition.schema.json +435 -0
  44. package/protocol/app-packages.json +172 -0
  45. package/protocol/common.schema.json +197 -0
  46. package/protocol/samples/calendar.json +63 -0
  47. package/protocol/samples/events/app.command.json +14 -0
  48. package/protocol/samples/events/item.end.json +13 -0
  49. package/protocol/samples/events/item.start.json +18 -0
  50. package/protocol/samples/events/state.changed.json +11 -0
  51. package/protocol/samples/news.json +37 -0
  52. package/protocol/samples/player-status.json +58 -0
  53. package/protocol/samples/weather.json +59 -0
  54. package/skill/wyndlass-app/SKILL.md +90 -0
  55. package/skill/wyndlass-app/references/contract.md +91 -0
  56. package/skill/wyndlass-app/references/mcp.md +79 -0
  57. package/skill/wyndlass-app/references/templates.md +38 -0
  58. package/templates/react/AGENTS.md +17 -0
  59. package/templates/react/README.md +23 -0
  60. package/templates/react/app.json +14 -0
  61. package/templates/react/gitignore +2 -0
  62. package/templates/react/package.json +22 -0
  63. package/templates/react/src/app.css +7 -0
  64. package/templates/react/src/app.tsx +39 -0
  65. package/templates/react/src/env.d.ts +13 -0
  66. package/templates/react/tsconfig.json +13 -0
  67. package/templates/vanilla/AGENTS.md +17 -0
  68. package/templates/vanilla/README.md +23 -0
  69. package/templates/vanilla/app.json +14 -0
  70. package/templates/vanilla/gitignore +2 -0
  71. package/templates/vanilla/package.json +18 -0
  72. package/templates/vanilla/src/app.css +7 -0
  73. package/templates/vanilla/src/app.ts +59 -0
  74. package/templates/vanilla/src/env.d.ts +13 -0
  75. package/templates/vanilla/tsconfig.json +12 -0
@@ -0,0 +1,155 @@
1
+ export type CommonSemver = string;
2
+ /**
3
+ * BCP 47 language tag.
4
+ */
5
+ export type CommonLocale = string;
6
+ /**
7
+ * The YAML definition of a web component app (scoping doc 7.8). Drives the designer's property panel, the catalog and the MCP tools.
8
+ */
9
+ export interface AppDefinition {
10
+ /**
11
+ * Reverse-domain id, e.g. com.wyndlass.weather. com.wyndlass. is Wyndlass's own: an app an organization imports may not use it (WP-0100).
12
+ */
13
+ id: string;
14
+ version: CommonSemver;
15
+ name: string;
16
+ description?: string;
17
+ /**
18
+ * The element's name. From Player API 2 (WP-0100) the host defines the module's default export under this name, a hyphen and a suffix of its own, so it is the readable part of the tag. Wyndlass's apps also define it themselves, for players older than that.
19
+ */
20
+ element: string;
21
+ params?: {
22
+ [k: string]: Param | undefined;
23
+ };
24
+ properties?: {
25
+ resizable?: boolean;
26
+ minDuration?: string;
27
+ offline?: boolean;
28
+ transparent?: boolean;
29
+ aspectRatio?: string;
30
+ };
31
+ capabilities?: {
32
+ network?: string[];
33
+ /**
34
+ * Sensors the app reads on the screen. `impressions`: the live, anonymous feed of the people at the screen, where its site measures them (WP-0105): context.impressions.
35
+ */
36
+ sensors?: string[];
37
+ audio?: boolean;
38
+ peers?: boolean;
39
+ /**
40
+ * What the app may do with the player's controller (ADR 0050): read its properties and events (read, the default), or also command playback, audio and display (control). The CMS shows it when the app is added.
41
+ */
42
+ player?: "read" | "control";
43
+ };
44
+ bindings?: string[];
45
+ /**
46
+ * Named binding slots (ADR 0053, decision 8; DES-AP-01): each a field the app shows, mapped to a table column in a layout's binding. A layout's binding.fields names these.
47
+ */
48
+ slots?: {
49
+ [k: string]: {
50
+ label: string;
51
+ /**
52
+ * What the column must hold.
53
+ */
54
+ type: "text" | "number" | "currency" | "date" | "datetime" | "image" | "url" | "boolean";
55
+ required?: boolean;
56
+ help?: string;
57
+ } | undefined;
58
+ };
59
+ /**
60
+ * The presets the app's enter and exit hooks take (ADR 0053, decision 8; DES-AH-01 to 07). An app without them is animated as one box.
61
+ */
62
+ animation?: {
63
+ /**
64
+ * Presets its enter hook plays (fade, slide, typewriter...).
65
+ */
66
+ enter?: string[];
67
+ /**
68
+ * Presets its exit hook plays.
69
+ */
70
+ exit?: string[];
71
+ /**
72
+ * Its items can enter one after another (DES-AN-06).
73
+ */
74
+ stagger?: boolean;
75
+ /**
76
+ * It pages through its items, playing exit and enter at each page (DES-DB-13): its page count comes from the snapshot the layout started with.
77
+ */
78
+ pages?: boolean;
79
+ };
80
+ /**
81
+ * The data service's sources it reads (ADR 0069): weather, news.
82
+ */
83
+ data?: string[];
84
+ events?: {
85
+ emits?: string[];
86
+ consumes?: string[];
87
+ };
88
+ mobile?: {
89
+ mode?: "render" | "snapshot" | "hidden";
90
+ };
91
+ locales?: CommonLocale[];
92
+ }
93
+ export interface Param {
94
+ /**
95
+ * A param's kind. A font param's value is a typography object (layout.schema.json#/$defs/typography): a family with its weight, style, decoration, letter case and spacing, line height, shadow and scale.
96
+ */
97
+ type: "string" | "text" | "number" | "boolean" | "enum" | "color" | "font" | "media" | "location" | "datetime" | "duration" | "url" | "datatable" | "column" | "secret" | "json";
98
+ label?: string;
99
+ default?: unknown;
100
+ /**
101
+ * On an enum, its choices. On any other type, suggestions the designer offers, while any valid value is still allowed (WP-0098). Each is a plain value, or labeled: shown by its label, under its group.
102
+ *
103
+ * @minItems 1
104
+ */
105
+ values?: [ParamValue, ...ParamValue[]];
106
+ group?: string;
107
+ required?: boolean;
108
+ min?: number;
109
+ max?: number;
110
+ step?: number;
111
+ help?: string;
112
+ advanced?: boolean;
113
+ /**
114
+ * When the param applies (WP-0068 part f, after gadget.yaml's depends): each key names another param of this app, and its test must hold. A param that does not apply is not shown in the designer and is not required; its value is kept.
115
+ */
116
+ when?: {
117
+ [k: string]: ParamTest | undefined;
118
+ };
119
+ }
120
+ /**
121
+ * A value as a param's values list it (WP-0098): a string, number or boolean, or labeled ({ value, label, group }) for the designer to show by its label, under its group.
122
+ */
123
+ export interface ParamValue {
124
+ [k: string]: unknown | undefined;
125
+ }
126
+ /**
127
+ * A test of another param's value (WP-0068 part f): every one given must hold. Values compare as text.
128
+ */
129
+ export interface ParamTest {
130
+ /**
131
+ * Its value is one of these.
132
+ *
133
+ * @minItems 1
134
+ * @maxItems 50
135
+ */
136
+ anyOf?: [string | number | boolean, ...(string | number | boolean)[]];
137
+ /**
138
+ * Its value, a list, holds every one of these.
139
+ *
140
+ * @minItems 1
141
+ * @maxItems 50
142
+ */
143
+ allOf?: [string | number | boolean, ...(string | number | boolean)[]];
144
+ /**
145
+ * Its value is none of these.
146
+ *
147
+ * @minItems 1
148
+ * @maxItems 50
149
+ */
150
+ noneOf?: [string | number | boolean, ...(string | number | boolean)[]];
151
+ /**
152
+ * true: it has a value; false: it has none (absent, empty text, or an empty list).
153
+ */
154
+ set?: boolean;
155
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/app-definition.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * What the data service answers for any source (ADR 0069): GET /v0/{source}. data is the source's normalized form (data-weather, data-news, data-quotes, data-series, data-calendar). Players keep the last answer and show it offline with its age.
3
+ */
4
+ export interface DataServiceAnswer {
5
+ /**
6
+ * The source asked: weather, news, quotes, series, calendar.
7
+ */
8
+ source: string;
9
+ /**
10
+ * The parameters the answer is for, as the service normalized them (a place rounded to 0.1°, a feed's URL). A calendar's address is left out: it often works as a password (WP-0111).
11
+ */
12
+ params: {
13
+ [k: string]: (string | number | boolean) | undefined;
14
+ };
15
+ /**
16
+ * When the provider answered.
17
+ */
18
+ fetchedAt: string;
19
+ /**
20
+ * When to ask again.
21
+ */
22
+ expiresAt: string;
23
+ /**
24
+ * True when the provider failed and this is the last answer it gave, kept for up to a day past expiresAt.
25
+ */
26
+ stale: boolean;
27
+ /**
28
+ * Credit the source requires wherever its data is shown (Open-Meteo: CC BY 4.0).
29
+ */
30
+ attribution?: {
31
+ text: string;
32
+ url?: string;
33
+ };
34
+ /**
35
+ * The source's normalized data.
36
+ */
37
+ data: {
38
+ [k: string]: unknown | undefined;
39
+ };
40
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-answer.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,57 @@
1
+ /**
2
+ * An instant in UTC (2026-10-14T14:00:00Z); a date (2026-10-14) for a whole-day event; a local time (2026-10-14T09:00:00) for a floating one.
3
+ */
4
+ export type Time = string;
5
+ /**
6
+ * The data service's calendar from an iCalendar, jCal or xCal feed (ADR 0069, WP-0111): the occurrences in the window asked for, repeats and time zones worked out, in time order. Attendees, organizers, alarms and attachments are never carried; a private event has no title, place or description.
7
+ */
8
+ export interface Calendar {
9
+ calendar: {
10
+ /**
11
+ * X-WR-CALNAME, or NAME (RFC 7986).
12
+ */
13
+ name?: string;
14
+ /**
15
+ * X-WR-TIMEZONE, as the calendar gives it.
16
+ */
17
+ timeZone?: string;
18
+ };
19
+ /**
20
+ * @maxItems 1000
21
+ */
22
+ events: {
23
+ /**
24
+ * The event's UID; for a repeat or a changed occurrence, the UID and the occurrence's start (20261014T140000Z).
25
+ */
26
+ id: string;
27
+ title?: string;
28
+ location?: string;
29
+ /**
30
+ * Plain text: markup stripped.
31
+ */
32
+ description?: string;
33
+ start: Time;
34
+ end: Time;
35
+ /**
36
+ * A whole-day event: start and end are dates, the end exclusive.
37
+ */
38
+ allDay?: true;
39
+ /**
40
+ * A floating event: start and end are local times with no zone, read in the screen's time zone.
41
+ */
42
+ floating?: true;
43
+ tentative?: true;
44
+ /**
45
+ * TRANSP:TRANSPARENT: the event does not make its calendar busy.
46
+ */
47
+ free?: true;
48
+ /**
49
+ * CLASS:PRIVATE or CONFIDENTIAL: its title, place and description are left out.
50
+ */
51
+ private?: true;
52
+ }[];
53
+ /**
54
+ * The window held more than 1,000 occurrences: the ones nearest the time asked are kept.
55
+ */
56
+ truncated?: true;
57
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-calendar.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The data service's news from an RSS 2.0 or Atom 1.0 feed (ADR 0069), each item's image its own or its page's Open Graph image.
3
+ */
4
+ export interface News {
5
+ feed: {
6
+ title: string;
7
+ url: string;
8
+ link?: string;
9
+ image?: string;
10
+ };
11
+ /**
12
+ * @maxItems 50
13
+ */
14
+ items: {
15
+ id?: string;
16
+ title: string;
17
+ /**
18
+ * Plain text: markup stripped.
19
+ */
20
+ summary?: string;
21
+ link: string;
22
+ published?: string;
23
+ author?: string;
24
+ /**
25
+ * The item's image through the data service's image proxy (a path from the service's root), so screens load only from Wyndlass.
26
+ */
27
+ image?: string;
28
+ }[];
29
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-news.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Why a symbol has no answer: the provider does not know it, the plan does not cover it, or there is no answer and no earlier one.
3
+ */
4
+ export type Reason = "unknown-symbol" | "not-in-plan" | "unavailable";
5
+ /**
6
+ * The data service's quotes from Twelve Data (ADR 0069, decision 9; WP-0103): each symbol asked for, in the order asked, or why it is missing. A value the provider does not give is left out.
7
+ */
8
+ export interface Quotes {
9
+ /**
10
+ * @maxItems 30
11
+ */
12
+ quotes: {
13
+ /**
14
+ * The symbol as asked, upper-cased: AAPL, EUR/USD, or with its exchange after a colon (TRP:TSX).
15
+ */
16
+ symbol: string;
17
+ name?: string;
18
+ exchange?: string;
19
+ /**
20
+ * The exchange's market identifier code (ISO 10383).
21
+ */
22
+ mic?: string;
23
+ /**
24
+ * The price's currency, where the provider gives one (not for currency pairs or crypto).
25
+ */
26
+ currency?: string;
27
+ /**
28
+ * The latest price.
29
+ */
30
+ price: number;
31
+ /**
32
+ * The price less the previous close.
33
+ */
34
+ change?: number;
35
+ /**
36
+ * The change as a percentage of the previous close.
37
+ */
38
+ percentChange?: number;
39
+ open?: number;
40
+ high?: number;
41
+ low?: number;
42
+ previousClose?: number;
43
+ /**
44
+ * Shares traded today, where there are shares.
45
+ */
46
+ volume?: number;
47
+ averageVolume?: number;
48
+ fiftyTwoWeek?: {
49
+ low: number;
50
+ high: number;
51
+ };
52
+ /**
53
+ * Whether its market is open now.
54
+ */
55
+ marketOpen: boolean;
56
+ /**
57
+ * When the price was quoted.
58
+ */
59
+ time: string;
60
+ /**
61
+ * True when the provider failed and this is the symbol's last quote, kept for up to a day.
62
+ */
63
+ stale: boolean;
64
+ }[];
65
+ /**
66
+ * @maxItems 30
67
+ */
68
+ missing: {
69
+ /**
70
+ * The symbol as asked, upper-cased: AAPL, EUR/USD, or with its exchange after a colon (TRP:TSX).
71
+ */
72
+ symbol: string;
73
+ reason: Reason;
74
+ }[];
75
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-quotes.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The data service's prices for one symbol over a range, from Twelve Data (ADR 0069, decision 9; WP-0103), for charts: the bars oldest first, or why the symbol is missing. A value the provider does not give is left out.
3
+ */
4
+ export interface Series {
5
+ /**
6
+ * The symbol as asked, upper-cased: AAPL, EUR/USD, or with its exchange after a colon (TRP:TSX).
7
+ */
8
+ symbol: string;
9
+ /**
10
+ * 1d: the latest trading day in 5-minute bars (the last 24 hours where a market never closes); 5d: 30-minute bars; 1m, 6m and 1y: days; 5y: weeks.
11
+ */
12
+ range: "1d" | "5d" | "1m" | "6m" | "1y" | "5y";
13
+ interval?: "5min" | "30min" | "1day" | "1week";
14
+ exchange?: string;
15
+ mic?: string;
16
+ currency?: string;
17
+ /**
18
+ * The provider's kind of instrument: Common Stock, ETF, Physical Currency, Digital Currency.
19
+ */
20
+ type?: string;
21
+ /**
22
+ * The exchange's time zone (IANA), which a trading day is counted in.
23
+ */
24
+ timeZone?: string;
25
+ /**
26
+ * For 1d and 5d: whether the market is open now, as its last bar is recent.
27
+ */
28
+ marketOpen?: boolean;
29
+ /**
30
+ * For 1d: the close before the day's first bar, which the day's change is measured from.
31
+ */
32
+ previousClose?: number;
33
+ /**
34
+ * @maxItems 400
35
+ */
36
+ points?: {
37
+ /**
38
+ * The bar's start.
39
+ */
40
+ time: string;
41
+ open: number;
42
+ high: number;
43
+ low: number;
44
+ close: number;
45
+ volume?: number;
46
+ }[];
47
+ /**
48
+ * Why a symbol has no answer: the provider does not know it, the plan does not cover it, or there is no answer and no earlier one.
49
+ */
50
+ missing?: "unknown-symbol" | "not-in-plan" | "unavailable";
51
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-series.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A column's key: set when the column is added and never changed, so a binding to it survives a relabel.
3
+ */
4
+ export type Key = string;
5
+ /**
6
+ * One version of a data table as screens read it (WP-0072, ADR 0072; ADR 0053 decision 7): a content-addressed JSON blob the manifest's dataSnapshots name. Bindings address a cell by its row's position in rows and its column's key. Values are typed: numbers as numbers, booleans as booleans, dates and date-times as ISO text; an empty cell is left out.
7
+ */
8
+ export interface DataTableSnapshot {
9
+ /**
10
+ * The table's id, as the manifest's dataSnapshots names it.
11
+ */
12
+ table: string;
13
+ version: number;
14
+ /**
15
+ * @minItems 1
16
+ * @maxItems 50
17
+ */
18
+ columns: [Column, ...Column[]];
19
+ /**
20
+ * @maxItems 5000
21
+ */
22
+ rows: {
23
+ [k: string]: (string | number | boolean) | undefined;
24
+ }[];
25
+ }
26
+ export interface Column {
27
+ key: Key;
28
+ label: string;
29
+ type: "text" | "number" | "currency" | "date" | "datetime" | "url" | "boolean";
30
+ }
@@ -0,0 +1,3 @@
1
+ // Copied from protocol/generated/ts/data-snapshot.d.ts by app-sdk/scripts/copy-protocol.mjs: edit the source, then run `pnpm --filter @wyndlass/app-sdk copy-protocol`.
2
+ /* Generated from protocol/schemas by scripts/generate.mjs. Do not edit. */
3
+ export {};