opkg 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/package.json +3 -1
  2. package/packages/cli/dist/add-U44SL3OR.js +624 -0
  3. package/packages/cli/dist/add-U44SL3OR.js.map +7 -0
  4. package/packages/cli/dist/chunk-4B5HJLP2.js +48 -0
  5. package/packages/cli/dist/chunk-4B5HJLP2.js.map +7 -0
  6. package/packages/cli/dist/chunk-BROJ6OUT.js +631 -0
  7. package/packages/cli/dist/chunk-BROJ6OUT.js.map +7 -0
  8. package/packages/cli/dist/chunk-CVA64SXK.js +1136 -0
  9. package/packages/cli/dist/chunk-CVA64SXK.js.map +7 -0
  10. package/packages/cli/dist/chunk-D6LEPODL.js +413 -0
  11. package/packages/cli/dist/chunk-D6LEPODL.js.map +7 -0
  12. package/packages/cli/dist/chunk-HTYHJA3B.js +61 -0
  13. package/packages/cli/dist/chunk-HTYHJA3B.js.map +7 -0
  14. package/packages/cli/dist/chunk-KI7FDU3H.js +99 -0
  15. package/packages/cli/dist/chunk-KI7FDU3H.js.map +7 -0
  16. package/packages/cli/dist/chunk-PSQXKAL4.js +371 -0
  17. package/packages/cli/dist/chunk-PSQXKAL4.js.map +7 -0
  18. package/packages/cli/dist/chunk-PUDRKDVZ.js +1419 -0
  19. package/packages/cli/dist/chunk-PUDRKDVZ.js.map +7 -0
  20. package/packages/cli/dist/chunk-U7FW7SXX.js +568 -0
  21. package/packages/cli/dist/chunk-U7FW7SXX.js.map +7 -0
  22. package/packages/cli/dist/configure-3AZUMDJZ.js +107 -0
  23. package/packages/cli/dist/configure-3AZUMDJZ.js.map +7 -0
  24. package/packages/cli/dist/index.js +15 -15
  25. package/packages/cli/dist/install-EZNWMLJR.js +7581 -0
  26. package/packages/cli/dist/install-EZNWMLJR.js.map +7 -0
  27. package/packages/cli/dist/list-XR7RSJFS.js +327 -0
  28. package/packages/cli/dist/list-XR7RSJFS.js.map +7 -0
  29. package/packages/cli/dist/login-NRKHXZKM.js +150 -0
  30. package/packages/cli/dist/login-NRKHXZKM.js.map +7 -0
  31. package/packages/cli/dist/logout-SYHXCVCQ.js +40 -0
  32. package/packages/cli/dist/logout-SYHXCVCQ.js.map +7 -0
  33. package/packages/cli/dist/new-F46OSD72.js +277 -0
  34. package/packages/cli/dist/new-F46OSD72.js.map +7 -0
  35. package/packages/cli/dist/publish-4H43PCSG.js +619 -0
  36. package/packages/cli/dist/publish-4H43PCSG.js.map +7 -0
  37. package/packages/cli/dist/remove-BD52BHR2.js +542 -0
  38. package/packages/cli/dist/remove-BD52BHR2.js.map +7 -0
  39. package/packages/cli/dist/save-N3QWF2WN.js +1728 -0
  40. package/packages/cli/dist/save-N3QWF2WN.js.map +7 -0
  41. package/packages/cli/dist/search-ABROK3UO.js +157 -0
  42. package/packages/cli/dist/search-ABROK3UO.js.map +7 -0
  43. package/packages/cli/dist/set-NGM2FIKF.js +251 -0
  44. package/packages/cli/dist/set-NGM2FIKF.js.map +7 -0
  45. package/packages/cli/dist/uninstall-Q3CP4UN5.js +539 -0
  46. package/packages/cli/dist/uninstall-Q3CP4UN5.js.map +7 -0
  47. package/packages/cli/dist/unpublish-VBTNTMS5.js +245 -0
  48. package/packages/cli/dist/unpublish-VBTNTMS5.js.map +7 -0
  49. package/packages/cli/dist/view-MXRBMXOG.js +488 -0
  50. package/packages/cli/dist/view-MXRBMXOG.js.map +7 -0
  51. package/packages/cli/package.json +2 -0
  52. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts +5 -4
  53. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts.map +1 -1
  54. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js +6 -5
  55. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js.map +1 -1
  56. package/packages/core/dist/core/install/install-reporting.js +1 -1
  57. package/packages/core/dist/core/install/install-reporting.js.map +1 -1
  58. package/packages/core/dist/core/install/list-handler.d.ts.map +1 -1
  59. package/packages/core/dist/core/install/list-handler.js +7 -0
  60. package/packages/core/dist/core/install/list-handler.js.map +1 -1
  61. package/packages/core/dist/core/install/marketplace-handler.d.ts.map +1 -1
  62. package/packages/core/dist/core/install/marketplace-handler.js.map +1 -1
  63. package/packages/core/dist/core/install/operations/conflict-handler.d.ts +2 -1
  64. package/packages/core/dist/core/install/operations/conflict-handler.d.ts.map +1 -1
  65. package/packages/core/dist/core/install/operations/conflict-handler.js +2 -2
  66. package/packages/core/dist/core/install/operations/conflict-handler.js.map +1 -1
  67. package/packages/core/dist/core/install/orchestrator/orchestrator.d.ts.map +1 -1
  68. package/packages/core/dist/core/install/orchestrator/orchestrator.js +22 -14
  69. package/packages/core/dist/core/install/orchestrator/orchestrator.js.map +1 -1
  70. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts +1 -0
  71. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts.map +1 -1
  72. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js +11 -24
  73. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js.map +1 -1
  74. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts +2 -0
  75. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts.map +1 -1
  76. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js +14 -14
  77. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js.map +1 -1
  78. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts +7 -0
  79. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts.map +1 -1
  80. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js +28 -0
  81. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js.map +1 -1
  82. package/packages/core/dist/core/install/platform-resolution.d.ts +3 -0
  83. package/packages/core/dist/core/install/platform-resolution.d.ts.map +1 -1
  84. package/packages/core/dist/core/install/platform-resolution.js +5 -2
  85. package/packages/core/dist/core/install/platform-resolution.js.map +1 -1
  86. package/packages/core/dist/core/install/preprocessing/context-population.d.ts +18 -0
  87. package/packages/core/dist/core/install/preprocessing/context-population.d.ts.map +1 -0
  88. package/packages/core/dist/core/install/preprocessing/context-population.js +36 -0
  89. package/packages/core/dist/core/install/preprocessing/context-population.js.map +1 -0
  90. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts +23 -0
  91. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts.map +1 -1
  92. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js +44 -0
  93. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js.map +1 -1
  94. package/packages/core/dist/core/install/sources/path-source.d.ts.map +1 -1
  95. package/packages/core/dist/core/install/sources/path-source.js +8 -0
  96. package/packages/core/dist/core/install/sources/path-source.js.map +1 -1
  97. package/packages/core/dist/core/install/unified/context-builders.d.ts +5 -0
  98. package/packages/core/dist/core/install/unified/context-builders.d.ts.map +1 -1
  99. package/packages/core/dist/core/install/unified/context-builders.js +13 -0
  100. package/packages/core/dist/core/install/unified/context-builders.js.map +1 -1
  101. package/packages/core/dist/core/install/unified/context-helpers.d.ts.map +1 -1
  102. package/packages/core/dist/core/install/unified/context-helpers.js +5 -0
  103. package/packages/core/dist/core/install/unified/context-helpers.js.map +1 -1
  104. package/packages/core/dist/core/install/unified/context.d.ts +6 -0
  105. package/packages/core/dist/core/install/unified/context.d.ts.map +1 -1
  106. package/packages/core/dist/core/install/unified/multi-context-pipeline.d.ts.map +1 -1
  107. package/packages/core/dist/core/install/unified/multi-context-pipeline.js +0 -2
  108. package/packages/core/dist/core/install/unified/multi-context-pipeline.js.map +1 -1
  109. package/packages/core/dist/core/install/unified/phases/conflicts.d.ts.map +1 -1
  110. package/packages/core/dist/core/install/unified/phases/conflicts.js +1 -1
  111. package/packages/core/dist/core/install/unified/phases/conflicts.js.map +1 -1
  112. package/packages/core/dist/core/install/unified/phases/execute.d.ts.map +1 -1
  113. package/packages/core/dist/core/install/unified/phases/execute.js +2 -1
  114. package/packages/core/dist/core/install/unified/phases/execute.js.map +1 -1
  115. package/packages/core/dist/core/install/unified/phases/report.js +1 -1
  116. package/packages/core/dist/core/install/unified/phases/report.js.map +1 -1
  117. package/packages/core/dist/core/install/unified/pipeline.d.ts.map +1 -1
  118. package/packages/core/dist/core/install/unified/pipeline.js +5 -2
  119. package/packages/core/dist/core/install/unified/pipeline.js.map +1 -1
  120. package/packages/core/dist/core/ports/resolve.d.ts +0 -13
  121. package/packages/core/dist/core/ports/resolve.d.ts.map +1 -1
  122. package/packages/core/dist/core/ports/resolve.js +0 -28
  123. package/packages/core/dist/core/ports/resolve.js.map +1 -1
  124. package/packages/core/dist/core/remove/removal-confirmation.d.ts +4 -1
  125. package/packages/core/dist/core/remove/removal-confirmation.d.ts.map +1 -1
  126. package/packages/core/dist/core/remove/removal-confirmation.js +5 -4
  127. package/packages/core/dist/core/remove/removal-confirmation.js.map +1 -1
  128. package/packages/core/dist/core/remove/remove-from-source-pipeline.d.ts.map +1 -1
  129. package/packages/core/dist/core/remove/remove-from-source-pipeline.js +1 -10
  130. package/packages/core/dist/core/remove/remove-from-source-pipeline.js.map +1 -1
  131. package/packages/core/dist/core/uninstall/uninstall-executor.js +1 -1
  132. package/packages/core/dist/core/uninstall/uninstall-executor.js.map +1 -1
  133. package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts +2 -2
  134. package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts.map +1 -1
  135. package/packages/core/dist/core/uninstall/uninstall-reporter.js +4 -4
  136. package/packages/core/dist/core/uninstall/uninstall-reporter.js.map +1 -1
  137. package/packages/core/dist/index.d.ts +1 -1
  138. package/packages/core/dist/index.d.ts.map +1 -1
  139. package/packages/core/dist/types/execution-context.d.ts +24 -10
  140. package/packages/core/dist/types/execution-context.d.ts.map +1 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/src/core/list/view-metadata.ts", "../../core/src/core/list/list-printers.ts", "../../core/src/core/resources/resource-namespace.ts", "../../core/src/core/list/list-pipeline.ts", "../../core/src/utils/entity-detector.ts"],
