codeapp-js 1.0.1 → 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 (130) hide show
  1. package/AI/skills/autoreview/SKILL.md +69 -0
  2. package/AI/skills/connections/SKILL.md +4 -4
  3. package/AI/skills/dataverse/SKILL.md +4 -2
  4. package/AI/skills/frontend-design/SKILL.md +32 -20
  5. package/AI/skills/keyvault/SKILL.md +139 -0
  6. package/AI/skills/office365-groups/SKILL.md +46 -25
  7. package/AI/skills/office365-outlook/SKILL.md +56 -25
  8. package/AI/skills/office365-users/SKILL.md +41 -36
  9. package/AI/skills/sharepoint/SKILL.md +174 -31
  10. package/AI/skills/start/SKILL.md +38 -30
  11. package/codeApp/dist/connectors/autoreview.js +1654 -0
  12. package/codeApp/dist/connectors/office365groups.js +2995 -432
  13. package/{examples/outlook Demo/.power/schemas/office365/office365.Schema.json → codeApp/dist/connectors/office365outlook.js} +7439 -16
  14. package/codeApp/dist/connectors/office365users.js +2990 -349
  15. package/codeApp/dist/connectors/sharepoint.js +529 -308
  16. package/examples/combined demo/dist/connectors/office365outlook.js +28521 -0
  17. package/examples/combined demo/dist/connectors/office365users.js +3154 -0
  18. package/examples/combined demo/dist/index.js +2 -6
  19. package/examples/combined demo/power.config.json +1 -1
  20. package/examples/groups Demo/{.power/schemas/office365groups/office365groups.Schema.json → dist/connectors/office365groups.js } +3205 -2204
  21. package/examples/groups Demo/dist/index.js +1 -5
  22. package/examples/groups Demo/power.config.json +1 -1
  23. package/examples/myProfile/dist/connectors/office365users.js +3154 -0
  24. package/examples/myProfile/dist/index.js +1 -5
  25. package/examples/myProfile/power.config.json +1 -1
  26. package/examples/outlook Demo/dist/connectors/office365outlook.js +28521 -0
  27. package/examples/outlook Demo/dist/index.js +2 -5
  28. package/examples/outlook Demo/power.config.json +1 -1
  29. package/examples/sharePoint Demo/dist/connectors/sharepoint.js +687 -0
  30. package/examples/sharePoint Demo/dist/index.js +86 -127
  31. package/examples/sharePoint Demo/power.config.json +1 -1
  32. package/package.json +1 -1
  33. package/codeApp/.power/schemas/appschemas/dataSourcesInfo.ts +0 -6275
  34. package/codeApp/.power/schemas/jira/jira.Schema.json +0 -6903
  35. package/codeApp/.power/schemas/keyvault/keyvault.Schema.json +0 -1600
  36. package/codeApp/.power/schemas/office365groups/office365groups.Schema.json +0 -2204
  37. package/codeApp/.power/schemas/teams/teams.Schema.json +0 -11112
  38. package/codeApp/dist/connectors/outlook.js +0 -1393
  39. package/codeApp/src/generated/index.ts +0 -12
  40. package/codeApp/src/generated/models/AzureKeyVaultModel.ts +0 -107
  41. package/codeApp/src/generated/models/JiraModel.ts +0 -501
  42. package/codeApp/src/generated/models/Office365GroupsModel.ts +0 -363
  43. package/codeApp/src/generated/models/Office365OutlookModel.ts +0 -2046
  44. package/codeApp/src/generated/models/Office365UsersModel.ts +0 -254
  45. package/codeApp/src/generated/services/AzureKeyVaultService.ts +0 -257
  46. package/codeApp/src/generated/services/JiraService.ts +0 -1124
  47. package/codeApp/src/generated/services/Office365GroupsService.ts +0 -326
  48. package/codeApp/src/generated/services/Office365OutlookService.ts +0 -2476
  49. package/codeApp/src/generated/services/Office365UsersService.ts +0 -358
  50. package/examples/apps/kanban/dist/dataverse.js +0 -94
  51. package/examples/apps/kanban/dist/environmentVar.js +0 -55
  52. package/examples/apps/kanban/dist/index.css +0 -605
  53. package/examples/apps/kanban/dist/index.html +0 -21
  54. package/examples/apps/kanban/dist/index.js +0 -860
  55. package/examples/apps/kanban/dist/office365groups.js +0 -97
  56. package/examples/apps/kanban/dist/office365users.js +0 -451
  57. package/examples/apps/kanban/dist/outlook.js +0 -162
  58. package/examples/apps/kanban/dist/power-apps-data.js +0 -2953
  59. package/examples/apps/kanban/dist/sharepoint.js +0 -435
  60. package/examples/apps/kanban/power.config.json +0 -35
  61. package/examples/apps/kanban/src/generated/index.ts +0 -14
  62. package/examples/apps/kanban/src/generated/models/Office365GroupsModel.ts +0 -363
  63. package/examples/apps/kanban/src/generated/models/Office365OutlookModel.ts +0 -2046
  64. package/examples/apps/kanban/src/generated/models/Office365UsersModel.ts +0 -254
  65. package/examples/apps/kanban/src/generated/services/Office365GroupsService.ts +0 -326
  66. package/examples/apps/kanban/src/generated/services/Office365OutlookService.ts +0 -2476
  67. package/examples/apps/kanban/src/generated/services/Office365UsersService.ts +0 -358
  68. package/examples/apps/planning Poker/additional files/AgilePoker_1_0_0_1.zip +0 -0
  69. package/examples/apps/planning Poker/additional files/PokerTables_1_0_0_1.zip +0 -0
  70. package/examples/apps/planning Poker/additional files/customizations (tables).xml +0 -6429
  71. package/examples/apps/planning Poker/additional files/dataverse-tables.json +0 -165
  72. package/examples/apps/planning Poker/additional files/readme.md +0 -122
  73. package/examples/apps/planning Poker/dist/dataverse.js +0 -78
  74. package/examples/apps/planning Poker/dist/index.html +0 -198
  75. package/examples/apps/planning Poker/dist/index.js +0 -955
  76. package/examples/apps/planning Poker/dist/power-apps-data.js +0 -2953
  77. package/examples/apps/planning Poker/dist/styles.css +0 -815
  78. package/examples/apps/planning Poker/power.config.json +0 -50
  79. package/examples/apps/solution explorer/dist/codeapp.js +0 -1098
  80. package/examples/apps/solution explorer/dist/icon-512.png +0 -0
  81. package/examples/apps/solution explorer/dist/index.html +0 -80
  82. package/examples/apps/solution explorer/dist/index.js +0 -735
  83. package/examples/apps/solution explorer/dist/power-apps-data.js +0 -3007
  84. package/examples/apps/solution explorer/dist/styles.css +0 -571
  85. package/examples/apps/solution explorer/power.config.json +0 -151
  86. package/examples/apps/todo/dist/dataverse.js +0 -64
  87. package/examples/apps/todo/dist/icon192.png +0 -0
  88. package/examples/apps/todo/dist/index.html +0 -75
  89. package/examples/apps/todo/dist/index.js +0 -9
  90. package/examples/apps/todo/dist/power-apps-data.js +0 -2953
  91. package/examples/apps/todo/dist/renderer.js +0 -375
  92. package/examples/apps/todo/dist/styles.css +0 -691
  93. package/examples/apps/todo/power.config.json +0 -35
  94. package/examples/combined demo/.power/schemas/appschemas/dataSourcesInfo.ts +0 -6275
  95. package/examples/combined demo/.power/schemas/jira/jira.Schema.json +0 -6903
  96. package/examples/combined demo/.power/schemas/keyvault/keyvault.Schema.json +0 -1600
  97. package/examples/combined demo/.power/schemas/teams/teams.Schema.json +0 -11112
  98. package/examples/combined demo/dist/office365users.js +0 -513
  99. package/examples/combined demo/dist/outlook.js +0 -1393
  100. package/examples/combined demo/src/generated/index.ts +0 -12
  101. package/examples/combined demo/src/generated/models/AzureKeyVaultModel.ts +0 -107
  102. package/examples/combined demo/src/generated/models/JiraModel.ts +0 -501
  103. package/examples/combined demo/src/generated/models/Office365GroupsModel.ts +0 -363
  104. package/examples/combined demo/src/generated/models/Office365OutlookModel.ts +0 -2046
  105. package/examples/combined demo/src/generated/models/Office365UsersModel.ts +0 -254
  106. package/examples/combined demo/src/generated/services/AzureKeyVaultService.ts +0 -257
  107. package/examples/combined demo/src/generated/services/JiraService.ts +0 -1124
  108. package/examples/combined demo/src/generated/services/Office365GroupsService.ts +0 -326
  109. package/examples/combined demo/src/generated/services/Office365OutlookService.ts +0 -2476
  110. package/examples/combined demo/src/generated/services/Office365UsersService.ts +0 -358
  111. package/examples/groups Demo/.power/schemas/appschemas/dataSourcesInfo.ts +0 -613
  112. package/examples/groups Demo/dist/office365groups.js +0 -642
  113. package/examples/groups Demo/src/generated/index.ts +0 -10
  114. package/examples/groups Demo/src/generated/models/Office365GroupsModel.ts +0 -363
  115. package/examples/groups Demo/src/generated/services/Office365GroupsService.ts +0 -326
  116. package/examples/myProfile/dist/office365users.js +0 -517
  117. package/examples/outlook Demo/.power/schemas/appschemas/dataSourcesInfo.ts +0 -6512
  118. package/examples/outlook Demo/dist/outlook.js +0 -1393
  119. package/examples/outlook Demo/src/generated/index.ts +0 -10
  120. package/examples/outlook Demo/src/generated/models/Office365OutlookModel.ts +0 -2046
  121. package/examples/outlook Demo/src/generated/services/Office365OutlookService.ts +0 -2476
  122. package/examples/sharePoint Demo/dist/sharepoint.js +0 -466
  123. package/examples/sharePoint Demo/src/generated/index.ts +0 -14
  124. package/examples/sharePoint Demo/src/generated/models/Office365GroupsModel.ts +0 -363
  125. package/examples/sharePoint Demo/src/generated/models/Office365OutlookModel.ts +0 -2046
  126. package/examples/sharePoint Demo/src/generated/models/Office365UsersModel.ts +0 -254
  127. package/examples/sharePoint Demo/src/generated/services/Office365GroupsService.ts +0 -326
  128. package/examples/sharePoint Demo/src/generated/services/Office365OutlookService.ts +0 -2476
  129. package/examples/sharePoint Demo/src/generated/services/Office365UsersService.ts +0 -358
  130. package/readme.md +0 -590
