@unextension/cli 0.0.0 → 0.1.0

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 (94) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +15 -0
  4. package/dist/__tests__/config.test.d.ts +2 -0
  5. package/dist/__tests__/config.test.d.ts.map +1 -0
  6. package/dist/__tests__/config.test.js +39 -0
  7. package/dist/__tests__/config.test.js.map +1 -0
  8. package/dist/__tests__/shared.test.d.ts +2 -0
  9. package/dist/__tests__/shared.test.d.ts.map +1 -0
  10. package/dist/__tests__/shared.test.js +42 -0
  11. package/dist/__tests__/shared.test.js.map +1 -0
  12. package/dist/build.d.ts +2 -0
  13. package/dist/build.d.ts.map +1 -0
  14. package/dist/build.js +47 -0
  15. package/dist/build.js.map +1 -0
  16. package/dist/cli.d.ts +3 -0
  17. package/dist/cli.d.ts.map +1 -0
  18. package/dist/cli.js +35 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/commands/build.d.ts +2 -0
  21. package/dist/commands/build.d.ts.map +1 -0
  22. package/dist/commands/build.js +60 -0
  23. package/dist/commands/build.js.map +1 -0
  24. package/dist/commands/dev.d.ts +2 -0
  25. package/dist/commands/dev.d.ts.map +1 -0
  26. package/dist/commands/dev.js +113 -0
  27. package/dist/commands/dev.js.map +1 -0
  28. package/dist/commands/init.d.ts +2 -0
  29. package/dist/commands/init.d.ts.map +1 -0
  30. package/dist/commands/init.js +94 -0
  31. package/dist/commands/init.js.map +1 -0
  32. package/dist/commands/sync.d.ts +2 -0
  33. package/dist/commands/sync.d.ts.map +1 -0
  34. package/dist/commands/sync.js +16 -0
  35. package/dist/commands/sync.js.map +1 -0
  36. package/dist/config.d.ts +100 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +4 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/index.d.ts +3 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +2 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/init.d.ts +2 -0
  45. package/dist/init.d.ts.map +1 -0
  46. package/dist/init.js +52 -0
  47. package/dist/init.js.map +1 -0
  48. package/dist/loader.d.ts +3 -0
  49. package/dist/loader.d.ts.map +1 -0
  50. package/dist/loader.js +28 -0
  51. package/dist/loader.js.map +1 -0
  52. package/dist/targets/jetbrains/actions/ListProjectFiles.kt +19 -0
  53. package/dist/targets/jetbrains/actions/Notify.kt +18 -0
  54. package/dist/targets/jetbrains/actions/ReadProjectFile.kt +12 -0
  55. package/dist/targets/jetbrains/actions/RunCommand.kt +25 -0
  56. package/dist/targets/jetbrains/actions/RunScript.kt +57 -0
  57. package/dist/targets/jetbrains/actions/WriteProjectFile.kt +16 -0
  58. package/dist/targets/jetbrains/actions.d.ts +8 -0
  59. package/dist/targets/jetbrains/actions.d.ts.map +1 -0
  60. package/dist/targets/jetbrains/actions.js +39 -0
  61. package/dist/targets/jetbrains/actions.js.map +1 -0
  62. package/dist/targets/jetbrains/index.d.ts +3 -0
  63. package/dist/targets/jetbrains/index.d.ts.map +1 -0
  64. package/dist/targets/jetbrains/index.js +202 -0
  65. package/dist/targets/jetbrains/index.js.map +1 -0
  66. package/dist/targets/jetbrains/toolwindow.d.ts +2 -0
  67. package/dist/targets/jetbrains/toolwindow.d.ts.map +1 -0
  68. package/dist/targets/jetbrains/toolwindow.js +162 -0
  69. package/dist/targets/jetbrains/toolwindow.js.map +1 -0
  70. package/dist/targets/shared.d.ts +5 -0
  71. package/dist/targets/shared.d.ts.map +1 -0
  72. package/dist/targets/shared.js +23 -0
  73. package/dist/targets/shared.js.map +1 -0
  74. package/dist/targets/vscode/actions/globals.js +23 -0
  75. package/dist/targets/vscode/actions/jsconfig.json +11 -0
  76. package/dist/targets/vscode/actions/list-project-files.js +27 -0
  77. package/dist/targets/vscode/actions/notify.js +17 -0
  78. package/dist/targets/vscode/actions/read-project-file.js +24 -0
  79. package/dist/targets/vscode/actions/run-command.js +42 -0
  80. package/dist/targets/vscode/actions/run-script.js +39 -0
  81. package/dist/targets/vscode/actions/write-project-file.js +24 -0
  82. package/dist/targets/vscode/actions.d.ts +2 -0
  83. package/dist/targets/vscode/actions.d.ts.map +1 -0
  84. package/dist/targets/vscode/actions.js +40 -0
  85. package/dist/targets/vscode/actions.js.map +1 -0
  86. package/dist/targets/vscode/extension.d.ts +3 -0
  87. package/dist/targets/vscode/extension.d.ts.map +1 -0
  88. package/dist/targets/vscode/extension.js +107 -0
  89. package/dist/targets/vscode/extension.js.map +1 -0
  90. package/dist/targets/vscode/index.d.ts +3 -0
  91. package/dist/targets/vscode/index.d.ts.map +1 -0
  92. package/dist/targets/vscode/index.js +99 -0
  93. package/dist/targets/vscode/index.js.map +1 -0
  94. package/package.json +44 -2
