maka-agent 0.2.0-dev.24.20260907 → 0.2.0-dev.26.20260909
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 +38 -19
- package/README.zh-CN.md +34 -19
- package/dist/mcp-capability-provider.js +4 -1
- package/dist/pi-transcript-tools.js +6 -0
- package/dist/pi-tui-layout.js +56 -10
- package/dist/pi-tui-mcp-status.js +2 -2
- package/dist/pi-tui-pickers.js +121 -30
- package/dist/pi-tui-runner.js +156 -42
- package/dist/pi-tui-todo.js +221 -0
- package/dist/pi-tui-transcript-viewer.js +134 -7
- package/dist/runtime-host-cli-context.js +70 -13
- package/dist/runtime-host-handoff-surface.js +51 -26
- package/dist/runtime-host-local-handoff.js +11 -1
- package/dist/runtime-host-service-manager.js +0 -3
- package/dist/runtime-host-session-channel.js +13 -0
- package/dist/runtime-host-session-driver.js +42 -1
- package/dist/tui-autocomplete-layout.js +3 -1
- package/dist/tui-copy-catalog.js +85 -6
- package/dist/tui-editor-render.js +36 -0
- package/dist/tui-mcp-control.js +41 -6
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/agent-run.js +1 -0
- package/node_modules/@maka/core/dist/attachments.js +3 -0
- package/node_modules/@maka/core/dist/canonical-json.js +27 -0
- package/node_modules/@maka/core/dist/capabilities.js +35 -0
- package/node_modules/@maka/core/dist/computer-use.js +0 -1
- package/node_modules/@maka/core/dist/display-redaction.js +18 -0
- package/node_modules/@maka/core/dist/llm-connections.js +13 -0
- package/node_modules/@maka/core/dist/model-call-attempt.js +2 -0
- package/node_modules/@maka/core/dist/model-metadata.js +4 -0
- package/node_modules/@maka/core/dist/redaction.js +35 -0
- package/node_modules/@maka/core/dist/run-composition.js +77 -2
- package/node_modules/@maka/core/dist/runtime-event.js +3 -0
- package/node_modules/@maka/core/dist/session.js +57 -6
- package/node_modules/@maka/core/dist/slash-command-catalog.js +1 -0
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/workhub-action-result.js +68 -0
- package/node_modules/@maka/core/package.json +3 -3
- package/node_modules/@maka/eval/dist/experiment-directory.js +4 -13
- package/node_modules/@maka/eval/dist/toolchain-verification.js +1 -1
- package/node_modules/@maka/mcp/dist/form-elicitation.js +213 -0
- package/node_modules/@maka/mcp/dist/index.js +337 -71
- package/node_modules/@maka/runtime/dist/agent-run-inspect.js +0 -13
- package/node_modules/@maka/runtime/dist/agent-run.js +90 -2
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +16 -8
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +57 -50
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +2 -2
- package/node_modules/@maka/runtime/dist/context-budget-helpers.js +0 -16
- package/node_modules/@maka/runtime/dist/conversation-copy.js +153 -11
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +3 -3
- package/node_modules/@maka/runtime/dist/goal-continuation.js +5 -1
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +69 -1
- package/node_modules/@maka/runtime/dist/mcp-tools.js +7 -2
- package/node_modules/@maka/runtime/dist/model-fetcher.js +42 -2
- package/node_modules/@maka/runtime/dist/model-history.js +0 -112
- package/node_modules/@maka/runtime/dist/plugin-runtime.js +20 -10
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +205 -0
- package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +8 -1
- package/node_modules/@maka/runtime/dist/request-shape.js +23 -0
- package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +1 -1
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +24 -1
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +127 -13
- package/node_modules/@maka/runtime/dist/session-manager.js +20 -36
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +21 -0
- package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +0 -5
- package/node_modules/@maka/runtime/dist/test-connection.js +0 -1
- package/node_modules/@maka/runtime/dist/tool-activation-identity.js +41 -0
- package/node_modules/@maka/runtime/dist/tool-availability.js +11 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +63 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +42 -12
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +27 -4
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/client/connection.js +30 -5
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +52 -13
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +4 -2
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +18 -1
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +19 -0
- package/node_modules/@maka/runtime-host/dist/control/endpoint.js +1 -3
- package/node_modules/@maka/runtime-host/dist/node-error.js +22 -0
- package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +1 -3
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +0 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +1 -3
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +9 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +3 -2
- package/node_modules/@maka/runtime-host/dist/protocol/plan.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +27 -5
- package/node_modules/@maka/runtime-host/dist/protocol/project-catalog.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +86 -157
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/agent-graph-coordinator.js +0 -3
- package/node_modules/@maka/runtime-host/dist/server/canonical-session-projection.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/connection-session.js +28 -8
- package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +112 -56
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +32 -32
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +85 -25
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +42 -14
- package/node_modules/@maka/runtime-host/dist/server/failure-diagnostic.js +24 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +7 -3
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -3
- package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +3 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +34 -4
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +51 -23
- package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +2 -7
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +110 -14
- package/node_modules/@maka/runtime-host/dist/server/runtime-resource-coordinator.js +11 -8
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +31 -21
- package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +20 -8
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +15 -104
- package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +59 -82
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +132 -139
- package/node_modules/@maka/runtime-host/dist/server/workhub-message-attachments.js +46 -0
- package/node_modules/@maka/storage/dist/agent-run-store.js +14 -1
- package/node_modules/@maka/storage/dist/artifact-store.js +40 -3
- package/node_modules/@maka/storage/dist/atomic-file-write.js +74 -0
- package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +0 -1
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +284 -196
- package/node_modules/@maka/storage/dist/credential-store.js +12 -63
- package/node_modules/@maka/storage/dist/execution-stores.js +4 -1
- package/node_modules/@maka/storage/dist/git-exec.js +61 -0
- package/node_modules/@maka/storage/dist/git-worktree-child-executor.js +8 -35
- package/node_modules/@maka/storage/dist/goal-authority.js +2 -2
- package/node_modules/@maka/storage/dist/interaction-store.js +2 -2
- package/node_modules/@maka/storage/dist/mcp-config-store.js +10 -25
- package/node_modules/@maka/storage/dist/project-catalog.js +2 -23
- package/node_modules/@maka/storage/dist/runtime-event-invariants.js +2 -2
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +8 -3
- package/node_modules/@maka/storage/dist/scheduled-task-store.js +249 -283
- package/node_modules/@maka/storage/dist/session-bundle-manifest.js +5 -17
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +2 -1
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +2 -1
- package/node_modules/@maka/storage/dist/session-store.js +14 -2
- package/node_modules/@maka/storage/dist/settings-store.js +8 -4
- package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +11 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +1 -2
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +12 -1
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +67 -3
- package/node_modules/@maka/storage/dist/stable-storage.js +14 -1
- package/node_modules/@maka/storage/dist/storage-id.js +28 -0
- package/node_modules/@maka/storage/dist/tool-result-archive-evidence.js +31 -4
- package/node_modules/@maka/storage/dist/workspace-identity.js +2 -15
- package/node_modules/@maka/storage/dist/workspace-version-authority-internal.js +1 -8
- package/package.json +1 -1
- package/node_modules/@maka/core/dist/workhub-creation-intent.js +0 -990
- package/node_modules/@maka/core/dist/workhub-session-resolver.js +0 -50
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
20
|
-
import { chmod, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
|
|
19
|
+
import { readFile } from 'node:fs/promises';
|
|
21
20
|
import { dirname, join } from 'node:path';
|
|
21
|
+
import { writeAtomicFile } from './atomic-file-write.js';
|
|
22
22
|
import { withFileUpdateLock } from './file-update-lock.js';
|
|
23
|
+
import { hardenDirectory } from './stable-storage.js';
|
|
23
24
|
/** Current on-disk schema version. Unknown versions fail closed on read. */
|
|
24
25
|
export const CREDENTIAL_SCHEMA_VERSION = 1;
|
|
25
26
|
export function createFileCredentialStore(workspaceRoot) {
|
|
@@ -129,68 +130,14 @@ class FileCredentialStore {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* write plaintext credentials into a dir we couldn't lock down); no-op on
|
|
137
|
-
* Windows. Shared by the writer and the lock so their dir hardening can't drift.
|
|
138
|
-
*/
|
|
139
|
-
async function ensureSecretDir(dir) {
|
|
140
|
-
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
141
|
-
await chmodStrict(dir, 0o700);
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Owner-only atomic write for a credentials file: a 0700 dir, an exclusive
|
|
145
|
-
* 0600 temp ('wx'/O_EXCL so we never follow a pre-planted symlink at a
|
|
146
|
-
* predictable path), a durability fence before and after the atomic rename,
|
|
147
|
-
* and temp cleanup on failure.
|
|
133
|
+
* Owner-only atomic write for a credentials file. Directory hardening is an
|
|
134
|
+
* explicit credential-store policy; file publication uses the shared legacy
|
|
135
|
+
* JSON writer so its mode, synchronization, and cleanup behavior remains
|
|
136
|
+
* aligned with settings and MCP config.
|
|
148
137
|
*/
|
|
149
138
|
async function writeSecretFileAtomic(path, contents) {
|
|
150
|
-
await
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const handle = await open(tempPath, 'wx', 0o600);
|
|
154
|
-
try {
|
|
155
|
-
await handle.writeFile(contents, 'utf8');
|
|
156
|
-
await handle.sync();
|
|
157
|
-
}
|
|
158
|
-
finally {
|
|
159
|
-
await handle.close();
|
|
160
|
-
}
|
|
161
|
-
await chmodStrict(tempPath, 0o600);
|
|
162
|
-
await rename(tempPath, path);
|
|
163
|
-
await syncDirectory(dirname(path));
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
await rm(tempPath, { force: true });
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
async function syncDirectory(path) {
|
|
171
|
-
if (process.platform === 'win32')
|
|
172
|
-
return;
|
|
173
|
-
const handle = await open(path, 'r');
|
|
174
|
-
try {
|
|
175
|
-
await handle.sync();
|
|
176
|
-
}
|
|
177
|
-
finally {
|
|
178
|
-
await handle.close();
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* chmod that fails loud on POSIX and is best-effort on Windows. A secret file
|
|
183
|
-
* or its directory left looser than intended breaks the 0600/0700 boundary, so
|
|
184
|
-
* on POSIX we surface the failure rather than write plaintext into it; Windows
|
|
185
|
-
* has no POSIX mode, so a failure there is a no-op. One policy for both the
|
|
186
|
-
* secret file (0600) and its directory (0700) so they can't drift apart.
|
|
187
|
-
*/
|
|
188
|
-
async function chmodStrict(path, mode) {
|
|
189
|
-
if (process.platform === 'win32') {
|
|
190
|
-
await chmod(path, mode).catch(() => { });
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
await chmod(path, mode);
|
|
139
|
+
await hardenDirectory(dirname(path));
|
|
140
|
+
await writeAtomicFile(path, contents, { fileMode: 0o600 });
|
|
194
141
|
}
|
|
195
142
|
const LOCK_TIMEOUT_MS = 10_000;
|
|
196
143
|
/**
|
|
@@ -220,7 +167,9 @@ const LOCK_TIMEOUT_MS = 10_000;
|
|
|
220
167
|
* stays the typed store and callers can't drive the lock directly.
|
|
221
168
|
*/
|
|
222
169
|
export async function withCredentialFileLock(targetPath, fn, timeoutMs = LOCK_TIMEOUT_MS) {
|
|
223
|
-
|
|
170
|
+
// Same owner-only hardening the writer applies, so the lock directory can
|
|
171
|
+
// never sit looser than the secret it guards.
|
|
172
|
+
await hardenDirectory(dirname(targetPath));
|
|
224
173
|
return withFileUpdateLock(targetPath, fn, timeoutMs);
|
|
225
174
|
}
|
|
226
175
|
const STORED_CREDENTIAL_KINDS = [
|
|
@@ -149,10 +149,13 @@ async function createExecutionStoresForWrite(lease, kind, extension) {
|
|
|
149
149
|
listForRecovery: () => run(() => sessionStore.listForRecovery()),
|
|
150
150
|
readHeaderSnapshot: (sessionId) => run(() => sessionStore.readHeaderSnapshot(sessionId)),
|
|
151
151
|
readHeaderRecordSnapshot: (sessionId) => run(() => sessionStore.readHeaderRecordSnapshot(sessionId)),
|
|
152
|
-
readCatalogRecord: (sessionId) => run(() => sessionStore.readCatalogRecord(sessionId)),
|
|
152
|
+
readCatalogRecord: (sessionId, roleScope) => run(() => sessionStore.readCatalogRecord(sessionId, roleScope)),
|
|
153
153
|
probeSessionRemoval: (sessionId) => run(() => sessionStore.probeSessionRemoval(sessionId)),
|
|
154
154
|
readMessagesSnapshot: (sessionId) => run(() => sessionStore.readMessagesSnapshot(sessionId)),
|
|
155
155
|
readTranscriptMessagesSnapshot: (sessionId, request) => run(() => sessionStore.readTranscriptMessagesSnapshot(sessionId, request)),
|
|
156
|
+
readCoordinationTranscriptIndexState: () => run(() => sessionStore.readCoordinationTranscriptIndexState()),
|
|
157
|
+
appendCoordinationTranscriptIndex: (records) => run(() => sessionStore.appendCoordinationTranscriptIndex(records)),
|
|
158
|
+
readCoordinationTranscriptIndex: (request) => run(() => sessionStore.readCoordinationTranscriptIndex(request)),
|
|
156
159
|
readTranscriptHighWaterSnapshot: (sessionId) => run(() => sessionStore.readTranscriptHighWaterSnapshot(sessionId)),
|
|
157
160
|
listTurnsSnapshot: (sessionId) => run(() => sessionStore.listTurnsSnapshot(sessionId)),
|
|
158
161
|
readHeader: (sessionId) => run(() => sessionStore.readHeader(sessionId)),
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { execFile } from 'node:child_process';
|
|
20
|
+
import { promisify } from 'node:util';
|
|
21
|
+
const execFileAsync = promisify(execFile);
|
|
22
|
+
const DEFAULT_TIMEOUT_MS = 2 * 60 * 1_000;
|
|
23
|
+
const DEFAULT_TEXT_MAX_BUFFER = 1024 * 1024;
|
|
24
|
+
const DEFAULT_BYTES_MAX_BUFFER = Number.MAX_SAFE_INTEGER;
|
|
25
|
+
/**
|
|
26
|
+
* Runs Git with repository discovery isolated from ambient Git environment
|
|
27
|
+
* variables. Callers may provide a temporary index for patch construction.
|
|
28
|
+
*/
|
|
29
|
+
export async function execGitText(cwd, args, options = {}) {
|
|
30
|
+
const { stdout } = await execFileAsync('git', ['-C', cwd, ...args], {
|
|
31
|
+
env: gitEnvironment(options),
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_TEXT_MAX_BUFFER,
|
|
34
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
35
|
+
windowsHide: true,
|
|
36
|
+
});
|
|
37
|
+
return stdout;
|
|
38
|
+
}
|
|
39
|
+
export async function execGitBytes(cwd, args, options = {}) {
|
|
40
|
+
const { stdout } = await execFileAsync('git', ['-C', cwd, ...args], {
|
|
41
|
+
env: gitEnvironment(options),
|
|
42
|
+
encoding: 'buffer',
|
|
43
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_BYTES_MAX_BUFFER,
|
|
44
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
45
|
+
windowsHide: true,
|
|
46
|
+
});
|
|
47
|
+
return new Uint8Array(stdout);
|
|
48
|
+
}
|
|
49
|
+
function gitEnvironment(options) {
|
|
50
|
+
const env = { ...process.env, GIT_OPTIONAL_LOCKS: '0' };
|
|
51
|
+
delete env.GIT_DIR;
|
|
52
|
+
delete env.GIT_WORK_TREE;
|
|
53
|
+
delete env.GIT_COMMON_DIR;
|
|
54
|
+
if (options.gitIndexFile === undefined) {
|
|
55
|
+
delete env.GIT_INDEX_FILE;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
env.GIT_INDEX_FILE = options.gitIndexFile;
|
|
59
|
+
}
|
|
60
|
+
return env;
|
|
61
|
+
}
|
|
@@ -16,17 +16,14 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { execFile } from 'node:child_process';
|
|
20
19
|
import { copyFile, mkdir, mkdtemp, readdir, realpath, rm, stat } from 'node:fs/promises';
|
|
21
20
|
import { tmpdir } from 'node:os';
|
|
22
21
|
import { isAbsolute, join, normalize, resolve } from 'node:path';
|
|
23
|
-
import { promisify } from 'node:util';
|
|
24
22
|
import { SUBAGENT_WORKSPACE_BINDING_SCHEMA_VERSION, isSubagentWorkspaceBinding, } from '@maka/core/subagent-workspace';
|
|
23
|
+
import { execGitBytes, execGitText } from './git-exec.js';
|
|
25
24
|
import { resolveProjectLocation } from './project-catalog.js';
|
|
26
|
-
const execFileAsync = promisify(execFile);
|
|
27
25
|
const LEASE_PATTERN = /^subagent_worktree_([a-f0-9]{32})$/;
|
|
28
26
|
const WORKTREE_DIRECTORY_PATTERN = /^[a-f0-9]{32}$/;
|
|
29
|
-
const GIT_TIMEOUT_MS = 2 * 60 * 1_000;
|
|
30
27
|
/**
|
|
31
28
|
* Host-owned Git worktree allocator for linked child Sessions.
|
|
32
29
|
*
|
|
@@ -96,8 +93,8 @@ class GitWorktreeChildExecutor {
|
|
|
96
93
|
const currentIndex = (await runGit(binding.worktreePath, ['rev-parse', '--git-path', 'index'])).trim();
|
|
97
94
|
// Preserve staged and committed ignored paths, then overlay all working-tree changes.
|
|
98
95
|
await copyFile(isAbsolute(currentIndex) ? currentIndex : resolve(binding.worktreePath, currentIndex), indexPath);
|
|
99
|
-
const
|
|
100
|
-
await runGit(binding.worktreePath, ['add', '--all', '--'],
|
|
96
|
+
const gitOptions = { gitIndexFile: indexPath };
|
|
97
|
+
await runGit(binding.worktreePath, ['add', '--all', '--'], gitOptions);
|
|
101
98
|
return await runGitBytes(binding.worktreePath, [
|
|
102
99
|
'diff',
|
|
103
100
|
'--cached',
|
|
@@ -108,7 +105,7 @@ class GitWorktreeChildExecutor {
|
|
|
108
105
|
'--no-color',
|
|
109
106
|
binding.baseCommit,
|
|
110
107
|
'--',
|
|
111
|
-
],
|
|
108
|
+
], gitOptions);
|
|
112
109
|
}
|
|
113
110
|
finally {
|
|
114
111
|
await rm(temporary, { recursive: true, force: true });
|
|
@@ -398,35 +395,11 @@ async function gitCurrentBranch(cwd) {
|
|
|
398
395
|
throw error;
|
|
399
396
|
}
|
|
400
397
|
}
|
|
401
|
-
async function runGit(cwd, args,
|
|
402
|
-
|
|
403
|
-
const { stdout } = await execFileAsync('git', ['-C', cwd, ...args], {
|
|
404
|
-
env,
|
|
405
|
-
encoding: 'utf8',
|
|
406
|
-
maxBuffer: 1024 * 1024,
|
|
407
|
-
timeout: GIT_TIMEOUT_MS,
|
|
408
|
-
windowsHide: true,
|
|
409
|
-
});
|
|
410
|
-
return stdout;
|
|
398
|
+
async function runGit(cwd, args, options = {}) {
|
|
399
|
+
return execGitText(cwd, args, options);
|
|
411
400
|
}
|
|
412
|
-
async function runGitBytes(cwd, args,
|
|
413
|
-
|
|
414
|
-
env: gitEnvironment(overrides),
|
|
415
|
-
encoding: 'buffer',
|
|
416
|
-
maxBuffer: Number.MAX_SAFE_INTEGER,
|
|
417
|
-
timeout: GIT_TIMEOUT_MS,
|
|
418
|
-
windowsHide: true,
|
|
419
|
-
});
|
|
420
|
-
return new Uint8Array(stdout);
|
|
421
|
-
}
|
|
422
|
-
function gitEnvironment(overrides) {
|
|
423
|
-
const env = { ...process.env, GIT_OPTIONAL_LOCKS: '0', ...overrides };
|
|
424
|
-
delete env.GIT_DIR;
|
|
425
|
-
delete env.GIT_WORK_TREE;
|
|
426
|
-
delete env.GIT_COMMON_DIR;
|
|
427
|
-
if (overrides.GIT_INDEX_FILE === undefined)
|
|
428
|
-
delete env.GIT_INDEX_FILE;
|
|
429
|
-
return env;
|
|
401
|
+
async function runGitBytes(cwd, args, options = {}) {
|
|
402
|
+
return execGitBytes(cwd, args, options);
|
|
430
403
|
}
|
|
431
404
|
function gitExitCode(error) {
|
|
432
405
|
if (!error || typeof error !== 'object' || !('code' in error))
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { decodeGoalAuthorityRecord } from '@maka/core/goal';
|
|
20
20
|
import { acquireOperationalStateDatabase, } from './operational-state-store.js';
|
|
21
21
|
import { assertStorageRootLease, runWithStorageRootLease, StorageRootAuthorityError, } from './root-authority.js';
|
|
22
|
+
import { assertSafeStorageId } from './storage-id.js';
|
|
22
23
|
const writerBrand = Symbol('InteractiveGoalAuthorityWriter');
|
|
23
24
|
const writers = new WeakSet();
|
|
24
25
|
const writerByLease = new WeakMap();
|
|
@@ -217,6 +218,5 @@ function cloneSnapshot(snapshot) {
|
|
|
217
218
|
});
|
|
218
219
|
}
|
|
219
220
|
function requireId(value, label) {
|
|
220
|
-
|
|
221
|
-
throw new TypeError(`${label} identity is invalid`);
|
|
221
|
+
assertSafeStorageId(value, `${label} identity is invalid`);
|
|
222
222
|
}
|
|
@@ -22,7 +22,7 @@ import { clientCapabilityScopeIdentity, decodeClientCapabilitySessionGrant, deco
|
|
|
22
22
|
import { decodeInteractionCanonicalOutcome, decodeInteractionRequest, interactionCanonicalOutcomesEquivalent, isInteractionCanonicalOutcomeValidForRequest, projectInteractionFormRequest, projectInteractionQuestionRequest, } from '@maka/core/interaction';
|
|
23
23
|
import { assertStorageRootLease, runWithStorageRootLease, StorageRootAuthorityError, } from './root-authority.js';
|
|
24
24
|
import { acquireOperationalStateDatabase, } from './operational-state-store.js';
|
|
25
|
-
|
|
25
|
+
import { isSafeStorageId } from './storage-id.js';
|
|
26
26
|
const REMEMBER_SCOPE_ID = /^[0-9a-f]{64}$/;
|
|
27
27
|
export const STORED_INTERACTION_REQUEST_MAX_BYTES = 20 * 1024;
|
|
28
28
|
export const STORED_INTERACTION_OUTCOME_MAX_BYTES = 12 * 1024;
|
|
@@ -512,7 +512,7 @@ function identity(value) {
|
|
|
512
512
|
};
|
|
513
513
|
}
|
|
514
514
|
function assertId(value, source = 'input', message = 'Invalid Interaction identity') {
|
|
515
|
-
if (
|
|
515
|
+
if (!isSafeStorageId(value))
|
|
516
516
|
decodeFailure(source, message);
|
|
517
517
|
return value;
|
|
518
518
|
}
|
|
@@ -16,11 +16,15 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
20
|
-
import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
19
|
+
import { readFile } from 'node:fs/promises';
|
|
21
20
|
import { dirname, join } from 'node:path';
|
|
22
21
|
import { MCP_CONFIG_VERSION, createDefaultMcpConfig, isNonLoopbackCleartextHttp, } from '@maka/core/mcp';
|
|
22
|
+
import { writeAtomicFile } from './atomic-file-write.js';
|
|
23
23
|
import { withProcessLifetimeFileUpdateLock } from './process-lifetime-file-update-lock.js';
|
|
24
|
+
import { hardenDirectory } from './stable-storage.js';
|
|
25
|
+
// Consumers reconcile an already-published write through this store's public
|
|
26
|
+
// boundary; the shared atomic writer itself remains internal to storage.
|
|
27
|
+
export { AtomicFileWriteCommitUnknownError } from './atomic-file-write.js';
|
|
24
28
|
const MAX_SERVERS = 100;
|
|
25
29
|
const MAX_ID_LENGTH = 128;
|
|
26
30
|
const MAX_STRING_LENGTH = 8_192;
|
|
@@ -157,34 +161,15 @@ class FileMcpConfigStore {
|
|
|
157
161
|
return withProcessLifetimeFileUpdateLock(this.path, operation);
|
|
158
162
|
}
|
|
159
163
|
async write(config) {
|
|
160
|
-
const dir = dirname(this.path);
|
|
161
164
|
await this.ensureDirectory();
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
encoding: 'utf8',
|
|
166
|
-
mode: 0o600,
|
|
167
|
-
flag: 'wx',
|
|
168
|
-
});
|
|
169
|
-
if (process.platform !== 'win32')
|
|
170
|
-
await chmod(tempPath, 0o600);
|
|
171
|
-
await rename(tempPath, this.path);
|
|
172
|
-
if (process.platform !== 'win32')
|
|
173
|
-
await chmod(this.path, 0o600);
|
|
174
|
-
}
|
|
175
|
-
finally {
|
|
176
|
-
await rm(tempPath, { force: true }).catch(() => { });
|
|
177
|
-
}
|
|
165
|
+
await writeAtomicFile(this.path, `${JSON.stringify(config, null, 2)}\n`, {
|
|
166
|
+
fileMode: 0o600,
|
|
167
|
+
});
|
|
178
168
|
}
|
|
179
169
|
ensureDirectory() {
|
|
180
170
|
if (this.directoryReady)
|
|
181
171
|
return this.directoryReady;
|
|
182
|
-
const
|
|
183
|
-
const ready = (async () => {
|
|
184
|
-
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
185
|
-
if (process.platform !== 'win32')
|
|
186
|
-
await chmod(dir, 0o700);
|
|
187
|
-
})();
|
|
172
|
+
const ready = hardenDirectory(dirname(this.path), 0o700);
|
|
188
173
|
this.directoryReady = ready;
|
|
189
174
|
void ready.catch(() => {
|
|
190
175
|
if (this.directoryReady === ready)
|
|
@@ -16,16 +16,14 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { execFile } from 'node:child_process';
|
|
20
19
|
import { randomUUID } from 'node:crypto';
|
|
21
20
|
import { realpath, stat } from 'node:fs/promises';
|
|
22
21
|
import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep } from 'node:path';
|
|
23
|
-
import { promisify } from 'node:util';
|
|
24
22
|
import { markPersisted } from '@maka/core/persisted-value';
|
|
23
|
+
import { execGitText } from './git-exec.js';
|
|
25
24
|
import { hasEnclosingGitEntry } from './git-entry.js';
|
|
26
25
|
import { acquireOperationalStateDatabase, } from './operational-state-store.js';
|
|
27
26
|
import { decodePersistedSessionHeader, normalizeSessionHeader } from './session-store.js';
|
|
28
|
-
const execFileAsync = promisify(execFile);
|
|
29
27
|
export class ProjectPathMismatchError extends Error {
|
|
30
28
|
projectId;
|
|
31
29
|
path;
|
|
@@ -690,26 +688,7 @@ function isPathWithin(root, candidate) {
|
|
|
690
688
|
return path === '' || (!isAbsolute(path) && path !== '..' && !path.startsWith(`..${sep}`));
|
|
691
689
|
}
|
|
692
690
|
async function resolveGitLocation(canonicalPath) {
|
|
693
|
-
const
|
|
694
|
-
delete env.GIT_DIR;
|
|
695
|
-
delete env.GIT_WORK_TREE;
|
|
696
|
-
delete env.GIT_INDEX_FILE;
|
|
697
|
-
delete env.GIT_COMMON_DIR;
|
|
698
|
-
const { stdout: locationOutput } = await execFileAsync('git', [
|
|
699
|
-
'-C',
|
|
700
|
-
canonicalPath,
|
|
701
|
-
'rev-parse',
|
|
702
|
-
'--path-format=absolute',
|
|
703
|
-
'--show-toplevel',
|
|
704
|
-
'--git-dir',
|
|
705
|
-
'--git-common-dir',
|
|
706
|
-
], {
|
|
707
|
-
env,
|
|
708
|
-
encoding: 'utf8',
|
|
709
|
-
maxBuffer: 64 * 1024,
|
|
710
|
-
timeout: 3_000,
|
|
711
|
-
windowsHide: true,
|
|
712
|
-
});
|
|
691
|
+
const locationOutput = await execGitText(canonicalPath, ['rev-parse', '--path-format=absolute', '--show-toplevel', '--git-dir', '--git-common-dir'], { maxBuffer: 64 * 1024, timeoutMs: 3_000 });
|
|
713
692
|
const [worktreeRootRaw, gitDirRaw, commonDirRaw] = locationOutput.trim().split(/\r?\n/);
|
|
714
693
|
if (!worktreeRootRaw || !gitDirRaw || !commonDirRaw) {
|
|
715
694
|
throw new Error(`Git returned an incomplete project location for: ${canonicalPath}`);
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
import { isSafeStorageId } from './storage-id.js';
|
|
20
20
|
export function isRuntimeStorageSafeId(value) {
|
|
21
|
-
return
|
|
21
|
+
return isSafeStorageId(value);
|
|
22
22
|
}
|
|
23
23
|
export function immutableSteeringMessageId(event) {
|
|
24
24
|
const messageId = event.refs?.providerEventId;
|
|
@@ -20,7 +20,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
20
20
|
import { isDeepStrictEqual } from 'node:util';
|
|
21
21
|
import { CONNECTION_CATALOG_MAX_CONNECTIONS, decodeCanonicalConnectionCatalogEntry, decodeConnectionName, decodeConnectionSlug, decodeConnectionTarget, decodeConnectionTestSummary, decodeProviderType, decodeRuntimePolicyEntityId, normalizeConnectionCatalogEntryUpdateForProvider, normalizeConnectionModelDiscoveryResult, normalizeCreateCatalogConnectionInput, normalizeRemoveCatalogConnectionInput, normalizeSetDefaultConnectionTargetInput, normalizeUpdateCatalogConnectionInput, } from '@maka/core/runtime-policy';
|
|
22
22
|
import { PROVIDER_REGISTRY, reconcileConnectionAfterModelFetch } from '@maka/core/llm-connections';
|
|
23
|
-
import { modelIdAliasesForProvider } from '@maka/core/model-metadata';
|
|
23
|
+
import { modelIdAliasesForProvider, providerReportsCompleteModelCatalog, } from '@maka/core/model-metadata';
|
|
24
24
|
import { isRetiredProvider } from '@maka/core/provider-registry';
|
|
25
25
|
import { pruneRelayModelProfiles } from '@maka/core/model-thinking';
|
|
26
26
|
import { deepFreeze, nextRevision, record, revision, unique } from './codec.js';
|
|
@@ -325,14 +325,19 @@ export class ConnectionCatalogDocumentOwner {
|
|
|
325
325
|
hasModelInventory: previous.models.length > 0,
|
|
326
326
|
}, result.models, {
|
|
327
327
|
aliases: modelIdAliasesForProvider(previous.providerType),
|
|
328
|
+
authoritative: providerReportsCompleteModelCatalog(previous.providerType),
|
|
328
329
|
});
|
|
329
330
|
// Discovery MOVES a target: a provider's model rename carries the default
|
|
330
331
|
// across by alias. A default outside the selection the reconciler just
|
|
331
332
|
// decided is its own bug — fail closed where it is still attributable.
|
|
332
333
|
const defaultTarget = currentDefaultTarget
|
|
333
|
-
?
|
|
334
|
+
? reconciled.defaultModel
|
|
335
|
+
? { connectionId: previous.connectionId, modelId: reconciled.defaultModel }
|
|
336
|
+
: null
|
|
334
337
|
: current.defaultTarget;
|
|
335
|
-
if (currentDefaultTarget &&
|
|
338
|
+
if (currentDefaultTarget &&
|
|
339
|
+
reconciled.defaultModel &&
|
|
340
|
+
!reconciled.enabledModelIds.includes(reconciled.defaultModel)) {
|
|
336
341
|
throw codecError('invalid_document', 'Model discovery reconciled a default outside its own selection');
|
|
337
342
|
}
|
|
338
343
|
// A refresh only ever migrates a renamed id now, but that rename still
|