farseer-cli 1.0.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 (120) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +741 -0
  3. package/dist/commands/app.d.ts +2 -0
  4. package/dist/commands/app.js +349 -0
  5. package/dist/commands/app.js.map +7 -0
  6. package/dist/commands/apps.d.ts +2 -0
  7. package/dist/commands/apps.js +111 -0
  8. package/dist/commands/apps.js.map +7 -0
  9. package/dist/commands/checkout.d.ts +2 -0
  10. package/dist/commands/checkout.js +166 -0
  11. package/dist/commands/checkout.js.map +7 -0
  12. package/dist/commands/config.d.ts +2 -0
  13. package/dist/commands/config.js +139 -0
  14. package/dist/commands/config.js.map +7 -0
  15. package/dist/commands/diff.d.ts +2 -0
  16. package/dist/commands/diff.js +183 -0
  17. package/dist/commands/diff.js.map +7 -0
  18. package/dist/commands/files.js +99 -0
  19. package/dist/commands/files.js.map +7 -0
  20. package/dist/commands/install.d.ts +2 -0
  21. package/dist/commands/install.js +79 -0
  22. package/dist/commands/install.js.map +7 -0
  23. package/dist/commands/list.d.ts +2 -0
  24. package/dist/commands/list.js +92 -0
  25. package/dist/commands/list.js.map +7 -0
  26. package/dist/commands/login.d.ts +2 -0
  27. package/dist/commands/login.js +134 -0
  28. package/dist/commands/login.js.map +7 -0
  29. package/dist/commands/logout.d.ts +2 -0
  30. package/dist/commands/logout.js +59 -0
  31. package/dist/commands/logout.js.map +7 -0
  32. package/dist/commands/mcp-server.d.ts +8 -0
  33. package/dist/commands/mcp-server.js +41 -0
  34. package/dist/commands/mcp-server.js.map +7 -0
  35. package/dist/commands/model.d.ts +2 -0
  36. package/dist/commands/model.js +189 -0
  37. package/dist/commands/model.js.map +7 -0
  38. package/dist/commands/pull.d.ts +2 -0
  39. package/dist/commands/pull.js +287 -0
  40. package/dist/commands/pull.js.map +7 -0
  41. package/dist/commands/push.d.ts +2 -0
  42. package/dist/commands/push.js +251 -0
  43. package/dist/commands/push.js.map +7 -0
  44. package/dist/commands/run.d.ts +2 -0
  45. package/dist/commands/run.js +246 -0
  46. package/dist/commands/run.js.map +7 -0
  47. package/dist/commands/setup.d.ts +2 -0
  48. package/dist/commands/setup.js +137 -0
  49. package/dist/commands/status.d.ts +2 -0
  50. package/dist/commands/status.js +145 -0
  51. package/dist/commands/status.js.map +7 -0
  52. package/dist/commands/unsetup.d.ts +2 -0
  53. package/dist/commands/unsetup.js +122 -0
  54. package/dist/commands/whoami.d.ts +2 -0
  55. package/dist/commands/whoami.js +63 -0
  56. package/dist/commands/whoami.js.map +7 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.js +135 -0
  59. package/dist/index.js.map +7 -0
  60. package/dist/mcp/index.d.ts +7 -0
  61. package/dist/mcp/index.js +35 -0
  62. package/dist/mcp/index.js.map +7 -0
  63. package/dist/mcp/prompts/workflows.d.ts +7 -0
  64. package/dist/mcp/prompts/workflows.js +374 -0
  65. package/dist/mcp/prompts/workflows.js.map +7 -0
  66. package/dist/mcp/resources/documentation.d.ts +8 -0
  67. package/dist/mcp/resources/documentation.js +167 -0
  68. package/dist/mcp/resources/documentation.js.map +7 -0
  69. package/dist/mcp/server.d.ts +7 -0
  70. package/dist/mcp/server.js +49 -0
  71. package/dist/mcp/server.js.map +7 -0
  72. package/dist/mcp/tools/appTools.d.ts +7 -0
  73. package/dist/mcp/tools/appTools.js +377 -0
  74. package/dist/mcp/tools/appTools.js.map +7 -0
  75. package/dist/mcp/tools/authTools.d.ts +7 -0
  76. package/dist/mcp/tools/authTools.js +158 -0
  77. package/dist/mcp/tools/authTools.js.map +7 -0
  78. package/dist/mcp/tools/modelTools.d.ts +7 -0
  79. package/dist/mcp/tools/modelTools.js +331 -0
  80. package/dist/mcp/tools/modelTools.js.map +7 -0
  81. package/dist/mcp/tools/runTools.d.ts +7 -0
  82. package/dist/mcp/tools/runTools.js +231 -0
  83. package/dist/mcp/tools/runTools.js.map +7 -0
  84. package/dist/mcp/tools/syncTools.d.ts +7 -0
  85. package/dist/mcp/tools/syncTools.js +382 -0
  86. package/dist/mcp/tools/syncTools.js.map +7 -0
  87. package/dist/mcp/utils/helpers.d.ts +69 -0
  88. package/dist/mcp/utils/helpers.js +113 -0
  89. package/dist/mcp/utils/helpers.js.map +7 -0
  90. package/dist/services/appSyncService.d.ts +75 -0
  91. package/dist/services/appSyncService.js +370 -0
  92. package/dist/services/appSyncService.js.map +7 -0
  93. package/dist/services/configService.d.ts +39 -0
  94. package/dist/services/configService.js +196 -0
  95. package/dist/services/configService.js.map +7 -0
  96. package/dist/services/farseerApi.d.ts +166 -0
  97. package/dist/services/farseerApi.js +378 -0
  98. package/dist/services/farseerApi.js.map +7 -0
  99. package/dist/services/farseerFactory.d.ts +88 -0
  100. package/dist/services/farseerFactory.js +179 -0
  101. package/dist/services/farseerFactory.js.map +7 -0
  102. package/dist/services/farseerService.d.ts +96 -0
  103. package/dist/services/farseerService.js +614 -0
  104. package/dist/services/farseerService.js.map +7 -0
  105. package/dist/services/gitService.d.ts +31 -0
  106. package/dist/services/gitService.js +134 -0
  107. package/dist/services/gitService.js.map +7 -0
  108. package/dist/services/syncService.d.ts +44 -0
  109. package/dist/services/syncService.js +320 -0
  110. package/dist/services/syncService.js.map +7 -0
  111. package/dist/utils/constants.d.ts +7 -0
  112. package/dist/utils/constants.js +46 -0
  113. package/dist/utils/constants.js.map +7 -0
  114. package/dist/utils/helpers.d.ts +69 -0
  115. package/dist/utils/helpers.js +413 -0
  116. package/dist/utils/helpers.js.map +7 -0
  117. package/dist/utils/logger.d.ts +14 -0
  118. package/dist/utils/logger.js +76 -0
  119. package/dist/utils/logger.js.map +7 -0
  120. package/package.json +62 -0