@@ -5,37 +5,45 @@ description: "Use when: building or debugging Office 365 Users connector flows i
5
5
 
6
6
  # Office 365 Users Connector Guide
7
7
 
8
- > Agent limitation: do not use CLI commands directly from chat for Office 365 Users setup. Use the built-in Sync Connections and Deploy buttons instead.
8
+ Do not use CLI PAC commands to get connecctor models or services,
9
+ use `codeApp/dist/connectors/office365users.js` as the repo source of truth.
9
10
 
10
- ## Core Rule
11
-
12
- The wrapper in `dev files/office365users.js` is the repo-local source of truth.
13
-
14
- - It uses `office365users` as the connector data-source name.
15
- - It includes inline metadata for the supported operations.
16
- - It preserves older naming compatibility, but the main search operation used by the wrapper is `SearchUserV2`.
17
11
 
18
12
  ## power.config.json
19
13
 
20
- Expose `office365users` in the connection reference `dataSources` array.
14
+ Always read the current `power.config.json` before editing it.
15
+
16
+ Ensure `"id": "/providers/Microsoft.PowerApps/apis/shared_office365users"` exists.
21
17
 
22
18
  ```json
23
- {
24
- "connectionReferences": {
25
- "usersConnection": {
19
+ "connectionReferences": {
20
+ "office365users": {
26
21
  "id": "/providers/Microsoft.PowerApps/apis/shared_office365users",
27
22
  "displayName": "Office 365 Users",
28
- "dataSources": ["office365users"],
23
+ "dataSources": [
24
+ "office365users"
25
+ ],
26
+ "authenticationType": null,
27
+ "sharedConnectionId": null,
29
28
  "dataSets": {}
30
29
  }
31
- }
32
30
  }
33
31
  ```
