@jagilber-org/index-server 1.28.10 → 1.28.19

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 (73) hide show
  1. package/CHANGELOG.md +109 -1
  2. package/CONTRIBUTING.md +13 -0
  3. package/README.md +10 -14
  4. package/dist/config/featureConfig.js +4 -1
  5. package/dist/dashboard/client/admin.html +69 -29
  6. package/dist/dashboard/client/js/admin.embeddings.js +97 -5
  7. package/dist/dashboard/client/js/admin.instructions.js +1 -1
  8. package/dist/dashboard/server/AdminPanel.js +38 -0
  9. package/dist/dashboard/server/ApiRoutes.js +14 -1
  10. package/dist/dashboard/server/routes/embeddings.routes.js +76 -1
  11. package/dist/dashboard/server/routes/instructions.routes.js +4 -11
  12. package/dist/dashboard/server/routes/scripts.routes.js +35 -10
  13. package/dist/dashboard/server/routes/status.routes.js +77 -0
  14. package/dist/models/instruction.d.ts +2 -1
  15. package/dist/models/instruction.js +2 -0
  16. package/dist/schemas/index-server.code-schema.json +52478 -0
  17. package/dist/schemas/index.d.ts +7 -164
  18. package/dist/schemas/index.js +45 -63
  19. package/dist/schemas/instructionSchema.d.ts +46 -0
  20. package/dist/schemas/instructionSchema.js +159 -0
  21. package/{schemas → dist/schemas}/json-schema/instruction-content-type.schema.json +6 -4
  22. package/{schemas → dist/schemas}/json-schema/instruction-instruction-entry.schema.json +6 -4
  23. package/dist/schemas/manifest.json +78 -0
  24. package/dist/server/index-server.js +7 -1
  25. package/dist/services/bootstrapGating.js +2 -2
  26. package/dist/services/handlers/instructions.add.js +18 -0
  27. package/dist/services/handlers/instructions.groom.js +6 -1
  28. package/dist/services/handlers/instructions.import.js +42 -7
  29. package/dist/services/handlers.activation.js +3 -1
  30. package/dist/services/handlers.dashboardConfig.js +2 -1
  31. package/dist/services/handlers.feedback.d.ts +4 -4
  32. package/dist/services/handlers.feedback.js +390 -27
  33. package/dist/services/handlers.instructionSchema.js +73 -31
  34. package/dist/services/handlers.search.js +11 -6
  35. package/dist/services/indexLoader.js +7 -0
  36. package/dist/services/instructionRecordValidation.js +32 -84
  37. package/dist/services/mcpConfig/flagCatalog.d.ts +1 -1
  38. package/dist/services/mcpConfig/flagCatalog.js +2 -0
  39. package/dist/services/mcpConfig/formats.js +2 -6
  40. package/dist/services/seedBootstrap.contentModel.d.ts +13 -0
  41. package/dist/services/seedBootstrap.contentModel.js +166 -0
  42. package/dist/services/seedBootstrap.contentTypes.d.ts +5 -0
  43. package/dist/services/seedBootstrap.contentTypes.js +76 -0
  44. package/dist/services/seedBootstrap.d.ts +1 -0
  45. package/dist/services/seedBootstrap.js +87 -10
  46. package/dist/services/toolRegistry.js +52 -24
  47. package/dist/services/toolRegistry.zod.js +84 -37
  48. package/dist/versioning/schemaVersion.d.ts +1 -1
  49. package/dist/versioning/schemaVersion.js +1 -13
  50. package/package.json +17 -3
  51. package/schemas/index-server.code-schema.json +31019 -25047
  52. package/schemas/instruction.schema.json +16 -6
  53. package/schemas/manifest.json +3 -3
  54. package/scripts/README.md +20 -0
  55. package/scripts/build/README.md +41 -0
  56. package/scripts/build/setup-wizard-paths.mjs +27 -0
  57. package/scripts/build/setup-wizard.mjs +7 -21
  58. package/scripts/client/README.md +26 -0
  59. package/scripts/client/index-server-client.ps1 +203 -0
  60. package/scripts/client/index-server-client.sh +149 -0
  61. package/scripts/client/powershell-mcp-server.ps1 +83 -0
  62. package/scripts/client/powershell-mcp-template.ps1 +85 -0
  63. package/scripts/hooks/README.md +40 -0
  64. package/server.json +2 -2
  65. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-admin-session.schema.json +0 -0
  66. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +0 -0
  67. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +0 -0
  68. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-config.schema.json +0 -0
  69. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-data.schema.json +0 -0
  70. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-manifest.schema.json +0 -0
  71. /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-metadata.schema.json +0 -0
  72. /package/{schemas → dist/schemas}/json-schema/instruction-audience-scope.schema.json +0 -0
  73. /package/{schemas → dist/schemas}/json-schema/instruction-requirement-level.schema.json +0 -0
@@ -49,6 +49,9 @@ const registry_1 = require("../server/registry");
49
49
  const fs = __importStar(require("fs"));
50
50
  const path = __importStar(require("path"));
51
51
  const runtimeConfig_1 = require("../config/runtimeConfig");
52
+ const instructionSchema_1 = require("../schemas/instructionSchema");
53
+ const instruction_1 = require("../models/instruction");
54
+ const schemaVersion_1 = require("../versioning/schemaVersion");
52
55
  const SCHEMA_VERSION = '1.0.0';
53
56
  /**
54
57
  * Load the canonical instruction.schema.json from disk
@@ -58,7 +61,14 @@ function loadInstructionSchema() {
58
61
  return JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
59
62
  }
60
63
  /**
61
- * Build a minimal valid instruction entry template
64
+ * Build a minimal valid instruction entry template.
65
+ *
66
+ * INPUT-ONLY: every property below must be a member of INPUT_KEYS (the
67
+ * canonical input surface). Server-managed fields like `schemaVersion`,
68
+ * `sourceHash`, `createdAt`, `updatedAt` are NEVER part of this example
69
+ * because the canonical INPUT_SCHEMA rejects them
70
+ * (additionalProperties:false). For the full on-disk record shape see
71
+ * `buildRecordExample()`.
62
72
  */
