@gajae-code/coding-agent 0.11.5 → 0.11.7

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 (138) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/types/capability/index.d.ts +10 -20
  3. package/dist/types/capability/types.d.ts +3 -0
  4. package/dist/types/commands/daemon.d.ts +2 -2
  5. package/dist/types/commands/sdk.d.ts +20 -2
  6. package/dist/types/config/keybindings.d.ts +1 -1
  7. package/dist/types/config/settings-schema.d.ts +67 -7
  8. package/dist/types/eval/py/runner-artifact.d.ts +8 -0
  9. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +5 -5
  10. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +20 -0
  11. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +19 -5
  12. package/dist/types/main.d.ts +24 -1
  13. package/dist/types/modes/components/btw-panel.d.ts +1 -0
  14. package/dist/types/modes/components/model-selector.d.ts +2 -0
  15. package/dist/types/modes/components/tool-status-header.d.ts +1 -0
  16. package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
  17. package/dist/types/modes/interactive-mode.d.ts +2 -0
  18. package/dist/types/modes/types.d.ts +1 -0
  19. package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
  20. package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -0
  21. package/dist/types/sdk/bus/index.d.ts +1 -1
  22. package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
  23. package/dist/types/sdk/bus/notification-service.d.ts +34 -0
  24. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +13 -3
  25. package/dist/types/sdk/bus/telegram-daemon.d.ts +61 -3
  26. package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
  27. package/dist/types/sdk/client/discovery.d.ts +2 -0
  28. package/dist/types/sdk/client/liveness.d.ts +7 -0
  29. package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
  30. package/dist/types/sdk/transport/index.d.ts +12 -0
  31. package/dist/types/sdk/transport/relay.d.ts +43 -0
  32. package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
  33. package/dist/types/sdk/transport/socket.d.ts +7 -0
  34. package/dist/types/sdk/transport/stdio.d.ts +3 -0
  35. package/dist/types/session/agent-session.d.ts +28 -5
  36. package/dist/types/session/btw-contract.d.ts +16 -0
  37. package/dist/types/session/internal/managed-session-scope.d.ts +21 -7
  38. package/dist/types/session/internal/managed-session-storage.d.ts +10 -8
  39. package/dist/types/session/session-manager.d.ts +35 -4
  40. package/dist/types/session/yield-queue.d.ts +8 -0
  41. package/dist/types/setup/credential-import.d.ts +5 -1
  42. package/dist/types/setup/provider-onboarding.d.ts +2 -0
  43. package/dist/types/ssh/utils.d.ts +1 -0
  44. package/dist/types/task/discovery.d.ts +3 -1
  45. package/dist/types/tools/fetch.d.ts +5 -8
  46. package/dist/types/tools/image-gen.d.ts +16 -0
  47. package/dist/types/tools/skill-discovery.d.ts +7 -0
  48. package/dist/types/tools/sqlite-reader.d.ts +7 -0
  49. package/dist/types/utils/shell-snapshot.d.ts +12 -0
  50. package/dist/types/web/insane/bridge.d.ts +1 -0
  51. package/dist/types/web/insane/url-guard.d.ts +17 -0
  52. package/package.json +8 -8
  53. package/scripts/generate-sdk-operation-inventory.ts +3 -0
  54. package/src/capability/index.ts +50 -42
  55. package/src/capability/types.ts +3 -0
  56. package/src/cli/setup-cli.ts +10 -4
  57. package/src/cli.ts +34 -9
  58. package/src/commands/daemon.ts +22 -5
  59. package/src/commands/sdk.ts +42 -9
  60. package/src/config/keybindings.ts +1 -1
  61. package/src/config/model-profiles.ts +18 -0
  62. package/src/config/settings-schema.ts +71 -7
  63. package/src/defaults/gjc/skills/ultragoal/SKILL.md +42 -1
  64. package/src/discovery/ssh.ts +12 -1
  65. package/src/eval/py/kernel.ts +1 -21
  66. package/src/eval/py/runner-artifact.ts +84 -0
  67. package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
  68. package/src/gjc-runtime/ultragoal-guard.ts +88 -10
  69. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +103 -0
  70. package/src/gjc-runtime/ultragoal-runtime.ts +275 -12
  71. package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
  72. package/src/gjc-runtime/workflow-manifest.ts +23 -0
  73. package/src/internal-urls/docs-index.generated.ts +9 -8
  74. package/src/internal-urls/local-protocol.ts +32 -6
  75. package/src/main.ts +87 -28
  76. package/src/modes/action-registry.ts +1 -1
  77. package/src/modes/components/btw-panel.ts +82 -16
  78. package/src/modes/components/model-selector.ts +31 -3
  79. package/src/modes/components/tool-status-header.ts +6 -1
  80. package/src/modes/controllers/btw-controller.ts +119 -36
  81. package/src/modes/controllers/command-controller.ts +15 -0
  82. package/src/modes/controllers/extension-ui-controller.ts +14 -2
  83. package/src/modes/controllers/input-controller.ts +31 -0
  84. package/src/modes/controllers/selector-controller.ts +106 -12
  85. package/src/modes/interactive-mode.ts +16 -7
  86. package/src/modes/runtime-init.ts +16 -2
  87. package/src/modes/types.ts +1 -0
  88. package/src/prompts/system/btw-user.md +3 -8
  89. package/src/prompts/tools/skill-discovery.md +1 -0
  90. package/src/runtime-mcp/client.ts +41 -55
  91. package/src/runtime-mcp/content-limits.ts +71 -0
  92. package/src/runtime-mcp/json-rpc.ts +23 -9
  93. package/src/runtime-mcp/transports/http.ts +50 -16
  94. package/src/sdk/bus/chat-daemon-control.ts +20 -7
  95. package/src/sdk/bus/index.ts +8 -7
  96. package/src/sdk/bus/lifecycle-commands.ts +16 -7
  97. package/src/sdk/bus/notification-service.ts +41 -18
  98. package/src/sdk/bus/telegram-daemon-contract.ts +13 -3
  99. package/src/sdk/bus/telegram-daemon-control.ts +26 -8
  100. package/src/sdk/bus/telegram-daemon.ts +1736 -338
  101. package/src/sdk/bus/topic-registry.ts +451 -12
  102. package/src/sdk/client/discovery.ts +19 -3
  103. package/src/sdk/client/liveness.ts +49 -0
  104. package/src/sdk/host/control/dispatch.ts +14 -5
  105. package/src/sdk/protocol/operation-inventory.generated.json +29 -0
  106. package/src/sdk/session.ts +29 -5
  107. package/src/sdk/transport/auth-preface.ts +82 -0
  108. package/src/sdk/transport/index.ts +18 -0
  109. package/src/sdk/transport/relay.ts +252 -0
  110. package/src/sdk/transport/serve-cli.ts +105 -0
  111. package/src/sdk/transport/socket.ts +197 -0
  112. package/src/sdk/transport/stdio.ts +17 -0
  113. package/src/session/agent-session.ts +1212 -768
  114. package/src/session/blob-store.ts +19 -6
  115. package/src/session/btw-contract.ts +59 -0
  116. package/src/session/internal/managed-session-scope.ts +313 -57
  117. package/src/session/internal/managed-session-storage.ts +146 -35
  118. package/src/session/session-manager.ts +385 -85
  119. package/src/session/yield-queue.ts +20 -0
  120. package/src/setup/credential-import.ts +28 -3
  121. package/src/setup/provider-onboarding.ts +30 -1
  122. package/src/setup/provider-presets.json +2 -1
  123. package/src/slash-commands/builtin-registry.ts +37 -1
  124. package/src/ssh/utils.ts +14 -0
  125. package/src/task/discovery.ts +8 -2
  126. package/src/tools/ask-answer-registry.ts +15 -1
  127. package/src/tools/ask.ts +1 -1
  128. package/src/tools/fetch.ts +13 -131
  129. package/src/tools/image-gen.ts +301 -20
  130. package/src/tools/read.ts +2 -0
  131. package/src/tools/skill-discovery.ts +39 -3
  132. package/src/tools/sqlite-reader.ts +63 -5
  133. package/src/utils/pasted-image-path.ts +15 -6
  134. package/src/utils/shell-snapshot.ts +173 -63
  135. package/src/web/insane/bridge.ts +5 -1
  136. package/src/web/insane/url-guard.ts +138 -27
  137. package/src/web/scrapers/types.ts +19 -49
  138. package/src/web/scrapers/utils.ts +12 -26
