@abdasis/agentdeck 2.44.2
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.
- package/README.md +122 -0
- package/agent/dist/config.d.ts +31 -0
- package/agent/dist/config.d.ts.map +1 -0
- package/agent/dist/config.js +81 -0
- package/agent/dist/config.js.map +1 -0
- package/agent/dist/db/commands.d.ts +25 -0
- package/agent/dist/db/commands.d.ts.map +1 -0
- package/agent/dist/db/commands.js +93 -0
- package/agent/dist/db/commands.js.map +1 -0
- package/agent/dist/db/index.d.ts +30 -0
- package/agent/dist/db/index.d.ts.map +1 -0
- package/agent/dist/db/index.js +368 -0
- package/agent/dist/db/index.js.map +1 -0
- package/agent/dist/db/schema.d.ts +74 -0
- package/agent/dist/db/schema.d.ts.map +1 -0
- package/agent/dist/db/schema.js +100 -0
- package/agent/dist/db/schema.js.map +1 -0
- package/agent/dist/db/sessions.d.ts +46 -0
- package/agent/dist/db/sessions.d.ts.map +1 -0
- package/agent/dist/db/sessions.js +198 -0
- package/agent/dist/db/sessions.js.map +1 -0
- package/agent/dist/index.d.ts +2 -0
- package/agent/dist/index.d.ts.map +1 -0
- package/agent/dist/index.js +19 -0
- package/agent/dist/index.js.map +1 -0
- package/agent/dist/lib/command-session.d.ts +20 -0
- package/agent/dist/lib/command-session.d.ts.map +1 -0
- package/agent/dist/lib/command-session.js +64 -0
- package/agent/dist/lib/command-session.js.map +1 -0
- package/agent/dist/lib/git.d.ts +8 -0
- package/agent/dist/lib/git.d.ts.map +1 -0
- package/agent/dist/lib/git.js +194 -0
- package/agent/dist/lib/git.js.map +1 -0
- package/agent/dist/lib/init-script.d.ts +33 -0
- package/agent/dist/lib/init-script.d.ts.map +1 -0
- package/agent/dist/lib/init-script.js +523 -0
- package/agent/dist/lib/init-script.js.map +1 -0
- package/agent/dist/lib/transcript.d.ts +16 -0
- package/agent/dist/lib/transcript.d.ts.map +1 -0
- package/agent/dist/lib/transcript.js +64 -0
- package/agent/dist/lib/transcript.js.map +1 -0
- package/agent/dist/logger.d.ts +12 -0
- package/agent/dist/logger.d.ts.map +1 -0
- package/agent/dist/logger.js +39 -0
- package/agent/dist/logger.js.map +1 -0
- package/agent/dist/middleware/auth.d.ts +15 -0
- package/agent/dist/middleware/auth.d.ts.map +1 -0
- package/agent/dist/middleware/auth.js +55 -0
- package/agent/dist/middleware/auth.js.map +1 -0
- package/agent/dist/routes/commands.d.ts +8 -0
- package/agent/dist/routes/commands.d.ts.map +1 -0
- package/agent/dist/routes/commands.js +229 -0
- package/agent/dist/routes/commands.js.map +1 -0
- package/agent/dist/routes/files.d.ts +7 -0
- package/agent/dist/routes/files.d.ts.map +1 -0
- package/agent/dist/routes/files.js +206 -0
- package/agent/dist/routes/files.js.map +1 -0
- package/agent/dist/routes/hooks.d.ts +7 -0
- package/agent/dist/routes/hooks.d.ts.map +1 -0
- package/agent/dist/routes/hooks.js +147 -0
- package/agent/dist/routes/hooks.js.map +1 -0
- package/agent/dist/routes/index.d.ts +10 -0
- package/agent/dist/routes/index.d.ts.map +1 -0
- package/agent/dist/routes/index.js +10 -0
- package/agent/dist/routes/index.js.map +1 -0
- package/agent/dist/routes/pair.d.ts +26 -0
- package/agent/dist/routes/pair.d.ts.map +1 -0
- package/agent/dist/routes/pair.js +384 -0
- package/agent/dist/routes/pair.js.map +1 -0
- package/agent/dist/routes/projects.d.ts +6 -0
- package/agent/dist/routes/projects.d.ts.map +1 -0
- package/agent/dist/routes/projects.js +121 -0
- package/agent/dist/routes/projects.js.map +1 -0
- package/agent/dist/routes/sessions-git.d.ts +7 -0
- package/agent/dist/routes/sessions-git.d.ts.map +1 -0
- package/agent/dist/routes/sessions-git.js +31 -0
- package/agent/dist/routes/sessions-git.js.map +1 -0
- package/agent/dist/routes/sessions-tmux.d.ts +7 -0
- package/agent/dist/routes/sessions-tmux.d.ts.map +1 -0
- package/agent/dist/routes/sessions-tmux.js +94 -0
- package/agent/dist/routes/sessions-tmux.js.map +1 -0
- package/agent/dist/routes/sessions.d.ts +7 -0
- package/agent/dist/routes/sessions.d.ts.map +1 -0
- package/agent/dist/routes/sessions.js +172 -0
- package/agent/dist/routes/sessions.js.map +1 -0
- package/agent/dist/server.d.ts +6 -0
- package/agent/dist/server.d.ts.map +1 -0
- package/agent/dist/server.js +95 -0
- package/agent/dist/server.js.map +1 -0
- package/agent/dist/terminal.d.ts +19 -0
- package/agent/dist/terminal.d.ts.map +1 -0
- package/agent/dist/terminal.js +175 -0
- package/agent/dist/terminal.js.map +1 -0
- package/agent/dist/updater.d.ts +18 -0
- package/agent/dist/updater.d.ts.map +1 -0
- package/agent/dist/updater.js +122 -0
- package/agent/dist/updater.js.map +1 -0
- package/agent/dist/version.d.ts +20 -0
- package/agent/dist/version.d.ts.map +1 -0
- package/agent/dist/version.js +66 -0
- package/agent/dist/version.js.map +1 -0
- package/agent/dist/websocket-handlers.d.ts +38 -0
- package/agent/dist/websocket-handlers.d.ts.map +1 -0
- package/agent/dist/websocket-handlers.js +389 -0
- package/agent/dist/websocket-handlers.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.d.ts +2 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.d.ts.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.js +2 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts +235 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.js +5 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/package.json +29 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +304 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +187 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +109 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +38 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/profile.d.ts +3 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +156 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/service.d.ts +3 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +235 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +122 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +48 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +3 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +23 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +129 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/version.d.ts +3 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +39 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +68 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +156 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/hooks.d.ts +67 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +353 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/paths.d.ts +36 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +77 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +60 -0
- package/dist/lib/prerequisites.d.ts.map +1 -0
- package/dist/lib/prerequisites.js +266 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +40 -0
- package/dist/lib/process.d.ts.map +1 -0
- package/dist/lib/process.js +192 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/service/index.d.ts +44 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +18 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/launchd.d.ts +18 -0
- package/dist/service/launchd.d.ts.map +1 -0
- package/dist/service/launchd.js +208 -0
- package/dist/service/launchd.js.map +1 -0
- package/dist/service/systemd.d.ts +18 -0
- package/dist/service/systemd.d.ts.map +1 -0
- package/dist/service/systemd.js +196 -0
- package/dist/service/systemd.js.map +1 -0
- package/hooks/notify-agentdeck.sh +53 -0
- package/package.json +83 -0
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# AgentDeck
|
|
2
|
+
|
|
3
|
+
**Your command center for every coding agent.**
|
|
4
|
+
|
|
5
|
+
A CLI tool by [AgentDeck](https://agentdeck.dev) that lets you run Claude Code remotely and access it from any device via a web dashboard.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @agentdeck/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Prerequisites
|
|
14
|
+
|
|
15
|
+
- **Node.js 22+**
|
|
16
|
+
- **tmux** - Required for terminal session persistence
|
|
17
|
+
- macOS: `brew install tmux`
|
|
18
|
+
- Linux: `sudo apt install tmux`
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Configure the agent
|
|
24
|
+
agentdeck init
|
|
25
|
+
|
|
26
|
+
# Install as a system service (recommended)
|
|
27
|
+
agentdeck service install --start
|
|
28
|
+
|
|
29
|
+
# Or run in foreground
|
|
30
|
+
agentdeck start --foreground
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
| Command | Description |
|
|
36
|
+
| -------------------------------- | -------------------------------- |
|
|
37
|
+
| `agentdeck init` | Interactive configuration wizard |
|
|
38
|
+
| `agentdeck start` | Start the agent (daemon mode) |
|
|
39
|
+
| `agentdeck start --foreground` | Start in foreground |
|
|
40
|
+
| `agentdeck stop` | Stop the agent |
|
|
41
|
+
| `agentdeck status` | Show agent status |
|
|
42
|
+
| `agentdeck logs [-f]` | View agent logs |
|
|
43
|
+
| `agentdeck service install` | Install system service |
|
|
44
|
+
| `agentdeck service uninstall` | Remove system service |
|
|
45
|
+
| `agentdeck service start/stop/restart` | Control service |
|
|
46
|
+
| `agentdeck hooks install` | Install Claude Code hooks |
|
|
47
|
+
| `agentdeck update` | Update to latest version |
|
|
48
|
+
| `agentdeck doctor` | Diagnose issues |
|
|
49
|
+
|
|
50
|
+
## System Service
|
|
51
|
+
|
|
52
|
+
The agent can run as a system service that starts automatically on boot:
|
|
53
|
+
|
|
54
|
+
**macOS (launchd):**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
agentdeck service install --start
|
|
58
|
+
# Config: ~/Library/LaunchAgents/com.agentdeck.agent.plist
|
|
59
|
+
# Logs: ~/Library/Logs/agentdeck-agent/
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Linux (systemd):**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
agentdeck service install --start
|
|
66
|
+
# Config: ~/.config/systemd/user/agentdeck-agent.service
|
|
67
|
+
# Logs: journalctl --user -u agentdeck-agent
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
Configuration is stored in `~/.agentdeck/config.json`:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"machine": {
|
|
77
|
+
"id": "unique-machine-id",
|
|
78
|
+
"name": "My Mac"
|
|
79
|
+
},
|
|
80
|
+
"agent": {
|
|
81
|
+
"port": 4678
|
|
82
|
+
},
|
|
83
|
+
"projects": {
|
|
84
|
+
"basePath": "~/Dev"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Claude Code Hooks
|
|
90
|
+
|
|
91
|
+
The agent includes hooks that notify when Claude Code sessions stop:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
agentdeck hooks install # Install hooks
|
|
95
|
+
agentdeck hooks status # Check status
|
|
96
|
+
agentdeck hooks update # Update to latest
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Codex Notifications
|
|
100
|
+
|
|
101
|
+
Codex supports a `notify` hook command. Configure it to point to the agentdeck hook script:
|
|
102
|
+
|
|
103
|
+
```toml
|
|
104
|
+
notify = ["bash", "~/.agentdeck/hooks/notify-agentdeck.sh"]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
If `~/.codex/config.toml` exists, `agentdeck hooks install` will try to add this line for you.
|
|
108
|
+
|
|
109
|
+
## Troubleshooting
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
agentdeck doctor
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Links
|
|
116
|
+
|
|
117
|
+
- **Dashboard:** https://agentdeck.dev
|
|
118
|
+
- **GitHub:** https://github.com/QuivrHQ/247
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
MIT - AgentDeck
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface AgentConfig {
|
|
2
|
+
machine: {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
};
|
|
6
|
+
agent?: {
|
|
7
|
+
port?: number;
|
|
8
|
+
url?: string;
|
|
9
|
+
accessToken?: string;
|
|
10
|
+
};
|
|
11
|
+
projects: {
|
|
12
|
+
basePath: string;
|
|
13
|
+
whitelist: string[];
|
|
14
|
+
};
|
|
15
|
+
dashboard?: {
|
|
16
|
+
apiUrl?: string;
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load agent configuration from ~/.agentdeck/
|
|
22
|
+
* Uses AGENTDECK_PROFILE env var if set, otherwise default config
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadConfig(): AgentConfig;
|
|
25
|
+
/**
|
|
26
|
+
* Get the per-machine access token (shared secret for WS/HTTP auth). Empty
|
|
27
|
+
* string when not set — callers treat empty as "auth disabled" (opt-in).
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAccessToken(): string;
|
|
30
|
+
export declare const config: AgentConfig;
|
|
31
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAgCD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,WAAW,CAwCxC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,eAAO,MAAM,MAAM,aAAe,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
let cachedConfig = null;
|
|
5
|
+
const CONFIG_DIR = resolve(process.env.HOME || '~', '.agentdeck');
|
|
6
|
+
/**
|
|
7
|
+
* Get config file path based on profile name
|
|
8
|
+
*/
|
|
9
|
+
function getConfigPath(profileName) {
|
|
10
|
+
if (profileName) {
|
|
11
|
+
return resolve(CONFIG_DIR, 'profiles', `${profileName}.json`);
|
|
12
|
+
}
|
|
13
|
+
return resolve(CONFIG_DIR, 'config.json');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Ensure config punya agent.accessToken. Generate + tulis balik ke file bila
|
|
17
|
+
* kosong (backward compat install lama pre-auth). Token ini shared-secret
|
|
18
|
+
* untuk auth WS/HTTP per-machine.
|
|
19
|
+
*/
|
|
20
|
+
function ensureAccessToken(cfg, configPath) {
|
|
21
|
+
if (cfg.agent?.accessToken)
|
|
22
|
+
return;
|
|
23
|
+
cfg.agent = { ...cfg.agent, accessToken: randomBytes(32).toString('hex') };
|
|
24
|
+
try {
|
|
25
|
+
writeFileSync(configPath, JSON.stringify(cfg, null, 2), 'utf-8');
|
|
26
|
+
console.log(`Generated access token and saved to: ${configPath}`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.error(`Failed to persist access token to ${configPath}:`, err);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load agent configuration from ~/.agentdeck/
|
|
34
|
+
* Uses AGENTDECK_PROFILE env var if set, otherwise default config
|
|
35
|
+
*/
|
|
36
|
+
export function loadConfig() {
|
|
37
|
+
if (cachedConfig) {
|
|
38
|
+
return cachedConfig;
|
|
39
|
+
}
|
|
40
|
+
const profileName = process.env.AGENTDECK_PROFILE || undefined;
|
|
41
|
+
const configPath = getConfigPath(profileName);
|
|
42
|
+
if (existsSync(configPath)) {
|
|
43
|
+
try {
|
|
44
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
45
|
+
cachedConfig = JSON.parse(content);
|
|
46
|
+
const label = profileName ? `profile '${profileName}'` : 'default';
|
|
47
|
+
console.log(`Loaded ${label} config from: ${configPath}`);
|
|
48
|
+
ensureAccessToken(cachedConfig, configPath);
|
|
49
|
+
return cachedConfig;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
console.error(`Failed to load config from ${configPath}:`, err);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// If profile specified but not found, try default config
|
|
56
|
+
if (profileName) {
|
|
57
|
+
const defaultPath = getConfigPath();
|
|
58
|
+
if (existsSync(defaultPath)) {
|
|
59
|
+
try {
|
|
60
|
+
const content = readFileSync(defaultPath, 'utf-8');
|
|
61
|
+
cachedConfig = JSON.parse(content);
|
|
62
|
+
console.log(`Profile '${profileName}' not found, using default: ${defaultPath}`);
|
|
63
|
+
ensureAccessToken(cachedConfig, defaultPath);
|
|
64
|
+
return cachedConfig;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error(`Failed to load config from ${defaultPath}:`, err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`No configuration found at ${configPath}\n` + `Run 'agentdeck init' to create configuration.`);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the per-machine access token (shared secret for WS/HTTP auth). Empty
|
|
75
|
+
* string when not set — callers treat empty as "auth disabled" (opt-in).
|
|
76
|
+
*/
|
|
77
|
+
export function getAccessToken() {
|
|
78
|
+
return config.agent?.accessToken ?? '';
|
|
79
|
+
}
|
|
80
|
+
export const config = loadConfig();
|
|
81
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DbProjectCommand, DbProjectCommandWithRunState, DbSession } from './schema.js';
|
|
2
|
+
export interface CreateCommandInput {
|
|
3
|
+
name: string;
|
|
4
|
+
command: string;
|
|
5
|
+
cwd?: string | null;
|
|
6
|
+
position?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface UpdateCommandInput {
|
|
9
|
+
name?: string;
|
|
10
|
+
command?: string;
|
|
11
|
+
cwd?: string | null;
|
|
12
|
+
position?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function listCommands(project: string): DbProjectCommand[];
|
|
15
|
+
export declare function getCommand(id: number): DbProjectCommand | null;
|
|
16
|
+
export declare function createCommand(project: string, input: CreateCommandInput): DbProjectCommand;
|
|
17
|
+
export declare function updateCommand(id: number, input: UpdateCommandInput): DbProjectCommand | null;
|
|
18
|
+
export declare function deleteCommand(id: number): boolean;
|
|
19
|
+
/** Session ber-command_id tertentu (running instance), bila ada. */
|
|
20
|
+
export declare function getSessionByCommandId(commandId: number): DbSession | null;
|
|
21
|
+
/** Safety: null-out command_id pada session rows yang menunjuk command terhapus. */
|
|
22
|
+
export declare function clearCommandId(commandId: number): void;
|
|
23
|
+
export declare function listCommandsWithRunState(project: string): DbProjectCommandWithRunState[];
|
|
24
|
+
export declare function getCommandWithRunState(id: number): DbProjectCommandWithRunState | null;
|
|
25
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/db/commands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKhE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAM9D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,gBAAgB,CAkB1F;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,IAAI,CA8B5F;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMzE;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGtD;AAcD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,4BAA4B,EAAE,CAExF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,4BAA4B,GAAG,IAAI,CAItF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { getDatabase } from './index.js';
|
|
2
|
+
export function listCommands(project) {
|
|
3
|
+
const db = getDatabase();
|
|
4
|
+
return db
|
|
5
|
+
.prepare('SELECT * FROM project_commands WHERE project = ? ORDER BY position, id')
|
|
6
|
+
.all(project);
|
|
7
|
+
}
|
|
8
|
+
export function getCommand(id) {
|
|
9
|
+
const db = getDatabase();
|
|
10
|
+
const row = db.prepare('SELECT * FROM project_commands WHERE id = ?').get(id);
|
|
11
|
+
return row ?? null;
|
|
12
|
+
}
|
|
13
|
+
export function createCommand(project, input) {
|
|
14
|
+
const db = getDatabase();
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const info = db
|
|
17
|
+
.prepare(`INSERT INTO project_commands (project, name, command, cwd, position, created_at, updated_at)
|
|
18
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
19
|
+
.run(project, input.name, input.command, input.cwd ?? null, input.position ?? 0, now, now);
|
|
20
|
+
return getCommand(info.lastInsertRowid);
|
|
21
|
+
}
|
|
22
|
+
export function updateCommand(id, input) {
|
|
23
|
+
const db = getDatabase();
|
|
24
|
+
const existing = getCommand(id);
|
|
25
|
+
if (!existing)
|
|
26
|
+
return null;
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
// Build SET clause dinamis: field undefined (tidak di-body) dilewati, null/string
|
|
29
|
+
// ditulis apa adanya. COALESCE sebelumnya membuat cwd=null tidak bisa dikosongkan.
|
|
30
|
+
const sets = [];
|
|
31
|
+
const vals = [];
|
|
32
|
+
if (input.name !== undefined) {
|
|
33
|
+
sets.push('name = ?');
|
|
34
|
+
vals.push(input.name);
|
|
35
|
+
}
|
|
36
|
+
if (input.command !== undefined) {
|
|
37
|
+
sets.push('command = ?');
|
|
38
|
+
vals.push(input.command);
|
|
39
|
+
}
|
|
40
|
+
if (input.cwd !== undefined) {
|
|
41
|
+
sets.push('cwd = ?');
|
|
42
|
+
vals.push(input.cwd ?? null);
|
|
43
|
+
}
|
|
44
|
+
if (input.position !== undefined) {
|
|
45
|
+
sets.push('position = ?');
|
|
46
|
+
vals.push(input.position);
|
|
47
|
+
}
|
|
48
|
+
if (sets.length === 0)
|
|
49
|
+
return getCommand(id);
|
|
50
|
+
sets.push('updated_at = ?');
|
|
51
|
+
vals.push(now, id);
|
|
52
|
+
db.prepare(`UPDATE project_commands SET ${sets.join(', ')} WHERE id = ?`).run(...vals);
|
|
53
|
+
return getCommand(id);
|
|
54
|
+
}
|
|
55
|
+
export function deleteCommand(id) {
|
|
56
|
+
const db = getDatabase();
|
|
57
|
+
const result = db.prepare('DELETE FROM project_commands WHERE id = ?').run(id);
|
|
58
|
+
return result.changes > 0;
|
|
59
|
+
}
|
|
60
|
+
/** Session ber-command_id tertentu (running instance), bila ada. */
|
|
61
|
+
export function getSessionByCommandId(commandId) {
|
|
62
|
+
const db = getDatabase();
|
|
63
|
+
const row = db
|
|
64
|
+
.prepare('SELECT * FROM sessions WHERE command_id = ? AND archived_at IS NULL')
|
|
65
|
+
.get(commandId);
|
|
66
|
+
return row ?? null;
|
|
67
|
+
}
|
|
68
|
+
/** Safety: null-out command_id pada session rows yang menunjuk command terhapus. */
|
|
69
|
+
export function clearCommandId(commandId) {
|
|
70
|
+
const db = getDatabase();
|
|
71
|
+
db.prepare('UPDATE sessions SET command_id = NULL WHERE command_id = ?').run(commandId);
|
|
72
|
+
}
|
|
73
|
+
function withRunState(cmd) {
|
|
74
|
+
const session = getSessionByCommandId(cmd.id);
|
|
75
|
+
return {
|
|
76
|
+
...cmd,
|
|
77
|
+
runState: {
|
|
78
|
+
sessionName: session?.name ?? null,
|
|
79
|
+
status: session?.status ?? null,
|
|
80
|
+
lastActivity: session?.last_activity ?? null,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function listCommandsWithRunState(project) {
|
|
85
|
+
return listCommands(project).map(withRunState);
|
|
86
|
+
}
|
|
87
|
+
export function getCommandWithRunState(id) {
|
|
88
|
+
const cmd = getCommand(id);
|
|
89
|
+
if (!cmd)
|
|
90
|
+
return null;
|
|
91
|
+
return withRunState(cmd);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/db/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { RETENTION_CONFIG } from './schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get or create the database instance
|
|
5
|
+
*/
|
|
6
|
+
export declare function getDatabase(): Database.Database;
|
|
7
|
+
/**
|
|
8
|
+
* Initialize the database
|
|
9
|
+
* - Creates data directory if missing
|
|
10
|
+
* - Opens/creates database file
|
|
11
|
+
* - Runs migrations
|
|
12
|
+
* - Sets WAL mode for better performance
|
|
13
|
+
*/
|
|
14
|
+
export declare function initDatabase(dbPath?: string): Database.Database;
|
|
15
|
+
/**
|
|
16
|
+
* Create an in-memory database for testing
|
|
17
|
+
*/
|
|
18
|
+
export declare function initTestDatabase(): Database.Database;
|
|
19
|
+
/**
|
|
20
|
+
* Close the database connection
|
|
21
|
+
*/
|
|
22
|
+
export declare function closeDatabase(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Get database statistics for debugging
|
|
25
|
+
*/
|
|
26
|
+
export declare function getDatabaseStats(): {
|
|
27
|
+
sessions: number;
|
|
28
|
+
};
|
|
29
|
+
export { RETENTION_CONFIG };
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,OAAO,EAAqC,gBAAgB,EAAgB,MAAM,aAAa,CAAC;AAUhG;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,QAAQ,CAK/C;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAyB/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAAC,QAAQ,CAIpD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAMpC;AAuVD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAUA;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|