@myagentroam/node 0.9.62 → 0.9.65
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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/dist/capabilities.js +110 -2
- package/dist/claude-agent-sdk.js +330 -2
- package/dist/claude-channel.js +44 -2
- package/dist/codex-app-server.js +510 -2
- package/dist/config.js +106 -2
- package/dist/connector/node-connector-options.js +1 -2
- package/dist/connector/node-operation-router.js +22 -2
- package/dist/connector.js +1736 -2
- package/dist/control-outbound-scheduler.js +153 -2
- package/dist/database.js +639 -2
- package/dist/fake-runner.js +129 -2
- package/dist/git-askpass.js +12 -0
- package/dist/git-execution-helper.js +266 -0
- package/dist/health.js +3 -2
- package/dist/main.js +57 -2
- package/dist/mcp-installation-model.js +1 -2
- package/dist/migrations/v004.js +55 -3
- package/dist/migrations/v005.js +13 -3
- package/dist/migrations/v006.js +90 -3
- package/dist/migrations/v007.js +22 -3
- package/dist/migrations/v008.js +18 -3
- package/dist/migrations/v009.js +70 -4
- package/dist/migrations/v010.js +43 -3
- package/dist/migrations/v011.js +20 -3
- package/dist/migrations/v012.js +8 -0
- package/dist/native-jsonl-reader.js +186 -2
- package/dist/native-session-history.js +1143 -2
- package/dist/opencode-runtime.js +80 -2
- package/dist/opencode-server.js +259 -2
- package/dist/operational.js +122 -2
- package/dist/process-tree.js +18 -2
- package/dist/ripgrep-binary.js +31 -2
- package/dist/rotating-log.js +67 -2
- package/dist/runner/abstract-runner.js +260 -2
- package/dist/runner/claude/managed-run-controller.js +355 -2
- package/dist/runner/claude/tool-normalizer.js +120 -2
- package/dist/runner/claude-code-runner.js +303 -2
- package/dist/runner/codex/composer-image-markers.js +8 -2
- package/dist/runner/codex/conversation-parser.js +913 -2
- package/dist/runner/codex/managed-run-controller.js +494 -2
- package/dist/runner/codex/tool-normalizer.js +214 -2
- package/dist/runner/codex-runner.js +585 -2
- package/dist/runner/fake-test-runner.js +47 -2
- package/dist/runner/mar-agent/conversation-normalizer.js +644 -2
- package/dist/runner/mar-agent/executor-stdio-client-transport.js +139 -2
- package/dist/runner/mar-agent/generated-images.js +41 -2
- package/dist/runner/mar-agent/history-projection.js +106 -2
- package/dist/runner/mar-agent/hosted-conversation-runtime.js +446 -2
- package/dist/runner/mar-agent/managed-run-controller.js +785 -2
- package/dist/runner/mar-agent/mcp-client-pool.js +233 -2
- package/dist/runner/mar-agent/runtime-model-factory.js +326 -2
- package/dist/runner/mar-agent-runner.js +458 -2
- package/dist/runner/opencode/conversation-parser.js +221 -2
- package/dist/runner/opencode/managed-run-controller.js +588 -2
- package/dist/runner/opencode/tool-normalizer.js +80 -2
- package/dist/runner/opencode-runner.js +426 -2
- package/dist/runner/runner-registry.js +87 -2
- package/dist/runner-command-engine.js +71 -2
- package/dist/runner-profiles.js +323 -2
- package/dist/runner-usage.js +190 -2
- package/dist/runtime-command-detector.js +73 -2
- package/dist/runtime-model.js +1 -2
- package/dist/runtime-state.js +1509 -2
- package/dist/service/attachment-domain-state.js +7 -2
- package/dist/service/bubblewrap-sandbox-executor.js +543 -2
- package/dist/service/continuous-run-coordinator.js +425 -2
- package/dist/service/conversation-history-service.js +552 -2
- package/dist/service/conversation-hosting-capability-service.js +61 -2
- package/dist/service/conversation-hosting-enablement-service.js +91 -2
- package/dist/service/conversation-hosting-maintenance-service.js +174 -2
- package/dist/service/conversation-segment-service.js +162 -2
- package/dist/service/conversation-template-node-service.js +992 -2
- package/dist/service/external-session-resume-service.js +152 -2
- package/dist/service/fake-managed-run-service.js +60 -2
- package/dist/service/git-execution-service.js +418 -0
- package/dist/service/git-operation-service.js +57 -0
- package/dist/service/hosted-conversation-node-service.js +1982 -2
- package/dist/service/hosted-conversation-store.js +1405 -2
- package/dist/service/managed-runner-session-service.js +35 -2
- package/dist/service/mar-agent-model-transport-test-service.js +88 -2
- package/dist/service/mcp-installation-verifier.js +87 -2
- package/dist/service/mcp-node-operation-service.js +90 -2
- package/dist/service/mission-mcp-server.js +124 -2
- package/dist/service/mission-mcp-stdio.js +40 -2
- package/dist/service/mission-runtime.js +142 -2
- package/dist/service/native-session-projection-service.js +274 -2
- package/dist/service/native-session-watch-service.js +683 -2
- package/dist/service/node-connection-lifecycle-service.js +88 -2
- package/dist/service/node-control-channel.js +85 -2
- package/dist/service/node-control-message-service.js +109 -2
- package/dist/service/node-request-service.js +62 -2
- package/dist/service/node-run-event-bridge.js +88 -2
- package/dist/service/node-terminal-channel.js +202 -2
- package/dist/service/node-upgrade-coordinator.js +137 -2
- package/dist/service/node-workspace-coordinator.js +97 -2
- package/dist/service/recent-run-projection-service.js +99 -2
- package/dist/service/run-attachment-service.js +321 -2
- package/dist/service/run-domain-state.js +4 -2
- package/dist/service/run-event-service.js +246 -2
- package/dist/service/run-ownership-policy.js +22 -2
- package/dist/service/run-workbench-service.js +120 -2
- package/dist/service/runner-channel-message-service.js +20 -2
- package/dist/service/runner-interaction-service.js +243 -2
- package/dist/service/runner-service.js +69 -2
- package/dist/service/runtime-credential-control-service.js +95 -2
- package/dist/service/session-catalog-service.js +404 -2
- package/dist/service/session-command-service.js +125 -2
- package/dist/service/session-context-service.js +128 -2
- package/dist/service/session-domain-state.js +9 -2
- package/dist/service/session-identity-service.js +86 -2
- package/dist/service/session-lifecycle-service.js +248 -2
- package/dist/service/session-message-service.js +270 -2
- package/dist/service/session-presentation-service.js +43 -2
- package/dist/service/session-query-service.js +82 -2
- package/dist/service/session-watch-slot-coordinator.js +21 -2
- package/dist/service/skill-directory-service.js +238 -2
- package/dist/service/skill-install-service.js +434 -2
- package/dist/service/skill-node-operation-service.js +206 -2
- package/dist/service/terminal-relay-state.js +3 -2
- package/dist/service/terminal-service.js +90 -2
- package/dist/service/web-search-error.js +40 -2
- package/dist/service/workbench-event-service.js +21 -2
- package/dist/service/workbench-manifest-service.js +69 -2
- package/dist/service/workspace-change-service.js +290 -2
- package/dist/service/workspace-content-search-service.js +457 -2
- package/dist/service/workspace-domain-state.js +41 -2
- package/dist/service/workspace-file-service.js +150 -2
- package/dist/service/workspace-git-exclude-service.js +119 -2
- package/dist/service/workspace-queue-workbench-service.js +176 -2
- package/dist/service/workspace-service.js +92 -2
- package/dist/service/workspace-session-service.js +154 -2
- package/dist/service/workspace-upload-service.js +262 -2
- package/dist/service/workspace-watch-controller.js +68 -2
- package/dist/service/workspace-watch-service.js +170 -2
- package/dist/service/workspace-watch-snapshot-service.js +218 -2
- package/dist/service/workspace-workbench-service.js +239 -2
- package/dist/service.js +91 -2
- package/dist/storage.js +32 -2
- package/dist/supervisor.js +136 -2
- package/dist/terminal.js +496 -2
- package/dist/util/git-credential-client.js +32 -0
- package/dist/util/node-operation-data.js +9 -2
- package/dist/util/node-operation-parsers.js +382 -2
- package/dist/util/personal-instructions.js +34 -2
- package/dist/util/runner-error.js +70 -2
- package/dist/util/runner-native-session-parsers.js +510 -2
- package/dist/util/safe-error.js +8 -2
- package/dist/util/secret-environment.js +25 -2
- package/dist/workspace.js +1793 -2
- package/package.json +11 -8
- package/vendor/ripgrep/darwin-arm64/rg +0 -0
- package/vendor/ripgrep/darwin-x64/rg +0 -0
- package/vendor/ripgrep/manifest.json +12 -0
- package/README.md +0 -42
- package/dist/event-buffer.js +0 -2
- package/dist/migrations/v001.js +0 -107
- package/dist/migrations/v002.js +0 -2
- package/dist/migrations/v003.js +0 -2
- package/dist/service/mcp-package-installer.js +0 -2
package/dist/migrations/v006.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V6 = 6;
|
|
2
|
+
/** Adds rebuildable hosted-conversation indexes and immutable template publication metadata. */
|
|
3
|
+
export const NODE_SCHEMA_MIGRATION_V6 = String.raw `
|
|
3
4
|
CREATE TABLE conversation_template_versions (
|
|
4
5
|
id TEXT PRIMARY KEY,
|
|
5
6
|
template_id TEXT NOT NULL,
|
|
@@ -101,4 +102,90 @@ const _0x31fb0d=_0x3fa8;(function(_0x4c57ca,_0x56554d){const _0xfb5c96=_0x3fa8,_
|
|
|
101
102
|
updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
|
|
102
103
|
PRIMARY KEY (conversation_id, client_message_id)
|
|
103
104
|
) STRICT;
|
|
104
|
-
`;
|
|
105
|
+
`;
|
|
106
|
+
export function assertNodeSchemaV6(database) {
|
|
107
|
+
const required = {
|
|
108
|
+
conversation_template_versions: [
|
|
109
|
+
'id',
|
|
110
|
+
'template_id',
|
|
111
|
+
'version_number',
|
|
112
|
+
'draft_revision',
|
|
113
|
+
'status',
|
|
114
|
+
'storage_key',
|
|
115
|
+
'manifest',
|
|
116
|
+
'content_hash',
|
|
117
|
+
'manifest_hash',
|
|
118
|
+
'file_count',
|
|
119
|
+
'total_bytes',
|
|
120
|
+
'host_policy_version',
|
|
121
|
+
'published_by_user_id',
|
|
122
|
+
'published_at',
|
|
123
|
+
'reference_count'
|
|
124
|
+
],
|
|
125
|
+
conversation_template_publish_jobs: [
|
|
126
|
+
'id',
|
|
127
|
+
'template_id',
|
|
128
|
+
'draft_revision',
|
|
129
|
+
'stage',
|
|
130
|
+
'status',
|
|
131
|
+
'version_id',
|
|
132
|
+
'error_code',
|
|
133
|
+
'error_summary',
|
|
134
|
+
'requested_by_user_id',
|
|
135
|
+
'draft',
|
|
136
|
+
'created_at',
|
|
137
|
+
'updated_at'
|
|
138
|
+
],
|
|
139
|
+
hosted_conversations: [
|
|
140
|
+
'id',
|
|
141
|
+
'user_storage_key',
|
|
142
|
+
'conversation_storage_key',
|
|
143
|
+
'client_request_id',
|
|
144
|
+
'node_id',
|
|
145
|
+
'session_id',
|
|
146
|
+
'template_id',
|
|
147
|
+
'template_name',
|
|
148
|
+
'active_version_id',
|
|
149
|
+
'pending_version_id',
|
|
150
|
+
'title',
|
|
151
|
+
'status',
|
|
152
|
+
'model_id',
|
|
153
|
+
'reasoning_effort',
|
|
154
|
+
'template_deleted',
|
|
155
|
+
'recoverable_until',
|
|
156
|
+
'used_bytes',
|
|
157
|
+
'max_bytes',
|
|
158
|
+
'created_at',
|
|
159
|
+
'updated_at',
|
|
160
|
+
'last_activity_at'
|
|
161
|
+
],
|
|
162
|
+
conversation_files: [
|
|
163
|
+
'id',
|
|
164
|
+
'conversation_id',
|
|
165
|
+
'category',
|
|
166
|
+
'relative_path',
|
|
167
|
+
'display_name',
|
|
168
|
+
'mime_type',
|
|
169
|
+
'size',
|
|
170
|
+
'source',
|
|
171
|
+
'turn_id',
|
|
172
|
+
'item_id',
|
|
173
|
+
'created_at',
|
|
174
|
+
'updated_at'
|
|
175
|
+
],
|
|
176
|
+
hosted_conversation_messages: [
|
|
177
|
+
'conversation_id',
|
|
178
|
+
'client_message_id',
|
|
179
|
+
'run_id',
|
|
180
|
+
'status',
|
|
181
|
+
'created_at',
|
|
182
|
+
'updated_at'
|
|
183
|
+
]
|
|
184
|
+
};
|
|
185
|
+
for (const [table, expected] of Object.entries(required)) {
|
|
186
|
+
const columns = database.prepare(`PRAGMA table_info(${table})`).all();
|
|
187
|
+
const actual = columns.map((column) => column.name);
|
|
188
|
+
if (actual.length !== expected.length || expected.some((name) => !actual.includes(name)))
|
|
189
|
+
throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
package/dist/migrations/v007.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V7 = 7;
|
|
2
|
+
export const EMPTY_MCP_CONFIG_HASH = '4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945';
|
|
3
|
+
/** Adds immutable MCP fingerprints and removes the retired hosted reasoning preference. */
|
|
4
|
+
export const NODE_SCHEMA_MIGRATION_V7 = String.raw `
|
|
3
5
|
ALTER TABLE conversation_template_versions
|
|
4
6
|
ADD COLUMN mcp_config_hash TEXT NOT NULL DEFAULT '${EMPTY_MCP_CONFIG_HASH}'
|
|
5
7
|
CHECK (length(mcp_config_hash) = 64);
|
|
@@ -30,4 +32,21 @@ const _0x201d71=_0x3969;(function(_0x3b271f,_0x43efcb){const _0x34ac54=_0x3969,_
|
|
|
30
32
|
ALTER TABLE conversation_files_v7 RENAME TO conversation_files;
|
|
31
33
|
CREATE INDEX conversation_files_conversation_updated
|
|
32
34
|
ON conversation_files(conversation_id, updated_at DESC, id);
|
|
33
|
-
`;
|
|
35
|
+
`;
|
|
36
|
+
export function assertNodeSchemaV7(database) {
|
|
37
|
+
const templateColumns = database
|
|
38
|
+
.prepare('PRAGMA table_info(conversation_template_versions)')
|
|
39
|
+
.all();
|
|
40
|
+
if (!templateColumns.some((column) => column.name === 'mcp_config_hash'))
|
|
41
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:conversation_template_versions');
|
|
42
|
+
const conversationColumns = database.prepare('PRAGMA table_info(hosted_conversations)').all();
|
|
43
|
+
if (conversationColumns === undefined ||
|
|
44
|
+
conversationColumns.some((column) => column.name === 'reasoning_effort'))
|
|
45
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
46
|
+
const conversationFiles = database
|
|
47
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='conversation_files'")
|
|
48
|
+
.get();
|
|
49
|
+
if (typeof conversationFiles?.sql !== 'string' ||
|
|
50
|
+
!conversationFiles.sql.includes("category IN ('UPLOAD','OUTPUT')"))
|
|
51
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:conversation_files');
|
|
52
|
+
}
|
package/dist/migrations/v008.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V8 = 8;
|
|
2
|
+
/** Adds hosted conversation pin metadata and its authoritative list order. */
|
|
3
|
+
export const NODE_SCHEMA_MIGRATION_V8 = String.raw `
|
|
3
4
|
ALTER TABLE hosted_conversations
|
|
4
5
|
ADD COLUMN pinned_at INTEGER CHECK (pinned_at IS NULL OR pinned_at >= 0);
|
|
5
6
|
DROP INDEX hosted_conversations_user_activity;
|
|
@@ -10,4 +11,18 @@ const _0x6b3905=_0xd039;(function(_0x81287e,_0x24e40a){const _0x2f4ba8=_0xd039,_
|
|
|
10
11
|
last_activity_at DESC,
|
|
11
12
|
id DESC
|
|
12
13
|
);
|
|
13
|
-
`;
|
|
14
|
+
`;
|
|
15
|
+
export function assertNodeSchemaV8(database) {
|
|
16
|
+
const conversationColumns = database
|
|
17
|
+
.prepare('PRAGMA table_info(hosted_conversations)')
|
|
18
|
+
.all();
|
|
19
|
+
if (!conversationColumns.some((column) => column.name === 'pinned_at'))
|
|
20
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
21
|
+
const index = database
|
|
22
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='index' AND name='hosted_conversations_user_pin_activity'")
|
|
23
|
+
.get();
|
|
24
|
+
if (typeof index?.sql !== 'string' ||
|
|
25
|
+
!index.sql.includes('(pinned_at IS NOT NULL) DESC') ||
|
|
26
|
+
!index.sql.includes('last_activity_at DESC'))
|
|
27
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
28
|
+
}
|
package/dist/migrations/v009.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V9 = 9;
|
|
2
|
+
/**
|
|
3
|
+
* Persists title/message metadata, removes recovery states, and restores failed upgrades to the
|
|
4
|
+
* active version. This unreleased migration is the single boundary from v8.
|
|
5
|
+
*/
|
|
6
|
+
const NODE_SCHEMA_MIGRATION_V9_METADATA = String.raw `
|
|
3
7
|
ALTER TABLE hosted_conversations
|
|
4
8
|
ADD COLUMN title_source TEXT NOT NULL DEFAULT 'CUSTOM'
|
|
5
9
|
CHECK (title_source IN ('AUTO','CUSTOM'));
|
|
@@ -7,7 +11,8 @@ function _0x2940(){const _0x21346e=['ufjbr01bigzVCMvPz25FA2v5CW','uKvdt1zfuKfcte
|
|
|
7
11
|
ALTER TABLE hosted_conversation_messages
|
|
8
12
|
ADD COLUMN user_text_present INTEGER NOT NULL DEFAULT 1
|
|
9
13
|
CHECK (user_text_present IN (0,1));
|
|
10
|
-
`;
|
|
14
|
+
`;
|
|
15
|
+
export const NODE_SCHEMA_MIGRATION_V9_FINALIZE = String.raw `
|
|
11
16
|
DELETE FROM conversation_files
|
|
12
17
|
WHERE conversation_id IN (
|
|
13
18
|
SELECT id
|
|
@@ -94,4 +99,65 @@ function _0x2940(){const _0x21346e=['ufjbr01bigzVCMvPz25FA2v5CW','uKvdt1zfuKfcte
|
|
|
94
99
|
);
|
|
95
100
|
CREATE INDEX hosted_conversations_template
|
|
96
101
|
ON hosted_conversations(template_id, status, id);
|
|
97
|
-
`;
|
|
102
|
+
`;
|
|
103
|
+
export const NODE_SCHEMA_MIGRATION_V9 = `${NODE_SCHEMA_MIGRATION_V9_METADATA}\n${NODE_SCHEMA_MIGRATION_V9_FINALIZE}`;
|
|
104
|
+
export function isDraftNodeSchemaV9(database) {
|
|
105
|
+
const conversationColumns = database
|
|
106
|
+
.prepare('PRAGMA table_info(hosted_conversations)')
|
|
107
|
+
.all();
|
|
108
|
+
const titleSource = conversationColumns.find((column) => column.name === 'title_source');
|
|
109
|
+
const conversationTable = database
|
|
110
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
|
|
111
|
+
.get();
|
|
112
|
+
const messageColumns = database
|
|
113
|
+
.prepare('PRAGMA table_info(hosted_conversation_messages)')
|
|
114
|
+
.all();
|
|
115
|
+
const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
|
|
116
|
+
return (titleSource?.notnull === 1 &&
|
|
117
|
+
titleSource.dflt_value === "'CUSTOM'" &&
|
|
118
|
+
conversationColumns.some((column) => column.name === 'recoverable_until') &&
|
|
119
|
+
conversationColumns.some((column) => column.name === 'pinned_at') &&
|
|
120
|
+
!conversationColumns.some((column) => column.name === 'reasoning_effort') &&
|
|
121
|
+
typeof conversationTable?.sql === 'string' &&
|
|
122
|
+
conversationTable.sql.includes("status IN ('ACTIVE','UPGRADE_PENDING','UPGRADE_FAILED','RECOVERABLE_DELETED','DELETING')") &&
|
|
123
|
+
userTextPresent?.notnull === 1 &&
|
|
124
|
+
userTextPresent.dflt_value === '1');
|
|
125
|
+
}
|
|
126
|
+
export function assertNodeSchemaV9(database) {
|
|
127
|
+
const conversationColumns = database
|
|
128
|
+
.prepare('PRAGMA table_info(hosted_conversations)')
|
|
129
|
+
.all();
|
|
130
|
+
const titleSource = conversationColumns.find((column) => column.name === 'title_source');
|
|
131
|
+
if (titleSource?.notnull !== 1 ||
|
|
132
|
+
titleSource.dflt_value !== "'CUSTOM'" ||
|
|
133
|
+
conversationColumns.some((column) => column.name === 'recoverable_until'))
|
|
134
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
135
|
+
const conversationTable = database
|
|
136
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
|
|
137
|
+
.get();
|
|
138
|
+
if (typeof conversationTable?.sql !== 'string' ||
|
|
139
|
+
!conversationTable.sql.includes("status IN ('ACTIVE','UPGRADE_PENDING')") ||
|
|
140
|
+
conversationTable.sql.includes('UPGRADE_FAILED') ||
|
|
141
|
+
conversationTable.sql.includes('RECOVERABLE_DELETED') ||
|
|
142
|
+
conversationTable.sql.includes('DELETING'))
|
|
143
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
144
|
+
const messageColumns = database
|
|
145
|
+
.prepare('PRAGMA table_info(hosted_conversation_messages)')
|
|
146
|
+
.all();
|
|
147
|
+
const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
|
|
148
|
+
if (userTextPresent?.notnull !== 1 || userTextPresent.dflt_value !== '1')
|
|
149
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversation_messages');
|
|
150
|
+
const foreignKeys = database.prepare('PRAGMA foreign_keys').get();
|
|
151
|
+
if (foreignKeys?.foreign_keys !== 1)
|
|
152
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
|
|
153
|
+
if (database.prepare('PRAGMA foreign_key_check(hosted_conversations)').get() !== undefined)
|
|
154
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
|
|
155
|
+
for (const table of ['conversation_files', 'hosted_conversation_messages']) {
|
|
156
|
+
const foreignKeys = database.prepare(`PRAGMA foreign_key_list(${table})`).all();
|
|
157
|
+
if (!foreignKeys.some((foreignKey) => foreignKey.table === 'hosted_conversations' &&
|
|
158
|
+
foreignKey.from === 'conversation_id' &&
|
|
159
|
+
foreignKey.to === 'id' &&
|
|
160
|
+
foreignKey.on_delete === 'CASCADE'))
|
|
161
|
+
throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
package/dist/migrations/v010.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V10 = 10;
|
|
2
|
+
/** Removes persistent hosted-conversation upgrade scheduling state. */
|
|
3
|
+
export const NODE_SCHEMA_MIGRATION_V10 = String.raw `
|
|
3
4
|
UPDATE conversation_template_versions
|
|
4
5
|
SET reference_count = (
|
|
5
6
|
SELECT COUNT(*)
|
|
@@ -53,4 +54,43 @@ const _0x49a32c=_0x53fb;(function(_0x4af5a2,_0x4dc189){const _0xe730c7=_0x53fb,_
|
|
|
53
54
|
);
|
|
54
55
|
CREATE INDEX hosted_conversations_template
|
|
55
56
|
ON hosted_conversations(template_id, status, id);
|
|
56
|
-
`;
|
|
57
|
+
`;
|
|
58
|
+
export function assertNodeSchemaV10(database) {
|
|
59
|
+
const conversationColumns = database
|
|
60
|
+
.prepare('PRAGMA table_info(hosted_conversations)')
|
|
61
|
+
.all();
|
|
62
|
+
const titleSource = conversationColumns.find((column) => column.name === 'title_source');
|
|
63
|
+
if (titleSource?.notnull !== 1 ||
|
|
64
|
+
titleSource.dflt_value !== "'CUSTOM'" ||
|
|
65
|
+
conversationColumns.some((column) => column.name === 'pending_version_id' || column.name === 'recoverable_until'))
|
|
66
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
67
|
+
const conversationTable = database
|
|
68
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
|
|
69
|
+
.get();
|
|
70
|
+
if (typeof conversationTable?.sql !== 'string' ||
|
|
71
|
+
!conversationTable.sql.includes("status IN ('ACTIVE')") ||
|
|
72
|
+
conversationTable.sql.includes('UPGRADE_PENDING') ||
|
|
73
|
+
conversationTable.sql.includes('UPGRADE_FAILED') ||
|
|
74
|
+
conversationTable.sql.includes('RECOVERABLE_DELETED') ||
|
|
75
|
+
conversationTable.sql.includes('DELETING'))
|
|
76
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
77
|
+
const messageColumns = database
|
|
78
|
+
.prepare('PRAGMA table_info(hosted_conversation_messages)')
|
|
79
|
+
.all();
|
|
80
|
+
const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
|
|
81
|
+
if (userTextPresent?.notnull !== 1 || userTextPresent.dflt_value !== '1')
|
|
82
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversation_messages');
|
|
83
|
+
const foreignKeys = database.prepare('PRAGMA foreign_keys').get();
|
|
84
|
+
if (foreignKeys?.foreign_keys !== 1)
|
|
85
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
|
|
86
|
+
if (database.prepare('PRAGMA foreign_key_check(hosted_conversations)').get() !== undefined)
|
|
87
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
|
|
88
|
+
for (const table of ['conversation_files', 'hosted_conversation_messages']) {
|
|
89
|
+
const foreignKeys = database.prepare(`PRAGMA foreign_key_list(${table})`).all();
|
|
90
|
+
if (!foreignKeys.some((foreignKey) => foreignKey.table === 'hosted_conversations' &&
|
|
91
|
+
foreignKey.from === 'conversation_id' &&
|
|
92
|
+
foreignKey.to === 'id' &&
|
|
93
|
+
foreignKey.on_delete === 'CASCADE'))
|
|
94
|
+
throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
package/dist/migrations/v011.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V11 = 11;
|
|
2
|
+
/** Adds the fixed localized-display marker for new hosted conversations. */
|
|
3
|
+
export const NODE_SCHEMA_MIGRATION_V11 = String.raw `
|
|
3
4
|
CREATE TABLE hosted_conversations_v11 (
|
|
4
5
|
id TEXT PRIMARY KEY,
|
|
5
6
|
user_storage_key TEXT NOT NULL,
|
|
@@ -47,4 +48,20 @@ const _0x403d69=_0x4b15;(function(_0x511a6e,_0xb02a3b){const _0x38de64=_0x4b15,_
|
|
|
47
48
|
);
|
|
48
49
|
CREATE INDEX hosted_conversations_template
|
|
49
50
|
ON hosted_conversations(template_id, status, id);
|
|
50
|
-
`;
|
|
51
|
+
`;
|
|
52
|
+
export function assertNodeSchemaV11(database) {
|
|
53
|
+
const conversationColumns = database
|
|
54
|
+
.prepare('PRAGMA table_info(hosted_conversations)')
|
|
55
|
+
.all();
|
|
56
|
+
const titleSource = conversationColumns.find((column) => column.name === 'title_source');
|
|
57
|
+
const conversationTable = database
|
|
58
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
|
|
59
|
+
.get();
|
|
60
|
+
if (titleSource?.notnull !== 1 ||
|
|
61
|
+
titleSource.dflt_value !== "'CUSTOM'" ||
|
|
62
|
+
typeof conversationTable?.sql !== 'string' ||
|
|
63
|
+
!conversationTable.sql.includes("title_source IN ('DEFAULT','AUTO','CUSTOM')"))
|
|
64
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
|
|
65
|
+
if (database.prepare('PRAGMA foreign_key_check(hosted_conversations)').get() !== undefined)
|
|
66
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
|
|
67
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const NODE_SCHEMA_VERSION_V12 = 12;
|
|
2
|
+
export const NODE_SCHEMA_MIGRATION_V12 = 'ALTER TABLE workspaces ADD COLUMN preserve_git_config INTEGER NOT NULL DEFAULT 1 CHECK (preserve_git_config IN (0,1));';
|
|
3
|
+
export function assertNodeSchemaV12(database) {
|
|
4
|
+
const columns = database.prepare('PRAGMA table_info(workspaces)').all();
|
|
5
|
+
const column = columns.find((value) => value.name === 'preserve_git_config');
|
|
6
|
+
if (column?.notnull !== 1 || column.dflt_value !== '1')
|
|
7
|
+
throw new Error('NODE_DATABASE_SCHEMA_INVALID:workspaces');
|
|
8
|
+
}
|
|
@@ -1,2 +1,186 @@
|
|
|
1
|
-
|
|
2
|
-
function _0xb187(){const _0x144535=['C3rHDa','BMfTzq','AxneAxjLy3rVCNK','yMfZzty0DxjS','C2HHmJu2','CgfYC2u','ndyZnJb1te9WCue','BgvUz3rO','mZqZotuXnK9NBNz4ua','ywXSB2nvBNnHzMu','DgfYz2v0tgLUzxm','yw5JAg9YqNL0zxm','zw5KC1DPDgG','y2XVC2u','mtq0u3P1y1Hj','C2L6zq','CgfNzq','CMvHza','ywXS','Bwf4','lMPZB25S','nujsrfDfta','B2jQzwn0','zgLNzxn0','C2XPy2u','BMv4DevUza','C3vIyxjYyxK','C25HChnOB3rfBMq','nJC5ota4uxLntM1R','zNjVBq','mJeWmZCZog5RqvHJyW','DxbKyxrL','ndG4otm1meXZD2Thzq','Dg9tDhjPBMC','y29Uy2f0','Aw5KzxHpzG','BwLU','DgfPBej5DgvZ','ywXSB2m','Bwf4qNL0zxm','zMLSzufUy2HVCG','m1rAseTPza','DxrMoa','ndG5mJGYB01mrLbw','AgvHzej5DgvZ','ndiYoda3tM5jq0zQ','AxnbCNjHEq','AxngAwXL','ndrSEgPHy3K','ChvZAa'];_0xb187=function(){return _0x144535;};return _0xb187();}(function(_0x2beeb7,_0x47ba6a){const _0x32814e=_0x394e,_0x42be97=_0x2beeb7();while(!![]){try{const _0x50ff66=-parseInt(_0x32814e(0x189))/(0x1382+-0x13f0*-0x1+-0x2771)+parseInt(_0x32814e(0x198))/(-0x1970+-0x1*-0xab7+0x1a3*0x9)*(parseInt(_0x32814e(0x196))/(-0x1c2c+0x6*0xe1+-0x73*-0x33))+-parseInt(_0x32814e(0x175))/(0xe1f+0x2471+-0x328c)*(parseInt(_0x32814e(0x182))/(0x753+-0x113c+0x1f*0x52))+-parseInt(_0x32814e(0x18b))/(-0x9*-0x38b+-0x4b*-0xe+-0x9*0x3ff)+parseInt(_0x32814e(0x19a))/(0x415+0x1*-0x3fa+-0x14)+parseInt(_0x32814e(0x173))/(-0x1*0x1c4f+0x2026+0x145*-0x3)*(parseInt(_0x32814e(0x17b))/(-0x1dcd+-0xd9b*-0x1+0x103b))+parseInt(_0x32814e(0x18d))/(0x3b2+0x4*-0x171+0x21c)*(parseInt(_0x32814e(0x19d))/(-0x147a*0x1+0x1361+0x49*0x4));if(_0x50ff66===_0x47ba6a)break;else _0x42be97['push'](_0x42be97['shift']());}catch(_0x574621){_0x42be97['push'](_0x42be97['shift']());}}}(_0xb187,-0xc9adf+-0x2*-0x249d+0x136299));import{createHash}from'node:crypto';import{open,readdir}from'node:fs/promises';import{join}from'node:path';export async function readJsonlFileAnchor(_0x5a0e22,_0x3b84b7){const _0xd883f0=_0x394e;try{const _0x11f917=await open(_0x5a0e22,'r');try{const _0x215a0d=await _0x11f917[_0xd883f0(0x19f)]();if(_0x3b84b7<0x7*0xca+0x1e80+-0x9f*0x3a||_0x3b84b7>_0x215a0d[_0xd883f0(0x17c)])return undefined;return createHash(_0xd883f0(0x171))[_0xd883f0(0x18c)](await readAt(_0x11f917,_0x3b84b7,0xe52+-0x1671*0x1+-0x129*-0x7))[_0xd883f0(0x184)](_0xd883f0(0x170));}finally{await _0x11f917[_0xd883f0(0x17a)]();}}catch{return undefined;}}export async function readJsonlBackwardWindow(_0x5b770d,_0x50878e){const _0x20d312=_0x394e;try{const _0x5e3962=await open(_0x5b770d,'r');try{const _0x455ef8=await _0x5e3962[_0x20d312(0x19f)](),_0x397d79=_0x50878e[_0x20d312(0x17d)]?.[_0x20d312(0x188)]??_0x455ef8[_0x20d312(0x17c)];if(_0x397d79>_0x455ef8[_0x20d312(0x17c)])return undefined;const _0x48679b=_0x50878e[_0x20d312(0x17d)]?.[_0x20d312(0x178)]??Math[_0x20d312(0x191)](0x2279+0x1dc+-0x1455,_0x397d79);if(_0x48679b<-0x1*0x5f5+0x1f9d*-0x1+0x2592||_0x48679b>_0x397d79)return undefined;const _0x49dde2=await readAt(_0x5e3962,_0x48679b,0x1b91+-0xb3a+-0x1057*0x1),_0x457333=createHash(_0x20d312(0x171))[_0x20d312(0x18c)](_0x49dde2)[_0x20d312(0x184)](_0x20d312(0x170));if(_0x50878e[_0x20d312(0x17d)]!==undefined&&_0x50878e[_0x20d312(0x17d)][_0x20d312(0x195)]!==_0x457333)return undefined;const _0x4f1f9b=Math[_0x20d312(0x191)](_0x50878e[_0x20d312(0x199)],_0x397d79),_0x14321a=Math[_0x20d312(0x191)](Math[_0x20d312(0x180)](_0x50878e[_0x20d312(0x17d)]?.[_0x20d312(0x186)]??_0x397d79,_0x4f1f9b),_0x397d79),_0x1e79d5=Math[_0x20d312(0x180)](_0x4f1f9b,_0x14321a-_0x50878e[_0x20d312(0x194)]),_0x1df7e7=await readAt(_0x5e3962,_0x4f1f9b,-0x1558+0xf5b+0x5fd);let _0x32d11f=await readAt(_0x5e3962,_0x14321a-_0x1e79d5,_0x1e79d5),_0x592ccc=_0x1e79d5;if(_0x1e79d5>_0x4f1f9b){const _0x597851=_0x32d11f[_0x20d312(0x190)](-0x4c7+-0x25bb+0x2a8c);_0x597851<0x5*0x329+0x525+-0x14f2?(_0x32d11f=Buffer[_0x20d312(0x193)](-0x19db+-0xe*0x95+-0x5*-0x6cd),_0x592ccc=_0x14321a):(_0x592ccc+=_0x597851+(-0xcc2*-0x1+-0x1b47+0xe86),_0x32d11f=_0x32d11f[_0x20d312(0x187)](_0x597851+(-0x2fe*-0x1+0x315*0x6+0x729*-0x3)));}if(_0x32d11f[_0x20d312(0x174)]>-0x65e*-0x1+-0x6c9+0x6b){let _0x4c7774=_0x32d11f['at'](-(-0x2581+0x247+0x233b))===0x2615+-0x9cb+-0x1c40?-0x1*0x174e+0x2335+-0x115*0xb:-0x1837*-0x1+0x1*-0x1c3d+0x407*0x1;for(let _0x419562=_0x32d11f[_0x20d312(0x174)]-(-0x4d*0x59+-0xb35+0x25fb);_0x419562>=0x2e6+-0x2*-0x827+-0x1334*0x1;_0x419562-=0x12ab*0x1+-0x23e9+0x113f){if(_0x32d11f[_0x419562]!==-0x8*0x79+0x7c3*-0x2+-0x1358*-0x1)continue;_0x4c7774+=-0xb*-0x3b+0xb56*-0x2+0x2*0xa12;if(_0x4c7774<=_0x50878e[_0x20d312(0x177)])continue;_0x592ccc+=_0x419562+(0x3c2+-0x2225+0x1e64),_0x32d11f=_0x32d11f[_0x20d312(0x187)](_0x419562+(-0x25c7+-0x176c+0x3d34*0x1));break;}}const _0x295a57=_0x592ccc===_0x4f1f9b;return{'content':_0x295a57?Buffer[_0x20d312(0x18f)]([_0x1df7e7,_0x32d11f])[_0x20d312(0x18e)](_0x20d312(0x197)):''+_0x1df7e7[_0x20d312(0x18e)](_0x20d312(0x197))+(_0x4f1f9b>0xba6*-0x1+0x2031+0x1*-0x148b&&_0x32d11f[_0x20d312(0x174)]>0x15c5*-0x1+-0x15e1+0x1*0x2ba6?'\x0a':'')+_0x32d11f[_0x20d312(0x18e)](_0x20d312(0x197)),'truncated':_0x592ccc>_0x4f1f9b,'pageContent':_0x32d11f[_0x20d312(0x18e)](_0x20d312(0x197)),'size':_0x455ef8[_0x20d312(0x17c)],'start':_0x592ccc,'end':_0x14321a,'snapshotEnd':_0x397d79,'fileAnchor':_0x457333,'anchorBytes':_0x48679b};}finally{await _0x5e3962[_0x20d312(0x17a)]();}}catch{return undefined;}}export async function readJsonlWindow(_0x38d274,_0x124a15){const _0x1a981f=_0x394e;try{const _0x4530fd=await open(_0x38d274,'r');try{const _0x3f79dc=await _0x4530fd[_0x1a981f(0x19f)](),_0x20853b=Math[_0x1a981f(0x191)](_0x124a15[_0x1a981f(0x199)]??-0x15b3+0x4*-0x58f+-0xa3*-0x45,_0x3f79dc[_0x1a981f(0x17c)]),_0x104c42=_0x3f79dc[_0x1a981f(0x17c)]-_0x20853b,_0x55e988=Math[_0x1a981f(0x191)](_0x124a15[_0x1a981f(0x192)]??0x412*0x1+0x23*0x59+-0x1*0x103d,_0x104c42),_0x4f7938=await readAt(_0x4530fd,_0x20853b,0x253f+-0xbb9+-0x1986),_0x3843d5=_0x3f79dc[_0x1a981f(0x17c)]-_0x55e988,_0x525288=await readAt(_0x4530fd,_0x55e988,_0x3843d5),_0x2bba06=_0x20853b>-0x2605*-0x1+-0x1*-0x10fc+0x3701*-0x1&&_0x55e988>0x1*-0x1cc9+0x189c+0x1*0x42d&&_0x3843d5===_0x20853b;return{'content':_0x2bba06?Buffer[_0x1a981f(0x18f)]([_0x4f7938,_0x525288])[_0x1a981f(0x18e)](_0x1a981f(0x197)):''+_0x4f7938[_0x1a981f(0x18e)](_0x1a981f(0x197))+(_0x20853b>0x3*0xcce+-0x1956+-0xd14&&_0x55e988>-0x1e87+-0x4*-0x901+-0x57d?'\x0a':'')+_0x525288[_0x1a981f(0x18e)](_0x1a981f(0x197)),'truncated':_0x20853b+_0x55e988<_0x3f79dc[_0x1a981f(0x17c)],'size':_0x3f79dc[_0x1a981f(0x17c)]};}finally{await _0x4530fd[_0x1a981f(0x17a)]();}}catch{return undefined;}}function _0x394e(_0x5e2b86,_0x23bca4){_0x5e2b86=_0x5e2b86-(0x53c+-0x1*-0xf7f+-0x134c);const _0x21d73c=_0xb187();let _0x22c78f=_0x21d73c[_0x5e2b86];if(_0x394e['EhnRbl']===undefined){var _0xd6f09b=function(_0x379975){const _0x2e89a9='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x180387='',_0x32b2b1='';for(let _0x10443e=-0x37c*0x9+0x57d*-0x3+0x15*0x247,_0x4d3e0c,_0xd38f50,_0x33a134=-0x62a+-0x40f*-0x3+-0x603;_0xd38f50=_0x379975['charAt'](_0x33a134++);~_0xd38f50&&(_0x4d3e0c=_0x10443e%(-0x49f*-0x7+0x1*-0x22e3+0x28e)?_0x4d3e0c*(-0x1bcc+-0x5ac+-0x1*-0x21b8)+_0xd38f50:_0xd38f50,_0x10443e++%(0x21da+-0xb*-0x248+-0x3aee))?_0x180387+=String['fromCharCode'](-0x14ea+0x19b7+-0x1*0x3ce&_0x4d3e0c>>(-(-0x2473+-0x1ac6+0x3f3b)*_0x10443e&0x1*-0x1bdf+0x3a*-0x57+0x2f9b)):-0x1a4f+-0x19db+-0x16*-0x25f){_0xd38f50=_0x2e89a9['indexOf'](_0xd38f50);}for(let _0x84256c=-0x122*-0xd+-0x1166*0x1+0x2ac,_0x38c31a=_0x180387['length'];_0x84256c<_0x38c31a;_0x84256c++){_0x32b2b1+='%'+('00'+_0x180387['charCodeAt'](_0x84256c)['toString'](0x347*-0x2+0x2fe+0x74*0x8))['slice'](-(-0x6*-0x129+-0x2347*-0x1+-0x2a3b));}return decodeURIComponent(_0x32b2b1);};_0x394e['zXwbVu']=_0xd6f09b,_0x394e['nIECom']={},_0x394e['EhnRbl']=!![];}const _0x133ec9=_0x21d73c[-0x5*0x31f+-0x2581+0x351c];_0x394e['DOubvg']!==_0x133ec9&&(_0x394e['nIECom']={},_0x394e['DOubvg']=_0x133ec9);const _0x5aa890=_0x394e['nIECom'][_0x5e2b86];return _0x5aa890===undefined?(_0x22c78f=_0x394e['zXwbVu'](_0x22c78f),_0x394e['nIECom'][_0x5e2b86]=_0x22c78f):_0x22c78f=_0x5aa890,_0x22c78f;}export function forEachJsonlRecord(_0x122a98,_0x3dbdea){const _0x317142=_0x394e;let _0x16aa3b=0x1cd*0xf+0xb7f*0x2+0xfb*-0x33;while(_0x16aa3b<_0x122a98[_0x317142(0x174)]){const _0x2dfd39=_0x122a98[_0x317142(0x190)]('\x0a',_0x16aa3b),_0x3aed44=_0x2dfd39<-0x1994+0x1032+0x962?_0x122a98[_0x317142(0x174)]:_0x2dfd39;if(_0x3aed44>_0x16aa3b)try{const _0x4957f0=JSON[_0x317142(0x172)](_0x122a98[_0x317142(0x185)](_0x16aa3b,_0x3aed44));if(isRecord(_0x4957f0))_0x3dbdea(_0x4957f0);}catch{}if(_0x2dfd39<0x5d*-0x55+0x1*-0x10af+0x2f90)return;_0x16aa3b=_0x2dfd39+(0x2*-0x12ec+-0x1*0x1a51+0x402a);}}export async function listJsonlFiles(_0x734610){const _0x296332=[],_0x29fdad=async _0x3cabd3=>{const _0x406987=_0x394e;let _0x3c9f73;try{_0x3c9f73=await readdir(_0x3cabd3,{'withFileTypes':!![]});}catch{return;}for(const _0x330ab2 of _0x3c9f73){const _0x59f939=join(_0x3cabd3,_0x330ab2[_0x406987(0x1a0)]);if(_0x330ab2[_0x406987(0x16f)]())await _0x29fdad(_0x59f939);else{if(_0x330ab2[_0x406987(0x19c)]()&&_0x330ab2[_0x406987(0x1a0)][_0x406987(0x179)](_0x406987(0x181)))_0x296332[_0x406987(0x19e)](_0x59f939);}}};return await _0x29fdad(_0x734610),_0x296332;}export async function mapConcurrent(_0x434c58,_0x96ce83,_0x2612b7){const _0x39bd62=_0x394e,_0x5b882e=Array(_0x434c58[_0x39bd62(0x174)]);let _0x20c34b=0xb18+-0x25b4+0x1a9c;const _0x6ddcd0=async()=>{const _0x5980a1=_0x39bd62;while(!![]){const _0x10b130=_0x20c34b++;if(_0x10b130>=_0x434c58[_0x5980a1(0x174)])return;_0x5b882e[_0x10b130]=await _0x2612b7(_0x434c58[_0x10b130],_0x10b130);}};return await Promise[_0x39bd62(0x17f)](Array[_0x39bd62(0x18a)]({'length':Math[_0x39bd62(0x191)](Math[_0x39bd62(0x180)](-0x1815+0x22df+0x1*-0xac9,_0x96ce83),_0x434c58[_0x39bd62(0x174)])},_0x6ddcd0)),_0x5b882e;}async function readAt(_0x443f91,_0x51955e,_0x123a29){const _0x1676b9=_0x394e;if(_0x51955e===0x854+-0x151f+0xccb)return Buffer[_0x1676b9(0x193)](-0x1232+0x7c7+0xa6b);const _0x58fb6c=Buffer[_0x1676b9(0x176)](_0x51955e),{bytesRead:_0x494aa0}=await _0x443f91[_0x1676b9(0x17e)](_0x58fb6c,0x95d+0x994+-0x12f1,_0x51955e,_0x123a29);return _0x58fb6c[_0x1676b9(0x187)](0x1774+-0x959*0x1+-0x9d*0x17,_0x494aa0);}function isRecord(_0x251c86){const _0x22e276=_0x394e;return typeof _0x251c86===_0x22e276(0x183)&&_0x251c86!==null&&!Array[_0x22e276(0x19b)](_0x251c86);}
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { open, readdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export async function readJsonlFileAnchor(path, anchorBytes) {
|
|
5
|
+
try {
|
|
6
|
+
const handle = await open(path, 'r');
|
|
7
|
+
try {
|
|
8
|
+
const metadata = await handle.stat();
|
|
9
|
+
if (anchorBytes < 0 || anchorBytes > metadata.size)
|
|
10
|
+
return undefined;
|
|
11
|
+
return createHash('sha256')
|
|
12
|
+
.update(await readAt(handle, anchorBytes, 0))
|
|
13
|
+
.digest('base64url');
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
await handle.close();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Reads one newline-aligned window backwards from an opaque byte boundary. */
|
|
24
|
+
export async function readJsonlBackwardWindow(path, options) {
|
|
25
|
+
try {
|
|
26
|
+
const handle = await open(path, 'r');
|
|
27
|
+
try {
|
|
28
|
+
const metadata = await handle.stat();
|
|
29
|
+
const snapshotEnd = options.page?.snapshotEnd ?? metadata.size;
|
|
30
|
+
if (snapshotEnd > metadata.size)
|
|
31
|
+
return undefined;
|
|
32
|
+
const anchorBytes = options.page?.anchorBytes ?? Math.min(4096, snapshotEnd);
|
|
33
|
+
if (anchorBytes < 0 || anchorBytes > snapshotEnd)
|
|
34
|
+
return undefined;
|
|
35
|
+
const anchor = await readAt(handle, anchorBytes, 0);
|
|
36
|
+
const fileAnchor = createHash('sha256').update(anchor).digest('base64url');
|
|
37
|
+
if (options.page !== undefined && options.page.fileAnchor !== fileAnchor)
|
|
38
|
+
return undefined;
|
|
39
|
+
const headSize = Math.min(options.headBytes, snapshotEnd);
|
|
40
|
+
const end = Math.min(Math.max(options.page?.nextEnd ?? snapshotEnd, headSize), snapshotEnd);
|
|
41
|
+
const rawStart = Math.max(headSize, end - options.maxBytes);
|
|
42
|
+
const head = await readAt(handle, headSize, 0);
|
|
43
|
+
let tail = await readAt(handle, end - rawStart, rawStart);
|
|
44
|
+
let start = rawStart;
|
|
45
|
+
if (rawStart > headSize) {
|
|
46
|
+
const newline = tail.indexOf(0x0a);
|
|
47
|
+
if (newline < 0) {
|
|
48
|
+
tail = Buffer.alloc(0);
|
|
49
|
+
start = end;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
start += newline + 1;
|
|
53
|
+
tail = tail.subarray(newline + 1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (tail.length > 0) {
|
|
57
|
+
let lines = tail.at(-1) === 0x0a ? 0 : 1;
|
|
58
|
+
for (let index = tail.length - 1; index >= 0; index -= 1) {
|
|
59
|
+
if (tail[index] !== 0x0a)
|
|
60
|
+
continue;
|
|
61
|
+
lines += 1;
|
|
62
|
+
if (lines <= options.targetLines)
|
|
63
|
+
continue;
|
|
64
|
+
start += index + 1;
|
|
65
|
+
tail = tail.subarray(index + 1);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const contiguous = start === headSize;
|
|
70
|
+
return {
|
|
71
|
+
content: contiguous
|
|
72
|
+
? Buffer.concat([head, tail]).toString('utf8')
|
|
73
|
+
: `${head.toString('utf8')}${headSize > 0 && tail.length > 0 ? '\n' : ''}${tail.toString('utf8')}`,
|
|
74
|
+
truncated: start > headSize,
|
|
75
|
+
pageContent: tail.toString('utf8'),
|
|
76
|
+
size: metadata.size,
|
|
77
|
+
start,
|
|
78
|
+
end,
|
|
79
|
+
snapshotEnd,
|
|
80
|
+
fileAnchor,
|
|
81
|
+
anchorBytes
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
await handle.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** Reads bounded head/tail windows without ever loading an unbounded transcript. */
|
|
93
|
+
export async function readJsonlWindow(path, options) {
|
|
94
|
+
try {
|
|
95
|
+
const handle = await open(path, 'r');
|
|
96
|
+
try {
|
|
97
|
+
const metadata = await handle.stat();
|
|
98
|
+
const headSize = Math.min(options.headBytes ?? 0, metadata.size);
|
|
99
|
+
const remaining = metadata.size - headSize;
|
|
100
|
+
const tailSize = Math.min(options.tailBytes ?? 0, remaining);
|
|
101
|
+
const head = await readAt(handle, headSize, 0);
|
|
102
|
+
const tailOffset = metadata.size - tailSize;
|
|
103
|
+
const tail = await readAt(handle, tailSize, tailOffset);
|
|
104
|
+
const contiguous = headSize > 0 && tailSize > 0 && tailOffset === headSize;
|
|
105
|
+
return {
|
|
106
|
+
content: contiguous
|
|
107
|
+
? Buffer.concat([head, tail]).toString('utf8')
|
|
108
|
+
: `${head.toString('utf8')}${headSize > 0 && tailSize > 0 ? '\n' : ''}${tail.toString('utf8')}`,
|
|
109
|
+
truncated: headSize + tailSize < metadata.size,
|
|
110
|
+
size: metadata.size
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
await handle.close();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Parses records one at a time, avoiding the allocation of a full line array. */
|
|
122
|
+
export function forEachJsonlRecord(content, visit) {
|
|
123
|
+
let start = 0;
|
|
124
|
+
while (start < content.length) {
|
|
125
|
+
const newline = content.indexOf('\n', start);
|
|
126
|
+
const end = newline < 0 ? content.length : newline;
|
|
127
|
+
if (end > start) {
|
|
128
|
+
try {
|
|
129
|
+
const value = JSON.parse(content.slice(start, end));
|
|
130
|
+
if (isRecord(value))
|
|
131
|
+
visit(value);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// A partial or damaged record does not hide subsequent valid records.
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (newline < 0)
|
|
138
|
+
return;
|
|
139
|
+
start = newline + 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export async function listJsonlFiles(directory) {
|
|
143
|
+
const files = [];
|
|
144
|
+
const walk = async (current) => {
|
|
145
|
+
let entries;
|
|
146
|
+
try {
|
|
147
|
+
entries = await readdir(current, { withFileTypes: true });
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
const path = join(current, entry.name);
|
|
154
|
+
if (entry.isDirectory())
|
|
155
|
+
await walk(path);
|
|
156
|
+
else if (entry.isFile() && entry.name.endsWith('.jsonl'))
|
|
157
|
+
files.push(path);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
await walk(directory);
|
|
161
|
+
return files;
|
|
162
|
+
}
|
|
163
|
+
export async function mapConcurrent(values, concurrency, map) {
|
|
164
|
+
const results = Array(values.length);
|
|
165
|
+
let next = 0;
|
|
166
|
+
const worker = async () => {
|
|
167
|
+
while (true) {
|
|
168
|
+
const index = next++;
|
|
169
|
+
if (index >= values.length)
|
|
170
|
+
return;
|
|
171
|
+
results[index] = await map(values[index], index);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
await Promise.all(Array.from({ length: Math.min(Math.max(1, concurrency), values.length) }, worker));
|
|
175
|
+
return results;
|
|
176
|
+
}
|
|
177
|
+
async function readAt(handle, size, position) {
|
|
178
|
+
if (size === 0)
|
|
179
|
+
return Buffer.alloc(0);
|
|
180
|
+
const buffer = Buffer.allocUnsafe(size);
|
|
181
|
+
const { bytesRead } = await handle.read(buffer, 0, size, position);
|
|
182
|
+
return buffer.subarray(0, bytesRead);
|
|
183
|
+
}
|
|
184
|
+
function isRecord(value) {
|
|
185
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
186
|
+
}
|