@a5c-ai/extension-mux 5.0.1-staging.04ca6ab00d21

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 (116) hide show
  1. package/README.md +58 -0
  2. package/dist/binTemplates.d.ts +7 -0
  3. package/dist/binTemplates.d.ts.map +1 -0
  4. package/dist/binTemplates.js +292 -0
  5. package/dist/cli.d.ts +8 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +299 -0
  8. package/dist/compiler.d.ts +15 -0
  9. package/dist/compiler.d.ts.map +1 -0
  10. package/dist/compiler.js +118 -0
  11. package/dist/diff.d.ts +9 -0
  12. package/dist/diff.d.ts.map +1 -0
  13. package/dist/diff.js +183 -0
  14. package/dist/emit.d.ts +3 -0
  15. package/dist/emit.d.ts.map +1 -0
  16. package/dist/emit.js +42 -0
  17. package/dist/hookRegistration.d.ts +8 -0
  18. package/dist/hookRegistration.d.ts.map +1 -0
  19. package/dist/hookRegistration.js +9 -0
  20. package/dist/index.d.ts +13 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +13 -0
  23. package/dist/init.d.ts +17 -0
  24. package/dist/init.d.ts.map +1 -0
  25. package/dist/init.js +200 -0
  26. package/dist/installInstructions.d.ts +3 -0
  27. package/dist/installInstructions.d.ts.map +1 -0
  28. package/dist/installInstructions.js +150 -0
  29. package/dist/installSharedGenerator.d.ts +3 -0
  30. package/dist/installSharedGenerator.d.ts.map +1 -0
  31. package/dist/installSharedGenerator.js +229 -0
  32. package/dist/manifestGenerators.d.ts +10 -0
  33. package/dist/manifestGenerators.d.ts.map +1 -0
  34. package/dist/manifestGenerators.js +11 -0
  35. package/dist/marketplaceGenerator.d.ts +3 -0
  36. package/dist/marketplaceGenerator.d.ts.map +1 -0
  37. package/dist/marketplaceGenerator.js +46 -0
  38. package/dist/proxiedHookTemplates.d.ts +10 -0
  39. package/dist/proxiedHookTemplates.d.ts.map +1 -0
  40. package/dist/proxiedHookTemplates.js +122 -0
  41. package/dist/resolve.d.ts +3 -0
  42. package/dist/resolve.d.ts.map +1 -0
  43. package/dist/resolve.js +106 -0
  44. package/dist/schema.d.ts +231 -0
  45. package/dist/schema.d.ts.map +1 -0
  46. package/dist/schema.js +340 -0
  47. package/dist/sdkConfig.d.ts +20 -0
  48. package/dist/sdkConfig.d.ts.map +1 -0
  49. package/dist/sdkConfig.js +41 -0
  50. package/dist/targets/adapters/base.d.ts +10 -0
  51. package/dist/targets/adapters/base.d.ts.map +1 -0
  52. package/dist/targets/adapters/base.js +16 -0
  53. package/dist/targets/adapters/claude-code.d.ts +9 -0
  54. package/dist/targets/adapters/claude-code.d.ts.map +1 -0
  55. package/dist/targets/adapters/claude-code.js +83 -0
  56. package/dist/targets/adapters/codex.d.ts +13 -0
  57. package/dist/targets/adapters/codex.d.ts.map +1 -0
  58. package/dist/targets/adapters/codex.js +103 -0
  59. package/dist/targets/adapters/cursor.d.ts +9 -0
  60. package/dist/targets/adapters/cursor.d.ts.map +1 -0
  61. package/dist/targets/adapters/cursor.js +57 -0
  62. package/dist/targets/adapters/gemini.d.ts +9 -0
  63. package/dist/targets/adapters/gemini.d.ts.map +1 -0
  64. package/dist/targets/adapters/gemini.js +86 -0
  65. package/dist/targets/adapters/github-copilot.d.ts +9 -0
  66. package/dist/targets/adapters/github-copilot.d.ts.map +1 -0
  67. package/dist/targets/adapters/github-copilot.js +61 -0
  68. package/dist/targets/adapters/hermes.d.ts +13 -0
  69. package/dist/targets/adapters/hermes.d.ts.map +1 -0
  70. package/dist/targets/adapters/hermes.js +96 -0
  71. package/dist/targets/adapters/hooks-utils.d.ts +12 -0
  72. package/dist/targets/adapters/hooks-utils.d.ts.map +1 -0
  73. package/dist/targets/adapters/hooks-utils.js +60 -0
  74. package/dist/targets/adapters/index.d.ts +27 -0
  75. package/dist/targets/adapters/index.d.ts.map +1 -0
  76. package/dist/targets/adapters/index.js +64 -0
  77. package/dist/targets/adapters/interface.d.ts +8 -0
  78. package/dist/targets/adapters/interface.d.ts.map +1 -0
  79. package/dist/targets/adapters/interface.js +2 -0
  80. package/dist/targets/adapters/oh-my-pi.d.ts +11 -0
  81. package/dist/targets/adapters/oh-my-pi.d.ts.map +1 -0
  82. package/dist/targets/adapters/oh-my-pi.js +88 -0
  83. package/dist/targets/adapters/openclaw.d.ts +14 -0
  84. package/dist/targets/adapters/openclaw.d.ts.map +1 -0
  85. package/dist/targets/adapters/openclaw.js +165 -0
  86. package/dist/targets/adapters/opencode.d.ts +10 -0
  87. package/dist/targets/adapters/opencode.d.ts.map +1 -0
  88. package/dist/targets/adapters/opencode.js +93 -0
  89. package/dist/targets/adapters/pi.d.ts +11 -0
  90. package/dist/targets/adapters/pi.d.ts.map +1 -0
  91. package/dist/targets/adapters/pi.js +90 -0
  92. package/dist/targets/index.d.ts +7 -0
  93. package/dist/targets/index.d.ts.map +1 -0
  94. package/dist/targets/index.js +77 -0
  95. package/dist/transform.d.ts +4 -0
  96. package/dist/transform.d.ts.map +1 -0
  97. package/dist/transform.js +243 -0
  98. package/dist/transformEmitters.d.ts +8 -0
  99. package/dist/transformEmitters.d.ts.map +1 -0
  100. package/dist/transformEmitters.js +340 -0
  101. package/dist/transformHelpers.d.ts +13 -0
  102. package/dist/transformHelpers.d.ts.map +1 -0
  103. package/dist/transformHelpers.js +239 -0
  104. package/dist/types.d.ts +204 -0
  105. package/dist/types.d.ts.map +1 -0
  106. package/dist/types.js +2 -0
  107. package/dist/utils.d.ts +42 -0
  108. package/dist/utils.d.ts.map +1 -0
  109. package/dist/utils.js +187 -0
  110. package/dist/validate.d.ts +3 -0
  111. package/dist/validate.d.ts.map +1 -0
  112. package/dist/validate.js +188 -0
  113. package/dist/verify.d.ts +6 -0
  114. package/dist/verify.d.ts.map +1 -0
  115. package/dist/verify.js +294 -0
  116. package/package.json +68 -0