@@ -0,0 +1,100 @@
1
+ export interface JetBrainsConfig {
2
+ /** Open Chrome DevTools automatically (set internally by `unextension dev`) */
3
+ _devMode?: boolean;
4
+ /** Download the Gradle wrapper jar during sync (default: true) */
5
+ downloadGradleWrapper?: boolean;
6
+ /** IntelliJ IDEA Community version to build against (default: '2024.3') */
7
+ ideVersion?: string;
8
+ /** Gradle version for the wrapper (default: '8.7') */
9
+ gradleVersion?: string;
10
+ /** org.jetbrains.kotlin.jvm plugin version (default: '2.1.0') */
11
+ kotlinVersion?: string;
12
+ /** org.jetbrains.intellij.platform plugin version (default: '2.2.1') */
13
+ intellijPlatformVersion?: string;
14
+ /** JVM toolchain version (default: 21) */
15
+ jvmTarget?: number;
16
+ /** Gradle group id (default: 'com.unextension') */
17
+ group?: string;
18
+ /**
19
+ * Maximum IDE build number the plugin is compatible with.
20
+ * Set to a specific build (e.g. '251.*') to restrict compatibility.
21
+ * Set to null or omit to allow all future IDE versions (default: null — no upper bound).
22
+ */
23
+ untilBuild?: string | null;
24
+ }
25
+ export interface VSCodeConfig {
26
+ /** Minimum VS Code engine version (default: '>=1.85.0') */
27
+ engineVersion?: string;
28
+ /** @types/vscode version (default: '^1.85.0') */
29
+ typesVscodeVersion?: string;
30
+ /** @vscode/vsce version (default: '^3.0.0') */
31
+ vsceVersion?: string;
32
+ }
33
+ export type ViewLocation = 'sidebar' | 'panel' | 'editor';
34
+ export interface ViewConfig {
35
+ /** Unique identifier for this view (kebab-case) */
36
+ id: string;
37
+ /** Human-readable title shown in the IDE */
38
+ title: string;
39
+ /** Web route pattern this view should load, e.g. '/toolbar' or '/toolbar/*' */
40
+ route: string;
41
+ /** Where to place the view in the IDE (default: 'sidebar') */
42
+ location?: ViewLocation;
43
+ /** Path to an SVG icon file relative to the project root. If omitted a default icon is generated. */
44
+ icon?: string;
45
+ }
46
+ export interface UnextensionConfig {
47
+ /** Extension identifier (kebab-case) */
48
+ name: string;
49
+ /** Human-readable name */
50
+ displayName: string;
51
+ /** Semver version */
52
+ version: string;
53
+ /** Publisher name (required for VS Code Marketplace publishing) */
54
+ publisher?: string;
55
+ /** Short description */
56
+ description?: string;
57
+ /** Repository URL, e.g. 'https://github.com/user/repo' */
58
+ repository?: string;
59
+ /** License identifier, e.g. 'MIT' (default: 'MIT') */
60
+ license?: string;
61
+ /** Path to an SVG icon for the plugin/extension (used as JetBrains pluginIcon, VS Code activity bar icon) */
62
+ icon?: string;
63
+ /** Path to the built web app (default: './dist') */
64
+ distDir?: string;
65
+ /**
66
+ * Path to a folder of Node.js scripts that can be called from the webview via `runScript(name, payload)`.
67
+ * Scripts receive the payload as a parsed object and must export a default async function.
68
+ * They are copied to the extension output and executed in a sandboxed Node.js process.
69
+ */
70
+ scriptsDir?: string;
71
+ /**
72
+ * Enable SPA mode. All views share a single shell HTML; the active route is set via window.__UNEXTENSION_ROUTE__.
73
+ * - true: uses 'index.html' as the shell
74
+ * - { shellPath: '_shell.html' }: uses a custom shell file relative to distDir
75
+ */
76
+ spa?: boolean | {
77
+ shellPath: string;
78
+ };
79
+ /**
80
+ * Path to the SSR server entry relative to distDir (e.g. 'server/server.js').
81
+ * When set, the extension starts this server and loads views via http://localhost:serverPort.
82
+ * When omitted, the extension loads static files from distDir/client/index.html.
83
+ */
84
+ serverEntry?: string;
85
+ /**
86
+ * Port the SSR server listens on (default: 3000).
87
+ * Only used when serverEntry is set.
88
+ */
89
+ serverPort?: number;
90
+ /** Target platforms to generate */
91
+ targets?: Array<'vscode' | 'jetbrains'>;
92
+ /** IDE views / tool windows to register */
93
+ views?: ViewConfig[];
94
+ /** VS Code-specific options */
95
+ vscode?: VSCodeConfig;
96
+ /** JetBrains-specific options */
97
+ jetbrains?: JetBrainsConfig;
98
+ }
99
+ export declare function defineConfig(config: UnextensionConfig): UnextensionConfig;
100
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,OAAO,GACP,QAAQ,CAAA;AAEZ,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAA;IACV,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,qGAAqG;IACrG,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6GAA6G;IAC7G,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACrC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mCAAmC;IACnC,OAAO,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAA;IACvC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,iCAAiC;IACjC,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAEzE"}
package/dist/config.js ADDED
@@ -0,0 +1,4 @@
1
+ export function defineConfig(config) {
2
+ return config;
3
+ }
4
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAwGA,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { defineConfig } from './config.js';
2
+ export type { UnextensionConfig } from './config.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { defineConfig } from './config.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function init(cwd: string): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAGA,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,iBAmDrC"}
package/dist/init.js ADDED
@@ -0,0 +1,52 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+ export async function init(cwd) {
4
+ const pkgPath = path.join(cwd, 'package.json');
5
+ const hasTsConfig = await fs.pathExists(path.join(cwd, 'tsconfig.json'));
6
+ // Read name/version/description from package.json if available
7
+ let name = path.basename(cwd);
8
+ let version = '0.0.1';
9
+ let description = '';
10
+ if (await fs.pathExists(pkgPath)) {
11
+ const pkg = await fs.readJson(pkgPath);
12
+ if (pkg.name)
13
+ name = pkg.name.replace(/^@[^/]+\//, ''); // strip scope
14
+ if (pkg.version)
15
+ version = pkg.version;
16
+ if (pkg.description)
17
+ description = pkg.description;
18
+ }
19
+ const configFile = hasTsConfig ? 'unextension.config.ts' : 'unextension.config.js';
20
+ const configPath = path.join(cwd, configFile);
21
+ if (await fs.pathExists(configPath)) {
22
+ console.log(`\n⚠️ ${configFile} already exists, skipping.\n`);
23
+ return;
24
+ }
25
+ const configContent = hasTsConfig
26
+ ? `import { defineConfig } from 'unextension'\n\nexport default defineConfig({\n name: '${name}',\n displayName: '${toDisplayName(name)}',\n version: '${version}',\n description: '${description}',\n distDir: './dist',\n targets: ['vscode', 'jetbrains'],\n})\n`
27
+ : `import { defineConfig } from 'unextension'\n\nexport default defineConfig({\n name: '${name}',\n displayName: '${toDisplayName(name)}',\n version: '${version}',\n description: '${description}',\n distDir: './dist',\n targets: ['vscode', 'jetbrains'],\n})\n`;
28
+ await fs.writeFile(configPath, configContent);
29
+ console.log(`\n⚡ unextension init\n`);
30
+ console.log(` ✓ Created ${configFile}`);
31
+ // Add @types/vscode to devDependencies if not present
32
+ if (await fs.pathExists(pkgPath)) {
33
+ const pkg = await fs.readJson(pkgPath);
34
+ const devDeps = pkg.devDependencies || {};
35
+ let changed = false;
36
+ if (!devDeps['@types/vscode']) {
37
+ devDeps['@types/vscode'] = '^1.85.0';
38
+ changed = true;
39
+ }
40
+ if (changed) {
41
+ pkg.devDependencies = devDeps;
42
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
43
+ console.log(` ✓ Added @types/vscode to devDependencies in package.json`);
44
+ console.log(`\n Run your package manager install to install new dependencies.\n`);
45
+ }
46
+ }
47
+ console.log();
48
+ }
49
+ function toDisplayName(name) {
50
+ return name.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
51
+ }
52
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { UnextensionConfig } from './config.js';
2
+ export declare function loadConfig(cwd: string): Promise<UnextensionConfig>;
3
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAIpD,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2BxE"}
package/dist/loader.js ADDED
@@ -0,0 +1,28 @@
1
+ import { cosmiconfig } from 'cosmiconfig';
2
+ import { TypeScriptLoader } from 'cosmiconfig-typescript-loader';
3
+ const MODULE_NAME = 'unextension';
4
+ export async function loadConfig(cwd) {
5
+ const explorer = cosmiconfig(MODULE_NAME, {
6
+ searchPlaces: [
7
+ `${MODULE_NAME}.config.ts`,
8
+ `${MODULE_NAME}.config.js`,
9
+ `${MODULE_NAME}.config.mjs`,
10
+ `${MODULE_NAME}.config.json`,
11
+ `${MODULE_NAME}.config.yaml`,
12
+ `${MODULE_NAME}.config.yml`,
13
+ `.${MODULE_NAME}rc`,
14
+ `.${MODULE_NAME}rc.json`,
15
+ `.${MODULE_NAME}rc.yaml`,
16
+ 'package.json',
17
+ ],
18
+ loaders: {
19
+ '.ts': TypeScriptLoader(),
20
+ },
21
+ });
22
+ const result = await explorer.search(cwd);
23
+ if (!result || result.isEmpty) {
24
+ throw new Error(`No unextension config found. Create an unextension.config.ts in your project root.`);
25
+ }
26
+ return result.config;
27
+ }
28
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAGhE,MAAM,WAAW,GAAG,aAAa,CAAA;AAEjC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE;QACxC,YAAY,EAAE;YACZ,GAAG,WAAW,YAAY;YAC1B,GAAG,WAAW,YAAY;YAC1B,GAAG,WAAW,aAAa;YAC3B,GAAG,WAAW,cAAc;YAC5B,GAAG,WAAW,cAAc;YAC5B,GAAG,WAAW,aAAa;YAC3B,IAAI,WAAW,IAAI;YACnB,IAAI,WAAW,SAAS;YACxB,IAAI,WAAW,SAAS;YACxB,cAAc;SACf;QACD,OAAO,EAAE;YACP,KAAK,EAAE,gBAAgB,EAAE;SAC1B;KACF,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACzC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAA;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAA2B,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,19 @@
1
+ fun handleListProjectFiles(payload: org.json.JSONObject?, reply: org.json.JSONObject) {
2
+ val projectPath = com.intellij.openapi.project.ProjectManager.getInstance().openProjects.firstOrNull()?.basePath ?: ""
3
+ val pattern = payload?.optString("pattern", "**/*") ?: "**/*"
4
+ val extFilter = Regex("""\*\*\/\*\.([a-zA-Z0-9]+)$""").find(pattern)?.groupValues?.get(1)
5
+ val files = if (projectPath.isNotEmpty()) {
6
+ val root = java.io.File(projectPath)
7
+ root.walkTopDown()
8
+ .onEnter { dir ->
9
+ val name = dir.name
10
+ name != "node_modules" && name != ".git" && name != ".idea" &&
11
+ name != ".gradle" && name != "build" && name != "out"
12
+ }
13
+ .filter { it.isFile && (extFilter == null || it.extension == extFilter) }
14
+ .map { it.relativeTo(root).path.replace("\\", "/") }
15
+ .toList()
16
+ } else emptyList()
17
+ reply.put("type", "list-project-files:reply")
18
+ reply.put("payload", org.json.JSONArray(files))
19
+ }
@@ -0,0 +1,18 @@
1
+ fun handleNotify(payload: org.json.JSONObject?, reply: org.json.JSONObject, project: Project) {
2
+ if (payload == null) return
3
+ val message = payload.optString("message", "")
4
+ val level = payload.optString("level", "info")
5
+ val notificationType = when (level) {
6
+ "error" -> com.intellij.notification.NotificationType.ERROR
7
+ "warning" -> com.intellij.notification.NotificationType.WARNING
8
+ else -> com.intellij.notification.NotificationType.INFORMATION
9
+ }
10
+ com.intellij.notification.NotificationGroupManager.getInstance()
11
+ .getNotificationGroup("unextension")
12
+ ?.createNotification(message, notificationType)
13
+ ?.notify(project)
14
+ reply.put("type", "notify:reply")
15
+ val replyPayload = org.json.JSONObject()
16
+ replyPayload.put("shown", true)
17
+ reply.put("payload", replyPayload)
18
+ }
@@ -0,0 +1,12 @@
1
+ fun handleReadProjectFile(payload: org.json.JSONObject?, reply: org.json.JSONObject) {
2
+ if (payload == null) return
3
+ val filePath = payload.optString("path", "")
4
+ val projectPath = com.intellij.openapi.project.ProjectManager.getInstance().openProjects.firstOrNull()?.basePath ?: ""
5
+ val file = java.io.File(projectPath, filePath)
6
+ val content = if (file.exists() && file.isFile) file.readText(Charsets.UTF_8) else ""
7
+ reply.put("type", "read-project-file:reply")
8
+ val replyPayload = org.json.JSONObject()
9
+ replyPayload.put("content", content)
10
+ replyPayload.put("encoding", "utf8")
11
+ reply.put("payload", replyPayload)
12
+ }
@@ -0,0 +1,25 @@
1
+ fun handleRunCommand(payload: org.json.JSONObject?, reply: org.json.JSONObject) {
2
+ if (payload == null) return
3
+ val command = payload.optString("command", "")
4
+ val requestedShell = payload.optString("shell", "")
5
+ val isWindows = System.getProperty("os.name").lowercase().contains("win")
6
+ val (shell, flag) = resolveShell(requestedShell, isWindows)
7
+ val result = runShellCommand(command, shell, flag)
8
+ reply.put("type", "run-command:reply")
9
+ val replyPayload = org.json.JSONObject()
10
+ replyPayload.put("command", command)
11
+ replyPayload.put("stdout", result.first)
12
+ replyPayload.put("stderr", result.second)
13
+ replyPayload.put("exitCode", result.third)
14
+ reply.put("payload", replyPayload)
15
+ }
16
+
17
+ fun resolveShell(requested: String, isWindows: Boolean): Pair<String, String> = when (requested) {
18
+ "cmd" -> Pair("cmd", "/c")
19
+ "powershell" -> Pair("powershell", "-Command")
20
+ "bash" -> Pair("bash", "-c")
21
+ "sh" -> Pair("sh", "-c")
22
+ "zsh" -> Pair("zsh", "-c")
23
+ "fish" -> Pair("fish", "-c")
24
+ else -> if (isWindows) Pair("cmd", "/c") else Pair("sh", "-c")
25
+ }
@@ -0,0 +1,57 @@
1
+ fun handleRunScript(payload: org.json.JSONObject?, reply: org.json.JSONObject) {
2
+ if (payload == null) return
3
+ val name = payload.optString("name", "")
4
+ val scriptPayload = payload.opt("payload")
5
+ val scriptName = if (name.endsWith(".js")) name else "$name.js"
6
+
7
+ // Extract script from classpath resources to a temp dir and run it
8
+ val tmpDir = java.io.File(System.getProperty("java.io.tmpdir"), "unextension-scripts")
9
+ tmpDir.mkdirs()
10
+ val outFile = java.io.File(tmpDir, scriptName)
11
+ val stream = object {}.javaClass.getResourceAsStream("/scripts/$scriptName")
12
+
13
+ if (stream == null) {
14
+ reply.put("type", "run-script:reply")
15
+ val replyPayload = org.json.JSONObject()
16
+ replyPayload.put("result", org.json.JSONObject.NULL)
17
+ replyPayload.put("exitCode", 1)
18
+ replyPayload.put("stderr", "Script not found: $scriptName")
19
+ reply.put("payload", replyPayload)
20
+ return
21
+ }
22
+ stream.use { it.copyTo(outFile.outputStream()) }
23
+
24
+ val inputJson = scriptPayload?.toString() ?: "null"
25
+ val nodePath = resolveNode()
26
+ val proc = ProcessBuilder(nodePath, outFile.absolutePath)
27
+ .apply { environment()["UNEXTENSION_PAYLOAD"] = inputJson }
28
+ .redirectErrorStream(false)
29
+ .start()
30
+ val stdout = proc.inputStream.bufferedReader().readText()
31
+ val stderr = proc.errorStream.bufferedReader().readText()
32
+ val exitCode = proc.waitFor()
33
+
34
+ var result: Any = org.json.JSONObject.NULL
35
+ try { result = org.json.JSONObject(stdout.trim()) } catch (_: Exception) {
36
+ try { result = org.json.JSONArray(stdout.trim()) } catch (_: Exception) {
37
+ result = stdout.trim()
38
+ }
39
+ }
40
+
41
+ reply.put("type", "run-script:reply")
42
+ val replyPayload = org.json.JSONObject()
43
+ replyPayload.put("result", result as Any)
44
+ replyPayload.put("exitCode", exitCode)
45
+ replyPayload.put("stderr", stderr)
46
+ reply.put("payload", replyPayload)
47
+ }
48
+
49
+ fun resolveNode(): String {
50
+ val candidates = if (System.getProperty("os.name").lowercase().contains("win"))
51
+ listOf("node.exe", "C:\\Program Files\\nodejs\\node.exe")
52
+ else
53
+ listOf("node", "/usr/local/bin/node", "/usr/bin/node")
54
+ return candidates.firstOrNull { java.io.File(it).exists() || runCatching {
55
+ ProcessBuilder("which", it).start().waitFor() == 0
56
+ }.getOrDefault(false) } ?: "node"
57
+ }
@@ -0,0 +1,16 @@
1
+ fun handleWriteProjectFile(payload: org.json.JSONObject?, reply: org.json.JSONObject) {
2
+ if (payload == null) return
3
+ val filePath = payload.optString("path", "")
4
+ val content = payload.optString("content", "")
5
+ val projectPath = com.intellij.openapi.project.ProjectManager.getInstance().openProjects.firstOrNull()?.basePath ?: ""
6
+ val file = java.io.File(projectPath, filePath)
7
+ val success = try {
8
+ file.parentFile?.mkdirs()
9
+ file.writeText(content, Charsets.UTF_8)
10
+ true
11
+ } catch (e: Exception) { false }
12
+ reply.put("type", "write-project-file:reply")
13
+ val replyPayload = org.json.JSONObject()
14
+ replyPayload.put("success", success)
15
+ reply.put("payload", replyPayload)
16
+ }
@@ -0,0 +1,8 @@
1
+ export interface KotlinActions {
2
+ /** Private fun declarations to embed as class members */
3
+ functions: string;
4
+ /** if/else if dispatch chain to embed in the message handler */
5
+ dispatch: string;
6
+ }
7
+ export declare function generateKotlinActions(): KotlinActions;
8
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/targets/jetbrains/actions.ts"],"names":[],"mappings":"AA+BA,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,qBAAqB,IAAI,aAAa,CAuBrD"}
@@ -0,0 +1,39 @@
1
+ import { readFileSync, readdirSync } from 'node:fs';
2
+ import { join, dirname, basename } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const actionsDir = join(dirname(fileURLToPath(import.meta.url)), 'actions');
5
+ function pascalToKebab(s) {
6
+ return s.replace(/([A-Z])/g, (_, c, i) => (i > 0 ? '-' : '') + c.toLowerCase());
7
+ }
8
+ function loadActions() {
9
+ return readdirSync(actionsDir)
10
+ .filter((f) => f.endsWith('.kt'))
11
+ .sort()
12
+ .map((f) => {
13
+ const name = basename(f, '.kt');
14
+ const fnName = `handle${name}`;
15
+ const type = pascalToKebab(name);
16
+ const body = readFileSync(join(actionsDir, f), 'utf8').trim();
17
+ const needsProject = body.includes(', project: Project');
18
+ return { type, fnName, body, needsProject };
19
+ });
20
+ }
21
+ export function generateKotlinActions() {
22
+ const actions = loadActions();
23
+ const functions = actions
24
+ .map((a) => a.body
25
+ .split('\n')
26
+ .map((l) => ' ' + l)
27
+ .join('\n'))
28
+ .join('\n\n');
29
+ const dispatch = actions
30
+ .map((a, i) => {
31
+ const call = `${a.fnName}(payload, reply${a.needsProject ? ', project' : ''})`;
32
+ const cond = `type == "${a.type}"`;
33
+ return i === 0 ? `if (${cond}) { ${call} }` : `else if (${cond}) { ${call} }`;
34
+ })
35
+ .join('\n ') +
36
+ `\n else {\n reply.put("type", "$type:reply")\n val replyPayload = org.json.JSONObject()\n replyPayload.put("received", true)\n replyPayload.put("echo", parsed.opt("payload"))\n reply.put("payload", replyPayload)\n }`;
37
+ return { functions, dispatch };
38
+ }
39
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/targets/jetbrains/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAS3E,SAAS,aAAa,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;AACjF,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,WAAW,CAAC,UAAU,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;QAC/B,MAAM,MAAM,GAAG,SAAS,IAAI,EAAE,CAAA;QAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAA;QACxD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;IAC7C,CAAC,CAAC,CAAA;AACN,CAAC;AASD,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAA;IAE7B,MAAM,SAAS,GAAG,OAAO;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,IAAI;SACH,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;SACtB,IAAI,CAAC,IAAI,CAAC,CACd;SACA,IAAI,CAAC,MAAM,CAAC,CAAA;IAEf,MAAM,QAAQ,GACZ,OAAO;SACJ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,kBAAkB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAA;QAC9E,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,GAAG,CAAA;QAClC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,OAAO,IAAI,IAAI,CAAA;IAC/E,CAAC,CAAC;SACD,IAAI,CAAC,oBAAoB,CAAC;QAC7B,sVAAsV,CAAA;IAExV,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAChC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { UnextensionConfig } from '../../config.js';
2
+ export declare function buildJetBrains(config: UnextensionConfig, cwd: string): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/targets/jetbrains/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAaxD,wBAAsB,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,iBA+I1E"}