34
32
 
35
- ## Public Helper Surface
33
+ Rules for editing `power.config.json`:
34
+
35
+ - Preserve existing keys such as `sharedConnectionId`, `authenticationType`, and other working connection metadata.
36
+ - If the app uses Dataverse environment variables, also load the environment-variables skill.
37
+
38
+ ## Core Rule
39
+
40
+ Prefer the exported helper layer instead of wiring raw connector operations directly in app code.
36
41
 
37
- The wrapper exports:
42
+ ## Action Helper Surface
38
43
 
44
+ - `callUsersOperation(operationName, parameters)`
45
+ - `openUsersHttpRequest(options)`
46
+ - `updateMyProfile(profile)`
39
47
  - `getMyProfile(options)`
40
48
  - `getUserProfile(userId, options)`
41
49
  - `getManager(userId, options)`
@@ -43,36 +51,33 @@ The wrapper exports:
43
51
  - `getMyTrendingDocuments(options)`
44
52
  - `getTrendingDocuments(userId, options)`
45
53
  - `getRelevantPeople(userId)`
46
- - `updateMyProfile(profile)`
47
54
  - `updateMyPhoto(bodyOrOptions, contentType)`
48
55
  - `getUserPhotoMetadata(userId)`
49
56
  - `getUserPhoto(userId)`
