@doriandev/devcc 0.1.2 → 0.3.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 (151) hide show
  1. package/README.md +589 -389
  2. package/bin/devcc.mjs +50 -23
  3. package/dist/devcc/agents/agents.d.ts +119 -0
  4. package/dist/devcc/agents/agents.d.ts.map +1 -0
  5. package/dist/devcc/agents/agents.js +182 -0
  6. package/dist/devcc/agents/agents.js.map +1 -0
  7. package/dist/devcc/app/App.d.ts +23 -0
  8. package/dist/devcc/app/App.d.ts.map +1 -1
  9. package/dist/devcc/app/App.js +451 -19
  10. package/dist/devcc/app/App.js.map +1 -1
  11. package/dist/devcc/app/controlPlaneCommands.d.ts +14 -0
  12. package/dist/devcc/app/controlPlaneCommands.d.ts.map +1 -0
  13. package/dist/devcc/app/controlPlaneCommands.js +204 -0
  14. package/dist/devcc/app/controlPlaneCommands.js.map +1 -0
  15. package/dist/devcc/app/keymap.d.ts.map +1 -1
  16. package/dist/devcc/app/keymap.js +25 -3
  17. package/dist/devcc/app/keymap.js.map +1 -1
  18. package/dist/devcc/automation.d.ts +52 -0
  19. package/dist/devcc/automation.d.ts.map +1 -0
  20. package/dist/devcc/automation.js +339 -0
  21. package/dist/devcc/automation.js.map +1 -0
  22. package/dist/devcc/cli.d.ts.map +1 -1
  23. package/dist/devcc/cli.js +73 -3
  24. package/dist/devcc/cli.js.map +1 -1
  25. package/dist/devcc/components/Sidebar.d.ts.map +1 -1
  26. package/dist/devcc/components/Sidebar.js +1 -0
  27. package/dist/devcc/components/Sidebar.js.map +1 -1
  28. package/dist/devcc/components/primitives.d.ts.map +1 -1
  29. package/dist/devcc/components/primitives.js +3 -0
  30. package/dist/devcc/components/primitives.js.map +1 -1
  31. package/dist/devcc/core/commands.d.ts +33 -0
  32. package/dist/devcc/core/commands.d.ts.map +1 -1
  33. package/dist/devcc/core/commands.js.map +1 -1
  34. package/dist/devcc/core/config.d.ts +71 -3
  35. package/dist/devcc/core/config.d.ts.map +1 -1
  36. package/dist/devcc/core/config.js +189 -5
  37. package/dist/devcc/core/config.js.map +1 -1
  38. package/dist/devcc/core/state.d.ts +19 -1
  39. package/dist/devcc/core/state.d.ts.map +1 -1
  40. package/dist/devcc/core/state.js +6 -0
  41. package/dist/devcc/core/state.js.map +1 -1
  42. package/dist/devcc/environment/EnvironmentService.d.ts +58 -0
  43. package/dist/devcc/environment/EnvironmentService.d.ts.map +1 -0
  44. package/dist/devcc/environment/EnvironmentService.js +159 -0
  45. package/dist/devcc/environment/EnvironmentService.js.map +1 -0
  46. package/dist/devcc/environment/integrations.d.ts +52 -0
  47. package/dist/devcc/environment/integrations.d.ts.map +1 -0
  48. package/dist/devcc/environment/integrations.js +94 -0
  49. package/dist/devcc/environment/integrations.js.map +1 -0
  50. package/dist/devcc/environment/tools.d.ts +51 -0
  51. package/dist/devcc/environment/tools.d.ts.map +1 -0
  52. package/dist/devcc/environment/tools.js +99 -0
  53. package/dist/devcc/environment/tools.js.map +1 -0
  54. package/dist/devcc/git/GitService.d.ts +26 -0
  55. package/dist/devcc/git/GitService.d.ts.map +1 -1
  56. package/dist/devcc/git/GitService.js +71 -2
  57. package/dist/devcc/git/GitService.js.map +1 -1
  58. package/dist/devcc/git/worktrees.d.ts +88 -0
  59. package/dist/devcc/git/worktrees.d.ts.map +1 -0
  60. package/dist/devcc/git/worktrees.js +226 -0
  61. package/dist/devcc/git/worktrees.js.map +1 -0
  62. package/dist/devcc/index.d.ts +15 -3
  63. package/dist/devcc/index.d.ts.map +1 -1
  64. package/dist/devcc/index.js +14 -2
  65. package/dist/devcc/index.js.map +1 -1
  66. package/dist/devcc/init/detect.d.ts +55 -0
  67. package/dist/devcc/init/detect.d.ts.map +1 -0
  68. package/dist/devcc/init/detect.js +207 -0
  69. package/dist/devcc/init/detect.js.map +1 -0
  70. package/dist/devcc/init/prompt.d.ts +25 -0
  71. package/dist/devcc/init/prompt.d.ts.map +1 -0
  72. package/dist/devcc/init/prompt.js +156 -0
  73. package/dist/devcc/init/prompt.js.map +1 -0
  74. package/dist/devcc/platform/launch.d.ts +30 -0
  75. package/dist/devcc/platform/launch.d.ts.map +1 -0
  76. package/dist/devcc/platform/launch.js +93 -0
  77. package/dist/devcc/platform/launch.js.map +1 -0
  78. package/dist/devcc/services/ServiceManager.d.ts +10 -2
  79. package/dist/devcc/services/ServiceManager.d.ts.map +1 -1
  80. package/dist/devcc/services/ServiceManager.js +18 -4
  81. package/dist/devcc/services/ServiceManager.js.map +1 -1
  82. package/dist/devcc/services/node.d.ts +11 -0
  83. package/dist/devcc/services/node.d.ts.map +1 -1
  84. package/dist/devcc/services/node.js +20 -18
  85. package/dist/devcc/services/node.js.map +1 -1
  86. package/dist/devcc/services/ollama.d.ts +64 -5
  87. package/dist/devcc/services/ollama.d.ts.map +1 -1
  88. package/dist/devcc/services/ollama.js +118 -17
  89. package/dist/devcc/services/ollama.js.map +1 -1
  90. package/dist/devcc/services/remote.d.ts +90 -0
  91. package/dist/devcc/services/remote.d.ts.map +1 -0
  92. package/dist/devcc/services/remote.js +233 -0
  93. package/dist/devcc/services/remote.js.map +1 -0
  94. package/dist/devcc/services/types.d.ts +8 -1
  95. package/dist/devcc/services/types.d.ts.map +1 -1
  96. package/dist/devcc/services/types.js.map +1 -1
  97. package/dist/devcc/utils/exec.d.ts +6 -0
  98. package/dist/devcc/utils/exec.d.ts.map +1 -1
  99. package/dist/devcc/utils/exec.js +12 -2
  100. package/dist/devcc/utils/exec.js.map +1 -1
  101. package/dist/devcc/verify/verify.d.ts +107 -0
  102. package/dist/devcc/verify/verify.d.ts.map +1 -0
  103. package/dist/devcc/verify/verify.js +203 -0
  104. package/dist/devcc/verify/verify.js.map +1 -0
  105. package/dist/devcc/views/OverviewView.d.ts.map +1 -1
  106. package/dist/devcc/views/OverviewView.js +58 -2
  107. package/dist/devcc/views/OverviewView.js.map +1 -1
  108. package/dist/devcc/views/ServicesView.d.ts +2 -0
  109. package/dist/devcc/views/ServicesView.d.ts.map +1 -1
  110. package/dist/devcc/views/ServicesView.js +15 -0
  111. package/dist/devcc/views/ServicesView.js.map +1 -1
  112. package/dist/devcc/views/SystemView.d.ts +10 -1
  113. package/dist/devcc/views/SystemView.d.ts.map +1 -1
  114. package/dist/devcc/views/SystemView.js +127 -19
  115. package/dist/devcc/views/SystemView.js.map +1 -1
  116. package/dist/devcc/views/WorktreesView.d.ts +48 -0
  117. package/dist/devcc/views/WorktreesView.d.ts.map +1 -0
  118. package/dist/devcc/views/WorktreesView.js +235 -0
  119. package/dist/devcc/views/WorktreesView.js.map +1 -0
  120. package/package.json +1 -1
  121. package/src/devcc/agents/agents.ts +292 -0
  122. package/src/devcc/app/App.ts +529 -22
  123. package/src/devcc/app/controlPlaneCommands.ts +227 -0
  124. package/src/devcc/app/keymap.ts +25 -3
  125. package/src/devcc/automation.ts +409 -0
  126. package/src/devcc/cli.ts +77 -3
  127. package/src/devcc/components/Sidebar.ts +1 -0
  128. package/src/devcc/components/primitives.ts +3 -0
  129. package/src/devcc/core/commands.ts +34 -0
  130. package/src/devcc/core/config.ts +275 -11
  131. package/src/devcc/core/state.ts +25 -0
  132. package/src/devcc/environment/EnvironmentService.ts +215 -0
  133. package/src/devcc/environment/integrations.ts +133 -0
  134. package/src/devcc/environment/tools.ts +151 -0
  135. package/src/devcc/git/GitService.ts +104 -2
  136. package/src/devcc/git/worktrees.ts +256 -0
  137. package/src/devcc/index.ts +66 -2
  138. package/src/devcc/init/detect.ts +268 -0
  139. package/src/devcc/init/prompt.ts +179 -0
  140. package/src/devcc/platform/launch.ts +125 -0
  141. package/src/devcc/services/ServiceManager.ts +15 -3
  142. package/src/devcc/services/node.ts +17 -14
  143. package/src/devcc/services/ollama.ts +162 -19
  144. package/src/devcc/services/remote.ts +306 -0
  145. package/src/devcc/services/types.ts +9 -1
  146. package/src/devcc/utils/exec.ts +26 -2
  147. package/src/devcc/verify/verify.ts +316 -0
  148. package/src/devcc/views/OverviewView.ts +84 -2
  149. package/src/devcc/views/ServicesView.ts +17 -0
  150. package/src/devcc/views/SystemView.ts +144 -22
  151. package/src/devcc/views/WorktreesView.ts +270 -0
