@agimon-ai/doompi-skill 0.0.1-alpha.9 → 0.0.1-alpha.91

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 (118) hide show
  1. package/README.md +3 -1
  2. package/dist/apiContracts.cjs +17 -0
  3. package/dist/apiContracts.cjs.map +1 -0
  4. package/dist/apiContracts.d.mts +53 -0
  5. package/dist/apiContracts.d.mts.map +1 -0
  6. package/dist/apiContracts.mjs +13 -0
  7. package/dist/apiContracts.mjs.map +1 -0
  8. package/dist/catalog.cjs +4 -1
  9. package/dist/catalog.d.mts +1 -1
  10. package/dist/catalog.mjs +2 -1
  11. package/dist/deferredSkills-BzhyXnJ4.mjs +176 -0
  12. package/dist/{adapters/deferredSkills.cjs.map → deferredSkills-BzhyXnJ4.mjs.map} +1 -1
  13. package/dist/deferredSkills-DF6UCAsk.cjs +195 -0
  14. package/dist/deferredSkills-DF6UCAsk.cjs.map +1 -0
  15. package/dist/extensions/mcp-ui.mjs +31 -0
  16. package/dist/extensions/mcp-ui.mjs.map +1 -0
  17. package/dist/extensions/mcp.cjs +130 -0
  18. package/dist/extensions/mcp.cjs.map +1 -0
  19. package/dist/extensions/mcp.d.mts +5 -0
  20. package/dist/extensions/mcp.d.mts.map +1 -0
  21. package/dist/extensions/mcp.mjs +125 -0
  22. package/dist/extensions/mcp.mjs.map +1 -0
  23. package/dist/extensions/pi.cjs +411 -1
  24. package/dist/extensions/pi.cjs.map +1 -0
  25. package/dist/extensions/pi.d.mts +5 -2
  26. package/dist/extensions/pi.d.mts.map +1 -0
  27. package/dist/extensions/pi.mjs +406 -1
  28. package/dist/extensions/pi.mjs.map +1 -0
  29. package/dist/extensions/server.cjs +367 -0
  30. package/dist/extensions/server.cjs.map +1 -0
  31. package/dist/extensions/server.d.mts +5 -0
  32. package/dist/extensions/server.d.mts.map +1 -0
  33. package/dist/extensions/server.mjs +359 -0
  34. package/dist/extensions/server.mjs.map +1 -0
  35. package/dist/{adapters/skillCatalog.d.cts → index-6I1f9Ola.d.mts} +12 -4
  36. package/dist/index-6I1f9Ola.d.mts.map +1 -0
  37. package/dist/index.cjs +11 -1
  38. package/dist/index.d.mts +60 -5
  39. package/dist/index.d.mts.map +1 -0
  40. package/dist/index.mjs +4 -1
  41. package/dist/rolldown-runtime-C0BPl7ul.cjs +43 -0
  42. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  43. package/dist/skillCatalog-DLuYFuS6.cjs +213 -0
  44. package/dist/skillCatalog-DLuYFuS6.cjs.map +1 -0
  45. package/dist/skillCatalog-DYpoSsdD.mjs +194 -0
  46. package/dist/skillCatalog-DYpoSsdD.mjs.map +1 -0
  47. package/dist/skillText-B8muK9HZ.mjs +17 -0
  48. package/dist/skillText-B8muK9HZ.mjs.map +1 -0
  49. package/dist/skillText-C5OuRtBY.cjs +22 -0
  50. package/dist/skillText-C5OuRtBY.cjs.map +1 -0
  51. package/dist/skills-CjL1THn-.cjs +61 -0
  52. package/dist/skills-CjL1THn-.cjs.map +1 -0
  53. package/dist/skills-DAabEcff.mjs +32 -0
  54. package/dist/skills-DAabEcff.mjs.map +1 -0
  55. package/dist/skillsOverlay-C-VBauyr.mjs +362 -0
  56. package/dist/skillsOverlay-C-VBauyr.mjs.map +1 -0
  57. package/dist/skillsOverlay-CYRvtxbp.cjs +375 -0
  58. package/dist/skillsOverlay-CYRvtxbp.cjs.map +1 -0
  59. package/package.json +70 -19
  60. package/src/prompts/doompi-author-skill/SKILL.md +6 -2
  61. package/dist/_virtual/_rolldown/runtime.cjs +0 -1
  62. package/dist/adapters/deferredSkills.cjs +0 -12
  63. package/dist/adapters/deferredSkills.mjs +0 -12
  64. package/dist/adapters/deferredSkills.mjs.map +0 -1
  65. package/dist/adapters/helpSkills.cjs +0 -2
  66. package/dist/adapters/helpSkills.cjs.map +0 -1
  67. package/dist/adapters/helpSkills.mjs +0 -2
  68. package/dist/adapters/helpSkills.mjs.map +0 -1
  69. package/dist/adapters/pi/extension.cjs +0 -2
  70. package/dist/adapters/pi/extension.cjs.map +0 -1
  71. package/dist/adapters/pi/extension.d.cts +0 -7
  72. package/dist/adapters/pi/extension.d.cts.map +0 -1
  73. package/dist/adapters/pi/extension.d.mts +0 -7
  74. package/dist/adapters/pi/extension.d.mts.map +0 -1
  75. package/dist/adapters/pi/extension.mjs +0 -2
  76. package/dist/adapters/pi/extension.mjs.map +0 -1
  77. package/dist/adapters/pi/skillReadiness.cjs +0 -4
  78. package/dist/adapters/pi/skillReadiness.cjs.map +0 -1
  79. package/dist/adapters/pi/skillReadiness.mjs +0 -4
  80. package/dist/adapters/pi/skillReadiness.mjs.map +0 -1
  81. package/dist/adapters/skillCatalog.cjs +0 -2
  82. package/dist/adapters/skillCatalog.cjs.map +0 -1
  83. package/dist/adapters/skillCatalog.d.cts.map +0 -1
  84. package/dist/adapters/skillCatalog.d.mts +0 -58
  85. package/dist/adapters/skillCatalog.d.mts.map +0 -1
  86. package/dist/adapters/skillCatalog.mjs +0 -2
  87. package/dist/adapters/skillCatalog.mjs.map +0 -1
  88. package/dist/catalog.d.cts +0 -2
  89. package/dist/commands/skillsCommand.cjs +0 -2
  90. package/dist/commands/skillsCommand.cjs.map +0 -1
  91. package/dist/commands/skillsCommand.mjs +0 -2
  92. package/dist/commands/skillsCommand.mjs.map +0 -1
  93. package/dist/extensions/pi.d.cts +0 -2
  94. package/dist/index.d.cts +0 -5
  95. package/dist/services/skillText.cjs +0 -2
  96. package/dist/services/skillText.cjs.map +0 -1
  97. package/dist/services/skillText.d.cts +0 -13
  98. package/dist/services/skillText.d.cts.map +0 -1
  99. package/dist/services/skillText.d.mts +0 -13
  100. package/dist/services/skillText.d.mts.map +0 -1
  101. package/dist/services/skillText.mjs +0 -2
  102. package/dist/services/skillText.mjs.map +0 -1
  103. package/dist/tui/skillsOverlay.cjs +0 -4
  104. package/dist/tui/skillsOverlay.cjs.map +0 -1
  105. package/dist/tui/skillsOverlay.d.cts +0 -18
  106. package/dist/tui/skillsOverlay.d.cts.map +0 -1
  107. package/dist/tui/skillsOverlay.d.mts +0 -18
  108. package/dist/tui/skillsOverlay.d.mts.map +0 -1
  109. package/dist/tui/skillsOverlay.mjs +0 -4
  110. package/dist/tui/skillsOverlay.mjs.map +0 -1
  111. package/dist/types/skills.cjs +0 -2
  112. package/dist/types/skills.cjs.map +0 -1
  113. package/dist/types/skills.d.cts +0 -32
  114. package/dist/types/skills.d.cts.map +0 -1
  115. package/dist/types/skills.d.mts +0 -32
  116. package/dist/types/skills.d.mts.map +0 -1
  117. package/dist/types/skills.mjs +0 -2
  118. package/dist/types/skills.mjs.map +0 -1
