clay-server 5.2.0-beta.5 → 5.2.0-beta.7

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 (246) hide show
  1. package/lib/claude-hook-installer.js +1 -267
  2. package/lib/claude-jsonl-watcher.js +1 -204
  3. package/lib/clay-control-presentation-binding.js +96 -0
  4. package/lib/clay-control-presentation.js +128 -0
  5. package/lib/clay-control-target-projection.js +26 -0
  6. package/lib/clay-mate-chat.js +1 -0
  7. package/lib/clay-mate-knowledge.js +1 -1
  8. package/lib/clay-product-control-tools.js +1 -1
  9. package/lib/clay-product-control.js +22 -12
  10. package/lib/clay-project-records.js +2 -1
  11. package/lib/clay-scheduling.js +1 -1
  12. package/lib/clay-screen-controls.js +13 -5
  13. package/lib/clay-skill-install.js +1 -33
  14. package/lib/clay-workspace-controls.js +2 -1
  15. package/lib/cli-sessions.js +1 -300
  16. package/lib/codex-defaults.js +1 -28
  17. package/lib/context-usage.js +3 -2
  18. package/lib/contextual-screen-snapshot.js +38 -0
  19. package/lib/daemon.js +5 -55
  20. package/lib/default-ai-runtime.js +4 -8
  21. package/lib/email-mcp-server.js +1 -1
  22. package/lib/kiro-defaults.js +1 -22
  23. package/lib/mate-context-service.js +138 -0
  24. package/lib/mate-context-tools.js +21 -0
  25. package/lib/mcp-proxy.js +2 -32
  26. package/lib/mcp-query-bridge.js +1 -1
  27. package/lib/mcp-source-adapters.js +1 -91
  28. package/lib/mcp-source-context.js +1 -42
  29. package/lib/mcp-source-discovery.js +1 -169
  30. package/lib/mcp-source-plugins.js +1 -68
  31. package/lib/mcp-source-restrictions.js +1 -47
  32. package/lib/mcp-tool-policy.js +1 -26
  33. package/lib/os-user-diagnostics.js +2 -4
  34. package/lib/os-users.js +4 -65
  35. package/lib/project-connection.js +14 -10
  36. package/lib/project-control-git-view.js +12 -0
  37. package/lib/project-filesystem.js +5 -1
  38. package/lib/project-http.js +7 -4
  39. package/lib/project-mcp.js +2 -2
  40. package/lib/project-notifications.js +5 -4
  41. package/lib/project-pair-result-delivery.js +2 -2
  42. package/lib/project-pair-usage.js +12 -13
  43. package/lib/project-pending-message-queue.js +3 -1
  44. package/lib/project-product-control.js +3 -1
  45. package/lib/project-scheduled-messages.js +4 -4
  46. package/lib/project-scheduled-task-control.js +1 -1
  47. package/lib/project-session-document.js +20 -5
  48. package/lib/project-session-history-actions.js +5 -3
  49. package/lib/project-session-pair.js +1 -1
  50. package/lib/project-session-runtime-actions.js +2 -1
  51. package/lib/project-session-spawn.js +2 -3
  52. package/lib/project-session-vendor.js +2 -1
  53. package/lib/project-sessions.js +18 -26
  54. package/lib/project-shared-browser.js +22 -5
  55. package/lib/project-studio-presentation.js +58 -0
  56. package/lib/project-user-message.js +37 -0
  57. package/lib/project-vendor-login.js +6 -36
  58. package/lib/project-workspace-query.js +11 -1
  59. package/lib/project.js +24 -7
  60. package/lib/public/app.js +25 -0
  61. package/lib/public/appearance-bootstrap.js +2 -0
  62. package/lib/public/css/contextual-clay.css +240 -0
  63. package/lib/public/css/messages.css +6 -2
  64. package/lib/public/modules/app-favicon.js +18 -9
  65. package/lib/public/modules/app-header.js +4 -2
  66. package/lib/public/modules/app-loop-ui.js +2 -0
  67. package/lib/public/modules/app-message-router.js +5 -1
  68. package/lib/public/modules/app-messages.js +50 -6
  69. package/lib/public/modules/app-notifications.js +11 -5
  70. package/lib/public/modules/app-panels.js +61 -123
  71. package/lib/public/modules/app-projects.js +3 -0
  72. package/lib/public/modules/app-rate-limit.js +7 -27
  73. package/lib/public/modules/chat-render-runtime.js +3 -0
  74. package/lib/public/modules/clay-control-activity.js +214 -0
  75. package/lib/public/modules/clay-control-copy.js +36 -0
  76. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  77. package/lib/public/modules/clay-control-object-targets.js +52 -0
  78. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  79. package/lib/public/modules/clay-control-targets.js +44 -0
  80. package/lib/public/modules/clay-navigation-render.js +52 -0
  81. package/lib/public/modules/clay-owner-navigation.js +11 -2
  82. package/lib/public/modules/clay-session-links.js +31 -0
  83. package/lib/public/modules/clay-studio-bridge.js +20 -0
  84. package/lib/public/modules/clay-studio-document.js +67 -0
  85. package/lib/public/modules/clay-studio-render.js +144 -0
  86. package/lib/public/modules/clay-tool-presentation.js +4 -0
  87. package/lib/public/modules/command-palette.js +26 -31
  88. package/lib/public/modules/contextual-ask-session.js +26 -0
  89. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  90. package/lib/public/modules/contextual-clay-session.js +130 -0
  91. package/lib/public/modules/contextual-clay-workspace.js +157 -0
  92. package/lib/public/modules/contextual-clay.js +237 -0
  93. package/lib/public/modules/contextual-composer.js +91 -0
  94. package/lib/public/modules/contextual-mate-context.js +115 -0
  95. package/lib/public/modules/contextual-mate-hint.js +40 -0
  96. package/lib/public/modules/contextual-mate-identity.js +23 -0
  97. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  98. package/lib/public/modules/contextual-search.js +137 -0
  99. package/lib/public/modules/contextual-session-citations.js +58 -0
  100. package/lib/public/modules/filebrowser.js +20 -1
  101. package/lib/public/modules/generation-stop.js +8 -5
  102. package/lib/public/modules/git-panel.js +3 -1
  103. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  104. package/lib/public/modules/input.js +35 -1
  105. package/lib/public/modules/issues-render.js +3 -2
  106. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  107. package/lib/public/modules/markdown.js +2 -34
  108. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  109. package/lib/public/modules/mcp-connection-view.js +1 -1
  110. package/lib/public/modules/message-delivery.js +10 -0
  111. package/lib/public/modules/pane-bridge.js +2 -2
  112. package/lib/public/modules/pending-message-queue.js +1 -0
  113. package/lib/public/modules/permission-control.js +5 -4
  114. package/lib/public/modules/product-review.js +26 -0
  115. package/lib/public/modules/project-chat-identity.js +13 -4
  116. package/lib/public/modules/project-logs-render.js +3 -0
  117. package/lib/public/modules/project-mate-navigation.js +58 -21
  118. package/lib/public/modules/scheduled-tasks.js +2 -0
  119. package/lib/public/modules/scheduler.js +2 -0
  120. package/lib/public/modules/search-clay-chat.js +5 -454
  121. package/lib/public/modules/session-create-form.js +10 -10
  122. package/lib/public/modules/settings-defaults.js +27 -28
  123. package/lib/public/modules/shared-browser.js +2 -0
  124. package/lib/public/modules/sidebar-mobile.js +4 -3
  125. package/lib/public/modules/sidebar-projects.js +1 -0
  126. package/lib/public/modules/sidebar-sessions.js +1 -0
  127. package/lib/public/modules/split-view.js +7 -16
  128. package/lib/public/modules/terminal.js +9 -0
  129. package/lib/public/modules/tools.js +6 -2
  130. package/lib/public/modules/tui-grab.js +1 -2
  131. package/lib/public/modules/vendor-login-browser.js +5 -3
  132. package/lib/public/modules/vendor-login.js +2 -2
  133. package/lib/public/modules/vendor-priority.js +15 -1
  134. package/lib/public/modules/wireframe-workbench.js +5 -2
  135. package/lib/public/muse-avatar.svg +4 -0
  136. package/lib/public/style.css +2 -0
  137. package/lib/safe-bash-commands.js +3 -45
  138. package/lib/sdk-bridge.js +131 -395
  139. package/lib/sdk-foreground-admission.js +16 -0
  140. package/lib/sdk-mcp-descriptors.js +2 -37
  141. package/lib/sdk-message-processor.js +50 -17
  142. package/lib/sdk-quota-snapshot.js +1 -1
  143. package/lib/sdk-response-recovery.js +1 -155
  144. package/lib/sdk-worker.js +2 -677
  145. package/lib/server-contextual-clay-settings.js +40 -0
  146. package/lib/server-contextual-mate-sessions.js +70 -0
  147. package/lib/server-home-chat.js +7 -1
  148. package/lib/server-home-clay-entry.js +23 -4
  149. package/lib/server-home-clay-session-links.js +12 -0
  150. package/lib/server-owner-ui.js +49 -8
  151. package/lib/server-settings.js +2 -0
  152. package/lib/server.js +18 -1
  153. package/lib/session-fork-history.js +21 -0
  154. package/lib/session-hygiene.js +3 -35
  155. package/lib/session-permission-mode.js +4 -3
  156. package/lib/session-skill-scope.js +11 -0
  157. package/lib/sessions.js +24 -89
  158. package/lib/terminal-manager.js +18 -11
  159. package/lib/tool-llm.js +1 -1
  160. package/lib/tui-transcript-index.js +1 -132
  161. package/lib/users-contextual-clay-preferences.js +31 -0
  162. package/lib/users.js +3 -0
  163. package/lib/vendor-login-browser.js +1 -11
  164. package/lib/workspace-assignment-service.js +25 -0
  165. package/lib/workspace-query-mcp-server.js +1 -1
  166. package/lib/ws-request.js +1 -0
  167. package/lib/ws-schema.js +10 -0
  168. package/lib/yoke/acp-agent-profiles.js +5 -3
  169. package/lib/yoke/adapters/antigravity.js +3 -14
  170. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  171. package/lib/yoke/adapters/claude.js +7 -42
  172. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  173. package/lib/yoke/adapters/codex.js +1 -0
  174. package/lib/yoke/adapters/kiro.js +3 -1
  175. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  176. package/lib/yoke/adapters/muse.js +122 -0
  177. package/lib/yoke/auth-events.js +17 -0
  178. package/lib/yoke/claude-hook-installer.js +271 -0
  179. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  180. package/lib/yoke/claude-maintenance.js +55 -0
  181. package/lib/yoke/claude-permission-patterns.js +53 -0
  182. package/lib/yoke/claude-response-recovery.js +155 -0
  183. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  184. package/lib/yoke/clay-skill-install.js +33 -0
  185. package/lib/yoke/cli-sessions.js +300 -0
  186. package/lib/yoke/codex-app-server.js +7 -12
  187. package/lib/yoke/configuration.js +13 -0
  188. package/lib/yoke/discovery.js +70 -0
  189. package/lib/yoke/errors.js +8 -0
  190. package/lib/yoke/host-environment.js +7 -0
  191. package/lib/yoke/index.js +9 -51
  192. package/lib/yoke/interface.js +116 -0
  193. package/lib/yoke/kiro-acp-server.js +5 -5
  194. package/lib/yoke/legacy-sessions.js +89 -0
  195. package/lib/yoke/login-protocol.js +25 -0
  196. package/lib/yoke/maintenance.js +12 -0
  197. package/lib/yoke/mcp-proxy.js +32 -0
  198. package/lib/yoke/mcp-source-adapters.js +91 -0
  199. package/lib/yoke/mcp-source-context.js +42 -0
  200. package/lib/yoke/mcp-source-discovery.js +169 -0
  201. package/lib/yoke/mcp-source-plugins.js +68 -0
  202. package/lib/yoke/mcp-source-restrictions.js +47 -0
  203. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  204. package/lib/yoke/model-preferences.js +6 -0
  205. package/lib/yoke/muse-artifacts.js +36 -0
  206. package/lib/yoke/muse-controls.js +50 -0
  207. package/lib/yoke/muse-input.js +64 -0
  208. package/lib/yoke/muse-items.js +157 -0
  209. package/lib/yoke/muse-policy.js +52 -0
  210. package/lib/yoke/muse-query.js +428 -0
  211. package/lib/yoke/muse-runtime.js +211 -0
  212. package/lib/yoke/muse-services.js +79 -0
  213. package/lib/yoke/muse-skills.js +79 -0
  214. package/lib/yoke/muse-turns.js +71 -0
  215. package/lib/yoke/options/acp.js +2 -0
  216. package/lib/yoke/options/antigravity.js +2 -0
  217. package/lib/yoke/options/claude.js +21 -0
  218. package/lib/yoke/options/codex-defaults.js +29 -0
  219. package/lib/yoke/options/codex-settings.js +21 -0
  220. package/lib/yoke/options/codex.js +6 -0
  221. package/lib/yoke/options/kiro-defaults.js +22 -0
  222. package/lib/yoke/options/kiro.js +5 -0
  223. package/lib/yoke/options/muse.js +5 -0
  224. package/lib/yoke/provider-contract.js +5 -0
  225. package/lib/yoke/providers/antigravity-executable.js +8 -0
  226. package/lib/yoke/providers/claude-executable.js +40 -0
  227. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  228. package/lib/yoke/providers/claude-process.js +97 -0
  229. package/lib/yoke/providers/claude-provision.js +75 -0
  230. package/lib/yoke/providers/codex-errors.js +8 -0
  231. package/lib/yoke/providers/muse-executable.js +17 -0
  232. package/lib/yoke/provisioning.js +6 -0
  233. package/lib/yoke/query-options.js +10 -0
  234. package/lib/yoke/response-recovery.js +41 -0
  235. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  236. package/lib/yoke/sdk-server-factory.js +7 -0
  237. package/lib/yoke/session-history.js +8 -0
  238. package/lib/yoke/session-tool-transport.js +31 -13
  239. package/lib/yoke/settings.js +23 -0
  240. package/lib/yoke/source-locations.js +4 -0
  241. package/lib/yoke/title-query.js +18 -7
  242. package/lib/yoke/tui-transcript-index.js +132 -0
  243. package/lib/yoke/usage.js +48 -0
  244. package/lib/yoke/user-input.js +13 -0
  245. package/lib/yoke/vendor-registry.js +81 -1
  246. package/package.json +3 -2