@@ -0,0 +1,93 @@
1
+ import { spawn } from "node:child_process";
2
+ import { sshDestination } from "../services/remote.js";
3
+ import { DevccError } from "../utils/errors.js";
4
+ /** Replace `{path}` inside individual arguments. Never joins arguments into a string. */
5
+ export function substitutePath(args, path) {
6
+ return args.map((arg) => arg.split("{path}").join(path));
7
+ }
8
+ export function editorCommand(path, editor, platform = process.platform) {
9
+ if (editor?.command)
10
+ return { command: editor.command, args: [...(editor.args ?? []), path] };
11
+ if (editor?.application) {
12
+ if (platform !== "darwin") {
13
+ throw new DevccError({
14
+ scope: "command",
15
+ message: `editor.application only works on macOS; set editor.command`,
16
+ });
17
+ }
18
+ return { command: "open", args: ["-a", editor.application, path] };
19
+ }
20
+ throw new DevccError({
21
+ scope: "command",
22
+ message: "No editor configured",
23
+ detail: 'Set editor: { command: "code" } (or zed, cursor, webstorm) in .devcc.ts',
24
+ });
25
+ }
26
+ export function terminalCommand(path, terminal, platform = process.platform) {
27
+ if (terminal?.command) {
28
+ const args = terminal.args ?? ["{path}"];
29
+ return { command: terminal.command, args: substitutePath(args, path) };
30
+ }
31
+ if (platform === "darwin") {
32
+ return { command: "open", args: ["-a", terminal?.application ?? "Terminal", path] };
33
+ }
34
+ throw new DevccError({
35
+ scope: "command",
36
+ message: "No terminal configured",
37
+ detail: 'Set terminal: { command: "wezterm", args: ["start", "--cwd", "{path}"] } in .devcc.ts',
38
+ });
39
+ }
40
+ /**
41
+ * An interactive SSH session needs a terminal. On macOS `open ssh://host`
42
+ * hands the URL to the default terminal, which runs `ssh` with the user's own
43
+ * config for that alias. Elsewhere the configured terminal runs `ssh`.
44
+ */
45
+ export function sshCommand(machine, terminal, platform = process.platform) {
46
+ if (terminal?.command && terminal.execArgs) {
47
+ const port = machine.port ? ["-p", String(machine.port)] : [];
48
+ return {
49
+ command: terminal.command,
50
+ args: [...terminal.execArgs, "ssh", ...port, sshDestination(machine)],
51
+ };
52
+ }
53
+ if (platform === "darwin") {
54
+ const user = machine.user ? `${encodeURIComponent(machine.user)}@` : "";
55
+ const port = machine.port ? `:${machine.port}` : "";
56
+ return { command: "open", args: [`ssh://${user}${machine.host}${port}`] };
57
+ }
58
+ throw new DevccError({
59
+ scope: "command",
60
+ message: "No terminal configured for SSH",
61
+ detail: 'Set terminal: { command: "wezterm", execArgs: ["start", "--"] } in .devcc.ts',
62
+ });
63
+ }
64
+ /**
65
+ * Start a GUI or launcher process detached from devcc. Resolves once it has
66
+ * spawned (not when it exits); rejects with a readable error if it cannot start.
67
+ */
68
+ export function launchDetached(launch, cwd) {
69
+ return new Promise((resolve, reject) => {
70
+ let child;
71
+ try {
72
+ child = spawn(launch.command, launch.args, { cwd, detached: true, stdio: "ignore", windowsHide: true });
73
+ }
74
+ catch (error) {
75
+ reject(toLaunchError(launch, error));
76
+ return;
77
+ }
78
+ child.once("error", (error) => reject(toLaunchError(launch, error)));
79
+ child.once("spawn", () => {
80
+ child.unref();
81
+ resolve();
82
+ });
83
+ });
84
+ }
85
+ function toLaunchError(launch, error) {
86
+ const code = error.code;
87
+ return new DevccError({
88
+ scope: "command",
89
+ message: code === "ENOENT" ? `\`${launch.command}\` was not found` : `Could not run ${launch.command}`,
90
+ cause: error,
91
+ });
92
+ }
93
+ //# sourceMappingURL=launch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../src/devcc/platform/launch.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,8 @@ export declare class ServiceManager extends TypedEmitter<ServiceManagerEvents> {
26
26
  private readonly adapters;