@@ -0,0 +1,150 @@
1
+ // Unified installation instructions generator for all targets
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { resolveSdkConfig, resolveTargetCliName, resolveTargetNpmPackageName, } from './sdkConfig.js';
5
+ export function generateInstallInstructions(manifest, targetProfile, sourceDir) {
6
+ // If a README.template.md exists in the source dir, use it
7
+ if (sourceDir) {
8
+ const templatePath = path.join(sourceDir, 'README.template.md');
9
+ if (fs.existsSync(templatePath)) {
10
+ return renderTemplate(fs.readFileSync(templatePath, 'utf-8'), manifest, targetProfile);
11
+ }
12
+ }
13
+ return renderDefault(manifest, targetProfile);
14
+ }
15
+ function renderTemplate(template, manifest, targetProfile) {
16
+ const sdk = resolveSdkConfig(manifest);
17
+ const npmPkg = resolveTargetNpmPackageName(manifest, targetProfile);
18
+ const cliName = resolveTargetCliName(manifest, targetProfile);
19
+ const skillNames = manifest.skills
20
+ ? manifest.skills.map(s => s.name).join(', ')
21
+ : 'none';
22
+ const hookNames = manifest.hooks
23
+ ? Object.keys(manifest.hooks)
24
+ .filter(h => {
25
+ const val = manifest.hooks[h];
26
+ if (val === null)
27
+ return false;
28
+ return targetProfile.supportedHooks.has(h);
29
+ })
30
+ .join(', ')
31
+ : 'none';
32
+ const commandList = getCommandNames(manifest).join(', ') || 'none';
33
+ const hasBinScripts = targetProfile.distribution === 'npm-cli' || targetProfile.distribution === 'both';
34
+ const hasExtension = targetProfile.adapterFamily === 'programmatic';
35
+ let installInstructions;
36
+ switch (targetProfile.distribution) {
37
+ case 'marketplace':
38
+ installInstructions = generateMarketplaceBlock(targetProfile, sdk.cli);
39
+ break;
40
+ case 'npm-cli':
41
+ installInstructions = generateNpmCliBlock(targetProfile, npmPkg, cliName);
42
+ break;
43
+ case 'both':
44
+ installInstructions = `### Option 1: Marketplace (Recommended)\n\n${generateMarketplaceBlock(targetProfile, sdk.cli)}\n\n### Option 2: npm Install\n\n${generateNpmCliBlock(targetProfile, npmPkg, cliName)}`;
45
+ break;
46
+ }
47
+ let verifyCommands = '';
48
+ if (targetProfile.npmPublishable) {
49
+ verifyCommands += `npm ls -g ${npmPkg} --depth=0\n`;
50
+ }
51
+ verifyCommands += `${sdk.cli} harness:discover --json | grep ${targetProfile.adapterName}`;
52
+ let result = template;
53
+ result = result.replace(/\{\{name\}\}/g, manifest.name);
54
+ result = result.replace(/\{\{description\}\}/g, manifest.description);
55
+ result = result.replace(/\{\{targetDisplayName\}\}/g, targetProfile.displayName);
56
+ result = result.replace(/\{\{installInstructions\}\}/g, installInstructions);
57
+ result = result.replace(/\{\{skillNames\}\}/g, skillNames);
58
+ result = result.replace(/\{\{hookNames\}\}/g, hookNames);
59
+ result = result.replace(/\{\{commandList\}\}/g, commandList);
60
+ result = result.replace(/\{\{verifyCommands\}\}/g, verifyCommands);
61
+ // Conditional blocks: {{#if flag}}...{{/if}}
62
+ result = replaceConditional(result, 'hasBinScripts', hasBinScripts);
63
+ result = replaceConditional(result, 'hasExtension', hasExtension);
64
+ return result;
65
+ }
66
+ function replaceConditional(text, flag, value) {
67
+ const pattern = new RegExp(`\\{\\{#if ${flag}\\}\\}([\\s\\S]*?)\\{\\{/if\\}\\}`, 'g');
68
+ return text.replace(pattern, value ? '$1' : '');
69
+ }
70
+ function getCommandNames(manifest) {
71
+ if (!manifest.commands)
72
+ return [];
73
+ if (typeof manifest.commands === 'string')
74
+ return ['(directory)'];
75
+ return manifest.commands.map(c => c.replace(/\.md$/, ''));
76
+ }
77
+ function generateMarketplaceBlock(targetProfile, sdkCli) {
78
+ return `\`\`\`bash\n${sdkCli} harness:install-plugin ${targetProfile.name}\n\`\`\``;
79
+ }
80
+ function generateNpmCliBlock(targetProfile, npmPkg, cliName) {
81
+ const lines = [
82
+ '```bash',
83
+ `npm install -g ${npmPkg}`,
84
+ `${cliName} install --global`,
85
+ '```',
86
+ '',
87
+ ];
88
+ if (targetProfile.packageMetadata?.activationMessage === 'codex-open-plugins') {
89
+ lines.push('Then open Codex and navigate to `/plugins` to activate the plugin.');
90
+ }
91
+ else {
92
+ lines.push(`Restart ${targetProfile.displayName} to pick up the installed plugin.`);
93
+ }
94
+ return lines.join('\n');
95
+ }
96
+ function renderDefault(manifest, targetProfile) {
97
+ const sdk = resolveSdkConfig(manifest);
98
+ const npmPkg = resolveTargetNpmPackageName(manifest, targetProfile);
99
+ const cliName = resolveTargetCliName(manifest, targetProfile);
100
+ const sections = [];
101
+ sections.push(`# ${manifest.name} — ${targetProfile.displayName} Plugin`);
102
+ sections.push('');
103
+ sections.push(manifest.description);
104
+ sections.push('');
105
+ sections.push('## Prerequisites');
106
+ sections.push('');
107
+ sections.push('Install the SDK CLI:');
108
+ sections.push('');
109
+ sections.push('```bash');
110
+ sections.push(`npm install -g ${sdk.package}`);
111
+ sections.push('```');
112
+ sections.push('');
113
+ sections.push('## Installation');
114
+ sections.push('');
115
+ switch (targetProfile.distribution) {
116
+ case 'marketplace':
117
+ sections.push(generateMarketplaceBlock(targetProfile, sdk.cli));
118
+ break;
119
+ case 'npm-cli':
120
+ sections.push(generateNpmCliBlock(targetProfile, npmPkg, cliName));
121
+ break;
122
+ case 'both':
123
+ sections.push('### Option 1: Marketplace (Recommended)');
124
+ sections.push('');
125
+ sections.push(generateMarketplaceBlock(targetProfile, sdk.cli));
126
+ sections.push('');
127
+ sections.push('### Option 2: npm Install');
128
+ sections.push('');
129
+ sections.push(generateNpmCliBlock(targetProfile, npmPkg, cliName));
130
+ break;
131
+ }
132
+ sections.push('');
133
+ if (targetProfile.npmPublishable) {
134
+ sections.push('### Workspace Install');
135
+ sections.push('');
136
+ sections.push('```bash');
137
+ sections.push(`npx -y ${npmPkg} install --workspace .`);
138
+ sections.push('```');
139
+ sections.push('');
140
+ }
141
+ sections.push('## Verification');
142
+ sections.push('');
143
+ sections.push('```bash');
144
+ if (targetProfile.npmPublishable) {
145
+ sections.push(`npm ls -g ${npmPkg} --depth=0`);
146
+ }
147
+ sections.push(`${sdk.cli} harness:discover --json | grep ${targetProfile.adapterName}`);
148
+ sections.push('```');
149
+ return sections.join('\n');
150
+ }
@@ -0,0 +1,3 @@
1
+ import type { A5cPluginManifest, TargetProfile } from './types.js';
2
+ export declare function generateInstallShared(manifest: A5cPluginManifest, targetProfile: TargetProfile, sourceDir?: string): string;
3
+ //# sourceMappingURL=installSharedGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installSharedGenerator.d.ts","sourceRoot":"","sources":["../src/installSharedGenerator.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA4BnE,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA4MR"}
@@ -0,0 +1,229 @@
1
+ // Generator for install-shared — generic plugin installation infrastructure.
2
+ // Only contains utilities any plugin would need: file ops, marketplace
3
+ // management, per-harness plugin paths.
4
+ // SDK-specific concepts (global state dirs, CLI resolution, process libraries)
5
+ // are provided by the plugin author via the manifest's `installSurface` field.
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { resolveSdkConfig } from './sdkConfig.js';
9
+ import { resolveHarnessInstallSurfaceExports } from './transformHelpers.js';
10
+ function getHomeDirCode(targetProfile, stateDir) {
11
+ const harnessHomeRelative = targetProfile.installLayout?.harnessHomeRelative;
12
+ if (!harnessHomeRelative) {
13
+ return `path.join(os.homedir(), '${stateDir}')`;
14
+ }
15
+ return `path.join(os.homedir(), ${JSON.stringify(harnessHomeRelative)})`;
16
+ }
17
+ function getPluginsDirCode(targetProfile) {
18
+ const pluginsDirRelative = targetProfile.installLayout?.pluginsDirRelative;
19
+ if (!pluginsDirRelative) {
20
+ return `path.join(getHarnessHome(), 'plugins')`;
21
+ }
22
+ return `path.join(os.homedir(), ${JSON.stringify(pluginsDirRelative)})`;
23
+ }
24
+ function getMarketplacePathCode(targetProfile) {
25
+ const marketplacePathRelative = targetProfile.installLayout?.marketplacePathRelative;
26
+ if (!marketplacePathRelative) {
27
+ return `path.join(getHarnessHome(), 'plugins', 'marketplace.json')`;
28
+ }
29
+ return `path.join(os.homedir(), ${JSON.stringify(marketplacePathRelative)})`;
30
+ }
31
+ export function generateInstallShared(manifest, targetProfile, sourceDir) {
32
+ const pluginName = manifest.name;
33
+ const sdk = resolveSdkConfig(manifest);
34
+ const authorName = typeof manifest.author === 'string' ? manifest.author : manifest.author.name;
35
+ const homeDirCode = getHomeDirCode(targetProfile, sdk.stateDir);
36
+ const pluginsDirCode = getPluginsDirCode(targetProfile);
37
+ const marketplacePathCode = getMarketplacePathCode(targetProfile);
38
+ const base = `'use strict';
39
+
40
+ const fs = require('fs');
41
+ const os = require('os');
42
+ const path = require('path');
43
+ const { spawnSync } = require('child_process');
44
+
45
+ const PLUGIN_NAME = ${JSON.stringify(pluginName)};
46
+ const PLUGIN_CATEGORY = 'Coding';
47
+
48
+ function getUserHome() {
49
+ return os.homedir();
50
+ }
51
+
52
+ function getHarnessHome() {
53
+ return ${homeDirCode};
54
+ }
55
+
56
+ function getHomePluginRoot(scope) {
57
+ if (scope === 'workspace') return path.join(process.cwd(), '${sdk.stateDir}', 'plugins', PLUGIN_NAME);
58
+ return path.join(${pluginsDirCode}, PLUGIN_NAME);
59
+ }
60
+
61
+ function getHomeMarketplacePath() {
62
+ return ${marketplacePathCode};
63
+ }
64
+
65
+ function writeFileIfChanged(filePath, contents) {
66
+ try {
67
+ const existing = fs.readFileSync(filePath, 'utf8');
68
+ if (existing === contents) return false;
69
+ } catch {}
70
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
71
+ fs.writeFileSync(filePath, contents);
72
+ return true;
73
+ }
74
+
75
+ function copyRecursive(src, dest) {
76
+ fs.mkdirSync(dest, { recursive: true });
77
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
78
+ if (entry.name === 'node_modules' || entry.name === '.git') continue;
79
+ const s = path.join(src, entry.name);
80
+ const d = path.join(dest, entry.name);
81
+ if (entry.isDirectory()) {
82
+ copyRecursive(s, d);
83
+ } else {
84
+ fs.copyFileSync(s, d);
85
+ }
86
+ }
87
+ }
88
+
89
+ function copyPluginBundle(packageRoot, pluginRoot) {
90
+ const bundleEntries = fs.readdirSync(packageRoot).filter(
91
+ e => !['node_modules', '.git', 'test', 'dist'].includes(e)
92
+ );
93
+ fs.mkdirSync(pluginRoot, { recursive: true });
94
+ for (const entry of bundleEntries) {
95
+ const src = path.join(packageRoot, entry);
96
+ const dest = path.join(pluginRoot, entry);
97
+ const stat = fs.statSync(src);
98
+ if (stat.isDirectory()) {
99
+ copyRecursive(src, dest);
100
+ } else {
101
+ fs.copyFileSync(src, dest);
102
+ }
103
+ }
104
+ }
105
+
106
+ function readJson(filePath) {
107
+ try {
108
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
109
+ } catch {
110
+ return null;
111
+ }
112
+ }
113
+
114
+ function writeJson(filePath, value) {
115
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
116
+ fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\\n');
117
+ }
118
+
119
+ function ensureExecutable(filePath) {
120
+ try {
121
+ fs.chmodSync(filePath, 0o755);
122
+ } catch {}
123
+ }
124
+
125
+ function normalizeMarketplaceSourcePath(source, marketplacePath) {
126
+ if (typeof source === 'string') {
127
+ return path.relative(path.dirname(marketplacePath), source).replace(/\\\\/g, '/');
128
+ }
129
+ return source;
130
+ }
131
+
132
+ function ensureMarketplaceEntry(marketplacePath, pluginRoot) {
133
+ let marketplace = readJson(marketplacePath) || {
134
+ name: ${JSON.stringify(authorName)},
135
+ plugins: [],
136
+ };
137
+ if (!Array.isArray(marketplace.plugins)) marketplace.plugins = [];
138
+ const idx = marketplace.plugins.findIndex(p => p.name === PLUGIN_NAME);
139
+ const relSource = './' + normalizeMarketplaceSourcePath(pluginRoot, marketplacePath);
140
+ const entry = {
141
+ name: PLUGIN_NAME,
142
+ source: relSource,
143
+ description: ${JSON.stringify(manifest.description)},
144
+ version: ${JSON.stringify(manifest.version)},
145
+ author: { name: ${JSON.stringify(authorName)} },
146
+ };
147
+ if (idx >= 0) marketplace.plugins[idx] = entry;
148
+ else marketplace.plugins.push(entry);
149
+ writeJson(marketplacePath, marketplace);
150
+ }
151
+
152
+ function removeMarketplaceEntry(marketplacePath) {
153
+ const marketplace = readJson(marketplacePath);
154
+ if (!marketplace || !Array.isArray(marketplace.plugins)) return;
155
+ marketplace.plugins = marketplace.plugins.filter(p => p.name !== PLUGIN_NAME);
156
+ writeJson(marketplacePath, marketplace);
157
+ }
158
+
159
+ function warnWindowsHooks() {
160
+ if (process.platform === 'win32') {
161
+ console.warn('[' + PLUGIN_NAME + '] Windows detected — shell hooks (.sh) require Git Bash or WSL.');
162
+ }
163
+ }
164
+
165
+ function runPostInstall(pluginRoot) {
166
+ const postInstall = path.join(pluginRoot, 'scripts', 'post-install.js');
167
+ if (fs.existsSync(postInstall)) {
168
+ spawnSync(process.execPath, [postInstall], {
169
+ cwd: pluginRoot, stdio: 'inherit',
170
+ env: { ...process.env, PLUGIN_ROOT: pluginRoot },
171
+ });
172
+ }
173
+ }
174
+ `;
175
+ const baseExports = [
176
+ 'PLUGIN_NAME',
177
+ 'PLUGIN_CATEGORY',
178
+ 'getUserHome',
179
+ 'getHarnessHome',
180
+ 'getHomePluginRoot',
181
+ 'getHomeMarketplacePath',
182
+ 'writeFileIfChanged',
183
+ 'copyRecursive',
184
+ 'copyPluginBundle',
185
+ 'readJson',
186
+ 'writeJson',
187
+ 'ensureExecutable',
188
+ 'normalizeMarketplaceSourcePath',
189
+ 'ensureMarketplaceEntry',
190
+ 'removeMarketplaceEntry',
191
+ 'warnWindowsHooks',
192
+ 'runPostInstall',
193
+ ];
194
+ // Read plugin-specific surface (SDK concepts: global state, CLI resolution, etc.)
195
+ let sdkSurface = '';
196
+ const surfaceExports = [];
197
+ if (sourceDir && manifest.installSurface) {
198
+ const surfacePath = path.join(sourceDir, manifest.installSurface);
199
+ if (fs.existsSync(surfacePath)) {
200
+ sdkSurface = fs.readFileSync(surfacePath, 'utf-8');
201
+ }
202
+ if (manifest.installSurfaceExports) {
203
+ surfaceExports.push(...manifest.installSurfaceExports);
204
+ }
205
+ }
206
+ // Read per-harness surface (harness-specific installation logic)
207
+ let harnessSurface = '';
208
+ const harnessSurfaceExports = resolveHarnessInstallSurfaceExports(manifest, targetProfile);
209
+ const override = manifest.targets?.[targetProfile.name];
210
+ if (sourceDir && override?.harnessInstallSurface) {
211
+ const surfacePath = path.join(sourceDir, override.harnessInstallSurface);
212
+ if (fs.existsSync(surfacePath)) {
213
+ harnessSurface = fs.readFileSync(surfacePath, 'utf-8');
214
+ }
215
+ }
216
+ // Deduplicate: per-harness exports override base/SDK exports of the same name
217
+ const overrideSet = new Set([...surfaceExports, ...harnessSurfaceExports]);
218
+ const dedupedBase = baseExports.filter(e => !overrideSet.has(e));
219
+ const allExports = [...dedupedBase, ...surfaceExports, ...harnessSurfaceExports];
220
+ const exportsBlock = `\nmodule.exports = {\n ${allExports.join(',\n ')},\n};\n`;
221
+ let result = base;
222
+ if (sdkSurface) {
223
+ result += '\n' + sdkSurface + '\n';
224
+ }
225
+ if (harnessSurface) {
226
+ result += '\n' + harnessSurface + '\n';
227
+ }
228
+ return result + exportsBlock;
229
+ }
@@ -0,0 +1,10 @@
1
+ export { generateClaudeCodeManifest } from './targets/adapters/claude-code.js';
2
+ export { generateCodexManifest } from './targets/adapters/codex.js';
3
+ export { generateCursorManifest } from './targets/adapters/cursor.js';
4
+ export { generateGeminiManifest } from './targets/adapters/gemini.js';
5
+ export { generateGithubCopilotManifest } from './targets/adapters/github-copilot.js';
6
+ export { generatePiManifest } from './targets/adapters/pi.js';
7
+ export { generateOhMyPiManifest } from './targets/adapters/oh-my-pi.js';
8
+ export { generateOpenCodeManifest } from './targets/adapters/opencode.js';
9
+ export { generateOpenClawPackageManifest, generateOpenClawManifest } from './targets/adapters/openclaw.js';
10
+ //# sourceMappingURL=manifestGenerators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestGenerators.d.ts","sourceRoot":"","sources":["../src/manifestGenerators.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,11 @@
1
+ // Manifest generators for all targets
2
+ // This is a thin re-export shell — actual implementations live in targets/adapters/
3
+ export { generateClaudeCodeManifest } from './targets/adapters/claude-code.js';
4
+ export { generateCodexManifest } from './targets/adapters/codex.js';
5
+ export { generateCursorManifest } from './targets/adapters/cursor.js';
6
+ export { generateGeminiManifest } from './targets/adapters/gemini.js';
7
+ export { generateGithubCopilotManifest } from './targets/adapters/github-copilot.js';
8
+ export { generatePiManifest } from './targets/adapters/pi.js';
9
+ export { generateOhMyPiManifest } from './targets/adapters/oh-my-pi.js';
10
+ export { generateOpenCodeManifest } from './targets/adapters/opencode.js';
11
+ export { generateOpenClawPackageManifest, generateOpenClawManifest } from './targets/adapters/openclaw.js';
@@ -0,0 +1,3 @@
1
+ import type { A5cPluginManifest, TargetProfile } from './types.js';
2
+ export declare function generateMarketplaceJson(manifest: A5cPluginManifest, targetProfile: TargetProfile, pluginOutputDir: string, outputBaseDir: string): string;
3
+ //# sourceMappingURL=marketplaceGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplaceGenerator.d.ts","sourceRoot":"","sources":["../src/marketplaceGenerator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnE,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACpB,MAAM,CA4CR"}
@@ -0,0 +1,46 @@
1
+ // Marketplace file generator
2
+ // Generates marketplace.json for targets that use marketplace distribution
3
+ import * as path from 'path';
4
+ export function generateMarketplaceJson(manifest, targetProfile, pluginOutputDir, outputBaseDir) {
5
+ const authorName = typeof manifest.author === 'string'
6
+ ? manifest.author
7
+ : manifest.author.name;
8
+ const relativePluginPath = path.relative(outputBaseDir, pluginOutputDir).replace(/\\/g, '/');
9
+ const pluginSourcePath = relativePluginPath.startsWith('.')
10
+ ? relativePluginPath
11
+ : `./${relativePluginPath}`;
12
+ if (targetProfile.packageMetadata?.activationMessage === 'codex-open-plugins') {
13
+ return JSON.stringify({
14
+ name: `${manifest.name}-local`,
15
+ interface: {
16
+ displayName: `${manifest.name.charAt(0).toUpperCase() + manifest.name.slice(1)} Local`,
17
+ },
18
+ plugins: [{
19
+ name: manifest.name,
20
+ source: {
21
+ source: 'local',
22
+ path: pluginSourcePath,
23
+ },
24
+ policy: {
25
+ installation: 'AVAILABLE',
26
+ authentication: 'ON_INSTALL',
27
+ },
28
+ category: 'Coding',
29
+ }],
30
+ }, null, 2) + '\n';
31
+ }
32
+ return JSON.stringify({
33
+ name: authorName,
34
+ owner: {
35
+ name: authorName,
36
+ email: `support@${authorName}`,
37
+ },
38
+ plugins: [{
39
+ name: manifest.name,
40
+ source: pluginSourcePath,
41
+ description: manifest.description,
42
+ version: manifest.version,
43
+ author: { name: authorName },
44
+ }],
45
+ }, null, 2) + '\n';
46
+ }
@@ -0,0 +1,10 @@
1
+ import type { TargetProfile } from './types.js';
2
+ export declare function generateProgrammaticExtension(manifest: {
3
+ name: string;
4
+ skills?: Array<{
5
+ name: string;
6
+ }>;
7
+ commands?: string[] | string;
8
+ hooks?: Record<string, string | boolean | null>;
9
+ }, targetProfile: TargetProfile, commandPaths?: string[]): string;
10
+ //# sourceMappingURL=proxiedHookTemplates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxiedHookTemplates.d.ts","sourceRoot":"","sources":["../src/proxiedHookTemplates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAA;CAAE,EAC3I,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,MAAM,CAuGR"}
@@ -0,0 +1,122 @@
1
+ // Programmatic extension templates for non-shell-hook targets (Pi, oh-my-pi, etc.)
2
+ function commandNameFromPath(cmdPath) {
3
+ const normalized = cmdPath.replace(/\\/g, '/');
4
+ return normalized.replace(/^.*\//, '').replace(/\.md$/, '');
5
+ }
6
+ export function generateProgrammaticExtension(manifest, targetProfile, commandPaths) {
7
+ const piPackage = targetProfile.packageMetadata?.peerDependencyPackage ?? null;
8
+ const pluginRootEnvVar = targetProfile.pluginRootEnvVarForExtension || 'PLUGIN_ROOT';
9
+ const commandNameSet = new Set();
10
+ const primaryName = manifest.name;
11
+ const excludeNames = new Set([primaryName]);
12
+ if (manifest.skills && Array.isArray(manifest.skills)) {
13
+ for (const skill of manifest.skills) {
14
+ if (!excludeNames.has(skill.name)) {
15
+ commandNameSet.add(skill.name);
16
+ }
17
+ }
18
+ }
19
+ if (commandPaths) {
20
+ for (const cmdPath of commandPaths) {
21
+ const name = commandNameFromPath(cmdPath);
22
+ if (!excludeNames.has(name)) {
23
+ commandNameSet.add(name);
24
+ }
25
+ }
26
+ }
27
+ const commandNames = Array.from(commandNameSet).sort();
28
+ let sessionStartCall = '';
29
+ if (manifest.hooks) {
30
+ const ssHandler = manifest.hooks.SessionStart;
31
+ if (typeof ssHandler === 'string' && ssHandler !== 'proxy') {
32
+ const jsBridge = ssHandler.replace(/^hooks\//, '').replace(/\.sh$/, '.js');
33
+ sessionStartCall = `\n runProxiedHook("${jsBridge}", {\n event: "session_start",\n cwd: process.cwd(),\n });`;
34
+ }
35
+ }
36
+ if (!piPackage) {
37
+ return `// Programmatic extension for ${targetProfile.displayName}
38
+ // Generated by extension-mux compiler
39
+
40
+ import { execSync } from "child_process";
41
+ import * as path from "path";
42
+
43
+ const PLUGIN_ROOT = path.resolve(__dirname, "..");
44
+
45
+ ${generateRunProxiedHookFunction(pluginRootEnvVar)}
46
+
47
+ const COMMANDS = [
48
+ ${commandNames.map((n) => `"${n}"`).join(', ')}
49
+ ] as const;
50
+
51
+ export function activate(api: unknown): void {${sessionStartCall}
52
+ // Register commands via target-specific API
53
+ }
54
+ `;
55
+ }
56
+ return `import type { ExtensionAPI } from "${piPackage}";
57
+ import { execSync } from "child_process";
58
+ import * as path from "path";
59
+
60
+ const PLUGIN_ROOT = path.resolve(__dirname, "..");
61
+
62
+ const COMMANDS = [
63
+ ${commandNames.map((n) => `"${n}"`).join(', ')}
64
+ ] as const;
65
+
66
+ function toSkillPrompt(name: string, args: string): string {
67
+ return \`/skill:\${name}\${args ? \` \${args}\` : ""}\`;
68
+ }
69
+
70
+ ${generateRunProxiedHookFunction(pluginRootEnvVar)}
71
+
72
+ export default function activate(pi: ExtensionAPI): void {${sessionStartCall}
73
+
74
+ const forwardPrimary = async (args: unknown) => {
75
+ pi.sendUserMessage(toSkillPrompt("${primaryName}", String(args ?? "").trim()));
76
+ };
77
+
78
+ pi.registerCommand("${primaryName}", {
79
+ description: "Load the ${primaryName} skill",
80
+ handler: forwardPrimary,
81
+ });
82
+
83
+ for (const name of COMMANDS) {
84
+ const forward = async (args: unknown) => {
85
+ pi.sendUserMessage(toSkillPrompt(name, String(args ?? "").trim()));
86
+ };
87
+
88
+ pi.registerCommand(name, {
89
+ description: \`Open the \${name} skill\`,
90
+ handler: forward,
91
+ });
92
+
93
+ pi.registerCommand(\`${primaryName}:\${name}\`, {
94
+ description: \`Alias for /\${name}\`,
95
+ handler: forward,
96
+ });
97
+ }
98
+ }
99
+ `;
100
+ }
101
+ function generateRunProxiedHookFunction(pluginRootEnvVar) {
102
+ return `function runProxiedHook(
103
+ scriptName: string,
104
+ inputData?: Record<string, unknown>
105
+ ): Record<string, unknown> {
106
+ const scriptPath = path.join(PLUGIN_ROOT, "hooks", scriptName);
107
+ try {
108
+ const result = execSync(\`node "\${scriptPath}"\`, {
109
+ input: inputData ? JSON.stringify(inputData) : undefined,
110
+ stdio: ["pipe", "pipe", "pipe"],
111
+ timeout: 30000,
112
+ env: {
113
+ ...process.env,
114
+ ${pluginRootEnvVar}: PLUGIN_ROOT,
115
+ },
116
+ });
117
+ return JSON.parse(result.toString("utf8").trim());
118
+ } catch {
119
+ return {};
120
+ }
121
+ }`;
122
+ }
@@ -0,0 +1,3 @@
1
+ import type { A5cPluginManifest, ResolveResult } from './types.js';
2
+ export declare function resolve(manifest: A5cPluginManifest, targetName: string): ResolveResult;
3
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EAGd,MAAM,YAAY,CAAC;AAIpB,wBAAgB,OAAO,CACrB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,MAAM,GACjB,aAAa,CAkHf"}