@@ -0,0 +1,79 @@
1
+ // Typed MSP operations; no arbitrary command forwarding or automatic effect replay.
2
+ var runtimeTools = require("./muse-runtime");
3
+ function attach(adapter) {
4
+ async function withRuntime(options, operation) {
5
+ options = options || {};
6
+ if (options.linuxUser || options.osUsers) throw new Error("Muse Code does not support OS-owner isolation");
7
+ if (adapter.shuttingDown) throw new Error("Muse Code adapter is shutting down");
8
+ if (!adapter.binaryPath) await adapter.init(options);
9
+ var sdk = await adapter.loadSdk();
10
+ if (adapter.shuttingDown) throw new Error("Muse Code adapter is shutting down");
11
+ var runtime = runtimeTools.createRuntime(adapter, sdk, {
12
+ command: adapter.binaryPath, args: ["serve"], cwd: options.dir || adapter.cwd,
13
+ env: Object.assign({}, process.env),
14
+ });
15
+ runtime.fail = function() { runtime.close().catch(function(error) { adapter.lastCloseError = error; }); };
16
+ try {
17
+ var spawned = await runtime.initialize();
18
+ return await operation(runtime, spawned);
19
+ } finally { await runtime.close(); }
20
+ }
21
+ adapter.listSessionPage = function(options) {
22
+ options = options || {};
23
+ return withRuntime(options, async function(runtime, spawned) {
24
+ var params = { workspaceRoot: options.dir || adapter.cwd, limit: options.limit || 50 };
25
+ if (options.cursor != null) params.cursor = options.cursor;
26
+ var page = await runtime.waitRequest(spawned.connection.request("session/list", params));
27
+ if (!Array.isArray(page.sessions)) throw new Error("Invalid Muse session list");
28
+ return page;
29
+ });
30
+ };
31
+ adapter.listSessions = async function(options) {
32
+ var page = await adapter.listSessionPage(options);
33
+ page.sessions.nextCursor = page.nextCursor;
34
+ return page.sessions;
35
+ };
36
+ adapter.readSession = function(sessionId, options) {
37
+ if (typeof sessionId !== "string" || !sessionId) return Promise.reject(new Error("Muse read requires an exact session id"));
38
+ return withRuntime(options, function(runtime, spawned) {
39
+ return runtime.waitRequest(spawned.connection.request("session/read", { sessionId: sessionId, excludeItems: !(options && options.includeItems) }));
40
+ });
41
+ };
42
+ adapter.renameSession = function(sessionId, name, options) {
43
+ if (typeof sessionId !== "string" || !sessionId || typeof name !== "string" || !name.trim()) return Promise.reject(new Error("Muse rename requires an exact session and name"));
44
+ return withRuntime(options, async function(runtime, spawned) {
45
+ if (sdkDurability(spawned) !== "durable") throw new Error("Muse rename is unsupported by an ephemeral host");
46
+ await runtime.waitRequest(spawned.connection.command("session/resume", { sessionId: sessionId, excludeItems: true }));
47
+ return runtime.waitRequest(spawned.connection.command("session/rename", { sessionId: sessionId, name: name }));
48
+ });
49
+ };
50
+ adapter.forkSession = function(sessionId, options) {
51
+ options = options || {};
52
+ return withRuntime(options, async function(runtime, spawned) {
53
+ var params = { sessionId: sessionId, excludeItems: true };
54
+ if (options.upToMessageId) params.cutPoint = { lastTurnId: options.upToMessageId };
55
+ var result = await runtime.waitRequest(spawned.connection.command("session/fork", params));
56
+ if (!result.session || !result.session.sessionId) throw new Error("Muse fork returned no session id; inspect before retrying");
57
+ return { sessionId: result.session.sessionId, useLocalHistory: true };
58
+ });
59
+ };
60
+ adapter.readUsage = function(options) {
61
+ return withRuntime(options, async function(runtime, spawned) {
62
+ var result = await runtime.waitRequest(spawned.connection.request("usage/read", {}));
63
+ return result.usage || null;
64
+ });
65
+ };
66
+ }
67
+ function sdkDurability(spawned) { return spawned.initializeResult.sessionDurability; }
68
+ function quotaEvent(usage) {
69
+ if (!usage || !Number.isFinite(usage.observedAtMs)) return null;
70
+ var windows = [];
71
+ ["window", "weekly"].forEach(function(key) {
72
+ var value = usage[key];
73
+ if (!value || !Number.isFinite(value.usedPercent) || value.usedPercent < 0 || !Number.isFinite(value.resetsAtMs)) return;
74
+ windows.push({ key: key, usedPercent: value.usedPercent, resetsAt: value.resetsAtMs / 1000,
75
+ windowDurationMins: key === "weekly" ? 10080 : value.windowDurationMins || null });
76
+ });
77
+ return { yokeType: "rate_limit", rateLimitInfo: { source: "account_snapshot", limitId: "muse", observedAtMs: usage.observedAtMs, windows: windows } };
78
+ }
79
+ module.exports = { attach: attach, quotaEvent: quotaEvent };
@@ -0,0 +1,79 @@
1
+ var discovery = require("./skill-discovery");
2
+ function create(queryOpts, getRuntime, push, assertLive) {
3
+ var options = queryOpts.skillOptions;
4
+ var delivered = false;
5
+ var lastCatalog = "";
6
+ var lastIndex = "";
7
+ function available() {
8
+ assertLive();
9
+ var readOnly = queryOpts.adapterOptions && queryOpts.adapterOptions.MUSE && queryOpts.adapterOptions.MUSE.readOnly;
10
+ var allowed = !queryOpts.skipSkills && !readOnly && options && !options.disable && typeof options.isAvailable === "function" && options.isAvailable() === true;
11
+ if (!allowed && delivered) throw new Error("The skill query scope is no longer available");
12
+ return !!allowed;
13
+ }
14
+ function check() {
15
+ if (!available()) throw new Error("Skills require an authorized Clay query scope");
16
+ }
17
+ async function listNative() {
18
+ check();
19
+ var runtime = getRuntime();
20
+ if (!runtime || !runtime.session) throw new Error("Muse skills require an opened session");
21
+ var result = await runtime.waitRequest(runtime.connection.request("skill/list", { sessionId: runtime.session.sessionId }));
22
+ check();
23
+ if (!result || !Array.isArray(result.skills)) throw new Error("Muse returned an invalid native skill catalog");
24
+ return { skills: result.skills.filter(function(skill) {
25
+ // Clay-only names are delivered from private roots, never native installs.
26
+ return skill && typeof skill.selector === "string" && !/(?:^|:)clay-/.test(skill.selector);
27
+ }) };
28
+ }
29
+ function scopedOptions() {
30
+ var fs = require("fs");
31
+ return Object.assign({}, options, {
32
+ readDir: function(dir) { check(); return options.readDir ? options.readDir(dir) : fs.readdirSync(dir, { withFileTypes: true }); },
33
+ readFile: function(file) { check(); var content = options.readFile ? options.readFile(file) : fs.readFileSync(file, "utf8"); check(); return content; },
34
+ realpath: function(file) { check(); return options.realpath ? options.realpath(file) : fs.realpathSync(file); },
35
+ });
36
+ }
37
+ async function prepare(text, selected) {
38
+ if (!available()) {
39
+ if (selected) throw new Error("Skills require an authorized Clay query scope");
40
+ return { text: text, skill: null, scoped: false };
41
+ }
42
+ var native = await listNative();
43
+ var readOpts = scopedOptions();
44
+ var shared = discovery.discoverSkills(queryOpts.cwd, readOpts).filter(function(skill) {
45
+ return !/^clay-/.test(skill.name) || /^clay-/.test(skill.source);
46
+ });
47
+ check();
48
+ var slash = typeof text === "string" && /^\/([^\s/]+)(?:[ \t]([\s\S]*))?$/.exec(text);
49
+ var explicit = selected;
50
+ var referenceText = text;
51
+ if (slash) {
52
+ if (native.skills.some(function(skill) { return skill.selector === slash[1]; })) {
53
+ explicit = { selector: slash[1], arguments: slash[2] || "" };
54
+ text = "";
55
+ } else if (shared.some(function(skill) { return skill.name === slash[1]; })) {
56
+ referenceText = "$" + slash[1] + (slash[2] ? " " + slash[2] : "");
57
+ text = referenceText;
58
+ } else throw new Error("Skill is not in the current Muse or shared catalog: " + slash[1]);
59
+ }
60
+ if (explicit && !native.skills.some(function(skill) { return skill.selector === explicit.selector; })) throw new Error("Muse skill is not in the live session catalog");
61
+ var index = discovery.buildSkillIndex(shared);
62
+ var content = discovery.readReferencedSkills(referenceText, shared, 32768, readOpts);
63
+ if (discovery.findSkillReferences(referenceText, shared).length && !content) throw new Error("Shared skill instructions are unavailable");
64
+ check();
65
+ var commands = native.skills.map(function(skill) { return skill.selector; });
66
+ var names = shared.map(function(skill) { return skill.name; });
67
+ var catalog = JSON.stringify([commands, names]);
68
+ if (catalog !== lastCatalog) {
69
+ push({ yokeType: "commands_changed", commandNames: commands, skills: names });
70
+ lastCatalog = catalog;
71
+ }
72
+ var guidance = index && index !== lastIndex ? index + "\nNative /selector commands invoke Muse skills; $name references load shared instructions. If names collide, /name is native and $name is shared." : "";
73
+ lastIndex = index;
74
+ delivered = true;
75
+ return { text: [text, guidance, content].filter(Boolean).join("\n\n"), skill: explicit || null, scoped: true };
76
+ }
77
+ return { prepare: prepare, listNative: listNative, check: check };
78
+ }
79
+ module.exports = { create: create };
@@ -0,0 +1,71 @@
1
+ // Foreground completion is a non-terminal SDK fact. Continue following every
2
+ // turn to its real outcome while releasing only the next submission boundary.
3
+ function create(options) {
4
+ var state = options.state;
5
+ var turns = new Map();
6
+ function started(entry) {
7
+ if (entry.started || !entry.turn.observedStart) return;
8
+ entry.started = true;
9
+ options.push({ yokeType: 'turn_start', uuid: entry.turn.turnId, messageType: 'user', turnId: entry.turn.turnId });
10
+ options.push({ yokeType: 'turn_activity', phase: 'running', turnId: entry.turn.turnId });
11
+ }
12
+ function foreground(entry, params) {
13
+ if (entry.yielded || !params || !Array.isArray(params.blockingAgents) || !params.blockingAgents.length) return;
14
+ entry.yielded = true;
15
+ entry.release({ kind: 'foreground' });
16
+ }
17
+ function onFrame(frame) {
18
+ if (frame.method !== 'turn/foregroundCompleted' && frame.method !== 'turn/started') return;
19
+ var entry = turns.get(frame.params.turnId);
20
+ if (entry && frame.method === 'turn/started') { started(entry); return; }
21
+ var folded = state.session.fold.turn(frame.params.turnId);
22
+ if (entry && folded && folded.state === 'running') foreground(entry, folded.foregroundCompleted);
23
+ }
24
+ function follow(turn, report, sequence) {
25
+ var entry = { turn: turn, yielded: false };
26
+ var boundary = new Promise(function (resolve) { entry.release = resolve; });
27
+ turns.set(turn.turnId, entry);
28
+ state.liveTurnIds.add(turn.turnId);
29
+ started(entry);
30
+ var admission = state.session.pending.list().find(function (pending) { return pending.ack && pending.ack.turnId === turn.turnId; });
31
+ var existing = state.session.fold.turn(turn.turnId);
32
+ if (!entry.started && (!existing || existing.state === 'running')) options.push({
33
+ yokeType: 'turn_activity', phase: 'waiting', turnId: turn.turnId,
34
+ disposition: admission && admission.ack.disposition
35
+ });
36
+ options.ready();
37
+ var terminal = (async function () {
38
+ try {
39
+ for await (var item of turn.items()) {
40
+ if (state.stopped) return { kind: 'stopped' };
41
+ if (!options.renderer.hasItem(item.itemId)) options.renderer.emitItem(item);
42
+ await options.emitArtifact(item);
43
+ }
44
+ var outcome = await options.runtime().wait(turn.completed);
45
+ if (state.stopped) return { kind: 'stopped' };
46
+ options.renderer.closeBlocks(turn.turnId);
47
+ var event = options.outcomeEvent(outcome);
48
+ // A retired foreground turn cannot settle a newer turn's reviews or
49
+ // user-work completion callbacks when its reminder checks finish late.
50
+ if (event.yokeType === 'result' && entry.yielded && sequence < state.messageSequence) event.backgroundOnly = true;
51
+ if (report || event.yokeType !== 'result') options.push(event);
52
+ if (event.yokeType !== 'result') await options.close();
53
+ return { kind: 'terminal', outcome: outcome, event: event };
54
+ } catch (error) {
55
+ options.fail(error);
56
+ return { kind: 'failed' };
57
+ } finally {
58
+ turns.delete(turn.turnId);
59
+ state.liveTurnIds.delete(turn.turnId);
60
+ if (!state.stopped && !state.active && state.inputEnded && !turns.size) options.close().catch(options.fail);
61
+ }
62
+ })();
63
+ // Session.apply can receive this event before turn/start's acknowledgement.
64
+ var folded = state.session.fold.turn(turn.turnId);
65
+ if (folded && folded.state === 'running') foreground(entry, folded.foregroundCompleted);
66
+ return Promise.race([terminal, boundary]);
67
+ }
68
+ return { follow: follow, onFrame: onFrame, pending: function () { return turns.size > 0; },
69
+ background: function () { return Array.from(turns.values()).some(function (entry) { return entry.yielded; }); } };
70
+ }
71
+ module.exports = { create: create };
@@ -0,0 +1,2 @@
1
+ function map(intent) { return { ACP: { mcpServers: intent.sessionBridge } }; }
2
+ module.exports = { map: map };
@@ -0,0 +1,2 @@
1
+ function map(intent) { return { ANTIGRAVITY: { dangerouslySkipPermissions: !intent.readOnly && (intent.nativeBypass || intent.permissionMode === "bypassPermissions") } }; }
2
+ module.exports = { map: map };
@@ -0,0 +1,21 @@
1
+ function map(intent) {
2
+ var options = { settingSources: intent.instructionSources || ["user", "project", "local"], includePartialMessages: true,
3
+ enableFileCheckpointing: true, extraArgs: { "replay-user-messages": null }, promptSuggestions: true, agentProgressSummaries: true };
4
+ if (intent.betas && intent.betas.length) options.betas = intent.betas;
5
+ var thinking = intent.thinking || {};
6
+ if (thinking.mode === "disabled") options.thinking = { type: "disabled" };
7
+ else if (thinking.mode === "budget" && thinking.budget) options.thinking = { type: "enabled", budgetTokens: thinking.budget };
8
+ else options.thinking = { type: "adaptive", display: "summarized" };
9
+ if (intent.disableHooks !== undefined) options.settings = { disableAllHooks: intent.disableHooks };
10
+ options.permissionMode = intent.nativePermissionMode || "default";
11
+ if (intent.nativeBypass && !intent.readOnly) { options.permissionMode = "bypassPermissions"; options.allowDangerouslySkipPermissions = true; }
12
+ if (intent.readOnly) { options.permissionMode = "default"; options.allowDangerouslySkipPermissions = false; }
13
+ if (intent.resumeAt) options.resumeSessionAt = intent.resumeAt;
14
+ if (intent.isolation && intent.isolation.user) {
15
+ var isolation = intent.isolation;
16
+ Object.assign(options, { linuxUser: isolation.user, originalHome: isolation.home, singleTurn: intent.singleTurn,
17
+ projectPath: isolation.projectPath, _perfT0: intent.startedAt, _workerState: isolation.workerState });
18
+ }
19
+ return { CLAUDE: options };
20
+ }
21
+ module.exports = { map: map };
@@ -0,0 +1,29 @@
1
+ var CODEX_DEFAULTS = {
2
+ approval: "on-request",
3
+ sandbox: "danger-full-access",
4
+ webSearch: "live",
5
+ };
6
+
7
+ var CODEX_APPROVAL_POLICIES = ["untrusted", "on-request", "granular", "never"];
8
+
9
+ function normalizeCodexApproval(value) {
10
+ if (value === "on-failure") return CODEX_DEFAULTS.approval;
11
+ if (CODEX_APPROVAL_POLICIES.indexOf(value) === -1) return CODEX_DEFAULTS.approval;
12
+ return value;
13
+ }
14
+
15
+ function getCodexConfig(sm) {
16
+ sm = sm || {};
17
+ return {
18
+ approval: normalizeCodexApproval(sm && sm.codexApproval),
19
+ sandbox: (sm && sm.codexSandbox) === undefined ? CODEX_DEFAULTS.sandbox : ["read-only", "workspace-write", "danger-full-access"].indexOf(sm.codexSandbox) >= 0 ? sm.codexSandbox : "read-only",
20
+ webSearch: (sm && sm.codexWebSearch) === undefined ? CODEX_DEFAULTS.webSearch : ["disabled", "cached", "live"].indexOf(sm.codexWebSearch) >= 0 ? sm.codexWebSearch : "disabled",
21
+ };
22
+ }
23
+
24
+ module.exports = {
25
+ CODEX_DEFAULTS: CODEX_DEFAULTS,
26
+ CODEX_APPROVAL_POLICIES: CODEX_APPROVAL_POLICIES,
27
+ normalizeCodexApproval: normalizeCodexApproval,
28
+ getCodexConfig: getCodexConfig,
29
+ };
@@ -0,0 +1,21 @@
1
+ // Provider setting validation and legacy wire projection. The host owns
2
+ // permission checks, the actual settings store and publication.
3
+ var config = require('./codex-defaults');
4
+ var actions = {
5
+ set_codex_approval: { key: 'codexApproval', input: 'approval', choices: config.CODEX_APPROVAL_POLICIES, fallback: config.CODEX_DEFAULTS.approval },
6
+ set_codex_sandbox: { key: 'codexSandbox', input: 'sandbox', choices: ['read-only', 'workspace-write', 'danger-full-access'], fallback: config.CODEX_DEFAULTS.sandbox },
7
+ set_codex_websearch: { key: 'codexWebSearch', input: 'webSearch', choices: ['disabled', 'cached', 'live'], fallback: config.CODEX_DEFAULTS.webSearch },
8
+ };
9
+ function defaults() { return { codexApproval: config.CODEX_DEFAULTS.approval, codexSandbox: config.CODEX_DEFAULTS.sandbox, codexWebSearch: config.CODEX_DEFAULTS.webSearch }; }
10
+ function messages(settings) { return [Object.assign({ type: 'codex_config' }, config.getCodexConfig(settings))]; }
11
+ function change(message, settings) {
12
+ var action = actions[message.type];
13
+ if (!action) return null;
14
+ var value = message[action.input];
15
+ if (value == null || value === '') value = action.fallback;
16
+ if (action.key === 'codexApproval' && value === 'on-failure') value = action.fallback;
17
+ if (action.choices.indexOf(value) < 0) throw new Error('Unsupported provider setting value.');
18
+ var patch = {}; patch[action.key] = value;
19
+ return { patch: patch, messages: messages(Object.assign({}, settings, patch)) };
20
+ }
21
+ module.exports = { defaults: defaults, messages: messages, change: change };
@@ -0,0 +1,6 @@
1
+ function map(intent) {
2
+ var config = require("./codex-defaults").getCodexConfig(intent.settings);
3
+ return { CODEX: { approvalPolicy: "never", sandboxMode: intent.readOnly ? "read-only" : config.sandbox,
4
+ webSearchMode: intent.readOnly ? "disabled" : config.webSearch } };
5
+ }
6
+ module.exports = { map: map };
@@ -0,0 +1,22 @@
1
+ // Kiro-specific default values. Single source of truth — do not duplicate
2
+ // elsewhere. Consumed by the server-side vendor plumbing and sent to clients
3
+ // via the config state so the UI renders the right controls.
4
+
5
+ var KIRO_DEFAULTS = {
6
+ // Kiro CLI 2.18.1 exposes the next-generation agent as the v3 engine. Its
7
+ // general-purpose mode id is "vibe" (displayed as "Default").
8
+ engine: "v3",
9
+ mode: "vibe",
10
+ };
11
+
12
+ function getKiroConfig(sm) {
13
+ return {
14
+ engine: (sm && sm.kiroEngine) || KIRO_DEFAULTS.engine,
15
+ mode: (sm && sm.kiroMode) || KIRO_DEFAULTS.mode,
16
+ };
17
+ }
18
+
19
+ module.exports = {
20
+ KIRO_DEFAULTS: KIRO_DEFAULTS,
21
+ getKiroConfig: getKiroConfig,
22
+ };
@@ -0,0 +1,5 @@
1
+ function map(intent) {
2
+ var config = require("./kiro-defaults").getKiroConfig(intent.settings);
3
+ return { KIRO: { engine: config.engine, mode: config.mode, mcpServers: intent.sessionBridge } };
4
+ }
5
+ module.exports = { map: map };
@@ -0,0 +1,5 @@
1
+ function map(intent) {
2
+ if (intent.readOnly) throw new Error("Muse SDK 1.4.7 cannot enforce the curator read-only sandbox contract");
3
+ return { MUSE: { mcpServers: intent.readOnly ? [] : intent.sessionBridge || [], readOnly: intent.readOnly === true } };
4
+ }
5
+ module.exports = { map: map };
@@ -0,0 +1,5 @@
1
+ function resolve(provider) {
2
+ if (provider && typeof provider === "object" && provider.providerContract) return provider.providerContract;
3
+ return require("./vendor-registry").getVendorInfo(typeof provider === "string" ? provider : provider && provider.vendor) || {};
4
+ }
5
+ module.exports = { resolve: resolve };
@@ -0,0 +1,8 @@
1
+ // One authoritative resolver for both installation discovery and adapter init.
2
+ var resolvePath = require("../discovery").pathResolver("agy", "ANTIGRAVITY_CLI_PATH");
3
+ function resolve(options) {
4
+ options = options || {};
5
+ if (options.user) return null;
6
+ return resolvePath(options);
7
+ }
8
+ module.exports = { resolve: resolve };
@@ -0,0 +1,40 @@
1
+ var fs = require("fs");
2
+ function resolveClaudeBinaryPath() {
3
+ // 1. Explicit env var override
4
+ var discovery = require("../discovery");
5
+ var explicit = discovery.explicitEntry(process.env, "CLAUDE_CODE_PATH", true);
6
+ if (explicit !== undefined) return explicit;
7
+
8
+ // 2. `which claude` in the daemon's PATH
9
+ try {
10
+ var result = require("child_process").execSync("which claude", { encoding: "utf8", timeout: 5000 }).trim();
11
+ if (discovery.validEntry(result, false)) return result;
12
+ } catch (e) {}
13
+
14
+ // 3. Common per-user and system locations (best-effort fallback for the daemon user)
15
+ var home = process.env.HOME || "";
16
+ var candidates = [];
17
+ if (home) {
18
+ candidates.push(home + "/.npm-global/bin/claude");
19
+ candidates.push(home + "/.local/bin/claude");
20
+ candidates.push(home + "/.volta/bin/claude");
21
+ candidates.push(home + "/.bun/bin/claude");
22
+ candidates.push(home + "/bin/claude");
23
+ }
24
+ candidates.push("/usr/local/bin/claude");
25
+ candidates.push("/usr/bin/claude");
26
+ candidates.push("/opt/homebrew/bin/claude");
27
+ for (var i = 0; i < candidates.length; i++) {
28
+ try { if (discovery.validEntry(candidates[i], false)) return candidates[i]; } catch (e) {}
29
+ }
30
+
31
+ // 4. Bundled CLI entry from the SDK's peer
32
+ try {
33
+ var resolved = require.resolve("@anthropic-ai/claude-code/cli.js");
34
+ if (discovery.validEntry(resolved, true)) return resolved;
35
+ } catch (e) {}
36
+
37
+ return null;
38
+ }
39
+
40
+ module.exports = { resolve: resolveClaudeBinaryPath };
@@ -0,0 +1,14 @@
1
+ // Preserve existing model descriptions and beta availability at the provider boundary.
2
+ var DESCRIPTIONS = { default: "Automatically selects the best model for the task.", sonnet: "Fast and capable. Great balance of speed and intelligence.", haiku: "Fastest model. Best for quick tasks and simple questions.", opus: "Most powerful model. Best for complex reasoning and analysis." };
3
+ function describe(entry) {
4
+ var model = typeof entry === "string" ? { value: entry, displayName: entry } : Object.assign({}, entry);
5
+ var name = String(model.value || "").toLowerCase();
6
+ if (model.supportsBetaContext === undefined) model.supportsBetaContext = name.indexOf("sonnet") !== -1;
7
+ if (!model.description) {
8
+ var family = Object.keys(DESCRIPTIONS).find(function(key) { return name.indexOf(key) !== -1; });
9
+ if (family) model.description = DESCRIPTIONS[family];
10
+ }
11
+ return model;
12
+ }
13
+ function list(models) { return (models || []).map(describe); }
14
+ module.exports = { describe: describe, list: list };
@@ -0,0 +1,97 @@
1
+ var fs = require("fs");
2
+ var path = require("path");
3
+ var execFileSync = require("child_process").execFileSync;
4
+ function prepareIsolation(linuxUser, session, cwd) {
5
+ try {
6
+ var configMod = require("../../config");
7
+ var osUsersMod = require("../../os-users");
8
+ var originalHome = configMod.REAL_HOME || require("os").homedir();
9
+ var linuxUserHome = osUsersMod.getLinuxUserHome(linuxUser);
10
+ var uid = osUsersMod.getLinuxUserUid(linuxUser);
11
+ if (originalHome !== linuxUserHome && uid != null) {
12
+ var projectSlug = (cwd || "").replace(/\//g, "-");
13
+ var dstDir = path.join(linuxUserHome, ".claude", "projects", projectSlug);
14
+ // Create and chown the project directory once
15
+ if (!fs.existsSync(dstDir)) {
16
+ fs.mkdirSync(dstDir, { recursive: true });
17
+ try { execFileSync("chown", ["-R", String(uid), path.join(linuxUserHome, ".claude")]); } catch (e2) {}
18
+ } else {
19
+ try {
20
+ var dirStat = fs.statSync(dstDir);
21
+ if (dirStat.uid !== uid) {
22
+ execFileSync("chown", [String(uid), dstDir]);
23
+ }
24
+ } catch (e2) {}
25
+ }
26
+ // Pre-copy CLI session file so the worker can resume the conversation
27
+ if (session.cliSessionId) {
28
+ var sessionFileName = session.cliSessionId + ".jsonl";
29
+ var srcFile = path.join(originalHome, ".claude", "projects", projectSlug, sessionFileName);
30
+ var dstFile = path.join(dstDir, sessionFileName);
31
+ if (fs.existsSync(srcFile) && !fs.existsSync(dstFile)) {
32
+ fs.copyFileSync(srcFile, dstFile);
33
+ try { execFileSync("chown", [String(uid), dstFile]); } catch (e2) {}
34
+ console.log("[sdk-bridge] Pre-copied CLI session " + session.cliSessionId + " to " + linuxUser);
35
+ }
36
+ }
37
+ }
38
+ } catch (copyErr) {
39
+ console.log("[sdk-bridge] Dir setup / session pre-copy skipped:", copyErr.message);
40
+ }
41
+ }
42
+ function findConflicts(cwd) {
43
+ try {
44
+ var output = execFileSync("ps", ["ax", "-o", "pid,command"], { encoding: "utf8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] });
45
+ var lines = output.trim().split("\n");
46
+ var candidates = [];
47
+ for (var i = 1; i < lines.length; i++) { // skip header
48
+ var line = lines[i].trim();
49
+ var m = line.match(/^(\d+)\s+(.+)/);
50
+ if (!m) continue;
51
+ var pid = parseInt(m[1], 10);
52
+ var cmd = m[2];
53
+ // Skip our own process
54
+ if (pid === process.pid) continue;
55
+ // Skip node processes (our daemon, dev watchers, etc.)
56
+ if (/\bnode\b/.test(cmd.split(/\s/)[0])) continue;
57
+ // Match actual claude binary (e.g. /Users/x/.claude/local/claude, /usr/local/bin/claude)
58
+ if (/\/claude(\s|$)/.test(cmd) || /^claude(\s|$)/.test(cmd)) {
59
+ candidates.push({ pid: pid, command: cmd.substring(0, 200) });
60
+ }
61
+ }
62
+
63
+ // Filter to only processes whose cwd matches our project
64
+ var results = [];
65
+ for (var j = 0; j < candidates.length; j++) {
66
+ var c = candidates[j];
67
+ try {
68
+ // Use /proc/<pid>/cwd symlink (always available on Linux, no lsof dependency)
69
+ var procCwd = fs.readlinkSync("/proc/" + c.pid + "/cwd");
70
+ if (procCwd === cwd) {
71
+ results.push(c);
72
+ }
73
+ } catch (e) {
74
+ // /proc read failed — include as candidate anyway (conservative)
75
+ results.push(c);
76
+ }
77
+ }
78
+ return results;
79
+ } catch (e) {
80
+ return [];
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Verify that a PID is actually a claude binary process (not arbitrary).
86
+ */
87
+ function verifyProcess(pid) {
88
+ try {
89
+ var output = execFileSync("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8", timeout: 3000, stdio: ["pipe", "pipe", "pipe"] }).trim();
90
+ return /\/claude(\s|$)/.test(output) || /^claude(\s|$)/.test(output);
91
+ } catch (e) {
92
+ return false;
93
+ }
94
+ }
95
+
96
+ function shouldInspect(error) { return error.exitCode === 1 || error.message && error.message.indexOf("exited with code 1") >= 0; }
97
+ module.exports = { shouldInspect: shouldInspect, prepareIsolation: prepareIsolation, findConflicts: findConflicts, verifyProcess: verifyProcess };
@@ -0,0 +1,75 @@
1
+ var fs = require("fs"), path = require("path");
2
+ var execFileSync = require("child_process").execFileSync;
3
+ function attachProvisioning(ctx) {
4
+ var isSafeLinuxUsername = ctx.isSafeLinuxUsername;
5
+ var resolveOsUserInfo = ctx.resolveOsUserInfo;
6
+ function claudeAvailableForUser(linuxName) {
7
+ if (!isSafeLinuxUsername(linuxName)) return false;
8
+ try {
9
+ var out = execFileSync("su", ["-", linuxName, "-c", "command -v claude"], {
10
+ encoding: "utf8",
11
+ timeout: 10000,
12
+ stdio: "pipe",
13
+ }).trim();
14
+ return out.length > 0;
15
+ } catch (e) {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Install Claude CLI for a Linux user account.
22
+ * Downloads and runs the install script, then ensures PATH is configured.
23
+ * Non-fatal: logs errors but does not throw.
24
+ * Skips entirely when claude is already resolvable for the user, or when
25
+ * CLAY_SKIP_CLAUDE_INSTALL is set (bring-your-own-claude).
26
+ */
27
+ function installClaudeCli(linuxName) {
28
+ if (process.env.CLAY_SKIP_CLAUDE_INSTALL) {
29
+ console.log("[os-users] CLAY_SKIP_CLAUDE_INSTALL set, skipping Claude CLI install for " + linuxName);
30
+ return;
31
+ }
32
+ if (claudeAvailableForUser(linuxName)) {
33
+ console.log("[os-users] Claude CLI already available for " + linuxName + ", skipping install");
34
+ return;
35
+ }
36
+ try {
37
+ if (!isSafeLinuxUsername(linuxName)) throw new Error("Invalid Linux username");
38
+ // Download and run the Claude CLI install script as the target user
39
+ execFileSync("su", ["-", linuxName, "-c", "curl -fsSL https://claude.ai/install.sh | bash"], {
40
+ encoding: "utf8",
41
+ timeout: 60000,
42
+ stdio: "pipe",
43
+ });
44
+ console.log("[os-users] Claude CLI installed for " + linuxName);
45
+ } catch (e) {
46
+ var msg = (e.stderr || e.message || "").trim();
47
+ console.error("[os-users] Failed to install Claude CLI for " + linuxName + ": " + msg);
48
+ return;
49
+ }
50
+
51
+ // Append PATH export to the user's shell config if not already present
52
+ try {
53
+ var userInfo = resolveOsUserInfo(linuxName);
54
+ var home = userInfo.home || ("/home/" + linuxName);
55
+ var rcPath = fs.existsSync(path.join(home, ".zshrc")) ? path.join(home, ".zshrc") : path.join(home, ".bashrc");
56
+ var exportLine = 'export PATH="$HOME/.local/bin:$PATH"';
57
+ var existing = "";
58
+ try { existing = fs.readFileSync(rcPath, "utf8"); } catch (e2) {}
59
+ if (existing.indexOf(exportLine) === -1) {
60
+ var prefix = existing && !/\n$/.test(existing) ? "\n" : "";
61
+ fs.appendFileSync(rcPath, prefix + exportLine + "\n", "utf8");
62
+ try { fs.chownSync(rcPath, userInfo.uid, userInfo.gid); } catch (e3) {}
63
+ console.log("[os-users] PATH export appended to " + rcPath + " for " + linuxName);
64
+ } else {
65
+ console.log("[os-users] PATH already configured in " + rcPath + " for " + linuxName);
66
+ }
67
+ } catch (e) {
68
+ var rcMsg = (e.stderr || e.message || "").trim();
69
+ console.error("[os-users] Failed to configure PATH for " + linuxName + ": " + rcMsg);
70
+ }
71
+ }
72
+
73
+ return { available: claudeAvailableForUser, install: installClaudeCli };
74
+ }
75
+ module.exports = { attachProvisioning: attachProvisioning };
@@ -0,0 +1,8 @@
1
+ function classify(text) {
2
+ if (/thread-store conflict|already has an active writer/i.test(String(text))) return {
3
+ kind: 'session_writer_conflict',
4
+ text: 'This Codex session is already open in another Clay or Codex process. Stop the other server or close the other session, then try again.',
5
+ };
6
+ return null;
7
+ }
8
+ module.exports = { classify: classify };
@@ -0,0 +1,17 @@
1
+ // Discovery and startup share this resolver; an invalid override never falls back.
2
+ var path = require("path");
3
+ var discovery = require("../discovery");
4
+ var onPath = discovery.pathResolver("muse");
5
+ function resolve(options) {
6
+ options = options || {};
7
+ if (options.user || options.linuxUser || options.osUsers) return null;
8
+ var env = options.env || process.env;
9
+ var explicit = discovery.explicitEntry(env, "MUSE_CODE_PATH", false);
10
+ if (explicit !== undefined) return explicit;
11
+ var found = onPath(options);
12
+ if (found) return found;
13
+ var home = options.home || require("../../config").REAL_HOME || require("os").homedir();
14
+ var local = path.join(home, ".local", "bin", process.platform === "win32" ? "muse.exe" : "muse");
15
+ return discovery.validEntry(local, false) ? local : null;
16
+ }
17
+ module.exports = { resolve: resolve };
@@ -0,0 +1,6 @@
1
+ function forProvider(provider, context) {
2
+ var service = require("./provider-contract").resolve(provider).provisionUser;
3
+ if (typeof service !== "function") throw new Error("Provider account provisioning is unavailable.");
4
+ return service(context);
5
+ }
6
+ module.exports = { forProvider: forProvider };