@structured-vibe-coding/core 0.17.1 → 0.18.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.
Files changed (31) hide show
  1. package/defaults/prices.yaml +9 -0
  2. package/defaults/search.yaml +18 -0
  3. package/dist/{agents-CLTJJVOD.js → agents-AKSUXQHN.js} +18 -7
  4. package/dist/{change-context-W4HDO2IK.js → change-context-REE7UKU7.js} +2 -4
  5. package/dist/chunk-44LQ5BKZ.js +2628 -0
  6. package/dist/{chunk-KYWETNFU.js → chunk-4BRO7BOJ.js} +2 -4
  7. package/dist/chunk-4PIRWYRA.js +1125 -0
  8. package/dist/{chunk-72QJHR53.js → chunk-LHSR7JG2.js} +569 -39
  9. package/dist/{chunk-EPFURATC.js → chunk-O5SP6X5R.js} +89 -0
  10. package/dist/{chunk-BGM6KS64.js → chunk-QGP43XCN.js} +2 -2
  11. package/dist/{chunk-A752UVPF.js → chunk-QHV5KZKX.js} +193 -28
  12. package/dist/{gather-S4A5YR7X.js → gather-ZNV2NAUN.js} +3 -4
  13. package/dist/{greenfield-QQJH3XL3.js → greenfield-I5S5OS2D.js} +5 -6
  14. package/dist/index.d.ts +1034 -40
  15. package/dist/index.js +2927 -988
  16. package/dist/{sources-PF45EUH2.js → sources-3TXUPU6V.js} +2 -3
  17. package/package.json +11 -3
  18. package/vendor/tree-sitter/NOTICE +29 -0
  19. package/vendor/tree-sitter/tree-sitter-javascript.wasm +0 -0
  20. package/vendor/tree-sitter/tree-sitter-python.wasm +0 -0
  21. package/vendor/tree-sitter/tree-sitter-rust.wasm +0 -0
  22. package/vendor/tree-sitter/tree-sitter-tsx.wasm +0 -0
  23. package/vendor/tree-sitter/tree-sitter-typescript.wasm +0 -0
  24. package/dist/chunk-67AUAGNV.js +0 -150
  25. package/dist/chunk-7MJYPJMR.js +0 -51
  26. package/dist/chunk-BVCTVKBD.js +0 -538
  27. package/dist/chunk-WHDG6OTG.js +0 -46
  28. package/dist/chunk-WPAGUBZ5.js +0 -139
  29. package/dist/config-X5VDBVR4.js +0 -16
  30. package/dist/fs-J6DIV6CX.js +0 -28
  31. package/dist/paths-64GA32IZ.js +0 -28
package/dist/index.d.ts CHANGED
@@ -524,6 +524,16 @@ declare const WorkflowSchema: z.ZodObject<{
524
524
  }>;