4
+ "sourcesContent": ["/**\n * Metadata extraction for view command output.\n * Separated to avoid circular dependencies between list-printers and remote-list-resolver.\n */\n\nimport type { PackageYml, PackageRepository } from '../../types/index.js';\n\nexport interface ViewMetadataEntry {\n key: string;\n value: string | boolean | string[];\n}\n\n/** Extract recognized manifest metadata for display (excludes dependencies) */\nexport function extractMetadataFromManifest(manifest: Partial<PackageYml>): ViewMetadataEntry[] {\n const entries: ViewMetadataEntry[] = [];\n const push = (key: string, value: unknown) => {\n if (value !== undefined && value !== null && value !== '') {\n entries.push({ key, value: value as string | boolean | string[] });\n }\n };\n push('name', manifest.name);\n push('version', manifest.version);\n push('description', manifest.description);\n push('keywords', manifest.keywords);\n push('author', manifest.author);\n push('license', manifest.license);\n push('homepage', manifest.homepage);\n if (manifest.repository) {\n const repo = manifest.repository as PackageRepository;\n const repoStr = repo.directory ? `${repo.url} (${repo.directory})` : repo.url;\n push('repository', repoStr);\n }\n if (manifest.private === true) push('private', true);\n if (manifest.partial === true) push('partial', true);\n return entries;\n}\n", "import type { ListPackageReport, ListTreeNode } from './list-pipeline.js';\nimport { flattenResourceGroups, renderFlatResourceList, getChildPrefix, type TreeRenderConfig, type EnhancedFileMapping, type EnhancedResourceGroup, type ResourceScope } from './list-tree-renderer.js';\nimport { formatScopeBadge } from '../../utils/formatters.js';\nimport type { ScopeResult, HeaderInfo } from './scope-data-collector.js';\nimport type { ViewMetadataEntry } from './view-metadata.js';\nimport type { OutputPort } from '../ports/output.js';\nimport { resolveOutput } from '../ports/resolve.js';\n\nexport type { ViewMetadataEntry } from './view-metadata.js';\nexport { extractMetadataFromManifest } from './view-metadata.js';\n\nexport function printMetadataSection(metadata: ViewMetadataEntry[], output?: OutputPort): void {\n const out = output ?? resolveOutput();\n out.info(sectionHeader('Metadata', metadata.length));\n metadata.forEach((entry) => {\n const valueStr = Array.isArray(entry.value)\n ? entry.value.join(', ')\n : String(entry.value);\n out.info(`${dim(entry.key + ':')} ${valueStr}`);\n });\n}\n\n// ---------------------------------------------------------------------------\n// ANSI helpers\n// ---------------------------------------------------------------------------\n\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst RED = '\\x1b[31m';\nconst CYAN = '\\x1b[36m';\n\nexport function dim(text: string): string {\n return `${DIM}${text}${RESET}`;\n}\n\nexport function cyan(text: string): string {\n return `${CYAN}${text}${RESET}`;\n}\n\nfunction red(text: string): string {\n return `${RED}${text}${RESET}`;\n}\n\nexport function sectionHeader(title: string, count: number): string {\n return `${cyan(`[${title}]`)} ${dim(`(${count})`)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPackageLine(pkg: ListPackageReport): string {\n const version = pkg.version && pkg.version !== '0.0.0' ? `@${pkg.version}` : '';\n\n let stateSuffix = '';\n if (pkg.state === 'missing') {\n stateSuffix = dim(' (missing)');\n }\n\n return `${pkg.name}${version}${stateSuffix}`;\n}\n\nfunction formatFilePath(file: EnhancedFileMapping): string {\n if (file.scope === 'global' && !file.target.startsWith('~')) {\n return `~/${file.target}`;\n }\n return file.target;\n}\n\n// ---------------------------------------------------------------------------\n// File and resource group printing\n// ---------------------------------------------------------------------------\n\nfunction printFileList(\n files: { source: string; target: string; exists: boolean }[],\n prefix: string,\n out: OutputPort\n): void {\n const sortedFiles = [...files].sort((a, b) => a.target.localeCompare(b.target));\n\n for (let i = 0; i < sortedFiles.length; i++) {\n const file = sortedFiles[i];\n const isLast = i === sortedFiles.length - 1;\n const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n const label = file.exists\n ? dim(file.target)\n : `${dim(file.target)} ${red('[MISSING]')}`;\n out.info(`${prefix}${connector}${label}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Deps view\n// ---------------------------------------------------------------------------\n\ninterface DepsPackageEntry {\n report: ListPackageReport;\n children: ListTreeNode[];\n scopes: Set<ResourceScope>;\n}\n\nfunction printDepTreeNode(\n node: ListTreeNode,\n prefix: string,\n isLast: boolean,\n showFiles: boolean,\n out: OutputPort\n): void {\n const hasChildren = node.children.length > 0;\n const hasFiles = showFiles && node.report.fileList && node.report.fileList.length > 0;\n const hasBranches = hasChildren || hasFiles;\n\n const connector = isLast\n ? (hasBranches ? '\u2514\u2500\u252C ' : '\u2514\u2500\u2500 ')\n : (hasBranches ? '\u251C\u2500\u252C ' : '\u251C\u2500\u2500 ');\n const childPrefix = getChildPrefix(prefix, isLast);\n\n out.info(`${prefix}${connector}${formatPackageLine(node.report)}`);\n\n if (hasFiles) {\n printFileList(node.report.fileList!, childPrefix, out);\n }\n\n node.children.forEach((child, index) => {\n const isLastChild = index === node.children.length - 1;\n printDepTreeNode(child, childPrefix, isLastChild, showFiles, out);\n });\n}\n\nexport function printDepsView(\n results: Array<{ scope: ResourceScope; result: ScopeResult }>,\n showFiles: boolean,\n headerInfo?: HeaderInfo,\n output?: OutputPort\n): void {\n const out = output ?? resolveOutput();\n const packageMap = new Map<string, DepsPackageEntry>();\n\n for (const { scope, result } of results) {\n for (const node of result.tree) {\n const key = node.report.name;\n if (packageMap.has(key)) {\n packageMap.get(key)!.scopes.add(scope);\n } else {\n packageMap.set(key, {\n report: node.report,\n children: node.children,\n scopes: new Set([scope])\n });\n }\n }\n }\n\n if (packageMap.size === 0) {\n out.info(dim('No packages installed.'));\n return;\n }\n\n // Option 1: When workspace is the header, exclude it from the tree to avoid duplication.\n // Its files are shown under the header when -f is used.\n let workspaceEntry: DepsPackageEntry | undefined;\n if (headerInfo?.type === 'workspace' && headerInfo.name) {\n workspaceEntry = packageMap.get(headerInfo.name);\n if (workspaceEntry) {\n packageMap.delete(headerInfo.name);\n }\n }\n\n // Print header showing workspace/package name and path\n if (headerInfo) {\n const version = headerInfo.version ? `@${headerInfo.version}` : '';\n const typeTag = dim(`[${headerInfo.type}]`);\n out.info(`${headerInfo.name}${version} ${dim(`(${headerInfo.path})`)} ${typeTag}`);\n } else if (results.length > 0) {\n const firstResult = results[0].result;\n const version = firstResult.headerVersion ? `@${firstResult.headerVersion}` : '';\n const typeTag = dim(`[${firstResult.headerType}]`);\n out.info(`${firstResult.headerName}${version} ${dim(`(${firstResult.headerPath})`)} ${typeTag}`);\n }\n\n const entries = Array.from(packageMap.values())\n .sort((a, b) => a.report.name.localeCompare(b.report.name));\n\n out.info(sectionHeader('Dependencies', entries.length));\n\n // If workspace was excluded, show its files under the header when -f is used.\n // Use empty prefix so workspace files appear as siblings of dep entries.\n if (workspaceEntry && showFiles && workspaceEntry.report.fileList && workspaceEntry.report.fileList.length > 0) {\n printFileList(workspaceEntry.report.fileList, '', out);\n }\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n const isLast = i === entries.length - 1;\n const hasChildren = entry.children.length > 0;\n const hasFiles = showFiles && entry.report.fileList && entry.report.fileList.length > 0;\n const hasBranches = hasChildren || hasFiles;\n\n const scopeBadge = dim(formatScopeBadge(entry.scopes));\n const connector = isLast\n ? (hasBranches ? '\u2514\u2500\u252C ' : '\u2514\u2500\u2500 ')\n : (hasBranches ? '\u251C\u2500\u252C ' : '\u251C\u2500\u2500 ');\n const childPrefix = getChildPrefix('', isLast);\n\n out.info(`${connector}${formatPackageLine(entry.report)} ${scopeBadge}`);\n\n // Show flat file list for the package when -f is requested\n if (hasFiles) {\n printFileList(entry.report.fileList!, childPrefix, out);\n }\n\n for (let ci = 0; ci < entry.children.length; ci++) {\n const child = entry.children[ci];\n const isLastChild = ci === entry.children.length - 1;\n printDepTreeNode(child, childPrefix, isLastChild, showFiles, out);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resources view (default)\n// ---------------------------------------------------------------------------\n\nexport function printResourcesView(\n groups: EnhancedResourceGroup[],\n showFiles: boolean,\n headerInfo?: HeaderInfo,\n output?: OutputPort\n): void {\n const out = output ?? resolveOutput();\n // Print header showing workspace/package name and path if provided\n if (headerInfo) {\n const version = headerInfo.version ? `@${headerInfo.version}` : '';\n const typeTag = dim(`[${headerInfo.type}]`);\n out.info(`${headerInfo.name}${version} ${dim(`(${headerInfo.path})`)} ${typeTag}`);\n }\n\n // Show package label only when listing workspace (not a specific package).\n // Temporarily disabled behind feature flag; set OPKG_LIST_SHOW_PACKAGE_LABELS=true to enable.\n const showPackageLabels =\n headerInfo?.type !== 'package' &&\n process.env.OPKG_LIST_SHOW_PACKAGE_LABELS === 'true';\n\n const config: TreeRenderConfig<EnhancedFileMapping> = {\n formatPath: (file) => formatFilePath(file),\n isMissing: (file) => file.status === 'missing',\n sortFiles: (a, b) => formatFilePath(a).localeCompare(formatFilePath(b)),\n getResourceBadge: (scopes) => scopes ? dim(formatScopeBadge(scopes)) : '',\n ...(showPackageLabels && {\n getResourcePackageLabels: (packages) => {\n if (!packages || packages.size === 0) return [];\n return Array.from(packages)\n .sort()\n .map((pkg) => dim(`(${pkg})`));\n }\n })\n };\n\n const flatResources = flattenResourceGroups(groups);\n out.info(sectionHeader('Installed', flatResources.length));\n renderFlatResourceList(flatResources, '', showFiles, config);\n}\n", "/**\n * Resource Namespace Module\n *\n * Single source of truth for deriving category/namespace from paths.\n * Used by list pipeline, scope merger, and future consumers.\n */\n\nimport { stripExtension } from './resource-naming.js';\nimport { getResourceTypeDef, toPluralKey, type ResourceTypeId } from './resource-registry.js';\nimport { stripPlatformSuffixFromFilename } from '../flows/platform-suffix-handler.js';\n\n/**\n * Extract the path segment under a category directory from a full path.\n * Handles both source keys (rules/foo.mdc) and workspace paths (.cursor/rules/foo.mdc).\n *\n * @param path - Normalized path (source key, target, or workspace path)\n * @param categoryDir - The category directory (e.g., 'rules', 'agents')\n * @returns Path under category, or null if category not found\n */\nexport function getPathUnderCategory(path: string, categoryDir: string): string | null {\n const normalized = path.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const parts = normalized.split('/');\n\n const idx = parts.indexOf(categoryDir);\n if (idx < 0) return null;\n\n const remaining = parts.slice(idx + 1);\n return remaining.length > 0 ? remaining.join('/') : '';\n}\n\n/**\n * Derive the namespace (path under category with extension stripped from last segment).\n * - File-based: \"basics/custom-rules.mdc\" \u2192 \"basics/custom-rules\"\n * - Skill: \"my-skill/readme.md\" \u2192 \"my-skill\" (first segment, directory-based)\n *\n * @param pathUnderCategory - Path under the category directory\n * @param resourceType - Singular type: rule, agent, skill, etc.\n */\nfunction deriveNamespace(pathUnderCategory: string, resourceType: ResourceTypeId): string {\n if (!pathUnderCategory || pathUnderCategory === '') return 'unnamed';\n\n const parts = pathUnderCategory.split('/');\n\n if (resourceType === 'skill') {\n return parts[0] || 'unnamed';\n }\n\n // Strip platform suffix (e.g. git-manager.opencode.md -> git-manager.md) so platform-specific\n // variants group under the same resource\n const pathStripped = stripPlatformSuffixFromFilename(pathUnderCategory);\n const strippedParts = pathStripped.split('/');\n const lastSegment = strippedParts[strippedParts.length - 1] ?? '';\n const nameWithoutExt = stripExtension(lastSegment);\n\n if (strippedParts.length === 1) {\n return nameWithoutExt || lastSegment;\n }\n\n const subpath = strippedParts.slice(0, -1).join('/');\n return subpath ? `${subpath}/${nameWithoutExt}` : nameWithoutExt;\n}\n\n/**\n * Derive the full resource identifier (category/namespace) from a path.\n *\n * @param path - Source key, target path, or workspace path\n * @param resourceType - Singular type: rule, agent, skill, command, hook, mcp, other\n * @returns Full name like \"rules/custom-rules\", \"rules/basics/custom-rules\", \"agents/agent-creator\"\n */\nexport function deriveResourceFullName(path: string, resourceType: ResourceTypeId): string {\n const normalizedType = resourceType as ResourceTypeId;\n\n if (normalizedType === 'mcp') {\n return 'mcps/configs';\n }\n\n if (normalizedType === 'other') {\n return 'other';\n }\n\n const def = getResourceTypeDef(normalizedType);\n const categoryDir = def.dirName;\n\n if (!categoryDir) {\n return `other/${deriveNamespace(path, 'other')}`;\n }\n\n const pathUnder = getPathUnderCategory(path, categoryDir);\n if (pathUnder === null) {\n const pluralKey = toPluralKey(normalizedType);\n const fallback = path.replace(/\\\\/g, '/').split('/').pop() ?? 'unnamed';\n return `${pluralKey}/${stripExtension(fallback)}`;\n }\n\n const namespace = deriveNamespace(pathUnder, normalizedType);\n const pluralKey = toPluralKey(normalizedType);\n return `${pluralKey}/${namespace}`;\n}\n", "import path from 'path';\n\nimport type { CommandResult, ExecutionContext } from '../../types/index.js';\nimport { ValidationError } from '../../utils/errors.js';\nimport { getLocalOpenPackageDir, getLocalPackageYmlPath } from '../../utils/paths.js';\nimport { readWorkspaceIndex } from '../../utils/workspace-index-yml.js';\nimport { resolveDeclaredPath } from '../../utils/path-resolution.js';\nimport { exists } from '../../utils/fs.js';\nimport type { WorkspaceIndexPackage } from '../../types/workspace-index.js';\nimport { logger } from '../../utils/logger.js';\nimport { getTargetPath } from '../../utils/workspace-index-helpers.js';\nimport { parsePackageYml } from '../../utils/package-yml.js';\nimport { arePackageNamesEquivalent } from '../../utils/package-name.js';\nimport { scanUntrackedFiles, type UntrackedScanResult } from './untracked-files-scanner.js';\nimport { getWorkspaceIndexPath } from '../../utils/workspace-index-yml.js';\nimport { isPlatformId, getAllPlatforms, getPlatformDefinition } from '../platforms.js';\nimport { normalizePlatforms } from '../platform/platform-mapper.js';\nimport { DIR_TO_TYPE, RESOURCE_TYPE_ORDER, toPluralKey, type ResourceTypeId } from '../resources/resource-registry.js';\nimport { classifySourceKey } from '../resources/source-key-classifier.js';\nimport { deriveResourceFullName } from '../resources/resource-namespace.js';\nexport { classifySourceKey } from '../resources/source-key-classifier.js';\n\nexport type PackageSyncState = 'synced' | 'partial' | 'missing';\n\nexport interface ListFileMapping {\n source: string;\n target: string;\n exists: boolean;\n}\n\n/**\n * A single resource within a package (e.g., one rule, one agent, one skill)\n */\nexport interface ListResourceInfo {\n /** Display name (filename sans .md for files, directory name for skills) */\n name: string;\n /** Resource type: agent, skill, command, rule, hook, mcp, or 'other' for unrecognized */\n resourceType: string;\n /** Files belonging to this resource */\n files: ListFileMapping[];\n}\n\n/**\n * Resources grouped by type within a package\n */\nexport interface ListResourceGroup {\n /** Resource type label (e.g., 'rules', 'agents', 'skills') */\n resourceType: string;\n /** Individual resources of this type */\n resources: ListResourceInfo[];\n}\n\nexport interface ListPackageReport {\n name: string;\n version?: string;\n path: string;\n state: PackageSyncState;\n totalFiles: number;\n existingFiles: number;\n fileList?: ListFileMapping[];\n resourceGroups?: ListResourceGroup[];\n dependencies?: string[];\n}\n\nexport interface ListTreeNode {\n report: ListPackageReport;\n children: ListTreeNode[];\n}\n\nexport interface ListPipelineOptions {\n /** Include full file list for each package */\n includeFiles?: boolean;\n /** Build full recursive dependency tree */\n all?: boolean;\n /** Filter to tracked view only */\n tracked?: boolean;\n /** Filter to untracked view only */\n untracked?: boolean;\n /** Filter by platform names */\n platforms?: string[];\n}\n\nexport interface ListPipelineResult {\n packages: ListPackageReport[];\n tree?: ListTreeNode[];\n rootPackageNames?: string[];\n /** When a specific package is targeted, this contains its info for the header */\n targetPackage?: ListPackageReport;\n /** Total tracked files that exist on disk */\n trackedCount: number;\n /** Total tracked files that are missing on disk */\n missingCount: number;\n /** Total untracked files found */\n untrackedCount: number;\n /** Untracked files scan result */\n untrackedFiles?: UntrackedScanResult;\n}\n\n\n/**\n * Extract the root directory prefix from a `to` pattern string.\n * e.g. \".cursor/agents/x.md\" -> \".cursor\", \".config/opencode/agents/x.md\" -> \".config/opencode\"\n * Returns null for patterns without a dot-prefixed root dir.\n */\nfunction extractRootPrefixFromToPattern(pattern: string): string | null {\n const parts = pattern.replace(/\\\\/g, '/').split('/');\n if (parts.length < 2 || !parts[0].startsWith('.')) return null;\n const nonGlobParts = [];\n for (const part of parts) {\n if (part.includes('*') || part.includes('{')) break;\n nonGlobParts.push(part);\n }\n if (nonGlobParts.length < 2) return nonGlobParts.length === 1 ? nonGlobParts[0] : null;\n // For paths like \".config/opencode/agents/foo.md\", the root prefix is everything\n // up to but not including known resource type dirs or the filename.\n const resourceDirs = new Set(Object.keys(DIR_TO_TYPE));\n const prefixParts = [];\n for (const part of nonGlobParts) {\n if (resourceDirs.has(part)) break;\n if (part.includes('.') && part !== nonGlobParts[0]) break;\n prefixParts.push(part);\n }\n return prefixParts.length > 0 ? prefixParts.join('/') : null;\n}\n\n/**\n * Collect all `to` pattern strings from a flow, including $switch cases.\n */\nfunction collectToPatternsFromFlow(toField: unknown): string[] {\n if (typeof toField === 'string') return [toField];\n\n if (typeof toField === 'object' && toField !== null) {\n if ('$switch' in toField) {\n const sw = (toField as any).$switch;\n const patterns: string[] = [];\n for (const c of sw?.cases ?? []) {\n const v = c.value;\n if (typeof v === 'string') patterns.push(v);\n else if (typeof v === 'object' && v && 'pattern' in v) patterns.push(v.pattern);\n }\n const d = sw?.default;\n if (typeof d === 'string') patterns.push(d);\n else if (typeof d === 'object' && d && 'pattern' in d) patterns.push(d.pattern);\n return patterns;\n }\n if ('pattern' in toField && typeof (toField as any).pattern === 'string') {\n return [(toField as any).pattern];\n }\n }\n return [];\n}\n\n/**\n * Build a mapping from root directory prefixes to platform IDs.\n * Collects all root prefixes from every export flow `to` pattern (including $switch cases).\n * Cached per targetDir to avoid recomputing on every file.\n */\nconst rootDirCacheMap = new Map<string, Map<string, string>>();\n\nfunction getRootDirToPlatformMap(targetDir: string): Map<string, string> {\n const cached = rootDirCacheMap.get(targetDir);\n if (cached) return cached;\n\n const map = new Map<string, string>();\n for (const platform of getAllPlatforms({ includeDisabled: true }, targetDir)) {\n const definition = getPlatformDefinition(platform, targetDir);\n if (!definition.export) continue;\n for (const flow of definition.export) {\n for (const pattern of collectToPatternsFromFlow(flow.to)) {\n const prefix = extractRootPrefixFromToPattern(pattern);\n if (prefix && !map.has(prefix)) {\n map.set(prefix, platform);\n }\n }\n }\n }\n rootDirCacheMap.set(targetDir, map);\n return map;\n}\n\n/**\n * Extract platform from a target path by matching its root directory against\n * known platform root directories derived from export flows.\n * Returns null if the file is universal (no platform).\n *\n * @param targetPath - Target path relative to workspace (e.g., \".cursor/agents/foo.md\")\n * @param targetDir - Target directory for context and flow resolution\n * @returns Platform ID or null if universal\n */\nfunction extractPlatformFromPath(targetPath: string, targetDir: string): string | null {\n const normalized = targetPath.replace(/\\\\/g, '/');\n\n // Check if the path starts with a known platform root directory\n // Sort by longest prefix first so more-specific prefixes match before shorter ones\n const rootDirMap = getRootDirToPlatformMap(targetDir);\n const sortedEntries = [...rootDirMap.entries()].sort((a, b) => b[0].length - a[0].length);\n for (const [rootDir, platform] of sortedEntries) {\n if (normalized === rootDir || normalized.startsWith(rootDir + '/')) {\n return platform;\n }\n }\n\n // Fallback: Check for platform suffix in filename (e.g., mcp.cursor.jsonc, rule.claude.md)\n const parts = normalized.split('/');\n const filename = parts[parts.length - 1];\n const nameParts = filename.split('.');\n\n // Need at least 3 parts: name.platform.ext\n if (nameParts.length >= 3) {\n const possiblePlatform = nameParts[nameParts.length - 2];\n if (isPlatformId(possiblePlatform, targetDir)) {\n return possiblePlatform;\n }\n }\n\n // No platform detected - this is a universal file\n return null;\n}\n\n/**\n * Group file mappings into resource groups by analyzing source keys.\n *\n * For skills, all files sharing the same skills/<name>/ prefix are grouped into one resource.\n * For other types, each source key maps to one resource.\n */\nexport function groupFilesIntoResources(fileList: ListFileMapping[]): ListResourceGroup[] {\n // First pass: classify each file and group by resource identity\n const resourceMap = new Map<string, ListResourceInfo>();\n\n for (const file of fileList) {\n const { resourceType } = classifySourceKey(file.source);\n const fullName = deriveResourceFullName(file.source, resourceType);\n const key = fullName;\n\n if (!resourceMap.has(key)) {\n resourceMap.set(key, {\n name: fullName,\n resourceType,\n files: []\n });\n }\n resourceMap.get(key)!.files.push(file);\n }\n\n // Second pass: group resources by type\n const typeGroupMap = new Map<string, ListResourceInfo[]>();\n\n for (const resource of resourceMap.values()) {\n if (!typeGroupMap.has(resource.resourceType)) {\n typeGroupMap.set(resource.resourceType, []);\n }\n typeGroupMap.get(resource.resourceType)!.push(resource);\n }\n\n // Build final groups, sorted by type then by resource name\n const typeOrder = RESOURCE_TYPE_ORDER;\n const groups: ListResourceGroup[] = [];\n\n for (const type of typeOrder) {\n const resources = typeGroupMap.get(type);\n if (!resources || resources.length === 0) continue;\n\n // Sort resources by name\n resources.sort((a, b) => a.name.localeCompare(b.name));\n\n // Sort files within each resource by target path\n for (const resource of resources) {\n resource.files.sort((a, b) => a.target.localeCompare(b.target));\n }\n\n // Use plural form for group label\n const pluralLabel = toPluralKey(type as ResourceTypeId);\n groups.push({ resourceType: pluralLabel, resources });\n }\n\n // Handle any types not in typeOrder\n for (const [type, resources] of typeGroupMap) {\n if ((typeOrder as readonly string[]).includes(type)) continue;\n resources.sort((a, b) => a.name.localeCompare(b.name));\n for (const resource of resources) {\n resource.files.sort((a, b) => a.target.localeCompare(b.target));\n }\n groups.push({ resourceType: `${type}s`, resources });\n }\n\n return groups;\n}\n\n/**\n * Check package list status by verifying file existence\n * Does not compare content - only checks if expected files exist\n */\nasync function checkPackageStatus(\n targetDir: string,\n pkgName: string,\n entry: WorkspaceIndexPackage,\n includeFileList: boolean = false,\n platformsFilter?: string[]\n): Promise<ListPackageReport> {\n const totalTargets = entry.files\n ? Object.values(entry.files).reduce((s, arr) => s + (Array.isArray(arr) ? arr.length : 0), 0)\n : 0;\n const resolved = resolveDeclaredPath(entry.path, targetDir);\n const sourceRoot = resolved.absolute;\n\n // Check if source path exists\n const sourceExists = await exists(sourceRoot);\n\n // When source path is gone but we have workspace file mappings, determine state from\n // workspace targets instead of marking the package missing (e.g. index.path was a temp dir).\n const canDeriveFromFiles = totalTargets > 0;\n if (!sourceExists && !canDeriveFromFiles) {\n return {\n name: pkgName,\n version: entry.version,\n path: entry.path,\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n fileList: includeFileList ? [] : undefined\n };\n }\n\n // Check workspace file existence\n let totalFiles = 0;\n let existingFiles = 0;\n const fileList: ListFileMapping[] = [];\n \n const filesMapping = entry.files || {};\n \n // Normalize platform filter\n const normalizedPlatforms = platformsFilter ? normalizePlatforms(platformsFilter) : null;\n\n for (const [sourceKey, targets] of Object.entries(filesMapping)) {\n if (!Array.isArray(targets) || targets.length === 0) continue;\n\n for (const mapping of targets) {\n const targetPath = getTargetPath(mapping);\n \n // Apply platform filter if specified\n if (normalizedPlatforms && normalizedPlatforms.length > 0) {\n const filePlatform = extractPlatformFromPath(targetPath, targetDir);\n \n // If the file has a platform, check if it matches the filter\n if (filePlatform) {\n if (!normalizedPlatforms.includes(filePlatform.toLowerCase())) {\n continue; // Skip this file - it doesn't match the platform filter\n }\n }\n // If the file has no platform (universal), include it in all platform filters\n }\n \n const absPath = path.join(targetDir, targetPath);\n totalFiles++;\n \n const fileExists = await exists(absPath);\n if (fileExists) {\n existingFiles++;\n }\n if (includeFileList) {\n fileList.push({\n source: sourceKey,\n target: targetPath,\n exists: fileExists\n });\n }\n }\n }\n\n // Classify package state\n const state: PackageSyncState = existingFiles === totalFiles ? 'synced' : 'partial';\n\n // Read dependencies from the package manifest (not workspace index)\n let dependencies: string[] | undefined = entry.dependencies;\n if (!dependencies || dependencies.length === 0) {\n try {\n const pkgManifestPath = path.join(sourceRoot, 'openpackage.yml');\n if (await exists(pkgManifestPath)) {\n const pkgManifest = await parsePackageYml(pkgManifestPath);\n const allDeps = [\n ...(pkgManifest.dependencies || []),\n ...(pkgManifest['dev-dependencies'] || [])\n ];\n dependencies = allDeps.map(dep => dep.name);\n }\n } catch (error) {\n logger.debug(`Failed to read package manifest for ${pkgName}: ${error}`);\n }\n }\n\n // Always compute resource groups from the file data we collected\n const allFilesForGrouping: ListFileMapping[] = includeFileList ? fileList : [];\n\n // If we didn't collect file details for the list, we still need them for resource grouping\n if (!includeFileList) {\n for (const [sourceKey, targets] of Object.entries(filesMapping)) {\n if (!Array.isArray(targets) || targets.length === 0) continue;\n for (const mapping of targets) {\n const targetPath = getTargetPath(mapping);\n \n // Apply platform filter if specified\n if (normalizedPlatforms && normalizedPlatforms.length > 0) {\n const filePlatform = extractPlatformFromPath(targetPath, targetDir);\n \n // If the file has a platform, check if it matches the filter\n if (filePlatform) {\n if (!normalizedPlatforms.includes(filePlatform.toLowerCase())) {\n continue; // Skip this file - it doesn't match the platform filter\n }\n }\n // If the file has no platform (universal), include it in all platform filters\n }\n \n allFilesForGrouping.push({\n source: sourceKey,\n target: targetPath,\n exists: true\n });\n }\n }\n }\n\n const resourceGroups = allFilesForGrouping.length > 0\n ? groupFilesIntoResources(allFilesForGrouping)\n : undefined;\n\n return {\n name: pkgName,\n version: entry.version,\n path: entry.path,\n state,\n totalFiles,\n existingFiles,\n fileList: includeFileList ? fileList : undefined,\n resourceGroups,\n dependencies\n };\n}\n\n/**\n * Build a dependency tree from package reports\n */\nfunction buildDependencyTree(\n rootNames: string[],\n reportMap: Map<string, ListPackageReport>,\n all: boolean\n): ListTreeNode[] {\n const visited = new Set<string>();\n\n function buildNode(pkgName: string, depth: number): ListTreeNode | null {\n const report = reportMap.get(pkgName);\n if (!report) return null;\n\n // Prevent infinite loops from circular dependencies\n if (visited.has(pkgName)) {\n return {\n report: { ...report, name: `${report.name} (circular)` },\n children: []\n };\n }\n\n visited.add(pkgName);\n\n let children: ListTreeNode[] = [];\n if (all && report.dependencies && report.dependencies.length > 0) {\n children = report.dependencies\n .map(depName => buildNode(depName, depth + 1))\n .filter((node): node is ListTreeNode => node !== null);\n }\n\n visited.delete(pkgName);\n\n return { report, children };\n }\n\n return rootNames\n .map(name => buildNode(name, 0))\n .filter((node): node is ListTreeNode => node !== null);\n}\n\nexport async function runListPipeline(\n packageName: string | undefined,\n execContext: ExecutionContext,\n options: ListPipelineOptions = {}\n): Promise<CommandResult<ListPipelineResult>> {\n const { includeFiles = false, all = false, tracked = false, untracked = false, platforms } = options;\n \n // Use targetDir for list operations\n const targetDir = execContext.targetDir;\n const indexPath = getWorkspaceIndexPath(targetDir);\n\n // Validate mutual exclusivity\n if (tracked && untracked) {\n throw new ValidationError('Cannot use --tracked and --untracked together.');\n }\n\n // For --untracked only, we just need the workspace index (not the full manifest)\n if (untracked) {\n if (!(await exists(indexPath))) {\n throw new ValidationError(\n `No workspace index found at ${indexPath}. Cannot scan for untracked files.`\n );\n }\n\n const untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n\n return {\n success: true,\n data: {\n packages: [],\n tree: [],\n rootPackageNames: [],\n trackedCount: 0,\n missingCount: 0,\n untrackedCount: untrackedFiles.totalFiles,\n untrackedFiles\n }\n };\n }\n\n // Regular list operation - require both index and manifest\n const openpkgDir = getLocalOpenPackageDir(targetDir);\n const manifestPath = getLocalPackageYmlPath(targetDir);\n\n if (!(await exists(openpkgDir)) || !(await exists(manifestPath))) {\n throw new ValidationError(\n `No .openpackage/openpackage.yml found in ${targetDir}.`\n );\n }\n\n const { index } = await readWorkspaceIndex(targetDir);\n const packages = index.packages || {};\n const reports: ListPackageReport[] = [];\n const reportMap = new Map<string, ListPackageReport>();\n\n // Get workspace config to find root packages\n let rootPackageNames: string[] = [];\n let workspacePackageName: string | undefined;\n try {\n const config = await parsePackageYml(manifestPath);\n workspacePackageName = config.name;\n // Root packages are those declared in dependencies/dev-dependencies\n const declaredDeps = [\n ...(config.dependencies || []),\n ...(config['dev-dependencies'] || [])\n ];\n rootPackageNames = declaredDeps.map(dep => dep.name);\n // Include workspace package in tree roots when it's in the index (so its resources are listed)\n if (workspacePackageName && packages[workspacePackageName]) {\n rootPackageNames = [workspacePackageName, ...rootPackageNames];\n }\n } catch (error) {\n logger.warn(`Failed to read workspace manifest: ${error}`);\n }\n\n // If specific package requested, that package becomes the \"root\" and we show its dependencies\n if (packageName) {\n const pkgEntry = packages[packageName];\n if (!pkgEntry) {\n return {\n success: true,\n data: { packages: [], rootPackageNames: [], trackedCount: 0, missingCount: 0, untrackedCount: 0 }\n };\n }\n\n let targetPackage: ListPackageReport;\n try {\n targetPackage = await checkPackageStatus(targetDir, packageName, pkgEntry, true, platforms);\n reports.push(targetPackage);\n reportMap.set(packageName, targetPackage);\n } catch (error) {\n logger.warn(`Failed to check package ${packageName}: ${error}`);\n targetPackage = {\n name: packageName,\n version: pkgEntry?.version,\n path: pkgEntry?.path ?? '',\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n fileList: [],\n dependencies: pkgEntry?.dependencies\n };\n reports.push(targetPackage);\n reportMap.set(packageName, targetPackage);\n }\n\n // Load the target package's dependencies as tree nodes\n const depNames = targetPackage.dependencies || [];\n for (const depName of depNames) {\n if (reportMap.has(depName)) continue;\n \n const depEntry = packages[depName];\n if (!depEntry) continue;\n \n try {\n const depReport = await checkPackageStatus(targetDir, depName, depEntry, includeFiles, platforms);\n reportMap.set(depName, depReport);\n } catch (error) {\n logger.debug(`Failed to load dependency ${depName}: ${error}`);\n }\n }\n\n // If full tree (deps view), recursively load nested dependencies\n if (all) {\n const loadNestedDeps = async (names: string[]) => {\n for (const name of names) {\n const report = reportMap.get(name);\n if (!report?.dependencies) continue;\n \n for (const nestedDepName of report.dependencies) {\n if (reportMap.has(nestedDepName)) continue;\n \n const nestedEntry = packages[nestedDepName];\n if (!nestedEntry) continue;\n \n try {\n const nestedReport = await checkPackageStatus(targetDir, nestedDepName, nestedEntry, includeFiles, platforms);\n reportMap.set(nestedDepName, nestedReport);\n \n if (nestedReport.dependencies && nestedReport.dependencies.length > 0) {\n await loadNestedDeps([nestedDepName]);\n }\n } catch (error) {\n logger.debug(`Failed to load nested dependency ${nestedDepName}: ${error}`);\n }\n }\n }\n };\n await loadNestedDeps(depNames);\n }\n\n // Build tree from the target package's dependencies (not the package itself)\n const tree = buildDependencyTree(depNames, reportMap, all);\n \n // When listing a specific package, also create a tree node for the target package itself\n // so its resources can be displayed\n const targetTreeNode: ListTreeNode = {\n report: targetPackage,\n children: tree\n };\n const treeWithTarget = [targetTreeNode];\n\n // Compute tracked/missing counts from reports\n const trackedCount = reports.reduce((sum, r) => sum + r.existingFiles, 0);\n const missingCount = reports.reduce((sum, r) => sum + (r.totalFiles - r.existingFiles), 0);\n\n // Scan untracked files unless --tracked flag is set\n let untrackedFiles: UntrackedScanResult | undefined;\n let untrackedCount = 0;\n if (!tracked) {\n untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n untrackedCount = untrackedFiles.totalFiles;\n }\n\n return {\n success: true,\n data: { packages: reports, tree: treeWithTarget, rootPackageNames: depNames, targetPackage, trackedCount, missingCount, untrackedCount, untrackedFiles }\n };\n }\n\n // Check all packages and build reports (include workspace package so its resources are listed)\n for (const [pkgName, pkgEntry] of Object.entries(packages)) {\n try {\n const report = await checkPackageStatus(targetDir, pkgName, pkgEntry, includeFiles, platforms);\n reports.push(report);\n reportMap.set(pkgName, report);\n } catch (error) {\n logger.warn(`Failed to check package ${pkgName}: ${error}`);\n const errorReport: ListPackageReport = {\n name: pkgName,\n version: pkgEntry?.version,\n path: pkgEntry?.path ?? '',\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n dependencies: pkgEntry?.dependencies\n };\n reports.push(errorReport);\n reportMap.set(pkgName, errorReport);\n }\n }\n\n // Build dependency tree from root packages\n const tree = buildDependencyTree(rootPackageNames, reportMap, all);\n\n // Compute tracked/missing counts from reports\n const trackedCount = reports.reduce((sum, r) => sum + r.existingFiles, 0);\n const missingCount = reports.reduce((sum, r) => sum + (r.totalFiles - r.existingFiles), 0);\n\n // Scan untracked files unless --tracked flag is set\n let untrackedFiles: UntrackedScanResult | undefined;\n let untrackedCount = 0;\n if (!tracked) {\n untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n untrackedCount = untrackedFiles.totalFiles;\n }\n\n return {\n success: true,\n data: { packages: reports, tree, rootPackageNames, trackedCount, missingCount, untrackedCount, untrackedFiles }\n };\n}\n", "/**\n * Entity Type Detection Utilities\n * \n * Determines whether a path represents a package, workspace, or generic resource.\n */\n\nimport { join } from 'path';\nimport { exists, isDirectory } from './fs.js';\n\n/**\n * Entity type classification\n */\nexport type EntityType = 'workspace' | 'package' | 'resource';\n\n/**\n * Detect the type of entity at a given path.\n * \n * Detection logic:\n * - workspace: Has .openpackage/openpackage.yml\n * - package: Has openpackage.yml, or has Claude plugin characteristics, or has standard package directories\n * - resource: Everything else (individual files, subdirectories without package markers)\n * \n * @param path - Absolute path to check\n * @returns Entity type\n */\nexport async function detectEntityType(path: string): Promise<EntityType> {\n // Check for workspace marker (.openpackage/openpackage.yml)\n const workspaceMarker = join(path, '.openpackage', 'openpackage.yml');\n if (await exists(workspaceMarker)) {\n return 'workspace';\n }\n\n // Check for package marker (openpackage.yml at root)\n const packageMarker = join(path, 'openpackage.yml');\n if (await exists(packageMarker)) {\n return 'package';\n }\n\n // Check for Claude plugin characteristics (.claude-plugin/plugin.json)\n const claudePluginMarker = join(path, '.claude-plugin', 'plugin.json');\n if (await exists(claudePluginMarker)) {\n return 'package';\n }\n\n // Check for standard package directories (agents/, skills/, commands/, rules/, hooks/)\n const packageDirs = ['agents', 'skills', 'commands', 'rules', 'hooks'];\n for (const dir of packageDirs) {\n const dirPath = join(path, dir);\n if (await exists(dirPath) && await isDirectory(dirPath)) {\n return 'package';\n }\n }\n\n // Default to resource for everything else\n return 'resource';\n}\n\n/**\n * Get the display name for an entity.\n * \n * For packages: reads name from openpackage.yml, falls back to directory name\n * For other types: uses the provided name\n * \n * @param path - Absolute path to the entity\n * @param fallbackName - Name to use if package name cannot be determined\n * @returns Display name\n */\nexport async function getEntityDisplayName(\n path: string,\n fallbackName: string\n): Promise<string> {\n const entityType = await detectEntityType(path);\n\n // For packages and workspaces, try to read the name from openpackage.yml\n if (entityType === 'package' || entityType === 'workspace') {\n try {\n const { parsePackageYml } = await import('./package-yml.js');\n const manifestPath = entityType === 'workspace'\n ? join(path, '.openpackage', 'openpackage.yml')\n : join(path, 'openpackage.yml');\n\n if (await exists(manifestPath)) {\n const manifest = await parsePackageYml(manifestPath);\n if (manifest.name) {\n return manifest.name;\n }\n }\n } catch (error) {\n // Fall through to use fallback name\n }\n }\n\n return fallbackName;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "pluralKey", "untrackedFiles", "tree", "trackedCount", "missingCount", "untrackedCount", "path", "parsePackageYml"]
7
+ }
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ profileManager
4
+ } from "./chunk-S6OARUVQ.js";
5
+ import {
6
+ createCliExecutionContext,
7
+ resolveOutput,
8
+ resolvePrompt
9
+ } from "./chunk-BROJ6OUT.js";
10
+ import {
11
+ ensureOpenPackageDirectories
12
+ } from "./chunk-XEPVYZO3.js";
13
+ import "./chunk-VN22A7NW.js";
14
+ import "./chunk-J4IFFBLP.js";
15
+ import "./chunk-S47F4OG4.js";
16
+ import {
17
+ UserCancellationError
18
+ } from "./chunk-ID4SVDQZ.js";
19
+ import {
20
+ logger
21
+ } from "./chunk-5EFWGD33.js";
22
+
23
+ // src/utils/messages.ts
24
+ var API_KEY_SIGNUP_MESSAGE = "\u{1F4A1} Obtain an API key by signing up at \x1B[4mhttps://openpackage.dev\x1B[0m";
25
+
26
+ // src/commands/configure.ts
27
+ async function setupProfile(profileName, out, prm) {
28
+ try {
29
+ logger.info(`Setting up profile: ${profileName}`), await ensureOpenPackageDirectories(), out.info(API_KEY_SIGNUP_MESSAGE);
30
+ let apiKey = await prm.text(`Enter API key for profile '${profileName}':`, {
31
+ validate: (value) => value.length > 0 ? !0 : "API key is required"
32
+ }), description = await prm.text(`Enter description for profile '${profileName}' (optional):`, {
33
+ initial: profileName === "default" ? "Default profile" : ""
34
+ });
35
+ if (!apiKey)
36
+ throw new UserCancellationError("Profile setup cancelled");
37
+ return await profileManager.setProfile(profileName, {
38
+ description: description || void 0
39
+ }), await profileManager.setProfileCredentials(profileName, {
40
+ api_key: apiKey
41
+ }), out.success(`Profile '${profileName}' configured successfully`), profileName === "default" ? (out.message(""), out.info("You can now use remote registry features with this profile.")) : (out.message(""), out.info(`You can now use remote registry features with --profile ${profileName}`)), {
42
+ success: !0,
43
+ data: {
44
+ profile: profileName,
45
+ message: "Profile configured successfully"
46
+ }
47
+ };
48
+ } catch (error) {
49
+ if (error instanceof UserCancellationError)
50
+ throw error;
51
+ return logger.error(`Failed to setup profile: ${profileName}`, { error }), { success: !1, error: `Failed to setup profile: ${error}` };
52
+ }
53
+ }
54
+ async function listProfiles(out) {
55
+ try {
56
+ let profiles = await profileManager.listProfiles();
57
+ if (profiles.length === 0)
58
+ return out.info("No profiles configured."), out.message(""), out.info("To create a profile, run:"), out.info(" opkg configure"), out.info(" opkg configure --profile <name>"), { success: !0, data: { profiles: [] } };
59
+ out.info("Configured profiles:"), out.message("");
60
+ for (let profileName of profiles) {
61
+ let profile = await profileManager.getProfile(profileName), hasCredentials = !!profile?.credentials?.api_key, description = profile?.config?.description || "(no description)";
62
+ out.message(` ${profileName}`), out.message(` Description: ${description}`), out.message(` Credentials: ${hasCredentials ? "\u2705 Configured" : "\u274C Missing"}`), out.message("");
63
+ }
64
+ return {
65
+ success: !0,
66
+ data: { profiles }
67
+ };
68
+ } catch (error) {
69
+ return logger.error("Failed to list profiles", { error }), { success: !1, error: `Failed to list profiles: ${error}` };
70
+ }
71
+ }
72
+ async function deleteProfile(profileName, out, prm) {
73
+ try {
74
+ if (profileName === "default")
75
+ return { success: !1, error: "Cannot delete the default profile" };
76
+ if (!await profileManager.hasProfile(profileName))
77
+ return { success: !1, error: `Profile '${profileName}' not found` };
78
+ if (!await prm.confirm(
79
+ `Are you sure you want to delete profile '${profileName}'?`,
80
+ !1
81
+ ))
82
+ throw new UserCancellationError("Profile deletion cancelled");
83
+ return await profileManager.deleteProfile(profileName), out.success(`Profile '${profileName}' deleted successfully`), {
84
+ success: !0,
85
+ data: {
86
+ profile: profileName,
87
+ message: "Profile deleted successfully"
88
+ }
89
+ };
90
+ } catch (error) {
91
+ if (error instanceof UserCancellationError)
92
+ throw error;
93
+ return logger.error(`Failed to delete profile: ${profileName}`, { error }), { success: !1, error: `Failed to delete profile: ${error}` };
94
+ }
95
+ }
96
+ async function configureCommand(options, out, prm) {
97
+ return logger.info("Configure command executed", { options }), options.list ? await listProfiles(out) : typeof options.delete == "string" ? await deleteProfile(options.delete, out, prm) : options.delete && options.profile ? await deleteProfile(options.profile, out, prm) : options.delete ? { success: !1, error: "Please provide a profile name via --delete <name> or --profile <name>." } : options.profile ? await setupProfile(options.profile, out, prm) : await setupProfile("default", out, prm);
98
+ }
99
+ async function setupConfigureCommand(args) {
100
+ let [options] = args, ctx = await createCliExecutionContext({ outputMode: "rich" }), out = resolveOutput(ctx), prm = resolvePrompt(ctx), result = await configureCommand(options, out, prm);
101
+ if (!result.success)
102
+ throw new Error(result.error || "Configure operation failed");
103
+ }
104
+ export {
105
+ setupConfigureCommand
106
+ };
107
+ //# sourceMappingURL=configure-3AZUMDJZ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/utils/messages.ts", "../src/commands/configure.ts"],
4
+ "sourcesContent": ["/**\n * User-facing messages and notifications for the OpenPackage CLI\n */\n\n/**\n * API key signup message\n * Displayed when prompting users to obtain an API key\n */\nexport const API_KEY_SIGNUP_MESSAGE = '\uD83D\uDCA1 Obtain an API key by signing up at \\x1b[4mhttps://openpackage.dev\\x1b[0m';\n\n/**\n * Display the API key signup message to the console\n */\nexport function showApiKeySignupMessage(): void {\n console.log(API_KEY_SIGNUP_MESSAGE);\n}\n", "import { CommandResult } from '@opkg/core/types/index.js';\nimport { profileManager } from '@opkg/core/core/profiles.js';\nimport { ensureOpenPackageDirectories } from '@opkg/core/core/directory.js';\nimport { logger } from '@opkg/core/utils/logger.js';\nimport { UserCancellationError } from '@opkg/core/utils/errors.js';\nimport { API_KEY_SIGNUP_MESSAGE } from '../utils/messages.js';\nimport { createCliExecutionContext } from '../cli/context.js';\nimport { resolveOutput, resolvePrompt } from '@opkg/core/core/ports/resolve.js';\nimport type { OutputPort } from '@opkg/core/core/ports/output.js';\nimport type { PromptPort } from '@opkg/core/core/ports/prompt.js';\n\n/**\n * Configure command implementation for profile management\n */\n\ninterface ConfigureOptions {\n profile?: string;\n list?: boolean;\n delete?: string | boolean;\n}\n\n/**\n * Interactive profile setup\n */\nasync function setupProfile(profileName: string, out: OutputPort, prm: PromptPort): Promise<CommandResult> {\n try {\n logger.info(`Setting up profile: ${profileName}`);\n\n // Ensure directories exist\n await ensureOpenPackageDirectories();\n\n out.info(API_KEY_SIGNUP_MESSAGE);\n\n // Prompt for API key\n const apiKey = await prm.text(`Enter API key for profile '${profileName}':`, {\n validate: (value: string) => value.length > 0 ? true : 'API key is required'\n });\n\n const description = await prm.text(`Enter description for profile '${profileName}' (optional):`, {\n initial: profileName === 'default' ? 'Default profile' : ''\n });\n\n if (!apiKey) {\n throw new UserCancellationError('Profile setup cancelled');\n }\n\n // Set profile configuration\n await profileManager.setProfile(profileName, {\n description: description || undefined\n });\n\n // Set profile credentials\n await profileManager.setProfileCredentials(profileName, {\n api_key: apiKey\n });\n\n out.success(`Profile '${profileName}' configured successfully`);\n \n if (profileName === 'default') {\n out.message('');\n out.info('You can now use remote registry features with this profile.');\n } else {\n out.message('');\n out.info(`You can now use remote registry features with --profile ${profileName}`);\n }\n\n return {\n success: true,\n data: {\n profile: profileName,\n message: 'Profile configured successfully'\n }\n };\n } catch (error) {\n if (error instanceof UserCancellationError) {\n throw error; // Re-throw to be handled by withErrorHandling\n }\n logger.error(`Failed to setup profile: ${profileName}`, { error });\n return { success: false, error: `Failed to setup profile: ${error}` };\n }\n}\n\n/**\n * List all profiles\n */\nasync function listProfiles(out: OutputPort): Promise<CommandResult> {\n try {\n const profiles = await profileManager.listProfiles();\n \n if (profiles.length === 0) {\n out.info('No profiles configured.');\n out.message('');\n out.info('To create a profile, run:');\n out.info(' opkg configure');\n out.info(' opkg configure --profile <name>');\n return { success: true, data: { profiles: [] } };\n }\n\n out.info('Configured profiles:');\n out.message('');\n\n for (const profileName of profiles) {\n const profile = await profileManager.getProfile(profileName);\n const hasCredentials = !!profile?.credentials?.api_key;\n const description = profile?.config?.description || '(no description)';\n \n out.message(` ${profileName}`);\n out.message(` Description: ${description}`);\n out.message(` Credentials: ${hasCredentials ? '\\u2705 Configured' : '\\u274C Missing'}`);\n out.message('');\n }\n\n return {\n success: true,\n data: { profiles }\n };\n } catch (error) {\n logger.error('Failed to list profiles', { error });\n return { success: false, error: `Failed to list profiles: ${error}` };\n }\n}\n\n/**\n * Delete a profile\n */\nasync function deleteProfile(profileName: string, out: OutputPort, prm: PromptPort): Promise<CommandResult> {\n try {\n if (profileName === 'default') {\n return { success: false, error: 'Cannot delete the default profile' };\n }\n\n const exists = await profileManager.hasProfile(profileName);\n if (!exists) {\n return { success: false, error: `Profile '${profileName}' not found` };\n }\n\n // Confirm deletion\n const confirmed = await prm.confirm(\n `Are you sure you want to delete profile '${profileName}'?`,\n false\n );\n\n if (!confirmed) {\n throw new UserCancellationError('Profile deletion cancelled');\n }\n\n await profileManager.deleteProfile(profileName);\n out.success(`Profile '${profileName}' deleted successfully`);\n\n return {\n success: true,\n data: {\n profile: profileName,\n message: 'Profile deleted successfully'\n }\n };\n } catch (error) {\n if (error instanceof UserCancellationError) {\n throw error; // Re-throw to be handled by withErrorHandling\n }\n logger.error(`Failed to delete profile: ${profileName}`, { error });\n return { success: false, error: `Failed to delete profile: ${error}` };\n }\n}\n\n\n/**\n * Main configure command implementation\n */\nasync function configureCommand(options: ConfigureOptions, out: OutputPort, prm: PromptPort): Promise<CommandResult> {\n logger.info('Configure command executed', { options });\n\n // List profiles\n if (options.list) {\n return await listProfiles(out);\n }\n\n // Delete profile\n if (typeof options.delete === 'string') {\n return await deleteProfile(options.delete, out, prm);\n }\n if (options.delete && options.profile) {\n // Backward compatibility: allow --delete with --profile <name>\n return await deleteProfile(options.profile, out, prm);\n }\n if (options.delete) {\n return { success: false, error: 'Please provide a profile name via --delete <name> or --profile <name>.' };\n }\n\n // Setup default profile (default behavior)\n if (!options.profile) {\n return await setupProfile('default', out, prm);\n }\n\n // Setup profile\n return await setupProfile(options.profile, out, prm);\n}\n\n/**\n * Setup the configure command\n */\nexport async function setupConfigureCommand(args: any[]): Promise<void> {\n const [options] = args as [ConfigureOptions];\n const ctx = await createCliExecutionContext({ outputMode: 'rich' });\n const out = resolveOutput(ctx);\n const prm = resolvePrompt(ctx);\n const result = await configureCommand(options, out, prm);\n if (!result.success) {\n throw new Error(result.error || 'Configure operation failed');\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -102,69 +102,69 @@ program.name("openpackage").alias("opkg ").description("OpenPackage - The Packag
102
102
  }
