@openontology/opencode-palantir 0.1.5-next.4 → 0.1.5-next.9

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 (2) hide show
  1. package/dist/index.js +450 -390
  2. package/package.json +12 -12
package/dist/index.js CHANGED
@@ -71,11 +71,6 @@ var PageTypes = [
71
71
  "DICTIONARY_PAGE",
72
72
  "DATA_PAGE_V2"
73
73
  ];
74
- var BoundaryOrders = [
75
- "UNORDERED",
76
- "ASCENDING",
77
- "DESCENDING"
78
- ];
79
74
  var EdgeInterpolationAlgorithms = [
80
75
  "SPHERICAL",
81
76
  "VINCENTY",
@@ -872,30 +867,6 @@ function pageLocation(loc) {
872
867
  }
873
868
 
874
869
  // node_modules/hyparquet/src/utils.js
875
- function toJson(obj) {
876
- if (obj === undefined)
877
- return null;
878
- if (typeof obj === "bigint")
879
- return Number(obj);
880
- if (Object.is(obj, -0))
881
- return 0;
882
- if (Array.isArray(obj))
883
- return obj.map(toJson);
884
- if (obj instanceof Uint8Array)
885
- return Array.from(obj);
886
- if (obj instanceof Date)
887
- return obj.toISOString();
888
- if (obj instanceof Object) {
889
- const newObj = {};
890
- for (const key of Object.keys(obj)) {
891
- if (obj[key] === undefined)
892
- continue;
893
- newObj[key] = toJson(obj[key]);
894
- }
895
- return newObj;
896
- }
897
- return obj;
898
- }
899
870
  function concat(aaa, bbb) {
900
871
  const chunk = 1e4;
901
872
  for (let i = 0;i < bbb.length; i += chunk) {
@@ -953,9 +924,9 @@ function columnsNeededForFilter(filter) {
953
924
  } else if ("$nor" in filter && Array.isArray(filter.$nor)) {
954
925
  columns.push(...filter.$nor.flatMap(columnsNeededForFilter));
955
926
  } else {
956
- columns.push(...Object.keys(filter));
927
+ columns.push(...Object.keys(filter).map((key) => key.split(".")[0]));
957
928
  }
958
- return columns;
929
+ return [...new Set(columns)];
959
930
  }
960
931
  function matchFilter(record, filter, strict = true) {
961
932
  if ("$and" in filter && Array.isArray(filter.$and)) {
@@ -968,7 +939,7 @@ function matchFilter(record, filter, strict = true) {
968
939
  return !filter.$nor.some((subQuery) => matchFilter(record, subQuery, strict));
969
940
  }
970
941
  return Object.entries(filter).every(([field, condition]) => {
971
- const value = record[field];
942
+ const value = resolve(record, field);
972
943
  if (typeof condition !== "object" || condition === null || Array.isArray(condition)) {
973
944
  return equals(value, condition, strict);
974
945
  }
@@ -1040,6 +1011,13 @@ function canSkipRowGroup({ rowGroup, physicalColumns, filter, strict = true }) {
1040
1011
  }
1041
1012
  return false;
1042
1013
  }
1014
+ function resolve(record, path) {
1015
+ let value = record;
1016
+ for (const part of path.split(".")) {
1017
+ value = value?.[part];
1018
+ }
1019
+ return value;
1020
+ }
1043
1021
 
1044
1022
  // node_modules/hyparquet/src/plan.js
1045
1023
  var runLimit = 1 << 21;
@@ -2093,6 +2071,7 @@ function readColumn(reader, { groupStart, selectStart, selectEnd }, columnDecode
2093
2071
  let dictionary = undefined;
2094
2072
  let lastChunk = undefined;
2095
2073
  let rowCount = 0;
2074
+ let skipped = 0;
2096
2075
  const emitLastChunk = onPage && (() => {
2097
2076
  lastChunk && onPage({
2098
2077
  pathInSchema,
@@ -2106,23 +2085,29 @@ function readColumn(reader, { groupStart, selectStart, selectEnd }, columnDecode
2106
2085
  break;
2107
2086
  const header = parquetHeader(reader);
2108
2087
  if (header.type === "DICTIONARY_PAGE") {
2109
- dictionary = readPage(reader, header, columnDecoder, dictionary, undefined, 0);
2110
- dictionary = convert(dictionary, columnDecoder);
2088
+ const { data } = readPage(reader, header, columnDecoder, dictionary, undefined, 0);
2089
+ if (data)
2090
+ dictionary = convert(data, columnDecoder);
2111
2091
  } else {
2112
2092
  const lastChunkLength = lastChunk?.length || 0;
2113
- const values = readPage(reader, header, columnDecoder, dictionary, lastChunk, selectStart - rowCount);
2114
- if (lastChunk === values) {
2115
- rowCount += values.length - lastChunkLength;
2116
- } else {
2093
+ const result = readPage(reader, header, columnDecoder, dictionary, lastChunk, selectStart - rowCount);
2094
+ if (result.skipped) {
2095
+ if (!chunks.length) {
2096
+ skipped += result.skipped;
2097
+ }
2098
+ rowCount += result.skipped;
2099
+ } else if (result.data && lastChunk === result.data) {
2100
+ rowCount += result.data.length - lastChunkLength;
2101
+ } else if (result.data && result.data.length) {
2117
2102
  emitLastChunk?.();
2118
- chunks.push(values);
2119
- rowCount += values.length;
2120
- lastChunk = values;
2103
+ chunks.push(result.data);
2104
+ rowCount += result.data.length;
2105
+ lastChunk = result.data;
2121
2106
  }
2122
2107
  }
2123
2108
  }
2124
2109
  emitLastChunk?.();
2125
- return chunks;
2110
+ return { data: chunks, skipped };
2126
2111
  }
2127
2112
  function readPage(reader, header, columnDecoder, dictionary, previousChunk, pageStart) {
2128
2113
  const { type, element, schemaPath, codec, compressors } = columnDecoder;
@@ -2133,31 +2118,34 @@ function readPage(reader, header, columnDecoder, dictionary, previousChunk, page
2133
2118
  if (!daph)
2134
2119
  throw new Error("parquet data page header is undefined");
2135
2120
  if (pageStart > daph.num_values && isFlatColumn(schemaPath)) {
2136
- return new Array(daph.num_values);
2121
+ return { skipped: daph.num_values };
2137
2122
  }
2138
2123
  const page = decompressPage(compressedBytes, Number(header.uncompressed_page_size), codec, compressors);
2139
2124
  const { definitionLevels, repetitionLevels, dataPage } = readDataPage(page, daph, columnDecoder);
2140
2125
  const values = convertWithDictionary(dataPage, dictionary, daph.encoding, columnDecoder);
2141
2126
  const output = Array.isArray(previousChunk) ? previousChunk : [];
2142
- return assembleLists(output, definitionLevels, repetitionLevels, values, schemaPath);
2127
+ const assembled = assembleLists(output, definitionLevels, repetitionLevels, values, schemaPath);
2128
+ return { skipped: 0, data: assembled };
2143
2129
  } else if (header.type === "DATA_PAGE_V2") {
2144
2130
  const daph2 = header.data_page_header_v2;
2145
2131
  if (!daph2)
2146
2132
  throw new Error("parquet data page header v2 is undefined");
2147
2133
  if (pageStart > daph2.num_rows) {
2148
- return new Array(daph2.num_values);
2134
+ return { skipped: daph2.num_values };
2149
2135
  }
2150
2136
  const { definitionLevels, repetitionLevels, dataPage } = readDataPageV2(compressedBytes, header, columnDecoder);
2151
2137
  const values = convertWithDictionary(dataPage, dictionary, daph2.encoding, columnDecoder);
2152
2138
  const output = Array.isArray(previousChunk) ? previousChunk : [];
2153
- return assembleLists(output, definitionLevels, repetitionLevels, values, schemaPath);
2139
+ const assembled = assembleLists(output, definitionLevels, repetitionLevels, values, schemaPath);
2140
+ return { skipped: 0, data: assembled };
2154
2141
  } else if (header.type === "DICTIONARY_PAGE") {
2155
2142
  const diph = header.dictionary_page_header;
2156
2143
  if (!diph)
2157
2144
  throw new Error("parquet dictionary page header is undefined");
2158
2145
  const page = decompressPage(compressedBytes, Number(header.uncompressed_page_size), codec, compressors);
2159
2146
  const reader2 = { view: new DataView(page.buffer, page.byteOffset, page.byteLength), offset: 0 };
2160
- return readPlain(reader2, type, diph.num_values, element.type_length);
2147
+ const dictArray = readPlain(reader2, type, diph.num_values, element.type_length);
2148
+ return { skipped: 0, data: dictArray };
2161
2149
  } else {
2162
2150
  throw new Error(`parquet unsupported page type: ${header.type}`);
2163
2151
  }
@@ -2233,10 +2221,7 @@ function readRowGroup(options, { metadata }, groupPlan) {
2233
2221
  pathInSchema: columnMetadata.path_in_schema,
2234
2222
  data: Promise.resolve(file.slice(chunkPlan.range.startByte, chunkPlan.range.endByte)).then((buffer) => {
2235
2223
  const reader = { view: new DataView(buffer), offset: 0 };
2236
- return {
2237
- pageSkip: 0,
2238
- data: readColumn(reader, groupPlan, columnDecoder, options.onPage)
2239
- };
2224
+ return readColumn(reader, groupPlan, columnDecoder, options.onPage);
2240
2225
  })
2241
2226
  });
2242
2227
  continue;
@@ -2249,7 +2234,7 @@ function readRowGroup(options, { metadata }, groupPlan) {
2249
2234
  const pages = offsetIndex.page_locations;
2250
2235
  let startByte = NaN;
2251
2236
  let endByte = NaN;
2252
- let pageSkip = 0;
2237
+ let skipped = 0;
2253
2238
  for (let i = 0;i < pages.length; i++) {
2254
2239
  const page = pages[i];
2255
2240
  const pageStart = Number(page.first_row_index);
@@ -2257,22 +2242,23 @@ function readRowGroup(options, { metadata }, groupPlan) {
2257
2242
  if (pageStart < selectEnd && pageEnd > selectStart) {
2258
2243
  if (Number.isNaN(startByte)) {
2259
2244
  startByte = Number(page.offset);
2260
- pageSkip = pageStart;
2245
+ skipped = pageStart;
2261
2246
  }
2262
2247
  endByte = Number(page.offset) + page.compressed_page_size;
2263
2248
  }
2264
2249
  }
2265
2250
  const buffer = await file.slice(startByte, endByte);
2266
2251
  const reader = { view: new DataView(buffer), offset: 0 };
2267
- const adjustedGroupPlan = pageSkip ? {
2252
+ const adjustedGroupPlan = skipped ? {
2268
2253
  ...groupPlan,
2269
- groupStart: groupPlan.groupStart + pageSkip,
2270
- selectStart: groupPlan.selectStart - pageSkip,
2271
- selectEnd: groupPlan.selectEnd - pageSkip
2254
+ groupStart: groupPlan.groupStart + skipped,
2255
+ selectStart: groupPlan.selectStart - skipped,
2256
+ selectEnd: groupPlan.selectEnd - skipped
2272
2257
  } : groupPlan;
2258
+ const { data, skipped: columnSkipped } = readColumn(reader, adjustedGroupPlan, columnDecoder, options.onPage);
2273
2259
  return {
2274
- data: readColumn(reader, adjustedGroupPlan, columnDecoder, options.onPage),
2275
- pageSkip
2260
+ data,
2261
+ skipped: skipped + columnSkipped
2276
2262
  };
2277
2263
  })
2278
2264
  });
@@ -2297,8 +2283,8 @@ async function asyncGroupToRows({ asyncColumns }, selectStart, selectEnd, column
2297
2283
  const row = selectStart + selectRow;
2298
2284
  const rowData = {};
2299
2285
  for (let i = 0;i < asyncColumns.length; i++) {
2300
- const { data, pageSkip } = asyncPages[i];
2301
- rowData[asyncColumns[i].pathInSchema[0]] = data[row - pageSkip];
2286
+ const { data, skipped } = asyncPages[i];
2287
+ rowData[asyncColumns[i].pathInSchema[0]] = data[row - skipped];
2302
2288
  }
2303
2289
  groupData2[selectRow] = rowData;
2304
2290
  }
@@ -2311,8 +2297,8 @@ async function asyncGroupToRows({ asyncColumns }, selectStart, selectEnd, column
2311
2297
  for (let i = 0;i < columnOrder.length; i++) {
2312
2298
  const colIdx = columnIndexes[i];
2313
2299
  if (colIdx >= 0) {
2314
- const { data, pageSkip } = asyncPages[colIdx];
2315
- rowData[i] = data[row - pageSkip];
2300
+ const { data, skipped } = asyncPages[colIdx];
2301
+ rowData[i] = data[row - skipped];
2316
2302
  }
2317
2303
  }
2318
2304
  groupData[selectRow] = rowData;
@@ -2338,7 +2324,7 @@ function assembleAsync(asyncRowGroup, schemaTree2, parsers) {
2338
2324
  const flatColumn = flatData.get(child.path.join("."));
2339
2325
  if (!flatColumn)
2340
2326
  throw new Error("parquet column data not assembled");
2341
- return { data: [flatColumn], pageSkip: 0 };
2327
+ return { data: [flatColumn], skipped: 0 };
2342
2328
  });
2343
2329
  assembled.push({ pathInSchema: child.path, data });
2344
2330
  } else {
@@ -2389,8 +2375,8 @@ async function parquetRead(options) {
2389
2375
  if (onChunk) {
2390
2376
  for (const asyncGroup of assembled) {
2391
2377
  for (const asyncColumn of asyncGroup.asyncColumns) {
2392
- asyncColumn.data.then(({ data, pageSkip }) => {
2393
- let rowStart2 = asyncGroup.groupStart + pageSkip;
2378
+ asyncColumn.data.then(({ data, skipped }) => {
2379
+ let rowStart2 = asyncGroup.groupStart + skipped;
2394
2380
  for (const columnData of data) {
2395
2381
  onChunk({
2396
2382
  columnName: asyncColumn.pathInSchema[0],
@@ -3976,6 +3962,108 @@ ByteWriter.prototype.appendZigZag = function(value) {
3976
3962
  }
3977
3963
  };
3978
3964
 
3965
+ // node_modules/hyparquet-writer/node_modules/hyparquet/src/schema.js
3966
+ function schemaTree2(schema, rootIndex, path) {
3967
+ const element = schema[rootIndex];
3968
+ const children = [];
3969
+ let count = 1;
3970
+ if (element.num_children) {
3971
+ while (children.length < element.num_children) {
3972
+ const childElement = schema[rootIndex + count];
3973
+ const child = schemaTree2(schema, rootIndex + count, [...path, childElement.name]);
3974
+ count += child.count;
3975
+ children.push(child);
3976
+ }
3977
+ }
3978
+ return { count, element, children, path };
3979
+ }
3980
+ function getSchemaPath2(schema, name) {
3981
+ let tree = schemaTree2(schema, 0, []);
3982
+ const path = [tree];
3983
+ for (const part of name) {
3984
+ const child = tree.children.find((child2) => child2.element.name === part);
3985
+ if (!child)
3986
+ throw new Error(`parquet schema element not found: ${name}`);
3987
+ path.push(child);
3988
+ tree = child;
3989
+ }
3990
+ return path;
3991
+ }
3992
+
3993
+ // node_modules/hyparquet-writer/node_modules/hyparquet/src/constants.js
3994
+ var ParquetTypes2 = [
3995
+ "BOOLEAN",
3996
+ "INT32",
3997
+ "INT64",
3998
+ "INT96",
3999
+ "FLOAT",
4000
+ "DOUBLE",
4001
+ "BYTE_ARRAY",
4002
+ "FIXED_LEN_BYTE_ARRAY"
4003
+ ];
4004
+ var Encodings2 = [
4005
+ "PLAIN",
4006
+ "GROUP_VAR_INT",
4007
+ "PLAIN_DICTIONARY",
4008
+ "RLE",
4009
+ "BIT_PACKED",
4010
+ "DELTA_BINARY_PACKED",
4011
+ "DELTA_LENGTH_BYTE_ARRAY",
4012
+ "DELTA_BYTE_ARRAY",
4013
+ "RLE_DICTIONARY",
4014
+ "BYTE_STREAM_SPLIT"
4015
+ ];
4016
+ var FieldRepetitionTypes2 = [
4017
+ "REQUIRED",
4018
+ "OPTIONAL",
4019
+ "REPEATED"
4020
+ ];
4021
+ var ConvertedTypes2 = [
4022
+ "UTF8",
4023
+ "MAP",
4024
+ "MAP_KEY_VALUE",
4025
+ "LIST",
4026
+ "ENUM",
4027
+ "DECIMAL",
4028
+ "DATE",
4029
+ "TIME_MILLIS",
4030
+ "TIME_MICROS",
4031
+ "TIMESTAMP_MILLIS",
4032
+ "TIMESTAMP_MICROS",
4033
+ "UINT_8",
4034
+ "UINT_16",
4035
+ "UINT_32",
4036
+ "UINT_64",
4037
+ "INT_8",
4038
+ "INT_16",
4039
+ "INT_32",
4040
+ "INT_64",
4041
+ "JSON",
4042
+ "BSON",
4043
+ "INTERVAL"
4044
+ ];
4045
+ var CompressionCodecs2 = [
4046
+ "UNCOMPRESSED",
4047
+ "SNAPPY",
4048
+ "GZIP",
4049
+ "LZO",
4050
+ "BROTLI",
4051
+ "LZ4",
4052
+ "ZSTD",
4053
+ "LZ4_RAW"
4054
+ ];
4055
+ var PageTypes2 = [
4056
+ "DATA_PAGE",
4057
+ "INDEX_PAGE",
4058
+ "DICTIONARY_PAGE",
4059
+ "DATA_PAGE_V2"
4060
+ ];
4061
+ var BoundaryOrders = [
4062
+ "UNORDERED",
4063
+ "ASCENDING",
4064
+ "DESCENDING"
4065
+ ];
4066
+
3979
4067
  // node_modules/hyparquet-writer/src/delta.js
3980
4068
  var BLOCK_SIZE = 128;
3981
4069
  var MINIBLOCKS_PER_BLOCK = 4;
@@ -4451,6 +4539,24 @@ function bigIntArray(values) {
4451
4539
  throw new Error("Expected bigint array for BYTE_STREAM_SPLIT encoding");
4452
4540
  }
4453
4541
 
4542
+ // node_modules/hyparquet-writer/node_modules/hyparquet/src/thrift.js
4543
+ var CompactType2 = {
4544
+ STOP: 0,
4545
+ TRUE: 1,
4546
+ FALSE: 2,
4547
+ BYTE: 3,
4548
+ I16: 4,
4549
+ I32: 5,
4550
+ I64: 6,
4551
+ DOUBLE: 7,
4552
+ BINARY: 8,
4553
+ LIST: 9,
4554
+ SET: 10,
4555
+ MAP: 11,
4556
+ STRUCT: 12,
4557
+ UUID: 13
4558
+ };
4559
+
4454
4560
  // node_modules/hyparquet-writer/src/thrift.js
4455
4561
  function serializeTCompactProtocol(writer, data) {
4456
4562
  let lastFid = 0;
@@ -4475,55 +4581,55 @@ function serializeTCompactProtocol(writer, data) {
4475
4581
  writeElement(writer, type, value);
4476
4582
  lastFid = fid;
4477
4583
  }
4478
- writer.appendUint8(CompactType.STOP);
4584
+ writer.appendUint8(CompactType2.STOP);
4479
4585
  }
4480
4586
  function getCompactTypeForValue(value) {
4481
4587
  if (value === true)
4482
- return CompactType.TRUE;
4588
+ return CompactType2.TRUE;
4483
4589
  if (value === false)
4484
- return CompactType.FALSE;
4590
+ return CompactType2.FALSE;
4485
4591
  if (Number.isInteger(value))
4486
- return CompactType.I32;
4592
+ return CompactType2.I32;
4487
4593
  if (typeof value === "number")
4488
- return CompactType.DOUBLE;
4594
+ return CompactType2.DOUBLE;
4489
4595
  if (typeof value === "bigint")
4490
- return CompactType.I64;
4596
+ return CompactType2.I64;
4491
4597
  if (typeof value === "string")
4492
- return CompactType.BINARY;
4598
+ return CompactType2.BINARY;
4493
4599
  if (value instanceof Uint8Array)
4494
- return CompactType.BINARY;
4600
+ return CompactType2.BINARY;
4495
4601
  if (Array.isArray(value))
4496
- return CompactType.LIST;
4602
+ return CompactType2.LIST;
4497
4603
  if (value && typeof value === "object")
4498
- return CompactType.STRUCT;
4604
+ return CompactType2.STRUCT;
4499
4605
  throw new Error(`Cannot determine thrift compact type for: ${value}`);
4500
4606
  }
4501
4607
  function writeElement(writer, type, value) {
4502
- if (type === CompactType.TRUE)
4608
+ if (type === CompactType2.TRUE)
4503
4609
  return;
4504
- if (type === CompactType.FALSE)
4610
+ if (type === CompactType2.FALSE)
4505
4611
  return;
4506
- if (type === CompactType.BYTE && typeof value === "number") {
4612
+ if (type === CompactType2.BYTE && typeof value === "number") {
4507
4613
  writer.appendUint8(value);
4508
- } else if (type === CompactType.I32 && typeof value === "number") {
4614
+ } else if (type === CompactType2.I32 && typeof value === "number") {
4509
4615
  const zigzag = value << 1 ^ value >> 31;
4510
4616
  writer.appendVarInt(zigzag);
4511
- } else if (type === CompactType.I64 && typeof value === "bigint") {
4617
+ } else if (type === CompactType2.I64 && typeof value === "bigint") {
4512
4618
  const zigzag = value << 1n ^ value >> 63n;
4513
4619
  writer.appendVarBigInt(zigzag);
4514
- } else if (type === CompactType.DOUBLE && typeof value === "number") {
4620
+ } else if (type === CompactType2.DOUBLE && typeof value === "number") {
4515
4621
  writer.appendFloat64(value);
4516
- } else if (type === CompactType.BINARY && typeof value === "string") {
4622
+ } else if (type === CompactType2.BINARY && typeof value === "string") {
4517
4623
  const bytes = new TextEncoder().encode(value);
4518
4624
  writer.appendVarInt(bytes.length);
4519
4625
  writer.appendBytes(bytes);
4520
- } else if (type === CompactType.BINARY && value instanceof Uint8Array) {
4626
+ } else if (type === CompactType2.BINARY && value instanceof Uint8Array) {
4521
4627
  writer.appendVarInt(value.byteLength);
4522
4628
  writer.appendBytes(value);
4523
- } else if (type === CompactType.LIST && Array.isArray(value)) {
4629
+ } else if (type === CompactType2.LIST && Array.isArray(value)) {
4524
4630
  const size = value.length;
4525
4631
  if (size === 0) {
4526
- writer.appendUint8(0 << 4 | CompactType.BYTE);
4632
+ writer.appendUint8(0 << 4 | CompactType2.BYTE);
4527
4633
  return;
4528
4634
  }
4529
4635
  const elemType = getCompactTypeForValue(value[0]);
@@ -4532,7 +4638,7 @@ function writeElement(writer, type, value) {
4532
4638
  if (size > 14) {
4533
4639
  writer.appendVarInt(size);
4534
4640
  }
4535
- if (elemType === CompactType.TRUE || elemType === CompactType.FALSE) {
4641
+ if (elemType === CompactType2.TRUE || elemType === CompactType2.FALSE) {
4536
4642
  for (const v of value) {
4537
4643
  writer.appendUint8(v ? 1 : 0);
4538
4644
  }
@@ -4541,7 +4647,7 @@ function writeElement(writer, type, value) {
4541
4647
  writeElement(writer, elemType, v);
4542
4648
  }
4543
4649
  }
4544
- } else if (type === CompactType.STRUCT && typeof value === "object") {
4650
+ } else if (type === CompactType2.STRUCT && typeof value === "object") {
4545
4651
  let lastFid = 0;
4546
4652
  for (const [k, v] of Object.entries(value)) {
4547
4653
  if (v === undefined)
@@ -4564,7 +4670,7 @@ function writeElement(writer, type, value) {
4564
4670
  writeElement(writer, t, v);
4565
4671
  lastFid = fid;
4566
4672
  }
4567
- writer.appendUint8(CompactType.STOP);
4673
+ writer.appendUint8(CompactType2.STOP);
4568
4674
  } else {
4569
4675
  throw new Error(`unhandled type in writeElement: ${type} for value ${value}`);
4570
4676
  }
@@ -4646,25 +4752,25 @@ function writeDataPageV2({ writer, values, column, encoding, pageData }) {
4646
4752
  }
4647
4753
  function writePageHeader(writer, header) {
4648
4754
  const compact = {
4649
- field_1: PageTypes.indexOf(header.type),
4755
+ field_1: PageTypes2.indexOf(header.type),
4650
4756
  field_2: header.uncompressed_page_size,
4651
4757
  field_3: header.compressed_page_size,
4652
4758
  field_4: header.crc,
4653
4759
  field_5: header.data_page_header && {
4654
4760
  field_1: header.data_page_header.num_values,
4655
- field_2: Encodings.indexOf(header.data_page_header.encoding),
4656
- field_3: Encodings.indexOf(header.data_page_header.definition_level_encoding),
4657
- field_4: Encodings.indexOf(header.data_page_header.repetition_level_encoding)
4761
+ field_2: Encodings2.indexOf(header.data_page_header.encoding),
4762
+ field_3: Encodings2.indexOf(header.data_page_header.definition_level_encoding),
4763
+ field_4: Encodings2.indexOf(header.data_page_header.repetition_level_encoding)
4658
4764
  },
4659
4765
  field_7: header.dictionary_page_header && {
4660
4766
  field_1: header.dictionary_page_header.num_values,
4661
- field_2: Encodings.indexOf(header.dictionary_page_header.encoding)
4767
+ field_2: Encodings2.indexOf(header.dictionary_page_header.encoding)
4662
4768
  },
4663
4769
  field_8: header.data_page_header_v2 && {
4664
4770
  field_1: header.data_page_header_v2.num_values,
4665
4771
  field_2: header.data_page_header_v2.num_nulls,
4666
4772
  field_3: header.data_page_header_v2.num_rows,
4667
- field_4: Encodings.indexOf(header.data_page_header_v2.encoding),
4773
+ field_4: Encodings2.indexOf(header.data_page_header_v2.encoding),
4668
4774
  field_5: header.data_page_header_v2.definition_levels_byte_length,
4669
4775
  field_6: header.data_page_header_v2.repetition_levels_byte_length,
4670
4776
  field_7: header.data_page_header_v2.is_compressed ? undefined : false
@@ -4798,6 +4904,31 @@ function inferCoordinateDimensions(value) {
4798
4904
  return maxDim || 2;
4799
4905
  }
4800
4906
 
4907
+ // node_modules/hyparquet-writer/node_modules/hyparquet/src/utils.js
4908
+ function toJson(obj) {
4909
+ if (obj === undefined)
4910
+ return null;
4911
+ if (typeof obj === "bigint")
4912
+ return Number(obj);
4913
+ if (Object.is(obj, -0))
4914
+ return 0;
4915
+ if (Array.isArray(obj))
4916
+ return obj.map(toJson);
4917
+ if (obj instanceof Uint8Array)
4918
+ return Array.from(obj);
4919
+ if (obj instanceof Date)
4920
+ return obj.toISOString();
4921
+ if (obj instanceof Object) {
4922
+ const newObj = {};
4923
+ for (const key of Object.keys(obj)) {
4924
+ if (obj[key] === undefined)
4925
+ continue;
4926
+ newObj[key] = toJson(obj[key]);
4927
+ }
4928
+ return newObj;
4929
+ }
4930
+ return obj;
4931
+ }
4801
4932
  // node_modules/hyparquet-writer/src/wkb.js
4802
4933
  function geojsonToWkb(geometry) {
4803
4934
  const writer = new ByteWriter;
@@ -5608,12 +5739,12 @@ function writeMetadata(writer, metadata) {
5608
5739
  const compact = {
5609
5740
  field_1: metadata.version,
5610
5741
  field_2: metadata.schema && metadata.schema.map((element) => ({
5611
- field_1: element.type && ParquetTypes.indexOf(element.type),
5742
+ field_1: element.type && ParquetTypes2.indexOf(element.type),
5612
5743
  field_2: element.type_length,
5613
- field_3: element.repetition_type && FieldRepetitionTypes.indexOf(element.repetition_type),
5744
+ field_3: element.repetition_type && FieldRepetitionTypes2.indexOf(element.repetition_type),
5614
5745
  field_4: element.name,
5615
5746
  field_5: element.num_children,
5616
- field_6: element.converted_type && ConvertedTypes.indexOf(element.converted_type),
5747
+ field_6: element.converted_type && ConvertedTypes2.indexOf(element.converted_type),
5617
5748
  field_7: element.scale,
5618
5749
  field_8: element.precision,
5619
5750
  field_9: element.field_id,
@@ -5625,10 +5756,10 @@ function writeMetadata(writer, metadata) {
5625
5756
  field_1: c.file_path,
5626
5757
  field_2: c.file_offset,
5627
5758
  field_3: c.meta_data && {
5628
- field_1: ParquetTypes.indexOf(c.meta_data.type),
5629
- field_2: c.meta_data.encodings.map((e) => Encodings.indexOf(e)),
5759
+ field_1: ParquetTypes2.indexOf(c.meta_data.type),
5760
+ field_2: c.meta_data.encodings.map((e) => Encodings2.indexOf(e)),
5630
5761
  field_3: c.meta_data.path_in_schema,
5631
- field_4: CompressionCodecs.indexOf(c.meta_data.codec),
5762
+ field_4: CompressionCodecs2.indexOf(c.meta_data.codec),
5632
5763
  field_5: c.meta_data.num_values,
5633
5764
  field_6: c.meta_data.total_uncompressed_size,
5634
5765
  field_7: c.meta_data.total_compressed_size,
@@ -5641,8 +5772,8 @@ function writeMetadata(writer, metadata) {
5641
5772
  field_11: c.meta_data.dictionary_page_offset,
5642
5773
  field_12: c.meta_data.statistics && unconvertStatistics(c.meta_data.statistics, schemaElement(metadata.schema, c.meta_data.path_in_schema, columnIndex + 1)),
5643
5774
  field_13: c.meta_data.encoding_stats && c.meta_data.encoding_stats.map((es) => ({
5644
- field_1: PageTypes.indexOf(es.page_type),
5645
- field_2: Encodings.indexOf(es.encoding),
5775
+ field_1: PageTypes2.indexOf(es.page_type),
5776
+ field_2: Encodings2.indexOf(es.encoding),
5646
5777
  field_3: es.count
5647
5778
  })),
5648
5779
  field_14: c.meta_data.bloom_filter_offset,
@@ -5695,7 +5826,7 @@ function writeMetadata(writer, metadata) {
5695
5826
  }
5696
5827
  function schemaElement(schema, path, fallbackIndex) {
5697
5828
  if (path?.length) {
5698
- const resolved = getSchemaPath(schema, path).at(-1)?.element;
5829
+ const resolved = getSchemaPath2(schema, path).at(-1)?.element;
5699
5830
  if (resolved)
5700
5831
  return resolved;
5701
5832
  }
@@ -5933,7 +6064,7 @@ ParquetWriter.prototype.write = function({ columnData, rowGroupSize = [100, 1000
5933
6064
  for (let j = 0;j < columnData.length; j++) {
5934
6065
  const { name, data, encoding, columnIndex = false, offsetIndex = false } = columnData[j];
5935
6066
  const groupData = data.slice(groupStartIndex, groupStartIndex + groupSize);
5936
- const schemaTreePath = getSchemaPath(this.schema, [name]);
6067
+ const schemaTreePath = getSchemaPath2(this.schema, [name]);
5937
6068
  const leafPaths = getLeafSchemaPaths(schemaTreePath);
5938
6069
  const columnNode = schemaTreePath.at(-1);
5939
6070
  const normalizedData = columnNode ? Array.from(groupData, (row) => normalizeValue(columnNode, row)) : Array.from(groupData);
@@ -6147,7 +6278,9 @@ async function fetchAndParseMeta(langHash) {
6147
6278
  decoded = decode2(decompressed);
6148
6279
  } catch (error) {
6149
6280
  const detail = error instanceof Error ? error.message : String(error);
6150
- throw new Error(`Failed to decode pf_meta: ${detail}. The Pagefind binary format may have changed.`);
6281
+ throw new Error(`Failed to decode pf_meta: ${detail}. The Pagefind binary format may have changed.`, {
6282
+ cause: error
6283
+ });
6151
6284
  }
6152
6285
  if (!Array.isArray(decoded) || !Array.isArray(decoded[1])) {
6153
6286
  throw new Error("Failed to decode pf_meta: unexpected structure. The Pagefind binary format may have changed.");
@@ -6179,10 +6312,10 @@ async function withConcurrencyLimit(tasks, limit) {
6179
6312
  let running = 0;
6180
6313
  let index = 0;
6181
6314
  let completed = 0;
6182
- return new Promise((resolve) => {
6315
+ return new Promise((resolve2) => {
6183
6316
  function next() {
6184
6317
  if (completed === tasks.length) {
6185
- resolve(results);
6318
+ resolve2(results);
6186
6319
  return;
6187
6320
  }
6188
6321
  while (running < limit && index < tasks.length) {
@@ -6445,61 +6578,53 @@ async function ensureDocsParquet(options) {
6445
6578
  import path4 from "path";
6446
6579
 
6447
6580
  // src/palantir-mcp/allowlist.ts
6448
- function isMutatingTool(toolName) {
6449
- const re = /(?:^|[_-])(create|update|delete|remove|set|write|put|post|patch|deploy|publish|commit|run|execute|trigger|start|stop|cancel|schedule|grant|revoke|upload|import|export)(?:$|[_-])/i;
6450
- return re.test(toolName);
6451
- }
6452
- function isReadOnlyTool(toolName) {
6453
- const re = /(?:^|[_-])(get|list|search|query|describe|read|fetch|inspect|schema|metadata|lineage|preview|validate|diff)(?:$|[_-])/i;
6454
- return re.test(toolName);
6455
- }
6456
6581
  function matchesAny(toolName, patterns) {
6457
6582
  return patterns.some((p) => p.test(toolName));
6458
6583
  }
6584
+ var LIBRARIAN_MUTATION_DENY = [
6585
+ /(?:^|[_-])(create|update|delete|remove|set|write|put|post|patch|deploy|publish|commit|run|execute|trigger|start|stop|cancel|schedule|grant|revoke|upload|import|export|connect|convert|install|clone|close|replace|abort)(?:$|[_-])/i
6586
+ ];
6587
+ var FOUNDRY_DISCOVERY_DENY = [
6588
+ /documentation/i,
6589
+ /(?:^|[_-])search_foundry_(documentation|ontology|functions)(?:$|[_-])/i,
6590
+ /(?:^|[_-])list_platform_sdk_apis(?:$|[_-])/i,
6591
+ /(?:^|[_-])get_platform_sdk_api_reference(?:$|[_-])/i,
6592
+ /(?:^|[_-])get_ontology_sdk_(context|examples)(?:$|[_-])/i,
6593
+ /(?:^|[_-])view_osdk_definition(?:$|[_-])/i
6594
+ ];
6595
+ var PROFILE_POLICIES = {
6596
+ pipelines_transforms: {
6597
+ librarianDeny: [...LIBRARIAN_MUTATION_DENY],
6598
+ foundryDeny: [
6599
+ ...FOUNDRY_DISCOVERY_DENY,
6600
+ /(?:^|[_-])(convert_to_osdk_react|install_sdk_package|generate_new_ontology_sdk_version)(?:$|[_-])/i
6601
+ ]
6602
+ },
6603
+ osdk_functions_ts: {
6604
+ librarianDeny: [...LIBRARIAN_MUTATION_DENY],
6605
+ foundryDeny: [
6606
+ ...FOUNDRY_DISCOVERY_DENY,
6607
+ /(?:^|[_-])(create_python_transforms_code_repository|get_python_transforms_documentation)(?:$|[_-])/i
6608
+ ]
6609
+ },
6610
+ default: {
6611
+ librarianDeny: [...LIBRARIAN_MUTATION_DENY],
6612
+ foundryDeny: [...FOUNDRY_DISCOVERY_DENY]
6613
+ }
6614
+ };
6459
6615
  function computeAllowedTools(profile, toolNames) {
6460
6616
  const uniqueSortedTools = Array.from(new Set(toolNames)).sort((a, b) => a.localeCompare(b));
6617
+ const policy = PROFILE_POLICIES[profile];
6461
6618
  const librarianAllow = new Set;
6462
- const pipelinesBoost = [
6463
- /pipeline/i,
6464
- /transform/i,
6465
- /job/i,
6466
- /dataset/i,
6467
- /ontology/i,
6468
- /object/i,
6469
- /action/i,
6470
- /lineage/i,
6471
- /schema/i,
6472
- /preview/i
6473
- ];
6474
- const osdkBoost = [
6475
- /osdk/i,
6476
- /function/i,
6477
- /artifact/i,
6478
- /package/i,
6479
- /release/i,
6480
- /deploy/i
6481
- ];
6619
+ const foundryAllow = new Set;
6482
6620
  for (const name of uniqueSortedTools) {
6483
- if (isMutatingTool(name))
6484
- continue;
6485
- if (profile === "all") {
6621
+ if (!matchesAny(name, policy.librarianDeny)) {
6486
6622
  librarianAllow.add(name);
6487
- continue;
6488
6623
  }
6489
- if (isReadOnlyTool(name)) {
6490
- librarianAllow.add(name);
6491
- continue;
6492
- }
6493
- if (profile === "pipelines_transforms" && matchesAny(name, pipelinesBoost)) {
6494
- librarianAllow.add(name);
6495
- continue;
6496
- }
6497
- if (profile === "osdk_functions_ts" && matchesAny(name, osdkBoost)) {
6498
- librarianAllow.add(name);
6499
- continue;
6624
+ if (!matchesAny(name, policy.foundryDeny)) {
6625
+ foundryAllow.add(name);
6500
6626
  }
6501
6627
  }
6502
- const foundryAllow = new Set(librarianAllow);
6503
6628
  return { librarianAllow, foundryAllow };
6504
6629
  }
6505
6630
 
@@ -6621,8 +6746,8 @@ ${errText}`));
6621
6746
  const req = { jsonrpc: "2.0", id, method, params };
6622
6747
  const line = `${JSON.stringify(req)}
6623
6748
  `;
6624
- const p = new Promise((resolve, reject) => {
6625
- pending.set(id, { resolve, reject });
6749
+ const p = new Promise((resolve2, reject) => {
6750
+ pending.set(id, { resolve: resolve2, reject });
6626
6751
  });
6627
6752
  await writeStdin(line);
6628
6753
  return p;
@@ -6646,7 +6771,9 @@ ${errText}`));
6646
6771
  } catch (err) {
6647
6772
  const stderrText = stderrChunks.join("");
6648
6773
  throw new Error(`[ERROR] Failed to list palantir-mcp tools: ${formatError3(err)}
6649
- ${stderrText}`);
6774
+ ${stderrText}`, {
6775
+ cause: err
6776
+ });
6650
6777
  } finally {
6651
6778
  try {
6652
6779
  proc.kill();
@@ -7670,9 +7797,11 @@ function ensureAgentBase(data, agentName) {
7670
7797
  }
7671
7798
  function ensureAgentDefaults(agent, agentName) {
7672
7799
  const defaultDescription = agentName === "foundry-librarian" ? "Foundry exploration and context gathering (parallel-friendly)" : "Foundry execution agent (uses only enabled palantir-mcp tools)";
7800
+ const defaultMode = agentName === "foundry" ? "all" : "subagent";
7673
7801
  const mode = agent["mode"];
7674
- if (typeof mode !== "string")
7675
- agent["mode"] = "subagent";
7802
+ if (mode !== "subagent" && mode !== "primary" && mode !== "all") {
7803
+ agent["mode"] = defaultMode;
7804
+ }
7676
7805
  if (typeof agent["hidden"] !== "boolean")
7677
7806
  agent["hidden"] = false;
7678
7807
  if (typeof agent["description"] !== "string") {
@@ -7861,205 +7990,116 @@ async function readTextFileBounded(p, maxBytes) {
7861
7990
  return null;
7862
7991
  }
7863
7992
  }
7864
- function addScore(scores, reasons, profile, delta, reason) {
7865
- scores[profile] += delta;
7866
- reasons.push(reason);
7867
- }
7868
- function pickBestProfile(scores) {
7869
- const threshold = 3;
7870
- const ordered = ["all", "pipelines_transforms", "osdk_functions_ts", "unknown"];
7871
- let best = "unknown";
7872
- let bestScore = -1;
7873
- for (const p of ordered) {
7874
- const s = scores[p];
7875
- if (s > bestScore) {
7876
- best = p;
7877
- bestScore = s;
7878
- }
7879
- }
7880
- if (bestScore < threshold)
7881
- return "unknown";
7882
- return best;
7883
- }
7884
- async function parsePackageJson(p) {
7885
- const text = await readTextFileBounded(p, 200000);
7886
- if (!text)
7993
+ async function getPackageJson(root, context) {
7994
+ if (context.packageJsonLoaded)
7995
+ return context.packageJson;
7996
+ context.packageJsonLoaded = true;
7997
+ const packageJsonPath = path3.join(root, "package.json");
7998
+ const text = await readTextFileBounded(packageJsonPath, 200000);
7999
+ if (!text) {
8000
+ context.packageJson = null;
7887
8001
  return null;
8002
+ }
7888
8003
  try {
7889
- return JSON.parse(text);
8004
+ context.packageJson = JSON.parse(text);
7890
8005
  } catch {
7891
- return null;
7892
- }
7893
- }
7894
- function getAllDependencyKeys(pkg) {
7895
- const deps = pkg.dependencies ?? {};
7896
- const dev = pkg.devDependencies ?? {};
7897
- const peer = pkg.peerDependencies ?? {};
7898
- return Object.keys({ ...deps, ...dev, ...peer });
7899
- }
7900
- async function collectSampleFiles(root, limit) {
7901
- const ignoreDirs = new Set([
7902
- ".git",
7903
- "node_modules",
7904
- "dist",
7905
- ".opencode",
7906
- "data",
7907
- ".memory",
7908
- ".sisyphus",
7909
- ".zed",
7910
- ".mise",
7911
- "coverage",
7912
- "build"
7913
- ]);
7914
- const allowedExts = new Set([
7915
- ".md",
7916
- ".ts",
7917
- ".js",
7918
- ".py",
7919
- ".yaml",
7920
- ".yml",
7921
- ".toml",
7922
- ".json"
7923
- ]);
7924
- const results = [];
7925
- const queue = [root];
7926
- const maxDirs = 1500;
7927
- let visitedDirs = 0;
7928
- while (queue.length > 0 && results.length < limit && visitedDirs < maxDirs) {
7929
- const dir = queue.shift() ?? "";
7930
- if (!dir)
7931
- continue;
7932
- visitedDirs += 1;
7933
- let entries;
7934
- try {
7935
- entries = await fs3.readdir(dir, { withFileTypes: true });
7936
- } catch {
7937
- continue;
8006
+ context.packageJson = null;
8007
+ }
8008
+ return context.packageJson;
8009
+ }
8010
+ async function getPyprojectText(root, context) {
8011
+ if (context.pyprojectLoaded)
8012
+ return context.pyprojectText;
8013
+ context.pyprojectLoaded = true;
8014
+ context.pyprojectText = await readTextFileBounded(path3.join(root, "pyproject.toml"), 200000);
8015
+ return context.pyprojectText;
8016
+ }
8017
+ async function getRequirementsText(root, context) {
8018
+ if (context.requirementsLoaded)
8019
+ return context.requirementsText;
8020
+ context.requirementsLoaded = true;
8021
+ context.requirementsText = await readTextFileBounded(path3.join(root, "requirements.txt"), 200000);
8022
+ return context.requirementsText;
8023
+ }
8024
+ function listDependencyNames(pkg) {
8025
+ if (!pkg)
8026
+ return [];
8027
+ const dependencies = pkg.dependencies ?? {};
8028
+ const devDependencies = pkg.devDependencies ?? {};
8029
+ const peerDependencies = pkg.peerDependencies ?? {};
8030
+ return Object.keys({ ...dependencies, ...devDependencies, ...peerDependencies });
8031
+ }
8032
+ var HARD_SIGNATURES = [
8033
+ {
8034
+ profile: "pipelines_transforms",
8035
+ reason: "Found transforms/ directory.",
8036
+ matches: async (root) => pathExists2(path3.join(root, "transforms"))
8037
+ },
8038
+ {
8039
+ profile: "pipelines_transforms",
8040
+ reason: "Found pipelines/ directory.",
8041
+ matches: async (root) => pathExists2(path3.join(root, "pipelines"))
8042
+ },
8043
+ {
8044
+ profile: "pipelines_transforms",
8045
+ reason: "Found internal/transforms/ directory.",
8046
+ matches: async (root) => pathExists2(path3.join(root, "internal", "transforms"))
8047
+ },
8048
+ {
8049
+ profile: "pipelines_transforms",
8050
+ reason: "Found internal/pipeline/ directory.",
8051
+ matches: async (root) => pathExists2(path3.join(root, "internal", "pipeline"))
8052
+ },
8053
+ {
8054
+ profile: "pipelines_transforms",
8055
+ reason: "pyproject.toml references transforms.api.",
8056
+ matches: async (root, context) => {
8057
+ const text = await getPyprojectText(root, context);
8058
+ if (!text)
8059
+ return false;
8060
+ return /\btransforms\.api\b/i.test(text);
7938
8061
  }
7939
- for (const ent of entries) {
7940
- if (results.length >= limit)
7941
- break;
7942
- const full = path3.join(dir, ent.name);
7943
- if (ent.isDirectory()) {
7944
- if (ignoreDirs.has(ent.name))
7945
- continue;
7946
- queue.push(full);
7947
- continue;
7948
- }
7949
- if (!ent.isFile())
7950
- continue;
7951
- const ext = path3.extname(ent.name);
7952
- if (!allowedExts.has(ext))
7953
- continue;
7954
- results.push(full);
8062
+ },
8063
+ {
8064
+ profile: "pipelines_transforms",
8065
+ reason: "requirements.txt references transforms.api.",
8066
+ matches: async (root, context) => {
8067
+ const text = await getRequirementsText(root, context);
8068
+ if (!text)
8069
+ return false;
8070
+ return /\btransforms\.api\b/i.test(text);
8071
+ }
8072
+ },
8073
+ {
8074
+ profile: "osdk_functions_ts",
8075
+ reason: "package.json includes an @osdk/* dependency.",
8076
+ matches: async (root, context) => {
8077
+ const depNames = listDependencyNames(await getPackageJson(root, context));
8078
+ return depNames.some((name) => name.startsWith("@osdk/"));
7955
8079
  }
7956
8080
  }
7957
- return results;
7958
- }
8081
+ ];
7959
8082
  async function scanRepoForProfile(root) {
7960
- const scores = {
7961
- pipelines_transforms: 0,
7962
- osdk_functions_ts: 0,
7963
- all: 0,
7964
- unknown: 0
8083
+ const context = {
8084
+ packageJson: null,
8085
+ packageJsonLoaded: false,
8086
+ pyprojectText: null,
8087
+ pyprojectLoaded: false,
8088
+ requirementsText: null,
8089
+ requirementsLoaded: false
7965
8090
  };
7966
- const reasons = [];
7967
- const candidates = [
7968
- { p: "pnpm-workspace.yaml", profile: "all", score: 3, reason: "Found pnpm-workspace.yaml" },
7969
- { p: "turbo.json", profile: "all", score: 3, reason: "Found turbo.json" },
7970
- { p: "nx.json", profile: "all", score: 3, reason: "Found nx.json" },
7971
- { p: "lerna.json", profile: "all", score: 3, reason: "Found lerna.json" }
7972
- ];
7973
- for (const c of candidates) {
7974
- if (await pathExists2(path3.join(root, c.p))) {
7975
- addScore(scores, reasons, c.profile, c.score, c.reason);
7976
- }
7977
- }
7978
- const packageJsonPath = path3.join(root, "package.json");
7979
- const pyprojectPath = path3.join(root, "pyproject.toml");
7980
- const requirementsPath = path3.join(root, "requirements.txt");
7981
- const hasPackageJson = await pathExists2(packageJsonPath);
7982
- const hasPyproject = await pathExists2(pyprojectPath);
7983
- if (hasPackageJson && hasPyproject) {
7984
- addScore(scores, reasons, "all", 2, "Found both package.json and pyproject.toml");
7985
- }
7986
- if (hasPackageJson) {
7987
- const pkg = await parsePackageJson(packageJsonPath);
7988
- if (pkg) {
7989
- const depKeys = getAllDependencyKeys(pkg);
7990
- if (depKeys.some((d) => d.toLowerCase().includes("osdk") || d.startsWith("@osdk/"))) {
7991
- addScore(scores, reasons, "osdk_functions_ts", 5, "package.json includes OSDK dependency");
7992
- }
7993
- if (depKeys.some((d) => d.toLowerCase().includes("palantir") || d.toLowerCase().includes("foundry"))) {
7994
- addScore(scores, reasons, "pipelines_transforms", 1, "package.json references palantir/foundry");
7995
- }
7996
- }
7997
- }
7998
- if (hasPyproject) {
7999
- const text = await readTextFileBounded(pyprojectPath, 200000);
8000
- if (text) {
8001
- if (/foundry/i.test(text)) {
8002
- addScore(scores, reasons, "pipelines_transforms", 1, "pyproject.toml mentions foundry");
8003
- }
8004
- if (/transform/i.test(text)) {
8005
- addScore(scores, reasons, "pipelines_transforms", 1, "pyproject.toml mentions transform");
8006
- }
8007
- }
8008
- }
8009
- if (await pathExists2(requirementsPath)) {
8010
- const text = await readTextFileBounded(requirementsPath, 200000);
8011
- if (text) {
8012
- if (/foundry/i.test(text)) {
8013
- addScore(scores, reasons, "pipelines_transforms", 1, "requirements.txt mentions foundry");
8014
- }
8015
- if (/transform/i.test(text)) {
8016
- addScore(scores, reasons, "pipelines_transforms", 1, "requirements.txt mentions transform");
8017
- }
8091
+ for (const signature of HARD_SIGNATURES) {
8092
+ if (await signature.matches(root, context)) {
8093
+ return {
8094
+ profile: signature.profile,
8095
+ reasons: [signature.reason]
8096
+ };
8018
8097
  }
8019
8098
  }
8020
- if (await pathExists2(path3.join(root, "pipelines"))) {
8021
- addScore(scores, reasons, "pipelines_transforms", 3, "Found pipelines/ directory");
8022
- }
8023
- if (await pathExists2(path3.join(root, "transforms"))) {
8024
- addScore(scores, reasons, "pipelines_transforms", 3, "Found transforms/ directory");
8025
- }
8026
- if (await pathExists2(path3.join(root, "internal", "pipeline"))) {
8027
- addScore(scores, reasons, "pipelines_transforms", 3, "Found internal/pipeline/ directory");
8028
- }
8029
- if (await pathExists2(path3.join(root, "internal", "transforms"))) {
8030
- addScore(scores, reasons, "pipelines_transforms", 3, "Found internal/transforms/ directory");
8031
- }
8032
- if (await pathExists2(path3.join(root, "functions"))) {
8033
- addScore(scores, reasons, "osdk_functions_ts", 2, "Found functions/ directory");
8034
- }
8035
- if (await pathExists2(path3.join(root, "src", "functions"))) {
8036
- addScore(scores, reasons, "osdk_functions_ts", 2, "Found src/functions/ directory");
8037
- }
8038
- const sampleFiles = await collectSampleFiles(root, 50);
8039
- const maxTotalBytes = 200000;
8040
- let consumedBytes = 0;
8041
- let pipelinesHits = 0;
8042
- let osdkHits = 0;
8043
- for (const p of sampleFiles) {
8044
- if (consumedBytes >= maxTotalBytes)
8045
- break;
8046
- const text = await readTextFileBounded(p, 8000);
8047
- if (!text)
8048
- continue;
8049
- consumedBytes += text.length;
8050
- if (/\b(pipeline|pipelines|transform|transforms)\b/i.test(text))
8051
- pipelinesHits += 1;
8052
- if (/\bosdk\b/i.test(text))
8053
- osdkHits += 1;
8054
- }
8055
- if (pipelinesHits >= 3) {
8056
- addScore(scores, reasons, "pipelines_transforms", 2, `Keyword sample hits pipelines/transforms (${pipelinesHits})`);
8057
- }
8058
- if (osdkHits >= 2) {
8059
- addScore(scores, reasons, "osdk_functions_ts", 2, `Keyword sample hits osdk (${osdkHits})`);
8060
- }
8061
- const profile = pickBestProfile(scores);
8062
- return { profile, scores, reasons };
8099
+ return {
8100
+ profile: "default",
8101
+ reasons: ["No hard signature matched. Falling back to default profile."]
8102
+ };
8063
8103
  }
8064
8104
 
8065
8105
  // src/palantir-mcp/commands.ts
@@ -8105,15 +8145,33 @@ function formatPatchSummary(patch) {
8105
8145
  return lines.join(`
8106
8146
  `);
8107
8147
  }
8148
+ function getTrimmedEnvVar(name) {
8149
+ const raw = process.env[name];
8150
+ if (!raw)
8151
+ return null;
8152
+ const trimmed = raw.trim();
8153
+ return trimmed.length > 0 ? trimmed : null;
8154
+ }
8155
+ function formatMissingEnvGuidance(missingVars) {
8156
+ const exports = missingVars.map((name) => `export ${name}=...`).join(`
8157
+ `);
8158
+ return [
8159
+ `[ERROR] Missing required environment: ${missingVars.join(", ")}`,
8160
+ "",
8161
+ "Foundry MCP setup is inactive until these are exported.",
8162
+ "Local docs tools (`get_doc_page`, `list_all_docs`) remain available.",
8163
+ "",
8164
+ "Set:",
8165
+ ` ${exports}`
8166
+ ].join(`
8167
+ `);
8168
+ }
8108
8169
  async function resolveProfile(worktree) {
8109
8170
  try {
8110
8171
  const scan = await scanRepoForProfile(worktree);
8111
- return { profile: scan.profile, reasons: scan.reasons };
8172
+ return scan.profile;
8112
8173
  } catch (err) {
8113
- return {
8114
- profile: "unknown",
8115
- reasons: [`Repo scan failed; falling back to unknown: ${formatError5(err)}`]
8116
- };
8174
+ return "default";
8117
8175
  }
8118
8176
  }
8119
8177
  function hasPalantirToolToggles(data, agentName) {
@@ -8137,11 +8195,11 @@ function isAutoBootstrapAlreadyComplete(data) {
8137
8195
  }
8138
8196
  async function autoBootstrapPalantirMcpIfConfigured(worktree) {
8139
8197
  try {
8140
- const tokenRaw = process.env.FOUNDRY_TOKEN;
8141
- const urlRaw = process.env.FOUNDRY_URL;
8142
- if (!tokenRaw || tokenRaw.trim().length === 0)
8198
+ const tokenRaw = getTrimmedEnvVar("FOUNDRY_TOKEN");
8199
+ const urlRaw = getTrimmedEnvVar("FOUNDRY_URL");
8200
+ if (!tokenRaw)
8143
8201
  return;
8144
- if (!urlRaw || urlRaw.trim().length === 0)
8202
+ if (!urlRaw)
8145
8203
  return;
8146
8204
  const normalized = normalizeFoundryBaseUrl(urlRaw);
8147
8205
  if ("error" in normalized)
@@ -8159,7 +8217,7 @@ async function autoBootstrapPalantirMcpIfConfigured(worktree) {
8159
8217
  return;
8160
8218
  const existingMcpUrlRaw = extractFoundryApiUrlFromMcpConfig(merged);
8161
8219
  const existingMcpUrlNorm = existingMcpUrlRaw ? normalizeFoundryBaseUrl(existingMcpUrlRaw) : null;
8162
- const { profile } = await resolveProfile(worktree);
8220
+ const profile = await resolveProfile(worktree);
8163
8221
  const discoveryUrl = existingMcpUrlNorm && "url" in existingMcpUrlNorm ? existingMcpUrlNorm.url : normalized.url;
8164
8222
  const toolNames = await listPalantirMcpTools(discoveryUrl);
8165
8223
  if (toolNames.length === 0)
@@ -8188,18 +8246,21 @@ async function autoBootstrapPalantirMcpIfConfigured(worktree) {
8188
8246
  }
8189
8247
  async function setupPalantirMcp(worktree, rawArgs) {
8190
8248
  const urlFromArgs = rawArgs.trim();
8191
- const urlFromEnvRaw = process.env.FOUNDRY_URL;
8192
- const urlFromEnv = typeof urlFromEnvRaw === "string" ? urlFromEnvRaw.trim() : "";
8193
- const urlArg = urlFromArgs || urlFromEnv;
8249
+ const urlFromEnv = getTrimmedEnvVar("FOUNDRY_URL");
8250
+ const token = getTrimmedEnvVar("FOUNDRY_TOKEN");
8251
+ const urlArg = urlFromArgs || urlFromEnv || "";
8194
8252
  if (!urlArg) {
8253
+ const missingVars = ["FOUNDRY_URL"];
8254
+ if (!token)
8255
+ missingVars.push("FOUNDRY_TOKEN");
8195
8256
  return [
8196
- "[ERROR] Missing Foundry base URL.",
8257
+ formatMissingEnvGuidance(missingVars),
8197
8258
  "",
8198
8259
  "Usage:",
8199
8260
  " /setup-palantir-mcp <foundry_api_url>",
8200
8261
  "",
8201
- "Or set:",
8202
- " export FOUNDRY_URL=<foundry_api_url>",
8262
+ "Or pass URL directly:",
8263
+ " /setup-palantir-mcp https://YOUR-STACK.palantirfoundry.com",
8203
8264
  "",
8204
8265
  "Example:",
8205
8266
  " /setup-palantir-mcp https://23dimethyl.usw-3.palantirfoundry.com"
@@ -8209,17 +8270,8 @@ async function setupPalantirMcp(worktree, rawArgs) {
8209
8270
  const normalized = normalizeFoundryBaseUrl(urlArg);
8210
8271
  if ("error" in normalized)
8211
8272
  return `[ERROR] ${normalized.error}`;
8212
- if (!process.env.FOUNDRY_TOKEN) {
8213
- return [
8214
- "[ERROR] FOUNDRY_TOKEN is not set in your environment.",
8215
- "",
8216
- "palantir-mcp tool discovery requires a token. Export FOUNDRY_TOKEN and retry.",
8217
- "",
8218
- "Tip: if `echo $FOUNDRY_TOKEN` prints a value but this still errors, it is likely " + "not exported.",
8219
- "Run `export FOUNDRY_TOKEN` (or set `export FOUNDRY_TOKEN=...` in your shell " + "secrets) and retry."
8220
- ].join(`
8221
- `);
8222
- }
8273
+ if (!token)
8274
+ return formatMissingEnvGuidance(["FOUNDRY_TOKEN"]);
8223
8275
  const readJsonc = await readOpencodeJsonc(worktree);
8224
8276
  if (!readJsonc.ok && "error" in readJsonc)
8225
8277
  return readJsonc.error;
@@ -8231,7 +8283,7 @@ async function setupPalantirMcp(worktree, rawArgs) {
8231
8283
  const merged = readLegacy.ok ? mergeLegacyIntoJsonc(readLegacy.data, base) : { ...base };
8232
8284
  const existingMcpUrlRaw = extractFoundryApiUrlFromMcpConfig(merged);
8233
8285
  const existingMcpUrlNorm = existingMcpUrlRaw ? normalizeFoundryBaseUrl(existingMcpUrlRaw) : null;
8234
- const { profile } = await resolveProfile(worktree);
8286
+ const profile = await resolveProfile(worktree);
8235
8287
  const discoveryUrl = existingMcpUrlNorm && "url" in existingMcpUrlNorm ? existingMcpUrlNorm.url : normalized.url;
8236
8288
  let toolNames;
8237
8289
  try {
@@ -8281,17 +8333,8 @@ Migrated legacy ${readLegacy.path} -> ${bakPath}`;
8281
8333
  `);
8282
8334
  }
8283
8335
  async function rescanPalantirMcpTools(worktree) {
8284
- if (!process.env.FOUNDRY_TOKEN) {
8285
- return [
8286
- "[ERROR] FOUNDRY_TOKEN is not set in your environment.",
8287
- "",
8288
- "palantir-mcp tool discovery requires a token. Export FOUNDRY_TOKEN and retry.",
8289
- "",
8290
- "Tip: if `echo $FOUNDRY_TOKEN` prints a value but this still errors, it is likely " + "not exported.",
8291
- "Run `export FOUNDRY_TOKEN` (or set `export FOUNDRY_TOKEN=...` in your shell " + "secrets) and retry."
8292
- ].join(`
8293
- `);
8294
- }
8336
+ if (!getTrimmedEnvVar("FOUNDRY_TOKEN"))
8337
+ return formatMissingEnvGuidance(["FOUNDRY_TOKEN"]);
8295
8338
  const readJsonc = await readOpencodeJsonc(worktree);
8296
8339
  if (!readJsonc.ok) {
8297
8340
  if ("missing" in readJsonc) {
@@ -8313,7 +8356,7 @@ async function rescanPalantirMcpTools(worktree) {
8313
8356
  const normalized = normalizeFoundryBaseUrl(foundryUrlRaw);
8314
8357
  if ("error" in normalized)
8315
8358
  return `[ERROR] Invalid Foundry URL in config: ${normalized.error}`;
8316
- const { profile } = await resolveProfile(worktree);
8359
+ const profile = await resolveProfile(worktree);
8317
8360
  let toolNames;
8318
8361
  try {
8319
8362
  toolNames = await listPalantirMcpTools(normalized.url);
@@ -8364,9 +8407,23 @@ var plugin = async (input) => {
8364
8407
  const decimals = value >= 10 || index === 0 ? 0 : 1;
8365
8408
  return `${value.toFixed(decimals)} ${units[index]}`;
8366
8409
  }
8410
+ function getMissingFoundryEnvVars() {
8411
+ const missing = [];
8412
+ const url = process.env.FOUNDRY_URL;
8413
+ const token = process.env.FOUNDRY_TOKEN;
8414
+ if (!url || url.trim().length === 0)
8415
+ missing.push("FOUNDRY_URL");
8416
+ if (!token || token.trim().length === 0)
8417
+ missing.push("FOUNDRY_TOKEN");
8418
+ return missing;
8419
+ }
8367
8420
  function ensureCommandDefinitions(cfg) {
8368
8421
  if (!cfg.command)
8369
8422
  cfg.command = {};
8423
+ const missingEnvVars = getMissingFoundryEnvVars();
8424
+ const hasMissingToken = missingEnvVars.includes("FOUNDRY_TOKEN");
8425
+ const setupEnvSuffix = missingEnvVars.length === 0 ? "" : ` Missing env: ${missingEnvVars.join(", ")}. Local docs tools remain available.`;
8426
+ const rescanEnvSuffix = hasMissingToken ? " Missing env: FOUNDRY_TOKEN. Local docs tools remain available." : "";
8370
8427
  if (!cfg.command["refresh-docs"]) {
8371
8428
  cfg.command["refresh-docs"] = {
8372
8429
  template: "Refresh Palantir docs snapshot (recommended).",
@@ -8382,20 +8439,23 @@ var plugin = async (input) => {
8382
8439
  if (!cfg.command["setup-palantir-mcp"]) {
8383
8440
  cfg.command["setup-palantir-mcp"] = {
8384
8441
  template: "Set up palantir-mcp for this repo.",
8385
- description: "Guided MCP setup for Foundry. Usage: /setup-palantir-mcp <foundry_api_url>. Requires FOUNDRY_TOKEN for tool discovery."
8442
+ description: `Guided MCP setup for Foundry. Usage: /setup-palantir-mcp <foundry_api_url>. Requires FOUNDRY_TOKEN for tool discovery.${setupEnvSuffix}`
8386
8443
  };
8387
8444
  }
8388
8445
  if (!cfg.command["rescan-palantir-mcp-tools"]) {
8389
8446
  cfg.command["rescan-palantir-mcp-tools"] = {
8390
8447
  template: "Re-scan palantir-mcp tools and patch tool gating.",
8391
- description: "Re-discovers the palantir-mcp tool list and adds missing palantir-mcp_* toggles (does not overwrite existing toggles). Requires FOUNDRY_TOKEN."
8448
+ description: `Re-discovers the palantir-mcp tool list and adds missing palantir-mcp_* toggles (does not overwrite existing toggles). Requires FOUNDRY_TOKEN.${rescanEnvSuffix}`
8392
8449
  };
8393
8450
  }
8394
8451
  }
8395
8452
  function ensureAgentDefaults2(agent, agentName) {
8396
- const defaultDescription = agentName === "foundry-librarian" ? "Foundry exploration and context gathering (parallel-friendly)" : "Foundry execution agent (uses only enabled palantir-mcp tools)";
8453
+ const missingEnvVars = getMissingFoundryEnvVars();
8454
+ const envSuffix = missingEnvVars.length === 0 ? "" : ` (inactive until ${missingEnvVars.join(" and ")} ${missingEnvVars.length === 1 ? "is" : "are"} exported)`;
8455
+ const defaultDescription = agentName === "foundry-librarian" ? `Foundry exploration and context gathering (parallel-friendly)${envSuffix}` : `Foundry execution agent (uses only enabled palantir-mcp tools)${envSuffix}`;
8456
+ const defaultMode = agentName === "foundry" ? "all" : "subagent";
8397
8457
  if (agent.mode !== "subagent" && agent.mode !== "primary" && agent.mode !== "all") {
8398
- agent.mode = "subagent";
8458
+ agent.mode = defaultMode;
8399
8459
  }
8400
8460
  if (typeof agent["hidden"] !== "boolean")
8401
8461
  agent["hidden"] = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openontology/opencode-palantir",
3
- "version": "0.1.5-next.4",
3
+ "version": "0.1.5-next.9",
4
4
  "description": "collection of tools, agents, hooks to supercharge development in foundry",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -29,26 +29,26 @@
29
29
  ],
30
30
  "private": false,
31
31
  "peerDependencies": {
32
- "@opencode-ai/plugin": "^1.1.51"
32
+ "@opencode-ai/plugin": "^1.2.6"
33
33
  },
34
34
  "devDependencies": {
35
- "@opencode-ai/plugin": "1.1.51",
36
- "@eslint/js": "^9.39.1",
37
- "@types/node": "^20.11.5",
38
- "@typescript-eslint/eslint-plugin": "8.47.0",
39
- "@typescript-eslint/parser": "8.47.0",
40
- "bun-types": "latest",
41
- "eslint": "^9.39.1",
35
+ "@eslint/js": "10.0.1",
36
+ "@opencode-ai/plugin": "1.2.6",
37
+ "@types/node": "25.2.3",
38
+ "@typescript-eslint/eslint-plugin": "8.56.0",
39
+ "@typescript-eslint/parser": "8.56.0",
40
+ "bun-types": "1.3.9",
41
+ "eslint": "10.0.0",
42
42
  "eslint-config-prettier": "10.1.8",
43
43
  "eslint-plugin-prettier": "^5.1.3",
44
44
  "hyparquet-writer": "^0.12.0",
45
45
  "prettier": "^3.2.4",
46
- "typescript-eslint": "^8.47.0",
47
- "vitest": "^3.2.4"
46
+ "typescript-eslint": "^8.56.0",
47
+ "vitest": "4.0.18"
48
48
  },
49
49
  "dependencies": {
50
50
  "cborg": "^4.5.8",
51
- "hyparquet": "^1.24.1",
51
+ "hyparquet": "^1.25.0",
52
52
  "jsonc-parser": "^3.3.1"
53
53
  }
54
54
  }