525
525
  declare const ConfigSchema: z.ZodObject<{
526
526
  version: z.ZodDefault<z.ZodNumber>;
527
+ metrics: z.ZodDefault<z.ZodObject<{
528
+ enabled: z.ZodDefault<z.ZodBoolean>;
529
+ exclude: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
530
+ }, "strip", z.ZodTypeAny, {
531
+ enabled: boolean;
532
+ exclude: string[];
533
+ }, {
534
+ enabled?: boolean | undefined;
535
+ exclude?: string[] | undefined;
536
+ }>>;
527
537
  memory_path: z.ZodDefault<z.ZodString>;
528
538
  changes_path: z.ZodDefault<z.ZodString>;
529
539
  archive_path: z.ZodDefault<z.ZodString>;
@@ -583,6 +593,10 @@ declare const ConfigSchema: z.ZodObject<{
583
593
  }>>;
584
594
  }, "strip", z.ZodTypeAny, {
585
595
  version: number;
596
+ metrics: {
597
+ enabled: boolean;
598
+ exclude: string[];
599
+ };
586
600
  memory_path: string;
587
601
  changes_path: string;
588
602
  archive_path: string;
@@ -608,6 +622,10 @@ declare const ConfigSchema: z.ZodObject<{
608
622
  allowed_workflows?: string[] | undefined;
609
623
  }, {
610
624
  version?: number | undefined;
625
+ metrics?: {
626
+ enabled?: boolean | undefined;
627
+ exclude?: string[] | undefined;
628
+ } | undefined;
611
629
  memory_path?: string | undefined;
612
630
  changes_path?: string | undefined;
613
631
  archive_path?: string | undefined;
@@ -641,6 +659,11 @@ declare const ChangeMetaSchema: z.ZodObject<{
641
659
  status: z.ZodDefault<z.ZodEnum<["in_progress", "blocked", "completed", "abandoned"]>>;
642
660
  stage: z.ZodString;
643
661
  branch: z.ZodOptional<z.ZodString>;
662
+ /** Epic key such as issue-37. Stories in one epic share a dependency graph. */
663
+ epic: z.ZodOptional<z.ZodString>;
664
+ /** Story id such as S-001. */
665
+ story: z.ZodOptional<z.ZodString>;
666
+ depends: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
644
667
  domain: z.ZodOptional<z.ZodString>;
645
668
  flags: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodBoolean, z.ZodString, z.ZodNumber]>>>;
646
669
  overrides: z.ZodDefault<z.ZodObject<{
@@ -913,6 +936,9 @@ declare const ChangeMetaSchema: z.ZodObject<{
913
936
  /** Results from `sdd verify` keyed by stage id */
914
937
  verify_results: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
915
938
  ok: z.ZodBoolean;
939
+ /** pass | fail | not_run (absent in metas written before 0.17.3) */
940
+ status: z.ZodOptional<z.ZodEnum<["pass", "fail", "not_run"]>>;
941
+ head_sha: z.ZodOptional<z.ZodString>;
916
942
  at: z.ZodString;
917
943
  results: z.ZodDefault<z.ZodArray<z.ZodObject<{
918
944
  name: z.ZodString;
@@ -931,9 +957,13 @@ declare const ChangeMetaSchema: z.ZodObject<{
931
957
  name: string;
932
958
  exitCode: number | null;
933
959
  }[];
960
+ status?: "pass" | "fail" | "not_run" | undefined;
961
+ head_sha?: string | undefined;
934
962
  }, {
935
963
  at: string;
936
964
  ok: boolean;
965
+ status?: "pass" | "fail" | "not_run" | undefined;
966
+ head_sha?: string | undefined;
937
967
  results?: {
938
968
  name: string;
939
969
  exitCode: number | null;
@@ -1014,9 +1044,14 @@ declare const ChangeMetaSchema: z.ZodObject<{
1014
1044
  name: string;
1015
1045
  exitCode: number | null;
1016
1046
  }[];
1047
+ status?: "pass" | "fail" | "not_run" | undefined;
1048
+ head_sha?: string | undefined;
1017
1049
  }>;
1018
1050
  updated?: string | undefined;
1019
1051
  branch?: string | undefined;
1052
+ epic?: string | undefined;
1053
+ story?: string | undefined;
1054
+ depends?: string[] | undefined;
1020
1055
  domain?: string | undefined;
1021
1056
  pr?: {
1022
1057
  number?: number | undefined;
@@ -1038,6 +1073,9 @@ declare const ChangeMetaSchema: z.ZodObject<{
1038
1073
  }> | undefined;
1039
1074
  updated?: string | undefined;
1040
1075
  branch?: string | undefined;
1076
+ epic?: string | undefined;
1077
+ story?: string | undefined;
1078
+ depends?: string[] | undefined;
1041
1079
  domain?: string | undefined;
1042
1080
  overrides?: {
1043
1081
  gates?: Record<string, "none" | "soft" | "hard"> | undefined;
@@ -1086,6 +1124,8 @@ declare const ChangeMetaSchema: z.ZodObject<{
1086
1124
  verify_results?: Record<string, {
1087
1125
  at: string;
1088
1126
  ok: boolean;
1127
+ status?: "pass" | "fail" | "not_run" | undefined;
1128
+ head_sha?: string | undefined;
1089
1129
  results?: {
1090
1130
  name: string;
1091
1131
  exitCode: number | null;
@@ -1111,17 +1151,680 @@ declare function configPath(projectRoot: string): string;
1111
1151
  declare function workflowsDir(projectRoot: string): string;
1112
1152
  declare function templatesDir(projectRoot: string): string;
1113
1153
  declare function memoryDir(projectRoot: string, config: Config): string;
1154
+ /** Project-relative memory folder, always with a trailing slash stripped. */
1155
+ declare function memoryPathRel(config: Pick<Config, "memory_path">): string;
1156
+ /** Project-relative changes folder, always with a trailing slash stripped. */
1157
+ declare function changesPathRel(config: Pick<Config, "changes_path">): string;
1158
+ /** Repo-relative archive directory for a completed change. */
1159
+ declare function displayArchivePath(config: Pick<Config, "archive_path">, changeId: string): string;
1160
+ /** Repo-relative change directory shown to humans. Never an absolute machine path. */
1161
+ declare function displayChangePath(config: Pick<Config, "changes_path">, changeId: string): string;
1162
+ /** Paths agents should be told to read, taken from config rather than defaults. */
1163
+ declare function guidancePaths(config: Pick<Config, "memory_path" | "changes_path">): {
1164
+ memory: string;
1165
+ changes: string;
1166
+ constitution: string;
1167
+ memoryIndex: string;
1168
+ };
1114
1169
  declare function changesDir(projectRoot: string, config: Config): string;
1115
1170
  declare function archiveDir(projectRoot: string, config: Config): string;
1116
1171
  declare function domainsDir(projectRoot: string, config: Config): string;
1117
1172
  declare function changePath(projectRoot: string, config: Config, changeId: string): string;
1118
1173
  declare function changeMetaPath(projectRoot: string, config: Config, changeId: string): string;
1119
1174
  declare function activePointerPath(projectRoot: string, config: Config): string;
1175
+ declare function searchConfigPath(projectRoot: string): string;
1176
+ declare function indexDbPath(projectRoot: string): string;
1120
1177
 
1121
1178
  declare function isInitialized(projectRoot: string): Promise<boolean>;
1122
1179
  declare function loadConfig(projectRoot: string): Promise<Config>;
1123
1180
  declare function saveConfig(projectRoot: string, config: Config): Promise<void>;
1124
1181
  declare function defaultConfig(): Config;
1182
+ /** Merge a user's config over current defaults, then validate and strip unsupported keys. */
1183
+ declare function mergeConfigDefaults(existing: unknown): Config;
1184
+
1185
+ type GitHeadRunner = (projectRoot: string) => Promise<string>;
1186
+ declare function getHeadSha(projectRoot: string, runGit?: GitHeadRunner): Promise<string | null>;
1187
+
1188
+ declare const PhaseMetricSchema: z.ZodEffects<z.ZodObject<{
1189
+ phase: z.ZodString;
1190
+ startedAt: z.ZodString;
1191
+ endedAt: z.ZodOptional<z.ZodString>;
1192
+ }, "strip", z.ZodTypeAny, {
1193
+ phase: string;
1194
+ startedAt: string;
1195
+ endedAt?: string | undefined;
1196
+ }, {
1197
+ phase: string;
1198
+ startedAt: string;
1199
+ endedAt?: string | undefined;
1200
+ }>, {
1201
+ phase: string;
1202
+ startedAt: string;
1203
+ endedAt?: string | undefined;
1204
+ }, {
1205
+ phase: string;
1206
+ startedAt: string;
1207
+ endedAt?: string | undefined;
1208
+ }>;
1209
+ declare const TokenUsageMetricSchema: z.ZodObject<{
1210
+ provider: z.ZodEnum<["claude-code", "codex", "grok"]>;
1211
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1212
+ requestId: z.ZodString;
1213
+ phase: z.ZodString;
1214
+ startedAt: z.ZodString;
1215
+ inputTokens: z.ZodNullable<z.ZodNumber>;
1216
+ cacheReadTokens: z.ZodNullable<z.ZodNumber>;
1217
+ cacheWriteTokens: z.ZodNullable<z.ZodNumber>;
1218
+ outputTokens: z.ZodNullable<z.ZodNumber>;
1219
+ measured: z.ZodLiteral<true>;
1220
+ }, "strip", z.ZodTypeAny, {
1221
+ phase: string;
1222
+ startedAt: string;
1223
+ provider: "claude-code" | "codex" | "grok";
1224
+ requestId: string;
1225
+ inputTokens: number | null;
1226
+ cacheReadTokens: number | null;
1227
+ cacheWriteTokens: number | null;
1228
+ outputTokens: number | null;
1229
+ measured: true;
1230
+ model?: string | null | undefined;
1231
+ }, {
1232
+ phase: string;
1233
+ startedAt: string;
1234
+ provider: "claude-code" | "codex" | "grok";
1235
+ requestId: string;
1236
+ inputTokens: number | null;
1237
+ cacheReadTokens: number | null;
1238
+ cacheWriteTokens: number | null;
1239
+ outputTokens: number | null;
1240
+ measured: true;
1241
+ model?: string | null | undefined;
1242
+ }>;
1243
+ declare const ChangeMetricsSchema: z.ZodObject<{
1244
+ version: z.ZodLiteral<1>;
1245
+ phases: z.ZodArray<z.ZodEffects<z.ZodObject<{
1246
+ phase: z.ZodString;
1247
+ startedAt: z.ZodString;
1248
+ endedAt: z.ZodOptional<z.ZodString>;
1249
+ }, "strip", z.ZodTypeAny, {
1250
+ phase: string;
1251
+ startedAt: string;
1252
+ endedAt?: string | undefined;
1253
+ }, {
1254
+ phase: string;
1255
+ startedAt: string;
1256
+ endedAt?: string | undefined;
1257
+ }>, {
1258
+ phase: string;
1259
+ startedAt: string;
1260
+ endedAt?: string | undefined;
1261
+ }, {
1262
+ phase: string;
1263
+ startedAt: string;
1264
+ endedAt?: string | undefined;
1265
+ }>, "many">;
1266
+ requests: z.ZodArray<z.ZodObject<{
1267
+ provider: z.ZodEnum<["claude-code", "codex", "grok"]>;
1268
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1269
+ requestId: z.ZodString;
1270
+ phase: z.ZodString;
1271
+ startedAt: z.ZodString;
1272
+ inputTokens: z.ZodNullable<z.ZodNumber>;
1273
+ cacheReadTokens: z.ZodNullable<z.ZodNumber>;
1274
+ cacheWriteTokens: z.ZodNullable<z.ZodNumber>;
1275
+ outputTokens: z.ZodNullable<z.ZodNumber>;
1276
+ measured: z.ZodLiteral<true>;
1277
+ }, "strip", z.ZodTypeAny, {
1278
+ phase: string;
1279
+ startedAt: string;
1280
+ provider: "claude-code" | "codex" | "grok";
1281
+ requestId: string;
1282
+ inputTokens: number | null;
1283
+ cacheReadTokens: number | null;
1284
+ cacheWriteTokens: number | null;
1285
+ outputTokens: number | null;
1286
+ measured: true;
1287
+ model?: string | null | undefined;
1288
+ }, {
1289
+ phase: string;
1290
+ startedAt: string;
1291
+ provider: "claude-code" | "codex" | "grok";
1292
+ requestId: string;
1293
+ inputTokens: number | null;
1294
+ cacheReadTokens: number | null;
1295
+ cacheWriteTokens: number | null;
1296
+ outputTokens: number | null;
1297
+ measured: true;
1298
+ model?: string | null | undefined;
1299
+ }>, "many">;
1300
+ }, "strip", z.ZodTypeAny, {
1301
+ version: 1;
1302
+ phases: {
1303
+ phase: string;
1304
+ startedAt: string;
1305
+ endedAt?: string | undefined;
1306
+ }[];
1307
+ requests: {
1308
+ phase: string;
1309
+ startedAt: string;
1310
+ provider: "claude-code" | "codex" | "grok";
1311
+ requestId: string;
1312
+ inputTokens: number | null;
1313
+ cacheReadTokens: number | null;
1314
+ cacheWriteTokens: number | null;
1315
+ outputTokens: number | null;
1316
+ measured: true;
1317
+ model?: string | null | undefined;
1318
+ }[];
1319
+ }, {
1320
+ version: 1;
1321
+ phases: {
1322
+ phase: string;
1323
+ startedAt: string;
1324
+ endedAt?: string | undefined;
1325
+ }[];
1326
+ requests: {
1327
+ phase: string;
1328
+ startedAt: string;
1329
+ provider: "claude-code" | "codex" | "grok";
1330
+ requestId: string;
1331
+ inputTokens: number | null;
1332
+ cacheReadTokens: number | null;
1333
+ cacheWriteTokens: number | null;
1334
+ outputTokens: number | null;
1335
+ measured: true;
1336
+ model?: string | null | undefined;
1337
+ }[];
1338
+ }>;
1339
+ type PhaseMetric = z.infer<typeof PhaseMetricSchema>;
1340
+ type TokenUsageMetric = z.infer<typeof TokenUsageMetricSchema>;
1341
+ type ChangeMetrics = z.infer<typeof ChangeMetricsSchema>;
1342
+ interface MetricsImportResult {
1343
+ imported: number;
1344
+ duplicates: number;
1345
+ ignored: number;
1346
+ unmatched: number;
1347
+ providers: string[];
1348
+ incomplete: boolean;
1349
+ }
1350
+ declare function emptyChangeMetrics(): ChangeMetrics;
1351
+ declare function readChangeMetrics(projectRoot: string, config: Config, changeId: string): Promise<ChangeMetrics>;
1352
+ declare function startPhase(projectRoot: string, config: Config, changeId: string, phase: string, startedAt?: string): Promise<void>;
1353
+ declare function transitionPhase(projectRoot: string, config: Config, changeId: string, fromPhase: string, toPhase: string | null, at?: string, fromStartedAt?: string): Promise<void>;
1354
+ /**
1355
+ * Refuse an in-repo session log under metrics.exclude before the file is opened.
1356
+ * Logs outside the project root are not excluded. Invalid prefixes throw first.
1357
+ */
1358
+ declare function assertSessionLogAllowed(projectRoot: string, prefixes: readonly string[], sessionLogPath: string): void;
1359
+ declare function importSessionMetrics(projectRoot: string, config: Config, changeId: string, sessionLogPath: string): Promise<MetricsImportResult>;
1360
+
1361
+ declare const PriceCardSchema: z.ZodObject<{
1362
+ input_per_million_usd: z.ZodNumber;
1363
+ cache_read_per_million_usd: z.ZodNumber;
1364
+ cache_write_per_million_usd: z.ZodNumber;
1365
+ output_per_million_usd: z.ZodNumber;
1366
+ }, "strip", z.ZodTypeAny, {
1367
+ input_per_million_usd: number;
1368
+ cache_read_per_million_usd: number;
1369
+ cache_write_per_million_usd: number;
1370
+ output_per_million_usd: number;
1371
+ }, {
1372
+ input_per_million_usd: number;
1373
+ cache_read_per_million_usd: number;
1374
+ cache_write_per_million_usd: number;
1375
+ output_per_million_usd: number;
1376
+ }>;
1377
+ declare const PricesSchema: z.ZodObject<{
1378
+ usd_to_inr: z.ZodDefault<z.ZodNumber>;
1379
+ models: z.ZodObject<{
1380
+ default: z.ZodObject<{
1381
+ input_per_million_usd: z.ZodNumber;
1382
+ cache_read_per_million_usd: z.ZodNumber;
1383
+ cache_write_per_million_usd: z.ZodNumber;
1384
+ output_per_million_usd: z.ZodNumber;
1385
+ }, "strip", z.ZodTypeAny, {
1386
+ input_per_million_usd: number;
1387
+ cache_read_per_million_usd: number;
1388
+ cache_write_per_million_usd: number;
1389
+ output_per_million_usd: number;
1390
+ }, {
1391
+ input_per_million_usd: number;
1392
+ cache_read_per_million_usd: number;
1393
+ cache_write_per_million_usd: number;
1394
+ output_per_million_usd: number;
1395
+ }>;
1396
+ }, "strip", z.ZodObject<{
1397
+ input_per_million_usd: z.ZodNumber;
1398
+ cache_read_per_million_usd: z.ZodNumber;
1399
+ cache_write_per_million_usd: z.ZodNumber;
1400
+ output_per_million_usd: z.ZodNumber;
1401
+ }, "strip", z.ZodTypeAny, {
1402
+ input_per_million_usd: number;
1403
+ cache_read_per_million_usd: number;
1404
+ cache_write_per_million_usd: number;
1405
+ output_per_million_usd: number;
1406
+ }, {
1407
+ input_per_million_usd: number;
1408
+ cache_read_per_million_usd: number;
1409
+ cache_write_per_million_usd: number;
1410
+ output_per_million_usd: number;
1411
+ }>, z.objectOutputType<{
1412
+ default: z.ZodObject<{
1413
+ input_per_million_usd: z.ZodNumber;
1414
+ cache_read_per_million_usd: z.ZodNumber;
1415
+ cache_write_per_million_usd: z.ZodNumber;
1416
+ output_per_million_usd: z.ZodNumber;
1417
+ }, "strip", z.ZodTypeAny, {
1418
+ input_per_million_usd: number;
1419
+ cache_read_per_million_usd: number;
1420
+ cache_write_per_million_usd: number;
1421
+ output_per_million_usd: number;
1422
+ }, {
1423
+ input_per_million_usd: number;
1424
+ cache_read_per_million_usd: number;
1425
+ cache_write_per_million_usd: number;
1426
+ output_per_million_usd: number;
1427
+ }>;
1428
+ }, z.ZodObject<{
1429
+ input_per_million_usd: z.ZodNumber;
1430
+ cache_read_per_million_usd: z.ZodNumber;
1431
+ cache_write_per_million_usd: z.ZodNumber;
1432
+ output_per_million_usd: z.ZodNumber;
1433
+ }, "strip", z.ZodTypeAny, {
1434
+ input_per_million_usd: number;
1435
+ cache_read_per_million_usd: number;
1436
+ cache_write_per_million_usd: number;
1437
+ output_per_million_usd: number;
1438
+ }, {
1439
+ input_per_million_usd: number;
1440
+ cache_read_per_million_usd: number;
1441
+ cache_write_per_million_usd: number;
1442
+ output_per_million_usd: number;
1443
+ }>, "strip">, z.objectInputType<{
1444
+ default: z.ZodObject<{
1445
+ input_per_million_usd: z.ZodNumber;
1446
+ cache_read_per_million_usd: z.ZodNumber;
1447
+ cache_write_per_million_usd: z.ZodNumber;
1448
+ output_per_million_usd: z.ZodNumber;
1449
+ }, "strip", z.ZodTypeAny, {
1450
+ input_per_million_usd: number;
1451
+ cache_read_per_million_usd: number;
1452
+ cache_write_per_million_usd: number;
1453
+ output_per_million_usd: number;
1454
+ }, {
1455
+ input_per_million_usd: number;
1456
+ cache_read_per_million_usd: number;
1457
+ cache_write_per_million_usd: number;
1458
+ output_per_million_usd: number;
1459
+ }>;
1460
+ }, z.ZodObject<{
1461
+ input_per_million_usd: z.ZodNumber;
1462
+ cache_read_per_million_usd: z.ZodNumber;
1463
+ cache_write_per_million_usd: z.ZodNumber;
1464
+ output_per_million_usd: z.ZodNumber;
1465
+ }, "strip", z.ZodTypeAny, {
1466
+ input_per_million_usd: number;
1467
+ cache_read_per_million_usd: number;
1468
+ cache_write_per_million_usd: number;
1469
+ output_per_million_usd: number;
1470
+ }, {
1471
+ input_per_million_usd: number;
1472
+ cache_read_per_million_usd: number;
1473
+ cache_write_per_million_usd: number;
1474
+ output_per_million_usd: number;
1475
+ }>, "strip">>;
1476
+ }, "strip", z.ZodTypeAny, {
1477
+ usd_to_inr: number;
1478
+ models: {
1479
+ default: {
1480
+ input_per_million_usd: number;
1481
+ cache_read_per_million_usd: number;
1482
+ cache_write_per_million_usd: number;
1483
+ output_per_million_usd: number;
1484
+ };
1485
+ } & {
1486
+ [k: string]: {
1487
+ input_per_million_usd: number;
1488
+ cache_read_per_million_usd: number;
1489
+ cache_write_per_million_usd: number;
1490
+ output_per_million_usd: number;
1491
+ };
1492
+ };
1493
+ }, {
1494
+ models: {
1495
+ default: {
1496
+ input_per_million_usd: number;
1497
+ cache_read_per_million_usd: number;
1498
+ cache_write_per_million_usd: number;
1499
+ output_per_million_usd: number;
1500
+ };
1501
+ } & {
1502
+ [k: string]: {
1503
+ input_per_million_usd: number;
1504
+ cache_read_per_million_usd: number;
1505
+ cache_write_per_million_usd: number;
1506
+ output_per_million_usd: number;
1507
+ };
1508
+ };
1509
+ usd_to_inr?: number | undefined;
1510
+ }>;
1511
+ type PriceCard = z.infer<typeof PriceCardSchema>;
1512
+ type Prices = z.infer<typeof PricesSchema>;
1513
+ interface TokenCounts {
1514
+ input: number | null;
1515
+ cacheRead: number | null;
1516
+ cacheWrite: number | null;
1517
+ output: number | null;
1518
+ }
1519
+ interface PhaseTimingRow {
1520
+ phase: string;
1521
+ startedAt: string;
1522
+ endedAt?: string;
1523
+ activeMs: number;
1524
+ open: boolean;
1525
+ }
1526
+ interface PhaseTiming {
1527
+ activeMs: number;
1528
+ waitMs: number;
1529
+ totalMs: number;
1530
+ phases: PhaseTimingRow[];
1531
+ }
1532
+ interface ChangePhaseOrder {
1533
+ id: string;
1534
+ /** First phase start. Null when a valid file has no phases. Ignored when invalid. */
1535
+ firstStartedAt: string | null;
1536
+ invalid: boolean;
1537
+ }
1538
+ interface RenderChangeReportInput {
1539
+ changeId: string;
1540
+ metrics: ChangeMetrics;
1541
+ prices: Prices | null;
1542
+ /** Unicode code points in `.sdd/handoff.md`. Null means that file is missing. */
1543
+ handoffCodePoints: number | null;
1544
+ now: Date;
1545
+ }
1546
+ /** `Hh Mm Ss` from whole seconds. Negative and non-finite inputs are `0h 0m 0s`. */
1547
+ declare function formatDuration(ms: number): string;
1548
+ /** Active time per stored visit, plus human wait as the gaps between visits. */
1549
+ declare function phaseTiming(phases: readonly PhaseMetric[], now: Date): PhaseTiming;
1550
+ /**
1551
+ * Sum category USD from numeric token counts only, then round once.
1552
+ * INR multiplies the unrounded USD sum by `usdToInr`, then rounds once.
1553
+ */
1554
+ declare function costFor(counts: TokenCounts, card: PriceCard, usdToInr: number): {
1555
+ usd: string;
1556
+ inr: string;
1557
+ };
1558
+ /** Parsed prices, null when `.sdd/prices.yaml` is missing, or a throw when it is invalid. */
1559
+ declare function loadPrices(projectRoot: string): Promise<Prices | null>;
1560
+ /** Plain-text one-change report. Does not read or write the filesystem. */
1561
+ declare function renderChangeReport(input: RenderChangeReportInput): string;
1562
+ /** Valid files with a first start, then empty phases, then invalid files. Tie-break by id. */
1563
+ declare function compareChangesByFirstPhase(left: ChangePhaseOrder, right: ChangePhaseOrder): number;
1564
+ declare function readHandoffCodePoints(projectRoot: string): Promise<number | null>;
1565
+ /** One-change report. Reads metrics and, when unmeasured, the handoff. Writes nothing. */
1566
+ declare function reportChange(input: {
1567
+ projectRoot: string;
1568
+ config: Config;
1569
+ changeId: string;
1570
+ prices: Prices | null;
1571
+ now: Date;
1572
+ }): Promise<string>;
1573
+ /** Every direct child that has metrics.json, or the empty-result sentence. Writes nothing. */
1574
+ declare function reportAllChanges(projectRoot: string, config: Config, prices: Prices | null, now: Date): Promise<string>;
1575
+
1576
+ declare function countTokens(text: string): number;
1577
+ /** FTS5 tokens. A token character is 0-9, A-Z, a-z, `_`, or a code point above 127. */
1578
+ declare function ftsTokens(query: string): string[];
1579
+
1580
+ declare class SearchConfigError extends Error {
1581
+ constructor();
1582
+ }
1583
+ declare const SearchConfigSchema: z.ZodObject<{
1584
+ version: z.ZodDefault<z.ZodLiteral<1>>;
1585
+ provider: z.ZodDefault<z.ZodString>;
1586
+ k: z.ZodDefault<z.ZodNumber>;
1587
+ embeddings: z.ZodDefault<z.ZodBoolean>;
1588
+ budgets: z.ZodDefault<z.ZodObject<{
1589
+ default: z.ZodDefault<z.ZodNumber>;
1590
+ }, "strip", z.ZodNumber, z.objectOutputType<{
1591
+ default: z.ZodDefault<z.ZodNumber>;
1592
+ }, z.ZodNumber, "strip">, z.objectInputType<{
1593
+ default: z.ZodDefault<z.ZodNumber>;
1594
+ }, z.ZodNumber, "strip">>>;
1595
+ exclude: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1596
+ }, "strip", z.ZodTypeAny, {
1597
+ version: 1;
1598
+ exclude: string[];
1599
+ provider: string;
1600
+ k: number;
1601
+ embeddings: boolean;
1602
+ budgets: {
1603
+ default: number;
1604
+ } & {
1605
+ [k: string]: number;
1606
+ };
1607
+ }, {
1608
+ version?: 1 | undefined;
1609
+ exclude?: string[] | undefined;
1610
+ provider?: string | undefined;
1611
+ k?: number | undefined;
1612
+ embeddings?: boolean | undefined;
1613
+ budgets?: z.objectInputType<{
1614
+ default: z.ZodDefault<z.ZodNumber>;
1615
+ }, z.ZodNumber, "strip"> | undefined;
1616
+ }>;
1617
+ type SearchConfig = z.infer<typeof SearchConfigSchema>;
1618
+ declare function budgetForStage(config: SearchConfig, stage: string | undefined): number;
1619
+ declare function loadSearchConfig(projectRoot: string): Promise<SearchConfig>;
1620
+
1621
+ type SearchScope = "code" | "specs" | "memory";
1622
+ interface SearchQuery {
1623
+ scope: SearchScope;
1624
+ k: number;
1625
+ budget: number;
1626
+ /** Header text counted against the budget. Empty for context and handoff. */
1627
+ preamble?: string;
1628
+ }
1629
+ interface SearchHit {
1630
+ scope: SearchScope;
1631
+ path: string;
1632
+ startLine: number;
1633
+ endLine: number;
1634
+ symbol: string;
1635
+ /**
1636
+ * Keyword hits store raw SQLite bm25() (more negative is better).
1637
+ * Hybrid hits store the RRF score (higher is better).
1638
+ */
1639
+ score: number;
1640
+ form: "full" | "signature" | "summary";
1641
+ text: string;
1642
+ signature: string;
1643
+ body: string;
1644
+ language: string;
1645
+ }
1646
+ interface SearchResult {
1647
+ provider: "builtin";
1648
+ warning?: string;
1649
+ query: string;
1650
+ scope: SearchScope;
1651
+ budget: number;
1652
+ usedTokens: number;
1653
+ hits: SearchHit[];
1654
+ text: string;
1655
+ }
1656
+ interface IndexStats {
1657
+ provider: "builtin";
1658
+ files: number;
1659
+ chunks: number;
1660
+ lastIndexFilesConsidered: number;
1661
+ lastIndexFilesReindexed: number;
1662
+ lastIndexChunksReindexed: number;
1663
+ lastIndexChunksEmbedded: number;
1664
+ indexedCommit: string | null;
1665
+ }
1666
+ interface SearchProvider {
1667
+ readonly id: string;
1668
+ index(changed?: readonly string[]): Promise<IndexStats>;
1669
+ search(query: string, options: SearchQuery): Promise<SearchResult>;
1670
+ stats(): Promise<IndexStats>;
1671
+ }
1672
+ interface RawHit {
1673
+ scope: SearchScope;
1674
+ path: string;
1675
+ startLine: number;
1676
+ endLine: number;
1677
+ symbol: string;
1678
+ score: number;
1679
+ signature: string;
1680
+ body: string;
1681
+ language: string;
1682
+ /** Not printed. Keyword rows are bm25. Fused rows are rrf. */
1683
+ rankedBy?: "bm25" | "rrf";
1684
+ /** Pack-time extract. Absent for code and for the active change. */
1685
+ summary?: string;
1686
+ }
1687
+
1688
+ declare function searchPreamble(query: string, scope: string, budget: number, hybrid?: boolean): string;
1689
+ declare function renderBlock(hit: RawHit, form: "full" | "signature" | "summary"): string;
1690
+ declare function packHits(input: {
1691
+ preamble: string;
1692
+ hits: readonly RawHit[];
1693
+ budget: number;
1694
+ }): {
1695
+ text: string;
1696
+ usedTokens: number;
1697
+ hits: SearchHit[];
1698
+ };
1699
+
1700
+ declare function isHardDenied(rel: string): boolean;
1701
+ /**
1702
+ * Directories the walker does not open. A directory whose basename merely
1703
+ * contains "secret" (the fixture `secret-nest`) is not pruned: `isSecretPath`
1704
+ * applies to the file itself, and `packages/secret-nest/shown.ts` is allowed.
1705
+ */
1706
+ declare function isPrunedDir(rel: string): boolean;
1707
+ declare function loadExcluder(projectRoot: string, exclude: readonly string[]): Promise<(rel: string) => boolean>;
1708
+
1709
+ interface MarkdownChunk {
1710
+ symbol: string;
1711
+ startLine: number;
1712
+ endLine: number;
1713
+ signature: string;
1714
+ body: string;
1715
+ }
1716
+ declare function chunkMarkdown(text: string): MarkdownChunk[];
1717
+
1718
+ declare const SUMMARY_TOKEN_CAP = 80;
1719
+ /** Deterministic extract. Same signature and body always return the same string. */
1720
+ declare function extractiveSummary(signature: string, body: string): string;
1721
+
1722
+ declare function resolveActiveDirectory(projectRoot: string, config: Config): Promise<string>;
1723
+
1724
+ interface CodeChunk {
1725
+ symbol: string;
1726
+ startLine: number;
1727
+ endLine: number;
1728
+ signature: string;
1729
+ body: string;
1730
+ language: string;
1731
+ }
1732
+ declare function chunkCode(text: string, ext: string): Promise<CodeChunk[] | null>;
1733
+
1734
+ declare const EMBEDDING_MODEL = "BAAI/bge-small-en-v1.5";
1735
+ declare const EMBEDDINGS_UNAVAILABLE = "Embeddings are unavailable. Using keyword search.";
1736
+ interface Embedder {
1737
+ /** One L2-normalized vector per text, same order. Text is the raw chunk body. */
1738
+ embedPassages(texts: readonly string[]): Promise<Float32Array[]>;
1739
+ /** One L2-normalized vector for the raw user query. */
1740
+ embedQuery(text: string): Promise<Float32Array>;
1741
+ }
1742
+ interface SearchRuntime {
1743
+ embedder?: Embedder;
1744
+ /** Called instead of fastembed. A throw is an embedder failure. */
1745
+ embedderFactory?: () => Promise<Embedder>;
1746
+ }
1747
+ type EmbedFailure = "none" | "load" | "query";
1748
+ interface FastembedModel {
1749
+ passageEmbed(texts: readonly string[], batchSize: number): AsyncIterable<ArrayLike<number>[]>;
1750
+ queryEmbed(text: string): Promise<ArrayLike<number>>;
1751
+ }
1752
+ type FastembedInit = (options: {
1753
+ model: unknown;
1754
+ executionProviders: unknown[];
1755
+ maxLength: number;
1756
+ showDownloadProgress: boolean;
1757
+ cacheDir: string;
1758
+ }) => Promise<FastembedModel>;
1759
+ interface FastembedHooks {
1760
+ init?: FastembedInit;
1761
+ }
1762
+ /** Incremented only when the embeddings-on path evaluates `import("fastembed")`. */
1763
+ declare let fastembedImportCount: number;
1764
+ /** Fastembed adapter. One successful session per cache directory per process. */
1765
+ declare function createFastembedEmbedder(projectRoot: string, hooks?: FastembedHooks): Promise<Embedder>;
1766
+ /** Embeddings off returns null and does not import fastembed. */
1767
+ declare function resolveEmbedder(projectRoot: string, embeddings: boolean, runtime?: SearchRuntime): Promise<Embedder | null>;
1768
+ declare function embedSearchQuery(embedder: Embedder | null, embeddings: boolean, query: string): Promise<{
1769
+ queryVec: Float32Array | null;
1770
+ failure: EmbedFailure;
1771
+ }>;
1772
+
1773
+ interface RankSession {
1774
+ embeddings: boolean;
1775
+ queryVec: Float32Array | null;
1776
+ failure: EmbedFailure;
1777
+ }
1778
+ declare function scopeForPath(rel: string, config: Config): SearchScope | null;
1779
+ declare function createBuiltinProvider(projectRoot: string, config: Config, runtime?: SearchRuntime): SearchProvider;
1780
+ declare function keywordHits(projectRoot: string, query: string, scope: SearchScope, k: number): Promise<RawHit[]>;
1781
+ declare function listScopeHits(projectRoot: string, scope: SearchScope): Promise<RawHit[]>;
1782
+ declare function rankScope(projectRoot: string, query: string, scope: SearchScope, k: number, session: RankSession): Promise<{
1783
+ hits: RawHit[];
1784
+ warning: boolean;
1785
+ hybrid: boolean;
1786
+ }>;
1787
+
1788
+ declare const RRF_K = 60;
1789
+ declare function rrf(rank: number | undefined): number;
1790
+ interface RankInput {
1791
+ id: string;
1792
+ path: string;
1793
+ startLine: number;
1794
+ symbol: string;
1795
+ keywordRank?: number;
1796
+ vectorRank?: number;
1797
+ }
1798
+ /** Pure fusion. Higher score first, then path, start line, and symbol. */
1799
+ declare function fuseByRank(entries: readonly RankInput[]): {
1800
+ id: string;
1801
+ score: number;
1802
+ }[];
1803
+ /** Union of the two source lists. Does not cut the result to k. */
1804
+ declare function fuseHits(keyword: readonly RawHit[], vector: readonly RawHit[]): RawHit[];
1805
+ /**
1806
+ * All-bm25 keeps the S1 sort. Any rrf hit is emitted first by RRF descending,
1807
+ * then bm25 hits by BM25 ascending. The two scores are never compared.
1808
+ */
1809
+ declare function mergeRankedHits(hits: readonly RawHit[]): RawHit[];
1810
+
1811
+ declare function registerSearchProvider(provider: SearchProvider): void;
1812
+ declare function clearRegisteredSearchProviders(): void;
1813
+ declare function fallbackWarning(name: string): string;
1814
+ declare function resolveSearchProvider(projectRoot: string, config: Config, search: SearchConfig, runtime?: SearchRuntime): SearchProvider;
1815
+ declare function buildRetrievedInner(projectRoot: string, config: Config, title: string, stage: string | undefined, budget: number | undefined, runtime?: SearchRuntime, activeChange?: string): Promise<string>;
1816
+ declare function executeSearch(projectRoot: string, config: Config, query: string, scope: SearchScope, budget: number | undefined): Promise<SearchResult>;
1817
+
1818
+ interface SyncChangeResult {
1819
+ changeId: string;
1820
+ headSha: string;
1821
+ updatedResults: number;
1822
+ reportUpdated: boolean;
1823
+ reportPreserved: boolean;
1824
+ }
1825
+ declare function syncChangeHead(projectRoot: string, config: Config, changeId: string, opts?: {
1826
+ headSha?: string | null;
1827
+ }): Promise<SyncChangeResult>;
1125
1828
 
1126
1829
  declare function listWorkflowNames(projectRoot: string): Promise<string[]>;
1127
1830
  declare function loadWorkflow(projectRoot: string, name: string): Promise<Workflow>;
@@ -1154,7 +1857,10 @@ declare function recommendWorkflow(projectRoot: string, title: string, config: C
1154
1857
 
1155
1858
  interface ChangeContext {
1156
1859
  id: string;
1860
+ /** Absolute directory used for file reads and writes. */
1157
1861
  path: string;
1862
+ /** Repo-relative directory for status, handoff, and active-context text. */
1863
+ displayPath: string;
1158
1864
  meta: ChangeMeta;
1159
1865
  workflow: Workflow;
1160
1866
  stages: Stage[];
@@ -1188,13 +1894,13 @@ declare function fallbackIncompleteStageId(ctx: ChangeContext): Promise<string |
1188
1894
  declare function approveGate(projectRoot: string, config: Config, changeId: string, stageId: string | undefined, note?: string, status?: "approved" | "waived" | "failed"): Promise<ChangeContext>;
1189
1895
 
1190
1896
  declare function formatStatus(ctx: ChangeContext): string;
1191
- declare function buildAgentPrompt(ctx: ChangeContext, config: Config, projectRoot: string): Promise<string>;
1897
+ declare function buildAgentPrompt(ctx: ChangeContext, config: Config, projectRoot: string, budget?: number, runtime?: SearchRuntime): Promise<string>;
1192
1898
 
1193
1899
  /**
1194
1900
  * Artifact content quality — existence alone is not "stage complete"
1195
1901
  * (templates are materialized on stage entry and would otherwise auto-pass).
1196
1902
  */
1197
- /** Strip comments/headings/empty bullets; require real prose. */
1903
+ /** Strip comments/headings/empty bullets/instructional template prose; require real prose. */
1198
1904
  declare function isSubstantiveArtifactContent(content: string): boolean;
1199
1905
 
1200
1906
  interface CreateChangeInput {
@@ -1205,6 +1911,9 @@ interface CreateChangeInput {
1205
1911
  domain?: string;
1206
1912
  flags?: Record<string, boolean | string | number>;
1207
1913
  branch?: string;
1914
+ epic?: string;
1915
+ story?: string;
1916
+ depends?: string[];
1208
1917
  }
1209
1918
  interface AdvanceResult {
1210
1919
  ctx: ChangeContext;
@@ -1226,6 +1935,76 @@ declare function completeChange(projectRoot: string, config: Config, changeId: s
1226
1935
  promoted?: string[];
1227
1936
  }>;
1228
1937
 
1938
+ /**
1939
+ * Typed, user-facing errors for sdd core.
1940
+ * CLI maps these to exit codes and optional hints.
1941
+ */
1942
+ declare class SddError extends Error {
1943
+ readonly code: string;
1944
+ readonly hint?: string;
1945
+ readonly exitCode: number;
1946
+ constructor(message: string, options?: {
1947
+ code?: string;
1948
+ hint?: string;
1949
+ exitCode?: number;
1950
+ cause?: unknown;
1951
+ });
1952
+ }
1953
+ declare function isSddError(err: unknown): err is SddError;
1954
+ /** Normalize unknown throws into Error for logging. */
1955
+ declare function errorMessage(err: unknown): string;
1956
+
1957
+ /**
1958
+ * Markers for files sdd generates outside its own state (AGENTS.md, host agent
1959
+ * stubs, protocol). The marker carries a sha256 of the generated body, so sdd
1960
+ * can tell three cases apart:
1961
+ *
1962
+ * - `unmodified`: sdd wrote it and nobody changed it. Safe to regenerate or remove.
1963
+ * - `edited`: sdd wrote it, then someone edited it. Never overwrite or delete.
1964
+ * - `not-generated`: no marker (a user's own file, another tool's, or an old sdd
1965
+ * version's). Never overwrite or delete.
1966
+ */
1967
+ type GeneratedState = "unmodified" | "edited" | "not-generated";
1968
+ /** Line endings are normalized (CRLF → LF) so a Windows/autocrlf checkout is not "edited". */
1969
+ declare function contentHash(body: string): string;
1970
+ /** Insert the marker after YAML front matter (agent hosts parse it) or at the top. */
1971
+ declare function markGenerated(body: string): string;
1972
+ declare function generatedState(content: string): GeneratedState;
1973
+ /**
1974
+ * Why a file was left alone:
1975
+ * - `not-generated` / `edited`: see {@link GeneratedState}
1976
+ * - `symlink`: a symbolic link (or a path through one); sdd never follows, writes
1977
+ * through, or deletes through links
1978
+ * - `unreadable`: could not be read, so sdd cannot prove it generated it
1979
+ */
1980
+ type KeptReason = "not-generated" | "edited" | "symlink" | "unreadable";
1981
+ interface KeptFile {
1982
+ /** Project-relative path */
1983
+ path: string;
1984
+ reason: KeptReason;
1985
+ }
1986
+ declare const GeneratedManifestSchema: z.ZodObject<{
1987
+ version: z.ZodLiteral<1>;
1988
+ files: z.ZodRecord<z.ZodString, z.ZodString>;
1989
+ }, "strict", z.ZodTypeAny, {
1990
+ version: 1;
1991
+ files: Record<string, string>;
1992
+ }, {
1993
+ version: 1;
1994
+ files: Record<string, string>;
1995
+ }>;
1996
+ type GeneratedManifest = z.infer<typeof GeneratedManifestSchema>;
1997
+ interface ReconcileGeneratedResult {
1998
+ created: string[];
1999
+ refreshed: string[];
2000
+ kept: KeptFile[];
2001
+ changed: boolean;
2002
+ }
2003
+ declare function loadGeneratedManifest(path: string): Promise<GeneratedManifest>;
2004
+ declare function saveGeneratedManifest(path: string, manifest: GeneratedManifest): Promise<void>;
2005
+ declare function reconcileGeneratedTree(projectRoot: string, sourceDir: string, destinationDir: string, destinationRelative: string, manifest: GeneratedManifest, force: boolean): Promise<ReconcileGeneratedResult>;
2006
+ declare function describeKept(k: KeptFile): string;
2007
+
1229
2008
  /**
1230
2009
  * AI coding agents (not IDEs).
1231
2010
  * Speckit-style: one integration at a time; public keys: `copilot` | `claude` | `grok` | `ollama` | `kilo`.
@@ -1269,10 +2048,36 @@ declare function optionForTarget(target: AgentTarget): AgentTargetOption;
1269
2048
  * Never includes shared SDD dirs (memory, changes, .sdd) or whole .github (workflows stay).
1270
2049
  */
1271
2050
  declare function agentHostPaths(target: AgentTarget): string[];
2051
+ interface RemoveAgentHostsResult {
2052
+ /** Project-relative files and directories sdd removed */
2053
+ removed: string[];
2054
+ /** Files left in place because sdd did not generate them, they were edited, or are links */
2055
+ kept: KeptFile[];
2056
+ }
2057
+ /** Turn a raw fs error (EACCES, EISDIR, …) into a sentence naming the path. */
2058
+ declare function describeFsError(err: unknown, action: string, rel: string): string;
2059
+ /** Thrown before anything is written when sdd cannot safely install agent files. */
2060
+ declare class AgentInstallPreflightError extends SddError {
2061
+ readonly problems: string[];
2062
+ constructor(problems: string[]);
2063
+ }
2064
+ /** Files sdd would remove from other hosts' folders, and what it leaves alone. */
2065
+ interface RemovalPlan {
2066
+ remove: string[];
2067
+ kept: KeptFile[];
2068
+ }
1272
2069
  /**
1273
- * Remove agent files for hosts other than `keep` (and legacy IntelliJ notes).
2070
+ * Remove agent files for hosts other than `keep`, but only files sdd generated
2071
+ * and nobody edited since (marker + content hash). User files, edited files,
2072
+ * symlinks and other tools' files in those folders are kept and reported.
2073
+ * Never follows symlinks. Only folders emptied by this removal are pruned.
1274
2074
  * Does not touch .sdd/, memory/, changes/, or non-agent .github content.
1275
2075
  */
2076
+ declare function removeOtherAgentHostsDetailed(projectRoot: string, keep: AgentTarget): Promise<RemoveAgentHostsResult>;
2077
+ /**
2078
+ * Remove sdd-generated, unedited agent files for hosts other than `keep`.
2079
+ * Returns the removed paths. See {@link removeOtherAgentHostsDetailed} for kept files.
2080
+ */
1276
2081
  declare function removeOtherAgentHosts(projectRoot: string, keep: AgentTarget): Promise<string[]>;
1277
2082
  /** Parse one Speckit-style integration key. */
1278
2083
  declare function parseIntegration(raw: string): AgentTarget;
@@ -1298,7 +2103,12 @@ interface InstallAgentOptions {
1298
2103
  }
1299
2104
  interface InstallAgentResult {
1300
2105
  created: string[];
2106
+ /** sdd-generated, unedited files that already existed (re-run with force to regenerate) */
1301
2107
  skipped: string[];
2108
+ /** Files never overwritten or deleted: not generated by sdd, or edited since */
2109
+ kept: KeptFile[];
2110
+ /** Other hosts' sdd-generated files that were removed */
2111
+ removed: string[];
1302
2112
  target: AgentTarget;
1303
2113
  }
1304
2114
  /** @deprecated Use InstallAgentOptions / installAgentIntegration. */
@@ -1313,6 +2123,30 @@ type InstallAgentsResult = {
1313
2123
  skipped: string[];
1314
2124
  targets: AgentTarget[];
1315
2125
  };
2126
+ /** What installAgentIntegration would do with one generated file. */
2127
+ interface PlannedWrite {
2128
+ rel: string;
2129
+ content: string;
2130
+ /** create: new file · overwrite: unmodified sdd file + force · skip: unmodified, no force · keep: never touched */
2131
+ action: "create" | "overwrite" | "skip" | "keep";
2132
+ keptReason?: KeptFile["reason"];
2133
+ /** For symlinks on the path: the link itself */
2134
+ keptPath?: string;
2135
+ }
2136
+ interface AgentInstallPlan {
2137
+ writes: PlannedWrite[];
2138
+ removal: RemovalPlan;
2139
+ /** Reasons the install cannot proceed safely; empty when it can */
2140
+ problems: string[];
2141
+ }
2142
+ /**
2143
+ * Work out every write and removal for an agent install without touching the disk,
2144
+ * and collect anything that would make it fail half-way (a directory where a file
2145
+ * goes, unreadable or read-only files, non-writable folders).
2146
+ */
2147
+ declare function planAgentIntegration(opts: InstallAgentOptions): Promise<AgentInstallPlan>;
2148
+ /** Throw {@link AgentInstallPreflightError} (before any write) if the install cannot finish. */
2149
+ declare function assertAgentInstallable(opts: InstallAgentOptions): Promise<void>;
1316
2150
  /**
1317
2151
  * Install thin agents for **one** AI integration (registry-driven).
1318
2152
  * Writes protocol + active-context + role stubs + single `.sdd/agents.json` snapshot.
@@ -1323,8 +2157,8 @@ declare function installAgentIntegration(opts: InstallAgentOptions): Promise<Ins
1323
2157
  * Prefer installAgentIntegration for product flows.
1324
2158
  */
1325
2159
  declare function installAgentIntegrations(opts: InstallAgentsOptions): Promise<InstallAgentsResult>;
1326
- /** Thin agent body shared across hosts (same text). */
1327
- declare function renderThinAgent(role: SddAgentRole): string;
2160
+ /** Thin agent body shared across hosts (same text). Paths come from config. */
2161
+ declare function renderThinAgent(role: SddAgentRole, config?: Config): string;
1328
2162
  interface InstalledAgentSnapshot {
1329
2163
  /** Public key: copilot | claude | grok | ollama | kilo */
1330
2164
  ai: string;
@@ -1337,7 +2171,7 @@ declare function loadInstalledAgent(projectRoot: string): Promise<InstalledAgent
1337
2171
  * Write `.sdd/handoff.md` for the active (or given) change — full agent brief.
1338
2172
  * Used by `sdd agent` and auto-launch after `sdd new`.
1339
2173
  */
1340
- declare function writeAgentHandoff(projectRoot: string, config: Config, changeId: string): Promise<string>;
2174
+ declare function writeAgentHandoff(projectRoot: string, config: Config, changeId: string, budget?: number, runtime?: SearchRuntime): Promise<string>;
1341
2175
  /** Short kickoff line to pass into agent CLIs (full brief is in handoff.md). */
1342
2176
  declare function agentKickoffMessage(opts: {
1343
2177
  title: string;
@@ -1350,34 +2184,60 @@ declare function agentKickoffMessage(opts: {
1350
2184
  * (used by sdd refine and other specialized modes).
1351
2185
  */
1352
2186
  instructions?: string;
2187
+ /** Configured folders; defaults keep existing `memory/` and `changes/` wording. */
2188
+ memoryPath?: string;
2189
+ changesPath?: string;
1353
2190
  }): string;
1354
2191
  /** Write .sdd/active-context.md for the current change. */
1355
2192
  declare function refreshActiveAgentContext(projectRoot: string): Promise<string | null>;
1356
- /** Single playbook — only long agent-facing content we author once. */
1357
- declare const PROTOCOL_MD = "# SDD protocol\n\nThis repo uses **Structured Vibe Coding** (`sdd`). Agents must follow this file plus `.sdd/active-context.md`. Do not invent a parallel process.\n\n## Source of truth\n\n| What | Where |\n|------|--------|\n| Process state | `changes/<id>/meta.yaml` (workflow, stage, gates) |\n| Current task snapshot | `.sdd/active-context.md` |\n| Non-negotiables | `memory/constitution.md` if present |\n| Stable product/tech rules | `memory/*.md` (start at `memory/index.md` if present) |\n| Stage artifacts | files in `changes/<id>/` for the active change |\n\n## Required read order\n\n1. `.sdd/active-context.md`\n2. This file (`.sdd/protocol.md`)\n3. `memory/constitution.md` if present (non-negotiables agents must not violate)\n4. `meta.yaml` + artifacts for the **current stage** (and prior stages if needed)\n5. `memory/index.md` (documentation map) if present, then linked memory pages when architecture or conventions matter\n\n## Stage behavior\n\n| Stage kind | Agent focus |\n|------------|-------------|\n| intent / feature / stories | Clarify scope; write short artifacts |\n| design / lld / db / research / hl_arb | Specs and decisions; minimal product code |\n| tasks | Break work into implementable checklist |\n| implement | Code only for this change; follow tasks/acceptance |\n| local_verify | Check acceptance; fix only; prepare for complete |\n| brainstorm (optional) | Multiple approaches; parallel exploration; no final design yet |\n| clarify_* (optional) | Ask clarifying questions; write Q&A; or tell human to skip |\n\n## Optional stages\n\n- Stages marked **optional** / kind `brainstorm` or `clarify` may be skipped: \n `sdd skip <stage_id> -r \"not needed\"`\n- Do **not** invent a skip by jumping stages. `sdd next` blocks on empty required stubs (e.g. design.md).\n- If the tool falls back to an earlier stage, **complete that stage** before advancing again.\n\n## Hard rules\n\n1. **Do not skip hard gates.** If blocked, tell the human to run `sdd gate approve` (or fix the gate).\n2. **Stay in scope** of the active change title/intent. No drive-by refactors or new features.\n3. **Honor constraints** in `arb-decision.md`, design, and memory non-negotiables.\n4. **Local verify** is part of done when the workflow has a verify stage: `sdd verify`.\n5. Prefer small, reviewable diffs.\n6. **Required stage artifacts must be substantive** \u2014 not empty templates. Design cannot be skipped via empty design.md.\n\n## Commands (human / shell)\n\n```bash\nsdd status\nsdd next\nsdd agent # print handoff\nsdd agents refresh # refresh active-context.md\nsdd verify\nsdd complete\n```\n\n## Out of scope for agents\n\n- Replacing CI/CD or team process tools\n- Deleting `.sdd` / completed change history\n- Claiming complete without verify when required\n";
2193
+ /** Default-path protocol text. Generated files use {@link renderProtocolMd}. */
2194
+ declare const PROTOCOL_MD: string;
2195
+ /** Single playbook — paths come from project config, not hard-coded defaults. */
2196
+ declare function renderProtocolMd(config: Pick<Config, "memory_path" | "changes_path">): string;
2197
+ declare function renderAgentsMd(integ: AgentIntegration, config?: Config): string;
1358
2198
 
1359
2199
  interface InitOptions {
1360
2200
  projectRoot: string;
1361
2201
  force?: boolean;
2202
+ /** Place memory, changes, domains, and archive beneath this project-relative root. */
2203
+ layoutRoot?: string;
1362
2204
  /**
1363
2205
  * AI coding agent to install (single, Speckit-style). Not an IDE.
1364
2206
  * - omit / `false` — no agent files
1365
2207
  * - `AgentTarget` — install that integration only
1366
2208
  */
1367
2209
  agents?: false | AgentTarget;
2210
+ /**
2211
+ * Test seam for "is this path tracked?". Return null when git cannot answer.
2212
+ * Production uses `git ls-files`.
2213
+ */
2214
+ indexLookup?: (projectRoot: string, relativePaths: string[]) => Promise<string[] | null>;
1368
2215
  }
1369
2216
  interface InitResult {
1370
2217
  created: string[];
1371
2218
  config: Config;
2219
+ warnings: string[];
2220
+ /** Existing files init left alone: not generated by sdd, or edited since */
2221
+ kept: KeptFile[];
1372
2222
  agents?: {
1373
2223
  created: string[];
1374
2224
  skipped: string[];
2225
+ kept: KeptFile[];
2226
+ removed: string[];
1375
2227
  };
1376
2228
  }
1377
2229
  declare function initProject(opts: InitOptions): Promise<InitResult>;
2230
+ /** Append missing required ignore lines. Does not rewrite config, memory, or workflows. */
2231
+ declare function repairRequiredIgnores(projectRoot: string): Promise<boolean>;
1378
2232
 
2233
+ /** pass: every command ran and exited 0 · fail: a command failed · not_run: nothing was executed */
2234
+ type VerifyStatus = "pass" | "fail" | "not_run";
1379
2235
  interface VerifyResult {
1380
2236
  stageId: string;
2237
+ /** Overall outcome; never "pass" unless at least one command ran and all exited 0 */
2238
+ status: VerifyStatus;
2239
+ /** Why the status is not "pass" (human readable) */
2240
+ reason?: string;
1381
2241
  results: {
1382
2242
  name: string;
1383
2243
  command: string;
@@ -1387,13 +2247,21 @@ interface VerifyResult {
1387
2247
  checklist: string[];
1388
2248
  /** Path to evidence dir when configured; null when no evidence_dir is set */
1389
2249
  evidencePath: string | null;
1390
- /** False if any required command failed or was not run when required */
2250
+ /** local-test-results.md that was written; null when nothing was recorded (wrong stage) */
2251
+ resultsPath: string | null;
2252
+ /** True only when status is "pass" */
1391
2253
  ok: boolean;
1392
2254
  }
1393
2255
  declare function runLocalVerify(projectRoot: string, config: Config, changeId: string, opts?: {
1394
2256
  runCommands?: boolean;
2257
+ headSha?: string | null;
1395
2258
  }): Promise<VerifyResult>;
1396
2259
 
2260
+ /**
2261
+ * Lowercase, strip quotes, collapse non-alphanumerics to `-`.
2262
+ * At most 60 characters, cut only on token boundaries.
2263
+ * A trailing `#NNN` is kept whole when it fits, never sliced into a shorter number.
2264
+ */
1397
2265
  declare function slugify(input: string): string;
1398
2266
  declare function todayIsoDate(d?: Date): string;
1399
2267
  declare function nowIso(d?: Date): string;
@@ -1412,6 +2280,8 @@ declare function defaultWorkflowsDir(): string;
1412
2280
  declare function defaultTemplatesDir(): string;
1413
2281
  declare function defaultMemoryDir(): string;
1414
2282
  declare function defaultMcpYamlPath(): string;
2283
+ declare function defaultPricesYamlPath(): string;
2284
+ declare function defaultSearchYamlPath(): string;
1415
2285
 
1416
2286
  declare function pathExists(path: string): Promise<boolean>;
1417
2287
  declare function ensureDir(path: string): Promise<void>;
@@ -1431,25 +2301,6 @@ declare function copyDirSkipExisting(src: string, dest: string): Promise<void>;
1431
2301
  declare function writeTextIfMissing(path: string, content: string): Promise<boolean>;
1432
2302
  declare function removePath(path: string): Promise<void>;
1433
2303
 
1434
- /**
1435
- * Typed, user-facing errors for sdd core.
1436
- * CLI maps these to exit codes and optional hints.
1437
- */
1438
- declare class SddError extends Error {
1439
- readonly code: string;
1440
- readonly hint?: string;
1441
- readonly exitCode: number;
1442
- constructor(message: string, options?: {
1443
- code?: string;
1444
- hint?: string;
1445
- exitCode?: number;
1446
- cause?: unknown;
1447
- });
1448
- }
1449
- declare function isSddError(err: unknown): err is SddError;
1450
- /** Normalize unknown throws into Error for logging. */
1451
- declare function errorMessage(err: unknown): string;
1452
-
1453
2304
  /**
1454
2305
  * Sanitize env maps for child processes (MCP stdio, verify commands).
1455
2306
  */
@@ -1458,6 +2309,16 @@ declare function toProcessEnv(base: NodeJS.ProcessEnv | Record<string, string |
1458
2309
 
1459
2310
  declare const SDD_CORE_VERSION: string;
1460
2311
 
2312
+ /** `.sdd/README.md` body. Paths come from config. */
2313
+ declare function renderSddReadme(config: Pick<Config, "memory_path" | "changes_path">): string;
2314
+ /** Documentation map. Paths come from config. */
2315
+ declare function renderMemoryIndex(config: Pick<Config, "memory_path" | "changes_path">): string;
2316
+ /**
2317
+ * Rewrite generated guidance that still names the default folders when config
2318
+ * uses other paths. Edited files are left alone.
2319
+ */
2320
+ declare function refreshConfiguredGuidance(projectRoot: string, config: Config): Promise<void>;
2321
+
1461
2322
  /**
1462
2323
  * Public + internal types for the on-demand structure-aware code context pipeline.
1463
2324
  * Contracts: LLD §2.1 / research §6.5.
@@ -1498,7 +2359,7 @@ interface CodeContextRequest {
1498
2359
  */
1499
2360
  writeArtifactTo?: string | null;
1500
2361
  }
1501
- type CodeContextGapCode = "no_focus" | "path_missing" | "path_denied_secret" | "path_ignored" | "unsupported_language" | "parse_error" | "empty_extract" | "cap_truncated" | "no_active_change" | "change_not_found" | "adapter_unavailable";
2362
+ type CodeContextGapCode = "no_focus" | "path_missing" | "path_denied_secret" | "path_ignored" | "unsupported_language" | "parse_error" | "empty_extract" | "cap_truncated" | "no_active_change" | "change_not_found" | "adapter_unavailable" | "embeddings_unavailable";
1502
2363
  interface CodeContextGap {
1503
2364
  code: CodeContextGapCode;
1504
2365
  message: string;
@@ -1664,10 +2525,12 @@ declare const fallbackAdapter: LanguageAdapter;
1664
2525
  * Public entry: generateCodeContext
1665
2526
  */
1666
2527
 
1667
- /** Optional deps for tests (inject adapters). */
2528
+ /** Optional deps for tests (inject adapters or an embedder). */
1668
2529
  type GenerateCodeContextDeps = {
1669
2530
  adapters?: LanguageAdapter[];
1670
2531
  now?: () => Date;
2532
+ embedder?: SearchRuntime["embedder"];
2533
+ embedderFactory?: SearchRuntime["embedderFactory"];
1671
2534
  };
1672
2535
  /**
1673
2536
  * Main entry: on-demand pipeline. Partial success returns ok:true with gaps.
@@ -1900,11 +2763,11 @@ declare const McpSourceSchema: z.ZodObject<{
1900
2763
  intents: string[];
1901
2764
  };
1902
2765
  priority: number;
2766
+ enabled: boolean;
1903
2767
  args: string[];
1904
2768
  transport: "stdio";
1905
2769
  command: string;
1906
2770
  env: Record<string, string>;
1907
- enabled: boolean;
1908
2771
  cwd?: string | undefined;
1909
2772
  invoke?: {
1910
2773
  tool: string;
@@ -1922,11 +2785,11 @@ declare const McpSourceSchema: z.ZodObject<{
1922
2785
  intents?: string[] | undefined;
1923
2786
  } | undefined;
1924
2787
  priority?: number | undefined;
2788
+ enabled?: boolean | undefined;
2789
+ cwd?: string | undefined;
1925
2790
  args?: string[] | undefined;
1926
2791
  transport?: "stdio" | undefined;
1927
2792
  env?: Record<string, string> | undefined;
1928
- cwd?: string | undefined;
1929
- enabled?: boolean | undefined;
1930
2793
  invoke?: {
1931
2794
  tool: string;
1932
2795
  args?: Record<string, unknown> | undefined;
@@ -2009,11 +2872,11 @@ declare const McpConfigSchema: z.ZodObject<{
2009
2872
  intents: string[];
2010
2873
  };
2011
2874
  priority: number;
2875
+ enabled: boolean;
2012
2876
  args: string[];
2013
2877
  transport: "stdio";
2014
2878
  command: string;
2015
2879
  env: Record<string, string>;
2016
- enabled: boolean;
2017
2880
  cwd?: string | undefined;
2018
2881
  invoke?: {
2019
2882
  tool: string;
@@ -2031,11 +2894,11 @@ declare const McpConfigSchema: z.ZodObject<{
2031
2894
  intents?: string[] | undefined;
2032
2895
  } | undefined;
2033
2896
  priority?: number | undefined;
2897
+ enabled?: boolean | undefined;
2898
+ cwd?: string | undefined;
2034
2899
  args?: string[] | undefined;
2035
2900
  transport?: "stdio" | undefined;
2036
2901
  env?: Record<string, string> | undefined;
2037
- cwd?: string | undefined;
2038
- enabled?: boolean | undefined;
2039
2902
  invoke?: {
2040
2903
  tool: string;
2041
2904
  args?: Record<string, unknown> | undefined;
@@ -2056,11 +2919,11 @@ declare const McpConfigSchema: z.ZodObject<{
2056
2919
  intents: string[];
2057
2920
  };
2058
2921
  priority: number;
2922
+ enabled: boolean;
2059
2923
  args: string[];
2060
2924
  transport: "stdio";
2061
2925
  command: string;
2062
2926
  env: Record<string, string>;
2063
- enabled: boolean;
2064
2927
  cwd?: string | undefined;
2065
2928
  invoke?: {
2066
2929
  tool: string;
@@ -2083,11 +2946,11 @@ declare const McpConfigSchema: z.ZodObject<{
2083
2946
  intents?: string[] | undefined;
2084
2947
  } | undefined;
2085
2948
  priority?: number | undefined;
2949
+ enabled?: boolean | undefined;
2950
+ cwd?: string | undefined;
2086
2951
  args?: string[] | undefined;
2087
2952
  transport?: "stdio" | undefined;
2088
2953
  env?: Record<string, string> | undefined;
2089
- cwd?: string | undefined;
2090
- enabled?: boolean | undefined;
2091
2954
  invoke?: {
2092
2955
  tool: string;
2093
2956
  args?: Record<string, unknown> | undefined;
@@ -2188,4 +3051,135 @@ declare function gatherMcpContextForChange(projectRoot: string, ctx: ChangeConte
2188
3051
  declare function formatMcpContextForHandoff(results: McpFetchResult[]): string;
2189
3052
  declare function listMatchingSourceIds(sources: McpSource[], match: McpMatchContext): string[];
2190
3053
 
2191
- export { AGENT_INTEGRATIONS, AGENT_TARGET_OPTIONS, ALL_AGENT_TARGETS, type AdapterExtractResult, AdapterRegistry, type AdvanceResult, type AgentIntegration, type AgentTarget, type AgentTargetOption, type ArtifactDef, ArtifactDefSchema, type BuildRefinePlanOptions, type CallMcpToolResult, type ChangeContext, type ChangeMeta, ChangeMetaSchema, type CodeContextCaps, type CodeContextGap, type CodeContextGapCode, type CodeContextRequest, type CodeContextResult, type CodeContextSummary, type CodeSlice, type Complexity, type Config, ConfigSchema, type CreateChangeInput, DEFAULT_CODE_CONTEXT_CAPS, DEFAULT_INIT_INTEGRATION, type FocusPlan, type Gate, GateSchema, type GatherMcpOptions, type GenerateCodeContextDeps, type GreenfieldFeature, type InitOptions, type InitResult, type InstallAgentOptions, type InstallAgentResult, type InstallAgentsOptions, type InstallAgentsResult, type InstalledAgentSnapshot, type LanguageAdapter, type McpConfig, McpConfigSchema, type McpFetchResult, type McpInvoke, McpInvokeSchema, type McpMatchContext, type McpSource, McpSourceSchema, type McpWhen, McpWhenSchema, PROTOCOL_MD, type RefineArtifactRef, type RefineMode, type RefinePlan, SDD_AGENT_ROLES, SDD_CORE_VERSION, SDD_DIR, type SddAgentRole, type SddAgentRoleId, SddError, type Stage, StageSchema, type StartFeatureInput, type StartGreenfieldInput, type StartGreenfieldResult, type SymbolInfo, type SymbolKind, VerifyCommandSchema, type VerifyResult, type Workflow, WorkflowSchema, activePointerPath, activeStages, addMcpSource, advanceStage, agentHostPaths, agentKickoffMessage, approveGate, archiveDir, buildAgentPrompt, buildContext, buildRefinePlan, callMcpSourceTool, canLeaveStage, changeDirName, changeMetaPath, changePath, changesDir, classifyPath, clearActiveIf, completeChange, configPath, copyDir, copyDirSkipExisting, createChange, defaultConfig, defaultMcpConfig, defaultMcpYamlPath, defaultMemoryDir, defaultTemplatesDir, defaultWorkflowsDir, defaultsRoot, domainsDir, ensureDir, ensureMcpConfig, errorMessage, explainMatch, fallbackAdapter, fallbackIncompleteStageId, findFeaturesBacklogPath, firstActiveStageId, formatJsonSummary, formatMcpContextForHandoff, formatStatus, gatherMcpContext, gatherMcpContextForChange, generateCodeContext, getActiveChangeId, getIntegration, getStage, incompletePriorStageErrors, inferComplexity, initProject, installAgentIntegration, installAgentIntegrations, integrationKeyFor, interpolate, interpolateArgs, isIgnoredPath, isInitialized, isSddError, isSecretPath, isStageSkipped, isSubstantiveArtifactContent, listBacklogFeatures, listChanges, listDirs, listFiles, listMatchingSourceIds, listMcpSourceTools, listWorkflowNames, loadChangeMeta, loadConfig, loadInstalledAgent, loadMcpConfig, loadWorkflow, matchMcpSources, mcpConfigPath, mcpTimeoutMs, memoryDir, mergeCaps, nextStageId, nowIso, optionForTarget, parseAgentTargets, parseFeaturesBacklog, parseIntegration, pathExists, promoteGreenfieldToMemory, readText, readYaml, recommendWorkflow, refreshActiveAgentContext, removeMcpSource, removeOtherAgentHosts, removePath, renderThinAgent, resolveChangeId, resolveFocus, resolveStages, runLocalVerify, saveChangeMeta, saveConfig, saveMcpConfig, sddRoot, setActiveChange, shouldAutoSkip, skipStage, slugify, startFeatureFromBacklog, startGreenfield, switchWorkflow, templatesDir, toProcessEnv, todayIsoDate, tokenizeKeywords, typescriptAdapter, uniqueChangeDirName, updateFeatureStatus, withMcpSource, workflowsDir, writeAgentHandoff, writeRefineBrief, writeText, writeTextIfMissing, writeYaml };
3054
+ interface RoleProfile {
3055
+ name: string;
3056
+ label: string;
3057
+ job: string;
3058
+ description: string;
3059
+ askFirst: boolean;
3060
+ pinned: boolean;
3061
+ hidden: boolean;
3062
+ }
3063
+ interface RoleModel {
3064
+ complete(input: {
3065
+ roleId: string;
3066
+ prompt: string;
3067
+ }): Promise<string>;
3068
+ }
3069
+ interface RoleCommandResult {
3070
+ exitCode: number;
3071
+ stdout: string;
3072
+ runId?: string;
3073
+ }
3074
+
3075
+ declare function setRoleMessaging(root: string, enabled: boolean): Promise<RoleCommandResult>;
3076
+ declare function handoffRole(root: string, input: {
3077
+ from: string;
3078
+ to: string;
3079
+ task?: string;
3080
+ change?: string;
3081
+ section?: string;
3082
+ model?: RoleModel;
3083
+ now?: () => Date;
3084
+ }): Promise<RoleCommandResult>;
3085
+ declare function showRoleGroup(root: string, changeId: string): Promise<RoleCommandResult>;
3086
+ declare function planNetwork(root: string, input: {
3087
+ change?: string;
3088
+ section?: string;
3089
+ task?: string;
3090
+ model?: RoleModel;
3091
+ now?: () => Date;
3092
+ }): Promise<RoleCommandResult>;
3093
+ declare function acceptNetwork(root: string, input: {
3094
+ change?: string;
3095
+ section?: string;
3096
+ }): Promise<RoleCommandResult>;
3097
+ declare function runNetwork(root: string, input: {
3098
+ change?: string;
3099
+ section?: string;
3100
+ model?: RoleModel;
3101
+ now?: () => Date;
3102
+ }): Promise<RoleCommandResult>;
3103
+ declare function rebuildNetwork(root: string, input: {
3104
+ change?: string;
3105
+ section?: string;
3106
+ model?: RoleModel;
3107
+ now?: () => Date;
3108
+ }): Promise<RoleCommandResult>;
3109
+
3110
+ interface RunRoleInput {
3111
+ name: string;
3112
+ task?: string;
3113
+ withRole?: string;
3114
+ kind?: string;
3115
+ section?: string;
3116
+ change?: string;
3117
+ stop?: boolean;
3118
+ model?: RoleModel;
3119
+ now?: () => Date;
3120
+ }
3121
+ interface AllowRoleInput {
3122
+ runId: string;
3123
+ mode: "once" | "always" | "deny";
3124
+ now?: () => Date;
3125
+ }
3126
+ declare function runRole(root: string, input: RunRoleInput): Promise<RoleCommandResult>;
3127
+ declare function allowRole(root: string, input: AllowRoleInput): Promise<RoleCommandResult>;
3128
+
3129
+ declare function createRole(root: string, input: {
3130
+ name: string;
3131
+ label: string;
3132
+ job: string;
3133
+ description?: string;
3134
+ askFirst?: boolean;
3135
+ }): Promise<RoleCommandResult>;
3136
+ declare function editRole(root: string, nameInput: string, patch: {
3137
+ label?: string;
3138
+ job?: string;
3139
+ description?: string;
3140
+ askFirst?: boolean;
3141
+ }): Promise<RoleCommandResult>;
3142
+ declare function pinRole(root: string, name: string): Promise<RoleCommandResult>;
3143
+ declare function hideRole(root: string, name: string): Promise<RoleCommandResult>;
3144
+ declare function showRoles(root: string, opts?: {
3145
+ name?: string;
3146
+ all?: boolean;
3147
+ }): Promise<RoleCommandResult>;
3148
+ declare function duplicateRole(root: string, nameInput: string): Promise<RoleCommandResult>;
3149
+ declare function deleteRole(root: string, nameInput: string): Promise<RoleCommandResult>;
3150
+
3151
+ interface StoryNode {
3152
+ changeId: string;
3153
+ title: string;
3154
+ story: string;
3155
+ epic: string;
3156
+ depends: string[];
3157
+ status: string;
3158
+ }
3159
+ interface StoryDraft {
3160
+ epic?: string;
3161
+ story?: string;
3162
+ depends: string[];
3163
+ }
3164
+ declare function validBranchName(name: string): boolean;
3165
+ declare function parseStoryDraft(input: {
3166
+ epic?: string;
3167
+ story?: string;
3168
+ depends?: string[];
3169
+ }): {
3170
+ ok: true;
3171
+ draft: StoryDraft;
3172
+ } | {
3173
+ ok: false;
3174
+ stdout: string;
3175
+ };
3176
+ declare function loadEpicStories(projectRoot: string, config: Config, epic: string): Promise<StoryNode[]>;
3177
+ declare function storyIdTaken(projectRoot: string, config: Config, epic: string, story: string): Promise<boolean>;
3178
+ declare function formatEpicGraph(nodes: StoryNode[]): {
3179
+ exitCode: number;
3180
+ stdout: string;
3181
+ };
3182
+ /** Graph errors, then open dependencies. Null means the branch may be created. */
3183
+ declare function branchBlock(nodes: StoryNode[], story: string): string | null;
3184
+
3185
+ export { AGENT_INTEGRATIONS, AGENT_TARGET_OPTIONS, ALL_AGENT_TARGETS, type AdapterExtractResult, AdapterRegistry, type AdvanceResult, type AgentInstallPlan, AgentInstallPreflightError, type AgentIntegration, type AgentTarget, type AgentTargetOption, type AllowRoleInput, type ArtifactDef, ArtifactDefSchema, type BuildRefinePlanOptions, type CallMcpToolResult, type ChangeContext, type ChangeMeta, ChangeMetaSchema, type ChangeMetrics, ChangeMetricsSchema, type ChangePhaseOrder, type CodeContextCaps, type CodeContextGap, type CodeContextGapCode, type CodeContextRequest, type CodeContextResult, type CodeContextSummary, type CodeSlice, type Complexity, type Config, ConfigSchema, type CreateChangeInput, DEFAULT_CODE_CONTEXT_CAPS, DEFAULT_INIT_INTEGRATION, EMBEDDINGS_UNAVAILABLE, EMBEDDING_MODEL, type Embedder, type FastembedHooks, type FocusPlan, type Gate, GateSchema, type GatherMcpOptions, type GenerateCodeContextDeps, type GeneratedManifest, type GeneratedState, type GitHeadRunner, type GreenfieldFeature, type IndexStats, type InitOptions, type InitResult, type InstallAgentOptions, type InstallAgentResult, type InstallAgentsOptions, type InstallAgentsResult, type InstalledAgentSnapshot, type KeptFile, type KeptReason, type LanguageAdapter, type McpConfig, McpConfigSchema, type McpFetchResult, type McpInvoke, McpInvokeSchema, type McpMatchContext, type McpSource, McpSourceSchema, type McpWhen, McpWhenSchema, type MetricsImportResult, PROTOCOL_MD, type PhaseMetric, PhaseMetricSchema, type PhaseTiming, type PhaseTimingRow, type PlannedWrite, type PriceCard, type Prices, RRF_K, type RawHit, type ReconcileGeneratedResult, type RefineArtifactRef, type RefineMode, type RefinePlan, type RemoveAgentHostsResult, type RenderChangeReportInput, type RoleCommandResult, type RoleModel, type RoleProfile, type RunRoleInput, SDD_AGENT_ROLES, SDD_CORE_VERSION, SDD_DIR, SUMMARY_TOKEN_CAP, type SddAgentRole, type SddAgentRoleId, SddError, type SearchConfig, SearchConfigError, type SearchHit, type SearchProvider, type SearchQuery, type SearchResult, type SearchRuntime, type SearchScope, type Stage, StageSchema, type StartFeatureInput, type StartGreenfieldInput, type StartGreenfieldResult, type StoryDraft, type StoryNode, type SymbolInfo, type SymbolKind, type SyncChangeResult, type TokenCounts, type TokenUsageMetric, TokenUsageMetricSchema, VerifyCommandSchema, type VerifyResult, type VerifyStatus, type Workflow, WorkflowSchema, acceptNetwork, activePointerPath, activeStages, addMcpSource, advanceStage, agentHostPaths, agentKickoffMessage, allowRole, approveGate, archiveDir, assertAgentInstallable, assertSessionLogAllowed, branchBlock, budgetForStage, buildAgentPrompt, buildContext, buildRefinePlan, buildRetrievedInner, callMcpSourceTool, canLeaveStage, changeDirName, changeMetaPath, changePath, changesDir, changesPathRel, chunkCode, chunkMarkdown, classifyPath, clearActiveIf, clearRegisteredSearchProviders, compareChangesByFirstPhase, completeChange, configPath, contentHash, copyDir, copyDirSkipExisting, costFor, countTokens, createBuiltinProvider, createChange, createFastembedEmbedder, createRole, defaultConfig, defaultMcpConfig, defaultMcpYamlPath, defaultMemoryDir, defaultPricesYamlPath, defaultSearchYamlPath, defaultTemplatesDir, defaultWorkflowsDir, defaultsRoot, deleteRole, describeFsError, describeKept, displayArchivePath, displayChangePath, domainsDir, duplicateRole, editRole, embedSearchQuery, emptyChangeMetrics, ensureDir, ensureMcpConfig, errorMessage, executeSearch, explainMatch, extractiveSummary, fallbackAdapter, fallbackIncompleteStageId, fallbackWarning, fastembedImportCount, findFeaturesBacklogPath, firstActiveStageId, formatDuration, formatEpicGraph, formatJsonSummary, formatMcpContextForHandoff, formatStatus, ftsTokens, fuseByRank, fuseHits, gatherMcpContext, gatherMcpContextForChange, generateCodeContext, generatedState, getActiveChangeId, getHeadSha, getIntegration, getStage, guidancePaths, handoffRole, hideRole, importSessionMetrics, incompletePriorStageErrors, indexDbPath, inferComplexity, initProject, installAgentIntegration, installAgentIntegrations, integrationKeyFor, interpolate, interpolateArgs, isHardDenied, isIgnoredPath, isInitialized, isPrunedDir, isSddError, isSecretPath, isStageSkipped, isSubstantiveArtifactContent, keywordHits, listBacklogFeatures, listChanges, listDirs, listFiles, listMatchingSourceIds, listMcpSourceTools, listScopeHits, listWorkflowNames, loadChangeMeta, loadConfig, loadEpicStories, loadExcluder, loadGeneratedManifest, loadInstalledAgent, loadMcpConfig, loadPrices, loadSearchConfig, loadWorkflow, markGenerated, matchMcpSources, mcpConfigPath, mcpTimeoutMs, memoryDir, memoryPathRel, mergeCaps, mergeConfigDefaults, mergeRankedHits, nextStageId, nowIso, optionForTarget, packHits, parseAgentTargets, parseFeaturesBacklog, parseIntegration, parseStoryDraft, pathExists, phaseTiming, pinRole, planAgentIntegration, planNetwork, promoteGreenfieldToMemory, rankScope, readChangeMetrics, readHandoffCodePoints, readText, readYaml, rebuildNetwork, recommendWorkflow, reconcileGeneratedTree, refreshActiveAgentContext, refreshConfiguredGuidance, registerSearchProvider, removeMcpSource, removeOtherAgentHosts, removeOtherAgentHostsDetailed, removePath, renderAgentsMd, renderBlock, renderChangeReport, renderMemoryIndex, renderProtocolMd, renderSddReadme, renderThinAgent, repairRequiredIgnores, reportAllChanges, reportChange, resolveActiveDirectory, resolveChangeId, resolveEmbedder, resolveFocus, resolveSearchProvider, resolveStages, rrf, runLocalVerify, runNetwork, runRole, saveChangeMeta, saveConfig, saveGeneratedManifest, saveMcpConfig, scopeForPath, sddRoot, searchConfigPath, searchPreamble, setActiveChange, setRoleMessaging, shouldAutoSkip, showRoleGroup, showRoles, skipStage, slugify, startFeatureFromBacklog, startGreenfield, startPhase, storyIdTaken, switchWorkflow, syncChangeHead, templatesDir, toProcessEnv, todayIsoDate, tokenizeKeywords, transitionPhase, typescriptAdapter, uniqueChangeDirName, updateFeatureStatus, validBranchName, withMcpSource, workflowsDir, writeAgentHandoff, writeRefineBrief, writeText, writeTextIfMissing, writeYaml };