103
103
  });
104
104
  program.command("new").argument("[package-name]", "package name (will prompt if not provided)").description('Create a new package with minimal manifest (use "opkg set" to configure metadata)').option("--scope <scope>", "package scope: root, project, or global (default: global)").option("--path <path>", "custom path for package directory (overrides scope)").option("-f, --force", "overwrite existing package without confirmation").action(withErrorHandling(async (...args) => {
105
- let { setupNewCommand } = await import("./new-UJ3HI5MZ.js");
105
+ let { setupNewCommand } = await import("./new-F46OSD72.js");
106
106
  await setupNewCommand(args);
107
107
  }));
108
108
  program.command("add").argument(
109
109
  "[resource-spec]",
110
110
  "resource to add (package[@version], gh@owner/repo, https://github.com/owner/repo, or /path/to/file). If omitted, shows interactive file selector."
111
111
  ).description("Add a dependency to openpackage.yml or copy files to a package").option("--to <package-name>", "target package (for dependency: which manifest; for copy: which package source)").option("--dev", "add to dev-dependencies instead of dependencies").option("--copy", "force copy mode (copy files instead of recording dependency)").option("--platform-specific", "save platform-specific variants for platform subdir inputs").option("--force", "overwrite existing files without prompting").action(withErrorHandling(async (...args) => {
112
- let { setupAddCommand } = await import("./add-AFORN4DK.js");
112
+ let { setupAddCommand } = await import("./add-U44SL3OR.js");
113
113
  await setupAddCommand(args);
114
114
  }));
