nomoreide 0.1.27 → 0.1.28

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 (41) hide show
  1. package/dist/core/config-store.d.ts +4 -1
  2. package/dist/core/config-store.js +85 -0
  3. package/dist/core/config-store.js.map +1 -1
  4. package/dist/core/log-sources.d.ts +21 -0
  5. package/dist/core/log-sources.js +219 -0
  6. package/dist/core/log-sources.js.map +1 -0
  7. package/dist/core/service-log-source.d.ts +9 -0
  8. package/dist/core/service-log-source.js +49 -0
  9. package/dist/core/service-log-source.js.map +1 -0
  10. package/dist/core/terminal-manager.d.ts +40 -0
  11. package/dist/core/terminal-manager.js +64 -0
  12. package/dist/core/terminal-manager.js.map +1 -0
  13. package/dist/core/terminal-session.d.ts +91 -0
  14. package/dist/core/terminal-session.js +159 -0
  15. package/dist/core/terminal-session.js.map +1 -0
  16. package/dist/core/types.d.ts +59 -0
  17. package/dist/web/client/assets/index-0aS5yzpo.js +40 -0
  18. package/dist/web/client/assets/index-DIpnQDCK.css +1 -0
  19. package/dist/web/client/index.html +2 -2
  20. package/dist/web/routes/context.d.ts +2 -0
  21. package/dist/web/routes/context.js.map +1 -1
  22. package/dist/web/routes/git-routes.js +9 -1
  23. package/dist/web/routes/git-routes.js.map +1 -1
  24. package/dist/web/routes/index.js +4 -0
  25. package/dist/web/routes/index.js.map +1 -1
  26. package/dist/web/routes/log-sources-routes.d.ts +6 -0
  27. package/dist/web/routes/log-sources-routes.js +102 -0
  28. package/dist/web/routes/log-sources-routes.js.map +1 -0
  29. package/dist/web/routes/service-routes.js +24 -2
  30. package/dist/web/routes/service-routes.js.map +1 -1
  31. package/dist/web/routes/shell-routes.js +8 -1
  32. package/dist/web/routes/shell-routes.js.map +1 -1
  33. package/dist/web/routes/terminal-routes.d.ts +7 -0
  34. package/dist/web/routes/terminal-routes.js +25 -0
  35. package/dist/web/routes/terminal-routes.js.map +1 -0
  36. package/dist/web/server.d.ts +2 -0
  37. package/dist/web/server.js +104 -0
  38. package/dist/web/server.js.map +1 -1
  39. package/package.json +6 -1
  40. package/dist/web/client/assets/index-BSh_mD42.css +0 -1
  41. package/dist/web/client/assets/index-CD6SvvAp.js +0 -26