27
27
  private readonly detected;
28
28
  private readonly snapshots;
29
+ /** When each adapter was last asked for its status. */
30
+ private readonly checkedAt;
29
31
  private timer;
30
32
  private refreshing;
31
33
  private readonly intervalMs;
@@ -40,8 +42,14 @@ export declare class ServiceManager extends TypedEmitter<ServiceManagerEvents> {
40
42
  detectAll(): Promise<ServiceSnapshot[]>;
41
43
  start(): void;
42
44
  stop(): void;
43
- /** Refresh all detected adapters concurrently. Overlapping calls are skipped. */
44
- refresh(): Promise<ServiceSnapshot[]>;
45
+ /**
46
+ * Refresh all detected adapters concurrently. Overlapping calls are skipped.
47
+ * A `polled` refresh (the timer) skips adapters whose `refreshIntervalMs`
48
+ * has not elapsed; an explicit refresh checks everything.
49
+ */
50
+ refresh(options?: {
51
+ polled?: boolean;
52
+ }): Promise<ServiceSnapshot[]>;
45
53
  runAction(id: string, action: "start" | "stop" | "restart", context: ServiceActionContext): Promise<void>;
46
54
  private setSnapshot;
47
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceManager.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/ServiceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAA8B,MAAM,oBAAoB,CAAA;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAA;AAEtG,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,CAAA;IACnC,iBAAiB,EAAE,CAAC,eAAe,CAAC,CAAA;IACpC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAA;CAC9B,CAAA;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAA;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAQD;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IASxD,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;gBAEX,OAAO,EAAE,qBAAqB;IAM3D,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIvC,WAAW,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAItD,IAAI,IAAI,eAAe,EAAE;IAIzB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI5C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIlD,mFAAmF;IAC7E,SAAS,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAuB7C,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAMZ,iFAAiF;IAC3E,OAAO,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAoCrC,SAAS,CACb,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EACpC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAqBhB,OAAO,CAAC,WAAW;CAapB"}
1
+ {"version":3,"file":"ServiceManager.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/ServiceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAA8B,MAAM,oBAAoB,CAAA;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAA;AAEtG,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,CAAA;IACnC,iBAAiB,EAAE,CAAC,eAAe,CAAC,CAAA;IACpC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAA;CAC9B,CAAA;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAA;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAQD;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAWxD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;gBAEX,OAAO,EAAE,qBAAqB;IAM3D,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIvC,WAAW,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAItD,IAAI,IAAI,eAAe,EAAE;IAIzB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI5C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIlD,mFAAmF;IAC7E,SAAS,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAuB7C,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAMZ;;;;OAIG;IACG,OAAO,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA0CvE,SAAS,CACb,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EACpC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAqBhB,OAAO,CAAC,WAAW;CAapB"}
@@ -18,6 +18,8 @@ export class ServiceManager extends TypedEmitter {
18
18
  adapters = new Map();
19
19
  detected = new Set();
20
20
  snapshots = new Map();
21
+ /** When each adapter was last asked for its status. */
22
+ checkedAt = new Map();
21
23
  timer = null;
22
24
  refreshing = false;
23
25
  intervalMs;
@@ -69,7 +71,7 @@ export class ServiceManager extends TypedEmitter {
69
71
  start() {
70
72
  if (this.timer)
71
73
  return;
72
- this.timer = setInterval(() => void this.refresh(), this.intervalMs);
74
+ this.timer = setInterval(() => void this.refresh({ polled: true }), this.intervalMs);
73
75
  this.timer.unref?.();
74
76
  }
75
77
  stop() {
@@ -78,15 +80,27 @@ export class ServiceManager extends TypedEmitter {
78
80
  clearInterval(this.timer);
79
81
  this.timer = null;
80
82
  }
81
- /** Refresh all detected adapters concurrently. Overlapping calls are skipped. */
82
- async refresh() {
83
+ /**
84
+ * Refresh all detected adapters concurrently. Overlapping calls are skipped.
85
+ * A `polled` refresh (the timer) skips adapters whose `refreshIntervalMs`
86
+ * has not elapsed; an explicit refresh checks everything.
87
+ */
88
+ async refresh(options = {}) {
83
89
  if (this.refreshing)
84
90
  return this.list();
85
91
  this.refreshing = true;
86
92
  try {
93
+ const now = Date.now();
87
94
  const targets = [...this.detected]
88
95
  .map((id) => this.adapters.get(id))
89
- .filter((a) => !!a);
96
+ .filter((a) => !!a)
97
+ .filter((adapter) => {
98
+ if (!options.polled || !adapter.refreshIntervalMs)
99
+ return true;
100
+ return now - (this.checkedAt.get(adapter.id) ?? 0) >= adapter.refreshIntervalMs;
101
+ });
102
+ for (const adapter of targets)
103
+ this.checkedAt.set(adapter.id, now);
90
104
  await Promise.all(targets.map(async (adapter) => {
91
105
  const status = await withTimeout(adapter.getStatus().catch((error) => {
92
106
  this.options.logger.debug("service status failed", {
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceManager.js","sourceRoot":"","sources":["../../../src/devcc/services/ServiceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAkB9C,MAAM,cAAc,GAAkB;IACpC,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,wBAAwB;IAChC,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;CACvB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,YAAkC;IASvC;IARZ,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAA;IAC5C,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;IAC5B,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAA;IACvD,KAAK,GAA0B,IAAI,CAAA;IACnC,UAAU,GAAG,KAAK,CAAA;IACT,UAAU,CAAQ;IAClB,eAAe,CAAQ;IAExC,YAA6B,OAA8B;QACzD,KAAK,EAAE,CAAA;QADoB,YAAO,GAAP,OAAO,CAAuB;QAEzD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAA;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAA;IACzD,CAAC;IAED,QAAQ,CAAC,OAAuB;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACxC,CAAC;IAED,WAAW,CAAC,QAAmC;QAC7C,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACxD,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC/B,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,mFAAmF;IACnF,KAAK,CAAC,SAAS;QACb,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAChD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;gBACjF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAClG,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;YACrC,CAAC;QACH,CAAC,CAAC,CACH,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACrB,KAAK,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,OAAO,EAAE,CAAC;YAC5C,IAAI,QAAQ;gBAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;;gBACtC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACxC,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;QACpB,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QACtB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QACpE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;IACtB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QACvB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;iBAC/B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;iBAClC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAE1C,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;oBAC3C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE;wBACjD,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC;qBAC3B,CAAC,CAAA;oBACF,OAAO;wBACL,KAAK,EAAE,SAAS;wBAChB,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;wBAC3B,SAAS,EAAE,IAAI,IAAI,EAAE;qBACE,CAAA;gBAC3B,CAAC,CAAC,EACF,IAAI,CAAC,eAAe,EACpB,EAAE,GAAG,cAAc,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAC7C,CAAA;gBACD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YACnC,CAAC,CAAC,CACH,CAAA;YAED,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YACtC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CACb,EAAU,EACV,MAAoC,EACpC,OAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAA;QAE5F,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,qBAAqB,MAAM,EAAE,EAAE,CAAC,CAAA;QACnG,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACpC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,SAAS,CAAC,CAAA;YACrF,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;YACtC,MAAM,UAAU,CAAA;QAClB,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;QACtB,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,OAAuB,EAAE,MAAqB;QAChE,MAAM,QAAQ,GAAoB;YAChC,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM;YACN,QAAQ,EAAE,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU;YAC7C,OAAO,EAAE,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU;YAC3C,UAAU,EAAE,OAAO,OAAO,CAAC,OAAO,KAAK,UAAU;SAClD,CAAA;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;IACxC,CAAC;CACF"}
1
+ {"version":3,"file":"ServiceManager.js","sourceRoot":"","sources":["../../../src/devcc/services/ServiceManager.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,17 @@ export declare class PortService implements ServiceAdapter {
32
32
  detect(): Promise<boolean>;
33
33
  getStatus(): Promise<ServiceStatus>;
34
34
  }
35
+ export interface FrameworkHint {
36
+ /** Dependency name to look for in package.json. */
37
+ dependency: string;
38
+ id: string;
39
+ name: string;
40
+ port: number;
41
+ category?: ServiceAdapter["category"];
42
+ healthPath?: string;
43
+ }
44
+ /** Frameworks this project depends on, in hint order, one per port. */
45
+ export declare function detectFrameworks(packageJson: Record<string, unknown> | null): FrameworkHint[];
35
46
  /**
36
47
  * Build port adapters for frameworks this project actually depends on.
37
48
  * Nothing is assumed: a project with none of these gets no adapters.
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACrC,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IAE7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,OAAO,EAAE,kBAAkB;IAWjC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;CAsB1C;AAqCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,WAAW,EAAE,CAsB7F"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACrC,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IAE7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,OAAO,EAAE,kBAAkB;IAWjC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;CAsB1C;AAED,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACrC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA2BD,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,aAAa,EAAE,CAU7F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,WAAW,EAAE,CAY7F"}
@@ -79,29 +79,31 @@ function dependencyNames(packageJson) {
79
79
  }
80
80
  return names;
81
81
  }
82
- /**
83
- * Build port adapters for frameworks this project actually depends on.
84
- * Nothing is assumed: a project with none of these gets no adapters.
85
- */
86
- export function detectNodeServices(packageJson) {
82
+ /** Frameworks this project depends on, in hint order, one per port. */
83
+ export function detectFrameworks(packageJson) {
87
84
  const dependencies = dependencyNames(packageJson);
88
85
  const seenPorts = new Set();
89
- const adapters = [];
86
+ const found = [];
90
87
  for (const hint of FRAMEWORK_HINTS) {
91
- if (!dependencies.has(hint.dependency))
92
- continue;
93
- if (seenPorts.has(hint.port))
88
+ if (!dependencies.has(hint.dependency) || seenPorts.has(hint.port))
94
89
  continue;
95
90
  seenPorts.add(hint.port);
96
- adapters.push(new PortService({
97
- id: hint.id,
98
- name: hint.name,
99
- port: hint.port,
100
- category: hint.category ?? "web",
101
- healthPath: hint.healthPath,
102
- onlyWhenListening: true,
103
- }));
91
+ found.push(hint);
104
92
  }
105
- return adapters;
93
+ return found;
94
+ }
95
+ /**
96
+ * Build port adapters for frameworks this project actually depends on.
97
+ * Nothing is assumed: a project with none of these gets no adapters.
98
+ */
99
+ export function detectNodeServices(packageJson) {
100
+ return detectFrameworks(packageJson).map((hint) => new PortService({
101
+ id: hint.id,
102
+ name: hint.name,
103
+ port: hint.port,
104
+ category: hint.category ?? "web",
105
+ healthPath: hint.healthPath,
106
+ onlyWhenListening: true,
107
+ }));
106
108
  }
107
109
  //# sourceMappingURL=node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/devcc/services/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/devcc/services/node.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,86 @@
1
1
  import type { ServiceAdapter, ServiceStatus } from "./types.js";
2
+ interface OllamaModelDetails {
3
+ parameter_size?: string;
4
+ quantization_level?: string;
5
+ family?: string;
6
+ }
7
+ interface OllamaTagsResponse {
8
+ models?: {
9
+ name?: string;
10
+ size?: number;
11
+ details?: OllamaModelDetails;
12
+ }[];
13
+ }
14
+ interface OllamaPsResponse {
15
+ models?: {
16
+ name?: string;
17
+ size?: number;
18
+ size_vram?: number;
19
+ expires_at?: string;
20
+ details?: OllamaModelDetails;
21
+ }[];
22
+ }
23
+ export interface OllamaModel {
24
+ name: string;
25
+ /** Bytes on disk. */
26
+ size?: number;
27
+ parameterSize?: string;
28
+ quantization?: string;
29
+ family?: string;
30
+ /** Loaded into memory right now. */
31
+ loaded: boolean;
32
+ /** Bytes of VRAM in use, when loaded. */
33
+ vram?: number;
34
+ /** When Ollama will unload it. */
35
+ expiresAt?: Date;
36
+ }
2
37
  export interface OllamaServiceOptions {
38
+ /** Defaults to `ollama`; set for extra endpoints. */
39
+ id?: string;
40
+ name?: string;
41
+ /** `http://gpu-server:11434`. Takes precedence over host/port and `OLLAMA_HOST`. */
42
+ baseUrl?: string;
3
43
  host?: string;
4
44
  port?: number;
5
45
  timeoutMs?: number;
46
+ /** Minimum time between polled checks (default: none locally, 60s for a baseUrl). */
47
+ refreshIntervalMs?: number;
6
48
  }
7
49
  /**
8
- * Ollama adapter. Uses the HTTP API for a model count when the port is open;
9
- * falls back to a plain port probe if the API call fails.
50
+ * Ollama adapter, local or remote.
51
+ *
52
+ * Reachability is a TCP probe; when the port answers, `/api/tags` lists the
53
+ * models and `/api/ps` says which are loaded. Model names are never assumed.
10
54
  */
11
55
  export declare class OllamaService implements ServiceAdapter {
12
- readonly id = "ollama";
13
- readonly name = "Ollama";
56
+ readonly id: string;
57
+ readonly name: string;
14
58
  readonly category: "ai";
59
+ readonly refreshIntervalMs: number | undefined;
60
+ private readonly baseUrl;
15
61
  private readonly host;
16
62
  private readonly port;
17
63
  private readonly timeoutMs;
64
+ private readonly remote;
18
65
  constructor(options?: OllamaServiceOptions);
66
+ /** A configured endpoint is always shown, so "unreachable" is visible; the local one only when running. */
19
67
  detect(): Promise<boolean>;
20
68
  getStatus(): Promise<ServiceStatus>;
21
- private listModels;
69
+ /** Models with metadata, for the CLI and tests. Null when unreachable. */
70
+ listModels(): Promise<OllamaModel[] | null>;
71
+ private getJson;
22
72
  }
73
+ /** Combine `/api/tags` with `/api/ps`: loaded models first, then by name. */
74
+ export declare function mergeOllamaModels(tags: OllamaTagsResponse, ps: OllamaPsResponse | null): OllamaModel[];
75
+ /** A full base URL: a missing port means the scheme's default, exactly as `fetch` will treat it. */
76
+ export declare function parseBaseUrl(value: string): {
77
+ host: string;
78
+ port: number;
79
+ } | null;
80
+ /** `OLLAMA_HOST`-style `host[:port]`, where a missing port means Ollama's 11434. */
23
81
  export declare function parseHostPort(value: string | undefined): {
24
82
  host: string;
25
83
  port: number;
26
84
  } | null;
85
+ export {};
27
86
  //# sourceMappingURL=ollama.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/ollama.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAS/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,QAAQ,CAAC,EAAE,YAAW;IACtB,QAAQ,CAAC,IAAI,YAAW;IACxB,QAAQ,CAAC,QAAQ,EAAG,IAAI,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,OAAO,GAAE,oBAAyB;IAOxC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAI1B,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;YAgB3B,UAAU;CAYzB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS9F"}
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/ollama.ts"],"names":[],"mappings":"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"}
@@ -1,56 +1,157 @@
1
+ import { formatBytes } from "../utils/format.js";
1
2
  import { probeTcpPort } from "../utils/exec.js";
2
3
  const DEFAULT_HOST = "127.0.0.1";
3
4
  const DEFAULT_PORT = 11434;
5
+ /** Remote endpoints are checked at most this often while polling. */
6
+ const REMOTE_REFRESH_MS = 60_000;
7
+ const MAX_ITEMS = 12;
4
8
  /**
5
- * Ollama adapter. Uses the HTTP API for a model count when the port is open;
6
- * falls back to a plain port probe if the API call fails.
9
+ * Ollama adapter, local or remote.
10
+ *
11
+ * Reachability is a TCP probe; when the port answers, `/api/tags` lists the
12
+ * models and `/api/ps` says which are loaded. Model names are never assumed.
7
13
  */
8
14
  export class OllamaService {
9
- id = "ollama";
10
- name = "Ollama";
15
+ id;
16
+ name;
11
17
  category = "ai";
18
+ refreshIntervalMs;
19
+ baseUrl;
12
20
  host;
13
21
  port;
14
22
  timeoutMs;
23
+ remote;
15
24
  constructor(options = {}) {
25
+ const fromUrl = options.baseUrl ? parseBaseUrl(options.baseUrl) : null;
16
26
  const fromEnv = parseHostPort(process.env.OLLAMA_HOST);
17
- this.host = options.host ?? fromEnv?.host ?? DEFAULT_HOST;
18
- this.port = options.port ?? fromEnv?.port ?? DEFAULT_PORT;
27
+ this.remote = options.baseUrl !== undefined;
28
+ this.id = options.id ?? "ollama";
29
+ this.host = fromUrl?.host ?? options.host ?? fromEnv?.host ?? DEFAULT_HOST;
30
+ this.port = fromUrl?.port ?? options.port ?? fromEnv?.port ?? DEFAULT_PORT;
31
+ this.baseUrl = options.baseUrl?.replace(/\/+$/u, "") ?? `http://${this.host}:${this.port}`;
32
+ this.name = options.name ?? (this.remote ? `Ollama (${this.host})` : "Ollama");
19
33
  this.timeoutMs = options.timeoutMs ?? 1_500;
34
+ this.refreshIntervalMs = options.refreshIntervalMs ?? (this.remote ? REMOTE_REFRESH_MS : undefined);
20
35
  }
36
+ /** A configured endpoint is always shown, so "unreachable" is visible; the local one only when running. */
21
37
  async detect() {
38
+ if (this.remote)
39
+ return true;
22
40
  return probeTcpPort(this.port, this.host);
23
41
  }
24
42
  async getStatus() {
25
43
  const checkedAt = new Date();
26
44
  const endpoint = `${this.host}:${this.port}`;
27
- const listening = await probeTcpPort(this.port, this.host);
28
- if (!listening)
29
- return { state: "stopped", endpoint, detail: "not listening", checkedAt };
30
- const models = await this.listModels();
45
+ const listening = await probeTcpPort(this.port, this.host, this.remote ? 2_000 : 700);
46
+ if (!listening) {
47
+ return { state: "stopped", endpoint, detail: this.remote ? "unreachable" : "not listening", checkedAt };
48
+ }
49
+ const [tags, ps] = await Promise.all([
50
+ this.getJson("/api/tags"),
51
+ this.getJson("/api/ps"),
52
+ ]);
53
+ if (!tags)
54
+ return { state: "degraded", endpoint, detail: "listening, API not responding", checkedAt };
55
+ const models = mergeOllamaModels(tags, ps);
56
+ const loaded = models.filter((model) => model.loaded).length;
57
+ const detail = [
58
+ `${models.length} model${models.length === 1 ? "" : "s"}`,
59
+ ps ? `${loaded} loaded` : undefined,
60
+ ]
61
+ .filter(Boolean)
62
+ .join(" · ");
31
63
  return {
32
64
  state: "running",
33
65
  endpoint,
34
- detail: models === null ? "listening" : `${models.length} model${models.length === 1 ? "" : "s"}`,
35
- items: models?.slice(0, 6).map((name) => ({ name, state: "running" })),
66
+ detail,
67
+ items: models.slice(0, MAX_ITEMS).map(modelItem),
36
68
  checkedAt,
37
69
  };
38
70
  }
71
+ /** Models with metadata, for the CLI and tests. Null when unreachable. */
39
72
  async listModels() {
73
+ const [tags, ps] = await Promise.all([
74
+ this.getJson("/api/tags"),
75
+ this.getJson("/api/ps"),
76
+ ]);
77
+ return tags ? mergeOllamaModels(tags, ps) : null;
78
+ }
79
+ async getJson(path) {
40
80
  try {
41
- const response = await fetch(`http://${this.host}:${this.port}/api/tags`, {
42
- signal: AbortSignal.timeout(this.timeoutMs),
43
- });
81
+ const response = await fetch(`${this.baseUrl}${path}`, { signal: AbortSignal.timeout(this.timeoutMs) });
44
82
  if (!response.ok)
45
83
  return null;
46
- const body = (await response.json());
47
- return (body.models ?? []).map((model) => model.name ?? "unnamed");
84
+ return (await response.json());
48
85
  }
49
86
  catch {
50
87
  return null;
51
88
  }
52
89
  }
53
90
  }
91
+ /** Combine `/api/tags` with `/api/ps`: loaded models first, then by name. */
92
+ export function mergeOllamaModels(tags, ps) {
93
+ const running = new Map((ps?.models ?? []).filter((model) => model.name).map((model) => [model.name, model]));
94
+ const models = (tags.models ?? [])
95
+ .filter((model) => typeof model.name === "string")
96
+ .map((model) => {
97
+ const name = model.name;
98
+ const live = running.get(name);
99
+ running.delete(name);
100
+ return {
101
+ name,
102
+ size: model.size,
103
+ parameterSize: model.details?.parameter_size,
104
+ quantization: model.details?.quantization_level,
105
+ family: model.details?.family,
106
+ loaded: live !== undefined,
107
+ vram: live?.size_vram,
108
+ expiresAt: parseDate(live?.expires_at),
109
+ };
110
+ });
111
+ // A model can be loaded but missing from tags (e.g. pulled mid-refresh).
112
+ for (const [name, live] of running) {
113
+ models.push({
114
+ name,
115
+ size: live.size,
116
+ parameterSize: live.details?.parameter_size,
117
+ quantization: live.details?.quantization_level,
118
+ family: live.details?.family,
119
+ loaded: true,
120
+ vram: live.size_vram,
121
+ expiresAt: parseDate(live.expires_at),
122
+ });
123
+ }
124
+ return models.sort((a, b) => Number(b.loaded) - Number(a.loaded) || a.name.localeCompare(b.name));
125
+ }
126
+ function modelItem(model) {
127
+ const meta = [model.parameterSize, model.quantization, model.size ? formatBytes(model.size) : undefined];
128
+ if (model.loaded && model.vram)
129
+ meta.push(`${formatBytes(model.vram)} VRAM`);
130
+ return {
131
+ name: model.name,
132
+ state: model.loaded ? "running" : "stopped",
133
+ detail: [model.loaded ? "loaded" : undefined, ...meta].filter(Boolean).join(" · "),
134
+ };
135
+ }
136
+ function parseDate(value) {
137
+ if (!value)
138
+ return undefined;
139
+ const date = new Date(value);
140
+ return Number.isNaN(date.getTime()) ? undefined : date;
141
+ }
142
+ /** A full base URL: a missing port means the scheme's default, exactly as `fetch` will treat it. */
143
+ export function parseBaseUrl(value) {
144
+ try {
145
+ const parsed = new URL(value);
146
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
147
+ return null;
148
+ return { host: parsed.hostname, port: Number(parsed.port || (parsed.protocol === "https:" ? 443 : 80)) };
149
+ }
150
+ catch {
151
+ return null;
152
+ }
153
+ }
154
+ /** `OLLAMA_HOST`-style `host[:port]`, where a missing port means Ollama's 11434. */
54
155
  export function parseHostPort(value) {
55
156
  if (!value)
56
157
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../src/devcc/services/ollama.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../src/devcc/services/ollama.ts"],"names":[],"mappings":"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"}