package/dist/index.js ADDED
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var import_commander = require("commander");
25
+ var import_chalk = __toESM(require("chalk"));
26
+ var import_login = require("./commands/login");
27
+ var import_logout = require("./commands/logout");
28
+ var import_config = require("./commands/config");
29
+ var import_list = require("./commands/list");
30
+ var import_files = require("./commands/files");
31
+ var import_status = require("./commands/status");
32
+ var import_diff = require("./commands/diff");
33
+ var import_pull = require("./commands/pull");
34
+ var import_push = require("./commands/push");
35
+ var import_run = require("./commands/run");
36
+ var import_install = require("./commands/install");
37
+ var import_whoami = require("./commands/whoami");
38
+ var import_app = require("./commands/app");
39
+ var import_model = require("./commands/model");
40
+ var import_checkout = require("./commands/checkout");
41
+ var import_mcp_server = require("./commands/mcp-server");
42
+ const originalEmit = process.emit;
43
+ process.emit = function(name, data, ...args) {
44
+ if (name === "warning" && typeof data === "object" && data !== null && "name" in data && data.name === "DeprecationWarning" && "message" in data && typeof data.message === "string" && data.message.includes("punycode")) {
45
+ return false;
46
+ }
47
+ return originalEmit.apply(process, [name, data, ...args]);
48
+ };
49
+ const program = new import_commander.Command();
50
+ program.configureHelp({
51
+ visibleCommands: () => []
52
+ // Hide all commands from default list
53
+ });
54
+ program.name("farseer").description("CLI tool for syncing Farseer App scripts between local repository and Farseer instances").version("1.0.0").addHelpText("after", `
55
+ ${import_chalk.default.bold.underline("Authentication")}
56
+ login Login via browser (OAuth) or use --api-key
57
+ logout [tenant] Logout and remove credentials
58
+ whoami Show login status and configured tenants
59
+ checkout [tenant] Set default tenant (verifies auth & pulls)
60
+ ${import_chalk.default.dim("--no-pull")} Skip automatic pull
61
+
62
+ ${import_chalk.default.bold.underline("Configuration")} ${import_chalk.default.dim("(farseer config <command>)")}
63
+ config set <tenant> Set API key for a tenant
64
+ ${import_chalk.default.dim("--api-key <key>")} API key (required)
65
+ ${import_chalk.default.dim("--org <name>")} Organisation if different from tenant
66
+ config remove <tenant> Remove credentials
67
+ config list List all configured tenants
68
+ config show <tenant> Show full credentials (incl. API key)
69
+ config test <tenant> Test connection to tenant
70
+
71
+ ${import_chalk.default.bold.underline("Sync Operations")} ${import_chalk.default.dim("(tenant optional if checked out)")}
72
+ pull [tenant] Pull files and apps from remote
73
+ ${import_chalk.default.dim("--no-git")} Skip git operations
74
+ ${import_chalk.default.dim("--all")} Download all files (not just .ts/.js)
75
+ push [tenant] Push local changes to remote
76
+ ${import_chalk.default.dim("-m, --message <msg>")} Commit message (required)
77
+ ${import_chalk.default.dim("--no-git")} Skip git operations
78
+ status [tenant] Show sync status (local vs remote)
79
+ ${import_chalk.default.dim("--all")} Show all files (not just .ts/.js)
80
+ diff [tenant] [file] Show file differences
81
+
82
+ ${import_chalk.default.bold.underline("App Management")} ${import_chalk.default.dim("(tenant optional if checked out)")}
83
+ app list [tenant] List all apps
84
+ ${import_chalk.default.dim("--details")} Show details for each app
85
+ app show [tenant] <name> Show app details
86
+ app create [tenant] <name> Create new app
87
+ app configure [tenant] <name> Configure app
88
+ ${import_chalk.default.dim("--entrypoint <script>")} Set main script
89
+ ${import_chalk.default.dim("--scripts <list>")} Comma-separated scripts
90
+ ${import_chalk.default.dim("--add-arg <Name=Value>")} Add argument (repeatable)
91
+ ${import_chalk.default.dim("--description <text>")} Set description
92
+ app delete [tenant] <name> Delete app (requires --force)
93
+
94
+ ${import_chalk.default.bold.underline("Running & Development")} ${import_chalk.default.dim("(tenant optional if checked out)")}
95
+ run [tenant] <app> Run app locally with injected credentials
96
+ ${import_chalk.default.dim("--arg <Name=Value>")} Override argument (repeatable)
97
+ run-script [tenant] <file> Run script directly (no app wrapper)
98
+ install [tenant] Install npm dependencies (npm install)
99
+
100
+ ${import_chalk.default.bold.underline("Model Inspection")} ${import_chalk.default.dim("(tenant optional if checked out)")}
101
+ model [tenant] Show model structure (dimensions, variables)
102
+ ${import_chalk.default.dim("--variables")} List all variables
103
+ ${import_chalk.default.dim("--tables")} List all dimension tables
104
+ ${import_chalk.default.dim("--variable <name>")} Show dimensions for variable
105
+
106
+ ${import_chalk.default.bold.underline("File Management")} ${import_chalk.default.dim("(farseer files <command>)")}
107
+ files list [tenant] List files on remote
108
+ ${import_chalk.default.dim("--all")} Show all files (not just scripts)
109
+
110
+ ${import_chalk.default.bold.underline("Examples")}
111
+ ${import_chalk.default.green("$")} farseer login ${import_chalk.default.dim("Login via browser")}
112
+ ${import_chalk.default.green("$")} farseer config set myco --api-key xxx ${import_chalk.default.dim("Add tenant with API key")}
113
+ ${import_chalk.default.green("$")} farseer pull mycompany --no-git ${import_chalk.default.dim("Download scripts & apps")}
114
+ ${import_chalk.default.green("$")} farseer push mycompany -m "Fix bug" ${import_chalk.default.dim("Upload changes")}
115
+ ${import_chalk.default.green("$")} farseer run mycompany "My App" ${import_chalk.default.dim("Run app locally")}
116
+ ${import_chalk.default.green("$")} farseer model mycompany --variables ${import_chalk.default.dim("List all variables")}
117
+ `);
118
+ (0, import_login.registerLoginCommand)(program);
119
+ (0, import_logout.registerLogoutCommand)(program);
120
+ (0, import_checkout.registerCheckoutCommand)(program);
121
+ (0, import_config.registerConfigCommand)(program);
122
+ (0, import_list.registerListCommand)(program);
123
+ (0, import_files.registerFilesCommand)(program);
124
+ (0, import_app.registerAppCommand)(program);
125
+ (0, import_model.registerModelCommand)(program);
126
+ (0, import_status.registerStatusCommand)(program);
127
+ (0, import_diff.registerDiffCommand)(program);
128
+ (0, import_pull.registerPullCommand)(program);
129
+ (0, import_push.registerPushCommand)(program);
130
+ (0, import_run.registerRunCommand)(program);
131
+ (0, import_install.registerInstallCommand)(program);
132
+ (0, import_whoami.registerWhoamiCommand)(program);
133
+ (0, import_mcp_server.registerMcpServerCommand)(program);
134
+ program.parse();
135
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n\n// Suppress punycode deprecation warning (comes from dependencies like axios)\nconst originalEmit = process.emit;\n// @ts-expect-error - overriding process.emit\nprocess.emit = function (name: string, data: unknown, ...args: unknown[]) {\n if (name === 'warning' && typeof data === 'object' && data !== null && 'name' in data && data.name === 'DeprecationWarning' && 'message' in data && typeof data.message === 'string' && data.message.includes('punycode')) {\n return false;\n }\n // @ts-expect-error - calling original emit\n return originalEmit.apply(process, [name, data, ...args]);\n};\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { registerLoginCommand } from './commands/login';\nimport { registerLogoutCommand } from './commands/logout';\nimport { registerConfigCommand } from './commands/config';\nimport { registerListCommand } from './commands/list';\nimport { registerFilesCommand } from './commands/files';\nimport { registerStatusCommand } from './commands/status';\nimport { registerDiffCommand } from './commands/diff';\nimport { registerPullCommand } from './commands/pull';\nimport { registerPushCommand } from './commands/push';\nimport { registerRunCommand } from './commands/run';\nimport { registerInstallCommand } from './commands/install';\nimport { registerWhoamiCommand } from './commands/whoami';\nimport { registerAppCommand } from './commands/app';\nimport { registerModelCommand } from './commands/model';\nimport { registerCheckoutCommand } from './commands/checkout';\nimport { registerMcpServerCommand } from './commands/mcp-server';\n\nconst program = new Command();\n\n// Configure help to hide default command list (we show our own custom list)\nprogram.configureHelp({\n visibleCommands: () => [], // Hide all commands from default list\n});\n\nprogram\n .name('farseer')\n .description('CLI tool for syncing Farseer App scripts between local repository and Farseer instances')\n .version('1.0.0')\n .addHelpText('after', `\n${chalk.bold.underline('Authentication')}\n login Login via browser (OAuth) or use --api-key\n logout [tenant] Logout and remove credentials\n whoami Show login status and configured tenants\n checkout [tenant] Set default tenant (verifies auth & pulls)\n ${chalk.dim('--no-pull')} Skip automatic pull\n\n${chalk.bold.underline('Configuration')} ${chalk.dim('(farseer config <command>)')}\n config set <tenant> Set API key for a tenant\n ${chalk.dim('--api-key <key>')} API key (required)\n ${chalk.dim('--org <name>')} Organisation if different from tenant\n config remove <tenant> Remove credentials\n config list List all configured tenants\n config show <tenant> Show full credentials (incl. API key)\n config test <tenant> Test connection to tenant\n\n${chalk.bold.underline('Sync Operations')} ${chalk.dim('(tenant optional if checked out)')}\n pull [tenant] Pull files and apps from remote\n ${chalk.dim('--no-git')} Skip git operations\n ${chalk.dim('--all')} Download all files (not just .ts/.js)\n push [tenant] Push local changes to remote\n ${chalk.dim('-m, --message <msg>')} Commit message (required)\n ${chalk.dim('--no-git')} Skip git operations\n status [tenant] Show sync status (local vs remote)\n ${chalk.dim('--all')} Show all files (not just .ts/.js)\n diff [tenant] [file] Show file differences\n\n${chalk.bold.underline('App Management')} ${chalk.dim('(tenant optional if checked out)')}\n app list [tenant] List all apps\n ${chalk.dim('--details')} Show details for each app\n app show [tenant] <name> Show app details\n app create [tenant] <name> Create new app\n app configure [tenant] <name> Configure app\n ${chalk.dim('--entrypoint <script>')} Set main script\n ${chalk.dim('--scripts <list>')} Comma-separated scripts\n ${chalk.dim('--add-arg <Name=Value>')} Add argument (repeatable)\n ${chalk.dim('--description <text>')} Set description\n app delete [tenant] <name> Delete app (requires --force)\n\n${chalk.bold.underline('Running & Development')} ${chalk.dim('(tenant optional if checked out)')}\n run [tenant] <app> Run app locally with injected credentials\n ${chalk.dim('--arg <Name=Value>')} Override argument (repeatable)\n run-script [tenant] <file> Run script directly (no app wrapper)\n install [tenant] Install npm dependencies (npm install)\n\n${chalk.bold.underline('Model Inspection')} ${chalk.dim('(tenant optional if checked out)')}\n model [tenant] Show model structure (dimensions, variables)\n ${chalk.dim('--variables')} List all variables\n ${chalk.dim('--tables')} List all dimension tables\n ${chalk.dim('--variable <name>')} Show dimensions for variable\n\n${chalk.bold.underline('File Management')} ${chalk.dim('(farseer files <command>)')}\n files list [tenant] List files on remote\n ${chalk.dim('--all')} Show all files (not just scripts)\n\n${chalk.bold.underline('Examples')}\n ${chalk.green('$')} farseer login ${chalk.dim('Login via browser')}\n ${chalk.green('$')} farseer config set myco --api-key xxx ${chalk.dim('Add tenant with API key')}\n ${chalk.green('$')} farseer pull mycompany --no-git ${chalk.dim('Download scripts & apps')}\n ${chalk.green('$')} farseer push mycompany -m \"Fix bug\" ${chalk.dim('Upload changes')}\n ${chalk.green('$')} farseer run mycompany \"My App\" ${chalk.dim('Run app locally')}\n ${chalk.green('$')} farseer model mycompany --variables ${chalk.dim('List all variables')}\n`);\n\n// Register all commands (hidden from default help, shown in custom help above)\nregisterLoginCommand(program);\nregisterLogoutCommand(program);\nregisterCheckoutCommand(program);\nregisterConfigCommand(program);\nregisterListCommand(program);\nregisterFilesCommand(program);\nregisterAppCommand(program);\nregisterModelCommand(program);\nregisterStatusCommand(program);\nregisterDiffCommand(program);\nregisterPullCommand(program);\nregisterPushCommand(program);\nregisterRunCommand(program);\nregisterInstallCommand(program);\nregisterWhoamiCommand(program);\nregisterMcpServerCommand(program);\n\n// Parse arguments\nprogram.parse();\n"],
5
+ "mappings": "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",
6
+ "names": ["chalk"]
7
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP Server Entry Point
3
+ *
4
+ * Starts the Farseer MCP server for AI assistant integration.
5
+ * Uses stdio transport for CLI compatibility.
6
+ */
7
+ export declare function startMcpServer(): Promise<void>;
@@ -0,0 +1,35 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var mcp_exports = {};
19
+ __export(mcp_exports, {
20
+ startMcpServer: () => startMcpServer
21
+ });
22
+ module.exports = __toCommonJS(mcp_exports);
23
+ var import_server = require("./server");
24
+ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
25
+ async function startMcpServer() {
26
+ const server = (0, import_server.createMcpServer)();
27
+ const transport = new import_stdio.StdioServerTransport();
28
+ await server.connect(transport);
29
+ console.error("Farseer MCP server started");
30
+ }
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ startMcpServer
34
+ });
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/mcp/index.ts"],
4
+ "sourcesContent": ["/**\n * MCP Server Entry Point\n *\n * Starts the Farseer MCP server for AI assistant integration.\n * Uses stdio transport for CLI compatibility.\n */\n\nimport { createMcpServer } from './server';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n\nexport async function startMcpServer(): Promise<void> {\n const server = createMcpServer();\n\n // Use stdio transport for CLI integration\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n // Log to stderr since stdout is reserved for MCP protocol\n console.error('Farseer MCP server started');\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,oBAAgC;AAChC,mBAAqC;AAErC,eAAsB,iBAAgC;AAClD,QAAM,aAAS,+BAAgB;AAG/B,QAAM,YAAY,IAAI,kCAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAG9B,UAAQ,MAAM,4BAA4B;AAC9C;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Workflow Prompts
3
+ *
4
+ * Reusable prompt templates for common Farseer workflows.
5
+ */
6
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
+ export declare function registerWorkflowPrompts(server: McpServer): void;
@@ -0,0 +1,374 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var workflows_exports = {};
19
+ __export(workflows_exports, {
20
+ registerWorkflowPrompts: () => registerWorkflowPrompts
21
+ });
22
+ module.exports = __toCommonJS(workflows_exports);
23
+ var import_zod = require("zod");
24
+ const setupTenantSchema = {
25
+ tenant: import_zod.z.string().describe("Tenant name to setup")
26
+ };
27
+ const createAppSchema = {
28
+ tenant: import_zod.z.string().describe("Tenant name"),
29
+ appName: import_zod.z.string().describe("Name for the new app"),
30
+ scriptName: import_zod.z.string().optional().describe("Main script filename (default: index.ts)")
31
+ };
32
+ const understandModelSchema = {
33
+ tenant: import_zod.z.string().describe("Tenant name")
34
+ };
35
+ const writeImportScriptSchema = {
36
+ tenant: import_zod.z.string().describe("Tenant name"),
37
+ variableName: import_zod.z.string().describe("Target variable to import into")
38
+ };
39
+ const copyAppSchema = {
40
+ tenant: import_zod.z.string().describe("Tenant name"),
41
+ sourceApp: import_zod.z.string().describe("Name of app to copy"),
42
+ newAppName: import_zod.z.string().describe("Name for the new app")
43
+ };
44
+ const debugSyncSchema = {
45
+ tenant: import_zod.z.string().describe("Tenant name")
46
+ };
47
+ function registerWorkflowPrompts(server) {
48
+ const anyServer = server;
49
+ anyServer.prompt(
50
+ "setup_new_tenant",
51
+ "Guide for setting up a new Farseer tenant: login, checkout, pull, install dependencies.",
52
+ setupTenantSchema,
53
+ async (params) => {
54
+ const { tenant } = params;
55
+ return {
56
+ messages: [
57
+ {
58
+ role: "user",
59
+ content: {
60
+ type: "text",
61
+ text: `You are setting up a new Farseer tenant "${tenant}".
62
+
63
+ Steps to follow:
64
+
65
+ 1. First, check authentication status with farseer_whoami
66
+ 2. If not logged in, inform the user to run "farseer login" in terminal (MCP cannot do browser login)
67
+ 3. Use farseer_checkout to set "${tenant}" as the default tenant (this also pulls files and apps)
68
+ 4. Tell user to run "farseer install ${tenant}" in terminal to install npm dependencies
69
+ 5. Use farseer_list_apps to show available apps
70
+ 6. Use farseer_export_model to understand the data structure
71
+
72
+ After setup, the user can:
73
+ - Run apps with farseer_run_app
74
+ - Edit scripts in apps/${tenant}/files/Scripts/
75
+ - Push changes with farseer_push
76
+ - Check model with farseer_get_variable or farseer_get_table`
77
+ }
78
+ }
79
+ ]
80
+ };
81
+ }
82
+ );
83
+ anyServer.prompt(
84
+ "create_new_app",
85
+ "Guide for creating a new Farseer app from scratch.",
86
+ createAppSchema,
87
+ async (params) => {
88
+ const { tenant, appName, scriptName } = params;
89
+ const script = scriptName || "index.ts";
90
+ return {
91
+ messages: [
92
+ {
93
+ role: "user",
94
+ content: {
95
+ type: "text",
96
+ text: `Creating a new Farseer app "${appName}" for tenant "${tenant}".
97
+
98
+ Steps to follow:
99
+
100
+ 1. Check if the script "${script}" exists with farseer_status
101
+ 2. If script doesn't exist locally:
102
+ - Create the script file at apps/${tenant}/files/Scripts/${script}
103
+ - Push with farseer_push
104
+
105
+ 3. Use farseer_create_app to create the app named "${appName}"
106
+
107
+ 4. Use farseer_configure_app to set:
108
+ - entrypoint: "${script}"
109
+ - scripts: ["${script}"]
110
+ - Add arguments if needed
111
+
112
+ 5. Test with farseer_run_app
113
+
114
+ Script template to create:
115
+ \`\`\`typescript
116
+ import * as farseer from 'farseer-client';
117
+
118
+ const args = process.argv.slice(2);
119
+ console.log('Arguments:', args);
120
+
121
+ const client = new farseer.FarseerClient();
122
+
123
+ async function main() {
124
+ await client.initTagMap();
125
+
126
+ // Your code here
127
+ console.log('App running successfully');
128
+ }
129
+
130
+ main().catch(farseer.handleUnknownError);
131
+ \`\`\``
132
+ }
133
+ }
134
+ ]
135
+ };
136
+ }
137
+ );
138
+ anyServer.prompt(
139
+ "understand_model",
140
+ "Explore and understand the data model of a Farseer tenant.",
141
+ understandModelSchema,
142
+ async (params) => {
143
+ const { tenant } = params;
144
+ return {
145
+ messages: [
146
+ {
147
+ role: "user",
148
+ content: {
149
+ type: "text",
150
+ text: `Analyzing the data model for tenant "${tenant}".
151
+
152
+ Steps to follow:
153
+
154
+ 1. Use farseer_export_model to get the full model structure
155
+
156
+ 2. Review dimension tables:
157
+ - Use farseer_list_tables for overview
158
+ - Key dimensions usually include: Products, Regions, Time (Months, Years), Versions
159
+ - Check foreign key relationships between tables
160
+
161
+ 3. Review variables:
162
+ - Use farseer_list_variables for overview
163
+ - Use farseer_get_variable for specific variable details
164
+ - Note which dimensions each variable has
165
+
166
+ 4. For import scripts, you need to know:
167
+ - Target variable name
168
+ - All dimensions the variable has
169
+ - Valid members for each dimension
170
+
171
+ Key concepts:
172
+ - Dimensions structure the data (Product, Region, Month, Year, Version)
173
+ - Variables store values at dimension intersections
174
+ - Formulas calculate values automatically
175
+ - Roll-up types determine aggregation (SUM, AVERAGE, etc.)
176
+
177
+ Common dimension tables:
178
+ - Months, Years (time)
179
+ - Versions (Plan, Actual, Forecast)
180
+ - Products, Categories, Brands
181
+ - Regions, Entities, Cost Centers`
182
+ }
183
+ }
184
+ ]
185
+ };
186
+ }
187
+ );
188
+ anyServer.prompt(
189
+ "write_import_script",
190
+ "Guide for writing a data import script.",
191
+ writeImportScriptSchema,
192
+ async (params) => {
193
+ const { tenant, variableName } = params;
194
+ return {
195
+ messages: [
196
+ {
197
+ role: "user",
198
+ content: {
199
+ type: "text",
200
+ text: `Writing an import script for variable "${variableName}" in tenant "${tenant}".
201
+
202
+ Steps to follow:
203
+
204
+ 1. Use farseer_get_variable to understand the target variable:
205
+ - What dimensions does it have?
206
+ - What is the roll-up type?
207
+
208
+ 2. Use farseer_get_table for each dimension to see valid members
209
+
210
+ 3. Create the import script with this pattern:
211
+
212
+ \`\`\`typescript
213
+ import * as farseer from 'farseer-client';
214
+
215
+ const client = new farseer.FarseerClient();
216
+
217
+ async function main() {
218
+ await client.initTagMap();
219
+
220
+ // Create import job with column definitions
221
+ const importJob = await client.createImportJob({
222
+ title: 'Import ${variableName}',
223
+ columns: [
224
+ { type: 'DIMENSION_TABLE', dimensionTableName: 'Product' },
225
+ { type: 'DIMENSION_TABLE', dimensionTableName: 'Years' },
226
+ { type: 'DIMENSION_TABLE', dimensionTableName: 'Months' },
227
+ { type: 'DIMENSION_TABLE', dimensionTableName: 'Versions' },
228
+ { type: 'VARIABLE', variableName: '${variableName}' },
229
+ ],
230
+ labels: ['auto', 'import-${variableName.toLowerCase().replace(/\s+/g, "-")}']
231
+ });
232
+
233
+ // Add rows - each row matches column order
234
+ const rows = [
235
+ ['ProductA', 'Y2025', 'M1', 'Plan', 1000],
236
+ ['ProductB', 'Y2025', 'M1', 'Plan', 2000],
237
+ ];
238
+
239
+ await importJob.addRows(rows);
240
+ await importJob.flushRows();
241
+ await importJob.undoPrevious(); // Remove previous import
242
+ await importJob.commit();
243
+
244
+ console.log('Import completed!');
245
+ }
246
+
247
+ main().catch(farseer.handleUnknownError);
248
+ \`\`\`
249
+
250
+ 4. Save script to apps/${tenant}/files/Scripts/
251
+ 5. Push with farseer_push
252
+ 6. Create app with farseer_create_app
253
+ 7. Configure with farseer_configure_app
254
+ 8. Test with farseer_run_app`
255
+ }
256
+ }
257
+ ]
258
+ };
259
+ }
260
+ );
261
+ anyServer.prompt(
262
+ "copy_app",
263
+ "Guide for copying an existing app to create a new one.",
264
+ copyAppSchema,
265
+ async (params) => {
266
+ const { tenant, sourceApp, newAppName } = params;
267
+ return {
268
+ messages: [
269
+ {
270
+ role: "user",
271
+ content: {
272
+ type: "text",
273
+ text: `Copying app "${sourceApp}" to create "${newAppName}" for tenant "${tenant}".
274
+
275
+ Steps to follow:
276
+
277
+ 1. Pull latest with farseer_pull to get current app JSON
278
+
279
+ 2. Use farseer_get_app to see the source app configuration
280
+
281
+ 3. The app JSON files are in apps/${tenant}/apps/
282
+
283
+ Copy the source JSON file and modify:
284
+ - Change "name" to "${newAppName}"
285
+ - **IMPORTANT: Remove "_remote" field** (this makes it a new app)
286
+ - Modify arguments, description as needed
287
+
288
+ 4. JSON format for new app:
289
+ \`\`\`json
290
+ {
291
+ "name": "${newAppName}",
292
+ "description": "Copied from ${sourceApp}",
293
+ "entrypoint": "script.ts",
294
+ "scripts": ["script.ts"],
295
+ "arguments": [
296
+ { "name": "Year", "defaultValue": "2025" }
297
+ ]
298
+ }
299
+ \`\`\`
300
+
301
+ Note: Do NOT include "_remote" for new apps - CLI adds it after first push.
302
+
303
+ 5. Push with farseer_push to create the new app
304
+
305
+ 6. Test with farseer_run_app`
306
+ }
307
+ }
308
+ ]
309
+ };
310
+ }
311
+ );
312
+ anyServer.prompt(
313
+ "debug_sync_issues",
314
+ "Troubleshoot synchronization problems between local and remote.",
315
+ debugSyncSchema,
316
+ async (params) => {
317
+ const { tenant } = params;
318
+ return {
319
+ messages: [
320
+ {
321
+ role: "user",
322
+ content: {
323
+ type: "text",
324
+ text: `Debugging sync issues for tenant "${tenant}".
325
+
326
+ Steps to follow:
327
+
328
+ 1. Check authentication: farseer_whoami
329
+ - Is JWT valid?
330
+ - Is tenant checked out?
331
+
332
+ 2. Check sync status: farseer_status
333
+ - Are there modified files?
334
+ - Are there only-local or only-remote files?
335
+
336
+ 3. If files show as modified:
337
+ - Use farseer_diff to see differences
338
+ - Decide: pull (accept remote) or push (upload local)
339
+
340
+ 4. Common issues and solutions:
341
+
342
+ **"No credentials found"**
343
+ \u2192 User needs to run "farseer login" in terminal
344
+ \u2192 Or configure API key: "farseer config set ${tenant} --api-key KEY"
345
+
346
+ **"Remote has changes"**
347
+ \u2192 Pull first with farseer_pull
348
+ \u2192 Then push with farseer_push
349
+
350
+ **"Token expired"**
351
+ \u2192 User needs to run "farseer login" again
352
+
353
+ **Apps not syncing**
354
+ \u2192 Need JWT login (browser), not API key
355
+ \u2192 API key only syncs files, not apps
356
+
357
+ 5. Force resolution:
358
+ - To accept remote: farseer_pull (overwrites local)
359
+ - To accept local: farseer_push with force=true (overwrites remote)
360
+
361
+ 6. Check specific file diff:
362
+ - Use farseer_diff with file parameter to see exact changes`
363
+ }
364
+ }
365
+ ]
366
+ };
367
+ }
368
+ );
369
+ }
370
+ // Annotate the CommonJS export names for ESM import in node:
371
+ 0 && (module.exports = {
372
+ registerWorkflowPrompts
373
+ });
374
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/prompts/workflows.ts"],
4
+ "sourcesContent": ["/**\n * Workflow Prompts\n *\n * Reusable prompt templates for common Farseer workflows.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\n// Define schemas outside of prompt registration to avoid deep type instantiation\nconst setupTenantSchema = {\n tenant: z.string().describe('Tenant name to setup'),\n};\n\nconst createAppSchema = {\n tenant: z.string().describe('Tenant name'),\n appName: z.string().describe('Name for the new app'),\n scriptName: z.string().optional().describe('Main script filename (default: index.ts)'),\n};\n\nconst understandModelSchema = {\n tenant: z.string().describe('Tenant name'),\n};\n\nconst writeImportScriptSchema = {\n tenant: z.string().describe('Tenant name'),\n variableName: z.string().describe('Target variable to import into'),\n};\n\nconst copyAppSchema = {\n tenant: z.string().describe('Tenant name'),\n sourceApp: z.string().describe('Name of app to copy'),\n newAppName: z.string().describe('Name for the new app'),\n};\n\nconst debugSyncSchema = {\n tenant: z.string().describe('Tenant name'),\n};\n\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Cast to any to avoid very deep generic type instantiation from the MCP SDK\n const anyServer = server as any;\n // Setup new tenant\n anyServer.prompt(\n 'setup_new_tenant',\n 'Guide for setting up a new Farseer tenant: login, checkout, pull, install dependencies.',\n setupTenantSchema,\n async (params: { tenant: string }) => {\n const { tenant } = params;\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `You are setting up a new Farseer tenant \"${tenant}\".\n\nSteps to follow:\n\n1. First, check authentication status with farseer_whoami\n2. If not logged in, inform the user to run \"farseer login\" in terminal (MCP cannot do browser login)\n3. Use farseer_checkout to set \"${tenant}\" as the default tenant (this also pulls files and apps)\n4. Tell user to run \"farseer install ${tenant}\" in terminal to install npm dependencies\n5. Use farseer_list_apps to show available apps\n6. Use farseer_export_model to understand the data structure\n\nAfter setup, the user can:\n- Run apps with farseer_run_app\n- Edit scripts in apps/${tenant}/files/Scripts/\n- Push changes with farseer_push\n- Check model with farseer_get_variable or farseer_get_table`,\n },\n },\n ],\n };\n },\n );\n\n // Create new app\n anyServer.prompt(\n 'create_new_app',\n 'Guide for creating a new Farseer app from scratch.',\n createAppSchema,\n async (params: { tenant: string; appName: string; scriptName?: string }) => {\n const { tenant, appName, scriptName } = params;\n const script = scriptName || 'index.ts';\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Creating a new Farseer app \"${appName}\" for tenant \"${tenant}\".\n\nSteps to follow:\n\n1. Check if the script \"${script}\" exists with farseer_status\n2. If script doesn't exist locally:\n - Create the script file at apps/${tenant}/files/Scripts/${script}\n - Push with farseer_push\n\n3. Use farseer_create_app to create the app named \"${appName}\"\n\n4. Use farseer_configure_app to set:\n - entrypoint: \"${script}\"\n - scripts: [\"${script}\"]\n - Add arguments if needed\n\n5. Test with farseer_run_app\n\nScript template to create:\n\\`\\`\\`typescript\nimport * as farseer from 'farseer-client';\n\nconst args = process.argv.slice(2);\nconsole.log('Arguments:', args);\n\nconst client = new farseer.FarseerClient();\n\nasync function main() {\n await client.initTagMap();\n\n // Your code here\n console.log('App running successfully');\n}\n\nmain().catch(farseer.handleUnknownError);\n\\`\\`\\``,\n },\n },\n ],\n };\n },\n );\n\n // Understand model\n anyServer.prompt(\n 'understand_model',\n 'Explore and understand the data model of a Farseer tenant.',\n understandModelSchema,\n async (params: { tenant: string }) => {\n const { tenant } = params;\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Analyzing the data model for tenant \"${tenant}\".\n\nSteps to follow:\n\n1. Use farseer_export_model to get the full model structure\n\n2. Review dimension tables:\n - Use farseer_list_tables for overview\n - Key dimensions usually include: Products, Regions, Time (Months, Years), Versions\n - Check foreign key relationships between tables\n\n3. Review variables:\n - Use farseer_list_variables for overview\n - Use farseer_get_variable for specific variable details\n - Note which dimensions each variable has\n\n4. For import scripts, you need to know:\n - Target variable name\n - All dimensions the variable has\n - Valid members for each dimension\n\nKey concepts:\n- Dimensions structure the data (Product, Region, Month, Year, Version)\n- Variables store values at dimension intersections\n- Formulas calculate values automatically\n- Roll-up types determine aggregation (SUM, AVERAGE, etc.)\n\nCommon dimension tables:\n- Months, Years (time)\n- Versions (Plan, Actual, Forecast)\n- Products, Categories, Brands\n- Regions, Entities, Cost Centers`,\n },\n },\n ],\n };\n },\n );\n\n // Write import script\n anyServer.prompt(\n 'write_import_script',\n 'Guide for writing a data import script.',\n writeImportScriptSchema,\n async (params: { tenant: string; variableName: string }) => {\n const { tenant, variableName } = params;\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Writing an import script for variable \"${variableName}\" in tenant \"${tenant}\".\n\nSteps to follow:\n\n1. Use farseer_get_variable to understand the target variable:\n - What dimensions does it have?\n - What is the roll-up type?\n\n2. Use farseer_get_table for each dimension to see valid members\n\n3. Create the import script with this pattern:\n\n\\`\\`\\`typescript\nimport * as farseer from 'farseer-client';\n\nconst client = new farseer.FarseerClient();\n\nasync function main() {\n await client.initTagMap();\n\n // Create import job with column definitions\n const importJob = await client.createImportJob({\n title: 'Import ${variableName}',\n columns: [\n { type: 'DIMENSION_TABLE', dimensionTableName: 'Product' },\n { type: 'DIMENSION_TABLE', dimensionTableName: 'Years' },\n { type: 'DIMENSION_TABLE', dimensionTableName: 'Months' },\n { type: 'DIMENSION_TABLE', dimensionTableName: 'Versions' },\n { type: 'VARIABLE', variableName: '${variableName}' },\n ],\n labels: ['auto', 'import-${variableName.toLowerCase().replace(/\\s+/g, '-')}']\n });\n\n // Add rows - each row matches column order\n const rows = [\n ['ProductA', 'Y2025', 'M1', 'Plan', 1000],\n ['ProductB', 'Y2025', 'M1', 'Plan', 2000],\n ];\n\n await importJob.addRows(rows);\n await importJob.flushRows();\n await importJob.undoPrevious(); // Remove previous import\n await importJob.commit();\n\n console.log('Import completed!');\n}\n\nmain().catch(farseer.handleUnknownError);\n\\`\\`\\`\n\n4. Save script to apps/${tenant}/files/Scripts/\n5. Push with farseer_push\n6. Create app with farseer_create_app\n7. Configure with farseer_configure_app\n8. Test with farseer_run_app`,\n },\n },\n ],\n };\n },\n );\n\n // Copy existing app\n anyServer.prompt(\n 'copy_app',\n 'Guide for copying an existing app to create a new one.',\n copyAppSchema,\n async (params: { tenant: string; sourceApp: string; newAppName: string }) => {\n const { tenant, sourceApp, newAppName } = params;\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Copying app \"${sourceApp}\" to create \"${newAppName}\" for tenant \"${tenant}\".\n\nSteps to follow:\n\n1. Pull latest with farseer_pull to get current app JSON\n\n2. Use farseer_get_app to see the source app configuration\n\n3. The app JSON files are in apps/${tenant}/apps/\n\n Copy the source JSON file and modify:\n - Change \"name\" to \"${newAppName}\"\n - **IMPORTANT: Remove \"_remote\" field** (this makes it a new app)\n - Modify arguments, description as needed\n\n4. JSON format for new app:\n\\`\\`\\`json\n{\n \"name\": \"${newAppName}\",\n \"description\": \"Copied from ${sourceApp}\",\n \"entrypoint\": \"script.ts\",\n \"scripts\": [\"script.ts\"],\n \"arguments\": [\n { \"name\": \"Year\", \"defaultValue\": \"2025\" }\n ]\n}\n\\`\\`\\`\n\nNote: Do NOT include \"_remote\" for new apps - CLI adds it after first push.\n\n5. Push with farseer_push to create the new app\n\n6. Test with farseer_run_app`,\n },\n },\n ],\n };\n },\n );\n\n // Debug sync issues\n anyServer.prompt(\n 'debug_sync_issues',\n 'Troubleshoot synchronization problems between local and remote.',\n debugSyncSchema,\n async (params: { tenant: string }) => {\n const { tenant } = params;\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Debugging sync issues for tenant \"${tenant}\".\n\nSteps to follow:\n\n1. Check authentication: farseer_whoami\n - Is JWT valid?\n - Is tenant checked out?\n\n2. Check sync status: farseer_status\n - Are there modified files?\n - Are there only-local or only-remote files?\n\n3. If files show as modified:\n - Use farseer_diff to see differences\n - Decide: pull (accept remote) or push (upload local)\n\n4. Common issues and solutions:\n\n **\"No credentials found\"**\n \u2192 User needs to run \"farseer login\" in terminal\n \u2192 Or configure API key: \"farseer config set ${tenant} --api-key KEY\"\n\n **\"Remote has changes\"**\n \u2192 Pull first with farseer_pull\n \u2192 Then push with farseer_push\n\n **\"Token expired\"**\n \u2192 User needs to run \"farseer login\" again\n\n **Apps not syncing**\n \u2192 Need JWT login (browser), not API key\n \u2192 API key only syncs files, not apps\n\n5. Force resolution:\n - To accept remote: farseer_pull (overwrites local)\n - To accept local: farseer_push with force=true (overwrites remote)\n\n6. Check specific file diff:\n - Use farseer_diff with file parameter to see exact changes`,\n },\n },\n ],\n };\n },\n );\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,iBAAkB;AAGlB,MAAM,oBAAoB;AAAA,EACtB,QAAQ,aAAE,OAAO,EAAE,SAAS,sBAAsB;AACtD;AAEA,MAAM,kBAAkB;AAAA,EACpB,QAAQ,aAAE,OAAO,EAAE,SAAS,aAAa;AAAA,EACzC,SAAS,aAAE,OAAO,EAAE,SAAS,sBAAsB;AAAA,EACnD,YAAY,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0CAA0C;AACzF;AAEA,MAAM,wBAAwB;AAAA,EAC1B,QAAQ,aAAE,OAAO,EAAE,SAAS,aAAa;AAC7C;AAEA,MAAM,0BAA0B;AAAA,EAC5B,QAAQ,aAAE,OAAO,EAAE,SAAS,aAAa;AAAA,EACzC,cAAc,aAAE,OAAO,EAAE,SAAS,gCAAgC;AACtE;AAEA,MAAM,gBAAgB;AAAA,EAClB,QAAQ,aAAE,OAAO,EAAE,SAAS,aAAa;AAAA,EACzC,WAAW,aAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,EACpD,YAAY,aAAE,OAAO,EAAE,SAAS,sBAAsB;AAC1D;AAEA,MAAM,kBAAkB;AAAA,EACpB,QAAQ,aAAE,OAAO,EAAE,SAAS,aAAa;AAC7C;AAEO,SAAS,wBAAwB,QAAyB;AAE7D,QAAM,YAAY;AAElB,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAA+B;AAClC,YAAM,EAAE,OAAO,IAAI;AACnB,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,4CAA4C,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAMlD,MAAM;AAAA,uCACD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAMpB,MAAM;AAAA;AAAA;AAAA,YAGP;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAAqE;AACxE,YAAM,EAAE,QAAQ,SAAS,WAAW,IAAI;AACxC,YAAM,SAAS,cAAc;AAC7B,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,+BAA+B,OAAO,iBAAiB,MAAM;AAAA;AAAA;AAAA;AAAA,0BAIrE,MAAM;AAAA;AAAA,sCAEM,MAAM,kBAAkB,MAAM;AAAA;AAAA;AAAA,qDAGf,OAAO;AAAA;AAAA;AAAA,oBAGxC,MAAM;AAAA,kBACR,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAuBA;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAA+B;AAClC,YAAM,EAAE,OAAO,IAAI;AACnB,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,wCAAwC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAgCxD;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAAqD;AACxD,YAAM,EAAE,QAAQ,aAAa,IAAI;AACjC,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,0CAA0C,YAAY,gBAAgB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAsBrF,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iDAMY,YAAY;AAAA;AAAA,mCAE1B,aAAa,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAoBzD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,YAKP;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAAsE;AACzE,YAAM,EAAE,QAAQ,WAAW,WAAW,IAAI;AAC1C,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,gBAAgB,SAAS,gBAAgB,UAAU,iBAAiB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAQxE,MAAM;AAAA;AAAA;AAAA,yBAGjB,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAOtB,UAAU;AAAA,gCACS,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAcjB;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,YAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,WAA+B;AAClC,YAAM,EAAE,OAAO,IAAI;AACnB,aAAO;AAAA,QACH,UAAU;AAAA,UACN;AAAA,YACI,MAAM;AAAA,YACN,SAAS;AAAA,cACL,MAAM;AAAA,cACN,MAAM,qCAAqC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAoB5B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAmB/B;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Documentation Resources
3
+ *
4
+ * Exposes Farseer documentation as MCP resources for AI assistants.
5
+ * Documentation is bundled as embedded strings to work when CLI is installed globally.
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ export declare function registerDocumentationResources(server: McpServer): void;