@@ -0,0 +1,91 @@
1
+ export type TerminalState = "idle" | "running" | "exited" | "error";
2
+ export interface TerminalSize {
3
+ cols: number;
4
+ rows: number;
5
+ }
6
+ export interface TerminalExit {
7
+ exitCode?: number;
8
+ signal?: number | string;
9
+ }
10
+ export interface TerminalSnapshot extends TerminalSize {
11
+ cwd: string;
12
+ state: TerminalState;
13
+ shell: string;
14
+ exit?: TerminalExit;
15
+ error?: string;
16
+ }
17
+ export interface PtyProcess {
18
+ write(data: string): void;
19
+ resize(cols: number, rows: number): void;
20
+ kill(signal?: string): void;
21
+ onData(callback: (data: string) => void): {
22
+ dispose(): void;
23
+ };
24
+ onExit(callback: (exit: TerminalExit) => void): {
25
+ dispose(): void;
26
+ };
27
+ }
28
+ export interface PtyAdapter {
29
+ spawn(file: string, args: string[], options: {
30
+ cwd: string;
31
+ env: NodeJS.ProcessEnv;
32
+ cols: number;
33
+ rows: number;
34
+ name: string;
35
+ }): PtyProcess;
36
+ }
37
+ export interface TerminalSessionOptions {
38
+ adapter?: PtyAdapter;
39
+ cwd: string;
40
+ env?: NodeJS.ProcessEnv;
41
+ shell?: string;
42
+ }
43
+ type Listener<T> = (value: T) => void;
44
+ export interface TerminalSessionLike {
45
+ dispose(): void;
46
+ onOutput(listener: Listener<string>): {
47
+ dispose(): void;
48
+ };
49
+ onState(listener: Listener<TerminalSnapshot>): {
50
+ dispose(): void;
51
+ };
52
+ resize(cols: number, rows: number): TerminalSnapshot;
53
+ restart(size?: Partial<TerminalSize>): TerminalSnapshot;
54
+ snapshot(): TerminalSnapshot;
55
+ start(size?: Partial<TerminalSize>): TerminalSnapshot;
56
+ stop(signal?: string): TerminalSnapshot;
57
+ write(data: string): void;
58
+ }
59
+ export declare class TerminalSession implements TerminalSessionLike {
60
+ private readonly adapter;
61
+ private readonly cwd;
62
+ private readonly env;
63
+ private readonly shell;
64
+ private cols;
65
+ private rows;
66
+ private exit;
67
+ private error;
68
+ private outputListeners;
69
+ private stateListeners;
70
+ private process;
71
+ private state;
72
+ private disposables;
73
+ constructor(options: TerminalSessionOptions);
74
+ snapshot(): TerminalSnapshot;
75
+ onOutput(listener: Listener<string>): {
76
+ dispose(): void;
77
+ };
78
+ onState(listener: Listener<TerminalSnapshot>): {
79
+ dispose(): void;
80
+ };
81
+ start(size?: Partial<TerminalSize>): TerminalSnapshot;
82
+ restart(size?: Partial<TerminalSize>): TerminalSnapshot;
83
+ stop(signal?: string): TerminalSnapshot;
84
+ write(data: string): void;
85
+ resize(cols: number, rows: number): TerminalSnapshot;
86
+ dispose(): void;
87
+ private emitOutput;
88
+ private emitState;
89
+ private disposeProcessListeners;
90
+ }
91
+ export {};
@@ -0,0 +1,159 @@
1
+ import { createRequire } from "node:module";
2
+ const require = createRequire(import.meta.url);
3
+ export class TerminalSession {
4
+ adapter;
5
+ cwd;
6
+ env;
7
+ shell;
8
+ cols = 80;
9
+ rows = 24;
10
+ exit;
11
+ error;
12
+ outputListeners = new Set();
13
+ stateListeners = new Set();
14
+ process;
15
+ state = "idle";
16
+ disposables = [];
17
+ constructor(options) {
18
+ this.adapter = options.adapter ?? new NodePtyAdapter();
19
+ this.cwd = options.cwd;
20
+ this.env = options.env ?? process.env;
21
+ this.shell = options.shell ?? defaultShell();
22
+ }
23
+ snapshot() {
24
+ return {
25
+ cols: this.cols,
26
+ cwd: this.cwd,
27
+ error: this.error,
28
+ exit: this.exit,
29
+ rows: this.rows,
30
+ shell: this.shell,
31
+ state: this.state,
32
+ };
33
+ }
34
+ onOutput(listener) {
35
+ this.outputListeners.add(listener);
36
+ return {
37
+ dispose: () => {
38
+ this.outputListeners.delete(listener);
39
+ },
40
+ };
41
+ }
42
+ onState(listener) {
43
+ this.stateListeners.add(listener);
44
+ return {
45
+ dispose: () => {
46
+ this.stateListeners.delete(listener);
47
+ },
48
+ };
49
+ }
50
+ start(size = {}) {
51
+ if (this.process && this.state === "running") {
52
+ if (size.cols && size.rows)
53
+ this.resize(size.cols, size.rows);
54
+ return this.snapshot();
55
+ }
56
+ this.cols = normalizeDimension(size.cols, this.cols);
57
+ this.rows = normalizeDimension(size.rows, this.rows);
58
+ this.exit = undefined;
59
+ this.error = undefined;
60
+ try {
61
+ const child = this.adapter.spawn(this.shell, [], {
62
+ cols: this.cols,
63
+ cwd: this.cwd,
64
+ env: this.env,
65
+ name: "xterm-256color",
66
+ rows: this.rows,
67
+ });
68
+ this.process = child;
69
+ this.state = "running";
70
+ this.disposables = [
71
+ child.onData((data) => this.emitOutput(data)),
72
+ child.onExit((exit) => {
73
+ this.exit = exit;
74
+ this.process = undefined;
75
+ this.state = "exited";
76
+ this.disposeProcessListeners();
77
+ this.emitState();
78
+ }),
79
+ ];
80
+ }
81
+ catch (caught) {
82
+ this.process = undefined;
83
+ this.error = caught instanceof Error ? caught.message : String(caught);
84
+ this.state = "error";
85
+ }
86
+ this.emitState();
87
+ return this.snapshot();
88
+ }
89
+ restart(size = {}) {
90
+ this.stop("SIGHUP");
91
+ return this.start(size);
92
+ }
93
+ stop(signal = "SIGHUP") {
94
+ const child = this.process;
95
+ this.process = undefined;
96
+ if (child) {
97
+ child.kill(signal);
98
+ }
99
+ this.disposeProcessListeners();
100
+ if (this.state === "running") {
101
+ this.state = "exited";
102
+ this.exit = { signal };
103
+ }
104
+ this.emitState();
105
+ return this.snapshot();
106
+ }
107
+ write(data) {
108
+ if (!this.process || this.state !== "running")
109
+ return;
110
+ this.process.write(data);
111
+ }
112
+ resize(cols, rows) {
113
+ this.cols = normalizeDimension(cols, this.cols);
114
+ this.rows = normalizeDimension(rows, this.rows);
115
+ if (this.process && this.state === "running") {
116
+ this.process.resize(this.cols, this.rows);
117
+ }
118
+ this.emitState();
119
+ return this.snapshot();
120
+ }
121
+ dispose() {
122
+ this.stop("SIGHUP");
123
+ this.outputListeners.clear();
124
+ this.stateListeners.clear();
125
+ }
126
+ emitOutput(data) {
127
+ for (const listener of this.outputListeners)
128
+ listener(data);
129
+ }
130
+ emitState() {
131
+ const snapshot = this.snapshot();
132
+ for (const listener of this.stateListeners)
133
+ listener(snapshot);
134
+ }
135
+ disposeProcessListeners() {
136
+ for (const item of this.disposables)
137
+ item.dispose();
138
+ this.disposables = [];
139
+ }
140
+ }
141
+ class NodePtyAdapter {
142
+ spawn(file, args, options) {
143
+ const nodePty = require("node-pty");
144
+ return nodePty.spawn(file, args, options);
145
+ }
146
+ }
147
+ function defaultShell() {
148
+ if (process.env.SHELL)
149
+ return process.env.SHELL;
150
+ if (process.platform === "win32")
151
+ return process.env.COMSPEC ?? "cmd.exe";
152
+ return process.platform === "darwin" ? "/bin/zsh" : "/bin/sh";
153
+ }
154
+ function normalizeDimension(value, fallback) {
155
+ if (typeof value !== "number" || !Number.isFinite(value))
156
+ return fallback;
157
+ return Math.max(1, Math.floor(value));
158
+ }
159
+ //# sourceMappingURL=terminal-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-session.js","sourceRoot":"","sources":["../../src/core/terminal-session.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,62 @@ export interface DatabaseConnection {
34
34
  engine: DatabaseEngine;