50
57
  - `searchForUsers(options)`
51
- - `openUsersHttpRequest(options)`
52
- - `callUsersOperation(operationName, parameters)`
53
58
 
54
- ## Important Wrapper Behavior
59
+ ## Latest Action Defaults
55
60
 
56
- - `select` can be an array or a comma-separated string.
57
- - `getDirectReports(...)` supports `top` and select options.
58
- - `searchForUsers(...)` uses `searchTerm`, `top`, `isSearchTermRequired`, and `skipToken`.
59
- - `searchForUsers(...)` accepts `nextLink` and legacy `skip` as compatibility inputs that the wrapper converts into `skipToken`.
60
- - `UserPhoto_V2` returns `image/jpeg`.
61
+ - Profile helpers default to the V2 profile and manager actions.
62
+ - `getDirectReports(...)` defaults to `DirectReports_V2`.
63
+ - `getUserPhoto(...)` uses `UserPhoto_V2`.
64
+ - `searchForUsers(...)` uses `SearchUserV2`.
65
+ - `searchForUsers(...)` accepts `nextLink` and `skip` aliases and converts them into `skipToken`.
61
66
 
62
- ## Raw HTTP Calls
67
+ ## HTTP Escape Hatch
63
68
 
64
- `openUsersHttpRequest(...)` does not use the simple `headers` object shape directly.
69
+ `openUsersHttpRequest(...)` maps friendly inputs to connector fields:
65
70
 
66
- The wrapper maps friendly inputs into connector fields:
71
+ - `uri` -> `Uri`
72
+ - `method` -> `Method`
73
+ - `body` -> `Body`
74
+ - `contentType` -> `ContentType`
75
+ - `customHeaders[0..4]` -> `CustomHeader1..5`
67
76
 
68
- - `Uri`
69
- - `Method`
70
- - `Body`
71
- - `ContentType`
72
- - `CustomHeader1..5`
77
+ Use this only when no helper exists for the action you need.
73
78
 
74
79
  ## Debugging
75
80
 
76
- - If search pagination is broken, verify the code is passing `skipToken` or `nextLink`, not `$skip`.
77
- - If HTTP requests fail, check whether the wrapper is being fed connector-style fields through `openUsersHttpRequest(...)` rather than raw fetch options.
78
- - Keep the existing helper names stable and widen input support instead of replacing them.
81
+ - If search pagination fails, pass `skipToken` or `nextLink`, not `$skip`.
82
+ - If HTTP requests fail, verify you are sending connector-style fields through `openUsersHttpRequest(...)`.
83
+ - Keep helper names stable and widen alias support instead of introducing another wrapper.
@@ -3,22 +3,42 @@ name: sharepoint
3
3
  description: "Use when: building or debugging SharePoint list, library, file, or HTTP-request flows in a Power Apps Code App, including list-id or environment-variable-based setup."
4
4
  ---
5
5
 
6
- # SharePoint Connector Guide
6
+ # SharePoint App Builder Guide
7
7
 
8
- > Agent limitation: do not use CLI commands directly from chat for SharePoint setup. Use the built-in Sync Connections and Deploy buttons instead.
8
+ Use this skill when an app needs SharePoint list CRUD, file operations, library metadata, or a last-resort SharePoint HTTP request through `./connectors/sharepoint.js`.
9
9
 
10
- ## Workflow
10
+ Use the working OG-style SharePoint wrapper pattern from this repo as the reference: siteUrl-based connector paths, wrapper-side site URL encoding, `GetTables` lookup for the connector table token, and standard CRUD after resolution.
11
11
 
12
- Before writing code, prefer these connection approaches:
12
+ Do not use CLI setup flows from chat. Use the built-in Auth, Sync Connections, and Deploy buttons.
13
+
14
+ ## First Questions To Ask
15
+
16
+ Ask only the minimum needed to choose the right setup and write working code:
17
+
18
+ 1. Is this app working with a SharePoint list, files in a document library, or a custom SharePoint HTTP endpoint?
19
+ 2. What is the exact SharePoint site URL?
20
+ 3. Do you already have the SharePoint list ID?
21
+ 4. If not, do you at least know the list name for one-time resolution?
22
+ 5. Should config come from hardcoded app config or Dataverse environment variables?
23
+ 6. Does the current `power.config.json` already contain `connectionReferences.sharepointonline`?
24
+ 7. Which operations are required: read, create, update, delete, file create/move/delete, or custom request only?
25
+ 8. Are there complex SharePoint fields involved such as person, lookup, or multi-value choice columns?
26
+
27
+ Preferred configuration order:
13
28
 
