@hyperdreamer/pi-webui 1.6.1

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 (276) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +148 -0
  3. package/dist/cli.js +975 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client/apple-touch-icon.png +0 -0
  6. package/dist/client/assets/CodeViewer-aB4ZVzEu.js +4 -0
  7. package/dist/client/assets/UnifiedDiffViewer-f8X7aTkU.js +39 -0
  8. package/dist/client/assets/index-Cffeusjy.js +6022 -0
  9. package/dist/client/assets/vendor-editor-core-vUi74DnD.js +12 -0
  10. package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +46 -0
  11. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
  12. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
  13. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
  14. package/dist/client/favicon.svg +8 -0
  15. package/dist/client/index.html +65 -0
  16. package/dist/client/manifest.webmanifest +24 -0
  17. package/dist/client/pwa-icon-192.png +0 -0
  18. package/dist/client/pwa-icon-512.png +0 -0
  19. package/dist/config.js +417 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/docker/piWebUiDockerCommandPlan.js +211 -0
  22. package/dist/docker/piWebUiDockerCommandPlan.js.map +1 -0
  23. package/dist/nativeServices/serviceDoctor.js +480 -0
  24. package/dist/nativeServices/serviceDoctor.js.map +1 -0
  25. package/dist/nativeServices/serviceInstall.js +35 -0
  26. package/dist/nativeServices/serviceInstall.js.map +1 -0
  27. package/dist/nativeServices/servicePlan.js +358 -0
  28. package/dist/nativeServices/servicePlan.js.map +1 -0
  29. package/dist/nativeServices/serviceProbe.js +447 -0
  30. package/dist/nativeServices/serviceProbe.js.map +1 -0
  31. package/dist/nativeServices/serviceRendering.js +122 -0
  32. package/dist/nativeServices/serviceRendering.js.map +1 -0
  33. package/dist/pi-webui-plugins/info/package.json +9 -0
  34. package/dist/pi-webui-plugins/info/pi-webui-plugin.js +51 -0
  35. package/dist/pi-webui-plugins/updates/package.json +9 -0
  36. package/dist/pi-webui-plugins/updates/pi-webui-plugin.js +185 -0
  37. package/dist/pi-webui-plugins/updates/updatesLogic.js +97 -0
  38. package/dist/pi-webui-plugins/workspace-tasks/config.js +91 -0
  39. package/dist/pi-webui-plugins/workspace-tasks/package.json +9 -0
  40. package/dist/pi-webui-plugins/workspace-tasks/pi-webui-plugin.js +48 -0
  41. package/dist/pi-webui-plugins/workspace-tasks/taskRunner.js +12 -0
  42. package/dist/pi-webui-plugins/workspace-tasks/tasksPanelElement.js +288 -0
  43. package/dist/pi-webui-plugins/workspace-tasks/workspaceTasksClient.js +47 -0
  44. package/dist/piWebUiVersionReport.js +225 -0
  45. package/dist/piWebUiVersionReport.js.map +1 -0
  46. package/dist/plugin-api/unstable.d.ts +22 -0
  47. package/dist/plugin-api.d.ts +199 -0
  48. package/dist/server/activeAgentProfileProvider.js +25 -0
  49. package/dist/server/activeAgentProfileProvider.js.map +1 -0
  50. package/dist/server/activity/workspaceActivityRoutes.js +4 -0
  51. package/dist/server/activity/workspaceActivityRoutes.js.map +1 -0
  52. package/dist/server/activity/workspaceActivityService.js +98 -0
  53. package/dist/server/activity/workspaceActivityService.js.map +1 -0
  54. package/dist/server/app.js +211 -0
  55. package/dist/server/app.js.map +1 -0
  56. package/dist/server/browserMessageProjection.js +56 -0
  57. package/dist/server/browserMessageProjection.js.map +1 -0
  58. package/dist/server/configRoutes.js +309 -0
  59. package/dist/server/configRoutes.js.map +1 -0
  60. package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
  61. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
  62. package/dist/server/diagnostics/nodePtySpawnHelper.js +135 -0
  63. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -0
  64. package/dist/server/git/gitEnv.js +15 -0
  65. package/dist/server/git/gitEnv.js.map +1 -0
  66. package/dist/server/git/gitService.js +123 -0
  67. package/dist/server/git/gitService.js.map +1 -0
  68. package/dist/server/gitRoutes.js +23 -0
  69. package/dist/server/gitRoutes.js.map +1 -0
  70. package/dist/server/index.js +7 -0
  71. package/dist/server/index.js.map +1 -0
  72. package/dist/server/machines/machineClient.js +172 -0
  73. package/dist/server/machines/machineClient.js.map +1 -0
  74. package/dist/server/machines/machinePluginProxyRoutes.js +190 -0
  75. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
  76. package/dist/server/machines/machineProxyRoutes.js +172 -0
  77. package/dist/server/machines/machineProxyRoutes.js.map +1 -0
  78. package/dist/server/machines/machineRoutes.js +56 -0
  79. package/dist/server/machines/machineRoutes.js.map +1 -0
  80. package/dist/server/machines/machineService.js +238 -0
  81. package/dist/server/machines/machineService.js.map +1 -0
  82. package/dist/server/machines/machineStore.js +128 -0
  83. package/dist/server/machines/machineStore.js.map +1 -0
  84. package/dist/server/models/modelsConfigRoutes.js +40 -0
  85. package/dist/server/models/modelsConfigRoutes.js.map +1 -0
  86. package/dist/server/models/modelsConfigService.js +339 -0
  87. package/dist/server/models/modelsConfigService.js.map +1 -0
  88. package/dist/server/piPackagePluginsConfigRoutes.js +86 -0
  89. package/dist/server/piPackagePluginsConfigRoutes.js.map +1 -0
  90. package/dist/server/piPackagePluginsConfigService.js +311 -0
  91. package/dist/server/piPackagePluginsConfigService.js.map +1 -0
  92. package/dist/server/piPackageRoutes.js +91 -0
  93. package/dist/server/piPackageRoutes.js.map +1 -0
  94. package/dist/server/piPackageService.js +101 -0
  95. package/dist/server/piPackageService.js.map +1 -0
  96. package/dist/server/piWebUiPluginService.js +326 -0
  97. package/dist/server/piWebUiPluginService.js.map +1 -0
  98. package/dist/server/piWebUiReleaseLookupCache.js +37 -0
  99. package/dist/server/piWebUiReleaseLookupCache.js.map +1 -0
  100. package/dist/server/piWebUiStatus.js +622 -0
  101. package/dist/server/piWebUiStatus.js.map +1 -0
  102. package/dist/server/piWebUiStatusCache.js +45 -0
  103. package/dist/server/piWebUiStatusCache.js.map +1 -0
  104. package/dist/server/projects/directorySuggestions.js +37 -0
  105. package/dist/server/projects/directorySuggestions.js.map +1 -0
  106. package/dist/server/projects/projectService.js +31 -0
  107. package/dist/server/projects/projectService.js.map +1 -0
  108. package/dist/server/realtime/sessionEventHub.js +70 -0
  109. package/dist/server/realtime/sessionEventHub.js.map +1 -0
  110. package/dist/server/sessiond/sessionDaemonStartup.js +49 -0
  111. package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -0
  112. package/dist/server/sessiond/sessionProxyRoutes.js +87 -0
  113. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -0
  114. package/dist/server/sessiond/skillsGithubToken.js +7 -0
  115. package/dist/server/sessiond/skillsGithubToken.js.map +1 -0
  116. package/dist/server/sessiond.js +152 -0
  117. package/dist/server/sessiond.js.map +1 -0
  118. package/dist/server/sessions/attachmentService.js +119 -0
  119. package/dist/server/sessions/attachmentService.js.map +1 -0
  120. package/dist/server/sessions/authProviderOptions.js +50 -0
  121. package/dist/server/sessions/authProviderOptions.js.map +1 -0
  122. package/dist/server/sessions/authRoutes.js +69 -0
  123. package/dist/server/sessions/authRoutes.js.map +1 -0
  124. package/dist/server/sessions/authService.js +134 -0
  125. package/dist/server/sessions/authService.js.map +1 -0
  126. package/dist/server/sessions/builtinCommands.js +27 -0
  127. package/dist/server/sessions/builtinCommands.js.map +1 -0
  128. package/dist/server/sessions/editPreview.js +196 -0
  129. package/dist/server/sessions/editPreview.js.map +1 -0
  130. package/dist/server/sessions/messagePaging.js +43 -0
  131. package/dist/server/sessions/messagePaging.js.map +1 -0
  132. package/dist/server/sessions/oauthLoginFlowService.js +349 -0
  133. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -0
  134. package/dist/server/sessions/piSessionManagerGateway.js +115 -0
  135. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
  136. package/dist/server/sessions/piSessionService.js +3230 -0
  137. package/dist/server/sessions/piSessionService.js.map +1 -0
  138. package/dist/server/sessions/plainTextTheme.js +112 -0
  139. package/dist/server/sessions/plainTextTheme.js.map +1 -0
  140. package/dist/server/sessions/sessionArchiveMigration.js +590 -0
  141. package/dist/server/sessions/sessionArchiveMigration.js.map +1 -0
  142. package/dist/server/sessions/sessionArchiveStore.js +262 -0
  143. package/dist/server/sessions/sessionArchiveStore.js.map +1 -0
  144. package/dist/server/sessions/sessionArchiveTree.js +35 -0
  145. package/dist/server/sessions/sessionArchiveTree.js.map +1 -0
  146. package/dist/server/sessions/sessionCleanup.js +157 -0
  147. package/dist/server/sessions/sessionCleanup.js.map +1 -0
  148. package/dist/server/sessions/sessionCommandService.js +313 -0
  149. package/dist/server/sessions/sessionCommandService.js.map +1 -0
  150. package/dist/server/sessions/sessionDefaultsRoutes.js +65 -0
  151. package/dist/server/sessions/sessionDefaultsRoutes.js.map +1 -0
  152. package/dist/server/sessions/sessionDefaultsService.js +90 -0
  153. package/dist/server/sessions/sessionDefaultsService.js.map +1 -0
  154. package/dist/server/sessions/sessionHistoryExport.js +115 -0
  155. package/dist/server/sessions/sessionHistoryExport.js.map +1 -0
  156. package/dist/server/sessions/sessionMetadataStore.js +102 -0
  157. package/dist/server/sessions/sessionMetadataStore.js.map +1 -0
  158. package/dist/server/sessions/sessionNameGenerator.js +90 -0
  159. package/dist/server/sessions/sessionNameGenerator.js.map +1 -0
  160. package/dist/server/sessions/sessionNotificationStore.js +484 -0
  161. package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
  162. package/dist/server/sessions/sessionRoutes.js +590 -0
  163. package/dist/server/sessions/sessionRoutes.js.map +1 -0
  164. package/dist/server/sessions/sessionRuntimeStore.js +2 -0
  165. package/dist/server/sessions/sessionRuntimeStore.js.map +1 -0
  166. package/dist/server/sessions/sessionService.js +2 -0
  167. package/dist/server/sessions/sessionService.js.map +1 -0
  168. package/dist/server/sessions/sessionTreeProjection.js +250 -0
  169. package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
  170. package/dist/server/sessions/sessionUnreadStore.js +520 -0
  171. package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
  172. package/dist/server/sessions/spawnSessionTool.js +41 -0
  173. package/dist/server/sessions/spawnSessionTool.js.map +1 -0
  174. package/dist/server/sessions/spawnSubsessionTool.js +214 -0
  175. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -0
  176. package/dist/server/sessions/spawnTargetResolver.js +36 -0
  177. package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
  178. package/dist/server/sessions/subsessionTranscript.js +235 -0
  179. package/dist/server/sessions/subsessionTranscript.js.map +1 -0
  180. package/dist/server/skills/runNpx.js +30 -0
  181. package/dist/server/skills/runNpx.js.map +1 -0
  182. package/dist/server/skills/skillLock.js +115 -0
  183. package/dist/server/skills/skillLock.js.map +1 -0
  184. package/dist/server/skills/skillUpdates.js +194 -0
  185. package/dist/server/skills/skillUpdates.js.map +1 -0
  186. package/dist/server/skills/skillsConfigRoutes.js +64 -0
  187. package/dist/server/skills/skillsConfigRoutes.js.map +1 -0
  188. package/dist/server/skills/skillsConfigService.js +391 -0
  189. package/dist/server/skills/skillsConfigService.js.map +1 -0
  190. package/dist/server/storage/projectStore.js +88 -0
  191. package/dist/server/storage/projectStore.js.map +1 -0
  192. package/dist/server/systemInfoRoutes.js +265 -0
  193. package/dist/server/systemInfoRoutes.js.map +1 -0
  194. package/dist/server/terminalProxyRoutes.js +140 -0
  195. package/dist/server/terminalProxyRoutes.js.map +1 -0
  196. package/dist/server/terminals/terminalRoutes.js +155 -0
  197. package/dist/server/terminals/terminalRoutes.js.map +1 -0
  198. package/dist/server/terminals/terminalService.js +305 -0
  199. package/dist/server/terminals/terminalService.js.map +1 -0
  200. package/dist/server/terminals/terminalSize.js +17 -0
  201. package/dist/server/terminals/terminalSize.js.map +1 -0
  202. package/dist/server/types.js +2 -0
  203. package/dist/server/types.js.map +1 -0
  204. package/dist/server/webSocketBridge.js +32 -0
  205. package/dist/server/webSocketBridge.js.map +1 -0
  206. package/dist/server/workingDirectory.js +44 -0
  207. package/dist/server/workingDirectory.js.map +1 -0
  208. package/dist/server/workspaceExplorerRoutes.js +109 -0
  209. package/dist/server/workspaceExplorerRoutes.js.map +1 -0
  210. package/dist/server/workspaces/effectivePathAccess.js +27 -0
  211. package/dist/server/workspaces/effectivePathAccess.js.map +1 -0
  212. package/dist/server/workspaces/fileContentService.js +181 -0
  213. package/dist/server/workspaces/fileContentService.js.map +1 -0
  214. package/dist/server/workspaces/fileSuggestions.js +520 -0
  215. package/dist/server/workspaces/fileSuggestions.js.map +1 -0
  216. package/dist/server/workspaces/fileTreeService.js +35 -0
  217. package/dist/server/workspaces/fileTreeService.js.map +1 -0
  218. package/dist/server/workspaces/gitWorktreeDiscovery.js +34 -0
  219. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -0
  220. package/dist/server/workspaces/imagePreviewService.js +40 -0
  221. package/dist/server/workspaces/imagePreviewService.js.map +1 -0
  222. package/dist/server/workspaces/pathAccessPolicy.js +90 -0
  223. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -0
  224. package/dist/server/workspaces/pathSafety.js +45 -0
  225. package/dist/server/workspaces/pathSafety.js.map +1 -0
  226. package/dist/server/workspaces/projectPiWebUiConfig.js +61 -0
  227. package/dist/server/workspaces/projectPiWebUiConfig.js.map +1 -0
  228. package/dist/server/workspaces/workspaceContext.js +8 -0
  229. package/dist/server/workspaces/workspaceContext.js.map +1 -0
  230. package/dist/server/workspaces/workspaceDeletionRoutes.js +113 -0
  231. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
  232. package/dist/server/workspaces/workspaceService.js +39 -0
  233. package/dist/server/workspaces/workspaceService.js.map +1 -0
  234. package/dist/sessiond/activeAgentProfile.js +31 -0
  235. package/dist/sessiond/activeAgentProfile.js.map +1 -0
  236. package/dist/sessiond/config.js +9 -0
  237. package/dist/sessiond/config.js.map +1 -0
  238. package/dist/sessiond/sessionDaemonClient.js +103 -0
  239. package/dist/sessiond/sessionDaemonClient.js.map +1 -0
  240. package/dist/shared/activeAgentProfile.js +76 -0
  241. package/dist/shared/activeAgentProfile.js.map +1 -0
  242. package/dist/shared/activity.js +11 -0
  243. package/dist/shared/activity.js.map +1 -0
  244. package/dist/shared/apiTypes.d.ts +1212 -0
  245. package/dist/shared/apiTypes.js +25 -0
  246. package/dist/shared/apiTypes.js.map +1 -0
  247. package/dist/shared/capabilities.js +69 -0
  248. package/dist/shared/capabilities.js.map +1 -0
  249. package/dist/shared/federatedRoutes.js +109 -0
  250. package/dist/shared/federatedRoutes.js.map +1 -0
  251. package/dist/shared/machinePluginIds.js +41 -0
  252. package/dist/shared/machinePluginIds.js.map +1 -0
  253. package/dist/shared/piWebUiStatusParsing.js +108 -0
  254. package/dist/shared/piWebUiStatusParsing.js.map +1 -0
  255. package/dist/shared/pluginIds.js +5 -0
  256. package/dist/shared/pluginIds.js.map +1 -0
  257. package/dist/shared/promptAttachments.js +92 -0
  258. package/dist/shared/promptAttachments.js.map +1 -0
  259. package/dist/shared/thinkingLevels.d.ts +27 -0
  260. package/dist/shared/thinkingLevels.js +31 -0
  261. package/dist/shared/thinkingLevels.js.map +1 -0
  262. package/dist/shared/workspaceDeletion.js +12 -0
  263. package/dist/shared/workspaceDeletion.js.map +1 -0
  264. package/dist/shared/workspaceFiles.js +3 -0
  265. package/dist/shared/workspaceFiles.js.map +1 -0
  266. package/docs/assets/favicon.svg +8 -0
  267. package/docs/assets/pi-webui-banner.png +0 -0
  268. package/docs/assets/pi-webui-desktop.png +0 -0
  269. package/docs/assets/pi-webui-mobile.png +0 -0
  270. package/docs/assets/pi-webui-tablet.png +0 -0
  271. package/docs/config.md +265 -0
  272. package/docs/plugins.md +988 -0
  273. package/extensions/pi-webui.ts +133 -0
  274. package/package.json +143 -0
  275. package/plugin-api/unstable.d.ts +1 -0
  276. package/plugin-api.d.ts +1 -0
