episoda 0.2.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.
- package/dist/commands/auth.d.ts +22 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +384 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/dev.d.ts +20 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +305 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +17 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +81 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/core/auth.d.ts +26 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +113 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/command-protocol.d.ts +262 -0
- package/dist/core/command-protocol.d.ts.map +1 -0
- package/dist/core/command-protocol.js +13 -0
- package/dist/core/command-protocol.js.map +1 -0
- package/dist/core/connection-manager.d.ts +58 -0
- package/dist/core/connection-manager.d.ts.map +1 -0
- package/dist/core/connection-manager.js +215 -0
- package/dist/core/connection-manager.js.map +1 -0
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +55 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/git-executor.d.ts +157 -0
- package/dist/core/git-executor.d.ts.map +1 -0
- package/dist/core/git-executor.js +1605 -0
- package/dist/core/git-executor.js.map +1 -0
- package/dist/core/git-parser.d.ts +40 -0
- package/dist/core/git-parser.d.ts.map +1 -0
- package/dist/core/git-parser.js +194 -0
- package/dist/core/git-parser.js.map +1 -0
- package/dist/core/git-validator.d.ts +42 -0
- package/dist/core/git-validator.d.ts.map +1 -0
- package/dist/core/git-validator.js +102 -0
- package/dist/core/git-validator.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +41 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +9 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +19 -0
- package/dist/core/version.js.map +1 -0
- package/dist/core/websocket-client.d.ts +122 -0
- package/dist/core/websocket-client.d.ts.map +1 -0
- package/dist/core/websocket-client.js +438 -0
- package/dist/core/websocket-client.js.map +1 -0
- package/dist/daemon/daemon-manager.d.ts +71 -0
- package/dist/daemon/daemon-manager.d.ts.map +1 -0
- package/dist/daemon/daemon-manager.js +289 -0
- package/dist/daemon/daemon-manager.js.map +1 -0
- package/dist/daemon/daemon-process.d.ts +13 -0
- package/dist/daemon/daemon-process.d.ts.map +1 -0
- package/dist/daemon/daemon-process.js +608 -0
- package/dist/daemon/daemon-process.js.map +1 -0
- package/dist/daemon/machine-id.d.ts +36 -0
- package/dist/daemon/machine-id.d.ts.map +1 -0
- package/dist/daemon/machine-id.js +195 -0
- package/dist/daemon/machine-id.js.map +1 -0
- package/dist/daemon/project-tracker.d.ts +92 -0
- package/dist/daemon/project-tracker.d.ts.map +1 -0
- package/dist/daemon/project-tracker.js +259 -0
- package/dist/daemon/project-tracker.js.map +1 -0
- package/dist/dev-wrapper.d.ts +88 -0
- package/dist/dev-wrapper.d.ts.map +1 -0
- package/dist/dev-wrapper.js +288 -0
- package/dist/dev-wrapper.js.map +1 -0
- package/dist/framework-detector.d.ts +29 -0
- package/dist/framework-detector.d.ts.map +1 -0
- package/dist/framework-detector.js +276 -0
- package/dist/framework-detector.js.map +1 -0
- package/dist/git-helpers/git-credential-helper.d.ts +29 -0
- package/dist/git-helpers/git-credential-helper.d.ts.map +1 -0
- package/dist/git-helpers/git-credential-helper.js +349 -0
- package/dist/git-helpers/git-credential-helper.js.map +1 -0
- package/dist/hooks/post-checkout +296 -0
- package/dist/hooks/pre-commit +139 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/ipc-client.d.ts +95 -0
- package/dist/ipc/ipc-client.d.ts.map +1 -0
- package/dist/ipc/ipc-client.js +204 -0
- package/dist/ipc/ipc-client.js.map +1 -0
- package/dist/ipc/ipc-server.d.ts +55 -0
- package/dist/ipc/ipc-server.d.ts.map +1 -0
- package/dist/ipc/ipc-server.js +177 -0
- package/dist/ipc/ipc-server.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +129 -0
- package/dist/output.js.map +1 -0
- package/dist/utils/port-check.d.ts +15 -0
- package/dist/utils/port-check.d.ts.map +1 -0
- package/dist/utils/port-check.js +79 -0
- package/dist/utils/port-check.js.map +1 -0
- package/dist/utils/update-checker.d.ts +23 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +95 -0
- package/dist/utils/update-checker.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Authentication utilities
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getConfigDir = getConfigDir;
|
|
40
|
+
exports.getConfigPath = getConfigPath;
|
|
41
|
+
exports.loadConfig = loadConfig;
|
|
42
|
+
exports.saveConfig = saveConfig;
|
|
43
|
+
exports.validateToken = validateToken;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
const DEFAULT_CONFIG_FILE = 'config.json';
|
|
48
|
+
/**
|
|
49
|
+
* Get the config directory path
|
|
50
|
+
* Supports EPISODA_CONFIG_DIR env var for running multiple environments
|
|
51
|
+
*/
|
|
52
|
+
function getConfigDir() {
|
|
53
|
+
return process.env.EPISODA_CONFIG_DIR || path.join(os.homedir(), '.episoda');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get the full path to the config file
|
|
57
|
+
*/
|
|
58
|
+
function getConfigPath(configPath) {
|
|
59
|
+
if (configPath) {
|
|
60
|
+
return configPath;
|
|
61
|
+
}
|
|
62
|
+
return path.join(getConfigDir(), DEFAULT_CONFIG_FILE);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Ensure the config directory exists
|
|
66
|
+
*/
|
|
67
|
+
function ensureConfigDir(configPath) {
|
|
68
|
+
const dir = path.dirname(configPath);
|
|
69
|
+
if (!fs.existsSync(dir)) {
|
|
70
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Load configuration from .episoda/config.json
|
|
75
|
+
*/
|
|
76
|
+
async function loadConfig(configPath) {
|
|
77
|
+
const fullPath = getConfigPath(configPath);
|
|
78
|
+
if (!fs.existsSync(fullPath)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
83
|
+
const config = JSON.parse(content);
|
|
84
|
+
return config;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error('Error loading config:', error);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Save configuration to .episoda/config.json
|
|
93
|
+
*/
|
|
94
|
+
async function saveConfig(config, configPath) {
|
|
95
|
+
const fullPath = getConfigPath(configPath);
|
|
96
|
+
ensureConfigDir(fullPath);
|
|
97
|
+
try {
|
|
98
|
+
const content = JSON.stringify(config, null, 2);
|
|
99
|
+
fs.writeFileSync(fullPath, content, { mode: 0o600 });
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw new Error(`Failed to save config: ${error instanceof Error ? error.message : String(error)}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Validate an access token
|
|
107
|
+
*/
|
|
108
|
+
async function validateToken(token) {
|
|
109
|
+
// For now, just check if token exists and is non-empty
|
|
110
|
+
// In the future, we can make an API call to validate
|
|
111
|
+
return Boolean(token && token.length > 0);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaH,oCAEC;AAKD,sCAKC;AAeD,gCAeC;AAKD,gCAUC;AAKD,sCAIC;AA7ED,uCAAwB;AACxB,2CAA4B;AAC5B,uCAAwB;AAGxB,MAAM,mBAAmB,GAAG,aAAa,CAAA;AAEzC;;;GAGG;AACH,SAAgB,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;AAC9E,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,UAAmB;IAC/C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAA;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,mBAAmB,CAAC,CAAA;AACvD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACrD,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IAE1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAkB,CAAA;QACnD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAA;QAC7C,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,MAAqB,EAAE,UAAmB;IACzE,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IAC1C,eAAe,CAAC,QAAQ,CAAC,CAAA;IAEzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC/C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACrG,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,uDAAuD;IACvD,qDAAqD;IACrD,OAAO,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC3C,CAAC"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Protocol Types for Episoda Local Development
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: These types are LOCKED for Phase 2 concurrent development.
|
|
5
|
+
* DO NOT modify after EP589-1 is complete without coordinating with all agents.
|
|
6
|
+
*
|
|
7
|
+
* These types are interface-agnostic and used by both:
|
|
8
|
+
* - @episoda/cli (current)
|
|
9
|
+
* - @episoda/mcp-local-dev (future)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Git command types supported by GitExecutor
|
|
13
|
+
*/
|
|
14
|
+
export type GitCommand = {
|
|
15
|
+
action: 'checkout';
|
|
16
|
+
branch: string;
|
|
17
|
+
create?: boolean;
|
|
18
|
+
} | {
|
|
19
|
+
action: 'create_branch';
|
|
20
|
+
branch: string;
|
|
21
|
+
from?: string;
|
|
22
|
+
} | {
|
|
23
|
+
action: 'commit';
|
|
24
|
+
message: string;
|
|
25
|
+
files?: string[];
|
|
26
|
+
} | {
|
|
27
|
+
action: 'push';
|
|
28
|
+
branch: string;
|
|
29
|
+
setUpstream?: boolean;
|
|
30
|
+
force?: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
action: 'status';
|
|
33
|
+
} | {
|
|
34
|
+
action: 'pull';
|
|
35
|
+
branch?: string;
|
|
36
|
+
} | {
|
|
37
|
+
action: 'delete_branch';
|
|
38
|
+
branch: string;
|
|
39
|
+
force?: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
action: 'branch_exists';
|
|
42
|
+
branch: string;
|
|
43
|
+
} | {
|
|
44
|
+
action: 'branch_has_commits';
|
|
45
|
+
branch: string;
|
|
46
|
+
baseBranch?: string;
|
|
47
|
+
} | {
|
|
48
|
+
action: 'main_branch_check';
|
|
49
|
+
} | {
|
|
50
|
+
action: 'get_commits';
|
|
51
|
+
branch: string;
|
|
52
|
+
limit?: number;
|
|
53
|
+
baseBranch?: string;
|
|
54
|
+
} | {
|
|
55
|
+
action: 'stash';
|
|
56
|
+
operation: 'push' | 'pop' | 'drop' | 'list';
|
|
57
|
+
message?: string;
|
|
58
|
+
includeUntracked?: boolean;
|
|
59
|
+
} | {
|
|
60
|
+
action: 'reset';
|
|
61
|
+
mode: 'soft' | 'mixed' | 'hard';
|
|
62
|
+
target?: string;
|
|
63
|
+
} | {
|
|
64
|
+
action: 'merge';
|
|
65
|
+
branch: string;
|
|
66
|
+
strategy?: 'ours' | 'theirs';
|
|
67
|
+
noEdit?: boolean;
|
|
68
|
+
abort?: boolean;
|
|
69
|
+
} | {
|
|
70
|
+
action: 'cherry_pick';
|
|
71
|
+
sha: string;
|
|
72
|
+
abort?: boolean;
|
|
73
|
+
} | {
|
|
74
|
+
action: 'clean';
|
|
75
|
+
force?: boolean;
|
|
76
|
+
directories?: boolean;
|
|
77
|
+
} | {
|
|
78
|
+
action: 'add';
|
|
79
|
+
files?: string[];
|
|
80
|
+
all?: boolean;
|
|
81
|
+
} | {
|
|
82
|
+
action: 'fetch';
|
|
83
|
+
remote?: string;
|
|
84
|
+
branch?: string;
|
|
85
|
+
} | {
|
|
86
|
+
action: 'move_to_module';
|
|
87
|
+
targetBranch: string;
|
|
88
|
+
commitShas?: string[];
|
|
89
|
+
conflictResolution?: 'ours' | 'theirs';
|
|
90
|
+
} | {
|
|
91
|
+
action: 'discard_main_changes';
|
|
92
|
+
} | {
|
|
93
|
+
action: 'sync_status';
|
|
94
|
+
branch: string;
|
|
95
|
+
} | {
|
|
96
|
+
action: 'sync_main';
|
|
97
|
+
} | {
|
|
98
|
+
action: 'rebase_branch';
|
|
99
|
+
branch: string;
|
|
100
|
+
} | {
|
|
101
|
+
action: 'rebase_abort';
|
|
102
|
+
} | {
|
|
103
|
+
action: 'rebase_continue';
|
|
104
|
+
} | {
|
|
105
|
+
action: 'rebase_status';
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Result of executing a git command
|
|
109
|
+
* Returns structured data (not formatted strings) for interface-agnostic use
|
|
110
|
+
*/
|
|
111
|
+
export type ExecutionResult = {
|
|
112
|
+
success: boolean;
|
|
113
|
+
output?: string;
|
|
114
|
+
error?: ErrorCode;
|
|
115
|
+
details?: {
|
|
116
|
+
uncommittedFiles?: string[];
|
|
117
|
+
conflictingFiles?: string[];
|
|
118
|
+
exitCode?: number;
|
|
119
|
+
branchName?: string;
|
|
120
|
+
branchExists?: boolean;
|
|
121
|
+
isLocal?: boolean;
|
|
122
|
+
isRemote?: boolean;
|
|
123
|
+
hasCommits?: boolean;
|
|
124
|
+
currentBranch?: string;
|
|
125
|
+
localCommits?: Array<{
|
|
126
|
+
sha: string;
|
|
127
|
+
message: string;
|
|
128
|
+
author: string;
|
|
129
|
+
}>;
|
|
130
|
+
commits?: Array<{
|
|
131
|
+
sha: string;
|
|
132
|
+
message: string;
|
|
133
|
+
authorName: string;
|
|
134
|
+
authorEmail: string;
|
|
135
|
+
date: string;
|
|
136
|
+
isPushed: boolean;
|
|
137
|
+
}>;
|
|
138
|
+
stashList?: Array<{
|
|
139
|
+
index: number;
|
|
140
|
+
message: string;
|
|
141
|
+
}>;
|
|
142
|
+
mergeConflicts?: boolean;
|
|
143
|
+
cherryPickConflicts?: boolean;
|
|
144
|
+
cleanedFiles?: string[];
|
|
145
|
+
stagedFiles?: string[];
|
|
146
|
+
movedToBranch?: string;
|
|
147
|
+
cherryPickedCommits?: string[];
|
|
148
|
+
discardedFiles?: number;
|
|
149
|
+
discardedCommits?: number;
|
|
150
|
+
hasConflicts?: boolean;
|
|
151
|
+
conflictedFiles?: string[];
|
|
152
|
+
commitsBehind?: number;
|
|
153
|
+
commitsAhead?: number;
|
|
154
|
+
isBehind?: boolean;
|
|
155
|
+
isAhead?: boolean;
|
|
156
|
+
needsSync?: boolean;
|
|
157
|
+
inRebase?: boolean;
|
|
158
|
+
rebaseConflicts?: string[];
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Standardized error codes for git operations
|
|
163
|
+
* Interfaces can map these to user-friendly messages
|
|
164
|
+
*/
|
|
165
|
+
export type ErrorCode = 'GIT_NOT_INSTALLED' | 'NOT_GIT_REPO' | 'MERGE_CONFLICT' | 'REBASE_CONFLICT' | 'UNCOMMITTED_CHANGES' | 'NETWORK_ERROR' | 'AUTH_FAILURE' | 'BRANCH_NOT_FOUND' | 'BRANCH_ALREADY_EXISTS' | 'PUSH_REJECTED' | 'COMMAND_TIMEOUT' | 'UNKNOWN_ERROR';
|
|
166
|
+
/**
|
|
167
|
+
* WebSocket message types for server → CLI communication
|
|
168
|
+
*/
|
|
169
|
+
export type ServerMessage = {
|
|
170
|
+
type: 'auth_success';
|
|
171
|
+
userId: string;
|
|
172
|
+
projectId: string;
|
|
173
|
+
workspaceId: string;
|
|
174
|
+
deviceName?: string;
|
|
175
|
+
deviceId?: string;
|
|
176
|
+
flyMachineId?: string;
|
|
177
|
+
} | {
|
|
178
|
+
type: 'command';
|
|
179
|
+
id: string;
|
|
180
|
+
command: GitCommand;
|
|
181
|
+
} | {
|
|
182
|
+
type: 'ping';
|
|
183
|
+
} | {
|
|
184
|
+
type: 'error';
|
|
185
|
+
code: string;
|
|
186
|
+
message: string;
|
|
187
|
+
retryAfter?: number;
|
|
188
|
+
} | {
|
|
189
|
+
type: 'shutdown';
|
|
190
|
+
message: string;
|
|
191
|
+
reason?: 'user_requested' | 'server_restart' | 'deployment';
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* WebSocket message types for CLI → server communication
|
|
195
|
+
*/
|
|
196
|
+
export type ClientMessage = {
|
|
197
|
+
type: 'auth';
|
|
198
|
+
token: string;
|
|
199
|
+
version: string;
|
|
200
|
+
machineId?: string;
|
|
201
|
+
hostname?: string;
|
|
202
|
+
osPlatform?: string;
|
|
203
|
+
osArch?: string;
|
|
204
|
+
daemonPid?: number;
|
|
205
|
+
} | {
|
|
206
|
+
type: 'pong';
|
|
207
|
+
} | {
|
|
208
|
+
type: 'result';
|
|
209
|
+
commandId: string;
|
|
210
|
+
result: ExecutionResult;
|
|
211
|
+
} | {
|
|
212
|
+
type: 'status';
|
|
213
|
+
connected: boolean;
|
|
214
|
+
workingDirectory?: string;
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* CLI connection status
|
|
218
|
+
*/
|
|
219
|
+
export type ConnectionStatus = {
|
|
220
|
+
connected: boolean;
|
|
221
|
+
projectId?: string;
|
|
222
|
+
connectedAt?: Date;
|
|
223
|
+
lastActivity?: Date;
|
|
224
|
+
cliVersion?: string;
|
|
225
|
+
workingDirectory?: string;
|
|
226
|
+
machineId?: string;
|
|
227
|
+
deviceName?: string;
|
|
228
|
+
hostname?: string;
|
|
229
|
+
osPlatform?: string;
|
|
230
|
+
osArch?: string;
|
|
231
|
+
userId?: string;
|
|
232
|
+
lastPingAt?: Date;
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Configuration stored in .episoda/config.json
|
|
236
|
+
*/
|
|
237
|
+
export type EpisodaConfig = {
|
|
238
|
+
project_id: string;
|
|
239
|
+
user_id: string;
|
|
240
|
+
workspace_id: string;
|
|
241
|
+
access_token: string;
|
|
242
|
+
refresh_token?: string;
|
|
243
|
+
expires_at?: number;
|
|
244
|
+
api_url: string;
|
|
245
|
+
cli_version?: string;
|
|
246
|
+
device_id?: string;
|
|
247
|
+
machine_id?: string;
|
|
248
|
+
project_settings?: {
|
|
249
|
+
local_project_path?: string;
|
|
250
|
+
local_server_url?: string;
|
|
251
|
+
cached_at: number;
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Command execution options
|
|
256
|
+
*/
|
|
257
|
+
export type ExecutionOptions = {
|
|
258
|
+
timeout?: number;
|
|
259
|
+
cwd?: string;
|
|
260
|
+
githubToken?: string;
|
|
261
|
+
};
|
|
262
|
+
//# sourceMappingURL=command-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-protocol.d.ts","sourceRoot":"","sources":["../../src/core/command-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Command Protocol Types for Episoda Local Development
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: These types are LOCKED for Phase 2 concurrent development.
|
|
6
|
+
* DO NOT modify after EP589-1 is complete without coordinating with all agents.
|
|
7
|
+
*
|
|
8
|
+
* These types are interface-agnostic and used by both:
|
|
9
|
+
* - @episoda/cli (current)
|
|
10
|
+
* - @episoda/mcp-local-dev (future)
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
//# sourceMappingURL=command-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-protocol.js","sourceRoot":"","sources":["../../src/core/command-protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Manager for CLI WebSocket tracking (Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Simpler than the full Git command WebSocket client.
|
|
5
|
+
* Focuses only on maintaining connection status via heartbeats.
|
|
6
|
+
*/
|
|
7
|
+
export interface ConnectionConfig {
|
|
8
|
+
apiUrl: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
workspaceId: string;
|
|
12
|
+
cliVersion: string;
|
|
13
|
+
workingDirectory: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class ConnectionManager {
|
|
16
|
+
private ws;
|
|
17
|
+
private pingInterval;
|
|
18
|
+
private reconnectTimeout;
|
|
19
|
+
private config;
|
|
20
|
+
private connectionId;
|
|
21
|
+
private isIntentionalClose;
|
|
22
|
+
private reconnectAttempts;
|
|
23
|
+
private maxReconnectAttempts;
|
|
24
|
+
constructor(config: ConnectionConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Connect to the WebSocket server
|
|
27
|
+
*/
|
|
28
|
+
connect(): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Disconnect from the server
|
|
31
|
+
*/
|
|
32
|
+
disconnect(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Send a message to the server
|
|
35
|
+
*/
|
|
36
|
+
private send;
|
|
37
|
+
/**
|
|
38
|
+
* Start sending heartbeat pings
|
|
39
|
+
*/
|
|
40
|
+
private startHeartbeat;
|
|
41
|
+
/**
|
|
42
|
+
* Stop heartbeat
|
|
43
|
+
*/
|
|
44
|
+
private stopHeartbeat;
|
|
45
|
+
/**
|
|
46
|
+
* Schedule reconnection with exponential backoff
|
|
47
|
+
*/
|
|
48
|
+
private scheduleReconnect;
|
|
49
|
+
/**
|
|
50
|
+
* Clear reconnect timeout
|
|
51
|
+
*/
|
|
52
|
+
private clearReconnectTimeout;
|
|
53
|
+
/**
|
|
54
|
+
* Check if connected
|
|
55
|
+
*/
|
|
56
|
+
isConnected(): boolean;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=connection-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/core/connection-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAM;gBAEtB,MAAM,EAAE,gBAAgB;IAIpC;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAiF1B;;OAEG;IACH,UAAU,IAAI,IAAI;IAelB;;OAEG;IACH,OAAO,CAAC,IAAI;IAMZ;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,WAAW,IAAI,OAAO;CAGvB"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Connection Manager for CLI WebSocket tracking (Phase 2)
|
|
4
|
+
*
|
|
5
|
+
* Simpler than the full Git command WebSocket client.
|
|
6
|
+
* Focuses only on maintaining connection status via heartbeats.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.ConnectionManager = void 0;
|
|
46
|
+
const ws_1 = __importDefault(require("ws"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
class ConnectionManager {
|
|
49
|
+
constructor(config) {
|
|
50
|
+
this.ws = null;
|
|
51
|
+
this.pingInterval = null;
|
|
52
|
+
this.reconnectTimeout = null;
|
|
53
|
+
this.connectionId = null;
|
|
54
|
+
this.isIntentionalClose = false;
|
|
55
|
+
this.reconnectAttempts = 0;
|
|
56
|
+
this.maxReconnectAttempts = 10;
|
|
57
|
+
this.config = config;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Connect to the WebSocket server
|
|
61
|
+
*/
|
|
62
|
+
connect() {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
try {
|
|
65
|
+
// Convert HTTP to WebSocket URL
|
|
66
|
+
const wsUrl = this.config.apiUrl
|
|
67
|
+
.replace('http://', 'ws://')
|
|
68
|
+
.replace('https://', 'wss://');
|
|
69
|
+
const url = `${wsUrl}/api/cli/ws`;
|
|
70
|
+
console.log(`[Connection] Connecting to ${url}`);
|
|
71
|
+
this.ws = new ws_1.default(url);
|
|
72
|
+
this.isIntentionalClose = false;
|
|
73
|
+
this.ws.on('open', () => {
|
|
74
|
+
console.log('[Connection] WebSocket connected');
|
|
75
|
+
this.reconnectAttempts = 0;
|
|
76
|
+
// Send connect message
|
|
77
|
+
this.send({
|
|
78
|
+
type: 'connect',
|
|
79
|
+
projectId: this.config.projectId,
|
|
80
|
+
userId: this.config.userId,
|
|
81
|
+
workspaceId: this.config.workspaceId,
|
|
82
|
+
cliVersion: this.config.cliVersion,
|
|
83
|
+
workingDirectory: this.config.workingDirectory,
|
|
84
|
+
osPlatform: os.platform(),
|
|
85
|
+
osArch: os.arch(),
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
this.ws.on('message', (data) => {
|
|
89
|
+
try {
|
|
90
|
+
const message = JSON.parse(data.toString());
|
|
91
|
+
switch (message.type) {
|
|
92
|
+
case 'connected':
|
|
93
|
+
this.connectionId = message.connectionId;
|
|
94
|
+
console.log(`[Connection] Connected with ID: ${this.connectionId}`);
|
|
95
|
+
this.startHeartbeat();
|
|
96
|
+
if (this.connectionId) {
|
|
97
|
+
resolve(this.connectionId);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
reject(new Error('Connection ID not received from server'));
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case 'pong':
|
|
104
|
+
// Heartbeat acknowledged
|
|
105
|
+
break;
|
|
106
|
+
case 'error':
|
|
107
|
+
console.error(`[Connection] Server error: ${message.message}`);
|
|
108
|
+
reject(new Error(message.message));
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('[Connection] Failed to parse message:', error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
this.ws.on('close', (code, reason) => {
|
|
117
|
+
console.log(`[Connection] WebSocket closed: ${code} ${reason.toString()}`);
|
|
118
|
+
this.stopHeartbeat();
|
|
119
|
+
if (!this.isIntentionalClose && this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
120
|
+
this.scheduleReconnect();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
this.ws.on('error', (error) => {
|
|
124
|
+
console.error('[Connection] WebSocket error:', error);
|
|
125
|
+
reject(error);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
reject(error);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Disconnect from the server
|
|
135
|
+
*/
|
|
136
|
+
disconnect() {
|
|
137
|
+
console.log('[Connection] Disconnecting...');
|
|
138
|
+
this.isIntentionalClose = true;
|
|
139
|
+
this.stopHeartbeat();
|
|
140
|
+
this.clearReconnectTimeout();
|
|
141
|
+
if (this.ws) {
|
|
142
|
+
if (this.ws.readyState === ws_1.default.OPEN) {
|
|
143
|
+
this.send({ type: 'disconnect' });
|
|
144
|
+
}
|
|
145
|
+
this.ws.close();
|
|
146
|
+
this.ws = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Send a message to the server
|
|
151
|
+
*/
|
|
152
|
+
send(message) {
|
|
153
|
+
if (this.ws?.readyState === ws_1.default.OPEN) {
|
|
154
|
+
this.ws.send(JSON.stringify(message));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Start sending heartbeat pings
|
|
159
|
+
*/
|
|
160
|
+
startHeartbeat() {
|
|
161
|
+
this.stopHeartbeat();
|
|
162
|
+
// Send ping every 15 seconds
|
|
163
|
+
this.pingInterval = setInterval(() => {
|
|
164
|
+
this.send({
|
|
165
|
+
type: 'ping',
|
|
166
|
+
timestamp: new Date().toISOString(),
|
|
167
|
+
});
|
|
168
|
+
}, 15000);
|
|
169
|
+
// Send initial ping
|
|
170
|
+
this.send({
|
|
171
|
+
type: 'ping',
|
|
172
|
+
timestamp: new Date().toISOString(),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Stop heartbeat
|
|
177
|
+
*/
|
|
178
|
+
stopHeartbeat() {
|
|
179
|
+
if (this.pingInterval) {
|
|
180
|
+
clearInterval(this.pingInterval);
|
|
181
|
+
this.pingInterval = null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Schedule reconnection with exponential backoff
|
|
186
|
+
*/
|
|
187
|
+
scheduleReconnect() {
|
|
188
|
+
this.clearReconnectTimeout();
|
|
189
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
|
|
190
|
+
console.log(`[Connection] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts + 1}/${this.maxReconnectAttempts})`);
|
|
191
|
+
this.reconnectTimeout = setTimeout(() => {
|
|
192
|
+
this.reconnectAttempts++;
|
|
193
|
+
this.connect().catch((error) => {
|
|
194
|
+
console.error('[Connection] Reconnection failed:', error);
|
|
195
|
+
});
|
|
196
|
+
}, delay);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Clear reconnect timeout
|
|
200
|
+
*/
|
|
201
|
+
clearReconnectTimeout() {
|
|
202
|
+
if (this.reconnectTimeout) {
|
|
203
|
+
clearTimeout(this.reconnectTimeout);
|
|
204
|
+
this.reconnectTimeout = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if connected
|
|
209
|
+
*/
|
|
210
|
+
isConnected() {
|
|
211
|
+
return this.ws?.readyState === ws_1.default.OPEN && this.connectionId !== null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.ConnectionManager = ConnectionManager;
|
|
215
|
+
//# sourceMappingURL=connection-manager.js.map
|