14
29
  - A: site URL + list ID
15
- - B: environment variables that resolve the site URL and list ID
30
+ - B: environment variables that resolve site URL + list ID
31
+ - C: site URL + list name only, resolved once through `resolveSharePointList(...)`
32
+
33
+ Do not ask for a list name as the primary CRUD identifier. If the user only knows the list name, use it only as a lookup hint.
16
34
 
17
- Do not ask the user for a list name as the primary CRUD identifier. If they only know the list name, use `listTables(...)` once to discover the connector table ID and then continue with list-ID operations.
35
+ Schemas are often stored in the 'agent' folder.
18
36
 
19
37
  ## power.config.json
20
38
 
21
- Expose `sharepointonline` in `connectionReferences`.
39
+ Always read the current `power.config.json` before editing it.
40
+
41
+ Ensure `"id": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline"` exists and ` "dataSources": ["sharepointonline"]`.
22
42
 
23
43
  ```json
24
44
  {
@@ -33,45 +53,168 @@ Expose `sharepointonline` in `connectionReferences`.
33
53
  }
34
54
  ```
35
55
 
36
- No Dataverse tables are needed unless the app also uses environment variables.
37
-
38
- ## Helper Surface
56
+ Rules for editing `power.config.json`:
39
57
 
40
- The wrapper in `dev files/sharepoint.js` exports:
58
+ - Preserve existing keys such as `sharedConnectionId`, `authenticationType`, and other working connection metadata.
59
+ - No Dataverse tables are needed for basic SharePoint-only apps.
60
+ - If the app uses Dataverse environment variables, also load the environment-variables skill and add the two Dataverse environment-variable tables there.
41
61
 
42
- - List ID pattern: `getItems`, `getSpItem`, `createSpItem`, `updateSpItem`, `deleteSpItem`
43
- - Generic helpers: `callSharePointOperation`, `sendHttpRequest`, `listTables`, `listLibrary`
44
- - File helpers: `createFile`, `updateFile`, `deleteFile`, `moveFile`, `getFileMetadata`
62
+ ## Core App Rules
45
63
 
46
- The list-ID helpers use the SharePoint connector table API. `sendHttpRequest(...)` remains available only as an advanced escape hatch when there is no dedicated helper for the operation you need.
64
+ - Prefer dedicated SharePoint helpers over raw HTTP.
65
+ - Keep SharePoint list discovery inside `sharepoint.js`, not in app pages or components.
66
+ - Do not pre-encode the site URL. Pass the raw URL string and let the wrapper encode it.
67
+ - If a list ID is known, still prefer resolving through `resolveSharePointList(...)` once at startup so the wrapper can match the connector table token.
68
+ - If the app only knows a list name, use `resolveSharePointList(...)` or a by-list helper and let the wrapper do `listTables(...)` lookup.
47
69
 
48
- ## Important Corrections
70
+ When generating or fixing a local `dist/connectors/sharepoint.js` wrapper:
49
71
 
50
- - The single-item and CRUD helpers for the list-ID path are `getSpItem`, `createSpItem`, `updateSpItem`, and `deleteSpItem` in this repo.
51
- - `sharepoint.js` encodes `siteUrl` internally with `encodeURIComponent(...)`. Do not pre-encode the URL before passing it in.
52
- - For environment-variable based setup, import `getEnvironmentVariable(...)` from `./codeapp.js`, not from a separate `environmentVar.js` helper.
72
+ - initialize the connector client with `getClient(dataSourcesInfo)`
73
+ - keep the working SharePoint action parameter names aligned with the OG contract: `siteUrl`, `table`, `item`, and the standard CRUD/query names
74
+ - keep reusable list-resolution helpers in the wrapper
75
+ - preserve `callSharePointOperation(...)` as the escape hatch for supported actions
76
+ - use `sendHttpRequest(...)` only when no dedicated helper exists
53
77
 
54
- ## Example Imports
78
+ ## Recommended Startup Pattern
55
79
 
56
- Approach A:
80
+ For list-backed apps, resolve the list once during startup and keep the returned access object in app state.
57
81
 
