@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.
- package/CHANGELOG.md +109 -1
- package/CONTRIBUTING.md +13 -0
- package/README.md +10 -14
- package/dist/config/featureConfig.js +4 -1
- package/dist/dashboard/client/admin.html +69 -29
- package/dist/dashboard/client/js/admin.embeddings.js +97 -5
- package/dist/dashboard/client/js/admin.instructions.js +1 -1
- package/dist/dashboard/server/AdminPanel.js +38 -0
- package/dist/dashboard/server/ApiRoutes.js +14 -1
- package/dist/dashboard/server/routes/embeddings.routes.js +76 -1
- package/dist/dashboard/server/routes/instructions.routes.js +4 -11
- package/dist/dashboard/server/routes/scripts.routes.js +35 -10
- package/dist/dashboard/server/routes/status.routes.js +77 -0
- package/dist/models/instruction.d.ts +2 -1
- package/dist/models/instruction.js +2 -0
- package/dist/schemas/index-server.code-schema.json +52478 -0
- package/dist/schemas/index.d.ts +7 -164
- package/dist/schemas/index.js +45 -63
- package/dist/schemas/instructionSchema.d.ts +46 -0
- package/dist/schemas/instructionSchema.js +159 -0
- package/{schemas → dist/schemas}/json-schema/instruction-content-type.schema.json +6 -4
- package/{schemas → dist/schemas}/json-schema/instruction-instruction-entry.schema.json +6 -4
- package/dist/schemas/manifest.json +78 -0
- package/dist/server/index-server.js +7 -1
- package/dist/services/bootstrapGating.js +2 -2
- package/dist/services/handlers/instructions.add.js +18 -0
- package/dist/services/handlers/instructions.groom.js +6 -1
- package/dist/services/handlers/instructions.import.js +42 -7
- package/dist/services/handlers.activation.js +3 -1
- package/dist/services/handlers.dashboardConfig.js +2 -1
- package/dist/services/handlers.feedback.d.ts +4 -4
- package/dist/services/handlers.feedback.js +390 -27
- package/dist/services/handlers.instructionSchema.js +73 -31
- package/dist/services/handlers.search.js +11 -6
- package/dist/services/indexLoader.js +7 -0
- package/dist/services/instructionRecordValidation.js +32 -84
- package/dist/services/mcpConfig/flagCatalog.d.ts +1 -1
- package/dist/services/mcpConfig/flagCatalog.js +2 -0
- package/dist/services/mcpConfig/formats.js +2 -6
- package/dist/services/seedBootstrap.contentModel.d.ts +13 -0
- package/dist/services/seedBootstrap.contentModel.js +166 -0
- package/dist/services/seedBootstrap.contentTypes.d.ts +5 -0
- package/dist/services/seedBootstrap.contentTypes.js +76 -0
- package/dist/services/seedBootstrap.d.ts +1 -0
- package/dist/services/seedBootstrap.js +87 -10
- package/dist/services/toolRegistry.js +52 -24
- package/dist/services/toolRegistry.zod.js +84 -37
- package/dist/versioning/schemaVersion.d.ts +1 -1
- package/dist/versioning/schemaVersion.js +1 -13
- package/package.json +17 -3
- package/schemas/index-server.code-schema.json +31019 -25047
- package/schemas/instruction.schema.json +16 -6
- package/schemas/manifest.json +3 -3
- package/scripts/README.md +20 -0
- package/scripts/build/README.md +41 -0
- package/scripts/build/setup-wizard-paths.mjs +27 -0
- package/scripts/build/setup-wizard.mjs +7 -21
- package/scripts/client/README.md +26 -0
- package/scripts/client/index-server-client.ps1 +203 -0
- package/scripts/client/index-server-client.sh +149 -0
- package/scripts/client/powershell-mcp-server.ps1 +83 -0
- package/scripts/client/powershell-mcp-template.ps1 +85 -0
- package/scripts/hooks/README.md +40 -0
- package/server.json +2 -2
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-admin-session.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-config.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-data.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-manifest.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/SessionPersistence-session-persistence-metadata.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/instruction-audience-scope.schema.json +0 -0
- /package/{schemas → dist/schemas}/json-schema/instruction-requirement-level.schema.json +0 -0
package/dist/schemas/index.d.ts
CHANGED
|
@@ -1,167 +1,10 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}, {
|
|
9
|
-
readonly type: "number";
|
|
10
|
-
}, {
|
|
11
|
-
readonly type: "boolean";
|
|
12
|
-
}, {
|
|
13
|
-
readonly type: "array";
|
|
14
|
-
readonly items: {
|
|
15
|
-
readonly $ref: "#/$defs/extensionValue";
|
|
16
|
-
};
|
|
17
|
-
}, {
|
|
18
|
-
readonly type: "object";
|
|
19
|
-
readonly additionalProperties: {
|
|
20
|
-
readonly $ref: "#/$defs/extensionValue";
|
|
21
|
-
};
|
|
22
|
-
}];
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
readonly required: readonly ["id", "title", "body", "priority", "audience", "requirement", "categories", "sourceHash", "schemaVersion", "createdAt", "updatedAt", "version", "status", "owner", "priorityTier", "classification", "lastReviewedAt", "nextReviewDue", "changeLog", "semanticSummary", "contentType"];
|
|
26
|
-
readonly properties: {
|
|
27
|
-
readonly id: {
|
|
28
|
-
readonly type: "string";
|
|
29
|
-
readonly minLength: 1;
|
|
30
|
-
};
|
|
31
|
-
readonly title: {
|
|
32
|
-
readonly type: "string";
|
|
33
|
-
};
|
|
34
|
-
readonly body: {
|
|
35
|
-
readonly type: "string";
|
|
36
|
-
};
|
|
37
|
-
readonly rationale: {
|
|
38
|
-
readonly type: "string";
|
|
39
|
-
};
|
|
40
|
-
readonly priority: {
|
|
41
|
-
readonly type: "number";
|
|
42
|
-
};
|
|
43
|
-
readonly audience: {
|
|
44
|
-
readonly enum: readonly ["individual", "group", "all"];
|
|
45
|
-
};
|
|
46
|
-
readonly requirement: {
|
|
47
|
-
readonly enum: readonly ["mandatory", "critical", "recommended", "optional", "deprecated"];
|
|
48
|
-
};
|
|
49
|
-
readonly categories: {
|
|
50
|
-
readonly type: "array";
|
|
51
|
-
readonly items: {
|
|
52
|
-
readonly type: "string";
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
readonly primaryCategory: {
|
|
56
|
-
readonly type: "string";
|
|
57
|
-
};
|
|
58
|
-
readonly sourceHash: {
|
|
59
|
-
readonly type: "string";
|
|
60
|
-
};
|
|
61
|
-
readonly schemaVersion: {
|
|
62
|
-
readonly type: "string";
|
|
63
|
-
};
|
|
64
|
-
readonly deprecatedBy: {
|
|
65
|
-
readonly type: "string";
|
|
66
|
-
};
|
|
67
|
-
readonly createdAt: {
|
|
68
|
-
readonly type: "string";
|
|
69
|
-
};
|
|
70
|
-
readonly updatedAt: {
|
|
71
|
-
readonly type: "string";
|
|
72
|
-
};
|
|
73
|
-
readonly usageCount: {
|
|
74
|
-
readonly type: "number";
|
|
75
|
-
};
|
|
76
|
-
readonly firstSeenTs: {
|
|
77
|
-
readonly type: "string";
|
|
78
|
-
};
|
|
79
|
-
readonly lastUsedAt: {
|
|
80
|
-
readonly type: "string";
|
|
81
|
-
};
|
|
82
|
-
readonly riskScore: {
|
|
83
|
-
readonly type: "number";
|
|
84
|
-
};
|
|
85
|
-
readonly reviewIntervalDays: {
|
|
86
|
-
readonly type: "number";
|
|
87
|
-
};
|
|
88
|
-
readonly workspaceId: {
|
|
89
|
-
readonly type: "string";
|
|
90
|
-
};
|
|
91
|
-
readonly userId: {
|
|
92
|
-
readonly type: "string";
|
|
93
|
-
};
|
|
94
|
-
readonly teamIds: {
|
|
95
|
-
readonly type: "array";
|
|
96
|
-
readonly items: {
|
|
97
|
-
readonly type: "string";
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
readonly contentType: {
|
|
101
|
-
readonly enum: readonly ["instruction", "template", "workflow", "reference", "example", "agent"];
|
|
102
|
-
};
|
|
103
|
-
readonly version: {
|
|
104
|
-
readonly type: "string";
|
|
105
|
-
};
|
|
106
|
-
readonly status: {
|
|
107
|
-
readonly enum: readonly ["draft", "review", "approved", "deprecated"];
|
|
108
|
-
};
|
|
109
|
-
readonly owner: {
|
|
110
|
-
readonly type: "string";
|
|
111
|
-
};
|
|
112
|
-
readonly priorityTier: {
|
|
113
|
-
readonly enum: readonly ["P1", "P2", "P3", "P4"];
|
|
114
|
-
};
|
|
115
|
-
readonly classification: {
|
|
116
|
-
readonly enum: readonly ["public", "internal", "restricted"];
|
|
117
|
-
};
|
|
118
|
-
readonly lastReviewedAt: {
|
|
119
|
-
readonly type: "string";
|
|
120
|
-
};
|
|
121
|
-
readonly nextReviewDue: {
|
|
122
|
-
readonly type: "string";
|
|
123
|
-
};
|
|
124
|
-
readonly changeLog: {
|
|
125
|
-
readonly type: "array";
|
|
126
|
-
readonly items: {
|
|
127
|
-
readonly type: "object";
|
|
128
|
-
readonly required: readonly ["version", "changedAt", "summary"];
|
|
129
|
-
readonly additionalProperties: false;
|
|
130
|
-
readonly properties: {
|
|
131
|
-
readonly version: {
|
|
132
|
-
readonly type: "string";
|
|
133
|
-
};
|
|
134
|
-
readonly changedAt: {
|
|
135
|
-
readonly type: "string";
|
|
136
|
-
};
|
|
137
|
-
readonly summary: {
|
|
138
|
-
readonly type: "string";
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
};
|
|
142
|
-
};
|
|
143
|
-
readonly supersedes: {
|
|
144
|
-
readonly type: "string";
|
|
145
|
-
};
|
|
146
|
-
readonly archivedAt: {
|
|
147
|
-
readonly type: "string";
|
|
148
|
-
};
|
|
149
|
-
readonly semanticSummary: {
|
|
150
|
-
readonly type: "string";
|
|
151
|
-
};
|
|
152
|
-
readonly createdByAgent: {
|
|
153
|
-
readonly type: "string";
|
|
154
|
-
};
|
|
155
|
-
readonly sourceWorkspace: {
|
|
156
|
-
readonly type: "string";
|
|
157
|
-
};
|
|
158
|
-
readonly extensions: {
|
|
159
|
-
readonly type: "object";
|
|
160
|
-
readonly additionalProperties: {
|
|
161
|
-
readonly $ref: "#/$defs/extensionValue";
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
};
|
|
1
|
+
export { RECORD_SCHEMA, INPUT_SCHEMA, splitEntry, RECORD_PROPERTY_KEYS, INPUT_KEYS, SERVER_MANAGED_KEYS, REQUIRED_RECORD_KEYS, REQUIRED_INPUT_KEYS, validateRecord, validateInput, buildToolInputEntrySchema, INSTRUCTION_INPUT_SCHEMA_REF, INSTRUCTION_RECORD_SCHEMA_REF, } from './instructionSchema';
|
|
2
|
+
export declare const instructionEntry: Record<string, unknown> & {
|
|
3
|
+
properties?: Record<string, Record<string, unknown> & /*elided*/ any>;
|
|
4
|
+
required?: string[];
|
|
5
|
+
additionalProperties?: boolean | (Record<string, unknown> & /*elided*/ any);
|
|
6
|
+
$defs?: Record<string, Record<string, unknown> & /*elided*/ any>;
|
|
7
|
+
definitions?: Record<string, Record<string, unknown> & /*elided*/ any>;
|
|
165
8
|
};
|
|
166
9
|
export declare const schemas: Record<string, unknown>;
|
|
167
10
|
export type SchemaMap = typeof schemas;
|
package/dist/schemas/index.js
CHANGED
|
@@ -1,66 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schemas = exports.instructionEntry = exports.INSTRUCTION_RECORD_SCHEMA_REF = exports.INSTRUCTION_INPUT_SCHEMA_REF = exports.buildToolInputEntrySchema = exports.validateInput = exports.validateRecord = exports.REQUIRED_INPUT_KEYS = exports.REQUIRED_RECORD_KEYS = exports.SERVER_MANAGED_KEYS = exports.INPUT_KEYS = exports.RECORD_PROPERTY_KEYS = exports.splitEntry = exports.INPUT_SCHEMA = exports.RECORD_SCHEMA = void 0;
|
|
2
4
|
// JSON Schemas for tool response contracts. These are used in tests to lock interfaces.
|
|
3
5
|
// Increment version in docs/tools.md when changing any stable schema.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
body: { type: 'string' },
|
|
28
|
-
rationale: { type: 'string' },
|
|
29
|
-
priority: { type: 'number' },
|
|
30
|
-
audience: { enum: ['individual', 'group', 'all'] },
|
|
31
|
-
requirement: { enum: ['mandatory', 'critical', 'recommended', 'optional', 'deprecated'] },
|
|
32
|
-
categories: { type: 'array', items: { type: 'string' } },
|
|
33
|
-
primaryCategory: { type: 'string' },
|
|
34
|
-
sourceHash: { type: 'string' },
|
|
35
|
-
schemaVersion: { type: 'string' },
|
|
36
|
-
deprecatedBy: { type: 'string' },
|
|
37
|
-
createdAt: { type: 'string' },
|
|
38
|
-
updatedAt: { type: 'string' },
|
|
39
|
-
usageCount: { type: 'number' },
|
|
40
|
-
firstSeenTs: { type: 'string' },
|
|
41
|
-
lastUsedAt: { type: 'string' },
|
|
42
|
-
riskScore: { type: 'number' },
|
|
43
|
-
reviewIntervalDays: { type: 'number' },
|
|
44
|
-
workspaceId: { type: 'string' },
|
|
45
|
-
userId: { type: 'string' },
|
|
46
|
-
teamIds: { type: 'array', items: { type: 'string' } },
|
|
47
|
-
contentType: { enum: ['instruction', 'template', 'workflow', 'reference', 'example', 'agent'] },
|
|
48
|
-
version: { type: 'string' },
|
|
49
|
-
status: { enum: ['draft', 'review', 'approved', 'deprecated'] },
|
|
50
|
-
owner: { type: 'string' },
|
|
51
|
-
priorityTier: { enum: ['P1', 'P2', 'P3', 'P4'] },
|
|
52
|
-
classification: { enum: ['public', 'internal', 'restricted'] },
|
|
53
|
-
lastReviewedAt: { type: 'string' },
|
|
54
|
-
nextReviewDue: { type: 'string' },
|
|
55
|
-
changeLog: { type: 'array', items: { type: 'object', required: ['version', 'changedAt', 'summary'], additionalProperties: false, properties: { version: { type: 'string' }, changedAt: { type: 'string' }, summary: { type: 'string' } } } },
|
|
56
|
-
supersedes: { type: 'string' },
|
|
57
|
-
archivedAt: { type: 'string' },
|
|
58
|
-
semanticSummary: { type: 'string' },
|
|
59
|
-
createdByAgent: { type: 'string' },
|
|
60
|
-
sourceWorkspace: { type: 'string' },
|
|
61
|
-
extensions: { type: 'object', additionalProperties: { $ref: '#/$defs/extensionValue' } }
|
|
62
|
-
}
|
|
63
|
-
};
|
|
6
|
+
//
|
|
7
|
+
// SOURCE OF TRUTH: instruction record/input schemas are derived from
|
|
8
|
+
// schemas/instruction.schema.json via src/schemas/instructionSchema.ts.
|
|
9
|
+
// This module re-exports them under their historic names so existing
|
|
10
|
+
// consumers keep working without restating the schema. Do NOT inline a
|
|
11
|
+
// copy here again — every duplicate causes the kind of drift that
|
|
12
|
+
// broke import round-trips.
|
|
13
|
+
const instructionSchema_1 = require("./instructionSchema");
|
|
14
|
+
var instructionSchema_2 = require("./instructionSchema");
|
|
15
|
+
Object.defineProperty(exports, "RECORD_SCHEMA", { enumerable: true, get: function () { return instructionSchema_2.RECORD_SCHEMA; } });
|
|
16
|
+
Object.defineProperty(exports, "INPUT_SCHEMA", { enumerable: true, get: function () { return instructionSchema_2.INPUT_SCHEMA; } });
|
|
17
|
+
Object.defineProperty(exports, "splitEntry", { enumerable: true, get: function () { return instructionSchema_2.splitEntry; } });
|
|
18
|
+
Object.defineProperty(exports, "RECORD_PROPERTY_KEYS", { enumerable: true, get: function () { return instructionSchema_2.RECORD_PROPERTY_KEYS; } });
|
|
19
|
+
Object.defineProperty(exports, "INPUT_KEYS", { enumerable: true, get: function () { return instructionSchema_2.INPUT_KEYS; } });
|
|
20
|
+
Object.defineProperty(exports, "SERVER_MANAGED_KEYS", { enumerable: true, get: function () { return instructionSchema_2.SERVER_MANAGED_KEYS; } });
|
|
21
|
+
Object.defineProperty(exports, "REQUIRED_RECORD_KEYS", { enumerable: true, get: function () { return instructionSchema_2.REQUIRED_RECORD_KEYS; } });
|
|
22
|
+
Object.defineProperty(exports, "REQUIRED_INPUT_KEYS", { enumerable: true, get: function () { return instructionSchema_2.REQUIRED_INPUT_KEYS; } });
|
|
23
|
+
Object.defineProperty(exports, "validateRecord", { enumerable: true, get: function () { return instructionSchema_2.validateRecord; } });
|
|
24
|
+
Object.defineProperty(exports, "validateInput", { enumerable: true, get: function () { return instructionSchema_2.validateInput; } });
|
|
25
|
+
Object.defineProperty(exports, "buildToolInputEntrySchema", { enumerable: true, get: function () { return instructionSchema_2.buildToolInputEntrySchema; } });
|
|
26
|
+
Object.defineProperty(exports, "INSTRUCTION_INPUT_SCHEMA_REF", { enumerable: true, get: function () { return instructionSchema_2.INSTRUCTION_INPUT_SCHEMA_REF; } });
|
|
27
|
+
Object.defineProperty(exports, "INSTRUCTION_RECORD_SCHEMA_REF", { enumerable: true, get: function () { return instructionSchema_2.INSTRUCTION_RECORD_SCHEMA_REF; } });
|
|
28
|
+
exports.instructionEntry = instructionSchema_1.RECORD_SCHEMA;
|
|
64
29
|
// (listLike schema removed after dispatcher consolidation of read-only instruction methods)
|
|
65
30
|
// Using unknown for schema values to avoid any and preserve flexibility
|
|
66
31
|
exports.schemas = {
|
|
@@ -89,9 +54,26 @@ exports.schemas = {
|
|
|
89
54
|
'index_import': {
|
|
90
55
|
anyOf: [
|
|
91
56
|
{ type: 'object', required: ['error'], properties: { error: { type: 'string' } }, additionalProperties: true },
|
|
92
|
-
{ type: 'object',
|
|
93
|
-
|
|
94
|
-
|
|
57
|
+
{ type: 'object',
|
|
58
|
+
required: ['hash', 'imported', 'skipped', 'overwritten', 'errors', 'total', 'verified', 'verifiedCount', 'verificationErrorCount', 'stripped'],
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
properties: {
|
|
61
|
+
hash: { type: 'string' },
|
|
62
|
+
imported: { type: 'number' },
|
|
63
|
+
skipped: { type: 'number' },
|
|
64
|
+
overwritten: { type: 'number' },
|
|
65
|
+
total: { type: 'number' },
|
|
66
|
+
errors: { type: 'array', items: { type: 'object', required: ['id', 'error'], properties: { id: { type: 'string' }, error: { type: 'string' } }, additionalProperties: false } },
|
|
67
|
+
verified: { type: 'boolean', description: 'True when every written entry was readable in the post-write reload (verifiedCount === written count, verificationErrorCount === 0).' },
|
|
68
|
+
verifiedCount: { type: 'number', description: 'Number of newly written/overwritten entries successfully read back after reload.' },
|
|
69
|
+
verificationErrorCount: { type: 'number', description: 'Number of newly written entries missing from the index after the post-write reload.' },
|
|
70
|
+
stripped: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
description: 'Per-key counts of server-managed fields (e.g. createdAt, updatedAt, sourceHash, schemaVersion) partitioned out of caller payloads via splitEntry. Empty object when no server-managed fields were supplied.',
|
|
73
|
+
additionalProperties: { type: 'number' },
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|
|
95
77
|
]
|
|
96
78
|
},
|
|
97
79
|
'index_repair': { type: 'object', required: ['repaired', 'updated'], additionalProperties: false, properties: { repaired: { type: 'number' }, updated: { type: 'array', items: { type: 'string' } } } },
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ValidateFunction } from 'ajv';
|
|
2
|
+
type JsonSchema = Record<string, unknown> & {
|
|
3
|
+
properties?: Record<string, JsonSchema>;
|
|
4
|
+
required?: string[];
|
|
5
|
+
additionalProperties?: boolean | JsonSchema;
|
|
6
|
+
$defs?: Record<string, JsonSchema>;
|
|
7
|
+
definitions?: Record<string, JsonSchema>;
|
|
8
|
+
};
|
|
9
|
+
export declare const RECORD_PROPERTY_KEYS: ReadonlySet<string>;
|
|
10
|
+
export declare const SERVER_MANAGED_KEYS: ReadonlySet<string>;
|
|
11
|
+
export declare const INPUT_KEYS: ReadonlySet<string>;
|
|
12
|
+
export declare const REQUIRED_RECORD_KEYS: ReadonlySet<string>;
|
|
13
|
+
export declare const REQUIRED_INPUT_KEYS: ReadonlySet<string>;
|
|
14
|
+
export declare const RECORD_SCHEMA: JsonSchema;
|
|
15
|
+
export declare const INPUT_SCHEMA: JsonSchema;
|
|
16
|
+
export interface SplitEntryResult<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
17
|
+
input: Partial<T>;
|
|
18
|
+
serverManaged: Partial<T>;
|
|
19
|
+
unknown: Partial<T>;
|
|
20
|
+
}
|
|
21
|
+
export declare function splitEntry<T extends Record<string, unknown>>(entry: T | null | undefined): SplitEntryResult<T>;
|
|
22
|
+
export declare const validateRecord: ValidateFunction;
|
|
23
|
+
export declare const validateInput: ValidateFunction;
|
|
24
|
+
export declare const INSTRUCTION_INPUT_SCHEMA_REF = "index_add#input";
|
|
25
|
+
export declare const INSTRUCTION_RECORD_SCHEMA_REF: string;
|
|
26
|
+
/**
|
|
27
|
+
* Build a tool-registry-friendly variant of INPUT_SCHEMA with a caller-supplied
|
|
28
|
+
* required[] minimum and a custom $id.
|
|
29
|
+
*
|
|
30
|
+
* Different MCP tool surfaces accept different "minimum required" shapes for
|
|
31
|
+
* the SAME underlying entry contract:
|
|
32
|
+
*
|
|
33
|
+
* - index_add accepts { id, body } at minimum (handler defaults the rest)
|
|
34
|
+
* - index_import requires { id, title, body, priority, audience, requirement }
|
|
35
|
+
*
|
|
36
|
+
* Both must still reject server-managed properties (additionalProperties:false +
|
|
37
|
+
* server-managed keys stripped) and use the same property definitions, enums,
|
|
38
|
+
* and patterns. This helper produces that variant from the canonical INPUT
|
|
39
|
+
* schema so the tool-discovery surface advertised over MCP cannot drift from
|
|
40
|
+
* the on-disk validation surface.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildToolInputEntrySchema(opts: {
|
|
43
|
+
required: string[];
|
|
44
|
+
schemaId?: string;
|
|
45
|
+
}): JsonSchema;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Single source of truth for the instruction record contract.
|
|
3
|
+
//
|
|
4
|
+
// The canonical JSON Schema lives at schemas/instruction.schema.json. This
|
|
5
|
+
// module loads it ONCE and derives every downstream artifact from it:
|
|
6
|
+
//
|
|
7
|
+
// * RECORD_SCHEMA — full record (used to validate on-disk entries
|
|
8
|
+
// and exports)
|
|
9
|
+
// * INPUT_SCHEMA — write-API contract: properties whose
|
|
10
|
+
// x-fieldClass is "server-managed" are stripped,
|
|
11
|
+
// additionalProperties is forced to false,
|
|
12
|
+
// required is filtered to input-only fields.
|
|
13
|
+
// * RECORD_PROPERTY_KEYS — every property name on the canonical schema
|
|
14
|
+
// * INPUT_KEYS — properties accepted from callers
|
|
15
|
+
// * SERVER_MANAGED_KEYS — properties owned by the server (exports show
|
|
16
|
+
// them, input must not)
|
|
17
|
+
// * REQUIRED_RECORD_KEYS — required[] from the canonical schema
|
|
18
|
+
// * REQUIRED_INPUT_KEYS — required[] minus server-managed
|
|
19
|
+
// * splitEntry() — partition a payload into
|
|
20
|
+
// { input, serverManaged, unknown }
|
|
21
|
+
// * compiled validators — validateRecord, validateInput
|
|
22
|
+
//
|
|
23
|
+
// Every other module in this codebase MUST import these derived artifacts
|
|
24
|
+
// instead of restating the schema. See instructionRecordValidation.ts and
|
|
25
|
+
// services/handlers/instructions.{add,import}.ts for the canonical
|
|
26
|
+
// consumers.
|
|
27
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
28
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.INSTRUCTION_RECORD_SCHEMA_REF = exports.INSTRUCTION_INPUT_SCHEMA_REF = exports.validateInput = exports.validateRecord = exports.INPUT_SCHEMA = exports.RECORD_SCHEMA = exports.REQUIRED_INPUT_KEYS = exports.REQUIRED_RECORD_KEYS = exports.INPUT_KEYS = exports.SERVER_MANAGED_KEYS = exports.RECORD_PROPERTY_KEYS = void 0;
|
|
32
|
+
exports.splitEntry = splitEntry;
|
|
33
|
+
exports.buildToolInputEntrySchema = buildToolInputEntrySchema;
|
|
34
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
35
|
+
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
36
|
+
const json_schema_draft_07_json_1 = __importDefault(require("ajv/dist/refs/json-schema-draft-07.json"));
|
|
37
|
+
const instruction_schema_json_1 = __importDefault(require("../../schemas/instruction.schema.json"));
|
|
38
|
+
const CANONICAL = instruction_schema_json_1.default;
|
|
39
|
+
function deepClone(value) {
|
|
40
|
+
return JSON.parse(JSON.stringify(value));
|
|
41
|
+
}
|
|
42
|
+
function isServerManaged(prop) {
|
|
43
|
+
if (!prop || typeof prop !== 'object')
|
|
44
|
+
return false;
|
|
45
|
+
return prop['x-fieldClass'] === 'server-managed';
|
|
46
|
+
}
|
|
47
|
+
const allProps = (CANONICAL.properties ?? {});
|
|
48
|
+
const requiredRecord = (CANONICAL.required ?? []);
|
|
49
|
+
exports.RECORD_PROPERTY_KEYS = new Set(Object.keys(allProps));
|
|
50
|
+
exports.SERVER_MANAGED_KEYS = new Set(Object.entries(allProps)
|
|
51
|
+
.filter(([, def]) => isServerManaged(def))
|
|
52
|
+
.map(([name]) => name));
|
|
53
|
+
exports.INPUT_KEYS = new Set(Object.keys(allProps).filter((name) => !exports.SERVER_MANAGED_KEYS.has(name)));
|
|
54
|
+
exports.REQUIRED_RECORD_KEYS = new Set(requiredRecord);
|
|
55
|
+
exports.REQUIRED_INPUT_KEYS = new Set(requiredRecord.filter((name) => !exports.SERVER_MANAGED_KEYS.has(name)));
|
|
56
|
+
// RECORD_SCHEMA: the canonical schema, deep-cloned so consumers cannot
|
|
57
|
+
// mutate the loaded module.
|
|
58
|
+
exports.RECORD_SCHEMA = deepClone(CANONICAL);
|
|
59
|
+
// INPUT_SCHEMA: derived. Strip server-managed properties, drop them from
|
|
60
|
+
// required[], force additionalProperties:false. Same $defs, same enum
|
|
61
|
+
// values, same patterns — single source.
|
|
62
|
+
exports.INPUT_SCHEMA = (() => {
|
|
63
|
+
const cloned = deepClone(CANONICAL);
|
|
64
|
+
const props = (cloned.properties ?? {});
|
|
65
|
+
const filteredProps = {};
|
|
66
|
+
for (const [name, def] of Object.entries(props)) {
|
|
67
|
+
if (exports.SERVER_MANAGED_KEYS.has(name))
|
|
68
|
+
continue;
|
|
69
|
+
filteredProps[name] = def;
|
|
70
|
+
}
|
|
71
|
+
cloned.properties = filteredProps;
|
|
72
|
+
cloned.required = (cloned.required ?? []).filter((name) => !exports.SERVER_MANAGED_KEYS.has(name));
|
|
73
|
+
cloned.additionalProperties = false;
|
|
74
|
+
// Distinguish the derived schema in error messages.
|
|
75
|
+
cloned.$id = 'index_add#input';
|
|
76
|
+
cloned.title = 'InstructionInput';
|
|
77
|
+
return cloned;
|
|
78
|
+
})();
|
|
79
|
+
function splitEntry(entry) {
|
|
80
|
+
const result = { input: {}, serverManaged: {}, unknown: {} };
|
|
81
|
+
if (!entry || typeof entry !== 'object')
|
|
82
|
+
return result;
|
|
83
|
+
for (const [key, value] of Object.entries(entry)) {
|
|
84
|
+
if (exports.SERVER_MANAGED_KEYS.has(key)) {
|
|
85
|
+
result.serverManaged[key] = value;
|
|
86
|
+
}
|
|
87
|
+
else if (exports.INPUT_KEYS.has(key)) {
|
|
88
|
+
result.input[key] = value;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
result.unknown[key] = value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
// Compiled validators. Construct a single Ajv instance and register both
|
|
97
|
+
// schemas so error messages can reference the right $id.
|
|
98
|
+
const ajv = new ajv_1.default({ allErrors: true, strict: false });
|
|
99
|
+
(0, ajv_formats_1.default)(ajv);
|
|
100
|
+
// Register the draft-07 meta schema under both URIs Ajv may look up
|
|
101
|
+
// (with and without trailing '#'), since the canonical schema declares
|
|
102
|
+
// `$schema: "https://json-schema.org/draft-07/schema#"` and Ajv will
|
|
103
|
+
// validate it on compile.
|
|
104
|
+
for (const id of [
|
|
105
|
+
'https://json-schema.org/draft-07/schema',
|
|
106
|
+
'https://json-schema.org/draft-07/schema#',
|
|
107
|
+
'http://json-schema.org/draft-07/schema',
|
|
108
|
+
'http://json-schema.org/draft-07/schema#',
|
|
109
|
+
]) {
|
|
110
|
+
try {
|
|
111
|
+
if (!ajv.getSchema(id))
|
|
112
|
+
ajv.addMetaSchema(json_schema_draft_07_json_1.default, id);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Non-fatal: Ajv refuses to register the meta schema twice across a hot
|
|
116
|
+
// module reload. Same defensive pattern used by the legacy validator.
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.validateRecord = ajv.compile(deepClone(exports.RECORD_SCHEMA));
|
|
120
|
+
exports.validateInput = ajv.compile(deepClone(exports.INPUT_SCHEMA));
|
|
121
|
+
exports.INSTRUCTION_INPUT_SCHEMA_REF = 'index_add#input';
|
|
122
|
+
exports.INSTRUCTION_RECORD_SCHEMA_REF = CANONICAL.$id ?? 'instruction.schema.json';
|
|
123
|
+
/**
|
|
124
|
+
* Build a tool-registry-friendly variant of INPUT_SCHEMA with a caller-supplied
|
|
125
|
+
* required[] minimum and a custom $id.
|
|
126
|
+
*
|
|
127
|
+
* Different MCP tool surfaces accept different "minimum required" shapes for
|
|
128
|
+
* the SAME underlying entry contract:
|
|
129
|
+
*
|
|
130
|
+
* - index_add accepts { id, body } at minimum (handler defaults the rest)
|
|
131
|
+
* - index_import requires { id, title, body, priority, audience, requirement }
|
|
132
|
+
*
|
|
133
|
+
* Both must still reject server-managed properties (additionalProperties:false +
|
|
134
|
+
* server-managed keys stripped) and use the same property definitions, enums,
|
|
135
|
+
* and patterns. This helper produces that variant from the canonical INPUT
|
|
136
|
+
* schema so the tool-discovery surface advertised over MCP cannot drift from
|
|
137
|
+
* the on-disk validation surface.
|
|
138
|
+
*/
|
|
139
|
+
function buildToolInputEntrySchema(opts) {
|
|
140
|
+
const cloned = deepClone(exports.INPUT_SCHEMA);
|
|
141
|
+
// Filter required[] to keys that actually exist as input properties. If a
|
|
142
|
+
// caller asks for a server-managed key we drop it (logic error in the
|
|
143
|
+
// caller, but never silently expose a server field as required input).
|
|
144
|
+
cloned.required = opts.required.filter((k) => exports.INPUT_KEYS.has(k) && !exports.SERVER_MANAGED_KEYS.has(k));
|
|
145
|
+
// Strip parent metadata that doesn't make sense embedded as a sub-schema.
|
|
146
|
+
// The tool-registry overlay (withDynamicInstructionBodyLimits) injects a
|
|
147
|
+
// per-compile unique $id so Ajv can both register the schema across
|
|
148
|
+
// re-compiles AND resolve internal "#/definitions/..." $refs.
|
|
149
|
+
const meta = cloned;
|
|
150
|
+
delete meta.$schema;
|
|
151
|
+
delete meta.title;
|
|
152
|
+
if (opts.schemaId) {
|
|
153
|
+
meta.$id = opts.schemaId;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
delete meta.$id;
|
|
157
|
+
}
|
|
158
|
+
return cloned;
|
|
159
|
+
}
|
|
@@ -198,12 +198,14 @@
|
|
|
198
198
|
"ContentType": {
|
|
199
199
|
"type": "string",
|
|
200
200
|
"enum": [
|
|
201
|
+
"agent",
|
|
202
|
+
"skill",
|
|
201
203
|
"instruction",
|
|
202
|
-
"
|
|
204
|
+
"prompt",
|
|
203
205
|
"workflow",
|
|
204
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"
|
|
206
|
+
"knowledge",
|
|
207
|
+
"template",
|
|
208
|
+
"integration"
|
|
207
209
|
]
|
|
208
210
|
}
|
|
209
211
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.28.19",
|
|
3
|
+
"generatedAt": "2026-05-11T01:35:27.991Z",
|
|
4
|
+
"trackedDir": "schemas",
|
|
5
|
+
"distDir": "dist/schemas",
|
|
6
|
+
"jsonSchemas": [
|
|
7
|
+
{
|
|
8
|
+
"type": "AudienceScope",
|
|
9
|
+
"source": "src/models/instruction.ts",
|
|
10
|
+
"file": "json-schema/instruction-audience-scope.schema.json"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "ContentType",
|
|
14
|
+
"source": "src/models/instruction.ts",
|
|
15
|
+
"file": "json-schema/instruction-content-type.schema.json"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "InstructionEntry",
|
|
19
|
+
"source": "src/models/instruction.ts",
|
|
20
|
+
"file": "json-schema/instruction-instruction-entry.schema.json"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "RequirementLevel",
|
|
24
|
+
"source": "src/models/instruction.ts",
|
|
25
|
+
"file": "json-schema/instruction-requirement-level.schema.json"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "PersistedAdminSession",
|
|
29
|
+
"source": "src/models/SessionPersistence.ts",
|
|
30
|
+
"file": "json-schema/SessionPersistence-persisted-admin-session.schema.json"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "PersistedSessionHistoryEntry",
|
|
34
|
+
"source": "src/models/SessionPersistence.ts",
|
|
35
|
+
"file": "json-schema/SessionPersistence-persisted-session-history-entry.schema.json"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "PersistedWebSocketConnection",
|
|
39
|
+
"source": "src/models/SessionPersistence.ts",
|
|
40
|
+
"file": "json-schema/SessionPersistence-persisted-web-socket-connection.schema.json"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "SessionPersistenceConfig",
|
|
44
|
+
"source": "src/models/SessionPersistence.ts",
|
|
45
|
+
"file": "json-schema/SessionPersistence-session-persistence-config.schema.json"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "SessionPersistenceData",
|
|
49
|
+
"source": "src/models/SessionPersistence.ts",
|
|
50
|
+
"file": "json-schema/SessionPersistence-session-persistence-data.schema.json"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "SessionPersistenceManifest",
|
|
54
|
+
"source": "src/models/SessionPersistence.ts",
|
|
55
|
+
"file": "json-schema/SessionPersistence-session-persistence-manifest.schema.json"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "SessionPersistenceMetadata",
|
|
59
|
+
"source": "src/models/SessionPersistence.ts",
|
|
60
|
+
"file": "json-schema/SessionPersistence-session-persistence-metadata.schema.json"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"skippedJsonSchemas": [],
|
|
64
|
+
"codeModel": {
|
|
65
|
+
"file": "index-server.code-schema.json",
|
|
66
|
+
"sourceRoots": [
|
|
67
|
+
"src",
|
|
68
|
+
"scripts"
|
|
69
|
+
],
|
|
70
|
+
"fileCount": 266,
|
|
71
|
+
"features": {
|
|
72
|
+
"jsdoc": true,
|
|
73
|
+
"lineNumbers": true,
|
|
74
|
+
"typeParameters": true,
|
|
75
|
+
"decorators": true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -178,9 +178,15 @@ if (!process.listeners('uncaughtException').some(l => l.name === 'mcpGlobalGuard
|
|
|
178
178
|
// are orphaned and should exit. The check uses process.kill(pid, 0) which on
|
|
179
179
|
// Windows calls OpenProcess() -- it throws ESRCH if the process doesn't exist.
|
|
180
180
|
// Skip when ppid is 0 or 1 (init / no parent) or when running interactively.
|
|
181
|
+
//
|
|
182
|
+
// Opt-out: INDEX_SERVER_DISABLE_PPID_WATCHDOG=1 disables the watchdog entirely.
|
|
183
|
+
// Required for dev sandbox launchers that intentionally spawn through a
|
|
184
|
+
// transient shell (e.g. `cmd /c start /B node ...`), where the recorded PPID
|
|
185
|
+
// is the cmd shell that exits immediately after spawning the node child.
|
|
181
186
|
try {
|
|
187
|
+
const watchdogDisabled = (0, envUtils_1.getBooleanEnv)('INDEX_SERVER_DISABLE_PPID_WATCHDOG');
|
|
182
188
|
const ppid = process.ppid;
|
|
183
|
-
if (ppid && ppid > 1) {
|
|
189
|
+
if (!watchdogDisabled && ppid && ppid > 1) {
|
|
184
190
|
const PPID_CHECK_INTERVAL_MS = 30_000; // 30 seconds
|
|
185
191
|
const ppidTimer = setInterval(() => {
|
|
186
192
|
try {
|
|
@@ -22,11 +22,11 @@ const runtimeConfig_1 = require("../config/runtimeConfig");
|
|
|
22
22
|
* Bootstrap / confirmation gating logic.
|
|
23
23
|
* States:
|
|
24
24
|
* - reference mode (INDEX_SERVER_REFERENCE_MODE=1): index is read-only, all mutation blocked permanently
|
|
25
|
-
* - new workspace: only bootstrap seed instructions present (000-bootstrapper / 001-lifecycle-bootstrap) → require confirmation
|
|
25
|
+
* - new workspace: only bootstrap seed instructions present (000-bootstrapper / 001-lifecycle-bootstrap / 002-content-model / 003-content-types) → require confirmation
|
|
26
26
|
* - existing workspace: any non-bootstrap instruction present OR confirmation file exists -> mutation allowed (unless explicitly forced read-only)
|
|
27
27
|
* - confirmed: confirmation file created after successful finalize → persists across restarts
|
|
28
28
|
*/
|
|
29
|
-
const BOOTSTRAP_IDS = new Set(['000-bootstrapper', '001-lifecycle-bootstrap']);
|
|
29
|
+
const BOOTSTRAP_IDS = new Set(['000-bootstrapper', '001-lifecycle-bootstrap', '002-content-model', '003-content-types']);
|
|
30
30
|
const CONFIRM_FILE = 'bootstrap.confirmed.json';
|
|
31
31
|
const PENDING_FILE = 'bootstrap.pending.json';
|
|
32
32
|
let inMemoryPending = null;
|