115
115
  program.command("remove").alias("rm").argument("[resource-spec]", "file, directory, or dependency to remove. If omitted, shows interactive file selector.").description("Remove files or dependencies from a mutable package source or workspace package").option("--from <package-name>", "source package name (defaults to workspace package)").option("--force", "Skip confirmation prompts").option("--dry-run", "Preview what would be removed without actually deleting").action(withErrorHandling(async (...args) => {
116
- let { setupRemoveCommand } = await import("./remove-Z5YY2PZZ.js");
116
+ let { setupRemoveCommand } = await import("./remove-BD52BHR2.js");
117
117
  await setupRemoveCommand(args);
118
118
  }));
119
119
  program.command("save").argument("<package-spec>", "resource spec to save workspace changes to").description("Save workspace edits back to mutable package source").option("-f, --force", "auto-select newest when conflicts occur").action(withErrorHandling(async (...args) => {
120
- let { setupSaveCommand } = await import("./save-YHCXQDLA.js");
120
+ let { setupSaveCommand } = await import("./save-N3QWF2WN.js");
121
121
  await setupSaveCommand(args);
122
122
  }));
123
123
  program.command("set").argument("<field>", "manifest field to set (name, version, description, author, license, keywords, homepage, repository)").argument("[value]", "value to set (omit for interactive prompt)").description("Set a field in the package manifest (openpackage.yml)").option("--package <name>", "target package name (defaults to workspace package)").action(withErrorHandling(async (...args) => {
124
- let { setupSetCommand } = await import("./set-SGEPTBDB.js");
124
+ let { setupSetCommand } = await import("./set-NGM2FIKF.js");
125
125
  await setupSetCommand(args);
126
126
  }));
