@agimon-ai/doompi-help 0.0.1-alpha.5 → 0.0.1-alpha.51
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.
- package/README.md +37 -11
- package/dist/adapters/helpStorage.cjs +1 -1
- package/dist/adapters/helpStorage.cjs.map +1 -1
- package/dist/adapters/helpStorage.mjs +1 -1
- package/dist/adapters/helpStorage.mjs.map +1 -1
- package/dist/adapters/pi/extension.cjs +2 -0
- package/dist/adapters/pi/extension.cjs.map +1 -0
- package/dist/adapters/pi/extension.d.cts +11 -0
- package/dist/adapters/pi/extension.d.cts.map +1 -0
- package/dist/adapters/pi/extension.d.mts +11 -0
- package/dist/adapters/pi/extension.d.mts.map +1 -0
- package/dist/adapters/pi/extension.mjs +2 -0
- package/dist/adapters/pi/extension.mjs.map +1 -0
- package/dist/adapters/pi/helpCommand.cjs +2 -0
- package/dist/adapters/pi/helpCommand.cjs.map +1 -0
- package/dist/adapters/pi/helpCommand.mjs +2 -0
- package/dist/adapters/pi/helpCommand.mjs.map +1 -0
- package/dist/adapters/pi/helpMode.cjs +1 -1
- package/dist/adapters/pi/helpMode.cjs.map +1 -1
- package/dist/adapters/pi/helpMode.mjs +1 -1
- package/dist/adapters/pi/helpMode.mjs.map +1 -1
- package/dist/container/index.cjs.map +1 -1
- package/dist/container/index.d.cts +1 -2
- package/dist/container/index.d.cts.map +1 -1
- package/dist/container/index.d.mts +1 -2
- package/dist/container/index.d.mts.map +1 -1
- package/dist/container/index.mjs.map +1 -1
- package/dist/extensions/pi.cjs +1 -0
- package/dist/extensions/pi.d.cts +2 -0
- package/dist/extensions/pi.d.mts +2 -0
- package/dist/extensions/pi.mjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/types/help.d.cts +2 -3
- package/dist/types/help.d.cts.map +1 -1
- package/dist/types/help.d.mts +2 -3
- package/dist/types/help.d.mts.map +1 -1
- package/llms.txt +4 -0
- package/package.json +39 -18
- package/src/exports/webClient.ts +1 -0
- package/src/prompts/doompi-use-help/SKILL.md +27 -0
- package/src/web/index.ts +21 -0
- package/src/web/tsconfig.json +22 -0
- package/dist/extensions/doom.cjs +0 -2
- package/dist/extensions/doom.cjs.map +0 -1
- package/dist/extensions/doom.d.cts +0 -8
- package/dist/extensions/doom.d.cts.map +0 -1
- package/dist/extensions/doom.d.mts +0 -8
- package/dist/extensions/doom.d.mts.map +0 -1
- package/dist/extensions/doom.mjs +0 -2
- package/dist/extensions/doom.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
# @agimon-ai/doompi-help
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Load package-owned DoomPi guidance only when Help mode is active.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Part of the [DoomPi distribution](https://www.npmjs.com/package/@agimon-ai/doompi).
|
|
6
|
+
|
|
7
|
+
Packages contribute concise `llms.txt` indexes. Help keeps them out of the default model context and exposes them only while Help mode is active.
|
|
6
8
|
|
|
7
9
|
> **Alpha:** Help contribution contracts may change between releases.
|
|
8
10
|
|
|
9
11
|
## Requirements
|
|
10
12
|
|
|
11
13
|
- Node.js 22.19.0 or newer
|
|
12
|
-
- Pi 0.
|
|
14
|
+
- Pi 0.85.0
|
|
13
15
|
|
|
14
16
|
## Install
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
The seeded `modes.yaml` selects Help in `default.packages`. It is configurable, not fixed host
|
|
19
|
+
infrastructure: keep it in that bundle or select it through a layer. To load it directly in Pi:
|
|
17
20
|
|
|
18
21
|
```bash
|
|
19
22
|
pi install npm:@agimon-ai/doompi-help
|
|
20
23
|
```
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
Pi loads the package through `@agimon-ai/doompi-help/extensions/pi`. DoomPi and standalone Pi use
|
|
26
|
+
the same extension.
|
|
23
27
|
|
|
24
28
|
## Activate and deactivate
|
|
25
29
|
|
|
26
|
-
In an interactive DoomPi session, use `SPC h e`. Headless clients
|
|
30
|
+
In an interactive DoomPi session, use `SPC h e`. Headless DoomPi clients invoke the Help action
|
|
31
|
+
through the shared minor-mode catalog service. In standalone Pi, run `/doom-help`; the command does
|
|
32
|
+
not require Doom config or Leader Space.
|
|
27
33
|
|
|
28
34
|
Activation resolves each contributor in this order:
|
|
29
35
|
|
|
@@ -31,21 +37,39 @@ Activation resolves each contributor in this order:
|
|
|
31
37
|
2. an immutable exact-version cache;
|
|
32
38
|
3. a verified exact-version unpkg fallback.
|
|
33
39
|
|
|
34
|
-
Deactivation
|
|
40
|
+
Deactivation withdraws the active Help skills before the next prompt or catalog read. Cached
|
|
41
|
+
package content or previously generated wrappers may remain on disk, but they are no longer active
|
|
42
|
+
model context.
|
|
43
|
+
|
|
44
|
+
The package contributes `doompi-use-help`. A standard parent catalog can compose two groups from
|
|
45
|
+
the packages that are present:
|
|
46
|
+
|
|
47
|
+
- **How to author:** extension, Config, Major Mode, Domain, Profile, Hook, Workflow, and Skill
|
|
48
|
+
guidance under explicit `doompi-author-*` names.
|
|
49
|
+
- **How to use:** Help, Voice, Plan, Goal, Loop, Workflow, Runner, MCP, and Skill guidance under
|
|
50
|
+
explicit `doompi-use-*` names.
|
|
35
51
|
|
|
36
|
-
|
|
52
|
+
Each owning package registers its descriptors and exact package index through the shared Help
|
|
53
|
+
service. Missing or inactive packages do not leave placeholder skills in the catalog.
|
|
37
54
|
|
|
38
55
|
## Parent and child behavior
|
|
39
56
|
|
|
40
|
-
|
|
57
|
+
Parent and child sessions use the same extension entry when their composition selects Help. Replacing a session removes
|
|
58
|
+
the previous Help service, its contributions, and its UI and mode integrations before activating
|
|
59
|
+
the replacement.
|
|
60
|
+
|
|
61
|
+
Root and axis authoring guidance is parent-only when those packages are absent from detached-child
|
|
62
|
+
composition. Config and selected child features can still contribute package guidance to a
|
|
63
|
+
detached child.
|
|
41
64
|
|
|
42
65
|
## Public API
|
|
43
66
|
|
|
44
67
|
```ts
|
|
45
|
-
import {
|
|
68
|
+
import { helpExtension, installHelpRuntime } from '@agimon-ai/doompi-help';
|
|
46
69
|
```
|
|
47
70
|
|
|
48
|
-
The root export is intended for
|
|
71
|
+
The root export is intended for host integrations and tests. Users activate Help through the normal
|
|
72
|
+
extension.
|
|
49
73
|
|
|
50
74
|
## Development
|
|
51
75
|
|
|
@@ -56,6 +80,8 @@ pnpm test
|
|
|
56
80
|
pnpm lint
|
|
57
81
|
```
|
|
58
82
|
|
|
83
|
+
Maintained by [Agimon](https://agimon.ai/about).
|
|
84
|
+
|
|
59
85
|
## License
|
|
60
86
|
|
|
61
87
|
MIT
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/llmsContent.cjs");let n=require("node:crypto"),r=require("node:fs");r=e.__toESM(r,1);let i=require("node:os");i=e.__toESM(i,1);let a=require("node:path");a=e.__toESM(a,1);let o=require("node:url");const s=`llms.txt`,c=`.complete`,l=`metadata.json`,u=`SKILL.md`,d=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u,f=/^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/u;function p(e){if(e.aborted)throw Error(`Help activation was cancelled.`)}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t){let n=a.default.relative(e,t);return n===``||!n.startsWith(`..${a.default.sep}`)&&n!==`..`&&!a.default.isAbsolute(n)}function g(e){let t;try{t=JSON.parse(r.default.readFileSync(e,`utf8`))}catch(t){throw Error(`Cannot read Help package manifest at ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!m(t))throw Error(`Help package manifest at ${e} must contain an object.`);return t}function _(e,t){if(!f.test(t))throw Error(`Help source '${t}' must be a valid lowercase npm package name.`);let n;try{let t=new URL(e);if(t.protocol!==`file:`)throw Error(`Help module URL must use file:, received ${t.protocol}`);n=r.default.realpathSync((0,o.fileURLToPath)(t))}catch(t){throw Error(`Invalid Help contributor module URL '${e}': ${t instanceof Error?t.message:String(t)}`)}if(!r.default.lstatSync(n).isFile())throw Error(`Help contributor module is not a regular file: ${n}`);let i=a.default.dirname(n);for(;;){let e=a.default.join(i,`package.json`);if(r.default.existsSync(e)){let a=g(e),o=a.name,s=a.version;if(o!==t)throw Error(`Help source '${t}' does not match nearest package '${String(o)}'.`);if(typeof s!=`string`||!d.test(s))throw Error(`Help package '${t}' must declare an exact semantic version.`);let c=r.default.realpathSync(i);if(!h(c,n))throw Error(`Help contributor module escapes its resolved package root.`);return{source:t,version:s,packageRoot:c,modulePath:n}}let o=a.default.dirname(i);if(o===i)break;i=o}throw Error(`Cannot find a package manifest for Help contributor ${n}.`)}function v(e=i.default.homedir()){return a.default.join(e,`.pi`,`.doom`,`llms-cache`)}function y(e){return(0,n.createHash)(`sha256`).update(e).digest(`hex`)}function b(e,t){if(m(e)&&e.schemaVersion===1&&e.source===t.source&&e.version===t.version&&e.path===s&&typeof e.integrity==`string`&&typeof e.digest==`string`&&typeof e.referenceBase==`string`)return e}function x(e){try{let t=r.default.lstatSync(e);return t.isFile()&&!t.isSymbolicLink()}catch{return!1}}var S=class{root;constructor(e=v()){this.root=e}entryDirectory(e){let t=y(`${e.source}\0${e.version}\0${s}`);return a.default.join(this.root,t)}discard(e){r.default.rmSync(this.entryDirectory(e),{recursive:!0,force:!0})}read(e){let t=this.entryDirectory(e),n=a.default.join(t,c),i=a.default.join(t,s),o=a.default.join(t,l);if(
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/llmsContent.cjs");let n=require("node:crypto"),r=require("node:fs");r=e.__toESM(r,1);let i=require("node:os");i=e.__toESM(i,1);let a=require("node:path");a=e.__toESM(a,1);let o=require("node:url");const s=`llms.txt`,c=`.complete`,l=`metadata.json`,u=`SKILL.md`,d=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u,f=/^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/u;function p(e){if(e.aborted)throw Error(`Help activation was cancelled.`)}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t){let n=a.default.relative(e,t);return n===``||!n.startsWith(`..${a.default.sep}`)&&n!==`..`&&!a.default.isAbsolute(n)}function g(e){let t;try{t=JSON.parse(r.default.readFileSync(e,`utf8`))}catch(t){throw Error(`Cannot read Help package manifest at ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!m(t))throw Error(`Help package manifest at ${e} must contain an object.`);return t}function _(e,t){if(!f.test(t))throw Error(`Help source '${t}' must be a valid lowercase npm package name.`);let n;try{let t=new URL(e);if(t.protocol!==`file:`)throw Error(`Help module URL must use file:, received ${t.protocol}`);n=r.default.realpathSync((0,o.fileURLToPath)(t))}catch(t){throw Error(`Invalid Help contributor module URL '${e}': ${t instanceof Error?t.message:String(t)}`)}if(!r.default.lstatSync(n).isFile())throw Error(`Help contributor module is not a regular file: ${n}`);let i=a.default.dirname(n);for(;;){let e=a.default.join(i,`package.json`);if(r.default.existsSync(e)){let a=g(e),o=a.name,s=a.version;if(o!==t)throw Error(`Help source '${t}' does not match nearest package '${String(o)}'.`);if(typeof s!=`string`||!d.test(s))throw Error(`Help package '${t}' must declare an exact semantic version.`);let c=r.default.realpathSync(i);if(!h(c,n))throw Error(`Help contributor module escapes its resolved package root.`);return{source:t,version:s,packageRoot:c,modulePath:n}}let o=a.default.dirname(i);if(o===i)break;i=o}throw Error(`Cannot find a package manifest for Help contributor ${n}.`)}function v(e=i.default.homedir()){return a.default.join(e,`.pi`,`.doom`,`llms-cache`)}function y(e){return(0,n.createHash)(`sha256`).update(e).digest(`hex`)}function b(e,t){if(m(e)&&e.schemaVersion===1&&e.source===t.source&&e.version===t.version&&e.path===s&&typeof e.integrity==`string`&&typeof e.digest==`string`&&typeof e.referenceBase==`string`)return e}function x(e){try{let t=r.default.lstatSync(e);return t.isFile()&&!t.isSymbolicLink()}catch{return!1}}var S=class{root;constructor(e=v()){this.root=e}entryDirectory(e){let t=y(`${e.source}\0${e.version}\0${s}`);return a.default.join(this.root,t)}discard(e){r.default.rmSync(this.entryDirectory(e),{recursive:!0,force:!0})}read(e){let t=this.entryDirectory(e),n=a.default.join(t,c),i=a.default.join(t,s),o=a.default.join(t,l);if(x(n)&&x(i)&&x(o))try{let t=b(JSON.parse(r.default.readFileSync(o,`utf8`)),e);if(!t)return;let a=r.default.readFileSync(i);return y(a)!==t.digest||r.default.readFileSync(n,`utf8`).trim()!==t.digest?void 0:{bytes:a,filePath:i,integrity:t.integrity,digest:t.digest,referenceBase:t.referenceBase}}catch{return}}publish(e,t,i,o,u){p(u);let d=this.read(e);if(d)return d;let f=this.entryDirectory(e);r.default.mkdirSync(this.root,{mode:448,recursive:!0}),r.default.existsSync(f)&&r.default.rmSync(f,{recursive:!0,force:!0});let m=`${f}.${process.pid}.${(0,n.randomUUID)()}.tmp`,h=y(t),g={schemaVersion:1,source:e.source,version:e.version,path:s,integrity:i,digest:h,referenceBase:o};try{r.default.mkdirSync(m,{mode:448}),r.default.writeFileSync(a.default.join(m,s),t,{mode:384}),r.default.writeFileSync(a.default.join(m,l),`${JSON.stringify(g,null,2)}\n`,{mode:384}),p(u),r.default.writeFileSync(a.default.join(m,c),`${h}\n`,{mode:384});try{r.default.renameSync(m,f)}catch(t){let n=this.read(e);if(n)return n;throw t}return{bytes:Uint8Array.from(t),filePath:a.default.join(f,s),integrity:i,digest:h,referenceBase:o}}finally{r.default.rmSync(m,{recursive:!0,force:!0})}}},C=class{cacheRoot;constructor(e=v()){this.cacheRoot=e}async materialize(e,i,o){let s=[];for(let c of e.skills){p(o);let l=y(`${i.identity.source}\0${i.identity.version}\0${c.name}\0${c.description}\0${i.digest}`),d=a.default.join(this.cacheRoot,`wrappers`,l),f=a.default.join(d,u),m=t.renderHelpSkillWrapper(c,i);if(!x(f)||r.default.readFileSync(f,`utf8`)!==m){r.default.mkdirSync(a.default.dirname(d),{mode:448,recursive:!0}),r.default.existsSync(d)&&r.default.rmSync(d,{recursive:!0,force:!0});let e=`${d}.${process.pid}.${(0,n.randomUUID)()}.tmp`;try{r.default.mkdirSync(e,{mode:448}),r.default.writeFileSync(a.default.join(e,u),m,{mode:384}),p(o);try{r.default.renameSync(e,d)}catch(e){if(!x(f)||r.default.readFileSync(f,`utf8`)!==m)throw e}}finally{r.default.rmSync(e,{recursive:!0,force:!0})}}s.push({source:e.source,name:c.name,description:c.description,filePath:f,baseDir:d})}return s}};exports.DefaultHelpSkillMaterializer=C,exports.HelpIndexCache=S,exports.defaultHelpCacheRoot=v,exports.resolveHelpPackageIdentity=_,exports.sha256Hex=y;
|
|
2
2
|
//# sourceMappingURL=helpStorage.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpStorage.cjs","names":["path","fs","fileURLToPath","os","createHash","randomUUID","renderHelpSkillWrapper"],"sources":["../../src/adapters/helpStorage.ts"],"sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { DoomHelpContribution, DoomHelpSkill } from '@agimon-ai/doompi-extension-contracts/help';\nimport { renderHelpSkillWrapper } from '../services/llmsContent.ts';\nimport type { HelpPackageIdentity, HelpSkillMaterializer, ResolvedHelpIndex } from '../types/help.ts';\n\nconst PACKAGE_MANIFEST = 'package.json';\nconst HELP_INDEX_PATH = 'llms.txt';\nconst CACHE_SCHEMA_VERSION = 1;\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst COMPLETION_FILE = '.complete';\nconst CACHE_METADATA_FILE = 'metadata.json';\nconst WRAPPER_DIRECTORY = 'wrappers';\nconst SKILL_FILE = 'SKILL.md';\nconst EXACT_SEMVER_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/u;\nconst NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/u;\n\ninterface CacheMetadata {\n schemaVersion: typeof CACHE_SCHEMA_VERSION;\n source: string;\n version: string;\n path: typeof HELP_INDEX_PATH;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nexport interface CachedHelpIndex {\n bytes: Uint8Array;\n filePath: string;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nfunction assertNotAborted(signal: AbortSignal): void {\n if (signal.aborted) throw new Error('Help activation was cancelled.');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isContained(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));\n}\n\nfunction readManifest(filePath: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as unknown;\n } catch (error) {\n throw new Error(\n `Cannot read Help package manifest at ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!isRecord(parsed)) throw new Error(`Help package manifest at ${filePath} must contain an object.`);\n return parsed;\n}\n\nexport function resolveHelpPackageIdentity(moduleUrl: string, expectedSource: string): HelpPackageIdentity {\n if (!NPM_PACKAGE_NAME_PATTERN.test(expectedSource)) {\n throw new Error(`Help source '${expectedSource}' must be a valid lowercase npm package name.`);\n }\n let modulePath: string;\n try {\n const url = new URL(moduleUrl);\n if (url.protocol !== 'file:') throw new Error(`Help module URL must use file:, received ${url.protocol}`);\n modulePath = fs.realpathSync(fileURLToPath(url));\n } catch (error) {\n throw new Error(\n `Invalid Help contributor module URL '${moduleUrl}': ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!fs.lstatSync(modulePath).isFile())\n throw new Error(`Help contributor module is not a regular file: ${modulePath}`);\n\n let directory = path.dirname(modulePath);\n while (true) {\n const manifestPath = path.join(directory, PACKAGE_MANIFEST);\n if (fs.existsSync(manifestPath)) {\n const manifest = readManifest(manifestPath);\n const source = manifest.name;\n const version = manifest.version;\n if (source !== expectedSource) {\n throw new Error(`Help source '${expectedSource}' does not match nearest package '${String(source)}'.`);\n }\n if (typeof version !== 'string' || !EXACT_SEMVER_PATTERN.test(version)) {\n throw new Error(`Help package '${expectedSource}' must declare an exact semantic version.`);\n }\n const packageRoot = fs.realpathSync(directory);\n if (!isContained(packageRoot, modulePath))\n throw new Error('Help contributor module escapes its resolved package root.');\n return { source: expectedSource, version, packageRoot, modulePath };\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Cannot find a package manifest for Help contributor ${modulePath}.`);\n}\n\nexport function defaultHelpCacheRoot(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, '.pi', '.doom', 'llms-cache');\n}\n\nexport function sha256Hex(bytes: Uint8Array | string): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction parseCacheMetadata(value: unknown, identity: HelpPackageIdentity): CacheMetadata | undefined {\n if (!isRecord(value)) return undefined;\n if (\n value.schemaVersion !== CACHE_SCHEMA_VERSION ||\n value.source !== identity.source ||\n value.version !== identity.version ||\n value.path !== HELP_INDEX_PATH ||\n typeof value.integrity !== 'string' ||\n typeof value.digest !== 'string' ||\n typeof value.referenceBase !== 'string'\n ) {\n return undefined;\n }\n return value as unknown as CacheMetadata;\n}\n\nfunction regularFile(filePath: string): boolean {\n try {\n const metadata = fs.lstatSync(filePath);\n return metadata.isFile() && !metadata.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport class HelpIndexCache {\n readonly root: string;\n\n constructor(root = defaultHelpCacheRoot()) {\n this.root = root;\n }\n\n entryDirectory(identity: HelpPackageIdentity): string {\n const key = sha256Hex(`${identity.source}\\0${identity.version}\\0${HELP_INDEX_PATH}`);\n return path.join(this.root, key);\n }\n\n discard(identity: HelpPackageIdentity): void {\n fs.rmSync(this.entryDirectory(identity), { recursive: true, force: true });\n }\n\n read(identity: HelpPackageIdentity): CachedHelpIndex | undefined {\n const directory = this.entryDirectory(identity);\n const completionPath = path.join(directory, COMPLETION_FILE);\n const indexPath = path.join(directory, HELP_INDEX_PATH);\n const metadataPath = path.join(directory, CACHE_METADATA_FILE);\n if (!regularFile(completionPath) || !regularFile(indexPath) || !regularFile(metadataPath)) return undefined;\n try {\n const metadata = parseCacheMetadata(JSON.parse(fs.readFileSync(metadataPath, 'utf8')) as unknown, identity);\n if (!metadata) return undefined;\n const bytes = fs.readFileSync(indexPath);\n if (sha256Hex(bytes) !== metadata.digest) return undefined;\n if (fs.readFileSync(completionPath, 'utf8').trim() !== metadata.digest) return undefined;\n return {\n bytes,\n filePath: indexPath,\n integrity: metadata.integrity,\n digest: metadata.digest,\n referenceBase: metadata.referenceBase,\n };\n } catch {\n return undefined;\n }\n }\n\n publish(\n identity: HelpPackageIdentity,\n bytes: Uint8Array,\n integrity: string,\n referenceBase: string,\n signal: AbortSignal,\n ): CachedHelpIndex {\n assertNotAborted(signal);\n const existing = this.read(identity);\n if (existing) return existing;\n const directory = this.entryDirectory(identity);\n fs.mkdirSync(this.root, { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n const digest = sha256Hex(bytes);\n const metadata: CacheMetadata = {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source: identity.source,\n version: identity.version,\n path: HELP_INDEX_PATH,\n integrity,\n digest,\n referenceBase,\n };\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, HELP_INDEX_PATH), bytes, { mode: PRIVATE_FILE_MODE });\n fs.writeFileSync(path.join(temporary, CACHE_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, {\n mode: PRIVATE_FILE_MODE,\n });\n assertNotAborted(signal);\n fs.writeFileSync(path.join(temporary, COMPLETION_FILE), `${digest}\\n`, { mode: PRIVATE_FILE_MODE });\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n const winner = this.read(identity);\n if (winner) return winner;\n throw error;\n }\n return {\n bytes: Uint8Array.from(bytes),\n filePath: path.join(directory, HELP_INDEX_PATH),\n integrity,\n digest,\n referenceBase,\n };\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n}\n\nexport class DefaultHelpSkillMaterializer implements HelpSkillMaterializer {\n constructor(private readonly cacheRoot = defaultHelpCacheRoot()) {}\n\n async materialize(\n contribution: DoomHelpContribution,\n index: ResolvedHelpIndex,\n signal: AbortSignal,\n ): Promise<readonly DoomHelpSkill[]> {\n const skills: DoomHelpSkill[] = [];\n for (const descriptor of contribution.skills) {\n assertNotAborted(signal);\n const key = sha256Hex(\n `${index.identity.source}\\0${index.identity.version}\\0${descriptor.name}\\0${descriptor.description}\\0${index.digest}`,\n );\n const directory = path.join(this.cacheRoot, WRAPPER_DIRECTORY, key);\n const filePath = path.join(directory, SKILL_FILE);\n const content = renderHelpSkillWrapper(descriptor, index);\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) {\n fs.mkdirSync(path.dirname(directory), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, SKILL_FILE), content, { mode: PRIVATE_FILE_MODE });\n assertNotAborted(signal);\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) throw error;\n }\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n skills.push({\n source: contribution.source,\n name: descriptor.name,\n description: descriptor.description,\n filePath,\n baseDir: directory,\n });\n }\n return skills;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpStorage.cjs","names":["path","fs","fileURLToPath","os","createHash","randomUUID","renderHelpSkillWrapper"],"sources":["../../src/adapters/helpStorage.ts"],"sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { DoomHelpContribution, DoomHelpSkill } from '@agimon-ai/doompi-extension-contracts/help';\nimport { renderHelpSkillWrapper } from '../services/llmsContent.ts';\nimport type { HelpPackageIdentity, HelpSkillMaterializer, ResolvedHelpIndex } from '../types/help.ts';\n\nconst PACKAGE_MANIFEST = 'package.json';\nconst HELP_INDEX_PATH = 'llms.txt';\nconst CACHE_SCHEMA_VERSION = 1;\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst COMPLETION_FILE = '.complete';\nconst CACHE_METADATA_FILE = 'metadata.json';\nconst WRAPPER_DIRECTORY = 'wrappers';\nconst SKILL_FILE = 'SKILL.md';\nconst EXACT_SEMVER_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/u;\nconst NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/u;\n\ninterface CacheMetadata {\n schemaVersion: typeof CACHE_SCHEMA_VERSION;\n source: string;\n version: string;\n path: typeof HELP_INDEX_PATH;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nexport interface CachedHelpIndex {\n bytes: Uint8Array;\n filePath: string;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nfunction assertNotAborted(signal: AbortSignal): void {\n if (signal.aborted) throw new Error('Help activation was cancelled.');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isContained(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));\n}\n\nfunction readManifest(filePath: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as unknown;\n } catch (error) {\n throw new Error(\n `Cannot read Help package manifest at ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!isRecord(parsed)) throw new Error(`Help package manifest at ${filePath} must contain an object.`);\n return parsed;\n}\n\nexport function resolveHelpPackageIdentity(moduleUrl: string, expectedSource: string): HelpPackageIdentity {\n if (!NPM_PACKAGE_NAME_PATTERN.test(expectedSource)) {\n throw new Error(`Help source '${expectedSource}' must be a valid lowercase npm package name.`);\n }\n let modulePath: string;\n try {\n const url = new URL(moduleUrl);\n if (url.protocol !== 'file:') throw new Error(`Help module URL must use file:, received ${url.protocol}`);\n modulePath = fs.realpathSync(fileURLToPath(url));\n } catch (error) {\n throw new Error(\n `Invalid Help contributor module URL '${moduleUrl}': ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!fs.lstatSync(modulePath).isFile())\n throw new Error(`Help contributor module is not a regular file: ${modulePath}`);\n\n let directory = path.dirname(modulePath);\n while (true) {\n const manifestPath = path.join(directory, PACKAGE_MANIFEST);\n if (fs.existsSync(manifestPath)) {\n const manifest = readManifest(manifestPath);\n const source = manifest.name;\n const version = manifest.version;\n if (source !== expectedSource) {\n throw new Error(`Help source '${expectedSource}' does not match nearest package '${String(source)}'.`);\n }\n if (typeof version !== 'string' || !EXACT_SEMVER_PATTERN.test(version)) {\n throw new Error(`Help package '${expectedSource}' must declare an exact semantic version.`);\n }\n const packageRoot = fs.realpathSync(directory);\n if (!isContained(packageRoot, modulePath))\n throw new Error('Help contributor module escapes its resolved package root.');\n return { source: expectedSource, version, packageRoot, modulePath };\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Cannot find a package manifest for Help contributor ${modulePath}.`);\n}\n\nexport function defaultHelpCacheRoot(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, '.pi', '.doom', 'llms-cache');\n}\n\nexport function sha256Hex(bytes: Uint8Array | string): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction parseCacheMetadata(value: unknown, identity: HelpPackageIdentity): CacheMetadata | undefined {\n if (!isRecord(value)) return undefined;\n if (\n value.schemaVersion !== CACHE_SCHEMA_VERSION ||\n value.source !== identity.source ||\n value.version !== identity.version ||\n value.path !== HELP_INDEX_PATH ||\n typeof value.integrity !== 'string' ||\n typeof value.digest !== 'string' ||\n typeof value.referenceBase !== 'string'\n ) {\n return undefined;\n }\n return value as unknown as CacheMetadata;\n}\n\nfunction regularFile(filePath: string): boolean {\n try {\n const metadata = fs.lstatSync(filePath);\n return metadata.isFile() && !metadata.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport class HelpIndexCache {\n readonly root: string;\n\n constructor(root = defaultHelpCacheRoot()) {\n this.root = root;\n }\n\n entryDirectory(identity: HelpPackageIdentity): string {\n const key = sha256Hex(`${identity.source}\\0${identity.version}\\0${HELP_INDEX_PATH}`);\n return path.join(this.root, key);\n }\n\n discard(identity: HelpPackageIdentity): void {\n fs.rmSync(this.entryDirectory(identity), { recursive: true, force: true });\n }\n\n read(identity: HelpPackageIdentity): CachedHelpIndex | undefined {\n const directory = this.entryDirectory(identity);\n const completionPath = path.join(directory, COMPLETION_FILE);\n const indexPath = path.join(directory, HELP_INDEX_PATH);\n const metadataPath = path.join(directory, CACHE_METADATA_FILE);\n if (!regularFile(completionPath) || !regularFile(indexPath) || !regularFile(metadataPath)) return undefined;\n try {\n const metadata = parseCacheMetadata(JSON.parse(fs.readFileSync(metadataPath, 'utf8')) as unknown, identity);\n if (!metadata) return undefined;\n const bytes = fs.readFileSync(indexPath);\n if (sha256Hex(bytes) !== metadata.digest) return undefined;\n if (fs.readFileSync(completionPath, 'utf8').trim() !== metadata.digest) return undefined;\n return {\n bytes,\n filePath: indexPath,\n integrity: metadata.integrity,\n digest: metadata.digest,\n referenceBase: metadata.referenceBase,\n };\n } catch {\n return undefined;\n }\n }\n\n publish(\n identity: HelpPackageIdentity,\n bytes: Uint8Array,\n integrity: string,\n referenceBase: string,\n signal: AbortSignal,\n ): CachedHelpIndex {\n assertNotAborted(signal);\n const existing = this.read(identity);\n if (existing) return existing;\n const directory = this.entryDirectory(identity);\n fs.mkdirSync(this.root, { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n const digest = sha256Hex(bytes);\n const metadata: CacheMetadata = {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source: identity.source,\n version: identity.version,\n path: HELP_INDEX_PATH,\n integrity,\n digest,\n referenceBase,\n };\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, HELP_INDEX_PATH), bytes, { mode: PRIVATE_FILE_MODE });\n fs.writeFileSync(path.join(temporary, CACHE_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, {\n mode: PRIVATE_FILE_MODE,\n });\n assertNotAborted(signal);\n fs.writeFileSync(path.join(temporary, COMPLETION_FILE), `${digest}\\n`, { mode: PRIVATE_FILE_MODE });\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n const winner = this.read(identity);\n if (winner) return winner;\n throw error;\n }\n return {\n bytes: Uint8Array.from(bytes),\n filePath: path.join(directory, HELP_INDEX_PATH),\n integrity,\n digest,\n referenceBase,\n };\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n}\n\nexport class DefaultHelpSkillMaterializer implements HelpSkillMaterializer {\n constructor(private readonly cacheRoot = defaultHelpCacheRoot()) {}\n\n async materialize(\n contribution: DoomHelpContribution,\n index: ResolvedHelpIndex,\n signal: AbortSignal,\n ): Promise<readonly DoomHelpSkill[]> {\n const skills: DoomHelpSkill[] = [];\n for (const descriptor of contribution.skills) {\n assertNotAborted(signal);\n const key = sha256Hex(\n `${index.identity.source}\\0${index.identity.version}\\0${descriptor.name}\\0${descriptor.description}\\0${index.digest}`,\n );\n const directory = path.join(this.cacheRoot, WRAPPER_DIRECTORY, key);\n const filePath = path.join(directory, SKILL_FILE);\n const content = renderHelpSkillWrapper(descriptor, index);\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) {\n fs.mkdirSync(path.dirname(directory), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, SKILL_FILE), content, { mode: PRIVATE_FILE_MODE });\n assertNotAborted(signal);\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) throw error;\n }\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n skills.push({\n source: contribution.source,\n name: descriptor.name,\n description: descriptor.description,\n filePath,\n baseDir: directory,\n });\n }\n return skills;\n }\n}\n"],"mappings":"iRASA,MACM,EAAkB,WAIlB,EAAkB,YAClB,EAAsB,gBAEtB,EAAa,WACb,EACJ,mIACI,EAA2B,wDAoBjC,SAAS,EAAiB,EAA2B,CACnD,GAAI,EAAO,QAAS,MAAU,MAAM,gCAAgC,CACtE,CAEA,SAAS,EAAS,EAAkD,CAClE,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EAAY,EAAc,EAA4B,CAC7D,IAAM,EAAWA,EAAAA,QAAK,SAAS,EAAM,CAAS,EAC9C,OAAO,IAAa,IAAO,CAAC,EAAS,WAAW,KAAKA,EAAAA,QAAK,KAAK,GAAK,IAAa,MAAQ,CAACA,EAAAA,QAAK,WAAW,CAAQ,CACpH,CAEA,SAAS,EAAa,EAA2C,CAC/D,IAAI,EACJ,GAAI,CACF,EAAS,KAAK,MAAMC,EAAAA,QAAG,aAAa,EAAU,MAAM,CAAC,CACvD,OAAS,EAAO,CACd,MAAU,MACR,wCAAwC,EAAS,IAAI,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GAC5G,CACF,CACA,GAAI,CAAC,EAAS,CAAM,EAAG,MAAU,MAAM,4BAA4B,EAAS,yBAAyB,EACrG,OAAO,CACT,CAEA,SAAgB,EAA2B,EAAmB,EAA6C,CACzG,GAAI,CAAC,EAAyB,KAAK,CAAc,EAC/C,MAAU,MAAM,gBAAgB,EAAe,8CAA8C,EAE/F,IAAI,EACJ,GAAI,CACF,IAAM,EAAM,IAAI,IAAI,CAAS,EAC7B,GAAI,EAAI,WAAa,QAAS,MAAU,MAAM,4CAA4C,EAAI,UAAU,EACxG,EAAaA,EAAAA,QAAG,cAAA,EAAaC,EAAAA,cAAAA,CAAc,CAAG,CAAC,CACjD,OAAS,EAAO,CACd,MAAU,MACR,wCAAwC,EAAU,KAAK,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GAC9G,CACF,CACA,GAAI,CAACD,EAAAA,QAAG,UAAU,CAAU,CAAC,CAAC,OAAO,EACnC,MAAU,MAAM,kDAAkD,GAAY,EAEhF,IAAI,EAAYD,EAAAA,QAAK,QAAQ,CAAU,EACvC,OAAa,CACX,IAAM,EAAeA,EAAAA,QAAK,KAAK,EAAW,cAAgB,EAC1D,GAAIC,EAAAA,QAAG,WAAW,CAAY,EAAG,CAC/B,IAAM,EAAW,EAAa,CAAY,EACpC,EAAS,EAAS,KAClB,EAAU,EAAS,QACzB,GAAI,IAAW,EACb,MAAU,MAAM,gBAAgB,EAAe,oCAAoC,OAAO,CAAM,EAAE,GAAG,EAEvG,GAAI,OAAO,GAAY,UAAY,CAAC,EAAqB,KAAK,CAAO,EACnE,MAAU,MAAM,iBAAiB,EAAe,0CAA0C,EAE5F,IAAM,EAAcA,EAAAA,QAAG,aAAa,CAAS,EAC7C,GAAI,CAAC,EAAY,EAAa,CAAU,EACtC,MAAU,MAAM,4DAA4D,EAC9E,MAAO,CAAE,OAAQ,EAAgB,UAAS,cAAa,YAAW,CACpE,CACA,IAAM,EAASD,EAAAA,QAAK,QAAQ,CAAS,EACrC,GAAI,IAAW,EAAW,MAC1B,EAAY,CACd,CACA,MAAU,MAAM,uDAAuD,EAAW,EAAE,CACtF,CAEA,SAAgB,EAAqB,EAAgBG,EAAAA,QAAG,QAAQ,EAAW,CACzE,OAAOH,EAAAA,QAAK,KAAK,EAAe,MAAO,QAAS,YAAY,CAC9D,CAEA,SAAgB,EAAU,EAAoC,CAC5D,OAAA,EAAOI,EAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,CAAK,CAAC,CAAC,OAAO,KAAK,CACxD,CAEA,SAAS,EAAmB,EAAgB,EAA0D,CAC/F,KAAS,CAAK,GAEjB,EAAM,gBAAkB,GACxB,EAAM,SAAW,EAAS,QAC1B,EAAM,UAAY,EAAS,SAC3B,EAAM,OAAS,GACf,OAAO,EAAM,WAAc,UAC3B,OAAO,EAAM,QAAW,UACxB,OAAO,EAAM,eAAkB,SAIjC,OAAO,CACT,CAEA,SAAS,EAAY,EAA2B,CAC9C,GAAI,CACF,IAAM,EAAWH,EAAAA,QAAG,UAAU,CAAQ,EACtC,OAAO,EAAS,OAAO,GAAK,CAAC,EAAS,eAAe,CACvD,MAAQ,CACN,MAAO,EACT,CACF,CAEA,IAAa,EAAb,KAA4B,CAC1B,KAEA,YAAY,EAAO,EAAqB,EAAG,CACzC,KAAK,KAAO,CACd,CAEA,eAAe,EAAuC,CACpD,IAAM,EAAM,EAAU,GAAG,EAAS,OAAO,IAAI,EAAS,QAAQ,IAAI,GAAiB,EACnF,OAAOD,EAAAA,QAAK,KAAK,KAAK,KAAM,CAAG,CACjC,CAEA,QAAQ,EAAqC,CAC3C,EAAA,QAAG,OAAO,KAAK,eAAe,CAAQ,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,CAC3E,CAEA,KAAK,EAA4D,CAC/D,IAAM,EAAY,KAAK,eAAe,CAAQ,EACxC,EAAiBA,EAAAA,QAAK,KAAK,EAAW,CAAe,EACrD,EAAYA,EAAAA,QAAK,KAAK,EAAW,CAAe,EAChD,EAAeA,EAAAA,QAAK,KAAK,EAAW,CAAmB,EACzD,GAAC,EAAY,CAAc,GAAM,EAAY,CAAS,GAAM,EAAY,CAAY,EACxF,GAAI,CACF,IAAM,EAAW,EAAmB,KAAK,MAAMC,EAAAA,QAAG,aAAa,EAAc,MAAM,CAAC,EAAc,CAAQ,EAC1G,GAAI,CAAC,EAAU,OACf,IAAM,EAAQA,EAAAA,QAAG,aAAa,CAAS,EAGvC,OAFI,EAAU,CAAK,IAAM,EAAS,QAC9BA,EAAAA,QAAG,aAAa,EAAgB,MAAM,CAAC,CAAC,KAAK,IAAM,EAAS,OAAQ,OACjE,CACL,QACA,SAAU,EACV,UAAW,EAAS,UACpB,OAAQ,EAAS,OACjB,cAAe,EAAS,aAC1B,CACF,MAAQ,CACN,MACF,CACF,CAEA,QACE,EACA,EACA,EACA,EACA,EACiB,CACjB,EAAiB,CAAM,EACvB,IAAM,EAAW,KAAK,KAAK,CAAQ,EACnC,GAAI,EAAU,OAAO,EACrB,IAAM,EAAY,KAAK,eAAe,CAAQ,EAC9C,EAAA,QAAG,UAAU,KAAK,KAAM,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACrEA,EAAAA,QAAG,WAAW,CAAS,GAAG,EAAA,QAAG,OAAO,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EACnF,IAAM,EAAY,GAAG,EAAU,GAAG,QAAQ,IAAI,IAAA,EAAGI,EAAAA,WAAAA,CAAW,EAAE,MACxD,EAAS,EAAU,CAAK,EACxB,EAA0B,CAC9B,cAAe,EACf,OAAQ,EAAS,OACjB,QAAS,EAAS,QAClB,KAAM,EACN,YACA,SACA,eACF,EACA,GAAI,CACF,EAAA,QAAG,UAAU,EAAW,CAAE,KAAM,GAAuB,CAAC,EACxD,EAAA,QAAG,cAAcL,EAAAA,QAAK,KAAK,EAAW,CAAe,EAAG,EAAO,CAAE,KAAM,GAAkB,CAAC,EAC1F,EAAA,QAAG,cAAcA,EAAAA,QAAK,KAAK,EAAW,CAAmB,EAAG,GAAG,KAAK,UAAU,EAAU,KAAM,CAAC,EAAE,IAAK,CACpG,KAAM,GACR,CAAC,EACD,EAAiB,CAAM,EACvB,EAAA,QAAG,cAAcA,EAAAA,QAAK,KAAK,EAAW,CAAe,EAAG,GAAG,EAAO,IAAK,CAAE,KAAM,GAAkB,CAAC,EAClG,GAAI,CACF,EAAA,QAAG,WAAW,EAAW,CAAS,CACpC,OAAS,EAAO,CACd,IAAM,EAAS,KAAK,KAAK,CAAQ,EACjC,GAAI,EAAQ,OAAO,EACnB,MAAM,CACR,CACA,MAAO,CACL,MAAO,WAAW,KAAK,CAAK,EAC5B,SAAUA,EAAAA,QAAK,KAAK,EAAW,CAAe,EAC9C,YACA,SACA,eACF,CACF,QAAU,CACR,EAAA,QAAG,OAAO,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,CACvD,CACF,CACF,EAEa,EAAb,KAA2E,CAC5C,UAA7B,YAAY,EAA6B,EAAqB,EAAG,CAApC,KAAA,UAAA,CAAqC,CAElE,MAAM,YACJ,EACA,EACA,EACmC,CACnC,IAAM,EAA0B,CAAC,EACjC,IAAK,IAAM,KAAc,EAAa,OAAQ,CAC5C,EAAiB,CAAM,EACvB,IAAM,EAAM,EACV,GAAG,EAAM,SAAS,OAAO,IAAI,EAAM,SAAS,QAAQ,IAAI,EAAW,KAAK,IAAI,EAAW,YAAY,IAAI,EAAM,QAC/G,EACM,EAAYA,EAAAA,QAAK,KAAK,KAAK,UAAW,WAAmB,CAAG,EAC5D,EAAWA,EAAAA,QAAK,KAAK,EAAW,CAAU,EAC1C,EAAUM,EAAAA,uBAAuB,EAAY,CAAK,EACxD,GAAI,CAAC,EAAY,CAAQ,GAAKL,EAAAA,QAAG,aAAa,EAAU,MAAM,IAAM,EAAS,CAC3E,EAAA,QAAG,UAAUD,EAAAA,QAAK,QAAQ,CAAS,EAAG,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACnFC,EAAAA,QAAG,WAAW,CAAS,GAAG,EAAA,QAAG,OAAO,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EACnF,IAAM,EAAY,GAAG,EAAU,GAAG,QAAQ,IAAI,IAAA,EAAGI,EAAAA,WAAAA,CAAW,EAAE,MAC9D,GAAI,CACF,EAAA,QAAG,UAAU,EAAW,CAAE,KAAM,GAAuB,CAAC,EACxD,EAAA,QAAG,cAAcL,EAAAA,QAAK,KAAK,EAAW,CAAU,EAAG,EAAS,CAAE,KAAM,GAAkB,CAAC,EACvF,EAAiB,CAAM,EACvB,GAAI,CACF,EAAA,QAAG,WAAW,EAAW,CAAS,CACpC,OAAS,EAAO,CACd,GAAI,CAAC,EAAY,CAAQ,GAAKC,EAAAA,QAAG,aAAa,EAAU,MAAM,IAAM,EAAS,MAAM,CACrF,CACF,QAAU,CACR,EAAA,QAAG,OAAO,EAAW,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,CACvD,CACF,CACA,EAAO,KAAK,CACV,OAAQ,EAAa,OACrB,KAAM,EAAW,KACjB,YAAa,EAAW,YACxB,WACA,QAAS,CACX,CAAC,CACH,CACA,OAAO,CACT,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{renderHelpSkillWrapper as e}from"../services/llmsContent.mjs";import{createHash as t,randomUUID as n}from"node:crypto";import r from"node:fs";import i from"node:os";import a from"node:path";import{fileURLToPath as o}from"node:url";const s=`llms.txt`,c=`.complete`,l=`metadata.json`,u=`SKILL.md`,d=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u,f=/^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/u;function p(e){if(e.aborted)throw Error(`Help activation was cancelled.`)}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t){let n=a.relative(e,t);return n===``||!n.startsWith(`..${a.sep}`)&&n!==`..`&&!a.isAbsolute(n)}function g(e){let t;try{t=JSON.parse(r.readFileSync(e,`utf8`))}catch(t){throw Error(`Cannot read Help package manifest at ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!m(t))throw Error(`Help package manifest at ${e} must contain an object.`);return t}function _(e,t){if(!f.test(t))throw Error(`Help source '${t}' must be a valid lowercase npm package name.`);let n;try{let t=new URL(e);if(t.protocol!==`file:`)throw Error(`Help module URL must use file:, received ${t.protocol}`);n=r.realpathSync(o(t))}catch(t){throw Error(`Invalid Help contributor module URL '${e}': ${t instanceof Error?t.message:String(t)}`)}if(!r.lstatSync(n).isFile())throw Error(`Help contributor module is not a regular file: ${n}`);let i=a.dirname(n);for(;;){let e=a.join(i,`package.json`);if(r.existsSync(e)){let a=g(e),o=a.name,s=a.version;if(o!==t)throw Error(`Help source '${t}' does not match nearest package '${String(o)}'.`);if(typeof s!=`string`||!d.test(s))throw Error(`Help package '${t}' must declare an exact semantic version.`);let c=r.realpathSync(i);if(!h(c,n))throw Error(`Help contributor module escapes its resolved package root.`);return{source:t,version:s,packageRoot:c,modulePath:n}}let o=a.dirname(i);if(o===i)break;i=o}throw Error(`Cannot find a package manifest for Help contributor ${n}.`)}function v(e=i.homedir()){return a.join(e,`.pi`,`.doom`,`llms-cache`)}function y(e){return t(`sha256`).update(e).digest(`hex`)}function b(e,t){if(m(e)&&e.schemaVersion===1&&e.source===t.source&&e.version===t.version&&e.path===s&&typeof e.integrity==`string`&&typeof e.digest==`string`&&typeof e.referenceBase==`string`)return e}function x(e){try{let t=r.lstatSync(e);return t.isFile()&&!t.isSymbolicLink()}catch{return!1}}var S=class{root;constructor(e=v()){this.root=e}entryDirectory(e){let t=y(`${e.source}\0${e.version}\0${s}`);return a.join(this.root,t)}discard(e){r.rmSync(this.entryDirectory(e),{recursive:!0,force:!0})}read(e){let t=this.entryDirectory(e),n=a.join(t,c),i=a.join(t,s),o=a.join(t,l);if(
|
|
1
|
+
import{renderHelpSkillWrapper as e}from"../services/llmsContent.mjs";import{createHash as t,randomUUID as n}from"node:crypto";import r from"node:fs";import i from"node:os";import a from"node:path";import{fileURLToPath as o}from"node:url";const s=`llms.txt`,c=`.complete`,l=`metadata.json`,u=`SKILL.md`,d=/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u,f=/^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/u;function p(e){if(e.aborted)throw Error(`Help activation was cancelled.`)}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t){let n=a.relative(e,t);return n===``||!n.startsWith(`..${a.sep}`)&&n!==`..`&&!a.isAbsolute(n)}function g(e){let t;try{t=JSON.parse(r.readFileSync(e,`utf8`))}catch(t){throw Error(`Cannot read Help package manifest at ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!m(t))throw Error(`Help package manifest at ${e} must contain an object.`);return t}function _(e,t){if(!f.test(t))throw Error(`Help source '${t}' must be a valid lowercase npm package name.`);let n;try{let t=new URL(e);if(t.protocol!==`file:`)throw Error(`Help module URL must use file:, received ${t.protocol}`);n=r.realpathSync(o(t))}catch(t){throw Error(`Invalid Help contributor module URL '${e}': ${t instanceof Error?t.message:String(t)}`)}if(!r.lstatSync(n).isFile())throw Error(`Help contributor module is not a regular file: ${n}`);let i=a.dirname(n);for(;;){let e=a.join(i,`package.json`);if(r.existsSync(e)){let a=g(e),o=a.name,s=a.version;if(o!==t)throw Error(`Help source '${t}' does not match nearest package '${String(o)}'.`);if(typeof s!=`string`||!d.test(s))throw Error(`Help package '${t}' must declare an exact semantic version.`);let c=r.realpathSync(i);if(!h(c,n))throw Error(`Help contributor module escapes its resolved package root.`);return{source:t,version:s,packageRoot:c,modulePath:n}}let o=a.dirname(i);if(o===i)break;i=o}throw Error(`Cannot find a package manifest for Help contributor ${n}.`)}function v(e=i.homedir()){return a.join(e,`.pi`,`.doom`,`llms-cache`)}function y(e){return t(`sha256`).update(e).digest(`hex`)}function b(e,t){if(m(e)&&e.schemaVersion===1&&e.source===t.source&&e.version===t.version&&e.path===s&&typeof e.integrity==`string`&&typeof e.digest==`string`&&typeof e.referenceBase==`string`)return e}function x(e){try{let t=r.lstatSync(e);return t.isFile()&&!t.isSymbolicLink()}catch{return!1}}var S=class{root;constructor(e=v()){this.root=e}entryDirectory(e){let t=y(`${e.source}\0${e.version}\0${s}`);return a.join(this.root,t)}discard(e){r.rmSync(this.entryDirectory(e),{recursive:!0,force:!0})}read(e){let t=this.entryDirectory(e),n=a.join(t,c),i=a.join(t,s),o=a.join(t,l);if(x(n)&&x(i)&&x(o))try{let t=b(JSON.parse(r.readFileSync(o,`utf8`)),e);if(!t)return;let a=r.readFileSync(i);return y(a)!==t.digest||r.readFileSync(n,`utf8`).trim()!==t.digest?void 0:{bytes:a,filePath:i,integrity:t.integrity,digest:t.digest,referenceBase:t.referenceBase}}catch{return}}publish(e,t,i,o,u){p(u);let d=this.read(e);if(d)return d;let f=this.entryDirectory(e);r.mkdirSync(this.root,{mode:448,recursive:!0}),r.existsSync(f)&&r.rmSync(f,{recursive:!0,force:!0});let m=`${f}.${process.pid}.${n()}.tmp`,h=y(t),g={schemaVersion:1,source:e.source,version:e.version,path:s,integrity:i,digest:h,referenceBase:o};try{r.mkdirSync(m,{mode:448}),r.writeFileSync(a.join(m,s),t,{mode:384}),r.writeFileSync(a.join(m,l),`${JSON.stringify(g,null,2)}\n`,{mode:384}),p(u),r.writeFileSync(a.join(m,c),`${h}\n`,{mode:384});try{r.renameSync(m,f)}catch(t){let n=this.read(e);if(n)return n;throw t}return{bytes:Uint8Array.from(t),filePath:a.join(f,s),integrity:i,digest:h,referenceBase:o}}finally{r.rmSync(m,{recursive:!0,force:!0})}}},C=class{cacheRoot;constructor(e=v()){this.cacheRoot=e}async materialize(t,i,o){let s=[];for(let c of t.skills){p(o);let l=y(`${i.identity.source}\0${i.identity.version}\0${c.name}\0${c.description}\0${i.digest}`),d=a.join(this.cacheRoot,`wrappers`,l),f=a.join(d,u),m=e(c,i);if(!x(f)||r.readFileSync(f,`utf8`)!==m){r.mkdirSync(a.dirname(d),{mode:448,recursive:!0}),r.existsSync(d)&&r.rmSync(d,{recursive:!0,force:!0});let e=`${d}.${process.pid}.${n()}.tmp`;try{r.mkdirSync(e,{mode:448}),r.writeFileSync(a.join(e,u),m,{mode:384}),p(o);try{r.renameSync(e,d)}catch(e){if(!x(f)||r.readFileSync(f,`utf8`)!==m)throw e}}finally{r.rmSync(e,{recursive:!0,force:!0})}}s.push({source:t.source,name:c.name,description:c.description,filePath:f,baseDir:d})}return s}};export{C as DefaultHelpSkillMaterializer,S as HelpIndexCache,v as defaultHelpCacheRoot,_ as resolveHelpPackageIdentity,y as sha256Hex};
|
|
2
2
|
//# sourceMappingURL=helpStorage.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpStorage.mjs","names":[],"sources":["../../src/adapters/helpStorage.ts"],"sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { DoomHelpContribution, DoomHelpSkill } from '@agimon-ai/doompi-extension-contracts/help';\nimport { renderHelpSkillWrapper } from '../services/llmsContent.ts';\nimport type { HelpPackageIdentity, HelpSkillMaterializer, ResolvedHelpIndex } from '../types/help.ts';\n\nconst PACKAGE_MANIFEST = 'package.json';\nconst HELP_INDEX_PATH = 'llms.txt';\nconst CACHE_SCHEMA_VERSION = 1;\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst COMPLETION_FILE = '.complete';\nconst CACHE_METADATA_FILE = 'metadata.json';\nconst WRAPPER_DIRECTORY = 'wrappers';\nconst SKILL_FILE = 'SKILL.md';\nconst EXACT_SEMVER_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/u;\nconst NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/u;\n\ninterface CacheMetadata {\n schemaVersion: typeof CACHE_SCHEMA_VERSION;\n source: string;\n version: string;\n path: typeof HELP_INDEX_PATH;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nexport interface CachedHelpIndex {\n bytes: Uint8Array;\n filePath: string;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nfunction assertNotAborted(signal: AbortSignal): void {\n if (signal.aborted) throw new Error('Help activation was cancelled.');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isContained(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));\n}\n\nfunction readManifest(filePath: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as unknown;\n } catch (error) {\n throw new Error(\n `Cannot read Help package manifest at ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!isRecord(parsed)) throw new Error(`Help package manifest at ${filePath} must contain an object.`);\n return parsed;\n}\n\nexport function resolveHelpPackageIdentity(moduleUrl: string, expectedSource: string): HelpPackageIdentity {\n if (!NPM_PACKAGE_NAME_PATTERN.test(expectedSource)) {\n throw new Error(`Help source '${expectedSource}' must be a valid lowercase npm package name.`);\n }\n let modulePath: string;\n try {\n const url = new URL(moduleUrl);\n if (url.protocol !== 'file:') throw new Error(`Help module URL must use file:, received ${url.protocol}`);\n modulePath = fs.realpathSync(fileURLToPath(url));\n } catch (error) {\n throw new Error(\n `Invalid Help contributor module URL '${moduleUrl}': ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!fs.lstatSync(modulePath).isFile())\n throw new Error(`Help contributor module is not a regular file: ${modulePath}`);\n\n let directory = path.dirname(modulePath);\n while (true) {\n const manifestPath = path.join(directory, PACKAGE_MANIFEST);\n if (fs.existsSync(manifestPath)) {\n const manifest = readManifest(manifestPath);\n const source = manifest.name;\n const version = manifest.version;\n if (source !== expectedSource) {\n throw new Error(`Help source '${expectedSource}' does not match nearest package '${String(source)}'.`);\n }\n if (typeof version !== 'string' || !EXACT_SEMVER_PATTERN.test(version)) {\n throw new Error(`Help package '${expectedSource}' must declare an exact semantic version.`);\n }\n const packageRoot = fs.realpathSync(directory);\n if (!isContained(packageRoot, modulePath))\n throw new Error('Help contributor module escapes its resolved package root.');\n return { source: expectedSource, version, packageRoot, modulePath };\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Cannot find a package manifest for Help contributor ${modulePath}.`);\n}\n\nexport function defaultHelpCacheRoot(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, '.pi', '.doom', 'llms-cache');\n}\n\nexport function sha256Hex(bytes: Uint8Array | string): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction parseCacheMetadata(value: unknown, identity: HelpPackageIdentity): CacheMetadata | undefined {\n if (!isRecord(value)) return undefined;\n if (\n value.schemaVersion !== CACHE_SCHEMA_VERSION ||\n value.source !== identity.source ||\n value.version !== identity.version ||\n value.path !== HELP_INDEX_PATH ||\n typeof value.integrity !== 'string' ||\n typeof value.digest !== 'string' ||\n typeof value.referenceBase !== 'string'\n ) {\n return undefined;\n }\n return value as unknown as CacheMetadata;\n}\n\nfunction regularFile(filePath: string): boolean {\n try {\n const metadata = fs.lstatSync(filePath);\n return metadata.isFile() && !metadata.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport class HelpIndexCache {\n readonly root: string;\n\n constructor(root = defaultHelpCacheRoot()) {\n this.root = root;\n }\n\n entryDirectory(identity: HelpPackageIdentity): string {\n const key = sha256Hex(`${identity.source}\\0${identity.version}\\0${HELP_INDEX_PATH}`);\n return path.join(this.root, key);\n }\n\n discard(identity: HelpPackageIdentity): void {\n fs.rmSync(this.entryDirectory(identity), { recursive: true, force: true });\n }\n\n read(identity: HelpPackageIdentity): CachedHelpIndex | undefined {\n const directory = this.entryDirectory(identity);\n const completionPath = path.join(directory, COMPLETION_FILE);\n const indexPath = path.join(directory, HELP_INDEX_PATH);\n const metadataPath = path.join(directory, CACHE_METADATA_FILE);\n if (!regularFile(completionPath) || !regularFile(indexPath) || !regularFile(metadataPath)) return undefined;\n try {\n const metadata = parseCacheMetadata(JSON.parse(fs.readFileSync(metadataPath, 'utf8')) as unknown, identity);\n if (!metadata) return undefined;\n const bytes = fs.readFileSync(indexPath);\n if (sha256Hex(bytes) !== metadata.digest) return undefined;\n if (fs.readFileSync(completionPath, 'utf8').trim() !== metadata.digest) return undefined;\n return {\n bytes,\n filePath: indexPath,\n integrity: metadata.integrity,\n digest: metadata.digest,\n referenceBase: metadata.referenceBase,\n };\n } catch {\n return undefined;\n }\n }\n\n publish(\n identity: HelpPackageIdentity,\n bytes: Uint8Array,\n integrity: string,\n referenceBase: string,\n signal: AbortSignal,\n ): CachedHelpIndex {\n assertNotAborted(signal);\n const existing = this.read(identity);\n if (existing) return existing;\n const directory = this.entryDirectory(identity);\n fs.mkdirSync(this.root, { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n const digest = sha256Hex(bytes);\n const metadata: CacheMetadata = {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source: identity.source,\n version: identity.version,\n path: HELP_INDEX_PATH,\n integrity,\n digest,\n referenceBase,\n };\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, HELP_INDEX_PATH), bytes, { mode: PRIVATE_FILE_MODE });\n fs.writeFileSync(path.join(temporary, CACHE_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, {\n mode: PRIVATE_FILE_MODE,\n });\n assertNotAborted(signal);\n fs.writeFileSync(path.join(temporary, COMPLETION_FILE), `${digest}\\n`, { mode: PRIVATE_FILE_MODE });\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n const winner = this.read(identity);\n if (winner) return winner;\n throw error;\n }\n return {\n bytes: Uint8Array.from(bytes),\n filePath: path.join(directory, HELP_INDEX_PATH),\n integrity,\n digest,\n referenceBase,\n };\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n}\n\nexport class DefaultHelpSkillMaterializer implements HelpSkillMaterializer {\n constructor(private readonly cacheRoot = defaultHelpCacheRoot()) {}\n\n async materialize(\n contribution: DoomHelpContribution,\n index: ResolvedHelpIndex,\n signal: AbortSignal,\n ): Promise<readonly DoomHelpSkill[]> {\n const skills: DoomHelpSkill[] = [];\n for (const descriptor of contribution.skills) {\n assertNotAborted(signal);\n const key = sha256Hex(\n `${index.identity.source}\\0${index.identity.version}\\0${descriptor.name}\\0${descriptor.description}\\0${index.digest}`,\n );\n const directory = path.join(this.cacheRoot, WRAPPER_DIRECTORY, key);\n const filePath = path.join(directory, SKILL_FILE);\n const content = renderHelpSkillWrapper(descriptor, index);\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) {\n fs.mkdirSync(path.dirname(directory), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, SKILL_FILE), content, { mode: PRIVATE_FILE_MODE });\n assertNotAborted(signal);\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) throw error;\n }\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n skills.push({\n source: contribution.source,\n name: descriptor.name,\n description: descriptor.description,\n filePath,\n baseDir: directory,\n });\n }\n return skills;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpStorage.mjs","names":[],"sources":["../../src/adapters/helpStorage.ts"],"sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { DoomHelpContribution, DoomHelpSkill } from '@agimon-ai/doompi-extension-contracts/help';\nimport { renderHelpSkillWrapper } from '../services/llmsContent.ts';\nimport type { HelpPackageIdentity, HelpSkillMaterializer, ResolvedHelpIndex } from '../types/help.ts';\n\nconst PACKAGE_MANIFEST = 'package.json';\nconst HELP_INDEX_PATH = 'llms.txt';\nconst CACHE_SCHEMA_VERSION = 1;\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst COMPLETION_FILE = '.complete';\nconst CACHE_METADATA_FILE = 'metadata.json';\nconst WRAPPER_DIRECTORY = 'wrappers';\nconst SKILL_FILE = 'SKILL.md';\nconst EXACT_SEMVER_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/u;\nconst NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/u;\n\ninterface CacheMetadata {\n schemaVersion: typeof CACHE_SCHEMA_VERSION;\n source: string;\n version: string;\n path: typeof HELP_INDEX_PATH;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nexport interface CachedHelpIndex {\n bytes: Uint8Array;\n filePath: string;\n integrity: string;\n digest: string;\n referenceBase: string;\n}\n\nfunction assertNotAborted(signal: AbortSignal): void {\n if (signal.aborted) throw new Error('Help activation was cancelled.');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isContained(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));\n}\n\nfunction readManifest(filePath: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as unknown;\n } catch (error) {\n throw new Error(\n `Cannot read Help package manifest at ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!isRecord(parsed)) throw new Error(`Help package manifest at ${filePath} must contain an object.`);\n return parsed;\n}\n\nexport function resolveHelpPackageIdentity(moduleUrl: string, expectedSource: string): HelpPackageIdentity {\n if (!NPM_PACKAGE_NAME_PATTERN.test(expectedSource)) {\n throw new Error(`Help source '${expectedSource}' must be a valid lowercase npm package name.`);\n }\n let modulePath: string;\n try {\n const url = new URL(moduleUrl);\n if (url.protocol !== 'file:') throw new Error(`Help module URL must use file:, received ${url.protocol}`);\n modulePath = fs.realpathSync(fileURLToPath(url));\n } catch (error) {\n throw new Error(\n `Invalid Help contributor module URL '${moduleUrl}': ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!fs.lstatSync(modulePath).isFile())\n throw new Error(`Help contributor module is not a regular file: ${modulePath}`);\n\n let directory = path.dirname(modulePath);\n while (true) {\n const manifestPath = path.join(directory, PACKAGE_MANIFEST);\n if (fs.existsSync(manifestPath)) {\n const manifest = readManifest(manifestPath);\n const source = manifest.name;\n const version = manifest.version;\n if (source !== expectedSource) {\n throw new Error(`Help source '${expectedSource}' does not match nearest package '${String(source)}'.`);\n }\n if (typeof version !== 'string' || !EXACT_SEMVER_PATTERN.test(version)) {\n throw new Error(`Help package '${expectedSource}' must declare an exact semantic version.`);\n }\n const packageRoot = fs.realpathSync(directory);\n if (!isContained(packageRoot, modulePath))\n throw new Error('Help contributor module escapes its resolved package root.');\n return { source: expectedSource, version, packageRoot, modulePath };\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Cannot find a package manifest for Help contributor ${modulePath}.`);\n}\n\nexport function defaultHelpCacheRoot(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, '.pi', '.doom', 'llms-cache');\n}\n\nexport function sha256Hex(bytes: Uint8Array | string): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction parseCacheMetadata(value: unknown, identity: HelpPackageIdentity): CacheMetadata | undefined {\n if (!isRecord(value)) return undefined;\n if (\n value.schemaVersion !== CACHE_SCHEMA_VERSION ||\n value.source !== identity.source ||\n value.version !== identity.version ||\n value.path !== HELP_INDEX_PATH ||\n typeof value.integrity !== 'string' ||\n typeof value.digest !== 'string' ||\n typeof value.referenceBase !== 'string'\n ) {\n return undefined;\n }\n return value as unknown as CacheMetadata;\n}\n\nfunction regularFile(filePath: string): boolean {\n try {\n const metadata = fs.lstatSync(filePath);\n return metadata.isFile() && !metadata.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport class HelpIndexCache {\n readonly root: string;\n\n constructor(root = defaultHelpCacheRoot()) {\n this.root = root;\n }\n\n entryDirectory(identity: HelpPackageIdentity): string {\n const key = sha256Hex(`${identity.source}\\0${identity.version}\\0${HELP_INDEX_PATH}`);\n return path.join(this.root, key);\n }\n\n discard(identity: HelpPackageIdentity): void {\n fs.rmSync(this.entryDirectory(identity), { recursive: true, force: true });\n }\n\n read(identity: HelpPackageIdentity): CachedHelpIndex | undefined {\n const directory = this.entryDirectory(identity);\n const completionPath = path.join(directory, COMPLETION_FILE);\n const indexPath = path.join(directory, HELP_INDEX_PATH);\n const metadataPath = path.join(directory, CACHE_METADATA_FILE);\n if (!regularFile(completionPath) || !regularFile(indexPath) || !regularFile(metadataPath)) return undefined;\n try {\n const metadata = parseCacheMetadata(JSON.parse(fs.readFileSync(metadataPath, 'utf8')) as unknown, identity);\n if (!metadata) return undefined;\n const bytes = fs.readFileSync(indexPath);\n if (sha256Hex(bytes) !== metadata.digest) return undefined;\n if (fs.readFileSync(completionPath, 'utf8').trim() !== metadata.digest) return undefined;\n return {\n bytes,\n filePath: indexPath,\n integrity: metadata.integrity,\n digest: metadata.digest,\n referenceBase: metadata.referenceBase,\n };\n } catch {\n return undefined;\n }\n }\n\n publish(\n identity: HelpPackageIdentity,\n bytes: Uint8Array,\n integrity: string,\n referenceBase: string,\n signal: AbortSignal,\n ): CachedHelpIndex {\n assertNotAborted(signal);\n const existing = this.read(identity);\n if (existing) return existing;\n const directory = this.entryDirectory(identity);\n fs.mkdirSync(this.root, { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n const digest = sha256Hex(bytes);\n const metadata: CacheMetadata = {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source: identity.source,\n version: identity.version,\n path: HELP_INDEX_PATH,\n integrity,\n digest,\n referenceBase,\n };\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, HELP_INDEX_PATH), bytes, { mode: PRIVATE_FILE_MODE });\n fs.writeFileSync(path.join(temporary, CACHE_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, {\n mode: PRIVATE_FILE_MODE,\n });\n assertNotAborted(signal);\n fs.writeFileSync(path.join(temporary, COMPLETION_FILE), `${digest}\\n`, { mode: PRIVATE_FILE_MODE });\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n const winner = this.read(identity);\n if (winner) return winner;\n throw error;\n }\n return {\n bytes: Uint8Array.from(bytes),\n filePath: path.join(directory, HELP_INDEX_PATH),\n integrity,\n digest,\n referenceBase,\n };\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n}\n\nexport class DefaultHelpSkillMaterializer implements HelpSkillMaterializer {\n constructor(private readonly cacheRoot = defaultHelpCacheRoot()) {}\n\n async materialize(\n contribution: DoomHelpContribution,\n index: ResolvedHelpIndex,\n signal: AbortSignal,\n ): Promise<readonly DoomHelpSkill[]> {\n const skills: DoomHelpSkill[] = [];\n for (const descriptor of contribution.skills) {\n assertNotAborted(signal);\n const key = sha256Hex(\n `${index.identity.source}\\0${index.identity.version}\\0${descriptor.name}\\0${descriptor.description}\\0${index.digest}`,\n );\n const directory = path.join(this.cacheRoot, WRAPPER_DIRECTORY, key);\n const filePath = path.join(directory, SKILL_FILE);\n const content = renderHelpSkillWrapper(descriptor, index);\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) {\n fs.mkdirSync(path.dirname(directory), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n if (fs.existsSync(directory)) fs.rmSync(directory, { recursive: true, force: true });\n const temporary = `${directory}.${process.pid}.${randomUUID()}.tmp`;\n try {\n fs.mkdirSync(temporary, { mode: PRIVATE_DIRECTORY_MODE });\n fs.writeFileSync(path.join(temporary, SKILL_FILE), content, { mode: PRIVATE_FILE_MODE });\n assertNotAborted(signal);\n try {\n fs.renameSync(temporary, directory);\n } catch (error) {\n if (!regularFile(filePath) || fs.readFileSync(filePath, 'utf8') !== content) throw error;\n }\n } finally {\n fs.rmSync(temporary, { recursive: true, force: true });\n }\n }\n skills.push({\n source: contribution.source,\n name: descriptor.name,\n description: descriptor.description,\n filePath,\n baseDir: directory,\n });\n }\n return skills;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./helpCommand.cjs"),t=require("./helpMode.cjs"),n=require("../../container/index.cjs");let r=require("@agimon-ai/doompi-extension-contracts/cordis-host"),i=require("@agimon-ai/doompi-extension-contracts/help"),a=require("@agimon-ai/doompi-extension-contracts/mode"),o=require("@agimon-ai/doompi-extension-contracts/ui-hub");const s=`@agimon-ai/doompi-help`;function c(c,l,u={}){let d;e.registerHelpCommand(l,()=>{if(!d)throw Error(`Doom Help is waiting for the active session service.`);return d}),c.inject([r.DOOM_CORDIS_SESSION_SERVICE],e=>{let c=e.get(r.DOOM_CORDIS_SESSION_SERVICE),l=(0,i.createDoomHelpService)(`${c.generation}:help`),f=l.register({source:s,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-use-help`,description:`Use Doom Pi Help to activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.`}]}),p=n.createHelpRuntime(l,u);d=p.activation;try{e.provide(i.DOOM_HELP_SERVICE,l),e.inject([a.DOOM_MINOR_MODE_CATALOG_SERVICE],e=>{let n=t.registerHelpModeIntegration((0,a.requireMinorModeCatalog)(e),p.activation);return()=>n.dispose()}),e.inject([o.DOOM_UI_HUB_SERVICE],e=>t.registerHelpUiIntegration((0,o.requireDoomUiHub)(e),p.activation))}catch(e){throw d===p.activation&&(d=void 0),p.dispose(),f.dispose(),l.dispose(),e}return()=>{d===p.activation&&(d=void 0),p.dispose(),f.dispose(),l.dispose()}})}async function l(e){let t=await(0,r.connectDoomCordisHost)(e,s),n=t.root.plugin(u,{pi:e});try{await n}catch(e){try{await n.dispose()}finally{await t.dispose()}throw e}let i;e.on(`session_shutdown`,()=>i??=(async()=>{try{await n.dispose()}finally{await t.dispose()}})())}function u(e,t){c(e,t.pi)}exports.default=l,exports.helpExtension=l,exports.installHelpRuntime=c;
|
|
2
|
+
//# sourceMappingURL=extension.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.cjs","names":["DOOM_CORDIS_SESSION_SERVICE","createDoomHelpService","createHelpRuntime","DOOM_HELP_SERVICE","DOOM_MINOR_MODE_CATALOG_SERVICE","registerHelpModeIntegration","requireMinorModeCatalog","DOOM_UI_HUB_SERVICE","registerHelpUiIntegration","requireDoomUiHub","connectDoomCordisHost"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import {\n connectDoomCordisHost,\n DOOM_CORDIS_SESSION_SERVICE,\n type DoomCordisSessionService,\n} from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n createDoomHelpService,\n DOOM_HELP_SERVICE,\n type DoomHelpService,\n} from '@agimon-ai/doompi-extension-contracts/help';\nimport { DOOM_MINOR_MODE_CATALOG_SERVICE, requireMinorModeCatalog } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHelpCommand } from '../../adapters/pi/helpCommand.ts';\nimport { registerHelpModeIntegration, registerHelpUiIntegration } from '../../adapters/pi/helpMode.ts';\nimport { createHelpRuntime, type HelpRuntimeOptions } from '../../container/index.ts';\nimport type { HelpActivationService } from '../../types/help.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-help';\n\n/** Install Help resources into its host-owned Cordis plugin fiber. */\nexport function installHelpRuntime(cordis: Context, pi: ExtensionAPI, options: HelpRuntimeOptions = {}): void {\n let activeActivation: HelpActivationService | undefined;\n registerHelpCommand(pi, () => {\n if (!activeActivation) throw new Error('Doom Help is waiting for the active session service.');\n return activeActivation;\n });\n\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], (sessionContext) => {\n const session = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const service: DoomHelpService = createDoomHelpService(`${session.generation}:help`);\n const selfContribution = service.register({\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-use-help',\n description:\n 'Use Doom Pi Help to activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.',\n },\n ],\n });\n const runtime = createHelpRuntime(service, options);\n activeActivation = runtime.activation;\n try {\n sessionContext.provide(DOOM_HELP_SERVICE, service);\n sessionContext.inject([DOOM_MINOR_MODE_CATALOG_SERVICE], (modeContext) => {\n const mode = registerHelpModeIntegration(requireMinorModeCatalog(modeContext), runtime.activation);\n return () => mode.dispose();\n });\n sessionContext.inject([DOOM_UI_HUB_SERVICE], (uiContext) =>\n registerHelpUiIntegration(requireDoomUiHub(uiContext), runtime.activation),\n );\n } catch (error) {\n if (activeActivation === runtime.activation) activeActivation = undefined;\n runtime.dispose();\n selfContribution.dispose();\n service.dispose();\n throw error;\n }\n return () => {\n if (activeActivation === runtime.activation) activeActivation = undefined;\n runtime.dispose();\n selfContribution.dispose();\n service.dispose();\n };\n });\n}\n\n/** The package's single standard Pi factory, including optional typed Doom integrations. */\nexport async function helpExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(helpPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface HelpPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction helpPlugin(cordis: Context, config: HelpPluginConfig): void {\n installHelpRuntime(cordis, config.pi);\n}\n\nexport default helpExtension;\n"],"mappings":"qVAmBA,MAAM,EAAiB,yBAGvB,SAAgB,EAAmB,EAAiB,EAAkB,EAA8B,CAAC,EAAS,CAC5G,IAAI,EACJ,EAAA,oBAAoB,MAAU,CAC5B,GAAI,CAAC,EAAkB,MAAU,MAAM,sDAAsD,EAC7F,OAAO,CACT,CAAC,EAED,EAAO,OAAO,CAACA,EAAAA,2BAA2B,EAAI,GAAmB,CAC/D,IAAM,EAAU,EAAe,IAAIA,EAAAA,2BAA2B,EACxD,GAAA,EAA2BC,EAAAA,sBAAAA,CAAsB,GAAG,EAAQ,WAAW,MAAM,EAC7E,EAAmB,EAAQ,SAAS,CACxC,OAAQ,EACR,UAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,KACA,OAAQ,CACN,CACE,KAAM,kBACN,YACE,kIACJ,CACF,CACF,CAAC,EACK,EAAUC,EAAAA,kBAAkB,EAAS,CAAO,EAClD,EAAmB,EAAQ,WAC3B,GAAI,CACF,EAAe,QAAQC,EAAAA,kBAAmB,CAAO,EACjD,EAAe,OAAO,CAACC,EAAAA,+BAA+B,EAAI,GAAgB,CACxE,IAAM,EAAOC,EAAAA,6BAAAA,EAA4BC,EAAAA,wBAAAA,CAAwB,CAAW,EAAG,EAAQ,UAAU,EACjG,UAAa,EAAK,QAAQ,CAC5B,CAAC,EACD,EAAe,OAAO,CAACC,EAAAA,mBAAmB,EAAI,GAC5CC,EAAAA,2BAAAA,EAA0BC,EAAAA,iBAAAA,CAAiB,CAAS,EAAG,EAAQ,UAAU,CAC3E,CACF,OAAS,EAAO,CAKd,MAJI,IAAqB,EAAQ,aAAY,EAAmB,IAAA,IAChE,EAAQ,QAAQ,EAChB,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,EACV,CACR,CACA,UAAa,CACP,IAAqB,EAAQ,aAAY,EAAmB,IAAA,IAChE,EAAQ,QAAQ,EAChB,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,CAClB,CACF,CAAC,CACH,CAGA,eAAsB,EAAc,EAAiC,CACnE,IAAM,EAAa,MAAA,EAAMC,EAAAA,sBAAAA,CAAsB,EAAI,CAAc,EAC3D,EAAQ,EAAW,KAAK,OAAO,EAAY,CAAE,IAAG,CAAC,EACvD,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CACA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF,CAMA,SAAS,EAAW,EAAiB,EAAgC,CACnE,EAAmB,EAAQ,EAAO,EAAE,CACtC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HelpRuntimeOptions } from "../../container/index.cjs";
|
|
2
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
//#region src/adapters/pi/extension.d.ts
|
|
5
|
+
/** Install Help resources into its host-owned Cordis plugin fiber. */
|
|
6
|
+
export declare function installHelpRuntime(cordis: Context, pi: ExtensionAPI, options?: HelpRuntimeOptions): void;
|
|
7
|
+
/** The package's single standard Pi factory, including optional typed Doom integrations. */
|
|
8
|
+
export declare function helpExtension(pi: ExtensionAPI): Promise<void>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { helpExtension as default };
|
|
11
|
+
//# sourceMappingURL=extension.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;wBAsBgB,mBAAmB,QAAQ,SAAS,IAAI,cAAc,UAAS;;wBAiDzD,cAAc,IAAI,eAAe"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HelpRuntimeOptions } from "../../container/index.mjs";
|
|
2
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
//#region src/adapters/pi/extension.d.ts
|
|
5
|
+
/** Install Help resources into its host-owned Cordis plugin fiber. */
|
|
6
|
+
export declare function installHelpRuntime(cordis: Context, pi: ExtensionAPI, options?: HelpRuntimeOptions): void;
|
|
7
|
+
/** The package's single standard Pi factory, including optional typed Doom integrations. */
|
|
8
|
+
export declare function helpExtension(pi: ExtensionAPI): Promise<void>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { helpExtension as default };
|
|
11
|
+
//# sourceMappingURL=extension.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;wBAsBgB,mBAAmB,QAAQ,SAAS,IAAI,cAAc,UAAS;;wBAiDzD,cAAc,IAAI,eAAe"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{registerHelpCommand as e}from"./helpCommand.mjs";import{registerHelpModeIntegration as t,registerHelpUiIntegration as n}from"./helpMode.mjs";import{createHelpRuntime as r}from"../../container/index.mjs";import{DOOM_CORDIS_SESSION_SERVICE as i,connectDoomCordisHost as a}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_HELP_SERVICE as o,createDoomHelpService as s}from"@agimon-ai/doompi-extension-contracts/help";import{DOOM_MINOR_MODE_CATALOG_SERVICE as c,requireMinorModeCatalog as l}from"@agimon-ai/doompi-extension-contracts/mode";import{DOOM_UI_HUB_SERVICE as u,requireDoomUiHub as d}from"@agimon-ai/doompi-extension-contracts/ui-hub";const f=`@agimon-ai/doompi-help`;function p(a,p,m={}){let h;e(p,()=>{if(!h)throw Error(`Doom Help is waiting for the active session service.`);return h}),a.inject([i],e=>{let a=e.get(i),p=s(`${a.generation}:help`),g=p.register({source:f,moduleUrl:import.meta.url,skills:[{name:`doompi-use-help`,description:`Use Doom Pi Help to activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.`}]}),_=r(p,m);h=_.activation;try{e.provide(o,p),e.inject([c],e=>{let n=t(l(e),_.activation);return()=>n.dispose()}),e.inject([u],e=>n(d(e),_.activation))}catch(e){throw h===_.activation&&(h=void 0),_.dispose(),g.dispose(),p.dispose(),e}return()=>{h===_.activation&&(h=void 0),_.dispose(),g.dispose(),p.dispose()}})}async function m(e){let t=await a(e,f),n=t.root.plugin(h,{pi:e});try{await n}catch(e){try{await n.dispose()}finally{await t.dispose()}throw e}let r;e.on(`session_shutdown`,()=>r??=(async()=>{try{await n.dispose()}finally{await t.dispose()}})())}function h(e,t){p(e,t.pi)}export{m as default,m as helpExtension,p as installHelpRuntime};
|
|
2
|
+
//# sourceMappingURL=extension.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import {\n connectDoomCordisHost,\n DOOM_CORDIS_SESSION_SERVICE,\n type DoomCordisSessionService,\n} from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n createDoomHelpService,\n DOOM_HELP_SERVICE,\n type DoomHelpService,\n} from '@agimon-ai/doompi-extension-contracts/help';\nimport { DOOM_MINOR_MODE_CATALOG_SERVICE, requireMinorModeCatalog } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHelpCommand } from '../../adapters/pi/helpCommand.ts';\nimport { registerHelpModeIntegration, registerHelpUiIntegration } from '../../adapters/pi/helpMode.ts';\nimport { createHelpRuntime, type HelpRuntimeOptions } from '../../container/index.ts';\nimport type { HelpActivationService } from '../../types/help.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-help';\n\n/** Install Help resources into its host-owned Cordis plugin fiber. */\nexport function installHelpRuntime(cordis: Context, pi: ExtensionAPI, options: HelpRuntimeOptions = {}): void {\n let activeActivation: HelpActivationService | undefined;\n registerHelpCommand(pi, () => {\n if (!activeActivation) throw new Error('Doom Help is waiting for the active session service.');\n return activeActivation;\n });\n\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], (sessionContext) => {\n const session = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const service: DoomHelpService = createDoomHelpService(`${session.generation}:help`);\n const selfContribution = service.register({\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-use-help',\n description:\n 'Use Doom Pi Help to activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.',\n },\n ],\n });\n const runtime = createHelpRuntime(service, options);\n activeActivation = runtime.activation;\n try {\n sessionContext.provide(DOOM_HELP_SERVICE, service);\n sessionContext.inject([DOOM_MINOR_MODE_CATALOG_SERVICE], (modeContext) => {\n const mode = registerHelpModeIntegration(requireMinorModeCatalog(modeContext), runtime.activation);\n return () => mode.dispose();\n });\n sessionContext.inject([DOOM_UI_HUB_SERVICE], (uiContext) =>\n registerHelpUiIntegration(requireDoomUiHub(uiContext), runtime.activation),\n );\n } catch (error) {\n if (activeActivation === runtime.activation) activeActivation = undefined;\n runtime.dispose();\n selfContribution.dispose();\n service.dispose();\n throw error;\n }\n return () => {\n if (activeActivation === runtime.activation) activeActivation = undefined;\n runtime.dispose();\n selfContribution.dispose();\n service.dispose();\n };\n });\n}\n\n/** The package's single standard Pi factory, including optional typed Doom integrations. */\nexport async function helpExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(helpPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface HelpPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction helpPlugin(cordis: Context, config: HelpPluginConfig): void {\n installHelpRuntime(cordis, config.pi);\n}\n\nexport default helpExtension;\n"],"mappings":"0pBAmBA,MAAM,EAAiB,yBAGvB,SAAgB,EAAmB,EAAiB,EAAkB,EAA8B,CAAC,EAAS,CAC5G,IAAI,EACJ,EAAoB,MAAU,CAC5B,GAAI,CAAC,EAAkB,MAAU,MAAM,sDAAsD,EAC7F,OAAO,CACT,CAAC,EAED,EAAO,OAAO,CAAC,CAA2B,EAAI,GAAmB,CAC/D,IAAM,EAAU,EAAe,IAAI,CAA2B,EACxD,EAA2B,EAAsB,GAAG,EAAQ,WAAW,MAAM,EAC7E,EAAmB,EAAQ,SAAS,CACxC,OAAQ,EACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,kBACN,YACE,kIACJ,CACF,CACF,CAAC,EACK,EAAU,EAAkB,EAAS,CAAO,EAClD,EAAmB,EAAQ,WAC3B,GAAI,CACF,EAAe,QAAQ,EAAmB,CAAO,EACjD,EAAe,OAAO,CAAC,CAA+B,EAAI,GAAgB,CACxE,IAAM,EAAO,EAA4B,EAAwB,CAAW,EAAG,EAAQ,UAAU,EACjG,UAAa,EAAK,QAAQ,CAC5B,CAAC,EACD,EAAe,OAAO,CAAC,CAAmB,EAAI,GAC5C,EAA0B,EAAiB,CAAS,EAAG,EAAQ,UAAU,CAC3E,CACF,OAAS,EAAO,CAKd,MAJI,IAAqB,EAAQ,aAAY,EAAmB,IAAA,IAChE,EAAQ,QAAQ,EAChB,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,EACV,CACR,CACA,UAAa,CACP,IAAqB,EAAQ,aAAY,EAAmB,IAAA,IAChE,EAAQ,QAAQ,EAChB,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,CAClB,CACF,CAAC,CACH,CAGA,eAAsB,EAAc,EAAiC,CACnE,IAAM,EAAa,MAAM,EAAsB,EAAI,CAAc,EAC3D,EAAQ,EAAW,KAAK,OAAO,EAAY,CAAE,IAAG,CAAC,EACvD,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CACA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF,CAMA,SAAS,EAAW,EAAiB,EAAgC,CACnE,EAAmB,EAAQ,EAAO,EAAE,CACtC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=`doom-help`,t=`Toggle package Help guidance`;function n(n,r){n.registerCommand(e,{description:t,handler:async(e,t)=>{let n=r(),i=n.getState().activation===`inactive`?await n.activate():n.deactivate();if(!t.hasUI)return;let a=i.activation===`inactive`?`Package Help deactivated.`:`Package Help activated.`;t.ui.notify(a,i.activation===`degraded`?`warning`:`info`)}})}exports.HELP_COMMAND_DESCRIPTION=t,exports.HELP_COMMAND_NAME=e,exports.registerHelpCommand=n;
|
|
2
|
+
//# sourceMappingURL=helpCommand.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpCommand.cjs","names":[],"sources":["../../../src/adapters/pi/helpCommand.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { HelpActivationService } from '../../types/help.ts';\n\nexport const HELP_COMMAND_NAME = 'doom-help';\nexport const HELP_COMMAND_DESCRIPTION = 'Toggle package Help guidance';\n\nexport type RequireHelpActivation = () => HelpActivationService;\n\nexport function registerHelpCommand(\n pi: Pick<ExtensionAPI, 'registerCommand'>,\n requireActivation: RequireHelpActivation,\n): void {\n pi.registerCommand(HELP_COMMAND_NAME, {\n description: HELP_COMMAND_DESCRIPTION,\n handler: async (_arguments, context) => {\n const activation = requireActivation();\n const current = activation.getState();\n const next = current.activation === 'inactive' ? await activation.activate() : activation.deactivate();\n if (!context.hasUI) return;\n const message = next.activation === 'inactive' ? 'Package Help deactivated.' : 'Package Help activated.';\n context.ui.notify(message, next.activation === 'degraded' ? 'warning' : 'info');\n },\n });\n}\n"],"mappings":"AAGA,MAAa,EAAoB,YACpB,EAA2B,+BAIxC,SAAgB,EACd,EACA,EACM,CACN,EAAG,gBAAgB,EAAmB,CACpC,YAAa,EACb,QAAS,MAAO,EAAY,IAAY,CACtC,IAAM,EAAa,EAAkB,EAE/B,EADU,EAAW,SACR,CAAC,CAAC,aAAe,WAAa,MAAM,EAAW,SAAS,EAAI,EAAW,WAAW,EACrG,GAAI,CAAC,EAAQ,MAAO,OACpB,IAAM,EAAU,EAAK,aAAe,WAAa,4BAA8B,0BAC/E,EAAQ,GAAG,OAAO,EAAS,EAAK,aAAe,WAAa,UAAY,MAAM,CAChF,CACF,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=`doom-help`,t=`Toggle package Help guidance`;function n(n,r){n.registerCommand(e,{description:t,handler:async(e,t)=>{let n=r(),i=n.getState().activation===`inactive`?await n.activate():n.deactivate();if(!t.hasUI)return;let a=i.activation===`inactive`?`Package Help deactivated.`:`Package Help activated.`;t.ui.notify(a,i.activation===`degraded`?`warning`:`info`)}})}export{t as HELP_COMMAND_DESCRIPTION,e as HELP_COMMAND_NAME,n as registerHelpCommand};
|
|
2
|
+
//# sourceMappingURL=helpCommand.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpCommand.mjs","names":[],"sources":["../../../src/adapters/pi/helpCommand.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { HelpActivationService } from '../../types/help.ts';\n\nexport const HELP_COMMAND_NAME = 'doom-help';\nexport const HELP_COMMAND_DESCRIPTION = 'Toggle package Help guidance';\n\nexport type RequireHelpActivation = () => HelpActivationService;\n\nexport function registerHelpCommand(\n pi: Pick<ExtensionAPI, 'registerCommand'>,\n requireActivation: RequireHelpActivation,\n): void {\n pi.registerCommand(HELP_COMMAND_NAME, {\n description: HELP_COMMAND_DESCRIPTION,\n handler: async (_arguments, context) => {\n const activation = requireActivation();\n const current = activation.getState();\n const next = current.activation === 'inactive' ? await activation.activate() : activation.deactivate();\n if (!context.hasUI) return;\n const message = next.activation === 'inactive' ? 'Package Help deactivated.' : 'Package Help activated.';\n context.ui.notify(message, next.activation === 'degraded' ? 'warning' : 'info');\n },\n });\n}\n"],"mappings":"AAGA,MAAa,EAAoB,YACpB,EAA2B,+BAIxC,SAAgB,EACd,EACA,EACM,CACN,EAAG,gBAAgB,EAAmB,CACpC,YAAa,EACb,QAAS,MAAO,EAAY,IAAY,CACtC,IAAM,EAAa,EAAkB,EAE/B,EADU,EAAW,SACR,CAAC,CAAC,aAAe,WAAa,MAAM,EAAW,SAAS,EAAI,EAAW,WAAW,EACrG,GAAI,CAAC,EAAQ,MAAO,OACpB,IAAM,EAAU,EAAK,aAAe,WAAa,4BAA8B,0BAC/E,EAAQ,GAAG,OAAO,EAAS,EAAK,aAAe,WAAa,UAAY,MAAM,CAChF,CACF,CAAC,CACH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("@agimon-ai/doompi-extension-contracts/
|
|
1
|
+
let e=require("@agimon-ai/doompi-extension-contracts/mode");const t=`@agimon-ai/doompi-help`,n=`help`,r=`help.toggle`,i={key:`h`,label:`help`,detail:`package docs and logs`,order:70},a=`activate`,o=`deactivate`;function s(e){return e.slice(0,160)}function c(e){if(e.activation===`activating`)return{activation:`activating`,condition:`queued`,detail:`loading package Help`,actions:[{id:a,enabled:!1,disabledReason:`Help activation is already running.`},{id:o,enabled:!0}]};if(e.activation===`active`||e.activation===`degraded`){let t=e.activation===`degraded`;return{activation:`active`,condition:t?`degraded`:`ready`,detail:s(`${e.skills.length} package Help skill${e.skills.length===1?``:`s`}`),...t?{color:`warning`}:{color:`accent`},actions:[{id:a,enabled:!1,disabledReason:`Help is already active.`},{id:o,enabled:!0}]}}let t=e.diagnostics[0]?.message;return{activation:`inactive`,condition:t?`failed`:`ready`,...t?{detail:s(t),color:`warning`}:{},actions:[{id:a,enabled:!0},{id:o,enabled:!1,disabledReason:`Help is not active.`}]}}function l(e){let t=e.activation!==`inactive`;return[{id:`help.toggle`,path:[i,t?{key:`e`,label:`exit`,detail:`hide package Help`}:{key:`e`,label:`enter`,detail:`load package Help`}],action:{name:r}}]}function u(e){queueMicrotask(()=>{throw e instanceof Error?e:Error(String(e))})}function d(r,i){let l=(0,e.registerMinorModeOwner)(r,{descriptor:{source:t,id:n,label:`Help`,description:`Activation-gated package guidance from exact installed package versions.`,order:50,actions:[{id:a,label:`Activate`,description:`Load package-owned Help indexes and expose their generated skills.`,contexts:[`tui`,`headless`],parameters:[]},{id:o,label:`Deactivate`,description:`Remove all active package Help skills immediately.`,contexts:[`tui`,`headless`],parameters:[]}]},initialState:c(i.getState()),async handleAction(e,t,n){if(e===a){let e=await i.activate(n.signal);return{message:s(`Activated ${e.skills.length} package Help skill${e.skills.length===1?``:`s`}${e.activation===`degraded`?` with diagnostics.`:`.`}`)}}if(e===o)return i.deactivate(),{message:`Package Help deactivated.`};throw Error(`Unknown Help mode action: ${e}`)},onError:u}),d=i.subscribe(e=>l.publish(c(e))),f=!1;return{mode:l,dispose(){f||(f=!0,d(),l.dispose())}}}function f(e,n){let i=e.registerLeader({source:t,bindings:l(n.getState())}),a=e.registerLeaderActions({source:t,handlers:{[r]:async e=>{n.getState().activation===`inactive`?await n.activate():n.deactivate(),e.hasUI&&e.ui.notify(n.getState().activation===`inactive`?`Package Help deactivated.`:`Package Help activated.`,`info`)}},onError:(e,t,n)=>{n.hasUI?n.ui.notify(e instanceof Error?e.message:String(e),`error`):u(e)}}),o=n.subscribe(e=>i.update(l(e))),s=!1;return()=>{s||(s=!0,o(),a(),i.dispose())}}exports.HELP_LEADER_ACTION=r,exports.HELP_MODE_ID=n,exports.HELP_PACKAGE_SOURCE=t,exports.helpMinorModeState=c,exports.registerHelpModeIntegration=d,exports.registerHelpUiIntegration=f;
|
|
2
2
|
//# sourceMappingURL=helpMode.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpMode.cjs","names":["registerMinorModeOwner"
|
|
1
|
+
{"version":3,"file":"helpMode.cjs","names":["registerMinorModeOwner"],"sources":["../../../src/adapters/pi/helpMode.ts"],"sourcesContent":["import type { LeaderBinding } from '@agimon-ai/doompi-extension-contracts/leader';\nimport {\n type MinorModeCatalogService,\n type MinorModeOwnerHandle,\n type MinorModeState,\n registerMinorModeOwner,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport type { DoomUiHubService } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { HelpActivationService, HelpRuntimeState } from '../../types/help.ts';\n\nexport const HELP_PACKAGE_SOURCE = '@agimon-ai/doompi-help';\nexport const HELP_MODE_ID = 'help';\nexport const HELP_MODE_ORDER = 50;\nexport const HELP_LEADER_ACTION = 'help.toggle';\n\nconst HELP_GROUP = { key: 'h', label: 'help', detail: 'package docs and logs', order: 70 } as const;\nconst MODE_ACTION_ACTIVATE = 'activate';\nconst MODE_ACTION_DEACTIVATE = 'deactivate';\nconst MAX_MODE_DETAIL_LENGTH = 160;\n\nfunction boundedDetail(value: string): string {\n return value.slice(0, MAX_MODE_DETAIL_LENGTH);\n}\n\nexport function helpMinorModeState(state: HelpRuntimeState): MinorModeState {\n if (state.activation === 'activating') {\n return {\n activation: 'activating',\n condition: 'queued',\n detail: 'loading package Help',\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: false, disabledReason: 'Help activation is already running.' },\n { id: MODE_ACTION_DEACTIVATE, enabled: true },\n ],\n };\n }\n if (state.activation === 'active' || state.activation === 'degraded') {\n const degraded = state.activation === 'degraded';\n return {\n activation: 'active',\n condition: degraded ? 'degraded' : 'ready',\n detail: boundedDetail(`${state.skills.length} package Help skill${state.skills.length === 1 ? '' : 's'}`),\n ...(degraded ? { color: 'warning' as const } : { color: 'accent' as const }),\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: false, disabledReason: 'Help is already active.' },\n { id: MODE_ACTION_DEACTIVATE, enabled: true },\n ],\n };\n }\n const failure = state.diagnostics[0]?.message;\n return {\n activation: 'inactive',\n condition: failure ? 'failed' : 'ready',\n ...(failure ? { detail: boundedDetail(failure), color: 'warning' as const } : {}),\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: true },\n { id: MODE_ACTION_DEACTIVATE, enabled: false, disabledReason: 'Help is not active.' },\n ],\n };\n}\n\nfunction leaderBindings(state: HelpRuntimeState): LeaderBinding[] {\n const active = state.activation !== 'inactive';\n return [\n {\n id: 'help.toggle',\n path: [\n HELP_GROUP,\n active\n ? { key: 'e', label: 'exit', detail: 'hide package Help' }\n : { key: 'e', label: 'enter', detail: 'load package Help' },\n ],\n action: { name: HELP_LEADER_ACTION },\n },\n ];\n}\n\nfunction reportAsync(error: unknown): void {\n queueMicrotask(() => {\n throw error instanceof Error ? error : new Error(String(error));\n });\n}\n\nexport interface HelpModeIntegration {\n mode: MinorModeOwnerHandle;\n dispose(): void;\n}\n\nexport function registerHelpModeIntegration(\n catalog: MinorModeCatalogService,\n activation: HelpActivationService,\n): HelpModeIntegration {\n const mode = registerMinorModeOwner<ExtensionContext>(catalog, {\n descriptor: {\n source: HELP_PACKAGE_SOURCE,\n id: HELP_MODE_ID,\n label: 'Help',\n description: 'Activation-gated package guidance from exact installed package versions.',\n order: HELP_MODE_ORDER,\n actions: [\n {\n id: MODE_ACTION_ACTIVATE,\n label: 'Activate',\n description: 'Load package-owned Help indexes and expose their generated skills.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: MODE_ACTION_DEACTIVATE,\n label: 'Deactivate',\n description: 'Remove all active package Help skills immediately.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n initialState: helpMinorModeState(activation.getState()),\n async handleAction(actionId, _arguments, execution) {\n if (actionId === MODE_ACTION_ACTIVATE) {\n const state = await activation.activate(execution.signal);\n return {\n message: boundedDetail(\n `Activated ${state.skills.length} package Help skill${state.skills.length === 1 ? '' : 's'}${state.activation === 'degraded' ? ' with diagnostics.' : '.'}`,\n ),\n };\n }\n if (actionId === MODE_ACTION_DEACTIVATE) {\n activation.deactivate();\n return { message: 'Package Help deactivated.' };\n }\n throw new Error(`Unknown Help mode action: ${actionId}`);\n },\n onError: reportAsync,\n });\n const stateDisposer = activation.subscribe((state) => mode.publish(helpMinorModeState(state)));\n let disposed = false;\n return {\n mode,\n dispose() {\n if (disposed) return;\n disposed = true;\n stateDisposer();\n mode.dispose();\n },\n };\n}\n\nexport function registerHelpUiIntegration(hub: DoomUiHubService, activation: HelpActivationService): () => void {\n const leader = hub.registerLeader({\n source: HELP_PACKAGE_SOURCE,\n bindings: leaderBindings(activation.getState()),\n });\n const actionDisposer = hub.registerLeaderActions<ExtensionContext>({\n source: HELP_PACKAGE_SOURCE,\n handlers: {\n [HELP_LEADER_ACTION]: async (context) => {\n const state = activation.getState();\n if (state.activation === 'inactive') await activation.activate();\n else activation.deactivate();\n if (context.hasUI) {\n context.ui.notify(\n activation.getState().activation === 'inactive' ? 'Package Help deactivated.' : 'Package Help activated.',\n 'info',\n );\n }\n },\n },\n onError: (error, _action, context) => {\n if (context.hasUI) context.ui.notify(error instanceof Error ? error.message : String(error), 'error');\n else reportAsync(error);\n },\n });\n const stateDisposer = activation.subscribe((state) => leader.update(leaderBindings(state)));\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n stateDisposer();\n actionDisposer();\n leader.dispose();\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{registerMinorModeOwner as e}from"@agimon-ai/doompi-extension-contracts/mode";const t=`@agimon-ai/doompi-help`,n=`help`,r=`help.toggle`,i={key:`h`,label:`help`,detail:`package docs and logs`,order:70},a=`activate`,o=`deactivate`;function s(e){return e.slice(0,160)}function c(e){if(e.activation===`activating`)return{activation:`activating`,condition:`queued`,detail:`loading package Help`,actions:[{id:a,enabled:!1,disabledReason:`Help activation is already running.`},{id:o,enabled:!0}]};if(e.activation===`active`||e.activation===`degraded`){let t=e.activation===`degraded`;return{activation:`active`,condition:t?`degraded`:`ready`,detail:s(`${e.skills.length} package Help skill${e.skills.length===1?``:`s`}`),...t?{color:`warning`}:{color:`accent`},actions:[{id:a,enabled:!1,disabledReason:`Help is already active.`},{id:o,enabled:!0}]}}let t=e.diagnostics[0]?.message;return{activation:`inactive`,condition:t?`failed`:`ready`,...t?{detail:s(t),color:`warning`}:{},actions:[{id:a,enabled:!0},{id:o,enabled:!1,disabledReason:`Help is not active.`}]}}function l(e){let t=e.activation!==`inactive`;return[{id:`help.toggle`,path:[i,t?{key:`e`,label:`exit`,detail:`hide package Help`}:{key:`e`,label:`enter`,detail:`load package Help`}],action:{name:r}}]}function u(e){queueMicrotask(()=>{throw e instanceof Error?e:Error(String(e))})}function d(r,i){let l=e(r,{descriptor:{source:t,id:n,label:`Help`,description:`Activation-gated package guidance from exact installed package versions.`,order:50,actions:[{id:a,label:`Activate`,description:`Load package-owned Help indexes and expose their generated skills.`,contexts:[`tui`,`headless`],parameters:[]},{id:o,label:`Deactivate`,description:`Remove all active package Help skills immediately.`,contexts:[`tui`,`headless`],parameters:[]}]},initialState:c(i.getState()),async handleAction(e,t,n){if(e===a){let e=await i.activate(n.signal);return{message:s(`Activated ${e.skills.length} package Help skill${e.skills.length===1?``:`s`}${e.activation===`degraded`?` with diagnostics.`:`.`}`)}}if(e===o)return i.deactivate(),{message:`Package Help deactivated.`};throw Error(`Unknown Help mode action: ${e}`)},onError:u}),d=i.subscribe(e=>l.publish(c(e))),f=!1;return{mode:l,dispose(){f||(f=!0,d(),l.dispose())}}}function f(e,n){let i=e.registerLeader({source:t,bindings:l(n.getState())}),a=e.registerLeaderActions({source:t,handlers:{[r]:async e=>{n.getState().activation===`inactive`?await n.activate():n.deactivate(),e.hasUI&&e.ui.notify(n.getState().activation===`inactive`?`Package Help deactivated.`:`Package Help activated.`,`info`)}},onError:(e,t,n)=>{n.hasUI?n.ui.notify(e instanceof Error?e.message:String(e),`error`):u(e)}}),o=n.subscribe(e=>i.update(l(e))),s=!1;return()=>{s||(s=!0,o(),a(),i.dispose())}}export{r as HELP_LEADER_ACTION,n as HELP_MODE_ID,t as HELP_PACKAGE_SOURCE,c as helpMinorModeState,d as registerHelpModeIntegration,f as registerHelpUiIntegration};
|
|
2
2
|
//# sourceMappingURL=helpMode.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpMode.mjs","names":[],"sources":["../../../src/adapters/pi/helpMode.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"helpMode.mjs","names":[],"sources":["../../../src/adapters/pi/helpMode.ts"],"sourcesContent":["import type { LeaderBinding } from '@agimon-ai/doompi-extension-contracts/leader';\nimport {\n type MinorModeCatalogService,\n type MinorModeOwnerHandle,\n type MinorModeState,\n registerMinorModeOwner,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport type { DoomUiHubService } from '@agimon-ai/doompi-extension-contracts/ui-hub';\nimport type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { HelpActivationService, HelpRuntimeState } from '../../types/help.ts';\n\nexport const HELP_PACKAGE_SOURCE = '@agimon-ai/doompi-help';\nexport const HELP_MODE_ID = 'help';\nexport const HELP_MODE_ORDER = 50;\nexport const HELP_LEADER_ACTION = 'help.toggle';\n\nconst HELP_GROUP = { key: 'h', label: 'help', detail: 'package docs and logs', order: 70 } as const;\nconst MODE_ACTION_ACTIVATE = 'activate';\nconst MODE_ACTION_DEACTIVATE = 'deactivate';\nconst MAX_MODE_DETAIL_LENGTH = 160;\n\nfunction boundedDetail(value: string): string {\n return value.slice(0, MAX_MODE_DETAIL_LENGTH);\n}\n\nexport function helpMinorModeState(state: HelpRuntimeState): MinorModeState {\n if (state.activation === 'activating') {\n return {\n activation: 'activating',\n condition: 'queued',\n detail: 'loading package Help',\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: false, disabledReason: 'Help activation is already running.' },\n { id: MODE_ACTION_DEACTIVATE, enabled: true },\n ],\n };\n }\n if (state.activation === 'active' || state.activation === 'degraded') {\n const degraded = state.activation === 'degraded';\n return {\n activation: 'active',\n condition: degraded ? 'degraded' : 'ready',\n detail: boundedDetail(`${state.skills.length} package Help skill${state.skills.length === 1 ? '' : 's'}`),\n ...(degraded ? { color: 'warning' as const } : { color: 'accent' as const }),\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: false, disabledReason: 'Help is already active.' },\n { id: MODE_ACTION_DEACTIVATE, enabled: true },\n ],\n };\n }\n const failure = state.diagnostics[0]?.message;\n return {\n activation: 'inactive',\n condition: failure ? 'failed' : 'ready',\n ...(failure ? { detail: boundedDetail(failure), color: 'warning' as const } : {}),\n actions: [\n { id: MODE_ACTION_ACTIVATE, enabled: true },\n { id: MODE_ACTION_DEACTIVATE, enabled: false, disabledReason: 'Help is not active.' },\n ],\n };\n}\n\nfunction leaderBindings(state: HelpRuntimeState): LeaderBinding[] {\n const active = state.activation !== 'inactive';\n return [\n {\n id: 'help.toggle',\n path: [\n HELP_GROUP,\n active\n ? { key: 'e', label: 'exit', detail: 'hide package Help' }\n : { key: 'e', label: 'enter', detail: 'load package Help' },\n ],\n action: { name: HELP_LEADER_ACTION },\n },\n ];\n}\n\nfunction reportAsync(error: unknown): void {\n queueMicrotask(() => {\n throw error instanceof Error ? error : new Error(String(error));\n });\n}\n\nexport interface HelpModeIntegration {\n mode: MinorModeOwnerHandle;\n dispose(): void;\n}\n\nexport function registerHelpModeIntegration(\n catalog: MinorModeCatalogService,\n activation: HelpActivationService,\n): HelpModeIntegration {\n const mode = registerMinorModeOwner<ExtensionContext>(catalog, {\n descriptor: {\n source: HELP_PACKAGE_SOURCE,\n id: HELP_MODE_ID,\n label: 'Help',\n description: 'Activation-gated package guidance from exact installed package versions.',\n order: HELP_MODE_ORDER,\n actions: [\n {\n id: MODE_ACTION_ACTIVATE,\n label: 'Activate',\n description: 'Load package-owned Help indexes and expose their generated skills.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: MODE_ACTION_DEACTIVATE,\n label: 'Deactivate',\n description: 'Remove all active package Help skills immediately.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n initialState: helpMinorModeState(activation.getState()),\n async handleAction(actionId, _arguments, execution) {\n if (actionId === MODE_ACTION_ACTIVATE) {\n const state = await activation.activate(execution.signal);\n return {\n message: boundedDetail(\n `Activated ${state.skills.length} package Help skill${state.skills.length === 1 ? '' : 's'}${state.activation === 'degraded' ? ' with diagnostics.' : '.'}`,\n ),\n };\n }\n if (actionId === MODE_ACTION_DEACTIVATE) {\n activation.deactivate();\n return { message: 'Package Help deactivated.' };\n }\n throw new Error(`Unknown Help mode action: ${actionId}`);\n },\n onError: reportAsync,\n });\n const stateDisposer = activation.subscribe((state) => mode.publish(helpMinorModeState(state)));\n let disposed = false;\n return {\n mode,\n dispose() {\n if (disposed) return;\n disposed = true;\n stateDisposer();\n mode.dispose();\n },\n };\n}\n\nexport function registerHelpUiIntegration(hub: DoomUiHubService, activation: HelpActivationService): () => void {\n const leader = hub.registerLeader({\n source: HELP_PACKAGE_SOURCE,\n bindings: leaderBindings(activation.getState()),\n });\n const actionDisposer = hub.registerLeaderActions<ExtensionContext>({\n source: HELP_PACKAGE_SOURCE,\n handlers: {\n [HELP_LEADER_ACTION]: async (context) => {\n const state = activation.getState();\n if (state.activation === 'inactive') await activation.activate();\n else activation.deactivate();\n if (context.hasUI) {\n context.ui.notify(\n activation.getState().activation === 'inactive' ? 'Package Help deactivated.' : 'Package Help activated.',\n 'info',\n );\n }\n },\n },\n onError: (error, _action, context) => {\n if (context.hasUI) context.ui.notify(error instanceof Error ? error.message : String(error), 'error');\n else reportAsync(error);\n },\n });\n const stateDisposer = activation.subscribe((state) => leader.update(leaderBindings(state)));\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n stateDisposer();\n actionDisposer();\n leader.dispose();\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["defaultHelpCacheRoot","HelpIndexCache","DefaultHelpActivationService","DefaultHelpIndexResolver","DefaultHelpSkillMaterializer"],"sources":["../../src/container/index.ts"],"sourcesContent":["import type { DoomHelpContribution,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["defaultHelpCacheRoot","HelpIndexCache","DefaultHelpActivationService","DefaultHelpIndexResolver","DefaultHelpSkillMaterializer"],"sources":["../../src/container/index.ts"],"sourcesContent":["import type { DoomHelpContribution, DoomHelpService } from '@agimon-ai/doompi-extension-contracts/help';\nimport { DefaultHelpSkillMaterializer, defaultHelpCacheRoot, HelpIndexCache } from '../adapters/helpStorage.ts';\nimport { DefaultHelpIndexResolver } from '../adapters/llmsResolver.ts';\nimport { DefaultHelpActivationService } from '../services/helpActivation.ts';\nimport type { HelpFetch } from '../types/help.ts';\n\nexport interface HelpRuntimeOptions {\n cacheRoot?: string;\n fetch?: HelpFetch;\n timeoutMs?: number;\n onBackgroundError?(error: unknown): void;\n}\n\nexport interface HelpRuntimeComposition {\n activation: DefaultHelpActivationService;\n dispose(): void;\n}\n\nfunction reportAsync(error: unknown): void {\n queueMicrotask(() => {\n throw error instanceof Error ? error : new Error(String(error));\n });\n}\n\nexport function createHelpRuntime(service: DoomHelpService, options: HelpRuntimeOptions = {}): HelpRuntimeComposition {\n const cacheRoot = options.cacheRoot ?? defaultHelpCacheRoot();\n const cache = new HelpIndexCache(cacheRoot);\n const activation = new DefaultHelpActivationService({\n resolver: new DefaultHelpIndexResolver({ cache, fetch: options.fetch, timeoutMs: options.timeoutMs }),\n materializer: new DefaultHelpSkillMaterializer(cacheRoot),\n publisher: { publish: (snapshot) => service.publish(snapshot) },\n onBackgroundError(error) {\n if (options.onBackgroundError) options.onBackgroundError(error);\n else reportAsync(error);\n },\n });\n const synchronize = (contributions: readonly DoomHelpContribution[]): void => {\n activation.replaceContributions(contributions);\n };\n const unsubscribe = service.subscribeContributions((contributions) => synchronize(contributions));\n synchronize(service.listContributions());\n let disposed = false;\n return {\n activation,\n dispose() {\n if (disposed) return;\n disposed = true;\n unsubscribe();\n activation.dispose();\n },\n };\n}\n"],"mappings":"qIAkBA,SAAS,EAAY,EAAsB,CACzC,mBAAqB,CACnB,MAAM,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,CAChE,CAAC,CACH,CAEA,SAAgB,EAAkB,EAA0B,EAA8B,CAAC,EAA2B,CACpH,IAAM,EAAY,EAAQ,WAAaA,EAAAA,qBAAqB,EACtD,EAAQ,IAAIC,EAAAA,eAAe,CAAS,EACpC,EAAa,IAAIC,EAAAA,6BAA6B,CAClD,SAAU,IAAIC,EAAAA,yBAAyB,CAAE,QAAO,MAAO,EAAQ,MAAO,UAAW,EAAQ,SAAU,CAAC,EACpG,aAAc,IAAIC,EAAAA,6BAA6B,CAAS,EACxD,UAAW,CAAE,QAAU,GAAa,EAAQ,QAAQ,CAAQ,CAAE,EAC9D,kBAAkB,EAAO,CACnB,EAAQ,kBAAmB,EAAQ,kBAAkB,CAAK,EACzD,EAAY,CAAK,CACxB,CACF,CAAC,EACK,EAAe,GAAyD,CAC5E,EAAW,qBAAqB,CAAa,CAC/C,EACM,EAAc,EAAQ,uBAAwB,GAAkB,EAAY,CAAa,CAAC,EAChG,EAAY,EAAQ,kBAAkB,CAAC,EACvC,IAAI,EAAW,GACf,MAAO,CACL,aACA,SAAU,CACJ,IACJ,EAAW,GACX,EAAY,EACZ,EAAW,QAAQ,EACrB,CACF,CACF"}
|
|
@@ -2,12 +2,11 @@ import { HelpFetch } from "../types/help.cjs";
|
|
|
2
2
|
import "../services/helpActivation.cjs";
|
|
3
3
|
import "@agimon-ai/doompi-extension-contracts/help";
|
|
4
4
|
//#region src/container/index.d.ts
|
|
5
|
-
interface HelpRuntimeOptions {
|
|
5
|
+
export interface HelpRuntimeOptions {
|
|
6
6
|
cacheRoot?: string;
|
|
7
7
|
fetch?: HelpFetch;
|
|
8
8
|
timeoutMs?: number;
|
|
9
9
|
onBackgroundError?(error: unknown): void;
|
|
10
10
|
}
|
|
11
11
|
//#endregion
|
|
12
|
-
export { HelpRuntimeOptions };
|
|
13
12
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;;;iBAMiB;EACf;EACA,QAAQ;EACR;EACA,mBAAmB"}
|
|
@@ -2,12 +2,11 @@ import { HelpFetch } from "../types/help.mjs";
|
|
|
2
2
|
import "../services/helpActivation.mjs";
|
|
3
3
|
import "@agimon-ai/doompi-extension-contracts/help";
|
|
4
4
|
//#region src/container/index.d.ts
|
|
5
|
-
interface HelpRuntimeOptions {
|
|
5
|
+
export interface HelpRuntimeOptions {
|
|
6
6
|
cacheRoot?: string;
|
|
7
7
|
fetch?: HelpFetch;
|
|
8
8
|
timeoutMs?: number;
|
|
9
9
|
onBackgroundError?(error: unknown): void;
|
|
10
10
|
}
|
|
11
11
|
//#endregion
|
|
12
|
-
export { HelpRuntimeOptions };
|
|
13
12
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/container/index.ts"],"mappings":";;;;iBAMiB;EACf;EACA,QAAQ;EACR;EACA,mBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import type { DoomHelpContribution,
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/container/index.ts"],"sourcesContent":["import type { DoomHelpContribution, DoomHelpService } from '@agimon-ai/doompi-extension-contracts/help';\nimport { DefaultHelpSkillMaterializer, defaultHelpCacheRoot, HelpIndexCache } from '../adapters/helpStorage.ts';\nimport { DefaultHelpIndexResolver } from '../adapters/llmsResolver.ts';\nimport { DefaultHelpActivationService } from '../services/helpActivation.ts';\nimport type { HelpFetch } from '../types/help.ts';\n\nexport interface HelpRuntimeOptions {\n cacheRoot?: string;\n fetch?: HelpFetch;\n timeoutMs?: number;\n onBackgroundError?(error: unknown): void;\n}\n\nexport interface HelpRuntimeComposition {\n activation: DefaultHelpActivationService;\n dispose(): void;\n}\n\nfunction reportAsync(error: unknown): void {\n queueMicrotask(() => {\n throw error instanceof Error ? error : new Error(String(error));\n });\n}\n\nexport function createHelpRuntime(service: DoomHelpService, options: HelpRuntimeOptions = {}): HelpRuntimeComposition {\n const cacheRoot = options.cacheRoot ?? defaultHelpCacheRoot();\n const cache = new HelpIndexCache(cacheRoot);\n const activation = new DefaultHelpActivationService({\n resolver: new DefaultHelpIndexResolver({ cache, fetch: options.fetch, timeoutMs: options.timeoutMs }),\n materializer: new DefaultHelpSkillMaterializer(cacheRoot),\n publisher: { publish: (snapshot) => service.publish(snapshot) },\n onBackgroundError(error) {\n if (options.onBackgroundError) options.onBackgroundError(error);\n else reportAsync(error);\n },\n });\n const synchronize = (contributions: readonly DoomHelpContribution[]): void => {\n activation.replaceContributions(contributions);\n };\n const unsubscribe = service.subscribeContributions((contributions) => synchronize(contributions));\n synchronize(service.listContributions());\n let disposed = false;\n return {\n activation,\n dispose() {\n if (disposed) return;\n disposed = true;\n unsubscribe();\n activation.dispose();\n },\n };\n}\n"],"mappings":"+QAkBA,SAAS,EAAY,EAAsB,CACzC,mBAAqB,CACnB,MAAM,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,CAChE,CAAC,CACH,CAEA,SAAgB,EAAkB,EAA0B,EAA8B,CAAC,EAA2B,CACpH,IAAM,EAAY,EAAQ,WAAa,EAAqB,EACtD,EAAQ,IAAI,EAAe,CAAS,EACpC,EAAa,IAAI,EAA6B,CAClD,SAAU,IAAI,EAAyB,CAAE,QAAO,MAAO,EAAQ,MAAO,UAAW,EAAQ,SAAU,CAAC,EACpG,aAAc,IAAI,EAA6B,CAAS,EACxD,UAAW,CAAE,QAAU,GAAa,EAAQ,QAAQ,CAAQ,CAAE,EAC9D,kBAAkB,EAAO,CACnB,EAAQ,kBAAmB,EAAQ,kBAAkB,CAAK,EACzD,EAAY,CAAK,CACxB,CACF,CAAC,EACK,EAAe,GAAyD,CAC5E,EAAW,qBAAqB,CAAa,CAC/C,EACM,EAAc,EAAQ,uBAAwB,GAAkB,EAAY,CAAa,CAAC,EAChG,EAAY,EAAQ,kBAAkB,CAAC,EACvC,IAAI,EAAW,GACf,MAAO,CACL,aACA,SAAU,CACJ,IACJ,EAAW,GACX,EAAY,EACZ,EAAW,QAAQ,EACrB,CACF,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../adapters/pi/extension.cjs");module.exports=e.default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"../adapters/pi/extension.mjs";export{e as default};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/pi/extension.cjs");exports.helpExtension=e.default,exports.installHelpRuntime=e.installHelpRuntime;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export {
|
|
1
|
+
import helpExtension, { installHelpRuntime } from "./adapters/pi/extension.cjs";
|
|
2
|
+
export { helpExtension, installHelpRuntime };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export {
|
|
1
|
+
import helpExtension, { installHelpRuntime } from "./adapters/pi/extension.mjs";
|
|
2
|
+
export { helpExtension, installHelpRuntime };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e,{
|
|
1
|
+
import e,{installHelpRuntime as t}from"./adapters/pi/extension.mjs";export{e as helpExtension,t as installHelpRuntime};
|
package/dist/types/help.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@agimon-ai/doompi-extension-contracts/help";
|
|
2
2
|
//#region src/types/help.d.ts
|
|
3
|
-
interface HelpFetchResponse {
|
|
3
|
+
export interface HelpFetchResponse {
|
|
4
4
|
ok: boolean;
|
|
5
5
|
status: number;
|
|
6
6
|
headers: {
|
|
@@ -9,10 +9,9 @@ interface HelpFetchResponse {
|
|
|
9
9
|
text(): Promise<string>;
|
|
10
10
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
11
11
|
}
|
|
12
|
-
type HelpFetch = (input: string, init: {
|
|
12
|
+
export type HelpFetch = (input: string, init: {
|
|
13
13
|
signal: AbortSignal;
|
|
14
14
|
redirect: 'manual';
|
|
15
15
|
}) => Promise<HelpFetchResponse>;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { HelpFetch, HelpFetchResponse };
|
|
18
17
|
//# sourceMappingURL=help.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.cts","names":[],"sources":["../../src/types/help.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"help.d.cts","names":[],"sources":["../../src/types/help.ts"],"mappings":";;iBA+DiB;EACf;EACA;EACA;IAAW,IAAI;;EACf,QAAQ;EACR,eAAe,QAAQ;;YAGb,aACV,eACA;EAAQ,QAAQ;EAAa;MAC1B,QAAQ"}
|
package/dist/types/help.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@agimon-ai/doompi-extension-contracts/help";
|
|
2
2
|
//#region src/types/help.d.ts
|
|
3
|
-
interface HelpFetchResponse {
|
|
3
|
+
export interface HelpFetchResponse {
|
|
4
4
|
ok: boolean;
|
|
5
5
|
status: number;
|
|
6
6
|
headers: {
|
|
@@ -9,10 +9,9 @@ interface HelpFetchResponse {
|
|
|
9
9
|
text(): Promise<string>;
|
|
10
10
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
11
11
|
}
|
|
12
|
-
type HelpFetch = (input: string, init: {
|
|
12
|
+
export type HelpFetch = (input: string, init: {
|
|
13
13
|
signal: AbortSignal;
|
|
14
14
|
redirect: 'manual';
|
|
15
15
|
}) => Promise<HelpFetchResponse>;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { HelpFetch, HelpFetchResponse };
|
|
18
17
|
//# sourceMappingURL=help.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.mts","names":[],"sources":["../../src/types/help.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"help.d.mts","names":[],"sources":["../../src/types/help.ts"],"mappings":";;iBA+DiB;EACf;EACA;EACA;IAAW,IAAI;;EACf,QAAQ;EACR,eAAe,QAAQ;;YAGb,aACV,eACA;EAAQ,QAAQ;EAAa;MAC1B,QAAQ"}
|
package/llms.txt
CHANGED
|
@@ -5,3 +5,7 @@ Activation-gated, package-owned guidance for Doom Pi parent sessions.
|
|
|
5
5
|
## Resources
|
|
6
6
|
|
|
7
7
|
- [Package README](./README.md): Public entrypoints, activation model, security guarantees, and development commands.
|
|
8
|
+
|
|
9
|
+
## How to use
|
|
10
|
+
|
|
11
|
+
- [doompi-use-help](./src/prompts/doompi-use-help/SKILL.md): Activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.
|
package/package.json
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-help",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
4
|
-
"description": "Activation-gated package guidance for DoomPi",
|
|
3
|
+
"version": "0.0.1-alpha.51",
|
|
4
|
+
"description": "Activation-gated package guidance and help skills for DoomPi and Pi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"agent-documentation",
|
|
6
7
|
"ai",
|
|
7
8
|
"coding-agent",
|
|
8
9
|
"developer-tools",
|
|
9
10
|
"doompi",
|
|
11
|
+
"help-system",
|
|
12
|
+
"pi-coding-agent",
|
|
10
13
|
"pi-extension",
|
|
11
14
|
"pi-package",
|
|
12
|
-
"
|
|
15
|
+
"skills"
|
|
13
16
|
],
|
|
14
17
|
"homepage": "https://agimon.ai",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/AgiFlow/doompi/issues"
|
|
20
|
+
},
|
|
15
21
|
"license": "MIT",
|
|
16
22
|
"author": "Vuong Ngo",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/AgiFlow/doompi.git",
|
|
26
|
+
"directory": "packages/minor/doompi-help"
|
|
27
|
+
},
|
|
17
28
|
"files": [
|
|
18
29
|
"dist",
|
|
30
|
+
"src/web",
|
|
31
|
+
"src/exports/webClient.ts",
|
|
19
32
|
"llms.txt",
|
|
33
|
+
"src/prompts",
|
|
20
34
|
"README.md",
|
|
21
35
|
"LICENSE",
|
|
22
36
|
"package.json"
|
|
@@ -31,10 +45,10 @@
|
|
|
31
45
|
"import": "./dist/index.mjs",
|
|
32
46
|
"require": "./dist/index.cjs"
|
|
33
47
|
},
|
|
34
|
-
"./extensions/
|
|
35
|
-
"types": "./dist/extensions/
|
|
36
|
-
"import": "./dist/extensions/
|
|
37
|
-
"require": "./dist/extensions/
|
|
48
|
+
"./extensions/pi": {
|
|
49
|
+
"types": "./dist/extensions/pi.d.mts",
|
|
50
|
+
"import": "./dist/extensions/pi.mjs",
|
|
51
|
+
"require": "./dist/extensions/pi.cjs"
|
|
38
52
|
},
|
|
39
53
|
"./package.json": "./package.json"
|
|
40
54
|
},
|
|
@@ -42,19 +56,21 @@
|
|
|
42
56
|
"access": "public"
|
|
43
57
|
},
|
|
44
58
|
"dependencies": {
|
|
45
|
-
"@
|
|
59
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
60
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.67",
|
|
61
|
+
"@agimon-ai/doompi-web-contracts": "0.0.1-alpha.30"
|
|
46
62
|
},
|
|
47
63
|
"devDependencies": {
|
|
48
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
49
|
-
"@types/node": "26.
|
|
50
|
-
"@vitest/coverage-v8": "
|
|
51
|
-
"tsdown": "0.
|
|
52
|
-
"typescript": "
|
|
53
|
-
"vitest": "
|
|
54
|
-
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.
|
|
64
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
65
|
+
"@types/node": "26.4.1",
|
|
66
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
67
|
+
"tsdown": "0.23.0",
|
|
68
|
+
"typescript": "7.0.2",
|
|
69
|
+
"vitest": "5.0.0",
|
|
70
|
+
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.64"
|
|
55
71
|
},
|
|
56
72
|
"peerDependencies": {
|
|
57
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
73
|
+
"@earendil-works/pi-coding-agent": "0.85.1"
|
|
58
74
|
},
|
|
59
75
|
"peerDependenciesMeta": {
|
|
60
76
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -64,15 +80,20 @@
|
|
|
64
80
|
"engines": {
|
|
65
81
|
"node": ">=22.19.0"
|
|
66
82
|
},
|
|
83
|
+
"doompiWeb": {
|
|
84
|
+
"pluginId": "help",
|
|
85
|
+
"channels": [],
|
|
86
|
+
"client": "./src/exports/webClient.ts"
|
|
87
|
+
},
|
|
67
88
|
"pi": {
|
|
68
89
|
"extensions": [
|
|
69
|
-
"./dist/extensions/
|
|
90
|
+
"./dist/extensions/pi.mjs"
|
|
70
91
|
]
|
|
71
92
|
},
|
|
72
93
|
"scripts": {
|
|
73
94
|
"build": "tsdown",
|
|
74
95
|
"test": "vitest --run",
|
|
75
|
-
"typecheck": "tsc --noEmit",
|
|
96
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p src/web/tsconfig.json",
|
|
76
97
|
"lint": "oxlint . && oxfmt . --check",
|
|
77
98
|
"fixcode": "oxlint . --fix && oxfmt ."
|
|
78
99
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { webPlugin } from '../web/index.ts';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doompi-use-help
|
|
3
|
+
description: Use Doom Pi Help to activate package guidance, load exact-version skills, and diagnose unavailable or conflicting contributions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Use Doom Pi Help
|
|
7
|
+
|
|
8
|
+
Use Help when a question depends on the installed Doom Pi packages and their current authoring or usage guidance.
|
|
9
|
+
|
|
10
|
+
## Activate guidance
|
|
11
|
+
|
|
12
|
+
1. In an interactive Doom Pi session, use `SPC h e` to toggle Help.
|
|
13
|
+
2. In standalone Pi, run `/doom-help`.
|
|
14
|
+
3. In a headless host, invoke Help through the shared minor-mode catalog.
|
|
15
|
+
4. Read the skills that appear after activation, then select the narrowest skill for the task.
|
|
16
|
+
5. Deactivate Help when the package guidance is no longer needed.
|
|
17
|
+
|
|
18
|
+
Help resolves package-owned `llms.txt` indexes from the installed package, an immutable exact-version cache, or an integrity-verified exact-version registry fallback. Treat the resulting skills as guidance for the installed version, not for an unspecified latest release.
|
|
19
|
+
|
|
20
|
+
## Diagnose activation
|
|
21
|
+
|
|
22
|
+
- If Help remains inactive, inspect the first reported diagnostic and verify that at least one package contributed a valid index and skill.
|
|
23
|
+
- If one package fails but others load, continue with the loaded skills and report the degraded source separately.
|
|
24
|
+
- If skill names collide, the contribution from the earlier package source wins and Help records a diagnostic for the duplicate.
|
|
25
|
+
- If no source can load, do not invent package guidance. Report the activation failure and use verified local package documentation instead.
|
|
26
|
+
|
|
27
|
+
Deactivation removes active Help skills immediately. Cached files may remain on disk, but they are not active model context.
|
package/src/web/index.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineWebPlugin } from '@agimon-ai/doompi-web-contracts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This package's cockpit presence: pure metadata. The selection bar renders
|
|
5
|
+
* the minor-mode entry and folds in what the session reports; no signal is published yet, so it shows as unavailable.
|
|
6
|
+
*/
|
|
7
|
+
export const webPlugin = defineWebPlugin({
|
|
8
|
+
id: 'help',
|
|
9
|
+
minorModes: [{ name: 'help', keys: 'h e', order: 10 }],
|
|
10
|
+
// The TUI's SPC h e, through the /minor command an RPC client can send.
|
|
11
|
+
leaderBindings: [
|
|
12
|
+
{
|
|
13
|
+
id: 'help.toggle',
|
|
14
|
+
path: [
|
|
15
|
+
{ key: 'h', label: 'help', detail: 'package docs and logs' },
|
|
16
|
+
{ key: 'e', label: 'toggle', detail: 'load or hide package Help' },
|
|
17
|
+
],
|
|
18
|
+
command: 'minor help',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noImplicitAny": true,
|
|
10
|
+
"noUnusedLocals": true,
|
|
11
|
+
"noUnusedParameters": true,
|
|
12
|
+
"noImplicitReturns": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"esModuleInterop": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"allowImportingTsExtensions": true,
|
|
19
|
+
"forceConsistentCasingInFileNames": true
|
|
20
|
+
},
|
|
21
|
+
"include": [".", "../types", "../exports/webClient.ts"]
|
|
22
|
+
}
|
package/dist/extensions/doom.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../adapters/pi/helpMode.cjs"),t=require("../container/index.cjs");let n=require("@agimon-ai/doompi-extension-contracts/help");const r=`@agimon-ai/doompi-help`,i=Symbol.for(`${r}/installed-hosts`);function a(e){let t=globalThis,n=t[i]??new WeakSet;return t[i]=n,!n.has(e)&&(n.add(e),!0)}function o(i,a={}){let o=i,s=(0,n.provideDoomHelpHost)(o),c=t.createHelpRuntime(s,a),l=e.registerHelpModeIntegration(i,c.activation),u=(0,n.registerDoomHelpContribution)(o,{source:r,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-help`,description:`Use Doom Pi package Help safely, including activation, exact-version retrieval, and diagnostics.`}]});i.on(`session_start`,()=>{c.activation.deactivate()});let d=!1;return()=>{d||(d=!0,l.dispose(),u.dispose(),c.dispose(),s.dispose())}}function s(e){if(!a(e))return;let t=o(e);e.on(`session_shutdown`,t)}exports.activateHelpExtension=o,exports.default=s,exports.registerHelpExtension=s;
|
|
2
|
-
//# sourceMappingURL=doom.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doom.cjs","names":["provideDoomHelpHost","createHelpRuntime","registerHelpModeIntegration","registerDoomHelpContribution"],"sources":["../../src/exports/extensions/doom.ts"],"sourcesContent":["import type { DoomExtensionHost } from '@agimon-ai/doompi-extension-contracts/config';\nimport { provideDoomHelpHost, registerDoomHelpContribution } from '@agimon-ai/doompi-extension-contracts/help';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHelpModeIntegration } from '../../adapters/pi/helpMode.ts';\nimport { createHelpRuntime, type HelpRuntimeOptions } from '../../container/index.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-help';\nconst INSTALLATIONS_KEY = Symbol.for(`${PACKAGE_SOURCE}/installed-hosts`);\n\ntype InstallationRegistry = typeof globalThis & {\n [INSTALLATIONS_KEY]?: WeakSet<object>;\n};\n\nfunction claimHostInstallation(pi: ExtensionAPI): boolean {\n const registry = globalThis as InstallationRegistry;\n const installedHosts = registry[INSTALLATIONS_KEY] ?? new WeakSet<object>();\n registry[INSTALLATIONS_KEY] = installedHosts;\n if (installedHosts.has(pi)) return false;\n installedHosts.add(pi);\n return true;\n}\n\nexport function activateHelpExtension(pi: ExtensionAPI, options: HelpRuntimeOptions = {}): () => void {\n const protocolHost = pi as unknown as DoomExtensionHost;\n const host = provideDoomHelpHost(protocolHost);\n const runtime = createHelpRuntime(host, options);\n const mode = registerHelpModeIntegration(pi, runtime.activation);\n const selfContribution = registerDoomHelpContribution(protocolHost, {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-help',\n description: 'Use Doom Pi package Help safely, including activation, exact-version retrieval, and diagnostics.',\n },\n ],\n });\n pi.on('session_start', () => {\n runtime.activation.deactivate();\n });\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n mode.dispose();\n selfContribution.dispose();\n runtime.dispose();\n host.dispose();\n };\n}\n\nexport function registerHelpExtension(pi: ExtensionAPI): void {\n if (!claimHostInstallation(pi)) return;\n const dispose = activateHelpExtension(pi);\n pi.on('session_shutdown', dispose);\n}\n\nexport default registerHelpExtension;\n"],"mappings":"8OAMA,MAAM,EAAiB,yBACjB,EAAoB,OAAO,IAAI,GAAG,EAAe,iBAAiB,EAMxE,SAAS,EAAsB,EAA2B,CACxD,IAAM,EAAW,WACX,EAAiB,EAAS,IAAsB,IAAI,QAI1D,MAHA,GAAS,GAAqB,EAC9B,CAAI,EAAe,IAAI,CAAE,IACzB,EAAe,IAAI,CAAE,EACd,GACT,CAEA,SAAgB,EAAsB,EAAkB,EAA8B,CAAC,EAAe,CACpG,IAAM,EAAe,EACf,GAAA,EAAOA,EAAAA,oBAAAA,CAAoB,CAAY,EACvC,EAAUC,EAAAA,kBAAkB,EAAM,CAAO,EACzC,EAAOC,EAAAA,4BAA4B,EAAI,EAAQ,UAAU,EACzD,GAAA,EAAmBC,EAAAA,6BAAAA,CAA6B,EAAc,CAClE,OAAQ,EACR,UAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,KACA,OAAQ,CACN,CACE,KAAM,cACN,YAAa,kGACf,CACF,CACF,CAAC,EACD,EAAG,GAAG,oBAAuB,CAC3B,EAAQ,WAAW,WAAW,CAChC,CAAC,EACD,IAAI,EAAW,GACf,UAAa,CACP,IACJ,EAAW,GACX,EAAK,QAAQ,EACb,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,EAChB,EAAK,QAAQ,EACf,CACF,CAEA,SAAgB,EAAsB,EAAwB,CAC5D,GAAI,CAAC,EAAsB,CAAE,EAAG,OAChC,IAAM,EAAU,EAAsB,CAAE,EACxC,EAAG,GAAG,mBAAoB,CAAO,CACnC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { HelpRuntimeOptions } from "../container/index.cjs";
|
|
2
|
-
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
//#region src/exports/extensions/doom.d.ts
|
|
4
|
-
declare function activateHelpExtension(pi: ExtensionAPI, options?: HelpRuntimeOptions): () => void;
|
|
5
|
-
declare function registerHelpExtension(pi: ExtensionAPI): void;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { activateHelpExtension, registerHelpExtension as default, registerHelpExtension };
|
|
8
|
-
//# sourceMappingURL=doom.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doom.d.cts","names":[],"sources":["../../src/exports/extensions/doom.ts"],"mappings":";;;iBAsBgB,sBAAsB,IAAI,cAAc,UAAS;iBA6BjD,sBAAsB,IAAI"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { HelpRuntimeOptions } from "../container/index.mjs";
|
|
2
|
-
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
//#region src/exports/extensions/doom.d.ts
|
|
4
|
-
declare function activateHelpExtension(pi: ExtensionAPI, options?: HelpRuntimeOptions): () => void;
|
|
5
|
-
declare function registerHelpExtension(pi: ExtensionAPI): void;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { activateHelpExtension, registerHelpExtension as default, registerHelpExtension };
|
|
8
|
-
//# sourceMappingURL=doom.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doom.d.mts","names":[],"sources":["../../src/exports/extensions/doom.ts"],"mappings":";;;iBAsBgB,sBAAsB,IAAI,cAAc,UAAS;iBA6BjD,sBAAsB,IAAI"}
|
package/dist/extensions/doom.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{registerHelpModeIntegration as e}from"../adapters/pi/helpMode.mjs";import{createHelpRuntime as t}from"../container/index.mjs";import{provideDoomHelpHost as n,registerDoomHelpContribution as r}from"@agimon-ai/doompi-extension-contracts/help";const i=`@agimon-ai/doompi-help`,a=Symbol.for(`${i}/installed-hosts`);function o(e){let t=globalThis,n=t[a]??new WeakSet;return t[a]=n,!n.has(e)&&(n.add(e),!0)}function s(a,o={}){let s=a,c=n(s),l=t(c,o),u=e(a,l.activation),d=r(s,{source:i,moduleUrl:import.meta.url,skills:[{name:`doompi-help`,description:`Use Doom Pi package Help safely, including activation, exact-version retrieval, and diagnostics.`}]});a.on(`session_start`,()=>{l.activation.deactivate()});let f=!1;return()=>{f||(f=!0,u.dispose(),d.dispose(),l.dispose(),c.dispose())}}function c(e){if(!o(e))return;let t=s(e);e.on(`session_shutdown`,t)}export{s as activateHelpExtension,c as default,c as registerHelpExtension};
|
|
2
|
-
//# sourceMappingURL=doom.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doom.mjs","names":[],"sources":["../../src/exports/extensions/doom.ts"],"sourcesContent":["import type { DoomExtensionHost } from '@agimon-ai/doompi-extension-contracts/config';\nimport { provideDoomHelpHost, registerDoomHelpContribution } from '@agimon-ai/doompi-extension-contracts/help';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHelpModeIntegration } from '../../adapters/pi/helpMode.ts';\nimport { createHelpRuntime, type HelpRuntimeOptions } from '../../container/index.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-help';\nconst INSTALLATIONS_KEY = Symbol.for(`${PACKAGE_SOURCE}/installed-hosts`);\n\ntype InstallationRegistry = typeof globalThis & {\n [INSTALLATIONS_KEY]?: WeakSet<object>;\n};\n\nfunction claimHostInstallation(pi: ExtensionAPI): boolean {\n const registry = globalThis as InstallationRegistry;\n const installedHosts = registry[INSTALLATIONS_KEY] ?? new WeakSet<object>();\n registry[INSTALLATIONS_KEY] = installedHosts;\n if (installedHosts.has(pi)) return false;\n installedHosts.add(pi);\n return true;\n}\n\nexport function activateHelpExtension(pi: ExtensionAPI, options: HelpRuntimeOptions = {}): () => void {\n const protocolHost = pi as unknown as DoomExtensionHost;\n const host = provideDoomHelpHost(protocolHost);\n const runtime = createHelpRuntime(host, options);\n const mode = registerHelpModeIntegration(pi, runtime.activation);\n const selfContribution = registerDoomHelpContribution(protocolHost, {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-help',\n description: 'Use Doom Pi package Help safely, including activation, exact-version retrieval, and diagnostics.',\n },\n ],\n });\n pi.on('session_start', () => {\n runtime.activation.deactivate();\n });\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n mode.dispose();\n selfContribution.dispose();\n runtime.dispose();\n host.dispose();\n };\n}\n\nexport function registerHelpExtension(pi: ExtensionAPI): void {\n if (!claimHostInstallation(pi)) return;\n const dispose = activateHelpExtension(pi);\n pi.on('session_shutdown', dispose);\n}\n\nexport default registerHelpExtension;\n"],"mappings":"wPAMA,MAAM,EAAiB,yBACjB,EAAoB,OAAO,IAAI,GAAG,EAAe,iBAAiB,EAMxE,SAAS,EAAsB,EAA2B,CACxD,IAAM,EAAW,WACX,EAAiB,EAAS,IAAsB,IAAI,QAI1D,MAHA,GAAS,GAAqB,EAC9B,CAAI,EAAe,IAAI,CAAE,IACzB,EAAe,IAAI,CAAE,EACd,GACT,CAEA,SAAgB,EAAsB,EAAkB,EAA8B,CAAC,EAAe,CACpG,IAAM,EAAe,EACf,EAAO,EAAoB,CAAY,EACvC,EAAU,EAAkB,EAAM,CAAO,EACzC,EAAO,EAA4B,EAAI,EAAQ,UAAU,EACzD,EAAmB,EAA6B,EAAc,CAClE,OAAQ,EACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,cACN,YAAa,kGACf,CACF,CACF,CAAC,EACD,EAAG,GAAG,oBAAuB,CAC3B,EAAQ,WAAW,WAAW,CAChC,CAAC,EACD,IAAI,EAAW,GACf,UAAa,CACP,IACJ,EAAW,GACX,EAAK,QAAQ,EACb,EAAiB,QAAQ,EACzB,EAAQ,QAAQ,EAChB,EAAK,QAAQ,EACf,CACF,CAEA,SAAgB,EAAsB,EAAwB,CAC5D,GAAI,CAAC,EAAsB,CAAE,EAAG,OAChC,IAAM,EAAU,EAAsB,CAAE,EACxC,EAAG,GAAG,mBAAoB,CAAO,CACnC"}
|