63
73
  function buildMinimalExample() {
64
74
  return {
@@ -70,8 +80,45 @@ function buildMinimalExample() {
70
80
  requirement: "recommended",
71
81
  categories: ["example", "documentation"],
72
82
  primaryCategory: "example",
83
+ contentType: "instruction"
84
+ };
85
+ }
86
+ /**
87
+ * Build a record-shape example showing the FULL on-disk shape, including
88
+ * server-managed fields. Documentation-only — do NOT submit this payload
89
+ * to `index_add` / `index_import`; the canonical INPUT_SCHEMA strips
90
+ * server-managed keys.
91
+ */
92
+ function buildRecordExample() {
93
+ const now = new Date().toISOString();
94
+ return {
95
+ // ── caller-supplied (INPUT_KEYS) ────────────────────────────────
96
+ id: "example-instruction-id",
97
+ title: "Example Instruction Title",
98
+ body: "Full record example with all governance metadata.",
99
+ priority: 50,
100
+ audience: "all",
101
+ requirement: "recommended",
102
+ categories: ["example", "documentation"],
103
+ primaryCategory: "example",
73
104
  contentType: "instruction",
74
- schemaVersion: "5"
105
+ semanticSummary: "Example instruction demonstrating full record shape.",
106
+ version: "1.0.0",
107
+ status: "approved",
108
+ owner: "platform-team",
109
+ priorityTier: "P2",
110
+ classification: "internal",
111
+ reviewIntervalDays: 90,
112
+ lastReviewedAt: now,
113
+ nextReviewDue: now,
114
+ // ── server-managed (SERVER_MANAGED_KEYS) ────────────────────────
115
+ schemaVersion: schemaVersion_1.SCHEMA_VERSION,
116
+ sourceHash: "a".repeat(64),
117
+ createdAt: now,
118
+ updatedAt: now,
119
+ usageCount: 0,
120
+ firstSeenTs: now,
121
+ lastUsedAt: now
75
122
  };
76
123
  }
77
124
  /**
@@ -89,7 +136,7 @@ function _buildComprehensiveExample() {
89
136
  categories: ["example", "documentation", "governance"],
90
137
  primaryCategory: "governance",
91
138
  contentType: "instruction",
92
- schemaVersion: "5",
139
+ schemaVersion: schemaVersion_1.SCHEMA_VERSION,
93
140
  version: "1.0.0",
94
141
  status: "approved",
95
142
  owner: "platform-team",
@@ -156,11 +203,15 @@ function definePromotionWorkflow() {
156
203
  ];
157
204
  }
158
205
  /**
159
- * Define key validation rules
206
+ * Define key validation rules.
207
+ *
208
+ * Each rule is annotated with `fieldClass` derived from the canonical
209
+ * SERVER_MANAGED_KEYS set. Callers can filter to `fieldClass === 'input'`
210
+ * to see only properties they may submit on `index_add` / `index_import`.
160
211
  */
161
212
  function defineValidationRules() {
162
213
  const bodyWarnLength = (0, runtimeConfig_1.getRuntimeConfig)().index.bodyWarnLength.toLocaleString('en-US');
163
- return [
214
+ const raw = [
164
215
  { field: 'id', rule: 'Pattern', constraint: '^[a-z0-9](?:[a-z0-9-_]{0,118}[a-z0-9])?$ (120 chars max, lowercase, no leading/trailing hyphen/underscore)' },
165
216
  { field: 'id', rule: 'Uniqueness', constraint: 'Must be unique across the index' },
166
217
  { field: 'title', rule: 'Length', constraint: '1-200 characters, non-empty' },
@@ -170,8 +221,8 @@ function defineValidationRules() {
170
221
  { field: 'requirement', rule: 'Enum', constraint: 'One of: mandatory, critical, recommended, optional, deprecated' },
171
222
  { field: 'categories', rule: 'Array', constraint: '0-25 items, each 1-49 chars, lowercase, pattern: ^[a-z0-9][a-z0-9-_]{0,48}$' },
172
223
  { field: 'primaryCategory', rule: 'Reference', constraint: 'Must be a member of categories array if present' },
173
- { field: 'contentType', rule: 'Enum', constraint: 'One of: instruction (default), template, workflow, reference, example, agent' },
174
- { field: 'schemaVersion', rule: 'Enum', constraint: 'Currently "5"' },
224
+ { field: 'contentType', rule: 'Enum', constraint: `One of: ${instruction_1.CONTENT_TYPES.join(', ')}` },
225
+ { field: 'schemaVersion', rule: 'Enum', constraint: `Currently "${schemaVersion_1.SCHEMA_VERSION}"` },
175
226
  { field: 'sourceHash', rule: 'Pattern', constraint: 'SHA256 hex string (64 chars) when present' },
176
227
  { field: 'version', rule: 'Pattern', constraint: 'Semantic version: ^\\d+\\.\\d+\\.\\d+$ (e.g., "1.0.0")' },
177
228
  { field: 'status', rule: 'Enum', constraint: 'One of: draft, review, approved, deprecated' },
@@ -179,39 +230,30 @@ function defineValidationRules() {
179
230
  { field: 'classification', rule: 'Enum', constraint: 'One of: public, internal, restricted' },
180
231
  { field: 'reviewIntervalDays', rule: 'Range', constraint: '1-365 days' }
181
232
  ];
233
+ return raw.map((r) => ({
234
+ ...r,
235
+ fieldClass: instructionSchema_1.SERVER_MANAGED_KEYS.has(r.field) ? 'server-managed' : 'input',
236
+ }));
182
237
  }
183
238
  (0, registry_1.registerHandler)('index_schema', () => {
184
239
  const schema = loadInstructionSchema();
240
+ // Derive field lists from the canonical source of truth so this self-doc
241
+ // tool cannot drift from the validation surface. The "common optional"
242
+ // surface is every input-accepted property that isn't required and isn't
243
+ // server-managed.
244
+ const requiredFields = [...instructionSchema_1.REQUIRED_INPUT_KEYS];
245
+ const optionalFieldsCommon = [...instructionSchema_1.INPUT_KEYS]
246
+ .filter((k) => !instructionSchema_1.REQUIRED_INPUT_KEYS.has(k) && !instructionSchema_1.SERVER_MANAGED_KEYS.has(k))
247
+ .sort();
185
248
  const response = {
186
249
  generatedAt: new Date().toISOString(),
187
250
  version: SCHEMA_VERSION,
188
251
  summary: 'Instruction schema template with validation rules, examples, and promotion workflow guidance.',
189
252
  schema,
190
253
  minimalExample: buildMinimalExample(),
191
- requiredFields: [
192
- 'id',
193
- 'title',
194
- 'body',
195
- 'priority',
196
- 'audience',
197
- 'requirement',
198
- 'categories'
199
- ],
200
- optionalFieldsCommon: [
201
- 'rationale',
202
- 'primaryCategory',
203
- 'contentType',
204
- 'schemaVersion',
205
- 'version',
206
- 'status',
207
- 'owner',
208
- 'priorityTier',
209
- 'classification',
210
- 'semanticSummary',
211
- 'reviewIntervalDays',
212
- 'lastReviewedAt',
213
- 'nextReviewDue'
214
- ],
254
+ recordExample: buildRecordExample(),
255
+ requiredFields,
256
+ optionalFieldsCommon,
215
257
  promotionWorkflow: definePromotionWorkflow(),
216
258
  validationRules: defineValidationRules(),
217
259
  nextSteps: [
@@ -32,6 +32,7 @@ const errors_1 = require("./errors");
32
32
  const runtimeConfig_1 = require("../config/runtimeConfig");
33
33
  const embeddingService_1 = require("./embeddingService");
34
34
  const safe_regex2_1 = __importDefault(require("safe-regex2"));
35
+ const instruction_1 = require("../models/instruction");
35
36
  const SEARCH_SCHEMA = {
36
37
  type: 'object',
37
38
  required: ['keywords'],
@@ -41,7 +42,7 @@ const SEARCH_SCHEMA = {
41
42
  limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
42
43
  includeCategories: { type: 'boolean', default: false },
43
44
  caseSensitive: { type: 'boolean', default: false },
44
- contentType: { type: 'string', enum: ['instruction', 'template', 'workflow', 'reference', 'example', 'agent'] }
45
+ contentType: { type: 'string', enum: [...instruction_1.CONTENT_TYPES] }
45
46
  },
46
47
  example: { keywords: ['build', 'validate', 'discipline'], limit: 10, includeCategories: true }
47
48
  };
@@ -242,7 +243,7 @@ function calculateRelevance(instruction, keywords, caseSensitive, includeCategor
242
243
  score += calculateOrderedProximityBonus(normalizedCategoryText, normalizedKeywords, 4);
243
244
  }
244
245
  }
245
- return { score, matchedFields: Array.from(matchedFieldSet) };
246
+ return { score, matchedFields: Array.from(matchedFieldSet), keywordsMatched: uniqueMatches.size };
246
247
  }
247
248
  const countMatches = (text, keyword) => {
248
249
  if (mode === 'regex') {
@@ -316,7 +317,7 @@ function calculateRelevance(instruction, keywords, caseSensitive, includeCategor
316
317
  if (uniqueMatches.size > 1) {
317
318
  score += (uniqueMatches.size - 1) * 5;
318
319
  }
319
- return { score, matchedFields: Array.from(matchedFieldSet) };
320
+ return { score, matchedFields: Array.from(matchedFieldSet), keywordsMatched: uniqueMatches.size };
320
321
  }
321
322
  /**
322
323
  * Escape special regex characters
@@ -394,7 +395,7 @@ function performSearch(params) {
394
395
  const caseSensitive = params.caseSensitive ?? false;
395
396
  const contentType = params.contentType;
396
397
  // Validate contentType if provided
397
- const validContentTypes = ['instruction', 'template', 'workflow', 'reference', 'example', 'agent'];
398
+ const validContentTypes = [...instruction_1.CONTENT_TYPES];
398
399
  if (contentType && !validContentTypes.includes(contentType)) {
399
400
  throw new Error(`Invalid contentType: must be one of ${validContentTypes.join(', ')}`);
400
401
  }
@@ -422,8 +423,12 @@ function performSearch(params) {
422
423
  continue; // Skip instructions that don't match the contentType filter
423
424
  }
424
425
  }
425
- const { score, matchedFields } = calculateRelevance(instruction, sanitizedKeywords, caseSensitive, includeCategories, mode, keywordContext, params.compiledRegexKeywords);
426
+ const { score, matchedFields, keywordsMatched } = calculateRelevance(instruction, sanitizedKeywords, caseSensitive, includeCategories, mode, keywordContext, params.compiledRegexKeywords);
426
427
  if (score > 0) {
428
+ // Enforce AND semantics in keyword mode: every normalized keyword must have matched
429
+ if (mode === 'keyword' && keywordContext && keywordsMatched < keywordContext.normalizedKeywords.length) {
430
+ continue;
431
+ }
427
432
  results.push({
428
433
  instructionId: instruction.id,
429
434
  relevanceScore: score,
@@ -556,7 +561,7 @@ async function handleInstructionsSearch(params) {
556
561
  if (typeof params.contentType !== 'string') {
557
562
  throw new Error('contentType must be a string');
558
563
  }
559
- const validContentTypes = ['instruction', 'template', 'workflow', 'reference', 'example', 'agent'];
564
+ const validContentTypes = [...instruction_1.CONTENT_TYPES];
560
565
  if (!validContentTypes.includes(params.contentType)) {
561
566
  throw new Error(`contentType must be one of: ${validContentTypes.join(', ')}`);
562
567
  }
@@ -160,6 +160,13 @@ class IndexLoader {
160
160
  // Exclude internal manifest file if present
161
161
  const MANIFEST_NAME = '_manifest.json';
162
162
  files = files.filter(f => f !== MANIFEST_NAME);
163
+ // Exclude bootstrap gating state files (owned by bootstrapGating.ts). These
164
+ // co-reside with instruction JSON in the instructions dir but are runtime
165
+ // state, NOT instructions. Without this filter they leak into the loader
166
+ // (rejected as schema-invalid) and into index_repair's disk-scan path
167
+ // (reported as 'missing required fields'). RCA 2026-05-07.
168
+ const STATE_FILES = new Set(['bootstrap.confirmed.json', 'bootstrap.pending.json']);
169
+ files = files.filter(f => !STATE_FILES.has(f));
163
170
  // Optional index size limit for performance (INDEX_SERVER_MAX_FILES)
164
171
  const maxFiles = IndexConfig.maxFiles;
165
172
  if (maxFiles && maxFiles > 0 && files.length > maxFiles) {
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.INSTRUCTION_INPUT_SCHEMA_REF = exports.INSTRUCTION_ID_PATTERN = exports.INSTRUCTION_ID_MAX_LENGTH = exports.InstructionValidationError = void 0;
7
4
  exports.validateInstructionIdSurface = validateInstructionIdSurface;
@@ -12,76 +9,24 @@ exports.assertValidInstructionRecord = assertValidInstructionRecord;
12
9
  exports.isInstructionValidationError = isInstructionValidationError;
13
10
  exports.sanitizeErrorDetail = sanitizeErrorDetail;
14
11
  exports.sanitizeLoadError = sanitizeLoadError;
15
- const ajv_1 = __importDefault(require("ajv"));
16
- const ajv_formats_1 = __importDefault(require("ajv-formats"));
17
- const json_schema_draft_07_json_1 = __importDefault(require("ajv/dist/refs/json-schema-draft-07.json"));
18
- const schemas_1 = require("../schemas");
12
+ const instruction_1 = require("../models/instruction");
13
+ const instructionSchema_1 = require("../schemas/instructionSchema");
19
14
  const classificationService_1 = require("./classificationService");
20
- const INPUT_SCHEMA_REF = 'index_add#input';
15
+ const INPUT_SCHEMA_REF = instructionSchema_1.INSTRUCTION_INPUT_SCHEMA_REF;
21
16
  exports.INSTRUCTION_INPUT_SCHEMA_REF = INPUT_SCHEMA_REF;
22
- const REQUIRED_RECORD_KEYS = new Set([
23
- 'id',
24
- 'title',
25
- 'body',
26
- 'priority',
27
- 'audience',
28
- 'requirement',
29
- 'categories',
30
- 'sourceHash',
31
- 'schemaVersion',
32
- 'createdAt',
33
- 'updatedAt',
34
- 'version',
35
- 'status',
36
- 'owner',
37
- 'priorityTier',
38
- 'classification',
39
- 'lastReviewedAt',
40
- 'nextReviewDue',
41
- 'changeLog',
42
- 'semanticSummary',
43
- ]);
44
- const ALLOWED_INPUT_KEYS = new Set([
45
- 'id',
46
- 'title',
47
- 'body',
48
- 'rationale',
49
- 'priority',
50
- 'audience',
51
- 'requirement',
52
- 'categories',
53
- 'primaryCategory',
54
- 'deprecatedBy',
55
- 'riskScore',
56
- 'reviewIntervalDays',
57
- 'version',
58
- 'owner',
59
- 'status',
60
- 'priorityTier',
61
- 'classification',
62
- 'lastReviewedAt',
63
- 'nextReviewDue',
64
- 'changeLog',
65
- 'semanticSummary',
66
- 'contentType',
67
- 'extensions',
68
- 'supersedes',
69
- 'createdByAgent',
70
- 'sourceWorkspace',
71
- 'mode',
72
- 'lax',
73
- ]);
74
- const ajv = new ajv_1.default({ allErrors: true, strict: false });
75
- (0, ajv_formats_1.default)(ajv);
76
- try {
77
- if (!ajv.getSchema('https://json-schema.org/draft-07/schema')) {
78
- ajv.addMetaSchema(json_schema_draft_07_json_1.default, 'https://json-schema.org/draft-07/schema');
79
- }
80
- }
81
- catch {
82
- // Non-fatal; loader uses the same best-effort registration pattern.
83
- }
84
- const validateInstructionSchema = ajv.compile(JSON.parse(JSON.stringify(schemas_1.instructionEntry)));
17
+ // REQUIRED_RECORD_KEYS, ALLOWED_INPUT_KEYS, and the compiled
18
+ // validateInstructionSchema are imported from src/schemas/instructionSchema.ts,
19
+ // which derives them from schemas/instruction.schema.json. Do not restate the
20
+ // schema here — the prior hand-maintained copies drifted (they required 21
21
+ // fields while the canonical schema required 8) and broke export→import
22
+ // round-trips.
23
+ //
24
+ // CONTROL_KEYS are transport-layer flags that callers historically inlined
25
+ // into the entry object as a convenience (instead of into the RPC params
26
+ // bag). They are not data fields and are deliberately not part of the
27
+ // canonical schema. The surface validator tolerates them but does not
28
+ // forward them to record validation.
29
+ const CONTROL_KEYS = new Set(['mode', 'lax']);
85
30
  class InstructionValidationError extends Error {
86
31
  validationErrors;
87
32
  hints;
@@ -164,11 +109,11 @@ function stripUndefinedAndOptionalNulls(value, key, depth = 0) {
164
109
  for (const [childKey, childValue] of Object.entries(value)) {
165
110
  if (childValue === undefined)
166
111
  continue;
167
- if (childValue === null && depth === 0 && !REQUIRED_RECORD_KEYS.has(childKey))
112
+ if (childValue === null && depth === 0 && !instructionSchema_1.REQUIRED_RECORD_KEYS.has(childKey))
168
113
  continue;
169
114
  out[childKey] = stripUndefinedAndOptionalNulls(childValue, childKey, depth + 1); // lgtm[js/remote-property-injection] — childKey is own-property of caller-controlled entry; schema rejects unknown top-level keys downstream
170
115
  }
171
- if (key && Object.keys(out).length === 0 && !REQUIRED_RECORD_KEYS.has(key))
116
+ if (key && Object.keys(out).length === 0 && !instructionSchema_1.REQUIRED_RECORD_KEYS.has(key))
172
117
  return undefined;
173
118
  return out;
174
119
  }
@@ -220,9 +165,6 @@ function applyWriteCompatibility(entry) {
220
165
  else if (legacyRequirementMap[upper])
221
166
  next.requirement = legacyRequirementMap[upper];
222
167
  }
223
- if (next.contentType === 'chat-session') {
224
- next.contentType = 'workflow';
225
- }
226
168
  if (typeof next.priority !== 'number' || next.priority < 1 || next.priority > 100)
227
169
  next.priority = 50;
228
170
  return next;
@@ -268,8 +210,7 @@ const VALID_STATUS = ['approved', 'draft', 'review', 'deprecated'];
268
210
  const COERCIBLE_STATUS = ['active'];
269
211
  const VALID_PRIORITY_TIER = ['P1', 'P2', 'P3', 'P4'];
270
212
  const VALID_CLASSIFICATION = ['public', 'internal', 'restricted'];
271
- const VALID_CONTENT_TYPE = ['instruction', 'template', 'workflow', 'reference', 'example', 'agent'];
272
- const COERCIBLE_CONTENT_TYPE = ['chat-session'];
213
+ const VALID_CONTENT_TYPE = instruction_1.CONTENT_TYPES;
273
214
  const VALID_AUDIENCE = ['individual', 'group', 'all'];
274
215
  const COERCIBLE_AUDIENCE = ['system', 'developers', 'developer', 'team', 'teams', 'users', 'dev', 'devs', 'testers', 'administrators', 'admins', 'agents', 'powershell script authors'];
275
216
  const VALID_REQUIREMENT = ['mandatory', 'critical', 'recommended', 'optional', 'deprecated'];
@@ -285,7 +226,7 @@ function validateInstructionInputEnumMembership(entry) {
285
226
  if (typeof entry.classification === 'string' && !VALID_CLASSIFICATION.includes(entry.classification)) {
286
227
  errs.push(`/classification: must be one of ${VALID_CLASSIFICATION.join(', ')}`);
287
228
  }
288
- if (typeof entry.contentType === 'string' && !VALID_CONTENT_TYPE.includes(entry.contentType) && !COERCIBLE_CONTENT_TYPE.includes(entry.contentType)) {
229
+ if (typeof entry.contentType === 'string' && !VALID_CONTENT_TYPE.includes(entry.contentType)) {
289
230
  errs.push(`/contentType: must be one of ${VALID_CONTENT_TYPE.join(', ')}`);
290
231
  }
291
232
  if (typeof entry.audience === 'string' && !VALID_AUDIENCE.includes(entry.audience) && !COERCIBLE_AUDIENCE.includes(entry.audience.toLowerCase())) {
@@ -314,11 +255,16 @@ function validateTypedInputShape(entry) {
314
255
  if (typeof category !== 'string') {
315
256
  errs.push(`/categories/${index}: must be a string, received ${typeof category}`);
316
257
  }
317
- else if (!/^[a-z0-9][a-z0-9-_]{0,48}$/.test(category.toLowerCase())) {
258
+ else if (!/^[a-z0-9][a-z0-9-_]{0,48}$/.test(category)) {
318
259
  errs.push(`/categories/${index}: must match /^[a-z0-9][a-z0-9-_]{0,48}$/`);
319
260
  }
320
261
  }
321
262
  }
263
+ if (typeof entry.primaryCategory === 'string' && Array.isArray(entry.categories) && entry.categories.length > 0) {
264
+ if (!entry.categories.includes(entry.primaryCategory)) {
265
+ errs.push(`/primaryCategory: must be a member of categories[]`);
266
+ }
267
+ }
322
268
  if (entry.audience !== undefined && typeof entry.audience !== 'string') {
323
269
  errs.push(`/audience: must be a string, received ${typeof entry.audience}`);
324
270
  }
@@ -343,7 +289,9 @@ function validateInstructionInputSurface(entry) {
343
289
  const validationErrors = [];
344
290
  validationErrors.push(...validateInstructionIdSurface(entry.id));
345
291
  for (const key of Object.keys(entry)) {
346
- if (!ALLOWED_INPUT_KEYS.has(key)) {
292
+ if (CONTROL_KEYS.has(key))
293
+ continue; // transport flags; tolerated, not forwarded
294
+ if (!instructionSchema_1.INPUT_KEYS.has(key)) {
347
295
  validationErrors.push(`/: unexpected property "${key}"`);
348
296
  continue;
349
297
  }
@@ -371,11 +319,11 @@ function validateInstructionRecord(entry) {
371
319
  if (record.classification !== undefined && !['public', 'internal', 'restricted'].includes(record.classification)) {
372
320
  validationErrors.push(`/classification: invalid value "${String(record.classification)}"`);
373
321
  }
374
- if (record.contentType !== undefined && !['instruction', 'template', 'workflow', 'reference', 'example', 'agent'].includes(record.contentType)) {
322
+ if (record.contentType !== undefined && !instruction_1.CONTENT_TYPES.includes(record.contentType)) {
375
323
  validationErrors.push(`/contentType: invalid value "${String(record.contentType)}"`);
376
324
  }
377
- if (!validateInstructionSchema(record)) {
378
- validationErrors.push(...(validateInstructionSchema.errors ?? []).map(formatAjvError));
325
+ if (!(0, instructionSchema_1.validateRecord)(record)) {
326
+ validationErrors.push(...(instructionSchema_1.validateRecord.errors ?? []).map(formatAjvError));
379
327
  }
380
328
  const classifierIssues = new classificationService_1.ClassificationService().validate(record);
381
329
  validationErrors.push(...classifierIssues.map((issue) => `/: ${issue}`));
@@ -37,7 +37,7 @@ export interface McpProfileConfig {
37
37
  mutation: boolean;
38
38
  logLevel: string;
39
39
  }
40
- export declare const DOCUMENTED_INDEX_SERVER_FLAGS: readonly ["INDEX_SERVER_ADD_TIMING", "INDEX_SERVER_ADMIN_API_KEY", "INDEX_SERVER_ADMIN_MAX_SESSION_HISTORY", "INDEX_SERVER_AGENT_ID", "INDEX_SERVER_ALWAYS_RELOAD", "INDEX_SERVER_ATOMIC_WRITE_BACKOFF_MS", "INDEX_SERVER_ATOMIC_WRITE_RETRIES", "INDEX_SERVER_AUDIT_LOG", "INDEX_SERVER_AUTH_KEY", "INDEX_SERVER_AUTO_BACKUP", "INDEX_SERVER_AUTO_BACKUP_INTERVAL_MS", "INDEX_SERVER_AUTO_BACKUP_MAX_COUNT", "INDEX_SERVER_AUTO_EMBED_ON_IMPORT", "INDEX_SERVER_AUTO_SEED", "INDEX_SERVER_AUTO_SPLIT_OVERSIZED", "INDEX_SERVER_AUTO_USAGE_TRACK", "INDEX_SERVER_BACKUP_BEFORE_BULK_DELETE", "INDEX_SERVER_BACKUPS_DIR", "INDEX_SERVER_BODY_MAX_LENGTH", "INDEX_SERVER_BODY_WARN_LENGTH", "INDEX_SERVER_BOOTSTRAP_AUTOCONFIRM", "INDEX_SERVER_BOOTSTRAP_TOKEN_TTL_SEC", "INDEX_SERVER_BUFFER_RING_APPEND", "INDEX_SERVER_BUFFER_RING_PRELOAD", "INDEX_SERVER_CACHE_MODE", "INDEX_SERVER_CANONICAL_DISABLE", "INDEX_SERVER_DASHBOARD", "INDEX_SERVER_DASHBOARD_GRAPH", "INDEX_SERVER_DASHBOARD_HOST", "INDEX_SERVER_DASHBOARD_PORT", "INDEX_SERVER_DASHBOARD_TLS", "INDEX_SERVER_DASHBOARD_TLS_CA", "INDEX_SERVER_DASHBOARD_TLS_CERT", "INDEX_SERVER_DASHBOARD_TLS_KEY", "INDEX_SERVER_DASHBOARD_TRIES", "INDEX_SERVER_DEBUG", "INDEX_SERVER_DIR", "INDEX_SERVER_DISABLE_EARLY_STDIN_BUFFER", "INDEX_SERVER_DISABLE_STDERR_BRIDGE", "INDEX_SERVER_DISABLE_USAGE_CLAMP", "INDEX_SERVER_EMBEDDING_PATH", "INDEX_SERVER_ENABLE_INDEX_SERVER_POLLER", "INDEX_SERVER_ENABLE_STDERR_BRIDGE", "INDEX_SERVER_EVENT_BUFFER_SIZE", "INDEX_SERVER_EVENT_SILENT", "INDEX_SERVER_FATAL_EXIT_DELAY_MS", "INDEX_SERVER_FEATURES", "INDEX_SERVER_FEEDBACK_DIR", "INDEX_SERVER_FEEDBACK_MAX_ENTRIES", "INDEX_SERVER_FILE_TRACE", "INDEX_SERVER_FLAG_TOOLS_ADMIN", "INDEX_SERVER_FLAG_TOOLS_EXTENDED", "INDEX_SERVER_FLAGS", "INDEX_SERVER_FLAGS_FILE", "INDEX_SERVER_FORCE_REBUILD", "INDEX_SERVER_GOV_HASH_CANON_VARIANTS", "INDEX_SERVER_GOV_HASH_HARDENING", "INDEX_SERVER_GOV_HASH_IMPORT_SET_SIZE", "INDEX_SERVER_GRAPH_INCLUDE_PRIMARY_EDGES", "INDEX_SERVER_GRAPH_LARGE_CATEGORY_CAP", "INDEX_SERVER_HEALTH_ERROR_THRESHOLD", "INDEX_SERVER_HEALTH_MEMORY_THRESHOLD", "INDEX_SERVER_HEALTH_MIN_UPTIME", "INDEX_SERVER_HEARTBEAT_MS", "INDEX_SERVER_HTTP_METRICS", "INDEX_SERVER_IDLE_KEEPALIVE_MS", "INDEX_SERVER_IDLE_READY_SENTINEL", "INDEX_SERVER_INIT_FEATURES", "INDEX_SERVER_ISSUE_317_COUNTER", "INDEX_SERVER_LEADER_PORT", "INDEX_SERVER_LEADER_URL", "INDEX_SERVER_LOAD_WARN_MS", "INDEX_SERVER_LOG_DIAG", "INDEX_SERVER_LOG_FILE", "INDEX_SERVER_LOG_JSON", "INDEX_SERVER_LOG_LEVEL", "INDEX_SERVER_LOG_MUTATION", "INDEX_SERVER_LOG_PROTOCOL", "INDEX_SERVER_LOG_SEARCH", "INDEX_SERVER_LOG_SYNC", "INDEX_SERVER_LOG_TOOLS", "INDEX_SERVER_MANIFEST_FASTLOAD", "INDEX_SERVER_MANIFEST_PATH", "INDEX_SERVER_MANIFEST_WRITE", "INDEX_SERVER_MAX_BULK_DELETE", "INDEX_SERVER_MAX_CONNECTIONS", "INDEX_SERVER_MAX_FILES", "INDEX_SERVER_MCP_BACKUP_RETAIN", "INDEX_SERVER_MCP_CONFIG_ROOT", "INDEX_SERVER_MEMOIZE", "INDEX_SERVER_MEMOIZE_HASH", "INDEX_SERVER_MEMORY_MONITOR", "INDEX_SERVER_MESSAGING_DIR", "INDEX_SERVER_MESSAGING_MAX", "INDEX_SERVER_MESSAGING_SWEEP_MS", "INDEX_SERVER_METRICS_DIR", "INDEX_SERVER_METRICS_FILE_STORAGE", "INDEX_SERVER_METRICS_MAX_FILES", "INDEX_SERVER_MINIMAL_DEBUG", "INDEX_SERVER_MODE", "INDEX_SERVER_MUTATION", "INDEX_SERVER_NORMALIZATION_LOG", "INDEX_SERVER_POLL_MS", "INDEX_SERVER_POLL_PROACTIVE", "INDEX_SERVER_PREFLIGHT_MODULES", "INDEX_SERVER_PREFLIGHT_STRICT", "INDEX_SERVER_PROFILE", "INDEX_SERVER_PWS_EXIT_MS", "INDEX_SERVER_RATE_LIMIT", "INDEX_SERVER_READ_BACKOFF_MS", "INDEX_SERVER_READ_RETRIES", "INDEX_SERVER_REFERENCE_MODE", "INDEX_SERVER_REQUEST_TIMEOUT", "INDEX_SERVER_REQUIRE_AUTH_ALL", "INDEX_SERVER_REQUIRE_CATEGORY", "INDEX_SERVER_RESOURCE_CAPACITY", "INDEX_SERVER_RESOURCE_SAMPLE_INTERVAL_MS", "INDEX_SERVER_SEED_VERBOSE", "INDEX_SERVER_SEMANTIC_CACHE_DIR", "INDEX_SERVER_SEMANTIC_DEVICE", "INDEX_SERVER_SEMANTIC_ENABLED", "INDEX_SERVER_SEMANTIC_LOCAL_ONLY", "INDEX_SERVER_SEMANTIC_MODEL", "INDEX_SERVER_SEARCH_OMIT_ZERO_QUERY", "INDEX_SERVER_SESSION_BACKUP_INTEGRATION", "INDEX_SERVER_SESSION_DEDUPLICATION_ENABLED", "INDEX_SERVER_SESSION_MAX_CONNECTION_HISTORY_DAYS", "INDEX_SERVER_SESSION_MAX_HISTORY_DAYS", "INDEX_SERVER_SESSION_MAX_HISTORY_ENTRIES", "INDEX_SERVER_SESSION_PERSISTENCE_DIR", "INDEX_SERVER_SESSION_PERSISTENCE_ENABLED", "INDEX_SERVER_SESSION_PERSISTENCE_INTERVAL_MS", "INDEX_SERVER_SHARED_SERVER_SENTINEL", "INDEX_SERVER_SQLITE_MIGRATE_ON_START", "INDEX_SERVER_SQLITE_PATH", "INDEX_SERVER_SQLITE_VEC_ENABLED", "INDEX_SERVER_SQLITE_VEC_PATH", "INDEX_SERVER_SQLITE_WAL", "INDEX_SERVER_STALE_THRESHOLD_MS", "INDEX_SERVER_STATE_DIR", "INDEX_SERVER_STORAGE_BACKEND", "INDEX_SERVER_STRESS_DIAG", "INDEX_SERVER_STRESS_MODE", "INDEX_SERVER_STRICT_", "INDEX_SERVER_STRICT_CREATE", "INDEX_SERVER_STRICT_REMOVE", "INDEX_SERVER_TEST_MODE", "INDEX_SERVER_TEST_STRICT_VISIBILITY", "INDEX_SERVER_TIMING_JSON", "INDEX_SERVER_TOOLCALL_APPEND_LOG", "INDEX_SERVER_TOOLCALL_CHUNK_SIZE", "INDEX_SERVER_TOOLCALL_COMPACT_MS", "INDEX_SERVER_TOOLCALL_FLUSH_MS", "INDEX_SERVER_TRACE", "INDEX_SERVER_TRACE_", "INDEX_SERVER_TRACE_ALL", "INDEX_SERVER_TRACE_BUFFER_", "INDEX_SERVER_TRACE_BUFFER_DUMP_ON_EXIT", "INDEX_SERVER_TRACE_BUFFER_FILE", "INDEX_SERVER_TRACE_BUFFER_SIZE", "INDEX_SERVER_TRACE_CALLSITE", "INDEX_SERVER_TRACE_CATEGORIES", "INDEX_SERVER_TRACE_DIR", "INDEX_SERVER_TRACE_DISPATCH_DIAG", "INDEX_SERVER_TRACE_FILE", "INDEX_SERVER_TRACE_FSYNC", "INDEX_SERVER_TRACE_LEVEL", "INDEX_SERVER_TRACE_MAX_FILE_SIZE", "INDEX_SERVER_TRACE_PERSIST", "INDEX_SERVER_TRACE_QUERY_DIAG", "INDEX_SERVER_TRACE_SESSION", "INDEX_SERVER_USAGE_FLUSH_MS", "INDEX_SERVER_USAGE_SNAPSHOT_PATH", "INDEX_SERVER_VALIDATION_MODE", "INDEX_SERVER_VERBOSE_LOGGING", "INDEX_SERVER_VISIBILITY_DIAG", "INDEX_SERVER_WARN_BUDGET", "INDEX_SERVER_WORKSPACE"];
40
+ export declare const DOCUMENTED_INDEX_SERVER_FLAGS: readonly ["INDEX_SERVER_ADD_TIMING", "INDEX_SERVER_ADMIN_API_KEY", "INDEX_SERVER_ADMIN_MAX_SESSION_HISTORY", "INDEX_SERVER_AGENT_ID", "INDEX_SERVER_ALWAYS_RELOAD", "INDEX_SERVER_ATOMIC_WRITE_BACKOFF_MS", "INDEX_SERVER_ATOMIC_WRITE_RETRIES", "INDEX_SERVER_AUDIT_LOG", "INDEX_SERVER_AUTH_KEY", "INDEX_SERVER_AUTO_BACKUP", "INDEX_SERVER_AUTO_BACKUP_INTERVAL_MS", "INDEX_SERVER_AUTO_BACKUP_MAX_COUNT", "INDEX_SERVER_AUTO_EMBED_ON_IMPORT", "INDEX_SERVER_AUTO_SEED", "INDEX_SERVER_AUTO_SPLIT_OVERSIZED", "INDEX_SERVER_AUTO_USAGE_TRACK", "INDEX_SERVER_BACKUP_BEFORE_BULK_DELETE", "INDEX_SERVER_BACKUPS_DIR", "INDEX_SERVER_BODY_MAX_LENGTH", "INDEX_SERVER_BODY_WARN_LENGTH", "INDEX_SERVER_BOOTSTRAP_AUTOCONFIRM", "INDEX_SERVER_BOOTSTRAP_TOKEN_TTL_SEC", "INDEX_SERVER_BUFFER_RING_APPEND", "INDEX_SERVER_BUFFER_RING_PRELOAD", "INDEX_SERVER_CACHE_MODE", "INDEX_SERVER_CANONICAL_DISABLE", "INDEX_SERVER_DASHBOARD", "INDEX_SERVER_DASHBOARD_GRAPH", "INDEX_SERVER_DASHBOARD_HOST", "INDEX_SERVER_DASHBOARD_PORT", "INDEX_SERVER_DASHBOARD_TLS", "INDEX_SERVER_DASHBOARD_TLS_CA", "INDEX_SERVER_DASHBOARD_TLS_CERT", "INDEX_SERVER_DASHBOARD_TLS_KEY", "INDEX_SERVER_DASHBOARD_TRIES", "INDEX_SERVER_DEBUG", "INDEX_SERVER_DIR", "INDEX_SERVER_DISABLE_EARLY_STDIN_BUFFER", "INDEX_SERVER_DISABLE_PPID_WATCHDOG", "INDEX_SERVER_DISABLE_STDERR_BRIDGE", "INDEX_SERVER_DISABLE_USAGE_CLAMP", "INDEX_SERVER_EMBEDDING_PATH", "INDEX_SERVER_ENABLE_INDEX_SERVER_POLLER", "INDEX_SERVER_ENABLE_STDERR_BRIDGE", "INDEX_SERVER_EVENT_BUFFER_SIZE", "INDEX_SERVER_EVENT_SILENT", "INDEX_SERVER_FATAL_EXIT_DELAY_MS", "INDEX_SERVER_FEATURES", "INDEX_SERVER_FEEDBACK_DIR", "INDEX_SERVER_FEEDBACK_MAX_ENTRIES", "INDEX_SERVER_FILE_TRACE", "INDEX_SERVER_FLAG_TOOLS_ADMIN", "INDEX_SERVER_FLAG_TOOLS_EXTENDED", "INDEX_SERVER_FLAGS", "INDEX_SERVER_FLAGS_FILE", "INDEX_SERVER_FORCE_REBUILD", "INDEX_SERVER_GOV_HASH_CANON_VARIANTS", "INDEX_SERVER_GOV_HASH_HARDENING", "INDEX_SERVER_GOV_HASH_IMPORT_SET_SIZE", "INDEX_SERVER_GRAPH_INCLUDE_PRIMARY_EDGES", "INDEX_SERVER_GRAPH_LARGE_CATEGORY_CAP", "INDEX_SERVER_HEALTH_ERROR_THRESHOLD", "INDEX_SERVER_HEALTH_MEMORY_THRESHOLD", "INDEX_SERVER_HEALTH_MIN_UPTIME", "INDEX_SERVER_HEARTBEAT_MS", "INDEX_SERVER_HTTP_METRICS", "INDEX_SERVER_IDLE_KEEPALIVE_MS", "INDEX_SERVER_IDLE_READY_SENTINEL", "INDEX_SERVER_INIT_FEATURES", "INDEX_SERVER_ISSUE_317_COUNTER", "INDEX_SERVER_LEADER_PORT", "INDEX_SERVER_LEADER_URL", "INDEX_SERVER_LOAD_WARN_MS", "INDEX_SERVER_LOG_DIAG", "INDEX_SERVER_LOG_FILE", "INDEX_SERVER_LOG_JSON", "INDEX_SERVER_LOG_LEVEL", "INDEX_SERVER_LOG_MUTATION", "INDEX_SERVER_LOG_PROTOCOL", "INDEX_SERVER_LOG_SEARCH", "INDEX_SERVER_LOG_SYNC", "INDEX_SERVER_LOG_TOOLS", "INDEX_SERVER_MANIFEST_FASTLOAD", "INDEX_SERVER_MANIFEST_PATH", "INDEX_SERVER_MANIFEST_WRITE", "INDEX_SERVER_MAX_BULK_DELETE", "INDEX_SERVER_MAX_CONNECTIONS", "INDEX_SERVER_MAX_FILES", "INDEX_SERVER_MCP_BACKUP_RETAIN", "INDEX_SERVER_MCP_CONFIG_ROOT", "INDEX_SERVER_MEMOIZE", "INDEX_SERVER_MEMOIZE_HASH", "INDEX_SERVER_MEMORY_MONITOR", "INDEX_SERVER_MESSAGING_DIR", "INDEX_SERVER_MESSAGING_MAX", "INDEX_SERVER_MESSAGING_SWEEP_MS", "INDEX_SERVER_METRICS_DIR", "INDEX_SERVER_METRICS_FILE_STORAGE", "INDEX_SERVER_METRICS_MAX_FILES", "INDEX_SERVER_MINIMAL_DEBUG", "INDEX_SERVER_MODE", "INDEX_SERVER_MUTATION", "INDEX_SERVER_NORMALIZATION_LOG", "INDEX_SERVER_POLL_MS", "INDEX_SERVER_POLL_PROACTIVE", "INDEX_SERVER_PREFLIGHT_MODULES", "INDEX_SERVER_PREFLIGHT_STRICT", "INDEX_SERVER_PROFILE", "INDEX_SERVER_PWS_EXIT_MS", "INDEX_SERVER_RATE_LIMIT", "INDEX_SERVER_READ_BACKOFF_MS", "INDEX_SERVER_READ_RETRIES", "INDEX_SERVER_REFERENCE_MODE", "INDEX_SERVER_REQUEST_TIMEOUT", "INDEX_SERVER_REQUIRE_AUTH_ALL", "INDEX_SERVER_REQUIRE_CATEGORY", "INDEX_SERVER_RESOURCE_CAPACITY", "INDEX_SERVER_RESOURCE_SAMPLE_INTERVAL_MS", "INDEX_SERVER_SEED_VERBOSE", "INDEX_SERVER_SEMANTIC_CACHE_DIR", "INDEX_SERVER_SEMANTIC_DEVICE", "INDEX_SERVER_SEMANTIC_ENABLED", "INDEX_SERVER_SEMANTIC_LOCAL_ONLY", "INDEX_SERVER_SEMANTIC_MODEL", "INDEX_SERVER_SEARCH_OMIT_ZERO_QUERY", "INDEX_SERVER_SESSION_BACKUP_INTEGRATION", "INDEX_SERVER_SESSION_DEDUPLICATION_ENABLED", "INDEX_SERVER_SESSION_MAX_CONNECTION_HISTORY_DAYS", "INDEX_SERVER_SESSION_MAX_HISTORY_DAYS", "INDEX_SERVER_SESSION_MAX_HISTORY_ENTRIES", "INDEX_SERVER_SESSION_PERSISTENCE_DIR", "INDEX_SERVER_SESSION_PERSISTENCE_ENABLED", "INDEX_SERVER_SESSION_PERSISTENCE_INTERVAL_MS", "INDEX_SERVER_SHARED_SERVER_SENTINEL", "INDEX_SERVER_SQLITE_MIGRATE_ON_START", "INDEX_SERVER_SQLITE_PATH", "INDEX_SERVER_SQLITE_VEC_ENABLED", "INDEX_SERVER_SQLITE_VEC_PATH", "INDEX_SERVER_SQLITE_WAL", "INDEX_SERVER_STALE_THRESHOLD_MS", "INDEX_SERVER_STATE_DIR", "INDEX_SERVER_STORAGE_BACKEND", "INDEX_SERVER_STRESS_DIAG", "INDEX_SERVER_STRESS_MODE", "INDEX_SERVER_STRICT_", "INDEX_SERVER_STRICT_CREATE", "INDEX_SERVER_STRICT_REMOVE", "INDEX_SERVER_TEST_MODE", "INDEX_SERVER_TEST_STRICT_VISIBILITY", "INDEX_SERVER_TIMING_JSON", "INDEX_SERVER_TOOLCALL_APPEND_LOG", "INDEX_SERVER_TOOLCALL_CHUNK_SIZE", "INDEX_SERVER_TOOLCALL_COMPACT_MS", "INDEX_SERVER_TOOLCALL_FLUSH_MS", "INDEX_SERVER_TRACE", "INDEX_SERVER_TRACE_", "INDEX_SERVER_TRACE_ALL", "INDEX_SERVER_TRACE_BUFFER_", "INDEX_SERVER_TRACE_BUFFER_DUMP_ON_EXIT", "INDEX_SERVER_TRACE_BUFFER_FILE", "INDEX_SERVER_TRACE_BUFFER_SIZE", "INDEX_SERVER_TRACE_CALLSITE", "INDEX_SERVER_TRACE_CATEGORIES", "INDEX_SERVER_TRACE_DIR", "INDEX_SERVER_TRACE_DISPATCH_DIAG", "INDEX_SERVER_TRACE_FILE", "INDEX_SERVER_TRACE_FSYNC", "INDEX_SERVER_TRACE_LEVEL", "INDEX_SERVER_TRACE_MAX_FILE_SIZE", "INDEX_SERVER_TRACE_PERSIST", "INDEX_SERVER_TRACE_QUERY_DIAG", "INDEX_SERVER_TRACE_SESSION", "INDEX_SERVER_USAGE_FLUSH_MS", "INDEX_SERVER_USAGE_SNAPSHOT_PATH", "INDEX_SERVER_VALIDATION_MODE", "INDEX_SERVER_VERBOSE_LOGGING", "INDEX_SERVER_VISIBILITY_DIAG", "INDEX_SERVER_WARN_BUDGET", "INDEX_SERVER_WORKSPACE"];
41
41
  export declare function toForwardSlashes(value: string): string;
42
42
  export declare function resolveDataPaths(root: string): McpDataPaths;
43
43
  export declare function buildEnvCatalog(config: McpProfileConfig, paths: McpDataPaths): McpEnvCatalogEntry[];
@@ -48,6 +48,7 @@ exports.DOCUMENTED_INDEX_SERVER_FLAGS = [
48
48
  'INDEX_SERVER_DEBUG',
49
49
  'INDEX_SERVER_DIR',
50
50
  'INDEX_SERVER_DISABLE_EARLY_STDIN_BUFFER',
51
+ 'INDEX_SERVER_DISABLE_PPID_WATCHDOG',
51
52
  'INDEX_SERVER_DISABLE_STDERR_BRIDGE',
52
53
  'INDEX_SERVER_DISABLE_USAGE_CLAMP',
53
54
  'INDEX_SERVER_EMBEDDING_PATH',
@@ -268,6 +269,7 @@ function buildEnvCatalog(config, paths) {
268
269
  { section: 'Server and transport' },
269
270
  { key: 'INDEX_SERVER_MODE', desc: 'Instance mode', active: false, value: 'standalone' },
270
271
  { key: 'INDEX_SERVER_DISABLE_EARLY_STDIN_BUFFER', desc: 'Disable stdin handshake hardening', active: false, value: '0' },
272
+ { key: 'INDEX_SERVER_DISABLE_PPID_WATCHDOG', desc: 'Disable parent-process watchdog (dev sandbox launchers)', active: false, value: '0' },
271
273
  { key: 'INDEX_SERVER_IDLE_KEEPALIVE_MS', desc: 'Keepalive interval in ms', active: false, value: '30000' },
272
274
  { key: 'INDEX_SERVER_POLL_MS', desc: 'Index filesystem poll interval', active: false, value: '10000' },
273
275
  { section: 'Advanced tuning' },
@@ -77,12 +77,8 @@ function buildServerEntry(format, config, paths, envOverrides = {}) {
77
77
  entry.cwd = (0, flagCatalog_1.toForwardSlashes)(launch.cwd);
78
78
  if (format === 'vscode-global' && launch.command === 'node') {
79
79
  const firstArg = launch.args[0] ?? '';
80
- const baseCwd = launch.cwd ?? config.root;
81
- entry.args = [path_1.default.isAbsolute(firstArg) ? (0, flagCatalog_1.toForwardSlashes)(firstArg) : (0, flagCatalog_1.toForwardSlashes)(path_1.default.resolve(baseCwd, firstArg))];
82
- // Prefer the launch cwd (config.root for 'local' source — a stable user-scope
83
- // directory). Fall back to package root only when the runtime hasn't been
84
- // self-deployed under config.root (e.g. 'packaged' source straight out of npm-global).
85
- entry.cwd = (0, flagCatalog_1.toForwardSlashes)(launch.cwd ?? path_1.default.resolve(__dirname, '..', '..', '..'));
80
+ entry.args = [path_1.default.isAbsolute(firstArg) ? (0, flagCatalog_1.toForwardSlashes)(firstArg) : (0, flagCatalog_1.toForwardSlashes)(path_1.default.resolve(launch.cwd ?? config.root, firstArg))];
81
+ entry.cwd = (0, flagCatalog_1.toForwardSlashes)(path_1.default.resolve(__dirname, '..', '..', '..'));
86
82
  }
87
83
  return entry;
88
84
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Build the canonical seed object for `002-content-model` from the schema.
3
+ *
4
+ * The function is pure: same schema input → same seed output. Tests rely on
5
+ * this determinism to assert drift-safety.
6
+ *
7
+ * @returns Canonical seed `{ file, id, json }` ready to push into CANONICAL_SEEDS.
8
+ */
9
+ export declare function buildContentModelSeed(): {
10
+ file: string;
11
+ id: string;
12
+ json: Record<string, unknown>;
13
+ };