127
127
  program.command("install").alias("i").description("Install packages to workspace").argument(
128
128
  "[resource-spec]",
129
129
  "resource to install (package[@version], gh@owner/repo, https://github.com/owner/repo, /path/to/local, or git@host:repo.git)"
130
130
  ).option("-g, --global", "install to home directory (~/) instead of current workspace").option("-a, --agents <names...>", "install specific agents by name (matches frontmatter name or filename)").option("-s, --skills <names...>", "install specific skills by name (matches SKILL.md frontmatter name or directory name)").option("-r, --rules <names...>", "install specific rules by name (matches frontmatter name or filename)").option("-c, --commands <names...>", "install specific commands by name (matches frontmatter name or filename)").option("--plugins <names...>", "install specific plugins from marketplace (bypasses interactive selection)").option("--platforms <platforms...>", "install to specific platforms (e.g., cursor claudecode opencode)").option("-i, --interactive", "interactively select resources to install (agents, skills, commands, etc.)").option("--dry-run", "preview changes without applying them").option("--force", "overwrite existing files").option("--conflicts <strategy>", "conflict handling strategy: namespace, overwrite, skip, or ask").option("--dev", "add resource to dev-dependencies (instead of dependencies)").option("--remote", "pull and install from remote registry, ignoring local versions").option("--local", "resolve and install using only local registry versions, skipping remote metadata and pulls").option("--profile <profile>", "profile to use for authentication").option("--api-key <key>", "API key for authentication (overrides profile)").action(withErrorHandling(async (...args) => {
131
- let { setupInstallCommand } = await import("./install-ZR42VB5K.js");
131
+ let { setupInstallCommand } = await import("./install-EZNWMLJR.js");
132
132
  await setupInstallCommand(args);
133
133
  }));