58
82
  ```js
59
- import { getItems, getSpItem, createSpItem, updateSpItem, deleteSpItem, listTables } from './sharepoint.js';
83
+ import {
84
+ createSpItemByList,
85
+ deleteSpItemByList,
86
+ getItemsByList,
87
+ resolveSharePointList,
88
+ updateSpItemByList,
89
+ } from './connectors/sharepoint.js';
90
+
91
+ const oAppConfig = {
92
+ sSiteUrl: 'https://tenant.sharepoint.com/sites/example',
93
+ sListId: '00000000-0000-0000-0000-000000000000',
94
+ sListName: 'Tasks',
95
+ };
96
+
97
+ const oListAccess = await resolveSharePointList(oAppConfig.sSiteUrl, {
98
+ listId: oAppConfig.sListId,
99
+ listName: oAppConfig.sListName,
100
+ });
101
+
102
+ const aItems = await getItemsByList(oListAccess.sSiteUrl, oListAccess, { top: 200 });
103
+ await createSpItemByList(oListAccess.sSiteUrl, oListAccess, { Title: 'New item' });
104
+ await updateSpItemByList(oListAccess.sSiteUrl, oListAccess, 1, { Title: 'Updated item' });
105
+ await deleteSpItemByList(oListAccess.sSiteUrl, oListAccess, 1);
60
106
  ```
61
107
 
62
- Approach B:
108
+ Why this is the preferred pattern:
63
109
 
64
- ```js
65
- import { getItems, getSpItem, createSpItem, updateSpItem, deleteSpItem } from './sharepoint.js';
66
- ```
110
+ - it keeps list lookup and fallback logic inside the wrapper
111
+ - it works whether the connector resolves a table token or falls back to the configured list ID
112
+ - it matches the working SharePoint demo app in this repo
113
+
114
+ ## Function Surface And Correct Usage
115
+
116
+ Generic helpers:
117
+
118
+ - `callSharePointOperation(operationName, parameters)`
119
+ - `sendHttpRequest({ method, uri, headers, body })`
120
+ - `listTables(siteUrl)`
121
+ - `listLibrary(siteUrl)`
122
+ - `resolveSharePointList(siteUrl, listReference)`
123
+
124
+ List-ID CRUD helpers:
125
+
126
+ - `getItems(siteUrl, listId, { filter, orderBy, top, skip })`
127
+ - `getSpItem(siteUrl, listId, itemId)`
128
+ - `createSpItem(siteUrl, listId, fields)`
129
+ - `updateSpItem(siteUrl, listId, itemId, changedFields)`
130
+ - `deleteSpItem(siteUrl, listId, itemId)`
131
+
132
+ By-list CRUD helpers:
133
+
134
+ - `getItemsByList(siteUrl, listReference, queryOptions)`
135
+ - `getSpItemByList(siteUrl, listReference, itemId)`
136
+ - `createSpItemByList(siteUrl, listReference, fields)`
137
+ - `updateSpItemByList(siteUrl, listReference, itemId, changedFields)`
138
+ - `deleteSpItemByList(siteUrl, listReference, itemId)`
139
+
140
+ File helpers:
67
141
 
68
- Approach C:
142
+ - `createFile(siteUrl, folderPath, fileName, fileContent)`
143
+ - `updateFile(siteUrl, fileId, fileContent)`
144
+ - `deleteFile(siteUrl, fileId)`
145
+ - `moveFile(siteUrl, sourceFileId, destinationFolderPath, newFileName)`
146
+ - `getFileMetadata(siteUrl, fileId)`
147
+
148
+ Important behavior:
149
+
150
+ - `resolveSharePointList(...)` returns both generic keys and app-friendly aliases: `siteUrl`, `listId`, `listName`, `sSiteUrl`, `sListId`, `sListName`, plus `table` and lookup metadata.
151
+ - `getItemsByList(...)` and the other by-list helpers accept a list name, list ID object, or resolved access object.
152
+ - Create and update payloads must be plain objects.
153
+ - Item IDs can be strings or numbers.
154
+ - Query options such as `top` and `skip` must be numeric if supplied.
155
+ - `moveFile(...)` can rename during the move when `newFileName` is supplied.
156
+ - `sendHttpRequest(...)` expects `{ method, uri, headers, body }` on the OG SharePoint wrapper contract.
157
+
158
+ ## Response Handling In App Code
159
+
160
+ SharePoint item reads may come back as an array or inside a nested result shape. Normalize collections in app code before rendering tables or computing counts.
69
161
 
