dxcomplete 0.2.1 → 0.2.2

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 (47) hide show
  1. package/.env.example +0 -7
  2. package/README.md +17 -45
  3. package/dist/cli.js +0 -22
  4. package/dist/validate.js +10 -26
  5. package/docs/model.md +3 -3
  6. package/docs/taxonomy.md +1 -1
  7. package/package.json +23 -23
  8. package/templates/process/README.md +1 -1
  9. package/dist/http/service.d.ts +0 -7
  10. package/dist/http/service.js +0 -725
  11. package/dist/mcp/docs.d.ts +0 -114
  12. package/dist/mcp/docs.js +0 -626
  13. package/dist/mcp/server.d.ts +0 -20
  14. package/dist/mcp/server.js +0 -3059
  15. package/dist/runtime/auth.d.ts +0 -162
  16. package/dist/runtime/auth.js +0 -394
  17. package/dist/runtime/check.d.ts +0 -7
  18. package/dist/runtime/check.js +0 -16
  19. package/dist/runtime/config.d.ts +0 -17
  20. package/dist/runtime/config.js +0 -93
  21. package/dist/runtime/mongo.d.ts +0 -9
  22. package/dist/runtime/mongo.js +0 -56
  23. package/dist/runtime/records.d.ts +0 -427
  24. package/dist/runtime/records.js +0 -2092
  25. package/scripts/check-env-surface.mjs +0 -136
  26. package/scripts/check-public-copy.mjs +0 -263
  27. package/scripts/check-service-boundary.mjs +0 -63
  28. package/scripts/runtime-work-order.mjs +0 -506
  29. package/scripts/smoke-mcp-http.mjs +0 -4026
  30. package/src/cli.ts +0 -268
  31. package/src/http/server.ts +0 -314
  32. package/src/http/service.ts +0 -934
  33. package/src/init.ts +0 -262
  34. package/src/install-manifest.ts +0 -144
  35. package/src/mcp/docs.ts +0 -777
  36. package/src/mcp/server.ts +0 -4580
  37. package/src/package-root.ts +0 -31
  38. package/src/runtime/actor.ts +0 -61
  39. package/src/runtime/auth.ts +0 -673
  40. package/src/runtime/check.ts +0 -18
  41. package/src/runtime/config.ts +0 -128
  42. package/src/runtime/mongo.ts +0 -89
  43. package/src/runtime/records.ts +0 -3205
  44. package/src/runtime/workspace.ts +0 -155
  45. package/src/upgrade.ts +0 -356
  46. package/src/validate.ts +0 -141
  47. package/src/version.ts +0 -16