134
134
  program.command("uninstall").alias("un").description("Remove installed resources or packages").argument("[resource-spec]", "name of the resource or package to uninstall").option("-g, --global", "uninstall from home directory (~/) instead of current workspace").option("--dry-run", "preview changes without applying them").option("-i, --interactive", "interactively select items to uninstall").action(withErrorHandling(async (...args) => {
135
- let { setupUninstallCommand } = await import("./uninstall-UBZTRBEK.js");
135
+ let { setupUninstallCommand } = await import("./uninstall-Q3CP4UN5.js");
136
136
  await setupUninstallCommand(args);
137
137
  }));
138
138
  program.command("list").alias("ls").description("List installed resources and packages").argument("[resource-spec]", "filter by a specific installed package").option("-s, --scope <scope>", "workspace scope: project or global (default: both)").option("-d, --deps", "show dependency tree (full tree including transitive dependencies)").option("-f, --files", "show individual file paths").option("-t, --tracked", "show only tracked resources (skip untracked scan)").option("-u, --untracked", "show only untracked resources").option("--platforms <platforms...>", "filter by specific platforms (e.g., cursor, claude)").action(withErrorHandling(async (...args) => {
139
- let { setupListCommand } = await import("./list-GSBJJXQT.js");
139
+ let { setupListCommand } = await import("./list-XR7RSJFS.js");
140
140
  await setupListCommand(args);
141
141
  }));