70
162
  ```js
71
- import { getEnvironmentVariable } from './codeapp.js';
72
- import { getItems, createSpItem, updateSpItem, deleteSpItem } from './sharepoint.js';
163
+ function normalizeCollection(oPayload) {
164
+ if (Array.isArray(oPayload)) {
165
+ return oPayload;
166
+ }
167
+
168
+ const aCandidates = [
169
+ oPayload && oPayload.value,
170
+ oPayload && oPayload.items,
171
+ oPayload && oPayload.results,
172
+ oPayload && oPayload.body,
173
+ oPayload && oPayload.data,
174
+ oPayload && oPayload.result,
175
+ oPayload && oPayload.response,
176
+ oPayload && oPayload.d && oPayload.d.results,
177
+ ];
178
+
179
+ return aCandidates.find(Array.isArray) || [];
180
+ }
73
181
  ```
74
182
 
75
- ## Additional Build Nudge
183
+ ## Environment Variable Pattern
184
+
185
+ If the app should not hardcode the site URL or list ID, load the environment-variables skill too.
186
+
187
+ Rules:
188
+
189
+ - Ask for the exact existing schema names.
190
+ - Read values through `getEnvironmentVariable(...)` from `./codeapp.js`.
191
+ - Update `power.config.json` with the Dataverse environment-variable tables only when the app actually uses them.
192
+ - If a Data Source environment variable stores JSON, parse it before extracting the site URL or list ID.
193
+
194
+ ## Error Handling
195
+
196
+ The wrapper already converts many connector failures into readable errors such as `SharePoint GetItems failed: ...`, so app code should display those messages rather than swallowing them.
197
+
198
+ Keep separate loading and submit flags in UI state so refresh, create, update, and delete actions do not overlap silently.
199
+
200
+ ## Debugging Checklist
201
+
202
+ - If the failure happens before any connector call, verify `initSharePointClient()` returns `getClient(dataSourcesInfo)` and the wrapper was not replaced with a stub.
203
+ - If SharePoint calls suddenly return 404 after switching wrapper style, fall back to the OG siteUrl-based contract instead of a generated dataset or OData-style surface.
204
+ - If you see `Provide a SharePoint listId or listName.`, the app never supplied startup list configuration.
205
+ - If you see `SharePoint item payload must be an object.`, the app passed a string, `FormData`, or another invalid payload.
206
+ - If you see `SharePoint site URL is required.`, the config source is empty or malformed.
207
+ - If list resolution fails, confirm the site URL and list ID belong to the same site.
208
+ - If the user only knows a list name, let the wrapper perform `listTables(...)` lookup instead of building lookup logic in the page.
209
+ - Do not manually call `encodeURIComponent(siteUrl)` before passing the site URL to the wrapper.
210
+ - Use `enableDebugger()` during app development so `_dbgWrap(...)` traces are available.
211
+ - Use `sendHttpRequest(...)` only as an escape hatch when there is no dedicated SharePoint helper.
212
+
213
+ ## Summary Rules
76
214
 
77
- When a SharePoint build introduces or depends on specific lists and columns, create an `agent/listSchema.json` artifact so the user can recreate the list structure correctly.
215
+ - Ask for site URL and list ID first.
216
+ - Treat list name as a fallback lookup hint, not the primary identifier.
217
+ - Update `power.config.json` by merging in `connectionReferences.sharepointonline`, not by overwriting working connection metadata.
218
+ - Resolve the list once at startup and keep the resolved access object in app state.
219
+ - Prefer by-list helpers in app code and keep list lookup inside `sharepoint.js`.
220
+ - Show connector error messages directly in the UI.
@@ -1,46 +1,54 @@
1
1
  ---
2
- name: frontend-design
3
- description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
2
+ name: start
3
+ aliases: start-codeapp
4
+ description: Start skill for new project setup. Use this skill when starting a fresh app build or UI build so the agent confirms theme direction, offers mockups, and only then implements files.
4
5
  ---
5
6
 
6
- # Frontend Design Skill
7
+ # Start: New Project Setup
7
8
 
8
- This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
9
+ This skill applies only when the project is new (the decision log has no prior decisions). It ensures the agent gathers style and colour preferences and offers mockup creation before building.
9
10
 
10
- The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.
11
+ ## folder setup
12
+ The current folder should have a power-config.json file and a dist folder. If it does not the run the cap newApp command with a given name or one created by you.
11
13
 
12
- ## Design Thinking
14
+ ## Style and Colour Direction
13
15
 
14
- Before coding, understand the context and commit to a BOLD aesthetic direction:
16
+ Before building any creative UI (website, app, dashboard, landing page, etc.):
15
17
 