package/README.md CHANGED
@@ -26,7 +26,7 @@ diagnostics.
26
26
  ## Contributing skill directories
27
27
 
28
28
  The package provides the session-owned `doom/skill-sources` Cordis service from
29
- `@agimon-ai/doompi-extension-contracts/skills`. Extensions register their directories inside
29
+ `@agimon-ai/doompi-core/skills`. Extensions register their directories inside
30
30
  `ctx.inject([DOOM_SKILL_SOURCES_SERVICE], ...)`; the returned handle is disposed automatically when
31
31
  either the contributor or provider unloads. Contributions are keyed by source, so a replacement
32
32
  generation takes the previous package slot without doubling it.
@@ -45,3 +45,5 @@ it. It is not selectable from `.doom/modes.yaml`.
45
45
  ## License
46
46
 
47
47
  MIT
48
+
49
+ Plugin entries live in `src/extensions`, host events and commands in routed surfaces, and catalog and discovery logic in named `src/services` folders. `src/exports` contains public helpers and types. Pi declares owned service bindings and native events. Its `onStop` invalidates pending discovery generations; final disposal releases the Help view. The server awaits its async declaration factory to discover named skill commands before registration and startup.
@@ -0,0 +1,17 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ //#region src/schemas/apiContracts.ts
6
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
7
+ const apiContracts = (0, require("@agimon-ai/doompi-core/apiContracts").defineApiContract)({
8
+ version: 1,
9
+ http: [],
10
+ sockets: [],
11
+ dynamic: []
12
+ });
13
+ //#endregion
14
+ exports.apiContracts = apiContracts;
15
+ exports.default = apiContracts;
16
+
17
+ //# sourceMappingURL=apiContracts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,gDAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
@@ -0,0 +1,53 @@
1
+ //#region src/schemas/apiContracts.d.ts
2
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
3
+ export declare const apiContracts: {
4
+ version: 1;
5
+ protocols?: Record<string, string> | undefined;
6
+ schemas?: Record<string, boolean | object> | undefined;
7
+ http: {
8
+ id: string;
9
+ scope: "global" | "session" | "workspace";
10
+ basePath?: string | undefined;
11
+ path: string;
12
+ method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
13
+ description: string;
14
+ availability?: string | undefined;
15
+ authentication: "device" | "none" | "owner";
16
+ parameters?: {
17
+ name: string;
18
+ in: "header" | "path" | "query";
19
+ required: boolean;
20
+ schema: boolean | object;
21
+ }[] | undefined;
22
+ body?: {
23
+ contentType: string;
24
+ contentTypes?: string[] | undefined;
25
+ required: boolean;
26
+ schema: boolean | object;
27
+ } | undefined;
28
+ responses: Record<string, {
29
+ description: string;
30
+ contentType?: string | undefined;
31
+ schema?: boolean | object | undefined;
32
+ events?: Record<string, boolean | object> | undefined;
33
+ }>;
34
+ }[];
35
+ sockets: {
36
+ id: string;
37
+ scope: "global" | "session" | "workspace";
38
+ description: string;
39
+ availability?: string | undefined;
40
+ service: string;
41
+ member: string;
42
+ direction: "client-to-server" | "server-to-client";
43
+ kind: "channel" | "method" | "state";
44
+ input: boolean | object;
45
+ output?: boolean | object | undefined;
46
+ errors?: boolean | object | undefined;
47
+ }[];
48
+ dynamic: string[];
49
+ gaps?: string[] | undefined;
50
+ };
51
+ //#endregion
52
+ export { apiContracts as default };
53
+ //# sourceMappingURL=apiContracts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
@@ -0,0 +1,13 @@
1
+ import { defineApiContract } from "@agimon-ai/doompi-core/apiContracts";
2
+ //#region src/schemas/apiContracts.ts
3
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
4
+ const apiContracts = defineApiContract({
5
+ version: 1,
6
+ http: [],
7
+ sockets: [],
8
+ dynamic: []
9
+ });
10
+ //#endregion
11
+ export { apiContracts, apiContracts as default };
12
+
13
+ //# sourceMappingURL=apiContracts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
package/dist/catalog.cjs CHANGED
@@ -1 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/skillCatalog.cjs");exports.buildSkillCatalog=e.buildSkillCatalog,exports.counter=e.counter;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_skillCatalog = require("./skillCatalog-DLuYFuS6.cjs");
3
+ exports.buildSkillCatalog = require_skillCatalog.buildSkillCatalog;
4
+ exports.counter = require_skillCatalog.counter;
@@ -1,2 +1,2 @@
1
- import { SkillCatalog, SkillCatalogOptions, SkillEntry, SkillGroup, SkillOwnerNode, buildSkillCatalog, counter } from "./adapters/skillCatalog.mjs";
1
+ import { a as SkillOwnerNode, i as SkillGroup, n as SkillCatalogOptions, o as buildSkillCatalog, r as SkillEntry, s as counter, t as SkillCatalog } from "./index-6I1f9Ola.mjs";
2
2
  export { type SkillCatalog, type SkillCatalogOptions, type SkillEntry, type SkillGroup, type SkillOwnerNode, buildSkillCatalog, counter };
