archondev 3.0.1 → 3.1.0
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/README.md +27 -32
- package/dist/auth-ZMBA5HYH.js +13 -0
- package/dist/{bug-TFICZ4OP.js → bug-MOMNYU5J.js} +2 -2
- package/dist/{chunk-43IIEFB2.js → chunk-7ELR6RW6.js} +1 -1
- package/dist/{chunk-IG3H7C7R.js → chunk-ARHCVLQW.js} +4 -4
- package/dist/chunk-AWHINKO2.js +244 -0
- package/dist/{chunk-7RXZTPXY.js → chunk-BSG5XY3C.js} +6 -6
- package/dist/{chunk-AJNKSFHL.js → chunk-CI5E4EX3.js} +80 -5
- package/dist/{chunk-4TZOCXAI.js → chunk-ECEWULAA.js} +1 -1
- package/dist/chunk-EF66S6ZQ.js +1189 -0
- package/dist/chunk-EV5QU5KG.js +18 -0
- package/dist/{chunk-45T2VB5R.js → chunk-IZFUFXDN.js} +98 -237
- package/dist/{chunk-YK5Z6U5A.js → chunk-LE5EJ6I4.js} +23 -20
- package/dist/{chunk-PQS3TQB6.js → chunk-LSLQIPLQ.js} +6 -6
- package/dist/chunk-NQBS7L2F.js +55 -0
- package/dist/chunk-RAM67KA6.js +57 -0
- package/dist/{chunk-Q3GIFHIQ.js → client-PPPOHAVY.js} +4 -3
- package/dist/constants-BES4STNW.js +11 -0
- package/dist/{execute-HWUL2M3B.js → execute-WSCLLLY6.js} +4 -4
- package/dist/geo-IRUGSLZS.js +50 -0
- package/dist/index.js +760 -1239
- package/dist/{interviewer-ZGKR7YQQ.js → interviewer-ZUYQ5ZFJ.js} +2 -2
- package/dist/{keys-3PRAVIRC.js → keys-SQUTA4L2.js} +2 -2
- package/dist/{list-7IBMJCCF.js → list-HZM7DNVS.js} +4 -4
- package/dist/{parallel-4PXJA2QD.js → parallel-MWPBKEEN.js} +5 -6
- package/dist/{plan-HBAUG3KD.js → plan-3Z6M4LE6.js} +3 -3
- package/dist/{preferences-VVFGRNPD.js → preferences-OXVXWARL.js} +2 -2
- package/dist/{ship-KHL6NVC2.js → ship-CTZU6RYR.js} +1 -1
- package/dist/{chunk-ONH6Y3CS.js → tier-selection-5KPN2RF2.js} +7 -28
- package/dist/truth-layer-7N32HKCE.js +19 -0
- package/package.json +2 -2
- package/dist/auth-T4C7OQWO.js +0 -14
- package/dist/chunk-57NSGWWD.js +0 -270
- package/dist/chunk-CFJECC3B.js +0 -495
- package/dist/chunk-GGRW4NTA.js +0 -118
- package/dist/chunk-M4LGRTLC.js +0 -10
- package/dist/client-PHW2C2HB.js +0 -11
- package/dist/constants-XDIWFFPN.js +0 -11
- package/dist/geo-BWH5PUBK.js +0 -20
- package/dist/tier-selection-O5AFLKD6.js +0 -18
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadAtom,
|
|
3
3
|
loadRoleOverrides
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BSG5XY3C.js";
|
|
5
5
|
import {
|
|
6
6
|
appendLocalUsageEntry,
|
|
7
7
|
debugLog,
|
|
8
8
|
getDebugLogPath
|
|
9
9
|
} from "./chunk-I3BBA7MB.js";
|
|
10
|
-
import {
|
|
11
|
-
ArchitectureParser
|
|
12
|
-
} from "./chunk-5EVHUDQX.js";
|
|
13
10
|
import {
|
|
14
11
|
transitionAtom
|
|
15
12
|
} from "./chunk-IYZN6FPJ.js";
|
|
16
13
|
import {
|
|
17
14
|
createAIClient
|
|
18
15
|
} from "./chunk-NIIFUBOE.js";
|
|
16
|
+
import {
|
|
17
|
+
loadConfig,
|
|
18
|
+
saveConfig
|
|
19
|
+
} from "./chunk-NQBS7L2F.js";
|
|
20
|
+
import {
|
|
21
|
+
ArchitectureParser
|
|
22
|
+
} from "./chunk-5EVHUDQX.js";
|
|
19
23
|
import {
|
|
20
24
|
getModelProvider
|
|
21
25
|
} from "./chunk-7C6JELBL.js";
|
|
22
26
|
import {
|
|
23
27
|
KeyManager
|
|
24
28
|
} from "./chunk-RDG5BUED.js";
|
|
25
|
-
import {
|
|
26
|
-
loadConfig,
|
|
27
|
-
saveConfig
|
|
28
|
-
} from "./chunk-GGRW4NTA.js";
|
|
29
29
|
import {
|
|
30
30
|
__commonJS,
|
|
31
31
|
__require,
|
|
@@ -4188,7 +4188,7 @@ var ExecutorAgent = class {
|
|
|
4188
4188
|
return {
|
|
4189
4189
|
success: false,
|
|
4190
4190
|
diffs: [],
|
|
4191
|
-
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
4191
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, baseCost: 0, markedUpCost: 0 },
|
|
4192
4192
|
qualityChecksPassed: false,
|
|
4193
4193
|
errorMessage: "Architecture violations: Plan has no target files to modify (files_to_modify is empty)",
|
|
4194
4194
|
rollbackPerformed: false
|
|
@@ -4444,11 +4444,12 @@ var ExecutorAgent = class {
|
|
|
4444
4444
|
if (allowedFiles.length !== 1 || diffs.length !== 1) {
|
|
4445
4445
|
return diffs;
|
|
4446
4446
|
}
|
|
4447
|
-
const
|
|
4447
|
+
const allowedFile = allowedFiles[0];
|
|
4448
4448
|
const candidate = diffs[0];
|
|
4449
|
-
if (!
|
|
4449
|
+
if (!allowedFile || !candidate) {
|
|
4450
4450
|
return diffs;
|
|
4451
4451
|
}
|
|
4452
|
+
const onlyAllowed = this.normalizePath(allowedFile);
|
|
4452
4453
|
const normalizedDiffPath = this.normalizePath(candidate.path);
|
|
4453
4454
|
if (normalizedDiffPath === onlyAllowed) {
|
|
4454
4455
|
return diffs;
|
|
@@ -5078,7 +5079,7 @@ async function attemptPathScopeAutoRecovery(atom, cwd, parseSchema, options) {
|
|
|
5078
5079
|
if (allowedPaths.length === 0) {
|
|
5079
5080
|
return false;
|
|
5080
5081
|
}
|
|
5081
|
-
const { listLocalAtoms, plan } = await import("./plan-
|
|
5082
|
+
const { listLocalAtoms, plan } = await import("./plan-3Z6M4LE6.js");
|
|
5082
5083
|
const before = await listLocalAtoms();
|
|
5083
5084
|
const recoveryStartedAt = Date.now();
|
|
5084
5085
|
const recoverySource = atom.description ?? atom.title;
|
|
@@ -5146,7 +5147,7 @@ async function execute(atomId, options) {
|
|
|
5146
5147
|
process.exit(1);
|
|
5147
5148
|
};
|
|
5148
5149
|
if (options.parallel && options.parallel.length > 0) {
|
|
5149
|
-
const { parallelExecute } = await import("./parallel-
|
|
5150
|
+
const { parallelExecute } = await import("./parallel-MWPBKEEN.js");
|
|
5150
5151
|
const allAtomIds = [atomId, ...options.parallel];
|
|
5151
5152
|
await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
|
|
5152
5153
|
return;
|
|
@@ -5216,6 +5217,7 @@ async function execute(atomId, options) {
|
|
|
5216
5217
|
console.log(chalk3.dim(`Run "archon plan" to create a plan first.`));
|
|
5217
5218
|
return fail();
|
|
5218
5219
|
}
|
|
5220
|
+
const plan = atom.plan;
|
|
5219
5221
|
const atomContext = atom.context;
|
|
5220
5222
|
const designApproved = atomContext?.["designApproved"] === true;
|
|
5221
5223
|
if (!designApproved) {
|
|
@@ -5345,14 +5347,15 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
5345
5347
|
const executorModel = normalizeModelForProvider(roleOverrides?.executor?.model, safeProvider);
|
|
5346
5348
|
const executorConfig = {
|
|
5347
5349
|
provider: safeProvider,
|
|
5348
|
-
model: executorModel
|
|
5350
|
+
...executorModel ? { model: executorModel } : {}
|
|
5349
5351
|
};
|
|
5350
5352
|
const executor = new ExecutorAgent(executorConfig, apiKeys);
|
|
5351
|
-
const
|
|
5353
|
+
const actualExecutorModel = executor.getModelConfig().model;
|
|
5354
|
+
const executionResult = await executor.executeAtom(atom, plan, parseResult.schema, cwd);
|
|
5352
5355
|
await appendLocalUsageEntry({
|
|
5353
5356
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5354
5357
|
projectPath: cwd,
|
|
5355
|
-
model:
|
|
5358
|
+
model: actualExecutorModel,
|
|
5356
5359
|
provider: safeProvider,
|
|
5357
5360
|
operation: "EXECUTION",
|
|
5358
5361
|
inputTokens: executionResult.usage.inputTokens,
|
|
@@ -5364,7 +5367,7 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
5364
5367
|
rollbackPerformed: executionResult.rollbackPerformed,
|
|
5365
5368
|
diffPaths: executionResult.diffs.map((d) => d.path),
|
|
5366
5369
|
errorMessage: executionResult.errorMessage ?? null,
|
|
5367
|
-
plannedFiles:
|
|
5370
|
+
plannedFiles: plan.files_to_modify
|
|
5368
5371
|
});
|
|
5369
5372
|
const filesChanged = executionResult.diffs.map((d) => d.path);
|
|
5370
5373
|
if (!executionResult.success) {
|
|
@@ -5373,7 +5376,7 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
5373
5376
|
atomId: atom.externalId,
|
|
5374
5377
|
errorMessage: executionResult.errorMessage ?? null,
|
|
5375
5378
|
diffPaths: executionResult.diffs.map((d) => d.path),
|
|
5376
|
-
plannedFiles:
|
|
5379
|
+
plannedFiles: plan.files_to_modify,
|
|
5377
5380
|
violations: extractGovernanceViolations(executionResult.errorMessage)
|
|
5378
5381
|
});
|
|
5379
5382
|
console.log(chalk3.yellow("\n\u26A0\uFE0F Execution paused by governance guidance"));
|
|
@@ -5539,8 +5542,8 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5539
5542
|
atomId: atom.id,
|
|
5540
5543
|
atomTitle: atom.title,
|
|
5541
5544
|
filesChanged,
|
|
5542
|
-
planSteps:
|
|
5543
|
-
planRisks:
|
|
5545
|
+
planSteps: plan.steps,
|
|
5546
|
+
planRisks: plan.risks,
|
|
5544
5547
|
success: true
|
|
5545
5548
|
};
|
|
5546
5549
|
const learningResult = await captureLearnings(atom, executionSummary, concise);
|
|
@@ -3,6 +3,10 @@ import {
|
|
|
3
3
|
getDebugLogPath,
|
|
4
4
|
summarizeLocalUsage
|
|
5
5
|
} from "./chunk-I3BBA7MB.js";
|
|
6
|
+
import {
|
|
7
|
+
loadConfig,
|
|
8
|
+
saveConfig
|
|
9
|
+
} from "./chunk-NQBS7L2F.js";
|
|
6
10
|
import {
|
|
7
11
|
findModel,
|
|
8
12
|
getAllActiveModels,
|
|
@@ -17,10 +21,6 @@ import {
|
|
|
17
21
|
import {
|
|
18
22
|
keyManager
|
|
19
23
|
} from "./chunk-RDG5BUED.js";
|
|
20
|
-
import {
|
|
21
|
-
loadConfig,
|
|
22
|
-
saveConfig
|
|
23
|
-
} from "./chunk-GGRW4NTA.js";
|
|
24
24
|
|
|
25
25
|
// src/cli/preferences.ts
|
|
26
26
|
import chalk from "chalk";
|
|
@@ -1033,7 +1033,7 @@ async function manageApiKeys() {
|
|
|
1033
1033
|
if (removeIndex >= 0 && removeIndex < providers.length) {
|
|
1034
1034
|
const providerToRemove = providers[removeIndex];
|
|
1035
1035
|
if (providerToRemove) {
|
|
1036
|
-
const { removeKey } = await import("./keys-
|
|
1036
|
+
const { removeKey } = await import("./keys-SQUTA4L2.js");
|
|
1037
1037
|
await removeKey(providerToRemove);
|
|
1038
1038
|
}
|
|
1039
1039
|
}
|
|
@@ -1041,7 +1041,7 @@ async function manageApiKeys() {
|
|
|
1041
1041
|
}
|
|
1042
1042
|
const provider = providerMap[choice];
|
|
1043
1043
|
if (provider) {
|
|
1044
|
-
const { addKey } = await import("./keys-
|
|
1044
|
+
const { addKey } = await import("./keys-SQUTA4L2.js");
|
|
1045
1045
|
await addKey(provider);
|
|
1046
1046
|
} else if (choice !== "b") {
|
|
1047
1047
|
console.log(chalk.yellow("I did not catch that."));
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/cli/config.ts
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { readFile, writeFile, mkdir, chmod, unlink } from "fs/promises";
|
|
5
|
+
import { existsSync } from "fs";
|
|
6
|
+
var CONFIG_DIR = join(homedir(), ".archon");
|
|
7
|
+
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
8
|
+
async function ensureConfigDir() {
|
|
9
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
10
|
+
await mkdir(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function loadConfig() {
|
|
14
|
+
try {
|
|
15
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
const content = await readFile(CONFIG_FILE, "utf-8");
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function saveConfig(config) {
|
|
25
|
+
await ensureConfigDir();
|
|
26
|
+
const content = JSON.stringify(config, null, 2);
|
|
27
|
+
await writeFile(CONFIG_FILE, content, { mode: 384 });
|
|
28
|
+
await chmod(CONFIG_FILE, 384);
|
|
29
|
+
}
|
|
30
|
+
async function clearConfig() {
|
|
31
|
+
if (existsSync(CONFIG_FILE)) {
|
|
32
|
+
await unlink(CONFIG_FILE);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function isAuthenticated() {
|
|
36
|
+
const config = await loadConfig();
|
|
37
|
+
if (!config.accessToken) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (!config.expiresAt) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const expiresAt = new Date(config.expiresAt);
|
|
44
|
+
if (Number.isNaN(expiresAt.getTime())) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return expiresAt >= /* @__PURE__ */ new Date();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
loadConfig,
|
|
52
|
+
saveConfig,
|
|
53
|
+
clearConfig,
|
|
54
|
+
isAuthenticated
|
|
55
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
printRetiredRemotePath
|
|
3
|
+
} from "./chunk-EV5QU5KG.js";
|
|
4
|
+
import {
|
|
5
|
+
clearConfig,
|
|
6
|
+
loadConfig
|
|
7
|
+
} from "./chunk-NQBS7L2F.js";
|
|
8
|
+
|
|
9
|
+
// src/cli/auth.ts
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import ora from "ora";
|
|
12
|
+
async function login(_providerOrOptions = "github") {
|
|
13
|
+
printRetiredRemotePath("Platform login");
|
|
14
|
+
}
|
|
15
|
+
async function logout() {
|
|
16
|
+
const spinner = ora("Clearing local legacy session...").start();
|
|
17
|
+
try {
|
|
18
|
+
await clearConfig();
|
|
19
|
+
spinner.succeed(chalk.green("Local legacy session cleared"));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
spinner.fail(chalk.red(`Failed to clear local session: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function status() {
|
|
25
|
+
const config = await loadConfig();
|
|
26
|
+
if (!config.accessToken) {
|
|
27
|
+
console.log(chalk.green("Local-only mode active"));
|
|
28
|
+
console.log(chalk.dim(`AI mode: ${formatTier(config.tier ?? "FREE")}`));
|
|
29
|
+
console.log(chalk.dim("Platform login has been retired for current Free/BYOK usage."));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(chalk.yellow("Legacy remote session found locally"));
|
|
33
|
+
console.log();
|
|
34
|
+
if (config.email) {
|
|
35
|
+
console.log(` ${chalk.dim("Email:")} ${config.email}`);
|
|
36
|
+
}
|
|
37
|
+
console.log(` ${chalk.dim("AI mode:")} ${formatTier(config.tier ?? "FREE")}`);
|
|
38
|
+
if (config.userId) {
|
|
39
|
+
console.log(` ${chalk.dim("User:")} ${config.userId}`);
|
|
40
|
+
}
|
|
41
|
+
console.log(chalk.dim("\nRun archon logout to clear old remote tokens. They are not needed for Free/BYOK usage."));
|
|
42
|
+
}
|
|
43
|
+
function formatTier(tier) {
|
|
44
|
+
switch (tier) {
|
|
45
|
+
case "BYOK":
|
|
46
|
+
return chalk.blue("BYOK (your provider keys)");
|
|
47
|
+
case "FREE":
|
|
48
|
+
default:
|
|
49
|
+
return chalk.gray("Local governance only");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
login,
|
|
55
|
+
logout,
|
|
56
|
+
status
|
|
57
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import "./chunk-4VNS5WPM.js";
|
|
2
|
+
|
|
1
3
|
// src/core/supabase/client.ts
|
|
2
4
|
import { createClient } from "@supabase/supabase-js";
|
|
3
5
|
function createAnonSupabaseClient(supabaseUrl, supabaseAnonKey) {
|
|
@@ -15,9 +17,8 @@ function createAuthedSupabaseClient(supabaseUrl, supabaseAnonKey, accessToken) {
|
|
|
15
17
|
global: { headers: { Authorization: `Bearer ${accessToken}` } }
|
|
16
18
|
});
|
|
17
19
|
}
|
|
18
|
-
|
|
19
20
|
export {
|
|
20
21
|
createAnonSupabaseClient,
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
createAuthedSupabaseClient,
|
|
23
|
+
createPkceSupabaseClient
|
|
23
24
|
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
execute
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-LE5EJ6I4.js";
|
|
4
|
+
import "./chunk-BSG5XY3C.js";
|
|
5
5
|
import "./chunk-I3BBA7MB.js";
|
|
6
|
-
import "./chunk-5EVHUDQX.js";
|
|
7
6
|
import "./chunk-IYZN6FPJ.js";
|
|
8
7
|
import "./chunk-D3TVDCJA.js";
|
|
9
8
|
import "./chunk-NIIFUBOE.js";
|
|
9
|
+
import "./chunk-NQBS7L2F.js";
|
|
10
|
+
import "./chunk-5EVHUDQX.js";
|
|
10
11
|
import "./chunk-7C6JELBL.js";
|
|
11
12
|
import "./chunk-TFSHS7EN.js";
|
|
12
13
|
import "./chunk-RDG5BUED.js";
|
|
13
|
-
import "./chunk-GGRW4NTA.js";
|
|
14
14
|
import "./chunk-4VNS5WPM.js";
|
|
15
15
|
export {
|
|
16
16
|
execute
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BANNED_WORDS_AI_WASHING,
|
|
3
|
+
BANNED_WORDS_ALL,
|
|
4
|
+
BANNED_WORDS_GENERIC,
|
|
5
|
+
approxTokenCount,
|
|
6
|
+
createGeoCommand,
|
|
7
|
+
detectSurfaces,
|
|
8
|
+
findBannedWords,
|
|
9
|
+
geoAudit,
|
|
10
|
+
geoClaims,
|
|
11
|
+
geoFaq,
|
|
12
|
+
geoIdentity,
|
|
13
|
+
geoQuickAudit,
|
|
14
|
+
geoSchema,
|
|
15
|
+
geoSurfaceAudit,
|
|
16
|
+
geoWashingAudit,
|
|
17
|
+
splitSentences,
|
|
18
|
+
validateFaqAnswer,
|
|
19
|
+
validateFiftyWordDescription,
|
|
20
|
+
validateSevenWordPhrase,
|
|
21
|
+
wordCount
|
|
22
|
+
} from "./chunk-EF66S6ZQ.js";
|
|
23
|
+
import "./chunk-3ASILTFB.js";
|
|
24
|
+
import "./chunk-D3TVDCJA.js";
|
|
25
|
+
import "./chunk-NIIFUBOE.js";
|
|
26
|
+
import "./chunk-NQBS7L2F.js";
|
|
27
|
+
import "./chunk-7C6JELBL.js";
|
|
28
|
+
import "./chunk-4VNS5WPM.js";
|
|
29
|
+
export {
|
|
30
|
+
BANNED_WORDS_AI_WASHING,
|
|
31
|
+
BANNED_WORDS_ALL,
|
|
32
|
+
BANNED_WORDS_GENERIC,
|
|
33
|
+
approxTokenCount,
|
|
34
|
+
createGeoCommand,
|
|
35
|
+
detectSurfaces,
|
|
36
|
+
findBannedWords,
|
|
37
|
+
geoAudit,
|
|
38
|
+
geoClaims,
|
|
39
|
+
geoFaq,
|
|
40
|
+
geoIdentity,
|
|
41
|
+
geoQuickAudit,
|
|
42
|
+
geoSchema,
|
|
43
|
+
geoSurfaceAudit,
|
|
44
|
+
geoWashingAudit,
|
|
45
|
+
splitSentences,
|
|
46
|
+
validateFaqAnswer,
|
|
47
|
+
validateFiftyWordDescription,
|
|
48
|
+
validateSevenWordPhrase,
|
|
49
|
+
wordCount
|
|
50
|
+
};
|