@@ -0,0 +1,197 @@
1
+ import * as fsSync from "node:fs";
2
+ import * as fs from "node:fs/promises";
3
+ import * as net from "node:net";
4
+ import * as path from "node:path";
5
+ import { MAX_UNIX_SOCKET_PATH_BYTES } from "../../harness-control-plane/storage";
6
+ import { authenticatePreface } from "./auth-preface";
7
+ import type { ServeHandle, ServeOptions } from "./index";
8
+ import type { RelayOptions, RelayPair, TransportError } from "./relay";
9
+ import { startRelayPair } from "./relay";
10
+
11
+ function socketFailure(code: string): Error {
12
+ return new Error(code);
13
+ }
14
+
15
+ async function validateSocketPath(socketPath: string): Promise<void> {
16
+ if (process.platform === "win32") throw socketFailure("unsupported_platform");
17
+ if (Buffer.byteLength(socketPath) > MAX_UNIX_SOCKET_PATH_BYTES) throw socketFailure("socket_path_too_long");
18
+ try {
19
+ await fs.lstat(socketPath);
20
+ throw socketFailure("socket_path_in_use");
21
+ } catch (error) {
22
+ if (error instanceof Error && error.message === "socket_path_in_use") throw error;
23
+ const code = error as NodeJS.ErrnoException;
24
+ if (code.code !== "ENOENT") throw error;
25
+ }
26
+ let parent: Awaited<ReturnType<typeof fs.stat>>;
27
+ try {
28
+ parent = await fs.stat(path.dirname(socketPath));
29
+ } catch {
30
+ throw socketFailure("socket_dir_insecure");
31
+ }
32
+ if (!parent.isDirectory() || parent.uid !== process.getuid?.() || (parent.mode & 0o022) !== 0)
33
+ throw socketFailure("socket_dir_insecure");
34
+ }
35
+
36
+ function sendTransportError(socket: net.Socket, error: TransportError): void {
37
+ socket.write(`${JSON.stringify(error)}\n`);
38
+ }
39
+
40
+ /** Serves authenticated SDK JSONL clients over a private Unix-domain socket. */
41
+ export async function startSocketServe(
42
+ options: ServeOptions & { socketPath: string; webSocketFactory?: RelayOptions["webSocketFactory"] },
43
+ ): Promise<ServeHandle> {
44
+ await validateSocketPath(options.socketPath);
45
+ const pairs = new Set<RelayPair>();
46
+ const sockets = new Set<net.Socket>();
47
+ const connectionTasks = new Set<Promise<void>>();
48
+ const dialControllers = new Set<AbortController>();
49
+ let server: net.Server | undefined;
50
+ let ownedIdentity: { dev: number; ino: number } | undefined;
51
+ let closing: Promise<void> | undefined;
52
+ const done = Promise.withResolvers<void>();
53
+ void done.promise.catch(() => undefined);
54
+
55
+ const removeOwnedSocket = async (): Promise<void> => {
56
+ if (!ownedIdentity) return;
57
+ try {
58
+ const current = await fs.lstat(options.socketPath);
59
+ if (current.isSocket() && current.dev === ownedIdentity.dev && current.ino === ownedIdentity.ino)
60
+ await fs.unlink(options.socketPath);
61
+ } catch (error) {
62
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
63
+ }
64
+ };
65
+
66
+ const removeOwnedSocketSync = (): void => {
67
+ if (!ownedIdentity) return;
68
+ try {
69
+ const current = fsSync.lstatSync(options.socketPath);
70
+ if (current.isSocket() && current.dev === ownedIdentity.dev && current.ino === ownedIdentity.ino)
71
+ fsSync.unlinkSync(options.socketPath);
72
+ } catch (error) {
73
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
74
+ }
75
+ };
76
+ const cleanupOnExit = (): void => removeOwnedSocketSync();
77
+ process.once("exit", cleanupOnExit);
78
+ const close = async (fatalError?: Error): Promise<void> => {
79
+ if (closing) return await closing;
80
+ closing = (async () => {
81
+ const errors: Error[] = fatalError ? [fatalError] : [];
82
+ for (const controller of dialControllers) controller.abort();
83
+ for (const socket of sockets) socket.destroy();
84
+ const pairResults = await Promise.allSettled([...pairs].map(pair => pair.close()));
85
+ for (const result of pairResults) {
86
+ if (result.status === "rejected")
87
+ errors.push(result.reason instanceof Error ? result.reason : new Error(String(result.reason)));
88
+ }
89
+ const connectionResults = await Promise.allSettled([...connectionTasks]);
90
+ for (const result of connectionResults) {
91
+ if (result.status === "rejected")
92
+ errors.push(result.reason instanceof Error ? result.reason : new Error(String(result.reason)));
93
+ }
94
+ let displacedPath: string | undefined;
95
+ if (server?.listening && ownedIdentity) {
96
+ try {
97
+ const current = await fs.lstat(options.socketPath).catch(() => undefined);
98
+ if (current && (current.dev !== ownedIdentity.dev || current.ino !== ownedIdentity.ino)) {
99
+ displacedPath = `${options.socketPath}.${process.pid}.closing`;
100
+ await fs.rename(options.socketPath, displacedPath);
101
+ }
102
+ } catch (error) {
103
+ errors.push(error instanceof Error ? error : new Error(String(error)));
104
+ }
105
+ }
106
+ if (server?.listening) {
107
+ try {
108
+ await new Promise<void>((resolve, reject) =>
109
+ server?.close(error => (error ? reject(error) : resolve())),
110
+ );
111
+ } catch (error) {
112
+ errors.push(error instanceof Error ? error : new Error(String(error)));
113
+ }
114
+ }
115
+ if (displacedPath) {
116
+ try {
117
+ await fs.rename(displacedPath, options.socketPath);
118
+ } catch (error) {
119
+ errors.push(error instanceof Error ? error : new Error(String(error)));
120
+ }
121
+ }
122
+ try {
123
+ await removeOwnedSocket();
124
+ } catch (error) {
125
+ errors.push(error instanceof Error ? error : new Error(String(error)));
126
+ }
127
+ process.removeListener("exit", cleanupOnExit);
128
+ if (errors.length > 0) {
129
+ const error = new AggregateError(errors, "socket_serve_close_failed");
130
+ done.reject(error);
131
+ throw error;
132
+ }
133
+ done.resolve();
134
+ })();
135
+ return await closing;
136
+ };
137
+ const handleConnection = async (socket: net.Socket, signal: AbortSignal): Promise<void> => {
138
+ sockets.add(socket);
139
+ socket.once("close", () => sockets.delete(socket));
140
+ try {
141
+ const initialDownstreamBytes = await authenticatePreface(socket, options.token);
142
+ if (closing) {
143
+ socket.destroy();
144
+ return;
145
+ }
146
+ const pair = await startRelayPair({
147
+ ...options,
148
+ signal,
149
+ downstream: socket,
150
+ downstreamSink: socket,
151
+ initialDownstreamBytes,
152
+ onTransportError: error => sendTransportError(socket, error),
153
+ });
154
+ pairs.add(pair);
155
+ try {
156
+ await pair.done.catch(() => undefined);
157
+ } finally {
158
+ pairs.delete(pair);
159
+ socket.end();
160
+ }
161
+ } catch {
162
+ socket.destroy();
163
+ }
164
+ };
165
+ server = net.createServer(socket => {
166
+ if (closing) {
167
+ socket.destroy();
168
+ return;
169
+ }
170
+ const controller = new AbortController();
171
+ dialControllers.add(controller);
172
+ const task = handleConnection(socket, controller.signal).finally(() => {
173
+ dialControllers.delete(controller);
174
+ connectionTasks.delete(task);
175
+ });
176
+ connectionTasks.add(task);
177
+ void task;
178
+ });
179
+ server.on("error", error => void close(error).catch(() => undefined));
180
+ await new Promise<void>((resolve, reject) => {
181
+ server?.once("error", reject);
182
+ server?.listen(options.socketPath, () => resolve());
183
+ });
184
+ const bound = await fs.lstat(options.socketPath);
185
+ if (!bound.isSocket()) {
186
+ await close();
187
+ throw socketFailure("socket_bind_failed");
188
+ }
189
+ ownedIdentity = { dev: bound.dev, ino: bound.ino };
190
+ try {
191
+ await fs.chmod(options.socketPath, 0o600);
192
+ } catch (error) {
193
+ await close();
194
+ throw error;
195
+ }
196
+ return { close, done: done.promise };
197
+ }
@@ -0,0 +1,17 @@
1
+ import type { ServeHandle, ServeOptions } from "./index";
2
+ import { startRelayPair } from "./relay";
3
+
4
+ function writeDiagnostic(value: unknown): void {
5
+ process.stderr.write(`${JSON.stringify(value)}\n`);
6
+ }
7
+
8
+ /** Serves one parent-owned JSONL connection over the process standard streams. */
9
+ export async function startStdioServe(options: ServeOptions): Promise<ServeHandle> {
10
+ const pair = await startRelayPair({
11
+ ...options,
12
+ downstream: process.stdin,
13
+ downstreamSink: process.stdout,
14
+ onTransportError: writeDiagnostic,
15
+ });
16
+ return { close: pair.close, done: pair.done };
17
+ }