package/dist/catalog.mjs CHANGED
@@ -1 +1,2 @@
1
- import{buildSkillCatalog as e,counter as t}from"./adapters/skillCatalog.mjs";export{e as buildSkillCatalog,t as counter};
1
+ import { n as counter, t as buildSkillCatalog } from "./skillCatalog-DYpoSsdD.mjs";
2
+ export { buildSkillCatalog, counter };
@@ -0,0 +1,176 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { formatSkillsForPrompt, getAgentDir, loadSkills, stripFrontmatter } from "@earendil-works/pi-coding-agent";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
+ import { Worker } from "node:worker_threads";
7
+ //#region src/services/deferredSkills/index.ts
8
+ var deferredSkills_exports = /* @__PURE__ */ __exportAll({
9
+ DeferredSkillLoader: () => DeferredSkillLoader,
10
+ buildPromptWithDeferredSkills: () => buildPromptWithDeferredSkills,
11
+ expandDeferredSkillCommand: () => expandDeferredSkillCommand
12
+ });
13
+ const PI_PACKAGE = "@earendil-works/pi-coding-agent";
14
+ const PACKAGE_MANIFEST = "package.json";
15
+ const SKILL_WORKER_SOURCE = `
16
+ const { parentPort, workerData } = require('node:worker_threads');
17
+ void (async () => {
18
+ try {
19
+ const { loadSkills } = await import(workerData.piModuleUrl);
20
+ parentPort.postMessage({ ok: true, result: loadSkills(workerData.loadOptions) });
21
+ } catch (error) {
22
+ parentPort.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });
23
+ }
24
+ })();
25
+ `;
26
+ function installedPiModuleUrl() {
27
+ const anchors = [
28
+ process.argv[1],
29
+ fileURLToPath(import.meta.url),
30
+ path.join(process.cwd(), PACKAGE_MANIFEST)
31
+ ];
32
+ for (const anchor of anchors) {
33
+ if (!anchor) continue;
34
+ let directory = path.dirname(path.resolve(anchor));
35
+ while (true) {
36
+ const packageRoot = path.join(directory, "node_modules", PI_PACKAGE);
37
+ const manifestPath = path.join(packageRoot, PACKAGE_MANIFEST);
38
+ try {
39
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
40
+ if (typeof manifest.main === "string") {
41
+ const entry = path.resolve(packageRoot, manifest.main);
42
+ if (fs.existsSync(entry)) return pathToFileURL(entry).href;
43
+ }
44
+ } catch {}
45
+ const parent = path.dirname(directory);
46
+ if (parent === directory) break;
47
+ directory = parent;
48
+ }
49
+ }
50
+ throw new Error(`Cannot resolve ${PI_PACKAGE} from the DoomPi or host module trees`);
51
+ }
52
+ /**
53
+ * One session's Doom-selected skill inventory.
54
+ *
55
+ * Construction is deliberately cheap. `start()` schedules the synchronous Pi
56
+ * walker after session_start returns, while `ready()` is the single promise the
57
+ * first input awaits before Pi expands `/skill:name`.
58
+ */
59
+ var DeferredSkillLoader = class {
60
+ #options;
61
+ #promise;
62
+ constructor(options) {
63
+ this.#options = options;
64
+ }
65
+ start() {
66
+ if (this.#promise) return this.#promise;
67
+ if (!this.#options.schedule && !this.#options.load) {
68
+ this.#promise = this.#loadInWorker();
69
+ return this.#promise;
70
+ }
71
+ const schedule = this.#options.schedule ?? ((load) => setImmediate(load));
72
+ this.#promise = new Promise((resolve) => {
73
+ const fail = (error) => {
74
+ resolve(this.#failure(error));
75
+ };
76
+ try {
77
+ schedule(() => {
78
+ try {
79
+ resolve(this.#load());
80
+ } catch (error) {
81
+ fail(error);
82
+ }
83
+ });
84
+ } catch (error) {
85
+ fail(error);
86
+ }
87
+ });
88
+ return this.#promise;
89
+ }
90
+ ready() {
91
+ return this.start();
92
+ }
93
+ #loadOptions() {
94
+ return {
95
+ cwd: this.#options.cwd,
96
+ agentDir: this.#options.agentDir ?? getAgentDir(),
97
+ skillPaths: [...this.#options.skillPaths],
98
+ includeDefaults: false
99
+ };
100
+ }
101
+ #snapshot(result) {
102
+ return {
103
+ skills: result.skills,
104
+ diagnostics: result.diagnostics.map((diagnostic) => `${diagnostic.path ?? this.#options.cwd}: ${diagnostic.message}`)
105
+ };
106
+ }
107
+ #failure(error) {
108
+ return {
109
+ skills: [],
110
+ diagnostics: [`${this.#options.cwd}: ${error instanceof Error ? error.message : String(error)}`]
111
+ };
112
+ }
113
+ #load() {
114
+ return this.#snapshot((this.#options.load ?? loadSkills)(this.#loadOptions()));
115
+ }
116
+ #loadInWorker() {
117
+ return new Promise((resolve) => {
118
+ let settled = false;
119
+ const settle = (snapshot) => {
120
+ if (settled) return;
121
+ settled = true;
122
+ resolve(snapshot);
123
+ };
124
+ let worker;
125
+ try {
126
+ worker = new Worker(SKILL_WORKER_SOURCE, {
127
+ eval: true,
128
+ workerData: {
129
+ piModuleUrl: this.#options.piModuleUrl ?? installedPiModuleUrl(),
130
+ loadOptions: this.#loadOptions()
131
+ }
132
+ });
133
+ } catch (error) {
134
+ settle(this.#failure(error));
135
+ return;
136
+ }
137
+ worker.unref();
138
+ worker.once("message", (message) => {
139
+ if (!message.ok || !message.result) {
140
+ settle(this.#failure(message.error ?? "Skill worker failed"));
141
+ return;
142
+ }
143
+ settle(this.#snapshot(message.result));
144
+ });
145
+ worker.once("error", (error) => settle(this.#failure(error)));
146
+ worker.once("exit", (code) => {
147
+ if (code !== 0) settle(this.#failure(`Skill worker exited with code ${code}`));
148
+ });
149
+ });
150
+ }
151
+ };
152
+ /** Appends only the inventory Pi would append for these deferred skills. */
153
+ function buildPromptWithDeferredSkills(systemPrompt, options, skills) {
154
+ if (options.selectedTools && !options.selectedTools.includes("read")) return systemPrompt;
155
+ return `${systemPrompt}${formatSkillsForPrompt(skills)}`;
156
+ }
157
+ /** Expands a deferred `/skill:name` before Pi consults its synchronous inventory. */
158
+ function expandDeferredSkillCommand(text, skills) {
159
+ if (!text.startsWith("/skill:")) return text;
160
+ const spaceIndex = text.indexOf(" ");
161
+ const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
162
+ const skill = skills.find((candidate) => candidate.name === skillName);
163
+ if (!skill) return text;
164
+ try {
165
+ const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
166
+ const body = stripFrontmatter(fs.readFileSync(skill.filePath, "utf8")).trim();
167
+ const skillBlock = `<skill name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${body}\n</skill>`;
168
+ return args ? `${skillBlock}\n\n${args}` : skillBlock;
169
+ } catch {
170
+ return text;
171
+ }
172
+ }
173
+ //#endregion
174
+ export { deferredSkills_exports as n, expandDeferredSkillCommand as r, DeferredSkillLoader as t };
175
+
176
+ //# sourceMappingURL=deferredSkills-BzhyXnJ4.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"deferredSkills.cjs","names":["fileURLToPath","path","fs","pathToFileURL","#options","#promise","#loadInWorker","#failure","#load","getAgentDir","#snapshot","loadSkills","#loadOptions","Worker","formatSkillsForPrompt","stripFrontmatter"],"sources":["../../src/adapters/deferredSkills.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { Worker } from 'node:worker_threads';\nimport {\n type BuildSystemPromptOptions,\n formatSkillsForPrompt,\n getAgentDir,\n loadSkills,\n type Skill,\n stripFrontmatter,\n} from '@earendil-works/pi-coding-agent';\n\nexport interface DeferredSkillSnapshot {\n skills: Skill[];\n diagnostics: string[];\n}\n\nconst PI_PACKAGE = '@earendil-works/pi-coding-agent';\nconst PACKAGE_MANIFEST = 'package.json';\nconst SKILL_WORKER_SOURCE = `\nconst { parentPort, workerData } = require('node:worker_threads');\nvoid (async () => {\n try {\n const { loadSkills } = await import(workerData.piModuleUrl);\n parentPort.postMessage({ ok: true, result: loadSkills(workerData.loadOptions) });\n } catch (error) {\n parentPort.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n})();\n`;\n\nfunction installedPiModuleUrl(): string {\n const anchors = [process.argv[1], fileURLToPath(import.meta.url), path.join(process.cwd(), PACKAGE_MANIFEST)];\n for (const anchor of anchors) {\n if (!anchor) continue;\n let directory = path.dirname(path.resolve(anchor));\n while (true) {\n const packageRoot = path.join(directory, 'node_modules', PI_PACKAGE);\n const manifestPath = path.join(packageRoot, PACKAGE_MANIFEST);\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { main?: unknown };\n if (typeof manifest.main === 'string') {\n const entry = path.resolve(packageRoot, manifest.main);\n if (fs.existsSync(entry)) return pathToFileURL(entry).href;\n }\n } catch {\n // This anchor does not expose Pi at this level; continue up its module chain.\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n }\n throw new Error(`Cannot resolve ${PI_PACKAGE} from the DoomPi or host module trees`);\n}\n\ninterface SkillWorkerResult {\n ok: boolean;\n result?: { skills: Skill[]; diagnostics: Array<{ path?: string; message: string }> };\n error?: string;\n}\n\nexport interface DeferredSkillLoaderOptions {\n cwd: string;\n skillPaths: readonly string[];\n agentDir?: string;\n piModuleUrl?: string;\n schedule?: (load: () => void) => void;\n load?: (options: { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean }) => {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n };\n}\n\n/**\n * One session's Doom-selected skill inventory.\n *\n * Construction is deliberately cheap. `start()` schedules the synchronous Pi\n * walker after session_start returns, while `ready()` is the single promise the\n * first input awaits before Pi expands `/skill:name`.\n */\nexport class DeferredSkillLoader {\n readonly #options: DeferredSkillLoaderOptions;\n #promise: Promise<DeferredSkillSnapshot> | undefined;\n\n constructor(options: DeferredSkillLoaderOptions) {\n this.#options = options;\n }\n\n start(): Promise<DeferredSkillSnapshot> {\n if (this.#promise) return this.#promise;\n\n if (!this.#options.schedule && !this.#options.load) {\n this.#promise = this.#loadInWorker();\n return this.#promise;\n }\n\n const schedule = this.#options.schedule ?? ((load: () => void) => setImmediate(load));\n this.#promise = new Promise((resolve) => {\n const fail = (error: unknown): void => {\n resolve(this.#failure(error));\n };\n try {\n schedule(() => {\n try {\n resolve(this.#load());\n } catch (error) {\n fail(error);\n }\n });\n } catch (error) {\n fail(error);\n }\n });\n return this.#promise;\n }\n\n ready(): Promise<DeferredSkillSnapshot> {\n return this.start();\n }\n\n #loadOptions(): { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean } {\n return {\n cwd: this.#options.cwd,\n agentDir: this.#options.agentDir ?? getAgentDir(),\n skillPaths: [...this.#options.skillPaths],\n includeDefaults: false,\n };\n }\n\n #snapshot(result: {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n }): DeferredSkillSnapshot {\n return {\n skills: result.skills,\n diagnostics: result.diagnostics.map(\n (diagnostic) => `${diagnostic.path ?? this.#options.cwd}: ${diagnostic.message}`,\n ),\n };\n }\n\n #failure(error: unknown): DeferredSkillSnapshot {\n return {\n skills: [],\n diagnostics: [`${this.#options.cwd}: ${error instanceof Error ? error.message : String(error)}`],\n };\n }\n\n #load(): DeferredSkillSnapshot {\n return this.#snapshot((this.#options.load ?? loadSkills)(this.#loadOptions()));\n }\n\n #loadInWorker(): Promise<DeferredSkillSnapshot> {\n return new Promise((resolve) => {\n let settled = false;\n const settle = (snapshot: DeferredSkillSnapshot): void => {\n if (settled) return;\n settled = true;\n resolve(snapshot);\n };\n let worker: Worker;\n try {\n worker = new Worker(SKILL_WORKER_SOURCE, {\n eval: true,\n workerData: {\n piModuleUrl: this.#options.piModuleUrl ?? installedPiModuleUrl(),\n loadOptions: this.#loadOptions(),\n },\n });\n } catch (error) {\n settle(this.#failure(error));\n return;\n }\n worker.unref();\n worker.once('message', (message: SkillWorkerResult) => {\n if (!message.ok || !message.result) {\n settle(this.#failure(message.error ?? 'Skill worker failed'));\n return;\n }\n settle(this.#snapshot(message.result));\n });\n worker.once('error', (error) => settle(this.#failure(error)));\n worker.once('exit', (code) => {\n if (code !== 0) settle(this.#failure(`Skill worker exited with code ${code}`));\n });\n });\n }\n}\n\n/** Appends only the inventory Pi would append for these deferred skills. */\nexport function buildPromptWithDeferredSkills(\n systemPrompt: string,\n options: BuildSystemPromptOptions,\n skills: Skill[],\n): string {\n if (options.selectedTools && !options.selectedTools.includes('read')) return systemPrompt;\n return `${systemPrompt}${formatSkillsForPrompt(skills)}`;\n}\n\n/** Expands a deferred `/skill:name` before Pi consults its synchronous inventory. */\nexport function expandDeferredSkillCommand(text: string, skills: readonly Skill[]): string {\n if (!text.startsWith('/skill:')) return text;\n const spaceIndex = text.indexOf(' ');\n const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);\n const skill = skills.find((candidate) => candidate.name === skillName);\n if (!skill) return text;\n\n try {\n const args = spaceIndex === -1 ? '' : text.slice(spaceIndex + 1).trim();\n const body = stripFrontmatter(fs.readFileSync(skill.filePath, 'utf8')).trim();\n const skillBlock = `<skill name=\"${skill.name}\" location=\"${skill.filePath}\">\\nReferences are relative to ${skill.baseDir}.\\n\\n${body}\\n</skill>`;\n return args ? `${skillBlock}\\n\\n${args}` : skillBlock;\n } catch {\n // Pi uses the same literal-text fallback if a skill disappears between\n // discovery and submission; the agent can still respond to the command.\n return text;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"deferredSkills-BzhyXnJ4.mjs","names":[],"sources":["../src/services/deferredSkills/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { Worker } from 'node:worker_threads';\n\nimport {\n type BuildSystemPromptOptions,\n formatSkillsForPrompt,\n getAgentDir,\n loadSkills,\n type Skill,\n stripFrontmatter,\n} from '@earendil-works/pi-coding-agent';\n\nexport interface DeferredSkillSnapshot {\n skills: Skill[];\n diagnostics: string[];\n}\n\nconst PI_PACKAGE = '@earendil-works/pi-coding-agent';\nconst PACKAGE_MANIFEST = 'package.json';\nconst SKILL_WORKER_SOURCE = `\nconst { parentPort, workerData } = require('node:worker_threads');\nvoid (async () => {\n try {\n const { loadSkills } = await import(workerData.piModuleUrl);\n parentPort.postMessage({ ok: true, result: loadSkills(workerData.loadOptions) });\n } catch (error) {\n parentPort.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n})();\n`;\n\nfunction installedPiModuleUrl(): string {\n const anchors = [process.argv[1], fileURLToPath(import.meta.url), path.join(process.cwd(), PACKAGE_MANIFEST)];\n for (const anchor of anchors) {\n if (!anchor) continue;\n let directory = path.dirname(path.resolve(anchor));\n while (true) {\n const packageRoot = path.join(directory, 'node_modules', PI_PACKAGE);\n const manifestPath = path.join(packageRoot, PACKAGE_MANIFEST);\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { main?: unknown };\n if (typeof manifest.main === 'string') {\n const entry = path.resolve(packageRoot, manifest.main);\n if (fs.existsSync(entry)) return pathToFileURL(entry).href;\n }\n } catch {\n // This anchor does not expose Pi at this level; continue up its module chain.\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n }\n throw new Error(`Cannot resolve ${PI_PACKAGE} from the DoomPi or host module trees`);\n}\n\ninterface SkillWorkerResult {\n ok: boolean;\n result?: { skills: Skill[]; diagnostics: Array<{ path?: string; message: string }> };\n error?: string;\n}\n\nexport interface DeferredSkillLoaderOptions {\n cwd: string;\n skillPaths: readonly string[];\n agentDir?: string;\n piModuleUrl?: string;\n schedule?: (load: () => void) => void;\n load?: (options: { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean }) => {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n };\n}\n\n/**\n * One session's Doom-selected skill inventory.\n *\n * Construction is deliberately cheap. `start()` schedules the synchronous Pi\n * walker after session_start returns, while `ready()` is the single promise the\n * first input awaits before Pi expands `/skill:name`.\n */\nexport class DeferredSkillLoader {\n readonly #options: DeferredSkillLoaderOptions;\n #promise: Promise<DeferredSkillSnapshot> | undefined;\n\n constructor(options: DeferredSkillLoaderOptions) {\n this.#options = options;\n }\n\n start(): Promise<DeferredSkillSnapshot> {\n if (this.#promise) return this.#promise;\n\n if (!this.#options.schedule && !this.#options.load) {\n this.#promise = this.#loadInWorker();\n return this.#promise;\n }\n\n const schedule = this.#options.schedule ?? ((load: () => void) => setImmediate(load));\n this.#promise = new Promise((resolve) => {\n const fail = (error: unknown): void => {\n resolve(this.#failure(error));\n };\n try {\n schedule(() => {\n try {\n resolve(this.#load());\n } catch (error) {\n fail(error);\n }\n });\n } catch (error) {\n fail(error);\n }\n });\n return this.#promise;\n }\n\n ready(): Promise<DeferredSkillSnapshot> {\n return this.start();\n }\n\n #loadOptions(): { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean } {\n return {\n cwd: this.#options.cwd,\n agentDir: this.#options.agentDir ?? getAgentDir(),\n skillPaths: [...this.#options.skillPaths],\n includeDefaults: false,\n };\n }\n\n #snapshot(result: {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n }): DeferredSkillSnapshot {\n return {\n skills: result.skills,\n diagnostics: result.diagnostics.map(\n (diagnostic) => `${diagnostic.path ?? this.#options.cwd}: ${diagnostic.message}`,\n ),\n };\n }\n\n #failure(error: unknown): DeferredSkillSnapshot {\n return {\n skills: [],\n diagnostics: [`${this.#options.cwd}: ${error instanceof Error ? error.message : String(error)}`],\n };\n }\n\n #load(): DeferredSkillSnapshot {\n return this.#snapshot((this.#options.load ?? loadSkills)(this.#loadOptions()));\n }\n\n #loadInWorker(): Promise<DeferredSkillSnapshot> {\n return new Promise((resolve) => {\n let settled = false;\n const settle = (snapshot: DeferredSkillSnapshot): void => {\n if (settled) return;\n settled = true;\n resolve(snapshot);\n };\n let worker: Worker;\n try {\n worker = new Worker(SKILL_WORKER_SOURCE, {\n eval: true,\n workerData: {\n piModuleUrl: this.#options.piModuleUrl ?? installedPiModuleUrl(),\n loadOptions: this.#loadOptions(),\n },\n });\n } catch (error) {\n settle(this.#failure(error));\n return;\n }\n worker.unref();\n worker.once('message', (message: SkillWorkerResult) => {\n if (!message.ok || !message.result) {\n settle(this.#failure(message.error ?? 'Skill worker failed'));\n return;\n }\n settle(this.#snapshot(message.result));\n });\n worker.once('error', (error) => settle(this.#failure(error)));\n worker.once('exit', (code) => {\n if (code !== 0) settle(this.#failure(`Skill worker exited with code ${code}`));\n });\n });\n }\n}\n\n/** Appends only the inventory Pi would append for these deferred skills. */\nexport function buildPromptWithDeferredSkills(\n systemPrompt: string,\n options: BuildSystemPromptOptions,\n skills: Skill[],\n): string {\n if (options.selectedTools && !options.selectedTools.includes('read')) return systemPrompt;\n return `${systemPrompt}${formatSkillsForPrompt(skills)}`;\n}\n\n/** Expands a deferred `/skill:name` before Pi consults its synchronous inventory. */\nexport function expandDeferredSkillCommand(text: string, skills: readonly Skill[]): string {\n if (!text.startsWith('/skill:')) return text;\n const spaceIndex = text.indexOf(' ');\n const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);\n const skill = skills.find((candidate) => candidate.name === skillName);\n if (!skill) return text;\n\n try {\n const args = spaceIndex === -1 ? '' : text.slice(spaceIndex + 1).trim();\n const body = stripFrontmatter(fs.readFileSync(skill.filePath, 'utf8')).trim();\n const skillBlock = `<skill name=\"${skill.name}\" location=\"${skill.filePath}\">\\nReferences are relative to ${skill.baseDir}.\\n\\n${body}\\n</skill>`;\n return args ? `${skillBlock}\\n\\n${args}` : skillBlock;\n } catch {\n // Pi uses the same literal-text fallback if a skill disappears between\n // discovery and submission; the agent can still respond to the command.\n return text;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,195 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
+ let node_fs = require("node:fs");
3
+ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
4
+ let node_path = require("node:path");
5
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
6
+ let _earendil_works_pi_coding_agent = require("@earendil-works/pi-coding-agent");
7
+ let node_url = require("node:url");
8
+ let node_worker_threads = require("node:worker_threads");
9
+ //#region src/services/deferredSkills/index.ts
10
+ var deferredSkills_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
11
+ DeferredSkillLoader: () => DeferredSkillLoader,
12
+ buildPromptWithDeferredSkills: () => buildPromptWithDeferredSkills,
13
+ expandDeferredSkillCommand: () => expandDeferredSkillCommand
14
+ });
15
+ const PI_PACKAGE = "@earendil-works/pi-coding-agent";
16
+ const PACKAGE_MANIFEST = "package.json";
17
+ const SKILL_WORKER_SOURCE = `
18
+ const { parentPort, workerData } = require('node:worker_threads');
19
+ void (async () => {
20
+ try {
21
+ const { loadSkills } = await import(workerData.piModuleUrl);
22
+ parentPort.postMessage({ ok: true, result: loadSkills(workerData.loadOptions) });
23
+ } catch (error) {
24
+ parentPort.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });
25
+ }
26
+ })();
27
+ `;
28
+ function installedPiModuleUrl() {
29
+ const anchors = [
30
+ process.argv[1],
31
+ (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href),
32
+ node_path.default.join(process.cwd(), PACKAGE_MANIFEST)
33
+ ];
34
+ for (const anchor of anchors) {
35
+ if (!anchor) continue;
36
+ let directory = node_path.default.dirname(node_path.default.resolve(anchor));
37
+ while (true) {
38
+ const packageRoot = node_path.default.join(directory, "node_modules", PI_PACKAGE);
39
+ const manifestPath = node_path.default.join(packageRoot, PACKAGE_MANIFEST);
40
+ try {
41
+ const manifest = JSON.parse(node_fs.default.readFileSync(manifestPath, "utf8"));
42
+ if (typeof manifest.main === "string") {
43
+ const entry = node_path.default.resolve(packageRoot, manifest.main);
44
+ if (node_fs.default.existsSync(entry)) return (0, node_url.pathToFileURL)(entry).href;
45
+ }
46
+ } catch {}
47
+ const parent = node_path.default.dirname(directory);
48
+ if (parent === directory) break;
49
+ directory = parent;
50
+ }
51
+ }
52
+ throw new Error(`Cannot resolve ${PI_PACKAGE} from the DoomPi or host module trees`);
53
+ }
54
+ /**
55
+ * One session's Doom-selected skill inventory.
56
+ *
57
+ * Construction is deliberately cheap. `start()` schedules the synchronous Pi
58
+ * walker after session_start returns, while `ready()` is the single promise the
59
+ * first input awaits before Pi expands `/skill:name`.
60
+ */
61
+ var DeferredSkillLoader = class {
62
+ #options;
63
+ #promise;
64
+ constructor(options) {
65
+ this.#options = options;
66
+ }
67
+ start() {
68
+ if (this.#promise) return this.#promise;
69
+ if (!this.#options.schedule && !this.#options.load) {
70
+ this.#promise = this.#loadInWorker();
71
+ return this.#promise;
72
+ }
73
+ const schedule = this.#options.schedule ?? ((load) => setImmediate(load));
74
+ this.#promise = new Promise((resolve) => {
75
+ const fail = (error) => {
76
+ resolve(this.#failure(error));
77
+ };
78
+ try {
79
+ schedule(() => {
80
+ try {
81
+ resolve(this.#load());
82
+ } catch (error) {
83
+ fail(error);
84
+ }
85
+ });
86
+ } catch (error) {
87
+ fail(error);
88
+ }
89
+ });
90
+ return this.#promise;
91
+ }
92
+ ready() {
93
+ return this.start();
94
+ }
95
+ #loadOptions() {
96
+ return {
97
+ cwd: this.#options.cwd,
98
+ agentDir: this.#options.agentDir ?? (0, _earendil_works_pi_coding_agent.getAgentDir)(),
99
+ skillPaths: [...this.#options.skillPaths],
100
+ includeDefaults: false
101
+ };
102
+ }
103
+ #snapshot(result) {
104
+ return {
105
+ skills: result.skills,
106
+ diagnostics: result.diagnostics.map((diagnostic) => `${diagnostic.path ?? this.#options.cwd}: ${diagnostic.message}`)
107
+ };
108
+ }
109
+ #failure(error) {
110
+ return {
111
+ skills: [],
112
+ diagnostics: [`${this.#options.cwd}: ${error instanceof Error ? error.message : String(error)}`]
113
+ };
114
+ }
115
+ #load() {
116
+ return this.#snapshot((this.#options.load ?? _earendil_works_pi_coding_agent.loadSkills)(this.#loadOptions()));
117
+ }
118
+ #loadInWorker() {
119
+ return new Promise((resolve) => {
120
+ let settled = false;
121
+ const settle = (snapshot) => {
122
+ if (settled) return;
123
+ settled = true;
124
+ resolve(snapshot);
125
+ };
126
+ let worker;
127
+ try {
128
+ worker = new node_worker_threads.Worker(SKILL_WORKER_SOURCE, {
129
+ eval: true,
130
+ workerData: {
131
+ piModuleUrl: this.#options.piModuleUrl ?? installedPiModuleUrl(),
132
+ loadOptions: this.#loadOptions()
133
+ }
134
+ });
135
+ } catch (error) {
136
+ settle(this.#failure(error));
137
+ return;
138
+ }
139
+ worker.unref();
140
+ worker.once("message", (message) => {
141
+ if (!message.ok || !message.result) {
142
+ settle(this.#failure(message.error ?? "Skill worker failed"));
143
+ return;
144
+ }
145
+ settle(this.#snapshot(message.result));
146
+ });
147
+ worker.once("error", (error) => settle(this.#failure(error)));
148
+ worker.once("exit", (code) => {
149
+ if (code !== 0) settle(this.#failure(`Skill worker exited with code ${code}`));
150
+ });
151
+ });
152
+ }
153
+ };
154
+ /** Appends only the inventory Pi would append for these deferred skills. */
155
+ function buildPromptWithDeferredSkills(systemPrompt, options, skills) {
156
+ if (options.selectedTools && !options.selectedTools.includes("read")) return systemPrompt;
157
+ return `${systemPrompt}${(0, _earendil_works_pi_coding_agent.formatSkillsForPrompt)(skills)}`;
158
+ }
159
+ /** Expands a deferred `/skill:name` before Pi consults its synchronous inventory. */
160
+ function expandDeferredSkillCommand(text, skills) {
161
+ if (!text.startsWith("/skill:")) return text;
162
+ const spaceIndex = text.indexOf(" ");
163
+ const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
164
+ const skill = skills.find((candidate) => candidate.name === skillName);
165
+ if (!skill) return text;
166
+ try {
167
+ const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
168
+ const body = (0, _earendil_works_pi_coding_agent.stripFrontmatter)(node_fs.default.readFileSync(skill.filePath, "utf8")).trim();
169
+ const skillBlock = `<skill name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${body}\n</skill>`;
170
+ return args ? `${skillBlock}\n\n${args}` : skillBlock;
171
+ } catch {
172
+ return text;
173
+ }
174
+ }
175
+ //#endregion
176
+ Object.defineProperty(exports, "DeferredSkillLoader", {
177
+ enumerable: true,
178
+ get: function() {
179
+ return DeferredSkillLoader;
180
+ }
181
+ });
182
+ Object.defineProperty(exports, "deferredSkills_exports", {
183
+ enumerable: true,
184
+ get: function() {
185
+ return deferredSkills_exports;
186
+ }
187
+ });
188
+ Object.defineProperty(exports, "expandDeferredSkillCommand", {
189
+ enumerable: true,
190
+ get: function() {
191
+ return expandDeferredSkillCommand;
192
+ }
193
+ });
194
+
195
+ //# sourceMappingURL=deferredSkills-DF6UCAsk.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferredSkills-DF6UCAsk.cjs","names":["fileURLToPath","path","fs","pathToFileURL","getAgentDir","loadSkills","Worker","formatSkillsForPrompt","stripFrontmatter"],"sources":["../src/services/deferredSkills/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { Worker } from 'node:worker_threads';\n\nimport {\n type BuildSystemPromptOptions,\n formatSkillsForPrompt,\n getAgentDir,\n loadSkills,\n type Skill,\n stripFrontmatter,\n} from '@earendil-works/pi-coding-agent';\n\nexport interface DeferredSkillSnapshot {\n skills: Skill[];\n diagnostics: string[];\n}\n\nconst PI_PACKAGE = '@earendil-works/pi-coding-agent';\nconst PACKAGE_MANIFEST = 'package.json';\nconst SKILL_WORKER_SOURCE = `\nconst { parentPort, workerData } = require('node:worker_threads');\nvoid (async () => {\n try {\n const { loadSkills } = await import(workerData.piModuleUrl);\n parentPort.postMessage({ ok: true, result: loadSkills(workerData.loadOptions) });\n } catch (error) {\n parentPort.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n})();\n`;\n\nfunction installedPiModuleUrl(): string {\n const anchors = [process.argv[1], fileURLToPath(import.meta.url), path.join(process.cwd(), PACKAGE_MANIFEST)];\n for (const anchor of anchors) {\n if (!anchor) continue;\n let directory = path.dirname(path.resolve(anchor));\n while (true) {\n const packageRoot = path.join(directory, 'node_modules', PI_PACKAGE);\n const manifestPath = path.join(packageRoot, PACKAGE_MANIFEST);\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { main?: unknown };\n if (typeof manifest.main === 'string') {\n const entry = path.resolve(packageRoot, manifest.main);\n if (fs.existsSync(entry)) return pathToFileURL(entry).href;\n }\n } catch {\n // This anchor does not expose Pi at this level; continue up its module chain.\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n }\n throw new Error(`Cannot resolve ${PI_PACKAGE} from the DoomPi or host module trees`);\n}\n\ninterface SkillWorkerResult {\n ok: boolean;\n result?: { skills: Skill[]; diagnostics: Array<{ path?: string; message: string }> };\n error?: string;\n}\n\nexport interface DeferredSkillLoaderOptions {\n cwd: string;\n skillPaths: readonly string[];\n agentDir?: string;\n piModuleUrl?: string;\n schedule?: (load: () => void) => void;\n load?: (options: { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean }) => {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n };\n}\n\n/**\n * One session's Doom-selected skill inventory.\n *\n * Construction is deliberately cheap. `start()` schedules the synchronous Pi\n * walker after session_start returns, while `ready()` is the single promise the\n * first input awaits before Pi expands `/skill:name`.\n */\nexport class DeferredSkillLoader {\n readonly #options: DeferredSkillLoaderOptions;\n #promise: Promise<DeferredSkillSnapshot> | undefined;\n\n constructor(options: DeferredSkillLoaderOptions) {\n this.#options = options;\n }\n\n start(): Promise<DeferredSkillSnapshot> {\n if (this.#promise) return this.#promise;\n\n if (!this.#options.schedule && !this.#options.load) {\n this.#promise = this.#loadInWorker();\n return this.#promise;\n }\n\n const schedule = this.#options.schedule ?? ((load: () => void) => setImmediate(load));\n this.#promise = new Promise((resolve) => {\n const fail = (error: unknown): void => {\n resolve(this.#failure(error));\n };\n try {\n schedule(() => {\n try {\n resolve(this.#load());\n } catch (error) {\n fail(error);\n }\n });\n } catch (error) {\n fail(error);\n }\n });\n return this.#promise;\n }\n\n ready(): Promise<DeferredSkillSnapshot> {\n return this.start();\n }\n\n #loadOptions(): { cwd: string; agentDir: string; skillPaths: string[]; includeDefaults: boolean } {\n return {\n cwd: this.#options.cwd,\n agentDir: this.#options.agentDir ?? getAgentDir(),\n skillPaths: [...this.#options.skillPaths],\n includeDefaults: false,\n };\n }\n\n #snapshot(result: {\n skills: Skill[];\n diagnostics: Array<{ path?: string; message: string }>;\n }): DeferredSkillSnapshot {\n return {\n skills: result.skills,\n diagnostics: result.diagnostics.map(\n (diagnostic) => `${diagnostic.path ?? this.#options.cwd}: ${diagnostic.message}`,\n ),\n };\n }\n\n #failure(error: unknown): DeferredSkillSnapshot {\n return {\n skills: [],\n diagnostics: [`${this.#options.cwd}: ${error instanceof Error ? error.message : String(error)}`],\n };\n }\n\n #load(): DeferredSkillSnapshot {\n return this.#snapshot((this.#options.load ?? loadSkills)(this.#loadOptions()));\n }\n\n #loadInWorker(): Promise<DeferredSkillSnapshot> {\n return new Promise((resolve) => {\n let settled = false;\n const settle = (snapshot: DeferredSkillSnapshot): void => {\n if (settled) return;\n settled = true;\n resolve(snapshot);\n };\n let worker: Worker;\n try {\n worker = new Worker(SKILL_WORKER_SOURCE, {\n eval: true,\n workerData: {\n piModuleUrl: this.#options.piModuleUrl ?? installedPiModuleUrl(),\n loadOptions: this.#loadOptions(),\n },\n });\n } catch (error) {\n settle(this.#failure(error));\n return;\n }\n worker.unref();\n worker.once('message', (message: SkillWorkerResult) => {\n if (!message.ok || !message.result) {\n settle(this.#failure(message.error ?? 'Skill worker failed'));\n return;\n }\n settle(this.#snapshot(message.result));\n });\n worker.once('error', (error) => settle(this.#failure(error)));\n worker.once('exit', (code) => {\n if (code !== 0) settle(this.#failure(`Skill worker exited with code ${code}`));\n });\n });\n }\n}\n\n/** Appends only the inventory Pi would append for these deferred skills. */\nexport function buildPromptWithDeferredSkills(\n systemPrompt: string,\n options: BuildSystemPromptOptions,\n skills: Skill[],\n): string {\n if (options.selectedTools && !options.selectedTools.includes('read')) return systemPrompt;\n return `${systemPrompt}${formatSkillsForPrompt(skills)}`;\n}\n\n/** Expands a deferred `/skill:name` before Pi consults its synchronous inventory. */\nexport function expandDeferredSkillCommand(text: string, skills: readonly Skill[]): string {\n if (!text.startsWith('/skill:')) return text;\n const spaceIndex = text.indexOf(' ');\n const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);\n const skill = skills.find((candidate) => candidate.name === skillName);\n if (!skill) return text;\n\n try {\n const args = spaceIndex === -1 ? '' : text.slice(spaceIndex + 1).trim();\n const body = stripFrontmatter(fs.readFileSync(skill.filePath, 'utf8')).trim();\n const skillBlock = `<skill name=\"${skill.name}\" location=\"${skill.filePath}\">\\nReferences are relative to ${skill.baseDir}.\\n\\n${body}\\n</skill>`;\n return args ? `${skillBlock}\\n\\n${args}` : skillBlock;\n } catch {\n // Pi uses the same literal-text fallback if a skill disappears between\n // discovery and submission; the agent can still respond to the command.\n return text;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { defineMcpWidget } from "@agimon-ai/doompi-core/web";
2
+ import { McpToolFields, McpToolFrame, McpToolOutput } from "@agimon-ai/doompi-web-components";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/load_skill.mcp.tsx
5
+ function LoadSkillMcpWidget(props) {
6
+ return /* @__PURE__ */ jsxs(McpToolFrame, {
7
+ ...props,
8
+ title: "Load skill",
9
+ children: [/* @__PURE__ */ jsx(McpToolFields, { fields: [["Skill", props.args.name]] }), /* @__PURE__ */ jsx(McpToolOutput, { result: props.result })]
10
+ });
11
+ }
12
+ var load_skill_mcp_default = defineMcpWidget(LoadSkillMcpWidget);
13
+ //#endregion
14
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/search_skills.mcp.tsx
15
+ function SearchSkillsMcpWidget(props) {
16
+ return /* @__PURE__ */ jsxs(McpToolFrame, {
17
+ ...props,
18
+ title: "Search skills",
19
+ children: [/* @__PURE__ */ jsx(McpToolFields, { fields: [["Query", props.args.query]] }), /* @__PURE__ */ jsx(McpToolOutput, { result: props.result })]
20
+ });
21
+ }
22
+ //#endregion
23
+ //#region generated/mcp-ui.ts
24
+ const widgets = {
25
+ "@agimon-ai/doompi-skill/load_skill": load_skill_mcp_default,
26
+ "@agimon-ai/doompi-skill/search_skills": defineMcpWidget(SearchSkillsMcpWidget)
27
+ };
28
+ //#endregion
29
+ export { widgets };
30
+
31
+ //# sourceMappingURL=mcp-ui.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-ui.mjs","names":["Widget0","Widget1"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/load_skill.mcp.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/search_skills.mcp.tsx","../../generated/mcp-ui.ts"],"sourcesContent":["import { defineMcpWidget, type DoomMcpWidgetProps } from '@agimon-ai/doompi-core/web';\nimport { McpToolFrame, McpToolFields, McpToolOutput } from '@agimon-ai/doompi-web-components';\n\nfunction LoadSkillMcpWidget(props: DoomMcpWidgetProps) {\n return (\n <McpToolFrame {...props} title=\"Load skill\">\n <McpToolFields fields={[['Skill', props.args.name]]} />\n <McpToolOutput result={props.result} />\n </McpToolFrame>\n );\n}\n\nexport default defineMcpWidget(LoadSkillMcpWidget);\n","import { defineMcpWidget, type DoomMcpWidgetProps } from '@agimon-ai/doompi-core/web';\nimport { McpToolFrame, McpToolFields, McpToolOutput } from '@agimon-ai/doompi-web-components';\n\nfunction SearchSkillsMcpWidget(props: DoomMcpWidgetProps) {\n return (\n <McpToolFrame {...props} title=\"Search skills\">\n <McpToolFields fields={[['Query', props.args.query]]} />\n <McpToolOutput result={props.result} />\n </McpToolFrame>\n );\n}\n\nexport default defineMcpWidget(SearchSkillsMcpWidget);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport type { ComponentType } from 'react';\nimport type { DoomMcpWidgetProps } from '@agimon-ai/doompi-core/mcpWidget';\nimport Widget0 from \"../src/extensions/workspaces/sessions/(frontend)/tool/load_skill.mcp\";\nimport Widget1 from \"../src/extensions/workspaces/sessions/(frontend)/tool/search_skills.mcp\";\n\nexport const widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>> = {\n \"@agimon-ai/doompi-skill/load_skill\": Widget0,\n \"@agimon-ai/doompi-skill/search_skills\": Widget1,\n};\n"],"mappings":";;;;AAGA,SAAS,mBAAmB,OAA2B;CACrD,OACE,qBAAC,cAAD;EAAc,GAAI;EAAO,OAAM;EAA/B,UAAA,CACE,oBAAC,eAAD,EAAe,QAAQ,CAAC,CAAC,SAAS,MAAM,KAAK,IAAI,CAAC,EAAI,CAAA,GACtD,oBAAC,eAAD,EAAe,QAAQ,MAAM,OAAS,CAAA,CAC1B;;AAElB;AAEA,IAAA,yBAAe,gBAAgB,kBAAkB;;;ACTjD,SAAS,sBAAsB,OAA2B;CACxD,OACE,qBAAC,cAAD;EAAc,GAAI;EAAO,OAAM;EAA/B,UAAA,CACE,oBAAC,eAAD,EAAe,QAAQ,CAAC,CAAC,SAAS,MAAM,KAAK,KAAK,CAAC,EAAI,CAAA,GACvD,oBAAC,eAAD,EAAe,QAAQ,MAAM,OAAS,CAAA,CAC1B;;AAElB;;;ACJA,MAAa,UAAuE;CAClF,sCAAsCA;CACtC,yCDIa,gBAAgB,qBCJYC;AAC3C"}