142
142
  program.command("search").description("Search available packages across local sources").argument("[query]", "filter by package name, keywords, or description").option("-p, --project", "search project packages only (./.openpackage/packages)").option("-g, --global", "search global packages only (~/.openpackage/packages)").option("-r, --registry", "search local registry only (~/.openpackage/registry)").option("-a, --all", "show all versions for registry packages (default: latest only)").option("--json", "output results as JSON").action(withErrorHandling(async (...args) => {
143
- let { setupSearchCommand } = await import("./search-RW5EX76L.js");
143
+ let { setupSearchCommand } = await import("./search-ABROK3UO.js");
144
144
  await setupSearchCommand(args);
145
145
  }));
146
146
  program.command("view").description("View package details").argument("[package-spec]", "package name or path to view").option("-s, --scope <scope>", "workspace scope: project or global (default: both)").option("-f, --files", "show individual file paths").option("--remote", "view remote package details").option("--profile <profile>", "profile to use for authentication").option("--api-key <key>", "API key for authentication (overrides profile)").action(withErrorHandling(async (...args) => {
147
- let { setupViewCommand } = await import("./view-TVWVUS3B.js");
147
+ let { setupViewCommand } = await import("./view-MXRBMXOG.js");
148
148
  await setupViewCommand(args);
149
149
  }));
