@agimon-ai/doompi 0.0.1-alpha.29 → 0.0.1-alpha.30
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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./modules/moduleResolution.cjs"),
|
|
1
|
+
const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./modules/moduleResolution.cjs"),n=require("../services/extensionAssembler.cjs"),r=require("./piSettings.cjs");let i=require("node:path");i=e.__toESM(i,1);let a=require("node:fs");a=e.__toESM(a,1);let o=require("@agimon-ai/doompi-config/majorModes"),s=require("@earendil-works/pi-coding-agent");const c=i.default.join(`.pi`,`npm`);function l(e){let t=e.indexOf(`@`,+!!e.startsWith(`@`));return t===-1?e:e.slice(0,t)}const u={"@hono/node-server@2.0.0 - 2.0.9":`^2.0.10`,"@opentelemetry/core@2.0.0 - 2.7.999":`2.8.0`,"brace-expansion@5.0.0 - 5.0.8":`^5.0.9`,"hono@4.0.0 - 4.12.33":`^4.12.34`,"js-yaml@4.0.0 - 4.3.0":`^4.3.1`,"js-yaml@5.0.0 - 5.2.1":`^5.2.2`,"liquidjs@10.0.0 - 10.27.0":`^10.27.1`,"protobufjs@8.0.0 - 8.7.1":`^8.7.2`},d=new Set(Object.keys(u).map(l));function f(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function p(e){return f(e)?{...e}:{}}function m(e){let t=p(e);for(let[e,n]of Object.entries(t))d.has(l(e))?delete t[e]:f(n)&&(t[e]=m(n));return t}function h(e){return i.default.join(e,c,`package.json`)}function g(e,t){let n=new Set,r=[...e.default?[e.default]:[],...t.map(t=>{let n=e.layers[t];if(!n)throw Error(`Unknown layer: ${t}`);return n})];for(let e of r)for(let t of e.packages??[]){let e=typeof t==`string`?t:t.name;(typeof t==`string`||t.optional!==!0)&&!(0,o.isLocalPackageSpecifier)(e)&&n.add(e)}return[...n]}function _(e,t){let n=e.optionalPackageEntries?.(t);if(n!==void 0)return n;let r=e.optionalPackageEntry(t);return r?[r]:void 0}function v(e,t){let n=h(e),r=a.default.existsSync(n)?a.default.readFileSync(n,`utf8`):void 0,o;if(r===void 0)o={name:`pi-extensions`,private:!0};else{let e=JSON.parse(r);if(!f(e))throw Error(`Pi managed package manifest at ${n} must be a JSON object.`);o=e}let s=p(o.dependencies);for(let e of t){let t=e.slice(4);Object.hasOwn(s,t)||(s[t]=`*`)}o.dependencies=s,o.overrides={...m(o.overrides),...u};let c=p(o.pnpm);c.overrides={...m(c.overrides),...u},o.pnpm=c;let l=`${JSON.stringify(o,null,2)}\n`;return l!==r&&(a.default.mkdirSync(i.default.dirname(n),{recursive:!0}),a.default.writeFileSync(n,l,`utf8`),!0)}function y(e,t,n){return g(e,t).filter(e=>_(n,e)===void 0)}function b(e){return[...new Set(e.map(e=>`npm:${t.splitPackageSpecifier(e).name}`))]}function x(e,t){let n=r.piAgentDirectory(t),i=s.SettingsManager.create(e,n,{projectTrusted:!0});return new s.DefaultPackageManager({cwd:e,agentDir:n,settingsManager:i})}async function S(e,t={}){let r=e.environment??process.env,o=t.resolvers??n.createLayerResolvers(e.repoRoot),s=g(e.config,e.layers),c=s.filter(e=>_(o,e)===void 0),l=b(c),u=b(s);if(u.length===0)return[];let d=i.default.dirname(h(e.repoRoot));if(c.length===0&&!a.default.existsSync(d))return[];let f=v(e.repoRoot,u);if(c.length===0&&!f)return[];let p=t.packageManager??x(e.repoRoot,r);try{f?await p.install(u[0],{local:!0}):await p.resolveExtensionSources(l,{local:!0})}catch(e){throw Error(`Failed to reconcile DoomPi layer package(s): ${(f?u:l).join(`, `)}`,{cause:e})}let m=c.filter(e=>!_(o,e)?.length);if(m.length>0)throw Error(`Installed DoomPi layer package(s) did not expose the configured Pi extension: ${m.join(`, `)}`);return l}exports.SAFE_TRANSITIVE_OVERRIDES=u,exports.ensureLayerPackages=S,exports.ensureManagedPackageManifest=v,exports.missingLayerPackageSpecifiers=y;
|
|
2
2
|
//# sourceMappingURL=layerPackageInstaller.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerPackageInstaller.cjs","names":["isLocalPackageSpecifier","splitPackageSpecifier","piAgentDirectory","SettingsManager","DefaultPackageManager","createLayerResolvers"],"sources":["../../../src/adapters/layerPackageInstaller.ts"],"sourcesContent":["import { isLocalPackageSpecifier, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { DefaultPackageManager, type PackageManager, SettingsManager } from '@earendil-works/pi-coding-agent';\nimport { createLayerResolvers, type ExtensionLayerResolvers } from '../services/extensionAssembler.ts';\nimport { splitPackageSpecifier } from './modules/moduleResolution.ts';\nimport { piAgentDirectory } from './piSettings.ts';\n\nconst NPM_SOURCE_PREFIX = 'npm:';\n\ntype LayerPackageManager = Pick<PackageManager, 'resolveExtensionSources'>;\n\nexport interface EnsureLayerPackagesOptions {\n repoRoot: string;\n config: MajorModesConfig;\n layers: readonly string[];\n environment?: NodeJS.ProcessEnv;\n}\n\nexport interface LayerPackageInstallerDependencies {\n packageManager?: LayerPackageManager;\n resolvers?: ExtensionLayerResolvers;\n}\n\nfunction resolvePackageEntries(resolvers: ExtensionLayerResolvers, specifier: string): string[] | undefined {\n const entries = resolvers.optionalPackageEntries?.(specifier);\n if (entries !== undefined) return entries;\n const entry = resolvers.optionalPackageEntry(specifier);\n return entry ? [entry] : undefined;\n}\n\n/** Finds required npm packages selected by defaults and active layers that DoomPi cannot resolve. */\nexport function missingLayerPackageSpecifiers(\n config: MajorModesConfig,\n layers: readonly string[],\n resolvers: ExtensionLayerResolvers,\n): string[] {\n const missing = new Set<string>();\n const selectedDefinitions = [\n ...(config.default ? [config.default] : []),\n ...layers.map((layerName) => {\n const layer = config.layers[layerName];\n if (!layer) throw new Error(`Unknown layer: ${layerName}`);\n return layer;\n }),\n ];\n for (const layer of selectedDefinitions) {\n for (const configured of layer.packages ?? []) {\n const specifier = typeof configured === 'string' ? configured : configured.name;\n const optional = typeof configured !== 'string' && configured.optional === true;\n if (optional || isLocalPackageSpecifier(specifier)) continue;\n // An empty entry list means the package exists but declares no usable Pi\n // extension. Leave that validation to the assembler rather than masking a\n // broken install with another copy from the registry.\n if (resolvePackageEntries(resolvers, specifier) === undefined) missing.add(specifier);\n }\n }\n return [...missing];\n}\n\nfunction npmSources(specifiers: readonly string[]): string[] {\n return [...new Set(specifiers.map((specifier) => `${NPM_SOURCE_PREFIX}${splitPackageSpecifier(specifier).name}`))];\n}\n\nfunction createPackageManager(repoRoot: string, environment: NodeJS.ProcessEnv): LayerPackageManager {\n const agentDirectory = piAgentDirectory(environment);\n const settingsManager = SettingsManager.create(repoRoot, agentDirectory, { projectTrusted: true });\n return new DefaultPackageManager({ cwd: repoRoot, agentDir: agentDirectory, settingsManager });\n}\n\n/** Installs missing selected layer packages into Pi's project-local `.pi/npm` store and verifies the retry. */\nexport async function ensureLayerPackages(\n options: EnsureLayerPackagesOptions,\n dependencies: LayerPackageInstallerDependencies = {},\n): Promise<string[]> {\n const environment = options.environment ?? process.env;\n const resolvers = dependencies.resolvers ?? createLayerResolvers(options.repoRoot);\n const missing = missingLayerPackageSpecifiers(options.config, options.layers, resolvers);\n if (missing.length === 0) return [];\n\n const sources = npmSources(missing);\n const packageManager = dependencies.packageManager ?? createPackageManager(options.repoRoot, environment);\n try {\n await packageManager.resolveExtensionSources(sources, { local: true });\n } catch (error) {\n throw new Error(`Failed to install missing DoomPi layer package(s): ${sources.join(', ')}`, { cause: error });\n }\n\n const unresolved = missing.filter((specifier) => !resolvePackageEntries(resolvers, specifier)?.length);\n if (unresolved.length > 0) {\n throw new Error(\n `Installed DoomPi layer package(s) did not expose the configured Pi extension: ${unresolved.join(', ')}`,\n );\n }\n return sources;\n}\n"],"mappings":"kOAsBA,SAAS,EAAsB,EAAoC,EAAyC,CAC1G,IAAM,EAAU,EAAU,yBAAyB,CAAS,EAC5D,GAAI,IAAY,IAAA,GAAW,OAAO,EAClC,IAAM,EAAQ,EAAU,qBAAqB,CAAS,EACtD,OAAO,EAAQ,CAAC,CAAK,EAAI,IAAA,EAC3B,CAGA,SAAgB,EACd,EACA,EACA,EACU,CACV,IAAM,EAAU,IAAI,IACd,EAAsB,CAC1B,GAAI,EAAO,QAAU,CAAC,EAAO,OAAO,EAAI,CAAC,EACzC,GAAG,EAAO,IAAK,GAAc,CAC3B,IAAM,EAAQ,EAAO,OAAO,GAC5B,GAAI,CAAC,EAAO,MAAU,MAAM,kBAAkB,GAAW,EACzD,OAAO,CACT,CAAC,CACH,EACA,IAAK,IAAM,KAAS,EAClB,IAAK,IAAM,KAAc,EAAM,UAAY,CAAC,EAAG,CAC7C,IAAM,EAAY,OAAO,GAAe,SAAW,EAAa,EAAW,KAC1D,OAAO,GAAe,UAAY,EAAW,WAAa,KAAA,EAC3DA,EAAAA,wBAAAA,CAAwB,CAAS,GAI7C,EAAsB,EAAW,CAAS,IAAM,IAAA,IAAW,EAAQ,IAAI,CAAS,CACtF,CAEF,MAAO,CAAC,GAAG,CAAO,CACpB,CAEA,SAAS,EAAW,EAAyC,CAC3D,MAAO,CAAC,GAAG,IAAI,IAAI,EAAW,IAAK,GAAc,OAAuBC,EAAAA,sBAAsB,CAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CACnH,CAEA,SAAS,EAAqB,EAAkB,EAAqD,CACnG,IAAM,EAAiBC,EAAAA,iBAAiB,CAAW,EAC7C,EAAkBC,EAAAA,gBAAgB,OAAO,EAAU,EAAgB,CAAE,eAAgB,EAAK,CAAC,EACjG,OAAO,IAAIC,EAAAA,sBAAsB,CAAE,IAAK,EAAU,SAAU,EAAgB,iBAAgB,CAAC,CAC/F,CAGA,eAAsB,EACpB,EACA,EAAkD,CAAC,EAChC,CACnB,IAAM,EAAc,EAAQ,aAAe,QAAQ,IAC7C,EAAY,EAAa,WAAaC,EAAAA,qBAAqB,EAAQ,QAAQ,EAC3E,EAAU,EAA8B,EAAQ,OAAQ,EAAQ,OAAQ,CAAS,EACvF,GAAI,EAAQ,SAAW,EAAG,MAAO,CAAC,EAElC,IAAM,EAAU,EAAW,CAAO,EAC5B,EAAiB,EAAa,gBAAkB,EAAqB,EAAQ,SAAU,CAAW,EACxG,GAAI,CACF,MAAM,EAAe,wBAAwB,EAAS,CAAE,MAAO,EAAK,CAAC,CACvE,OAAS,EAAO,CACd,MAAU,MAAM,sDAAsD,EAAQ,KAAK,IAAI,IAAK,CAAE,MAAO,CAAM,CAAC,CAC9G,CAEA,IAAM,EAAa,EAAQ,OAAQ,GAAc,CAAC,EAAsB,EAAW,CAAS,CAAC,EAAE,MAAM,EACrG,GAAI,EAAW,OAAS,EACtB,MAAU,MACR,iFAAiF,EAAW,KAAK,IAAI,GACvG,EAEF,OAAO,CACT"}
|
|
1
|
+
{"version":3,"file":"layerPackageInstaller.cjs","names":["path","isLocalPackageSpecifier","fs","splitPackageSpecifier","piAgentDirectory","SettingsManager","DefaultPackageManager","createLayerResolvers"],"sources":["../../../src/adapters/layerPackageInstaller.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { isLocalPackageSpecifier, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { DefaultPackageManager, type PackageManager, SettingsManager } from '@earendil-works/pi-coding-agent';\nimport { createLayerResolvers, type ExtensionLayerResolvers } from '../services/extensionAssembler.ts';\nimport { splitPackageSpecifier } from './modules/moduleResolution.ts';\nimport { piAgentDirectory } from './piSettings.ts';\n\nconst NPM_SOURCE_PREFIX = 'npm:';\nconst PI_MANAGED_NPM_DIRECTORY = path.join('.pi', 'npm');\nconst PI_MANAGED_PACKAGE_NAME = 'pi-extensions';\nconst UNPINNED_PACKAGE_RANGE = '*';\n\nfunction overridePackageName(selector: string): string {\n const separatorIndex = selector.indexOf('@', selector.startsWith('@') ? 1 : 0);\n return separatorIndex === -1 ? selector : selector.slice(0, separatorIndex);\n}\n\n/**\n * Same-major patches for transitive versions pinned by the current foundation packages.\n * npm only honors overrides from the install root, so published extensions cannot carry\n * these fixes in their own manifests.\n */\nexport const SAFE_TRANSITIVE_OVERRIDES = {\n '@hono/node-server@2.0.0 - 2.0.9': '^2.0.10',\n '@opentelemetry/core@2.0.0 - 2.7.999': '2.8.0',\n 'brace-expansion@5.0.0 - 5.0.8': '^5.0.9',\n 'hono@4.0.0 - 4.12.33': '^4.12.34',\n 'js-yaml@4.0.0 - 4.3.0': '^4.3.1',\n 'js-yaml@5.0.0 - 5.2.1': '^5.2.2',\n 'liquidjs@10.0.0 - 10.27.0': '^10.27.1',\n 'protobufjs@8.0.0 - 8.7.1': '^8.7.2',\n} as const satisfies Readonly<Record<string, string>>;\n\nconst SAFE_TRANSITIVE_PACKAGE_NAMES = new Set(Object.keys(SAFE_TRANSITIVE_OVERRIDES).map(overridePackageName));\n\ntype LayerPackageManager = Pick<PackageManager, 'install' | 'resolveExtensionSources'>;\n\nexport interface EnsureLayerPackagesOptions {\n repoRoot: string;\n config: MajorModesConfig;\n layers: readonly string[];\n environment?: NodeJS.ProcessEnv;\n}\n\nexport interface LayerPackageInstallerDependencies {\n packageManager?: LayerPackageManager;\n resolvers?: ExtensionLayerResolvers;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> {\n return isRecord(value) ? { ...value } : {};\n}\n\nfunction withoutConflictingTransitiveOverrides(value: unknown): Record<string, unknown> {\n const overrides = recordValue(value);\n for (const [selector, replacement] of Object.entries(overrides)) {\n if (SAFE_TRANSITIVE_PACKAGE_NAMES.has(overridePackageName(selector))) {\n delete overrides[selector];\n } else if (isRecord(replacement)) {\n overrides[selector] = withoutConflictingTransitiveOverrides(replacement);\n }\n }\n return overrides;\n}\n\nfunction managedPackageManifestPath(repoRoot: string): string {\n return path.join(repoRoot, PI_MANAGED_NPM_DIRECTORY, 'package.json');\n}\n\nfunction configuredPackageSpecifiers(config: MajorModesConfig, layers: readonly string[]): string[] {\n const specifiers = new Set<string>();\n const selectedDefinitions = [\n ...(config.default ? [config.default] : []),\n ...layers.map((layerName) => {\n const layer = config.layers[layerName];\n if (!layer) throw new Error(`Unknown layer: ${layerName}`);\n return layer;\n }),\n ];\n for (const layer of selectedDefinitions) {\n for (const configured of layer.packages ?? []) {\n const specifier = typeof configured === 'string' ? configured : configured.name;\n const optional = typeof configured !== 'string' && configured.optional === true;\n if (!optional && !isLocalPackageSpecifier(specifier)) specifiers.add(specifier);\n }\n }\n return [...specifiers];\n}\n\nfunction resolvePackageEntries(resolvers: ExtensionLayerResolvers, specifier: string): string[] | undefined {\n const entries = resolvers.optionalPackageEntries?.(specifier);\n if (entries !== undefined) return entries;\n const entry = resolvers.optionalPackageEntry(specifier);\n return entry ? [entry] : undefined;\n}\n\n/** Adds the complete package set and patched transitive policy to Pi's managed install root. */\nexport function ensureManagedPackageManifest(repoRoot: string, sources: readonly string[]): boolean {\n const manifestPath = managedPackageManifestPath(repoRoot);\n const current = fs.existsSync(manifestPath) ? fs.readFileSync(manifestPath, 'utf8') : undefined;\n let manifest: Record<string, unknown>;\n if (current === undefined) {\n manifest = { name: PI_MANAGED_PACKAGE_NAME, private: true };\n } else {\n const parsed: unknown = JSON.parse(current);\n if (!isRecord(parsed)) throw new Error(`Pi managed package manifest at ${manifestPath} must be a JSON object.`);\n manifest = parsed;\n }\n\n const dependencies = recordValue(manifest.dependencies);\n for (const source of sources) {\n const name = source.slice(NPM_SOURCE_PREFIX.length);\n if (!Object.hasOwn(dependencies, name)) dependencies[name] = UNPINNED_PACKAGE_RANGE;\n }\n manifest.dependencies = dependencies;\n // npm gives nested and overlapping consumer rules precedence in cases that can retain\n // vulnerable versions, so DoomPi owns these package-specific selectors recursively.\n manifest.overrides = {\n ...withoutConflictingTransitiveOverrides(manifest.overrides),\n ...SAFE_TRANSITIVE_OVERRIDES,\n };\n const pnpm = recordValue(manifest.pnpm);\n pnpm.overrides = {\n ...withoutConflictingTransitiveOverrides(pnpm.overrides),\n ...SAFE_TRANSITIVE_OVERRIDES,\n };\n manifest.pnpm = pnpm;\n\n const serialized = `${JSON.stringify(manifest, null, 2)}\\n`;\n if (serialized === current) return false;\n fs.mkdirSync(path.dirname(manifestPath), { recursive: true });\n fs.writeFileSync(manifestPath, serialized, 'utf8');\n return true;\n}\n\n/** Finds required npm packages selected by defaults and active layers that DoomPi cannot resolve. */\nexport function missingLayerPackageSpecifiers(\n config: MajorModesConfig,\n layers: readonly string[],\n resolvers: ExtensionLayerResolvers,\n): string[] {\n return configuredPackageSpecifiers(config, layers).filter(\n (specifier) => resolvePackageEntries(resolvers, specifier) === undefined,\n );\n}\n\nfunction npmSources(specifiers: readonly string[]): string[] {\n return [...new Set(specifiers.map((specifier) => `${NPM_SOURCE_PREFIX}${splitPackageSpecifier(specifier).name}`))];\n}\n\nfunction createPackageManager(repoRoot: string, environment: NodeJS.ProcessEnv): LayerPackageManager {\n const agentDirectory = piAgentDirectory(environment);\n const settingsManager = SettingsManager.create(repoRoot, agentDirectory, { projectTrusted: true });\n return new DefaultPackageManager({ cwd: repoRoot, agentDir: agentDirectory, settingsManager });\n}\n\n/** Installs missing selected layer packages into Pi's project-local `.pi/npm` store and verifies the retry. */\nexport async function ensureLayerPackages(\n options: EnsureLayerPackagesOptions,\n dependencies: LayerPackageInstallerDependencies = {},\n): Promise<string[]> {\n const environment = options.environment ?? process.env;\n const resolvers = dependencies.resolvers ?? createLayerResolvers(options.repoRoot);\n const configured = configuredPackageSpecifiers(options.config, options.layers);\n const missing = configured.filter((specifier) => resolvePackageEntries(resolvers, specifier) === undefined);\n const missingSources = npmSources(missing);\n const sources = npmSources(configured);\n if (sources.length === 0) return [];\n\n const managedDirectory = path.dirname(managedPackageManifestPath(options.repoRoot));\n if (missing.length === 0 && !fs.existsSync(managedDirectory)) return [];\n const manifestChanged = ensureManagedPackageManifest(options.repoRoot, sources);\n if (missing.length === 0 && !manifestChanged) return [];\n\n const packageManager = dependencies.packageManager ?? createPackageManager(options.repoRoot, environment);\n try {\n if (manifestChanged) {\n // Installing one source reconciles the complete dependency set already written\n // to package.json, avoiding one npm install and audit report per DoomPi package.\n await packageManager.install(sources[0]!, { local: true });\n } else {\n await packageManager.resolveExtensionSources(missingSources, { local: true });\n }\n } catch (error) {\n const attempted = manifestChanged ? sources : missingSources;\n throw new Error(`Failed to reconcile DoomPi layer package(s): ${attempted.join(', ')}`, { cause: error });\n }\n\n const unresolved = missing.filter((specifier) => !resolvePackageEntries(resolvers, specifier)?.length);\n if (unresolved.length > 0) {\n throw new Error(\n `Installed DoomPi layer package(s) did not expose the configured Pi extension: ${unresolved.join(', ')}`,\n );\n }\n return missingSources;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{splitPackageSpecifier as e}from"./modules/moduleResolution.mjs";import{createLayerResolvers as t}from"../services/extensionAssembler.mjs";import{piAgentDirectory as n}from"./piSettings.mjs";import{isLocalPackageSpecifier as
|
|
1
|
+
import{splitPackageSpecifier as e}from"./modules/moduleResolution.mjs";import{createLayerResolvers as t}from"../services/extensionAssembler.mjs";import{piAgentDirectory as n}from"./piSettings.mjs";import r from"node:path";import i from"node:fs";import{isLocalPackageSpecifier as a}from"@agimon-ai/doompi-config/majorModes";import{DefaultPackageManager as o,SettingsManager as s}from"@earendil-works/pi-coding-agent";const c=r.join(`.pi`,`npm`);function l(e){let t=e.indexOf(`@`,+!!e.startsWith(`@`));return t===-1?e:e.slice(0,t)}const u={"@hono/node-server@2.0.0 - 2.0.9":`^2.0.10`,"@opentelemetry/core@2.0.0 - 2.7.999":`2.8.0`,"brace-expansion@5.0.0 - 5.0.8":`^5.0.9`,"hono@4.0.0 - 4.12.33":`^4.12.34`,"js-yaml@4.0.0 - 4.3.0":`^4.3.1`,"js-yaml@5.0.0 - 5.2.1":`^5.2.2`,"liquidjs@10.0.0 - 10.27.0":`^10.27.1`,"protobufjs@8.0.0 - 8.7.1":`^8.7.2`},d=new Set(Object.keys(u).map(l));function f(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function p(e){return f(e)?{...e}:{}}function m(e){let t=p(e);for(let[e,n]of Object.entries(t))d.has(l(e))?delete t[e]:f(n)&&(t[e]=m(n));return t}function h(e){return r.join(e,c,`package.json`)}function g(e,t){let n=new Set,r=[...e.default?[e.default]:[],...t.map(t=>{let n=e.layers[t];if(!n)throw Error(`Unknown layer: ${t}`);return n})];for(let e of r)for(let t of e.packages??[]){let e=typeof t==`string`?t:t.name;(typeof t==`string`||t.optional!==!0)&&!a(e)&&n.add(e)}return[...n]}function _(e,t){let n=e.optionalPackageEntries?.(t);if(n!==void 0)return n;let r=e.optionalPackageEntry(t);return r?[r]:void 0}function v(e,t){let n=h(e),a=i.existsSync(n)?i.readFileSync(n,`utf8`):void 0,o;if(a===void 0)o={name:`pi-extensions`,private:!0};else{let e=JSON.parse(a);if(!f(e))throw Error(`Pi managed package manifest at ${n} must be a JSON object.`);o=e}let s=p(o.dependencies);for(let e of t){let t=e.slice(4);Object.hasOwn(s,t)||(s[t]=`*`)}o.dependencies=s,o.overrides={...m(o.overrides),...u};let c=p(o.pnpm);c.overrides={...m(c.overrides),...u},o.pnpm=c;let l=`${JSON.stringify(o,null,2)}\n`;return l!==a&&(i.mkdirSync(r.dirname(n),{recursive:!0}),i.writeFileSync(n,l,`utf8`),!0)}function y(e,t,n){return g(e,t).filter(e=>_(n,e)===void 0)}function b(t){return[...new Set(t.map(t=>`npm:${e(t).name}`))]}function x(e,t){let r=n(t),i=s.create(e,r,{projectTrusted:!0});return new o({cwd:e,agentDir:r,settingsManager:i})}async function S(e,n={}){let a=e.environment??process.env,o=n.resolvers??t(e.repoRoot),s=g(e.config,e.layers),c=s.filter(e=>_(o,e)===void 0),l=b(c),u=b(s);if(u.length===0)return[];let d=r.dirname(h(e.repoRoot));if(c.length===0&&!i.existsSync(d))return[];let f=v(e.repoRoot,u);if(c.length===0&&!f)return[];let p=n.packageManager??x(e.repoRoot,a);try{f?await p.install(u[0],{local:!0}):await p.resolveExtensionSources(l,{local:!0})}catch(e){throw Error(`Failed to reconcile DoomPi layer package(s): ${(f?u:l).join(`, `)}`,{cause:e})}let m=c.filter(e=>!_(o,e)?.length);if(m.length>0)throw Error(`Installed DoomPi layer package(s) did not expose the configured Pi extension: ${m.join(`, `)}`);return l}export{u as SAFE_TRANSITIVE_OVERRIDES,S as ensureLayerPackages,v as ensureManagedPackageManifest,y as missingLayerPackageSpecifiers};
|
|
2
2
|
//# sourceMappingURL=layerPackageInstaller.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerPackageInstaller.mjs","names":[],"sources":["../../../src/adapters/layerPackageInstaller.ts"],"sourcesContent":["import { isLocalPackageSpecifier, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { DefaultPackageManager, type PackageManager, SettingsManager } from '@earendil-works/pi-coding-agent';\nimport { createLayerResolvers, type ExtensionLayerResolvers } from '../services/extensionAssembler.ts';\nimport { splitPackageSpecifier } from './modules/moduleResolution.ts';\nimport { piAgentDirectory } from './piSettings.ts';\n\nconst NPM_SOURCE_PREFIX = 'npm:';\n\ntype LayerPackageManager = Pick<PackageManager, 'resolveExtensionSources'>;\n\nexport interface EnsureLayerPackagesOptions {\n repoRoot: string;\n config: MajorModesConfig;\n layers: readonly string[];\n environment?: NodeJS.ProcessEnv;\n}\n\nexport interface LayerPackageInstallerDependencies {\n packageManager?: LayerPackageManager;\n resolvers?: ExtensionLayerResolvers;\n}\n\nfunction resolvePackageEntries(resolvers: ExtensionLayerResolvers, specifier: string): string[] | undefined {\n const entries = resolvers.optionalPackageEntries?.(specifier);\n if (entries !== undefined) return entries;\n const entry = resolvers.optionalPackageEntry(specifier);\n return entry ? [entry] : undefined;\n}\n\n/** Finds required npm packages selected by defaults and active layers that DoomPi cannot resolve. */\nexport function missingLayerPackageSpecifiers(\n config: MajorModesConfig,\n layers: readonly string[],\n resolvers: ExtensionLayerResolvers,\n): string[] {\n const missing = new Set<string>();\n const selectedDefinitions = [\n ...(config.default ? [config.default] : []),\n ...layers.map((layerName) => {\n const layer = config.layers[layerName];\n if (!layer) throw new Error(`Unknown layer: ${layerName}`);\n return layer;\n }),\n ];\n for (const layer of selectedDefinitions) {\n for (const configured of layer.packages ?? []) {\n const specifier = typeof configured === 'string' ? configured : configured.name;\n const optional = typeof configured !== 'string' && configured.optional === true;\n if (optional || isLocalPackageSpecifier(specifier)) continue;\n // An empty entry list means the package exists but declares no usable Pi\n // extension. Leave that validation to the assembler rather than masking a\n // broken install with another copy from the registry.\n if (resolvePackageEntries(resolvers, specifier) === undefined) missing.add(specifier);\n }\n }\n return [...missing];\n}\n\nfunction npmSources(specifiers: readonly string[]): string[] {\n return [...new Set(specifiers.map((specifier) => `${NPM_SOURCE_PREFIX}${splitPackageSpecifier(specifier).name}`))];\n}\n\nfunction createPackageManager(repoRoot: string, environment: NodeJS.ProcessEnv): LayerPackageManager {\n const agentDirectory = piAgentDirectory(environment);\n const settingsManager = SettingsManager.create(repoRoot, agentDirectory, { projectTrusted: true });\n return new DefaultPackageManager({ cwd: repoRoot, agentDir: agentDirectory, settingsManager });\n}\n\n/** Installs missing selected layer packages into Pi's project-local `.pi/npm` store and verifies the retry. */\nexport async function ensureLayerPackages(\n options: EnsureLayerPackagesOptions,\n dependencies: LayerPackageInstallerDependencies = {},\n): Promise<string[]> {\n const environment = options.environment ?? process.env;\n const resolvers = dependencies.resolvers ?? createLayerResolvers(options.repoRoot);\n const missing = missingLayerPackageSpecifiers(options.config, options.layers, resolvers);\n if (missing.length === 0) return [];\n\n const sources = npmSources(missing);\n const packageManager = dependencies.packageManager ?? createPackageManager(options.repoRoot, environment);\n try {\n await packageManager.resolveExtensionSources(sources, { local: true });\n } catch (error) {\n throw new Error(`Failed to install missing DoomPi layer package(s): ${sources.join(', ')}`, { cause: error });\n }\n\n const unresolved = missing.filter((specifier) => !resolvePackageEntries(resolvers, specifier)?.length);\n if (unresolved.length > 0) {\n throw new Error(\n `Installed DoomPi layer package(s) did not expose the configured Pi extension: ${unresolved.join(', ')}`,\n );\n }\n return sources;\n}\n"],"mappings":"gXAsBA,SAAS,EAAsB,EAAoC,EAAyC,CAC1G,IAAM,EAAU,EAAU,yBAAyB,CAAS,EAC5D,GAAI,IAAY,IAAA,GAAW,OAAO,EAClC,IAAM,EAAQ,EAAU,qBAAqB,CAAS,EACtD,OAAO,EAAQ,CAAC,CAAK,EAAI,IAAA,EAC3B,CAGA,SAAgB,EACd,EACA,EACA,EACU,CACV,IAAM,EAAU,IAAI,IACd,EAAsB,CAC1B,GAAI,EAAO,QAAU,CAAC,EAAO,OAAO,EAAI,CAAC,EACzC,GAAG,EAAO,IAAK,GAAc,CAC3B,IAAM,EAAQ,EAAO,OAAO,GAC5B,GAAI,CAAC,EAAO,MAAU,MAAM,kBAAkB,GAAW,EACzD,OAAO,CACT,CAAC,CACH,EACA,IAAK,IAAM,KAAS,EAClB,IAAK,IAAM,KAAc,EAAM,UAAY,CAAC,EAAG,CAC7C,IAAM,EAAY,OAAO,GAAe,SAAW,EAAa,EAAW,KAC1D,OAAO,GAAe,UAAY,EAAW,WAAa,IAC3D,EAAwB,CAAS,GAI7C,EAAsB,EAAW,CAAS,IAAM,IAAA,IAAW,EAAQ,IAAI,CAAS,CACtF,CAEF,MAAO,CAAC,GAAG,CAAO,CACpB,CAEA,SAAS,EAAW,EAAyC,CAC3D,MAAO,CAAC,GAAG,IAAI,IAAI,EAAW,IAAK,GAAc,OAAuB,EAAsB,CAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CACnH,CAEA,SAAS,EAAqB,EAAkB,EAAqD,CACnG,IAAM,EAAiB,EAAiB,CAAW,EAC7C,EAAkB,EAAgB,OAAO,EAAU,EAAgB,CAAE,eAAgB,EAAK,CAAC,EACjG,OAAO,IAAI,EAAsB,CAAE,IAAK,EAAU,SAAU,EAAgB,iBAAgB,CAAC,CAC/F,CAGA,eAAsB,EACpB,EACA,EAAkD,CAAC,EAChC,CACnB,IAAM,EAAc,EAAQ,aAAe,QAAQ,IAC7C,EAAY,EAAa,WAAa,EAAqB,EAAQ,QAAQ,EAC3E,EAAU,EAA8B,EAAQ,OAAQ,EAAQ,OAAQ,CAAS,EACvF,GAAI,EAAQ,SAAW,EAAG,MAAO,CAAC,EAElC,IAAM,EAAU,EAAW,CAAO,EAC5B,EAAiB,EAAa,gBAAkB,EAAqB,EAAQ,SAAU,CAAW,EACxG,GAAI,CACF,MAAM,EAAe,wBAAwB,EAAS,CAAE,MAAO,EAAK,CAAC,CACvE,OAAS,EAAO,CACd,MAAU,MAAM,sDAAsD,EAAQ,KAAK,IAAI,IAAK,CAAE,MAAO,CAAM,CAAC,CAC9G,CAEA,IAAM,EAAa,EAAQ,OAAQ,GAAc,CAAC,EAAsB,EAAW,CAAS,CAAC,EAAE,MAAM,EACrG,GAAI,EAAW,OAAS,EACtB,MAAU,MACR,iFAAiF,EAAW,KAAK,IAAI,GACvG,EAEF,OAAO,CACT"}
|
|
1
|
+
{"version":3,"file":"layerPackageInstaller.mjs","names":[],"sources":["../../../src/adapters/layerPackageInstaller.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { isLocalPackageSpecifier, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { DefaultPackageManager, type PackageManager, SettingsManager } from '@earendil-works/pi-coding-agent';\nimport { createLayerResolvers, type ExtensionLayerResolvers } from '../services/extensionAssembler.ts';\nimport { splitPackageSpecifier } from './modules/moduleResolution.ts';\nimport { piAgentDirectory } from './piSettings.ts';\n\nconst NPM_SOURCE_PREFIX = 'npm:';\nconst PI_MANAGED_NPM_DIRECTORY = path.join('.pi', 'npm');\nconst PI_MANAGED_PACKAGE_NAME = 'pi-extensions';\nconst UNPINNED_PACKAGE_RANGE = '*';\n\nfunction overridePackageName(selector: string): string {\n const separatorIndex = selector.indexOf('@', selector.startsWith('@') ? 1 : 0);\n return separatorIndex === -1 ? selector : selector.slice(0, separatorIndex);\n}\n\n/**\n * Same-major patches for transitive versions pinned by the current foundation packages.\n * npm only honors overrides from the install root, so published extensions cannot carry\n * these fixes in their own manifests.\n */\nexport const SAFE_TRANSITIVE_OVERRIDES = {\n '@hono/node-server@2.0.0 - 2.0.9': '^2.0.10',\n '@opentelemetry/core@2.0.0 - 2.7.999': '2.8.0',\n 'brace-expansion@5.0.0 - 5.0.8': '^5.0.9',\n 'hono@4.0.0 - 4.12.33': '^4.12.34',\n 'js-yaml@4.0.0 - 4.3.0': '^4.3.1',\n 'js-yaml@5.0.0 - 5.2.1': '^5.2.2',\n 'liquidjs@10.0.0 - 10.27.0': '^10.27.1',\n 'protobufjs@8.0.0 - 8.7.1': '^8.7.2',\n} as const satisfies Readonly<Record<string, string>>;\n\nconst SAFE_TRANSITIVE_PACKAGE_NAMES = new Set(Object.keys(SAFE_TRANSITIVE_OVERRIDES).map(overridePackageName));\n\ntype LayerPackageManager = Pick<PackageManager, 'install' | 'resolveExtensionSources'>;\n\nexport interface EnsureLayerPackagesOptions {\n repoRoot: string;\n config: MajorModesConfig;\n layers: readonly string[];\n environment?: NodeJS.ProcessEnv;\n}\n\nexport interface LayerPackageInstallerDependencies {\n packageManager?: LayerPackageManager;\n resolvers?: ExtensionLayerResolvers;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> {\n return isRecord(value) ? { ...value } : {};\n}\n\nfunction withoutConflictingTransitiveOverrides(value: unknown): Record<string, unknown> {\n const overrides = recordValue(value);\n for (const [selector, replacement] of Object.entries(overrides)) {\n if (SAFE_TRANSITIVE_PACKAGE_NAMES.has(overridePackageName(selector))) {\n delete overrides[selector];\n } else if (isRecord(replacement)) {\n overrides[selector] = withoutConflictingTransitiveOverrides(replacement);\n }\n }\n return overrides;\n}\n\nfunction managedPackageManifestPath(repoRoot: string): string {\n return path.join(repoRoot, PI_MANAGED_NPM_DIRECTORY, 'package.json');\n}\n\nfunction configuredPackageSpecifiers(config: MajorModesConfig, layers: readonly string[]): string[] {\n const specifiers = new Set<string>();\n const selectedDefinitions = [\n ...(config.default ? [config.default] : []),\n ...layers.map((layerName) => {\n const layer = config.layers[layerName];\n if (!layer) throw new Error(`Unknown layer: ${layerName}`);\n return layer;\n }),\n ];\n for (const layer of selectedDefinitions) {\n for (const configured of layer.packages ?? []) {\n const specifier = typeof configured === 'string' ? configured : configured.name;\n const optional = typeof configured !== 'string' && configured.optional === true;\n if (!optional && !isLocalPackageSpecifier(specifier)) specifiers.add(specifier);\n }\n }\n return [...specifiers];\n}\n\nfunction resolvePackageEntries(resolvers: ExtensionLayerResolvers, specifier: string): string[] | undefined {\n const entries = resolvers.optionalPackageEntries?.(specifier);\n if (entries !== undefined) return entries;\n const entry = resolvers.optionalPackageEntry(specifier);\n return entry ? [entry] : undefined;\n}\n\n/** Adds the complete package set and patched transitive policy to Pi's managed install root. */\nexport function ensureManagedPackageManifest(repoRoot: string, sources: readonly string[]): boolean {\n const manifestPath = managedPackageManifestPath(repoRoot);\n const current = fs.existsSync(manifestPath) ? fs.readFileSync(manifestPath, 'utf8') : undefined;\n let manifest: Record<string, unknown>;\n if (current === undefined) {\n manifest = { name: PI_MANAGED_PACKAGE_NAME, private: true };\n } else {\n const parsed: unknown = JSON.parse(current);\n if (!isRecord(parsed)) throw new Error(`Pi managed package manifest at ${manifestPath} must be a JSON object.`);\n manifest = parsed;\n }\n\n const dependencies = recordValue(manifest.dependencies);\n for (const source of sources) {\n const name = source.slice(NPM_SOURCE_PREFIX.length);\n if (!Object.hasOwn(dependencies, name)) dependencies[name] = UNPINNED_PACKAGE_RANGE;\n }\n manifest.dependencies = dependencies;\n // npm gives nested and overlapping consumer rules precedence in cases that can retain\n // vulnerable versions, so DoomPi owns these package-specific selectors recursively.\n manifest.overrides = {\n ...withoutConflictingTransitiveOverrides(manifest.overrides),\n ...SAFE_TRANSITIVE_OVERRIDES,\n };\n const pnpm = recordValue(manifest.pnpm);\n pnpm.overrides = {\n ...withoutConflictingTransitiveOverrides(pnpm.overrides),\n ...SAFE_TRANSITIVE_OVERRIDES,\n };\n manifest.pnpm = pnpm;\n\n const serialized = `${JSON.stringify(manifest, null, 2)}\\n`;\n if (serialized === current) return false;\n fs.mkdirSync(path.dirname(manifestPath), { recursive: true });\n fs.writeFileSync(manifestPath, serialized, 'utf8');\n return true;\n}\n\n/** Finds required npm packages selected by defaults and active layers that DoomPi cannot resolve. */\nexport function missingLayerPackageSpecifiers(\n config: MajorModesConfig,\n layers: readonly string[],\n resolvers: ExtensionLayerResolvers,\n): string[] {\n return configuredPackageSpecifiers(config, layers).filter(\n (specifier) => resolvePackageEntries(resolvers, specifier) === undefined,\n );\n}\n\nfunction npmSources(specifiers: readonly string[]): string[] {\n return [...new Set(specifiers.map((specifier) => `${NPM_SOURCE_PREFIX}${splitPackageSpecifier(specifier).name}`))];\n}\n\nfunction createPackageManager(repoRoot: string, environment: NodeJS.ProcessEnv): LayerPackageManager {\n const agentDirectory = piAgentDirectory(environment);\n const settingsManager = SettingsManager.create(repoRoot, agentDirectory, { projectTrusted: true });\n return new DefaultPackageManager({ cwd: repoRoot, agentDir: agentDirectory, settingsManager });\n}\n\n/** Installs missing selected layer packages into Pi's project-local `.pi/npm` store and verifies the retry. */\nexport async function ensureLayerPackages(\n options: EnsureLayerPackagesOptions,\n dependencies: LayerPackageInstallerDependencies = {},\n): Promise<string[]> {\n const environment = options.environment ?? process.env;\n const resolvers = dependencies.resolvers ?? createLayerResolvers(options.repoRoot);\n const configured = configuredPackageSpecifiers(options.config, options.layers);\n const missing = configured.filter((specifier) => resolvePackageEntries(resolvers, specifier) === undefined);\n const missingSources = npmSources(missing);\n const sources = npmSources(configured);\n if (sources.length === 0) return [];\n\n const managedDirectory = path.dirname(managedPackageManifestPath(options.repoRoot));\n if (missing.length === 0 && !fs.existsSync(managedDirectory)) return [];\n const manifestChanged = ensureManagedPackageManifest(options.repoRoot, sources);\n if (missing.length === 0 && !manifestChanged) return [];\n\n const packageManager = dependencies.packageManager ?? createPackageManager(options.repoRoot, environment);\n try {\n if (manifestChanged) {\n // Installing one source reconciles the complete dependency set already written\n // to package.json, avoiding one npm install and audit report per DoomPi package.\n await packageManager.install(sources[0]!, { local: true });\n } else {\n await packageManager.resolveExtensionSources(missingSources, { local: true });\n }\n } catch (error) {\n const attempted = manifestChanged ? sources : missingSources;\n throw new Error(`Failed to reconcile DoomPi layer package(s): ${attempted.join(', ')}`, { cause: error });\n }\n\n const unresolved = missing.filter((specifier) => !resolvePackageEntries(resolvers, specifier)?.length);\n if (unresolved.length > 0) {\n throw new Error(\n `Installed DoomPi layer package(s) did not expose the configured Pi extension: ${unresolved.join(', ')}`,\n );\n }\n return missingSources;\n}\n"],"mappings":"gaAQA,MACM,EAA2B,EAAK,KAAK,MAAO,KAAK,EAIvD,SAAS,EAAoB,EAA0B,CACrD,IAAM,EAAiB,EAAS,QAAQ,IAAK,KAAS,WAAW,GAAG,CAAS,EAC7E,OAAO,IAAmB,GAAK,EAAW,EAAS,MAAM,EAAG,CAAc,CAC5E,CAOA,MAAa,EAA4B,CACvC,kCAAmC,UACnC,sCAAuC,QACvC,gCAAiC,SACjC,uBAAwB,WACxB,wBAAyB,SACzB,wBAAyB,SACzB,4BAA6B,WAC7B,2BAA4B,QAC9B,EAEM,EAAgC,IAAI,IAAI,OAAO,KAAK,CAAyB,CAAC,CAAC,IAAI,CAAmB,CAAC,EAgB7G,SAAS,EAAS,EAAkD,CAClE,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EAAY,EAAyC,CAC5D,OAAO,EAAS,CAAK,EAAI,CAAE,GAAG,CAAM,EAAI,CAAC,CAC3C,CAEA,SAAS,EAAsC,EAAyC,CACtF,IAAM,EAAY,EAAY,CAAK,EACnC,IAAK,GAAM,CAAC,EAAU,KAAgB,OAAO,QAAQ,CAAS,EACxD,EAA8B,IAAI,EAAoB,CAAQ,CAAC,EACjE,OAAO,EAAU,GACR,EAAS,CAAW,IAC7B,EAAU,GAAY,EAAsC,CAAW,GAG3E,OAAO,CACT,CAEA,SAAS,EAA2B,EAA0B,CAC5D,OAAO,EAAK,KAAK,EAAU,EAA0B,cAAc,CACrE,CAEA,SAAS,EAA4B,EAA0B,EAAqC,CAClG,IAAM,EAAa,IAAI,IACjB,EAAsB,CAC1B,GAAI,EAAO,QAAU,CAAC,EAAO,OAAO,EAAI,CAAC,EACzC,GAAG,EAAO,IAAK,GAAc,CAC3B,IAAM,EAAQ,EAAO,OAAO,GAC5B,GAAI,CAAC,EAAO,MAAU,MAAM,kBAAkB,GAAW,EACzD,OAAO,CACT,CAAC,CACH,EACA,IAAK,IAAM,KAAS,EAClB,IAAK,IAAM,KAAc,EAAM,UAAY,CAAC,EAAG,CAC7C,IAAM,EAAY,OAAO,GAAe,SAAW,EAAa,EAAW,MAC1D,OAAO,GAAe,UAAY,EAAW,WAAa,KAC1D,CAAC,EAAwB,CAAS,GAAG,EAAW,IAAI,CAAS,CAChF,CAEF,MAAO,CAAC,GAAG,CAAU,CACvB,CAEA,SAAS,EAAsB,EAAoC,EAAyC,CAC1G,IAAM,EAAU,EAAU,yBAAyB,CAAS,EAC5D,GAAI,IAAY,IAAA,GAAW,OAAO,EAClC,IAAM,EAAQ,EAAU,qBAAqB,CAAS,EACtD,OAAO,EAAQ,CAAC,CAAK,EAAI,IAAA,EAC3B,CAGA,SAAgB,EAA6B,EAAkB,EAAqC,CAClG,IAAM,EAAe,EAA2B,CAAQ,EAClD,EAAU,EAAG,WAAW,CAAY,EAAI,EAAG,aAAa,EAAc,MAAM,EAAI,IAAA,GAClF,EACJ,GAAI,IAAY,IAAA,GACd,EAAW,CAAE,KAAM,gBAAyB,QAAS,EAAK,MACrD,CACL,IAAM,EAAkB,KAAK,MAAM,CAAO,EAC1C,GAAI,CAAC,EAAS,CAAM,EAAG,MAAU,MAAM,kCAAkC,EAAa,wBAAwB,EAC9G,EAAW,CACb,CAEA,IAAM,EAAe,EAAY,EAAS,YAAY,EACtD,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EAAO,EAAO,MAAM,CAAwB,EAC7C,OAAO,OAAO,EAAc,CAAI,IAAG,EAAa,GAAQ,IAC/D,CACA,EAAS,aAAe,EAGxB,EAAS,UAAY,CACnB,GAAG,EAAsC,EAAS,SAAS,EAC3D,GAAG,CACL,EACA,IAAM,EAAO,EAAY,EAAS,IAAI,EACtC,EAAK,UAAY,CACf,GAAG,EAAsC,EAAK,SAAS,EACvD,GAAG,CACL,EACA,EAAS,KAAO,EAEhB,IAAM,EAAa,GAAG,KAAK,UAAU,EAAU,KAAM,CAAC,EAAE,IAIxD,OAHI,IAAe,IACnB,EAAG,UAAU,EAAK,QAAQ,CAAY,EAAG,CAAE,UAAW,EAAK,CAAC,EAC5D,EAAG,cAAc,EAAc,EAAY,MAAM,EAC1C,GACT,CAGA,SAAgB,EACd,EACA,EACA,EACU,CACV,OAAO,EAA4B,EAAQ,CAAM,CAAC,CAAC,OAChD,GAAc,EAAsB,EAAW,CAAS,IAAM,IAAA,EACjE,CACF,CAEA,SAAS,EAAW,EAAyC,CAC3D,MAAO,CAAC,GAAG,IAAI,IAAI,EAAW,IAAK,GAAc,OAAuB,EAAsB,CAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CACnH,CAEA,SAAS,EAAqB,EAAkB,EAAqD,CACnG,IAAM,EAAiB,EAAiB,CAAW,EAC7C,EAAkB,EAAgB,OAAO,EAAU,EAAgB,CAAE,eAAgB,EAAK,CAAC,EACjG,OAAO,IAAI,EAAsB,CAAE,IAAK,EAAU,SAAU,EAAgB,iBAAgB,CAAC,CAC/F,CAGA,eAAsB,EACpB,EACA,EAAkD,CAAC,EAChC,CACnB,IAAM,EAAc,EAAQ,aAAe,QAAQ,IAC7C,EAAY,EAAa,WAAa,EAAqB,EAAQ,QAAQ,EAC3E,EAAa,EAA4B,EAAQ,OAAQ,EAAQ,MAAM,EACvE,EAAU,EAAW,OAAQ,GAAc,EAAsB,EAAW,CAAS,IAAM,IAAA,EAAS,EACpG,EAAiB,EAAW,CAAO,EACnC,EAAU,EAAW,CAAU,EACrC,GAAI,EAAQ,SAAW,EAAG,MAAO,CAAC,EAElC,IAAM,EAAmB,EAAK,QAAQ,EAA2B,EAAQ,QAAQ,CAAC,EAClF,GAAI,EAAQ,SAAW,GAAK,CAAC,EAAG,WAAW,CAAgB,EAAG,MAAO,CAAC,EACtE,IAAM,EAAkB,EAA6B,EAAQ,SAAU,CAAO,EAC9E,GAAI,EAAQ,SAAW,GAAK,CAAC,EAAiB,MAAO,CAAC,EAEtD,IAAM,EAAiB,EAAa,gBAAkB,EAAqB,EAAQ,SAAU,CAAW,EACxG,GAAI,CACE,EAGF,MAAM,EAAe,QAAQ,EAAQ,GAAK,CAAE,MAAO,EAAK,CAAC,EAEzD,MAAM,EAAe,wBAAwB,EAAgB,CAAE,MAAO,EAAK,CAAC,CAEhF,OAAS,EAAO,CAEd,MAAU,MAAM,iDADE,EAAkB,EAAU,EAAA,CAC4B,KAAK,IAAI,IAAK,CAAE,MAAO,CAAM,CAAC,CAC1G,CAEA,IAAM,EAAa,EAAQ,OAAQ,GAAc,CAAC,EAAsB,EAAW,CAAS,CAAC,EAAE,MAAM,EACrG,GAAI,EAAW,OAAS,EACtB,MAAU,MACR,iFAAiF,EAAW,KAAK,IAAI,GACvG,EAEF,OAAO,CACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.30",
|
|
4
4
|
"description": "Opinionated, composable Pi distribution for scoped agent tools, skills, MCP servers, and developer workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -302,16 +302,16 @@
|
|
|
302
302
|
"rolldown": "1.2.5",
|
|
303
303
|
"typebox": "1.3.16",
|
|
304
304
|
"yaml": "2.9.0",
|
|
305
|
-
"@agimon-ai/doompi-autostop": "0.0.1-alpha.
|
|
306
|
-
"@agimon-ai/doompi-domain": "0.0.1-alpha.
|
|
307
|
-
"@agimon-ai/doompi-
|
|
308
|
-
"@agimon-ai/doompi-
|
|
309
|
-
"@agimon-ai/doompi-
|
|
310
|
-
"@agimon-ai/doompi-
|
|
311
|
-
"@agimon-ai/doompi-
|
|
312
|
-
"@agimon-ai/doompi-
|
|
313
|
-
"@agimon-ai/doompi-
|
|
314
|
-
"@agimon-ai/doompi-
|
|
305
|
+
"@agimon-ai/doompi-autostop": "0.0.1-alpha.8",
|
|
306
|
+
"@agimon-ai/doompi-domain": "0.0.1-alpha.8",
|
|
307
|
+
"@agimon-ai/doompi-config": "0.0.1-alpha.30",
|
|
308
|
+
"@agimon-ai/doompi-major-mode": "0.0.1-alpha.8",
|
|
309
|
+
"@agimon-ai/doompi-notification": "0.0.1-alpha.8",
|
|
310
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.30",
|
|
311
|
+
"@agimon-ai/doompi-profile": "0.0.1-alpha.8",
|
|
312
|
+
"@agimon-ai/doompi-skill": "0.0.1-alpha.8",
|
|
313
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.30",
|
|
314
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.30"
|
|
315
315
|
},
|
|
316
316
|
"devDependencies": {
|
|
317
317
|
"@earendil-works/pi-ai": "0.84.2",
|
|
@@ -321,7 +321,7 @@
|
|
|
321
321
|
"@vitest/coverage-v8": "4.1.11",
|
|
322
322
|
"typescript": "7.0.2",
|
|
323
323
|
"vitest": "4.1.11",
|
|
324
|
-
"@agimon-ai/doompi-runner": "0.0.1-alpha.
|
|
324
|
+
"@agimon-ai/doompi-runner": "0.0.1-alpha.30"
|
|
325
325
|
},
|
|
326
326
|
"peerDependencies": {
|
|
327
327
|
"@earendil-works/pi-tui": "0.84.2"
|