@unibridge/cli 0.5.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 (53) hide show
  1. package/dist/commands/domain.d.ts +11 -0
  2. package/dist/commands/domain.d.ts.map +1 -0
  3. package/dist/commands/domain.js +27 -0
  4. package/dist/commands/domain.js.map +1 -0
  5. package/dist/commands/execute.d.ts +10 -0
  6. package/dist/commands/execute.d.ts.map +1 -0
  7. package/dist/commands/execute.js +27 -0
  8. package/dist/commands/execute.js.map +1 -0
  9. package/dist/commands/init.d.ts +14 -0
  10. package/dist/commands/init.d.ts.map +1 -0
  11. package/dist/commands/init.js +30 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/output.d.ts +6 -0
  14. package/dist/commands/output.d.ts.map +1 -0
  15. package/dist/commands/output.js +21 -0
  16. package/dist/commands/output.js.map +1 -0
  17. package/dist/commands/scene.d.ts +23 -0
  18. package/dist/commands/scene.d.ts.map +1 -0
  19. package/dist/commands/scene.js +71 -0
  20. package/dist/commands/scene.js.map +1 -0
  21. package/dist/commands/status.d.ts +11 -0
  22. package/dist/commands/status.d.ts.map +1 -0
  23. package/dist/commands/status.js +28 -0
  24. package/dist/commands/status.js.map +1 -0
  25. package/dist/commands/with-unity-client.d.ts +12 -0
  26. package/dist/commands/with-unity-client.d.ts.map +1 -0
  27. package/dist/commands/with-unity-client.js +27 -0
  28. package/dist/commands/with-unity-client.js.map +1 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +24 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/options.d.ts +8 -0
  34. package/dist/options.d.ts.map +1 -0
  35. package/dist/options.js +4 -0
  36. package/dist/options.js.map +1 -0
  37. package/dist/preflight.d.ts +8 -0
  38. package/dist/preflight.d.ts.map +1 -0
  39. package/dist/preflight.js +18 -0
  40. package/dist/preflight.js.map +1 -0
  41. package/package.json +22 -0
  42. package/src/commands/domain.ts +49 -0
  43. package/src/commands/execute.ts +48 -0
  44. package/src/commands/init.ts +56 -0
  45. package/src/commands/output.ts +29 -0
  46. package/src/commands/scene.ts +135 -0
  47. package/src/commands/status.ts +49 -0
  48. package/src/commands/with-unity-client.ts +47 -0
  49. package/src/index.ts +29 -0
  50. package/src/options.ts +11 -0
  51. package/src/preflight.test.ts +39 -0
  52. package/src/preflight.ts +23 -0
  53. package/tsconfig.json +16 -0
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+ import type { DomainReloadResult } from '@unibridge/sdk';
3
+ interface DomainReloadDeps {
4
+ reload: () => Promise<DomainReloadResult>;
5
+ console: Pick<Console, 'log' | 'error'>;
6
+ exit?: (code: number) => void;
7
+ }
8
+ export declare function handleDomainReload(jsonOutput: boolean, deps: DomainReloadDeps): Promise<void>;
9
+ export declare function registerDomain(program: Command): void;
10
+ export {};
11
+ //# sourceMappingURL=domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAIxD,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACzC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBrD"}
@@ -0,0 +1,27 @@
1
+ import { runWithOutput } from "./output.js";
2
+ import { withUnityClient } from "./with-unity-client.js";
3
+ export async function handleDomainReload(jsonOutput, deps) {
4
+ await runWithOutput(jsonOutput, deps, () => deps.reload(), (_result, output) => {
5
+ output.log('Domain reload triggered.');
6
+ });
7
+ }
8
+ export function registerDomain(program) {
9
+ const domain = program
10
+ .command('domain')
11
+ .description('Unity domain operations');
12
+ domain
13
+ .command('reload')
14
+ .description('Trigger an asset refresh and domain reload')
15
+ .action(async (_opts, command) => {
16
+ await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
17
+ await handleDomainReload(ctx.jsonOutput, {
18
+ reload: () => client.domainReload(),
19
+ console,
20
+ exit: (exitCode) => {
21
+ process.exitCode = exitCode;
22
+ },
23
+ });
24
+ });
25
+ });
26
+ }
27
+ //# sourceMappingURL=domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAmB,EACnB,IAAsB;IAEtB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EACnB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClB,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;IACxC,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yBAAyB,CAAC,CAAA;IAEzC,MAAM;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC/D,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE;gBACvC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE;gBACnC,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Command } from 'commander';
2
+ interface ExecuteDeps {
3
+ execute: (code: string) => Promise<unknown>;
4
+ console: Pick<Console, 'log' | 'error'>;
5
+ exit?: (code: number) => void;
6
+ }
7
+ export declare function handleExecute(code: string, jsonOutput: boolean, deps: ExecuteDeps): Promise<void>;
8
+ export declare function registerExecute(program: Command): void;
9
+ export {};
10
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,UAAU,WAAW;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsBtD"}
@@ -0,0 +1,27 @@
1
+ import { runWithOutput } from "./output.js";
2
+ import { withUnityClient } from "./with-unity-client.js";
3
+ export async function handleExecute(code, jsonOutput, deps) {
4
+ await runWithOutput(jsonOutput, deps, () => deps.execute(code), (result, output) => {
5
+ output.log(String(result));
6
+ });
7
+ }
8
+ export function registerExecute(program) {
9
+ program
10
+ .command('execute <code>')
11
+ .description('Execute C# code in the Unity Editor')
12
+ .action(async (code, _opts, command) => {
13
+ await withUnityClient(command, {
14
+ requirePlugin: true,
15
+ requiresExecute: true,
16
+ }, async (client, ctx) => {
17
+ await handleExecute(code, ctx.jsonOutput, {
18
+ execute: (requestCode) => client.execute(requestCode),
19
+ console,
20
+ exit: (exitCode) => {
21
+ process.exitCode = exitCode;
22
+ },
23
+ });
24
+ });
25
+ });
26
+ }
27
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,UAAmB,EACnB,IAAiB;IAEjB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EACxB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC7E,MAAM,eAAe,CACnB,OAAO,EACP;YACE,aAAa,EAAE,IAAI;YACnB,eAAe,EAAE,IAAI;SACtB,EACD,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE;gBACxC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;gBACrD,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Command } from 'commander';
2
+ import { type InitOptions, type InitResult } from '@unibridge/sdk';
3
+ interface InitCommandOptions {
4
+ local?: string;
5
+ git?: string;
6
+ }
7
+ interface InitHandlerDeps {
8
+ init: (options?: InitOptions) => Promise<InitResult>;
9
+ console: Pick<Console, 'log' | 'error'>;
10
+ }
11
+ export declare function handleInit(opts: InitCommandOptions, jsonOutput: boolean, deps?: InitHandlerDeps): Promise<void>;
12
+ export declare function registerInit(program: Command): void;
13
+ export {};
14
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAInF,UAAU,kBAAkB;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACpD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;CACxC;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,OAAO,EACnB,IAAI,GAAE,eAA4C,GACjD,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBnD"}
@@ -0,0 +1,30 @@
1
+ import { init as sdkInit } from '@unibridge/sdk';
2
+ import { getGlobalOptions } from "../options.js";
3
+ import { runWithOutput } from "./output.js";
4
+ export async function handleInit(opts, jsonOutput, deps = { init: sdkInit, console }) {
5
+ const source = opts.local
6
+ ? { type: 'local', path: opts.local }
7
+ : opts.git
8
+ ? { type: 'git', url: opts.git }
9
+ : undefined;
10
+ await runWithOutput(jsonOutput, deps, () => deps.init({ source }), (result, output) => {
11
+ output.log(`Found Unity ${result.unityVersion} at ${result.projectPath}`);
12
+ output.log(`Installed com.msanatan.unibridge@${result.pluginVersion}`);
13
+ output.log('Open Unity to load the plugin.');
14
+ });
15
+ }
16
+ export function registerInit(program) {
17
+ program
18
+ .command('init')
19
+ .description('Install the unibridge plugin into a Unity project')
20
+ .option('--local <path>', 'Install from a local path')
21
+ .option('--git <url>', 'Install from a custom git URL')
22
+ .action(async (opts, command) => {
23
+ const globalOpts = getGlobalOptions(command);
24
+ await handleInit(opts, globalOpts.json === true, {
25
+ init: (initOpts) => sdkInit({ ...initOpts, projectPath: globalOpts.project }),
26
+ console,
27
+ });
28
+ });
29
+ }
30
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,IAAI,OAAO,EAAqC,MAAM,gBAAgB,CAAA;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAY3C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAwB,EACxB,UAAmB,EACnB,OAAwB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;IAElD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK;QACvB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE;QAC9C,CAAC,CAAC,IAAI,CAAC,GAAG;YACR,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACzC,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAC3B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,YAAY,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QACzE,MAAM,CAAC,GAAG,CAAC,oCAAoC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAA;QACtE,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAC9C,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,gBAAgB,EAAE,2BAA2B,CAAC;SACrD,MAAM,CAAC,aAAa,EAAE,+BAA+B,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,OAAgB,EAAE,EAAE;QAC3D,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,UAAU,CACd,IAAI,EACJ,UAAU,CAAC,IAAI,KAAK,IAAI,EACxB;YACE,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;YAC7E,OAAO;SACR,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface CommandOutputDeps {
2
+ console: Pick<Console, 'log' | 'error'>;
3
+ exit?: (code: number) => void;
4
+ }
5
+ export declare function runWithOutput<TResult>(jsonOutput: boolean, deps: CommandOutputDeps, execute: () => Promise<TResult>, renderText: (result: TResult, consoleLike: Pick<Console, 'log'>) => void): Promise<void>;
6
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/commands/output.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,aAAa,CAAC,OAAO,EACzC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC/B,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,IAAI,GACvE,OAAO,CAAC,IAAI,CAAC,CAkBf"}
@@ -0,0 +1,21 @@
1
+ export async function runWithOutput(jsonOutput, deps, execute, renderText) {
2
+ try {
3
+ const result = await execute();
4
+ if (jsonOutput) {
5
+ deps.console.log(JSON.stringify({ success: true, result }));
6
+ return;
7
+ }
8
+ renderText(result, deps.console);
9
+ }
10
+ catch (error) {
11
+ const message = error instanceof Error ? error.message : String(error);
12
+ if (jsonOutput) {
13
+ deps.console.log(JSON.stringify({ success: false, error: message }));
14
+ }
15
+ else {
16
+ deps.console.error(`Error: ${message}`);
17
+ }
18
+ deps.exit?.(1);
19
+ }
20
+ }
21
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/commands/output.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAmB,EACnB,IAAuB,EACvB,OAA+B,EAC/B,UAAwE;IAExE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;QAC9B,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAC3D,OAAM;QACR,CAAC;QAED,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACtE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Command } from 'commander';
2
+ import type { SceneActiveResult, SceneCreateResult, SceneOpenResult } from '@unibridge/sdk';
3
+ interface SceneActiveDeps {
4
+ active: () => Promise<SceneActiveResult>;
5
+ console: Pick<Console, 'log' | 'error'>;
6
+ exit?: (code: number) => void;
7
+ }
8
+ export declare function handleSceneActive(jsonOutput: boolean, deps: SceneActiveDeps): Promise<void>;
9
+ interface SceneOpenDeps {
10
+ open: (path: string) => Promise<SceneOpenResult>;
11
+ console: Pick<Console, 'log' | 'error'>;
12
+ exit?: (code: number) => void;
13
+ }
14
+ export declare function handleSceneOpen(path: string, jsonOutput: boolean, deps: SceneOpenDeps): Promise<void>;
15
+ interface SceneCreateDeps {
16
+ create: (path: string) => Promise<SceneCreateResult>;
17
+ console: Pick<Console, 'log' | 'error'>;
18
+ exit?: (code: number) => void;
19
+ }
20
+ export declare function handleSceneCreate(path: string, jsonOutput: boolean, deps: SceneCreateDeps): Promise<void>;
21
+ export declare function registerScene(program: Command): void;
22
+ export {};
23
+ //# sourceMappingURL=scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/commands/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAI3F,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACxC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACpD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6DpD"}
@@ -0,0 +1,71 @@
1
+ import { runWithOutput } from "./output.js";
2
+ import { withUnityClient } from "./with-unity-client.js";
3
+ export async function handleSceneActive(jsonOutput, deps) {
4
+ await runWithOutput(jsonOutput, deps, () => deps.active(), (result, output) => {
5
+ output.log(`Name: ${result.scene.name}`);
6
+ output.log(`Path: ${result.scene.path}`);
7
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
8
+ });
9
+ }
10
+ export async function handleSceneOpen(path, jsonOutput, deps) {
11
+ await runWithOutput(jsonOutput, deps, () => deps.open(path), (result, output) => {
12
+ output.log(`Name: ${result.scene.name}`);
13
+ output.log(`Path: ${result.scene.path}`);
14
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
15
+ });
16
+ }
17
+ export async function handleSceneCreate(path, jsonOutput, deps) {
18
+ await runWithOutput(jsonOutput, deps, () => deps.create(path), (result, output) => {
19
+ output.log(`Name: ${result.scene.name}`);
20
+ output.log(`Path: ${result.scene.path}`);
21
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
22
+ });
23
+ }
24
+ export function registerScene(program) {
25
+ const scene = program
26
+ .command('scene')
27
+ .description('Read and modify Unity scenes');
28
+ scene
29
+ .command('active')
30
+ .description('Show the active scene')
31
+ .action(async (_opts, command) => {
32
+ await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
33
+ await handleSceneActive(ctx.jsonOutput, {
34
+ active: () => client.sceneActive(),
35
+ console,
36
+ exit: (exitCode) => {
37
+ process.exitCode = exitCode;
38
+ },
39
+ });
40
+ });
41
+ });
42
+ scene
43
+ .command('create <path>')
44
+ .description('Create a new scene at a project-relative path')
45
+ .action(async (path, _opts, command) => {
46
+ await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
47
+ await handleSceneCreate(path, ctx.jsonOutput, {
48
+ create: (scenePath) => client.sceneCreate(scenePath),
49
+ console,
50
+ exit: (exitCode) => {
51
+ process.exitCode = exitCode;
52
+ },
53
+ });
54
+ });
55
+ });
56
+ scene
57
+ .command('open <path>')
58
+ .description('Open a scene by project-relative path')
59
+ .action(async (path, _opts, command) => {
60
+ await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
61
+ await handleSceneOpen(path, ctx.jsonOutput, {
62
+ open: (scenePath) => client.sceneOpen(scenePath),
63
+ console,
64
+ exit: (exitCode) => {
65
+ process.exitCode = exitCode;
66
+ },
67
+ });
68
+ });
69
+ });
70
+ }
71
+ //# sourceMappingURL=scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.js","sourceRoot":"","sources":["../../src/commands/scene.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAmB,EACnB,IAAqB;IAErB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EACnB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAC/D,CAAC,CACF,CAAA;AACH,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,UAAmB,EACnB,IAAmB;IAEnB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EACrB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAC/D,CAAC,CACF,CAAA;AACH,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,UAAmB,EACnB,IAAqB;IAErB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EACvB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAC/D,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8BAA8B,CAAC,CAAA;IAE9C,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,KAAK,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC/D,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE;gBACtC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;gBAClC,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;IAEJ,KAAK;SACF,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC7E,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE;gBAC5C,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC;gBACpD,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;IAEJ,KAAK;SACF,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC7E,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE;gBAC1C,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC;gBAChD,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+ import type { StatusResult } from '@unibridge/sdk';
3
+ interface StatusDeps {
4
+ status: () => Promise<StatusResult>;
5
+ console: Pick<Console, 'log' | 'error'>;
6
+ exit?: (code: number) => void;
7
+ }
8
+ export declare function handleStatus(jsonOutput: boolean, deps: StatusDeps): Promise<void>;
9
+ export declare function registerStatus(program: Command): void;
10
+ export {};
11
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAA;IACnC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmBrD"}
@@ -0,0 +1,28 @@
1
+ import { runWithOutput } from "./output.js";
2
+ import { withUnityClient } from "./with-unity-client.js";
3
+ export async function handleStatus(jsonOutput, deps) {
4
+ await runWithOutput(jsonOutput, deps, () => deps.status(), (result, output) => {
5
+ output.log(`Project: ${result.projectPath}`);
6
+ output.log(`Unity: ${result.unityVersion}`);
7
+ output.log(`Plugin: ${result.pluginVersion}`);
8
+ output.log(`Scene: ${result.activeScene}`);
9
+ output.log(`Mode: ${result.playMode}`);
10
+ });
11
+ }
12
+ export function registerStatus(program) {
13
+ program
14
+ .command('status')
15
+ .description('Show the current state of the Unity Editor')
16
+ .action(async (_opts, command) => {
17
+ await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
18
+ await handleStatus(ctx.jsonOutput, {
19
+ status: () => client.status(),
20
+ console,
21
+ exit: (exitCode) => {
22
+ process.exitCode = exitCode;
23
+ },
24
+ });
25
+ });
26
+ });
27
+ }
28
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAmB,EACnB,IAAgB;IAEhB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EACnB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;QAC7C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,aAAa,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3C,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC/D,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE;gBACjC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE;gBAC7B,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Command } from 'commander';
2
+ import { createClient } from '@unibridge/sdk';
3
+ interface ClientCommandRequirements {
4
+ requirePlugin: boolean;
5
+ requiresExecute?: boolean;
6
+ }
7
+ interface GlobalCommandContext {
8
+ jsonOutput: boolean;
9
+ }
10
+ export declare function withUnityClient(command: Command, requirements: ClientCommandRequirements, run: (client: ReturnType<typeof createClient>, ctx: GlobalCommandContext) => Promise<void>): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=with-unity-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-unity-client.d.ts","sourceRoot":"","sources":["../../src/commands/with-unity-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAI7C,UAAU,yBAAyB;IACjC,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,UAAU,oBAAoB;IAC5B,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,yBAAyB,EACvC,GAAG,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EAAE,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,GACzF,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
@@ -0,0 +1,27 @@
1
+ import { createClient } from '@unibridge/sdk';
2
+ import { getGlobalOptions } from "../options.js";
3
+ import { resolveCommandProject } from "../preflight.js";
4
+ export async function withUnityClient(command, requirements, run) {
5
+ let client;
6
+ try {
7
+ const globalOpts = getGlobalOptions(command);
8
+ const envExecute = process.env.UNIBRIDGE_ENABLE_EXECUTE !== '0';
9
+ const executeEnabled = globalOpts.execute !== false && envExecute;
10
+ const projectPath = resolveCommandProject({
11
+ project: globalOpts.project,
12
+ execute: executeEnabled,
13
+ }, requirements);
14
+ client = createClient({
15
+ projectPath,
16
+ enableExecute: executeEnabled,
17
+ connectTimeout: 10_000,
18
+ });
19
+ await run(client, {
20
+ jsonOutput: globalOpts.json === true,
21
+ });
22
+ }
23
+ finally {
24
+ client?.close();
25
+ }
26
+ }
27
+ //# sourceMappingURL=with-unity-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-unity-client.js","sourceRoot":"","sources":["../../src/commands/with-unity-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAWvD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,YAAuC,EACvC,GAA0F;IAE1F,IAAI,MAAmD,CAAA;IAEvD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAA;QAC/D,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,KAAK,KAAK,IAAI,UAAU,CAAA;QAEjE,MAAM,WAAW,GAAG,qBAAqB,CACvC;YACE,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,OAAO,EAAE,cAAc;SACxB,EACD,YAAY,CACb,CAAA;QAED,MAAM,GAAG,YAAY,CAAC;YACpB,WAAW;YACX,aAAa,EAAE,cAAc;YAC7B,cAAc,EAAE,MAAM;SACvB,CAAC,CAAA;QAEF,MAAM,GAAG,CAAC,MAAM,EAAE;YAChB,UAAU,EAAE,UAAU,CAAC,IAAI,KAAK,IAAI;SACrC,CAAC,CAAA;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,KAAK,EAAE,CAAA;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { program } from 'commander';
5
+ import { registerDomain } from "./commands/domain.js";
6
+ import { registerInit } from "./commands/init.js";
7
+ import { registerExecute } from "./commands/execute.js";
8
+ import { registerStatus } from "./commands/status.js";
9
+ import { registerScene } from "./commands/scene.js";
10
+ const { version } = JSON.parse(readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'));
11
+ program
12
+ .name('unibridge')
13
+ .description('Bridge between Unity and your code')
14
+ .version(version)
15
+ .option('-p, --project <path>', 'Path to Unity project')
16
+ .option('--json', 'Output result as JSON')
17
+ .option('--no-execute', 'Disable execute tool for this invocation');
18
+ registerDomain(program);
19
+ registerInit(program);
20
+ registerExecute(program);
21
+ registerStatus(program);
22
+ registerScene(program);
23
+ program.parse();
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CACrD,CAAA;AAExB,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;KACvD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KACzC,MAAM,CAAC,cAAc,EAAE,0CAA0C,CAAC,CAAA;AAErE,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,aAAa,CAAC,OAAO,CAAC,CAAA;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { Command } from 'commander';
2
+ export interface GlobalCommandOptions {
3
+ project?: string;
4
+ json?: boolean;
5
+ execute?: boolean;
6
+ }
7
+ export declare function getGlobalOptions(command: Command): GlobalCommandOptions;
8
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAEvE"}
@@ -0,0 +1,4 @@
1
+ export function getGlobalOptions(command) {
2
+ return command.optsWithGlobals();
3
+ }
4
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,OAAO,CAAC,eAAe,EAA0B,CAAA;AAC1D,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function resolveCommandProject(opts: {
2
+ project?: string;
3
+ execute?: boolean;
4
+ }, config: {
5
+ requirePlugin: boolean;
6
+ requiresExecute?: boolean;
7
+ }): string;
8
+ //# sourceMappingURL=preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EAC7C,MAAM,EAAE;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5D,MAAM,CAiBR"}
@@ -0,0 +1,18 @@
1
+ import { findUnityProject, isPluginInstalled } from '@unibridge/sdk';
2
+ export function resolveCommandProject(opts, config) {
3
+ let projectPath;
4
+ try {
5
+ projectPath = findUnityProject(opts.project);
6
+ }
7
+ catch {
8
+ throw new Error('Unity project not found. Run inside a Unity project or pass --project <path>.');
9
+ }
10
+ if (config.requiresExecute && opts.execute === false) {
11
+ throw new Error('Execute is disabled for this invocation (--no-execute).');
12
+ }
13
+ if (config.requirePlugin && !isPluginInstalled(projectPath)) {
14
+ throw new Error('com.msanatan.unibridge is not installed. Run `unibridge init` first.');
15
+ }
16
+ return projectPath;
17
+ }
18
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEpE,MAAM,UAAU,qBAAqB,CACnC,IAA6C,EAC7C,MAA6D;IAE7D,IAAI,WAAmB,CAAA;IACvB,IAAI,CAAC;QACH,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IAClG,CAAC;IAED,IAAI,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;IAC5E,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAA;IACzF,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@unibridge/cli",
3
+ "version": "0.5.0",
4
+ "description": "",
5
+ "main": "./dist/index.js",
6
+ "scripts": {
7
+ "test": "node --test src/*.test.ts src/**/*.test.ts",
8
+ "build": "tsc -p tsconfig.json",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "keywords": [],
12
+ "author": "",
13
+ "license": "ISC",
14
+ "type": "module",
15
+ "bin": {
16
+ "unibridge": "./dist/index.js"
17
+ },
18
+ "dependencies": {
19
+ "@unibridge/sdk": "0.5.0",
20
+ "commander": "^14.0.3"
21
+ }
22
+ }
@@ -0,0 +1,49 @@
1
+ import type { Command } from 'commander'
2
+ import type { DomainReloadResult } from '@unibridge/sdk'
3
+ import { runWithOutput } from './output.ts'
4
+ import { withUnityClient } from './with-unity-client.ts'
5
+
6
+ interface DomainReloadDeps {
7
+ reload: () => Promise<DomainReloadResult>
8
+ console: Pick<Console, 'log' | 'error'>
9
+ exit?: (code: number) => void
10
+ }
11
+
12
+ export async function handleDomainReload(
13
+ jsonOutput: boolean,
14
+ deps: DomainReloadDeps,
15
+ ): Promise<void> {
16
+ await runWithOutput(
17
+ jsonOutput,
18
+ deps,
19
+ () => deps.reload(),
20
+ (_result, output) => {
21
+ output.log('Domain reload triggered.')
22
+ },
23
+ )
24
+ }
25
+
26
+ export function registerDomain(program: Command): void {
27
+ const domain = program
28
+ .command('domain')
29
+ .description('Unity domain operations')
30
+
31
+ domain
32
+ .command('reload')
33
+ .description('Trigger an asset refresh and domain reload')
34
+ .action(async (_opts: Record<string, never>, command: Command) => {
35
+ await withUnityClient(
36
+ command,
37
+ { requirePlugin: true },
38
+ async (client, ctx) => {
39
+ await handleDomainReload(ctx.jsonOutput, {
40
+ reload: () => client.domainReload(),
41
+ console,
42
+ exit: (exitCode) => {
43
+ process.exitCode = exitCode
44
+ },
45
+ })
46
+ },
47
+ )
48
+ })
49
+ }
@@ -0,0 +1,48 @@
1
+ import type { Command } from 'commander'
2
+ import { runWithOutput } from './output.ts'
3
+ import { withUnityClient } from './with-unity-client.ts'
4
+
5
+ interface ExecuteDeps {
6
+ execute: (code: string) => Promise<unknown>
7
+ console: Pick<Console, 'log' | 'error'>
8
+ exit?: (code: number) => void
9
+ }
10
+
11
+ export async function handleExecute(
12
+ code: string,
13
+ jsonOutput: boolean,
14
+ deps: ExecuteDeps,
15
+ ): Promise<void> {
16
+ await runWithOutput(
17
+ jsonOutput,
18
+ deps,
19
+ () => deps.execute(code),
20
+ (result, output) => {
21
+ output.log(String(result))
22
+ },
23
+ )
24
+ }
25
+
26
+ export function registerExecute(program: Command): void {
27
+ program
28
+ .command('execute <code>')
29
+ .description('Execute C# code in the Unity Editor')
30
+ .action(async (code: string, _opts: Record<string, never>, command: Command) => {
31
+ await withUnityClient(
32
+ command,
33
+ {
34
+ requirePlugin: true,
35
+ requiresExecute: true,
36
+ },
37
+ async (client, ctx) => {
38
+ await handleExecute(code, ctx.jsonOutput, {
39
+ execute: (requestCode) => client.execute(requestCode),
40
+ console,
41
+ exit: (exitCode) => {
42
+ process.exitCode = exitCode
43
+ },
44
+ })
45
+ },
46
+ )
47
+ })
48
+ }
@@ -0,0 +1,56 @@
1
+ import type { Command } from 'commander'
2
+ import { init as sdkInit, type InitOptions, type InitResult } from '@unibridge/sdk'
3
+ import { getGlobalOptions } from '../options.ts'
4
+ import { runWithOutput } from './output.ts'
5
+
6
+ interface InitCommandOptions {
7
+ local?: string
8
+ git?: string
9
+ }
10
+
11
+ interface InitHandlerDeps {
12
+ init: (options?: InitOptions) => Promise<InitResult>
13
+ console: Pick<Console, 'log' | 'error'>
14
+ }
15
+
16
+ export async function handleInit(
17
+ opts: InitCommandOptions,
18
+ jsonOutput: boolean,
19
+ deps: InitHandlerDeps = { init: sdkInit, console },
20
+ ): Promise<void> {
21
+ const source = opts.local
22
+ ? { type: 'local' as const, path: opts.local }
23
+ : opts.git
24
+ ? { type: 'git' as const, url: opts.git }
25
+ : undefined
26
+
27
+ await runWithOutput(
28
+ jsonOutput,
29
+ deps,
30
+ () => deps.init({ source }),
31
+ (result, output) => {
32
+ output.log(`Found Unity ${result.unityVersion} at ${result.projectPath}`)
33
+ output.log(`Installed com.msanatan.unibridge@${result.pluginVersion}`)
34
+ output.log('Open Unity to load the plugin.')
35
+ },
36
+ )
37
+ }
38
+
39
+ export function registerInit(program: Command): void {
40
+ program
41
+ .command('init')
42
+ .description('Install the unibridge plugin into a Unity project')
43
+ .option('--local <path>', 'Install from a local path')
44
+ .option('--git <url>', 'Install from a custom git URL')
45
+ .action(async (opts: InitCommandOptions, command: Command) => {
46
+ const globalOpts = getGlobalOptions(command)
47
+ await handleInit(
48
+ opts,
49
+ globalOpts.json === true,
50
+ {
51
+ init: (initOpts) => sdkInit({ ...initOpts, projectPath: globalOpts.project }),
52
+ console,
53
+ },
54
+ )
55
+ })
56
+ }
@@ -0,0 +1,29 @@
1
+ export interface CommandOutputDeps {
2
+ console: Pick<Console, 'log' | 'error'>
3
+ exit?: (code: number) => void
4
+ }
5
+
6
+ export async function runWithOutput<TResult>(
7
+ jsonOutput: boolean,
8
+ deps: CommandOutputDeps,
9
+ execute: () => Promise<TResult>,
10
+ renderText: (result: TResult, consoleLike: Pick<Console, 'log'>) => void,
11
+ ): Promise<void> {
12
+ try {
13
+ const result = await execute()
14
+ if (jsonOutput) {
15
+ deps.console.log(JSON.stringify({ success: true, result }))
16
+ return
17
+ }
18
+
19
+ renderText(result, deps.console)
20
+ } catch (error) {
21
+ const message = error instanceof Error ? error.message : String(error)
22
+ if (jsonOutput) {
23
+ deps.console.log(JSON.stringify({ success: false, error: message }))
24
+ } else {
25
+ deps.console.error(`Error: ${message}`)
26
+ }
27
+ deps.exit?.(1)
28
+ }
29
+ }
@@ -0,0 +1,135 @@
1
+ import type { Command } from 'commander'
2
+ import type { SceneActiveResult, SceneCreateResult, SceneOpenResult } from '@unibridge/sdk'
3
+ import { runWithOutput } from './output.ts'
4
+ import { withUnityClient } from './with-unity-client.ts'
5
+
6
+ interface SceneActiveDeps {
7
+ active: () => Promise<SceneActiveResult>
8
+ console: Pick<Console, 'log' | 'error'>
9
+ exit?: (code: number) => void
10
+ }
11
+
12
+ export async function handleSceneActive(
13
+ jsonOutput: boolean,
14
+ deps: SceneActiveDeps,
15
+ ): Promise<void> {
16
+ await runWithOutput(
17
+ jsonOutput,
18
+ deps,
19
+ () => deps.active(),
20
+ (result, output) => {
21
+ output.log(`Name: ${result.scene.name}`)
22
+ output.log(`Path: ${result.scene.path}`)
23
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
24
+ },
25
+ )
26
+ }
27
+
28
+ interface SceneOpenDeps {
29
+ open: (path: string) => Promise<SceneOpenResult>
30
+ console: Pick<Console, 'log' | 'error'>
31
+ exit?: (code: number) => void
32
+ }
33
+
34
+ export async function handleSceneOpen(
35
+ path: string,
36
+ jsonOutput: boolean,
37
+ deps: SceneOpenDeps,
38
+ ): Promise<void> {
39
+ await runWithOutput(
40
+ jsonOutput,
41
+ deps,
42
+ () => deps.open(path),
43
+ (result, output) => {
44
+ output.log(`Name: ${result.scene.name}`)
45
+ output.log(`Path: ${result.scene.path}`)
46
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
47
+ },
48
+ )
49
+ }
50
+
51
+ interface SceneCreateDeps {
52
+ create: (path: string) => Promise<SceneCreateResult>
53
+ console: Pick<Console, 'log' | 'error'>
54
+ exit?: (code: number) => void
55
+ }
56
+
57
+ export async function handleSceneCreate(
58
+ path: string,
59
+ jsonOutput: boolean,
60
+ deps: SceneCreateDeps,
61
+ ): Promise<void> {
62
+ await runWithOutput(
63
+ jsonOutput,
64
+ deps,
65
+ () => deps.create(path),
66
+ (result, output) => {
67
+ output.log(`Name: ${result.scene.name}`)
68
+ output.log(`Path: ${result.scene.path}`)
69
+ output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
70
+ },
71
+ )
72
+ }
73
+
74
+ export function registerScene(program: Command): void {
75
+ const scene = program
76
+ .command('scene')
77
+ .description('Read and modify Unity scenes')
78
+
79
+ scene
80
+ .command('active')
81
+ .description('Show the active scene')
82
+ .action(async (_opts: Record<string, never>, command: Command) => {
83
+ await withUnityClient(
84
+ command,
85
+ { requirePlugin: true },
86
+ async (client, ctx) => {
87
+ await handleSceneActive(ctx.jsonOutput, {
88
+ active: () => client.sceneActive(),
89
+ console,
90
+ exit: (exitCode) => {
91
+ process.exitCode = exitCode
92
+ },
93
+ })
94
+ },
95
+ )
96
+ })
97
+
98
+ scene
99
+ .command('create <path>')
100
+ .description('Create a new scene at a project-relative path')
101
+ .action(async (path: string, _opts: Record<string, never>, command: Command) => {
102
+ await withUnityClient(
103
+ command,
104
+ { requirePlugin: true },
105
+ async (client, ctx) => {
106
+ await handleSceneCreate(path, ctx.jsonOutput, {
107
+ create: (scenePath) => client.sceneCreate(scenePath),
108
+ console,
109
+ exit: (exitCode) => {
110
+ process.exitCode = exitCode
111
+ },
112
+ })
113
+ },
114
+ )
115
+ })
116
+
117
+ scene
118
+ .command('open <path>')
119
+ .description('Open a scene by project-relative path')
120
+ .action(async (path: string, _opts: Record<string, never>, command: Command) => {
121
+ await withUnityClient(
122
+ command,
123
+ { requirePlugin: true },
124
+ async (client, ctx) => {
125
+ await handleSceneOpen(path, ctx.jsonOutput, {
126
+ open: (scenePath) => client.sceneOpen(scenePath),
127
+ console,
128
+ exit: (exitCode) => {
129
+ process.exitCode = exitCode
130
+ },
131
+ })
132
+ },
133
+ )
134
+ })
135
+ }
@@ -0,0 +1,49 @@
1
+ import type { Command } from 'commander'
2
+ import type { StatusResult } from '@unibridge/sdk'
3
+ import { runWithOutput } from './output.ts'
4
+ import { withUnityClient } from './with-unity-client.ts'
5
+
6
+ interface StatusDeps {
7
+ status: () => Promise<StatusResult>
8
+ console: Pick<Console, 'log' | 'error'>
9
+ exit?: (code: number) => void
10
+ }
11
+
12
+ export async function handleStatus(
13
+ jsonOutput: boolean,
14
+ deps: StatusDeps,
15
+ ): Promise<void> {
16
+ await runWithOutput(
17
+ jsonOutput,
18
+ deps,
19
+ () => deps.status(),
20
+ (result, output) => {
21
+ output.log(`Project: ${result.projectPath}`)
22
+ output.log(`Unity: ${result.unityVersion}`)
23
+ output.log(`Plugin: ${result.pluginVersion}`)
24
+ output.log(`Scene: ${result.activeScene}`)
25
+ output.log(`Mode: ${result.playMode}`)
26
+ },
27
+ )
28
+ }
29
+
30
+ export function registerStatus(program: Command): void {
31
+ program
32
+ .command('status')
33
+ .description('Show the current state of the Unity Editor')
34
+ .action(async (_opts: Record<string, never>, command: Command) => {
35
+ await withUnityClient(
36
+ command,
37
+ { requirePlugin: true },
38
+ async (client, ctx) => {
39
+ await handleStatus(ctx.jsonOutput, {
40
+ status: () => client.status(),
41
+ console,
42
+ exit: (exitCode) => {
43
+ process.exitCode = exitCode
44
+ },
45
+ })
46
+ },
47
+ )
48
+ })
49
+ }
@@ -0,0 +1,47 @@
1
+ import type { Command } from 'commander'
2
+ import { createClient } from '@unibridge/sdk'
3
+ import { getGlobalOptions } from '../options.ts'
4
+ import { resolveCommandProject } from '../preflight.ts'
5
+
6
+ interface ClientCommandRequirements {
7
+ requirePlugin: boolean
8
+ requiresExecute?: boolean
9
+ }
10
+
11
+ interface GlobalCommandContext {
12
+ jsonOutput: boolean
13
+ }
14
+
15
+ export async function withUnityClient(
16
+ command: Command,
17
+ requirements: ClientCommandRequirements,
18
+ run: (client: ReturnType<typeof createClient>, ctx: GlobalCommandContext) => Promise<void>,
19
+ ): Promise<void> {
20
+ let client: ReturnType<typeof createClient> | undefined
21
+
22
+ try {
23
+ const globalOpts = getGlobalOptions(command)
24
+ const envExecute = process.env.UNIBRIDGE_ENABLE_EXECUTE !== '0'
25
+ const executeEnabled = globalOpts.execute !== false && envExecute
26
+
27
+ const projectPath = resolveCommandProject(
28
+ {
29
+ project: globalOpts.project,
30
+ execute: executeEnabled,
31
+ },
32
+ requirements,
33
+ )
34
+
35
+ client = createClient({
36
+ projectPath,
37
+ enableExecute: executeEnabled,
38
+ connectTimeout: 10_000,
39
+ })
40
+
41
+ await run(client, {
42
+ jsonOutput: globalOpts.json === true,
43
+ })
44
+ } finally {
45
+ client?.close()
46
+ }
47
+ }
package/src/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs'
3
+ import path from 'node:path'
4
+ import { program } from 'commander'
5
+ import { registerDomain } from './commands/domain.ts'
6
+ import { registerInit } from './commands/init.ts'
7
+ import { registerExecute } from './commands/execute.ts'
8
+ import { registerStatus } from './commands/status.ts'
9
+ import { registerScene } from './commands/scene.ts'
10
+
11
+ const { version } = JSON.parse(
12
+ readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'),
13
+ ) as { version: string }
14
+
15
+ program
16
+ .name('unibridge')
17
+ .description('Bridge between Unity and your code')
18
+ .version(version)
19
+ .option('-p, --project <path>', 'Path to Unity project')
20
+ .option('--json', 'Output result as JSON')
21
+ .option('--no-execute', 'Disable execute tool for this invocation')
22
+
23
+ registerDomain(program)
24
+ registerInit(program)
25
+ registerExecute(program)
26
+ registerStatus(program)
27
+ registerScene(program)
28
+
29
+ program.parse()
package/src/options.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander'
2
+
3
+ export interface GlobalCommandOptions {
4
+ project?: string
5
+ json?: boolean
6
+ execute?: boolean
7
+ }
8
+
9
+ export function getGlobalOptions(command: Command): GlobalCommandOptions {
10
+ return command.optsWithGlobals() as GlobalCommandOptions
11
+ }
@@ -0,0 +1,39 @@
1
+ import { afterEach, beforeEach, describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { mkdirSync, rmSync, writeFileSync } from 'node:fs'
4
+ import { resolveCommandProject } from './preflight.ts'
5
+
6
+ const projectPath = '/tmp/unibridge-cli-preflight/My Game'
7
+
8
+ beforeEach(() => {
9
+ mkdirSync(`${projectPath}/Assets`, { recursive: true })
10
+ mkdirSync(`${projectPath}/ProjectSettings`, { recursive: true })
11
+ mkdirSync(`${projectPath}/Packages`, { recursive: true })
12
+ writeFileSync(`${projectPath}/ProjectSettings/ProjectVersion.txt`, 'm_EditorVersion: 2022.3.10f1\n')
13
+ writeFileSync(`${projectPath}/Packages/manifest.json`, JSON.stringify({ dependencies: {} }, null, 2))
14
+ })
15
+
16
+ afterEach(() => {
17
+ rmSync('/tmp/unibridge-cli-preflight', { recursive: true, force: true })
18
+ })
19
+
20
+ describe('resolveCommandProject', () => {
21
+ it('throws when plugin is missing for command execution', () => {
22
+ assert.throws(
23
+ () => resolveCommandProject({ project: projectPath, execute: true }, { requirePlugin: true, requiresExecute: true }),
24
+ /Run `unibridge init` first/,
25
+ )
26
+ })
27
+
28
+ it('throws when execute is disabled', () => {
29
+ writeFileSync(
30
+ `${projectPath}/Packages/manifest.json`,
31
+ JSON.stringify({ dependencies: { 'com.msanatan.unibridge': 'file:../unity' } }, null, 2),
32
+ )
33
+
34
+ assert.throws(
35
+ () => resolveCommandProject({ project: projectPath, execute: false }, { requirePlugin: true, requiresExecute: true }),
36
+ /Execute is disabled/,
37
+ )
38
+ })
39
+ })
@@ -0,0 +1,23 @@
1
+ import { findUnityProject, isPluginInstalled } from '@unibridge/sdk'
2
+
3
+ export function resolveCommandProject(
4
+ opts: { project?: string; execute?: boolean },
5
+ config: { requirePlugin: boolean; requiresExecute?: boolean },
6
+ ): string {
7
+ let projectPath: string
8
+ try {
9
+ projectPath = findUnityProject(opts.project)
10
+ } catch {
11
+ throw new Error('Unity project not found. Run inside a Unity project or pass --project <path>.')
12
+ }
13
+
14
+ if (config.requiresExecute && opts.execute === false) {
15
+ throw new Error('Execute is disabled for this invocation (--no-execute).')
16
+ }
17
+
18
+ if (config.requirePlugin && !isPluginInstalled(projectPath)) {
19
+ throw new Error('com.msanatan.unibridge is not installed. Run `unibridge init` first.')
20
+ }
21
+
22
+ return projectPath
23
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "sourceMap": true
9
+ },
10
+ "include": [
11
+ "src/**/*.ts"
12
+ ],
13
+ "exclude": [
14
+ "src/**/*.test.ts"
15
+ ]
16
+ }