@chatroomcp/chatroom 0.2.1 → 0.2.3
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 +5 -3
- package/dist/app/application.d.ts +0 -1
- package/dist/app/application.js +2 -0
- package/dist/app/event-bus.d.ts +0 -2
- package/dist/app/event-bus.js +0 -1
- package/dist/app/external-access-registry.d.ts +0 -1
- package/dist/app/external-access-registry.js +0 -1
- package/dist/app/lifecycle.d.ts +0 -1
- package/dist/auth/auth-service.js +0 -4
- package/dist/auth/ingress-policy.d.ts +0 -1
- package/dist/auth/ingress-policy.js +0 -1
- package/dist/cli/run-cli.js +0 -1
- package/dist/config/types.d.ts +0 -1
- package/dist/core/auth/repository.d.ts +0 -23
- package/dist/core/auth/repository.js +0 -6
- package/dist/core/errors/chatroom-error.d.ts +0 -15
- package/dist/core/errors/chatroom-error.js +0 -15
- package/dist/core/operations/bounded-value.d.ts +0 -1
- package/dist/core/operations/bounded-value.js +26 -10
- package/dist/core/operations/redactor.js +0 -1
- package/dist/core/operations/repository.d.ts +0 -1
- package/dist/core/operations/types.d.ts +0 -4
- package/dist/core/operations/types.js +0 -2
- package/dist/infrastructure/database/app-database.js +4 -97
- package/dist/infrastructure/database/migrations.d.ts +2 -0
- package/dist/infrastructure/database/migrations.js +44 -0
- package/dist/infrastructure/database/operation-repository.js +3 -9
- package/dist/infrastructure/database/schema.d.ts +2 -0
- package/dist/infrastructure/database/schema.js +85 -0
- package/dist/infrastructure/http/http-server.js +0 -1
- package/dist/mcp/server/create-mcp-server.js +3 -3
- package/dist/mcp/server/plugin-mcp-registrar.d.ts +0 -2
- package/dist/mcp/server/plugin-mcp-registrar.js +0 -4
- package/dist/mcp/server/tool-support.d.ts +0 -61
- package/dist/mcp/server/tool-support.js +0 -54
- package/dist/native/linux/chatroom-computer-helper +0 -0
- package/dist/native/macos/ChatRoomComputerHelper.app/Contents/Info.plist +1 -1
- package/dist/native/macos/ChatRoomComputerHelper.app/Contents/MacOS/chatroom-computer-helper +0 -0
- package/dist/native/windows/chatroom-computer-helper.exe +0 -0
- package/dist/operations/operation-log.d.ts +0 -3
- package/dist/operations/operation-log.js +0 -15
- package/dist/plugins/cloud/api-client.js +1 -0
- package/dist/plugins/cloud/controller.d.ts +2 -0
- package/dist/plugins/cloud/controller.js +28 -5
- package/dist/plugins/cloud/tunnel-client.js +0 -4
- package/dist/plugins/git/git-service.d.ts +33 -0
- package/dist/plugins/git/git-service.js +414 -0
- package/dist/plugins/git/plugin.d.ts +4 -0
- package/dist/plugins/git/plugin.js +12 -0
- package/dist/plugins/git/types.d.ts +32 -0
- package/dist/plugins/process/backend.d.ts +0 -1
- package/dist/plugins/process/head-tail-buffer.d.ts +0 -1
- package/dist/plugins/process/infrastructure/pipe-process-backend.js +0 -1
- package/dist/plugins/process/infrastructure/pty-process-backend.js +1 -4
- package/dist/plugins/process/process-supervisor.js +10 -23
- package/dist/plugins/process/types.d.ts +0 -5
- package/dist/plugins/types.d.ts +0 -1
- package/dist/plugins/web/api-types.d.ts +3 -7
- package/dist/plugins/web/http/api-router.d.ts +0 -1
- package/dist/plugins/web/http/api-router.js +2 -4
- package/dist/plugins/web/http/git-api-router.d.ts +3 -0
- package/dist/plugins/web/http/git-api-router.js +98 -0
- package/dist/plugins/web/http/workspace-api-router.js +51 -37
- package/dist/plugins/web/plugin.js +4 -6
- package/dist/plugins/web/runtime.d.ts +5 -27
- package/dist/plugins/web/runtime.js +3 -42
- package/dist/plugins/workspace/mcp.js +20 -135
- package/dist/plugins/workspace/metadata.d.ts +6 -0
- package/dist/plugins/workspace/metadata.js +115 -0
- package/dist/plugins/workspace/plugin.d.ts +2 -8
- package/dist/plugins/workspace/plugin.js +8 -20
- package/dist/plugins/workspace/types.d.ts +23 -0
- package/dist/plugins/workspace/{infrastructure/workspace-fs.d.ts → workspace-fs.d.ts} +4 -14
- package/dist/plugins/workspace/workspace-fs.js +200 -0
- package/dist/plugins/workspace/workspace-service.d.ts +11 -42
- package/dist/plugins/workspace/workspace-service.js +103 -302
- package/dist/presentation/http/http-utils.d.ts +0 -1
- package/dist/presentation/http/oauth-router.d.ts +0 -1
- package/dist/presentation/http/oauth-router.js +0 -1
- package/dist/web/assets/index-CEzdY5mz.js +27 -0
- package/dist/web/assets/index-D_mpjwCG.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +4 -3
- package/dist/plugins/workspace/domain/filesystem.d.ts +0 -25
- package/dist/plugins/workspace/domain/git.d.ts +0 -7
- package/dist/plugins/workspace/domain/repository.d.ts +0 -16
- package/dist/plugins/workspace/domain/repository.js +0 -1
- package/dist/plugins/workspace/domain/review.d.ts +0 -28
- package/dist/plugins/workspace/domain/review.js +0 -1
- package/dist/plugins/workspace/domain/workspace.d.ts +0 -23
- package/dist/plugins/workspace/domain/workspace.js +0 -1
- package/dist/plugins/workspace/git/git-command-runner.d.ts +0 -6
- package/dist/plugins/workspace/git/git-command-runner.js +0 -15
- package/dist/plugins/workspace/git/git-service.d.ts +0 -14
- package/dist/plugins/workspace/git/git-service.js +0 -107
- package/dist/plugins/workspace/git/git-snapshot-service.d.ts +0 -33
- package/dist/plugins/workspace/git/git-snapshot-service.js +0 -352
- package/dist/plugins/workspace/infrastructure/workspace-fs.js +0 -340
- package/dist/plugins/workspace/infrastructure/workspace-repository.d.ts +0 -12
- package/dist/plugins/workspace/infrastructure/workspace-repository.js +0 -51
- package/dist/plugins/workspace/workspace-helpers.d.ts +0 -9
- package/dist/plugins/workspace/workspace-helpers.js +0 -67
- package/dist/plugins/workspace/worktree-review-service.d.ts +0 -16
- package/dist/plugins/workspace/worktree-review-service.js +0 -51
- package/dist/web/assets/index-B4vO7wVS.css +0 -1
- package/dist/web/assets/index-BU7LCgKB.js +0 -26
- /package/dist/plugins/{workspace/domain/filesystem.js → git/types.js} +0 -0
- /package/dist/plugins/workspace/{domain/git.js → types.js} +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const DATABASE_SCHEMA_VERSION = 1;
|
|
2
|
+
export const DATABASE_SCHEMA = `
|
|
3
|
+
CREATE TABLE IF NOT EXISTS operations (
|
|
4
|
+
operation_id TEXT PRIMARY KEY,
|
|
5
|
+
plugin_id TEXT NOT NULL,
|
|
6
|
+
source TEXT NOT NULL,
|
|
7
|
+
action TEXT NOT NULL,
|
|
8
|
+
status TEXT NOT NULL,
|
|
9
|
+
process_id TEXT,
|
|
10
|
+
input_json TEXT NOT NULL,
|
|
11
|
+
output_json TEXT NOT NULL,
|
|
12
|
+
error_json TEXT NOT NULL,
|
|
13
|
+
input_truncated INTEGER NOT NULL DEFAULT 0,
|
|
14
|
+
output_truncated INTEGER NOT NULL DEFAULT 0,
|
|
15
|
+
started_at TEXT NOT NULL,
|
|
16
|
+
finished_at TEXT,
|
|
17
|
+
duration_ms INTEGER
|
|
18
|
+
);
|
|
19
|
+
CREATE INDEX IF NOT EXISTS operations_started_idx ON operations(started_at DESC);
|
|
20
|
+
CREATE INDEX IF NOT EXISTS operations_plugin_idx ON operations(plugin_id, started_at DESC);
|
|
21
|
+
CREATE INDEX IF NOT EXISTS operations_status_idx ON operations(status, started_at DESC);
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS oauth_clients (
|
|
24
|
+
client_id TEXT PRIMARY KEY,
|
|
25
|
+
name TEXT NOT NULL,
|
|
26
|
+
redirect_uris_json TEXT NOT NULL,
|
|
27
|
+
created_at TEXT NOT NULL
|
|
28
|
+
);
|
|
29
|
+
CREATE TABLE IF NOT EXISTS oauth_codes (
|
|
30
|
+
code_hash TEXT PRIMARY KEY,
|
|
31
|
+
client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
32
|
+
redirect_uri TEXT NOT NULL,
|
|
33
|
+
code_challenge TEXT NOT NULL,
|
|
34
|
+
scope TEXT NOT NULL,
|
|
35
|
+
expires_at TEXT NOT NULL,
|
|
36
|
+
used_at TEXT
|
|
37
|
+
);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS oauth_code_expiry_idx ON oauth_codes(expires_at);
|
|
39
|
+
CREATE TABLE IF NOT EXISTS oauth_tokens (
|
|
40
|
+
token_hash TEXT PRIMARY KEY,
|
|
41
|
+
client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
42
|
+
scope TEXT NOT NULL,
|
|
43
|
+
expires_at TEXT NOT NULL,
|
|
44
|
+
revoked_at TEXT,
|
|
45
|
+
created_at TEXT NOT NULL
|
|
46
|
+
);
|
|
47
|
+
CREATE INDEX IF NOT EXISTS oauth_token_expiry_idx ON oauth_tokens(expires_at);
|
|
48
|
+
CREATE TABLE IF NOT EXISTS oauth_refresh_tokens (
|
|
49
|
+
token_hash TEXT PRIMARY KEY,
|
|
50
|
+
client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
51
|
+
scope TEXT NOT NULL,
|
|
52
|
+
expires_at TEXT NOT NULL,
|
|
53
|
+
revoked_at TEXT,
|
|
54
|
+
created_at TEXT NOT NULL
|
|
55
|
+
);
|
|
56
|
+
CREATE INDEX IF NOT EXISTS oauth_refresh_expiry_idx ON oauth_refresh_tokens(expires_at);
|
|
57
|
+
|
|
58
|
+
CREATE TABLE IF NOT EXISTS web_sessions (
|
|
59
|
+
token_hash TEXT PRIMARY KEY,
|
|
60
|
+
expires_at TEXT NOT NULL,
|
|
61
|
+
created_at TEXT NOT NULL
|
|
62
|
+
);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS web_session_expiry_idx ON web_sessions(expires_at);
|
|
64
|
+
|
|
65
|
+
CREATE TABLE IF NOT EXISTS passkeys (
|
|
66
|
+
credential_id TEXT PRIMARY KEY,
|
|
67
|
+
public_key BLOB NOT NULL,
|
|
68
|
+
counter INTEGER NOT NULL,
|
|
69
|
+
transports_json TEXT NOT NULL,
|
|
70
|
+
device_type TEXT NOT NULL CHECK(device_type IN ('singleDevice','multiDevice')),
|
|
71
|
+
backed_up INTEGER NOT NULL,
|
|
72
|
+
name TEXT NOT NULL,
|
|
73
|
+
created_at TEXT NOT NULL,
|
|
74
|
+
last_used_at TEXT NOT NULL
|
|
75
|
+
);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS passkeys_last_used_idx ON passkeys(last_used_at DESC);
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS computer_settings (
|
|
79
|
+
id INTEGER PRIMARY KEY CHECK(id = 1),
|
|
80
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
81
|
+
remote_access INTEGER NOT NULL DEFAULT 1,
|
|
82
|
+
updated_at TEXT NOT NULL
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
`;
|
|
@@ -7,9 +7,9 @@ export function createChatRoomMcpHandler(plugins) {
|
|
|
7
7
|
});
|
|
8
8
|
}
|
|
9
9
|
function createServer(plugins) {
|
|
10
|
-
const server = new McpServer({
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: CHATROOM_NAME,
|
|
12
|
+
version: CHATROOM_VERSION,
|
|
13
13
|
});
|
|
14
14
|
plugins.registerMcp(server);
|
|
15
15
|
return server;
|
|
@@ -4,7 +4,6 @@ type PluginToolInput<Schema extends StandardSchemaWithJSON> = StandardSchemaWith
|
|
|
4
4
|
type PluginToolAction<Input> = string | ((input: Input) => string);
|
|
5
5
|
export interface PluginToolExecution {
|
|
6
6
|
readonly operationId: string;
|
|
7
|
-
/** Keep the operation running after the MCP handler returns. The owner must finish it later. */
|
|
8
7
|
deferCompletion(): void;
|
|
9
8
|
}
|
|
10
9
|
export interface PluginToolConfig<InputSchema extends StandardSchemaWithJSON, OutputSchema extends StandardSchemaWithJSON> {
|
|
@@ -20,7 +19,6 @@ export interface PluginToolConfig<InputSchema extends StandardSchemaWithJSON, Ou
|
|
|
20
19
|
};
|
|
21
20
|
present?: (output: unknown) => CallToolResult;
|
|
22
21
|
}
|
|
23
|
-
/** Framework-owned MCP registration boundary that guarantees every plugin tool is audited. */
|
|
24
22
|
export declare class PluginMcpRegistrar {
|
|
25
23
|
private readonly server;
|
|
26
24
|
private readonly operations;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { asChatRoomError } from "../../core/errors/chatroom-error.js";
|
|
2
2
|
import { mcpTool } from "./tool-support.js";
|
|
3
|
-
/** Framework-owned MCP registration boundary that guarantees every plugin tool is audited. */
|
|
4
3
|
export class PluginMcpRegistrar {
|
|
5
4
|
server;
|
|
6
5
|
operations;
|
|
@@ -53,9 +52,6 @@ function operationReferences(input) {
|
|
|
53
52
|
return {};
|
|
54
53
|
const record = input;
|
|
55
54
|
return {
|
|
56
|
-
...(typeof record.workspaceId === "string"
|
|
57
|
-
? { workspaceId: record.workspaceId }
|
|
58
|
-
: {}),
|
|
59
55
|
...(typeof record.processId === "string"
|
|
60
56
|
? { processId: record.processId }
|
|
61
57
|
: {}),
|
|
@@ -6,18 +6,6 @@ export declare const closedRead: {
|
|
|
6
6
|
idempotentHint: true;
|
|
7
7
|
openWorldHint: false;
|
|
8
8
|
};
|
|
9
|
-
export declare const localWrite: {
|
|
10
|
-
readOnlyHint: false;
|
|
11
|
-
destructiveHint: true;
|
|
12
|
-
idempotentHint: true;
|
|
13
|
-
openWorldHint: false;
|
|
14
|
-
};
|
|
15
|
-
export declare const localMutation: {
|
|
16
|
-
readOnlyHint: false;
|
|
17
|
-
destructiveHint: false;
|
|
18
|
-
idempotentHint: false;
|
|
19
|
-
openWorldHint: false;
|
|
20
|
-
};
|
|
21
9
|
export declare const destructiveLocalMutation: {
|
|
22
10
|
readOnlyHint: false;
|
|
23
11
|
destructiveHint: true;
|
|
@@ -30,55 +18,6 @@ export declare const openWorldMutation: {
|
|
|
30
18
|
idempotentHint: false;
|
|
31
19
|
openWorldHint: true;
|
|
32
20
|
};
|
|
33
|
-
export declare const workspaceOutputSchema: z.ZodObject<{
|
|
34
|
-
id: z.ZodString;
|
|
35
|
-
root: z.ZodString;
|
|
36
|
-
sourceRoot: z.ZodString;
|
|
37
|
-
mode: z.ZodEnum<{
|
|
38
|
-
checkout: "checkout";
|
|
39
|
-
worktree: "worktree";
|
|
40
|
-
}>;
|
|
41
|
-
createdAt: z.ZodString;
|
|
42
|
-
lastUsedAt: z.ZodString;
|
|
43
|
-
instructions: z.ZodArray<z.ZodString>;
|
|
44
|
-
skills: z.ZodArray<z.ZodString>;
|
|
45
|
-
capabilities: z.ZodObject<{
|
|
46
|
-
filesystem: z.ZodLiteral<"read-write">;
|
|
47
|
-
git: z.ZodBoolean;
|
|
48
|
-
skills: z.ZodBoolean;
|
|
49
|
-
}, z.core.$strip>;
|
|
50
|
-
}, z.core.$strip>;
|
|
51
|
-
export declare const fileReadOutputSchema: z.ZodObject<{
|
|
52
|
-
content: z.ZodString;
|
|
53
|
-
bytes: z.ZodNumber;
|
|
54
|
-
truncated: z.ZodBoolean;
|
|
55
|
-
}, z.core.$strip>;
|
|
56
|
-
export declare const fileWriteOutputSchema: z.ZodObject<{
|
|
57
|
-
path: z.ZodString;
|
|
58
|
-
bytes: z.ZodNumber;
|
|
59
|
-
}, z.core.$strip>;
|
|
60
|
-
export declare const fileInfoSchema: z.ZodObject<{
|
|
61
|
-
path: z.ZodString;
|
|
62
|
-
type: z.ZodEnum<{
|
|
63
|
-
file: "file";
|
|
64
|
-
directory: "directory";
|
|
65
|
-
symlink: "symlink";
|
|
66
|
-
}>;
|
|
67
|
-
size: z.ZodNumber;
|
|
68
|
-
modifiedAt: z.ZodString;
|
|
69
|
-
}, z.core.$strip>;
|
|
70
|
-
export declare const searchMatchSchema: z.ZodObject<{
|
|
71
|
-
path: z.ZodString;
|
|
72
|
-
line: z.ZodNumber;
|
|
73
|
-
column: z.ZodNumber;
|
|
74
|
-
preview: z.ZodString;
|
|
75
|
-
}, z.core.$strip>;
|
|
76
|
-
export declare const changeSetSchema: z.ZodObject<{
|
|
77
|
-
files: z.ZodArray<z.ZodString>;
|
|
78
|
-
replacements: z.ZodNumber;
|
|
79
|
-
bytesBefore: z.ZodNumber;
|
|
80
|
-
bytesAfter: z.ZodNumber;
|
|
81
|
-
}, z.core.$strip>;
|
|
82
21
|
export declare const processSnapshotSchema: z.ZodObject<{
|
|
83
22
|
processId: z.ZodString;
|
|
84
23
|
command: z.ZodString;
|
|
@@ -6,18 +6,6 @@ export const closedRead = {
|
|
|
6
6
|
idempotentHint: true,
|
|
7
7
|
openWorldHint: false,
|
|
8
8
|
};
|
|
9
|
-
export const localWrite = {
|
|
10
|
-
readOnlyHint: false,
|
|
11
|
-
destructiveHint: true,
|
|
12
|
-
idempotentHint: true,
|
|
13
|
-
openWorldHint: false,
|
|
14
|
-
};
|
|
15
|
-
export const localMutation = {
|
|
16
|
-
readOnlyHint: false,
|
|
17
|
-
destructiveHint: false,
|
|
18
|
-
idempotentHint: false,
|
|
19
|
-
openWorldHint: false,
|
|
20
|
-
};
|
|
21
9
|
export const destructiveLocalMutation = {
|
|
22
10
|
readOnlyHint: false,
|
|
23
11
|
destructiveHint: true,
|
|
@@ -30,48 +18,6 @@ export const openWorldMutation = {
|
|
|
30
18
|
idempotentHint: false,
|
|
31
19
|
openWorldHint: true,
|
|
32
20
|
};
|
|
33
|
-
export const workspaceOutputSchema = z.object({
|
|
34
|
-
id: z.string(),
|
|
35
|
-
root: z.string(),
|
|
36
|
-
sourceRoot: z.string(),
|
|
37
|
-
mode: z.enum(["checkout", "worktree"]),
|
|
38
|
-
createdAt: z.string(),
|
|
39
|
-
lastUsedAt: z.string(),
|
|
40
|
-
instructions: z.array(z.string()),
|
|
41
|
-
skills: z.array(z.string()),
|
|
42
|
-
capabilities: z.object({
|
|
43
|
-
filesystem: z.literal("read-write"),
|
|
44
|
-
git: z.boolean(),
|
|
45
|
-
skills: z.boolean(),
|
|
46
|
-
}),
|
|
47
|
-
});
|
|
48
|
-
export const fileReadOutputSchema = z.object({
|
|
49
|
-
content: z.string(),
|
|
50
|
-
bytes: z.number().int().nonnegative(),
|
|
51
|
-
truncated: z.boolean(),
|
|
52
|
-
});
|
|
53
|
-
export const fileWriteOutputSchema = z.object({
|
|
54
|
-
path: z.string(),
|
|
55
|
-
bytes: z.number().int().nonnegative(),
|
|
56
|
-
});
|
|
57
|
-
export const fileInfoSchema = z.object({
|
|
58
|
-
path: z.string(),
|
|
59
|
-
type: z.enum(["file", "directory", "symlink"]),
|
|
60
|
-
size: z.number().int().nonnegative(),
|
|
61
|
-
modifiedAt: z.string(),
|
|
62
|
-
});
|
|
63
|
-
export const searchMatchSchema = z.object({
|
|
64
|
-
path: z.string(),
|
|
65
|
-
line: z.number().int().positive(),
|
|
66
|
-
column: z.number().int().positive(),
|
|
67
|
-
preview: z.string(),
|
|
68
|
-
});
|
|
69
|
-
export const changeSetSchema = z.object({
|
|
70
|
-
files: z.array(z.string()),
|
|
71
|
-
replacements: z.number().int().nonnegative(),
|
|
72
|
-
bytesBefore: z.number().int().nonnegative(),
|
|
73
|
-
bytesAfter: z.number().int().nonnegative(),
|
|
74
|
-
});
|
|
75
21
|
export const processSnapshotSchema = z.object({
|
|
76
22
|
processId: z.string(),
|
|
77
23
|
command: z.string(),
|
|
Binary file
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
9
9
|
<key>CFBundleVersion</key><string>1</string>
|
|
10
10
|
<key>CFBundleShortVersionString</key><string>1.0</string>
|
|
11
|
-
<key>LSMinimumSystemVersion</key><string>
|
|
11
|
+
<key>LSMinimumSystemVersion</key><string>14.0</string>
|
|
12
12
|
<key>LSUIElement</key><true/>
|
|
13
13
|
<key>NSHumanReadableCopyright</key><string>ChatRoom</string>
|
|
14
14
|
</dict></plist>
|
package/dist/native/macos/ChatRoomComputerHelper.app/Contents/MacOS/chatroom-computer-helper
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Operation, OperationStart, OperationStatus } from "../core/operations/types.js";
|
|
2
2
|
import type { OperationQuery, OperationRepository } from "../core/operations/repository.js";
|
|
3
3
|
import type { RuntimeEventBus } from "../app/event-bus.js";
|
|
4
|
-
/** Persists redacted, bounded operations produced by ChatRoom plugins. */
|
|
5
4
|
export declare class OperationLog {
|
|
6
5
|
private readonly repository;
|
|
7
6
|
private readonly eventBus;
|
|
@@ -10,12 +9,10 @@ export declare class OperationLog {
|
|
|
10
9
|
constructor(repository: OperationRepository, eventBus: RuntimeEventBus, maxPayloadBytes: number);
|
|
11
10
|
start(request: OperationStart): Operation;
|
|
12
11
|
finish(operationId: string, status: Exclude<OperationStatus, "running">, output?: unknown, error?: unknown): Operation;
|
|
13
|
-
updateRunning(operationId: string, output: unknown): Operation;
|
|
14
12
|
run<T>(request: OperationStart, action: () => Promise<T>): Promise<T>;
|
|
15
13
|
list(query?: OperationQuery): Operation[];
|
|
16
14
|
get(operationId: string): Operation | null;
|
|
17
15
|
associate(operationId: string, references: {
|
|
18
|
-
workspaceId?: string | null;
|
|
19
16
|
processId?: string | null;
|
|
20
17
|
}): Operation;
|
|
21
18
|
clearHistory(): {
|
|
@@ -2,7 +2,6 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { boundJson } from "../core/operations/bounded-value.js";
|
|
3
3
|
import { SecretRedactor } from "../core/operations/redactor.js";
|
|
4
4
|
import { asChatRoomError, ChatRoomError, } from "../core/errors/chatroom-error.js";
|
|
5
|
-
/** Persists redacted, bounded operations produced by ChatRoom plugins. */
|
|
6
5
|
export class OperationLog {
|
|
7
6
|
repository;
|
|
8
7
|
eventBus;
|
|
@@ -21,7 +20,6 @@ export class OperationLog {
|
|
|
21
20
|
source: request.source,
|
|
22
21
|
action: request.action,
|
|
23
22
|
status: "running",
|
|
24
|
-
workspaceId: request.workspaceId ?? null,
|
|
25
23
|
processId: request.processId ?? null,
|
|
26
24
|
input: input.value,
|
|
27
25
|
output: null,
|
|
@@ -52,17 +50,6 @@ export class OperationLog {
|
|
|
52
50
|
this.eventBus.emit({ type: "operation", operation });
|
|
53
51
|
return operation;
|
|
54
52
|
}
|
|
55
|
-
updateRunning(operationId, output) {
|
|
56
|
-
const operation = this.require(operationId);
|
|
57
|
-
if (operation.status !== "running")
|
|
58
|
-
return operation;
|
|
59
|
-
const bounded = boundJson(this.redactor.redact(output), this.maxPayloadBytes);
|
|
60
|
-
operation.output = bounded.value;
|
|
61
|
-
operation.outputTruncated = bounded.truncated;
|
|
62
|
-
this.repository.update(operation);
|
|
63
|
-
this.eventBus.emit({ type: "operation", operation });
|
|
64
|
-
return operation;
|
|
65
|
-
}
|
|
66
53
|
async run(request, action) {
|
|
67
54
|
const operation = this.start(request);
|
|
68
55
|
try {
|
|
@@ -88,8 +75,6 @@ export class OperationLog {
|
|
|
88
75
|
}
|
|
89
76
|
associate(operationId, references) {
|
|
90
77
|
const operation = this.require(operationId);
|
|
91
|
-
if (references.workspaceId !== undefined)
|
|
92
|
-
operation.workspaceId = references.workspaceId;
|
|
93
78
|
if (references.processId !== undefined)
|
|
94
79
|
operation.processId = references.processId;
|
|
95
80
|
this.repository.update(operation);
|
|
@@ -18,6 +18,7 @@ export declare class CloudController {
|
|
|
18
18
|
private lastError;
|
|
19
19
|
private managementTimer;
|
|
20
20
|
private renewalTimer;
|
|
21
|
+
private statusRetryTimer;
|
|
21
22
|
private stopped;
|
|
22
23
|
private constructor();
|
|
23
24
|
static create(config: ChatRoomConfig, externalAccess?: ExternalAccessSink): Promise<CloudController>;
|
|
@@ -38,6 +39,7 @@ export declare class CloudController {
|
|
|
38
39
|
private refreshLeaseIfNeeded;
|
|
39
40
|
private connectTunnel;
|
|
40
41
|
private publishExternalAccess;
|
|
42
|
+
private scheduleStatusRetry;
|
|
41
43
|
private scheduleManagementSync;
|
|
42
44
|
private scheduleRenewal;
|
|
43
45
|
private validManagementSession;
|
|
@@ -13,6 +13,7 @@ export class CloudController {
|
|
|
13
13
|
lastError = null;
|
|
14
14
|
managementTimer = null;
|
|
15
15
|
renewalTimer = null;
|
|
16
|
+
statusRetryTimer = null;
|
|
16
17
|
stopped = true;
|
|
17
18
|
constructor(config, cloudApi, externalAccess) {
|
|
18
19
|
this.config = config;
|
|
@@ -28,6 +29,9 @@ export class CloudController {
|
|
|
28
29
|
return controller;
|
|
29
30
|
}
|
|
30
31
|
status() {
|
|
32
|
+
const lease = this.state.lease && Date.parse(this.state.lease.expiresAt) > Date.now()
|
|
33
|
+
? this.state.lease
|
|
34
|
+
: null;
|
|
31
35
|
return {
|
|
32
36
|
installationId: this.state.installationId,
|
|
33
37
|
customerId: this.state.customerId,
|
|
@@ -37,10 +41,8 @@ export class CloudController {
|
|
|
37
41
|
managementSessionActive: Boolean(this.state.managementSession &&
|
|
38
42
|
Date.parse(this.state.managementSession.expiresAt) > Date.now()),
|
|
39
43
|
connection: this.connection,
|
|
40
|
-
mcpUrl:
|
|
41
|
-
|
|
42
|
-
: null,
|
|
43
|
-
webUrl: this.state.lease?.webBaseUrl ?? null,
|
|
44
|
+
mcpUrl: lease?.mcpBaseUrl ? `${lease.mcpBaseUrl}/mcp` : null,
|
|
45
|
+
webUrl: lease?.webBaseUrl ?? null,
|
|
44
46
|
lastError: this.lastError,
|
|
45
47
|
};
|
|
46
48
|
}
|
|
@@ -48,7 +50,10 @@ export class CloudController {
|
|
|
48
50
|
if (!this.stopped)
|
|
49
51
|
return;
|
|
50
52
|
this.stopped = false;
|
|
51
|
-
await this.syncStatus().catch((error) =>
|
|
53
|
+
await this.syncStatus().catch((error) => {
|
|
54
|
+
this.setError(error);
|
|
55
|
+
this.scheduleStatusRetry();
|
|
56
|
+
});
|
|
52
57
|
this.scheduleManagementSync();
|
|
53
58
|
}
|
|
54
59
|
async stop() {
|
|
@@ -57,8 +62,11 @@ export class CloudController {
|
|
|
57
62
|
clearTimeout(this.managementTimer);
|
|
58
63
|
if (this.renewalTimer)
|
|
59
64
|
clearTimeout(this.renewalTimer);
|
|
65
|
+
if (this.statusRetryTimer)
|
|
66
|
+
clearTimeout(this.statusRetryTimer);
|
|
60
67
|
this.managementTimer = null;
|
|
61
68
|
this.renewalTimer = null;
|
|
69
|
+
this.statusRetryTimer = null;
|
|
62
70
|
this.tunnel?.stop();
|
|
63
71
|
this.tunnel = null;
|
|
64
72
|
this.externalAccess?.clearCloud();
|
|
@@ -106,6 +114,9 @@ export class CloudController {
|
|
|
106
114
|
this.scheduleRenewal();
|
|
107
115
|
}
|
|
108
116
|
this.lastError = null;
|
|
117
|
+
if (this.statusRetryTimer)
|
|
118
|
+
clearTimeout(this.statusRetryTimer);
|
|
119
|
+
this.statusRetryTimer = null;
|
|
109
120
|
return this.status();
|
|
110
121
|
}
|
|
111
122
|
async restore(recoveryKey) {
|
|
@@ -222,6 +233,18 @@ export class CloudController {
|
|
|
222
233
|
: null,
|
|
223
234
|
});
|
|
224
235
|
}
|
|
236
|
+
scheduleStatusRetry(delayMs = 30_000) {
|
|
237
|
+
if (this.stopped || this.statusRetryTimer)
|
|
238
|
+
return;
|
|
239
|
+
this.statusRetryTimer = setTimeout(() => {
|
|
240
|
+
this.statusRetryTimer = null;
|
|
241
|
+
void this.syncStatus().catch((error) => {
|
|
242
|
+
this.setError(error);
|
|
243
|
+
this.scheduleStatusRetry();
|
|
244
|
+
});
|
|
245
|
+
}, delayMs);
|
|
246
|
+
this.statusRetryTimer.unref();
|
|
247
|
+
}
|
|
225
248
|
scheduleManagementSync(delayMs = 3_000) {
|
|
226
249
|
if (this.managementTimer)
|
|
227
250
|
clearTimeout(this.managementTimer);
|
|
@@ -77,15 +77,11 @@ export class CloudTunnelClient {
|
|
|
77
77
|
this.acceptingServices = new Set(lease.services);
|
|
78
78
|
if (this.stopped)
|
|
79
79
|
return;
|
|
80
|
-
// A new signed lease on the same tunnel is applied in-band. This keeps the
|
|
81
|
-
// current WebUI/API request alive while service permissions change.
|
|
82
80
|
if (!tunnelChanged) {
|
|
83
81
|
if (this.socket?.readyState === WebSocket.OPEN)
|
|
84
82
|
this.send({ type: "update-lease", lease: lease.token });
|
|
85
83
|
return;
|
|
86
84
|
}
|
|
87
|
-
// Changing the tunnel endpoint still requires a reconnect. If a service is
|
|
88
|
-
// being removed, let current streams finish before moving the connection.
|
|
89
85
|
if (!removesService || this.streams.size === 0) {
|
|
90
86
|
this.socket?.close();
|
|
91
87
|
return;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CommandRunner } from "../../core/runtime/command-runner.js";
|
|
2
|
+
import type { GitBranch, GitCommit, GitDiff, GitStatus } from "./types.js";
|
|
3
|
+
export declare class GitService {
|
|
4
|
+
private readonly commands;
|
|
5
|
+
constructor(commands: CommandRunner);
|
|
6
|
+
status(cwd: string): Promise<GitStatus | null>;
|
|
7
|
+
diff(cwd: string, filePath?: string, maxPreviewBytes?: number): Promise<GitDiff>;
|
|
8
|
+
stage(cwd: string, paths: string[]): Promise<GitStatus>;
|
|
9
|
+
unstage(cwd: string, paths: string[]): Promise<GitStatus>;
|
|
10
|
+
restore(cwd: string, filePath: string): Promise<GitStatus>;
|
|
11
|
+
commit(cwd: string, message: string): Promise<GitStatus>;
|
|
12
|
+
branches(cwd: string): Promise<GitBranch[]>;
|
|
13
|
+
createBranch(cwd: string, name: string): Promise<GitStatus>;
|
|
14
|
+
switchBranch(cwd: string, name: string): Promise<GitStatus>;
|
|
15
|
+
deleteBranch(cwd: string, name: string): Promise<GitStatus>;
|
|
16
|
+
log(cwd: string, limit?: number): Promise<GitCommit[]>;
|
|
17
|
+
fetch(cwd: string): Promise<GitStatus>;
|
|
18
|
+
pull(cwd: string): Promise<GitStatus>;
|
|
19
|
+
push(cwd: string): Promise<GitStatus>;
|
|
20
|
+
private run;
|
|
21
|
+
private repositoryRoot;
|
|
22
|
+
private requireRepository;
|
|
23
|
+
private requireStatus;
|
|
24
|
+
private head;
|
|
25
|
+
private requireHead;
|
|
26
|
+
private branch;
|
|
27
|
+
private upstream;
|
|
28
|
+
private aheadBehind;
|
|
29
|
+
private relatedPaths;
|
|
30
|
+
private pathExistsInHead;
|
|
31
|
+
private validateBranchName;
|
|
32
|
+
private withSnapshotIndex;
|
|
33
|
+
}
|