16
- - **Purpose:** What problem does this interface solve? Who uses it?
17
- - **Tone:** Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
18
- - **Constraints:** Technical requirements (framework, performance, accessibility).
19
- - For CAP code apps, treat workspace configuration and loaded skills as the source of truth for technical constraints. If `power.config.json` or the agent prompt already fixes the stack, connector, or app name, do not ask the user to restate them.
20
- - **Differentiation:** What makes this UNFORGETTABLE? What's the one thing someone will remember?
18
+ 1. Check if the user's message already includes colour, theme, or style direction.
19
+ 2. If style direction is **not** provided, ask: _"What colours or overall theme do you want for this site or app? If you do not want to choose, tell me to proceed and I will decide the visual direction myself."_.
20
+ When interactive user input is available, ask through the interactive question flow and continue in the same session after the user answers.
21
+ Only stop and wait for a later run when interactive user input is not available.
22
+ 3. If the user says to decide yourself, choose a bold and distinctive visual direction. Do **not** ask again.
23
+ 4. Record the chosen style and colour direction in `agent/decision-log.md` under **Custom Requirements**.
24
+ 5. Use the frontend-design skill when creating the UI, including for any mockups.
21
25
 
22
- **CRITICAL:** Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
26
+ **Important:** The agent must have colour and style direction before building. Never start building a creative UI without it — either the user provides it or you decide it.
23
27
 
24
- Then implement working code in the project's required stack. Default to plain HTML/CSS/JS when the workspace instructions or agent prompt do not explicitly require a framework. Do not ask the user to choose React, Vue, or another framework unless the project requirements are genuinely ambiguous.
28
+ ## Mockup Offer
25
29
 
26
- - Production-grade and functional
27
- - Visually striking and memorable
28
- - Cohesive with a clear aesthetic point-of-view
29
- - Meticulously refined in every detail
30
+ After style direction is established (or if the user's prompt already includes it):
30
31
 
31
- ## Frontend Aesthetics Guidelines
32
+ 0. If a TODO checklist exists in `agent/decision-log.md`, ensure it includes these setup steps explicitly before any build tasks: theme/colour confirmation, mockup offer, optional mockup creation, then implementation.
33
+ 1. Check if mockup files already exist in the `agent/` folder. If they do, skip this step.
34
+ 2. If no mockups exist, ask: _"Do you want me to create 5 creative and unique mockups in agent/ for you to pick from? Reply yes or no."_.
35
+ When interactive user input is available, ask through the interactive question flow and continue in the same session after the user answers.
36
+ Only stop and wait for a later run when interactive user input is not available.
37
+ 3. If the user says yes, create 5 **CREATIVE** and **DISTINCT** HTML mockup options in `agent/`, using the frontend-design skill, then stop so the user can pick one. Name them clearly, for example `agent/mockup-1.html` through `agent/mockup-5.html`.
38
+ Each mockup must be a self-contained, one-page HTML file that opens directly in a browser, shows the visual design, and includes lightweight interaction such as search filtering, panel toggles, or compose drawer open/close behavior. It is a visual prototype only, not a fully functional app.
39
+ Create the files sequentially as you work: fully write `agent/mockup-1.html` before starting `agent/mockup-2.html`, and continue one mockup at a time instead of batching all file writes at the end.
40
+ 4. If the user says no or wants to skip, proceed directly to building in the same session.
41
+ 5. Never say a mockup is ready unless the corresponding files have actually been created in `agent/`.
32
42
 
33
- Focus on:
43
+ ## Interactive Sessions
34
44
 
35
- - **Typography:** Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
36
- - **Color & Theme:** Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
37
- - **Motion:** Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Only use framework-specific animation libraries when the project already uses that framework. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
38
- - **Spatial Composition:** Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
39
- - **Backgrounds & Visual Details:** Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
40
- NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
45
+ - If the runtime says interactive user input is available, do not end the turn after a required clarification if the answer you need can be gathered through the interactive question flow.
46
+ - After the user answers the required setup questions, continue with planning and implementation immediately.
47
+ - Do not ask optional open-ended follow-up questions such as "let me know if you have more preferences" before producing the first concrete implementation unless the task is still blocked.
48
+ - If the user asks how to view a mockup, point them to the actual generated files in `agent/`. Do not ask them to choose a framework when the project structure already dictates the implementation stack.
41
49
 
42
- Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
50
+ ## When to Skip
43
51
 
44
- IMPORTANT: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
45
-
46
- Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.
52
+ - If the user's prompt already contains style guidance **and** they explicitly decline mockups, proceed directly to building.
53
+ - If the user's request is not a creative build (e.g. bug fix, add feature, deploy, refactor), skip this skill entirely.
54
+ - If mockups already exist in the `agent/` folder, skip the mockup offer.