@prompd/core 0.5.0-beta.15 → 0.5.0-beta.18

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/dist/index.d.cts CHANGED
@@ -22,9 +22,11 @@ interface IFileSystem {
22
22
  /**
23
23
  * Extract a `.pdpkg` (ZIP) buffer to a flat map of entry-relative path -> UTF-8
24
24
  * content. The SINGLE ZIP-extraction primitive shared by package ingestion
25
- * (MemoryFileSystem.addPackage) and skill install — so hosts never hand-roll their
26
- * own jszip pass. Directories and binary assets are skipped (the consumers store
27
- * text only).
25
+ * (MemoryFileSystem.addPackage), the installer, and skill install — so hosts never
26
+ * hand-roll their own jszip pass. Directories and binary assets are skipped (the
27
+ * consumers store text only). Enforces the same archive-security checks as the CLI:
28
+ * rejects null bytes, path traversal, symlinks, and oversized / decompression-bomb
29
+ * archives.
28
30
  */
29
31
  declare function extractPdpkg(buffer: Uint8Array): Promise<Map<string, string>>;
30
32
  /**
@@ -670,6 +672,13 @@ declare class MemoryPackageResolver implements IPackageResolver {
670
672
  resolvePackage(packageRef: string, options: ResolvePackageOptions): Promise<string>;
671
673
  }
672
674
 
675
+ /** Deploy an installed skill into a tool-native dir (e.g. ~/.claude/skills). Host-only
676
+ * (Node fs); the browser omits it. Injected so core stays Node-free. */
677
+ type ToolDeployHook = (opts: {
678
+ installedPath: string;
679
+ name: string;
680
+ tool: string;
681
+ }) => void | Promise<void>;
673
682
  /**
674
683
  * A writable sink the host injects so installPackage stays FS-/Node-agnostic.
675
684
  * Browser: an adapter over the workspace FileService; CLI/sidecar: over Node fs.
@@ -677,30 +686,36 @@ declare class MemoryPackageResolver implements IPackageResolver {
677
686
  interface PackageStore {
678
687
  /** Write a UTF-8 file, creating parent directories as needed. */
679
688
  writeFile(path: string, content: string): void | Promise<void>;
680
- /** Remove a directory and its contents if present, for a clean reinstall. */
689
+ /** Write raw bytes — required for node-templates (stored as the raw .pdpkg). */
690
+ writeBytes?(path: string, bytes: Uint8Array): void | Promise<void>;
691
+ /** Remove a directory and its contents if present. */
681
692
  removeDir?(path: string): void | Promise<void>;
682
- /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json
683
- * dependency list. When omitted, dependency tracking is skipped (non-fatal). */
693
+ /** Remove a single file if present (node-template .pdpkg uninstall). */
694
+ removeFile?(path: string): void | Promise<void>;
695
+ /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json. */
684
696
  readFile?(path: string): Promise<string | null> | string | null;
697
+ /** Read raw bytes — used to match a node-template .pdpkg by its manifest on uninstall. */
698
+ readBytes?(path: string): Promise<Uint8Array> | Uint8Array;
699
+ /** List a directory's entry names — used to find a node-template .pdpkg to uninstall. */
700
+ readdir?(path: string): Promise<string[]> | string[];
685
701
  }
686
702
  interface InstallPackageOptions {
687
703
  /** "@scope/name@version" or "@scope/name" (defaults to latest). */
688
704
  ref: string;
689
- /** Artifact type — selects the .prompd subdir (packages/skills/workflows/templates). */
690
- type: PackageType;
691
- /**
692
- * Install root the caller chose: the open workspace folder (browser/local) or the
693
- * home dir for a global install (sidecar/CLI). installPackage NEVER computes '~'
694
- * itself — core stays Node-free.
695
- */
705
+ /** Type HINT. The package's own manifest `type` wins; this is the fallback. */
706
+ type?: PackageType;
707
+ /** Install root: the open workspace (local) or the home dir (global). */
696
708
  root: string;
697
709
  /** Writable sink for the chosen host. */
698
710
  store: PackageStore;
699
- /**
700
- * Fetch the .pdpkg bytes for a (name, version). Injected: the registry client in
701
- * the browser, a Node fetch in the CLI. May resolve 'latest' to a concrete version.
702
- */
711
+ /** Fetch the .pdpkg bytes for a (name, version). May resolve 'latest'. */
703
712
  download: PackageDownloader;
713
+ /** Global install — skips the workspace prompd.json dependency record (CLI parity). */
714
+ global?: boolean;
715
+ /** Deploy the installed skill to these tools (skills only), via deployTool. */
716
+ tools?: string[];
717
+ /** Host hook performing the per-tool deploy. Required when `tools` is set. */
718
+ deployTool?: ToolDeployHook;
704
719
  }