@@ -0,0 +1,391 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { DefaultResourceLoader, parseFrontmatter } from "@earendil-works/pi-coding-agent";
3
+ import { annotateSkillsWithInstallInfo } from "./skillLock.js";
4
+ import { runNpx } from "./runNpx.js";
5
+ import { buildSkillUpdateArgs, checkSkillUpdates } from "./skillUpdates.js";
6
+ const ANSI_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "gu");
7
+ const DEFAULT_SEARCH_LIMIT = 50;
8
+ const MIN_SEARCH_LIMIT = 1;
9
+ const MAX_SEARCH_LIMIT = 50;
10
+ const skillsApiUrl = process.env["SKILLS_API_URL"];
11
+ const DEFAULT_SKILLS_API_BASE = skillsApiUrl === undefined || skillsApiUrl === "" ? "https://skills.sh" : skillsApiUrl;
12
+ export class SkillsConfigRequestError extends Error {
13
+ }
14
+ export class SkillsConfigNotFoundError extends Error {
15
+ }
16
+ /**
17
+ * Reads and mutates the skills visible to a selected workspace. This service
18
+ * runs in sessiond so the profile, filesystem, and external commands belong to
19
+ * the same long-lived Pi runtime as the sessions it serves.
20
+ */
21
+ export class SkillsConfigService {
22
+ constructor(dependencies) {
23
+ this.dependencies = dependencies;
24
+ this.loadResourceSkills = dependencies.loadSkills ?? loadSkillsWithResourceLoader;
25
+ this.npx = dependencies.runNpx ?? runNpx;
26
+ this.fetcher = dependencies.fetcher ?? fetch;
27
+ this.skillsApiBase = dependencies.skillsApiBase ?? DEFAULT_SKILLS_API_BASE;
28
+ this.githubToken = dependencies.githubToken;
29
+ }
30
+ async list(cwd) {
31
+ return { skills: await this.loadedSkills(requireCwd(cwd)) };
32
+ }
33
+ async toggle(value) {
34
+ const request = parseSkillToggleRequest(value);
35
+ const skill = (await this.loadedSkills(request.cwd)).find((item) => item.filePath === request.filePath);
36
+ if (skill === undefined)
37
+ throw new SkillsConfigNotFoundError("Skill not found in the selected workspace");
38
+ if (!isSkillMarkdownPath(skill.filePath))
39
+ throw new SkillsConfigRequestError("Only SKILL.md files can be toggled");
40
+ let content;
41
+ try {
42
+ content = await readFile(skill.filePath, "utf8");
43
+ }
44
+ catch (error) {
45
+ if (isMissingFile(error))
46
+ throw new SkillsConfigNotFoundError("Skill file not found");
47
+ throw error;
48
+ }
49
+ await writeFile(skill.filePath, updateDisableModelInvocation(content, request.disableModelInvocation), "utf8");
50
+ return { success: true };
51
+ }
52
+ async search(value) {
53
+ const request = parseSkillSearchRequest(value);
54
+ try {
55
+ return { results: await searchSkillsApi(request.query, request.limit, this.fetcher, this.skillsApiBase) };
56
+ }
57
+ catch {
58
+ try {
59
+ const { stdout, stderr } = await this.npx(["skills", "find", request.query], {
60
+ timeout: 20_000,
61
+ env: { ...process.env, FORCE_COLOR: "0" },
62
+ });
63
+ return { results: parseSearchOutput(`${stdout}${stderr}`).slice(0, request.limit) };
64
+ }
65
+ catch (error) {
66
+ const results = parseSearchOutput(npxOutput(error)).slice(0, request.limit);
67
+ if (results.length > 0)
68
+ return { results };
69
+ throw error;
70
+ }
71
+ }
72
+ }
73
+ async install(value) {
74
+ const request = parseSkillInstallRequest(value);
75
+ const global = request.scope === "global";
76
+ const args = ["skills", "add", request.package, "-y", "--agent", "pi"];
77
+ if (global)
78
+ args.push("-g");
79
+ try {
80
+ const { stdout, stderr } = await this.npx(args, {
81
+ timeout: 60_000,
82
+ ...(global ? {} : { cwd: request.cwd }),
83
+ env: { ...process.env, FORCE_COLOR: "0" },
84
+ });
85
+ const output = `${stdout}${stderr}`.replace(ANSI_RE, "");
86
+ if (!/Installation complete|Installed \d+ skill/u.test(output)) {
87
+ throw new Error(output.slice(-300) || "Install failed");
88
+ }
89
+ return { success: true };
90
+ }
91
+ catch (error) {
92
+ throw new Error(npxErrorMessage(error), { cause: error });
93
+ }
94
+ }
95
+ async check(value) {
96
+ const request = parseSkillCheckRequest(value);
97
+ const installs = (await this.loadedSkills(request.cwd))
98
+ .flatMap((skill) => skill.install === undefined ? [] : [skill.install])
99
+ .filter((install) => request.package === undefined || (install.package === request.package && install.scope === request.scope));
100
+ if (request.package !== undefined && installs.length === 0)
101
+ throw new SkillsConfigNotFoundError("Installed skill not found");
102
+ return {
103
+ updates: await checkSkillUpdates(installs, this.skillUpdateCheckOptions()),
104
+ };
105
+ }
106
+ async update(value) {
107
+ const request = parseSkillUpdateRequest(value);
108
+ const skills = await this.loadedSkills(request.cwd);
109
+ const skill = skills.find((item) => item.install?.package === request.package && item.install.scope === request.scope);
110
+ if (skill?.install === undefined)
111
+ throw new SkillsConfigNotFoundError("Installed skill not found");
112
+ if (!skill.install.canCheckForUpdates)
113
+ throw new SkillsConfigRequestError("This skill cannot be updated automatically");
114
+ try {
115
+ const { stdout, stderr } = await this.npx(buildSkillUpdateArgs(skill.install), {
116
+ timeout: 60_000,
117
+ ...(request.scope === "project" ? { cwd: request.cwd } : {}),
118
+ env: { ...process.env, FORCE_COLOR: "0" },
119
+ });
120
+ const updatedSkill = (await this.loadedSkills(request.cwd)).find((item) => item.install?.package === request.package && item.install.scope === request.scope);
121
+ return {
122
+ success: true,
123
+ ...(updatedSkill === undefined ? {} : { skill: updatedSkill }),
124
+ output: `${stdout}${stderr}`.slice(-500),
125
+ };
126
+ }
127
+ catch (error) {
128
+ throw new Error(npxErrorMessage(error), { cause: error });
129
+ }
130
+ }
131
+ async loadedSkills(cwd) {
132
+ const skills = await this.loadResourceSkills(cwd, this.dependencies.agentDir);
133
+ return annotateSkillsWithInstallInfo(skills, { cwd, agentDir: this.dependencies.agentDir });
134
+ }
135
+ skillUpdateCheckOptions() {
136
+ return {
137
+ fetcher: this.fetcher,
138
+ skillsApiBase: this.skillsApiBase,
139
+ ...(this.githubToken === undefined ? {} : { githubToken: this.githubToken }),
140
+ };
141
+ }
142
+ }
143
+ async function loadSkillsWithResourceLoader(cwd, agentDir) {
144
+ const loader = new DefaultResourceLoader({ cwd, agentDir });
145
+ await loader.reload();
146
+ return loader.getSkills().skills;
147
+ }
148
+ const DISABLE_MODEL_INVOCATION_KEY = "disable-model-invocation";
149
+ const FRONTMATTER_BLOCK_PATTERN = /^(---[ \t]*\r?\n)([\s\S]*?)(^---[ \t]*(?:\r?\n|$))/mu;
150
+ const DISABLE_MODEL_INVOCATION_LINE_PATTERN = /^disable-model-invocation[ \t]*:[^\r\n]*(?:\r?\n|$)/mu;
151
+ export function updateDisableModelInvocation(content, disableModelInvocation) {
152
+ const { frontmatter } = parseFrontmatter(content);
153
+ const hasDisableModelInvocation = Object.hasOwn(frontmatter, DISABLE_MODEL_INVOCATION_KEY);
154
+ if (disableModelInvocation) {
155
+ if (hasDisableModelInvocation && frontmatter[DISABLE_MODEL_INVOCATION_KEY] === true)
156
+ return content;
157
+ return hasDisableModelInvocation
158
+ ? updateExistingDisableModelInvocation(content, true)
159
+ : addDisableModelInvocation(content);
160
+ }
161
+ return hasDisableModelInvocation ? updateExistingDisableModelInvocation(content, false) : content;
162
+ }
163
+ function addDisableModelInvocation(content) {
164
+ const openingDelimiter = /^---[ \t]*(\r?\n)/u.exec(content);
165
+ if (openingDelimiter === null)
166
+ return `---\n${DISABLE_MODEL_INVOCATION_KEY}: true\n---\n${content}`;
167
+ const lineEnding = openingDelimiter[1] ?? "\n";
168
+ return content.replace(/^---[ \t]*\r?\n/u, (delimiter) => `${delimiter}${DISABLE_MODEL_INVOCATION_KEY}: true${lineEnding}`);
169
+ }
170
+ function updateExistingDisableModelInvocation(content, disableModelInvocation) {
171
+ const frontmatter = FRONTMATTER_BLOCK_PATTERN.exec(content)?.[2];
172
+ if (frontmatter === undefined || !DISABLE_MODEL_INVOCATION_LINE_PATTERN.test(frontmatter)) {
173
+ throw new Error("Could not locate disable-model-invocation in skill frontmatter");
174
+ }
175
+ return content.replace(FRONTMATTER_BLOCK_PATTERN, (_block, openingDelimiter, blockFrontmatter, closingDelimiter) => {
176
+ const updatedFrontmatter = blockFrontmatter.replace(DISABLE_MODEL_INVOCATION_LINE_PATTERN, (line) => {
177
+ return disableModelInvocation ? `${DISABLE_MODEL_INVOCATION_KEY}: true${lineEnding(line)}` : "";
178
+ });
179
+ return `${openingDelimiter}${updatedFrontmatter}${closingDelimiter}`;
180
+ });
181
+ }
182
+ function lineEnding(line) {
183
+ return line.endsWith("\r\n") ? "\r\n" : line.endsWith("\n") ? "\n" : "";
184
+ }
185
+ function parseSkillToggleRequest(value) {
186
+ const record = requireRecord(value, "Skill toggle request");
187
+ const disableModelInvocation = record["disableModelInvocation"];
188
+ if (typeof disableModelInvocation !== "boolean")
189
+ throw new SkillsConfigRequestError("disableModelInvocation must be a boolean");
190
+ return {
191
+ cwd: requiredString(record, "cwd"),
192
+ filePath: requiredString(record, "filePath"),
193
+ disableModelInvocation,
194
+ };
195
+ }
196
+ function parseSkillSearchRequest(value) {
197
+ const record = requireRecord(value, "Skill search request");
198
+ const query = requiredString(record, "query");
199
+ return { query, limit: parseSearchLimit(record["limit"]) };
200
+ }
201
+ function parseSkillInstallRequest(value) {
202
+ const record = requireRecord(value, "Skill install request");
203
+ const scope = record["scope"];
204
+ if (scope !== "global" && scope !== "project")
205
+ throw new SkillsConfigRequestError("scope must be \"global\" or \"project\"");
206
+ return {
207
+ cwd: requiredString(record, "cwd"),
208
+ package: requiredString(record, "package"),
209
+ scope,
210
+ };
211
+ }
212
+ function parseSkillCheckRequest(value) {
213
+ const record = requireRecord(value, "Skill update check request");
214
+ const packageName = optionalString(record, "package");
215
+ const scope = record["scope"];
216
+ if (scope !== undefined && scope !== "global" && scope !== "project")
217
+ throw new SkillsConfigRequestError("scope must be \"global\" or \"project\"");
218
+ if ((packageName === undefined) !== (scope === undefined))
219
+ throw new SkillsConfigRequestError("package and scope must be provided together");
220
+ return {
221
+ cwd: requiredString(record, "cwd"),
222
+ ...(packageName === undefined ? {} : { package: packageName }),
223
+ ...(scope === undefined ? {} : { scope }),
224
+ };
225
+ }
226
+ function parseSkillUpdateRequest(value) {
227
+ const record = requireRecord(value, "Skill update request");
228
+ const scope = record["scope"];
229
+ if (scope !== "global" && scope !== "project")
230
+ throw new SkillsConfigRequestError("scope must be \"global\" or \"project\"");
231
+ return {
232
+ cwd: requiredString(record, "cwd"),
233
+ package: requiredString(record, "package"),
234
+ scope,
235
+ };
236
+ }
237
+ function requireCwd(cwd) {
238
+ if (typeof cwd !== "string" || cwd.trim() === "")
239
+ throw new SkillsConfigRequestError("cwd is required");
240
+ return cwd;
241
+ }
242
+ function requireRecord(value, label) {
243
+ if (!isRecord(value))
244
+ throw new SkillsConfigRequestError(`${label} must be an object`);
245
+ return value;
246
+ }
247
+ function requiredString(record, field) {
248
+ const value = record[field];
249
+ if (typeof value !== "string" || value.trim() === "")
250
+ throw new SkillsConfigRequestError(`${field} is required`);
251
+ return value.trim();
252
+ }
253
+ function optionalString(record, field) {
254
+ const value = record[field];
255
+ if (value === undefined)
256
+ return undefined;
257
+ if (typeof value !== "string" || value.trim() === "")
258
+ throw new SkillsConfigRequestError(`${field} must be a non-empty string`);
259
+ return value.trim();
260
+ }
261
+ function parseSearchLimit(value) {
262
+ if (value === undefined)
263
+ return DEFAULT_SEARCH_LIMIT;
264
+ const numberValue = typeof value === "number" ? value : Number(value);
265
+ if (!Number.isFinite(numberValue))
266
+ return DEFAULT_SEARCH_LIMIT;
267
+ return Math.min(MAX_SEARCH_LIMIT, Math.max(MIN_SEARCH_LIMIT, Math.floor(numberValue)));
268
+ }
269
+ function parseSearchOutput(raw) {
270
+ const clean = raw.replace(ANSI_RE, "");
271
+ const results = [];
272
+ const lines = clean.split("\n");
273
+ for (let index = 0; index < lines.length; index += 1) {
274
+ const line = lines[index]?.trim() ?? "";
275
+ const packageMatch = /^([\w.-]+\/[\w.@:-]+)\s+([\d.,]+[KMB]?\s+installs)$/u.exec(line);
276
+ if (packageMatch === null)
277
+ continue;
278
+ const urlLine = lines[index + 1]?.trim().replace(/^└\s*/u, "");
279
+ results.push({
280
+ package: packageMatch[1] ?? "",
281
+ installs: packageMatch[2] ?? "",
282
+ url: urlLine?.startsWith("https://") === true ? urlLine : "",
283
+ });
284
+ }
285
+ return results;
286
+ }
287
+ function parseSkillsApiResponse(value) {
288
+ if (!isRecord(value))
289
+ throw new Error("skills.sh search returned an invalid response");
290
+ const rawSkills = value["skills"];
291
+ if (rawSkills === undefined || rawSkills === null)
292
+ return {};
293
+ if (!Array.isArray(rawSkills))
294
+ throw new Error("skills.sh search returned an invalid skills list");
295
+ return { skills: rawSkills.flatMap(parseSkillsApiSkill) };
296
+ }
297
+ function parseSkillsApiSkill(value) {
298
+ if (!isRecord(value))
299
+ return [];
300
+ const id = typeof value["id"] === "string" ? value["id"] : undefined;
301
+ const name = typeof value["name"] === "string" ? value["name"] : undefined;
302
+ const source = typeof value["source"] === "string" ? value["source"] : undefined;
303
+ const installs = typeof value["installs"] === "number" ? value["installs"] : undefined;
304
+ return [{
305
+ ...(id === undefined ? {} : { id }),
306
+ ...(name === undefined ? {} : { name }),
307
+ ...(source === undefined ? {} : { source }),
308
+ ...(installs === undefined ? {} : { installs }),
309
+ }];
310
+ }
311
+ async function searchSkillsApi(query, limit, fetcher, skillsApiBase) {
312
+ const url = `${skillsApiBase}/api/search?q=${encodeURIComponent(query)}&limit=${String(limit)}`;
313
+ const response = await fetcher(url, { cache: "no-store" });
314
+ if (!response.ok)
315
+ throw new Error(`skills.sh search failed: HTTP ${String(response.status)}`);
316
+ const rawData = await response.json();
317
+ const data = parseSkillsApiResponse(rawData);
318
+ return (data.skills ?? [])
319
+ .map((skill) => {
320
+ const name = skill.name?.trim();
321
+ const source = skill.source?.trim();
322
+ const slug = skill.id?.trim();
323
+ if (name === undefined || name === "")
324
+ return undefined;
325
+ const packageSource = source === undefined || source === "" ? slug : source;
326
+ if (packageSource === undefined || packageSource === "")
327
+ return undefined;
328
+ return {
329
+ package: `${packageSource}@${name}`,
330
+ installs: formatInstalls(skill.installs),
331
+ url: slug === undefined || slug === "" ? "" : `${skillsApiBase}/${slug}`,
332
+ };
333
+ })
334
+ .filter((skill) => skill !== undefined)
335
+ .sort((left, right) => parseInstallCount(right.installs) - parseInstallCount(left.installs));
336
+ }
337
+ function formatInstalls(count) {
338
+ if (count === undefined || count <= 0)
339
+ return "";
340
+ if (count >= 1_000_000)
341
+ return `${(count / 1_000_000).toFixed(1).replace(/\.0$/u, "")}M installs`;
342
+ if (count >= 1_000)
343
+ return `${(count / 1_000).toFixed(1).replace(/\.0$/u, "")}K installs`;
344
+ return `${String(count)} install${count === 1 ? "" : "s"}`;
345
+ }
346
+ function parseInstallCount(installs) {
347
+ const match = /^([\d.]+)([KMB])?\s+installs?$/u.exec(installs);
348
+ if (match === null)
349
+ return 0;
350
+ const value = Number(match[1]);
351
+ if (!Number.isFinite(value))
352
+ return 0;
353
+ const multiplier = match[2] === "B" ? 1_000_000_000 : match[2] === "M" ? 1_000_000 : match[2] === "K" ? 1_000 : 1;
354
+ return value * multiplier;
355
+ }
356
+ function npxOutput(error) {
357
+ if (!isRecord(error))
358
+ return "";
359
+ const stdout = typeof error["stdout"] === "string" ? error["stdout"] : "";
360
+ const stderr = typeof error["stderr"] === "string" ? error["stderr"] : "";
361
+ return `${stdout}${stderr}`;
362
+ }
363
+ function npxErrorMessage(error) {
364
+ const output = npxOutput(error).replace(ANSI_RE, "");
365
+ return output === "" ? errorMessage(error) : output;
366
+ }
367
+ function errorMessage(error) {
368
+ if (error instanceof Error)
369
+ return error.message;
370
+ if (typeof error === "string")
371
+ return error;
372
+ if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint")
373
+ return String(error);
374
+ if (typeof error === "symbol")
375
+ return error.toString();
376
+ if (error === undefined)
377
+ return "undefined";
378
+ if (error === null)
379
+ return "null";
380
+ return Object.prototype.toString.call(error);
381
+ }
382
+ function isSkillMarkdownPath(path) {
383
+ return /(?:^|[\\/])SKILL\.md$/iu.test(path);
384
+ }
385
+ function isMissingFile(error) {
386
+ return isRecord(error) && error["code"] === "ENOENT";
387
+ }
388
+ function isRecord(value) {
389
+ return typeof value === "object" && value !== null && !Array.isArray(value);
390
+ }
391
+ //# sourceMappingURL=skillsConfigService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillsConfigService.js","sourceRoot":"","sources":["../../../src/server/skills/skillsConfigService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { piWebUiDataDir } from "../../config.js";
4
+ import { randomUUID } from "node:crypto";
5
+ function isNodeErrorWithCode(error, code) {
6
+ return error instanceof Error && "code" in error && error.code === code;
7
+ }
8
+ function parseProjectFile(value) {
9
+ if (!isRecord(value) || !Array.isArray(value["projects"]))
10
+ throw new Error("Invalid project file");
11
+ return { projects: value["projects"].map(parseProject) };
12
+ }
13
+ function parseProject(value) {
14
+ if (!isRecord(value))
15
+ throw new Error("Invalid project");
16
+ const id = value["id"];
17
+ const name = value["name"];
18
+ const path = value["path"];
19
+ const createdAt = value["createdAt"];
20
+ if (typeof id !== "string" || typeof name !== "string" || typeof path !== "string" || typeof createdAt !== "string")
21
+ throw new Error("Invalid project");
22
+ return { id, name, path, createdAt };
23
+ }
24
+ function isRecord(value) {
25
+ return typeof value === "object" && value !== null;
26
+ }
27
+ export function defaultProjectStorePath(env = process.env, cwd = process.cwd()) {
28
+ return join(piWebUiDataDir(env, cwd), "projects.json");
29
+ }
30
+ export function projectStorePath(env = process.env, cwd = process.cwd()) {
31
+ const configured = env["PI_WEBUI_PROJECTS_FILE"];
32
+ if (configured === undefined || configured === "")
33
+ return defaultProjectStorePath(env, cwd);
34
+ return resolve(cwd, configured);
35
+ }
36
+ export class ProjectStore {
37
+ constructor(filePath = projectStorePath()) {
38
+ this.filePath = filePath;
39
+ }
40
+ async list() {
41
+ return (await this.read()).projects;
42
+ }
43
+ async add(input) {
44
+ const data = await this.read();
45
+ const path = input.path;
46
+ const existing = data.projects.find((p) => p.path === path);
47
+ if (existing)
48
+ return existing;
49
+ const trimmedName = input.name?.trim();
50
+ const leafName = path.split("/").filter((part) => part !== "").at(-1);
51
+ const project = {
52
+ id: randomUUID(),
53
+ name: trimmedName !== undefined && trimmedName !== "" ? trimmedName : leafName ?? path,
54
+ path,
55
+ createdAt: new Date().toISOString(),
56
+ };
57
+ data.projects.push(project);
58
+ await this.write(data);
59
+ return project;
60
+ }
61
+ async get(id) {
62
+ return (await this.list()).find((p) => p.id === id);
63
+ }
64
+ async remove(id) {
65
+ const data = await this.read();
66
+ const projects = data.projects.filter((p) => p.id !== id);
67
+ if (projects.length === data.projects.length)
68
+ return false;
69
+ await this.write({ projects });
70
+ return true;
71
+ }
72
+ async read() {
73
+ try {
74
+ const value = JSON.parse(await readFile(this.filePath, "utf8"));
75
+ return parseProjectFile(value);
76
+ }
77
+ catch (error) {
78
+ if (isNodeErrorWithCode(error, "ENOENT"))
79
+ return { projects: [] };
80
+ throw error;
81
+ }
82
+ }
83
+ async write(data) {
84
+ await mkdir(dirname(this.filePath), { recursive: true });
85
+ await writeFile(this.filePath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
86
+ }
87
+ }
88
+ //# sourceMappingURL=projectStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectStore.js","sourceRoot":"","sources":["../../../src/server/storage/projectStore.ts"],"names":[],"mappings":"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"}