@@ -1,128 +0,0 @@
1
- import { constants as fsConstants } from "node:fs";
2
- import { access, readFile } from "node:fs/promises";
3
- import path from "node:path";
4
-
5
- export type RuntimeOptions = {
6
- cwd?: string;
7
- env?: NodeJS.ProcessEnv;
8
- envFile?: string;
9
- };
10
-
11
- export type RuntimeConfig = {
12
- mongodbUri: string;
13
- databaseName: string;
14
- googleClientId?: string;
15
- googleClientSecret?: string;
16
- serviceProvisioningSecret?: string;
17
- envFilePath?: string;
18
- };
19
-
20
- export class RuntimeConfigError extends Error {
21
- constructor(message: string) {
22
- super(message);
23
- this.name = "RuntimeConfigError";
24
- }
25
- }
26
-
27
- const DEFAULT_ENV_FILE = ".env.local";
28
- const DEFAULT_DATABASE_NAME = "dxcomplete";
29
-
30
- export async function loadRuntimeConfig(options: RuntimeOptions = {}): Promise<RuntimeConfig> {
31
- const cwd = path.resolve(options.cwd ?? process.cwd());
32
- const envFilePath = await resolveEnvFile(cwd, options.envFile);
33
- const fileEnv = envFilePath ? await parseEnvFile(envFilePath) : {};
34
- const env = {
35
- ...fileEnv,
36
- ...(options.env ?? process.env)
37
- };
38
-
39
- const mongodbUri = readRequiredEnv(env, "DXC_MONGODB_URI");
40
- const databaseName = readOptionalEnv(env, "DXC_DATABASE_NAME") ?? DEFAULT_DATABASE_NAME;
41
- const googleClientId = readOptionalEnv(env, "DXC_GOOGLE_CLIENT_ID");
42
- const googleClientSecret = readOptionalEnv(env, "DXC_GOOGLE_CLIENT_SECRET");
43
- const serviceProvisioningSecret = readOptionalEnv(env, "DXC_SERVICE_PROVISIONING_SECRET");
44
-
45
- return {
46
- mongodbUri,
47
- databaseName,
48
- ...(googleClientId ? { googleClientId } : {}),
49
- ...(googleClientSecret ? { googleClientSecret } : {}),
50
- ...(serviceProvisioningSecret ? { serviceProvisioningSecret } : {}),
51
- envFilePath
52
- };
53
- }
54
-
55
- async function resolveEnvFile(cwd: string, envFile?: string): Promise<string | undefined> {
56
- if (envFile) {
57
- const explicitPath = path.resolve(cwd, envFile);
58
- if (!(await fileExists(explicitPath))) {
59
- throw new RuntimeConfigError(`Env file not found: ${explicitPath}`);
60
- }
61
- return explicitPath;
62
- }
63
-
64
- const defaultPath = path.join(cwd, DEFAULT_ENV_FILE);
65
- return (await fileExists(defaultPath)) ? defaultPath : undefined;
66
- }
67
-
68
- async function parseEnvFile(filePath: string): Promise<NodeJS.ProcessEnv> {
69
- const content = await readFile(filePath, "utf8");
70
- const parsed: NodeJS.ProcessEnv = {};
71
-
72
- for (const [index, rawLine] of content.split(/\r?\n/).entries()) {
73
- const trimmed = rawLine.trim();
74
- if (!trimmed || trimmed.startsWith("#")) {
75
- continue;
76
- }
77
-
78
- const line = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trim() : trimmed;
79
- const equalsIndex = line.indexOf("=");
80
- if (equalsIndex === -1) {
81
- throw new RuntimeConfigError(`Invalid env line ${index + 1} in ${filePath}. Expected KEY=value.`);
82
- }
83
-
84
- const key = line.slice(0, equalsIndex).trim();
85
- const value = line.slice(equalsIndex + 1).trim();
86
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
87
- throw new RuntimeConfigError(`Invalid env key "${key}" on line ${index + 1} in ${filePath}.`);
88
- }
89
-
90
- parsed[key] = unquote(value);
91
- }
92
-
93
- return parsed;
94
- }
95
-
96
- function readRequiredEnv(env: NodeJS.ProcessEnv, key: string): string {
97
- const value = readOptionalEnv(env, key);
98
- if (!value) {
99
- throw new RuntimeConfigError(
100
- `${key} is required. Create .env.local from .env.example or export ${key} before running this command.`
101
- );
102
- }
103
- return value;
104
- }
105
-
106
- function readOptionalEnv(env: NodeJS.ProcessEnv, key: string): string | undefined {
107
- const value = env[key]?.trim();
108
- return value ? value : undefined;
109
- }
110
-
111
- function unquote(value: string): string {
112
- if (
113
- (value.startsWith("\"") && value.endsWith("\"")) ||
114
- (value.startsWith("'") && value.endsWith("'"))
115
- ) {
116
- return value.slice(1, -1);
117
- }
118
- return value;
119
- }
120
-
121
- async function fileExists(filePath: string): Promise<boolean> {
122
- try {
123
- await access(filePath, fsConstants.F_OK);
124
- return true;
125
- } catch {
126
- return false;
127
- }
128
- }
@@ -1,89 +0,0 @@
1
- import { MongoClient, type Db } from "mongodb";
2
- import {
3
- OAUTH_AUTH_REQUESTS_COLLECTION,
4
- OAUTH_CLIENTS_COLLECTION,
5
- OAUTH_CODES_COLLECTION,
6
- OAUTH_TOKENS_COLLECTION,
7
- WORKSPACE_SERVICE_CLIENTS_COLLECTION,
8
- WORKSPACE_MEMBERSHIPS_COLLECTION
9
- } from "./auth.js";
10
- import { loadRuntimeConfig, type RuntimeConfig, type RuntimeOptions } from "./config.js";
11
- import {
12
- DXCOMPLETE_TICKET_COLLECTION_NAME,
13
- INDEX_COLLECTION_NAMES,
14
- READABLE_ID_COLLECTION_NAMES,
15
- READABLE_ID_SEQUENCES_COLLECTION,
16
- migrateLegacyIntakeItemsToDxcompleteTickets
17
- } from "./records.js";
18
-
19
- export type DxRuntime = {
20
- config: RuntimeConfig;
21
- client: MongoClient;
22
- db: Db;
23
- close: () => Promise<void>;
24
- };
25
-
26
- export async function connectRuntime(options: RuntimeOptions = {}): Promise<DxRuntime> {
27
- const config = await loadRuntimeConfig(options);
28
- const client = new MongoClient(config.mongodbUri, {
29
- serverSelectionTimeoutMS: 10000
30
- });
31
-
32
- await client.connect();
33
- const db = client.db(config.databaseName);
34
- await db.command({ ping: 1 });
35
- await migrateLegacyIntakeItemsToDxcompleteTickets(db);
36
- await ensureIndexes(db);
37
-
38
- return {
39
- config,
40
- client,
41
- db,
42
- close: () => client.close()
43
- };
44
- }
45
-
46
- async function ensureIndexes(db: Db): Promise<void> {
47
- await Promise.all(
48
- INDEX_COLLECTION_NAMES.map(async (collectionName) => {
49
- const collection = db.collection(collectionName);
50
- await collection.createIndex({ recordType: 1, createdAt: -1 });
51
- await collection.createIndex({ workspaceId: 1, recordType: 1, createdAt: -1 });
52
- await collection.createIndex({ "links.toId": 1 });
53
- await collection.createIndex({ workspaceId: 1, "links.toId": 1 });
54
-
55
- if ((READABLE_ID_COLLECTION_NAMES as readonly string[]).includes(collectionName)) {
56
- await collection.createIndex(
57
- { workspaceId: 1, readableId: 1 },
58
- {
59
- unique: true,
60
- partialFilterExpression: { readableId: { $exists: true } }
61
- }
62
- );
63
- }
64
-
65
- if (collectionName === DXCOMPLETE_TICKET_COLLECTION_NAME) {
66
- await collection.createIndex({ "fields.ownerActorId": 1, archivedAt: 1, updatedAt: -1 });
67
- await collection.createIndex({ "fields.entries.addressedToActorId": 1, "fields.entries.readAt": 1 });
68
- }
69
-
70
- if (collectionName === "journal_entries") {
71
- await collection.createIndex({ workspaceId: 1, "fields.kind": 1, archivedAt: 1, createdAt: 1 });
72
- await collection.createIndex({ workspaceId: 1, archivedAt: 1, createdAt: 1 });
73
- }
74
- })
75
- );
76
-
77
- await Promise.all([
78
- db.collection(WORKSPACE_MEMBERSHIPS_COLLECTION).createIndex({ workspaceId: 1, email: 1 }, { unique: true }),
79
- db.collection(WORKSPACE_MEMBERSHIPS_COLLECTION).createIndex({ provider: 1, providerSubject: 1 }),
80
- db.collection(WORKSPACE_SERVICE_CLIENTS_COLLECTION).createIndex({ workspaceId: 1, clientId: 1 }, { unique: true }),
81
- db.collection(WORKSPACE_SERVICE_CLIENTS_COLLECTION).createIndex({ clientId: 1 }, { unique: true }),
82
- db.collection(OAUTH_CLIENTS_COLLECTION).createIndex({ clientId: 1 }, { unique: true }),
83
- db.collection(OAUTH_AUTH_REQUESTS_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
84
- db.collection(OAUTH_CODES_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
85
- db.collection(OAUTH_TOKENS_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
86
- db.collection(OAUTH_TOKENS_COLLECTION).createIndex({ workspaceId: 1, "actor.actorId": 1 }),
87
- db.collection(READABLE_ID_SEQUENCES_COLLECTION).createIndex({ workspaceId: 1, recordType: 1 }, { unique: true })
88
- ]);
89
- }