150
150
  program.command("publish").argument("[package-spec]", "package name or path (optional if cwd is a package)").description("Publish package to remote registry (use --local for local publishing)").option("--local", "publish to local registry (~/.openpackage/registry)").option("--force", "overwrite existing version without confirmation").option("--profile <profile>", "profile to use for authentication (remote only)").option("--api-key <key>", "API key for authentication (remote only, overrides profile)").action(withErrorHandling(async (...args) => {
151
- let { setupPublishCommand } = await import("./publish-VXEPM3TI.js");
151
+ let { setupPublishCommand } = await import("./publish-4H43PCSG.js");
152
152
  await setupPublishCommand(args);
153
153
  }));
154
154
  program.command("unpublish").argument("[package-spec]", "package name to unpublish (optional, interactive if omitted)").description("Remove a package or version from the local registry").option("--all", "unpublish all versions").action(withErrorHandling(async (...args) => {
155
- let { setupUnpublishCommand } = await import("./unpublish-V4PMWZVD.js");
155
+ let { setupUnpublishCommand } = await import("./unpublish-VBTNTMS5.js");
156
156
  await setupUnpublishCommand(args);
157
157
  }));
158
158
  program.command("configure").alias("config").description("Configure default profile and authentication").option("--profile <name>", "profile name to configure").option("--list", "list all configured profiles").option("--delete <name>", "delete the specified profile").action(withErrorHandling(async (...args) => {
159
- let { setupConfigureCommand } = await import("./configure-IW22RQIX.js");
159
+ let { setupConfigureCommand } = await import("./configure-3AZUMDJZ.js");
160
160
  await setupConfigureCommand(args);
161
161
  }));
162
162
  program.command("login").description("Authenticate with OpenPackage").option("--profile <profile>", "profile to use for authentication").action(withErrorHandling(async (...args) => {
163
- let { setupLoginCommand } = await import("./login-TUPFY4I2.js");
163
+ let { setupLoginCommand } = await import("./login-NRKHXZKM.js");
164
164
  await setupLoginCommand(args);
165
165
  }));
166
166
  program.command("logout").description("Remove stored credentials").option("--profile <profile>", "profile to log out").action(withErrorHandling(async (...args) => {
167
- let { setupLogoutCommand } = await import("./logout-GTYZM3NQ.js");
167
+ let { setupLogoutCommand } = await import("./logout-SYHXCVCQ.js");
168
168
  await setupLogoutCommand(args);
169
169
  }));
170
170
  program.hook("preAction", async (thisCommand) => {