705
720
  interface InstalledPackage {
706
721
  /** Full scoped name (manifest-authoritative when present), e.g. "@prompd/core". */
@@ -708,41 +723,42 @@ interface InstalledPackage {
708
723
  /** Resolved version (from the package manifest when present). */
709
724
  version: string;
710
725
  scope?: string;
711
- /** Install dir written to: <root>/.prompd/<typeDir>/<name>. */
726
+ /** Resolved type (from the package manifest when present). */
727
+ type: PackageType;
728
+ /** Where it was written: the version dir, or the .pdpkg path for node-templates. */
712
729
  installedPath: string;
713
- /** Entry-relative paths written under installedPath. */
730
+ /** Entry-relative paths written (empty for node-templates). */
714
731
  files: string[];
715
732
  }
716
733
  /**
717
- * Install a registry artifact into <root>/.prompd/<typeDir>/<name>/, replacing any
718
- * prior install (idempotent). The host injects the writable `store` and the
719
- * `download` fetcher, so the same install runs in the browser and the CLI/sidecar.
720
- * Returns the resolved name/version (manifest-authoritative when present) and the
721
- * files written. Rejects entries that escape the install directory (zip-slip) and
722
- * archives over the size cap.
734
+ * Install a registry artifact, matching the CLI. Resolves the type from the package's
735
+ * own manifest (the `type` option is only a fallback). Standard types extract to
736
+ * <root>/.prompd/<typeDir>/<name>/<version>/ with a `.prmdmeta`; node-templates are
737
+ * stored as the raw .pdpkg. Installs the package's own dependencies recursively,
738
+ * records the dependency in the workspace prompd.json (local installs only), and
739
+ * deploys to any requested tools. Idempotent per version.
723
740
  */
724
741
  declare function installPackage(opts: InstallPackageOptions): Promise<InstalledPackage>;
725
742
  interface UninstallPackageOptions {
726
- /** "@scope/name" (a version suffix is accepted but ignored — one install per name). */
743
+ /** "@scope/name" (a version suffix is accepted but ignored). */
727
744
  ref: string;
728
- /** Artifact type — selects the .prompd subdir. */
729
- type: PackageType;
730
- /** Install root the caller chose (the open workspace, or '~' for a global install). */
745
+ /** Install root the caller chose. */
731
746
  root: string;
732
- /** Writable sink for the chosen host; removeDir is required to uninstall. */
747
+ /** Writable sink for the chosen host. */
733
748
  store: PackageStore;
749
+ /** Global uninstall — skips the workspace prompd.json dependency removal. */
750
+ global?: boolean;
734
751
  }
735
752
  interface UninstalledPackage {
736
753
  name: string;
737
754
  scope?: string;
738
- /** The directory that was removed: <root>/.prompd/<typeDir>/<name>. */
739
- installedPath: string;
755
+ /** Dirs/files removed. */
756
+ removed: string[];
740
757
  }
741
758
  /**
742
- * Uninstall an artifact: remove <root>/.prompd/<typeDir>/<name>/ via the injected
743
- * store. The symmetric inverse of installPackage, sharing the same install-dir
744
- * computation. Idempotent — removing an absent install is a no-op (the host's
745
- * removeDir should swallow not-found). Throws if the store can't remove directories.
759
+ * Uninstall by name, matching the CLI: scan EVERY type dir under <root>/.prompd/ and
760
+ * remove the package's dir (all versions); for node-templates, find the .pdpkg whose
761
+ * manifest name matches and remove it. Drops the prompd.json dependency. Idempotent.
746
762
  */
747
763
  declare function uninstallPackage(opts: UninstallPackageOptions): Promise<UninstalledPackage>;
748
764
 
@@ -3039,4 +3055,4 @@ declare function validateWorkflow(workflow: WorkflowFile): ValidationResult;
3039
3055
  */
3040
3056
  declare function validateWorkflowQuick(workflow: WorkflowFile): Pick<ValidationResult, 'isValid'>;
3041
3057
 
3042
- export { type AgentCheckpointEvent, type AgentCheckpointEventType, type AgentIterationRecord, type AgentNodeData, type AgentTool, AnthropicFormatter, type ApiNodeData, type AsyncFileBackend, BUILTIN_COMMAND_EXECUTABLES, type BaseNodeData, CODE_EXTENSIONS, CONTENT_TYPES, type CallbackNodeData, type ChatAgentCheckpointConfig, type ChatAgentNodeData, type ClaudeCodeNodeData, CodeGenerationStage, type CodeNodeData, type CommandNodeData, CompilationContext, type CompilationDiagnostic, CompilationError, type CompilationOptions, CompilationStage, type CompiledPrompt, CompilerPipeline, type CompilerStage, type CompleteEventData, type ConditionBranch, type ConditionNodeData, type Config, type CustomCommandConfig, type CustomConnectionConfig, type CustomProvider, DEFAULT_SECURITY_CONFIG, DOCKABLE_HANDLES, DOCKABLE_NODE_TYPES, type DatabaseConnectionConfig, type DatabaseQueryNodeData, DependencyResolutionStage, EXTENSION_TO_LANGUAGE, EXTENSION_TO_LANGUAGE_ALIASES, type ErrorEventData, type ErrorHandlerNodeData, type ErrorHandlingConfig, type ExecuteOptions, type ExecutionConfig, type GitHubConnectionConfig, type GuardrailNodeData, type HttpApiConnectionConfig, HybridFileSystem, type IFileSystem, type IPackageResolver, type InstallPackageOptions, type InstalledPackage, type IterationEventData, type JsonSchema, type LLMResponse, LexicalAnalysisStage, type LoopNodeData, MEMORY_OPERATIONS_BY_MODE, MarkdownFormatter, type McpServerConnectionConfig, type McpToolNodeData, MemoryFileSystem, type MemoryNodeData, type MemoryOperation, MemoryPackageResolver, type MergeNodeData, type NodeExecutionState, type NodeExecutionStatus, OpenAIFormatter, type OutputFormatter, type OutputNodeData, PACKAGE_TYPE_DIRS, PROMPD_EXTENSIONS, type PackageAlias, type PackageDownloader, type PackageStore, type PackageType, type ParallelBranch, type ParallelNodeData, ParseError, type ParsedWorkflow, PrompdCompiler, PrompdError, type PrompdFile, PrompdLoader, type PrompdMetadata, type PrompdParameter, PrompdParser, type PromptNodeData, type ProviderConfig, type ProviderNodeData, type RegistryConfig, type ResolvePackageOptions, type ResolvedPackage, type RetryPolicy, type SSHConnectionConfig, type SectionInfo, SectionOverrideProcessor, type SecurityConfig, SecurityError, SemanticAnalysisStage, type SlackConnectionConfig, TOOL_DEPLOY_DIRS, TemplateProcessingStage, type ThinkingEventData, type ToolCallEventData, type ToolCallParserNodeData, type ToolCallRouterNodeData, type ToolNodeData, type TransformerNodeData, type TriggerNodeData, type UninstallPackageOptions, type UninstalledPackage, type UserInputNodeData, type UsingPackage, VALID_PACKAGE_TYPES, ValidationError, type ValidationIssue, type ValidationResult, type WebSearchNodeData, type WebSocketConnectionConfig, type WorkflowConnection, type WorkflowConnectionConfig, type WorkflowConnectionStatus, type WorkflowConnectionType, type WorkflowEdge, type WorkflowExecutionError, type WorkflowExecutionState, type WorkflowExecutionStatus, type WorkflowFile, type WorkflowMetadata, type WorkflowNode, type WorkflowNodeData, type WorkflowNodeType, type WorkflowParameter, type WorkflowResult, type WorkflowValidationError, type WorkflowValidationWarning, type WorkflowVariable, basenamePosix, compile, createCoreStages, createEmptyWorkflow, createPrompdEnvironment, createWorkflowNode, dirnamePosix, extname, extractPdpkg, getContentType, getExecutionOrder, getInstallDirForType, getLanguageAliasesForExtension, getLanguageForExtension, installPackage, isAbsolutePosix, isPrompdFile, isValidPackageReference, isValidPackageType, joinPosix, needsFrontmatterProtection, normalizePosix, parsePackageReference, parsePackageReferenceWithPath, parseWorkflow, resolvePackageFile, resolvePosix, serializeWorkflow, stripFilePath, uninstallPackage, validateWorkflow, validateWorkflowQuick };
3058
+ export { type AgentCheckpointEvent, type AgentCheckpointEventType, type AgentIterationRecord, type AgentNodeData, type AgentTool, AnthropicFormatter, type ApiNodeData, type AsyncFileBackend, BUILTIN_COMMAND_EXECUTABLES, type BaseNodeData, CODE_EXTENSIONS, CONTENT_TYPES, type CallbackNodeData, type ChatAgentCheckpointConfig, type ChatAgentNodeData, type ClaudeCodeNodeData, CodeGenerationStage, type CodeNodeData, type CommandNodeData, CompilationContext, type CompilationDiagnostic, CompilationError, type CompilationOptions, CompilationStage, type CompiledPrompt, CompilerPipeline, type CompilerStage, type CompleteEventData, type ConditionBranch, type ConditionNodeData, type Config, type CustomCommandConfig, type CustomConnectionConfig, type CustomProvider, DEFAULT_SECURITY_CONFIG, DOCKABLE_HANDLES, DOCKABLE_NODE_TYPES, type DatabaseConnectionConfig, type DatabaseQueryNodeData, DependencyResolutionStage, EXTENSION_TO_LANGUAGE, EXTENSION_TO_LANGUAGE_ALIASES, type ErrorEventData, type ErrorHandlerNodeData, type ErrorHandlingConfig, type ExecuteOptions, type ExecutionConfig, type GitHubConnectionConfig, type GuardrailNodeData, type HttpApiConnectionConfig, HybridFileSystem, type IFileSystem, type IPackageResolver, type InstallPackageOptions, type InstalledPackage, type IterationEventData, type JsonSchema, type LLMResponse, LexicalAnalysisStage, type LoopNodeData, MEMORY_OPERATIONS_BY_MODE, MarkdownFormatter, type McpServerConnectionConfig, type McpToolNodeData, MemoryFileSystem, type MemoryNodeData, type MemoryOperation, MemoryPackageResolver, type MergeNodeData, type NodeExecutionState, type NodeExecutionStatus, OpenAIFormatter, type OutputFormatter, type OutputNodeData, PACKAGE_TYPE_DIRS, PROMPD_EXTENSIONS, type PackageAlias, type PackageDownloader, type PackageStore, type PackageType, type ParallelBranch, type ParallelNodeData, ParseError, type ParsedWorkflow, PrompdCompiler, PrompdError, type PrompdFile, PrompdLoader, type PrompdMetadata, type PrompdParameter, PrompdParser, type PromptNodeData, type ProviderConfig, type ProviderNodeData, type RegistryConfig, type ResolvePackageOptions, type ResolvedPackage, type RetryPolicy, type SSHConnectionConfig, type SectionInfo, SectionOverrideProcessor, type SecurityConfig, SecurityError, SemanticAnalysisStage, type SlackConnectionConfig, TOOL_DEPLOY_DIRS, TemplateProcessingStage, type ThinkingEventData, type ToolCallEventData, type ToolCallParserNodeData, type ToolCallRouterNodeData, type ToolDeployHook, type ToolNodeData, type TransformerNodeData, type TriggerNodeData, type UninstallPackageOptions, type UninstalledPackage, type UserInputNodeData, type UsingPackage, VALID_PACKAGE_TYPES, ValidationError, type ValidationIssue, type ValidationResult, type WebSearchNodeData, type WebSocketConnectionConfig, type WorkflowConnection, type WorkflowConnectionConfig, type WorkflowConnectionStatus, type WorkflowConnectionType, type WorkflowEdge, type WorkflowExecutionError, type WorkflowExecutionState, type WorkflowExecutionStatus, type WorkflowFile, type WorkflowMetadata, type WorkflowNode, type WorkflowNodeData, type WorkflowNodeType, type WorkflowParameter, type WorkflowResult, type WorkflowValidationError, type WorkflowValidationWarning, type WorkflowVariable, basenamePosix, compile, createCoreStages, createEmptyWorkflow, createPrompdEnvironment, createWorkflowNode, dirnamePosix, extname, extractPdpkg, getContentType, getExecutionOrder, getInstallDirForType, getLanguageAliasesForExtension, getLanguageForExtension, installPackage, isAbsolutePosix, isPrompdFile, isValidPackageReference, isValidPackageType, joinPosix, needsFrontmatterProtection, normalizePosix, parsePackageReference, parsePackageReferenceWithPath, parseWorkflow, resolvePackageFile, resolvePosix, serializeWorkflow, stripFilePath, uninstallPackage, validateWorkflow, validateWorkflowQuick };
package/dist/index.d.ts CHANGED
@@ -22,9 +22,11 @@ interface IFileSystem {
22
22
  /**
23
23
  * Extract a `.pdpkg` (ZIP) buffer to a flat map of entry-relative path -> UTF-8
24
24
  * content. The SINGLE ZIP-extraction primitive shared by package ingestion
25
- * (MemoryFileSystem.addPackage) and skill install — so hosts never hand-roll their
26
- * own jszip pass. Directories and binary assets are skipped (the consumers store
27
- * text only).
25
+ * (MemoryFileSystem.addPackage), the installer, and skill install — so hosts never
26
+ * hand-roll their own jszip pass. Directories and binary assets are skipped (the
27
+ * consumers store text only). Enforces the same archive-security checks as the CLI:
28
+ * rejects null bytes, path traversal, symlinks, and oversized / decompression-bomb
29
+ * archives.
28
30
  */
29
31
  declare function extractPdpkg(buffer: Uint8Array): Promise<Map<string, string>>;
30
32
  /**
@@ -670,6 +672,13 @@ declare class MemoryPackageResolver implements IPackageResolver {
670
672
  resolvePackage(packageRef: string, options: ResolvePackageOptions): Promise<string>;
671
673
  }
672
674
 
675
+ /** Deploy an installed skill into a tool-native dir (e.g. ~/.claude/skills). Host-only
676
+ * (Node fs); the browser omits it. Injected so core stays Node-free. */
677
+ type ToolDeployHook = (opts: {
678
+ installedPath: string;
679
+ name: string;
680
+ tool: string;
681
+ }) => void | Promise<void>;
673
682
  /**
674
683
  * A writable sink the host injects so installPackage stays FS-/Node-agnostic.
675
684
  * Browser: an adapter over the workspace FileService; CLI/sidecar: over Node fs.
@@ -677,30 +686,36 @@ declare class MemoryPackageResolver implements IPackageResolver {
677
686
  interface PackageStore {
678
687
  /** Write a UTF-8 file, creating parent directories as needed. */
679
688
  writeFile(path: string, content: string): void | Promise<void>;
680
- /** Remove a directory and its contents if present, for a clean reinstall. */
689
+ /** Write raw bytes — required for node-templates (stored as the raw .pdpkg). */
690
+ writeBytes?(path: string, bytes: Uint8Array): void | Promise<void>;
691
+ /** Remove a directory and its contents if present. */
681
692
  removeDir?(path: string): void | Promise<void>;
682
- /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json
683
- * dependency list. When omitted, dependency tracking is skipped (non-fatal). */
693
+ /** Remove a single file if present (node-template .pdpkg uninstall). */
694
+ removeFile?(path: string): void | Promise<void>;
695
+ /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json. */
684
696
  readFile?(path: string): Promise<string | null> | string | null;
697
+ /** Read raw bytes — used to match a node-template .pdpkg by its manifest on uninstall. */
698
+ readBytes?(path: string): Promise<Uint8Array> | Uint8Array;
699
+ /** List a directory's entry names — used to find a node-template .pdpkg to uninstall. */
700
+ readdir?(path: string): Promise<string[]> | string[];
685
701
  }
686
702
  interface InstallPackageOptions {
687
703
  /** "@scope/name@version" or "@scope/name" (defaults to latest). */
688
704
  ref: string;
689
- /** Artifact type — selects the .prompd subdir (packages/skills/workflows/templates). */
690
- type: PackageType;
691
- /**
692
- * Install root the caller chose: the open workspace folder (browser/local) or the
693
- * home dir for a global install (sidecar/CLI). installPackage NEVER computes '~'
694
- * itself — core stays Node-free.
695
- */
705
+ /** Type HINT. The package's own manifest `type` wins; this is the fallback. */
706
+ type?: PackageType;
707
+ /** Install root: the open workspace (local) or the home dir (global). */
696
708
  root: string;
697
709
  /** Writable sink for the chosen host. */
698
710
  store: PackageStore;
699
- /**
700
- * Fetch the .pdpkg bytes for a (name, version). Injected: the registry client in
701
- * the browser, a Node fetch in the CLI. May resolve 'latest' to a concrete version.
702
- */
711
+ /** Fetch the .pdpkg bytes for a (name, version). May resolve 'latest'. */
703
712
  download: PackageDownloader;
713
+ /** Global install — skips the workspace prompd.json dependency record (CLI parity). */
714
+ global?: boolean;
715
+ /** Deploy the installed skill to these tools (skills only), via deployTool. */
716
+ tools?: string[];
717
+ /** Host hook performing the per-tool deploy. Required when `tools` is set. */
718
+ deployTool?: ToolDeployHook;
704
719
  }
705
720
  interface InstalledPackage {
706
721
  /** Full scoped name (manifest-authoritative when present), e.g. "@prompd/core". */
@@ -708,41 +723,42 @@ interface InstalledPackage {
708
723
  /** Resolved version (from the package manifest when present). */
709
724
  version: string;
710
725
  scope?: string;
711
- /** Install dir written to: <root>/.prompd/<typeDir>/<name>. */
726
+ /** Resolved type (from the package manifest when present). */
727
+ type: PackageType;
728
+ /** Where it was written: the version dir, or the .pdpkg path for node-templates. */
712
729
  installedPath: string;
713
- /** Entry-relative paths written under installedPath. */
730
+ /** Entry-relative paths written (empty for node-templates). */
714
731
  files: string[];
715
732
  }
716
733
  /**
717
- * Install a registry artifact into <root>/.prompd/<typeDir>/<name>/, replacing any
718
- * prior install (idempotent). The host injects the writable `store` and the
719
- * `download` fetcher, so the same install runs in the browser and the CLI/sidecar.
720
- * Returns the resolved name/version (manifest-authoritative when present) and the
721
- * files written. Rejects entries that escape the install directory (zip-slip) and
722
- * archives over the size cap.
734
+ * Install a registry artifact, matching the CLI. Resolves the type from the package's
735
+ * own manifest (the `type` option is only a fallback). Standard types extract to
736
+ * <root>/.prompd/<typeDir>/<name>/<version>/ with a `.prmdmeta`; node-templates are
737
+ * stored as the raw .pdpkg. Installs the package's own dependencies recursively,
738
+ * records the dependency in the workspace prompd.json (local installs only), and
739
+ * deploys to any requested tools. Idempotent per version.
723
740
  */
724
741
  declare function installPackage(opts: InstallPackageOptions): Promise<InstalledPackage>;
725
742
  interface UninstallPackageOptions {
726
- /** "@scope/name" (a version suffix is accepted but ignored — one install per name). */
743
+ /** "@scope/name" (a version suffix is accepted but ignored). */
727
744
  ref: string;
728
- /** Artifact type — selects the .prompd subdir. */
729
- type: PackageType;
730
- /** Install root the caller chose (the open workspace, or '~' for a global install). */
745
+ /** Install root the caller chose. */
731
746
  root: string;
732
- /** Writable sink for the chosen host; removeDir is required to uninstall. */
747
+ /** Writable sink for the chosen host. */
733
748
  store: PackageStore;
749
+ /** Global uninstall — skips the workspace prompd.json dependency removal. */
750
+ global?: boolean;
734
751
  }
735
752
  interface UninstalledPackage {
736
753
  name: string;
737
754
  scope?: string;
738
- /** The directory that was removed: <root>/.prompd/<typeDir>/<name>. */
739
- installedPath: string;
755
+ /** Dirs/files removed. */
756
+ removed: string[];
740
757
  }
741
758
  /**
742
- * Uninstall an artifact: remove <root>/.prompd/<typeDir>/<name>/ via the injected
743
- * store. The symmetric inverse of installPackage, sharing the same install-dir
744
- * computation. Idempotent — removing an absent install is a no-op (the host's
745
- * removeDir should swallow not-found). Throws if the store can't remove directories.
759
+ * Uninstall by name, matching the CLI: scan EVERY type dir under <root>/.prompd/ and
760
+ * remove the package's dir (all versions); for node-templates, find the .pdpkg whose
761
+ * manifest name matches and remove it. Drops the prompd.json dependency. Idempotent.
746
762
  */
747
763
  declare function uninstallPackage(opts: UninstallPackageOptions): Promise<UninstalledPackage>;
748
764
 
@@ -3039,4 +3055,4 @@ declare function validateWorkflow(workflow: WorkflowFile): ValidationResult;
3039
3055
  */
3040
3056
  declare function validateWorkflowQuick(workflow: WorkflowFile): Pick<ValidationResult, 'isValid'>;
3041
3057
 
3042
- export { type AgentCheckpointEvent, type AgentCheckpointEventType, type AgentIterationRecord, type AgentNodeData, type AgentTool, AnthropicFormatter, type ApiNodeData, type AsyncFileBackend, BUILTIN_COMMAND_EXECUTABLES, type BaseNodeData, CODE_EXTENSIONS, CONTENT_TYPES, type CallbackNodeData, type ChatAgentCheckpointConfig, type ChatAgentNodeData, type ClaudeCodeNodeData, CodeGenerationStage, type CodeNodeData, type CommandNodeData, CompilationContext, type CompilationDiagnostic, CompilationError, type CompilationOptions, CompilationStage, type CompiledPrompt, CompilerPipeline, type CompilerStage, type CompleteEventData, type ConditionBranch, type ConditionNodeData, type Config, type CustomCommandConfig, type CustomConnectionConfig, type CustomProvider, DEFAULT_SECURITY_CONFIG, DOCKABLE_HANDLES, DOCKABLE_NODE_TYPES, type DatabaseConnectionConfig, type DatabaseQueryNodeData, DependencyResolutionStage, EXTENSION_TO_LANGUAGE, EXTENSION_TO_LANGUAGE_ALIASES, type ErrorEventData, type ErrorHandlerNodeData, type ErrorHandlingConfig, type ExecuteOptions, type ExecutionConfig, type GitHubConnectionConfig, type GuardrailNodeData, type HttpApiConnectionConfig, HybridFileSystem, type IFileSystem, type IPackageResolver, type InstallPackageOptions, type InstalledPackage, type IterationEventData, type JsonSchema, type LLMResponse, LexicalAnalysisStage, type LoopNodeData, MEMORY_OPERATIONS_BY_MODE, MarkdownFormatter, type McpServerConnectionConfig, type McpToolNodeData, MemoryFileSystem, type MemoryNodeData, type MemoryOperation, MemoryPackageResolver, type MergeNodeData, type NodeExecutionState, type NodeExecutionStatus, OpenAIFormatter, type OutputFormatter, type OutputNodeData, PACKAGE_TYPE_DIRS, PROMPD_EXTENSIONS, type PackageAlias, type PackageDownloader, type PackageStore, type PackageType, type ParallelBranch, type ParallelNodeData, ParseError, type ParsedWorkflow, PrompdCompiler, PrompdError, type PrompdFile, PrompdLoader, type PrompdMetadata, type PrompdParameter, PrompdParser, type PromptNodeData, type ProviderConfig, type ProviderNodeData, type RegistryConfig, type ResolvePackageOptions, type ResolvedPackage, type RetryPolicy, type SSHConnectionConfig, type SectionInfo, SectionOverrideProcessor, type SecurityConfig, SecurityError, SemanticAnalysisStage, type SlackConnectionConfig, TOOL_DEPLOY_DIRS, TemplateProcessingStage, type ThinkingEventData, type ToolCallEventData, type ToolCallParserNodeData, type ToolCallRouterNodeData, type ToolNodeData, type TransformerNodeData, type TriggerNodeData, type UninstallPackageOptions, type UninstalledPackage, type UserInputNodeData, type UsingPackage, VALID_PACKAGE_TYPES, ValidationError, type ValidationIssue, type ValidationResult, type WebSearchNodeData, type WebSocketConnectionConfig, type WorkflowConnection, type WorkflowConnectionConfig, type WorkflowConnectionStatus, type WorkflowConnectionType, type WorkflowEdge, type WorkflowExecutionError, type WorkflowExecutionState, type WorkflowExecutionStatus, type WorkflowFile, type WorkflowMetadata, type WorkflowNode, type WorkflowNodeData, type WorkflowNodeType, type WorkflowParameter, type WorkflowResult, type WorkflowValidationError, type WorkflowValidationWarning, type WorkflowVariable, basenamePosix, compile, createCoreStages, createEmptyWorkflow, createPrompdEnvironment, createWorkflowNode, dirnamePosix, extname, extractPdpkg, getContentType, getExecutionOrder, getInstallDirForType, getLanguageAliasesForExtension, getLanguageForExtension, installPackage, isAbsolutePosix, isPrompdFile, isValidPackageReference, isValidPackageType, joinPosix, needsFrontmatterProtection, normalizePosix, parsePackageReference, parsePackageReferenceWithPath, parseWorkflow, resolvePackageFile, resolvePosix, serializeWorkflow, stripFilePath, uninstallPackage, validateWorkflow, validateWorkflowQuick };
3058
+ export { type AgentCheckpointEvent, type AgentCheckpointEventType, type AgentIterationRecord, type AgentNodeData, type AgentTool, AnthropicFormatter, type ApiNodeData, type AsyncFileBackend, BUILTIN_COMMAND_EXECUTABLES, type BaseNodeData, CODE_EXTENSIONS, CONTENT_TYPES, type CallbackNodeData, type ChatAgentCheckpointConfig, type ChatAgentNodeData, type ClaudeCodeNodeData, CodeGenerationStage, type CodeNodeData, type CommandNodeData, CompilationContext, type CompilationDiagnostic, CompilationError, type CompilationOptions, CompilationStage, type CompiledPrompt, CompilerPipeline, type CompilerStage, type CompleteEventData, type ConditionBranch, type ConditionNodeData, type Config, type CustomCommandConfig, type CustomConnectionConfig, type CustomProvider, DEFAULT_SECURITY_CONFIG, DOCKABLE_HANDLES, DOCKABLE_NODE_TYPES, type DatabaseConnectionConfig, type DatabaseQueryNodeData, DependencyResolutionStage, EXTENSION_TO_LANGUAGE, EXTENSION_TO_LANGUAGE_ALIASES, type ErrorEventData, type ErrorHandlerNodeData, type ErrorHandlingConfig, type ExecuteOptions, type ExecutionConfig, type GitHubConnectionConfig, type GuardrailNodeData, type HttpApiConnectionConfig, HybridFileSystem, type IFileSystem, type IPackageResolver, type InstallPackageOptions, type InstalledPackage, type IterationEventData, type JsonSchema, type LLMResponse, LexicalAnalysisStage, type LoopNodeData, MEMORY_OPERATIONS_BY_MODE, MarkdownFormatter, type McpServerConnectionConfig, type McpToolNodeData, MemoryFileSystem, type MemoryNodeData, type MemoryOperation, MemoryPackageResolver, type MergeNodeData, type NodeExecutionState, type NodeExecutionStatus, OpenAIFormatter, type OutputFormatter, type OutputNodeData, PACKAGE_TYPE_DIRS, PROMPD_EXTENSIONS, type PackageAlias, type PackageDownloader, type PackageStore, type PackageType, type ParallelBranch, type ParallelNodeData, ParseError, type ParsedWorkflow, PrompdCompiler, PrompdError, type PrompdFile, PrompdLoader, type PrompdMetadata, type PrompdParameter, PrompdParser, type PromptNodeData, type ProviderConfig, type ProviderNodeData, type RegistryConfig, type ResolvePackageOptions, type ResolvedPackage, type RetryPolicy, type SSHConnectionConfig, type SectionInfo, SectionOverrideProcessor, type SecurityConfig, SecurityError, SemanticAnalysisStage, type SlackConnectionConfig, TOOL_DEPLOY_DIRS, TemplateProcessingStage, type ThinkingEventData, type ToolCallEventData, type ToolCallParserNodeData, type ToolCallRouterNodeData, type ToolDeployHook, type ToolNodeData, type TransformerNodeData, type TriggerNodeData, type UninstallPackageOptions, type UninstalledPackage, type UserInputNodeData, type UsingPackage, VALID_PACKAGE_TYPES, ValidationError, type ValidationIssue, type ValidationResult, type WebSearchNodeData, type WebSocketConnectionConfig, type WorkflowConnection, type WorkflowConnectionConfig, type WorkflowConnectionStatus, type WorkflowConnectionType, type WorkflowEdge, type WorkflowExecutionError, type WorkflowExecutionState, type WorkflowExecutionStatus, type WorkflowFile, type WorkflowMetadata, type WorkflowNode, type WorkflowNodeData, type WorkflowNodeType, type WorkflowParameter, type WorkflowResult, type WorkflowValidationError, type WorkflowValidationWarning, type WorkflowVariable, basenamePosix, compile, createCoreStages, createEmptyWorkflow, createPrompdEnvironment, createWorkflowNode, dirnamePosix, extname, extractPdpkg, getContentType, getExecutionOrder, getInstallDirForType, getLanguageAliasesForExtension, getLanguageForExtension, installPackage, isAbsolutePosix, isPrompdFile, isValidPackageReference, isValidPackageType, joinPosix, needsFrontmatterProtection, normalizePosix, parsePackageReference, parsePackageReferenceWithPath, parseWorkflow, resolvePackageFile, resolvePosix, serializeWorkflow, stripFilePath, uninstallPackage, validateWorkflow, validateWorkflowQuick };
package/dist/index.js CHANGED
@@ -3109,12 +3109,36 @@ function isBinaryAsset(name) {
3109
3109
  const dot = name.lastIndexOf(".");
3110
3110
  return dot >= 0 && BINARY_ASSET_EXT.has(name.slice(dot + 1).toLowerCase());
3111
3111
  }
3112
+ var MAX_FILE_SIZE_IN_ZIP = 10 * 1024 * 1024;
3113
+ var MAX_TOTAL_EXTRACTED_SIZE = 500 * 1024 * 1024;
3114
+ function isSymlinkEntry(perms) {
3115
+ return typeof perms === "number" && (perms & 61440) === 40960;
3116
+ }
3117
+ var pdpkgDecoder = new TextDecoder();
3112
3118
  async function extractPdpkg(buffer) {
3113
3119
  const zip = await JSZip.loadAsync(buffer);
3114
3120
  const out = /* @__PURE__ */ new Map();
3121
+ let total = 0;
3115
3122
  for (const entry of Object.values(zip.files)) {
3123
+ if (entry.name.includes("\0")) {
3124
+ throw new Error(`Security violation: null byte in entry name: ${entry.name}`);
3125
+ }
3126
+ if (entry.name.startsWith("/") || /(^|\/)\.\.(\/|$)/.test(entry.name)) {
3127
+ throw new Error(`Security violation: path traversal in entry: ${entry.name}`);
3128
+ }
3129
+ if (isSymlinkEntry(entry.unixPermissions)) {
3130
+ throw new Error(`Security violation: symlink entry in archive: ${entry.name}`);
3131
+ }
3116
3132
  if (entry.dir || isBinaryAsset(entry.name)) continue;
3117
- out.set(entry.name, await entry.async("string"));
3133
+ const bytes = await entry.async("uint8array");
3134
+ if (bytes.length > MAX_FILE_SIZE_IN_ZIP) {
3135
+ throw new Error(`File too large in package: ${entry.name} (${bytes.length} bytes, max ${MAX_FILE_SIZE_IN_ZIP})`);
3136
+ }
3137
+ total += bytes.length;
3138
+ if (total > MAX_TOTAL_EXTRACTED_SIZE) {
3139
+ throw new Error(`Package total decompressed size exceeds limit (${MAX_TOTAL_EXTRACTED_SIZE} bytes). Possible decompression bomb.`);
3140
+ }
3141
+ out.set(entry.name, pdpkgDecoder.decode(bytes));
3118
3142
  }
3119
3143
  return out;
3120
3144
  }
@@ -3341,28 +3365,18 @@ var HybridFileSystem = class {
3341
3365
 
3342
3366
  // src/lib/compiler/install.ts
3343
3367
  var MAX_PACKAGE_SIZE = 50 * 1024 * 1024;
3344
- function joinPosix3(...parts) {
3345
- const joined = parts.filter((p) => p && p !== ".").join("/").replace(/\/{2,}/g, "/");
3346
- return joined.replace(/\/+$/, "") || "/";
3368
+ function slugify(name) {
3369
+ return name.toLowerCase().replace(/[@/]+/g, "-").replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
3347
3370
  }
3348
- function normalizeSegments(p) {
3349
- const out = [];
3350
- for (const seg of p.split("/")) {
3351
- if (!seg || seg === ".") continue;
3352
- if (seg === "..") {
3353
- out.pop();
3354
- continue;
3355
- }
3356
- out.push(seg);
3357
- }
3358
- return out.join("/");
3371
+ function resolvePackageDir(root, type, name) {
3372
+ return joinPosix(root, ".prompd", getInstallDirForType(type), name);
3359
3373
  }
3360
- function resolveInstallDir(root, type, name) {
3361
- return joinPosix3(root, ".prompd", getInstallDirForType(type), name);
3374
+ function resolveInstallDir(root, type, name, version) {
3375
+ return joinPosix(resolvePackageDir(root, type, name), version);
3362
3376
  }
3363
3377
  async function addWorkspaceDependency(store, root, name, version) {
3364
3378
  if (!store.readFile) return;
3365
- const manifestPath = joinPosix3(root, "prompd.json");
3379
+ const manifestPath = joinPosix(root, "prompd.json");
3366
3380
  try {
3367
3381
  const existing = await store.readFile(manifestPath);
3368
3382
  const manifest = existing && existing.trim() ? JSON.parse(existing) : {};
@@ -3374,7 +3388,7 @@ async function addWorkspaceDependency(store, root, name, version) {
3374
3388
  }
3375
3389
  async function removeWorkspaceDependency(store, root, name) {
3376
3390
  if (!store.readFile) return;
3377
- const manifestPath = joinPosix3(root, "prompd.json");
3391
+ const manifestPath = joinPosix(root, "prompd.json");
3378
3392
  try {
3379
3393
  const existing = await store.readFile(manifestPath);
3380
3394
  if (!existing || !existing.trim()) return;
@@ -3386,8 +3400,20 @@ async function removeWorkspaceDependency(store, root, name) {
3386
3400
  } catch {
3387
3401
  }
3388
3402
  }
3403
+ function readManifest(files) {
3404
+ const raw = files.get("manifest.json") ?? files.get("prompd.json");
3405
+ if (!raw) return {};
3406
+ try {
3407
+ return JSON.parse(raw);
3408
+ } catch {
3409
+ return {};
3410
+ }
3411
+ }
3389
3412
  async function installPackage(opts) {
3390
- const { ref, type, root, store, download } = opts;
3413
+ return installInternal(opts, /* @__PURE__ */ new Set());
3414
+ }
3415
+ async function installInternal(opts, visited) {
3416
+ const { ref, root, store, download, global, tools, deployTool } = opts;
3391
3417
  const parsed = parsePackageReference(ref);
3392
3418
  const bytes = await download(parsed.name, parsed.version);
3393
3419
  if (bytes.length > MAX_PACKAGE_SIZE) {
@@ -3397,43 +3423,81 @@ async function installPackage(opts) {
3397
3423
  if (files.size === 0) {
3398
3424
  throw new Error(`Package "${parsed.name}" contains no installable files.`);
3399
3425
  }
3400
- let name = parsed.name;
3401
- let version = parsed.version;
3402
- const manifest = files.get("manifest.json") ?? files.get("prompd.json");
3403
- if (manifest) {
3404
- try {
3405
- const m = JSON.parse(manifest);
3406
- if (typeof m.name === "string" && m.name) name = m.name;
3407
- if (typeof m.version === "string" && m.version) version = m.version;
3408
- } catch {
3426
+ const m = readManifest(files);
3427
+ const name = typeof m.name === "string" && m.name ? m.name : parsed.name;
3428
+ const version = typeof m.version === "string" && m.version ? m.version : parsed.version;
3429
+ const type = typeof m.type === "string" && isValidPackageType(m.type) ? m.type : opts.type && isValidPackageType(opts.type) ? opts.type : "package";
3430
+ visited.add(name);
3431
+ if (m.dependencies && typeof m.dependencies === "object") {
3432
+ for (const [depName, depVersion] of Object.entries(m.dependencies)) {
3433
+ if (depName === name || visited.has(depName)) continue;
3434
+ await installInternal({ ...opts, ref: `${depName}@${depVersion}`, type: void 0 }, visited);
3409
3435
  }
3410
3436
  }
3411
- const installedPath = resolveInstallDir(root, type, name);
3412
- const baseSegments = normalizeSegments(installedPath);
3413
- await store.removeDir?.(installedPath);
3437
+ let installedPath;
3414
3438
  const written = [];
3415
- for (const [rel, content] of files) {
3416
- const dest = joinPosix3(installedPath, rel);
3417
- const destSegments = normalizeSegments(dest);
3418
- if (destSegments !== baseSegments && !destSegments.startsWith(baseSegments + "/")) {
3419
- throw new Error(`Security violation: extracted path escapes install directory: ${rel}`);
3439
+ if (type === "node-template") {
3440
+ if (!store.writeBytes) {
3441
+ throw new Error("Installing a node-template requires a PackageStore with writeBytes (binary). This host does not support it.");
3442
+ }
3443
+ const dir = joinPosix(root, ".prompd", getInstallDirForType("node-template"));
3444
+ installedPath = joinPosix(dir, `${slugify(name)}-${version}.pdpkg`);
3445
+ await store.writeBytes(installedPath, bytes);
3446
+ } else {
3447
+ installedPath = resolveInstallDir(root, type, name, version);
3448
+ const base = normalizePosix(installedPath);
3449
+ await store.removeDir?.(installedPath);
3450
+ for (const [rel, content] of files) {
3451
+ const dest = joinPosix(installedPath, rel);
3452
+ if (dest !== base && !dest.startsWith(base + "/")) {
3453
+ throw new Error(`Security violation: extracted path escapes install directory: ${rel}`);
3454
+ }
3455
+ await store.writeFile(dest, content);
3456
+ written.push(rel);
3457
+ }
3458
+ await store.writeFile(joinPosix(installedPath, ".prmdmeta"), JSON.stringify(m, null, 2) + "\n");
3459
+ if (tools && tools.length > 0) {
3460
+ if (type !== "skill") throw new Error(`Tool deploy is only valid for skills, but '${name}' is a ${type}.`);
3461
+ if (!deployTool) throw new Error("tools were requested but no deployTool hook was provided.");
3462
+ for (const tool of tools) await deployTool({ installedPath, name, tool });
3420
3463
  }
3421
- await store.writeFile(dest, content);
3422
- written.push(rel);
3423
3464
  }
3424
- await addWorkspaceDependency(store, root, name, version);
3425
- return { name, version, scope: parsed.scope, installedPath, files: written };
3465
+ if (!global) await addWorkspaceDependency(store, root, name, version);
3466
+ return { name, version, scope: parsed.scope, type, installedPath, files: written };
3426
3467
  }
3427
3468
  async function uninstallPackage(opts) {
3428
- const { ref, type, root, store } = opts;
3429
- if (!store.removeDir) {
3430
- throw new Error("Uninstall requires a PackageStore with removeDir.");
3469
+ const { root, store, global } = opts;
3470
+ if (!store.removeDir) throw new Error("Uninstall requires a PackageStore with removeDir.");
3471
+ const parsed = parsePackageReference(opts.ref);
3472
+ const name = parsed.name;
3473
+ const removed = [];
3474
+ for (const type of ["package", "workflow", "skill", "node-template"]) {
3475
+ if (type === "node-template") {
3476
+ const dir = joinPosix(root, ".prompd", getInstallDirForType("node-template"));
3477
+ if (!store.readdir || !store.removeFile || !store.readBytes) continue;
3478
+ try {
3479
+ for (const entry of await store.readdir(dir)) {
3480
+ if (!entry.endsWith(".pdpkg")) continue;
3481
+ const p = joinPosix(dir, entry);
3482
+ try {
3483
+ const m = readManifest(await extractPdpkg(await store.readBytes(p)));
3484
+ if (m.name === name) {
3485
+ await store.removeFile(p);
3486
+ removed.push(p);
3487
+ }
3488
+ } catch {
3489
+ }
3490
+ }
3491
+ } catch {
3492
+ }
3493
+ } else {
3494
+ const dir = resolvePackageDir(root, type, name);
3495
+ await store.removeDir(dir);
3496
+ removed.push(dir);
3497
+ }
3431
3498
  }
3432
- const parsed = parsePackageReference(ref);
3433
- const installedPath = resolveInstallDir(root, type, parsed.name);
3434
- await store.removeDir(installedPath);
3435
- await removeWorkspaceDependency(store, root, parsed.name);
3436
- return { name: parsed.name, scope: parsed.scope, installedPath };
3499
+ if (!global) await removeWorkspaceDependency(store, root, name);
3500
+ return { name, scope: parsed.scope, removed };
3437
3501
  }
3438
3502
 
3439
3503
  // src/lib/compiler/index.ts