35
35
  url: string;
36
36
  }
37
+ export type LogSourceKind = "file" | "ssh" | "command";
38
+ /**
39
+ * Structured log backend. When set, the source builds its own query (time
40
+ * range, text filter, level) instead of a fixed `tail`, pushing the work down
41
+ * to the host. Runs over ssh when `host` is set, otherwise locally.
42
+ */
43
+ export type LogDriver = "journald" | "docker";
44
+ /**
45
+ * A named, on-demand log reader (e.g. "UAT", "PROD") that is *not* tied to a
46
+ * managed process. `file` tails a local path, `ssh` tails a path on a remote
47
+ * host via the local ssh binary + ~/.ssh/config, and `command` runs an
48
+ * arbitrary command (journalctl, kubectl logs, …) and treats its output as log.
49
+ *
50
+ * Setting `driver` upgrades the source to a query backend: `journald` filters
51
+ * server-side via journalctl flags, `docker` via `docker logs` windowing.
52
+ */
53
+ export interface LogSourceDefinition {
54
+ name: string;
55
+ kind: LogSourceKind;
56
+ /** Absolute path for `file`; remote path for `ssh`. */
57
+ path?: string;
58
+ /** SSH host/alias for `ssh`, and for any `driver` source run remotely. */
59
+ host?: string;
60
+ /** Command line for `command`. */
61
+ command?: string;
62
+ /** Optional working directory for `command`. */
63
+ cwd?: string;
64
+ /** Query backend. When set, `since`/`until`/`grep`/`level` are honored. */
65
+ driver?: LogDriver;
66
+ /** systemd unit for `driver: "journald"`. */
67
+ unit?: string;
68
+ /** container name/id for `driver: "docker"`. */
69
+ container?: string;
70
+ }
71
+ /**
72
+ * Read-time query for a log source. Honored fully by `journald` (server-side
73
+ * journalctl flags) and partially by `docker` (time window server-side, text +
74
+ * level filtered client-side); for plain file/ssh/command sources `grep`/`level`
75
+ * are applied client-side and `since`/`until`/`cursor` are ignored.
76
+ */
77
+ export interface LogQuery {
78
+ /** Start of time window, e.g. "today", "1 hour ago", "2026-05-24 00:00". */
79
+ since?: string;
80
+ /** End of time window. */
81
+ until?: string;
82
+ /** Case-insensitive text/regex filter. */
83
+ grep?: string;
84
+ /** Minimum severity to include. */
85
+ level?: "warn" | "error";
86
+ /** Max lines (tail). */
87
+ lines?: number;
88
+ /** journald cursor to page *newer* than (`--after-cursor`). */
89
+ cursor?: string;
90
+ /** journald cursor to page *older* than — returns the `lines` entries before it. */
91
+ before?: string;
92
+ }
37
93
  export interface NoMoreIdeConfig {
38
94
  version: 1;
39
95
  services: ServiceDefinition[];
@@ -41,6 +97,7 @@ export interface NoMoreIdeConfig {
41
97
  gitRepositories: GitRepositoryDefinition[];
42
98
  selectedGitRepository?: string;
43
99
  databases: DatabaseConnection[];
100
+ logSources: LogSourceDefinition[];
44
101
  }
45
102
  export type ServiceState = "stopped" | "starting" | "running" | "exited";
46
103
  export interface ServiceStatus {
@@ -69,6 +126,8 @@ export interface LogEntry {
69
126
  stream: LogStream;
70
127
  text: string;
71
128
  timestamp: string;
129
+ /** journald `__CURSOR` for sources that support it; enables "load older" paging. */
130
+ cursor?: string;
72
131
  }
73
132
  export type ServiceHealthStatus = "unknown" | "healthy" | "warning" | "unhealthy";
74
133
  export interface HealthCheckResult {